aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 12:03:10 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-09-21 12:03:10 -0400
commitc720f5655df159a630fa0290a0bd67c93e92b0bf (patch)
tree940d139d0ec1ff5201efddef6cc663166a8a2df3
parent33e6c1a0de818d3698cdab27c42915661011319d (diff)
parent84d6ae431f315e8973aac3c3fe1d550fc9240ef3 (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (222 commits) V4L/DVB (13033): pt1: Don't use a deprecated DMA_BIT_MASK macro V4L/DVB (13029): radio-si4713: remove #include <linux/version.h> V4L/DVB (13027): go7007: convert printks to v4l2_info V4L/DVB (13026): s2250-board: Implement brightness and contrast controls V4L/DVB (13025): s2250-board: Fix memory leaks V4L/DVB (13024): go7007: Implement vidioc_g_std and vidioc_querystd V4L/DVB (13023): go7007: Merge struct gofh and go declarations V4L/DVB (13022): go7007: Fix mpeg controls V4L/DVB (13021): go7007: Fix whitespace and line lengths V4L/DVB (13020): go7007: Updates to Kconfig and Makefile V4L/DVB (13019): video: initial support for ADV7180 V4L/DVB (13018): kzalloc failure ignored in au8522_probe() V4L/DVB (13017): gspca: kmalloc failure ignored in sd_start() V4L/DVB (13016): kmalloc failure ignored in lgdt3304_attach() and s921_attach() V4L/DVB (13015): kmalloc failure ignored in m920x_firmware_download() V4L/DVB (13014): Add support for Compro VideoMate E800 (DVB-T part only) V4L/DVB (13013): FM TX: si4713: Kconfig: Fixed two typos. V4L/DVB (13012): uvc: introduce missing kfree V4L/DVB (13011): Change tuner type of BeholdTV cards V4L/DVB (13009): gspca - stv06xx-hdcs: Reduce exposure range ...
-rw-r--r--Documentation/DocBook/Makefile10
-rw-r--r--Documentation/DocBook/dvb/.gitignore1
-rw-r--r--Documentation/DocBook/dvb/audio.xml1473
-rw-r--r--Documentation/DocBook/dvb/ca.xml221
-rw-r--r--Documentation/DocBook/dvb/demux.xml973
-rw-r--r--Documentation/DocBook/dvb/dvbapi.xml87
-rw-r--r--Documentation/DocBook/dvb/dvbstb.pdfbin0 -> 1881 bytes
-rw-r--r--Documentation/DocBook/dvb/dvbstb.pngbin0 -> 22655 bytes
-rw-r--r--Documentation/DocBook/dvb/examples.xml365
-rw-r--r--Documentation/DocBook/dvb/frontend.xml1766
-rw-r--r--Documentation/DocBook/dvb/intro.xml191
-rw-r--r--Documentation/DocBook/dvb/isdbt.xml314
-rw-r--r--Documentation/DocBook/dvb/kdapi.xml2309
-rw-r--r--Documentation/DocBook/dvb/net.xml12
-rw-r--r--Documentation/DocBook/dvb/video.xml1971
-rw-r--r--Documentation/DocBook/media-entities.tmpl364
-rw-r--r--Documentation/DocBook/media-indices.tmpl85
-rw-r--r--Documentation/DocBook/media.tmpl112
-rw-r--r--Documentation/DocBook/stylesheet.xsl1
-rw-r--r--Documentation/DocBook/v4l/.gitignore1
-rw-r--r--Documentation/DocBook/v4l/biblio.xml188
-rw-r--r--Documentation/DocBook/v4l/capture.c.xml659
-rw-r--r--Documentation/DocBook/v4l/common.xml1160
-rw-r--r--Documentation/DocBook/v4l/compat.xml2457
-rw-r--r--Documentation/DocBook/v4l/controls.xml2049
-rw-r--r--Documentation/DocBook/v4l/crop.gifbin0 -> 5967 bytes
-rw-r--r--Documentation/DocBook/v4l/crop.pdfbin0 -> 5846 bytes
-rw-r--r--Documentation/DocBook/v4l/dev-capture.xml115
-rw-r--r--Documentation/DocBook/v4l/dev-codec.xml26
-rw-r--r--Documentation/DocBook/v4l/dev-effect.xml25
-rw-r--r--Documentation/DocBook/v4l/dev-osd.xml164
-rw-r--r--Documentation/DocBook/v4l/dev-output.xml111
-rw-r--r--Documentation/DocBook/v4l/dev-overlay.xml379
-rw-r--r--Documentation/DocBook/v4l/dev-radio.xml57
-rw-r--r--Documentation/DocBook/v4l/dev-raw-vbi.xml347
-rw-r--r--Documentation/DocBook/v4l/dev-rds.xml168
-rw-r--r--Documentation/DocBook/v4l/dev-sliced-vbi.xml708
-rw-r--r--Documentation/DocBook/v4l/dev-teletext.xml40
-rw-r--r--Documentation/DocBook/v4l/driver.xml208
-rw-r--r--Documentation/DocBook/v4l/fdl-appendix.xml671
-rw-r--r--Documentation/DocBook/v4l/fieldseq_bt.gifbin0 -> 25430 bytes
-rw-r--r--Documentation/DocBook/v4l/fieldseq_bt.pdfbin0 -> 9185 bytes
-rw-r--r--Documentation/DocBook/v4l/fieldseq_tb.gifbin0 -> 25323 bytes
-rw-r--r--Documentation/DocBook/v4l/fieldseq_tb.pdfbin0 -> 9173 bytes
-rw-r--r--Documentation/DocBook/v4l/func-close.xml70
-rw-r--r--Documentation/DocBook/v4l/func-ioctl.xml146
-rw-r--r--Documentation/DocBook/v4l/func-mmap.xml185
-rw-r--r--Documentation/DocBook/v4l/func-munmap.xml83
-rw-r--r--Documentation/DocBook/v4l/func-open.xml121
-rw-r--r--Documentation/DocBook/v4l/func-poll.xml127
-rw-r--r--Documentation/DocBook/v4l/func-read.xml189
-rw-r--r--Documentation/DocBook/v4l/func-select.xml138
-rw-r--r--Documentation/DocBook/v4l/func-write.xml136
-rw-r--r--Documentation/DocBook/v4l/io.xml1073
-rw-r--r--Documentation/DocBook/v4l/keytable.c.xml172
-rw-r--r--Documentation/DocBook/v4l/libv4l.xml167
-rw-r--r--Documentation/DocBook/v4l/pixfmt-grey.xml70
-rw-r--r--Documentation/DocBook/v4l/pixfmt-nv12.xml151
-rw-r--r--Documentation/DocBook/v4l/pixfmt-nv16.xml174
-rw-r--r--Documentation/DocBook/v4l/pixfmt-packed-rgb.xml862
-rw-r--r--Documentation/DocBook/v4l/pixfmt-packed-yuv.xml244
-rw-r--r--Documentation/DocBook/v4l/pixfmt-sbggr16.xml91
-rw-r--r--Documentation/DocBook/v4l/pixfmt-sbggr8.xml75
-rw-r--r--Documentation/DocBook/v4l/pixfmt-sgbrg8.xml75
-rw-r--r--Documentation/DocBook/v4l/pixfmt-sgrbg8.xml75
-rw-r--r--Documentation/DocBook/v4l/pixfmt-uyvy.xml128
-rw-r--r--Documentation/DocBook/v4l/pixfmt-vyuy.xml128
-rw-r--r--Documentation/DocBook/v4l/pixfmt-y16.xml89
-rw-r--r--Documentation/DocBook/v4l/pixfmt-y41p.xml157
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuv410.xml141
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuv411p.xml155
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuv420.xml157
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuv422p.xml161
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuyv.xml128
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yvyu.xml128
-rw-r--r--Documentation/DocBook/v4l/pixfmt.xml801
-rw-r--r--Documentation/DocBook/v4l/remote_controllers.xml175
-rw-r--r--Documentation/DocBook/v4l/v4l2.xml479
-rw-r--r--Documentation/DocBook/v4l/v4l2grab.c.xml164
-rw-r--r--Documentation/DocBook/v4l/vbi_525.gifbin0 -> 4741 bytes
-rw-r--r--Documentation/DocBook/v4l/vbi_525.pdfbin0 -> 3395 bytes
-rw-r--r--Documentation/DocBook/v4l/vbi_625.gifbin0 -> 5095 bytes
-rw-r--r--Documentation/DocBook/v4l/vbi_625.pdfbin0 -> 3683 bytes
-rw-r--r--Documentation/DocBook/v4l/vbi_hsync.gifbin0 -> 2400 bytes
-rw-r--r--Documentation/DocBook/v4l/vbi_hsync.pdfbin0 -> 7405 bytes
-rw-r--r--Documentation/DocBook/v4l/videodev2.h.xml1640
-rw-r--r--Documentation/DocBook/v4l/vidioc-cropcap.xml174
-rw-r--r--Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml275
-rw-r--r--Documentation/DocBook/v4l/vidioc-dbg-g-register.xml275
-rw-r--r--Documentation/DocBook/v4l/vidioc-encoder-cmd.xml204
-rw-r--r--Documentation/DocBook/v4l/vidioc-enum-fmt.xml164
-rw-r--r--Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml270
-rw-r--r--Documentation/DocBook/v4l/vidioc-enum-framesizes.xml282
-rw-r--r--Documentation/DocBook/v4l/vidioc-enumaudio.xml86
-rw-r--r--Documentation/DocBook/v4l/vidioc-enumaudioout.xml89
-rw-r--r--Documentation/DocBook/v4l/vidioc-enuminput.xml287
-rw-r--r--Documentation/DocBook/v4l/vidioc-enumoutput.xml172
-rw-r--r--Documentation/DocBook/v4l/vidioc-enumstd.xml391
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-audio.xml188
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-audioout.xml154
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-crop.xml143
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-ctrl.xml130
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-enc-index.xml213
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml307
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-fbuf.xml456
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-fmt.xml201
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-frequency.xml145
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-input.xml100
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml180
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-modulator.xml246
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-output.xml100
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-parm.xml332
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-priority.xml144
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml264
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-std.xml99
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-tuner.xml535
-rw-r--r--Documentation/DocBook/v4l/vidioc-log-status.xml58
-rw-r--r--Documentation/DocBook/v4l/vidioc-overlay.xml83
-rw-r--r--Documentation/DocBook/v4l/vidioc-qbuf.xml168
-rw-r--r--Documentation/DocBook/v4l/vidioc-querybuf.xml103
-rw-r--r--Documentation/DocBook/v4l/vidioc-querycap.xml284
-rw-r--r--Documentation/DocBook/v4l/vidioc-queryctrl.xml428
-rw-r--r--Documentation/DocBook/v4l/vidioc-querystd.xml83
-rw-r--r--Documentation/DocBook/v4l/vidioc-reqbufs.xml160
-rw-r--r--Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml129
-rw-r--r--Documentation/DocBook/v4l/vidioc-streamon.xml106
-rw-r--r--Documentation/dvb/get_dvb_firmware37
-rw-r--r--Documentation/dvb/technisat.txt75
-rw-r--r--Documentation/video4linux/CARDLIST.cx238851
-rw-r--r--Documentation/video4linux/CARDLIST.em28xx3
-rw-r--r--Documentation/video4linux/CARDLIST.saa71341
-rw-r--r--Documentation/video4linux/CARDLIST.saa71649
-rw-r--r--Documentation/video4linux/CARDLIST.tuner2
-rw-r--r--Documentation/video4linux/gspca.txt2
-rw-r--r--Documentation/video4linux/soc-camera.txt40
-rw-r--r--Documentation/video4linux/v4l2-framework.txt61
-rw-r--r--arch/sh/boards/board-ap325rxa.c58
-rw-r--r--drivers/media/common/tuners/tda18271-common.c3
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c83
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c3
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h1
-rw-r--r--drivers/media/common/tuners/tda18271.h14
-rw-r--r--drivers/media/common/tuners/tuner-types.c27
-rw-r--r--drivers/media/dvb/Kconfig4
-rw-r--r--drivers/media/dvb/Makefile2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c218
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h17
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig9
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c50
-rw-r--r--drivers/media/dvb/dvb-usb/anysee.c14
-rw-r--r--drivers/media/dvb/dvb-usb/ce6230.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c501
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h11
-rw-r--r--drivers/media/dvb/dvb-usb/friio-fe.c483
-rw-r--r--drivers/media/dvb/dvb-usb/friio.c525
-rw-r--r--drivers/media/dvb/dvb-usb/friio.h99
-rw-r--r--drivers/media/dvb/dvb-usb/m920x.c2
-rw-r--r--drivers/media/dvb/frontends/Kconfig8
-rw-r--r--drivers/media/dvb/frontends/Makefile1
-rw-r--r--drivers/media/dvb/frontends/au8522_decoder.c5
-rw-r--r--drivers/media/dvb/frontends/dib0070.c803
-rw-r--r--drivers/media/dvb/frontends/dib0070.h30
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c33
-rw-r--r--drivers/media/dvb/frontends/dib8000.c2277
-rw-r--r--drivers/media/dvb/frontends/dib8000.h79
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c95
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h31
-rw-r--r--drivers/media/dvb/frontends/lgdt3304.c2
-rw-r--r--drivers/media/dvb/frontends/s921_module.c2
-rw-r--r--drivers/media/dvb/pt1/Kconfig12
-rw-r--r--drivers/media/dvb/pt1/Makefile5
-rw-r--r--drivers/media/dvb/pt1/pt1.c1056
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.c658
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007s.h40
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.c468
-rw-r--r--drivers/media/dvb/pt1/va1j5jf8007t.h40
-rw-r--r--drivers/media/radio/Kconfig2
-rw-r--r--drivers/media/radio/radio-si4713.c1
-rw-r--r--drivers/media/video/Kconfig93
-rw-r--r--drivers/media/video/Makefile6
-rw-r--r--drivers/media/video/adv7180.c202
-rw-r--r--drivers/media/video/adv7343.c1
-rw-r--r--drivers/media/video/au0828/au0828-cards.c4
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c44
-rw-r--r--drivers/media/video/cafe_ccic.c2
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c16
-rw-r--r--drivers/media/video/cx18/cx18-streams.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c4
-rw-r--r--drivers/media/video/cx23885/cimax2.c12
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c14
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c1
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c5
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c6
-rw-r--r--drivers/media/video/cx23885/cx23885.h2
-rw-r--r--drivers/media/video/cx23885/netup-eeprom.c6
-rw-r--r--drivers/media/video/cx88/cx88-cards.c14
-rw-r--r--drivers/media/video/cx88/cx88-video.c6
-rw-r--r--drivers/media/video/davinci/Makefile17
-rw-r--r--drivers/media/video/davinci/ccdc_hw_device.h110
-rw-r--r--drivers/media/video/davinci/dm355_ccdc.c978
-rw-r--r--drivers/media/video/davinci/dm355_ccdc_regs.h310
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc.c878
-rw-r--r--drivers/media/video/davinci/dm644x_ccdc_regs.h145
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2124
-rw-r--r--drivers/media/video/davinci/vpif.c296
-rw-r--r--drivers/media/video/davinci/vpif.h642
-rw-r--r--drivers/media/video/davinci/vpif_capture.c2168
-rw-r--r--drivers/media/video/davinci/vpif_capture.h165
-rw-r--r--drivers/media/video/davinci/vpif_display.c1656
-rw-r--r--drivers/media/video/davinci/vpif_display.h175
-rw-r--r--drivers/media/video/davinci/vpss.c301
-rw-r--r--drivers/media/video/em28xx/Kconfig1
-rw-r--r--drivers/media/video/em28xx/Makefile2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c59
-rw-r--r--drivers/media/video/em28xx/em28xx-core.c51
-rw-r--r--drivers/media/video/em28xx/em28xx-dvb.c19
-rw-r--r--drivers/media/video/em28xx/em28xx-reg.h16
-rw-r--r--drivers/media/video/em28xx/em28xx-vbi.c142
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c589
-rw-r--r--drivers/media/video/em28xx/em28xx.h26
-rw-r--r--drivers/media/video/et61x251/et61x251_core.c6
-rw-r--r--drivers/media/video/gspca/Kconfig1
-rw-r--r--drivers/media/video/gspca/Makefile1
-rw-r--r--drivers/media/video/gspca/gl860/Kconfig8
-rw-r--r--drivers/media/video/gspca/gl860/Makefile10
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi1320.c537
-rw-r--r--drivers/media/video/gspca/gl860/gl860-mi2020.c937
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov2640.c505
-rw-r--r--drivers/media/video/gspca/gl860/gl860-ov9655.c337
-rw-r--r--drivers/media/video/gspca/gl860/gl860.c785
-rw-r--r--drivers/media/video/gspca/gl860/gl860.h108
-rw-r--r--drivers/media/video/gspca/jeilinj.c2
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.c262
-rw-r--r--drivers/media/video/gspca/m5602/m5602_ov7660.h138
-rw-r--r--drivers/media/video/gspca/m5602/m5602_s5k4aa.c13
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c19
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c151
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h2
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx_st6422.c15
-rw-r--r--drivers/media/video/gspca/vc032x.c7
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c18
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c4
-rw-r--r--drivers/media/video/mt9m001.c435
-rw-r--r--drivers/media/video/mt9m111.c524
-rw-r--r--drivers/media/video/mt9t031.c491
-rw-r--r--drivers/media/video/mt9v022.c434
-rw-r--r--drivers/media/video/mx1_camera.c78
-rw-r--r--drivers/media/video/mx3_camera.c207
-rw-r--r--drivers/media/video/mxb.c14
-rw-r--r--drivers/media/video/ov772x.c381
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c2
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c10
-rw-r--r--drivers/media/video/pxa_camera.c358
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c53
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c6
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c30
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c4
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa7164/Kconfig18
-rw-r--r--drivers/media/video/saa7164/Makefile12
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c600
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c155
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c448
-rw-r--r--drivers/media/video/saa7164/saa7164-cards.c624
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c572
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c740
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c602
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c613
-rw-r--r--drivers/media/video/saa7164/saa7164-i2c.c141
-rw-r--r--drivers/media/video/saa7164/saa7164-reg.h166
-rw-r--r--drivers/media/video/saa7164/saa7164-types.h287
-rw-r--r--drivers/media/video/saa7164/saa7164.h400
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c1062
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c6
-rw-r--r--drivers/media/video/soc_camera.c725
-rw-r--r--drivers/media/video/soc_camera_platform.c163
-rw-r--r--drivers/media/video/tuner-core.c12
-rw-r--r--drivers/media/video/tvp514x.c1030
-rw-r--r--drivers/media/video/tvp514x_regs.h10
-rw-r--r--drivers/media/video/tw9910.c361
-rw-r--r--drivers/media/video/usbvision/usbvision-i2c.c12
-rw-r--r--drivers/media/video/uvc/uvc_video.c7
-rw-r--r--drivers/media/video/v4l1-compat.c14
-rw-r--r--drivers/media/video/v4l2-common.c133
-rw-r--r--drivers/media/video/v4l2-dev.c154
-rw-r--r--drivers/media/video/vino.c8
-rw-r--r--drivers/media/video/w9968cf.c4
-rw-r--r--drivers/media/video/zc0301/zc0301_core.c6
-rw-r--r--drivers/media/video/zoran/zoran_card.c8
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/cx25821/Kconfig34
-rw-r--r--drivers/staging/cx25821/Makefile14
-rw-r--r--drivers/staging/cx25821/README6
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c789
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.c804
-rw-r--r--drivers/staging/cx25821/cx25821-audio-upstream.h57
-rw-r--r--drivers/staging/cx25821/cx25821-audio.h57
-rw-r--r--drivers/staging/cx25821/cx25821-audups11.c434
-rw-r--r--drivers/staging/cx25821/cx25821-biffuncs.h45
-rw-r--r--drivers/staging/cx25821/cx25821-cards.c70
-rw-r--r--drivers/staging/cx25821/cx25821-core.c1551
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.c98
-rw-r--r--drivers/staging/cx25821/cx25821-gpio.h2
-rw-r--r--drivers/staging/cx25821/cx25821-i2c.c419
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-defines.h51
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-reg.h455
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.c869
-rw-r--r--drivers/staging/cx25821/cx25821-medusa-video.h49
-rw-r--r--drivers/staging/cx25821/cx25821-reg.h1592
-rw-r--r--drivers/staging/cx25821/cx25821-sram.h261
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.c835
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream-ch2.h101
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.c894
-rw-r--r--drivers/staging/cx25821/cx25821-video-upstream.h109
-rw-r--r--drivers/staging/cx25821/cx25821-video.c1299
-rw-r--r--drivers/staging/cx25821/cx25821-video.h194
-rw-r--r--drivers/staging/cx25821/cx25821-video0.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video1.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video2.c452
-rw-r--r--drivers/staging/cx25821/cx25821-video3.c451
-rw-r--r--drivers/staging/cx25821/cx25821-video4.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video5.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video6.c450
-rw-r--r--drivers/staging/cx25821/cx25821-video7.c449
-rw-r--r--drivers/staging/cx25821/cx25821-videoioctl.c496
-rw-r--r--drivers/staging/cx25821/cx25821-vidups10.c435
-rw-r--r--drivers/staging/cx25821/cx25821-vidups9.c433
-rw-r--r--drivers/staging/cx25821/cx25821.h602
-rw-r--r--drivers/staging/go7007/Kconfig84
-rw-r--r--drivers/staging/go7007/Makefile20
-rw-r--r--drivers/staging/go7007/go7007-driver.c35
-rw-r--r--drivers/staging/go7007/go7007-fw.c3
-rw-r--r--drivers/staging/go7007/go7007-i2c.c12
-rw-r--r--drivers/staging/go7007/go7007-priv.h6
-rw-r--r--drivers/staging/go7007/go7007-usb.c58
-rw-r--r--drivers/staging/go7007/go7007-v4l2.c225
-rw-r--r--drivers/staging/go7007/go7007.txt176
-rw-r--r--drivers/staging/go7007/s2250-board.c107
-rw-r--r--drivers/staging/go7007/s2250-loader.c8
-rw-r--r--drivers/staging/go7007/snd-go7007.c2
-rw-r--r--drivers/staging/go7007/wis-tw9903.c3
-rw-r--r--include/linux/dvb/frontend.h46
-rw-r--r--include/linux/dvb/version.h2
-rw-r--r--include/linux/videodev2.h3
-rw-r--r--include/media/davinci/ccdc_types.h43
-rw-r--r--include/media/davinci/dm355_ccdc.h321
-rw-r--r--include/media/davinci/dm644x_ccdc.h184
-rw-r--r--include/media/davinci/vpfe_capture.h198
-rw-r--r--include/media/davinci/vpfe_types.h51
-rw-r--r--include/media/davinci/vpss.h69
-rw-r--r--include/media/soc_camera.h113
-rw-r--r--include/media/soc_camera_platform.h9
-rw-r--r--include/media/tuner.h2
-rw-r--r--include/media/tvp514x.h4
-rw-r--r--include/media/v4l2-chip-ident.h3
-rw-r--r--include/media/v4l2-common.h24
-rw-r--r--include/media/v4l2-dev.h6
361 files changed, 86808 insertions, 4033 deletions
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 9632444f6c62..ab8300f67182 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -14,7 +14,7 @@ DOCBOOKS := z8530book.xml mcabook.xml device-drivers.xml \
14 genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \ 14 genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
15 mac80211.xml debugobjects.xml sh.xml regulator.xml \ 15 mac80211.xml debugobjects.xml sh.xml regulator.xml \
16 alsa-driver-api.xml writing-an-alsa-driver.xml \ 16 alsa-driver-api.xml writing-an-alsa-driver.xml \
17 tracepoint.xml 17 tracepoint.xml media.xml
18 18
19### 19###
20# The build process is as follows (targets): 20# The build process is as follows (targets):
@@ -32,7 +32,7 @@ PS_METHOD = $(prefer-db2x)
32 32
33### 33###
34# The targets that may be used. 34# The targets that may be used.
35PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs 35PHONY += xmldocs sgmldocs psdocs pdfdocs htmldocs mandocs installmandocs cleandocs media
36 36
37BOOKS := $(addprefix $(obj)/,$(DOCBOOKS)) 37BOOKS := $(addprefix $(obj)/,$(DOCBOOKS))
38xmldocs: $(BOOKS) 38xmldocs: $(BOOKS)
@@ -45,12 +45,16 @@ PDF := $(patsubst %.xml, %.pdf, $(BOOKS))
45pdfdocs: $(PDF) 45pdfdocs: $(PDF)
46 46
47HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS))) 47HTML := $(sort $(patsubst %.xml, %.html, $(BOOKS)))
48htmldocs: $(HTML) 48htmldocs: media $(HTML)
49 $(call build_main_index) 49 $(call build_main_index)
50 50
51MAN := $(patsubst %.xml, %.9, $(BOOKS)) 51MAN := $(patsubst %.xml, %.9, $(BOOKS))
52mandocs: $(MAN) 52mandocs: $(MAN)
53 53
54media:
55 mkdir -p $(srctree)/Documentation/DocBook/media/
56 cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(srctree)/Documentation/DocBook/media/
57
54installmandocs: mandocs 58installmandocs: mandocs
55 mkdir -p /usr/local/man/man9/ 59 mkdir -p /usr/local/man/man9/
56 install Documentation/DocBook/man/*.9.gz /usr/local/man/man9/ 60 install Documentation/DocBook/man/*.9.gz /usr/local/man/man9/
diff --git a/Documentation/DocBook/dvb/.gitignore b/Documentation/DocBook/dvb/.gitignore
new file mode 100644
index 000000000000..d7ec32eafac9
--- /dev/null
+++ b/Documentation/DocBook/dvb/.gitignore
@@ -0,0 +1 @@
!*.xml
diff --git a/Documentation/DocBook/dvb/audio.xml b/Documentation/DocBook/dvb/audio.xml
new file mode 100644
index 000000000000..eeb96b8a0864
--- /dev/null
+++ b/Documentation/DocBook/dvb/audio.xml
@@ -0,0 +1,1473 @@
1<title>DVB Audio Device</title>
2<para>The DVB audio device controls the MPEG2 audio decoder of the DVB hardware. It
3can be accessed through <emphasis role="tt">/dev/dvb/adapter0/audio0</emphasis>. Data types and and
4ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
5application.
6</para>
7<para>Please note that some DVB cards don&#8217;t have their own MPEG decoder, which results in
8the omission of the audio and video device.
9</para>
10
11<section id="audio_data_types">
12<title>Audio Data Types</title>
13<para>This section describes the structures, data types and defines used when talking to the
14audio device.
15</para>
16
17<section id="audio_stream_source_t">
18<title>audio_stream_source_t</title>
19<para>The audio stream source is set through the AUDIO_SELECT_SOURCE call and can take
20the following values, depending on whether we are replaying from an internal (demux) or
21external (user write) source.
22</para>
23<programlisting>
24 typedef enum {
25 AUDIO_SOURCE_DEMUX,
26 AUDIO_SOURCE_MEMORY
27 } audio_stream_source_t;
28</programlisting>
29<para>AUDIO_SOURCE_DEMUX selects the demultiplexer (fed either by the frontend or the
30DVR device) as the source of the video stream. If AUDIO_SOURCE_MEMORY
31is selected the stream comes from the application through the <emphasis role="tt">write()</emphasis> system
32call.
33</para>
34
35</section>
36<section id="audio_play_state_t">
37<title>audio_play_state_t</title>
38<para>The following values can be returned by the AUDIO_GET_STATUS call representing the
39state of audio playback.
40</para>
41<programlisting>
42 typedef enum {
43 AUDIO_STOPPED,
44 AUDIO_PLAYING,
45 AUDIO_PAUSED
46 } audio_play_state_t;
47</programlisting>
48
49</section>
50<section id="audio_channel_select_t">
51<title>audio_channel_select_t</title>
52<para>The audio channel selected via AUDIO_CHANNEL_SELECT is determined by the
53following values.
54</para>
55<programlisting>
56 typedef enum {
57 AUDIO_STEREO,
58 AUDIO_MONO_LEFT,
59 AUDIO_MONO_RIGHT,
60 } audio_channel_select_t;
61</programlisting>
62
63</section>
64<section id="struct_audio_status">
65<title>struct audio_status</title>
66<para>The AUDIO_GET_STATUS call returns the following structure informing about various
67states of the playback operation.
68</para>
69<programlisting>
70 typedef struct audio_status {
71 boolean AV_sync_state;
72 boolean mute_state;
73 audio_play_state_t play_state;
74 audio_stream_source_t stream_source;
75 audio_channel_select_t channel_select;
76 boolean bypass_mode;
77 } audio_status_t;
78</programlisting>
79
80</section>
81<section id="struct_audio_mixer">
82<title>struct audio_mixer</title>
83<para>The following structure is used by the AUDIO_SET_MIXER call to set the audio
84volume.
85</para>
86<programlisting>
87 typedef struct audio_mixer {
88 unsigned int volume_left;
89 unsigned int volume_right;
90 } audio_mixer_t;
91</programlisting>
92
93</section>
94<section id="audio_encodings">
95<title>audio encodings</title>
96<para>A call to AUDIO_GET_CAPABILITIES returns an unsigned integer with the following
97bits set according to the hardwares capabilities.
98</para>
99<programlisting>
100 #define AUDIO_CAP_DTS 1
101 #define AUDIO_CAP_LPCM 2
102 #define AUDIO_CAP_MP1 4
103 #define AUDIO_CAP_MP2 8
104 #define AUDIO_CAP_MP3 16
105 #define AUDIO_CAP_AAC 32
106 #define AUDIO_CAP_OGG 64
107 #define AUDIO_CAP_SDDS 128
108 #define AUDIO_CAP_AC3 256
109</programlisting>
110
111</section>
112<section id="struct_audio_karaoke">
113<title>struct audio_karaoke</title>
114<para>The ioctl AUDIO_SET_KARAOKE uses the following format:
115</para>
116<programlisting>
117 typedef
118 struct audio_karaoke{
119 int vocal1;
120 int vocal2;
121 int melody;
122 } audio_karaoke_t;
123</programlisting>
124<para>If Vocal1 or Vocal2 are non-zero, they get mixed into left and right t at 70% each. If both,
125Vocal1 and Vocal2 are non-zero, Vocal1 gets mixed into the left channel and Vocal2 into the
126right channel at 100% each. Ff Melody is non-zero, the melody channel gets mixed into left
127and right.
128</para>
129
130</section>
131<section id="audio_attributes">
132<title>audio attributes</title>
133<para>The following attributes can be set by a call to AUDIO_SET_ATTRIBUTES:
134</para>
135<programlisting>
136 typedef uint16_t audio_attributes_t;
137 /&#x22C6; bits: descr. &#x22C6;/
138 /&#x22C6; 15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, &#x22C6;/
139 /&#x22C6; 12 multichannel extension &#x22C6;/
140 /&#x22C6; 11-10 audio type (0=not spec, 1=language included) &#x22C6;/
141 /&#x22C6; 9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) &#x22C6;/
142 /&#x22C6; 7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit, &#x22C6;/
143 /&#x22C6; 5- 4 Sample frequency fs (0=48kHz, 1=96kHz) &#x22C6;/
144 /&#x22C6; 2- 0 number of audio channels (n+1 channels) &#x22C6;/
145</programlisting>
146 </section></section>
147<section id="audio_function_calls">
148<title>Audio Function Calls</title>
149
150
151<section id="audio_fopen">
152<title>open()</title>
153<para>DESCRIPTION
154</para>
155<informaltable><tgroup cols="1"><tbody><row><entry
156 align="char">
157<para>This system call opens a named audio device (e.g. /dev/dvb/adapter0/audio0)
158 for subsequent use. When an open() call has succeeded, the device will be ready
159 for use. The significance of blocking or non-blocking mode is described in the
160 documentation for functions where there is a difference. It does not affect the
161 semantics of the open() call itself. A device opened in blocking mode can later
162 be put into non-blocking mode (and vice versa) using the F_SETFL command
163 of the fcntl system call. This is a standard system call, documented in the Linux
164 manual page for fcntl. Only one user can open the Audio Device in O_RDWR
165 mode. All other attempts to open the device in this mode will fail, and an error
166 code will be returned. If the Audio Device is opened in O_RDONLY mode, the
167 only ioctl call that can be used is AUDIO_GET_STATUS. All other call will
168 return with an error code.</para>
169</entry>
170 </row></tbody></tgroup></informaltable>
171<para>SYNOPSIS
172</para>
173<informaltable><tgroup cols="1"><tbody><row><entry
174 align="char">
175<para>int open(const char &#x22C6;deviceName, int flags);</para>
176</entry>
177 </row></tbody></tgroup></informaltable>
178<para>PARAMETERS
179</para>
180<informaltable><tgroup cols="2"><tbody><row><entry
181 align="char">
182<para>const char
183 *deviceName</para>
184</entry><entry
185 align="char">
186<para>Name of specific audio device.</para>
187</entry>
188 </row><row><entry
189 align="char">
190<para>int flags</para>
191</entry><entry
192 align="char">
193<para>A bit-wise OR of the following flags:</para>
194</entry>
195 </row><row><entry
196 align="char">
197</entry><entry
198 align="char">
199<para>O_RDONLY read-only access</para>
200</entry>
201 </row><row><entry
202 align="char">
203</entry><entry
204 align="char">
205<para>O_RDWR read/write access</para>
206</entry>
207 </row><row><entry
208 align="char">
209</entry><entry
210 align="char">
211<para>O_NONBLOCK open in non-blocking mode</para>
212</entry>
213 </row><row><entry
214 align="char">
215</entry><entry
216 align="char">
217<para>(blocking mode is the default)</para>
218</entry>
219 </row></tbody></tgroup></informaltable>
220<para>ERRORS
221</para>
222<informaltable><tgroup cols="2"><tbody><row><entry
223 align="char">
224<para>ENODEV</para>
225</entry><entry
226 align="char">
227<para>Device driver not loaded/available.</para>
228</entry>
229 </row><row><entry
230 align="char">
231<para>EINTERNAL</para>
232</entry><entry
233 align="char">
234<para>Internal error.</para>
235</entry>
236 </row><row><entry
237 align="char">
238<para>EBUSY</para>
239</entry><entry
240 align="char">
241<para>Device or resource busy.</para>
242</entry>
243 </row><row><entry
244 align="char">
245<para>EINVAL</para>
246</entry><entry
247 align="char">
248<para>Invalid argument.</para>
249</entry>
250 </row></tbody></tgroup></informaltable>
251
252</section>
253<section id="audio_fclose">
254<title>close()</title>
255<para>DESCRIPTION
256</para>
257<informaltable><tgroup cols="1"><tbody><row><entry
258 align="char">
259<para>This system call closes a previously opened audio device.</para>
260</entry>
261 </row></tbody></tgroup></informaltable>
262<para>SYNOPSIS
263</para>
264<informaltable><tgroup cols="1"><tbody><row><entry
265 align="char">
266<para>int close(int fd);</para>
267</entry>
268 </row></tbody></tgroup></informaltable>
269<para>PARAMETERS
270</para>
271<informaltable><tgroup cols="2"><tbody><row><entry
272 align="char">
273<para>int fd</para>
274</entry><entry
275 align="char">
276<para>File descriptor returned by a previous call to open().</para>
277</entry>
278 </row></tbody></tgroup></informaltable>
279<para>ERRORS
280</para>
281<informaltable><tgroup cols="2"><tbody><row><entry
282 align="char">
283<para>EBADF</para>
284</entry><entry
285 align="char">
286<para>fd is not a valid open file descriptor.</para>
287</entry>
288 </row></tbody></tgroup></informaltable>
289
290</section>
291<section id="audio_fwrite">
292<title>write()</title>
293<para>DESCRIPTION
294</para>
295<informaltable><tgroup cols="1"><tbody><row><entry
296 align="char">
297<para>This system call can only be used if AUDIO_SOURCE_MEMORY is selected
298 in the ioctl call AUDIO_SELECT_SOURCE. The data provided shall be in
299 PES format. If O_NONBLOCK is not specified the function will block until
300 buffer space is available. The amount of data to be transferred is implied by
301 count.</para>
302</entry>
303 </row></tbody></tgroup></informaltable>
304<para>SYNOPSIS
305</para>
306<informaltable><tgroup cols="1"><tbody><row><entry
307 align="char">
308<para>size_t write(int fd, const void &#x22C6;buf, size_t count);</para>
309</entry>
310 </row></tbody></tgroup></informaltable>
311<para>PARAMETERS
312</para>
313<informaltable><tgroup cols="2"><tbody><row><entry
314 align="char">
315<para>int fd</para>
316</entry><entry
317 align="char">
318<para>File descriptor returned by a previous call to open().</para>
319</entry>
320 </row><row><entry
321 align="char">
322<para>void *buf</para>
323</entry><entry
324 align="char">
325<para>Pointer to the buffer containing the PES data.</para>
326</entry>
327 </row><row><entry
328 align="char">
329<para>size_t count</para>
330</entry><entry
331 align="char">
332<para>Size of buf.</para>
333</entry>
334 </row></tbody></tgroup></informaltable>
335<para>ERRORS
336</para>
337<informaltable><tgroup cols="2"><tbody><row><entry
338 align="char">
339<para>EPERM</para>
340</entry><entry
341 align="char">
342<para>Mode AUDIO_SOURCE_MEMORY not selected.</para>
343</entry>
344 </row><row><entry
345 align="char">
346<para>ENOMEM</para>
347</entry><entry
348 align="char">
349<para>Attempted to write more data than the internal buffer can
350 hold.</para>
351</entry>
352 </row><row><entry
353 align="char">
354<para>EBADF</para>
355</entry><entry
356 align="char">
357<para>fd is not a valid open file descriptor.</para>
358</entry>
359 </row></tbody></tgroup></informaltable>
360
361</section><section
362role="subsection"><title>AUDIO_STOP</title>
363<para>DESCRIPTION
364</para>
365<informaltable><tgroup cols="1"><tbody><row><entry
366 align="char">
367<para>This ioctl call asks the Audio Device to stop playing the current stream.</para>
368</entry>
369 </row></tbody></tgroup></informaltable>
370<para>SYNOPSIS
371</para>
372<informaltable><tgroup cols="1"><tbody><row><entry
373 align="char">
374<para>int ioctl(int fd, int request = AUDIO_STOP);</para>
375</entry>
376 </row></tbody></tgroup></informaltable>
377<para>PARAMETERS
378</para>
379<informaltable><tgroup cols="2"><tbody><row><entry
380 align="char">
381<para>int fd</para>
382</entry><entry
383 align="char">
384<para>File descriptor returned by a previous call to open().</para>
385</entry>
386 </row><row><entry
387 align="char">
388<para>int request</para>
389</entry><entry
390 align="char">
391<para>Equals AUDIO_STOP for this command.</para>
392</entry>
393 </row></tbody></tgroup></informaltable>
394<para>ERRORS
395</para>
396<informaltable><tgroup cols="2"><tbody><row><entry
397 align="char">
398<para>EBADF</para>
399</entry><entry
400 align="char">
401<para>fd is not a valid open file descriptor</para>
402</entry>
403 </row><row><entry
404 align="char">
405<para>EINTERNAL</para>
406</entry><entry
407 align="char">
408<para>Internal error.</para>
409</entry>
410 </row></tbody></tgroup></informaltable>
411
412</section><section
413role="subsection"><title>AUDIO_PLAY</title>
414<para>DESCRIPTION
415</para>
416<informaltable><tgroup cols="1"><tbody><row><entry
417 align="char">
418<para>This ioctl call asks the Audio Device to start playing an audio stream from the
419 selected source.</para>
420</entry>
421 </row></tbody></tgroup></informaltable>
422<para>SYNOPSIS
423</para>
424<informaltable><tgroup cols="1"><tbody><row><entry
425 align="char">
426<para>int ioctl(int fd, int request = AUDIO_PLAY);</para>
427</entry>
428 </row></tbody></tgroup></informaltable>
429<para>PARAMETERS
430</para>
431<informaltable><tgroup cols="2"><tbody><row><entry
432 align="char">
433<para>int fd</para>
434</entry><entry
435 align="char">
436<para>File descriptor returned by a previous call to open().</para>
437</entry>
438 </row><row><entry
439 align="char">
440<para>int request</para>
441</entry><entry
442 align="char">
443<para>Equals AUDIO_PLAY for this command.</para>
444</entry>
445 </row></tbody></tgroup></informaltable>
446<para>ERRORS
447</para>
448<informaltable><tgroup cols="2"><tbody><row><entry
449 align="char">
450<para>EBADF</para>
451</entry><entry
452 align="char">
453<para>fd is not a valid open file descriptor</para>
454</entry>
455 </row><row><entry
456 align="char">
457<para>EINTERNAL</para>
458</entry><entry
459 align="char">
460<para>Internal error.</para>
461</entry>
462 </row></tbody></tgroup></informaltable>
463
464</section><section
465role="subsection"><title>AUDIO_PAUSE</title>
466<para>DESCRIPTION
467</para>
468<informaltable><tgroup cols="1"><tbody><row><entry
469 align="char">
470<para>This ioctl call suspends the audio stream being played. Decoding and playing
471 are paused. It is then possible to restart again decoding and playing process of
472 the audio stream using AUDIO_CONTINUE command.</para>
473</entry>
474 </row><row><entry
475 align="char">
476<para>If AUDIO_SOURCE_MEMORY is selected in the ioctl call
477 AUDIO_SELECT_SOURCE, the DVB-subsystem will not decode (consume)
478 any more data until the ioctl call AUDIO_CONTINUE or AUDIO_PLAY is
479 performed.</para>
480</entry>
481 </row></tbody></tgroup></informaltable>
482<para>SYNOPSIS
483</para>
484<informaltable><tgroup cols="1"><tbody><row><entry
485 align="char">
486<para>int ioctl(int fd, int request = AUDIO_PAUSE);</para>
487</entry>
488 </row></tbody></tgroup></informaltable>
489<para>PARAMETERS
490</para>
491<informaltable><tgroup cols="2"><tbody><row><entry
492 align="char">
493<para>int fd</para>
494</entry><entry
495 align="char">
496<para>File descriptor returned by a previous call to open().</para>
497</entry>
498 </row><row><entry
499 align="char">
500<para>int request</para>
501</entry><entry
502 align="char">
503<para>Equals AUDIO_PAUSE for this command.</para>
504</entry>
505 </row></tbody></tgroup></informaltable>
506<para>ERRORS
507</para>
508<informaltable><tgroup cols="2"><tbody><row><entry
509 align="char">
510<para>EBADF</para>
511</entry><entry
512 align="char">
513<para>fd is not a valid open file descriptor.</para>
514</entry>
515 </row><row><entry
516 align="char">
517<para>EINTERNAL</para>
518</entry><entry
519 align="char">
520<para>Internal error.</para>
521</entry>
522 </row></tbody></tgroup></informaltable>
523
524</section><section
525role="subsection"><title>AUDIO_SELECT_SOURCE</title>
526<para>DESCRIPTION
527</para>
528<informaltable><tgroup cols="1"><tbody><row><entry
529 align="char">
530<para>This ioctl call informs the audio device which source shall be used
531 for the input data. The possible sources are demux or memory. If
532 AUDIO_SOURCE_MEMORY is selected, the data is fed to the Audio Device
533 through the write command.</para>
534</entry>
535 </row></tbody></tgroup></informaltable>
536<para>SYNOPSIS
537</para>
538<informaltable><tgroup cols="1"><tbody><row><entry
539 align="char">
540<para>int ioctl(int fd, int request = AUDIO_SELECT_SOURCE,
541 audio_stream_source_t source);</para>
542</entry>
543 </row></tbody></tgroup></informaltable>
544<para>PARAMETERS
545</para>
546<informaltable><tgroup cols="2"><tbody><row><entry
547 align="char">
548<para>int fd</para>
549</entry><entry
550 align="char">
551<para>File descriptor returned by a previous call to open().</para>
552</entry>
553 </row><row><entry
554 align="char">
555<para>int request</para>
556</entry><entry
557 align="char">
558<para>Equals AUDIO_SELECT_SOURCE for this command.</para>
559</entry>
560 </row><row><entry
561 align="char">
562<para>audio_stream_source_t
563 source</para>
564</entry><entry
565 align="char">
566<para>Indicates the source that shall be used for the Audio
567 stream.</para>
568</entry>
569 </row></tbody></tgroup></informaltable>
570<para>ERRORS
571</para>
572<informaltable><tgroup cols="2"><tbody><row><entry
573 align="char">
574<para>EBADF</para>
575</entry><entry
576 align="char">
577<para>fd is not a valid open file descriptor.</para>
578</entry>
579 </row><row><entry
580 align="char">
581<para>EINTERNAL</para>
582</entry><entry
583 align="char">
584<para>Internal error.</para>
585</entry>
586 </row><row><entry
587 align="char">
588<para>EINVAL</para>
589</entry><entry
590 align="char">
591<para>Illegal input parameter.</para>
592</entry>
593 </row></tbody></tgroup></informaltable>
594
595</section><section
596role="subsection"><title>AUDIO_SET_MUTE</title>
597<para>DESCRIPTION
598</para>
599<informaltable><tgroup cols="1"><tbody><row><entry
600 align="char">
601<para>This ioctl call asks the audio device to mute the stream that is currently being
602 played.</para>
603</entry>
604 </row></tbody></tgroup></informaltable>
605<para>SYNOPSIS
606</para>
607<informaltable><tgroup cols="1"><tbody><row><entry
608 align="char">
609<para>int ioctl(int fd, int request = AUDIO_SET_MUTE,
610 boolean state);</para>
611</entry>
612 </row></tbody></tgroup></informaltable>
613<para>PARAMETERS
614</para>
615<informaltable><tgroup cols="2"><tbody><row><entry
616 align="char">
617<para>int fd</para>
618</entry><entry
619 align="char">
620<para>File descriptor returned by a previous call to open().</para>
621</entry>
622 </row><row><entry
623 align="char">
624<para>int request</para>
625</entry><entry
626 align="char">
627<para>Equals AUDIO_SET_MUTE for this command.</para>
628</entry>
629 </row><row><entry
630 align="char">
631<para>boolean state</para>
632</entry><entry
633 align="char">
634<para>Indicates if audio device shall mute or not.</para>
635</entry>
636 </row><row><entry
637 align="char">
638</entry><entry
639 align="char">
640<para>TRUE Audio Mute</para>
641</entry>
642 </row><row><entry
643 align="char">
644</entry><entry
645 align="char">
646<para>FALSE Audio Un-mute</para>
647</entry>
648 </row></tbody></tgroup></informaltable>
649<para>ERRORS
650</para>
651<informaltable><tgroup cols="2"><tbody><row><entry
652 align="char">
653<para>EBADF</para>
654</entry><entry
655 align="char">
656<para>fd is not a valid open file descriptor.</para>
657</entry>
658 </row><row><entry
659 align="char">
660<para>EINTERNAL</para>
661</entry><entry
662 align="char">
663<para>Internal error.</para>
664</entry>
665 </row><row><entry
666 align="char">
667<para>EINVAL</para>
668</entry><entry
669 align="char">
670<para>Illegal input parameter.</para>
671</entry>
672 </row></tbody></tgroup></informaltable>
673
674</section><section
675role="subsection"><title>AUDIO_SET_AV_SYNC</title>
676<para>DESCRIPTION
677</para>
678<informaltable><tgroup cols="1"><tbody><row><entry
679 align="char">
680<para>This ioctl call asks the Audio Device to turn ON or OFF A/V synchronization.</para>
681</entry>
682 </row></tbody></tgroup></informaltable>
683<para>SYNOPSIS
684</para>
685<informaltable><tgroup cols="1"><tbody><row><entry
686 align="char">
687<para>int ioctl(int fd, int request = AUDIO_SET_AV_SYNC,
688 boolean state);</para>
689</entry>
690 </row></tbody></tgroup></informaltable>
691<para>PARAMETERS
692</para>
693<informaltable><tgroup cols="2"><tbody><row><entry
694 align="char">
695<para>int fd</para>
696</entry><entry
697 align="char">
698<para>File descriptor returned by a previous call to open().</para>
699</entry>
700 </row><row><entry
701 align="char">
702<para>int request</para>
703</entry><entry
704 align="char">
705<para>Equals AUDIO_AV_SYNC for this command.</para>
706</entry>
707 </row><row><entry
708 align="char">
709<para>boolean state</para>
710</entry><entry
711 align="char">
712<para>Tells the DVB subsystem if A/V synchronization shall be
713 ON or OFF.</para>
714</entry>
715 </row><row><entry
716 align="char">
717</entry><entry
718 align="char">
719<para>TRUE AV-sync ON</para>
720</entry>
721 </row><row><entry
722 align="char">
723</entry><entry
724 align="char">
725<para>FALSE AV-sync OFF</para>
726</entry>
727 </row></tbody></tgroup></informaltable>
728<para>ERRORS
729</para>
730<informaltable><tgroup cols="2"><tbody><row><entry
731 align="char">
732<para>EBADF</para>
733</entry><entry
734 align="char">
735<para>fd is not a valid open file descriptor.</para>
736</entry>
737 </row><row><entry
738 align="char">
739<para>EINTERNAL</para>
740</entry><entry
741 align="char">
742<para>Internal error.</para>
743</entry>
744 </row><row><entry
745 align="char">
746<para>EINVAL</para>
747</entry><entry
748 align="char">
749<para>Illegal input parameter.</para>
750</entry>
751 </row></tbody></tgroup></informaltable>
752
753</section><section
754role="subsection"><title>AUDIO_SET_BYPASS_MODE</title>
755<para>DESCRIPTION
756</para>
757<informaltable><tgroup cols="1"><tbody><row><entry
758 align="char">
759<para>This ioctl call asks the Audio Device to bypass the Audio decoder and forward
760 the stream without decoding. This mode shall be used if streams that can&#8217;t be
761 handled by the DVB system shall be decoded. Dolby DigitalTM streams are
762 automatically forwarded by the DVB subsystem if the hardware can handle it.</para>
763</entry>
764 </row></tbody></tgroup></informaltable>
765<para>SYNOPSIS
766</para>
767<informaltable><tgroup cols="1"><tbody><row><entry
768 align="char">
769<para>int ioctl(int fd, int request =
770 AUDIO_SET_BYPASS_MODE, boolean mode);</para>
771</entry>
772 </row></tbody></tgroup></informaltable>
773<para>PARAMETERS
774</para>
775<informaltable><tgroup cols="2"><tbody><row><entry
776 align="char">
777<para>int fd</para>
778</entry><entry
779 align="char">
780<para>File descriptor returned by a previous call to open().</para>
781</entry>
782 </row><row><entry
783 align="char">
784<para>int request</para>
785</entry><entry
786 align="char">
787<para>Equals AUDIO_SET_BYPASS_MODE for this
788 command.</para>
789</entry>
790 </row><row><entry
791 align="char">
792<para>boolean mode</para>
793</entry><entry
794 align="char">
795<para>Enables or disables the decoding of the current Audio
796 stream in the DVB subsystem.</para>
797</entry>
798 </row><row><entry
799 align="char">
800</entry><entry
801 align="char">
802<para>TRUE Bypass is disabled</para>
803</entry>
804 </row><row><entry
805 align="char">
806</entry><entry
807 align="char">
808<para>FALSE Bypass is enabled</para>
809</entry>
810 </row></tbody></tgroup></informaltable>
811<para>ERRORS
812</para>
813<informaltable><tgroup cols="2"><tbody><row><entry
814 align="char">
815<para>EBADF</para>
816</entry><entry
817 align="char">
818<para>fd is not a valid open file descriptor.</para>
819</entry>
820 </row><row><entry
821 align="char">
822<para>EINTERNAL</para>
823</entry><entry
824 align="char">
825<para>Internal error.</para>
826</entry>
827 </row><row><entry
828 align="char">
829<para>EINVAL</para>
830</entry><entry
831 align="char">
832<para>Illegal input parameter.</para>
833</entry>
834 </row></tbody></tgroup></informaltable>
835
836</section><section
837role="subsection"><title>AUDIO_CHANNEL_SELECT</title>
838<para>DESCRIPTION
839</para>
840<informaltable><tgroup cols="1"><tbody><row><entry
841 align="char">
842<para>This ioctl call asks the Audio Device to select the requested channel if possible.</para>
843</entry>
844 </row></tbody></tgroup></informaltable>
845<para>SYNOPSIS
846</para>
847<informaltable><tgroup cols="1"><tbody><row><entry
848 align="char">
849<para>int ioctl(int fd, int request =
850 AUDIO_CHANNEL_SELECT, audio_channel_select_t);</para>
851</entry>
852 </row></tbody></tgroup></informaltable>
853<para>PARAMETERS
854</para>
855<informaltable><tgroup cols="2"><tbody><row><entry
856 align="char">
857<para>int fd</para>
858</entry><entry
859 align="char">
860<para>File descriptor returned by a previous call to open().</para>
861</entry>
862 </row><row><entry
863 align="char">
864<para>int request</para>
865</entry><entry
866 align="char">
867<para>Equals AUDIO_CHANNEL_SELECT for this
868 command.</para>
869</entry>
870 </row><row><entry
871 align="char">
872<para>audio_channel_select_t
873 ch</para>
874</entry><entry
875 align="char">
876<para>Select the output format of the audio (mono left/right,
877 stereo).</para>
878</entry>
879 </row></tbody></tgroup></informaltable>
880<para>ERRORS
881</para>
882<informaltable><tgroup cols="2"><tbody><row><entry
883 align="char">
884<para>EBADF</para>
885</entry><entry
886 align="char">
887<para>fd is not a valid open file descriptor.</para>
888</entry>
889 </row><row><entry
890 align="char">
891<para>EINTERNAL</para>
892</entry><entry
893 align="char">
894<para>Internal error.</para>
895</entry>
896 </row><row><entry
897 align="char">
898<para>EINVAL</para>
899</entry><entry
900 align="char">
901<para>Illegal input parameter ch.</para>
902</entry>
903 </row></tbody></tgroup></informaltable>
904
905</section><section
906role="subsection"><title>AUDIO_GET_STATUS</title>
907<para>DESCRIPTION
908</para>
909<informaltable><tgroup cols="1"><tbody><row><entry
910 align="char">
911<para>This ioctl call asks the Audio Device to return the current state of the Audio
912 Device.</para>
913</entry>
914 </row></tbody></tgroup></informaltable>
915<para>SYNOPSIS
916</para>
917<informaltable><tgroup cols="1"><tbody><row><entry
918 align="char">
919<para>int ioctl(int fd, int request = AUDIO_GET_STATUS,
920 struct audio_status &#x22C6;status);</para>
921</entry>
922 </row></tbody></tgroup></informaltable>
923<para>PARAMETERS
924</para>
925<informaltable><tgroup cols="2"><tbody><row><entry
926 align="char">
927<para>int fd</para>
928</entry><entry
929 align="char">
930<para>File descriptor returned by a previous call to open().</para>
931</entry>
932 </row><row><entry
933 align="char">
934<para>int request</para>
935</entry><entry
936 align="char">
937<para>Equals AUDIO_GET_STATUS for this command.</para>
938</entry>
939 </row><row><entry
940 align="char">
941<para>struct audio_status
942 *status</para>
943</entry><entry
944 align="char">
945<para>Returns the current state of Audio Device.</para>
946</entry>
947 </row></tbody></tgroup></informaltable>
948<para>ERRORS
949</para>
950<informaltable><tgroup cols="2"><tbody><row><entry
951 align="char">
952<para>EBADF</para>
953</entry><entry
954 align="char">
955<para>fd is not a valid open file descriptor.</para>
956</entry>
957 </row><row><entry
958 align="char">
959<para>EINTERNAL</para>
960</entry><entry
961 align="char">
962<para>Internal error.</para>
963</entry>
964 </row><row><entry
965 align="char">
966<para>EFAULT</para>
967</entry><entry
968 align="char">
969<para>status points to invalid address.</para>
970</entry>
971 </row></tbody></tgroup></informaltable>
972
973</section><section
974role="subsection"><title>AUDIO_GET_CAPABILITIES</title>
975<para>DESCRIPTION
976</para>
977<informaltable><tgroup cols="1"><tbody><row><entry
978 align="char">
979<para>This ioctl call asks the Audio Device to tell us about the decoding capabilities
980 of the audio hardware.</para>
981</entry>
982 </row></tbody></tgroup></informaltable>
983<para>SYNOPSIS
984</para>
985<informaltable><tgroup cols="1"><tbody><row><entry
986 align="char">
987<para>int ioctl(int fd, int request =
988 AUDIO_GET_CAPABILITIES, unsigned int &#x22C6;cap);</para>
989</entry>
990 </row></tbody></tgroup></informaltable>
991<para>PARAMETERS
992</para>
993<informaltable><tgroup cols="2"><tbody><row><entry
994 align="char">
995<para>int fd</para>
996</entry><entry
997 align="char">
998<para>File descriptor returned by a previous call to open().</para>
999</entry>
1000 </row><row><entry
1001 align="char">
1002<para>int request</para>
1003</entry><entry
1004 align="char">
1005<para>Equals AUDIO_GET_CAPABILITIES for this
1006 command.</para>
1007</entry>
1008 </row><row><entry
1009 align="char">
1010<para>unsigned int *cap</para>
1011</entry><entry
1012 align="char">
1013<para>Returns a bit array of supported sound formats.</para>
1014</entry>
1015 </row></tbody></tgroup></informaltable>
1016<para>ERRORS
1017</para>
1018<informaltable><tgroup cols="2"><tbody><row><entry
1019 align="char">
1020<para>EBADF</para>
1021</entry><entry
1022 align="char">
1023<para>fd is not a valid open file descriptor.</para>
1024</entry>
1025 </row><row><entry
1026 align="char">
1027<para>EINTERNAL</para>
1028</entry><entry
1029 align="char">
1030<para>Internal error.</para>
1031</entry>
1032 </row><row><entry
1033 align="char">
1034<para>EFAULT</para>
1035</entry><entry
1036 align="char">
1037<para>cap points to an invalid address.</para>
1038</entry>
1039 </row></tbody></tgroup></informaltable>
1040
1041</section><section
1042role="subsection"><title>AUDIO_CLEAR_BUFFER</title>
1043<para>DESCRIPTION
1044</para>
1045<informaltable><tgroup cols="1"><tbody><row><entry
1046 align="char">
1047<para>This ioctl call asks the Audio Device to clear all software and hardware buffers
1048 of the audio decoder device.</para>
1049</entry>
1050 </row></tbody></tgroup></informaltable>
1051<para>SYNOPSIS
1052</para>
1053<informaltable><tgroup cols="1"><tbody><row><entry
1054 align="char">
1055<para>int ioctl(int fd, int request = AUDIO_CLEAR_BUFFER);</para>
1056</entry>
1057 </row></tbody></tgroup></informaltable>
1058<para>PARAMETERS
1059</para>
1060<informaltable><tgroup cols="2"><tbody><row><entry
1061 align="char">
1062<para>int fd</para>
1063</entry><entry
1064 align="char">
1065<para>File descriptor returned by a previous call to open().</para>
1066</entry>
1067 </row><row><entry
1068 align="char">
1069<para>int request</para>
1070</entry><entry
1071 align="char">
1072<para>Equals AUDIO_CLEAR_BUFFER for this command.</para>
1073</entry>
1074 </row></tbody></tgroup></informaltable>
1075<para>ERRORS
1076</para>
1077<informaltable><tgroup cols="2"><tbody><row><entry
1078 align="char">
1079<para>EBADF</para>
1080</entry><entry
1081 align="char">
1082<para>fd is not a valid open file descriptor.</para>
1083</entry>
1084 </row><row><entry
1085 align="char">
1086<para>EINTERNAL</para>
1087</entry><entry
1088 align="char">
1089<para>Internal error.</para>
1090</entry>
1091 </row></tbody></tgroup></informaltable>
1092
1093</section><section
1094role="subsection"><title>AUDIO_SET_ID</title>
1095<para>DESCRIPTION
1096</para>
1097<informaltable><tgroup cols="1"><tbody><row><entry
1098 align="char">
1099<para>This ioctl selects which sub-stream is to be decoded if a program or system
1100 stream is sent to the video device. If no audio stream type is set the id has to be
1101 in [0xC0,0xDF] for MPEG sound, in [0x80,0x87] for AC3 and in [0xA0,0xA7]
1102 for LPCM. More specifications may follow for other stream types. If the stream
1103 type is set the id just specifies the substream id of the audio stream and only
1104 the first 5 bits are recognized.</para>
1105</entry>
1106 </row></tbody></tgroup></informaltable>
1107<para>SYNOPSIS
1108</para>
1109<informaltable><tgroup cols="1"><tbody><row><entry
1110 align="char">
1111<para>int ioctl(int fd, int request = AUDIO_SET_ID, int
1112 id);</para>
1113</entry>
1114 </row></tbody></tgroup></informaltable>
1115<para>PARAMETERS
1116</para>
1117<informaltable><tgroup cols="2"><tbody><row><entry
1118 align="char">
1119<para>int fd</para>
1120</entry><entry
1121 align="char">
1122<para>File descriptor returned by a previous call to open().</para>
1123</entry>
1124 </row><row><entry
1125 align="char">
1126<para>int request</para>
1127</entry><entry
1128 align="char">
1129<para>Equals AUDIO_SET_ID for this command.</para>
1130</entry>
1131 </row><row><entry
1132 align="char">
1133<para>int id</para>
1134</entry><entry
1135 align="char">
1136<para>audio sub-stream id</para>
1137</entry>
1138 </row></tbody></tgroup></informaltable>
1139<para>ERRORS
1140</para>
1141<informaltable><tgroup cols="2"><tbody><row><entry
1142 align="char">
1143<para>EBADF</para>
1144</entry><entry
1145 align="char">
1146<para>fd is not a valid open file descriptor.</para>
1147</entry>
1148 </row><row><entry
1149 align="char">
1150<para>EINTERNAL</para>
1151</entry><entry
1152 align="char">
1153<para>Internal error.</para>
1154</entry>
1155 </row><row><entry
1156 align="char">
1157<para>EINVAL</para>
1158</entry><entry
1159 align="char">
1160<para>Invalid sub-stream id.</para>
1161</entry>
1162 </row></tbody></tgroup></informaltable>
1163
1164</section><section
1165role="subsection"><title>AUDIO_SET_MIXER</title>
1166<para>DESCRIPTION
1167</para>
1168<informaltable><tgroup cols="1"><tbody><row><entry
1169 align="char">
1170<para>This ioctl lets you adjust the mixer settings of the audio decoder.</para>
1171</entry>
1172 </row></tbody></tgroup></informaltable>
1173<para>SYNOPSIS
1174</para>
1175<informaltable><tgroup cols="1"><tbody><row><entry
1176 align="char">
1177<para>int ioctl(int fd, int request = AUDIO_SET_MIXER,
1178 audio_mixer_t &#x22C6;mix);</para>
1179</entry>
1180 </row></tbody></tgroup></informaltable>
1181<para>PARAMETERS
1182</para>
1183<informaltable><tgroup cols="2"><tbody><row><entry
1184 align="char">
1185<para>int fd</para>
1186</entry><entry
1187 align="char">
1188<para>File descriptor returned by a previous call to open().</para>
1189</entry>
1190 </row><row><entry
1191 align="char">
1192<para>int request</para>
1193</entry><entry
1194 align="char">
1195<para>Equals AUDIO_SET_ID for this command.</para>
1196</entry>
1197 </row><row><entry
1198 align="char">
1199<para>audio_mixer_t *mix</para>
1200</entry><entry
1201 align="char">
1202<para>mixer settings.</para>
1203</entry>
1204 </row></tbody></tgroup></informaltable>
1205<para>ERRORS
1206</para>
1207<informaltable><tgroup cols="2"><tbody><row><entry
1208 align="char">
1209<para>EBADF</para>
1210</entry><entry
1211 align="char">
1212<para>fd is not a valid open file descriptor.</para>
1213</entry>
1214 </row><row><entry
1215 align="char">
1216<para>EINTERNAL</para>
1217</entry><entry
1218 align="char">
1219<para>Internal error.</para>
1220</entry>
1221 </row><row><entry
1222 align="char">
1223<para>EFAULT</para>
1224</entry><entry
1225 align="char">
1226<para>mix points to an invalid address.</para>
1227</entry>
1228 </row></tbody></tgroup></informaltable>
1229
1230</section><section
1231role="subsection"><title>AUDIO_SET_STREAMTYPE</title>
1232<para>DESCRIPTION
1233</para>
1234<informaltable><tgroup cols="1"><tbody><row><entry
1235 align="char">
1236<para>This ioctl tells the driver which kind of audio stream to expect. This is useful
1237 if the stream offers several audio sub-streams like LPCM and AC3.</para>
1238</entry>
1239 </row></tbody></tgroup></informaltable>
1240<para>SYNOPSIS
1241</para>
1242<informaltable><tgroup cols="1"><tbody><row><entry
1243 align="char">
1244<para>int ioctl(fd, int request = AUDIO_SET_STREAMTYPE,
1245 int type);</para>
1246</entry>
1247 </row></tbody></tgroup></informaltable>
1248<para>PARAMETERS
1249</para>
1250<informaltable><tgroup cols="2"><tbody><row><entry
1251 align="char">
1252<para>int fd</para>
1253</entry><entry
1254 align="char">
1255<para>File descriptor returned by a previous call to open().</para>
1256</entry>
1257 </row><row><entry
1258 align="char">
1259<para>int request</para>
1260</entry><entry
1261 align="char">
1262<para>Equals AUDIO_SET_STREAMTYPE for this
1263 command.</para>
1264</entry>
1265 </row><row><entry
1266 align="char">
1267<para>int type</para>
1268</entry><entry
1269 align="char">
1270<para>stream type</para>
1271</entry>
1272 </row></tbody></tgroup></informaltable>
1273<para>ERRORS
1274</para>
1275<informaltable><tgroup cols="2"><tbody><row><entry
1276 align="char">
1277<para>EBADF</para>
1278</entry><entry
1279 align="char">
1280<para>fd is not a valid open file descriptor</para>
1281</entry>
1282 </row><row><entry
1283 align="char">
1284<para>EINVAL</para>
1285</entry><entry
1286 align="char">
1287<para>type is not a valid or supported stream type.</para>
1288</entry>
1289 </row></tbody></tgroup></informaltable>
1290
1291</section><section
1292role="subsection"><title>AUDIO_SET_EXT_ID</title>
1293<para>DESCRIPTION
1294</para>
1295<informaltable><tgroup cols="1"><tbody><row><entry
1296 align="char">
1297<para>This ioctl can be used to set the extension id for MPEG streams in DVD
1298 playback. Only the first 3 bits are recognized.</para>
1299</entry>
1300 </row></tbody></tgroup></informaltable>
1301<para>SYNOPSIS
1302</para>
1303<informaltable><tgroup cols="1"><tbody><row><entry
1304 align="char">
1305<para>int ioctl(fd, int request = AUDIO_SET_EXT_ID, int
1306 id);</para>
1307</entry>
1308 </row></tbody></tgroup></informaltable>
1309<para>PARAMETERS
1310</para>
1311<informaltable><tgroup cols="2"><tbody><row><entry
1312 align="char">
1313<para>int fd</para>
1314</entry><entry
1315 align="char">
1316<para>File descriptor returned by a previous call to open().</para>
1317</entry>
1318 </row><row><entry
1319 align="char">
1320<para>int request</para>
1321</entry><entry
1322 align="char">
1323<para>Equals AUDIO_SET_EXT_ID for this command.</para>
1324</entry>
1325 </row><row><entry
1326 align="char">
1327<para>int id</para>
1328</entry><entry
1329 align="char">
1330<para>audio sub_stream_id</para>
1331</entry>
1332 </row></tbody></tgroup></informaltable>
1333<para>ERRORS
1334</para>
1335<informaltable><tgroup cols="2"><tbody><row><entry
1336 align="char">
1337<para>EBADF</para>
1338</entry><entry
1339 align="char">
1340<para>fd is not a valid open file descriptor</para>
1341</entry>
1342 </row><row><entry
1343 align="char">
1344<para>EINVAL</para>
1345</entry><entry
1346 align="char">
1347<para>id is not a valid id.</para>
1348</entry>
1349 </row></tbody></tgroup></informaltable>
1350
1351</section><section
1352role="subsection"><title>AUDIO_SET_ATTRIBUTES</title>
1353<para>DESCRIPTION
1354</para>
1355<informaltable><tgroup cols="1"><tbody><row><entry
1356 align="char">
1357<para>This ioctl is intended for DVD playback and allows you to set certain
1358 information about the audio stream.</para>
1359</entry>
1360 </row></tbody></tgroup></informaltable>
1361<para>SYNOPSIS
1362</para>
1363<informaltable><tgroup cols="1"><tbody><row><entry
1364 align="char">
1365<para>int ioctl(fd, int request = AUDIO_SET_ATTRIBUTES,
1366 audio_attributes_t attr );</para>
1367</entry>
1368 </row></tbody></tgroup></informaltable>
1369<para>PARAMETERS
1370</para>
1371<informaltable><tgroup cols="2"><tbody><row><entry
1372 align="char">
1373<para>int fd</para>
1374</entry><entry
1375 align="char">
1376<para>File descriptor returned by a previous call to open().</para>
1377</entry>
1378 </row><row><entry
1379 align="char">
1380<para>int request</para>
1381</entry><entry
1382 align="char">
1383<para>Equals AUDIO_SET_ATTRIBUTES for this command.</para>
1384</entry>
1385 </row><row><entry
1386 align="char">
1387<para>audio_attributes_t
1388 attr</para>
1389</entry><entry
1390 align="char">
1391<para>audio attributes according to section ??</para>
1392</entry>
1393 </row></tbody></tgroup></informaltable>
1394<para>ERRORS
1395</para>
1396<informaltable><tgroup cols="2"><tbody><row><entry
1397 align="char">
1398<para>EBADF</para>
1399</entry><entry
1400 align="char">
1401<para>fd is not a valid open file descriptor</para>
1402</entry>
1403 </row><row><entry
1404 align="char">
1405<para>EINVAL</para>
1406</entry><entry
1407 align="char">
1408<para>attr is not a valid or supported attribute setting.</para>
1409</entry>
1410 </row></tbody></tgroup></informaltable>
1411
1412</section><section
1413role="subsection"><title>AUDIO_SET_KARAOKE</title>
1414<para>DESCRIPTION
1415</para>
1416<informaltable><tgroup cols="1"><tbody><row><entry
1417 align="char">
1418<para>This ioctl allows one to set the mixer settings for a karaoke DVD.</para>
1419</entry>
1420 </row></tbody></tgroup></informaltable>
1421<para>SYNOPSIS
1422</para>
1423<informaltable><tgroup cols="1"><tbody><row><entry
1424 align="char">
1425<para>int ioctl(fd, int request = AUDIO_SET_STREAMTYPE,
1426 audio_karaoke_t &#x22C6;karaoke);</para>
1427</entry>
1428 </row></tbody></tgroup></informaltable>
1429<para>PARAMETERS
1430</para>
1431<informaltable><tgroup cols="2"><tbody><row><entry
1432 align="char">
1433<para>int fd</para>
1434</entry><entry
1435 align="char">
1436<para>File descriptor returned by a previous call to open().</para>
1437</entry>
1438 </row><row><entry
1439 align="char">
1440<para>int request</para>
1441</entry><entry
1442 align="char">
1443<para>Equals AUDIO_SET_STREAMTYPE for this
1444 command.</para>
1445</entry>
1446 </row><row><entry
1447 align="char">
1448<para>audio_karaoke_t
1449 *karaoke</para>
1450</entry><entry
1451 align="char">
1452<para>karaoke settings according to section ??.</para>
1453</entry>
1454 </row></tbody></tgroup></informaltable>
1455<para>ERRORS
1456</para>
1457<informaltable><tgroup cols="2"><tbody><row><entry
1458 align="char">
1459<para>EBADF</para>
1460</entry><entry
1461 align="char">
1462<para>fd is not a valid open file descriptor</para>
1463</entry>
1464 </row><row><entry
1465 align="char">
1466<para>EINVAL</para>
1467</entry><entry
1468 align="char">
1469<para>karaoke is not a valid or supported karaoke setting.</para>
1470</entry>
1471 </row></tbody></tgroup></informaltable>
1472 </section>
1473</section>
diff --git a/Documentation/DocBook/dvb/ca.xml b/Documentation/DocBook/dvb/ca.xml
new file mode 100644
index 000000000000..b1f1d2fad654
--- /dev/null
+++ b/Documentation/DocBook/dvb/ca.xml
@@ -0,0 +1,221 @@
1<title>DVB CA Device</title>
2<para>The DVB CA device controls the conditional access hardware. It can be accessed through
3<emphasis role="tt">/dev/dvb/adapter0/ca0</emphasis>. Data types and and ioctl definitions can be accessed by
4including <emphasis role="tt">linux/dvb/ca.h</emphasis> in your application.
5</para>
6
7<section id="ca_data_types">
8<title>CA Data Types</title>
9
10
11<section id="ca_slot_info_t">
12<title>ca_slot_info_t</title>
13 <programlisting>
14 /&#x22C6; slot interface types and info &#x22C6;/
15
16 typedef struct ca_slot_info_s {
17 int num; /&#x22C6; slot number &#x22C6;/
18
19 int type; /&#x22C6; CA interface this slot supports &#x22C6;/
20 #define CA_CI 1 /&#x22C6; CI high level interface &#x22C6;/
21 #define CA_CI_LINK 2 /&#x22C6; CI link layer level interface &#x22C6;/
22 #define CA_CI_PHYS 4 /&#x22C6; CI physical layer level interface &#x22C6;/
23 #define CA_SC 128 /&#x22C6; simple smart card interface &#x22C6;/
24
25 unsigned int flags;
26 #define CA_CI_MODULE_PRESENT 1 /&#x22C6; module (or card) inserted &#x22C6;/
27 #define CA_CI_MODULE_READY 2
28 } ca_slot_info_t;
29</programlisting>
30
31</section>
32<section id="ca_descr_info_t">
33<title>ca_descr_info_t</title>
34 <programlisting>
35 typedef struct ca_descr_info_s {
36 unsigned int num; /&#x22C6; number of available descramblers (keys) &#x22C6;/
37 unsigned int type; /&#x22C6; type of supported scrambling system &#x22C6;/
38 #define CA_ECD 1
39 #define CA_NDS 2
40 #define CA_DSS 4
41 } ca_descr_info_t;
42</programlisting>
43
44</section>
45<section id="ca_cap_t">
46<title>ca_cap_t</title>
47 <programlisting>
48 typedef struct ca_cap_s {
49 unsigned int slot_num; /&#x22C6; total number of CA card and module slots &#x22C6;/
50 unsigned int slot_type; /&#x22C6; OR of all supported types &#x22C6;/
51 unsigned int descr_num; /&#x22C6; total number of descrambler slots (keys) &#x22C6;/
52 unsigned int descr_type;/&#x22C6; OR of all supported types &#x22C6;/
53 } ca_cap_t;
54</programlisting>
55
56</section>
57<section id="ca_msg_t">
58<title>ca_msg_t</title>
59 <programlisting>
60 /&#x22C6; a message to/from a CI-CAM &#x22C6;/
61 typedef struct ca_msg_s {
62 unsigned int index;
63 unsigned int type;
64 unsigned int length;
65 unsigned char msg[256];
66 } ca_msg_t;
67</programlisting>
68
69</section>
70<section id="ca_descr_t">
71<title>ca_descr_t</title>
72 <programlisting>
73 typedef struct ca_descr_s {
74 unsigned int index;
75 unsigned int parity;
76 unsigned char cw[8];
77 } ca_descr_t;
78</programlisting>
79 </section></section>
80<section id="ca_function_calls">
81<title>CA Function Calls</title>
82
83
84<section id="ca_fopen">
85<title>open()</title>
86<para>DESCRIPTION
87</para>
88<informaltable><tgroup cols="1"><tbody><row><entry
89 align="char">
90<para>This system call opens a named ca device (e.g. /dev/ost/ca) for subsequent use.</para>
91<para>When an open() call has succeeded, the device will be ready for use.
92 The significance of blocking or non-blocking mode is described in the
93 documentation for functions where there is a difference. It does not affect the
94 semantics of the open() call itself. A device opened in blocking mode can later
95 be put into non-blocking mode (and vice versa) using the F_SETFL command
96 of the fcntl system call. This is a standard system call, documented in the Linux
97 manual page for fcntl. Only one user can open the CA Device in O_RDWR
98 mode. All other attempts to open the device in this mode will fail, and an error
99 code will be returned.</para>
100</entry>
101 </row></tbody></tgroup></informaltable>
102<para>SYNOPSIS
103</para>
104<informaltable><tgroup cols="1"><tbody><row><entry
105 align="char">
106<para>int open(const char &#x22C6;deviceName, int flags);</para>
107</entry>
108 </row></tbody></tgroup></informaltable>
109<para>PARAMETERS
110</para>
111<informaltable><tgroup cols="2"><tbody><row><entry
112 align="char">
113<para>const char
114 *deviceName</para>
115</entry><entry
116 align="char">
117<para>Name of specific video device.</para>
118</entry>
119 </row><row><entry
120 align="char">
121<para>int flags</para>
122</entry><entry
123 align="char">
124<para>A bit-wise OR of the following flags:</para>
125</entry>
126 </row><row><entry
127 align="char">
128</entry><entry
129 align="char">
130<para>O_RDONLY read-only access</para>
131</entry>
132 </row><row><entry
133 align="char">
134</entry><entry
135 align="char">
136<para>O_RDWR read/write access</para>
137</entry>
138 </row><row><entry
139 align="char">
140</entry><entry
141 align="char">
142<para>O_NONBLOCK open in non-blocking mode</para>
143</entry>
144 </row><row><entry
145 align="char">
146</entry><entry
147 align="char">
148<para>(blocking mode is the default)</para>
149</entry>
150 </row></tbody></tgroup></informaltable>
151<para>ERRORS
152</para>
153<informaltable><tgroup cols="2"><tbody><row><entry
154 align="char">
155<para>ENODEV</para>
156</entry><entry
157 align="char">
158<para>Device driver not loaded/available.</para>
159</entry>
160 </row><row><entry
161 align="char">
162<para>EINTERNAL</para>
163</entry><entry
164 align="char">
165<para>Internal error.</para>
166</entry>
167 </row><row><entry
168 align="char">
169<para>EBUSY</para>
170</entry><entry
171 align="char">
172<para>Device or resource busy.</para>
173</entry>
174 </row><row><entry
175 align="char">
176<para>EINVAL</para>
177</entry><entry
178 align="char">
179<para>Invalid argument.</para>
180</entry>
181 </row></tbody></tgroup></informaltable>
182
183</section>
184<section id="ca_fclose">
185<title>close()</title>
186<para>DESCRIPTION
187</para>
188<informaltable><tgroup cols="1"><tbody><row><entry
189 align="char">
190<para>This system call closes a previously opened audio device.</para>
191</entry>
192 </row></tbody></tgroup></informaltable>
193<para>SYNOPSIS
194</para>
195<informaltable><tgroup cols="1"><tbody><row><entry
196 align="char">
197<para>int close(int fd);</para>
198</entry>
199 </row></tbody></tgroup></informaltable>
200<para>PARAMETERS
201</para>
202<informaltable><tgroup cols="2"><tbody><row><entry
203 align="char">
204<para>int fd</para>
205</entry><entry
206 align="char">
207<para>File descriptor returned by a previous call to open().</para>
208</entry>
209 </row></tbody></tgroup></informaltable>
210<para>ERRORS
211</para>
212<informaltable><tgroup cols="2"><tbody><row><entry
213 align="char">
214<para>EBADF</para>
215</entry><entry
216 align="char">
217<para>fd is not a valid open file descriptor.</para>
218</entry>
219 </row></tbody></tgroup></informaltable>
220 </section>
221</section>
diff --git a/Documentation/DocBook/dvb/demux.xml b/Documentation/DocBook/dvb/demux.xml
new file mode 100644
index 000000000000..1b8c4e9835b9
--- /dev/null
+++ b/Documentation/DocBook/dvb/demux.xml
@@ -0,0 +1,973 @@
1<title>DVB Demux Device</title>
2
3<para>The DVB demux device controls the filters of the DVB hardware/software. It can be
4accessed through <emphasis role="tt">/dev/adapter0/demux0</emphasis>. Data types and and ioctl definitions can be
5accessed by including <emphasis role="tt">linux/dvb/dmx.h</emphasis> in your application.
6</para>
7<section id="dmx_types">
8<title>Demux Data Types</title>
9
10<section id="dmx_output_t">
11<title>dmx_output_t</title>
12 <programlisting>
13 typedef enum
14 {
15 DMX_OUT_DECODER,
16 DMX_OUT_TAP,
17 DMX_OUT_TS_TAP
18 } dmx_output_t;
19</programlisting>
20<para><emphasis role="tt">DMX_OUT_TAP</emphasis> delivers the stream output to the demux device on which the ioctl is
21called.
22</para>
23<para><emphasis role="tt">DMX_OUT_TS_TAP</emphasis> routes output to the logical DVR device <emphasis role="tt">/dev/dvb/adapter0/dvr0</emphasis>,
24which delivers a TS multiplexed from all filters for which <emphasis role="tt">DMX_OUT_TS_TAP</emphasis> was
25specified.
26</para>
27</section>
28
29<section id="dmx_input_t">
30<title>dmx_input_t</title>
31 <programlisting>
32 typedef enum
33 {
34 DMX_IN_FRONTEND,
35 DMX_IN_DVR
36 } dmx_input_t;
37</programlisting>
38</section>
39
40<section id="dmx_pes_type_t">
41<title>dmx_pes_type_t</title>
42 <programlisting>
43 typedef enum
44 {
45 DMX_PES_AUDIO,
46 DMX_PES_VIDEO,
47 DMX_PES_TELETEXT,
48 DMX_PES_SUBTITLE,
49 DMX_PES_PCR,
50 DMX_PES_OTHER
51 } dmx_pes_type_t;
52</programlisting>
53</section>
54
55<section id="dmx_event_t">
56<title>dmx_event_t</title>
57 <programlisting>
58 typedef enum
59 {
60 DMX_SCRAMBLING_EV,
61 DMX_FRONTEND_EV
62 } dmx_event_t;
63</programlisting>
64</section>
65
66<section id="dmx_scrambling_status_t">
67<title>dmx_scrambling_status_t</title>
68 <programlisting>
69 typedef enum
70 {
71 DMX_SCRAMBLING_OFF,
72 DMX_SCRAMBLING_ON
73 } dmx_scrambling_status_t;
74</programlisting>
75</section>
76
77<section id="dmx_filter">
78<title>struct dmx_filter</title>
79 <programlisting>
80 typedef struct dmx_filter
81 {
82 uint8_t filter[DMX_FILTER_SIZE];
83 uint8_t mask[DMX_FILTER_SIZE];
84 } dmx_filter_t;
85</programlisting>
86</section>
87
88<section id="dmx_sct_filter_params">
89<title>struct dmx_sct_filter_params</title>
90 <programlisting>
91 struct dmx_sct_filter_params
92 {
93 uint16_t pid;
94 dmx_filter_t filter;
95 uint32_t timeout;
96 uint32_t flags;
97 #define DMX_CHECK_CRC 1
98 #define DMX_ONESHOT 2
99 #define DMX_IMMEDIATE_START 4
100 };
101</programlisting>
102</section>
103
104<section id="dmx_pes_filter_params">
105<title>struct dmx_pes_filter_params</title>
106 <programlisting>
107 struct dmx_pes_filter_params
108 {
109 uint16_t pid;
110 dmx_input_t input;
111 dmx_output_t output;
112 dmx_pes_type_t pes_type;
113 uint32_t flags;
114 };
115</programlisting>
116</section>
117
118<section id="dmx_event">
119<title>struct dmx_event</title>
120 <programlisting>
121 struct dmx_event
122 {
123 dmx_event_t event;
124 time_t timeStamp;
125 union
126 {
127 dmx_scrambling_status_t scrambling;
128 } u;
129 };
130</programlisting>
131</section>
132
133<section id="dmx_stc">
134<title>struct dmx_stc</title>
135 <programlisting>
136 struct dmx_stc {
137 unsigned int num; /&#x22C6; input : which STC? 0..N &#x22C6;/
138 unsigned int base; /&#x22C6; output: divisor for stc to get 90 kHz clock &#x22C6;/
139 uint64_t stc; /&#x22C6; output: stc in 'base'&#x22C6;90 kHz units &#x22C6;/
140 };
141</programlisting>
142 </section>
143
144</section>
145
146<section id="dmx_fcalls">
147<title>Demux Function Calls</title>
148
149<section id="dmx_fopen">
150<title>open()</title>
151<para>DESCRIPTION
152</para>
153<informaltable><tgroup cols="1"><tbody><row><entry
154 align="char">
155<para>This system call, used with a device name of /dev/dvb/adapter0/demux0,
156 allocates a new filter and returns a handle which can be used for subsequent
157 control of that filter. This call has to be made for each filter to be used, i.e. every
158 returned file descriptor is a reference to a single filter. /dev/dvb/adapter0/dvr0
159 is a logical device to be used for retrieving Transport Streams for digital
160 video recording. When reading from this device a transport stream containing
161 the packets from all PES filters set in the corresponding demux device
162 (/dev/dvb/adapter0/demux0) having the output set to DMX_OUT_TS_TAP. A
163 recorded Transport Stream is replayed by writing to this device. </para>
164<para>The significance of blocking or non-blocking mode is described in the
165 documentation for functions where there is a difference. It does not affect the
166 semantics of the open() call itself. A device opened in blocking mode can later
167 be put into non-blocking mode (and vice versa) using the F_SETFL command
168 of the fcntl system call.</para>
169</entry>
170 </row></tbody></tgroup></informaltable>
171<para>SYNOPSIS
172</para>
173<informaltable><tgroup cols="1"><tbody><row><entry
174 align="char">
175<para>int open(const char &#x22C6;deviceName, int flags);</para>
176</entry>
177 </row></tbody></tgroup></informaltable>
178<para>PARAMETERS
179</para>
180<informaltable><tgroup cols="2"><tbody><row><entry
181 align="char">
182<para>const char
183 *deviceName</para>
184</entry><entry
185 align="char">
186<para>Name of demux device.</para>
187</entry>
188 </row><row><entry
189 align="char">
190<para>int flags</para>
191</entry><entry
192 align="char">
193<para>A bit-wise OR of the following flags:</para>
194</entry>
195 </row><row><entry
196 align="char">
197</entry><entry
198 align="char">
199<para>O_RDWR read/write access</para>
200</entry>
201 </row><row><entry
202 align="char">
203</entry><entry
204 align="char">
205<para>O_NONBLOCK open in non-blocking mode</para>
206</entry>
207 </row><row><entry
208 align="char">
209</entry><entry
210 align="char">
211<para>(blocking mode is the default)</para>
212</entry>
213 </row></tbody></tgroup></informaltable>
214<para>ERRORS
215</para>
216<informaltable><tgroup cols="2"><tbody><row><entry
217 align="char">
218<para>ENODEV</para>
219</entry><entry
220 align="char">
221<para>Device driver not loaded/available.</para>
222</entry>
223 </row><row><entry
224 align="char">
225<para>EINVAL</para>
226</entry><entry
227 align="char">
228<para>Invalid argument.</para>
229</entry>
230 </row><row><entry
231 align="char">
232<para>EMFILE</para>
233</entry><entry
234 align="char">
235<para>&#8220;Too many open files&#8221;, i.e. no more filters available.</para>
236</entry>
237 </row><row><entry
238 align="char">
239<para>ENOMEM</para>
240</entry><entry
241 align="char">
242<para>The driver failed to allocate enough memory.</para>
243</entry>
244 </row></tbody></tgroup></informaltable>
245</section>
246
247<section id="dmx_fclose">
248<title>close()</title>
249<para>DESCRIPTION
250</para>
251<informaltable><tgroup cols="1"><tbody><row><entry
252 align="char">
253<para>This system call deactivates and deallocates a filter that was previously
254 allocated via the open() call.</para>
255</entry>
256 </row></tbody></tgroup></informaltable>
257<para>SYNOPSIS
258</para>
259<informaltable><tgroup cols="1"><tbody><row><entry
260 align="char">
261<para>int close(int fd);</para>
262</entry>
263 </row></tbody></tgroup></informaltable>
264<para>PARAMETERS
265</para>
266<informaltable><tgroup cols="2"><tbody><row><entry
267 align="char">
268<para>int fd</para>
269</entry><entry
270 align="char">
271<para>File descriptor returned by a previous call to open().</para>
272</entry>
273 </row></tbody></tgroup></informaltable>
274<para>ERRORS
275</para>
276<informaltable><tgroup cols="2"><tbody><row><entry
277 align="char">
278<para>EBADF</para>
279</entry><entry
280 align="char">
281<para>fd is not a valid open file descriptor.</para>
282</entry>
283 </row></tbody></tgroup></informaltable>
284</section>
285
286<section id="dmx_fread">
287<title>read()</title>
288<para>DESCRIPTION
289</para>
290<informaltable><tgroup cols="1"><tbody><row><entry
291 align="char">
292<para>This system call returns filtered data, which might be section or PES data. The
293 filtered data is transferred from the driver&#8217;s internal circular buffer to buf. The
294 maximum amount of data to be transferred is implied by count.</para>
295</entry>
296 </row><row><entry
297 align="char">
298<para>When returning section data the driver always tries to return a complete single
299 section (even though buf would provide buffer space for more data). If the size
300 of the buffer is smaller than the section as much as possible will be returned,
301 and the remaining data will be provided in subsequent calls.</para>
302</entry>
303 </row><row><entry
304 align="char">
305<para>The size of the internal buffer is 2 * 4096 bytes (the size of two maximum
306 sized sections) by default. The size of this buffer may be changed by using the
307 DMX_SET_BUFFER_SIZE function. If the buffer is not large enough, or if
308 the read operations are not performed fast enough, this may result in a buffer
309 overflow error. In this case EOVERFLOW will be returned, and the circular
310 buffer will be emptied. This call is blocking if there is no data to return, i.e. the
311 process will be put to sleep waiting for data, unless the O_NONBLOCK flag
312 is specified.</para>
313</entry>
314 </row><row><entry
315 align="char">
316<para>Note that in order to be able to read, the filtering process has to be started
317 by defining either a section or a PES filter by means of the ioctl functions,
318 and then starting the filtering process via the DMX_START ioctl function
319 or by setting the DMX_IMMEDIATE_START flag. If the reading is done
320 from a logical DVR demux device, the data will constitute a Transport Stream
321 including the packets from all PES filters in the corresponding demux device
322 /dev/dvb/adapter0/demux0 having the output set to DMX_OUT_TS_TAP.</para>
323</entry>
324 </row></tbody></tgroup></informaltable>
325<para>SYNOPSIS
326</para>
327<informaltable><tgroup cols="1"><tbody><row><entry
328 align="char">
329<para>size_t read(int fd, void &#x22C6;buf, size_t count);</para>
330</entry>
331 </row></tbody></tgroup></informaltable>
332<para>PARAMETERS
333</para>
334<informaltable><tgroup cols="2"><tbody><row><entry
335 align="char">
336<para>int fd</para>
337</entry><entry
338 align="char">
339<para>File descriptor returned by a previous call to open().</para>
340</entry>
341 </row><row><entry
342 align="char">
343<para>void *buf</para>
344</entry><entry
345 align="char">
346<para>Pointer to the buffer to be used for returned filtered data.</para>
347</entry>
348 </row><row><entry
349 align="char">
350<para>size_t count</para>
351</entry><entry
352 align="char">
353<para>Size of buf.</para>
354</entry>
355 </row></tbody></tgroup></informaltable>
356<para>ERRORS
357</para>
358<informaltable><tgroup cols="2"><tbody><row><entry
359 align="char">
360<para>EWOULDBLOCK</para>
361</entry><entry
362 align="char">
363<para>No data to return and O_NONBLOCK was specified.</para>
364</entry>
365 </row><row><entry
366 align="char">
367<para>EBADF</para>
368</entry><entry
369 align="char">
370<para>fd is not a valid open file descriptor.</para>
371</entry>
372 </row><row><entry
373 align="char">
374<para>ECRC</para>
375</entry><entry
376 align="char">
377<para>Last section had a CRC error - no data returned. The
378 buffer is flushed.</para>
379</entry>
380 </row><row><entry
381 align="char">
382<para>EOVERFLOW</para>
383</entry><entry
384 align="char">
385</entry>
386 </row><row><entry
387 align="char">
388</entry><entry
389 align="char">
390<para>The filtered data was not read from the buffer in due
391 time, resulting in non-read data being lost. The buffer is
392 flushed.</para>
393</entry>
394 </row><row><entry
395 align="char">
396<para>ETIMEDOUT</para>
397</entry><entry
398 align="char">
399<para>The section was not loaded within the stated timeout
400 period. See ioctl DMX_SET_FILTER for how to set a
401 timeout.</para>
402</entry>
403 </row><row><entry
404 align="char">
405<para>EFAULT</para>
406</entry><entry
407 align="char">
408<para>The driver failed to write to the callers buffer due to an
409 invalid *buf pointer.</para>
410</entry>
411 </row></tbody></tgroup></informaltable>
412</section>
413
414<section id="dmx_fwrite">
415<title>write()</title>
416<para>DESCRIPTION
417</para>
418<informaltable><tgroup cols="1"><tbody><row><entry
419 align="char">
420<para>This system call is only provided by the logical device /dev/dvb/adapter0/dvr0,
421 associated with the physical demux device that provides the actual DVR
422 functionality. It is used for replay of a digitally recorded Transport Stream.
423 Matching filters have to be defined in the corresponding physical demux
424 device, /dev/dvb/adapter0/demux0. The amount of data to be transferred is
425 implied by count.</para>
426</entry>
427 </row></tbody></tgroup></informaltable>
428<para>SYNOPSIS
429</para>
430<informaltable><tgroup cols="1"><tbody><row><entry
431 align="char">
432<para>ssize_t write(int fd, const void &#x22C6;buf, size_t
433 count);</para>
434</entry>
435 </row></tbody></tgroup></informaltable>
436<para>PARAMETERS
437</para>
438<informaltable><tgroup cols="2"><tbody><row><entry
439 align="char">
440<para>int fd</para>
441</entry><entry
442 align="char">
443<para>File descriptor returned by a previous call to open().</para>
444</entry>
445 </row><row><entry
446 align="char">
447<para>void *buf</para>
448</entry><entry
449 align="char">
450<para>Pointer to the buffer containing the Transport Stream.</para>
451</entry>
452 </row><row><entry
453 align="char">
454<para>size_t count</para>
455</entry><entry
456 align="char">
457<para>Size of buf.</para>
458</entry>
459 </row></tbody></tgroup></informaltable>
460<para>ERRORS
461</para>
462<informaltable><tgroup cols="2"><tbody><row><entry
463 align="char">
464<para>EWOULDBLOCK</para>
465</entry><entry
466 align="char">
467<para>No data was written. This
468 might happen if O_NONBLOCK was specified and there
469 is no more buffer space available (if O_NONBLOCK is
470 not specified the function will block until buffer space is
471 available).</para>
472</entry>
473 </row><row><entry
474 align="char">
475<para>EBUSY</para>
476</entry><entry
477 align="char">
478<para>This error code indicates that there are conflicting
479 requests. The corresponding demux device is setup to
480 receive data from the front- end. Make sure that these
481 filters are stopped and that the filters with input set to
482 DMX_IN_DVR are started.</para>
483</entry>
484 </row><row><entry
485 align="char">
486<para>EBADF</para>
487</entry><entry
488 align="char">
489<para>fd is not a valid open file descriptor.</para>
490</entry>
491 </row></tbody></tgroup></informaltable>
492</section>
493
494<section id="dmx_start">
495<title>DMX_START</title>
496<para>DESCRIPTION
497</para>
498<informaltable><tgroup cols="1"><tbody><row><entry
499 align="char">
500<para>This ioctl call is used to start the actual filtering operation defined via the ioctl
501 calls DMX_SET_FILTER or DMX_SET_PES_FILTER.</para>
502</entry>
503 </row></tbody></tgroup></informaltable>
504<para>SYNOPSIS
505</para>
506<informaltable><tgroup cols="1"><tbody><row><entry
507 align="char">
508<para>int ioctl( int fd, int request = DMX_START);</para>
509</entry>
510 </row></tbody></tgroup></informaltable>
511<para>PARAMETERS
512</para>
513<informaltable><tgroup cols="2"><tbody><row><entry
514 align="char">
515<para>int fd</para>
516</entry><entry
517 align="char">
518<para>File descriptor returned by a previous call to open().</para>
519</entry>
520 </row><row><entry
521 align="char">
522<para>int request</para>
523</entry><entry
524 align="char">
525<para>Equals DMX_START for this command.</para>
526</entry>
527 </row></tbody></tgroup></informaltable>
528<para>ERRORS
529</para>
530<informaltable><tgroup cols="2"><tbody><row><entry
531 align="char">
532<para>EBADF</para>
533</entry><entry
534 align="char">
535<para>fd is not a valid file descriptor.</para>
536</entry>
537 </row><row><entry
538 align="char">
539<para>EINVAL</para>
540</entry><entry
541 align="char">
542<para>Invalid argument, i.e. no filtering parameters provided via
543 the DMX_SET_FILTER or DMX_SET_PES_FILTER
544 functions.</para>
545</entry>
546 </row><row><entry
547 align="char">
548<para>EBUSY</para>
549</entry><entry
550 align="char">
551<para>This error code indicates that there are conflicting
552 requests. There are active filters filtering data from
553 another input source. Make sure that these filters are
554 stopped before starting this filter.</para>
555</entry>
556 </row></tbody></tgroup></informaltable>
557</section>
558
559<section id="dmx_stop">
560<title>DMX_STOP</title>
561<para>DESCRIPTION
562</para>
563<informaltable><tgroup cols="1"><tbody><row><entry
564 align="char">
565<para>This ioctl call is used to stop the actual filtering operation defined via the
566 ioctl calls DMX_SET_FILTER or DMX_SET_PES_FILTER and started via
567 the DMX_START command.</para>
568</entry>
569 </row></tbody></tgroup></informaltable>
570<para>SYNOPSIS
571</para>
572<informaltable><tgroup cols="1"><tbody><row><entry
573 align="char">
574<para>int ioctl( int fd, int request = DMX_STOP);</para>
575</entry>
576 </row></tbody></tgroup></informaltable>
577<para>PARAMETERS
578</para>
579<informaltable><tgroup cols="2"><tbody><row><entry
580 align="char">
581<para>int fd</para>
582</entry><entry
583 align="char">
584<para>File descriptor returned by a previous call to open().</para>
585</entry>
586 </row><row><entry
587 align="char">
588<para>int request</para>
589</entry><entry
590 align="char">
591<para>Equals DMX_STOP for this command.</para>
592</entry>
593 </row></tbody></tgroup></informaltable>
594<para>ERRORS
595</para>
596<informaltable><tgroup cols="2"><tbody><row><entry
597 align="char">
598<para>EBADF</para>
599</entry><entry
600 align="char">
601<para>fd is not a valid file descriptor.</para>
602</entry>
603 </row></tbody></tgroup></informaltable>
604</section>
605
606<section id="dmx_set_filter">
607<title>DMX_SET_FILTER</title>
608<para>DESCRIPTION
609</para>
610<informaltable><tgroup cols="1"><tbody><row><entry
611 align="char">
612<para>This ioctl call sets up a filter according to the filter and mask parameters
613 provided. A timeout may be defined stating number of seconds to wait for a
614 section to be loaded. A value of 0 means that no timeout should be applied.
615 Finally there is a flag field where it is possible to state whether a section should
616 be CRC-checked, whether the filter should be a &#8221;one-shot&#8221; filter, i.e. if the
617 filtering operation should be stopped after the first section is received, and
618 whether the filtering operation should be started immediately (without waiting
619 for a DMX_START ioctl call). If a filter was previously set-up, this filter will
620 be canceled, and the receive buffer will be flushed.</para>
621</entry>
622 </row></tbody></tgroup></informaltable>
623<para>SYNOPSIS
624</para>
625<informaltable><tgroup cols="1"><tbody><row><entry
626 align="char">
627<para>int ioctl( int fd, int request = DMX_SET_FILTER,
628 struct dmx_sct_filter_params &#x22C6;params);</para>
629</entry>
630 </row></tbody></tgroup></informaltable>
631<para>PARAMETERS
632</para>
633<informaltable><tgroup cols="2"><tbody><row><entry
634 align="char">
635<para>int fd</para>
636</entry><entry
637 align="char">
638<para>File descriptor returned by a previous call to open().</para>
639</entry>
640 </row><row><entry
641 align="char">
642<para>int request</para>
643</entry><entry
644 align="char">
645<para>Equals DMX_SET_FILTER for this command.</para>
646</entry>
647 </row><row><entry
648 align="char">
649<para>struct
650 dmx_sct_filter_params
651 *params</para>
652</entry><entry
653 align="char">
654<para>Pointer to structure containing filter parameters.</para>
655</entry>
656 </row></tbody></tgroup></informaltable>
657<para>ERRORS
658</para>
659<informaltable><tgroup cols="2"><tbody><row><entry
660 align="char">
661<para>EBADF</para>
662</entry><entry
663 align="char">
664<para>fd is not a valid file descriptor.</para>
665</entry>
666 </row><row><entry
667 align="char">
668<para>EINVAL</para>
669</entry><entry
670 align="char">
671<para>Invalid argument.</para>
672</entry>
673 </row></tbody></tgroup></informaltable>
674</section>
675
676<section id="dmx_set_pes_filter">
677<title>DMX_SET_PES_FILTER</title>
678<para>DESCRIPTION
679</para>
680<informaltable><tgroup cols="1"><tbody><row><entry
681 align="char">
682<para>This ioctl call sets up a PES filter according to the parameters provided. By a
683 PES filter is meant a filter that is based just on the packet identifier (PID), i.e.
684 no PES header or payload filtering capability is supported.</para>
685</entry>
686 </row><row><entry
687 align="char">
688<para>The transport stream destination for the filtered output may be set. Also the
689 PES type may be stated in order to be able to e.g. direct a video stream directly
690 to the video decoder. Finally there is a flag field where it is possible to state
691 whether the filtering operation should be started immediately (without waiting
692 for a DMX_START ioctl call). If a filter was previously set-up, this filter will
693 be cancelled, and the receive buffer will be flushed.</para>
694</entry>
695 </row></tbody></tgroup></informaltable>
696<para>SYNOPSIS
697</para>
698<informaltable><tgroup cols="1"><tbody><row><entry
699 align="char">
700<para>int ioctl( int fd, int request = DMX_SET_PES_FILTER,
701 struct dmx_pes_filter_params &#x22C6;params);</para>
702</entry>
703 </row></tbody></tgroup></informaltable>
704<para>PARAMETERS
705</para>
706<informaltable><tgroup cols="2"><tbody><row><entry
707 align="char">
708<para>int fd</para>
709</entry><entry
710 align="char">
711<para>File descriptor returned by a previous call to open().</para>
712</entry>
713 </row><row><entry
714 align="char">
715<para>int request</para>
716</entry><entry
717 align="char">
718<para>Equals DMX_SET_PES_FILTER for this command.</para>
719</entry>
720 </row><row><entry
721 align="char">
722<para>struct
723 dmx_pes_filter_params
724 *params</para>
725</entry><entry
726 align="char">
727<para>Pointer to structure containing filter parameters.</para>
728</entry>
729 </row></tbody></tgroup></informaltable>
730<para>ERRORS
731</para>
732<informaltable><tgroup cols="2"><tbody><row><entry
733 align="char">
734<para>EBADF</para>
735</entry><entry
736 align="char">
737<para>fd is not a valid file descriptor.</para>
738</entry>
739 </row><row><entry
740 align="char">
741<para>EINVAL</para>
742</entry><entry
743 align="char">
744<para>Invalid argument.</para>
745</entry>
746 </row><row><entry
747 align="char">
748<para>EBUSY</para>
749</entry><entry
750 align="char">
751<para>This error code indicates that there are conflicting
752 requests. There are active filters filtering data from
753 another input source. Make sure that these filters are
754 stopped before starting this filter.</para>
755</entry>
756 </row></tbody></tgroup></informaltable>
757</section>
758
759<section id="dms_set_buffer_size">
760<title>DMX_SET_BUFFER_SIZE</title>
761<para>DESCRIPTION
762</para>
763<informaltable><tgroup cols="1"><tbody><row><entry
764 align="char">
765<para>This ioctl call is used to set the size of the circular buffer used for filtered data.
766 The default size is two maximum sized sections, i.e. if this function is not called
767 a buffer size of 2 * 4096 bytes will be used.</para>
768</entry>
769 </row></tbody></tgroup></informaltable>
770<para>SYNOPSIS
771</para>
772<informaltable><tgroup cols="1"><tbody><row><entry
773 align="char">
774<para>int ioctl( int fd, int request =
775 DMX_SET_BUFFER_SIZE, unsigned long size);</para>
776</entry>
777 </row></tbody></tgroup></informaltable>
778<para>PARAMETERS
779</para>
780<informaltable><tgroup cols="2"><tbody><row><entry
781 align="char">
782<para>int fd</para>
783</entry><entry
784 align="char">
785<para>File descriptor returned by a previous call to open().</para>
786</entry>
787 </row><row><entry
788 align="char">
789<para>int request</para>
790</entry><entry
791 align="char">
792<para>Equals DMX_SET_BUFFER_SIZE for this command.</para>
793</entry>
794 </row><row><entry
795 align="char">
796<para>unsigned long size</para>
797</entry><entry
798 align="char">
799<para>Size of circular buffer.</para>
800</entry>
801 </row></tbody></tgroup></informaltable>
802<para>ERRORS
803</para>
804<informaltable><tgroup cols="2"><tbody><row><entry
805 align="char">
806<para>EBADF</para>
807</entry><entry
808 align="char">
809<para>fd is not a valid file descriptor.</para>
810</entry>
811 </row><row><entry
812 align="char">
813<para>ENOMEM</para>
814</entry><entry
815 align="char">
816<para>The driver was not able to allocate a buffer of the
817 requested size.</para>
818</entry>
819 </row></tbody></tgroup></informaltable>
820</section>
821
822<section id="dmx_get_event">
823<title>DMX_GET_EVENT</title>
824<para>DESCRIPTION
825</para>
826<informaltable><tgroup cols="1"><tbody><row><entry
827 align="char">
828<para>This ioctl call returns an event if available. If an event is not available,
829 the behavior depends on whether the device is in blocking or non-blocking
830 mode. In the latter case, the call fails immediately with errno set to
831 EWOULDBLOCK. In the former case, the call blocks until an event becomes
832 available.</para>
833</entry>
834 </row><row><entry
835 align="char">
836<para>The standard Linux poll() and/or select() system calls can be used with the
837 device file descriptor to watch for new events. For select(), the file descriptor
838 should be included in the exceptfds argument, and for poll(), POLLPRI should
839 be specified as the wake-up condition. Only the latest event for each filter is
840 saved.</para>
841</entry>
842 </row></tbody></tgroup></informaltable>
843<para>SYNOPSIS
844</para>
845<informaltable><tgroup cols="1"><tbody><row><entry
846 align="char">
847<para>int ioctl( int fd, int request = DMX_GET_EVENT,
848 struct dmx_event &#x22C6;ev);</para>
849</entry>
850 </row></tbody></tgroup></informaltable>
851<para>PARAMETERS
852</para>
853<informaltable><tgroup cols="2"><tbody><row><entry
854 align="char">
855<para>int fd</para>
856</entry><entry
857 align="char">
858<para>File descriptor returned by a previous call to open().</para>
859</entry>
860 </row><row><entry
861 align="char">
862<para>int request</para>
863</entry><entry
864 align="char">
865<para>Equals DMX_GET_EVENT for this command.</para>
866</entry>
867 </row><row><entry
868 align="char">
869<para>struct dmx_event *ev</para>
870</entry><entry
871 align="char">
872<para>Pointer to the location where the event is to be stored.</para>
873</entry>
874 </row></tbody></tgroup></informaltable>
875<para>ERRORS
876</para>
877<informaltable><tgroup cols="2"><tbody><row><entry
878 align="char">
879<para>EBADF</para>
880</entry><entry
881 align="char">
882<para>fd is not a valid file descriptor.</para>
883</entry>
884 </row><row><entry
885 align="char">
886<para>EFAULT</para>
887</entry><entry
888 align="char">
889<para>ev points to an invalid address.</para>
890</entry>
891 </row><row><entry
892 align="char">
893<para>EWOULDBLOCK</para>
894</entry><entry
895 align="char">
896<para>There is no event pending, and the device is in
897 non-blocking mode.</para>
898</entry>
899 </row></tbody></tgroup></informaltable>
900</section>
901
902<section id="dmx_get_stc">
903<title>DMX_GET_STC</title>
904<para>DESCRIPTION
905</para>
906<informaltable><tgroup cols="1"><tbody><row><entry
907 align="char">
908<para>This ioctl call returns the current value of the system time counter (which is driven
909 by a PES filter of type DMX_PES_PCR). Some hardware supports more than one
910 STC, so you must specify which one by setting the num field of stc before the ioctl
911 (range 0...n). The result is returned in form of a ratio with a 64 bit numerator
912 and a 32 bit denominator, so the real 90kHz STC value is stc-&#x003E;stc /
913 stc-&#x003E;base
914 .</para>
915</entry>
916 </row></tbody></tgroup></informaltable>
917<para>SYNOPSIS
918</para>
919<informaltable><tgroup cols="1"><tbody><row><entry
920 align="char">
921<para>int ioctl( int fd, int request = DMX_GET_STC, struct
922 dmx_stc &#x22C6;stc);</para>
923</entry>
924 </row></tbody></tgroup></informaltable>
925<para>PARAMETERS
926</para>
927<informaltable><tgroup cols="2"><tbody><row><entry
928 align="char">
929<para>int fd</para>
930</entry><entry
931 align="char">
932<para>File descriptor returned by a previous call to open().</para>
933</entry>
934 </row><row><entry
935 align="char">
936<para>int request</para>
937</entry><entry
938 align="char">
939<para>Equals DMX_GET_STC for this command.</para>
940</entry>
941 </row><row><entry
942 align="char">
943<para>struct dmx_stc *stc</para>
944</entry><entry
945 align="char">
946<para>Pointer to the location where the stc is to be stored.</para>
947</entry>
948 </row></tbody></tgroup></informaltable>
949<para>ERRORS
950</para>
951<informaltable><tgroup cols="2"><tbody><row><entry
952 align="char">
953<para>EBADF</para>
954</entry><entry
955 align="char">
956<para>fd is not a valid file descriptor.</para>
957</entry>
958 </row><row><entry
959 align="char">
960<para>EFAULT</para>
961</entry><entry
962 align="char">
963<para>stc points to an invalid address.</para>
964</entry>
965 </row><row><entry
966 align="char">
967<para>EINVAL</para>
968</entry><entry
969 align="char">
970<para>Invalid stc number.</para>
971</entry>
972 </row></tbody></tgroup></informaltable>
973 </section></section>
diff --git a/Documentation/DocBook/dvb/dvbapi.xml b/Documentation/DocBook/dvb/dvbapi.xml
new file mode 100644
index 000000000000..4fc5b23470a3
--- /dev/null
+++ b/Documentation/DocBook/dvb/dvbapi.xml
@@ -0,0 +1,87 @@
1<partinfo>
2<authorgroup>
3<author>
4<firstname>Ralph</firstname>
5<surname>Metzler</surname>
6<othername role="mi">J. K.</othername>
7<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
8</author>
9<author>
10<firstname>Marcus</firstname>
11<surname>Metzler</surname>
12<othername role="mi">O. C.</othername>
13<affiliation><address><email>rjkm@metzlerbros.de</email></address></affiliation>
14</author>
15<author>
16<firstname>Mauro</firstname>
17<surname>Chehab</surname>
18<othername role="mi">Carvalho</othername>
19<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
20<contrib>Ported document to Docbook XML.</contrib>
21</author>
22</authorgroup>
23<copyright>
24 <year>2002</year>
25 <year>2003</year>
26 <year>2009</year>
27 <holder>Convergence GmbH</holder>
28</copyright>
29
30<revhistory>
31<!-- Put document revisions here, newest first. -->
32<revision>
33<revnumber>2.0.1</revnumber>
34<date>2009-09-16</date>
35<authorinitials>mcc</authorinitials>
36<revremark>
37Added ISDB-T test originally written by Patrick Boettcher
38</revremark>
39</revision>
40<revision>
41<revnumber>2.0.0</revnumber>
42<date>2009-09-06</date>
43<authorinitials>mcc</authorinitials>
44<revremark>Conversion from LaTex to DocBook XML. The
45 contents is the same as the original LaTex version.</revremark>
46</revision>
47<revision>
48<revnumber>1.0.0</revnumber>
49<date>2003-07-24</date>
50<authorinitials>rjkm</authorinitials>
51<revremark>Initial revision on LaTEX.</revremark>
52</revision>
53</revhistory>
54</partinfo>
55
56
57<title>LINUX DVB API</title>
58<subtitle>Version 3</subtitle>
59<!-- ADD THE CHAPTERS HERE -->
60 <chapter id="dvb_introdution">
61 &sub-intro;
62 </chapter>
63 <chapter id="dvb_frontend">
64 &sub-frontend;
65 </chapter>
66 <chapter id="dvb_demux">
67 &sub-demux;
68 </chapter>
69 <chapter id="dvb_video">
70 &sub-video;
71 </chapter>
72 <chapter id="dvb_audio">
73 &sub-audio;
74 </chapter>
75 <chapter id="dvb_ca">
76 &sub-ca;
77 </chapter>
78 <chapter id="dvb_net">
79 &sub-net;
80 </chapter>
81 <chapter id="dvb_kdapi">
82 &sub-kdapi;
83 </chapter>
84 <chapter id="dvb_examples">
85 &sub-examples;
86 </chapter>
87<!-- END OF CHAPTERS -->
diff --git a/Documentation/DocBook/dvb/dvbstb.pdf b/Documentation/DocBook/dvb/dvbstb.pdf
new file mode 100644
index 000000000000..0fa75d90c3eb
--- /dev/null
+++ b/Documentation/DocBook/dvb/dvbstb.pdf
Binary files differ
diff --git a/Documentation/DocBook/dvb/dvbstb.png b/Documentation/DocBook/dvb/dvbstb.png
new file mode 100644
index 000000000000..9b8f372e7afd
--- /dev/null
+++ b/Documentation/DocBook/dvb/dvbstb.png
Binary files differ
diff --git a/Documentation/DocBook/dvb/examples.xml b/Documentation/DocBook/dvb/examples.xml
new file mode 100644
index 000000000000..f037e568eb6e
--- /dev/null
+++ b/Documentation/DocBook/dvb/examples.xml
@@ -0,0 +1,365 @@
1<title>Examples</title>
2<para>In this section we would like to present some examples for using the DVB API.
3</para>
4<para>Maintainer note: This section is out of date. Please refer to the sample programs packaged
5with the driver distribution from <ulink url="http://linuxtv.org/hg/dvb-apps" />.
6</para>
7
8<section id="tuning">
9<title>Tuning</title>
10<para>We will start with a generic tuning subroutine that uses the frontend and SEC, as well as
11the demux devices. The example is given for QPSK tuners, but can easily be adjusted for
12QAM.
13</para>
14<programlisting>
15 #include &#x003C;sys/ioctl.h&#x003E;
16 #include &#x003C;stdio.h&#x003E;
17 #include &#x003C;stdint.h&#x003E;
18 #include &#x003C;sys/types.h&#x003E;
19 #include &#x003C;sys/stat.h&#x003E;
20 #include &#x003C;fcntl.h&#x003E;
21 #include &#x003C;time.h&#x003E;
22 #include &#x003C;unistd.h&#x003E;
23
24 #include &#x003C;linux/dvb/dmx.h&#x003E;
25 #include &#x003C;linux/dvb/frontend.h&#x003E;
26 #include &#x003C;linux/dvb/sec.h&#x003E;
27 #include &#x003C;sys/poll.h&#x003E;
28
29 #define DMX "/dev/dvb/adapter0/demux1"
30 #define FRONT "/dev/dvb/adapter0/frontend1"
31 #define SEC "/dev/dvb/adapter0/sec1"
32
33 /&#x22C6; routine for checking if we have a signal and other status information&#x22C6;/
34 int FEReadStatus(int fd, fe_status_t &#x22C6;stat)
35 {
36 int ans;
37
38 if ( (ans = ioctl(fd,FE_READ_STATUS,stat) &#x003C; 0)){
39 perror("FE READ STATUS: ");
40 return -1;
41 }
42
43 if (&#x22C6;stat &amp; FE_HAS_POWER)
44 printf("FE HAS POWER\n");
45
46 if (&#x22C6;stat &amp; FE_HAS_SIGNAL)
47 printf("FE HAS SIGNAL\n");
48
49 if (&#x22C6;stat &amp; FE_SPECTRUM_INV)
50 printf("SPEKTRUM INV\n");
51
52 return 0;
53 }
54
55
56 /&#x22C6; tune qpsk &#x22C6;/
57 /&#x22C6; freq: frequency of transponder &#x22C6;/
58 /&#x22C6; vpid, apid, tpid: PIDs of video, audio and teletext TS packets &#x22C6;/
59 /&#x22C6; diseqc: DiSEqC address of the used LNB &#x22C6;/
60 /&#x22C6; pol: Polarisation &#x22C6;/
61 /&#x22C6; srate: Symbol Rate &#x22C6;/
62 /&#x22C6; fec. FEC &#x22C6;/
63 /&#x22C6; lnb_lof1: local frequency of lower LNB band &#x22C6;/
64 /&#x22C6; lnb_lof2: local frequency of upper LNB band &#x22C6;/
65 /&#x22C6; lnb_slof: switch frequency of LNB &#x22C6;/
66
67 int set_qpsk_channel(int freq, int vpid, int apid, int tpid,
68 int diseqc, int pol, int srate, int fec, int lnb_lof1,
69 int lnb_lof2, int lnb_slof)
70 {
71 struct secCommand scmd;
72 struct secCmdSequence scmds;
73 struct dmx_pes_filter_params pesFilterParams;
74 FrontendParameters frp;
75 struct pollfd pfd[1];
76 FrontendEvent event;
77 int demux1, demux2, demux3, front;
78
79 frequency = (uint32_t) freq;
80 symbolrate = (uint32_t) srate;
81
82 if((front = open(FRONT,O_RDWR)) &#x003C; 0){
83 perror("FRONTEND DEVICE: ");
84 return -1;
85 }
86
87 if((sec = open(SEC,O_RDWR)) &#x003C; 0){
88 perror("SEC DEVICE: ");
89 return -1;
90 }
91
92 if (demux1 &#x003C; 0){
93 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
94 &#x003C; 0){
95 perror("DEMUX DEVICE: ");
96 return -1;
97 }
98 }
99
100 if (demux2 &#x003C; 0){
101 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
102 &#x003C; 0){
103 perror("DEMUX DEVICE: ");
104 return -1;
105 }
106 }
107
108 if (demux3 &#x003C; 0){
109 if ((demux3=open(DMX, O_RDWR|O_NONBLOCK))
110 &#x003C; 0){
111 perror("DEMUX DEVICE: ");
112 return -1;
113 }
114 }
115
116 if (freq &#x003C; lnb_slof) {
117 frp.Frequency = (freq - lnb_lof1);
118 scmds.continuousTone = SEC_TONE_OFF;
119 } else {
120 frp.Frequency = (freq - lnb_lof2);
121 scmds.continuousTone = SEC_TONE_ON;
122 }
123 frp.Inversion = INVERSION_AUTO;
124 if (pol) scmds.voltage = SEC_VOLTAGE_18;
125 else scmds.voltage = SEC_VOLTAGE_13;
126
127 scmd.type=0;
128 scmd.u.diseqc.addr=0x10;
129 scmd.u.diseqc.cmd=0x38;
130 scmd.u.diseqc.numParams=1;
131 scmd.u.diseqc.params[0] = 0xF0 | ((diseqc &#x22C6; 4) &amp; 0x0F) |
132 (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) |
133 (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0);
134
135 scmds.miniCommand=SEC_MINI_NONE;
136 scmds.numCommands=1;
137 scmds.commands=&amp;scmd;
138 if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
139 perror("SEC SEND: ");
140 return -1;
141 }
142
143 if (ioctl(sec, SEC_SEND_SEQUENCE, &amp;scmds) &#x003C; 0){
144 perror("SEC SEND: ");
145 return -1;
146 }
147
148 frp.u.qpsk.SymbolRate = srate;
149 frp.u.qpsk.FEC_inner = fec;
150
151 if (ioctl(front, FE_SET_FRONTEND, &amp;frp) &#x003C; 0){
152 perror("QPSK TUNE: ");
153 return -1;
154 }
155
156 pfd[0].fd = front;
157 pfd[0].events = POLLIN;
158
159 if (poll(pfd,1,3000)){
160 if (pfd[0].revents &amp; POLLIN){
161 printf("Getting QPSK event\n");
162 if ( ioctl(front, FE_GET_EVENT, &amp;event)
163
164 == -EOVERFLOW){
165 perror("qpsk get event");
166 return -1;
167 }
168 printf("Received ");
169 switch(event.type){
170 case FE_UNEXPECTED_EV:
171 printf("unexpected event\n");
172 return -1;
173 case FE_FAILURE_EV:
174 printf("failure event\n");
175 return -1;
176
177 case FE_COMPLETION_EV:
178 printf("completion event\n");
179 }
180 }
181 }
182
183
184 pesFilterParams.pid = vpid;
185 pesFilterParams.input = DMX_IN_FRONTEND;
186 pesFilterParams.output = DMX_OUT_DECODER;
187 pesFilterParams.pes_type = DMX_PES_VIDEO;
188 pesFilterParams.flags = DMX_IMMEDIATE_START;
189 if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
190 perror("set_vpid");
191 return -1;
192 }
193
194 pesFilterParams.pid = apid;
195 pesFilterParams.input = DMX_IN_FRONTEND;
196 pesFilterParams.output = DMX_OUT_DECODER;
197 pesFilterParams.pes_type = DMX_PES_AUDIO;
198 pesFilterParams.flags = DMX_IMMEDIATE_START;
199 if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
200 perror("set_apid");
201 return -1;
202 }
203
204 pesFilterParams.pid = tpid;
205 pesFilterParams.input = DMX_IN_FRONTEND;
206 pesFilterParams.output = DMX_OUT_DECODER;
207 pesFilterParams.pes_type = DMX_PES_TELETEXT;
208 pesFilterParams.flags = DMX_IMMEDIATE_START;
209 if (ioctl(demux3, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
210 perror("set_tpid");
211 return -1;
212 }
213
214 return has_signal(fds);
215 }
216
217</programlisting>
218<para>The program assumes that you are using a universal LNB and a standard DiSEqC
219switch with up to 4 addresses. Of course, you could build in some more checking if
220tuning was successful and maybe try to repeat the tuning process. Depending on the
221external hardware, i.e. LNB and DiSEqC switch, and weather conditions this may be
222necessary.
223</para>
224</section>
225
226<section id="the_dvr_device">
227<title>The DVR device</title>
228<para>The following program code shows how to use the DVR device for recording.
229</para>
230<programlisting>
231 #include &#x003C;sys/ioctl.h&#x003E;
232 #include &#x003C;stdio.h&#x003E;
233 #include &#x003C;stdint.h&#x003E;
234 #include &#x003C;sys/types.h&#x003E;
235 #include &#x003C;sys/stat.h&#x003E;
236 #include &#x003C;fcntl.h&#x003E;
237 #include &#x003C;time.h&#x003E;
238 #include &#x003C;unistd.h&#x003E;
239
240 #include &#x003C;linux/dvb/dmx.h&#x003E;
241 #include &#x003C;linux/dvb/video.h&#x003E;
242 #include &#x003C;sys/poll.h&#x003E;
243 #define DVR "/dev/dvb/adapter0/dvr1"
244 #define AUDIO "/dev/dvb/adapter0/audio1"
245 #define VIDEO "/dev/dvb/adapter0/video1"
246
247 #define BUFFY (188&#x22C6;20)
248 #define MAX_LENGTH (1024&#x22C6;1024&#x22C6;5) /&#x22C6; record 5MB &#x22C6;/
249
250
251 /&#x22C6; switch the demuxes to recording, assuming the transponder is tuned &#x22C6;/
252
253 /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
254 /&#x22C6; vpid, apid: PIDs of video and audio channels &#x22C6;/
255
256 int switch_to_record(int demux1, int demux2, uint16_t vpid, uint16_t apid)
257 {
258 struct dmx_pes_filter_params pesFilterParams;
259
260 if (demux1 &#x003C; 0){
261 if ((demux1=open(DMX, O_RDWR|O_NONBLOCK))
262 &#x003C; 0){
263 perror("DEMUX DEVICE: ");
264 return -1;
265 }
266 }
267
268 if (demux2 &#x003C; 0){
269 if ((demux2=open(DMX, O_RDWR|O_NONBLOCK))
270 &#x003C; 0){
271 perror("DEMUX DEVICE: ");
272 return -1;
273 }
274 }
275
276 pesFilterParams.pid = vpid;
277 pesFilterParams.input = DMX_IN_FRONTEND;
278 pesFilterParams.output = DMX_OUT_TS_TAP;
279 pesFilterParams.pes_type = DMX_PES_VIDEO;
280 pesFilterParams.flags = DMX_IMMEDIATE_START;
281 if (ioctl(demux1, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
282 perror("DEMUX DEVICE");
283 return -1;
284 }
285 pesFilterParams.pid = apid;
286 pesFilterParams.input = DMX_IN_FRONTEND;
287 pesFilterParams.output = DMX_OUT_TS_TAP;
288 pesFilterParams.pes_type = DMX_PES_AUDIO;
289 pesFilterParams.flags = DMX_IMMEDIATE_START;
290 if (ioctl(demux2, DMX_SET_PES_FILTER, &amp;pesFilterParams) &#x003C; 0){
291 perror("DEMUX DEVICE");
292 return -1;
293 }
294 return 0;
295 }
296
297 /&#x22C6; start recording MAX_LENGTH , assuming the transponder is tuned &#x22C6;/
298
299 /&#x22C6; demux1, demux2: file descriptor of video and audio filters &#x22C6;/
300 /&#x22C6; vpid, apid: PIDs of video and audio channels &#x22C6;/
301 int record_dvr(int demux1, int demux2, uint16_t vpid, uint16_t apid)
302 {
303 int i;
304 int len;
305 int written;
306 uint8_t buf[BUFFY];
307 uint64_t length;
308 struct pollfd pfd[1];
309 int dvr, dvr_out;
310
311 /&#x22C6; open dvr device &#x22C6;/
312 if ((dvr = open(DVR, O_RDONLY|O_NONBLOCK)) &#x003C; 0){
313 perror("DVR DEVICE");
314 return -1;
315 }
316
317 /&#x22C6; switch video and audio demuxes to dvr &#x22C6;/
318 printf ("Switching dvr on\n");
319 i = switch_to_record(demux1, demux2, vpid, apid);
320 printf("finished: ");
321
322 printf("Recording %2.0f MB of test file in TS format\n",
323 MAX_LENGTH/(1024.0&#x22C6;1024.0));
324 length = 0;
325
326 /&#x22C6; open output file &#x22C6;/
327 if ((dvr_out = open(DVR_FILE,O_WRONLY|O_CREAT
328 |O_TRUNC, S_IRUSR|S_IWUSR
329 |S_IRGRP|S_IWGRP|S_IROTH|
330 S_IWOTH)) &#x003C; 0){
331 perror("Can't open file for dvr test");
332 return -1;
333 }
334
335 pfd[0].fd = dvr;
336 pfd[0].events = POLLIN;
337
338 /&#x22C6; poll for dvr data and write to file &#x22C6;/
339 while (length &#x003C; MAX_LENGTH ) {
340 if (poll(pfd,1,1)){
341 if (pfd[0].revents &amp; POLLIN){
342 len = read(dvr, buf, BUFFY);
343 if (len &#x003C; 0){
344 perror("recording");
345 return -1;
346 }
347 if (len &#x003E; 0){
348 written = 0;
349 while (written &#x003C; len)
350 written +=
351 write (dvr_out,
352 buf, len);
353 length += len;
354 printf("written %2.0f MB\r",
355 length/1024./1024.);
356 }
357 }
358 }
359 }
360 return 0;
361 }
362
363</programlisting>
364
365</section>
diff --git a/Documentation/DocBook/dvb/frontend.xml b/Documentation/DocBook/dvb/frontend.xml
new file mode 100644
index 000000000000..9d89a7b94fd5
--- /dev/null
+++ b/Documentation/DocBook/dvb/frontend.xml
@@ -0,0 +1,1766 @@
1<title>DVB Frontend API</title>
2
3<para>The DVB frontend device controls the tuner and DVB demodulator
4hardware. It can be accessed through <emphasis
5role="tt">/dev/dvb/adapter0/frontend0</emphasis>. Data types and and
6ioctl definitions can be accessed by including <emphasis
7role="tt">linux/dvb/frontend.h</emphasis> in your application.</para>
8
9<para>DVB frontends come in three varieties: DVB-S (satellite), DVB-C
10(cable) and DVB-T (terrestrial). Transmission via the internet (DVB-IP)
11is not yet handled by this API but a future extension is possible. For
12DVB-S the frontend device also supports satellite equipment control
13(SEC) via DiSEqC and V-SEC protocols. The DiSEqC (digital SEC)
14specification is available from
15<ulink url="http://www.eutelsat.com/satellites/4_5_5.html">Eutelsat</ulink>.</para>
16
17<para>Note that the DVB API may also be used for MPEG decoder-only PCI
18cards, in which case there exists no frontend device.</para>
19
20<section id="frontend_types">
21<title>Frontend Data Types</title>
22
23<section id="frontend_type">
24<title>frontend type</title>
25
26<para>For historical reasons frontend types are named after the type of modulation used in
27transmission.</para>
28<programlisting>
29 typedef enum fe_type {
30 FE_QPSK, /&#x22C6; DVB-S &#x22C6;/
31 FE_QAM, /&#x22C6; DVB-C &#x22C6;/
32 FE_OFDM /&#x22C6; DVB-T &#x22C6;/
33 } fe_type_t;
34</programlisting>
35
36</section>
37
38<section id="frontend_caps">
39<title>frontend capabilities</title>
40
41<para>Capabilities describe what a frontend can do. Some capabilities can only be supported for
42a specific frontend type.</para>
43<programlisting>
44 typedef enum fe_caps {
45 FE_IS_STUPID = 0,
46 FE_CAN_INVERSION_AUTO = 0x1,
47 FE_CAN_FEC_1_2 = 0x2,
48 FE_CAN_FEC_2_3 = 0x4,
49 FE_CAN_FEC_3_4 = 0x8,
50 FE_CAN_FEC_4_5 = 0x10,
51 FE_CAN_FEC_5_6 = 0x20,
52 FE_CAN_FEC_6_7 = 0x40,
53 FE_CAN_FEC_7_8 = 0x80,
54 FE_CAN_FEC_8_9 = 0x100,
55 FE_CAN_FEC_AUTO = 0x200,
56 FE_CAN_QPSK = 0x400,
57 FE_CAN_QAM_16 = 0x800,
58 FE_CAN_QAM_32 = 0x1000,
59 FE_CAN_QAM_64 = 0x2000,
60 FE_CAN_QAM_128 = 0x4000,
61 FE_CAN_QAM_256 = 0x8000,
62 FE_CAN_QAM_AUTO = 0x10000,
63 FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000,
64 FE_CAN_BANDWIDTH_AUTO = 0x40000,
65 FE_CAN_GUARD_INTERVAL_AUTO = 0x80000,
66 FE_CAN_HIERARCHY_AUTO = 0x100000,
67 FE_CAN_MUTE_TS = 0x80000000,
68 FE_CAN_CLEAN_SETUP = 0x40000000
69 } fe_caps_t;
70</programlisting>
71</section>
72
73<section id="frontend_info">
74<title>frontend information</title>
75
76<para>Information about the frontend ca be queried with FE_GET_INFO.</para>
77
78<programlisting>
79 struct dvb_frontend_info {
80 char name[128];
81 fe_type_t type;
82 uint32_t frequency_min;
83 uint32_t frequency_max;
84 uint32_t frequency_stepsize;
85 uint32_t frequency_tolerance;
86 uint32_t symbol_rate_min;
87 uint32_t symbol_rate_max;
88 uint32_t symbol_rate_tolerance; /&#x22C6; ppm &#x22C6;/
89 uint32_t notifier_delay; /&#x22C6; ms &#x22C6;/
90 fe_caps_t caps;
91 };
92</programlisting>
93</section>
94
95<section id="frontend_diseqc">
96<title>diseqc master command</title>
97
98<para>A message sent from the frontend to DiSEqC capable equipment.</para>
99<programlisting>
100 struct dvb_diseqc_master_cmd {
101 uint8_t msg [6]; /&#x22C6; { framing, address, command, data[3] } &#x22C6;/
102 uint8_t msg_len; /&#x22C6; valid values are 3...6 &#x22C6;/
103 };
104</programlisting>
105</section>
106<section role="subsection">
107<title>diseqc slave reply</title>
108
109<para>A reply to the frontend from DiSEqC 2.0 capable equipment.</para>
110<programlisting>
111 struct dvb_diseqc_slave_reply {
112 uint8_t msg [4]; /&#x22C6; { framing, data [3] } &#x22C6;/
113 uint8_t msg_len; /&#x22C6; valid values are 0...4, 0 means no msg &#x22C6;/
114 int timeout; /&#x22C6; return from ioctl after timeout ms with &#x22C6;/
115 }; /&#x22C6; errorcode when no message was received &#x22C6;/
116</programlisting>
117</section>
118
119<section id="frontend_diseqc_slave_reply">
120<title>diseqc slave reply</title>
121<para>The voltage is usually used with non-DiSEqC capable LNBs to switch the polarzation
122(horizontal/vertical). When using DiSEqC epuipment this voltage has to be switched
123consistently to the DiSEqC commands as described in the DiSEqC spec.</para>
124<programlisting>
125 typedef enum fe_sec_voltage {
126 SEC_VOLTAGE_13,
127 SEC_VOLTAGE_18
128 } fe_sec_voltage_t;
129</programlisting>
130</section>
131
132<section id="frontend_sec_tone">
133<title>SEC continuous tone</title>
134
135<para>The continous 22KHz tone is usually used with non-DiSEqC capable LNBs to switch the
136high/low band of a dual-band LNB. When using DiSEqC epuipment this voltage has to
137be switched consistently to the DiSEqC commands as described in the DiSEqC
138spec.</para>
139<programlisting>
140 typedef enum fe_sec_tone_mode {
141 SEC_TONE_ON,
142 SEC_TONE_OFF
143 } fe_sec_tone_mode_t;
144</programlisting>
145</section>
146
147<section id="frontend_sec_burst">
148<title>SEC tone burst</title>
149
150<para>The 22KHz tone burst is usually used with non-DiSEqC capable switches to select
151between two connected LNBs/satellites. When using DiSEqC epuipment this voltage has to
152be switched consistently to the DiSEqC commands as described in the DiSEqC
153spec.</para>
154<programlisting>
155 typedef enum fe_sec_mini_cmd {
156 SEC_MINI_A,
157 SEC_MINI_B
158 } fe_sec_mini_cmd_t;
159</programlisting>
160
161<para></para>
162</section>
163
164<section id="frontend_status">
165<title>frontend status</title>
166<para>Several functions of the frontend device use the fe_status data type defined
167by</para>
168<programlisting>
169 typedef enum fe_status {
170 FE_HAS_SIGNAL = 0x01, /&#x22C6; found something above the noise level &#x22C6;/
171 FE_HAS_CARRIER = 0x02, /&#x22C6; found a DVB signal &#x22C6;/
172 FE_HAS_VITERBI = 0x04, /&#x22C6; FEC is stable &#x22C6;/
173 FE_HAS_SYNC = 0x08, /&#x22C6; found sync bytes &#x22C6;/
174 FE_HAS_LOCK = 0x10, /&#x22C6; everything's working... &#x22C6;/
175 FE_TIMEDOUT = 0x20, /&#x22C6; no lock within the last ~2 seconds &#x22C6;/
176 FE_REINIT = 0x40 /&#x22C6; frontend was reinitialized, &#x22C6;/
177 } fe_status_t; /&#x22C6; application is recommned to reset &#x22C6;/
178</programlisting>
179<para>to indicate the current state and/or state changes of the frontend hardware.
180</para>
181
182</section>
183
184<section id="frontend_params">
185<title>frontend parameters</title>
186<para>The kind of parameters passed to the frontend device for tuning depend on
187the kind of hardware you are using. All kinds of parameters are combined as an
188union in the FrontendParameters structure:</para>
189<programlisting>
190 struct dvb_frontend_parameters {
191 uint32_t frequency; /&#x22C6; (absolute) frequency in Hz for QAM/OFDM &#x22C6;/
192 /&#x22C6; intermediate frequency in kHz for QPSK &#x22C6;/
193 fe_spectral_inversion_t inversion;
194 union {
195 struct dvb_qpsk_parameters qpsk;
196 struct dvb_qam_parameters qam;
197 struct dvb_ofdm_parameters ofdm;
198 } u;
199 };
200</programlisting>
201<para>For satellite QPSK frontends you have to use the <constant>QPSKParameters</constant> member defined by</para>
202<programlisting>
203 struct dvb_qpsk_parameters {
204 uint32_t symbol_rate; /&#x22C6; symbol rate in Symbols per second &#x22C6;/
205 fe_code_rate_t fec_inner; /&#x22C6; forward error correction (see above) &#x22C6;/
206 };
207</programlisting>
208<para>for cable QAM frontend you use the <constant>QAMParameters</constant> structure</para>
209<programlisting>
210 struct dvb_qam_parameters {
211 uint32_t symbol_rate; /&#x22C6; symbol rate in Symbols per second &#x22C6;/
212 fe_code_rate_t fec_inner; /&#x22C6; forward error correction (see above) &#x22C6;/
213 fe_modulation_t modulation; /&#x22C6; modulation type (see above) &#x22C6;/
214 };
215</programlisting>
216<para>DVB-T frontends are supported by the <constant>OFDMParamters</constant> structure
217</para>
218<programlisting>
219 struct dvb_ofdm_parameters {
220 fe_bandwidth_t bandwidth;
221 fe_code_rate_t code_rate_HP; /&#x22C6; high priority stream code rate &#x22C6;/
222 fe_code_rate_t code_rate_LP; /&#x22C6; low priority stream code rate &#x22C6;/
223 fe_modulation_t constellation; /&#x22C6; modulation type (see above) &#x22C6;/
224 fe_transmit_mode_t transmission_mode;
225 fe_guard_interval_t guard_interval;
226 fe_hierarchy_t hierarchy_information;
227 };
228</programlisting>
229<para>In the case of QPSK frontends the <constant>Frequency</constant> field specifies the intermediate
230frequency, i.e. the offset which is effectively added to the local oscillator frequency (LOF) of
231the LNB. The intermediate frequency has to be specified in units of kHz. For QAM and
232OFDM frontends the Frequency specifies the absolute frequency and is given in
233Hz.
234</para>
235<para>The Inversion field can take one of these values:
236</para>
237<programlisting>
238 typedef enum fe_spectral_inversion {
239 INVERSION_OFF,
240 INVERSION_ON,
241 INVERSION_AUTO
242 } fe_spectral_inversion_t;
243</programlisting>
244<para>It indicates if spectral inversion should be presumed or not. In the automatic setting
245(<constant>INVERSION_AUTO</constant>) the hardware will try to figure out the correct setting by
246itself.
247</para>
248<para>The possible values for the <constant>FEC_inner</constant> field are
249</para>
250<programlisting>
251 typedef enum fe_code_rate {
252 FEC_NONE = 0,
253 FEC_1_2,
254 FEC_2_3,
255 FEC_3_4,
256 FEC_4_5,
257 FEC_5_6,
258 FEC_6_7,
259 FEC_7_8,
260 FEC_8_9,
261 FEC_AUTO
262 } fe_code_rate_t;
263</programlisting>
264<para>which correspond to error correction rates of 1/2, 2/3, etc., no error correction or auto
265detection.
266</para>
267<para>For cable and terrestrial frontends (QAM and OFDM) one also has to specify the quadrature
268modulation mode which can be one of the following:
269</para>
270<programlisting>
271 typedef enum fe_modulation {
272 QPSK,
273 QAM_16,
274 QAM_32,
275 QAM_64,
276 QAM_128,
277 QAM_256,
278 QAM_AUTO
279 } fe_modulation_t;
280</programlisting>
281<para>Finally, there are several more parameters for OFDM:
282</para>
283<programlisting>
284 typedef enum fe_transmit_mode {
285 TRANSMISSION_MODE_2K,
286 TRANSMISSION_MODE_8K,
287 TRANSMISSION_MODE_AUTO
288 } fe_transmit_mode_t;
289</programlisting>
290 <programlisting>
291 typedef enum fe_bandwidth {
292 BANDWIDTH_8_MHZ,
293 BANDWIDTH_7_MHZ,
294 BANDWIDTH_6_MHZ,
295 BANDWIDTH_AUTO
296 } fe_bandwidth_t;
297</programlisting>
298 <programlisting>
299 typedef enum fe_guard_interval {
300 GUARD_INTERVAL_1_32,
301 GUARD_INTERVAL_1_16,
302 GUARD_INTERVAL_1_8,
303 GUARD_INTERVAL_1_4,
304 GUARD_INTERVAL_AUTO
305 } fe_guard_interval_t;
306</programlisting>
307 <programlisting>
308 typedef enum fe_hierarchy {
309 HIERARCHY_NONE,
310 HIERARCHY_1,
311 HIERARCHY_2,
312 HIERARCHY_4,
313 HIERARCHY_AUTO
314 } fe_hierarchy_t;
315</programlisting>
316
317</section>
318
319<section id="frontend_events">
320<title>frontend events</title>
321 <programlisting>
322 struct dvb_frontend_event {
323 fe_status_t status;
324 struct dvb_frontend_parameters parameters;
325 };
326</programlisting>
327 </section>
328</section>
329
330
331<section id="frontend_fcalls">
332<title>Frontend Function Calls</title>
333
334<section id="frontend_f_open">
335<title>open()</title>
336<para>DESCRIPTION</para>
337<informaltable><tgroup cols="1"><tbody><row>
338<entry align="char">
339<para>This system call opens a named frontend device (/dev/dvb/adapter0/frontend0)
340 for subsequent use. Usually the first thing to do after a successful open is to
341 find out the frontend type with FE_GET_INFO.</para>
342<para>The device can be opened in read-only mode, which only allows monitoring of
343 device status and statistics, or read/write mode, which allows any kind of use
344 (e.g. performing tuning operations.)
345</para>
346<para>In a system with multiple front-ends, it is usually the case that multiple devices
347 cannot be open in read/write mode simultaneously. As long as a front-end
348 device is opened in read/write mode, other open() calls in read/write mode will
349 either fail or block, depending on whether non-blocking or blocking mode was
350 specified. A front-end device opened in blocking mode can later be put into
351 non-blocking mode (and vice versa) using the F_SETFL command of the fcntl
352 system call. This is a standard system call, documented in the Linux manual
353 page for fcntl. When an open() call has succeeded, the device will be ready
354 for use in the specified mode. This implies that the corresponding hardware is
355 powered up, and that other front-ends may have been powered down to make
356 that possible.</para>
357</entry>
358 </row></tbody></tgroup></informaltable>
359
360<para>SYNOPSIS</para>
361<informaltable><tgroup cols="1"><tbody><row><entry
362 align="char">
363<para>int open(const char &#x22C6;deviceName, int flags);</para>
364</entry>
365 </row></tbody></tgroup></informaltable>
366<para>PARAMETERS
367</para>
368<informaltable><tgroup cols="2"><tbody><row><entry
369 align="char">
370<para>const char
371 *deviceName</para>
372</entry><entry
373 align="char">
374<para>Name of specific video device.</para>
375</entry>
376 </row><row><entry
377 align="char">
378<para>int flags</para>
379</entry><entry
380 align="char">
381<para>A bit-wise OR of the following flags:</para>
382</entry>
383 </row><row><entry
384 align="char">
385</entry><entry
386 align="char">
387<para>O_RDONLY read-only access</para>
388</entry>
389 </row><row><entry
390 align="char">
391</entry><entry
392 align="char">
393<para>O_RDWR read/write access</para>
394</entry>
395 </row><row><entry
396 align="char">
397</entry><entry
398 align="char">
399<para>O_NONBLOCK open in non-blocking mode</para>
400</entry>
401 </row><row><entry
402 align="char">
403</entry><entry
404 align="char">
405<para>(blocking mode is the default)</para>
406</entry>
407 </row></tbody></tgroup></informaltable>
408<para>ERRORS
409</para>
410<informaltable><tgroup cols="2"><tbody><row><entry
411 align="char">
412<para>ENODEV</para>
413</entry><entry
414 align="char">
415<para>Device driver not loaded/available.</para>
416</entry>
417 </row><row><entry
418 align="char">
419<para>EINTERNAL</para>
420</entry><entry
421 align="char">
422<para>Internal error.</para>
423</entry>
424 </row><row><entry
425 align="char">
426<para>EBUSY</para>
427</entry><entry
428 align="char">
429<para>Device or resource busy.</para>
430</entry>
431 </row><row><entry
432 align="char">
433<para>EINVAL</para>
434</entry><entry
435 align="char">
436<para>Invalid argument.</para>
437</entry>
438 </row></tbody></tgroup></informaltable>
439</section>
440
441<section id="frontend_f_close">
442<title>close()</title>
443<para>DESCRIPTION
444</para>
445<informaltable><tgroup cols="1"><tbody><row><entry
446 align="char">
447<para>This system call closes a previously opened front-end device. After closing
448 a front-end device, its corresponding hardware might be powered down
449 automatically.</para>
450</entry>
451 </row></tbody></tgroup></informaltable>
452<para>SYNOPSIS
453</para>
454<informaltable><tgroup cols="1"><tbody><row><entry
455 align="char">
456<para>int close(int fd);</para>
457</entry>
458 </row></tbody></tgroup></informaltable>
459<para>PARAMETERS
460</para>
461<informaltable><tgroup cols="2"><tbody><row><entry
462 align="char">
463<para>int fd</para>
464</entry><entry
465 align="char">
466<para>File descriptor returned by a previous call to open().</para>
467</entry>
468 </row></tbody></tgroup></informaltable>
469<para>ERRORS
470</para>
471<informaltable><tgroup cols="2"><tbody><row><entry
472 align="char">
473<para>EBADF</para>
474</entry><entry
475 align="char">
476<para>fd is not a valid open file descriptor.</para>
477</entry>
478 </row></tbody></tgroup></informaltable>
479</section>
480
481<section id="frontend_read_status">
482<title>FE_READ_STATUS</title>
483<para>DESCRIPTION
484</para>
485<informaltable><tgroup cols="1"><tbody><row><entry
486 align="char">
487<para>This ioctl call returns status information about the front-end. This call only
488 requires read-only access to the device.</para>
489</entry>
490 </row></tbody></tgroup></informaltable>
491<para>SYNOPSIS
492</para>
493<informaltable><tgroup cols="1"><tbody><row><entry
494 align="char">
495<para>int ioctl(int fd, int request = FE_READ_STATUS,
496 fe_status_t &#x22C6;status);</para>
497</entry>
498 </row></tbody></tgroup></informaltable>
499<para>PARAMETERS
500</para>
501
502<informaltable><tgroup cols="2"><tbody><row><entry
503 align="char">
504<para>int fd</para>
505</entry><entry
506 align="char">
507<para>File descriptor returned by a previous call to open().</para>
508</entry>
509 </row><row><entry
510 align="char">
511<para>int request</para>
512</entry><entry
513 align="char">
514<para>Equals FE_READ_STATUS for this command.</para>
515</entry>
516 </row><row><entry
517 align="char">
518<para>struct fe_status_t
519 *status</para>
520</entry><entry
521 align="char">
522<para>Points to the location where the front-end status word is
523 to be stored.</para>
524</entry>
525 </row></tbody></tgroup></informaltable>
526<para>ERRORS
527</para>
528<informaltable><tgroup cols="2"><tbody><row><entry
529 align="char">
530<para>EBADF</para>
531</entry><entry
532 align="char">
533<para>fd is not a valid open file descriptor.</para>
534</entry>
535 </row><row><entry
536 align="char">
537<para>EFAULT</para>
538</entry><entry
539 align="char">
540<para>status points to invalid address.</para>
541</entry>
542 </row></tbody></tgroup></informaltable>
543</section>
544
545<section id="frontend_read_ber">
546<title>FE_READ_BER</title>
547<para>DESCRIPTION
548</para>
549<informaltable><tgroup cols="1"><tbody><row><entry
550 align="char">
551<para>This ioctl call returns the bit error rate for the signal currently
552 received/demodulated by the front-end. For this command, read-only access to
553 the device is sufficient.</para>
554</entry>
555 </row></tbody></tgroup></informaltable>
556<para>SYNOPSIS
557</para>
558<informaltable><tgroup cols="1"><tbody><row><entry
559 align="char">
560<para>int ioctl(int fd, int request = FE_READ_BER,
561 uint32_t &#x22C6;ber);</para>
562</entry>
563 </row></tbody></tgroup></informaltable>
564<para>PARAMETERS
565</para>
566<informaltable><tgroup cols="2"><tbody><row><entry
567 align="char">
568<para>int fd</para>
569</entry><entry
570 align="char">
571<para>File descriptor returned by a previous call to open().</para>
572</entry>
573 </row><row><entry
574 align="char">
575<para>int request</para>
576</entry><entry
577 align="char">
578<para>Equals FE_READ_BER for this command.</para>
579</entry>
580 </row><row><entry
581 align="char">
582<para>uint32_t *ber</para>
583</entry><entry
584 align="char">
585<para>The bit error rate is stored into *ber.</para>
586</entry>
587 </row></tbody></tgroup></informaltable>
588<para>ERRORS
589</para>
590<informaltable><tgroup cols="2"><tbody><row><entry
591 align="char">
592<para>EBADF</para>
593</entry><entry
594 align="char">
595<para>fd is not a valid open file descriptor.</para>
596</entry>
597 </row><row><entry
598 align="char">
599<para>EFAULT</para>
600</entry><entry
601 align="char">
602<para>ber points to invalid address.</para>
603</entry>
604 </row><row><entry
605 align="char">
606<para>ENOSIGNAL</para>
607</entry><entry
608 align="char">
609<para>There is no signal, thus no meaningful bit error rate. Also
610 returned if the front-end is not turned on.</para>
611</entry>
612 </row><row><entry
613 align="char">
614<para>ENOSYS</para>
615</entry><entry
616 align="char">
617<para>Function not available for this device.</para>
618</entry>
619 </row></tbody></tgroup></informaltable>
620</section>
621
622<section id="frontend_read_snr">
623<title>FE_READ_SNR</title>
624
625<para>DESCRIPTION
626</para>
627<informaltable><tgroup cols="1"><tbody><row><entry
628 align="char">
629<para>This ioctl call returns the signal-to-noise ratio for the signal currently received
630 by the front-end. For this command, read-only access to the device is sufficient.</para>
631</entry>
632 </row></tbody></tgroup></informaltable>
633<para>SYNOPSIS
634</para>
635<informaltable><tgroup cols="1"><tbody><row><entry
636 align="char">
637<para>int ioctl(int fd, int request = FE_READ_SNR, int16_t
638 &#x22C6;snr);</para>
639</entry>
640 </row></tbody></tgroup></informaltable>
641<para>PARAMETERS
642</para>
643<informaltable><tgroup cols="2"><tbody><row><entry
644 align="char">
645<para>int fd</para>
646</entry><entry
647 align="char">
648<para>File descriptor returned by a previous call to open().</para>
649</entry>
650 </row><row><entry
651 align="char">
652<para>int request</para>
653</entry><entry
654 align="char">
655<para>Equals FE_READ_SNR for this command.</para>
656</entry>
657 </row><row><entry
658 align="char">
659<para>int16_t *snr</para>
660</entry><entry
661 align="char">
662<para>The signal-to-noise ratio is stored into *snr.</para>
663</entry>
664 </row></tbody></tgroup></informaltable>
665
666<para>ERRORS
667</para>
668<informaltable><tgroup cols="2"><tbody><row><entry
669 align="char">
670<para>EBADF</para>
671</entry><entry
672 align="char">
673<para>fd is not a valid open file descriptor.</para>
674</entry>
675 </row><row><entry
676 align="char">
677<para>EFAULT</para>
678</entry><entry
679 align="char">
680<para>snr points to invalid address.</para>
681</entry>
682 </row><row><entry
683 align="char">
684<para>ENOSIGNAL</para>
685</entry><entry
686 align="char">
687<para>There is no signal, thus no meaningful signal strength
688 value. Also returned if front-end is not turned on.</para>
689</entry>
690 </row><row><entry
691 align="char">
692<para>ENOSYS</para>
693</entry><entry
694 align="char">
695<para>Function not available for this device.</para>
696</entry>
697 </row></tbody></tgroup></informaltable>
698</section>
699
700<section id="frontend_read_signal_strength">
701<title>FE_READ_SIGNAL_STRENGTH</title>
702<para>DESCRIPTION
703</para>
704<informaltable><tgroup cols="1"><tbody><row><entry
705 align="char">
706<para>This ioctl call returns the signal strength value for the signal currently received
707 by the front-end. For this command, read-only access to the device is sufficient.</para>
708</entry>
709 </row></tbody></tgroup></informaltable>
710<para>SYNOPSIS
711</para>
712<informaltable><tgroup cols="1"><tbody><row><entry
713 align="char">
714<para>int ioctl( int fd, int request =
715 FE_READ_SIGNAL_STRENGTH, int16_t &#x22C6;strength);</para>
716</entry>
717 </row></tbody></tgroup></informaltable>
718
719<para>PARAMETERS
720</para>
721<informaltable><tgroup cols="2"><tbody><row><entry
722 align="char">
723<para>int fd</para>
724</entry><entry
725 align="char">
726<para>File descriptor returned by a previous call to open().</para>
727</entry>
728 </row><row><entry
729 align="char">
730<para>int request</para>
731</entry><entry
732 align="char">
733<para>Equals FE_READ_SIGNAL_STRENGTH for this
734 command.</para>
735</entry>
736 </row><row><entry
737 align="char">
738<para>int16_t *strength</para>
739</entry><entry
740 align="char">
741<para>The signal strength value is stored into *strength.</para>
742</entry>
743 </row></tbody></tgroup></informaltable>
744<para>ERRORS
745</para>
746<informaltable><tgroup cols="2"><tbody><row><entry
747 align="char">
748<para>EBADF</para>
749</entry><entry
750 align="char">
751<para>fd is not a valid open file descriptor.</para>
752</entry>
753 </row><row><entry
754 align="char">
755<para>EFAULT</para>
756</entry><entry
757 align="char">
758<para>status points to invalid address.</para>
759</entry>
760 </row><row><entry
761 align="char">
762<para>ENOSIGNAL</para>
763</entry><entry
764 align="char">
765<para>There is no signal, thus no meaningful signal strength
766 value. Also returned if front-end is not turned on.</para>
767</entry>
768 </row><row><entry
769 align="char">
770<para>ENOSYS</para>
771</entry><entry
772 align="char">
773<para>Function not available for this device.</para>
774</entry>
775 </row></tbody></tgroup></informaltable>
776</section>
777
778<section id="frontend_read_ub">
779<title>FE_READ_UNCORRECTED_BLOCKS</title>
780<para>DESCRIPTION
781</para>
782<informaltable><tgroup cols="1"><tbody><row><entry
783 align="char">
784<para>This ioctl call returns the number of uncorrected blocks detected by the device
785 driver during its lifetime. For meaningful measurements, the increment in block
786 count during a specific time interval should be calculated. For this command,
787 read-only access to the device is sufficient.</para>
788</entry>
789 </row><row><entry
790 align="char">
791<para>Note that the counter will wrap to zero after its maximum count has been
792 reached.</para>
793</entry>
794 </row></tbody></tgroup></informaltable>
795<para>SYNOPSIS
796</para>
797<informaltable><tgroup cols="1"><tbody><row><entry
798 align="char">
799<para>int ioctl( int fd, int request =
800 FE_READ_UNCORRECTED_BLOCKS, uint32_t &#x22C6;ublocks);</para>
801</entry>
802 </row></tbody></tgroup></informaltable>
803<para>PARAMETERS
804</para>
805<informaltable><tgroup cols="2"><tbody><row><entry
806 align="char">
807<para>int fd</para>
808</entry><entry
809 align="char">
810<para>File descriptor returned by a previous call to open().</para>
811</entry>
812 </row><row><entry
813 align="char">
814<para>int request</para>
815</entry><entry
816 align="char">
817<para>Equals FE_READ_UNCORRECTED_BLOCKS for this
818 command.</para>
819</entry>
820 </row><row><entry
821 align="char">
822<para>uint32_t *ublocks</para>
823</entry><entry
824 align="char">
825<para>The total number of uncorrected blocks seen by the driver
826 so far.</para>
827</entry>
828 </row></tbody></tgroup></informaltable>
829<para>ERRORS
830</para>
831<informaltable><tgroup cols="2"><tbody><row><entry
832 align="char">
833<para>EBADF</para>
834</entry><entry
835 align="char">
836<para>fd is not a valid open file descriptor.</para>
837</entry>
838 </row><row><entry
839 align="char">
840<para>EFAULT</para>
841</entry><entry
842 align="char">
843<para>ublocks points to invalid address.</para>
844</entry>
845 </row><row><entry
846 align="char">
847<para>ENOSYS</para>
848</entry><entry
849 align="char">
850<para>Function not available for this device.</para>
851</entry>
852 </row></tbody></tgroup></informaltable>
853</section>
854
855<section id="frontend_set_fe">
856<title>FE_SET_FRONTEND</title>
857<para>DESCRIPTION
858</para>
859<informaltable><tgroup cols="1"><tbody><row><entry
860 align="char">
861<para>This ioctl call starts a tuning operation using specified parameters. The result
862 of this call will be successful if the parameters were valid and the tuning could
863 be initiated. The result of the tuning operation in itself, however, will arrive
864 asynchronously as an event (see documentation for FE_GET_EVENT and
865 FrontendEvent.) If a new FE_SET_FRONTEND operation is initiated before
866 the previous one was completed, the previous operation will be aborted in favor
867 of the new one. This command requires read/write access to the device.</para>
868</entry>
869 </row></tbody></tgroup></informaltable>
870
871<para>SYNOPSIS
872</para>
873<informaltable><tgroup cols="1"><tbody><row><entry
874 align="char">
875<para>int ioctl(int fd, int request = FE_SET_FRONTEND,
876 struct dvb_frontend_parameters &#x22C6;p);</para>
877</entry>
878 </row></tbody></tgroup></informaltable>
879<para>PARAMETERS
880</para>
881<informaltable><tgroup cols="2"><tbody><row><entry
882 align="char">
883<para>int fd</para>
884</entry><entry
885 align="char">
886<para>File descriptor returned by a previous call to open().</para>
887</entry>
888 </row><row><entry
889 align="char">
890<para>int request</para>
891</entry><entry
892 align="char">
893<para>Equals FE_SET_FRONTEND for this command.</para>
894</entry>
895 </row><row><entry
896 align="char">
897<para>struct
898 dvb_frontend_parameters
899 *p</para>
900</entry><entry
901 align="char">
902<para>Points to parameters for tuning operation.</para>
903</entry>
904 </row></tbody></tgroup></informaltable>
905<para>ERRORS
906</para>
907<informaltable><tgroup cols="2"><tbody><row><entry
908 align="char">
909<para>EBADF</para>
910</entry><entry
911 align="char">
912<para>fd is not a valid open file descriptor.</para>
913</entry>
914 </row><row><entry
915 align="char">
916<para>EFAULT</para>
917</entry><entry
918 align="char">
919<para>p points to invalid address.</para>
920</entry>
921 </row><row><entry
922 align="char">
923<para>EINVAL</para>
924</entry><entry
925 align="char">
926<para>Maximum supported symbol rate reached.</para>
927</entry>
928</row></tbody></tgroup></informaltable>
929</section>
930
931<section id="frontend_get_fe">
932<title>FE_GET_FRONTEND</title>
933<para>DESCRIPTION
934</para>
935<informaltable><tgroup cols="1"><tbody><row><entry
936 align="char">
937<para>This ioctl call queries the currently effective frontend parameters. For this
938 command, read-only access to the device is sufficient.</para>
939</entry>
940 </row></tbody></tgroup></informaltable>
941
942<para>SYNOPSIS
943</para>
944<informaltable><tgroup cols="1"><tbody><row><entry
945 align="char">
946<para>int ioctl(int fd, int request = FE_GET_FRONTEND,
947 struct dvb_frontend_parameters &#x22C6;p);</para>
948</entry>
949 </row></tbody></tgroup></informaltable>
950
951<para>PARAMETERS
952</para>
953<informaltable><tgroup cols="2"><tbody><row><entry
954 align="char">
955<para>int fd</para>
956</entry><entry
957 align="char">
958<para>File descriptor returned by a previous call to open().</para>
959</entry>
960 </row><row><entry
961 align="char">
962<para>int request</para>
963</entry><entry
964 align="char">
965<para>Equals FE_SET_FRONTEND for this command.</para>
966</entry>
967 </row><row><entry
968 align="char">
969<para>struct
970 dvb_frontend_parameters
971 *p</para>
972</entry><entry
973 align="char">
974<para>Points to parameters for tuning operation.</para>
975</entry>
976 </row></tbody></tgroup></informaltable>
977
978<para>ERRORS
979</para>
980
981<informaltable><tgroup cols="2"><tbody><row><entry
982 align="char">
983<para>EBADF</para>
984</entry><entry
985 align="char">
986<para>fd is not a valid open file descriptor.</para>
987</entry>
988 </row><row><entry
989 align="char">
990<para>EFAULT</para>
991</entry><entry
992 align="char">
993<para>p points to invalid address.</para>
994</entry>
995 </row><row><entry
996 align="char">
997<para>EINVAL</para>
998</entry><entry
999 align="char">
1000<para>Maximum supported symbol rate reached.</para>
1001</entry>
1002 </row></tbody></tgroup></informaltable>
1003
1004</section>
1005
1006<section id="frontend_get_event">
1007<title>FE_GET_EVENT</title>
1008<para>DESCRIPTION
1009</para>
1010<informaltable><tgroup cols="1"><tbody><row><entry
1011 align="char">
1012<para>This ioctl call returns a frontend event if available. If an event is not
1013 available, the behavior depends on whether the device is in blocking or
1014 non-blocking mode. In the latter case, the call fails immediately with errno
1015 set to EWOULDBLOCK. In the former case, the call blocks until an event
1016 becomes available.</para>
1017</entry>
1018 </row><row><entry
1019 align="char">
1020<para>The standard Linux poll() and/or select() system calls can be used with the
1021 device file descriptor to watch for new events. For select(), the file descriptor
1022 should be included in the exceptfds argument, and for poll(), POLLPRI should
1023 be specified as the wake-up condition. Since the event queue allocated is
1024 rather small (room for 8 events), the queue must be serviced regularly to avoid
1025 overflow. If an overflow happens, the oldest event is discarded from the queue,
1026 and an error (EOVERFLOW) occurs the next time the queue is read. After
1027 reporting the error condition in this fashion, subsequent FE_GET_EVENT
1028 calls will return events from the queue as usual.</para>
1029</entry>
1030 </row><row><entry
1031 align="char">
1032<para>For the sake of implementation simplicity, this command requires read/write
1033 access to the device.</para>
1034</entry>
1035 </row></tbody></tgroup></informaltable>
1036
1037<para>SYNOPSIS
1038</para>
1039<informaltable><tgroup cols="1"><tbody><row><entry
1040 align="char">
1041<para>int ioctl(int fd, int request = QPSK_GET_EVENT,
1042 struct dvb_frontend_event &#x22C6;ev);</para>
1043</entry>
1044 </row></tbody></tgroup></informaltable>
1045
1046<para>PARAMETERS
1047</para>
1048<informaltable><tgroup cols="2"><tbody><row><entry
1049 align="char">
1050<para>int fd</para>
1051</entry><entry
1052 align="char">
1053<para>File descriptor returned by a previous call to open().</para>
1054</entry>
1055 </row><row><entry
1056 align="char">
1057<para>int request</para>
1058</entry><entry
1059 align="char">
1060<para>Equals FE_GET_EVENT for this command.</para>
1061</entry>
1062 </row><row><entry
1063 align="char">
1064<para>struct
1065 dvb_frontend_event
1066 *ev</para>
1067</entry><entry
1068 align="char">
1069<para>Points to the location where the event,</para>
1070</entry>
1071 </row><row><entry
1072 align="char">
1073</entry><entry
1074 align="char">
1075<para>if any, is to be stored.</para>
1076</entry>
1077 </row></tbody></tgroup></informaltable>
1078
1079<para>ERRORS
1080</para>
1081<informaltable><tgroup cols="2"><tbody><row><entry
1082 align="char">
1083<para>EBADF</para>
1084</entry><entry
1085 align="char">
1086<para>fd is not a valid open file descriptor.</para>
1087</entry>
1088 </row><row><entry
1089 align="char">
1090<para>EFAULT</para>
1091</entry><entry
1092 align="char">
1093<para>ev points to invalid address.</para>
1094</entry>
1095 </row><row><entry
1096 align="char">
1097<para>EWOULDBLOCK</para>
1098</entry><entry
1099 align="char">
1100<para>There is no event pending, and the device is in
1101 non-blocking mode.</para>
1102</entry>
1103 </row><row><entry
1104 align="char">
1105<para>EOVERFLOW</para>
1106</entry><entry
1107 align="char">
1108</entry>
1109 </row><row><entry
1110 align="char">
1111</entry><entry
1112 align="char">
1113<para>Overflow in event queue - one or more events were lost.</para>
1114</entry>
1115</row></tbody></tgroup></informaltable>
1116</section>
1117
1118<section id="frontend_get_info">
1119<title>FE_GET_INFO</title>
1120<para>DESCRIPTION
1121</para>
1122<informaltable><tgroup cols="1"><tbody><row><entry
1123 align="char">
1124<para>This ioctl call returns information about the front-end. This call only requires
1125 read-only access to the device.</para>
1126</entry>
1127 </row></tbody></tgroup></informaltable>
1128<para>SYNOPSIS
1129</para>
1130
1131<informaltable><tgroup cols="1"><tbody><row><entry
1132 align="char">
1133<para> int ioctl(int fd, int request = FE_GET_INFO, struct
1134 dvb_frontend_info &#x22C6;info);</para>
1135</entry>
1136 </row></tbody></tgroup></informaltable>
1137<para>PARAMETERS
1138</para>
1139
1140<informaltable><tgroup cols="2"><tbody><row><entry
1141 align="char">
1142<para>int fd</para>
1143</entry><entry
1144 align="char">
1145<para>File descriptor returned by a previous call to open().</para>
1146</entry>
1147 </row><row><entry
1148 align="char">
1149<para>int request</para>
1150</entry><entry
1151 align="char">
1152<para>Equals FE_GET_INFO for this command.</para>
1153</entry>
1154 </row><row><entry
1155 align="char">
1156<para>struct
1157 dvb_frontend_info
1158 *info</para>
1159</entry><entry
1160 align="char">
1161<para>Points to the location where the front-end information is
1162 to be stored.</para>
1163</entry>
1164 </row></tbody></tgroup></informaltable>
1165<para>ERRORS
1166</para>
1167<informaltable><tgroup cols="2"><tbody><row><entry
1168 align="char">
1169<para>EBADF</para>
1170</entry><entry
1171 align="char">
1172<para>fd is not a valid open file descriptor.</para>
1173</entry>
1174 </row><row><entry
1175 align="char">
1176<para>EFAULT</para>
1177</entry><entry
1178 align="char">
1179<para>info points to invalid address.</para>
1180</entry>
1181</row></tbody></tgroup></informaltable>
1182</section>
1183
1184<section id="frontend_diseqc_reset_overload">
1185<title>FE_DISEQC_RESET_OVERLOAD</title>
1186<para>DESCRIPTION
1187</para>
1188<informaltable><tgroup cols="1"><tbody><row><entry
1189 align="char">
1190<para>If the bus has been automatically powered off due to power overload, this ioctl
1191 call restores the power to the bus. The call requires read/write access to the
1192 device. This call has no effect if the device is manually powered off. Not all
1193 DVB adapters support this ioctl.</para>
1194</entry>
1195 </row></tbody></tgroup></informaltable>
1196
1197<para>SYNOPSIS
1198</para>
1199<informaltable><tgroup cols="1"><tbody><row><entry
1200 align="char">
1201<para>int ioctl(int fd, int request =
1202 FE_DISEQC_RESET_OVERLOAD);</para>
1203</entry>
1204 </row></tbody></tgroup></informaltable>
1205<para>PARAMETERS
1206</para>
1207<informaltable><tgroup cols="2"><tbody><row><entry
1208 align="char">
1209<para>int fd</para>
1210</entry><entry
1211 align="char">
1212<para>File descriptor returned by a previous call to open().</para>
1213</entry>
1214 </row><row><entry
1215 align="char">
1216<para>int request</para>
1217</entry><entry
1218 align="char">
1219<para>Equals FE_DISEQC_RESET_OVERLOAD for this
1220 command.</para>
1221</entry>
1222 </row></tbody></tgroup></informaltable>
1223
1224<para>ERRORS
1225</para>
1226<informaltable><tgroup cols="2"><tbody><row><entry
1227 align="char">
1228<para>EBADF</para>
1229</entry><entry
1230 align="char">
1231<para>fd is not a valid file descriptor.</para>
1232</entry>
1233 </row><row><entry
1234 align="char">
1235<para>EPERM</para>
1236</entry><entry
1237 align="char">
1238<para>Permission denied (needs read/write access).</para>
1239</entry>
1240 </row><row><entry
1241 align="char">
1242<para>EINTERNAL</para>
1243</entry><entry
1244 align="char">
1245<para>Internal error in the device driver.</para>
1246</entry>
1247</row></tbody></tgroup></informaltable>
1248</section>
1249
1250<section id="frontend_diseqc_send_master_cmd">
1251<title>FE_DISEQC_SEND_MASTER_CMD</title>
1252<para>DESCRIPTION
1253</para>
1254<informaltable><tgroup cols="1"><tbody><row><entry
1255 align="char">
1256<para>This ioctl call is used to send a a DiSEqC command.</para>
1257</entry>
1258 </row></tbody></tgroup></informaltable>
1259<para>SYNOPSIS
1260</para>
1261<informaltable><tgroup cols="1"><tbody><row><entry
1262 align="char">
1263<para>int ioctl(int fd, int request =
1264 FE_DISEQC_SEND_MASTER_CMD, struct
1265 dvb_diseqc_master_cmd &#x22C6;cmd);</para>
1266</entry>
1267 </row></tbody></tgroup></informaltable>
1268
1269<para>PARAMETERS
1270</para>
1271<informaltable><tgroup cols="2"><tbody><row><entry
1272 align="char">
1273<para>int fd</para>
1274</entry><entry
1275 align="char">
1276<para>File descriptor returned by a previous call to open().</para>
1277</entry>
1278 </row><row><entry
1279 align="char">
1280<para>int request</para>
1281</entry><entry
1282 align="char">
1283<para>Equals FE_DISEQC_SEND_MASTER_CMD for this
1284 command.</para>
1285</entry>
1286 </row><row><entry
1287 align="char">
1288<para>struct
1289 dvb_diseqc_master_cmd
1290 *cmd</para>
1291</entry><entry
1292 align="char">
1293<para>Pointer to the command to be transmitted.</para>
1294</entry>
1295 </row></tbody></tgroup></informaltable>
1296
1297<para>ERRORS
1298</para>
1299<informaltable><tgroup cols="2"><tbody><row><entry
1300 align="char">
1301<para>EBADF</para>
1302</entry><entry
1303 align="char">
1304<para>fd is not a valid file descriptor.</para>
1305</entry>
1306 </row><row><entry
1307 align="char">
1308<para>EFAULT</para>
1309</entry><entry
1310 align="char">
1311<para>Seq points to an invalid address.</para>
1312</entry>
1313 </row><row><entry
1314 align="char">
1315<para>EINVAL</para>
1316</entry><entry
1317 align="char">
1318<para>The data structure referred to by seq is invalid in some
1319 way.</para>
1320</entry>
1321 </row><row><entry
1322 align="char">
1323<para>EPERM</para>
1324</entry><entry
1325 align="char">
1326<para>Permission denied (needs read/write access).</para>
1327</entry>
1328 </row><row><entry
1329 align="char">
1330<para>EINTERNAL</para>
1331</entry><entry
1332 align="char">
1333<para>Internal error in the device driver.</para>
1334</entry>
1335</row></tbody></tgroup></informaltable>
1336</section>
1337
1338<section id="frontend_diseqc_recv_slave_reply">
1339<title>FE_DISEQC_RECV_SLAVE_REPLY</title>
1340<para>DESCRIPTION
1341</para>
1342<informaltable><tgroup cols="1"><tbody><row><entry
1343 align="char">
1344<para>This ioctl call is used to receive reply to a DiSEqC 2.0 command.</para>
1345</entry>
1346 </row></tbody></tgroup></informaltable>
1347
1348<para>SYNOPSIS
1349</para>
1350<informaltable><tgroup cols="1"><tbody><row><entry
1351 align="char">
1352<para>int ioctl(int fd, int request =
1353 FE_DISEQC_RECV_SLAVE_REPLY, struct
1354 dvb_diseqc_slave_reply &#x22C6;reply);</para>
1355</entry>
1356 </row></tbody></tgroup></informaltable>
1357
1358<para>PARAMETERS
1359</para>
1360<informaltable><tgroup cols="2"><tbody><row><entry
1361 align="char">
1362<para>int fd</para>
1363</entry><entry
1364 align="char">
1365<para>File descriptor returned by a previous call to open().</para>
1366</entry>
1367 </row><row><entry
1368 align="char">
1369<para>int request</para>
1370</entry><entry
1371 align="char">
1372<para>Equals FE_DISEQC_RECV_SLAVE_REPLY for this
1373 command.</para>
1374</entry>
1375 </row><row><entry
1376 align="char">
1377<para>struct
1378 dvb_diseqc_slave_reply
1379 *reply</para>
1380</entry><entry
1381 align="char">
1382<para>Pointer to the command to be received.</para>
1383</entry>
1384 </row></tbody></tgroup></informaltable>
1385<para>ERRORS
1386</para>
1387<informaltable><tgroup cols="2"><tbody><row><entry
1388 align="char">
1389<para>EBADF</para>
1390</entry><entry
1391 align="char">
1392<para>fd is not a valid file descriptor.</para>
1393</entry>
1394 </row><row><entry
1395 align="char">
1396<para>EFAULT</para>
1397</entry><entry
1398 align="char">
1399<para>Seq points to an invalid address.</para>
1400</entry>
1401 </row><row><entry
1402 align="char">
1403<para>EINVAL</para>
1404</entry><entry
1405 align="char">
1406<para>The data structure referred to by seq is invalid in some
1407 way.</para>
1408</entry>
1409 </row><row><entry
1410 align="char">
1411<para>EPERM</para>
1412</entry><entry
1413 align="char">
1414<para>Permission denied (needs read/write access).</para>
1415</entry>
1416 </row><row><entry
1417 align="char">
1418<para>EINTERNAL</para>
1419</entry><entry
1420 align="char">
1421<para>Internal error in the device driver.</para>
1422</entry>
1423 </row></tbody></tgroup></informaltable>
1424</section>
1425
1426<section id="frontend_diseqc_send_burst">
1427<title>FE_DISEQC_SEND_BURST</title>
1428<para>DESCRIPTION
1429</para>
1430<informaltable><tgroup cols="1"><tbody><row><entry
1431 align="char">
1432<para>This ioctl call is used to send a 22KHz tone burst.</para>
1433</entry>
1434 </row></tbody></tgroup></informaltable>
1435
1436<para>SYNOPSIS
1437</para>
1438<informaltable><tgroup cols="1"><tbody><row><entry
1439 align="char">
1440<para>int ioctl(int fd, int request =
1441 FE_DISEQC_SEND_BURST, fe_sec_mini_cmd_t burst);</para>
1442</entry>
1443 </row></tbody></tgroup></informaltable>
1444
1445<para>PARAMETERS
1446</para>
1447<informaltable><tgroup cols="2"><tbody><row><entry
1448 align="char">
1449<para>int fd</para>
1450</entry><entry
1451 align="char">
1452<para>File descriptor returned by a previous call to open().</para>
1453</entry>
1454 </row><row><entry
1455 align="char">
1456<para>int request</para>
1457</entry><entry
1458 align="char">
1459<para>Equals FE_DISEQC_SEND_BURST for this command.</para>
1460</entry>
1461 </row><row><entry
1462 align="char">
1463<para>fe_sec_mini_cmd_t
1464 burst</para>
1465</entry><entry
1466 align="char">
1467<para>burst A or B.</para>
1468</entry>
1469 </row></tbody></tgroup></informaltable>
1470
1471<para>ERRORS
1472</para>
1473<informaltable><tgroup cols="2"><tbody><row><entry
1474 align="char">
1475<para>EBADF</para>
1476</entry><entry
1477 align="char">
1478<para>fd is not a valid file descriptor.</para>
1479</entry>
1480 </row><row><entry
1481 align="char">
1482<para>EFAULT</para>
1483</entry><entry
1484 align="char">
1485<para>Seq points to an invalid address.</para>
1486</entry>
1487 </row><row><entry
1488 align="char">
1489<para>EINVAL</para>
1490</entry><entry
1491 align="char">
1492<para>The data structure referred to by seq is invalid in some
1493 way.</para>
1494</entry>
1495 </row><row><entry
1496 align="char">
1497<para>EPERM</para>
1498</entry><entry
1499 align="char">
1500<para>Permission denied (needs read/write access).</para>
1501</entry>
1502 </row><row><entry
1503 align="char">
1504<para>EINTERNAL</para>
1505</entry><entry
1506 align="char">
1507<para>Internal error in the device driver.</para>
1508</entry>
1509</row></tbody></tgroup></informaltable>
1510</section>
1511
1512<section id="frontend_set_tone">
1513<title>FE_SET_TONE</title>
1514<para>DESCRIPTION
1515</para>
1516<informaltable><tgroup cols="1"><tbody><row><entry
1517 align="char">
1518<para>This call is used to set the generation of the continuous 22kHz tone. This call
1519 requires read/write permissions.</para>
1520</entry>
1521 </row></tbody></tgroup></informaltable>
1522<para>SYNOPSIS
1523</para>
1524<informaltable><tgroup cols="1"><tbody><row><entry
1525 align="char">
1526<para>int ioctl(int fd, int request = FE_SET_TONE,
1527 fe_sec_tone_mode_t tone);</para>
1528</entry>
1529 </row></tbody></tgroup></informaltable>
1530<para>PARAMETERS
1531</para>
1532<informaltable><tgroup cols="2"><tbody><row><entry
1533 align="char">
1534<para>int fd</para>
1535</entry><entry
1536 align="char">
1537<para>File descriptor returned by a previous call to open().</para>
1538</entry>
1539 </row><row><entry
1540 align="char">
1541<para>int request</para>
1542</entry><entry
1543 align="char">
1544<para>Equals FE_SET_TONE for this command.</para>
1545</entry>
1546 </row><row><entry
1547 align="char">
1548<para>fe_sec_tone_mode_t
1549 tone</para>
1550</entry><entry
1551 align="char">
1552<para>The requested tone generation mode (on/off).</para>
1553</entry>
1554 </row></tbody></tgroup></informaltable>
1555<para>ERRORS
1556</para>
1557<informaltable><tgroup cols="2"><tbody><row><entry
1558 align="char">
1559<para>ENODEV</para>
1560</entry><entry
1561 align="char">
1562<para>Device driver not loaded/available.</para>
1563</entry>
1564 </row><row><entry
1565 align="char">
1566<para>EBUSY</para>
1567</entry><entry
1568 align="char">
1569<para>Device or resource busy.</para>
1570</entry>
1571 </row><row><entry
1572 align="char">
1573<para>EINVAL</para>
1574</entry><entry
1575 align="char">
1576<para>Invalid argument.</para>
1577</entry>
1578 </row><row><entry
1579 align="char">
1580<para>EPERM</para>
1581</entry><entry
1582 align="char">
1583<para>File not opened with read permissions.</para>
1584</entry>
1585 </row><row><entry
1586 align="char">
1587<para>EINTERNAL</para>
1588</entry><entry
1589 align="char">
1590<para>Internal error in the device driver.</para>
1591</entry>
1592</row></tbody></tgroup></informaltable>
1593</section>
1594
1595<section id="fe_set_voltage">
1596<title>FE_SET_VOLTAGE</title>
1597<para>DESCRIPTION
1598</para>
1599<informaltable><tgroup cols="1"><tbody><row><entry
1600 align="char">
1601<para>This call is used to set the bus voltage. This call requires read/write
1602 permissions.</para>
1603</entry>
1604 </row></tbody></tgroup></informaltable>
1605<para>SYNOPSIS
1606</para>
1607<informaltable><tgroup cols="1"><tbody><row><entry
1608 align="char">
1609<para>int ioctl(int fd, int request = FE_SET_VOLTAGE,
1610 fe_sec_voltage_t voltage);</para>
1611</entry>
1612 </row></tbody></tgroup></informaltable>
1613
1614<para>PARAMETERS
1615</para>
1616<informaltable><tgroup cols="2"><tbody><row><entry
1617 align="char">
1618<para>int fd</para>
1619</entry><entry
1620 align="char">
1621<para>File descriptor returned by a previous call to open().</para>
1622</entry>
1623 </row><row><entry
1624 align="char">
1625<para>int request</para>
1626</entry><entry
1627 align="char">
1628<para>Equals FE_SET_VOLTAGE for this command.</para>
1629</entry>
1630 </row><row><entry
1631 align="char">
1632<para>fe_sec_voltage_t
1633 voltage</para>
1634</entry><entry
1635 align="char">
1636<para>The requested bus voltage.</para>
1637</entry>
1638 </row></tbody></tgroup></informaltable>
1639
1640<para>ERRORS
1641</para>
1642<informaltable><tgroup cols="2"><tbody><row><entry
1643 align="char">
1644<para>ENODEV</para>
1645</entry><entry
1646 align="char">
1647<para>Device driver not loaded/available.</para>
1648</entry>
1649 </row><row><entry
1650 align="char">
1651<para>EBUSY</para>
1652</entry><entry
1653 align="char">
1654<para>Device or resource busy.</para>
1655</entry>
1656 </row><row><entry
1657 align="char">
1658<para>EINVAL</para>
1659</entry><entry
1660 align="char">
1661<para>Invalid argument.</para>
1662</entry>
1663 </row><row><entry
1664 align="char">
1665<para>EPERM</para>
1666</entry><entry
1667 align="char">
1668<para>File not opened with read permissions.</para>
1669</entry>
1670 </row><row><entry
1671 align="char">
1672<para>EINTERNAL</para>
1673</entry><entry
1674 align="char">
1675<para>Internal error in the device driver.</para>
1676</entry>
1677 </row></tbody></tgroup></informaltable>
1678</section>
1679
1680<section id="frontend_enable_high_lnb_volt">
1681<title>FE_ENABLE_HIGH_LNB_VOLTAGE</title>
1682<para>DESCRIPTION
1683</para>
1684<informaltable><tgroup cols="1"><tbody><row><entry
1685 align="char">
1686<para>If high != 0 enables slightly higher voltages instead of 13/18V (to compensate
1687 for long cables). This call requires read/write permissions. Not all DVB
1688 adapters support this ioctl.</para>
1689</entry>
1690 </row></tbody></tgroup></informaltable>
1691
1692<para>SYNOPSIS
1693</para>
1694<informaltable><tgroup cols="1"><tbody><row><entry
1695 align="char">
1696<para>int ioctl(int fd, int request =
1697 FE_ENABLE_HIGH_LNB_VOLTAGE, int high);</para>
1698</entry>
1699 </row></tbody></tgroup></informaltable>
1700
1701<para>PARAMETERS
1702</para>
1703<informaltable><tgroup cols="2"><tbody><row><entry
1704 align="char">
1705<para>int fd</para>
1706</entry><entry
1707 align="char">
1708<para>File descriptor returned by a previous call to open().</para>
1709</entry>
1710 </row><row><entry
1711 align="char">
1712<para>int request</para>
1713</entry><entry
1714 align="char">
1715<para>Equals FE_SET_VOLTAGE for this command.</para>
1716</entry>
1717 </row><row><entry
1718 align="char">
1719<para>int high</para>
1720</entry><entry
1721 align="char">
1722<para>The requested bus voltage.</para>
1723</entry>
1724 </row></tbody></tgroup></informaltable>
1725
1726<para>ERRORS
1727</para>
1728<informaltable><tgroup cols="2"><tbody><row><entry
1729 align="char">
1730<para>ENODEV</para>
1731</entry><entry
1732 align="char">
1733<para>Device driver not loaded/available.</para>
1734</entry>
1735 </row><row><entry
1736 align="char">
1737<para>EBUSY</para>
1738</entry><entry
1739 align="char">
1740<para>Device or resource busy.</para>
1741</entry>
1742 </row><row><entry
1743 align="char">
1744<para>EINVAL</para>
1745</entry><entry
1746 align="char">
1747<para>Invalid argument.</para>
1748</entry>
1749 </row><row><entry
1750 align="char">
1751<para>EPERM</para>
1752</entry><entry
1753 align="char">
1754<para>File not opened with read permissions.</para>
1755</entry>
1756 </row><row><entry
1757 align="char">
1758<para>EINTERNAL</para>
1759</entry><entry
1760 align="char">
1761<para>Internal error in the device driver.</para>
1762</entry>
1763 </row></tbody></tgroup></informaltable>
1764</section>
1765</section>
1766&sub-isdbt;
diff --git a/Documentation/DocBook/dvb/intro.xml b/Documentation/DocBook/dvb/intro.xml
new file mode 100644
index 000000000000..0dc83f672ea2
--- /dev/null
+++ b/Documentation/DocBook/dvb/intro.xml
@@ -0,0 +1,191 @@
1<title>Introduction</title>
2
3<section id="requisites">
4<title>What you need to know</title>
5
6<para>The reader of this document is required to have some knowledge in
7the area of digital video broadcasting (DVB) and should be familiar with
8part I of the MPEG2 specification ISO/IEC 13818 (aka ITU-T H.222), i.e
9you should know what a program/transport stream (PS/TS) is and what is
10meant by a packetized elementary stream (PES) or an I-frame.</para>
11
12<para>Various DVB standards documents are available from
13<ulink url="http://www.dvb.org" /> and/or
14<ulink url="http://www.etsi.org" />.</para>
15
16<para>It is also necessary to know how to access unix/linux devices and
17how to use ioctl calls. This also includes the knowledge of C or C++.
18</para>
19</section>
20
21<section id="history">
22<title>History</title>
23
24<para>The first API for DVB cards we used at Convergence in late 1999
25was an extension of the Video4Linux API which was primarily developed
26for frame grabber cards. As such it was not really well suited to be
27used for DVB cards and their new features like recording MPEG streams
28and filtering several section and PES data streams at the same time.
29</para>
30
31<para>In early 2000, we were approached by Nokia with a proposal for a
32new standard Linux DVB API. As a commitment to the development of
33terminals based on open standards, Nokia and Convergence made it
34available to all Linux developers and published it on
35<ulink url="http://www.linuxtv.org/" /> in September 2000.
36Convergence is the maintainer of the Linux DVB API. Together with the
37LinuxTV community (i.e. you, the reader of this document), the Linux DVB
38API will be constantly reviewed and improved. With the Linux driver for
39the Siemens/Hauppauge DVB PCI card Convergence provides a first
40implementation of the Linux DVB API.</para>
41</section>
42
43<section id="overview">
44<title>Overview</title>
45
46<figure id="stb_components">
47<title>Components of a DVB card/STB</title>
48<mediaobject>
49<imageobject>
50<imagedata fileref="dvbstb.pdf" format="PS" />
51</imageobject>
52<imageobject>
53<imagedata fileref="dvbstb.png" format="PNG" />
54</imageobject>
55</mediaobject>
56</figure>
57
58<para>A DVB PCI card or DVB set-top-box (STB) usually consists of the
59following main hardware components: </para>
60
61<itemizedlist>
62 <listitem>
63
64<para>Frontend consisting of tuner and DVB demodulator</para>
65
66<para>Here the raw signal reaches the DVB hardware from a satellite dish
67or antenna or directly from cable. The frontend down-converts and
68demodulates this signal into an MPEG transport stream (TS). In case of a
69satellite frontend, this includes a facility for satellite equipment
70control (SEC), which allows control of LNB polarization, multi feed
71switches or dish rotors.</para>
72
73</listitem>
74 <listitem>
75
76<para>Conditional Access (CA) hardware like CI adapters and smartcard slots
77</para>
78
79<para>The complete TS is passed through the CA hardware. Programs to
80which the user has access (controlled by the smart card) are decoded in
81real time and re-inserted into the TS.</para>
82
83</listitem>
84 <listitem>
85 <para>Demultiplexer which filters the incoming DVB stream</para>
86
87<para>The demultiplexer splits the TS into its components like audio and
88video streams. Besides usually several of such audio and video streams
89it also contains data streams with information about the programs
90offered in this or other streams of the same provider.</para>
91
92</listitem>
93<listitem>
94
95<para>MPEG2 audio and video decoder</para>
96
97<para>The main targets of the demultiplexer are the MPEG2 audio and
98video decoders. After decoding they pass on the uncompressed audio and
99video to the computer screen or (through a PAL/NTSC encoder) to a TV
100set.</para>
101
102
103</listitem>
104</itemizedlist>
105
106<para><xref linkend="stb_components" /> shows a crude schematic of the control and data flow
107between those components.</para>
108
109<para>On a DVB PCI card not all of these have to be present since some
110functionality can be provided by the main CPU of the PC (e.g. MPEG
111picture and sound decoding) or is not needed (e.g. for data-only uses
112like &#8220;internet over satellite&#8221;). Also not every card or STB
113provides conditional access hardware.</para>
114
115</section>
116
117<section id="dvb_devices">
118<title>Linux DVB Devices</title>
119
120<para>The Linux DVB API lets you control these hardware components
121through currently six Unix-style character devices for video, audio,
122frontend, demux, CA and IP-over-DVB networking. The video and audio
123devices control the MPEG2 decoder hardware, the frontend device the
124tuner and the DVB demodulator. The demux device gives you control over
125the PES and section filters of the hardware. If the hardware does not
126support filtering these filters can be implemented in software. Finally,
127the CA device controls all the conditional access capabilities of the
128hardware. It can depend on the individual security requirements of the
129platform, if and how many of the CA functions are made available to the
130application through this device.</para>
131
132<para>All devices can be found in the <emphasis role="tt">/dev</emphasis>
133tree under <emphasis role="tt">/dev/dvb</emphasis>. The individual devices
134are called:</para>
135
136<itemizedlist>
137<listitem>
138
139<para><emphasis role="tt">/dev/dvb/adapterN/audioM</emphasis>,</para>
140</listitem>
141<listitem>
142<para><emphasis role="tt">/dev/dvb/adapterN/videoM</emphasis>,</para>
143</listitem>
144<listitem>
145<para><emphasis role="tt">/dev/dvb/adapterN/frontendM</emphasis>,</para>
146</listitem>
147 <listitem>
148
149<para><emphasis role="tt">/dev/dvb/adapterN/netM</emphasis>,</para>
150</listitem>
151 <listitem>
152
153<para><emphasis role="tt">/dev/dvb/adapterN/demuxM</emphasis>,</para>
154</listitem>
155 <listitem>
156
157<para><emphasis role="tt">/dev/dvb/adapterN/caM</emphasis>,</para></listitem></itemizedlist>
158
159<para>where N enumerates the DVB PCI cards in a system starting
160from&#x00A0;0, and M enumerates the devices of each type within each
161adapter, starting from&#x00A0;0, too. We will omit the &#8220;<emphasis
162role="tt">/dev/dvb/adapterN/</emphasis>&#8221; in the further dicussion
163of these devices. The naming scheme for the devices is the same wheter
164devfs is used or not.</para>
165
166<para>More details about the data structures and function calls of all
167the devices are described in the following chapters.</para>
168
169</section>
170
171<section id="include_files">
172<title>API include files</title>
173
174<para>For each of the DVB devices a corresponding include file exists.
175The DVB API include files should be included in application sources with
176a partial path like:</para>
177
178
179<programlisting>
180 #include &#x003C;linux/dvb/frontend.h&#x003E;
181</programlisting>
182
183<para>To enable applications to support different API version, an
184additional include file <emphasis
185role="tt">linux/dvb/version.h</emphasis> exists, which defines the
186constant <emphasis role="tt">DVB_API_VERSION</emphasis>. This document
187describes <emphasis role="tt">DVB_API_VERSION&#x00A0;3</emphasis>.
188</para>
189
190</section>
191
diff --git a/Documentation/DocBook/dvb/isdbt.xml b/Documentation/DocBook/dvb/isdbt.xml
new file mode 100644
index 000000000000..92855222fccb
--- /dev/null
+++ b/Documentation/DocBook/dvb/isdbt.xml
@@ -0,0 +1,314 @@
1<section id="isdbt">
2 <title>ISDB-T frontend</title>
3 <para>This section describes shortly what are the possible parameters in the Linux
4 DVB-API called "S2API" and now DVB API 5 in order to tune an ISDB-T/ISDB-Tsb
5 demodulator:</para>
6
7 <para>This ISDB-T/ISDB-Tsb API extension should reflect all information
8 needed to tune any ISDB-T/ISDB-Tsb hardware. Of course it is possible
9 that some very sophisticated devices won't need certain parameters to
10 tune.</para>
11
12 <para>The information given here should help application writers to know how
13 to handle ISDB-T and ISDB-Tsb hardware using the Linux DVB-API.</para>
14
15 <para>The details given here about ISDB-T and ISDB-Tsb are just enough to
16 basically show the dependencies between the needed parameter values,
17 but surely some information is left out. For more detailed information
18 see the following documents:</para>
19
20 <para>ARIB STD-B31 - "Transmission System for Digital Terrestrial
21 Television Broadcasting" and</para>
22 <para>ARIB TR-B14 - "Operational Guidelines for Digital Terrestrial
23 Television Broadcasting".</para>
24
25 <para>In order to read this document one has to have some knowledge the
26 channel structure in ISDB-T and ISDB-Tsb. I.e. it has to be known to
27 the reader that an ISDB-T channel consists of 13 segments, that it can
28 have up to 3 layer sharing those segments, and things like that.</para>
29
30 <para>Parameters used by ISDB-T and ISDB-Tsb.</para>
31
32 <section id="isdbt-parms">
33 <title>Parameters that are common with DVB-T and ATSC</title>
34
35 <section id="isdbt-freq">
36 <title><constant>DTV_FREQUENCY</constant></title>
37
38 <para>Central frequency of the channel.</para>
39
40 <para>For ISDB-T the channels are usally transmitted with an offset of 143kHz. E.g. a
41 valid frequncy could be 474143 kHz. The stepping is bound to the bandwidth of
42 the channel which is 6MHz.</para>
43
44 <para>As in ISDB-Tsb the channel consists of only one or three segments the
45 frequency step is 429kHz, 3*429 respectively. As for ISDB-T the
46 central frequency of the channel is expected.</para>
47 </section>
48
49 <section id="isdbt-bw">
50 <title><constant>DTV_BANDWIDTH_HZ</constant> (optional)</title>
51
52 <para>Possible values:</para>
53
54 <para>For ISDB-T it should be always 6000000Hz (6MHz)</para>
55 <para>For ISDB-Tsb it can vary depending on the number of connected segments</para>
56
57 <para>Note: Hardware specific values might be given here, but standard
58 applications should not bother to set a value to this field as
59 standard demods are ignoring it anyway.</para>
60
61 <para>Bandwidth in ISDB-T is fixed (6MHz) or can be easily derived from
62 other parameters (DTV_ISDBT_SB_SEGMENT_IDX,
63 DTV_ISDBT_SB_SEGMENT_COUNT).</para>
64 </section>
65
66 <section id="isdbt-delivery-sys">
67 <title><constant>DTV_DELIVERY_SYSTEM</constant></title>
68
69 <para>Possible values: <constant>SYS_ISDBT</constant></para>
70 </section>
71
72 <section id="isdbt-tx-mode">
73 <title><constant>DTV_TRANSMISSION_MODE</constant></title>
74
75 <para>ISDB-T supports three carrier/symbol-size: 8K, 4K, 2K. It is called
76 'mode' in the standard: Mode 1 is 2K, mode 2 is 4K, mode 3 is 8K</para>
77
78 <para>Possible values: <constant>TRANSMISSION_MODE_2K</constant>, <constant>TRANSMISSION_MODE_8K</constant>,
79 <constant>TRANSMISSION_MODE_AUTO</constant>, <constant>TRANSMISSION_MODE_4K</constant></para>
80
81 <para>If <constant>DTV_TRANSMISSION_MODE</constant> is set the <constant>TRANSMISSION_MODE_AUTO</constant> the
82 hardware will try to find the correct FFT-size (if capable) and will
83 use TMCC to fill in the missing parameters.</para>
84
85 <para><constant>TRANSMISSION_MODE_4K</constant> is added at the same time as the other new parameters.</para>
86 </section>
87
88 <section id="isdbt-guard-interval">
89 <title><constant>DTV_GUARD_INTERVAL</constant></title>
90
91 <para>Possible values: <constant>GUARD_INTERVAL_1_32</constant>, <constant>GUARD_INTERVAL_1_16</constant>, <constant>GUARD_INTERVAL_1_8</constant>,
92 <constant>GUARD_INTERVAL_1_4</constant>, <constant>GUARD_INTERVAL_AUTO</constant></para>
93
94 <para>If <constant>DTV_GUARD_INTERVAL</constant> is set the <constant>GUARD_INTERVAL_AUTO</constant> the hardware will
95 try to find the correct guard interval (if capable) and will use TMCC to fill
96 in the missing parameters.</para>
97 </section>
98 </section>
99 <section id="isdbt-new-parms">
100 <title>ISDB-T only parameters</title>
101
102 <section id="isdbt-part-rec">
103 <title><constant>DTV_ISDBT_PARTIAL_RECEPTION</constant></title>
104
105 <para><constant>If DTV_ISDBT_SOUND_BROADCASTING</constant> is '0' this bit-field represents whether
106 the channel is in partial reception mode or not.</para>
107
108 <para>If '1' <constant>DTV_ISDBT_LAYERA_*</constant> values are assigned to the center segment and
109 <constant>DTV_ISDBT_LAYERA_SEGMENT_COUNT</constant> has to be '1'.</para>
110
111 <para>If in addition <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'
112 <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> represents whether this ISDB-Tsb channel
113 is consisting of one segment and layer or three segments and two layers.</para>
114
115 <para>Possible values: 0, 1, -1 (AUTO)</para>
116 </section>
117
118 <section id="isdbt-sound-bcast">
119 <title><constant>DTV_ISDBT_SOUND_BROADCASTING</constant></title>
120
121 <para>This field represents whether the other DTV_ISDBT_*-parameters are
122 referring to an ISDB-T and an ISDB-Tsb channel. (See also
123 <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>).</para>
124
125 <para>Possible values: 0, 1, -1 (AUTO)</para>
126 </section>
127
128 <section id="isdbt-sb-ch-id">
129 <title><constant>DTV_ISDBT_SB_SUBCHANNEL_ID</constant></title>
130
131 <para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
132
133 <para>(Note of the author: This might not be the correct description of the
134 <constant>SUBCHANNEL-ID</constant> in all details, but it is my understanding of the technical
135 background needed to program a device)</para>
136
137 <para>An ISDB-Tsb channel (1 or 3 segments) can be broadcasted alone or in a
138 set of connected ISDB-Tsb channels. In this set of channels every
139 channel can be received independently. The number of connected
140 ISDB-Tsb segment can vary, e.g. depending on the frequency spectrum
141 bandwidth available.</para>
142
143 <para>Example: Assume 8 ISDB-Tsb connected segments are broadcasted. The
144 broadcaster has several possibilities to put those channels in the
145 air: Assuming a normal 13-segment ISDB-T spectrum he can align the 8
146 segments from position 1-8 to 5-13 or anything in between.</para>
147
148 <para>The underlying layer of segments are subchannels: each segment is
149 consisting of several subchannels with a predefined IDs. A sub-channel
150 is used to help the demodulator to synchronize on the channel.</para>
151
152 <para>An ISDB-T channel is always centered over all sub-channels. As for
153 the example above, in ISDB-Tsb it is no longer as simple as that.</para>
154
155 <para><constant>The DTV_ISDBT_SB_SUBCHANNEL_ID</constant> parameter is used to give the
156 sub-channel ID of the segment to be demodulated.</para>
157
158 <para>Possible values: 0 .. 41, -1 (AUTO)</para>
159 </section>
160
161 <section id="isdbt-sb-seg-idx">
162
163 <title><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant></title>
164
165 <para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
166
167 <para><constant>DTV_ISDBT_SB_SEGMENT_IDX</constant> gives the index of the segment to be
168 demodulated for an ISDB-Tsb channel where several of them are
169 transmitted in the connected manner.</para>
170
171 <para>Possible values: 0 .. <constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> - 1</para>
172
173 <para>Note: This value cannot be determined by an automatic channel search.</para>
174 </section>
175
176 <section id="isdbt-sb-seg-cnt">
177 <title><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant></title>
178
179 <para>This field only applies if <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> is '1'.</para>
180
181 <para><constant>DTV_ISDBT_SB_SEGMENT_COUNT</constant> gives the total count of connected ISDB-Tsb
182 channels.</para>
183
184 <para>Possible values: 1 .. 13</para>
185
186 <para>Note: This value cannot be determined by an automatic channel search.</para>
187 </section>
188
189 <section id="isdb-hierq-layers">
190 <title>Hierarchical layers</title>
191
192 <para>ISDB-T channels can be coded hierarchically. As opposed to DVB-T in
193 ISDB-T hierarchical layers can be decoded simultaneously. For that
194 reason a ISDB-T demodulator has 3 viterbi and 3 reed-solomon-decoders.</para>
195
196 <para>ISDB-T has 3 hierarchical layers which each can use a part of the
197 available segments. The total number of segments over all layers has
198 to 13 in ISDB-T.</para>
199
200 <section id="isdbt-layer-ena">
201 <title><constant>DTV_ISDBT_LAYER_ENABLED</constant></title>
202
203 <para>Hierarchical reception in ISDB-T is achieved by enabling or disabling
204 layers in the decoding process. Setting all bits of
205 <constant>DTV_ISDBT_LAYER_ENABLED</constant> to '1' forces all layers (if applicable) to be
206 demodulated. This is the default.</para>
207
208 <para>If the channel is in the partial reception mode
209 (<constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> = 1) the central segment can be decoded
210 independently of the other 12 segments. In that mode layer A has to
211 have a <constant>SEGMENT_COUNT</constant> of 1.</para>
212
213 <para>In ISDB-Tsb only layer A is used, it can be 1 or 3 in ISDB-Tsb
214 according to <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>. <constant>SEGMENT_COUNT</constant> must be filled
215 accordingly.</para>
216
217 <para>Possible values: 0x1, 0x2, 0x4 (|-able)</para>
218
219 <para><constant>DTV_ISDBT_LAYER_ENABLED[0:0]</constant> - layer A</para>
220 <para><constant>DTV_ISDBT_LAYER_ENABLED[1:1]</constant> - layer B</para>
221 <para><constant>DTV_ISDBT_LAYER_ENABLED[2:2]</constant> - layer C</para>
222 <para><constant>DTV_ISDBT_LAYER_ENABLED[31:3]</constant> unused</para>
223 </section>
224
225 <section id="isdbt-layer-fec">
226 <title><constant>DTV_ISDBT_LAYER*_FEC</constant></title>
227
228 <para>Possible values: <constant>FEC_AUTO</constant>, <constant>FEC_1_2</constant>, <constant>FEC_2_3</constant>, <constant>FEC_3_4</constant>, <constant>FEC_5_6</constant>, <constant>FEC_7_8</constant></para>
229 </section>
230
231 <section id="isdbt-layer-mod">
232 <title><constant>DTV_ISDBT_LAYER*_MODULATION</constant></title>
233
234 <para>Possible values: <constant>QAM_AUTO</constant>, QP<constant>SK, QAM_16</constant>, <constant>QAM_64</constant>, <constant>DQPSK</constant></para>
235
236 <para>Note: If layer C is <constant>DQPSK</constant> layer B has to be <constant>DQPSK</constant>. If layer B is <constant>DQPSK</constant>
237 and <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant>=0 layer has to be <constant>DQPSK</constant>.</para>
238 </section>
239
240 <section id="isdbt-layer-seg-cnt">
241 <title><constant>DTV_ISDBT_LAYER*_SEGMENT_COUNT</constant></title>
242
243 <para>Possible values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, -1 (AUTO)</para>
244
245 <para>Note: Truth table for <constant>DTV_ISDBT_SOUND_BROADCASTING</constant> and
246 <constant>DTV_ISDBT_PARTIAL_RECEPTION</constant> and <constant>LAYER</constant>*_SEGMENT_COUNT</para>
247
248 <informaltable id="isdbt-layer_seg-cnt-table">
249 <tgroup cols="6">
250
251 <tbody>
252 <row>
253 <entry>PR</entry>
254 <entry>SB</entry>
255 <entry>Layer A width</entry>
256 <entry>Layer B width</entry>
257 <entry>Layer C width</entry>
258 <entry>total width</entry>
259 </row>
260
261 <row>
262 <entry>0</entry>
263 <entry>0</entry>
264 <entry>1 .. 13</entry>
265 <entry>1 .. 13</entry>
266 <entry>1 .. 13</entry>
267 <entry>13</entry>
268 </row>
269
270 <row>
271 <entry>1</entry>
272 <entry>0</entry>
273 <entry>1</entry>
274 <entry>1 .. 13</entry>
275 <entry>1 .. 13</entry>
276 <entry>13</entry>
277 </row>
278
279 <row>
280 <entry>0</entry>
281 <entry>1</entry>
282 <entry>1</entry>
283 <entry>0</entry>
284 <entry>0</entry>
285 <entry>1</entry>
286 </row>
287
288 <row>
289 <entry>1</entry>
290 <entry>1</entry>
291 <entry>1</entry>
292 <entry>2</entry>
293 <entry>0</entry>
294 <entry>13</entry>
295 </row>
296 </tbody>
297
298 </tgroup>
299 </informaltable>
300
301 </section>
302
303 <section id="isdbt_layer_t_interl">
304 <title><constant>DTV_ISDBT_LAYER*_TIME_INTERLEAVING</constant></title>
305
306 <para>Possible values: 0, 1, 2, 3, -1 (AUTO)</para>
307
308 <para>Note: The real inter-leaver depth-names depend on the mode (fft-size); the values
309 here are referring to what can be found in the TMCC-structure -
310 independent of the mode.</para>
311 </section>
312 </section>
313 </section>
314</section>
diff --git a/Documentation/DocBook/dvb/kdapi.xml b/Documentation/DocBook/dvb/kdapi.xml
new file mode 100644
index 000000000000..6c67481eaa4b
--- /dev/null
+++ b/Documentation/DocBook/dvb/kdapi.xml
@@ -0,0 +1,2309 @@
1<title>Kernel Demux API</title>
2<para>The kernel demux API defines a driver-internal interface for registering low-level,
3hardware specific driver to a hardware independent demux layer. It is only of interest for
4DVB device driver writers. The header file for this API is named <emphasis role="tt">demux.h</emphasis> and located in
5<emphasis role="tt">drivers/media/dvb/dvb-core</emphasis>.
6</para>
7<para>Maintainer note: This section must be reviewed. It is probably out of date.
8</para>
9
10<section id="kernel_demux_data_types">
11<title>Kernel Demux Data Types</title>
12
13
14<section id="dmx_success_t">
15<title>dmx_success_t</title>
16 <programlisting>
17 typedef enum {
18 DMX_OK = 0, /&#x22C6; Received Ok &#x22C6;/
19 DMX_LENGTH_ERROR, /&#x22C6; Incorrect length &#x22C6;/
20 DMX_OVERRUN_ERROR, /&#x22C6; Receiver ring buffer overrun &#x22C6;/
21 DMX_CRC_ERROR, /&#x22C6; Incorrect CRC &#x22C6;/
22 DMX_FRAME_ERROR, /&#x22C6; Frame alignment error &#x22C6;/
23 DMX_FIFO_ERROR, /&#x22C6; Receiver FIFO overrun &#x22C6;/
24 DMX_MISSED_ERROR /&#x22C6; Receiver missed packet &#x22C6;/
25 } dmx_success_t;
26</programlisting>
27
28</section>
29<section id="ts_filter_types">
30<title>TS filter types</title>
31 <programlisting>
32 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
33 /&#x22C6; TS packet reception &#x22C6;/
34 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
35
36 /&#x22C6; TS filter type for set_type() &#x22C6;/
37
38 #define TS_PACKET 1 /&#x22C6; send TS packets (188 bytes) to callback (default) &#x22C6;/
39 #define TS_PAYLOAD_ONLY 2 /&#x22C6; in case TS_PACKET is set, only send the TS
40 payload (&#x003C;=184 bytes per packet) to callback &#x22C6;/
41 #define TS_DECODER 4 /&#x22C6; send stream to built-in decoder (if present) &#x22C6;/
42</programlisting>
43
44</section>
45<section id="dmx_ts_pes_t">
46<title>dmx_ts_pes_t</title>
47<para>The structure
48</para>
49<programlisting>
50 typedef enum
51 {
52 DMX_TS_PES_AUDIO, /&#x22C6; also send packets to audio decoder (if it exists) &#x22C6;/
53 DMX_TS_PES_VIDEO, /&#x22C6; ... &#x22C6;/
54 DMX_TS_PES_TELETEXT,
55 DMX_TS_PES_SUBTITLE,
56 DMX_TS_PES_PCR,
57 DMX_TS_PES_OTHER,
58 } dmx_ts_pes_t;
59</programlisting>
60<para>describes the PES type for filters which write to a built-in decoder. The correspond (and
61should be kept identical) to the types in the demux device.
62</para>
63<programlisting>
64 struct dmx_ts_feed_s {
65 int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
66 struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
67 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
68 int (&#x22C6;set) (struct dmx_ts_feed_s&#x22C6; feed,
69 __u16 pid,
70 size_t callback_length,
71 size_t circular_buffer_size,
72 int descramble,
73 struct timespec timeout);
74 int (&#x22C6;start_filtering) (struct dmx_ts_feed_s&#x22C6; feed);
75 int (&#x22C6;stop_filtering) (struct dmx_ts_feed_s&#x22C6; feed);
76 int (&#x22C6;set_type) (struct dmx_ts_feed_s&#x22C6; feed,
77 int type,
78 dmx_ts_pes_t pes_type);
79 };
80
81 typedef struct dmx_ts_feed_s dmx_ts_feed_t;
82</programlisting>
83 <programlisting>
84 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
85 /&#x22C6; PES packet reception (not supported yet) &#x22C6;/
86 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
87
88 typedef struct dmx_pes_filter_s {
89 struct dmx_pes_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
90 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
91 } dmx_pes_filter_t;
92</programlisting>
93 <programlisting>
94 typedef struct dmx_pes_feed_s {
95 int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
96 struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
97 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
98 int (&#x22C6;set) (struct dmx_pes_feed_s&#x22C6; feed,
99 __u16 pid,
100 size_t circular_buffer_size,
101 int descramble,
102 struct timespec timeout);
103 int (&#x22C6;start_filtering) (struct dmx_pes_feed_s&#x22C6; feed);
104 int (&#x22C6;stop_filtering) (struct dmx_pes_feed_s&#x22C6; feed);
105 int (&#x22C6;allocate_filter) (struct dmx_pes_feed_s&#x22C6; feed,
106 dmx_pes_filter_t&#x22C6;&#x22C6; filter);
107 int (&#x22C6;release_filter) (struct dmx_pes_feed_s&#x22C6; feed,
108 dmx_pes_filter_t&#x22C6; filter);
109 } dmx_pes_feed_t;
110</programlisting>
111 <programlisting>
112 typedef struct {
113 __u8 filter_value [DMX_MAX_FILTER_SIZE];
114 __u8 filter_mask [DMX_MAX_FILTER_SIZE];
115 struct dmx_section_feed_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
116 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
117 } dmx_section_filter_t;
118</programlisting>
119 <programlisting>
120 struct dmx_section_feed_s {
121 int is_filtering; /&#x22C6; Set to non-zero when filtering in progress &#x22C6;/
122 struct dmx_demux_s&#x22C6; parent; /&#x22C6; Back-pointer &#x22C6;/
123 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
124 int (&#x22C6;set) (struct dmx_section_feed_s&#x22C6; feed,
125 __u16 pid,
126 size_t circular_buffer_size,
127 int descramble,
128 int check_crc);
129 int (&#x22C6;allocate_filter) (struct dmx_section_feed_s&#x22C6; feed,
130 dmx_section_filter_t&#x22C6;&#x22C6; filter);
131 int (&#x22C6;release_filter) (struct dmx_section_feed_s&#x22C6; feed,
132 dmx_section_filter_t&#x22C6; filter);
133 int (&#x22C6;start_filtering) (struct dmx_section_feed_s&#x22C6; feed);
134 int (&#x22C6;stop_filtering) (struct dmx_section_feed_s&#x22C6; feed);
135 };
136 typedef struct dmx_section_feed_s dmx_section_feed_t;
137
138 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
139 /&#x22C6; Callback functions &#x22C6;/
140 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
141
142 typedef int (&#x22C6;dmx_ts_cb) ( __u8 &#x22C6; buffer1,
143 size_t buffer1_length,
144 __u8 &#x22C6; buffer2,
145 size_t buffer2_length,
146 dmx_ts_feed_t&#x22C6; source,
147 dmx_success_t success);
148
149 typedef int (&#x22C6;dmx_section_cb) ( __u8 &#x22C6; buffer1,
150 size_t buffer1_len,
151 __u8 &#x22C6; buffer2,
152 size_t buffer2_len,
153 dmx_section_filter_t &#x22C6; source,
154 dmx_success_t success);
155
156 typedef int (&#x22C6;dmx_pes_cb) ( __u8 &#x22C6; buffer1,
157 size_t buffer1_len,
158 __u8 &#x22C6; buffer2,
159 size_t buffer2_len,
160 dmx_pes_filter_t&#x22C6; source,
161 dmx_success_t success);
162
163 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
164 /&#x22C6; DVB Front-End &#x22C6;/
165 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
166
167 typedef enum {
168 DMX_OTHER_FE = 0,
169 DMX_SATELLITE_FE,
170 DMX_CABLE_FE,
171 DMX_TERRESTRIAL_FE,
172 DMX_LVDS_FE,
173 DMX_ASI_FE, /&#x22C6; DVB-ASI interface &#x22C6;/
174 DMX_MEMORY_FE
175 } dmx_frontend_source_t;
176
177 typedef struct {
178 /&#x22C6; The following char&#x22C6; fields point to NULL terminated strings &#x22C6;/
179 char&#x22C6; id; /&#x22C6; Unique front-end identifier &#x22C6;/
180 char&#x22C6; vendor; /&#x22C6; Name of the front-end vendor &#x22C6;/
181 char&#x22C6; model; /&#x22C6; Name of the front-end model &#x22C6;/
182 struct list_head connectivity_list; /&#x22C6; List of front-ends that can
183 be connected to a particular
184 demux &#x22C6;/
185 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
186 dmx_frontend_source_t source;
187 } dmx_frontend_t;
188
189 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
190 /&#x22C6; MPEG-2 TS Demux &#x22C6;/
191 /&#x22C6;--------------------------------------------------------------------------&#x22C6;/
192
193 /&#x22C6;
194 &#x22C6; Flags OR'ed in the capabilites field of struct dmx_demux_s.
195 &#x22C6;/
196
197 #define DMX_TS_FILTERING 1
198 #define DMX_PES_FILTERING 2
199 #define DMX_SECTION_FILTERING 4
200 #define DMX_MEMORY_BASED_FILTERING 8 /&#x22C6; write() available &#x22C6;/
201 #define DMX_CRC_CHECKING 16
202 #define DMX_TS_DESCRAMBLING 32
203 #define DMX_SECTION_PAYLOAD_DESCRAMBLING 64
204 #define DMX_MAC_ADDRESS_DESCRAMBLING 128
205</programlisting>
206
207</section>
208<section id="demux_demux_t">
209<title>demux_demux_t</title>
210 <programlisting>
211 /&#x22C6;
212 &#x22C6; DMX_FE_ENTRY(): Casts elements in the list of registered
213 &#x22C6; front-ends from the generic type struct list_head
214 &#x22C6; to the type &#x22C6; dmx_frontend_t
215 &#x22C6;.
216 &#x22C6;/
217
218 #define DMX_FE_ENTRY(list) list_entry(list, dmx_frontend_t, connectivity_list)
219
220 struct dmx_demux_s {
221 /&#x22C6; The following char&#x22C6; fields point to NULL terminated strings &#x22C6;/
222 char&#x22C6; id; /&#x22C6; Unique demux identifier &#x22C6;/
223 char&#x22C6; vendor; /&#x22C6; Name of the demux vendor &#x22C6;/
224 char&#x22C6; model; /&#x22C6; Name of the demux model &#x22C6;/
225 __u32 capabilities; /&#x22C6; Bitfield of capability flags &#x22C6;/
226 dmx_frontend_t&#x22C6; frontend; /&#x22C6; Front-end connected to the demux &#x22C6;/
227 struct list_head reg_list; /&#x22C6; List of registered demuxes &#x22C6;/
228 void&#x22C6; priv; /&#x22C6; Pointer to private data of the API client &#x22C6;/
229 int users; /&#x22C6; Number of users &#x22C6;/
230 int (&#x22C6;open) (struct dmx_demux_s&#x22C6; demux);
231 int (&#x22C6;close) (struct dmx_demux_s&#x22C6; demux);
232 int (&#x22C6;write) (struct dmx_demux_s&#x22C6; demux, const char&#x22C6; buf, size_t count);
233 int (&#x22C6;allocate_ts_feed) (struct dmx_demux_s&#x22C6; demux,
234 dmx_ts_feed_t&#x22C6;&#x22C6; feed,
235 dmx_ts_cb callback);
236 int (&#x22C6;release_ts_feed) (struct dmx_demux_s&#x22C6; demux,
237 dmx_ts_feed_t&#x22C6; feed);
238 int (&#x22C6;allocate_pes_feed) (struct dmx_demux_s&#x22C6; demux,
239 dmx_pes_feed_t&#x22C6;&#x22C6; feed,
240 dmx_pes_cb callback);
241 int (&#x22C6;release_pes_feed) (struct dmx_demux_s&#x22C6; demux,
242 dmx_pes_feed_t&#x22C6; feed);
243 int (&#x22C6;allocate_section_feed) (struct dmx_demux_s&#x22C6; demux,
244 dmx_section_feed_t&#x22C6;&#x22C6; feed,
245 dmx_section_cb callback);
246 int (&#x22C6;release_section_feed) (struct dmx_demux_s&#x22C6; demux,
247 dmx_section_feed_t&#x22C6; feed);
248 int (&#x22C6;descramble_mac_address) (struct dmx_demux_s&#x22C6; demux,
249 __u8&#x22C6; buffer1,
250 size_t buffer1_length,
251 __u8&#x22C6; buffer2,
252 size_t buffer2_length,
253 __u16 pid);
254 int (&#x22C6;descramble_section_payload) (struct dmx_demux_s&#x22C6; demux,
255 __u8&#x22C6; buffer1,
256 size_t buffer1_length,
257 __u8&#x22C6; buffer2, size_t buffer2_length,
258 __u16 pid);
259 int (&#x22C6;add_frontend) (struct dmx_demux_s&#x22C6; demux,
260 dmx_frontend_t&#x22C6; frontend);
261 int (&#x22C6;remove_frontend) (struct dmx_demux_s&#x22C6; demux,
262 dmx_frontend_t&#x22C6; frontend);
263 struct list_head&#x22C6; (&#x22C6;get_frontends) (struct dmx_demux_s&#x22C6; demux);
264 int (&#x22C6;connect_frontend) (struct dmx_demux_s&#x22C6; demux,
265 dmx_frontend_t&#x22C6; frontend);
266 int (&#x22C6;disconnect_frontend) (struct dmx_demux_s&#x22C6; demux);
267
268
269 /&#x22C6; added because js cannot keep track of these himself &#x22C6;/
270 int (&#x22C6;get_pes_pids) (struct dmx_demux_s&#x22C6; demux, __u16 &#x22C6;pids);
271 };
272 typedef struct dmx_demux_s dmx_demux_t;
273</programlisting>
274
275</section>
276<section id="demux_directory">
277<title>Demux directory</title>
278 <programlisting>
279 /&#x22C6;
280 &#x22C6; DMX_DIR_ENTRY(): Casts elements in the list of registered
281 &#x22C6; demuxes from the generic type struct list_head&#x22C6; to the type dmx_demux_t
282 &#x22C6;.
283 &#x22C6;/
284
285 #define DMX_DIR_ENTRY(list) list_entry(list, dmx_demux_t, reg_list)
286
287 int dmx_register_demux (dmx_demux_t&#x22C6; demux);
288 int dmx_unregister_demux (dmx_demux_t&#x22C6; demux);
289 struct list_head&#x22C6; dmx_get_demuxes (void);
290</programlisting>
291 </section></section>
292<section id="demux_directory_api">
293<title>Demux Directory API</title>
294<para>The demux directory is a Linux kernel-wide facility for registering and accessing the
295MPEG-2 TS demuxes in the system. Run-time registering and unregistering of demux drivers
296is possible using this API.
297</para>
298<para>All demux drivers in the directory implement the abstract interface dmx_demux_t.
299</para>
300
301<section
302role="subsection"><title>dmx_register_demux()</title>
303<para>DESCRIPTION
304</para>
305<informaltable><tgroup cols="1"><tbody><row><entry
306 align="char">
307<para>This function makes a demux driver interface available to the Linux kernel. It is
308 usually called by the init_module() function of the kernel module that contains
309 the demux driver. The caller of this function is responsible for allocating
310 dynamic or static memory for the demux structure and for initializing its fields
311 before calling this function. The memory allocated for the demux structure
312 must not be freed before calling dmx_unregister_demux(),</para>
313</entry>
314 </row></tbody></tgroup></informaltable>
315<para>SYNOPSIS
316</para>
317<informaltable><tgroup cols="1"><tbody><row><entry
318 align="char">
319<para>int dmx_register_demux ( dmx_demux_t &#x22C6;demux )</para>
320</entry>
321 </row></tbody></tgroup></informaltable>
322<para>PARAMETERS
323</para>
324<informaltable><tgroup cols="2"><tbody><row><entry
325 align="char">
326<para>dmx_demux_t*
327 demux</para>
328</entry><entry
329 align="char">
330<para>Pointer to the demux structure.</para>
331</entry>
332 </row></tbody></tgroup></informaltable>
333<para>RETURNS
334</para>
335<informaltable><tgroup cols="2"><tbody><row><entry
336 align="char">
337<para>0</para>
338</entry><entry
339 align="char">
340<para>The function was completed without errors.</para>
341</entry>
342 </row><row><entry
343 align="char">
344<para>-EEXIST</para>
345</entry><entry
346 align="char">
347<para>A demux with the same value of the id field already stored
348 in the directory.</para>
349</entry>
350 </row><row><entry
351 align="char">
352<para>-ENOSPC</para>
353</entry><entry
354 align="char">
355<para>No space left in the directory.</para>
356</entry>
357 </row></tbody></tgroup></informaltable>
358
359</section><section
360role="subsection"><title>dmx_unregister_demux()</title>
361<para>DESCRIPTION
362</para>
363<informaltable><tgroup cols="1"><tbody><row><entry
364 align="char">
365<para>This function is called to indicate that the given demux interface is no
366 longer available. The caller of this function is responsible for freeing the
367 memory of the demux structure, if it was dynamically allocated before calling
368 dmx_register_demux(). The cleanup_module() function of the kernel module
369 that contains the demux driver should call this function. Note that this function
370 fails if the demux is currently in use, i.e., release_demux() has not been called
371 for the interface.</para>
372</entry>
373 </row></tbody></tgroup></informaltable>
374<para>SYNOPSIS
375</para>
376<informaltable><tgroup cols="1"><tbody><row><entry
377 align="char">
378<para>int dmx_unregister_demux ( dmx_demux_t &#x22C6;demux )</para>
379</entry>
380 </row></tbody></tgroup></informaltable>
381<para>PARAMETERS
382</para>
383<informaltable><tgroup cols="2"><tbody><row><entry
384 align="char">
385<para>dmx_demux_t*
386 demux</para>
387</entry><entry
388 align="char">
389<para>Pointer to the demux structure which is to be
390 unregistered.</para>
391</entry>
392 </row></tbody></tgroup></informaltable>
393<para>RETURNS
394</para>
395<informaltable><tgroup cols="2"><tbody><row><entry
396 align="char">
397<para>0</para>
398</entry><entry
399 align="char">
400<para>The function was completed without errors.</para>
401</entry>
402 </row><row><entry
403 align="char">
404<para>ENODEV</para>
405</entry><entry
406 align="char">
407<para>The specified demux is not registered in the demux
408 directory.</para>
409</entry>
410 </row><row><entry
411 align="char">
412<para>EBUSY</para>
413</entry><entry
414 align="char">
415<para>The specified demux is currently in use.</para>
416</entry>
417 </row></tbody></tgroup></informaltable>
418
419</section><section
420role="subsection"><title>dmx_get_demuxes()</title>
421<para>DESCRIPTION
422</para>
423<informaltable><tgroup cols="1"><tbody><row><entry
424 align="char">
425<para>Provides the caller with the list of registered demux interfaces, using the
426 standard list structure defined in the include file linux/list.h. The include file
427 demux.h defines the macro DMX_DIR_ENTRY() for converting an element of
428 the generic type struct list_head* to the type dmx_demux_t*. The caller must
429 not free the memory of any of the elements obtained via this function call.</para>
430</entry>
431 </row></tbody></tgroup></informaltable>
432<para>SYNOPSIS
433</para>
434<informaltable><tgroup cols="1"><tbody><row><entry
435 align="char">
436<para>struct list_head &#x22C6;dmx_get_demuxes ()</para>
437</entry>
438 </row></tbody></tgroup></informaltable>
439<para>PARAMETERS
440</para>
441<informaltable><tgroup cols="2"><tbody><row><entry
442 align="char">
443<para>none</para>
444</entry>
445 </row></tbody></tgroup></informaltable>
446<para>RETURNS
447</para>
448<informaltable><tgroup cols="2"><tbody><row><entry
449 align="char">
450<para>struct list_head *</para>
451</entry><entry
452 align="char">
453<para>A list of demux interfaces, or NULL in the case of an
454 empty list.</para>
455</entry>
456 </row></tbody></tgroup></informaltable>
457 </section></section>
458<section id="demux_api">
459<title>Demux API</title>
460<para>The demux API should be implemented for each demux in the system. It is used to select
461the TS source of a demux and to manage the demux resources. When the demux
462client allocates a resource via the demux API, it receives a pointer to the API of that
463resource.
464</para>
465<para>Each demux receives its TS input from a DVB front-end or from memory, as set via the
466demux API. In a system with more than one front-end, the API can be used to select one of
467the DVB front-ends as a TS source for a demux, unless this is fixed in the HW platform. The
468demux API only controls front-ends regarding their connections with demuxes; the APIs
469used to set the other front-end parameters, such as tuning, are not defined in this
470document.
471</para>
472<para>The functions that implement the abstract interface demux should be defined static or
473module private and registered to the Demux Directory for external access. It is not necessary
474to implement every function in the demux_t struct, however (for example, a demux interface
475might support Section filtering, but not TS or PES filtering). The API client is expected to
476check the value of any function pointer before calling the function: the value of NULL means
477&#8220;function not available&#8221;.
478</para>
479<para>Whenever the functions of the demux API modify shared data, the possibilities of lost
480update and race condition problems should be addressed, e.g. by protecting parts of code with
481mutexes. This is especially important on multi-processor hosts.
482</para>
483<para>Note that functions called from a bottom half context must not sleep, at least in the 2.2.x
484kernels. Even a simple memory allocation can result in a kernel thread being put to sleep if
485swapping is needed. For example, the Linux kernel calls the functions of a network device
486interface from a bottom half context. Thus, if a demux API function is called from network
487device code, the function must not sleep.
488</para>
489
490
491<section id="kdapi_fopen">
492<title>open()</title>
493<para>DESCRIPTION
494</para>
495<informaltable><tgroup cols="1"><tbody><row><entry
496 align="char">
497<para>This function reserves the demux for use by the caller and, if necessary,
498 initializes the demux. When the demux is no longer needed, the function close()
499 should be called. It should be possible for multiple clients to access the demux
500 at the same time. Thus, the function implementation should increment the
501 demux usage count when open() is called and decrement it when close() is
502 called.</para>
503</entry>
504 </row></tbody></tgroup></informaltable>
505<para>SYNOPSIS
506</para>
507<informaltable><tgroup cols="1"><tbody><row><entry
508 align="char">
509<para>int open ( demux_t&#x22C6; demux );</para>
510</entry>
511 </row></tbody></tgroup></informaltable>
512<para>PARAMETERS
513</para>
514<informaltable><tgroup cols="2"><tbody><row><entry
515 align="char">
516<para>demux_t* demux</para>
517</entry><entry
518 align="char">
519<para>Pointer to the demux API and instance data.</para>
520</entry>
521 </row></tbody></tgroup></informaltable>
522<para>RETURNS
523</para>
524<informaltable><tgroup cols="2"><tbody><row><entry
525 align="char">
526<para>0</para>
527</entry><entry
528 align="char">
529<para>The function was completed without errors.</para>
530</entry>
531 </row><row><entry
532 align="char">
533<para>-EUSERS</para>
534</entry><entry
535 align="char">
536<para>Maximum usage count reached.</para>
537</entry>
538 </row><row><entry
539 align="char">
540<para>-EINVAL</para>
541</entry><entry
542 align="char">
543<para>Bad parameter.</para>
544</entry>
545 </row></tbody></tgroup></informaltable>
546
547</section>
548<section id="kdapi_fclose">
549<title>close()</title>
550<para>DESCRIPTION
551</para>
552<informaltable><tgroup cols="1"><tbody><row><entry
553 align="char">
554<para>This function reserves the demux for use by the caller and, if necessary,
555 initializes the demux. When the demux is no longer needed, the function close()
556 should be called. It should be possible for multiple clients to access the demux
557 at the same time. Thus, the function implementation should increment the
558 demux usage count when open() is called and decrement it when close() is
559 called.</para>
560</entry>
561 </row></tbody></tgroup></informaltable>
562<para>SYNOPSIS
563</para>
564<informaltable><tgroup cols="1"><tbody><row><entry
565 align="char">
566<para>int close(demux_t&#x22C6; demux);</para>
567</entry>
568 </row></tbody></tgroup></informaltable>
569<para>PARAMETERS
570</para>
571<informaltable><tgroup cols="2"><tbody><row><entry
572 align="char">
573<para>demux_t* demux</para>
574</entry><entry
575 align="char">
576<para>Pointer to the demux API and instance data.</para>
577</entry>
578 </row></tbody></tgroup></informaltable>
579<para>RETURNS
580</para>
581<informaltable><tgroup cols="2"><tbody><row><entry
582 align="char">
583<para>0</para>
584</entry><entry
585 align="char">
586<para>The function was completed without errors.</para>
587</entry>
588 </row><row><entry
589 align="char">
590<para>-ENODEV</para>
591</entry><entry
592 align="char">
593<para>The demux was not in use.</para>
594</entry>
595 </row><row><entry
596 align="char">
597<para>-EINVAL</para>
598</entry><entry
599 align="char">
600<para>Bad parameter.</para>
601</entry>
602 </row></tbody></tgroup></informaltable>
603
604</section>
605<section id="kdapi_fwrite">
606<title>write()</title>
607<para>DESCRIPTION
608</para>
609<informaltable><tgroup cols="1"><tbody><row><entry
610 align="char">
611<para>This function provides the demux driver with a memory buffer containing TS
612 packets. Instead of receiving TS packets from the DVB front-end, the demux
613 driver software will read packets from memory. Any clients of this demux
614 with active TS, PES or Section filters will receive filtered data via the Demux
615 callback API (see 0). The function returns when all the data in the buffer has
616 been consumed by the demux. Demux hardware typically cannot read TS from
617 memory. If this is the case, memory-based filtering has to be implemented
618 entirely in software.</para>
619</entry>
620 </row></tbody></tgroup></informaltable>
621<para>SYNOPSIS
622</para>
623<informaltable><tgroup cols="1"><tbody><row><entry
624 align="char">
625<para>int write(demux_t&#x22C6; demux, const char&#x22C6; buf, size_t
626 count);</para>
627</entry>
628 </row></tbody></tgroup></informaltable>
629<para>PARAMETERS
630</para>
631<informaltable><tgroup cols="2"><tbody><row><entry
632 align="char">
633<para>demux_t* demux</para>
634</entry><entry
635 align="char">
636<para>Pointer to the demux API and instance data.</para>
637</entry>
638 </row><row><entry
639 align="char">
640<para>const char* buf</para>
641</entry><entry
642 align="char">
643<para>Pointer to the TS data in kernel-space memory.</para>
644</entry>
645 </row><row><entry
646 align="char">
647<para>size_t length</para>
648</entry><entry
649 align="char">
650<para>Length of the TS data.</para>
651</entry>
652 </row></tbody></tgroup></informaltable>
653<para>RETURNS
654</para>
655<informaltable><tgroup cols="2"><tbody><row><entry
656 align="char">
657<para>0</para>
658</entry><entry
659 align="char">
660<para>The function was completed without errors.</para>
661</entry>
662 </row><row><entry
663 align="char">
664<para>-ENOSYS</para>
665</entry><entry
666 align="char">
667<para>The command is not implemented.</para>
668</entry>
669 </row><row><entry
670 align="char">
671<para>-EINVAL</para>
672</entry><entry
673 align="char">
674<para>Bad parameter.</para>
675</entry>
676 </row></tbody></tgroup></informaltable>
677
678</section><section
679role="subsection"><title>allocate_ts_feed()</title>
680<para>DESCRIPTION
681</para>
682<informaltable><tgroup cols="1"><tbody><row><entry
683 align="char">
684<para>Allocates a new TS feed, which is used to filter the TS packets carrying a
685 certain PID. The TS feed normally corresponds to a hardware PID filter on the
686 demux chip.</para>
687</entry>
688 </row></tbody></tgroup></informaltable>
689<para>SYNOPSIS
690</para>
691<informaltable><tgroup cols="1"><tbody><row><entry
692 align="char">
693<para>int allocate_ts_feed(dmx_demux_t&#x22C6; demux,
694 dmx_ts_feed_t&#x22C6;&#x22C6; feed, dmx_ts_cb callback);</para>
695</entry>
696 </row></tbody></tgroup></informaltable>
697<para>PARAMETERS
698</para>
699<informaltable><tgroup cols="2"><tbody><row><entry
700 align="char">
701<para>demux_t* demux</para>
702</entry><entry
703 align="char">
704<para>Pointer to the demux API and instance data.</para>
705</entry>
706 </row><row><entry
707 align="char">
708<para>dmx_ts_feed_t**
709 feed</para>
710</entry><entry
711 align="char">
712<para>Pointer to the TS feed API and instance data.</para>
713</entry>
714 </row><row><entry
715 align="char">
716<para>dmx_ts_cb callback</para>
717</entry><entry
718 align="char">
719<para>Pointer to the callback function for passing received TS
720 packet</para>
721</entry>
722 </row></tbody></tgroup></informaltable>
723<para>RETURNS
724</para>
725<informaltable><tgroup cols="2"><tbody><row><entry
726 align="char">
727<para>0</para>
728</entry><entry
729 align="char">
730<para>The function was completed without errors.</para>
731</entry>
732 </row><row><entry
733 align="char">
734<para>-EBUSY</para>
735</entry><entry
736 align="char">
737<para>No more TS feeds available.</para>
738</entry>
739 </row><row><entry
740 align="char">
741<para>-ENOSYS</para>
742</entry><entry
743 align="char">
744<para>The command is not implemented.</para>
745</entry>
746 </row><row><entry
747 align="char">
748<para>-EINVAL</para>
749</entry><entry
750 align="char">
751<para>Bad parameter.</para>
752</entry>
753 </row></tbody></tgroup></informaltable>
754
755</section><section
756role="subsection"><title>release_ts_feed()</title>
757<para>DESCRIPTION
758</para>
759<informaltable><tgroup cols="1"><tbody><row><entry
760 align="char">
761<para>Releases the resources allocated with allocate_ts_feed(). Any filtering in
762 progress on the TS feed should be stopped before calling this function.</para>
763</entry>
764 </row></tbody></tgroup></informaltable>
765<para>SYNOPSIS
766</para>
767<informaltable><tgroup cols="1"><tbody><row><entry
768 align="char">
769<para>int release_ts_feed(dmx_demux_t&#x22C6; demux,
770 dmx_ts_feed_t&#x22C6; feed);</para>
771</entry>
772 </row></tbody></tgroup></informaltable>
773<para>PARAMETERS
774</para>
775<informaltable><tgroup cols="2"><tbody><row><entry
776 align="char">
777<para>demux_t* demux</para>
778</entry><entry
779 align="char">
780<para>Pointer to the demux API and instance data.</para>
781</entry>
782 </row><row><entry
783 align="char">
784<para>dmx_ts_feed_t* feed</para>
785</entry><entry
786 align="char">
787<para>Pointer to the TS feed API and instance data.</para>
788</entry>
789 </row></tbody></tgroup></informaltable>
790<para>RETURNS
791</para>
792<informaltable><tgroup cols="2"><tbody><row><entry
793 align="char">
794<para>0</para>
795</entry><entry
796 align="char">
797<para>The function was completed without errors.</para>
798</entry>
799 </row><row><entry
800 align="char">
801<para>-EINVAL</para>
802</entry><entry
803 align="char">
804<para>Bad parameter.</para>
805</entry>
806 </row></tbody></tgroup></informaltable>
807
808</section><section
809role="subsection"><title>allocate_section_feed()</title>
810<para>DESCRIPTION
811</para>
812<informaltable><tgroup cols="1"><tbody><row><entry
813 align="char">
814<para>Allocates a new section feed, i.e. a demux resource for filtering and receiving
815 sections. On platforms with hardware support for section filtering, a section
816 feed is directly mapped to the demux HW. On other platforms, TS packets are
817 first PID filtered in hardware and a hardware section filter then emulated in
818 software. The caller obtains an API pointer of type dmx_section_feed_t as an
819 out parameter. Using this API the caller can set filtering parameters and start
820 receiving sections.</para>
821</entry>
822 </row></tbody></tgroup></informaltable>
823<para>SYNOPSIS
824</para>
825<informaltable><tgroup cols="1"><tbody><row><entry
826 align="char">
827<para>int allocate_section_feed(dmx_demux_t&#x22C6; demux,
828 dmx_section_feed_t &#x22C6;&#x22C6;feed, dmx_section_cb callback);</para>
829</entry>
830 </row></tbody></tgroup></informaltable>
831<para>PARAMETERS
832</para>
833<informaltable><tgroup cols="2"><tbody><row><entry
834 align="char">
835<para>demux_t *demux</para>
836</entry><entry
837 align="char">
838<para>Pointer to the demux API and instance data.</para>
839</entry>
840 </row><row><entry
841 align="char">
842<para>dmx_section_feed_t
843 **feed</para>
844</entry><entry
845 align="char">
846<para>Pointer to the section feed API and instance data.</para>
847</entry>
848 </row><row><entry
849 align="char">
850<para>dmx_section_cb
851 callback</para>
852</entry><entry
853 align="char">
854<para>Pointer to the callback function for passing received
855 sections.</para>
856</entry>
857 </row></tbody></tgroup></informaltable>
858<para>RETURNS
859</para>
860<informaltable><tgroup cols="2"><tbody><row><entry
861 align="char">
862<para>0</para>
863</entry><entry
864 align="char">
865<para>The function was completed without errors.</para>
866</entry>
867 </row><row><entry
868 align="char">
869<para>-EBUSY</para>
870</entry><entry
871 align="char">
872<para>No more section feeds available.</para>
873</entry>
874 </row><row><entry
875 align="char">
876<para>-ENOSYS</para>
877</entry><entry
878 align="char">
879<para>The command is not implemented.</para>
880</entry>
881 </row><row><entry
882 align="char">
883<para>-EINVAL</para>
884</entry><entry
885 align="char">
886<para>Bad parameter.</para>
887</entry>
888 </row></tbody></tgroup></informaltable>
889
890</section><section
891role="subsection"><title>release_section_feed()</title>
892<para>DESCRIPTION
893</para>
894<informaltable><tgroup cols="1"><tbody><row><entry
895 align="char">
896<para>Releases the resources allocated with allocate_section_feed(), including
897 allocated filters. Any filtering in progress on the section feed should be stopped
898 before calling this function.</para>
899</entry>
900 </row></tbody></tgroup></informaltable>
901<para>SYNOPSIS
902</para>
903<informaltable><tgroup cols="1"><tbody><row><entry
904 align="char">
905<para>int release_section_feed(dmx_demux_t&#x22C6; demux,
906 dmx_section_feed_t &#x22C6;feed);</para>
907</entry>
908 </row></tbody></tgroup></informaltable>
909<para>PARAMETERS
910</para>
911<informaltable><tgroup cols="2"><tbody><row><entry
912 align="char">
913<para>demux_t *demux</para>
914</entry><entry
915 align="char">
916<para>Pointer to the demux API and instance data.</para>
917</entry>
918 </row><row><entry
919 align="char">
920<para>dmx_section_feed_t
921 *feed</para>
922</entry><entry
923 align="char">
924<para>Pointer to the section feed API and instance data.</para>
925</entry>
926 </row></tbody></tgroup></informaltable>
927<para>RETURNS
928</para>
929<informaltable><tgroup cols="2"><tbody><row><entry
930 align="char">
931<para>0</para>
932</entry><entry
933 align="char">
934<para>The function was completed without errors.</para>
935</entry>
936 </row><row><entry
937 align="char">
938<para>-EINVAL</para>
939</entry><entry
940 align="char">
941<para>Bad parameter.</para>
942</entry>
943 </row></tbody></tgroup></informaltable>
944
945</section><section
946role="subsection"><title>descramble_mac_address()</title>
947<para>DESCRIPTION
948</para>
949<informaltable><tgroup cols="1"><tbody><row><entry
950 align="char">
951<para>This function runs a descrambling algorithm on the destination MAC
952 address field of a DVB Datagram Section, replacing the original address
953 with its un-encrypted version. Otherwise, the description on the function
954 descramble_section_payload() applies also to this function.</para>
955</entry>
956 </row></tbody></tgroup></informaltable>
957<para>SYNOPSIS
958</para>
959<informaltable><tgroup cols="1"><tbody><row><entry
960 align="char">
961<para>int descramble_mac_address(dmx_demux_t&#x22C6; demux, __u8
962 &#x22C6;buffer1, size_t buffer1_length, __u8 &#x22C6;buffer2,
963 size_t buffer2_length, __u16 pid);</para>
964</entry>
965 </row></tbody></tgroup></informaltable>
966<para>PARAMETERS
967</para>
968<informaltable><tgroup cols="2"><tbody><row><entry
969 align="char">
970<para>dmx_demux_t
971 *demux</para>
972</entry><entry
973 align="char">
974<para>Pointer to the demux API and instance data.</para>
975</entry>
976 </row><row><entry
977 align="char">
978<para>__u8 *buffer1</para>
979</entry><entry
980 align="char">
981<para>Pointer to the first byte of the section.</para>
982</entry>
983 </row><row><entry
984 align="char">
985<para>size_t buffer1_length</para>
986</entry><entry
987 align="char">
988<para>Length of the section data, including headers and CRC,
989 in buffer1.</para>
990</entry>
991 </row><row><entry
992 align="char">
993<para>__u8* buffer2</para>
994</entry><entry
995 align="char">
996<para>Pointer to the tail of the section data, or NULL. The
997 pointer has a non-NULL value if the section wraps past
998 the end of a circular buffer.</para>
999</entry>
1000 </row><row><entry
1001 align="char">
1002<para>size_t buffer2_length</para>
1003</entry><entry
1004 align="char">
1005<para>Length of the section data, including headers and CRC,
1006 in buffer2.</para>
1007</entry>
1008 </row><row><entry
1009 align="char">
1010<para>__u16 pid</para>
1011</entry><entry
1012 align="char">
1013<para>The PID on which the section was received. Useful
1014 for obtaining the descrambling key, e.g. from a DVB
1015 Common Access facility.</para>
1016</entry>
1017 </row></tbody></tgroup></informaltable>
1018<para>RETURNS
1019</para>
1020<informaltable><tgroup cols="2"><tbody><row><entry
1021 align="char">
1022<para>0</para>
1023</entry><entry
1024 align="char">
1025<para>The function was completed without errors.</para>
1026</entry>
1027 </row><row><entry
1028 align="char">
1029<para>-ENOSYS</para>
1030</entry><entry
1031 align="char">
1032<para>No descrambling facility available.</para>
1033</entry>
1034 </row><row><entry
1035 align="char">
1036<para>-EINVAL</para>
1037</entry><entry
1038 align="char">
1039<para>Bad parameter.</para>
1040</entry>
1041 </row></tbody></tgroup></informaltable>
1042
1043</section><section
1044role="subsection"><title>descramble_section_payload()</title>
1045<para>DESCRIPTION
1046</para>
1047<informaltable><tgroup cols="1"><tbody><row><entry
1048 align="char">
1049<para>This function runs a descrambling algorithm on the payload of a DVB
1050 Datagram Section, replacing the original payload with its un-encrypted
1051 version. The function will be called from the demux API implementation;
1052 the API client need not call this function directly. Section-level scrambling
1053 algorithms are currently standardized only for DVB-RCC (return channel
1054 over 2-directional cable TV network) systems. For all other DVB networks,
1055 encryption schemes are likely to be proprietary to each data broadcaster. Thus,
1056 it is expected that this function pointer will have the value of NULL (i.e.,
1057 function not available) in most demux API implementations. Nevertheless, it
1058 should be possible to use the function pointer as a hook for dynamically adding
1059 a &#8220;plug-in&#8221; descrambling facility to a demux driver.</para>
1060</entry>
1061 </row><row><entry
1062 align="char">
1063<para>While this function is not needed with hardware-based section descrambling,
1064 the descramble_section_payload function pointer can be used to override the
1065 default hardware-based descrambling algorithm: if the function pointer has a
1066 non-NULL value, the corresponding function should be used instead of any
1067 descrambling hardware.</para>
1068</entry>
1069 </row></tbody></tgroup></informaltable>
1070<para>SYNOPSIS
1071</para>
1072<informaltable><tgroup cols="1"><tbody><row><entry
1073 align="char">
1074<para>int descramble_section_payload(dmx_demux_t&#x22C6; demux,
1075 __u8 &#x22C6;buffer1, size_t buffer1_length, __u8 &#x22C6;buffer2,
1076 size_t buffer2_length, __u16 pid);</para>
1077</entry>
1078 </row></tbody></tgroup></informaltable>
1079<para>PARAMETERS
1080</para>
1081<informaltable><tgroup cols="2"><tbody><row><entry
1082 align="char">
1083<para>dmx_demux_t
1084 *demux</para>
1085</entry><entry
1086 align="char">
1087<para>Pointer to the demux API and instance data.</para>
1088</entry>
1089 </row><row><entry
1090 align="char">
1091<para>__u8 *buffer1</para>
1092</entry><entry
1093 align="char">
1094<para>Pointer to the first byte of the section.</para>
1095</entry>
1096 </row><row><entry
1097 align="char">
1098<para>size_t buffer1_length</para>
1099</entry><entry
1100 align="char">
1101<para>Length of the section data, including headers and CRC,
1102 in buffer1.</para>
1103</entry>
1104 </row><row><entry
1105 align="char">
1106<para>__u8 *buffer2</para>
1107</entry><entry
1108 align="char">
1109<para>Pointer to the tail of the section data, or NULL. The
1110 pointer has a non-NULL value if the section wraps past
1111 the end of a circular buffer.</para>
1112</entry>
1113 </row><row><entry
1114 align="char">
1115<para>size_t buffer2_length</para>
1116</entry><entry
1117 align="char">
1118<para>Length of the section data, including headers and CRC,
1119 in buffer2.</para>
1120</entry>
1121 </row><row><entry
1122 align="char">
1123<para>__u16 pid</para>
1124</entry><entry
1125 align="char">
1126<para>The PID on which the section was received. Useful
1127 for obtaining the descrambling key, e.g. from a DVB
1128 Common Access facility.</para>
1129</entry>
1130 </row></tbody></tgroup></informaltable>
1131<para>RETURNS
1132</para>
1133<informaltable><tgroup cols="2"><tbody><row><entry
1134 align="char">
1135<para>0</para>
1136</entry><entry
1137 align="char">
1138<para>The function was completed without errors.</para>
1139</entry>
1140 </row><row><entry
1141 align="char">
1142<para>-ENOSYS</para>
1143</entry><entry
1144 align="char">
1145<para>No descrambling facility available.</para>
1146</entry>
1147 </row><row><entry
1148 align="char">
1149<para>-EINVAL</para>
1150</entry><entry
1151 align="char">
1152<para>Bad parameter.</para>
1153</entry>
1154 </row></tbody></tgroup></informaltable>
1155
1156</section><section
1157role="subsection"><title>add_frontend()</title>
1158<para>DESCRIPTION
1159</para>
1160<informaltable><tgroup cols="1"><tbody><row><entry
1161 align="char">
1162<para>Registers a connectivity between a demux and a front-end, i.e., indicates that
1163 the demux can be connected via a call to connect_frontend() to use the given
1164 front-end as a TS source. The client of this function has to allocate dynamic or
1165 static memory for the frontend structure and initialize its fields before calling
1166 this function. This function is normally called during the driver initialization.
1167 The caller must not free the memory of the frontend struct before successfully
1168 calling remove_frontend().</para>
1169</entry>
1170 </row></tbody></tgroup></informaltable>
1171<para>SYNOPSIS
1172</para>
1173<informaltable><tgroup cols="1"><tbody><row><entry
1174 align="char">
1175<para>int add_frontend(dmx_demux_t &#x22C6;demux, dmx_frontend_t
1176 &#x22C6;frontend);</para>
1177</entry>
1178 </row></tbody></tgroup></informaltable>
1179<para>PARAMETERS
1180</para>
1181<informaltable><tgroup cols="2"><tbody><row><entry
1182 align="char">
1183<para>dmx_demux_t*
1184 demux</para>
1185</entry><entry
1186 align="char">
1187<para>Pointer to the demux API and instance data.</para>
1188</entry>
1189 </row><row><entry
1190 align="char">
1191<para>dmx_frontend_t*
1192 frontend</para>
1193</entry><entry
1194 align="char">
1195<para>Pointer to the front-end instance data.</para>
1196</entry>
1197 </row></tbody></tgroup></informaltable>
1198<para>RETURNS
1199</para>
1200<informaltable><tgroup cols="2"><tbody><row><entry
1201 align="char">
1202<para>0</para>
1203</entry><entry
1204 align="char">
1205<para>The function was completed without errors.</para>
1206</entry>
1207 </row><row><entry
1208 align="char">
1209<para>-EEXIST</para>
1210</entry><entry
1211 align="char">
1212<para>A front-end with the same value of the id field already
1213 registered.</para>
1214</entry>
1215 </row><row><entry
1216 align="char">
1217<para>-EINUSE</para>
1218</entry><entry
1219 align="char">
1220<para>The demux is in use.</para>
1221</entry>
1222 </row><row><entry
1223 align="char">
1224<para>-ENOMEM</para>
1225</entry><entry
1226 align="char">
1227<para>No more front-ends can be added.</para>
1228</entry>
1229 </row><row><entry
1230 align="char">
1231<para>-EINVAL</para>
1232</entry><entry
1233 align="char">
1234<para>Bad parameter.</para>
1235</entry>
1236 </row></tbody></tgroup></informaltable>
1237
1238</section><section
1239role="subsection"><title>remove_frontend()</title>
1240<para>DESCRIPTION
1241</para>
1242<informaltable><tgroup cols="1"><tbody><row><entry
1243 align="char">
1244<para>Indicates that the given front-end, registered by a call to add_frontend(), can
1245 no longer be connected as a TS source by this demux. The function should be
1246 called when a front-end driver or a demux driver is removed from the system.
1247 If the front-end is in use, the function fails with the return value of -EBUSY.
1248 After successfully calling this function, the caller can free the memory of
1249 the frontend struct if it was dynamically allocated before the add_frontend()
1250 operation.</para>
1251</entry>
1252 </row></tbody></tgroup></informaltable>
1253<para>SYNOPSIS
1254</para>
1255<informaltable><tgroup cols="1"><tbody><row><entry
1256 align="char">
1257<para>int remove_frontend(dmx_demux_t&#x22C6; demux,
1258 dmx_frontend_t&#x22C6; frontend);</para>
1259</entry>
1260 </row></tbody></tgroup></informaltable>
1261<para>PARAMETERS
1262</para>
1263<informaltable><tgroup cols="2"><tbody><row><entry
1264 align="char">
1265<para>dmx_demux_t*
1266 demux</para>
1267</entry><entry
1268 align="char">
1269<para>Pointer to the demux API and instance data.</para>
1270</entry>
1271 </row><row><entry
1272 align="char">
1273<para>dmx_frontend_t*
1274 frontend</para>
1275</entry><entry
1276 align="char">
1277<para>Pointer to the front-end instance data.</para>
1278</entry>
1279 </row></tbody></tgroup></informaltable>
1280<para>RETURNS
1281</para>
1282<informaltable><tgroup cols="2"><tbody><row><entry
1283 align="char">
1284<para>0</para>
1285</entry><entry
1286 align="char">
1287<para>The function was completed without errors.</para>
1288</entry>
1289 </row><row><entry
1290 align="char">
1291<para>-EINVAL</para>
1292</entry><entry
1293 align="char">
1294<para>Bad parameter.</para>
1295</entry>
1296 </row><row><entry
1297 align="char">
1298<para>-EBUSY</para>
1299</entry><entry
1300 align="char">
1301<para>The front-end is in use, i.e. a call to connect_frontend()
1302 has not been followed by a call to disconnect_frontend().</para>
1303</entry>
1304 </row></tbody></tgroup></informaltable>
1305
1306</section><section
1307role="subsection"><title>get_frontends()</title>
1308<para>DESCRIPTION
1309</para>
1310<informaltable><tgroup cols="1"><tbody><row><entry
1311 align="char">
1312<para>Provides the APIs of the front-ends that have been registered for this demux.
1313 Any of the front-ends obtained with this call can be used as a parameter for
1314 connect_frontend().</para>
1315</entry>
1316 </row><row><entry
1317 align="char">
1318<para>The include file demux.h contains the macro DMX_FE_ENTRY() for
1319 converting an element of the generic type struct list_head* to the type
1320 dmx_frontend_t*. The caller must not free the memory of any of the elements
1321 obtained via this function call.</para>
1322</entry>
1323 </row></tbody></tgroup></informaltable>
1324<para>SYNOPSIS
1325</para>
1326<informaltable><tgroup cols="1"><tbody><row><entry
1327 align="char">
1328<para>struct list_head&#x22C6; get_frontends(dmx_demux_t&#x22C6; demux);</para>
1329</entry>
1330 </row></tbody></tgroup></informaltable>
1331<para>PARAMETERS
1332</para>
1333<informaltable><tgroup cols="2"><tbody><row><entry
1334 align="char">
1335<para>dmx_demux_t*
1336 demux</para>
1337</entry><entry
1338 align="char">
1339<para>Pointer to the demux API and instance data.</para>
1340</entry>
1341 </row></tbody></tgroup></informaltable>
1342<para>RETURNS
1343</para>
1344<informaltable><tgroup cols="2"><tbody><row><entry
1345 align="char">
1346<para>dmx_demux_t*</para>
1347</entry><entry
1348 align="char">
1349<para>A list of front-end interfaces, or NULL in the case of an
1350 empty list.</para>
1351</entry>
1352 </row></tbody></tgroup></informaltable>
1353
1354</section><section
1355role="subsection"><title>connect_frontend()</title>
1356<para>DESCRIPTION
1357</para>
1358<informaltable><tgroup cols="1"><tbody><row><entry
1359 align="char">
1360<para>Connects the TS output of the front-end to the input of the demux. A demux
1361 can only be connected to a front-end registered to the demux with the function
1362 add_frontend().</para>
1363</entry>
1364 </row><row><entry
1365 align="char">
1366<para>It may or may not be possible to connect multiple demuxes to the same
1367 front-end, depending on the capabilities of the HW platform. When not used,
1368 the front-end should be released by calling disconnect_frontend().</para>
1369</entry>
1370 </row></tbody></tgroup></informaltable>
1371<para>SYNOPSIS
1372</para>
1373<informaltable><tgroup cols="1"><tbody><row><entry
1374 align="char">
1375<para>int connect_frontend(dmx_demux_t&#x22C6; demux,
1376 dmx_frontend_t&#x22C6; frontend);</para>
1377</entry>
1378 </row></tbody></tgroup></informaltable>
1379<para>PARAMETERS
1380</para>
1381<informaltable><tgroup cols="2"><tbody><row><entry
1382 align="char">
1383<para>dmx_demux_t*
1384 demux</para>
1385</entry><entry
1386 align="char">
1387<para>Pointer to the demux API and instance data.</para>
1388</entry>
1389 </row><row><entry
1390 align="char">
1391<para>dmx_frontend_t*
1392 frontend</para>
1393</entry><entry
1394 align="char">
1395<para>Pointer to the front-end instance data.</para>
1396</entry>
1397 </row></tbody></tgroup></informaltable>
1398<para>RETURNS
1399</para>
1400<informaltable><tgroup cols="2"><tbody><row><entry
1401 align="char">
1402<para>0</para>
1403</entry><entry
1404 align="char">
1405<para>The function was completed without errors.</para>
1406</entry>
1407 </row><row><entry
1408 align="char">
1409<para>-EINVAL</para>
1410</entry><entry
1411 align="char">
1412<para>Bad parameter.</para>
1413</entry>
1414 </row><row><entry
1415 align="char">
1416<para>-EBUSY</para>
1417</entry><entry
1418 align="char">
1419<para>The front-end is in use.</para>
1420</entry>
1421 </row></tbody></tgroup></informaltable>
1422
1423</section><section
1424role="subsection"><title>disconnect_frontend()</title>
1425<para>DESCRIPTION
1426</para>
1427<informaltable><tgroup cols="1"><tbody><row><entry
1428 align="char">
1429<para>Disconnects the demux and a front-end previously connected by a
1430 connect_frontend() call.</para>
1431</entry>
1432 </row></tbody></tgroup></informaltable>
1433<para>SYNOPSIS
1434</para>
1435<informaltable><tgroup cols="1"><tbody><row><entry
1436 align="char">
1437<para>int disconnect_frontend(dmx_demux_t&#x22C6; demux);</para>
1438</entry>
1439 </row></tbody></tgroup></informaltable>
1440<para>PARAMETERS
1441</para>
1442<informaltable><tgroup cols="2"><tbody><row><entry
1443 align="char">
1444<para>dmx_demux_t*
1445 demux</para>
1446</entry><entry
1447 align="char">
1448<para>Pointer to the demux API and instance data.</para>
1449</entry>
1450 </row></tbody></tgroup></informaltable>
1451<para>RETURNS
1452</para>
1453<informaltable><tgroup cols="2"><tbody><row><entry
1454 align="char">
1455<para>0</para>
1456</entry><entry
1457 align="char">
1458<para>The function was completed without errors.</para>
1459</entry>
1460 </row><row><entry
1461 align="char">
1462<para>-EINVAL</para>
1463</entry><entry
1464 align="char">
1465<para>Bad parameter.</para>
1466</entry>
1467 </row></tbody></tgroup></informaltable>
1468 </section></section>
1469<section id="demux_callback_api">
1470<title>Demux Callback API</title>
1471<para>This kernel-space API comprises the callback functions that deliver filtered data to the
1472demux client. Unlike the other APIs, these API functions are provided by the client and called
1473from the demux code.
1474</para>
1475<para>The function pointers of this abstract interface are not packed into a structure as in the
1476other demux APIs, because the callback functions are registered and used independent
1477of each other. As an example, it is possible for the API client to provide several
1478callback functions for receiving TS packets and no callbacks for PES packets or
1479sections.
1480</para>
1481<para>The functions that implement the callback API need not be re-entrant: when a demux
1482driver calls one of these functions, the driver is not allowed to call the function again before
1483the original call returns. If a callback is triggered by a hardware interrupt, it is recommended
1484to use the Linux &#8220;bottom half&#8221; mechanism or start a tasklet instead of making the callback
1485function call directly from a hardware interrupt.
1486</para>
1487
1488<section
1489role="subsection"><title>dmx_ts_cb()</title>
1490<para>DESCRIPTION
1491</para>
1492<informaltable><tgroup cols="1"><tbody><row><entry
1493 align="char">
1494<para>This function, provided by the client of the demux API, is called from the
1495 demux code. The function is only called when filtering on this TS feed has
1496 been enabled using the start_filtering() function.</para>
1497</entry>
1498 </row><row><entry
1499 align="char">
1500<para>Any TS packets that match the filter settings are copied to a circular buffer. The
1501 filtered TS packets are delivered to the client using this callback function. The
1502 size of the circular buffer is controlled by the circular_buffer_size parameter
1503 of the set() function in the TS Feed API. It is expected that the buffer1 and
1504 buffer2 callback parameters point to addresses within the circular buffer, but
1505 other implementations are also possible. Note that the called party should not
1506 try to free the memory the buffer1 and buffer2 parameters point to.</para>
1507</entry>
1508 </row><row><entry
1509 align="char">
1510<para>When this function is called, the buffer1 parameter typically points to the
1511 start of the first undelivered TS packet within a circular buffer. The buffer2
1512 buffer parameter is normally NULL, except when the received TS packets have
1513 crossed the last address of the circular buffer and &#8221;wrapped&#8221; to the beginning
1514 of the buffer. In the latter case the buffer1 parameter would contain an address
1515 within the circular buffer, while the buffer2 parameter would contain the first
1516 address of the circular buffer.</para>
1517</entry>
1518 </row><row><entry
1519 align="char">
1520<para>The number of bytes delivered with this function (i.e. buffer1_length +
1521 buffer2_length) is usually equal to the value of callback_length parameter
1522 given in the set() function, with one exception: if a timeout occurs before
1523 receiving callback_length bytes of TS data, any undelivered packets are
1524 immediately delivered to the client by calling this function. The timeout
1525 duration is controlled by the set() function in the TS Feed API.</para>
1526</entry>
1527 </row><row><entry
1528 align="char">
1529<para>If a TS packet is received with errors that could not be fixed by the TS-level
1530 forward error correction (FEC), the Transport_error_indicator flag of the TS
1531 packet header should be set. The TS packet should not be discarded, as
1532 the error can possibly be corrected by a higher layer protocol. If the called
1533 party is slow in processing the callback, it is possible that the circular buffer
1534 eventually fills up. If this happens, the demux driver should discard any TS
1535 packets received while the buffer is full. The error should be indicated to the
1536 client on the next callback by setting the success parameter to the value of
1537 DMX_OVERRUN_ERROR.</para>
1538</entry>
1539 </row><row><entry
1540 align="char">
1541<para>The type of data returned to the callback can be selected by the new
1542 function int (*set_type) (struct dmx_ts_feed_s* feed, int type, dmx_ts_pes_t
1543 pes_type) which is part of the dmx_ts_feed_s struct (also cf. to the
1544 include file ost/demux.h) The type parameter decides if the raw TS packet
1545 (TS_PACKET) or just the payload (TS_PACKET&#8212;TS_PAYLOAD_ONLY)
1546 should be returned. If additionally the TS_DECODER bit is set the stream
1547 will also be sent to the hardware MPEG decoder. In this case, the second
1548 flag decides as what kind of data the stream should be interpreted. The
1549 possible choices are one of DMX_TS_PES_AUDIO, DMX_TS_PES_VIDEO,
1550 DMX_TS_PES_TELETEXT, DMX_TS_PES_SUBTITLE,
1551 DMX_TS_PES_PCR, or DMX_TS_PES_OTHER.</para>
1552</entry>
1553 </row></tbody></tgroup></informaltable>
1554<para>SYNOPSIS
1555</para>
1556<informaltable><tgroup cols="1"><tbody><row><entry
1557 align="char">
1558<para>int dmx_ts_cb(__u8&#x22C6; buffer1, size_t buffer1_length,
1559 __u8&#x22C6; buffer2, size_t buffer2_length, dmx_ts_feed_t&#x22C6;
1560 source, dmx_success_t success);</para>
1561</entry>
1562 </row></tbody></tgroup></informaltable>
1563<para>PARAMETERS
1564</para>
1565<informaltable><tgroup cols="2"><tbody><row><entry
1566 align="char">
1567<para>__u8* buffer1</para>
1568</entry><entry
1569 align="char">
1570<para>Pointer to the start of the filtered TS packets.</para>
1571</entry>
1572 </row><row><entry
1573 align="char">
1574<para>size_t buffer1_length</para>
1575</entry><entry
1576 align="char">
1577<para>Length of the TS data in buffer1.</para>
1578</entry>
1579 </row><row><entry
1580 align="char">
1581<para>__u8* buffer2</para>
1582</entry><entry
1583 align="char">
1584<para>Pointer to the tail of the filtered TS packets, or NULL.</para>
1585</entry>
1586 </row><row><entry
1587 align="char">
1588<para>size_t buffer2_length</para>
1589</entry><entry
1590 align="char">
1591<para>Length of the TS data in buffer2.</para>
1592</entry>
1593 </row><row><entry
1594 align="char">
1595<para>dmx_ts_feed_t*
1596 source</para>
1597</entry><entry
1598 align="char">
1599<para>Indicates which TS feed is the source of the callback.</para>
1600</entry>
1601 </row><row><entry
1602 align="char">
1603<para>dmx_success_t
1604 success</para>
1605</entry><entry
1606 align="char">
1607<para>Indicates if there was an error in TS reception.</para>
1608</entry>
1609 </row></tbody></tgroup></informaltable>
1610<para>RETURNS
1611</para>
1612<informaltable><tgroup cols="2"><tbody><row><entry
1613 align="char">
1614<para>0</para>
1615</entry><entry
1616 align="char">
1617<para>Continue filtering.</para>
1618</entry>
1619 </row><row><entry
1620 align="char">
1621<para>-1</para>
1622</entry><entry
1623 align="char">
1624<para>Stop filtering - has the same effect as a call to
1625 stop_filtering() on the TS Feed API.</para>
1626</entry>
1627 </row></tbody></tgroup></informaltable>
1628
1629</section><section
1630role="subsection"><title>dmx_section_cb()</title>
1631<para>DESCRIPTION
1632</para>
1633<informaltable><tgroup cols="1"><tbody><row><entry
1634 align="char">
1635<para>This function, provided by the client of the demux API, is called from the
1636 demux code. The function is only called when filtering of sections has been
1637 enabled using the function start_filtering() of the section feed API. When the
1638 demux driver has received a complete section that matches at least one section
1639 filter, the client is notified via this callback function. Normally this function is
1640 called for each received section; however, it is also possible to deliver multiple
1641 sections with one callback, for example when the system load is high. If an
1642 error occurs while receiving a section, this function should be called with
1643 the corresponding error type set in the success field, whether or not there is
1644 data to deliver. The Section Feed implementation should maintain a circular
1645 buffer for received sections. However, this is not necessary if the Section Feed
1646 API is implemented as a client of the TS Feed API, because the TS Feed
1647 implementation then buffers the received data. The size of the circular buffer
1648 can be configured using the set() function in the Section Feed API. If there
1649 is no room in the circular buffer when a new section is received, the section
1650 must be discarded. If this happens, the value of the success parameter should
1651 be DMX_OVERRUN_ERROR on the next callback.</para>
1652</entry>
1653 </row></tbody></tgroup></informaltable>
1654<para>SYNOPSIS
1655</para>
1656<informaltable><tgroup cols="1"><tbody><row><entry
1657 align="char">
1658<para>int dmx_section_cb(__u8&#x22C6; buffer1, size_t
1659 buffer1_length, __u8&#x22C6; buffer2, size_t
1660 buffer2_length, dmx_section_filter_t&#x22C6; source,
1661 dmx_success_t success);</para>
1662</entry>
1663 </row></tbody></tgroup></informaltable>
1664<para>PARAMETERS
1665</para>
1666<informaltable><tgroup cols="2"><tbody><row><entry
1667 align="char">
1668<para>__u8* buffer1</para>
1669</entry><entry
1670 align="char">
1671<para>Pointer to the start of the filtered section, e.g. within the
1672 circular buffer of the demux driver.</para>
1673</entry>
1674 </row><row><entry
1675 align="char">
1676<para>size_t buffer1_length</para>
1677</entry><entry
1678 align="char">
1679<para>Length of the filtered section data in buffer1, including
1680 headers and CRC.</para>
1681</entry>
1682 </row><row><entry
1683 align="char">
1684<para>__u8* buffer2</para>
1685</entry><entry
1686 align="char">
1687<para>Pointer to the tail of the filtered section data, or NULL.
1688 Useful to handle the wrapping of a circular buffer.</para>
1689</entry>
1690 </row><row><entry
1691 align="char">
1692<para>size_t buffer2_length</para>
1693</entry><entry
1694 align="char">
1695<para>Length of the filtered section data in buffer2, including
1696 headers and CRC.</para>
1697</entry>
1698 </row><row><entry
1699 align="char">
1700<para>dmx_section_filter_t*
1701 filter</para>
1702</entry><entry
1703 align="char">
1704<para>Indicates the filter that triggered the callback.</para>
1705</entry>
1706 </row><row><entry
1707 align="char">
1708<para>dmx_success_t
1709 success</para>
1710</entry><entry
1711 align="char">
1712<para>Indicates if there was an error in section reception.</para>
1713</entry>
1714 </row></tbody></tgroup></informaltable>
1715<para>RETURNS
1716</para>
1717<informaltable><tgroup cols="2"><tbody><row><entry
1718 align="char">
1719<para>0</para>
1720</entry><entry
1721 align="char">
1722<para>Continue filtering.</para>
1723</entry>
1724 </row><row><entry
1725 align="char">
1726<para>-1</para>
1727</entry><entry
1728 align="char">
1729<para>Stop filtering - has the same effect as a call to
1730 stop_filtering() on the Section Feed API.</para>
1731</entry>
1732 </row></tbody></tgroup></informaltable>
1733 </section></section>
1734<section id="ts_feed_api">
1735<title>TS Feed API</title>
1736<para>A TS feed is typically mapped to a hardware PID filter on the demux chip.
1737Using this API, the client can set the filtering properties to start/stop filtering TS
1738packets on a particular TS feed. The API is defined as an abstract interface of the type
1739dmx_ts_feed_t.
1740</para>
1741<para>The functions that implement the interface should be defined static or module private. The
1742client can get the handle of a TS feed API by calling the function allocate_ts_feed() in the
1743demux API.
1744</para>
1745
1746<section
1747role="subsection"><title>set()</title>
1748<para>DESCRIPTION
1749</para>
1750<informaltable><tgroup cols="1"><tbody><row><entry
1751 align="char">
1752<para>This function sets the parameters of a TS feed. Any filtering in progress on the
1753 TS feed must be stopped before calling this function.</para>
1754</entry>
1755 </row></tbody></tgroup></informaltable>
1756<para>SYNOPSIS
1757</para>
1758<informaltable><tgroup cols="1"><tbody><row><entry
1759 align="char">
1760<para>int set ( dmx_ts_feed_t&#x22C6; feed, __u16 pid, size_t
1761 callback_length, size_t circular_buffer_size, int
1762 descramble, struct timespec timeout);</para>
1763</entry>
1764 </row></tbody></tgroup></informaltable>
1765<para>PARAMETERS
1766</para>
1767<informaltable><tgroup cols="2"><tbody><row><entry
1768 align="char">
1769<para>dmx_ts_feed_t* feed</para>
1770</entry><entry
1771 align="char">
1772<para>Pointer to the TS feed API and instance data.</para>
1773</entry>
1774 </row><row><entry
1775 align="char">
1776<para>__u16 pid</para>
1777</entry><entry
1778 align="char">
1779<para>PID value to filter. Only the TS packets carrying the
1780 specified PID will be passed to the API client.</para>
1781</entry>
1782 </row><row><entry
1783 align="char">
1784<para>size_t
1785 callback_length</para>
1786</entry><entry
1787 align="char">
1788<para>Number of bytes to deliver with each call to the
1789 dmx_ts_cb() callback function. The value of this
1790 parameter should be a multiple of 188.</para>
1791</entry>
1792 </row><row><entry
1793 align="char">
1794<para>size_t
1795 circular_buffer_size</para>
1796</entry><entry
1797 align="char">
1798<para>Size of the circular buffer for the filtered TS packets.</para>
1799</entry>
1800 </row><row><entry
1801 align="char">
1802<para>int descramble</para>
1803</entry><entry
1804 align="char">
1805<para>If non-zero, descramble the filtered TS packets.</para>
1806</entry>
1807 </row><row><entry
1808 align="char">
1809<para>struct timespec
1810 timeout</para>
1811</entry><entry
1812 align="char">
1813<para>Maximum time to wait before delivering received TS
1814 packets to the client.</para>
1815</entry>
1816 </row></tbody></tgroup></informaltable>
1817<para>RETURNS
1818</para>
1819<informaltable><tgroup cols="2"><tbody><row><entry
1820 align="char">
1821<para>0</para>
1822</entry><entry
1823 align="char">
1824<para>The function was completed without errors.</para>
1825</entry>
1826 </row><row><entry
1827 align="char">
1828<para>-ENOMEM</para>
1829</entry><entry
1830 align="char">
1831<para>Not enough memory for the requested buffer size.</para>
1832</entry>
1833 </row><row><entry
1834 align="char">
1835<para>-ENOSYS</para>
1836</entry><entry
1837 align="char">
1838<para>No descrambling facility available for TS.</para>
1839</entry>
1840 </row><row><entry
1841 align="char">
1842<para>-EINVAL</para>
1843</entry><entry
1844 align="char">
1845<para>Bad parameter.</para>
1846</entry>
1847 </row></tbody></tgroup></informaltable>
1848
1849</section><section
1850role="subsection"><title>start_filtering()</title>
1851<para>DESCRIPTION
1852</para>
1853<informaltable><tgroup cols="1"><tbody><row><entry
1854 align="char">
1855<para>Starts filtering TS packets on this TS feed, according to its settings. The PID
1856 value to filter can be set by the API client. All matching TS packets are
1857 delivered asynchronously to the client, using the callback function registered
1858 with allocate_ts_feed().</para>
1859</entry>
1860 </row></tbody></tgroup></informaltable>
1861<para>SYNOPSIS
1862</para>
1863<informaltable><tgroup cols="1"><tbody><row><entry
1864 align="char">
1865<para>int start_filtering(dmx_ts_feed_t&#x22C6; feed);</para>
1866</entry>
1867 </row></tbody></tgroup></informaltable>
1868<para>PARAMETERS
1869</para>
1870<informaltable><tgroup cols="2"><tbody><row><entry
1871 align="char">
1872<para>dmx_ts_feed_t* feed</para>
1873</entry><entry
1874 align="char">
1875<para>Pointer to the TS feed API and instance data.</para>
1876</entry>
1877 </row></tbody></tgroup></informaltable>
1878<para>RETURNS
1879</para>
1880<informaltable><tgroup cols="2"><tbody><row><entry
1881 align="char">
1882<para>0</para>
1883</entry><entry
1884 align="char">
1885<para>The function was completed without errors.</para>
1886</entry>
1887 </row><row><entry
1888 align="char">
1889<para>-EINVAL</para>
1890</entry><entry
1891 align="char">
1892<para>Bad parameter.</para>
1893</entry>
1894 </row></tbody></tgroup></informaltable>
1895
1896</section><section
1897role="subsection"><title>stop_filtering()</title>
1898<para>DESCRIPTION
1899</para>
1900<informaltable><tgroup cols="1"><tbody><row><entry
1901 align="char">
1902<para>Stops filtering TS packets on this TS feed.</para>
1903</entry>
1904 </row></tbody></tgroup></informaltable>
1905<para>SYNOPSIS
1906</para>
1907<informaltable><tgroup cols="1"><tbody><row><entry
1908 align="char">
1909<para>int stop_filtering(dmx_ts_feed_t&#x22C6; feed);</para>
1910</entry>
1911 </row></tbody></tgroup></informaltable>
1912<para>PARAMETERS
1913</para>
1914<informaltable><tgroup cols="2"><tbody><row><entry
1915 align="char">
1916<para>dmx_ts_feed_t* feed</para>
1917</entry><entry
1918 align="char">
1919<para>Pointer to the TS feed API and instance data.</para>
1920</entry>
1921 </row></tbody></tgroup></informaltable>
1922<para>RETURNS
1923</para>
1924<informaltable><tgroup cols="2"><tbody><row><entry
1925 align="char">
1926<para>0</para>
1927</entry><entry
1928 align="char">
1929<para>The function was completed without errors.</para>
1930</entry>
1931 </row><row><entry
1932 align="char">
1933<para>-EINVAL</para>
1934</entry><entry
1935 align="char">
1936<para>Bad parameter.</para>
1937</entry>
1938 </row></tbody></tgroup></informaltable>
1939 </section></section>
1940<section id="section_feed_api">
1941<title>Section Feed API</title>
1942<para>A section feed is a resource consisting of a PID filter and a set of section filters. Using this
1943API, the client can set the properties of a section feed and to start/stop filtering. The API is
1944defined as an abstract interface of the type dmx_section_feed_t. The functions that implement
1945the interface should be defined static or module private. The client can get the handle of
1946a section feed API by calling the function allocate_section_feed() in the demux
1947API.
1948</para>
1949<para>On demux platforms that provide section filtering in hardware, the Section Feed API
1950implementation provides a software wrapper for the demux hardware. Other platforms may
1951support only PID filtering in hardware, requiring that TS packets are converted to sections in
1952software. In the latter case the Section Feed API implementation can be a client of the TS
1953Feed API.
1954</para>
1955
1956</section>
1957<section id="kdapi_set">
1958<title>set()</title>
1959<para>DESCRIPTION
1960</para>
1961<informaltable><tgroup cols="1"><tbody><row><entry
1962 align="char">
1963<para>This function sets the parameters of a section feed. Any filtering in progress on
1964 the section feed must be stopped before calling this function. If descrambling
1965 is enabled, the payload_scrambling_control and address_scrambling_control
1966 fields of received DVB datagram sections should be observed. If either one is
1967 non-zero, the section should be descrambled either in hardware or using the
1968 functions descramble_mac_address() and descramble_section_payload() of the
1969 demux API. Note that according to the MPEG-2 Systems specification, only
1970 the payloads of private sections can be scrambled while the rest of the section
1971 data must be sent in the clear.</para>
1972</entry>
1973 </row></tbody></tgroup></informaltable>
1974<para>SYNOPSIS
1975</para>
1976<informaltable><tgroup cols="1"><tbody><row><entry
1977 align="char">
1978<para>int set(dmx_section_feed_t&#x22C6; feed, __u16 pid, size_t
1979 circular_buffer_size, int descramble, int
1980 check_crc);</para>
1981</entry>
1982 </row></tbody></tgroup></informaltable>
1983<para>PARAMETERS
1984</para>
1985<informaltable><tgroup cols="2"><tbody><row><entry
1986 align="char">
1987<para>dmx_section_feed_t*
1988 feed</para>
1989</entry><entry
1990 align="char">
1991<para>Pointer to the section feed API and instance data.</para>
1992</entry>
1993 </row><row><entry
1994 align="char">
1995<para>__u16 pid</para>
1996</entry><entry
1997 align="char">
1998<para>PID value to filter; only the TS packets carrying the
1999 specified PID will be accepted.</para>
2000</entry>
2001 </row><row><entry
2002 align="char">
2003<para>size_t
2004 circular_buffer_size</para>
2005</entry><entry
2006 align="char">
2007<para>Size of the circular buffer for filtered sections.</para>
2008</entry>
2009 </row><row><entry
2010 align="char">
2011<para>int descramble</para>
2012</entry><entry
2013 align="char">
2014<para>If non-zero, descramble any sections that are scrambled.</para>
2015</entry>
2016 </row><row><entry
2017 align="char">
2018<para>int check_crc</para>
2019</entry><entry
2020 align="char">
2021<para>If non-zero, check the CRC values of filtered sections.</para>
2022</entry>
2023 </row></tbody></tgroup></informaltable>
2024<para>RETURNS
2025</para>
2026<informaltable><tgroup cols="2"><tbody><row><entry
2027 align="char">
2028<para>0</para>
2029</entry><entry
2030 align="char">
2031<para>The function was completed without errors.</para>
2032</entry>
2033 </row><row><entry
2034 align="char">
2035<para>-ENOMEM</para>
2036</entry><entry
2037 align="char">
2038<para>Not enough memory for the requested buffer size.</para>
2039</entry>
2040 </row><row><entry
2041 align="char">
2042<para>-ENOSYS</para>
2043</entry><entry
2044 align="char">
2045<para>No descrambling facility available for sections.</para>
2046</entry>
2047 </row><row><entry
2048 align="char">
2049<para>-EINVAL</para>
2050</entry><entry
2051 align="char">
2052<para>Bad parameters.</para>
2053</entry>
2054 </row></tbody></tgroup></informaltable>
2055
2056</section><section
2057role="subsection"><title>allocate_filter()</title>
2058<para>DESCRIPTION
2059</para>
2060<informaltable><tgroup cols="1"><tbody><row><entry
2061 align="char">
2062<para>This function is used to allocate a section filter on the demux. It should only be
2063 called when no filtering is in progress on this section feed. If a filter cannot be
2064 allocated, the function fails with -ENOSPC. See in section ?? for the format of
2065 the section filter.</para>
2066</entry>
2067 </row><row><entry
2068 align="char">
2069<para>The bitfields filter_mask and filter_value should only be modified when no
2070 filtering is in progress on this section feed. filter_mask controls which bits of
2071 filter_value are compared with the section headers/payload. On a binary value
2072 of 1 in filter_mask, the corresponding bits are compared. The filter only accepts
2073 sections that are equal to filter_value in all the tested bit positions. Any changes
2074 to the values of filter_mask and filter_value are guaranteed to take effect only
2075 when the start_filtering() function is called next time. The parent pointer in
2076 the struct is initialized by the API implementation to the value of the feed
2077 parameter. The priv pointer is not used by the API implementation, and can
2078 thus be freely utilized by the caller of this function. Any data pointed to by the
2079 priv pointer is available to the recipient of the dmx_section_cb() function call.</para>
2080</entry>
2081 </row><row><entry
2082 align="char">
2083<para>While the maximum section filter length (DMX_MAX_FILTER_SIZE) is
2084 currently set at 16 bytes, hardware filters of that size are not available on all
2085 platforms. Therefore, section filtering will often take place first in hardware,
2086 followed by filtering in software for the header bytes that were not covered
2087 by a hardware filter. The filter_mask field can be checked to determine how
2088 many bytes of the section filter are actually used, and if the hardware filter will
2089 suffice. Additionally, software-only section filters can optionally be allocated
2090 to clients when all hardware section filters are in use. Note that on most demux
2091 hardware it is not possible to filter on the section_length field of the section
2092 header &#8211; thus this field is ignored, even though it is included in filter_value and
2093 filter_mask fields.</para>
2094</entry>
2095 </row></tbody></tgroup></informaltable>
2096<para>SYNOPSIS
2097</para>
2098<informaltable><tgroup cols="1"><tbody><row><entry
2099 align="char">
2100<para>int allocate_filter(dmx_section_feed_t&#x22C6; feed,
2101 dmx_section_filter_t&#x22C6;&#x22C6; filter);</para>
2102</entry>
2103 </row></tbody></tgroup></informaltable>
2104<para>PARAMETERS
2105</para>
2106<informaltable><tgroup cols="2"><tbody><row><entry
2107 align="char">
2108<para>dmx_section_feed_t*
2109 feed</para>
2110</entry><entry
2111 align="char">
2112<para>Pointer to the section feed API and instance data.</para>
2113</entry>
2114 </row><row><entry
2115 align="char">
2116<para>dmx_section_filter_t**
2117 filter</para>
2118</entry><entry
2119 align="char">
2120<para>Pointer to the allocated filter.</para>
2121</entry>
2122 </row></tbody></tgroup></informaltable>
2123<para>RETURNS
2124</para>
2125<informaltable><tgroup cols="2"><tbody><row><entry
2126 align="char">
2127<para>0</para>
2128</entry><entry
2129 align="char">
2130<para>The function was completed without errors.</para>
2131</entry>
2132 </row><row><entry
2133 align="char">
2134<para>-ENOSPC</para>
2135</entry><entry
2136 align="char">
2137<para>No filters of given type and length available.</para>
2138</entry>
2139 </row><row><entry
2140 align="char">
2141<para>-EINVAL</para>
2142</entry><entry
2143 align="char">
2144<para>Bad parameters.</para>
2145</entry>
2146 </row></tbody></tgroup></informaltable>
2147
2148</section><section
2149role="subsection"><title>release_filter()</title>
2150<para>DESCRIPTION
2151</para>
2152<informaltable><tgroup cols="1"><tbody><row><entry
2153 align="char">
2154<para>This function releases all the resources of a previously allocated section filter.
2155 The function should not be called while filtering is in progress on this section
2156 feed. After calling this function, the caller should not try to dereference the
2157 filter pointer.</para>
2158</entry>
2159 </row></tbody></tgroup></informaltable>
2160<para>SYNOPSIS
2161</para>
2162<informaltable><tgroup cols="1"><tbody><row><entry
2163 align="char">
2164<para>int release_filter ( dmx_section_feed_t&#x22C6; feed,
2165 dmx_section_filter_t&#x22C6; filter);</para>
2166</entry>
2167 </row></tbody></tgroup></informaltable>
2168<para>PARAMETERS
2169</para>
2170<informaltable><tgroup cols="2"><tbody><row><entry
2171 align="char">
2172<para>dmx_section_feed_t*
2173 feed</para>
2174</entry><entry
2175 align="char">
2176<para>Pointer to the section feed API and instance data.</para>
2177</entry>
2178 </row><row><entry
2179 align="char">
2180<para>dmx_section_filter_t*
2181 filter</para>
2182</entry><entry
2183 align="char">
2184<para>I/O Pointer to the instance data of a section filter.</para>
2185</entry>
2186 </row></tbody></tgroup></informaltable>
2187<para>RETURNS
2188</para>
2189<informaltable><tgroup cols="2"><tbody><row><entry
2190 align="char">
2191<para>0</para>
2192</entry><entry
2193 align="char">
2194<para>The function was completed without errors.</para>
2195</entry>
2196 </row><row><entry
2197 align="char">
2198<para>-ENODEV</para>
2199</entry><entry
2200 align="char">
2201<para>No such filter allocated.</para>
2202</entry>
2203 </row><row><entry
2204 align="char">
2205<para>-EINVAL</para>
2206</entry><entry
2207 align="char">
2208<para>Bad parameter.</para>
2209</entry>
2210 </row></tbody></tgroup></informaltable>
2211
2212</section><section
2213role="subsection"><title>start_filtering()</title>
2214<para>DESCRIPTION
2215</para>
2216<informaltable><tgroup cols="1"><tbody><row><entry
2217 align="char">
2218<para>Starts filtering sections on this section feed, according to its settings. Sections
2219 are first filtered based on their PID and then matched with the section
2220 filters allocated for this feed. If the section matches the PID filter and
2221 at least one section filter, it is delivered to the API client. The section
2222 is delivered asynchronously using the callback function registered with
2223 allocate_section_feed().</para>
2224</entry>
2225 </row></tbody></tgroup></informaltable>
2226<para>SYNOPSIS
2227</para>
2228<informaltable><tgroup cols="1"><tbody><row><entry
2229 align="char">
2230<para>int start_filtering ( dmx_section_feed_t&#x22C6; feed );</para>
2231</entry>
2232 </row></tbody></tgroup></informaltable>
2233<para>PARAMETERS
2234</para>
2235<informaltable><tgroup cols="2"><tbody><row><entry
2236 align="char">
2237<para>dmx_section_feed_t*
2238 feed</para>
2239</entry><entry
2240 align="char">
2241<para>Pointer to the section feed API and instance data.</para>
2242</entry>
2243 </row></tbody></tgroup></informaltable>
2244<para>RETURNS
2245</para>
2246<informaltable><tgroup cols="2"><tbody><row><entry
2247 align="char">
2248<para>0</para>
2249</entry><entry
2250 align="char">
2251<para>The function was completed without errors.</para>
2252</entry>
2253 </row><row><entry
2254 align="char">
2255<para>-EINVAL</para>
2256</entry><entry
2257 align="char">
2258<para>Bad parameter.</para>
2259</entry>
2260 </row></tbody></tgroup></informaltable>
2261
2262</section><section
2263role="subsection"><title>stop_filtering()</title>
2264<para>DESCRIPTION
2265</para>
2266<informaltable><tgroup cols="1"><tbody><row><entry
2267 align="char">
2268<para>Stops filtering sections on this section feed. Note that any changes to the
2269 filtering parameters (filter_value, filter_mask, etc.) should only be made when
2270 filtering is stopped.</para>
2271</entry>
2272 </row></tbody></tgroup></informaltable>
2273<para>SYNOPSIS
2274</para>
2275<informaltable><tgroup cols="1"><tbody><row><entry
2276 align="char">
2277<para>int stop_filtering ( dmx_section_feed_t&#x22C6; feed );</para>
2278</entry>
2279 </row></tbody></tgroup></informaltable>
2280<para>PARAMETERS
2281</para>
2282<informaltable><tgroup cols="2"><tbody><row><entry
2283 align="char">
2284<para>dmx_section_feed_t*
2285 feed</para>
2286</entry><entry
2287 align="char">
2288<para>Pointer to the section feed API and instance data.</para>
2289</entry>
2290 </row></tbody></tgroup></informaltable>
2291<para>RETURNS
2292</para>
2293<informaltable><tgroup cols="2"><tbody><row><entry
2294 align="char">
2295<para>0</para>
2296</entry><entry
2297 align="char">
2298<para>The function was completed without errors.</para>
2299</entry>
2300 </row><row><entry
2301 align="char">
2302<para>-EINVAL</para>
2303</entry><entry
2304 align="char">
2305<para>Bad parameter.</para>
2306</entry>
2307 </row></tbody></tgroup></informaltable>
2308
2309</section>
diff --git a/Documentation/DocBook/dvb/net.xml b/Documentation/DocBook/dvb/net.xml
new file mode 100644
index 000000000000..94e388d94c0d
--- /dev/null
+++ b/Documentation/DocBook/dvb/net.xml
@@ -0,0 +1,12 @@
1<title>DVB Network API</title>
2<para>The DVB net device enables feeding of MPE (multi protocol encapsulation) packets
3received via DVB into the Linux network protocol stack, e.g. for internet via satellite
4applications. It can be accessed through <emphasis role="tt">/dev/dvb/adapter0/net0</emphasis>. Data types and
5and ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/net.h</emphasis> in your
6application.
7</para>
8<section id="dvb_net_types">
9<title>DVB Net Data Types</title>
10<para>To be written&#x2026;
11</para>
12</section>
diff --git a/Documentation/DocBook/dvb/video.xml b/Documentation/DocBook/dvb/video.xml
new file mode 100644
index 000000000000..7bb287e67c8e
--- /dev/null
+++ b/Documentation/DocBook/dvb/video.xml
@@ -0,0 +1,1971 @@
1<title>DVB Video Device</title>
2<para>The DVB video device controls the MPEG2 video decoder of the DVB hardware. It
3can be accessed through <emphasis role="tt">/dev/dvb/adapter0/video0</emphasis>. Data types and and
4ioctl definitions can be accessed by including <emphasis role="tt">linux/dvb/video.h</emphasis> in your
5application.
6</para>
7<para>Note that the DVB video device only controls decoding of the MPEG video stream, not
8its presentation on the TV or computer screen. On PCs this is typically handled by an
9associated video4linux device, e.g. <emphasis role="tt">/dev/video</emphasis>, which allows scaling and defining output
10windows.
11</para>
12<para>Some DVB cards don&#8217;t have their own MPEG decoder, which results in the omission of
13the audio and video device as well as the video4linux device.
14</para>
15<para>The ioctls that deal with SPUs (sub picture units) and navigation packets are only
16supported on some MPEG decoders made for DVD playback.
17</para>
18<section id="video_types">
19<title>Video Data Types</title>
20
21<section id="video_format_t">
22<title>video_format_t</title>
23<para>The <emphasis role="tt">video_format_t</emphasis> data type defined by
24</para>
25<programlisting>
26 typedef enum {
27 VIDEO_FORMAT_4_3,
28 VIDEO_FORMAT_16_9
29 } video_format_t;
30</programlisting>
31<para>is used in the VIDEO_SET_FORMAT function (??) to tell the driver which aspect ratio
32the output hardware (e.g. TV) has. It is also used in the data structures video_status
33(??) returned by VIDEO_GET_STATUS (??) and video_event (??) returned by
34VIDEO_GET_EVENT (??) which report about the display format of the current video
35stream.
36</para>
37</section>
38
39<section id="video_display_format_t">
40<title>video_display_format_t</title>
41<para>In case the display format of the video stream and of the display hardware differ the
42application has to specify how to handle the cropping of the picture. This can be done using
43the VIDEO_SET_DISPLAY_FORMAT call (??) which accepts
44</para>
45<programlisting>
46 typedef enum {
47 VIDEO_PAN_SCAN,
48 VIDEO_LETTER_BOX,
49 VIDEO_CENTER_CUT_OUT
50 } video_display_format_t;
51</programlisting>
52<para>as argument.
53</para>
54</section>
55
56<section id="video_stream_source">
57<title>video stream source</title>
58<para>The video stream source is set through the VIDEO_SELECT_SOURCE call and can take
59the following values, depending on whether we are replaying from an internal (demuxer) or
60external (user write) source.
61</para>
62<programlisting>
63 typedef enum {
64 VIDEO_SOURCE_DEMUX,
65 VIDEO_SOURCE_MEMORY
66 } video_stream_source_t;
67</programlisting>
68<para>VIDEO_SOURCE_DEMUX selects the demultiplexer (fed either by the frontend or the
69DVR device) as the source of the video stream. If VIDEO_SOURCE_MEMORY
70is selected the stream comes from the application through the <emphasis role="tt">write()</emphasis> system
71call.
72</para>
73</section>
74
75<section id="video_play_state">
76<title>video play state</title>
77<para>The following values can be returned by the VIDEO_GET_STATUS call representing the
78state of video playback.
79</para>
80<programlisting>
81 typedef enum {
82 VIDEO_STOPPED,
83 VIDEO_PLAYING,
84 VIDEO_FREEZED
85 } video_play_state_t;
86</programlisting>
87</section>
88
89<section id="video_event">
90<title>struct video_event</title>
91<para>The following is the structure of a video event as it is returned by the VIDEO_GET_EVENT
92call.
93</para>
94<programlisting>
95 struct video_event {
96 int32_t type;
97 time_t timestamp;
98 union {
99 video_format_t video_format;
100 } u;
101 };
102</programlisting>
103</section>
104
105<section id="video_status">
106<title>struct video_status</title>
107<para>The VIDEO_GET_STATUS call returns the following structure informing about various
108states of the playback operation.
109</para>
110<programlisting>
111 struct video_status {
112 boolean video_blank;
113 video_play_state_t play_state;
114 video_stream_source_t stream_source;
115 video_format_t video_format;
116 video_displayformat_t display_format;
117 };
118</programlisting>
119<para>If video_blank is set video will be blanked out if the channel is changed or if playback is
120stopped. Otherwise, the last picture will be displayed. play_state indicates if the video is
121currently frozen, stopped, or being played back. The stream_source corresponds to the seleted
122source for the video stream. It can come either from the demultiplexer or from memory.
123The video_format indicates the aspect ratio (one of 4:3 or 16:9) of the currently
124played video stream. Finally, display_format corresponds to the selected cropping
125mode in case the source video format is not the same as the format of the output
126device.
127</para>
128</section>
129
130<section id="video_still_picture">
131<title>struct video_still_picture</title>
132<para>An I-frame displayed via the VIDEO_STILLPICTURE call is passed on within the
133following structure.
134</para>
135<programlisting>
136 /&#x22C6; pointer to and size of a single iframe in memory &#x22C6;/
137 struct video_still_picture {
138 char &#x22C6;iFrame;
139 int32_t size;
140 };
141</programlisting>
142</section>
143
144<section id="video_caps">
145<title>video capabilities</title>
146<para>A call to VIDEO_GET_CAPABILITIES returns an unsigned integer with the following
147bits set according to the hardwares capabilities.
148</para>
149<programlisting>
150 /&#x22C6; bit definitions for capabilities: &#x22C6;/
151 /&#x22C6; can the hardware decode MPEG1 and/or MPEG2? &#x22C6;/
152 #define VIDEO_CAP_MPEG1 1
153 #define VIDEO_CAP_MPEG2 2
154 /&#x22C6; can you send a system and/or program stream to video device?
155 (you still have to open the video and the audio device but only
156 send the stream to the video device) &#x22C6;/
157 #define VIDEO_CAP_SYS 4
158 #define VIDEO_CAP_PROG 8
159 /&#x22C6; can the driver also handle SPU, NAVI and CSS encoded data?
160 (CSS API is not present yet) &#x22C6;/
161 #define VIDEO_CAP_SPU 16
162 #define VIDEO_CAP_NAVI 32
163 #define VIDEO_CAP_CSS 64
164</programlisting>
165</section>
166
167<section id="video_system">
168<title>video system</title>
169<para>A call to VIDEO_SET_SYSTEM sets the desired video system for TV output. The
170following system types can be set:
171</para>
172<programlisting>
173 typedef enum {
174 VIDEO_SYSTEM_PAL,
175 VIDEO_SYSTEM_NTSC,
176 VIDEO_SYSTEM_PALN,
177 VIDEO_SYSTEM_PALNc,
178 VIDEO_SYSTEM_PALM,
179 VIDEO_SYSTEM_NTSC60,
180 VIDEO_SYSTEM_PAL60,
181 VIDEO_SYSTEM_PALM60
182 } video_system_t;
183</programlisting>
184</section>
185
186<section id="video_highlight">
187<title>struct video_highlight</title>
188<para>Calling the ioctl VIDEO_SET_HIGHLIGHTS posts the SPU highlight information. The
189call expects the following format for that information:
190</para>
191<programlisting>
192 typedef
193 struct video_highlight {
194 boolean active; /&#x22C6; 1=show highlight, 0=hide highlight &#x22C6;/
195 uint8_t contrast1; /&#x22C6; 7- 4 Pattern pixel contrast &#x22C6;/
196 /&#x22C6; 3- 0 Background pixel contrast &#x22C6;/
197 uint8_t contrast2; /&#x22C6; 7- 4 Emphasis pixel-2 contrast &#x22C6;/
198 /&#x22C6; 3- 0 Emphasis pixel-1 contrast &#x22C6;/
199 uint8_t color1; /&#x22C6; 7- 4 Pattern pixel color &#x22C6;/
200 /&#x22C6; 3- 0 Background pixel color &#x22C6;/
201 uint8_t color2; /&#x22C6; 7- 4 Emphasis pixel-2 color &#x22C6;/
202 /&#x22C6; 3- 0 Emphasis pixel-1 color &#x22C6;/
203 uint32_t ypos; /&#x22C6; 23-22 auto action mode &#x22C6;/
204 /&#x22C6; 21-12 start y &#x22C6;/
205 /&#x22C6; 9- 0 end y &#x22C6;/
206 uint32_t xpos; /&#x22C6; 23-22 button color number &#x22C6;/
207 /&#x22C6; 21-12 start x &#x22C6;/
208 /&#x22C6; 9- 0 end x &#x22C6;/
209 } video_highlight_t;
210</programlisting>
211
212</section>
213<section id="video_spu">
214<title>video SPU</title>
215<para>Calling VIDEO_SET_SPU deactivates or activates SPU decoding, according to the
216following format:
217</para>
218<programlisting>
219 typedef
220 struct video_spu {
221 boolean active;
222 int stream_id;
223 } video_spu_t;
224</programlisting>
225
226</section>
227<section id="video_spu_palette">
228<title>video SPU palette</title>
229<para>The following structure is used to set the SPU palette by calling VIDEO_SPU_PALETTE:
230</para>
231<programlisting>
232 typedef
233 struct video_spu_palette{
234 int length;
235 uint8_t &#x22C6;palette;
236 } video_spu_palette_t;
237</programlisting>
238
239</section>
240<section id="video_navi_pack">
241<title>video NAVI pack</title>
242<para>In order to get the navigational data the following structure has to be passed to the ioctl
243VIDEO_GET_NAVI:
244</para>
245<programlisting>
246 typedef
247 struct video_navi_pack{
248 int length; /&#x22C6; 0 ... 1024 &#x22C6;/
249 uint8_t data[1024];
250 } video_navi_pack_t;
251</programlisting>
252</section>
253
254
255<section id="video_attributes">
256<title>video attributes</title>
257<para>The following attributes can be set by a call to VIDEO_SET_ATTRIBUTES:
258</para>
259<programlisting>
260 typedef uint16_t video_attributes_t;
261 /&#x22C6; bits: descr. &#x22C6;/
262 /&#x22C6; 15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) &#x22C6;/
263 /&#x22C6; 13-12 TV system (0=525/60, 1=625/50) &#x22C6;/
264 /&#x22C6; 11-10 Aspect ratio (0=4:3, 3=16:9) &#x22C6;/
265 /&#x22C6; 9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca &#x22C6;/
266 /&#x22C6; 7 line 21-1 data present in GOP (1=yes, 0=no) &#x22C6;/
267 /&#x22C6; 6 line 21-2 data present in GOP (1=yes, 0=no) &#x22C6;/
268 /&#x22C6; 5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 &#x22C6;/
269 /&#x22C6; 2 source letterboxed (1=yes, 0=no) &#x22C6;/
270 /&#x22C6; 0 film/camera mode (0=camera, 1=film (625/50 only)) &#x22C6;/
271</programlisting>
272</section></section>
273
274
275<section id="video_function_calls">
276<title>Video Function Calls</title>
277
278
279<section id="video_fopen">
280<title>open()</title>
281<para>DESCRIPTION
282</para>
283<informaltable><tgroup cols="1"><tbody><row><entry
284 align="char">
285<para>This system call opens a named video device (e.g. /dev/dvb/adapter0/video0)
286 for subsequent use.</para>
287<para>When an open() call has succeeded, the device will be ready for use.
288 The significance of blocking or non-blocking mode is described in the
289 documentation for functions where there is a difference. It does not affect the
290 semantics of the open() call itself. A device opened in blocking mode can later
291 be put into non-blocking mode (and vice versa) using the F_SETFL command
292 of the fcntl system call. This is a standard system call, documented in the Linux
293 manual page for fcntl. Only one user can open the Video Device in O_RDWR
294 mode. All other attempts to open the device in this mode will fail, and an
295 error-code will be returned. If the Video Device is opened in O_RDONLY
296 mode, the only ioctl call that can be used is VIDEO_GET_STATUS. All other
297 call will return an error code.</para>
298</entry>
299 </row></tbody></tgroup></informaltable>
300
301<para>SYNOPSIS
302</para>
303<informaltable><tgroup cols="1"><tbody><row><entry
304 align="char">
305<para>int open(const char &#x22C6;deviceName, int flags);</para>
306</entry>
307 </row></tbody></tgroup></informaltable>
308<para>PARAMETERS
309</para>
310<informaltable><tgroup cols="2"><tbody><row><entry
311 align="char">
312<para>const char
313 *deviceName</para>
314</entry><entry
315 align="char">
316<para>Name of specific video device.</para>
317</entry>
318 </row><row><entry
319 align="char">
320<para>int flags</para>
321</entry><entry
322 align="char">
323<para>A bit-wise OR of the following flags:</para>
324</entry>
325 </row><row><entry
326 align="char">
327</entry><entry
328 align="char">
329<para>O_RDONLY read-only access</para>
330</entry>
331 </row><row><entry
332 align="char">
333</entry><entry
334 align="char">
335<para>O_RDWR read/write access</para>
336</entry>
337 </row><row><entry
338 align="char">
339</entry><entry
340 align="char">
341<para>O_NONBLOCK open in non-blocking mode</para>
342</entry>
343 </row><row><entry
344 align="char">
345</entry><entry
346 align="char">
347<para>(blocking mode is the default)</para>
348</entry>
349 </row></tbody></tgroup></informaltable>
350<para>ERRORS
351</para>
352<informaltable><tgroup cols="2"><tbody><row><entry
353 align="char">
354<para>ENODEV</para>
355</entry><entry
356 align="char">
357<para>Device driver not loaded/available.</para>
358</entry>
359 </row><row><entry
360 align="char">
361<para>EINTERNAL</para>
362</entry><entry
363 align="char">
364<para>Internal error.</para>
365</entry>
366 </row><row><entry
367 align="char">
368<para>EBUSY</para>
369</entry><entry
370 align="char">
371<para>Device or resource busy.</para>
372</entry>
373 </row><row><entry
374 align="char">
375<para>EINVAL</para>
376</entry><entry
377 align="char">
378<para>Invalid argument.</para>
379</entry>
380 </row></tbody></tgroup></informaltable>
381
382</section>
383<section id="video_fclose">
384<title>close()</title>
385<para>DESCRIPTION
386</para>
387<informaltable><tgroup cols="1"><tbody><row><entry
388 align="char">
389<para>This system call closes a previously opened video device.</para>
390</entry>
391 </row></tbody></tgroup></informaltable>
392<para>SYNOPSIS
393</para>
394<informaltable><tgroup cols="1"><tbody><row><entry
395 align="char">
396<para>int close(int fd);</para>
397</entry>
398 </row></tbody></tgroup></informaltable>
399<para>PARAMETERS
400</para>
401<informaltable><tgroup cols="2"><tbody><row><entry
402 align="char">
403<para>int fd</para>
404</entry><entry
405 align="char">
406<para>File descriptor returned by a previous call to open().</para>
407</entry>
408 </row></tbody></tgroup></informaltable>
409<para>ERRORS
410</para>
411<informaltable><tgroup cols="2"><tbody><row><entry
412 align="char">
413<para>EBADF</para>
414</entry><entry
415 align="char">
416<para>fd is not a valid open file descriptor.</para>
417</entry>
418 </row></tbody></tgroup></informaltable>
419
420</section>
421<section id="video_fwrite">
422<title>write()</title>
423<para>DESCRIPTION
424</para>
425<informaltable><tgroup cols="1"><tbody><row><entry
426 align="char">
427<para>This system call can only be used if VIDEO_SOURCE_MEMORY is selected
428 in the ioctl call VIDEO_SELECT_SOURCE. The data provided shall be in
429 PES format, unless the capability allows other formats. If O_NONBLOCK is
430 not specified the function will block until buffer space is available. The amount
431 of data to be transferred is implied by count.</para>
432</entry>
433 </row></tbody></tgroup></informaltable>
434<para>SYNOPSIS
435</para>
436<informaltable><tgroup cols="1"><tbody><row><entry
437 align="char">
438<para>size_t write(int fd, const void &#x22C6;buf, size_t count);</para>
439</entry>
440 </row></tbody></tgroup></informaltable>
441<para>PARAMETERS
442</para>
443<informaltable><tgroup cols="2"><tbody><row><entry
444 align="char">
445<para>int fd</para>
446</entry><entry
447 align="char">
448<para>File descriptor returned by a previous call to open().</para>
449</entry>
450 </row><row><entry
451 align="char">
452<para>void *buf</para>
453</entry><entry
454 align="char">
455<para>Pointer to the buffer containing the PES data.</para>
456</entry>
457 </row><row><entry
458 align="char">
459<para>size_t count</para>
460</entry><entry
461 align="char">
462<para>Size of buf.</para>
463</entry>
464 </row></tbody></tgroup></informaltable>
465<para>ERRORS
466</para>
467<informaltable><tgroup cols="2"><tbody><row><entry
468 align="char">
469<para>EPERM</para>
470</entry><entry
471 align="char">
472<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
473</entry>
474 </row><row><entry
475 align="char">
476<para>ENOMEM</para>
477</entry><entry
478 align="char">
479<para>Attempted to write more data than the internal buffer can
480 hold.</para>
481</entry>
482 </row><row><entry
483 align="char">
484<para>EBADF</para>
485</entry><entry
486 align="char">
487<para>fd is not a valid open file descriptor.</para>
488</entry>
489 </row></tbody></tgroup></informaltable>
490
491</section><section
492role="subsection"><title>VIDEO_STOP</title>
493<para>DESCRIPTION
494</para>
495<informaltable><tgroup cols="1"><tbody><row><entry
496 align="char">
497<para>This ioctl call asks the Video Device to stop playing the current stream.
498 Depending on the input parameter, the screen can be blanked out or displaying
499 the last decoded frame.</para>
500</entry>
501 </row></tbody></tgroup></informaltable>
502<para>SYNOPSIS
503</para>
504<informaltable><tgroup cols="1"><tbody><row><entry
505 align="char">
506<para>int ioctl(fd, int request = VIDEO_STOP, boolean
507 mode);</para>
508</entry>
509 </row></tbody></tgroup></informaltable>
510<para>PARAMETERS
511</para>
512<informaltable><tgroup cols="2"><tbody><row><entry
513 align="char">
514<para>int fd</para>
515</entry><entry
516 align="char">
517<para>File descriptor returned by a previous call to open().</para>
518</entry>
519 </row><row><entry
520 align="char">
521<para>int request</para>
522</entry><entry
523 align="char">
524<para>Equals VIDEO_STOP for this command.</para>
525</entry>
526 </row><row><entry
527 align="char">
528<para>Boolean mode</para>
529</entry><entry
530 align="char">
531<para>Indicates how the screen shall be handled.</para>
532</entry>
533 </row><row><entry
534 align="char">
535</entry><entry
536 align="char">
537<para>TRUE: Blank screen when stop.</para>
538</entry>
539 </row><row><entry
540 align="char">
541</entry><entry
542 align="char">
543<para>FALSE: Show last decoded frame.</para>
544</entry>
545 </row></tbody></tgroup></informaltable>
546<para>ERRORS
547</para>
548<informaltable><tgroup cols="2"><tbody><row><entry
549 align="char">
550<para>EBADF</para>
551</entry><entry
552 align="char">
553<para>fd is not a valid open file descriptor</para>
554</entry>
555 </row><row><entry
556 align="char">
557<para>EINTERNAL</para>
558</entry><entry
559 align="char">
560<para>Internal error, possibly in the communication with the
561 DVB subsystem.</para>
562</entry>
563 </row></tbody></tgroup></informaltable>
564
565</section><section
566role="subsection"><title>VIDEO_PLAY</title>
567<para>DESCRIPTION
568</para>
569<informaltable><tgroup cols="1"><tbody><row><entry
570 align="char">
571<para>This ioctl call asks the Video Device to start playing a video stream from the
572 selected source.</para>
573</entry>
574 </row></tbody></tgroup></informaltable>
575<para>SYNOPSIS
576</para>
577<informaltable><tgroup cols="1"><tbody><row><entry
578 align="char">
579<para>int ioctl(fd, int request = VIDEO_PLAY);</para>
580</entry>
581 </row></tbody></tgroup></informaltable>
582<para>PARAMETERS
583</para>
584<informaltable><tgroup cols="2"><tbody><row><entry
585 align="char">
586<para>int fd</para>
587</entry><entry
588 align="char">
589<para>File descriptor returned by a previous call to open().</para>
590</entry>
591 </row><row><entry
592 align="char">
593<para>int request</para>
594</entry><entry
595 align="char">
596<para>Equals VIDEO_PLAY for this command.</para>
597</entry>
598 </row></tbody></tgroup></informaltable>
599<para>ERRORS
600</para>
601<informaltable><tgroup cols="2"><tbody><row><entry
602 align="char">
603<para>EBADF</para>
604</entry><entry
605 align="char">
606<para>fd is not a valid open file descriptor</para>
607</entry>
608 </row><row><entry
609 align="char">
610<para>EINTERNAL</para>
611</entry><entry
612 align="char">
613<para>Internal error, possibly in the communication with the
614 DVB subsystem.</para>
615</entry>
616 </row></tbody></tgroup></informaltable>
617
618</section><section
619role="subsection"><title>VIDEO_FREEZE</title>
620<para>DESCRIPTION
621</para>
622<informaltable><tgroup cols="1"><tbody><row><entry
623 align="char">
624<para>This ioctl call suspends the live video stream being played. Decoding
625 and playing are frozen. It is then possible to restart the decoding
626 and playing process of the video stream using the VIDEO_CONTINUE
627 command. If VIDEO_SOURCE_MEMORY is selected in the ioctl call
628 VIDEO_SELECT_SOURCE, the DVB subsystem will not decode any more
629 data until the ioctl call VIDEO_CONTINUE or VIDEO_PLAY is performed.</para>
630</entry>
631 </row></tbody></tgroup></informaltable>
632<para>SYNOPSIS
633</para>
634<informaltable><tgroup cols="1"><tbody><row><entry
635 align="char">
636<para>int ioctl(fd, int request = VIDEO_FREEZE);</para>
637</entry>
638 </row></tbody></tgroup></informaltable>
639<para>PARAMETERS
640</para>
641<informaltable><tgroup cols="2"><tbody><row><entry
642 align="char">
643<para>int fd</para>
644</entry><entry
645 align="char">
646<para>File descriptor returned by a previous call to open().</para>
647</entry>
648 </row><row><entry
649 align="char">
650<para>int request</para>
651</entry><entry
652 align="char">
653<para>Equals VIDEO_FREEZE for this command.</para>
654</entry>
655 </row></tbody></tgroup></informaltable>
656<para>ERRORS
657</para>
658<informaltable><tgroup cols="2"><tbody><row><entry
659 align="char">
660<para>EBADF</para>
661</entry><entry
662 align="char">
663<para>fd is not a valid open file descriptor</para>
664</entry>
665 </row><row><entry
666 align="char">
667<para>EINTERNAL</para>
668</entry><entry
669 align="char">
670<para>Internal error, possibly in the communication with the
671 DVB subsystem.</para>
672</entry>
673 </row></tbody></tgroup></informaltable>
674
675</section><section
676role="subsection"><title>VIDEO_CONTINUE</title>
677<para>DESCRIPTION
678</para>
679<informaltable><tgroup cols="1"><tbody><row><entry
680 align="char">
681<para>This ioctl call restarts decoding and playing processes of the video stream
682 which was played before a call to VIDEO_FREEZE was made.</para>
683</entry>
684 </row></tbody></tgroup></informaltable>
685<para>SYNOPSIS
686</para>
687<informaltable><tgroup cols="1"><tbody><row><entry
688 align="char">
689<para>int ioctl(fd, int request = VIDEO_CONTINUE);</para>
690</entry>
691 </row></tbody></tgroup></informaltable>
692<para>PARAMETERS
693</para>
694<informaltable><tgroup cols="2"><tbody><row><entry
695 align="char">
696<para>int fd</para>
697</entry><entry
698 align="char">
699<para>File descriptor returned by a previous call to open().</para>
700</entry>
701 </row><row><entry
702 align="char">
703<para>int request</para>
704</entry><entry
705 align="char">
706<para>Equals VIDEO_CONTINUE for this command.</para>
707</entry>
708 </row></tbody></tgroup></informaltable>
709<para>ERRORS
710</para>
711<informaltable><tgroup cols="2"><tbody><row><entry
712 align="char">
713<para>EBADF</para>
714</entry><entry
715 align="char">
716<para>fd is not a valid open file descriptor</para>
717</entry>
718 </row><row><entry
719 align="char">
720<para>EINTERNAL</para>
721</entry><entry
722 align="char">
723<para>Internal error, possibly in the communication with the
724 DVB subsystem.</para>
725</entry>
726 </row></tbody></tgroup></informaltable>
727
728</section><section
729role="subsection"><title>VIDEO_SELECT_SOURCE</title>
730<para>DESCRIPTION
731</para>
732<informaltable><tgroup cols="1"><tbody><row><entry
733 align="char">
734<para>This ioctl call informs the video device which source shall be used for the input
735 data. The possible sources are demux or memory. If memory is selected, the
736 data is fed to the video device through the write command.</para>
737</entry>
738 </row></tbody></tgroup></informaltable>
739<para>SYNOPSIS
740</para>
741<informaltable><tgroup cols="1"><tbody><row><entry
742 align="char">
743<para>int ioctl(fd, int request = VIDEO_SELECT_SOURCE,
744 video_stream_source_t source);</para>
745</entry>
746 </row></tbody></tgroup></informaltable>
747<para>PARAMETERS
748</para>
749<informaltable><tgroup cols="2"><tbody><row><entry
750 align="char">
751<para>int fd</para>
752</entry><entry
753 align="char">
754<para>File descriptor returned by a previous call to open().</para>
755</entry>
756 </row><row><entry
757 align="char">
758<para>int request</para>
759</entry><entry
760 align="char">
761<para>Equals VIDEO_SELECT_SOURCE for this command.</para>
762</entry>
763 </row><row><entry
764 align="char">
765<para>video_stream_source_t
766 source</para>
767</entry><entry
768 align="char">
769<para>Indicates which source shall be used for the Video stream.</para>
770</entry>
771 </row></tbody></tgroup></informaltable>
772<para>ERRORS
773</para>
774<informaltable><tgroup cols="2"><tbody><row><entry
775 align="char">
776<para>EBADF</para>
777</entry><entry
778 align="char">
779<para>fd is not a valid open file descriptor</para>
780</entry>
781 </row><row><entry
782 align="char">
783<para>EINTERNAL</para>
784</entry><entry
785 align="char">
786<para>Internal error, possibly in the communication with the
787 DVB subsystem.</para>
788</entry>
789 </row></tbody></tgroup></informaltable>
790
791</section><section
792role="subsection"><title>VIDEO_SET_BLANK</title>
793<para>DESCRIPTION
794</para>
795<informaltable><tgroup cols="1"><tbody><row><entry
796 align="char">
797<para>This ioctl call asks the Video Device to blank out the picture.</para>
798</entry>
799 </row></tbody></tgroup></informaltable>
800<para>SYNOPSIS
801</para>
802<informaltable><tgroup cols="1"><tbody><row><entry
803 align="char">
804<para>int ioctl(fd, int request = VIDEO_SET_BLANK, boolean
805 mode);</para>
806</entry>
807 </row></tbody></tgroup></informaltable>
808<para>PARAMETERS
809</para>
810<informaltable><tgroup cols="2"><tbody><row><entry
811 align="char">
812<para>int fd</para>
813</entry><entry
814 align="char">
815<para>File descriptor returned by a previous call to open().</para>
816</entry>
817 </row><row><entry
818 align="char">
819<para>int request</para>
820</entry><entry
821 align="char">
822<para>Equals VIDEO_SET_BLANK for this command.</para>
823</entry>
824 </row><row><entry
825 align="char">
826<para>boolean mode</para>
827</entry><entry
828 align="char">
829<para>TRUE: Blank screen when stop.</para>
830</entry>
831 </row><row><entry
832 align="char">
833</entry><entry
834 align="char">
835<para>FALSE: Show last decoded frame.</para>
836</entry>
837 </row></tbody></tgroup></informaltable>
838<para>ERRORS
839</para>
840<informaltable><tgroup cols="2"><tbody><row><entry
841 align="char">
842<para>EBADF</para>
843</entry><entry
844 align="char">
845<para>fd is not a valid open file descriptor</para>
846</entry>
847 </row><row><entry
848 align="char">
849<para>EINTERNAL</para>
850</entry><entry
851 align="char">
852<para>Internal error, possibly in the communication with the
853 DVB subsystem.</para>
854</entry>
855 </row><row><entry
856 align="char">
857<para>EINVAL</para>
858</entry><entry
859 align="char">
860<para>Illegal input parameter</para>
861</entry>
862 </row></tbody></tgroup></informaltable>
863
864</section><section
865role="subsection"><title>VIDEO_GET_STATUS</title>
866<para>DESCRIPTION
867</para>
868<informaltable><tgroup cols="1"><tbody><row><entry
869 align="char">
870<para>This ioctl call asks the Video Device to return the current status of the device.</para>
871</entry>
872 </row></tbody></tgroup></informaltable>
873<para>SYNOPSIS
874</para>
875<informaltable><tgroup cols="1"><tbody><row><entry
876 align="char">
877<para> int ioctl(fd, int request = VIDEO_GET_STATUS, struct
878 video_status &#x22C6;status);</para>
879</entry>
880 </row></tbody></tgroup></informaltable>
881<para>PARAMETERS
882</para>
883<informaltable><tgroup cols="2"><tbody><row><entry
884 align="char">
885<para>int fd</para>
886</entry><entry
887 align="char">
888<para>File descriptor returned by a previous call to open().</para>
889</entry>
890 </row><row><entry
891 align="char">
892<para>int request</para>
893</entry><entry
894 align="char">
895<para>Equals VIDEO_GET_STATUS for this command.</para>
896</entry>
897 </row><row><entry
898 align="char">
899<para>struct video_status
900 *status</para>
901</entry><entry
902 align="char">
903<para>Returns the current status of the Video Device.</para>
904</entry>
905 </row></tbody></tgroup></informaltable>
906<para>ERRORS
907</para>
908<informaltable><tgroup cols="2"><tbody><row><entry
909 align="char">
910<para>EBADF</para>
911</entry><entry
912 align="char">
913<para>fd is not a valid open file descriptor</para>
914</entry>
915 </row><row><entry
916 align="char">
917<para>EINTERNAL</para>
918</entry><entry
919 align="char">
920<para>Internal error, possibly in the communication with the
921 DVB subsystem.</para>
922</entry>
923 </row><row><entry
924 align="char">
925<para>EFAULT</para>
926</entry><entry
927 align="char">
928<para>status points to invalid address</para>
929</entry>
930 </row></tbody></tgroup></informaltable>
931
932</section><section
933role="subsection"><title>VIDEO_GET_EVENT</title>
934<para>DESCRIPTION
935</para>
936<informaltable><tgroup cols="1"><tbody><row><entry
937 align="char">
938<para>This ioctl call returns an event of type video_event if available. If an event is
939 not available, the behavior depends on whether the device is in blocking or
940 non-blocking mode. In the latter case, the call fails immediately with errno
941 set to EWOULDBLOCK. In the former case, the call blocks until an event
942 becomes available. The standard Linux poll() and/or select() system calls can
943 be used with the device file descriptor to watch for new events. For select(),
944 the file descriptor should be included in the exceptfds argument, and for
945 poll(), POLLPRI should be specified as the wake-up condition. Read-only
946 permissions are sufficient for this ioctl call.</para>
947</entry>
948 </row></tbody></tgroup></informaltable>
949<para>SYNOPSIS
950</para>
951<informaltable><tgroup cols="1"><tbody><row><entry
952 align="char">
953<para> int ioctl(fd, int request = VIDEO_GET_EVENT, struct
954 video_event &#x22C6;ev);</para>
955</entry>
956 </row></tbody></tgroup></informaltable>
957<para>PARAMETERS
958</para>
959<informaltable><tgroup cols="2"><tbody><row><entry
960 align="char">
961<para>int fd</para>
962</entry><entry
963 align="char">
964<para>File descriptor returned by a previous call to open().</para>
965</entry>
966 </row><row><entry
967 align="char">
968<para>int request</para>
969</entry><entry
970 align="char">
971<para>Equals VIDEO_GET_EVENT for this command.</para>
972</entry>
973 </row><row><entry
974 align="char">
975<para>struct video_event
976 *ev</para>
977</entry><entry
978 align="char">
979<para>Points to the location where the event, if any, is to be
980 stored.</para>
981</entry>
982 </row></tbody></tgroup></informaltable>
983<para>ERRORS
984</para>
985<informaltable><tgroup cols="2"><tbody><row><entry
986 align="char">
987<para>EBADF</para>
988</entry><entry
989 align="char">
990<para>fd is not a valid open file descriptor</para>
991</entry>
992 </row><row><entry
993 align="char">
994<para>EFAULT</para>
995</entry><entry
996 align="char">
997<para>ev points to invalid address</para>
998</entry>
999 </row><row><entry
1000 align="char">
1001<para>EWOULDBLOCK</para>
1002</entry><entry
1003 align="char">
1004<para>There is no event pending, and the device is in
1005 non-blocking mode.</para>
1006</entry>
1007 </row><row><entry
1008 align="char">
1009<para>EOVERFLOW</para>
1010</entry><entry
1011 align="char">
1012</entry>
1013 </row><row><entry
1014 align="char">
1015</entry><entry
1016 align="char">
1017<para>Overflow in event queue - one or more events were lost.</para>
1018</entry>
1019 </row></tbody></tgroup></informaltable>
1020
1021</section><section
1022role="subsection"><title>VIDEO_SET_DISPLAY_FORMAT</title>
1023<para>DESCRIPTION
1024</para>
1025<informaltable><tgroup cols="1"><tbody><row><entry
1026 align="char">
1027<para>This ioctl call asks the Video Device to select the video format to be applied
1028 by the MPEG chip on the video.</para>
1029</entry>
1030 </row></tbody></tgroup></informaltable>
1031<para>SYNOPSIS
1032</para>
1033<informaltable><tgroup cols="1"><tbody><row><entry
1034 align="char">
1035<para> int ioctl(fd, int request =
1036 VIDEO_SET_DISPLAY_FORMAT, video_display_format_t
1037 format);</para>
1038</entry>
1039 </row></tbody></tgroup></informaltable>
1040<para>PARAMETERS
1041</para>
1042<informaltable><tgroup cols="2"><tbody><row><entry
1043 align="char">
1044<para>int fd</para>
1045</entry><entry
1046 align="char">
1047<para>File descriptor returned by a previous call to open().</para>
1048</entry>
1049 </row><row><entry
1050 align="char">
1051<para>int request</para>
1052</entry><entry
1053 align="char">
1054<para>Equals VIDEO_SET_DISPLAY_FORMAT for this
1055 command.</para>
1056</entry>
1057 </row><row><entry
1058 align="char">
1059<para>video_display_format_t
1060 format</para>
1061</entry><entry
1062 align="char">
1063<para>Selects the video format to be used.</para>
1064</entry>
1065 </row></tbody></tgroup></informaltable>
1066<para>ERRORS
1067</para>
1068<informaltable><tgroup cols="2"><tbody><row><entry
1069 align="char">
1070<para>EBADF</para>
1071</entry><entry
1072 align="char">
1073<para>fd is not a valid open file descriptor</para>
1074</entry>
1075 </row><row><entry
1076 align="char">
1077<para>EINTERNAL</para>
1078</entry><entry
1079 align="char">
1080<para>Internal error.</para>
1081</entry>
1082 </row><row><entry
1083 align="char">
1084<para>EINVAL</para>
1085</entry><entry
1086 align="char">
1087<para>Illegal parameter format.</para>
1088</entry>
1089 </row></tbody></tgroup></informaltable>
1090
1091</section><section
1092role="subsection"><title>VIDEO_STILLPICTURE</title>
1093<para>DESCRIPTION
1094</para>
1095<informaltable><tgroup cols="1"><tbody><row><entry
1096 align="char">
1097<para>This ioctl call asks the Video Device to display a still picture (I-frame). The
1098 input data shall contain an I-frame. If the pointer is NULL, then the current
1099 displayed still picture is blanked.</para>
1100</entry>
1101 </row></tbody></tgroup></informaltable>
1102<para>SYNOPSIS
1103</para>
1104<informaltable><tgroup cols="1"><tbody><row><entry
1105 align="char">
1106<para>int ioctl(fd, int request = VIDEO_STILLPICTURE,
1107 struct video_still_picture &#x22C6;sp);</para>
1108</entry>
1109 </row></tbody></tgroup></informaltable>
1110<para>PARAMETERS
1111</para>
1112<informaltable><tgroup cols="2"><tbody><row><entry
1113 align="char">
1114<para>int fd</para>
1115</entry><entry
1116 align="char">
1117<para>File descriptor returned by a previous call to open().</para>
1118</entry>
1119 </row><row><entry
1120 align="char">
1121<para>int request</para>
1122</entry><entry
1123 align="char">
1124<para>Equals VIDEO_STILLPICTURE for this command.</para>
1125</entry>
1126 </row><row><entry
1127 align="char">
1128<para>struct
1129 video_still_picture
1130 *sp</para>
1131</entry><entry
1132 align="char">
1133<para>Pointer to a location where an I-frame and size is stored.</para>
1134</entry>
1135 </row></tbody></tgroup></informaltable>
1136<para>ERRORS
1137</para>
1138<informaltable><tgroup cols="2"><tbody><row><entry
1139 align="char">
1140<para>EBADF</para>
1141</entry><entry
1142 align="char">
1143<para>fd is not a valid open file descriptor</para>
1144</entry>
1145 </row><row><entry
1146 align="char">
1147<para>EINTERNAL</para>
1148</entry><entry
1149 align="char">
1150<para>Internal error.</para>
1151</entry>
1152 </row><row><entry
1153 align="char">
1154<para>EFAULT</para>
1155</entry><entry
1156 align="char">
1157<para>sp points to an invalid iframe.</para>
1158</entry>
1159 </row></tbody></tgroup></informaltable>
1160
1161</section><section
1162role="subsection"><title>VIDEO_FAST_FORWARD</title>
1163<para>DESCRIPTION
1164</para>
1165<informaltable><tgroup cols="1"><tbody><row><entry
1166 align="char">
1167<para>This ioctl call asks the Video Device to skip decoding of N number of I-frames.
1168 This call can only be used if VIDEO_SOURCE_MEMORY is selected.</para>
1169</entry>
1170 </row></tbody></tgroup></informaltable>
1171<para>SYNOPSIS
1172</para>
1173<informaltable><tgroup cols="1"><tbody><row><entry
1174 align="char">
1175<para>int ioctl(fd, int request = VIDEO_FAST_FORWARD, int
1176 nFrames);</para>
1177</entry>
1178 </row></tbody></tgroup></informaltable>
1179<para>PARAMETERS
1180</para>
1181<informaltable><tgroup cols="2"><tbody><row><entry
1182 align="char">
1183<para>int fd</para>
1184</entry><entry
1185 align="char">
1186<para>File descriptor returned by a previous call to open().</para>
1187</entry>
1188 </row><row><entry
1189 align="char">
1190<para>int request</para>
1191</entry><entry
1192 align="char">
1193<para>Equals VIDEO_FAST_FORWARD for this command.</para>
1194</entry>
1195 </row><row><entry
1196 align="char">
1197<para>int nFrames</para>
1198</entry><entry
1199 align="char">
1200<para>The number of frames to skip.</para>
1201</entry>
1202 </row></tbody></tgroup></informaltable>
1203<para>ERRORS
1204</para>
1205<informaltable><tgroup cols="2"><tbody><row><entry
1206 align="char">
1207<para>EBADF</para>
1208</entry><entry
1209 align="char">
1210<para>fd is not a valid open file descriptor</para>
1211</entry>
1212 </row><row><entry
1213 align="char">
1214<para>EINTERNAL</para>
1215</entry><entry
1216 align="char">
1217<para>Internal error.</para>
1218</entry>
1219 </row><row><entry
1220 align="char">
1221<para>EPERM</para>
1222</entry><entry
1223 align="char">
1224<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
1225</entry>
1226 </row><row><entry
1227 align="char">
1228<para>EINVAL</para>
1229</entry><entry
1230 align="char">
1231<para>Illegal parameter format.</para>
1232</entry>
1233 </row></tbody></tgroup></informaltable>
1234
1235</section><section
1236role="subsection"><title>VIDEO_SLOWMOTION</title>
1237<para>DESCRIPTION
1238</para>
1239<informaltable><tgroup cols="1"><tbody><row><entry
1240 align="char">
1241<para>This ioctl call asks the video device to repeat decoding frames N number of
1242 times. This call can only be used if VIDEO_SOURCE_MEMORY is selected.</para>
1243</entry>
1244 </row></tbody></tgroup></informaltable>
1245<para>SYNOPSIS
1246</para>
1247<informaltable><tgroup cols="1"><tbody><row><entry
1248 align="char">
1249<para>int ioctl(fd, int request = VIDEO_SLOWMOTION, int
1250 nFrames);</para>
1251</entry>
1252 </row></tbody></tgroup></informaltable>
1253<para>PARAMETERS
1254</para>
1255<informaltable><tgroup cols="2"><tbody><row><entry
1256 align="char">
1257<para>int fd</para>
1258</entry><entry
1259 align="char">
1260<para>File descriptor returned by a previous call to open().</para>
1261</entry>
1262 </row><row><entry
1263 align="char">
1264<para>int request</para>
1265</entry><entry
1266 align="char">
1267<para>Equals VIDEO_SLOWMOTION for this command.</para>
1268</entry>
1269 </row><row><entry
1270 align="char">
1271<para>int nFrames</para>
1272</entry><entry
1273 align="char">
1274<para>The number of times to repeat each frame.</para>
1275</entry>
1276 </row></tbody></tgroup></informaltable>
1277<para>ERRORS
1278</para>
1279<informaltable><tgroup cols="2"><tbody><row><entry
1280 align="char">
1281<para>EBADF</para>
1282</entry><entry
1283 align="char">
1284<para>fd is not a valid open file descriptor</para>
1285</entry>
1286 </row><row><entry
1287 align="char">
1288<para>EINTERNAL</para>
1289</entry><entry
1290 align="char">
1291<para>Internal error.</para>
1292</entry>
1293 </row><row><entry
1294 align="char">
1295<para>EPERM</para>
1296</entry><entry
1297 align="char">
1298<para>Mode VIDEO_SOURCE_MEMORY not selected.</para>
1299</entry>
1300 </row><row><entry
1301 align="char">
1302<para>EINVAL</para>
1303</entry><entry
1304 align="char">
1305<para>Illegal parameter format.</para>
1306</entry>
1307 </row></tbody></tgroup></informaltable>
1308
1309</section><section
1310role="subsection"><title>VIDEO_GET_CAPABILITIES</title>
1311<para>DESCRIPTION
1312</para>
1313<informaltable><tgroup cols="1"><tbody><row><entry
1314 align="char">
1315<para>This ioctl call asks the video device about its decoding capabilities. On success
1316 it returns and integer which has bits set according to the defines in section ??.</para>
1317</entry>
1318 </row></tbody></tgroup></informaltable>
1319<para>SYNOPSIS
1320</para>
1321<informaltable><tgroup cols="1"><tbody><row><entry
1322 align="char">
1323<para>int ioctl(fd, int request = VIDEO_GET_CAPABILITIES,
1324 unsigned int &#x22C6;cap);</para>
1325</entry>
1326 </row></tbody></tgroup></informaltable>
1327<para>PARAMETERS
1328</para>
1329<informaltable><tgroup cols="2"><tbody><row><entry
1330 align="char">
1331<para>int fd</para>
1332</entry><entry
1333 align="char">
1334<para>File descriptor returned by a previous call to open().</para>
1335</entry>
1336 </row><row><entry
1337 align="char">
1338<para>int request</para>
1339</entry><entry
1340 align="char">
1341<para>Equals VIDEO_GET_CAPABILITIES for this
1342 command.</para>
1343</entry>
1344 </row><row><entry
1345 align="char">
1346<para>unsigned int *cap</para>
1347</entry><entry
1348 align="char">
1349<para>Pointer to a location where to store the capability
1350 information.</para>
1351</entry>
1352 </row></tbody></tgroup></informaltable>
1353<para>ERRORS
1354</para>
1355<informaltable><tgroup cols="2"><tbody><row><entry
1356 align="char">
1357<para>EBADF</para>
1358</entry><entry
1359 align="char">
1360<para>fd is not a valid open file descriptor</para>
1361</entry>
1362 </row><row><entry
1363 align="char">
1364<para>EFAULT</para>
1365</entry><entry
1366 align="char">
1367<para>cap points to an invalid iframe.</para>
1368</entry>
1369 </row></tbody></tgroup></informaltable>
1370
1371</section><section
1372role="subsection"><title>VIDEO_SET_ID</title>
1373<para>DESCRIPTION
1374</para>
1375<informaltable><tgroup cols="1"><tbody><row><entry
1376 align="char">
1377<para>This ioctl selects which sub-stream is to be decoded if a program or system
1378 stream is sent to the video device.</para>
1379</entry>
1380 </row></tbody></tgroup></informaltable>
1381<para>SYNOPSIS
1382</para>
1383<informaltable><tgroup cols="1"><tbody><row><entry
1384 align="char">
1385<para>int ioctl(int fd, int request = VIDEO_SET_ID, int
1386 id);</para>
1387</entry>
1388 </row></tbody></tgroup></informaltable>
1389<para>PARAMETERS
1390</para>
1391<informaltable><tgroup cols="2"><tbody><row><entry
1392 align="char">
1393<para>int fd</para>
1394</entry><entry
1395 align="char">
1396<para>File descriptor returned by a previous call to open().</para>
1397</entry>
1398 </row><row><entry
1399 align="char">
1400<para>int request</para>
1401</entry><entry
1402 align="char">
1403<para>Equals VIDEO_SET_ID for this command.</para>
1404</entry>
1405 </row><row><entry
1406 align="char">
1407<para>int id</para>
1408</entry><entry
1409 align="char">
1410<para>video sub-stream id</para>
1411</entry>
1412 </row></tbody></tgroup></informaltable>
1413<para>ERRORS
1414</para>
1415<informaltable><tgroup cols="2"><tbody><row><entry
1416 align="char">
1417<para>EBADF</para>
1418</entry><entry
1419 align="char">
1420<para>fd is not a valid open file descriptor.</para>
1421</entry>
1422 </row><row><entry
1423 align="char">
1424<para>EINTERNAL</para>
1425</entry><entry
1426 align="char">
1427<para>Internal error.</para>
1428</entry>
1429 </row><row><entry
1430 align="char">
1431<para>EINVAL</para>
1432</entry><entry
1433 align="char">
1434<para>Invalid sub-stream id.</para>
1435</entry>
1436 </row></tbody></tgroup></informaltable>
1437
1438</section><section
1439role="subsection"><title>VIDEO_CLEAR_BUFFER</title>
1440<para>DESCRIPTION
1441</para>
1442<informaltable><tgroup cols="1"><tbody><row><entry
1443 align="char">
1444<para>This ioctl call clears all video buffers in the driver and in the decoder hardware.</para>
1445</entry>
1446 </row></tbody></tgroup></informaltable>
1447<para>SYNOPSIS
1448</para>
1449<informaltable><tgroup cols="1"><tbody><row><entry
1450 align="char">
1451<para>int ioctl(fd, int request = VIDEO_CLEAR_BUFFER);</para>
1452</entry>
1453 </row></tbody></tgroup></informaltable>
1454<para>PARAMETERS
1455</para>
1456<informaltable><tgroup cols="2"><tbody><row><entry
1457 align="char">
1458<para>int fd</para>
1459</entry><entry
1460 align="char">
1461<para>File descriptor returned by a previous call to open().</para>
1462</entry>
1463 </row><row><entry
1464 align="char">
1465<para>int request</para>
1466</entry><entry
1467 align="char">
1468<para>Equals VIDEO_CLEAR_BUFFER for this command.</para>
1469</entry>
1470 </row></tbody></tgroup></informaltable>
1471<para>ERRORS
1472</para>
1473<informaltable><tgroup cols="2"><tbody><row><entry
1474 align="char">
1475<para>EBADF</para>
1476</entry><entry
1477 align="char">
1478<para>fd is not a valid open file descriptor</para>
1479</entry>
1480 </row></tbody></tgroup></informaltable>
1481
1482</section><section
1483role="subsection"><title>VIDEO_SET_STREAMTYPE</title>
1484<para>DESCRIPTION
1485</para>
1486<informaltable><tgroup cols="1"><tbody><row><entry
1487 align="char">
1488<para>This ioctl tells the driver which kind of stream to expect being written to it. If
1489 this call is not used the default of video PES is used. Some drivers might not
1490 support this call and always expect PES.</para>
1491</entry>
1492 </row></tbody></tgroup></informaltable>
1493<para>SYNOPSIS
1494</para>
1495<informaltable><tgroup cols="1"><tbody><row><entry
1496 align="char">
1497<para>int ioctl(fd, int request = VIDEO_SET_STREAMTYPE,
1498 int type);</para>
1499</entry>
1500 </row></tbody></tgroup></informaltable>
1501<para>PARAMETERS
1502</para>
1503<informaltable><tgroup cols="2"><tbody><row><entry
1504 align="char">
1505<para>int fd</para>
1506</entry><entry
1507 align="char">
1508<para>File descriptor returned by a previous call to open().</para>
1509</entry>
1510 </row><row><entry
1511 align="char">
1512<para>int request</para>
1513</entry><entry
1514 align="char">
1515<para>Equals VIDEO_SET_STREAMTYPE for this command.</para>
1516</entry>
1517 </row><row><entry
1518 align="char">
1519<para>int type</para>
1520</entry><entry
1521 align="char">
1522<para>stream type</para>
1523</entry>
1524 </row></tbody></tgroup></informaltable>
1525<para>ERRORS
1526</para>
1527<informaltable><tgroup cols="2"><tbody><row><entry
1528 align="char">
1529<para>EBADF</para>
1530</entry><entry
1531 align="char">
1532<para>fd is not a valid open file descriptor</para>
1533</entry>
1534 </row><row><entry
1535 align="char">
1536<para>EINVAL</para>
1537</entry><entry
1538 align="char">
1539<para>type is not a valid or supported stream type.</para>
1540</entry>
1541 </row></tbody></tgroup></informaltable>
1542
1543</section><section
1544role="subsection"><title>VIDEO_SET_FORMAT</title>
1545<para>DESCRIPTION
1546</para>
1547<informaltable><tgroup cols="1"><tbody><row><entry
1548 align="char">
1549<para>This ioctl sets the screen format (aspect ratio) of the connected output device
1550 (TV) so that the output of the decoder can be adjusted accordingly.</para>
1551</entry>
1552 </row></tbody></tgroup></informaltable>
1553<para>SYNOPSIS
1554</para>
1555<informaltable><tgroup cols="1"><tbody><row><entry
1556 align="char">
1557<para> int ioctl(fd, int request = VIDEO_SET_FORMAT,
1558 video_format_t format);</para>
1559</entry>
1560 </row></tbody></tgroup></informaltable>
1561<para>PARAMETERS
1562</para>
1563<informaltable><tgroup cols="2"><tbody><row><entry
1564 align="char">
1565<para>int fd</para>
1566</entry><entry
1567 align="char">
1568<para>File descriptor returned by a previous call to open().</para>
1569</entry>
1570 </row><row><entry
1571 align="char">
1572<para>int request</para>
1573</entry><entry
1574 align="char">
1575<para>Equals VIDEO_SET_FORMAT for this command.</para>
1576</entry>
1577 </row><row><entry
1578 align="char">
1579<para>video_format_t
1580 format</para>
1581</entry><entry
1582 align="char">
1583<para>video format of TV as defined in section ??.</para>
1584</entry>
1585 </row></tbody></tgroup></informaltable>
1586<para>ERRORS
1587</para>
1588<informaltable><tgroup cols="2"><tbody><row><entry
1589 align="char">
1590<para>EBADF</para>
1591</entry><entry
1592 align="char">
1593<para>fd is not a valid open file descriptor</para>
1594</entry>
1595 </row><row><entry
1596 align="char">
1597<para>EINVAL</para>
1598</entry><entry
1599 align="char">
1600<para>format is not a valid video format.</para>
1601</entry>
1602 </row></tbody></tgroup></informaltable>
1603
1604</section><section
1605role="subsection"><title>VIDEO_SET_SYSTEM</title>
1606<para>DESCRIPTION
1607</para>
1608<informaltable><tgroup cols="1"><tbody><row><entry
1609 align="char">
1610<para>This ioctl sets the television output format. The format (see section ??) may
1611 vary from the color format of the displayed MPEG stream. If the hardware is
1612 not able to display the requested format the call will return an error.</para>
1613</entry>
1614 </row></tbody></tgroup></informaltable>
1615<para>SYNOPSIS
1616</para>
1617<informaltable><tgroup cols="1"><tbody><row><entry
1618 align="char">
1619<para> int ioctl(fd, int request = VIDEO_SET_SYSTEM ,
1620 video_system_t system);</para>
1621</entry>
1622 </row></tbody></tgroup></informaltable>
1623<para>PARAMETERS
1624</para>
1625<informaltable><tgroup cols="2"><tbody><row><entry
1626 align="char">
1627<para>int fd</para>
1628</entry><entry
1629 align="char">
1630<para>File descriptor returned by a previous call to open().</para>
1631</entry>
1632 </row><row><entry
1633 align="char">
1634<para>int request</para>
1635</entry><entry
1636 align="char">
1637<para>Equals VIDEO_SET_FORMAT for this command.</para>
1638</entry>
1639 </row><row><entry
1640 align="char">
1641<para>video_system_t
1642 system</para>
1643</entry><entry
1644 align="char">
1645<para>video system of TV output.</para>
1646</entry>
1647 </row></tbody></tgroup></informaltable>
1648<para>ERRORS
1649</para>
1650<informaltable><tgroup cols="2"><tbody><row><entry
1651 align="char">
1652<para>EBADF</para>
1653</entry><entry
1654 align="char">
1655<para>fd is not a valid open file descriptor</para>
1656</entry>
1657 </row><row><entry
1658 align="char">
1659<para>EINVAL</para>
1660</entry><entry
1661 align="char">
1662<para>system is not a valid or supported video system.</para>
1663</entry>
1664 </row></tbody></tgroup></informaltable>
1665
1666</section><section
1667role="subsection"><title>VIDEO_SET_HIGHLIGHT</title>
1668<para>DESCRIPTION
1669</para>
1670<informaltable><tgroup cols="1"><tbody><row><entry
1671 align="char">
1672<para>This ioctl sets the SPU highlight information for the menu access of a DVD.</para>
1673</entry>
1674 </row></tbody></tgroup></informaltable>
1675<para>SYNOPSIS
1676</para>
1677<informaltable><tgroup cols="1"><tbody><row><entry
1678 align="char">
1679<para> int ioctl(fd, int request = VIDEO_SET_HIGHLIGHT
1680 ,video_highlight_t &#x22C6;vhilite)</para>
1681</entry>
1682 </row></tbody></tgroup></informaltable>
1683<para>PARAMETERS
1684</para>
1685<informaltable><tgroup cols="2"><tbody><row><entry
1686 align="char">
1687<para>int fd</para>
1688</entry><entry
1689 align="char">
1690<para>File descriptor returned by a previous call to open().</para>
1691</entry>
1692 </row><row><entry
1693 align="char">
1694<para>int request</para>
1695</entry><entry
1696 align="char">
1697<para>Equals VIDEO_SET_HIGHLIGHT for this command.</para>
1698</entry>
1699 </row><row><entry
1700 align="char">
1701<para>video_highlight_t
1702 *vhilite</para>
1703</entry><entry
1704 align="char">
1705<para>SPU Highlight information according to section ??.</para>
1706</entry>
1707 </row></tbody></tgroup></informaltable>
1708<para>ERRORS
1709</para>
1710<informaltable><tgroup cols="2"><tbody><row><entry
1711 align="char">
1712<para>EBADF</para>
1713</entry><entry
1714 align="char">
1715<para>fd is not a valid open file descriptor.</para>
1716</entry>
1717 </row><row><entry
1718 align="char">
1719<para>EINVAL</para>
1720</entry><entry
1721 align="char">
1722<para>input is not a valid highlight setting.</para>
1723</entry>
1724 </row></tbody></tgroup></informaltable>
1725
1726</section><section
1727role="subsection"><title>VIDEO_SET_SPU</title>
1728<para>DESCRIPTION
1729</para>
1730<informaltable><tgroup cols="1"><tbody><row><entry
1731 align="char">
1732<para>This ioctl activates or deactivates SPU decoding in a DVD input stream. It can
1733 only be used, if the driver is able to handle a DVD stream.</para>
1734</entry>
1735 </row></tbody></tgroup></informaltable>
1736<para>SYNOPSIS
1737</para>
1738<informaltable><tgroup cols="1"><tbody><row><entry
1739 align="char">
1740<para> int ioctl(fd, int request = VIDEO_SET_SPU ,
1741 video_spu_t &#x22C6;spu)</para>
1742</entry>
1743 </row></tbody></tgroup></informaltable>
1744<para>PARAMETERS
1745</para>
1746<informaltable><tgroup cols="2"><tbody><row><entry
1747 align="char">
1748<para>int fd</para>
1749</entry><entry
1750 align="char">
1751<para>File descriptor returned by a previous call to open().</para>
1752</entry>
1753 </row><row><entry
1754 align="char">
1755<para>int request</para>
1756</entry><entry
1757 align="char">
1758<para>Equals VIDEO_SET_SPU for this command.</para>
1759</entry>
1760 </row><row><entry
1761 align="char">
1762<para>video_spu_t *spu</para>
1763</entry><entry
1764 align="char">
1765<para>SPU decoding (de)activation and subid setting according
1766 to section ??.</para>
1767</entry>
1768 </row></tbody></tgroup></informaltable>
1769<para>ERRORS
1770</para>
1771<informaltable><tgroup cols="2"><tbody><row><entry
1772 align="char">
1773<para>EBADF</para>
1774</entry><entry
1775 align="char">
1776<para>fd is not a valid open file descriptor</para>
1777</entry>
1778 </row><row><entry
1779 align="char">
1780<para>EINVAL</para>
1781</entry><entry
1782 align="char">
1783<para>input is not a valid spu setting or driver cannot handle
1784 SPU.</para>
1785</entry>
1786 </row></tbody></tgroup></informaltable>
1787
1788</section><section
1789role="subsection"><title>VIDEO_SET_SPU_PALETTE</title>
1790<para>DESCRIPTION
1791</para>
1792<informaltable><tgroup cols="1"><tbody><row><entry
1793 align="char">
1794<para>This ioctl sets the SPU color palette.</para>
1795</entry>
1796 </row></tbody></tgroup></informaltable>
1797<para>SYNOPSIS
1798</para>
1799<informaltable><tgroup cols="1"><tbody><row><entry
1800 align="char">
1801<para> int ioctl(fd, int request = VIDEO_SET_SPU_PALETTE
1802 ,video_spu_palette_t &#x22C6;palette )</para>
1803</entry>
1804 </row></tbody></tgroup></informaltable>
1805<para>PARAMETERS
1806</para>
1807<informaltable><tgroup cols="2"><tbody><row><entry
1808 align="char">
1809<para>int fd</para>
1810</entry><entry
1811 align="char">
1812<para>File descriptor returned by a previous call to open().</para>
1813</entry>
1814 </row><row><entry
1815 align="char">
1816<para>int request</para>
1817</entry><entry
1818 align="char">
1819<para>Equals VIDEO_SET_SPU_PALETTE for this command.</para>
1820</entry>
1821 </row><row><entry
1822 align="char">
1823<para>video_spu_palette_t
1824 *palette</para>
1825</entry><entry
1826 align="char">
1827<para>SPU palette according to section ??.</para>
1828</entry>
1829 </row></tbody></tgroup></informaltable>
1830<para>ERRORS
1831</para>
1832<informaltable><tgroup cols="2"><tbody><row><entry
1833 align="char">
1834<para>EBADF</para>
1835</entry><entry
1836 align="char">
1837<para>fd is not a valid open file descriptor</para>
1838</entry>
1839 </row><row><entry
1840 align="char">
1841<para>EINVAL</para>
1842</entry><entry
1843 align="char">
1844<para>input is not a valid palette or driver doesn&#8217;t handle SPU.</para>
1845</entry>
1846 </row></tbody></tgroup></informaltable>
1847
1848</section><section
1849role="subsection"><title>VIDEO_GET_NAVI</title>
1850<para>DESCRIPTION
1851</para>
1852<informaltable><tgroup cols="1"><tbody><row><entry
1853 align="char">
1854<para>This ioctl returns navigational information from the DVD stream. This is
1855 especially needed if an encoded stream has to be decoded by the hardware.</para>
1856</entry>
1857 </row></tbody></tgroup></informaltable>
1858<para>SYNOPSIS
1859</para>
1860<informaltable><tgroup cols="1"><tbody><row><entry
1861 align="char">
1862<para> int ioctl(fd, int request = VIDEO_GET_NAVI ,
1863 video_navi_pack_t &#x22C6;navipack)</para>
1864</entry>
1865 </row></tbody></tgroup></informaltable>
1866<para>PARAMETERS
1867</para>
1868<informaltable><tgroup cols="2"><tbody><row><entry
1869 align="char">
1870<para>int fd</para>
1871</entry><entry
1872 align="char">
1873<para>File descriptor returned by a previous call to open().</para>
1874</entry>
1875 </row><row><entry
1876 align="char">
1877<para>int request</para>
1878</entry><entry
1879 align="char">
1880<para>Equals VIDEO_GET_NAVI for this command.</para>
1881</entry>
1882 </row><row><entry
1883 align="char">
1884<para>video_navi_pack_t
1885 *navipack</para>
1886</entry><entry
1887 align="char">
1888<para>PCI or DSI pack (private stream 2) according to section
1889 ??.</para>
1890</entry>
1891 </row></tbody></tgroup></informaltable>
1892<para>ERRORS
1893</para>
1894<informaltable><tgroup cols="2"><tbody><row><entry
1895 align="char">
1896<para>EBADF</para>
1897</entry><entry
1898 align="char">
1899<para>fd is not a valid open file descriptor</para>
1900</entry>
1901 </row><row><entry
1902 align="char">
1903<para>EFAULT</para>
1904</entry><entry
1905 align="char">
1906<para>driver is not able to return navigational information</para>
1907</entry>
1908 </row></tbody></tgroup></informaltable>
1909
1910</section><section
1911role="subsection"><title>VIDEO_SET_ATTRIBUTES</title>
1912<para>DESCRIPTION
1913</para>
1914<informaltable><tgroup cols="1"><tbody><row><entry
1915 align="char">
1916<para>This ioctl is intended for DVD playback and allows you to set certain
1917 information about the stream. Some hardware may not need this information,
1918 but the call also tells the hardware to prepare for DVD playback.</para>
1919</entry>
1920 </row></tbody></tgroup></informaltable>
1921<para>SYNOPSIS
1922</para>
1923<informaltable><tgroup cols="1"><tbody><row><entry
1924 align="char">
1925<para> int ioctl(fd, int request = VIDEO_SET_ATTRIBUTE
1926 ,video_attributes_t vattr)</para>
1927</entry>
1928 </row></tbody></tgroup></informaltable>
1929<para>PARAMETERS
1930</para>
1931<informaltable><tgroup cols="2"><tbody><row><entry
1932 align="char">
1933<para>int fd</para>
1934</entry><entry
1935 align="char">
1936<para>File descriptor returned by a previous call to open().</para>
1937</entry>
1938 </row><row><entry
1939 align="char">
1940<para>int request</para>
1941</entry><entry
1942 align="char">
1943<para>Equals VIDEO_SET_ATTRIBUTE for this command.</para>
1944</entry>
1945 </row><row><entry
1946 align="char">
1947<para>video_attributes_t
1948 vattr</para>
1949</entry><entry
1950 align="char">
1951<para>video attributes according to section ??.</para>
1952</entry>
1953 </row></tbody></tgroup></informaltable>
1954<para>ERRORS
1955</para>
1956<informaltable><tgroup cols="2"><tbody><row><entry
1957 align="char">
1958<para>EBADF</para>
1959</entry><entry
1960 align="char">
1961<para>fd is not a valid open file descriptor</para>
1962</entry>
1963 </row><row><entry
1964 align="char">
1965<para>EINVAL</para>
1966</entry><entry
1967 align="char">
1968<para>input is not a valid attribute setting.</para>
1969</entry>
1970 </row></tbody></tgroup></informaltable>
1971 </section></section>
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
new file mode 100644
index 000000000000..0eb43c1970bb
--- /dev/null
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -0,0 +1,364 @@
1<!-- Generated file! Do not edit. -->
2
3<!-- Functions -->
4<!ENTITY func-close "<link linkend='func-close'><function>close()</function></link>">
5<!ENTITY func-ioctl "<link linkend='func-ioctl'><function>ioctl()</function></link>">
6<!ENTITY func-mmap "<link linkend='func-mmap'><function>mmap()</function></link>">
7<!ENTITY func-munmap "<link linkend='func-munmap'><function>munmap()</function></link>">
8<!ENTITY func-open "<link linkend='func-open'><function>open()</function></link>">
9<!ENTITY func-poll "<link linkend='func-poll'><function>poll()</function></link>">
10<!ENTITY func-read "<link linkend='func-read'><function>read()</function></link>">
11<!ENTITY func-select "<link linkend='func-select'><function>select()</function></link>">
12<!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>">
13
14<!-- Ioctls -->
15<!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>">
16<!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>">
17<!ENTITY VIDIOC-DBG-G-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_G_REGISTER</constant></link>">
18<!ENTITY VIDIOC-DBG-S-REGISTER "<link linkend='vidioc-dbg-g-register'><constant>VIDIOC_DBG_S_REGISTER</constant></link>">
19<!ENTITY VIDIOC-DQBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_DQBUF</constant></link>">
20<!ENTITY VIDIOC-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_ENCODER_CMD</constant></link>">
21<!ENTITY VIDIOC-ENUMAUDIO "<link linkend='vidioc-enumaudio'><constant>VIDIOC_ENUMAUDIO</constant></link>">
22<!ENTITY VIDIOC-ENUMAUDOUT "<link linkend='vidioc-enumaudioout'><constant>VIDIOC_ENUMAUDOUT</constant></link>">
23<!ENTITY VIDIOC-ENUMINPUT "<link linkend='vidioc-enuminput'><constant>VIDIOC_ENUMINPUT</constant></link>">
24<!ENTITY VIDIOC-ENUMOUTPUT "<link linkend='vidioc-enumoutput'><constant>VIDIOC_ENUMOUTPUT</constant></link>">
25<!ENTITY VIDIOC-ENUMSTD "<link linkend='vidioc-enumstd'><constant>VIDIOC_ENUMSTD</constant></link>">
26<!ENTITY VIDIOC-ENUM-FMT "<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>">
27<!ENTITY VIDIOC-ENUM-FRAMEINTERVALS "<link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>">
28<!ENTITY VIDIOC-ENUM-FRAMESIZES "<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>">
29<!ENTITY VIDIOC-G-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_G_AUDIO</constant></link>">
30<!ENTITY VIDIOC-G-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_G_AUDOUT</constant></link>">
31<!ENTITY VIDIOC-G-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_G_CROP</constant></link>">
32<!ENTITY VIDIOC-G-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_G_CTRL</constant></link>">
33<!ENTITY VIDIOC-G-ENC-INDEX "<link linkend='vidioc-g-enc-index'><constant>VIDIOC_G_ENC_INDEX</constant></link>">
34<!ENTITY VIDIOC-G-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_G_EXT_CTRLS</constant></link>">
35<!ENTITY VIDIOC-G-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_G_FBUF</constant></link>">
36<!ENTITY VIDIOC-G-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_G_FMT</constant></link>">
37<!ENTITY VIDIOC-G-FREQUENCY "<link linkend='vidioc-g-frequency'><constant>VIDIOC_G_FREQUENCY</constant></link>">
38<!ENTITY VIDIOC-G-INPUT "<link linkend='vidioc-g-input'><constant>VIDIOC_G_INPUT</constant></link>">
39<!ENTITY VIDIOC-G-JPEGCOMP "<link linkend='vidioc-g-jpegcomp'><constant>VIDIOC_G_JPEGCOMP</constant></link>">
40<!ENTITY VIDIOC-G-MPEGCOMP "<link linkend=''><constant>VIDIOC_G_MPEGCOMP</constant></link>">
41<!ENTITY VIDIOC-G-MODULATOR "<link linkend='vidioc-g-modulator'><constant>VIDIOC_G_MODULATOR</constant></link>">
42<!ENTITY VIDIOC-G-OUTPUT "<link linkend='vidioc-g-output'><constant>VIDIOC_G_OUTPUT</constant></link>">
43<!ENTITY VIDIOC-G-PARM "<link linkend='vidioc-g-parm'><constant>VIDIOC_G_PARM</constant></link>">
44<!ENTITY VIDIOC-G-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_G_PRIORITY</constant></link>">
45<!ENTITY VIDIOC-G-SLICED-VBI-CAP "<link linkend='vidioc-g-sliced-vbi-cap'><constant>VIDIOC_G_SLICED_VBI_CAP</constant></link>">
46<!ENTITY VIDIOC-G-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_G_STD</constant></link>">
47<!ENTITY VIDIOC-G-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_G_TUNER</constant></link>">
48<!ENTITY VIDIOC-LOG-STATUS "<link linkend='vidioc-log-status'><constant>VIDIOC_LOG_STATUS</constant></link>">
49<!ENTITY VIDIOC-OVERLAY "<link linkend='vidioc-overlay'><constant>VIDIOC_OVERLAY</constant></link>">
50<!ENTITY VIDIOC-QBUF "<link linkend='vidioc-qbuf'><constant>VIDIOC_QBUF</constant></link>">
51<!ENTITY VIDIOC-QUERYBUF "<link linkend='vidioc-querybuf'><constant>VIDIOC_QUERYBUF</constant></link>">
52<!ENTITY VIDIOC-QUERYCAP "<link linkend='vidioc-querycap'><constant>VIDIOC_QUERYCAP</constant></link>">
53<!ENTITY VIDIOC-QUERYCTRL "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYCTRL</constant></link>">
54<!ENTITY VIDIOC-QUERYMENU "<link linkend='vidioc-queryctrl'><constant>VIDIOC_QUERYMENU</constant></link>">
55<!ENTITY VIDIOC-QUERYSTD "<link linkend='vidioc-querystd'><constant>VIDIOC_QUERYSTD</constant></link>">
56<!ENTITY VIDIOC-REQBUFS "<link linkend='vidioc-reqbufs'><constant>VIDIOC_REQBUFS</constant></link>">
57<!ENTITY VIDIOC-STREAMOFF "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMOFF</constant></link>">
58<!ENTITY VIDIOC-STREAMON "<link linkend='vidioc-streamon'><constant>VIDIOC_STREAMON</constant></link>">
59<!ENTITY VIDIOC-S-AUDIO "<link linkend='vidioc-g-audio'><constant>VIDIOC_S_AUDIO</constant></link>">
60<!ENTITY VIDIOC-S-AUDOUT "<link linkend='vidioc-g-audioout'><constant>VIDIOC_S_AUDOUT</constant></link>">
61<!ENTITY VIDIOC-S-CROP "<link linkend='vidioc-g-crop'><constant>VIDIOC_S_CROP</constant></link>">
62<!ENTITY VIDIOC-S-CTRL "<link linkend='vidioc-g-ctrl'><constant>VIDIOC_S_CTRL</constant></link>">
63<!ENTITY VIDIOC-S-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_S_EXT_CTRLS</constant></link>">
64<!ENTITY VIDIOC-S-FBUF "<link linkend='vidioc-g-fbuf'><constant>VIDIOC_S_FBUF</constant></link>">
65<!ENTITY VIDIOC-S-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>">
66<!ENTITY VIDIOC-S-FREQUENCY "<link linkend='vidioc-g-frequency'><constant>VIDIOC_S_FREQUENCY</constant></link>">
67<!ENTITY VIDIOC-S-HW-FREQ-SEEK "<link linkend='vidioc-s-hw-freq-seek'><constant>VIDIOC_S_HW_FREQ_SEEK</constant></link>">
68<!ENTITY VIDIOC-S-INPUT "<link linkend='vidioc-g-input'><constant>VIDIOC_S_INPUT</constant></link>">
69<!ENTITY VIDIOC-S-JPEGCOMP "<link linkend='vidioc-g-jpegcomp'><constant>VIDIOC_S_JPEGCOMP</constant></link>">
70<!ENTITY VIDIOC-S-MPEGCOMP "<link linkend=''><constant>VIDIOC_S_MPEGCOMP</constant></link>">
71<!ENTITY VIDIOC-S-MODULATOR "<link linkend='vidioc-g-modulator'><constant>VIDIOC_S_MODULATOR</constant></link>">
72<!ENTITY VIDIOC-S-OUTPUT "<link linkend='vidioc-g-output'><constant>VIDIOC_S_OUTPUT</constant></link>">
73<!ENTITY VIDIOC-S-PARM "<link linkend='vidioc-g-parm'><constant>VIDIOC_S_PARM</constant></link>">
74<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
75<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
76<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
77<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
78<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
79<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
80
81<!-- Types -->
82<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
83
84<!-- Enums -->
85<!ENTITY v4l2-buf-type "enum&nbsp;<link linkend='v4l2-buf-type'>v4l2_buf_type</link>">
86<!ENTITY v4l2-colorspace "enum&nbsp;<link linkend='v4l2-colorspace'>v4l2_colorspace</link>">
87<!ENTITY v4l2-ctrl-type "enum&nbsp;<link linkend='v4l2-ctrl-type'>v4l2_ctrl_type</link>">
88<!ENTITY v4l2-exposure-auto-type "enum&nbsp;<link linkend='v4l2-exposure-auto-type'>v4l2_exposure_auto_type</link>">
89<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
90<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
91<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
92<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
93<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
94<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
95<!ENTITY v4l2-mpeg-audio-emphasis "enum&nbsp;<link linkend='v4l2-mpeg-audio-emphasis'>v4l2_mpeg_audio_emphasis</link>">
96<!ENTITY v4l2-mpeg-audio-encoding "enum&nbsp;<link linkend='v4l2-mpeg-audio-encoding'>v4l2_mpeg_audio_encoding</link>">
97<!ENTITY v4l2-mpeg-audio-l1-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l1-bitrate'>v4l2_mpeg_audio_l1_bitrate</link>">
98<!ENTITY v4l2-mpeg-audio-l2-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l2-bitrate'>v4l2_mpeg_audio_l2_bitrate</link>">
99<!ENTITY v4l2-mpeg-audio-l3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-l3-bitrate'>v4l2_mpeg_audio_l3_bitrate</link>">
100<!ENTITY v4l2-mpeg-audio-mode "enum&nbsp;<link linkend='v4l2-mpeg-audio-mode'>v4l2_mpeg_audio_mode</link>">
101<!ENTITY v4l2-mpeg-audio-mode-extension "enum&nbsp;<link linkend='v4l2-mpeg-audio-mode-extension'>v4l2_mpeg_audio_mode_extension</link>">
102<!ENTITY v4l2-mpeg-audio-sampling-freq "enum&nbsp;<link linkend='v4l2-mpeg-audio-sampling-freq'>v4l2_mpeg_audio_sampling_freq</link>">
103<!ENTITY chroma-spatial-filter-type "enum&nbsp;<link linkend='chroma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link>">
104<!ENTITY luma-spatial-filter-type "enum&nbsp;<link linkend='luma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link>">
105<!ENTITY v4l2-mpeg-cx2341x-video-median-filter-type "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-median-filter-type'>v4l2_mpeg_cx2341x_video_median_filter_type</link>">
106<!ENTITY v4l2-mpeg-cx2341x-video-spatial-filter-mode "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-spatial-filter-mode'>v4l2_mpeg_cx2341x_video_spatial_filter_mode</link>">
107<!ENTITY v4l2-mpeg-cx2341x-video-temporal-filter-mode "enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-temporal-filter-mode'>v4l2_mpeg_cx2341x_video_temporal_filter_mode</link>">
108<!ENTITY v4l2-mpeg-stream-type "enum&nbsp;<link linkend='v4l2-mpeg-stream-type'>v4l2_mpeg_stream_type</link>">
109<!ENTITY v4l2-mpeg-stream-vbi-fmt "enum&nbsp;<link linkend='v4l2-mpeg-stream-vbi-fmt'>v4l2_mpeg_stream_vbi_fmt</link>">
110<!ENTITY v4l2-mpeg-video-aspect "enum&nbsp;<link linkend='v4l2-mpeg-video-aspect'>v4l2_mpeg_video_aspect</link>">
111<!ENTITY v4l2-mpeg-video-bitrate-mode "enum&nbsp;<link linkend='v4l2-mpeg-video-bitrate-mode'>v4l2_mpeg_video_bitrate_mode</link>">
112<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
113<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
114<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
115<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
116<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
117
118<!-- Structures -->
119<!ENTITY v4l2-audio "struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link>">
120<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
121<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
122<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
123<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
124<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>">
125<!ENTITY v4l2-control "struct&nbsp;<link linkend='v4l2-control'>v4l2_control</link>">
126<!ENTITY v4l2-crop "struct&nbsp;<link linkend='v4l2-crop'>v4l2_crop</link>">
127<!ENTITY v4l2-cropcap "struct&nbsp;<link linkend='v4l2-cropcap'>v4l2_cropcap</link>">
128<!ENTITY v4l2-dbg-chip-ident "struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link>">
129<!ENTITY v4l2-dbg-match "struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link>">
130<!ENTITY v4l2-dbg-register "struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link>">
131<!ENTITY v4l2-enc-idx "struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link>">
132<!ENTITY v4l2-enc-idx-entry "struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link>">
133<!ENTITY v4l2-encoder-cmd "struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link>">
134<!ENTITY v4l2-ext-control "struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link>">
135<!ENTITY v4l2-ext-controls "struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link>">
136<!ENTITY v4l2-fmtdesc "struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link>">
137<!ENTITY v4l2-format "struct&nbsp;<link linkend='v4l2-format'>v4l2_format</link>">
138<!ENTITY v4l2-fract "struct&nbsp;<link linkend='v4l2-fract'>v4l2_fract</link>">
139<!ENTITY v4l2-framebuffer "struct&nbsp;<link linkend='v4l2-framebuffer'>v4l2_framebuffer</link>">
140<!ENTITY v4l2-frequency "struct&nbsp;<link linkend='v4l2-frequency'>v4l2_frequency</link>">
141<!ENTITY v4l2-frmival-stepwise "struct&nbsp;<link linkend='v4l2-frmival-stepwise'>v4l2_frmival_stepwise</link>">
142<!ENTITY v4l2-frmivalenum "struct&nbsp;<link linkend='v4l2-frmivalenum'>v4l2_frmivalenum</link>">
143<!ENTITY v4l2-frmsize-discrete "struct&nbsp;<link linkend='v4l2-frmsize-discrete'>v4l2_frmsize_discrete</link>">
144<!ENTITY v4l2-frmsize-stepwise "struct&nbsp;<link linkend='v4l2-frmsize-stepwise'>v4l2_frmsize_stepwise</link>">
145<!ENTITY v4l2-frmsizeenum "struct&nbsp;<link linkend='v4l2-frmsizeenum'>v4l2_frmsizeenum</link>">
146<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
147<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
148<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
149<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
150<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
151<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
152<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>">
153<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>">
154<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>">
155<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>">
156<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>">
157<!ENTITY v4l2-requestbuffers "struct&nbsp;<link linkend='v4l2-requestbuffers'>v4l2_requestbuffers</link>">
158<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
159<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
160<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
161<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
162<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
163<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
164<!ENTITY v4l2-tuner "struct&nbsp;<link linkend='v4l2-tuner'>v4l2_tuner</link>">
165<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>">
166<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>">
167
168<!-- Error Codes -->
169<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code">
170<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code">
171<!ENTITY EBADF "<errorcode>EBADF</errorcode> error code">
172<!ENTITY EBUSY "<errorcode>EBUSY</errorcode> error code">
173<!ENTITY EFAULT "<errorcode>EFAULT</errorcode> error code">
174<!ENTITY EIO "<errorcode>EIO</errorcode> error code">
175<!ENTITY EINTR "<errorcode>EINTR</errorcode> error code">
176<!ENTITY EINVAL "<errorcode>EINVAL</errorcode> error code">
177<!ENTITY ENFILE "<errorcode>ENFILE</errorcode> error code">
178<!ENTITY ENOMEM "<errorcode>ENOMEM</errorcode> error code">
179<!ENTITY ENOSPC "<errorcode>ENOSPC</errorcode> error code">
180<!ENTITY ENOTTY "<errorcode>ENOTTY</errorcode> error code">
181<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
182<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
183<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
184<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
185
186<!-- Subsections -->
187<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml">
188<!ENTITY sub-common SYSTEM "v4l/common.xml">
189<!ENTITY sub-compat SYSTEM "v4l/compat.xml">
190<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
191<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
192<!ENTITY sub-dev-codec SYSTEM "v4l/dev-codec.xml">
193<!ENTITY sub-dev-effect SYSTEM "v4l/dev-effect.xml">
194<!ENTITY sub-dev-osd SYSTEM "v4l/dev-osd.xml">
195<!ENTITY sub-dev-output SYSTEM "v4l/dev-output.xml">
196<!ENTITY sub-dev-overlay SYSTEM "v4l/dev-overlay.xml">
197<!ENTITY sub-dev-radio SYSTEM "v4l/dev-radio.xml">
198<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
199<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
200<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
201<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
202<!ENTITY sub-driver SYSTEM "v4l/driver.xml">
203<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
204<!ENTITY sub-remote_controllers SYSTEM "v4l/remote_controllers.xml">
205<!ENTITY sub-fdl-appendix SYSTEM "v4l/fdl-appendix.xml">
206<!ENTITY sub-close SYSTEM "v4l/func-close.xml">
207<!ENTITY sub-ioctl SYSTEM "v4l/func-ioctl.xml">
208<!ENTITY sub-mmap SYSTEM "v4l/func-mmap.xml">
209<!ENTITY sub-munmap SYSTEM "v4l/func-munmap.xml">
210<!ENTITY sub-open SYSTEM "v4l/func-open.xml">
211<!ENTITY sub-poll SYSTEM "v4l/func-poll.xml">
212<!ENTITY sub-read SYSTEM "v4l/func-read.xml">
213<!ENTITY sub-select SYSTEM "v4l/func-select.xml">
214<!ENTITY sub-write SYSTEM "v4l/func-write.xml">
215<!ENTITY sub-io SYSTEM "v4l/io.xml">
216<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
217<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
218<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml">
219<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
220<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
221<!ENTITY sub-sbggr16 SYSTEM "v4l/pixfmt-sbggr16.xml">
222<!ENTITY sub-sbggr8 SYSTEM "v4l/pixfmt-sbggr8.xml">
223<!ENTITY sub-sgbrg8 SYSTEM "v4l/pixfmt-sgbrg8.xml">
224<!ENTITY sub-sgrbg8 SYSTEM "v4l/pixfmt-sgrbg8.xml">
225<!ENTITY sub-uyvy SYSTEM "v4l/pixfmt-uyvy.xml">
226<!ENTITY sub-vyuy SYSTEM "v4l/pixfmt-vyuy.xml">
227<!ENTITY sub-y16 SYSTEM "v4l/pixfmt-y16.xml">
228<!ENTITY sub-y41p SYSTEM "v4l/pixfmt-y41p.xml">
229<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
230<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
231<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
232<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
233<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
234<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
235<!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
236<!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
237<!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
238<!ENTITY sub-encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">
239<!ENTITY sub-enum-fmt SYSTEM "v4l/vidioc-enum-fmt.xml">
240<!ENTITY sub-enum-frameintervals SYSTEM "v4l/vidioc-enum-frameintervals.xml">
241<!ENTITY sub-enum-framesizes SYSTEM "v4l/vidioc-enum-framesizes.xml">
242<!ENTITY sub-enumaudio SYSTEM "v4l/vidioc-enumaudio.xml">
243<!ENTITY sub-enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
244<!ENTITY sub-enuminput SYSTEM "v4l/vidioc-enuminput.xml">
245<!ENTITY sub-enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
246<!ENTITY sub-enumstd SYSTEM "v4l/vidioc-enumstd.xml">
247<!ENTITY sub-g-audio SYSTEM "v4l/vidioc-g-audio.xml">
248<!ENTITY sub-g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
249<!ENTITY sub-dbg-g-chip-ident SYSTEM "v4l/vidioc-dbg-g-chip-ident.xml">
250<!ENTITY sub-g-crop SYSTEM "v4l/vidioc-g-crop.xml">
251<!ENTITY sub-g-ctrl SYSTEM "v4l/vidioc-g-ctrl.xml">
252<!ENTITY sub-g-enc-index SYSTEM "v4l/vidioc-g-enc-index.xml">
253<!ENTITY sub-g-ext-ctrls SYSTEM "v4l/vidioc-g-ext-ctrls.xml">
254<!ENTITY sub-g-fbuf SYSTEM "v4l/vidioc-g-fbuf.xml">
255<!ENTITY sub-g-fmt SYSTEM "v4l/vidioc-g-fmt.xml">
256<!ENTITY sub-g-frequency SYSTEM "v4l/vidioc-g-frequency.xml">
257<!ENTITY sub-g-input SYSTEM "v4l/vidioc-g-input.xml">
258<!ENTITY sub-g-jpegcomp SYSTEM "v4l/vidioc-g-jpegcomp.xml">
259<!ENTITY sub-g-modulator SYSTEM "v4l/vidioc-g-modulator.xml">
260<!ENTITY sub-g-output SYSTEM "v4l/vidioc-g-output.xml">
261<!ENTITY sub-g-parm SYSTEM "v4l/vidioc-g-parm.xml">
262<!ENTITY sub-g-priority SYSTEM "v4l/vidioc-g-priority.xml">
263<!ENTITY sub-g-sliced-vbi-cap SYSTEM "v4l/vidioc-g-sliced-vbi-cap.xml">
264<!ENTITY sub-g-std SYSTEM "v4l/vidioc-g-std.xml">
265<!ENTITY sub-g-tuner SYSTEM "v4l/vidioc-g-tuner.xml">
266<!ENTITY sub-log-status SYSTEM "v4l/vidioc-log-status.xml">
267<!ENTITY sub-overlay SYSTEM "v4l/vidioc-overlay.xml">
268<!ENTITY sub-qbuf SYSTEM "v4l/vidioc-qbuf.xml">
269<!ENTITY sub-querybuf SYSTEM "v4l/vidioc-querybuf.xml">
270<!ENTITY sub-querycap SYSTEM "v4l/vidioc-querycap.xml">
271<!ENTITY sub-queryctrl SYSTEM "v4l/vidioc-queryctrl.xml">
272<!ENTITY sub-querystd SYSTEM "v4l/vidioc-querystd.xml">
273<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
274<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
275<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
276<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
277<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
278<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
279<!ENTITY sub-videodev2-h SYSTEM "v4l/videodev2.h.xml">
280<!ENTITY sub-v4l2 SYSTEM "v4l/v4l2.xml">
281<!ENTITY sub-intro SYSTEM "dvb/intro.xml">
282<!ENTITY sub-frontend SYSTEM "dvb/frontend.xml">
283<!ENTITY sub-isdbt SYSTEM "dvb/isdbt.xml">
284<!ENTITY sub-demux SYSTEM "dvb/demux.xml">
285<!ENTITY sub-video SYSTEM "dvb/video.xml">
286<!ENTITY sub-audio SYSTEM "dvb/audio.xml">
287<!ENTITY sub-ca SYSTEM "dvb/ca.xml">
288<!ENTITY sub-net SYSTEM "dvb/net.xml">
289<!ENTITY sub-kdapi SYSTEM "dvb/kdapi.xml">
290<!ENTITY sub-examples SYSTEM "dvb/examples.xml">
291<!ENTITY sub-dvbapi SYSTEM "dvb/dvbapi.xml">
292<!ENTITY sub-media SYSTEM "media.xml">
293<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
294<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
295
296<!-- Function Reference -->
297<!ENTITY close SYSTEM "v4l/func-close.xml">
298<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml">
299<!ENTITY mmap SYSTEM "v4l/func-mmap.xml">
300<!ENTITY munmap SYSTEM "v4l/func-munmap.xml">
301<!ENTITY open SYSTEM "v4l/func-open.xml">
302<!ENTITY poll SYSTEM "v4l/func-poll.xml">
303<!ENTITY read SYSTEM "v4l/func-read.xml">
304<!ENTITY select SYSTEM "v4l/func-select.xml">
305<!ENTITY write SYSTEM "v4l/func-write.xml">
306<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml">
307<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml">
308<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml">
309<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
310<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
311<!ENTITY sbggr16 SYSTEM "v4l/pixfmt-sbggr16.xml">
312<!ENTITY sbggr8 SYSTEM "v4l/pixfmt-sbggr8.xml">
313<!ENTITY sgbrg8 SYSTEM "v4l/pixfmt-sgbrg8.xml">
314<!ENTITY sgrbg8 SYSTEM "v4l/pixfmt-sgrbg8.xml">
315<!ENTITY uyvy SYSTEM "v4l/pixfmt-uyvy.xml">
316<!ENTITY vyuy SYSTEM "v4l/pixfmt-vyuy.xml">
317<!ENTITY y16 SYSTEM "v4l/pixfmt-y16.xml">
318<!ENTITY y41p SYSTEM "v4l/pixfmt-y41p.xml">
319<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
320<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
321<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
322<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
323<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
324<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
325<!ENTITY cropcap SYSTEM "v4l/vidioc-cropcap.xml">
326<!ENTITY dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
327<!ENTITY encoder-cmd SYSTEM "v4l/vidioc-encoder-cmd.xml">
328<!ENTITY enum-fmt SYSTEM "v4l/vidioc-enum-fmt.xml">
329<!ENTITY enum-frameintervals SYSTEM "v4l/vidioc-enum-frameintervals.xml">
330<!ENTITY enum-framesizes SYSTEM "v4l/vidioc-enum-framesizes.xml">
331<!ENTITY enumaudio SYSTEM "v4l/vidioc-enumaudio.xml">
332<!ENTITY enumaudioout SYSTEM "v4l/vidioc-enumaudioout.xml">
333<!ENTITY enuminput SYSTEM "v4l/vidioc-enuminput.xml">
334<!ENTITY enumoutput SYSTEM "v4l/vidioc-enumoutput.xml">
335<!ENTITY enumstd SYSTEM "v4l/vidioc-enumstd.xml">
336<!ENTITY g-audio SYSTEM "v4l/vidioc-g-audio.xml">
337<!ENTITY g-audioout SYSTEM "v4l/vidioc-g-audioout.xml">
338<!ENTITY dbg-g-chip-ident SYSTEM "v4l/vidioc-dbg-g-chip-ident.xml">
339<!ENTITY g-crop SYSTEM "v4l/vidioc-g-crop.xml">
340<!ENTITY g-ctrl SYSTEM "v4l/vidioc-g-ctrl.xml">
341<!ENTITY g-enc-index SYSTEM "v4l/vidioc-g-enc-index.xml">
342<!ENTITY g-ext-ctrls SYSTEM "v4l/vidioc-g-ext-ctrls.xml">
343<!ENTITY g-fbuf SYSTEM "v4l/vidioc-g-fbuf.xml">
344<!ENTITY g-fmt SYSTEM "v4l/vidioc-g-fmt.xml">
345<!ENTITY g-frequency SYSTEM "v4l/vidioc-g-frequency.xml">
346<!ENTITY g-input SYSTEM "v4l/vidioc-g-input.xml">
347<!ENTITY g-jpegcomp SYSTEM "v4l/vidioc-g-jpegcomp.xml">
348<!ENTITY g-modulator SYSTEM "v4l/vidioc-g-modulator.xml">
349<!ENTITY g-output SYSTEM "v4l/vidioc-g-output.xml">
350<!ENTITY g-parm SYSTEM "v4l/vidioc-g-parm.xml">
351<!ENTITY g-priority SYSTEM "v4l/vidioc-g-priority.xml">
352<!ENTITY g-sliced-vbi-cap SYSTEM "v4l/vidioc-g-sliced-vbi-cap.xml">
353<!ENTITY g-std SYSTEM "v4l/vidioc-g-std.xml">
354<!ENTITY g-tuner SYSTEM "v4l/vidioc-g-tuner.xml">
355<!ENTITY log-status SYSTEM "v4l/vidioc-log-status.xml">
356<!ENTITY overlay SYSTEM "v4l/vidioc-overlay.xml">
357<!ENTITY qbuf SYSTEM "v4l/vidioc-qbuf.xml">
358<!ENTITY querybuf SYSTEM "v4l/vidioc-querybuf.xml">
359<!ENTITY querycap SYSTEM "v4l/vidioc-querycap.xml">
360<!ENTITY queryctrl SYSTEM "v4l/vidioc-queryctrl.xml">
361<!ENTITY querystd SYSTEM "v4l/vidioc-querystd.xml">
362<!ENTITY reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
363<!ENTITY s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
364<!ENTITY streamon SYSTEM "v4l/vidioc-streamon.xml">
diff --git a/Documentation/DocBook/media-indices.tmpl b/Documentation/DocBook/media-indices.tmpl
new file mode 100644
index 000000000000..9e30a236d74f
--- /dev/null
+++ b/Documentation/DocBook/media-indices.tmpl
@@ -0,0 +1,85 @@
1<!-- Generated file! Do not edit. -->
2
3<index><title>List of Types</title>
4<indexentry><primaryie><link linkend='v4l2-std-id'>v4l2_std_id</link></primaryie></indexentry>
5<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-buf-type'>v4l2_buf_type</link></primaryie></indexentry>
6<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-colorspace'>v4l2_colorspace</link></primaryie></indexentry>
7<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-ctrl-type'>v4l2_ctrl_type</link></primaryie></indexentry>
8<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-exposure-auto-type'>v4l2_exposure_auto_type</link></primaryie></indexentry>
9<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link></primaryie></indexentry>
10<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link></primaryie></indexentry>
11<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link></primaryie></indexentry>
12<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link></primaryie></indexentry>
13<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link></primaryie></indexentry>
14<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link></primaryie></indexentry>
15<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-emphasis'>v4l2_mpeg_audio_emphasis</link></primaryie></indexentry>
16<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-encoding'>v4l2_mpeg_audio_encoding</link></primaryie></indexentry>
17<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l1-bitrate'>v4l2_mpeg_audio_l1_bitrate</link></primaryie></indexentry>
18<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l2-bitrate'>v4l2_mpeg_audio_l2_bitrate</link></primaryie></indexentry>
19<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-l3-bitrate'>v4l2_mpeg_audio_l3_bitrate</link></primaryie></indexentry>
20<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-mode'>v4l2_mpeg_audio_mode</link></primaryie></indexentry>
21<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-mode-extension'>v4l2_mpeg_audio_mode_extension</link></primaryie></indexentry>
22<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-audio-sampling-freq'>v4l2_mpeg_audio_sampling_freq</link></primaryie></indexentry>
23<indexentry><primaryie>enum&nbsp;<link linkend='chroma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link></primaryie></indexentry>
24<indexentry><primaryie>enum&nbsp;<link linkend='luma-spatial-filter-type'>v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link></primaryie></indexentry>
25<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-median-filter-type'>v4l2_mpeg_cx2341x_video_median_filter_type</link></primaryie></indexentry>
26<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-spatial-filter-mode'>v4l2_mpeg_cx2341x_video_spatial_filter_mode</link></primaryie></indexentry>
27<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-cx2341x-video-temporal-filter-mode'>v4l2_mpeg_cx2341x_video_temporal_filter_mode</link></primaryie></indexentry>
28<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-stream-type'>v4l2_mpeg_stream_type</link></primaryie></indexentry>
29<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-stream-vbi-fmt'>v4l2_mpeg_stream_vbi_fmt</link></primaryie></indexentry>
30<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-aspect'>v4l2_mpeg_video_aspect</link></primaryie></indexentry>
31<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-bitrate-mode'>v4l2_mpeg_video_bitrate_mode</link></primaryie></indexentry>
32<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link></primaryie></indexentry>
33<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link></primaryie></indexentry>
34<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link></primaryie></indexentry>
35<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link></primaryie></indexentry>
36<indexentry><primaryie>enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link></primaryie></indexentry>
37<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audio'>v4l2_audio</link></primaryie></indexentry>
38<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link></primaryie></indexentry>
39<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link></primaryie></indexentry>
40<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link></primaryie></indexentry>
41<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link></primaryie></indexentry>
42<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link></primaryie></indexentry>
43<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-control'>v4l2_control</link></primaryie></indexentry>
44<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-crop'>v4l2_crop</link></primaryie></indexentry>
45<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-cropcap'>v4l2_cropcap</link></primaryie></indexentry>
46<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-chip-ident'>v4l2_dbg_chip_ident</link></primaryie></indexentry>
47<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-match'>v4l2_dbg_match</link></primaryie></indexentry>
48<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-dbg-register'>v4l2_dbg_register</link></primaryie></indexentry>
49<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx'>v4l2_enc_idx</link></primaryie></indexentry>
50<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-enc-idx-entry'>v4l2_enc_idx_entry</link></primaryie></indexentry>
51<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-encoder-cmd'>v4l2_encoder_cmd</link></primaryie></indexentry>
52<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-ext-control'>v4l2_ext_control</link></primaryie></indexentry>
53<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-ext-controls'>v4l2_ext_controls</link></primaryie></indexentry>
54<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-fmtdesc'>v4l2_fmtdesc</link></primaryie></indexentry>
55<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-format'>v4l2_format</link></primaryie></indexentry>
56<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-fract'>v4l2_fract</link></primaryie></indexentry>
57<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-framebuffer'>v4l2_framebuffer</link></primaryie></indexentry>
58<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frequency'>v4l2_frequency</link></primaryie></indexentry>
59<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmival-stepwise'>v4l2_frmival_stepwise</link></primaryie></indexentry>
60<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmivalenum'>v4l2_frmivalenum</link></primaryie></indexentry>
61<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsize-discrete'>v4l2_frmsize_discrete</link></primaryie></indexentry>
62<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsize-stepwise'>v4l2_frmsize_stepwise</link></primaryie></indexentry>
63<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-frmsizeenum'>v4l2_frmsizeenum</link></primaryie></indexentry>
64<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link></primaryie></indexentry>
65<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link></primaryie></indexentry>
66<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link></primaryie></indexentry>
67<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link></primaryie></indexentry>
68<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link></primaryie></indexentry>
69<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link></primaryie></indexentry>
70<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link></primaryie></indexentry>
71<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link></primaryie></indexentry>
72<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link></primaryie></indexentry>
73<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link></primaryie></indexentry>
74<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link></primaryie></indexentry>
75<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-requestbuffers'>v4l2_requestbuffers</link></primaryie></indexentry>
76<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link></primaryie></indexentry>
77<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link></primaryie></indexentry>
78<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link></primaryie></indexentry>
79<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link></primaryie></indexentry>
80<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link></primaryie></indexentry>
81<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link></primaryie></indexentry>
82<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-tuner'>v4l2_tuner</link></primaryie></indexentry>
83<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link></primaryie></indexentry>
84<indexentry><primaryie>struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link></primaryie></indexentry>
85</index>
diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
new file mode 100644
index 000000000000..eea564bb12cb
--- /dev/null
+++ b/Documentation/DocBook/media.tmpl
@@ -0,0 +1,112 @@
1<?xml version="1.0"?>
2<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
3 "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" [
4<!ENTITY % media-entities SYSTEM "./media-entities.tmpl"> %media-entities;
5<!ENTITY media-indices SYSTEM "./media-indices.tmpl">
6
7<!ENTITY eg "e.&nbsp;g.">
8<!ENTITY ie "i.&nbsp;e.">
9<!ENTITY fd "File descriptor returned by <link linkend='func-open'><function>open()</function></link>.">
10<!ENTITY i2c "I<superscript>2</superscript>C">
11<!ENTITY return-value "<title>Return Value</title><para>On success <returnvalue>0</returnvalue> is returned, on error <returnvalue>-1</returnvalue> and the <varname>errno</varname> variable is set appropriately:</para>">
12<!ENTITY manvol "<manvolnum>2</manvolnum>">
13
14<!-- Table templates: structs, structs w/union, defines. -->
15<!ENTITY cs-str "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
16<!ENTITY cs-ustr "<colspec colname='c1' colwidth='1*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='1*' /><colspec colname='c4' colwidth='2*' /><spanspec spanname='hspan' namest='c1' nameend='c4' />">
17<!ENTITY cs-def "<colspec colname='c1' colwidth='3*' /><colspec colname='c2' colwidth='1*' /><colspec colname='c3' colwidth='4*' /><spanspec spanname='hspan' namest='c1' nameend='c3' />">
18
19<!-- Video for Linux mailing list address. -->
20<!ENTITY v4l-ml "<ulink url='http://www.linuxtv.org/lists.php'>http://www.linuxtv.org/lists.php</ulink>">
21
22<!-- LinuxTV v4l-dvb repository. -->
23<!ENTITY v4l-dvb "<ulink url='http://linuxtv.org/repo/'>http://linuxtv.org/repo/</ulink>">
24]>
25
26<book id="media_api">
27<bookinfo>
28<title>LINUX MEDIA INFRASTRUCTURE API</title>
29
30<copyright>
31 <year>2009</year>
32 <holder>LinuxTV Developers</holder>
33</copyright>
34
35<legalnotice>
36
37<para>Permission is granted to copy, distribute and/or modify
38this document under the terms of the GNU Free Documentation License,
39Version 1.1 or any later version published by the Free Software
40Foundation. A copy of the license is included in the chapter entitled
41"GNU Free Documentation License"</para>
42</legalnotice>
43
44</bookinfo>
45
46<toc></toc> <!-- autogenerated -->
47
48<preface>
49 <title>Introduction</title>
50
51 <para>This document covers the Linux Kernel to Userspace API's used by
52 video and radio straming devices, including video cameras,
53 analog and digital TV receiver cards, AM/FM receiver cards,
54 streaming capture devices.</para>
55 <para>It is divided into three parts.</para>
56 <para>The first part covers radio, capture,
57 cameras and analog TV devices.</para>
58 <para>The second part covers the
59 API used for digital TV and Internet reception via one of the
60 several digital tv standards. While it is called as DVB API,
61 in fact it covers several different video standards including
62 DVB-T, DVB-S, DVB-C and ATSC. The API is currently being updated
63 to documment support also for DVB-S2, ISDB-T and ISDB-S.</para>
64 <para>The third part covers other API's used by all media infrastructure devices</para>
65 <para>For additional information and for the latest development code,
66 see: <ulink url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
67 <para>For discussing improvements, reporting troubles, sending new drivers, etc, please mail to: <ulink url="http://vger.kernel.org/vger-lists.html#linux-media">Linux Media Mailing List (LMML).</ulink>.</para>
68
69</preface>
70
71<part id="v4l2spec">
72&sub-v4l2;
73</part>
74<part id="dvbapi">
75&sub-dvbapi;
76</part>
77<part id="v4ldvb_common">
78<partinfo>
79<authorgroup>
80<author>
81<firstname>Mauro</firstname>
82<surname>Chehab</surname>
83<othername role="mi">Carvalho</othername>
84<affiliation><address><email>mchehab@redhat.com</email></address></affiliation>
85<contrib>Initial version.</contrib>
86</author>
87</authorgroup>
88<copyright>
89 <year>2009</year>
90 <holder>Mauro Carvalho Chehab</holder>
91</copyright>
92
93<revhistory>
94<!-- Put document revisions here, newest first. -->
95<revision>
96<revnumber>1.0.0</revnumber>
97<date>2009-09-06</date>
98<authorinitials>mcc</authorinitials>
99<revremark>Initial revision</revremark>
100</revision>
101</revhistory>
102</partinfo>
103
104<title>Other API's used by media infrastructure drivers</title>
105<chapter id="remote_controllers">
106&sub-remote_controllers;
107</chapter>
108</part>
109
110&sub-fdl-appendix;
111
112</book>
diff --git a/Documentation/DocBook/stylesheet.xsl b/Documentation/DocBook/stylesheet.xsl
index 974e17ccf106..254c1d5d2e50 100644
--- a/Documentation/DocBook/stylesheet.xsl
+++ b/Documentation/DocBook/stylesheet.xsl
@@ -3,6 +3,7 @@
3<param name="chunk.quietly">1</param> 3<param name="chunk.quietly">1</param>
4<param name="funcsynopsis.style">ansi</param> 4<param name="funcsynopsis.style">ansi</param>
5<param name="funcsynopsis.tabular.threshold">80</param> 5<param name="funcsynopsis.tabular.threshold">80</param>
6<param name="callout.graphics">0</param>
6<!-- <param name="paper.type">A4</param> --> 7<!-- <param name="paper.type">A4</param> -->
7<param name="generate.section.toc.level">2</param> 8<param name="generate.section.toc.level">2</param>
8</stylesheet> 9</stylesheet>
diff --git a/Documentation/DocBook/v4l/.gitignore b/Documentation/DocBook/v4l/.gitignore
new file mode 100644
index 000000000000..d7ec32eafac9
--- /dev/null
+++ b/Documentation/DocBook/v4l/.gitignore
@@ -0,0 +1 @@
!*.xml
diff --git a/Documentation/DocBook/v4l/biblio.xml b/Documentation/DocBook/v4l/biblio.xml
new file mode 100644
index 000000000000..afc8a0dd2601
--- /dev/null
+++ b/Documentation/DocBook/v4l/biblio.xml
@@ -0,0 +1,188 @@
1 <bibliography>
2 <title>References</title>
3
4 <biblioentry id="eia608">
5 <abbrev>EIA&nbsp;608-B</abbrev>
6 <authorgroup>
7 <corpauthor>Electronic Industries Alliance (<ulink
8url="http://www.eia.org">http://www.eia.org</ulink>)</corpauthor>
9 </authorgroup>
10 <title>EIA 608-B "Recommended Practice for Line 21 Data
11Service"</title>
12 </biblioentry>
13
14 <biblioentry id="en300294">
15 <abbrev>EN&nbsp;300&nbsp;294</abbrev>
16 <authorgroup>
17 <corpauthor>European Telecommunication Standards Institute
18(<ulink url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
19 </authorgroup>
20 <title>EN 300 294 "625-line television Wide Screen Signalling
21(WSS)"</title>
22 </biblioentry>
23
24 <biblioentry id="ets300231">
25 <abbrev>ETS&nbsp;300&nbsp;231</abbrev>
26 <authorgroup>
27 <corpauthor>European Telecommunication Standards Institute
28(<ulink
29url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
30 </authorgroup>
31 <title>ETS 300 231 "Specification of the domestic video
32Programme Delivery Control system (PDC)"</title>
33 </biblioentry>
34
35 <biblioentry id="ets300706">
36 <abbrev>ETS&nbsp;300&nbsp;706</abbrev>
37 <authorgroup>
38 <corpauthor>European Telecommunication Standards Institute
39(<ulink url="http://www.etsi.org">http://www.etsi.org</ulink>)</corpauthor>
40 </authorgroup>
41 <title>ETS 300 706 "Enhanced Teletext specification"</title>
42 </biblioentry>
43
44 <biblioentry id="mpeg2part1">
45 <abbrev>ISO&nbsp;13818-1</abbrev>
46 <authorgroup>
47 <corpauthor>International Telecommunication Union (<ulink
48url="http://www.itu.ch">http://www.itu.ch</ulink>), International
49Organisation for Standardisation (<ulink
50url="http://www.iso.ch">http://www.iso.ch</ulink>)</corpauthor>
51 </authorgroup>
52 <title>ITU-T Rec. H.222.0 | ISO/IEC 13818-1 "Information
53technology &mdash; Generic coding of moving pictures and associated
54audio information: Systems"</title>
55 </biblioentry>
56
57 <biblioentry id="mpeg2part2">
58 <abbrev>ISO&nbsp;13818-2</abbrev>
59 <authorgroup>
60 <corpauthor>International Telecommunication Union (<ulink
61url="http://www.itu.ch">http://www.itu.ch</ulink>), International
62Organisation for Standardisation (<ulink
63url="http://www.iso.ch">http://www.iso.ch</ulink>)</corpauthor>
64 </authorgroup>
65 <title>ITU-T Rec. H.262 | ISO/IEC 13818-2 "Information
66technology &mdash; Generic coding of moving pictures and associated
67audio information: Video"</title>
68 </biblioentry>
69
70 <biblioentry id="itu470">
71 <abbrev>ITU&nbsp;BT.470</abbrev>
72 <authorgroup>
73 <corpauthor>International Telecommunication Union (<ulink
74url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
75 </authorgroup>
76 <title>ITU-R Recommendation BT.470-6 "Conventional Television
77Systems"</title>
78 </biblioentry>
79
80 <biblioentry id="itu601">
81 <abbrev>ITU&nbsp;BT.601</abbrev>
82 <authorgroup>
83 <corpauthor>International Telecommunication Union (<ulink
84url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
85 </authorgroup>
86 <title>ITU-R Recommendation BT.601-5 "Studio Encoding Parameters
87of Digital Television for Standard 4:3 and Wide-Screen 16:9 Aspect
88Ratios"</title>
89 </biblioentry>
90
91 <biblioentry id="itu653">
92 <abbrev>ITU&nbsp;BT.653</abbrev>
93 <authorgroup>
94 <corpauthor>International Telecommunication Union (<ulink
95url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
96 </authorgroup>
97 <title>ITU-R Recommendation BT.653-3 "Teletext systems"</title>
98 </biblioentry>
99
100 <biblioentry id="itu709">
101 <abbrev>ITU&nbsp;BT.709</abbrev>
102 <authorgroup>
103 <corpauthor>International Telecommunication Union (<ulink
104url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
105 </authorgroup>
106 <title>ITU-R Recommendation BT.709-5 "Parameter values for the
107HDTV standards for production and international programme
108exchange"</title>
109 </biblioentry>
110
111 <biblioentry id="itu1119">
112 <abbrev>ITU&nbsp;BT.1119</abbrev>
113 <authorgroup>
114 <corpauthor>International Telecommunication Union (<ulink
115url="http://www.itu.ch">http://www.itu.ch</ulink>)</corpauthor>
116 </authorgroup>
117 <title>ITU-R Recommendation BT.1119 "625-line
118television Wide Screen Signalling (WSS)"</title>
119 </biblioentry>
120
121 <biblioentry id="jfif">
122 <abbrev>JFIF</abbrev>
123 <authorgroup>
124 <corpauthor>Independent JPEG Group (<ulink
125url="http://www.ijg.org">http://www.ijg.org</ulink>)</corpauthor>
126 </authorgroup>
127 <title>JPEG File Interchange Format</title>
128 <subtitle>Version 1.02</subtitle>
129 </biblioentry>
130
131 <biblioentry id="smpte12m">
132 <abbrev>SMPTE&nbsp;12M</abbrev>
133 <authorgroup>
134 <corpauthor>Society of Motion Picture and Television Engineers
135(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
136 </authorgroup>
137 <title>SMPTE 12M-1999 "Television, Audio and Film - Time and
138Control Code"</title>
139 </biblioentry>
140
141 <biblioentry id="smpte170m">
142 <abbrev>SMPTE&nbsp;170M</abbrev>
143 <authorgroup>
144 <corpauthor>Society of Motion Picture and Television Engineers
145(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
146 </authorgroup>
147 <title>SMPTE 170M-1999 "Television - Composite Analog Video
148Signal - NTSC for Studio Applications"</title>
149 </biblioentry>
150
151 <biblioentry id="smpte240m">
152 <abbrev>SMPTE&nbsp;240M</abbrev>
153 <authorgroup>
154 <corpauthor>Society of Motion Picture and Television Engineers
155(<ulink url="http://www.smpte.org">http://www.smpte.org</ulink>)</corpauthor>
156 </authorgroup>
157 <title>SMPTE 240M-1999 "Television - Signal Parameters -
1581125-Line High-Definition Production"</title>
159 </biblioentry>
160
161 <biblioentry id="en50067">
162 <abbrev>EN&nbsp;50067</abbrev>
163 <authorgroup>
164 <corpauthor>European Committee for Electrotechnical Standardization
165(<ulink url="http://www.cenelec.eu">http://www.cenelec.eu</ulink>)</corpauthor>
166 </authorgroup>
167 <title>Specification of the radio data system (RDS) for VHF/FM sound broadcasting
168in the frequency range from 87,5 to 108,0 MHz</title>
169 </biblioentry>
170
171 <biblioentry id="nrsc4">
172 <abbrev>NRSC-4</abbrev>
173 <authorgroup>
174 <corpauthor>National Radio Systems Committee
175(<ulink url="http://www.nrscstandards.org">http://www.nrscstandards.org</ulink>)</corpauthor>
176 </authorgroup>
177 <title>NTSC-4: United States RBDS Standard</title>
178 </biblioentry>
179
180 </bibliography>
181
182 <!--
183Local Variables:
184mode: sgml
185sgml-parent-document: "v4l2.sgml"
186indent-tabs-mode: nil
187End:
188 -->
diff --git a/Documentation/DocBook/v4l/capture.c.xml b/Documentation/DocBook/v4l/capture.c.xml
new file mode 100644
index 000000000000..1c5c49a2de59
--- /dev/null
+++ b/Documentation/DocBook/v4l/capture.c.xml
@@ -0,0 +1,659 @@
1<programlisting>
2/*
3 * V4L2 video capture example
4 *
5 * This program can be used and distributed without restrictions.
6 *
7 * This program is provided with the V4L2 API
8 * see http://linuxtv.org/docs.php for more information
9 */
10
11#include &lt;stdio.h&gt;
12#include &lt;stdlib.h&gt;
13#include &lt;string.h&gt;
14#include &lt;assert.h&gt;
15
16#include &lt;getopt.h&gt; /* getopt_long() */
17
18#include &lt;fcntl.h&gt; /* low-level i/o */
19#include &lt;unistd.h&gt;
20#include &lt;errno.h&gt;
21#include &lt;sys/stat.h&gt;
22#include &lt;sys/types.h&gt;
23#include &lt;sys/time.h&gt;
24#include &lt;sys/mman.h&gt;
25#include &lt;sys/ioctl.h&gt;
26
27#include &lt;linux/videodev2.h&gt;
28
29#define CLEAR(x) memset(&amp;(x), 0, sizeof(x))
30
31enum io_method {
32 IO_METHOD_READ,
33 IO_METHOD_MMAP,
34 IO_METHOD_USERPTR,
35};
36
37struct buffer {
38 void *start;
39 size_t length;
40};
41
42static char *dev_name;
43static enum io_method io = IO_METHOD_MMAP;
44static int fd = -1;
45struct buffer *buffers;
46static unsigned int n_buffers;
47static int out_buf;
48static int force_format;
49static int frame_count = 70;
50
51static void errno_exit(const char *s)
52{
53 fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno));
54 exit(EXIT_FAILURE);
55}
56
57static int xioctl(int fh, int request, void *arg)
58{
59 int r;
60
61 do {
62 r = ioctl(fh, request, arg);
63 } while (-1 == r &amp;&amp; EINTR == errno);
64
65 return r;
66}
67
68static void process_image(const void *p, int size)
69{
70 if (out_buf)
71 fwrite(p, size, 1, stdout);
72
73 fflush(stderr);
74 fprintf(stderr, ".");
75 fflush(stdout);
76}
77
78static int read_frame(void)
79{
80 struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
81 unsigned int i;
82
83 switch (io) {
84 case IO_METHOD_READ:
85 if (-1 == read(fd, buffers[0].start, buffers[0].length)) {
86 switch (errno) {
87 case EAGAIN:
88 return 0;
89
90 case EIO:
91 /* Could ignore EIO, see spec. */
92
93 /* fall through */
94
95 default:
96 errno_exit("read");
97 }
98 }
99
100 process_image(buffers[0].start, buffers[0].length);
101 break;
102
103 case IO_METHOD_MMAP:
104 CLEAR(buf);
105
106 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
107 buf.memory = V4L2_MEMORY_MMAP;
108
109 if (-1 == xioctl(fd, VIDIOC_DQBUF, &amp;buf)) {
110 switch (errno) {
111 case EAGAIN:
112 return 0;
113
114 case EIO:
115 /* Could ignore EIO, see spec. */
116
117 /* fall through */
118
119 default:
120 errno_exit("VIDIOC_DQBUF");
121 }
122 }
123
124 assert(buf.index &lt; n_buffers);
125
126 process_image(buffers[buf.index].start, buf.bytesused);
127
128 if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
129 errno_exit("VIDIOC_QBUF");
130 break;
131
132 case IO_METHOD_USERPTR:
133 CLEAR(buf);
134
135 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
136 buf.memory = V4L2_MEMORY_USERPTR;
137
138 if (-1 == xioctl(fd, VIDIOC_DQBUF, &amp;buf)) {
139 switch (errno) {
140 case EAGAIN:
141 return 0;
142
143 case EIO:
144 /* Could ignore EIO, see spec. */
145
146 /* fall through */
147
148 default:
149 errno_exit("VIDIOC_DQBUF");
150 }
151 }
152
153 for (i = 0; i &lt; n_buffers; ++i)
154 if (buf.m.userptr == (unsigned long)buffers[i].start
155 &amp;&amp; buf.length == buffers[i].length)
156 break;
157
158 assert(i &lt; n_buffers);
159
160 process_image((void *)buf.m.userptr, buf.bytesused);
161
162 if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
163 errno_exit("VIDIOC_QBUF");
164 break;
165 }
166
167 return 1;
168}
169
170static void mainloop(void)
171{
172 unsigned int count;
173
174 count = frame_count;
175
176 while (count-- &gt; 0) {
177 for (;;) {
178 fd_set fds;
179 struct timeval tv;
180 int r;
181
182 FD_ZERO(&amp;fds);
183 FD_SET(fd, &amp;fds);
184
185 /* Timeout. */
186 tv.tv_sec = 2;
187 tv.tv_usec = 0;
188
189 r = select(fd + 1, &amp;fds, NULL, NULL, &amp;tv);
190
191 if (-1 == r) {
192 if (EINTR == errno)
193 continue;
194 errno_exit("select");
195 }
196
197 if (0 == r) {
198 fprintf(stderr, "select timeout\n");
199 exit(EXIT_FAILURE);
200 }
201
202 if (read_frame())
203 break;
204 /* EAGAIN - continue select loop. */
205 }
206 }
207}
208
209static void stop_capturing(void)
210{
211 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
212
213 switch (io) {
214 case IO_METHOD_READ:
215 /* Nothing to do. */
216 break;
217
218 case IO_METHOD_MMAP:
219 case IO_METHOD_USERPTR:
220 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
221 if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &amp;type))
222 errno_exit("VIDIOC_STREAMOFF");
223 break;
224 }
225}
226
227static void start_capturing(void)
228{
229 unsigned int i;
230 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
231
232 switch (io) {
233 case IO_METHOD_READ:
234 /* Nothing to do. */
235 break;
236
237 case IO_METHOD_MMAP:
238 for (i = 0; i &lt; n_buffers; ++i) {
239 struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
240
241 CLEAR(buf);
242 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
243 buf.memory = V4L2_MEMORY_MMAP;
244 buf.index = i;
245
246 if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
247 errno_exit("VIDIOC_QBUF");
248 }
249 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
250 if (-1 == xioctl(fd, VIDIOC_STREAMON, &amp;type))
251 errno_exit("VIDIOC_STREAMON");
252 break;
253
254 case IO_METHOD_USERPTR:
255 for (i = 0; i &lt; n_buffers; ++i) {
256 struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
257
258 CLEAR(buf);
259 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
260 buf.memory = V4L2_MEMORY_USERPTR;
261 buf.index = i;
262 buf.m.userptr = (unsigned long)buffers[i].start;
263 buf.length = buffers[i].length;
264
265 if (-1 == xioctl(fd, VIDIOC_QBUF, &amp;buf))
266 errno_exit("VIDIOC_QBUF");
267 }
268 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
269 if (-1 == xioctl(fd, VIDIOC_STREAMON, &amp;type))
270 errno_exit("VIDIOC_STREAMON");
271 break;
272 }
273}
274
275static void uninit_device(void)
276{
277 unsigned int i;
278
279 switch (io) {
280 case IO_METHOD_READ:
281 free(buffers[0].start);
282 break;
283
284 case IO_METHOD_MMAP:
285 for (i = 0; i &lt; n_buffers; ++i)
286 if (-1 == munmap(buffers[i].start, buffers[i].length))
287 errno_exit("munmap");
288 break;
289
290 case IO_METHOD_USERPTR:
291 for (i = 0; i &lt; n_buffers; ++i)
292 free(buffers[i].start);
293 break;
294 }
295
296 free(buffers);
297}
298
299static void init_read(unsigned int buffer_size)
300{
301 buffers = calloc(1, sizeof(*buffers));
302
303 if (!buffers) {
304 fprintf(stderr, "Out of memory\n");
305 exit(EXIT_FAILURE);
306 }
307
308 buffers[0].length = buffer_size;
309 buffers[0].start = malloc(buffer_size);
310
311 if (!buffers[0].start) {
312 fprintf(stderr, "Out of memory\n");
313 exit(EXIT_FAILURE);
314 }
315}
316
317static void init_mmap(void)
318{
319 struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> req;
320
321 CLEAR(req);
322
323 req.count = 4;
324 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
325 req.memory = V4L2_MEMORY_MMAP;
326
327 if (-1 == xioctl(fd, VIDIOC_REQBUFS, &amp;req)) {
328 if (EINVAL == errno) {
329 fprintf(stderr, "%s does not support "
330 "memory mapping\n", dev_name);
331 exit(EXIT_FAILURE);
332 } else {
333 errno_exit("VIDIOC_REQBUFS");
334 }
335 }
336
337 if (req.count &lt; 2) {
338 fprintf(stderr, "Insufficient buffer memory on %s\n",
339 dev_name);
340 exit(EXIT_FAILURE);
341 }
342
343 buffers = calloc(req.count, sizeof(*buffers));
344
345 if (!buffers) {
346 fprintf(stderr, "Out of memory\n");
347 exit(EXIT_FAILURE);
348 }
349
350 for (n_buffers = 0; n_buffers &lt; req.count; ++n_buffers) {
351 struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
352
353 CLEAR(buf);
354
355 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
356 buf.memory = V4L2_MEMORY_MMAP;
357 buf.index = n_buffers;
358
359 if (-1 == xioctl(fd, VIDIOC_QUERYBUF, &amp;buf))
360 errno_exit("VIDIOC_QUERYBUF");
361
362 buffers[n_buffers].length = buf.length;
363 buffers[n_buffers].start =
364 mmap(NULL /* start anywhere */,
365 buf.length,
366 PROT_READ | PROT_WRITE /* required */,
367 MAP_SHARED /* recommended */,
368 fd, buf.m.offset);
369
370 if (MAP_FAILED == buffers[n_buffers].start)
371 errno_exit("mmap");
372 }
373}
374
375static void init_userp(unsigned int buffer_size)
376{
377 struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> req;
378
379 CLEAR(req);
380
381 req.count = 4;
382 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
383 req.memory = V4L2_MEMORY_USERPTR;
384
385 if (-1 == xioctl(fd, VIDIOC_REQBUFS, &amp;req)) {
386 if (EINVAL == errno) {
387 fprintf(stderr, "%s does not support "
388 "user pointer i/o\n", dev_name);
389 exit(EXIT_FAILURE);
390 } else {
391 errno_exit("VIDIOC_REQBUFS");
392 }
393 }
394
395 buffers = calloc(4, sizeof(*buffers));
396
397 if (!buffers) {
398 fprintf(stderr, "Out of memory\n");
399 exit(EXIT_FAILURE);
400 }
401
402 for (n_buffers = 0; n_buffers &lt; 4; ++n_buffers) {
403 buffers[n_buffers].length = buffer_size;
404 buffers[n_buffers].start = malloc(buffer_size);
405
406 if (!buffers[n_buffers].start) {
407 fprintf(stderr, "Out of memory\n");
408 exit(EXIT_FAILURE);
409 }
410 }
411}
412
413static void init_device(void)
414{
415 struct <link linkend="v4l2-capability">v4l2_capability</link> cap;
416 struct <link linkend="v4l2-cropcap">v4l2_cropcap</link> cropcap;
417 struct <link linkend="v4l2-crop">v4l2_crop</link> crop;
418 struct <link linkend="v4l2-format">v4l2_format</link> fmt;
419 unsigned int min;
420
421 if (-1 == xioctl(fd, VIDIOC_QUERYCAP, &amp;cap)) {
422 if (EINVAL == errno) {
423 fprintf(stderr, "%s is no V4L2 device\n",
424 dev_name);
425 exit(EXIT_FAILURE);
426 } else {
427 errno_exit("VIDIOC_QUERYCAP");
428 }
429 }
430
431 if (!(cap.capabilities &amp; V4L2_CAP_VIDEO_CAPTURE)) {
432 fprintf(stderr, "%s is no video capture device\n",
433 dev_name);
434 exit(EXIT_FAILURE);
435 }
436
437 switch (io) {
438 case IO_METHOD_READ:
439 if (!(cap.capabilities &amp; V4L2_CAP_READWRITE)) {
440 fprintf(stderr, "%s does not support read i/o\n",
441 dev_name);
442 exit(EXIT_FAILURE);
443 }
444 break;
445
446 case IO_METHOD_MMAP:
447 case IO_METHOD_USERPTR:
448 if (!(cap.capabilities &amp; V4L2_CAP_STREAMING)) {
449 fprintf(stderr, "%s does not support streaming i/o\n",
450 dev_name);
451 exit(EXIT_FAILURE);
452 }
453 break;
454 }
455
456
457 /* Select video input, video standard and tune here. */
458
459
460 CLEAR(cropcap);
461
462 cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
463
464 if (0 == xioctl(fd, VIDIOC_CROPCAP, &amp;cropcap)) {
465 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
466 crop.c = cropcap.defrect; /* reset to default */
467
468 if (-1 == xioctl(fd, VIDIOC_S_CROP, &amp;crop)) {
469 switch (errno) {
470 case EINVAL:
471 /* Cropping not supported. */
472 break;
473 default:
474 /* Errors ignored. */
475 break;
476 }
477 }
478 } else {
479 /* Errors ignored. */
480 }
481
482
483 CLEAR(fmt);
484
485 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
486 if (force_format) {
487 fmt.fmt.pix.width = 640;
488 fmt.fmt.pix.height = 480;
489 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
490 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
491
492 if (-1 == xioctl(fd, VIDIOC_S_FMT, &amp;fmt))
493 errno_exit("VIDIOC_S_FMT");
494
495 /* Note VIDIOC_S_FMT may change width and height. */
496 } else {
497 /* Preserve original settings as set by v4l2-ctl for example */
498 if (-1 == xioctl(fd, VIDIOC_G_FMT, &amp;fmt))
499 errno_exit("VIDIOC_G_FMT");
500 }
501
502 /* Buggy driver paranoia. */
503 min = fmt.fmt.pix.width * 2;
504 if (fmt.fmt.pix.bytesperline &lt; min)
505 fmt.fmt.pix.bytesperline = min;
506 min = fmt.fmt.pix.bytesperline * fmt.fmt.pix.height;
507 if (fmt.fmt.pix.sizeimage &lt; min)
508 fmt.fmt.pix.sizeimage = min;
509
510 switch (io) {
511 case IO_METHOD_READ:
512 init_read(fmt.fmt.pix.sizeimage);
513 break;
514
515 case IO_METHOD_MMAP:
516 init_mmap();
517 break;
518
519 case IO_METHOD_USERPTR:
520 init_userp(fmt.fmt.pix.sizeimage);
521 break;
522 }
523}
524
525static void close_device(void)
526{
527 if (-1 == close(fd))
528 errno_exit("close");
529
530 fd = -1;
531}
532
533static void open_device(void)
534{
535 struct stat st;
536
537 if (-1 == stat(dev_name, &amp;st)) {
538 fprintf(stderr, "Cannot identify '%s': %d, %s\n",
539 dev_name, errno, strerror(errno));
540 exit(EXIT_FAILURE);
541 }
542
543 if (!S_ISCHR(st.st_mode)) {
544 fprintf(stderr, "%s is no device\n", dev_name);
545 exit(EXIT_FAILURE);
546 }
547
548 fd = open(dev_name, O_RDWR /* required */ | O_NONBLOCK, 0);
549
550 if (-1 == fd) {
551 fprintf(stderr, "Cannot open '%s': %d, %s\n",
552 dev_name, errno, strerror(errno));
553 exit(EXIT_FAILURE);
554 }
555}
556
557static void usage(FILE *fp, int argc, char **argv)
558{
559 fprintf(fp,
560 "Usage: %s [options]\n\n"
561 "Version 1.3\n"
562 "Options:\n"
563 "-d | --device name Video device name [%s]\n"
564 "-h | --help Print this message\n"
565 "-m | --mmap Use memory mapped buffers [default]\n"
566 "-r | --read Use read() calls\n"
567 "-u | --userp Use application allocated buffers\n"
568 "-o | --output Outputs stream to stdout\n"
569 "-f | --format Force format to 640x480 YUYV\n"
570 "-c | --count Number of frames to grab [%i]\n"
571 "",
572 argv[0], dev_name, frame_count);
573}
574
575static const char short_options[] = "d:hmruofc:";
576
577static const struct option
578long_options[] = {
579 { "device", required_argument, NULL, 'd' },
580 { "help", no_argument, NULL, 'h' },
581 { "mmap", no_argument, NULL, 'm' },
582 { "read", no_argument, NULL, 'r' },
583 { "userp", no_argument, NULL, 'u' },
584 { "output", no_argument, NULL, 'o' },
585 { "format", no_argument, NULL, 'f' },
586 { "count", required_argument, NULL, 'c' },
587 { 0, 0, 0, 0 }
588};
589
590int main(int argc, char **argv)
591{
592 dev_name = "/dev/video0";
593
594 for (;;) {
595 int idx;
596 int c;
597
598 c = getopt_long(argc, argv,
599 short_options, long_options, &amp;idx);
600
601 if (-1 == c)
602 break;
603
604 switch (c) {
605 case 0: /* getopt_long() flag */
606 break;
607
608 case 'd':
609 dev_name = optarg;
610 break;
611
612 case 'h':
613 usage(stdout, argc, argv);
614 exit(EXIT_SUCCESS);
615
616 case 'm':
617 io = IO_METHOD_MMAP;
618 break;
619
620 case 'r':
621 io = IO_METHOD_READ;
622 break;
623
624 case 'u':
625 io = IO_METHOD_USERPTR;
626 break;
627
628 case 'o':
629 out_buf++;
630 break;
631
632 case 'f':
633 force_format++;
634 break;
635
636 case 'c':
637 errno = 0;
638 frame_count = strtol(optarg, NULL, 0);
639 if (errno)
640 errno_exit(optarg);
641 break;
642
643 default:
644 usage(stderr, argc, argv);
645 exit(EXIT_FAILURE);
646 }
647 }
648
649 open_device();
650 init_device();
651 start_capturing();
652 mainloop();
653 stop_capturing();
654 uninit_device();
655 close_device();
656 fprintf(stderr, "\n");
657 return 0;
658}
659</programlisting>
diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml
new file mode 100644
index 000000000000..b1a81d246d58
--- /dev/null
+++ b/Documentation/DocBook/v4l/common.xml
@@ -0,0 +1,1160 @@
1 <title>Common API Elements</title>
2
3 <para>Programming a V4L2 device consists of these
4steps:</para>
5
6 <itemizedlist>
7 <listitem>
8 <para>Opening the device</para>
9 </listitem>
10 <listitem>
11 <para>Changing device properties, selecting a video and audio
12input, video standard, picture brightness a.&nbsp;o.</para>
13 </listitem>
14 <listitem>
15 <para>Negotiating a data format</para>
16 </listitem>
17 <listitem>
18 <para>Negotiating an input/output method</para>
19 </listitem>
20 <listitem>
21 <para>The actual input/output loop</para>
22 </listitem>
23 <listitem>
24 <para>Closing the device</para>
25 </listitem>
26 </itemizedlist>
27
28 <para>In practice most steps are optional and can be executed out of
29order. It depends on the V4L2 device type, you can read about the
30details in <xref linkend="devices" />. In this chapter we will discuss
31the basic concepts applicable to all devices.</para>
32
33 <section id="open">
34 <title>Opening and Closing Devices</title>
35
36 <section>
37 <title>Device Naming</title>
38
39 <para>V4L2 drivers are implemented as kernel modules, loaded
40manually by the system administrator or automatically when a device is
41first opened. The driver modules plug into the "videodev" kernel
42module. It provides helper functions and a common application
43interface specified in this document.</para>
44
45 <para>Each driver thus loaded registers one or more device nodes
46with major number 81 and a minor number between 0 and 255. Assigning
47minor numbers to V4L2 devices is entirely up to the system administrator,
48this is primarily intended to solve conflicts between devices.<footnote>
49 <para>Access permissions are associated with character
50device special files, hence we must ensure device numbers cannot
51change with the module load order. To this end minor numbers are no
52longer automatically assigned by the "videodev" module as in V4L but
53requested by the driver. The defaults will suffice for most people
54unless two drivers compete for the same minor numbers.</para>
55 </footnote> The module options to select minor numbers are named
56after the device special file with a "_nr" suffix. For example "video_nr"
57for <filename>/dev/video</filename> video capture devices. The number is
58an offset to the base minor number associated with the device type.
59<footnote>
60 <para>In earlier versions of the V4L2 API the module options
61where named after the device special file with a "unit_" prefix, expressing
62the minor number itself, not an offset. Rationale for this change is unknown.
63Lastly the naming and semantics are just a convention among driver writers,
64the point to note is that minor numbers are not supposed to be hardcoded
65into drivers.</para>
66 </footnote> When the driver supports multiple devices of the same
67type more than one minor number can be assigned, separated by commas:
68<informalexample>
69 <screen>
70&gt; insmod mydriver.o video_nr=0,1 radio_nr=0,1</screen>
71 </informalexample></para>
72
73 <para>In <filename>/etc/modules.conf</filename> this may be
74written as: <informalexample>
75 <screen>
76alias char-major-81-0 mydriver
77alias char-major-81-1 mydriver
78alias char-major-81-64 mydriver <co id="alias" />
79options mydriver video_nr=0,1 radio_nr=0,1 <co id="options" />
80 </screen>
81 <calloutlist>
82 <callout arearefs="alias">
83 <para>When an application attempts to open a device
84special file with major number 81 and minor number 0, 1, or 64, load
85"mydriver" (and the "videodev" module it depends upon).</para>
86 </callout>
87 <callout arearefs="options">
88 <para>Register the first two video capture devices with
89minor number 0 and 1 (base number is 0), the first two radio device
90with minor number 64 and 65 (base 64).</para>
91 </callout>
92 </calloutlist>
93 </informalexample> When no minor number is given as module
94option the driver supplies a default. <xref linkend="devices" />
95recommends the base minor numbers to be used for the various device
96types. Obviously minor numbers must be unique. When the number is
97already in use the <emphasis>offending device</emphasis> will not be
98registered. <!-- Blessed by Linus Torvalds on
99linux-kernel@vger.kernel.org, 2002-11-20. --></para>
100
101 <para>By convention system administrators create various
102character device special files with these major and minor numbers in
103the <filename>/dev</filename> directory. The names recomended for the
104different V4L2 device types are listed in <xref linkend="devices" />.
105</para>
106
107 <para>The creation of character special files (with
108<application>mknod</application>) is a privileged operation and
109devices cannot be opened by major and minor number. That means
110applications cannot <emphasis>reliable</emphasis> scan for loaded or
111installed drivers. The user must enter a device name, or the
112application can try the conventional device names.</para>
113
114 <para>Under the device filesystem (devfs) the minor number
115options are ignored. V4L2 drivers (or by proxy the "videodev" module)
116automatically create the required device files in the
117<filename>/dev/v4l</filename> directory using the conventional device
118names above.</para>
119 </section>
120
121 <section id="related">
122 <title>Related Devices</title>
123
124 <para>Devices can support several related functions. For example
125video capturing, video overlay and VBI capturing are related because
126these functions share, amongst other, the same video input and tuner
127frequency. V4L and earlier versions of V4L2 used the same device name
128and minor number for video capturing and overlay, but different ones
129for VBI. Experience showed this approach has several problems<footnote>
130 <para>Given a device file name one cannot reliable find
131related devices. For once names are arbitrary and in a system with
132multiple devices, where only some support VBI capturing, a
133<filename>/dev/video2</filename> is not necessarily related to
134<filename>/dev/vbi2</filename>. The V4L
135<constant>VIDIOCGUNIT</constant> ioctl would require a search for a
136device file with a particular major and minor number.</para>
137 </footnote>, and to make things worse the V4L videodev module
138used to prohibit multiple opens of a device.</para>
139
140 <para>As a remedy the present version of the V4L2 API relaxed the
141concept of device types with specific names and minor numbers. For
142compatibility with old applications drivers must still register different
143minor numbers to assign a default function to the device. But if related
144functions are supported by the driver they must be available under all
145registered minor numbers. The desired function can be selected after
146opening the device as described in <xref linkend="devices" />.</para>
147
148 <para>Imagine a driver supporting video capturing, video
149overlay, raw VBI capturing, and FM radio reception. It registers three
150devices with minor number 0, 64 and 224 (this numbering scheme is
151inherited from the V4L API). Regardless if
152<filename>/dev/video</filename> (81, 0) or
153<filename>/dev/vbi</filename> (81, 224) is opened the application can
154select any one of the video capturing, overlay or VBI capturing
155functions. Without programming (e.&nbsp;g. reading from the device
156with <application>dd</application> or <application>cat</application>)
157<filename>/dev/video</filename> captures video images, while
158<filename>/dev/vbi</filename> captures raw VBI data.
159<filename>/dev/radio</filename> (81, 64) is invariable a radio device,
160unrelated to the video functions. Being unrelated does not imply the
161devices can be used at the same time, however. The &func-open;
162function may very well return an &EBUSY;.</para>
163
164 <para>Besides video input or output the hardware may also
165support audio sampling or playback. If so, these functions are
166implemented as OSS or ALSA PCM devices and eventually OSS or ALSA
167audio mixer. The V4L2 API makes no provisions yet to find these
168related devices. If you have an idea please write to the linux-media
169mailing list: &v4l-ml;.</para>
170 </section>
171
172 <section>
173 <title>Multiple Opens</title>
174
175 <para>In general, V4L2 devices can be opened more than once.
176When this is supported by the driver, users can for example start a
177"panel" application to change controls like brightness or audio
178volume, while another application captures video and audio. In other words, panel
179applications are comparable to an OSS or ALSA audio mixer application.
180When a device supports multiple functions like capturing and overlay
181<emphasis>simultaneously</emphasis>, multiple opens allow concurrent
182use of the device by forked processes or specialized applications.</para>
183
184 <para>Multiple opens are optional, although drivers should
185permit at least concurrent accesses without data exchange, &ie; panel
186applications. This implies &func-open; can return an &EBUSY; when the
187device is already in use, as well as &func-ioctl; functions initiating
188data exchange (namely the &VIDIOC-S-FMT; ioctl), and the &func-read;
189and &func-write; functions.</para>
190
191 <para>Mere opening a V4L2 device does not grant exclusive
192access.<footnote>
193 <para>Drivers could recognize the
194<constant>O_EXCL</constant> open flag. Presently this is not required,
195so applications cannot know if it really works.</para>
196 </footnote> Initiating data exchange however assigns the right
197to read or write the requested type of data, and to change related
198properties, to this file descriptor. Applications can request
199additional access privileges using the priority mechanism described in
200<xref linkend="app-pri" />.</para>
201 </section>
202
203 <section>
204 <title>Shared Data Streams</title>
205
206 <para>V4L2 drivers should not support multiple applications
207reading or writing the same data stream on a device by copying
208buffers, time multiplexing or similar means. This is better handled by
209a proxy application in user space. When the driver supports stream
210sharing anyway it must be implemented transparently. The V4L2 API does
211not specify how conflicts are solved. <!-- For example O_EXCL when the
212application does not want to be preempted, PROT_READ mmapped buffers
213which can be mapped twice, what happens when image formats do not
214match etc.--></para>
215 </section>
216
217 <section>
218 <title>Functions</title>
219
220 <para>To open and close V4L2 devices applications use the
221&func-open; and &func-close; function, respectively. Devices are
222programmed using the &func-ioctl; function as explained in the
223following sections.</para>
224 </section>
225 </section>
226
227 <section id="querycap">
228 <title>Querying Capabilities</title>
229
230 <para>Because V4L2 covers a wide variety of devices not all
231aspects of the API are equally applicable to all types of devices.
232Furthermore devices of the same type have different capabilities and
233this specification permits the omission of a few complicated and less
234important parts of the API.</para>
235
236 <para>The &VIDIOC-QUERYCAP; ioctl is available to check if the kernel
237device is compatible with this specification, and to query the <link
238linkend="devices">functions</link> and <link linkend="io">I/O
239methods</link> supported by the device. Other features can be queried
240by calling the respective ioctl, for example &VIDIOC-ENUMINPUT;
241to learn about the number, types and names of video connectors on the
242device. Although abstraction is a major objective of this API, the
243ioctl also allows driver specific applications to reliable identify
244the driver.</para>
245
246 <para>All V4L2 drivers must support
247<constant>VIDIOC_QUERYCAP</constant>. Applications should always call
248this ioctl after opening the device.</para>
249 </section>
250
251 <section id="app-pri">
252 <title>Application Priority</title>
253
254 <para>When multiple applications share a device it may be
255desirable to assign them different priorities. Contrary to the
256traditional "rm -rf /" school of thought a video recording application
257could for example block other applications from changing video
258controls or switching the current TV channel. Another objective is to
259permit low priority applications working in background, which can be
260preempted by user controlled applications and automatically regain
261control of the device at a later time.</para>
262
263 <para>Since these features cannot be implemented entirely in user
264space V4L2 defines the &VIDIOC-G-PRIORITY; and &VIDIOC-S-PRIORITY;
265ioctls to request and query the access priority associate with a file
266descriptor. Opening a device assigns a medium priority, compatible
267with earlier versions of V4L2 and drivers not supporting these ioctls.
268Applications requiring a different priority will usually call
269<constant>VIDIOC_S_PRIORITY</constant> after verifying the device with
270the &VIDIOC-QUERYCAP; ioctl.</para>
271
272 <para>Ioctls changing driver properties, such as &VIDIOC-S-INPUT;,
273return an &EBUSY; after another application obtained higher priority.
274An event mechanism to notify applications about asynchronous property
275changes has been proposed but not added yet.</para>
276 </section>
277
278 <section id="video">
279 <title>Video Inputs and Outputs</title>
280
281 <para>Video inputs and outputs are physical connectors of a
282device. These can be for example RF connectors (antenna/cable), CVBS
283a.k.a. Composite Video, S-Video or RGB connectors. Only video and VBI
284capture devices have inputs, output devices have outputs, at least one
285each. Radio devices have no video inputs or outputs.</para>
286
287 <para>To learn about the number and attributes of the
288available inputs and outputs applications can enumerate them with the
289&VIDIOC-ENUMINPUT; and &VIDIOC-ENUMOUTPUT; ioctl, respectively. The
290&v4l2-input; returned by the <constant>VIDIOC_ENUMINPUT</constant>
291ioctl also contains signal status information applicable when the
292current video input is queried.</para>
293
294 <para>The &VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; ioctl return the
295index of the current video input or output. To select a different
296input or output applications call the &VIDIOC-S-INPUT; and
297&VIDIOC-S-OUTPUT; ioctl. Drivers must implement all the input ioctls
298when the device has one or more inputs, all the output ioctls when the
299device has one or more outputs.</para>
300
301 <!--
302 <figure id=io-tree>
303 <title>Input and output enumeration is the root of most device properties.</title>
304 <mediaobject>
305 <imageobject>
306 <imagedata fileref="links.pdf" format="ps" />
307 </imageobject>
308 <imageobject>
309 <imagedata fileref="links.gif" format="gif" />
310 </imageobject>
311 <textobject>
312 <phrase>Links between various device property structures.</phrase>
313 </textobject>
314 </mediaobject>
315 </figure>
316 -->
317
318 <example>
319 <title>Information about the current video input</title>
320
321 <programlisting>
322&v4l2-input; input;
323int index;
324
325if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;index)) {
326 perror ("VIDIOC_G_INPUT");
327 exit (EXIT_FAILURE);
328}
329
330memset (&amp;input, 0, sizeof (input));
331input.index = index;
332
333if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
334 perror ("VIDIOC_ENUMINPUT");
335 exit (EXIT_FAILURE);
336}
337
338printf ("Current input: %s\n", input.name);
339 </programlisting>
340 </example>
341
342 <example>
343 <title>Switching to the first video input</title>
344
345 <programlisting>
346int index;
347
348index = 0;
349
350if (-1 == ioctl (fd, &VIDIOC-S-INPUT;, &amp;index)) {
351 perror ("VIDIOC_S_INPUT");
352 exit (EXIT_FAILURE);
353}
354 </programlisting>
355 </example>
356 </section>
357
358 <section id="audio">
359 <title>Audio Inputs and Outputs</title>
360
361 <para>Audio inputs and outputs are physical connectors of a
362device. Video capture devices have inputs, output devices have
363outputs, zero or more each. Radio devices have no audio inputs or
364outputs. They have exactly one tuner which in fact
365<emphasis>is</emphasis> an audio source, but this API associates
366tuners with video inputs or outputs only, and radio devices have
367none of these.<footnote>
368 <para>Actually &v4l2-audio; ought to have a
369<structfield>tuner</structfield> field like &v4l2-input;, not only
370making the API more consistent but also permitting radio devices with
371multiple tuners.</para>
372 </footnote> A connector on a TV card to loop back the received
373audio signal to a sound card is not considered an audio output.</para>
374
375 <para>Audio and video inputs and outputs are associated. Selecting
376a video source also selects an audio source. This is most evident when
377the video and audio source is a tuner. Further audio connectors can
378combine with more than one video input or output. Assumed two
379composite video inputs and two audio inputs exist, there may be up to
380four valid combinations. The relation of video and audio connectors
381is defined in the <structfield>audioset</structfield> field of the
382respective &v4l2-input; or &v4l2-output;, where each bit represents
383the index number, starting at zero, of one audio input or output.</para>
384
385 <para>To learn about the number and attributes of the
386available inputs and outputs applications can enumerate them with the
387&VIDIOC-ENUMAUDIO; and &VIDIOC-ENUMAUDOUT; ioctl, respectively. The
388&v4l2-audio; returned by the <constant>VIDIOC_ENUMAUDIO</constant> ioctl
389also contains signal status information applicable when the current
390audio input is queried.</para>
391
392 <para>The &VIDIOC-G-AUDIO; and &VIDIOC-G-AUDOUT; ioctl report
393the current audio input and output, respectively. Note that, unlike
394&VIDIOC-G-INPUT; and &VIDIOC-G-OUTPUT; these ioctls return a structure
395as <constant>VIDIOC_ENUMAUDIO</constant> and
396<constant>VIDIOC_ENUMAUDOUT</constant> do, not just an index.</para>
397
398 <para>To select an audio input and change its properties
399applications call the &VIDIOC-S-AUDIO; ioctl. To select an audio
400output (which presently has no changeable properties) applications
401call the &VIDIOC-S-AUDOUT; ioctl.</para>
402
403 <para>Drivers must implement all input ioctls when the device
404has one or more inputs, all output ioctls when the device has one
405or more outputs. When the device has any audio inputs or outputs the
406driver must set the <constant>V4L2_CAP_AUDIO</constant> flag in the
407&v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl.</para>
408
409 <example>
410 <title>Information about the current audio input</title>
411
412 <programlisting>
413&v4l2-audio; audio;
414
415memset (&amp;audio, 0, sizeof (audio));
416
417if (-1 == ioctl (fd, &VIDIOC-G-AUDIO;, &amp;audio)) {
418 perror ("VIDIOC_G_AUDIO");
419 exit (EXIT_FAILURE);
420}
421
422printf ("Current input: %s\n", audio.name);
423 </programlisting>
424 </example>
425
426 <example>
427 <title>Switching to the first audio input</title>
428
429 <programlisting>
430&v4l2-audio; audio;
431
432memset (&amp;audio, 0, sizeof (audio)); /* clear audio.mode, audio.reserved */
433
434audio.index = 0;
435
436if (-1 == ioctl (fd, &VIDIOC-S-AUDIO;, &amp;audio)) {
437 perror ("VIDIOC_S_AUDIO");
438 exit (EXIT_FAILURE);
439}
440 </programlisting>
441 </example>
442 </section>
443
444 <section id="tuner">
445 <title>Tuners and Modulators</title>
446
447 <section>
448 <title>Tuners</title>
449
450 <para>Video input devices can have one or more tuners
451demodulating a RF signal. Each tuner is associated with one or more
452video inputs, depending on the number of RF connectors on the tuner.
453The <structfield>type</structfield> field of the respective
454&v4l2-input; returned by the &VIDIOC-ENUMINPUT; ioctl is set to
455<constant>V4L2_INPUT_TYPE_TUNER</constant> and its
456<structfield>tuner</structfield> field contains the index number of
457the tuner.</para>
458
459 <para>Radio devices have exactly one tuner with index zero, no
460video inputs.</para>
461
462 <para>To query and change tuner properties applications use the
463&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; ioctl, respectively. The
464&v4l2-tuner; returned by <constant>VIDIOC_G_TUNER</constant> also
465contains signal status information applicable when the tuner of the
466current video input, or a radio tuner is queried. Note that
467<constant>VIDIOC_S_TUNER</constant> does not switch the current tuner,
468when there is more than one at all. The tuner is solely determined by
469the current video input. Drivers must support both ioctls and set the
470<constant>V4L2_CAP_TUNER</constant> flag in the &v4l2-capability;
471returned by the &VIDIOC-QUERYCAP; ioctl when the device has one or
472more tuners.</para>
473 </section>
474
475 <section>
476 <title>Modulators</title>
477
478 <para>Video output devices can have one or more modulators, uh,
479modulating a video signal for radiation or connection to the antenna
480input of a TV set or video recorder. Each modulator is associated with
481one or more video outputs, depending on the number of RF connectors on
482the modulator. The <structfield>type</structfield> field of the
483respective &v4l2-output; returned by the &VIDIOC-ENUMOUTPUT; ioctl is
484set to <constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> and its
485<structfield>modulator</structfield> field contains the index number
486of the modulator. This specification does not define radio output
487devices.</para>
488
489 <para>To query and change modulator properties applications use
490the &VIDIOC-G-MODULATOR; and &VIDIOC-S-MODULATOR; ioctl. Note that
491<constant>VIDIOC_S_MODULATOR</constant> does not switch the current
492modulator, when there is more than one at all. The modulator is solely
493determined by the current video output. Drivers must support both
494ioctls and set the <constant>V4L2_CAP_MODULATOR</constant> flag in
495the &v4l2-capability; returned by the &VIDIOC-QUERYCAP; ioctl when the
496device has one or more modulators.</para>
497 </section>
498
499 <section>
500 <title>Radio Frequency</title>
501
502 <para>To get and set the tuner or modulator radio frequency
503applications use the &VIDIOC-G-FREQUENCY; and &VIDIOC-S-FREQUENCY;
504ioctl which both take a pointer to a &v4l2-frequency;. These ioctls
505are used for TV and radio devices alike. Drivers must support both
506ioctls when the tuner or modulator ioctls are supported, or
507when the device is a radio device.</para>
508 </section>
509 </section>
510
511 <section id="standard">
512 <title>Video Standards</title>
513
514 <para>Video devices typically support one or more different video
515standards or variations of standards. Each video input and output may
516support another set of standards. This set is reported by the
517<structfield>std</structfield> field of &v4l2-input; and
518&v4l2-output; returned by the &VIDIOC-ENUMINPUT; and
519&VIDIOC-ENUMOUTPUT; ioctl, respectively.</para>
520
521 <para>V4L2 defines one bit for each analog video standard
522currently in use worldwide, and sets aside bits for driver defined
523standards, &eg; hybrid standards to watch NTSC video tapes on PAL TVs
524and vice versa. Applications can use the predefined bits to select a
525particular standard, although presenting the user a menu of supported
526standards is preferred. To enumerate and query the attributes of the
527supported standards applications use the &VIDIOC-ENUMSTD; ioctl.</para>
528
529 <para>Many of the defined standards are actually just variations
530of a few major standards. The hardware may in fact not distinguish
531between them, or do so internal and switch automatically. Therefore
532enumerated standards also contain sets of one or more standard
533bits.</para>
534
535 <para>Assume a hypothetic tuner capable of demodulating B/PAL,
536G/PAL and I/PAL signals. The first enumerated standard is a set of B
537and G/PAL, switched automatically depending on the selected radio
538frequency in UHF or VHF band. Enumeration gives a "PAL-B/G" or "PAL-I"
539choice. Similar a Composite input may collapse standards, enumerating
540"PAL-B/G/H/I", "NTSC-M" and "SECAM-D/K".<footnote>
541 <para>Some users are already confused by technical terms PAL,
542NTSC and SECAM. There is no point asking them to distinguish between
543B, G, D, or K when the software or hardware can do that
544automatically.</para>
545 </footnote></para>
546
547 <para>To query and select the standard used by the current video
548input or output applications call the &VIDIOC-G-STD; and
549&VIDIOC-S-STD; ioctl, respectively. The <emphasis>received</emphasis>
550standard can be sensed with the &VIDIOC-QUERYSTD; ioctl. Note parameter of all these ioctls is a pointer to a &v4l2-std-id; type (a standard set), <emphasis>not</emphasis> an index into the standard enumeration.<footnote>
551 <para>An alternative to the current scheme is to use pointers
552to indices as arguments of <constant>VIDIOC_G_STD</constant> and
553<constant>VIDIOC_S_STD</constant>, the &v4l2-input; and
554&v4l2-output; <structfield>std</structfield> field would be a set of
555indices like <structfield>audioset</structfield>.</para>
556 <para>Indices are consistent with the rest of the API
557and identify the standard unambiguously. In the present scheme of
558things an enumerated standard is looked up by &v4l2-std-id;. Now the
559standards supported by the inputs of a device can overlap. Just
560assume the tuner and composite input in the example above both
561exist on a device. An enumeration of "PAL-B/G", "PAL-H/I" suggests
562a choice which does not exist. We cannot merge or omit sets, because
563applications would be unable to find the standards reported by
564<constant>VIDIOC_G_STD</constant>. That leaves separate enumerations
565for each input. Also selecting a standard by &v4l2-std-id; can be
566ambiguous. Advantage of this method is that applications need not
567identify the standard indirectly, after enumerating.</para><para>So in
568summary, the lookup itself is unavoidable. The difference is only
569whether the lookup is necessary to find an enumerated standard or to
570switch to a standard by &v4l2-std-id;.</para>
571 </footnote> Drivers must implement all video standard ioctls
572when the device has one or more video inputs or outputs.</para>
573
574 <para>Special rules apply to USB cameras where the notion of video
575standards makes little sense. More generally any capture device,
576output devices accordingly, which is <itemizedlist>
577 <listitem>
578 <para>incapable of capturing fields or frames at the nominal
579rate of the video standard, or</para>
580 </listitem>
581 <listitem>
582 <para>where <link linkend="buffer">timestamps</link> refer
583to the instant the field or frame was received by the driver, not the
584capture time, or</para>
585 </listitem>
586 <listitem>
587 <para>where <link linkend="buffer">sequence numbers</link>
588refer to the frames received by the driver, not the captured
589frames.</para>
590 </listitem>
591 </itemizedlist> Here the driver shall set the
592<structfield>std</structfield> field of &v4l2-input; and &v4l2-output;
593to zero, the <constant>VIDIOC_G_STD</constant>,
594<constant>VIDIOC_S_STD</constant>,
595<constant>VIDIOC_QUERYSTD</constant> and
596<constant>VIDIOC_ENUMSTD</constant> ioctls shall return the
597&EINVAL;.<footnote>
598 <para>See <xref linkend="buffer" /> for a rationale. Probably
599even USB cameras follow some well known video standard. It might have
600been better to explicitly indicate elsewhere if a device cannot live
601up to normal expectations, instead of this exception.</para>
602 </footnote></para>
603
604 <example>
605 <title>Information about the current video standard</title>
606
607 <programlisting>
608&v4l2-std-id; std_id;
609&v4l2-standard; standard;
610
611if (-1 == ioctl (fd, &VIDIOC-G-STD;, &amp;std_id)) {
612 /* Note when VIDIOC_ENUMSTD always returns EINVAL this
613 is no video device or it falls under the USB exception,
614 and VIDIOC_G_STD returning EINVAL is no error. */
615
616 perror ("VIDIOC_G_STD");
617 exit (EXIT_FAILURE);
618}
619
620memset (&amp;standard, 0, sizeof (standard));
621standard.index = 0;
622
623while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
624 if (standard.id &amp; std_id) {
625 printf ("Current video standard: %s\n", standard.name);
626 exit (EXIT_SUCCESS);
627 }
628
629 standard.index++;
630}
631
632/* EINVAL indicates the end of the enumeration, which cannot be
633 empty unless this device falls under the USB exception. */
634
635if (errno == EINVAL || standard.index == 0) {
636 perror ("VIDIOC_ENUMSTD");
637 exit (EXIT_FAILURE);
638}
639 </programlisting>
640 </example>
641
642 <example>
643 <title>Listing the video standards supported by the current
644input</title>
645
646 <programlisting>
647&v4l2-input; input;
648&v4l2-standard; standard;
649
650memset (&amp;input, 0, sizeof (input));
651
652if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
653 perror ("VIDIOC_G_INPUT");
654 exit (EXIT_FAILURE);
655}
656
657if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
658 perror ("VIDIOC_ENUM_INPUT");
659 exit (EXIT_FAILURE);
660}
661
662printf ("Current input %s supports:\n", input.name);
663
664memset (&amp;standard, 0, sizeof (standard));
665standard.index = 0;
666
667while (0 == ioctl (fd, &VIDIOC-ENUMSTD;, &amp;standard)) {
668 if (standard.id &amp; input.std)
669 printf ("%s\n", standard.name);
670
671 standard.index++;
672}
673
674/* EINVAL indicates the end of the enumeration, which cannot be
675 empty unless this device falls under the USB exception. */
676
677if (errno != EINVAL || standard.index == 0) {
678 perror ("VIDIOC_ENUMSTD");
679 exit (EXIT_FAILURE);
680}
681 </programlisting>
682 </example>
683
684 <example>
685 <title>Selecting a new video standard</title>
686
687 <programlisting>
688&v4l2-input; input;
689&v4l2-std-id; std_id;
690
691memset (&amp;input, 0, sizeof (input));
692
693if (-1 == ioctl (fd, &VIDIOC-G-INPUT;, &amp;input.index)) {
694 perror ("VIDIOC_G_INPUT");
695 exit (EXIT_FAILURE);
696}
697
698if (-1 == ioctl (fd, &VIDIOC-ENUMINPUT;, &amp;input)) {
699 perror ("VIDIOC_ENUM_INPUT");
700 exit (EXIT_FAILURE);
701}
702
703if (0 == (input.std &amp; V4L2_STD_PAL_BG)) {
704 fprintf (stderr, "Oops. B/G PAL is not supported.\n");
705 exit (EXIT_FAILURE);
706}
707
708/* Note this is also supposed to work when only B
709 <emphasis>or</emphasis> G/PAL is supported. */
710
711std_id = V4L2_STD_PAL_BG;
712
713if (-1 == ioctl (fd, &VIDIOC-S-STD;, &amp;std_id)) {
714 perror ("VIDIOC_S_STD");
715 exit (EXIT_FAILURE);
716}
717 </programlisting>
718 </example>
719 </section>
720
721 &sub-controls;
722
723 <section id="format">
724 <title>Data Formats</title>
725
726 <section>
727 <title>Data Format Negotiation</title>
728
729 <para>Different devices exchange different kinds of data with
730applications, for example video images, raw or sliced VBI data, RDS
731datagrams. Even within one kind many different formats are possible,
732in particular an abundance of image formats. Although drivers must
733provide a default and the selection persists across closing and
734reopening a device, applications should always negotiate a data format
735before engaging in data exchange. Negotiation means the application
736asks for a particular format and the driver selects and reports the
737best the hardware can do to satisfy the request. Of course
738applications can also just query the current selection.</para>
739
740 <para>A single mechanism exists to negotiate all data formats
741using the aggregate &v4l2-format; and the &VIDIOC-G-FMT; and
742&VIDIOC-S-FMT; ioctls. Additionally the &VIDIOC-TRY-FMT; ioctl can be
743used to examine what the hardware <emphasis>could</emphasis> do,
744without actually selecting a new data format. The data formats
745supported by the V4L2 API are covered in the respective device section
746in <xref linkend="devices" />. For a closer look at image formats see
747<xref linkend="pixfmt" />.</para>
748
749 <para>The <constant>VIDIOC_S_FMT</constant> ioctl is a major
750turning-point in the initialization sequence. Prior to this point
751multiple panel applications can access the same device concurrently to
752select the current input, change controls or modify other properties.
753The first <constant>VIDIOC_S_FMT</constant> assigns a logical stream
754(video data, VBI data etc.) exclusively to one file descriptor.</para>
755
756 <para>Exclusive means no other application, more precisely no
757other file descriptor, can grab this stream or change device
758properties inconsistent with the negotiated parameters. A video
759standard change for example, when the new standard uses a different
760number of scan lines, can invalidate the selected image format.
761Therefore only the file descriptor owning the stream can make
762invalidating changes. Accordingly multiple file descriptors which
763grabbed different logical streams prevent each other from interfering
764with their settings. When for example video overlay is about to start
765or already in progress, simultaneous video capturing may be restricted
766to the same cropping and image size.</para>
767
768 <para>When applications omit the
769<constant>VIDIOC_S_FMT</constant> ioctl its locking side effects are
770implied by the next step, the selection of an I/O method with the
771&VIDIOC-REQBUFS; ioctl or implicit with the first &func-read; or
772&func-write; call.</para>
773
774 <para>Generally only one logical stream can be assigned to a
775file descriptor, the exception being drivers permitting simultaneous
776video capturing and overlay using the same file descriptor for
777compatibility with V4L and earlier versions of V4L2. Switching the
778logical stream or returning into "panel mode" is possible by closing
779and reopening the device. Drivers <emphasis>may</emphasis> support a
780switch using <constant>VIDIOC_S_FMT</constant>.</para>
781
782 <para>All drivers exchanging data with
783applications must support the <constant>VIDIOC_G_FMT</constant> and
784<constant>VIDIOC_S_FMT</constant> ioctl. Implementation of the
785<constant>VIDIOC_TRY_FMT</constant> is highly recommended but
786optional.</para>
787 </section>
788
789 <section>
790 <title>Image Format Enumeration</title>
791
792 <para>Apart of the generic format negotiation functions
793a special ioctl to enumerate all image formats supported by video
794capture, overlay or output devices is available.<footnote>
795 <para>Enumerating formats an application has no a-priori
796knowledge of (otherwise it could explicitly ask for them and need not
797enumerate) seems useless, but there are applications serving as proxy
798between drivers and the actual video applications for which this is
799useful.</para>
800 </footnote></para>
801
802 <para>The &VIDIOC-ENUM-FMT; ioctl must be supported
803by all drivers exchanging image data with applications.</para>
804
805 <important>
806 <para>Drivers are not supposed to convert image formats in
807kernel space. They must enumerate only formats directly supported by
808the hardware. If necessary driver writers should publish an example
809conversion routine or library for integration into applications.</para>
810 </important>
811 </section>
812 </section>
813
814 <section id="crop">
815 <title>Image Cropping, Insertion and Scaling</title>
816
817 <para>Some video capture devices can sample a subsection of the
818picture and shrink or enlarge it to an image of arbitrary size. We
819call these abilities cropping and scaling. Some video output devices
820can scale an image up or down and insert it at an arbitrary scan line
821and horizontal offset into a video signal.</para>
822
823 <para>Applications can use the following API to select an area in
824the video signal, query the default area and the hardware limits.
825<emphasis>Despite their name, the &VIDIOC-CROPCAP;, &VIDIOC-G-CROP;
826and &VIDIOC-S-CROP; ioctls apply to input as well as output
827devices.</emphasis></para>
828
829 <para>Scaling requires a source and a target. On a video capture
830or overlay device the source is the video signal, and the cropping
831ioctls determine the area actually sampled. The target are images
832read by the application or overlaid onto the graphics screen. Their
833size (and position for an overlay) is negotiated with the
834&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls.</para>
835
836 <para>On a video output device the source are the images passed in
837by the application, and their size is again negotiated with the
838<constant>VIDIOC_G/S_FMT</constant> ioctls, or may be encoded in a
839compressed video stream. The target is the video signal, and the
840cropping ioctls determine the area where the images are
841inserted.</para>
842
843 <para>Source and target rectangles are defined even if the device
844does not support scaling or the <constant>VIDIOC_G/S_CROP</constant>
845ioctls. Their size (and position where applicable) will be fixed in
846this case. <emphasis>All capture and output device must support the
847<constant>VIDIOC_CROPCAP</constant> ioctl such that applications can
848determine if scaling takes place.</emphasis></para>
849
850 <section>
851 <title>Cropping Structures</title>
852
853 <figure id="crop-scale">
854 <title>Image Cropping, Insertion and Scaling</title>
855 <mediaobject>
856 <imageobject>
857 <imagedata fileref="crop.pdf" format="PS" />
858 </imageobject>
859 <imageobject>
860 <imagedata fileref="crop.gif" format="GIF" />
861 </imageobject>
862 <textobject>
863 <phrase>The cropping, insertion and scaling process</phrase>
864 </textobject>
865 </mediaobject>
866 </figure>
867
868 <para>For capture devices the coordinates of the top left
869corner, width and height of the area which can be sampled is given by
870the <structfield>bounds</structfield> substructure of the
871&v4l2-cropcap; returned by the <constant>VIDIOC_CROPCAP</constant>
872ioctl. To support a wide range of hardware this specification does not
873define an origin or units. However by convention drivers should
874horizontally count unscaled samples relative to 0H (the leading edge
875of the horizontal sync pulse, see <xref linkend="vbi-hsync" />).
876Vertically ITU-R line
877numbers of the first field (<xref linkend="vbi-525" />, <xref
878linkend="vbi-625" />), multiplied by two if the driver can capture both
879fields.</para>
880
881 <para>The top left corner, width and height of the source
882rectangle, that is the area actually sampled, is given by &v4l2-crop;
883using the same coordinate system as &v4l2-cropcap;. Applications can
884use the <constant>VIDIOC_G_CROP</constant> and
885<constant>VIDIOC_S_CROP</constant> ioctls to get and set this
886rectangle. It must lie completely within the capture boundaries and
887the driver may further adjust the requested size and/or position
888according to hardware limitations.</para>
889
890 <para>Each capture device has a default source rectangle, given
891by the <structfield>defrect</structfield> substructure of
892&v4l2-cropcap;. The center of this rectangle shall align with the
893center of the active picture area of the video signal, and cover what
894the driver writer considers the complete picture. Drivers shall reset
895the source rectangle to the default when the driver is first loaded,
896but not later.</para>
897
898 <para>For output devices these structures and ioctls are used
899accordingly, defining the <emphasis>target</emphasis> rectangle where
900the images will be inserted into the video signal.</para>
901
902 </section>
903
904 <section>
905 <title>Scaling Adjustments</title>
906
907 <para>Video hardware can have various cropping, insertion and
908scaling limitations. It may only scale up or down, support only
909discrete scaling factors, or have different scaling abilities in
910horizontal and vertical direction. Also it may not support scaling at
911all. At the same time the &v4l2-crop; rectangle may have to be
912aligned, and both the source and target rectangles may have arbitrary
913upper and lower size limits. In particular the maximum
914<structfield>width</structfield> and <structfield>height</structfield>
915in &v4l2-crop; may be smaller than the
916&v4l2-cropcap;.<structfield>bounds</structfield> area. Therefore, as
917usual, drivers are expected to adjust the requested parameters and
918return the actual values selected.</para>
919
920 <para>Applications can change the source or the target rectangle
921first, as they may prefer a particular image size or a certain area in
922the video signal. If the driver has to adjust both to satisfy hardware
923limitations, the last requested rectangle shall take priority, and the
924driver should preferably adjust the opposite one. The &VIDIOC-TRY-FMT;
925ioctl however shall not change the driver state and therefore only
926adjust the requested rectangle.</para>
927
928 <para>Suppose scaling on a video capture device is restricted to
929a factor 1:1 or 2:1 in either direction and the target image size must
930be a multiple of 16&nbsp;&times;&nbsp;16 pixels. The source cropping
931rectangle is set to defaults, which are also the upper limit in this
932example, of 640&nbsp;&times;&nbsp;400 pixels at offset 0,&nbsp;0. An
933application requests an image size of 300&nbsp;&times;&nbsp;225
934pixels, assuming video will be scaled down from the "full picture"
935accordingly. The driver sets the image size to the closest possible
936values 304&nbsp;&times;&nbsp;224, then chooses the cropping rectangle
937closest to the requested size, that is 608&nbsp;&times;&nbsp;224
938(224&nbsp;&times;&nbsp;2:1 would exceed the limit 400). The offset
9390,&nbsp;0 is still valid, thus unmodified. Given the default cropping
940rectangle reported by <constant>VIDIOC_CROPCAP</constant> the
941application can easily propose another offset to center the cropping
942rectangle.</para>
943
944 <para>Now the application may insist on covering an area using a
945picture aspect ratio closer to the original request, so it asks for a
946cropping rectangle of 608&nbsp;&times;&nbsp;456 pixels. The present
947scaling factors limit cropping to 640&nbsp;&times;&nbsp;384, so the
948driver returns the cropping size 608&nbsp;&times;&nbsp;384 and adjusts
949the image size to closest possible 304&nbsp;&times;&nbsp;192.</para>
950
951 </section>
952
953 <section>
954 <title>Examples</title>
955
956 <para>Source and target rectangles shall remain unchanged across
957closing and reopening a device, such that piping data into or out of a
958device will work without special preparations. More advanced
959applications should ensure the parameters are suitable before starting
960I/O.</para>
961
962 <example>
963 <title>Resetting the cropping parameters</title>
964
965 <para>(A video capture device is assumed; change
966<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> for other
967devices.)</para>
968
969 <programlisting>
970&v4l2-cropcap; cropcap;
971&v4l2-crop; crop;
972
973memset (&amp;cropcap, 0, sizeof (cropcap));
974cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
975
976if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &amp;cropcap)) {
977 perror ("VIDIOC_CROPCAP");
978 exit (EXIT_FAILURE);
979}
980
981memset (&amp;crop, 0, sizeof (crop));
982crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
983crop.c = cropcap.defrect;
984
985/* Ignore if cropping is not supported (EINVAL). */
986
987if (-1 == ioctl (fd, &VIDIOC-S-CROP;, &amp;crop)
988 &amp;&amp; errno != EINVAL) {
989 perror ("VIDIOC_S_CROP");
990 exit (EXIT_FAILURE);
991}
992 </programlisting>
993 </example>
994
995 <example>
996 <title>Simple downscaling</title>
997
998 <para>(A video capture device is assumed.)</para>
999
1000 <programlisting>
1001&v4l2-cropcap; cropcap;
1002&v4l2-format; format;
1003
1004reset_cropping_parameters ();
1005
1006/* Scale down to 1/4 size of full picture. */
1007
1008memset (&amp;format, 0, sizeof (format)); /* defaults */
1009
1010format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1011
1012format.fmt.pix.width = cropcap.defrect.width &gt;&gt; 1;
1013format.fmt.pix.height = cropcap.defrect.height &gt;&gt; 1;
1014format.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV;
1015
1016if (-1 == ioctl (fd, &VIDIOC-S-FMT;, &amp;format)) {
1017 perror ("VIDIOC_S_FORMAT");
1018 exit (EXIT_FAILURE);
1019}
1020
1021/* We could check the actual image size now, the actual scaling factor
1022 or if the driver can scale at all. */
1023 </programlisting>
1024 </example>
1025
1026 <example>
1027 <title>Selecting an output area</title>
1028
1029 <programlisting>
1030&v4l2-cropcap; cropcap;
1031&v4l2-crop; crop;
1032
1033memset (&amp;cropcap, 0, sizeof (cropcap));
1034cropcap.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1035
1036if (-1 == ioctl (fd, VIDIOC_CROPCAP;, &amp;cropcap)) {
1037 perror ("VIDIOC_CROPCAP");
1038 exit (EXIT_FAILURE);
1039}
1040
1041memset (&amp;crop, 0, sizeof (crop));
1042
1043crop.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1044crop.c = cropcap.defrect;
1045
1046/* Scale the width and height to 50 % of their original size
1047 and center the output. */
1048
1049crop.c.width /= 2;
1050crop.c.height /= 2;
1051crop.c.left += crop.c.width / 2;
1052crop.c.top += crop.c.height / 2;
1053
1054/* Ignore if cropping is not supported (EINVAL). */
1055
1056if (-1 == ioctl (fd, VIDIOC_S_CROP, &amp;crop)
1057 &amp;&amp; errno != EINVAL) {
1058 perror ("VIDIOC_S_CROP");
1059 exit (EXIT_FAILURE);
1060}
1061</programlisting>
1062 </example>
1063
1064 <example>
1065 <title>Current scaling factor and pixel aspect</title>
1066
1067 <para>(A video capture device is assumed.)</para>
1068
1069 <programlisting>
1070&v4l2-cropcap; cropcap;
1071&v4l2-crop; crop;
1072&v4l2-format; format;
1073double hscale, vscale;
1074double aspect;
1075int dwidth, dheight;
1076
1077memset (&amp;cropcap, 0, sizeof (cropcap));
1078cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1079
1080if (-1 == ioctl (fd, &VIDIOC-CROPCAP;, &amp;cropcap)) {
1081 perror ("VIDIOC_CROPCAP");
1082 exit (EXIT_FAILURE);
1083}
1084
1085memset (&amp;crop, 0, sizeof (crop));
1086crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1087
1088if (-1 == ioctl (fd, &VIDIOC-G-CROP;, &amp;crop)) {
1089 if (errno != EINVAL) {
1090 perror ("VIDIOC_G_CROP");
1091 exit (EXIT_FAILURE);
1092 }
1093
1094 /* Cropping not supported. */
1095 crop.c = cropcap.defrect;
1096}
1097
1098memset (&amp;format, 0, sizeof (format));
1099format.fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1100
1101if (-1 == ioctl (fd, &VIDIOC-G-FMT;, &amp;format)) {
1102 perror ("VIDIOC_G_FMT");
1103 exit (EXIT_FAILURE);
1104}
1105
1106/* The scaling applied by the driver. */
1107
1108hscale = format.fmt.pix.width / (double) crop.c.width;
1109vscale = format.fmt.pix.height / (double) crop.c.height;
1110
1111aspect = cropcap.pixelaspect.numerator /
1112 (double) cropcap.pixelaspect.denominator;
1113aspect = aspect * hscale / vscale;
1114
1115/* Devices following ITU-R BT.601 do not capture
1116 square pixels. For playback on a computer monitor
1117 we should scale the images to this size. */
1118
1119dwidth = format.fmt.pix.width / aspect;
1120dheight = format.fmt.pix.height;
1121 </programlisting>
1122 </example>
1123 </section>
1124 </section>
1125
1126 <section id="streaming-par">
1127 <title>Streaming Parameters</title>
1128
1129 <para>Streaming parameters are intended to optimize the video
1130capture process as well as I/O. Presently applications can request a
1131high quality capture mode with the &VIDIOC-S-PARM; ioctl.</para>
1132
1133 <para>The current video standard determines a nominal number of
1134frames per second. If less than this number of frames is to be
1135captured or output, applications can request frame skipping or
1136duplicating on the driver side. This is especially useful when using
1137the &func-read; or &func-write;, which are not augmented by timestamps
1138or sequence counters, and to avoid unneccessary data copying.</para>
1139
1140 <para>Finally these ioctls can be used to determine the number of
1141buffers used internally by a driver in read/write mode. For
1142implications see the section discussing the &func-read;
1143function.</para>
1144
1145 <para>To get and set the streaming parameters applications call
1146the &VIDIOC-G-PARM; and &VIDIOC-S-PARM; ioctl, respectively. They take
1147a pointer to a &v4l2-streamparm;, which contains a union holding
1148separate parameters for input and output devices.</para>
1149
1150 <para>These ioctls are optional, drivers need not implement
1151them. If so, they return the &EINVAL;.</para>
1152 </section>
1153
1154 <!--
1155Local Variables:
1156mode: sgml
1157sgml-parent-document: "v4l2.sgml"
1158indent-tabs-mode: nil
1159End:
1160 -->
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml
new file mode 100644
index 000000000000..4d1902a54d61
--- /dev/null
+++ b/Documentation/DocBook/v4l/compat.xml
@@ -0,0 +1,2457 @@
1 <title>Changes</title>
2
3 <para>The following chapters document the evolution of the V4L2 API,
4errata or extensions. They are also intended to help application and
5driver writers to port or update their code.</para>
6
7 <section id="diff-v4l">
8 <title>Differences between V4L and V4L2</title>
9
10 <para>The Video For Linux API was first introduced in Linux 2.1 to
11unify and replace various TV and radio device related interfaces,
12developed independently by driver writers in prior years. Starting
13with Linux 2.5 the much improved V4L2 API replaces the V4L API,
14although existing drivers will continue to support V4L applications in
15the future, either directly or through the V4L2 compatibility layer in
16the <filename>videodev</filename> kernel module translating ioctls on
17the fly. For a transition period not all drivers will support the V4L2
18API.</para>
19
20 <section>
21 <title>Opening and Closing Devices</title>
22
23 <para>For compatibility reasons the character device file names
24recommended for V4L2 video capture, overlay, radio, teletext and raw
25vbi capture devices did not change from those used by V4L. They are
26listed in <xref linkend="devices" /> and below in <xref
27 linkend="v4l-dev" />.</para>
28
29 <para>The V4L <filename>videodev</filename> module automatically
30assigns minor numbers to drivers in load order, depending on the
31registered device type. We recommend that V4L2 drivers by default
32register devices with the same numbers, but the system administrator
33can assign arbitrary minor numbers using driver module options. The
34major device number remains 81.</para>
35
36 <table id="v4l-dev">
37 <title>V4L Device Types, Names and Numbers</title>
38 <tgroup cols="3">
39 <thead>
40 <row>
41 <entry>Device Type</entry>
42 <entry>File Name</entry>
43 <entry>Minor Numbers</entry>
44 </row>
45 </thead>
46 <tbody valign="top">
47 <row>
48 <entry>Video capture and overlay</entry>
49 <entry><para><filename>/dev/video</filename> and
50<filename>/dev/bttv0</filename><footnote> <para>According to
51Documentation/devices.txt these should be symbolic links to
52<filename>/dev/video0</filename>. Note the original bttv interface is
53not compatible with V4L or V4L2.</para> </footnote>,
54<filename>/dev/video0</filename> to
55<filename>/dev/video63</filename></para></entry>
56 <entry>0-63</entry>
57 </row>
58 <row>
59 <entry>Radio receiver</entry>
60 <entry><para><filename>/dev/radio</filename><footnote>
61 <para>According to
62<filename>Documentation/devices.txt</filename> a symbolic link to
63<filename>/dev/radio0</filename>.</para>
64 </footnote>, <filename>/dev/radio0</filename> to
65<filename>/dev/radio63</filename></para></entry>
66 <entry>64-127</entry>
67 </row>
68 <row>
69 <entry>Teletext decoder</entry>
70 <entry><para><filename>/dev/vtx</filename>,
71<filename>/dev/vtx0</filename> to
72<filename>/dev/vtx31</filename></para></entry>
73 <entry>192-223</entry>
74 </row>
75 <row>
76 <entry>Raw VBI capture</entry>
77 <entry><para><filename>/dev/vbi</filename>,
78<filename>/dev/vbi0</filename> to
79<filename>/dev/vbi31</filename></para></entry>
80 <entry>224-255</entry>
81 </row>
82 </tbody>
83 </tgroup>
84 </table>
85
86 <para>V4L prohibits (or used to prohibit) multiple opens of a
87device file. V4L2 drivers <emphasis>may</emphasis> support multiple
88opens, see <xref linkend="open" /> for details and consequences.</para>
89
90 <para>V4L drivers respond to V4L2 ioctls with an &EINVAL;. The
91compatibility layer in the V4L2 <filename>videodev</filename> module
92can translate V4L ioctl requests to their V4L2 counterpart, however a
93V4L2 driver usually needs more preparation to become fully V4L
94compatible. This is covered in more detail in <xref
95 linkend="driver" />.</para>
96 </section>
97
98 <section>
99 <title>Querying Capabilities</title>
100
101 <para>The V4L <constant>VIDIOCGCAP</constant> ioctl is
102equivalent to V4L2's &VIDIOC-QUERYCAP;.</para>
103
104 <para>The <structfield>name</structfield> field in struct
105<structname>video_capability</structname> became
106<structfield>card</structfield> in &v4l2-capability;,
107<structfield>type</structfield> was replaced by
108<structfield>capabilities</structfield>. Note V4L2 does not
109distinguish between device types like this, better think of basic
110video input, video output and radio devices supporting a set of
111related functions like video capturing, video overlay and VBI
112capturing. See <xref linkend="open" /> for an
113introduction.<informaltable>
114 <tgroup cols="3">
115 <thead>
116 <row>
117 <entry>struct
118<structname>video_capability</structname>
119<structfield>type</structfield></entry>
120 <entry>&v4l2-capability;
121<structfield>capabilities</structfield> flags</entry>
122 <entry>Purpose</entry>
123 </row>
124 </thead>
125 <tbody valign="top">
126 <row>
127 <entry><constant>VID_TYPE_CAPTURE</constant></entry>
128 <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
129 <entry>The <link linkend="capture">video
130capture</link> interface is supported.</entry>
131 </row>
132 <row>
133 <entry><constant>VID_TYPE_TUNER</constant></entry>
134 <entry><constant>V4L2_CAP_TUNER</constant></entry>
135 <entry>The device has a <link linkend="tuner">tuner or
136modulator</link>.</entry>
137 </row>
138 <row>
139 <entry><constant>VID_TYPE_TELETEXT</constant></entry>
140 <entry><constant>V4L2_CAP_VBI_CAPTURE</constant></entry>
141 <entry>The <link linkend="raw-vbi">raw VBI
142capture</link> interface is supported.</entry>
143 </row>
144 <row>
145 <entry><constant>VID_TYPE_OVERLAY</constant></entry>
146 <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
147 <entry>The <link linkend="overlay">video
148overlay</link> interface is supported.</entry>
149 </row>
150 <row>
151 <entry><constant>VID_TYPE_CHROMAKEY</constant></entry>
152 <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant> in
153field <structfield>capability</structfield> of
154&v4l2-framebuffer;</entry>
155 <entry>Whether chromakey overlay is supported. For
156more information on overlay see
157<xref linkend="overlay" />.</entry>
158 </row>
159 <row>
160 <entry><constant>VID_TYPE_CLIPPING</constant></entry>
161 <entry><constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant>
162and <constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant> in field
163<structfield>capability</structfield> of &v4l2-framebuffer;</entry>
164 <entry>Whether clipping the overlaid image is
165supported, see <xref linkend="overlay" />.</entry>
166 </row>
167 <row>
168 <entry><constant>VID_TYPE_FRAMERAM</constant></entry>
169 <entry><constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant>
170<emphasis>not set</emphasis> in field
171<structfield>capability</structfield> of &v4l2-framebuffer;</entry>
172 <entry>Whether overlay overwrites frame buffer memory,
173see <xref linkend="overlay" />.</entry>
174 </row>
175 <row>
176 <entry><constant>VID_TYPE_SCALES</constant></entry>
177 <entry><constant>-</constant></entry>
178 <entry>This flag indicates if the hardware can scale
179images. The V4L2 API implies the scale factor by setting the cropping
180dimensions and image size with the &VIDIOC-S-CROP; and &VIDIOC-S-FMT;
181ioctl, respectively. The driver returns the closest sizes possible.
182For more information on cropping and scaling see <xref
183 linkend="crop" />.</entry>
184 </row>
185 <row>
186 <entry><constant>VID_TYPE_MONOCHROME</constant></entry>
187 <entry><constant>-</constant></entry>
188 <entry>Applications can enumerate the supported image
189formats with the &VIDIOC-ENUM-FMT; ioctl to determine if the device
190supports grey scale capturing only. For more information on image
191formats see <xref linkend="pixfmt" />.</entry>
192 </row>
193 <row>
194 <entry><constant>VID_TYPE_SUBCAPTURE</constant></entry>
195 <entry><constant>-</constant></entry>
196 <entry>Applications can call the &VIDIOC-G-CROP; ioctl
197to determine if the device supports capturing a subsection of the full
198picture ("cropping" in V4L2). If not, the ioctl returns the &EINVAL;.
199For more information on cropping and scaling see <xref
200 linkend="crop" />.</entry>
201 </row>
202 <row>
203 <entry><constant>VID_TYPE_MPEG_DECODER</constant></entry>
204 <entry><constant>-</constant></entry>
205 <entry>Applications can enumerate the supported image
206formats with the &VIDIOC-ENUM-FMT; ioctl to determine if the device
207supports MPEG streams.</entry>
208 </row>
209 <row>
210 <entry><constant>VID_TYPE_MPEG_ENCODER</constant></entry>
211 <entry><constant>-</constant></entry>
212 <entry>See above.</entry>
213 </row>
214 <row>
215 <entry><constant>VID_TYPE_MJPEG_DECODER</constant></entry>
216 <entry><constant>-</constant></entry>
217 <entry>See above.</entry>
218 </row>
219 <row>
220 <entry><constant>VID_TYPE_MJPEG_ENCODER</constant></entry>
221 <entry><constant>-</constant></entry>
222 <entry>See above.</entry>
223 </row>
224 </tbody>
225 </tgroup>
226 </informaltable></para>
227
228 <para>The <structfield>audios</structfield> field was replaced
229by <structfield>capabilities</structfield> flag
230<constant>V4L2_CAP_AUDIO</constant>, indicating
231<emphasis>if</emphasis> the device has any audio inputs or outputs. To
232determine their number applications can enumerate audio inputs with
233the &VIDIOC-G-AUDIO; ioctl. The audio ioctls are described in <xref
234 linkend="audio" />.</para>
235
236 <para>The <structfield>maxwidth</structfield>,
237<structfield>maxheight</structfield>,
238<structfield>minwidth</structfield> and
239<structfield>minheight</structfield> fields were removed. Calling the
240&VIDIOC-S-FMT; or &VIDIOC-TRY-FMT; ioctl with the desired dimensions
241returns the closest size possible, taking into account the current
242video standard, cropping and scaling limitations.</para>
243 </section>
244
245 <section>
246 <title>Video Sources</title>
247
248 <para>V4L provides the <constant>VIDIOCGCHAN</constant> and
249<constant>VIDIOCSCHAN</constant> ioctl using struct
250<structname>video_channel</structname> to enumerate
251the video inputs of a V4L device. The equivalent V4L2 ioctls
252are &VIDIOC-ENUMINPUT;, &VIDIOC-G-INPUT; and &VIDIOC-S-INPUT;
253using &v4l2-input; as discussed in <xref linkend="video" />.</para>
254
255 <para>The <structfield>channel</structfield> field counting
256inputs was renamed to <structfield>index</structfield>, the video
257input types were renamed as follows: <informaltable>
258 <tgroup cols="2">
259 <thead>
260 <row>
261 <entry>struct <structname>video_channel</structname>
262<structfield>type</structfield></entry>
263 <entry>&v4l2-input;
264<structfield>type</structfield></entry>
265 </row>
266 </thead>
267 <tbody valign="top">
268 <row>
269 <entry><constant>VIDEO_TYPE_TV</constant></entry>
270 <entry><constant>V4L2_INPUT_TYPE_TUNER</constant></entry>
271 </row>
272 <row>
273 <entry><constant>VIDEO_TYPE_CAMERA</constant></entry>
274 <entry><constant>V4L2_INPUT_TYPE_CAMERA</constant></entry>
275 </row>
276 </tbody>
277 </tgroup>
278 </informaltable></para>
279
280 <para>Unlike the <structfield>tuners</structfield> field
281expressing the number of tuners of this input, V4L2 assumes each video
282input is connected to at most one tuner. However a tuner can have more
283than one input, &ie; RF connectors, and a device can have multiple
284tuners. The index number of the tuner associated with the input, if
285any, is stored in field <structfield>tuner</structfield> of
286&v4l2-input;. Enumeration of tuners is discussed in <xref
287 linkend="tuner" />.</para>
288
289 <para>The redundant <constant>VIDEO_VC_TUNER</constant> flag was
290dropped. Video inputs associated with a tuner are of type
291<constant>V4L2_INPUT_TYPE_TUNER</constant>. The
292<constant>VIDEO_VC_AUDIO</constant> flag was replaced by the
293<structfield>audioset</structfield> field. V4L2 considers devices with
294up to 32 audio inputs. Each set bit in the
295<structfield>audioset</structfield> field represents one audio input
296this video input combines with. For information about audio inputs and
297how to switch between them see <xref linkend="audio" />.</para>
298
299 <para>The <structfield>norm</structfield> field describing the
300supported video standards was replaced by
301<structfield>std</structfield>. The V4L specification mentions a flag
302<constant>VIDEO_VC_NORM</constant> indicating whether the standard can
303be changed. This flag was a later addition together with the
304<structfield>norm</structfield> field and has been removed in the
305meantime. V4L2 has a similar, albeit more comprehensive approach
306to video standards, see <xref linkend="standard" /> for more
307information.</para>
308 </section>
309
310 <section>
311 <title>Tuning</title>
312
313 <para>The V4L <constant>VIDIOCGTUNER</constant> and
314<constant>VIDIOCSTUNER</constant> ioctl and struct
315<structname>video_tuner</structname> can be used to enumerate the
316tuners of a V4L TV or radio device. The equivalent V4L2 ioctls are
317&VIDIOC-G-TUNER; and &VIDIOC-S-TUNER; using &v4l2-tuner;. Tuners are
318covered in <xref linkend="tuner" />.</para>
319
320 <para>The <structfield>tuner</structfield> field counting tuners
321was renamed to <structfield>index</structfield>. The fields
322<structfield>name</structfield>, <structfield>rangelow</structfield>
323and <structfield>rangehigh</structfield> remained unchanged.</para>
324
325 <para>The <constant>VIDEO_TUNER_PAL</constant>,
326<constant>VIDEO_TUNER_NTSC</constant> and
327<constant>VIDEO_TUNER_SECAM</constant> flags indicating the supported
328video standards were dropped. This information is now contained in the
329associated &v4l2-input;. No replacement exists for the
330<constant>VIDEO_TUNER_NORM</constant> flag indicating whether the
331video standard can be switched. The <structfield>mode</structfield>
332field to select a different video standard was replaced by a whole new
333set of ioctls and structures described in <xref linkend="standard" />.
334Due to its ubiquity it should be mentioned the BTTV driver supports
335several standards in addition to the regular
336<constant>VIDEO_MODE_PAL</constant> (0),
337<constant>VIDEO_MODE_NTSC</constant>,
338<constant>VIDEO_MODE_SECAM</constant> and
339<constant>VIDEO_MODE_AUTO</constant> (3). Namely N/PAL Argentina,
340M/PAL, N/PAL, and NTSC Japan with numbers 3-6 (sic).</para>
341
342 <para>The <constant>VIDEO_TUNER_STEREO_ON</constant> flag
343indicating stereo reception became
344<constant>V4L2_TUNER_SUB_STEREO</constant> in field
345<structfield>rxsubchans</structfield>. This field also permits the
346detection of monaural and bilingual audio, see the definition of
347&v4l2-tuner; for details. Presently no replacement exists for the
348<constant>VIDEO_TUNER_RDS_ON</constant> and
349<constant>VIDEO_TUNER_MBS_ON</constant> flags.</para>
350
351 <para> The <constant>VIDEO_TUNER_LOW</constant> flag was renamed
352to <constant>V4L2_TUNER_CAP_LOW</constant> in the &v4l2-tuner;
353<structfield>capability</structfield> field.</para>
354
355 <para>The <constant>VIDIOCGFREQ</constant> and
356<constant>VIDIOCSFREQ</constant> ioctl to change the tuner frequency
357where renamed to &VIDIOC-G-FREQUENCY; and &VIDIOC-S-FREQUENCY;. They
358take a pointer to a &v4l2-frequency; instead of an unsigned long
359integer.</para>
360 </section>
361
362 <section id="v4l-image-properties">
363 <title>Image Properties</title>
364
365 <para>V4L2 has no equivalent of the
366<constant>VIDIOCGPICT</constant> and <constant>VIDIOCSPICT</constant>
367ioctl and struct <structname>video_picture</structname>. The following
368fields where replaced by V4L2 controls accessible with the
369&VIDIOC-QUERYCTRL;, &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls:<informaltable>
370 <tgroup cols="2">
371 <thead>
372 <row>
373 <entry>struct <structname>video_picture</structname></entry>
374 <entry>V4L2 Control ID</entry>
375 </row>
376 </thead>
377 <tbody valign="top">
378 <row>
379 <entry><structfield>brightness</structfield></entry>
380 <entry><constant>V4L2_CID_BRIGHTNESS</constant></entry>
381 </row>
382 <row>
383 <entry><structfield>hue</structfield></entry>
384 <entry><constant>V4L2_CID_HUE</constant></entry>
385 </row>
386 <row>
387 <entry><structfield>colour</structfield></entry>
388 <entry><constant>V4L2_CID_SATURATION</constant></entry>
389 </row>
390 <row>
391 <entry><structfield>contrast</structfield></entry>
392 <entry><constant>V4L2_CID_CONTRAST</constant></entry>
393 </row>
394 <row>
395 <entry><structfield>whiteness</structfield></entry>
396 <entry><constant>V4L2_CID_WHITENESS</constant></entry>
397 </row>
398 </tbody>
399 </tgroup>
400 </informaltable></para>
401
402 <para>The V4L picture controls are assumed to range from 0 to
40365535 with no particular reset value. The V4L2 API permits arbitrary
404limits and defaults which can be queried with the &VIDIOC-QUERYCTRL;
405ioctl. For general information about controls see <xref
406linkend="control" />.</para>
407
408 <para>The <structfield>depth</structfield> (average number of
409bits per pixel) of a video image is implied by the selected image
410format. V4L2 does not explicitely provide such information assuming
411applications recognizing the format are aware of the image depth and
412others need not know. The <structfield>palette</structfield> field
413moved into the &v4l2-pix-format;:<informaltable>
414 <tgroup cols="2">
415 <thead>
416 <row>
417 <entry>struct <structname>video_picture</structname>
418<structfield>palette</structfield></entry>
419 <entry>&v4l2-pix-format;
420<structfield>pixfmt</structfield></entry>
421 </row>
422 </thead>
423 <tbody valign="top">
424 <row>
425 <entry><constant>VIDEO_PALETTE_GREY</constant></entry>
426 <entry><para><link
427linkend="V4L2-PIX-FMT-GREY"><constant>V4L2_PIX_FMT_GREY</constant></link></para></entry>
428 </row>
429 <row>
430 <entry><constant>VIDEO_PALETTE_HI240</constant></entry>
431 <entry><para><link
432linkend="pixfmt-reserved"><constant>V4L2_PIX_FMT_HI240</constant></link><footnote>
433 <para>This is a custom format used by the BTTV
434driver, not one of the V4L2 standard formats.</para>
435 </footnote></para></entry>
436 </row>
437 <row>
438 <entry><constant>VIDEO_PALETTE_RGB565</constant></entry>
439 <entry><para><link
440linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_RGB565</constant></link></para></entry>
441 </row>
442 <row>
443 <entry><constant>VIDEO_PALETTE_RGB555</constant></entry>
444 <entry><para><link
445linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_RGB555</constant></link></para></entry>
446 </row>
447 <row>
448 <entry><constant>VIDEO_PALETTE_RGB24</constant></entry>
449 <entry><para><link
450linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_BGR24</constant></link></para></entry>
451 </row>
452 <row>
453 <entry><constant>VIDEO_PALETTE_RGB32</constant></entry>
454 <entry><para><link
455linkend="pixfmt-rgb"><constant>V4L2_PIX_FMT_BGR32</constant></link><footnote>
456 <para>Presumably all V4L RGB formats are
457little-endian, although some drivers might interpret them according to machine endianess. V4L2 defines little-endian, big-endian and red/blue
458swapped variants. For details see <xref linkend="pixfmt-rgb" />.</para>
459 </footnote></para></entry>
460 </row>
461 <row>
462 <entry><constant>VIDEO_PALETTE_YUV422</constant></entry>
463 <entry><para><link
464linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link></para></entry>
465 </row>
466 <row>
467 <entry><para><constant>VIDEO_PALETTE_YUYV</constant><footnote>
468 <para><constant>VIDEO_PALETTE_YUV422</constant>
469and <constant>VIDEO_PALETTE_YUYV</constant> are the same formats. Some
470V4L drivers respond to one, some to the other.</para>
471 </footnote></para></entry>
472 <entry><para><link
473linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link></para></entry>
474 </row>
475 <row>
476 <entry><constant>VIDEO_PALETTE_UYVY</constant></entry>
477 <entry><para><link
478linkend="V4L2-PIX-FMT-UYVY"><constant>V4L2_PIX_FMT_UYVY</constant></link></para></entry>
479 </row>
480 <row>
481 <entry><constant>VIDEO_PALETTE_YUV420</constant></entry>
482 <entry>None</entry>
483 </row>
484 <row>
485 <entry><constant>VIDEO_PALETTE_YUV411</constant></entry>
486 <entry><para><link
487linkend="V4L2-PIX-FMT-Y41P"><constant>V4L2_PIX_FMT_Y41P</constant></link><footnote>
488 <para>Not to be confused with
489<constant>V4L2_PIX_FMT_YUV411P</constant>, which is a planar
490format.</para> </footnote></para></entry>
491 </row>
492 <row>
493 <entry><constant>VIDEO_PALETTE_RAW</constant></entry>
494 <entry><para>None<footnote> <para>V4L explains this
495as: "RAW capture (BT848)"</para> </footnote></para></entry>
496 </row>
497 <row>
498 <entry><constant>VIDEO_PALETTE_YUV422P</constant></entry>
499 <entry><para><link
500linkend="V4L2-PIX-FMT-YUV422P"><constant>V4L2_PIX_FMT_YUV422P</constant></link></para></entry>
501 </row>
502 <row>
503 <entry><constant>VIDEO_PALETTE_YUV411P</constant></entry>
504 <entry><para><link
505linkend="V4L2-PIX-FMT-YUV411P"><constant>V4L2_PIX_FMT_YUV411P</constant></link><footnote>
506 <para>Not to be confused with
507<constant>V4L2_PIX_FMT_Y41P</constant>, which is a packed
508format.</para> </footnote></para></entry>
509 </row>
510 <row>
511 <entry><constant>VIDEO_PALETTE_YUV420P</constant></entry>
512 <entry><para><link
513linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link></para></entry>
514 </row>
515 <row>
516 <entry><constant>VIDEO_PALETTE_YUV410P</constant></entry>
517 <entry><para><link
518linkend="V4L2-PIX-FMT-YVU410"><constant>V4L2_PIX_FMT_YVU410</constant></link></para></entry>
519 </row>
520 </tbody>
521 </tgroup>
522 </informaltable></para>
523
524 <para>V4L2 image formats are defined in <xref
525linkend="pixfmt" />. The image format can be selected with the
526&VIDIOC-S-FMT; ioctl.</para>
527 </section>
528
529 <section>
530 <title>Audio</title>
531
532 <para>The <constant>VIDIOCGAUDIO</constant> and
533<constant>VIDIOCSAUDIO</constant> ioctl and struct
534<structname>video_audio</structname> are used to enumerate the
535audio inputs of a V4L device. The equivalent V4L2 ioctls are
536&VIDIOC-G-AUDIO; and &VIDIOC-S-AUDIO; using &v4l2-audio; as
537discussed in <xref linkend="audio" />.</para>
538
539 <para>The <structfield>audio</structfield> "channel number"
540field counting audio inputs was renamed to
541<structfield>index</structfield>.</para>
542
543 <para>On <constant>VIDIOCSAUDIO</constant> the
544<structfield>mode</structfield> field selects <emphasis>one</emphasis>
545of the <constant>VIDEO_SOUND_MONO</constant>,
546<constant>VIDEO_SOUND_STEREO</constant>,
547<constant>VIDEO_SOUND_LANG1</constant> or
548<constant>VIDEO_SOUND_LANG2</constant> audio demodulation modes. When
549the current audio standard is BTSC
550<constant>VIDEO_SOUND_LANG2</constant> refers to SAP and
551<constant>VIDEO_SOUND_LANG1</constant> is meaningless. Also
552undocumented in the V4L specification, there is no way to query the
553selected mode. On <constant>VIDIOCGAUDIO</constant> the driver returns
554the <emphasis>actually received</emphasis> audio programmes in this
555field. In the V4L2 API this information is stored in the &v4l2-tuner;
556<structfield>rxsubchans</structfield> and
557<structfield>audmode</structfield> fields, respectively. See <xref
558linkend="tuner" /> for more information on tuners. Related to audio
559modes &v4l2-audio; also reports if this is a mono or stereo
560input, regardless if the source is a tuner.</para>
561
562 <para>The following fields where replaced by V4L2 controls
563accessible with the &VIDIOC-QUERYCTRL;, &VIDIOC-G-CTRL; and
564&VIDIOC-S-CTRL; ioctls:<informaltable>
565 <tgroup cols="2">
566 <thead>
567 <row>
568 <entry>struct
569<structname>video_audio</structname></entry>
570 <entry>V4L2 Control ID</entry>
571 </row>
572 </thead>
573 <tbody valign="top">
574 <row>
575 <entry><structfield>volume</structfield></entry>
576 <entry><constant>V4L2_CID_AUDIO_VOLUME</constant></entry>
577 </row>
578 <row>
579 <entry><structfield>bass</structfield></entry>
580 <entry><constant>V4L2_CID_AUDIO_BASS</constant></entry>
581 </row>
582 <row>
583 <entry><structfield>treble</structfield></entry>
584 <entry><constant>V4L2_CID_AUDIO_TREBLE</constant></entry>
585 </row>
586 <row>
587 <entry><structfield>balance</structfield></entry>
588 <entry><constant>V4L2_CID_AUDIO_BALANCE</constant></entry>
589 </row>
590 </tbody>
591 </tgroup>
592 </informaltable></para>
593
594 <para>To determine which of these controls are supported by a
595driver V4L provides the <structfield>flags</structfield>
596<constant>VIDEO_AUDIO_VOLUME</constant>,
597<constant>VIDEO_AUDIO_BASS</constant>,
598<constant>VIDEO_AUDIO_TREBLE</constant> and
599<constant>VIDEO_AUDIO_BALANCE</constant>. In the V4L2 API the
600&VIDIOC-QUERYCTRL; ioctl reports if the respective control is
601supported. Accordingly the <constant>VIDEO_AUDIO_MUTABLE</constant>
602and <constant>VIDEO_AUDIO_MUTE</constant> flags where replaced by the
603boolean <constant>V4L2_CID_AUDIO_MUTE</constant> control.</para>
604
605 <para>All V4L2 controls have a <structfield>step</structfield>
606attribute replacing the struct <structname>video_audio</structname>
607<structfield>step</structfield> field. The V4L audio controls are
608assumed to range from 0 to 65535 with no particular reset value. The
609V4L2 API permits arbitrary limits and defaults which can be queried
610with the &VIDIOC-QUERYCTRL; ioctl. For general information about
611controls see <xref linkend="control" />.</para>
612 </section>
613
614 <section>
615 <title>Frame Buffer Overlay</title>
616
617 <para>The V4L2 ioctls equivalent to
618<constant>VIDIOCGFBUF</constant> and <constant>VIDIOCSFBUF</constant>
619are &VIDIOC-G-FBUF; and &VIDIOC-S-FBUF;. The
620<structfield>base</structfield> field of struct
621<structname>video_buffer</structname> remained unchanged, except V4L2
622defines a flag to indicate non-destructive overlays instead of a
623<constant>NULL</constant> pointer. All other fields moved into the
624&v4l2-pix-format; <structfield>fmt</structfield> substructure of
625&v4l2-framebuffer;. The <structfield>depth</structfield> field was
626replaced by <structfield>pixelformat</structfield>. See <xref
627 linkend="pixfmt-rgb" /> for a list of RGB formats and their
628respective color depths.</para>
629
630 <para>Instead of the special ioctls
631<constant>VIDIOCGWIN</constant> and <constant>VIDIOCSWIN</constant>
632V4L2 uses the general-purpose data format negotiation ioctls
633&VIDIOC-G-FMT; and &VIDIOC-S-FMT;. They take a pointer to a
634&v4l2-format; as argument. Here the <structfield>win</structfield>
635member of the <structfield>fmt</structfield> union is used, a
636&v4l2-window;.</para>
637
638 <para>The <structfield>x</structfield>,
639<structfield>y</structfield>, <structfield>width</structfield> and
640<structfield>height</structfield> fields of struct
641<structname>video_window</structname> moved into &v4l2-rect;
642substructure <structfield>w</structfield> of struct
643<structname>v4l2_window</structname>. The
644<structfield>chromakey</structfield>,
645<structfield>clips</structfield>, and
646<structfield>clipcount</structfield> fields remained unchanged. Struct
647<structname>video_clip</structname> was renamed to &v4l2-clip;, also
648containing a struct <structname>v4l2_rect</structname>, but the
649semantics are still the same.</para>
650
651 <para>The <constant>VIDEO_WINDOW_INTERLACE</constant> flag was
652dropped. Instead applications must set the
653<structfield>field</structfield> field to
654<constant>V4L2_FIELD_ANY</constant> or
655<constant>V4L2_FIELD_INTERLACED</constant>. The
656<constant>VIDEO_WINDOW_CHROMAKEY</constant> flag moved into
657&v4l2-framebuffer;, under the new name
658<constant>V4L2_FBUF_FLAG_CHROMAKEY</constant>.</para>
659
660 <para>In V4L, storing a bitmap pointer in
661<structfield>clips</structfield> and setting
662<structfield>clipcount</structfield> to
663<constant>VIDEO_CLIP_BITMAP</constant> (-1) requests bitmap
664clipping, using a fixed size bitmap of 1024 &times; 625 bits. Struct
665<structname>v4l2_window</structname> has a separate
666<structfield>bitmap</structfield> pointer field for this purpose and
667the bitmap size is determined by <structfield>w.width</structfield> and
668<structfield>w.height</structfield>.</para>
669
670 <para>The <constant>VIDIOCCAPTURE</constant> ioctl to enable or
671disable overlay was renamed to &VIDIOC-OVERLAY;.</para>
672 </section>
673
674 <section>
675 <title>Cropping</title>
676
677 <para>To capture only a subsection of the full picture V4L
678defines the <constant>VIDIOCGCAPTURE</constant> and
679<constant>VIDIOCSCAPTURE</constant> ioctls using struct
680<structname>video_capture</structname>. The equivalent V4L2 ioctls are
681&VIDIOC-G-CROP; and &VIDIOC-S-CROP; using &v4l2-crop;, and the related
682&VIDIOC-CROPCAP; ioctl. This is a rather complex matter, see
683<xref linkend="crop" /> for details.</para>
684
685 <para>The <structfield>x</structfield>,
686<structfield>y</structfield>, <structfield>width</structfield> and
687<structfield>height</structfield> fields moved into &v4l2-rect;
688substructure <structfield>c</structfield> of struct
689<structname>v4l2_crop</structname>. The
690<structfield>decimation</structfield> field was dropped. In the V4L2
691API the scaling factor is implied by the size of the cropping
692rectangle and the size of the captured or overlaid image.</para>
693
694 <para>The <constant>VIDEO_CAPTURE_ODD</constant>
695and <constant>VIDEO_CAPTURE_EVEN</constant> flags to capture only the
696odd or even field, respectively, were replaced by
697<constant>V4L2_FIELD_TOP</constant> and
698<constant>V4L2_FIELD_BOTTOM</constant> in the field named
699<structfield>field</structfield> of &v4l2-pix-format; and
700&v4l2-window;. These structures are used to select a capture or
701overlay format with the &VIDIOC-S-FMT; ioctl.</para>
702 </section>
703
704 <section>
705 <title>Reading Images, Memory Mapping</title>
706
707 <section>
708 <title>Capturing using the read method</title>
709
710 <para>There is no essential difference between reading images
711from a V4L or V4L2 device using the &func-read; function, however V4L2
712drivers are not required to support this I/O method. Applications can
713determine if the function is available with the &VIDIOC-QUERYCAP;
714ioctl. All V4L2 devices exchanging data with applications must support
715the &func-select; and &func-poll; functions.</para>
716
717 <para>To select an image format and size, V4L provides the
718<constant>VIDIOCSPICT</constant> and <constant>VIDIOCSWIN</constant>
719ioctls. V4L2 uses the general-purpose data format negotiation ioctls
720&VIDIOC-G-FMT; and &VIDIOC-S-FMT;. They take a pointer to a
721&v4l2-format; as argument, here the &v4l2-pix-format; named
722<structfield>pix</structfield> of its <structfield>fmt</structfield>
723union is used.</para>
724
725 <para>For more information about the V4L2 read interface see
726<xref linkend="rw" />.</para>
727 </section>
728 <section>
729 <title>Capturing using memory mapping</title>
730
731 <para>Applications can read from V4L devices by mapping
732buffers in device memory, or more often just buffers allocated in
733DMA-able system memory, into their address space. This avoids the data
734copying overhead of the read method. V4L2 supports memory mapping as
735well, with a few differences.</para>
736
737 <informaltable>
738 <tgroup cols="2">
739 <thead>
740 <row>
741 <entry>V4L</entry>
742 <entry>V4L2</entry>
743 </row>
744 </thead>
745 <tbody valign="top">
746 <row>
747 <entry></entry>
748 <entry>The image format must be selected before
749buffers are allocated, with the &VIDIOC-S-FMT; ioctl. When no format
750is selected the driver may use the last, possibly by another
751application requested format.</entry>
752 </row>
753 <row>
754 <entry><para>Applications cannot change the number of
755buffers. The it is built into the driver, unless it has a module
756option to change the number when the driver module is
757loaded.</para></entry>
758 <entry><para>The &VIDIOC-REQBUFS; ioctl allocates the
759desired number of buffers, this is a required step in the initialization
760sequence.</para></entry>
761 </row>
762 <row>
763 <entry><para>Drivers map all buffers as one contiguous
764range of memory. The <constant>VIDIOCGMBUF</constant> ioctl is
765available to query the number of buffers, the offset of each buffer
766from the start of the virtual file, and the overall amount of memory
767used, which can be used as arguments for the &func-mmap;
768function.</para></entry>
769 <entry><para>Buffers are individually mapped. The
770offset and size of each buffer can be determined with the
771&VIDIOC-QUERYBUF; ioctl.</para></entry>
772 </row>
773 <row>
774 <entry><para>The <constant>VIDIOCMCAPTURE</constant>
775ioctl prepares a buffer for capturing. It also determines the image
776format for this buffer. The ioctl returns immediately, eventually with
777an &EAGAIN; if no video signal had been detected. When the driver
778supports more than one buffer applications can call the ioctl multiple
779times and thus have multiple outstanding capture
780requests.</para><para>The <constant>VIDIOCSYNC</constant> ioctl
781suspends execution until a particular buffer has been
782filled.</para></entry>
783 <entry><para>Drivers maintain an incoming and outgoing
784queue. &VIDIOC-QBUF; enqueues any empty buffer into the incoming
785queue. Filled buffers are dequeued from the outgoing queue with the
786&VIDIOC-DQBUF; ioctl. To wait until filled buffers become available this
787function, &func-select; or &func-poll; can be used. The
788&VIDIOC-STREAMON; ioctl must be called once after enqueuing one or
789more buffers to start capturing. Its counterpart
790&VIDIOC-STREAMOFF; stops capturing and dequeues all buffers from both
791queues. Applications can query the signal status, if known, with the
792&VIDIOC-ENUMINPUT; ioctl.</para></entry>
793 </row>
794 </tbody>
795 </tgroup>
796 </informaltable>
797
798 <para>For a more in-depth discussion of memory mapping and
799examples, see <xref linkend="mmap" />.</para>
800 </section>
801 </section>
802
803 <section>
804 <title>Reading Raw VBI Data</title>
805
806 <para>Originally the V4L API did not specify a raw VBI capture
807interface, only the device file <filename>/dev/vbi</filename> was
808reserved for this purpose. The only driver supporting this interface
809was the BTTV driver, de-facto defining the V4L VBI interface. Reading
810from the device yields a raw VBI image with the following
811parameters:<informaltable>
812 <tgroup cols="2">
813 <thead>
814 <row>
815 <entry>&v4l2-vbi-format;</entry>
816 <entry>V4L, BTTV driver</entry>
817 </row>
818 </thead>
819 <tbody valign="top">
820 <row>
821 <entry>sampling_rate</entry>
822 <entry>28636363&nbsp;Hz NTSC (or any other 525-line
823standard); 35468950&nbsp;Hz PAL and SECAM (625-line standards)</entry>
824 </row>
825 <row>
826 <entry>offset</entry>
827 <entry>?</entry>
828 </row>
829 <row>
830 <entry>samples_per_line</entry>
831 <entry>2048</entry>
832 </row>
833 <row>
834 <entry>sample_format</entry>
835 <entry>V4L2_PIX_FMT_GREY. The last four bytes (a
836machine endianess integer) contain a frame counter.</entry>
837 </row>
838 <row>
839 <entry>start[]</entry>
840 <entry>10, 273 NTSC; 22, 335 PAL and SECAM</entry>
841 </row>
842 <row>
843 <entry>count[]</entry>
844 <entry><para>16, 16<footnote><para>Old driver
845versions used different values, eventually the custom
846<constant>BTTV_VBISIZE</constant> ioctl was added to query the
847correct values.</para></footnote></para></entry>
848 </row>
849 <row>
850 <entry>flags</entry>
851 <entry>0</entry>
852 </row>
853 </tbody>
854 </tgroup>
855 </informaltable></para>
856
857 <para>Undocumented in the V4L specification, in Linux 2.3 the
858<constant>VIDIOCGVBIFMT</constant> and
859<constant>VIDIOCSVBIFMT</constant> ioctls using struct
860<structname>vbi_format</structname> were added to determine the VBI
861image parameters. These ioctls are only partially compatible with the
862V4L2 VBI interface specified in <xref linkend="raw-vbi" />.</para>
863
864 <para>An <structfield>offset</structfield> field does not
865exist, <structfield>sample_format</structfield> is supposed to be
866<constant>VIDEO_PALETTE_RAW</constant>, equivalent to
867<constant>V4L2_PIX_FMT_GREY</constant>. The remaining fields are
868probably equivalent to &v4l2-vbi-format;.</para>
869
870 <para>Apparently only the Zoran (ZR 36120) driver implements
871these ioctls. The semantics differ from those specified for V4L2 in two
872ways. The parameters are reset on &func-open; and
873<constant>VIDIOCSVBIFMT</constant> always returns an &EINVAL; if the
874parameters are invalid.</para>
875 </section>
876
877 <section>
878 <title>Miscellaneous</title>
879
880 <para>V4L2 has no equivalent of the
881<constant>VIDIOCGUNIT</constant> ioctl. Applications can find the VBI
882device associated with a video capture device (or vice versa) by
883reopening the device and requesting VBI data. For details see
884<xref linkend="open" />.</para>
885
886 <para>No replacement exists for <constant>VIDIOCKEY</constant>,
887and the V4L functions for microcode programming. A new interface for
888MPEG compression and playback devices is documented in <xref
889 linkend="extended-controls" />.</para>
890 </section>
891
892 </section>
893
894 <section id="hist-v4l2">
895 <title>Changes of the V4L2 API</title>
896
897 <para>Soon after the V4L API was added to the kernel it was
898criticised as too inflexible. In August 1998 Bill Dirks proposed a
899number of improvements and began to work on documentation, example
900drivers and applications. With the help of other volunteers this
901eventually became the V4L2 API, not just an extension but a
902replacement for the V4L API. However it took another four years and
903two stable kernel releases until the new API was finally accepted for
904inclusion into the kernel in its present form.</para>
905
906 <section>
907 <title>Early Versions</title>
908 <para>1998-08-20: First version.</para>
909
910 <para>1998-08-27: The &func-select; function was introduced.</para>
911
912 <para>1998-09-10: New video standard interface.</para>
913
914 <para>1998-09-18: The <constant>VIDIOC_NONCAP</constant> ioctl
915was replaced by the otherwise meaningless <constant>O_TRUNC</constant>
916&func-open; flag, and the aliases <constant>O_NONCAP</constant> and
917<constant>O_NOIO</constant> were defined. Applications can set this
918flag if they intend to access controls only, as opposed to capture
919applications which need exclusive access. The
920<constant>VIDEO_STD_XXX</constant> identifiers are now ordinals
921instead of flags, and the <function>video_std_construct()</function>
922helper function takes id and transmission arguments.</para>
923
924 <para>1998-09-28: Revamped video standard. Made video controls
925individually enumerable.</para>
926
927 <para>1998-10-02: The <structfield>id</structfield> field was
928removed from struct <structname>video_standard</structname> and the
929color subcarrier fields were renamed. The &VIDIOC-QUERYSTD; ioctl was
930renamed to &VIDIOC-ENUMSTD;, &VIDIOC-G-INPUT; to &VIDIOC-ENUMINPUT;. A
931first draft of the Codec API was released.</para>
932
933 <para>1998-11-08: Many minor changes. Most symbols have been
934renamed. Some material changes to &v4l2-capability;.</para>
935
936 <para>1998-11-12: The read/write directon of some ioctls was misdefined.</para>
937
938 <para>1998-11-14: <constant>V4L2_PIX_FMT_RGB24</constant>
939changed to <constant>V4L2_PIX_FMT_BGR24</constant>, and
940<constant>V4L2_PIX_FMT_RGB32</constant> changed to
941<constant>V4L2_PIX_FMT_BGR32</constant>. Audio controls are now
942accessible with the &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls under
943names starting with <constant>V4L2_CID_AUDIO</constant>. The
944<constant>V4L2_MAJOR</constant> define was removed from
945<filename>videodev.h</filename> since it was only used once in the
946<filename>videodev</filename> kernel module. The
947<constant>YUV422</constant> and <constant>YUV411</constant> planar
948image formats were added.</para>
949
950 <para>1998-11-28: A few ioctl symbols changed. Interfaces for codecs and
951video output devices were added.</para>
952
953 <para>1999-01-14: A raw VBI capture interface was added.</para>
954
955 <para>1999-01-19: The <constant>VIDIOC_NEXTBUF</constant> ioctl
956 was removed.</para>
957 </section>
958
959 <section>
960 <title>V4L2 Version 0.16 1999-01-31</title>
961 <para>1999-01-27: There is now one QBUF ioctl, VIDIOC_QWBUF and VIDIOC_QRBUF
962are gone. VIDIOC_QBUF takes a v4l2_buffer as a parameter. Added
963digital zoom (cropping) controls.</para>
964 </section>
965
966 <!-- Where's 0.17? mhs couldn't find that videodev.h, perhaps Bill
967 forgot to bump the version number or never released it. -->
968
969 <section>
970 <title>V4L2 Version 0.18 1999-03-16</title>
971 <para>Added a v4l to V4L2 ioctl compatibility layer to
972videodev.c. Driver writers, this changes how you implement your ioctl
973handler. See the Driver Writer's Guide. Added some more control id
974codes.</para>
975 </section>
976
977 <section>
978 <title>V4L2 Version 0.19 1999-06-05</title>
979 <para>1999-03-18: Fill in the category and catname fields of
980v4l2_queryctrl objects before passing them to the driver. Required a
981minor change to the VIDIOC_QUERYCTRL handlers in the sample
982drivers.</para>
983 <para>1999-03-31: Better compatibility for v4l memory capture
984ioctls. Requires changes to drivers to fully support new compatibility
985features, see Driver Writer's Guide and v4l2cap.c. Added new control
986IDs: V4L2_CID_HFLIP, _VFLIP. Changed V4L2_PIX_FMT_YUV422P to _YUV422P,
987and _YUV411P to _YUV411P.</para>
988 <para>1999-04-04: Added a few more control IDs.</para>
989 <para>1999-04-07: Added the button control type.</para>
990 <para>1999-05-02: Fixed a typo in videodev.h, and added the
991V4L2_CTRL_FLAG_GRAYED (later V4L2_CTRL_FLAG_GRABBED) flag.</para>
992 <para>1999-05-20: Definition of VIDIOC_G_CTRL was wrong causing
993a malfunction of this ioctl.</para>
994 <para>1999-06-05: Changed the value of
995V4L2_CID_WHITENESS.</para>
996 </section>
997
998 <section>
999 <title>V4L2 Version 0.20 (1999-09-10)</title>
1000
1001 <para>Version 0.20 introduced a number of changes which were
1002<emphasis>not backward compatible</emphasis> with 0.19 and earlier
1003versions. Purpose of these changes was to simplify the API, while
1004making it more extensible and following common Linux driver API
1005conventions.</para>
1006
1007 <orderedlist>
1008 <listitem>
1009 <para>Some typos in <constant>V4L2_FMT_FLAG</constant>
1010symbols were fixed. &v4l2-clip; was changed for compatibility with
1011v4l. (1999-08-30)</para>
1012 </listitem>
1013
1014 <listitem>
1015 <para><constant>V4L2_TUNER_SUB_LANG1</constant> was added.
1016(1999-09-05)</para>
1017 </listitem>
1018
1019 <listitem>
1020 <para>All ioctl() commands that used an integer argument now
1021take a pointer to an integer. Where it makes sense, ioctls will return
1022the actual new value in the integer pointed to by the argument, a
1023common convention in the V4L2 API. The affected ioctls are:
1024VIDIOC_PREVIEW, VIDIOC_STREAMON, VIDIOC_STREAMOFF, VIDIOC_S_FREQ,
1025VIDIOC_S_INPUT, VIDIOC_S_OUTPUT, VIDIOC_S_EFFECT. For example
1026<programlisting>
1027err = ioctl (fd, VIDIOC_XXX, V4L2_XXX);
1028</programlisting> becomes <programlisting>
1029int a = V4L2_XXX; err = ioctl(fd, VIDIOC_XXX, &amp;a);
1030</programlisting>
1031 </para>
1032 </listitem>
1033
1034 <listitem>
1035 <para>All the different get- and set-format commands were
1036swept into one &VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctl taking a union
1037and a type field selecting the union member as parameter. Purpose is to
1038simplify the API by eliminating several ioctls and to allow new and
1039driver private data streams without adding new ioctls.</para>
1040
1041 <para>This change obsoletes the following ioctls:
1042<constant>VIDIOC_S_INFMT</constant>,
1043<constant>VIDIOC_G_INFMT</constant>,
1044<constant>VIDIOC_S_OUTFMT</constant>,
1045<constant>VIDIOC_G_OUTFMT</constant>,
1046<constant>VIDIOC_S_VBIFMT</constant> and
1047<constant>VIDIOC_G_VBIFMT</constant>. The image format structure
1048<structname>v4l2_format</structname> was renamed to &v4l2-pix-format;,
1049while &v4l2-format; is now the envelopping structure for all format
1050negotiations.</para>
1051 </listitem>
1052
1053 <listitem>
1054 <para>Similar to the changes above, the
1055<constant>VIDIOC_G_PARM</constant> and
1056<constant>VIDIOC_S_PARM</constant> ioctls were merged with
1057<constant>VIDIOC_G_OUTPARM</constant> and
1058<constant>VIDIOC_S_OUTPARM</constant>. A
1059<structfield>type</structfield> field in the new &v4l2-streamparm;
1060selects the respective union member.</para>
1061
1062 <para>This change obsoletes the
1063<constant>VIDIOC_G_OUTPARM</constant> and
1064<constant>VIDIOC_S_OUTPARM</constant> ioctls.</para>
1065 </listitem>
1066
1067 <listitem>
1068 <para>Control enumeration was simplified, and two new
1069control flags were introduced and one dropped. The
1070<structfield>catname</structfield> field was replaced by a
1071<structfield>group</structfield> field.</para>
1072
1073 <para>Drivers can now flag unsupported and temporarily
1074unavailable controls with <constant>V4L2_CTRL_FLAG_DISABLED</constant>
1075and <constant>V4L2_CTRL_FLAG_GRABBED</constant> respectively. The
1076<structfield>group</structfield> name indicates a possibly narrower
1077classification than the <structfield>category</structfield>. In other
1078words, there may be multiple groups within a category. Controls within
1079a group would typically be drawn within a group box. Controls in
1080different categories might have a greater separation, or may even
1081appear in separate windows.</para>
1082 </listitem>
1083
1084 <listitem>
1085 <para>The &v4l2-buffer; <structfield>timestamp</structfield>
1086was changed to a 64 bit integer, containing the sampling or output
1087time of the frame in nanoseconds. Additionally timestamps will be in
1088absolute system time, not starting from zero at the beginning of a
1089stream. The data type name for timestamps is stamp_t, defined as a
1090signed 64-bit integer. Output devices should not send a buffer out
1091until the time in the timestamp field has arrived. I would like to
1092follow SGI's lead, and adopt a multimedia timestamping system like
1093their UST (Unadjusted System Time). See
1094http://reality.sgi.com/cpirazzi_engr/lg/time/intro.html. [This link is
1095no longer valid.] UST uses timestamps that are 64-bit signed integers
1096(not struct timeval's) and given in nanosecond units. The UST clock
1097starts at zero when the system is booted and runs continuously and
1098uniformly. It takes a little over 292 years for UST to overflow. There
1099is no way to set the UST clock. The regular Linux time-of-day clock
1100can be changed periodically, which would cause errors if it were being
1101used for timestamping a multimedia stream. A real UST style clock will
1102require some support in the kernel that is not there yet. But in
1103anticipation, I will change the timestamp field to a 64-bit integer,
1104and I will change the v4l2_masterclock_gettime() function (used only
1105by drivers) to return a 64-bit integer.</para>
1106 </listitem>
1107
1108 <listitem>
1109 <para>A <structfield>sequence</structfield> field was added
1110to &v4l2-buffer;. The <structfield>sequence</structfield> field counts
1111captured frames, it is ignored by output devices. When a capture
1112driver drops a frame, the sequence number of that frame is
1113skipped.</para>
1114 </listitem>
1115 </orderedlist>
1116 </section>
1117
1118 <section>
1119 <title>V4L2 Version 0.20 incremental changes</title>
1120 <!-- Version number didn't change anymore, reason unknown. -->
1121
1122 <para>1999-12-23: In &v4l2-vbi-format; the
1123<structfield>reserved1</structfield> field became
1124<structfield>offset</structfield>. Previously drivers were required to
1125clear the <structfield>reserved1</structfield> field.</para>
1126
1127 <para>2000-01-13: The
1128 <constant>V4L2_FMT_FLAG_NOT_INTERLACED</constant> flag was added.</para>
1129
1130 <para>2000-07-31: The <filename>linux/poll.h</filename> header
1131is now included by <filename>videodev.h</filename> for compatibility
1132with the original <filename>videodev.h</filename> file.</para>
1133
1134 <para>2000-11-20: <constant>V4L2_TYPE_VBI_OUTPUT</constant> and
1135<constant>V4L2_PIX_FMT_Y41P</constant> were added.</para>
1136
1137 <para>2000-11-25: <constant>V4L2_TYPE_VBI_INPUT</constant> was
1138added.</para>
1139
1140 <para>2000-12-04: A couple typos in symbol names were fixed.</para>
1141
1142 <para>2001-01-18: To avoid namespace conflicts the
1143<constant>fourcc</constant> macro defined in the
1144<filename>videodev.h</filename> header file was renamed to
1145<constant>v4l2_fourcc</constant>.</para>
1146
1147 <para>2001-01-25: A possible driver-level compatibility problem
1148between the <filename>videodev.h</filename> file in Linux 2.4.0 and
1149the <filename>videodev.h</filename> file included in the
1150<filename>videodevX</filename> patch was fixed. Users of an earlier
1151version of <filename>videodevX</filename> on Linux 2.4.0 should
1152recompile their V4L and V4L2 drivers.</para>
1153
1154 <para>2001-01-26: A possible kernel-level incompatibility
1155between the <filename>videodev.h</filename> file in the
1156<filename>videodevX</filename> patch and the
1157<filename>videodev.h</filename> file in Linux 2.2.x with devfs patches
1158applied was fixed.</para>
1159
1160 <para>2001-03-02: Certain V4L ioctls which pass data in both
1161direction although they are defined with read-only parameter, did not
1162work correctly through the backward compatibility layer.
1163[Solution?]</para>
1164
1165 <para>2001-04-13: Big endian 16-bit RGB formats were added.</para>
1166
1167 <para>2001-09-17: New YUV formats and the &VIDIOC-G-FREQUENCY; and
1168&VIDIOC-S-FREQUENCY; ioctls were added. (The old
1169<constant>VIDIOC_G_FREQ</constant> and
1170<constant>VIDIOC_S_FREQ</constant> ioctls did not take multiple tuners
1171into account.)</para>
1172
1173 <para>2000-09-18: <constant>V4L2_BUF_TYPE_VBI</constant> was
1174added. This may <emphasis>break compatibility</emphasis> as the
1175&VIDIOC-G-FMT; and &VIDIOC-S-FMT; ioctls may fail now if the struct
1176<structname>v4l2_fmt</structname> <structfield>type</structfield>
1177field does not contain <constant>V4L2_BUF_TYPE_VBI</constant>. In the
1178documentation of the &v4l2-vbi-format;
1179<structfield>offset</structfield> field the ambiguous phrase "rising
1180edge" was changed to "leading edge".</para>
1181 </section>
1182
1183 <section>
1184 <title>V4L2 Version 0.20 2000-11-23</title>
1185
1186 <para>A number of changes were made to the raw VBI
1187interface.</para>
1188
1189 <orderedlist>
1190 <listitem>
1191 <para>Figures clarifying the line numbering scheme were
1192added to the V4L2 API specification. The
1193<structfield>start</structfield>[0] and
1194<structfield>start</structfield>[1] fields no longer count line
1195numbers beginning at zero. Rationale: a) The previous definition was
1196unclear. b) The <structfield>start</structfield>[] values are ordinal
1197numbers. c) There is no point in inventing a new line numbering
1198scheme. We now use line number as defined by ITU-R, period.
1199Compatibility: Add one to the start values. Applications depending on
1200the previous semantics may not function correctly.</para>
1201 </listitem>
1202
1203 <listitem>
1204 <para>The restriction "count[0] &gt; 0 and count[1] &gt; 0"
1205has been relaxed to "(count[0] + count[1]) &gt; 0". Rationale:
1206Drivers may allocate resources at scan line granularity and some data
1207services are transmitted only on the first field. The comment that
1208both <structfield>count</structfield> values will usually be equal is
1209misleading and pointless and has been removed. This change
1210<emphasis>breaks compatibility</emphasis> with earlier versions:
1211Drivers may return EINVAL, applications may not function
1212correctly.</para>
1213 </listitem>
1214
1215 <listitem>
1216 <para>Drivers are again permitted to return negative
1217(unknown) start values as proposed earlier. Why this feature was
1218dropped is unclear. This change may <emphasis>break
1219compatibility</emphasis> with applications depending on the start
1220values being positive. The use of <constant>EBUSY</constant> and
1221<constant>EINVAL</constant> error codes with the &VIDIOC-S-FMT; ioctl
1222was clarified. The &EBUSY; was finally documented, and the
1223<structfield>reserved2</structfield> field which was previously
1224mentioned only in the <filename>videodev.h</filename> header
1225file.</para>
1226 </listitem>
1227
1228 <listitem>
1229 <para>New buffer types
1230<constant>V4L2_TYPE_VBI_INPUT</constant> and
1231<constant>V4L2_TYPE_VBI_OUTPUT</constant> were added. The former is an
1232alias for the old <constant>V4L2_TYPE_VBI</constant>, the latter was
1233missing in the <filename>videodev.h</filename> file.</para>
1234 </listitem>
1235 </orderedlist>
1236 </section>
1237
1238 <section>
1239 <title>V4L2 Version 0.20 2002-07-25</title>
1240 <para>Added sliced VBI interface proposal.</para>
1241 </section>
1242
1243 <section>
1244 <title>V4L2 in Linux 2.5.46, 2002-10</title>
1245
1246 <para>Around October-November 2002, prior to an announced
1247feature freeze of Linux 2.5, the API was revised, drawing from
1248experience with V4L2 0.20. This unnamed version was finally merged
1249into Linux 2.5.46.</para>
1250
1251 <orderedlist>
1252 <listitem>
1253 <para>As specified in <xref linkend="related" />, drivers
1254must make related device functions available under all minor device
1255numbers.</para>
1256 </listitem>
1257
1258 <listitem>
1259 <para>The &func-open; function requires access mode
1260<constant>O_RDWR</constant> regardless of the device type. All V4L2
1261drivers exchanging data with applications must support the
1262<constant>O_NONBLOCK</constant> flag. The <constant>O_NOIO</constant>
1263flag, a V4L2 symbol which aliased the meaningless
1264<constant>O_TRUNC</constant> to indicate accesses without data
1265exchange (panel applications) was dropped. Drivers must stay in "panel
1266mode" until the application attempts to initiate a data exchange, see
1267<xref linkend="open" />.</para>
1268 </listitem>
1269
1270 <listitem>
1271 <para>The &v4l2-capability; changed dramatically. Note that
1272also the size of the structure changed, which is encoded in the ioctl
1273request code, thus older V4L2 devices will respond with an &EINVAL; to
1274the new &VIDIOC-QUERYCAP; ioctl.</para>
1275
1276 <para>There are new fields to identify the driver, a new RDS
1277device function <constant>V4L2_CAP_RDS_CAPTURE</constant>, the
1278<constant>V4L2_CAP_AUDIO</constant> flag indicates if the device has
1279any audio connectors, another I/O capability
1280<constant>V4L2_CAP_ASYNCIO</constant> can be flagged. In response to
1281these changes the <structfield>type</structfield> field became a bit
1282set and was merged into the <structfield>flags</structfield> field.
1283<constant>V4L2_FLAG_TUNER</constant> was renamed to
1284<constant>V4L2_CAP_TUNER</constant>,
1285<constant>V4L2_CAP_VIDEO_OVERLAY</constant> replaced
1286<constant>V4L2_FLAG_PREVIEW</constant> and
1287<constant>V4L2_CAP_VBI_CAPTURE</constant> and
1288<constant>V4L2_CAP_VBI_OUTPUT</constant> replaced
1289<constant>V4L2_FLAG_DATA_SERVICE</constant>.
1290<constant>V4L2_FLAG_READ</constant> and
1291<constant>V4L2_FLAG_WRITE</constant> were merged into
1292<constant>V4L2_CAP_READWRITE</constant>.</para>
1293
1294 <para>The redundant fields
1295<structfield>inputs</structfield>, <structfield>outputs</structfield>
1296and <structfield>audios</structfield> were removed. These properties
1297can be determined as described in <xref linkend="video" /> and <xref
1298linkend="audio" />.</para>
1299
1300 <para>The somewhat volatile and therefore barely useful
1301fields <structfield>maxwidth</structfield>,
1302<structfield>maxheight</structfield>,
1303<structfield>minwidth</structfield>,
1304<structfield>minheight</structfield>,
1305<structfield>maxframerate</structfield> were removed. This information
1306is available as described in <xref linkend="format" /> and
1307<xref linkend="standard" />.</para>
1308
1309 <para><constant>V4L2_FLAG_SELECT</constant> was removed. We
1310believe the select() function is important enough to require support
1311of it in all V4L2 drivers exchanging data with applications. The
1312redundant <constant>V4L2_FLAG_MONOCHROME</constant> flag was removed,
1313this information is available as described in <xref
1314 linkend="format" />.</para>
1315 </listitem>
1316
1317 <listitem>
1318 <para>In &v4l2-input; the
1319<structfield>assoc_audio</structfield> field and the
1320<structfield>capability</structfield> field and its only flag
1321<constant>V4L2_INPUT_CAP_AUDIO</constant> was replaced by the new
1322<structfield>audioset</structfield> field. Instead of linking one
1323video input to one audio input this field reports all audio inputs
1324this video input combines with.</para>
1325
1326 <para>New fields are <structfield>tuner</structfield>
1327(reversing the former link from tuners to video inputs),
1328<structfield>std</structfield> and
1329<structfield>status</structfield>.</para>
1330
1331 <para>Accordingly &v4l2-output; lost its
1332<structfield>capability</structfield> and
1333<structfield>assoc_audio</structfield> fields.
1334<structfield>audioset</structfield>,
1335<structfield>modulator</structfield> and
1336<structfield>std</structfield> where added instead.</para>
1337 </listitem>
1338
1339 <listitem>
1340 <para>The &v4l2-audio; field
1341<structfield>audio</structfield> was renamed to
1342<structfield>index</structfield>, for consistency with other
1343structures. A new capability flag
1344<constant>V4L2_AUDCAP_STEREO</constant> was added to indicated if the
1345audio input in question supports stereo sound.
1346<constant>V4L2_AUDCAP_EFFECTS</constant> and the corresponding
1347<constant>V4L2_AUDMODE</constant> flags where removed. This can be
1348easily implemented using controls. (However the same applies to AVL
1349which is still there.)</para>
1350
1351 <para>Again for consistency the &v4l2-audioout; field
1352<structfield>audio</structfield> was renamed to
1353<structfield>index</structfield>.</para>
1354 </listitem>
1355
1356 <listitem>
1357 <para>The &v4l2-tuner;
1358<structfield>input</structfield> field was replaced by an
1359<structfield>index</structfield> field, permitting devices with
1360multiple tuners. The link between video inputs and tuners is now
1361reversed, inputs point to their tuner. The
1362<structfield>std</structfield> substructure became a
1363simple set (more about this below) and moved into &v4l2-input;. A
1364<structfield>type</structfield> field was added.</para>
1365
1366 <para>Accordingly in &v4l2-modulator; the
1367<structfield>output</structfield> was replaced by an
1368<structfield>index</structfield> field.</para>
1369
1370 <para>In &v4l2-frequency; the
1371<structfield>port</structfield> field was replaced by a
1372<structfield>tuner</structfield> field containing the respective tuner
1373or modulator index number. A tuner <structfield>type</structfield>
1374field was added and the <structfield>reserved</structfield> field
1375became larger for future extensions (satellite tuners in
1376particular).</para>
1377 </listitem>
1378
1379 <listitem>
1380 <para>The idea of completely transparent video standards was
1381dropped. Experience showed that applications must be able to work with
1382video standards beyond presenting the user a menu. Instead of
1383enumerating supported standards with an ioctl applications can now
1384refer to standards by &v4l2-std-id; and symbols defined in the
1385<filename>videodev2.h</filename> header file. For details see <xref
1386 linkend="standard" />. The &VIDIOC-G-STD; and
1387&VIDIOC-S-STD; now take a pointer to this type as argument.
1388&VIDIOC-QUERYSTD; was added to autodetect the received standard, if
1389the hardware has this capability. In &v4l2-standard; an
1390<structfield>index</structfield> field was added for &VIDIOC-ENUMSTD;.
1391A &v4l2-std-id; field named <structfield>id</structfield> was added as
1392machine readable identifier, also replacing the
1393<structfield>transmission</structfield> field. The misleading
1394<structfield>framerate</structfield> field was renamed
1395to <structfield>frameperiod</structfield>. The now obsolete
1396<structfield>colorstandard</structfield> information, originally
1397needed to distguish between variations of standards, were
1398removed.</para>
1399
1400 <para>Struct <structname>v4l2_enumstd</structname> ceased to
1401be. &VIDIOC-ENUMSTD; now takes a pointer to a &v4l2-standard;
1402directly. The information which standards are supported by a
1403particular video input or output moved into &v4l2-input; and
1404&v4l2-output; fields named <structfield>std</structfield>,
1405respectively.</para>
1406 </listitem>
1407
1408 <listitem>
1409 <para>The &v4l2-queryctrl; fields
1410<structfield>category</structfield> and
1411<structfield>group</structfield> did not catch on and/or were not
1412implemented as expected and therefore removed.</para>
1413 </listitem>
1414
1415 <listitem>
1416 <para>The &VIDIOC-TRY-FMT; ioctl was added to negotiate data
1417formats as with &VIDIOC-S-FMT;, but without the overhead of
1418programming the hardware and regardless of I/O in progress.</para>
1419
1420 <para>In &v4l2-format; the <structfield>fmt</structfield>
1421union was extended to contain &v4l2-window;. All image format
1422negotiations are now possible with <constant>VIDIOC_G_FMT</constant>,
1423<constant>VIDIOC_S_FMT</constant> and
1424<constant>VIDIOC_TRY_FMT</constant>; ioctl. The
1425<constant>VIDIOC_G_WIN</constant> and
1426<constant>VIDIOC_S_WIN</constant> ioctls to prepare for a video
1427overlay were removed. The <structfield>type</structfield> field
1428changed to type &v4l2-buf-type; and the buffer type names changed as
1429follows.<informaltable>
1430 <tgroup cols="2">
1431 <thead>
1432 <row>
1433 <entry>Old defines</entry>
1434 <entry>&v4l2-buf-type;</entry>
1435 </row>
1436 </thead>
1437 <tbody valign="top">
1438 <row>
1439 <entry><constant>V4L2_BUF_TYPE_CAPTURE</constant></entry>
1440 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
1441 </row>
1442 <row>
1443 <entry><constant>V4L2_BUF_TYPE_CODECIN</constant></entry>
1444 <entry>Omitted for now</entry>
1445 </row>
1446 <row>
1447 <entry><constant>V4L2_BUF_TYPE_CODECOUT</constant></entry>
1448 <entry>Omitted for now</entry>
1449 </row>
1450 <row>
1451 <entry><constant>V4L2_BUF_TYPE_EFFECTSIN</constant></entry>
1452 <entry>Omitted for now</entry>
1453 </row>
1454 <row>
1455 <entry><constant>V4L2_BUF_TYPE_EFFECTSIN2</constant></entry>
1456 <entry>Omitted for now</entry>
1457 </row>
1458 <row>
1459 <entry><constant>V4L2_BUF_TYPE_EFFECTSOUT</constant></entry>
1460 <entry>Omitted for now</entry>
1461 </row>
1462 <row>
1463 <entry><constant>V4L2_BUF_TYPE_VIDEOOUT</constant></entry>
1464 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
1465 </row>
1466 <row>
1467 <entry><constant>-</constant></entry>
1468 <entry><constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant></entry>
1469 </row>
1470 <row>
1471 <entry><constant>-</constant></entry>
1472 <entry><constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant></entry>
1473 </row>
1474 <row>
1475 <entry><constant>-</constant></entry>
1476 <entry><constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant></entry>
1477 </row>
1478 <row>
1479 <entry><constant>-</constant></entry>
1480 <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant></entry>
1481 </row>
1482 <row>
1483 <entry><constant>-</constant></entry>
1484 <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant></entry>
1485 </row>
1486 <row>
1487 <entry><constant>V4L2_BUF_TYPE_PRIVATE_BASE</constant></entry>
1488 <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
1489 </row>
1490 </tbody>
1491 </tgroup>
1492 </informaltable></para>
1493 </listitem>
1494
1495 <listitem>
1496 <para>In &v4l2-fmtdesc; a &v4l2-buf-type; field named
1497<structfield>type</structfield> was added as in &v4l2-format;. The
1498<constant>VIDIOC_ENUM_FBUFFMT</constant> ioctl is no longer needed and
1499was removed. These calls can be replaced by &VIDIOC-ENUM-FMT; with
1500type <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>.</para>
1501 </listitem>
1502
1503 <listitem>
1504 <para>In &v4l2-pix-format; the
1505<structfield>depth</structfield> field was removed, assuming
1506applications which recognize the format by its four-character-code
1507already know the color depth, and others do not care about it. The
1508same rationale lead to the removal of the
1509<constant>V4L2_FMT_FLAG_COMPRESSED</constant> flag. The
1510<constant>V4L2_FMT_FLAG_SWCONVECOMPRESSED</constant> flag was removed
1511because drivers are not supposed to convert images in kernel space. A
1512user library of conversion functions should be provided instead. The
1513<constant>V4L2_FMT_FLAG_BYTESPERLINE</constant> flag was redundant.
1514Applications can set the <structfield>bytesperline</structfield> field
1515to zero to get a reasonable default. Since the remaining flags were
1516replaced as well, the <structfield>flags</structfield> field itself
1517was removed.</para>
1518 <para>The interlace flags were replaced by a &v4l2-field;
1519value in a newly added <structfield>field</structfield>
1520field.<informaltable>
1521 <tgroup cols="2">
1522 <thead>
1523 <row>
1524 <entry>Old flag</entry>
1525 <entry>&v4l2-field;</entry>
1526 </row>
1527 </thead>
1528 <tbody valign="top">
1529 <row>
1530 <entry><constant>V4L2_FMT_FLAG_NOT_INTERLACED</constant></entry>
1531 <entry>?</entry>
1532 </row>
1533 <row>
1534 <entry><constant>V4L2_FMT_FLAG_INTERLACED</constant>
1535= <constant>V4L2_FMT_FLAG_COMBINED</constant></entry>
1536 <entry><constant>V4L2_FIELD_INTERLACED</constant></entry>
1537 </row>
1538 <row>
1539 <entry><constant>V4L2_FMT_FLAG_TOPFIELD</constant>
1540= <constant>V4L2_FMT_FLAG_ODDFIELD</constant></entry>
1541 <entry><constant>V4L2_FIELD_TOP</constant></entry>
1542 </row>
1543 <row>
1544 <entry><constant>V4L2_FMT_FLAG_BOTFIELD</constant>
1545= <constant>V4L2_FMT_FLAG_EVENFIELD</constant></entry>
1546 <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
1547 </row>
1548 <row>
1549 <entry><constant>-</constant></entry>
1550 <entry><constant>V4L2_FIELD_SEQ_TB</constant></entry>
1551 </row>
1552 <row>
1553 <entry><constant>-</constant></entry>
1554 <entry><constant>V4L2_FIELD_SEQ_BT</constant></entry>
1555 </row>
1556 <row>
1557 <entry><constant>-</constant></entry>
1558 <entry><constant>V4L2_FIELD_ALTERNATE</constant></entry>
1559 </row>
1560 </tbody>
1561 </tgroup>
1562 </informaltable></para>
1563
1564 <para>The color space flags were replaced by a
1565&v4l2-colorspace; value in a newly added
1566<structfield>colorspace</structfield> field, where one of
1567<constant>V4L2_COLORSPACE_SMPTE170M</constant>,
1568<constant>V4L2_COLORSPACE_BT878</constant>,
1569<constant>V4L2_COLORSPACE_470_SYSTEM_M</constant> or
1570<constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant> replaces
1571<constant>V4L2_FMT_CS_601YUV</constant>.</para>
1572 </listitem>
1573
1574 <listitem>
1575 <para>In &v4l2-requestbuffers; the
1576<structfield>type</structfield> field was properly defined as
1577&v4l2-buf-type;. Buffer types changed as mentioned above. A new
1578<structfield>memory</structfield> field of type &v4l2-memory; was
1579added to distinguish between I/O methods using buffers allocated
1580by the driver or the application. See <xref linkend="io" /> for
1581details.</para>
1582 </listitem>
1583
1584 <listitem>
1585 <para>In &v4l2-buffer; the <structfield>type</structfield>
1586field was properly defined as &v4l2-buf-type;. Buffer types changed as
1587mentioned above. A <structfield>field</structfield> field of type
1588&v4l2-field; was added to indicate if a buffer contains a top or
1589bottom field. The old field flags were removed. Since no unadjusted
1590system time clock was added to the kernel as planned, the
1591<structfield>timestamp</structfield> field changed back from type
1592stamp_t, an unsigned 64 bit integer expressing the sample time in
1593nanoseconds, to struct <structname>timeval</structname>. With the
1594addition of a second memory mapping method the
1595<structfield>offset</structfield> field moved into union
1596<structfield>m</structfield>, and a new
1597<structfield>memory</structfield> field of type &v4l2-memory; was
1598added to distinguish between I/O methods. See <xref linkend="io" />
1599for details.</para>
1600
1601 <para>The <constant>V4L2_BUF_REQ_CONTIG</constant>
1602flag was used by the V4L compatibility layer, after changes to this
1603code it was no longer needed. The
1604<constant>V4L2_BUF_ATTR_DEVICEMEM</constant> flag would indicate if
1605the buffer was indeed allocated in device memory rather than DMA-able
1606system memory. It was barely useful and so was removed.</para>
1607 </listitem>
1608
1609 <listitem>
1610 <para>In &v4l2-framebuffer; the
1611<structfield>base[3]</structfield> array anticipating double- and
1612triple-buffering in off-screen video memory, however without defining
1613a synchronization mechanism, was replaced by a single pointer. The
1614<constant>V4L2_FBUF_CAP_SCALEUP</constant> and
1615<constant>V4L2_FBUF_CAP_SCALEDOWN</constant> flags were removed.
1616Applications can determine this capability more accurately using the
1617new cropping and scaling interface. The
1618<constant>V4L2_FBUF_CAP_CLIPPING</constant> flag was replaced by
1619<constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant> and
1620<constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant>.</para>
1621 </listitem>
1622
1623 <listitem>
1624 <para>In &v4l2-clip; the <structfield>x</structfield>,
1625<structfield>y</structfield>, <structfield>width</structfield> and
1626<structfield>height</structfield> field moved into a
1627<structfield>c</structfield> substructure of type &v4l2-rect;. The
1628<structfield>x</structfield> and <structfield>y</structfield> fields
1629were renamed to <structfield>left</structfield> and
1630<structfield>top</structfield>, &ie; offsets to a context dependent
1631origin.</para>
1632 </listitem>
1633
1634 <listitem>
1635 <para>In &v4l2-window; the <structfield>x</structfield>,
1636<structfield>y</structfield>, <structfield>width</structfield> and
1637<structfield>height</structfield> field moved into a
1638<structfield>w</structfield> substructure as above. A
1639<structfield>field</structfield> field of type %v4l2-field; was added
1640to distinguish between field and frame (interlaced) overlay.</para>
1641 </listitem>
1642
1643 <listitem>
1644 <para>The digital zoom interface, including struct
1645<structname>v4l2_zoomcap</structname>, struct
1646<structname>v4l2_zoom</structname>,
1647<constant>V4L2_ZOOM_NONCAP</constant> and
1648<constant>V4L2_ZOOM_WHILESTREAMING</constant> was replaced by a new
1649cropping and scaling interface. The previously unused struct
1650<structname>v4l2_cropcap</structname> and
1651<structname>v4l2_crop</structname> where redefined for this purpose.
1652See <xref linkend="crop" /> for details.</para>
1653 </listitem>
1654
1655 <listitem>
1656 <para>In &v4l2-vbi-format; the
1657<structfield>SAMPLE_FORMAT</structfield> field now contains a
1658four-character-code as used to identify video image formats and
1659<constant>V4L2_PIX_FMT_GREY</constant> replaces the
1660<constant>V4L2_VBI_SF_UBYTE</constant> define. The
1661<structfield>reserved</structfield> field was extended.</para>
1662 </listitem>
1663
1664 <listitem>
1665 <para>In &v4l2-captureparm; the type of the
1666<structfield>timeperframe</structfield> field changed from unsigned
1667long to &v4l2-fract;. This allows the accurate expression of multiples
1668of the NTSC-M frame rate 30000 / 1001. A new field
1669<structfield>readbuffers</structfield> was added to control the driver
1670behaviour in read I/O mode.</para>
1671
1672 <para>Similar changes were made to &v4l2-outputparm;.</para>
1673 </listitem>
1674
1675 <listitem>
1676 <para>The struct <structname>v4l2_performance</structname>
1677and <constant>VIDIOC_G_PERF</constant> ioctl were dropped. Except when
1678using the <link linkend="rw">read/write I/O method</link>, which is
1679limited anyway, this information is already available to
1680applications.</para>
1681 </listitem>
1682
1683 <listitem>
1684 <para>The example transformation from RGB to YCbCr color
1685space in the old V4L2 documentation was inaccurate, this has been
1686corrected in <xref linkend="pixfmt" />.<!-- 0.5670G should be
16870.587, and 127/112 != 255/224 --></para>
1688 </listitem>
1689 </orderedlist>
1690 </section>
1691
1692 <section>
1693 <title>V4L2 2003-06-19</title>
1694
1695 <orderedlist>
1696 <listitem>
1697 <para>A new capability flag
1698<constant>V4L2_CAP_RADIO</constant> was added for radio devices. Prior
1699to this change radio devices would identify solely by having exactly one
1700tuner whose type field reads <constant>V4L2_TUNER_RADIO</constant>.</para>
1701 </listitem>
1702
1703 <listitem>
1704 <para>An optional driver access priority mechanism was
1705added, see <xref linkend="app-pri" /> for details.</para>
1706 </listitem>
1707
1708 <listitem>
1709 <para>The audio input and output interface was found to be
1710incomplete.</para>
1711 <para>Previously the &VIDIOC-G-AUDIO;
1712ioctl would enumerate the available audio inputs. An ioctl to
1713determine the current audio input, if more than one combines with the
1714current video input, did not exist. So
1715<constant>VIDIOC_G_AUDIO</constant> was renamed to
1716<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl will be removed in
1717the future. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate
1718audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio
1719input.</para>
1720 <para>The same changes were made to &VIDIOC-G-AUDOUT; and
1721&VIDIOC-ENUMAUDOUT;.</para>
1722 <para>Until further the "videodev" module will automatically
1723translate between the old and new ioctls, but drivers and applications
1724must be updated to successfully compile again.</para>
1725 </listitem>
1726
1727 <listitem>
1728 <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with
1729write-read parameter. It was changed to write-only, while the write-read
1730version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old
1731ioctl will be removed in the future. Until further the "videodev"
1732kernel module will automatically translate to the new version, so drivers
1733must be recompiled, but not applications.</para>
1734 </listitem>
1735
1736 <listitem>
1737 <para><xref linkend="overlay" /> incorrectly stated that
1738clipping rectangles define regions where the video can be seen.
1739Correct is that clipping rectangles define regions where
1740<emphasis>no</emphasis> video shall be displayed and so the graphics
1741surface can be seen.</para>
1742 </listitem>
1743
1744 <listitem>
1745 <para>The &VIDIOC-S-PARM; and &VIDIOC-S-CTRL; ioctls were
1746defined with write-only parameter, inconsistent with other ioctls
1747modifying their argument. They were changed to write-read, while a
1748<constant>_OLD</constant> suffix was added to the write-only versions.
1749The old ioctls will be removed in the future. Drivers and
1750applications assuming a constant parameter need an update.</para>
1751 </listitem>
1752 </orderedlist>
1753 </section>
1754
1755 <section>
1756 <title>V4L2 2003-11-05</title>
1757 <orderedlist>
1758 <listitem>
1759 <para>In <xref linkend="pixfmt-rgb" /> the following pixel
1760formats were incorrectly transferred from Bill Dirks' V4L2
1761specification. Descriptions below refer to bytes in memory, in
1762ascending address order.<informaltable>
1763 <tgroup cols="3">
1764 <thead>
1765 <row>
1766 <entry>Symbol</entry>
1767 <entry>In this document prior to revision
17680.5</entry>
1769 <entry>Corrected</entry>
1770 </row>
1771 </thead>
1772 <tbody valign="top">
1773 <row>
1774 <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
1775 <entry>B, G, R</entry>
1776 <entry>R, G, B</entry>
1777 </row>
1778 <row>
1779 <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
1780 <entry>R, G, B</entry>
1781 <entry>B, G, R</entry>
1782 </row>
1783 <row>
1784 <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
1785 <entry>B, G, R, X</entry>
1786 <entry>R, G, B, X</entry>
1787 </row>
1788 <row>
1789 <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
1790 <entry>R, G, B, X</entry>
1791 <entry>B, G, R, X</entry>
1792 </row>
1793 </tbody>
1794 </tgroup>
1795 </informaltable> The
1796<constant>V4L2_PIX_FMT_BGR24</constant> example was always
1797correct.</para>
1798 <para>In <xref linkend="v4l-image-properties" /> the mapping
1799of the V4L <constant>VIDEO_PALETTE_RGB24</constant> and
1800<constant>VIDEO_PALETTE_RGB32</constant> formats to V4L2 pixel formats
1801was accordingly corrected.</para>
1802 </listitem>
1803
1804 <listitem>
1805 <para>Unrelated to the fixes above, drivers may still
1806interpret some V4L2 RGB pixel formats differently. These issues have
1807yet to be addressed, for details see <xref
1808 linkend="pixfmt-rgb" />.</para>
1809 </listitem>
1810 </orderedlist>
1811 </section>
1812
1813 <section>
1814 <title>V4L2 in Linux 2.6.6, 2004-05-09</title>
1815 <orderedlist>
1816 <listitem>
1817 <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined
1818with read-only parameter. It is now defined as write-read ioctl, while
1819the read-only version was renamed to
1820<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl will be removed
1821in the future.</para>
1822 </listitem>
1823 </orderedlist>
1824 </section>
1825
1826 <section>
1827 <title>V4L2 in Linux 2.6.8</title>
1828 <orderedlist>
1829 <listitem>
1830 <para>A new field <structfield>input</structfield> (former
1831<structfield>reserved[0]</structfield>) was added to the &v4l2-buffer;
1832structure. Purpose of this field is to alternate between video inputs
1833(&eg; cameras) in step with the video capturing process. This function
1834must be enabled with the new <constant>V4L2_BUF_FLAG_INPUT</constant>
1835flag. The <structfield>flags</structfield> field is no longer
1836read-only.</para>
1837 </listitem>
1838 </orderedlist>
1839 </section>
1840
1841 <section>
1842 <title>V4L2 spec erratum 2004-08-01</title>
1843
1844 <orderedlist>
1845 <listitem>
1846 <para>The return value of the
1847<xref linkend="func-open" /> function was incorrectly documented.</para>
1848 </listitem>
1849
1850 <listitem>
1851 <para>Audio output ioctls end in -AUDOUT, not -AUDIOOUT.</para>
1852 </listitem>
1853
1854 <listitem>
1855 <para>In the Current Audio Input example the
1856<constant>VIDIOC_G_AUDIO</constant> ioctl took the wrong
1857argument.</para>
1858 </listitem>
1859
1860 <listitem>
1861 <para>The documentation of the &VIDIOC-QBUF; and
1862&VIDIOC-DQBUF; ioctls did not mention the &v4l2-buffer;
1863<structfield>memory</structfield> field. It was also missing from
1864examples. Also on the <constant>VIDIOC_DQBUF</constant> page the &EIO;
1865was not documented.</para>
1866 </listitem>
1867 </orderedlist>
1868 </section>
1869
1870 <section>
1871 <title>V4L2 in Linux 2.6.14</title>
1872 <orderedlist>
1873 <listitem>
1874 <para>A new sliced VBI interface was added. It is documented
1875in <xref linkend="sliced" /> and replaces the interface first
1876proposed in V4L2 specification 0.8.</para>
1877 </listitem>
1878 </orderedlist>
1879 </section>
1880
1881 <section>
1882 <title>V4L2 in Linux 2.6.15</title>
1883 <orderedlist>
1884 <listitem>
1885 <para>The &VIDIOC-LOG-STATUS; ioctl was added.</para>
1886 </listitem>
1887
1888 <listitem>
1889 <para>New video standards
1890<constant>V4L2_STD_NTSC_443</constant>,
1891<constant>V4L2_STD_SECAM_LC</constant>,
1892<constant>V4L2_STD_SECAM_DK</constant> (a set of SECAM D, K and K1),
1893and <constant>V4L2_STD_ATSC</constant> (a set of
1894<constant>V4L2_STD_ATSC_8_VSB</constant> and
1895<constant>V4L2_STD_ATSC_16_VSB</constant>) were defined. Note the
1896<constant>V4L2_STD_525_60</constant> set now includes
1897<constant>V4L2_STD_NTSC_443</constant>. See also <xref
1898 linkend="v4l2-std-id" />.</para>
1899 </listitem>
1900
1901 <listitem>
1902 <para>The <constant>VIDIOC_G_COMP</constant> and
1903<constant>VIDIOC_S_COMP</constant> ioctl were renamed to
1904<constant>VIDIOC_G_MPEGCOMP</constant> and
1905<constant>VIDIOC_S_MPEGCOMP</constant> respectively. Their argument
1906was replaced by a struct
1907<structname>v4l2_mpeg_compression</structname> pointer. (The
1908<constant>VIDIOC_G_MPEGCOMP</constant> and
1909<constant>VIDIOC_S_MPEGCOMP</constant> ioctls where removed in Linux
19102.6.25.)</para>
1911 </listitem>
1912 </orderedlist>
1913 </section>
1914
1915 <section>
1916 <title>V4L2 spec erratum 2005-11-27</title>
1917 <para>The capture example in <xref linkend="capture-example" />
1918called the &VIDIOC-S-CROP; ioctl without checking if cropping is
1919supported. In the video standard selection example in
1920<xref linkend="standard" /> the &VIDIOC-S-STD; call used the wrong
1921argument type.</para>
1922 </section>
1923
1924 <section>
1925 <title>V4L2 spec erratum 2006-01-10</title>
1926 <orderedlist>
1927 <listitem>
1928 <para>The <constant>V4L2_IN_ST_COLOR_KILL</constant> flag in
1929&v4l2-input; not only indicates if the color killer is enabled, but
1930also if it is active. (The color killer disables color decoding when
1931it detects no color in the video signal to improve the image
1932quality.)</para>
1933 </listitem>
1934
1935 <listitem>
1936 <para>&VIDIOC-S-PARM; is a write-read ioctl, not write-only as
1937stated on its reference page. The ioctl changed in 2003 as noted above.</para>
1938 </listitem>
1939 </orderedlist>
1940 </section>
1941
1942 <section>
1943 <title>V4L2 spec erratum 2006-02-03</title>
1944 <orderedlist>
1945 <listitem>
1946 <para>In &v4l2-captureparm; and &v4l2-outputparm; the
1947<structfield>timeperframe</structfield> field gives the time in
1948seconds, not microseconds.</para>
1949 </listitem>
1950 </orderedlist>
1951 </section>
1952
1953 <section>
1954 <title>V4L2 spec erratum 2006-02-04</title>
1955 <orderedlist>
1956 <listitem>
1957 <para>The <structfield>clips</structfield> field in
1958&v4l2-window; must point to an array of &v4l2-clip;, not a linked
1959list, because drivers ignore the struct
1960<structname>v4l2_clip</structname>.<structfield>next</structfield>
1961pointer.</para>
1962 </listitem>
1963 </orderedlist>
1964 </section>
1965
1966 <section>
1967 <title>V4L2 in Linux 2.6.17</title>
1968 <orderedlist>
1969 <listitem>
1970 <para>New video standard macros were added:
1971<constant>V4L2_STD_NTSC_M_KR</constant> (NTSC M South Korea), and the
1972sets <constant>V4L2_STD_MN</constant>,
1973<constant>V4L2_STD_B</constant>, <constant>V4L2_STD_GH</constant> and
1974<constant>V4L2_STD_DK</constant>. The
1975<constant>V4L2_STD_NTSC</constant> and
1976<constant>V4L2_STD_SECAM</constant> sets now include
1977<constant>V4L2_STD_NTSC_M_KR</constant> and
1978<constant>V4L2_STD_SECAM_LC</constant> respectively.</para>
1979 </listitem>
1980
1981 <listitem>
1982 <para>A new <constant>V4L2_TUNER_MODE_LANG1_LANG2</constant>
1983was defined to record both languages of a bilingual program. The
1984use of <constant>V4L2_TUNER_MODE_STEREO</constant> for this purpose
1985is deprecated now. See the &VIDIOC-G-TUNER; section for
1986details.</para>
1987 </listitem>
1988 </orderedlist>
1989 </section>
1990
1991 <section>
1992 <title>V4L2 spec erratum 2006-09-23 (Draft 0.15)</title>
1993 <orderedlist>
1994 <listitem>
1995 <para>In various places
1996<constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> and
1997<constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant> of the sliced VBI
1998interface were not mentioned along with other buffer types.</para>
1999 </listitem>
2000
2001 <listitem>
2002 <para>In <xref linkend="vidioc-g-audio" /> it was clarified
2003that the &v4l2-audio; <structfield>mode</structfield> field is a flags
2004field.</para>
2005 </listitem>
2006
2007 <listitem>
2008 <para><xref linkend="vidioc-querycap" /> did not mention the
2009sliced VBI and radio capability flags.</para>
2010 </listitem>
2011
2012 <listitem>
2013 <para>In <xref linkend="vidioc-g-frequency" /> it was
2014clarified that applications must initialize the tuner
2015<structfield>type</structfield> field of &v4l2-frequency; before
2016calling &VIDIOC-S-FREQUENCY;.</para>
2017 </listitem>
2018
2019 <listitem>
2020 <para>The <structfield>reserved</structfield> array
2021in &v4l2-requestbuffers; has 2 elements, not 32.</para>
2022 </listitem>
2023
2024 <listitem>
2025 <para>In <xref linkend="output" /> and <xref
2026 linkend="raw-vbi" /> the device file names
2027<filename>/dev/vout</filename> which never caught on were replaced
2028by <filename>/dev/video</filename>.</para>
2029 </listitem>
2030
2031 <listitem>
2032 <para>With Linux 2.6.15 the possible range for VBI device minor
2033numbers was extended from 224-239 to 224-255. Accordingly device file names
2034<filename>/dev/vbi0</filename> to <filename>/dev/vbi31</filename> are
2035possible now.</para>
2036 </listitem>
2037 </orderedlist>
2038 </section>
2039
2040 <section>
2041 <title>V4L2 in Linux 2.6.18</title>
2042 <orderedlist>
2043 <listitem>
2044 <para>New ioctls &VIDIOC-G-EXT-CTRLS;, &VIDIOC-S-EXT-CTRLS;
2045and &VIDIOC-TRY-EXT-CTRLS; were added, a flag to skip unsupported
2046controls with &VIDIOC-QUERYCTRL;, new control types
2047<constant>V4L2_CTRL_TYPE_INTEGER64</constant> and
2048<constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant> (<xref
2049 linkend="v4l2-ctrl-type" />), and new control flags
2050<constant>V4L2_CTRL_FLAG_READ_ONLY</constant>,
2051<constant>V4L2_CTRL_FLAG_UPDATE</constant>,
2052<constant>V4L2_CTRL_FLAG_INACTIVE</constant> and
2053<constant>V4L2_CTRL_FLAG_SLIDER</constant> (<xref
2054 linkend="control-flags" />). See <xref
2055 linkend="extended-controls" /> for details.</para>
2056 </listitem>
2057 </orderedlist>
2058 </section>
2059
2060 <section>
2061 <title>V4L2 in Linux 2.6.19</title>
2062 <orderedlist>
2063 <listitem>
2064 <para>In &v4l2-sliced-vbi-cap; a buffer type field was added
2065replacing a reserved field. Note on architectures where the size of
2066enum types differs from int types the size of the structure changed.
2067The &VIDIOC-G-SLICED-VBI-CAP; ioctl was redefined from being read-only
2068to write-read. Applications must initialize the type field and clear
2069the reserved fields now. These changes may <emphasis>break the
2070compatibility</emphasis> with older drivers and applications.</para>
2071 </listitem>
2072
2073 <listitem>
2074 <para>The ioctls &VIDIOC-ENUM-FRAMESIZES; and
2075&VIDIOC-ENUM-FRAMEINTERVALS; were added.</para>
2076 </listitem>
2077
2078 <listitem>
2079 <para>A new pixel format <constant>V4L2_PIX_FMT_RGB444</constant> (<xref
2080linkend="rgb-formats" />) was added.</para>
2081 </listitem>
2082 </orderedlist>
2083 </section>
2084
2085 <section>
2086 <title>V4L2 spec erratum 2006-10-12 (Draft 0.17)</title>
2087 <orderedlist>
2088 <listitem>
2089 <para><constant>V4L2_PIX_FMT_HM12</constant> (<xref
2090linkend="reserved-formats" />) is a YUV 4:2:0, not 4:2:2 format.</para>
2091 </listitem>
2092 </orderedlist>
2093 </section>
2094
2095 <section>
2096 <title>V4L2 in Linux 2.6.21</title>
2097 <orderedlist>
2098 <listitem>
2099 <para>The <filename>videodev2.h</filename> header file is
2100now dual licensed under GNU General Public License version two or
2101later, and under a 3-clause BSD-style license.</para>
2102 </listitem>
2103 </orderedlist>
2104 </section>
2105
2106 <section>
2107 <title>V4L2 in Linux 2.6.22</title>
2108 <orderedlist>
2109 <listitem>
2110 <para>Two new field orders
2111 <constant>V4L2_FIELD_INTERLACED_TB</constant> and
2112 <constant>V4L2_FIELD_INTERLACED_BT</constant> were
2113 added. See <xref linkend="v4l2-field" /> for details.</para>
2114 </listitem>
2115
2116 <listitem>
2117 <para>Three new clipping/blending methods with a global or
2118straight or inverted local alpha value were added to the video overlay
2119interface. See the description of the &VIDIOC-G-FBUF; and
2120&VIDIOC-S-FBUF; ioctls for details.</para>
2121 <para>A new <structfield>global_alpha</structfield> field
2122was added to <link
2123linkend="v4l2-window"><structname>v4l2_window</structname></link>,
2124extending the structure. This may <emphasis>break
2125compatibility</emphasis> with applications using a struct
2126<structname>v4l2_window</structname> directly. However the <link
2127linkend="vidioc-g-fmt">VIDIOC_G/S/TRY_FMT</link> ioctls, which take a
2128pointer to a <link linkend="v4l2-format">v4l2_format</link> parent
2129structure with padding bytes at the end, are not affected.</para>
2130 </listitem>
2131
2132 <listitem>
2133 <para>The format of the <structfield>chromakey</structfield>
2134field in &v4l2-window; changed from "host order RGB32" to a pixel
2135value in the same format as the framebuffer. This may <emphasis>break
2136compatibility</emphasis> with existing applications. Drivers
2137supporting the "host order RGB32" format are not known.</para>
2138 </listitem>
2139
2140 </orderedlist>
2141 </section>
2142
2143 <section>
2144 <title>V4L2 in Linux 2.6.24</title>
2145 <orderedlist>
2146 <listitem>
2147 <para>The pixel formats
2148<constant>V4L2_PIX_FMT_PAL8</constant>,
2149<constant>V4L2_PIX_FMT_YUV444</constant>,
2150<constant>V4L2_PIX_FMT_YUV555</constant>,
2151<constant>V4L2_PIX_FMT_YUV565</constant> and
2152<constant>V4L2_PIX_FMT_YUV32</constant> were added.</para>
2153 </listitem>
2154 </orderedlist>
2155 </section>
2156
2157 <section>
2158 <title>V4L2 in Linux 2.6.25</title>
2159 <orderedlist>
2160 <listitem>
2161 <para>The pixel formats <link linkend="V4L2-PIX-FMT-Y16">
2162<constant>V4L2_PIX_FMT_Y16</constant></link> and <link
2163linkend="V4L2-PIX-FMT-SBGGR16">
2164<constant>V4L2_PIX_FMT_SBGGR16</constant></link> were added.</para>
2165 </listitem>
2166 <listitem>
2167 <para>New <link linkend="control">controls</link>
2168<constant>V4L2_CID_POWER_LINE_FREQUENCY</constant>,
2169<constant>V4L2_CID_HUE_AUTO</constant>,
2170<constant>V4L2_CID_WHITE_BALANCE_TEMPERATURE</constant>,
2171<constant>V4L2_CID_SHARPNESS</constant> and
2172<constant>V4L2_CID_BACKLIGHT_COMPENSATION</constant> were added. The
2173controls <constant>V4L2_CID_BLACK_LEVEL</constant>,
2174<constant>V4L2_CID_WHITENESS</constant>,
2175<constant>V4L2_CID_HCENTER</constant> and
2176<constant>V4L2_CID_VCENTER</constant> were deprecated.
2177</para>
2178 </listitem>
2179 <listitem>
2180 <para>A <link linkend="camera-controls">Camera controls
2181class</link> was added, with the new controls
2182<constant>V4L2_CID_EXPOSURE_AUTO</constant>,
2183<constant>V4L2_CID_EXPOSURE_ABSOLUTE</constant>,
2184<constant>V4L2_CID_EXPOSURE_AUTO_PRIORITY</constant>,
2185<constant>V4L2_CID_PAN_RELATIVE</constant>,
2186<constant>V4L2_CID_TILT_RELATIVE</constant>,
2187<constant>V4L2_CID_PAN_RESET</constant>,
2188<constant>V4L2_CID_TILT_RESET</constant>,
2189<constant>V4L2_CID_PAN_ABSOLUTE</constant>,
2190<constant>V4L2_CID_TILT_ABSOLUTE</constant>,
2191<constant>V4L2_CID_FOCUS_ABSOLUTE</constant>,
2192<constant>V4L2_CID_FOCUS_RELATIVE</constant> and
2193<constant>V4L2_CID_FOCUS_AUTO</constant>.</para>
2194 </listitem>
2195 <listitem>
2196 <para>The <constant>VIDIOC_G_MPEGCOMP</constant> and
2197<constant>VIDIOC_S_MPEGCOMP</constant> ioctls, which were superseded
2198by the <link linkend="extended-controls">extended controls</link>
2199interface in Linux 2.6.18, where finally removed from the
2200<filename>videodev2.h</filename> header file.</para>
2201 </listitem>
2202 </orderedlist>
2203 </section>
2204
2205 <section>
2206 <title>V4L2 in Linux 2.6.26</title>
2207 <orderedlist>
2208 <listitem>
2209 <para>The pixel formats
2210<constant>V4L2_PIX_FMT_Y16</constant> and
2211<constant>V4L2_PIX_FMT_SBGGR16</constant> were added.</para>
2212 </listitem>
2213 <listitem>
2214 <para>Added user controls
2215<constant>V4L2_CID_CHROMA_AGC</constant> and
2216<constant>V4L2_CID_COLOR_KILLER</constant>.</para>
2217 </listitem>
2218 </orderedlist>
2219 </section>
2220
2221 <section>
2222 <title>V4L2 in Linux 2.6.27</title>
2223 <orderedlist>
2224 <listitem>
2225 <para>The &VIDIOC-S-HW-FREQ-SEEK; ioctl and the
2226<constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability were added.</para>
2227 </listitem>
2228 <listitem>
2229 <para>The pixel formats
2230<constant>V4L2_PIX_FMT_YVYU</constant>,
2231<constant>V4L2_PIX_FMT_PCA501</constant>,
2232<constant>V4L2_PIX_FMT_PCA505</constant>,
2233<constant>V4L2_PIX_FMT_PCA508</constant>,
2234<constant>V4L2_PIX_FMT_PCA561</constant>,
2235<constant>V4L2_PIX_FMT_SGBRG8</constant>,
2236<constant>V4L2_PIX_FMT_PAC207</constant> and
2237<constant>V4L2_PIX_FMT_PJPG</constant> were added.</para>
2238 </listitem>
2239 </orderedlist>
2240 </section>
2241
2242 <section>
2243 <title>V4L2 in Linux 2.6.28</title>
2244 <orderedlist>
2245 <listitem>
2246 <para>Added <constant>V4L2_MPEG_AUDIO_ENCODING_AAC</constant> and
2247<constant>V4L2_MPEG_AUDIO_ENCODING_AC3</constant> MPEG audio encodings.</para>
2248 </listitem>
2249 <listitem>
2250 <para>Added <constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC</constant> MPEG
2251video encoding.</para>
2252 </listitem>
2253 <listitem>
2254 <para>The pixel formats
2255<constant>V4L2_PIX_FMT_SGRBG10</constant> and
2256<constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant> were added.</para>
2257 </listitem>
2258 </orderedlist>
2259 </section>
2260
2261 <section>
2262 <title>V4L2 in Linux 2.6.29</title>
2263 <orderedlist>
2264 <listitem>
2265 <para>The <constant>VIDIOC_G_CHIP_IDENT</constant> ioctl was renamed
2266to <constant>VIDIOC_G_CHIP_IDENT_OLD</constant> and &VIDIOC-DBG-G-CHIP-IDENT;
2267was introduced in its place. The old struct <structname>v4l2_chip_ident</structname>
2268was renamed to <structname id="v4l2-chip-ident-old">v4l2_chip_ident_old</structname>.</para>
2269 </listitem>
2270 <listitem>
2271 <para>The pixel formats
2272<constant>V4L2_PIX_FMT_VYUY</constant>,
2273<constant>V4L2_PIX_FMT_NV16</constant> and
2274<constant>V4L2_PIX_FMT_NV61</constant> were added.</para>
2275 </listitem>
2276 <listitem>
2277 <para>Added camera controls
2278<constant>V4L2_CID_ZOOM_ABSOLUTE</constant>,
2279<constant>V4L2_CID_ZOOM_RELATIVE</constant>,
2280<constant>V4L2_CID_ZOOM_CONTINUOUS</constant> and
2281<constant>V4L2_CID_PRIVACY</constant>.</para>
2282 </listitem>
2283 </orderedlist>
2284 </section>
2285 <section>
2286 <title>V4L2 in Linux 2.6.30</title>
2287 <orderedlist>
2288 <listitem>
2289 <para>New control flag <constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant> was added.</para>
2290 </listitem>
2291 <listitem>
2292 <para>New control <constant>V4L2_CID_COLORFX</constant> was added.</para>
2293 </listitem>
2294 </orderedlist>
2295 </section>
2296 <section>
2297 <title>V4L2 in Linux 2.6.32</title>
2298 <orderedlist>
2299 <listitem>
2300 <para>In order to be easier to compare a V4L2 API and a kernel
2301version, now V4L2 API is numbered using the Linux Kernel version numeration.</para>
2302 </listitem>
2303 <listitem>
2304 <para>Finalized the RDS capture API. See <xref linkend="rds" /> for
2305more information.</para>
2306 </listitem>
2307 <listitem>
2308 <para>Added new capabilities for modulators and RDS encoders.</para>
2309 </listitem>
2310 <listitem>
2311 <para>Add description for libv4l API.</para>
2312 </listitem>
2313 <listitem>
2314 <para>Added support for string controls via new type <constant>V4L2_CTRL_TYPE_STRING</constant>.</para>
2315 </listitem>
2316 <listitem>
2317 <para>Added <constant>V4L2_CID_BAND_STOP_FILTER</constant> documentation.</para>
2318 </listitem>
2319 <listitem>
2320 <para>Added FM Modulator (FM TX) Extended Control Class: <constant>V4L2_CTRL_CLASS_FM_TX</constant> and their Control IDs.</para>
2321 </listitem>
2322 <listitem>
2323 <para>Added Remote Controller chapter, describing the default Remote Controller mapping for media devices.</para>
2324 </listitem>
2325 </orderedlist>
2326 </section>
2327 </section>
2328
2329 <section id="other">
2330 <title>Relation of V4L2 to other Linux multimedia APIs</title>
2331
2332 <section id="xvideo">
2333 <title>X Video Extension</title>
2334
2335 <para>The X Video Extension (abbreviated XVideo or just Xv) is
2336an extension of the X Window system, implemented for example by the
2337XFree86 project. Its scope is similar to V4L2, an API to video capture
2338and output devices for X clients. Xv allows applications to display
2339live video in a window, send window contents to a TV output, and
2340capture or output still images in XPixmaps<footnote>
2341 <para>This is not implemented in XFree86.</para>
2342 </footnote>. With their implementation XFree86 makes the
2343extension available across many operating systems and
2344architectures.</para>
2345
2346 <para>Because the driver is embedded into the X server Xv has a
2347number of advantages over the V4L2 <link linkend="overlay">video
2348overlay interface</link>. The driver can easily determine the overlay
2349target, &ie; visible graphics memory or off-screen buffers for a
2350destructive overlay. It can program the RAMDAC for a non-destructive
2351overlay, scaling or color-keying, or the clipping functions of the
2352video capture hardware, always in sync with drawing operations or
2353windows moving or changing their stacking order.</para>
2354
2355 <para>To combine the advantages of Xv and V4L a special Xv
2356driver exists in XFree86 and XOrg, just programming any overlay capable
2357Video4Linux device it finds. To enable it
2358<filename>/etc/X11/XF86Config</filename> must contain these lines:</para>
2359 <para><screen>
2360Section "Module"
2361 Load "v4l"
2362EndSection</screen></para>
2363
2364 <para>As of XFree86 4.2 this driver still supports only V4L
2365ioctls, however it should work just fine with all V4L2 devices through
2366the V4L2 backward-compatibility layer. Since V4L2 permits multiple
2367opens it is possible (if supported by the V4L2 driver) to capture
2368video while an X client requested video overlay. Restrictions of
2369simultaneous capturing and overlay are discussed in <xref
2370 linkend="overlay" /> apply.</para>
2371
2372 <para>Only marginally related to V4L2, XFree86 extended Xv to
2373support hardware YUV to RGB conversion and scaling for faster video
2374playback, and added an interface to MPEG-2 decoding hardware. This API
2375is useful to display images captured with V4L2 devices.</para>
2376 </section>
2377
2378 <section>
2379 <title>Digital Video</title>
2380
2381 <para>V4L2 does not support digital terrestrial, cable or
2382satellite broadcast. A separate project aiming at digital receivers
2383exists. You can find its homepage at <ulink
2384url="http://linuxtv.org">http://linuxtv.org</ulink>. The Linux DVB API
2385has no connection to the V4L2 API except that drivers for hybrid
2386hardware may support both.</para>
2387 </section>
2388
2389 <section>
2390 <title>Audio Interfaces</title>
2391
2392 <para>[to do - OSS/ALSA]</para>
2393 </section>
2394 </section>
2395
2396 <section id="experimental">
2397 <title>Experimental API Elements</title>
2398
2399 <para>The following V4L2 API elements are currently experimental
2400and may change in the future.</para>
2401
2402 <itemizedlist>
2403 <listitem>
2404 <para>Video Output Overlay (OSD) Interface, <xref
2405 linkend="osd" />.</para>
2406 </listitem>
2407 <listitem>
2408 <para><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>,
2409 &v4l2-buf-type;, <xref linkend="v4l2-buf-type" />.</para>
2410 </listitem>
2411 <listitem>
2412 <para><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant>,
2413&VIDIOC-QUERYCAP; ioctl, <xref linkend="device-capabilities" />.</para>
2414 </listitem>
2415 <listitem>
2416 <para>&VIDIOC-ENUM-FRAMESIZES; and
2417&VIDIOC-ENUM-FRAMEINTERVALS; ioctls.</para>
2418 </listitem>
2419 <listitem>
2420 <para>&VIDIOC-G-ENC-INDEX; ioctl.</para>
2421 </listitem>
2422 <listitem>
2423 <para>&VIDIOC-ENCODER-CMD; and &VIDIOC-TRY-ENCODER-CMD;
2424ioctls.</para>
2425 </listitem>
2426 <listitem>
2427 <para>&VIDIOC-DBG-G-REGISTER; and &VIDIOC-DBG-S-REGISTER;
2428ioctls.</para>
2429 </listitem>
2430 <listitem>
2431 <para>&VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
2432 </listitem>
2433 </itemizedlist>
2434 </section>
2435
2436 <section id="obsolete">
2437 <title>Obsolete API Elements</title>
2438
2439 <para>The following V4L2 API elements were superseded by new
2440interfaces and should not be implemented in new drivers.</para>
2441
2442 <itemizedlist>
2443 <listitem>
2444 <para><constant>VIDIOC_G_MPEGCOMP</constant> and
2445<constant>VIDIOC_S_MPEGCOMP</constant> ioctls. Use Extended Controls,
2446<xref linkend="extended-controls" />.</para>
2447 </listitem>
2448 </itemizedlist>
2449 </section>
2450
2451 <!--
2452Local Variables:
2453mode: sgml
2454sgml-parent-document: "v4l2.sgml"
2455indent-tabs-mode: nil
2456End:
2457 -->
diff --git a/Documentation/DocBook/v4l/controls.xml b/Documentation/DocBook/v4l/controls.xml
new file mode 100644
index 000000000000..f492accb691d
--- /dev/null
+++ b/Documentation/DocBook/v4l/controls.xml
@@ -0,0 +1,2049 @@
1 <section id="control">
2 <title>User Controls</title>
3
4 <para>Devices typically have a number of user-settable controls
5such as brightness, saturation and so on, which would be presented to
6the user on a graphical user interface. But, different devices
7will have different controls available, and furthermore, the range of
8possible values, and the default value will vary from device to
9device. The control ioctls provide the information and a mechanism to
10create a nice user interface for these controls that will work
11correctly with any device.</para>
12
13 <para>All controls are accessed using an ID value. V4L2 defines
14several IDs for specific purposes. Drivers can also implement their
15own custom controls using <constant>V4L2_CID_PRIVATE_BASE</constant>
16and higher values. The pre-defined control IDs have the prefix
17<constant>V4L2_CID_</constant>, and are listed in <xref
18linkend="control-id" />. The ID is used when querying the attributes of
19a control, and when getting or setting the current value.</para>
20
21 <para>Generally applications should present controls to the user
22without assumptions about their purpose. Each control comes with a
23name string the user is supposed to understand. When the purpose is
24non-intuitive the driver writer should provide a user manual, a user
25interface plug-in or a driver specific panel application. Predefined
26IDs were introduced to change a few controls programmatically, for
27example to mute a device during a channel switch.</para>
28
29 <para>Drivers may enumerate different controls after switching
30the current video input or output, tuner or modulator, or audio input
31or output. Different in the sense of other bounds, another default and
32current value, step size or other menu items. A control with a certain
33<emphasis>custom</emphasis> ID can also change name and
34type.<footnote>
35 <para>It will be more convenient for applications if drivers
36make use of the <constant>V4L2_CTRL_FLAG_DISABLED</constant> flag, but
37that was never required.</para>
38 </footnote> Control values are stored globally, they do not
39change when switching except to stay within the reported bounds. They
40also do not change &eg; when the device is opened or closed, when the
41tuner radio frequency is changed or generally never without
42application request. Since V4L2 specifies no event mechanism, panel
43applications intended to cooperate with other panel applications (be
44they built into a larger application, as a TV viewer) may need to
45regularly poll control values to update their user
46interface.<footnote>
47 <para>Applications could call an ioctl to request events.
48After another process called &VIDIOC-S-CTRL; or another ioctl changing
49shared properties the &func-select; function would indicate
50readability until any ioctl (querying the properties) is
51called.</para>
52 </footnote></para>
53
54 <table pgwide="1" frame="none" id="control-id">
55 <title>Control IDs</title>
56 <tgroup cols="3">
57 &cs-def;
58 <thead>
59 <row>
60 <entry>ID</entry>
61 <entry>Type</entry>
62 <entry>Description</entry>
63 </row>
64 </thead>
65 <tbody valign="top">
66 <row>
67 <entry><constant>V4L2_CID_BASE</constant></entry>
68 <entry></entry>
69 <entry>First predefined ID, equal to
70<constant>V4L2_CID_BRIGHTNESS</constant>.</entry>
71 </row>
72 <row>
73 <entry><constant>V4L2_CID_USER_BASE</constant></entry>
74 <entry></entry>
75 <entry>Synonym of <constant>V4L2_CID_BASE</constant>.</entry>
76 </row>
77 <row>
78 <entry><constant>V4L2_CID_BRIGHTNESS</constant></entry>
79 <entry>integer</entry>
80 <entry>Picture brightness, or more precisely, the black
81level.</entry>
82 </row>
83 <row>
84 <entry><constant>V4L2_CID_CONTRAST</constant></entry>
85 <entry>integer</entry>
86 <entry>Picture contrast or luma gain.</entry>
87 </row>
88 <row>
89 <entry><constant>V4L2_CID_SATURATION</constant></entry>
90 <entry>integer</entry>
91 <entry>Picture color saturation or chroma gain.</entry>
92 </row>
93 <row>
94 <entry><constant>V4L2_CID_HUE</constant></entry>
95 <entry>integer</entry>
96 <entry>Hue or color balance.</entry>
97 </row>
98 <row>
99 <entry><constant>V4L2_CID_AUDIO_VOLUME</constant></entry>
100 <entry>integer</entry>
101 <entry>Overall audio volume. Note some drivers also
102provide an OSS or ALSA mixer interface.</entry>
103 </row>
104 <row>
105 <entry><constant>V4L2_CID_AUDIO_BALANCE</constant></entry>
106 <entry>integer</entry>
107 <entry>Audio stereo balance. Minimum corresponds to all
108the way left, maximum to right.</entry>
109 </row>
110 <row>
111 <entry><constant>V4L2_CID_AUDIO_BASS</constant></entry>
112 <entry>integer</entry>
113 <entry>Audio bass adjustment.</entry>
114 </row>
115 <row>
116 <entry><constant>V4L2_CID_AUDIO_TREBLE</constant></entry>
117 <entry>integer</entry>
118 <entry>Audio treble adjustment.</entry>
119 </row>
120 <row>
121 <entry><constant>V4L2_CID_AUDIO_MUTE</constant></entry>
122 <entry>boolean</entry>
123 <entry>Mute audio, &ie; set the volume to zero, however
124without affecting <constant>V4L2_CID_AUDIO_VOLUME</constant>. Like
125ALSA drivers, V4L2 drivers must mute at load time to avoid excessive
126noise. Actually the entire device should be reset to a low power
127consumption state.</entry>
128 </row>
129 <row>
130 <entry><constant>V4L2_CID_AUDIO_LOUDNESS</constant></entry>
131 <entry>boolean</entry>
132 <entry>Loudness mode (bass boost).</entry>
133 </row>
134 <row>
135 <entry><constant>V4L2_CID_BLACK_LEVEL</constant></entry>
136 <entry>integer</entry>
137 <entry>Another name for brightness (not a synonym of
138<constant>V4L2_CID_BRIGHTNESS</constant>). This control is deprecated
139and should not be used in new drivers and applications.</entry>
140 </row>
141 <row>
142 <entry><constant>V4L2_CID_AUTO_WHITE_BALANCE</constant></entry>
143 <entry>boolean</entry>
144 <entry>Automatic white balance (cameras).</entry>
145 </row>
146 <row>
147 <entry><constant>V4L2_CID_DO_WHITE_BALANCE</constant></entry>
148 <entry>button</entry>
149 <entry>This is an action control. When set (the value is
150ignored), the device will do a white balance and then hold the current
151setting. Contrast this with the boolean
152<constant>V4L2_CID_AUTO_WHITE_BALANCE</constant>, which, when
153activated, keeps adjusting the white balance.</entry>
154 </row>
155 <row>
156 <entry><constant>V4L2_CID_RED_BALANCE</constant></entry>
157 <entry>integer</entry>
158 <entry>Red chroma balance.</entry>
159 </row>
160 <row>
161 <entry><constant>V4L2_CID_BLUE_BALANCE</constant></entry>
162 <entry>integer</entry>
163 <entry>Blue chroma balance.</entry>
164 </row>
165 <row>
166 <entry><constant>V4L2_CID_GAMMA</constant></entry>
167 <entry>integer</entry>
168 <entry>Gamma adjust.</entry>
169 </row>
170 <row>
171 <entry><constant>V4L2_CID_WHITENESS</constant></entry>
172 <entry>integer</entry>
173 <entry>Whiteness for grey-scale devices. This is a synonym
174for <constant>V4L2_CID_GAMMA</constant>. This control is deprecated
175and should not be used in new drivers and applications.</entry>
176 </row>
177 <row>
178 <entry><constant>V4L2_CID_EXPOSURE</constant></entry>
179 <entry>integer</entry>
180 <entry>Exposure (cameras). [Unit?]</entry>
181 </row>
182 <row>
183 <entry><constant>V4L2_CID_AUTOGAIN</constant></entry>
184 <entry>boolean</entry>
185 <entry>Automatic gain/exposure control.</entry>
186 </row>
187 <row>
188 <entry><constant>V4L2_CID_GAIN</constant></entry>
189 <entry>integer</entry>
190 <entry>Gain control.</entry>
191 </row>
192 <row>
193 <entry><constant>V4L2_CID_HFLIP</constant></entry>
194 <entry>boolean</entry>
195 <entry>Mirror the picture horizontally.</entry>
196 </row>
197 <row>
198 <entry><constant>V4L2_CID_VFLIP</constant></entry>
199 <entry>boolean</entry>
200 <entry>Mirror the picture vertically.</entry>
201 </row>
202 <row>
203 <entry><constant>V4L2_CID_HCENTER_DEPRECATED</constant> (formerly <constant>V4L2_CID_HCENTER</constant>)</entry>
204 <entry>integer</entry>
205 <entry>Horizontal image centering. This control is
206deprecated. New drivers and applications should use the <link
207linkend="camera-controls">Camera class controls</link>
208<constant>V4L2_CID_PAN_ABSOLUTE</constant>,
209<constant>V4L2_CID_PAN_RELATIVE</constant> and
210<constant>V4L2_CID_PAN_RESET</constant> instead.</entry>
211 </row>
212 <row>
213 <entry><constant>V4L2_CID_VCENTER_DEPRECATED</constant>
214 (formerly <constant>V4L2_CID_VCENTER</constant>)</entry>
215 <entry>integer</entry>
216 <entry>Vertical image centering. Centering is intended to
217<emphasis>physically</emphasis> adjust cameras. For image cropping see
218<xref linkend="crop" />, for clipping <xref linkend="overlay" />. This
219control is deprecated. New drivers and applications should use the
220<link linkend="camera-controls">Camera class controls</link>
221<constant>V4L2_CID_TILT_ABSOLUTE</constant>,
222<constant>V4L2_CID_TILT_RELATIVE</constant> and
223<constant>V4L2_CID_TILT_RESET</constant> instead.</entry>
224 </row>
225 <row id="v4l2-power-line-frequency">
226 <entry><constant>V4L2_CID_POWER_LINE_FREQUENCY</constant></entry>
227 <entry>enum</entry>
228 <entry>Enables a power line frequency filter to avoid
229flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are:
230<constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0),
231<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1) and
232<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2).</entry>
233 </row>
234 <row>
235 <entry><constant>V4L2_CID_HUE_AUTO</constant></entry>
236 <entry>boolean</entry>
237 <entry>Enables automatic hue control by the device. The
238effect of setting <constant>V4L2_CID_HUE</constant> while automatic
239hue control is enabled is undefined, drivers should ignore such
240request.</entry>
241 </row>
242 <row>
243 <entry><constant>V4L2_CID_WHITE_BALANCE_TEMPERATURE</constant></entry>
244 <entry>integer</entry>
245 <entry>This control specifies the white balance settings
246as a color temperature in Kelvin. A driver should have a minimum of
2472800 (incandescent) to 6500 (daylight). For more information about
248color temperature see <ulink
249url="http://en.wikipedia.org/wiki/Color_temperature">Wikipedia</ulink>.</entry>
250 </row>
251 <row>
252 <entry><constant>V4L2_CID_SHARPNESS</constant></entry>
253 <entry>integer</entry>
254 <entry>Adjusts the sharpness filters in a camera. The
255minimum value disables the filters, higher values give a sharper
256picture.</entry>
257 </row>
258 <row>
259 <entry><constant>V4L2_CID_BACKLIGHT_COMPENSATION</constant></entry>
260 <entry>integer</entry>
261 <entry>Adjusts the backlight compensation in a camera. The
262minimum value disables backlight compensation.</entry>
263 </row>
264 <row>
265 <entry><constant>V4L2_CID_CHROMA_AGC</constant></entry>
266 <entry>boolean</entry>
267 <entry>Chroma automatic gain control.</entry>
268 </row>
269 <row>
270 <entry><constant>V4L2_CID_COLOR_KILLER</constant></entry>
271 <entry>boolean</entry>
272 <entry>Enable the color killer (&ie; force a black &amp; white image in case of a weak video signal).</entry>
273 </row>
274 <row id="v4l2-colorfx">
275 <entry><constant>V4L2_CID_COLORFX</constant></entry>
276 <entry>enum</entry>
277 <entry>Selects a color effect. Possible values for
278<constant>enum v4l2_colorfx</constant> are:
279<constant>V4L2_COLORFX_NONE</constant> (0),
280<constant>V4L2_COLORFX_BW</constant> (1) and
281<constant>V4L2_COLORFX_SEPIA</constant> (2).</entry>
282 </row>
283 <row>
284 <entry><constant>V4L2_CID_LASTP1</constant></entry>
285 <entry></entry>
286 <entry>End of the predefined control IDs (currently
287<constant>V4L2_CID_COLORFX</constant> + 1).</entry>
288 </row>
289 <row>
290 <entry><constant>V4L2_CID_PRIVATE_BASE</constant></entry>
291 <entry></entry>
292 <entry>ID of the first custom (driver specific) control.
293Applications depending on particular custom controls should check the
294driver name and version, see <xref linkend="querycap" />.</entry>
295 </row>
296 </tbody>
297 </tgroup>
298 </table>
299
300 <para>Applications can enumerate the available controls with the
301&VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls, get and set a
302control value with the &VIDIOC-G-CTRL; and &VIDIOC-S-CTRL; ioctls.
303Drivers must implement <constant>VIDIOC_QUERYCTRL</constant>,
304<constant>VIDIOC_G_CTRL</constant> and
305<constant>VIDIOC_S_CTRL</constant> when the device has one or more
306controls, <constant>VIDIOC_QUERYMENU</constant> when it has one or
307more menu type controls.</para>
308
309 <example>
310 <title>Enumerating all controls</title>
311
312 <programlisting>
313&v4l2-queryctrl; queryctrl;
314&v4l2-querymenu; querymenu;
315
316static void
317enumerate_menu (void)
318{
319 printf (" Menu items:\n");
320
321 memset (&amp;querymenu, 0, sizeof (querymenu));
322 querymenu.id = queryctrl.id;
323
324 for (querymenu.index = queryctrl.minimum;
325 querymenu.index &lt;= queryctrl.maximum;
326 querymenu.index++) {
327 if (0 == ioctl (fd, &VIDIOC-QUERYMENU;, &amp;querymenu)) {
328 printf (" %s\n", querymenu.name);
329 } else {
330 perror ("VIDIOC_QUERYMENU");
331 exit (EXIT_FAILURE);
332 }
333 }
334}
335
336memset (&amp;queryctrl, 0, sizeof (queryctrl));
337
338for (queryctrl.id = V4L2_CID_BASE;
339 queryctrl.id &lt; V4L2_CID_LASTP1;
340 queryctrl.id++) {
341 if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
342 if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
343 continue;
344
345 printf ("Control %s\n", queryctrl.name);
346
347 if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
348 enumerate_menu ();
349 } else {
350 if (errno == EINVAL)
351 continue;
352
353 perror ("VIDIOC_QUERYCTRL");
354 exit (EXIT_FAILURE);
355 }
356}
357
358for (queryctrl.id = V4L2_CID_PRIVATE_BASE;;
359 queryctrl.id++) {
360 if (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
361 if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED)
362 continue;
363
364 printf ("Control %s\n", queryctrl.name);
365
366 if (queryctrl.type == V4L2_CTRL_TYPE_MENU)
367 enumerate_menu ();
368 } else {
369 if (errno == EINVAL)
370 break;
371
372 perror ("VIDIOC_QUERYCTRL");
373 exit (EXIT_FAILURE);
374 }
375}
376</programlisting>
377 </example>
378
379 <example>
380 <title>Changing controls</title>
381
382 <programlisting>
383&v4l2-queryctrl; queryctrl;
384&v4l2-control; control;
385
386memset (&amp;queryctrl, 0, sizeof (queryctrl));
387queryctrl.id = V4L2_CID_BRIGHTNESS;
388
389if (-1 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;queryctrl)) {
390 if (errno != EINVAL) {
391 perror ("VIDIOC_QUERYCTRL");
392 exit (EXIT_FAILURE);
393 } else {
394 printf ("V4L2_CID_BRIGHTNESS is not supported\n");
395 }
396} else if (queryctrl.flags &amp; V4L2_CTRL_FLAG_DISABLED) {
397 printf ("V4L2_CID_BRIGHTNESS is not supported\n");
398} else {
399 memset (&amp;control, 0, sizeof (control));
400 control.id = V4L2_CID_BRIGHTNESS;
401 control.value = queryctrl.default_value;
402
403 if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)) {
404 perror ("VIDIOC_S_CTRL");
405 exit (EXIT_FAILURE);
406 }
407}
408
409memset (&amp;control, 0, sizeof (control));
410control.id = V4L2_CID_CONTRAST;
411
412if (0 == ioctl (fd, &VIDIOC-G-CTRL;, &amp;control)) {
413 control.value += 1;
414
415 /* The driver may clamp the value or return ERANGE, ignored here */
416
417 if (-1 == ioctl (fd, &VIDIOC-S-CTRL;, &amp;control)
418 &amp;&amp; errno != ERANGE) {
419 perror ("VIDIOC_S_CTRL");
420 exit (EXIT_FAILURE);
421 }
422/* Ignore if V4L2_CID_CONTRAST is unsupported */
423} else if (errno != EINVAL) {
424 perror ("VIDIOC_G_CTRL");
425 exit (EXIT_FAILURE);
426}
427
428control.id = V4L2_CID_AUDIO_MUTE;
429control.value = TRUE; /* silence */
430
431/* Errors ignored */
432ioctl (fd, VIDIOC_S_CTRL, &amp;control);
433</programlisting>
434 </example>
435 </section>
436
437 <section id="extended-controls">
438 <title>Extended Controls</title>
439
440 <section>
441 <title>Introduction</title>
442
443 <para>The control mechanism as originally designed was meant
444to be used for user settings (brightness, saturation, etc). However,
445it turned out to be a very useful model for implementing more
446complicated driver APIs where each driver implements only a subset of
447a larger API.</para>
448
449 <para>The MPEG encoding API was the driving force behind
450designing and implementing this extended control mechanism: the MPEG
451standard is quite large and the currently supported hardware MPEG
452encoders each only implement a subset of this standard. Further more,
453many parameters relating to how the video is encoded into an MPEG
454stream are specific to the MPEG encoding chip since the MPEG standard
455only defines the format of the resulting MPEG stream, not how the
456video is actually encoded into that format.</para>
457
458 <para>Unfortunately, the original control API lacked some
459features needed for these new uses and so it was extended into the
460(not terribly originally named) extended control API.</para>
461
462 <para>Even though the MPEG encoding API was the first effort
463to use the Extended Control API, nowadays there are also other classes
464of Extended Controls, such as Camera Controls and FM Transmitter Controls.
465The Extended Controls API as well as all Extended Controls classes are
466described in the following text.</para>
467 </section>
468
469 <section>
470 <title>The Extended Control API</title>
471
472 <para>Three new ioctls are available: &VIDIOC-G-EXT-CTRLS;,
473&VIDIOC-S-EXT-CTRLS; and &VIDIOC-TRY-EXT-CTRLS;. These ioctls act on
474arrays of controls (as opposed to the &VIDIOC-G-CTRL; and
475&VIDIOC-S-CTRL; ioctls that act on a single control). This is needed
476since it is often required to atomically change several controls at
477once.</para>
478
479 <para>Each of the new ioctls expects a pointer to a
480&v4l2-ext-controls;. This structure contains a pointer to the control
481array, a count of the number of controls in that array and a control
482class. Control classes are used to group similar controls into a
483single class. For example, control class
484<constant>V4L2_CTRL_CLASS_USER</constant> contains all user controls
485(&ie; all controls that can also be set using the old
486<constant>VIDIOC_S_CTRL</constant> ioctl). Control class
487<constant>V4L2_CTRL_CLASS_MPEG</constant> contains all controls
488relating to MPEG encoding, etc.</para>
489
490 <para>All controls in the control array must belong to the
491specified control class. An error is returned if this is not the
492case.</para>
493
494 <para>It is also possible to use an empty control array (count
495== 0) to check whether the specified control class is
496supported.</para>
497
498 <para>The control array is a &v4l2-ext-control; array. The
499<structname>v4l2_ext_control</structname> structure is very similar to
500&v4l2-control;, except for the fact that it also allows for 64-bit
501values and pointers to be passed.</para>
502
503 <para>It is important to realize that due to the flexibility of
504controls it is necessary to check whether the control you want to set
505actually is supported in the driver and what the valid range of values
506is. So use the &VIDIOC-QUERYCTRL; and &VIDIOC-QUERYMENU; ioctls to
507check this. Also note that it is possible that some of the menu
508indices in a control of type <constant>V4L2_CTRL_TYPE_MENU</constant>
509may not be supported (<constant>VIDIOC_QUERYMENU</constant> will
510return an error). A good example is the list of supported MPEG audio
511bitrates. Some drivers only support one or two bitrates, others
512support a wider range.</para>
513 </section>
514
515 <section>
516 <title>Enumerating Extended Controls</title>
517
518 <para>The recommended way to enumerate over the extended
519controls is by using &VIDIOC-QUERYCTRL; in combination with the
520<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> flag:</para>
521
522 <informalexample>
523 <programlisting>
524&v4l2-queryctrl; qctrl;
525
526qctrl.id = V4L2_CTRL_FLAG_NEXT_CTRL;
527while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
528 /* ... */
529 qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
530}
531</programlisting>
532 </informalexample>
533
534 <para>The initial control ID is set to 0 ORed with the
535<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> flag. The
536<constant>VIDIOC_QUERYCTRL</constant> ioctl will return the first
537control with a higher ID than the specified one. When no such controls
538are found an error is returned.</para>
539
540 <para>If you want to get all controls within a specific control
541class, then you can set the initial
542<structfield>qctrl.id</structfield> value to the control class and add
543an extra check to break out of the loop when a control of another
544control class is found:</para>
545
546 <informalexample>
547 <programlisting>
548qctrl.id = V4L2_CTRL_CLASS_MPEG | V4L2_CTRL_FLAG_NEXT_CTRL;
549while (0 == ioctl (fd, &VIDIOC-QUERYCTRL;, &amp;qctrl)) {
550 if (V4L2_CTRL_ID2CLASS (qctrl.id) != V4L2_CTRL_CLASS_MPEG)
551 break;
552 /* ... */
553 qctrl.id |= V4L2_CTRL_FLAG_NEXT_CTRL;
554 }
555</programlisting>
556 </informalexample>
557
558 <para>The 32-bit <structfield>qctrl.id</structfield> value is
559subdivided into three bit ranges: the top 4 bits are reserved for
560flags (&eg; <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>) and are not
561actually part of the ID. The remaining 28 bits form the control ID, of
562which the most significant 12 bits define the control class and the
563least significant 16 bits identify the control within the control
564class. It is guaranteed that these last 16 bits are always non-zero
565for controls. The range of 0x1000 and up are reserved for
566driver-specific controls. The macro
567<constant>V4L2_CTRL_ID2CLASS(id)</constant> returns the control class
568ID based on a control ID.</para>
569
570 <para>If the driver does not support extended controls, then
571<constant>VIDIOC_QUERYCTRL</constant> will fail when used in
572combination with <constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant>. In
573that case the old method of enumerating control should be used (see
5741.8). But if it is supported, then it is guaranteed to enumerate over
575all controls, including driver-private controls.</para>
576 </section>
577
578 <section>
579 <title>Creating Control Panels</title>
580
581 <para>It is possible to create control panels for a graphical
582user interface where the user can select the various controls.
583Basically you will have to iterate over all controls using the method
584described above. Each control class starts with a control of type
585<constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant>.
586<constant>VIDIOC_QUERYCTRL</constant> will return the name of this
587control class which can be used as the title of a tab page within a
588control panel.</para>
589
590 <para>The flags field of &v4l2-queryctrl; also contains hints on
591the behavior of the control. See the &VIDIOC-QUERYCTRL; documentation
592for more details.</para>
593 </section>
594
595 <section id="mpeg-controls">
596 <title>MPEG Control Reference</title>
597
598 <para>Below all controls within the MPEG control class are
599described. First the generic controls, then controls specific for
600certain hardware.</para>
601
602 <section>
603 <title>Generic MPEG Controls</title>
604
605 <table pgwide="1" frame="none" id="mpeg-control-id">
606 <title>MPEG Control IDs</title>
607 <tgroup cols="4">
608 <colspec colname="c1" colwidth="1*" />
609 <colspec colname="c2" colwidth="6*" />
610 <colspec colname="c3" colwidth="2*" />
611 <colspec colname="c4" colwidth="6*" />
612 <spanspec namest="c1" nameend="c2" spanname="id" />
613 <spanspec namest="c2" nameend="c4" spanname="descr" />
614 <thead>
615 <row>
616 <entry spanname="id" align="left">ID</entry>
617 <entry align="left">Type</entry>
618 </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
619 </row>
620 </thead>
621 <tbody valign="top">
622 <row><entry></entry></row>
623 <row>
624 <entry spanname="id"><constant>V4L2_CID_MPEG_CLASS</constant>&nbsp;</entry>
625 <entry>class</entry>
626 </row><row><entry spanname="descr">The MPEG class
627descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
628description of this control class. This description can be used as the
629caption of a Tab page in a GUI, for example.</entry>
630 </row>
631 <row><entry></entry></row>
632 <row id="v4l2-mpeg-stream-type">
633 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_TYPE</constant>&nbsp;</entry>
634 <entry>enum&nbsp;v4l2_mpeg_stream_type</entry>
635 </row><row><entry spanname="descr">The MPEG-1, -2 or -4
636output stream type. One cannot assume anything here. Each hardware
637MPEG encoder tends to support different subsets of the available MPEG
638stream types. The currently defined stream types are:</entry>
639 </row>
640 <row>
641 <entrytbl spanname="descr" cols="2">
642 <tbody valign="top">
643 <row>
644 <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_PS</constant>&nbsp;</entry>
645 <entry>MPEG-2 program stream</entry>
646 </row>
647 <row>
648 <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_TS</constant>&nbsp;</entry>
649 <entry>MPEG-2 transport stream</entry>
650 </row>
651 <row>
652 <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG1_SS</constant>&nbsp;</entry>
653 <entry>MPEG-1 system stream</entry>
654 </row>
655 <row>
656 <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_DVD</constant>&nbsp;</entry>
657 <entry>MPEG-2 DVD-compatible stream</entry>
658 </row>
659 <row>
660 <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG1_VCD</constant>&nbsp;</entry>
661 <entry>MPEG-1 VCD-compatible stream</entry>
662 </row>
663 <row>
664 <entry><constant>V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD</constant>&nbsp;</entry>
665 <entry>MPEG-2 SVCD-compatible stream</entry>
666 </row>
667 </tbody>
668 </entrytbl>
669 </row>
670 <row><entry></entry></row>
671 <row>
672 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_PMT</constant>&nbsp;</entry>
673 <entry>integer</entry>
674 </row><row><entry spanname="descr">Program Map Table
675Packet ID for the MPEG transport stream (default 16)</entry>
676 </row>
677 <row><entry></entry></row>
678 <row>
679 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_AUDIO</constant>&nbsp;</entry>
680 <entry>integer</entry>
681 </row><row><entry spanname="descr">Audio Packet ID for
682the MPEG transport stream (default 256)</entry>
683 </row>
684 <row><entry></entry></row>
685 <row>
686 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_VIDEO</constant>&nbsp;</entry>
687 <entry>integer</entry>
688 </row><row><entry spanname="descr">Video Packet ID for
689the MPEG transport stream (default 260)</entry>
690 </row>
691 <row><entry></entry></row>
692 <row>
693 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PID_PCR</constant>&nbsp;</entry>
694 <entry>integer</entry>
695 </row><row><entry spanname="descr">Packet ID for the
696MPEG transport stream carrying PCR fields (default 259)</entry>
697 </row>
698 <row><entry></entry></row>
699 <row>
700 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PES_ID_AUDIO</constant>&nbsp;</entry>
701 <entry>integer</entry>
702 </row><row><entry spanname="descr">Audio ID for MPEG
703PES</entry>
704 </row>
705 <row><entry></entry></row>
706 <row>
707 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_PES_ID_VIDEO</constant>&nbsp;</entry>
708 <entry>integer</entry>
709 </row><row><entry spanname="descr">Video ID for MPEG
710PES</entry>
711 </row>
712 <row><entry></entry></row>
713 <row id="v4l2-mpeg-stream-vbi-fmt">
714 <entry spanname="id"><constant>V4L2_CID_MPEG_STREAM_VBI_FMT</constant>&nbsp;</entry>
715 <entry>enum&nbsp;v4l2_mpeg_stream_vbi_fmt</entry>
716 </row><row><entry spanname="descr">Some cards can embed
717VBI data (&eg; Closed Caption, Teletext) into the MPEG stream. This
718control selects whether VBI data should be embedded, and if so, what
719embedding method should be used. The list of possible VBI formats
720depends on the driver. The currently defined VBI format types
721are:</entry>
722 </row>
723 <row>
724 <entrytbl spanname="descr" cols="2">
725 <tbody valign="top">
726 <row>
727 <entry><constant>V4L2_MPEG_STREAM_VBI_FMT_NONE</constant>&nbsp;</entry>
728 <entry>No VBI in the MPEG stream</entry>
729 </row>
730 <row>
731 <entry><constant>V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant>&nbsp;</entry>
732 <entry>VBI in private packets, IVTV format (documented
733in the kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.vbi</filename>)</entry>
734 </row>
735 </tbody>
736 </entrytbl>
737 </row>
738 <row><entry></entry></row>
739 <row id="v4l2-mpeg-audio-sampling-freq">
740 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ</constant>&nbsp;</entry>
741 <entry>enum&nbsp;v4l2_mpeg_audio_sampling_freq</entry>
742 </row><row><entry spanname="descr">MPEG Audio sampling
743frequency. Possible values are:</entry>
744 </row>
745 <row>
746 <entrytbl spanname="descr" cols="2">
747 <tbody valign="top">
748 <row>
749 <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100</constant>&nbsp;</entry>
750 <entry>44.1 kHz</entry>
751 </row>
752 <row>
753 <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000</constant>&nbsp;</entry>
754 <entry>48 kHz</entry>
755 </row>
756 <row>
757 <entry><constant>V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000</constant>&nbsp;</entry>
758 <entry>32 kHz</entry>
759 </row>
760 </tbody>
761 </entrytbl>
762 </row>
763 <row><entry></entry></row>
764 <row id="v4l2-mpeg-audio-encoding">
765 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_ENCODING</constant>&nbsp;</entry>
766 <entry>enum&nbsp;v4l2_mpeg_audio_encoding</entry>
767 </row><row><entry spanname="descr">MPEG Audio encoding.
768Possible values are:</entry>
769 </row>
770 <row>
771 <entrytbl spanname="descr" cols="2">
772 <tbody valign="top">
773 <row>
774 <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_1</constant>&nbsp;</entry>
775 <entry>MPEG-1/2 Layer I encoding</entry>
776 </row>
777 <row>
778 <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_2</constant>&nbsp;</entry>
779 <entry>MPEG-1/2 Layer II encoding</entry>
780 </row>
781 <row>
782 <entry><constant>V4L2_MPEG_AUDIO_ENCODING_LAYER_3</constant>&nbsp;</entry>
783 <entry>MPEG-1/2 Layer III encoding</entry>
784 </row>
785 <row>
786 <entry><constant>V4L2_MPEG_AUDIO_ENCODING_AAC</constant>&nbsp;</entry>
787 <entry>MPEG-2/4 AAC (Advanced Audio Coding)</entry>
788 </row>
789 <row>
790 <entry><constant>V4L2_MPEG_AUDIO_ENCODING_AC3</constant>&nbsp;</entry>
791 <entry>AC-3 aka ATSC A/52 encoding</entry>
792 </row>
793 </tbody>
794 </entrytbl>
795 </row>
796 <row><entry></entry></row>
797 <row id="v4l2-mpeg-audio-l1-bitrate">
798 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L1_BITRATE</constant>&nbsp;</entry>
799 <entry>enum&nbsp;v4l2_mpeg_audio_l1_bitrate</entry>
800 </row><row><entry spanname="descr">MPEG-1/2 Layer I bitrate.
801Possible values are:</entry>
802 </row>
803 <row>
804 <entrytbl spanname="descr" cols="2">
805 <tbody valign="top">
806 <row>
807 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_32K</constant>&nbsp;</entry>
808 <entry>32 kbit/s</entry></row>
809 <row>
810 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_64K</constant>&nbsp;</entry>
811 <entry>64 kbit/s</entry>
812 </row>
813 <row>
814 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_96K</constant>&nbsp;</entry>
815 <entry>96 kbit/s</entry>
816 </row>
817 <row>
818 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_128K</constant>&nbsp;</entry>
819 <entry>128 kbit/s</entry>
820 </row>
821 <row>
822 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_160K</constant>&nbsp;</entry>
823 <entry>160 kbit/s</entry>
824 </row>
825 <row>
826 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_192K</constant>&nbsp;</entry>
827 <entry>192 kbit/s</entry>
828 </row>
829 <row>
830 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_224K</constant>&nbsp;</entry>
831 <entry>224 kbit/s</entry>
832 </row>
833 <row>
834 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_256K</constant>&nbsp;</entry>
835 <entry>256 kbit/s</entry>
836 </row>
837 <row>
838 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_288K</constant>&nbsp;</entry>
839 <entry>288 kbit/s</entry>
840 </row>
841 <row>
842 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_320K</constant>&nbsp;</entry>
843 <entry>320 kbit/s</entry>
844 </row>
845 <row>
846 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_352K</constant>&nbsp;</entry>
847 <entry>352 kbit/s</entry>
848 </row>
849 <row>
850 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_384K</constant>&nbsp;</entry>
851 <entry>384 kbit/s</entry>
852 </row>
853 <row>
854 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_416K</constant>&nbsp;</entry>
855 <entry>416 kbit/s</entry>
856 </row>
857 <row>
858 <entry><constant>V4L2_MPEG_AUDIO_L1_BITRATE_448K</constant>&nbsp;</entry>
859 <entry>448 kbit/s</entry>
860 </row>
861 </tbody>
862 </entrytbl>
863 </row>
864 <row><entry></entry></row>
865 <row id="v4l2-mpeg-audio-l2-bitrate">
866 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L2_BITRATE</constant>&nbsp;</entry>
867 <entry>enum&nbsp;v4l2_mpeg_audio_l2_bitrate</entry>
868 </row><row><entry spanname="descr">MPEG-1/2 Layer II bitrate.
869Possible values are:</entry>
870 </row>
871 <row>
872 <entrytbl spanname="descr" cols="2">
873 <tbody valign="top">
874 <row>
875 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_32K</constant>&nbsp;</entry>
876 <entry>32 kbit/s</entry>
877 </row>
878 <row>
879 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_48K</constant>&nbsp;</entry>
880 <entry>48 kbit/s</entry>
881 </row>
882 <row>
883 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_56K</constant>&nbsp;</entry>
884 <entry>56 kbit/s</entry>
885 </row>
886 <row>
887 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_64K</constant>&nbsp;</entry>
888 <entry>64 kbit/s</entry>
889 </row>
890 <row>
891 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_80K</constant>&nbsp;</entry>
892 <entry>80 kbit/s</entry>
893 </row>
894 <row>
895 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_96K</constant>&nbsp;</entry>
896 <entry>96 kbit/s</entry>
897 </row>
898 <row>
899 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_112K</constant>&nbsp;</entry>
900 <entry>112 kbit/s</entry>
901 </row>
902 <row>
903 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_128K</constant>&nbsp;</entry>
904 <entry>128 kbit/s</entry>
905 </row>
906 <row>
907 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_160K</constant>&nbsp;</entry>
908 <entry>160 kbit/s</entry>
909 </row>
910 <row>
911 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_192K</constant>&nbsp;</entry>
912 <entry>192 kbit/s</entry>
913 </row>
914 <row>
915 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_224K</constant>&nbsp;</entry>
916 <entry>224 kbit/s</entry>
917 </row>
918 <row>
919 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_256K</constant>&nbsp;</entry>
920 <entry>256 kbit/s</entry>
921 </row>
922 <row>
923 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_320K</constant>&nbsp;</entry>
924 <entry>320 kbit/s</entry>
925 </row>
926 <row>
927 <entry><constant>V4L2_MPEG_AUDIO_L2_BITRATE_384K</constant>&nbsp;</entry>
928 <entry>384 kbit/s</entry>
929 </row>
930 </tbody>
931 </entrytbl>
932 </row>
933 <row><entry></entry></row>
934 <row id="v4l2-mpeg-audio-l3-bitrate">
935 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_L3_BITRATE</constant>&nbsp;</entry>
936 <entry>enum&nbsp;v4l2_mpeg_audio_l3_bitrate</entry>
937 </row><row><entry spanname="descr">MPEG-1/2 Layer III bitrate.
938Possible values are:</entry>
939 </row>
940 <row>
941 <entrytbl spanname="descr" cols="2">
942 <tbody valign="top">
943 <row>
944 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_32K</constant>&nbsp;</entry>
945 <entry>32 kbit/s</entry>
946 </row>
947 <row>
948 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_40K</constant>&nbsp;</entry>
949 <entry>40 kbit/s</entry>
950 </row>
951 <row>
952 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_48K</constant>&nbsp;</entry>
953 <entry>48 kbit/s</entry>
954 </row>
955 <row>
956 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_56K</constant>&nbsp;</entry>
957 <entry>56 kbit/s</entry>
958 </row>
959 <row>
960 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_64K</constant>&nbsp;</entry>
961 <entry>64 kbit/s</entry>
962 </row>
963 <row>
964 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_80K</constant>&nbsp;</entry>
965 <entry>80 kbit/s</entry>
966 </row>
967 <row>
968 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_96K</constant>&nbsp;</entry>
969 <entry>96 kbit/s</entry>
970 </row>
971 <row>
972 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_112K</constant>&nbsp;</entry>
973 <entry>112 kbit/s</entry>
974 </row>
975 <row>
976 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_128K</constant>&nbsp;</entry>
977 <entry>128 kbit/s</entry>
978 </row>
979 <row>
980 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_160K</constant>&nbsp;</entry>
981 <entry>160 kbit/s</entry>
982 </row>
983 <row>
984 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_192K</constant>&nbsp;</entry>
985 <entry>192 kbit/s</entry>
986 </row>
987 <row>
988 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_224K</constant>&nbsp;</entry>
989 <entry>224 kbit/s</entry>
990 </row>
991 <row>
992 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_256K</constant>&nbsp;</entry>
993 <entry>256 kbit/s</entry>
994 </row>
995 <row>
996 <entry><constant>V4L2_MPEG_AUDIO_L3_BITRATE_320K</constant>&nbsp;</entry>
997 <entry>320 kbit/s</entry>
998 </row>
999 </tbody>
1000 </entrytbl>
1001 </row>
1002 <row><entry></entry></row>
1003 <row>
1004 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_AAC_BITRATE</constant>&nbsp;</entry>
1005 <entry>integer</entry>
1006 </row><row><entry spanname="descr">AAC bitrate in bits per second.</entry>
1007 </row>
1008 <row><entry></entry></row>
1009 <row id="v4l2-mpeg-audio-ac3-bitrate">
1010 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_AC3_BITRATE</constant>&nbsp;</entry>
1011 <entry>enum&nbsp;v4l2_mpeg_audio_ac3_bitrate</entry>
1012 </row><row><entry spanname="descr">AC-3 bitrate.
1013Possible values are:</entry>
1014 </row>
1015 <row>
1016 <entrytbl spanname="descr" cols="2">
1017 <tbody valign="top">
1018 <row>
1019 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_32K</constant>&nbsp;</entry>
1020 <entry>32 kbit/s</entry>
1021 </row>
1022 <row>
1023 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_40K</constant>&nbsp;</entry>
1024 <entry>40 kbit/s</entry>
1025 </row>
1026 <row>
1027 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_48K</constant>&nbsp;</entry>
1028 <entry>48 kbit/s</entry>
1029 </row>
1030 <row>
1031 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_56K</constant>&nbsp;</entry>
1032 <entry>56 kbit/s</entry>
1033 </row>
1034 <row>
1035 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_64K</constant>&nbsp;</entry>
1036 <entry>64 kbit/s</entry>
1037 </row>
1038 <row>
1039 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_80K</constant>&nbsp;</entry>
1040 <entry>80 kbit/s</entry>
1041 </row>
1042 <row>
1043 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_96K</constant>&nbsp;</entry>
1044 <entry>96 kbit/s</entry>
1045 </row>
1046 <row>
1047 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_112K</constant>&nbsp;</entry>
1048 <entry>112 kbit/s</entry>
1049 </row>
1050 <row>
1051 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_128K</constant>&nbsp;</entry>
1052 <entry>128 kbit/s</entry>
1053 </row>
1054 <row>
1055 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_160K</constant>&nbsp;</entry>
1056 <entry>160 kbit/s</entry>
1057 </row>
1058 <row>
1059 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_192K</constant>&nbsp;</entry>
1060 <entry>192 kbit/s</entry>
1061 </row>
1062 <row>
1063 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_224K</constant>&nbsp;</entry>
1064 <entry>224 kbit/s</entry>
1065 </row>
1066 <row>
1067 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_256K</constant>&nbsp;</entry>
1068 <entry>256 kbit/s</entry>
1069 </row>
1070 <row>
1071 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_320K</constant>&nbsp;</entry>
1072 <entry>320 kbit/s</entry>
1073 </row>
1074 <row>
1075 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_384K</constant>&nbsp;</entry>
1076 <entry>384 kbit/s</entry>
1077 </row>
1078 <row>
1079 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_448K</constant>&nbsp;</entry>
1080 <entry>448 kbit/s</entry>
1081 </row>
1082 <row>
1083 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_512K</constant>&nbsp;</entry>
1084 <entry>512 kbit/s</entry>
1085 </row>
1086 <row>
1087 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_576K</constant>&nbsp;</entry>
1088 <entry>576 kbit/s</entry>
1089 </row>
1090 <row>
1091 <entry><constant>V4L2_MPEG_AUDIO_AC3_BITRATE_640K</constant>&nbsp;</entry>
1092 <entry>640 kbit/s</entry>
1093 </row>
1094 </tbody>
1095 </entrytbl>
1096 </row>
1097 <row><entry></entry></row>
1098 <row id="v4l2-mpeg-audio-mode">
1099 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MODE</constant>&nbsp;</entry>
1100 <entry>enum&nbsp;v4l2_mpeg_audio_mode</entry>
1101 </row><row><entry spanname="descr">MPEG Audio mode.
1102Possible values are:</entry>
1103 </row>
1104 <row>
1105 <entrytbl spanname="descr" cols="2">
1106 <tbody valign="top">
1107 <row>
1108 <entry><constant>V4L2_MPEG_AUDIO_MODE_STEREO</constant>&nbsp;</entry>
1109 <entry>Stereo</entry>
1110 </row>
1111 <row>
1112 <entry><constant>V4L2_MPEG_AUDIO_MODE_JOINT_STEREO</constant>&nbsp;</entry>
1113 <entry>Joint Stereo</entry>
1114 </row>
1115 <row>
1116 <entry><constant>V4L2_MPEG_AUDIO_MODE_DUAL</constant>&nbsp;</entry>
1117 <entry>Bilingual</entry>
1118 </row>
1119 <row>
1120 <entry><constant>V4L2_MPEG_AUDIO_MODE_MONO</constant>&nbsp;</entry>
1121 <entry>Mono</entry>
1122 </row>
1123 </tbody>
1124 </entrytbl>
1125 </row>
1126 <row><entry></entry></row>
1127 <row id="v4l2-mpeg-audio-mode-extension">
1128 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MODE_EXTENSION</constant>&nbsp;</entry>
1129 <entry>enum&nbsp;v4l2_mpeg_audio_mode_extension</entry>
1130 </row><row><entry spanname="descr">Joint Stereo
1131audio mode extension. In Layer I and II they indicate which subbands
1132are in intensity stereo. All other subbands are coded in stereo. Layer
1133III is not (yet) supported. Possible values
1134are:</entry>
1135 </row>
1136 <row>
1137 <entrytbl spanname="descr" cols="2">
1138 <tbody valign="top">
1139 <row>
1140 <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4</constant>&nbsp;</entry>
1141 <entry>Subbands 4-31 in intensity stereo</entry>
1142 </row>
1143 <row>
1144 <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8</constant>&nbsp;</entry>
1145 <entry>Subbands 8-31 in intensity stereo</entry>
1146 </row>
1147 <row>
1148 <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12</constant>&nbsp;</entry>
1149 <entry>Subbands 12-31 in intensity stereo</entry>
1150 </row>
1151 <row>
1152 <entry><constant>V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16</constant>&nbsp;</entry>
1153 <entry>Subbands 16-31 in intensity stereo</entry>
1154 </row>
1155 </tbody>
1156 </entrytbl>
1157 </row>
1158 <row><entry></entry></row>
1159 <row id="v4l2-mpeg-audio-emphasis">
1160 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_EMPHASIS</constant>&nbsp;</entry>
1161 <entry>enum&nbsp;v4l2_mpeg_audio_emphasis</entry>
1162 </row><row><entry spanname="descr">Audio Emphasis.
1163Possible values are:</entry>
1164 </row>
1165 <row>
1166 <entrytbl spanname="descr" cols="2">
1167 <tbody valign="top">
1168 <row>
1169 <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_NONE</constant>&nbsp;</entry>
1170 <entry>None</entry>
1171 </row>
1172 <row>
1173 <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS</constant>&nbsp;</entry>
1174 <entry>50/15 microsecond emphasis</entry>
1175 </row>
1176 <row>
1177 <entry><constant>V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17</constant>&nbsp;</entry>
1178 <entry>CCITT J.17</entry>
1179 </row>
1180 </tbody>
1181 </entrytbl>
1182 </row>
1183 <row><entry></entry></row>
1184 <row id="v4l2-mpeg-audio-crc">
1185 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_CRC</constant>&nbsp;</entry>
1186 <entry>enum&nbsp;v4l2_mpeg_audio_crc</entry>
1187 </row><row><entry spanname="descr">CRC method. Possible
1188values are:</entry>
1189 </row>
1190 <row>
1191 <entrytbl spanname="descr" cols="2">
1192 <tbody valign="top">
1193 <row>
1194 <entry><constant>V4L2_MPEG_AUDIO_CRC_NONE</constant>&nbsp;</entry>
1195 <entry>None</entry>
1196 </row>
1197 <row>
1198 <entry><constant>V4L2_MPEG_AUDIO_CRC_CRC16</constant>&nbsp;</entry>
1199 <entry>16 bit parity check</entry>
1200 </row>
1201 </tbody>
1202 </entrytbl>
1203 </row>
1204 <row><entry></entry></row>
1205 <row>
1206 <entry spanname="id"><constant>V4L2_CID_MPEG_AUDIO_MUTE</constant>&nbsp;</entry>
1207 <entry>boolean</entry>
1208 </row><row><entry spanname="descr">Mutes the audio when
1209capturing. This is not done by muting audio hardware, which can still
1210produce a slight hiss, but in the encoder itself, guaranteeing a fixed
1211and reproducable audio bitstream. 0 = unmuted, 1 = muted.</entry>
1212 </row>
1213 <row><entry></entry></row>
1214 <row id="v4l2-mpeg-video-encoding">
1215 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ENCODING</constant>&nbsp;</entry>
1216 <entry>enum&nbsp;v4l2_mpeg_video_encoding</entry>
1217 </row><row><entry spanname="descr">MPEG Video encoding
1218method. Possible values are:</entry>
1219 </row>
1220 <row>
1221 <entrytbl spanname="descr" cols="2">
1222 <tbody valign="top">
1223 <row>
1224 <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_1</constant>&nbsp;</entry>
1225 <entry>MPEG-1 Video encoding</entry>
1226 </row>
1227 <row>
1228 <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_2</constant>&nbsp;</entry>
1229 <entry>MPEG-2 Video encoding</entry>
1230 </row>
1231 <row>
1232 <entry><constant>V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC</constant>&nbsp;</entry>
1233 <entry>MPEG-4 AVC (H.264) Video encoding</entry>
1234 </row>
1235 </tbody>
1236 </entrytbl>
1237 </row>
1238 <row><entry></entry></row>
1239 <row id="v4l2-mpeg-video-aspect">
1240 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_ASPECT</constant>&nbsp;</entry>
1241 <entry>enum&nbsp;v4l2_mpeg_video_aspect</entry>
1242 </row><row><entry spanname="descr">Video aspect.
1243Possible values are:</entry>
1244 </row>
1245 <row>
1246 <entrytbl spanname="descr" cols="2">
1247 <tbody valign="top">
1248 <row>
1249 <entry><constant>V4L2_MPEG_VIDEO_ASPECT_1x1</constant>&nbsp;</entry>
1250 </row>
1251 <row>
1252 <entry><constant>V4L2_MPEG_VIDEO_ASPECT_4x3</constant>&nbsp;</entry>
1253 </row>
1254 <row>
1255 <entry><constant>V4L2_MPEG_VIDEO_ASPECT_16x9</constant>&nbsp;</entry>
1256 </row>
1257 <row>
1258 <entry><constant>V4L2_MPEG_VIDEO_ASPECT_221x100</constant>&nbsp;</entry>
1259 </row>
1260 </tbody>
1261 </entrytbl>
1262 </row>
1263 <row><entry></entry></row>
1264 <row>
1265 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_B_FRAMES</constant>&nbsp;</entry>
1266 <entry>integer</entry>
1267 </row><row><entry spanname="descr">Number of B-Frames
1268(default 2)</entry>
1269 </row>
1270 <row><entry></entry></row>
1271 <row>
1272 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_GOP_SIZE</constant>&nbsp;</entry>
1273 <entry>integer</entry>
1274 </row><row><entry spanname="descr">GOP size (default
127512)</entry>
1276 </row>
1277 <row><entry></entry></row>
1278 <row>
1279 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_GOP_CLOSURE</constant>&nbsp;</entry>
1280 <entry>boolean</entry>
1281 </row><row><entry spanname="descr">GOP closure (default
12821)</entry>
1283 </row>
1284 <row><entry></entry></row>
1285 <row>
1286 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_PULLDOWN</constant>&nbsp;</entry>
1287 <entry>boolean</entry>
1288 </row><row><entry spanname="descr">Enable 3:2 pulldown
1289(default 0)</entry>
1290 </row>
1291 <row><entry></entry></row>
1292 <row id="v4l2-mpeg-video-bitrate-mode">
1293 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE_MODE</constant>&nbsp;</entry>
1294 <entry>enum&nbsp;v4l2_mpeg_video_bitrate_mode</entry>
1295 </row><row><entry spanname="descr">Video bitrate mode.
1296Possible values are:</entry>
1297 </row>
1298 <row>
1299 <entrytbl spanname="descr" cols="2">
1300 <tbody valign="top">
1301 <row>
1302 <entry><constant>V4L2_MPEG_VIDEO_BITRATE_MODE_VBR</constant>&nbsp;</entry>
1303 <entry>Variable bitrate</entry>
1304 </row>
1305 <row>
1306 <entry><constant>V4L2_MPEG_VIDEO_BITRATE_MODE_CBR</constant>&nbsp;</entry>
1307 <entry>Constant bitrate</entry>
1308 </row>
1309 </tbody>
1310 </entrytbl>
1311 </row>
1312 <row><entry></entry></row>
1313 <row>
1314 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE</constant>&nbsp;</entry>
1315 <entry>integer</entry>
1316 </row><row><entry spanname="descr">Video bitrate in bits
1317per second.</entry>
1318 </row>
1319 <row><entry></entry></row>
1320 <row>
1321 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_BITRATE_PEAK</constant>&nbsp;</entry>
1322 <entry>integer</entry>
1323 </row><row><entry spanname="descr">Peak video bitrate in
1324bits per second. Must be larger or equal to the average video bitrate.
1325It is ignored if the video bitrate mode is set to constant
1326bitrate.</entry>
1327 </row>
1328 <row><entry></entry></row>
1329 <row>
1330 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION</constant>&nbsp;</entry>
1331 <entry>integer</entry>
1332 </row><row><entry spanname="descr">For every captured
1333frame, skip this many subsequent frames (default 0).</entry>
1334 </row>
1335 <row><entry></entry></row>
1336 <row>
1337 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MUTE</constant>&nbsp;</entry>
1338 <entry>boolean</entry>
1339 </row>
1340 <row><entry spanname="descr">"Mutes" the video to a
1341fixed color when capturing. This is useful for testing, to produce a
1342fixed video bitstream. 0 = unmuted, 1 = muted.</entry>
1343 </row>
1344 <row><entry></entry></row>
1345 <row>
1346 <entry spanname="id"><constant>V4L2_CID_MPEG_VIDEO_MUTE_YUV</constant>&nbsp;</entry>
1347 <entry>integer</entry>
1348 </row><row><entry spanname="descr">Sets the "mute" color
1349of the video. The supplied 32-bit integer is interpreted as follows (bit
13500 = least significant bit):</entry>
1351 </row>
1352 <row>
1353 <entrytbl spanname="descr" cols="2">
1354 <tbody valign="top">
1355 <row>
1356 <entry>Bit 0:7</entry>
1357 <entry>V chrominance information</entry>
1358 </row>
1359 <row>
1360 <entry>Bit 8:15</entry>
1361 <entry>U chrominance information</entry>
1362 </row>
1363 <row>
1364 <entry>Bit 16:23</entry>
1365 <entry>Y luminance information</entry>
1366 </row>
1367 <row>
1368 <entry>Bit 24:31</entry>
1369 <entry>Must be zero.</entry>
1370 </row>
1371 </tbody>
1372 </entrytbl>
1373 </row>
1374 </tbody>
1375 </tgroup>
1376 </table>
1377 </section>
1378
1379 <section>
1380 <title>CX2341x MPEG Controls</title>
1381
1382 <para>The following MPEG class controls deal with MPEG
1383encoding settings that are specific to the Conexant CX23415 and
1384CX23416 MPEG encoding chips.</para>
1385
1386 <table pgwide="1" frame="none" id="cx2341x-control-id">
1387 <title>CX2341x Control IDs</title>
1388 <tgroup cols="4">
1389 <colspec colname="c1" colwidth="1*" />
1390 <colspec colname="c2" colwidth="6*" />
1391 <colspec colname="c3" colwidth="2*" />
1392 <colspec colname="c4" colwidth="6*" />
1393 <spanspec namest="c1" nameend="c2" spanname="id" />
1394 <spanspec namest="c2" nameend="c4" spanname="descr" />
1395 <thead>
1396 <row>
1397 <entry spanname="id" align="left">ID</entry>
1398 <entry align="left">Type</entry>
1399 </row><row><entry spanname="descr" align="left">Description</entry>
1400 </row>
1401 </thead>
1402 <tbody valign="top">
1403 <row><entry></entry></row>
1404 <row id="v4l2-mpeg-cx2341x-video-spatial-filter-mode">
1405 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE</constant>&nbsp;</entry>
1406 <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_spatial_filter_mode</entry>
1407 </row><row><entry spanname="descr">Sets the Spatial
1408Filter mode (default <constant>MANUAL</constant>). Possible values
1409are:</entry>
1410 </row>
1411 <row>
1412 <entrytbl spanname="descr" cols="2">
1413 <tbody valign="top">
1414 <row>
1415 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL</constant>&nbsp;</entry>
1416 <entry>Choose the filter manually</entry>
1417 </row>
1418 <row>
1419 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO</constant>&nbsp;</entry>
1420 <entry>Choose the filter automatically</entry>
1421 </row>
1422 </tbody>
1423 </entrytbl>
1424 </row>
1425 <row><entry></entry></row>
1426 <row>
1427 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER</constant>&nbsp;</entry>
1428 <entry>integer&nbsp;(0-15)</entry>
1429 </row><row><entry spanname="descr">The setting for the
1430Spatial Filter. 0 = off, 15 = maximum. (Default is 0.)</entry>
1431 </row>
1432 <row><entry></entry></row>
1433 <row id="luma-spatial-filter-type">
1434 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE</constant>&nbsp;</entry>
1435 <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</entry>
1436 </row><row><entry spanname="descr">Select the algorithm
1437to use for the Luma Spatial Filter (default
1438<constant>1D_HOR</constant>). Possible values:</entry>
1439 </row>
1440 <row>
1441 <entrytbl spanname="descr" cols="2">
1442 <tbody valign="top">
1443 <row>
1444 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF</constant>&nbsp;</entry>
1445 <entry>No filter</entry>
1446 </row>
1447 <row>
1448 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR</constant>&nbsp;</entry>
1449 <entry>One-dimensional horizontal</entry>
1450 </row>
1451 <row>
1452 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT</constant>&nbsp;</entry>
1453 <entry>One-dimensional vertical</entry>
1454 </row>
1455 <row>
1456 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE</constant>&nbsp;</entry>
1457 <entry>Two-dimensional separable</entry>
1458 </row>
1459 <row>
1460 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE</constant>&nbsp;</entry>
1461 <entry>Two-dimensional symmetrical
1462non-separable</entry>
1463 </row>
1464 </tbody>
1465 </entrytbl>
1466 </row>
1467 <row><entry></entry></row>
1468 <row id="chroma-spatial-filter-type">
1469 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE</constant>&nbsp;</entry>
1470 <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</entry>
1471 </row><row><entry spanname="descr">Select the algorithm
1472for the Chroma Spatial Filter (default <constant>1D_HOR</constant>).
1473Possible values are:</entry>
1474 </row>
1475 <row>
1476 <entrytbl spanname="descr" cols="2">
1477 <tbody valign="top">
1478 <row>
1479 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF</constant>&nbsp;</entry>
1480 <entry>No filter</entry>
1481 </row>
1482 <row>
1483 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR</constant>&nbsp;</entry>
1484 <entry>One-dimensional horizontal</entry>
1485 </row>
1486 </tbody>
1487 </entrytbl>
1488 </row>
1489 <row><entry></entry></row>
1490 <row id="v4l2-mpeg-cx2341x-video-temporal-filter-mode">
1491 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE</constant>&nbsp;</entry>
1492 <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_temporal_filter_mode</entry>
1493 </row><row><entry spanname="descr">Sets the Temporal
1494Filter mode (default <constant>MANUAL</constant>). Possible values
1495are:</entry>
1496 </row>
1497 <row>
1498 <entrytbl spanname="descr" cols="2">
1499 <tbody valign="top">
1500 <row>
1501 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL</constant>&nbsp;</entry>
1502 <entry>Choose the filter manually</entry>
1503 </row>
1504 <row>
1505 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO</constant>&nbsp;</entry>
1506 <entry>Choose the filter automatically</entry>
1507 </row>
1508 </tbody>
1509 </entrytbl>
1510 </row>
1511 <row><entry></entry></row>
1512 <row>
1513 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER</constant>&nbsp;</entry>
1514 <entry>integer&nbsp;(0-31)</entry>
1515 </row><row><entry spanname="descr">The setting for the
1516Temporal Filter. 0 = off, 31 = maximum. (Default is 8 for full-scale
1517capturing and 0 for scaled capturing.)</entry>
1518 </row>
1519 <row><entry></entry></row>
1520 <row id="v4l2-mpeg-cx2341x-video-median-filter-type">
1521 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE</constant>&nbsp;</entry>
1522 <entry>enum&nbsp;v4l2_mpeg_cx2341x_video_median_filter_type</entry>
1523 </row><row><entry spanname="descr">Median Filter Type
1524(default <constant>OFF</constant>). Possible values are:</entry>
1525 </row>
1526 <row>
1527 <entrytbl spanname="descr" cols="2">
1528 <tbody valign="top">
1529 <row>
1530 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF</constant>&nbsp;</entry>
1531 <entry>No filter</entry>
1532 </row>
1533 <row>
1534 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR</constant>&nbsp;</entry>
1535 <entry>Horizontal filter</entry>
1536 </row>
1537 <row>
1538 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT</constant>&nbsp;</entry>
1539 <entry>Vertical filter</entry>
1540 </row>
1541 <row>
1542 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT</constant>&nbsp;</entry>
1543 <entry>Horizontal and vertical filter</entry>
1544 </row>
1545 <row>
1546 <entry><constant>V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG</constant>&nbsp;</entry>
1547 <entry>Diagonal filter</entry>
1548 </row>
1549 </tbody>
1550 </entrytbl>
1551 </row>
1552 <row><entry></entry></row>
1553 <row>
1554 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM</constant>&nbsp;</entry>
1555 <entry>integer&nbsp;(0-255)</entry>
1556 </row><row><entry spanname="descr">Threshold above which
1557the luminance median filter is enabled (default 0)</entry>
1558 </row>
1559 <row><entry></entry></row>
1560 <row>
1561 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP</constant>&nbsp;</entry>
1562 <entry>integer&nbsp;(0-255)</entry>
1563 </row><row><entry spanname="descr">Threshold below which
1564the luminance median filter is enabled (default 255)</entry>
1565 </row>
1566 <row><entry></entry></row>
1567 <row>
1568 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM</constant>&nbsp;</entry>
1569 <entry>integer&nbsp;(0-255)</entry>
1570 </row><row><entry spanname="descr">Threshold above which
1571the chroma median filter is enabled (default 0)</entry>
1572 </row>
1573 <row><entry></entry></row>
1574 <row>
1575 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP</constant>&nbsp;</entry>
1576 <entry>integer&nbsp;(0-255)</entry>
1577 </row><row><entry spanname="descr">Threshold below which
1578the chroma median filter is enabled (default 255)</entry>
1579 </row>
1580 <row><entry></entry></row>
1581 <row>
1582 <entry spanname="id"><constant>V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS</constant>&nbsp;</entry>
1583 <entry>boolean</entry>
1584 </row>
1585 <row><entry spanname="descr">The CX2341X MPEG encoder
1586can insert one empty MPEG-2 PES packet into the stream between every
1587four video frames. The packet size is 2048 bytes, including the
1588packet_start_code_prefix and stream_id fields. The stream_id is 0xBF
1589(private stream 2). The payload consists of 0x00 bytes, to be filled
1590in by the application. 0 = do not insert, 1 = insert packets.</entry>
1591 </row>
1592 </tbody>
1593 </tgroup>
1594 </table>
1595 </section>
1596 </section>
1597
1598 <section id="camera-controls">
1599 <title>Camera Control Reference</title>
1600
1601 <para>The Camera class includes controls for mechanical (or
1602equivalent digital) features of a device such as controllable lenses
1603or sensors.</para>
1604
1605 <table pgwide="1" frame="none" id="camera-control-id">
1606 <title>Camera Control IDs</title>
1607 <tgroup cols="4">
1608 <colspec colname="c1" colwidth="1*" />
1609 <colspec colname="c2" colwidth="6*" />
1610 <colspec colname="c3" colwidth="2*" />
1611 <colspec colname="c4" colwidth="6*" />
1612 <spanspec namest="c1" nameend="c2" spanname="id" />
1613 <spanspec namest="c2" nameend="c4" spanname="descr" />
1614 <thead>
1615 <row>
1616 <entry spanname="id" align="left">ID</entry>
1617 <entry align="left">Type</entry>
1618 </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
1619 </row>
1620 </thead>
1621 <tbody valign="top">
1622 <row><entry></entry></row>
1623 <row>
1624 <entry spanname="id"><constant>V4L2_CID_CAMERA_CLASS</constant>&nbsp;</entry>
1625 <entry>class</entry>
1626 </row><row><entry spanname="descr">The Camera class
1627descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
1628description of this control class.</entry>
1629 </row>
1630 <row><entry></entry></row>
1631
1632 <row id="v4l2-exposure-auto-type">
1633 <entry spanname="id"><constant>V4L2_CID_EXPOSURE_AUTO</constant>&nbsp;</entry>
1634 <entry>enum&nbsp;v4l2_exposure_auto_type</entry>
1635 </row><row><entry spanname="descr">Enables automatic
1636adjustments of the exposure time and/or iris aperture. The effect of
1637manual changes of the exposure time or iris aperture while these
1638features are enabled is undefined, drivers should ignore such
1639requests. Possible values are:</entry>
1640 </row>
1641 <row>
1642 <entrytbl spanname="descr" cols="2">
1643 <tbody valign="top">
1644 <row>
1645 <entry><constant>V4L2_EXPOSURE_AUTO</constant>&nbsp;</entry>
1646 <entry>Automatic exposure time, automatic iris
1647aperture.</entry>
1648 </row>
1649 <row>
1650 <entry><constant>V4L2_EXPOSURE_MANUAL</constant>&nbsp;</entry>
1651 <entry>Manual exposure time, manual iris.</entry>
1652 </row>
1653 <row>
1654 <entry><constant>V4L2_EXPOSURE_SHUTTER_PRIORITY</constant>&nbsp;</entry>
1655 <entry>Manual exposure time, auto iris.</entry>
1656 </row>
1657 <row>
1658 <entry><constant>V4L2_EXPOSURE_APERTURE_PRIORITY</constant>&nbsp;</entry>
1659 <entry>Auto exposure time, manual iris.</entry>
1660 </row>
1661 </tbody>
1662 </entrytbl>
1663 </row>
1664 <row><entry></entry></row>
1665
1666 <row>
1667 <entry spanname="id"><constant>V4L2_CID_EXPOSURE_ABSOLUTE</constant>&nbsp;</entry>
1668 <entry>integer</entry>
1669 </row><row><entry spanname="descr">Determines the exposure
1670time of the camera sensor. The exposure time is limited by the frame
1671interval. Drivers should interpret the values as 100 &micro;s units,
1672where the value 1 stands for 1/10000th of a second, 10000 for 1 second
1673and 100000 for 10 seconds.</entry>
1674 </row>
1675 <row><entry></entry></row>
1676
1677 <row>
1678 <entry spanname="id"><constant>V4L2_CID_EXPOSURE_AUTO_PRIORITY</constant>&nbsp;</entry>
1679 <entry>boolean</entry>
1680 </row><row><entry spanname="descr">When
1681<constant>V4L2_CID_EXPOSURE_AUTO</constant> is set to
1682<constant>AUTO</constant> or <constant>APERTURE_PRIORITY</constant>,
1683this control determines if the device may dynamically vary the frame
1684rate. By default this feature is disabled (0) and the frame rate must
1685remain constant.</entry>
1686 </row>
1687 <row><entry></entry></row>
1688
1689 <row>
1690 <entry spanname="id"><constant>V4L2_CID_PAN_RELATIVE</constant>&nbsp;</entry>
1691 <entry>integer</entry>
1692 </row><row><entry spanname="descr">This control turns the
1693camera horizontally by the specified amount. The unit is undefined. A
1694positive value moves the camera to the right (clockwise when viewed
1695from above), a negative value to the left. A value of zero does not
1696cause motion. This is a write-only control.</entry>
1697 </row>
1698 <row><entry></entry></row>
1699
1700 <row>
1701 <entry spanname="id"><constant>V4L2_CID_TILT_RELATIVE</constant>&nbsp;</entry>
1702 <entry>integer</entry>
1703 </row><row><entry spanname="descr">This control turns the
1704camera vertically by the specified amount. The unit is undefined. A
1705positive value moves the camera up, a negative value down. A value of
1706zero does not cause motion. This is a write-only control.</entry>
1707 </row>
1708 <row><entry></entry></row>
1709
1710 <row>
1711 <entry spanname="id"><constant>V4L2_CID_PAN_RESET</constant>&nbsp;</entry>
1712 <entry>button</entry>
1713 </row><row><entry spanname="descr">When this control is set,
1714the camera moves horizontally to the default position.</entry>
1715 </row>
1716 <row><entry></entry></row>
1717
1718 <row>
1719 <entry spanname="id"><constant>V4L2_CID_TILT_RESET</constant>&nbsp;</entry>
1720 <entry>button</entry>
1721 </row><row><entry spanname="descr">When this control is set,
1722the camera moves vertically to the default position.</entry>
1723 </row>
1724 <row><entry></entry></row>
1725
1726 <row>
1727 <entry spanname="id"><constant>V4L2_CID_PAN_ABSOLUTE</constant>&nbsp;</entry>
1728 <entry>integer</entry>
1729 </row><row><entry spanname="descr">This control
1730turns the camera horizontally to the specified position. Positive
1731values move the camera to the right (clockwise when viewed from above),
1732negative values to the left. Drivers should interpret the values as arc
1733seconds, with valid values between -180 * 3600 and +180 * 3600
1734inclusive.</entry>
1735 </row>
1736 <row><entry></entry></row>
1737
1738 <row>
1739 <entry spanname="id"><constant>V4L2_CID_TILT_ABSOLUTE</constant>&nbsp;</entry>
1740 <entry>integer</entry>
1741 </row><row><entry spanname="descr">This control
1742turns the camera vertically to the specified position. Positive values
1743move the camera up, negative values down. Drivers should interpret the
1744values as arc seconds, with valid values between -180 * 3600 and +180
1745* 3600 inclusive.</entry>
1746 </row>
1747 <row><entry></entry></row>
1748
1749 <row>
1750 <entry spanname="id"><constant>V4L2_CID_FOCUS_ABSOLUTE</constant>&nbsp;</entry>
1751 <entry>integer</entry>
1752 </row><row><entry spanname="descr">This control sets the
1753focal point of the camera to the specified position. The unit is
1754undefined. Positive values set the focus closer to the camera,
1755negative values towards infinity.</entry>
1756 </row>
1757 <row><entry></entry></row>
1758
1759 <row>
1760 <entry spanname="id"><constant>V4L2_CID_FOCUS_RELATIVE</constant>&nbsp;</entry>
1761 <entry>integer</entry>
1762 </row><row><entry spanname="descr">This control moves the
1763focal point of the camera by the specified amount. The unit is
1764undefined. Positive values move the focus closer to the camera,
1765negative values towards infinity. This is a write-only control.</entry>
1766 </row>
1767 <row><entry></entry></row>
1768
1769 <row>
1770 <entry spanname="id"><constant>V4L2_CID_FOCUS_AUTO</constant>&nbsp;</entry>
1771 <entry>boolean</entry>
1772 </row><row><entry spanname="descr">Enables automatic focus
1773adjustments. The effect of manual focus adjustments while this feature
1774is enabled is undefined, drivers should ignore such requests.</entry>
1775 </row>
1776 <row><entry></entry></row>
1777
1778 <row>
1779 <entry spanname="id"><constant>V4L2_CID_ZOOM_ABSOLUTE</constant>&nbsp;</entry>
1780 <entry>integer</entry>
1781 </row><row><entry spanname="descr">Specify the objective lens
1782focal length as an absolute value. The zoom unit is driver-specific and its
1783value should be a positive integer.</entry>
1784 </row>
1785 <row><entry></entry></row>
1786
1787 <row>
1788 <entry spanname="id"><constant>V4L2_CID_ZOOM_RELATIVE</constant>&nbsp;</entry>
1789 <entry>integer</entry>
1790 </row><row><entry spanname="descr">Specify the objective lens
1791focal length relatively to the current value. Positive values move the zoom
1792lens group towards the telephoto direction, negative values towards the
1793wide-angle direction. The zoom unit is driver-specific. This is a write-only control.</entry>
1794 </row>
1795 <row><entry></entry></row>
1796
1797 <row>
1798 <entry spanname="id"><constant>V4L2_CID_ZOOM_CONTINUOUS</constant>&nbsp;</entry>
1799 <entry>integer</entry>
1800 </row><row><entry spanname="descr">Move the objective lens group
1801at the specified speed until it reaches physical device limits or until an
1802explicit request to stop the movement. A positive value moves the zoom lens
1803group towards the telephoto direction. A value of zero stops the zoom lens
1804group movement. A negative value moves the zoom lens group towards the
1805wide-angle direction. The zoom speed unit is driver-specific.</entry>
1806 </row>
1807 <row><entry></entry></row>
1808
1809 <row>
1810 <entry spanname="id"><constant>V4L2_CID_PRIVACY</constant>&nbsp;</entry>
1811 <entry>boolean</entry>
1812 </row><row><entry spanname="descr">Prevent video from being acquired
1813by the camera. When this control is set to <constant>TRUE</constant> (1), no
1814image can be captured by the camera. Common means to enforce privacy are
1815mechanical obturation of the sensor and firmware image processing, but the
1816device is not restricted to these methods. Devices that implement the privacy
1817control must support read access and may support write access.</entry>
1818 </row>
1819
1820 <row>
1821 <entry spanname="id"><constant>V4L2_CID_BAND_STOP_FILTER</constant>&nbsp;</entry>
1822 <entry>integer</entry>
1823 </row><row><entry spanname="descr">Switch the band-stop filter of a
1824camera sensor on or off, or specify its strength. Such band-stop filters can
1825be used, for example, to filter out the fluorescent light component.</entry>
1826 </row>
1827 <row><entry></entry></row>
1828 </tbody>
1829 </tgroup>
1830 </table>
1831 </section>
1832
1833 <section id="fm-tx-controls">
1834 <title>FM Transmitter Control Reference</title>
1835
1836 <para>The FM Transmitter (FM_TX) class includes controls for common features of
1837FM transmissions capable devices. Currently this class includes parameters for audio
1838compression, pilot tone generation, audio deviation limiter, RDS transmission and
1839tuning power features.</para>
1840
1841 <table pgwide="1" frame="none" id="fm-tx-control-id">
1842 <title>FM_TX Control IDs</title>
1843
1844 <tgroup cols="4">
1845 <colspec colname="c1" colwidth="1*" />
1846 <colspec colname="c2" colwidth="6*" />
1847 <colspec colname="c3" colwidth="2*" />
1848 <colspec colname="c4" colwidth="6*" />
1849 <spanspec namest="c1" nameend="c2" spanname="id" />
1850 <spanspec namest="c2" nameend="c4" spanname="descr" />
1851 <thead>
1852 <row>
1853 <entry spanname="id" align="left">ID</entry>
1854 <entry align="left">Type</entry>
1855 </row><row rowsep="1"><entry spanname="descr" align="left">Description</entry>
1856 </row>
1857 </thead>
1858 <tbody valign="top">
1859 <row><entry></entry></row>
1860 <row>
1861 <entry spanname="id"><constant>V4L2_CID_FM_TX_CLASS</constant>&nbsp;</entry>
1862 <entry>class</entry>
1863 </row><row><entry spanname="descr">The FM_TX class
1864descriptor. Calling &VIDIOC-QUERYCTRL; for this control will return a
1865description of this control class.</entry>
1866 </row>
1867 <row>
1868 <entry spanname="id"><constant>V4L2_CID_RDS_TX_DEVIATION</constant>&nbsp;</entry>
1869 <entry>integer</entry>
1870 </row>
1871 <row><entry spanname="descr">Configures RDS signal frequency deviation level in Hz.
1872The range and step are driver-specific.</entry>
1873 </row>
1874 <row>
1875 <entry spanname="id"><constant>V4L2_CID_RDS_TX_PI</constant>&nbsp;</entry>
1876 <entry>integer</entry>
1877 </row>
1878 <row><entry spanname="descr">Sets the RDS Programme Identification field
1879for transmission.</entry>
1880 </row>
1881 <row>
1882 <entry spanname="id"><constant>V4L2_CID_RDS_TX_PTY</constant>&nbsp;</entry>
1883 <entry>integer</entry>
1884 </row>
1885 <row><entry spanname="descr">Sets the RDS Programme Type field for transmission.
1886This encodes up to 31 pre-defined programme types.</entry>
1887 </row>
1888 <row>
1889 <entry spanname="id"><constant>V4L2_CID_RDS_TX_PS_NAME</constant>&nbsp;</entry>
1890 <entry>string</entry>
1891 </row>
1892 <row><entry spanname="descr">Sets the Programme Service name (PS_NAME) for transmission.
1893It is intended for static display on a receiver. It is the primary aid to listeners in programme service
1894identification and selection. In Annex E of <xref linkend="en50067" />, the RDS specification,
1895there is a full description of the correct character encoding for Programme Service name strings.
1896Also from RDS specification, PS is usually a single eight character text. However, it is also possible
1897to find receivers which can scroll strings sized as 8 x N characters. So, this control must be configured
1898with steps of 8 characters. The result is it must always contain a string with size multiple of 8.</entry>
1899 </row>
1900 <row>
1901 <entry spanname="id"><constant>V4L2_CID_RDS_TX_RADIO_TEXT</constant>&nbsp;</entry>
1902 <entry>string</entry>
1903 </row>
1904 <row><entry spanname="descr">Sets the Radio Text info for transmission. It is a textual description of
1905what is being broadcasted. RDS Radio Text can be applied when broadcaster wishes to transmit longer PS names,
1906programme-related information or any other text. In these cases, RadioText should be used in addition to
1907<constant>V4L2_CID_RDS_TX_PS_NAME</constant>. The encoding for Radio Text strings is also fully described
1908in Annex E of <xref linkend="en50067" />. The length of Radio Text strings depends on which RDS Block is being
1909used to transmit it, either 32 (2A block) or 64 (2B block). However, it is also possible
1910to find receivers which can scroll strings sized as 32 x N or 64 x N characters. So, this control must be configured
1911with steps of 32 or 64 characters. The result is it must always contain a string with size multiple of 32 or 64. </entry>
1912 </row>
1913 <row>
1914 <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_ENABLED</constant>&nbsp;</entry>
1915 <entry>boolean</entry>
1916 </row>
1917 <row><entry spanname="descr">Enables or disables the audio deviation limiter feature.
1918The limiter is useful when trying to maximize the audio volume, minimize receiver-generated
1919distortion and prevent overmodulation.
1920</entry>
1921 </row>
1922 <row>
1923 <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_RELEASE_TIME</constant>&nbsp;</entry>
1924 <entry>integer</entry>
1925 </row>
1926 <row><entry spanname="descr">Sets the audio deviation limiter feature release time.
1927Unit is in useconds. Step and range are driver-specific.</entry>
1928 </row>
1929 <row>
1930 <entry spanname="id"><constant>V4L2_CID_AUDIO_LIMITER_DEVIATION</constant>&nbsp;</entry>
1931 <entry>integer</entry>
1932 </row>
1933 <row><entry spanname="descr">Configures audio frequency deviation level in Hz.
1934The range and step are driver-specific.</entry>
1935 </row>
1936 <row>
1937 <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_ENABLED</constant>&nbsp;</entry>
1938 <entry>boolean</entry>
1939 </row>
1940 <row><entry spanname="descr">Enables or disables the audio compression feature.
1941This feature amplifies signals below the threshold by a fixed gain and compresses audio
1942signals above the threshold by the ratio of Threshold/(Gain + Threshold).</entry>
1943 </row>
1944 <row>
1945 <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_GAIN</constant>&nbsp;</entry>
1946 <entry>integer</entry>
1947 </row>
1948 <row><entry spanname="descr">Sets the gain for audio compression feature. It is
1949a dB value. The range and step are driver-specific.</entry>
1950 </row>
1951 <row>
1952 <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_THRESHOLD</constant>&nbsp;</entry>
1953 <entry>integer</entry>
1954 </row>
1955 <row><entry spanname="descr">Sets the threshold level for audio compression freature.
1956It is a dB value. The range and step are driver-specific.</entry>
1957 </row>
1958 <row>
1959 <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME</constant>&nbsp;</entry>
1960 <entry>integer</entry>
1961 </row>
1962 <row><entry spanname="descr">Sets the attack time for audio compression feature.
1963It is a useconds value. The range and step are driver-specific.</entry>
1964 </row>
1965 <row>
1966 <entry spanname="id"><constant>V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME</constant>&nbsp;</entry>
1967 <entry>integer</entry>
1968 </row>
1969 <row><entry spanname="descr">Sets the release time for audio compression feature.
1970It is a useconds value. The range and step are driver-specific.</entry>
1971 </row>
1972 <row>
1973 <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_ENABLED</constant>&nbsp;</entry>
1974 <entry>boolean</entry>
1975 </row>
1976 <row><entry spanname="descr">Enables or disables the pilot tone generation feature.</entry>
1977 </row>
1978 <row>
1979 <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_DEVIATION</constant>&nbsp;</entry>
1980 <entry>integer</entry>
1981 </row>
1982 <row><entry spanname="descr">Configures pilot tone frequency deviation level. Unit is
1983in Hz. The range and step are driver-specific.</entry>
1984 </row>
1985 <row>
1986 <entry spanname="id"><constant>V4L2_CID_PILOT_TONE_FREQUENCY</constant>&nbsp;</entry>
1987 <entry>integer</entry>
1988 </row>
1989 <row><entry spanname="descr">Configures pilot tone frequency value. Unit is
1990in Hz. The range and step are driver-specific.</entry>
1991 </row>
1992 <row>
1993 <entry spanname="id"><constant>V4L2_CID_TUNE_PREEMPHASIS</constant>&nbsp;</entry>
1994 <entry>integer</entry>
1995 </row>
1996 <row id="v4l2-preemphasis"><entry spanname="descr">Configures the pre-emphasis value for broadcasting.
1997A pre-emphasis filter is applied to the broadcast to accentuate the high audio frequencies.
1998Depending on the region, a time constant of either 50 or 75 useconds is used. The enum&nbsp;v4l2_preemphasis
1999defines possible values for pre-emphasis. Here they are:</entry>
2000 </row><row>
2001 <entrytbl spanname="descr" cols="2">
2002 <tbody valign="top">
2003 <row>
2004 <entry><constant>V4L2_PREEMPHASIS_DISABLED</constant>&nbsp;</entry>
2005 <entry>No pre-emphasis is applied.</entry>
2006 </row>
2007 <row>
2008 <entry><constant>V4L2_PREEMPHASIS_50_uS</constant>&nbsp;</entry>
2009 <entry>A pre-emphasis of 50 uS is used.</entry>
2010 </row>
2011 <row>
2012 <entry><constant>V4L2_PREEMPHASIS_75_uS</constant>&nbsp;</entry>
2013 <entry>A pre-emphasis of 75 uS is used.</entry>
2014 </row>
2015 </tbody>
2016 </entrytbl>
2017
2018 </row>
2019 <row>
2020 <entry spanname="id"><constant>V4L2_CID_TUNE_POWER_LEVEL</constant>&nbsp;</entry>
2021 <entry>integer</entry>
2022 </row>
2023 <row><entry spanname="descr">Sets the output power level for signal transmission.
2024Unit is in dBuV. Range and step are driver-specific.</entry>
2025 </row>
2026 <row>
2027 <entry spanname="id"><constant>V4L2_CID_TUNE_ANTENNA_CAPACITOR</constant>&nbsp;</entry>
2028 <entry>integer</entry>
2029 </row>
2030 <row><entry spanname="descr">This selects the value of antenna tuning capacitor
2031manually or automatically if set to zero. Unit, range and step are driver-specific.</entry>
2032 </row>
2033 <row><entry></entry></row>
2034 </tbody>
2035 </tgroup>
2036 </table>
2037
2038<para>For more details about RDS specification, refer to
2039<xref linkend="en50067" /> document, from CENELEC.</para>
2040 </section>
2041</section>
2042
2043 <!--
2044Local Variables:
2045mode: sgml
2046sgml-parent-document: "common.sgml"
2047indent-tabs-mode: nil
2048End:
2049 -->
diff --git a/Documentation/DocBook/v4l/crop.gif b/Documentation/DocBook/v4l/crop.gif
new file mode 100644
index 000000000000..3b9e7d836d4b
--- /dev/null
+++ b/Documentation/DocBook/v4l/crop.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/crop.pdf b/Documentation/DocBook/v4l/crop.pdf
new file mode 100644
index 000000000000..c9fb81cd32f3
--- /dev/null
+++ b/Documentation/DocBook/v4l/crop.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/dev-capture.xml b/Documentation/DocBook/v4l/dev-capture.xml
new file mode 100644
index 000000000000..32807e43f170
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-capture.xml
@@ -0,0 +1,115 @@
1 <title>Video Capture Interface</title>
2
3 <para>Video capture devices sample an analog video signal and store
4the digitized images in memory. Today nearly all devices can capture
5at full 25 or 30 frames/second. With this interface applications can
6control the capture process and move images from the driver into user
7space.</para>
8
9 <para>Conventionally V4L2 video capture devices are accessed through
10character device special files named <filename>/dev/video</filename>
11and <filename>/dev/video0</filename> to
12<filename>/dev/video63</filename> with major number 81 and minor
13numbers 0 to 63. <filename>/dev/video</filename> is typically a
14symbolic link to the preferred video device. Note the same device
15files are used for video output devices.</para>
16
17 <section>
18 <title>Querying Capabilities</title>
19
20 <para>Devices supporting the video capture interface set the
21<constant>V4L2_CAP_VIDEO_CAPTURE</constant> flag in the
22<structfield>capabilities</structfield> field of &v4l2-capability;
23returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
24they may also support the <link linkend="overlay">video overlay</link>
25(<constant>V4L2_CAP_VIDEO_OVERLAY</constant>) and the <link
26linkend="raw-vbi">raw VBI capture</link>
27(<constant>V4L2_CAP_VBI_CAPTURE</constant>) interface. At least one of
28the read/write or streaming I/O methods must be supported. Tuners and
29audio inputs are optional.</para>
30 </section>
31
32 <section>
33 <title>Supplemental Functions</title>
34
35 <para>Video capture devices shall support <link
36linkend="audio">audio input</link>, <link
37linkend="tuner">tuner</link>, <link linkend="control">controls</link>,
38<link linkend="crop">cropping and scaling</link> and <link
39linkend="streaming-par">streaming parameter</link> ioctls as needed.
40The <link linkend="video">video input</link> and <link
41linkend="standard">video standard</link> ioctls must be supported by
42all video capture devices.</para>
43 </section>
44
45 <section>
46 <title>Image Format Negotiation</title>
47
48 <para>The result of a capture operation is determined by
49cropping and image format parameters. The former select an area of the
50video picture to capture, the latter how images are stored in memory,
51&ie; in RGB or YUV format, the number of bits per pixel or width and
52height. Together they also define how images are scaled in the
53process.</para>
54
55 <para>As usual these parameters are <emphasis>not</emphasis> reset
56at &func-open; time to permit Unix tool chains, programming a device
57and then reading from it as if it was a plain file. Well written V4L2
58applications ensure they really get what they want, including cropping
59and scaling.</para>
60
61 <para>Cropping initialization at minimum requires to reset the
62parameters to defaults. An example is given in <xref
63linkend="crop" />.</para>
64
65 <para>To query the current image format applications set the
66<structfield>type</structfield> field of a &v4l2-format; to
67<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and call the
68&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
69the &v4l2-pix-format; <structfield>pix</structfield> member of the
70<structfield>fmt</structfield> union.</para>
71
72 <para>To request different parameters applications set the
73<structfield>type</structfield> field of a &v4l2-format; as above and
74initialize all fields of the &v4l2-pix-format;
75<structfield>vbi</structfield> member of the
76<structfield>fmt</structfield> union, or better just modify the
77results of <constant>VIDIOC_G_FMT</constant>, and call the
78&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers may
79adjust the parameters and finally return the actual parameters as
80<constant>VIDIOC_G_FMT</constant> does.</para>
81
82 <para>Like <constant>VIDIOC_S_FMT</constant> the
83&VIDIOC-TRY-FMT; ioctl can be used to learn about hardware limitations
84without disabling I/O or possibly time consuming hardware
85preparations.</para>
86
87 <para>The contents of &v4l2-pix-format; are discussed in <xref
88linkend="pixfmt" />. See also the specification of the
89<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
90and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
91capture devices must implement both the
92<constant>VIDIOC_G_FMT</constant> and
93<constant>VIDIOC_S_FMT</constant> ioctl, even if
94<constant>VIDIOC_S_FMT</constant> ignores all requests and always
95returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
96<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
97 </section>
98
99 <section>
100 <title>Reading Images</title>
101
102 <para>A video capture device may support the <link
103linkend="rw">read() function</link> and/or streaming (<link
104linkend="mmap">memory mapping</link> or <link
105linkend="userp">user pointer</link>) I/O. See <xref
106linkend="io" /> for details.</para>
107 </section>
108
109 <!--
110Local Variables:
111mode: sgml
112sgml-parent-document: "v4l2.sgml"
113indent-tabs-mode: nil
114End:
115 -->
diff --git a/Documentation/DocBook/v4l/dev-codec.xml b/Documentation/DocBook/v4l/dev-codec.xml
new file mode 100644
index 000000000000..6e156dc45b94
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-codec.xml
@@ -0,0 +1,26 @@
1 <title>Codec Interface</title>
2
3 <note>
4 <title>Suspended</title>
5
6 <para>This interface has been be suspended from the V4L2 API
7implemented in Linux 2.6 until we have more experience with codec
8device interfaces.</para>
9 </note>
10
11 <para>A V4L2 codec can compress, decompress, transform, or otherwise
12convert video data from one format into another format, in memory.
13Applications send data to be converted to the driver through a
14&func-write; call, and receive the converted data through a
15&func-read; call. For efficiency a driver may also support streaming
16I/O.</para>
17
18 <para>[to do]</para>
19
20 <!--
21Local Variables:
22mode: sgml
23sgml-parent-document: "v4l2.sgml"
24indent-tabs-mode: nil
25End:
26 -->
diff --git a/Documentation/DocBook/v4l/dev-effect.xml b/Documentation/DocBook/v4l/dev-effect.xml
new file mode 100644
index 000000000000..9c243beba0e6
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-effect.xml
@@ -0,0 +1,25 @@
1 <title>Effect Devices Interface</title>
2
3 <note>
4 <title>Suspended</title>
5
6 <para>This interface has been be suspended from the V4L2 API
7implemented in Linux 2.6 until we have more experience with effect
8device interfaces.</para>
9 </note>
10
11 <para>A V4L2 video effect device can do image effects, filtering, or
12combine two or more images or image streams. For example video
13transitions or wipes. Applications send data to be processed and
14receive the result data either with &func-read; and &func-write;
15functions, or through the streaming I/O mechanism.</para>
16
17 <para>[to do]</para>
18
19 <!--
20Local Variables:
21mode: sgml
22sgml-parent-document: "v4l2.sgml"
23indent-tabs-mode: nil
24End:
25 -->
diff --git a/Documentation/DocBook/v4l/dev-osd.xml b/Documentation/DocBook/v4l/dev-osd.xml
new file mode 100644
index 000000000000..c9a68a2ccd33
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-osd.xml
@@ -0,0 +1,164 @@
1 <title>Video Output Overlay Interface</title>
2 <subtitle>Also known as On-Screen Display (OSD)</subtitle>
3
4 <note>
5 <title>Experimental</title>
6
7 <para>This is an <link linkend="experimental">experimental</link>
8interface and may change in the future.</para>
9 </note>
10
11 <para>Some video output devices can overlay a framebuffer image onto
12the outgoing video signal. Applications can set up such an overlay
13using this interface, which borrows structures and ioctls of the <link
14linkend="overlay">Video Overlay</link> interface.</para>
15
16 <para>The OSD function is accessible through the same character
17special file as the <link linkend="capture">Video Output</link> function.
18Note the default function of such a <filename>/dev/video</filename> device
19is video capturing or output. The OSD function is only available after
20calling the &VIDIOC-S-FMT; ioctl.</para>
21
22 <section>
23 <title>Querying Capabilities</title>
24
25 <para>Devices supporting the <wordasword>Video Output
26Overlay</wordasword> interface set the
27<constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant> flag in the
28<structfield>capabilities</structfield> field of &v4l2-capability;
29returned by the &VIDIOC-QUERYCAP; ioctl.</para>
30 </section>
31
32 <section>
33 <title>Framebuffer</title>
34
35 <para>Contrary to the <wordasword>Video Overlay</wordasword>
36interface the framebuffer is normally implemented on the TV card and
37not the graphics card. On Linux it is accessible as a framebuffer
38device (<filename>/dev/fbN</filename>). Given a V4L2 device,
39applications can find the corresponding framebuffer device by calling
40the &VIDIOC-G-FBUF; ioctl. It returns, amongst other information, the
41physical address of the framebuffer in the
42<structfield>base</structfield> field of &v4l2-framebuffer;. The
43framebuffer device ioctl <constant>FBIOGET_FSCREENINFO</constant>
44returns the same address in the <structfield>smem_start</structfield>
45field of struct <structname>fb_fix_screeninfo</structname>. The
46<constant>FBIOGET_FSCREENINFO</constant> ioctl and struct
47<structname>fb_fix_screeninfo</structname> are defined in the
48<filename>linux/fb.h</filename> header file.</para>
49
50 <para>The width and height of the framebuffer depends on the
51current video standard. A V4L2 driver may reject attempts to change
52the video standard (or any other ioctl which would imply a framebuffer
53size change) with an &EBUSY; until all applications closed the
54framebuffer device.</para>
55
56 <example>
57 <title>Finding a framebuffer device for OSD</title>
58
59 <programlisting>
60#include &lt;linux/fb.h&gt;
61
62&v4l2-framebuffer; fbuf;
63unsigned int i;
64int fb_fd;
65
66if (-1 == ioctl (fd, VIDIOC_G_FBUF, &amp;fbuf)) {
67 perror ("VIDIOC_G_FBUF");
68 exit (EXIT_FAILURE);
69}
70
71for (i = 0; i &gt; 30; ++i) {
72 char dev_name[16];
73 struct fb_fix_screeninfo si;
74
75 snprintf (dev_name, sizeof (dev_name), "/dev/fb%u", i);
76
77 fb_fd = open (dev_name, O_RDWR);
78 if (-1 == fb_fd) {
79 switch (errno) {
80 case ENOENT: /* no such file */
81 case ENXIO: /* no driver */
82 continue;
83
84 default:
85 perror ("open");
86 exit (EXIT_FAILURE);
87 }
88 }
89
90 if (0 == ioctl (fb_fd, FBIOGET_FSCREENINFO, &amp;si)) {
91 if (si.smem_start == (unsigned long) fbuf.base)
92 break;
93 } else {
94 /* Apparently not a framebuffer device. */
95 }
96
97 close (fb_fd);
98 fb_fd = -1;
99}
100
101/* fb_fd is the file descriptor of the framebuffer device
102 for the video output overlay, or -1 if no device was found. */
103</programlisting>
104 </example>
105 </section>
106
107 <section>
108 <title>Overlay Window and Scaling</title>
109
110 <para>The overlay is controlled by source and target rectangles.
111The source rectangle selects a subsection of the framebuffer image to
112be overlaid, the target rectangle an area in the outgoing video signal
113where the image will appear. Drivers may or may not support scaling,
114and arbitrary sizes and positions of these rectangles. Further drivers
115may support any (or none) of the clipping/blending methods defined for
116the <link linkend="overlay">Video Overlay</link> interface.</para>
117
118 <para>A &v4l2-window; defines the size of the source rectangle,
119its position in the framebuffer and the clipping/blending method to be
120used for the overlay. To get the current parameters applications set
121the <structfield>type</structfield> field of a &v4l2-format; to
122<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant> and call the
123&VIDIOC-G-FMT; ioctl. The driver fills the
124<structname>v4l2_window</structname> substructure named
125<structfield>win</structfield>. It is not possible to retrieve a
126previously programmed clipping list or bitmap.</para>
127
128 <para>To program the source rectangle applications set the
129<structfield>type</structfield> field of a &v4l2-format; to
130<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant>, initialize
131the <structfield>win</structfield> substructure and call the
132&VIDIOC-S-FMT; ioctl. The driver adjusts the parameters against
133hardware limits and returns the actual parameters as
134<constant>VIDIOC_G_FMT</constant> does. Like
135<constant>VIDIOC_S_FMT</constant>, the &VIDIOC-TRY-FMT; ioctl can be
136used to learn about driver capabilities without actually changing
137driver state. Unlike <constant>VIDIOC_S_FMT</constant> this also works
138after the overlay has been enabled.</para>
139
140 <para>A &v4l2-crop; defines the size and position of the target
141rectangle. The scaling factor of the overlay is implied by the width
142and height given in &v4l2-window; and &v4l2-crop;. The cropping API
143applies to <wordasword>Video Output</wordasword> and <wordasword>Video
144Output Overlay</wordasword> devices in the same way as to
145<wordasword>Video Capture</wordasword> and <wordasword>Video
146Overlay</wordasword> devices, merely reversing the direction of the
147data flow. For more information see <xref linkend="crop" />.</para>
148 </section>
149
150 <section>
151 <title>Enabling Overlay</title>
152
153 <para>There is no V4L2 ioctl to enable or disable the overlay,
154however the framebuffer interface of the driver may support the
155<constant>FBIOBLANK</constant> ioctl.</para>
156 </section>
157
158 <!--
159Local Variables:
160mode: sgml
161sgml-parent-document: "v4l2.sgml"
162indent-tabs-mode: nil
163End:
164 -->
diff --git a/Documentation/DocBook/v4l/dev-output.xml b/Documentation/DocBook/v4l/dev-output.xml
new file mode 100644
index 000000000000..63c3c20e5a72
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-output.xml
@@ -0,0 +1,111 @@
1 <title>Video Output Interface</title>
2
3 <para>Video output devices encode stills or image sequences as
4analog video signal. With this interface applications can
5control the encoding process and move images from user space to
6the driver.</para>
7
8 <para>Conventionally V4L2 video output devices are accessed through
9character device special files named <filename>/dev/video</filename>
10and <filename>/dev/video0</filename> to
11<filename>/dev/video63</filename> with major number 81 and minor
12numbers 0 to 63. <filename>/dev/video</filename> is typically a
13symbolic link to the preferred video device. Note the same device
14files are used for video capture devices.</para>
15
16 <section>
17 <title>Querying Capabilities</title>
18
19 <para>Devices supporting the video output interface set the
20<constant>V4L2_CAP_VIDEO_OUTPUT</constant> flag in the
21<structfield>capabilities</structfield> field of &v4l2-capability;
22returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
23they may also support the <link linkend="raw-vbi">raw VBI
24output</link> (<constant>V4L2_CAP_VBI_OUTPUT</constant>) interface. At
25least one of the read/write or streaming I/O methods must be
26supported. Modulators and audio outputs are optional.</para>
27 </section>
28
29 <section>
30 <title>Supplemental Functions</title>
31
32 <para>Video output devices shall support <link
33linkend="audio">audio output</link>, <link
34linkend="tuner">modulator</link>, <link linkend="control">controls</link>,
35<link linkend="crop">cropping and scaling</link> and <link
36linkend="streaming-par">streaming parameter</link> ioctls as needed.
37The <link linkend="video">video output</link> and <link
38linkend="standard">video standard</link> ioctls must be supported by
39all video output devices.</para>
40 </section>
41
42 <section>
43 <title>Image Format Negotiation</title>
44
45 <para>The output is determined by cropping and image format
46parameters. The former select an area of the video picture where the
47image will appear, the latter how images are stored in memory, &ie; in
48RGB or YUV format, the number of bits per pixel or width and height.
49Together they also define how images are scaled in the process.</para>
50
51 <para>As usual these parameters are <emphasis>not</emphasis> reset
52at &func-open; time to permit Unix tool chains, programming a device
53and then writing to it as if it was a plain file. Well written V4L2
54applications ensure they really get what they want, including cropping
55and scaling.</para>
56
57 <para>Cropping initialization at minimum requires to reset the
58parameters to defaults. An example is given in <xref
59linkend="crop" />.</para>
60
61 <para>To query the current image format applications set the
62<structfield>type</structfield> field of a &v4l2-format; to
63<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and call the
64&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
65the &v4l2-pix-format; <structfield>pix</structfield> member of the
66<structfield>fmt</structfield> union.</para>
67
68 <para>To request different parameters applications set the
69<structfield>type</structfield> field of a &v4l2-format; as above and
70initialize all fields of the &v4l2-pix-format;
71<structfield>vbi</structfield> member of the
72<structfield>fmt</structfield> union, or better just modify the
73results of <constant>VIDIOC_G_FMT</constant>, and call the
74&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers may
75adjust the parameters and finally return the actual parameters as
76<constant>VIDIOC_G_FMT</constant> does.</para>
77
78 <para>Like <constant>VIDIOC_S_FMT</constant> the
79&VIDIOC-TRY-FMT; ioctl can be used to learn about hardware limitations
80without disabling I/O or possibly time consuming hardware
81preparations.</para>
82
83 <para>The contents of &v4l2-pix-format; are discussed in <xref
84linkend="pixfmt" />. See also the specification of the
85<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
86and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
87output devices must implement both the
88<constant>VIDIOC_G_FMT</constant> and
89<constant>VIDIOC_S_FMT</constant> ioctl, even if
90<constant>VIDIOC_S_FMT</constant> ignores all requests and always
91returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
92<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
93 </section>
94
95 <section>
96 <title>Writing Images</title>
97
98 <para>A video output device may support the <link
99linkend="rw">write() function</link> and/or streaming (<link
100linkend="mmap">memory mapping</link> or <link
101linkend="userp">user pointer</link>) I/O. See <xref
102linkend="io" /> for details.</para>
103 </section>
104
105 <!--
106Local Variables:
107mode: sgml
108sgml-parent-document: "v4l2.sgml"
109indent-tabs-mode: nil
110End:
111 -->
diff --git a/Documentation/DocBook/v4l/dev-overlay.xml b/Documentation/DocBook/v4l/dev-overlay.xml
new file mode 100644
index 000000000000..92513cf79150
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-overlay.xml
@@ -0,0 +1,379 @@
1 <title>Video Overlay Interface</title>
2 <subtitle>Also known as Framebuffer Overlay or Previewing</subtitle>
3
4 <para>Video overlay devices have the ability to genlock (TV-)video
5into the (VGA-)video signal of a graphics card, or to store captured
6images directly in video memory of a graphics card, typically with
7clipping. This can be considerable more efficient than capturing
8images and displaying them by other means. In the old days when only
9nuclear power plants needed cooling towers this used to be the only
10way to put live video into a window.</para>
11
12 <para>Video overlay devices are accessed through the same character
13special files as <link linkend="capture">video capture</link> devices.
14Note the default function of a <filename>/dev/video</filename> device
15is video capturing. The overlay function is only available after
16calling the &VIDIOC-S-FMT; ioctl.</para>
17
18 <para>The driver may support simultaneous overlay and capturing
19using the read/write and streaming I/O methods. If so, operation at
20the nominal frame rate of the video standard is not guaranteed. Frames
21may be directed away from overlay to capture, or one field may be used
22for overlay and the other for capture if the capture parameters permit
23this.</para>
24
25 <para>Applications should use different file descriptors for
26capturing and overlay. This must be supported by all drivers capable
27of simultaneous capturing and overlay. Optionally these drivers may
28also permit capturing and overlay with a single file descriptor for
29compatibility with V4L and earlier versions of V4L2.<footnote>
30 <para>A common application of two file descriptors is the
31XFree86 <link linkend="xvideo">Xv/V4L</link> interface driver and
32a V4L2 application. While the X server controls video overlay, the
33application can take advantage of memory mapping and DMA.</para>
34 <para>In the opinion of the designers of this API, no driver
35writer taking the efforts to support simultaneous capturing and
36overlay will restrict this ability by requiring a single file
37descriptor, as in V4L and earlier versions of V4L2. Making this
38optional means applications depending on two file descriptors need
39backup routines to be compatible with all drivers, which is
40considerable more work than using two fds in applications which do
41not. Also two fd's fit the general concept of one file descriptor for
42each logical stream. Hence as a complexity trade-off drivers
43<emphasis>must</emphasis> support two file descriptors and
44<emphasis>may</emphasis> support single fd operation.</para>
45 </footnote></para>
46
47 <section>
48 <title>Querying Capabilities</title>
49
50 <para>Devices supporting the video overlay interface set the
51<constant>V4L2_CAP_VIDEO_OVERLAY</constant> flag in the
52<structfield>capabilities</structfield> field of &v4l2-capability;
53returned by the &VIDIOC-QUERYCAP; ioctl. The overlay I/O method specified
54below must be supported. Tuners and audio inputs are optional.</para>
55 </section>
56
57 <section>
58 <title>Supplemental Functions</title>
59
60 <para>Video overlay devices shall support <link
61linkend="audio">audio input</link>, <link
62linkend="tuner">tuner</link>, <link linkend="control">controls</link>,
63<link linkend="crop">cropping and scaling</link> and <link
64linkend="streaming-par">streaming parameter</link> ioctls as needed.
65The <link linkend="video">video input</link> and <link
66linkend="standard">video standard</link> ioctls must be supported by
67all video overlay devices.</para>
68 </section>
69
70 <section>
71 <title>Setup</title>
72
73 <para>Before overlay can commence applications must program the
74driver with frame buffer parameters, namely the address and size of
75the frame buffer and the image format, for example RGB 5:6:5. The
76&VIDIOC-G-FBUF; and &VIDIOC-S-FBUF; ioctls are available to get
77and set these parameters, respectively. The
78<constant>VIDIOC_S_FBUF</constant> ioctl is privileged because it
79allows to set up DMA into physical memory, bypassing the memory
80protection mechanisms of the kernel. Only the superuser can change the
81frame buffer address and size. Users are not supposed to run TV
82applications as root or with SUID bit set. A small helper application
83with suitable privileges should query the graphics system and program
84the V4L2 driver at the appropriate time.</para>
85
86 <para>Some devices add the video overlay to the output signal
87of the graphics card. In this case the frame buffer is not modified by
88the video device, and the frame buffer address and pixel format are
89not needed by the driver. The <constant>VIDIOC_S_FBUF</constant> ioctl
90is not privileged. An application can check for this type of device by
91calling the <constant>VIDIOC_G_FBUF</constant> ioctl.</para>
92
93 <para>A driver may support any (or none) of five clipping/blending
94methods:<orderedlist>
95 <listitem>
96 <para>Chroma-keying displays the overlaid image only where
97pixels in the primary graphics surface assume a certain color.</para>
98 </listitem>
99 <listitem>
100 <para>A bitmap can be specified where each bit corresponds
101to a pixel in the overlaid image. When the bit is set, the
102corresponding video pixel is displayed, otherwise a pixel of the
103graphics surface.</para>
104 </listitem>
105 <listitem>
106 <para>A list of clipping rectangles can be specified. In
107these regions <emphasis>no</emphasis> video is displayed, so the
108graphics surface can be seen here.</para>
109 </listitem>
110 <listitem>
111 <para>The framebuffer has an alpha channel that can be used
112to clip or blend the framebuffer with the video.</para>
113 </listitem>
114 <listitem>
115 <para>A global alpha value can be specified to blend the
116framebuffer contents with video images.</para>
117 </listitem>
118 </orderedlist></para>
119
120 <para>When simultaneous capturing and overlay is supported and
121the hardware prohibits different image and frame buffer formats, the
122format requested first takes precedence. The attempt to capture
123(&VIDIOC-S-FMT;) or overlay (&VIDIOC-S-FBUF;) may fail with an
124&EBUSY; or return accordingly modified parameters..</para>
125 </section>
126
127 <section>
128 <title>Overlay Window</title>
129
130 <para>The overlaid image is determined by cropping and overlay
131window parameters. The former select an area of the video picture to
132capture, the latter how images are overlaid and clipped. Cropping
133initialization at minimum requires to reset the parameters to
134defaults. An example is given in <xref linkend="crop" />.</para>
135
136 <para>The overlay window is described by a &v4l2-window;. It
137defines the size of the image, its position over the graphics surface
138and the clipping to be applied. To get the current parameters
139applications set the <structfield>type</structfield> field of a
140&v4l2-format; to <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant> and
141call the &VIDIOC-G-FMT; ioctl. The driver fills the
142<structname>v4l2_window</structname> substructure named
143<structfield>win</structfield>. It is not possible to retrieve a
144previously programmed clipping list or bitmap.</para>
145
146 <para>To program the overlay window applications set the
147<structfield>type</structfield> field of a &v4l2-format; to
148<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, initialize the
149<structfield>win</structfield> substructure and call the
150&VIDIOC-S-FMT; ioctl. The driver adjusts the parameters against
151hardware limits and returns the actual parameters as
152<constant>VIDIOC_G_FMT</constant> does. Like
153<constant>VIDIOC_S_FMT</constant>, the &VIDIOC-TRY-FMT; ioctl can be
154used to learn about driver capabilities without actually changing
155driver state. Unlike <constant>VIDIOC_S_FMT</constant> this also works
156after the overlay has been enabled.</para>
157
158 <para>The scaling factor of the overlaid image is implied by the
159width and height given in &v4l2-window; and the size of the cropping
160rectangle. For more information see <xref linkend="crop" />.</para>
161
162 <para>When simultaneous capturing and overlay is supported and
163the hardware prohibits different image and window sizes, the size
164requested first takes precedence. The attempt to capture or overlay as
165well (&VIDIOC-S-FMT;) may fail with an &EBUSY; or return accordingly
166modified parameters.</para>
167
168 <table pgwide="1" frame="none" id="v4l2-window">
169 <title>struct <structname>v4l2_window</structname></title>
170 <tgroup cols="3">
171 &cs-str;
172 <tbody valign="top">
173 <row>
174 <entry>&v4l2-rect;</entry>
175 <entry><structfield>w</structfield></entry>
176 <entry>Size and position of the window relative to the
177top, left corner of the frame buffer defined with &VIDIOC-S-FBUF;. The
178window can extend the frame buffer width and height, the
179<structfield>x</structfield> and <structfield>y</structfield>
180coordinates can be negative, and it can lie completely outside the
181frame buffer. The driver clips the window accordingly, or if that is
182not possible, modifies its size and/or position.</entry>
183 </row>
184 <row>
185 <entry>&v4l2-field;</entry>
186 <entry><structfield>field</structfield></entry>
187 <entry>Applications set this field to determine which
188video field shall be overlaid, typically one of
189<constant>V4L2_FIELD_ANY</constant> (0),
190<constant>V4L2_FIELD_TOP</constant>,
191<constant>V4L2_FIELD_BOTTOM</constant> or
192<constant>V4L2_FIELD_INTERLACED</constant>. Drivers may have to choose
193a different field order and return the actual setting here.</entry>
194 </row>
195 <row>
196 <entry>__u32</entry>
197 <entry><structfield>chromakey</structfield></entry>
198 <entry>When chroma-keying has been negotiated with
199&VIDIOC-S-FBUF; applications set this field to the desired pixel value
200for the chroma key. The format is the same as the pixel format of the
201framebuffer (&v4l2-framebuffer;
202<structfield>fmt.pixelformat</structfield> field), with bytes in host
203order. E.&nbsp;g. for <link
204linkend="V4L2-PIX-FMT-BGR32"><constant>V4L2_PIX_FMT_BGR24</constant></link>
205the value should be 0xRRGGBB on a little endian, 0xBBGGRR on a big
206endian host.</entry>
207 </row>
208 <row>
209 <entry>&v4l2-clip; *</entry>
210 <entry><structfield>clips</structfield></entry>
211 <entry>When chroma-keying has <emphasis>not</emphasis>
212been negotiated and &VIDIOC-G-FBUF; indicated this capability,
213applications can set this field to point to an array of
214clipping rectangles.</entry>
215 </row>
216 <row>
217 <entry></entry>
218 <entry></entry>
219 <entry>Like the window coordinates
220<structfield>w</structfield>, clipping rectangles are defined relative
221to the top, left corner of the frame buffer. However clipping
222rectangles must not extend the frame buffer width and height, and they
223must not overlap. If possible applications should merge adjacent
224rectangles. Whether this must create x-y or y-x bands, or the order of
225rectangles, is not defined. When clip lists are not supported the
226driver ignores this field. Its contents after calling &VIDIOC-S-FMT;
227are undefined.</entry>
228 </row>
229 <row>
230 <entry>__u32</entry>
231 <entry><structfield>clipcount</structfield></entry>
232 <entry>When the application set the
233<structfield>clips</structfield> field, this field must contain the
234number of clipping rectangles in the list. When clip lists are not
235supported the driver ignores this field, its contents after calling
236<constant>VIDIOC_S_FMT</constant> are undefined. When clip lists are
237supported but no clipping is desired this field must be set to
238zero.</entry>
239 </row>
240 <row>
241 <entry>void *</entry>
242 <entry><structfield>bitmap</structfield></entry>
243 <entry>When chroma-keying has
244<emphasis>not</emphasis> been negotiated and &VIDIOC-G-FBUF; indicated
245this capability, applications can set this field to point to a
246clipping bit mask.</entry>
247 </row>
248 <row>
249 <entry spanname="hspan"><para>It must be of the same size
250as the window, <structfield>w.width</structfield> and
251<structfield>w.height</structfield>. Each bit corresponds to a pixel
252in the overlaid image, which is displayed only when the bit is
253<emphasis>set</emphasis>. Pixel coordinates translate to bits like:
254<programlisting>
255((__u8 *) <structfield>bitmap</structfield>)[<structfield>w.width</structfield> * y + x / 8] &amp; (1 &lt;&lt; (x &amp; 7))</programlisting></para><para>where <structfield>0</structfield> &le; x &lt;
256<structfield>w.width</structfield> and <structfield>0</structfield> &le;
257y &lt;<structfield>w.height</structfield>.<footnote>
258 <para>Should we require
259 <structfield>w.width</structfield> to be a multiple of
260 eight?</para>
261 </footnote></para><para>When a clipping
262bit mask is not supported the driver ignores this field, its contents
263after calling &VIDIOC-S-FMT; are undefined. When a bit mask is supported
264but no clipping is desired this field must be set to
265<constant>NULL</constant>.</para><para>Applications need not create a
266clip list or bit mask. When they pass both, or despite negotiating
267chroma-keying, the results are undefined. Regardless of the chosen
268method, the clipping abilities of the hardware may be limited in
269quantity or quality. The results when these limits are exceeded are
270undefined.<footnote>
271 <para>When the image is written into frame buffer
272memory it will be undesirable if the driver clips out less pixels
273than expected, because the application and graphics system are not
274aware these regions need to be refreshed. The driver should clip out
275more pixels or not write the image at all.</para>
276 </footnote></para></entry>
277 </row>
278 <row>
279 <entry>__u8</entry>
280 <entry><structfield>global_alpha</structfield></entry>
281 <entry>The global alpha value used to blend the
282framebuffer with video images, if global alpha blending has been
283negotiated (<constant>V4L2_FBUF_FLAG_GLOBAL_ALPHA</constant>, see
284&VIDIOC-S-FBUF;, <xref linkend="framebuffer-flags" />).</entry>
285 </row>
286 <row>
287 <entry></entry>
288 <entry></entry>
289 <entry>Note this field was added in Linux 2.6.23, extending the structure. However
290the <link linkend="vidioc-g-fmt">VIDIOC_G/S/TRY_FMT</link> ioctls,
291which take a pointer to a <link
292linkend="v4l2-format">v4l2_format</link> parent structure with padding
293bytes at the end, are not affected.</entry>
294 </row>
295 </tbody>
296 </tgroup>
297 </table>
298
299 <table pgwide="1" frame="none" id="v4l2-clip">
300 <title>struct <structname>v4l2_clip</structname><footnote>
301 <para>The X Window system defines "regions" which are
302vectors of struct BoxRec { short x1, y1, x2, y2; } with width = x2 -
303x1 and height = y2 - y1, so one cannot pass X11 clip lists
304directly.</para>
305 </footnote></title>
306 <tgroup cols="3">
307 &cs-str;
308 <tbody valign="top">
309 <row>
310 <entry>&v4l2-rect;</entry>
311 <entry><structfield>c</structfield></entry>
312 <entry>Coordinates of the clipping rectangle, relative to
313the top, left corner of the frame buffer. Only window pixels
314<emphasis>outside</emphasis> all clipping rectangles are
315displayed.</entry>
316 </row>
317 <row>
318 <entry>&v4l2-clip; *</entry>
319 <entry><structfield>next</structfield></entry>
320 <entry>Pointer to the next clipping rectangle, NULL when
321this is the last rectangle. Drivers ignore this field, it cannot be
322used to pass a linked list of clipping rectangles.</entry>
323 </row>
324 </tbody>
325 </tgroup>
326 </table>
327
328 <!-- NB for easier reading this table is duplicated
329 in the vidioc-cropcap chapter.-->
330
331 <table pgwide="1" frame="none" id="v4l2-rect">
332 <title>struct <structname>v4l2_rect</structname></title>
333 <tgroup cols="3">
334 &cs-str;
335 <tbody valign="top">
336 <row>
337 <entry>__s32</entry>
338 <entry><structfield>left</structfield></entry>
339 <entry>Horizontal offset of the top, left corner of the
340rectangle, in pixels.</entry>
341 </row>
342 <row>
343 <entry>__s32</entry>
344 <entry><structfield>top</structfield></entry>
345 <entry>Vertical offset of the top, left corner of the
346rectangle, in pixels. Offsets increase to the right and down.</entry>
347 </row>
348 <row>
349 <entry>__s32</entry>
350 <entry><structfield>width</structfield></entry>
351 <entry>Width of the rectangle, in pixels.</entry>
352 </row>
353 <row>
354 <entry>__s32</entry>
355 <entry><structfield>height</structfield></entry>
356 <entry>Height of the rectangle, in pixels. Width and
357height cannot be negative, the fields are signed for hysterical
358reasons. <!-- video4linux-list@redhat.com on 22 Oct 2002 subject
359"Re:[V4L][patches!] Re:v4l2/kernel-2.5" --></entry>
360 </row>
361 </tbody>
362 </tgroup>
363 </table>
364 </section>
365
366 <section>
367 <title>Enabling Overlay</title>
368
369 <para>To start or stop the frame buffer overlay applications call
370the &VIDIOC-OVERLAY; ioctl.</para>
371 </section>
372
373 <!--
374Local Variables:
375mode: sgml
376sgml-parent-document: "v4l2.sgml"
377indent-tabs-mode: nil
378End:
379 -->
diff --git a/Documentation/DocBook/v4l/dev-radio.xml b/Documentation/DocBook/v4l/dev-radio.xml
new file mode 100644
index 000000000000..73aa90b45b34
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-radio.xml
@@ -0,0 +1,57 @@
1 <title>Radio Interface</title>
2
3 <para>This interface is intended for AM and FM (analog) radio
4receivers and transmitters.</para>
5
6 <para>Conventionally V4L2 radio devices are accessed through
7character device special files named <filename>/dev/radio</filename>
8and <filename>/dev/radio0</filename> to
9<filename>/dev/radio63</filename> with major number 81 and minor
10numbers 64 to 127.</para>
11
12 <section>
13 <title>Querying Capabilities</title>
14
15 <para>Devices supporting the radio interface set the
16<constant>V4L2_CAP_RADIO</constant> and
17<constant>V4L2_CAP_TUNER</constant> or
18<constant>V4L2_CAP_MODULATOR</constant> flag in the
19<structfield>capabilities</structfield> field of &v4l2-capability;
20returned by the &VIDIOC-QUERYCAP; ioctl. Other combinations of
21capability flags are reserved for future extensions.</para>
22 </section>
23
24 <section>
25 <title>Supplemental Functions</title>
26
27 <para>Radio devices can support <link
28linkend="control">controls</link>, and must support the <link
29linkend="tuner">tuner or modulator</link> ioctls.</para>
30
31 <para>They do not support the video input or output, audio input
32or output, video standard, cropping and scaling, compression and
33streaming parameter, or overlay ioctls. All other ioctls and I/O
34methods are reserved for future extensions.</para>
35 </section>
36
37 <section>
38 <title>Programming</title>
39
40 <para>Radio devices may have a couple audio controls (as discussed
41in <xref linkend="control" />) such as a volume control, possibly custom
42controls. Further all radio devices have one tuner or modulator (these are
43discussed in <xref linkend="tuner" />) with index number zero to select
44the radio frequency and to determine if a monaural or FM stereo
45program is received/emitted. Drivers switch automatically between AM and FM
46depending on the selected frequency. The &VIDIOC-G-TUNER; or
47&VIDIOC-G-MODULATOR; ioctl
48reports the supported frequency range.</para>
49 </section>
50
51<!--
52Local Variables:
53mode: sgml
54sgml-parent-document: "v4l2.sgml"
55indent-tabs-mode: nil
56End:
57 -->
diff --git a/Documentation/DocBook/v4l/dev-raw-vbi.xml b/Documentation/DocBook/v4l/dev-raw-vbi.xml
new file mode 100644
index 000000000000..c5a70bdfaf27
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-raw-vbi.xml
@@ -0,0 +1,347 @@
1 <title>Raw VBI Data Interface</title>
2
3 <para>VBI is an abbreviation of Vertical Blanking Interval, a gap
4in the sequence of lines of an analog video signal. During VBI
5no picture information is transmitted, allowing some time while the
6electron beam of a cathode ray tube TV returns to the top of the
7screen. Using an oscilloscope you will find here the vertical
8synchronization pulses and short data packages ASK
9modulated<footnote><para>ASK: Amplitude-Shift Keying. A high signal
10level represents a '1' bit, a low level a '0' bit.</para></footnote>
11onto the video signal. These are transmissions of services such as
12Teletext or Closed Caption.</para>
13
14 <para>Subject of this interface type is raw VBI data, as sampled off
15a video signal, or to be added to a signal for output.
16The data format is similar to uncompressed video images, a number of
17lines times a number of samples per line, we call this a VBI image.</para>
18
19 <para>Conventionally V4L2 VBI devices are accessed through character
20device special files named <filename>/dev/vbi</filename> and
21<filename>/dev/vbi0</filename> to <filename>/dev/vbi31</filename> with
22major number 81 and minor numbers 224 to 255.
23<filename>/dev/vbi</filename> is typically a symbolic link to the
24preferred VBI device. This convention applies to both input and output
25devices.</para>
26
27 <para>To address the problems of finding related video and VBI
28devices VBI capturing and output is also available as device function
29under <filename>/dev/video</filename>. To capture or output raw VBI
30data with these devices applications must call the &VIDIOC-S-FMT;
31ioctl. Accessed as <filename>/dev/vbi</filename>, raw VBI capturing
32or output is the default device function.</para>
33
34 <section>
35 <title>Querying Capabilities</title>
36
37 <para>Devices supporting the raw VBI capturing or output API set
38the <constant>V4L2_CAP_VBI_CAPTURE</constant> or
39<constant>V4L2_CAP_VBI_OUTPUT</constant> flags, respectively, in the
40<structfield>capabilities</structfield> field of &v4l2-capability;
41returned by the &VIDIOC-QUERYCAP; ioctl. At least one of the
42read/write, streaming or asynchronous I/O methods must be
43supported. VBI devices may or may not have a tuner or modulator.</para>
44 </section>
45
46 <section>
47 <title>Supplemental Functions</title>
48
49 <para>VBI devices shall support <link linkend="video">video
50input or output</link>, <link linkend="tuner">tuner or
51modulator</link>, and <link linkend="control">controls</link> ioctls
52as needed. The <link linkend="standard">video standard</link> ioctls provide
53information vital to program a VBI device, therefore must be
54supported.</para>
55 </section>
56
57 <section>
58 <title>Raw VBI Format Negotiation</title>
59
60 <para>Raw VBI sampling abilities can vary, in particular the
61sampling frequency. To properly interpret the data V4L2 specifies an
62ioctl to query the sampling parameters. Moreover, to allow for some
63flexibility applications can also suggest different parameters.</para>
64
65 <para>As usual these parameters are <emphasis>not</emphasis>
66reset at &func-open; time to permit Unix tool chains, programming a
67device and then reading from it as if it was a plain file. Well
68written V4L2 applications should always ensure they really get what
69they want, requesting reasonable parameters and then checking if the
70actual parameters are suitable.</para>
71
72 <para>To query the current raw VBI capture parameters
73applications set the <structfield>type</structfield> field of a
74&v4l2-format; to <constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant> or
75<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>, and call the
76&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
77the &v4l2-vbi-format; <structfield>vbi</structfield> member of the
78<structfield>fmt</structfield> union.</para>
79
80 <para>To request different parameters applications set the
81<structfield>type</structfield> field of a &v4l2-format; as above and
82initialize all fields of the &v4l2-vbi-format;
83<structfield>vbi</structfield> member of the
84<structfield>fmt</structfield> union, or better just modify the
85results of <constant>VIDIOC_G_FMT</constant>, and call the
86&VIDIOC-S-FMT; ioctl with a pointer to this structure. Drivers return
87an &EINVAL; only when the given parameters are ambiguous, otherwise
88they modify the parameters according to the hardware capabilites and
89return the actual parameters. When the driver allocates resources at
90this point, it may return an &EBUSY; to indicate the returned
91parameters are valid but the required resources are currently not
92available. That may happen for instance when the video and VBI areas
93to capture would overlap, or when the driver supports multiple opens
94and another process already requested VBI capturing or output. Anyway,
95applications must expect other resource allocation points which may
96return <errorcode>EBUSY</errorcode>, at the &VIDIOC-STREAMON; ioctl
97and the first read(), write() and select() call.</para>
98
99 <para>VBI devices must implement both the
100<constant>VIDIOC_G_FMT</constant> and
101<constant>VIDIOC_S_FMT</constant> ioctl, even if
102<constant>VIDIOC_S_FMT</constant> ignores all requests and always
103returns default parameters as <constant>VIDIOC_G_FMT</constant> does.
104<constant>VIDIOC_TRY_FMT</constant> is optional.</para>
105
106 <table pgwide="1" frame="none" id="v4l2-vbi-format">
107 <title>struct <structname>v4l2_vbi_format</structname></title>
108 <tgroup cols="3">
109 &cs-str;
110 <tbody valign="top">
111 <row>
112 <entry>__u32</entry>
113 <entry><structfield>sampling_rate</structfield></entry>
114 <entry>Samples per second, i.&nbsp;e. unit 1 Hz.</entry>
115 </row>
116 <row>
117 <entry>__u32</entry>
118 <entry><structfield>offset</structfield></entry>
119 <entry><para>Horizontal offset of the VBI image,
120relative to the leading edge of the line synchronization pulse and
121counted in samples: The first sample in the VBI image will be located
122<structfield>offset</structfield> /
123<structfield>sampling_rate</structfield> seconds following the leading
124edge. See also <xref linkend="vbi-hsync" />.</para></entry>
125 </row>
126 <row>
127 <entry>__u32</entry>
128 <entry><structfield>samples_per_line</structfield></entry>
129 <entry></entry>
130 </row>
131 <row>
132 <entry>__u32</entry>
133 <entry><structfield>sample_format</structfield></entry>
134 <entry><para>Defines the sample format as in <xref
135linkend="pixfmt" />, a four-character-code.<footnote>
136 <para>A few devices may be unable to
137sample VBI data at all but can extend the video capture window to the
138VBI region.</para>
139 </footnote> Usually this is
140<constant>V4L2_PIX_FMT_GREY</constant>, i.&nbsp;e. each sample
141consists of 8 bits with lower values oriented towards the black level.
142Do not assume any other correlation of values with the signal level.
143For example, the MSB does not necessarily indicate if the signal is
144'high' or 'low' because 128 may not be the mean value of the
145signal. Drivers shall not convert the sample format by software.</para></entry>
146 </row>
147 <row>
148 <entry>__u32</entry>
149 <entry><structfield>start</structfield>[2]</entry>
150 <entry>This is the scanning system line number
151associated with the first line of the VBI image, of the first and the
152second field respectively. See <xref linkend="vbi-525" /> and
153<xref linkend="vbi-625" /> for valid values. VBI input drivers can
154return start values 0 if the hardware cannot reliable identify
155scanning lines, VBI acquisition may not require this
156information.</entry>
157 </row>
158 <row>
159 <entry>__u32</entry>
160 <entry><structfield>count</structfield>[2]</entry>
161 <entry>The number of lines in the first and second
162field image, respectively.</entry>
163 </row>
164 <row>
165 <entry spanname="hspan"><para>Drivers should be as
166flexibility as possible. For example, it may be possible to extend or
167move the VBI capture window down to the picture area, implementing a
168'full field mode' to capture data service transmissions embedded in
169the picture.</para><para>An application can set the first or second
170<structfield>count</structfield> value to zero if no data is required
171from the respective field; <structfield>count</structfield>[1] if the
172scanning system is progressive, &ie; not interlaced. The
173corresponding start value shall be ignored by the application and
174driver. Anyway, drivers may not support single field capturing and
175return both count values non-zero.</para><para>Both
176<structfield>count</structfield> values set to zero, or line numbers
177outside the bounds depicted in <xref linkend="vbi-525" /> and <xref
178 linkend="vbi-625" />, or a field image covering
179lines of two fields, are invalid and shall not be returned by the
180driver.</para><para>To initialize the <structfield>start</structfield>
181and <structfield>count</structfield> fields, applications must first
182determine the current video standard selection. The &v4l2-std-id; or
183the <structfield>framelines</structfield> field of &v4l2-standard; can
184be evaluated for this purpose.</para></entry>
185 </row>
186 <row>
187 <entry>__u32</entry>
188 <entry><structfield>flags</structfield></entry>
189 <entry>See <xref linkend="vbifmt-flags" /> below. Currently
190only drivers set flags, applications must set this field to
191zero.</entry>
192 </row>
193 <row>
194 <entry>__u32</entry>
195 <entry><structfield>reserved</structfield>[2]</entry>
196 <entry>This array is reserved for future extensions.
197Drivers and applications must set it to zero.</entry>
198 </row>
199 </tbody>
200 </tgroup>
201 </table>
202
203 <table pgwide="1" frame="none" id="vbifmt-flags">
204 <title>Raw VBI Format Flags</title>
205 <tgroup cols="3">
206 &cs-def;
207 <tbody valign="top">
208 <row>
209 <entry><constant>V4L2_VBI_UNSYNC</constant></entry>
210 <entry>0x0001</entry>
211 <entry><para>This flag indicates hardware which does not
212properly distinguish between fields. Normally the VBI image stores the
213first field (lower scanning line numbers) first in memory. This may be
214a top or bottom field depending on the video standard. When this flag
215is set the first or second field may be stored first, however the
216fields are still in correct temporal order with the older field first
217in memory.<footnote>
218 <para>Most VBI services transmit on both fields, but
219some have different semantics depending on the field number. These
220cannot be reliable decoded or encoded when
221<constant>V4L2_VBI_UNSYNC</constant> is set.</para>
222 </footnote></para></entry>
223 </row>
224 <row>
225 <entry><constant>V4L2_VBI_INTERLACED</constant></entry>
226 <entry>0x0002</entry>
227 <entry>By default the two field images will be passed
228sequentially; all lines of the first field followed by all lines of
229the second field (compare <xref linkend="field-order" />
230<constant>V4L2_FIELD_SEQ_TB</constant> and
231<constant>V4L2_FIELD_SEQ_BT</constant>, whether the top or bottom
232field is first in memory depends on the video standard). When this
233flag is set, the two fields are interlaced (cf.
234<constant>V4L2_FIELD_INTERLACED</constant>). The first line of the
235first field followed by the first line of the second field, then the
236two second lines, and so on. Such a layout may be necessary when the
237hardware has been programmed to capture or output interlaced video
238images and is unable to separate the fields for VBI capturing at
239the same time. For simplicity setting this flag implies that both
240<structfield>count</structfield> values are equal and non-zero.</entry>
241 </row>
242 </tbody>
243 </tgroup>
244 </table>
245
246 <figure id="vbi-hsync">
247 <title>Line synchronization</title>
248 <mediaobject>
249 <imageobject>
250 <imagedata fileref="vbi_hsync.pdf" format="PS" />
251 </imageobject>
252 <imageobject>
253 <imagedata fileref="vbi_hsync.gif" format="GIF" />
254 </imageobject>
255 <textobject>
256 <phrase>Line synchronization diagram</phrase>
257 </textobject>
258 </mediaobject>
259 </figure>
260
261 <figure id="vbi-525">
262 <title>ITU-R 525 line numbering (M/NTSC and M/PAL)</title>
263 <mediaobject>
264 <imageobject>
265 <imagedata fileref="vbi_525.pdf" format="PS" />
266 </imageobject>
267 <imageobject>
268 <imagedata fileref="vbi_525.gif" format="GIF" />
269 </imageobject>
270 <textobject>
271 <phrase>NTSC field synchronization diagram</phrase>
272 </textobject>
273 <caption>
274 <para>(1) For the purpose of this specification field 2
275starts in line 264 and not 263.5 because half line capturing is not
276supported.</para>
277 </caption>
278 </mediaobject>
279 </figure>
280
281 <figure id="vbi-625">
282 <title>ITU-R 625 line numbering</title>
283 <mediaobject>
284 <imageobject>
285 <imagedata fileref="vbi_625.pdf" format="PS" />
286 </imageobject>
287 <imageobject>
288 <imagedata fileref="vbi_625.gif" format="GIF" />
289 </imageobject>
290 <textobject>
291 <phrase>PAL/SECAM field synchronization diagram</phrase>
292 </textobject>
293 <caption>
294 <para>(1) For the purpose of this specification field 2
295starts in line 314 and not 313.5 because half line capturing is not
296supported.</para>
297 </caption>
298 </mediaobject>
299 </figure>
300
301 <para>Remember the VBI image format depends on the selected
302video standard, therefore the application must choose a new standard or
303query the current standard first. Attempts to read or write data ahead
304of format negotiation, or after switching the video standard which may
305invalidate the negotiated VBI parameters, should be refused by the
306driver. A format change during active I/O is not permitted.</para>
307 </section>
308
309 <section>
310 <title>Reading and writing VBI images</title>
311
312 <para>To assure synchronization with the field number and easier
313implementation, the smallest unit of data passed at a time is one
314frame, consisting of two fields of VBI images immediately following in
315memory.</para>
316
317 <para>The total size of a frame computes as follows:</para>
318
319 <programlisting>
320(<structfield>count</structfield>[0] + <structfield>count</structfield>[1]) *
321<structfield>samples_per_line</structfield> * sample size in bytes</programlisting>
322
323 <para>The sample size is most likely always one byte,
324applications must check the <structfield>sample_format</structfield>
325field though, to function properly with other drivers.</para>
326
327 <para>A VBI device may support <link
328 linkend="rw">read/write</link> and/or streaming (<link
329 linkend="mmap">memory mapping</link> or <link
330 linkend="userp">user pointer</link>) I/O. The latter bears the
331possibility of synchronizing video and
332VBI data by using buffer timestamps.</para>
333
334 <para>Remember the &VIDIOC-STREAMON; ioctl and the first read(),
335write() and select() call can be resource allocation points returning
336an &EBUSY; if the required hardware resources are temporarily
337unavailable, for example the device is already in use by another
338process.</para>
339 </section>
340
341 <!--
342Local Variables:
343mode: sgml
344sgml-parent-document: "v4l2.sgml"
345indent-tabs-mode: nil
346End:
347 -->
diff --git a/Documentation/DocBook/v4l/dev-rds.xml b/Documentation/DocBook/v4l/dev-rds.xml
new file mode 100644
index 000000000000..0869d701b1e5
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-rds.xml
@@ -0,0 +1,168 @@
1 <title>RDS Interface</title>
2
3 <para>The Radio Data System transmits supplementary
4information in binary format, for example the station name or travel
5information, on an inaudible audio subcarrier of a radio program. This
6interface is aimed at devices capable of receiving and decoding RDS
7information.</para>
8
9 <para>For more information see the core RDS standard <xref linkend="en50067" />
10and the RBDS standard <xref linkend="nrsc4" />.</para>
11
12 <para>Note that the RBDS standard as is used in the USA is almost identical
13to the RDS standard. Any RDS decoder can also handle RBDS. Only some of the fields
14have slightly different meanings. See the RBDS standard for more information.</para>
15
16 <para>The RBDS standard also specifies support for MMBS (Modified Mobile Search).
17This is a proprietary format which seems to be discontinued. The RDS interface does not
18support this format. Should support for MMBS (or the so-called 'E blocks' in general)
19be needed, then please contact the linux-media mailing list: &v4l-ml;.</para>
20
21 <section>
22 <title>Querying Capabilities</title>
23
24 <para>Devices supporting the RDS capturing API
25set the <constant>V4L2_CAP_RDS_CAPTURE</constant> flag in
26the <structfield>capabilities</structfield> field of &v4l2-capability;
27returned by the &VIDIOC-QUERYCAP; ioctl.
28Any tuner that supports RDS will set the
29<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
30field of &v4l2-tuner;.
31Whether an RDS signal is present can be detected by looking at
32the <structfield>rxsubchans</structfield> field of &v4l2-tuner;: the
33<constant>V4L2_TUNER_SUB_RDS</constant> will be set if RDS data was detected.</para>
34
35 <para>Devices supporting the RDS output API
36set the <constant>V4L2_CAP_RDS_OUTPUT</constant> flag in
37the <structfield>capabilities</structfield> field of &v4l2-capability;
38returned by the &VIDIOC-QUERYCAP; ioctl.
39Any modulator that supports RDS will set the
40<constant>V4L2_TUNER_CAP_RDS</constant> flag in the <structfield>capability</structfield>
41field of &v4l2-modulator;.
42In order to enable the RDS transmission one must set the <constant>V4L2_TUNER_SUB_RDS</constant>
43bit in the <structfield>txsubchans</structfield> field of &v4l2-modulator;.</para>
44
45 </section>
46
47 <section>
48 <title>Reading RDS data</title>
49
50 <para>RDS data can be read from the radio device
51with the &func-read; function. The data is packed in groups of three bytes,
52as follows:</para>
53 <table frame="none" pgwide="1" id="v4l2-rds-data">
54 <title>struct
55<structname>v4l2_rds_data</structname></title>
56 <tgroup cols="3">
57 <colspec colname="c1" colwidth="1*" />
58 <colspec colname="c2" colwidth="1*" />
59 <colspec colname="c3" colwidth="5*" />
60 <tbody valign="top">
61 <row>
62 <entry>__u8</entry>
63 <entry><structfield>lsb</structfield></entry>
64 <entry>Least Significant Byte of RDS Block</entry>
65 </row>
66 <row>
67 <entry>__u8</entry>
68 <entry><structfield>msb</structfield></entry>
69 <entry>Most Significant Byte of RDS Block</entry>
70 </row>
71 <row>
72 <entry>__u8</entry>
73 <entry><structfield>block</structfield></entry>
74 <entry>Block description</entry>
75 </row>
76 </tbody>
77 </tgroup>
78 </table>
79 <table frame="none" pgwide="1" id="v4l2-rds-block">
80 <title>Block description</title>
81 <tgroup cols="2">
82 <colspec colname="c1" colwidth="1*" />
83 <colspec colname="c2" colwidth="5*" />
84 <tbody valign="top">
85 <row>
86 <entry>Bits 0-2</entry>
87 <entry>Block (aka offset) of the received data.</entry>
88 </row>
89 <row>
90 <entry>Bits 3-5</entry>
91 <entry>Deprecated. Currently identical to bits 0-2. Do not use these bits.</entry>
92 </row>
93 <row>
94 <entry>Bit 6</entry>
95 <entry>Corrected bit. Indicates that an error was corrected for this data block.</entry>
96 </row>
97 <row>
98 <entry>Bit 7</entry>
99 <entry>Error bit. Indicates that an uncorrectable error occurred during reception of this block.</entry>
100 </row>
101 </tbody>
102 </tgroup>
103 </table>
104
105 <table frame="none" pgwide="1" id="v4l2-rds-block-codes">
106 <title>Block defines</title>
107 <tgroup cols="3">
108 <colspec colname="c1" colwidth="1*" />
109 <colspec colname="c2" colwidth="1*" />
110 <colspec colname="c3" colwidth="5*" />
111 <tbody valign="top">
112 <row>
113 <entry>V4L2_RDS_BLOCK_MSK</entry>
114 <entry>7</entry>
115 <entry>Mask for bits 0-2 to get the block ID.</entry>
116 </row>
117 <row>
118 <entry>V4L2_RDS_BLOCK_A</entry>
119 <entry>0</entry>
120 <entry>Block A.</entry>
121 </row>
122 <row>
123 <entry>V4L2_RDS_BLOCK_B</entry>
124 <entry>1</entry>
125 <entry>Block B.</entry>
126 </row>
127 <row>
128 <entry>V4L2_RDS_BLOCK_C</entry>
129 <entry>2</entry>
130 <entry>Block C.</entry>
131 </row>
132 <row>
133 <entry>V4L2_RDS_BLOCK_D</entry>
134 <entry>3</entry>
135 <entry>Block D.</entry>
136 </row>
137 <row>
138 <entry>V4L2_RDS_BLOCK_C_ALT</entry>
139 <entry>4</entry>
140 <entry>Block C'.</entry>
141 </row>
142 <row>
143 <entry>V4L2_RDS_BLOCK_INVALID</entry>
144 <entry>7</entry>
145 <entry>An invalid block.</entry>
146 </row>
147 <row>
148 <entry>V4L2_RDS_BLOCK_CORRECTED</entry>
149 <entry>0x40</entry>
150 <entry>A bit error was detected but corrected.</entry>
151 </row>
152 <row>
153 <entry>V4L2_RDS_BLOCK_ERROR</entry>
154 <entry>0x80</entry>
155 <entry>An incorrectable error occurred.</entry>
156 </row>
157 </tbody>
158 </tgroup>
159 </table>
160 </section>
161
162<!--
163Local Variables:
164mode: sgml
165sgml-parent-document: "v4l2.sgml"
166indent-tabs-mode: nil
167End:
168 -->
diff --git a/Documentation/DocBook/v4l/dev-sliced-vbi.xml b/Documentation/DocBook/v4l/dev-sliced-vbi.xml
new file mode 100644
index 000000000000..69e789fa7f7b
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-sliced-vbi.xml
@@ -0,0 +1,708 @@
1 <title>Sliced VBI Data Interface</title>
2
3 <para>VBI stands for Vertical Blanking Interval, a gap in the
4sequence of lines of an analog video signal. During VBI no picture
5information is transmitted, allowing some time while the electron beam
6of a cathode ray tube TV returns to the top of the screen.</para>
7
8 <para>Sliced VBI devices use hardware to demodulate data transmitted
9in the VBI. V4L2 drivers shall <emphasis>not</emphasis> do this by
10software, see also the <link linkend="raw-vbi">raw VBI
11interface</link>. The data is passed as short packets of fixed size,
12covering one scan line each. The number of packets per video frame is
13variable.</para>
14
15 <para>Sliced VBI capture and output devices are accessed through the
16same character special files as raw VBI devices. When a driver
17supports both interfaces, the default function of a
18<filename>/dev/vbi</filename> device is <emphasis>raw</emphasis> VBI
19capturing or output, and the sliced VBI function is only available
20after calling the &VIDIOC-S-FMT; ioctl as defined below. Likewise a
21<filename>/dev/video</filename> device may support the sliced VBI API,
22however the default function here is video capturing or output.
23Different file descriptors must be used to pass raw and sliced VBI
24data simultaneously, if this is supported by the driver.</para>
25
26 <section>
27 <title>Querying Capabilities</title>
28
29 <para>Devices supporting the sliced VBI capturing or output API
30set the <constant>V4L2_CAP_SLICED_VBI_CAPTURE</constant> or
31<constant>V4L2_CAP_SLICED_VBI_OUTPUT</constant> flag respectively, in
32the <structfield>capabilities</structfield> field of &v4l2-capability;
33returned by the &VIDIOC-QUERYCAP; ioctl. At least one of the
34read/write, streaming or asynchronous <link linkend="io">I/O
35methods</link> must be supported. Sliced VBI devices may have a tuner
36or modulator.</para>
37 </section>
38
39 <section>
40 <title>Supplemental Functions</title>
41
42 <para>Sliced VBI devices shall support <link linkend="video">video
43input or output</link> and <link linkend="tuner">tuner or
44modulator</link> ioctls if they have these capabilities, and they may
45support <link linkend="control">control</link> ioctls. The <link
46linkend="standard">video standard</link> ioctls provide information
47vital to program a sliced VBI device, therefore must be
48supported.</para>
49 </section>
50
51 <section id="sliced-vbi-format-negotitation">
52 <title>Sliced VBI Format Negotiation</title>
53
54 <para>To find out which data services are supported by the
55hardware applications can call the &VIDIOC-G-SLICED-VBI-CAP; ioctl.
56All drivers implementing the sliced VBI interface must support this
57ioctl. The results may differ from those of the &VIDIOC-S-FMT; ioctl
58when the number of VBI lines the hardware can capture or output per
59frame, or the number of services it can identify on a given line are
60limited. For example on PAL line 16 the hardware may be able to look
61for a VPS or Teletext signal, but not both at the same time.</para>
62
63 <para>To determine the currently selected services applications
64set the <structfield>type </structfield> field of &v4l2-format; to
65<constant> V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> or <constant>
66V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant>, and the &VIDIOC-G-FMT;
67ioctl fills the <structfield>fmt.sliced</structfield> member, a
68&v4l2-sliced-vbi-format;.</para>
69
70 <para>Applications can request different parameters by
71initializing or modifying the <structfield>fmt.sliced</structfield>
72member and calling the &VIDIOC-S-FMT; ioctl with a pointer to the
73<structname>v4l2_format</structname> structure.</para>
74
75 <para>The sliced VBI API is more complicated than the raw VBI API
76because the hardware must be told which VBI service to expect on each
77scan line. Not all services may be supported by the hardware on all
78lines (this is especially true for VBI output where Teletext is often
79unsupported and other services can only be inserted in one specific
80line). In many cases, however, it is sufficient to just set the
81<structfield>service_set</structfield> field to the required services
82and let the driver fill the <structfield>service_lines</structfield>
83array according to hardware capabilities. Only if more precise control
84is needed should the programmer set the
85<structfield>service_lines</structfield> array explicitly.</para>
86
87 <para>The &VIDIOC-S-FMT; ioctl modifies the parameters
88according to hardware capabilities. When the driver allocates
89resources at this point, it may return an &EBUSY; if the required
90resources are temporarily unavailable. Other resource allocation
91points which may return <errorcode>EBUSY</errorcode> can be the
92&VIDIOC-STREAMON; ioctl and the first &func-read;, &func-write; and
93&func-select; call.</para>
94
95 <table frame="none" pgwide="1" id="v4l2-sliced-vbi-format">
96 <title>struct
97<structname>v4l2_sliced_vbi_format</structname></title>
98 <tgroup cols="5">
99 <colspec colname="c1" colwidth="3*" />
100 <colspec colname="c2" colwidth="3*" />
101 <colspec colname="c3" colwidth="2*" />
102 <colspec colname="c4" colwidth="2*" />
103 <colspec colname="c5" colwidth="2*" />
104 <spanspec namest="c3" nameend="c5" spanname="hspan" />
105 <tbody valign="top">
106 <row>
107 <entry>__u32</entry>
108 <entry><structfield>service_set</structfield></entry>
109 <entry spanname="hspan"><para>If
110<structfield>service_set</structfield> is non-zero when passed with
111&VIDIOC-S-FMT; or &VIDIOC-TRY-FMT;, the
112<structfield>service_lines</structfield> array will be filled by the
113driver according to the services specified in this field. For example,
114if <structfield>service_set</structfield> is initialized with
115<constant>V4L2_SLICED_TELETEXT_B | V4L2_SLICED_WSS_625</constant>, a
116driver for the cx25840 video decoder sets lines 7-22 of both
117fields<footnote><para>According to <link
118linkend="ets300706">ETS&nbsp;300&nbsp;706</link> lines 6-22 of the
119first field and lines 5-22 of the second field may carry Teletext
120data.</para></footnote> to <constant>V4L2_SLICED_TELETEXT_B</constant>
121and line 23 of the first field to
122<constant>V4L2_SLICED_WSS_625</constant>. If
123<structfield>service_set</structfield> is set to zero, then the values
124of <structfield>service_lines</structfield> will be used instead.
125</para><para>On return the driver sets this field to the union of all
126elements of the returned <structfield>service_lines</structfield>
127array. It may contain less services than requested, perhaps just one,
128if the hardware cannot handle more services simultaneously. It may be
129empty (zero) if none of the requested services are supported by the
130hardware.</para></entry>
131 </row>
132 <row>
133 <entry>__u16</entry>
134 <entry><structfield>service_lines</structfield>[2][24]</entry>
135 <entry spanname="hspan"><para>Applications initialize this
136array with sets of data services the driver shall look for or insert
137on the respective scan line. Subject to hardware capabilities drivers
138return the requested set, a subset, which may be just a single
139service, or an empty set. When the hardware cannot handle multiple
140services on the same line the driver shall choose one. No assumptions
141can be made on which service the driver chooses.</para><para>Data
142services are defined in <xref linkend="vbi-services2" />. Array indices
143map to ITU-R line numbers (see also <xref linkend="vbi-525" /> and <xref
144 linkend="vbi-625" />) as follows: <!-- No nested
145tables, sigh. --></para></entry>
146 </row>
147 <row>
148 <entry></entry>
149 <entry></entry>
150 <entry>Element</entry>
151 <entry>525 line systems</entry>
152 <entry>625 line systems</entry>
153 </row>
154 <row>
155 <entry></entry>
156 <entry></entry>
157 <entry><structfield>service_lines</structfield>[0][1]</entry>
158 <entry align="center">1</entry>
159 <entry align="center">1</entry>
160 </row>
161 <row>
162 <entry></entry>
163 <entry></entry>
164 <entry><structfield>service_lines</structfield>[0][23]</entry>
165 <entry align="center">23</entry>
166 <entry align="center">23</entry>
167 </row>
168 <row>
169 <entry></entry>
170 <entry></entry>
171 <entry><structfield>service_lines</structfield>[1][1]</entry>
172 <entry align="center">264</entry>
173 <entry align="center">314</entry>
174 </row>
175 <row>
176 <entry></entry>
177 <entry></entry>
178 <entry><structfield>service_lines</structfield>[1][23]</entry>
179 <entry align="center">286</entry>
180 <entry align="center">336</entry>
181 </row>
182 <!-- End of line numbers table. -->
183 <row>
184 <entry></entry>
185 <entry></entry>
186 <entry spanname="hspan">Drivers must set
187<structfield>service_lines</structfield>[0][0] and
188<structfield>service_lines</structfield>[1][0] to zero.</entry>
189 </row>
190 <row>
191 <entry>__u32</entry>
192 <entry><structfield>io_size</structfield></entry>
193 <entry spanname="hspan">Maximum number of bytes passed by
194one &func-read; or &func-write; call, and the buffer size in bytes for
195the &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. Drivers set this field to
196the size of &v4l2-sliced-vbi-data; times the number of non-zero
197elements in the returned <structfield>service_lines</structfield>
198array (that is the number of lines potentially carrying data).</entry>
199 </row>
200 <row>
201 <entry>__u32</entry>
202 <entry><structfield>reserved</structfield>[2]</entry>
203 <entry spanname="hspan">This array is reserved for future
204extensions. Applications and drivers must set it to zero.</entry>
205 </row>
206 </tbody>
207 </tgroup>
208 </table>
209
210 <!-- See also vidioc-g-sliced-vbi-cap.sgml -->
211 <table frame="none" pgwide="1" id="vbi-services2">
212 <title>Sliced VBI services</title>
213 <tgroup cols="5">
214 <colspec colname="c1" colwidth="2*" />
215 <colspec colname="c2" colwidth="1*" />
216 <colspec colname="c3" colwidth="1*" />
217 <colspec colname="c4" colwidth="2*" />
218 <colspec colname="c5" colwidth="2*" />
219 <spanspec namest="c3" nameend="c5" spanname="rlp" />
220 <thead>
221 <row>
222 <entry>Symbol</entry>
223 <entry>Value</entry>
224 <entry>Reference</entry>
225 <entry>Lines, usually</entry>
226 <entry>Payload</entry>
227 </row>
228 </thead>
229 <tbody valign="top">
230 <row>
231 <entry><constant>V4L2_SLICED_TELETEXT_B</constant>
232(Teletext System B)</entry>
233 <entry>0x0001</entry>
234 <entry><xref linkend="ets300706" />, <xref linkend="itu653" /></entry>
235 <entry>PAL/SECAM line 7-22, 320-335 (second field 7-22)</entry>
236 <entry>Last 42 of the 45 byte Teletext packet, that is
237without clock run-in and framing code, lsb first transmitted.</entry>
238 </row>
239 <row>
240 <entry><constant>V4L2_SLICED_VPS</constant></entry>
241 <entry>0x0400</entry>
242 <entry><xref linkend="ets300231" /></entry>
243 <entry>PAL line 16</entry>
244 <entry>Byte number 3 to 15 according to Figure 9 of
245ETS&nbsp;300&nbsp;231, lsb first transmitted.</entry>
246 </row>
247 <row>
248 <entry><constant>V4L2_SLICED_CAPTION_525</constant></entry>
249 <entry>0x1000</entry>
250 <entry><xref linkend="eia608" /></entry>
251 <entry>NTSC line 21, 284 (second field 21)</entry>
252 <entry>Two bytes in transmission order, including parity
253bit, lsb first transmitted.</entry>
254 </row>
255 <row>
256 <entry><constant>V4L2_SLICED_WSS_625</constant></entry>
257 <entry>0x4000</entry>
258 <entry><xref linkend="itu1119" />, <xref linkend="en300294" /></entry>
259 <entry>PAL/SECAM line 23</entry>
260 <entry><screen>
261Byte 0 1
262 msb lsb msb lsb
263 Bit 7 6 5 4 3 2 1 0 x x 13 12 11 10 9
264</screen></entry>
265 </row>
266 <row>
267 <entry><constant>V4L2_SLICED_VBI_525</constant></entry>
268 <entry>0x1000</entry>
269 <entry spanname="rlp">Set of services applicable to 525
270line systems.</entry>
271 </row>
272 <row>
273 <entry><constant>V4L2_SLICED_VBI_625</constant></entry>
274 <entry>0x4401</entry>
275 <entry spanname="rlp">Set of services applicable to 625
276line systems.</entry>
277 </row>
278 </tbody>
279 </tgroup>
280 </table>
281
282 <para>Drivers may return an &EINVAL; when applications attempt to
283read or write data without prior format negotiation, after switching
284the video standard (which may invalidate the negotiated VBI
285parameters) and after switching the video input (which may change the
286video standard as a side effect). The &VIDIOC-S-FMT; ioctl may return
287an &EBUSY; when applications attempt to change the format while i/o is
288in progress (between a &VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; call,
289and after the first &func-read; or &func-write; call).</para>
290 </section>
291
292 <section>
293 <title>Reading and writing sliced VBI data</title>
294
295 <para>A single &func-read; or &func-write; call must pass all data
296belonging to one video frame. That is an array of
297<structname>v4l2_sliced_vbi_data</structname> structures with one or
298more elements and a total size not exceeding
299<structfield>io_size</structfield> bytes. Likewise in streaming I/O
300mode one buffer of <structfield>io_size</structfield> bytes must
301contain data of one video frame. The <structfield>id</structfield> of
302unused <structname>v4l2_sliced_vbi_data</structname> elements must be
303zero.</para>
304
305 <table frame="none" pgwide="1" id="v4l2-sliced-vbi-data">
306 <title>struct
307<structname>v4l2_sliced_vbi_data</structname></title>
308 <tgroup cols="3">
309 &cs-def;
310 <tbody valign="top">
311 <row>
312 <entry>__u32</entry>
313 <entry><structfield>id</structfield></entry>
314 <entry>A flag from <xref linkend="vbi-services" />
315identifying the type of data in this packet. Only a single bit must be
316set. When the <structfield>id</structfield> of a captured packet is
317zero, the packet is empty and the contents of other fields are
318undefined. Applications shall ignore empty packets. When the
319<structfield>id</structfield> of a packet for output is zero the
320contents of the <structfield>data</structfield> field are undefined
321and the driver must no longer insert data on the requested
322<structfield>field</structfield> and
323<structfield>line</structfield>.</entry>
324 </row>
325 <row>
326 <entry>__u32</entry>
327 <entry><structfield>field</structfield></entry>
328 <entry>The video field number this data has been captured
329from, or shall be inserted at. <constant>0</constant> for the first
330field, <constant>1</constant> for the second field.</entry>
331 </row>
332 <row>
333 <entry>__u32</entry>
334 <entry><structfield>line</structfield></entry>
335 <entry>The field (as opposed to frame) line number this
336data has been captured from, or shall be inserted at. See <xref
337 linkend="vbi-525" /> and <xref linkend="vbi-625" /> for valid
338values. Sliced VBI capture devices can set the line number of all
339packets to <constant>0</constant> if the hardware cannot reliably
340identify scan lines. The field number must always be valid.</entry>
341 </row>
342 <row>
343 <entry>__u32</entry>
344 <entry><structfield>reserved</structfield></entry>
345 <entry>This field is reserved for future extensions.
346Applications and drivers must set it to zero.</entry>
347 </row>
348 <row>
349 <entry>__u8</entry>
350 <entry><structfield>data</structfield>[48]</entry>
351 <entry>The packet payload. See <xref
352 linkend="vbi-services" /> for the contents and number of
353bytes passed for each data type. The contents of padding bytes at the
354end of this array are undefined, drivers and applications shall ignore
355them.</entry>
356 </row>
357 </tbody>
358 </tgroup>
359 </table>
360
361 <para>Packets are always passed in ascending line number order,
362without duplicate line numbers. The &func-write; function and the
363&VIDIOC-QBUF; ioctl must return an &EINVAL; when applications violate
364this rule. They must also return an &EINVAL; when applications pass an
365incorrect field or line number, or a combination of
366<structfield>field</structfield>, <structfield>line</structfield> and
367<structfield>id</structfield> which has not been negotiated with the
368&VIDIOC-G-FMT; or &VIDIOC-S-FMT; ioctl. When the line numbers are
369unknown the driver must pass the packets in transmitted order. The
370driver can insert empty packets with <structfield>id</structfield> set
371to zero anywhere in the packet array.</para>
372
373 <para>To assure synchronization and to distinguish from frame
374dropping, when a captured frame does not carry any of the requested
375data services drivers must pass one or more empty packets. When an
376application fails to pass VBI data in time for output, the driver
377must output the last VPS and WSS packet again, and disable the output
378of Closed Caption and Teletext data, or output data which is ignored
379by Closed Caption and Teletext decoders.</para>
380
381 <para>A sliced VBI device may support <link
382linkend="rw">read/write</link> and/or streaming (<link
383linkend="mmap">memory mapping</link> and/or <link linkend="userp">user
384pointer</link>) I/O. The latter bears the possibility of synchronizing
385video and VBI data by using buffer timestamps.</para>
386
387 </section>
388
389 <section>
390 <title>Sliced VBI Data in MPEG Streams</title>
391
392 <para>If a device can produce an MPEG output stream, it may be
393capable of providing <link
394linkend="sliced-vbi-format-negotitation">negotiated sliced VBI
395services</link> as data embedded in the MPEG stream. Users or
396applications control this sliced VBI data insertion with the <link
397linkend="v4l2-mpeg-stream-vbi-fmt">V4L2_CID_MPEG_STREAM_VBI_FMT</link>
398control.</para>
399
400 <para>If the driver does not provide the <link
401linkend="v4l2-mpeg-stream-vbi-fmt">V4L2_CID_MPEG_STREAM_VBI_FMT</link>
402control, or only allows that control to be set to <link
403linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
404V4L2_MPEG_STREAM_VBI_FMT_NONE</constant></link>, then the device
405cannot embed sliced VBI data in the MPEG stream.</para>
406
407 <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt">
408V4L2_CID_MPEG_STREAM_VBI_FMT</link> control does not implicitly set
409the device driver to capture nor cease capturing sliced VBI data. The
410control only indicates to embed sliced VBI data in the MPEG stream, if
411an application has negotiated sliced VBI service be captured.</para>
412
413 <para>It may also be the case that a device can embed sliced VBI
414data in only certain types of MPEG streams: for example in an MPEG-2
415PS but not an MPEG-2 TS. In this situation, if sliced VBI data
416insertion is requested, the sliced VBI data will be embedded in MPEG
417stream types when supported, and silently omitted from MPEG stream
418types where sliced VBI data insertion is not supported by the device.
419</para>
420
421 <para>The following subsections specify the format of the
422embedded sliced VBI data.</para>
423
424 <section>
425 <title>MPEG Stream Embedded, Sliced VBI Data Format: NONE</title>
426 <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
427V4L2_MPEG_STREAM_VBI_FMT_NONE</constant></link> embedded sliced VBI
428format shall be interpreted by drivers as a control to cease
429embedding sliced VBI data in MPEG streams. Neither the device nor
430driver shall insert "empty" embedded sliced VBI data packets in the
431MPEG stream when this format is set. No MPEG stream data structures
432are specified for this format.</para>
433 </section>
434
435 <section>
436 <title>MPEG Stream Embedded, Sliced VBI Data Format: IVTV</title>
437 <para>The <link linkend="v4l2-mpeg-stream-vbi-fmt"><constant>
438V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant></link> embedded sliced VBI
439format, when supported, indicates to the driver to embed up to 36
440lines of sliced VBI data per frame in an MPEG-2 <emphasis>Private
441Stream 1 PES</emphasis> packet encapsulated in an MPEG-2 <emphasis>
442Program Pack</emphasis> in the MPEG stream.</para>
443
444 <para><emphasis>Historical context</emphasis>: This format
445specification originates from a custom, embedded, sliced VBI data
446format used by the <filename>ivtv</filename> driver. This format
447has already been informally specified in the kernel sources in the
448file <filename>Documentation/video4linux/cx2341x/README.vbi</filename>
449. The maximum size of the payload and other aspects of this format
450are driven by the CX23415 MPEG decoder's capabilities and limitations
451with respect to extracting, decoding, and displaying sliced VBI data
452embedded within an MPEG stream.</para>
453
454 <para>This format's use is <emphasis>not</emphasis> exclusive to
455the <filename>ivtv</filename> driver <emphasis>nor</emphasis>
456exclusive to CX2341x devices, as the sliced VBI data packet insertion
457into the MPEG stream is implemented in driver software. At least the
458<filename>cx18</filename> driver provides sliced VBI data insertion
459into an MPEG-2 PS in this format as well.</para>
460
461 <para>The following definitions specify the payload of the
462MPEG-2 <emphasis>Private Stream 1 PES</emphasis> packets that contain
463sliced VBI data when <link linkend="v4l2-mpeg-stream-vbi-fmt">
464<constant>V4L2_MPEG_STREAM_VBI_FMT_IVTV</constant></link> is set.
465(The MPEG-2 <emphasis>Private Stream 1 PES</emphasis> packet header
466and encapsulating MPEG-2 <emphasis>Program Pack</emphasis> header are
467not detailed here. Please refer to the MPEG-2 specifications for
468details on those packet headers.)</para>
469
470 <para>The payload of the MPEG-2 <emphasis>Private Stream 1 PES
471</emphasis> packets that contain sliced VBI data is specified by
472&v4l2-mpeg-vbi-fmt-ivtv;. The payload is variable
473length, depending on the actual number of lines of sliced VBI data
474present in a video frame. The payload may be padded at the end with
475unspecified fill bytes to align the end of the payload to a 4-byte
476boundary. The payload shall never exceed 1552 bytes (2 fields with
47718 lines/field with 43 bytes of data/line and a 4 byte magic number).
478</para>
479
480 <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-fmt-ivtv">
481 <title>struct <structname>v4l2_mpeg_vbi_fmt_ivtv</structname>
482 </title>
483 <tgroup cols="4">
484 &cs-ustr;
485 <tbody valign="top">
486 <row>
487 <entry>__u8</entry>
488 <entry><structfield>magic</structfield>[4]</entry>
489 <entry></entry>
490 <entry>A "magic" constant from <xref
491 linkend="v4l2-mpeg-vbi-fmt-ivtv-magic" /> that indicates
492this is a valid sliced VBI data payload and also indicates which
493member of the anonymous union, <structfield>itv0</structfield> or
494<structfield>ITV0</structfield>, to use for the payload data.</entry>
495 </row>
496 <row>
497 <entry>union</entry>
498 <entry>(anonymous)</entry>
499 </row>
500 <row>
501 <entry></entry>
502 <entry>struct <link linkend="v4l2-mpeg-vbi-itv0">
503 <structname>v4l2_mpeg_vbi_itv0</structname></link>
504 </entry>
505 <entry><structfield>itv0</structfield></entry>
506 <entry>The primary form of the sliced VBI data payload
507that contains anywhere from 1 to 35 lines of sliced VBI data.
508Line masks are provided in this form of the payload indicating
509which VBI lines are provided.</entry>
510 </row>
511 <row>
512 <entry></entry>
513 <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-1">
514 <structname>v4l2_mpeg_vbi_ITV0</structname></link>
515 </entry>
516 <entry><structfield>ITV0</structfield></entry>
517 <entry>An alternate form of the sliced VBI data payload
518used when 36 lines of sliced VBI data are present. No line masks are
519provided in this form of the payload; all valid line mask bits are
520implcitly set.</entry>
521 </row>
522 </tbody>
523 </tgroup>
524 </table>
525
526 <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-fmt-ivtv-magic">
527 <title>Magic Constants for &v4l2-mpeg-vbi-fmt-ivtv;
528 <structfield>magic</structfield> field</title>
529 <tgroup cols="3">
530 &cs-def;
531 <thead>
532 <row>
533 <entry align="left">Defined Symbol</entry>
534 <entry align="left">Value</entry>
535 <entry align="left">Description</entry>
536 </row>
537 </thead>
538 <tbody valign="top">
539 <row>
540 <entry><constant>V4L2_MPEG_VBI_IVTV_MAGIC0</constant>
541 </entry>
542 <entry>"itv0"</entry>
543 <entry>Indicates the <structfield>itv0</structfield>
544member of the union in &v4l2-mpeg-vbi-fmt-ivtv; is valid.</entry>
545 </row>
546 <row>
547 <entry><constant>V4L2_MPEG_VBI_IVTV_MAGIC1</constant>
548 </entry>
549 <entry>"ITV0"</entry>
550 <entry>Indicates the <structfield>ITV0</structfield>
551member of the union in &v4l2-mpeg-vbi-fmt-ivtv; is valid and
552that 36 lines of sliced VBI data are present.</entry>
553 </row>
554 </tbody>
555 </tgroup>
556 </table>
557
558 <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0">
559 <title>struct <structname>v4l2_mpeg_vbi_itv0</structname>
560 </title>
561 <tgroup cols="3">
562 &cs-str;
563 <tbody valign="top">
564 <row>
565 <entry>__le32</entry>
566 <entry><structfield>linemask</structfield>[2]</entry>
567 <entry><para>Bitmasks indicating the VBI service lines
568present. These <structfield>linemask</structfield> values are stored
569in little endian byte order in the MPEG stream. Some reference
570<structfield>linemask</structfield> bit positions with their
571corresponding VBI line number and video field are given below.
572b<subscript>0</subscript> indicates the least significant bit of a
573<structfield>linemask</structfield> value:<screen>
574<structfield>linemask</structfield>[0] b<subscript>0</subscript>: line 6 first field
575<structfield>linemask</structfield>[0] b<subscript>17</subscript>: line 23 first field
576<structfield>linemask</structfield>[0] b<subscript>18</subscript>: line 6 second field
577<structfield>linemask</structfield>[0] b<subscript>31</subscript>: line 19 second field
578<structfield>linemask</structfield>[1] b<subscript>0</subscript>: line 20 second field
579<structfield>linemask</structfield>[1] b<subscript>3</subscript>: line 23 second field
580<structfield>linemask</structfield>[1] b<subscript>4</subscript>-b<subscript>31</subscript>: unused and set to 0</screen></para></entry>
581 </row>
582 <row>
583 <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-line">
584 <structname>v4l2_mpeg_vbi_itv0_line</structname></link>
585 </entry>
586 <entry><structfield>line</structfield>[35]</entry>
587 <entry>This is a variable length array that holds from 1
588to 35 lines of sliced VBI data. The sliced VBI data lines present
589correspond to the bits set in the <structfield>linemask</structfield>
590array, starting from b<subscript>0</subscript> of <structfield>
591linemask</structfield>[0] up through b<subscript>31</subscript> of
592<structfield>linemask</structfield>[0], and from b<subscript>0
593</subscript> of <structfield>linemask</structfield>[1] up through b
594<subscript>3</subscript> of <structfield>linemask</structfield>[1].
595<structfield>line</structfield>[0] corresponds to the first bit
596found set in the <structfield>linemask</structfield> array,
597<structfield>line</structfield>[1] corresponds to the second bit
598found set in the <structfield>linemask</structfield> array, etc.
599If no <structfield>linemask</structfield> array bits are set, then
600<structfield>line</structfield>[0] may contain one line of
601unspecified data that should be ignored by applications.</entry>
602 </row>
603 </tbody>
604 </tgroup>
605 </table>
606
607 <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0-1">
608 <title>struct <structname>v4l2_mpeg_vbi_ITV0</structname>
609 </title>
610 <tgroup cols="3">
611 &cs-str;
612 <tbody valign="top">
613 <row>
614 <entry>struct <link linkend="v4l2-mpeg-vbi-itv0-line">
615 <structname>v4l2_mpeg_vbi_itv0_line</structname></link>
616 </entry>
617 <entry><structfield>line</structfield>[36]</entry>
618 <entry>A fixed length array of 36 lines of sliced VBI
619data. <structfield>line</structfield>[0] through <structfield>line
620</structfield>[17] correspond to lines 6 through 23 of the
621first field. <structfield>line</structfield>[18] through
622<structfield>line</structfield>[35] corresponds to lines 6
623through 23 of the second field.</entry>
624 </row>
625 </tbody>
626 </tgroup>
627 </table>
628
629 <table frame="none" pgwide="1" id="v4l2-mpeg-vbi-itv0-line">
630 <title>struct <structname>v4l2_mpeg_vbi_itv0_line</structname>
631 </title>
632 <tgroup cols="3">
633 &cs-str;
634 <tbody valign="top">
635 <row>
636 <entry>__u8</entry>
637 <entry><structfield>id</structfield></entry>
638 <entry>A line identifier value from
639<xref linkend="ITV0-Line-Identifier-Constants" /> that indicates
640the type of sliced VBI data stored on this line.</entry>
641 </row>
642 <row>
643 <entry>__u8</entry>
644 <entry><structfield>data</structfield>[42]</entry>
645 <entry>The sliced VBI data for the line.</entry>
646 </row>
647 </tbody>
648 </tgroup>
649 </table>
650
651 <table frame="none" pgwide="1" id="ITV0-Line-Identifier-Constants">
652 <title>Line Identifiers for struct <link
653 linkend="v4l2-mpeg-vbi-itv0-line"><structname>
654v4l2_mpeg_vbi_itv0_line</structname></link> <structfield>id
655</structfield> field</title>
656 <tgroup cols="3">
657 &cs-def;
658 <thead>
659 <row>
660 <entry align="left">Defined Symbol</entry>
661 <entry align="left">Value</entry>
662 <entry align="left">Description</entry>
663 </row>
664 </thead>
665 <tbody valign="top">
666 <row>
667 <entry><constant>V4L2_MPEG_VBI_IVTV_TELETEXT_B</constant>
668 </entry>
669 <entry>1</entry>
670 <entry>Refer to <link linkend="vbi-services2">
671Sliced VBI services</link> for a description of the line payload.</entry>
672 </row>
673 <row>
674 <entry><constant>V4L2_MPEG_VBI_IVTV_CAPTION_525</constant>
675 </entry>
676 <entry>4</entry>
677 <entry>Refer to <link linkend="vbi-services2">
678Sliced VBI services</link> for a description of the line payload.</entry>
679 </row>
680 <row>
681 <entry><constant>V4L2_MPEG_VBI_IVTV_WSS_625</constant>
682 </entry>
683 <entry>5</entry>
684 <entry>Refer to <link linkend="vbi-services2">
685Sliced VBI services</link> for a description of the line payload.</entry>
686 </row>
687 <row>
688 <entry><constant>V4L2_MPEG_VBI_IVTV_VPS</constant>
689 </entry>
690 <entry>7</entry>
691 <entry>Refer to <link linkend="vbi-services2">
692Sliced VBI services</link> for a description of the line payload.</entry>
693 </row>
694 </tbody>
695 </tgroup>
696 </table>
697
698 </section>
699 </section>
700
701
702<!--
703Local Variables:
704mode: sgml
705sgml-parent-document: "v4l2.sgml"
706indent-tabs-mode: nil
707End:
708 -->
diff --git a/Documentation/DocBook/v4l/dev-teletext.xml b/Documentation/DocBook/v4l/dev-teletext.xml
new file mode 100644
index 000000000000..76184e8ed618
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-teletext.xml
@@ -0,0 +1,40 @@
1 <title>Teletext Interface</title>
2
3 <para>This interface aims at devices receiving and demodulating
4Teletext data [<xref linkend="ets300706" />, <xref linkend="itu653" />], evaluating the
5Teletext packages and storing formatted pages in cache memory. Such
6devices are usually implemented as microcontrollers with serial
7interface (I<superscript>2</superscript>C) and can be found on older
8TV cards, dedicated Teletext decoding cards and home-brew devices
9connected to the PC parallel port.</para>
10
11 <para>The Teletext API was designed by Martin Buck. It is defined in
12the kernel header file <filename>linux/videotext.h</filename>, the
13specification is available from <ulink url="ftp://ftp.gwdg.de/pub/linux/misc/videotext/">
14ftp://ftp.gwdg.de/pub/linux/misc/videotext/</ulink>. (Videotext is the name of
15the German public television Teletext service.) Conventional character
16device file names are <filename>/dev/vtx</filename> and
17<filename>/dev/vttuner</filename>, with device number 83, 0 and 83, 16
18respectively. A similar interface exists for the Philips SAA5249
19Teletext decoder [specification?] with character device file names
20<filename>/dev/tlkN</filename>, device number 102, N.</para>
21
22 <para>Eventually the Teletext API was integrated into the V4L API
23with character device file names <filename>/dev/vtx0</filename> to
24<filename>/dev/vtx31</filename>, device major number 81, minor numbers
25192 to 223. For reference the V4L Teletext API specification is
26reproduced here in full: "Teletext interfaces talk the existing VTX
27API." Teletext devices with major number 83 and 102 will be removed in
28Linux 2.6.</para>
29
30 <para>There are no plans to replace the Teletext API or to integrate
31it into V4L2. Please write to the linux-media mailing list: &v4l-ml;
32when the need arises.</para>
33
34 <!--
35Local Variables:
36mode: sgml
37sgml-parent-document: "v4l2.sgml"
38indent-tabs-mode: nil
39End:
40 -->
diff --git a/Documentation/DocBook/v4l/driver.xml b/Documentation/DocBook/v4l/driver.xml
new file mode 100644
index 000000000000..1f7eea5c4ec3
--- /dev/null
+++ b/Documentation/DocBook/v4l/driver.xml
@@ -0,0 +1,208 @@
1 <title>V4L2 Driver Programming</title>
2
3 <!-- This part defines the interface between the "videodev"
4 module and individual drivers. -->
5
6 <para>to do</para>
7<!--
8 <para>V4L2 is a two-layer driver system. The top layer is the "videodev"
9kernel module. When videodev initializes it registers as character device
10with major number 81, and it registers a set of file operations. All V4L2
11drivers are really clients of videodev, which calls V4L2 drivers through
12driver method functions. V4L2 drivers are also written as kernel modules.
13After probing the hardware they register one or more devices with
14videodev.</para>
15
16 <section id="driver-modules">
17 <title>Driver Modules</title>
18
19 <para>V4L2 driver modules must have an initialization function which is
20called after the module was loaded into kernel, an exit function whis is
21called before the module is removed. When the driver is compiled into the
22kernel these functions called at system boot and shutdown time.</para>
23
24 <informalexample>
25 <programlisting>
26#include &lt;linux/module.h&gt;
27
28/* Export information about this module. For details and other useful
29 macros see <filename>linux/module.h</filename>. */
30MODULE_DESCRIPTION("my - driver for my hardware");
31MODULE_AUTHOR("Your name here");
32MODULE_LICENSE("GPL");
33
34static void
35my_module_exit (void)
36{
37 /* Free all resources allocated by my_module_init(). */
38}
39
40static int
41my_module_init (void)
42{
43 /* Bind the driver to the supported hardware, see
44 <link linkend="driver-pci"> and
45 <link linkend="driver-usb"> for examples. */
46
47 return 0; /* a negative value on error, 0 on success. */
48}
49
50/* Export module functions. */
51module_init (my_module_init);
52module_exit (my_module_exit);
53</programlisting>
54 </informalexample>
55
56 <para>Users can add parameters when kernel modules are inserted:</para>
57
58 <informalexample>
59 <programlisting>
60include &lt;linux/moduleparam.h&gt;
61
62static int my_option = 123;
63static int my_option_array[47];
64
65/* Export the symbol, an int, with access permissions 0664.
66 See <filename>linux/moduleparam.h</filename> for other types. */
67module_param (my_option, int, 0644);
68module_param_array (my_option_array, int, NULL, 0644);
69
70MODULE_PARM_DESC (my_option, "Does magic things, default 123");
71</programlisting>
72 </informalexample>
73
74 <para>One parameter should be supported by all V4L2 drivers, the minor
75number of the device it will register. Purpose is to predictably link V4L2
76drivers to device nodes if more than one video device is installed. Use the
77name of the device node followed by a "_nr" suffix, for example "video_nr"
78for <filename>/dev/video</filename>.</para>
79
80 <informalexample>
81 <programlisting>
82/* Minor number of the device, -1 to allocate the first unused. */
83static int video_nr = -1;
84
85module_param (video_nr, int, 0444);
86</programlisting>
87 </informalexample>
88 </section>
89
90 <section id="driver-pci">
91 <title>PCI Devices</title>
92
93 <para>PCI devices are initialized like this:</para>
94
95 <informalexample>
96 <programlisting>
97typedef struct {
98 /* State of one physical device. */
99} my_device;
100
101static int
102my_resume (struct pci_dev * pci_dev)
103{
104 /* Restore the suspended device to working state. */
105}
106
107static int
108my_suspend (struct pci_dev * pci_dev,
109 pm_message_t state)
110{
111 /* This function is called before the system goes to sleep.
112 Stop all DMAs and disable interrupts, then put the device
113 into a low power state. For details see the kernel
114 sources under <filename>Documentation/power</filename>. */
115
116 return 0; /* a negative value on error, 0 on success. */
117}
118
119static void __devexit
120my_remove (struct pci_dev * pci_dev)
121{
122 my_device *my = pci_get_drvdata (pci_dev);
123
124 /* Describe me. */
125}
126
127static int __devinit
128my_probe (struct pci_dev * pci_dev,
129 const struct pci_device_id * pci_id)
130{
131 my_device *my;
132
133 /* Describe me. */
134
135 /* You can allocate per-device data here and store a pointer
136 to it in the pci_dev structure. */
137 my = ...;
138 pci_set_drvdata (pci_dev, my);
139
140 return 0; /* a negative value on error, 0 on success. */
141}
142
143/* A list of supported PCI devices. */
144static struct pci_device_id
145my_pci_device_ids [] = {
146 { PCI_VENDOR_ID_FOO, PCI_DEVICE_ID_BAR,
147 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
148 { 0 } /* end of list */
149};
150
151/* Load our module if supported PCI devices are installed. */
152MODULE_DEVICE_TABLE (pci, my_pci_device_ids);
153
154static struct pci_driver
155my_pci_driver = {
156 .name = "my",
157 .id_table = my_pci_device_ids,
158
159 .probe = my_probe,
160 .remove = __devexit_p (my_remove),
161
162 /* Power management functions. */
163 .suspend = my_suspend,
164 .resume = my_resume,
165};
166
167static void
168my_module_exit (void)
169{
170 pci_unregister_driver (&my_pci_driver);
171}
172
173static int
174my_module_init (void)
175{
176 return pci_register_driver (&my_pci_driver);
177}
178</programlisting>
179 </informalexample>
180 </section>
181
182 <section id="driver-usb">
183 <title>USB Devices</title>
184 <para>to do</para>
185 </section>
186 <section id="driver-registering">
187 <title>Registering V4L2 Drivers</title>
188
189 <para>After a V4L2 driver probed the hardware it registers one or more
190devices with the videodev module.</para>
191 </section>
192 <section id="driver-file-ops">
193 <title>File Operations</title>
194 <para>to do</para>
195 </section>
196 <section id="driver-internal-api">
197 <title>Internal API</title>
198 <para>to do</para>
199 </section>
200-->
201
202<!--
203Local Variables:
204mode: sgml
205sgml-parent-document: "v4l2.sgml"
206indent-tabs-mode: nil
207End:
208-->
diff --git a/Documentation/DocBook/v4l/fdl-appendix.xml b/Documentation/DocBook/v4l/fdl-appendix.xml
new file mode 100644
index 000000000000..b6ce50dbe492
--- /dev/null
+++ b/Documentation/DocBook/v4l/fdl-appendix.xml
@@ -0,0 +1,671 @@
1<!--
2 The GNU Free Documentation License 1.1 in DocBook
3 Markup by Eric Baudais <baudais@okstate.edu>
4 Maintained by the GNOME Documentation Project
5 http://developer.gnome.org/projects/gdp
6 Version: 1.0.1
7 Last Modified: Nov 16, 2000
8-->
9
10<appendix id="fdl">
11 <appendixinfo>
12 <releaseinfo>
13 Version 1.1, March 2000
14 </releaseinfo>
15 <copyright>
16 <year>2000</year><holder>Free Software Foundation, Inc.</holder>
17 </copyright>
18 <legalnotice id="fdl-legalnotice">
19 <para>
20 <address>Free Software Foundation, Inc. <street>59 Temple Place,
21 Suite 330</street>, <city>Boston</city>, <state>MA</state>
22 <postcode>02111-1307</postcode> <country>USA</country></address>
23 Everyone is permitted to copy and distribute verbatim copies of this
24 license document, but changing it is not allowed.
25 </para>
26 </legalnotice>
27 </appendixinfo>
28 <title>GNU Free Documentation License</title>
29
30 <sect1 id="fdl-preamble">
31 <title>0. PREAMBLE</title>
32 <para>
33 The purpose of this License is to make a manual, textbook, or
34 other written document <quote>free</quote> in the sense of
35 freedom: to assure everyone the effective freedom to copy and
36 redistribute it, with or without modifying it, either
37 commercially or noncommercially. Secondarily, this License
38 preserves for the author and publisher a way to get credit for
39 their work, while not being considered responsible for
40 modifications made by others.
41 </para>
42
43 <para>
44 This License is a kind of <quote>copyleft</quote>, which means
45 that derivative works of the document must themselves be free in
46 the same sense. It complements the GNU General Public License,
47 which is a copyleft license designed for free software.
48 </para>
49
50 <para>
51 We have designed this License in order to use it for manuals for
52 free software, because free software needs free documentation: a
53 free program should come with manuals providing the same
54 freedoms that the software does. But this License is not limited
55 to software manuals; it can be used for any textual work,
56 regardless of subject matter or whether it is published as a
57 printed book. We recommend this License principally for works
58 whose purpose is instruction or reference.
59 </para>
60 </sect1>
61 <sect1 id="fdl-section1">
62 <title>1. APPLICABILITY AND DEFINITIONS</title>
63 <para id="fdl-document">
64 This License applies to any manual or other work that contains a
65 notice placed by the copyright holder saying it can be
66 distributed under the terms of this License. The
67 <quote>Document</quote>, below, refers to any such manual or
68 work. Any member of the public is a licensee, and is addressed
69 as <quote>you</quote>.
70 </para>
71
72 <para id="fdl-modified">
73 A <quote>Modified Version</quote> of the Document means any work
74 containing the Document or a portion of it, either copied
75 verbatim, or with modifications and/or translated into another
76 language.
77 </para>
78
79 <para id="fdl-secondary">
80 A <quote>Secondary Section</quote> is a named appendix or a
81 front-matter section of the <link
82 linkend="fdl-document">Document</link> that deals exclusively
83 with the relationship of the publishers or authors of the
84 Document to the Document's overall subject (or to related
85 matters) and contains nothing that could fall directly within
86 that overall subject. (For example, if the Document is in part a
87 textbook of mathematics, a Secondary Section may not explain any
88 mathematics.) The relationship could be a matter of historical
89 connection with the subject or with related matters, or of
90 legal, commercial, philosophical, ethical or political position
91 regarding them.
92 </para>
93
94 <para id="fdl-invariant">
95 The <quote>Invariant Sections</quote> are certain <link
96 linkend="fdl-secondary"> Secondary Sections</link> whose titles
97 are designated, as being those of Invariant Sections, in the
98 notice that says that the <link
99 linkend="fdl-document">Document</link> is released under this
100 License.
101 </para>
102
103 <para id="fdl-cover-texts">
104 The <quote>Cover Texts</quote> are certain short passages of
105 text that are listed, as Front-Cover Texts or Back-Cover Texts,
106 in the notice that says that the <link
107 linkend="fdl-document">Document</link> is released under this
108 License.
109 </para>
110
111 <para id="fdl-transparent">
112 A <quote>Transparent</quote> copy of the <link
113 linkend="fdl-document"> Document</link> means a machine-readable
114 copy, represented in a format whose specification is available
115 to the general public, whose contents can be viewed and edited
116 directly and straightforwardly with generic text editors or (for
117 images composed of pixels) generic paint programs or (for
118 drawings) some widely available drawing editor, and that is
119 suitable for input to text formatters or for automatic
120 translation to a variety of formats suitable for input to text
121 formatters. A copy made in an otherwise Transparent file format
122 whose markup has been designed to thwart or discourage
123 subsequent modification by readers is not Transparent. A copy
124 that is not <quote>Transparent</quote> is called
125 <quote>Opaque</quote>.
126 </para>
127
128 <para>
129 Examples of suitable formats for Transparent copies include
130 plain ASCII without markup, Texinfo input format, LaTeX input
131 format, SGML or XML using a publicly available DTD, and
132 standard-conforming simple HTML designed for human
133 modification. Opaque formats include PostScript, PDF,
134 proprietary formats that can be read and edited only by
135 proprietary word processors, SGML or XML for which the DTD
136 and/or processing tools are not generally available, and the
137 machine-generated HTML produced by some word processors for
138 output purposes only.
139 </para>
140
141 <para id="fdl-title-page">
142 The <quote>Title Page</quote> means, for a printed book, the
143 title page itself, plus such following pages as are needed to
144 hold, legibly, the material this License requires to appear in
145 the title page. For works in formats which do not have any title
146 page as such, <quote>Title Page</quote> means the text near the
147 most prominent appearance of the work's title, preceding the
148 beginning of the body of the text.
149 </para>
150 </sect1>
151
152 <sect1 id="fdl-section2">
153 <title>2. VERBATIM COPYING</title>
154 <para>
155 You may copy and distribute the <link
156 linkend="fdl-document">Document</link> in any medium, either
157 commercially or noncommercially, provided that this License, the
158 copyright notices, and the license notice saying this License
159 applies to the Document are reproduced in all copies, and that
160 you add no other conditions whatsoever to those of this
161 License. You may not use technical measures to obstruct or
162 control the reading or further copying of the copies you make or
163 distribute. However, you may accept compensation in exchange for
164 copies. If you distribute a large enough number of copies you
165 must also follow the conditions in <link
166 linkend="fdl-section3">section 3</link>.
167 </para>
168
169 <para>
170 You may also lend copies, under the same conditions stated
171 above, and you may publicly display copies.
172 </para>
173 </sect1>
174
175 <sect1 id="fdl-section3">
176 <title>3. COPYING IN QUANTITY</title>
177 <para>
178 If you publish printed copies of the <link
179 linkend="fdl-document">Document</link> numbering more than 100,
180 and the Document's license notice requires <link
181 linkend="fdl-cover-texts">Cover Texts</link>, you must enclose
182 the copies in covers that carry, clearly and legibly, all these
183 Cover Texts: Front-Cover Texts on the front cover, and
184 Back-Cover Texts on the back cover. Both covers must also
185 clearly and legibly identify you as the publisher of these
186 copies. The front cover must present the full title with all
187 words of the title equally prominent and visible. You may add
188 other material on the covers in addition. Copying with changes
189 limited to the covers, as long as they preserve the title of the
190 <link linkend="fdl-document">Document</link> and satisfy these
191 conditions, can be treated as verbatim copying in other
192 respects.
193 </para>
194
195 <para>
196 If the required texts for either cover are too voluminous to fit
197 legibly, you should put the first ones listed (as many as fit
198 reasonably) on the actual cover, and continue the rest onto
199 adjacent pages.
200 </para>
201
202 <para>
203 If you publish or distribute <link
204 linkend="fdl-transparent">Opaque</link> copies of the <link
205 linkend="fdl-document">Document</link> numbering more than 100,
206 you must either include a machine-readable <link
207 linkend="fdl-transparent">Transparent</link> copy along with
208 each Opaque copy, or state in or with each Opaque copy a
209 publicly-accessible computer-network location containing a
210 complete Transparent copy of the Document, free of added
211 material, which the general network-using public has access to
212 download anonymously at no charge using public-standard network
213 protocols. If you use the latter option, you must take
214 reasonably prudent steps, when you begin distribution of Opaque
215 copies in quantity, to ensure that this Transparent copy will
216 remain thus accessible at the stated location until at least one
217 year after the last time you distribute an Opaque copy (directly
218 or through your agents or retailers) of that edition to the
219 public.
220 </para>
221
222 <para>
223 It is requested, but not required, that you contact the authors
224 of the <link linkend="fdl-document">Document</link> well before
225 redistributing any large number of copies, to give them a chance
226 to provide you with an updated version of the Document.
227 </para>
228 </sect1>
229
230 <sect1 id="fdl-section4">
231 <title>4. MODIFICATIONS</title>
232 <para>
233 You may copy and distribute a <link
234 linkend="fdl-modified">Modified Version</link> of the <link
235 linkend="fdl-document">Document</link> under the conditions of
236 sections <link linkend="fdl-section2">2</link> and <link
237 linkend="fdl-section3">3</link> above, provided that you release
238 the Modified Version under precisely this License, with the
239 Modified Version filling the role of the Document, thus
240 licensing distribution and modification of the Modified Version
241 to whoever possesses a copy of it. In addition, you must do
242 these things in the Modified Version:
243 </para>
244
245 <itemizedlist mark="opencircle">
246 <listitem>
247 <formalpara>
248 <title>A</title>
249 <para>
250 Use in the <link linkend="fdl-title-page">Title
251 Page</link> (and on the covers, if any) a title distinct
252 from that of the <link
253 linkend="fdl-document">Document</link>, and from those of
254 previous versions (which should, if there were any, be
255 listed in the History section of the Document). You may
256 use the same title as a previous version if the original
257 publisher of that version gives permission.
258 </para>
259 </formalpara>
260 </listitem>
261
262 <listitem>
263 <formalpara>
264 <title>B</title>
265 <para>
266 List on the <link linkend="fdl-title-page">Title
267 Page</link>, as authors, one or more persons or entities
268 responsible for authorship of the modifications in the
269 <link linkend="fdl-modified">Modified Version</link>,
270 together with at least five of the principal authors of
271 the <link linkend="fdl-document">Document</link> (all of
272 its principal authors, if it has less than five).
273 </para>
274 </formalpara>
275 </listitem>
276
277 <listitem>
278 <formalpara>
279 <title>C</title>
280 <para>
281 State on the <link linkend="fdl-title-page">Title
282 Page</link> the name of the publisher of the <link
283 linkend="fdl-modified">Modified Version</link>, as the
284 publisher.
285 </para>
286 </formalpara>
287 </listitem>
288
289 <listitem>
290 <formalpara>
291 <title>D</title>
292 <para>
293 Preserve all the copyright notices of the <link
294 linkend="fdl-document">Document</link>.
295 </para>
296 </formalpara>
297 </listitem>
298
299 <listitem>
300 <formalpara>
301 <title>E</title>
302 <para>
303 Add an appropriate copyright notice for your modifications
304 adjacent to the other copyright notices.
305 </para>
306 </formalpara>
307 </listitem>
308
309 <listitem>
310 <formalpara>
311 <title>F</title>
312 <para>
313 Include, immediately after the copyright notices, a
314 license notice giving the public permission to use the
315 <link linkend="fdl-modified">Modified Version</link> under
316 the terms of this License, in the form shown in the
317 Addendum below.
318 </para>
319 </formalpara>
320 </listitem>
321
322 <listitem>
323 <formalpara>
324 <title>G</title>
325 <para>
326 Preserve in that license notice the full lists of <link
327 linkend="fdl-invariant"> Invariant Sections</link> and
328 required <link linkend="fdl-cover-texts">Cover
329 Texts</link> given in the <link
330 linkend="fdl-document">Document's</link> license notice.
331 </para>
332 </formalpara>
333 </listitem>
334
335 <listitem>
336 <formalpara>
337 <title>H</title>
338 <para>
339 Include an unaltered copy of this License.
340 </para>
341 </formalpara>
342 </listitem>
343
344 <listitem>
345 <formalpara>
346 <title>I</title>
347 <para>
348 Preserve the section entitled <quote>History</quote>, and
349 its title, and add to it an item stating at least the
350 title, year, new authors, and publisher of the <link
351 linkend="fdl-modified">Modified Version </link>as given on
352 the <link linkend="fdl-title-page">Title Page</link>. If
353 there is no section entitled <quote>History</quote> in the
354 <link linkend="fdl-document">Document</link>, create one
355 stating the title, year, authors, and publisher of the
356 Document as given on its Title Page, then add an item
357 describing the Modified Version as stated in the previous
358 sentence.
359 </para>
360 </formalpara>
361 </listitem>
362
363 <listitem>
364 <formalpara>
365 <title>J</title>
366 <para>
367 Preserve the network location, if any, given in the <link
368 linkend="fdl-document">Document</link> for public access
369 to a <link linkend="fdl-transparent">Transparent</link>
370 copy of the Document, and likewise the network locations
371 given in the Document for previous versions it was based
372 on. These may be placed in the <quote>History</quote>
373 section. You may omit a network location for a work that
374 was published at least four years before the Document
375 itself, or if the original publisher of the version it
376 refers to gives permission.
377 </para>
378 </formalpara>
379 </listitem>
380
381 <listitem>
382 <formalpara>
383 <title>K</title>
384 <para>
385 In any section entitled <quote>Acknowledgements</quote> or
386 <quote>Dedications</quote>, preserve the section's title,
387 and preserve in the section all the substance and tone of
388 each of the contributor acknowledgements and/or
389 dedications given therein.
390 </para>
391 </formalpara>
392 </listitem>
393
394 <listitem>
395 <formalpara>
396 <title>L</title>
397 <para>
398 Preserve all the <link linkend="fdl-invariant">Invariant
399 Sections</link> of the <link
400 linkend="fdl-document">Document</link>, unaltered in their
401 text and in their titles. Section numbers or the
402 equivalent are not considered part of the section titles.
403 </para>
404 </formalpara>
405 </listitem>
406
407 <listitem>
408 <formalpara>
409 <title>M</title>
410 <para>
411 Delete any section entitled
412 <quote>Endorsements</quote>. Such a section may not be
413 included in the <link linkend="fdl-modified">Modified
414 Version</link>.
415 </para>
416 </formalpara>
417 </listitem>
418
419 <listitem>
420 <formalpara>
421 <title>N</title>
422 <para>
423 Do not retitle any existing section as
424 <quote>Endorsements</quote> or to conflict in title with
425 any <link linkend="fdl-invariant">Invariant
426 Section</link>.
427 </para>
428 </formalpara>
429 </listitem>
430 </itemizedlist>
431
432 <para>
433 If the <link linkend="fdl-modified">Modified Version</link>
434 includes new front-matter sections or appendices that qualify as
435 <link linkend="fdl-secondary">Secondary Sections</link> and
436 contain no material copied from the Document, you may at your
437 option designate some or all of these sections as invariant. To
438 do this, add their titles to the list of <link
439 linkend="fdl-invariant">Invariant Sections</link> in the
440 Modified Version's license notice. These titles must be
441 distinct from any other section titles.
442 </para>
443
444 <para>
445 You may add a section entitled <quote>Endorsements</quote>,
446 provided it contains nothing but endorsements of your <link
447 linkend="fdl-modified">Modified Version</link> by various
448 parties--for example, statements of peer review or that the text
449 has been approved by an organization as the authoritative
450 definition of a standard.
451 </para>
452
453 <para>
454 You may add a passage of up to five words as a <link
455 linkend="fdl-cover-texts">Front-Cover Text</link>, and a passage
456 of up to 25 words as a <link
457 linkend="fdl-cover-texts">Back-Cover Text</link>, to the end of
458 the list of <link linkend="fdl-cover-texts">Cover Texts</link>
459 in the <link linkend="fdl-modified">Modified Version</link>.
460 Only one passage of Front-Cover Text and one of Back-Cover Text
461 may be added by (or through arrangements made by) any one
462 entity. If the <link linkend="fdl-document">Document</link>
463 already includes a cover text for the same cover, previously
464 added by you or by arrangement made by the same entity you are
465 acting on behalf of, you may not add another; but you may
466 replace the old one, on explicit permission from the previous
467 publisher that added the old one.
468 </para>
469
470 <para>
471 The author(s) and publisher(s) of the <link
472 linkend="fdl-document">Document</link> do not by this License
473 give permission to use their names for publicity for or to
474 assert or imply endorsement of any <link
475 linkend="fdl-modified">Modified Version </link>.
476 </para>
477 </sect1>
478
479 <sect1 id="fdl-section5">
480 <title>5. COMBINING DOCUMENTS</title>
481 <para>
482 You may combine the <link linkend="fdl-document">Document</link>
483 with other documents released under this License, under the
484 terms defined in <link linkend="fdl-section4">section 4</link>
485 above for modified versions, provided that you include in the
486 combination all of the <link linkend="fdl-invariant">Invariant
487 Sections</link> of all of the original documents, unmodified,
488 and list them all as Invariant Sections of your combined work in
489 its license notice.
490 </para>
491
492 <para>
493 The combined work need only contain one copy of this License,
494 and multiple identical <link linkend="fdl-invariant">Invariant
495 Sections</link> may be replaced with a single copy. If there are
496 multiple Invariant Sections with the same name but different
497 contents, make the title of each such section unique by adding
498 at the end of it, in parentheses, the name of the original
499 author or publisher of that section if known, or else a unique
500 number. Make the same adjustment to the section titles in the
501 list of Invariant Sections in the license notice of the combined
502 work.
503 </para>
504
505 <para>
506 In the combination, you must combine any sections entitled
507 <quote>History</quote> in the various original documents,
508 forming one section entitled <quote>History</quote>; likewise
509 combine any sections entitled <quote>Acknowledgements</quote>,
510 and any sections entitled <quote>Dedications</quote>. You must
511 delete all sections entitled <quote>Endorsements.</quote>
512 </para>
513 </sect1>
514
515 <sect1 id="fdl-section6">
516 <title>6. COLLECTIONS OF DOCUMENTS</title>
517 <para>
518 You may make a collection consisting of the <link
519 linkend="fdl-document">Document</link> and other documents
520 released under this License, and replace the individual copies
521 of this License in the various documents with a single copy that
522 is included in the collection, provided that you follow the
523 rules of this License for verbatim copying of each of the
524 documents in all other respects.
525 </para>
526
527 <para>
528 You may extract a single document from such a collection, and
529 dispbibute it individually under this License, provided you
530 insert a copy of this License into the extracted document, and
531 follow this License in all other respects regarding verbatim
532 copying of that document.
533 </para>
534 </sect1>
535
536 <sect1 id="fdl-section7">
537 <title>7. AGGREGATION WITH INDEPENDENT WORKS</title>
538 <para>
539 A compilation of the <link
540 linkend="fdl-document">Document</link> or its derivatives with
541 other separate and independent documents or works, in or on a
542 volume of a storage or distribution medium, does not as a whole
543 count as a <link linkend="fdl-modified">Modified Version</link>
544 of the Document, provided no compilation copyright is claimed
545 for the compilation. Such a compilation is called an
546 <quote>aggregate</quote>, and this License does not apply to the
547 other self-contained works thus compiled with the Document , on
548 account of their being thus compiled, if they are not themselves
549 derivative works of the Document. If the <link
550 linkend="fdl-cover-texts">Cover Text</link> requirement of <link
551 linkend="fdl-section3">section 3</link> is applicable to these
552 copies of the Document, then if the Document is less than one
553 quarter of the entire aggregate, the Document's Cover Texts may
554 be placed on covers that surround only the Document within the
555 aggregate. Otherwise they must appear on covers around the whole
556 aggregate.
557 </para>
558 </sect1>
559
560 <sect1 id="fdl-section8">
561 <title>8. TRANSLATION</title>
562 <para>
563 Translation is considered a kind of modification, so you may
564 distribute translations of the <link
565 linkend="fdl-document">Document</link> under the terms of <link
566 linkend="fdl-section4">section 4</link>. Replacing <link
567 linkend="fdl-invariant"> Invariant Sections</link> with
568 translations requires special permission from their copyright
569 holders, but you may include translations of some or all
570 Invariant Sections in addition to the original versions of these
571 Invariant Sections. You may include a translation of this
572 License provided that you also include the original English
573 version of this License. In case of a disagreement between the
574 translation and the original English version of this License,
575 the original English version will prevail.
576 </para>
577 </sect1>
578
579 <sect1 id="fdl-section9">
580 <title>9. TERMINATION</title>
581 <para>
582 You may not copy, modify, sublicense, or distribute the <link
583 linkend="fdl-document">Document</link> except as expressly
584 provided for under this License. Any other attempt to copy,
585 modify, sublicense or distribute the Document is void, and will
586 automatically terminate your rights under this License. However,
587 parties who have received copies, or rights, from you under this
588 License will not have their licenses terminated so long as such
589 parties remain in full compliance.
590 </para>
591 </sect1>
592
593 <sect1 id="fdl-section10">
594 <title>10. FUTURE REVISIONS OF THIS LICENSE</title>
595 <para>
596 The <ulink type="http"
597 url="http://www.gnu.org/fsf/fsf.html">Free Software
598 Foundation</ulink> may publish new, revised versions of the GNU
599 Free Documentation License from time to time. Such new versions
600 will be similar in spirit to the present version, but may differ
601 in detail to address new problems or concerns. See <ulink
602 type="http"
603 url="http://www.gnu.org/copyleft">http://www.gnu.org/copyleft/</ulink>.
604 </para>
605
606 <para>
607 Each version of the License is given a distinguishing version
608 number. If the <link linkend="fdl-document">Document</link>
609 specifies that a particular numbered version of this License
610 <quote>or any later version</quote> applies to it, you have the
611 option of following the terms and conditions either of that
612 specified version or of any later version that has been
613 published (not as a draft) by the Free Software Foundation. If
614 the Document does not specify a version number of this License,
615 you may choose any version ever published (not as a draft) by
616 the Free Software Foundation.
617 </para>
618 </sect1>
619
620 <sect1 id="fdl-using">
621 <title>Addendum</title>
622 <para>
623 To use this License in a document you have written, include a copy of
624 the License in the document and put the following copyright and
625 license notices just after the title page:
626 </para>
627
628 <blockquote>
629 <para>
630 Copyright &copy; YEAR YOUR NAME.
631 </para>
632 <para>
633 Permission is granted to copy, distribute and/or modify this
634 document under the terms of the GNU Free Documentation
635 License, Version 1.1 or any later version published by the
636 Free Software Foundation; with the <link
637 linkend="fdl-invariant">Invariant Sections</link> being LIST
638 THEIR TITLES, with the <link
639 linkend="fdl-cover-texts">Front-Cover Texts</link> being LIST,
640 and with the <link linkend="fdl-cover-texts">Back-Cover
641 Texts</link> being LIST. A copy of the license is included in
642 the section entitled <quote>GNU Free Documentation
643 License</quote>.
644 </para>
645 </blockquote>
646
647 <para>
648 If you have no <link linkend="fdl-invariant">Invariant
649 Sections</link>, write <quote>with no Invariant Sections</quote>
650 instead of saying which ones are invariant. If you have no
651 <link linkend="fdl-cover-texts">Front-Cover Texts</link>, write
652 <quote>no Front-Cover Texts</quote> instead of
653 <quote>Front-Cover Texts being LIST</quote>; likewise for <link
654 linkend="fdl-cover-texts">Back-Cover Texts</link>.
655 </para>
656
657 <para>
658 If your document contains nontrivial examples of program code,
659 we recommend releasing these examples in parallel under your
660 choice of free software license, such as the <ulink type="http"
661 url="http://www.gnu.org/copyleft/gpl.html"> GNU General Public
662 License</ulink>, to permit their use in free software.
663 </para>
664 </sect1>
665</appendix>
666
667
668
669
670
671
diff --git a/Documentation/DocBook/v4l/fieldseq_bt.gif b/Documentation/DocBook/v4l/fieldseq_bt.gif
new file mode 100644
index 000000000000..60e8569a76c9
--- /dev/null
+++ b/Documentation/DocBook/v4l/fieldseq_bt.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/fieldseq_bt.pdf b/Documentation/DocBook/v4l/fieldseq_bt.pdf
new file mode 100644
index 000000000000..26598b23f80d
--- /dev/null
+++ b/Documentation/DocBook/v4l/fieldseq_bt.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/fieldseq_tb.gif b/Documentation/DocBook/v4l/fieldseq_tb.gif
new file mode 100644
index 000000000000..718492f1cfc7
--- /dev/null
+++ b/Documentation/DocBook/v4l/fieldseq_tb.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/fieldseq_tb.pdf b/Documentation/DocBook/v4l/fieldseq_tb.pdf
new file mode 100644
index 000000000000..4965b22ddb3a
--- /dev/null
+++ b/Documentation/DocBook/v4l/fieldseq_tb.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/func-close.xml b/Documentation/DocBook/v4l/func-close.xml
new file mode 100644
index 000000000000..dfb41cbbbec3
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-close.xml
@@ -0,0 +1,70 @@
1<refentry id="func-close">
2 <refmeta>
3 <refentrytitle>V4L2 close()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-close</refname>
9 <refpurpose>Close a V4L2 device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>close</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 </funcprototype>
19 </funcsynopsis>
20 </refsynopsisdiv>
21
22 <refsect1>
23 <title>Arguments</title>
24
25 <variablelist>
26 <varlistentry>
27 <term><parameter>fd</parameter></term>
28 <listitem>
29 <para>&fd;</para>
30 </listitem>
31 </varlistentry>
32 </variablelist>
33 </refsect1>
34
35 <refsect1>
36 <title>Description</title>
37
38 <para>Closes the device. Any I/O in progress is terminated and
39resources associated with the file descriptor are freed. However data
40format parameters, current input or output, control values or other
41properties remain unchanged.</para>
42 </refsect1>
43
44 <refsect1>
45 <title>Return Value</title>
46
47 <para>The function returns <returnvalue>0</returnvalue> on
48success, <returnvalue>-1</returnvalue> on failure and the
49<varname>errno</varname> is set appropriately. Possible error
50codes:</para>
51
52 <variablelist>
53 <varlistentry>
54 <term><errorcode>EBADF</errorcode></term>
55 <listitem>
56 <para><parameter>fd</parameter> is not a valid open file
57descriptor.</para>
58 </listitem>
59 </varlistentry>
60 </variablelist>
61 </refsect1>
62</refentry>
63
64<!--
65Local Variables:
66mode: sgml
67sgml-parent-document: "v4l2.sgml"
68indent-tabs-mode: nil
69End:
70-->
diff --git a/Documentation/DocBook/v4l/func-ioctl.xml b/Documentation/DocBook/v4l/func-ioctl.xml
new file mode 100644
index 000000000000..00f9690e1c28
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-ioctl.xml
@@ -0,0 +1,146 @@
1<refentry id="func-ioctl">
2 <refmeta>
3 <refentrytitle>V4L2 ioctl()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-ioctl</refname>
9 <refpurpose>Program a V4L2 device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;sys/ioctl.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>void *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>V4L2 ioctl request code as defined in the <link
38linkend="videodev">videodev.h</link> header file, for example
39VIDIOC_QUERYCAP.</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>argp</parameter></term>
44 <listitem>
45 <para>Pointer to a function parameter, usually a structure.</para>
46 </listitem>
47 </varlistentry>
48 </variablelist>
49 </refsect1>
50
51 <refsect1>
52 <title>Description</title>
53
54 <para>The <function>ioctl()</function> function is used to program
55V4L2 devices. The argument <parameter>fd</parameter> must be an open
56file descriptor. An ioctl <parameter>request</parameter> has encoded
57in it whether the argument is an input, output or read/write
58parameter, and the size of the argument <parameter>argp</parameter> in
59bytes. Macros and defines specifying V4L2 ioctl requests are located
60in the <link linkend="videodev">videodev.h</link> header file.
61Applications should use their own copy, not include the version in the
62kernel sources on the system they compile on. All V4L2 ioctl requests,
63their respective function and parameters are specified in <xref
64 linkend="user-func" />.</para>
65 </refsect1>
66
67 <refsect1>
68 <title>Return Value</title>
69
70 <para>On success the <function>ioctl()</function> function returns
71<returnvalue>0</returnvalue> and does not reset the
72<varname>errno</varname> variable. On failure
73<returnvalue>-1</returnvalue> is returned, when the ioctl takes an
74output or read/write parameter it remains unmodified, and the
75<varname>errno</varname> variable is set appropriately. See below for
76possible error codes. Generic errors like <errorcode>EBADF</errorcode>
77or <errorcode>EFAULT</errorcode> are not listed in the sections
78discussing individual ioctl requests.</para>
79 <para>Note ioctls may return undefined error codes. Since errors
80may have side effects such as a driver reset applications should
81abort on unexpected errors.</para>
82
83 <variablelist>
84 <varlistentry>
85 <term><errorcode>EBADF</errorcode></term>
86 <listitem>
87 <para><parameter>fd</parameter> is not a valid open file
88descriptor.</para>
89 </listitem>
90 </varlistentry>
91 <varlistentry>
92 <term><errorcode>EBUSY</errorcode></term>
93 <listitem>
94 <para>The property cannot be changed right now. Typically
95this error code is returned when I/O is in progress or the driver
96supports multiple opens and another process locked the property.</para>
97 </listitem>
98 </varlistentry>
99 <varlistentry>
100 <term><errorcode>EFAULT</errorcode></term>
101 <listitem>
102 <para><parameter>argp</parameter> references an inaccessible
103memory area.</para>
104 </listitem>
105 </varlistentry>
106 <varlistentry>
107 <term><errorcode>ENOTTY</errorcode></term>
108 <listitem>
109 <para><parameter>fd</parameter> is not associated with a
110character special device.</para>
111 </listitem>
112 </varlistentry>
113 <varlistentry>
114 <term><errorcode>EINVAL</errorcode></term>
115 <listitem>
116 <para>The <parameter>request</parameter> or the data pointed
117to by <parameter>argp</parameter> is not valid. This is a very common
118error code, see the individual ioctl requests listed in <xref
119 linkend="user-func" /> for actual causes.</para>
120 </listitem>
121 </varlistentry>
122 <varlistentry>
123 <term><errorcode>ENOMEM</errorcode></term>
124 <listitem>
125 <para>Not enough physical or virtual memory was available to
126complete the request.</para>
127 </listitem>
128 </varlistentry>
129 <varlistentry>
130 <term><errorcode>ERANGE</errorcode></term>
131 <listitem>
132 <para>The application attempted to set a control with the
133&VIDIOC-S-CTRL; ioctl to a value which is out of bounds.</para>
134 </listitem>
135 </varlistentry>
136 </variablelist>
137 </refsect1>
138</refentry>
139
140<!--
141Local Variables:
142mode: sgml
143sgml-parent-document: "v4l2.sgml"
144indent-tabs-mode: nil
145End:
146-->
diff --git a/Documentation/DocBook/v4l/func-mmap.xml b/Documentation/DocBook/v4l/func-mmap.xml
new file mode 100644
index 000000000000..2e2fc3933aea
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-mmap.xml
@@ -0,0 +1,185 @@
1<refentry id="func-mmap">
2 <refmeta>
3 <refentrytitle>V4L2 mmap()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-mmap</refname>
9 <refpurpose>Map device memory into application address space</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>
15#include &lt;unistd.h&gt;
16#include &lt;sys/mman.h&gt;</funcsynopsisinfo>
17 <funcprototype>
18 <funcdef>void *<function>mmap</function></funcdef>
19 <paramdef>void *<parameter>start</parameter></paramdef>
20 <paramdef>size_t <parameter>length</parameter></paramdef>
21 <paramdef>int <parameter>prot</parameter></paramdef>
22 <paramdef>int <parameter>flags</parameter></paramdef>
23 <paramdef>int <parameter>fd</parameter></paramdef>
24 <paramdef>off_t <parameter>offset</parameter></paramdef>
25 </funcprototype>
26 </funcsynopsis>
27 </refsynopsisdiv>
28
29 <refsect1>
30 <title>Arguments</title>
31 <variablelist>
32 <varlistentry>
33 <term><parameter>start</parameter></term>
34 <listitem>
35 <para>Map the buffer to this address in the
36application's address space. When the <constant>MAP_FIXED</constant>
37flag is specified, <parameter>start</parameter> must be a multiple of the
38pagesize and mmap will fail when the specified address
39cannot be used. Use of this option is discouraged; applications should
40just specify a <constant>NULL</constant> pointer here.</para>
41 </listitem>
42 </varlistentry>
43 <varlistentry>
44 <term><parameter>length</parameter></term>
45 <listitem>
46 <para>Length of the memory area to map. This must be the
47same value as returned by the driver in the &v4l2-buffer;
48<structfield>length</structfield> field.</para>
49 </listitem>
50 </varlistentry>
51 <varlistentry>
52 <term><parameter>prot</parameter></term>
53 <listitem>
54 <para>The <parameter>prot</parameter> argument describes the
55desired memory protection. Regardless of the device type and the
56direction of data exchange it should be set to
57<constant>PROT_READ</constant> | <constant>PROT_WRITE</constant>,
58permitting read and write access to image buffers. Drivers should
59support at least this combination of flags. Note the Linux
60<filename>video-buf</filename> kernel module, which is used by the
61bttv, saa7134, saa7146, cx88 and vivi driver supports only
62<constant>PROT_READ</constant> | <constant>PROT_WRITE</constant>. When
63the driver does not support the desired protection the
64<function>mmap()</function> function fails.</para>
65 <para>Note device memory accesses (&eg; the memory on a
66graphics card with video capturing hardware) may incur a performance
67penalty compared to main memory accesses, or reads may be
68significantly slower than writes or vice versa. Other I/O methods may
69be more efficient in this case.</para>
70 </listitem>
71 </varlistentry>
72 <varlistentry>
73 <term><parameter>flags</parameter></term>
74 <listitem>
75 <para>The <parameter>flags</parameter> parameter
76specifies the type of the mapped object, mapping options and whether
77modifications made to the mapped copy of the page are private to the
78process or are to be shared with other references.</para>
79 <para><constant>MAP_FIXED</constant> requests that the
80driver selects no other address than the one specified. If the
81specified address cannot be used, <function>mmap()</function> will fail. If
82<constant>MAP_FIXED</constant> is specified,
83<parameter>start</parameter> must be a multiple of the pagesize. Use
84of this option is discouraged.</para>
85 <para>One of the <constant>MAP_SHARED</constant> or
86<constant>MAP_PRIVATE</constant> flags must be set.
87<constant>MAP_SHARED</constant> allows applications to share the
88mapped memory with other (&eg; child-) processes. Note the Linux
89<filename>video-buf</filename> module which is used by the bttv,
90saa7134, saa7146, cx88 and vivi driver supports only
91<constant>MAP_SHARED</constant>. <constant>MAP_PRIVATE</constant>
92requests copy-on-write semantics. V4L2 applications should not set the
93<constant>MAP_PRIVATE</constant>, <constant>MAP_DENYWRITE</constant>,
94<constant>MAP_EXECUTABLE</constant> or <constant>MAP_ANON</constant>
95flag.</para>
96 </listitem>
97 </varlistentry>
98 <varlistentry>
99 <term><parameter>fd</parameter></term>
100 <listitem>
101 <para>&fd;</para>
102 </listitem>
103 </varlistentry>
104 <varlistentry>
105 <term><parameter>offset</parameter></term>
106 <listitem>
107 <para>Offset of the buffer in device memory. This must be the
108same value as returned by the driver in the &v4l2-buffer;
109<structfield>m</structfield> union <structfield>offset</structfield> field.</para>
110 </listitem>
111 </varlistentry>
112 </variablelist>
113 </refsect1>
114
115 <refsect1>
116 <title>Description</title>
117
118 <para>The <function>mmap()</function> function asks to map
119<parameter>length</parameter> bytes starting at
120<parameter>offset</parameter> in the memory of the device specified by
121<parameter>fd</parameter> into the application address space,
122preferably at address <parameter>start</parameter>. This latter
123address is a hint only, and is usually specified as 0.</para>
124
125 <para>Suitable length and offset parameters are queried with the
126&VIDIOC-QUERYBUF; ioctl. Buffers must be allocated with the
127&VIDIOC-REQBUFS; ioctl before they can be queried.</para>
128
129 <para>To unmap buffers the &func-munmap; function is used.</para>
130 </refsect1>
131
132 <refsect1>
133 <title>Return Value</title>
134
135 <para>On success <function>mmap()</function> returns a pointer to
136the mapped buffer. On error <constant>MAP_FAILED</constant> (-1) is
137returned, and the <varname>errno</varname> variable is set
138appropriately. Possible error codes are:</para>
139
140 <variablelist>
141 <varlistentry>
142 <term><errorcode>EBADF</errorcode></term>
143 <listitem>
144 <para><parameter>fd</parameter> is not a valid file
145descriptor.</para>
146 </listitem>
147 </varlistentry>
148 <varlistentry>
149 <term><errorcode>EACCES</errorcode></term>
150 <listitem>
151 <para><parameter>fd</parameter> is
152not open for reading and writing.</para>
153 </listitem>
154 </varlistentry>
155 <varlistentry>
156 <term><errorcode>EINVAL</errorcode></term>
157 <listitem>
158 <para>The <parameter>start</parameter> or
159<parameter>length</parameter> or <parameter>offset</parameter> are not
160suitable. (E.&nbsp;g. they are too large, or not aligned on a
161<constant>PAGESIZE</constant> boundary.)</para>
162 <para>The <parameter>flags</parameter> or
163<parameter>prot</parameter> value is not supported.</para>
164 <para>No buffers have been allocated with the
165&VIDIOC-REQBUFS; ioctl.</para>
166 </listitem>
167 </varlistentry>
168 <varlistentry>
169 <term><errorcode>ENOMEM</errorcode></term>
170 <listitem>
171 <para>Not enough physical or virtual memory was available to
172complete the request.</para>
173 </listitem>
174 </varlistentry>
175 </variablelist>
176 </refsect1>
177</refentry>
178
179<!--
180Local Variables:
181mode: sgml
182sgml-parent-document: "v4l2.sgml"
183indent-tabs-mode: nil
184End:
185-->
diff --git a/Documentation/DocBook/v4l/func-munmap.xml b/Documentation/DocBook/v4l/func-munmap.xml
new file mode 100644
index 000000000000..502ed49323b0
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-munmap.xml
@@ -0,0 +1,83 @@
1<refentry id="func-munmap">
2 <refmeta>
3 <refentrytitle>V4L2 munmap()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-munmap</refname>
9 <refpurpose>Unmap device memory</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>
15#include &lt;unistd.h&gt;
16#include &lt;sys/mman.h&gt;</funcsynopsisinfo>
17 <funcprototype>
18 <funcdef>int <function>munmap</function></funcdef>
19 <paramdef>void *<parameter>start</parameter></paramdef>
20 <paramdef>size_t <parameter>length</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 </refsynopsisdiv>
24 <refsect1>
25 <title>Arguments</title>
26 <variablelist>
27 <varlistentry>
28 <term><parameter>start</parameter></term>
29 <listitem>
30 <para>Address of the mapped buffer as returned by the
31&func-mmap; function.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>length</parameter></term>
36 <listitem>
37 <para>Length of the mapped buffer. This must be the same
38value as given to <function>mmap()</function> and returned by the
39driver in the &v4l2-buffer; <structfield>length</structfield>
40field.</para>
41 </listitem>
42 </varlistentry>
43 </variablelist>
44 </refsect1>
45
46 <refsect1>
47 <title>Description</title>
48
49 <para>Unmaps a previously with the &func-mmap; function mapped
50buffer and frees it, if possible. <!-- ? This function (not freeing)
51has no impact on I/O in progress, specifically it does not imply
52&VIDIOC-STREAMOFF; to terminate I/O. Unmapped buffers can still be
53enqueued, dequeued or queried, they are just not accessible by the
54application.--></para>
55 </refsect1>
56
57 <refsect1>
58 <title>Return Value</title>
59
60 <para>On success <function>munmap()</function> returns 0, on
61failure -1 and the <varname>errno</varname> variable is set
62appropriately:</para>
63
64 <variablelist>
65 <varlistentry>
66 <term><errorcode>EINVAL</errorcode></term>
67 <listitem>
68 <para>The <parameter>start</parameter> or
69<parameter>length</parameter> is incorrect, or no buffers have been
70mapped yet.</para>
71 </listitem>
72 </varlistentry>
73 </variablelist>
74 </refsect1>
75</refentry>
76
77<!--
78Local Variables:
79mode: sgml
80sgml-parent-document: "v4l2.sgml"
81indent-tabs-mode: nil
82End:
83-->
diff --git a/Documentation/DocBook/v4l/func-open.xml b/Documentation/DocBook/v4l/func-open.xml
new file mode 100644
index 000000000000..7595d07a8c72
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-open.xml
@@ -0,0 +1,121 @@
1<refentry id="func-open">
2 <refmeta>
3 <refentrytitle>V4L2 open()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-open</refname>
9 <refpurpose>Open a V4L2 device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;fcntl.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>open</function></funcdef>
17 <paramdef>const char *<parameter>device_name</parameter></paramdef>
18 <paramdef>int <parameter>flags</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>device_name</parameter></term>
29 <listitem>
30 <para>Device to be opened.</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>flags</parameter></term>
35 <listitem>
36 <para>Open flags. Access mode must be
37<constant>O_RDWR</constant>. This is just a technicality, input devices
38still support only reading and output devices only writing.</para>
39 <para>When the <constant>O_NONBLOCK</constant> flag is
40given, the read() function and the &VIDIOC-DQBUF; ioctl will return
41the &EAGAIN; when no data is available or no buffer is in the driver
42outgoing queue, otherwise these functions block until data becomes
43available. All V4L2 drivers exchanging data with applications must
44support the <constant>O_NONBLOCK</constant> flag.</para>
45 <para>Other flags have no effect.</para>
46 </listitem>
47 </varlistentry>
48 </variablelist>
49 </refsect1>
50 <refsect1>
51 <title>Description</title>
52
53 <para>To open a V4L2 device applications call
54<function>open()</function> with the desired device name. This
55function has no side effects; all data format parameters, current
56input or output, control values or other properties remain unchanged.
57At the first <function>open()</function> call after loading the driver
58they will be reset to default values, drivers are never in an
59undefined state.</para>
60 </refsect1>
61 <refsect1>
62 <title>Return Value</title>
63
64 <para>On success <function>open</function> returns the new file
65descriptor. On error -1 is returned, and the <varname>errno</varname>
66variable is set appropriately. Possible error codes are:</para>
67
68 <variablelist>
69 <varlistentry>
70 <term><errorcode>EACCES</errorcode></term>
71 <listitem>
72 <para>The caller has no permission to access the
73device.</para>
74 </listitem>
75 </varlistentry>
76 <varlistentry>
77 <term><errorcode>EBUSY</errorcode></term>
78 <listitem>
79 <para>The driver does not support multiple opens and the
80device is already in use.</para>
81 </listitem>
82 </varlistentry>
83 <varlistentry>
84 <term><errorcode>ENXIO</errorcode></term>
85 <listitem>
86 <para>No device corresponding to this device special file
87exists.</para>
88 </listitem>
89 </varlistentry>
90 <varlistentry>
91 <term><errorcode>ENOMEM</errorcode></term>
92 <listitem>
93 <para>Not enough kernel memory was available to complete the
94request.</para>
95 </listitem>
96 </varlistentry>
97 <varlistentry>
98 <term><errorcode>EMFILE</errorcode></term>
99 <listitem>
100 <para>The process already has the maximum number of
101files open.</para>
102 </listitem>
103 </varlistentry>
104 <varlistentry>
105 <term><errorcode>ENFILE</errorcode></term>
106 <listitem>
107 <para>The limit on the total number of files open on the
108system has been reached.</para>
109 </listitem>
110 </varlistentry>
111 </variablelist>
112 </refsect1>
113</refentry>
114
115<!--
116Local Variables:
117mode: sgml
118sgml-parent-document: "v4l2.sgml"
119indent-tabs-mode: nil
120End:
121-->
diff --git a/Documentation/DocBook/v4l/func-poll.xml b/Documentation/DocBook/v4l/func-poll.xml
new file mode 100644
index 000000000000..ec3c718f5963
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-poll.xml
@@ -0,0 +1,127 @@
1<refentry id="func-poll">
2 <refmeta>
3 <refentrytitle>V4L2 poll()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-poll</refname>
9 <refpurpose>Wait for some event on a file descriptor</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;sys/poll.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>int <function>poll</function></funcdef>
17 <paramdef>struct pollfd *<parameter>ufds</parameter></paramdef>
18 <paramdef>unsigned int <parameter>nfds</parameter></paramdef>
19 <paramdef>int <parameter>timeout</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Description</title>
26
27 <para>With the <function>poll()</function> function applications
28can suspend execution until the driver has captured data or is ready
29to accept data for output.</para>
30
31 <para>When streaming I/O has been negotiated this function waits
32until a buffer has been filled or displayed and can be dequeued with
33the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing
34queue of the driver the function returns immediately.</para>
35
36 <para>On success <function>poll()</function> returns the number of
37file descriptors that have been selected (that is, file descriptors
38for which the <structfield>revents</structfield> field of the
39respective <structname>pollfd</structname> structure is non-zero).
40Capture devices set the <constant>POLLIN</constant> and
41<constant>POLLRDNORM</constant> flags in the
42<structfield>revents</structfield> field, output devices the
43<constant>POLLOUT</constant> and <constant>POLLWRNORM</constant>
44flags. When the function timed out it returns a value of zero, on
45failure it returns <returnvalue>-1</returnvalue> and the
46<varname>errno</varname> variable is set appropriately. When the
47application did not call &VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the
48<function>poll()</function> function succeeds, but sets the
49<constant>POLLERR</constant> flag in the
50<structfield>revents</structfield> field.</para>
51
52 <para>When use of the <function>read()</function> function has
53been negotiated and the driver does not capture yet, the
54<function>poll</function> function starts capturing. When that fails
55it returns a <constant>POLLERR</constant> as above. Otherwise it waits
56until data has been captured and can be read. When the driver captures
57continuously (as opposed to, for example, still images) the function
58may return immediately.</para>
59
60 <para>When use of the <function>write()</function> function has
61been negotiated the <function>poll</function> function just waits
62until the driver is ready for a non-blocking
63<function>write()</function> call.</para>
64
65 <para>All drivers implementing the <function>read()</function> or
66<function>write()</function> function or streaming I/O must also
67support the <function>poll()</function> function.</para>
68
69 <para>For more details see the
70<function>poll()</function> manual page.</para>
71 </refsect1>
72
73 <refsect1>
74 <title>Return Value</title>
75
76 <para>On success, <function>poll()</function> returns the number
77structures which have non-zero <structfield>revents</structfield>
78fields, or zero if the call timed out. On error
79<returnvalue>-1</returnvalue> is returned, and the
80<varname>errno</varname> variable is set appropriately:</para>
81
82 <variablelist>
83 <varlistentry>
84 <term><errorcode>EBADF</errorcode></term>
85 <listitem>
86 <para>One or more of the <parameter>ufds</parameter> members
87specify an invalid file descriptor.</para>
88 </listitem>
89 </varlistentry>
90 <varlistentry>
91 <term><errorcode>EBUSY</errorcode></term>
92 <listitem>
93 <para>The driver does not support multiple read or write
94streams and the device is already in use.</para>
95 </listitem>
96 </varlistentry>
97 <varlistentry>
98 <term><errorcode>EFAULT</errorcode></term>
99 <listitem>
100 <para><parameter>ufds</parameter> references an inaccessible
101memory area.</para>
102 </listitem>
103 </varlistentry>
104 <varlistentry>
105 <term><errorcode>EINTR</errorcode></term>
106 <listitem>
107 <para>The call was interrupted by a signal.</para>
108 </listitem>
109 </varlistentry>
110 <varlistentry>
111 <term><errorcode>EINVAL</errorcode></term>
112 <listitem>
113 <para>The <parameter>nfds</parameter> argument is greater
114than <constant>OPEN_MAX</constant>.</para>
115 </listitem>
116 </varlistentry>
117 </variablelist>
118 </refsect1>
119</refentry>
120
121<!--
122Local Variables:
123mode: sgml
124sgml-parent-document: "v4l2.sgml"
125indent-tabs-mode: nil
126End:
127-->
diff --git a/Documentation/DocBook/v4l/func-read.xml b/Documentation/DocBook/v4l/func-read.xml
new file mode 100644
index 000000000000..a5089bf8873d
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-read.xml
@@ -0,0 +1,189 @@
1<refentry id="func-read">
2 <refmeta>
3 <refentrytitle>V4L2 read()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-read</refname>
9 <refpurpose>Read from a V4L2 device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>ssize_t <function>read</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>void *<parameter>buf</parameter></paramdef>
19 <paramdef>size_t <parameter>count</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>buf</parameter></term>
36 <listitem>
37 <para></para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>count</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para><function>read()</function> attempts to read up to
53<parameter>count</parameter> bytes from file descriptor
54<parameter>fd</parameter> into the buffer starting at
55<parameter>buf</parameter>. The layout of the data in the buffer is
56discussed in the respective device interface section, see ##. If <parameter>count</parameter> is zero,
57<function>read()</function> returns zero and has no other results. If
58<parameter>count</parameter> is greater than
59<constant>SSIZE_MAX</constant>, the result is unspecified. Regardless
60of the <parameter>count</parameter> value each
61<function>read()</function> call will provide at most one frame (two
62fields) worth of data.</para>
63
64 <para>By default <function>read()</function> blocks until data
65becomes available. When the <constant>O_NONBLOCK</constant> flag was
66given to the &func-open; function it
67returns immediately with an &EAGAIN; when no data is available. The
68&func-select; or &func-poll; functions
69can always be used to suspend execution until data becomes available. All
70drivers supporting the <function>read()</function> function must also
71support <function>select()</function> and
72<function>poll()</function>.</para>
73
74 <para>Drivers can implement read functionality in different
75ways, using a single or multiple buffers and discarding the oldest or
76newest frames once the internal buffers are filled.</para>
77
78 <para><function>read()</function> never returns a "snapshot" of a
79buffer being filled. Using a single buffer the driver will stop
80capturing when the application starts reading the buffer until the
81read is finished. Thus only the period of the vertical blanking
82interval is available for reading, or the capture rate must fall below
83the nominal frame rate of the video standard.</para>
84
85<para>The behavior of
86<function>read()</function> when called during the active picture
87period or the vertical blanking separating the top and bottom field
88depends on the discarding policy. A driver discarding the oldest
89frames keeps capturing into an internal buffer, continuously
90overwriting the previously, not read frame, and returns the frame
91being received at the time of the <function>read()</function> call as
92soon as it is complete.</para>
93
94 <para>A driver discarding the newest frames stops capturing until
95the next <function>read()</function> call. The frame being received at
96<function>read()</function> time is discarded, returning the following
97frame instead. Again this implies a reduction of the capture rate to
98one half or less of the nominal frame rate. An example of this model
99is the video read mode of the bttv driver, initiating a DMA to user
100memory when <function>read()</function> is called and returning when
101the DMA finished.</para>
102
103 <para>In the multiple buffer model drivers maintain a ring of
104internal buffers, automatically advancing to the next free buffer.
105This allows continuous capturing when the application can empty the
106buffers fast enough. Again, the behavior when the driver runs out of
107free buffers depends on the discarding policy.</para>
108
109 <para>Applications can get and set the number of buffers used
110internally by the driver with the &VIDIOC-G-PARM; and &VIDIOC-S-PARM;
111ioctls. They are optional, however. The discarding policy is not
112reported and cannot be changed. For minimum requirements see <xref
113 linkend="devices" />.</para>
114 </refsect1>
115
116 <refsect1>
117 <title>Return Value</title>
118
119 <para>On success, the number of bytes read is returned. It is not
120an error if this number is smaller than the number of bytes requested,
121or the amount of data required for one frame. This may happen for
122example because <function>read()</function> was interrupted by a
123signal. On error, -1 is returned, and the <varname>errno</varname>
124variable is set appropriately. In this case the next read will start
125at the beginning of a new frame. Possible error codes are:</para>
126
127 <variablelist>
128 <varlistentry>
129 <term><errorcode>EAGAIN</errorcode></term>
130 <listitem>
131 <para>Non-blocking I/O has been selected using
132O_NONBLOCK and no data was immediately available for reading.</para>
133 </listitem>
134 </varlistentry>
135 <varlistentry>
136 <term><errorcode>EBADF</errorcode></term>
137 <listitem>
138 <para><parameter>fd</parameter> is not a valid file
139descriptor or is not open for reading, or the process already has the
140maximum number of files open.</para>
141 </listitem>
142 </varlistentry>
143 <varlistentry>
144 <term><errorcode>EBUSY</errorcode></term>
145 <listitem>
146 <para>The driver does not support multiple read streams and the
147device is already in use.</para>
148 </listitem>
149 </varlistentry>
150 <varlistentry>
151 <term><errorcode>EFAULT</errorcode></term>
152 <listitem>
153 <para><parameter>buf</parameter> references an inaccessible
154memory area.</para>
155 </listitem>
156 </varlistentry>
157 <varlistentry>
158 <term><errorcode>EINTR</errorcode></term>
159 <listitem>
160 <para>The call was interrupted by a signal before any
161data was read.</para>
162 </listitem>
163 </varlistentry>
164 <varlistentry>
165 <term><errorcode>EIO</errorcode></term>
166 <listitem>
167 <para>I/O error. This indicates some hardware problem or a
168failure to communicate with a remote device (USB camera etc.).</para>
169 </listitem>
170 </varlistentry>
171 <varlistentry>
172 <term><errorcode>EINVAL</errorcode></term>
173 <listitem>
174 <para>The <function>read()</function> function is not
175supported by this driver, not on this device, or generally not on this
176type of device.</para>
177 </listitem>
178 </varlistentry>
179 </variablelist>
180 </refsect1>
181</refentry>
182
183<!--
184Local Variables:
185mode: sgml
186sgml-parent-document: "v4l2.sgml"
187indent-tabs-mode: nil
188End:
189-->
diff --git a/Documentation/DocBook/v4l/func-select.xml b/Documentation/DocBook/v4l/func-select.xml
new file mode 100644
index 000000000000..b6713623181f
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-select.xml
@@ -0,0 +1,138 @@
1<refentry id="func-select">
2 <refmeta>
3 <refentrytitle>V4L2 select()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-select</refname>
9 <refpurpose>Synchronous I/O multiplexing</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>
15#include &lt;sys/time.h&gt;
16#include &lt;sys/types.h&gt;
17#include &lt;unistd.h&gt;</funcsynopsisinfo>
18 <funcprototype>
19 <funcdef>int <function>select</function></funcdef>
20 <paramdef>int <parameter>nfds</parameter></paramdef>
21 <paramdef>fd_set *<parameter>readfds</parameter></paramdef>
22 <paramdef>fd_set *<parameter>writefds</parameter></paramdef>
23 <paramdef>fd_set *<parameter>exceptfds</parameter></paramdef>
24 <paramdef>struct timeval *<parameter>timeout</parameter></paramdef>
25 </funcprototype>
26 </funcsynopsis>
27 </refsynopsisdiv>
28
29 <refsect1>
30 <title>Description</title>
31
32 <para>With the <function>select()</function> function applications
33can suspend execution until the driver has captured data or is ready
34to accept data for output.</para>
35
36 <para>When streaming I/O has been negotiated this function waits
37until a buffer has been filled or displayed and can be dequeued with
38the &VIDIOC-DQBUF; ioctl. When buffers are already in the outgoing
39queue of the driver the function returns immediately.</para>
40
41 <para>On success <function>select()</function> returns the total
42number of bits set in the <structname>fd_set</structname>s. When the
43function timed out it returns a value of zero. On failure it returns
44<returnvalue>-1</returnvalue> and the <varname>errno</varname>
45variable is set appropriately. When the application did not call
46&VIDIOC-QBUF; or &VIDIOC-STREAMON; yet the
47<function>select()</function> function succeeds, setting the bit of
48the file descriptor in <parameter>readfds</parameter> or
49<parameter>writefds</parameter>, but subsequent &VIDIOC-DQBUF; calls
50will fail.<footnote><para>The Linux kernel implements
51<function>select()</function> like the &func-poll; function, but
52<function>select()</function> cannot return a
53<constant>POLLERR</constant>.</para>
54 </footnote></para>
55
56 <para>When use of the <function>read()</function> function has
57been negotiated and the driver does not capture yet, the
58<function>select()</function> function starts capturing. When that
59fails, <function>select()</function> returns successful and a
60subsequent <function>read()</function> call, which also attempts to
61start capturing, will return an appropriate error code. When the
62driver captures continuously (as opposed to, for example, still
63images) and data is already available the
64<function>select()</function> function returns immediately.</para>
65
66 <para>When use of the <function>write()</function> function has
67been negotiated the <function>select()</function> function just waits
68until the driver is ready for a non-blocking
69<function>write()</function> call.</para>
70
71 <para>All drivers implementing the <function>read()</function> or
72<function>write()</function> function or streaming I/O must also
73support the <function>select()</function> function.</para>
74
75 <para>For more details see the <function>select()</function>
76manual page.</para>
77
78 </refsect1>
79
80 <refsect1>
81 <title>Return Value</title>
82
83 <para>On success, <function>select()</function> returns the number
84of descriptors contained in the three returned descriptor sets, which
85will be zero if the timeout expired. On error
86<returnvalue>-1</returnvalue> is returned, and the
87<varname>errno</varname> variable is set appropriately; the sets and
88<parameter>timeout</parameter> are undefined. Possible error codes
89are:</para>
90
91 <variablelist>
92 <varlistentry>
93 <term><errorcode>EBADF</errorcode></term>
94 <listitem>
95 <para>One or more of the file descriptor sets specified a
96file descriptor that is not open.</para>
97 </listitem>
98 </varlistentry>
99 <varlistentry>
100 <term><errorcode>EBUSY</errorcode></term>
101 <listitem>
102 <para>The driver does not support multiple read or write
103streams and the device is already in use.</para>
104 </listitem>
105 </varlistentry>
106 <varlistentry>
107 <term><errorcode>EFAULT</errorcode></term>
108 <listitem>
109 <para>The <parameter>readfds</parameter>,
110<parameter>writefds</parameter>, <parameter>exceptfds</parameter> or
111<parameter>timeout</parameter> pointer references an inaccessible memory
112area.</para>
113 </listitem>
114 </varlistentry>
115 <varlistentry>
116 <term><errorcode>EINTR</errorcode></term>
117 <listitem>
118 <para>The call was interrupted by a signal.</para>
119 </listitem>
120 </varlistentry>
121 <varlistentry>
122 <term><errorcode>EINVAL</errorcode></term>
123 <listitem>
124 <para>The <parameter>nfds</parameter> argument is less than
125zero or greater than <constant>FD_SETSIZE</constant>.</para>
126 </listitem>
127 </varlistentry>
128 </variablelist>
129 </refsect1>
130</refentry>
131
132<!--
133Local Variables:
134mode: sgml
135sgml-parent-document: "v4l2.sgml"
136indent-tabs-mode: nil
137End:
138-->
diff --git a/Documentation/DocBook/v4l/func-write.xml b/Documentation/DocBook/v4l/func-write.xml
new file mode 100644
index 000000000000..2c09c09371c3
--- /dev/null
+++ b/Documentation/DocBook/v4l/func-write.xml
@@ -0,0 +1,136 @@
1<refentry id="func-write">
2 <refmeta>
3 <refentrytitle>V4L2 write()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>v4l2-write</refname>
9 <refpurpose>Write to a V4L2 device</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcsynopsisinfo>#include &lt;unistd.h&gt;</funcsynopsisinfo>
15 <funcprototype>
16 <funcdef>ssize_t <function>write</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>void *<parameter>buf</parameter></paramdef>
19 <paramdef>size_t <parameter>count</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>buf</parameter></term>
36 <listitem>
37 <para></para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>count</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para><function>write()</function> writes up to
53<parameter>count</parameter> bytes to the device referenced by the
54file descriptor <parameter>fd</parameter> from the buffer starting at
55<parameter>buf</parameter>. When the hardware outputs are not active
56yet, this function enables them. When <parameter>count</parameter> is
57zero, <function>write()</function> returns
58<returnvalue>0</returnvalue> without any other effect.</para>
59
60 <para>When the application does not provide more data in time, the
61previous video frame, raw VBI image, sliced VPS or WSS data is
62displayed again. Sliced Teletext or Closed Caption data is not
63repeated, the driver inserts a blank line instead.</para>
64 </refsect1>
65
66 <refsect1>
67 <title>Return Value</title>
68
69 <para>On success, the number of bytes written are returned. Zero
70indicates nothing was written. On error, <returnvalue>-1</returnvalue>
71is returned, and the <varname>errno</varname> variable is set
72appropriately. In this case the next write will start at the beginning
73of a new frame. Possible error codes are:</para>
74
75 <variablelist>
76 <varlistentry>
77 <term><errorcode>EAGAIN</errorcode></term>
78 <listitem>
79 <para>Non-blocking I/O has been selected using the <link
80linkend="func-open"><constant>O_NONBLOCK</constant></link> flag and no
81buffer space was available to write the data immediately.</para>
82 </listitem>
83 </varlistentry>
84 <varlistentry>
85 <term><errorcode>EBADF</errorcode></term>
86 <listitem>
87 <para><parameter>fd</parameter> is not a valid file
88descriptor or is not open for writing.</para>
89 </listitem>
90 </varlistentry>
91 <varlistentry>
92 <term><errorcode>EBUSY</errorcode></term>
93 <listitem>
94 <para>The driver does not support multiple write streams and the
95device is already in use.</para>
96 </listitem>
97 </varlistentry>
98 <varlistentry>
99 <term><errorcode>EFAULT</errorcode></term>
100 <listitem>
101 <para><parameter>buf</parameter> references an inaccessible
102memory area.</para>
103 </listitem>
104 </varlistentry>
105 <varlistentry>
106 <term><errorcode>EINTR</errorcode></term>
107 <listitem>
108 <para>The call was interrupted by a signal before any
109data was written.</para>
110 </listitem>
111 </varlistentry>
112 <varlistentry>
113 <term><errorcode>EIO</errorcode></term>
114 <listitem>
115 <para>I/O error. This indicates some hardware problem.</para>
116 </listitem>
117 </varlistentry>
118 <varlistentry>
119 <term><errorcode>EINVAL</errorcode></term>
120 <listitem>
121 <para>The <function>write()</function> function is not
122supported by this driver, not on this device, or generally not on this
123type of device.</para>
124 </listitem>
125 </varlistentry>
126 </variablelist>
127 </refsect1>
128</refentry>
129
130<!--
131Local Variables:
132mode: sgml
133sgml-parent-document: "v4l2.sgml"
134indent-tabs-mode: nil
135End:
136-->
diff --git a/Documentation/DocBook/v4l/io.xml b/Documentation/DocBook/v4l/io.xml
new file mode 100644
index 000000000000..f92f24323b2a
--- /dev/null
+++ b/Documentation/DocBook/v4l/io.xml
@@ -0,0 +1,1073 @@
1 <title>Input/Output</title>
2
3 <para>The V4L2 API defines several different methods to read from or
4write to a device. All drivers exchanging data with applications must
5support at least one of them.</para>
6
7 <para>The classic I/O method using the <function>read()</function>
8and <function>write()</function> function is automatically selected
9after opening a V4L2 device. When the driver does not support this
10method attempts to read or write will fail at any time.</para>
11
12 <para>Other methods must be negotiated. To select the streaming I/O
13method with memory mapped or user buffers applications call the
14&VIDIOC-REQBUFS; ioctl. The asynchronous I/O method is not defined
15yet.</para>
16
17 <para>Video overlay can be considered another I/O method, although
18the application does not directly receive the image data. It is
19selected by initiating video overlay with the &VIDIOC-S-FMT; ioctl.
20For more information see <xref linkend="overlay" />.</para>
21
22 <para>Generally exactly one I/O method, including overlay, is
23associated with each file descriptor. The only exceptions are
24applications not exchanging data with a driver ("panel applications",
25see <xref linkend="open" />) and drivers permitting simultaneous video capturing
26and overlay using the same file descriptor, for compatibility with V4L
27and earlier versions of V4L2.</para>
28
29 <para><constant>VIDIOC_S_FMT</constant> and
30<constant>VIDIOC_REQBUFS</constant> would permit this to some degree,
31but for simplicity drivers need not support switching the I/O method
32(after first switching away from read/write) other than by closing
33and reopening the device.</para>
34
35 <para>The following sections describe the various I/O methods in
36more detail.</para>
37
38 <section id="rw">
39 <title>Read/Write</title>
40
41 <para>Input and output devices support the
42<function>read()</function> and <function>write()</function> function,
43respectively, when the <constant>V4L2_CAP_READWRITE</constant> flag in
44the <structfield>capabilities</structfield> field of &v4l2-capability;
45returned by the &VIDIOC-QUERYCAP; ioctl is set.</para>
46
47 <para>Drivers may need the CPU to copy the data, but they may also
48support DMA to or from user memory, so this I/O method is not
49necessarily less efficient than other methods merely exchanging buffer
50pointers. It is considered inferior though because no meta-information
51like frame counters or timestamps are passed. This information is
52necessary to recognize frame dropping and to synchronize with other
53data streams. However this is also the simplest I/O method, requiring
54little or no setup to exchange data. It permits command line stunts
55like this (the <application>vidctrl</application> tool is
56fictitious):</para>
57
58 <informalexample>
59 <screen>
60&gt; vidctrl /dev/video --input=0 --format=YUYV --size=352x288
61&gt; dd if=/dev/video of=myimage.422 bs=202752 count=1
62</screen>
63 </informalexample>
64
65 <para>To read from the device applications use the
66&func-read; function, to write the &func-write; function.
67Drivers must implement one I/O method if they
68exchange data with applications, but it need not be this.<footnote>
69 <para>It would be desirable if applications could depend on
70drivers supporting all I/O interfaces, but as much as the complex
71memory mapping I/O can be inadequate for some devices we have no
72reason to require this interface, which is most useful for simple
73applications capturing still images.</para>
74 </footnote> When reading or writing is supported, the driver
75must also support the &func-select; and &func-poll;
76function.<footnote>
77 <para>At the driver level <function>select()</function> and
78<function>poll()</function> are the same, and
79<function>select()</function> is too important to be optional.</para>
80 </footnote></para>
81 </section>
82
83 <section id="mmap">
84 <title>Streaming I/O (Memory Mapping)</title>
85
86 <para>Input and output devices support this I/O method when the
87<constant>V4L2_CAP_STREAMING</constant> flag in the
88<structfield>capabilities</structfield> field of &v4l2-capability;
89returned by the &VIDIOC-QUERYCAP; ioctl is set. There are two
90streaming methods, to determine if the memory mapping flavor is
91supported applications must call the &VIDIOC-REQBUFS; ioctl.</para>
92
93 <para>Streaming is an I/O method where only pointers to buffers
94are exchanged between application and driver, the data itself is not
95copied. Memory mapping is primarily intended to map buffers in device
96memory into the application's address space. Device memory can be for
97example the video memory on a graphics card with a video capture
98add-on. However, being the most efficient I/O method available for a
99long time, many other drivers support streaming as well, allocating
100buffers in DMA-able main memory.</para>
101
102 <para>A driver can support many sets of buffers. Each set is
103identified by a unique buffer type value. The sets are independent and
104each set can hold a different type of data. To access different sets
105at the same time different file descriptors must be used.<footnote>
106 <para>One could use one file descriptor and set the buffer
107type field accordingly when calling &VIDIOC-QBUF; etc., but it makes
108the <function>select()</function> function ambiguous. We also like the
109clean approach of one file descriptor per logical stream. Video
110overlay for example is also a logical stream, although the CPU is not
111needed for continuous operation.</para>
112 </footnote></para>
113
114 <para>To allocate device buffers applications call the
115&VIDIOC-REQBUFS; ioctl with the desired number of buffers and buffer
116type, for example <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>.
117This ioctl can also be used to change the number of buffers or to free
118the allocated memory, provided none of the buffers are still
119mapped.</para>
120
121 <para>Before applications can access the buffers they must map
122them into their address space with the &func-mmap; function. The
123location of the buffers in device memory can be determined with the
124&VIDIOC-QUERYBUF; ioctl. The <structfield>m.offset</structfield> and
125<structfield>length</structfield> returned in a &v4l2-buffer; are
126passed as sixth and second parameter to the
127<function>mmap()</function> function. The offset and length values
128must not be modified. Remember the buffers are allocated in physical
129memory, as opposed to virtual memory which can be swapped out to disk.
130Applications should free the buffers as soon as possible with the
131&func-munmap; function.</para>
132
133 <example>
134 <title>Mapping buffers</title>
135
136 <programlisting>
137&v4l2-requestbuffers; reqbuf;
138struct {
139 void *start;
140 size_t length;
141} *buffers;
142unsigned int i;
143
144memset (&amp;reqbuf, 0, sizeof (reqbuf));
145reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
146reqbuf.memory = V4L2_MEMORY_MMAP;
147reqbuf.count = 20;
148
149if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) {
150 if (errno == EINVAL)
151 printf ("Video capturing or mmap-streaming is not supported\n");
152 else
153 perror ("VIDIOC_REQBUFS");
154
155 exit (EXIT_FAILURE);
156}
157
158/* We want at least five buffers. */
159
160if (reqbuf.count &lt; 5) {
161 /* You may need to free the buffers here. */
162 printf ("Not enough buffer memory\n");
163 exit (EXIT_FAILURE);
164}
165
166buffers = calloc (reqbuf.count, sizeof (*buffers));
167assert (buffers != NULL);
168
169for (i = 0; i &lt; reqbuf.count; i++) {
170 &v4l2-buffer; buffer;
171
172 memset (&amp;buffer, 0, sizeof (buffer));
173 buffer.type = reqbuf.type;
174 buffer.memory = V4L2_MEMORY_MMAP;
175 buffer.index = i;
176
177 if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) {
178 perror ("VIDIOC_QUERYBUF");
179 exit (EXIT_FAILURE);
180 }
181
182 buffers[i].length = buffer.length; /* remember for munmap() */
183
184 buffers[i].start = mmap (NULL, buffer.length,
185 PROT_READ | PROT_WRITE, /* recommended */
186 MAP_SHARED, /* recommended */
187 fd, buffer.m.offset);
188
189 if (MAP_FAILED == buffers[i].start) {
190 /* If you do not exit here you should unmap() and free()
191 the buffers mapped so far. */
192 perror ("mmap");
193 exit (EXIT_FAILURE);
194 }
195}
196
197/* Cleanup. */
198
199for (i = 0; i &lt; reqbuf.count; i++)
200 munmap (buffers[i].start, buffers[i].length);
201 </programlisting>
202 </example>
203
204 <para>Conceptually streaming drivers maintain two buffer queues, an incoming
205and an outgoing queue. They separate the synchronous capture or output
206operation locked to a video clock from the application which is
207subject to random disk or network delays and preemption by
208other processes, thereby reducing the probability of data loss.
209The queues are organized as FIFOs, buffers will be
210output in the order enqueued in the incoming FIFO, and were
211captured in the order dequeued from the outgoing FIFO.</para>
212
213 <para>The driver may require a minimum number of buffers enqueued
214at all times to function, apart of this no limit exists on the number
215of buffers applications can enqueue in advance, or dequeue and
216process. They can also enqueue in a different order than buffers have
217been dequeued, and the driver can <emphasis>fill</emphasis> enqueued
218<emphasis>empty</emphasis> buffers in any order. <footnote>
219 <para>Random enqueue order permits applications processing
220images out of order (such as video codecs) to return buffers earlier,
221reducing the probability of data loss. Random fill order allows
222drivers to reuse buffers on a LIFO-basis, taking advantage of caches
223holding scatter-gather lists and the like.</para>
224 </footnote> The index number of a buffer (&v4l2-buffer;
225<structfield>index</structfield>) plays no role here, it only
226identifies the buffer.</para>
227
228 <para>Initially all mapped buffers are in dequeued state,
229inaccessible by the driver. For capturing applications it is customary
230to first enqueue all mapped buffers, then to start capturing and enter
231the read loop. Here the application waits until a filled buffer can be
232dequeued, and re-enqueues the buffer when the data is no longer
233needed. Output applications fill and enqueue buffers, when enough
234buffers are stacked up the output is started with
235<constant>VIDIOC_STREAMON</constant>. In the write loop, when
236the application runs out of free buffers, it must wait until an empty
237buffer can be dequeued and reused.</para>
238
239 <para>To enqueue and dequeue a buffer applications use the
240&VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl. The status of a buffer being
241mapped, enqueued, full or empty can be determined at any time using the
242&VIDIOC-QUERYBUF; ioctl. Two methods exist to suspend execution of the
243application until one or more buffers can be dequeued. By default
244<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
245outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
246given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
247returns immediately with an &EAGAIN; when no buffer is available. The
248&func-select; or &func-poll; function are always available.</para>
249
250 <para>To start and stop capturing or output applications call the
251&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
252<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both
253queues as a side effect. Since there is no notion of doing anything
254"now" on a multitasking system, if an application needs to synchronize
255with another event it should examine the &v4l2-buffer;
256<structfield>timestamp</structfield> of captured buffers, or set the
257field before enqueuing buffers for output.</para>
258
259 <para>Drivers implementing memory mapping I/O must
260support the <constant>VIDIOC_REQBUFS</constant>,
261<constant>VIDIOC_QUERYBUF</constant>,
262<constant>VIDIOC_QBUF</constant>, <constant>VIDIOC_DQBUF</constant>,
263<constant>VIDIOC_STREAMON</constant> and
264<constant>VIDIOC_STREAMOFF</constant> ioctl, the
265<function>mmap()</function>, <function>munmap()</function>,
266<function>select()</function> and <function>poll()</function>
267function.<footnote>
268 <para>At the driver level <function>select()</function> and
269<function>poll()</function> are the same, and
270<function>select()</function> is too important to be optional. The
271rest should be evident.</para>
272 </footnote></para>
273
274 <para>[capture example]</para>
275
276 </section>
277
278 <section id="userp">
279 <title>Streaming I/O (User Pointers)</title>
280
281 <para>Input and output devices support this I/O method when the
282<constant>V4L2_CAP_STREAMING</constant> flag in the
283<structfield>capabilities</structfield> field of &v4l2-capability;
284returned by the &VIDIOC-QUERYCAP; ioctl is set. If the particular user
285pointer method (not only memory mapping) is supported must be
286determined by calling the &VIDIOC-REQBUFS; ioctl.</para>
287
288 <para>This I/O method combines advantages of the read/write and
289memory mapping methods. Buffers are allocated by the application
290itself, and can reside for example in virtual or shared memory. Only
291pointers to data are exchanged, these pointers and meta-information
292are passed in &v4l2-buffer;. The driver must be switched
293into user pointer I/O mode by calling the &VIDIOC-REQBUFS; with the
294desired buffer type. No buffers are allocated beforehands,
295consequently they are not indexed and cannot be queried like mapped
296buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para>
297
298 <example>
299 <title>Initiating streaming I/O with user pointers</title>
300
301 <programlisting>
302&v4l2-requestbuffers; reqbuf;
303
304memset (&amp;reqbuf, 0, sizeof (reqbuf));
305reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
306reqbuf.memory = V4L2_MEMORY_USERPTR;
307
308if (ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
309 if (errno == EINVAL)
310 printf ("Video capturing or user pointer streaming is not supported\n");
311 else
312 perror ("VIDIOC_REQBUFS");
313
314 exit (EXIT_FAILURE);
315}
316 </programlisting>
317 </example>
318
319 <para>Buffer addresses and sizes are passed on the fly with the
320&VIDIOC-QBUF; ioctl. Although buffers are commonly cycled,
321applications can pass different addresses and sizes at each
322<constant>VIDIOC_QBUF</constant> call. If required by the hardware the
323driver swaps memory pages within physical memory to create a
324continuous area of memory. This happens transparently to the
325application in the virtual memory subsystem of the kernel. When buffer
326pages have been swapped out to disk they are brought back and finally
327locked in physical memory for DMA.<footnote>
328 <para>We expect that frequently used buffers are typically not
329swapped out. Anyway, the process of swapping, locking or generating
330scatter-gather lists may be time consuming. The delay can be masked by
331the depth of the incoming buffer queue, and perhaps by maintaining
332caches assuming a buffer will be soon enqueued again. On the other
333hand, to optimize memory usage drivers can limit the number of buffers
334locked in advance and recycle the most recently used buffers first. Of
335course, the pages of empty buffers in the incoming queue need not be
336saved to disk. Output buffers must be saved on the incoming and
337outgoing queue because an application may share them with other
338processes.</para>
339 </footnote></para>
340
341 <para>Filled or displayed buffers are dequeued with the
342&VIDIOC-DQBUF; ioctl. The driver can unlock the memory pages at any
343time between the completion of the DMA and this ioctl. The memory is
344also unlocked when &VIDIOC-STREAMOFF; is called, &VIDIOC-REQBUFS;, or
345when the device is closed. Applications must take care not to free
346buffers without dequeuing. For once, the buffers remain locked until
347further, wasting physical memory. Second the driver will not be
348notified when the memory is returned to the application's free list
349and subsequently reused for other purposes, possibly completing the
350requested DMA and overwriting valuable data.</para>
351
352 <para>For capturing applications it is customary to enqueue a
353number of empty buffers, to start capturing and enter the read loop.
354Here the application waits until a filled buffer can be dequeued, and
355re-enqueues the buffer when the data is no longer needed. Output
356applications fill and enqueue buffers, when enough buffers are stacked
357up output is started. In the write loop, when the application
358runs out of free buffers it must wait until an empty buffer can be
359dequeued and reused. Two methods exist to suspend execution of the
360application until one or more buffers can be dequeued. By default
361<constant>VIDIOC_DQBUF</constant> blocks when no buffer is in the
362outgoing queue. When the <constant>O_NONBLOCK</constant> flag was
363given to the &func-open; function, <constant>VIDIOC_DQBUF</constant>
364returns immediately with an &EAGAIN; when no buffer is available. The
365&func-select; or &func-poll; function are always available.</para>
366
367 <para>To start and stop capturing or output applications call the
368&VIDIOC-STREAMON; and &VIDIOC-STREAMOFF; ioctl. Note
369<constant>VIDIOC_STREAMOFF</constant> removes all buffers from both
370queues and unlocks all buffers as a side effect. Since there is no
371notion of doing anything "now" on a multitasking system, if an
372application needs to synchronize with another event it should examine
373the &v4l2-buffer; <structfield>timestamp</structfield> of captured
374buffers, or set the field before enqueuing buffers for output.</para>
375
376 <para>Drivers implementing user pointer I/O must
377support the <constant>VIDIOC_REQBUFS</constant>,
378<constant>VIDIOC_QBUF</constant>, <constant>VIDIOC_DQBUF</constant>,
379<constant>VIDIOC_STREAMON</constant> and
380<constant>VIDIOC_STREAMOFF</constant> ioctl, the
381<function>select()</function> and <function>poll()</function> function.<footnote>
382 <para>At the driver level <function>select()</function> and
383<function>poll()</function> are the same, and
384<function>select()</function> is too important to be optional. The
385rest should be evident.</para>
386 </footnote></para>
387 </section>
388
389 <section id="async">
390 <title>Asynchronous I/O</title>
391
392 <para>This method is not defined yet.</para>
393 </section>
394
395 <section id="buffer">
396 <title>Buffers</title>
397
398 <para>A buffer contains data exchanged by application and
399driver using one of the Streaming I/O methods. Only pointers to
400buffers are exchanged, the data itself is not copied. These pointers,
401together with meta-information like timestamps or field parity, are
402stored in a struct <structname>v4l2_buffer</structname>, argument to
403the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.</para>
404
405 <para>Nominally timestamps refer to the first data byte transmitted.
406In practice however the wide range of hardware covered by the V4L2 API
407limits timestamp accuracy. Often an interrupt routine will
408sample the system clock shortly after the field or frame was stored
409completely in memory. So applications must expect a constant
410difference up to one field or frame period plus a small (few scan
411lines) random error. The delay and error can be much
412larger due to compression or transmission over an external bus when
413the frames are not properly stamped by the sender. This is frequently
414the case with USB cameras. Here timestamps refer to the instant the
415field or frame was received by the driver, not the capture time. These
416devices identify by not enumerating any video standards, see <xref
417linkend="standard" />.</para>
418
419 <para>Similar limitations apply to output timestamps. Typically
420the video hardware locks to a clock controlling the video timing, the
421horizontal and vertical synchronization pulses. At some point in the
422line sequence, possibly the vertical blanking, an interrupt routine
423samples the system clock, compares against the timestamp and programs
424the hardware to repeat the previous field or frame, or to display the
425buffer contents.</para>
426
427 <para>Apart of limitations of the video device and natural
428inaccuracies of all clocks, it should be noted system time itself is
429not perfectly stable. It can be affected by power saving cycles,
430warped to insert leap seconds, or even turned back or forth by the
431system administrator affecting long term measurements. <footnote>
432 <para>Since no other Linux multimedia
433API supports unadjusted time it would be foolish to introduce here. We
434must use a universally supported clock to synchronize different media,
435hence time of day.</para>
436 </footnote></para>
437
438 <table frame="none" pgwide="1" id="v4l2-buffer">
439 <title>struct <structname>v4l2_buffer</structname></title>
440 <tgroup cols="4">
441 &cs-ustr;
442 <tbody valign="top">
443 <row>
444 <entry>__u32</entry>
445 <entry><structfield>index</structfield></entry>
446 <entry></entry>
447 <entry>Number of the buffer, set by the application. This
448field is only used for <link linkend="mmap">memory mapping</link> I/O
449and can range from zero to the number of buffers allocated
450with the &VIDIOC-REQBUFS; ioctl (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.</entry>
451 </row>
452 <row>
453 <entry>&v4l2-buf-type;</entry>
454 <entry><structfield>type</structfield></entry>
455 <entry></entry>
456 <entry>Type of the buffer, same as &v4l2-format;
457<structfield>type</structfield> or &v4l2-requestbuffers;
458<structfield>type</structfield>, set by the application.</entry>
459 </row>
460 <row>
461 <entry>__u32</entry>
462 <entry><structfield>bytesused</structfield></entry>
463 <entry></entry>
464 <entry>The number of bytes occupied by the data in the
465buffer. It depends on the negotiated data format and may change with
466each buffer for compressed variable size data like JPEG images.
467Drivers must set this field when <structfield>type</structfield>
468refers to an input stream, applications when an output stream.</entry>
469 </row>
470 <row>
471 <entry>__u32</entry>
472 <entry><structfield>flags</structfield></entry>
473 <entry></entry>
474 <entry>Flags set by the application or driver, see <xref
475linkend="buffer-flags" />.</entry>
476 </row>
477 <row>
478 <entry>&v4l2-field;</entry>
479 <entry><structfield>field</structfield></entry>
480 <entry></entry>
481 <entry>Indicates the field order of the image in the
482buffer, see <xref linkend="v4l2-field" />. This field is not used when
483the buffer contains VBI data. Drivers must set it when
484<structfield>type</structfield> refers to an input stream,
485applications when an output stream.</entry>
486 </row>
487 <row>
488 <entry>struct timeval</entry>
489 <entry><structfield>timestamp</structfield></entry>
490 <entry></entry>
491 <entry><para>For input streams this is the
492system time (as returned by the <function>gettimeofday()</function>
493function) when the first data byte was captured. For output streams
494the data will not be displayed before this time, secondary to the
495nominal frame rate determined by the current video standard in
496enqueued order. Applications can for example zero this field to
497display frames as soon as possible. The driver stores the time at
498which the first data byte was actually sent out in the
499<structfield>timestamp</structfield> field. This permits
500applications to monitor the drift between the video and system
501clock.</para></entry>
502 </row>
503 <row>
504 <entry>&v4l2-timecode;</entry>
505 <entry><structfield>timecode</structfield></entry>
506 <entry></entry>
507 <entry>When <structfield>type</structfield> is
508<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and the
509<constant>V4L2_BUF_FLAG_TIMECODE</constant> flag is set in
510<structfield>flags</structfield>, this structure contains a frame
511timecode. In <link linkend="v4l2-field">V4L2_FIELD_ALTERNATE</link>
512mode the top and bottom field contain the same timecode.
513Timecodes are intended to help video editing and are typically recorded on
514video tapes, but also embedded in compressed formats like MPEG. This
515field is independent of the <structfield>timestamp</structfield> and
516<structfield>sequence</structfield> fields.</entry>
517 </row>
518 <row>
519 <entry>__u32</entry>
520 <entry><structfield>sequence</structfield></entry>
521 <entry></entry>
522 <entry>Set by the driver, counting the frames in the
523sequence.</entry>
524 </row>
525 <row>
526 <entry spanname="hspan"><para>In <link
527linkend="v4l2-field">V4L2_FIELD_ALTERNATE</link> mode the top and
528bottom field have the same sequence number. The count starts at zero
529and includes dropped or repeated frames. A dropped frame was received
530by an input device but could not be stored due to lack of free buffer
531space. A repeated frame was displayed again by an output device
532because the application did not pass new data in
533time.</para><para>Note this may count the frames received
534e.g. over USB, without taking into account the frames dropped by the
535remote hardware due to limited compression throughput or bus
536bandwidth. These devices identify by not enumerating any video
537standards, see <xref linkend="standard" />.</para></entry>
538 </row>
539 <row>
540 <entry>&v4l2-memory;</entry>
541 <entry><structfield>memory</structfield></entry>
542 <entry></entry>
543 <entry>This field must be set by applications and/or drivers
544in accordance with the selected I/O method.</entry>
545 </row>
546 <row>
547 <entry>union</entry>
548 <entry><structfield>m</structfield></entry>
549 </row>
550 <row>
551 <entry></entry>
552 <entry>__u32</entry>
553 <entry><structfield>offset</structfield></entry>
554 <entry>When <structfield>memory</structfield> is
555<constant>V4L2_MEMORY_MMAP</constant> this is the offset of the buffer
556from the start of the device memory. The value is returned by the
557driver and apart of serving as parameter to the &func-mmap; function
558not useful for applications. See <xref linkend="mmap" /> for details.</entry>
559 </row>
560 <row>
561 <entry></entry>
562 <entry>unsigned long</entry>
563 <entry><structfield>userptr</structfield></entry>
564 <entry>When <structfield>memory</structfield> is
565<constant>V4L2_MEMORY_USERPTR</constant> this is a pointer to the
566buffer (casted to unsigned long type) in virtual memory, set by the
567application. See <xref linkend="userp" /> for details.</entry>
568 </row>
569 <row>
570 <entry>__u32</entry>
571 <entry><structfield>length</structfield></entry>
572 <entry></entry>
573 <entry>Size of the buffer (not the payload) in bytes.</entry>
574 </row>
575 <row>
576 <entry>__u32</entry>
577 <entry><structfield>input</structfield></entry>
578 <entry></entry>
579 <entry>Some video capture drivers support rapid and
580synchronous video input changes, a function useful for example in
581video surveillance applications. For this purpose applications set the
582<constant>V4L2_BUF_FLAG_INPUT</constant> flag, and this field to the
583number of a video input as in &v4l2-input; field
584<structfield>index</structfield>.</entry>
585 </row>
586 <row>
587 <entry>__u32</entry>
588 <entry><structfield>reserved</structfield></entry>
589 <entry></entry>
590 <entry>A place holder for future extensions and custom
591(driver defined) buffer types
592<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
593 </row>
594 </tbody>
595 </tgroup>
596 </table>
597
598 <table frame="none" pgwide="1" id="v4l2-buf-type">
599 <title>enum v4l2_buf_type</title>
600 <tgroup cols="3">
601 &cs-def;
602 <tbody valign="top">
603 <row>
604 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
605 <entry>1</entry>
606 <entry>Buffer of a video capture stream, see <xref
607 linkend="capture" />.</entry>
608 </row>
609 <row>
610 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
611 <entry>2</entry>
612 <entry>Buffer of a video output stream, see <xref
613 linkend="output" />.</entry>
614 </row>
615 <row>
616 <entry><constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant></entry>
617 <entry>3</entry>
618 <entry>Buffer for video overlay, see <xref linkend="overlay" />.</entry>
619 </row>
620 <row>
621 <entry><constant>V4L2_BUF_TYPE_VBI_CAPTURE</constant></entry>
622 <entry>4</entry>
623 <entry>Buffer of a raw VBI capture stream, see <xref
624 linkend="raw-vbi" />.</entry>
625 </row>
626 <row>
627 <entry><constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant></entry>
628 <entry>5</entry>
629 <entry>Buffer of a raw VBI output stream, see <xref
630 linkend="raw-vbi" />.</entry>
631 </row>
632 <row>
633 <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant></entry>
634 <entry>6</entry>
635 <entry>Buffer of a sliced VBI capture stream, see <xref
636 linkend="sliced" />.</entry>
637 </row>
638 <row>
639 <entry><constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant></entry>
640 <entry>7</entry>
641 <entry>Buffer of a sliced VBI output stream, see <xref
642 linkend="sliced" />.</entry>
643 </row>
644 <row>
645 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY</constant></entry>
646 <entry>8</entry>
647 <entry>Buffer for video output overlay (OSD), see <xref
648 linkend="osd" />. Status: <link
649linkend="experimental">Experimental</link>.</entry>
650 </row>
651 <row>
652 <entry><constant>V4L2_BUF_TYPE_PRIVATE</constant></entry>
653 <entry>0x80</entry>
654 <entry>This and higher values are reserved for custom
655(driver defined) buffer types.</entry>
656 </row>
657 </tbody>
658 </tgroup>
659 </table>
660
661 <table frame="none" pgwide="1" id="buffer-flags">
662 <title>Buffer Flags</title>
663 <tgroup cols="3">
664 &cs-def;
665 <tbody valign="top">
666 <row>
667 <entry><constant>V4L2_BUF_FLAG_MAPPED</constant></entry>
668 <entry>0x0001</entry>
669 <entry>The buffer resides in device memory and has been mapped
670into the application's address space, see <xref linkend="mmap" /> for details.
671Drivers set or clear this flag when the
672<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
673 linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
674 linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called. Set by the driver.</entry>
675 </row>
676 <row>
677 <entry><constant>V4L2_BUF_FLAG_QUEUED</constant></entry>
678 <entry>0x0002</entry>
679 <entry>Internally drivers maintain two buffer queues, an
680incoming and outgoing queue. When this flag is set, the buffer is
681currently on the incoming queue. It automatically moves to the
682outgoing queue after the buffer has been filled (capture devices) or
683displayed (output devices). Drivers set or clear this flag when the
684<constant>VIDIOC_QUERYBUF</constant> ioctl is called. After
685(successful) calling the <constant>VIDIOC_QBUF </constant>ioctl it is
686always set and after <constant>VIDIOC_DQBUF</constant> always
687cleared.</entry>
688 </row>
689 <row>
690 <entry><constant>V4L2_BUF_FLAG_DONE</constant></entry>
691 <entry>0x0004</entry>
692 <entry>When this flag is set, the buffer is currently on
693the outgoing queue, ready to be dequeued from the driver. Drivers set
694or clear this flag when the <constant>VIDIOC_QUERYBUF</constant> ioctl
695is called. After calling the <constant>VIDIOC_QBUF</constant> or
696<constant>VIDIOC_DQBUF</constant> it is always cleared. Of course a
697buffer cannot be on both queues at the same time, the
698<constant>V4L2_BUF_FLAG_QUEUED</constant> and
699<constant>V4L2_BUF_FLAG_DONE</constant> flag are mutually exclusive.
700They can be both cleared however, then the buffer is in "dequeued"
701state, in the application domain to say so.</entry>
702 </row>
703 <row>
704 <entry><constant>V4L2_BUF_FLAG_KEYFRAME</constant></entry>
705 <entry>0x0008</entry>
706 <entry>Drivers set or clear this flag when calling the
707<constant>VIDIOC_DQBUF</constant> ioctl. It may be set by video
708capture devices when the buffer contains a compressed image which is a
709key frame (or field), &ie; can be decompressed on its own.</entry>
710 </row>
711 <row>
712 <entry><constant>V4L2_BUF_FLAG_PFRAME</constant></entry>
713 <entry>0x0010</entry>
714 <entry>Similar to <constant>V4L2_BUF_FLAG_KEYFRAME</constant>
715this flags predicted frames or fields which contain only differences to a
716previous key frame.</entry>
717 </row>
718 <row>
719 <entry><constant>V4L2_BUF_FLAG_BFRAME</constant></entry>
720 <entry>0x0020</entry>
721 <entry>Similar to <constant>V4L2_BUF_FLAG_PFRAME</constant>
722 this is a bidirectional predicted frame or field. [ooc tbd]</entry>
723 </row>
724 <row>
725 <entry><constant>V4L2_BUF_FLAG_TIMECODE</constant></entry>
726 <entry>0x0100</entry>
727 <entry>The <structfield>timecode</structfield> field is valid.
728Drivers set or clear this flag when the <constant>VIDIOC_DQBUF</constant>
729ioctl is called.</entry>
730 </row>
731 <row>
732 <entry><constant>V4L2_BUF_FLAG_INPUT</constant></entry>
733 <entry>0x0200</entry>
734 <entry>The <structfield>input</structfield> field is valid.
735Applications set or clear this flag before calling the
736<constant>VIDIOC_QBUF</constant> ioctl.</entry>
737 </row>
738 </tbody>
739 </tgroup>
740 </table>
741
742 <table pgwide="1" frame="none" id="v4l2-memory">
743 <title>enum v4l2_memory</title>
744 <tgroup cols="3">
745 &cs-def;
746 <tbody valign="top">
747 <row>
748 <entry><constant>V4L2_MEMORY_MMAP</constant></entry>
749 <entry>1</entry>
750 <entry>The buffer is used for <link linkend="mmap">memory
751mapping</link> I/O.</entry>
752 </row>
753 <row>
754 <entry><constant>V4L2_MEMORY_USERPTR</constant></entry>
755 <entry>2</entry>
756 <entry>The buffer is used for <link linkend="userp">user
757pointer</link> I/O.</entry>
758 </row>
759 <row>
760 <entry><constant>V4L2_MEMORY_OVERLAY</constant></entry>
761 <entry>3</entry>
762 <entry>[to do]</entry>
763 </row>
764 </tbody>
765 </tgroup>
766 </table>
767
768 <section>
769 <title>Timecodes</title>
770
771 <para>The <structname>v4l2_timecode</structname> structure is
772designed to hold a <xref linkend="smpte12m" /> or similar timecode.
773(struct <structname>timeval</structname> timestamps are stored in
774&v4l2-buffer; field <structfield>timestamp</structfield>.)</para>
775
776 <table frame="none" pgwide="1" id="v4l2-timecode">
777 <title>struct <structname>v4l2_timecode</structname></title>
778 <tgroup cols="3">
779 &cs-str;
780 <tbody valign="top">
781 <row>
782 <entry>__u32</entry>
783 <entry><structfield>type</structfield></entry>
784 <entry>Frame rate the timecodes are based on, see <xref
785 linkend="timecode-type" />.</entry>
786 </row>
787 <row>
788 <entry>__u32</entry>
789 <entry><structfield>flags</structfield></entry>
790 <entry>Timecode flags, see <xref linkend="timecode-flags" />.</entry>
791 </row>
792 <row>
793 <entry>__u8</entry>
794 <entry><structfield>frames</structfield></entry>
795 <entry>Frame count, 0 ... 23/24/29/49/59, depending on the
796 type of timecode.</entry>
797 </row>
798 <row>
799 <entry>__u8</entry>
800 <entry><structfield>seconds</structfield></entry>
801 <entry>Seconds count, 0 ... 59. This is a binary, not BCD number.</entry>
802 </row>
803 <row>
804 <entry>__u8</entry>
805 <entry><structfield>minutes</structfield></entry>
806 <entry>Minutes count, 0 ... 59. This is a binary, not BCD number.</entry>
807 </row>
808 <row>
809 <entry>__u8</entry>
810 <entry><structfield>hours</structfield></entry>
811 <entry>Hours count, 0 ... 29. This is a binary, not BCD number.</entry>
812 </row>
813 <row>
814 <entry>__u8</entry>
815 <entry><structfield>userbits</structfield>[4]</entry>
816 <entry>The "user group" bits from the timecode.</entry>
817 </row>
818 </tbody>
819 </tgroup>
820 </table>
821
822 <table frame="none" pgwide="1" id="timecode-type">
823 <title>Timecode Types</title>
824 <tgroup cols="3">
825 &cs-def;
826 <tbody valign="top">
827 <row>
828 <entry><constant>V4L2_TC_TYPE_24FPS</constant></entry>
829 <entry>1</entry>
830 <entry>24 frames per second, i.&nbsp;e. film.</entry>
831 </row>
832 <row>
833 <entry><constant>V4L2_TC_TYPE_25FPS</constant></entry>
834 <entry>2</entry>
835 <entry>25 frames per second, &ie; PAL or SECAM video.</entry>
836 </row>
837 <row>
838 <entry><constant>V4L2_TC_TYPE_30FPS</constant></entry>
839 <entry>3</entry>
840 <entry>30 frames per second, &ie; NTSC video.</entry>
841 </row>
842 <row>
843 <entry><constant>V4L2_TC_TYPE_50FPS</constant></entry>
844 <entry>4</entry>
845 <entry></entry>
846 </row>
847 <row>
848 <entry><constant>V4L2_TC_TYPE_60FPS</constant></entry>
849 <entry>5</entry>
850 <entry></entry>
851 </row>
852 </tbody>
853 </tgroup>
854 </table>
855
856 <table frame="none" pgwide="1" id="timecode-flags">
857 <title>Timecode Flags</title>
858 <tgroup cols="3">
859 &cs-def;
860 <tbody valign="top">
861 <row>
862 <entry><constant>V4L2_TC_FLAG_DROPFRAME</constant></entry>
863 <entry>0x0001</entry>
864 <entry>Indicates "drop frame" semantics for counting frames
865in 29.97 fps material. When set, frame numbers 0 and 1 at the start of
866each minute, except minutes 0, 10, 20, 30, 40, 50 are omitted from the
867count.</entry>
868 </row>
869 <row>
870 <entry><constant>V4L2_TC_FLAG_COLORFRAME</constant></entry>
871 <entry>0x0002</entry>
872 <entry>The "color frame" flag.</entry>
873 </row>
874 <row>
875 <entry><constant>V4L2_TC_USERBITS_field</constant></entry>
876 <entry>0x000C</entry>
877 <entry>Field mask for the "binary group flags".</entry>
878 </row>
879 <row>
880 <entry><constant>V4L2_TC_USERBITS_USERDEFINED</constant></entry>
881 <entry>0x0000</entry>
882 <entry>Unspecified format.</entry>
883 </row>
884 <row>
885 <entry><constant>V4L2_TC_USERBITS_8BITCHARS</constant></entry>
886 <entry>0x0008</entry>
887 <entry>8-bit ISO characters.</entry>
888 </row>
889 </tbody>
890 </tgroup>
891 </table>
892 </section>
893 </section>
894
895 <section id="field-order">
896 <title>Field Order</title>
897
898 <para>We have to distinguish between progressive and interlaced
899video. Progressive video transmits all lines of a video image
900sequentially. Interlaced video divides an image into two fields,
901containing only the odd and even lines of the image, respectively.
902Alternating the so called odd and even field are transmitted, and due
903to a small delay between fields a cathode ray TV displays the lines
904interleaved, yielding the original frame. This curious technique was
905invented because at refresh rates similar to film the image would
906fade out too quickly. Transmitting fields reduces the flicker without
907the necessity of doubling the frame rate and with it the bandwidth
908required for each channel.</para>
909
910 <para>It is important to understand a video camera does not expose
911one frame at a time, merely transmitting the frames separated into
912fields. The fields are in fact captured at two different instances in
913time. An object on screen may well move between one field and the
914next. For applications analysing motion it is of paramount importance
915to recognize which field of a frame is older, the <emphasis>temporal
916order</emphasis>.</para>
917
918 <para>When the driver provides or accepts images field by field
919rather than interleaved, it is also important applications understand
920how the fields combine to frames. We distinguish between top and
921bottom fields, the <emphasis>spatial order</emphasis>: The first line
922of the top field is the first line of an interlaced frame, the first
923line of the bottom field is the second line of that frame.</para>
924
925 <para>However because fields were captured one after the other,
926arguing whether a frame commences with the top or bottom field is
927pointless. Any two successive top and bottom, or bottom and top fields
928yield a valid frame. Only when the source was progressive to begin
929with, &eg; when transferring film to video, two fields may come from
930the same frame, creating a natural order.</para>
931
932 <para>Counter to intuition the top field is not necessarily the
933older field. Whether the older field contains the top or bottom lines
934is a convention determined by the video standard. Hence the
935distinction between temporal and spatial order of fields. The diagrams
936below should make this clearer.</para>
937
938 <para>All video capture and output devices must report the current
939field order. Some drivers may permit the selection of a different
940order, to this end applications initialize the
941<structfield>field</structfield> field of &v4l2-pix-format; before
942calling the &VIDIOC-S-FMT; ioctl. If this is not desired it should
943have the value <constant>V4L2_FIELD_ANY</constant> (0).</para>
944
945 <table frame="none" pgwide="1" id="v4l2-field">
946 <title>enum v4l2_field</title>
947 <tgroup cols="3">
948 &cs-def;
949 <tbody valign="top">
950 <row>
951 <entry><constant>V4L2_FIELD_ANY</constant></entry>
952 <entry>0</entry>
953 <entry>Applications request this field order when any
954one of the <constant>V4L2_FIELD_NONE</constant>,
955<constant>V4L2_FIELD_TOP</constant>,
956<constant>V4L2_FIELD_BOTTOM</constant>, or
957<constant>V4L2_FIELD_INTERLACED</constant> formats is acceptable.
958Drivers choose depending on hardware capabilities or e.&nbsp;g. the
959requested image size, and return the actual field order. &v4l2-buffer;
960<structfield>field</structfield> can never be
961<constant>V4L2_FIELD_ANY</constant>.</entry>
962 </row>
963 <row>
964 <entry><constant>V4L2_FIELD_NONE</constant></entry>
965 <entry>1</entry>
966 <entry>Images are in progressive format, not interlaced.
967The driver may also indicate this order when it cannot distinguish
968between <constant>V4L2_FIELD_TOP</constant> and
969<constant>V4L2_FIELD_BOTTOM</constant>.</entry>
970 </row>
971 <row>
972 <entry><constant>V4L2_FIELD_TOP</constant></entry>
973 <entry>2</entry>
974 <entry>Images consist of the top field only.</entry>
975 </row>
976 <row>
977 <entry><constant>V4L2_FIELD_BOTTOM</constant></entry>
978 <entry>3</entry>
979 <entry>Images consist of the bottom field only.
980Applications may wish to prevent a device from capturing interlaced
981images because they will have "comb" or "feathering" artefacts around
982moving objects.</entry>
983 </row>
984 <row>
985 <entry><constant>V4L2_FIELD_INTERLACED</constant></entry>
986 <entry>4</entry>
987 <entry>Images contain both fields, interleaved line by
988line. The temporal order of the fields (whether the top or bottom
989field is first transmitted) depends on the current video standard.
990M/NTSC transmits the bottom field first, all other standards the top
991field first.</entry>
992 </row>
993 <row>
994 <entry><constant>V4L2_FIELD_SEQ_TB</constant></entry>
995 <entry>5</entry>
996 <entry>Images contain both fields, the top field lines
997are stored first in memory, immediately followed by the bottom field
998lines. Fields are always stored in temporal order, the older one first
999in memory. Image sizes refer to the frame, not fields.</entry>
1000 </row>
1001 <row>
1002 <entry><constant>V4L2_FIELD_SEQ_BT</constant></entry>
1003 <entry>6</entry>
1004 <entry>Images contain both fields, the bottom field
1005lines are stored first in memory, immediately followed by the top
1006field lines. Fields are always stored in temporal order, the older one
1007first in memory. Image sizes refer to the frame, not fields.</entry>
1008 </row>
1009 <row>
1010 <entry><constant>V4L2_FIELD_ALTERNATE</constant></entry>
1011 <entry>7</entry>
1012 <entry>The two fields of a frame are passed in separate
1013buffers, in temporal order, &ie; the older one first. To indicate the field
1014parity (whether the current field is a top or bottom field) the driver
1015or application, depending on data direction, must set &v4l2-buffer;
1016<structfield>field</structfield> to
1017<constant>V4L2_FIELD_TOP</constant> or
1018<constant>V4L2_FIELD_BOTTOM</constant>. Any two successive fields pair
1019to build a frame. If fields are successive, without any dropped fields
1020between them (fields can drop individually), can be determined from
1021the &v4l2-buffer; <structfield>sequence</structfield> field. Image
1022sizes refer to the frame, not fields. This format cannot be selected
1023when using the read/write I/O method.<!-- Where it's indistinguishable
1024from V4L2_FIELD_SEQ_*. --></entry>
1025 </row>
1026 <row>
1027 <entry><constant>V4L2_FIELD_INTERLACED_TB</constant></entry>
1028 <entry>8</entry>
1029 <entry>Images contain both fields, interleaved line by
1030line, top field first. The top field is transmitted first.</entry>
1031 </row>
1032 <row>
1033 <entry><constant>V4L2_FIELD_INTERLACED_BT</constant></entry>
1034 <entry>9</entry>
1035 <entry>Images contain both fields, interleaved line by
1036line, top field first. The bottom field is transmitted first.</entry>
1037 </row>
1038 </tbody>
1039 </tgroup>
1040 </table>
1041
1042 <figure id="fieldseq-tb">
1043 <title>Field Order, Top Field First Transmitted</title>
1044 <mediaobject>
1045 <imageobject>
1046 <imagedata fileref="fieldseq_tb.pdf" format="PS" />
1047 </imageobject>
1048 <imageobject>
1049 <imagedata fileref="fieldseq_tb.gif" format="GIF" />
1050 </imageobject>
1051 </mediaobject>
1052 </figure>
1053
1054 <figure id="fieldseq-bt">
1055 <title>Field Order, Bottom Field First Transmitted</title>
1056 <mediaobject>
1057 <imageobject>
1058 <imagedata fileref="fieldseq_bt.pdf" format="PS" />
1059 </imageobject>
1060 <imageobject>
1061 <imagedata fileref="fieldseq_bt.gif" format="GIF" />
1062 </imageobject>
1063 </mediaobject>
1064 </figure>
1065 </section>
1066
1067 <!--
1068Local Variables:
1069mode: sgml
1070sgml-parent-document: "v4l2.sgml"
1071indent-tabs-mode: nil
1072End:
1073 -->
diff --git a/Documentation/DocBook/v4l/keytable.c.xml b/Documentation/DocBook/v4l/keytable.c.xml
new file mode 100644
index 000000000000..d53254a3be15
--- /dev/null
+++ b/Documentation/DocBook/v4l/keytable.c.xml
@@ -0,0 +1,172 @@
1<programlisting>
2/* keytable.c - This program allows checking/replacing keys at IR
3
4 Copyright (C) 2006-2009 Mauro Carvalho Chehab &lt;mchehab@infradead.org&gt;
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 2 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14 */
15
16#include &lt;ctype.h&gt;
17#include &lt;errno.h&gt;
18#include &lt;fcntl.h&gt;
19#include &lt;stdio.h&gt;
20#include &lt;stdlib.h&gt;
21#include &lt;string.h&gt;
22#include &lt;linux/input.h&gt;
23#include &lt;sys/ioctl.h&gt;
24
25#include "parse.h"
26
27void prtcode (int *codes)
28{
29 struct parse_key *p;
30
31 for (p=keynames;p-&gt;name!=NULL;p++) {
32 if (p-&gt;value == (unsigned)codes[1]) {
33 printf("scancode 0x%04x = %s (0x%02x)\n", codes[0], p-&gt;name, codes[1]);
34 return;
35 }
36 }
37
38 if (isprint (codes[1]))
39 printf("scancode %d = '%c' (0x%02x)\n", codes[0], codes[1], codes[1]);
40 else
41 printf("scancode %d = 0x%02x\n", codes[0], codes[1]);
42}
43
44int parse_code(char *string)
45{
46 struct parse_key *p;
47
48 for (p=keynames;p-&gt;name!=NULL;p++) {
49 if (!strcasecmp(p-&gt;name, string)) {
50 return p-&gt;value;
51 }
52 }
53 return -1;
54}
55
56int main (int argc, char *argv[])
57{
58 int fd;
59 unsigned int i, j;
60 int codes[2];
61
62 if (argc&lt;2 || argc&gt;4) {
63 printf ("usage: %s &lt;device&gt; to get table; or\n"
64 " %s &lt;device&gt; &lt;scancode&gt; &lt;keycode&gt;\n"
65 " %s &lt;device&gt; &lt;keycode_file&gt;\n",*argv,*argv,*argv);
66 return -1;
67 }
68
69 if ((fd = open(argv[1], O_RDONLY)) &lt; 0) {
70 perror("Couldn't open input device");
71 return(-1);
72 }
73
74 if (argc==4) {
75 int value;
76
77 value=parse_code(argv[3]);
78
79 if (value==-1) {
80 value = strtol(argv[3], NULL, 0);
81 if (errno)
82 perror("value");
83 }
84
85 codes [0] = (unsigned) strtol(argv[2], NULL, 0);
86 codes [1] = (unsigned) value;
87
88 if(ioctl(fd, EVIOCSKEYCODE, codes))
89 perror ("EVIOCSKEYCODE");
90
91 if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
92 prtcode(codes);
93 return 0;
94 }
95
96 if (argc==3) {
97 FILE *fin;
98 int value;
99 char *scancode, *keycode, s[2048];
100
101 fin=fopen(argv[2],"r");
102 if (fin==NULL) {
103 perror ("opening keycode file");
104 return -1;
105 }
106
107 /* Clears old table */
108 for (j = 0; j &lt; 256; j++) {
109 for (i = 0; i &lt; 256; i++) {
110 codes[0] = (j &lt;&lt; 8) | i;
111 codes[1] = KEY_RESERVED;
112 ioctl(fd, EVIOCSKEYCODE, codes);
113 }
114 }
115
116 while (fgets(s,sizeof(s),fin)) {
117 scancode=strtok(s,"\n\t =:");
118 if (!scancode) {
119 perror ("parsing input file scancode");
120 return -1;
121 }
122 if (!strcasecmp(scancode, "scancode")) {
123 scancode = strtok(NULL,"\n\t =:");
124 if (!scancode) {
125 perror ("parsing input file scancode");
126 return -1;
127 }
128 }
129
130 keycode=strtok(NULL,"\n\t =:(");
131 if (!keycode) {
132 perror ("parsing input file keycode");
133 return -1;
134 }
135
136 // printf ("parsing %s=%s:", scancode, keycode);
137 value=parse_code(keycode);
138 // printf ("\tvalue=%d\n",value);
139
140 if (value==-1) {
141 value = strtol(keycode, NULL, 0);
142 if (errno)
143 perror("value");
144 }
145
146 codes [0] = (unsigned) strtol(scancode, NULL, 0);
147 codes [1] = (unsigned) value;
148
149 // printf("\t%04x=%04x\n",codes[0], codes[1]);
150 if(ioctl(fd, EVIOCSKEYCODE, codes)) {
151 fprintf(stderr, "Setting scancode 0x%04x with 0x%04x via ",codes[0], codes[1]);
152 perror ("EVIOCSKEYCODE");
153 }
154
155 if(ioctl(fd, EVIOCGKEYCODE, codes)==0)
156 prtcode(codes);
157 }
158 return 0;
159 }
160
161 /* Get scancode table */
162 for (j = 0; j &lt; 256; j++) {
163 for (i = 0; i &lt; 256; i++) {
164 codes[0] = (j &lt;&lt; 8) | i;
165 if (!ioctl(fd, EVIOCGKEYCODE, codes) &amp;&amp; codes[1] != KEY_RESERVED)
166 prtcode(codes);
167 }
168 }
169 return 0;
170}
171
172</programlisting>
diff --git a/Documentation/DocBook/v4l/libv4l.xml b/Documentation/DocBook/v4l/libv4l.xml
new file mode 100644
index 000000000000..c14fc3db2a81
--- /dev/null
+++ b/Documentation/DocBook/v4l/libv4l.xml
@@ -0,0 +1,167 @@
1<title>Libv4l Userspace Library</title>
2<section id="libv4l-introduction">
3 <title>Introduction</title>
4
5 <para>libv4l is a collection of libraries which adds a thin abstraction
6layer on top of video4linux2 devices. The purpose of this (thin) layer
7is to make it easy for application writers to support a wide variety of
8devices without having to write separate code for different devices in the
9same class.</para>
10<para>An example of using libv4l is provided by
11<link linkend='v4l2grab-example'>v4l2grab</link>.
12</para>
13
14 <para>libv4l consists of 3 different libraries:</para>
15 <section>
16 <title>libv4lconvert</title>
17
18 <para>libv4lconvert is a library that converts several
19different pixelformats found in V4L2 drivers into a few common RGB and
20YUY formats.</para>
21 <para>It currently accepts the following V4L2 driver formats:
22<link linkend="V4L2-PIX-FMT-BGR24"><constant>V4L2_PIX_FMT_BGR24</constant></link>,
23<link linkend="V4L2-PIX-FMT-HM12"><constant>V4L2_PIX_FMT_HM12</constant></link>,
24<link linkend="V4L2-PIX-FMT-JPEG"><constant>V4L2_PIX_FMT_JPEG</constant></link>,
25<link linkend="V4L2-PIX-FMT-MJPEG"><constant>V4L2_PIX_FMT_MJPEG</constant></link>,
26<link linkend="V4L2-PIX-FMT-MR97310A"><constant>V4L2_PIX_FMT_MR97310A</constant></link>,
27<link linkend="V4L2-PIX-FMT-OV511"><constant>V4L2_PIX_FMT_OV511</constant></link>,
28<link linkend="V4L2-PIX-FMT-OV518"><constant>V4L2_PIX_FMT_OV518</constant></link>,
29<link linkend="V4L2-PIX-FMT-PAC207"><constant>V4L2_PIX_FMT_PAC207</constant></link>,
30<link linkend="V4L2-PIX-FMT-PJPG"><constant>V4L2_PIX_FMT_PJPG</constant></link>,
31<link linkend="V4L2-PIX-FMT-RGB24"><constant>V4L2_PIX_FMT_RGB24</constant></link>,
32<link linkend="V4L2-PIX-FMT-SBGGR8"><constant>V4L2_PIX_FMT_SBGGR8</constant></link>,
33<link linkend="V4L2-PIX-FMT-SGBRG8"><constant>V4L2_PIX_FMT_SGBRG8</constant></link>,
34<link linkend="V4L2-PIX-FMT-SGRBG8"><constant>V4L2_PIX_FMT_SGRBG8</constant></link>,
35<link linkend="V4L2-PIX-FMT-SN9C10X"><constant>V4L2_PIX_FMT_SN9C10X</constant></link>,
36<link linkend="V4L2-PIX-FMT-SN9C20X-I420"><constant>V4L2_PIX_FMT_SN9C20X_I420</constant></link>,
37<link linkend="V4L2-PIX-FMT-SPCA501"><constant>V4L2_PIX_FMT_SPCA501</constant></link>,
38<link linkend="V4L2-PIX-FMT-SPCA505"><constant>V4L2_PIX_FMT_SPCA505</constant></link>,
39<link linkend="V4L2-PIX-FMT-SPCA508"><constant>V4L2_PIX_FMT_SPCA508</constant></link>,
40<link linkend="V4L2-PIX-FMT-SPCA561"><constant>V4L2_PIX_FMT_SPCA561</constant></link>,
41<link linkend="V4L2-PIX-FMT-SQ905C"><constant>V4L2_PIX_FMT_SQ905C</constant></link>,
42<constant>V4L2_PIX_FMT_SRGGB8</constant>,
43<link linkend="V4L2-PIX-FMT-UYVY"><constant>V4L2_PIX_FMT_UYVY</constant></link>,
44<link linkend="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></link>,
45<link linkend="V4L2-PIX-FMT-YUYV"><constant>V4L2_PIX_FMT_YUYV</constant></link>,
46<link linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link>,
47and <link linkend="V4L2-PIX-FMT-YVYU"><constant>V4L2_PIX_FMT_YVYU</constant></link>.
48</para>
49 <para>Later on libv4lconvert was expanded to also be able to do
50various video processing functions to improve webcam video quality.
51The video processing is split in to 2 parts: libv4lconvert/control and
52libv4lconvert/processing.</para>
53
54 <para>The control part is used to offer video controls which can
55be used to control the video processing functions made available by
56 libv4lconvert/processing. These controls are stored application wide
57(until reboot) by using a persistent shared memory object.</para>
58
59 <para>libv4lconvert/processing offers the actual video
60processing functionality.</para>
61 </section>
62 <section>
63 <title>libv4l1</title>
64 <para>This library offers functions that can be used to quickly
65make v4l1 applications work with v4l2 devices. These functions work exactly
66like the normal open/close/etc, except that libv4l1 does full emulation of
67the v4l1 api on top of v4l2 drivers, in case of v4l1 drivers it
68will just pass calls through.</para>
69 <para>Since those functions are emulations of the old V4L1 API,
70it shouldn't be used for new applications.</para>
71 </section>
72 <section>
73 <title>libv4l2</title>
74 <para>This library should be used for all modern V4L2
75applications.</para>
76 <para>It provides handles to call V4L2 open/ioctl/close/poll
77methods. Instead of just providing the raw output of the device, it enhances
78the calls in the sense that it will use libv4lconvert to provide more video
79formats and to enhance the image quality.</para>
80 <para>In most cases, libv4l2 just passes the calls directly
81through to the v4l2 driver, intercepting the calls to
82<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>,
83<link linkend='vidioc-g-fmt'><constant>VIDIOC_G_FMT</constant></link>
84<link linkend='vidioc-g-fmt'><constant>VIDIOC_S_FMT</constant></link>
85<link linkend='vidioc-enum-framesizes'><constant>VIDIOC_ENUM_FRAMESIZES</constant></link>
86and <link linkend='vidioc-enum-frameintervals'><constant>VIDIOC_ENUM_FRAMEINTERVALS</constant></link>
87in order to emulate the formats
88<link linkend="V4L2-PIX-FMT-BGR24"><constant>V4L2_PIX_FMT_BGR24</constant></link>,
89<link linkend="V4L2-PIX-FMT-RGB24"><constant>V4L2_PIX_FMT_RGB24</constant></link>,
90<link linkend="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></link>,
91and <link linkend="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></link>,
92if they aren't available in the driver.
93<link linkend='vidioc-enum-fmt'><constant>VIDIOC_ENUM_FMT</constant></link>
94keeps enumerating the hardware supported formats, plus the emulated formats
95offered by libv4l at the end.
96</para>
97 <section id="libv4l-ops">
98 <title>Libv4l device control functions</title>
99 <para>The common file operation methods are provided by
100libv4l.</para>
101 <para>Those functions operate just like glibc
102open/close/dup/ioctl/read/mmap/munmap:</para>
103<itemizedlist><listitem>
104 <para>int v4l2_open(const char *file, int oflag,
105...) -
106operates like the standard <link linkend='func-open'>open()</link> function.
107</para></listitem><listitem>
108 <para>int v4l2_close(int fd) -
109operates like the standard <link linkend='func-close'>close()</link> function.
110</para></listitem><listitem>
111 <para>int v4l2_dup(int fd) -
112operates like the standard dup() function, duplicating a file handler.
113</para></listitem><listitem>
114 <para>int v4l2_ioctl (int fd, unsigned long int request, ...) -
115operates like the standard <link linkend='func-ioctl'>ioctl()</link> function.
116</para></listitem><listitem>
117 <para>int v4l2_read (int fd, void* buffer, size_t n) -
118operates like the standard <link linkend='func-read'>read()</link> function.
119</para></listitem><listitem>
120 <para>void v4l2_mmap(void *start, size_t length, int prot, int flags, int fd, int64_t offset); -
121operates like the standard <link linkend='func-mmap'>mmap()</link> function.
122</para></listitem><listitem>
123 <para>int v4l2_munmap(void *_start, size_t length); -
124operates like the standard <link linkend='func-munmap'>munmap()</link> function.
125</para></listitem>
126</itemizedlist>
127 <para>Those functions provide additional control:</para>
128<itemizedlist><listitem>
129 <para>int v4l2_fd_open(int fd, int v4l2_flags) -
130opens an already opened fd for further use through v4l2lib and possibly
131modify libv4l2's default behavior through the v4l2_flags argument.
132Currently, v4l2_flags can be <constant>V4L2_DISABLE_CONVERSION</constant>,
133to disable format conversion.
134</para></listitem><listitem>
135 <para>int v4l2_set_control(int fd, int cid, int value) -
136This function takes a value of 0 - 65535, and then scales that range to
137the actual range of the given v4l control id, and then if the cid exists
138and is not locked sets the cid to the scaled value.
139</para></listitem><listitem>
140 <para>int v4l2_get_control(int fd, int cid) -
141This function returns a value of 0 - 65535, scaled to from the actual range
142of the given v4l control id. when the cid does not exist, could not be
143accessed for some reason, or some error occured 0 is returned.
144</para></listitem>
145</itemizedlist>
146 </section>
147 </section>
148 <section>
149
150 <title>v4l1compat.so wrapper library</title>
151
152 <para>This library intercepts calls to
153open/close/ioctl/mmap/mmunmap operations and redirects them to the libv4l
154counterparts, by using LD_PRELOAD=/usr/lib/v4l1compat.so. It also
155emulates V4L1 calls via V4L2 API.</para>
156 <para>It allows usage of binary legacy applications that
157still don't use libv4l.</para>
158 </section>
159
160</section>
161<!--
162Local Variables:
163mode: sgml
164sgml-parent-document: "v4l2.sgml"
165indent-tabs-mode: nil
166End:
167-->
diff --git a/Documentation/DocBook/v4l/pixfmt-grey.xml b/Documentation/DocBook/v4l/pixfmt-grey.xml
new file mode 100644
index 000000000000..3b72bc6b2de7
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-grey.xml
@@ -0,0 +1,70 @@
1 <refentry id="V4L2-PIX-FMT-GREY">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_GREY ('GREY')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_GREY</constant></refname>
8 <refpurpose>Grey-scale image</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>This is a grey-scale image. It is really a degenerate
14Y'CbCr format which simply contains no Cb or Cr data.</para>
15
16 <example>
17 <title><constant>V4L2_PIX_FMT_GREY</constant> 4 &times; 4
18pixel image</title>
19
20 <formalpara>
21 <title>Byte Order.</title>
22 <para>Each cell is one byte.
23 <informaltable frame="none">
24 <tgroup cols="5" align="center">
25 <colspec align="left" colwidth="2*" />
26 <tbody valign="top">
27 <row>
28 <entry>start&nbsp;+&nbsp;0:</entry>
29 <entry>Y'<subscript>00</subscript></entry>
30 <entry>Y'<subscript>01</subscript></entry>
31 <entry>Y'<subscript>02</subscript></entry>
32 <entry>Y'<subscript>03</subscript></entry>
33 </row>
34 <row>
35 <entry>start&nbsp;+&nbsp;4:</entry>
36 <entry>Y'<subscript>10</subscript></entry>
37 <entry>Y'<subscript>11</subscript></entry>
38 <entry>Y'<subscript>12</subscript></entry>
39 <entry>Y'<subscript>13</subscript></entry>
40 </row>
41 <row>
42 <entry>start&nbsp;+&nbsp;8:</entry>
43 <entry>Y'<subscript>20</subscript></entry>
44 <entry>Y'<subscript>21</subscript></entry>
45 <entry>Y'<subscript>22</subscript></entry>
46 <entry>Y'<subscript>23</subscript></entry>
47 </row>
48 <row>
49 <entry>start&nbsp;+&nbsp;12:</entry>
50 <entry>Y'<subscript>30</subscript></entry>
51 <entry>Y'<subscript>31</subscript></entry>
52 <entry>Y'<subscript>32</subscript></entry>
53 <entry>Y'<subscript>33</subscript></entry>
54 </row>
55 </tbody>
56 </tgroup>
57 </informaltable>
58 </para>
59 </formalpara>
60 </example>
61 </refsect1>
62 </refentry>
63
64 <!--
65Local Variables:
66mode: sgml
67sgml-parent-document: "pixfmt.sgml"
68indent-tabs-mode: nil
69End:
70 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-nv12.xml b/Documentation/DocBook/v4l/pixfmt-nv12.xml
new file mode 100644
index 000000000000..873f67035181
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv12.xml
@@ -0,0 +1,151 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_NV12 ('NV12'), V4L2_PIX_FMT_NV21 ('NV21')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname id="V4L2-PIX-FMT-NV12"><constant>V4L2_PIX_FMT_NV12</constant></refname>
8 <refname id="V4L2-PIX-FMT-NV21"><constant>V4L2_PIX_FMT_NV21</constant></refname>
9 <refpurpose>Formats with &frac12; horizontal and vertical
10chroma resolution, also known as YUV 4:2:0. One luminance and one
11chrominance plane with alternating chroma samples as opposed to
12<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
13 </refnamediv>
14 <refsect1>
15 <title>Description</title>
16
17 <para>These are two-plane versions of the YUV 4:2:0 format.
18The three components are separated into two sub-images or planes. The
19Y plane is first. The Y plane has one byte per pixel. For
20<constant>V4L2_PIX_FMT_NV12</constant>, a combined CbCr plane
21immediately follows the Y plane in memory. The CbCr plane is the same
22width, in bytes, as the Y plane (and of the image), but is half as
23tall in pixels. Each CbCr pair belongs to four pixels. For example,
24Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
25Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
26Y'<subscript>10</subscript>, Y'<subscript>11</subscript>.
27<constant>V4L2_PIX_FMT_NV21</constant> is the same except the Cb and
28Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
29
30 <para>If the Y plane has pad bytes after each row, then the
31CbCr plane has as many pad bytes after its rows.</para>
32
33 <example>
34 <title><constant>V4L2_PIX_FMT_NV12</constant> 4 &times; 4
35pixel image</title>
36
37 <formalpara>
38 <title>Byte Order.</title>
39 <para>Each cell is one byte.
40 <informaltable frame="none">
41 <tgroup cols="5" align="center">
42 <colspec align="left" colwidth="2*" />
43 <tbody valign="top">
44 <row>
45 <entry>start&nbsp;+&nbsp;0:</entry>
46 <entry>Y'<subscript>00</subscript></entry>
47 <entry>Y'<subscript>01</subscript></entry>
48 <entry>Y'<subscript>02</subscript></entry>
49 <entry>Y'<subscript>03</subscript></entry>
50 </row>
51 <row>
52 <entry>start&nbsp;+&nbsp;4:</entry>
53 <entry>Y'<subscript>10</subscript></entry>
54 <entry>Y'<subscript>11</subscript></entry>
55 <entry>Y'<subscript>12</subscript></entry>
56 <entry>Y'<subscript>13</subscript></entry>
57 </row>
58 <row>
59 <entry>start&nbsp;+&nbsp;8:</entry>
60 <entry>Y'<subscript>20</subscript></entry>
61 <entry>Y'<subscript>21</subscript></entry>
62 <entry>Y'<subscript>22</subscript></entry>
63 <entry>Y'<subscript>23</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;12:</entry>
67 <entry>Y'<subscript>30</subscript></entry>
68 <entry>Y'<subscript>31</subscript></entry>
69 <entry>Y'<subscript>32</subscript></entry>
70 <entry>Y'<subscript>33</subscript></entry>
71 </row>
72 <row>
73 <entry>start&nbsp;+&nbsp;16:</entry>
74 <entry>Cb<subscript>00</subscript></entry>
75 <entry>Cr<subscript>00</subscript></entry>
76 <entry>Cb<subscript>01</subscript></entry>
77 <entry>Cr<subscript>01</subscript></entry>
78 </row>
79 <row>
80 <entry>start&nbsp;+&nbsp;20:</entry>
81 <entry>Cb<subscript>10</subscript></entry>
82 <entry>Cr<subscript>10</subscript></entry>
83 <entry>Cb<subscript>11</subscript></entry>
84 <entry>Cr<subscript>11</subscript></entry>
85 </row>
86 </tbody>
87 </tgroup>
88 </informaltable>
89 </para>
90 </formalpara>
91
92 <formalpara>
93 <title>Color Sample Location.</title>
94 <para>
95 <informaltable frame="none">
96 <tgroup cols="7" align="center">
97 <tbody valign="top">
98 <row>
99 <entry></entry>
100 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
101 <entry>2</entry><entry></entry><entry>3</entry>
102 </row>
103 <row>
104 <entry>0</entry>
105 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
106 <entry>Y</entry><entry></entry><entry>Y</entry>
107 </row>
108 <row>
109 <entry></entry>
110 <entry></entry><entry>C</entry><entry></entry><entry></entry>
111 <entry></entry><entry>C</entry><entry></entry>
112 </row>
113 <row>
114 <entry>1</entry>
115 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
116 <entry>Y</entry><entry></entry><entry>Y</entry>
117 </row>
118 <row>
119 <entry></entry>
120 </row>
121 <row>
122 <entry>2</entry>
123 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
124 <entry>Y</entry><entry></entry><entry>Y</entry>
125 </row>
126 <row>
127 <entry></entry>
128 <entry></entry><entry>C</entry><entry></entry><entry></entry>
129 <entry></entry><entry>C</entry><entry></entry>
130 </row>
131 <row>
132 <entry>3</entry>
133 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
134 <entry>Y</entry><entry></entry><entry>Y</entry>
135 </row>
136 </tbody>
137 </tgroup>
138 </informaltable>
139 </para>
140 </formalpara>
141 </example>
142 </refsect1>
143 </refentry>
144
145 <!--
146Local Variables:
147mode: sgml
148sgml-parent-document: "pixfmt.sgml"
149indent-tabs-mode: nil
150End:
151 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-nv16.xml b/Documentation/DocBook/v4l/pixfmt-nv16.xml
new file mode 100644
index 000000000000..26094035fc04
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv16.xml
@@ -0,0 +1,174 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_NV16 ('NV16'), V4L2_PIX_FMT_NV61 ('NV61')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname id="V4L2-PIX-FMT-NV16"><constant>V4L2_PIX_FMT_NV16</constant></refname>
8 <refname id="V4L2-PIX-FMT-NV61"><constant>V4L2_PIX_FMT_NV61</constant></refname>
9 <refpurpose>Formats with &frac12; horizontal
10chroma resolution, also known as YUV 4:2:2. One luminance and one
11chrominance plane with alternating chroma samples as opposed to
12<constant>V4L2_PIX_FMT_YVU420</constant></refpurpose>
13 </refnamediv>
14 <refsect1>
15 <title>Description</title>
16
17 <para>These are two-plane versions of the YUV 4:2:2 format.
18The three components are separated into two sub-images or planes. The
19Y plane is first. The Y plane has one byte per pixel. For
20<constant>V4L2_PIX_FMT_NV16</constant>, a combined CbCr plane
21immediately follows the Y plane in memory. The CbCr plane is the same
22width and height, in bytes, as the Y plane (and of the image).
23Each CbCr pair belongs to two pixels. For example,
24Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
25Y'<subscript>00</subscript>, Y'<subscript>01</subscript>.
26<constant>V4L2_PIX_FMT_NV61</constant> is the same except the Cb and
27Cr bytes are swapped, the CrCb plane starts with a Cr byte.</para>
28
29 <para>If the Y plane has pad bytes after each row, then the
30CbCr plane has as many pad bytes after its rows.</para>
31
32 <example>
33 <title><constant>V4L2_PIX_FMT_NV16</constant> 4 &times; 4
34pixel image</title>
35
36 <formalpara>
37 <title>Byte Order.</title>
38 <para>Each cell is one byte.
39 <informaltable frame="none">
40 <tgroup cols="5" align="center">
41 <colspec align="left" colwidth="2*" />
42 <tbody valign="top">
43 <row>
44 <entry>start&nbsp;+&nbsp;0:</entry>
45 <entry>Y'<subscript>00</subscript></entry>
46 <entry>Y'<subscript>01</subscript></entry>
47 <entry>Y'<subscript>02</subscript></entry>
48 <entry>Y'<subscript>03</subscript></entry>
49 </row>
50 <row>
51 <entry>start&nbsp;+&nbsp;4:</entry>
52 <entry>Y'<subscript>10</subscript></entry>
53 <entry>Y'<subscript>11</subscript></entry>
54 <entry>Y'<subscript>12</subscript></entry>
55 <entry>Y'<subscript>13</subscript></entry>
56 </row>
57 <row>
58 <entry>start&nbsp;+&nbsp;8:</entry>
59 <entry>Y'<subscript>20</subscript></entry>
60 <entry>Y'<subscript>21</subscript></entry>
61 <entry>Y'<subscript>22</subscript></entry>
62 <entry>Y'<subscript>23</subscript></entry>
63 </row>
64 <row>
65 <entry>start&nbsp;+&nbsp;12:</entry>
66 <entry>Y'<subscript>30</subscript></entry>
67 <entry>Y'<subscript>31</subscript></entry>
68 <entry>Y'<subscript>32</subscript></entry>
69 <entry>Y'<subscript>33</subscript></entry>
70 </row>
71 <row>
72 <entry>start&nbsp;+&nbsp;16:</entry>
73 <entry>Cb<subscript>00</subscript></entry>
74 <entry>Cr<subscript>00</subscript></entry>
75 <entry>Cb<subscript>01</subscript></entry>
76 <entry>Cr<subscript>01</subscript></entry>
77 </row>
78 <row>
79 <entry>start&nbsp;+&nbsp;20:</entry>
80 <entry>Cb<subscript>10</subscript></entry>
81 <entry>Cr<subscript>10</subscript></entry>
82 <entry>Cb<subscript>11</subscript></entry>
83 <entry>Cr<subscript>11</subscript></entry>
84 </row>
85 <row>
86 <entry>start&nbsp;+&nbsp;24:</entry>
87 <entry>Cb<subscript>20</subscript></entry>
88 <entry>Cr<subscript>20</subscript></entry>
89 <entry>Cb<subscript>21</subscript></entry>
90 <entry>Cr<subscript>21</subscript></entry>
91 </row>
92 <row>
93 <entry>start&nbsp;+&nbsp;28:</entry>
94 <entry>Cb<subscript>30</subscript></entry>
95 <entry>Cr<subscript>30</subscript></entry>
96 <entry>Cb<subscript>31</subscript></entry>
97 <entry>Cr<subscript>31</subscript></entry>
98 </row>
99 </tbody>
100 </tgroup>
101 </informaltable>
102 </para>
103 </formalpara>
104
105 <formalpara>
106 <title>Color Sample Location.</title>
107 <para>
108 <informaltable frame="none">
109 <tgroup cols="7" align="center">
110 <tbody valign="top">
111 <row>
112 <entry></entry>
113 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
114 <entry>2</entry><entry></entry><entry>3</entry>
115 </row>
116 <row>
117 <entry>0</entry>
118 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
119 <entry>Y</entry><entry></entry><entry>Y</entry>
120 </row>
121 <row>
122 <entry></entry>
123 <entry></entry><entry>C</entry><entry></entry><entry></entry>
124 <entry></entry><entry>C</entry><entry></entry>
125 </row>
126 <row>
127 <entry>1</entry>
128 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
129 <entry>Y</entry><entry></entry><entry>Y</entry>
130 </row>
131 <row>
132 <entry></entry>
133 <entry></entry><entry>C</entry><entry></entry><entry></entry>
134 <entry></entry><entry>C</entry><entry></entry>
135 </row>
136 <row>
137 <entry></entry>
138 </row>
139 <row>
140 <entry>2</entry>
141 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
142 <entry>Y</entry><entry></entry><entry>Y</entry>
143 </row>
144 <row>
145 <entry></entry>
146 <entry></entry><entry>C</entry><entry></entry><entry></entry>
147 <entry></entry><entry>C</entry><entry></entry>
148 </row>
149 <row>
150 <entry>3</entry>
151 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
152 <entry>Y</entry><entry></entry><entry>Y</entry>
153 </row>
154 <row>
155 <entry></entry>
156 <entry></entry><entry>C</entry><entry></entry><entry></entry>
157 <entry></entry><entry>C</entry><entry></entry>
158 </row>
159 </tbody>
160 </tgroup>
161 </informaltable>
162 </para>
163 </formalpara>
164 </example>
165 </refsect1>
166 </refentry>
167
168 <!--
169Local Variables:
170mode: sgml
171sgml-parent-document: "pixfmt.sgml"
172indent-tabs-mode: nil
173End:
174 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml b/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml
new file mode 100644
index 000000000000..d2dd697a81d8
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-packed-rgb.xml
@@ -0,0 +1,862 @@
1<refentry id="packed-rgb">
2 <refmeta>
3 <refentrytitle>Packed RGB formats</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname>Packed RGB formats</refname>
8 <refpurpose>Packed RGB formats</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>These formats are designed to match the pixel formats of
14typical PC graphics frame buffers. They occupy 8, 16, 24 or 32 bits
15per pixel. These are all packed-pixel formats, meaning all the data
16for a pixel lie next to each other in memory.</para>
17
18 <para>When one of these formats is used, drivers shall report the
19colorspace <constant>V4L2_COLORSPACE_SRGB</constant>.</para>
20
21 <table pgwide="1" frame="none" id="rgb-formats">
22 <title>Packed RGB Image Formats</title>
23 <tgroup cols="37" align="center">
24 <colspec colname="id" align="left" />
25 <colspec colname="fourcc" />
26 <colspec colname="bit" />
27
28 <colspec colnum="4" colname="b07" align="center" />
29 <colspec colnum="5" colname="b06" align="center" />
30 <colspec colnum="6" colname="b05" align="center" />
31 <colspec colnum="7" colname="b04" align="center" />
32 <colspec colnum="8" colname="b03" align="center" />
33 <colspec colnum="9" colname="b02" align="center" />
34 <colspec colnum="10" colname="b01" align="center" />
35 <colspec colnum="11" colname="b00" align="center" />
36
37 <colspec colnum="13" colname="b17" align="center" />
38 <colspec colnum="14" colname="b16" align="center" />
39 <colspec colnum="15" colname="b15" align="center" />
40 <colspec colnum="16" colname="b14" align="center" />
41 <colspec colnum="17" colname="b13" align="center" />
42 <colspec colnum="18" colname="b12" align="center" />
43 <colspec colnum="19" colname="b11" align="center" />
44 <colspec colnum="20" colname="b10" align="center" />
45
46 <colspec colnum="22" colname="b27" align="center" />
47 <colspec colnum="23" colname="b26" align="center" />
48 <colspec colnum="24" colname="b25" align="center" />
49 <colspec colnum="25" colname="b24" align="center" />
50 <colspec colnum="26" colname="b23" align="center" />
51 <colspec colnum="27" colname="b22" align="center" />
52 <colspec colnum="28" colname="b21" align="center" />
53 <colspec colnum="29" colname="b20" align="center" />
54
55 <colspec colnum="31" colname="b37" align="center" />
56 <colspec colnum="32" colname="b36" align="center" />
57 <colspec colnum="33" colname="b35" align="center" />
58 <colspec colnum="34" colname="b34" align="center" />
59 <colspec colnum="35" colname="b33" align="center" />
60 <colspec colnum="36" colname="b32" align="center" />
61 <colspec colnum="37" colname="b31" align="center" />
62 <colspec colnum="38" colname="b30" align="center" />
63
64 <spanspec namest="b07" nameend="b00" spanname="b0" />
65 <spanspec namest="b17" nameend="b10" spanname="b1" />
66 <spanspec namest="b27" nameend="b20" spanname="b2" />
67 <spanspec namest="b37" nameend="b30" spanname="b3" />
68 <thead>
69 <row>
70 <entry>Identifier</entry>
71 <entry>Code</entry>
72 <entry>&nbsp;</entry>
73 <entry spanname="b0">Byte&nbsp;0 in memory</entry>
74 <entry spanname="b1">Byte&nbsp;1</entry>
75 <entry spanname="b2">Byte&nbsp;2</entry>
76 <entry spanname="b3">Byte&nbsp;3</entry>
77 </row>
78 <row>
79 <entry>&nbsp;</entry>
80 <entry>&nbsp;</entry>
81 <entry>Bit</entry>
82 <entry>7</entry>
83 <entry>6</entry>
84 <entry>5</entry>
85 <entry>4</entry>
86 <entry>3</entry>
87 <entry>2</entry>
88 <entry>1</entry>
89 <entry>0</entry>
90 <entry>&nbsp;</entry>
91 <entry>7</entry>
92 <entry>6</entry>
93 <entry>5</entry>
94 <entry>4</entry>
95 <entry>3</entry>
96 <entry>2</entry>
97 <entry>1</entry>
98 <entry>0</entry>
99 <entry>&nbsp;</entry>
100 <entry>7</entry>
101 <entry>6</entry>
102 <entry>5</entry>
103 <entry>4</entry>
104 <entry>3</entry>
105 <entry>2</entry>
106 <entry>1</entry>
107 <entry>0</entry>
108 <entry>&nbsp;</entry>
109 <entry>7</entry>
110 <entry>6</entry>
111 <entry>5</entry>
112 <entry>4</entry>
113 <entry>3</entry>
114 <entry>2</entry>
115 <entry>1</entry>
116 <entry>0</entry>
117 </row>
118 </thead>
119 <tbody valign="top">
120 <row id="V4L2-PIX-FMT-RGB332">
121 <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
122 <entry>'RGB1'</entry>
123 <entry></entry>
124 <entry>b<subscript>1</subscript></entry>
125 <entry>b<subscript>0</subscript></entry>
126 <entry>g<subscript>2</subscript></entry>
127 <entry>g<subscript>1</subscript></entry>
128 <entry>g<subscript>0</subscript></entry>
129 <entry>r<subscript>2</subscript></entry>
130 <entry>r<subscript>1</subscript></entry>
131 <entry>r<subscript>0</subscript></entry>
132 </row>
133 <row id="V4L2-PIX-FMT-RGB444">
134 <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
135 <entry>'R444'</entry>
136 <entry></entry>
137 <entry>g<subscript>3</subscript></entry>
138 <entry>g<subscript>2</subscript></entry>
139 <entry>g<subscript>1</subscript></entry>
140 <entry>g<subscript>0</subscript></entry>
141 <entry>b<subscript>3</subscript></entry>
142 <entry>b<subscript>2</subscript></entry>
143 <entry>b<subscript>1</subscript></entry>
144 <entry>b<subscript>0</subscript></entry>
145 <entry></entry>
146 <entry>a<subscript>3</subscript></entry>
147 <entry>a<subscript>2</subscript></entry>
148 <entry>a<subscript>1</subscript></entry>
149 <entry>a<subscript>0</subscript></entry>
150 <entry>r<subscript>3</subscript></entry>
151 <entry>r<subscript>2</subscript></entry>
152 <entry>r<subscript>1</subscript></entry>
153 <entry>r<subscript>0</subscript></entry>
154 </row>
155 <row id="V4L2-PIX-FMT-RGB555">
156 <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
157 <entry>'RGBO'</entry>
158 <entry></entry>
159 <entry>g<subscript>2</subscript></entry>
160 <entry>g<subscript>1</subscript></entry>
161 <entry>g<subscript>0</subscript></entry>
162 <entry>r<subscript>4</subscript></entry>
163 <entry>r<subscript>3</subscript></entry>
164 <entry>r<subscript>2</subscript></entry>
165 <entry>r<subscript>1</subscript></entry>
166 <entry>r<subscript>0</subscript></entry>
167 <entry></entry>
168 <entry>a</entry>
169 <entry>b<subscript>4</subscript></entry>
170 <entry>b<subscript>3</subscript></entry>
171 <entry>b<subscript>2</subscript></entry>
172 <entry>b<subscript>1</subscript></entry>
173 <entry>b<subscript>0</subscript></entry>
174 <entry>g<subscript>4</subscript></entry>
175 <entry>g<subscript>3</subscript></entry>
176 </row>
177 <row id="V4L2-PIX-FMT-RGB565">
178 <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
179 <entry>'RGBP'</entry>
180 <entry></entry>
181 <entry>g<subscript>2</subscript></entry>
182 <entry>g<subscript>1</subscript></entry>
183 <entry>g<subscript>0</subscript></entry>
184 <entry>r<subscript>4</subscript></entry>
185 <entry>r<subscript>3</subscript></entry>
186 <entry>r<subscript>2</subscript></entry>
187 <entry>r<subscript>1</subscript></entry>
188 <entry>r<subscript>0</subscript></entry>
189 <entry></entry>
190 <entry>b<subscript>4</subscript></entry>
191 <entry>b<subscript>3</subscript></entry>
192 <entry>b<subscript>2</subscript></entry>
193 <entry>b<subscript>1</subscript></entry>
194 <entry>b<subscript>0</subscript></entry>
195 <entry>g<subscript>5</subscript></entry>
196 <entry>g<subscript>4</subscript></entry>
197 <entry>g<subscript>3</subscript></entry>
198 </row>
199 <row id="V4L2-PIX-FMT-RGB555X">
200 <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
201 <entry>'RGBQ'</entry>
202 <entry></entry>
203 <entry>a</entry>
204 <entry>b<subscript>4</subscript></entry>
205 <entry>b<subscript>3</subscript></entry>
206 <entry>b<subscript>2</subscript></entry>
207 <entry>b<subscript>1</subscript></entry>
208 <entry>b<subscript>0</subscript></entry>
209 <entry>g<subscript>4</subscript></entry>
210 <entry>g<subscript>3</subscript></entry>
211 <entry></entry>
212 <entry>g<subscript>2</subscript></entry>
213 <entry>g<subscript>1</subscript></entry>
214 <entry>g<subscript>0</subscript></entry>
215 <entry>r<subscript>4</subscript></entry>
216 <entry>r<subscript>3</subscript></entry>
217 <entry>r<subscript>2</subscript></entry>
218 <entry>r<subscript>1</subscript></entry>
219 <entry>r<subscript>0</subscript></entry>
220 </row>
221 <row id="V4L2-PIX-FMT-RGB565X">
222 <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
223 <entry>'RGBR'</entry>
224 <entry></entry>
225 <entry>b<subscript>4</subscript></entry>
226 <entry>b<subscript>3</subscript></entry>
227 <entry>b<subscript>2</subscript></entry>
228 <entry>b<subscript>1</subscript></entry>
229 <entry>b<subscript>0</subscript></entry>
230 <entry>g<subscript>5</subscript></entry>
231 <entry>g<subscript>4</subscript></entry>
232 <entry>g<subscript>3</subscript></entry>
233 <entry></entry>
234 <entry>g<subscript>2</subscript></entry>
235 <entry>g<subscript>1</subscript></entry>
236 <entry>g<subscript>0</subscript></entry>
237 <entry>r<subscript>4</subscript></entry>
238 <entry>r<subscript>3</subscript></entry>
239 <entry>r<subscript>2</subscript></entry>
240 <entry>r<subscript>1</subscript></entry>
241 <entry>r<subscript>0</subscript></entry>
242 </row>
243 <row id="V4L2-PIX-FMT-BGR24">
244 <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
245 <entry>'BGR3'</entry>
246 <entry></entry>
247 <entry>b<subscript>7</subscript></entry>
248 <entry>b<subscript>6</subscript></entry>
249 <entry>b<subscript>5</subscript></entry>
250 <entry>b<subscript>4</subscript></entry>
251 <entry>b<subscript>3</subscript></entry>
252 <entry>b<subscript>2</subscript></entry>
253 <entry>b<subscript>1</subscript></entry>
254 <entry>b<subscript>0</subscript></entry>
255 <entry></entry>
256 <entry>g<subscript>7</subscript></entry>
257 <entry>g<subscript>6</subscript></entry>
258 <entry>g<subscript>5</subscript></entry>
259 <entry>g<subscript>4</subscript></entry>
260 <entry>g<subscript>3</subscript></entry>
261 <entry>g<subscript>2</subscript></entry>
262 <entry>g<subscript>1</subscript></entry>
263 <entry>g<subscript>0</subscript></entry>
264 <entry></entry>
265 <entry>r<subscript>7</subscript></entry>
266 <entry>r<subscript>6</subscript></entry>
267 <entry>r<subscript>5</subscript></entry>
268 <entry>r<subscript>4</subscript></entry>
269 <entry>r<subscript>3</subscript></entry>
270 <entry>r<subscript>2</subscript></entry>
271 <entry>r<subscript>1</subscript></entry>
272 <entry>r<subscript>0</subscript></entry>
273 </row>
274 <row id="V4L2-PIX-FMT-RGB24">
275 <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
276 <entry>'RGB3'</entry>
277 <entry></entry>
278 <entry>r<subscript>7</subscript></entry>
279 <entry>r<subscript>6</subscript></entry>
280 <entry>r<subscript>5</subscript></entry>
281 <entry>r<subscript>4</subscript></entry>
282 <entry>r<subscript>3</subscript></entry>
283 <entry>r<subscript>2</subscript></entry>
284 <entry>r<subscript>1</subscript></entry>
285 <entry>r<subscript>0</subscript></entry>
286 <entry></entry>
287 <entry>g<subscript>7</subscript></entry>
288 <entry>g<subscript>6</subscript></entry>
289 <entry>g<subscript>5</subscript></entry>
290 <entry>g<subscript>4</subscript></entry>
291 <entry>g<subscript>3</subscript></entry>
292 <entry>g<subscript>2</subscript></entry>
293 <entry>g<subscript>1</subscript></entry>
294 <entry>g<subscript>0</subscript></entry>
295 <entry></entry>
296 <entry>b<subscript>7</subscript></entry>
297 <entry>b<subscript>6</subscript></entry>
298 <entry>b<subscript>5</subscript></entry>
299 <entry>b<subscript>4</subscript></entry>
300 <entry>b<subscript>3</subscript></entry>
301 <entry>b<subscript>2</subscript></entry>
302 <entry>b<subscript>1</subscript></entry>
303 <entry>b<subscript>0</subscript></entry>
304 </row>
305 <row id="V4L2-PIX-FMT-BGR32">
306 <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
307 <entry>'BGR4'</entry>
308 <entry></entry>
309 <entry>b<subscript>7</subscript></entry>
310 <entry>b<subscript>6</subscript></entry>
311 <entry>b<subscript>5</subscript></entry>
312 <entry>b<subscript>4</subscript></entry>
313 <entry>b<subscript>3</subscript></entry>
314 <entry>b<subscript>2</subscript></entry>
315 <entry>b<subscript>1</subscript></entry>
316 <entry>b<subscript>0</subscript></entry>
317 <entry></entry>
318 <entry>g<subscript>7</subscript></entry>
319 <entry>g<subscript>6</subscript></entry>
320 <entry>g<subscript>5</subscript></entry>
321 <entry>g<subscript>4</subscript></entry>
322 <entry>g<subscript>3</subscript></entry>
323 <entry>g<subscript>2</subscript></entry>
324 <entry>g<subscript>1</subscript></entry>
325 <entry>g<subscript>0</subscript></entry>
326 <entry></entry>
327 <entry>r<subscript>7</subscript></entry>
328 <entry>r<subscript>6</subscript></entry>
329 <entry>r<subscript>5</subscript></entry>
330 <entry>r<subscript>4</subscript></entry>
331 <entry>r<subscript>3</subscript></entry>
332 <entry>r<subscript>2</subscript></entry>
333 <entry>r<subscript>1</subscript></entry>
334 <entry>r<subscript>0</subscript></entry>
335 <entry></entry>
336 <entry>a<subscript>7</subscript></entry>
337 <entry>a<subscript>6</subscript></entry>
338 <entry>a<subscript>5</subscript></entry>
339 <entry>a<subscript>4</subscript></entry>
340 <entry>a<subscript>3</subscript></entry>
341 <entry>a<subscript>2</subscript></entry>
342 <entry>a<subscript>1</subscript></entry>
343 <entry>a<subscript>0</subscript></entry>
344 </row>
345 <row id="V4L2-PIX-FMT-RGB32">
346 <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
347 <entry>'RGB4'</entry>
348 <entry></entry>
349 <entry>r<subscript>7</subscript></entry>
350 <entry>r<subscript>6</subscript></entry>
351 <entry>r<subscript>5</subscript></entry>
352 <entry>r<subscript>4</subscript></entry>
353 <entry>r<subscript>3</subscript></entry>
354 <entry>r<subscript>2</subscript></entry>
355 <entry>r<subscript>1</subscript></entry>
356 <entry>r<subscript>0</subscript></entry>
357 <entry></entry>
358 <entry>g<subscript>7</subscript></entry>
359 <entry>g<subscript>6</subscript></entry>
360 <entry>g<subscript>5</subscript></entry>
361 <entry>g<subscript>4</subscript></entry>
362 <entry>g<subscript>3</subscript></entry>
363 <entry>g<subscript>2</subscript></entry>
364 <entry>g<subscript>1</subscript></entry>
365 <entry>g<subscript>0</subscript></entry>
366 <entry></entry>
367 <entry>b<subscript>7</subscript></entry>
368 <entry>b<subscript>6</subscript></entry>
369 <entry>b<subscript>5</subscript></entry>
370 <entry>b<subscript>4</subscript></entry>
371 <entry>b<subscript>3</subscript></entry>
372 <entry>b<subscript>2</subscript></entry>
373 <entry>b<subscript>1</subscript></entry>
374 <entry>b<subscript>0</subscript></entry>
375 <entry></entry>
376 <entry>a<subscript>7</subscript></entry>
377 <entry>a<subscript>6</subscript></entry>
378 <entry>a<subscript>5</subscript></entry>
379 <entry>a<subscript>4</subscript></entry>
380 <entry>a<subscript>3</subscript></entry>
381 <entry>a<subscript>2</subscript></entry>
382 <entry>a<subscript>1</subscript></entry>
383 <entry>a<subscript>0</subscript></entry>
384 </row>
385 </tbody>
386 </tgroup>
387 </table>
388
389 <para>Bit 7 is the most significant bit. The value of a = alpha
390bits is undefined when reading from the driver, ignored when writing
391to the driver, except when alpha blending has been negotiated for a
392<link linkend="overlay">Video Overlay</link> or <link
393linkend="osd">Video Output Overlay</link>.</para>
394
395 <example>
396 <title><constant>V4L2_PIX_FMT_BGR24</constant> 4 &times; 4 pixel
397image</title>
398
399 <formalpara>
400 <title>Byte Order.</title>
401 <para>Each cell is one byte.
402 <informaltable frame="none">
403 <tgroup cols="13" align="center">
404 <colspec align="left" colwidth="2*" />
405 <tbody valign="top">
406 <row>
407 <entry>start&nbsp;+&nbsp;0:</entry>
408 <entry>B<subscript>00</subscript></entry>
409 <entry>G<subscript>00</subscript></entry>
410 <entry>R<subscript>00</subscript></entry>
411 <entry>B<subscript>01</subscript></entry>
412 <entry>G<subscript>01</subscript></entry>
413 <entry>R<subscript>01</subscript></entry>
414 <entry>B<subscript>02</subscript></entry>
415 <entry>G<subscript>02</subscript></entry>
416 <entry>R<subscript>02</subscript></entry>
417 <entry>B<subscript>03</subscript></entry>
418 <entry>G<subscript>03</subscript></entry>
419 <entry>R<subscript>03</subscript></entry>
420 </row>
421 <row>
422 <entry>start&nbsp;+&nbsp;12:</entry>
423 <entry>B<subscript>10</subscript></entry>
424 <entry>G<subscript>10</subscript></entry>
425 <entry>R<subscript>10</subscript></entry>
426 <entry>B<subscript>11</subscript></entry>
427 <entry>G<subscript>11</subscript></entry>
428 <entry>R<subscript>11</subscript></entry>
429 <entry>B<subscript>12</subscript></entry>
430 <entry>G<subscript>12</subscript></entry>
431 <entry>R<subscript>12</subscript></entry>
432 <entry>B<subscript>13</subscript></entry>
433 <entry>G<subscript>13</subscript></entry>
434 <entry>R<subscript>13</subscript></entry>
435 </row>
436 <row>
437 <entry>start&nbsp;+&nbsp;24:</entry>
438 <entry>B<subscript>20</subscript></entry>
439 <entry>G<subscript>20</subscript></entry>
440 <entry>R<subscript>20</subscript></entry>
441 <entry>B<subscript>21</subscript></entry>
442 <entry>G<subscript>21</subscript></entry>
443 <entry>R<subscript>21</subscript></entry>
444 <entry>B<subscript>22</subscript></entry>
445 <entry>G<subscript>22</subscript></entry>
446 <entry>R<subscript>22</subscript></entry>
447 <entry>B<subscript>23</subscript></entry>
448 <entry>G<subscript>23</subscript></entry>
449 <entry>R<subscript>23</subscript></entry>
450 </row>
451 <row>
452 <entry>start&nbsp;+&nbsp;36:</entry>
453 <entry>B<subscript>30</subscript></entry>
454 <entry>G<subscript>30</subscript></entry>
455 <entry>R<subscript>30</subscript></entry>
456 <entry>B<subscript>31</subscript></entry>
457 <entry>G<subscript>31</subscript></entry>
458 <entry>R<subscript>31</subscript></entry>
459 <entry>B<subscript>32</subscript></entry>
460 <entry>G<subscript>32</subscript></entry>
461 <entry>R<subscript>32</subscript></entry>
462 <entry>B<subscript>33</subscript></entry>
463 <entry>G<subscript>33</subscript></entry>
464 <entry>R<subscript>33</subscript></entry>
465 </row>
466 </tbody>
467 </tgroup>
468 </informaltable>
469 </para>
470 </formalpara>
471 </example>
472
473 <important>
474 <para>Drivers may interpret these formats differently.</para>
475 </important>
476
477 <para>Some RGB formats above are uncommon and were probably
478defined in error. Drivers may interpret them as in <xref
479 linkend="rgb-formats-corrected" />.</para>
480
481 <table pgwide="1" frame="none" id="rgb-formats-corrected">
482 <title>Packed RGB Image Formats (corrected)</title>
483 <tgroup cols="37" align="center">
484 <colspec colname="id" align="left" />
485 <colspec colname="fourcc" />
486 <colspec colname="bit" />
487
488 <colspec colnum="4" colname="b07" align="center" />
489 <colspec colnum="5" colname="b06" align="center" />
490 <colspec colnum="6" colname="b05" align="center" />
491 <colspec colnum="7" colname="b04" align="center" />
492 <colspec colnum="8" colname="b03" align="center" />
493 <colspec colnum="9" colname="b02" align="center" />
494 <colspec colnum="10" colname="b01" align="center" />
495 <colspec colnum="11" colname="b00" align="center" />
496
497 <colspec colnum="13" colname="b17" align="center" />
498 <colspec colnum="14" colname="b16" align="center" />
499 <colspec colnum="15" colname="b15" align="center" />
500 <colspec colnum="16" colname="b14" align="center" />
501 <colspec colnum="17" colname="b13" align="center" />
502 <colspec colnum="18" colname="b12" align="center" />
503 <colspec colnum="19" colname="b11" align="center" />
504 <colspec colnum="20" colname="b10" align="center" />
505
506 <colspec colnum="22" colname="b27" align="center" />
507 <colspec colnum="23" colname="b26" align="center" />
508 <colspec colnum="24" colname="b25" align="center" />
509 <colspec colnum="25" colname="b24" align="center" />
510 <colspec colnum="26" colname="b23" align="center" />
511 <colspec colnum="27" colname="b22" align="center" />
512 <colspec colnum="28" colname="b21" align="center" />
513 <colspec colnum="29" colname="b20" align="center" />
514
515 <colspec colnum="31" colname="b37" align="center" />
516 <colspec colnum="32" colname="b36" align="center" />
517 <colspec colnum="33" colname="b35" align="center" />
518 <colspec colnum="34" colname="b34" align="center" />
519 <colspec colnum="35" colname="b33" align="center" />
520 <colspec colnum="36" colname="b32" align="center" />
521 <colspec colnum="37" colname="b31" align="center" />
522 <colspec colnum="38" colname="b30" align="center" />
523
524 <spanspec namest="b07" nameend="b00" spanname="b0" />
525 <spanspec namest="b17" nameend="b10" spanname="b1" />
526 <spanspec namest="b27" nameend="b20" spanname="b2" />
527 <spanspec namest="b37" nameend="b30" spanname="b3" />
528 <thead>
529 <row>
530 <entry>Identifier</entry>
531 <entry>Code</entry>
532 <entry>&nbsp;</entry>
533 <entry spanname="b0">Byte&nbsp;0 in memory</entry>
534 <entry spanname="b1">Byte&nbsp;1</entry>
535 <entry spanname="b2">Byte&nbsp;2</entry>
536 <entry spanname="b3">Byte&nbsp;3</entry>
537 </row>
538 <row>
539 <entry>&nbsp;</entry>
540 <entry>&nbsp;</entry>
541 <entry>Bit</entry>
542 <entry>7</entry>
543 <entry>6</entry>
544 <entry>5</entry>
545 <entry>4</entry>
546 <entry>3</entry>
547 <entry>2</entry>
548 <entry>1</entry>
549 <entry>0</entry>
550 <entry>&nbsp;</entry>
551 <entry>7</entry>
552 <entry>6</entry>
553 <entry>5</entry>
554 <entry>4</entry>
555 <entry>3</entry>
556 <entry>2</entry>
557 <entry>1</entry>
558 <entry>0</entry>
559 <entry>&nbsp;</entry>
560 <entry>7</entry>
561 <entry>6</entry>
562 <entry>5</entry>
563 <entry>4</entry>
564 <entry>3</entry>
565 <entry>2</entry>
566 <entry>1</entry>
567 <entry>0</entry>
568 <entry>&nbsp;</entry>
569 <entry>7</entry>
570 <entry>6</entry>
571 <entry>5</entry>
572 <entry>4</entry>
573 <entry>3</entry>
574 <entry>2</entry>
575 <entry>1</entry>
576 <entry>0</entry>
577 </row>
578 </thead>
579 <tbody valign="top">
580 <row><!-- id="V4L2-PIX-FMT-RGB332" -->
581 <entry><constant>V4L2_PIX_FMT_RGB332</constant></entry>
582 <entry>'RGB1'</entry>
583 <entry></entry>
584 <entry>r<subscript>2</subscript></entry>
585 <entry>r<subscript>1</subscript></entry>
586 <entry>r<subscript>0</subscript></entry>
587 <entry>g<subscript>2</subscript></entry>
588 <entry>g<subscript>1</subscript></entry>
589 <entry>g<subscript>0</subscript></entry>
590 <entry>b<subscript>1</subscript></entry>
591 <entry>b<subscript>0</subscript></entry>
592 </row>
593 <row><!-- id="V4L2-PIX-FMT-RGB444" -->
594 <entry><constant>V4L2_PIX_FMT_RGB444</constant></entry>
595 <entry>'R444'</entry>
596 <entry></entry>
597 <entry>g<subscript>3</subscript></entry>
598 <entry>g<subscript>2</subscript></entry>
599 <entry>g<subscript>1</subscript></entry>
600 <entry>g<subscript>0</subscript></entry>
601 <entry>b<subscript>3</subscript></entry>
602 <entry>b<subscript>2</subscript></entry>
603 <entry>b<subscript>1</subscript></entry>
604 <entry>b<subscript>0</subscript></entry>
605 <entry></entry>
606 <entry>a<subscript>3</subscript></entry>
607 <entry>a<subscript>2</subscript></entry>
608 <entry>a<subscript>1</subscript></entry>
609 <entry>a<subscript>0</subscript></entry>
610 <entry>r<subscript>3</subscript></entry>
611 <entry>r<subscript>2</subscript></entry>
612 <entry>r<subscript>1</subscript></entry>
613 <entry>r<subscript>0</subscript></entry>
614 </row>
615 <row><!-- id="V4L2-PIX-FMT-RGB555" -->
616 <entry><constant>V4L2_PIX_FMT_RGB555</constant></entry>
617 <entry>'RGBO'</entry>
618 <entry></entry>
619 <entry>g<subscript>2</subscript></entry>
620 <entry>g<subscript>1</subscript></entry>
621 <entry>g<subscript>0</subscript></entry>
622 <entry>b<subscript>4</subscript></entry>
623 <entry>b<subscript>3</subscript></entry>
624 <entry>b<subscript>2</subscript></entry>
625 <entry>b<subscript>1</subscript></entry>
626 <entry>b<subscript>0</subscript></entry>
627 <entry></entry>
628 <entry>a</entry>
629 <entry>r<subscript>4</subscript></entry>
630 <entry>r<subscript>3</subscript></entry>
631 <entry>r<subscript>2</subscript></entry>
632 <entry>r<subscript>1</subscript></entry>
633 <entry>r<subscript>0</subscript></entry>
634 <entry>g<subscript>4</subscript></entry>
635 <entry>g<subscript>3</subscript></entry>
636 </row>
637 <row><!-- id="V4L2-PIX-FMT-RGB565" -->
638 <entry><constant>V4L2_PIX_FMT_RGB565</constant></entry>
639 <entry>'RGBP'</entry>
640 <entry></entry>
641 <entry>g<subscript>2</subscript></entry>
642 <entry>g<subscript>1</subscript></entry>
643 <entry>g<subscript>0</subscript></entry>
644 <entry>b<subscript>4</subscript></entry>
645 <entry>b<subscript>3</subscript></entry>
646 <entry>b<subscript>2</subscript></entry>
647 <entry>b<subscript>1</subscript></entry>
648 <entry>b<subscript>0</subscript></entry>
649 <entry></entry>
650 <entry>r<subscript>4</subscript></entry>
651 <entry>r<subscript>3</subscript></entry>
652 <entry>r<subscript>2</subscript></entry>
653 <entry>r<subscript>1</subscript></entry>
654 <entry>r<subscript>0</subscript></entry>
655 <entry>g<subscript>5</subscript></entry>
656 <entry>g<subscript>4</subscript></entry>
657 <entry>g<subscript>3</subscript></entry>
658 </row>
659 <row><!-- id="V4L2-PIX-FMT-RGB555X" -->
660 <entry><constant>V4L2_PIX_FMT_RGB555X</constant></entry>
661 <entry>'RGBQ'</entry>
662 <entry></entry>
663 <entry>a</entry>
664 <entry>r<subscript>4</subscript></entry>
665 <entry>r<subscript>3</subscript></entry>
666 <entry>r<subscript>2</subscript></entry>
667 <entry>r<subscript>1</subscript></entry>
668 <entry>r<subscript>0</subscript></entry>
669 <entry>g<subscript>4</subscript></entry>
670 <entry>g<subscript>3</subscript></entry>
671 <entry></entry>
672 <entry>g<subscript>2</subscript></entry>
673 <entry>g<subscript>1</subscript></entry>
674 <entry>g<subscript>0</subscript></entry>
675 <entry>b<subscript>4</subscript></entry>
676 <entry>b<subscript>3</subscript></entry>
677 <entry>b<subscript>2</subscript></entry>
678 <entry>b<subscript>1</subscript></entry>
679 <entry>b<subscript>0</subscript></entry>
680 </row>
681 <row><!-- id="V4L2-PIX-FMT-RGB565X" -->
682 <entry><constant>V4L2_PIX_FMT_RGB565X</constant></entry>
683 <entry>'RGBR'</entry>
684 <entry></entry>
685 <entry>r<subscript>4</subscript></entry>
686 <entry>r<subscript>3</subscript></entry>
687 <entry>r<subscript>2</subscript></entry>
688 <entry>r<subscript>1</subscript></entry>
689 <entry>r<subscript>0</subscript></entry>
690 <entry>g<subscript>5</subscript></entry>
691 <entry>g<subscript>4</subscript></entry>
692 <entry>g<subscript>3</subscript></entry>
693 <entry></entry>
694 <entry>g<subscript>2</subscript></entry>
695 <entry>g<subscript>1</subscript></entry>
696 <entry>g<subscript>0</subscript></entry>
697 <entry>b<subscript>4</subscript></entry>
698 <entry>b<subscript>3</subscript></entry>
699 <entry>b<subscript>2</subscript></entry>
700 <entry>b<subscript>1</subscript></entry>
701 <entry>b<subscript>0</subscript></entry>
702 </row>
703 <row><!-- id="V4L2-PIX-FMT-BGR24" -->
704 <entry><constant>V4L2_PIX_FMT_BGR24</constant></entry>
705 <entry>'BGR3'</entry>
706 <entry></entry>
707 <entry>b<subscript>7</subscript></entry>
708 <entry>b<subscript>6</subscript></entry>
709 <entry>b<subscript>5</subscript></entry>
710 <entry>b<subscript>4</subscript></entry>
711 <entry>b<subscript>3</subscript></entry>
712 <entry>b<subscript>2</subscript></entry>
713 <entry>b<subscript>1</subscript></entry>
714 <entry>b<subscript>0</subscript></entry>
715 <entry></entry>
716 <entry>g<subscript>7</subscript></entry>
717 <entry>g<subscript>6</subscript></entry>
718 <entry>g<subscript>5</subscript></entry>
719 <entry>g<subscript>4</subscript></entry>
720 <entry>g<subscript>3</subscript></entry>
721 <entry>g<subscript>2</subscript></entry>
722 <entry>g<subscript>1</subscript></entry>
723 <entry>g<subscript>0</subscript></entry>
724 <entry></entry>
725 <entry>r<subscript>7</subscript></entry>
726 <entry>r<subscript>6</subscript></entry>
727 <entry>r<subscript>5</subscript></entry>
728 <entry>r<subscript>4</subscript></entry>
729 <entry>r<subscript>3</subscript></entry>
730 <entry>r<subscript>2</subscript></entry>
731 <entry>r<subscript>1</subscript></entry>
732 <entry>r<subscript>0</subscript></entry>
733 </row>
734 <row><!-- id="V4L2-PIX-FMT-RGB24" -->
735 <entry><constant>V4L2_PIX_FMT_RGB24</constant></entry>
736 <entry>'RGB3'</entry>
737 <entry></entry>
738 <entry>r<subscript>7</subscript></entry>
739 <entry>r<subscript>6</subscript></entry>
740 <entry>r<subscript>5</subscript></entry>
741 <entry>r<subscript>4</subscript></entry>
742 <entry>r<subscript>3</subscript></entry>
743 <entry>r<subscript>2</subscript></entry>
744 <entry>r<subscript>1</subscript></entry>
745 <entry>r<subscript>0</subscript></entry>
746 <entry></entry>
747 <entry>g<subscript>7</subscript></entry>
748 <entry>g<subscript>6</subscript></entry>
749 <entry>g<subscript>5</subscript></entry>
750 <entry>g<subscript>4</subscript></entry>
751 <entry>g<subscript>3</subscript></entry>
752 <entry>g<subscript>2</subscript></entry>
753 <entry>g<subscript>1</subscript></entry>
754 <entry>g<subscript>0</subscript></entry>
755 <entry></entry>
756 <entry>b<subscript>7</subscript></entry>
757 <entry>b<subscript>6</subscript></entry>
758 <entry>b<subscript>5</subscript></entry>
759 <entry>b<subscript>4</subscript></entry>
760 <entry>b<subscript>3</subscript></entry>
761 <entry>b<subscript>2</subscript></entry>
762 <entry>b<subscript>1</subscript></entry>
763 <entry>b<subscript>0</subscript></entry>
764 </row>
765 <row><!-- id="V4L2-PIX-FMT-BGR32" -->
766 <entry><constant>V4L2_PIX_FMT_BGR32</constant></entry>
767 <entry>'BGR4'</entry>
768 <entry></entry>
769 <entry>b<subscript>7</subscript></entry>
770 <entry>b<subscript>6</subscript></entry>
771 <entry>b<subscript>5</subscript></entry>
772 <entry>b<subscript>4</subscript></entry>
773 <entry>b<subscript>3</subscript></entry>
774 <entry>b<subscript>2</subscript></entry>
775 <entry>b<subscript>1</subscript></entry>
776 <entry>b<subscript>0</subscript></entry>
777 <entry></entry>
778 <entry>g<subscript>7</subscript></entry>
779 <entry>g<subscript>6</subscript></entry>
780 <entry>g<subscript>5</subscript></entry>
781 <entry>g<subscript>4</subscript></entry>
782 <entry>g<subscript>3</subscript></entry>
783 <entry>g<subscript>2</subscript></entry>
784 <entry>g<subscript>1</subscript></entry>
785 <entry>g<subscript>0</subscript></entry>
786 <entry></entry>
787 <entry>r<subscript>7</subscript></entry>
788 <entry>r<subscript>6</subscript></entry>
789 <entry>r<subscript>5</subscript></entry>
790 <entry>r<subscript>4</subscript></entry>
791 <entry>r<subscript>3</subscript></entry>
792 <entry>r<subscript>2</subscript></entry>
793 <entry>r<subscript>1</subscript></entry>
794 <entry>r<subscript>0</subscript></entry>
795 <entry></entry>
796 <entry>a<subscript>7</subscript></entry>
797 <entry>a<subscript>6</subscript></entry>
798 <entry>a<subscript>5</subscript></entry>
799 <entry>a<subscript>4</subscript></entry>
800 <entry>a<subscript>3</subscript></entry>
801 <entry>a<subscript>2</subscript></entry>
802 <entry>a<subscript>1</subscript></entry>
803 <entry>a<subscript>0</subscript></entry>
804 </row>
805 <row><!-- id="V4L2-PIX-FMT-RGB32" -->
806 <entry><constant>V4L2_PIX_FMT_RGB32</constant></entry>
807 <entry>'RGB4'</entry>
808 <entry></entry>
809 <entry>a<subscript>7</subscript></entry>
810 <entry>a<subscript>6</subscript></entry>
811 <entry>a<subscript>5</subscript></entry>
812 <entry>a<subscript>4</subscript></entry>
813 <entry>a<subscript>3</subscript></entry>
814 <entry>a<subscript>2</subscript></entry>
815 <entry>a<subscript>1</subscript></entry>
816 <entry>a<subscript>0</subscript></entry>
817 <entry></entry>
818 <entry>r<subscript>7</subscript></entry>
819 <entry>r<subscript>6</subscript></entry>
820 <entry>r<subscript>5</subscript></entry>
821 <entry>r<subscript>4</subscript></entry>
822 <entry>r<subscript>3</subscript></entry>
823 <entry>r<subscript>2</subscript></entry>
824 <entry>r<subscript>1</subscript></entry>
825 <entry>r<subscript>0</subscript></entry>
826 <entry></entry>
827 <entry>g<subscript>7</subscript></entry>
828 <entry>g<subscript>6</subscript></entry>
829 <entry>g<subscript>5</subscript></entry>
830 <entry>g<subscript>4</subscript></entry>
831 <entry>g<subscript>3</subscript></entry>
832 <entry>g<subscript>2</subscript></entry>
833 <entry>g<subscript>1</subscript></entry>
834 <entry>g<subscript>0</subscript></entry>
835 <entry></entry>
836 <entry>b<subscript>7</subscript></entry>
837 <entry>b<subscript>6</subscript></entry>
838 <entry>b<subscript>5</subscript></entry>
839 <entry>b<subscript>4</subscript></entry>
840 <entry>b<subscript>3</subscript></entry>
841 <entry>b<subscript>2</subscript></entry>
842 <entry>b<subscript>1</subscript></entry>
843 <entry>b<subscript>0</subscript></entry>
844 </row>
845 </tbody>
846 </tgroup>
847 </table>
848
849 <para>A test utility to determine which RGB formats a driver
850actually supports is available from the LinuxTV v4l-dvb repository.
851See &v4l-dvb; for access instructions.</para>
852
853 </refsect1>
854 </refentry>
855
856 <!--
857Local Variables:
858mode: sgml
859sgml-parent-document: "pixfmt.sgml"
860indent-tabs-mode: nil
861End:
862 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml b/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml
new file mode 100644
index 000000000000..3cab5d0ca75d
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-packed-yuv.xml
@@ -0,0 +1,244 @@
1<refentry id="packed-yuv">
2 <refmeta>
3 <refentrytitle>Packed YUV formats</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname>Packed YUV formats</refname>
8 <refpurpose>Packed YUV formats</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>Similar to the packed RGB formats these formats store
14the Y, Cb and Cr component of each pixel in one 16 or 32 bit
15word.</para>
16
17 <table pgwide="1" frame="none">
18 <title>Packed YUV Image Formats</title>
19 <tgroup cols="37" align="center">
20 <colspec colname="id" align="left" />
21 <colspec colname="fourcc" />
22 <colspec colname="bit" />
23
24 <colspec colnum="4" colname="b07" align="center" />
25 <colspec colnum="5" colname="b06" align="center" />
26 <colspec colnum="6" colname="b05" align="center" />
27 <colspec colnum="7" colname="b04" align="center" />
28 <colspec colnum="8" colname="b03" align="center" />
29 <colspec colnum="9" colname="b02" align="center" />
30 <colspec colnum="10" colname="b01" align="center" />
31 <colspec colnum="11" colname="b00" align="center" />
32
33 <colspec colnum="13" colname="b17" align="center" />
34 <colspec colnum="14" colname="b16" align="center" />
35 <colspec colnum="15" colname="b15" align="center" />
36 <colspec colnum="16" colname="b14" align="center" />
37 <colspec colnum="17" colname="b13" align="center" />
38 <colspec colnum="18" colname="b12" align="center" />
39 <colspec colnum="19" colname="b11" align="center" />
40 <colspec colnum="20" colname="b10" align="center" />
41
42 <colspec colnum="22" colname="b27" align="center" />
43 <colspec colnum="23" colname="b26" align="center" />
44 <colspec colnum="24" colname="b25" align="center" />
45 <colspec colnum="25" colname="b24" align="center" />
46 <colspec colnum="26" colname="b23" align="center" />
47 <colspec colnum="27" colname="b22" align="center" />
48 <colspec colnum="28" colname="b21" align="center" />
49 <colspec colnum="29" colname="b20" align="center" />
50
51 <colspec colnum="31" colname="b37" align="center" />
52 <colspec colnum="32" colname="b36" align="center" />
53 <colspec colnum="33" colname="b35" align="center" />
54 <colspec colnum="34" colname="b34" align="center" />
55 <colspec colnum="35" colname="b33" align="center" />
56 <colspec colnum="36" colname="b32" align="center" />
57 <colspec colnum="37" colname="b31" align="center" />
58 <colspec colnum="38" colname="b30" align="center" />
59
60 <spanspec namest="b07" nameend="b00" spanname="b0" />
61 <spanspec namest="b17" nameend="b10" spanname="b1" />
62 <spanspec namest="b27" nameend="b20" spanname="b2" />
63 <spanspec namest="b37" nameend="b30" spanname="b3" />
64 <thead>
65 <row>
66 <entry>Identifier</entry>
67 <entry>Code</entry>
68 <entry>&nbsp;</entry>
69 <entry spanname="b0">Byte&nbsp;0 in memory</entry>
70 <entry spanname="b1">Byte&nbsp;1</entry>
71 <entry spanname="b2">Byte&nbsp;2</entry>
72 <entry spanname="b3">Byte&nbsp;3</entry>
73 </row>
74 <row>
75 <entry>&nbsp;</entry>
76 <entry>&nbsp;</entry>
77 <entry>Bit</entry>
78 <entry>7</entry>
79 <entry>6</entry>
80 <entry>5</entry>
81 <entry>4</entry>
82 <entry>3</entry>
83 <entry>2</entry>
84 <entry>1</entry>
85 <entry>0</entry>
86 <entry>&nbsp;</entry>
87 <entry>7</entry>
88 <entry>6</entry>
89 <entry>5</entry>
90 <entry>4</entry>
91 <entry>3</entry>
92 <entry>2</entry>
93 <entry>1</entry>
94 <entry>0</entry>
95 <entry>&nbsp;</entry>
96 <entry>7</entry>
97 <entry>6</entry>
98 <entry>5</entry>
99 <entry>4</entry>
100 <entry>3</entry>
101 <entry>2</entry>
102 <entry>1</entry>
103 <entry>0</entry>
104 <entry>&nbsp;</entry>
105 <entry>7</entry>
106 <entry>6</entry>
107 <entry>5</entry>
108 <entry>4</entry>
109 <entry>3</entry>
110 <entry>2</entry>
111 <entry>1</entry>
112 <entry>0</entry>
113 </row>
114 </thead>
115 <tbody valign="top">
116 <row id="V4L2-PIX-FMT-YUV444">
117 <entry><constant>V4L2_PIX_FMT_YUV444</constant></entry>
118 <entry>'Y444'</entry>
119 <entry></entry>
120 <entry>Cb<subscript>3</subscript></entry>
121 <entry>Cb<subscript>2</subscript></entry>
122 <entry>Cb<subscript>1</subscript></entry>
123 <entry>Cb<subscript>0</subscript></entry>
124 <entry>Cr<subscript>3</subscript></entry>
125 <entry>Cr<subscript>2</subscript></entry>
126 <entry>Cr<subscript>1</subscript></entry>
127 <entry>Cr<subscript>0</subscript></entry>
128 <entry></entry>
129 <entry>a<subscript>3</subscript></entry>
130 <entry>a<subscript>2</subscript></entry>
131 <entry>a<subscript>1</subscript></entry>
132 <entry>a<subscript>0</subscript></entry>
133 <entry>Y'<subscript>3</subscript></entry>
134 <entry>Y'<subscript>2</subscript></entry>
135 <entry>Y'<subscript>1</subscript></entry>
136 <entry>Y'<subscript>0</subscript></entry>
137 </row>
138
139 <row id="V4L2-PIX-FMT-YUV555">
140 <entry><constant>V4L2_PIX_FMT_YUV555</constant></entry>
141 <entry>'YUVO'</entry>
142 <entry></entry>
143 <entry>Cb<subscript>2</subscript></entry>
144 <entry>Cb<subscript>1</subscript></entry>
145 <entry>Cb<subscript>0</subscript></entry>
146 <entry>Cr<subscript>4</subscript></entry>
147 <entry>Cr<subscript>3</subscript></entry>
148 <entry>Cr<subscript>2</subscript></entry>
149 <entry>Cr<subscript>1</subscript></entry>
150 <entry>Cr<subscript>0</subscript></entry>
151 <entry></entry>
152 <entry>a</entry>
153 <entry>Y'<subscript>4</subscript></entry>
154 <entry>Y'<subscript>3</subscript></entry>
155 <entry>Y'<subscript>2</subscript></entry>
156 <entry>Y'<subscript>1</subscript></entry>
157 <entry>Y'<subscript>0</subscript></entry>
158 <entry>Cb<subscript>4</subscript></entry>
159 <entry>Cb<subscript>3</subscript></entry>
160 </row>
161
162 <row id="V4L2-PIX-FMT-YUV565">
163 <entry><constant>V4L2_PIX_FMT_YUV565</constant></entry>
164 <entry>'YUVP'</entry>
165 <entry></entry>
166 <entry>Cb<subscript>2</subscript></entry>
167 <entry>Cb<subscript>1</subscript></entry>
168 <entry>Cb<subscript>0</subscript></entry>
169 <entry>Cr<subscript>4</subscript></entry>
170 <entry>Cr<subscript>3</subscript></entry>
171 <entry>Cr<subscript>2</subscript></entry>
172 <entry>Cr<subscript>1</subscript></entry>
173 <entry>Cr<subscript>0</subscript></entry>
174 <entry></entry>
175 <entry>Y'<subscript>4</subscript></entry>
176 <entry>Y'<subscript>3</subscript></entry>
177 <entry>Y'<subscript>2</subscript></entry>
178 <entry>Y'<subscript>1</subscript></entry>
179 <entry>Y'<subscript>0</subscript></entry>
180 <entry>Cb<subscript>5</subscript></entry>
181 <entry>Cb<subscript>4</subscript></entry>
182 <entry>Cb<subscript>3</subscript></entry>
183 </row>
184
185 <row id="V4L2-PIX-FMT-YUV32">
186 <entry><constant>V4L2_PIX_FMT_YUV32</constant></entry>
187 <entry>'YUV4'</entry>
188 <entry></entry>
189 <entry>a<subscript>7</subscript></entry>
190 <entry>a<subscript>6</subscript></entry>
191 <entry>a<subscript>5</subscript></entry>
192 <entry>a<subscript>4</subscript></entry>
193 <entry>a<subscript>3</subscript></entry>
194 <entry>a<subscript>2</subscript></entry>
195 <entry>a<subscript>1</subscript></entry>
196 <entry>a<subscript>0</subscript></entry>
197 <entry></entry>
198 <entry>Y'<subscript>7</subscript></entry>
199 <entry>Y'<subscript>6</subscript></entry>
200 <entry>Y'<subscript>5</subscript></entry>
201 <entry>Y'<subscript>4</subscript></entry>
202 <entry>Y'<subscript>3</subscript></entry>
203 <entry>Y'<subscript>2</subscript></entry>
204 <entry>Y'<subscript>1</subscript></entry>
205 <entry>Y'<subscript>0</subscript></entry>
206 <entry></entry>
207 <entry>Cb<subscript>7</subscript></entry>
208 <entry>Cb<subscript>6</subscript></entry>
209 <entry>Cb<subscript>5</subscript></entry>
210 <entry>Cb<subscript>4</subscript></entry>
211 <entry>Cb<subscript>3</subscript></entry>
212 <entry>Cb<subscript>2</subscript></entry>
213 <entry>Cb<subscript>1</subscript></entry>
214 <entry>Cb<subscript>0</subscript></entry>
215 <entry></entry>
216 <entry>Cr<subscript>7</subscript></entry>
217 <entry>Cr<subscript>6</subscript></entry>
218 <entry>Cr<subscript>5</subscript></entry>
219 <entry>Cr<subscript>4</subscript></entry>
220 <entry>Cr<subscript>3</subscript></entry>
221 <entry>Cr<subscript>2</subscript></entry>
222 <entry>Cr<subscript>1</subscript></entry>
223 <entry>Cr<subscript>0</subscript></entry>
224 </row>
225 </tbody>
226 </tgroup>
227 </table>
228
229 <para>Bit 7 is the most significant bit. The value of a = alpha
230bits is undefined when reading from the driver, ignored when writing
231to the driver, except when alpha blending has been negotiated for a
232<link linkend="overlay">Video Overlay</link> or <link
233linkend="osd">Video Output Overlay</link>.</para>
234
235 </refsect1>
236 </refentry>
237
238 <!--
239Local Variables:
240mode: sgml
241sgml-parent-document: "pixfmt.sgml"
242indent-tabs-mode: nil
243End:
244 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sbggr16.xml b/Documentation/DocBook/v4l/pixfmt-sbggr16.xml
new file mode 100644
index 000000000000..519a9efbac10
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sbggr16.xml
@@ -0,0 +1,91 @@
1<refentry id="V4L2-PIX-FMT-SBGGR16">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SBGGR16 ('BYR2')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_SBGGR16</constant></refname>
8 <refpurpose>Bayer RGB format</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>This format is similar to <link
14linkend="V4L2-PIX-FMT-SBGGR8">
15<constant>V4L2_PIX_FMT_SBGGR8</constant></link>, except each pixel has
16a depth of 16 bits. The least significant byte is stored at lower
17memory addresses (little-endian). Note the actual sampling precision
18may be lower than 16 bits, for example 10 bits per pixel with values
19in range 0 to 1023.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_SBGGR16</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="5" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>B<subscript>00low</subscript></entry>
35 <entry>B<subscript>00high</subscript></entry>
36 <entry>G<subscript>01low</subscript></entry>
37 <entry>G<subscript>01high</subscript></entry>
38 <entry>B<subscript>02low</subscript></entry>
39 <entry>B<subscript>02high</subscript></entry>
40 <entry>G<subscript>03low</subscript></entry>
41 <entry>G<subscript>03high</subscript></entry>
42 </row>
43 <row>
44 <entry>start&nbsp;+&nbsp;8:</entry>
45 <entry>G<subscript>10low</subscript></entry>
46 <entry>G<subscript>10high</subscript></entry>
47 <entry>R<subscript>11low</subscript></entry>
48 <entry>R<subscript>11high</subscript></entry>
49 <entry>G<subscript>12low</subscript></entry>
50 <entry>G<subscript>12high</subscript></entry>
51 <entry>R<subscript>13low</subscript></entry>
52 <entry>R<subscript>13high</subscript></entry>
53 </row>
54 <row>
55 <entry>start&nbsp;+&nbsp;16:</entry>
56 <entry>B<subscript>20low</subscript></entry>
57 <entry>B<subscript>20high</subscript></entry>
58 <entry>G<subscript>21low</subscript></entry>
59 <entry>G<subscript>21high</subscript></entry>
60 <entry>B<subscript>22low</subscript></entry>
61 <entry>B<subscript>22high</subscript></entry>
62 <entry>G<subscript>23low</subscript></entry>
63 <entry>G<subscript>23high</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;24:</entry>
67 <entry>G<subscript>30low</subscript></entry>
68 <entry>G<subscript>30high</subscript></entry>
69 <entry>R<subscript>31low</subscript></entry>
70 <entry>R<subscript>31high</subscript></entry>
71 <entry>G<subscript>32low</subscript></entry>
72 <entry>G<subscript>32high</subscript></entry>
73 <entry>R<subscript>33low</subscript></entry>
74 <entry>R<subscript>33high</subscript></entry>
75 </row>
76 </tbody>
77 </tgroup>
78 </informaltable>
79 </para>
80 </formalpara>
81 </example>
82 </refsect1>
83</refentry>
84
85 <!--
86Local Variables:
87mode: sgml
88sgml-parent-document: "pixfmt.sgml"
89indent-tabs-mode: nil
90End:
91 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sbggr8.xml b/Documentation/DocBook/v4l/pixfmt-sbggr8.xml
new file mode 100644
index 000000000000..5fe84ecc2ebe
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sbggr8.xml
@@ -0,0 +1,75 @@
1 <refentry id="V4L2-PIX-FMT-SBGGR8">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SBGGR8 ('BA81')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_SBGGR8</constant></refname>
8 <refpurpose>Bayer RGB format</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>This is commonly the native format of digital cameras,
14reflecting the arrangement of sensors on the CCD device. Only one red,
15green or blue value is given for each pixel. Missing components must
16be interpolated from neighbouring pixels. From left to right the first
17row consists of a blue and green value, the second row of a green and
18red value. This scheme repeats to the right and down for every two
19columns and rows.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_SBGGR8</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="5" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>B<subscript>00</subscript></entry>
35 <entry>G<subscript>01</subscript></entry>
36 <entry>B<subscript>02</subscript></entry>
37 <entry>G<subscript>03</subscript></entry>
38 </row>
39 <row>
40 <entry>start&nbsp;+&nbsp;4:</entry>
41 <entry>G<subscript>10</subscript></entry>
42 <entry>R<subscript>11</subscript></entry>
43 <entry>G<subscript>12</subscript></entry>
44 <entry>R<subscript>13</subscript></entry>
45 </row>
46 <row>
47 <entry>start&nbsp;+&nbsp;8:</entry>
48 <entry>B<subscript>20</subscript></entry>
49 <entry>G<subscript>21</subscript></entry>
50 <entry>B<subscript>22</subscript></entry>
51 <entry>G<subscript>23</subscript></entry>
52 </row>
53 <row>
54 <entry>start&nbsp;+&nbsp;12:</entry>
55 <entry>G<subscript>30</subscript></entry>
56 <entry>R<subscript>31</subscript></entry>
57 <entry>G<subscript>32</subscript></entry>
58 <entry>R<subscript>33</subscript></entry>
59 </row>
60 </tbody>
61 </tgroup>
62 </informaltable>
63 </para>
64 </formalpara>
65 </example>
66 </refsect1>
67 </refentry>
68
69 <!--
70Local Variables:
71mode: sgml
72sgml-parent-document: "pixfmt.sgml"
73indent-tabs-mode: nil
74End:
75 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml b/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml
new file mode 100644
index 000000000000..d67a472b0880
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sgbrg8.xml
@@ -0,0 +1,75 @@
1 <refentry id="V4L2-PIX-FMT-SGBRG8">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SGBRG8 ('GBRG')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_SGBRG8</constant></refname>
8 <refpurpose>Bayer RGB format</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>This is commonly the native format of digital cameras,
14reflecting the arrangement of sensors on the CCD device. Only one red,
15green or blue value is given for each pixel. Missing components must
16be interpolated from neighbouring pixels. From left to right the first
17row consists of a green and blue value, the second row of a red and
18green value. This scheme repeats to the right and down for every two
19columns and rows.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_SGBRG8</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="5" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>G<subscript>00</subscript></entry>
35 <entry>B<subscript>01</subscript></entry>
36 <entry>G<subscript>02</subscript></entry>
37 <entry>B<subscript>03</subscript></entry>
38 </row>
39 <row>
40 <entry>start&nbsp;+&nbsp;4:</entry>
41 <entry>R<subscript>10</subscript></entry>
42 <entry>G<subscript>11</subscript></entry>
43 <entry>R<subscript>12</subscript></entry>
44 <entry>G<subscript>13</subscript></entry>
45 </row>
46 <row>
47 <entry>start&nbsp;+&nbsp;8:</entry>
48 <entry>G<subscript>20</subscript></entry>
49 <entry>B<subscript>21</subscript></entry>
50 <entry>G<subscript>22</subscript></entry>
51 <entry>B<subscript>23</subscript></entry>
52 </row>
53 <row>
54 <entry>start&nbsp;+&nbsp;12:</entry>
55 <entry>R<subscript>30</subscript></entry>
56 <entry>G<subscript>31</subscript></entry>
57 <entry>R<subscript>32</subscript></entry>
58 <entry>G<subscript>33</subscript></entry>
59 </row>
60 </tbody>
61 </tgroup>
62 </informaltable>
63 </para>
64 </formalpara>
65 </example>
66 </refsect1>
67 </refentry>
68
69 <!--
70Local Variables:
71mode: sgml
72sgml-parent-document: "pixfmt.sgml"
73indent-tabs-mode: nil
74End:
75 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml b/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml
new file mode 100644
index 000000000000..0cdf13b8ac1c
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-sgrbg8.xml
@@ -0,0 +1,75 @@
1 <refentry id="V4L2-PIX-FMT-SGRBG8">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SGRBG8 ('GRBG')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_SGRBG8</constant></refname>
8 <refpurpose>Bayer RGB format</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>This is commonly the native format of digital cameras,
14reflecting the arrangement of sensors on the CCD device. Only one red,
15green or blue value is given for each pixel. Missing components must
16be interpolated from neighbouring pixels. From left to right the first
17row consists of a green and blue value, the second row of a red and
18green value. This scheme repeats to the right and down for every two
19columns and rows.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_SGRBG8</constant> 4 &times;
234 pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="5" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>G<subscript>00</subscript></entry>
35 <entry>R<subscript>01</subscript></entry>
36 <entry>G<subscript>02</subscript></entry>
37 <entry>R<subscript>03</subscript></entry>
38 </row>
39 <row>
40 <entry>start&nbsp;+&nbsp;4:</entry>
41 <entry>R<subscript>10</subscript></entry>
42 <entry>B<subscript>11</subscript></entry>
43 <entry>R<subscript>12</subscript></entry>
44 <entry>B<subscript>13</subscript></entry>
45 </row>
46 <row>
47 <entry>start&nbsp;+&nbsp;8:</entry>
48 <entry>G<subscript>20</subscript></entry>
49 <entry>R<subscript>21</subscript></entry>
50 <entry>G<subscript>22</subscript></entry>
51 <entry>R<subscript>23</subscript></entry>
52 </row>
53 <row>
54 <entry>start&nbsp;+&nbsp;12:</entry>
55 <entry>R<subscript>30</subscript></entry>
56 <entry>B<subscript>31</subscript></entry>
57 <entry>R<subscript>32</subscript></entry>
58 <entry>B<subscript>33</subscript></entry>
59 </row>
60 </tbody>
61 </tgroup>
62 </informaltable>
63 </para>
64 </formalpara>
65 </example>
66 </refsect1>
67 </refentry>
68
69 <!--
70Local Variables:
71mode: sgml
72sgml-parent-document: "pixfmt.sgml"
73indent-tabs-mode: nil
74End:
75 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-uyvy.xml b/Documentation/DocBook/v4l/pixfmt-uyvy.xml
new file mode 100644
index 000000000000..816c8d467c16
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-uyvy.xml
@@ -0,0 +1,128 @@
1 <refentry id="V4L2-PIX-FMT-UYVY">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_UYVY ('UYVY')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_UYVY</constant></refname>
8 <refpurpose>Variation of
9<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
10in memory</refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>In this format each four bytes is two pixels. Each four
16bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
17the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
18components have half the horizontal resolution of the Y
19component.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_UYVY</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="9" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>Cb<subscript>00</subscript></entry>
35 <entry>Y'<subscript>00</subscript></entry>
36 <entry>Cr<subscript>00</subscript></entry>
37 <entry>Y'<subscript>01</subscript></entry>
38 <entry>Cb<subscript>01</subscript></entry>
39 <entry>Y'<subscript>02</subscript></entry>
40 <entry>Cr<subscript>01</subscript></entry>
41 <entry>Y'<subscript>03</subscript></entry>
42 </row>
43 <row>
44 <entry>start&nbsp;+&nbsp;8:</entry>
45 <entry>Cb<subscript>10</subscript></entry>
46 <entry>Y'<subscript>10</subscript></entry>
47 <entry>Cr<subscript>10</subscript></entry>
48 <entry>Y'<subscript>11</subscript></entry>
49 <entry>Cb<subscript>11</subscript></entry>
50 <entry>Y'<subscript>12</subscript></entry>
51 <entry>Cr<subscript>11</subscript></entry>
52 <entry>Y'<subscript>13</subscript></entry>
53 </row>
54 <row>
55 <entry>start&nbsp;+&nbsp;16:</entry>
56 <entry>Cb<subscript>20</subscript></entry>
57 <entry>Y'<subscript>20</subscript></entry>
58 <entry>Cr<subscript>20</subscript></entry>
59 <entry>Y'<subscript>21</subscript></entry>
60 <entry>Cb<subscript>21</subscript></entry>
61 <entry>Y'<subscript>22</subscript></entry>
62 <entry>Cr<subscript>21</subscript></entry>
63 <entry>Y'<subscript>23</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;24:</entry>
67 <entry>Cb<subscript>30</subscript></entry>
68 <entry>Y'<subscript>30</subscript></entry>
69 <entry>Cr<subscript>30</subscript></entry>
70 <entry>Y'<subscript>31</subscript></entry>
71 <entry>Cb<subscript>31</subscript></entry>
72 <entry>Y'<subscript>32</subscript></entry>
73 <entry>Cr<subscript>31</subscript></entry>
74 <entry>Y'<subscript>33</subscript></entry>
75 </row>
76 </tbody>
77 </tgroup>
78 </informaltable>
79 </para>
80 </formalpara>
81
82 <formalpara>
83 <title>Color Sample Location.</title>
84 <para>
85 <informaltable frame="none">
86 <tgroup cols="7" align="center">
87 <tbody valign="top">
88 <row>
89 <entry></entry>
90 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
91 <entry>2</entry><entry></entry><entry>3</entry>
92 </row>
93 <row>
94 <entry>0</entry>
95 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
96 <entry>Y</entry><entry>C</entry><entry>Y</entry>
97 </row>
98 <row>
99 <entry>1</entry>
100 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
101 <entry>Y</entry><entry>C</entry><entry>Y</entry>
102 </row>
103 <row>
104 <entry>2</entry>
105 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
106 <entry>Y</entry><entry>C</entry><entry>Y</entry>
107 </row>
108 <row>
109 <entry>3</entry>
110 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
111 <entry>Y</entry><entry>C</entry><entry>Y</entry>
112 </row>
113 </tbody>
114 </tgroup>
115 </informaltable>
116 </para>
117 </formalpara>
118 </example>
119 </refsect1>
120 </refentry>
121
122 <!--
123Local Variables:
124mode: sgml
125sgml-parent-document: "pixfmt.sgml"
126indent-tabs-mode: nil
127End:
128 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-vyuy.xml b/Documentation/DocBook/v4l/pixfmt-vyuy.xml
new file mode 100644
index 000000000000..61f12a5e68d9
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-vyuy.xml
@@ -0,0 +1,128 @@
1 <refentry id="V4L2-PIX-FMT-VYUY">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_VYUY ('VYUY')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_VYUY</constant></refname>
8 <refpurpose>Variation of
9<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
10in memory</refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>In this format each four bytes is two pixels. Each four
16bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
17the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
18components have half the horizontal resolution of the Y
19component.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_VYUY</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="9" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>Cr<subscript>00</subscript></entry>
35 <entry>Y'<subscript>00</subscript></entry>
36 <entry>Cb<subscript>00</subscript></entry>
37 <entry>Y'<subscript>01</subscript></entry>
38 <entry>Cr<subscript>01</subscript></entry>
39 <entry>Y'<subscript>02</subscript></entry>
40 <entry>Cb<subscript>01</subscript></entry>
41 <entry>Y'<subscript>03</subscript></entry>
42 </row>
43 <row>
44 <entry>start&nbsp;+&nbsp;8:</entry>
45 <entry>Cr<subscript>10</subscript></entry>
46 <entry>Y'<subscript>10</subscript></entry>
47 <entry>Cb<subscript>10</subscript></entry>
48 <entry>Y'<subscript>11</subscript></entry>
49 <entry>Cr<subscript>11</subscript></entry>
50 <entry>Y'<subscript>12</subscript></entry>
51 <entry>Cb<subscript>11</subscript></entry>
52 <entry>Y'<subscript>13</subscript></entry>
53 </row>
54 <row>
55 <entry>start&nbsp;+&nbsp;16:</entry>
56 <entry>Cr<subscript>20</subscript></entry>
57 <entry>Y'<subscript>20</subscript></entry>
58 <entry>Cb<subscript>20</subscript></entry>
59 <entry>Y'<subscript>21</subscript></entry>
60 <entry>Cr<subscript>21</subscript></entry>
61 <entry>Y'<subscript>22</subscript></entry>
62 <entry>Cb<subscript>21</subscript></entry>
63 <entry>Y'<subscript>23</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;24:</entry>
67 <entry>Cr<subscript>30</subscript></entry>
68 <entry>Y'<subscript>30</subscript></entry>
69 <entry>Cb<subscript>30</subscript></entry>
70 <entry>Y'<subscript>31</subscript></entry>
71 <entry>Cr<subscript>31</subscript></entry>
72 <entry>Y'<subscript>32</subscript></entry>
73 <entry>Cb<subscript>31</subscript></entry>
74 <entry>Y'<subscript>33</subscript></entry>
75 </row>
76 </tbody>
77 </tgroup>
78 </informaltable>
79 </para>
80 </formalpara>
81
82 <formalpara>
83 <title>Color Sample Location.</title>
84 <para>
85 <informaltable frame="none">
86 <tgroup cols="7" align="center">
87 <tbody valign="top">
88 <row>
89 <entry></entry>
90 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
91 <entry>2</entry><entry></entry><entry>3</entry>
92 </row>
93 <row>
94 <entry>0</entry>
95 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
96 <entry>Y</entry><entry>C</entry><entry>Y</entry>
97 </row>
98 <row>
99 <entry>1</entry>
100 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
101 <entry>Y</entry><entry>C</entry><entry>Y</entry>
102 </row>
103 <row>
104 <entry>2</entry>
105 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
106 <entry>Y</entry><entry>C</entry><entry>Y</entry>
107 </row>
108 <row>
109 <entry>3</entry>
110 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
111 <entry>Y</entry><entry>C</entry><entry>Y</entry>
112 </row>
113 </tbody>
114 </tgroup>
115 </informaltable>
116 </para>
117 </formalpara>
118 </example>
119 </refsect1>
120 </refentry>
121
122 <!--
123Local Variables:
124mode: sgml
125sgml-parent-document: "pixfmt.sgml"
126indent-tabs-mode: nil
127End:
128 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-y16.xml b/Documentation/DocBook/v4l/pixfmt-y16.xml
new file mode 100644
index 000000000000..d58404015078
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-y16.xml
@@ -0,0 +1,89 @@
1<refentry id="V4L2-PIX-FMT-Y16">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_Y16 ('Y16 ')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_Y16</constant></refname>
8 <refpurpose>Grey-scale image</refpurpose>
9 </refnamediv>
10 <refsect1>
11 <title>Description</title>
12
13 <para>This is a grey-scale image with a depth of 16 bits per
14pixel. The least significant byte is stored at lower memory addresses
15(little-endian). Note the actual sampling precision may be lower than
1616 bits, for example 10 bits per pixel with values in range 0 to
171023.</para>
18
19 <example>
20 <title><constant>V4L2_PIX_FMT_Y16</constant> 4 &times; 4
21pixel image</title>
22
23 <formalpara>
24 <title>Byte Order.</title>
25 <para>Each cell is one byte.
26 <informaltable frame="none">
27 <tgroup cols="9" align="center">
28 <colspec align="left" colwidth="2*" />
29 <tbody valign="top">
30 <row>
31 <entry>start&nbsp;+&nbsp;0:</entry>
32 <entry>Y'<subscript>00low</subscript></entry>
33 <entry>Y'<subscript>00high</subscript></entry>
34 <entry>Y'<subscript>01low</subscript></entry>
35 <entry>Y'<subscript>01high</subscript></entry>
36 <entry>Y'<subscript>02low</subscript></entry>
37 <entry>Y'<subscript>02high</subscript></entry>
38 <entry>Y'<subscript>03low</subscript></entry>
39 <entry>Y'<subscript>03high</subscript></entry>
40 </row>
41 <row>
42 <entry>start&nbsp;+&nbsp;8:</entry>
43 <entry>Y'<subscript>10low</subscript></entry>
44 <entry>Y'<subscript>10high</subscript></entry>
45 <entry>Y'<subscript>11low</subscript></entry>
46 <entry>Y'<subscript>11high</subscript></entry>
47 <entry>Y'<subscript>12low</subscript></entry>
48 <entry>Y'<subscript>12high</subscript></entry>
49 <entry>Y'<subscript>13low</subscript></entry>
50 <entry>Y'<subscript>13high</subscript></entry>
51 </row>
52 <row>
53 <entry>start&nbsp;+&nbsp;16:</entry>
54 <entry>Y'<subscript>20low</subscript></entry>
55 <entry>Y'<subscript>20high</subscript></entry>
56 <entry>Y'<subscript>21low</subscript></entry>
57 <entry>Y'<subscript>21high</subscript></entry>
58 <entry>Y'<subscript>22low</subscript></entry>
59 <entry>Y'<subscript>22high</subscript></entry>
60 <entry>Y'<subscript>23low</subscript></entry>
61 <entry>Y'<subscript>23high</subscript></entry>
62 </row>
63 <row>
64 <entry>start&nbsp;+&nbsp;24:</entry>
65 <entry>Y'<subscript>30low</subscript></entry>
66 <entry>Y'<subscript>30high</subscript></entry>
67 <entry>Y'<subscript>31low</subscript></entry>
68 <entry>Y'<subscript>31high</subscript></entry>
69 <entry>Y'<subscript>32low</subscript></entry>
70 <entry>Y'<subscript>32high</subscript></entry>
71 <entry>Y'<subscript>33low</subscript></entry>
72 <entry>Y'<subscript>33high</subscript></entry>
73 </row>
74 </tbody>
75 </tgroup>
76 </informaltable>
77 </para>
78 </formalpara>
79 </example>
80 </refsect1>
81</refentry>
82
83 <!--
84Local Variables:
85mode: sgml
86sgml-parent-document: "pixfmt.sgml"
87indent-tabs-mode: nil
88End:
89 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-y41p.xml b/Documentation/DocBook/v4l/pixfmt-y41p.xml
new file mode 100644
index 000000000000..73c8536efb05
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-y41p.xml
@@ -0,0 +1,157 @@
1 <refentry id="V4L2-PIX-FMT-Y41P">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_Y41P ('Y41P')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_Y41P</constant></refname>
8 <refpurpose>Format with &frac14; horizontal chroma
9resolution, also known as YUV 4:1:1</refpurpose>
10 </refnamediv>
11 <refsect1>
12 <title>Description</title>
13
14 <para>In this format each 12 bytes is eight pixels. In the
15twelve bytes are two CbCr pairs and eight Y's. The first CbCr pair
16goes with the first four Y's, and the second CbCr pair goes with the
17other four Y's. The Cb and Cr components have one fourth the
18horizontal resolution of the Y component.</para>
19
20 <para>Do not confuse this format with <link
21linkend="V4L2-PIX-FMT-YUV411P"><constant>V4L2_PIX_FMT_YUV411P</constant></link>.
22Y41P is derived from "YUV 4:1:1 <emphasis>packed</emphasis>", while
23YUV411P stands for "YUV 4:1:1 <emphasis>planar</emphasis>".</para>
24
25 <example>
26 <title><constant>V4L2_PIX_FMT_Y41P</constant> 8 &times; 4
27pixel image</title>
28
29 <formalpara>
30 <title>Byte Order</title>
31 <para>Each cell is one byte.
32 <informaltable frame="none">
33 <tgroup cols="13" align="center">
34 <colspec align="left" colwidth="2*" />
35 <tbody valign="top">
36 <row>
37 <entry>start&nbsp;+&nbsp;0:</entry>
38 <entry>Cb<subscript>00</subscript></entry>
39 <entry>Y'<subscript>00</subscript></entry>
40 <entry>Cr<subscript>00</subscript></entry>
41 <entry>Y'<subscript>01</subscript></entry>
42 <entry>Cb<subscript>01</subscript></entry>
43 <entry>Y'<subscript>02</subscript></entry>
44 <entry>Cr<subscript>01</subscript></entry>
45 <entry>Y'<subscript>03</subscript></entry>
46 <entry>Y'<subscript>04</subscript></entry>
47 <entry>Y'<subscript>05</subscript></entry>
48 <entry>Y'<subscript>06</subscript></entry>
49 <entry>Y'<subscript>07</subscript></entry>
50 </row>
51 <row>
52 <entry>start&nbsp;+&nbsp;12:</entry>
53 <entry>Cb<subscript>10</subscript></entry>
54 <entry>Y'<subscript>10</subscript></entry>
55 <entry>Cr<subscript>10</subscript></entry>
56 <entry>Y'<subscript>11</subscript></entry>
57 <entry>Cb<subscript>11</subscript></entry>
58 <entry>Y'<subscript>12</subscript></entry>
59 <entry>Cr<subscript>11</subscript></entry>
60 <entry>Y'<subscript>13</subscript></entry>
61 <entry>Y'<subscript>14</subscript></entry>
62 <entry>Y'<subscript>15</subscript></entry>
63 <entry>Y'<subscript>16</subscript></entry>
64 <entry>Y'<subscript>17</subscript></entry>
65 </row>
66 <row>
67 <entry>start&nbsp;+&nbsp;24:</entry>
68 <entry>Cb<subscript>20</subscript></entry>
69 <entry>Y'<subscript>20</subscript></entry>
70 <entry>Cr<subscript>20</subscript></entry>
71 <entry>Y'<subscript>21</subscript></entry>
72 <entry>Cb<subscript>21</subscript></entry>
73 <entry>Y'<subscript>22</subscript></entry>
74 <entry>Cr<subscript>21</subscript></entry>
75 <entry>Y'<subscript>23</subscript></entry>
76 <entry>Y'<subscript>24</subscript></entry>
77 <entry>Y'<subscript>25</subscript></entry>
78 <entry>Y'<subscript>26</subscript></entry>
79 <entry>Y'<subscript>27</subscript></entry>
80 </row>
81 <row>
82 <entry>start&nbsp;+&nbsp;36:</entry>
83 <entry>Cb<subscript>30</subscript></entry>
84 <entry>Y'<subscript>30</subscript></entry>
85 <entry>Cr<subscript>30</subscript></entry>
86 <entry>Y'<subscript>31</subscript></entry>
87 <entry>Cb<subscript>31</subscript></entry>
88 <entry>Y'<subscript>32</subscript></entry>
89 <entry>Cr<subscript>31</subscript></entry>
90 <entry>Y'<subscript>33</subscript></entry>
91 <entry>Y'<subscript>34</subscript></entry>
92 <entry>Y'<subscript>35</subscript></entry>
93 <entry>Y'<subscript>36</subscript></entry>
94 <entry>Y'<subscript>37</subscript></entry>
95 </row>
96 </tbody>
97 </tgroup>
98 </informaltable></para>
99 </formalpara>
100
101 <formalpara>
102 <title>Color Sample Location.</title>
103 <para>
104 <informaltable frame="none">
105 <tgroup cols="15" align="center">
106 <tbody valign="top">
107 <row>
108 <entry></entry>
109 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
110 <entry>2</entry><entry></entry><entry>3</entry><entry></entry>
111 <entry>4</entry><entry></entry><entry>5</entry><entry></entry>
112 <entry>6</entry><entry></entry><entry>7</entry>
113 </row>
114 <row>
115 <entry>0</entry>
116 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
117 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
118 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
119 <entry>Y</entry><entry></entry><entry>Y</entry>
120 </row>
121 <row>
122 <entry>1</entry>
123 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
124 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
125 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
126 <entry>Y</entry><entry></entry><entry>Y</entry>
127 </row>
128 <row>
129 <entry>2</entry>
130 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
131 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
132 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
133 <entry>Y</entry><entry></entry><entry>Y</entry>
134 </row>
135 <row>
136 <entry>3</entry>
137 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
138 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
139 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
140 <entry>Y</entry><entry></entry><entry>Y</entry>
141 </row>
142 </tbody>
143 </tgroup>
144 </informaltable>
145 </para>
146 </formalpara>
147 </example>
148 </refsect1>
149 </refentry>
150
151 <!--
152Local Variables:
153mode: sgml
154sgml-parent-document: "pixfmt.sgml"
155indent-tabs-mode: nil
156End:
157 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv410.xml b/Documentation/DocBook/v4l/pixfmt-yuv410.xml
new file mode 100644
index 000000000000..8eb4a193d770
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv410.xml
@@ -0,0 +1,141 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YVU410 ('YVU9'), V4L2_PIX_FMT_YUV410 ('YUV9')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname id="V4L2-PIX-FMT-YVU410"><constant>V4L2_PIX_FMT_YVU410</constant></refname>
8 <refname id="V4L2-PIX-FMT-YUV410"><constant>V4L2_PIX_FMT_YUV410</constant></refname>
9 <refpurpose>Planar formats with &frac14; horizontal and
10vertical chroma resolution, also known as YUV 4:1:0</refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>These are planar formats, as opposed to a packed format.
16The three components are separated into three sub-images or planes.
17The Y plane is first. The Y plane has one byte per pixel. For
18<constant>V4L2_PIX_FMT_YVU410</constant>, the Cr plane immediately
19follows the Y plane in memory. The Cr plane is &frac14; the width and
20&frac14; the height of the Y plane (and of the image). Each Cr belongs
21to 16 pixels, a four-by-four square of the image. Following the Cr
22plane is the Cb plane, just like the Cr plane.
23<constant>V4L2_PIX_FMT_YUV410</constant> is the same, except the Cb
24plane comes first, then the Cr plane.</para>
25
26 <para>If the Y plane has pad bytes after each row, then the Cr
27and Cb planes have &frac14; as many pad bytes after their rows. In
28other words, four Cx rows (including padding) are exactly as long as
29one Y row (including padding).</para>
30
31 <example>
32 <title><constant>V4L2_PIX_FMT_YVU410</constant> 4 &times; 4
33pixel image</title>
34
35 <formalpara>
36 <title>Byte Order.</title>
37 <para>Each cell is one byte.
38 <informaltable frame="none">
39 <tgroup cols="5" align="center">
40 <colspec align="left" colwidth="2*" />
41 <tbody valign="top">
42 <row>
43 <entry>start&nbsp;+&nbsp;0:</entry>
44 <entry>Y'<subscript>00</subscript></entry>
45 <entry>Y'<subscript>01</subscript></entry>
46 <entry>Y'<subscript>02</subscript></entry>
47 <entry>Y'<subscript>03</subscript></entry>
48 </row>
49 <row>
50 <entry>start&nbsp;+&nbsp;4:</entry>
51 <entry>Y'<subscript>10</subscript></entry>
52 <entry>Y'<subscript>11</subscript></entry>
53 <entry>Y'<subscript>12</subscript></entry>
54 <entry>Y'<subscript>13</subscript></entry>
55 </row>
56 <row>
57 <entry>start&nbsp;+&nbsp;8:</entry>
58 <entry>Y'<subscript>20</subscript></entry>
59 <entry>Y'<subscript>21</subscript></entry>
60 <entry>Y'<subscript>22</subscript></entry>
61 <entry>Y'<subscript>23</subscript></entry>
62 </row>
63 <row>
64 <entry>start&nbsp;+&nbsp;12:</entry>
65 <entry>Y'<subscript>30</subscript></entry>
66 <entry>Y'<subscript>31</subscript></entry>
67 <entry>Y'<subscript>32</subscript></entry>
68 <entry>Y'<subscript>33</subscript></entry>
69 </row>
70 <row>
71 <entry>start&nbsp;+&nbsp;16:</entry>
72 <entry>Cr<subscript>00</subscript></entry>
73 </row>
74 <row>
75 <entry>start&nbsp;+&nbsp;17:</entry>
76 <entry>Cb<subscript>00</subscript></entry>
77 </row>
78 </tbody>
79 </tgroup>
80 </informaltable>
81 </para>
82 </formalpara>
83
84 <formalpara>
85 <title>Color Sample Location.</title>
86 <para>
87 <informaltable frame="none">
88 <tgroup cols="7" align="center">
89 <tbody valign="top">
90 <row>
91 <entry></entry>
92 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
93 <entry>2</entry><entry></entry><entry>3</entry>
94 </row>
95 <row>
96 <entry>0</entry>
97 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
98 <entry>Y</entry><entry></entry><entry>Y</entry>
99 </row>
100 <row>
101 <entry></entry>
102 </row>
103 <row>
104 <entry>1</entry>
105 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
106 <entry>Y</entry><entry></entry><entry>Y</entry>
107 </row>
108 <row>
109 <entry></entry>
110 <entry></entry><entry></entry><entry></entry><entry>C</entry>
111 <entry></entry><entry></entry><entry></entry>
112 </row>
113 <row>
114 <entry>2</entry>
115 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
116 <entry>Y</entry><entry></entry><entry>Y</entry>
117 </row>
118 <row>
119 <entry></entry>
120 </row>
121 <row>
122 <entry>3</entry>
123 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
124 <entry>Y</entry><entry></entry><entry>Y</entry>
125 </row>
126 </tbody>
127 </tgroup>
128 </informaltable>
129 </para>
130 </formalpara>
131 </example>
132 </refsect1>
133 </refentry>
134
135 <!--
136Local Variables:
137mode: sgml
138sgml-parent-document: "pixfmt.sgml"
139indent-tabs-mode: nil
140End:
141 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv411p.xml b/Documentation/DocBook/v4l/pixfmt-yuv411p.xml
new file mode 100644
index 000000000000..00e0960a9869
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv411p.xml
@@ -0,0 +1,155 @@
1 <refentry id="V4L2-PIX-FMT-YUV411P">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YUV411P ('411P')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_YUV411P</constant></refname>
8 <refpurpose>Format with &frac14; horizontal chroma resolution,
9also known as YUV 4:1:1. Planar layout as opposed to
10<constant>V4L2_PIX_FMT_Y41P</constant></refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>This format is not commonly used. This is a planar
16format similar to the 4:2:2 planar format except with half as many
17chroma. The three components are separated into three sub-images or
18planes. The Y plane is first. The Y plane has one byte per pixel. The
19Cb plane immediately follows the Y plane in memory. The Cb plane is
20&frac14; the width of the Y plane (and of the image). Each Cb belongs
21to 4 pixels all on the same row. For example,
22Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
23Y'<subscript>01</subscript>, Y'<subscript>02</subscript> and
24Y'<subscript>03</subscript>. Following the Cb plane is the Cr plane,
25just like the Cb plane.</para>
26
27 <para>If the Y plane has pad bytes after each row, then the Cr
28and Cb planes have &frac14; as many pad bytes after their rows. In
29other words, four C x rows (including padding) is exactly as long as
30one Y row (including padding).</para>
31
32 <example>
33 <title><constant>V4L2_PIX_FMT_YUV411P</constant> 4 &times; 4
34pixel image</title>
35
36 <formalpara>
37 <title>Byte Order.</title>
38 <para>Each cell is one byte.
39 <informaltable frame="none">
40 <tgroup cols="5" align="center">
41 <colspec align="left" colwidth="2*" />
42 <tbody valign="top">
43 <row>
44 <entry>start&nbsp;+&nbsp;0:</entry>
45 <entry>Y'<subscript>00</subscript></entry>
46 <entry>Y'<subscript>01</subscript></entry>
47 <entry>Y'<subscript>02</subscript></entry>
48 <entry>Y'<subscript>03</subscript></entry>
49 </row>
50 <row>
51 <entry>start&nbsp;+&nbsp;4:</entry>
52 <entry>Y'<subscript>10</subscript></entry>
53 <entry>Y'<subscript>11</subscript></entry>
54 <entry>Y'<subscript>12</subscript></entry>
55 <entry>Y'<subscript>13</subscript></entry>
56 </row>
57 <row>
58 <entry>start&nbsp;+&nbsp;8:</entry>
59 <entry>Y'<subscript>20</subscript></entry>
60 <entry>Y'<subscript>21</subscript></entry>
61 <entry>Y'<subscript>22</subscript></entry>
62 <entry>Y'<subscript>23</subscript></entry>
63 </row>
64 <row>
65 <entry>start&nbsp;+&nbsp;12:</entry>
66 <entry>Y'<subscript>30</subscript></entry>
67 <entry>Y'<subscript>31</subscript></entry>
68 <entry>Y'<subscript>32</subscript></entry>
69 <entry>Y'<subscript>33</subscript></entry>
70 </row>
71 <row>
72 <entry>start&nbsp;+&nbsp;16:</entry>
73 <entry>Cb<subscript>00</subscript></entry>
74 </row>
75 <row>
76 <entry>start&nbsp;+&nbsp;17:</entry>
77 <entry>Cb<subscript>10</subscript></entry>
78 </row>
79 <row>
80 <entry>start&nbsp;+&nbsp;18:</entry>
81 <entry>Cb<subscript>20</subscript></entry>
82 </row>
83 <row>
84 <entry>start&nbsp;+&nbsp;19:</entry>
85 <entry>Cb<subscript>30</subscript></entry>
86 </row>
87 <row>
88 <entry>start&nbsp;+&nbsp;20:</entry>
89 <entry>Cr<subscript>00</subscript></entry>
90 </row>
91 <row>
92 <entry>start&nbsp;+&nbsp;21:</entry>
93 <entry>Cr<subscript>10</subscript></entry>
94 </row>
95 <row>
96 <entry>start&nbsp;+&nbsp;22:</entry>
97 <entry>Cr<subscript>20</subscript></entry>
98 </row>
99 <row>
100 <entry>start&nbsp;+&nbsp;23:</entry>
101 <entry>Cr<subscript>30</subscript></entry>
102 </row>
103 </tbody>
104 </tgroup>
105 </informaltable>
106 </para>
107 </formalpara>
108
109 <formalpara>
110 <title>Color Sample Location.</title>
111 <para>
112 <informaltable frame="none">
113 <tgroup cols="7" align="center">
114 <tbody valign="top">
115 <row>
116 <entry></entry>
117 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
118 <entry>2</entry><entry></entry><entry>3</entry>
119 </row>
120 <row>
121 <entry>0</entry>
122 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
123 <entry>Y</entry><entry></entry><entry>Y</entry>
124 </row>
125 <row>
126 <entry>1</entry>
127 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
128 <entry>Y</entry><entry></entry><entry>Y</entry>
129 </row>
130 <row>
131 <entry>2</entry>
132 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
133 <entry>Y</entry><entry></entry><entry>Y</entry>
134 </row>
135 <row>
136 <entry>3</entry>
137 <entry>Y</entry><entry></entry><entry>Y</entry><entry>C</entry>
138 <entry>Y</entry><entry></entry><entry>Y</entry>
139 </row>
140 </tbody>
141 </tgroup>
142 </informaltable>
143 </para>
144 </formalpara>
145 </example>
146 </refsect1>
147 </refentry>
148
149 <!--
150Local Variables:
151mode: sgml
152sgml-parent-document: "v4l2.sgml"
153indent-tabs-mode: nil
154End:
155 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv420.xml b/Documentation/DocBook/v4l/pixfmt-yuv420.xml
new file mode 100644
index 000000000000..42d7de5e456d
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv420.xml
@@ -0,0 +1,157 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YVU420 ('YV12'), V4L2_PIX_FMT_YUV420 ('YU12')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname id="V4L2-PIX-FMT-YVU420"><constant>V4L2_PIX_FMT_YVU420</constant></refname>
8 <refname id="V4L2-PIX-FMT-YUV420"><constant>V4L2_PIX_FMT_YUV420</constant></refname>
9 <refpurpose>Planar formats with &frac12; horizontal and
10vertical chroma resolution, also known as YUV 4:2:0</refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>These are planar formats, as opposed to a packed format.
16The three components are separated into three sub- images or planes.
17The Y plane is first. The Y plane has one byte per pixel. For
18<constant>V4L2_PIX_FMT_YVU420</constant>, the Cr plane immediately
19follows the Y plane in memory. The Cr plane is half the width and half
20the height of the Y plane (and of the image). Each Cr belongs to four
21pixels, a two-by-two square of the image. For example,
22Cr<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
23Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
24Y'<subscript>11</subscript>. Following the Cr plane is the Cb plane,
25just like the Cr plane. <constant>V4L2_PIX_FMT_YUV420</constant> is
26the same except the Cb plane comes first, then the Cr plane.</para>
27
28 <para>If the Y plane has pad bytes after each row, then the Cr
29and Cb planes have half as many pad bytes after their rows. In other
30words, two Cx rows (including padding) is exactly as long as one Y row
31(including padding).</para>
32
33 <example>
34 <title><constant>V4L2_PIX_FMT_YVU420</constant> 4 &times; 4
35pixel image</title>
36
37 <formalpara>
38 <title>Byte Order.</title>
39 <para>Each cell is one byte.
40 <informaltable frame="none">
41 <tgroup cols="5" align="center">
42 <colspec align="left" colwidth="2*" />
43 <tbody valign="top">
44 <row>
45 <entry>start&nbsp;+&nbsp;0:</entry>
46 <entry>Y'<subscript>00</subscript></entry>
47 <entry>Y'<subscript>01</subscript></entry>
48 <entry>Y'<subscript>02</subscript></entry>
49 <entry>Y'<subscript>03</subscript></entry>
50 </row>
51 <row>
52 <entry>start&nbsp;+&nbsp;4:</entry>
53 <entry>Y'<subscript>10</subscript></entry>
54 <entry>Y'<subscript>11</subscript></entry>
55 <entry>Y'<subscript>12</subscript></entry>
56 <entry>Y'<subscript>13</subscript></entry>
57 </row>
58 <row>
59 <entry>start&nbsp;+&nbsp;8:</entry>
60 <entry>Y'<subscript>20</subscript></entry>
61 <entry>Y'<subscript>21</subscript></entry>
62 <entry>Y'<subscript>22</subscript></entry>
63 <entry>Y'<subscript>23</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;12:</entry>
67 <entry>Y'<subscript>30</subscript></entry>
68 <entry>Y'<subscript>31</subscript></entry>
69 <entry>Y'<subscript>32</subscript></entry>
70 <entry>Y'<subscript>33</subscript></entry>
71 </row>
72 <row>
73 <entry>start&nbsp;+&nbsp;16:</entry>
74 <entry>Cr<subscript>00</subscript></entry>
75 <entry>Cr<subscript>01</subscript></entry>
76 </row>
77 <row>
78 <entry>start&nbsp;+&nbsp;18:</entry>
79 <entry>Cr<subscript>10</subscript></entry>
80 <entry>Cr<subscript>11</subscript></entry>
81 </row>
82 <row>
83 <entry>start&nbsp;+&nbsp;20:</entry>
84 <entry>Cb<subscript>00</subscript></entry>
85 <entry>Cb<subscript>01</subscript></entry>
86 </row>
87 <row>
88 <entry>start&nbsp;+&nbsp;22:</entry>
89 <entry>Cb<subscript>10</subscript></entry>
90 <entry>Cb<subscript>11</subscript></entry>
91 </row>
92 </tbody>
93 </tgroup>
94 </informaltable>
95 </para>
96 </formalpara>
97
98 <formalpara>
99 <title>Color Sample Location.</title>
100 <para>
101 <informaltable frame="none">
102 <tgroup cols="7" align="center">
103 <tbody valign="top">
104 <row>
105 <entry></entry>
106 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
107 <entry>2</entry><entry></entry><entry>3</entry>
108 </row>
109 <row>
110 <entry>0</entry>
111 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
112 <entry>Y</entry><entry></entry><entry>Y</entry>
113 </row>
114 <row>
115 <entry></entry>
116 <entry></entry><entry>C</entry><entry></entry><entry></entry>
117 <entry></entry><entry>C</entry><entry></entry>
118 </row>
119 <row>
120 <entry>1</entry>
121 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
122 <entry>Y</entry><entry></entry><entry>Y</entry>
123 </row>
124 <row>
125 <entry></entry>
126 </row>
127 <row>
128 <entry>2</entry>
129 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
130 <entry>Y</entry><entry></entry><entry>Y</entry>
131 </row>
132 <row>
133 <entry></entry>
134 <entry></entry><entry>C</entry><entry></entry><entry></entry>
135 <entry></entry><entry>C</entry><entry></entry>
136 </row>
137 <row>
138 <entry>3</entry>
139 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
140 <entry>Y</entry><entry></entry><entry>Y</entry>
141 </row>
142 </tbody>
143 </tgroup>
144 </informaltable>
145 </para>
146 </formalpara>
147 </example>
148 </refsect1>
149 </refentry>
150
151 <!--
152Local Variables:
153mode: sgml
154sgml-parent-document: "pixfmt.sgml"
155indent-tabs-mode: nil
156End:
157 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv422p.xml b/Documentation/DocBook/v4l/pixfmt-yuv422p.xml
new file mode 100644
index 000000000000..4348bd9f0d01
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv422p.xml
@@ -0,0 +1,161 @@
1 <refentry id="V4L2-PIX-FMT-YUV422P">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YUV422P ('422P')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_YUV422P</constant></refname>
8 <refpurpose>Format with &frac12; horizontal chroma resolution,
9also known as YUV 4:2:2. Planar layout as opposed to
10<constant>V4L2_PIX_FMT_YUYV</constant></refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>This format is not commonly used. This is a planar
16version of the YUYV format. The three components are separated into
17three sub-images or planes. The Y plane is first. The Y plane has one
18byte per pixel. The Cb plane immediately follows the Y plane in
19memory. The Cb plane is half the width of the Y plane (and of the
20image). Each Cb belongs to two pixels. For example,
21Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
22Y'<subscript>01</subscript>. Following the Cb plane is the Cr plane,
23just like the Cb plane.</para>
24
25 <para>If the Y plane has pad bytes after each row, then the Cr
26and Cb planes have half as many pad bytes after their rows. In other
27words, two Cx rows (including padding) is exactly as long as one Y row
28(including padding).</para>
29
30 <example>
31 <title><constant>V4L2_PIX_FMT_YUV422P</constant> 4 &times; 4
32pixel image</title>
33
34 <formalpara>
35 <title>Byte Order.</title>
36 <para>Each cell is one byte.
37 <informaltable frame="none">
38 <tgroup cols="5" align="center">
39 <colspec align="left" colwidth="2*" />
40 <tbody valign="top">
41 <row>
42 <entry>start&nbsp;+&nbsp;0:</entry>
43 <entry>Y'<subscript>00</subscript></entry>
44 <entry>Y'<subscript>01</subscript></entry>
45 <entry>Y'<subscript>02</subscript></entry>
46 <entry>Y'<subscript>03</subscript></entry>
47 </row>
48 <row>
49 <entry>start&nbsp;+&nbsp;4:</entry>
50 <entry>Y'<subscript>10</subscript></entry>
51 <entry>Y'<subscript>11</subscript></entry>
52 <entry>Y'<subscript>12</subscript></entry>
53 <entry>Y'<subscript>13</subscript></entry>
54 </row>
55 <row>
56 <entry>start&nbsp;+&nbsp;8:</entry>
57 <entry>Y'<subscript>20</subscript></entry>
58 <entry>Y'<subscript>21</subscript></entry>
59 <entry>Y'<subscript>22</subscript></entry>
60 <entry>Y'<subscript>23</subscript></entry>
61 </row>
62 <row>
63 <entry>start&nbsp;+&nbsp;12:</entry>
64 <entry>Y'<subscript>30</subscript></entry>
65 <entry>Y'<subscript>31</subscript></entry>
66 <entry>Y'<subscript>32</subscript></entry>
67 <entry>Y'<subscript>33</subscript></entry>
68 </row>
69 <row>
70 <entry>start&nbsp;+&nbsp;16:</entry>
71 <entry>Cb<subscript>00</subscript></entry>
72 <entry>Cb<subscript>01</subscript></entry>
73 </row>
74 <row>
75 <entry>start&nbsp;+&nbsp;18:</entry>
76 <entry>Cb<subscript>10</subscript></entry>
77 <entry>Cb<subscript>11</subscript></entry>
78 </row>
79 <row>
80 <entry>start&nbsp;+&nbsp;20:</entry>
81 <entry>Cb<subscript>20</subscript></entry>
82 <entry>Cb<subscript>21</subscript></entry>
83 </row>
84 <row>
85 <entry>start&nbsp;+&nbsp;22:</entry>
86 <entry>Cb<subscript>30</subscript></entry>
87 <entry>Cb<subscript>31</subscript></entry>
88 </row>
89 <row>
90 <entry>start&nbsp;+&nbsp;24:</entry>
91 <entry>Cr<subscript>00</subscript></entry>
92 <entry>Cr<subscript>01</subscript></entry>
93 </row>
94 <row>
95 <entry>start&nbsp;+&nbsp;26:</entry>
96 <entry>Cr<subscript>10</subscript></entry>
97 <entry>Cr<subscript>11</subscript></entry>
98 </row>
99 <row>
100 <entry>start&nbsp;+&nbsp;28:</entry>
101 <entry>Cr<subscript>20</subscript></entry>
102 <entry>Cr<subscript>21</subscript></entry>
103 </row>
104 <row>
105 <entry>start&nbsp;+&nbsp;30:</entry>
106 <entry>Cr<subscript>30</subscript></entry>
107 <entry>Cr<subscript>31</subscript></entry>
108 </row>
109 </tbody>
110 </tgroup>
111 </informaltable>
112 </para>
113 </formalpara>
114
115 <formalpara>
116 <title>Color Sample Location.</title>
117 <para>
118 <informaltable frame="none">
119 <tgroup cols="7" align="center">
120 <tbody valign="top">
121 <row>
122 <entry></entry>
123 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
124 <entry>2</entry><entry></entry><entry>3</entry>
125 </row>
126 <row>
127 <entry>0</entry>
128 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
129 <entry>Y</entry><entry>C</entry><entry>Y</entry>
130 </row>
131 <row>
132 <entry>1</entry>
133 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
134 <entry>Y</entry><entry>C</entry><entry>Y</entry>
135 </row>
136 <row>
137 <entry>2</entry>
138 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
139 <entry>Y</entry><entry>C</entry><entry>Y</entry>
140 </row>
141 <row>
142 <entry>3</entry>
143 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
144 <entry>Y</entry><entry>C</entry><entry>Y</entry>
145 </row>
146 </tbody>
147 </tgroup>
148 </informaltable>
149 </para>
150 </formalpara>
151 </example>
152 </refsect1>
153 </refentry>
154
155 <!--
156Local Variables:
157mode: sgml
158sgml-parent-document: "pixfmt.sgml"
159indent-tabs-mode: nil
160End:
161 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yuyv.xml b/Documentation/DocBook/v4l/pixfmt-yuyv.xml
new file mode 100644
index 000000000000..bdb2ffacbbcc
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuyv.xml
@@ -0,0 +1,128 @@
1 <refentry id="V4L2-PIX-FMT-YUYV">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YUYV ('YUYV')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_YUYV</constant></refname>
8 <refpurpose>Packed format with &frac12; horizontal chroma
9resolution, also known as YUV 4:2:2</refpurpose>
10 </refnamediv>
11 <refsect1>
12 <title>Description</title>
13
14 <para>In this format each four bytes is two pixels. Each four
15bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
16the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
17components have half the horizontal resolution of the Y component.
18<constant>V4L2_PIX_FMT_YUYV </constant> is known in the Windows
19environment as YUY2.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_YUYV</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="9" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>Y'<subscript>00</subscript></entry>
35 <entry>Cb<subscript>00</subscript></entry>
36 <entry>Y'<subscript>01</subscript></entry>
37 <entry>Cr<subscript>00</subscript></entry>
38 <entry>Y'<subscript>02</subscript></entry>
39 <entry>Cb<subscript>01</subscript></entry>
40 <entry>Y'<subscript>03</subscript></entry>
41 <entry>Cr<subscript>01</subscript></entry>
42 </row>
43 <row>
44 <entry>start&nbsp;+&nbsp;8:</entry>
45 <entry>Y'<subscript>10</subscript></entry>
46 <entry>Cb<subscript>10</subscript></entry>
47 <entry>Y'<subscript>11</subscript></entry>
48 <entry>Cr<subscript>10</subscript></entry>
49 <entry>Y'<subscript>12</subscript></entry>
50 <entry>Cb<subscript>11</subscript></entry>
51 <entry>Y'<subscript>13</subscript></entry>
52 <entry>Cr<subscript>11</subscript></entry>
53 </row>
54 <row>
55 <entry>start&nbsp;+&nbsp;16:</entry>
56 <entry>Y'<subscript>20</subscript></entry>
57 <entry>Cb<subscript>20</subscript></entry>
58 <entry>Y'<subscript>21</subscript></entry>
59 <entry>Cr<subscript>20</subscript></entry>
60 <entry>Y'<subscript>22</subscript></entry>
61 <entry>Cb<subscript>21</subscript></entry>
62 <entry>Y'<subscript>23</subscript></entry>
63 <entry>Cr<subscript>21</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;24:</entry>
67 <entry>Y'<subscript>30</subscript></entry>
68 <entry>Cb<subscript>30</subscript></entry>
69 <entry>Y'<subscript>31</subscript></entry>
70 <entry>Cr<subscript>30</subscript></entry>
71 <entry>Y'<subscript>32</subscript></entry>
72 <entry>Cb<subscript>31</subscript></entry>
73 <entry>Y'<subscript>33</subscript></entry>
74 <entry>Cr<subscript>31</subscript></entry>
75 </row>
76 </tbody>
77 </tgroup>
78 </informaltable>
79 </para>
80 </formalpara>
81
82 <formalpara>
83 <title>Color Sample Location.</title>
84 <para>
85 <informaltable frame="none">
86 <tgroup cols="7" align="center">
87 <tbody valign="top">
88 <row>
89 <entry></entry>
90 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
91 <entry>2</entry><entry></entry><entry>3</entry>
92 </row>
93 <row>
94 <entry>0</entry>
95 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
96 <entry>Y</entry><entry>C</entry><entry>Y</entry>
97 </row>
98 <row>
99 <entry>1</entry>
100 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
101 <entry>Y</entry><entry>C</entry><entry>Y</entry>
102 </row>
103 <row>
104 <entry>2</entry>
105 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
106 <entry>Y</entry><entry>C</entry><entry>Y</entry>
107 </row>
108 <row>
109 <entry>3</entry>
110 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
111 <entry>Y</entry><entry>C</entry><entry>Y</entry>
112 </row>
113 </tbody>
114 </tgroup>
115 </informaltable>
116 </para>
117 </formalpara>
118 </example>
119 </refsect1>
120 </refentry>
121
122 <!--
123Local Variables:
124mode: sgml
125sgml-parent-document: "pixfmt.sgml"
126indent-tabs-mode: nil
127End:
128 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-yvyu.xml b/Documentation/DocBook/v4l/pixfmt-yvyu.xml
new file mode 100644
index 000000000000..40d17ae39dde
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yvyu.xml
@@ -0,0 +1,128 @@
1 <refentry id="V4L2-PIX-FMT-YVYU">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YVYU ('YVYU')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname><constant>V4L2_PIX_FMT_YVYU</constant></refname>
8 <refpurpose>Variation of
9<constant>V4L2_PIX_FMT_YUYV</constant> with different order of samples
10in memory</refpurpose>
11 </refnamediv>
12 <refsect1>
13 <title>Description</title>
14
15 <para>In this format each four bytes is two pixels. Each four
16bytes is two Y's, a Cb and a Cr. Each Y goes to one of the pixels, and
17the Cb and Cr belong to both pixels. As you can see, the Cr and Cb
18components have half the horizontal resolution of the Y
19component.</para>
20
21 <example>
22 <title><constant>V4L2_PIX_FMT_YVYU</constant> 4 &times; 4
23pixel image</title>
24
25 <formalpara>
26 <title>Byte Order.</title>
27 <para>Each cell is one byte.
28 <informaltable frame="none">
29 <tgroup cols="9" align="center">
30 <colspec align="left" colwidth="2*" />
31 <tbody valign="top">
32 <row>
33 <entry>start&nbsp;+&nbsp;0:</entry>
34 <entry>Y'<subscript>00</subscript></entry>
35 <entry>Cr<subscript>00</subscript></entry>
36 <entry>Y'<subscript>01</subscript></entry>
37 <entry>Cb<subscript>00</subscript></entry>
38 <entry>Y'<subscript>02</subscript></entry>
39 <entry>Cr<subscript>01</subscript></entry>
40 <entry>Y'<subscript>03</subscript></entry>
41 <entry>Cb<subscript>01</subscript></entry>
42 </row>
43 <row>
44 <entry>start&nbsp;+&nbsp;8:</entry>
45 <entry>Y'<subscript>10</subscript></entry>
46 <entry>Cr<subscript>10</subscript></entry>
47 <entry>Y'<subscript>11</subscript></entry>
48 <entry>Cb<subscript>10</subscript></entry>
49 <entry>Y'<subscript>12</subscript></entry>
50 <entry>Cr<subscript>11</subscript></entry>
51 <entry>Y'<subscript>13</subscript></entry>
52 <entry>Cb<subscript>11</subscript></entry>
53 </row>
54 <row>
55 <entry>start&nbsp;+&nbsp;16:</entry>
56 <entry>Y'<subscript>20</subscript></entry>
57 <entry>Cr<subscript>20</subscript></entry>
58 <entry>Y'<subscript>21</subscript></entry>
59 <entry>Cb<subscript>20</subscript></entry>
60 <entry>Y'<subscript>22</subscript></entry>
61 <entry>Cr<subscript>21</subscript></entry>
62 <entry>Y'<subscript>23</subscript></entry>
63 <entry>Cb<subscript>21</subscript></entry>
64 </row>
65 <row>
66 <entry>start&nbsp;+&nbsp;24:</entry>
67 <entry>Y'<subscript>30</subscript></entry>
68 <entry>Cr<subscript>30</subscript></entry>
69 <entry>Y'<subscript>31</subscript></entry>
70 <entry>Cb<subscript>30</subscript></entry>
71 <entry>Y'<subscript>32</subscript></entry>
72 <entry>Cr<subscript>31</subscript></entry>
73 <entry>Y'<subscript>33</subscript></entry>
74 <entry>Cb<subscript>31</subscript></entry>
75 </row>
76 </tbody>
77 </tgroup>
78 </informaltable>
79 </para>
80 </formalpara>
81
82 <formalpara>
83 <title>Color Sample Location.</title>
84 <para>
85 <informaltable frame="none">
86 <tgroup cols="7" align="center">
87 <tbody valign="top">
88 <row>
89 <entry></entry>
90 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
91 <entry>2</entry><entry></entry><entry>3</entry>
92 </row>
93 <row>
94 <entry>0</entry>
95 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
96 <entry>Y</entry><entry>C</entry><entry>Y</entry>
97 </row>
98 <row>
99 <entry>1</entry>
100 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
101 <entry>Y</entry><entry>C</entry><entry>Y</entry>
102 </row>
103 <row>
104 <entry>2</entry>
105 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
106 <entry>Y</entry><entry>C</entry><entry>Y</entry>
107 </row>
108 <row>
109 <entry>3</entry>
110 <entry>Y</entry><entry>C</entry><entry>Y</entry><entry></entry>
111 <entry>Y</entry><entry>C</entry><entry>Y</entry>
112 </row>
113 </tbody>
114 </tgroup>
115 </informaltable>
116 </para>
117 </formalpara>
118 </example>
119 </refsect1>
120 </refentry>
121
122 <!--
123Local Variables:
124mode: sgml
125sgml-parent-document: "pixfmt.sgml"
126indent-tabs-mode: nil
127End:
128 -->
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
new file mode 100644
index 000000000000..7d396a3785f5
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -0,0 +1,801 @@
1 <title>Image Formats</title>
2
3 <para>The V4L2 API was primarily designed for devices exchanging
4image data with applications. The
5<structname>v4l2_pix_format</structname> structure defines the format
6and layout of an image in memory. Image formats are negotiated with
7the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video
8capturing and output, for overlay frame buffer formats see also
9&VIDIOC-G-FBUF;.)</para>
10
11 <table pgwide="1" frame="none" id="v4l2-pix-format">
12 <title>struct <structname>v4l2_pix_format</structname></title>
13 <tgroup cols="3">
14 &cs-str;
15 <tbody valign="top">
16 <row>
17 <entry>__u32</entry>
18 <entry><structfield>width</structfield></entry>
19 <entry>Image width in pixels.</entry>
20 </row>
21 <row>
22 <entry>__u32</entry>
23 <entry><structfield>height</structfield></entry>
24 <entry>Image height in pixels.</entry>
25 </row>
26 <row>
27 <entry spanname="hspan">Applications set these fields to
28request an image size, drivers return the closest possible values. In
29case of planar formats the <structfield>width</structfield> and
30<structfield>height</structfield> applies to the largest plane. To
31avoid ambiguities drivers must return values rounded up to a multiple
32of the scale factor of any smaller planes. For example when the image
33format is YUV 4:2:0, <structfield>width</structfield> and
34<structfield>height</structfield> must be multiples of two.</entry>
35 </row>
36 <row>
37 <entry>__u32</entry>
38 <entry><structfield>pixelformat</structfield></entry>
39 <entry>The pixel format or type of compression, set by the
40application. This is a little endian <link
41linkend="v4l2-fourcc">four character code</link>. V4L2 defines
42standard RGB formats in <xref linkend="rgb-formats" />, YUV formats in <xref
43linkend="yuv-formats" />, and reserved codes in <xref
44linkend="reserved-formats" /></entry>
45 </row>
46 <row>
47 <entry>&v4l2-field;</entry>
48 <entry><structfield>field</structfield></entry>
49 <entry>Video images are typically interlaced. Applications
50can request to capture or output only the top or bottom field, or both
51fields interlaced or sequentially stored in one buffer or alternating
52in separate buffers. Drivers return the actual field order selected.
53For details see <xref linkend="field-order" />.</entry>
54 </row>
55 <row>
56 <entry>__u32</entry>
57 <entry><structfield>bytesperline</structfield></entry>
58 <entry>Distance in bytes between the leftmost pixels in two
59adjacent lines.</entry>
60 </row>
61 <row>
62 <entry spanname="hspan"><para>Both applications and drivers
63can set this field to request padding bytes at the end of each line.
64Drivers however may ignore the value requested by the application,
65returning <structfield>width</structfield> times bytes per pixel or a
66larger value required by the hardware. That implies applications can
67just set this field to zero to get a reasonable
68default.</para><para>Video hardware may access padding bytes,
69therefore they must reside in accessible memory. Consider cases where
70padding bytes after the last line of an image cross a system page
71boundary. Input devices may write padding bytes, the value is
72undefined. Output devices ignore the contents of padding
73bytes.</para><para>When the image format is planar the
74<structfield>bytesperline</structfield> value applies to the largest
75plane and is divided by the same factor as the
76<structfield>width</structfield> field for any smaller planes. For
77example the Cb and Cr planes of a YUV 4:2:0 image have half as many
78padding bytes following each line as the Y plane. To avoid ambiguities
79drivers must return a <structfield>bytesperline</structfield> value
80rounded up to a multiple of the scale factor.</para></entry>
81 </row>
82 <row>
83 <entry>__u32</entry>
84 <entry><structfield>sizeimage</structfield></entry>
85 <entry>Size in bytes of the buffer to hold a complete image,
86set by the driver. Usually this is
87<structfield>bytesperline</structfield> times
88<structfield>height</structfield>. When the image consists of variable
89length compressed data this is the maximum number of bytes required to
90hold an image.</entry>
91 </row>
92 <row>
93 <entry>&v4l2-colorspace;</entry>
94 <entry><structfield>colorspace</structfield></entry>
95 <entry>This information supplements the
96<structfield>pixelformat</structfield> and must be set by the driver,
97see <xref linkend="colorspaces" />.</entry>
98 </row>
99 <row>
100 <entry>__u32</entry>
101 <entry><structfield>priv</structfield></entry>
102 <entry>Reserved for custom (driver defined) additional
103information about formats. When not used drivers and applications must
104set this field to zero.</entry>
105 </row>
106 </tbody>
107 </tgroup>
108 </table>
109
110 <section>
111 <title>Standard Image Formats</title>
112
113 <para>In order to exchange images between drivers and
114applications, it is necessary to have standard image data formats
115which both sides will interpret the same way. V4L2 includes several
116such formats, and this section is intended to be an unambiguous
117specification of the standard image data formats in V4L2.</para>
118
119 <para>V4L2 drivers are not limited to these formats, however.
120Driver-specific formats are possible. In that case the application may
121depend on a codec to convert images to one of the standard formats
122when needed. But the data can still be stored and retrieved in the
123proprietary format. For example, a device may support a proprietary
124compressed format. Applications can still capture and save the data in
125the compressed format, saving much disk space, and later use a codec
126to convert the images to the X Windows screen format when the video is
127to be displayed.</para>
128
129 <para>Even so, ultimately, some standard formats are needed, so
130the V4L2 specification would not be complete without well-defined
131standard formats.</para>
132
133 <para>The V4L2 standard formats are mainly uncompressed formats. The
134pixels are always arranged in memory from left to right, and from top
135to bottom. The first byte of data in the image buffer is always for
136the leftmost pixel of the topmost row. Following that is the pixel
137immediately to its right, and so on until the end of the top row of
138pixels. Following the rightmost pixel of the row there may be zero or
139more bytes of padding to guarantee that each row of pixel data has a
140certain alignment. Following the pad bytes, if any, is data for the
141leftmost pixel of the second row from the top, and so on. The last row
142has just as many pad bytes after it as the other rows.</para>
143
144 <para>In V4L2 each format has an identifier which looks like
145<constant>PIX_FMT_XXX</constant>, defined in the <link
146linkend="videodev">videodev.h</link> header file. These identifiers
147represent <link linkend="v4l2-fourcc">four character codes</link>
148which are also listed below, however they are not the same as those
149used in the Windows world.</para>
150 </section>
151
152 <section id="colorspaces">
153 <title>Colorspaces</title>
154
155 <para>[intro]</para>
156
157 <!-- See proposal by Billy Biggs, video4linux-list@redhat.com
158on 11 Oct 2002, subject: "Re: [V4L] Re: v4l2 api", and
159http://vektor.theorem.ca/graphics/ycbcr/ and
160http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html -->
161
162 <para>
163 <variablelist>
164 <varlistentry>
165 <term>Gamma Correction</term>
166 <listitem>
167 <para>[to do]</para>
168 <para>E'<subscript>R</subscript> = f(R)</para>
169 <para>E'<subscript>G</subscript> = f(G)</para>
170 <para>E'<subscript>B</subscript> = f(B)</para>
171 </listitem>
172 </varlistentry>
173 <varlistentry>
174 <term>Construction of luminance and color-difference
175signals</term>
176 <listitem>
177 <para>[to do]</para>
178 <para>E'<subscript>Y</subscript> =
179Coeff<subscript>R</subscript> E'<subscript>R</subscript>
180+ Coeff<subscript>G</subscript> E'<subscript>G</subscript>
181+ Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
182 <para>(E'<subscript>R</subscript> - E'<subscript>Y</subscript>) = E'<subscript>R</subscript>
183- Coeff<subscript>R</subscript> E'<subscript>R</subscript>
184- Coeff<subscript>G</subscript> E'<subscript>G</subscript>
185- Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
186 <para>(E'<subscript>B</subscript> - E'<subscript>Y</subscript>) = E'<subscript>B</subscript>
187- Coeff<subscript>R</subscript> E'<subscript>R</subscript>
188- Coeff<subscript>G</subscript> E'<subscript>G</subscript>
189- Coeff<subscript>B</subscript> E'<subscript>B</subscript></para>
190 </listitem>
191 </varlistentry>
192 <varlistentry>
193 <term>Re-normalized color-difference signals</term>
194 <listitem>
195 <para>The color-difference signals are scaled back to unity
196range [-0.5;+0.5]:</para>
197 <para>K<subscript>B</subscript> = 0.5 / (1 - Coeff<subscript>B</subscript>)</para>
198 <para>K<subscript>R</subscript> = 0.5 / (1 - Coeff<subscript>R</subscript>)</para>
199 <para>P<subscript>B</subscript> =
200K<subscript>B</subscript> (E'<subscript>B</subscript> - E'<subscript>Y</subscript>) =
201 0.5 (Coeff<subscript>R</subscript> / Coeff<subscript>B</subscript>) E'<subscript>R</subscript>
202+ 0.5 (Coeff<subscript>G</subscript> / Coeff<subscript>B</subscript>) E'<subscript>G</subscript>
203+ 0.5 E'<subscript>B</subscript></para>
204 <para>P<subscript>R</subscript> =
205K<subscript>R</subscript> (E'<subscript>R</subscript> - E'<subscript>Y</subscript>) =
206 0.5 E'<subscript>R</subscript>
207+ 0.5 (Coeff<subscript>G</subscript> / Coeff<subscript>R</subscript>) E'<subscript>G</subscript>
208+ 0.5 (Coeff<subscript>B</subscript> / Coeff<subscript>R</subscript>) E'<subscript>B</subscript></para>
209 </listitem>
210 </varlistentry>
211 <varlistentry>
212 <term>Quantization</term>
213 <listitem>
214 <para>[to do]</para>
215 <para>Y' = (Lum. Levels - 1) &middot; E'<subscript>Y</subscript> + Lum. Offset</para>
216 <para>C<subscript>B</subscript> = (Chrom. Levels - 1)
217&middot; P<subscript>B</subscript> + Chrom. Offset</para>
218 <para>C<subscript>R</subscript> = (Chrom. Levels - 1)
219&middot; P<subscript>R</subscript> + Chrom. Offset</para>
220 <para>Rounding to the nearest integer and clamping to the range
221[0;255] finally yields the digital color components Y'CbCr
222stored in YUV images.</para>
223 </listitem>
224 </varlistentry>
225 </variablelist>
226 </para>
227
228 <example>
229 <title>ITU-R Rec. BT.601 color conversion</title>
230
231 <para>Forward Transformation</para>
232
233 <programlisting>
234int ER, EG, EB; /* gamma corrected RGB input [0;255] */
235int Y1, Cb, Cr; /* output [0;255] */
236
237double r, g, b; /* temporaries */
238double y1, pb, pr;
239
240int
241clamp (double x)
242{
243 int r = x; /* round to nearest */
244
245 if (r &lt; 0) return 0;
246 else if (r &gt; 255) return 255;
247 else return r;
248}
249
250r = ER / 255.0;
251g = EG / 255.0;
252b = EB / 255.0;
253
254y1 = 0.299 * r + 0.587 * g + 0.114 * b;
255pb = -0.169 * r - 0.331 * g + 0.5 * b;
256pr = 0.5 * r - 0.419 * g - 0.081 * b;
257
258Y1 = clamp (219 * y1 + 16);
259Cb = clamp (224 * pb + 128);
260Cr = clamp (224 * pr + 128);
261
262/* or shorter */
263
264y1 = 0.299 * ER + 0.587 * EG + 0.114 * EB;
265
266Y1 = clamp ( (219 / 255.0) * y1 + 16);
267Cb = clamp (((224 / 255.0) / (2 - 2 * 0.114)) * (EB - y1) + 128);
268Cr = clamp (((224 / 255.0) / (2 - 2 * 0.299)) * (ER - y1) + 128);
269 </programlisting>
270
271 <para>Inverse Transformation</para>
272
273 <programlisting>
274int Y1, Cb, Cr; /* gamma pre-corrected input [0;255] */
275int ER, EG, EB; /* output [0;255] */
276
277double r, g, b; /* temporaries */
278double y1, pb, pr;
279
280int
281clamp (double x)
282{
283 int r = x; /* round to nearest */
284
285 if (r &lt; 0) return 0;
286 else if (r &gt; 255) return 255;
287 else return r;
288}
289
290y1 = (255 / 219.0) * (Y1 - 16);
291pb = (255 / 224.0) * (Cb - 128);
292pr = (255 / 224.0) * (Cr - 128);
293
294r = 1.0 * y1 + 0 * pb + 1.402 * pr;
295g = 1.0 * y1 - 0.344 * pb - 0.714 * pr;
296b = 1.0 * y1 + 1.772 * pb + 0 * pr;
297
298ER = clamp (r * 255); /* [ok? one should prob. limit y1,pb,pr] */
299EG = clamp (g * 255);
300EB = clamp (b * 255);
301 </programlisting>
302 </example>
303
304 <table pgwide="1" id="v4l2-colorspace" orient="land">
305 <title>enum v4l2_colorspace</title>
306 <tgroup cols="11" align="center">
307 <colspec align="left" />
308 <colspec align="center" />
309 <colspec align="left" />
310 <colspec colname="cr" />
311 <colspec colname="cg" />
312 <colspec colname="cb" />
313 <colspec colname="wp" />
314 <colspec colname="gc" />
315 <colspec colname="lum" />
316 <colspec colname="qy" />
317 <colspec colname="qc" />
318 <spanspec namest="cr" nameend="cb" spanname="chrom" />
319 <spanspec namest="qy" nameend="qc" spanname="quant" />
320 <spanspec namest="lum" nameend="qc" spanname="spam" />
321 <thead>
322 <row>
323 <entry morerows="1">Identifier</entry>
324 <entry morerows="1">Value</entry>
325 <entry morerows="1">Description</entry>
326 <entry spanname="chrom">Chromaticities<footnote>
327 <para>The coordinates of the color primaries are
328given in the CIE system (1931)</para>
329 </footnote></entry>
330 <entry morerows="1">White Point</entry>
331 <entry morerows="1">Gamma Correction</entry>
332 <entry morerows="1">Luminance E'<subscript>Y</subscript></entry>
333 <entry spanname="quant">Quantization</entry>
334 </row>
335 <row>
336 <entry>Red</entry>
337 <entry>Green</entry>
338 <entry>Blue</entry>
339 <entry>Y'</entry>
340 <entry>Cb, Cr</entry>
341 </row>
342 </thead>
343 <tbody valign="top">
344 <row>
345 <entry><constant>V4L2_COLORSPACE_SMPTE170M</constant></entry>
346 <entry>1</entry>
347 <entry>NTSC/PAL according to <xref linkend="smpte170m" />,
348<xref linkend="itu601" /></entry>
349 <entry>x&nbsp;=&nbsp;0.630, y&nbsp;=&nbsp;0.340</entry>
350 <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.595</entry>
351 <entry>x&nbsp;=&nbsp;0.155, y&nbsp;=&nbsp;0.070</entry>
352 <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
353 Illuminant D<subscript>65</subscript></entry>
354 <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
3551.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
356 <entry>0.299&nbsp;E'<subscript>R</subscript>
357+&nbsp;0.587&nbsp;E'<subscript>G</subscript>
358+&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
359 <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
360 <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
361 </row>
362 <row>
363 <entry><constant>V4L2_COLORSPACE_SMPTE240M</constant></entry>
364 <entry>2</entry>
365 <entry>1125-Line (US) HDTV, see <xref
366linkend="smpte240m" /></entry>
367 <entry>x&nbsp;=&nbsp;0.630, y&nbsp;=&nbsp;0.340</entry>
368 <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.595</entry>
369 <entry>x&nbsp;=&nbsp;0.155, y&nbsp;=&nbsp;0.070</entry>
370 <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
371 Illuminant D<subscript>65</subscript></entry>
372 <entry>E' = 4&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.0228,
3731.1115&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.1115&nbsp;for&nbsp;0.0228&nbsp;&lt;&nbsp;I</entry>
374 <entry>0.212&nbsp;E'<subscript>R</subscript>
375+&nbsp;0.701&nbsp;E'<subscript>G</subscript>
376+&nbsp;0.087&nbsp;E'<subscript>B</subscript></entry>
377 <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
378 <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
379 </row>
380 <row>
381 <entry><constant>V4L2_COLORSPACE_REC709</constant></entry>
382 <entry>3</entry>
383 <entry>HDTV and modern devices, see <xref
384linkend="itu709" /></entry>
385 <entry>x&nbsp;=&nbsp;0.640, y&nbsp;=&nbsp;0.330</entry>
386 <entry>x&nbsp;=&nbsp;0.300, y&nbsp;=&nbsp;0.600</entry>
387 <entry>x&nbsp;=&nbsp;0.150, y&nbsp;=&nbsp;0.060</entry>
388 <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
389 Illuminant D<subscript>65</subscript></entry>
390 <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
3911.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
392 <entry>0.2125&nbsp;E'<subscript>R</subscript>
393+&nbsp;0.7154&nbsp;E'<subscript>G</subscript>
394+&nbsp;0.0721&nbsp;E'<subscript>B</subscript></entry>
395 <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
396 <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
397 </row>
398 <row>
399 <entry><constant>V4L2_COLORSPACE_BT878</constant></entry>
400 <entry>4</entry>
401 <entry>Broken Bt878 extents<footnote>
402 <para>The ubiquitous Bt878 video capture chip
403quantizes E'<subscript>Y</subscript> to 238 levels, yielding a range
404of Y' = 16 &hellip; 253, unlike Rec. 601 Y' = 16 &hellip;
405235. This is not a typo in the Bt878 documentation, it has been
406implemented in silicon. The chroma extents are unclear.</para>
407 </footnote>, <xref linkend="itu601" /></entry>
408 <entry>?</entry>
409 <entry>?</entry>
410 <entry>?</entry>
411 <entry>?</entry>
412 <entry>?</entry>
413 <entry>0.299&nbsp;E'<subscript>R</subscript>
414+&nbsp;0.587&nbsp;E'<subscript>G</subscript>
415+&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
416 <entry><emphasis>237</emphasis>&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
417 <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128 (probably)</entry>
418 </row>
419 <row>
420 <entry><constant>V4L2_COLORSPACE_470_SYSTEM_M</constant></entry>
421 <entry>5</entry>
422 <entry>M/NTSC<footnote>
423 <para>No identifier exists for M/PAL which uses
424the chromaticities of M/NTSC, the remaining parameters are equal to B and
425G/PAL.</para>
426 </footnote> according to <xref linkend="itu470" />, <xref
427 linkend="itu601" /></entry>
428 <entry>x&nbsp;=&nbsp;0.67, y&nbsp;=&nbsp;0.33</entry>
429 <entry>x&nbsp;=&nbsp;0.21, y&nbsp;=&nbsp;0.71</entry>
430 <entry>x&nbsp;=&nbsp;0.14, y&nbsp;=&nbsp;0.08</entry>
431 <entry>x&nbsp;=&nbsp;0.310, y&nbsp;=&nbsp;0.316, Illuminant C</entry>
432 <entry>?</entry>
433 <entry>0.299&nbsp;E'<subscript>R</subscript>
434+&nbsp;0.587&nbsp;E'<subscript>G</subscript>
435+&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
436 <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
437 <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
438 </row>
439 <row>
440 <entry><constant>V4L2_COLORSPACE_470_SYSTEM_BG</constant></entry>
441 <entry>6</entry>
442 <entry>625-line PAL and SECAM systems according to <xref
443linkend="itu470" />, <xref linkend="itu601" /></entry>
444 <entry>x&nbsp;=&nbsp;0.64, y&nbsp;=&nbsp;0.33</entry>
445 <entry>x&nbsp;=&nbsp;0.29, y&nbsp;=&nbsp;0.60</entry>
446 <entry>x&nbsp;=&nbsp;0.15, y&nbsp;=&nbsp;0.06</entry>
447 <entry>x&nbsp;=&nbsp;0.313, y&nbsp;=&nbsp;0.329,
448Illuminant D<subscript>65</subscript></entry>
449 <entry>?</entry>
450 <entry>0.299&nbsp;E'<subscript>R</subscript>
451+&nbsp;0.587&nbsp;E'<subscript>G</subscript>
452+&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
453 <entry>219&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16</entry>
454 <entry>224&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
455 </row>
456 <row>
457 <entry><constant>V4L2_COLORSPACE_JPEG</constant></entry>
458 <entry>7</entry>
459 <entry>JPEG Y'CbCr, see <xref linkend="jfif" />, <xref linkend="itu601" /></entry>
460 <entry>?</entry>
461 <entry>?</entry>
462 <entry>?</entry>
463 <entry>?</entry>
464 <entry>?</entry>
465 <entry>0.299&nbsp;E'<subscript>R</subscript>
466+&nbsp;0.587&nbsp;E'<subscript>G</subscript>
467+&nbsp;0.114&nbsp;E'<subscript>B</subscript></entry>
468 <entry>256&nbsp;E'<subscript>Y</subscript>&nbsp;+&nbsp;16<footnote>
469 <para>Note JFIF quantizes
470Y'P<subscript>B</subscript>P<subscript>R</subscript> in range [0;+1] and
471[-0.5;+0.5] to <emphasis>257</emphasis> levels, however Y'CbCr signals
472are still clamped to [0;255].</para>
473 </footnote></entry>
474 <entry>256&nbsp;P<subscript>B,R</subscript>&nbsp;+&nbsp;128</entry>
475 </row>
476 <row>
477 <entry><constant>V4L2_COLORSPACE_SRGB</constant></entry>
478 <entry>8</entry>
479 <entry>[?]</entry>
480 <entry>x&nbsp;=&nbsp;0.640, y&nbsp;=&nbsp;0.330</entry>
481 <entry>x&nbsp;=&nbsp;0.300, y&nbsp;=&nbsp;0.600</entry>
482 <entry>x&nbsp;=&nbsp;0.150, y&nbsp;=&nbsp;0.060</entry>
483 <entry>x&nbsp;=&nbsp;0.3127, y&nbsp;=&nbsp;0.3290,
484 Illuminant D<subscript>65</subscript></entry>
485 <entry>E' = 4.5&nbsp;I&nbsp;for&nbsp;I&nbsp;&le;0.018,
4861.099&nbsp;I<superscript>0.45</superscript>&nbsp;-&nbsp;0.099&nbsp;for&nbsp;0.018&nbsp;&lt;&nbsp;I</entry>
487 <entry spanname="spam">n/a</entry>
488 </row>
489 </tbody>
490 </tgroup>
491 </table>
492 </section>
493
494 <section id="pixfmt-indexed">
495 <title>Indexed Format</title>
496
497 <para>In this format each pixel is represented by an 8 bit index
498into a 256 entry ARGB palette. It is intended for <link
499linkend="osd">Video Output Overlays</link> only. There are no ioctls to
500access the palette, this must be done with ioctls of the Linux framebuffer API.</para>
501
502 <table pgwide="0" frame="none">
503 <title>Indexed Image Format</title>
504 <tgroup cols="37" align="center">
505 <colspec colname="id" align="left" />
506 <colspec colname="fourcc" />
507 <colspec colname="bit" />
508
509 <colspec colnum="4" colname="b07" align="center" />
510 <colspec colnum="5" colname="b06" align="center" />
511 <colspec colnum="6" colname="b05" align="center" />
512 <colspec colnum="7" colname="b04" align="center" />
513 <colspec colnum="8" colname="b03" align="center" />
514 <colspec colnum="9" colname="b02" align="center" />
515 <colspec colnum="10" colname="b01" align="center" />
516 <colspec colnum="11" colname="b00" align="center" />
517
518 <spanspec namest="b07" nameend="b00" spanname="b0" />
519 <spanspec namest="b17" nameend="b10" spanname="b1" />
520 <spanspec namest="b27" nameend="b20" spanname="b2" />
521 <spanspec namest="b37" nameend="b30" spanname="b3" />
522 <thead>
523 <row>
524 <entry>Identifier</entry>
525 <entry>Code</entry>
526 <entry>&nbsp;</entry>
527 <entry spanname="b0">Byte&nbsp;0</entry>
528 </row>
529 <row>
530 <entry>&nbsp;</entry>
531 <entry>&nbsp;</entry>
532 <entry>Bit</entry>
533 <entry>7</entry>
534 <entry>6</entry>
535 <entry>5</entry>
536 <entry>4</entry>
537 <entry>3</entry>
538 <entry>2</entry>
539 <entry>1</entry>
540 <entry>0</entry>
541 </row>
542 </thead>
543 <tbody valign="top">
544 <row id="V4L2-PIX-FMT-PAL8">
545 <entry><constant>V4L2_PIX_FMT_PAL8</constant></entry>
546 <entry>'PAL8'</entry>
547 <entry></entry>
548 <entry>i<subscript>7</subscript></entry>
549 <entry>i<subscript>6</subscript></entry>
550 <entry>i<subscript>5</subscript></entry>
551 <entry>i<subscript>4</subscript></entry>
552 <entry>i<subscript>3</subscript></entry>
553 <entry>i<subscript>2</subscript></entry>
554 <entry>i<subscript>1</subscript></entry>
555 <entry>i<subscript>0</subscript></entry>
556 </row>
557 </tbody>
558 </tgroup>
559 </table>
560 </section>
561
562 <section id="pixfmt-rgb">
563 <title>RGB Formats</title>
564
565 &sub-packed-rgb;
566 &sub-sbggr8;
567 &sub-sgbrg8;
568 &sub-sgrbg8;
569 &sub-sbggr16;
570 </section>
571
572 <section id="yuv-formats">
573 <title>YUV Formats</title>
574
575 <para>YUV is the format native to TV broadcast and composite video
576signals. It separates the brightness information (Y) from the color
577information (U and V or Cb and Cr). The color information consists of
578red and blue <emphasis>color difference</emphasis> signals, this way
579the green component can be reconstructed by subtracting from the
580brightness component. See <xref linkend="colorspaces" /> for conversion
581examples. YUV was chosen because early television would only transmit
582brightness information. To add color in a way compatible with existing
583receivers a new signal carrier was added to transmit the color
584difference signals. Secondary in the YUV format the U and V components
585usually have lower resolution than the Y component. This is an analog
586video compression technique taking advantage of a property of the
587human visual system, being more sensitive to brightness
588information.</para>
589
590 &sub-packed-yuv;
591 &sub-grey;
592 &sub-y16;
593 &sub-yuyv;
594 &sub-uyvy;
595 &sub-yvyu;
596 &sub-vyuy;
597 &sub-y41p;
598 &sub-yuv420;
599 &sub-yuv410;
600 &sub-yuv422p;
601 &sub-yuv411p;
602 &sub-nv12;
603 &sub-nv16;
604 </section>
605
606 <section>
607 <title>Compressed Formats</title>
608
609 <table pgwide="1" frame="none" id="compressed-formats">
610 <title>Compressed Image Formats</title>
611 <tgroup cols="3" align="left">
612 &cs-def;
613 <thead>
614 <row>
615 <entry>Identifier</entry>
616 <entry>Code</entry>
617 <entry>Details</entry>
618 </row>
619 </thead>
620 <tbody valign="top">
621 <row id="V4L2-PIX-FMT-JPEG">
622 <entry><constant>V4L2_PIX_FMT_JPEG</constant></entry>
623 <entry>'JPEG'</entry>
624 <entry>TBD. See also &VIDIOC-G-JPEGCOMP;,
625 &VIDIOC-S-JPEGCOMP;.</entry>
626 </row>
627 <row id="V4L2-PIX-FMT-MPEG">
628 <entry><constant>V4L2_PIX_FMT_MPEG</constant></entry>
629 <entry>'MPEG'</entry>
630 <entry>MPEG stream. The actual format is determined by
631extended control <constant>V4L2_CID_MPEG_STREAM_TYPE</constant>, see
632<xref linkend="mpeg-control-id" />.</entry>
633 </row>
634 </tbody>
635 </tgroup>
636 </table>
637 </section>
638
639 <section id="pixfmt-reserved">
640 <title>Reserved Format Identifiers</title>
641
642 <para>These formats are not defined by this specification, they
643are just listed for reference and to avoid naming conflicts. If you
644want to register your own format, send an e-mail to the linux-media mailing
645list &v4l-ml; for inclusion in the <filename>videodev2.h</filename>
646file. If you want to share your format with other developers add a
647link to your documentation and send a copy to the linux-media mailing list
648for inclusion in this section. If you think your format should be listed
649in a standard format section please make a proposal on the linux-media mailing
650list.</para>
651
652 <table pgwide="1" frame="none" id="reserved-formats">
653 <title>Reserved Image Formats</title>
654 <tgroup cols="3" align="left">
655 &cs-def;
656 <thead>
657 <row>
658 <entry>Identifier</entry>
659 <entry>Code</entry>
660 <entry>Details</entry>
661 </row>
662 </thead>
663 <tbody valign="top">
664 <row id="V4L2-PIX-FMT-DV">
665 <entry><constant>V4L2_PIX_FMT_DV</constant></entry>
666 <entry>'dvsd'</entry>
667 <entry>unknown</entry>
668 </row>
669 <row id="V4L2-PIX-FMT-ET61X251">
670 <entry><constant>V4L2_PIX_FMT_ET61X251</constant></entry>
671 <entry>'E625'</entry>
672 <entry>Compressed format of the ET61X251 driver.</entry>
673 </row>
674 <row id="V4L2-PIX-FMT-HI240">
675 <entry><constant>V4L2_PIX_FMT_HI240</constant></entry>
676 <entry>'HI24'</entry>
677 <entry><para>8 bit RGB format used by the BTTV driver.</para></entry>
678 </row>
679 <row id="V4L2-PIX-FMT-HM12">
680 <entry><constant>V4L2_PIX_FMT_HM12</constant></entry>
681 <entry>'HM12'</entry>
682 <entry><para>YUV 4:2:0 format used by the
683IVTV driver, <ulink url="http://www.ivtvdriver.org/">
684http://www.ivtvdriver.org/</ulink></para><para>The format is documented in the
685kernel sources in the file <filename>Documentation/video4linux/cx2341x/README.hm12</filename>
686</para></entry>
687 </row>
688 <row id="V4L2-PIX-FMT-SPCA501">
689 <entry><constant>V4L2_PIX_FMT_SPCA501</constant></entry>
690 <entry>'S501'</entry>
691 <entry>YUYV per line used by the gspca driver.</entry>
692 </row>
693 <row id="V4L2-PIX-FMT-SPCA505">
694 <entry><constant>V4L2_PIX_FMT_SPCA505</constant></entry>
695 <entry>'S505'</entry>
696 <entry>YYUV per line used by the gspca driver.</entry>
697 </row>
698 <row id="V4L2-PIX-FMT-SPCA508">
699 <entry><constant>V4L2_PIX_FMT_SPCA508</constant></entry>
700 <entry>'S508'</entry>
701 <entry>YUVY per line used by the gspca driver.</entry>
702 </row>
703 <row id="V4L2-PIX-FMT-SPCA561">
704 <entry><constant>V4L2_PIX_FMT_SPCA561</constant></entry>
705 <entry>'S561'</entry>
706 <entry>Compressed GBRG Bayer format used by the gspca driver.</entry>
707 </row>
708 <row id="V4L2-PIX-FMT-SGRBG10">
709 <entry><constant>V4L2_PIX_FMT_SGRBG10</constant></entry>
710 <entry>'DA10'</entry>
711 <entry>10 bit raw Bayer, expanded to 16 bits.</entry>
712 </row>
713 <row id="V4L2-PIX-FMT-SGRBG10DPCM8">
714 <entry><constant>V4L2_PIX_FMT_SGRBG10DPCM8</constant></entry>
715 <entry>'DB10'</entry>
716 <entry>10 bit raw Bayer DPCM compressed to 8 bits.</entry>
717 </row>
718 <row id="V4L2-PIX-FMT-PAC207">
719 <entry><constant>V4L2_PIX_FMT_PAC207</constant></entry>
720 <entry>'P207'</entry>
721 <entry>Compressed BGGR Bayer format used by the gspca driver.</entry>
722 </row>
723 <row id="V4L2-PIX-FMT-MR97310A">
724 <entry><constant>V4L2_PIX_FMT_MR97310A</constant></entry>
725 <entry>'M310'</entry>
726 <entry>Compressed BGGR Bayer format used by the gspca driver.</entry>
727 </row>
728 <row id="V4L2-PIX-FMT-OV511">
729 <entry><constant>V4L2_PIX_FMT_OV511</constant></entry>
730 <entry>'O511'</entry>
731 <entry>OV511 JPEG format used by the gspca driver.</entry>
732 </row>
733 <row id="V4L2-PIX-FMT-OV518">
734 <entry><constant>V4L2_PIX_FMT_OV518</constant></entry>
735 <entry>'O518'</entry>
736 <entry>OV518 JPEG format used by the gspca driver.</entry>
737 </row>
738 <row id="V4L2-PIX-FMT-PJPG">
739 <entry><constant>V4L2_PIX_FMT_PJPG</constant></entry>
740 <entry>'PJPG'</entry>
741 <entry>Pixart 73xx JPEG format used by the gspca driver.</entry>
742 </row>
743 <row id="V4L2-PIX-FMT-SQ905C">
744 <entry><constant>V4L2_PIX_FMT_SQ905C</constant></entry>
745 <entry>'905C'</entry>
746 <entry>Compressed RGGB bayer format used by the gspca driver.</entry>
747 </row>
748 <row id="V4L2-PIX-FMT-MJPEG">
749 <entry><constant>V4L2_PIX_FMT_MJPEG</constant></entry>
750 <entry>'MJPG'</entry>
751 <entry>Compressed format used by the Zoran driver</entry>
752 </row>
753 <row id="V4L2-PIX-FMT-PWC1">
754 <entry><constant>V4L2_PIX_FMT_PWC1</constant></entry>
755 <entry>'PWC1'</entry>
756 <entry>Compressed format of the PWC driver.</entry>
757 </row>
758 <row id="V4L2-PIX-FMT-PWC2">
759 <entry><constant>V4L2_PIX_FMT_PWC2</constant></entry>
760 <entry>'PWC2'</entry>
761 <entry>Compressed format of the PWC driver.</entry>
762 </row>
763 <row id="V4L2-PIX-FMT-SN9C10X">
764 <entry><constant>V4L2_PIX_FMT_SN9C10X</constant></entry>
765 <entry>'S910'</entry>
766 <entry>Compressed format of the SN9C102 driver.</entry>
767 </row>
768 <row id="V4L2-PIX-FMT-SN9C20X-I420">
769 <entry><constant>V4L2_PIX_FMT_SN9C20X_I420</constant></entry>
770 <entry>'S920'</entry>
771 <entry>YUV 4:2:0 format of the gspca sn9c20x driver.</entry>
772 </row>
773 <row id="V4L2-PIX-FMT-WNVA">
774 <entry><constant>V4L2_PIX_FMT_WNVA</constant></entry>
775 <entry>'WNVA'</entry>
776 <entry><para>Used by the Winnov Videum driver, <ulink
777url="http://www.thedirks.org/winnov/">
778http://www.thedirks.org/winnov/</ulink></para></entry>
779 </row>
780 <row id="V4L2-PIX-FMT-TM6000">
781 <entry><constant>V4L2_PIX_FMT_TM6000</constant></entry>
782 <entry>'TM60'</entry>
783 <entry><para>Used by Trident tm6000</para></entry>
784 </row>
785 <row id="V4L2-PIX-FMT-YYUV">
786 <entry><constant>V4L2_PIX_FMT_YYUV</constant></entry>
787 <entry>'YYUV'</entry>
788 <entry>unknown</entry>
789 </row>
790 </tbody>
791 </tgroup>
792 </table>
793 </section>
794
795 <!--
796Local Variables:
797mode: sgml
798sgml-parent-document: "v4l2.sgml"
799indent-tabs-mode: nil
800End:
801 -->
diff --git a/Documentation/DocBook/v4l/remote_controllers.xml b/Documentation/DocBook/v4l/remote_controllers.xml
new file mode 100644
index 000000000000..73f5eab091f4
--- /dev/null
+++ b/Documentation/DocBook/v4l/remote_controllers.xml
@@ -0,0 +1,175 @@
1<title>Remote Controllers</title>
2<section id="Remote_controllers_Intro">
3<title>Introduction</title>
4
5<para>Currently, most analog and digital devices have a Infrared input for remote controllers. Each
6manufacturer has their own type of control. It is not rare for the same manufacturer to ship different
7types of controls, depending on the device.</para>
8<para>Unfortunately, for several years, there was no effort to create uniform IR keycodes for
9different devices. This caused the same IR keyname to be mapped completely differently on
10different IR devices. This resulted that the same IR keyname to be mapped completely different on
11different IR's. Due to that, V4L2 API now specifies a standard for mapping Media keys on IR.</para>
12<para>This standard should be used by both V4L/DVB drivers and userspace applications</para>
13<para>The modules register the remote as keyboard within the linux input layer. This means that the IR key strokes will look like normal keyboard key strokes (if CONFIG_INPUT_KEYBOARD is enabled). Using the event devices (CONFIG_INPUT_EVDEV) it is possible for applications to access the remote via /dev/input/event devices.</para>
14
15<table pgwide="1" frame="none" id="rc_standard_keymap">
16<title>IR default keymapping</title>
17<tgroup cols="3">
18&cs-str;
19<tbody valign="top">
20<row>
21<entry>Key code</entry>
22<entry>Meaning</entry>
23<entry>Key examples on IR</entry>
24</row>
25
26<row><entry><emphasis role="bold">Numeric keys</emphasis></entry></row>
27
28<row><entry><constant>KEY_0</constant></entry><entry>Keyboard digit 0</entry><entry>0</entry></row>
29<row><entry><constant>KEY_1</constant></entry><entry>Keyboard digit 1</entry><entry>1</entry></row>
30<row><entry><constant>KEY_2</constant></entry><entry>Keyboard digit 2</entry><entry>2</entry></row>
31<row><entry><constant>KEY_3</constant></entry><entry>Keyboard digit 3</entry><entry>3</entry></row>
32<row><entry><constant>KEY_4</constant></entry><entry>Keyboard digit 4</entry><entry>4</entry></row>
33<row><entry><constant>KEY_5</constant></entry><entry>Keyboard digit 5</entry><entry>5</entry></row>
34<row><entry><constant>KEY_6</constant></entry><entry>Keyboard digit 6</entry><entry>6</entry></row>
35<row><entry><constant>KEY_7</constant></entry><entry>Keyboard digit 7</entry><entry>7</entry></row>
36<row><entry><constant>KEY_8</constant></entry><entry>Keyboard digit 8</entry><entry>8</entry></row>
37<row><entry><constant>KEY_9</constant></entry><entry>Keyboard digit 9</entry><entry>9</entry></row>
38
39<row><entry><emphasis role="bold">Movie play control</emphasis></entry></row>
40
41<row><entry><constant>KEY_FORWARD</constant></entry><entry>Instantly advance in time</entry><entry>&gt;&gt; / FORWARD</entry></row>
42<row><entry><constant>KEY_BACK</constant></entry><entry>Instantly go back in time</entry><entry>&lt;&lt;&lt; / BACK</entry></row>
43<row><entry><constant>KEY_FASTFORWARD</constant></entry><entry>Play movie faster</entry><entry>&gt;&gt;&gt; / FORWARD</entry></row>
44<row><entry><constant>KEY_REWIND</constant></entry><entry>Play movie back</entry><entry>REWIND / BACKWARD</entry></row>
45<row><entry><constant>KEY_NEXT</constant></entry><entry>Select next chapter / sub-chapter / interval</entry><entry>NEXT / SKIP</entry></row>
46<row><entry><constant>KEY_PREVIOUS</constant></entry><entry>Select previous chapter / sub-chapter / interval</entry><entry>&lt;&lt; / PREV / PREVIOUS</entry></row>
47<row><entry><constant>KEY_AGAIN</constant></entry><entry>Repeat the video or a video interval</entry><entry>REPEAT / LOOP / RECALL</entry></row>
48<row><entry><constant>KEY_PAUSE</constant></entry><entry>Pause sroweam</entry><entry>PAUSE / FREEZE</entry></row>
49<row><entry><constant>KEY_PLAY</constant></entry><entry>Play movie at the normal timeshift</entry><entry>NORMAL TIMESHIFT / LIVE / &gt;</entry></row>
50<row><entry><constant>KEY_PLAYPAUSE</constant></entry><entry>Alternate between play and pause</entry><entry>PLAY / PAUSE</entry></row>
51<row><entry><constant>KEY_STOP</constant></entry><entry>Stop sroweam</entry><entry>STOP</entry></row>
52<row><entry><constant>KEY_RECORD</constant></entry><entry>Start/stop recording sroweam</entry><entry>CAPTURE / REC / RECORD/PAUSE</entry></row>
53<row><entry><constant>KEY_CAMERA</constant></entry><entry>Take a picture of the image</entry><entry>CAMERA ICON / CAPTURE / SNAPSHOT</entry></row>
54<row><entry><constant>KEY_SHUFFLE</constant></entry><entry>Enable shuffle mode</entry><entry>SHUFFLE</entry></row>
55<row><entry><constant>KEY_TIME</constant></entry><entry>Activate time shift mode</entry><entry>TIME SHIFT</entry></row>
56<row><entry><constant>KEY_TITLE</constant></entry><entry>Allow changing the chapter</entry><entry>CHAPTER</entry></row>
57<row><entry><constant>KEY_SUBTITLE</constant></entry><entry>Allow changing the subtitle</entry><entry>SUBTITLE</entry></row>
58
59<row><entry><emphasis role="bold">Image control</emphasis></entry></row>
60
61<row><entry><constant>KEY_BRIGHTNESSDOWN</constant></entry><entry>Decrease Brightness</entry><entry>BRIGHTNESS DECREASE</entry></row>
62<row><entry><constant>KEY_BRIGHTNESSUP</constant></entry><entry>Increase Brightness</entry><entry>BRIGHTNESS INCREASE</entry></row>
63
64<row><entry><constant>KEY_ANGLE</constant></entry><entry>Switch video camera angle (on videos with more than one angle stored)</entry><entry>ANGLE / SWAP</entry></row>
65<row><entry><constant>KEY_EPG</constant></entry><entry>Open the Elecrowonic Play Guide (EPG)</entry><entry>EPG / GUIDE</entry></row>
66<row><entry><constant>KEY_TEXT</constant></entry><entry>Activate/change closed caption mode</entry><entry>CLOSED CAPTION/TELETEXT / DVD TEXT / TELETEXT / TTX</entry></row>
67
68<row><entry><emphasis role="bold">Audio control</emphasis></entry></row>
69
70<row><entry><constant>KEY_AUDIO</constant></entry><entry>Change audio source</entry><entry>AUDIO SOURCE / AUDIO / MUSIC</entry></row>
71<row><entry><constant>KEY_MUTE</constant></entry><entry>Mute/unmute audio</entry><entry>MUTE / DEMUTE / UNMUTE</entry></row>
72<row><entry><constant>KEY_VOLUMEDOWN</constant></entry><entry>Decrease volume</entry><entry>VOLUME- / VOLUME DOWN</entry></row>
73<row><entry><constant>KEY_VOLUMEUP</constant></entry><entry>Increase volume</entry><entry>VOLUME+ / VOLUME UP</entry></row>
74<row><entry><constant>KEY_MODE</constant></entry><entry>Change sound mode</entry><entry>MONO/STEREO</entry></row>
75<row><entry><constant>KEY_LANGUAGE</constant></entry><entry>Select Language</entry><entry>1ST / 2ND LANGUAGE / DVD LANG / MTS/SAP / MTS SEL</entry></row>
76
77<row><entry><emphasis role="bold">Channel control</emphasis></entry></row>
78
79<row><entry><constant>KEY_CHANNEL</constant></entry><entry>Go to the next favorite channel</entry><entry>ALT / CHANNEL / CH SURFING / SURF / FAV</entry></row>
80<row><entry><constant>KEY_CHANNELDOWN</constant></entry><entry>Decrease channel sequencially</entry><entry>CHANNEL - / CHANNEL DOWN / DOWN</entry></row>
81<row><entry><constant>KEY_CHANNELUP</constant></entry><entry>Increase channel sequencially</entry><entry>CHANNEL + / CHANNEL UP / UP</entry></row>
82<row><entry><constant>KEY_DIGITS</constant></entry><entry>Use more than one digit for channel</entry><entry>PLUS / 100/ 1xx / xxx / -/-- / Single Double Triple Digit</entry></row>
83<row><entry><constant>KEY_SEARCH</constant></entry><entry>Start channel autoscan</entry><entry>SCAN / AUTOSCAN</entry></row>
84
85<row><entry><emphasis role="bold">Colored keys</emphasis></entry></row>
86
87<row><entry><constant>KEY_BLUE</constant></entry><entry>IR Blue key</entry><entry>BLUE</entry></row>
88<row><entry><constant>KEY_GREEN</constant></entry><entry>IR Green Key</entry><entry>GREEN</entry></row>
89<row><entry><constant>KEY_RED</constant></entry><entry>IR Red key</entry><entry>RED</entry></row>
90<row><entry><constant>KEY_YELLOW</constant></entry><entry>IR Yellow key</entry><entry> YELLOW</entry></row>
91
92<row><entry><emphasis role="bold">Media selection</emphasis></entry></row>
93
94<row><entry><constant>KEY_CD</constant></entry><entry>Change input source to Compact Disc</entry><entry>CD</entry></row>
95<row><entry><constant>KEY_DVD</constant></entry><entry>Change input to DVD</entry><entry>DVD / DVD MENU</entry></row>
96<row><entry><constant>KEY_EJECTCLOSECD</constant></entry><entry>Open/close the CD/DVD player</entry><entry>-&gt; ) / CLOSE / OPEN</entry></row>
97
98<row><entry><constant>KEY_MEDIA</constant></entry><entry>Turn on/off Media application</entry><entry>PC/TV / TURN ON/OFF APP</entry></row>
99<row><entry><constant>KEY_PC</constant></entry><entry>Selects from TV to PC</entry><entry>PC</entry></row>
100<row><entry><constant>KEY_RADIO</constant></entry><entry>Put into AM/FM radio mode</entry><entry>RADIO / TV/FM / TV/RADIO / FM / FM/RADIO</entry></row>
101<row><entry><constant>KEY_TV</constant></entry><entry>Select tv mode</entry><entry>TV / LIVE TV</entry></row>
102<row><entry><constant>KEY_TV2</constant></entry><entry>Select Cable mode</entry><entry>AIR/CBL</entry></row>
103<row><entry><constant>KEY_VCR</constant></entry><entry>Select VCR mode</entry><entry>VCR MODE / DTR</entry></row>
104<row><entry><constant>KEY_VIDEO</constant></entry><entry>Alternate between input modes</entry><entry>SOURCE / SELECT / DISPLAY / SWITCH INPUTS / VIDEO</entry></row>
105
106<row><entry><emphasis role="bold">Power control</emphasis></entry></row>
107
108<row><entry><constant>KEY_POWER</constant></entry><entry>Turn on/off computer</entry><entry>SYSTEM POWER / COMPUTER POWER</entry></row>
109<row><entry><constant>KEY_POWER2</constant></entry><entry>Turn on/off application</entry><entry>TV ON/OFF / POWER</entry></row>
110<row><entry><constant>KEY_SLEEP</constant></entry><entry>Activate sleep timer</entry><entry>SLEEP / SLEEP TIMER</entry></row>
111<row><entry><constant>KEY_SUSPEND</constant></entry><entry>Put computer into suspend mode</entry><entry>STANDBY / SUSPEND</entry></row>
112
113<row><entry><emphasis role="bold">Window control</emphasis></entry></row>
114
115<row><entry><constant>KEY_CLEAR</constant></entry><entry>Stop sroweam and return to default input video/audio</entry><entry>CLEAR / RESET / BOSS KEY</entry></row>
116<row><entry><constant>KEY_CYCLEWINDOWS</constant></entry><entry>Minimize windows and move to the next one</entry><entry>ALT-TAB / MINIMIZE / DESKTOP</entry></row>
117<row><entry><constant>KEY_FAVORITES</constant></entry><entry>Open the favorites sroweam window</entry><entry>TV WALL / Favorites</entry></row>
118<row><entry><constant>KEY_MENU</constant></entry><entry>Call application menu</entry><entry>2ND CONTROLS (USA: MENU) / DVD/MENU / SHOW/HIDE CTRL</entry></row>
119<row><entry><constant>KEY_NEW</constant></entry><entry>Open/Close Picture in Picture</entry><entry>PIP</entry></row>
120<row><entry><constant>KEY_OK</constant></entry><entry>Send a confirmation code to application</entry><entry>OK / ENTER / RETURN</entry></row>
121<row><entry><constant>KEY_SCREEN</constant></entry><entry>Select screen aspect ratio</entry><entry>4:3 16:9 SELECT</entry></row>
122<row><entry><constant>KEY_ZOOM</constant></entry><entry>Put device into zoom/full screen mode</entry><entry>ZOOM / FULL SCREEN / ZOOM+ / HIDE PANNEL / SWITCH</entry></row>
123
124<row><entry><emphasis role="bold">Navigation keys</emphasis></entry></row>
125
126<row><entry><constant>KEY_ESC</constant></entry><entry>Cancel current operation</entry><entry>CANCEL / BACK</entry></row>
127<row><entry><constant>KEY_HELP</constant></entry><entry>Open a Help window</entry><entry>HELP</entry></row>
128<row><entry><constant>KEY_HOMEPAGE</constant></entry><entry>Navigate to Homepage</entry><entry>HOME</entry></row>
129<row><entry><constant>KEY_INFO</constant></entry><entry>Open On Screen Display</entry><entry>DISPLAY INFORMATION / OSD</entry></row>
130<row><entry><constant>KEY_WWW</constant></entry><entry>Open the default browser</entry><entry>WEB</entry></row>
131<row><entry><constant>KEY_UP</constant></entry><entry>Up key</entry><entry>UP</entry></row>
132<row><entry><constant>KEY_DOWN</constant></entry><entry>Down key</entry><entry>DOWN</entry></row>
133<row><entry><constant>KEY_LEFT</constant></entry><entry>Left key</entry><entry>LEFT</entry></row>
134<row><entry><constant>KEY_RIGHT</constant></entry><entry>Right key</entry><entry>RIGHT</entry></row>
135
136<row><entry><emphasis role="bold">Miscelaneous keys</emphasis></entry></row>
137
138<row><entry><constant>KEY_DOT</constant></entry><entry>Return a dot</entry><entry>.</entry></row>
139<row><entry><constant>KEY_FN</constant></entry><entry>Select a function</entry><entry>FUNCTION</entry></row>
140
141</tbody>
142</tgroup>
143</table>
144
145<para>It should be noticed that, sometimes, there some fundamental missing keys at some cheaper IR's. Due to that, it is recommended to:</para>
146
147<table pgwide="1" frame="none" id="rc_keymap_notes">
148<title>Notes</title>
149<tgroup cols="1">
150&cs-str;
151<tbody valign="top">
152<row>
153<entry>On simpler IR's, without separate channel keys, you need to map UP as <constant>KEY_CHANNELUP</constant></entry>
154</row><row>
155<entry>On simpler IR's, without separate channel keys, you need to map DOWN as <constant>KEY_CHANNELDOWN</constant></entry>
156</row><row>
157<entry>On simpler IR's, without separate volume keys, you need to map LEFT as <constant>KEY_VOLUMEDOWN</constant></entry>
158</row><row>
159<entry>On simpler IR's, without separate volume keys, you need to map RIGHT as <constant>KEY_VOLUMEUP</constant></entry>
160</row>
161</tbody>
162</tgroup>
163</table>
164
165</section>
166
167<section id="Remote_controllers_table_change">
168<title>Changing default Remote Controller mappings</title>
169<para>The event interface provides two ioctls to be used against
170the /dev/input/event device, to allow changing the default
171keymapping.</para>
172
173<para>This program demonstrates how to replace the keymap tables.</para>
174&sub-keytable-c;
175</section>
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
new file mode 100644
index 000000000000..937b4157a5d0
--- /dev/null
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -0,0 +1,479 @@
1 <partinfo>
2 <authorgroup>
3 <author>
4 <firstname>Michael</firstname>
5 <surname>Schimek</surname>
6 <othername role="mi">H</othername>
7 <affiliation>
8 <address>
9 <email>mschimek@gmx.at</email>
10 </address>
11 </affiliation>
12 </author>
13
14 <author>
15 <firstname>Bill</firstname>
16 <surname>Dirks</surname>
17 <!-- Commented until Bill opts in to be spammed.
18 <affiliation>
19 <address>
20 <email>bill@thedirks.org</email>
21 </address>
22 </affiliation> -->
23 <contrib>Original author of the V4L2 API and
24documentation.</contrib>
25 </author>
26
27 <author>
28 <firstname>Hans</firstname>
29 <surname>Verkuil</surname>
30 <contrib>Designed and documented the VIDIOC_LOG_STATUS ioctl,
31the extended control ioctls and major parts of the sliced VBI
32API.</contrib>
33 <affiliation>
34 <address>
35 <email>hverkuil@xs4all.nl</email>
36 </address>
37 </affiliation>
38 </author>
39
40 <author>
41 <firstname>Martin</firstname>
42 <surname>Rubli</surname>
43 <!--
44 <affiliation>
45 <address>
46 <email>martin_rubli@logitech.com</email>
47 </address>
48 </affiliation> -->
49 <contrib>Designed and documented the VIDIOC_ENUM_FRAMESIZES
50and VIDIOC_ENUM_FRAMEINTERVALS ioctls.</contrib>
51 </author>
52
53 <author>
54 <firstname>Andy</firstname>
55 <surname>Walls</surname>
56 <contrib>Documented the fielded V4L2_MPEG_STREAM_VBI_FMT_IVTV
57MPEG stream embedded, sliced VBI data format in this specification.
58</contrib>
59 <affiliation>
60 <address>
61 <email>awalls@radix.net</email>
62 </address>
63 </affiliation>
64 </author>
65
66 <author>
67 <firstname>Mauro</firstname>
68 <surname>Carvalho Chehab</surname>
69 <contrib>Documented libv4l, designed and added v4l2grab example,
70Remote Controller chapter.</contrib>
71 <affiliation>
72 <address>
73 <email>mchehab@redhat.com</email>
74 </address>
75 </affiliation>
76 </author>
77 </authorgroup>
78
79 <copyright>
80 <year>1999</year>
81 <year>2000</year>
82 <year>2001</year>
83 <year>2002</year>
84 <year>2003</year>
85 <year>2004</year>
86 <year>2005</year>
87 <year>2006</year>
88 <year>2007</year>
89 <year>2008</year>
90 <year>2009</year>
91 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
92Rubli, Andy Walls, Mauro Carvalho Chehab</holder>
93 </copyright>
94 <legalnotice>
95 <para>Except when explicitly stated as GPL, programming examples within
96 this part can be used and distributed without restrictions.</para>
97 </legalnotice>
98 <revhistory>
99 <!-- Put document revisions here, newest first. -->
100 <!-- API revisions (changes and additions of defines, enums,
101structs, ioctls) must be noted in more detail in the history chapter
102(compat.sgml), along with the possible impact on existing drivers and
103applications. -->
104
105 <revision>
106 <revnumber>2.6.32</revnumber>
107 <date>2009-08-31</date>
108 <authorinitials>mcc</authorinitials>
109 <revremark>Now, revisions will match the kernel version where
110the V4L2 API changes will be used by the Linux Kernel.
111Also added Remote Controller chapter.</revremark>
112 </revision>
113
114 <revision>
115 <revnumber>0.29</revnumber>
116 <date>2009-08-26</date>
117 <authorinitials>ev</authorinitials>
118 <revremark>Added documentation for string controls and for FM Transmitter controls.</revremark>
119 </revision>
120
121 <revision>
122 <revnumber>0.28</revnumber>
123 <date>2009-08-26</date>
124 <authorinitials>gl</authorinitials>
125 <revremark>Added V4L2_CID_BAND_STOP_FILTER documentation.</revremark>
126 </revision>
127
128 <revision>
129 <revnumber>0.27</revnumber>
130 <date>2009-08-15</date>
131 <authorinitials>mcc</authorinitials>
132 <revremark>Added libv4l and Remote Controller documentation;
133added v4l2grab and keytable application examples.</revremark>
134 </revision>
135
136 <revision>
137 <revnumber>0.26</revnumber>
138 <date>2009-07-23</date>
139 <authorinitials>hv</authorinitials>
140 <revremark>Finalized the RDS capture API. Added modulator and RDS encoder
141capabilities. Added support for string controls.</revremark>
142 </revision>
143
144 <revision>
145 <revnumber>0.25</revnumber>
146 <date>2009-01-18</date>
147 <authorinitials>hv</authorinitials>
148 <revremark>Added pixel formats VYUY, NV16 and NV61, and changed
149the debug ioctls VIDIOC_DBG_G/S_REGISTER and VIDIOC_DBG_G_CHIP_IDENT.
150Added camera controls V4L2_CID_ZOOM_ABSOLUTE, V4L2_CID_ZOOM_RELATIVE,
151V4L2_CID_ZOOM_CONTINUOUS and V4L2_CID_PRIVACY.</revremark>
152 </revision>
153
154 <revision>
155 <revnumber>0.24</revnumber>
156 <date>2008-03-04</date>
157 <authorinitials>mhs</authorinitials>
158 <revremark>Added pixel formats Y16 and SBGGR16, new controls
159and a camera controls class. Removed VIDIOC_G/S_MPEGCOMP.</revremark>
160 </revision>
161
162 <revision>
163 <revnumber>0.23</revnumber>
164 <date>2007-08-30</date>
165 <authorinitials>mhs</authorinitials>
166 <revremark>Fixed a typo in VIDIOC_DBG_G/S_REGISTER.
167Clarified the byte order of packed pixel formats.</revremark>
168 </revision>
169
170 <revision>
171 <revnumber>0.22</revnumber>
172 <date>2007-08-29</date>
173 <authorinitials>mhs</authorinitials>
174 <revremark>Added the Video Output Overlay interface, new MPEG
175controls, V4L2_FIELD_INTERLACED_TB and V4L2_FIELD_INTERLACED_BT,
176VIDIOC_DBG_G/S_REGISTER, VIDIOC_(TRY_)ENCODER_CMD,
177VIDIOC_G_CHIP_IDENT, VIDIOC_G_ENC_INDEX, new pixel formats.
178Clarifications in the cropping chapter, about RGB pixel formats, the
179mmap(), poll(), select(), read() and write() functions. Typographical
180fixes.</revremark>
181 </revision>
182
183 <revision>
184 <revnumber>0.21</revnumber>
185 <date>2006-12-19</date>
186 <authorinitials>mhs</authorinitials>
187 <revremark>Fixed a link in the VIDIOC_G_EXT_CTRLS section.</revremark>
188 </revision>
189
190 <revision>
191 <revnumber>0.20</revnumber>
192 <date>2006-11-24</date>
193 <authorinitials>mhs</authorinitials>
194 <revremark>Clarified the purpose of the audioset field in
195struct v4l2_input and v4l2_output.</revremark>
196 </revision>
197
198 <revision>
199 <revnumber>0.19</revnumber>
200 <date>2006-10-19</date>
201 <authorinitials>mhs</authorinitials>
202 <revremark>Documented V4L2_PIX_FMT_RGB444.</revremark>
203 </revision>
204
205 <revision>
206 <revnumber>0.18</revnumber>
207 <date>2006-10-18</date>
208 <authorinitials>mhs</authorinitials>
209 <revremark>Added the description of extended controls by Hans
210Verkuil. Linked V4L2_PIX_FMT_MPEG to V4L2_CID_MPEG_STREAM_TYPE.</revremark>
211 </revision>
212
213 <revision>
214 <revnumber>0.17</revnumber>
215 <date>2006-10-12</date>
216 <authorinitials>mhs</authorinitials>
217 <revremark>Corrected V4L2_PIX_FMT_HM12 description.</revremark>
218 </revision>
219
220 <revision>
221 <revnumber>0.16</revnumber>
222 <date>2006-10-08</date>
223 <authorinitials>mhs</authorinitials>
224 <revremark>VIDIOC_ENUM_FRAMESIZES and
225VIDIOC_ENUM_FRAMEINTERVALS are now part of the API.</revremark>
226 </revision>
227
228 <revision>
229 <revnumber>0.15</revnumber>
230 <date>2006-09-23</date>
231 <authorinitials>mhs</authorinitials>
232 <revremark>Cleaned up the bibliography, added BT.653 and
233BT.1119. capture.c/start_capturing() for user pointer I/O did not
234initialize the buffer index. Documented the V4L MPEG and MJPEG
235VID_TYPEs and V4L2_PIX_FMT_SBGGR8. Updated the list of reserved pixel
236formats. See the history chapter for API changes.</revremark>
237 </revision>
238
239 <revision>
240 <revnumber>0.14</revnumber>
241 <date>2006-09-14</date>
242 <authorinitials>mr</authorinitials>
243 <revremark>Added VIDIOC_ENUM_FRAMESIZES and
244VIDIOC_ENUM_FRAMEINTERVALS proposal for frame format enumeration of
245digital devices.</revremark>
246 </revision>
247
248 <revision>
249 <revnumber>0.13</revnumber>
250 <date>2006-04-07</date>
251 <authorinitials>mhs</authorinitials>
252 <revremark>Corrected the description of struct v4l2_window
253clips. New V4L2_STD_ and V4L2_TUNER_MODE_LANG1_LANG2
254defines.</revremark>
255 </revision>
256
257 <revision>
258 <revnumber>0.12</revnumber>
259 <date>2006-02-03</date>
260 <authorinitials>mhs</authorinitials>
261 <revremark>Corrected the description of struct
262v4l2_captureparm and v4l2_outputparm.</revremark>
263 </revision>
264
265 <revision>
266 <revnumber>0.11</revnumber>
267 <date>2006-01-27</date>
268 <authorinitials>mhs</authorinitials>
269 <revremark>Improved the description of struct
270v4l2_tuner.</revremark>
271 </revision>
272
273 <revision>
274 <revnumber>0.10</revnumber>
275 <date>2006-01-10</date>
276 <authorinitials>mhs</authorinitials>
277 <revremark>VIDIOC_G_INPUT and VIDIOC_S_PARM
278clarifications.</revremark>
279 </revision>
280
281 <revision>
282 <revnumber>0.9</revnumber>
283 <date>2005-11-27</date>
284 <authorinitials>mhs</authorinitials>
285 <revremark>Improved the 525 line numbering diagram. Hans
286Verkuil and I rewrote the sliced VBI section. He also contributed a
287VIDIOC_LOG_STATUS page. Fixed VIDIOC_S_STD call in the video standard
288selection example. Various updates.</revremark>
289 </revision>
290
291 <revision>
292 <revnumber>0.8</revnumber>
293 <date>2004-10-04</date>
294 <authorinitials>mhs</authorinitials>
295 <revremark>Somehow a piece of junk slipped into the capture
296example, removed.</revremark>
297 </revision>
298
299 <revision>
300 <revnumber>0.7</revnumber>
301 <date>2004-09-19</date>
302 <authorinitials>mhs</authorinitials>
303 <revremark>Fixed video standard selection, control
304enumeration, downscaling and aspect example. Added read and user
305pointer i/o to video capture example.</revremark>
306 </revision>
307
308 <revision>
309 <revnumber>0.6</revnumber>
310 <date>2004-08-01</date>
311 <authorinitials>mhs</authorinitials>
312 <revremark>v4l2_buffer changes, added video capture example,
313various corrections.</revremark>
314 </revision>
315
316 <revision>
317 <revnumber>0.5</revnumber>
318 <date>2003-11-05</date>
319 <authorinitials>mhs</authorinitials>
320 <revremark>Pixel format erratum.</revremark>
321 </revision>
322
323 <revision>
324 <revnumber>0.4</revnumber>
325 <date>2003-09-17</date>
326 <authorinitials>mhs</authorinitials>
327 <revremark>Corrected source and Makefile to generate a PDF.
328SGML fixes. Added latest API changes. Closed gaps in the history
329chapter.</revremark>
330 </revision>
331
332 <revision>
333 <revnumber>0.3</revnumber>
334 <date>2003-02-05</date>
335 <authorinitials>mhs</authorinitials>
336 <revremark>Another draft, more corrections.</revremark>
337 </revision>
338
339 <revision>
340 <revnumber>0.2</revnumber>
341 <date>2003-01-15</date>
342 <authorinitials>mhs</authorinitials>
343 <revremark>Second draft, with corrections pointed out by Gerd
344Knorr.</revremark>
345 </revision>
346
347 <revision>
348 <revnumber>0.1</revnumber>
349 <date>2002-12-01</date>
350 <authorinitials>mhs</authorinitials>
351 <revremark>First draft, based on documentation by Bill Dirks
352and discussions on the V4L mailing list.</revremark>
353 </revision>
354 </revhistory>
355</partinfo>
356
357<title>Video for Linux Two API Specification</title>
358 <subtitle>Revision 2.6.32</subtitle>
359
360 <chapter id="common">
361 &sub-common;
362 </chapter>
363
364 <chapter id="pixfmt">
365 &sub-pixfmt;
366 </chapter>
367
368 <chapter id="io">
369 &sub-io;
370 </chapter>
371
372 <chapter id="devices">
373 <title>Interfaces</title>
374
375 <section id="capture"> &sub-dev-capture; </section>
376 <section id="overlay"> &sub-dev-overlay; </section>
377 <section id="output"> &sub-dev-output; </section>
378 <section id="osd"> &sub-dev-osd; </section>
379 <section id="codec"> &sub-dev-codec; </section>
380 <section id="effect"> &sub-dev-effect; </section>
381 <section id="raw-vbi"> &sub-dev-raw-vbi; </section>
382 <section id="sliced"> &sub-dev-sliced-vbi; </section>
383 <section id="ttx"> &sub-dev-teletext; </section>
384 <section id="radio"> &sub-dev-radio; </section>
385 <section id="rds"> &sub-dev-rds; </section>
386 </chapter>
387
388 <chapter id="driver">
389 &sub-driver;
390 </chapter>
391
392 <chapter id="libv4l">
393 &sub-libv4l;
394 </chapter>
395
396 <chapter id="compat">
397 &sub-compat;
398 </chapter>
399
400 <appendix id="user-func">
401 <title>Function Reference</title>
402
403 <!-- Keep this alphabetically sorted. -->
404
405 &sub-close;
406 &sub-ioctl;
407 <!-- All ioctls go here. -->
408 &sub-cropcap;
409 &sub-dbg-g-chip-ident;
410 &sub-dbg-g-register;
411 &sub-encoder-cmd;
412 &sub-enumaudio;
413 &sub-enumaudioout;
414 &sub-enum-fmt;
415 &sub-enum-framesizes;
416 &sub-enum-frameintervals;
417 &sub-enuminput;
418 &sub-enumoutput;
419 &sub-enumstd;
420 &sub-g-audio;
421 &sub-g-audioout;
422 &sub-g-crop;
423 &sub-g-ctrl;
424 &sub-g-enc-index;
425 &sub-g-ext-ctrls;
426 &sub-g-fbuf;
427 &sub-g-fmt;
428 &sub-g-frequency;
429 &sub-g-input;
430 &sub-g-jpegcomp;
431 &sub-g-modulator;
432 &sub-g-output;
433 &sub-g-parm;
434 &sub-g-priority;
435 &sub-g-sliced-vbi-cap;
436 &sub-g-std;
437 &sub-g-tuner;
438 &sub-log-status;
439 &sub-overlay;
440 &sub-qbuf;
441 &sub-querybuf;
442 &sub-querycap;
443 &sub-queryctrl;
444 &sub-querystd;
445 &sub-reqbufs;
446 &sub-s-hw-freq-seek;
447 &sub-streamon;
448 <!-- End of ioctls. -->
449 &sub-mmap;
450 &sub-munmap;
451 &sub-open;
452 &sub-poll;
453 &sub-read;
454 &sub-select;
455 &sub-write;
456 </appendix>
457
458 <appendix id="videodev">
459 <title>Video For Linux Two Header File</title>
460 &sub-videodev2-h;
461 </appendix>
462
463 <appendix id="capture-example">
464 <title>Video Capture Example</title>
465 &sub-capture-c;
466 </appendix>
467
468 <appendix id="v4l2grab-example">
469 <title>Video Grabber example using libv4l</title>
470 <para>This program demonstrates how to grab V4L2 images in ppm format by
471using libv4l handlers. The advantage is that this grabber can potentially work
472with any V4L2 driver.</para>
473 &sub-v4l2grab-c;
474 </appendix>
475
476 &sub-media-indices;
477
478 &sub-biblio;
479
diff --git a/Documentation/DocBook/v4l/v4l2grab.c.xml b/Documentation/DocBook/v4l/v4l2grab.c.xml
new file mode 100644
index 000000000000..bed12e40be27
--- /dev/null
+++ b/Documentation/DocBook/v4l/v4l2grab.c.xml
@@ -0,0 +1,164 @@
1<programlisting>
2/* V4L2 video picture grabber
3 Copyright (C) 2009 Mauro Carvalho Chehab &lt;mchehab@infradead.org&gt;
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation version 2 of the License.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13 */
14
15#include &lt;stdio.h&gt;
16#include &lt;stdlib.h&gt;
17#include &lt;string.h&gt;
18#include &lt;fcntl.h&gt;
19#include &lt;errno.h&gt;
20#include &lt;sys/ioctl.h&gt;
21#include &lt;sys/types.h&gt;
22#include &lt;sys/time.h&gt;
23#include &lt;sys/mman.h&gt;
24#include &lt;linux/videodev2.h&gt;
25#include "../libv4l/include/libv4l2.h"
26
27#define CLEAR(x) memset(&amp;(x), 0, sizeof(x))
28
29struct buffer {
30 void *start;
31 size_t length;
32};
33
34static void xioctl(int fh, int request, void *arg)
35{
36 int r;
37
38 do {
39 r = v4l2_ioctl(fh, request, arg);
40 } while (r == -1 &amp;&amp; ((errno == EINTR) || (errno == EAGAIN)));
41
42 if (r == -1) {
43 fprintf(stderr, "error %d, %s\n", errno, strerror(errno));
44 exit(EXIT_FAILURE);
45 }
46}
47
48int main(int argc, char **argv)
49{
50 struct <link linkend="v4l2-format">v4l2_format</link> fmt;
51 struct <link linkend="v4l2-buffer">v4l2_buffer</link> buf;
52 struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> req;
53 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
54 fd_set fds;
55 struct timeval tv;
56 int r, fd = -1;
57 unsigned int i, n_buffers;
58 char *dev_name = "/dev/video0";
59 char out_name[256];
60 FILE *fout;
61 struct buffer *buffers;
62
63 fd = v4l2_open(dev_name, O_RDWR | O_NONBLOCK, 0);
64 if (fd &lt; 0) {
65 perror("Cannot open device");
66 exit(EXIT_FAILURE);
67 }
68
69 CLEAR(fmt);
70 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
71 fmt.fmt.pix.width = 640;
72 fmt.fmt.pix.height = 480;
73 fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24;
74 fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
75 xioctl(fd, VIDIOC_S_FMT, &amp;fmt);
76 if (fmt.fmt.pix.pixelformat != V4L2_PIX_FMT_RGB24) {
77 printf("Libv4l didn't accept RGB24 format. Can't proceed.\n");
78 exit(EXIT_FAILURE);
79 }
80 if ((fmt.fmt.pix.width != 640) || (fmt.fmt.pix.height != 480))
81 printf("Warning: driver is sending image at %dx%d\n",
82 fmt.fmt.pix.width, fmt.fmt.pix.height);
83
84 CLEAR(req);
85 req.count = 2;
86 req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
87 req.memory = V4L2_MEMORY_MMAP;
88 xioctl(fd, VIDIOC_REQBUFS, &amp;req);
89
90 buffers = calloc(req.count, sizeof(*buffers));
91 for (n_buffers = 0; n_buffers &lt; req.count; ++n_buffers) {
92 CLEAR(buf);
93
94 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
95 buf.memory = V4L2_MEMORY_MMAP;
96 buf.index = n_buffers;
97
98 xioctl(fd, VIDIOC_QUERYBUF, &amp;buf);
99
100 buffers[n_buffers].length = buf.length;
101 buffers[n_buffers].start = v4l2_mmap(NULL, buf.length,
102 PROT_READ | PROT_WRITE, MAP_SHARED,
103 fd, buf.m.offset);
104
105 if (MAP_FAILED == buffers[n_buffers].start) {
106 perror("mmap");
107 exit(EXIT_FAILURE);
108 }
109 }
110
111 for (i = 0; i &lt; n_buffers; ++i) {
112 CLEAR(buf);
113 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
114 buf.memory = V4L2_MEMORY_MMAP;
115 buf.index = i;
116 xioctl(fd, VIDIOC_QBUF, &amp;buf);
117 }
118 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
119
120 xioctl(fd, VIDIOC_STREAMON, &amp;type);
121 for (i = 0; i &lt; 20; i++) {
122 do {
123 FD_ZERO(&amp;fds);
124 FD_SET(fd, &amp;fds);
125
126 /* Timeout. */
127 tv.tv_sec = 2;
128 tv.tv_usec = 0;
129
130 r = select(fd + 1, &amp;fds, NULL, NULL, &amp;tv);
131 } while ((r == -1 &amp;&amp; (errno = EINTR)));
132 if (r == -1) {
133 perror("select");
134 return errno;
135 }
136
137 CLEAR(buf);
138 buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
139 buf.memory = V4L2_MEMORY_MMAP;
140 xioctl(fd, VIDIOC_DQBUF, &amp;buf);
141
142 sprintf(out_name, "out%03d.ppm", i);
143 fout = fopen(out_name, "w");
144 if (!fout) {
145 perror("Cannot open image");
146 exit(EXIT_FAILURE);
147 }
148 fprintf(fout, "P6\n%d %d 255\n",
149 fmt.fmt.pix.width, fmt.fmt.pix.height);
150 fwrite(buffers[buf.index].start, buf.bytesused, 1, fout);
151 fclose(fout);
152
153 xioctl(fd, VIDIOC_QBUF, &amp;buf);
154 }
155
156 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
157 xioctl(fd, VIDIOC_STREAMOFF, &amp;type);
158 for (i = 0; i &lt; n_buffers; ++i)
159 v4l2_munmap(buffers[i].start, buffers[i].length);
160 v4l2_close(fd);
161
162 return 0;
163}
164</programlisting>
diff --git a/Documentation/DocBook/v4l/vbi_525.gif b/Documentation/DocBook/v4l/vbi_525.gif
new file mode 100644
index 000000000000..5580b690d504
--- /dev/null
+++ b/Documentation/DocBook/v4l/vbi_525.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/vbi_525.pdf b/Documentation/DocBook/v4l/vbi_525.pdf
new file mode 100644
index 000000000000..9e72c25b208d
--- /dev/null
+++ b/Documentation/DocBook/v4l/vbi_525.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/vbi_625.gif b/Documentation/DocBook/v4l/vbi_625.gif
new file mode 100644
index 000000000000..34e3251983c4
--- /dev/null
+++ b/Documentation/DocBook/v4l/vbi_625.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/vbi_625.pdf b/Documentation/DocBook/v4l/vbi_625.pdf
new file mode 100644
index 000000000000..765235e33a4d
--- /dev/null
+++ b/Documentation/DocBook/v4l/vbi_625.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/vbi_hsync.gif b/Documentation/DocBook/v4l/vbi_hsync.gif
new file mode 100644
index 000000000000..b02434d3b356
--- /dev/null
+++ b/Documentation/DocBook/v4l/vbi_hsync.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/vbi_hsync.pdf b/Documentation/DocBook/v4l/vbi_hsync.pdf
new file mode 100644
index 000000000000..200b668189bf
--- /dev/null
+++ b/Documentation/DocBook/v4l/vbi_hsync.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
new file mode 100644
index 000000000000..97002060ac4f
--- /dev/null
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -0,0 +1,1640 @@
1<programlisting>
2/*
3 * Video for Linux Two header file
4 *
5 * Copyright (C) 1999-2007 the contributors
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * Alternatively you can redistribute this file under the terms of the
18 * BSD license as stated below:
19 *
20 * Redistribution and use in source and binary forms, with or without
21 * modification, are permitted provided that the following conditions
22 * are met:
23 * 1. Redistributions of source code must retain the above copyright
24 * notice, this list of conditions and the following disclaimer.
25 * 2. Redistributions in binary form must reproduce the above copyright
26 * notice, this list of conditions and the following disclaimer in
27 * the documentation and/or other materials provided with the
28 * distribution.
29 * 3. The names of its contributors may not be used to endorse or promote
30 * products derived from this software without specific prior written
31 * permission.
32 *
33 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
34 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
35 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
36 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
37 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
38 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
39 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
40 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
41 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
42 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
43 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 *
45 * Header file for v4l or V4L2 drivers and applications
46 * with public API.
47 * All kernel-specific stuff were moved to media/v4l2-dev.h, so
48 * no #if __KERNEL tests are allowed here
49 *
50 * See http://linuxtv.org for more info
51 *
52 * Author: Bill Dirks &lt;bill@thedirks.org&gt;
53 * Justin Schoeman
54 * Hans Verkuil &lt;hverkuil@xs4all.nl&gt;
55 * et al.
56 */
57#ifndef __LINUX_VIDEODEV2_H
58#define __LINUX_VIDEODEV2_H
59
60#ifdef __KERNEL__
61#include &lt;linux/time.h&gt; /* need struct timeval */
62#else
63#include &lt;sys/time.h&gt;
64#endif
65#include &lt;linux/compiler.h&gt;
66#include &lt;linux/ioctl.h&gt;
67#include &lt;linux/types.h&gt;
68
69/*
70 * Common stuff for both V4L1 and V4L2
71 * Moved from videodev.h
72 */
73#define VIDEO_MAX_FRAME 32
74
75#ifndef __KERNEL__
76
77/* These defines are V4L1 specific and should not be used with the V4L2 API!
78 They will be removed from this header in the future. */
79
80#define VID_TYPE_CAPTURE 1 /* Can capture */
81#define VID_TYPE_TUNER 2 /* Can tune */
82#define VID_TYPE_TELETEXT 4 /* Does teletext */
83#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
84#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
85#define VID_TYPE_CLIPPING 32 /* Can clip */
86#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
87#define VID_TYPE_SCALES 128 /* Scalable */
88#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
89#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
90#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
91#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
92#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
93#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
94#endif
95
96/*
97 * M I S C E L L A N E O U S
98 */
99
100/* Four-character-code (FOURCC) */
101#define v4l2_fourcc(a, b, c, d)\
102 ((__u32)(a) | ((__u32)(b) &lt;&lt; 8) | ((__u32)(c) &lt;&lt; 16) | ((__u32)(d) &lt;&lt; 24))
103
104/*
105 * E N U M S
106 */
107enum <link linkend="v4l2-field">v4l2_field</link> {
108 V4L2_FIELD_ANY = 0, /* driver can choose from none,
109 top, bottom, interlaced
110 depending on whatever it thinks
111 is approximate ... */
112 V4L2_FIELD_NONE = 1, /* this device has no fields ... */
113 V4L2_FIELD_TOP = 2, /* top field only */
114 V4L2_FIELD_BOTTOM = 3, /* bottom field only */
115 V4L2_FIELD_INTERLACED = 4, /* both fields interlaced */
116 V4L2_FIELD_SEQ_TB = 5, /* both fields sequential into one
117 buffer, top-bottom order */
118 V4L2_FIELD_SEQ_BT = 6, /* same as above + bottom-top order */
119 V4L2_FIELD_ALTERNATE = 7, /* both fields alternating into
120 separate buffers */
121 V4L2_FIELD_INTERLACED_TB = 8, /* both fields interlaced, top field
122 first and the top field is
123 transmitted first */
124 V4L2_FIELD_INTERLACED_BT = 9, /* both fields interlaced, top field
125 first and the bottom field is
126 transmitted first */
127};
128#define V4L2_FIELD_HAS_TOP(field) \
129 ((field) == V4L2_FIELD_TOP ||\
130 (field) == V4L2_FIELD_INTERLACED ||\
131 (field) == V4L2_FIELD_INTERLACED_TB ||\
132 (field) == V4L2_FIELD_INTERLACED_BT ||\
133 (field) == V4L2_FIELD_SEQ_TB ||\
134 (field) == V4L2_FIELD_SEQ_BT)
135#define V4L2_FIELD_HAS_BOTTOM(field) \
136 ((field) == V4L2_FIELD_BOTTOM ||\
137 (field) == V4L2_FIELD_INTERLACED ||\
138 (field) == V4L2_FIELD_INTERLACED_TB ||\
139 (field) == V4L2_FIELD_INTERLACED_BT ||\
140 (field) == V4L2_FIELD_SEQ_TB ||\
141 (field) == V4L2_FIELD_SEQ_BT)
142#define V4L2_FIELD_HAS_BOTH(field) \
143 ((field) == V4L2_FIELD_INTERLACED ||\
144 (field) == V4L2_FIELD_INTERLACED_TB ||\
145 (field) == V4L2_FIELD_INTERLACED_BT ||\
146 (field) == V4L2_FIELD_SEQ_TB ||\
147 (field) == V4L2_FIELD_SEQ_BT)
148
149enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> {
150 V4L2_BUF_TYPE_VIDEO_CAPTURE = 1,
151 V4L2_BUF_TYPE_VIDEO_OUTPUT = 2,
152 V4L2_BUF_TYPE_VIDEO_OVERLAY = 3,
153 V4L2_BUF_TYPE_VBI_CAPTURE = 4,
154 V4L2_BUF_TYPE_VBI_OUTPUT = 5,
155 V4L2_BUF_TYPE_SLICED_VBI_CAPTURE = 6,
156 V4L2_BUF_TYPE_SLICED_VBI_OUTPUT = 7,
157#if 1 /*KEEP*/
158 /* Experimental */
159 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
160#endif
161 V4L2_BUF_TYPE_PRIVATE = 0x80,
162};
163
164enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> {
165 V4L2_CTRL_TYPE_INTEGER = 1,
166 V4L2_CTRL_TYPE_BOOLEAN = 2,
167 V4L2_CTRL_TYPE_MENU = 3,
168 V4L2_CTRL_TYPE_BUTTON = 4,
169 V4L2_CTRL_TYPE_INTEGER64 = 5,
170 V4L2_CTRL_TYPE_CTRL_CLASS = 6,
171 V4L2_CTRL_TYPE_STRING = 7,
172};
173
174enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> {
175 V4L2_TUNER_RADIO = 1,
176 V4L2_TUNER_ANALOG_TV = 2,
177 V4L2_TUNER_DIGITAL_TV = 3,
178};
179
180enum <link linkend="v4l2-memory">v4l2_memory</link> {
181 V4L2_MEMORY_MMAP = 1,
182 V4L2_MEMORY_USERPTR = 2,
183 V4L2_MEMORY_OVERLAY = 3,
184};
185
186/* see also http://vektor.theorem.ca/graphics/ycbcr/ */
187enum <link linkend="v4l2-colorspace">v4l2_colorspace</link> {
188 /* ITU-R 601 -- broadcast NTSC/PAL */
189 V4L2_COLORSPACE_SMPTE170M = 1,
190
191 /* 1125-Line (US) HDTV */
192 V4L2_COLORSPACE_SMPTE240M = 2,
193
194 /* HD and modern captures. */
195 V4L2_COLORSPACE_REC709 = 3,
196
197 /* broken BT878 extents (601, luma range 16-253 instead of 16-235) */
198 V4L2_COLORSPACE_BT878 = 4,
199
200 /* These should be useful. Assume 601 extents. */
201 V4L2_COLORSPACE_470_SYSTEM_M = 5,
202 V4L2_COLORSPACE_470_SYSTEM_BG = 6,
203
204 /* I know there will be cameras that send this. So, this is
205 * unspecified chromaticities and full 0-255 on each of the
206 * Y'CbCr components
207 */
208 V4L2_COLORSPACE_JPEG = 7,
209
210 /* For RGB colourspaces, this is probably a good start. */
211 V4L2_COLORSPACE_SRGB = 8,
212};
213
214enum <link linkend="v4l2-priority">v4l2_priority</link> {
215 V4L2_PRIORITY_UNSET = 0, /* not initialized */
216 V4L2_PRIORITY_BACKGROUND = 1,
217 V4L2_PRIORITY_INTERACTIVE = 2,
218 V4L2_PRIORITY_RECORD = 3,
219 V4L2_PRIORITY_DEFAULT = V4L2_PRIORITY_INTERACTIVE,
220};
221
222struct <link linkend="v4l2-rect">v4l2_rect</link> {
223 __s32 left;
224 __s32 top;
225 __s32 width;
226 __s32 height;
227};
228
229struct <link linkend="v4l2-fract">v4l2_fract</link> {
230 __u32 numerator;
231 __u32 denominator;
232};
233
234/*
235 * D R I V E R C A P A B I L I T I E S
236 */
237struct <link linkend="v4l2-capability">v4l2_capability</link> {
238 __u8 driver[16]; /* i.e.ie; "bttv" */
239 __u8 card[32]; /* i.e.ie; "Hauppauge WinTV" */
240 __u8 bus_info[32]; /* "PCI:" + pci_name(pci_dev) */
241 __u32 version; /* should use KERNEL_VERSION() */
242 __u32 capabilities; /* Device capabilities */
243 __u32 reserved[4];
244};
245
246/* Values for 'capabilities' field */
247#define V4L2_CAP_VIDEO_CAPTURE 0x00000001 /* Is a video capture device */
248#define V4L2_CAP_VIDEO_OUTPUT 0x00000002 /* Is a video output device */
249#define V4L2_CAP_VIDEO_OVERLAY 0x00000004 /* Can do video overlay */
250#define V4L2_CAP_VBI_CAPTURE 0x00000010 /* Is a raw VBI capture device */
251#define V4L2_CAP_VBI_OUTPUT 0x00000020 /* Is a raw VBI output device */
252#define V4L2_CAP_SLICED_VBI_CAPTURE 0x00000040 /* Is a sliced VBI capture device */
253#define V4L2_CAP_SLICED_VBI_OUTPUT 0x00000080 /* Is a sliced VBI output device */
254#define V4L2_CAP_RDS_CAPTURE 0x00000100 /* RDS data capture */
255#define V4L2_CAP_VIDEO_OUTPUT_OVERLAY 0x00000200 /* Can do video output overlay */
256#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
257#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
258
259#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
260#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
261#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
262#define V4L2_CAP_MODULATOR 0x00080000 /* has a modulator */
263
264#define V4L2_CAP_READWRITE 0x01000000 /* read/write systemcalls */
265#define V4L2_CAP_ASYNCIO 0x02000000 /* async I/O */
266#define V4L2_CAP_STREAMING 0x04000000 /* streaming I/O ioctls */
267
268/*
269 * V I D E O I M A G E F O R M A T
270 */
271struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
272 __u32 width;
273 __u32 height;
274 __u32 pixelformat;
275 enum <link linkend="v4l2-field">v4l2_field</link> field;
276 __u32 bytesperline; /* for padding, zero if unused */
277 __u32 sizeimage;
278 enum <link linkend="v4l2-colorspace">v4l2_colorspace</link> colorspace;
279 __u32 priv; /* private data, depends on pixelformat */
280};
281
282/* Pixel format FOURCC depth Description */
283
284/* RGB formats */
285#define <link linkend="V4L2-PIX-FMT-RGB332">V4L2_PIX_FMT_RGB332</link> v4l2_fourcc('R', 'G', 'B', '1') /* 8 RGB-3-3-2 */
286#define <link linkend="V4L2-PIX-FMT-RGB444">V4L2_PIX_FMT_RGB444</link> v4l2_fourcc('R', '4', '4', '4') /* 16 xxxxrrrr ggggbbbb */
287#define <link linkend="V4L2-PIX-FMT-RGB555">V4L2_PIX_FMT_RGB555</link> v4l2_fourcc('R', 'G', 'B', 'O') /* 16 RGB-5-5-5 */
288#define <link linkend="V4L2-PIX-FMT-RGB565">V4L2_PIX_FMT_RGB565</link> v4l2_fourcc('R', 'G', 'B', 'P') /* 16 RGB-5-6-5 */
289#define <link linkend="V4L2-PIX-FMT-RGB555X">V4L2_PIX_FMT_RGB555X</link> v4l2_fourcc('R', 'G', 'B', 'Q') /* 16 RGB-5-5-5 BE */
290#define <link linkend="V4L2-PIX-FMT-RGB565X">V4L2_PIX_FMT_RGB565X</link> v4l2_fourcc('R', 'G', 'B', 'R') /* 16 RGB-5-6-5 BE */
291#define <link linkend="V4L2-PIX-FMT-BGR24">V4L2_PIX_FMT_BGR24</link> v4l2_fourcc('B', 'G', 'R', '3') /* 24 BGR-8-8-8 */
292#define <link linkend="V4L2-PIX-FMT-RGB24">V4L2_PIX_FMT_RGB24</link> v4l2_fourcc('R', 'G', 'B', '3') /* 24 RGB-8-8-8 */
293#define <link linkend="V4L2-PIX-FMT-BGR32">V4L2_PIX_FMT_BGR32</link> v4l2_fourcc('B', 'G', 'R', '4') /* 32 BGR-8-8-8-8 */
294#define <link linkend="V4L2-PIX-FMT-RGB32">V4L2_PIX_FMT_RGB32</link> v4l2_fourcc('R', 'G', 'B', '4') /* 32 RGB-8-8-8-8 */
295
296/* Grey formats */
297#define <link linkend="V4L2-PIX-FMT-GREY">V4L2_PIX_FMT_GREY</link> v4l2_fourcc('G', 'R', 'E', 'Y') /* 8 Greyscale */
298#define <link linkend="V4L2-PIX-FMT-Y16">V4L2_PIX_FMT_Y16</link> v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
299
300/* Palette formats */
301#define <link linkend="V4L2-PIX-FMT-PAL8">V4L2_PIX_FMT_PAL8</link> v4l2_fourcc('P', 'A', 'L', '8') /* 8 8-bit palette */
302
303/* Luminance+Chrominance formats */
304#define <link linkend="V4L2-PIX-FMT-YVU410">V4L2_PIX_FMT_YVU410</link> v4l2_fourcc('Y', 'V', 'U', '9') /* 9 YVU 4:1:0 */
305#define <link linkend="V4L2-PIX-FMT-YVU420">V4L2_PIX_FMT_YVU420</link> v4l2_fourcc('Y', 'V', '1', '2') /* 12 YVU 4:2:0 */
306#define <link linkend="V4L2-PIX-FMT-YUYV">V4L2_PIX_FMT_YUYV</link> v4l2_fourcc('Y', 'U', 'Y', 'V') /* 16 YUV 4:2:2 */
307#define <link linkend="V4L2-PIX-FMT-YYUV">V4L2_PIX_FMT_YYUV</link> v4l2_fourcc('Y', 'Y', 'U', 'V') /* 16 YUV 4:2:2 */
308#define <link linkend="V4L2-PIX-FMT-YVYU">V4L2_PIX_FMT_YVYU</link> v4l2_fourcc('Y', 'V', 'Y', 'U') /* 16 YVU 4:2:2 */
309#define <link linkend="V4L2-PIX-FMT-UYVY">V4L2_PIX_FMT_UYVY</link> v4l2_fourcc('U', 'Y', 'V', 'Y') /* 16 YUV 4:2:2 */
310#define <link linkend="V4L2-PIX-FMT-VYUY">V4L2_PIX_FMT_VYUY</link> v4l2_fourcc('V', 'Y', 'U', 'Y') /* 16 YUV 4:2:2 */
311#define <link linkend="V4L2-PIX-FMT-YUV422P">V4L2_PIX_FMT_YUV422P</link> v4l2_fourcc('4', '2', '2', 'P') /* 16 YVU422 planar */
312#define <link linkend="V4L2-PIX-FMT-YUV411P">V4L2_PIX_FMT_YUV411P</link> v4l2_fourcc('4', '1', '1', 'P') /* 16 YVU411 planar */
313#define <link linkend="V4L2-PIX-FMT-Y41P">V4L2_PIX_FMT_Y41P</link> v4l2_fourcc('Y', '4', '1', 'P') /* 12 YUV 4:1:1 */
314#define <link linkend="V4L2-PIX-FMT-YUV444">V4L2_PIX_FMT_YUV444</link> v4l2_fourcc('Y', '4', '4', '4') /* 16 xxxxyyyy uuuuvvvv */
315#define <link linkend="V4L2-PIX-FMT-YUV555">V4L2_PIX_FMT_YUV555</link> v4l2_fourcc('Y', 'U', 'V', 'O') /* 16 YUV-5-5-5 */
316#define <link linkend="V4L2-PIX-FMT-YUV565">V4L2_PIX_FMT_YUV565</link> v4l2_fourcc('Y', 'U', 'V', 'P') /* 16 YUV-5-6-5 */
317#define <link linkend="V4L2-PIX-FMT-YUV32">V4L2_PIX_FMT_YUV32</link> v4l2_fourcc('Y', 'U', 'V', '4') /* 32 YUV-8-8-8-8 */
318#define <link linkend="V4L2-PIX-FMT-YUV410">V4L2_PIX_FMT_YUV410</link> v4l2_fourcc('Y', 'U', 'V', '9') /* 9 YUV 4:1:0 */
319#define <link linkend="V4L2-PIX-FMT-YUV420">V4L2_PIX_FMT_YUV420</link> v4l2_fourcc('Y', 'U', '1', '2') /* 12 YUV 4:2:0 */
320#define <link linkend="V4L2-PIX-FMT-HI240">V4L2_PIX_FMT_HI240</link> v4l2_fourcc('H', 'I', '2', '4') /* 8 8-bit color */
321#define <link linkend="V4L2-PIX-FMT-HM12">V4L2_PIX_FMT_HM12</link> v4l2_fourcc('H', 'M', '1', '2') /* 8 YUV 4:2:0 16x16 macroblocks */
322
323/* two planes -- one Y, one Cr + Cb interleaved */
324#define <link linkend="V4L2-PIX-FMT-NV12">V4L2_PIX_FMT_NV12</link> v4l2_fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
325#define <link linkend="V4L2-PIX-FMT-NV21">V4L2_PIX_FMT_NV21</link> v4l2_fourcc('N', 'V', '2', '1') /* 12 Y/CrCb 4:2:0 */
326#define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link> v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
327#define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link> v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
328
329/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
330#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
331#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
332#define <link linkend="V4L2-PIX-FMT-SGRBG8">V4L2_PIX_FMT_SGRBG8</link> v4l2_fourcc('G', 'R', 'B', 'G') /* 8 GRGR.. BGBG.. */
333#define <link linkend="V4L2-PIX-FMT-SGRBG10">V4L2_PIX_FMT_SGRBG10</link> v4l2_fourcc('B', 'A', '1', '0') /* 10bit raw bayer */
334 /* 10bit raw bayer DPCM compressed to 8 bits */
335#define <link linkend="V4L2-PIX-FMT-SGRBG10DPCM8">V4L2_PIX_FMT_SGRBG10DPCM8</link> v4l2_fourcc('B', 'D', '1', '0')
336 /*
337 * 10bit raw bayer, expanded to 16 bits
338 * xxxxrrrrrrrrrrxxxxgggggggggg xxxxggggggggggxxxxbbbbbbbbbb...
339 */
340#define <link linkend="V4L2-PIX-FMT-SBGGR16">V4L2_PIX_FMT_SBGGR16</link> v4l2_fourcc('B', 'Y', 'R', '2') /* 16 BGBG.. GRGR.. */
341
342/* compressed formats */
343#define <link linkend="V4L2-PIX-FMT-MJPEG">V4L2_PIX_FMT_MJPEG</link> v4l2_fourcc('M', 'J', 'P', 'G') /* Motion-JPEG */
344#define <link linkend="V4L2-PIX-FMT-JPEG">V4L2_PIX_FMT_JPEG</link> v4l2_fourcc('J', 'P', 'E', 'G') /* JFIF JPEG */
345#define <link linkend="V4L2-PIX-FMT-DV">V4L2_PIX_FMT_DV</link> v4l2_fourcc('d', 'v', 's', 'd') /* 1394 */
346#define <link linkend="V4L2-PIX-FMT-MPEG">V4L2_PIX_FMT_MPEG</link> v4l2_fourcc('M', 'P', 'E', 'G') /* MPEG-1/2/4 */
347
348/* Vendor-specific formats */
349#define <link linkend="V4L2-PIX-FMT-WNVA">V4L2_PIX_FMT_WNVA</link> v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
350#define <link linkend="V4L2-PIX-FMT-SN9C10X">V4L2_PIX_FMT_SN9C10X</link> v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */
351#define <link linkend="V4L2-PIX-FMT-SN9C20X-I420">V4L2_PIX_FMT_SN9C20X_I420</link> v4l2_fourcc('S', '9', '2', '0') /* SN9C20x YUV 4:2:0 */
352#define <link linkend="V4L2-PIX-FMT-PWC1">V4L2_PIX_FMT_PWC1</link> v4l2_fourcc('P', 'W', 'C', '1') /* pwc older webcam */
353#define <link linkend="V4L2-PIX-FMT-PWC2">V4L2_PIX_FMT_PWC2</link> v4l2_fourcc('P', 'W', 'C', '2') /* pwc newer webcam */
354#define <link linkend="V4L2-PIX-FMT-ET61X251">V4L2_PIX_FMT_ET61X251</link> v4l2_fourcc('E', '6', '2', '5') /* ET61X251 compression */
355#define <link linkend="V4L2-PIX-FMT-SPCA501">V4L2_PIX_FMT_SPCA501</link> v4l2_fourcc('S', '5', '0', '1') /* YUYV per line */
356#define <link linkend="V4L2-PIX-FMT-SPCA505">V4L2_PIX_FMT_SPCA505</link> v4l2_fourcc('S', '5', '0', '5') /* YYUV per line */
357#define <link linkend="V4L2-PIX-FMT-SPCA508">V4L2_PIX_FMT_SPCA508</link> v4l2_fourcc('S', '5', '0', '8') /* YUVY per line */
358#define <link linkend="V4L2-PIX-FMT-SPCA561">V4L2_PIX_FMT_SPCA561</link> v4l2_fourcc('S', '5', '6', '1') /* compressed GBRG bayer */
359#define <link linkend="V4L2-PIX-FMT-PAC207">V4L2_PIX_FMT_PAC207</link> v4l2_fourcc('P', '2', '0', '7') /* compressed BGGR bayer */
360#define <link linkend="V4L2-PIX-FMT-MR97310A">V4L2_PIX_FMT_MR97310A</link> v4l2_fourcc('M', '3', '1', '0') /* compressed BGGR bayer */
361#define <link linkend="V4L2-PIX-FMT-SQ905C">V4L2_PIX_FMT_SQ905C</link> v4l2_fourcc('9', '0', '5', 'C') /* compressed RGGB bayer */
362#define <link linkend="V4L2-PIX-FMT-PJPG">V4L2_PIX_FMT_PJPG</link> v4l2_fourcc('P', 'J', 'P', 'G') /* Pixart 73xx JPEG */
363#define <link linkend="V4L2-PIX-FMT-OV511">V4L2_PIX_FMT_OV511</link> v4l2_fourcc('O', '5', '1', '1') /* ov511 JPEG */
364#define <link linkend="V4L2-PIX-FMT-OV518">V4L2_PIX_FMT_OV518</link> v4l2_fourcc('O', '5', '1', '8') /* ov518 JPEG */
365#define <link linkend="V4L2-PIX-FMT-TM6000">V4L2_PIX_FMT_TM6000</link> v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
366
367/*
368 * F O R M A T E N U M E R A T I O N
369 */
370struct <link linkend="v4l2-fmtdesc">v4l2_fmtdesc</link> {
371 __u32 index; /* Format number */
372 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type; /* buffer type */
373 __u32 flags;
374 __u8 description[32]; /* Description string */
375 __u32 pixelformat; /* Format fourcc */
376 __u32 reserved[4];
377};
378
379#define V4L2_FMT_FLAG_COMPRESSED 0x0001
380#define V4L2_FMT_FLAG_EMULATED 0x0002
381
382#if 1 /*KEEP*/
383 /* Experimental Frame Size and frame rate enumeration */
384/*
385 * F R A M E S I Z E E N U M E R A T I O N
386 */
387enum <link linkend="v4l2-frmsizetypes">v4l2_frmsizetypes</link> {
388 V4L2_FRMSIZE_TYPE_DISCRETE = 1,
389 V4L2_FRMSIZE_TYPE_CONTINUOUS = 2,
390 V4L2_FRMSIZE_TYPE_STEPWISE = 3,
391};
392
393struct <link linkend="v4l2-frmsize-discrete">v4l2_frmsize_discrete</link> {
394 __u32 width; /* Frame width [pixel] */
395 __u32 height; /* Frame height [pixel] */
396};
397
398struct <link linkend="v4l2-frmsize-stepwise">v4l2_frmsize_stepwise</link> {
399 __u32 min_width; /* Minimum frame width [pixel] */
400 __u32 max_width; /* Maximum frame width [pixel] */
401 __u32 step_width; /* Frame width step size [pixel] */
402 __u32 min_height; /* Minimum frame height [pixel] */
403 __u32 max_height; /* Maximum frame height [pixel] */
404 __u32 step_height; /* Frame height step size [pixel] */
405};
406
407struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link> {
408 __u32 index; /* Frame size number */
409 __u32 pixel_format; /* Pixel format */
410 __u32 type; /* Frame size type the device supports. */
411
412 union { /* Frame size */
413 struct <link linkend="v4l2-frmsize-discrete">v4l2_frmsize_discrete</link> discrete;
414 struct <link linkend="v4l2-frmsize-stepwise">v4l2_frmsize_stepwise</link> stepwise;
415 };
416
417 __u32 reserved[2]; /* Reserved space for future use */
418};
419
420/*
421 * F R A M E R A T E E N U M E R A T I O N
422 */
423enum <link linkend="v4l2-frmivaltypes">v4l2_frmivaltypes</link> {
424 V4L2_FRMIVAL_TYPE_DISCRETE = 1,
425 V4L2_FRMIVAL_TYPE_CONTINUOUS = 2,
426 V4L2_FRMIVAL_TYPE_STEPWISE = 3,
427};
428
429struct <link linkend="v4l2-frmival-stepwise">v4l2_frmival_stepwise</link> {
430 struct <link linkend="v4l2-fract">v4l2_fract</link> min; /* Minimum frame interval [s] */
431 struct <link linkend="v4l2-fract">v4l2_fract</link> max; /* Maximum frame interval [s] */
432 struct <link linkend="v4l2-fract">v4l2_fract</link> step; /* Frame interval step size [s] */
433};
434
435struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link> {
436 __u32 index; /* Frame format index */
437 __u32 pixel_format; /* Pixel format */
438 __u32 width; /* Frame width */
439 __u32 height; /* Frame height */
440 __u32 type; /* Frame interval type the device supports. */
441
442 union { /* Frame interval */
443 struct <link linkend="v4l2-fract">v4l2_fract</link> discrete;
444 struct <link linkend="v4l2-frmival-stepwise">v4l2_frmival_stepwise</link> stepwise;
445 };
446
447 __u32 reserved[2]; /* Reserved space for future use */
448};
449#endif
450
451/*
452 * T I M E C O D E
453 */
454struct <link linkend="v4l2-timecode">v4l2_timecode</link> {
455 __u32 type;
456 __u32 flags;
457 __u8 frames;
458 __u8 seconds;
459 __u8 minutes;
460 __u8 hours;
461 __u8 userbits[4];
462};
463
464/* Type */
465#define V4L2_TC_TYPE_24FPS 1
466#define V4L2_TC_TYPE_25FPS 2
467#define V4L2_TC_TYPE_30FPS 3
468#define V4L2_TC_TYPE_50FPS 4
469#define V4L2_TC_TYPE_60FPS 5
470
471/* Flags */
472#define V4L2_TC_FLAG_DROPFRAME 0x0001 /* "drop-frame" mode */
473#define V4L2_TC_FLAG_COLORFRAME 0x0002
474#define V4L2_TC_USERBITS_field 0x000C
475#define V4L2_TC_USERBITS_USERDEFINED 0x0000
476#define V4L2_TC_USERBITS_8BITCHARS 0x0008
477/* The above is based on SMPTE timecodes */
478
479struct <link linkend="v4l2-jpegcompression">v4l2_jpegcompression</link> {
480 int quality;
481
482 int APPn; /* Number of APP segment to be written,
483 * must be 0..15 */
484 int APP_len; /* Length of data in JPEG APPn segment */
485 char APP_data[60]; /* Data in the JPEG APPn segment. */
486
487 int COM_len; /* Length of data in JPEG COM segment */
488 char COM_data[60]; /* Data in JPEG COM segment */
489
490 __u32 jpeg_markers; /* Which markers should go into the JPEG
491 * output. Unless you exactly know what
492 * you do, leave them untouched.
493 * Inluding less markers will make the
494 * resulting code smaller, but there will
495 * be fewer aplications which can read it.
496 * The presence of the APP and COM marker
497 * is influenced by APP_len and COM_len
498 * ONLY, not by this property! */
499
500#define V4L2_JPEG_MARKER_DHT (1&lt;&lt;3) /* Define Huffman Tables */
501#define V4L2_JPEG_MARKER_DQT (1&lt;&lt;4) /* Define Quantization Tables */
502#define V4L2_JPEG_MARKER_DRI (1&lt;&lt;5) /* Define Restart Interval */
503#define V4L2_JPEG_MARKER_COM (1&lt;&lt;6) /* Comment segment */
504#define V4L2_JPEG_MARKER_APP (1&lt;&lt;7) /* App segment, driver will
505 * allways use APP0 */
506};
507
508/*
509 * M E M O R Y - M A P P I N G B U F F E R S
510 */
511struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> {
512 __u32 count;
513 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
514 enum <link linkend="v4l2-memory">v4l2_memory</link> memory;
515 __u32 reserved[2];
516};
517
518struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
519 __u32 index;
520 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
521 __u32 bytesused;
522 __u32 flags;
523 enum <link linkend="v4l2-field">v4l2_field</link> field;
524 struct timeval timestamp;
525 struct <link linkend="v4l2-timecode">v4l2_timecode</link> timecode;
526 __u32 sequence;
527
528 /* memory location */
529 enum <link linkend="v4l2-memory">v4l2_memory</link> memory;
530 union {
531 __u32 offset;
532 unsigned long userptr;
533 } m;
534 __u32 length;
535 __u32 input;
536 __u32 reserved;
537};
538
539/* Flags for 'flags' field */
540#define V4L2_BUF_FLAG_MAPPED 0x0001 /* Buffer is mapped (flag) */
541#define V4L2_BUF_FLAG_QUEUED 0x0002 /* Buffer is queued for processing */
542#define V4L2_BUF_FLAG_DONE 0x0004 /* Buffer is ready */
543#define V4L2_BUF_FLAG_KEYFRAME 0x0008 /* Image is a keyframe (I-frame) */
544#define V4L2_BUF_FLAG_PFRAME 0x0010 /* Image is a P-frame */
545#define V4L2_BUF_FLAG_BFRAME 0x0020 /* Image is a B-frame */
546#define V4L2_BUF_FLAG_TIMECODE 0x0100 /* timecode field is valid */
547#define V4L2_BUF_FLAG_INPUT 0x0200 /* input field is valid */
548
549/*
550 * O V E R L A Y P R E V I E W
551 */
552struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link> {
553 __u32 capability;
554 __u32 flags;
555/* FIXME: in theory we should pass something like PCI device + memory
556 * region + offset instead of some physical address */
557 void *base;
558 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> fmt;
559};
560/* Flags for the 'capability' field. Read only */
561#define V4L2_FBUF_CAP_EXTERNOVERLAY 0x0001
562#define V4L2_FBUF_CAP_CHROMAKEY 0x0002
563#define V4L2_FBUF_CAP_LIST_CLIPPING 0x0004
564#define V4L2_FBUF_CAP_BITMAP_CLIPPING 0x0008
565#define V4L2_FBUF_CAP_LOCAL_ALPHA 0x0010
566#define V4L2_FBUF_CAP_GLOBAL_ALPHA 0x0020
567#define V4L2_FBUF_CAP_LOCAL_INV_ALPHA 0x0040
568/* Flags for the 'flags' field. */
569#define V4L2_FBUF_FLAG_PRIMARY 0x0001
570#define V4L2_FBUF_FLAG_OVERLAY 0x0002
571#define V4L2_FBUF_FLAG_CHROMAKEY 0x0004
572#define V4L2_FBUF_FLAG_LOCAL_ALPHA 0x0008
573#define V4L2_FBUF_FLAG_GLOBAL_ALPHA 0x0010
574#define V4L2_FBUF_FLAG_LOCAL_INV_ALPHA 0x0020
575
576struct <link linkend="v4l2-clip">v4l2_clip</link> {
577 struct <link linkend="v4l2-rect">v4l2_rect</link> c;
578 struct <link linkend="v4l2-clip">v4l2_clip</link> __user *next;
579};
580
581struct <link linkend="v4l2-window">v4l2_window</link> {
582 struct <link linkend="v4l2-rect">v4l2_rect</link> w;
583 enum <link linkend="v4l2-field">v4l2_field</link> field;
584 __u32 chromakey;
585 struct <link linkend="v4l2-clip">v4l2_clip</link> __user *clips;
586 __u32 clipcount;
587 void __user *bitmap;
588 __u8 global_alpha;
589};
590
591/*
592 * C A P T U R E P A R A M E T E R S
593 */
594struct <link linkend="v4l2-captureparm">v4l2_captureparm</link> {
595 __u32 capability; /* Supported modes */
596 __u32 capturemode; /* Current mode */
597 struct <link linkend="v4l2-fract">v4l2_fract</link> timeperframe; /* Time per frame in .1us units */
598 __u32 extendedmode; /* Driver-specific extensions */
599 __u32 readbuffers; /* # of buffers for read */
600 __u32 reserved[4];
601};
602
603/* Flags for 'capability' and 'capturemode' fields */
604#define V4L2_MODE_HIGHQUALITY 0x0001 /* High quality imaging mode */
605#define V4L2_CAP_TIMEPERFRAME 0x1000 /* timeperframe field is supported */
606
607struct <link linkend="v4l2-outputparm">v4l2_outputparm</link> {
608 __u32 capability; /* Supported modes */
609 __u32 outputmode; /* Current mode */
610 struct <link linkend="v4l2-fract">v4l2_fract</link> timeperframe; /* Time per frame in seconds */
611 __u32 extendedmode; /* Driver-specific extensions */
612 __u32 writebuffers; /* # of buffers for write */
613 __u32 reserved[4];
614};
615
616/*
617 * I N P U T I M A G E C R O P P I N G
618 */
619struct <link linkend="v4l2-cropcap">v4l2_cropcap</link> {
620 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
621 struct <link linkend="v4l2-rect">v4l2_rect</link> bounds;
622 struct <link linkend="v4l2-rect">v4l2_rect</link> defrect;
623 struct <link linkend="v4l2-fract">v4l2_fract</link> pixelaspect;
624};
625
626struct <link linkend="v4l2-crop">v4l2_crop</link> {
627 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
628 struct <link linkend="v4l2-rect">v4l2_rect</link> c;
629};
630
631/*
632 * A N A L O G V I D E O S T A N D A R D
633 */
634
635typedef __u64 v4l2_std_id;
636
637/* one bit for each */
638#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
639#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
640#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
641#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
642#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
643#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
644#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
645#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
646
647#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
648#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
649#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
650#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
651
652#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
653#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
654#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
655#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000)
656
657#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
658#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
659#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
660#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
661#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
662#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
663#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
664#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
665
666/* ATSC/HDTV */
667#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
668#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
669
670/* FIXME:
671 Although std_id is 64 bits, there is an issue on PPC32 architecture that
672 makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding
673 this value to 32 bits.
674 As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide),
675 it should work fine. However, if needed to add more than two standards,
676 v4l2-common.c should be fixed.
677 */
678
679/* some merged standards */
680#define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC)
681#define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B)
682#define V4L2_STD_GH (V4L2_STD_PAL_G|V4L2_STD_PAL_H|V4L2_STD_SECAM_G|V4L2_STD_SECAM_H)
683#define V4L2_STD_DK (V4L2_STD_PAL_DK|V4L2_STD_SECAM_DK)
684
685/* some common needed stuff */
686#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
687 V4L2_STD_PAL_B1 |\
688 V4L2_STD_PAL_G)
689#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
690 V4L2_STD_PAL_D1 |\
691 V4L2_STD_PAL_K)
692#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
693 V4L2_STD_PAL_DK |\
694 V4L2_STD_PAL_H |\
695 V4L2_STD_PAL_I)
696#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
697 V4L2_STD_NTSC_M_JP |\
698 V4L2_STD_NTSC_M_KR)
699#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
700 V4L2_STD_SECAM_K |\
701 V4L2_STD_SECAM_K1)
702#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
703 V4L2_STD_SECAM_G |\
704 V4L2_STD_SECAM_H |\
705 V4L2_STD_SECAM_DK |\
706 V4L2_STD_SECAM_L |\
707 V4L2_STD_SECAM_LC)
708
709#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
710 V4L2_STD_PAL_60 |\
711 V4L2_STD_NTSC |\
712 V4L2_STD_NTSC_443)
713#define V4L2_STD_625_50 (V4L2_STD_PAL |\
714 V4L2_STD_PAL_N |\
715 V4L2_STD_PAL_Nc |\
716 V4L2_STD_SECAM)
717#define V4L2_STD_ATSC (V4L2_STD_ATSC_8_VSB |\
718 V4L2_STD_ATSC_16_VSB)
719
720#define V4L2_STD_UNKNOWN 0
721#define V4L2_STD_ALL (V4L2_STD_525_60 |\
722 V4L2_STD_625_50)
723
724struct <link linkend="v4l2-standard">v4l2_standard</link> {
725 __u32 index;
726 v4l2_std_id id;
727 __u8 name[24];
728 struct <link linkend="v4l2-fract">v4l2_fract</link> frameperiod; /* Frames, not fields */
729 __u32 framelines;
730 __u32 reserved[4];
731};
732
733/*
734 * V I D E O I N P U T S
735 */
736struct <link linkend="v4l2-input">v4l2_input</link> {
737 __u32 index; /* Which input */
738 __u8 name[32]; /* Label */
739 __u32 type; /* Type of input */
740 __u32 audioset; /* Associated audios (bitfield) */
741 __u32 tuner; /* Associated tuner */
742 v4l2_std_id std;
743 __u32 status;
744 __u32 reserved[4];
745};
746
747/* Values for the 'type' field */
748#define V4L2_INPUT_TYPE_TUNER 1
749#define V4L2_INPUT_TYPE_CAMERA 2
750
751/* field 'status' - general */
752#define V4L2_IN_ST_NO_POWER 0x00000001 /* Attached device is off */
753#define V4L2_IN_ST_NO_SIGNAL 0x00000002
754#define V4L2_IN_ST_NO_COLOR 0x00000004
755
756/* field 'status' - sensor orientation */
757/* If sensor is mounted upside down set both bits */
758#define V4L2_IN_ST_HFLIP 0x00000010 /* Frames are flipped horizontally */
759#define V4L2_IN_ST_VFLIP 0x00000020 /* Frames are flipped vertically */
760
761/* field 'status' - analog */
762#define V4L2_IN_ST_NO_H_LOCK 0x00000100 /* No horizontal sync lock */
763#define V4L2_IN_ST_COLOR_KILL 0x00000200 /* Color killer is active */
764
765/* field 'status' - digital */
766#define V4L2_IN_ST_NO_SYNC 0x00010000 /* No synchronization lock */
767#define V4L2_IN_ST_NO_EQU 0x00020000 /* No equalizer lock */
768#define V4L2_IN_ST_NO_CARRIER 0x00040000 /* Carrier recovery failed */
769
770/* field 'status' - VCR and set-top box */
771#define V4L2_IN_ST_MACROVISION 0x01000000 /* Macrovision detected */
772#define V4L2_IN_ST_NO_ACCESS 0x02000000 /* Conditional access denied */
773#define V4L2_IN_ST_VTR 0x04000000 /* VTR time constant */
774
775/*
776 * V I D E O O U T P U T S
777 */
778struct <link linkend="v4l2-output">v4l2_output</link> {
779 __u32 index; /* Which output */
780 __u8 name[32]; /* Label */
781 __u32 type; /* Type of output */
782 __u32 audioset; /* Associated audios (bitfield) */
783 __u32 modulator; /* Associated modulator */
784 v4l2_std_id std;
785 __u32 reserved[4];
786};
787/* Values for the 'type' field */
788#define V4L2_OUTPUT_TYPE_MODULATOR 1
789#define V4L2_OUTPUT_TYPE_ANALOG 2
790#define V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY 3
791
792/*
793 * C O N T R O L S
794 */
795struct <link linkend="v4l2-control">v4l2_control</link> {
796 __u32 id;
797 __s32 value;
798};
799
800struct <link linkend="v4l2-ext-control">v4l2_ext_control</link> {
801 __u32 id;
802 __u32 size;
803 __u32 reserved2[1];
804 union {
805 __s32 value;
806 __s64 value64;
807 char *string;
808 };
809} __attribute__ ((packed));
810
811struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link> {
812 __u32 ctrl_class;
813 __u32 count;
814 __u32 error_idx;
815 __u32 reserved[2];
816 struct <link linkend="v4l2-ext-control">v4l2_ext_control</link> *controls;
817};
818
819/* Values for ctrl_class field */
820#define V4L2_CTRL_CLASS_USER 0x00980000 /* Old-style 'user' controls */
821#define V4L2_CTRL_CLASS_MPEG 0x00990000 /* MPEG-compression controls */
822#define V4L2_CTRL_CLASS_CAMERA 0x009a0000 /* Camera class controls */
823#define V4L2_CTRL_CLASS_FM_TX 0x009b0000 /* FM Modulator control class */
824
825#define V4L2_CTRL_ID_MASK (0x0fffffff)
826#define V4L2_CTRL_ID2CLASS(id) ((id) &amp; 0x0fff0000UL)
827#define V4L2_CTRL_DRIVER_PRIV(id) (((id) &amp; 0xffff) &gt;= 0x1000)
828
829/* Used in the VIDIOC_QUERYCTRL ioctl for querying controls */
830struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link> {
831 __u32 id;
832 enum <link linkend="v4l2-ctrl-type">v4l2_ctrl_type</link> type;
833 __u8 name[32]; /* Whatever */
834 __s32 minimum; /* Note signedness */
835 __s32 maximum;
836 __s32 step;
837 __s32 default_value;
838 __u32 flags;
839 __u32 reserved[2];
840};
841
842/* Used in the VIDIOC_QUERYMENU ioctl for querying menu items */
843struct <link linkend="v4l2-querymenu">v4l2_querymenu</link> {
844 __u32 id;
845 __u32 index;
846 __u8 name[32]; /* Whatever */
847 __u32 reserved;
848};
849
850/* Control flags */
851#define V4L2_CTRL_FLAG_DISABLED 0x0001
852#define V4L2_CTRL_FLAG_GRABBED 0x0002
853#define V4L2_CTRL_FLAG_READ_ONLY 0x0004
854#define V4L2_CTRL_FLAG_UPDATE 0x0008
855#define V4L2_CTRL_FLAG_INACTIVE 0x0010
856#define V4L2_CTRL_FLAG_SLIDER 0x0020
857#define V4L2_CTRL_FLAG_WRITE_ONLY 0x0040
858
859/* Query flag, to be ORed with the control ID */
860#define V4L2_CTRL_FLAG_NEXT_CTRL 0x80000000
861
862/* User-class control IDs defined by V4L2 */
863#define V4L2_CID_BASE (V4L2_CTRL_CLASS_USER | 0x900)
864#define V4L2_CID_USER_BASE V4L2_CID_BASE
865/* IDs reserved for driver specific controls */
866#define V4L2_CID_PRIVATE_BASE 0x08000000
867
868#define V4L2_CID_USER_CLASS (V4L2_CTRL_CLASS_USER | 1)
869#define V4L2_CID_BRIGHTNESS (V4L2_CID_BASE+0)
870#define V4L2_CID_CONTRAST (V4L2_CID_BASE+1)
871#define V4L2_CID_SATURATION (V4L2_CID_BASE+2)
872#define V4L2_CID_HUE (V4L2_CID_BASE+3)
873#define V4L2_CID_AUDIO_VOLUME (V4L2_CID_BASE+5)
874#define V4L2_CID_AUDIO_BALANCE (V4L2_CID_BASE+6)
875#define V4L2_CID_AUDIO_BASS (V4L2_CID_BASE+7)
876#define V4L2_CID_AUDIO_TREBLE (V4L2_CID_BASE+8)
877#define V4L2_CID_AUDIO_MUTE (V4L2_CID_BASE+9)
878#define V4L2_CID_AUDIO_LOUDNESS (V4L2_CID_BASE+10)
879#define V4L2_CID_BLACK_LEVEL (V4L2_CID_BASE+11) /* Deprecated */
880#define V4L2_CID_AUTO_WHITE_BALANCE (V4L2_CID_BASE+12)
881#define V4L2_CID_DO_WHITE_BALANCE (V4L2_CID_BASE+13)
882#define V4L2_CID_RED_BALANCE (V4L2_CID_BASE+14)
883#define V4L2_CID_BLUE_BALANCE (V4L2_CID_BASE+15)
884#define V4L2_CID_GAMMA (V4L2_CID_BASE+16)
885#define V4L2_CID_WHITENESS (V4L2_CID_GAMMA) /* Deprecated */
886#define V4L2_CID_EXPOSURE (V4L2_CID_BASE+17)
887#define V4L2_CID_AUTOGAIN (V4L2_CID_BASE+18)
888#define V4L2_CID_GAIN (V4L2_CID_BASE+19)
889#define V4L2_CID_HFLIP (V4L2_CID_BASE+20)
890#define V4L2_CID_VFLIP (V4L2_CID_BASE+21)
891
892/* Deprecated; use V4L2_CID_PAN_RESET and V4L2_CID_TILT_RESET */
893#define V4L2_CID_HCENTER (V4L2_CID_BASE+22)
894#define V4L2_CID_VCENTER (V4L2_CID_BASE+23)
895
896#define V4L2_CID_POWER_LINE_FREQUENCY (V4L2_CID_BASE+24)
897enum <link linkend="v4l2-power-line-frequency">v4l2_power_line_frequency</link> {
898 V4L2_CID_POWER_LINE_FREQUENCY_DISABLED = 0,
899 V4L2_CID_POWER_LINE_FREQUENCY_50HZ = 1,
900 V4L2_CID_POWER_LINE_FREQUENCY_60HZ = 2,
901};
902#define V4L2_CID_HUE_AUTO (V4L2_CID_BASE+25)
903#define V4L2_CID_WHITE_BALANCE_TEMPERATURE (V4L2_CID_BASE+26)
904#define V4L2_CID_SHARPNESS (V4L2_CID_BASE+27)
905#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28)
906#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29)
907#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
908#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
909enum <link linkend="v4l2-colorfx">v4l2_colorfx</link> {
910 V4L2_COLORFX_NONE = 0,
911 V4L2_COLORFX_BW = 1,
912 V4L2_COLORFX_SEPIA = 2,
913};
914#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
915#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
916
917/* last CID + 1 */
918#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34)
919
920/* MPEG-class control IDs defined by V4L2 */
921#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
922#define V4L2_CID_MPEG_CLASS (V4L2_CTRL_CLASS_MPEG | 1)
923
924/* MPEG streams */
925#define V4L2_CID_MPEG_STREAM_TYPE (V4L2_CID_MPEG_BASE+0)
926enum <link linkend="v4l2-mpeg-stream-type">v4l2_mpeg_stream_type</link> {
927 V4L2_MPEG_STREAM_TYPE_MPEG2_PS = 0, /* MPEG-2 program stream */
928 V4L2_MPEG_STREAM_TYPE_MPEG2_TS = 1, /* MPEG-2 transport stream */
929 V4L2_MPEG_STREAM_TYPE_MPEG1_SS = 2, /* MPEG-1 system stream */
930 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD = 3, /* MPEG-2 DVD-compatible stream */
931 V4L2_MPEG_STREAM_TYPE_MPEG1_VCD = 4, /* MPEG-1 VCD-compatible stream */
932 V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD = 5, /* MPEG-2 SVCD-compatible stream */
933};
934#define V4L2_CID_MPEG_STREAM_PID_PMT (V4L2_CID_MPEG_BASE+1)
935#define V4L2_CID_MPEG_STREAM_PID_AUDIO (V4L2_CID_MPEG_BASE+2)
936#define V4L2_CID_MPEG_STREAM_PID_VIDEO (V4L2_CID_MPEG_BASE+3)
937#define V4L2_CID_MPEG_STREAM_PID_PCR (V4L2_CID_MPEG_BASE+4)
938#define V4L2_CID_MPEG_STREAM_PES_ID_AUDIO (V4L2_CID_MPEG_BASE+5)
939#define V4L2_CID_MPEG_STREAM_PES_ID_VIDEO (V4L2_CID_MPEG_BASE+6)
940#define V4L2_CID_MPEG_STREAM_VBI_FMT (V4L2_CID_MPEG_BASE+7)
941enum <link linkend="v4l2-mpeg-stream-vbi-fmt">v4l2_mpeg_stream_vbi_fmt</link> {
942 V4L2_MPEG_STREAM_VBI_FMT_NONE = 0, /* No VBI in the MPEG stream */
943 V4L2_MPEG_STREAM_VBI_FMT_IVTV = 1, /* VBI in private packets, IVTV format */
944};
945
946/* MPEG audio */
947#define V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ (V4L2_CID_MPEG_BASE+100)
948enum <link linkend="v4l2-mpeg-audio-sampling-freq">v4l2_mpeg_audio_sampling_freq</link> {
949 V4L2_MPEG_AUDIO_SAMPLING_FREQ_44100 = 0,
950 V4L2_MPEG_AUDIO_SAMPLING_FREQ_48000 = 1,
951 V4L2_MPEG_AUDIO_SAMPLING_FREQ_32000 = 2,
952};
953#define V4L2_CID_MPEG_AUDIO_ENCODING (V4L2_CID_MPEG_BASE+101)
954enum <link linkend="v4l2-mpeg-audio-encoding">v4l2_mpeg_audio_encoding</link> {
955 V4L2_MPEG_AUDIO_ENCODING_LAYER_1 = 0,
956 V4L2_MPEG_AUDIO_ENCODING_LAYER_2 = 1,
957 V4L2_MPEG_AUDIO_ENCODING_LAYER_3 = 2,
958 V4L2_MPEG_AUDIO_ENCODING_AAC = 3,
959 V4L2_MPEG_AUDIO_ENCODING_AC3 = 4,
960};
961#define V4L2_CID_MPEG_AUDIO_L1_BITRATE (V4L2_CID_MPEG_BASE+102)
962enum <link linkend="v4l2-mpeg-audio-l1-bitrate">v4l2_mpeg_audio_l1_bitrate</link> {
963 V4L2_MPEG_AUDIO_L1_BITRATE_32K = 0,
964 V4L2_MPEG_AUDIO_L1_BITRATE_64K = 1,
965 V4L2_MPEG_AUDIO_L1_BITRATE_96K = 2,
966 V4L2_MPEG_AUDIO_L1_BITRATE_128K = 3,
967 V4L2_MPEG_AUDIO_L1_BITRATE_160K = 4,
968 V4L2_MPEG_AUDIO_L1_BITRATE_192K = 5,
969 V4L2_MPEG_AUDIO_L1_BITRATE_224K = 6,
970 V4L2_MPEG_AUDIO_L1_BITRATE_256K = 7,
971 V4L2_MPEG_AUDIO_L1_BITRATE_288K = 8,
972 V4L2_MPEG_AUDIO_L1_BITRATE_320K = 9,
973 V4L2_MPEG_AUDIO_L1_BITRATE_352K = 10,
974 V4L2_MPEG_AUDIO_L1_BITRATE_384K = 11,
975 V4L2_MPEG_AUDIO_L1_BITRATE_416K = 12,
976 V4L2_MPEG_AUDIO_L1_BITRATE_448K = 13,
977};
978#define V4L2_CID_MPEG_AUDIO_L2_BITRATE (V4L2_CID_MPEG_BASE+103)
979enum <link linkend="v4l2-mpeg-audio-l2-bitrate">v4l2_mpeg_audio_l2_bitrate</link> {
980 V4L2_MPEG_AUDIO_L2_BITRATE_32K = 0,
981 V4L2_MPEG_AUDIO_L2_BITRATE_48K = 1,
982 V4L2_MPEG_AUDIO_L2_BITRATE_56K = 2,
983 V4L2_MPEG_AUDIO_L2_BITRATE_64K = 3,
984 V4L2_MPEG_AUDIO_L2_BITRATE_80K = 4,
985 V4L2_MPEG_AUDIO_L2_BITRATE_96K = 5,
986 V4L2_MPEG_AUDIO_L2_BITRATE_112K = 6,
987 V4L2_MPEG_AUDIO_L2_BITRATE_128K = 7,
988 V4L2_MPEG_AUDIO_L2_BITRATE_160K = 8,
989 V4L2_MPEG_AUDIO_L2_BITRATE_192K = 9,
990 V4L2_MPEG_AUDIO_L2_BITRATE_224K = 10,
991 V4L2_MPEG_AUDIO_L2_BITRATE_256K = 11,
992 V4L2_MPEG_AUDIO_L2_BITRATE_320K = 12,
993 V4L2_MPEG_AUDIO_L2_BITRATE_384K = 13,
994};
995#define V4L2_CID_MPEG_AUDIO_L3_BITRATE (V4L2_CID_MPEG_BASE+104)
996enum <link linkend="v4l2-mpeg-audio-l3-bitrate">v4l2_mpeg_audio_l3_bitrate</link> {
997 V4L2_MPEG_AUDIO_L3_BITRATE_32K = 0,
998 V4L2_MPEG_AUDIO_L3_BITRATE_40K = 1,
999 V4L2_MPEG_AUDIO_L3_BITRATE_48K = 2,
1000 V4L2_MPEG_AUDIO_L3_BITRATE_56K = 3,
1001 V4L2_MPEG_AUDIO_L3_BITRATE_64K = 4,
1002 V4L2_MPEG_AUDIO_L3_BITRATE_80K = 5,
1003 V4L2_MPEG_AUDIO_L3_BITRATE_96K = 6,
1004 V4L2_MPEG_AUDIO_L3_BITRATE_112K = 7,
1005 V4L2_MPEG_AUDIO_L3_BITRATE_128K = 8,
1006 V4L2_MPEG_AUDIO_L3_BITRATE_160K = 9,
1007 V4L2_MPEG_AUDIO_L3_BITRATE_192K = 10,
1008 V4L2_MPEG_AUDIO_L3_BITRATE_224K = 11,
1009 V4L2_MPEG_AUDIO_L3_BITRATE_256K = 12,
1010 V4L2_MPEG_AUDIO_L3_BITRATE_320K = 13,
1011};
1012#define V4L2_CID_MPEG_AUDIO_MODE (V4L2_CID_MPEG_BASE+105)
1013enum <link linkend="v4l2-mpeg-audio-mode">v4l2_mpeg_audio_mode</link> {
1014 V4L2_MPEG_AUDIO_MODE_STEREO = 0,
1015 V4L2_MPEG_AUDIO_MODE_JOINT_STEREO = 1,
1016 V4L2_MPEG_AUDIO_MODE_DUAL = 2,
1017 V4L2_MPEG_AUDIO_MODE_MONO = 3,
1018};
1019#define V4L2_CID_MPEG_AUDIO_MODE_EXTENSION (V4L2_CID_MPEG_BASE+106)
1020enum <link linkend="v4l2-mpeg-audio-mode-extension">v4l2_mpeg_audio_mode_extension</link> {
1021 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_4 = 0,
1022 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_8 = 1,
1023 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_12 = 2,
1024 V4L2_MPEG_AUDIO_MODE_EXTENSION_BOUND_16 = 3,
1025};
1026#define V4L2_CID_MPEG_AUDIO_EMPHASIS (V4L2_CID_MPEG_BASE+107)
1027enum <link linkend="v4l2-mpeg-audio-emphasis">v4l2_mpeg_audio_emphasis</link> {
1028 V4L2_MPEG_AUDIO_EMPHASIS_NONE = 0,
1029 V4L2_MPEG_AUDIO_EMPHASIS_50_DIV_15_uS = 1,
1030 V4L2_MPEG_AUDIO_EMPHASIS_CCITT_J17 = 2,
1031};
1032#define V4L2_CID_MPEG_AUDIO_CRC (V4L2_CID_MPEG_BASE+108)
1033enum <link linkend="v4l2-mpeg-audio-crc">v4l2_mpeg_audio_crc</link> {
1034 V4L2_MPEG_AUDIO_CRC_NONE = 0,
1035 V4L2_MPEG_AUDIO_CRC_CRC16 = 1,
1036};
1037#define V4L2_CID_MPEG_AUDIO_MUTE (V4L2_CID_MPEG_BASE+109)
1038#define V4L2_CID_MPEG_AUDIO_AAC_BITRATE (V4L2_CID_MPEG_BASE+110)
1039#define V4L2_CID_MPEG_AUDIO_AC3_BITRATE (V4L2_CID_MPEG_BASE+111)
1040enum <link linkend="v4l2-mpeg-audio-ac3-bitrate">v4l2_mpeg_audio_ac3_bitrate</link> {
1041 V4L2_MPEG_AUDIO_AC3_BITRATE_32K = 0,
1042 V4L2_MPEG_AUDIO_AC3_BITRATE_40K = 1,
1043 V4L2_MPEG_AUDIO_AC3_BITRATE_48K = 2,
1044 V4L2_MPEG_AUDIO_AC3_BITRATE_56K = 3,
1045 V4L2_MPEG_AUDIO_AC3_BITRATE_64K = 4,
1046 V4L2_MPEG_AUDIO_AC3_BITRATE_80K = 5,
1047 V4L2_MPEG_AUDIO_AC3_BITRATE_96K = 6,
1048 V4L2_MPEG_AUDIO_AC3_BITRATE_112K = 7,
1049 V4L2_MPEG_AUDIO_AC3_BITRATE_128K = 8,
1050 V4L2_MPEG_AUDIO_AC3_BITRATE_160K = 9,
1051 V4L2_MPEG_AUDIO_AC3_BITRATE_192K = 10,
1052 V4L2_MPEG_AUDIO_AC3_BITRATE_224K = 11,
1053 V4L2_MPEG_AUDIO_AC3_BITRATE_256K = 12,
1054 V4L2_MPEG_AUDIO_AC3_BITRATE_320K = 13,
1055 V4L2_MPEG_AUDIO_AC3_BITRATE_384K = 14,
1056 V4L2_MPEG_AUDIO_AC3_BITRATE_448K = 15,
1057 V4L2_MPEG_AUDIO_AC3_BITRATE_512K = 16,
1058 V4L2_MPEG_AUDIO_AC3_BITRATE_576K = 17,
1059 V4L2_MPEG_AUDIO_AC3_BITRATE_640K = 18,
1060};
1061
1062/* MPEG video */
1063#define V4L2_CID_MPEG_VIDEO_ENCODING (V4L2_CID_MPEG_BASE+200)
1064enum <link linkend="v4l2-mpeg-video-encoding">v4l2_mpeg_video_encoding</link> {
1065 V4L2_MPEG_VIDEO_ENCODING_MPEG_1 = 0,
1066 V4L2_MPEG_VIDEO_ENCODING_MPEG_2 = 1,
1067 V4L2_MPEG_VIDEO_ENCODING_MPEG_4_AVC = 2,
1068};
1069#define V4L2_CID_MPEG_VIDEO_ASPECT (V4L2_CID_MPEG_BASE+201)
1070enum <link linkend="v4l2-mpeg-video-aspect">v4l2_mpeg_video_aspect</link> {
1071 V4L2_MPEG_VIDEO_ASPECT_1x1 = 0,
1072 V4L2_MPEG_VIDEO_ASPECT_4x3 = 1,
1073 V4L2_MPEG_VIDEO_ASPECT_16x9 = 2,
1074 V4L2_MPEG_VIDEO_ASPECT_221x100 = 3,
1075};
1076#define V4L2_CID_MPEG_VIDEO_B_FRAMES (V4L2_CID_MPEG_BASE+202)
1077#define V4L2_CID_MPEG_VIDEO_GOP_SIZE (V4L2_CID_MPEG_BASE+203)
1078#define V4L2_CID_MPEG_VIDEO_GOP_CLOSURE (V4L2_CID_MPEG_BASE+204)
1079#define V4L2_CID_MPEG_VIDEO_PULLDOWN (V4L2_CID_MPEG_BASE+205)
1080#define V4L2_CID_MPEG_VIDEO_BITRATE_MODE (V4L2_CID_MPEG_BASE+206)
1081enum <link linkend="v4l2-mpeg-video-bitrate-mode">v4l2_mpeg_video_bitrate_mode</link> {
1082 V4L2_MPEG_VIDEO_BITRATE_MODE_VBR = 0,
1083 V4L2_MPEG_VIDEO_BITRATE_MODE_CBR = 1,
1084};
1085#define V4L2_CID_MPEG_VIDEO_BITRATE (V4L2_CID_MPEG_BASE+207)
1086#define V4L2_CID_MPEG_VIDEO_BITRATE_PEAK (V4L2_CID_MPEG_BASE+208)
1087#define V4L2_CID_MPEG_VIDEO_TEMPORAL_DECIMATION (V4L2_CID_MPEG_BASE+209)
1088#define V4L2_CID_MPEG_VIDEO_MUTE (V4L2_CID_MPEG_BASE+210)
1089#define V4L2_CID_MPEG_VIDEO_MUTE_YUV (V4L2_CID_MPEG_BASE+211)
1090
1091/* MPEG-class control IDs specific to the CX2341x driver as defined by V4L2 */
1092#define V4L2_CID_MPEG_CX2341X_BASE (V4L2_CTRL_CLASS_MPEG | 0x1000)
1093#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+0)
1094enum <link linkend="v4l2-mpeg-cx2341x-video-spatial-filter-mode">v4l2_mpeg_cx2341x_video_spatial_filter_mode</link> {
1095 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_MANUAL = 0,
1096 V4L2_MPEG_CX2341X_VIDEO_SPATIAL_FILTER_MODE_AUTO = 1,
1097};
1098#define V4L2_CID_MPEG_CX2341X_VIDEO_SPATIAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+1)
1099#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+2)
1100enum <link linkend="luma-spatial-filter-type">v4l2_mpeg_cx2341x_video_luma_spatial_filter_type</link> {
1101 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_OFF = 0,
1102 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
1103 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_1D_VERT = 2,
1104 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_HV_SEPARABLE = 3,
1105 V4L2_MPEG_CX2341X_VIDEO_LUMA_SPATIAL_FILTER_TYPE_2D_SYM_NON_SEPARABLE = 4,
1106};
1107#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+3)
1108enum <link linkend="chroma-spatial-filter-type">v4l2_mpeg_cx2341x_video_chroma_spatial_filter_type</link> {
1109 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_OFF = 0,
1110 V4L2_MPEG_CX2341X_VIDEO_CHROMA_SPATIAL_FILTER_TYPE_1D_HOR = 1,
1111};
1112#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE (V4L2_CID_MPEG_CX2341X_BASE+4)
1113enum <link linkend="v4l2-mpeg-cx2341x-video-temporal-filter-mode">v4l2_mpeg_cx2341x_video_temporal_filter_mode</link> {
1114 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_MANUAL = 0,
1115 V4L2_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER_MODE_AUTO = 1,
1116};
1117#define V4L2_CID_MPEG_CX2341X_VIDEO_TEMPORAL_FILTER (V4L2_CID_MPEG_CX2341X_BASE+5)
1118#define V4L2_CID_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE (V4L2_CID_MPEG_CX2341X_BASE+6)
1119enum <link linkend="v4l2-mpeg-cx2341x-video-median-filter-type">v4l2_mpeg_cx2341x_video_median_filter_type</link> {
1120 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_OFF = 0,
1121 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR = 1,
1122 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_VERT = 2,
1123 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_HOR_VERT = 3,
1124 V4L2_MPEG_CX2341X_VIDEO_MEDIAN_FILTER_TYPE_DIAG = 4,
1125};
1126#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+7)
1127#define V4L2_CID_MPEG_CX2341X_VIDEO_LUMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+8)
1128#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_BOTTOM (V4L2_CID_MPEG_CX2341X_BASE+9)
1129#define V4L2_CID_MPEG_CX2341X_VIDEO_CHROMA_MEDIAN_FILTER_TOP (V4L2_CID_MPEG_CX2341X_BASE+10)
1130#define V4L2_CID_MPEG_CX2341X_STREAM_INSERT_NAV_PACKETS (V4L2_CID_MPEG_CX2341X_BASE+11)
1131
1132/* Camera class control IDs */
1133#define V4L2_CID_CAMERA_CLASS_BASE (V4L2_CTRL_CLASS_CAMERA | 0x900)
1134#define V4L2_CID_CAMERA_CLASS (V4L2_CTRL_CLASS_CAMERA | 1)
1135
1136#define V4L2_CID_EXPOSURE_AUTO (V4L2_CID_CAMERA_CLASS_BASE+1)
1137enum <link linkend="v4l2-exposure-auto-type">v4l2_exposure_auto_type</link> {
1138 V4L2_EXPOSURE_AUTO = 0,
1139 V4L2_EXPOSURE_MANUAL = 1,
1140 V4L2_EXPOSURE_SHUTTER_PRIORITY = 2,
1141 V4L2_EXPOSURE_APERTURE_PRIORITY = 3
1142};
1143#define V4L2_CID_EXPOSURE_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+2)
1144#define V4L2_CID_EXPOSURE_AUTO_PRIORITY (V4L2_CID_CAMERA_CLASS_BASE+3)
1145
1146#define V4L2_CID_PAN_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+4)
1147#define V4L2_CID_TILT_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+5)
1148#define V4L2_CID_PAN_RESET (V4L2_CID_CAMERA_CLASS_BASE+6)
1149#define V4L2_CID_TILT_RESET (V4L2_CID_CAMERA_CLASS_BASE+7)
1150
1151#define V4L2_CID_PAN_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+8)
1152#define V4L2_CID_TILT_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+9)
1153
1154#define V4L2_CID_FOCUS_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+10)
1155#define V4L2_CID_FOCUS_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+11)
1156#define V4L2_CID_FOCUS_AUTO (V4L2_CID_CAMERA_CLASS_BASE+12)
1157
1158#define V4L2_CID_ZOOM_ABSOLUTE (V4L2_CID_CAMERA_CLASS_BASE+13)
1159#define V4L2_CID_ZOOM_RELATIVE (V4L2_CID_CAMERA_CLASS_BASE+14)
1160#define V4L2_CID_ZOOM_CONTINUOUS (V4L2_CID_CAMERA_CLASS_BASE+15)
1161
1162#define V4L2_CID_PRIVACY (V4L2_CID_CAMERA_CLASS_BASE+16)
1163
1164/* FM Modulator class control IDs */
1165#define V4L2_CID_FM_TX_CLASS_BASE (V4L2_CTRL_CLASS_FM_TX | 0x900)
1166#define V4L2_CID_FM_TX_CLASS (V4L2_CTRL_CLASS_FM_TX | 1)
1167
1168#define V4L2_CID_RDS_TX_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 1)
1169#define V4L2_CID_RDS_TX_PI (V4L2_CID_FM_TX_CLASS_BASE + 2)
1170#define V4L2_CID_RDS_TX_PTY (V4L2_CID_FM_TX_CLASS_BASE + 3)
1171#define V4L2_CID_RDS_TX_PS_NAME (V4L2_CID_FM_TX_CLASS_BASE + 5)
1172#define V4L2_CID_RDS_TX_RADIO_TEXT (V4L2_CID_FM_TX_CLASS_BASE + 6)
1173
1174#define V4L2_CID_AUDIO_LIMITER_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 64)
1175#define V4L2_CID_AUDIO_LIMITER_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 65)
1176#define V4L2_CID_AUDIO_LIMITER_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 66)
1177
1178#define V4L2_CID_AUDIO_COMPRESSION_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 80)
1179#define V4L2_CID_AUDIO_COMPRESSION_GAIN (V4L2_CID_FM_TX_CLASS_BASE + 81)
1180#define V4L2_CID_AUDIO_COMPRESSION_THRESHOLD (V4L2_CID_FM_TX_CLASS_BASE + 82)
1181#define V4L2_CID_AUDIO_COMPRESSION_ATTACK_TIME (V4L2_CID_FM_TX_CLASS_BASE + 83)
1182#define V4L2_CID_AUDIO_COMPRESSION_RELEASE_TIME (V4L2_CID_FM_TX_CLASS_BASE + 84)
1183
1184#define V4L2_CID_PILOT_TONE_ENABLED (V4L2_CID_FM_TX_CLASS_BASE + 96)
1185#define V4L2_CID_PILOT_TONE_DEVIATION (V4L2_CID_FM_TX_CLASS_BASE + 97)
1186#define V4L2_CID_PILOT_TONE_FREQUENCY (V4L2_CID_FM_TX_CLASS_BASE + 98)
1187
1188#define V4L2_CID_TUNE_PREEMPHASIS (V4L2_CID_FM_TX_CLASS_BASE + 112)
1189enum <link linkend="v4l2-preemphasis">v4l2_preemphasis</link> {
1190 V4L2_PREEMPHASIS_DISABLED = 0,
1191 V4L2_PREEMPHASIS_50_uS = 1,
1192 V4L2_PREEMPHASIS_75_uS = 2,
1193};
1194#define V4L2_CID_TUNE_POWER_LEVEL (V4L2_CID_FM_TX_CLASS_BASE + 113)
1195#define V4L2_CID_TUNE_ANTENNA_CAPACITOR (V4L2_CID_FM_TX_CLASS_BASE + 114)
1196
1197/*
1198 * T U N I N G
1199 */
1200struct <link linkend="v4l2-tuner">v4l2_tuner</link> {
1201 __u32 index;
1202 __u8 name[32];
1203 enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> type;
1204 __u32 capability;
1205 __u32 rangelow;
1206 __u32 rangehigh;
1207 __u32 rxsubchans;
1208 __u32 audmode;
1209 __s32 signal;
1210 __s32 afc;
1211 __u32 reserved[4];
1212};
1213
1214struct <link linkend="v4l2-modulator">v4l2_modulator</link> {
1215 __u32 index;
1216 __u8 name[32];
1217 __u32 capability;
1218 __u32 rangelow;
1219 __u32 rangehigh;
1220 __u32 txsubchans;
1221 __u32 reserved[4];
1222};
1223
1224/* Flags for the 'capability' field */
1225#define V4L2_TUNER_CAP_LOW 0x0001
1226#define V4L2_TUNER_CAP_NORM 0x0002
1227#define V4L2_TUNER_CAP_STEREO 0x0010
1228#define V4L2_TUNER_CAP_LANG2 0x0020
1229#define V4L2_TUNER_CAP_SAP 0x0020
1230#define V4L2_TUNER_CAP_LANG1 0x0040
1231#define V4L2_TUNER_CAP_RDS 0x0080
1232
1233/* Flags for the 'rxsubchans' field */
1234#define V4L2_TUNER_SUB_MONO 0x0001
1235#define V4L2_TUNER_SUB_STEREO 0x0002
1236#define V4L2_TUNER_SUB_LANG2 0x0004
1237#define V4L2_TUNER_SUB_SAP 0x0004
1238#define V4L2_TUNER_SUB_LANG1 0x0008
1239#define V4L2_TUNER_SUB_RDS 0x0010
1240
1241/* Values for the 'audmode' field */
1242#define V4L2_TUNER_MODE_MONO 0x0000
1243#define V4L2_TUNER_MODE_STEREO 0x0001
1244#define V4L2_TUNER_MODE_LANG2 0x0002
1245#define V4L2_TUNER_MODE_SAP 0x0002
1246#define V4L2_TUNER_MODE_LANG1 0x0003
1247#define V4L2_TUNER_MODE_LANG1_LANG2 0x0004
1248
1249struct <link linkend="v4l2-frequency">v4l2_frequency</link> {
1250 __u32 tuner;
1251 enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> type;
1252 __u32 frequency;
1253 __u32 reserved[8];
1254};
1255
1256struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link> {
1257 __u32 tuner;
1258 enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> type;
1259 __u32 seek_upward;
1260 __u32 wrap_around;
1261 __u32 reserved[8];
1262};
1263
1264/*
1265 * R D S
1266 */
1267
1268struct <link linkend="v4l2-rds-data">v4l2_rds_data</link> {
1269 __u8 lsb;
1270 __u8 msb;
1271 __u8 block;
1272} __attribute__ ((packed));
1273
1274#define V4L2_RDS_BLOCK_MSK 0x7
1275#define V4L2_RDS_BLOCK_A 0
1276#define V4L2_RDS_BLOCK_B 1
1277#define V4L2_RDS_BLOCK_C 2
1278#define V4L2_RDS_BLOCK_D 3
1279#define V4L2_RDS_BLOCK_C_ALT 4
1280#define V4L2_RDS_BLOCK_INVALID 7
1281
1282#define V4L2_RDS_BLOCK_CORRECTED 0x40
1283#define V4L2_RDS_BLOCK_ERROR 0x80
1284
1285/*
1286 * A U D I O
1287 */
1288struct <link linkend="v4l2-audio">v4l2_audio</link> {
1289 __u32 index;
1290 __u8 name[32];
1291 __u32 capability;
1292 __u32 mode;
1293 __u32 reserved[2];
1294};
1295
1296/* Flags for the 'capability' field */
1297#define V4L2_AUDCAP_STEREO 0x00001
1298#define V4L2_AUDCAP_AVL 0x00002
1299
1300/* Flags for the 'mode' field */
1301#define V4L2_AUDMODE_AVL 0x00001
1302
1303struct <link linkend="v4l2-audioout">v4l2_audioout</link> {
1304 __u32 index;
1305 __u8 name[32];
1306 __u32 capability;
1307 __u32 mode;
1308 __u32 reserved[2];
1309};
1310
1311/*
1312 * M P E G S E R V I C E S
1313 *
1314 * NOTE: EXPERIMENTAL API
1315 */
1316#if 1 /*KEEP*/
1317#define V4L2_ENC_IDX_FRAME_I (0)
1318#define V4L2_ENC_IDX_FRAME_P (1)
1319#define V4L2_ENC_IDX_FRAME_B (2)
1320#define V4L2_ENC_IDX_FRAME_MASK (0xf)
1321
1322struct <link linkend="v4l2-enc-idx-entry">v4l2_enc_idx_entry</link> {
1323 __u64 offset;
1324 __u64 pts;
1325 __u32 length;
1326 __u32 flags;
1327 __u32 reserved[2];
1328};
1329
1330#define V4L2_ENC_IDX_ENTRIES (64)
1331struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link> {
1332 __u32 entries;
1333 __u32 entries_cap;
1334 __u32 reserved[4];
1335 struct <link linkend="v4l2-enc-idx-entry">v4l2_enc_idx_entry</link> entry[V4L2_ENC_IDX_ENTRIES];
1336};
1337
1338
1339#define V4L2_ENC_CMD_START (0)
1340#define V4L2_ENC_CMD_STOP (1)
1341#define V4L2_ENC_CMD_PAUSE (2)
1342#define V4L2_ENC_CMD_RESUME (3)
1343
1344/* Flags for V4L2_ENC_CMD_STOP */
1345#define V4L2_ENC_CMD_STOP_AT_GOP_END (1 &lt;&lt; 0)
1346
1347struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link> {
1348 __u32 cmd;
1349 __u32 flags;
1350 union {
1351 struct {
1352 __u32 data[8];
1353 } raw;
1354 };
1355};
1356
1357#endif
1358
1359
1360/*
1361 * D A T A S E R V I C E S ( V B I )
1362 *
1363 * Data services API by Michael Schimek
1364 */
1365
1366/* Raw VBI */
1367struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> {
1368 __u32 sampling_rate; /* in 1 Hz */
1369 __u32 offset;
1370 __u32 samples_per_line;
1371 __u32 sample_format; /* V4L2_PIX_FMT_* */
1372 __s32 start[2];
1373 __u32 count[2];
1374 __u32 flags; /* V4L2_VBI_* */
1375 __u32 reserved[2]; /* must be zero */
1376};
1377
1378/* VBI flags */
1379#define V4L2_VBI_UNSYNC (1 &lt;&lt; 0)
1380#define V4L2_VBI_INTERLACED (1 &lt;&lt; 1)
1381
1382/* Sliced VBI
1383 *
1384 * This implements is a proposal V4L2 API to allow SLICED VBI
1385 * required for some hardware encoders. It should change without
1386 * notice in the definitive implementation.
1387 */
1388
1389struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> {
1390 __u16 service_set;
1391 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
1392 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
1393 (equals frame lines 313-336 for 625 line video
1394 standards, 263-286 for 525 line standards) */
1395 __u16 service_lines[2][24];
1396 __u32 io_size;
1397 __u32 reserved[2]; /* must be zero */
1398};
1399
1400/* Teletext World System Teletext
1401 (WST), defined on ITU-R BT.653-2 */
1402#define V4L2_SLICED_TELETEXT_B (0x0001)
1403/* Video Program System, defined on ETS 300 231*/
1404#define V4L2_SLICED_VPS (0x0400)
1405/* Closed Caption, defined on EIA-608 */
1406#define V4L2_SLICED_CAPTION_525 (0x1000)
1407/* Wide Screen System, defined on ITU-R BT1119.1 */
1408#define V4L2_SLICED_WSS_625 (0x4000)
1409
1410#define V4L2_SLICED_VBI_525 (V4L2_SLICED_CAPTION_525)
1411#define V4L2_SLICED_VBI_625 (V4L2_SLICED_TELETEXT_B | V4L2_SLICED_VPS | V4L2_SLICED_WSS_625)
1412
1413struct <link linkend="v4l2-sliced-vbi-cap">v4l2_sliced_vbi_cap</link> {
1414 __u16 service_set;
1415 /* service_lines[0][...] specifies lines 0-23 (1-23 used) of the first field
1416 service_lines[1][...] specifies lines 0-23 (1-23 used) of the second field
1417 (equals frame lines 313-336 for 625 line video
1418 standards, 263-286 for 525 line standards) */
1419 __u16 service_lines[2][24];
1420 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
1421 __u32 reserved[3]; /* must be 0 */
1422};
1423
1424struct <link linkend="v4l2-sliced-vbi-data">v4l2_sliced_vbi_data</link> {
1425 __u32 id;
1426 __u32 field; /* 0: first field, 1: second field */
1427 __u32 line; /* 1-23 */
1428 __u32 reserved; /* must be 0 */
1429 __u8 data[48];
1430};
1431
1432/*
1433 * Sliced VBI data inserted into MPEG Streams
1434 */
1435
1436/*
1437 * V4L2_MPEG_STREAM_VBI_FMT_IVTV:
1438 *
1439 * Structure of payload contained in an MPEG 2 Private Stream 1 PES Packet in an
1440 * MPEG-2 Program Pack that contains V4L2_MPEG_STREAM_VBI_FMT_IVTV Sliced VBI
1441 * data
1442 *
1443 * Note, the MPEG-2 Program Pack and Private Stream 1 PES packet header
1444 * definitions are not included here. See the MPEG-2 specifications for details
1445 * on these headers.
1446 */
1447
1448/* Line type IDs */
1449#define V4L2_MPEG_VBI_IVTV_TELETEXT_B (1)
1450#define V4L2_MPEG_VBI_IVTV_CAPTION_525 (4)
1451#define V4L2_MPEG_VBI_IVTV_WSS_625 (5)
1452#define V4L2_MPEG_VBI_IVTV_VPS (7)
1453
1454struct <link linkend="v4l2-mpeg-vbi-itv0-line">v4l2_mpeg_vbi_itv0_line</link> {
1455 __u8 id; /* One of V4L2_MPEG_VBI_IVTV_* above */
1456 __u8 data[42]; /* Sliced VBI data for the line */
1457} __attribute__ ((packed));
1458
1459struct <link linkend="v4l2-mpeg-vbi-itv0">v4l2_mpeg_vbi_itv0</link> {
1460 __le32 linemask[2]; /* Bitmasks of VBI service lines present */
1461 struct <link linkend="v4l2-mpeg-vbi-itv0-line">v4l2_mpeg_vbi_itv0_line</link> line[35];
1462} __attribute__ ((packed));
1463
1464struct <link linkend="v4l2-mpeg-vbi-itv0-1">v4l2_mpeg_vbi_ITV0</link> {
1465 struct <link linkend="v4l2-mpeg-vbi-itv0-line">v4l2_mpeg_vbi_itv0_line</link> line[36];
1466} __attribute__ ((packed));
1467
1468#define V4L2_MPEG_VBI_IVTV_MAGIC0 "itv0"
1469#define V4L2_MPEG_VBI_IVTV_MAGIC1 "ITV0"
1470
1471struct <link linkend="v4l2-mpeg-vbi-fmt-ivtv">v4l2_mpeg_vbi_fmt_ivtv</link> {
1472 __u8 magic[4];
1473 union {
1474 struct <link linkend="v4l2-mpeg-vbi-itv0">v4l2_mpeg_vbi_itv0</link> itv0;
1475 struct <link linkend="v4l2-mpeg-vbi-itv0-1">v4l2_mpeg_vbi_ITV0</link> ITV0;
1476 };
1477} __attribute__ ((packed));
1478
1479/*
1480 * A G G R E G A T E S T R U C T U R E S
1481 */
1482
1483/* Stream data format
1484 */
1485struct <link linkend="v4l2-format">v4l2_format</link> {
1486 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
1487 union {
1488 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
1489 struct <link linkend="v4l2-window">v4l2_window</link> win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
1490 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
1491 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
1492 __u8 raw_data[200]; /* user-defined */
1493 } fmt;
1494};
1495
1496
1497/* Stream type-dependent parameters
1498 */
1499struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> {
1500 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
1501 union {
1502 struct <link linkend="v4l2-captureparm">v4l2_captureparm</link> capture;
1503 struct <link linkend="v4l2-outputparm">v4l2_outputparm</link> output;
1504 __u8 raw_data[200]; /* user-defined */
1505 } parm;
1506};
1507
1508/*
1509 * A D V A N C E D D E B U G G I N G
1510 *
1511 * NOTE: EXPERIMENTAL API, NEVER RELY ON THIS IN APPLICATIONS!
1512 * FOR DEBUGGING, TESTING AND INTERNAL USE ONLY!
1513 */
1514
1515/* VIDIOC_DBG_G_REGISTER and VIDIOC_DBG_S_REGISTER */
1516
1517#define V4L2_CHIP_MATCH_HOST 0 /* Match against chip ID on host (0 for the host) */
1518#define V4L2_CHIP_MATCH_I2C_DRIVER 1 /* Match against I2C driver name */
1519#define V4L2_CHIP_MATCH_I2C_ADDR 2 /* Match against I2C 7-bit address */
1520#define V4L2_CHIP_MATCH_AC97 3 /* Match against anciliary AC97 chip */
1521
1522struct <link linkend="v4l2-dbg-match">v4l2_dbg_match</link> {
1523 __u32 type; /* Match type */
1524 union { /* Match this chip, meaning determined by type */
1525 __u32 addr;
1526 char name[32];
1527 };
1528} __attribute__ ((packed));
1529
1530struct <link linkend="v4l2-dbg-register">v4l2_dbg_register</link> {
1531 struct <link linkend="v4l2-dbg-match">v4l2_dbg_match</link> match;
1532 __u32 size; /* register size in bytes */
1533 __u64 reg;
1534 __u64 val;
1535} __attribute__ ((packed));
1536
1537/* VIDIOC_DBG_G_CHIP_IDENT */
1538struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
1539 struct <link linkend="v4l2-dbg-match">v4l2_dbg_match</link> match;
1540 __u32 ident; /* chip identifier as specified in &lt;media/v4l2-chip-ident.h&gt; */
1541 __u32 revision; /* chip revision, chip specific */
1542} __attribute__ ((packed));
1543
1544/*
1545 * I O C T L C O D E S F O R V I D E O D E V I C E S
1546 *
1547 */
1548#define VIDIOC_QUERYCAP _IOR('V', 0, struct <link linkend="v4l2-capability">v4l2_capability</link>)
1549#define VIDIOC_RESERVED _IO('V', 1)
1550#define VIDIOC_ENUM_FMT _IOWR('V', 2, struct <link linkend="v4l2-fmtdesc">v4l2_fmtdesc</link>)
1551#define VIDIOC_G_FMT _IOWR('V', 4, struct <link linkend="v4l2-format">v4l2_format</link>)
1552#define VIDIOC_S_FMT _IOWR('V', 5, struct <link linkend="v4l2-format">v4l2_format</link>)
1553#define VIDIOC_REQBUFS _IOWR('V', 8, struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link>)
1554#define VIDIOC_QUERYBUF _IOWR('V', 9, struct <link linkend="v4l2-buffer">v4l2_buffer</link>)
1555#define VIDIOC_G_FBUF _IOR('V', 10, struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link>)
1556#define VIDIOC_S_FBUF _IOW('V', 11, struct <link linkend="v4l2-framebuffer">v4l2_framebuffer</link>)
1557#define VIDIOC_OVERLAY _IOW('V', 14, int)
1558#define VIDIOC_QBUF _IOWR('V', 15, struct <link linkend="v4l2-buffer">v4l2_buffer</link>)
1559#define VIDIOC_DQBUF _IOWR('V', 17, struct <link linkend="v4l2-buffer">v4l2_buffer</link>)
1560#define VIDIOC_STREAMON _IOW('V', 18, int)
1561#define VIDIOC_STREAMOFF _IOW('V', 19, int)
1562#define VIDIOC_G_PARM _IOWR('V', 21, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
1563#define VIDIOC_S_PARM _IOWR('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
1564#define VIDIOC_G_STD _IOR('V', 23, v4l2_std_id)
1565#define VIDIOC_S_STD _IOW('V', 24, v4l2_std_id)
1566#define VIDIOC_ENUMSTD _IOWR('V', 25, struct <link linkend="v4l2-standard">v4l2_standard</link>)
1567#define VIDIOC_ENUMINPUT _IOWR('V', 26, struct <link linkend="v4l2-input">v4l2_input</link>)
1568#define VIDIOC_G_CTRL _IOWR('V', 27, struct <link linkend="v4l2-control">v4l2_control</link>)
1569#define VIDIOC_S_CTRL _IOWR('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
1570#define VIDIOC_G_TUNER _IOWR('V', 29, struct <link linkend="v4l2-tuner">v4l2_tuner</link>)
1571#define VIDIOC_S_TUNER _IOW('V', 30, struct <link linkend="v4l2-tuner">v4l2_tuner</link>)
1572#define VIDIOC_G_AUDIO _IOR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
1573#define VIDIOC_S_AUDIO _IOW('V', 34, struct <link linkend="v4l2-audio">v4l2_audio</link>)
1574#define VIDIOC_QUERYCTRL _IOWR('V', 36, struct <link linkend="v4l2-queryctrl">v4l2_queryctrl</link>)
1575#define VIDIOC_QUERYMENU _IOWR('V', 37, struct <link linkend="v4l2-querymenu">v4l2_querymenu</link>)
1576#define VIDIOC_G_INPUT _IOR('V', 38, int)
1577#define VIDIOC_S_INPUT _IOWR('V', 39, int)
1578#define VIDIOC_G_OUTPUT _IOR('V', 46, int)
1579#define VIDIOC_S_OUTPUT _IOWR('V', 47, int)
1580#define VIDIOC_ENUMOUTPUT _IOWR('V', 48, struct <link linkend="v4l2-output">v4l2_output</link>)
1581#define VIDIOC_G_AUDOUT _IOR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
1582#define VIDIOC_S_AUDOUT _IOW('V', 50, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
1583#define VIDIOC_G_MODULATOR _IOWR('V', 54, struct <link linkend="v4l2-modulator">v4l2_modulator</link>)
1584#define VIDIOC_S_MODULATOR _IOW('V', 55, struct <link linkend="v4l2-modulator">v4l2_modulator</link>)
1585#define VIDIOC_G_FREQUENCY _IOWR('V', 56, struct <link linkend="v4l2-frequency">v4l2_frequency</link>)
1586#define VIDIOC_S_FREQUENCY _IOW('V', 57, struct <link linkend="v4l2-frequency">v4l2_frequency</link>)
1587#define VIDIOC_CROPCAP _IOWR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
1588#define VIDIOC_G_CROP _IOWR('V', 59, struct <link linkend="v4l2-crop">v4l2_crop</link>)
1589#define VIDIOC_S_CROP _IOW('V', 60, struct <link linkend="v4l2-crop">v4l2_crop</link>)
1590#define VIDIOC_G_JPEGCOMP _IOR('V', 61, struct <link linkend="v4l2-jpegcompression">v4l2_jpegcompression</link>)
1591#define VIDIOC_S_JPEGCOMP _IOW('V', 62, struct <link linkend="v4l2-jpegcompression">v4l2_jpegcompression</link>)
1592#define VIDIOC_QUERYSTD _IOR('V', 63, v4l2_std_id)
1593#define VIDIOC_TRY_FMT _IOWR('V', 64, struct <link linkend="v4l2-format">v4l2_format</link>)
1594#define VIDIOC_ENUMAUDIO _IOWR('V', 65, struct <link linkend="v4l2-audio">v4l2_audio</link>)
1595#define VIDIOC_ENUMAUDOUT _IOWR('V', 66, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
1596#define VIDIOC_G_PRIORITY _IOR('V', 67, enum <link linkend="v4l2-priority">v4l2_priority</link>)
1597#define VIDIOC_S_PRIORITY _IOW('V', 68, enum <link linkend="v4l2-priority">v4l2_priority</link>)
1598#define VIDIOC_G_SLICED_VBI_CAP _IOWR('V', 69, struct <link linkend="v4l2-sliced-vbi-cap">v4l2_sliced_vbi_cap</link>)
1599#define VIDIOC_LOG_STATUS _IO('V', 70)
1600#define VIDIOC_G_EXT_CTRLS _IOWR('V', 71, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
1601#define VIDIOC_S_EXT_CTRLS _IOWR('V', 72, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
1602#define VIDIOC_TRY_EXT_CTRLS _IOWR('V', 73, struct <link linkend="v4l2-ext-controls">v4l2_ext_controls</link>)
1603#if 1 /*KEEP*/
1604#define VIDIOC_ENUM_FRAMESIZES _IOWR('V', 74, struct <link linkend="v4l2-frmsizeenum">v4l2_frmsizeenum</link>)
1605#define VIDIOC_ENUM_FRAMEINTERVALS _IOWR('V', 75, struct <link linkend="v4l2-frmivalenum">v4l2_frmivalenum</link>)
1606#define VIDIOC_G_ENC_INDEX _IOR('V', 76, struct <link linkend="v4l2-enc-idx">v4l2_enc_idx</link>)
1607#define VIDIOC_ENCODER_CMD _IOWR('V', 77, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>)
1608#define VIDIOC_TRY_ENCODER_CMD _IOWR('V', 78, struct <link linkend="v4l2-encoder-cmd">v4l2_encoder_cmd</link>)
1609#endif
1610
1611#if 1 /*KEEP*/
1612/* Experimental, meant for debugging, testing and internal use.
1613 Only implemented if CONFIG_VIDEO_ADV_DEBUG is defined.
1614 You must be root to use these ioctls. Never use these in applications! */
1615#define VIDIOC_DBG_S_REGISTER _IOW('V', 79, struct <link linkend="v4l2-dbg-register">v4l2_dbg_register</link>)
1616#define VIDIOC_DBG_G_REGISTER _IOWR('V', 80, struct <link linkend="v4l2-dbg-register">v4l2_dbg_register</link>)
1617
1618/* Experimental, meant for debugging, testing and internal use.
1619 Never use this ioctl in applications! */
1620#define VIDIOC_DBG_G_CHIP_IDENT _IOWR('V', 81, struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link>)
1621#endif
1622
1623#define VIDIOC_S_HW_FREQ_SEEK _IOW('V', 82, struct <link linkend="v4l2-hw-freq-seek">v4l2_hw_freq_seek</link>)
1624/* Reminder: when adding new ioctls please add support for them to
1625 drivers/media/video/v4l2-compat-ioctl32.c as well! */
1626
1627#ifdef __OLD_VIDIOC_
1628/* for compatibility, will go away some day */
1629#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
1630#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
1631#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
1632#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
1633#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
1634#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
1635#endif
1636
1637#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
1638
1639#endif /* __LINUX_VIDEODEV2_H */
1640</programlisting>
diff --git a/Documentation/DocBook/v4l/vidioc-cropcap.xml b/Documentation/DocBook/v4l/vidioc-cropcap.xml
new file mode 100644
index 000000000000..816e90e283c5
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-cropcap.xml
@@ -0,0 +1,174 @@
1<refentry id="vidioc-cropcap">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_CROPCAP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_CROPCAP</refname>
9 <refpurpose>Information about the video cropping and scaling abilities</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_cropcap
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_CROPCAP</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>Applications use this function to query the cropping
53limits, the pixel aspect of images and to calculate scale factors.
54They set the <structfield>type</structfield> field of a v4l2_cropcap
55structure to the respective buffer (stream) type and call the
56<constant>VIDIOC_CROPCAP</constant> ioctl with a pointer to this
57structure. Drivers fill the rest of the structure. The results are
58constant except when switching the video standard. Remember this
59switch can occur implicit when switching the video input or
60output.</para>
61
62 <table pgwide="1" frame="none" id="v4l2-cropcap">
63 <title>struct <structname>v4l2_cropcap</structname></title>
64 <tgroup cols="3">
65 &cs-str;
66 <tbody valign="top">
67 <row>
68 <entry>&v4l2-buf-type;</entry>
69 <entry><structfield>type</structfield></entry>
70 <entry>Type of the data stream, set by the application.
71Only these types are valid here:
72<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
73<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
74<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
75defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
76and higher.</entry>
77 </row>
78 <row>
79 <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
80 <entry><structfield>bounds</structfield></entry>
81 <entry>Defines the window within capturing or output is
82possible, this may exclude for example the horizontal and vertical
83blanking areas. The cropping rectangle cannot exceed these limits.
84Width and height are defined in pixels, the driver writer is free to
85choose origin and units of the coordinate system in the analog
86domain.</entry>
87 </row>
88 <row>
89 <entry>struct <link linkend="v4l2-rect-crop">v4l2_rect</link></entry>
90 <entry><structfield>defrect</structfield></entry>
91 <entry>Default cropping rectangle, it shall cover the
92"whole picture". Assuming pixel aspect 1/1 this could be for example a
93640&nbsp;&times;&nbsp;480 rectangle for NTSC, a
94768&nbsp;&times;&nbsp;576 rectangle for PAL and SECAM centered over
95the active picture area. The same co-ordinate system as for
96 <structfield>bounds</structfield> is used.</entry>
97 </row>
98 <row>
99 <entry>&v4l2-fract;</entry>
100 <entry><structfield>pixelaspect</structfield></entry>
101 <entry><para>This is the pixel aspect (y / x) when no
102scaling is applied, the ratio of the actual sampling
103frequency and the frequency required to get square
104pixels.</para><para>When cropping coordinates refer to square pixels,
105the driver sets <structfield>pixelaspect</structfield> to 1/1. Other
106common values are 54/59 for PAL and SECAM, 11/10 for NTSC sampled
107according to [<xref linkend="itu601" />].</para></entry>
108 </row>
109 </tbody>
110 </tgroup>
111 </table>
112
113 <!-- NB this table is duplicated in the overlay chapter. -->
114
115 <table pgwide="1" frame="none" id="v4l2-rect-crop">
116 <title>struct <structname>v4l2_rect</structname></title>
117 <tgroup cols="3">
118 &cs-str;
119 <tbody valign="top">
120 <row>
121 <entry>__s32</entry>
122 <entry><structfield>left</structfield></entry>
123 <entry>Horizontal offset of the top, left corner of the
124rectangle, in pixels.</entry>
125 </row>
126 <row>
127 <entry>__s32</entry>
128 <entry><structfield>top</structfield></entry>
129 <entry>Vertical offset of the top, left corner of the
130rectangle, in pixels.</entry>
131 </row>
132 <row>
133 <entry>__s32</entry>
134 <entry><structfield>width</structfield></entry>
135 <entry>Width of the rectangle, in pixels.</entry>
136 </row>
137 <row>
138 <entry>__s32</entry>
139 <entry><structfield>height</structfield></entry>
140 <entry>Height of the rectangle, in pixels. Width
141and height cannot be negative, the fields are signed for
142hysterical reasons. <!-- video4linux-list@redhat.com
143on 22 Oct 2002 subject "Re:[V4L][patches!] Re:v4l2/kernel-2.5" -->
144</entry>
145 </row>
146 </tbody>
147 </tgroup>
148 </table>
149 </refsect1>
150
151 <refsect1>
152 &return-value;
153
154 <variablelist>
155 <varlistentry>
156 <term><errorcode>EINVAL</errorcode></term>
157 <listitem>
158 <para>The &v4l2-cropcap; <structfield>type</structfield> is
159invalid or the ioctl is not supported. This is not permitted for
160video capture, output and overlay devices, which must support
161<constant>VIDIOC_CROPCAP</constant>.</para>
162 </listitem>
163 </varlistentry>
164 </variablelist>
165 </refsect1>
166</refentry>
167
168<!--
169Local Variables:
170mode: sgml
171sgml-parent-document: "v4l2.sgml"
172indent-tabs-mode: nil
173End:
174-->
diff --git a/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml b/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
new file mode 100644
index 000000000000..4a09e203af0f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-dbg-g-chip-ident.xml
@@ -0,0 +1,275 @@
1<refentry id="vidioc-dbg-g-chip-ident">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_DBG_G_CHIP_IDENT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_DBG_G_CHIP_IDENT</refname>
9 <refpurpose>Identify the chips on a TV card</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_dbg_chip_ident
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_DBG_G_CHIP_IDENT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54
55 <para>This is an <link
56linkend="experimental">experimental</link> interface and may change in
57the future.</para>
58 </note>
59
60 <para>For driver debugging purposes this ioctl allows test
61applications to query the driver about the chips present on the TV
62card. Regular applications must not use it. When you found a chip
63specific bug, please contact the linux-media mailing list (&v4l-ml;)
64so it can be fixed.</para>
65
66 <para>To query the driver applications must initialize the
67<structfield>match.type</structfield> and
68<structfield>match.addr</structfield> or <structfield>match.name</structfield>
69fields of a &v4l2-dbg-chip-ident;
70and call <constant>VIDIOC_DBG_G_CHIP_IDENT</constant> with a pointer to
71this structure. On success the driver stores information about the
72selected chip in the <structfield>ident</structfield> and
73<structfield>revision</structfield> fields. On failure the structure
74remains unchanged.</para>
75
76 <para>When <structfield>match.type</structfield> is
77<constant>V4L2_CHIP_MATCH_HOST</constant>,
78<structfield>match.addr</structfield> selects the nth non-&i2c; chip
79on the TV card. You can enumerate all chips by starting at zero and
80incrementing <structfield>match.addr</structfield> by one until
81<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.
82The number zero always selects the host chip, &eg; the chip connected
83to the PCI or USB bus.</para>
84
85 <para>When <structfield>match.type</structfield> is
86<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
87<structfield>match.name</structfield> contains the I2C driver name.
88For instance
89<constant>"saa7127"</constant> will match any chip
90supported by the saa7127 driver, regardless of its &i2c; bus address.
91When multiple chips supported by the same driver are present, the
92ioctl will return <constant>V4L2_IDENT_AMBIGUOUS</constant> in the
93<structfield>ident</structfield> field.</para>
94
95 <para>When <structfield>match.type</structfield> is
96<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
97<structfield>match.addr</structfield> selects a chip by its 7 bit
98&i2c; bus address.</para>
99
100 <para>When <structfield>match.type</structfield> is
101<constant>V4L2_CHIP_MATCH_AC97</constant>,
102<structfield>match.addr</structfield> selects the nth AC97 chip
103on the TV card. You can enumerate all chips by starting at zero and
104incrementing <structfield>match.addr</structfield> by one until
105<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> fails with an &EINVAL;.</para>
106
107 <para>On success, the <structfield>ident</structfield> field will
108contain a chip ID from the Linux
109<filename>media/v4l2-chip-ident.h</filename> header file, and the
110<structfield>revision</structfield> field will contain a driver
111specific value, or zero if no particular revision is associated with
112this chip.</para>
113
114 <para>When the driver could not identify the selected chip,
115<structfield>ident</structfield> will contain
116<constant>V4L2_IDENT_UNKNOWN</constant>. When no chip matched
117the ioctl will succeed but the
118<structfield>ident</structfield> field will contain
119<constant>V4L2_IDENT_NONE</constant>. If multiple chips matched,
120<structfield>ident</structfield> will contain
121<constant>V4L2_IDENT_AMBIGUOUS</constant>. In all these cases the
122<structfield>revision</structfield> field remains unchanged.</para>
123
124 <para>This ioctl is optional, not all drivers may support it. It
125was introduced in Linux 2.6.21, but the API was changed to the
126one described here in 2.6.29.</para>
127
128 <para>We recommended the <application>v4l2-dbg</application>
129utility over calling this ioctl directly. It is available from the
130LinuxTV v4l-dvb repository; see <ulink
131url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
132access instructions.</para>
133
134 <!-- Note for convenience vidioc-dbg-g-register.sgml
135 contains a duplicate of this table. -->
136 <table pgwide="1" frame="none" id="ident-v4l2-dbg-match">
137 <title>struct <structname>v4l2_dbg_match</structname></title>
138 <tgroup cols="4">
139 &cs-ustr;
140 <tbody valign="top">
141 <row>
142 <entry>__u32</entry>
143 <entry><structfield>type</structfield></entry>
144 <entry>See <xref linkend="ident-chip-match-types" /> for a list of
145possible types.</entry>
146 </row>
147 <row>
148 <entry>union</entry>
149 <entry>(anonymous)</entry>
150 </row>
151 <row>
152 <entry></entry>
153 <entry>__u32</entry>
154 <entry><structfield>addr</structfield></entry>
155 <entry>Match a chip by this number, interpreted according
156to the <structfield>type</structfield> field.</entry>
157 </row>
158 <row>
159 <entry></entry>
160 <entry>char</entry>
161 <entry><structfield>name[32]</structfield></entry>
162 <entry>Match a chip by this name, interpreted according
163to the <structfield>type</structfield> field.</entry>
164 </row>
165 </tbody>
166 </tgroup>
167 </table>
168
169 <table pgwide="1" frame="none" id="v4l2-dbg-chip-ident">
170 <title>struct <structname>v4l2_dbg_chip_ident</structname></title>
171 <tgroup cols="3">
172 &cs-str;
173 <tbody valign="top">
174 <row>
175 <entry>struct v4l2_dbg_match</entry>
176 <entry><structfield>match</structfield></entry>
177 <entry>How to match the chip, see <xref linkend="ident-v4l2-dbg-match" />.</entry>
178 </row>
179 <row>
180 <entry>__u32</entry>
181 <entry><structfield>ident</structfield></entry>
182 <entry>A chip identifier as defined in the Linux
183<filename>media/v4l2-chip-ident.h</filename> header file, or one of
184the values from <xref linkend="chip-ids" />.</entry>
185 </row>
186 <row>
187 <entry>__u32</entry>
188 <entry><structfield>revision</structfield></entry>
189 <entry>A chip revision, chip and driver specific.</entry>
190 </row>
191 </tbody>
192 </tgroup>
193 </table>
194
195 <!-- Note for convenience vidioc-dbg-g-register.sgml
196 contains a duplicate of this table. -->
197 <table pgwide="1" frame="none" id="ident-chip-match-types">
198 <title>Chip Match Types</title>
199 <tgroup cols="3">
200 &cs-def;
201 <tbody valign="top">
202 <row>
203 <entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
204 <entry>0</entry>
205 <entry>Match the nth chip on the card, zero for the
206 host chip. Does not match &i2c; chips.</entry>
207 </row>
208 <row>
209 <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
210 <entry>1</entry>
211 <entry>Match an &i2c; chip by its driver name.</entry>
212 </row>
213 <row>
214 <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
215 <entry>2</entry>
216 <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
217 </row>
218 <row>
219 <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
220 <entry>3</entry>
221 <entry>Match the nth anciliary AC97 chip.</entry>
222 </row>
223 </tbody>
224 </tgroup>
225 </table>
226
227 <!-- This is an anonymous enum in media/v4l2-chip-ident.h. -->
228 <table pgwide="1" frame="none" id="chip-ids">
229 <title>Chip Identifiers</title>
230 <tgroup cols="3">
231 &cs-def;
232 <tbody valign="top">
233 <row>
234 <entry><constant>V4L2_IDENT_NONE</constant></entry>
235 <entry>0</entry>
236 <entry>No chip matched.</entry>
237 </row>
238 <row>
239 <entry><constant>V4L2_IDENT_AMBIGUOUS</constant></entry>
240 <entry>1</entry>
241 <entry>Multiple chips matched.</entry>
242 </row>
243 <row>
244 <entry><constant>V4L2_IDENT_UNKNOWN</constant></entry>
245 <entry>2</entry>
246 <entry>A chip is present at this address, but the driver
247could not identify it.</entry>
248 </row>
249 </tbody>
250 </tgroup>
251 </table>
252 </refsect1>
253
254 <refsect1>
255 &return-value;
256
257 <variablelist>
258 <varlistentry>
259 <term><errorcode>EINVAL</errorcode></term>
260 <listitem>
261 <para>The driver does not support this ioctl, or the
262<structfield>match_type</structfield> is invalid.</para>
263 </listitem>
264 </varlistentry>
265 </variablelist>
266 </refsect1>
267</refentry>
268
269<!--
270Local Variables:
271mode: sgml
272sgml-parent-document: "v4l2.sgml"
273indent-tabs-mode: nil
274End:
275-->
diff --git a/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml b/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml
new file mode 100644
index 000000000000..980c7f3e2fd6
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-dbg-g-register.xml
@@ -0,0 +1,275 @@
1<refentry id="vidioc-dbg-g-register">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_DBG_G_REGISTER</refname>
9 <refname>VIDIOC_DBG_S_REGISTER</refname>
10 <refpurpose>Read or write hardware registers</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_dbg_register *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>const struct v4l2_dbg_register
28*<parameter>argp</parameter></paramdef>
29 </funcprototype>
30 </funcsynopsis>
31 </refsynopsisdiv>
32
33 <refsect1>
34 <title>Arguments</title>
35
36 <variablelist>
37 <varlistentry>
38 <term><parameter>fd</parameter></term>
39 <listitem>
40 <para>&fd;</para>
41 </listitem>
42 </varlistentry>
43 <varlistentry>
44 <term><parameter>request</parameter></term>
45 <listitem>
46 <para>VIDIOC_DBG_G_REGISTER, VIDIOC_DBG_S_REGISTER</para>
47 </listitem>
48 </varlistentry>
49 <varlistentry>
50 <term><parameter>argp</parameter></term>
51 <listitem>
52 <para></para>
53 </listitem>
54 </varlistentry>
55 </variablelist>
56 </refsect1>
57
58 <refsect1>
59 <title>Description</title>
60
61 <note>
62 <title>Experimental</title>
63
64 <para>This is an <link linkend="experimental">experimental</link>
65interface and may change in the future.</para>
66 </note>
67
68 <para>For driver debugging purposes these ioctls allow test
69applications to access hardware registers directly. Regular
70applications must not use them.</para>
71
72 <para>Since writing or even reading registers can jeopardize the
73system security, its stability and damage the hardware, both ioctls
74require superuser privileges. Additionally the Linux kernel must be
75compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant> option
76to enable these ioctls.</para>
77
78 <para>To write a register applications must initialize all fields
79of a &v4l2-dbg-register; and call
80<constant>VIDIOC_DBG_S_REGISTER</constant> with a pointer to this
81structure. The <structfield>match.type</structfield> and
82<structfield>match.addr</structfield> or <structfield>match.name</structfield>
83fields select a chip on the TV
84card, the <structfield>reg</structfield> field specifies a register
85number and the <structfield>val</structfield> field the value to be
86written into the register.</para>
87
88 <para>To read a register applications must initialize the
89<structfield>match.type</structfield>,
90<structfield>match.chip</structfield> or <structfield>match.name</structfield> and
91<structfield>reg</structfield> fields, and call
92<constant>VIDIOC_DBG_G_REGISTER</constant> with a pointer to this
93structure. On success the driver stores the register value in the
94<structfield>val</structfield> field. On failure the structure remains
95unchanged.</para>
96
97 <para>When <structfield>match.type</structfield> is
98<constant>V4L2_CHIP_MATCH_HOST</constant>,
99<structfield>match.addr</structfield> selects the nth non-&i2c; chip
100on the TV card. The number zero always selects the host chip, &eg; the
101chip connected to the PCI or USB bus. You can find out which chips are
102present with the &VIDIOC-DBG-G-CHIP-IDENT; ioctl.</para>
103
104 <para>When <structfield>match.type</structfield> is
105<constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant>,
106<structfield>match.name</structfield> contains the I2C driver name.
107For instance
108<constant>"saa7127"</constant> will match any chip
109supported by the saa7127 driver, regardless of its &i2c; bus address.
110When multiple chips supported by the same driver are present, the
111effect of these ioctls is undefined. Again with the
112&VIDIOC-DBG-G-CHIP-IDENT; ioctl you can find out which &i2c; chips are
113present.</para>
114
115 <para>When <structfield>match.type</structfield> is
116<constant>V4L2_CHIP_MATCH_I2C_ADDR</constant>,
117<structfield>match.addr</structfield> selects a chip by its 7 bit &i2c;
118bus address.</para>
119
120 <para>When <structfield>match.type</structfield> is
121<constant>V4L2_CHIP_MATCH_AC97</constant>,
122<structfield>match.addr</structfield> selects the nth AC97 chip
123on the TV card.</para>
124
125 <note>
126 <title>Success not guaranteed</title>
127
128 <para>Due to a flaw in the Linux &i2c; bus driver these ioctls may
129return successfully without actually reading or writing a register. To
130catch the most likely failure we recommend a &VIDIOC-DBG-G-CHIP-IDENT;
131call confirming the presence of the selected &i2c; chip.</para>
132 </note>
133
134 <para>These ioctls are optional, not all drivers may support them.
135However when a driver supports these ioctls it must also support
136&VIDIOC-DBG-G-CHIP-IDENT;. Conversely it may support
137<constant>VIDIOC_DBG_G_CHIP_IDENT</constant> but not these ioctls.</para>
138
139 <para><constant>VIDIOC_DBG_G_REGISTER</constant> and
140<constant>VIDIOC_DBG_S_REGISTER</constant> were introduced in Linux
1412.6.21, but their API was changed to the one described here in kernel 2.6.29.</para>
142
143 <para>We recommended the <application>v4l2-dbg</application>
144utility over calling these ioctls directly. It is available from the
145LinuxTV v4l-dvb repository; see <ulink
146url="http://linuxtv.org/repo/">http://linuxtv.org/repo/</ulink> for
147access instructions.</para>
148
149 <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
150 contains a duplicate of this table. -->
151 <table pgwide="1" frame="none" id="v4l2-dbg-match">
152 <title>struct <structname>v4l2_dbg_match</structname></title>
153 <tgroup cols="4">
154 &cs-ustr;
155 <tbody valign="top">
156 <row>
157 <entry>__u32</entry>
158 <entry><structfield>type</structfield></entry>
159 <entry>See <xref linkend="ident-chip-match-types" /> for a list of
160possible types.</entry>
161 </row>
162 <row>
163 <entry>union</entry>
164 <entry>(anonymous)</entry>
165 </row>
166 <row>
167 <entry></entry>
168 <entry>__u32</entry>
169 <entry><structfield>addr</structfield></entry>
170 <entry>Match a chip by this number, interpreted according
171to the <structfield>type</structfield> field.</entry>
172 </row>
173 <row>
174 <entry></entry>
175 <entry>char</entry>
176 <entry><structfield>name[32]</structfield></entry>
177 <entry>Match a chip by this name, interpreted according
178to the <structfield>type</structfield> field.</entry>
179 </row>
180 </tbody>
181 </tgroup>
182 </table>
183
184
185 <table pgwide="1" frame="none" id="v4l2-dbg-register">
186 <title>struct <structname>v4l2_dbg_register</structname></title>
187 <tgroup cols="4">
188 <colspec colname="c1" />
189 <colspec colname="c2" />
190 <colspec colname="c4" />
191 <tbody valign="top">
192 <row>
193 <entry>struct v4l2_dbg_match</entry>
194 <entry><structfield>match</structfield></entry>
195 <entry>How to match the chip, see <xref linkend="v4l2-dbg-match" />.</entry>
196 </row>
197 <row>
198 <entry>__u64</entry>
199 <entry><structfield>reg</structfield></entry>
200 <entry>A register number.</entry>
201 </row>
202 <row>
203 <entry>__u64</entry>
204 <entry><structfield>val</structfield></entry>
205 <entry>The value read from, or to be written into the
206register.</entry>
207 </row>
208 </tbody>
209 </tgroup>
210 </table>
211
212 <!-- Note for convenience vidioc-dbg-g-chip-ident.sgml
213 contains a duplicate of this table. -->
214 <table pgwide="1" frame="none" id="chip-match-types">
215 <title>Chip Match Types</title>
216 <tgroup cols="3">
217 &cs-def;
218 <tbody valign="top">
219 <row>
220 <entry><constant>V4L2_CHIP_MATCH_HOST</constant></entry>
221 <entry>0</entry>
222 <entry>Match the nth chip on the card, zero for the
223 host chip. Does not match &i2c; chips.</entry>
224 </row>
225 <row>
226 <entry><constant>V4L2_CHIP_MATCH_I2C_DRIVER</constant></entry>
227 <entry>1</entry>
228 <entry>Match an &i2c; chip by its driver name.</entry>
229 </row>
230 <row>
231 <entry><constant>V4L2_CHIP_MATCH_I2C_ADDR</constant></entry>
232 <entry>2</entry>
233 <entry>Match a chip by its 7 bit &i2c; bus address.</entry>
234 </row>
235 <row>
236 <entry><constant>V4L2_CHIP_MATCH_AC97</constant></entry>
237 <entry>3</entry>
238 <entry>Match the nth anciliary AC97 chip.</entry>
239 </row>
240 </tbody>
241 </tgroup>
242 </table>
243 </refsect1>
244
245 <refsect1>
246 &return-value;
247
248 <variablelist>
249 <varlistentry>
250 <term><errorcode>EINVAL</errorcode></term>
251 <listitem>
252 <para>The driver does not support this ioctl, or the kernel
253was not compiled with the <constant>CONFIG_VIDEO_ADV_DEBUG</constant>
254option, or the <structfield>match_type</structfield> is invalid, or the
255selected chip or register does not exist.</para>
256 </listitem>
257 </varlistentry>
258 <varlistentry>
259 <term><errorcode>EPERM</errorcode></term>
260 <listitem>
261 <para>Insufficient permissions. Root privileges are required
262to execute these ioctls.</para>
263 </listitem>
264 </varlistentry>
265 </variablelist>
266 </refsect1>
267</refentry>
268
269<!--
270Local Variables:
271mode: sgml
272sgml-parent-document: "v4l2.sgml"
273indent-tabs-mode: nil
274End:
275-->
diff --git a/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml b/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml
new file mode 100644
index 000000000000..b0dde943825c
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-encoder-cmd.xml
@@ -0,0 +1,204 @@
1<refentry id="vidioc-encoder-cmd">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENCODER_CMD</refname>
9 <refname>VIDIOC_TRY_ENCODER_CMD</refname>
10 <refpurpose>Execute an encoder command</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_encoder_cmd *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_ENCODER_CMD, VIDIOC_TRY_ENCODER_CMD</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <note>
53 <title>Experimental</title>
54
55 <para>This is an <link linkend="experimental">experimental</link>
56interface and may change in the future.</para>
57 </note>
58
59 <para>These ioctls control an audio/video (usually MPEG-) encoder.
60<constant>VIDIOC_ENCODER_CMD</constant> sends a command to the
61encoder, <constant>VIDIOC_TRY_ENCODER_CMD</constant> can be used to
62try a command without actually executing it.</para>
63
64 <para>To send a command applications must initialize all fields of a
65 &v4l2-encoder-cmd; and call
66 <constant>VIDIOC_ENCODER_CMD</constant> or
67 <constant>VIDIOC_TRY_ENCODER_CMD</constant> with a pointer to this
68 structure.</para>
69
70 <para>The <structfield>cmd</structfield> field must contain the
71command code. The <structfield>flags</structfield> field is currently
72only used by the STOP command and contains one bit: If the
73<constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant> flag is set,
74encoding will continue until the end of the current <wordasword>Group
75Of Pictures</wordasword>, otherwise it will stop immediately.</para>
76
77 <para>A <function>read</function>() call sends a START command to
78the encoder if it has not been started yet. After a STOP command,
79<function>read</function>() calls will read the remaining data
80buffered by the driver. When the buffer is empty,
81<function>read</function>() will return zero and the next
82<function>read</function>() call will restart the encoder.</para>
83
84 <para>A <function>close</function>() call sends an immediate STOP
85to the encoder, and all buffered data is discarded.</para>
86
87 <para>These ioctls are optional, not all drivers may support
88them. They were introduced in Linux 2.6.21.</para>
89
90 <table pgwide="1" frame="none" id="v4l2-encoder-cmd">
91 <title>struct <structname>v4l2_encoder_cmd</structname></title>
92 <tgroup cols="3">
93 &cs-str;
94 <tbody valign="top">
95 <row>
96 <entry>__u32</entry>
97 <entry><structfield>cmd</structfield></entry>
98 <entry>The encoder command, see <xref linkend="encoder-cmds" />.</entry>
99 </row>
100 <row>
101 <entry>__u32</entry>
102 <entry><structfield>flags</structfield></entry>
103 <entry>Flags to go with the command, see <xref
104 linkend="encoder-flags" />. If no flags are defined for
105this command, drivers and applications must set this field to
106zero.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>data</structfield>[8]</entry>
111 <entry>Reserved for future extensions. Drivers and
112applications must set the array to zero.</entry>
113 </row>
114 </tbody>
115 </tgroup>
116 </table>
117
118 <table pgwide="1" frame="none" id="encoder-cmds">
119 <title>Encoder Commands</title>
120 <tgroup cols="3">
121 &cs-def;
122 <tbody valign="top">
123 <row>
124 <entry><constant>V4L2_ENC_CMD_START</constant></entry>
125 <entry>0</entry>
126 <entry>Start the encoder. When the encoder is already
127running or paused, this command does nothing. No flags are defined for
128this command.</entry>
129 </row>
130 <row>
131 <entry><constant>V4L2_ENC_CMD_STOP</constant></entry>
132 <entry>1</entry>
133 <entry>Stop the encoder. When the
134<constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant> flag is set,
135encoding will continue until the end of the current <wordasword>Group
136Of Pictures</wordasword>, otherwise encoding will stop immediately.
137When the encoder is already stopped, this command does
138nothing.</entry>
139 </row>
140 <row>
141 <entry><constant>V4L2_ENC_CMD_PAUSE</constant></entry>
142 <entry>2</entry>
143 <entry>Pause the encoder. When the encoder has not been
144started yet, the driver will return an &EPERM;. When the encoder is
145already paused, this command does nothing. No flags are defined for
146this command.</entry>
147 </row>
148 <row>
149 <entry><constant>V4L2_ENC_CMD_RESUME</constant></entry>
150 <entry>3</entry>
151 <entry>Resume encoding after a PAUSE command. When the
152encoder has not been started yet, the driver will return an &EPERM;.
153When the encoder is already running, this command does nothing. No
154flags are defined for this command.</entry>
155 </row>
156 </tbody>
157 </tgroup>
158 </table>
159
160 <table pgwide="1" frame="none" id="encoder-flags">
161 <title>Encoder Command Flags</title>
162 <tgroup cols="3">
163 &cs-def;
164 <tbody valign="top">
165 <row>
166 <entry><constant>V4L2_ENC_CMD_STOP_AT_GOP_END</constant></entry>
167 <entry>0x0001</entry>
168 <entry>Stop encoding at the end of the current <wordasword>Group Of
169Pictures</wordasword>, rather than immediately.</entry>
170 </row>
171 </tbody>
172 </tgroup>
173 </table>
174 </refsect1>
175
176 <refsect1>
177 &return-value;
178
179 <variablelist>
180 <varlistentry>
181 <term><errorcode>EINVAL</errorcode></term>
182 <listitem>
183 <para>The driver does not support this ioctl, or the
184<structfield>cmd</structfield> field is invalid.</para>
185 </listitem>
186 </varlistentry>
187 <varlistentry>
188 <term><errorcode>EPERM</errorcode></term>
189 <listitem>
190 <para>The application sent a PAUSE or RESUME command when
191the encoder was not running.</para>
192 </listitem>
193 </varlistentry>
194 </variablelist>
195 </refsect1>
196</refentry>
197
198<!--
199Local Variables:
200mode: sgml
201sgml-parent-document: "v4l2.sgml"
202indent-tabs-mode: nil
203End:
204-->
diff --git a/Documentation/DocBook/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
new file mode 100644
index 000000000000..960d44615ca6
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
@@ -0,0 +1,164 @@
1<refentry id="vidioc-enum-fmt">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUM_FMT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUM_FMT</refname>
9 <refpurpose>Enumerate image formats</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_fmtdesc
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_ENUM_FMT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>To enumerate image formats applications initialize the
53<structfield>type</structfield> and <structfield>index</structfield>
54field of &v4l2-fmtdesc; and call the
55<constant>VIDIOC_ENUM_FMT</constant> ioctl with a pointer to this
56structure. Drivers fill the rest of the structure or return an
57&EINVAL;. All formats are enumerable by beginning at index zero and
58incrementing by one until <errorcode>EINVAL</errorcode> is
59returned.</para>
60
61 <table pgwide="1" frame="none" id="v4l2-fmtdesc">
62 <title>struct <structname>v4l2_fmtdesc</structname></title>
63 <tgroup cols="3">
64 &cs-str;
65 <tbody valign="top">
66 <row>
67 <entry>__u32</entry>
68 <entry><structfield>index</structfield></entry>
69 <entry>Number of the format in the enumeration, set by
70the application. This is in no way related to the <structfield>
71pixelformat</structfield> field.</entry>
72 </row>
73 <row>
74 <entry>&v4l2-buf-type;</entry>
75 <entry><structfield>type</structfield></entry>
76 <entry>Type of the data stream, set by the application.
77Only these types are valid here:
78<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
79<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
80<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
81defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
82and higher.</entry>
83 </row>
84 <row>
85 <entry>__u32</entry>
86 <entry><structfield>flags</structfield></entry>
87 <entry>See <xref linkend="fmtdesc-flags" /></entry>
88 </row>
89 <row>
90 <entry>__u8</entry>
91 <entry><structfield>description</structfield>[32]</entry>
92 <entry>Description of the format, a NUL-terminated ASCII
93string. This information is intended for the user, for example: "YUV
944:2:2".</entry>
95 </row>
96 <row>
97 <entry>__u32</entry>
98 <entry><structfield>pixelformat</structfield></entry>
99 <entry>The image format identifier. This is a
100four character code as computed by the v4l2_fourcc()
101macro:</entry>
102 </row>
103 <row>
104 <entry spanname="hspan"><para><programlisting id="v4l2-fourcc">
105#define v4l2_fourcc(a,b,c,d) (((__u32)(a)&lt;&lt;0)|((__u32)(b)&lt;&lt;8)|((__u32)(c)&lt;&lt;16)|((__u32)(d)&lt;&lt;24))
106</programlisting></para><para>Several image formats are already
107defined by this specification in <xref linkend="pixfmt" />. Note these
108codes are not the same as those used in the Windows world.</para></entry>
109 </row>
110 <row>
111 <entry>__u32</entry>
112 <entry><structfield>reserved</structfield>[4]</entry>
113 <entry>Reserved for future extensions. Drivers must set
114the array to zero.</entry>
115 </row>
116 </tbody>
117 </tgroup>
118 </table>
119
120 <table pgwide="1" frame="none" id="fmtdesc-flags">
121 <title>Image Format Description Flags</title>
122 <tgroup cols="3">
123 &cs-def;
124 <tbody valign="top">
125 <row>
126 <entry><constant>V4L2_FMT_FLAG_COMPRESSED</constant></entry>
127 <entry>0x0001</entry>
128 <entry>This is a compressed format.</entry>
129 </row>
130 <row>
131 <entry><constant>V4L2_FMT_FLAG_EMULATED</constant></entry>
132 <entry>0x0002</entry>
133 <entry>This format is not native to the device but emulated
134through software (usually libv4l2), where possible try to use a native format
135instead for better performance.</entry>
136 </row>
137 </tbody>
138 </tgroup>
139 </table>
140 </refsect1>
141
142 <refsect1>
143 &return-value;
144
145 <variablelist>
146 <varlistentry>
147 <term><errorcode>EINVAL</errorcode></term>
148 <listitem>
149 <para>The &v4l2-fmtdesc; <structfield>type</structfield>
150is not supported or the <structfield>index</structfield> is out of
151bounds.</para>
152 </listitem>
153 </varlistentry>
154 </variablelist>
155 </refsect1>
156</refentry>
157
158<!--
159Local Variables:
160mode: sgml
161sgml-parent-document: "v4l2.sgml"
162indent-tabs-mode: nil
163End:
164-->
diff --git a/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml b/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml
new file mode 100644
index 000000000000..3c216e113a54
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enum-frameintervals.xml
@@ -0,0 +1,270 @@
1<refentry id="vidioc-enum-frameintervals">
2
3 <refmeta>
4 <refentrytitle>ioctl VIDIOC_ENUM_FRAMEINTERVALS</refentrytitle>
5 &manvol;
6 </refmeta>
7
8 <refnamediv>
9 <refname>VIDIOC_ENUM_FRAMEINTERVALS</refname>
10 <refpurpose>Enumerate frame intervals</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_frmivalenum *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_ENUM_FRAMEINTERVALS</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para>Pointer to a &v4l2-frmivalenum; structure that
44contains a pixel format and size and receives a frame interval.</para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52
53 <para>This ioctl allows applications to enumerate all frame
54intervals that the device supports for the given pixel format and
55frame size.</para>
56 <para>The supported pixel formats and frame sizes can be obtained
57by using the &VIDIOC-ENUM-FMT; and &VIDIOC-ENUM-FRAMESIZES;
58functions.</para>
59 <para>The return value and the content of the
60<structfield>v4l2_frmivalenum.type</structfield> field depend on the
61type of frame intervals the device supports. Here are the semantics of
62the function for the different cases:</para>
63 <itemizedlist>
64 <listitem>
65 <para><emphasis role="bold">Discrete:</emphasis> The function
66returns success if the given index value (zero-based) is valid. The
67application should increase the index by one for each call until
68<constant>EINVAL</constant> is returned. The `v4l2_frmivalenum.type`
69field is set to `V4L2_FRMIVAL_TYPE_DISCRETE` by the driver. Of the
70union only the `discrete` member is valid.</para>
71 </listitem>
72 <listitem>
73 <para><emphasis role="bold">Step-wise:</emphasis> The function
74returns success if the given index value is zero and
75<constant>EINVAL</constant> for any other index value. The
76<structfield>v4l2_frmivalenum.type</structfield> field is set to
77<constant>V4L2_FRMIVAL_TYPE_STEPWISE</constant> by the driver. Of the
78union only the <structfield>stepwise</structfield> member is
79valid.</para>
80 </listitem>
81 <listitem>
82 <para><emphasis role="bold">Continuous:</emphasis> This is a
83special case of the step-wise type above. The function returns success
84if the given index value is zero and <constant>EINVAL</constant> for
85any other index value. The
86<structfield>v4l2_frmivalenum.type</structfield> field is set to
87<constant>V4L2_FRMIVAL_TYPE_CONTINUOUS</constant> by the driver. Of
88the union only the <structfield>stepwise</structfield> member is valid
89and the <structfield>step</structfield> value is set to 1.</para>
90 </listitem>
91 </itemizedlist>
92
93 <para>When the application calls the function with index zero, it
94must check the <structfield>type</structfield> field to determine the
95type of frame interval enumeration the device supports. Only for the
96<constant>V4L2_FRMIVAL_TYPE_DISCRETE</constant> type does it make
97sense to increase the index value to receive more frame
98intervals.</para>
99 <para>Note that the order in which the frame intervals are
100returned has no special meaning. In particular does it not say
101anything about potential default frame intervals.</para>
102 <para>Applications can assume that the enumeration data does not
103change without any interaction from the application itself. This means
104that the enumeration data is consistent if the application does not
105perform any other ioctl calls while it runs the frame interval
106enumeration.</para>
107 </refsect1>
108
109 <refsect1>
110 <title>Notes</title>
111
112 <itemizedlist>
113 <listitem>
114 <para><emphasis role="bold">Frame intervals and frame
115rates:</emphasis> The V4L2 API uses frame intervals instead of frame
116rates. Given the frame interval the frame rate can be computed as
117follows:<screen>frame_rate = 1 / frame_interval</screen></para>
118 </listitem>
119 </itemizedlist>
120
121 </refsect1>
122
123 <refsect1>
124 <title>Structs</title>
125
126 <para>In the structs below, <emphasis>IN</emphasis> denotes a
127value that has to be filled in by the application,
128<emphasis>OUT</emphasis> denotes values that the driver fills in. The
129application should zero out all members except for the
130<emphasis>IN</emphasis> fields.</para>
131
132 <table pgwide="1" frame="none" id="v4l2-frmival-stepwise">
133 <title>struct <structname>v4l2_frmival_stepwise</structname></title>
134 <tgroup cols="3">
135 &cs-str;
136 <tbody valign="top">
137 <row>
138 <entry>&v4l2-fract;</entry>
139 <entry><structfield>min</structfield></entry>
140 <entry>Minimum frame interval [s].</entry>
141 </row>
142 <row>
143 <entry>&v4l2-fract;</entry>
144 <entry><structfield>max</structfield></entry>
145 <entry>Maximum frame interval [s].</entry>
146 </row>
147 <row>
148 <entry>&v4l2-fract;</entry>
149 <entry><structfield>step</structfield></entry>
150 <entry>Frame interval step size [s].</entry>
151 </row>
152 </tbody>
153 </tgroup>
154 </table>
155
156 <table pgwide="1" frame="none" id="v4l2-frmivalenum">
157 <title>struct <structname>v4l2_frmivalenum</structname></title>
158 <tgroup cols="4">
159 <colspec colname="c1" />
160 <colspec colname="c2" />
161 <colspec colname="c3" />
162 <colspec colname="c4" />
163 <tbody valign="top">
164 <row>
165 <entry>__u32</entry>
166 <entry><structfield>index</structfield></entry>
167 <entry></entry>
168 <entry>IN: Index of the given frame interval in the
169enumeration.</entry>
170 </row>
171 <row>
172 <entry>__u32</entry>
173 <entry><structfield>pixel_format</structfield></entry>
174 <entry></entry>
175 <entry>IN: Pixel format for which the frame intervals are
176enumerated.</entry>
177 </row>
178 <row>
179 <entry>__u32</entry>
180 <entry><structfield>width</structfield></entry>
181 <entry></entry>
182 <entry>IN: Frame width for which the frame intervals are
183enumerated.</entry>
184 </row>
185 <row>
186 <entry>__u32</entry>
187 <entry><structfield>height</structfield></entry>
188 <entry></entry>
189 <entry>IN: Frame height for which the frame intervals are
190enumerated.</entry>
191 </row>
192 <row>
193 <entry>__u32</entry>
194 <entry><structfield>type</structfield></entry>
195 <entry></entry>
196 <entry>OUT: Frame interval type the device supports.</entry>
197 </row>
198 <row>
199 <entry>union</entry>
200 <entry></entry>
201 <entry></entry>
202 <entry>OUT: Frame interval with the given index.</entry>
203 </row>
204 <row>
205 <entry></entry>
206 <entry>&v4l2-fract;</entry>
207 <entry><structfield>discrete</structfield></entry>
208 <entry>Frame interval [s].</entry>
209 </row>
210 <row>
211 <entry></entry>
212 <entry>&v4l2-frmival-stepwise;</entry>
213 <entry><structfield>stepwise</structfield></entry>
214 <entry></entry>
215 </row>
216 <row>
217 <entry>__u32</entry>
218 <entry><structfield>reserved[2]</structfield></entry>
219 <entry></entry>
220 <entry>Reserved space for future use.</entry>
221 </row>
222 </tbody>
223 </tgroup>
224 </table>
225 </refsect1>
226
227 <refsect1>
228 <title>Enums</title>
229
230 <table pgwide="1" frame="none" id="v4l2-frmivaltypes">
231 <title>enum <structname>v4l2_frmivaltypes</structname></title>
232 <tgroup cols="3">
233 &cs-def;
234 <tbody valign="top">
235 <row>
236 <entry><constant>V4L2_FRMIVAL_TYPE_DISCRETE</constant></entry>
237 <entry>1</entry>
238 <entry>Discrete frame interval.</entry>
239 </row>
240 <row>
241 <entry><constant>V4L2_FRMIVAL_TYPE_CONTINUOUS</constant></entry>
242 <entry>2</entry>
243 <entry>Continuous frame interval.</entry>
244 </row>
245 <row>
246 <entry><constant>V4L2_FRMIVAL_TYPE_STEPWISE</constant></entry>
247 <entry>3</entry>
248 <entry>Step-wise defined frame interval.</entry>
249 </row>
250 </tbody>
251 </tgroup>
252 </table>
253 </refsect1>
254
255 <refsect1>
256 &return-value;
257
258 <para>See the description section above for a list of return
259values that <varname>errno</varname> can have.</para>
260 </refsect1>
261
262</refentry>
263
264<!--
265Local Variables:
266mode: sgml
267sgml-parent-document: "v4l2.sgml"
268indent-tabs-mode: nil
269End:
270-->
diff --git a/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml b/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml
new file mode 100644
index 000000000000..6afa4542c818
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enum-framesizes.xml
@@ -0,0 +1,282 @@
1<refentry id="vidioc-enum-framesizes">
2
3 <refmeta>
4 <refentrytitle>ioctl VIDIOC_ENUM_FRAMESIZES</refentrytitle>
5 &manvol;
6 </refmeta>
7
8 <refnamediv>
9 <refname>VIDIOC_ENUM_FRAMESIZES</refname>
10 <refpurpose>Enumerate frame sizes</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_frmsizeenum *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_ENUM_FRAMESIZES</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para>Pointer to a &v4l2-frmsizeenum; that contains an index
44and pixel format and receives a frame width and height.</para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52
53 <note>
54 <title>Experimental</title>
55
56 <para>This is an <link linkend="experimental">experimental</link>
57interface and may change in the future.</para>
58 </note>
59
60 <para>This ioctl allows applications to enumerate all frame sizes
61(&ie; width and height in pixels) that the device supports for the
62given pixel format.</para>
63 <para>The supported pixel formats can be obtained by using the
64&VIDIOC-ENUM-FMT; function.</para>
65 <para>The return value and the content of the
66<structfield>v4l2_frmsizeenum.type</structfield> field depend on the
67type of frame sizes the device supports. Here are the semantics of the
68function for the different cases:</para>
69
70 <itemizedlist>
71 <listitem>
72 <para><emphasis role="bold">Discrete:</emphasis> The function
73returns success if the given index value (zero-based) is valid. The
74application should increase the index by one for each call until
75<constant>EINVAL</constant> is returned. The
76<structfield>v4l2_frmsizeenum.type</structfield> field is set to
77<constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant> by the driver. Of the
78union only the <structfield>discrete</structfield> member is
79valid.</para>
80 </listitem>
81 <listitem>
82 <para><emphasis role="bold">Step-wise:</emphasis> The function
83returns success if the given index value is zero and
84<constant>EINVAL</constant> for any other index value. The
85<structfield>v4l2_frmsizeenum.type</structfield> field is set to
86<constant>V4L2_FRMSIZE_TYPE_STEPWISE</constant> by the driver. Of the
87union only the <structfield>stepwise</structfield> member is
88valid.</para>
89 </listitem>
90 <listitem>
91 <para><emphasis role="bold">Continuous:</emphasis> This is a
92special case of the step-wise type above. The function returns success
93if the given index value is zero and <constant>EINVAL</constant> for
94any other index value. The
95<structfield>v4l2_frmsizeenum.type</structfield> field is set to
96<constant>V4L2_FRMSIZE_TYPE_CONTINUOUS</constant> by the driver. Of
97the union only the <structfield>stepwise</structfield> member is valid
98and the <structfield>step_width</structfield> and
99<structfield>step_height</structfield> values are set to 1.</para>
100 </listitem>
101 </itemizedlist>
102
103 <para>When the application calls the function with index zero, it
104must check the <structfield>type</structfield> field to determine the
105type of frame size enumeration the device supports. Only for the
106<constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant> type does it make
107sense to increase the index value to receive more frame sizes.</para>
108 <para>Note that the order in which the frame sizes are returned
109has no special meaning. In particular does it not say anything about
110potential default format sizes.</para>
111 <para>Applications can assume that the enumeration data does not
112change without any interaction from the application itself. This means
113that the enumeration data is consistent if the application does not
114perform any other ioctl calls while it runs the frame size
115enumeration.</para>
116 </refsect1>
117
118 <refsect1>
119 <title>Structs</title>
120
121 <para>In the structs below, <emphasis>IN</emphasis> denotes a
122value that has to be filled in by the application,
123<emphasis>OUT</emphasis> denotes values that the driver fills in. The
124application should zero out all members except for the
125<emphasis>IN</emphasis> fields.</para>
126
127 <table pgwide="1" frame="none" id="v4l2-frmsize-discrete">
128 <title>struct <structname>v4l2_frmsize_discrete</structname></title>
129 <tgroup cols="3">
130 &cs-str;
131 <tbody valign="top">
132 <row>
133 <entry>__u32</entry>
134 <entry><structfield>width</structfield></entry>
135 <entry>Width of the frame [pixel].</entry>
136 </row>
137 <row>
138 <entry>__u32</entry>
139 <entry><structfield>height</structfield></entry>
140 <entry>Height of the frame [pixel].</entry>
141 </row>
142 </tbody>
143 </tgroup>
144 </table>
145
146 <table pgwide="1" frame="none" id="v4l2-frmsize-stepwise">
147 <title>struct <structname>v4l2_frmsize_stepwise</structname></title>
148 <tgroup cols="3">
149 &cs-str;
150 <tbody valign="top">
151 <row>
152 <entry>__u32</entry>
153 <entry><structfield>min_width</structfield></entry>
154 <entry>Minimum frame width [pixel].</entry>
155 </row>
156 <row>
157 <entry>__u32</entry>
158 <entry><structfield>max_width</structfield></entry>
159 <entry>Maximum frame width [pixel].</entry>
160 </row>
161 <row>
162 <entry>__u32</entry>
163 <entry><structfield>step_width</structfield></entry>
164 <entry>Frame width step size [pixel].</entry>
165 </row>
166 <row>
167 <entry>__u32</entry>
168 <entry><structfield>min_height</structfield></entry>
169 <entry>Minimum frame height [pixel].</entry>
170 </row>
171 <row>
172 <entry>__u32</entry>
173 <entry><structfield>max_height</structfield></entry>
174 <entry>Maximum frame height [pixel].</entry>
175 </row>
176 <row>
177 <entry>__u32</entry>
178 <entry><structfield>step_height</structfield></entry>
179 <entry>Frame height step size [pixel].</entry>
180 </row>
181 </tbody>
182 </tgroup>
183 </table>
184
185 <table pgwide="1" frame="none" id="v4l2-frmsizeenum">
186 <title>struct <structname>v4l2_frmsizeenum</structname></title>
187 <tgroup cols="4">
188 <colspec colname="c1" />
189 <colspec colname="c2" />
190 <colspec colname="c3" />
191 <colspec colname="c4" />
192 <tbody valign="top">
193 <row>
194 <entry>__u32</entry>
195 <entry><structfield>index</structfield></entry>
196 <entry></entry>
197 <entry>IN: Index of the given frame size in the enumeration.</entry>
198 </row>
199 <row>
200 <entry>__u32</entry>
201 <entry><structfield>pixel_format</structfield></entry>
202 <entry></entry>
203 <entry>IN: Pixel format for which the frame sizes are enumerated.</entry>
204 </row>
205 <row>
206 <entry>__u32</entry>
207 <entry><structfield>type</structfield></entry>
208 <entry></entry>
209 <entry>OUT: Frame size type the device supports.</entry>
210 </row>
211 <row>
212 <entry>union</entry>
213 <entry></entry>
214 <entry></entry>
215 <entry>OUT: Frame size with the given index.</entry>
216 </row>
217 <row>
218 <entry></entry>
219 <entry>&v4l2-frmsize-discrete;</entry>
220 <entry><structfield>discrete</structfield></entry>
221 <entry></entry>
222 </row>
223 <row>
224 <entry></entry>
225 <entry>&v4l2-frmsize-stepwise;</entry>
226 <entry><structfield>stepwise</structfield></entry>
227 <entry></entry>
228 </row>
229 <row>
230 <entry>__u32</entry>
231 <entry><structfield>reserved[2]</structfield></entry>
232 <entry></entry>
233 <entry>Reserved space for future use.</entry>
234 </row>
235 </tbody>
236 </tgroup>
237 </table>
238 </refsect1>
239
240 <refsect1>
241 <title>Enums</title>
242
243 <table pgwide="1" frame="none" id="v4l2-frmsizetypes">
244 <title>enum <structname>v4l2_frmsizetypes</structname></title>
245 <tgroup cols="3">
246 &cs-def;
247 <tbody valign="top">
248 <row>
249 <entry><constant>V4L2_FRMSIZE_TYPE_DISCRETE</constant></entry>
250 <entry>1</entry>
251 <entry>Discrete frame size.</entry>
252 </row>
253 <row>
254 <entry><constant>V4L2_FRMSIZE_TYPE_CONTINUOUS</constant></entry>
255 <entry>2</entry>
256 <entry>Continuous frame size.</entry>
257 </row>
258 <row>
259 <entry><constant>V4L2_FRMSIZE_TYPE_STEPWISE</constant></entry>
260 <entry>3</entry>
261 <entry>Step-wise defined frame size.</entry>
262 </row>
263 </tbody>
264 </tgroup>
265 </table>
266 </refsect1>
267
268 <refsect1>
269 &return-value;
270
271 <para>See the description section above for a list of return
272values that <varname>errno</varname> can have.</para>
273 </refsect1>
274</refentry>
275
276<!--
277Local Variables:
278mode: sgml
279sgml-parent-document: "v4l2.sgml"
280indent-tabs-mode: nil
281End:
282-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumaudio.xml b/Documentation/DocBook/v4l/vidioc-enumaudio.xml
new file mode 100644
index 000000000000..9ae8f2d3a96f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumaudio.xml
@@ -0,0 +1,86 @@
1<refentry id="vidioc-enumaudio">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUMAUDIO</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUMAUDIO</refname>
9 <refpurpose>Enumerate audio inputs</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_audio *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_ENUMAUDIO</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>To query the attributes of an audio input applications
52initialize the <structfield>index</structfield> field and zero out the
53<structfield>reserved</structfield> array of a &v4l2-audio;
54and call the <constant>VIDIOC_ENUMAUDIO</constant> ioctl with a pointer
55to this structure. Drivers fill the rest of the structure or return an
56&EINVAL; when the index is out of bounds. To enumerate all audio
57inputs applications shall begin at index zero, incrementing by one
58until the driver returns <errorcode>EINVAL</errorcode>.</para>
59
60 <para>See <xref linkend="vidioc-g-audio" /> for a description of
61&v4l2-audio;.</para>
62 </refsect1>
63
64 <refsect1>
65 &return-value;
66
67 <variablelist>
68 <varlistentry>
69 <term><errorcode>EINVAL</errorcode></term>
70 <listitem>
71 <para>The number of the audio input is out of bounds, or
72there are no audio inputs at all and this ioctl is not
73supported.</para>
74 </listitem>
75 </varlistentry>
76 </variablelist>
77 </refsect1>
78</refentry>
79
80<!--
81Local Variables:
82mode: sgml
83sgml-parent-document: "v4l2.sgml"
84indent-tabs-mode: nil
85End:
86-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumaudioout.xml b/Documentation/DocBook/v4l/vidioc-enumaudioout.xml
new file mode 100644
index 000000000000..d3d7c0ab17b8
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumaudioout.xml
@@ -0,0 +1,89 @@
1<refentry id="vidioc-enumaudioout">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUMAUDOUT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUMAUDOUT</refname>
9 <refpurpose>Enumerate audio outputs</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_audioout *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_ENUMAUDOUT</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>To query the attributes of an audio output applications
52initialize the <structfield>index</structfield> field and zero out the
53<structfield>reserved</structfield> array of a &v4l2-audioout; and
54call the <constant>VIDIOC_G_AUDOUT</constant> ioctl with a pointer
55to this structure. Drivers fill the rest of the structure or return an
56&EINVAL; when the index is out of bounds. To enumerate all audio
57outputs applications shall begin at index zero, incrementing by one
58until the driver returns <errorcode>EINVAL</errorcode>.</para>
59
60 <para>Note connectors on a TV card to loop back the received audio
61signal to a sound card are not audio outputs in this sense.</para>
62
63 <para>See <xref linkend="vidioc-g-audioout" /> for a description of
64&v4l2-audioout;.</para>
65 </refsect1>
66
67 <refsect1>
68 &return-value;
69
70 <variablelist>
71 <varlistentry>
72 <term><errorcode>EINVAL</errorcode></term>
73 <listitem>
74 <para>The number of the audio output is out of bounds, or
75there are no audio outputs at all and this ioctl is not
76supported.</para>
77 </listitem>
78 </varlistentry>
79 </variablelist>
80 </refsect1>
81</refentry>
82
83<!--
84Local Variables:
85mode: sgml
86sgml-parent-document: "v4l2.sgml"
87indent-tabs-mode: nil
88End:
89-->
diff --git a/Documentation/DocBook/v4l/vidioc-enuminput.xml b/Documentation/DocBook/v4l/vidioc-enuminput.xml
new file mode 100644
index 000000000000..414856b82473
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enuminput.xml
@@ -0,0 +1,287 @@
1<refentry id="vidioc-enuminput">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUMINPUT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUMINPUT</refname>
9 <refpurpose>Enumerate video inputs</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_input
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_ENUMINPUT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>To query the attributes of a video input applications
53initialize the <structfield>index</structfield> field of &v4l2-input;
54and call the <constant>VIDIOC_ENUMINPUT</constant> ioctl with a
55pointer to this structure. Drivers fill the rest of the structure or
56return an &EINVAL; when the index is out of bounds. To enumerate all
57inputs applications shall begin at index zero, incrementing by one
58until the driver returns <errorcode>EINVAL</errorcode>.</para>
59
60 <table frame="none" pgwide="1" id="v4l2-input">
61 <title>struct <structname>v4l2_input</structname></title>
62 <tgroup cols="3">
63 &cs-str;
64 <tbody valign="top">
65 <row>
66 <entry>__u32</entry>
67 <entry><structfield>index</structfield></entry>
68 <entry>Identifies the input, set by the
69application.</entry>
70 </row>
71 <row>
72 <entry>__u8</entry>
73 <entry><structfield>name</structfield>[32]</entry>
74 <entry>Name of the video input, a NUL-terminated ASCII
75string, for example: "Vin (Composite 2)". This information is intended
76for the user, preferably the connector label on the device itself.</entry>
77 </row>
78 <row>
79 <entry>__u32</entry>
80 <entry><structfield>type</structfield></entry>
81 <entry>Type of the input, see <xref
82 linkend="input-type" />.</entry>
83 </row>
84 <row>
85 <entry>__u32</entry>
86 <entry><structfield>audioset</structfield></entry>
87 <entry><para>Drivers can enumerate up to 32 video and
88audio inputs. This field shows which audio inputs were selectable as
89audio source if this was the currently selected video input. It is a
90bit mask. The LSB corresponds to audio input 0, the MSB to input 31.
91Any number of bits can be set, or none.</para><para>When the driver
92does not enumerate audio inputs no bits must be set. Applications
93shall not interpret this as lack of audio support. Some drivers
94automatically select audio sources and do not enumerate them since
95there is no choice anyway.</para><para>For details on audio inputs and
96how to select the current input see <xref
97 linkend="audio" />.</para></entry>
98 </row>
99 <row>
100 <entry>__u32</entry>
101 <entry><structfield>tuner</structfield></entry>
102 <entry>Capture devices can have zero or more tuners (RF
103demodulators). When the <structfield>type</structfield> is set to
104<constant>V4L2_INPUT_TYPE_TUNER</constant> this is an RF connector and
105this field identifies the tuner. It corresponds to
106&v4l2-tuner; field <structfield>index</structfield>. For details on
107tuners see <xref linkend="tuner" />.</entry>
108 </row>
109 <row>
110 <entry>&v4l2-std-id;</entry>
111 <entry><structfield>std</structfield></entry>
112 <entry>Every video input supports one or more different
113video standards. This field is a set of all supported standards. For
114details on video standards and how to switch see <xref
115linkend="standard" />.</entry>
116 </row>
117 <row>
118 <entry>__u32</entry>
119 <entry><structfield>status</structfield></entry>
120 <entry>This field provides status information about the
121input. See <xref linkend="input-status" /> for flags.
122With the exception of the sensor orientation bits <structfield>status</structfield> is only valid when this is the
123current input.</entry>
124 </row>
125 <row>
126 <entry>__u32</entry>
127 <entry><structfield>reserved</structfield>[4]</entry>
128 <entry>Reserved for future extensions. Drivers must set
129the array to zero.</entry>
130 </row>
131 </tbody>
132 </tgroup>
133 </table>
134
135 <table frame="none" pgwide="1" id="input-type">
136 <title>Input Types</title>
137 <tgroup cols="3">
138 &cs-def;
139 <tbody valign="top">
140 <row>
141 <entry><constant>V4L2_INPUT_TYPE_TUNER</constant></entry>
142 <entry>1</entry>
143 <entry>This input uses a tuner (RF demodulator).</entry>
144 </row>
145 <row>
146 <entry><constant>V4L2_INPUT_TYPE_CAMERA</constant></entry>
147 <entry>2</entry>
148 <entry>Analog baseband input, for example CVBS /
149Composite Video, S-Video, RGB.</entry>
150 </row>
151 </tbody>
152 </tgroup>
153 </table>
154
155 <!-- Status flags based on proposal by Mark McClelland,
156video4linux-list@redhat.com on 18 Oct 2002, subject "Re: [V4L] Re:
157v4l2 api". "Why are some of them inverted? So that the driver doesn't
158have to lie about the status in cases where it can't tell one way or
159the other. Plus, a status of zero would generally mean that everything
160is OK." -->
161
162 <table frame="none" pgwide="1" id="input-status">
163 <title>Input Status Flags</title>
164 <tgroup cols="3">
165 <colspec colname="c1" />
166 <colspec colname="c2" align="center" />
167 <colspec colname="c3" />
168 <spanspec namest="c1" nameend="c3" spanname="hspan"
169 align="left" />
170 <tbody valign="top">
171 <row>
172 <entry spanname="hspan">General</entry>
173 </row>
174 <row>
175 <entry><constant>V4L2_IN_ST_NO_POWER</constant></entry>
176 <entry>0x00000001</entry>
177 <entry>Attached device is off.</entry>
178 </row>
179 <row>
180 <entry><constant>V4L2_IN_ST_NO_SIGNAL</constant></entry>
181 <entry>0x00000002</entry>
182 <entry></entry>
183 </row>
184 <row>
185 <entry><constant>V4L2_IN_ST_NO_COLOR</constant></entry>
186 <entry>0x00000004</entry>
187 <entry>The hardware supports color decoding, but does not
188detect color modulation in the signal.</entry>
189 </row>
190 <row>
191 <entry spanname="hspan">Sensor Orientation</entry>
192 </row>
193 <row>
194 <entry><constant>V4L2_IN_ST_HFLIP</constant></entry>
195 <entry>0x00000010</entry>
196 <entry>The input is connected to a device that produces a signal
197that is flipped horizontally and does not correct this before passing the
198signal to userspace.</entry>
199 </row>
200 <row>
201 <entry><constant>V4L2_IN_ST_VFLIP</constant></entry>
202 <entry>0x00000020</entry>
203 <entry>The input is connected to a device that produces a signal
204that is flipped vertically and does not correct this before passing the
205signal to userspace. Note that a 180 degree rotation is the same as HFLIP | VFLIP</entry>
206 </row>
207 <row>
208 <entry spanname="hspan">Analog Video</entry>
209 </row>
210 <row>
211 <entry><constant>V4L2_IN_ST_NO_H_LOCK</constant></entry>
212 <entry>0x00000100</entry>
213 <entry>No horizontal sync lock.</entry>
214 </row>
215 <row>
216 <entry><constant>V4L2_IN_ST_COLOR_KILL</constant></entry>
217 <entry>0x00000200</entry>
218 <entry>A color killer circuit automatically disables color
219decoding when it detects no color modulation. When this flag is set
220the color killer is enabled <emphasis>and</emphasis> has shut off
221color decoding.</entry>
222 </row>
223 <row>
224 <entry spanname="hspan">Digital Video</entry>
225 </row>
226 <row>
227 <entry><constant>V4L2_IN_ST_NO_SYNC</constant></entry>
228 <entry>0x00010000</entry>
229 <entry>No synchronization lock.</entry>
230 </row>
231 <row>
232 <entry><constant>V4L2_IN_ST_NO_EQU</constant></entry>
233 <entry>0x00020000</entry>
234 <entry>No equalizer lock.</entry>
235 </row>
236 <row>
237 <entry><constant>V4L2_IN_ST_NO_CARRIER</constant></entry>
238 <entry>0x00040000</entry>
239 <entry>Carrier recovery failed.</entry>
240 </row>
241 <row>
242 <entry spanname="hspan">VCR and Set-Top Box</entry>
243 </row>
244 <row>
245 <entry><constant>V4L2_IN_ST_MACROVISION</constant></entry>
246 <entry>0x01000000</entry>
247 <entry>Macrovision is an analog copy prevention system
248mangling the video signal to confuse video recorders. When this
249flag is set Macrovision has been detected.</entry>
250 </row>
251 <row>
252 <entry><constant>V4L2_IN_ST_NO_ACCESS</constant></entry>
253 <entry>0x02000000</entry>
254 <entry>Conditional access denied.</entry>
255 </row>
256 <row>
257 <entry><constant>V4L2_IN_ST_VTR</constant></entry>
258 <entry>0x04000000</entry>
259 <entry>VTR time constant. [?]</entry>
260 </row>
261 </tbody>
262 </tgroup>
263 </table>
264 </refsect1>
265
266 <refsect1>
267 &return-value;
268
269 <variablelist>
270 <varlistentry>
271 <term><errorcode>EINVAL</errorcode></term>
272 <listitem>
273 <para>The &v4l2-input; <structfield>index</structfield> is
274out of bounds.</para>
275 </listitem>
276 </varlistentry>
277 </variablelist>
278 </refsect1>
279</refentry>
280
281<!--
282Local Variables:
283mode: sgml
284sgml-parent-document: "v4l2.sgml"
285indent-tabs-mode: nil
286End:
287-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumoutput.xml b/Documentation/DocBook/v4l/vidioc-enumoutput.xml
new file mode 100644
index 000000000000..e8d16dcd50cf
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumoutput.xml
@@ -0,0 +1,172 @@
1<refentry id="vidioc-enumoutput">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUMOUTPUT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUMOUTPUT</refname>
9 <refpurpose>Enumerate video outputs</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_output *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_ENUMOUTPUT</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>To query the attributes of a video outputs applications
52initialize the <structfield>index</structfield> field of &v4l2-output;
53and call the <constant>VIDIOC_ENUMOUTPUT</constant> ioctl with a
54pointer to this structure. Drivers fill the rest of the structure or
55return an &EINVAL; when the index is out of bounds. To enumerate all
56outputs applications shall begin at index zero, incrementing by one
57until the driver returns <errorcode>EINVAL</errorcode>.</para>
58
59 <table frame="none" pgwide="1" id="v4l2-output">
60 <title>struct <structname>v4l2_output</structname></title>
61 <tgroup cols="3">
62 &cs-str;
63 <tbody valign="top">
64 <row>
65 <entry>__u32</entry>
66 <entry><structfield>index</structfield></entry>
67 <entry>Identifies the output, set by the
68application.</entry>
69 </row>
70 <row>
71 <entry>__u8</entry>
72 <entry><structfield>name</structfield>[32]</entry>
73 <entry>Name of the video output, a NUL-terminated ASCII
74string, for example: "Vout". This information is intended for the
75user, preferably the connector label on the device itself.</entry>
76 </row>
77 <row>
78 <entry>__u32</entry>
79 <entry><structfield>type</structfield></entry>
80 <entry>Type of the output, see <xref
81 linkend="output-type" />.</entry>
82 </row>
83 <row>
84 <entry>__u32</entry>
85 <entry><structfield>audioset</structfield></entry>
86 <entry><para>Drivers can enumerate up to 32 video and
87audio outputs. This field shows which audio outputs were
88selectable as the current output if this was the currently selected
89video output. It is a bit mask. The LSB corresponds to audio output 0,
90the MSB to output 31. Any number of bits can be set, or
91none.</para><para>When the driver does not enumerate audio outputs no
92bits must be set. Applications shall not interpret this as lack of
93audio support. Drivers may automatically select audio outputs without
94enumerating them.</para><para>For details on audio outputs and how to
95select the current output see <xref linkend="audio" />.</para></entry>
96 </row>
97 <row>
98 <entry>__u32</entry>
99 <entry><structfield>modulator</structfield></entry>
100 <entry>Output devices can have zero or more RF modulators.
101When the <structfield>type</structfield> is
102<constant>V4L2_OUTPUT_TYPE_MODULATOR</constant> this is an RF
103connector and this field identifies the modulator. It corresponds to
104&v4l2-modulator; field <structfield>index</structfield>. For details
105on modulators see <xref linkend="tuner" />.</entry>
106 </row>
107 <row>
108 <entry>&v4l2-std-id;</entry>
109 <entry><structfield>std</structfield></entry>
110 <entry>Every video output supports one or more different
111video standards. This field is a set of all supported standards. For
112details on video standards and how to switch see <xref
113 linkend="standard" />.</entry>
114 </row>
115 <row>
116 <entry>__u32</entry>
117 <entry><structfield>reserved</structfield>[4]</entry>
118 <entry>Reserved for future extensions. Drivers must set
119the array to zero.</entry>
120 </row>
121 </tbody>
122 </tgroup>
123 </table>
124
125 <table frame="none" pgwide="1" id="output-type">
126 <title>Output Type</title>
127 <tgroup cols="3">
128 &cs-def;
129 <tbody valign="top">
130 <row>
131 <entry><constant>V4L2_OUTPUT_TYPE_MODULATOR</constant></entry>
132 <entry>1</entry>
133 <entry>This output is an analog TV modulator.</entry>
134 </row>
135 <row>
136 <entry><constant>V4L2_OUTPUT_TYPE_ANALOG</constant></entry>
137 <entry>2</entry>
138 <entry>Analog baseband output, for example Composite /
139CVBS, S-Video, RGB.</entry>
140 </row>
141 <row>
142 <entry><constant>V4L2_OUTPUT_TYPE_ANALOGVGAOVERLAY</constant></entry>
143 <entry>3</entry>
144 <entry>[?]</entry>
145 </row>
146 </tbody>
147 </tgroup>
148 </table>
149
150 </refsect1>
151 <refsect1>
152 &return-value;
153
154 <variablelist>
155 <varlistentry>
156 <term><errorcode>EINVAL</errorcode></term>
157 <listitem>
158 <para>The &v4l2-output; <structfield>index</structfield>
159is out of bounds.</para>
160 </listitem>
161 </varlistentry>
162 </variablelist>
163 </refsect1>
164</refentry>
165
166<!--
167Local Variables:
168mode: sgml
169sgml-parent-document: "v4l2.sgml"
170indent-tabs-mode: nil
171End:
172-->
diff --git a/Documentation/DocBook/v4l/vidioc-enumstd.xml b/Documentation/DocBook/v4l/vidioc-enumstd.xml
new file mode 100644
index 000000000000..95803fe2c8e4
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-enumstd.xml
@@ -0,0 +1,391 @@
1<refentry id="vidioc-enumstd">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_ENUMSTD</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_ENUMSTD</refname>
9 <refpurpose>Enumerate supported video standards</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_standard *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_ENUMSTD</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>To query the attributes of a video standard,
52especially a custom (driver defined) one, applications initialize the
53<structfield>index</structfield> field of &v4l2-standard; and call the
54<constant>VIDIOC_ENUMSTD</constant> ioctl with a pointer to this
55structure. Drivers fill the rest of the structure or return an
56&EINVAL; when the index is out of bounds. To enumerate all standards
57applications shall begin at index zero, incrementing by one until the
58driver returns <errorcode>EINVAL</errorcode>. Drivers may enumerate a
59different set of standards after switching the video input or
60output.<footnote>
61 <para>The supported standards may overlap and we need an
62unambiguous set to find the current standard returned by
63<constant>VIDIOC_G_STD</constant>.</para>
64 </footnote></para>
65
66 <table pgwide="1" frame="none" id="v4l2-standard">
67 <title>struct <structname>v4l2_standard</structname></title>
68 <tgroup cols="3">
69 &cs-str;
70 <tbody valign="top">
71 <row>
72 <entry>__u32</entry>
73 <entry><structfield>index</structfield></entry>
74 <entry>Number of the video standard, set by the
75application.</entry>
76 </row>
77 <row>
78 <entry>&v4l2-std-id;</entry>
79 <entry><structfield>id</structfield></entry>
80 <entry>The bits in this field identify the standard as
81one of the common standards listed in <xref linkend="v4l2-std-id" />,
82or if bits 32 to 63 are set as custom standards. Multiple bits can be
83set if the hardware does not distinguish between these standards,
84however separate indices do not indicate the opposite. The
85<structfield>id</structfield> must be unique. No other enumerated
86<structname>v4l2_standard</structname> structure, for this input or
87output anyway, can contain the same set of bits.</entry>
88 </row>
89 <row>
90 <entry>__u8</entry>
91 <entry><structfield>name</structfield>[24]</entry>
92 <entry>Name of the standard, a NUL-terminated ASCII
93string, for example: "PAL-B/G", "NTSC Japan". This information is
94intended for the user.</entry>
95 </row>
96 <row>
97 <entry>&v4l2-fract;</entry>
98 <entry><structfield>frameperiod</structfield></entry>
99 <entry>The frame period (not field period) is numerator
100/ denominator. For example M/NTSC has a frame period of 1001 /
10130000 seconds.</entry>
102 </row>
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>framelines</structfield></entry>
106 <entry>Total lines per frame including blanking,
107e.&nbsp;g. 625 for B/PAL.</entry>
108 </row>
109 <row>
110 <entry>__u32</entry>
111 <entry><structfield>reserved</structfield>[4]</entry>
112 <entry>Reserved for future extensions. Drivers must set
113the array to zero.</entry>
114 </row>
115 </tbody>
116 </tgroup>
117 </table>
118
119 <table pgwide="1" frame="none" id="v4l2-fract">
120 <title>struct <structname>v4l2_fract</structname></title>
121 <tgroup cols="3">
122 &cs-str;
123 <tbody valign="top">
124 <row>
125 <entry>__u32</entry>
126 <entry><structfield>numerator</structfield></entry>
127 <entry></entry>
128 </row>
129 <row>
130 <entry>__u32</entry>
131 <entry><structfield>denominator</structfield></entry>
132 <entry></entry>
133 </row>
134 </tbody>
135 </tgroup>
136 </table>
137
138 <table pgwide="1" frame="none" id="v4l2-std-id">
139 <title>typedef <structname>v4l2_std_id</structname></title>
140 <tgroup cols="3">
141 &cs-str;
142 <tbody valign="top">
143 <row>
144 <entry>__u64</entry>
145 <entry><structfield>v4l2_std_id</structfield></entry>
146 <entry>This type is a set, each bit representing another
147video standard as listed below and in <xref
148linkend="video-standards" />. The 32 most significant bits are reserved
149for custom (driver defined) video standards.</entry>
150 </row>
151 </tbody>
152 </tgroup>
153 </table>
154
155 <para><programlisting>
156#define V4L2_STD_PAL_B ((v4l2_std_id)0x00000001)
157#define V4L2_STD_PAL_B1 ((v4l2_std_id)0x00000002)
158#define V4L2_STD_PAL_G ((v4l2_std_id)0x00000004)
159#define V4L2_STD_PAL_H ((v4l2_std_id)0x00000008)
160#define V4L2_STD_PAL_I ((v4l2_std_id)0x00000010)
161#define V4L2_STD_PAL_D ((v4l2_std_id)0x00000020)
162#define V4L2_STD_PAL_D1 ((v4l2_std_id)0x00000040)
163#define V4L2_STD_PAL_K ((v4l2_std_id)0x00000080)
164
165#define V4L2_STD_PAL_M ((v4l2_std_id)0x00000100)
166#define V4L2_STD_PAL_N ((v4l2_std_id)0x00000200)
167#define V4L2_STD_PAL_Nc ((v4l2_std_id)0x00000400)
168#define V4L2_STD_PAL_60 ((v4l2_std_id)0x00000800)
169</programlisting></para><para><constant>V4L2_STD_PAL_60</constant> is
170a hybrid standard with 525 lines, 60 Hz refresh rate, and PAL color
171modulation with a 4.43 MHz color subcarrier. Some PAL video recorders
172can play back NTSC tapes in this mode for display on a 50/60 Hz agnostic
173PAL TV.</para><para><programlisting>
174#define V4L2_STD_NTSC_M ((v4l2_std_id)0x00001000)
175#define V4L2_STD_NTSC_M_JP ((v4l2_std_id)0x00002000)
176#define V4L2_STD_NTSC_443 ((v4l2_std_id)0x00004000)
177</programlisting></para><para><constant>V4L2_STD_NTSC_443</constant>
178is a hybrid standard with 525 lines, 60 Hz refresh rate, and NTSC
179color modulation with a 4.43 MHz color
180subcarrier.</para><para><programlisting>
181#define V4L2_STD_NTSC_M_KR ((v4l2_std_id)0x00008000)
182
183#define V4L2_STD_SECAM_B ((v4l2_std_id)0x00010000)
184#define V4L2_STD_SECAM_D ((v4l2_std_id)0x00020000)
185#define V4L2_STD_SECAM_G ((v4l2_std_id)0x00040000)
186#define V4L2_STD_SECAM_H ((v4l2_std_id)0x00080000)
187#define V4L2_STD_SECAM_K ((v4l2_std_id)0x00100000)
188#define V4L2_STD_SECAM_K1 ((v4l2_std_id)0x00200000)
189#define V4L2_STD_SECAM_L ((v4l2_std_id)0x00400000)
190#define V4L2_STD_SECAM_LC ((v4l2_std_id)0x00800000)
191
192/* ATSC/HDTV */
193#define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000)
194#define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000)
195</programlisting></para><para><!-- ATSC proposal by Mark McClelland,
196video4linux-list@redhat.com on 17 Oct 2002
197--><constant>V4L2_STD_ATSC_8_VSB</constant> and
198<constant>V4L2_STD_ATSC_16_VSB</constant> are U.S. terrestrial digital
199TV standards. Presently the V4L2 API does not support digital TV. See
200also the Linux DVB API at <ulink
201url="http://linuxtv.org">http://linuxtv.org</ulink>.</para>
202<para><programlisting>
203#define V4L2_STD_PAL_BG (V4L2_STD_PAL_B |\
204 V4L2_STD_PAL_B1 |\
205 V4L2_STD_PAL_G)
206#define V4L2_STD_B (V4L2_STD_PAL_B |\
207 V4L2_STD_PAL_B1 |\
208 V4L2_STD_SECAM_B)
209#define V4L2_STD_GH (V4L2_STD_PAL_G |\
210 V4L2_STD_PAL_H |\
211 V4L2_STD_SECAM_G |\
212 V4L2_STD_SECAM_H)
213#define V4L2_STD_PAL_DK (V4L2_STD_PAL_D |\
214 V4L2_STD_PAL_D1 |\
215 V4L2_STD_PAL_K)
216#define V4L2_STD_PAL (V4L2_STD_PAL_BG |\
217 V4L2_STD_PAL_DK |\
218 V4L2_STD_PAL_H |\
219 V4L2_STD_PAL_I)
220#define V4L2_STD_NTSC (V4L2_STD_NTSC_M |\
221 V4L2_STD_NTSC_M_JP |\
222 V4L2_STD_NTSC_M_KR)
223#define V4L2_STD_MN (V4L2_STD_PAL_M |\
224 V4L2_STD_PAL_N |\
225 V4L2_STD_PAL_Nc |\
226 V4L2_STD_NTSC)
227#define V4L2_STD_SECAM_DK (V4L2_STD_SECAM_D |\
228 V4L2_STD_SECAM_K |\
229 V4L2_STD_SECAM_K1)
230#define V4L2_STD_DK (V4L2_STD_PAL_DK |\
231 V4L2_STD_SECAM_DK)
232
233#define V4L2_STD_SECAM (V4L2_STD_SECAM_B |\
234 V4L2_STD_SECAM_G |\
235 V4L2_STD_SECAM_H |\
236 V4L2_STD_SECAM_DK |\
237 V4L2_STD_SECAM_L |\
238 V4L2_STD_SECAM_LC)
239
240#define V4L2_STD_525_60 (V4L2_STD_PAL_M |\
241 V4L2_STD_PAL_60 |\
242 V4L2_STD_NTSC |\
243 V4L2_STD_NTSC_443)
244#define V4L2_STD_625_50 (V4L2_STD_PAL |\
245 V4L2_STD_PAL_N |\
246 V4L2_STD_PAL_Nc |\
247 V4L2_STD_SECAM)
248
249#define V4L2_STD_UNKNOWN 0
250#define V4L2_STD_ALL (V4L2_STD_525_60 |\
251 V4L2_STD_625_50)
252</programlisting></para>
253
254 <table pgwide="1" id="video-standards" orient="land">
255 <title>Video Standards (based on [<xref linkend="itu470" />])</title>
256 <tgroup cols="12" colsep="1" rowsep="1" align="center">
257 <colspec colname="c1" align="left" />
258 <colspec colname="c2" />
259 <colspec colname="c3" />
260 <colspec colname="c4" />
261 <colspec colname="c5" />
262 <colspec colnum="7" colname="c7" />
263 <colspec colnum="9" colname="c9" />
264 <colspec colnum="12" colname="c12" />
265 <spanspec namest="c2" nameend="c3" spanname="m" align="center" />
266 <spanspec namest="c4" nameend="c12" spanname="x" align="center" />
267 <spanspec namest="c5" nameend="c7" spanname="b" align="center" />
268 <spanspec namest="c9" nameend="c12" spanname="s" align="center" />
269 <thead>
270 <row>
271 <entry>Characteristics</entry>
272 <entry><para>M/NTSC<footnote><para>Japan uses a standard
273similar to M/NTSC
274(V4L2_STD_NTSC_M_JP).</para></footnote></para></entry>
275 <entry>M/PAL</entry>
276 <entry><para>N/PAL<footnote><para> The values in
277brackets apply to the combination N/PAL a.k.a.
278N<subscript>C</subscript> used in Argentina
279(V4L2_STD_PAL_Nc).</para></footnote></para></entry>
280 <entry align="center">B, B1, G/PAL</entry>
281 <entry align="center">D, D1, K/PAL</entry>
282 <entry align="center">H/PAL</entry>
283 <entry align="center">I/PAL</entry>
284 <entry align="center">B, G/SECAM</entry>
285 <entry align="center">D, K/SECAM</entry>
286 <entry align="center">K1/SECAM</entry>
287 <entry align="center">L/SECAM</entry>
288 </row>
289 </thead>
290 <tbody valign="top">
291 <row>
292 <entry>Frame lines</entry>
293 <entry spanname="m">525</entry>
294 <entry spanname="x">625</entry>
295 </row>
296 <row>
297 <entry>Frame period (s)</entry>
298 <entry spanname="m">1001/30000</entry>
299 <entry spanname="x">1/25</entry>
300 </row>
301 <row>
302 <entry>Chrominance sub-carrier frequency (Hz)</entry>
303 <entry>3579545 &plusmn;&nbsp;10</entry>
304 <entry>3579611.49 &plusmn;&nbsp;10</entry>
305 <entry>4433618.75 &plusmn;&nbsp;5 (3582056.25
306&plusmn;&nbsp;5)</entry>
307 <entry spanname="b">4433618.75 &plusmn;&nbsp;5</entry>
308 <entry>4433618.75 &plusmn;&nbsp;1</entry>
309 <entry spanname="s">f<subscript>OR</subscript>&nbsp;=
3104406250 &plusmn;&nbsp;2000, f<subscript>OB</subscript>&nbsp;= 4250000
311&plusmn;&nbsp;2000</entry>
312 </row>
313 <row>
314 <entry>Nominal radio-frequency channel bandwidth
315(MHz)</entry>
316 <entry>6</entry>
317 <entry>6</entry>
318 <entry>6</entry>
319 <entry>B: 7; B1, G: 8</entry>
320 <entry>8</entry>
321 <entry>8</entry>
322 <entry>8</entry>
323 <entry>8</entry>
324 <entry>8</entry>
325 <entry>8</entry>
326 <entry>8</entry>
327 </row>
328 <row>
329 <entry>Sound carrier relative to vision carrier
330(MHz)</entry>
331 <entry>+&nbsp;4.5</entry>
332 <entry>+&nbsp;4.5</entry>
333 <entry>+&nbsp;4.5</entry>
334 <entry><para>+&nbsp;5.5 &plusmn;&nbsp;0.001
335<footnote><para>In the Federal Republic of Germany, Austria, Italy,
336the Netherlands, Slovakia and Switzerland a system of two sound
337carriers is used, the frequency of the second carrier being
338242.1875&nbsp;kHz above the frequency of the first sound carrier. For
339stereophonic sound transmissions a similar system is used in
340Australia.</para></footnote> <footnote><para>New Zealand uses a sound
341carrier displaced 5.4996 &plusmn;&nbsp;0.0005 MHz from the vision
342carrier.</para></footnote> <footnote><para>In Denmark, Finland, New
343Zealand, Sweden and Spain a system of two sound carriers is used. In
344Iceland, Norway and Poland the same system is being introduced. The
345second carrier is 5.85&nbsp;MHz above the vision carrier and is DQPSK
346modulated with 728&nbsp;kbit/s sound and data multiplex. (NICAM
347system)</para></footnote> <footnote><para>In the United Kingdom, a
348system of two sound carriers is used. The second sound carrier is
3496.552&nbsp;MHz above the vision carrier and is DQPSK modulated with a
350728&nbsp;kbit/s sound and data multiplex able to carry two sound
351channels. (NICAM system)</para></footnote></para></entry>
352 <entry>+&nbsp;6.5 &plusmn;&nbsp;0.001</entry>
353 <entry>+&nbsp;5.5</entry>
354 <entry>+&nbsp;5.9996 &plusmn;&nbsp;0.0005</entry>
355 <entry>+&nbsp;5.5 &plusmn;&nbsp;0.001</entry>
356 <entry>+&nbsp;6.5 &plusmn;&nbsp;0.001</entry>
357 <entry>+&nbsp;6.5</entry>
358 <entry><para>+&nbsp;6.5 <footnote><para>In France, a
359digital carrier 5.85 MHz away from the vision carrier may be used in
360addition to the main sound carrier. It is modulated in differentially
361encoded QPSK with a 728 kbit/s sound and data multiplexer capable of
362carrying two sound channels. (NICAM
363system)</para></footnote></para></entry>
364 </row>
365 </tbody>
366 </tgroup>
367 </table>
368 </refsect1>
369
370 <refsect1>
371 &return-value;
372
373 <variablelist>
374 <varlistentry>
375 <term><errorcode>EINVAL</errorcode></term>
376 <listitem>
377 <para>The &v4l2-standard; <structfield>index</structfield>
378is out of bounds.</para>
379 </listitem>
380 </varlistentry>
381 </variablelist>
382 </refsect1>
383</refentry>
384
385<!--
386Local Variables:
387mode: sgml
388sgml-parent-document: "v4l2.sgml"
389indent-tabs-mode: nil
390End:
391-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-audio.xml b/Documentation/DocBook/v4l/vidioc-g-audio.xml
new file mode 100644
index 000000000000..65361a8c2b05
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-audio.xml
@@ -0,0 +1,188 @@
1<refentry id="vidioc-g-audio">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_AUDIO, VIDIOC_S_AUDIO</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_AUDIO</refname>
9 <refname>VIDIOC_S_AUDIO</refname>
10 <refpurpose>Query or select the current audio input and its
11attributes</refpurpose>
12 </refnamediv>
13
14 <refsynopsisdiv>
15 <funcsynopsis>
16 <funcprototype>
17 <funcdef>int <function>ioctl</function></funcdef>
18 <paramdef>int <parameter>fd</parameter></paramdef>
19 <paramdef>int <parameter>request</parameter></paramdef>
20 <paramdef>struct v4l2_audio *<parameter>argp</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 <funcsynopsis>
24 <funcprototype>
25 <funcdef>int <function>ioctl</function></funcdef>
26 <paramdef>int <parameter>fd</parameter></paramdef>
27 <paramdef>int <parameter>request</parameter></paramdef>
28 <paramdef>const struct v4l2_audio *<parameter>argp</parameter></paramdef>
29 </funcprototype>
30 </funcsynopsis>
31 </refsynopsisdiv>
32
33 <refsect1>
34 <title>Arguments</title>
35
36 <variablelist>
37 <varlistentry>
38 <term><parameter>fd</parameter></term>
39 <listitem>
40 <para>&fd;</para>
41 </listitem>
42 </varlistentry>
43 <varlistentry>
44 <term><parameter>request</parameter></term>
45 <listitem>
46 <para>VIDIOC_G_AUDIO, VIDIOC_S_AUDIO</para>
47 </listitem>
48 </varlistentry>
49 <varlistentry>
50 <term><parameter>argp</parameter></term>
51 <listitem>
52 <para></para>
53 </listitem>
54 </varlistentry>
55 </variablelist>
56 </refsect1>
57
58 <refsect1>
59 <title>Description</title>
60
61 <para>To query the current audio input applications zero out the
62<structfield>reserved</structfield> array of a &v4l2-audio;
63and call the <constant>VIDIOC_G_AUDIO</constant> ioctl with a pointer
64to this structure. Drivers fill the rest of the structure or return an
65&EINVAL; when the device has no audio inputs, or none which combine
66with the current video input.</para>
67
68 <para>Audio inputs have one writable property, the audio mode. To
69select the current audio input <emphasis>and</emphasis> change the
70audio mode, applications initialize the
71<structfield>index</structfield> and <structfield>mode</structfield>
72fields, and the
73<structfield>reserved</structfield> array of a
74<structname>v4l2_audio</structname> structure and call the
75<constant>VIDIOC_S_AUDIO</constant> ioctl. Drivers may switch to a
76different audio mode if the request cannot be satisfied. However, this
77is a write-only ioctl, it does not return the actual new audio
78mode.</para>
79
80 <table pgwide="1" frame="none" id="v4l2-audio">
81 <title>struct <structname>v4l2_audio</structname></title>
82 <tgroup cols="3">
83 &cs-str;
84 <tbody valign="top">
85 <row>
86 <entry>__u32</entry>
87 <entry><structfield>index</structfield></entry>
88 <entry>Identifies the audio input, set by the
89driver or application.</entry>
90 </row>
91 <row>
92 <entry>__u8</entry>
93 <entry><structfield>name</structfield>[32]</entry>
94 <entry>Name of the audio input, a NUL-terminated ASCII
95string, for example: "Line In". This information is intended for the
96user, preferably the connector label on the device itself.</entry>
97 </row>
98 <row>
99 <entry>__u32</entry>
100 <entry><structfield>capability</structfield></entry>
101 <entry>Audio capability flags, see <xref
102 linkend="audio-capability" />.</entry>
103 </row>
104 <row>
105 <entry>__u32</entry>
106 <entry><structfield>mode</structfield></entry>
107 <entry>Audio mode flags set by drivers and applications (on
108 <constant>VIDIOC_S_AUDIO</constant> ioctl), see <xref linkend="audio-mode" />.</entry>
109 </row>
110 <row>
111 <entry>__u32</entry>
112 <entry><structfield>reserved</structfield>[2]</entry>
113 <entry>Reserved for future extensions. Drivers and
114applications must set the array to zero.</entry>
115 </row>
116 </tbody>
117 </tgroup>
118 </table>
119
120 <table pgwide="1" frame="none" id="audio-capability">
121 <title>Audio Capability Flags</title>
122 <tgroup cols="3">
123 &cs-def;
124 <tbody valign="top">
125 <row>
126 <entry><constant>V4L2_AUDCAP_STEREO</constant></entry>
127 <entry>0x00001</entry>
128 <entry>This is a stereo input. The flag is intended to
129automatically disable stereo recording etc. when the signal is always
130monaural. The API provides no means to detect if stereo is
131<emphasis>received</emphasis>, unless the audio input belongs to a
132tuner.</entry>
133 </row>
134 <row>
135 <entry><constant>V4L2_AUDCAP_AVL</constant></entry>
136 <entry>0x00002</entry>
137 <entry>Automatic Volume Level mode is supported.</entry>
138 </row>
139 </tbody>
140 </tgroup>
141 </table>
142
143 <table pgwide="1" frame="none" id="audio-mode">
144 <title>Audio Mode Flags</title>
145 <tgroup cols="3">
146 &cs-def;
147 <tbody valign="top">
148 <row>
149 <entry><constant>V4L2_AUDMODE_AVL</constant></entry>
150 <entry>0x00001</entry>
151 <entry>AVL mode is on.</entry>
152 </row>
153 </tbody>
154 </tgroup>
155 </table>
156 </refsect1>
157
158 <refsect1>
159 &return-value;
160
161 <variablelist>
162 <varlistentry>
163 <term><errorcode>EINVAL</errorcode></term>
164 <listitem>
165 <para>No audio inputs combine with the current video input,
166or the number of the selected audio input is out of bounds or it does
167not combine, or there are no audio inputs at all and the ioctl is not
168supported.</para>
169 </listitem>
170 </varlistentry>
171 <varlistentry>
172 <term><errorcode>EBUSY</errorcode></term>
173 <listitem>
174 <para>I/O is in progress, the input cannot be
175switched.</para>
176 </listitem>
177 </varlistentry>
178 </variablelist>
179 </refsect1>
180</refentry>
181
182<!--
183Local Variables:
184mode: sgml
185sgml-parent-document: "v4l2.sgml"
186indent-tabs-mode: nil
187End:
188-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-audioout.xml b/Documentation/DocBook/v4l/vidioc-g-audioout.xml
new file mode 100644
index 000000000000..3632730c5c6e
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-audioout.xml
@@ -0,0 +1,154 @@
1<refentry id="vidioc-g-audioout">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_AUDOUT</refname>
9 <refname>VIDIOC_S_AUDOUT</refname>
10 <refpurpose>Query or select the current audio output</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_audioout *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>const struct v4l2_audioout *<parameter>argp</parameter></paramdef>
28 </funcprototype>
29 </funcsynopsis>
30 </refsynopsisdiv>
31
32 <refsect1>
33 <title>Arguments</title>
34
35 <variablelist>
36 <varlistentry>
37 <term><parameter>fd</parameter></term>
38 <listitem>
39 <para>&fd;</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>request</parameter></term>
44 <listitem>
45 <para>VIDIOC_G_AUDOUT, VIDIOC_S_AUDOUT</para>
46 </listitem>
47 </varlistentry>
48 <varlistentry>
49 <term><parameter>argp</parameter></term>
50 <listitem>
51 <para></para>
52 </listitem>
53 </varlistentry>
54 </variablelist>
55 </refsect1>
56
57 <refsect1>
58 <title>Description</title>
59
60 <para>To query the current audio output applications zero out the
61<structfield>reserved</structfield> array of a &v4l2-audioout; and
62call the <constant>VIDIOC_G_AUDOUT</constant> ioctl with a pointer
63to this structure. Drivers fill the rest of the structure or return an
64&EINVAL; when the device has no audio inputs, or none which combine
65with the current video output.</para>
66
67 <para>Audio outputs have no writable properties. Nevertheless, to
68select the current audio output applications can initialize the
69<structfield>index</structfield> field and
70<structfield>reserved</structfield> array (which in the future may
71contain writable properties) of a
72<structname>v4l2_audioout</structname> structure and call the
73<constant>VIDIOC_S_AUDOUT</constant> ioctl. Drivers switch to the
74requested output or return the &EINVAL; when the index is out of
75bounds. This is a write-only ioctl, it does not return the current
76audio output attributes as <constant>VIDIOC_G_AUDOUT</constant>
77does.</para>
78
79 <para>Note connectors on a TV card to loop back the received audio
80signal to a sound card are not audio outputs in this sense.</para>
81
82 <table pgwide="1" frame="none" id="v4l2-audioout">
83 <title>struct <structname>v4l2_audioout</structname></title>
84 <tgroup cols="3">
85 &cs-str;
86 <tbody valign="top">
87 <row>
88 <entry>__u32</entry>
89 <entry><structfield>index</structfield></entry>
90 <entry>Identifies the audio output, set by the
91driver or application.</entry>
92 </row>
93 <row>
94 <entry>__u8</entry>
95 <entry><structfield>name</structfield>[32]</entry>
96 <entry>Name of the audio output, a NUL-terminated ASCII
97string, for example: "Line Out". This information is intended for the
98user, preferably the connector label on the device itself.</entry>
99 </row>
100 <row>
101 <entry>__u32</entry>
102 <entry><structfield>capability</structfield></entry>
103 <entry>Audio capability flags, none defined yet. Drivers
104must set this field to zero.</entry>
105 </row>
106 <row>
107 <entry>__u32</entry>
108 <entry><structfield>mode</structfield></entry>
109 <entry>Audio mode, none defined yet. Drivers and
110applications (on <constant>VIDIOC_S_AUDOUT</constant>) must set this
111field to zero.</entry>
112 </row>
113 <row>
114 <entry>__u32</entry>
115 <entry><structfield>reserved</structfield>[2]</entry>
116 <entry>Reserved for future extensions. Drivers and
117applications must set the array to zero.</entry>
118 </row>
119 </tbody>
120 </tgroup>
121 </table>
122 </refsect1>
123
124 <refsect1>
125 &return-value;
126
127 <variablelist>
128 <varlistentry>
129 <term><errorcode>EINVAL</errorcode></term>
130 <listitem>
131 <para>No audio outputs combine with the current video
132output, or the number of the selected audio output is out of bounds or
133it does not combine, or there are no audio outputs at all and the
134ioctl is not supported.</para>
135 </listitem>
136 </varlistentry>
137 <varlistentry>
138 <term><errorcode>EBUSY</errorcode></term>
139 <listitem>
140 <para>I/O is in progress, the output cannot be
141switched.</para>
142 </listitem>
143 </varlistentry>
144 </variablelist>
145 </refsect1>
146</refentry>
147
148<!--
149Local Variables:
150mode: sgml
151sgml-parent-document: "v4l2.sgml"
152indent-tabs-mode: nil
153End:
154-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-crop.xml b/Documentation/DocBook/v4l/vidioc-g-crop.xml
new file mode 100644
index 000000000000..d235b1dedbed
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-crop.xml
@@ -0,0 +1,143 @@
1<refentry id="vidioc-g-crop">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_CROP, VIDIOC_S_CROP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_CROP</refname>
9 <refname>VIDIOC_S_CROP</refname>
10 <refpurpose>Get or set the current cropping rectangle</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_crop *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>const struct v4l2_crop *<parameter>argp</parameter></paramdef>
28 </funcprototype>
29 </funcsynopsis>
30 </refsynopsisdiv>
31
32 <refsect1>
33 <title>Arguments</title>
34
35 <variablelist>
36 <varlistentry>
37 <term><parameter>fd</parameter></term>
38 <listitem>
39 <para>&fd;</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>request</parameter></term>
44 <listitem>
45 <para>VIDIOC_G_CROP, VIDIOC_S_CROP</para>
46 </listitem>
47 </varlistentry>
48 <varlistentry>
49 <term><parameter>argp</parameter></term>
50 <listitem>
51 <para></para>
52 </listitem>
53 </varlistentry>
54 </variablelist>
55 </refsect1>
56
57 <refsect1>
58 <title>Description</title>
59
60 <para>To query the cropping rectangle size and position
61applications set the <structfield>type</structfield> field of a
62<structname>v4l2_crop</structname> structure to the respective buffer
63(stream) type and call the <constant>VIDIOC_G_CROP</constant> ioctl
64with a pointer to this structure. The driver fills the rest of the
65structure or returns the &EINVAL; if cropping is not supported.</para>
66
67 <para>To change the cropping rectangle applications initialize the
68<structfield>type</structfield> and &v4l2-rect; substructure named
69<structfield>c</structfield> of a v4l2_crop structure and call the
70<constant>VIDIOC_S_CROP</constant> ioctl with a pointer to this
71structure.</para>
72
73 <para>The driver first adjusts the requested dimensions against
74hardware limits, &ie; the bounds given by the capture/output window,
75and it rounds to the closest possible values of horizontal and
76vertical offset, width and height. In particular the driver must round
77the vertical offset of the cropping rectangle to frame lines modulo
78two, such that the field order cannot be confused.</para>
79
80 <para>Second the driver adjusts the image size (the opposite
81rectangle of the scaling process, source or target depending on the
82data direction) to the closest size possible while maintaining the
83current horizontal and vertical scaling factor.</para>
84
85 <para>Finally the driver programs the hardware with the actual
86cropping and image parameters. <constant>VIDIOC_S_CROP</constant> is a
87write-only ioctl, it does not return the actual parameters. To query
88them applications must call <constant>VIDIOC_G_CROP</constant> and
89&VIDIOC-G-FMT;. When the parameters are unsuitable the application may
90modify the cropping or image parameters and repeat the cycle until
91satisfactory parameters have been negotiated.</para>
92
93 <para>When cropping is not supported then no parameters are
94changed and <constant>VIDIOC_S_CROP</constant> returns the
95&EINVAL;.</para>
96
97 <table pgwide="1" frame="none" id="v4l2-crop">
98 <title>struct <structname>v4l2_crop</structname></title>
99 <tgroup cols="3">
100 &cs-str;
101 <tbody valign="top">
102 <row>
103 <entry>&v4l2-buf-type;</entry>
104 <entry><structfield>type</structfield></entry>
105 <entry>Type of the data stream, set by the application.
106Only these types are valid here: <constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
107<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
108<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
109defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
110and higher.</entry>
111 </row>
112 <row>
113 <entry>&v4l2-rect;</entry>
114 <entry><structfield>c</structfield></entry>
115 <entry>Cropping rectangle. The same co-ordinate system as
116for &v4l2-cropcap; <structfield>bounds</structfield> is used.</entry>
117 </row>
118 </tbody>
119 </tgroup>
120 </table>
121 </refsect1>
122
123 <refsect1>
124 &return-value;
125
126 <variablelist>
127 <varlistentry>
128 <term><errorcode>EINVAL</errorcode></term>
129 <listitem>
130 <para>Cropping is not supported.</para>
131 </listitem>
132 </varlistentry>
133 </variablelist>
134 </refsect1>
135</refentry>
136
137<!--
138Local Variables:
139mode: sgml
140sgml-parent-document: "v4l2.sgml"
141indent-tabs-mode: nil
142End:
143-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-ctrl.xml b/Documentation/DocBook/v4l/vidioc-g-ctrl.xml
new file mode 100644
index 000000000000..8b5e6ff7f3df
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-ctrl.xml
@@ -0,0 +1,130 @@
1<refentry id="vidioc-g-ctrl">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_CTRL, VIDIOC_S_CTRL</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_CTRL</refname>
9 <refname>VIDIOC_S_CTRL</refname>
10 <refpurpose>Get or set the value of a control</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_control
20*<parameter>argp</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 </refsynopsisdiv>
24
25 <refsect1>
26 <title>Arguments</title>
27
28 <variablelist>
29 <varlistentry>
30 <term><parameter>fd</parameter></term>
31 <listitem>
32 <para>&fd;</para>
33 </listitem>
34 </varlistentry>
35 <varlistentry>
36 <term><parameter>request</parameter></term>
37 <listitem>
38 <para>VIDIOC_G_CTRL, VIDIOC_S_CTRL</para>
39 </listitem>
40 </varlistentry>
41 <varlistentry>
42 <term><parameter>argp</parameter></term>
43 <listitem>
44 <para></para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52
53 <para>To get the current value of a control applications
54initialize the <structfield>id</structfield> field of a struct
55<structname>v4l2_control</structname> and call the
56<constant>VIDIOC_G_CTRL</constant> ioctl with a pointer to this
57structure. To change the value of a control applications initialize
58the <structfield>id</structfield> and <structfield>value</structfield>
59fields of a struct <structname>v4l2_control</structname> and call the
60<constant>VIDIOC_S_CTRL</constant> ioctl.</para>
61
62 <para>When the <structfield>id</structfield> is invalid drivers
63return an &EINVAL;. When the <structfield>value</structfield> is out
64of bounds drivers can choose to take the closest valid value or return
65an &ERANGE;, whatever seems more appropriate. However,
66<constant>VIDIOC_S_CTRL</constant> is a write-only ioctl, it does not
67return the actual new value.</para>
68
69 <para>These ioctls work only with user controls. For other
70control classes the &VIDIOC-G-EXT-CTRLS;, &VIDIOC-S-EXT-CTRLS; or
71&VIDIOC-TRY-EXT-CTRLS; must be used.</para>
72
73 <table pgwide="1" frame="none" id="v4l2-control">
74 <title>struct <structname>v4l2_control</structname></title>
75 <tgroup cols="3">
76 &cs-str;
77 <tbody valign="top">
78 <row>
79 <entry>__u32</entry>
80 <entry><structfield>id</structfield></entry>
81 <entry>Identifies the control, set by the
82application.</entry>
83 </row>
84 <row>
85 <entry>__s32</entry>
86 <entry><structfield>value</structfield></entry>
87 <entry>New value or current value.</entry>
88 </row>
89 </tbody>
90 </tgroup>
91 </table>
92 </refsect1>
93
94 <refsect1>
95 &return-value;
96
97 <variablelist>
98 <varlistentry>
99 <term><errorcode>EINVAL</errorcode></term>
100 <listitem>
101 <para>The &v4l2-control; <structfield>id</structfield> is
102invalid.</para>
103 </listitem>
104 </varlistentry>
105 <varlistentry>
106 <term><errorcode>ERANGE</errorcode></term>
107 <listitem>
108 <para>The &v4l2-control; <structfield>value</structfield>
109is out of bounds.</para>
110 </listitem>
111 </varlistentry>
112 <varlistentry>
113 <term><errorcode>EBUSY</errorcode></term>
114 <listitem>
115 <para>The control is temporarily not changeable, possibly
116because another applications took over control of the device function
117this control belongs to.</para>
118 </listitem>
119 </varlistentry>
120 </variablelist>
121 </refsect1>
122</refentry>
123
124<!--
125Local Variables:
126mode: sgml
127sgml-parent-document: "v4l2.sgml"
128indent-tabs-mode: nil
129End:
130-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-enc-index.xml b/Documentation/DocBook/v4l/vidioc-g-enc-index.xml
new file mode 100644
index 000000000000..9f242e4b2948
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-enc-index.xml
@@ -0,0 +1,213 @@
1<refentry id="vidioc-g-enc-index">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_ENC_INDEX</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_ENC_INDEX</refname>
9 <refpurpose>Get meta data about a compressed video stream</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_enc_idx *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_G_ENC_INDEX</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <note>
52 <title>Experimental</title>
53
54 <para>This is an <link linkend="experimental">experimental</link>
55interface and may change in the future.</para>
56 </note>
57
58 <para>The <constant>VIDIOC_G_ENC_INDEX</constant> ioctl provides
59meta data about a compressed video stream the same or another
60application currently reads from the driver, which is useful for
61random access into the stream without decoding it.</para>
62
63 <para>To read the data applications must call
64<constant>VIDIOC_G_ENC_INDEX</constant> with a pointer to a
65&v4l2-enc-idx;. On success the driver fills the
66<structfield>entry</structfield> array, stores the number of elements
67written in the <structfield>entries</structfield> field, and
68initializes the <structfield>entries_cap</structfield> field.</para>
69
70 <para>Each element of the <structfield>entry</structfield> array
71contains meta data about one picture. A
72<constant>VIDIOC_G_ENC_INDEX</constant> call reads up to
73<constant>V4L2_ENC_IDX_ENTRIES</constant> entries from a driver
74buffer, which can hold up to <structfield>entries_cap</structfield>
75entries. This number can be lower or higher than
76<constant>V4L2_ENC_IDX_ENTRIES</constant>, but not zero. When the
77application fails to read the meta data in time the oldest entries
78will be lost. When the buffer is empty or no capturing/encoding is in
79progress, <structfield>entries</structfield> will be zero.</para>
80
81 <para>Currently this ioctl is only defined for MPEG-2 program
82streams and video elementary streams.</para>
83
84 <table pgwide="1" frame="none" id="v4l2-enc-idx">
85 <title>struct <structname>v4l2_enc_idx</structname></title>
86 <tgroup cols="3">
87 &cs-str;
88 <tbody valign="top">
89 <row>
90 <entry>__u32</entry>
91 <entry><structfield>entries</structfield></entry>
92 <entry>The number of entries the driver stored in the
93<structfield>entry</structfield> array.</entry>
94 </row>
95 <row>
96 <entry>__u32</entry>
97 <entry><structfield>entries_cap</structfield></entry>
98 <entry>The number of entries the driver can
99buffer. Must be greater than zero.</entry>
100 </row>
101 <row>
102 <entry>__u32</entry>
103 <entry><structfield>reserved</structfield>[4]</entry>
104 <entry spanname="hspan">Reserved for future extensions.
105Drivers must set the array to zero.</entry>
106 </row>
107 <row>
108 <entry>&v4l2-enc-idx-entry;</entry>
109 <entry><structfield>entry</structfield>[<constant>V4L2_ENC_IDX_ENTRIES</constant>]</entry>
110 <entry>Meta data about a compressed video stream. Each
111element of the array corresponds to one picture, sorted in ascending
112order by their <structfield>offset</structfield>.</entry>
113 </row>
114 </tbody>
115 </tgroup>
116 </table>
117
118 <table pgwide="1" frame="none" id="v4l2-enc-idx-entry">
119 <title>struct <structname>v4l2_enc_idx_entry</structname></title>
120 <tgroup cols="3">
121 &cs-str;
122 <tbody valign="top">
123 <row>
124 <entry>__u64</entry>
125 <entry><structfield>offset</structfield></entry>
126 <entry>The offset in bytes from the beginning of the
127compressed video stream to the beginning of this picture, that is a
128<wordasword>PES packet header</wordasword> as defined in <xref
129 linkend="mpeg2part1" /> or a <wordasword>picture
130header</wordasword> as defined in <xref linkend="mpeg2part2" />. When
131the encoder is stopped, the driver resets the offset to zero.</entry>
132 </row>
133 <row>
134 <entry>__u64</entry>
135 <entry><structfield>pts</structfield></entry>
136 <entry>The 33 bit <wordasword>Presentation Time
137Stamp</wordasword> of this picture as defined in <xref
138 linkend="mpeg2part1" />.</entry>
139 </row>
140 <row>
141 <entry>__u32</entry>
142 <entry><structfield>length</structfield></entry>
143 <entry>The length of this picture in bytes.</entry>
144 </row>
145 <row>
146 <entry>__u32</entry>
147 <entry><structfield>flags</structfield></entry>
148 <entry>Flags containing the coding type of this picture, see <xref
149 linkend="enc-idx-flags" />.</entry>
150 </row>
151 <row>
152 <entry>__u32</entry>
153 <entry><structfield>reserved</structfield>[2]</entry>
154 <entry>Reserved for future extensions.
155Drivers must set the array to zero.</entry>
156 </row>
157 </tbody>
158 </tgroup>
159 </table>
160
161 <table pgwide="1" frame="none" id="enc-idx-flags">
162 <title>Index Entry Flags</title>
163 <tgroup cols="3">
164 &cs-def;
165 <tbody valign="top">
166 <row>
167 <entry><constant>V4L2_ENC_IDX_FRAME_I</constant></entry>
168 <entry>0x00</entry>
169 <entry>This is an Intra-coded picture.</entry>
170 </row>
171 <row>
172 <entry><constant>V4L2_ENC_IDX_FRAME_P</constant></entry>
173 <entry>0x01</entry>
174 <entry>This is a Predictive-coded picture.</entry>
175 </row>
176 <row>
177 <entry><constant>V4L2_ENC_IDX_FRAME_B</constant></entry>
178 <entry>0x02</entry>
179 <entry>This is a Bidirectionally predictive-coded
180picture.</entry>
181 </row>
182 <row>
183 <entry><constant>V4L2_ENC_IDX_FRAME_MASK</constant></entry>
184 <entry>0x0F</entry>
185 <entry><wordasword>AND</wordasword> the flags field with
186this mask to obtain the picture coding type.</entry>
187 </row>
188 </tbody>
189 </tgroup>
190 </table>
191 </refsect1>
192
193 <refsect1>
194 &return-value;
195
196 <variablelist>
197 <varlistentry>
198 <term><errorcode>EINVAL</errorcode></term>
199 <listitem>
200 <para>The driver does not support this ioctl.</para>
201 </listitem>
202 </varlistentry>
203 </variablelist>
204 </refsect1>
205</refentry>
206
207<!--
208Local Variables:
209mode: sgml
210sgml-parent-document: "v4l2.sgml"
211indent-tabs-mode: nil
212End:
213-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml b/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml
new file mode 100644
index 000000000000..3aa7f8f9ff0c
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-ext-ctrls.xml
@@ -0,0 +1,307 @@
1<refentry id="vidioc-g-ext-ctrls">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS,
4VIDIOC_TRY_EXT_CTRLS</refentrytitle>
5 &manvol;
6 </refmeta>
7
8 <refnamediv>
9 <refname>VIDIOC_G_EXT_CTRLS</refname>
10 <refname>VIDIOC_S_EXT_CTRLS</refname>
11 <refname>VIDIOC_TRY_EXT_CTRLS</refname>
12 <refpurpose>Get or set the value of several controls, try control
13values</refpurpose>
14 </refnamediv>
15
16 <refsynopsisdiv>
17 <funcsynopsis>
18 <funcprototype>
19 <funcdef>int <function>ioctl</function></funcdef>
20 <paramdef>int <parameter>fd</parameter></paramdef>
21 <paramdef>int <parameter>request</parameter></paramdef>
22 <paramdef>struct v4l2_ext_controls
23*<parameter>argp</parameter></paramdef>
24 </funcprototype>
25 </funcsynopsis>
26 </refsynopsisdiv>
27
28 <refsect1>
29 <title>Arguments</title>
30
31 <variablelist>
32 <varlistentry>
33 <term><parameter>fd</parameter></term>
34 <listitem>
35 <para>&fd;</para>
36 </listitem>
37 </varlistentry>
38 <varlistentry>
39 <term><parameter>request</parameter></term>
40 <listitem>
41 <para>VIDIOC_G_EXT_CTRLS, VIDIOC_S_EXT_CTRLS,
42VIDIOC_TRY_EXT_CTRLS</para>
43 </listitem>
44 </varlistentry>
45 <varlistentry>
46 <term><parameter>argp</parameter></term>
47 <listitem>
48 <para></para>
49 </listitem>
50 </varlistentry>
51 </variablelist>
52 </refsect1>
53
54 <refsect1>
55 <title>Description</title>
56
57 <para>These ioctls allow the caller to get or set multiple
58controls atomically. Control IDs are grouped into control classes (see
59<xref linkend="ctrl-class" />) and all controls in the control array
60must belong to the same control class.</para>
61
62 <para>Applications must always fill in the
63<structfield>count</structfield>,
64<structfield>ctrl_class</structfield>,
65<structfield>controls</structfield> and
66<structfield>reserved</structfield> fields of &v4l2-ext-controls;, and
67initialize the &v4l2-ext-control; array pointed to by the
68<structfield>controls</structfield> fields.</para>
69
70 <para>To get the current value of a set of controls applications
71initialize the <structfield>id</structfield>,
72<structfield>size</structfield> and <structfield>reserved2</structfield> fields
73of each &v4l2-ext-control; and call the
74<constant>VIDIOC_G_EXT_CTRLS</constant> ioctl. String controls controls
75must also set the <structfield>string</structfield> field.</para>
76
77 <para>If the <structfield>size</structfield> is too small to
78receive the control result (only relevant for pointer-type controls
79like strings), then the driver will set <structfield>size</structfield>
80to a valid value and return an &ENOSPC;. You should re-allocate the
81string memory to this new size and try again. It is possible that the
82same issue occurs again if the string has grown in the meantime. It is
83recommended to call &VIDIOC-QUERYCTRL; first and use
84<structfield>maximum</structfield>+1 as the new <structfield>size</structfield>
85value. It is guaranteed that that is sufficient memory.
86</para>
87
88 <para>To change the value of a set of controls applications
89initialize the <structfield>id</structfield>, <structfield>size</structfield>,
90<structfield>reserved2</structfield> and
91<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
92call the <constant>VIDIOC_S_EXT_CTRLS</constant> ioctl. The controls
93will only be set if <emphasis>all</emphasis> control values are
94valid.</para>
95
96 <para>To check if a set of controls have correct values applications
97initialize the <structfield>id</structfield>, <structfield>size</structfield>,
98<structfield>reserved2</structfield> and
99<structfield>value/string</structfield> fields of each &v4l2-ext-control; and
100call the <constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctl. It is up to
101the driver whether wrong values are automatically adjusted to a valid
102value or if an error is returned.</para>
103
104 <para>When the <structfield>id</structfield> or
105<structfield>ctrl_class</structfield> is invalid drivers return an
106&EINVAL;. When the value is out of bounds drivers can choose to take
107the closest valid value or return an &ERANGE;, whatever seems more
108appropriate. In the first case the new value is set in
109&v4l2-ext-control;.</para>
110
111 <para>The driver will only set/get these controls if all control
112values are correct. This prevents the situation where only some of the
113controls were set/get. Only low-level errors (&eg; a failed i2c
114command) can still cause this situation.</para>
115
116 <table pgwide="1" frame="none" id="v4l2-ext-control">
117 <title>struct <structname>v4l2_ext_control</structname></title>
118 <tgroup cols="4">
119 &cs-ustr;
120 <tbody valign="top">
121 <row>
122 <entry>__u32</entry>
123 <entry><structfield>id</structfield></entry>
124 <entry></entry>
125 <entry>Identifies the control, set by the
126application.</entry>
127 </row>
128 <row>
129 <entry>__u32</entry>
130 <entry><structfield>size</structfield></entry>
131 <entry></entry>
132 <entry>The total size in bytes of the payload of this
133control. This is normally 0, but for pointer controls this should be
134set to the size of the memory containing the payload, or that will
135receive the payload. If <constant>VIDIOC_G_EXT_CTRLS</constant> finds
136that this value is less than is required to store
137the payload result, then it is set to a value large enough to store the
138payload result and ENOSPC is returned. Note that for string controls
139this <structfield>size</structfield> field should not be confused with the length of the string.
140This field refers to the size of the memory that contains the string.
141The actual <emphasis>length</emphasis> of the string may well be much smaller.
142</entry>
143 </row>
144 <row>
145 <entry>__u32</entry>
146 <entry><structfield>reserved2</structfield>[1]</entry>
147 <entry></entry>
148 <entry>Reserved for future extensions. Drivers and
149applications must set the array to zero.</entry>
150 </row>
151 <row>
152 <entry>union</entry>
153 <entry>(anonymous)</entry>
154 </row>
155 <row>
156 <entry></entry>
157 <entry>__s32</entry>
158 <entry><structfield>value</structfield></entry>
159 <entry>New value or current value.</entry>
160 </row>
161 <row>
162 <entry></entry>
163 <entry>__s64</entry>
164 <entry><structfield>value64</structfield></entry>
165 <entry>New value or current value.</entry>
166 </row>
167 <row>
168 <entry></entry>
169 <entry>char *</entry>
170 <entry><structfield>string</structfield></entry>
171 <entry>A pointer to a string.</entry>
172 </row>
173 </tbody>
174 </tgroup>
175 </table>
176
177 <table pgwide="1" frame="none" id="v4l2-ext-controls">
178 <title>struct <structname>v4l2_ext_controls</structname></title>
179 <tgroup cols="3">
180 &cs-str;
181 <tbody valign="top">
182 <row>
183 <entry>__u32</entry>
184 <entry><structfield>ctrl_class</structfield></entry>
185 <entry>The control class to which all controls belong, see
186<xref linkend="ctrl-class" />.</entry>
187 </row>
188 <row>
189 <entry>__u32</entry>
190 <entry><structfield>count</structfield></entry>
191 <entry>The number of controls in the controls array. May
192also be zero.</entry>
193 </row>
194 <row>
195 <entry>__u32</entry>
196 <entry><structfield>error_idx</structfield></entry>
197 <entry>Set by the driver in case of an error. It is the
198index of the control causing the error or equal to 'count' when the
199error is not associated with a particular control. Undefined when the
200ioctl returns 0 (success).</entry>
201 </row>
202 <row>
203 <entry>__u32</entry>
204 <entry><structfield>reserved</structfield>[2]</entry>
205 <entry>Reserved for future extensions. Drivers and
206applications must set the array to zero.</entry>
207 </row>
208 <row>
209 <entry>&v4l2-ext-control; *</entry>
210 <entry><structfield>controls</structfield></entry>
211 <entry>Pointer to an array of
212<structfield>count</structfield> v4l2_ext_control structures. Ignored
213if <structfield>count</structfield> equals zero.</entry>
214 </row>
215 </tbody>
216 </tgroup>
217 </table>
218
219 <table pgwide="1" frame="none" id="ctrl-class">
220 <title>Control classes</title>
221 <tgroup cols="3">
222 &cs-def;
223 <tbody valign="top">
224 <row>
225 <entry><constant>V4L2_CTRL_CLASS_USER</constant></entry>
226 <entry>0x980000</entry>
227 <entry>The class containing user controls. These controls
228are described in <xref linkend="control" />. All controls that can be set
229using the &VIDIOC-S-CTRL; and &VIDIOC-G-CTRL; ioctl belong to this
230class.</entry>
231 </row>
232 <row>
233 <entry><constant>V4L2_CTRL_CLASS_MPEG</constant></entry>
234 <entry>0x990000</entry>
235 <entry>The class containing MPEG compression controls.
236These controls are described in <xref
237 linkend="mpeg-controls" />.</entry>
238 </row>
239 <row>
240 <entry><constant>V4L2_CTRL_CLASS_CAMERA</constant></entry>
241 <entry>0x9a0000</entry>
242 <entry>The class containing camera controls.
243These controls are described in <xref
244 linkend="camera-controls" />.</entry>
245 </row>
246 <row>
247 <entry><constant>V4L2_CTRL_CLASS_FM_TX</constant></entry>
248 <entry>0x9b0000</entry>
249 <entry>The class containing FM Transmitter (FM TX) controls.
250These controls are described in <xref
251 linkend="fm-tx-controls" />.</entry>
252 </row>
253 </tbody>
254 </tgroup>
255 </table>
256
257 </refsect1>
258
259 <refsect1>
260 &return-value;
261
262 <variablelist>
263 <varlistentry>
264 <term><errorcode>EINVAL</errorcode></term>
265 <listitem>
266 <para>The &v4l2-ext-control; <structfield>id</structfield>
267is invalid or the &v4l2-ext-controls;
268<structfield>ctrl_class</structfield> is invalid. This error code is
269also returned by the <constant>VIDIOC_S_EXT_CTRLS</constant> and
270<constant>VIDIOC_TRY_EXT_CTRLS</constant> ioctls if two or more
271control values are in conflict.</para>
272 </listitem>
273 </varlistentry>
274 <varlistentry>
275 <term><errorcode>ERANGE</errorcode></term>
276 <listitem>
277 <para>The &v4l2-ext-control; <structfield>value</structfield>
278is out of bounds.</para>
279 </listitem>
280 </varlistentry>
281 <varlistentry>
282 <term><errorcode>EBUSY</errorcode></term>
283 <listitem>
284 <para>The control is temporarily not changeable, possibly
285because another applications took over control of the device function
286this control belongs to.</para>
287 </listitem>
288 </varlistentry>
289 <varlistentry>
290 <term><errorcode>ENOSPC</errorcode></term>
291 <listitem>
292 <para>The space reserved for the control's payload is insufficient.
293The field <structfield>size</structfield> is set to a value that is enough
294to store the payload and this error code is returned.</para>
295 </listitem>
296 </varlistentry>
297 </variablelist>
298 </refsect1>
299</refentry>
300
301<!--
302Local Variables:
303mode: sgml
304sgml-parent-document: "v4l2.sgml"
305indent-tabs-mode: nil
306End:
307-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-fbuf.xml b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
new file mode 100644
index 000000000000..f7017062656e
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-fbuf.xml
@@ -0,0 +1,456 @@
1<refentry id="vidioc-g-fbuf">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_FBUF, VIDIOC_S_FBUF</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_FBUF</refname>
9 <refname>VIDIOC_S_FBUF</refname>
10 <refpurpose>Get or set frame buffer overlay parameters</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_framebuffer *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>const struct v4l2_framebuffer *<parameter>argp</parameter></paramdef>
28 </funcprototype>
29 </funcsynopsis>
30 </refsynopsisdiv>
31
32 <refsect1>
33 <title>Arguments</title>
34
35 <variablelist>
36 <varlistentry>
37 <term><parameter>fd</parameter></term>
38 <listitem>
39 <para>&fd;</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>request</parameter></term>
44 <listitem>
45 <para>VIDIOC_G_FBUF, VIDIOC_S_FBUF</para>
46 </listitem>
47 </varlistentry>
48 <varlistentry>
49 <term><parameter>argp</parameter></term>
50 <listitem>
51 <para></para>
52 </listitem>
53 </varlistentry>
54 </variablelist>
55 </refsect1>
56
57 <refsect1>
58 <title>Description</title>
59
60 <para>Applications can use the <constant>VIDIOC_G_FBUF</constant> and
61<constant>VIDIOC_S_FBUF</constant> ioctl to get and set the
62framebuffer parameters for a <link linkend="overlay">Video
63Overlay</link> or <link linkend="osd">Video Output Overlay</link>
64(OSD). The type of overlay is implied by the device type (capture or
65output device) and can be determined with the &VIDIOC-QUERYCAP; ioctl.
66One <filename>/dev/videoN</filename> device must not support both
67kinds of overlay.</para>
68
69 <para>The V4L2 API distinguishes destructive and non-destructive
70overlays. A destructive overlay copies captured video images into the
71video memory of a graphics card. A non-destructive overlay blends
72video images into a VGA signal or graphics into a video signal.
73<wordasword>Video Output Overlays</wordasword> are always
74non-destructive.</para>
75
76 <para>To get the current parameters applications call the
77<constant>VIDIOC_G_FBUF</constant> ioctl with a pointer to a
78<structname>v4l2_framebuffer</structname> structure. The driver fills
79all fields of the structure or returns an &EINVAL; when overlays are
80not supported.</para>
81
82 <para>To set the parameters for a <wordasword>Video Output
83Overlay</wordasword>, applications must initialize the
84<structfield>flags</structfield> field of a struct
85<structname>v4l2_framebuffer</structname>. Since the framebuffer is
86implemented on the TV card all other parameters are determined by the
87driver. When an application calls <constant>VIDIOC_S_FBUF</constant>
88with a pointer to this structure, the driver prepares for the overlay
89and returns the framebuffer parameters as
90<constant>VIDIOC_G_FBUF</constant> does, or it returns an error
91code.</para>
92
93 <para>To set the parameters for a <wordasword>non-destructive
94Video Overlay</wordasword>, applications must initialize the
95<structfield>flags</structfield> field, the
96<structfield>fmt</structfield> substructure, and call
97<constant>VIDIOC_S_FBUF</constant>. Again the driver prepares for the
98overlay and returns the framebuffer parameters as
99<constant>VIDIOC_G_FBUF</constant> does, or it returns an error
100code.</para>
101
102 <para>For a <wordasword>destructive Video Overlay</wordasword>
103applications must additionally provide a
104<structfield>base</structfield> address. Setting up a DMA to a
105random memory location can jeopardize the system security, its
106stability or even damage the hardware, therefore only the superuser
107can set the parameters for a destructive video overlay.</para>
108
109 <!-- NB v4l2_pix_format is also specified in pixfmt.sgml.-->
110
111 <table pgwide="1" frame="none" id="v4l2-framebuffer">
112 <title>struct <structname>v4l2_framebuffer</structname></title>
113 <tgroup cols="4">
114 &cs-ustr;
115 <tbody valign="top">
116 <row>
117 <entry>__u32</entry>
118 <entry><structfield>capability</structfield></entry>
119 <entry></entry>
120 <entry>Overlay capability flags set by the driver, see
121<xref linkend="framebuffer-cap" />.</entry>
122 </row>
123 <row>
124 <entry>__u32</entry>
125 <entry><structfield>flags</structfield></entry>
126 <entry></entry>
127 <entry>Overlay control flags set by application and
128driver, see <xref linkend="framebuffer-flags" /></entry>
129 </row>
130 <row>
131 <entry>void *</entry>
132 <entry><structfield>base</structfield></entry>
133 <entry></entry>
134 <entry>Physical base address of the framebuffer,
135that is the address of the pixel in the top left corner of the
136framebuffer.<footnote><para>A physical base address may not suit all
137platforms. GK notes in theory we should pass something like PCI device
138+ memory region + offset instead. If you encounter problems please
139discuss on the linux-media mailing list: &v4l-ml;.</para></footnote></entry>
140 </row>
141 <row>
142 <entry></entry>
143 <entry></entry>
144 <entry></entry>
145 <entry>This field is irrelevant to
146<wordasword>non-destructive Video Overlays</wordasword>. For
147<wordasword>destructive Video Overlays</wordasword> applications must
148provide a base address. The driver may accept only base addresses
149which are a multiple of two, four or eight bytes. For
150<wordasword>Video Output Overlays</wordasword> the driver must return
151a valid base address, so applications can find the corresponding Linux
152framebuffer device (see <xref linkend="osd" />).</entry>
153 </row>
154 <row>
155 <entry>&v4l2-pix-format;</entry>
156 <entry><structfield>fmt</structfield></entry>
157 <entry></entry>
158 <entry>Layout of the frame buffer. The
159<structname>v4l2_pix_format</structname> structure is defined in <xref
160linkend="pixfmt" />, for clarification the fields and acceptable values
161 are listed below:</entry>
162 </row>
163 <row>
164 <entry></entry>
165 <entry>__u32</entry>
166 <entry><structfield>width</structfield></entry>
167 <entry>Width of the frame buffer in pixels.</entry>
168 </row>
169 <row>
170 <entry></entry>
171 <entry>__u32</entry>
172 <entry><structfield>height</structfield></entry>
173 <entry>Height of the frame buffer in pixels.</entry>
174 </row>
175 <row>
176 <entry></entry>
177 <entry>__u32</entry>
178 <entry><structfield>pixelformat</structfield></entry>
179 <entry>The pixel format of the
180framebuffer.</entry>
181 </row>
182 <row>
183 <entry></entry>
184 <entry></entry>
185 <entry></entry>
186 <entry>For <wordasword>non-destructive Video
187Overlays</wordasword> this field only defines a format for the
188&v4l2-window; <structfield>chromakey</structfield> field.</entry>
189 </row>
190 <row>
191 <entry></entry>
192 <entry></entry>
193 <entry></entry>
194 <entry>For <wordasword>destructive Video
195Overlays</wordasword> applications must initialize this field. For
196<wordasword>Video Output Overlays</wordasword> the driver must return
197a valid format.</entry>
198 </row>
199 <row>
200 <entry></entry>
201 <entry></entry>
202 <entry></entry>
203 <entry>Usually this is an RGB format (for example
204<link linkend="V4L2-PIX-FMT-RGB565"><constant>V4L2_PIX_FMT_RGB565</constant></link>)
205but YUV formats (only packed YUV formats when chroma keying is used,
206not including <constant>V4L2_PIX_FMT_YUYV</constant> and
207<constant>V4L2_PIX_FMT_UYVY</constant>) and the
208<constant>V4L2_PIX_FMT_PAL8</constant> format are also permitted. The
209behavior of the driver when an application requests a compressed
210format is undefined. See <xref linkend="pixfmt" /> for information on
211pixel formats.</entry>
212 </row>
213 <row>
214 <entry></entry>
215 <entry>&v4l2-field;</entry>
216 <entry><structfield>field</structfield></entry>
217 <entry>Drivers and applications shall ignore this field.
218If applicable, the field order is selected with the &VIDIOC-S-FMT;
219ioctl, using the <structfield>field</structfield> field of
220&v4l2-window;.</entry>
221 </row>
222 <row>
223 <entry></entry>
224 <entry>__u32</entry>
225 <entry><structfield>bytesperline</structfield></entry>
226 <entry>Distance in bytes between the leftmost pixels in
227two adjacent lines.</entry>
228 </row>
229 <row>
230 <entry spanname="hspan"><para>This field is irrelevant to
231<wordasword>non-destructive Video
232Overlays</wordasword>.</para><para>For <wordasword>destructive Video
233Overlays</wordasword> both applications and drivers can set this field
234to request padding bytes at the end of each line. Drivers however may
235ignore the requested value, returning <structfield>width</structfield>
236times bytes-per-pixel or a larger value required by the hardware. That
237implies applications can just set this field to zero to get a
238reasonable default.</para><para>For <wordasword>Video Output
239Overlays</wordasword> the driver must return a valid
240value.</para><para>Video hardware may access padding bytes, therefore
241they must reside in accessible memory. Consider for example the case
242where padding bytes after the last line of an image cross a system
243page boundary. Capture devices may write padding bytes, the value is
244undefined. Output devices ignore the contents of padding
245bytes.</para><para>When the image format is planar the
246<structfield>bytesperline</structfield> value applies to the largest
247plane and is divided by the same factor as the
248<structfield>width</structfield> field for any smaller planes. For
249example the Cb and Cr planes of a YUV 4:2:0 image have half as many
250padding bytes following each line as the Y plane. To avoid ambiguities
251drivers must return a <structfield>bytesperline</structfield> value
252rounded up to a multiple of the scale factor.</para></entry>
253 </row>
254 <row>
255 <entry></entry>
256 <entry>__u32</entry>
257 <entry><structfield>sizeimage</structfield></entry>
258 <entry><para>This field is irrelevant to
259<wordasword>non-destructive Video Overlays</wordasword>. For
260<wordasword>destructive Video Overlays</wordasword> applications must
261initialize this field. For <wordasword>Video Output
262Overlays</wordasword> the driver must return a valid
263format.</para><para>Together with <structfield>base</structfield> it
264defines the framebuffer memory accessible by the
265driver.</para></entry>
266 </row>
267 <row>
268 <entry></entry>
269 <entry>&v4l2-colorspace;</entry>
270 <entry><structfield>colorspace</structfield></entry>
271 <entry>This information supplements the
272<structfield>pixelformat</structfield> and must be set by the driver,
273see <xref linkend="colorspaces" />.</entry>
274 </row>
275 <row>
276 <entry></entry>
277 <entry>__u32</entry>
278 <entry><structfield>priv</structfield></entry>
279 <entry>Reserved for additional information about custom
280(driver defined) formats. When not used drivers and applications must
281set this field to zero.</entry>
282 </row>
283 </tbody>
284 </tgroup>
285 </table>
286
287 <table pgwide="1" frame="none" id="framebuffer-cap">
288 <title>Frame Buffer Capability Flags</title>
289 <tgroup cols="3">
290 &cs-def;
291 <tbody valign="top">
292 <row>
293 <entry><constant>V4L2_FBUF_CAP_EXTERNOVERLAY</constant></entry>
294 <entry>0x0001</entry>
295 <entry>The device is capable of non-destructive overlays.
296When the driver clears this flag, only destructive overlays are
297supported. There are no drivers yet which support both destructive and
298non-destructive overlays.</entry>
299 </row>
300 <row>
301 <entry><constant>V4L2_FBUF_CAP_CHROMAKEY</constant></entry>
302 <entry>0x0002</entry>
303 <entry>The device supports clipping by chroma-keying the
304images. That is, image pixels replace pixels in the VGA or video
305signal only where the latter assume a certain color. Chroma-keying
306makes no sense for destructive overlays.</entry>
307 </row>
308 <row>
309 <entry><constant>V4L2_FBUF_CAP_LIST_CLIPPING</constant></entry>
310 <entry>0x0004</entry>
311 <entry>The device supports clipping using a list of clip
312rectangles.</entry>
313 </row>
314 <row>
315 <entry><constant>V4L2_FBUF_CAP_BITMAP_CLIPPING</constant></entry>
316 <entry>0x0008</entry>
317 <entry>The device supports clipping using a bit mask.</entry>
318 </row>
319 <row>
320 <entry><constant>V4L2_FBUF_CAP_LOCAL_ALPHA</constant></entry>
321 <entry>0x0010</entry>
322 <entry>The device supports clipping/blending using the
323alpha channel of the framebuffer or VGA signal. Alpha blending makes
324no sense for destructive overlays.</entry>
325 </row>
326 <row>
327 <entry><constant>V4L2_FBUF_CAP_GLOBAL_ALPHA</constant></entry>
328 <entry>0x0020</entry>
329 <entry>The device supports alpha blending using a global
330alpha value. Alpha blending makes no sense for destructive overlays.</entry>
331 </row>
332 <row>
333 <entry><constant>V4L2_FBUF_CAP_LOCAL_INV_ALPHA</constant></entry>
334 <entry>0x0040</entry>
335 <entry>The device supports clipping/blending using the
336inverted alpha channel of the framebuffer or VGA signal. Alpha
337blending makes no sense for destructive overlays.</entry>
338 </row>
339 </tbody>
340 </tgroup>
341 </table>
342
343 <table pgwide="1" frame="none" id="framebuffer-flags">
344 <title>Frame Buffer Flags</title>
345 <tgroup cols="3">
346 &cs-def;
347 <tbody valign="top">
348 <row>
349 <entry><constant>V4L2_FBUF_FLAG_PRIMARY</constant></entry>
350 <entry>0x0001</entry>
351 <entry>The framebuffer is the primary graphics surface.
352In other words, the overlay is destructive. [?]</entry>
353 </row>
354 <row>
355 <entry><constant>V4L2_FBUF_FLAG_OVERLAY</constant></entry>
356 <entry>0x0002</entry>
357 <entry>The frame buffer is an overlay surface the same
358size as the capture. [?]</entry>
359 </row>
360 <row>
361 <entry spanname="hspan">The purpose of
362<constant>V4L2_FBUF_FLAG_PRIMARY</constant> and
363<constant>V4L2_FBUF_FLAG_OVERLAY</constant> was never quite clear.
364Most drivers seem to ignore these flags. For compatibility with the
365<wordasword>bttv</wordasword> driver applications should set the
366<constant>V4L2_FBUF_FLAG_OVERLAY</constant> flag.</entry>
367 </row>
368 <row>
369 <entry><constant>V4L2_FBUF_FLAG_CHROMAKEY</constant></entry>
370 <entry>0x0004</entry>
371 <entry>Use chroma-keying. The chroma-key color is
372determined by the <structfield>chromakey</structfield> field of
373&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
374 linkend="overlay" />
375and
376 <xref linkend="osd" />.</entry>
377 </row>
378 <row>
379 <entry spanname="hspan">There are no flags to enable
380clipping using a list of clip rectangles or a bitmap. These methods
381are negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
382 linkend="overlay" /> and <xref linkend="osd" />.</entry>
383 </row>
384 <row>
385 <entry><constant>V4L2_FBUF_FLAG_LOCAL_ALPHA</constant></entry>
386 <entry>0x0008</entry>
387 <entry>Use the alpha channel of the framebuffer to clip or
388blend framebuffer pixels with video images. The blend
389function is: output = framebuffer pixel * alpha + video pixel * (1 -
390alpha). The actual alpha depth depends on the framebuffer pixel
391format.</entry>
392 </row>
393 <row>
394 <entry><constant>V4L2_FBUF_FLAG_GLOBAL_ALPHA</constant></entry>
395 <entry>0x0010</entry>
396 <entry>Use a global alpha value to blend the framebuffer
397with video images. The blend function is: output = (framebuffer pixel
398* alpha + video pixel * (255 - alpha)) / 255. The alpha value is
399determined by the <structfield>global_alpha</structfield> field of
400&v4l2-window; and negotiated with the &VIDIOC-S-FMT; ioctl, see <xref
401 linkend="overlay" />
402and <xref linkend="osd" />.</entry>
403 </row>
404 <row>
405 <entry><constant>V4L2_FBUF_FLAG_LOCAL_INV_ALPHA</constant></entry>
406 <entry>0x0020</entry>
407 <entry>Like
408<constant>V4L2_FBUF_FLAG_LOCAL_ALPHA</constant>, use the alpha channel
409of the framebuffer to clip or blend framebuffer pixels with video
410images, but with an inverted alpha value. The blend function is:
411output = framebuffer pixel * (1 - alpha) + video pixel * alpha. The
412actual alpha depth depends on the framebuffer pixel format.</entry>
413 </row>
414 </tbody>
415 </tgroup>
416 </table>
417 </refsect1>
418
419 <refsect1>
420 &return-value;
421
422 <variablelist>
423 <varlistentry>
424 <term><errorcode>EPERM</errorcode></term>
425 <listitem>
426 <para><constant>VIDIOC_S_FBUF</constant> can only be called
427by a privileged user to negotiate the parameters for a destructive
428overlay.</para>
429 </listitem>
430 </varlistentry>
431 <varlistentry>
432 <term><errorcode>EBUSY</errorcode></term>
433 <listitem>
434 <para>The framebuffer parameters cannot be changed at this
435time because overlay is already enabled, or capturing is enabled
436and the hardware cannot capture and overlay simultaneously.</para>
437 </listitem>
438 </varlistentry>
439 <varlistentry>
440 <term><errorcode>EINVAL</errorcode></term>
441 <listitem>
442 <para>The ioctl is not supported or the
443<constant>VIDIOC_S_FBUF</constant> parameters are unsuitable.</para>
444 </listitem>
445 </varlistentry>
446 </variablelist>
447 </refsect1>
448</refentry>
449
450<!--
451Local Variables:
452mode: sgml
453sgml-parent-document: "v4l2.sgml"
454indent-tabs-mode: nil
455End:
456-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
new file mode 100644
index 000000000000..7c7d1b72c40d
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
@@ -0,0 +1,201 @@
1<refentry id="vidioc-g-fmt">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_FMT, VIDIOC_S_FMT,
4VIDIOC_TRY_FMT</refentrytitle>
5 &manvol;
6 </refmeta>
7
8 <refnamediv>
9 <refname>VIDIOC_G_FMT</refname>
10 <refname>VIDIOC_S_FMT</refname>
11 <refname>VIDIOC_TRY_FMT</refname>
12 <refpurpose>Get or set the data format, try a format</refpurpose>
13 </refnamediv>
14
15 <refsynopsisdiv>
16 <funcsynopsis>
17 <funcprototype>
18 <funcdef>int <function>ioctl</function></funcdef>
19 <paramdef>int <parameter>fd</parameter></paramdef>
20 <paramdef>int <parameter>request</parameter></paramdef>
21 <paramdef>struct v4l2_format
22*<parameter>argp</parameter></paramdef>
23 </funcprototype>
24 </funcsynopsis>
25 </refsynopsisdiv>
26
27 <refsect1>
28 <title>Arguments</title>
29
30 <variablelist>
31 <varlistentry>
32 <term><parameter>fd</parameter></term>
33 <listitem>
34 <para>&fd;</para>
35 </listitem>
36 </varlistentry>
37 <varlistentry>
38 <term><parameter>request</parameter></term>
39 <listitem>
40 <para>VIDIOC_G_FMT, VIDIOC_S_FMT, VIDIOC_TRY_FMT</para>
41 </listitem>
42 </varlistentry>
43 <varlistentry>
44 <term><parameter>argp</parameter></term>
45 <listitem>
46 <para></para>
47 </listitem>
48 </varlistentry>
49 </variablelist>
50 </refsect1>
51
52 <refsect1>
53 <title>Description</title>
54
55 <para>These ioctls are used to negotiate the format of data
56(typically image format) exchanged between driver and
57application.</para>
58
59 <para>To query the current parameters applications set the
60<structfield>type</structfield> field of a struct
61<structname>v4l2_format</structname> to the respective buffer (stream)
62type. For example video capture devices use
63<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>. When the application
64calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to
65this structure the driver fills the respective member of the
66<structfield>fmt</structfield> union. In case of video capture devices
67that is the &v4l2-pix-format; <structfield>pix</structfield> member.
68When the requested buffer type is not supported drivers return an
69&EINVAL;.</para>
70
71 <para>To change the current format parameters applications
72initialize the <structfield>type</structfield> field and all
73fields of the respective <structfield>fmt</structfield>
74union member. For details see the documentation of the various devices
75types in <xref linkend="devices" />. Good practice is to query the
76current parameters first, and to
77modify only those parameters not suitable for the application. When
78the application calls the <constant>VIDIOC_S_FMT</constant> ioctl
79with a pointer to a <structname>v4l2_format</structname> structure
80the driver checks
81and adjusts the parameters against hardware abilities. Drivers
82should not return an error code unless the input is ambiguous, this is
83a mechanism to fathom device capabilities and to approach parameters
84acceptable for both the application and driver. On success the driver
85may program the hardware, allocate resources and generally prepare for
86data exchange.
87Finally the <constant>VIDIOC_S_FMT</constant> ioctl returns the
88current format parameters as <constant>VIDIOC_G_FMT</constant> does.
89Very simple, inflexible devices may even ignore all input and always
90return the default parameters. However all V4L2 devices exchanging
91data with the application must implement the
92<constant>VIDIOC_G_FMT</constant> and
93<constant>VIDIOC_S_FMT</constant> ioctl. When the requested buffer
94type is not supported drivers return an &EINVAL; on a
95<constant>VIDIOC_S_FMT</constant> attempt. When I/O is already in
96progress or the resource is not available for other reasons drivers
97return the &EBUSY;.</para>
98
99 <para>The <constant>VIDIOC_TRY_FMT</constant> ioctl is equivalent
100to <constant>VIDIOC_S_FMT</constant> with one exception: it does not
101change driver state. It can also be called at any time, never
102returning <errorcode>EBUSY</errorcode>. This function is provided to
103negotiate parameters, to learn about hardware limitations, without
104disabling I/O or possibly time consuming hardware preparations.
105Although strongly recommended drivers are not required to implement
106this ioctl.</para>
107
108 <table pgwide="1" frame="none" id="v4l2-format">
109 <title>struct <structname>v4l2_format</structname></title>
110 <tgroup cols="4">
111 <colspec colname="c1" />
112 <colspec colname="c2" />
113 <colspec colname="c3" />
114 <colspec colname="c4" />
115 <tbody valign="top">
116 <row>
117 <entry>&v4l2-buf-type;</entry>
118 <entry><structfield>type</structfield></entry>
119 <entry></entry>
120 <entry>Type of the data stream, see <xref
121 linkend="v4l2-buf-type" />.</entry>
122 </row>
123 <row>
124 <entry>union</entry>
125 <entry><structfield>fmt</structfield></entry>
126 </row>
127 <row>
128 <entry></entry>
129 <entry>&v4l2-pix-format;</entry>
130 <entry><structfield>pix</structfield></entry>
131 <entry>Definition of an image format, see <xref
132 linkend="pixfmt" />, used by video capture and output
133devices.</entry>
134 </row>
135 <row>
136 <entry></entry>
137 <entry>&v4l2-window;</entry>
138 <entry><structfield>win</structfield></entry>
139 <entry>Definition of an overlaid image, see <xref
140 linkend="overlay" />, used by video overlay devices.</entry>
141 </row>
142 <row>
143 <entry></entry>
144 <entry>&v4l2-vbi-format;</entry>
145 <entry><structfield>vbi</structfield></entry>
146 <entry>Raw VBI capture or output parameters. This is
147discussed in more detail in <xref linkend="raw-vbi" />. Used by raw VBI
148capture and output devices.</entry>
149 </row>
150 <row>
151 <entry></entry>
152 <entry>&v4l2-sliced-vbi-format;</entry>
153 <entry><structfield>sliced</structfield></entry>
154 <entry>Sliced VBI capture or output parameters. See
155<xref linkend="sliced" /> for details. Used by sliced VBI
156capture and output devices.</entry>
157 </row>
158 <row>
159 <entry></entry>
160 <entry>__u8</entry>
161 <entry><structfield>raw_data</structfield>[200]</entry>
162 <entry>Place holder for future extensions and custom
163(driver defined) formats with <structfield>type</structfield>
164<constant>V4L2_BUF_TYPE_PRIVATE</constant> and higher.</entry>
165 </row>
166 </tbody>
167 </tgroup>
168 </table>
169 </refsect1>
170
171 <refsect1>
172 &return-value;
173
174 <variablelist>
175 <varlistentry>
176 <term><errorcode>EBUSY</errorcode></term>
177 <listitem>
178 <para>The data format cannot be changed at this
179time, for example because I/O is already in progress.</para>
180 </listitem>
181 </varlistentry>
182 <varlistentry>
183 <term><errorcode>EINVAL</errorcode></term>
184 <listitem>
185 <para>The &v4l2-format; <structfield>type</structfield>
186field is invalid, the requested buffer type not supported, or
187<constant>VIDIOC_TRY_FMT</constant> was called and is not
188supported with this buffer type.</para>
189 </listitem>
190 </varlistentry>
191 </variablelist>
192 </refsect1>
193</refentry>
194
195<!--
196Local Variables:
197mode: sgml
198sgml-parent-document: "v4l2.sgml"
199indent-tabs-mode: nil
200End:
201-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-frequency.xml b/Documentation/DocBook/v4l/vidioc-g-frequency.xml
new file mode 100644
index 000000000000..062d72069090
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-frequency.xml
@@ -0,0 +1,145 @@
1<refentry id="vidioc-g-frequency">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_FREQUENCY</refname>
9 <refname>VIDIOC_S_FREQUENCY</refname>
10 <refpurpose>Get or set tuner or modulator radio
11frequency</refpurpose>
12 </refnamediv>
13
14 <refsynopsisdiv>
15 <funcsynopsis>
16 <funcprototype>
17 <funcdef>int <function>ioctl</function></funcdef>
18 <paramdef>int <parameter>fd</parameter></paramdef>
19 <paramdef>int <parameter>request</parameter></paramdef>
20 <paramdef>struct v4l2_frequency
21*<parameter>argp</parameter></paramdef>
22 </funcprototype>
23 </funcsynopsis>
24 <funcsynopsis>
25 <funcprototype>
26 <funcdef>int <function>ioctl</function></funcdef>
27 <paramdef>int <parameter>fd</parameter></paramdef>
28 <paramdef>int <parameter>request</parameter></paramdef>
29 <paramdef>const struct v4l2_frequency
30*<parameter>argp</parameter></paramdef>
31 </funcprototype>
32 </funcsynopsis>
33 </refsynopsisdiv>
34
35 <refsect1>
36 <title>Arguments</title>
37
38 <variablelist>
39 <varlistentry>
40 <term><parameter>fd</parameter></term>
41 <listitem>
42 <para>&fd;</para>
43 </listitem>
44 </varlistentry>
45 <varlistentry>
46 <term><parameter>request</parameter></term>
47 <listitem>
48 <para>VIDIOC_G_FREQUENCY, VIDIOC_S_FREQUENCY</para>
49 </listitem>
50 </varlistentry>
51 <varlistentry>
52 <term><parameter>argp</parameter></term>
53 <listitem>
54 <para></para>
55 </listitem>
56 </varlistentry>
57 </variablelist>
58 </refsect1>
59
60 <refsect1>
61 <title>Description</title>
62
63 <para>To get the current tuner or modulator radio frequency
64applications set the <structfield>tuner</structfield> field of a
65&v4l2-frequency; to the respective tuner or modulator number (only
66input devices have tuners, only output devices have modulators), zero
67out the <structfield>reserved</structfield> array and
68call the <constant>VIDIOC_G_FREQUENCY</constant> ioctl with a pointer
69to this structure. The driver stores the current frequency in the
70<structfield>frequency</structfield> field.</para>
71
72 <para>To change the current tuner or modulator radio frequency
73applications initialize the <structfield>tuner</structfield>,
74<structfield>type</structfield> and
75<structfield>frequency</structfield> fields, and the
76<structfield>reserved</structfield> array of a &v4l2-frequency; and
77call the <constant>VIDIOC_S_FREQUENCY</constant> ioctl with a pointer
78to this structure. When the requested frequency is not possible the
79driver assumes the closest possible value. However
80<constant>VIDIOC_S_FREQUENCY</constant> is a write-only ioctl, it does
81not return the actual new frequency.</para>
82
83 <table pgwide="1" frame="none" id="v4l2-frequency">
84 <title>struct <structname>v4l2_frequency</structname></title>
85 <tgroup cols="3">
86 &cs-str;
87 <tbody valign="top">
88 <row>
89 <entry>__u32</entry>
90 <entry><structfield>tuner</structfield></entry>
91 <entry>The tuner or modulator index number. This is the
92same value as in the &v4l2-input; <structfield>tuner</structfield>
93field and the &v4l2-tuner; <structfield>index</structfield> field, or
94the &v4l2-output; <structfield>modulator</structfield> field and the
95&v4l2-modulator; <structfield>index</structfield> field.</entry>
96 </row>
97 <row>
98 <entry>&v4l2-tuner-type;</entry>
99 <entry><structfield>type</structfield></entry>
100 <entry>The tuner type. This is the same value as in the
101&v4l2-tuner; <structfield>type</structfield> field. The field is not
102applicable to modulators, &ie; ignored by drivers.</entry>
103 </row>
104 <row>
105 <entry>__u32</entry>
106 <entry><structfield>frequency</structfield></entry>
107 <entry>Tuning frequency in units of 62.5 kHz, or if the
108&v4l2-tuner; or &v4l2-modulator; <structfield>capabilities</structfield> flag
109<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
110Hz.</entry>
111 </row>
112 <row>
113 <entry>__u32</entry>
114 <entry><structfield>reserved</structfield>[8]</entry>
115 <entry>Reserved for future extensions. Drivers and
116 applications must set the array to zero.</entry>
117 </row>
118 </tbody>
119 </tgroup>
120 </table>
121 </refsect1>
122
123 <refsect1>
124 &return-value;
125
126 <variablelist>
127 <varlistentry>
128 <term><errorcode>EINVAL</errorcode></term>
129 <listitem>
130 <para>The <structfield>tuner</structfield> index is out of
131bounds or the value in the <structfield>type</structfield> field is
132wrong.</para>
133 </listitem>
134 </varlistentry>
135 </variablelist>
136 </refsect1>
137</refentry>
138
139<!--
140Local Variables:
141mode: sgml
142sgml-parent-document: "v4l2.sgml"
143indent-tabs-mode: nil
144End:
145-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-input.xml b/Documentation/DocBook/v4l/vidioc-g-input.xml
new file mode 100644
index 000000000000..ed076e92760d
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-input.xml
@@ -0,0 +1,100 @@
1<refentry id="vidioc-g-input">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_INPUT, VIDIOC_S_INPUT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_INPUT</refname>
9 <refname>VIDIOC_S_INPUT</refname>
10 <refpurpose>Query or select the current video input</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>int *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_G_INPUT, VIDIOC_S_INPUT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>To query the current video input applications call the
53<constant>VIDIOC_G_INPUT</constant> ioctl with a pointer to an integer
54where the driver stores the number of the input, as in the
55&v4l2-input; <structfield>index</structfield> field. This ioctl will
56fail only when there are no video inputs, returning
57<errorcode>EINVAL</errorcode>.</para>
58
59 <para>To select a video input applications store the number of the
60desired input in an integer and call the
61<constant>VIDIOC_S_INPUT</constant> ioctl with a pointer to this
62integer. Side effects are possible. For example inputs may support
63different video standards, so the driver may implicitly switch the
64current standard. It is good practice to select an input before
65querying or negotiating any other parameters.</para>
66
67 <para>Information about video inputs is available using the
68&VIDIOC-ENUMINPUT; ioctl.</para>
69 </refsect1>
70
71 <refsect1>
72 &return-value;
73
74 <variablelist>
75 <varlistentry>
76 <term><errorcode>EINVAL</errorcode></term>
77 <listitem>
78 <para>The number of the video input is out of bounds, or
79there are no video inputs at all and this ioctl is not
80supported.</para>
81 </listitem>
82 </varlistentry>
83 <varlistentry>
84 <term><errorcode>EBUSY</errorcode></term>
85 <listitem>
86 <para>I/O is in progress, the input cannot be
87switched.</para>
88 </listitem>
89 </varlistentry>
90 </variablelist>
91 </refsect1>
92</refentry>
93
94<!--
95Local Variables:
96mode: sgml
97sgml-parent-document: "v4l2.sgml"
98indent-tabs-mode: nil
99End:
100-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml b/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml
new file mode 100644
index 000000000000..77394b287411
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-jpegcomp.xml
@@ -0,0 +1,180 @@
1<refentry id="vidioc-g-jpegcomp">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_JPEGCOMP</refname>
9 <refname>VIDIOC_S_JPEGCOMP</refname>
10 <refpurpose></refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>v4l2_jpegcompression *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>const v4l2_jpegcompression *<parameter>argp</parameter></paramdef>
28 </funcprototype>
29 </funcsynopsis>
30 </refsynopsisdiv>
31
32 <refsect1>
33 <title>Arguments</title>
34
35 <variablelist>
36 <varlistentry>
37 <term><parameter>fd</parameter></term>
38 <listitem>
39 <para>&fd;</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>request</parameter></term>
44 <listitem>
45 <para>VIDIOC_G_JPEGCOMP, VIDIOC_S_JPEGCOMP</para>
46 </listitem>
47 </varlistentry>
48 <varlistentry>
49 <term><parameter>argp</parameter></term>
50 <listitem>
51 <para></para>
52 </listitem>
53 </varlistentry>
54 </variablelist>
55 </refsect1>
56
57 <refsect1>
58 <title>Description</title>
59
60 <para>[to do]</para>
61
62 <para>Ronald Bultje elaborates:</para>
63
64 <!-- See video4linux-list@redhat.com on 16 Oct 2002, subject
65"Re: [V4L] Re: v4l2 api / Zoran v4l2_jpegcompression" -->
66
67 <para>APP is some application-specific information. The
68application can set it itself, and it'll be stored in the JPEG-encoded
69fields (eg; interlacing information for in an AVI or so). COM is the
70same, but it's comments, like 'encoded by me' or so.</para>
71
72 <para>jpeg_markers describes whether the huffman tables,
73quantization tables and the restart interval information (all
74JPEG-specific stuff) should be stored in the JPEG-encoded fields.
75These define how the JPEG field is encoded. If you omit them,
76applications assume you've used standard encoding. You usually do want
77to add them.</para>
78
79 <!-- NB VIDIOC_S_JPEGCOMP is w/o. -->
80
81 <table pgwide="1" frame="none" id="v4l2-jpegcompression">
82 <title>struct <structname>v4l2_jpegcompression</structname></title>
83 <tgroup cols="3">
84 &cs-str;
85 <tbody valign="top">
86 <row>
87 <entry>int</entry>
88 <entry><structfield>quality</structfield></entry>
89 <entry></entry>
90 </row>
91 <row>
92 <entry>int</entry>
93 <entry><structfield>APPn</structfield></entry>
94 <entry></entry>
95 </row>
96 <row>
97 <entry>int</entry>
98 <entry><structfield>APP_len</structfield></entry>
99 <entry></entry>
100 </row>
101 <row>
102 <entry>char</entry>
103 <entry><structfield>APP_data</structfield>[60]</entry>
104 <entry></entry>
105 </row>
106 <row>
107 <entry>int</entry>
108 <entry><structfield>COM_len</structfield></entry>
109 <entry></entry>
110 </row>
111 <row>
112 <entry>char</entry>
113 <entry><structfield>COM_data</structfield>[60]</entry>
114 <entry></entry>
115 </row>
116 <row>
117 <entry>__u32</entry>
118 <entry><structfield>jpeg_markers</structfield></entry>
119 <entry>See <xref linkend="jpeg-markers" />.</entry>
120 </row>
121 </tbody>
122 </tgroup>
123 </table>
124
125 <table pgwide="1" frame="none" id="jpeg-markers">
126 <title>JPEG Markers Flags</title>
127 <tgroup cols="3">
128 &cs-def;
129 <tbody valign="top">
130 <row>
131 <entry><constant>V4L2_JPEG_MARKER_DHT</constant></entry>
132 <entry>(1&lt;&lt;3)</entry>
133 <entry>Define Huffman Tables</entry>
134 </row>
135 <row>
136 <entry><constant>V4L2_JPEG_MARKER_DQT</constant></entry>
137 <entry>(1&lt;&lt;4)</entry>
138 <entry>Define Quantization Tables</entry>
139 </row>
140 <row>
141 <entry><constant>V4L2_JPEG_MARKER_DRI</constant></entry>
142 <entry>(1&lt;&lt;5)</entry>
143 <entry>Define Restart Interval</entry>
144 </row>
145 <row>
146 <entry><constant>V4L2_JPEG_MARKER_COM</constant></entry>
147 <entry>(1&lt;&lt;6)</entry>
148 <entry>Comment segment</entry>
149 </row>
150 <row>
151 <entry><constant>V4L2_JPEG_MARKER_APP</constant></entry>
152 <entry>(1&lt;&lt;7)</entry>
153 <entry>App segment, driver will always use APP0</entry>
154 </row>
155 </tbody>
156 </tgroup>
157 </table>
158 </refsect1>
159
160 <refsect1>
161 &return-value;
162
163 <variablelist>
164 <varlistentry>
165 <term><errorcode>EINVAL</errorcode></term>
166 <listitem>
167 <para>This ioctl is not supported.</para>
168 </listitem>
169 </varlistentry>
170 </variablelist>
171 </refsect1>
172</refentry>
173
174<!--
175Local Variables:
176mode: sgml
177sgml-parent-document: "v4l2.sgml"
178indent-tabs-mode: nil
179End:
180-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-modulator.xml b/Documentation/DocBook/v4l/vidioc-g-modulator.xml
new file mode 100644
index 000000000000..15ce660f0f5a
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-modulator.xml
@@ -0,0 +1,246 @@
1<refentry id="vidioc-g-modulator">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_MODULATOR</refname>
9 <refname>VIDIOC_S_MODULATOR</refname>
10 <refpurpose>Get or set modulator attributes</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_modulator
20*<parameter>argp</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 <funcsynopsis>
24 <funcprototype>
25 <funcdef>int <function>ioctl</function></funcdef>
26 <paramdef>int <parameter>fd</parameter></paramdef>
27 <paramdef>int <parameter>request</parameter></paramdef>
28 <paramdef>const struct v4l2_modulator
29*<parameter>argp</parameter></paramdef>
30 </funcprototype>
31 </funcsynopsis>
32 </refsynopsisdiv>
33
34 <refsect1>
35 <title>Arguments</title>
36
37 <variablelist>
38 <varlistentry>
39 <term><parameter>fd</parameter></term>
40 <listitem>
41 <para>&fd;</para>
42 </listitem>
43 </varlistentry>
44 <varlistentry>
45 <term><parameter>request</parameter></term>
46 <listitem>
47 <para>VIDIOC_G_MODULATOR, VIDIOC_S_MODULATOR</para>
48 </listitem>
49 </varlistentry>
50 <varlistentry>
51 <term><parameter>argp</parameter></term>
52 <listitem>
53 <para></para>
54 </listitem>
55 </varlistentry>
56 </variablelist>
57 </refsect1>
58
59 <refsect1>
60 <title>Description</title>
61
62 <para>To query the attributes of a modulator applications initialize
63the <structfield>index</structfield> field and zero out the
64<structfield>reserved</structfield> array of a &v4l2-modulator; and
65call the <constant>VIDIOC_G_MODULATOR</constant> ioctl with a pointer
66to this structure. Drivers fill the rest of the structure or return an
67&EINVAL; when the index is out of bounds. To enumerate all modulators
68applications shall begin at index zero, incrementing by one until the
69driver returns <errorcode>EINVAL</errorcode>.</para>
70
71 <para>Modulators have two writable properties, an audio
72modulation set and the radio frequency. To change the modulated audio
73subprograms, applications initialize the <structfield>index
74</structfield> and <structfield>txsubchans</structfield> fields and the
75<structfield>reserved</structfield> array and call the
76<constant>VIDIOC_S_MODULATOR</constant> ioctl. Drivers may choose a
77different audio modulation if the request cannot be satisfied. However
78this is a write-only ioctl, it does not return the actual audio
79modulation selected.</para>
80
81 <para>To change the radio frequency the &VIDIOC-S-FREQUENCY; ioctl
82is available.</para>
83
84 <table pgwide="1" frame="none" id="v4l2-modulator">
85 <title>struct <structname>v4l2_modulator</structname></title>
86 <tgroup cols="3">
87 &cs-str;
88 <tbody valign="top">
89 <row>
90 <entry>__u32</entry>
91 <entry><structfield>index</structfield></entry>
92 <entry>Identifies the modulator, set by the
93application.</entry>
94 </row>
95 <row>
96 <entry>__u8</entry>
97 <entry><structfield>name</structfield>[32]</entry>
98 <entry>Name of the modulator, a NUL-terminated ASCII
99string. This information is intended for the user.</entry>
100 </row>
101 <row>
102 <entry>__u32</entry>
103 <entry><structfield>capability</structfield></entry>
104 <entry>Modulator capability flags. No flags are defined
105for this field, the tuner flags in &v4l2-tuner;
106are used accordingly. The audio flags indicate the ability
107to encode audio subprograms. They will <emphasis>not</emphasis>
108change for example with the current video standard.</entry>
109 </row>
110 <row>
111 <entry>__u32</entry>
112 <entry><structfield>rangelow</structfield></entry>
113 <entry>The lowest tunable frequency in units of 62.5
114KHz, or if the <structfield>capability</structfield> flag
115<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
116Hz.</entry>
117 </row>
118 <row>
119 <entry>__u32</entry>
120 <entry><structfield>rangehigh</structfield></entry>
121 <entry>The highest tunable frequency in units of 62.5
122KHz, or if the <structfield>capability</structfield> flag
123<constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
124Hz.</entry>
125 </row>
126 <row>
127 <entry>__u32</entry>
128 <entry><structfield>txsubchans</structfield></entry>
129 <entry>With this field applications can determine how
130audio sub-carriers shall be modulated. It contains a set of flags as
131defined in <xref linkend="modulator-txsubchans" />. Note the tuner
132<structfield>rxsubchans</structfield> flags are reused, but the
133semantics are different. Video output devices are assumed to have an
134analog or PCM audio input with 1-3 channels. The
135<structfield>txsubchans</structfield> flags select one or more
136channels for modulation, together with some audio subprogram
137indicator, for example a stereo pilot tone.</entry>
138 </row>
139 <row>
140 <entry>__u32</entry>
141 <entry><structfield>reserved</structfield>[4]</entry>
142 <entry>Reserved for future extensions. Drivers and
143applications must set the array to zero.</entry>
144 </row>
145 </tbody>
146 </tgroup>
147 </table>
148
149 <table pgwide="1" frame="none" id="modulator-txsubchans">
150 <title>Modulator Audio Transmission Flags</title>
151 <tgroup cols="3">
152 &cs-def;
153 <tbody valign="top">
154 <row>
155 <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
156 <entry>0x0001</entry>
157 <entry>Modulate channel 1 as mono audio, when the input
158has more channels, a down-mix of channel 1 and 2. This flag does not
159combine with <constant>V4L2_TUNER_SUB_STEREO</constant> or
160<constant>V4L2_TUNER_SUB_LANG1</constant>.</entry>
161 </row>
162 <row>
163 <entry><constant>V4L2_TUNER_SUB_STEREO</constant></entry>
164 <entry>0x0002</entry>
165 <entry>Modulate channel 1 and 2 as left and right
166channel of a stereo audio signal. When the input has only one channel
167or two channels and <constant>V4L2_TUNER_SUB_SAP</constant> is also
168set, channel 1 is encoded as left and right channel. This flag does
169not combine with <constant>V4L2_TUNER_SUB_MONO</constant> or
170<constant>V4L2_TUNER_SUB_LANG1</constant>. When the driver does not
171support stereo audio it shall fall back to mono.</entry>
172 </row>
173 <row>
174 <entry><constant>V4L2_TUNER_SUB_LANG1</constant></entry>
175 <entry>0x0008</entry>
176 <entry>Modulate channel 1 and 2 as primary and secondary
177language of a bilingual audio signal. When the input has only one
178channel it is used for both languages. It is not possible to encode
179the primary or secondary language only. This flag does not combine
180with <constant>V4L2_TUNER_SUB_MONO</constant>,
181<constant>V4L2_TUNER_SUB_STEREO</constant> or
182<constant>V4L2_TUNER_SUB_SAP</constant>. If the hardware does not
183support the respective audio matrix, or the current video standard
184does not permit bilingual audio the
185<constant>VIDIOC_S_MODULATOR</constant> ioctl shall return an &EINVAL;
186and the driver shall fall back to mono or stereo mode.</entry>
187 </row>
188 <row>
189 <entry><constant>V4L2_TUNER_SUB_LANG2</constant></entry>
190 <entry>0x0004</entry>
191 <entry>Same effect as
192<constant>V4L2_TUNER_SUB_SAP</constant>.</entry>
193 </row>
194 <row>
195 <entry><constant>V4L2_TUNER_SUB_SAP</constant></entry>
196 <entry>0x0004</entry>
197 <entry>When combined with <constant>V4L2_TUNER_SUB_MONO
198</constant> the first channel is encoded as mono audio, the last
199channel as Second Audio Program. When the input has only one channel
200it is used for both audio tracks. When the input has three channels
201the mono track is a down-mix of channel 1 and 2. When combined with
202<constant>V4L2_TUNER_SUB_STEREO</constant> channel 1 and 2 are
203encoded as left and right stereo audio, channel 3 as Second Audio
204Program. When the input has only two channels, the first is encoded as
205left and right channel and the second as SAP. When the input has only
206one channel it is used for all audio tracks. It is not possible to
207encode a Second Audio Program only. This flag must combine with
208<constant>V4L2_TUNER_SUB_MONO</constant> or
209<constant>V4L2_TUNER_SUB_STEREO</constant>. If the hardware does not
210support the respective audio matrix, or the current video standard
211does not permit SAP the <constant>VIDIOC_S_MODULATOR</constant> ioctl
212shall return an &EINVAL; and driver shall fall back to mono or stereo
213mode.</entry>
214 </row>
215 <row>
216 <entry><constant>V4L2_TUNER_SUB_RDS</constant></entry>
217 <entry>0x0010</entry>
218 <entry>Enable the RDS encoder for a radio FM transmitter.</entry>
219 </row>
220 </tbody>
221 </tgroup>
222 </table>
223 </refsect1>
224
225 <refsect1>
226 &return-value;
227
228 <variablelist>
229 <varlistentry>
230 <term><errorcode>EINVAL</errorcode></term>
231 <listitem>
232 <para>The &v4l2-modulator;
233<structfield>index</structfield> is out of bounds.</para>
234 </listitem>
235 </varlistentry>
236 </variablelist>
237 </refsect1>
238</refentry>
239
240<!--
241Local Variables:
242mode: sgml
243sgml-parent-document: "v4l2.sgml"
244indent-tabs-mode: nil
245End:
246-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-output.xml b/Documentation/DocBook/v4l/vidioc-g-output.xml
new file mode 100644
index 000000000000..3ea8c0ed812e
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-output.xml
@@ -0,0 +1,100 @@
1<refentry id="vidioc-g-output">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_OUTPUT</refname>
9 <refname>VIDIOC_S_OUTPUT</refname>
10 <refpurpose>Query or select the current video output</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>int *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_G_OUTPUT, VIDIOC_S_OUTPUT</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>To query the current video output applications call the
53<constant>VIDIOC_G_OUTPUT</constant> ioctl with a pointer to an integer
54where the driver stores the number of the output, as in the
55&v4l2-output; <structfield>index</structfield> field. This ioctl
56will fail only when there are no video outputs, returning the
57&EINVAL;.</para>
58
59 <para>To select a video output applications store the number of the
60desired output in an integer and call the
61<constant>VIDIOC_S_OUTPUT</constant> ioctl with a pointer to this integer.
62Side effects are possible. For example outputs may support different
63video standards, so the driver may implicitly switch the current
64standard. It is good practice to select an output before querying or
65negotiating any other parameters.</para>
66
67 <para>Information about video outputs is available using the
68&VIDIOC-ENUMOUTPUT; ioctl.</para>
69 </refsect1>
70
71 <refsect1>
72 &return-value;
73
74 <variablelist>
75 <varlistentry>
76 <term><errorcode>EINVAL</errorcode></term>
77 <listitem>
78 <para>The number of the video output is out of bounds, or
79there are no video outputs at all and this ioctl is not
80supported.</para>
81 </listitem>
82 </varlistentry>
83 <varlistentry>
84 <term><errorcode>EBUSY</errorcode></term>
85 <listitem>
86 <para>I/O is in progress, the output cannot be
87switched.</para>
88 </listitem>
89 </varlistentry>
90 </variablelist>
91 </refsect1>
92</refentry>
93
94<!--
95Local Variables:
96mode: sgml
97sgml-parent-document: "v4l2.sgml"
98indent-tabs-mode: nil
99End:
100-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-parm.xml b/Documentation/DocBook/v4l/vidioc-g-parm.xml
new file mode 100644
index 000000000000..78332d365ce9
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-parm.xml
@@ -0,0 +1,332 @@
1<refentry id="vidioc-g-parm">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_PARM, VIDIOC_S_PARM</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_PARM</refname>
9 <refname>VIDIOC_S_PARM</refname>
10 <refpurpose>Get or set streaming parameters</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>v4l2_streamparm *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_G_PARM, VIDIOC_S_PARM</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>The current video standard determines a nominal number of
53frames per second. If less than this number of frames is to be
54captured or output, applications can request frame skipping or
55duplicating on the driver side. This is especially useful when using
56the <function>read()</function> or <function>write()</function>, which
57are not augmented by timestamps or sequence counters, and to avoid
58unneccessary data copying.</para>
59
60 <para>Further these ioctls can be used to determine the number of
61buffers used internally by a driver in read/write mode. For
62implications see the section discussing the &func-read;
63function.</para>
64
65 <para>To get and set the streaming parameters applications call
66the <constant>VIDIOC_G_PARM</constant> and
67<constant>VIDIOC_S_PARM</constant> ioctl, respectively. They take a
68pointer to a struct <structname>v4l2_streamparm</structname> which
69contains a union holding separate parameters for input and output
70devices.</para>
71
72 <table pgwide="1" frame="none" id="v4l2-streamparm">
73 <title>struct <structname>v4l2_streamparm</structname></title>
74 <tgroup cols="4">
75 &cs-ustr;
76 <tbody valign="top">
77 <row>
78 <entry>&v4l2-buf-type;</entry>
79 <entry><structfield>type</structfield></entry>
80 <entry></entry>
81 <entry>The buffer (stream) type, same as &v4l2-format;
82<structfield>type</structfield>, set by the application.</entry>
83 </row>
84 <row>
85 <entry>union</entry>
86 <entry><structfield>parm</structfield></entry>
87 <entry></entry>
88 <entry></entry>
89 </row>
90 <row>
91 <entry></entry>
92 <entry>&v4l2-captureparm;</entry>
93 <entry><structfield>capture</structfield></entry>
94 <entry>Parameters for capture devices, used when
95<structfield>type</structfield> is
96<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>.</entry>
97 </row>
98 <row>
99 <entry></entry>
100 <entry>&v4l2-outputparm;</entry>
101 <entry><structfield>output</structfield></entry>
102 <entry>Parameters for output devices, used when
103<structfield>type</structfield> is
104<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>.</entry>
105 </row>
106 <row>
107 <entry></entry>
108 <entry>__u8</entry>
109 <entry><structfield>raw_data</structfield>[200]</entry>
110 <entry>A place holder for future extensions and custom
111(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
112higher.</entry>
113 </row>
114 </tbody>
115 </tgroup>
116 </table>
117
118 <table pgwide="1" frame="none" id="v4l2-captureparm">
119 <title>struct <structname>v4l2_captureparm</structname></title>
120 <tgroup cols="3">
121 &cs-str;
122 <tbody valign="top">
123 <row>
124 <entry>__u32</entry>
125 <entry><structfield>capability</structfield></entry>
126 <entry>See <xref linkend="parm-caps" />.</entry>
127 </row>
128 <row>
129 <entry>__u32</entry>
130 <entry><structfield>capturemode</structfield></entry>
131 <entry>Set by drivers and applications, see <xref linkend="parm-flags" />.</entry>
132 </row>
133 <row>
134 <entry>&v4l2-fract;</entry>
135 <entry><structfield>timeperframe</structfield></entry>
136 <entry><para>This is is the desired period between
137successive frames captured by the driver, in seconds. The
138field is intended to skip frames on the driver side, saving I/O
139bandwidth.</para><para>Applications store here the desired frame
140period, drivers return the actual frame period, which must be greater
141or equal to the nominal frame period determined by the current video
142standard (&v4l2-standard; <structfield>frameperiod</structfield>
143field). Changing the video standard (also implicitly by switching the
144video input) may reset this parameter to the nominal frame period. To
145reset manually applications can just set this field to
146zero.</para><para>Drivers support this function only when they set the
147<constant>V4L2_CAP_TIMEPERFRAME</constant> flag in the
148<structfield>capability</structfield> field.</para></entry>
149 </row>
150 <row>
151 <entry>__u32</entry>
152 <entry><structfield>extendedmode</structfield></entry>
153 <entry>Custom (driver specific) streaming parameters. When
154unused, applications and drivers must set this field to zero.
155Applications using this field should check the driver name and
156version, see <xref linkend="querycap" />.</entry>
157 </row>
158 <row>
159 <entry>__u32</entry>
160 <entry><structfield>readbuffers</structfield></entry>
161 <entry>Applications set this field to the desired number
162of buffers used internally by the driver in &func-read; mode. Drivers
163return the actual number of buffers. When an application requests zero
164buffers, drivers should just return the current setting rather than
165the minimum or an error code. For details see <xref
166 linkend="rw" />.</entry>
167 </row>
168 <row>
169 <entry>__u32</entry>
170 <entry><structfield>reserved</structfield>[4]</entry>
171 <entry>Reserved for future extensions. Drivers and
172applications must set the array to zero.</entry>
173 </row>
174 </tbody>
175 </tgroup>
176 </table>
177
178 <table pgwide="1" frame="none" id="v4l2-outputparm">
179 <title>struct <structname>v4l2_outputparm</structname></title>
180 <tgroup cols="3">
181 &cs-str;
182 <tbody valign="top">
183 <row>
184 <entry>__u32</entry>
185 <entry><structfield>capability</structfield></entry>
186 <entry>See <xref linkend="parm-caps" />.</entry>
187 </row>
188 <row>
189 <entry>__u32</entry>
190 <entry><structfield>outputmode</structfield></entry>
191 <entry>Set by drivers and applications, see <xref
192 linkend="parm-flags" />.</entry>
193 </row>
194 <row>
195 <entry>&v4l2-fract;</entry>
196 <entry><structfield>timeperframe</structfield></entry>
197 <entry>This is is the desired period between
198successive frames output by the driver, in seconds.</entry>
199 </row>
200 <row>
201 <entry spanname="hspan"><para>The field is intended to
202repeat frames on the driver side in &func-write; mode (in streaming
203mode timestamps can be used to throttle the output), saving I/O
204bandwidth.</para><para>Applications store here the desired frame
205period, drivers return the actual frame period, which must be greater
206or equal to the nominal frame period determined by the current video
207standard (&v4l2-standard; <structfield>frameperiod</structfield>
208field). Changing the video standard (also implicitly by switching the
209video output) may reset this parameter to the nominal frame period. To
210reset manually applications can just set this field to
211zero.</para><para>Drivers support this function only when they set the
212<constant>V4L2_CAP_TIMEPERFRAME</constant> flag in the
213<structfield>capability</structfield> field.</para></entry>
214 </row>
215 <row>
216 <entry>__u32</entry>
217 <entry><structfield>extendedmode</structfield></entry>
218 <entry>Custom (driver specific) streaming parameters. When
219unused, applications and drivers must set this field to zero.
220Applications using this field should check the driver name and
221version, see <xref linkend="querycap" />.</entry>
222 </row>
223 <row>
224 <entry>__u32</entry>
225 <entry><structfield>writebuffers</structfield></entry>
226 <entry>Applications set this field to the desired number
227of buffers used internally by the driver in
228<function>write()</function> mode. Drivers return the actual number of
229buffers. When an application requests zero buffers, drivers should
230just return the current setting rather than the minimum or an error
231code. For details see <xref linkend="rw" />.</entry>
232 </row>
233 <row>
234 <entry>__u32</entry>
235 <entry><structfield>reserved</structfield>[4]</entry>
236 <entry>Reserved for future extensions. Drivers and
237applications must set the array to zero.</entry>
238 </row>
239 </tbody>
240 </tgroup>
241 </table>
242
243 <table pgwide="1" frame="none" id="parm-caps">
244 <title>Streaming Parameters Capabilites</title>
245 <tgroup cols="3">
246 &cs-def;
247 <tbody valign="top">
248 <row>
249 <entry><constant>V4L2_CAP_TIMEPERFRAME</constant></entry>
250 <entry>0x1000</entry>
251 <entry>The frame skipping/repeating controlled by the
252<structfield>timeperframe</structfield> field is supported.</entry>
253 </row>
254 </tbody>
255 </tgroup>
256 </table>
257
258 <table pgwide="1" frame="none" id="parm-flags">
259 <title>Capture Parameters Flags</title>
260 <tgroup cols="3">
261 &cs-def;
262 <tbody valign="top">
263 <row>
264 <entry><constant>V4L2_MODE_HIGHQUALITY</constant></entry>
265 <entry>0x0001</entry>
266 <entry><para>High quality imaging mode. High quality mode
267is intended for still imaging applications. The idea is to get the
268best possible image quality that the hardware can deliver. It is not
269defined how the driver writer may achieve that; it will depend on the
270hardware and the ingenuity of the driver writer. High quality mode is
271a different mode from the the regular motion video capture modes. In
272high quality mode:<itemizedlist>
273 <listitem>
274 <para>The driver may be able to capture higher
275resolutions than for motion capture.</para>
276 </listitem>
277 <listitem>
278 <para>The driver may support fewer pixel formats
279than motion capture (eg; true color).</para>
280 </listitem>
281 <listitem>
282 <para>The driver may capture and arithmetically
283combine multiple successive fields or frames to remove color edge
284artifacts and reduce the noise in the video data.
285</para>
286 </listitem>
287 <listitem>
288 <para>The driver may capture images in slices like
289a scanner in order to handle larger format images than would otherwise
290be possible. </para>
291 </listitem>
292 <listitem>
293 <para>An image capture operation may be
294significantly slower than motion capture. </para>
295 </listitem>
296 <listitem>
297 <para>Moving objects in the image might have
298excessive motion blur. </para>
299 </listitem>
300 <listitem>
301 <para>Capture might only work through the
302<function>read()</function> call.</para>
303 </listitem>
304 </itemizedlist></para></entry>
305 </row>
306 </tbody>
307 </tgroup>
308 </table>
309
310 </refsect1>
311
312 <refsect1>
313 &return-value;
314
315 <variablelist>
316 <varlistentry>
317 <term><errorcode>EINVAL</errorcode></term>
318 <listitem>
319 <para>This ioctl is not supported.</para>
320 </listitem>
321 </varlistentry>
322 </variablelist>
323 </refsect1>
324</refentry>
325
326<!--
327Local Variables:
328mode: sgml
329sgml-parent-document: "v4l2.sgml"
330indent-tabs-mode: nil
331End:
332-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-priority.xml b/Documentation/DocBook/v4l/vidioc-g-priority.xml
new file mode 100644
index 000000000000..5fb001978645
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-priority.xml
@@ -0,0 +1,144 @@
1<refentry id="vidioc-g-priority">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_PRIORITY</refname>
9 <refname>VIDIOC_S_PRIORITY</refname>
10 <refpurpose>Query or request the access priority associated with a
11file descriptor</refpurpose>
12 </refnamediv>
13
14 <refsynopsisdiv>
15 <funcsynopsis>
16 <funcprototype>
17 <funcdef>int <function>ioctl</function></funcdef>
18 <paramdef>int <parameter>fd</parameter></paramdef>
19 <paramdef>int <parameter>request</parameter></paramdef>
20 <paramdef>enum v4l2_priority *<parameter>argp</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 <funcsynopsis>
24 <funcprototype>
25 <funcdef>int <function>ioctl</function></funcdef>
26 <paramdef>int <parameter>fd</parameter></paramdef>
27 <paramdef>int <parameter>request</parameter></paramdef>
28 <paramdef>const enum v4l2_priority *<parameter>argp</parameter></paramdef>
29 </funcprototype>
30 </funcsynopsis>
31 </refsynopsisdiv>
32
33 <refsect1>
34 <title>Arguments</title>
35
36 <variablelist>
37 <varlistentry>
38 <term><parameter>fd</parameter></term>
39 <listitem>
40 <para>&fd;</para>
41 </listitem>
42 </varlistentry>
43 <varlistentry>
44 <term><parameter>request</parameter></term>
45 <listitem>
46 <para>VIDIOC_G_PRIORITY, VIDIOC_S_PRIORITY</para>
47 </listitem>
48 </varlistentry>
49 <varlistentry>
50 <term><parameter>argp</parameter></term>
51 <listitem>
52 <para>Pointer to an enum v4l2_priority type.</para>
53 </listitem>
54 </varlistentry>
55 </variablelist>
56 </refsect1>
57
58 <refsect1>
59 <title>Description</title>
60
61 <para>To query the current access priority
62applications call the <constant>VIDIOC_G_PRIORITY</constant> ioctl
63with a pointer to an enum v4l2_priority variable where the driver stores
64the current priority.</para>
65
66 <para>To request an access priority applications store the
67desired priority in an enum v4l2_priority variable and call
68<constant>VIDIOC_S_PRIORITY</constant> ioctl with a pointer to this
69variable.</para>
70
71 <table frame="none" pgwide="1" id="v4l2-priority">
72 <title>enum v4l2_priority</title>
73 <tgroup cols="3">
74 &cs-def;
75 <tbody valign="top">
76 <row>
77 <entry><constant>V4L2_PRIORITY_UNSET</constant></entry>
78 <entry>0</entry>
79 <entry></entry>
80 </row>
81 <row>
82 <entry><constant>V4L2_PRIORITY_BACKGROUND</constant></entry>
83 <entry>1</entry>
84 <entry>Lowest priority, usually applications running in
85background, for example monitoring VBI transmissions. A proxy
86application running in user space will be necessary if multiple
87applications want to read from a device at this priority.</entry>
88 </row>
89 <row>
90 <entry><constant>V4L2_PRIORITY_INTERACTIVE</constant></entry>
91 <entry>2</entry>
92 <entry></entry>
93 </row>
94 <row>
95 <entry><constant>V4L2_PRIORITY_DEFAULT</constant></entry>
96 <entry>2</entry>
97 <entry>Medium priority, usually applications started and
98interactively controlled by the user. For example TV viewers, Teletext
99browsers, or just "panel" applications to change the channel or video
100controls. This is the default priority unless an application requests
101another.</entry>
102 </row>
103 <row>
104 <entry><constant>V4L2_PRIORITY_RECORD</constant></entry>
105 <entry>3</entry>
106 <entry>Highest priority. Only one file descriptor can have
107this priority, it blocks any other fd from changing device properties.
108Usually applications which must not be interrupted, like video
109recording.</entry>
110 </row>
111 </tbody>
112 </tgroup>
113 </table>
114 </refsect1>
115
116 <refsect1>
117 &return-value;
118
119 <variablelist>
120 <varlistentry>
121 <term><errorcode>EINVAL</errorcode></term>
122 <listitem>
123 <para>The requested priority value is invalid, or the
124driver does not support access priorities.</para>
125 </listitem>
126 </varlistentry>
127 <varlistentry>
128 <term><errorcode>EBUSY</errorcode></term>
129 <listitem>
130 <para>Another application already requested higher
131priority.</para>
132 </listitem>
133 </varlistentry>
134 </variablelist>
135 </refsect1>
136</refentry>
137
138<!--
139Local Variables:
140mode: sgml
141sgml-parent-document: "v4l2.sgml"
142indent-tabs-mode: nil
143End:
144-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml b/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml
new file mode 100644
index 000000000000..10e721b17374
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-sliced-vbi-cap.xml
@@ -0,0 +1,264 @@
1<refentry id="vidioc-g-sliced-vbi-cap">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_SLICED_VBI_CAP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_SLICED_VBI_CAP</refname>
9 <refpurpose>Query sliced VBI capabilities</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_sliced_vbi_cap *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_G_SLICED_VBI_CAP</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>To find out which data services are supported by a sliced
52VBI capture or output device, applications initialize the
53<structfield>type</structfield> field of a &v4l2-sliced-vbi-cap;,
54clear the <structfield>reserved</structfield> array and
55call the <constant>VIDIOC_G_SLICED_VBI_CAP</constant> ioctl. The
56driver fills in the remaining fields or returns an &EINVAL; if the
57sliced VBI API is unsupported or <structfield>type</structfield>
58is invalid.</para>
59
60 <para>Note the <structfield>type</structfield> field was added,
61and the ioctl changed from read-only to write-read, in Linux 2.6.19.</para>
62
63 <table pgwide="1" frame="none" id="v4l2-sliced-vbi-cap">
64 <title>struct <structname>v4l2_sliced_vbi_cap</structname></title>
65 <tgroup cols="5">
66 <colspec colname="c1" colwidth="3*" />
67 <colspec colname="c2" colwidth="3*" />
68 <colspec colname="c3" colwidth="2*" />
69 <colspec colname="c4" colwidth="2*" />
70 <colspec colname="c5" colwidth="2*" />
71 <spanspec spanname="hspan" namest="c3" nameend="c5" />
72 <tbody valign="top">
73 <row>
74 <entry>__u16</entry>
75 <entry><structfield>service_set</structfield></entry>
76 <entry spanname="hspan">A set of all data services
77supported by the driver. Equal to the union of all elements of the
78<structfield>service_lines </structfield> array.</entry>
79 </row>
80 <row>
81 <entry>__u16</entry>
82 <entry><structfield>service_lines</structfield>[2][24]</entry>
83 <entry spanname="hspan">Each element of this array
84contains a set of data services the hardware can look for or insert
85into a particular scan line. Data services are defined in <xref
86 linkend="vbi-services" />. Array indices map to ITU-R
87line numbers (see also <xref
88 linkend="vbi-525" /> and <xref
89linkend="vbi-625" />) as follows:</entry>
90 </row>
91 <row>
92 <entry></entry>
93 <entry></entry>
94 <entry>Element</entry>
95 <entry>525 line systems</entry>
96 <entry>625 line systems</entry>
97 </row>
98 <row>
99 <entry></entry>
100 <entry></entry>
101 <entry><structfield>service_lines</structfield>[0][1]</entry>
102 <entry align="center">1</entry>
103 <entry align="center">1</entry>
104 </row>
105 <row>
106 <entry></entry>
107 <entry></entry>
108 <entry><structfield>service_lines</structfield>[0][23]</entry>
109 <entry align="center">23</entry>
110 <entry align="center">23</entry>
111 </row>
112 <row>
113 <entry></entry>
114 <entry></entry>
115 <entry><structfield>service_lines</structfield>[1][1]</entry>
116 <entry align="center">264</entry>
117 <entry align="center">314</entry>
118 </row>
119 <row>
120 <entry></entry>
121 <entry></entry>
122 <entry><structfield>service_lines</structfield>[1][23]</entry>
123 <entry align="center">286</entry>
124 <entry align="center">336</entry>
125 </row>
126 <row>
127 <entry></entry>
128 </row>
129 <row>
130 <entry></entry>
131 <entry></entry>
132 <entry spanname="hspan">The number of VBI lines the
133hardware can capture or output per frame, or the number of services it
134can identify on a given line may be limited. For example on PAL line
13516 the hardware may be able to look for a VPS or Teletext signal, but
136not both at the same time. Applications can learn about these limits
137using the &VIDIOC-S-FMT; ioctl as described in <xref
138 linkend="sliced" />.</entry>
139 </row>
140 <row>
141 <entry></entry>
142 </row>
143 <row>
144 <entry></entry>
145 <entry></entry>
146 <entry spanname="hspan">Drivers must set
147<structfield>service_lines</structfield>[0][0] and
148<structfield>service_lines</structfield>[1][0] to zero.</entry>
149 </row>
150 <row>
151 <entry>&v4l2-buf-type;</entry>
152 <entry><structfield>type</structfield></entry>
153 <entry>Type of the data stream, see <xref
154 linkend="v4l2-buf-type" />. Should be
155<constant>V4L2_BUF_TYPE_SLICED_VBI_CAPTURE</constant> or
156<constant>V4L2_BUF_TYPE_SLICED_VBI_OUTPUT</constant>.</entry>
157 </row>
158 <row>
159 <entry>__u32</entry>
160 <entry><structfield>reserved</structfield>[3]</entry>
161 <entry spanname="hspan">This array is reserved for future
162extensions. Applications and drivers must set it to zero.</entry>
163 </row>
164 </tbody>
165 </tgroup>
166 </table>
167
168 <!-- See also dev-sliced-vbi.sgml -->
169 <table pgwide="1" frame="none" id="vbi-services">
170 <title>Sliced VBI services</title>
171 <tgroup cols="5">
172 <colspec colname="c1" colwidth="2*" />
173 <colspec colname="c2" colwidth="1*" />
174 <colspec colname="c3" colwidth="1*" />
175 <colspec colname="c4" colwidth="2*" />
176 <colspec colname="c5" colwidth="2*" />
177 <spanspec spanname='rlp' namest='c3' nameend='c5' />
178 <thead>
179 <row>
180 <entry>Symbol</entry>
181 <entry>Value</entry>
182 <entry>Reference</entry>
183 <entry>Lines, usually</entry>
184 <entry>Payload</entry>
185 </row>
186 </thead>
187 <tbody valign="top">
188 <row>
189 <entry><constant>V4L2_SLICED_TELETEXT_B</constant> (Teletext
190System B)</entry>
191 <entry>0x0001</entry>
192 <entry><xref linkend="ets300706" />, <xref linkend="itu653" /></entry>
193 <entry>PAL/SECAM line 7-22, 320-335 (second field 7-22)</entry>
194 <entry>Last 42 of the 45 byte Teletext packet, that is
195without clock run-in and framing code, lsb first transmitted.</entry>
196 </row>
197 <row>
198 <entry><constant>V4L2_SLICED_VPS</constant></entry>
199 <entry>0x0400</entry>
200 <entry><xref linkend="ets300231" /></entry>
201 <entry>PAL line 16</entry>
202 <entry>Byte number 3 to 15 according to Figure 9 of
203ETS&nbsp;300&nbsp;231, lsb first transmitted.</entry>
204 </row>
205 <row>
206 <entry><constant>V4L2_SLICED_CAPTION_525</constant></entry>
207 <entry>0x1000</entry>
208 <entry><xref linkend="eia608" /></entry>
209 <entry>NTSC line 21, 284 (second field 21)</entry>
210 <entry>Two bytes in transmission order, including parity
211bit, lsb first transmitted.</entry>
212 </row>
213 <row>
214 <entry><constant>V4L2_SLICED_WSS_625</constant></entry>
215 <entry>0x4000</entry>
216 <entry><xref linkend="en300294" />, <xref linkend="itu1119" /></entry>
217 <entry>PAL/SECAM line 23</entry>
218 <entry><screen>
219Byte 0 1
220 msb lsb msb lsb
221Bit 7 6 5 4 3 2 1 0 x x 13 12 11 10 9
222</screen></entry>
223 </row>
224 <row>
225 <entry><constant>V4L2_SLICED_VBI_525</constant></entry>
226 <entry>0x1000</entry>
227 <entry spanname="rlp">Set of services applicable to 525
228line systems.</entry>
229 </row>
230 <row>
231 <entry><constant>V4L2_SLICED_VBI_625</constant></entry>
232 <entry>0x4401</entry>
233 <entry spanname="rlp">Set of services applicable to 625
234line systems.</entry>
235 </row>
236 </tbody>
237 </tgroup>
238 </table>
239
240 </refsect1>
241
242 <refsect1>
243 &return-value;
244
245 <variablelist>
246 <varlistentry>
247 <term><errorcode>EINVAL</errorcode></term>
248 <listitem>
249 <para>The device does not support sliced VBI capturing or
250output, or the value in the <structfield>type</structfield> field is
251wrong.</para>
252 </listitem>
253 </varlistentry>
254 </variablelist>
255 </refsect1>
256</refentry>
257
258<!--
259Local Variables:
260mode: sgml
261sgml-parent-document: "v4l2.sgml"
262indent-tabs-mode: nil
263End:
264-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-std.xml b/Documentation/DocBook/v4l/vidioc-g-std.xml
new file mode 100644
index 000000000000..b6f5d267e856
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-std.xml
@@ -0,0 +1,99 @@
1<refentry id="vidioc-g-std">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_STD, VIDIOC_S_STD</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_STD</refname>
9 <refname>VIDIOC_S_STD</refname>
10 <refpurpose>Query or select the video standard of the current input</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>v4l2_std_id
20*<parameter>argp</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 <funcsynopsis>
24 <funcprototype>
25 <funcdef>int <function>ioctl</function></funcdef>
26 <paramdef>int <parameter>fd</parameter></paramdef>
27 <paramdef>int <parameter>request</parameter></paramdef>
28 <paramdef>const v4l2_std_id
29*<parameter>argp</parameter></paramdef>
30 </funcprototype>
31 </funcsynopsis>
32 </refsynopsisdiv>
33
34 <refsect1>
35 <title>Arguments</title>
36
37 <variablelist>
38 <varlistentry>
39 <term><parameter>fd</parameter></term>
40 <listitem>
41 <para>&fd;</para>
42 </listitem>
43 </varlistentry>
44 <varlistentry>
45 <term><parameter>request</parameter></term>
46 <listitem>
47 <para>VIDIOC_G_STD, VIDIOC_S_STD</para>
48 </listitem>
49 </varlistentry>
50 <varlistentry>
51 <term><parameter>argp</parameter></term>
52 <listitem>
53 <para></para>
54 </listitem>
55 </varlistentry>
56 </variablelist>
57 </refsect1>
58
59 <refsect1>
60 <title>Description</title>
61
62 <para>To query and select the current video standard applications
63use the <constant>VIDIOC_G_STD</constant> and <constant>VIDIOC_S_STD</constant> ioctls which take a pointer to a
64&v4l2-std-id; type as argument. <constant>VIDIOC_G_STD</constant> can
65return a single flag or a set of flags as in &v4l2-standard; field
66<structfield>id</structfield>. The flags must be unambiguous such
67that they appear in only one enumerated <structname>v4l2_standard</structname> structure.</para>
68
69 <para><constant>VIDIOC_S_STD</constant> accepts one or more
70flags, being a write-only ioctl it does not return the actual new standard as
71<constant>VIDIOC_G_STD</constant> does. When no flags are given or
72the current input does not support the requested standard the driver
73returns an &EINVAL;. When the standard set is ambiguous drivers may
74return <errorcode>EINVAL</errorcode> or choose any of the requested
75standards.</para>
76 </refsect1>
77
78 <refsect1>
79 &return-value;
80
81 <variablelist>
82 <varlistentry>
83 <term><errorcode>EINVAL</errorcode></term>
84 <listitem>
85 <para>This ioctl is not supported, or the
86<constant>VIDIOC_S_STD</constant> parameter was unsuitable.</para>
87 </listitem>
88 </varlistentry>
89 </variablelist>
90 </refsect1>
91</refentry>
92
93<!--
94Local Variables:
95mode: sgml
96sgml-parent-document: "v4l2.sgml"
97indent-tabs-mode: nil
98End:
99-->
diff --git a/Documentation/DocBook/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/v4l/vidioc-g-tuner.xml
new file mode 100644
index 000000000000..bd98c734c06b
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-g-tuner.xml
@@ -0,0 +1,535 @@
1<refentry id="vidioc-g-tuner">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_G_TUNER, VIDIOC_S_TUNER</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_G_TUNER</refname>
9 <refname>VIDIOC_S_TUNER</refname>
10 <refpurpose>Get or set tuner attributes</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_tuner
20*<parameter>argp</parameter></paramdef>
21 </funcprototype>
22 </funcsynopsis>
23 <funcsynopsis>
24 <funcprototype>
25 <funcdef>int <function>ioctl</function></funcdef>
26 <paramdef>int <parameter>fd</parameter></paramdef>
27 <paramdef>int <parameter>request</parameter></paramdef>
28 <paramdef>const struct v4l2_tuner
29*<parameter>argp</parameter></paramdef>
30 </funcprototype>
31 </funcsynopsis>
32 </refsynopsisdiv>
33
34 <refsect1>
35 <title>Arguments</title>
36
37 <variablelist>
38 <varlistentry>
39 <term><parameter>fd</parameter></term>
40 <listitem>
41 <para>&fd;</para>
42 </listitem>
43 </varlistentry>
44 <varlistentry>
45 <term><parameter>request</parameter></term>
46 <listitem>
47 <para>VIDIOC_G_TUNER, VIDIOC_S_TUNER</para>
48 </listitem>
49 </varlistentry>
50 <varlistentry>
51 <term><parameter>argp</parameter></term>
52 <listitem>
53 <para></para>
54 </listitem>
55 </varlistentry>
56 </variablelist>
57 </refsect1>
58
59 <refsect1>
60 <title>Description</title>
61
62 <para>To query the attributes of a tuner applications initialize the
63<structfield>index</structfield> field and zero out the
64<structfield>reserved</structfield> array of a &v4l2-tuner; and call the
65<constant>VIDIOC_G_TUNER</constant> ioctl with a pointer to this
66structure. Drivers fill the rest of the structure or return an
67&EINVAL; when the index is out of bounds. To enumerate all tuners
68applications shall begin at index zero, incrementing by one until the
69driver returns <errorcode>EINVAL</errorcode>.</para>
70
71 <para>Tuners have two writable properties, the audio mode and
72the radio frequency. To change the audio mode, applications initialize
73the <structfield>index</structfield>,
74<structfield>audmode</structfield> and
75<structfield>reserved</structfield> fields and call the
76<constant>VIDIOC_S_TUNER</constant> ioctl. This will
77<emphasis>not</emphasis> change the current tuner, which is determined
78by the current video input. Drivers may choose a different audio mode
79if the requested mode is invalid or unsupported. Since this is a
80<!-- FIXME -->write-only ioctl, it does not return the actually
81selected audio mode.</para>
82
83 <para>To change the radio frequency the &VIDIOC-S-FREQUENCY; ioctl
84is available.</para>
85
86 <table pgwide="1" frame="none" id="v4l2-tuner">
87 <title>struct <structname>v4l2_tuner</structname></title>
88 <tgroup cols="3">
89 <colspec colname="c1" colwidth="1*" />
90 <colspec colname="c2" colwidth="1*" />
91 <colspec colname="c3" colwidth="1*" />
92 <colspec colname="c4" colwidth="1*" />
93 <spanspec spanname="hspan" namest="c3" nameend="c4" />
94 <tbody valign="top">
95 <row>
96 <entry>__u32</entry>
97 <entry><structfield>index</structfield></entry>
98 <entry spanname="hspan">Identifies the tuner, set by the
99application.</entry>
100 </row>
101 <row>
102 <entry>__u8</entry>
103 <entry><structfield>name</structfield>[32]</entry>
104 <entry spanname="hspan"><para>Name of the tuner, a
105NUL-terminated ASCII string. This information is intended for the
106user.<!-- FIXME Video inputs already have a name, the purpose of this
107field is not quite clear.--></para></entry>
108 </row>
109 <row>
110 <entry>&v4l2-tuner-type;</entry>
111 <entry><structfield>type</structfield></entry>
112 <entry spanname="hspan">Type of the tuner, see <xref
113 linkend="v4l2-tuner-type" />.</entry>
114 </row>
115 <row>
116 <entry>__u32</entry>
117 <entry><structfield>capability</structfield></entry>
118 <entry spanname="hspan"><para>Tuner capability flags, see
119<xref linkend="tuner-capability" />. Audio flags indicate the ability
120to decode audio subprograms. They will <emphasis>not</emphasis>
121change, for example with the current video standard.</para><para>When
122the structure refers to a radio tuner only the
123<constant>V4L2_TUNER_CAP_LOW</constant>,
124<constant>V4L2_TUNER_CAP_STEREO</constant> and
125<constant>V4L2_TUNER_CAP_RDS</constant> flags can be set.</para></entry>
126 </row>
127 <row>
128 <entry>__u32</entry>
129 <entry><structfield>rangelow</structfield></entry>
130 <entry spanname="hspan">The lowest tunable frequency in
131units of 62.5 kHz, or if the <structfield>capability</structfield>
132flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
133Hz.</entry>
134 </row>
135 <row>
136 <entry>__u32</entry>
137 <entry><structfield>rangehigh</structfield></entry>
138 <entry spanname="hspan">The highest tunable frequency in
139units of 62.5 kHz, or if the <structfield>capability</structfield>
140flag <constant>V4L2_TUNER_CAP_LOW</constant> is set, in units of 62.5
141Hz.</entry>
142 </row>
143 <row>
144 <entry>__u32</entry>
145 <entry><structfield>rxsubchans</structfield></entry>
146 <entry spanname="hspan"><para>Some tuners or audio
147decoders can determine the received audio subprograms by analyzing
148audio carriers, pilot tones or other indicators. To pass this
149information drivers set flags defined in <xref
150 linkend="tuner-rxsubchans" /> in this field. For
151example:</para></entry>
152 </row>
153 <row>
154 <entry></entry>
155 <entry></entry>
156 <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
157 <entry>receiving mono audio</entry>
158 </row>
159 <row>
160 <entry></entry>
161 <entry></entry>
162 <entry><constant>STEREO | SAP</constant></entry>
163 <entry>receiving stereo audio and a secondary audio
164program</entry>
165 </row>
166 <row>
167 <entry></entry>
168 <entry></entry>
169 <entry><constant>MONO | STEREO</constant></entry>
170 <entry>receiving mono or stereo audio, the hardware cannot
171distinguish</entry>
172 </row>
173 <row>
174 <entry></entry>
175 <entry></entry>
176 <entry><constant>LANG1 | LANG2</constant></entry>
177 <entry>receiving bilingual audio</entry>
178 </row>
179 <row>
180 <entry></entry>
181 <entry></entry>
182 <entry><constant>MONO | STEREO | LANG1 | LANG2</constant></entry>
183 <entry>receiving mono, stereo or bilingual
184audio</entry>
185 </row>
186 <row>
187 <entry></entry>
188 <entry></entry>
189 <entry spanname="hspan"><para>When the
190<constant>V4L2_TUNER_CAP_STEREO</constant>,
191<constant>_LANG1</constant>, <constant>_LANG2</constant> or
192<constant>_SAP</constant> flag is cleared in the
193<structfield>capability</structfield> field, the corresponding
194<constant>V4L2_TUNER_SUB_</constant> flag must not be set
195here.</para><para>This field is valid only if this is the tuner of the
196current video input, or when the structure refers to a radio
197tuner.</para></entry>
198 </row>
199 <row>
200 <entry>__u32</entry>
201 <entry><structfield>audmode</structfield></entry>
202 <entry spanname="hspan"><para>The selected audio mode, see
203<xref linkend="tuner-audmode" /> for valid values. The audio mode does
204not affect audio subprogram detection, and like a <link
205linkend="control">control</link> it does not automatically change
206unless the requested mode is invalid or unsupported. See <xref
207 linkend="tuner-matrix" /> for possible results when
208the selected and received audio programs do not
209match.</para><para>Currently this is the only field of struct
210<structname>v4l2_tuner</structname> applications can
211change.</para></entry>
212 </row>
213 <row>
214 <entry>__u32</entry>
215 <entry><structfield>signal</structfield></entry>
216 <entry spanname="hspan">The signal strength if known, ranging
217from 0 to 65535. Higher values indicate a better signal.</entry>
218 </row>
219 <row>
220 <entry>__s32</entry>
221 <entry><structfield>afc</structfield></entry>
222 <entry spanname="hspan">Automatic frequency control: When the
223<structfield>afc</structfield> value is negative, the frequency is too
224low, when positive too high.<!-- FIXME need example what to do when it never
225settles at zero, &ie; range is what? --></entry>
226 </row>
227 <row>
228 <entry>__u32</entry>
229 <entry><structfield>reserved</structfield>[4]</entry>
230 <entry spanname="hspan">Reserved for future extensions. Drivers and
231applications must set the array to zero.</entry>
232 </row>
233 </tbody>
234 </tgroup>
235 </table>
236
237 <table pgwide="1" frame="none" id="v4l2-tuner-type">
238 <title>enum v4l2_tuner_type</title>
239 <tgroup cols="3">
240 &cs-def;
241 <tbody valign="top">
242 <row>
243 <entry><constant>V4L2_TUNER_RADIO</constant></entry>
244 <entry>1</entry>
245 <entry></entry>
246 </row>
247 <row>
248 <entry><constant>V4L2_TUNER_ANALOG_TV</constant></entry>
249 <entry>2</entry>
250 <entry></entry>
251 </row>
252 </tbody>
253 </tgroup>
254 </table>
255
256 <table pgwide="1" frame="none" id="tuner-capability">
257 <title>Tuner and Modulator Capability Flags</title>
258 <tgroup cols="3">
259 &cs-def;
260 <tbody valign="top">
261 <row>
262 <entry><constant>V4L2_TUNER_CAP_LOW</constant></entry>
263 <entry>0x0001</entry>
264 <entry>When set, tuning frequencies are expressed in units of
26562.5&nbsp;Hz, otherwise in units of 62.5&nbsp;kHz.</entry>
266 </row>
267 <row>
268 <entry><constant>V4L2_TUNER_CAP_NORM</constant></entry>
269 <entry>0x0002</entry>
270 <entry>This is a multi-standard tuner; the video standard
271can or must be switched. (B/G PAL tuners for example are typically not
272 considered multi-standard because the video standard is automatically
273 determined from the frequency band.) The set of supported video
274 standards is available from the &v4l2-input; pointing to this tuner,
275 see the description of ioctl &VIDIOC-ENUMINPUT; for details. Only
276 <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
277 </row>
278 <row>
279 <entry><constant>V4L2_TUNER_CAP_STEREO</constant></entry>
280 <entry>0x0010</entry>
281 <entry>Stereo audio reception is supported.</entry>
282 </row>
283 <row>
284 <entry><constant>V4L2_TUNER_CAP_LANG1</constant></entry>
285 <entry>0x0040</entry>
286 <entry>Reception of the primary language of a bilingual
287audio program is supported. Bilingual audio is a feature of
288two-channel systems, transmitting the primary language monaural on the
289main audio carrier and a secondary language monaural on a second
290carrier. Only
291 <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
292 </row>
293 <row>
294 <entry><constant>V4L2_TUNER_CAP_LANG2</constant></entry>
295 <entry>0x0020</entry>
296 <entry>Reception of the secondary language of a bilingual
297audio program is supported. Only
298 <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</entry>
299 </row>
300 <row>
301 <entry><constant>V4L2_TUNER_CAP_SAP</constant></entry>
302 <entry>0x0020</entry>
303 <entry><para>Reception of a secondary audio program is
304supported. This is a feature of the BTSC system which accompanies the
305NTSC video standard. Two audio carriers are available for mono or
306stereo transmissions of a primary language, and an independent third
307carrier for a monaural secondary language. Only
308 <constant>V4L2_TUNER_ANALOG_TV</constant> tuners can have this capability.</para><para>Note the
309<constant>V4L2_TUNER_CAP_LANG2</constant> and
310<constant>V4L2_TUNER_CAP_SAP</constant> flags are synonyms.
311<constant>V4L2_TUNER_CAP_SAP</constant> applies when the tuner
312supports the <constant>V4L2_STD_NTSC_M</constant> video
313standard.</para><!-- FIXME what if PAL+NTSC and Bi but not SAP? --></entry>
314 </row>
315 <row>
316 <entry><constant>V4L2_TUNER_CAP_RDS</constant></entry>
317 <entry>0x0080</entry>
318 <entry>RDS capture is supported. This capability is only valid for
319radio tuners.</entry>
320 </row>
321 </tbody>
322 </tgroup>
323 </table>
324
325 <table pgwide="1" frame="none" id="tuner-rxsubchans">
326 <title>Tuner Audio Reception Flags</title>
327 <tgroup cols="3">
328 &cs-def;
329 <tbody valign="top">
330 <row>
331 <entry><constant>V4L2_TUNER_SUB_MONO</constant></entry>
332 <entry>0x0001</entry>
333 <entry>The tuner receives a mono audio signal.</entry>
334 </row>
335 <row>
336 <entry><constant>V4L2_TUNER_SUB_STEREO</constant></entry>
337 <entry>0x0002</entry>
338 <entry>The tuner receives a stereo audio signal.</entry>
339 </row>
340 <row>
341 <entry><constant>V4L2_TUNER_SUB_LANG1</constant></entry>
342 <entry>0x0008</entry>
343 <entry>The tuner receives the primary language of a
344bilingual audio signal. Drivers must clear this flag when the current
345video standard is <constant>V4L2_STD_NTSC_M</constant>.</entry>
346 </row>
347 <row>
348 <entry><constant>V4L2_TUNER_SUB_LANG2</constant></entry>
349 <entry>0x0004</entry>
350 <entry>The tuner receives the secondary language of a
351bilingual audio signal (or a second audio program).</entry>
352 </row>
353 <row>
354 <entry><constant>V4L2_TUNER_SUB_SAP</constant></entry>
355 <entry>0x0004</entry>
356 <entry>The tuner receives a Second Audio Program. Note the
357<constant>V4L2_TUNER_SUB_LANG2</constant> and
358<constant>V4L2_TUNER_SUB_SAP</constant> flags are synonyms. The
359<constant>V4L2_TUNER_SUB_SAP</constant> flag applies when the
360current video standard is <constant>V4L2_STD_NTSC_M</constant>.</entry>
361 </row>
362 <row>
363 <entry><constant>V4L2_TUNER_SUB_RDS</constant></entry>
364 <entry>0x0010</entry>
365 <entry>The tuner receives an RDS channel.</entry>
366 </row>
367 </tbody>
368 </tgroup>
369 </table>
370
371 <table pgwide="1" frame="none" id="tuner-audmode">
372 <title>Tuner Audio Modes</title>
373 <tgroup cols="3">
374 &cs-def;
375 <tbody valign="top">
376 <row>
377 <entry><constant>V4L2_TUNER_MODE_MONO</constant></entry>
378 <entry>0</entry>
379 <entry>Play mono audio. When the tuner receives a stereo
380signal this a down-mix of the left and right channel. When the tuner
381receives a bilingual or SAP signal this mode selects the primary
382language.</entry>
383 </row>
384 <row>
385 <entry><constant>V4L2_TUNER_MODE_STEREO</constant></entry>
386 <entry>1</entry>
387 <entry><para>Play stereo audio. When the tuner receives
388bilingual audio it may play different languages on the left and right
389channel or the primary language is played on both channels.</para><para>Playing
390different languages in this mode is
391deprecated. New drivers should do this only in
392<constant>MODE_LANG1_LANG2</constant>.</para><para>When the tuner
393receives no stereo signal or does not support stereo reception the
394driver shall fall back to <constant>MODE_MONO</constant>.</para></entry>
395 </row>
396 <row>
397 <entry><constant>V4L2_TUNER_MODE_LANG1</constant></entry>
398 <entry>3</entry>
399 <entry>Play the primary language, mono or stereo. Only
400<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
401mode.</entry>
402 </row>
403 <row>
404 <entry><constant>V4L2_TUNER_MODE_LANG2</constant></entry>
405 <entry>2</entry>
406 <entry>Play the secondary language, mono. When the tuner
407receives no bilingual audio or SAP, or their reception is not
408supported the driver shall fall back to mono or stereo mode. Only
409<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
410mode.</entry>
411 </row>
412 <row>
413 <entry><constant>V4L2_TUNER_MODE_SAP</constant></entry>
414 <entry>2</entry>
415 <entry>Play the Second Audio Program. When the tuner
416receives no bilingual audio or SAP, or their reception is not
417supported the driver shall fall back to mono or stereo mode. Only
418<constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this mode.
419Note the <constant>V4L2_TUNER_MODE_LANG2</constant> and
420<constant>V4L2_TUNER_MODE_SAP</constant> are synonyms.</entry>
421 </row>
422 <row>
423 <entry><constant>V4L2_TUNER_MODE_LANG1_LANG2</constant></entry>
424 <entry>4</entry>
425 <entry>Play the primary language on the left channel, the
426secondary language on the right channel. When the tuner receives no
427bilingual audio or SAP, it shall fall back to
428<constant>MODE_LANG1</constant> or <constant>MODE_MONO</constant>.
429Only <constant>V4L2_TUNER_ANALOG_TV</constant> tuners support this
430mode.</entry>
431 </row>
432 </tbody>
433 </tgroup>
434 </table>
435
436 <table pgwide="1" frame="all" id="tuner-matrix">
437 <title>Tuner Audio Matrix</title>
438 <tgroup cols="6" align="center">
439 <colspec align="left" />
440 <colspec colname="c2" colwidth="1*" />
441 <colspec colwidth="1*" />
442 <colspec colwidth="1*" />
443 <colspec colnum="6" colname="c6" colwidth="1*" />
444 <spanspec namest="c2" nameend="c6" spanname="hspan" align="center" />
445 <thead>
446 <row>
447 <entry></entry>
448 <entry spanname="hspan">Selected
449<constant>V4L2_TUNER_MODE_</constant></entry>
450 </row>
451 <row>
452 <entry>Received <constant>V4L2_TUNER_SUB_</constant></entry>
453 <entry><constant>MONO</constant></entry>
454 <entry><constant>STEREO</constant></entry>
455 <entry><constant>LANG1</constant></entry>
456 <entry><constant>LANG2 = SAP</constant></entry>
457 <entry><constant>LANG1_LANG2</constant><footnote><para>This
458mode has been added in Linux 2.6.17 and may not be supported by older
459drivers.</para></footnote></entry>
460 </row>
461 </thead>
462 <tbody valign="top">
463 <row>
464 <entry><constant>MONO</constant></entry>
465 <entry>Mono</entry>
466 <entry>Mono/Mono</entry>
467 <entry>Mono</entry>
468 <entry>Mono</entry>
469 <entry>Mono/Mono</entry>
470 </row>
471 <row>
472 <entry><constant>MONO | SAP</constant></entry>
473 <entry>Mono</entry>
474 <entry>Mono/Mono</entry>
475 <entry>Mono</entry>
476 <entry>SAP</entry>
477 <entry>Mono/SAP (preferred) or Mono/Mono</entry>
478 </row>
479 <row>
480 <entry><constant>STEREO</constant></entry>
481 <entry>L+R</entry>
482 <entry>L/R</entry>
483 <entry>Stereo L/R (preferred) or Mono L+R</entry>
484 <entry>Stereo L/R (preferred) or Mono L+R</entry>
485 <entry>L/R (preferred) or L+R/L+R</entry>
486 </row>
487 <row>
488 <entry><constant>STEREO | SAP</constant></entry>
489 <entry>L+R</entry>
490 <entry>L/R</entry>
491 <entry>Stereo L/R (preferred) or Mono L+R</entry>
492 <entry>SAP</entry>
493 <entry>L+R/SAP (preferred) or L/R or L+R/L+R</entry>
494 </row>
495 <row>
496 <entry><constant>LANG1 | LANG2</constant></entry>
497 <entry>Language&nbsp;1</entry>
498 <entry>Lang1/Lang2 (deprecated<footnote><para>Playback of
499both languages in <constant>MODE_STEREO</constant> is deprecated. In
500the future drivers should produce only the primary language in this
501mode. Applications should request
502<constant>MODE_LANG1_LANG2</constant> to record both languages or a
503stereo signal.</para></footnote>) or
504Lang1/Lang1</entry>
505 <entry>Language&nbsp;1</entry>
506 <entry>Language&nbsp;2</entry>
507 <entry>Lang1/Lang2 (preferred) or Lang1/Lang1</entry>
508 </row>
509 </tbody>
510 </tgroup>
511 </table>
512 </refsect1>
513
514 <refsect1>
515 &return-value;
516
517 <variablelist>
518 <varlistentry>
519 <term><errorcode>EINVAL</errorcode></term>
520 <listitem>
521 <para>The &v4l2-tuner; <structfield>index</structfield> is
522out of bounds.</para>
523 </listitem>
524 </varlistentry>
525 </variablelist>
526 </refsect1>
527</refentry>
528
529<!--
530Local Variables:
531mode: sgml
532sgml-parent-document: "v4l2.sgml"
533indent-tabs-mode: nil
534End:
535-->
diff --git a/Documentation/DocBook/v4l/vidioc-log-status.xml b/Documentation/DocBook/v4l/vidioc-log-status.xml
new file mode 100644
index 000000000000..2634b7c88b58
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-log-status.xml
@@ -0,0 +1,58 @@
1<refentry id="vidioc-log-status">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_LOG_STATUS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_LOG_STATUS</refname>
9 <refpurpose>Log driver status information</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 </funcprototype>
19 </funcsynopsis>
20 </refsynopsisdiv>
21
22 <refsect1>
23 <title>Description</title>
24
25 <para>As the video/audio devices become more complicated it
26becomes harder to debug problems. When this ioctl is called the driver
27will output the current device status to the kernel log. This is
28particular useful when dealing with problems like no sound, no video
29and incorrectly tuned channels. Also many modern devices autodetect
30video and audio standards and this ioctl will report what the device
31thinks what the standard is. Mismatches may give an indication where
32the problem is.</para>
33
34 <para>This ioctl is optional and not all drivers support it. It
35was introduced in Linux 2.6.15.</para>
36 </refsect1>
37
38 <refsect1>
39 &return-value;
40
41 <variablelist>
42 <varlistentry>
43 <term><errorcode>EINVAL</errorcode></term>
44 <listitem>
45 <para>The driver does not support this ioctl.</para>
46 </listitem>
47 </varlistentry>
48 </variablelist>
49 </refsect1>
50</refentry>
51
52<!--
53Local Variables:
54mode: sgml
55sgml-parent-document: "v4l2.sgml"
56indent-tabs-mode: nil
57End:
58-->
diff --git a/Documentation/DocBook/v4l/vidioc-overlay.xml b/Documentation/DocBook/v4l/vidioc-overlay.xml
new file mode 100644
index 000000000000..1036c582cc15
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-overlay.xml
@@ -0,0 +1,83 @@
1<refentry id="vidioc-overlay">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_OVERLAY</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_OVERLAY</refname>
9 <refpurpose>Start or stop video overlay</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>const int *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_OVERLAY</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>This ioctl is part of the <link linkend="overlay">video
52 overlay</link> I/O method. Applications call
53 <constant>VIDIOC_OVERLAY</constant> to start or stop the
54 overlay. It takes a pointer to an integer which must be set to
55 zero by the application to stop overlay, to one to start.</para>
56
57 <para>Drivers do not support &VIDIOC-STREAMON; or
58&VIDIOC-STREAMOFF; with <constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>.</para>
59 </refsect1>
60
61 <refsect1>
62 &return-value;
63
64 <variablelist>
65 <varlistentry>
66 <term><errorcode>EINVAL</errorcode></term>
67 <listitem>
68 <para>Video overlay is not supported, or the
69parameters have not been set up. See <xref
70linkend="overlay" /> for the necessary steps.</para>
71 </listitem>
72 </varlistentry>
73 </variablelist>
74 </refsect1>
75</refentry>
76
77<!--
78Local Variables:
79mode: sgml
80sgml-parent-document: "v4l2.sgml"
81indent-tabs-mode: nil
82End:
83-->
diff --git a/Documentation/DocBook/v4l/vidioc-qbuf.xml b/Documentation/DocBook/v4l/vidioc-qbuf.xml
new file mode 100644
index 000000000000..187081778154
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-qbuf.xml
@@ -0,0 +1,168 @@
1<refentry id="vidioc-qbuf">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_QBUF, VIDIOC_DQBUF</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_QBUF</refname>
9 <refname>VIDIOC_DQBUF</refname>
10 <refpurpose>Exchange a buffer with the driver</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_QBUF, VIDIOC_DQBUF</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>Applications call the <constant>VIDIOC_QBUF</constant> ioctl
53to enqueue an empty (capturing) or filled (output) buffer in the
54driver's incoming queue. The semantics depend on the selected I/O
55method.</para>
56
57 <para>To enqueue a <link linkend="mmap">memory mapped</link>
58buffer applications set the <structfield>type</structfield> field of a
59&v4l2-buffer; to the same buffer type as previously &v4l2-format;
60<structfield>type</structfield> and &v4l2-requestbuffers;
61<structfield>type</structfield>, the <structfield>memory</structfield>
62field to <constant>V4L2_MEMORY_MMAP</constant> and the
63<structfield>index</structfield> field. Valid index numbers range from
64zero to the number of buffers allocated with &VIDIOC-REQBUFS;
65(&v4l2-requestbuffers; <structfield>count</structfield>) minus one. The
66contents of the struct <structname>v4l2_buffer</structname> returned
67by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is
68intended for output (<structfield>type</structfield> is
69<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or
70<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
71initialize the <structfield>bytesused</structfield>,
72<structfield>field</structfield> and
73<structfield>timestamp</structfield> fields. See <xref
74 linkend="buffer" /> for details. When
75<constant>VIDIOC_QBUF</constant> is called with a pointer to this
76structure the driver sets the
77<constant>V4L2_BUF_FLAG_MAPPED</constant> and
78<constant>V4L2_BUF_FLAG_QUEUED</constant> flags and clears the
79<constant>V4L2_BUF_FLAG_DONE</constant> flag in the
80<structfield>flags</structfield> field, or it returns an
81&EINVAL;.</para>
82
83 <para>To enqueue a <link linkend="userp">user pointer</link>
84buffer applications set the <structfield>type</structfield> field of a
85&v4l2-buffer; to the same buffer type as previously &v4l2-format;
86<structfield>type</structfield> and &v4l2-requestbuffers;
87<structfield>type</structfield>, the <structfield>memory</structfield>
88field to <constant>V4L2_MEMORY_USERPTR</constant> and the
89<structfield>m.userptr</structfield> field to the address of the
90buffer and <structfield>length</structfield> to its size. When the
91buffer is intended for output additional fields must be set as above.
92When <constant>VIDIOC_QBUF</constant> is called with a pointer to this
93structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant>
94flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and
95<constant>V4L2_BUF_FLAG_DONE</constant> flags in the
96<structfield>flags</structfield> field, or it returns an error code.
97This ioctl locks the memory pages of the buffer in physical memory,
98they cannot be swapped out to disk. Buffers remain locked until
99dequeued, until the &VIDIOC-STREAMOFF; or &VIDIOC-REQBUFS; ioctl are
100called, or until the device is closed.</para>
101
102 <para>Applications call the <constant>VIDIOC_DQBUF</constant>
103ioctl to dequeue a filled (capturing) or displayed (output) buffer
104from the driver's outgoing queue. They just set the
105<structfield>type</structfield> and <structfield>memory</structfield>
106fields of a &v4l2-buffer; as above, when <constant>VIDIOC_DQBUF</constant>
107is called with a pointer to this structure the driver fills the
108remaining fields or returns an error code.</para>
109
110 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
111buffer is in the outgoing queue. When the
112<constant>O_NONBLOCK</constant> flag was given to the &func-open;
113function, <constant>VIDIOC_DQBUF</constant> returns immediately
114with an &EAGAIN; when no buffer is available.</para>
115
116 <para>The <structname>v4l2_buffer</structname> structure is
117specified in <xref linkend="buffer" />.</para>
118 </refsect1>
119
120 <refsect1>
121 &return-value;
122
123 <variablelist>
124 <varlistentry>
125 <term><errorcode>EAGAIN</errorcode></term>
126 <listitem>
127 <para>Non-blocking I/O has been selected using
128<constant>O_NONBLOCK</constant> and no buffer was in the outgoing
129queue.</para>
130 </listitem>
131 </varlistentry>
132 <varlistentry>
133 <term><errorcode>EINVAL</errorcode></term>
134 <listitem>
135 <para>The buffer <structfield>type</structfield> is not
136supported, or the <structfield>index</structfield> is out of bounds,
137or no buffers have been allocated yet, or the
138<structfield>userptr</structfield> or
139<structfield>length</structfield> are invalid.</para>
140 </listitem>
141 </varlistentry>
142 <varlistentry>
143 <term><errorcode>ENOMEM</errorcode></term>
144 <listitem>
145 <para>Not enough physical or virtual memory was available to
146enqueue a user pointer buffer.</para>
147 </listitem>
148 </varlistentry>
149 <varlistentry>
150 <term><errorcode>EIO</errorcode></term>
151 <listitem>
152 <para><constant>VIDIOC_DQBUF</constant> failed due to an
153internal error. Can also indicate temporary problems like signal
154loss. Note the driver might dequeue an (empty) buffer despite
155returning an error, or even stop capturing.</para>
156 </listitem>
157 </varlistentry>
158 </variablelist>
159 </refsect1>
160</refentry>
161
162<!--
163Local Variables:
164mode: sgml
165sgml-parent-document: "v4l2.sgml"
166indent-tabs-mode: nil
167End:
168-->
diff --git a/Documentation/DocBook/v4l/vidioc-querybuf.xml b/Documentation/DocBook/v4l/vidioc-querybuf.xml
new file mode 100644
index 000000000000..d834993e6191
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-querybuf.xml
@@ -0,0 +1,103 @@
1<refentry id="vidioc-querybuf">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_QUERYBUF</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_QUERYBUF</refname>
9 <refpurpose>Query the status of a buffer</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_QUERYBUF</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>This ioctl is part of the <link linkend="mmap">memory
52mapping</link> I/O method. It can be used to query the status of a
53buffer at any time after buffers have been allocated with the
54&VIDIOC-REQBUFS; ioctl.</para>
55
56 <para>Applications set the <structfield>type</structfield> field
57 of a &v4l2-buffer; to the same buffer type as previously
58&v4l2-format; <structfield>type</structfield> and &v4l2-requestbuffers;
59<structfield>type</structfield>, and the <structfield>index</structfield>
60 field. Valid index numbers range from zero
61to the number of buffers allocated with &VIDIOC-REQBUFS;
62 (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
63After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
64 this structure drivers return an error code or fill the rest of
65the structure.</para>
66
67 <para>In the <structfield>flags</structfield> field the
68<constant>V4L2_BUF_FLAG_MAPPED</constant>,
69<constant>V4L2_BUF_FLAG_QUEUED</constant> and
70<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
71<structfield>memory</structfield> field will be set to
72<constant>V4L2_MEMORY_MMAP</constant>, the <structfield>m.offset</structfield>
73contains the offset of the buffer from the start of the device memory,
74the <structfield>length</structfield> field its size. The driver may
75or may not set the remaining fields and flags, they are meaningless in
76this context.</para>
77
78 <para>The <structname>v4l2_buffer</structname> structure is
79 specified in <xref linkend="buffer" />.</para>
80 </refsect1>
81
82 <refsect1>
83 &return-value;
84
85 <variablelist>
86 <varlistentry>
87 <term><errorcode>EINVAL</errorcode></term>
88 <listitem>
89 <para>The buffer <structfield>type</structfield> is not
90supported, or the <structfield>index</structfield> is out of bounds.</para>
91 </listitem>
92 </varlistentry>
93 </variablelist>
94 </refsect1>
95</refentry>
96
97<!--
98Local Variables:
99mode: sgml
100sgml-parent-document: "v4l2.sgml"
101indent-tabs-mode: nil
102End:
103-->
diff --git a/Documentation/DocBook/v4l/vidioc-querycap.xml b/Documentation/DocBook/v4l/vidioc-querycap.xml
new file mode 100644
index 000000000000..6ab7e25b31b6
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-querycap.xml
@@ -0,0 +1,284 @@
1<refentry id="vidioc-querycap">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_QUERYCAP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_QUERYCAP</refname>
9 <refpurpose>Query device capabilities</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_capability *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_QUERYCAP</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>All V4L2 devices support the
52<constant>VIDIOC_QUERYCAP</constant> ioctl. It is used to identify
53kernel devices compatible with this specification and to obtain
54information about driver and hardware capabilities. The ioctl takes a
55pointer to a &v4l2-capability; which is filled by the driver. When the
56driver is not compatible with this specification the ioctl returns an
57&EINVAL;.</para>
58
59 <table pgwide="1" frame="none" id="v4l2-capability">
60 <title>struct <structname>v4l2_capability</structname></title>
61 <tgroup cols="3">
62 &cs-str;
63 <tbody valign="top">
64 <row>
65 <entry>__u8</entry>
66 <entry><structfield>driver</structfield>[16]</entry>
67 <entry><para>Name of the driver, a unique NUL-terminated
68ASCII string. For example: "bttv". Driver specific applications can
69use this information to verify the driver identity. It is also useful
70to work around known bugs, or to identify drivers in error reports.
71The driver version is stored in the <structfield>version</structfield>
72field.</para><para>Storing strings in fixed sized arrays is bad
73practice but unavoidable here. Drivers and applications should take
74precautions to never read or write beyond the end of the array and to
75make sure the strings are properly NUL-terminated.</para></entry>
76 </row>
77 <row>
78 <entry>__u8</entry>
79 <entry><structfield>card</structfield>[32]</entry>
80 <entry>Name of the device, a NUL-terminated ASCII string.
81For example: "Yoyodyne TV/FM". One driver may support different brands
82or models of video hardware. This information is intended for users,
83for example in a menu of available devices. Since multiple TV cards of
84the same brand may be installed which are supported by the same
85driver, this name should be combined with the character device file
86name (&eg; <filename>/dev/video2</filename>) or the
87<structfield>bus_info</structfield> string to avoid
88ambiguities.</entry>
89 </row>
90 <row>
91 <entry>__u8</entry>
92 <entry><structfield>bus_info</structfield>[32]</entry>
93 <entry>Location of the device in the system, a
94NUL-terminated ASCII string. For example: "PCI Slot 4". This
95information is intended for users, to distinguish multiple
96identical devices. If no such information is available the field may
97simply count the devices controlled by the driver, or contain the
98empty string (<structfield>bus_info</structfield>[0] = 0).<!-- XXX pci_dev->slot_name example --></entry>
99 </row>
100 <row>
101 <entry>__u32</entry>
102 <entry><structfield>version</structfield></entry>
103 <entry><para>Version number of the driver. Together with
104the <structfield>driver</structfield> field this identifies a
105particular driver. The version number is formatted using the
106<constant>KERNEL_VERSION()</constant> macro:</para></entry>
107 </row>
108 <row>
109 <entry spanname="hspan"><para>
110<programlisting>
111#define KERNEL_VERSION(a,b,c) (((a) &lt;&lt; 16) + ((b) &lt;&lt; 8) + (c))
112
113__u32 version = KERNEL_VERSION(0, 8, 1);
114
115printf ("Version: %u.%u.%u\n",
116 (version &gt;&gt; 16) &amp; 0xFF,
117 (version &gt;&gt; 8) &amp; 0xFF,
118 version &amp; 0xFF);
119</programlisting></para></entry>
120 </row>
121 <row>
122 <entry>__u32</entry>
123 <entry><structfield>capabilities</structfield></entry>
124 <entry>Device capabilities, see <xref
125 linkend="device-capabilities" />.</entry>
126 </row>
127 <row>
128 <entry>__u32</entry>
129 <entry><structfield>reserved</structfield>[4]</entry>
130 <entry>Reserved for future extensions. Drivers must set
131this array to zero.</entry>
132 </row>
133 </tbody>
134 </tgroup>
135 </table>
136
137 <table pgwide="1" frame="none" id="device-capabilities">
138 <title>Device Capabilities Flags</title>
139 <tgroup cols="3">
140 &cs-def;
141 <tbody valign="top">
142 <row>
143 <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
144 <entry>0x00000001</entry>
145 <entry>The device supports the <link
146linkend="capture">Video Capture</link> interface.</entry>
147 </row>
148 <row>
149 <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry>
150 <entry>0x00000002</entry>
151 <entry>The device supports the <link
152linkend="output">Video Output</link> interface.</entry>
153 </row>
154 <row>
155 <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
156 <entry>0x00000004</entry>
157 <entry>The device supports the <link
158linkend="overlay">Video Overlay</link> interface. A video overlay device
159typically stores captured images directly in the video memory of a
160graphics card, with hardware clipping and scaling.</entry>
161 </row>
162 <row>
163 <entry><constant>V4L2_CAP_VBI_CAPTURE</constant></entry>
164 <entry>0x00000010</entry>
165 <entry>The device supports the <link linkend="raw-vbi">Raw
166VBI Capture</link> interface, providing Teletext and Closed Caption
167data.</entry>
168 </row>
169 <row>
170 <entry><constant>V4L2_CAP_VBI_OUTPUT</constant></entry>
171 <entry>0x00000020</entry>
172 <entry>The device supports the <link linkend="raw-vbi">Raw VBI Output</link> interface.</entry>
173 </row>
174 <row>
175 <entry><constant>V4L2_CAP_SLICED_VBI_CAPTURE</constant></entry>
176 <entry>0x00000040</entry>
177 <entry>The device supports the <link linkend="sliced">Sliced VBI Capture</link> interface.</entry>
178 </row>
179 <row>
180 <entry><constant>V4L2_CAP_SLICED_VBI_OUTPUT</constant></entry>
181 <entry>0x00000080</entry>
182 <entry>The device supports the <link linkend="sliced">Sliced VBI Output</link> interface.</entry>
183 </row>
184 <row>
185 <entry><constant>V4L2_CAP_RDS_CAPTURE</constant></entry>
186 <entry>0x00000100</entry>
187 <entry>The device supports the <link linkend="rds">RDS</link> interface.</entry>
188 </row>
189 <row>
190 <entry><constant>V4L2_CAP_VIDEO_OUTPUT_OVERLAY</constant></entry>
191 <entry>0x00000200</entry>
192 <entry>The device supports the <link linkend="osd">Video
193Output Overlay</link> (OSD) interface. Unlike the <wordasword>Video
194Overlay</wordasword> interface, this is a secondary function of video
195output devices and overlays an image onto an outgoing video signal.
196When the driver sets this flag, it must clear the
197<constant>V4L2_CAP_VIDEO_OVERLAY</constant> flag and vice
198versa.<footnote><para>The &v4l2-framebuffer; lacks an
199&v4l2-buf-type; field, therefore the type of overlay is implied by the
200driver capabilities.</para></footnote></entry>
201 </row>
202 <row>
203 <entry><constant>V4L2_CAP_HW_FREQ_SEEK</constant></entry>
204 <entry>0x00000400</entry>
205 <entry>The device supports the &VIDIOC-S-HW-FREQ-SEEK; ioctl for
206hardware frequency seeking.</entry>
207 </row>
208 <row>
209 <entry><constant>V4L2_CAP_TUNER</constant></entry>
210 <entry>0x00010000</entry>
211 <entry>The device has some sort of tuner to
212receive RF-modulated video signals. For more information about
213tuner programming see
214<xref linkend="tuner" />.</entry>
215 </row>
216 <row>
217 <entry><constant>V4L2_CAP_AUDIO</constant></entry>
218 <entry>0x00020000</entry>
219 <entry>The device has audio inputs or outputs. It may or
220may not support audio recording or playback, in PCM or compressed
221formats. PCM audio support must be implemented as ALSA or OSS
222interface. For more information on audio inputs and outputs see <xref
223 linkend="audio" />.</entry>
224 </row>
225 <row>
226 <entry><constant>V4L2_CAP_RADIO</constant></entry>
227 <entry>0x00040000</entry>
228 <entry>This is a radio receiver.</entry>
229 </row>
230 <row>
231 <entry><constant>V4L2_CAP_MODULATOR</constant></entry>
232 <entry>0x00080000</entry>
233 <entry>The device has some sort of modulator to
234emit RF-modulated video/audio signals. For more information about
235modulator programming see
236<xref linkend="tuner" />.</entry>
237 </row>
238 <row>
239 <entry><constant>V4L2_CAP_READWRITE</constant></entry>
240 <entry>0x01000000</entry>
241 <entry>The device supports the <link
242linkend="rw">read()</link> and/or <link linkend="rw">write()</link>
243I/O methods.</entry>
244 </row>
245 <row>
246 <entry><constant>V4L2_CAP_ASYNCIO</constant></entry>
247 <entry>0x02000000</entry>
248 <entry>The device supports the <link
249linkend="async">asynchronous</link> I/O methods.</entry>
250 </row>
251 <row>
252 <entry><constant>V4L2_CAP_STREAMING</constant></entry>
253 <entry>0x04000000</entry>
254 <entry>The device supports the <link
255linkend="mmap">streaming</link> I/O method.</entry>
256 </row>
257 </tbody>
258 </tgroup>
259 </table>
260 </refsect1>
261
262 <refsect1>
263 &return-value;
264
265 <variablelist>
266 <varlistentry>
267 <term><errorcode>EINVAL</errorcode></term>
268 <listitem>
269 <para>The device is not compatible with this
270specification.</para>
271 </listitem>
272 </varlistentry>
273 </variablelist>
274 </refsect1>
275</refentry>
276
277<!--
278Local Variables:
279mode: sgml
280sgml-parent-document: "v4l2.sgml"
281indent-tabs-mode: nil
282End:
283-->
284
diff --git a/Documentation/DocBook/v4l/vidioc-queryctrl.xml b/Documentation/DocBook/v4l/vidioc-queryctrl.xml
new file mode 100644
index 000000000000..4876ff1a1a04
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-queryctrl.xml
@@ -0,0 +1,428 @@
1<refentry id="vidioc-queryctrl">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_QUERYCTRL</refname>
9 <refname>VIDIOC_QUERYMENU</refname>
10 <refpurpose>Enumerate controls and menu control items</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>struct v4l2_queryctrl *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 <funcsynopsis>
23 <funcprototype>
24 <funcdef>int <function>ioctl</function></funcdef>
25 <paramdef>int <parameter>fd</parameter></paramdef>
26 <paramdef>int <parameter>request</parameter></paramdef>
27 <paramdef>struct v4l2_querymenu *<parameter>argp</parameter></paramdef>
28 </funcprototype>
29 </funcsynopsis>
30 </refsynopsisdiv>
31
32 <refsect1>
33 <title>Arguments</title>
34
35 <variablelist>
36 <varlistentry>
37 <term><parameter>fd</parameter></term>
38 <listitem>
39 <para>&fd;</para>
40 </listitem>
41 </varlistentry>
42 <varlistentry>
43 <term><parameter>request</parameter></term>
44 <listitem>
45 <para>VIDIOC_QUERYCTRL, VIDIOC_QUERYMENU</para>
46 </listitem>
47 </varlistentry>
48 <varlistentry>
49 <term><parameter>argp</parameter></term>
50 <listitem>
51 <para></para>
52 </listitem>
53 </varlistentry>
54 </variablelist>
55 </refsect1>
56
57 <refsect1>
58 <title>Description</title>
59
60 <para>To query the attributes of a control applications set the
61<structfield>id</structfield> field of a &v4l2-queryctrl; and call the
62<constant>VIDIOC_QUERYCTRL</constant> ioctl with a pointer to this
63structure. The driver fills the rest of the structure or returns an
64&EINVAL; when the <structfield>id</structfield> is invalid.</para>
65
66 <para>It is possible to enumerate controls by calling
67<constant>VIDIOC_QUERYCTRL</constant> with successive
68<structfield>id</structfield> values starting from
69<constant>V4L2_CID_BASE</constant> up to and exclusive
70<constant>V4L2_CID_BASE_LASTP1</constant>. Drivers may return
71<errorcode>EINVAL</errorcode> if a control in this range is not
72supported. Further applications can enumerate private controls, which
73are not defined in this specification, by starting at
74<constant>V4L2_CID_PRIVATE_BASE</constant> and incrementing
75<structfield>id</structfield> until the driver returns
76<errorcode>EINVAL</errorcode>.</para>
77
78 <para>In both cases, when the driver sets the
79<constant>V4L2_CTRL_FLAG_DISABLED</constant> flag in the
80<structfield>flags</structfield> field this control is permanently
81disabled and should be ignored by the application.<footnote>
82 <para><constant>V4L2_CTRL_FLAG_DISABLED</constant> was
83intended for two purposes: Drivers can skip predefined controls not
84supported by the hardware (although returning EINVAL would do as
85well), or disable predefined and private controls after hardware
86detection without the trouble of reordering control arrays and indices
87(EINVAL cannot be used to skip private controls because it would
88prematurely end the enumeration).</para></footnote></para>
89
90 <para>When the application ORs <structfield>id</structfield> with
91<constant>V4L2_CTRL_FLAG_NEXT_CTRL</constant> the driver returns the
92next supported control, or <errorcode>EINVAL</errorcode> if there is
93none. Drivers which do not support this flag yet always return
94<errorcode>EINVAL</errorcode>.</para>
95
96 <para>Additional information is required for menu controls: the
97names of the menu items. To query them applications set the
98<structfield>id</structfield> and <structfield>index</structfield>
99fields of &v4l2-querymenu; and call the
100<constant>VIDIOC_QUERYMENU</constant> ioctl with a pointer to this
101structure. The driver fills the rest of the structure or returns an
102&EINVAL; when the <structfield>id</structfield> or
103<structfield>index</structfield> is invalid. Menu items are enumerated
104by calling <constant>VIDIOC_QUERYMENU</constant> with successive
105<structfield>index</structfield> values from &v4l2-queryctrl;
106<structfield>minimum</structfield> (0) to
107<structfield>maximum</structfield>, inclusive.</para>
108
109 <para>See also the examples in <xref linkend="control" />.</para>
110
111 <table pgwide="1" frame="none" id="v4l2-queryctrl">
112 <title>struct <structname>v4l2_queryctrl</structname></title>
113 <tgroup cols="3">
114 &cs-str;
115 <tbody valign="top">
116 <row>
117 <entry>__u32</entry>
118 <entry><structfield>id</structfield></entry>
119 <entry>Identifies the control, set by the application. See
120<xref linkend="control-id" /> for predefined IDs. When the ID is ORed
121with V4L2_CTRL_FLAG_NEXT_CTRL the driver clears the flag and returns
122the first control with a higher ID. Drivers which do not support this
123flag yet always return an &EINVAL;.</entry>
124 </row>
125 <row>
126 <entry>&v4l2-ctrl-type;</entry>
127 <entry><structfield>type</structfield></entry>
128 <entry>Type of control, see <xref
129 linkend="v4l2-ctrl-type" />.</entry>
130 </row>
131 <row>
132 <entry>__u8</entry>
133 <entry><structfield>name</structfield>[32]</entry>
134 <entry>Name of the control, a NUL-terminated ASCII
135string. This information is intended for the user.</entry>
136 </row>
137 <row>
138 <entry>__s32</entry>
139 <entry><structfield>minimum</structfield></entry>
140 <entry>Minimum value, inclusive. This field gives a lower
141bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
142lowest valid index (always 0) for <constant>V4L2_CTRL_TYPE_MENU</constant> controls.
143For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the minimum value
144gives the minimum length of the string. This length <emphasis>does not include the terminating
145zero</emphasis>. It may not be valid for any other type of control, including
146<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
147signed value.</entry>
148 </row>
149 <row>
150 <entry>__s32</entry>
151 <entry><structfield>maximum</structfield></entry>
152 <entry>Maximum value, inclusive. This field gives an upper
153bound for <constant>V4L2_CTRL_TYPE_INTEGER</constant> controls and the
154highest valid index for <constant>V4L2_CTRL_TYPE_MENU</constant>
155controls.
156For <constant>V4L2_CTRL_TYPE_STRING</constant> controls the maximum value
157gives the maximum length of the string. This length <emphasis>does not include the terminating
158zero</emphasis>. It may not be valid for any other type of control, including
159<constant>V4L2_CTRL_TYPE_INTEGER64</constant> controls. Note that this is a
160signed value.</entry>
161 </row>
162 <row>
163 <entry>__s32</entry>
164 <entry><structfield>step</structfield></entry>
165 <entry><para>This field gives a step size for
166<constant>V4L2_CTRL_TYPE_INTEGER</constant> controls. For
167<constant>V4L2_CTRL_TYPE_STRING</constant> controls this field refers to
168the string length that has to be a multiple of this step size.
169It may not be valid for any other type of control, including
170<constant>V4L2_CTRL_TYPE_INTEGER64</constant>
171controls.</para><para>Generally drivers should not scale hardware
172control values. It may be necessary for example when the
173<structfield>name</structfield> or <structfield>id</structfield> imply
174a particular unit and the hardware actually accepts only multiples of
175said unit. If so, drivers must take care values are properly rounded
176when scaling, such that errors will not accumulate on repeated
177read-write cycles.</para><para>This field gives the smallest change of
178an integer control actually affecting hardware. Often the information
179is needed when the user can change controls by keyboard or GUI
180buttons, rather than a slider. When for example a hardware register
181accepts values 0-511 and the driver reports 0-65535, step should be
182128.</para><para>Note that although signed, the step value is supposed to
183be always positive.</para></entry>
184 </row>
185 <row>
186 <entry>__s32</entry>
187 <entry><structfield>default_value</structfield></entry>
188 <entry>The default value of a
189<constant>V4L2_CTRL_TYPE_INTEGER</constant>,
190<constant>_BOOLEAN</constant> or <constant>_MENU</constant> control.
191Not valid for other types of controls. Drivers reset controls only
192when the driver is loaded, not later, in particular not when the
193func-open; is called.</entry>
194 </row>
195 <row>
196 <entry>__u32</entry>
197 <entry><structfield>flags</structfield></entry>
198 <entry>Control flags, see <xref
199 linkend="control-flags" />.</entry>
200 </row>
201 <row>
202 <entry>__u32</entry>
203 <entry><structfield>reserved</structfield>[2]</entry>
204 <entry>Reserved for future extensions. Drivers must set
205the array to zero.</entry>
206 </row>
207 </tbody>
208 </tgroup>
209 </table>
210
211 <table pgwide="1" frame="none" id="v4l2-querymenu">
212 <title>struct <structname>v4l2_querymenu</structname></title>
213 <tgroup cols="3">
214 &cs-str;
215 <tbody valign="top">
216 <row>
217 <entry>__u32</entry>
218 <entry><structfield>id</structfield></entry>
219 <entry>Identifies the control, set by the application
220from the respective &v4l2-queryctrl;
221<structfield>id</structfield>.</entry>
222 </row>
223 <row>
224 <entry>__u32</entry>
225 <entry><structfield>index</structfield></entry>
226 <entry>Index of the menu item, starting at zero, set by
227 the application.</entry>
228 </row>
229 <row>
230 <entry>__u8</entry>
231 <entry><structfield>name</structfield>[32]</entry>
232 <entry>Name of the menu item, a NUL-terminated ASCII
233string. This information is intended for the user.</entry>
234 </row>
235 <row>
236 <entry>__u32</entry>
237 <entry><structfield>reserved</structfield></entry>
238 <entry>Reserved for future extensions. Drivers must set
239the array to zero.</entry>
240 </row>
241 </tbody>
242 </tgroup>
243 </table>
244
245 <table pgwide="1" frame="none" id="v4l2-ctrl-type">
246 <title>enum v4l2_ctrl_type</title>
247 <tgroup cols="5" align="left">
248 <colspec colwidth="30*" />
249 <colspec colwidth="5*" align="center" />
250 <colspec colwidth="5*" align="center" />
251 <colspec colwidth="5*" align="center" />
252 <colspec colwidth="55*" />
253 <thead>
254 <row>
255 <entry>Type</entry>
256 <entry><structfield>minimum</structfield></entry>
257 <entry><structfield>step</structfield></entry>
258 <entry><structfield>maximum</structfield></entry>
259 <entry>Description</entry>
260 </row>
261 </thead>
262 <tbody valign="top">
263 <row>
264 <entry><constant>V4L2_CTRL_TYPE_INTEGER</constant></entry>
265 <entry>any</entry>
266 <entry>any</entry>
267 <entry>any</entry>
268 <entry>An integer-valued control ranging from minimum to
269maximum inclusive. The step value indicates the increment between
270values which are actually different on the hardware.</entry>
271 </row>
272 <row>
273 <entry><constant>V4L2_CTRL_TYPE_BOOLEAN</constant></entry>
274 <entry>0</entry>
275 <entry>1</entry>
276 <entry>1</entry>
277 <entry>A boolean-valued control. Zero corresponds to
278"disabled", and one means "enabled".</entry>
279 </row>
280 <row>
281 <entry><constant>V4L2_CTRL_TYPE_MENU</constant></entry>
282 <entry>0</entry>
283 <entry>1</entry>
284 <entry>N-1</entry>
285 <entry>The control has a menu of N choices. The names of
286the menu items can be enumerated with the
287<constant>VIDIOC_QUERYMENU</constant> ioctl.</entry>
288 </row>
289 <row>
290 <entry><constant>V4L2_CTRL_TYPE_BUTTON</constant></entry>
291 <entry>0</entry>
292 <entry>0</entry>
293 <entry>0</entry>
294 <entry>A control which performs an action when set.
295Drivers must ignore the value passed with
296<constant>VIDIOC_S_CTRL</constant> and return an &EINVAL; on a
297<constant>VIDIOC_G_CTRL</constant> attempt.</entry>
298 </row>
299 <row>
300 <entry><constant>V4L2_CTRL_TYPE_INTEGER64</constant></entry>
301 <entry>n/a</entry>
302 <entry>n/a</entry>
303 <entry>n/a</entry>
304 <entry>A 64-bit integer valued control. Minimum, maximum
305and step size cannot be queried.</entry>
306 </row>
307 <row>
308 <entry><constant>V4L2_CTRL_TYPE_STRING</constant></entry>
309 <entry>&ge; 0</entry>
310 <entry>&ge; 1</entry>
311 <entry>&ge; 0</entry>
312 <entry>The minimum and maximum string lengths. The step size
313means that the string must be (minimum + N * step) characters long for
314N &ge; 0. These lengths do not include the terminating zero, so in order to
315pass a string of length 8 to &VIDIOC-S-EXT-CTRLS; you need to set the
316<structfield>size</structfield> field of &v4l2-ext-control; to 9. For &VIDIOC-G-EXT-CTRLS; you can
317set the <structfield>size</structfield> field to <structfield>maximum</structfield> + 1.
318Which character encoding is used will depend on the string control itself and
319should be part of the control documentation.</entry>
320 </row>
321 <row>
322 <entry><constant>V4L2_CTRL_TYPE_CTRL_CLASS</constant></entry>
323 <entry>n/a</entry>
324 <entry>n/a</entry>
325 <entry>n/a</entry>
326 <entry>This is not a control. When
327<constant>VIDIOC_QUERYCTRL</constant> is called with a control ID
328equal to a control class code (see <xref linkend="ctrl-class" />), the
329ioctl returns the name of the control class and this control type.
330Older drivers which do not support this feature return an
331&EINVAL;.</entry>
332 </row>
333 </tbody>
334 </tgroup>
335 </table>
336
337 <table pgwide="1" frame="none" id="control-flags">
338 <title>Control Flags</title>
339 <tgroup cols="3">
340 &cs-def;
341 <tbody valign="top">
342 <row>
343 <entry><constant>V4L2_CTRL_FLAG_DISABLED</constant></entry>
344 <entry>0x0001</entry>
345 <entry>This control is permanently disabled and should be
346ignored by the application. Any attempt to change the control will
347result in an &EINVAL;.</entry>
348 </row>
349 <row>
350 <entry><constant>V4L2_CTRL_FLAG_GRABBED</constant></entry>
351 <entry>0x0002</entry>
352 <entry>This control is temporarily unchangeable, for
353example because another application took over control of the
354respective resource. Such controls may be displayed specially in a
355user interface. Attempts to change the control may result in an
356&EBUSY;.</entry>
357 </row>
358 <row>
359 <entry><constant>V4L2_CTRL_FLAG_READ_ONLY</constant></entry>
360 <entry>0x0004</entry>
361 <entry>This control is permanently readable only. Any
362attempt to change the control will result in an &EINVAL;.</entry>
363 </row>
364 <row>
365 <entry><constant>V4L2_CTRL_FLAG_UPDATE</constant></entry>
366 <entry>0x0008</entry>
367 <entry>A hint that changing this control may affect the
368value of other controls within the same control class. Applications
369should update their user interface accordingly.</entry>
370 </row>
371 <row>
372 <entry><constant>V4L2_CTRL_FLAG_INACTIVE</constant></entry>
373 <entry>0x0010</entry>
374 <entry>This control is not applicable to the current
375configuration and should be displayed accordingly in a user interface.
376For example the flag may be set on a MPEG audio level 2 bitrate
377control when MPEG audio encoding level 1 was selected with another
378control.</entry>
379 </row>
380 <row>
381 <entry><constant>V4L2_CTRL_FLAG_SLIDER</constant></entry>
382 <entry>0x0020</entry>
383 <entry>A hint that this control is best represented as a
384slider-like element in a user interface.</entry>
385 </row>
386 <row>
387 <entry><constant>V4L2_CTRL_FLAG_WRITE_ONLY</constant></entry>
388 <entry>0x0040</entry>
389 <entry>This control is permanently writable only. Any
390attempt to read the control will result in an &EACCES; error code. This
391flag is typically present for relative controls or action controls where
392writing a value will cause the device to carry out a given action
393(&eg; motor control) but no meaningful value can be returned.</entry>
394 </row>
395 </tbody>
396 </tgroup>
397 </table>
398 </refsect1>
399
400 <refsect1>
401 &return-value;
402
403 <variablelist>
404 <varlistentry>
405 <term><errorcode>EINVAL</errorcode></term>
406 <listitem>
407 <para>The &v4l2-queryctrl; <structfield>id</structfield>
408is invalid. The &v4l2-querymenu; <structfield>id</structfield> or
409<structfield>index</structfield> is invalid.</para>
410 </listitem>
411 </varlistentry>
412 <varlistentry>
413 <term><errorcode>EACCES</errorcode></term>
414 <listitem>
415 <para>An attempt was made to read a write-only control.</para>
416 </listitem>
417 </varlistentry>
418 </variablelist>
419 </refsect1>
420</refentry>
421
422<!--
423Local Variables:
424mode: sgml
425sgml-parent-document: "v4l2.sgml"
426indent-tabs-mode: nil
427End:
428-->
diff --git a/Documentation/DocBook/v4l/vidioc-querystd.xml b/Documentation/DocBook/v4l/vidioc-querystd.xml
new file mode 100644
index 000000000000..b5a7ff934486
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-querystd.xml
@@ -0,0 +1,83 @@
1<refentry id="vidioc-querystd">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_QUERYSTD</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_QUERYSTD</refname>
9 <refpurpose>Sense the video standard received by the current
10input</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>v4l2_std_id *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_QUERYSTD</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>The hardware may be able to detect the current video
53standard automatically. To do so, applications call <constant>
54VIDIOC_QUERYSTD</constant> with a pointer to a &v4l2-std-id; type. The
55driver stores here a set of candidates, this can be a single flag or a
56set of supported standards if for example the hardware can only
57distinguish between 50 and 60 Hz systems. When detection is not
58possible or fails, the set must contain all standards supported by the
59current video input or output.</para>
60
61 </refsect1>
62
63 <refsect1>
64 &return-value;
65
66 <variablelist>
67 <varlistentry>
68 <term><errorcode>EINVAL</errorcode></term>
69 <listitem>
70 <para>This ioctl is not supported.</para>
71 </listitem>
72 </varlistentry>
73 </variablelist>
74 </refsect1>
75</refentry>
76
77<!--
78Local Variables:
79mode: sgml
80sgml-parent-document: "v4l2.sgml"
81indent-tabs-mode: nil
82End:
83-->
diff --git a/Documentation/DocBook/v4l/vidioc-reqbufs.xml b/Documentation/DocBook/v4l/vidioc-reqbufs.xml
new file mode 100644
index 000000000000..bab38084454f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-reqbufs.xml
@@ -0,0 +1,160 @@
1<refentry id="vidioc-reqbufs">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_REQBUFS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_REQBUFS</refname>
9 <refpurpose>Initiate Memory Mapping or User Pointer I/O</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_requestbuffers *<parameter>argp</parameter></paramdef>
19 </funcprototype>
20 </funcsynopsis>
21 </refsynopsisdiv>
22
23 <refsect1>
24 <title>Arguments</title>
25
26 <variablelist>
27 <varlistentry>
28 <term><parameter>fd</parameter></term>
29 <listitem>
30 <para>&fd;</para>
31 </listitem>
32 </varlistentry>
33 <varlistentry>
34 <term><parameter>request</parameter></term>
35 <listitem>
36 <para>VIDIOC_REQBUFS</para>
37 </listitem>
38 </varlistentry>
39 <varlistentry>
40 <term><parameter>argp</parameter></term>
41 <listitem>
42 <para></para>
43 </listitem>
44 </varlistentry>
45 </variablelist>
46 </refsect1>
47
48 <refsect1>
49 <title>Description</title>
50
51 <para>This ioctl is used to initiate <link linkend="mmap">memory
52mapped</link> or <link linkend="userp">user pointer</link>
53I/O. Memory mapped buffers are located in device memory and must be
54allocated with this ioctl before they can be mapped into the
55application's address space. User buffers are allocated by
56applications themselves, and this ioctl is merely used to switch the
57driver into user pointer I/O mode.</para>
58
59 <para>To allocate device buffers applications initialize three
60fields of a <structname>v4l2_requestbuffers</structname> structure.
61They set the <structfield>type</structfield> field to the respective
62stream or buffer type, the <structfield>count</structfield> field to
63the desired number of buffers, and <structfield>memory</structfield>
64must be set to <constant>V4L2_MEMORY_MMAP</constant>. When the ioctl
65is called with a pointer to this structure the driver attempts to
66allocate the requested number of buffers and stores the actual number
67allocated in the <structfield>count</structfield> field. It can be
68smaller than the number requested, even zero, when the driver runs out
69of free memory. A larger number is possible when the driver requires
70more buffers to function correctly.<footnote>
71 <para>For example video output requires at least two buffers,
72one displayed and one filled by the application.</para>
73 </footnote> When memory mapping I/O is not supported the ioctl
74returns an &EINVAL;.</para>
75
76 <para>Applications can call <constant>VIDIOC_REQBUFS</constant>
77again to change the number of buffers, however this cannot succeed
78when any buffers are still mapped. A <structfield>count</structfield>
79value of zero frees all buffers, after aborting or finishing any DMA
80in progress, an implicit &VIDIOC-STREAMOFF;. <!-- mhs: I see no
81reason why munmap()ping one or even all buffers must imply
82streamoff.--></para>
83
84 <para>To negotiate user pointer I/O, applications initialize only
85the <structfield>type</structfield> field and set
86<structfield>memory</structfield> to
87<constant>V4L2_MEMORY_USERPTR</constant>. When the ioctl is called
88with a pointer to this structure the driver prepares for user pointer
89I/O, when this I/O method is not supported the ioctl returns an
90&EINVAL;.</para>
91
92 <table pgwide="1" frame="none" id="v4l2-requestbuffers">
93 <title>struct <structname>v4l2_requestbuffers</structname></title>
94 <tgroup cols="3">
95 &cs-str;
96 <tbody valign="top">
97 <row>
98 <entry>__u32</entry>
99 <entry><structfield>count</structfield></entry>
100 <entry>The number of buffers requested or granted. This
101field is only used when <structfield>memory</structfield> is set to
102<constant>V4L2_MEMORY_MMAP</constant>.</entry>
103 </row>
104 <row>
105 <entry>&v4l2-buf-type;</entry>
106 <entry><structfield>type</structfield></entry>
107 <entry>Type of the stream or buffers, this is the same
108as the &v4l2-format; <structfield>type</structfield> field. See <xref
109 linkend="v4l2-buf-type" /> for valid values.</entry>
110 </row>
111 <row>
112 <entry>&v4l2-memory;</entry>
113 <entry><structfield>memory</structfield></entry>
114 <entry>Applications set this field to
115<constant>V4L2_MEMORY_MMAP</constant> or
116<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
117 </row>
118 <row>
119 <entry>__u32</entry>
120 <entry><structfield>reserved</structfield>[2]</entry>
121 <entry>A place holder for future extensions and custom
122(driver defined) buffer types <constant>V4L2_BUF_TYPE_PRIVATE</constant> and
123higher.</entry>
124 </row>
125 </tbody>
126 </tgroup>
127 </table>
128 </refsect1>
129
130 <refsect1>
131 &return-value;
132
133 <variablelist>
134 <varlistentry>
135 <term><errorcode>EBUSY</errorcode></term>
136 <listitem>
137 <para>The driver supports multiple opens and I/O is already
138in progress, or reallocation of buffers was attempted although one or
139more are still mapped.</para>
140 </listitem>
141 </varlistentry>
142 <varlistentry>
143 <term><errorcode>EINVAL</errorcode></term>
144 <listitem>
145 <para>The buffer type (<structfield>type</structfield> field) or the
146requested I/O method (<structfield>memory</structfield>) is not
147supported.</para>
148 </listitem>
149 </varlistentry>
150 </variablelist>
151 </refsect1>
152</refentry>
153
154<!--
155Local Variables:
156mode: sgml
157sgml-parent-document: "v4l2.sgml"
158indent-tabs-mode: nil
159End:
160-->
diff --git a/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml b/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml
new file mode 100644
index 000000000000..14b3ec7ed75b
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-s-hw-freq-seek.xml
@@ -0,0 +1,129 @@
1<refentry id="vidioc-s-hw-freq-seek">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_S_HW_FREQ_SEEK</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_S_HW_FREQ_SEEK</refname>
9 <refpurpose>Perform a hardware frequency seek</refpurpose>
10 </refnamediv>
11
12 <refsynopsisdiv>
13 <funcsynopsis>
14 <funcprototype>
15 <funcdef>int <function>ioctl</function></funcdef>
16 <paramdef>int <parameter>fd</parameter></paramdef>
17 <paramdef>int <parameter>request</parameter></paramdef>
18 <paramdef>struct v4l2_hw_freq_seek
19*<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_S_HW_FREQ_SEEK</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>Start a hardware frequency seek from the current frequency.
53To do this applications initialize the <structfield>tuner</structfield>,
54<structfield>type</structfield>, <structfield>seek_upward</structfield> and
55<structfield>wrap_around</structfield> fields, and zero out the
56<structfield>reserved</structfield> array of a &v4l2-hw-freq-seek; and
57call the <constant>VIDIOC_S_HW_FREQ_SEEK</constant> ioctl with a pointer
58to this structure.</para>
59
60 <para>This ioctl is supported if the <constant>V4L2_CAP_HW_FREQ_SEEK</constant> capability is set.</para>
61
62 <table pgwide="1" frame="none" id="v4l2-hw-freq-seek">
63 <title>struct <structname>v4l2_hw_freq_seek</structname></title>
64 <tgroup cols="3">
65 &cs-str;
66 <tbody valign="top">
67 <row>
68 <entry>__u32</entry>
69 <entry><structfield>tuner</structfield></entry>
70 <entry>The tuner index number. This is the
71same value as in the &v4l2-input; <structfield>tuner</structfield>
72field and the &v4l2-tuner; <structfield>index</structfield> field.</entry>
73 </row>
74 <row>
75 <entry>&v4l2-tuner-type;</entry>
76 <entry><structfield>type</structfield></entry>
77 <entry>The tuner type. This is the same value as in the
78&v4l2-tuner; <structfield>type</structfield> field.</entry>
79 </row>
80 <row>
81 <entry>__u32</entry>
82 <entry><structfield>seek_upward</structfield></entry>
83 <entry>If non-zero, seek upward from the current frequency, else seek downward.</entry>
84 </row>
85 <row>
86 <entry>__u32</entry>
87 <entry><structfield>wrap_around</structfield></entry>
88 <entry>If non-zero, wrap around when at the end of the frequency range, else stop seeking.</entry>
89 </row>
90 <row>
91 <entry>__u32</entry>
92 <entry><structfield>reserved</structfield>[8]</entry>
93 <entry>Reserved for future extensions. Drivers and
94 applications must set the array to zero.</entry>
95 </row>
96 </tbody>
97 </tgroup>
98 </table>
99 </refsect1>
100
101 <refsect1>
102 &return-value;
103
104 <variablelist>
105 <varlistentry>
106 <term><errorcode>EINVAL</errorcode></term>
107 <listitem>
108 <para>The <structfield>tuner</structfield> index is out of
109bounds or the value in the <structfield>type</structfield> field is
110wrong.</para>
111 </listitem>
112 </varlistentry>
113 <varlistentry>
114 <term><errorcode>EAGAIN</errorcode></term>
115 <listitem>
116 <para>The ioctl timed-out. Try again.</para>
117 </listitem>
118 </varlistentry>
119 </variablelist>
120 </refsect1>
121</refentry>
122
123<!--
124Local Variables:
125mode: sgml
126sgml-parent-document: "v4l2.sgml"
127indent-tabs-mode: nil
128End:
129-->
diff --git a/Documentation/DocBook/v4l/vidioc-streamon.xml b/Documentation/DocBook/v4l/vidioc-streamon.xml
new file mode 100644
index 000000000000..e42bff1f2c0a
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-streamon.xml
@@ -0,0 +1,106 @@
1<refentry id="vidioc-streamon">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_STREAMON, VIDIOC_STREAMOFF</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_STREAMON</refname>
9 <refname>VIDIOC_STREAMOFF</refname>
10 <refpurpose>Start or stop streaming I/O</refpurpose>
11 </refnamediv>
12
13 <refsynopsisdiv>
14 <funcsynopsis>
15 <funcprototype>
16 <funcdef>int <function>ioctl</function></funcdef>
17 <paramdef>int <parameter>fd</parameter></paramdef>
18 <paramdef>int <parameter>request</parameter></paramdef>
19 <paramdef>const int *<parameter>argp</parameter></paramdef>
20 </funcprototype>
21 </funcsynopsis>
22 </refsynopsisdiv>
23
24 <refsect1>
25 <title>Arguments</title>
26
27 <variablelist>
28 <varlistentry>
29 <term><parameter>fd</parameter></term>
30 <listitem>
31 <para>&fd;</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>VIDIOC_STREAMON, VIDIOC_STREAMOFF</para>
38 </listitem>
39 </varlistentry>
40 <varlistentry>
41 <term><parameter>argp</parameter></term>
42 <listitem>
43 <para></para>
44 </listitem>
45 </varlistentry>
46 </variablelist>
47 </refsect1>
48
49 <refsect1>
50 <title>Description</title>
51
52 <para>The <constant>VIDIOC_STREAMON</constant> and
53<constant>VIDIOC_STREAMOFF</constant> ioctl start and stop the capture
54or output process during streaming (<link linkend="mmap">memory
55mapping</link> or <link linkend="userp">user pointer</link>) I/O.</para>
56
57 <para>Specifically the capture hardware is disabled and no input
58buffers are filled (if there are any empty buffers in the incoming
59queue) until <constant>VIDIOC_STREAMON</constant> has been called.
60Accordingly the output hardware is disabled, no video signal is
61produced until <constant>VIDIOC_STREAMON</constant> has been called.
62The ioctl will succeed only when at least one output buffer is in the
63incoming queue.</para>
64
65 <para>The <constant>VIDIOC_STREAMOFF</constant> ioctl, apart of
66aborting or finishing any DMA in progress, unlocks any user pointer
67buffers locked in physical memory, and it removes all buffers from the
68incoming and outgoing queues. That means all images captured but not
69dequeued yet will be lost, likewise all images enqueued for output but
70not transmitted yet. I/O returns to the same state as after calling
71&VIDIOC-REQBUFS; and can be restarted accordingly.</para>
72
73 <para>Both ioctls take a pointer to an integer, the desired buffer or
74stream type. This is the same as &v4l2-requestbuffers;
75<structfield>type</structfield>.</para>
76
77 <para>Note applications can be preempted for unknown periods right
78before or after the <constant>VIDIOC_STREAMON</constant> or
79<constant>VIDIOC_STREAMOFF</constant> calls, there is no notion of
80starting or stopping "now". Buffer timestamps can be used to
81synchronize with other events.</para>
82 </refsect1>
83
84 <refsect1>
85 &return-value;
86
87 <variablelist>
88 <varlistentry>
89 <term><errorcode>EINVAL</errorcode></term>
90 <listitem>
91 <para>Streaming I/O is not supported, the buffer
92<structfield>type</structfield> is not supported, or no buffers have
93been allocated (memory mapping) or enqueued (output) yet.</para>
94 </listitem>
95 </varlistentry>
96 </variablelist>
97 </refsect1>
98</refentry>
99
100<!--
101Local Variables:
102mode: sgml
103sgml-parent-document: "v4l2.sgml"
104indent-tabs-mode: nil
105End:
106-->
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 3d1b0ab70c8e..14b7b5a3bcb9 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -25,7 +25,8 @@ use IO::Handle;
25 "tda10046lifeview", "av7110", "dec2000t", "dec2540t", 25 "tda10046lifeview", "av7110", "dec2000t", "dec2540t",
26 "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004", 26 "dec3000s", "vp7041", "dibusb", "nxt2002", "nxt2004",
27 "or51211", "or51132_qam", "or51132_vsb", "bluebird", 27 "or51211", "or51132_qam", "or51132_vsb", "bluebird",
28 "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718" ); 28 "opera1", "cx231xx", "cx18", "cx23885", "pvrusb2", "mpc718",
29 "af9015");
29 30
30# Check args 31# Check args
31syntax() if (scalar(@ARGV) != 1); 32syntax() if (scalar(@ARGV) != 1);
@@ -514,6 +515,40 @@ sub bluebird {
514 $outfile; 515 $outfile;
515} 516}
516 517
518sub af9015 {
519 my $sourcefile = "download.ashx?file=57";
520 my $url = "http://www.ite.com.tw/EN/Services/$sourcefile";
521 my $hash = "ff5b096ed47c080870eacdab2de33ad6";
522 my $outfile = "dvb-usb-af9015.fw";
523 my $tmpdir = tempdir(DIR => "/tmp", CLEANUP => 1);
524 my $fwoffset = 0x22708;
525 my $fwlength = 18225;
526 my ($chunklength, $buf, $rcount);
527
528 checkstandard();
529
530 wgetfile($sourcefile, $url);
531 unzip($sourcefile, $tmpdir);
532 verify("$tmpdir/Driver/Files/AF15BDA.sys", $hash);
533
534 open INFILE, '<', "$tmpdir/Driver/Files/AF15BDA.sys";
535 open OUTFILE, '>', $outfile;
536
537 sysseek(INFILE, $fwoffset, SEEK_SET);
538 while($fwlength > 0) {
539 $chunklength = 55;
540 $chunklength = $fwlength if ($chunklength > $fwlength);
541 $rcount = sysread(INFILE, $buf, $chunklength);
542 die "Ran out of data\n" if ($rcount != $chunklength);
543 syswrite(OUTFILE, $buf);
544 sysread(INFILE, $buf, 8);
545 $fwlength -= $rcount + 8;
546 }
547
548 close OUTFILE;
549 close INFILE;
550}
551
517# --------------------------------------------------------------- 552# ---------------------------------------------------------------
518# Utilities 553# Utilities
519 554
diff --git a/Documentation/dvb/technisat.txt b/Documentation/dvb/technisat.txt
index 3f435ffb289c..f0cc4f2d8365 100644
--- a/Documentation/dvb/technisat.txt
+++ b/Documentation/dvb/technisat.txt
@@ -4,9 +4,12 @@ How to set up the Technisat/B2C2 Flexcop devices
41) Find out what device you have 41) Find out what device you have
5================================ 5================================
6 6
7Important Notice: The driver does NOT support Technisat USB 2 devices!
8
7First start your linux box with a shipped kernel: 9First start your linux box with a shipped kernel:
8lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example: 10lspci -vvv for a PCI device (lsusb -vvv for an USB device) will show you for example:
902:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip / Technisat SkyStar2 DVB card (rev 02) 1102:0b.0 Network controller: Techsan Electronics Co Ltd B2C2 FlexCopII DVB chip /
12 Technisat SkyStar2 DVB card (rev 02)
10 13
11dmesg | grep frontend may show you for example: 14dmesg | grep frontend may show you for example:
12DVB: registering frontend 0 (Conexant CX24123/CX24109)... 15DVB: registering frontend 0 (Conexant CX24123/CX24109)...
@@ -14,62 +17,62 @@ DVB: registering frontend 0 (Conexant CX24123/CX24109)...
142) Kernel compilation: 172) Kernel compilation:
15====================== 18======================
16 19
17If the Technisat is the only TV device in your box get rid of unnecessary modules and check this one: 20If the Flexcop / Technisat is the only DVB / TV / Radio device in your box
18"Multimedia devices" => "Customise analog and hybrid tuner modules to build" 21 get rid of unnecessary modules and check this one:
19In this directory uncheck every driver which is activated there (except "Simple tuner support" for case 9 only). 22"Multimedia support" => "Customise analog and hybrid tuner modules to build"
23In this directory uncheck every driver which is activated there
24 (except "Simple tuner support" for ATSC 3rd generation only -> see case 9 please).
20 25
21Then please activate: 26Then please activate:
222a) Main module part: 272a) Main module part:
28"Multimedia support" => "DVB/ATSC adapters"
29 => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters"
23 30
24a.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" 31a.) => "Technisat/B2C2 Air/Sky/Cable2PC PCI" (PCI card) or
25b.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC PCI" in case of a PCI card 32b.) => "Technisat/B2C2 Air/Sky/Cable2PC USB" (USB 1.1 adapter)
26OR 33 and for troubleshooting purposes:
27c.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Technisat/B2C2 Air/Sky/Cable2PC USB" in case of an USB 1.1 adapter 34c.) => "Enable debug for the B2C2 FlexCop drivers"
28d.)"Multimedia devices" => "DVB/ATSC adapters" => "Technisat/B2C2 FlexcopII(b) and FlexCopIII adapters" => "Enable debug for the B2C2 FlexCop drivers"
29Notice: d.) is helpful for troubleshooting
30 35
312b) Frontend module part: 362b) Frontend / Tuner / Demodulator module part:
37"Multimedia support" => "DVB/ATSC adapters"
38 => "Customise the frontend modules to build" "Customise DVB frontends" =>
32 39
331.) SkyStar DVB-S Revision 2.3: 401.) SkyStar DVB-S Revision 2.3:
34a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 41a.) => "Zarlink VP310/MT312/ZL10313 based"
35b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink VP310/MT312/ZL10313 based" 42b.) => "Generic I2C PLL based tuners"
36 43
372.) SkyStar DVB-S Revision 2.6: 442.) SkyStar DVB-S Revision 2.6:
38a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 45a.) => "ST STV0299 based"
39b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0299 based" 46b.) => "Generic I2C PLL based tuners"
40 47
413.) SkyStar DVB-S Revision 2.7: 483.) SkyStar DVB-S Revision 2.7:
42a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 49a.) => "Samsung S5H1420 based"
43b.)"Multimedia devices" => "Customise DVB frontends" => "Samsung S5H1420 based" 50b.) => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
44c.)"Multimedia devices" => "Customise DVB frontends" => "Integrant ITD1000 Zero IF tuner for DVB-S/DSS" 51c.) => "ISL6421 SEC controller"
45d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
46 52
474.) SkyStar DVB-S Revision 2.8: 534.) SkyStar DVB-S Revision 2.8:
48a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 54a.) => "Conexant CX24123 based"
49b.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24113/CX24128 tuner for DVB-S/DSS" 55b.) => "Conexant CX24113/CX24128 tuner for DVB-S/DSS"
50c.)"Multimedia devices" => "Customise DVB frontends" => "Conexant CX24123 based" 56c.) => "ISL6421 SEC controller"
51d.)"Multimedia devices" => "Customise DVB frontends" => "ISL6421 SEC controller"
52 57
535.) AirStar DVB-T card: 585.) AirStar DVB-T card:
54a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 59a.) => "Zarlink MT352 based"
55b.)"Multimedia devices" => "Customise DVB frontends" => "Zarlink MT352 based" 60b.) => "Generic I2C PLL based tuners"
56 61
576.) CableStar DVB-C card: 626.) CableStar DVB-C card:
58a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 63a.) => "ST STV0297 based"
59b.)"Multimedia devices" => "Customise DVB frontends" => "ST STV0297 based" 64b.) => "Generic I2C PLL based tuners"
60 65
617.) AirStar ATSC card 1st generation: 667.) AirStar ATSC card 1st generation:
62a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 67a.) => "Broadcom BCM3510"
63b.)"Multimedia devices" => "Customise DVB frontends" => "Broadcom BCM3510"
64 68
658.) AirStar ATSC card 2nd generation: 698.) AirStar ATSC card 2nd generation:
66a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 70a.) => "NxtWave Communications NXT2002/NXT2004 based"
67b.)"Multimedia devices" => "Customise DVB frontends" => "NxtWave Communications NXT2002/NXT2004 based" 71b.) => "Generic I2C PLL based tuners"
68c.)"Multimedia devices" => "Customise DVB frontends" => "Generic I2C PLL based tuners"
69 72
709.) AirStar ATSC card 3rd generation: 739.) AirStar ATSC card 3rd generation:
71a.)"Multimedia devices" => "Customise DVB frontends" => "Customise the frontend modules to build" 74a.) => "LG Electronics LGDT3302/LGDT3303 based"
72b.)"Multimedia devices" => "Customise DVB frontends" => "LG Electronics LGDT3302/LGDT3303 based" 75b.) "Multimedia support" => "Customise analog and hybrid tuner modules to build"
73c.)"Multimedia devices" => "Customise analog and hybrid tuner modules to build" => "Simple tuner support" 76 => "Simple tuner support"
74 77
75Author: Uwe Bugla <uwe.bugla@gmx.de> February 2009 78Author: Uwe Bugla <uwe.bugla@gmx.de> August 2009
diff --git a/Documentation/video4linux/CARDLIST.cx23885 b/Documentation/video4linux/CARDLIST.cx23885
index 525edb37c758..5f33d8486102 100644
--- a/Documentation/video4linux/CARDLIST.cx23885
+++ b/Documentation/video4linux/CARDLIST.cx23885
@@ -23,3 +23,4 @@
23 22 -> Mygica X8506 DMB-TH [14f1:8651] 23 22 -> Mygica X8506 DMB-TH [14f1:8651]
24 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657] 24 23 -> Magic-Pro ProHDTV Extreme 2 [14f1:8657]
25 24 -> Hauppauge WinTV-HVR1850 [0070:8541] 25 24 -> Hauppauge WinTV-HVR1850 [0070:8541]
26 25 -> Compro VideoMate E800 [1858:e800]
diff --git a/Documentation/video4linux/CARDLIST.em28xx b/Documentation/video4linux/CARDLIST.em28xx
index b13fcbd5d94b..b8afef4c0e01 100644
--- a/Documentation/video4linux/CARDLIST.em28xx
+++ b/Documentation/video4linux/CARDLIST.em28xx
@@ -1,5 +1,5 @@
1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800] 1 0 -> Unknown EM2800 video grabber (em2800) [eb1a:2800]
2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883] 2 1 -> Unknown EM2750/28xx video grabber (em2820/em2840) [eb1a:2710,eb1a:2820,eb1a:2821,eb1a:2860,eb1a:2861,eb1a:2870,eb1a:2881,eb1a:2883,eb1a:2868]
3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036] 3 2 -> Terratec Cinergy 250 USB (em2820/em2840) [0ccd:0036]
4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208] 4 3 -> Pinnacle PCTV USB 2 (em2820/em2840) [2304:0208]
5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201] 5 4 -> Hauppauge WinTV USB 2 (em2820/em2840) [2040:4200,2040:4201]
@@ -68,3 +68,4 @@
68 70 -> Evga inDtube (em2882) 68 70 -> Evga inDtube (em2882)
69 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840) 69 71 -> Silvercrest Webcam 1.3mpix (em2820/em2840)
70 72 -> Gadmei UTV330+ (em2861) 70 72 -> Gadmei UTV330+ (em2861)
71 73 -> Reddo DVB-C USB TV Box (em2870)
diff --git a/Documentation/video4linux/CARDLIST.saa7134 b/Documentation/video4linux/CARDLIST.saa7134
index 0ac4d2544778..2620d60341ee 100644
--- a/Documentation/video4linux/CARDLIST.saa7134
+++ b/Documentation/video4linux/CARDLIST.saa7134
@@ -171,3 +171,4 @@
171170 -> AverMedia AverTV Studio 505 [1461:a115] 171170 -> AverMedia AverTV Studio 505 [1461:a115]
172171 -> Beholder BeholdTV X7 [5ace:7595] 172171 -> Beholder BeholdTV X7 [5ace:7595]
173172 -> RoverMedia TV Link Pro FM [19d1:0138] 173172 -> RoverMedia TV Link Pro FM [19d1:0138]
174173 -> Zolid Hybrid TV Tuner PCI [1131:2004]
diff --git a/Documentation/video4linux/CARDLIST.saa7164 b/Documentation/video4linux/CARDLIST.saa7164
new file mode 100644
index 000000000000..152bd7b781ca
--- /dev/null
+++ b/Documentation/video4linux/CARDLIST.saa7164
@@ -0,0 +1,9 @@
1 0 -> Unknown
2 1 -> Generic Rev2
3 2 -> Generic Rev3
4 3 -> Hauppauge WinTV-HVR2250 [0070:8880,0070:8810]
5 4 -> Hauppauge WinTV-HVR2200 [0070:8980]
6 5 -> Hauppauge WinTV-HVR2200 [0070:8900]
7 6 -> Hauppauge WinTV-HVR2200 [0070:8901]
8 7 -> Hauppauge WinTV-HVR2250 [0070:8891,0070:8851]
9 8 -> Hauppauge WinTV-HVR2250 [0070:88A1]
diff --git a/Documentation/video4linux/CARDLIST.tuner b/Documentation/video4linux/CARDLIST.tuner
index ba9fa679e2d3..e0d298fe8830 100644
--- a/Documentation/video4linux/CARDLIST.tuner
+++ b/Documentation/video4linux/CARDLIST.tuner
@@ -79,3 +79,5 @@ tuner=78 - Philips FMD1216MEX MK3 Hybrid Tuner
79tuner=79 - Philips PAL/SECAM multi (FM1216 MK5) 79tuner=79 - Philips PAL/SECAM multi (FM1216 MK5)
80tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough 80tuner=80 - Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough
81tuner=81 - Partsnic (Daewoo) PTI-5NF05 81tuner=81 - Partsnic (Daewoo) PTI-5NF05
82tuner=82 - Philips CU1216L
83tuner=83 - NXP TDA18271
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 4686e84dd800..3f61825be499 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -173,6 +173,8 @@ ov519 05a9:8519 OmniVision
173ov519 05a9:a518 D-Link DSB-C310 Webcam 173ov519 05a9:a518 D-Link DSB-C310 Webcam
174sunplus 05da:1018 Digital Dream Enigma 1.3 174sunplus 05da:1018 Digital Dream Enigma 1.3
175stk014 05e1:0893 Syntek DV4000 175stk014 05e1:0893 Syntek DV4000
176gl860 05e3:0503 Genesys Logic PC Camera
177gl860 05e3:f191 Genesys Logic PC Camera
176spca561 060b:a001 Maxell Compact Pc PM3 178spca561 060b:a001 Maxell Compact Pc PM3
177zc3xx 0698:2003 CTX M730V built in 179zc3xx 0698:2003 CTX M730V built in
178spca500 06bd:0404 Agfa CL20 180spca500 06bd:0404 Agfa CL20
diff --git a/Documentation/video4linux/soc-camera.txt b/Documentation/video4linux/soc-camera.txt
index 178ef3c5e579..3f87c7da4ca2 100644
--- a/Documentation/video4linux/soc-camera.txt
+++ b/Documentation/video4linux/soc-camera.txt
@@ -116,5 +116,45 @@ functionality.
116struct soc_camera_device also links to an array of struct soc_camera_data_format, 116struct soc_camera_device also links to an array of struct soc_camera_data_format,
117listing pixel formats, supported by the camera. 117listing pixel formats, supported by the camera.
118 118
119VIDIOC_S_CROP and VIDIOC_S_FMT behaviour
120----------------------------------------
121
122Above user ioctls modify image geometry as follows:
123
124VIDIOC_S_CROP: sets location and sizes of the sensor window. Unit is one sensor
125pixel. Changing sensor window sizes preserves any scaling factors, therefore
126user window sizes change as well.
127
128VIDIOC_S_FMT: sets user window. Should preserve previously set sensor window as
129much as possible by modifying scaling factors. If the sensor window cannot be
130preserved precisely, it may be changed too.
131
132In soc-camera there are two locations, where scaling and cropping can taks
133place: in the camera driver and in the host driver. User ioctls are first passed
134to the host driver, which then generally passes them down to the camera driver.
135It is more efficient to perform scaling and cropping in the camera driver to
136save camera bus bandwidth and maximise the framerate. However, if the camera
137driver failed to set the required parameters with sufficient precision, the host
138driver may decide to also use its own scaling and cropping to fulfill the user's
139request.
140
141Camera drivers are interfaced to the soc-camera core and to host drivers over
142the v4l2-subdev API, which is completely functional, it doesn't pass any data.
143Therefore all camera drivers shall reply to .g_fmt() requests with their current
144output geometry. This is necessary to correctly configure the camera bus.
145.s_fmt() and .try_fmt() have to be implemented too. Sensor window and scaling
146factors have to be maintained by camera drivers internally. According to the
147V4L2 API all capture drivers must support the VIDIOC_CROPCAP ioctl, hence we
148rely on camera drivers implementing .cropcap(). If the camera driver does not
149support cropping, it may choose to not implement .s_crop(), but to enable
150cropping support by the camera host driver at least the .g_crop method must be
151implemented.
152
153User window geometry is kept in .user_width and .user_height fields in struct
154soc_camera_device and used by the soc-camera core and host drivers. The core
155updates these fields upon successful completion of a .s_fmt() call, but if these
156fields change elsewhere, e.g., during .s_crop() processing, the host driver is
157responsible for updating them.
158
119-- 159--
120Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de> 160Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index ba4706afc5fb..b806edaf3e75 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -370,19 +370,20 @@ from the remove() callback ensures that this is always done correctly.
370The bridge driver also has some helper functions it can use: 370The bridge driver also has some helper functions it can use:
371 371
372struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter, 372struct v4l2_subdev *sd = v4l2_i2c_new_subdev(v4l2_dev, adapter,
373 "module_foo", "chipid", 0x36); 373 "module_foo", "chipid", 0x36, NULL);
374 374
375This loads the given module (can be NULL if no module needs to be loaded) and 375This loads the given module (can be NULL if no module needs to be loaded) and
376calls i2c_new_device() with the given i2c_adapter and chip/address arguments. 376calls i2c_new_device() with the given i2c_adapter and chip/address arguments.
377If all goes well, then it registers the subdev with the v4l2_device. 377If all goes well, then it registers the subdev with the v4l2_device.
378 378
379You can also use v4l2_i2c_new_probed_subdev() which is very similar to 379You can also use the last argument of v4l2_i2c_new_subdev() to pass an array
380v4l2_i2c_new_subdev(), except that it has an array of possible I2C addresses 380of possible I2C addresses that it should probe. These probe addresses are
381that it should probe. Internally it calls i2c_new_probed_device(). 381only used if the previous argument is 0. A non-zero argument means that you
382know the exact i2c address so in that case no probing will take place.
382 383
383Both functions return NULL if something went wrong. 384Both functions return NULL if something went wrong.
384 385
385Note that the chipid you pass to v4l2_i2c_new_(probed_)subdev() is usually 386Note that the chipid you pass to v4l2_i2c_new_subdev() is usually
386the same as the module name. It allows you to specify a chip variant, e.g. 387the same as the module name. It allows you to specify a chip variant, e.g.
387"saa7114" or "saa7115". In general though the i2c driver autodetects this. 388"saa7114" or "saa7115". In general though the i2c driver autodetects this.
388The use of chipid is something that needs to be looked at more closely at a 389The use of chipid is something that needs to be looked at more closely at a
@@ -410,11 +411,6 @@ the irq and platform_data arguments after the subdev was setup. The older
410v4l2_i2c_new_(probed_)subdev functions will call s_config as well, but with 411v4l2_i2c_new_(probed_)subdev functions will call s_config as well, but with
411irq set to 0 and platform_data set to NULL. 412irq set to 0 and platform_data set to NULL.
412 413
413Note that in the next kernel release the functions v4l2_i2c_new_subdev,
414v4l2_i2c_new_probed_subdev and v4l2_i2c_new_probed_subdev_addr will all be
415replaced by a single v4l2_i2c_new_subdev that is identical to
416v4l2_i2c_new_subdev_cfg but without the irq and platform_data arguments.
417
418struct video_device 414struct video_device
419------------------- 415-------------------
420 416
@@ -490,31 +486,35 @@ VFL_TYPE_RADIO: radioX for radio tuners
490VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use) 486VFL_TYPE_VTX: vtxX for teletext devices (deprecated, don't use)
491 487
492The last argument gives you a certain amount of control over the device 488The last argument gives you a certain amount of control over the device
493kernel number used (i.e. the X in videoX). Normally you will pass -1 to 489device node number used (i.e. the X in videoX). Normally you will pass -1
494let the v4l2 framework pick the first free number. But if a driver creates 490to let the v4l2 framework pick the first free number. But sometimes users
495many devices, then it can be useful to have different video devices in 491want to select a specific node number. It is common that drivers allow
496separate ranges. For example, video capture devices start at 0, video 492the user to select a specific device node number through a driver module
497output devices start at 16. 493option. That number is then passed to this function and video_register_device
498 494will attempt to select that device node number. If that number was already
499So you can use the last argument to specify a minimum kernel number and 495in use, then the next free device node number will be selected and it
500the v4l2 framework will try to pick the first free number that is equal 496will send a warning to the kernel log.
497
498Another use-case is if a driver creates many devices. In that case it can
499be useful to place different video devices in separate ranges. For example,
500video capture devices start at 0, video output devices start at 16.
501So you can use the last argument to specify a minimum device node number
502and the v4l2 framework will try to pick the first free number that is equal
501or higher to what you passed. If that fails, then it will just pick the 503or higher to what you passed. If that fails, then it will just pick the
502first free number. 504first free number.
503 505
506Since in this case you do not care about a warning about not being able
507to select the specified device node number, you can call the function
508video_register_device_no_warn() instead.
509
504Whenever a device node is created some attributes are also created for you. 510Whenever a device node is created some attributes are also created for you.
505If you look in /sys/class/video4linux you see the devices. Go into e.g. 511If you look in /sys/class/video4linux you see the devices. Go into e.g.
506video0 and you will see 'name' and 'index' attributes. The 'name' attribute 512video0 and you will see 'name' and 'index' attributes. The 'name' attribute
507is the 'name' field of the video_device struct. The 'index' attribute is 513is the 'name' field of the video_device struct.
508a device node index that can be assigned by the driver, or that is calculated
509for you.
510
511If you call video_register_device(), then the index is just increased by
5121 for each device node you register. The first video device node you register
513always starts off with 0.
514 514
515Alternatively you can call video_register_device_index() which is identical 515The 'index' attribute is the index of the device node: for each call to
516to video_register_device(), but with an extra index argument. Here you can 516video_register_device() the index is just increased by 1. The first video
517pass a specific index value (between 0 and 31) that should be used. 517device node you register always starts with index 0.
518 518
519Users can setup udev rules that utilize the index attribute to make fancy 519Users can setup udev rules that utilize the index attribute to make fancy
520device names (e.g. 'mpegX' for MPEG video capture device nodes). 520device names (e.g. 'mpegX' for MPEG video capture device nodes).
@@ -523,9 +523,8 @@ After the device was successfully registered, then you can use these fields:
523 523
524- vfl_type: the device type passed to video_register_device. 524- vfl_type: the device type passed to video_register_device.
525- minor: the assigned device minor number. 525- minor: the assigned device minor number.
526- num: the device kernel number (i.e. the X in videoX). 526- num: the device node number (i.e. the X in videoX).
527- index: the device index number (calculated or set explicitly using 527- index: the device index number.
528 video_register_device_index).
529 528
530If the registration failed, then you need to call video_device_release() 529If the registration failed, then you need to call video_device_release()
531to free the allocated video_device struct, or free your own struct if the 530to free the allocated video_device struct, or free your own struct if the
diff --git a/arch/sh/boards/board-ap325rxa.c b/arch/sh/boards/board-ap325rxa.c
index 327d47c25a57..2d080732a964 100644
--- a/arch/sh/boards/board-ap325rxa.c
+++ b/arch/sh/boards/board-ap325rxa.c
@@ -310,8 +310,10 @@ static int camera_set_capture(struct soc_camera_platform_info *info,
310 return ret; 310 return ret;
311} 311}
312 312
313static int ap325rxa_camera_add(struct soc_camera_link *icl, struct device *dev);
314static void ap325rxa_camera_del(struct soc_camera_link *icl);
315
313static struct soc_camera_platform_info camera_info = { 316static struct soc_camera_platform_info camera_info = {
314 .iface = 0,
315 .format_name = "UYVY", 317 .format_name = "UYVY",
316 .format_depth = 16, 318 .format_depth = 16,
317 .format = { 319 .format = {
@@ -323,24 +325,46 @@ static struct soc_camera_platform_info camera_info = {
323 .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH | 325 .bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
324 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8, 326 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8,
325 .set_capture = camera_set_capture, 327 .set_capture = camera_set_capture,
328 .link = {
329 .bus_id = 0,
330 .add_device = ap325rxa_camera_add,
331 .del_device = ap325rxa_camera_del,
332 .module_name = "soc_camera_platform",
333 },
326}; 334};
327 335
336static void dummy_release(struct device *dev)
337{
338}
339
328static struct platform_device camera_device = { 340static struct platform_device camera_device = {
329 .name = "soc_camera_platform", 341 .name = "soc_camera_platform",
330 .dev = { 342 .dev = {
331 .platform_data = &camera_info, 343 .platform_data = &camera_info,
344 .release = dummy_release,
332 }, 345 },
333}; 346};
334 347
335static int __init camera_setup(void) 348static int ap325rxa_camera_add(struct soc_camera_link *icl,
349 struct device *dev)
336{ 350{
337 if (camera_probe() > 0) 351 if (icl != &camera_info.link || camera_probe() <= 0)
338 platform_device_register(&camera_device); 352 return -ENODEV;
339 353
340 return 0; 354 camera_info.dev = dev;
355
356 return platform_device_register(&camera_device);
341} 357}
342late_initcall(camera_setup);
343 358
359static void ap325rxa_camera_del(struct soc_camera_link *icl)
360{
361 if (icl != &camera_info.link)
362 return;
363
364 platform_device_unregister(&camera_device);
365 memset(&camera_device.dev.kobj, 0,
366 sizeof(camera_device.dev.kobj));
367}
344#endif /* CONFIG_I2C */ 368#endif /* CONFIG_I2C */
345 369
346static int ov7725_power(struct device *dev, int mode) 370static int ov7725_power(struct device *dev, int mode)
@@ -416,6 +440,7 @@ static struct ov772x_camera_info ov7725_info = {
416 .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP, 440 .flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
417 .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0), 441 .edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
418 .link = { 442 .link = {
443 .bus_id = 0,
419 .power = ov7725_power, 444 .power = ov7725_power,
420 .board_info = &ap325rxa_i2c_camera[0], 445 .board_info = &ap325rxa_i2c_camera[0],
421 .i2c_adapter_id = 0, 446 .i2c_adapter_id = 0,
@@ -423,11 +448,19 @@ static struct ov772x_camera_info ov7725_info = {
423 }, 448 },
424}; 449};
425 450
426static struct platform_device ap325rxa_camera = { 451static struct platform_device ap325rxa_camera[] = {
427 .name = "soc-camera-pdrv", 452 {
428 .id = 0, 453 .name = "soc-camera-pdrv",
429 .dev = { 454 .id = 0,
430 .platform_data = &ov7725_info.link, 455 .dev = {
456 .platform_data = &ov7725_info.link,
457 },
458 }, {
459 .name = "soc-camera-pdrv",
460 .id = 1,
461 .dev = {
462 .platform_data = &camera_info.link,
463 },
431 }, 464 },
432}; 465};
433 466
@@ -438,7 +471,8 @@ static struct platform_device *ap325rxa_devices[] __initdata = {
438 &ceu_device, 471 &ceu_device,
439 &nand_flash_device, 472 &nand_flash_device,
440 &sdcard_cn3_device, 473 &sdcard_cn3_device,
441 &ap325rxa_camera, 474 &ap325rxa_camera[0],
475 &ap325rxa_camera[1],
442}; 476};
443 477
444static struct spi_board_info ap325rxa_spi_devices[] = { 478static struct spi_board_info ap325rxa_spi_devices[] = {
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index fc76c30e24f1..155c93eb75da 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -210,7 +210,8 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
210 tda18271_i2c_gate_ctrl(fe, 0); 210 tda18271_i2c_gate_ctrl(fe, 0);
211 211
212 if (ret != 1) 212 if (ret != 1)
213 tda_err("ERROR: i2c_transfer returned: %d\n", ret); 213 tda_err("ERROR: idx = 0x%x, len = %d, "
214 "i2c_transfer returned: %d\n", idx, len, ret);
214 215
215 return (ret == 1 ? 0 : ret); 216 return (ret == 1 ? 0 : ret);
216} 217}
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index bc4b004ba7db..64595112000d 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -36,6 +36,27 @@ static LIST_HEAD(hybrid_tuner_instance_list);
36 36
37/*---------------------------------------------------------------------*/ 37/*---------------------------------------------------------------------*/
38 38
39static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
40{
41 struct tda18271_priv *priv = fe->tuner_priv;
42
43 int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
44 priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
45 priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
46
47 if (tda_fail(ret))
48 goto fail;
49
50 tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
51 standby ? "standby" : "active",
52 priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
53 priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
54fail:
55 return ret;
56}
57
58/*---------------------------------------------------------------------*/
59
39static inline int charge_pump_source(struct dvb_frontend *fe, int force) 60static inline int charge_pump_source(struct dvb_frontend *fe, int force)
40{ 61{
41 struct tda18271_priv *priv = fe->tuner_priv; 62 struct tda18271_priv *priv = fe->tuner_priv;
@@ -271,7 +292,7 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
271 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); 292 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
272 293
273 /* calculate temperature compensation */ 294 /* calculate temperature compensation */
274 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal); 295 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000;
275 296
276 regs[R_EB14] = approx + rfcal_comp; 297 regs[R_EB14] = approx + rfcal_comp;
277 ret = tda18271_write_regs(fe, R_EB14, 1); 298 ret = tda18271_write_regs(fe, R_EB14, 1);
@@ -800,7 +821,7 @@ static int tda18271_init(struct dvb_frontend *fe)
800 821
801 mutex_lock(&priv->lock); 822 mutex_lock(&priv->lock);
802 823
803 /* power up */ 824 /* full power up */
804 ret = tda18271_set_standby_mode(fe, 0, 0, 0); 825 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
805 if (tda_fail(ret)) 826 if (tda_fail(ret))
806 goto fail; 827 goto fail;
@@ -818,6 +839,21 @@ fail:
818 return ret; 839 return ret;
819} 840}
820 841
842static int tda18271_sleep(struct dvb_frontend *fe)
843{
844 struct tda18271_priv *priv = fe->tuner_priv;
845 int ret;
846
847 mutex_lock(&priv->lock);
848
849 /* enter standby mode, with required output features enabled */
850 ret = tda18271_toggle_output(fe, 1);
851
852 mutex_unlock(&priv->lock);
853
854 return ret;
855}
856
821/* ------------------------------------------------------------------ */ 857/* ------------------------------------------------------------------ */
822 858
823static int tda18271_agc(struct dvb_frontend *fe) 859static int tda18271_agc(struct dvb_frontend *fe)
@@ -827,8 +863,9 @@ static int tda18271_agc(struct dvb_frontend *fe)
827 863
828 switch (priv->config) { 864 switch (priv->config) {
829 case 0: 865 case 0:
830 /* no LNA */ 866 /* no external agc configuration required */
831 tda_dbg("no agc configuration provided\n"); 867 if (tda18271_debug & DBG_ADV)
868 tda_dbg("no agc configuration provided\n");
832 break; 869 break;
833 case 3: 870 case 3:
834 /* switch with GPIO of saa713x */ 871 /* switch with GPIO of saa713x */
@@ -1010,22 +1047,6 @@ fail:
1010 return ret; 1047 return ret;
1011} 1048}
1012 1049
1013static int tda18271_sleep(struct dvb_frontend *fe)
1014{
1015 struct tda18271_priv *priv = fe->tuner_priv;
1016 int ret;
1017
1018 mutex_lock(&priv->lock);
1019
1020 /* standby mode w/ slave tuner output
1021 * & loop thru & xtal oscillator on */
1022 ret = tda18271_set_standby_mode(fe, 1, 0, 0);
1023
1024 mutex_unlock(&priv->lock);
1025
1026 return ret;
1027}
1028
1029static int tda18271_release(struct dvb_frontend *fe) 1050static int tda18271_release(struct dvb_frontend *fe)
1030{ 1051{
1031 struct tda18271_priv *priv = fe->tuner_priv; 1052 struct tda18271_priv *priv = fe->tuner_priv;
@@ -1199,6 +1220,9 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1199 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; 1220 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1200 priv->role = (cfg) ? cfg->role : TDA18271_MASTER; 1221 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1201 priv->config = (cfg) ? cfg->config : 0; 1222 priv->config = (cfg) ? cfg->config : 0;
1223 priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
1224 priv->output_opt = (cfg) ?
1225 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1202 1226
1203 /* tda18271_cal_on_startup == -1 when cal 1227 /* tda18271_cal_on_startup == -1 when cal
1204 * module option is unset */ 1228 * module option is unset */
@@ -1216,9 +1240,6 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1216 1240
1217 fe->tuner_priv = priv; 1241 fe->tuner_priv = priv;
1218 1242
1219 if (cfg)
1220 priv->small_i2c = cfg->small_i2c;
1221
1222 if (tda_fail(tda18271_get_id(fe))) 1243 if (tda_fail(tda18271_get_id(fe)))
1223 goto fail; 1244 goto fail;
1224 1245
@@ -1238,9 +1259,19 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1238 /* existing tuner instance */ 1259 /* existing tuner instance */
1239 fe->tuner_priv = priv; 1260 fe->tuner_priv = priv;
1240 1261
1241 /* allow dvb driver to override i2c gate setting */ 1262 /* allow dvb driver to override configuration settings */
1242 if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG)) 1263 if (cfg) {
1243 priv->gate = cfg->gate; 1264 if (cfg->gate != TDA18271_GATE_ANALOG)
1265 priv->gate = cfg->gate;
1266 if (cfg->role)
1267 priv->role = cfg->role;
1268 if (cfg->config)
1269 priv->config = cfg->config;
1270 if (cfg->small_i2c)
1271 priv->small_i2c = cfg->small_i2c;
1272 if (cfg->output_opt)
1273 priv->output_opt = cfg->output_opt;
1274 }
1244 break; 1275 break;
1245 } 1276 }
1246 1277
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index ab14ceb9e0ce..e21fdeff3ddf 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -962,10 +962,9 @@ struct tda18271_cid_target_map {
962static struct tda18271_cid_target_map tda18271_cid_target[] = { 962static struct tda18271_cid_target_map tda18271_cid_target[] = {
963 { .rfmax = 46000, .target = 0x04, .limit = 1800 }, 963 { .rfmax = 46000, .target = 0x04, .limit = 1800 },
964 { .rfmax = 52200, .target = 0x0a, .limit = 1500 }, 964 { .rfmax = 52200, .target = 0x0a, .limit = 1500 },
965 { .rfmax = 79100, .target = 0x01, .limit = 4000 }, 965 { .rfmax = 70100, .target = 0x01, .limit = 4000 },
966 { .rfmax = 136800, .target = 0x18, .limit = 4000 }, 966 { .rfmax = 136800, .target = 0x18, .limit = 4000 },
967 { .rfmax = 156700, .target = 0x18, .limit = 4000 }, 967 { .rfmax = 156700, .target = 0x18, .limit = 4000 },
968 { .rfmax = 156700, .target = 0x18, .limit = 4000 },
969 { .rfmax = 186250, .target = 0x0a, .limit = 4000 }, 968 { .rfmax = 186250, .target = 0x0a, .limit = 4000 },
970 { .rfmax = 230000, .target = 0x0a, .limit = 4000 }, 969 { .rfmax = 230000, .target = 0x0a, .limit = 4000 },
971 { .rfmax = 345000, .target = 0x18, .limit = 4000 }, 970 { .rfmax = 345000, .target = 0x18, .limit = 4000 },
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index e6a80ad09356..2bee229acd91 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -108,6 +108,7 @@ struct tda18271_priv {
108 enum tda18271_role role; 108 enum tda18271_role role;
109 enum tda18271_i2c_gate gate; 109 enum tda18271_i2c_gate gate;
110 enum tda18271_ver id; 110 enum tda18271_ver id;
111 enum tda18271_output_options output_opt;
111 112
112 unsigned int config; /* interface to saa713x / tda829x */ 113 unsigned int config; /* interface to saa713x / tda829x */
113 unsigned int tm_rfcal; 114 unsigned int tm_rfcal;
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 71bac9593f1e..323f2912128d 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -67,6 +67,17 @@ enum tda18271_i2c_gate {
67 TDA18271_GATE_DIGITAL, 67 TDA18271_GATE_DIGITAL,
68}; 68};
69 69
70enum tda18271_output_options {
71 /* slave tuner output & loop thru & xtal oscillator always on */
72 TDA18271_OUTPUT_LT_XT_ON = 0,
73
74 /* slave tuner output loop thru off */
75 TDA18271_OUTPUT_LT_OFF = 1,
76
77 /* xtal oscillator off */
78 TDA18271_OUTPUT_XT_OFF = 2,
79};
80
70struct tda18271_config { 81struct tda18271_config {
71 /* override default if freq / std settings (optional) */ 82 /* override default if freq / std settings (optional) */
72 struct tda18271_std_map *std_map; 83 struct tda18271_std_map *std_map;
@@ -77,6 +88,9 @@ struct tda18271_config {
77 /* use i2c gate provided by analog or digital demod */ 88 /* use i2c gate provided by analog or digital demod */
78 enum tda18271_i2c_gate gate; 89 enum tda18271_i2c_gate gate;
79 90
91 /* output options that can be disabled */
92 enum tda18271_output_options output_opt;
93
80 /* force rf tracking filter calibration on startup */ 94 /* force rf tracking filter calibration on startup */
81 unsigned int rf_cal_on_startup:1; 95 unsigned int rf_cal_on_startup:1;
82 96
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 5c6ef1e23c94..2b876f3988c1 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -1320,6 +1320,23 @@ static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
1320 }, 1320 },
1321}; 1321};
1322 1322
1323/* --------- TUNER_PHILIPS_CU1216L - DVB-C NIM ------------------------- */
1324
1325static struct tuner_range tuner_cu1216l_ranges[] = {
1326 { 16 * 160.25 /*MHz*/, 0xce, 0x01 },
1327 { 16 * 444.25 /*MHz*/, 0xce, 0x02 },
1328 { 16 * 999.99 , 0xce, 0x04 },
1329};
1330
1331static struct tuner_params tuner_philips_cu1216l_params[] = {
1332 {
1333 .type = TUNER_PARAM_TYPE_DIGITAL,
1334 .ranges = tuner_cu1216l_ranges,
1335 .count = ARRAY_SIZE(tuner_cu1216l_ranges),
1336 .iffreq = 16 * 36.125, /*MHz*/
1337 },
1338};
1339
1323/* --------------------------------------------------------------------- */ 1340/* --------------------------------------------------------------------- */
1324 1341
1325struct tunertype tuners[] = { 1342struct tunertype tuners[] = {
@@ -1778,6 +1795,16 @@ struct tunertype tuners[] = {
1778 .params = tuner_partsnic_pti_5nf05_params, 1795 .params = tuner_partsnic_pti_5nf05_params,
1779 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params), 1796 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
1780 }, 1797 },
1798 [TUNER_PHILIPS_CU1216L] = {
1799 .name = "Philips CU1216L",
1800 .params = tuner_philips_cu1216l_params,
1801 .count = ARRAY_SIZE(tuner_philips_cu1216l_params),
1802 .stepsize = 62500,
1803 },
1804 [TUNER_NXP_TDA18271] = {
1805 .name = "NXP TDA18271",
1806 /* see tda18271-fe.c for details */
1807 },
1781}; 1808};
1782EXPORT_SYMBOL(tuners); 1809EXPORT_SYMBOL(tuners);
1783 1810
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 1d0e4b1ef10c..35d0817126e9 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -68,6 +68,10 @@ comment "Supported FireWire (IEEE 1394) Adapters"
68 depends on DVB_CORE && IEEE1394 68 depends on DVB_CORE && IEEE1394
69source "drivers/media/dvb/firewire/Kconfig" 69source "drivers/media/dvb/firewire/Kconfig"
70 70
71comment "Supported Earthsoft PT1 Adapters"
72 depends on DVB_CORE && PCI && I2C
73source "drivers/media/dvb/pt1/Kconfig"
74
71comment "Supported DVB Frontends" 75comment "Supported DVB Frontends"
72 depends on DVB_CORE 76 depends on DVB_CORE
73source "drivers/media/dvb/frontends/Kconfig" 77source "drivers/media/dvb/frontends/Kconfig"
diff --git a/drivers/media/dvb/Makefile b/drivers/media/dvb/Makefile
index 6092a5bb5a7d..16d262ddb45d 100644
--- a/drivers/media/dvb/Makefile
+++ b/drivers/media/dvb/Makefile
@@ -2,6 +2,6 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ 5obj-y := dvb-core/ frontends/ ttpci/ ttusb-dec/ ttusb-budget/ b2c2/ bt8xx/ dvb-usb/ pluto2/ siano/ dm1105/ pt1/
6 6
7obj-$(CONFIG_DVB_FIREDTV) += firewire/ 7obj-$(CONFIG_DVB_FIREDTV) += firewire/
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c
index d13ebcb0c6b6..ddf639ed2fd8 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -850,6 +850,49 @@ static int dvb_frontend_check_parameters(struct dvb_frontend *fe,
850 return 0; 850 return 0;
851} 851}
852 852
853static int dvb_frontend_clear_cache(struct dvb_frontend *fe)
854{
855 int i;
856
857 memset(&(fe->dtv_property_cache), 0,
858 sizeof(struct dtv_frontend_properties));
859
860 fe->dtv_property_cache.state = DTV_CLEAR;
861 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
862 fe->dtv_property_cache.inversion = INVERSION_AUTO;
863 fe->dtv_property_cache.fec_inner = FEC_AUTO;
864 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
865 fe->dtv_property_cache.bandwidth_hz = BANDWIDTH_AUTO;
866 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
867 fe->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
868 fe->dtv_property_cache.symbol_rate = QAM_AUTO;
869 fe->dtv_property_cache.code_rate_HP = FEC_AUTO;
870 fe->dtv_property_cache.code_rate_LP = FEC_AUTO;
871
872 fe->dtv_property_cache.isdbt_partial_reception = -1;
873 fe->dtv_property_cache.isdbt_sb_mode = -1;
874 fe->dtv_property_cache.isdbt_sb_subchannel = -1;
875 fe->dtv_property_cache.isdbt_sb_segment_idx = -1;
876 fe->dtv_property_cache.isdbt_sb_segment_count = -1;
877 fe->dtv_property_cache.isdbt_layer_enabled = 0x7;
878 for (i = 0; i < 3; i++) {
879 fe->dtv_property_cache.layer[i].fec = FEC_AUTO;
880 fe->dtv_property_cache.layer[i].modulation = QAM_AUTO;
881 fe->dtv_property_cache.layer[i].interleaving = -1;
882 fe->dtv_property_cache.layer[i].segment_count = -1;
883 }
884
885 return 0;
886}
887
888#define _DTV_CMD(n, s, b) \
889[n] = { \
890 .name = #n, \
891 .cmd = n, \
892 .set = s,\
893 .buffer = b \
894}
895
853static struct dtv_cmds_h dtv_cmds[] = { 896static struct dtv_cmds_h dtv_cmds[] = {
854 [DTV_TUNE] = { 897 [DTV_TUNE] = {
855 .name = "DTV_TUNE", 898 .name = "DTV_TUNE",
@@ -949,6 +992,47 @@ static struct dtv_cmds_h dtv_cmds[] = {
949 .cmd = DTV_TRANSMISSION_MODE, 992 .cmd = DTV_TRANSMISSION_MODE,
950 .set = 1, 993 .set = 1,
951 }, 994 },
995
996 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1, 0),
997 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 1, 0),
998 _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 1, 0),
999 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 1, 0),
1000 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 1, 0),
1001 _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 1, 0),
1002 _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 1, 0),
1003 _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 1, 0),
1004 _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 1, 0),
1005 _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 1, 0),
1006 _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 1, 0),
1007 _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 1, 0),
1008 _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 1, 0),
1009 _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 1, 0),
1010 _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 1, 0),
1011 _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 1, 0),
1012 _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 1, 0),
1013 _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 1, 0),
1014
1015 _DTV_CMD(DTV_ISDBT_PARTIAL_RECEPTION, 0, 0),
1016 _DTV_CMD(DTV_ISDBT_SOUND_BROADCASTING, 0, 0),
1017 _DTV_CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0, 0),
1018 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0, 0),
1019 _DTV_CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0, 0),
1020 _DTV_CMD(DTV_ISDBT_LAYER_ENABLED, 0, 0),
1021 _DTV_CMD(DTV_ISDBT_LAYERA_FEC, 0, 0),
1022 _DTV_CMD(DTV_ISDBT_LAYERA_MODULATION, 0, 0),
1023 _DTV_CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT, 0, 0),
1024 _DTV_CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING, 0, 0),
1025 _DTV_CMD(DTV_ISDBT_LAYERB_FEC, 0, 0),
1026 _DTV_CMD(DTV_ISDBT_LAYERB_MODULATION, 0, 0),
1027 _DTV_CMD(DTV_ISDBT_LAYERB_SEGMENT_COUNT, 0, 0),
1028 _DTV_CMD(DTV_ISDBT_LAYERB_TIME_INTERLEAVING, 0, 0),
1029 _DTV_CMD(DTV_ISDBT_LAYERC_FEC, 0, 0),
1030 _DTV_CMD(DTV_ISDBT_LAYERC_MODULATION, 0, 0),
1031 _DTV_CMD(DTV_ISDBT_LAYERC_SEGMENT_COUNT, 0, 0),
1032 _DTV_CMD(DTV_ISDBT_LAYERC_TIME_INTERLEAVING, 0, 0),
1033
1034 _DTV_CMD(DTV_ISDBS_TS_ID, 1, 0),
1035
952 /* Get */ 1036 /* Get */
953 [DTV_DISEQC_SLAVE_REPLY] = { 1037 [DTV_DISEQC_SLAVE_REPLY] = {
954 .name = "DTV_DISEQC_SLAVE_REPLY", 1038 .name = "DTV_DISEQC_SLAVE_REPLY",
@@ -956,6 +1040,7 @@ static struct dtv_cmds_h dtv_cmds[] = {
956 .set = 0, 1040 .set = 0,
957 .buffer = 1, 1041 .buffer = 1,
958 }, 1042 },
1043
959 [DTV_API_VERSION] = { 1044 [DTV_API_VERSION] = {
960 .name = "DTV_API_VERSION", 1045 .name = "DTV_API_VERSION",
961 .cmd = DTV_API_VERSION, 1046 .cmd = DTV_API_VERSION,
@@ -1165,14 +1250,21 @@ static void dtv_property_adv_params_sync(struct dvb_frontend *fe)
1165 if(c->delivery_system == SYS_ISDBT) { 1250 if(c->delivery_system == SYS_ISDBT) {
1166 /* Fake out a generic DVB-T request so we pass validation in the ioctl */ 1251 /* Fake out a generic DVB-T request so we pass validation in the ioctl */
1167 p->frequency = c->frequency; 1252 p->frequency = c->frequency;
1168 p->inversion = INVERSION_AUTO; 1253 p->inversion = c->inversion;
1169 p->u.ofdm.constellation = QAM_AUTO; 1254 p->u.ofdm.constellation = QAM_AUTO;
1170 p->u.ofdm.code_rate_HP = FEC_AUTO; 1255 p->u.ofdm.code_rate_HP = FEC_AUTO;
1171 p->u.ofdm.code_rate_LP = FEC_AUTO; 1256 p->u.ofdm.code_rate_LP = FEC_AUTO;
1172 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1173 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO; 1257 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
1174 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO; 1258 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
1175 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO; 1259 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
1260 if (c->bandwidth_hz == 8000000)
1261 p->u.ofdm.bandwidth = BANDWIDTH_8_MHZ;
1262 else if (c->bandwidth_hz == 7000000)
1263 p->u.ofdm.bandwidth = BANDWIDTH_7_MHZ;
1264 else if (c->bandwidth_hz == 6000000)
1265 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
1266 else
1267 p->u.ofdm.bandwidth = BANDWIDTH_AUTO;
1176 } 1268 }
1177} 1269}
1178 1270
@@ -1274,6 +1366,65 @@ static int dtv_property_process_get(struct dvb_frontend *fe,
1274 case DTV_HIERARCHY: 1366 case DTV_HIERARCHY:
1275 tvp->u.data = fe->dtv_property_cache.hierarchy; 1367 tvp->u.data = fe->dtv_property_cache.hierarchy;
1276 break; 1368 break;
1369
1370 /* ISDB-T Support here */
1371 case DTV_ISDBT_PARTIAL_RECEPTION:
1372 tvp->u.data = fe->dtv_property_cache.isdbt_partial_reception;
1373 break;
1374 case DTV_ISDBT_SOUND_BROADCASTING:
1375 tvp->u.data = fe->dtv_property_cache.isdbt_sb_mode;
1376 break;
1377 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1378 tvp->u.data = fe->dtv_property_cache.isdbt_sb_subchannel;
1379 break;
1380 case DTV_ISDBT_SB_SEGMENT_IDX:
1381 tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_idx;
1382 break;
1383 case DTV_ISDBT_SB_SEGMENT_COUNT:
1384 tvp->u.data = fe->dtv_property_cache.isdbt_sb_segment_count;
1385 break;
1386 case DTV_ISDBT_LAYER_ENABLED:
1387 tvp->u.data = fe->dtv_property_cache.isdbt_layer_enabled;
1388 break;
1389 case DTV_ISDBT_LAYERA_FEC:
1390 tvp->u.data = fe->dtv_property_cache.layer[0].fec;
1391 break;
1392 case DTV_ISDBT_LAYERA_MODULATION:
1393 tvp->u.data = fe->dtv_property_cache.layer[0].modulation;
1394 break;
1395 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1396 tvp->u.data = fe->dtv_property_cache.layer[0].segment_count;
1397 break;
1398 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1399 tvp->u.data = fe->dtv_property_cache.layer[0].interleaving;
1400 break;
1401 case DTV_ISDBT_LAYERB_FEC:
1402 tvp->u.data = fe->dtv_property_cache.layer[1].fec;
1403 break;
1404 case DTV_ISDBT_LAYERB_MODULATION:
1405 tvp->u.data = fe->dtv_property_cache.layer[1].modulation;
1406 break;
1407 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1408 tvp->u.data = fe->dtv_property_cache.layer[1].segment_count;
1409 break;
1410 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1411 tvp->u.data = fe->dtv_property_cache.layer[1].interleaving;
1412 break;
1413 case DTV_ISDBT_LAYERC_FEC:
1414 tvp->u.data = fe->dtv_property_cache.layer[2].fec;
1415 break;
1416 case DTV_ISDBT_LAYERC_MODULATION:
1417 tvp->u.data = fe->dtv_property_cache.layer[2].modulation;
1418 break;
1419 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1420 tvp->u.data = fe->dtv_property_cache.layer[2].segment_count;
1421 break;
1422 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1423 tvp->u.data = fe->dtv_property_cache.layer[2].interleaving;
1424 break;
1425 case DTV_ISDBS_TS_ID:
1426 tvp->u.data = fe->dtv_property_cache.isdbs_ts_id;
1427 break;
1277 default: 1428 default:
1278 r = -1; 1429 r = -1;
1279 } 1430 }
@@ -1302,10 +1453,8 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1302 /* Reset a cache of data specific to the frontend here. This does 1453 /* Reset a cache of data specific to the frontend here. This does
1303 * not effect hardware. 1454 * not effect hardware.
1304 */ 1455 */
1456 dvb_frontend_clear_cache(fe);
1305 dprintk("%s() Flushing property cache\n", __func__); 1457 dprintk("%s() Flushing property cache\n", __func__);
1306 memset(&fe->dtv_property_cache, 0, sizeof(struct dtv_frontend_properties));
1307 fe->dtv_property_cache.state = tvp->cmd;
1308 fe->dtv_property_cache.delivery_system = SYS_UNDEFINED;
1309 break; 1458 break;
1310 case DTV_TUNE: 1459 case DTV_TUNE:
1311 /* interpret the cache of data, build either a traditional frontend 1460 /* interpret the cache of data, build either a traditional frontend
@@ -1371,6 +1520,65 @@ static int dtv_property_process_set(struct dvb_frontend *fe,
1371 case DTV_HIERARCHY: 1520 case DTV_HIERARCHY:
1372 fe->dtv_property_cache.hierarchy = tvp->u.data; 1521 fe->dtv_property_cache.hierarchy = tvp->u.data;
1373 break; 1522 break;
1523
1524 /* ISDB-T Support here */
1525 case DTV_ISDBT_PARTIAL_RECEPTION:
1526 fe->dtv_property_cache.isdbt_partial_reception = tvp->u.data;
1527 break;
1528 case DTV_ISDBT_SOUND_BROADCASTING:
1529 fe->dtv_property_cache.isdbt_sb_mode = tvp->u.data;
1530 break;
1531 case DTV_ISDBT_SB_SUBCHANNEL_ID:
1532 fe->dtv_property_cache.isdbt_sb_subchannel = tvp->u.data;
1533 break;
1534 case DTV_ISDBT_SB_SEGMENT_IDX:
1535 fe->dtv_property_cache.isdbt_sb_segment_idx = tvp->u.data;
1536 break;
1537 case DTV_ISDBT_SB_SEGMENT_COUNT:
1538 fe->dtv_property_cache.isdbt_sb_segment_count = tvp->u.data;
1539 break;
1540 case DTV_ISDBT_LAYER_ENABLED:
1541 fe->dtv_property_cache.isdbt_layer_enabled = tvp->u.data;
1542 break;
1543 case DTV_ISDBT_LAYERA_FEC:
1544 fe->dtv_property_cache.layer[0].fec = tvp->u.data;
1545 break;
1546 case DTV_ISDBT_LAYERA_MODULATION:
1547 fe->dtv_property_cache.layer[0].modulation = tvp->u.data;
1548 break;
1549 case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
1550 fe->dtv_property_cache.layer[0].segment_count = tvp->u.data;
1551 break;
1552 case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
1553 fe->dtv_property_cache.layer[0].interleaving = tvp->u.data;
1554 break;
1555 case DTV_ISDBT_LAYERB_FEC:
1556 fe->dtv_property_cache.layer[1].fec = tvp->u.data;
1557 break;
1558 case DTV_ISDBT_LAYERB_MODULATION:
1559 fe->dtv_property_cache.layer[1].modulation = tvp->u.data;
1560 break;
1561 case DTV_ISDBT_LAYERB_SEGMENT_COUNT:
1562 fe->dtv_property_cache.layer[1].segment_count = tvp->u.data;
1563 break;
1564 case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
1565 fe->dtv_property_cache.layer[1].interleaving = tvp->u.data;
1566 break;
1567 case DTV_ISDBT_LAYERC_FEC:
1568 fe->dtv_property_cache.layer[2].fec = tvp->u.data;
1569 break;
1570 case DTV_ISDBT_LAYERC_MODULATION:
1571 fe->dtv_property_cache.layer[2].modulation = tvp->u.data;
1572 break;
1573 case DTV_ISDBT_LAYERC_SEGMENT_COUNT:
1574 fe->dtv_property_cache.layer[2].segment_count = tvp->u.data;
1575 break;
1576 case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
1577 fe->dtv_property_cache.layer[2].interleaving = tvp->u.data;
1578 break;
1579 case DTV_ISDBS_TS_ID:
1580 fe->dtv_property_cache.isdbs_ts_id = tvp->u.data;
1581 break;
1374 default: 1582 default:
1375 r = -1; 1583 r = -1;
1376 } 1584 }
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index e176da472d7a..810f07d63246 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -341,6 +341,23 @@ struct dtv_frontend_properties {
341 fe_rolloff_t rolloff; 341 fe_rolloff_t rolloff;
342 342
343 fe_delivery_system_t delivery_system; 343 fe_delivery_system_t delivery_system;
344
345 /* ISDB-T specifics */
346 u8 isdbt_partial_reception;
347 u8 isdbt_sb_mode;
348 u8 isdbt_sb_subchannel;
349 u32 isdbt_sb_segment_idx;
350 u32 isdbt_sb_segment_count;
351 u8 isdbt_layer_enabled;
352 struct {
353 u8 segment_count;
354 fe_code_rate_t fec;
355 fe_modulation_t modulation;
356 u8 interleaving;
357 } layer[3];
358
359 /* ISDB-T specifics */
360 u32 isdbs_ts_id;
344}; 361};
345 362
346struct dvb_frontend { 363struct dvb_frontend {
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 8b8bc04ee980..0e4b97fba384 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -71,6 +71,7 @@ config DVB_USB_DIB0700
71 depends on DVB_USB 71 depends on DVB_USB
72 select DVB_DIB7000P if !DVB_FE_CUSTOMISE 72 select DVB_DIB7000P if !DVB_FE_CUSTOMISE
73 select DVB_DIB7000M if !DVB_FE_CUSTOMISE 73 select DVB_DIB7000M if !DVB_FE_CUSTOMISE
74 select DVB_DIB8000 if !DVB_FE_CUSTOMISE
74 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE 75 select DVB_DIB3000MC if !DVB_FE_CUSTOMISE
75 select DVB_S5H1411 if !DVB_FE_CUSTOMISE 76 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
76 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE 77 select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
@@ -87,7 +88,7 @@ config DVB_USB_DIB0700
87 Avermedia and other big and small companies. 88 Avermedia and other big and small companies.
88 89
89 For an up-to-date list of devices supported by this driver, have a look 90 For an up-to-date list of devices supported by this driver, have a look
90 on the Linux-DVB Wiki at www.linuxtv.org. 91 on the LinuxTV Wiki at www.linuxtv.org.
91 92
92 Say Y if you own such a device and want to use it. You should build it as 93 Say Y if you own such a device and want to use it. You should build it as
93 a module. 94 a module.
@@ -315,3 +316,9 @@ config DVB_USB_CE6230
315 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE 316 select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
316 help 317 help
317 Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver 318 Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
319
320config DVB_USB_FRIIO
321 tristate "Friio ISDB-T USB2.0 Receiver support"
322 depends on DVB_USB
323 help
324 Say Y here to support the Japanese DTV receiver Friio.
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index f92734ed777a..85b83a43d55d 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -79,6 +79,9 @@ obj-$(CONFIG_DVB_USB_CINERGY_T2) += dvb-usb-cinergyT2.o
79dvb-usb-ce6230-objs = ce6230.o 79dvb-usb-ce6230-objs = ce6230.o
80obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o 80obj-$(CONFIG_DVB_USB_CE6230) += dvb-usb-ce6230.o
81 81
82dvb-usb-friio-objs = friio.o friio-fe.o
83obj-$(CONFIG_DVB_USB_FRIIO) += dvb-usb-friio.o
84
82EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 85EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
83# due to tuner-xc3028 86# due to tuner-xc3028
84EXTRA_CFLAGS += -Idrivers/media/common/tuners 87EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 99cdd0d101ca..cf042b309b46 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -61,10 +61,13 @@ static struct af9013_config af9015_af9013_config[] = {
61 61
62static int af9015_rw_udev(struct usb_device *udev, struct req_t *req) 62static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
63{ 63{
64#define BUF_LEN 63
65#define REQ_HDR_LEN 8 /* send header size */
66#define ACK_HDR_LEN 2 /* rece header size */
64 int act_len, ret; 67 int act_len, ret;
65 u8 buf[64]; 68 u8 buf[BUF_LEN];
66 u8 write = 1; 69 u8 write = 1;
67 u8 msg_len = 8; 70 u8 msg_len = REQ_HDR_LEN;
68 static u8 seq; /* packet sequence number */ 71 static u8 seq; /* packet sequence number */
69 72
70 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0) 73 if (mutex_lock_interruptible(&af9015_usb_mutex) < 0)
@@ -94,7 +97,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
94 break; 97 break;
95 case WRITE_MEMORY: 98 case WRITE_MEMORY:
96 if (((req->addr & 0xff00) == 0xff00) || 99 if (((req->addr & 0xff00) == 0xff00) ||
97 ((req->addr & 0xae00) == 0xae00)) 100 ((req->addr & 0xff00) == 0xae00))
98 buf[0] = WRITE_VIRTUAL_MEMORY; 101 buf[0] = WRITE_VIRTUAL_MEMORY;
99 case WRITE_VIRTUAL_MEMORY: 102 case WRITE_VIRTUAL_MEMORY:
100 case COPY_FIRMWARE: 103 case COPY_FIRMWARE:
@@ -107,17 +110,26 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
107 goto error_unlock; 110 goto error_unlock;
108 } 111 }
109 112
113 /* buffer overflow check */
114 if ((write && (req->data_len > BUF_LEN - REQ_HDR_LEN)) ||
115 (!write && (req->data_len > BUF_LEN - ACK_HDR_LEN))) {
116 err("too much data; cmd:%d len:%d", req->cmd, req->data_len);
117 ret = -EINVAL;
118 goto error_unlock;
119 }
120
110 /* write requested */ 121 /* write requested */
111 if (write) { 122 if (write) {
112 memcpy(&buf[8], req->data, req->data_len); 123 memcpy(&buf[REQ_HDR_LEN], req->data, req->data_len);
113 msg_len += req->data_len; 124 msg_len += req->data_len;
114 } 125 }
126
115 deb_xfer(">>> "); 127 deb_xfer(">>> ");
116 debug_dump(buf, msg_len, deb_xfer); 128 debug_dump(buf, msg_len, deb_xfer);
117 129
118 /* send req */ 130 /* send req */
119 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len, 131 ret = usb_bulk_msg(udev, usb_sndbulkpipe(udev, 0x02), buf, msg_len,
120 &act_len, AF9015_USB_TIMEOUT); 132 &act_len, AF9015_USB_TIMEOUT);
121 if (ret) 133 if (ret)
122 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len); 134 err("bulk message failed:%d (%d/%d)", ret, msg_len, act_len);
123 else 135 else
@@ -130,10 +142,14 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
130 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB) 142 if (req->cmd == DOWNLOAD_FIRMWARE || req->cmd == RECONNECT_USB)
131 goto exit_unlock; 143 goto exit_unlock;
132 144
133 /* receive ack and data if read req */ 145 /* write receives seq + status = 2 bytes
134 msg_len = 1 + 1 + req->data_len; /* seq + status + data len */ 146 read receives seq + status + data = 2 + N bytes */
147 msg_len = ACK_HDR_LEN;
148 if (!write)
149 msg_len += req->data_len;
150
135 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len, 151 ret = usb_bulk_msg(udev, usb_rcvbulkpipe(udev, 0x81), buf, msg_len,
136 &act_len, AF9015_USB_TIMEOUT); 152 &act_len, AF9015_USB_TIMEOUT);
137 if (ret) { 153 if (ret) {
138 err("recv bulk message failed:%d", ret); 154 err("recv bulk message failed:%d", ret);
139 ret = -1; 155 ret = -1;
@@ -159,7 +175,7 @@ static int af9015_rw_udev(struct usb_device *udev, struct req_t *req)
159 175
160 /* read request, copy returned data to return buf */ 176 /* read request, copy returned data to return buf */
161 if (!write) 177 if (!write)
162 memcpy(req->data, &buf[2], req->data_len); 178 memcpy(req->data, &buf[ACK_HDR_LEN], req->data_len);
163 179
164error_unlock: 180error_unlock:
165exit_unlock: 181exit_unlock:
@@ -369,12 +385,14 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
369 u8 packet_size; 385 u8 packet_size;
370 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed); 386 deb_info("%s: USB speed:%d\n", __func__, d->udev->speed);
371 387
388 /* Windows driver uses packet count 21 for USB1.1 and 348 for USB2.0.
389 We use smaller - about 1/4 from the original, 5 and 87. */
372#define TS_PACKET_SIZE 188 390#define TS_PACKET_SIZE 188
373 391
374#define TS_USB20_PACKET_COUNT 348 392#define TS_USB20_PACKET_COUNT 87
375#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT) 393#define TS_USB20_FRAME_SIZE (TS_PACKET_SIZE*TS_USB20_PACKET_COUNT)
376 394
377#define TS_USB11_PACKET_COUNT 21 395#define TS_USB11_PACKET_COUNT 5
378#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT) 396#define TS_USB11_FRAME_SIZE (TS_PACKET_SIZE*TS_USB11_PACKET_COUNT)
379 397
380#define TS_USB20_MAX_PACKET_SIZE 512 398#define TS_USB20_MAX_PACKET_SIZE 512
@@ -868,13 +886,13 @@ static int af9015_read_config(struct usb_device *udev)
868 /* USB1.1 set smaller buffersize and disable 2nd adapter */ 886 /* USB1.1 set smaller buffersize and disable 2nd adapter */
869 if (udev->speed == USB_SPEED_FULL) { 887 if (udev->speed == USB_SPEED_FULL) {
870 af9015_properties[i].adapter[0].stream.u.bulk.buffersize 888 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
871 = TS_USB11_MAX_PACKET_SIZE; 889 = TS_USB11_FRAME_SIZE;
872 /* disable 2nd adapter because we don't have 890 /* disable 2nd adapter because we don't have
873 PID-filters */ 891 PID-filters */
874 af9015_config.dual_mode = 0; 892 af9015_config.dual_mode = 0;
875 } else { 893 } else {
876 af9015_properties[i].adapter[0].stream.u.bulk.buffersize 894 af9015_properties[i].adapter[0].stream.u.bulk.buffersize
877 = TS_USB20_MAX_PACKET_SIZE; 895 = TS_USB20_FRAME_SIZE;
878 } 896 }
879 } 897 }
880 898
@@ -1310,7 +1328,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1310 .u = { 1328 .u = {
1311 .bulk = { 1329 .bulk = {
1312 .buffersize = 1330 .buffersize =
1313 TS_USB20_MAX_PACKET_SIZE, 1331 TS_USB20_FRAME_SIZE,
1314 } 1332 }
1315 } 1333 }
1316 }, 1334 },
@@ -1416,7 +1434,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1416 .u = { 1434 .u = {
1417 .bulk = { 1435 .bulk = {
1418 .buffersize = 1436 .buffersize =
1419 TS_USB20_MAX_PACKET_SIZE, 1437 TS_USB20_FRAME_SIZE,
1420 } 1438 }
1421 } 1439 }
1422 }, 1440 },
@@ -1522,7 +1540,7 @@ static struct dvb_usb_device_properties af9015_properties[] = {
1522 .u = { 1540 .u = {
1523 .bulk = { 1541 .bulk = {
1524 .buffersize = 1542 .buffersize =
1525 TS_USB20_MAX_PACKET_SIZE, 1543 TS_USB20_FRAME_SIZE,
1526 } 1544 }
1527 } 1545 }
1528 }, 1546 },
diff --git a/drivers/media/dvb/dvb-usb/anysee.c b/drivers/media/dvb/dvb-usb/anysee.c
index 7381aff4dcf6..2ae7f648effe 100644
--- a/drivers/media/dvb/dvb-usb/anysee.c
+++ b/drivers/media/dvb/dvb-usb/anysee.c
@@ -203,11 +203,11 @@ static struct i2c_algorithm anysee_i2c_algo = {
203 203
204static int anysee_mt352_demod_init(struct dvb_frontend *fe) 204static int anysee_mt352_demod_init(struct dvb_frontend *fe)
205{ 205{
206 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x28 }; 206 static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x28 };
207 static u8 reset [] = { RESET, 0x80 }; 207 static u8 reset[] = { RESET, 0x80 };
208 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; 208 static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 };
209 static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; 209 static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0x20 };
210 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; 210 static u8 gpp_ctl_cfg[] = { GPP_CTL, 0x33 };
211 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; 211 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
212 212
213 mt352_write(fe, clock_config, sizeof(clock_config)); 213 mt352_write(fe, clock_config, sizeof(clock_config));
@@ -485,7 +485,7 @@ static int anysee_probe(struct usb_interface *intf,
485 return ret; 485 return ret;
486} 486}
487 487
488static struct usb_device_id anysee_table [] = { 488static struct usb_device_id anysee_table[] = {
489 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) }, 489 { USB_DEVICE(USB_VID_CYPRESS, USB_PID_ANYSEE) },
490 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) }, 490 { USB_DEVICE(USB_VID_AMT, USB_PID_ANYSEE) },
491 { } /* Terminating entry */ 491 { } /* Terminating entry */
@@ -511,7 +511,7 @@ static struct dvb_usb_device_properties anysee_properties = {
511 .endpoint = 0x82, 511 .endpoint = 0x82,
512 .u = { 512 .u = {
513 .bulk = { 513 .bulk = {
514 .buffersize = 512, 514 .buffersize = (16*512),
515 } 515 }
516 } 516 }
517 }, 517 },
diff --git a/drivers/media/dvb/dvb-usb/ce6230.c b/drivers/media/dvb/dvb-usb/ce6230.c
index 52badc00e673..0737c6377892 100644
--- a/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/drivers/media/dvb/dvb-usb/ce6230.c
@@ -274,7 +274,7 @@ static struct dvb_usb_device_properties ce6230_properties = {
274 .endpoint = 0x82, 274 .endpoint = 0x82,
275 .u = { 275 .u = {
276 .bulk = { 276 .bulk = {
277 .buffersize = 512, 277 .buffersize = (16*512),
278 } 278 }
279 } 279 }
280 }, 280 },
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index d1d6f4491403..0b2812aa30a4 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -4,13 +4,14 @@
4 * under the terms of the GNU General Public License as published by the Free 4 * under the terms of the GNU General Public License as published by the Free
5 * Software Foundation, version 2. 5 * Software Foundation, version 2.
6 * 6 *
7 * Copyright (C) 2005-7 DiBcom, SA 7 * Copyright (C) 2005-9 DiBcom, SA et al
8 */ 8 */
9#include "dib0700.h" 9#include "dib0700.h"
10 10
11#include "dib3000mc.h" 11#include "dib3000mc.h"
12#include "dib7000m.h" 12#include "dib7000m.h"
13#include "dib7000p.h" 13#include "dib7000p.h"
14#include "dib8000.h"
14#include "mt2060.h" 15#include "mt2060.h"
15#include "mt2266.h" 16#include "mt2266.h"
16#include "tuner-xc2028.h" 17#include "tuner-xc2028.h"
@@ -1098,11 +1099,13 @@ static struct dibx000_agc_config dib7070_agc_config = {
1098 1099
1099static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff) 1100static int dib7070_tuner_reset(struct dvb_frontend *fe, int onoff)
1100{ 1101{
1102 deb_info("reset: %d", onoff);
1101 return dib7000p_set_gpio(fe, 8, 0, !onoff); 1103 return dib7000p_set_gpio(fe, 8, 0, !onoff);
1102} 1104}
1103 1105
1104static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff) 1106static int dib7070_tuner_sleep(struct dvb_frontend *fe, int onoff)
1105{ 1107{
1108 deb_info("sleep: %d", onoff);
1106 return dib7000p_set_gpio(fe, 9, 0, onoff); 1109 return dib7000p_set_gpio(fe, 9, 0, onoff);
1107} 1110}
1108 1111
@@ -1112,16 +1115,26 @@ static struct dib0070_config dib7070p_dib0070_config[2] = {
1112 .reset = dib7070_tuner_reset, 1115 .reset = dib7070_tuner_reset,
1113 .sleep = dib7070_tuner_sleep, 1116 .sleep = dib7070_tuner_sleep,
1114 .clock_khz = 12000, 1117 .clock_khz = 12000,
1115 .clock_pad_drive = 4 1118 .clock_pad_drive = 4,
1119 .charge_pump = 2,
1116 }, { 1120 }, {
1117 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS, 1121 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1118 .reset = dib7070_tuner_reset, 1122 .reset = dib7070_tuner_reset,
1119 .sleep = dib7070_tuner_sleep, 1123 .sleep = dib7070_tuner_sleep,
1120 .clock_khz = 12000, 1124 .clock_khz = 12000,
1121 1125 .charge_pump = 2,
1122 } 1126 }
1123}; 1127};
1124 1128
1129static struct dib0070_config dib7770p_dib0070_config = {
1130 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1131 .reset = dib7070_tuner_reset,
1132 .sleep = dib7070_tuner_sleep,
1133 .clock_khz = 12000,
1134 .clock_pad_drive = 0,
1135 .flip_chip = 1,
1136};
1137
1125static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1138static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1126{ 1139{
1127 struct dvb_usb_adapter *adap = fe->dvb->priv; 1140 struct dvb_usb_adapter *adap = fe->dvb->priv;
@@ -1139,6 +1152,45 @@ static int dib7070_set_param_override(struct dvb_frontend *fe, struct dvb_fronte
1139 return state->set_param_save(fe, fep); 1152 return state->set_param_save(fe, fep);
1140} 1153}
1141 1154
1155static int dib7770_set_param_override(struct dvb_frontend *fe,
1156 struct dvb_frontend_parameters *fep)
1157{
1158 struct dvb_usb_adapter *adap = fe->dvb->priv;
1159 struct dib0700_adapter_state *state = adap->priv;
1160
1161 u16 offset;
1162 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1163 switch (band) {
1164 case BAND_VHF:
1165 dib7000p_set_gpio(fe, 0, 0, 1);
1166 offset = 850;
1167 break;
1168 case BAND_UHF:
1169 default:
1170 dib7000p_set_gpio(fe, 0, 0, 0);
1171 offset = 250;
1172 break;
1173 }
1174 deb_info("WBD for DiB7000P: %d\n", offset + dib0070_wbd_offset(fe));
1175 dib7000p_set_wbd_ref(fe, offset + dib0070_wbd_offset(fe));
1176 return state->set_param_save(fe, fep);
1177}
1178
1179static int dib7770p_tuner_attach(struct dvb_usb_adapter *adap)
1180{
1181 struct dib0700_adapter_state *st = adap->priv;
1182 struct i2c_adapter *tun_i2c = dib7000p_get_i2c_master(adap->fe,
1183 DIBX000_I2C_INTERFACE_TUNER, 1);
1184
1185 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1186 &dib7770p_dib0070_config) == NULL)
1187 return -ENODEV;
1188
1189 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1190 adap->fe->ops.tuner_ops.set_params = dib7770_set_param_override;
1191 return 0;
1192}
1193
1142static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap) 1194static int dib7070p_tuner_attach(struct dvb_usb_adapter *adap)
1143{ 1195{
1144 struct dib0700_adapter_state *st = adap->priv; 1196 struct dib0700_adapter_state *st = adap->priv;
@@ -1217,6 +1269,306 @@ static int stk7070p_frontend_attach(struct dvb_usb_adapter *adap)
1217 return adap->fe == NULL ? -ENODEV : 0; 1269 return adap->fe == NULL ? -ENODEV : 0;
1218} 1270}
1219 1271
1272/* DIB807x generic */
1273static struct dibx000_agc_config dib807x_agc_config[2] = {
1274 {
1275 BAND_VHF,
1276 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1277 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1278 * P_agc_inv_pwm2=0,P_agc_inh_dc_rv_est=0,
1279 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1280 * P_agc_write=0 */
1281 (0 << 15) | (0 << 14) | (7 << 11) | (0 << 10) | (0 << 9) |
1282 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1283 (0 << 0), /* setup*/
1284
1285 600, /* inv_gain*/
1286 10, /* time_stabiliz*/
1287
1288 0, /* alpha_level*/
1289 118, /* thlock*/
1290
1291 0, /* wbd_inv*/
1292 3530, /* wbd_ref*/
1293 1, /* wbd_sel*/
1294 5, /* wbd_alpha*/
1295
1296 65535, /* agc1_max*/
1297 0, /* agc1_min*/
1298
1299 65535, /* agc2_max*/
1300 0, /* agc2_min*/
1301
1302 0, /* agc1_pt1*/
1303 40, /* agc1_pt2*/
1304 183, /* agc1_pt3*/
1305 206, /* agc1_slope1*/
1306 255, /* agc1_slope2*/
1307 72, /* agc2_pt1*/
1308 152, /* agc2_pt2*/
1309 88, /* agc2_slope1*/
1310 90, /* agc2_slope2*/
1311
1312 17, /* alpha_mant*/
1313 27, /* alpha_exp*/
1314 23, /* beta_mant*/
1315 51, /* beta_exp*/
1316
1317 0, /* perform_agc_softsplit*/
1318 }, {
1319 BAND_UHF,
1320 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0,
1321 * P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0,
1322 * P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1323 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5,
1324 * P_agc_write=0 */
1325 (0 << 15) | (0 << 14) | (1 << 11) | (0 << 10) | (0 << 9) |
1326 (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) |
1327 (0 << 0), /* setup */
1328
1329 600, /* inv_gain*/
1330 10, /* time_stabiliz*/
1331
1332 0, /* alpha_level*/
1333 118, /* thlock*/
1334
1335 0, /* wbd_inv*/
1336 3530, /* wbd_ref*/
1337 1, /* wbd_sel*/
1338 5, /* wbd_alpha*/
1339
1340 65535, /* agc1_max*/
1341 0, /* agc1_min*/
1342
1343 65535, /* agc2_max*/
1344 0, /* agc2_min*/
1345
1346 0, /* agc1_pt1*/
1347 40, /* agc1_pt2*/
1348 183, /* agc1_pt3*/
1349 206, /* agc1_slope1*/
1350 255, /* agc1_slope2*/
1351 72, /* agc2_pt1*/
1352 152, /* agc2_pt2*/
1353 88, /* agc2_slope1*/
1354 90, /* agc2_slope2*/
1355
1356 17, /* alpha_mant*/
1357 27, /* alpha_exp*/
1358 23, /* beta_mant*/
1359 51, /* beta_exp*/
1360
1361 0, /* perform_agc_softsplit*/
1362 }
1363};
1364
1365static struct dibx000_bandwidth_config dib807x_bw_config_12_mhz = {
1366 60000, 15000, /* internal, sampling*/
1367 1, 20, 3, 1, 0, /* pll_cfg: prediv, ratio, range, reset, bypass*/
1368 0, 0, 1, 1, 2, /* misc: refdiv, bypclk_div, IO_CLK_en_core,
1369 ADClkSrc, modulo */
1370 (3 << 14) | (1 << 12) | (599 << 0), /* sad_cfg: refsel, sel, freq_15k*/
1371 (0 << 25) | 0, /* ifreq = 0.000000 MHz*/
1372 18179755, /* timf*/
1373 12000000, /* xtal_hz*/
1374};
1375
1376static struct dib8000_config dib807x_dib8000_config[2] = {
1377 {
1378 .output_mpeg2_in_188_bytes = 1,
1379
1380 .agc_config_count = 2,
1381 .agc = dib807x_agc_config,
1382 .pll = &dib807x_bw_config_12_mhz,
1383 .tuner_is_baseband = 1,
1384
1385 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1386 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1387 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1388
1389 .hostbus_diversity = 1,
1390 .div_cfg = 1,
1391 .agc_control = &dib0070_ctrl_agc_filter,
1392 .output_mode = OUTMODE_MPEG2_FIFO,
1393 .drives = 0x2d98,
1394 }, {
1395 .output_mpeg2_in_188_bytes = 1,
1396
1397 .agc_config_count = 2,
1398 .agc = dib807x_agc_config,
1399 .pll = &dib807x_bw_config_12_mhz,
1400 .tuner_is_baseband = 1,
1401
1402 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1403 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1404 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1405
1406 .hostbus_diversity = 1,
1407 .agc_control = &dib0070_ctrl_agc_filter,
1408 .output_mode = OUTMODE_MPEG2_FIFO,
1409 .drives = 0x2d98,
1410 }
1411};
1412
1413static int dib807x_tuner_reset(struct dvb_frontend *fe, int onoff)
1414{
1415 return dib8000_set_gpio(fe, 5, 0, !onoff);
1416}
1417
1418static int dib807x_tuner_sleep(struct dvb_frontend *fe, int onoff)
1419{
1420 return dib8000_set_gpio(fe, 0, 0, onoff);
1421}
1422
1423static const struct dib0070_wbd_gain_cfg dib8070_wbd_gain_cfg[] = {
1424 { 240, 7},
1425 { 0xffff, 6},
1426};
1427
1428static struct dib0070_config dib807x_dib0070_config[2] = {
1429 {
1430 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1431 .reset = dib807x_tuner_reset,
1432 .sleep = dib807x_tuner_sleep,
1433 .clock_khz = 12000,
1434 .clock_pad_drive = 4,
1435 .vga_filter = 1,
1436 .force_crystal_mode = 1,
1437 .enable_third_order_filter = 1,
1438 .charge_pump = 0,
1439 .wbd_gain = dib8070_wbd_gain_cfg,
1440 .osc_buffer_state = 0,
1441 .freq_offset_khz_uhf = -100,
1442 .freq_offset_khz_vhf = -100,
1443 }, {
1444 .i2c_address = DEFAULT_DIB0070_I2C_ADDRESS,
1445 .reset = dib807x_tuner_reset,
1446 .sleep = dib807x_tuner_sleep,
1447 .clock_khz = 12000,
1448 .clock_pad_drive = 2,
1449 .vga_filter = 1,
1450 .force_crystal_mode = 1,
1451 .enable_third_order_filter = 1,
1452 .charge_pump = 0,
1453 .wbd_gain = dib8070_wbd_gain_cfg,
1454 .osc_buffer_state = 0,
1455 .freq_offset_khz_uhf = -25,
1456 .freq_offset_khz_vhf = -25,
1457 }
1458};
1459
1460static int dib807x_set_param_override(struct dvb_frontend *fe,
1461 struct dvb_frontend_parameters *fep)
1462{
1463 struct dvb_usb_adapter *adap = fe->dvb->priv;
1464 struct dib0700_adapter_state *state = adap->priv;
1465
1466 u16 offset = dib0070_wbd_offset(fe);
1467 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1468 switch (band) {
1469 case BAND_VHF:
1470 offset += 750;
1471 break;
1472 case BAND_UHF: /* fall-thru wanted */
1473 default:
1474 offset += 250; break;
1475 }
1476 deb_info("WBD for DiB8000: %d\n", offset);
1477 dib8000_set_wbd_ref(fe, offset);
1478
1479 return state->set_param_save(fe, fep);
1480}
1481
1482static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1483{
1484 struct dib0700_adapter_state *st = adap->priv;
1485 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe,
1486 DIBX000_I2C_INTERFACE_TUNER, 1);
1487
1488 if (adap->id == 0) {
1489 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1490 &dib807x_dib0070_config[0]) == NULL)
1491 return -ENODEV;
1492 } else {
1493 if (dvb_attach(dib0070_attach, adap->fe, tun_i2c,
1494 &dib807x_dib0070_config[1]) == NULL)
1495 return -ENODEV;
1496 }
1497
1498 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1499 adap->fe->ops.tuner_ops.set_params = dib807x_set_param_override;
1500 return 0;
1501}
1502
1503
1504/* STK807x */
1505static int stk807x_frontend_attach(struct dvb_usb_adapter *adap)
1506{
1507 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1508 msleep(10);
1509 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1510 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1511 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1512
1513 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1514
1515 dib0700_ctrl_clock(adap->dev, 72, 1);
1516
1517 msleep(10);
1518 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1519 msleep(10);
1520 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1521
1522 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18,
1523 0x80);
1524
1525 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1526 &dib807x_dib8000_config[0]);
1527
1528 return adap->fe == NULL ? -ENODEV : 0;
1529}
1530
1531/* STK807xPVR */
1532static int stk807xpvr_frontend_attach0(struct dvb_usb_adapter *adap)
1533{
1534 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1535 msleep(30);
1536 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1537 msleep(500);
1538 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1539 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1540 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1541
1542 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1543
1544 dib0700_ctrl_clock(adap->dev, 72, 1);
1545
1546 msleep(10);
1547 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1548 msleep(10);
1549 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1550
1551 /* initialize IC 0 */
1552 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x12, 0x80);
1553
1554 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80,
1555 &dib807x_dib8000_config[0]);
1556
1557 return adap->fe == NULL ? -ENODEV : 0;
1558}
1559
1560static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1561{
1562 /* initialize IC 1 */
1563 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x22, 0x82);
1564
1565 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82,
1566 &dib807x_dib8000_config[1]);
1567
1568 return adap->fe == NULL ? -ENODEV : 0;
1569}
1570
1571
1220/* STK7070PD */ 1572/* STK7070PD */
1221static struct dib7000p_config stk7070pd_dib7000p_config[2] = { 1573static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1222 { 1574 {
@@ -1500,7 +1852,15 @@ struct usb_device_id dib0700_usb_id_table[] = {
1500 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) }, 1852 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T3) },
1501 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) }, 1853 { USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_T5) },
1502 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) }, 1854 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D) },
1503 { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) }, 1855/* 55 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_STK7700D_2) },
1856 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73A) },
1857 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV73ESE) },
1858 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
1859 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK7770P) },
1860/* 60 */{ USB_DEVICE(USB_VID_TERRATEC, USB_PID_TERRATEC_CINERGY_T_XXS_2) },
1861 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XPVR) },
1862 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK807XP) },
1863 { USB_DEVICE(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD) },
1504 { 0 } /* Terminating entry */ 1864 { 0 } /* Terminating entry */
1505}; 1865};
1506MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 1866MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1565,7 +1925,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1565 { NULL }, 1925 { NULL },
1566 }, 1926 },
1567 { "Leadtek Winfast DTV Dongle (STK7700P based)", 1927 { "Leadtek Winfast DTV Dongle (STK7700P based)",
1568 { &dib0700_usb_id_table[8], &dib0700_usb_id_table[34] }, 1928 { &dib0700_usb_id_table[8] },
1569 { NULL }, 1929 { NULL },
1570 }, 1930 },
1571 { "AVerMedia AVerTV DVB-T Express", 1931 { "AVerMedia AVerTV DVB-T Express",
@@ -1764,6 +2124,41 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1764 2124
1765 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES, 2125 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
1766 2126
2127 .num_adapters = 1,
2128 .adapter = {
2129 {
2130 .frontend_attach = stk7070p_frontend_attach,
2131 .tuner_attach = dib7070p_tuner_attach,
2132
2133 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2134
2135 .size_of_priv = sizeof(struct dib0700_adapter_state),
2136 },
2137 },
2138
2139 .num_device_descs = 3,
2140 .devices = {
2141 { "Pinnacle PCTV 73A",
2142 { &dib0700_usb_id_table[56], NULL },
2143 { NULL },
2144 },
2145 { "Pinnacle PCTV 73e SE",
2146 { &dib0700_usb_id_table[57], NULL },
2147 { NULL },
2148 },
2149 { "Pinnacle PCTV 282e",
2150 { &dib0700_usb_id_table[58], NULL },
2151 { NULL },
2152 },
2153 },
2154
2155 .rc_interval = DEFAULT_RC_INTERVAL,
2156 .rc_key_map = dib0700_rc_keys,
2157 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2158 .rc_query = dib0700_rc_query
2159
2160 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2161
1767 .num_adapters = 2, 2162 .num_adapters = 2,
1768 .adapter = { 2163 .adapter = {
1769 { 2164 {
@@ -1927,6 +2322,102 @@ struct dvb_usb_device_properties dib0700_devices[] = {
1927 { NULL }, 2322 { NULL },
1928 }, 2323 },
1929 }, 2324 },
2325 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2326
2327 .num_adapters = 1,
2328 .adapter = {
2329 {
2330 .frontend_attach = stk7070p_frontend_attach,
2331 .tuner_attach = dib7770p_tuner_attach,
2332
2333 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2334
2335 .size_of_priv =
2336 sizeof(struct dib0700_adapter_state),
2337 },
2338 },
2339
2340 .num_device_descs = 2,
2341 .devices = {
2342 { "DiBcom STK7770P reference design",
2343 { &dib0700_usb_id_table[59], NULL },
2344 { NULL },
2345 },
2346 { "Terratec Cinergy T USB XXS (HD)",
2347 { &dib0700_usb_id_table[34], &dib0700_usb_id_table[60] },
2348 { NULL },
2349 },
2350 },
2351 .rc_interval = DEFAULT_RC_INTERVAL,
2352 .rc_key_map = dib0700_rc_keys,
2353 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2354 .rc_query = dib0700_rc_query
2355 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2356 .num_adapters = 1,
2357 .adapter = {
2358 {
2359 .frontend_attach = stk807x_frontend_attach,
2360 .tuner_attach = dib807x_tuner_attach,
2361
2362 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2363
2364 .size_of_priv =
2365 sizeof(struct dib0700_adapter_state),
2366 },
2367 },
2368
2369 .num_device_descs = 2,
2370 .devices = {
2371 { "DiBcom STK807xP reference design",
2372 { &dib0700_usb_id_table[62], NULL },
2373 { NULL },
2374 },
2375 { "Prolink Pixelview SBTVD",
2376 { &dib0700_usb_id_table[63], NULL },
2377 { NULL },
2378 },
2379 },
2380
2381 .rc_interval = DEFAULT_RC_INTERVAL,
2382 .rc_key_map = dib0700_rc_keys,
2383 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2384 .rc_query = dib0700_rc_query
2385
2386 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
2387 .num_adapters = 2,
2388 .adapter = {
2389 {
2390 .frontend_attach = stk807xpvr_frontend_attach0,
2391 .tuner_attach = dib807x_tuner_attach,
2392
2393 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
2394
2395 .size_of_priv =
2396 sizeof(struct dib0700_adapter_state),
2397 },
2398 {
2399 .frontend_attach = stk807xpvr_frontend_attach1,
2400 .tuner_attach = dib807x_tuner_attach,
2401
2402 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
2403
2404 .size_of_priv =
2405 sizeof(struct dib0700_adapter_state),
2406 },
2407 },
2408
2409 .num_device_descs = 1,
2410 .devices = {
2411 { "DiBcom STK807xPVR reference design",
2412 { &dib0700_usb_id_table[61], NULL },
2413 { NULL },
2414 },
2415 },
2416
2417 .rc_interval = DEFAULT_RC_INTERVAL,
2418 .rc_key_map = dib0700_rc_keys,
2419 .rc_key_map_size = ARRAY_SIZE(dib0700_rc_keys),
2420 .rc_query = dib0700_rc_query
1930 }, 2421 },
1931}; 2422};
1932 2423
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 185a5069b10b..a548c14c1944 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -46,6 +46,7 @@
46#define USB_VID_MSI_2 0x1462 46#define USB_VID_MSI_2 0x1462
47#define USB_VID_OPERA1 0x695c 47#define USB_VID_OPERA1 0x695c
48#define USB_VID_PINNACLE 0x2304 48#define USB_VID_PINNACLE 0x2304
49#define USB_VID_PIXELVIEW 0x1554
49#define USB_VID_TECHNOTREND 0x0b48 50#define USB_VID_TECHNOTREND 0x0b48
50#define USB_VID_TERRATEC 0x0ccd 51#define USB_VID_TERRATEC 0x0ccd
51#define USB_VID_TELESTAR 0x10b9 52#define USB_VID_TELESTAR 0x10b9
@@ -59,6 +60,7 @@
59#define USB_VID_YUAN 0x1164 60#define USB_VID_YUAN 0x1164
60#define USB_VID_XTENSIONS 0x1ae7 61#define USB_VID_XTENSIONS 0x1ae7
61#define USB_VID_HUMAX_COEX 0x10b9 62#define USB_VID_HUMAX_COEX 0x10b9
63#define USB_VID_774 0x7a69
62 64
63/* Product IDs */ 65/* Product IDs */
64#define USB_PID_ADSTECH_USB2_COLD 0xa333 66#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -95,7 +97,10 @@
95#define USB_PID_DIBCOM_STK7700_U7000 0x7001 97#define USB_PID_DIBCOM_STK7700_U7000 0x7001
96#define USB_PID_DIBCOM_STK7070P 0x1ebc 98#define USB_PID_DIBCOM_STK7070P 0x1ebc
97#define USB_PID_DIBCOM_STK7070PD 0x1ebe 99#define USB_PID_DIBCOM_STK7070PD 0x1ebe
100#define USB_PID_DIBCOM_STK807XP 0x1f90
101#define USB_PID_DIBCOM_STK807XPVR 0x1f98
98#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 102#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
103#define USB_PID_DIBCOM_STK7770P 0x1e80
99#define USB_PID_DPOSH_M9206_COLD 0x9206 104#define USB_PID_DPOSH_M9206_COLD 0x9206
100#define USB_PID_DPOSH_M9206_WARM 0xa090 105#define USB_PID_DPOSH_M9206_WARM 0xa090
101#define USB_PID_UNIWILL_STK7700P 0x6003 106#define USB_PID_UNIWILL_STK7700P 0x6003
@@ -184,6 +189,7 @@
184#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060 189#define USB_PID_TERRATEC_CINERGY_HT_EXPRESS 0x0060
185#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062 190#define USB_PID_TERRATEC_CINERGY_T_EXPRESS 0x0062
186#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078 191#define USB_PID_TERRATEC_CINERGY_T_XXS 0x0078
192#define USB_PID_TERRATEC_CINERGY_T_XXS_2 0x00ab
187#define USB_PID_TERRATEC_T3 0x10a0 193#define USB_PID_TERRATEC_T3 0x10a0
188#define USB_PID_TERRATEC_T5 0x10a1 194#define USB_PID_TERRATEC_T5 0x10a1
189#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e 195#define USB_PID_PINNACLE_EXPRESSCARD_320CX 0x022e
@@ -195,6 +201,10 @@
195#define USB_PID_PINNACLE_PCTV73E 0x0237 201#define USB_PID_PINNACLE_PCTV73E 0x0237
196#define USB_PID_PINNACLE_PCTV801E 0x023a 202#define USB_PID_PINNACLE_PCTV801E 0x023a
197#define USB_PID_PINNACLE_PCTV801E_SE 0x023b 203#define USB_PID_PINNACLE_PCTV801E_SE 0x023b
204#define USB_PID_PINNACLE_PCTV73A 0x0243
205#define USB_PID_PINNACLE_PCTV73ESE 0x0245
206#define USB_PID_PINNACLE_PCTV282E 0x0248
207#define USB_PID_PIXELVIEW_SBTVD 0x5010
198#define USB_PID_PCTV_200E 0x020e 208#define USB_PID_PCTV_200E 0x020e
199#define USB_PID_PCTV_400E 0x020f 209#define USB_PID_PCTV_400E 0x020f
200#define USB_PID_PCTV_450E 0x0222 210#define USB_PID_PCTV_450E 0x0222
@@ -265,5 +275,6 @@
265#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020 275#define USB_PID_ELGATO_EYETV_DTT_Dlx 0x0020
266#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000 276#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_COLD 0x5000
267#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001 277#define USB_PID_DVB_T_USB_STICK_HIGH_SPEED_WARM 0x5001
278#define USB_PID_FRIIO_WHITE 0x0001
268 279
269#endif 280#endif
diff --git a/drivers/media/dvb/dvb-usb/friio-fe.c b/drivers/media/dvb/dvb-usb/friio-fe.c
new file mode 100644
index 000000000000..c4dfe25cf60d
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio-fe.c
@@ -0,0 +1,483 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include <linux/init.h>
14#include <linux/string.h>
15#include <linux/slab.h>
16
17#include "friio.h"
18
19struct jdvbt90502_state {
20 struct i2c_adapter *i2c;
21 struct dvb_frontend frontend;
22 struct jdvbt90502_config config;
23};
24
25/* NOTE: TC90502 has 16bit register-address? */
26/* register 0x0100 is used for reading PLL status, so reg is u16 here */
27static int jdvbt90502_reg_read(struct jdvbt90502_state *state,
28 const u16 reg, u8 *buf, const size_t count)
29{
30 int ret;
31 u8 wbuf[3];
32 struct i2c_msg msg[2];
33
34 wbuf[0] = reg & 0xFF;
35 wbuf[1] = 0;
36 wbuf[2] = reg >> 8;
37
38 msg[0].addr = state->config.demod_address;
39 msg[0].flags = 0;
40 msg[0].buf = wbuf;
41 msg[0].len = sizeof(wbuf);
42
43 msg[1].addr = msg[0].addr;
44 msg[1].flags = I2C_M_RD;
45 msg[1].buf = buf;
46 msg[1].len = count;
47
48 ret = i2c_transfer(state->i2c, msg, 2);
49 if (ret != 2) {
50 deb_fe(" reg read failed.\n");
51 return -EREMOTEIO;
52 }
53 return 0;
54}
55
56/* currently 16bit register-address is not used, so reg is u8 here */
57static int jdvbt90502_single_reg_write(struct jdvbt90502_state *state,
58 const u8 reg, const u8 val)
59{
60 struct i2c_msg msg;
61 u8 wbuf[2];
62
63 wbuf[0] = reg;
64 wbuf[1] = val;
65
66 msg.addr = state->config.demod_address;
67 msg.flags = 0;
68 msg.buf = wbuf;
69 msg.len = sizeof(wbuf);
70
71 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
72 deb_fe(" reg write failed.");
73 return -EREMOTEIO;
74 }
75 return 0;
76}
77
78static int _jdvbt90502_write(struct dvb_frontend *fe, u8 *buf, int len)
79{
80 struct jdvbt90502_state *state = fe->demodulator_priv;
81 int err, i;
82 for (i = 0; i < len - 1; i++) {
83 err = jdvbt90502_single_reg_write(state,
84 buf[0] + i, buf[i + 1]);
85 if (err)
86 return err;
87 }
88
89 return 0;
90}
91
92/* read pll status byte via the demodulator's I2C register */
93/* note: Win box reads it by 8B block at the I2C addr 0x30 from reg:0x80 */
94static int jdvbt90502_pll_read(struct jdvbt90502_state *state, u8 *result)
95{
96 int ret;
97
98 /* +1 for reading */
99 u8 pll_addr_byte = (state->config.pll_address << 1) + 1;
100
101 *result = 0;
102
103 ret = jdvbt90502_single_reg_write(state, JDVBT90502_2ND_I2C_REG,
104 pll_addr_byte);
105 if (ret)
106 goto error;
107
108 ret = jdvbt90502_reg_read(state, 0x0100, result, 1);
109 if (ret)
110 goto error;
111
112 deb_fe("PLL read val:%02x\n", *result);
113 return 0;
114
115error:
116 deb_fe("%s:ret == %d\n", __func__, ret);
117 return -EREMOTEIO;
118}
119
120
121/* set pll frequency via the demodulator's I2C register */
122static int jdvbt90502_pll_set_freq(struct jdvbt90502_state *state, u32 freq)
123{
124 int ret;
125 int retry;
126 u8 res1;
127 u8 res2[9];
128
129 u8 pll_freq_cmd[PLL_CMD_LEN];
130 u8 pll_agc_cmd[PLL_CMD_LEN];
131 struct i2c_msg msg[2];
132 u32 f;
133
134 deb_fe("%s: freq=%d, step=%d\n", __func__, freq,
135 state->frontend.ops.info.frequency_stepsize);
136 /* freq -> oscilator frequency conversion. */
137 /* freq: 473,000,000 + n*6,000,000 (no 1/7MHz shift to center freq) */
138 /* add 400[1/7 MHZ] = 57.142857MHz. 57MHz for the IF, */
139 /* 1/7MHz for center freq shift */
140 f = freq / state->frontend.ops.info.frequency_stepsize;
141 f += 400;
142 pll_freq_cmd[DEMOD_REDIRECT_REG] = JDVBT90502_2ND_I2C_REG; /* 0xFE */
143 pll_freq_cmd[ADDRESS_BYTE] = state->config.pll_address << 1;
144 pll_freq_cmd[DIVIDER_BYTE1] = (f >> 8) & 0x7F;
145 pll_freq_cmd[DIVIDER_BYTE2] = f & 0xFF;
146 pll_freq_cmd[CONTROL_BYTE] = 0xB2; /* ref.divider:28, 4MHz/28=1/7MHz */
147 pll_freq_cmd[BANDSWITCH_BYTE] = 0x08; /* UHF band */
148
149 msg[0].addr = state->config.demod_address;
150 msg[0].flags = 0;
151 msg[0].buf = pll_freq_cmd;
152 msg[0].len = sizeof(pll_freq_cmd);
153
154 ret = i2c_transfer(state->i2c, &msg[0], 1);
155 if (ret != 1)
156 goto error;
157
158 udelay(50);
159
160 pll_agc_cmd[DEMOD_REDIRECT_REG] = pll_freq_cmd[DEMOD_REDIRECT_REG];
161 pll_agc_cmd[ADDRESS_BYTE] = pll_freq_cmd[ADDRESS_BYTE];
162 pll_agc_cmd[DIVIDER_BYTE1] = pll_freq_cmd[DIVIDER_BYTE1];
163 pll_agc_cmd[DIVIDER_BYTE2] = pll_freq_cmd[DIVIDER_BYTE2];
164 pll_agc_cmd[CONTROL_BYTE] = 0x9A; /* AGC_CTRL instead of BANDSWITCH */
165 pll_agc_cmd[AGC_CTRL_BYTE] = 0x50;
166 /* AGC Time Constant 2s, AGC take-over point:103dBuV(lowest) */
167
168 msg[1].addr = msg[0].addr;
169 msg[1].flags = 0;
170 msg[1].buf = pll_agc_cmd;
171 msg[1].len = sizeof(pll_agc_cmd);
172
173 ret = i2c_transfer(state->i2c, &msg[1], 1);
174 if (ret != 1)
175 goto error;
176
177 /* I don't know what these cmds are for, */
178 /* but the USB log on a windows box contains them */
179 ret = jdvbt90502_single_reg_write(state, 0x01, 0x40);
180 ret |= jdvbt90502_single_reg_write(state, 0x01, 0x00);
181 if (ret)
182 goto error;
183 udelay(100);
184
185 /* wait for the demod to be ready? */
186#define RETRY_COUNT 5
187 for (retry = 0; retry < RETRY_COUNT; retry++) {
188 ret = jdvbt90502_reg_read(state, 0x0096, &res1, 1);
189 if (ret)
190 goto error;
191 /* if (res1 != 0x00) goto error; */
192 ret = jdvbt90502_reg_read(state, 0x00B0, res2, sizeof(res2));
193 if (ret)
194 goto error;
195 if (res2[0] >= 0xA7)
196 break;
197 msleep(100);
198 }
199 if (retry >= RETRY_COUNT) {
200 deb_fe("%s: FE does not get ready after freq setting.\n",
201 __func__);
202 return -EREMOTEIO;
203 }
204
205 return 0;
206error:
207 deb_fe("%s:ret == %d\n", __func__, ret);
208 return -EREMOTEIO;
209}
210
211static int jdvbt90502_read_status(struct dvb_frontend *fe, fe_status_t *state)
212{
213 u8 result;
214 int ret;
215
216 *state = FE_HAS_SIGNAL;
217
218 ret = jdvbt90502_pll_read(fe->demodulator_priv, &result);
219 if (ret) {
220 deb_fe("%s:ret == %d\n", __func__, ret);
221 return -EREMOTEIO;
222 }
223
224 *state = FE_HAS_SIGNAL
225 | FE_HAS_CARRIER
226 | FE_HAS_VITERBI
227 | FE_HAS_SYNC;
228
229 if (result & PLL_STATUS_LOCKED)
230 *state |= FE_HAS_LOCK;
231
232 return 0;
233}
234
235static int jdvbt90502_read_ber(struct dvb_frontend *fe, u32 *ber)
236{
237 *ber = 0;
238 return 0;
239}
240
241static int jdvbt90502_read_signal_strength(struct dvb_frontend *fe,
242 u16 *strength)
243{
244 int ret;
245 u8 rbuf[37];
246
247 *strength = 0;
248
249 /* status register (incl. signal strength) : 0x89 */
250 /* TODO: read just the necessary registers [0x8B..0x8D]? */
251 ret = jdvbt90502_reg_read(fe->demodulator_priv, 0x0089,
252 rbuf, sizeof(rbuf));
253
254 if (ret) {
255 deb_fe("%s:ret == %d\n", __func__, ret);
256 return -EREMOTEIO;
257 }
258
259 /* signal_strength: rbuf[2-4] (24bit BE), use lower 16bit for now. */
260 *strength = (rbuf[3] << 8) + rbuf[4];
261 if (rbuf[2])
262 *strength = 0xffff;
263
264 return 0;
265}
266
267static int jdvbt90502_read_snr(struct dvb_frontend *fe, u16 *snr)
268{
269 *snr = 0x0101;
270 return 0;
271}
272
273static int jdvbt90502_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
274{
275 *ucblocks = 0;
276 return 0;
277}
278
279static int jdvbt90502_get_tune_settings(struct dvb_frontend *fe,
280 struct dvb_frontend_tune_settings *fs)
281{
282 fs->min_delay_ms = 500;
283 fs->step_size = 0;
284 fs->max_drift = 0;
285
286 return 0;
287}
288
289static int jdvbt90502_get_frontend(struct dvb_frontend *fe,
290 struct dvb_frontend_parameters *p)
291{
292 p->inversion = INVERSION_AUTO;
293 p->u.ofdm.bandwidth = BANDWIDTH_6_MHZ;
294 p->u.ofdm.code_rate_HP = FEC_AUTO;
295 p->u.ofdm.code_rate_LP = FEC_AUTO;
296 p->u.ofdm.constellation = QAM_64;
297 p->u.ofdm.transmission_mode = TRANSMISSION_MODE_AUTO;
298 p->u.ofdm.guard_interval = GUARD_INTERVAL_AUTO;
299 p->u.ofdm.hierarchy_information = HIERARCHY_AUTO;
300 return 0;
301}
302
303static int jdvbt90502_set_frontend(struct dvb_frontend *fe,
304 struct dvb_frontend_parameters *p)
305{
306 /**
307 * NOTE: ignore all the paramters except frequency.
308 * others should be fixed to the proper value for ISDB-T,
309 * but don't check here.
310 */
311
312 struct jdvbt90502_state *state = fe->demodulator_priv;
313 int ret;
314
315 deb_fe("%s: Freq:%d\n", __func__, p->frequency);
316
317 ret = jdvbt90502_pll_set_freq(state, p->frequency);
318 if (ret) {
319 deb_fe("%s:ret == %d\n", __func__, ret);
320 return -EREMOTEIO;
321 }
322
323 return 0;
324}
325
326static int jdvbt90502_sleep(struct dvb_frontend *fe)
327{
328 deb_fe("%s called.\n", __func__);
329 return 0;
330}
331
332
333/**
334 * (reg, val) commad list to initialize this module.
335 * captured on a Windows box.
336 */
337static u8 init_code[][2] = {
338 {0x01, 0x40},
339 {0x04, 0x38},
340 {0x05, 0x40},
341 {0x07, 0x40},
342 {0x0F, 0x4F},
343 {0x11, 0x21},
344 {0x12, 0x0B},
345 {0x13, 0x2F},
346 {0x14, 0x31},
347 {0x16, 0x02},
348 {0x21, 0xC4},
349 {0x22, 0x20},
350 {0x2C, 0x79},
351 {0x2D, 0x34},
352 {0x2F, 0x00},
353 {0x30, 0x28},
354 {0x31, 0x31},
355 {0x32, 0xDF},
356 {0x38, 0x01},
357 {0x39, 0x78},
358 {0x3B, 0x33},
359 {0x3C, 0x33},
360 {0x48, 0x90},
361 {0x51, 0x68},
362 {0x5E, 0x38},
363 {0x71, 0x00},
364 {0x72, 0x08},
365 {0x77, 0x00},
366 {0xC0, 0x21},
367 {0xC1, 0x10},
368 {0xE4, 0x1A},
369 {0xEA, 0x1F},
370 {0x77, 0x00},
371 {0x71, 0x00},
372 {0x71, 0x00},
373 {0x76, 0x0C},
374};
375
376const static int init_code_len = sizeof(init_code) / sizeof(u8[2]);
377
378static int jdvbt90502_init(struct dvb_frontend *fe)
379{
380 int i = -1;
381 int ret;
382 struct i2c_msg msg;
383
384 struct jdvbt90502_state *state = fe->demodulator_priv;
385
386 deb_fe("%s called.\n", __func__);
387
388 msg.addr = state->config.demod_address;
389 msg.flags = 0;
390 msg.len = 2;
391 for (i = 0; i < init_code_len; i++) {
392 msg.buf = init_code[i];
393 ret = i2c_transfer(state->i2c, &msg, 1);
394 if (ret != 1)
395 goto error;
396 }
397 msleep(100);
398
399 return 0;
400
401error:
402 deb_fe("%s: init_code[%d] failed. ret==%d\n", __func__, i, ret);
403 return -EREMOTEIO;
404}
405
406
407static void jdvbt90502_release(struct dvb_frontend *fe)
408{
409 struct jdvbt90502_state *state = fe->demodulator_priv;
410 kfree(state);
411}
412
413
414static struct dvb_frontend_ops jdvbt90502_ops;
415
416struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d)
417{
418 struct jdvbt90502_state *state = NULL;
419
420 deb_info("%s called.\n", __func__);
421
422 /* allocate memory for the internal state */
423 state = kzalloc(sizeof(struct jdvbt90502_state), GFP_KERNEL);
424 if (state == NULL)
425 goto error;
426
427 /* setup the state */
428 state->i2c = &d->i2c_adap;
429 memcpy(&state->config, &friio_fe_config, sizeof(friio_fe_config));
430
431 /* create dvb_frontend */
432 memcpy(&state->frontend.ops, &jdvbt90502_ops,
433 sizeof(jdvbt90502_ops));
434 state->frontend.demodulator_priv = state;
435
436 if (jdvbt90502_init(&state->frontend) < 0)
437 goto error;
438
439 return &state->frontend;
440
441error:
442 kfree(state);
443 return NULL;
444}
445
446static struct dvb_frontend_ops jdvbt90502_ops = {
447
448 .info = {
449 .name = "Comtech JDVBT90502 ISDB-T",
450 .type = FE_OFDM,
451 .frequency_min = 473000000, /* UHF 13ch, center */
452 .frequency_max = 767142857, /* UHF 62ch, center */
453 .frequency_stepsize = JDVBT90502_PLL_CLK /
454 JDVBT90502_PLL_DIVIDER,
455 .frequency_tolerance = 0,
456
457 /* NOTE: this driver ignores all parameters but frequency. */
458 .caps = FE_CAN_INVERSION_AUTO |
459 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
460 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
461 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
462 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
463 FE_CAN_TRANSMISSION_MODE_AUTO |
464 FE_CAN_GUARD_INTERVAL_AUTO |
465 FE_CAN_HIERARCHY_AUTO,
466 },
467
468 .release = jdvbt90502_release,
469
470 .init = jdvbt90502_init,
471 .sleep = jdvbt90502_sleep,
472 .write = _jdvbt90502_write,
473
474 .set_frontend = jdvbt90502_set_frontend,
475 .get_frontend = jdvbt90502_get_frontend,
476 .get_tune_settings = jdvbt90502_get_tune_settings,
477
478 .read_status = jdvbt90502_read_status,
479 .read_ber = jdvbt90502_read_ber,
480 .read_signal_strength = jdvbt90502_read_signal_strength,
481 .read_snr = jdvbt90502_read_snr,
482 .read_ucblocks = jdvbt90502_read_ucblocks,
483};
diff --git a/drivers/media/dvb/dvb-usb/friio.c b/drivers/media/dvb/dvb-usb/friio.c
new file mode 100644
index 000000000000..14a65b4aec07
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.c
@@ -0,0 +1,525 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#include "friio.h"
14
15/* debug */
16int dvb_usb_friio_debug;
17module_param_named(debug, dvb_usb_friio_debug, int, 0644);
18MODULE_PARM_DESC(debug,
19 "set debugging level (1=info,2=xfer,4=rc,8=fe (or-able))."
20 DVB_USB_DEBUG_STATUS);
21
22DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
23
24/**
25 * Indirect I2C access to the PLL via FE.
26 * whole I2C protocol data to the PLL is sent via the FE's I2C register.
27 * This is done by a control msg to the FE with the I2C data accompanied, and
28 * a specific USB request number is assigned for that purpose.
29 *
30 * this func sends wbuf[1..] to the I2C register wbuf[0] at addr (= at FE).
31 * TODO: refoctored, smarter i2c functions.
32 */
33static int gl861_i2c_ctrlmsg_data(struct dvb_usb_device *d, u8 addr,
34 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
35{
36 u16 index = wbuf[0]; /* must be JDVBT90502_2ND_I2C_REG(=0xFE) */
37 u16 value = addr << (8 + 1);
38 int wo = (rbuf == NULL || rlen == 0); /* write only */
39 u8 req, type;
40
41 deb_xfer("write to PLL:0x%02x via FE reg:0x%02x, len:%d\n",
42 wbuf[1], wbuf[0], wlen - 1);
43
44 if (wo && wlen >= 2) {
45 req = GL861_REQ_I2C_DATA_CTRL_WRITE;
46 type = GL861_WRITE;
47 udelay(20);
48 return usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
49 req, type, value, index,
50 &wbuf[1], wlen - 1, 2000);
51 }
52
53 deb_xfer("not supported ctrl-msg, aborting.");
54 return -EINVAL;
55}
56
57/* normal I2C access (without extra data arguments).
58 * write to the register wbuf[0] at I2C address addr with the value wbuf[1],
59 * or read from the register wbuf[0].
60 * register address can be 16bit (wbuf[2]<<8 | wbuf[0]) if wlen==3
61 */
62static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
63 u8 *wbuf, u16 wlen, u8 *rbuf, u16 rlen)
64{
65 u16 index;
66 u16 value = addr << (8 + 1);
67 int wo = (rbuf == NULL || rlen == 0); /* write-only */
68 u8 req, type;
69 unsigned int pipe;
70
71 /* special case for the indirect I2C access to the PLL via FE, */
72 if (addr == friio_fe_config.demod_address &&
73 wbuf[0] == JDVBT90502_2ND_I2C_REG)
74 return gl861_i2c_ctrlmsg_data(d, addr, wbuf, wlen, rbuf, rlen);
75
76 if (wo) {
77 req = GL861_REQ_I2C_WRITE;
78 type = GL861_WRITE;
79 pipe = usb_sndctrlpipe(d->udev, 0);
80 } else { /* rw */
81 req = GL861_REQ_I2C_READ;
82 type = GL861_READ;
83 pipe = usb_rcvctrlpipe(d->udev, 0);
84 }
85
86 switch (wlen) {
87 case 1:
88 index = wbuf[0];
89 break;
90 case 2:
91 index = wbuf[0];
92 value = value + wbuf[1];
93 break;
94 case 3:
95 /* special case for 16bit register-address */
96 index = (wbuf[2] << 8) | wbuf[0];
97 value = value + wbuf[1];
98 break;
99 default:
100 deb_xfer("wlen = %x, aborting.", wlen);
101 return -EINVAL;
102 }
103 msleep(1);
104 return usb_control_msg(d->udev, pipe, req, type,
105 value, index, rbuf, rlen, 2000);
106}
107
108/* I2C */
109static int gl861_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
110 int num)
111{
112 struct dvb_usb_device *d = i2c_get_adapdata(adap);
113 int i;
114
115
116 if (num > 2)
117 return -EINVAL;
118
119 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
120 return -EAGAIN;
121
122 for (i = 0; i < num; i++) {
123 /* write/read request */
124 if (i + 1 < num && (msg[i + 1].flags & I2C_M_RD)) {
125 if (gl861_i2c_msg(d, msg[i].addr,
126 msg[i].buf, msg[i].len,
127 msg[i + 1].buf, msg[i + 1].len) < 0)
128 break;
129 i++;
130 } else
131 if (gl861_i2c_msg(d, msg[i].addr, msg[i].buf,
132 msg[i].len, NULL, 0) < 0)
133 break;
134 }
135
136 mutex_unlock(&d->i2c_mutex);
137 return i;
138}
139
140static u32 gl861_i2c_func(struct i2c_adapter *adapter)
141{
142 return I2C_FUNC_I2C;
143}
144
145
146static int friio_ext_ctl(struct dvb_usb_adapter *adap,
147 u32 sat_color, int lnb_on)
148{
149 int i;
150 int ret;
151 struct i2c_msg msg;
152 u8 buf[2];
153 u32 mask;
154 u8 lnb = (lnb_on) ? FRIIO_CTL_LNB : 0;
155
156 msg.addr = 0x00;
157 msg.flags = 0;
158 msg.len = 2;
159 msg.buf = buf;
160
161 buf[0] = 0x00;
162
163 /* send 2bit header (&B10) */
164 buf[1] = lnb | FRIIO_CTL_LED | FRIIO_CTL_STROBE;
165 ret = gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
166 buf[1] |= FRIIO_CTL_CLK;
167 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
168
169 buf[1] = lnb | FRIIO_CTL_STROBE;
170 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
171 buf[1] |= FRIIO_CTL_CLK;
172 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
173
174 /* send 32bit(satur, R, G, B) data in serial */
175 mask = 1 << 31;
176 for (i = 0; i < 32; i++) {
177 buf[1] = lnb | FRIIO_CTL_STROBE;
178 if (sat_color & mask)
179 buf[1] |= FRIIO_CTL_LED;
180 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
181 buf[1] |= FRIIO_CTL_CLK;
182 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
183 mask >>= 1;
184 }
185
186 /* set the strobe off */
187 buf[1] = lnb;
188 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
189 buf[1] |= FRIIO_CTL_CLK;
190 ret += gl861_i2c_xfer(&adap->dev->i2c_adap, &msg, 1);
191
192 return (ret == 70);
193}
194
195
196static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff);
197
198/* TODO: move these init cmds to the FE's init routine? */
199static u8 streaming_init_cmds[][2] = {
200 {0x33, 0x08},
201 {0x37, 0x40},
202 {0x3A, 0x1F},
203 {0x3B, 0xFF},
204 {0x3C, 0x1F},
205 {0x3D, 0xFF},
206 {0x38, 0x00},
207 {0x35, 0x00},
208 {0x39, 0x00},
209 {0x36, 0x00},
210};
211static int cmdlen = sizeof(streaming_init_cmds) / 2;
212
213/*
214 * Command sequence in this init function is a replay
215 * of the captured USB commands from the Windows proprietary driver.
216 */
217static int friio_initialize(struct dvb_usb_device *d)
218{
219 int ret;
220 int i;
221 int retry = 0;
222 u8 rbuf[2];
223 u8 wbuf[3];
224
225 deb_info("%s called.\n", __func__);
226
227 /* use gl861_i2c_msg instead of gl861_i2c_xfer(), */
228 /* because the i2c device is not set up yet. */
229 wbuf[0] = 0x11;
230 wbuf[1] = 0x02;
231 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
232 if (ret < 0)
233 goto error;
234 msleep(2);
235
236 wbuf[0] = 0x11;
237 wbuf[1] = 0x00;
238 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
239 if (ret < 0)
240 goto error;
241 msleep(1);
242
243 /* following msgs should be in the FE's init code? */
244 /* cmd sequence to identify the device type? (friio black/white) */
245 wbuf[0] = 0x03;
246 wbuf[1] = 0x80;
247 /* can't use gl861_i2c_cmd, as the register-addr is 16bit(0x0100) */
248 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
249 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
250 0x1200, 0x0100, wbuf, 2, 2000);
251 if (ret < 0)
252 goto error;
253
254 msleep(2);
255 wbuf[0] = 0x00;
256 wbuf[2] = 0x01; /* reg.0x0100 */
257 wbuf[1] = 0x00;
258 ret = gl861_i2c_msg(d, 0x12 >> 1, wbuf, 3, rbuf, 2);
259 /* my Friio White returns 0xffff. */
260 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
261 goto error;
262
263 msleep(2);
264 wbuf[0] = 0x03;
265 wbuf[1] = 0x80;
266 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
267 GL861_REQ_I2C_DATA_CTRL_WRITE, GL861_WRITE,
268 0x9000, 0x0100, wbuf, 2, 2000);
269 if (ret < 0)
270 goto error;
271
272 msleep(2);
273 wbuf[0] = 0x00;
274 wbuf[2] = 0x01; /* reg.0x0100 */
275 wbuf[1] = 0x00;
276 ret = gl861_i2c_msg(d, 0x90 >> 1, wbuf, 3, rbuf, 2);
277 /* my Friio White returns 0xffff again. */
278 if (ret < 0 || rbuf[0] != 0xff || rbuf[1] != 0xff)
279 goto error;
280
281 msleep(1);
282
283restart:
284 /* ============ start DEMOD init cmds ================== */
285 /* read PLL status to clear the POR bit */
286 wbuf[0] = JDVBT90502_2ND_I2C_REG;
287 wbuf[1] = (FRIIO_PLL_ADDR << 1) + 1; /* +1 for reading */
288 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, NULL, 0);
289 if (ret < 0)
290 goto error;
291
292 msleep(5);
293 /* note: DEMODULATOR has 16bit register-address. */
294 wbuf[0] = 0x00;
295 wbuf[2] = 0x01; /* reg addr: 0x0100 */
296 wbuf[1] = 0x00; /* val: not used */
297 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 3, rbuf, 1);
298 if (ret < 0)
299 goto error;
300/*
301 msleep(1);
302 wbuf[0] = 0x80;
303 wbuf[1] = 0x00;
304 ret = gl861_i2c_msg(d, FRIIO_DEMOD_ADDR, wbuf, 2, rbuf, 1);
305 if (ret < 0)
306 goto error;
307 */
308 if (rbuf[0] & 0x80) { /* still in PowerOnReset state? */
309 if (++retry > 3) {
310 deb_info("failed to get the correct"
311 " FE demod status:0x%02x\n", rbuf[0]);
312 goto error;
313 }
314 msleep(100);
315 goto restart;
316 }
317
318 /* TODO: check return value in rbuf */
319 /* =========== end DEMOD init cmds ===================== */
320 msleep(1);
321
322 wbuf[0] = 0x30;
323 wbuf[1] = 0x04;
324 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
325 if (ret < 0)
326 goto error;
327
328 msleep(2);
329 /* following 2 cmds unnecessary? */
330 wbuf[0] = 0x00;
331 wbuf[1] = 0x01;
332 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
333 if (ret < 0)
334 goto error;
335
336 wbuf[0] = 0x06;
337 wbuf[1] = 0x0F;
338 ret = gl861_i2c_msg(d, 0x00, wbuf, 2, NULL, 0);
339 if (ret < 0)
340 goto error;
341
342 /* some streaming ctl cmds (maybe) */
343 msleep(10);
344 for (i = 0; i < cmdlen; i++) {
345 ret = gl861_i2c_msg(d, 0x00, streaming_init_cmds[i], 2,
346 NULL, 0);
347 if (ret < 0)
348 goto error;
349 msleep(1);
350 }
351 msleep(20);
352
353 /* change the LED color etc. */
354 ret = friio_streaming_ctrl(&d->adapter[0], 0);
355 if (ret < 0)
356 goto error;
357
358 return 0;
359
360error:
361 deb_info("%s:ret == %d\n", __func__, ret);
362 return -EIO;
363}
364
365/* Callbacks for DVB USB */
366
367static int friio_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
368{
369 int ret;
370
371 deb_info("%s called.(%d)\n", __func__, onoff);
372
373 /* set the LED color and saturation (and LNB on) */
374 if (onoff)
375 ret = friio_ext_ctl(adap, 0x6400ff64, 1);
376 else
377 ret = friio_ext_ctl(adap, 0x96ff00ff, 1);
378
379 if (ret != 1) {
380 deb_info("%s failed to send cmdx. ret==%d\n", __func__, ret);
381 return -EREMOTEIO;
382 }
383 return 0;
384}
385
386static int friio_frontend_attach(struct dvb_usb_adapter *adap)
387{
388 if (friio_initialize(adap->dev) < 0)
389 return -EIO;
390
391 adap->fe = jdvbt90502_attach(adap->dev);
392 if (adap->fe == NULL)
393 return -EIO;
394
395 return 0;
396}
397
398/* DVB USB Driver stuff */
399static struct dvb_usb_device_properties friio_properties;
400
401static int friio_probe(struct usb_interface *intf,
402 const struct usb_device_id *id)
403{
404 struct dvb_usb_device *d;
405 struct usb_host_interface *alt;
406 int ret;
407
408 if (intf->num_altsetting < GL861_ALTSETTING_COUNT)
409 return -ENODEV;
410
411 alt = usb_altnum_to_altsetting(intf, FRIIO_BULK_ALTSETTING);
412 if (alt == NULL) {
413 deb_rc("not alt found!\n");
414 return -ENODEV;
415 }
416 ret = usb_set_interface(interface_to_usbdev(intf),
417 alt->desc.bInterfaceNumber,
418 alt->desc.bAlternateSetting);
419 if (ret != 0) {
420 deb_rc("failed to set alt-setting!\n");
421 return ret;
422 }
423
424 ret = dvb_usb_device_init(intf, &friio_properties,
425 THIS_MODULE, &d, adapter_nr);
426 if (ret == 0)
427 friio_streaming_ctrl(&d->adapter[0], 1);
428
429 return ret;
430}
431
432
433struct jdvbt90502_config friio_fe_config = {
434 .demod_address = FRIIO_DEMOD_ADDR,
435 .pll_address = FRIIO_PLL_ADDR,
436};
437
438static struct i2c_algorithm gl861_i2c_algo = {
439 .master_xfer = gl861_i2c_xfer,
440 .functionality = gl861_i2c_func,
441};
442
443static struct usb_device_id friio_table[] = {
444 { USB_DEVICE(USB_VID_774, USB_PID_FRIIO_WHITE) },
445 { } /* Terminating entry */
446};
447MODULE_DEVICE_TABLE(usb, friio_table);
448
449
450static struct dvb_usb_device_properties friio_properties = {
451 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
452 .usb_ctrl = DEVICE_SPECIFIC,
453
454 .size_of_priv = 0,
455
456 .num_adapters = 1,
457 .adapter = {
458 /* caps:0 => no pid filter, 188B TS packet */
459 /* GL861 has a HW pid filter, but no info available. */
460 {
461 .caps = 0,
462
463 .frontend_attach = friio_frontend_attach,
464 .streaming_ctrl = friio_streaming_ctrl,
465
466 .stream = {
467 .type = USB_BULK,
468 /* count <= MAX_NO_URBS_FOR_DATA_STREAM(10) */
469 .count = 8,
470 .endpoint = 0x01,
471 .u = {
472 /* GL861 has 6KB buf inside */
473 .bulk = {
474 .buffersize = 16384,
475 }
476 }
477 },
478 }
479 },
480 .i2c_algo = &gl861_i2c_algo,
481
482 .num_device_descs = 1,
483 .devices = {
484 {
485 .name = "774 Friio ISDB-T USB2.0",
486 .cold_ids = { NULL },
487 .warm_ids = { &friio_table[0], NULL },
488 },
489 }
490};
491
492static struct usb_driver friio_driver = {
493 .name = "dvb_usb_friio",
494 .probe = friio_probe,
495 .disconnect = dvb_usb_device_exit,
496 .id_table = friio_table,
497};
498
499
500/* module stuff */
501static int __init friio_module_init(void)
502{
503 int ret;
504
505 ret = usb_register(&friio_driver);
506 if (ret)
507 err("usb_register failed. Error number %d", ret);
508
509 return ret;
510}
511
512
513static void __exit friio_module_exit(void)
514{
515 /* deregister this driver from the USB subsystem */
516 usb_deregister(&friio_driver);
517}
518
519module_init(friio_module_init);
520module_exit(friio_module_exit);
521
522MODULE_AUTHOR("Akihiro Tsukada <tskd2@yahoo.co.jp>");
523MODULE_DESCRIPTION("Driver for Friio ISDB-T USB2.0 Receiver");
524MODULE_VERSION("0.2");
525MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/friio.h b/drivers/media/dvb/dvb-usb/friio.h
new file mode 100644
index 000000000000..af8d55e390fb
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/friio.h
@@ -0,0 +1,99 @@
1/* DVB USB compliant Linux driver for the Friio USB2.0 ISDB-T receiver.
2 *
3 * Copyright (C) 2009 Akihiro Tsukada <tskd2@yahoo.co.jp>
4 *
5 * This module is based off the the gl861 and vp702x modules.
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation, version 2.
10 *
11 * see Documentation/dvb/README.dvb-usb for more information
12 */
13#ifndef _DVB_USB_FRIIO_H_
14#define _DVB_USB_FRIIO_H_
15
16/**
17 * Friio Components
18 * USB hub: AU4254
19 * USB controller(+ TS dmx & streaming): GL861
20 * Frontend: comtech JDVBT-90502
21 * (tuner PLL: tua6034, I2C addr:(0xC0 >> 1))
22 * (OFDM demodulator: TC90502, I2C addr:(0x30 >> 1))
23 * LED x3 (+LNB) controll: PIC 16F676
24 * EEPROM: 24C08
25 *
26 * (USB smart card reader: AU9522)
27 *
28 */
29
30#define DVB_USB_LOG_PREFIX "friio"
31#include "dvb-usb.h"
32
33extern int dvb_usb_friio_debug;
34#define deb_info(args...) dprintk(dvb_usb_friio_debug, 0x01, args)
35#define deb_xfer(args...) dprintk(dvb_usb_friio_debug, 0x02, args)
36#define deb_rc(args...) dprintk(dvb_usb_friio_debug, 0x04, args)
37#define deb_fe(args...) dprintk(dvb_usb_friio_debug, 0x08, args)
38
39/* Vendor requests */
40#define GL861_WRITE 0x40
41#define GL861_READ 0xc0
42
43/* command bytes */
44#define GL861_REQ_I2C_WRITE 0x01
45#define GL861_REQ_I2C_READ 0x02
46/* For control msg with data argument */
47/* Used for accessing the PLL on the secondary I2C bus of FE via GL861 */
48#define GL861_REQ_I2C_DATA_CTRL_WRITE 0x03
49
50#define GL861_ALTSETTING_COUNT 2
51#define FRIIO_BULK_ALTSETTING 0
52#define FRIIO_ISOC_ALTSETTING 1
53
54/* LED & LNB control via PIC. */
55/* basically, it's serial control with clock and strobe. */
56/* write the below 4bit control data to the reg 0x00 at the I2C addr 0x00 */
57/* when controlling the LEDs, 32bit(saturation, R, G, B) is sent on the bit3*/
58#define FRIIO_CTL_LNB (1 << 0)
59#define FRIIO_CTL_STROBE (1 << 1)
60#define FRIIO_CTL_CLK (1 << 2)
61#define FRIIO_CTL_LED (1 << 3)
62
63/* Front End related */
64
65#define FRIIO_DEMOD_ADDR (0x30 >> 1)
66#define FRIIO_PLL_ADDR (0xC0 >> 1)
67
68#define JDVBT90502_PLL_CLK 4000000
69#define JDVBT90502_PLL_DIVIDER 28
70
71#define JDVBT90502_2ND_I2C_REG 0xFE
72
73/* byte index for pll i2c command data structure*/
74/* see datasheet for tua6034 */
75#define DEMOD_REDIRECT_REG 0
76#define ADDRESS_BYTE 1
77#define DIVIDER_BYTE1 2
78#define DIVIDER_BYTE2 3
79#define CONTROL_BYTE 4
80#define BANDSWITCH_BYTE 5
81#define AGC_CTRL_BYTE 5
82#define PLL_CMD_LEN 6
83
84/* bit masks for PLL STATUS response */
85#define PLL_STATUS_POR_MODE 0x80 /* 1: Power on Reset (test) Mode */
86#define PLL_STATUS_LOCKED 0x40 /* 1: locked */
87#define PLL_STATUS_AGC_ACTIVE 0x08 /* 1:active */
88#define PLL_STATUS_TESTMODE 0x07 /* digital output level (5 level) */
89 /* 0.15Vcc step 0x00: < 0.15Vcc, ..., 0x04: >= 0.6Vcc (<= 1Vcc) */
90
91
92struct jdvbt90502_config {
93 u8 demod_address; /* i2c addr for demodulator IC */
94 u8 pll_address; /* PLL addr on the secondary i2c*/
95};
96extern struct jdvbt90502_config friio_fe_config;
97
98extern struct dvb_frontend *jdvbt90502_attach(struct dvb_usb_device *d);
99#endif
diff --git a/drivers/media/dvb/dvb-usb/m920x.c b/drivers/media/dvb/dvb-usb/m920x.c
index aec7a1943b66..ef9b7bed13ff 100644
--- a/drivers/media/dvb/dvb-usb/m920x.c
+++ b/drivers/media/dvb/dvb-usb/m920x.c
@@ -337,6 +337,8 @@ static int m920x_firmware_download(struct usb_device *udev, const struct firmwar
337 int i, pass, ret = 0; 337 int i, pass, ret = 0;
338 338
339 buff = kmalloc(65536, GFP_KERNEL); 339 buff = kmalloc(65536, GFP_KERNEL);
340 if (buff == NULL)
341 return -ENOMEM;
340 342
341 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0) 343 if ((ret = m920x_read(udev, M9206_FILTER, 0x0, 0x8000, read, 4)) != 0)
342 goto done; 344 goto done;
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b794e860b4e2..d7c4837fa71c 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -484,6 +484,14 @@ config DVB_S921
484 AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module. 484 AN ISDB-T DQPSK, QPSK, 16QAM and 64QAM 1seg tuner module.
485 Say Y when you want to support this frontend. 485 Say Y when you want to support this frontend.
486 486
487config DVB_DIB8000
488 tristate "DiBcom 8000MB/MC"
489 depends on DVB_CORE && I2C
490 default m if DVB_FE_CUSTOMISE
491 help
492 A driver for DiBcom's DiB8000 ISDB-T/ISDB-Tsb demodulator.
493 Say Y when you want to support this frontend.
494
487comment "Digital terrestrial only tuners/PLL" 495comment "Digital terrestrial only tuners/PLL"
488 depends on DVB_CORE 496 depends on DVB_CORE
489 497
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 3b49d37ab5fa..3523767e7a76 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
23obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o 23obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
24obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o 24obj-$(CONFIG_DVB_DIB7000M) += dib7000m.o dibx000_common.o
25obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o 25obj-$(CONFIG_DVB_DIB7000P) += dib7000p.o dibx000_common.o
26obj-$(CONFIG_DVB_DIB8000) += dib8000.o dibx000_common.o
26obj-$(CONFIG_DVB_MT312) += mt312.o 27obj-$(CONFIG_DVB_MT312) += mt312.o
27obj-$(CONFIG_DVB_VES1820) += ves1820.o 28obj-$(CONFIG_DVB_VES1820) += ves1820.o
28obj-$(CONFIG_DVB_VES1X93) += ves1x93.o 29obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
diff --git a/drivers/media/dvb/frontends/au8522_decoder.c b/drivers/media/dvb/frontends/au8522_decoder.c
index 9e9a75576a1d..74981ee923c8 100644
--- a/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/drivers/media/dvb/frontends/au8522_decoder.c
@@ -792,6 +792,11 @@ static int au8522_probe(struct i2c_client *client,
792 } 792 }
793 793
794 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL); 794 demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
795 if (demod_config == NULL) {
796 if (instance == 1)
797 kfree(state);
798 return -ENOMEM;
799 }
795 demod_config->demod_address = 0x8e >> 1; 800 demod_config->demod_address = 0x8e >> 1;
796 801
797 state->config = demod_config; 802 state->config = demod_config;
diff --git a/drivers/media/dvb/frontends/dib0070.c b/drivers/media/dvb/frontends/dib0070.c
index da92cbe1b8ea..2be17b93e0bd 100644
--- a/drivers/media/dvb/frontends/dib0070.c
+++ b/drivers/media/dvb/frontends/dib0070.c
@@ -1,12 +1,29 @@
1/* 1/*
2 * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner. 2 * Linux-DVB Driver for DiBcom's DiB0070 base-band RF Tuner.
3 * 3 *
4 * Copyright (C) 2005-7 DiBcom (http://www.dibcom.fr/) 4 * Copyright (C) 2005-9 DiBcom (http://www.dibcom.fr/)
5 * 5 *
6 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as 7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2. 8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 * This code is more or less generated from another driver, please
23 * excuse some codingstyle oddities.
24 *
9 */ 25 */
26
10#include <linux/kernel.h> 27#include <linux/kernel.h>
11#include <linux/i2c.h> 28#include <linux/i2c.h>
12 29
@@ -19,27 +36,65 @@ static int debug;
19module_param(debug, int, 0644); 36module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "turn on debugging (default: 0)"); 37MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
21 38
22#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB0070: "); printk(args); printk("\n"); } } while (0) 39#define dprintk(args...) do { \
40 if (debug) { \
41 printk(KERN_DEBUG "DiB0070: "); \
42 printk(args); \
43 printk("\n"); \
44 } \
45} while (0)
23 46
24#define DIB0070_P1D 0x00 47#define DIB0070_P1D 0x00
25#define DIB0070_P1F 0x01 48#define DIB0070_P1F 0x01
26#define DIB0070_P1G 0x03 49#define DIB0070_P1G 0x03
27#define DIB0070S_P1A 0x02 50#define DIB0070S_P1A 0x02
28 51
52enum frontend_tune_state {
53 CT_TUNER_START = 10,
54 CT_TUNER_STEP_0,
55 CT_TUNER_STEP_1,
56 CT_TUNER_STEP_2,
57 CT_TUNER_STEP_3,
58 CT_TUNER_STEP_4,
59 CT_TUNER_STEP_5,
60 CT_TUNER_STEP_6,
61 CT_TUNER_STEP_7,
62 CT_TUNER_STOP,
63};
64
65#define FE_CALLBACK_TIME_NEVER 0xffffffff
66
29struct dib0070_state { 67struct dib0070_state {
30 struct i2c_adapter *i2c; 68 struct i2c_adapter *i2c;
31 struct dvb_frontend *fe; 69 struct dvb_frontend *fe;
32 const struct dib0070_config *cfg; 70 const struct dib0070_config *cfg;
33 u16 wbd_ff_offset; 71 u16 wbd_ff_offset;
34 u8 revision; 72 u8 revision;
73
74 enum frontend_tune_state tune_state;
75 u32 current_rf;
76
77 /* for the captrim binary search */
78 s8 step;
79 u16 adc_diff;
80
81 s8 captrim;
82 s8 fcaptrim;
83 u16 lo4;
84
85 const struct dib0070_tuning *current_tune_table_index;
86 const struct dib0070_lna_match *lna_match;
87
88 u8 wbd_gain_current;
89 u16 wbd_offset_3_3[2];
35}; 90};
36 91
37static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg) 92static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
38{ 93{
39 u8 b[2]; 94 u8 b[2];
40 struct i2c_msg msg[2] = { 95 struct i2c_msg msg[2] = {
41 { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 }, 96 {.addr = state->cfg->i2c_address,.flags = 0,.buf = &reg,.len = 1},
42 { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = b, .len = 2 }, 97 {.addr = state->cfg->i2c_address,.flags = I2C_M_RD,.buf = b,.len = 2},
43 }; 98 };
44 if (i2c_transfer(state->i2c, msg, 2) != 2) { 99 if (i2c_transfer(state->i2c, msg, 2) != 2) {
45 printk(KERN_WARNING "DiB0070 I2C read failed\n"); 100 printk(KERN_WARNING "DiB0070 I2C read failed\n");
@@ -51,7 +106,7 @@ static uint16_t dib0070_read_reg(struct dib0070_state *state, u8 reg)
51static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val) 106static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
52{ 107{
53 u8 b[3] = { reg, val >> 8, val & 0xff }; 108 u8 b[3] = { reg, val >> 8, val & 0xff };
54 struct i2c_msg msg = { .addr = state->cfg->i2c_address, .flags = 0, .buf = b, .len = 3 }; 109 struct i2c_msg msg = {.addr = state->cfg->i2c_address,.flags = 0,.buf = b,.len = 3 };
55 if (i2c_transfer(state->i2c, &msg, 1) != 1) { 110 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
56 printk(KERN_WARNING "DiB0070 I2C write failed\n"); 111 printk(KERN_WARNING "DiB0070 I2C write failed\n");
57 return -EREMOTEIO; 112 return -EREMOTEIO;
@@ -59,55 +114,71 @@ static int dib0070_write_reg(struct dib0070_state *state, u8 reg, u16 val)
59 return 0; 114 return 0;
60} 115}
61 116
62#define HARD_RESET(state) do { if (state->cfg->reset) { state->cfg->reset(state->fe,1); msleep(10); state->cfg->reset(state->fe,0); msleep(10); } } while (0) 117#define HARD_RESET(state) do { \
118 state->cfg->sleep(state->fe, 0); \
119 if (state->cfg->reset) { \
120 state->cfg->reset(state->fe,1); msleep(10); \
121 state->cfg->reset(state->fe,0); msleep(10); \
122 } \
123} while (0)
63 124
64static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch) 125static int dib0070_set_bandwidth(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
65{ 126{
66 struct dib0070_state *st = fe->tuner_priv; 127 struct dib0070_state *state = fe->tuner_priv;
67 u16 tmp = 0; 128 u16 tmp = dib0070_read_reg(state, 0x02) & 0x3fff;
68 tmp = dib0070_read_reg(st, 0x02) & 0x3fff; 129
130 if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 7000)
131 tmp |= (0 << 14);
132 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 6000)
133 tmp |= (1 << 14);
134 else if (state->fe->dtv_property_cache.bandwidth_hz / 1000 > 5000)
135 tmp |= (2 << 14);
136 else
137 tmp |= (3 << 14);
69 138
70 switch(BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)) { 139 dib0070_write_reg(state, 0x02, tmp);
71 case 8000: 140
72 tmp |= (0 << 14); 141 /* sharpen the BB filter in ISDB-T to have higher immunity to adjacent channels */
73 break; 142 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) {
74 case 7000: 143 u16 value = dib0070_read_reg(state, 0x17);
75 tmp |= (1 << 14); 144
76 break; 145 dib0070_write_reg(state, 0x17, value & 0xfffc);
77 case 6000: 146 tmp = dib0070_read_reg(state, 0x01) & 0x01ff;
78 tmp |= (2 << 14); 147 dib0070_write_reg(state, 0x01, tmp | (60 << 9));
79 break; 148
80 case 5000: 149 dib0070_write_reg(state, 0x17, value);
81 default:
82 tmp |= (3 << 14);
83 break;
84 } 150 }
85 dib0070_write_reg(st, 0x02, tmp);
86 return 0; 151 return 0;
87} 152}
88 153
89static void dib0070_captrim(struct dib0070_state *st, u16 LO4) 154static int dib0070_captrim(struct dib0070_state *state, enum frontend_tune_state *tune_state)
90{ 155{
91 int8_t captrim, fcaptrim, step_sign, step; 156 int8_t step_sign;
92 u16 adc, adc_diff = 3000; 157 u16 adc;
158 int ret = 0;
93 159
160 if (*tune_state == CT_TUNER_STEP_0) {
94 161
162 dib0070_write_reg(state, 0x0f, 0xed10);
163 dib0070_write_reg(state, 0x17, 0x0034);
95 164
96 dib0070_write_reg(st, 0x0f, 0xed10); 165 dib0070_write_reg(state, 0x18, 0x0032);
97 dib0070_write_reg(st, 0x17, 0x0034); 166 state->step = state->captrim = state->fcaptrim = 64;
167 state->adc_diff = 3000;
168 ret = 20;
98 169
99 dib0070_write_reg(st, 0x18, 0x0032); 170 *tune_state = CT_TUNER_STEP_1;
100 msleep(2); 171 } else if (*tune_state == CT_TUNER_STEP_1) {
172 state->step /= 2;
173 dib0070_write_reg(state, 0x14, state->lo4 | state->captrim);
174 ret = 15;
101 175
102 step = captrim = fcaptrim = 64; 176 *tune_state = CT_TUNER_STEP_2;
177 } else if (*tune_state == CT_TUNER_STEP_2) {
103 178
104 do { 179 adc = dib0070_read_reg(state, 0x19);
105 step /= 2;
106 dib0070_write_reg(st, 0x14, LO4 | captrim);
107 msleep(1);
108 adc = dib0070_read_reg(st, 0x19);
109 180
110 dprintk( "CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", captrim, adc, (u32) adc*(u32)1800/(u32)1024); 181 dprintk("CAPTRIM=%hd; ADC = %hd (ADC) & %dmV", state->captrim, adc, (u32) adc * (u32) 1800 / (u32) 1024);
111 182
112 if (adc >= 400) { 183 if (adc >= 400) {
113 adc -= 400; 184 adc -= 400;
@@ -117,379 +188,430 @@ static void dib0070_captrim(struct dib0070_state *st, u16 LO4)
117 step_sign = 1; 188 step_sign = 1;
118 } 189 }
119 190
120 if (adc < adc_diff) { 191 if (adc < state->adc_diff) {
121 dprintk( "CAPTRIM=%hd is closer to target (%hd/%hd)", captrim, adc, adc_diff); 192 dprintk("CAPTRIM=%hd is closer to target (%hd/%hd)", state->captrim, adc, state->adc_diff);
122 adc_diff = adc; 193 state->adc_diff = adc;
123 fcaptrim = captrim; 194 state->fcaptrim = state->captrim;
124 195
196 }
197 state->captrim += (step_sign * state->step);
125 198
199 if (state->step >= 1)
200 *tune_state = CT_TUNER_STEP_1;
201 else
202 *tune_state = CT_TUNER_STEP_3;
126 203
127 } 204 } else if (*tune_state == CT_TUNER_STEP_3) {
128 captrim += (step_sign * step); 205 dib0070_write_reg(state, 0x14, state->lo4 | state->fcaptrim);
129 } while (step >= 1); 206 dib0070_write_reg(state, 0x18, 0x07ff);
207 *tune_state = CT_TUNER_STEP_4;
208 }
130 209
131 dib0070_write_reg(st, 0x14, LO4 | fcaptrim); 210 return ret;
132 dib0070_write_reg(st, 0x18, 0x07ff);
133} 211}
134 212
135#define LPF 100 // define for the loop filter 100kHz by default 16-07-06 213static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
136#define LO4_SET_VCO_HFDIV(l, v, h) l |= ((v) << 11) | ((h) << 7)
137#define LO4_SET_SD(l, s) l |= ((s) << 14) | ((s) << 12)
138#define LO4_SET_CTRIM(l, c) l |= (c) << 10
139static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
140{ 214{
141 struct dib0070_state *st = fe->tuner_priv; 215 struct dib0070_state *state = fe->tuner_priv;
142 u32 freq = ch->frequency/1000 + (BAND_OF_FREQUENCY(ch->frequency/1000) == BAND_VHF ? st->cfg->freq_offset_khz_vhf : st->cfg->freq_offset_khz_uhf); 216 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0);
143 217 dprintk("CTRL_LO5: 0x%x", lo5);
144 u8 band = BAND_OF_FREQUENCY(freq), c; 218 return dib0070_write_reg(state, 0x15, lo5);
219}
145 220
146 /*******************VCO***********************************/ 221void dib0070_ctrl_agc_filter(struct dvb_frontend *fe, u8 open)
147 u16 lo4 = 0; 222{
223 struct dib0070_state *state = fe->tuner_priv;
148 224
149 u8 REFDIV, PRESC = 2; 225 if (open) {
150 u32 FBDiv, Rest, FREF, VCOF_kHz; 226 dib0070_write_reg(state, 0x1b, 0xff00);
151 u16 Num, Den; 227 dib0070_write_reg(state, 0x1a, 0x0000);
152 /*******************FrontEnd******************************/ 228 } else {
153 u16 value = 0; 229 dib0070_write_reg(state, 0x1b, 0x4112);
230 if (state->cfg->vga_filter != 0) {
231 dib0070_write_reg(state, 0x1a, state->cfg->vga_filter);
232 dprintk("vga filter register is set to %x", state->cfg->vga_filter);
233 } else
234 dib0070_write_reg(state, 0x1a, 0x0009);
235 }
236}
154 237
155 dprintk( "Tuning for Band: %hd (%d kHz)", band, freq); 238EXPORT_SYMBOL(dib0070_ctrl_agc_filter);
239struct dib0070_tuning {
240 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
241 u8 switch_trim;
242 u8 vco_band;
243 u8 hfdiv;
244 u8 vco_multi;
245 u8 presc;
246 u8 wbdmux;
247 u16 tuner_enable;
248};
156 249
250struct dib0070_lna_match {
251 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
252 u8 lna_band;
253};
157 254
158 dib0070_write_reg(st, 0x17, 0x30); 255static const struct dib0070_tuning dib0070s_tuning_table[] = {
256 {570000, 2, 1, 3, 6, 6, 2, 0x4000 | 0x0800}, /* UHF */
257 {700000, 2, 0, 2, 4, 2, 2, 0x4000 | 0x0800},
258 {863999, 2, 1, 2, 4, 2, 2, 0x4000 | 0x0800},
259 {1500000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND */
260 {1600000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
261 {2000000, 0, 1, 1, 2, 2, 4, 0x2000 | 0x0400},
262 {0xffffffff, 0, 0, 8, 1, 2, 1, 0x8000 | 0x1000}, /* SBAND */
263};
159 264
160 dib0070_set_bandwidth(fe, ch); /* c is used as HF */ 265static const struct dib0070_tuning dib0070_tuning_table[] = {
161 switch (st->revision) { 266 {115000, 1, 0, 7, 24, 2, 1, 0x8000 | 0x1000}, /* FM below 92MHz cannot be tuned */
162 case DIB0070S_P1A: 267 {179500, 1, 0, 3, 16, 2, 1, 0x8000 | 0x1000}, /* VHF */
163 switch (band) { 268 {189999, 1, 1, 3, 16, 2, 1, 0x8000 | 0x1000},
164 case BAND_LBAND: 269 {250000, 1, 0, 6, 12, 2, 1, 0x8000 | 0x1000},
165 LO4_SET_VCO_HFDIV(lo4, 1, 1); 270 {569999, 2, 1, 5, 6, 2, 2, 0x4000 | 0x0800}, /* UHF */
166 c = 2; 271 {699999, 2, 0, 1, 4, 2, 2, 0x4000 | 0x0800},
167 break; 272 {863999, 2, 1, 1, 4, 2, 2, 0x4000 | 0x0800},
168 case BAND_SBAND: 273 {0xffffffff, 0, 1, 0, 2, 2, 4, 0x2000 | 0x0400}, /* LBAND or everything higher than UHF */
169 LO4_SET_VCO_HFDIV(lo4, 0, 0); 274};
170 LO4_SET_CTRIM(lo4, 1);
171 c = 1;
172 break;
173 case BAND_UHF:
174 default:
175 if (freq < 570000) {
176 LO4_SET_VCO_HFDIV(lo4, 1, 3);
177 PRESC = 6; c = 6;
178 } else if (freq < 680000) {
179 LO4_SET_VCO_HFDIV(lo4, 0, 2);
180 c = 4;
181 } else {
182 LO4_SET_VCO_HFDIV(lo4, 1, 2);
183 c = 4;
184 }
185 break;
186 } break;
187
188 case DIB0070_P1G:
189 case DIB0070_P1F:
190 default:
191 switch (band) {
192 case BAND_FM:
193 LO4_SET_VCO_HFDIV(lo4, 0, 7);
194 c = 24;
195 break;
196 case BAND_LBAND:
197 LO4_SET_VCO_HFDIV(lo4, 1, 0);
198 c = 2;
199 break;
200 case BAND_VHF:
201 if (freq < 180000) {
202 LO4_SET_VCO_HFDIV(lo4, 0, 3);
203 c = 16;
204 } else if (freq < 190000) {
205 LO4_SET_VCO_HFDIV(lo4, 1, 3);
206 c = 16;
207 } else {
208 LO4_SET_VCO_HFDIV(lo4, 0, 6);
209 c = 12;
210 }
211 break;
212
213 case BAND_UHF:
214 default:
215 if (freq < 570000) {
216 LO4_SET_VCO_HFDIV(lo4, 1, 5);
217 c = 6;
218 } else if (freq < 700000) {
219 LO4_SET_VCO_HFDIV(lo4, 0, 1);
220 c = 4;
221 } else {
222 LO4_SET_VCO_HFDIV(lo4, 1, 1);
223 c = 4;
224 }
225 break;
226 }
227 break;
228 }
229 275
230 dprintk( "HFDIV code: %hd", (lo4 >> 7) & 0xf); 276static const struct dib0070_lna_match dib0070_lna_flip_chip[] = {
231 dprintk( "VCO = %hd", (lo4 >> 11) & 0x3); 277 {180000, 0}, /* VHF */
278 {188000, 1},
279 {196400, 2},
280 {250000, 3},
281 {550000, 0}, /* UHF */
282 {590000, 1},
283 {666000, 3},
284 {864000, 5},
285 {1500000, 0}, /* LBAND or everything higher than UHF */
286 {1600000, 1},
287 {2000000, 3},
288 {0xffffffff, 7},
289};
232 290
291static const struct dib0070_lna_match dib0070_lna[] = {
292 {180000, 0}, /* VHF */
293 {188000, 1},
294 {196400, 2},
295 {250000, 3},
296 {550000, 2}, /* UHF */
297 {650000, 3},
298 {750000, 5},
299 {850000, 6},
300 {864000, 7},
301 {1500000, 0}, /* LBAND or everything higher than UHF */
302 {1600000, 1},
303 {2000000, 3},
304 {0xffffffff, 7},
305};
233 306
234 VCOF_kHz = (c * freq) * 2; 307#define LPF 100 // define for the loop filter 100kHz by default 16-07-06
235 dprintk( "VCOF in kHz: %d ((%hd*%d) << 1))",VCOF_kHz, c, freq); 308static int dib0070_tune_digital(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
309{
310 struct dib0070_state *state = fe->tuner_priv;
236 311
237 switch (band) { 312 const struct dib0070_tuning *tune;
238 case BAND_VHF: 313 const struct dib0070_lna_match *lna_match;
239 REFDIV = (u8) ((st->cfg->clock_khz + 9999) / 10000);
240 break;
241 case BAND_FM:
242 REFDIV = (u8) ((st->cfg->clock_khz) / 1000);
243 break;
244 default:
245 REFDIV = (u8) ( st->cfg->clock_khz / 10000);
246 break;
247 }
248 FREF = st->cfg->clock_khz / REFDIV;
249 314
250 dprintk( "REFDIV: %hd, FREF: %d", REFDIV, FREF); 315 enum frontend_tune_state *tune_state = &state->tune_state;
316 int ret = 10; /* 1ms is the default delay most of the time */
251 317
318 u8 band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000);
319 u32 freq = fe->dtv_property_cache.frequency / 1000 + (band == BAND_VHF ? state->cfg->freq_offset_khz_vhf : state->cfg->freq_offset_khz_uhf);
252 320
321#ifdef CONFIG_SYS_ISDBT
322 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1)
323 if (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2)
324 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
325 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
326 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == (state->fe->dtv_property_cache.isdbt_sb_segment_count / 2)))
327 || (((state->fe->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
328 && (state->fe->dtv_property_cache.isdbt_sb_segment_idx == ((state->fe->dtv_property_cache.isdbt_sb_segment_count / 2) + 1))))
329 freq += 850;
330#endif
331 if (state->current_rf != freq) {
253 332
254 switch (st->revision) { 333 switch (state->revision) {
255 case DIB0070S_P1A: 334 case DIB0070S_P1A:
256 FBDiv = (VCOF_kHz / PRESC / FREF); 335 tune = dib0070s_tuning_table;
257 Rest = (VCOF_kHz / PRESC) - FBDiv * FREF; 336 lna_match = dib0070_lna;
258 break; 337 break;
259
260 case DIB0070_P1G:
261 case DIB0070_P1F:
262 default: 338 default:
263 FBDiv = (freq / (FREF / 2)); 339 tune = dib0070_tuning_table;
264 Rest = 2 * freq - FBDiv * FREF; 340 if (state->cfg->flip_chip)
341 lna_match = dib0070_lna_flip_chip;
342 else
343 lna_match = dib0070_lna;
265 break; 344 break;
266 } 345 }
267 346 while (freq > tune->max_freq) /* find the right one */
268 347 tune++;
269 if (Rest < LPF) Rest = 0; 348 while (freq > lna_match->max_freq) /* find the right one */
270 else if (Rest < 2 * LPF) Rest = 2 * LPF; 349 lna_match++;
271 else if (Rest > (FREF - LPF)) { Rest = 0 ; FBDiv += 1; }
272 else if (Rest > (FREF - 2 * LPF)) Rest = FREF - 2 * LPF;
273 Rest = (Rest * 6528) / (FREF / 10);
274 dprintk( "FBDIV: %d, Rest: %d", FBDiv, Rest);
275
276 Num = 0;
277 Den = 1;
278 350
279 if (Rest > 0) { 351 state->current_tune_table_index = tune;
280 LO4_SET_SD(lo4, 1); 352 state->lna_match = lna_match;
281 Den = 255;
282 Num = (u16)Rest;
283 } 353 }
284 dprintk( "Num: %hd, Den: %hd, SD: %hd",Num, Den, (lo4 >> 12) & 0x1);
285 354
355 if (*tune_state == CT_TUNER_START) {
356 dprintk("Tuning for Band: %hd (%d kHz)", band, freq);
357 if (state->current_rf != freq) {
358 u8 REFDIV;
359 u32 FBDiv, Rest, FREF, VCOF_kHz;
360 u8 Den;
286 361
362 state->current_rf = freq;
363 state->lo4 = (state->current_tune_table_index->vco_band << 11) | (state->current_tune_table_index->hfdiv << 7);
287 364
288 dib0070_write_reg(st, 0x11, (u16)FBDiv); 365 dib0070_write_reg(state, 0x17, 0x30);
289 366
367 VCOF_kHz = state->current_tune_table_index->vco_multi * freq * 2;
290 368
291 dib0070_write_reg(st, 0x12, (Den << 8) | REFDIV); 369 switch (band) {
292 370 case BAND_VHF:
371 REFDIV = (u8) ((state->cfg->clock_khz + 9999) / 10000);
372 break;
373 case BAND_FM:
374 REFDIV = (u8) ((state->cfg->clock_khz) / 1000);
375 break;
376 default:
377 REFDIV = (u8) (state->cfg->clock_khz / 10000);
378 break;
379 }
380 FREF = state->cfg->clock_khz / REFDIV;
381
382 switch (state->revision) {
383 case DIB0070S_P1A:
384 FBDiv = (VCOF_kHz / state->current_tune_table_index->presc / FREF);
385 Rest = (VCOF_kHz / state->current_tune_table_index->presc) - FBDiv * FREF;
386 break;
387
388 case DIB0070_P1G:
389 case DIB0070_P1F:
390 default:
391 FBDiv = (freq / (FREF / 2));
392 Rest = 2 * freq - FBDiv * FREF;
393 break;
394 }
293 395
294 dib0070_write_reg(st, 0x13, Num); 396 if (Rest < LPF)
397 Rest = 0;
398 else if (Rest < 2 * LPF)
399 Rest = 2 * LPF;
400 else if (Rest > (FREF - LPF)) {
401 Rest = 0;
402 FBDiv += 1;
403 } else if (Rest > (FREF - 2 * LPF))
404 Rest = FREF - 2 * LPF;
405 Rest = (Rest * 6528) / (FREF / 10);
406
407 Den = 1;
408 if (Rest > 0) {
409 state->lo4 |= (1 << 14) | (1 << 12);
410 Den = 255;
411 }
295 412
413 dib0070_write_reg(state, 0x11, (u16) FBDiv);
414 dib0070_write_reg(state, 0x12, (Den << 8) | REFDIV);
415 dib0070_write_reg(state, 0x13, (u16) Rest);
296 416
297 value = 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001; 417 if (state->revision == DIB0070S_P1A) {
298 418
299 switch (band) { 419 if (band == BAND_SBAND) {
300 case BAND_UHF: value |= 0x4000 | 0x0800; break; 420 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
301 case BAND_LBAND: value |= 0x2000 | 0x0400; break; 421 dib0070_write_reg(state, 0x1d, 0xFFFF);
302 default: value |= 0x8000 | 0x1000; break; 422 } else
303 } 423 dib0070_set_ctrl_lo5(fe, 5, 4, 3, 1);
304 dib0070_write_reg(st, 0x20, value); 424 }
305 425
306 dib0070_captrim(st, lo4); 426 dib0070_write_reg(state, 0x20,
307 if (st->revision == DIB0070S_P1A) { 427 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001 | state->current_tune_table_index->tuner_enable);
308 if (band == BAND_SBAND)
309 dib0070_write_reg(st, 0x15, 0x16e2);
310 else
311 dib0070_write_reg(st, 0x15, 0x56e5);
312 }
313 428
429 dprintk("REFDIV: %hd, FREF: %d", REFDIV, FREF);
430 dprintk("FBDIV: %d, Rest: %d", FBDiv, Rest);
431 dprintk("Num: %hd, Den: %hd, SD: %hd", (u16) Rest, Den, (state->lo4 >> 12) & 0x1);
432 dprintk("HFDIV code: %hd", state->current_tune_table_index->hfdiv);
433 dprintk("VCO = %hd", state->current_tune_table_index->vco_band);
434 dprintk("VCOF: ((%hd*%d) << 1))", state->current_tune_table_index->vco_multi, freq);
314 435
436 *tune_state = CT_TUNER_STEP_0;
437 } else { /* we are already tuned to this frequency - the configuration is correct */
438 ret = 50; /* wakeup time */
439 *tune_state = CT_TUNER_STEP_5;
440 }
441 } else if ((*tune_state > CT_TUNER_START) && (*tune_state < CT_TUNER_STEP_4)) {
442
443 ret = dib0070_captrim(state, tune_state);
444
445 } else if (*tune_state == CT_TUNER_STEP_4) {
446 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
447 if (tmp != NULL) {
448 while (freq / 1000 > tmp->freq) /* find the right one */
449 tmp++;
450 dib0070_write_reg(state, 0x0f,
451 (0 << 15) | (1 << 14) | (3 << 12) | (tmp->wbd_gain_val << 9) | (0 << 8) | (1 << 7) | (state->
452 current_tune_table_index->
453 wbdmux << 0));
454 state->wbd_gain_current = tmp->wbd_gain_val;
455 } else {
456 dib0070_write_reg(state, 0x0f,
457 (0 << 15) | (1 << 14) | (3 << 12) | (6 << 9) | (0 << 8) | (1 << 7) | (state->current_tune_table_index->
458 wbdmux << 0));
459 state->wbd_gain_current = 6;
460 }
315 461
316 switch (band) { 462 dib0070_write_reg(state, 0x06, 0x3fff);
317 case BAND_UHF: value = 0x7c82; break; 463 dib0070_write_reg(state, 0x07,
318 case BAND_LBAND: value = 0x7c84; break; 464 (state->current_tune_table_index->switch_trim << 11) | (7 << 8) | (state->lna_match->lna_band << 3) | (3 << 0));
319 default: value = 0x7c81; break; 465 dib0070_write_reg(state, 0x08, (state->lna_match->lna_band << 10) | (3 << 7) | (127));
320 } 466 dib0070_write_reg(state, 0x0d, 0x0d80);
321 dib0070_write_reg(st, 0x0f, value); 467
322 dib0070_write_reg(st, 0x06, 0x3fff); 468 dib0070_write_reg(state, 0x18, 0x07ff);
323 469 dib0070_write_reg(state, 0x17, 0x0033);
324 /* Front End */ 470
325 /* c == TUNE, value = SWITCH */ 471 *tune_state = CT_TUNER_STEP_5;
326 c = 0; 472 } else if (*tune_state == CT_TUNER_STEP_5) {
327 value = 0; 473 dib0070_set_bandwidth(fe, ch);
328 switch (band) { 474 *tune_state = CT_TUNER_STOP;
329 case BAND_FM: 475 } else {
330 c = 0; value = 1; 476 ret = FE_CALLBACK_TIME_NEVER; /* tuner finished, time to call again infinite */
331 break;
332
333 case BAND_VHF:
334 if (freq <= 180000) c = 0;
335 else if (freq <= 188200) c = 1;
336 else if (freq <= 196400) c = 2;
337 else c = 3;
338 value = 1;
339 break;
340
341 case BAND_LBAND:
342 if (freq <= 1500000) c = 0;
343 else if (freq <= 1600000) c = 1;
344 else c = 3;
345 break;
346
347 case BAND_SBAND:
348 c = 7;
349 dib0070_write_reg(st, 0x1d,0xFFFF);
350 break;
351
352 case BAND_UHF:
353 default:
354 if (st->cfg->flip_chip) {
355 if (freq <= 550000) c = 0;
356 else if (freq <= 590000) c = 1;
357 else if (freq <= 666000) c = 3;
358 else c = 5;
359 } else {
360 if (freq <= 550000) c = 2;
361 else if (freq <= 650000) c = 3;
362 else if (freq <= 750000) c = 5;
363 else if (freq <= 850000) c = 6;
364 else c = 7;
365 }
366 value = 2;
367 break;
368 } 477 }
478 return ret;
479}
369 480
370 /* default: LNA_MATCH=7, BIAS=3 */ 481static int dib0070_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
371 dib0070_write_reg(st, 0x07, (value << 11) | (7 << 8) | (c << 3) | (3 << 0)); 482{
372 dib0070_write_reg(st, 0x08, (c << 10) | (3 << 7) | (127)); 483 struct dib0070_state *state = fe->tuner_priv;
373 dib0070_write_reg(st, 0x0d, 0x0d80); 484 uint32_t ret;
374 485
486 state->tune_state = CT_TUNER_START;
375 487
376 dib0070_write_reg(st, 0x18, 0x07ff); 488 do {
377 dib0070_write_reg(st, 0x17, 0x0033); 489 ret = dib0070_tune_digital(fe, p);
490 if (ret != FE_CALLBACK_TIME_NEVER)
491 msleep(ret / 10);
492 else
493 break;
494 } while (state->tune_state != CT_TUNER_STOP);
378 495
379 return 0; 496 return 0;
380} 497}
381 498
382static int dib0070_wakeup(struct dvb_frontend *fe) 499static int dib0070_wakeup(struct dvb_frontend *fe)
383{ 500{
384 struct dib0070_state *st = fe->tuner_priv; 501 struct dib0070_state *state = fe->tuner_priv;
385 if (st->cfg->sleep) 502 if (state->cfg->sleep)
386 st->cfg->sleep(fe, 0); 503 state->cfg->sleep(fe, 0);
387 return 0; 504 return 0;
388} 505}
389 506
390static int dib0070_sleep(struct dvb_frontend *fe) 507static int dib0070_sleep(struct dvb_frontend *fe)
391{ 508{
392 struct dib0070_state *st = fe->tuner_priv; 509 struct dib0070_state *state = fe->tuner_priv;
393 if (st->cfg->sleep) 510 if (state->cfg->sleep)
394 st->cfg->sleep(fe, 1); 511 state->cfg->sleep(fe, 1);
395 return 0; 512 return 0;
396} 513}
397 514
398static u16 dib0070_p1f_defaults[] = 515static const u16 dib0070_p1f_defaults[] = {
399
400{
401 7, 0x02, 516 7, 0x02,
402 0x0008, 517 0x0008,
403 0x0000, 518 0x0000,
404 0x0000, 519 0x0000,
405 0x0000, 520 0x0000,
406 0x0000, 521 0x0000,
407 0x0002, 522 0x0002,
408 0x0100, 523 0x0100,
409 524
410 3, 0x0d, 525 3, 0x0d,
411 0x0d80, 526 0x0d80,
412 0x0001, 527 0x0001,
413 0x0000, 528 0x0000,
414 529
415 4, 0x11, 530 4, 0x11,
416 0x0000, 531 0x0000,
417 0x0103, 532 0x0103,
418 0x0000, 533 0x0000,
419 0x0000, 534 0x0000,
420 535
421 3, 0x16, 536 3, 0x16,
422 0x0004 | 0x0040, 537 0x0004 | 0x0040,
423 0x0030, 538 0x0030,
424 0x07ff, 539 0x07ff,
425 540
426 6, 0x1b, 541 6, 0x1b,
427 0x4112, 542 0x4112,
428 0xff00, 543 0xff00,
429 0xc07f, 544 0xc07f,
430 0x0000, 545 0x0000,
431 0x0180, 546 0x0180,
432 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001, 547 0x4000 | 0x0800 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001,
433 548
434 0, 549 0,
435}; 550};
436 551
437static void dib0070_wbd_calibration(struct dvb_frontend *fe) 552static u16 dib0070_read_wbd_offset(struct dib0070_state *state, u8 gain)
438{ 553{
439 u16 wbd_offs; 554 u16 tuner_en = dib0070_read_reg(state, 0x20);
440 struct dib0070_state *state = fe->tuner_priv; 555 u16 offset;
441
442 if (state->cfg->sleep)
443 state->cfg->sleep(fe, 0);
444 556
445 dib0070_write_reg(state, 0x0f, 0x6d81); 557 dib0070_write_reg(state, 0x18, 0x07ff);
446 dib0070_write_reg(state, 0x20, 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001); 558 dib0070_write_reg(state, 0x20, 0x0800 | 0x4000 | 0x0040 | 0x0020 | 0x0010 | 0x0008 | 0x0002 | 0x0001);
559 dib0070_write_reg(state, 0x0f, (1 << 14) | (2 << 12) | (gain << 9) | (1 << 8) | (1 << 7) | (0 << 0));
447 msleep(9); 560 msleep(9);
448 wbd_offs = dib0070_read_reg(state, 0x19); 561 offset = dib0070_read_reg(state, 0x19);
449 dib0070_write_reg(state, 0x20, 0); 562 dib0070_write_reg(state, 0x20, tuner_en);
450 state->wbd_ff_offset = ((wbd_offs * 8 * 18 / 33 + 1) / 2); 563 return offset;
451 dprintk( "WBDStart = %d (Vargen) - FF = %hd", (u32) wbd_offs * 1800/1024, state->wbd_ff_offset);
452
453 if (state->cfg->sleep)
454 state->cfg->sleep(fe, 1);
455
456} 564}
457 565
458u16 dib0070_wbd_offset(struct dvb_frontend *fe) 566static void dib0070_wbd_offset_calibration(struct dib0070_state *state)
459{ 567{
460 struct dib0070_state *st = fe->tuner_priv; 568 u8 gain;
461 return st->wbd_ff_offset; 569 for (gain = 6; gain < 8; gain++) {
570 state->wbd_offset_3_3[gain - 6] = ((dib0070_read_wbd_offset(state, gain) * 8 * 18 / 33 + 1) / 2);
571 dprintk("Gain: %d, WBDOffset (3.3V) = %hd", gain, state->wbd_offset_3_3[gain - 6]);
572 }
462} 573}
463 574
464EXPORT_SYMBOL(dib0070_wbd_offset); 575u16 dib0070_wbd_offset(struct dvb_frontend *fe)
465static int dib0070_set_ctrl_lo5(struct dvb_frontend *fe, u8 vco_bias_trim, u8 hf_div_trim, u8 cp_current, u8 third_order_filt)
466{ 576{
467 struct dib0070_state *state = fe->tuner_priv; 577 struct dib0070_state *state = fe->tuner_priv;
468 u16 lo5 = (third_order_filt << 14) | (0 << 13) | (1 << 12) | (3 << 9) | (cp_current << 6) | (hf_div_trim << 3) | (vco_bias_trim << 0); 578 const struct dib0070_wbd_gain_cfg *tmp = state->cfg->wbd_gain;
469 dprintk( "CTRL_LO5: 0x%x", lo5); 579 u32 freq = fe->dtv_property_cache.frequency / 1000;
470 return dib0070_write_reg(state, 0x15, lo5); 580
581 if (tmp != NULL) {
582 while (freq / 1000 > tmp->freq) /* find the right one */
583 tmp++;
584 state->wbd_gain_current = tmp->wbd_gain_val;
585 } else
586 state->wbd_gain_current = 6;
587
588 return state->wbd_offset_3_3[state->wbd_gain_current - 6];
471} 589}
472 590
591EXPORT_SYMBOL(dib0070_wbd_offset);
592
473#define pgm_read_word(w) (*w) 593#define pgm_read_word(w) (*w)
474static int dib0070_reset(struct dib0070_state *state) 594static int dib0070_reset(struct dvb_frontend *fe)
475{ 595{
596 struct dib0070_state *state = fe->tuner_priv;
476 u16 l, r, *n; 597 u16 l, r, *n;
477 598
478 HARD_RESET(state); 599 HARD_RESET(state);
479 600
480
481#ifndef FORCE_SBAND_TUNER 601#ifndef FORCE_SBAND_TUNER
482 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1) 602 if ((dib0070_read_reg(state, 0x22) >> 9) & 0x1)
483 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff; 603 state->revision = (dib0070_read_reg(state, 0x1f) >> 8) & 0xff;
484 else 604 else
605#else
606#warning forcing SBAND
485#endif 607#endif
486 state->revision = DIB0070S_P1A; 608 state->revision = DIB0070S_P1A;
487 609
488 /* P1F or not */ 610 /* P1F or not */
489 dprintk( "Revision: %x", state->revision); 611 dprintk("Revision: %x", state->revision);
490 612
491 if (state->revision == DIB0070_P1D) { 613 if (state->revision == DIB0070_P1D) {
492 dprintk( "Error: this driver is not to be used meant for P1D or earlier"); 614 dprintk("Error: this driver is not to be used meant for P1D or earlier");
493 return -EINVAL; 615 return -EINVAL;
494 } 616 }
495 617
@@ -498,7 +620,7 @@ static int dib0070_reset(struct dib0070_state *state)
498 while (l) { 620 while (l) {
499 r = pgm_read_word(n++); 621 r = pgm_read_word(n++);
500 do { 622 do {
501 dib0070_write_reg(state, (u8)r, pgm_read_word(n++)); 623 dib0070_write_reg(state, (u8) r, pgm_read_word(n++));
502 r++; 624 r++;
503 } while (--l); 625 } while (--l);
504 l = pgm_read_word(n++); 626 l = pgm_read_word(n++);
@@ -514,24 +636,25 @@ static int dib0070_reset(struct dib0070_state *state)
514 r |= state->cfg->osc_buffer_state << 3; 636 r |= state->cfg->osc_buffer_state << 3;
515 637
516 dib0070_write_reg(state, 0x10, r); 638 dib0070_write_reg(state, 0x10, r);
517 dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 4)); 639 dib0070_write_reg(state, 0x1f, (1 << 8) | ((state->cfg->clock_pad_drive & 0xf) << 5));
518 640
519 if (state->cfg->invert_iq) { 641 if (state->cfg->invert_iq) {
520 r = dib0070_read_reg(state, 0x02) & 0xffdf; 642 r = dib0070_read_reg(state, 0x02) & 0xffdf;
521 dib0070_write_reg(state, 0x02, r | (1 << 5)); 643 dib0070_write_reg(state, 0x02, r | (1 << 5));
522 } 644 }
523 645
524
525 if (state->revision == DIB0070S_P1A) 646 if (state->revision == DIB0070S_P1A)
526 dib0070_set_ctrl_lo5(state->fe, 4, 7, 3, 1); 647 dib0070_set_ctrl_lo5(fe, 2, 4, 3, 0);
527 else 648 else
528 dib0070_set_ctrl_lo5(state->fe, 4, 4, 2, 0); 649 dib0070_set_ctrl_lo5(fe, 5, 4, state->cfg->charge_pump, state->cfg->enable_third_order_filter);
529 650
530 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8); 651 dib0070_write_reg(state, 0x01, (54 << 9) | 0xc8);
652
653 dib0070_wbd_offset_calibration(state);
654
531 return 0; 655 return 0;
532} 656}
533 657
534
535static int dib0070_release(struct dvb_frontend *fe) 658static int dib0070_release(struct dvb_frontend *fe)
536{ 659{
537 kfree(fe->tuner_priv); 660 kfree(fe->tuner_priv);
@@ -539,23 +662,24 @@ static int dib0070_release(struct dvb_frontend *fe)
539 return 0; 662 return 0;
540} 663}
541 664
542static struct dvb_tuner_ops dib0070_ops = { 665static const struct dvb_tuner_ops dib0070_ops = {
543 .info = { 666 .info = {
544 .name = "DiBcom DiB0070", 667 .name = "DiBcom DiB0070",
545 .frequency_min = 45000000, 668 .frequency_min = 45000000,
546 .frequency_max = 860000000, 669 .frequency_max = 860000000,
547 .frequency_step = 1000, 670 .frequency_step = 1000,
548 }, 671 },
549 .release = dib0070_release, 672 .release = dib0070_release,
550 673
551 .init = dib0070_wakeup, 674 .init = dib0070_wakeup,
552 .sleep = dib0070_sleep, 675 .sleep = dib0070_sleep,
553 .set_params = dib0070_tune_digital, 676 .set_params = dib0070_tune,
554// .get_frequency = dib0070_get_frequency, 677
555// .get_bandwidth = dib0070_get_bandwidth 678// .get_frequency = dib0070_get_frequency,
679// .get_bandwidth = dib0070_get_bandwidth
556}; 680};
557 681
558struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg) 682struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
559{ 683{
560 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL); 684 struct dib0070_state *state = kzalloc(sizeof(struct dib0070_state), GFP_KERNEL);
561 if (state == NULL) 685 if (state == NULL)
@@ -563,25 +687,24 @@ struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter
563 687
564 state->cfg = cfg; 688 state->cfg = cfg;
565 state->i2c = i2c; 689 state->i2c = i2c;
566 state->fe = fe; 690 state->fe = fe;
567 fe->tuner_priv = state; 691 fe->tuner_priv = state;
568 692
569 if (dib0070_reset(state) != 0) 693 if (dib0070_reset(fe) != 0)
570 goto free_mem; 694 goto free_mem;
571 695
572 dib0070_wbd_calibration(fe);
573
574 printk(KERN_INFO "DiB0070: successfully identified\n"); 696 printk(KERN_INFO "DiB0070: successfully identified\n");
575 memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops)); 697 memcpy(&fe->ops.tuner_ops, &dib0070_ops, sizeof(struct dvb_tuner_ops));
576 698
577 fe->tuner_priv = state; 699 fe->tuner_priv = state;
578 return fe; 700 return fe;
579 701
580free_mem: 702 free_mem:
581 kfree(state); 703 kfree(state);
582 fe->tuner_priv = NULL; 704 fe->tuner_priv = NULL;
583 return NULL; 705 return NULL;
584} 706}
707
585EXPORT_SYMBOL(dib0070_attach); 708EXPORT_SYMBOL(dib0070_attach);
586 709
587MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 710MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb/frontends/dib0070.h b/drivers/media/dvb/frontends/dib0070.h
index 9670f5d20cfb..8a2e1e710adb 100644
--- a/drivers/media/dvb/frontends/dib0070.h
+++ b/drivers/media/dvb/frontends/dib0070.h
@@ -15,6 +15,11 @@ struct i2c_adapter;
15 15
16#define DEFAULT_DIB0070_I2C_ADDRESS 0x60 16#define DEFAULT_DIB0070_I2C_ADDRESS 0x60
17 17
18struct dib0070_wbd_gain_cfg {
19 u16 freq;
20 u16 wbd_gain_val;
21};
22
18struct dib0070_config { 23struct dib0070_config {
19 u8 i2c_address; 24 u8 i2c_address;
20 25
@@ -26,26 +31,28 @@ struct dib0070_config {
26 int freq_offset_khz_uhf; 31 int freq_offset_khz_uhf;
27 int freq_offset_khz_vhf; 32 int freq_offset_khz_vhf;
28 33
29 u8 osc_buffer_state; /* 0= normal, 1= tri-state */ 34 u8 osc_buffer_state; /* 0= normal, 1= tri-state */
30 u32 clock_khz; 35 u32 clock_khz;
31 u8 clock_pad_drive; /* (Drive + 1) * 2mA */ 36 u8 clock_pad_drive; /* (Drive + 1) * 2mA */
32 37
33 u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */ 38 u8 invert_iq; /* invert Q - in case I or Q is inverted on the board */
34 39
35 u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */ 40 u8 force_crystal_mode; /* if == 0 -> decision is made in the driver default: <24 -> 2, >=24 -> 1 */
36 41
37 u8 flip_chip; 42 u8 flip_chip;
43 u8 enable_third_order_filter;
44 u8 charge_pump;
45
46 const struct dib0070_wbd_gain_cfg *wbd_gain;
47
48 u8 vga_filter;
38}; 49};
39 50
40#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE)) 51#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
41extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 52extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
42 struct i2c_adapter *i2c,
43 struct dib0070_config *cfg);
44extern u16 dib0070_wbd_offset(struct dvb_frontend *); 53extern u16 dib0070_wbd_offset(struct dvb_frontend *);
45#else 54#else
46static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, 55static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg)
47 struct i2c_adapter *i2c,
48 struct dib0070_config *cfg)
49{ 56{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 57 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL; 58 return NULL;
@@ -57,5 +64,6 @@ static inline u16 dib0070_wbd_offset(struct dvb_frontend *fe)
57 return -ENODEV; 64 return -ENODEV;
58} 65}
59#endif 66#endif
67extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, u8 open);
60 68
61#endif 69#endif
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index fc96fbf03d6d..55ef6eeb0769 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -10,6 +10,7 @@
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/i2c.h> 11#include <linux/i2c.h>
12 12
13#include "dvb_math.h"
13#include "dvb_frontend.h" 14#include "dvb_frontend.h"
14 15
15#include "dib7000p.h" 16#include "dib7000p.h"
@@ -1217,7 +1218,37 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1217 1218
1218static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr) 1219static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1219{ 1220{
1220 *snr = 0x0000; 1221 struct dib7000p_state *state = fe->demodulator_priv;
1222 u16 val;
1223 s32 signal_mant, signal_exp, noise_mant, noise_exp;
1224 u32 result = 0;
1225
1226 val = dib7000p_read_word(state, 479);
1227 noise_mant = (val >> 4) & 0xff;
1228 noise_exp = ((val & 0xf) << 2);
1229 val = dib7000p_read_word(state, 480);
1230 noise_exp += ((val >> 14) & 0x3);
1231 if ((noise_exp & 0x20) != 0)
1232 noise_exp -= 0x40;
1233
1234 signal_mant = (val >> 6) & 0xFF;
1235 signal_exp = (val & 0x3F);
1236 if ((signal_exp & 0x20) != 0)
1237 signal_exp -= 0x40;
1238
1239 if (signal_mant != 0)
1240 result = intlog10(2) * 10 * signal_exp + 10 *
1241 intlog10(signal_mant);
1242 else
1243 result = intlog10(2) * 10 * signal_exp - 100;
1244
1245 if (noise_mant != 0)
1246 result -= intlog10(2) * 10 * noise_exp + 10 *
1247 intlog10(noise_mant);
1248 else
1249 result -= intlog10(2) * 10 * noise_exp - 100;
1250
1251 *snr = result / ((1 << 24) / 10);
1221 return 0; 1252 return 0;
1222} 1253}
1223 1254
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
new file mode 100644
index 000000000000..852c790d09d9
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -0,0 +1,2277 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB8000 chip (ISDB-T).
3 *
4 * Copyright (C) 2009 DiBcom (http://www.dibcom.fr/)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 */
10#include <linux/kernel.h>
11#include <linux/i2c.h>
12#include "dvb_math.h"
13
14#include "dvb_frontend.h"
15
16#include "dib8000.h"
17
18#define LAYER_ALL -1
19#define LAYER_A 1
20#define LAYER_B 2
21#define LAYER_C 3
22
23#define FE_CALLBACK_TIME_NEVER 0xffffffff
24
25static int debug;
26module_param(debug, int, 0644);
27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
28
29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB8000: "); printk(args); printk("\n"); } } while (0)
30
31enum frontend_tune_state {
32 CT_AGC_START = 20,
33 CT_AGC_STEP_0,
34 CT_AGC_STEP_1,
35 CT_AGC_STEP_2,
36 CT_AGC_STEP_3,
37 CT_AGC_STEP_4,
38 CT_AGC_STOP,
39
40 CT_DEMOD_START = 30,
41};
42
43#define FE_STATUS_TUNE_FAILED 0
44
45struct i2c_device {
46 struct i2c_adapter *adap;
47 u8 addr;
48};
49
50struct dib8000_state {
51 struct dvb_frontend fe;
52 struct dib8000_config cfg;
53
54 struct i2c_device i2c;
55
56 struct dibx000_i2c_master i2c_master;
57
58 u16 wbd_ref;
59
60 u8 current_band;
61 u32 current_bandwidth;
62 struct dibx000_agc_config *current_agc;
63 u32 timf;
64 u32 timf_default;
65
66 u8 div_force_off:1;
67 u8 div_state:1;
68 u16 div_sync_wait;
69
70 u8 agc_state;
71 u8 differential_constellation;
72 u8 diversity_onoff;
73
74 s16 ber_monitored_layer;
75 u16 gpio_dir;
76 u16 gpio_val;
77
78 u16 revision;
79 u8 isdbt_cfg_loaded;
80 enum frontend_tune_state tune_state;
81 u32 status;
82};
83
84enum dib8000_power_mode {
85 DIB8000M_POWER_ALL = 0,
86 DIB8000M_POWER_INTERFACE_ONLY,
87};
88
89static u16 dib8000_i2c_read16(struct i2c_device *i2c, u16 reg)
90{
91 u8 wb[2] = { reg >> 8, reg & 0xff };
92 u8 rb[2];
93 struct i2c_msg msg[2] = {
94 {.addr = i2c->addr >> 1,.flags = 0,.buf = wb,.len = 2},
95 {.addr = i2c->addr >> 1,.flags = I2C_M_RD,.buf = rb,.len = 2},
96 };
97
98 if (i2c_transfer(i2c->adap, msg, 2) != 2)
99 dprintk("i2c read error on %d", reg);
100
101 return (rb[0] << 8) | rb[1];
102}
103
104static u16 dib8000_read_word(struct dib8000_state *state, u16 reg)
105{
106 return dib8000_i2c_read16(&state->i2c, reg);
107}
108
109static u32 dib8000_read32(struct dib8000_state *state, u16 reg)
110{
111 u16 rw[2];
112
113 rw[0] = dib8000_read_word(state, reg + 0);
114 rw[1] = dib8000_read_word(state, reg + 1);
115
116 return ((rw[0] << 16) | (rw[1]));
117}
118
119static int dib8000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
120{
121 u8 b[4] = {
122 (reg >> 8) & 0xff, reg & 0xff,
123 (val >> 8) & 0xff, val & 0xff,
124 };
125 struct i2c_msg msg = {
126 .addr = i2c->addr >> 1,.flags = 0,.buf = b,.len = 4
127 };
128 return i2c_transfer(i2c->adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
129}
130
131static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
132{
133 return dib8000_i2c_write16(&state->i2c, reg, val);
134}
135
136const int16_t coeff_2k_sb_1seg_dqpsk[8] = {
137 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
138 (920 << 5) | 0x09
139};
140
141const int16_t coeff_2k_sb_1seg[8] = {
142 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
143};
144
145const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
146 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
147 (-931 << 5) | 0x0f
148};
149
150const int16_t coeff_2k_sb_3seg_0dqpsk[8] = {
151 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
152 (982 << 5) | 0x0c
153};
154
155const int16_t coeff_2k_sb_3seg_1dqpsk[8] = {
156 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
157 (-720 << 5) | 0x0d
158};
159
160const int16_t coeff_2k_sb_3seg[8] = {
161 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
162 (-610 << 5) | 0x0a
163};
164
165const int16_t coeff_4k_sb_1seg_dqpsk[8] = {
166 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
167 (-922 << 5) | 0x0d
168};
169
170const int16_t coeff_4k_sb_1seg[8] = {
171 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
172 (-655 << 5) | 0x0a
173};
174
175const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
176 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
177 (-958 << 5) | 0x13
178};
179
180const int16_t coeff_4k_sb_3seg_0dqpsk[8] = {
181 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
182 (-568 << 5) | 0x0f
183};
184
185const int16_t coeff_4k_sb_3seg_1dqpsk[8] = {
186 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
187 (-848 << 5) | 0x13
188};
189
190const int16_t coeff_4k_sb_3seg[8] = {
191 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
192 (-869 << 5) | 0x13
193};
194
195const int16_t coeff_8k_sb_1seg_dqpsk[8] = {
196 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
197 (-598 << 5) | 0x10
198};
199
200const int16_t coeff_8k_sb_1seg[8] = {
201 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
202 (585 << 5) | 0x0f
203};
204
205const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
206 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
207 (0 << 5) | 0x14
208};
209
210const int16_t coeff_8k_sb_3seg_0dqpsk[8] = {
211 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
212 (-877 << 5) | 0x15
213};
214
215const int16_t coeff_8k_sb_3seg_1dqpsk[8] = {
216 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
217 (-921 << 5) | 0x14
218};
219
220const int16_t coeff_8k_sb_3seg[8] = {
221 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
222 (690 << 5) | 0x14
223};
224
225const int16_t ana_fe_coeff_3seg[24] = {
226 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
227};
228
229const int16_t ana_fe_coeff_1seg[24] = {
230 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
231};
232
233const int16_t ana_fe_coeff_13seg[24] = {
234 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
235};
236
237static u16 fft_to_mode(struct dib8000_state *state)
238{
239 u16 mode;
240 switch (state->fe.dtv_property_cache.transmission_mode) {
241 case TRANSMISSION_MODE_2K:
242 mode = 1;
243 break;
244 case TRANSMISSION_MODE_4K:
245 mode = 2;
246 break;
247 default:
248 case TRANSMISSION_MODE_AUTO:
249 case TRANSMISSION_MODE_8K:
250 mode = 3;
251 break;
252 }
253 return mode;
254}
255
256static void dib8000_set_acquisition_mode(struct dib8000_state *state)
257{
258 u16 nud = dib8000_read_word(state, 298);
259 nud |= (1 << 3) | (1 << 0);
260 dprintk("acquisition mode activated");
261 dib8000_write_word(state, 298, nud);
262}
263
264static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
265{
266 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
267
268 outreg = 0;
269 fifo_threshold = 1792;
270 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
271
272 dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode);
273
274 switch (mode) {
275 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
276 outreg = (1 << 10); /* 0x0400 */
277 break;
278 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
279 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
280 break;
281 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
282 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
283 break;
284 case OUTMODE_DIVERSITY:
285 if (state->cfg.hostbus_diversity) {
286 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
287 sram &= 0xfdff;
288 } else
289 sram |= 0x0c00;
290 break;
291 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
292 smo_mode |= (3 << 1);
293 fifo_threshold = 512;
294 outreg = (1 << 10) | (5 << 6);
295 break;
296 case OUTMODE_HIGH_Z: // disable
297 outreg = 0;
298 break;
299
300 case OUTMODE_ANALOG_ADC:
301 outreg = (1 << 10) | (3 << 6);
302 dib8000_set_acquisition_mode(state);
303 break;
304
305 default:
306 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe);
307 return -EINVAL;
308 }
309
310 if (state->cfg.output_mpeg2_in_188_bytes)
311 smo_mode |= (1 << 5);
312
313 dib8000_write_word(state, 299, smo_mode);
314 dib8000_write_word(state, 300, fifo_threshold); /* synchronous fread */
315 dib8000_write_word(state, 1286, outreg);
316 dib8000_write_word(state, 1291, sram);
317
318 return 0;
319}
320
321static int dib8000_set_diversity_in(struct dvb_frontend *fe, int onoff)
322{
323 struct dib8000_state *state = fe->demodulator_priv;
324 u16 sync_wait = dib8000_read_word(state, 273) & 0xfff0;
325
326 if (!state->differential_constellation) {
327 dib8000_write_word(state, 272, 1 << 9); //dvsy_off_lmod4 = 1
328 dib8000_write_word(state, 273, sync_wait | (1 << 2) | 2); // sync_enable = 1; comb_mode = 2
329 } else {
330 dib8000_write_word(state, 272, 0); //dvsy_off_lmod4 = 0
331 dib8000_write_word(state, 273, sync_wait); // sync_enable = 0; comb_mode = 0
332 }
333 state->diversity_onoff = onoff;
334
335 switch (onoff) {
336 case 0: /* only use the internal way - not the diversity input */
337 dib8000_write_word(state, 270, 1);
338 dib8000_write_word(state, 271, 0);
339 break;
340 case 1: /* both ways */
341 dib8000_write_word(state, 270, 6);
342 dib8000_write_word(state, 271, 6);
343 break;
344 case 2: /* only the diversity input */
345 dib8000_write_word(state, 270, 0);
346 dib8000_write_word(state, 271, 1);
347 break;
348 }
349 return 0;
350}
351
352static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_power_mode mode)
353{
354 /* by default everything is going to be powered off */
355 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
356 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
357
358 /* now, depending on the requested mode, we power on */
359 switch (mode) {
360 /* power up everything in the demod */
361 case DIB8000M_POWER_ALL:
362 reg_774 = 0x0000;
363 reg_775 = 0x0000;
364 reg_776 = 0x0000;
365 reg_900 &= 0xfffc;
366 reg_1280 &= 0x00ff;
367 break;
368 case DIB8000M_POWER_INTERFACE_ONLY:
369 reg_1280 &= 0x00ff;
370 break;
371 }
372
373 dprintk("powermode : 774 : %x ; 775 : %x; 776 : %x ; 900 : %x; 1280 : %x", reg_774, reg_775, reg_776, reg_900, reg_1280);
374 dib8000_write_word(state, 774, reg_774);
375 dib8000_write_word(state, 775, reg_775);
376 dib8000_write_word(state, 776, reg_776);
377 dib8000_write_word(state, 900, reg_900);
378 dib8000_write_word(state, 1280, reg_1280);
379}
380
381static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_states no)
382{
383 int ret = 0;
384 u16 reg_907 = dib8000_read_word(state, 907), reg_908 = dib8000_read_word(state, 908);
385
386 switch (no) {
387 case DIBX000_SLOW_ADC_ON:
388 reg_908 |= (1 << 1) | (1 << 0);
389 ret |= dib8000_write_word(state, 908, reg_908);
390 reg_908 &= ~(1 << 1);
391 break;
392
393 case DIBX000_SLOW_ADC_OFF:
394 reg_908 |= (1 << 1) | (1 << 0);
395 break;
396
397 case DIBX000_ADC_ON:
398 reg_907 &= 0x0fff;
399 reg_908 &= 0x0003;
400 break;
401
402 case DIBX000_ADC_OFF: // leave the VBG voltage on
403 reg_907 |= (1 << 14) | (1 << 13) | (1 << 12);
404 reg_908 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
405 break;
406
407 case DIBX000_VBG_ENABLE:
408 reg_907 &= ~(1 << 15);
409 break;
410
411 case DIBX000_VBG_DISABLE:
412 reg_907 |= (1 << 15);
413 break;
414
415 default:
416 break;
417 }
418
419 ret |= dib8000_write_word(state, 907, reg_907);
420 ret |= dib8000_write_word(state, 908, reg_908);
421
422 return ret;
423}
424
425static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw)
426{
427 u32 timf;
428
429 if (bw == 0)
430 bw = 6000;
431
432 if (state->timf == 0) {
433 dprintk("using default timf");
434 timf = state->timf_default;
435 } else {
436 dprintk("using updated timf");
437 timf = state->timf;
438 }
439
440 dib8000_write_word(state, 29, (u16) ((timf >> 16) & 0xffff));
441 dib8000_write_word(state, 30, (u16) ((timf) & 0xffff));
442
443 return 0;
444}
445
446static int dib8000_sad_calib(struct dib8000_state *state)
447{
448/* internal */
449 dib8000_write_word(state, 923, (0 << 1) | (0 << 0));
450 dib8000_write_word(state, 924, 776); // 0.625*3.3 / 4096
451
452 /* do the calibration */
453 dib8000_write_word(state, 923, (1 << 0));
454 dib8000_write_word(state, 923, (0 << 0));
455
456 msleep(1);
457 return 0;
458}
459
460int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
461{
462 struct dib8000_state *state = fe->demodulator_priv;
463 if (value > 4095)
464 value = 4095;
465 state->wbd_ref = value;
466 return dib8000_write_word(state, 106, value);
467}
468
469EXPORT_SYMBOL(dib8000_set_wbd_ref);
470static void dib8000_reset_pll_common(struct dib8000_state *state, const struct dibx000_bandwidth_config *bw)
471{
472 dprintk("ifreq: %d %x, inversion: %d", bw->ifreq, bw->ifreq, bw->ifreq >> 25);
473 dib8000_write_word(state, 23, (u16) (((bw->internal * 1000) >> 16) & 0xffff)); /* P_sec_len */
474 dib8000_write_word(state, 24, (u16) ((bw->internal * 1000) & 0xffff));
475 dib8000_write_word(state, 27, (u16) ((bw->ifreq >> 16) & 0x01ff));
476 dib8000_write_word(state, 28, (u16) (bw->ifreq & 0xffff));
477 dib8000_write_word(state, 26, (u16) ((bw->ifreq >> 25) & 0x0003));
478
479 dib8000_write_word(state, 922, bw->sad_cfg);
480}
481
482static void dib8000_reset_pll(struct dib8000_state *state)
483{
484 const struct dibx000_bandwidth_config *pll = state->cfg.pll;
485 u16 clk_cfg1;
486
487 // clk_cfg0
488 dib8000_write_word(state, 901, (pll->pll_prediv << 8) | (pll->pll_ratio << 0));
489
490 // clk_cfg1
491 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
492 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0);
493
494 dib8000_write_word(state, 902, clk_cfg1);
495 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
496 dib8000_write_word(state, 902, clk_cfg1);
497
498 dprintk("clk_cfg1: 0x%04x", clk_cfg1); /* 0x507 1 0 1 000 0 0 11 1 */
499
500 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
501 if (state->cfg.pll->ADClkSrc == 0)
502 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
503 else if (state->cfg.refclksel != 0)
504 dib8000_write_word(state, 904,
505 (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll->
506 ADClkSrc << 7) | (0 << 1));
507 else
508 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
509
510 dib8000_reset_pll_common(state, pll);
511}
512
513static int dib8000_reset_gpio(struct dib8000_state *st)
514{
515 /* reset the GPIOs */
516 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
517 dib8000_write_word(st, 1030, st->cfg.gpio_val);
518
519 /* TODO 782 is P_gpio_od */
520
521 dib8000_write_word(st, 1032, st->cfg.gpio_pwm_pos);
522
523 dib8000_write_word(st, 1037, st->cfg.pwm_freq_div);
524 return 0;
525}
526
527static int dib8000_cfg_gpio(struct dib8000_state *st, u8 num, u8 dir, u8 val)
528{
529 st->cfg.gpio_dir = dib8000_read_word(st, 1029);
530 st->cfg.gpio_dir &= ~(1 << num); /* reset the direction bit */
531 st->cfg.gpio_dir |= (dir & 0x1) << num; /* set the new direction */
532 dib8000_write_word(st, 1029, st->cfg.gpio_dir);
533
534 st->cfg.gpio_val = dib8000_read_word(st, 1030);
535 st->cfg.gpio_val &= ~(1 << num); /* reset the direction bit */
536 st->cfg.gpio_val |= (val & 0x01) << num; /* set the new value */
537 dib8000_write_word(st, 1030, st->cfg.gpio_val);
538
539 dprintk("gpio dir: %x: gpio val: %x", st->cfg.gpio_dir, st->cfg.gpio_val);
540
541 return 0;
542}
543
544int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
545{
546 struct dib8000_state *state = fe->demodulator_priv;
547 return dib8000_cfg_gpio(state, num, dir, val);
548}
549
550EXPORT_SYMBOL(dib8000_set_gpio);
551static const u16 dib8000_defaults[] = {
552 /* auto search configuration - lock0 by default waiting
553 * for cpil_lock; lock1 cpil_lock; lock2 tmcc_sync_lock */
554 3, 7,
555 0x0004,
556 0x0400,
557 0x0814,
558
559 12, 11,
560 0x001b,
561 0x7740,
562 0x005b,
563 0x8d80,
564 0x01c9,
565 0xc380,
566 0x0000,
567 0x0080,
568 0x0000,
569 0x0090,
570 0x0001,
571 0xd4c0,
572
573 /*1, 32,
574 0x6680 // P_corm_thres Lock algorithms configuration */
575
576 11, 80, /* set ADC level to -16 */
577 (1 << 13) - 825 - 117,
578 (1 << 13) - 837 - 117,
579 (1 << 13) - 811 - 117,
580 (1 << 13) - 766 - 117,
581 (1 << 13) - 737 - 117,
582 (1 << 13) - 693 - 117,
583 (1 << 13) - 648 - 117,
584 (1 << 13) - 619 - 117,
585 (1 << 13) - 575 - 117,
586 (1 << 13) - 531 - 117,
587 (1 << 13) - 501 - 117,
588
589 4, 108,
590 0,
591 0,
592 0,
593 0,
594
595 1, 175,
596 0x0410,
597 1, 179,
598 8192, // P_fft_nb_to_cut
599
600 6, 181,
601 0x2800, // P_coff_corthres_ ( 2k 4k 8k ) 0x2800
602 0x2800,
603 0x2800,
604 0x2800, // P_coff_cpilthres_ ( 2k 4k 8k ) 0x2800
605 0x2800,
606 0x2800,
607
608 2, 193,
609 0x0666, // P_pha3_thres
610 0x0000, // P_cti_use_cpe, P_cti_use_prog
611
612 2, 205,
613 0x200f, // P_cspu_regul, P_cspu_win_cut
614 0x000f, // P_des_shift_work
615
616 5, 215,
617 0x023d, // P_adp_regul_cnt
618 0x00a4, // P_adp_noise_cnt
619 0x00a4, // P_adp_regul_ext
620 0x7ff0, // P_adp_noise_ext
621 0x3ccc, // P_adp_fil
622
623 1, 230,
624 0x0000, // P_2d_byp_ti_num
625
626 1, 263,
627 0x800, //P_equal_thres_wgn
628
629 1, 268,
630 (2 << 9) | 39, // P_equal_ctrl_synchro, P_equal_speedmode
631
632 1, 270,
633 0x0001, // P_div_lock0_wait
634 1, 285,
635 0x0020, //p_fec_
636 1, 299,
637 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard
638
639 1, 338,
640 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
641 (1 << 10) | // P_ctrl_pre_freq_mode_sat=1
642 (0 << 9) | // P_ctrl_pre_freq_inh=0
643 (3 << 5) | // P_ctrl_pre_freq_step=3
644 (1 << 0), // P_pre_freq_win_len=1
645
646 1, 903,
647 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
648
649 0,
650};
651
652static u16 dib8000_identify(struct i2c_device *client)
653{
654 u16 value;
655
656 //because of glitches sometimes
657 value = dib8000_i2c_read16(client, 896);
658
659 if ((value = dib8000_i2c_read16(client, 896)) != 0x01b3) {
660 dprintk("wrong Vendor ID (read=0x%x)", value);
661 return 0;
662 }
663
664 value = dib8000_i2c_read16(client, 897);
665 if (value != 0x8000 && value != 0x8001 && value != 0x8002) {
666 dprintk("wrong Device ID (%x)", value);
667 return 0;
668 }
669
670 switch (value) {
671 case 0x8000:
672 dprintk("found DiB8000A");
673 break;
674 case 0x8001:
675 dprintk("found DiB8000B");
676 break;
677 case 0x8002:
678 dprintk("found DiB8000C");
679 break;
680 }
681 return value;
682}
683
684static int dib8000_reset(struct dvb_frontend *fe)
685{
686 struct dib8000_state *state = fe->demodulator_priv;
687
688 dib8000_write_word(state, 1287, 0x0003); /* sram lead in, rdy */
689
690 if ((state->revision = dib8000_identify(&state->i2c)) == 0)
691 return -EINVAL;
692
693 if (state->revision == 0x8000)
694 dprintk("error : dib8000 MA not supported");
695
696 dibx000_reset_i2c_master(&state->i2c_master);
697
698 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
699
700 /* always leave the VBG voltage on - it consumes almost nothing but takes a long time to start */
701 dib8000_set_adc_state(state, DIBX000_VBG_ENABLE);
702
703 /* restart all parts */
704 dib8000_write_word(state, 770, 0xffff);
705 dib8000_write_word(state, 771, 0xffff);
706 dib8000_write_word(state, 772, 0xfffc);
707 dib8000_write_word(state, 898, 0x000c); // sad
708 dib8000_write_word(state, 1280, 0x004d);
709 dib8000_write_word(state, 1281, 0x000c);
710
711 dib8000_write_word(state, 770, 0x0000);
712 dib8000_write_word(state, 771, 0x0000);
713 dib8000_write_word(state, 772, 0x0000);
714 dib8000_write_word(state, 898, 0x0004); // sad
715 dib8000_write_word(state, 1280, 0x0000);
716 dib8000_write_word(state, 1281, 0x0000);
717
718 /* drives */
719 if (state->cfg.drives)
720 dib8000_write_word(state, 906, state->cfg.drives);
721 else {
722 dprintk("using standard PAD-drive-settings, please adjust settings in config-struct to be optimal.");
723 dib8000_write_word(state, 906, 0x2d98); // min drive SDRAM - not optimal - adjust
724 }
725
726 dib8000_reset_pll(state);
727
728 if (dib8000_reset_gpio(state) != 0)
729 dprintk("GPIO reset was not successful.");
730
731 if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
732 dprintk("OUTPUT_MODE could not be resetted.");
733
734 state->current_agc = NULL;
735
736 // P_iqc_alpha_pha, P_iqc_alpha_amp, P_iqc_dcc_alpha, ...
737 /* P_iqc_ca2 = 0; P_iqc_impnc_on = 0; P_iqc_mode = 0; */
738 if (state->cfg.pll->ifreq == 0)
739 dib8000_write_word(state, 40, 0x0755); /* P_iqc_corr_inh = 0 enable IQcorr block */
740 else
741 dib8000_write_word(state, 40, 0x1f55); /* P_iqc_corr_inh = 1 disable IQcorr block */
742
743 {
744 u16 l = 0, r;
745 const u16 *n;
746 n = dib8000_defaults;
747 l = *n++;
748 while (l) {
749 r = *n++;
750 do {
751 dib8000_write_word(state, r, *n++);
752 r++;
753 } while (--l);
754 l = *n++;
755 }
756 }
757 state->isdbt_cfg_loaded = 0;
758
759 //div_cfg override for special configs
760 if (state->cfg.div_cfg != 0)
761 dib8000_write_word(state, 903, state->cfg.div_cfg);
762
763 /* unforce divstr regardless whether i2c enumeration was done or not */
764 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
765
766 dib8000_set_bandwidth(state, 6000);
767
768 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
769 dib8000_sad_calib(state);
770 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
771
772 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
773
774 return 0;
775}
776
777static void dib8000_restart_agc(struct dib8000_state *state)
778{
779 // P_restart_iqc & P_restart_agc
780 dib8000_write_word(state, 770, 0x0a00);
781 dib8000_write_word(state, 770, 0x0000);
782}
783
784static int dib8000_update_lna(struct dib8000_state *state)
785{
786 u16 dyn_gain;
787
788 if (state->cfg.update_lna) {
789 // read dyn_gain here (because it is demod-dependent and not tuner)
790 dyn_gain = dib8000_read_word(state, 390);
791
792 if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed
793 dib8000_restart_agc(state);
794 return 1;
795 }
796 }
797 return 0;
798}
799
800static int dib8000_set_agc_config(struct dib8000_state *state, u8 band)
801{
802 struct dibx000_agc_config *agc = NULL;
803 int i;
804 if (state->current_band == band && state->current_agc != NULL)
805 return 0;
806 state->current_band = band;
807
808 for (i = 0; i < state->cfg.agc_config_count; i++)
809 if (state->cfg.agc[i].band_caps & band) {
810 agc = &state->cfg.agc[i];
811 break;
812 }
813
814 if (agc == NULL) {
815 dprintk("no valid AGC configuration found for band 0x%02x", band);
816 return -EINVAL;
817 }
818
819 state->current_agc = agc;
820
821 /* AGC */
822 dib8000_write_word(state, 76, agc->setup);
823 dib8000_write_word(state, 77, agc->inv_gain);
824 dib8000_write_word(state, 78, agc->time_stabiliz);
825 dib8000_write_word(state, 101, (agc->alpha_level << 12) | agc->thlock);
826
827 // Demod AGC loop configuration
828 dib8000_write_word(state, 102, (agc->alpha_mant << 5) | agc->alpha_exp);
829 dib8000_write_word(state, 103, (agc->beta_mant << 6) | agc->beta_exp);
830
831 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
832 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
833
834 /* AGC continued */
835 if (state->wbd_ref != 0)
836 dib8000_write_word(state, 106, state->wbd_ref);
837 else // use default
838 dib8000_write_word(state, 106, agc->wbd_ref);
839 dib8000_write_word(state, 107, (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
840 dib8000_write_word(state, 108, agc->agc1_max);
841 dib8000_write_word(state, 109, agc->agc1_min);
842 dib8000_write_word(state, 110, agc->agc2_max);
843 dib8000_write_word(state, 111, agc->agc2_min);
844 dib8000_write_word(state, 112, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
845 dib8000_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
846 dib8000_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
847 dib8000_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
848
849 dib8000_write_word(state, 75, agc->agc1_pt3);
850 dib8000_write_word(state, 923, (dib8000_read_word(state, 923) & 0xffe3) | (agc->wbd_inv << 4) | (agc->wbd_sel << 2)); /*LB : 929 -> 923 */
851
852 return 0;
853}
854
855static int dib8000_agc_soft_split(struct dib8000_state *state)
856{
857 u16 agc, split_offset;
858
859 if (!state->current_agc || !state->current_agc->perform_agc_softsplit || state->current_agc->split.max == 0)
860 return FE_CALLBACK_TIME_NEVER;
861
862 // n_agc_global
863 agc = dib8000_read_word(state, 390);
864
865 if (agc > state->current_agc->split.min_thres)
866 split_offset = state->current_agc->split.min;
867 else if (agc < state->current_agc->split.max_thres)
868 split_offset = state->current_agc->split.max;
869 else
870 split_offset = state->current_agc->split.max *
871 (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
872
873 dprintk("AGC split_offset: %d", split_offset);
874
875 // P_agc_force_split and P_agc_split_offset
876 dib8000_write_word(state, 107, (dib8000_read_word(state, 107) & 0xff00) | split_offset);
877 return 5000;
878}
879
880static int dib8000_agc_startup(struct dvb_frontend *fe)
881{
882 struct dib8000_state *state = fe->demodulator_priv;
883 enum frontend_tune_state *tune_state = &state->tune_state;
884
885 int ret = 0;
886
887 switch (*tune_state) {
888 case CT_AGC_START:
889 // set power-up level: interf+analog+AGC
890
891 dib8000_set_adc_state(state, DIBX000_ADC_ON);
892
893 if (dib8000_set_agc_config(state, (unsigned char)(BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000))) != 0) {
894 *tune_state = CT_AGC_STOP;
895 state->status = FE_STATUS_TUNE_FAILED;
896 break;
897 }
898
899 ret = 70;
900 *tune_state = CT_AGC_STEP_0;
901 break;
902
903 case CT_AGC_STEP_0:
904 //AGC initialization
905 if (state->cfg.agc_control)
906 state->cfg.agc_control(&state->fe, 1);
907
908 dib8000_restart_agc(state);
909
910 // wait AGC rough lock time
911 ret = 50;
912 *tune_state = CT_AGC_STEP_1;
913 break;
914
915 case CT_AGC_STEP_1:
916 // wait AGC accurate lock time
917 ret = 70;
918
919 if (dib8000_update_lna(state))
920 // wait only AGC rough lock time
921 ret = 50;
922 else
923 *tune_state = CT_AGC_STEP_2;
924 break;
925
926 case CT_AGC_STEP_2:
927 dib8000_agc_soft_split(state);
928
929 if (state->cfg.agc_control)
930 state->cfg.agc_control(&state->fe, 0);
931
932 *tune_state = CT_AGC_STOP;
933 break;
934 default:
935 ret = dib8000_agc_soft_split(state);
936 break;
937 }
938 return ret;
939
940}
941
942static void dib8000_update_timf(struct dib8000_state *state)
943{
944 u32 timf = state->timf = dib8000_read32(state, 435);
945
946 dib8000_write_word(state, 29, (u16) (timf >> 16));
947 dib8000_write_word(state, 30, (u16) (timf & 0xffff));
948 dprintk("Updated timing frequency: %d (default: %d)", state->timf, state->timf_default);
949}
950
951static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosearching)
952{
953 u16 mode, max_constellation, seg_diff_mask = 0, nbseg_diff = 0;
954 u8 guard, crate, constellation, timeI;
955 u8 permu_seg[] = { 6, 5, 7, 4, 8, 3, 9, 2, 10, 1, 11, 0, 12 };
956 u16 i, coeff[4], P_cfr_left_edge = 0, P_cfr_right_edge = 0, seg_mask13 = 0x1fff; // All 13 segments enabled
957 const s16 *ncoeff, *ana_fe;
958 u16 tmcc_pow = 0;
959 u16 coff_pow = 0x2800;
960 u16 init_prbs = 0xfff;
961 u16 ana_gain = 0;
962 u16 adc_target_16dB[11] = {
963 (1 << 13) - 825 - 117,
964 (1 << 13) - 837 - 117,
965 (1 << 13) - 811 - 117,
966 (1 << 13) - 766 - 117,
967 (1 << 13) - 737 - 117,
968 (1 << 13) - 693 - 117,
969 (1 << 13) - 648 - 117,
970 (1 << 13) - 619 - 117,
971 (1 << 13) - 575 - 117,
972 (1 << 13) - 531 - 117,
973 (1 << 13) - 501 - 117
974 };
975
976 if (state->ber_monitored_layer != LAYER_ALL)
977 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & 0x60) | state->ber_monitored_layer);
978 else
979 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
980
981 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
982 dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i);
983
984 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
985 //compute new dds_freq for the seg and adjust prbs
986 int seg_offset =
987 state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) -
988 (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2);
989 int clk = state->cfg.pll->internal;
990 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
991 int dds_offset = seg_offset * segtodds;
992 int new_dds, sub_channel;
993 if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even
994 dds_offset -= (int)(segtodds / 2);
995
996 if (state->cfg.pll->ifreq == 0) {
997 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) {
998 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
999 new_dds = dds_offset;
1000 } else
1001 new_dds = dds_offset;
1002
1003 // We shift tuning frequency if the wanted segment is :
1004 // - the segment of center frequency with an odd total number of segments
1005 // - the segment to the left of center frequency with an even total number of segments
1006 // - the segment to the right of center frequency with an even total number of segments
1007 if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1008 &&
1009 (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2)
1010 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1011 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1012 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1013 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2)))
1014 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1015 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx ==
1016 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1017 )) {
1018 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1019 }
1020 } else {
1021 if ((state->fe.dtv_property_cache.inversion ^ i) == 0)
1022 new_dds = state->cfg.pll->ifreq - dds_offset;
1023 else
1024 new_dds = state->cfg.pll->ifreq + dds_offset;
1025 }
1026 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1027 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1028 if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd
1029 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1030 else // if even
1031 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1032 sub_channel -= 6;
1033
1034 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1035 || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1036 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1037 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1038 } else {
1039 dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); //adp_pass =0
1040 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1041 }
1042
1043 switch (state->fe.dtv_property_cache.transmission_mode) {
1044 case TRANSMISSION_MODE_2K:
1045 switch (sub_channel) {
1046 case -6:
1047 init_prbs = 0x0;
1048 break; // 41, 0, 1
1049 case -5:
1050 init_prbs = 0x423;
1051 break; // 02~04
1052 case -4:
1053 init_prbs = 0x9;
1054 break; // 05~07
1055 case -3:
1056 init_prbs = 0x5C7;
1057 break; // 08~10
1058 case -2:
1059 init_prbs = 0x7A6;
1060 break; // 11~13
1061 case -1:
1062 init_prbs = 0x3D8;
1063 break; // 14~16
1064 case 0:
1065 init_prbs = 0x527;
1066 break; // 17~19
1067 case 1:
1068 init_prbs = 0x7FF;
1069 break; // 20~22
1070 case 2:
1071 init_prbs = 0x79B;
1072 break; // 23~25
1073 case 3:
1074 init_prbs = 0x3D6;
1075 break; // 26~28
1076 case 4:
1077 init_prbs = 0x3A2;
1078 break; // 29~31
1079 case 5:
1080 init_prbs = 0x53B;
1081 break; // 32~34
1082 case 6:
1083 init_prbs = 0x2F4;
1084 break; // 35~37
1085 default:
1086 case 7:
1087 init_prbs = 0x213;
1088 break; // 38~40
1089 }
1090 break;
1091
1092 case TRANSMISSION_MODE_4K:
1093 switch (sub_channel) {
1094 case -6:
1095 init_prbs = 0x0;
1096 break; // 41, 0, 1
1097 case -5:
1098 init_prbs = 0x208;
1099 break; // 02~04
1100 case -4:
1101 init_prbs = 0xC3;
1102 break; // 05~07
1103 case -3:
1104 init_prbs = 0x7B9;
1105 break; // 08~10
1106 case -2:
1107 init_prbs = 0x423;
1108 break; // 11~13
1109 case -1:
1110 init_prbs = 0x5C7;
1111 break; // 14~16
1112 case 0:
1113 init_prbs = 0x3D8;
1114 break; // 17~19
1115 case 1:
1116 init_prbs = 0x7FF;
1117 break; // 20~22
1118 case 2:
1119 init_prbs = 0x3D6;
1120 break; // 23~25
1121 case 3:
1122 init_prbs = 0x53B;
1123 break; // 26~28
1124 case 4:
1125 init_prbs = 0x213;
1126 break; // 29~31
1127 case 5:
1128 init_prbs = 0x29;
1129 break; // 32~34
1130 case 6:
1131 init_prbs = 0xD0;
1132 break; // 35~37
1133 default:
1134 case 7:
1135 init_prbs = 0x48E;
1136 break; // 38~40
1137 }
1138 break;
1139
1140 default:
1141 case TRANSMISSION_MODE_8K:
1142 switch (sub_channel) {
1143 case -6:
1144 init_prbs = 0x0;
1145 break; // 41, 0, 1
1146 case -5:
1147 init_prbs = 0x740;
1148 break; // 02~04
1149 case -4:
1150 init_prbs = 0x069;
1151 break; // 05~07
1152 case -3:
1153 init_prbs = 0x7DD;
1154 break; // 08~10
1155 case -2:
1156 init_prbs = 0x208;
1157 break; // 11~13
1158 case -1:
1159 init_prbs = 0x7B9;
1160 break; // 14~16
1161 case 0:
1162 init_prbs = 0x5C7;
1163 break; // 17~19
1164 case 1:
1165 init_prbs = 0x7FF;
1166 break; // 20~22
1167 case 2:
1168 init_prbs = 0x53B;
1169 break; // 23~25
1170 case 3:
1171 init_prbs = 0x29;
1172 break; // 26~28
1173 case 4:
1174 init_prbs = 0x48E;
1175 break; // 29~31
1176 case 5:
1177 init_prbs = 0x4C4;
1178 break; // 32~34
1179 case 6:
1180 init_prbs = 0x367;
1181 break; // 33~37
1182 default:
1183 case 7:
1184 init_prbs = 0x684;
1185 break; // 38~40
1186 }
1187 break;
1188 }
1189 } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode
1190 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1191 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1192 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
1193 }
1194 /*P_mode == ?? */
1195 dib8000_write_word(state, 10, (seq << 4));
1196 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1197
1198 switch (state->fe.dtv_property_cache.guard_interval) {
1199 case GUARD_INTERVAL_1_32:
1200 guard = 0;
1201 break;
1202 case GUARD_INTERVAL_1_16:
1203 guard = 1;
1204 break;
1205 case GUARD_INTERVAL_1_8:
1206 guard = 2;
1207 break;
1208 case GUARD_INTERVAL_1_4:
1209 default:
1210 guard = 3;
1211 break;
1212 }
1213
1214 dib8000_write_word(state, 1, (init_prbs << 2) | (guard & 0x3)); // ADDR 1
1215
1216 max_constellation = DQPSK;
1217 for (i = 0; i < 3; i++) {
1218 switch (state->fe.dtv_property_cache.layer[i].modulation) {
1219 case DQPSK:
1220 constellation = 0;
1221 break;
1222 case QPSK:
1223 constellation = 1;
1224 break;
1225 case QAM_16:
1226 constellation = 2;
1227 break;
1228 case QAM_64:
1229 default:
1230 constellation = 3;
1231 break;
1232 }
1233
1234 switch (state->fe.dtv_property_cache.layer[i].fec) {
1235 case FEC_1_2:
1236 crate = 1;
1237 break;
1238 case FEC_2_3:
1239 crate = 2;
1240 break;
1241 case FEC_3_4:
1242 crate = 3;
1243 break;
1244 case FEC_5_6:
1245 crate = 5;
1246 break;
1247 case FEC_7_8:
1248 default:
1249 crate = 7;
1250 break;
1251 }
1252
1253 if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) &&
1254 ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) ||
1255 (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1))
1256 )
1257 timeI = state->fe.dtv_property_cache.layer[i].interleaving;
1258 else
1259 timeI = 0;
1260 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1261 (crate << 3) | timeI);
1262 if (state->fe.dtv_property_cache.layer[i].segment_count > 0) {
1263 switch (max_constellation) {
1264 case DQPSK:
1265 case QPSK:
1266 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 ||
1267 state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1268 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1269 break;
1270 case QAM_16:
1271 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64)
1272 max_constellation = state->fe.dtv_property_cache.layer[i].modulation;
1273 break;
1274 }
1275 }
1276 }
1277
1278 mode = fft_to_mode(state);
1279
1280 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1281
1282 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1283 ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache.
1284 isdbt_sb_mode & 1) << 4));
1285
1286 dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval);
1287
1288 /* signal optimization parameter */
1289
1290 if (state->fe.dtv_property_cache.isdbt_partial_reception) {
1291 seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1292 for (i = 1; i < 3; i++)
1293 nbseg_diff +=
1294 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1295 for (i = 0; i < nbseg_diff; i++)
1296 seg_diff_mask |= 1 << permu_seg[i + 1];
1297 } else {
1298 for (i = 0; i < 3; i++)
1299 nbseg_diff +=
1300 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count;
1301 for (i = 0; i < nbseg_diff; i++)
1302 seg_diff_mask |= 1 << permu_seg[i];
1303 }
1304 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1305
1306 state->differential_constellation = (seg_diff_mask != 0);
1307 dib8000_set_diversity_in(&state->fe, state->diversity_onoff);
1308
1309 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1310 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1311 seg_mask13 = 0x00E0;
1312 else // 1-segment
1313 seg_mask13 = 0x0040;
1314 } else
1315 seg_mask13 = 0x1fff;
1316
1317 // WRITE: Mode & Diff mask
1318 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1319
1320 if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode))
1321 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1322 else
1323 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
1324
1325 // ---- SMALL ----
1326 // P_small_seg_diff
1327 dib8000_write_word(state, 352, seg_diff_mask); // ADDR 352
1328
1329 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1330
1331/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1332 // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1333
1334 // ---- SMALL ----
1335 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1336 switch (state->fe.dtv_property_cache.transmission_mode) {
1337 case TRANSMISSION_MODE_2K:
1338 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1339 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1340 ncoeff = coeff_2k_sb_1seg_dqpsk;
1341 else // QPSK or QAM
1342 ncoeff = coeff_2k_sb_1seg;
1343 } else { // 3-segments
1344 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1345 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1346 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1347 else // QPSK or QAM on external segments
1348 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1349 } else { // QPSK or QAM on central segment
1350 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments
1351 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1352 else // QPSK or QAM on external segments
1353 ncoeff = coeff_2k_sb_3seg;
1354 }
1355 }
1356 break;
1357
1358 case TRANSMISSION_MODE_4K:
1359 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1360 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1361 ncoeff = coeff_4k_sb_1seg_dqpsk;
1362 else // QPSK or QAM
1363 ncoeff = coeff_4k_sb_1seg;
1364 } else { // 3-segments
1365 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1366 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1367 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1368 } else { // QPSK or QAM on external segments
1369 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1370 }
1371 } else { // QPSK or QAM on central segment
1372 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1373 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1374 } else // QPSK or QAM on external segments
1375 ncoeff = coeff_4k_sb_3seg;
1376 }
1377 }
1378 break;
1379
1380 case TRANSMISSION_MODE_AUTO:
1381 case TRANSMISSION_MODE_8K:
1382 default:
1383 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg
1384 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK
1385 ncoeff = coeff_8k_sb_1seg_dqpsk;
1386 else // QPSK or QAM
1387 ncoeff = coeff_8k_sb_1seg;
1388 } else { // 3-segments
1389 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment
1390 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1391 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1392 } else { // QPSK or QAM on external segments
1393 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1394 }
1395 } else { // QPSK or QAM on central segment
1396 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments
1397 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1398 } else // QPSK or QAM on external segments
1399 ncoeff = coeff_8k_sb_3seg;
1400 }
1401 }
1402 break;
1403 }
1404 }
1405 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1406 for (i = 0; i < 8; i++)
1407 dib8000_write_word(state, 343 + i, ncoeff[i]);
1408
1409 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1410 dib8000_write_word(state, 351,
1411 (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1412
1413 // ---- COFF ----
1414 // Carloff, the most robust
1415 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots
1416
1417 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1418 // P_coff_narrow_band=1, P_coff_square_val=1, P_coff_one_seg=~partial_rcpt, P_coff_use_tmcc=1, P_coff_use_ac=1
1419 dib8000_write_word(state, 187,
1420 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2)
1421 | 0x3);
1422
1423/* // P_small_coef_ext_enable = 1 */
1424/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1425
1426 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1427
1428 // P_coff_winlen=63, P_coff_thres_lock=15, P_coff_one_seg_width= (P_mode == 3) , P_coff_one_seg_sym= (P_mode-1)
1429 if (mode == 3)
1430 dib8000_write_word(state, 180, 0x1fcf | ((mode - 1) << 14));
1431 else
1432 dib8000_write_word(state, 180, 0x0fcf | ((mode - 1) << 14));
1433 // P_ctrl_corm_thres4pre_freq_inh=1,P_ctrl_pre_freq_mode_sat=1,
1434 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 5, P_pre_freq_win_len=4
1435 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (5 << 5) | 4);
1436 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1437 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1438 // P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1439 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1440
1441 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1442 dib8000_write_word(state, 181, 300);
1443 dib8000_write_word(state, 182, 150);
1444 dib8000_write_word(state, 183, 80);
1445 dib8000_write_word(state, 184, 300);
1446 dib8000_write_word(state, 185, 150);
1447 dib8000_write_word(state, 186, 80);
1448 } else { // Sound Broadcasting mode 3 seg
1449 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1450 /* if (mode == 3) */
1451 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1452 /* else */
1453 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1454 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1455
1456 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
1457 // P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 4, P_pre_freq_win_len=4
1458 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (4 << 5) | 4);
1459 // P_ctrl_pre_freq_win_len=16, P_ctrl_pre_freq_thres_lockin=8
1460 dib8000_write_word(state, 340, (16 << 6) | (8 << 0));
1461 //P_ctrl_pre_freq_thres_lockout=6, P_small_use_tmcc/ac/cp=1
1462 dib8000_write_word(state, 341, (6 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1463
1464 // P_coff_corthres_8k, 4k, 2k and P_coff_cpilthres_8k, 4k, 2k
1465 dib8000_write_word(state, 181, 350);
1466 dib8000_write_word(state, 182, 300);
1467 dib8000_write_word(state, 183, 250);
1468 dib8000_write_word(state, 184, 350);
1469 dib8000_write_word(state, 185, 300);
1470 dib8000_write_word(state, 186, 250);
1471 }
1472
1473 } else if (state->isdbt_cfg_loaded == 0) { // if not Sound Broadcasting mode : put default values for 13 segments
1474 dib8000_write_word(state, 180, (16 << 6) | 9);
1475 dib8000_write_word(state, 187, (4 << 12) | (8 << 5) | 0x2);
1476 coff_pow = 0x2800;
1477 for (i = 0; i < 6; i++)
1478 dib8000_write_word(state, 181 + i, coff_pow);
1479
1480 // P_ctrl_corm_thres4pre_freq_inh=1, P_ctrl_pre_freq_mode_sat=1,
1481 // P_ctrl_pre_freq_mode_sat=1, P_ctrl_pre_freq_inh=0, P_ctrl_pre_freq_step = 3, P_pre_freq_win_len=1
1482 dib8000_write_word(state, 338, (1 << 12) | (1 << 10) | (0 << 9) | (3 << 5) | 1);
1483
1484 // P_ctrl_pre_freq_win_len=8, P_ctrl_pre_freq_thres_lockin=6
1485 dib8000_write_word(state, 340, (8 << 6) | (6 << 0));
1486 // P_ctrl_pre_freq_thres_lockout=4, P_small_use_tmcc/ac/cp=1
1487 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1488 }
1489 // ---- FFT ----
1490 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg
1491 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1492 else
1493 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
1494
1495 /* make the cpil_coff_lock more robust but slower p_coff_winlen
1496 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1497 */
1498 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1499 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1500
1501 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1502 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1503 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1504 if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1505 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1506 else
1507 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
1508 dib8000_write_word(state, 287, ~seg_mask13 | 0x1000); /* P_tmcc_seg_inh */
1509 //dib8000_write_word(state, 288, ~seg_mask13 | seg_diff_mask); /* P_tmcc_seg_eq_inh */
1510 if (!autosearching)
1511 dib8000_write_word(state, 288, (~seg_mask13 | seg_diff_mask) & 0x1fff); /* P_tmcc_seg_eq_inh */
1512 else
1513 dib8000_write_word(state, 288, 0x1fff); //disable equalisation of the tmcc when autosearch to be able to find the DQPSK channels.
1514 dprintk("287 = %X (%d)", ~seg_mask13 | 0x1000, ~seg_mask13 | 0x1000);
1515
1516 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1517
1518 /* offset loop parameters */
1519 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1520 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1521 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1522 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1523
1524 else // Sound Broadcasting mode 3 seg
1525 /* P_timf_alpha = (10-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1526 dib8000_write_word(state, 32, ((10 - mode) << 12) | (6 << 8) | 0x60);
1527 } else
1528 // TODO in 13 seg, timf_alpha can always be the same or not ?
1529 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1530 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1531
1532 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1533 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1534 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1535 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1536
1537 else // Sound Broadcasting mode 3 seg
1538 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (10-P_mode) */
1539 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (9 - mode));
1540 } else
1541 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = 9 */
1542 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1543
1544 /* P_dvsy_sync_wait - reuse mode */
1545 switch (state->fe.dtv_property_cache.transmission_mode) {
1546 case TRANSMISSION_MODE_8K:
1547 mode = 256;
1548 break;
1549 case TRANSMISSION_MODE_4K:
1550 mode = 128;
1551 break;
1552 default:
1553 case TRANSMISSION_MODE_2K:
1554 mode = 64;
1555 break;
1556 }
1557 if (state->cfg.diversity_delay == 0)
1558 mode = (mode * (1 << (guard)) * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo
1559 else
1560 mode = (mode * (1 << (guard)) * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for DVSY-fifo
1561 mode <<= 4;
1562 dib8000_write_word(state, 273, (dib8000_read_word(state, 273) & 0x000f) | mode);
1563
1564 /* channel estimation fine configuration */
1565 switch (max_constellation) {
1566 case QAM_64:
1567 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1568 coeff[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
1569 coeff[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
1570 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1571 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
1572 //if (!state->cfg.hostbus_diversity) //if diversity, we should prehaps use the configuration of the max_constallation -1
1573 break;
1574 case QAM_16:
1575 ana_gain = 0x7; // -1 : avoid def_est saturation when ADC target is -16dB
1576 coeff[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
1577 coeff[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
1578 coeff[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
1579 coeff[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
1580 //if (!((state->cfg.hostbus_diversity) && (max_constellation == QAM_16)))
1581 break;
1582 default:
1583 ana_gain = 0; // 0 : goes along with ADC target at -22dB to keep good mobile performance and lock at sensitivity level
1584 coeff[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
1585 coeff[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
1586 coeff[2] = 0x0333; /* P_adp_regul_ext 0.1 */
1587 coeff[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
1588 break;
1589 }
1590 for (mode = 0; mode < 4; mode++)
1591 dib8000_write_word(state, 215 + mode, coeff[mode]);
1592
1593 // update ana_gain depending on max constellation
1594 dib8000_write_word(state, 116, ana_gain);
1595 // update ADC target depending on ana_gain
1596 if (ana_gain) { // set -16dB ADC target for ana_gain=-1
1597 for (i = 0; i < 10; i++)
1598 dib8000_write_word(state, 80 + i, adc_target_16dB[i]);
1599 } else { // set -22dB ADC target for ana_gain=0
1600 for (i = 0; i < 10; i++)
1601 dib8000_write_word(state, 80 + i, adc_target_16dB[i] - 355);
1602 }
1603
1604 // ---- ANA_FE ----
1605 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1606 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments
1607 ana_fe = ana_fe_coeff_3seg;
1608 else // 1-segment
1609 ana_fe = ana_fe_coeff_1seg;
1610 } else
1611 ana_fe = ana_fe_coeff_13seg;
1612
1613 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1614 for (mode = 0; mode < 24; mode++)
1615 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1616
1617 // ---- CHAN_BLK ----
1618 for (i = 0; i < 13; i++) {
1619 if ((((~seg_diff_mask) >> i) & 1) == 1) {
1620 P_cfr_left_edge += (1 << i) * ((i == 0) || ((((seg_mask13 & (~seg_diff_mask)) >> (i - 1)) & 1) == 0));
1621 P_cfr_right_edge += (1 << i) * ((i == 12) || ((((seg_mask13 & (~seg_diff_mask)) >> (i + 1)) & 1) == 0));
1622 }
1623 }
1624 dib8000_write_word(state, 222, P_cfr_left_edge); // P_cfr_left_edge
1625 dib8000_write_word(state, 223, P_cfr_right_edge); // P_cfr_right_edge
1626 // "P_cspu_left_edge" not used => do not care
1627 // "P_cspu_right_edge" not used => do not care
1628
1629 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb
1630 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1631 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1632 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment
1633 && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1634 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1635 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1636 }
1637 } else if (state->isdbt_cfg_loaded == 0) {
1638 dib8000_write_word(state, 228, 0); // default value
1639 dib8000_write_word(state, 265, 31); // default value
1640 dib8000_write_word(state, 205, 0x200f); // init value
1641 }
1642 // ---- TMCC ----
1643 for (i = 0; i < 3; i++)
1644 tmcc_pow +=
1645 (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count);
1646 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1647 // Threshold is set at 1/4 of max power.
1648 tmcc_pow *= (1 << (9 - 2));
1649
1650 dib8000_write_word(state, 290, tmcc_pow); // P_tmcc_dec_thres_2k
1651 dib8000_write_word(state, 291, tmcc_pow); // P_tmcc_dec_thres_4k
1652 dib8000_write_word(state, 292, tmcc_pow); // P_tmcc_dec_thres_8k
1653 //dib8000_write_word(state, 287, (1 << 13) | 0x1000 );
1654 // ---- PHA3 ----
1655
1656 if (state->isdbt_cfg_loaded == 0)
1657 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1658
1659 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1)
1660 state->isdbt_cfg_loaded = 0;
1661 else
1662 state->isdbt_cfg_loaded = 1;
1663
1664}
1665
1666static int dib8000_autosearch_start(struct dvb_frontend *fe)
1667{
1668 u8 factor;
1669 u32 value;
1670 struct dib8000_state *state = fe->demodulator_priv;
1671
1672 int slist = 0;
1673
1674 state->fe.dtv_property_cache.inversion = 0;
1675 if (!state->fe.dtv_property_cache.isdbt_sb_mode)
1676 state->fe.dtv_property_cache.layer[0].segment_count = 13;
1677 state->fe.dtv_property_cache.layer[0].modulation = QAM_64;
1678 state->fe.dtv_property_cache.layer[0].fec = FEC_2_3;
1679 state->fe.dtv_property_cache.layer[0].interleaving = 0;
1680
1681 //choose the right list, in sb, always do everything
1682 if (state->fe.dtv_property_cache.isdbt_sb_mode) {
1683 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1684 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1685 slist = 7;
1686 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1687 } else {
1688 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1689 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1690 slist = 7;
1691 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1692 } else
1693 slist = 3;
1694 } else {
1695 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1696 slist = 2;
1697 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1698 } else
1699 slist = 0;
1700 }
1701
1702 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1703 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1704 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1705 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1706
1707 dprintk("using list for autosearch : %d", slist);
1708 dib8000_set_channel(state, (unsigned char)slist, 1);
1709 //dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1710
1711 factor = 1;
1712
1713 //set lock_mask values
1714 dib8000_write_word(state, 6, 0x4);
1715 dib8000_write_word(state, 7, 0x8);
1716 dib8000_write_word(state, 8, 0x1000);
1717
1718 //set lock_mask wait time values
1719 value = 50 * state->cfg.pll->internal * factor;
1720 dib8000_write_word(state, 11, (u16) ((value >> 16) & 0xffff)); // lock0 wait time
1721 dib8000_write_word(state, 12, (u16) (value & 0xffff)); // lock0 wait time
1722 value = 100 * state->cfg.pll->internal * factor;
1723 dib8000_write_word(state, 13, (u16) ((value >> 16) & 0xffff)); // lock1 wait time
1724 dib8000_write_word(state, 14, (u16) (value & 0xffff)); // lock1 wait time
1725 value = 1000 * state->cfg.pll->internal * factor;
1726 dib8000_write_word(state, 15, (u16) ((value >> 16) & 0xffff)); // lock2 wait time
1727 dib8000_write_word(state, 16, (u16) (value & 0xffff)); // lock2 wait time
1728
1729 value = dib8000_read_word(state, 0);
1730 dib8000_write_word(state, 0, (u16) ((1 << 15) | value));
1731 dib8000_read_word(state, 1284); // reset the INT. n_irq_pending
1732 dib8000_write_word(state, 0, (u16) value);
1733
1734 }
1735
1736 return 0;
1737}
1738
1739static int dib8000_autosearch_irq(struct dvb_frontend *fe)
1740{
1741 struct dib8000_state *state = fe->demodulator_priv;
1742 u16 irq_pending = dib8000_read_word(state, 1284);
1743
1744 if (irq_pending & 0x1) { // failed
1745 dprintk("dib8000_autosearch_irq failed");
1746 return 1;
1747 }
1748
1749 if (irq_pending & 0x2) { // succeeded
1750 dprintk("dib8000_autosearch_irq succeeded");
1751 return 2;
1752 }
1753
1754 return 0; // still pending
1755}
1756
1757static int dib8000_tune(struct dvb_frontend *fe)
1758{
1759 struct dib8000_state *state = fe->demodulator_priv;
1760 int ret = 0;
1761 u16 value, mode = fft_to_mode(state);
1762
1763 // we are already tuned - just resuming from suspend
1764 if (state == NULL)
1765 return -EINVAL;
1766
1767 dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000);
1768 dib8000_set_channel(state, 0, 0);
1769
1770 // restart demod
1771 ret |= dib8000_write_word(state, 770, 0x4000);
1772 ret |= dib8000_write_word(state, 770, 0x0000);
1773 msleep(45);
1774
1775 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3 */
1776 /* ret |= dib8000_write_word(state, 29, (0 << 9) | (4 << 5) | (0 << 4) | (3 << 0) ); workaround inh_isi stays at 1 */
1777
1778 // never achieved a lock before - wait for timfreq to update
1779 if (state->timf == 0) {
1780 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1781 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg
1782 msleep(300);
1783 else // Sound Broadcasting mode 3 seg
1784 msleep(500);
1785 } else // 13 seg
1786 msleep(200);
1787 }
1788 //dump_reg(state);
1789 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) {
1790 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1791
1792 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1793 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
1794 //dib8000_write_word(state, 32, (8 << 12) | (6 << 8) | 0x80);
1795
1796 /* P_ctrl_sfreq_step= (12-P_mode) P_ctrl_sfreq_inh =0 P_ctrl_pha_off_max */
1797 ret |= dib8000_write_word(state, 37, (12 - mode) | ((5 + mode) << 5));
1798
1799 } else { // Sound Broadcasting mode 3 seg
1800
1801 /* P_timf_alpha = (12-P_mode) , P_corm_alpha=6, P_corm_thres=0x60 alpha to check on board */
1802 dib8000_write_word(state, 32, ((12 - mode) << 12) | (6 << 8) | 0x60);
1803
1804 ret |= dib8000_write_word(state, 37, (11 - mode) | ((5 + mode) << 5));
1805 }
1806
1807 } else { // 13 seg
1808 /* P_timf_alpha = 8 , P_corm_alpha=6, P_corm_thres=0x80 alpha to check on board */
1809 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x80);
1810
1811 ret |= dib8000_write_word(state, 37, (10 - mode) | ((5 + mode) << 5));
1812
1813 }
1814
1815 // we achieved a coff_cpil_lock - it's time to update the timf
1816 if ((dib8000_read_word(state, 568) >> 11) & 0x1)
1817 dib8000_update_timf(state);
1818
1819 //now that tune is finished, lock0 should lock on fec_mpeg to output this lock on MP_LOCK. It's changed in autosearch start
1820 dib8000_write_word(state, 6, 0x200);
1821
1822 if (state->revision == 0x8002) {
1823 value = dib8000_read_word(state, 903);
1824 dib8000_write_word(state, 903, value & ~(1 << 3));
1825 msleep(1);
1826 dib8000_write_word(state, 903, value | (1 << 3));
1827 }
1828
1829 return ret;
1830}
1831
1832static int dib8000_wakeup(struct dvb_frontend *fe)
1833{
1834 struct dib8000_state *state = fe->demodulator_priv;
1835
1836 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1837 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1838 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1839 dprintk("could not start Slow ADC");
1840
1841 return 0;
1842}
1843
1844static int dib8000_sleep(struct dvb_frontend *fe)
1845{
1846 struct dib8000_state *st = fe->demodulator_priv;
1847 if (1) {
1848 dib8000_set_output_mode(st, OUTMODE_HIGH_Z);
1849 dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1850 return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1851 } else {
1852
1853 return 0;
1854 }
1855}
1856
1857static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1858{
1859 struct dib8000_state *state = fe->demodulator_priv;
1860 u16 i, val = 0;
1861
1862 fe->dtv_property_cache.bandwidth_hz = 6000000;
1863
1864 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1865
1866 val = dib8000_read_word(state, 570);
1867 fe->dtv_property_cache.inversion = (val & 0x40) >> 6;
1868 switch ((val & 0x30) >> 4) {
1869 case 1:
1870 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1871 break;
1872 case 3:
1873 default:
1874 fe->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1875 break;
1876 }
1877
1878 switch (val & 0x3) {
1879 case 0:
1880 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1881 dprintk("dib8000_get_frontend GI = 1/32 ");
1882 break;
1883 case 1:
1884 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1885 dprintk("dib8000_get_frontend GI = 1/16 ");
1886 break;
1887 case 2:
1888 dprintk("dib8000_get_frontend GI = 1/8 ");
1889 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1890 break;
1891 case 3:
1892 dprintk("dib8000_get_frontend GI = 1/4 ");
1893 fe->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1894 break;
1895 }
1896
1897 val = dib8000_read_word(state, 505);
1898 fe->dtv_property_cache.isdbt_partial_reception = val & 1;
1899 dprintk("dib8000_get_frontend : partial_reception = %d ", fe->dtv_property_cache.isdbt_partial_reception);
1900
1901 for (i = 0; i < 3; i++) {
1902 val = dib8000_read_word(state, 493 + i);
1903 fe->dtv_property_cache.layer[i].segment_count = val & 0x0F;
1904 dprintk("dib8000_get_frontend : Layer %d segments = %d ", i, fe->dtv_property_cache.layer[i].segment_count);
1905
1906 val = dib8000_read_word(state, 499 + i);
1907 fe->dtv_property_cache.layer[i].interleaving = val & 0x3;
1908 dprintk("dib8000_get_frontend : Layer %d time_intlv = %d ", i, fe->dtv_property_cache.layer[i].interleaving);
1909
1910 val = dib8000_read_word(state, 481 + i);
1911 switch (val & 0x7) {
1912 case 1:
1913 fe->dtv_property_cache.layer[i].fec = FEC_1_2;
1914 dprintk("dib8000_get_frontend : Layer %d Code Rate = 1/2 ", i);
1915 break;
1916 case 2:
1917 fe->dtv_property_cache.layer[i].fec = FEC_2_3;
1918 dprintk("dib8000_get_frontend : Layer %d Code Rate = 2/3 ", i);
1919 break;
1920 case 3:
1921 fe->dtv_property_cache.layer[i].fec = FEC_3_4;
1922 dprintk("dib8000_get_frontend : Layer %d Code Rate = 3/4 ", i);
1923 break;
1924 case 5:
1925 fe->dtv_property_cache.layer[i].fec = FEC_5_6;
1926 dprintk("dib8000_get_frontend : Layer %d Code Rate = 5/6 ", i);
1927 break;
1928 default:
1929 fe->dtv_property_cache.layer[i].fec = FEC_7_8;
1930 dprintk("dib8000_get_frontend : Layer %d Code Rate = 7/8 ", i);
1931 break;
1932 }
1933
1934 val = dib8000_read_word(state, 487 + i);
1935 switch (val & 0x3) {
1936 case 0:
1937 dprintk("dib8000_get_frontend : Layer %d DQPSK ", i);
1938 fe->dtv_property_cache.layer[i].modulation = DQPSK;
1939 break;
1940 case 1:
1941 fe->dtv_property_cache.layer[i].modulation = QPSK;
1942 dprintk("dib8000_get_frontend : Layer %d QPSK ", i);
1943 break;
1944 case 2:
1945 fe->dtv_property_cache.layer[i].modulation = QAM_16;
1946 dprintk("dib8000_get_frontend : Layer %d QAM16 ", i);
1947 break;
1948 case 3:
1949 default:
1950 dprintk("dib8000_get_frontend : Layer %d QAM64 ", i);
1951 fe->dtv_property_cache.layer[i].modulation = QAM_64;
1952 break;
1953 }
1954 }
1955 return 0;
1956}
1957
1958static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1959{
1960 struct dib8000_state *state = fe->demodulator_priv;
1961 int time, ret;
1962
1963 dib8000_set_output_mode(state, OUTMODE_HIGH_Z);
1964
1965 if (fe->ops.tuner_ops.set_params)
1966 fe->ops.tuner_ops.set_params(fe, fep);
1967
1968 /* start up the AGC */
1969 state->tune_state = CT_AGC_START;
1970 do {
1971 time = dib8000_agc_startup(fe);
1972 if (time != FE_CALLBACK_TIME_NEVER)
1973 msleep(time / 10);
1974 else
1975 break;
1976 } while (state->tune_state != CT_AGC_STOP);
1977
1978 if (state->fe.dtv_property_cache.frequency == 0) {
1979 dprintk("dib8000: must at least specify frequency ");
1980 return 0;
1981 }
1982
1983 if (state->fe.dtv_property_cache.bandwidth_hz == 0) {
1984 dprintk("dib8000: no bandwidth specified, set to default ");
1985 state->fe.dtv_property_cache.bandwidth_hz = 6000000;
1986 }
1987
1988 state->tune_state = CT_DEMOD_START;
1989
1990 if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
1991 (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
1992 (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
1993 (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
1994 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
1995 (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
1996 (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
1997 ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
1998 (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
1999 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2000 (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2001 (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2002 ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2003 (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2004 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2005 (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2006 (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2007 ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2008 (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2009 (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2010 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2011 ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2012 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2013 ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2014 int i = 800, found;
2015
2016 dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2017 dib8000_autosearch_start(fe);
2018 do {
2019 msleep(10);
2020 found = dib8000_autosearch_irq(fe);
2021 } while (found == 0 && i--);
2022
2023 dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found);
2024
2025 if (found == 0 || found == 1)
2026 return 0; // no channel found
2027
2028 dib8000_get_frontend(fe, fep);
2029 }
2030
2031 ret = dib8000_tune(fe);
2032
2033 /* make this a config parameter */
2034 dib8000_set_output_mode(state, state->cfg.output_mode);
2035
2036 return ret;
2037}
2038
2039static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2040{
2041 struct dib8000_state *state = fe->demodulator_priv;
2042 u16 lock = dib8000_read_word(state, 568);
2043
2044 *stat = 0;
2045
2046 if ((lock >> 14) & 1) // AGC
2047 *stat |= FE_HAS_SIGNAL;
2048
2049 if ((lock >> 8) & 1) // Equal
2050 *stat |= FE_HAS_CARRIER;
2051
2052 if ((lock >> 3) & 1) // TMCC_SYNC
2053 *stat |= FE_HAS_SYNC;
2054
2055 if ((lock >> 5) & 7) // FEC MPEG
2056 *stat |= FE_HAS_LOCK;
2057
2058 lock = dib8000_read_word(state, 554); // Viterbi Layer A
2059 if (lock & 0x01)
2060 *stat |= FE_HAS_VITERBI;
2061
2062 lock = dib8000_read_word(state, 555); // Viterbi Layer B
2063 if (lock & 0x01)
2064 *stat |= FE_HAS_VITERBI;
2065
2066 lock = dib8000_read_word(state, 556); // Viterbi Layer C
2067 if (lock & 0x01)
2068 *stat |= FE_HAS_VITERBI;
2069
2070 return 0;
2071}
2072
2073static int dib8000_read_ber(struct dvb_frontend *fe, u32 * ber)
2074{
2075 struct dib8000_state *state = fe->demodulator_priv;
2076 *ber = (dib8000_read_word(state, 560) << 16) | dib8000_read_word(state, 561); // 13 segments
2077 return 0;
2078}
2079
2080static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2081{
2082 struct dib8000_state *state = fe->demodulator_priv;
2083 *unc = dib8000_read_word(state, 565); // packet error on 13 seg
2084 return 0;
2085}
2086
2087static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2088{
2089 struct dib8000_state *state = fe->demodulator_priv;
2090 u16 val = dib8000_read_word(state, 390);
2091 *strength = 65535 - val;
2092 return 0;
2093}
2094
2095static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2096{
2097 struct dib8000_state *state = fe->demodulator_priv;
2098 u16 val;
2099 s32 signal_mant, signal_exp, noise_mant, noise_exp;
2100 u32 result = 0;
2101
2102 val = dib8000_read_word(state, 542);
2103 noise_mant = (val >> 6) & 0xff;
2104 noise_exp = (val & 0x3f);
2105
2106 val = dib8000_read_word(state, 543);
2107 signal_mant = (val >> 6) & 0xff;
2108 signal_exp = (val & 0x3f);
2109
2110 if ((noise_exp & 0x20) != 0)
2111 noise_exp -= 0x40;
2112 if ((signal_exp & 0x20) != 0)
2113 signal_exp -= 0x40;
2114
2115 if (signal_mant != 0)
2116 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
2117 else
2118 result = intlog10(2) * 10 * signal_exp - 100;
2119 if (noise_mant != 0)
2120 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
2121 else
2122 result -= intlog10(2) * 10 * noise_exp - 100;
2123
2124 *snr = result / (1 << 24);
2125 return 0;
2126}
2127
2128int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2129{
2130 int k = 0;
2131 u8 new_addr = 0;
2132 struct i2c_device client = {.adap = host };
2133
2134 for (k = no_of_demods - 1; k >= 0; k--) {
2135 /* designated i2c address */
2136 new_addr = first_addr + (k << 1);
2137
2138 client.addr = new_addr;
2139 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2140 if (dib8000_identify(&client) == 0) {
2141 dib8000_i2c_write16(&client, 1287, 0x0003); /* sram lead in, rdy */
2142 client.addr = default_addr;
2143 if (dib8000_identify(&client) == 0) {
2144 dprintk("#%d: not identified", k);
2145 return -EINVAL;
2146 }
2147 }
2148
2149 /* start diversity to pull_down div_str - just for i2c-enumeration */
2150 dib8000_i2c_write16(&client, 1286, (1 << 10) | (4 << 6));
2151
2152 /* set new i2c address and force divstart */
2153 dib8000_i2c_write16(&client, 1285, (new_addr << 2) | 0x2);
2154 client.addr = new_addr;
2155 dib8000_identify(&client);
2156
2157 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2158 }
2159
2160 for (k = 0; k < no_of_demods; k++) {
2161 new_addr = first_addr | (k << 1);
2162 client.addr = new_addr;
2163
2164 // unforce divstr
2165 dib8000_i2c_write16(&client, 1285, new_addr << 2);
2166
2167 /* deactivate div - it was just for i2c-enumeration */
2168 dib8000_i2c_write16(&client, 1286, 0);
2169 }
2170
2171 return 0;
2172}
2173
2174EXPORT_SYMBOL(dib8000_i2c_enumeration);
2175static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
2176{
2177 tune->min_delay_ms = 1000;
2178 tune->step_size = 0;
2179 tune->max_drift = 0;
2180 return 0;
2181}
2182
2183static void dib8000_release(struct dvb_frontend *fe)
2184{
2185 struct dib8000_state *st = fe->demodulator_priv;
2186 dibx000_exit_i2c_master(&st->i2c_master);
2187 kfree(st);
2188}
2189
2190struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
2191{
2192 struct dib8000_state *st = fe->demodulator_priv;
2193 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
2194}
2195
2196EXPORT_SYMBOL(dib8000_get_i2c_master);
2197
2198static const struct dvb_frontend_ops dib8000_ops = {
2199 .info = {
2200 .name = "DiBcom 8000 ISDB-T",
2201 .type = FE_OFDM,
2202 .frequency_min = 44250000,
2203 .frequency_max = 867250000,
2204 .frequency_stepsize = 62500,
2205 .caps = FE_CAN_INVERSION_AUTO |
2206 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2207 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2208 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2209 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2210 },
2211
2212 .release = dib8000_release,
2213
2214 .init = dib8000_wakeup,
2215 .sleep = dib8000_sleep,
2216
2217 .set_frontend = dib8000_set_frontend,
2218 .get_tune_settings = dib8000_fe_get_tune_settings,
2219 .get_frontend = dib8000_get_frontend,
2220
2221 .read_status = dib8000_read_status,
2222 .read_ber = dib8000_read_ber,
2223 .read_signal_strength = dib8000_read_signal_strength,
2224 .read_snr = dib8000_read_snr,
2225 .read_ucblocks = dib8000_read_unc_blocks,
2226};
2227
2228struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
2229{
2230 struct dvb_frontend *fe;
2231 struct dib8000_state *state;
2232
2233 dprintk("dib8000_attach");
2234
2235 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2236 if (state == NULL)
2237 return NULL;
2238
2239 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2240 state->i2c.adap = i2c_adap;
2241 state->i2c.addr = i2c_addr;
2242 state->gpio_val = cfg->gpio_val;
2243 state->gpio_dir = cfg->gpio_dir;
2244
2245 /* Ensure the output mode remains at the previous default if it's
2246 * not specifically set by the caller.
2247 */
2248 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2249 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2250
2251 fe = &state->fe;
2252 fe->demodulator_priv = state;
2253 memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2254
2255 state->timf_default = cfg->pll->timf;
2256
2257 if (dib8000_identify(&state->i2c) == 0)
2258 goto error;
2259
2260 dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr);
2261
2262 dib8000_reset(fe);
2263
2264 dib8000_write_word(state, 285, (dib8000_read_word(state, 285) & ~0x60) | (3 << 5)); /* ber_rs_len = 3 */
2265
2266 return fe;
2267
2268 error:
2269 kfree(state);
2270 return NULL;
2271}
2272
2273EXPORT_SYMBOL(dib8000_attach);
2274
2275MODULE_AUTHOR("Olivier Grenie <Olivier.Grenie@dibcom.fr, " "Patrick Boettcher <pboettcher@dibcom.fr>");
2276MODULE_DESCRIPTION("Driver for the DiBcom 8000 ISDB-T demodulator");
2277MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
new file mode 100644
index 000000000000..a86de340dd54
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -0,0 +1,79 @@
1#ifndef DIB8000_H
2#define DIB8000_H
3
4#include "dibx000_common.h"
5
6struct dib8000_config {
7 u8 output_mpeg2_in_188_bytes;
8 u8 hostbus_diversity;
9 u8 tuner_is_baseband;
10 int (*update_lna) (struct dvb_frontend *, u16 agc_global);
11
12 u8 agc_config_count;
13 struct dibx000_agc_config *agc;
14 struct dibx000_bandwidth_config *pll;
15
16#define DIB8000_GPIO_DEFAULT_DIRECTIONS 0xffff
17 u16 gpio_dir;
18#define DIB8000_GPIO_DEFAULT_VALUES 0x0000
19 u16 gpio_val;
20#define DIB8000_GPIO_PWM_POS0(v) ((v & 0xf) << 12)
21#define DIB8000_GPIO_PWM_POS1(v) ((v & 0xf) << 8 )
22#define DIB8000_GPIO_PWM_POS2(v) ((v & 0xf) << 4 )
23#define DIB8000_GPIO_PWM_POS3(v) (v & 0xf)
24#define DIB8000_GPIO_DEFAULT_PWM_POS 0xffff
25 u16 gpio_pwm_pos;
26 u16 pwm_freq_div;
27
28 void (*agc_control) (struct dvb_frontend *, u8 before);
29
30 u16 drives;
31 u16 diversity_delay;
32 u8 div_cfg;
33 u8 output_mode;
34 u8 refclksel;
35};
36
37#define DEFAULT_DIB8000_I2C_ADDRESS 18
38
39#if defined(CONFIG_DVB_DIB8000) || (defined(CONFIG_DVB_DIB8000_MODULE) && defined(MODULE))
40extern struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg);
41extern struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
42
43extern int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
44
45extern int dib8000_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
46extern int dib8000_set_wbd_ref(struct dvb_frontend *, u16 value);
47#else
48static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
51 return NULL;
52}
53
54static inline struct i2c_adapter *dib8000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return NULL;
58}
59
60int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
63 return -ENODEV;
64}
65
66int dib8000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
67{
68 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
69 return -ENODEV;
70}
71
72int dib8000_set_wbd_ref(struct dvb_frontend *fe, u16 value)
73{
74 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
75 return -ENODEV;
76}
77#endif
78
79#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index 315e09e95b0c..4efca30d2127 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -15,29 +15,31 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
15 (val >> 8) & 0xff, val & 0xff, 15 (val >> 8) & 0xff, val & 0xff,
16 }; 16 };
17 struct i2c_msg msg = { 17 struct i2c_msg msg = {
18 .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4 18 .addr = mst->i2c_addr,.flags = 0,.buf = b,.len = 4
19 }; 19 };
20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
21} 21}
22 22
23 23
24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf) 24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
25 enum dibx000_i2c_interface intf)
25{ 26{
26 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) { 27 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
27 dprintk("selecting interface: %d\n",intf); 28 dprintk("selecting interface: %d\n", intf);
28 mst->selected_interface = intf; 29 mst->selected_interface = intf;
29 return dibx000_write_word(mst, mst->base_reg + 4, intf); 30 return dibx000_write_word(mst, mst->base_reg + 4, intf);
30 } 31 }
31 return 0; 32 return 0;
32} 33}
33 34
34static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff) 35static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
36 u8 addr, int onoff)
35{ 37{
36 u16 val; 38 u16 val;
37 39
38 40
39 if (onoff) 41 if (onoff)
40 val = addr << 8; // bit 7 = use master or not, if 0, the gate is open 42 val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
41 else 43 else
42 val = 1 << 7; 44 val = 1 << 7;
43 45
@@ -45,7 +47,7 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 ad
45 val <<= 1; 47 val <<= 1;
46 48
47 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff); 49 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
48 tx[1] = ( (mst->base_reg + 1) & 0xff); 50 tx[1] = ((mst->base_reg + 1) & 0xff);
49 tx[2] = val >> 8; 51 tx[2] = val >> 8;
50 tx[3] = val & 0xff; 52 tx[3] = val & 0xff;
51 53
@@ -57,59 +59,78 @@ static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
57 return I2C_FUNC_I2C; 59 return I2C_FUNC_I2C;
58} 60}
59 61
60static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num) 62static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
63 struct i2c_msg msg[], int num)
61{ 64{
62 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap); 65 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
63 struct i2c_msg m[2 + num]; 66 struct i2c_msg m[2 + num];
64 u8 tx_open[4], tx_close[4]; 67 u8 tx_open[4], tx_close[4];
65 68
66 memset(m,0, sizeof(struct i2c_msg) * (2 + num)); 69 memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
67 70
68 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER); 71 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
69 72
70 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1); 73 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
71 m[0].addr = mst->i2c_addr; 74 m[0].addr = mst->i2c_addr;
72 m[0].buf = tx_open; 75 m[0].buf = tx_open;
73 m[0].len = 4; 76 m[0].len = 4;
74 77
75 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num); 78 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
76 79
77 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0); 80 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
78 m[num+1].addr = mst->i2c_addr; 81 m[num + 1].addr = mst->i2c_addr;
79 m[num+1].buf = tx_close; 82 m[num + 1].buf = tx_close;
80 m[num+1].len = 4; 83 m[num + 1].len = 4;
81 84
82 return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO; 85 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
83} 86}
84 87
85static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = { 88static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
86 .master_xfer = dibx000_i2c_gated_tuner_xfer, 89 .master_xfer = dibx000_i2c_gated_tuner_xfer,
87 .functionality = dibx000_i2c_func, 90 .functionality = dibx000_i2c_func,
88}; 91};
89 92
90struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating) 93struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
94 enum dibx000_i2c_interface intf,
95 int gating)
91{ 96{
92 struct i2c_adapter *i2c = NULL; 97 struct i2c_adapter *i2c = NULL;
93 98
94 switch (intf) { 99 switch (intf) {
95 case DIBX000_I2C_INTERFACE_TUNER: 100 case DIBX000_I2C_INTERFACE_TUNER:
96 if (gating) 101 if (gating)
97 i2c = &mst->gated_tuner_i2c_adap; 102 i2c = &mst->gated_tuner_i2c_adap;
98 break; 103 break;
99 default: 104 default:
100 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); 105 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
101 break; 106 break;
102 } 107 }
103 108
104 return i2c; 109 return i2c;
105} 110}
111
106EXPORT_SYMBOL(dibx000_get_i2c_adapter); 112EXPORT_SYMBOL(dibx000_get_i2c_adapter);
107 113
108static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char *name, struct dibx000_i2c_master *mst) 114void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
115{
116 /* initialize the i2c-master by closing the gate */
117 u8 tx[4];
118 struct i2c_msg m = {.addr = mst->i2c_addr,.buf = tx,.len = 4 };
119
120 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
121 i2c_transfer(mst->i2c_adap, &m, 1);
122 mst->selected_interface = 0xff; // the first time force a select of the I2C
123 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
124}
125
126EXPORT_SYMBOL(dibx000_reset_i2c_master);
127
128static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
129 struct i2c_algorithm *algo, const char *name,
130 struct dibx000_i2c_master *mst)
109{ 131{
110 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); 132 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
111 i2c_adap->class = I2C_CLASS_TV_DIGITAL, 133 i2c_adap->class = I2C_CLASS_TV_DIGITAL, i2c_adap->algo = algo;
112 i2c_adap->algo = algo;
113 i2c_adap->algo_data = NULL; 134 i2c_adap->algo_data = NULL;
114 i2c_set_adapdata(i2c_adap, mst); 135 i2c_set_adapdata(i2c_adap, mst);
115 if (i2c_add_adapter(i2c_adap) < 0) 136 if (i2c_add_adapter(i2c_adap) < 0)
@@ -117,34 +138,40 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *
117 return 0; 138 return 0;
118} 139}
119 140
120int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr) 141int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
142 struct i2c_adapter *i2c_adap, u8 i2c_addr)
121{ 143{
122 u8 tx[4]; 144 u8 tx[4];
123 struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 }; 145 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
124 146
125 mst->device_rev = device_rev; 147 mst->device_rev = device_rev;
126 mst->i2c_adap = i2c_adap; 148 mst->i2c_adap = i2c_adap;
127 mst->i2c_addr = i2c_addr >> 1; 149 mst->i2c_addr = i2c_addr >> 1;
128 150
129 if (device_rev == DIB7000P) 151 if (device_rev == DIB7000P || device_rev == DIB8000)
130 mst->base_reg = 1024; 152 mst->base_reg = 1024;
131 else 153 else
132 mst->base_reg = 768; 154 mst->base_reg = 768;
133 155
134 if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0) 156 if (i2c_adapter_init
135 printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n"); 157 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
158 "DiBX000 tuner I2C bus", mst) != 0)
159 printk(KERN_ERR
160 "DiBX000: could not initialize the tuner i2c_adapter\n");
136 161
137 /* initialize the i2c-master by closing the gate */ 162 /* initialize the i2c-master by closing the gate */
138 dibx000_i2c_gate_ctrl(mst, tx, 0, 0); 163 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
139 164
140 return i2c_transfer(i2c_adap, &m, 1) == 1; 165 return i2c_transfer(i2c_adap, &m, 1) == 1;
141} 166}
167
142EXPORT_SYMBOL(dibx000_init_i2c_master); 168EXPORT_SYMBOL(dibx000_init_i2c_master);
143 169
144void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) 170void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
145{ 171{
146 i2c_del_adapter(&mst->gated_tuner_i2c_adap); 172 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
147} 173}
174
148EXPORT_SYMBOL(dibx000_exit_i2c_master); 175EXPORT_SYMBOL(dibx000_exit_i2c_master);
149 176
150MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 177MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 84e4d5362922..5be10eca07c0 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -2,7 +2,7 @@
2#define DIBX000_COMMON_H 2#define DIBX000_COMMON_H
3 3
4enum dibx000_i2c_interface { 4enum dibx000_i2c_interface {
5 DIBX000_I2C_INTERFACE_TUNER = 0, 5 DIBX000_I2C_INTERFACE_TUNER = 0,
6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1, 6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2 7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
8}; 8};
@@ -12,22 +12,29 @@ struct dibx000_i2c_master {
12#define DIB7000 2 12#define DIB7000 2
13#define DIB7000P 11 13#define DIB7000P 11
14#define DIB7000MC 12 14#define DIB7000MC 12
15#define DIB8000 13
15 u16 device_rev; 16 u16 device_rev;
16 17
17 enum dibx000_i2c_interface selected_interface; 18 enum dibx000_i2c_interface selected_interface;
18 19
19// struct i2c_adapter tuner_i2c_adap; 20// struct i2c_adapter tuner_i2c_adap;
20 struct i2c_adapter gated_tuner_i2c_adap; 21 struct i2c_adapter gated_tuner_i2c_adap;
21 22
22 struct i2c_adapter *i2c_adap; 23 struct i2c_adapter *i2c_adap;
23 u8 i2c_addr; 24 u8 i2c_addr;
24 25
25 u16 base_reg; 26 u16 base_reg;
26}; 27};
27 28
28extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr); 29extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
29extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating); 30 u16 device_rev, struct i2c_adapter *i2c_adap,
31 u8 i2c_addr);
32extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
33 *mst,
34 enum dibx000_i2c_interface
35 intf, int gating);
30extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); 36extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
37extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
31 38
32#define BAND_LBAND 0x01 39#define BAND_LBAND 0x01
33#define BAND_UHF 0x02 40#define BAND_UHF 0x02
@@ -41,18 +48,18 @@ extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
41 (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND ) 48 (freq_kHz) <= 2000000 ? BAND_LBAND : BAND_SBAND )
42 49
43struct dibx000_agc_config { 50struct dibx000_agc_config {
44 /* defines the capabilities of this AGC-setting - using the BAND_-defines*/ 51 /* defines the capabilities of this AGC-setting - using the BAND_-defines */
45 u8 band_caps; 52 u8 band_caps;
46 53
47 u16 setup; 54 u16 setup;
48 55
49 u16 inv_gain; 56 u16 inv_gain;
50 u16 time_stabiliz; 57 u16 time_stabiliz;
51 58
52 u8 alpha_level; 59 u8 alpha_level;
53 u16 thlock; 60 u16 thlock;
54 61
55 u8 wbd_inv; 62 u8 wbd_inv;
56 u16 wbd_ref; 63 u16 wbd_ref;
57 u8 wbd_sel; 64 u8 wbd_sel;
58 u8 wbd_alpha; 65 u8 wbd_alpha;
@@ -92,8 +99,8 @@ struct dibx000_agc_config {
92}; 99};
93 100
94struct dibx000_bandwidth_config { 101struct dibx000_bandwidth_config {
95 u32 internal; 102 u32 internal;
96 u32 sampling; 103 u32 sampling;
97 104
98 u8 pll_prediv; 105 u8 pll_prediv;
99 u8 pll_ratio; 106 u8 pll_ratio;
diff --git a/drivers/media/dvb/frontends/lgdt3304.c b/drivers/media/dvb/frontends/lgdt3304.c
index eb72a9866c93..e334b5d4e578 100644
--- a/drivers/media/dvb/frontends/lgdt3304.c
+++ b/drivers/media/dvb/frontends/lgdt3304.c
@@ -363,6 +363,8 @@ struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
363 363
364 struct lgdt3304_state *state; 364 struct lgdt3304_state *state;
365 state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL); 365 state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
366 if (state == NULL)
367 return NULL;
366 state->addr = config->i2c_address; 368 state->addr = config->i2c_address;
367 state->i2c = i2c; 369 state->i2c = i2c;
368 370
diff --git a/drivers/media/dvb/frontends/s921_module.c b/drivers/media/dvb/frontends/s921_module.c
index 3f5a0e1dfdf5..3156b64cfc96 100644
--- a/drivers/media/dvb/frontends/s921_module.c
+++ b/drivers/media/dvb/frontends/s921_module.c
@@ -169,6 +169,8 @@ struct dvb_frontend* s921_attach(const struct s921_config *config,
169 169
170 struct s921_state *state; 170 struct s921_state *state;
171 state = kzalloc(sizeof(struct s921_state), GFP_KERNEL); 171 state = kzalloc(sizeof(struct s921_state), GFP_KERNEL);
172 if (state == NULL)
173 return NULL;
172 174
173 state->addr = config->i2c_address; 175 state->addr = config->i2c_address;
174 state->i2c = i2c; 176 state->i2c = i2c;
diff --git a/drivers/media/dvb/pt1/Kconfig b/drivers/media/dvb/pt1/Kconfig
new file mode 100644
index 000000000000..24501d5bf70d
--- /dev/null
+++ b/drivers/media/dvb/pt1/Kconfig
@@ -0,0 +1,12 @@
1config DVB_PT1
2 tristate "PT1 cards"
3 depends on DVB_CORE && PCI && I2C
4 help
5 Support for Earthsoft PT1 PCI cards.
6
7 Since these cards have no MPEG decoder onboard, they transmit
8 only compressed MPEG data over the PCI bus, so you need
9 an external software decoder to watch TV on your computer.
10
11 Say Y or M if you own such a device and want to use it.
12
diff --git a/drivers/media/dvb/pt1/Makefile b/drivers/media/dvb/pt1/Makefile
new file mode 100644
index 000000000000..a66da17bbe31
--- /dev/null
+++ b/drivers/media/dvb/pt1/Makefile
@@ -0,0 +1,5 @@
1earth-pt1-objs := pt1.o va1j5jf8007s.o va1j5jf8007t.o
2
3obj-$(CONFIG_DVB_PT1) += earth-pt1.o
4
5EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core -Idrivers/media/dvb/frontends
diff --git a/drivers/media/dvb/pt1/pt1.c b/drivers/media/dvb/pt1/pt1.c
new file mode 100644
index 000000000000..8ffbcecad931
--- /dev/null
+++ b/drivers/media/dvb/pt1/pt1.c
@@ -0,0 +1,1056 @@
1/*
2 * driver for Earthsoft PT1
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/kthread.h>
28#include <linux/freezer.h>
29
30#include "dvbdev.h"
31#include "dvb_demux.h"
32#include "dmxdev.h"
33#include "dvb_net.h"
34#include "dvb_frontend.h"
35
36#include "va1j5jf8007t.h"
37#include "va1j5jf8007s.h"
38
39#define DRIVER_NAME "earth-pt1"
40
41#define PT1_PAGE_SHIFT 12
42#define PT1_PAGE_SIZE (1 << PT1_PAGE_SHIFT)
43#define PT1_NR_UPACKETS 1024
44#define PT1_NR_BUFS 511
45
46struct pt1_buffer_page {
47 __le32 upackets[PT1_NR_UPACKETS];
48};
49
50struct pt1_table_page {
51 __le32 next_pfn;
52 __le32 buf_pfns[PT1_NR_BUFS];
53};
54
55struct pt1_buffer {
56 struct pt1_buffer_page *page;
57 dma_addr_t addr;
58};
59
60struct pt1_table {
61 struct pt1_table_page *page;
62 dma_addr_t addr;
63 struct pt1_buffer bufs[PT1_NR_BUFS];
64};
65
66#define PT1_NR_ADAPS 4
67
68struct pt1_adapter;
69
70struct pt1 {
71 struct pci_dev *pdev;
72 void __iomem *regs;
73 struct i2c_adapter i2c_adap;
74 int i2c_running;
75 struct pt1_adapter *adaps[PT1_NR_ADAPS];
76 struct pt1_table *tables;
77 struct task_struct *kthread;
78};
79
80struct pt1_adapter {
81 struct pt1 *pt1;
82 int index;
83
84 u8 *buf;
85 int upacket_count;
86 int packet_count;
87
88 struct dvb_adapter adap;
89 struct dvb_demux demux;
90 int users;
91 struct dmxdev dmxdev;
92 struct dvb_net net;
93 struct dvb_frontend *fe;
94 int (*orig_set_voltage)(struct dvb_frontend *fe,
95 fe_sec_voltage_t voltage);
96};
97
98#define pt1_printk(level, pt1, format, arg...) \
99 dev_printk(level, &(pt1)->pdev->dev, format, ##arg)
100
101static void pt1_write_reg(struct pt1 *pt1, int reg, u32 data)
102{
103 writel(data, pt1->regs + reg * 4);
104}
105
106static u32 pt1_read_reg(struct pt1 *pt1, int reg)
107{
108 return readl(pt1->regs + reg * 4);
109}
110
111static int pt1_nr_tables = 64;
112module_param_named(nr_tables, pt1_nr_tables, int, 0);
113
114static void pt1_increment_table_count(struct pt1 *pt1)
115{
116 pt1_write_reg(pt1, 0, 0x00000020);
117}
118
119static void pt1_init_table_count(struct pt1 *pt1)
120{
121 pt1_write_reg(pt1, 0, 0x00000010);
122}
123
124static void pt1_register_tables(struct pt1 *pt1, u32 first_pfn)
125{
126 pt1_write_reg(pt1, 5, first_pfn);
127 pt1_write_reg(pt1, 0, 0x0c000040);
128}
129
130static void pt1_unregister_tables(struct pt1 *pt1)
131{
132 pt1_write_reg(pt1, 0, 0x08080000);
133}
134
135static int pt1_sync(struct pt1 *pt1)
136{
137 int i;
138 for (i = 0; i < 57; i++) {
139 if (pt1_read_reg(pt1, 0) & 0x20000000)
140 return 0;
141 pt1_write_reg(pt1, 0, 0x00000008);
142 }
143 pt1_printk(KERN_ERR, pt1, "could not sync\n");
144 return -EIO;
145}
146
147static u64 pt1_identify(struct pt1 *pt1)
148{
149 int i;
150 u64 id;
151 id = 0;
152 for (i = 0; i < 57; i++) {
153 id |= (u64)(pt1_read_reg(pt1, 0) >> 30 & 1) << i;
154 pt1_write_reg(pt1, 0, 0x00000008);
155 }
156 return id;
157}
158
159static int pt1_unlock(struct pt1 *pt1)
160{
161 int i;
162 pt1_write_reg(pt1, 0, 0x00000008);
163 for (i = 0; i < 3; i++) {
164 if (pt1_read_reg(pt1, 0) & 0x80000000)
165 return 0;
166 schedule_timeout_uninterruptible((HZ + 999) / 1000);
167 }
168 pt1_printk(KERN_ERR, pt1, "could not unlock\n");
169 return -EIO;
170}
171
172static int pt1_reset_pci(struct pt1 *pt1)
173{
174 int i;
175 pt1_write_reg(pt1, 0, 0x01010000);
176 pt1_write_reg(pt1, 0, 0x01000000);
177 for (i = 0; i < 10; i++) {
178 if (pt1_read_reg(pt1, 0) & 0x00000001)
179 return 0;
180 schedule_timeout_uninterruptible((HZ + 999) / 1000);
181 }
182 pt1_printk(KERN_ERR, pt1, "could not reset PCI\n");
183 return -EIO;
184}
185
186static int pt1_reset_ram(struct pt1 *pt1)
187{
188 int i;
189 pt1_write_reg(pt1, 0, 0x02020000);
190 pt1_write_reg(pt1, 0, 0x02000000);
191 for (i = 0; i < 10; i++) {
192 if (pt1_read_reg(pt1, 0) & 0x00000002)
193 return 0;
194 schedule_timeout_uninterruptible((HZ + 999) / 1000);
195 }
196 pt1_printk(KERN_ERR, pt1, "could not reset RAM\n");
197 return -EIO;
198}
199
200static int pt1_do_enable_ram(struct pt1 *pt1)
201{
202 int i, j;
203 u32 status;
204 status = pt1_read_reg(pt1, 0) & 0x00000004;
205 pt1_write_reg(pt1, 0, 0x00000002);
206 for (i = 0; i < 10; i++) {
207 for (j = 0; j < 1024; j++) {
208 if ((pt1_read_reg(pt1, 0) & 0x00000004) != status)
209 return 0;
210 }
211 schedule_timeout_uninterruptible((HZ + 999) / 1000);
212 }
213 pt1_printk(KERN_ERR, pt1, "could not enable RAM\n");
214 return -EIO;
215}
216
217static int pt1_enable_ram(struct pt1 *pt1)
218{
219 int i, ret;
220 schedule_timeout_uninterruptible((HZ + 999) / 1000);
221 for (i = 0; i < 10; i++) {
222 ret = pt1_do_enable_ram(pt1);
223 if (ret < 0)
224 return ret;
225 }
226 return 0;
227}
228
229static void pt1_disable_ram(struct pt1 *pt1)
230{
231 pt1_write_reg(pt1, 0, 0x0b0b0000);
232}
233
234static void pt1_set_stream(struct pt1 *pt1, int index, int enabled)
235{
236 pt1_write_reg(pt1, 2, 1 << (index + 8) | enabled << index);
237}
238
239static void pt1_init_streams(struct pt1 *pt1)
240{
241 int i;
242 for (i = 0; i < PT1_NR_ADAPS; i++)
243 pt1_set_stream(pt1, i, 0);
244}
245
246static int pt1_filter(struct pt1 *pt1, struct pt1_buffer_page *page)
247{
248 u32 upacket;
249 int i;
250 int index;
251 struct pt1_adapter *adap;
252 int offset;
253 u8 *buf;
254
255 if (!page->upackets[PT1_NR_UPACKETS - 1])
256 return 0;
257
258 for (i = 0; i < PT1_NR_UPACKETS; i++) {
259 upacket = le32_to_cpu(page->upackets[i]);
260 index = (upacket >> 29) - 1;
261 if (index < 0 || index >= PT1_NR_ADAPS)
262 continue;
263
264 adap = pt1->adaps[index];
265 if (upacket >> 25 & 1)
266 adap->upacket_count = 0;
267 else if (!adap->upacket_count)
268 continue;
269
270 buf = adap->buf;
271 offset = adap->packet_count * 188 + adap->upacket_count * 3;
272 buf[offset] = upacket >> 16;
273 buf[offset + 1] = upacket >> 8;
274 if (adap->upacket_count != 62)
275 buf[offset + 2] = upacket;
276
277 if (++adap->upacket_count >= 63) {
278 adap->upacket_count = 0;
279 if (++adap->packet_count >= 21) {
280 dvb_dmx_swfilter_packets(&adap->demux, buf, 21);
281 adap->packet_count = 0;
282 }
283 }
284 }
285
286 page->upackets[PT1_NR_UPACKETS - 1] = 0;
287 return 1;
288}
289
290static int pt1_thread(void *data)
291{
292 struct pt1 *pt1;
293 int table_index;
294 int buf_index;
295 struct pt1_buffer_page *page;
296
297 pt1 = data;
298 set_freezable();
299
300 table_index = 0;
301 buf_index = 0;
302
303 while (!kthread_should_stop()) {
304 try_to_freeze();
305
306 page = pt1->tables[table_index].bufs[buf_index].page;
307 if (!pt1_filter(pt1, page)) {
308 schedule_timeout_interruptible((HZ + 999) / 1000);
309 continue;
310 }
311
312 if (++buf_index >= PT1_NR_BUFS) {
313 pt1_increment_table_count(pt1);
314 buf_index = 0;
315 if (++table_index >= pt1_nr_tables)
316 table_index = 0;
317 }
318 }
319
320 return 0;
321}
322
323static void pt1_free_page(struct pt1 *pt1, void *page, dma_addr_t addr)
324{
325 dma_free_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, page, addr);
326}
327
328static void *pt1_alloc_page(struct pt1 *pt1, dma_addr_t *addrp, u32 *pfnp)
329{
330 void *page;
331 dma_addr_t addr;
332
333 page = dma_alloc_coherent(&pt1->pdev->dev, PT1_PAGE_SIZE, &addr,
334 GFP_KERNEL);
335 if (page == NULL)
336 return NULL;
337
338 BUG_ON(addr & (PT1_PAGE_SIZE - 1));
339 BUG_ON(addr >> PT1_PAGE_SHIFT >> 31 >> 1);
340
341 *addrp = addr;
342 *pfnp = addr >> PT1_PAGE_SHIFT;
343 return page;
344}
345
346static void pt1_cleanup_buffer(struct pt1 *pt1, struct pt1_buffer *buf)
347{
348 pt1_free_page(pt1, buf->page, buf->addr);
349}
350
351static int
352pt1_init_buffer(struct pt1 *pt1, struct pt1_buffer *buf, u32 *pfnp)
353{
354 struct pt1_buffer_page *page;
355 dma_addr_t addr;
356
357 page = pt1_alloc_page(pt1, &addr, pfnp);
358 if (page == NULL)
359 return -ENOMEM;
360
361 page->upackets[PT1_NR_UPACKETS - 1] = 0;
362
363 buf->page = page;
364 buf->addr = addr;
365 return 0;
366}
367
368static void pt1_cleanup_table(struct pt1 *pt1, struct pt1_table *table)
369{
370 int i;
371
372 for (i = 0; i < PT1_NR_BUFS; i++)
373 pt1_cleanup_buffer(pt1, &table->bufs[i]);
374
375 pt1_free_page(pt1, table->page, table->addr);
376}
377
378static int
379pt1_init_table(struct pt1 *pt1, struct pt1_table *table, u32 *pfnp)
380{
381 struct pt1_table_page *page;
382 dma_addr_t addr;
383 int i, ret;
384 u32 buf_pfn;
385
386 page = pt1_alloc_page(pt1, &addr, pfnp);
387 if (page == NULL)
388 return -ENOMEM;
389
390 for (i = 0; i < PT1_NR_BUFS; i++) {
391 ret = pt1_init_buffer(pt1, &table->bufs[i], &buf_pfn);
392 if (ret < 0)
393 goto err;
394
395 page->buf_pfns[i] = cpu_to_le32(buf_pfn);
396 }
397
398 pt1_increment_table_count(pt1);
399 table->page = page;
400 table->addr = addr;
401 return 0;
402
403err:
404 while (i--)
405 pt1_cleanup_buffer(pt1, &table->bufs[i]);
406
407 pt1_free_page(pt1, page, addr);
408 return ret;
409}
410
411static void pt1_cleanup_tables(struct pt1 *pt1)
412{
413 struct pt1_table *tables;
414 int i;
415
416 tables = pt1->tables;
417 pt1_unregister_tables(pt1);
418
419 for (i = 0; i < pt1_nr_tables; i++)
420 pt1_cleanup_table(pt1, &tables[i]);
421
422 vfree(tables);
423}
424
425static int pt1_init_tables(struct pt1 *pt1)
426{
427 struct pt1_table *tables;
428 int i, ret;
429 u32 first_pfn, pfn;
430
431 tables = vmalloc(sizeof(struct pt1_table) * pt1_nr_tables);
432 if (tables == NULL)
433 return -ENOMEM;
434
435 pt1_init_table_count(pt1);
436
437 i = 0;
438 if (pt1_nr_tables) {
439 ret = pt1_init_table(pt1, &tables[0], &first_pfn);
440 if (ret)
441 goto err;
442 i++;
443 }
444
445 while (i < pt1_nr_tables) {
446 ret = pt1_init_table(pt1, &tables[i], &pfn);
447 if (ret)
448 goto err;
449 tables[i - 1].page->next_pfn = cpu_to_le32(pfn);
450 i++;
451 }
452
453 tables[pt1_nr_tables - 1].page->next_pfn = cpu_to_le32(first_pfn);
454
455 pt1_register_tables(pt1, first_pfn);
456 pt1->tables = tables;
457 return 0;
458
459err:
460 while (i--)
461 pt1_cleanup_table(pt1, &tables[i]);
462
463 vfree(tables);
464 return ret;
465}
466
467static int pt1_start_feed(struct dvb_demux_feed *feed)
468{
469 struct pt1_adapter *adap;
470 adap = container_of(feed->demux, struct pt1_adapter, demux);
471 if (!adap->users++)
472 pt1_set_stream(adap->pt1, adap->index, 1);
473 return 0;
474}
475
476static int pt1_stop_feed(struct dvb_demux_feed *feed)
477{
478 struct pt1_adapter *adap;
479 adap = container_of(feed->demux, struct pt1_adapter, demux);
480 if (!--adap->users)
481 pt1_set_stream(adap->pt1, adap->index, 0);
482 return 0;
483}
484
485static void
486pt1_set_power(struct pt1 *pt1, int power, int lnb, int reset)
487{
488 pt1_write_reg(pt1, 1, power | lnb << 1 | !reset << 3);
489}
490
491static int pt1_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
492{
493 struct pt1_adapter *adap;
494 int lnb;
495
496 adap = container_of(fe->dvb, struct pt1_adapter, adap);
497
498 switch (voltage) {
499 case SEC_VOLTAGE_13: /* actually 11V */
500 lnb = 2;
501 break;
502 case SEC_VOLTAGE_18: /* actually 15V */
503 lnb = 3;
504 break;
505 case SEC_VOLTAGE_OFF:
506 lnb = 0;
507 break;
508 default:
509 return -EINVAL;
510 }
511
512 pt1_set_power(adap->pt1, 1, lnb, 0);
513
514 if (adap->orig_set_voltage)
515 return adap->orig_set_voltage(fe, voltage);
516 else
517 return 0;
518}
519
520static void pt1_free_adapter(struct pt1_adapter *adap)
521{
522 dvb_unregister_frontend(adap->fe);
523 dvb_net_release(&adap->net);
524 adap->demux.dmx.close(&adap->demux.dmx);
525 dvb_dmxdev_release(&adap->dmxdev);
526 dvb_dmx_release(&adap->demux);
527 dvb_unregister_adapter(&adap->adap);
528 free_page((unsigned long)adap->buf);
529 kfree(adap);
530}
531
532DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
533
534static struct pt1_adapter *
535pt1_alloc_adapter(struct pt1 *pt1, struct dvb_frontend *fe)
536{
537 struct pt1_adapter *adap;
538 void *buf;
539 struct dvb_adapter *dvb_adap;
540 struct dvb_demux *demux;
541 struct dmxdev *dmxdev;
542 int ret;
543
544 adap = kzalloc(sizeof(struct pt1_adapter), GFP_KERNEL);
545 if (!adap) {
546 ret = -ENOMEM;
547 goto err;
548 }
549
550 adap->pt1 = pt1;
551
552 adap->orig_set_voltage = fe->ops.set_voltage;
553 fe->ops.set_voltage = pt1_set_voltage;
554
555 buf = (u8 *)__get_free_page(GFP_KERNEL);
556 if (!buf) {
557 ret = -ENOMEM;
558 goto err_kfree;
559 }
560
561 adap->buf = buf;
562 adap->upacket_count = 0;
563 adap->packet_count = 0;
564
565 dvb_adap = &adap->adap;
566 dvb_adap->priv = adap;
567 ret = dvb_register_adapter(dvb_adap, DRIVER_NAME, THIS_MODULE,
568 &pt1->pdev->dev, adapter_nr);
569 if (ret < 0)
570 goto err_free_page;
571
572 demux = &adap->demux;
573 demux->dmx.capabilities = DMX_TS_FILTERING | DMX_SECTION_FILTERING;
574 demux->priv = adap;
575 demux->feednum = 256;
576 demux->filternum = 256;
577 demux->start_feed = pt1_start_feed;
578 demux->stop_feed = pt1_stop_feed;
579 demux->write_to_decoder = NULL;
580 ret = dvb_dmx_init(demux);
581 if (ret < 0)
582 goto err_unregister_adapter;
583
584 dmxdev = &adap->dmxdev;
585 dmxdev->filternum = 256;
586 dmxdev->demux = &demux->dmx;
587 dmxdev->capabilities = 0;
588 ret = dvb_dmxdev_init(dmxdev, dvb_adap);
589 if (ret < 0)
590 goto err_dmx_release;
591
592 dvb_net_init(dvb_adap, &adap->net, &demux->dmx);
593
594 ret = dvb_register_frontend(dvb_adap, fe);
595 if (ret < 0)
596 goto err_net_release;
597 adap->fe = fe;
598
599 return adap;
600
601err_net_release:
602 dvb_net_release(&adap->net);
603 adap->demux.dmx.close(&adap->demux.dmx);
604 dvb_dmxdev_release(&adap->dmxdev);
605err_dmx_release:
606 dvb_dmx_release(demux);
607err_unregister_adapter:
608 dvb_unregister_adapter(dvb_adap);
609err_free_page:
610 free_page((unsigned long)buf);
611err_kfree:
612 kfree(adap);
613err:
614 return ERR_PTR(ret);
615}
616
617static void pt1_cleanup_adapters(struct pt1 *pt1)
618{
619 int i;
620 for (i = 0; i < PT1_NR_ADAPS; i++)
621 pt1_free_adapter(pt1->adaps[i]);
622}
623
624struct pt1_config {
625 struct va1j5jf8007s_config va1j5jf8007s_config;
626 struct va1j5jf8007t_config va1j5jf8007t_config;
627};
628
629static const struct pt1_config pt1_configs[2] = {
630 {
631 { .demod_address = 0x1b },
632 { .demod_address = 0x1a },
633 }, {
634 { .demod_address = 0x19 },
635 { .demod_address = 0x18 },
636 },
637};
638
639static int pt1_init_adapters(struct pt1 *pt1)
640{
641 int i, j;
642 struct i2c_adapter *i2c_adap;
643 const struct pt1_config *config;
644 struct dvb_frontend *fe[4];
645 struct pt1_adapter *adap;
646 int ret;
647
648 i = 0;
649 j = 0;
650
651 i2c_adap = &pt1->i2c_adap;
652 do {
653 config = &pt1_configs[i / 2];
654
655 fe[i] = va1j5jf8007s_attach(&config->va1j5jf8007s_config,
656 i2c_adap);
657 if (!fe[i]) {
658 ret = -ENODEV; /* This does not sound nice... */
659 goto err;
660 }
661 i++;
662
663 fe[i] = va1j5jf8007t_attach(&config->va1j5jf8007t_config,
664 i2c_adap);
665 if (!fe[i]) {
666 ret = -ENODEV;
667 goto err;
668 }
669 i++;
670
671 ret = va1j5jf8007s_prepare(fe[i - 2]);
672 if (ret < 0)
673 goto err;
674
675 ret = va1j5jf8007t_prepare(fe[i - 1]);
676 if (ret < 0)
677 goto err;
678
679 } while (i < 4);
680
681 do {
682 adap = pt1_alloc_adapter(pt1, fe[j]);
683 if (IS_ERR(adap))
684 goto err;
685 adap->index = j;
686 pt1->adaps[j] = adap;
687 } while (++j < 4);
688
689 return 0;
690
691err:
692 while (i-- > j)
693 fe[i]->ops.release(fe[i]);
694
695 while (j--)
696 pt1_free_adapter(pt1->adaps[j]);
697
698 return ret;
699}
700
701static void pt1_i2c_emit(struct pt1 *pt1, int addr, int busy, int read_enable,
702 int clock, int data, int next_addr)
703{
704 pt1_write_reg(pt1, 4, addr << 18 | busy << 13 | read_enable << 12 |
705 !clock << 11 | !data << 10 | next_addr);
706}
707
708static void pt1_i2c_write_bit(struct pt1 *pt1, int addr, int *addrp, int data)
709{
710 pt1_i2c_emit(pt1, addr, 1, 0, 0, data, addr + 1);
711 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, data, addr + 2);
712 pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, data, addr + 3);
713 *addrp = addr + 3;
714}
715
716static void pt1_i2c_read_bit(struct pt1 *pt1, int addr, int *addrp)
717{
718 pt1_i2c_emit(pt1, addr, 1, 0, 0, 1, addr + 1);
719 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 1, addr + 2);
720 pt1_i2c_emit(pt1, addr + 2, 1, 1, 1, 1, addr + 3);
721 pt1_i2c_emit(pt1, addr + 3, 1, 0, 0, 1, addr + 4);
722 *addrp = addr + 4;
723}
724
725static void pt1_i2c_write_byte(struct pt1 *pt1, int addr, int *addrp, int data)
726{
727 int i;
728 for (i = 0; i < 8; i++)
729 pt1_i2c_write_bit(pt1, addr, &addr, data >> (7 - i) & 1);
730 pt1_i2c_write_bit(pt1, addr, &addr, 1);
731 *addrp = addr;
732}
733
734static void pt1_i2c_read_byte(struct pt1 *pt1, int addr, int *addrp, int last)
735{
736 int i;
737 for (i = 0; i < 8; i++)
738 pt1_i2c_read_bit(pt1, addr, &addr);
739 pt1_i2c_write_bit(pt1, addr, &addr, last);
740 *addrp = addr;
741}
742
743static void pt1_i2c_prepare(struct pt1 *pt1, int addr, int *addrp)
744{
745 pt1_i2c_emit(pt1, addr, 1, 0, 1, 1, addr + 1);
746 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
747 pt1_i2c_emit(pt1, addr + 2, 1, 0, 0, 0, addr + 3);
748 *addrp = addr + 3;
749}
750
751static void
752pt1_i2c_write_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
753{
754 int i;
755 pt1_i2c_prepare(pt1, addr, &addr);
756 pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1);
757 for (i = 0; i < msg->len; i++)
758 pt1_i2c_write_byte(pt1, addr, &addr, msg->buf[i]);
759 *addrp = addr;
760}
761
762static void
763pt1_i2c_read_msg(struct pt1 *pt1, int addr, int *addrp, struct i2c_msg *msg)
764{
765 int i;
766 pt1_i2c_prepare(pt1, addr, &addr);
767 pt1_i2c_write_byte(pt1, addr, &addr, msg->addr << 1 | 1);
768 for (i = 0; i < msg->len; i++)
769 pt1_i2c_read_byte(pt1, addr, &addr, i == msg->len - 1);
770 *addrp = addr;
771}
772
773static int pt1_i2c_end(struct pt1 *pt1, int addr)
774{
775 pt1_i2c_emit(pt1, addr, 1, 0, 0, 0, addr + 1);
776 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
777 pt1_i2c_emit(pt1, addr + 2, 1, 0, 1, 1, 0);
778
779 pt1_write_reg(pt1, 0, 0x00000004);
780 do {
781 if (signal_pending(current))
782 return -EINTR;
783 schedule_timeout_interruptible((HZ + 999) / 1000);
784 } while (pt1_read_reg(pt1, 0) & 0x00000080);
785 return 0;
786}
787
788static void pt1_i2c_begin(struct pt1 *pt1, int *addrp)
789{
790 int addr;
791 addr = 0;
792
793 pt1_i2c_emit(pt1, addr, 0, 0, 1, 1, addr /* itself */);
794 addr = addr + 1;
795
796 if (!pt1->i2c_running) {
797 pt1_i2c_emit(pt1, addr, 1, 0, 1, 1, addr + 1);
798 pt1_i2c_emit(pt1, addr + 1, 1, 0, 1, 0, addr + 2);
799 addr = addr + 2;
800 pt1->i2c_running = 1;
801 }
802 *addrp = addr;
803}
804
805static int pt1_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
806{
807 struct pt1 *pt1;
808 int i;
809 struct i2c_msg *msg, *next_msg;
810 int addr, ret;
811 u16 len;
812 u32 word;
813
814 pt1 = i2c_get_adapdata(adap);
815
816 for (i = 0; i < num; i++) {
817 msg = &msgs[i];
818 if (msg->flags & I2C_M_RD)
819 return -ENOTSUPP;
820
821 if (i + 1 < num)
822 next_msg = &msgs[i + 1];
823 else
824 next_msg = NULL;
825
826 if (next_msg && next_msg->flags & I2C_M_RD) {
827 i++;
828
829 len = next_msg->len;
830 if (len > 4)
831 return -ENOTSUPP;
832
833 pt1_i2c_begin(pt1, &addr);
834 pt1_i2c_write_msg(pt1, addr, &addr, msg);
835 pt1_i2c_read_msg(pt1, addr, &addr, next_msg);
836 ret = pt1_i2c_end(pt1, addr);
837 if (ret < 0)
838 return ret;
839
840 word = pt1_read_reg(pt1, 2);
841 while (len--) {
842 next_msg->buf[len] = word;
843 word >>= 8;
844 }
845 } else {
846 pt1_i2c_begin(pt1, &addr);
847 pt1_i2c_write_msg(pt1, addr, &addr, msg);
848 ret = pt1_i2c_end(pt1, addr);
849 if (ret < 0)
850 return ret;
851 }
852 }
853
854 return num;
855}
856
857static u32 pt1_i2c_func(struct i2c_adapter *adap)
858{
859 return I2C_FUNC_I2C;
860}
861
862static const struct i2c_algorithm pt1_i2c_algo = {
863 .master_xfer = pt1_i2c_xfer,
864 .functionality = pt1_i2c_func,
865};
866
867static void pt1_i2c_wait(struct pt1 *pt1)
868{
869 int i;
870 for (i = 0; i < 128; i++)
871 pt1_i2c_emit(pt1, 0, 0, 0, 1, 1, 0);
872}
873
874static void pt1_i2c_init(struct pt1 *pt1)
875{
876 int i;
877 for (i = 0; i < 1024; i++)
878 pt1_i2c_emit(pt1, i, 0, 0, 1, 1, 0);
879}
880
881static void __devexit pt1_remove(struct pci_dev *pdev)
882{
883 struct pt1 *pt1;
884 void __iomem *regs;
885
886 pt1 = pci_get_drvdata(pdev);
887 regs = pt1->regs;
888
889 kthread_stop(pt1->kthread);
890 pt1_cleanup_tables(pt1);
891 pt1_cleanup_adapters(pt1);
892 pt1_disable_ram(pt1);
893 pt1_set_power(pt1, 0, 0, 1);
894 i2c_del_adapter(&pt1->i2c_adap);
895 pci_set_drvdata(pdev, NULL);
896 kfree(pt1);
897 pci_iounmap(pdev, regs);
898 pci_release_regions(pdev);
899 pci_disable_device(pdev);
900}
901
902static int __devinit
903pt1_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
904{
905 int ret;
906 void __iomem *regs;
907 struct pt1 *pt1;
908 struct i2c_adapter *i2c_adap;
909 struct task_struct *kthread;
910
911 ret = pci_enable_device(pdev);
912 if (ret < 0)
913 goto err;
914
915 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
916 if (ret < 0)
917 goto err_pci_disable_device;
918
919 pci_set_master(pdev);
920
921 ret = pci_request_regions(pdev, DRIVER_NAME);
922 if (ret < 0)
923 goto err_pci_disable_device;
924
925 regs = pci_iomap(pdev, 0, 0);
926 if (!regs) {
927 ret = -EIO;
928 goto err_pci_release_regions;
929 }
930
931 pt1 = kzalloc(sizeof(struct pt1), GFP_KERNEL);
932 if (!pt1) {
933 ret = -ENOMEM;
934 goto err_pci_iounmap;
935 }
936
937 pt1->pdev = pdev;
938 pt1->regs = regs;
939 pci_set_drvdata(pdev, pt1);
940
941 i2c_adap = &pt1->i2c_adap;
942 i2c_adap->class = I2C_CLASS_TV_DIGITAL;
943 i2c_adap->algo = &pt1_i2c_algo;
944 i2c_adap->algo_data = NULL;
945 i2c_adap->dev.parent = &pdev->dev;
946 i2c_set_adapdata(i2c_adap, pt1);
947 ret = i2c_add_adapter(i2c_adap);
948 if (ret < 0)
949 goto err_kfree;
950
951 pt1_set_power(pt1, 0, 0, 1);
952
953 pt1_i2c_init(pt1);
954 pt1_i2c_wait(pt1);
955
956 ret = pt1_sync(pt1);
957 if (ret < 0)
958 goto err_i2c_del_adapter;
959
960 pt1_identify(pt1);
961
962 ret = pt1_unlock(pt1);
963 if (ret < 0)
964 goto err_i2c_del_adapter;
965
966 ret = pt1_reset_pci(pt1);
967 if (ret < 0)
968 goto err_i2c_del_adapter;
969
970 ret = pt1_reset_ram(pt1);
971 if (ret < 0)
972 goto err_i2c_del_adapter;
973
974 ret = pt1_enable_ram(pt1);
975 if (ret < 0)
976 goto err_i2c_del_adapter;
977
978 pt1_init_streams(pt1);
979
980 pt1_set_power(pt1, 1, 0, 1);
981 schedule_timeout_uninterruptible((HZ + 49) / 50);
982
983 pt1_set_power(pt1, 1, 0, 0);
984 schedule_timeout_uninterruptible((HZ + 999) / 1000);
985
986 ret = pt1_init_adapters(pt1);
987 if (ret < 0)
988 goto err_pt1_disable_ram;
989
990 ret = pt1_init_tables(pt1);
991 if (ret < 0)
992 goto err_pt1_cleanup_adapters;
993
994 kthread = kthread_run(pt1_thread, pt1, "pt1");
995 if (IS_ERR(kthread)) {
996 ret = PTR_ERR(kthread);
997 goto err_pt1_cleanup_tables;
998 }
999
1000 pt1->kthread = kthread;
1001 return 0;
1002
1003err_pt1_cleanup_tables:
1004 pt1_cleanup_tables(pt1);
1005err_pt1_cleanup_adapters:
1006 pt1_cleanup_adapters(pt1);
1007err_pt1_disable_ram:
1008 pt1_disable_ram(pt1);
1009 pt1_set_power(pt1, 0, 0, 1);
1010err_i2c_del_adapter:
1011 i2c_del_adapter(i2c_adap);
1012err_kfree:
1013 pci_set_drvdata(pdev, NULL);
1014 kfree(pt1);
1015err_pci_iounmap:
1016 pci_iounmap(pdev, regs);
1017err_pci_release_regions:
1018 pci_release_regions(pdev);
1019err_pci_disable_device:
1020 pci_disable_device(pdev);
1021err:
1022 return ret;
1023
1024}
1025
1026static struct pci_device_id pt1_id_table[] = {
1027 { PCI_DEVICE(0x10ee, 0x211a) },
1028 { },
1029};
1030MODULE_DEVICE_TABLE(pci, pt1_id_table);
1031
1032static struct pci_driver pt1_driver = {
1033 .name = DRIVER_NAME,
1034 .probe = pt1_probe,
1035 .remove = __devexit_p(pt1_remove),
1036 .id_table = pt1_id_table,
1037};
1038
1039
1040static int __init pt1_init(void)
1041{
1042 return pci_register_driver(&pt1_driver);
1043}
1044
1045
1046static void __exit pt1_cleanup(void)
1047{
1048 pci_unregister_driver(&pt1_driver);
1049}
1050
1051module_init(pt1_init);
1052module_exit(pt1_cleanup);
1053
1054MODULE_AUTHOR("Takahito HIRANO <hiranotaka@zng.info>");
1055MODULE_DESCRIPTION("Earthsoft PT1 Driver");
1056MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.c b/drivers/media/dvb/pt1/va1j5jf8007s.c
new file mode 100644
index 000000000000..2db940f8635f
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.c
@@ -0,0 +1,658 @@
1/*
2 * ISDB-S driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include "dvb_frontend.h"
29#include "va1j5jf8007s.h"
30
31enum va1j5jf8007s_tune_state {
32 VA1J5JF8007S_IDLE,
33 VA1J5JF8007S_SET_FREQUENCY_1,
34 VA1J5JF8007S_SET_FREQUENCY_2,
35 VA1J5JF8007S_SET_FREQUENCY_3,
36 VA1J5JF8007S_CHECK_FREQUENCY,
37 VA1J5JF8007S_SET_MODULATION,
38 VA1J5JF8007S_CHECK_MODULATION,
39 VA1J5JF8007S_SET_TS_ID,
40 VA1J5JF8007S_CHECK_TS_ID,
41 VA1J5JF8007S_TRACK,
42};
43
44struct va1j5jf8007s_state {
45 const struct va1j5jf8007s_config *config;
46 struct i2c_adapter *adap;
47 struct dvb_frontend fe;
48 enum va1j5jf8007s_tune_state tune_state;
49};
50
51static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
52{
53 return DVBFE_ALGO_HW;
54}
55
56static int
57va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
58{
59 struct va1j5jf8007s_state *state;
60
61 state = fe->demodulator_priv;
62
63 switch (state->tune_state) {
64 case VA1J5JF8007S_IDLE:
65 case VA1J5JF8007S_SET_FREQUENCY_1:
66 case VA1J5JF8007S_SET_FREQUENCY_2:
67 case VA1J5JF8007S_SET_FREQUENCY_3:
68 case VA1J5JF8007S_CHECK_FREQUENCY:
69 *status = 0;
70 return 0;
71
72
73 case VA1J5JF8007S_SET_MODULATION:
74 case VA1J5JF8007S_CHECK_MODULATION:
75 *status |= FE_HAS_SIGNAL;
76 return 0;
77
78 case VA1J5JF8007S_SET_TS_ID:
79 case VA1J5JF8007S_CHECK_TS_ID:
80 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
81 return 0;
82
83 case VA1J5JF8007S_TRACK:
84 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
85 return 0;
86 }
87
88 BUG();
89}
90
91struct va1j5jf8007s_cb_map {
92 u32 frequency;
93 u8 cb;
94};
95
96static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
97 { 986000, 0xb2 },
98 { 1072000, 0xd2 },
99 { 1154000, 0xe2 },
100 { 1291000, 0x20 },
101 { 1447000, 0x40 },
102 { 1615000, 0x60 },
103 { 1791000, 0x80 },
104 { 1972000, 0xa0 },
105};
106
107static u8 va1j5jf8007s_lookup_cb(u32 frequency)
108{
109 int i;
110 const struct va1j5jf8007s_cb_map *map;
111
112 for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
113 map = &va1j5jf8007s_cb_maps[i];
114 if (frequency < map->frequency)
115 return map->cb;
116 }
117 return 0xc0;
118}
119
120static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
121{
122 u32 frequency;
123 u16 word;
124 u8 buf[6];
125 struct i2c_msg msg;
126
127 frequency = state->fe.dtv_property_cache.frequency;
128
129 word = (frequency + 500) / 1000;
130 if (frequency < 1072000)
131 word = (word << 1 & ~0x1f) | (word & 0x0f);
132
133 buf[0] = 0xfe;
134 buf[1] = 0xc0;
135 buf[2] = 0x40 | word >> 8;
136 buf[3] = word;
137 buf[4] = 0xe0;
138 buf[5] = va1j5jf8007s_lookup_cb(frequency);
139
140 msg.addr = state->config->demod_address;
141 msg.flags = 0;
142 msg.len = sizeof(buf);
143 msg.buf = buf;
144
145 if (i2c_transfer(state->adap, &msg, 1) != 1)
146 return -EREMOTEIO;
147
148 return 0;
149}
150
151static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
152{
153 u8 buf[3];
154 struct i2c_msg msg;
155
156 buf[0] = 0xfe;
157 buf[1] = 0xc0;
158 buf[2] = 0xe4;
159
160 msg.addr = state->config->demod_address;
161 msg.flags = 0;
162 msg.len = sizeof(buf);
163 msg.buf = buf;
164
165 if (i2c_transfer(state->adap, &msg, 1) != 1)
166 return -EREMOTEIO;
167
168 return 0;
169}
170
171static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
172{
173 u32 frequency;
174 u8 buf[4];
175 struct i2c_msg msg;
176
177 frequency = state->fe.dtv_property_cache.frequency;
178
179 buf[0] = 0xfe;
180 buf[1] = 0xc0;
181 buf[2] = 0xf4;
182 buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
183
184 msg.addr = state->config->demod_address;
185 msg.flags = 0;
186 msg.len = sizeof(buf);
187 msg.buf = buf;
188
189 if (i2c_transfer(state->adap, &msg, 1) != 1)
190 return -EREMOTEIO;
191
192 return 0;
193}
194
195static int
196va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
197{
198 u8 addr;
199 u8 write_buf[2], read_buf[1];
200 struct i2c_msg msgs[2];
201
202 addr = state->config->demod_address;
203
204 write_buf[0] = 0xfe;
205 write_buf[1] = 0xc1;
206
207 msgs[0].addr = addr;
208 msgs[0].flags = 0;
209 msgs[0].len = sizeof(write_buf);
210 msgs[0].buf = write_buf;
211
212 msgs[1].addr = addr;
213 msgs[1].flags = I2C_M_RD;
214 msgs[1].len = sizeof(read_buf);
215 msgs[1].buf = read_buf;
216
217 if (i2c_transfer(state->adap, msgs, 2) != 2)
218 return -EREMOTEIO;
219
220 *lock = read_buf[0] & 0x40;
221 return 0;
222}
223
224static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
225{
226 u8 buf[2];
227 struct i2c_msg msg;
228
229 buf[0] = 0x03;
230 buf[1] = 0x01;
231
232 msg.addr = state->config->demod_address;
233 msg.flags = 0;
234 msg.len = sizeof(buf);
235 msg.buf = buf;
236
237 if (i2c_transfer(state->adap, &msg, 1) != 1)
238 return -EREMOTEIO;
239
240 return 0;
241}
242
243static int
244va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
245{
246 u8 addr;
247 u8 write_buf[1], read_buf[1];
248 struct i2c_msg msgs[2];
249
250 addr = state->config->demod_address;
251
252 write_buf[0] = 0xc3;
253
254 msgs[0].addr = addr;
255 msgs[0].flags = 0;
256 msgs[0].len = sizeof(write_buf);
257 msgs[0].buf = write_buf;
258
259 msgs[1].addr = addr;
260 msgs[1].flags = I2C_M_RD;
261 msgs[1].len = sizeof(read_buf);
262 msgs[1].buf = read_buf;
263
264 if (i2c_transfer(state->adap, msgs, 2) != 2)
265 return -EREMOTEIO;
266
267 *lock = !(read_buf[0] & 0x10);
268 return 0;
269}
270
271static int
272va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
273{
274 u32 ts_id;
275 u8 buf[3];
276 struct i2c_msg msg;
277
278 ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
279 if (!ts_id)
280 return 0;
281
282 buf[0] = 0x8f;
283 buf[1] = ts_id >> 8;
284 buf[2] = ts_id;
285
286 msg.addr = state->config->demod_address;
287 msg.flags = 0;
288 msg.len = sizeof(buf);
289 msg.buf = buf;
290
291 if (i2c_transfer(state->adap, &msg, 1) != 1)
292 return -EREMOTEIO;
293
294 return 0;
295}
296
297static int
298va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
299{
300 u8 addr;
301 u8 write_buf[1], read_buf[2];
302 struct i2c_msg msgs[2];
303 u32 ts_id;
304
305 ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
306 if (!ts_id) {
307 *lock = 1;
308 return 0;
309 }
310
311 addr = state->config->demod_address;
312
313 write_buf[0] = 0xe6;
314
315 msgs[0].addr = addr;
316 msgs[0].flags = 0;
317 msgs[0].len = sizeof(write_buf);
318 msgs[0].buf = write_buf;
319
320 msgs[1].addr = addr;
321 msgs[1].flags = I2C_M_RD;
322 msgs[1].len = sizeof(read_buf);
323 msgs[1].buf = read_buf;
324
325 if (i2c_transfer(state->adap, msgs, 2) != 2)
326 return -EREMOTEIO;
327
328 *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
329 return 0;
330}
331
332static int
333va1j5jf8007s_tune(struct dvb_frontend *fe,
334 struct dvb_frontend_parameters *params,
335 unsigned int mode_flags, unsigned int *delay,
336 fe_status_t *status)
337{
338 struct va1j5jf8007s_state *state;
339 int ret;
340 int lock;
341
342 state = fe->demodulator_priv;
343
344 if (params != NULL)
345 state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1;
346
347 switch (state->tune_state) {
348 case VA1J5JF8007S_IDLE:
349 *delay = 3 * HZ;
350 *status = 0;
351 return 0;
352
353 case VA1J5JF8007S_SET_FREQUENCY_1:
354 ret = va1j5jf8007s_set_frequency_1(state);
355 if (ret < 0)
356 return ret;
357
358 state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2;
359 *delay = 0;
360 *status = 0;
361 return 0;
362
363 case VA1J5JF8007S_SET_FREQUENCY_2:
364 ret = va1j5jf8007s_set_frequency_2(state);
365 if (ret < 0)
366 return ret;
367
368 state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3;
369 *delay = (HZ + 99) / 100;
370 *status = 0;
371 return 0;
372
373 case VA1J5JF8007S_SET_FREQUENCY_3:
374 ret = va1j5jf8007s_set_frequency_3(state);
375 if (ret < 0)
376 return ret;
377
378 state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY;
379 *delay = 0;
380 *status = 0;
381 return 0;
382
383 case VA1J5JF8007S_CHECK_FREQUENCY:
384 ret = va1j5jf8007s_check_frequency(state, &lock);
385 if (ret < 0)
386 return ret;
387
388 if (!lock) {
389 *delay = (HZ + 999) / 1000;
390 *status = 0;
391 return 0;
392 }
393
394 state->tune_state = VA1J5JF8007S_SET_MODULATION;
395 *delay = 0;
396 *status = FE_HAS_SIGNAL;
397 return 0;
398
399 case VA1J5JF8007S_SET_MODULATION:
400 ret = va1j5jf8007s_set_modulation(state);
401 if (ret < 0)
402 return ret;
403
404 state->tune_state = VA1J5JF8007S_CHECK_MODULATION;
405 *delay = 0;
406 *status = FE_HAS_SIGNAL;
407 return 0;
408
409 case VA1J5JF8007S_CHECK_MODULATION:
410 ret = va1j5jf8007s_check_modulation(state, &lock);
411 if (ret < 0)
412 return ret;
413
414 if (!lock) {
415 *delay = (HZ + 49) / 50;
416 *status = FE_HAS_SIGNAL;
417 return 0;
418 }
419
420 state->tune_state = VA1J5JF8007S_SET_TS_ID;
421 *delay = 0;
422 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
423 return 0;
424
425 case VA1J5JF8007S_SET_TS_ID:
426 ret = va1j5jf8007s_set_ts_id(state);
427 if (ret < 0)
428 return ret;
429
430 state->tune_state = VA1J5JF8007S_CHECK_TS_ID;
431 return 0;
432
433 case VA1J5JF8007S_CHECK_TS_ID:
434 ret = va1j5jf8007s_check_ts_id(state, &lock);
435 if (ret < 0)
436 return ret;
437
438 if (!lock) {
439 *delay = (HZ + 99) / 100;
440 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
441 return 0;
442 }
443
444 state->tune_state = VA1J5JF8007S_TRACK;
445 /* fall through */
446
447 case VA1J5JF8007S_TRACK:
448 *delay = 3 * HZ;
449 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
450 return 0;
451 }
452
453 BUG();
454}
455
456static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
457{
458 u8 buf[4];
459 struct i2c_msg msg;
460
461 buf[0] = 0xfe;
462 buf[1] = 0xc0;
463 buf[2] = 0xf0;
464 buf[3] = 0x04;
465
466 msg.addr = state->config->demod_address;
467 msg.flags = 0;
468 msg.len = sizeof(buf);
469 msg.buf = buf;
470
471 if (i2c_transfer(state->adap, &msg, 1) != 1)
472 return -EREMOTEIO;
473
474 return 0;
475}
476
477static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
478{
479 u8 buf[2];
480 struct i2c_msg msg;
481
482 buf[0] = 0x17;
483 buf[1] = sleep ? 0x01 : 0x00;
484
485 msg.addr = state->config->demod_address;
486 msg.flags = 0;
487 msg.len = sizeof(buf);
488 msg.buf = buf;
489
490 if (i2c_transfer(state->adap, &msg, 1) != 1)
491 return -EREMOTEIO;
492
493 return 0;
494}
495
496static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
497{
498 struct va1j5jf8007s_state *state;
499 int ret;
500
501 state = fe->demodulator_priv;
502
503 ret = va1j5jf8007s_init_frequency(state);
504 if (ret < 0)
505 return ret;
506
507 return va1j5jf8007s_set_sleep(state, 1);
508}
509
510static int va1j5jf8007s_init(struct dvb_frontend *fe)
511{
512 struct va1j5jf8007s_state *state;
513
514 state = fe->demodulator_priv;
515 state->tune_state = VA1J5JF8007S_IDLE;
516
517 return va1j5jf8007s_set_sleep(state, 0);
518}
519
520static void va1j5jf8007s_release(struct dvb_frontend *fe)
521{
522 struct va1j5jf8007s_state *state;
523 state = fe->demodulator_priv;
524 kfree(state);
525}
526
527static struct dvb_frontend_ops va1j5jf8007s_ops = {
528 .info = {
529 .name = "VA1J5JF8007 ISDB-S",
530 .type = FE_QPSK,
531 .frequency_min = 950000,
532 .frequency_max = 2150000,
533 .frequency_stepsize = 1000,
534 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
535 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
536 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
537 },
538
539 .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
540 .read_status = va1j5jf8007s_read_status,
541 .tune = va1j5jf8007s_tune,
542 .sleep = va1j5jf8007s_sleep,
543 .init = va1j5jf8007s_init,
544 .release = va1j5jf8007s_release,
545};
546
547static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
548{
549 u8 addr;
550 u8 write_buf[1], read_buf[1];
551 struct i2c_msg msgs[2];
552
553 addr = state->config->demod_address;
554
555 write_buf[0] = 0x07;
556
557 msgs[0].addr = addr;
558 msgs[0].flags = 0;
559 msgs[0].len = sizeof(write_buf);
560 msgs[0].buf = write_buf;
561
562 msgs[1].addr = addr;
563 msgs[1].flags = I2C_M_RD;
564 msgs[1].len = sizeof(read_buf);
565 msgs[1].buf = read_buf;
566
567 if (i2c_transfer(state->adap, msgs, 2) != 2)
568 return -EREMOTEIO;
569
570 if (read_buf[0] != 0x41)
571 return -EIO;
572
573 return 0;
574}
575
576static const u8 va1j5jf8007s_prepare_bufs[][2] = {
577 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
578 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
579 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
580 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
581};
582
583static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
584{
585 u8 addr;
586 u8 buf[2];
587 struct i2c_msg msg;
588 int i;
589
590 addr = state->config->demod_address;
591
592 msg.addr = addr;
593 msg.flags = 0;
594 msg.len = 2;
595 msg.buf = buf;
596 for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_prepare_bufs); i++) {
597 memcpy(buf, va1j5jf8007s_prepare_bufs[i], sizeof(buf));
598 if (i2c_transfer(state->adap, &msg, 1) != 1)
599 return -EREMOTEIO;
600 }
601
602 return 0;
603}
604
605/* must be called after va1j5jf8007t_attach */
606int va1j5jf8007s_prepare(struct dvb_frontend *fe)
607{
608 struct va1j5jf8007s_state *state;
609 int ret;
610
611 state = fe->demodulator_priv;
612
613 ret = va1j5jf8007s_prepare_1(state);
614 if (ret < 0)
615 return ret;
616
617 ret = va1j5jf8007s_prepare_2(state);
618 if (ret < 0)
619 return ret;
620
621 return va1j5jf8007s_init_frequency(state);
622}
623
624struct dvb_frontend *
625va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
626 struct i2c_adapter *adap)
627{
628 struct va1j5jf8007s_state *state;
629 struct dvb_frontend *fe;
630 u8 buf[2];
631 struct i2c_msg msg;
632
633 state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
634 if (!state)
635 return NULL;
636
637 state->config = config;
638 state->adap = adap;
639
640 fe = &state->fe;
641 memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
642 fe->demodulator_priv = state;
643
644 buf[0] = 0x01;
645 buf[1] = 0x80;
646
647 msg.addr = state->config->demod_address;
648 msg.flags = 0;
649 msg.len = sizeof(buf);
650 msg.buf = buf;
651
652 if (i2c_transfer(state->adap, &msg, 1) != 1) {
653 kfree(state);
654 return NULL;
655 }
656
657 return fe;
658}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007s.h b/drivers/media/dvb/pt1/va1j5jf8007s.h
new file mode 100644
index 000000000000..aa228a816353
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007s.h
@@ -0,0 +1,40 @@
1/*
2 * ISDB-S driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef VA1J5JF8007S_H
25#define VA1J5JF8007S_H
26
27struct va1j5jf8007s_config {
28 u8 demod_address;
29};
30
31struct i2c_adapter;
32
33struct dvb_frontend *
34va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
35 struct i2c_adapter *adap);
36
37/* must be called after va1j5jf8007t_attach */
38int va1j5jf8007s_prepare(struct dvb_frontend *fe);
39
40#endif
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.c b/drivers/media/dvb/pt1/va1j5jf8007t.c
new file mode 100644
index 000000000000..71117f4ca7e6
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.c
@@ -0,0 +1,468 @@
1/*
2 * ISDB-T driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/slab.h>
27#include <linux/i2c.h>
28#include "dvb_frontend.h"
29#include "dvb_math.h"
30#include "va1j5jf8007t.h"
31
32enum va1j5jf8007t_tune_state {
33 VA1J5JF8007T_IDLE,
34 VA1J5JF8007T_SET_FREQUENCY,
35 VA1J5JF8007T_CHECK_FREQUENCY,
36 VA1J5JF8007T_SET_MODULATION,
37 VA1J5JF8007T_CHECK_MODULATION,
38 VA1J5JF8007T_TRACK,
39 VA1J5JF8007T_ABORT,
40};
41
42struct va1j5jf8007t_state {
43 const struct va1j5jf8007t_config *config;
44 struct i2c_adapter *adap;
45 struct dvb_frontend fe;
46 enum va1j5jf8007t_tune_state tune_state;
47};
48
49static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
50{
51 return DVBFE_ALGO_HW;
52}
53
54static int
55va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
56{
57 struct va1j5jf8007t_state *state;
58
59 state = fe->demodulator_priv;
60
61 switch (state->tune_state) {
62 case VA1J5JF8007T_IDLE:
63 case VA1J5JF8007T_SET_FREQUENCY:
64 case VA1J5JF8007T_CHECK_FREQUENCY:
65 *status = 0;
66 return 0;
67
68
69 case VA1J5JF8007T_SET_MODULATION:
70 case VA1J5JF8007T_CHECK_MODULATION:
71 case VA1J5JF8007T_ABORT:
72 *status |= FE_HAS_SIGNAL;
73 return 0;
74
75 case VA1J5JF8007T_TRACK:
76 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
77 return 0;
78 }
79
80 BUG();
81}
82
83struct va1j5jf8007t_cb_map {
84 u32 frequency;
85 u8 cb;
86};
87
88static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
89 { 90000000, 0x80 },
90 { 140000000, 0x81 },
91 { 170000000, 0xa1 },
92 { 220000000, 0x62 },
93 { 330000000, 0xa2 },
94 { 402000000, 0xe2 },
95 { 450000000, 0x64 },
96 { 550000000, 0x84 },
97 { 600000000, 0xa4 },
98 { 700000000, 0xc4 },
99};
100
101static u8 va1j5jf8007t_lookup_cb(u32 frequency)
102{
103 int i;
104 const struct va1j5jf8007t_cb_map *map;
105
106 for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
107 map = &va1j5jf8007t_cb_maps[i];
108 if (frequency < map->frequency)
109 return map->cb;
110 }
111 return 0xe4;
112}
113
114static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
115{
116 u32 frequency;
117 u16 word;
118 u8 buf[6];
119 struct i2c_msg msg;
120
121 frequency = state->fe.dtv_property_cache.frequency;
122
123 word = (frequency + 71428) / 142857 + 399;
124 buf[0] = 0xfe;
125 buf[1] = 0xc2;
126 buf[2] = word >> 8;
127 buf[3] = word;
128 buf[4] = 0x80;
129 buf[5] = va1j5jf8007t_lookup_cb(frequency);
130
131 msg.addr = state->config->demod_address;
132 msg.flags = 0;
133 msg.len = sizeof(buf);
134 msg.buf = buf;
135
136 if (i2c_transfer(state->adap, &msg, 1) != 1)
137 return -EREMOTEIO;
138
139 return 0;
140}
141
142static int
143va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
144{
145 u8 addr;
146 u8 write_buf[2], read_buf[1];
147 struct i2c_msg msgs[2];
148
149 addr = state->config->demod_address;
150
151 write_buf[0] = 0xfe;
152 write_buf[1] = 0xc3;
153
154 msgs[0].addr = addr;
155 msgs[0].flags = 0;
156 msgs[0].len = sizeof(write_buf);
157 msgs[0].buf = write_buf;
158
159 msgs[1].addr = addr;
160 msgs[1].flags = I2C_M_RD;
161 msgs[1].len = sizeof(read_buf);
162 msgs[1].buf = read_buf;
163
164 if (i2c_transfer(state->adap, msgs, 2) != 2)
165 return -EREMOTEIO;
166
167 *lock = read_buf[0] & 0x40;
168 return 0;
169}
170
171static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
172{
173 u8 buf[2];
174 struct i2c_msg msg;
175
176 buf[0] = 0x01;
177 buf[1] = 0x40;
178
179 msg.addr = state->config->demod_address;
180 msg.flags = 0;
181 msg.len = sizeof(buf);
182 msg.buf = buf;
183
184 if (i2c_transfer(state->adap, &msg, 1) != 1)
185 return -EREMOTEIO;
186
187 return 0;
188}
189
190static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
191 int *lock, int *retry)
192{
193 u8 addr;
194 u8 write_buf[1], read_buf[1];
195 struct i2c_msg msgs[2];
196
197 addr = state->config->demod_address;
198
199 write_buf[0] = 0x80;
200
201 msgs[0].addr = addr;
202 msgs[0].flags = 0;
203 msgs[0].len = sizeof(write_buf);
204 msgs[0].buf = write_buf;
205
206 msgs[1].addr = addr;
207 msgs[1].flags = I2C_M_RD;
208 msgs[1].len = sizeof(read_buf);
209 msgs[1].buf = read_buf;
210
211 if (i2c_transfer(state->adap, msgs, 2) != 2)
212 return -EREMOTEIO;
213
214 *lock = !(read_buf[0] & 0x10);
215 *retry = read_buf[0] & 0x80;
216 return 0;
217}
218
219static int
220va1j5jf8007t_tune(struct dvb_frontend *fe,
221 struct dvb_frontend_parameters *params,
222 unsigned int mode_flags, unsigned int *delay,
223 fe_status_t *status)
224{
225 struct va1j5jf8007t_state *state;
226 int ret;
227 int lock, retry;
228
229 state = fe->demodulator_priv;
230
231 if (params != NULL)
232 state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
233
234 switch (state->tune_state) {
235 case VA1J5JF8007T_IDLE:
236 *delay = 3 * HZ;
237 *status = 0;
238 return 0;
239
240 case VA1J5JF8007T_SET_FREQUENCY:
241 ret = va1j5jf8007t_set_frequency(state);
242 if (ret < 0)
243 return ret;
244
245 state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
246 *delay = 0;
247 *status = 0;
248 return 0;
249
250 case VA1J5JF8007T_CHECK_FREQUENCY:
251 ret = va1j5jf8007t_check_frequency(state, &lock);
252 if (ret < 0)
253 return ret;
254
255 if (!lock) {
256 *delay = (HZ + 999) / 1000;
257 *status = 0;
258 return 0;
259 }
260
261 state->tune_state = VA1J5JF8007T_SET_MODULATION;
262 *delay = 0;
263 *status = FE_HAS_SIGNAL;
264 return 0;
265
266 case VA1J5JF8007T_SET_MODULATION:
267 ret = va1j5jf8007t_set_modulation(state);
268 if (ret < 0)
269 return ret;
270
271 state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
272 *delay = 0;
273 *status = FE_HAS_SIGNAL;
274 return 0;
275
276 case VA1J5JF8007T_CHECK_MODULATION:
277 ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
278 if (ret < 0)
279 return ret;
280
281 if (!lock) {
282 if (!retry) {
283 state->tune_state = VA1J5JF8007T_ABORT;
284 *delay = 3 * HZ;
285 *status = FE_HAS_SIGNAL;
286 return 0;
287 }
288 *delay = (HZ + 999) / 1000;
289 *status = FE_HAS_SIGNAL;
290 return 0;
291 }
292
293 state->tune_state = VA1J5JF8007T_TRACK;
294 /* fall through */
295
296 case VA1J5JF8007T_TRACK:
297 *delay = 3 * HZ;
298 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
299 return 0;
300
301 case VA1J5JF8007T_ABORT:
302 *delay = 3 * HZ;
303 *status = FE_HAS_SIGNAL;
304 return 0;
305 }
306
307 BUG();
308}
309
310static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
311{
312 u8 buf[7];
313 struct i2c_msg msg;
314
315 buf[0] = 0xfe;
316 buf[1] = 0xc2;
317 buf[2] = 0x01;
318 buf[3] = 0x8f;
319 buf[4] = 0xc1;
320 buf[5] = 0x80;
321 buf[6] = 0x80;
322
323 msg.addr = state->config->demod_address;
324 msg.flags = 0;
325 msg.len = sizeof(buf);
326 msg.buf = buf;
327
328 if (i2c_transfer(state->adap, &msg, 1) != 1)
329 return -EREMOTEIO;
330
331 return 0;
332}
333
334static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
335{
336 u8 buf[2];
337 struct i2c_msg msg;
338
339 buf[0] = 0x03;
340 buf[1] = sleep ? 0x90 : 0x80;
341
342 msg.addr = state->config->demod_address;
343 msg.flags = 0;
344 msg.len = sizeof(buf);
345 msg.buf = buf;
346
347 if (i2c_transfer(state->adap, &msg, 1) != 1)
348 return -EREMOTEIO;
349
350 return 0;
351}
352
353static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
354{
355 struct va1j5jf8007t_state *state;
356 int ret;
357
358 state = fe->demodulator_priv;
359
360 ret = va1j5jf8007t_init_frequency(state);
361 if (ret < 0)
362 return ret;
363
364 return va1j5jf8007t_set_sleep(state, 1);
365}
366
367static int va1j5jf8007t_init(struct dvb_frontend *fe)
368{
369 struct va1j5jf8007t_state *state;
370
371 state = fe->demodulator_priv;
372 state->tune_state = VA1J5JF8007T_IDLE;
373
374 return va1j5jf8007t_set_sleep(state, 0);
375}
376
377static void va1j5jf8007t_release(struct dvb_frontend *fe)
378{
379 struct va1j5jf8007t_state *state;
380 state = fe->demodulator_priv;
381 kfree(state);
382}
383
384static struct dvb_frontend_ops va1j5jf8007t_ops = {
385 .info = {
386 .name = "VA1J5JF8007 ISDB-T",
387 .type = FE_OFDM,
388 .frequency_min = 90000000,
389 .frequency_max = 770000000,
390 .frequency_stepsize = 142857,
391 .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
392 FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
393 FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
394 },
395
396 .get_frontend_algo = va1j5jf8007t_get_frontend_algo,
397 .read_status = va1j5jf8007t_read_status,
398 .tune = va1j5jf8007t_tune,
399 .sleep = va1j5jf8007t_sleep,
400 .init = va1j5jf8007t_init,
401 .release = va1j5jf8007t_release,
402};
403
404static const u8 va1j5jf8007t_prepare_bufs[][2] = {
405 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
406 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
407 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
408 {0xef, 0x01}
409};
410
411int va1j5jf8007t_prepare(struct dvb_frontend *fe)
412{
413 struct va1j5jf8007t_state *state;
414 u8 buf[2];
415 struct i2c_msg msg;
416 int i;
417
418 state = fe->demodulator_priv;
419
420 msg.addr = state->config->demod_address;
421 msg.flags = 0;
422 msg.len = sizeof(buf);
423 msg.buf = buf;
424
425 for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_prepare_bufs); i++) {
426 memcpy(buf, va1j5jf8007t_prepare_bufs[i], sizeof(buf));
427 if (i2c_transfer(state->adap, &msg, 1) != 1)
428 return -EREMOTEIO;
429 }
430
431 return va1j5jf8007t_init_frequency(state);
432}
433
434struct dvb_frontend *
435va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
436 struct i2c_adapter *adap)
437{
438 struct va1j5jf8007t_state *state;
439 struct dvb_frontend *fe;
440 u8 buf[2];
441 struct i2c_msg msg;
442
443 state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
444 if (!state)
445 return NULL;
446
447 state->config = config;
448 state->adap = adap;
449
450 fe = &state->fe;
451 memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
452 fe->demodulator_priv = state;
453
454 buf[0] = 0x01;
455 buf[1] = 0x80;
456
457 msg.addr = state->config->demod_address;
458 msg.flags = 0;
459 msg.len = sizeof(buf);
460 msg.buf = buf;
461
462 if (i2c_transfer(state->adap, &msg, 1) != 1) {
463 kfree(state);
464 return NULL;
465 }
466
467 return fe;
468}
diff --git a/drivers/media/dvb/pt1/va1j5jf8007t.h b/drivers/media/dvb/pt1/va1j5jf8007t.h
new file mode 100644
index 000000000000..ed49906f7769
--- /dev/null
+++ b/drivers/media/dvb/pt1/va1j5jf8007t.h
@@ -0,0 +1,40 @@
1/*
2 * ISDB-T driver for VA1J5JF8007
3 *
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5 *
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef VA1J5JF8007T_H
25#define VA1J5JF8007T_H
26
27struct va1j5jf8007t_config {
28 u8 demod_address;
29};
30
31struct i2c_adapter;
32
33struct dvb_frontend *
34va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
35 struct i2c_adapter *adap);
36
37/* must be called after va1j5jf8007s_attach */
38int va1j5jf8007t_prepare(struct dvb_frontend *fe);
39
40#endif
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index 25a36ad60c5e..a87a477c87f2 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -346,7 +346,7 @@ config RADIO_SI4713
346 ---help--- 346 ---help---
347 Say Y here if you want support to Si4713 FM Radio Transmitter. 347 Say Y here if you want support to Si4713 FM Radio Transmitter.
348 This device can transmit audio through FM. It can transmit 348 This device can transmit audio through FM. It can transmit
349 EDS and EBDS signals as well. This module is the v4l2 radio 349 RDS and RBDS signals as well. This module is the v4l2 radio
350 interface for the i2c driver of this device. 350 interface for the i2c driver of this device.
351 351
352 To compile this driver as a module, choose M here: the 352 To compile this driver as a module, choose M here: the
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 65c14b704586..170bbe554787 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -24,7 +24,6 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/version.h>
28#include <linux/platform_device.h> 27#include <linux/platform_device.h>
29#include <linux/i2c.h> 28#include <linux/i2c.h>
30#include <linux/videodev2.h> 29#include <linux/videodev2.h>
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index 1d758525d236..e6186b338a12 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -265,6 +265,15 @@ config VIDEO_SAA6588
265 265
266comment "Video decoders" 266comment "Video decoders"
267 267
268config VIDEO_ADV7180
269 tristate "Analog Devices ADV7180 decoder"
270 depends on VIDEO_V4L2 && I2C
271 ---help---
272 Support for the Analog Devices ADV7180 video decoder.
273
274 To compile this driver as a module, choose M here: the
275 module will be called adv7180.
276
268config VIDEO_BT819 277config VIDEO_BT819
269 tristate "BT819A VideoStream decoder" 278 tristate "BT819A VideoStream decoder"
270 depends on VIDEO_V4L2 && I2C 279 depends on VIDEO_V4L2 && I2C
@@ -493,6 +502,39 @@ config VIDEO_UPD64083
493 502
494endmenu # encoder / decoder chips 503endmenu # encoder / decoder chips
495 504
505config DISPLAY_DAVINCI_DM646X_EVM
506 tristate "DM646x EVM Video Display"
507 depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
508 select VIDEOBUF_DMA_CONTIG
509 select VIDEO_DAVINCI_VPIF
510 select VIDEO_ADV7343
511 select VIDEO_THS7303
512 help
513 Support for DM6467 based display device.
514
515 To compile this driver as a module, choose M here: the
516 module will be called vpif_display.
517
518config CAPTURE_DAVINCI_DM646X_EVM
519 tristate "DM646x EVM Video Capture"
520 depends on VIDEO_DEV && MACH_DAVINCI_DM6467_EVM
521 select VIDEOBUF_DMA_CONTIG
522 select VIDEO_DAVINCI_VPIF
523 help
524 Support for DM6467 based capture device.
525
526 To compile this driver as a module, choose M here: the
527 module will be called vpif_capture.
528
529config VIDEO_DAVINCI_VPIF
530 tristate "DaVinci VPIF Driver"
531 depends on DISPLAY_DAVINCI_DM646X_EVM
532 help
533 Support for DaVinci VPIF Driver.
534
535 To compile this driver as a module, choose M here: the
536 module will be called vpif.
537
496config VIDEO_VIVI 538config VIDEO_VIVI
497 tristate "Virtual Video Driver" 539 tristate "Virtual Video Driver"
498 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 540 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
@@ -505,6 +547,55 @@ config VIDEO_VIVI
505 Say Y here if you want to test video apps or debug V4L devices. 547 Say Y here if you want to test video apps or debug V4L devices.
506 In doubt, say N. 548 In doubt, say N.
507 549
550config VIDEO_VPSS_SYSTEM
551 tristate "VPSS System module driver"
552 depends on ARCH_DAVINCI
553 help
554 Support for vpss system module for video driver
555 default y
556
557config VIDEO_VPFE_CAPTURE
558 tristate "VPFE Video Capture Driver"
559 depends on VIDEO_V4L2 && ARCH_DAVINCI
560 select VIDEOBUF_DMA_CONTIG
561 help
562 Support for DMXXXX VPFE based frame grabber. This is the
563 common V4L2 module for following DMXXX SoCs from Texas
564 Instruments:- DM6446 & DM355.
565
566 To compile this driver as a module, choose M here: the
567 module will be called vpfe-capture.
568
569config VIDEO_DM6446_CCDC
570 tristate "DM6446 CCDC HW module"
571 depends on ARCH_DAVINCI_DM644x && VIDEO_VPFE_CAPTURE
572 select VIDEO_VPSS_SYSTEM
573 default y
574 help
575 Enables DaVinci CCD hw module. DaVinci CCDC hw interfaces
576 with decoder modules such as TVP5146 over BT656 or
577 sensor module such as MT9T001 over a raw interface. This
578 module configures the interface and CCDC/ISIF to do
579 video frame capture from slave decoders.
580
581 To compile this driver as a module, choose M here: the
582 module will be called vpfe.
583
584config VIDEO_DM355_CCDC
585 tristate "DM355 CCDC HW module"
586 depends on ARCH_DAVINCI_DM355 && VIDEO_VPFE_CAPTURE
587 select VIDEO_VPSS_SYSTEM
588 default y
589 help
590 Enables DM355 CCD hw module. DM355 CCDC hw interfaces
591 with decoder modules such as TVP5146 over BT656 or
592 sensor module such as MT9T001 over a raw interface. This
593 module configures the interface and CCDC/ISIF to do
594 video frame capture from a slave decoders
595
596 To compile this driver as a module, choose M here: the
597 module will be called vpfe.
598
508source "drivers/media/video/bt8xx/Kconfig" 599source "drivers/media/video/bt8xx/Kconfig"
509 600
510config VIDEO_PMS 601config VIDEO_PMS
@@ -690,6 +781,8 @@ source "drivers/media/video/ivtv/Kconfig"
690 781
691source "drivers/media/video/cx18/Kconfig" 782source "drivers/media/video/cx18/Kconfig"
692 783
784source "drivers/media/video/saa7164/Kconfig"
785
693config VIDEO_M32R_AR 786config VIDEO_M32R_AR
694 tristate "AR devices" 787 tristate "AR devices"
695 depends on M32R && VIDEO_V4L1 788 depends on M32R && VIDEO_V4L1
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 9f2e3214a482..e541932a789b 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -45,6 +45,7 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
45obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o 45obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
46obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o 46obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
47obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o 47obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
48obj-$(CONFIG_VIDEO_ADV7180) += adv7180.o
48obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o 49obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
49obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o 50obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
50obj-$(CONFIG_VIDEO_BT819) += bt819.o 51obj-$(CONFIG_VIDEO_BT819) += bt819.o
@@ -154,12 +155,17 @@ obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o
154obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o 155obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o
155obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o 156obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o
156 157
158obj-$(CONFIG_ARCH_DAVINCI) += davinci/
159
157obj-$(CONFIG_VIDEO_AU0828) += au0828/ 160obj-$(CONFIG_VIDEO_AU0828) += au0828/
158 161
159obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/ 162obj-$(CONFIG_USB_VIDEO_CLASS) += uvc/
163obj-$(CONFIG_VIDEO_SAA7164) += saa7164/
160 164
161obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o 165obj-$(CONFIG_VIDEO_IR_I2C) += ir-kbd-i2c.o
162 166
167obj-$(CONFIG_ARCH_DAVINCI) += davinci/
168
163EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 169EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
164EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 170EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
165EXTRA_CFLAGS += -Idrivers/media/common/tuners 171EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/adv7180.c b/drivers/media/video/adv7180.c
new file mode 100644
index 000000000000..1b3cbd02a7fd
--- /dev/null
+++ b/drivers/media/video/adv7180.c
@@ -0,0 +1,202 @@
1/*
2 * adv7180.c Analog Devices ADV7180 video decoder driver
3 * Copyright (c) 2009 Intel Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19#include <linux/module.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/kernel.h>
23#include <linux/interrupt.h>
24#include <linux/i2c.h>
25#include <linux/i2c-id.h>
26#include <media/v4l2-ioctl.h>
27#include <linux/videodev2.h>
28#include <media/v4l2-device.h>
29#include <media/v4l2-chip-ident.h>
30
31#define DRIVER_NAME "adv7180"
32
33#define ADV7180_INPUT_CONTROL_REG 0x00
34#define ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM 0x00
35#define ADV7180_AUTODETECT_ENABLE_REG 0x07
36#define ADV7180_AUTODETECT_DEFAULT 0x7f
37
38
39#define ADV7180_STATUS1_REG 0x10
40#define ADV7180_STATUS1_AUTOD_MASK 0x70
41#define ADV7180_STATUS1_AUTOD_NTSM_M_J 0x00
42#define ADV7180_STATUS1_AUTOD_NTSC_4_43 0x10
43#define ADV7180_STATUS1_AUTOD_PAL_M 0x20
44#define ADV7180_STATUS1_AUTOD_PAL_60 0x30
45#define ADV7180_STATUS1_AUTOD_PAL_B_G 0x40
46#define ADV7180_STATUS1_AUTOD_SECAM 0x50
47#define ADV7180_STATUS1_AUTOD_PAL_COMB 0x60
48#define ADV7180_STATUS1_AUTOD_SECAM_525 0x70
49
50#define ADV7180_IDENT_REG 0x11
51#define ADV7180_ID_7180 0x18
52
53
54struct adv7180_state {
55 struct v4l2_subdev sd;
56};
57
58static v4l2_std_id determine_norm(struct i2c_client *client)
59{
60 u8 status1 = i2c_smbus_read_byte_data(client, ADV7180_STATUS1_REG);
61
62 switch (status1 & ADV7180_STATUS1_AUTOD_MASK) {
63 case ADV7180_STATUS1_AUTOD_NTSM_M_J:
64 return V4L2_STD_NTSC_M_JP;
65 case ADV7180_STATUS1_AUTOD_NTSC_4_43:
66 return V4L2_STD_NTSC_443;
67 case ADV7180_STATUS1_AUTOD_PAL_M:
68 return V4L2_STD_PAL_M;
69 case ADV7180_STATUS1_AUTOD_PAL_60:
70 return V4L2_STD_PAL_60;
71 case ADV7180_STATUS1_AUTOD_PAL_B_G:
72 return V4L2_STD_PAL;
73 case ADV7180_STATUS1_AUTOD_SECAM:
74 return V4L2_STD_SECAM;
75 case ADV7180_STATUS1_AUTOD_PAL_COMB:
76 return V4L2_STD_PAL_Nc | V4L2_STD_PAL_N;
77 case ADV7180_STATUS1_AUTOD_SECAM_525:
78 return V4L2_STD_SECAM;
79 default:
80 return V4L2_STD_UNKNOWN;
81 }
82}
83
84static inline struct adv7180_state *to_state(struct v4l2_subdev *sd)
85{
86 return container_of(sd, struct adv7180_state, sd);
87}
88
89static int adv7180_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
90{
91 struct i2c_client *client = v4l2_get_subdevdata(sd);
92
93 *std = determine_norm(client);
94 return 0;
95}
96
97static int adv7180_g_chip_ident(struct v4l2_subdev *sd,
98 struct v4l2_dbg_chip_ident *chip)
99{
100 struct i2c_client *client = v4l2_get_subdevdata(sd);
101
102 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7180, 0);
103}
104
105static const struct v4l2_subdev_video_ops adv7180_video_ops = {
106 .querystd = adv7180_querystd,
107};
108
109static const struct v4l2_subdev_core_ops adv7180_core_ops = {
110 .g_chip_ident = adv7180_g_chip_ident,
111};
112
113static const struct v4l2_subdev_ops adv7180_ops = {
114 .core = &adv7180_core_ops,
115 .video = &adv7180_video_ops,
116};
117
118/*
119 * Generic i2c probe
120 * concerning the addresses: i2c wants 7 bit (without the r/w bit), so '>>1'
121 */
122
123static int adv7180_probe(struct i2c_client *client,
124 const struct i2c_device_id *id)
125{
126 struct adv7180_state *state;
127 struct v4l2_subdev *sd;
128 int ret;
129
130 /* Check if the adapter supports the needed features */
131 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
132 return -EIO;
133
134 v4l_info(client, "chip found @ 0x%02x (%s)\n",
135 client->addr << 1, client->adapter->name);
136
137 state = kzalloc(sizeof(struct adv7180_state), GFP_KERNEL);
138 if (state == NULL)
139 return -ENOMEM;
140 sd = &state->sd;
141 v4l2_i2c_subdev_init(sd, client, &adv7180_ops);
142
143 /* Initialize adv7180 */
144 /* enable autodetection */
145 ret = i2c_smbus_write_byte_data(client, ADV7180_INPUT_CONTROL_REG,
146 ADV7180_INPUT_CONTROL_PAL_BG_NTSC_J_SECAM);
147 if (ret > 0)
148 ret = i2c_smbus_write_byte_data(client,
149 ADV7180_AUTODETECT_ENABLE_REG,
150 ADV7180_AUTODETECT_DEFAULT);
151 if (ret < 0) {
152 printk(KERN_ERR DRIVER_NAME
153 ": Failed to communicate to chip: %d\n", ret);
154 return ret;
155 }
156
157 return 0;
158}
159
160static int adv7180_remove(struct i2c_client *client)
161{
162 struct v4l2_subdev *sd = i2c_get_clientdata(client);
163
164 v4l2_device_unregister_subdev(sd);
165 kfree(to_state(sd));
166 return 0;
167}
168
169static const struct i2c_device_id adv7180_id[] = {
170 {DRIVER_NAME, 0},
171 {},
172};
173
174MODULE_DEVICE_TABLE(i2c, adv7180_id);
175
176static struct i2c_driver adv7180_driver = {
177 .driver = {
178 .owner = THIS_MODULE,
179 .name = DRIVER_NAME,
180 },
181 .probe = adv7180_probe,
182 .remove = adv7180_remove,
183 .id_table = adv7180_id,
184};
185
186static __init int adv7180_init(void)
187{
188 return i2c_add_driver(&adv7180_driver);
189}
190
191static __exit void adv7180_exit(void)
192{
193 i2c_del_driver(&adv7180_driver);
194}
195
196module_init(adv7180_init);
197module_exit(adv7180_exit);
198
199MODULE_DESCRIPTION("Analog Devices ADV7180 video decoder driver");
200MODULE_AUTHOR("Mocean Laboratories");
201MODULE_LICENSE("GPL v2");
202
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 30f5caf5dda5..df26f2fe44eb 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -24,7 +24,6 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/version.h>
28 27
29#include <media/adv7343.h> 28#include <media/adv7343.h>
30#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 830c4a933f63..57dd9195daf5 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -212,7 +212,7 @@ void au0828_card_setup(struct au0828_dev *dev)
212 be abstracted out if we ever need to support a different 212 be abstracted out if we ever need to support a different
213 demod) */ 213 demod) */
214 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 214 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
215 "au8522", "au8522", 0x8e >> 1); 215 "au8522", "au8522", 0x8e >> 1, NULL);
216 if (sd == NULL) 216 if (sd == NULL)
217 printk(KERN_ERR "analog subdev registration failed\n"); 217 printk(KERN_ERR "analog subdev registration failed\n");
218 } 218 }
@@ -221,7 +221,7 @@ void au0828_card_setup(struct au0828_dev *dev)
221 if (dev->board.tuner_type != TUNER_ABSENT) { 221 if (dev->board.tuner_type != TUNER_ABSENT) {
222 /* Load the tuner module, which does the attach */ 222 /* Load the tuner module, which does the attach */
223 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 223 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
224 "tuner", "tuner", dev->board.tuner_addr); 224 "tuner", "tuner", dev->board.tuner_addr, NULL);
225 if (sd == NULL) 225 if (sd == NULL)
226 printk(KERN_ERR "tuner subdev registration fail\n"); 226 printk(KERN_ERR "tuner subdev registration fail\n");
227 227
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index b42251fa96ba..12279f6d9bc4 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3524,8 +3524,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
3524 }; 3524 };
3525 struct v4l2_subdev *sd; 3525 struct v4l2_subdev *sd;
3526 3526
3527 sd = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3527 sd = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3528 &btv->c.i2c_adap, "saa6588", "saa6588", addrs); 3528 &btv->c.i2c_adap, "saa6588", "saa6588", 0, addrs);
3529 btv->has_saa6588 = (sd != NULL); 3529 btv->has_saa6588 = (sd != NULL);
3530 } 3530 }
3531 3531
@@ -3549,8 +3549,8 @@ void __devinit bttv_init_card2(struct bttv *btv)
3549 I2C_CLIENT_END 3549 I2C_CLIENT_END
3550 }; 3550 };
3551 3551
3552 btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3552 btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3553 &btv->c.i2c_adap, "msp3400", "msp3400", addrs); 3553 &btv->c.i2c_adap, "msp3400", "msp3400", 0, addrs);
3554 if (btv->sd_msp34xx) 3554 if (btv->sd_msp34xx)
3555 return; 3555 return;
3556 goto no_audio; 3556 goto no_audio;
@@ -3563,16 +3563,16 @@ void __devinit bttv_init_card2(struct bttv *btv)
3563 I2C_CLIENT_END 3563 I2C_CLIENT_END
3564 }; 3564 };
3565 3565
3566 if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3566 if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3567 &btv->c.i2c_adap, "tda7432", "tda7432", addrs)) 3567 &btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs))
3568 return; 3568 return;
3569 goto no_audio; 3569 goto no_audio;
3570 } 3570 }
3571 3571
3572 case 3: { 3572 case 3: {
3573 /* The user specified that we should probe for tvaudio */ 3573 /* The user specified that we should probe for tvaudio */
3574 btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3574 btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3575 &btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs()); 3575 &btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs());
3576 if (btv->sd_tvaudio) 3576 if (btv->sd_tvaudio)
3577 return; 3577 return;
3578 goto no_audio; 3578 goto no_audio;
@@ -3591,13 +3591,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
3591 it really is a msp3400, so it will return NULL when the device 3591 it really is a msp3400, so it will return NULL when the device
3592 found is really something else (e.g. a tea6300). */ 3592 found is really something else (e.g. a tea6300). */
3593 if (!bttv_tvcards[btv->c.type].no_msp34xx) { 3593 if (!bttv_tvcards[btv->c.type].no_msp34xx) {
3594 btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev, 3594 btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3595 &btv->c.i2c_adap, "msp3400", "msp3400", 3595 &btv->c.i2c_adap, "msp3400", "msp3400",
3596 I2C_ADDR_MSP3400 >> 1); 3596 0, I2C_ADDRS(I2C_ADDR_MSP3400 >> 1));
3597 } else if (bttv_tvcards[btv->c.type].msp34xx_alt) { 3597 } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
3598 btv->sd_msp34xx = v4l2_i2c_new_probed_subdev_addr(&btv->c.v4l2_dev, 3598 btv->sd_msp34xx = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3599 &btv->c.i2c_adap, "msp3400", "msp3400", 3599 &btv->c.i2c_adap, "msp3400", "msp3400",
3600 I2C_ADDR_MSP3400_ALT >> 1); 3600 0, I2C_ADDRS(I2C_ADDR_MSP3400_ALT >> 1));
3601 } 3601 }
3602 3602
3603 /* If we found a msp34xx, then we're done. */ 3603 /* If we found a msp34xx, then we're done. */
@@ -3611,14 +3611,14 @@ void __devinit bttv_init_card2(struct bttv *btv)
3611 I2C_CLIENT_END 3611 I2C_CLIENT_END
3612 }; 3612 };
3613 3613
3614 if (v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3614 if (v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3615 &btv->c.i2c_adap, "tda7432", "tda7432", addrs)) 3615 &btv->c.i2c_adap, "tda7432", "tda7432", 0, addrs))
3616 return; 3616 return;
3617 } 3617 }
3618 3618
3619 /* Now see if we can find one of the tvaudio devices. */ 3619 /* Now see if we can find one of the tvaudio devices. */
3620 btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3620 btv->sd_tvaudio = v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3621 &btv->c.i2c_adap, "tvaudio", "tvaudio", tvaudio_addrs()); 3621 &btv->c.i2c_adap, "tvaudio", "tvaudio", 0, tvaudio_addrs());
3622 if (btv->sd_tvaudio) 3622 if (btv->sd_tvaudio)
3623 return; 3623 return;
3624 3624
@@ -3641,15 +3641,15 @@ void __devinit bttv_init_tuner(struct bttv *btv)
3641 3641
3642 /* Load tuner module before issuing tuner config call! */ 3642 /* Load tuner module before issuing tuner config call! */
3643 if (bttv_tvcards[btv->c.type].has_radio) 3643 if (bttv_tvcards[btv->c.type].has_radio)
3644 v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3644 v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3645 &btv->c.i2c_adap, "tuner", "tuner", 3645 &btv->c.i2c_adap, "tuner", "tuner",
3646 v4l2_i2c_tuner_addrs(ADDRS_RADIO)); 3646 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
3647 v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3647 v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3648 &btv->c.i2c_adap, "tuner", "tuner", 3648 &btv->c.i2c_adap, "tuner", "tuner",
3649 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 3649 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
3650 v4l2_i2c_new_probed_subdev(&btv->c.v4l2_dev, 3650 v4l2_i2c_new_subdev(&btv->c.v4l2_dev,
3651 &btv->c.i2c_adap, "tuner", "tuner", 3651 &btv->c.i2c_adap, "tuner", "tuner",
3652 v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); 3652 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
3653 3653
3654 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 3654 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
3655 tun_setup.type = btv->tuner_type; 3655 tun_setup.type = btv->tuner_type;
diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c
index 9c149a781294..657c481d255c 100644
--- a/drivers/media/video/cafe_ccic.c
+++ b/drivers/media/video/cafe_ccic.c
@@ -1955,7 +1955,7 @@ static int cafe_pci_probe(struct pci_dev *pdev,
1955 1955
1956 cam->sensor_addr = 0x42; 1956 cam->sensor_addr = 0x42;
1957 cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter, 1957 cam->sensor = v4l2_i2c_new_subdev(&cam->v4l2_dev, &cam->i2c_adapter,
1958 "ov7670", "ov7670", cam->sensor_addr); 1958 "ov7670", "ov7670", cam->sensor_addr, NULL);
1959 if (cam->sensor == NULL) { 1959 if (cam->sensor == NULL) {
1960 ret = -ENODEV; 1960 ret = -ENODEV;
1961 goto out_smbus; 1961 goto out_smbus;
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index dd0224f328ad..6dd51e27582c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -231,7 +231,7 @@ MODULE_PARM_DESC(enc_pcm_bufs,
231 "Number of encoder PCM buffers\n" 231 "Number of encoder PCM buffers\n"
232 "\t\t\tDefault is computed from other enc_pcm_* parameters"); 232 "\t\t\tDefault is computed from other enc_pcm_* parameters");
233 233
234MODULE_PARM_DESC(cx18_first_minor, "Set kernel number assigned to first card"); 234MODULE_PARM_DESC(cx18_first_minor, "Set device node number assigned to first card");
235 235
236MODULE_AUTHOR("Hans Verkuil"); 236MODULE_AUTHOR("Hans Verkuil");
237MODULE_DESCRIPTION("CX23418 driver"); 237MODULE_DESCRIPTION("CX23418 driver");
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index da395fef50df..2477461e84d7 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -116,7 +116,7 @@ static int cx18_i2c_new_ir(struct i2c_adapter *adap, u32 hw, const char *type,
116 /* Our default information for ir-kbd-i2c.c to use */ 116 /* Our default information for ir-kbd-i2c.c to use */
117 switch (hw) { 117 switch (hw) {
118 case CX18_HW_Z8F0811_IR_RX_HAUP: 118 case CX18_HW_Z8F0811_IR_RX_HAUP:
119 info.platform_data = &z8f0811_ir_init_data; 119 info.platform_data = (void *) &z8f0811_ir_init_data;
120 break; 120 break;
121 default: 121 default:
122 break; 122 break;
@@ -139,16 +139,16 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
139 139
140 if (hw == CX18_HW_TUNER) { 140 if (hw == CX18_HW_TUNER) {
141 /* special tuner group handling */ 141 /* special tuner group handling */
142 sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, 142 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
143 adap, mod, type, cx->card_i2c->radio); 143 adap, mod, type, 0, cx->card_i2c->radio);
144 if (sd != NULL) 144 if (sd != NULL)
145 sd->grp_id = hw; 145 sd->grp_id = hw;
146 sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, 146 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
147 adap, mod, type, cx->card_i2c->demod); 147 adap, mod, type, 0, cx->card_i2c->demod);
148 if (sd != NULL) 148 if (sd != NULL)
149 sd->grp_id = hw; 149 sd->grp_id = hw;
150 sd = v4l2_i2c_new_probed_subdev(&cx->v4l2_dev, 150 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev,
151 adap, mod, type, cx->card_i2c->tv); 151 adap, mod, type, 0, cx->card_i2c->tv);
152 if (sd != NULL) 152 if (sd != NULL)
153 sd->grp_id = hw; 153 sd->grp_id = hw;
154 return sd != NULL ? 0 : -1; 154 return sd != NULL ? 0 : -1;
@@ -162,7 +162,7 @@ int cx18_i2c_register(struct cx18 *cx, unsigned idx)
162 return -1; 162 return -1;
163 163
164 /* It's an I2C device other than an analog tuner or IR chip */ 164 /* It's an I2C device other than an analog tuner or IR chip */
165 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx]); 165 sd = v4l2_i2c_new_subdev(&cx->v4l2_dev, adap, mod, type, hw_addrs[idx], NULL);
166 if (sd != NULL) 166 if (sd != NULL)
167 sd->grp_id = hw; 167 sd->grp_id = hw;
168 return sd != NULL ? 0 : -1; 168 return sd != NULL ? 0 : -1;
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 54d248e16d85..7df513a2dba8 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -245,9 +245,9 @@ static int cx18_reg_dev(struct cx18 *cx, int type)
245 video_set_drvdata(s->video_dev, s); 245 video_set_drvdata(s->video_dev, s);
246 246
247 /* Register device. First try the desired minor, then any free one. */ 247 /* Register device. First try the desired minor, then any free one. */
248 ret = video_register_device(s->video_dev, vfl_type, num); 248 ret = video_register_device_no_warn(s->video_dev, vfl_type, num);
249 if (ret < 0) { 249 if (ret < 0) {
250 CX18_ERR("Couldn't register v4l2 device for %s kernel number %d\n", 250 CX18_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
251 s->name, num); 251 s->name, num);
252 video_device_release(s->video_dev); 252 video_device_release(s->video_dev);
253 s->video_dev = NULL; 253 s->video_dev = NULL;
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 63d2239fd324..319c459459e0 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -313,7 +313,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
313 if (dev->board.decoder == CX231XX_AVDECODER) { 313 if (dev->board.decoder == CX231XX_AVDECODER) {
314 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 314 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
315 &dev->i2c_bus[0].i2c_adap, 315 &dev->i2c_bus[0].i2c_adap,
316 "cx25840", "cx25840", 0x88 >> 1); 316 "cx25840", "cx25840", 0x88 >> 1, NULL);
317 if (dev->sd_cx25840 == NULL) 317 if (dev->sd_cx25840 == NULL)
318 cx231xx_info("cx25840 subdev registration failure\n"); 318 cx231xx_info("cx25840 subdev registration failure\n");
319 cx25840_call(dev, core, load_fw); 319 cx25840_call(dev, core, load_fw);
@@ -323,7 +323,7 @@ void cx231xx_card_setup(struct cx231xx *dev)
323 if (dev->board.tuner_type != TUNER_ABSENT) { 323 if (dev->board.tuner_type != TUNER_ABSENT) {
324 dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, 324 dev->sd_tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev,
325 &dev->i2c_bus[1].i2c_adap, 325 &dev->i2c_bus[1].i2c_adap,
326 "tuner", "tuner", 0xc2 >> 1); 326 "tuner", "tuner", 0xc2 >> 1, NULL);
327 if (dev->sd_tuner == NULL) 327 if (dev->sd_tuner == NULL)
328 cx231xx_info("tuner subdev registration failure\n"); 328 cx231xx_info("tuner subdev registration failure\n");
329 329
diff --git a/drivers/media/video/cx23885/cimax2.c b/drivers/media/video/cx23885/cimax2.c
index 0316257b7345..c04222ffb286 100644
--- a/drivers/media/video/cx23885/cimax2.c
+++ b/drivers/media/video/cx23885/cimax2.c
@@ -75,7 +75,6 @@ struct netup_ci_state {
75 void *priv; 75 void *priv;
76}; 76};
77 77
78struct mutex gpio_mutex;/* Two CiMax's uses same GPIO lines */
79 78
80int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg, 79int netup_read_i2c(struct i2c_adapter *i2c_adap, u8 addr, u8 reg,
81 u8 *buf, int len) 80 u8 *buf, int len)
@@ -183,10 +182,11 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
183 if (ret != 0) 182 if (ret != 0)
184 return ret; 183 return ret;
185 184
186 mutex_lock(&gpio_mutex); 185 mutex_lock(&dev->gpio_lock);
187 186
188 /* write addr */ 187 /* write addr */
189 cx_write(MC417_OEN, NETUP_EN_ALL); 188 cx_write(MC417_OEN, NETUP_EN_ALL);
189 msleep(2);
190 cx_write(MC417_RWD, NETUP_CTRL_OFF | 190 cx_write(MC417_RWD, NETUP_CTRL_OFF |
191 NETUP_ADLO | (0xff & addr)); 191 NETUP_ADLO | (0xff & addr));
192 cx_clear(MC417_RWD, NETUP_ADLO); 192 cx_clear(MC417_RWD, NETUP_ADLO);
@@ -194,9 +194,10 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
194 NETUP_ADHI | (0xff & (addr >> 8))); 194 NETUP_ADHI | (0xff & (addr >> 8)));
195 cx_clear(MC417_RWD, NETUP_ADHI); 195 cx_clear(MC417_RWD, NETUP_ADHI);
196 196
197 if (read) /* data in */ 197 if (read) { /* data in */
198 cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA); 198 cx_write(MC417_OEN, NETUP_EN_ALL | NETUP_DATA);
199 else /* data out */ 199 msleep(2);
200 } else /* data out */
200 cx_write(MC417_RWD, NETUP_CTRL_OFF | data); 201 cx_write(MC417_RWD, NETUP_CTRL_OFF | data);
201 202
202 /* choose chip */ 203 /* choose chip */
@@ -206,7 +207,7 @@ int netup_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
206 cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR); 207 cx_clear(MC417_RWD, (read) ? NETUP_RD : NETUP_WR);
207 mem = netup_ci_get_mem(dev); 208 mem = netup_ci_get_mem(dev);
208 209
209 mutex_unlock(&gpio_mutex); 210 mutex_unlock(&dev->gpio_lock);
210 211
211 if (!read) 212 if (!read)
212 if (mem < 0) 213 if (mem < 0)
@@ -403,7 +404,6 @@ int netup_ci_init(struct cx23885_tsport *port)
403 switch (port->nr) { 404 switch (port->nr) {
404 case 1: 405 case 1:
405 state->ci_i2c_addr = 0x40; 406 state->ci_i2c_addr = 0x40;
406 mutex_init(&gpio_mutex);
407 break; 407 break;
408 case 2: 408 case 2:
409 state->ci_i2c_addr = 0x41; 409 state->ci_i2c_addr = 0x41;
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index 3143d85ef31d..bfdf79f1033c 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -210,6 +210,10 @@ struct cx23885_board cx23885_boards[] = {
210 .portb = CX23885_MPEG_ENCODER, 210 .portb = CX23885_MPEG_ENCODER,
211 .portc = CX23885_MPEG_DVB, 211 .portc = CX23885_MPEG_DVB,
212 }, 212 },
213 [CX23885_BOARD_COMPRO_VIDEOMATE_E800] = {
214 .name = "Compro VideoMate E800",
215 .portc = CX23885_MPEG_DVB,
216 },
213}; 217};
214const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 218const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
215 219
@@ -341,6 +345,10 @@ struct cx23885_subid cx23885_subids[] = {
341 .subvendor = 0x0070, 345 .subvendor = 0x0070,
342 .subdevice = 0x8541, 346 .subdevice = 0x8541,
343 .card = CX23885_BOARD_HAUPPAUGE_HVR1850, 347 .card = CX23885_BOARD_HAUPPAUGE_HVR1850,
348 }, {
349 .subvendor = 0x1858,
350 .subdevice = 0xe800,
351 .card = CX23885_BOARD_COMPRO_VIDEOMATE_E800,
344 }, 352 },
345}; 353};
346const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 354const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -536,6 +544,7 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
536 case CX23885_BOARD_HAUPPAUGE_HVR1500Q: 544 case CX23885_BOARD_HAUPPAUGE_HVR1500Q:
537 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 545 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
538 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 546 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
547 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
539 /* Tuner Reset Command */ 548 /* Tuner Reset Command */
540 bitmask = 0x04; 549 bitmask = 0x04;
541 break; 550 break;
@@ -687,6 +696,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
687 break; 696 break;
688 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 697 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
689 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 698 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
699 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
690 /* GPIO-2 xc3028 tuner reset */ 700 /* GPIO-2 xc3028 tuner reset */
691 701
692 /* The following GPIO's are on the internal AVCore (cx25840) */ 702 /* The following GPIO's are on the internal AVCore (cx25840) */
@@ -911,6 +921,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
911 case CX23885_BOARD_HAUPPAUGE_HVR1255: 921 case CX23885_BOARD_HAUPPAUGE_HVR1255:
912 case CX23885_BOARD_HAUPPAUGE_HVR1210: 922 case CX23885_BOARD_HAUPPAUGE_HVR1210:
913 case CX23885_BOARD_HAUPPAUGE_HVR1850: 923 case CX23885_BOARD_HAUPPAUGE_HVR1850:
924 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
914 default: 925 default:
915 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 926 ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
916 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 927 ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
@@ -927,9 +938,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
927 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 938 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
928 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 939 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
929 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 940 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
941 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
930 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, 942 dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->v4l2_dev,
931 &dev->i2c_bus[2].i2c_adap, 943 &dev->i2c_bus[2].i2c_adap,
932 "cx25840", "cx25840", 0x88 >> 1); 944 "cx25840", "cx25840", 0x88 >> 1, NULL);
933 v4l2_subdev_call(dev->sd_cx25840, core, load_fw); 945 v4l2_subdev_call(dev->sd_cx25840, core, load_fw);
934 break; 946 break;
935 } 947 }
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 40d438d7234d..c31284ba19dd 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -758,6 +758,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
758 int i; 758 int i;
759 759
760 mutex_init(&dev->lock); 760 mutex_init(&dev->lock);
761 mutex_init(&dev->gpio_lock);
761 762
762 atomic_inc(&dev->refcount); 763 atomic_inc(&dev->refcount);
763 764
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 022fad798fc2..45e13ee66dc7 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -255,15 +255,18 @@ static struct tda18271_std_map hauppauge_hvr1200_tda18271_std_map = {
255static struct tda18271_config hauppauge_tda18271_config = { 255static struct tda18271_config hauppauge_tda18271_config = {
256 .std_map = &hauppauge_tda18271_std_map, 256 .std_map = &hauppauge_tda18271_std_map,
257 .gate = TDA18271_GATE_ANALOG, 257 .gate = TDA18271_GATE_ANALOG,
258 .output_opt = TDA18271_OUTPUT_LT_OFF,
258}; 259};
259 260
260static struct tda18271_config hauppauge_hvr1200_tuner_config = { 261static struct tda18271_config hauppauge_hvr1200_tuner_config = {
261 .std_map = &hauppauge_hvr1200_tda18271_std_map, 262 .std_map = &hauppauge_hvr1200_tda18271_std_map,
262 .gate = TDA18271_GATE_ANALOG, 263 .gate = TDA18271_GATE_ANALOG,
264 .output_opt = TDA18271_OUTPUT_LT_OFF,
263}; 265};
264 266
265static struct tda18271_config hauppauge_hvr1210_tuner_config = { 267static struct tda18271_config hauppauge_hvr1210_tuner_config = {
266 .gate = TDA18271_GATE_DIGITAL, 268 .gate = TDA18271_GATE_DIGITAL,
269 .output_opt = TDA18271_OUTPUT_LT_OFF,
267}; 270};
268 271
269static struct tda18271_std_map hauppauge_hvr127x_std_map = { 272static struct tda18271_std_map hauppauge_hvr127x_std_map = {
@@ -275,6 +278,7 @@ static struct tda18271_std_map hauppauge_hvr127x_std_map = {
275 278
276static struct tda18271_config hauppauge_hvr127x_config = { 279static struct tda18271_config hauppauge_hvr127x_config = {
277 .std_map = &hauppauge_hvr127x_std_map, 280 .std_map = &hauppauge_hvr127x_std_map,
281 .output_opt = TDA18271_OUTPUT_LT_OFF,
278}; 282};
279 283
280static struct lgdt3305_config hauppauge_lgdt3305_config = { 284static struct lgdt3305_config hauppauge_lgdt3305_config = {
@@ -743,6 +747,7 @@ static int dvb_register(struct cx23885_tsport *port)
743 } 747 }
744 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 748 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
745 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 749 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
750 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
746 i2c_bus = &dev->i2c_bus[0]; 751 i2c_bus = &dev->i2c_bus[0];
747 752
748 fe0->dvb.frontend = dvb_attach(zl10353_attach, 753 fe0->dvb.frontend = dvb_attach(zl10353_attach,
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 5d6093336300..654cc253cd50 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1521,11 +1521,11 @@ int cx23885_video_register(struct cx23885_dev *dev)
1521 if (dev->tuner_addr) 1521 if (dev->tuner_addr)
1522 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1522 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1523 &dev->i2c_bus[1].i2c_adap, 1523 &dev->i2c_bus[1].i2c_adap,
1524 "tuner", "tuner", dev->tuner_addr); 1524 "tuner", "tuner", dev->tuner_addr, NULL);
1525 else 1525 else
1526 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 1526 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1527 &dev->i2c_bus[1].i2c_adap, 1527 &dev->i2c_bus[1].i2c_adap,
1528 "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV)); 1528 "tuner", "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
1529 if (sd) { 1529 if (sd) {
1530 struct tuner_setup tun_setup; 1530 struct tuner_setup tun_setup;
1531 1531
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 86f26947bb78..cc7a165561ff 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -78,6 +78,7 @@
78#define CX23885_BOARD_MYGICA_X8506 22 78#define CX23885_BOARD_MYGICA_X8506 22
79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23 79#define CX23885_BOARD_MAGICPRO_PROHDTVE2 23
80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24 80#define CX23885_BOARD_HAUPPAUGE_HVR1850 24
81#define CX23885_BOARD_COMPRO_VIDEOMATE_E800 25
81 82
82#define GPIO_0 0x00000001 83#define GPIO_0 0x00000001
83#define GPIO_1 0x00000002 84#define GPIO_1 0x00000002
@@ -325,6 +326,7 @@ struct cx23885_dev {
325 326
326 int nr; 327 int nr;
327 struct mutex lock; 328 struct mutex lock;
329 struct mutex gpio_lock;
328 330
329 /* board details */ 331 /* board details */
330 unsigned int board; 332 unsigned int board;
diff --git a/drivers/media/video/cx23885/netup-eeprom.c b/drivers/media/video/cx23885/netup-eeprom.c
index 042bbbbd48f8..98a48f500684 100644
--- a/drivers/media/video/cx23885/netup-eeprom.c
+++ b/drivers/media/video/cx23885/netup-eeprom.c
@@ -97,11 +97,11 @@ void netup_get_card_info(struct i2c_adapter *i2c_adap,
97{ 97{
98 int i, j; 98 int i, j;
99 99
100 cinfo->rev = netup_eeprom_read(i2c_adap, 13); 100 cinfo->rev = netup_eeprom_read(i2c_adap, 63);
101 101
102 for (i = 0, j = 0; i < 6; i++, j++) 102 for (i = 64, j = 0; i < 70; i++, j++)
103 cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i); 103 cinfo->port[0].mac[j] = netup_eeprom_read(i2c_adap, i);
104 104
105 for (i = 6, j = 0; i < 12; i++, j++) 105 for (i = 70, j = 0; i < 76; i++, j++)
106 cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i); 106 cinfo->port[1].mac[j] = netup_eeprom_read(i2c_adap, i);
107}; 107};
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index e5f07fbd5a35..33be6369871a 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -3439,20 +3439,20 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
3439 The radio_type is sometimes missing, or set to UNSET but 3439 The radio_type is sometimes missing, or set to UNSET but
3440 later code configures a tea5767. 3440 later code configures a tea5767.
3441 */ 3441 */
3442 v4l2_i2c_new_probed_subdev(&core->v4l2_dev, &core->i2c_adap, 3442 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
3443 "tuner", "tuner", 3443 "tuner", "tuner",
3444 v4l2_i2c_tuner_addrs(ADDRS_RADIO)); 3444 0, v4l2_i2c_tuner_addrs(ADDRS_RADIO));
3445 if (has_demod) 3445 if (has_demod)
3446 v4l2_i2c_new_probed_subdev(&core->v4l2_dev, 3446 v4l2_i2c_new_subdev(&core->v4l2_dev,
3447 &core->i2c_adap, "tuner", "tuner", 3447 &core->i2c_adap, "tuner", "tuner",
3448 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 3448 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
3449 if (core->board.tuner_addr == ADDR_UNSET) { 3449 if (core->board.tuner_addr == ADDR_UNSET) {
3450 v4l2_i2c_new_probed_subdev(&core->v4l2_dev, 3450 v4l2_i2c_new_subdev(&core->v4l2_dev,
3451 &core->i2c_adap, "tuner", "tuner", 3451 &core->i2c_adap, "tuner", "tuner",
3452 has_demod ? tv_addrs + 4 : tv_addrs); 3452 0, has_demod ? tv_addrs + 4 : tv_addrs);
3453 } else { 3453 } else {
3454 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, 3454 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
3455 "tuner", "tuner", core->board.tuner_addr); 3455 "tuner", "tuner", core->board.tuner_addr, NULL);
3456 } 3456 }
3457 } 3457 }
3458 3458
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 2bb54c3ef5cd..81d2b5dea18e 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -1881,14 +1881,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1881 1881
1882 if (core->board.audio_chip == V4L2_IDENT_WM8775) 1882 if (core->board.audio_chip == V4L2_IDENT_WM8775)
1883 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, 1883 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap,
1884 "wm8775", "wm8775", 0x36 >> 1); 1884 "wm8775", "wm8775", 0x36 >> 1, NULL);
1885 1885
1886 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { 1886 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
1887 /* This probes for a tda9874 as is used on some 1887 /* This probes for a tda9874 as is used on some
1888 Pixelview Ultra boards. */ 1888 Pixelview Ultra boards. */
1889 v4l2_i2c_new_probed_subdev_addr(&core->v4l2_dev, 1889 v4l2_i2c_new_subdev(&core->v4l2_dev,
1890 &core->i2c_adap, 1890 &core->i2c_adap,
1891 "tvaudio", "tvaudio", 0xb0 >> 1); 1891 "tvaudio", "tvaudio", 0, I2C_ADDRS(0xb0 >> 1));
1892 } 1892 }
1893 1893
1894 switch (core->boardnr) { 1894 switch (core->boardnr) {
diff --git a/drivers/media/video/davinci/Makefile b/drivers/media/video/davinci/Makefile
new file mode 100644
index 000000000000..1a8b8f3f182e
--- /dev/null
+++ b/drivers/media/video/davinci/Makefile
@@ -0,0 +1,17 @@
1#
2# Makefile for the davinci video device drivers.
3#
4
5# VPIF
6obj-$(CONFIG_VIDEO_DAVINCI_VPIF) += vpif.o
7
8#DM646x EVM Display driver
9obj-$(CONFIG_DISPLAY_DAVINCI_DM646X_EVM) += vpif_display.o
10#DM646x EVM Capture driver
11obj-$(CONFIG_CAPTURE_DAVINCI_DM646X_EVM) += vpif_capture.o
12
13# Capture: DM6446 and DM355
14obj-$(CONFIG_VIDEO_VPSS_SYSTEM) += vpss.o
15obj-$(CONFIG_VIDEO_VPFE_CAPTURE) += vpfe_capture.o
16obj-$(CONFIG_VIDEO_DM6446_CCDC) += dm644x_ccdc.o
17obj-$(CONFIG_VIDEO_DM355_CCDC) += dm355_ccdc.o
diff --git a/drivers/media/video/davinci/ccdc_hw_device.h b/drivers/media/video/davinci/ccdc_hw_device.h
new file mode 100644
index 000000000000..86b9b3518965
--- /dev/null
+++ b/drivers/media/video/davinci/ccdc_hw_device.h
@@ -0,0 +1,110 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * ccdc device API
19 */
20#ifndef _CCDC_HW_DEVICE_H
21#define _CCDC_HW_DEVICE_H
22
23#ifdef __KERNEL__
24#include <linux/videodev2.h>
25#include <linux/device.h>
26#include <media/davinci/vpfe_types.h>
27#include <media/davinci/ccdc_types.h>
28
29/*
30 * ccdc hw operations
31 */
32struct ccdc_hw_ops {
33 /* Pointer to initialize function to initialize ccdc device */
34 int (*open) (struct device *dev);
35 /* Pointer to deinitialize function */
36 int (*close) (struct device *dev);
37 /* set ccdc base address */
38 void (*set_ccdc_base)(void *base, int size);
39 /* Pointer to function to enable or disable ccdc */
40 void (*enable) (int en);
41 /* reset sbl. only for 6446 */
42 void (*reset) (void);
43 /* enable output to sdram */
44 void (*enable_out_to_sdram) (int en);
45 /* Pointer to function to set hw parameters */
46 int (*set_hw_if_params) (struct vpfe_hw_if_param *param);
47 /* get interface parameters */
48 int (*get_hw_if_params) (struct vpfe_hw_if_param *param);
49 /*
50 * Pointer to function to set parameters. Used
51 * for implementing VPFE_S_CCDC_PARAMS
52 */
53 int (*set_params) (void *params);
54 /*
55 * Pointer to function to get parameter. Used
56 * for implementing VPFE_G_CCDC_PARAMS
57 */
58 int (*get_params) (void *params);
59 /* Pointer to function to configure ccdc */
60 int (*configure) (void);
61
62 /* Pointer to function to set buffer type */
63 int (*set_buftype) (enum ccdc_buftype buf_type);
64 /* Pointer to function to get buffer type */
65 enum ccdc_buftype (*get_buftype) (void);
66 /* Pointer to function to set frame format */
67 int (*set_frame_format) (enum ccdc_frmfmt frm_fmt);
68 /* Pointer to function to get frame format */
69 enum ccdc_frmfmt (*get_frame_format) (void);
70 /* enumerate hw pix formats */
71 int (*enum_pix)(u32 *hw_pix, int i);
72 /* Pointer to function to set buffer type */
73 u32 (*get_pixel_format) (void);
74 /* Pointer to function to get pixel format. */
75 int (*set_pixel_format) (u32 pixfmt);
76 /* Pointer to function to set image window */
77 int (*set_image_window) (struct v4l2_rect *win);
78 /* Pointer to function to set image window */
79 void (*get_image_window) (struct v4l2_rect *win);
80 /* Pointer to function to get line length */
81 unsigned int (*get_line_length) (void);
82
83 /* Query CCDC control IDs */
84 int (*queryctrl)(struct v4l2_queryctrl *qctrl);
85 /* Set CCDC control */
86 int (*set_control)(struct v4l2_control *ctrl);
87 /* Get CCDC control */
88 int (*get_control)(struct v4l2_control *ctrl);
89
90 /* Pointer to function to set frame buffer address */
91 void (*setfbaddr) (unsigned long addr);
92 /* Pointer to function to get field id */
93 int (*getfid) (void);
94};
95
96struct ccdc_hw_device {
97 /* ccdc device name */
98 char name[32];
99 /* module owner */
100 struct module *owner;
101 /* hw ops */
102 struct ccdc_hw_ops hw_ops;
103};
104
105/* Used by CCDC module to register & unregister with vpfe capture driver */
106int vpfe_register_ccdc_device(struct ccdc_hw_device *dev);
107void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev);
108
109#endif
110#endif
diff --git a/drivers/media/video/davinci/dm355_ccdc.c b/drivers/media/video/davinci/dm355_ccdc.c
new file mode 100644
index 000000000000..4629cabe3f28
--- /dev/null
+++ b/drivers/media/video/davinci/dm355_ccdc.c
@@ -0,0 +1,978 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * CCDC hardware module for DM355
19 * ------------------------------
20 *
21 * This module is for configuring DM355 CCD controller of VPFE to capture
22 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
23 * such as Defect Pixel Correction, Color Space Conversion etc to
24 * pre-process the Bayer RGB data, before writing it to SDRAM. This
25 * module also allows application to configure individual
26 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
27 * To do so, application include dm355_ccdc.h and vpfe_capture.h header
28 * files. The setparams() API is called by vpfe_capture driver
29 * to configure module parameters
30 *
31 * TODO: 1) Raw bayer parameter settings and bayer capture
32 * 2) Split module parameter structure to module specific ioctl structs
33 * 3) add support for lense shading correction
34 * 4) investigate if enum used for user space type definition
35 * to be replaced by #defines or integer
36 */
37#include <linux/platform_device.h>
38#include <linux/uaccess.h>
39#include <linux/videodev2.h>
40#include <media/davinci/dm355_ccdc.h>
41#include <media/davinci/vpss.h>
42#include "dm355_ccdc_regs.h"
43#include "ccdc_hw_device.h"
44
45MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM355");
47MODULE_AUTHOR("Texas Instruments");
48
49static struct device *dev;
50
51/* Object for CCDC raw mode */
52static struct ccdc_params_raw ccdc_hw_params_raw = {
53 .pix_fmt = CCDC_PIXFMT_RAW,
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
55 .win = CCDC_WIN_VGA,
56 .fid_pol = VPFE_PINPOL_POSITIVE,
57 .vd_pol = VPFE_PINPOL_POSITIVE,
58 .hd_pol = VPFE_PINPOL_POSITIVE,
59 .gain = {
60 .r_ye = 256,
61 .gb_g = 256,
62 .gr_cy = 256,
63 .b_mg = 256
64 },
65 .config_params = {
66 .datasft = 2,
67 .data_sz = CCDC_DATA_10BITS,
68 .mfilt1 = CCDC_NO_MEDIAN_FILTER1,
69 .mfilt2 = CCDC_NO_MEDIAN_FILTER2,
70 .alaw = {
71 .gama_wd = 2,
72 },
73 .blk_clamp = {
74 .sample_pixel = 1,
75 .dc_sub = 25
76 },
77 .col_pat_field0 = {
78 .olop = CCDC_GREEN_BLUE,
79 .olep = CCDC_BLUE,
80 .elop = CCDC_RED,
81 .elep = CCDC_GREEN_RED
82 },
83 .col_pat_field1 = {
84 .olop = CCDC_GREEN_BLUE,
85 .olep = CCDC_BLUE,
86 .elop = CCDC_RED,
87 .elep = CCDC_GREEN_RED
88 },
89 },
90};
91
92
93/* Object for CCDC ycbcr mode */
94static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
95 .win = CCDC_WIN_PAL,
96 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
97 .frm_fmt = CCDC_FRMFMT_INTERLACED,
98 .fid_pol = VPFE_PINPOL_POSITIVE,
99 .vd_pol = VPFE_PINPOL_POSITIVE,
100 .hd_pol = VPFE_PINPOL_POSITIVE,
101 .bt656_enable = 1,
102 .pix_order = CCDC_PIXORDER_CBYCRY,
103 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
104};
105
106static enum vpfe_hw_if_type ccdc_if_type;
107static void *__iomem ccdc_base_addr;
108static int ccdc_addr_size;
109
110/* Raw Bayer formats */
111static u32 ccdc_raw_bayer_pix_formats[] =
112 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
113
114/* Raw YUV formats */
115static u32 ccdc_raw_yuv_pix_formats[] =
116 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
117
118/* register access routines */
119static inline u32 regr(u32 offset)
120{
121 return __raw_readl(ccdc_base_addr + offset);
122}
123
124static inline void regw(u32 val, u32 offset)
125{
126 __raw_writel(val, ccdc_base_addr + offset);
127}
128
129static void ccdc_set_ccdc_base(void *addr, int size)
130{
131 ccdc_base_addr = addr;
132 ccdc_addr_size = size;
133}
134
135static void ccdc_enable(int en)
136{
137 unsigned int temp;
138 temp = regr(SYNCEN);
139 temp &= (~CCDC_SYNCEN_VDHDEN_MASK);
140 temp |= (en & CCDC_SYNCEN_VDHDEN_MASK);
141 regw(temp, SYNCEN);
142}
143
144static void ccdc_enable_output_to_sdram(int en)
145{
146 unsigned int temp;
147 temp = regr(SYNCEN);
148 temp &= (~(CCDC_SYNCEN_WEN_MASK));
149 temp |= ((en << CCDC_SYNCEN_WEN_SHIFT) & CCDC_SYNCEN_WEN_MASK);
150 regw(temp, SYNCEN);
151}
152
153static void ccdc_config_gain_offset(void)
154{
155 /* configure gain */
156 regw(ccdc_hw_params_raw.gain.r_ye, RYEGAIN);
157 regw(ccdc_hw_params_raw.gain.gr_cy, GRCYGAIN);
158 regw(ccdc_hw_params_raw.gain.gb_g, GBGGAIN);
159 regw(ccdc_hw_params_raw.gain.b_mg, BMGGAIN);
160 /* configure offset */
161 regw(ccdc_hw_params_raw.ccdc_offset, OFFSET);
162}
163
164/*
165 * ccdc_restore_defaults()
166 * This function restore power on defaults in the ccdc registers
167 */
168static int ccdc_restore_defaults(void)
169{
170 int i;
171
172 dev_dbg(dev, "\nstarting ccdc_restore_defaults...");
173 /* set all registers to zero */
174 for (i = 0; i <= CCDC_REG_LAST; i += 4)
175 regw(0, i);
176
177 /* now override the values with power on defaults in registers */
178 regw(MODESET_DEFAULT, MODESET);
179 /* no culling support */
180 regw(CULH_DEFAULT, CULH);
181 regw(CULV_DEFAULT, CULV);
182 /* Set default Gain and Offset */
183 ccdc_hw_params_raw.gain.r_ye = GAIN_DEFAULT;
184 ccdc_hw_params_raw.gain.gb_g = GAIN_DEFAULT;
185 ccdc_hw_params_raw.gain.gr_cy = GAIN_DEFAULT;
186 ccdc_hw_params_raw.gain.b_mg = GAIN_DEFAULT;
187 ccdc_config_gain_offset();
188 regw(OUTCLIP_DEFAULT, OUTCLIP);
189 regw(LSCCFG2_DEFAULT, LSCCFG2);
190 /* select ccdc input */
191 if (vpss_select_ccdc_source(VPSS_CCDCIN)) {
192 dev_dbg(dev, "\ncouldn't select ccdc input source");
193 return -EFAULT;
194 }
195 /* select ccdc clock */
196 if (vpss_enable_clock(VPSS_CCDC_CLOCK, 1) < 0) {
197 dev_dbg(dev, "\ncouldn't enable ccdc clock");
198 return -EFAULT;
199 }
200 dev_dbg(dev, "\nEnd of ccdc_restore_defaults...");
201 return 0;
202}
203
204static int ccdc_open(struct device *device)
205{
206 dev = device;
207 return ccdc_restore_defaults();
208}
209
210static int ccdc_close(struct device *device)
211{
212 /* disable clock */
213 vpss_enable_clock(VPSS_CCDC_CLOCK, 0);
214 /* do nothing for now */
215 return 0;
216}
217/*
218 * ccdc_setwin()
219 * This function will configure the window size to
220 * be capture in CCDC reg.
221 */
222static void ccdc_setwin(struct v4l2_rect *image_win,
223 enum ccdc_frmfmt frm_fmt, int ppc)
224{
225 int horz_start, horz_nr_pixels;
226 int vert_start, vert_nr_lines;
227 int mid_img = 0;
228
229 dev_dbg(dev, "\nStarting ccdc_setwin...");
230
231 /*
232 * ppc - per pixel count. indicates how many pixels per cell
233 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
234 * raw capture this is 1
235 */
236 horz_start = image_win->left << (ppc - 1);
237 horz_nr_pixels = ((image_win->width) << (ppc - 1)) - 1;
238
239 /* Writing the horizontal info into the registers */
240 regw(horz_start, SPH);
241 regw(horz_nr_pixels, NPH);
242 vert_start = image_win->top;
243
244 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
245 vert_nr_lines = (image_win->height >> 1) - 1;
246 vert_start >>= 1;
247 /* Since first line doesn't have any data */
248 vert_start += 1;
249 /* configure VDINT0 and VDINT1 */
250 regw(vert_start, VDINT0);
251 } else {
252 /* Since first line doesn't have any data */
253 vert_start += 1;
254 vert_nr_lines = image_win->height - 1;
255 /* configure VDINT0 and VDINT1 */
256 mid_img = vert_start + (image_win->height / 2);
257 regw(vert_start, VDINT0);
258 regw(mid_img, VDINT1);
259 }
260 regw(vert_start & CCDC_START_VER_ONE_MASK, SLV0);
261 regw(vert_start & CCDC_START_VER_TWO_MASK, SLV1);
262 regw(vert_nr_lines & CCDC_NUM_LINES_VER, NLV);
263 dev_dbg(dev, "\nEnd of ccdc_setwin...");
264}
265
266static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
267{
268 if (ccdcparam->datasft < CCDC_DATA_NO_SHIFT ||
269 ccdcparam->datasft > CCDC_DATA_SHIFT_6BIT) {
270 dev_dbg(dev, "Invalid value of data shift\n");
271 return -EINVAL;
272 }
273
274 if (ccdcparam->mfilt1 < CCDC_NO_MEDIAN_FILTER1 ||
275 ccdcparam->mfilt1 > CCDC_MEDIAN_FILTER1) {
276 dev_dbg(dev, "Invalid value of median filter1\n");
277 return -EINVAL;
278 }
279
280 if (ccdcparam->mfilt2 < CCDC_NO_MEDIAN_FILTER2 ||
281 ccdcparam->mfilt2 > CCDC_MEDIAN_FILTER2) {
282 dev_dbg(dev, "Invalid value of median filter2\n");
283 return -EINVAL;
284 }
285
286 if ((ccdcparam->med_filt_thres < 0) ||
287 (ccdcparam->med_filt_thres > CCDC_MED_FILT_THRESH)) {
288 dev_dbg(dev, "Invalid value of median filter thresold\n");
289 return -EINVAL;
290 }
291
292 if (ccdcparam->data_sz < CCDC_DATA_16BITS ||
293 ccdcparam->data_sz > CCDC_DATA_8BITS) {
294 dev_dbg(dev, "Invalid value of data size\n");
295 return -EINVAL;
296 }
297
298 if (ccdcparam->alaw.enable) {
299 if (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_13_4 ||
300 ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) {
301 dev_dbg(dev, "Invalid value of ALAW\n");
302 return -EINVAL;
303 }
304 }
305
306 if (ccdcparam->blk_clamp.b_clamp_enable) {
307 if (ccdcparam->blk_clamp.sample_pixel < CCDC_SAMPLE_1PIXELS ||
308 ccdcparam->blk_clamp.sample_pixel > CCDC_SAMPLE_16PIXELS) {
309 dev_dbg(dev, "Invalid value of sample pixel\n");
310 return -EINVAL;
311 }
312 if (ccdcparam->blk_clamp.sample_ln < CCDC_SAMPLE_1LINES ||
313 ccdcparam->blk_clamp.sample_ln > CCDC_SAMPLE_16LINES) {
314 dev_dbg(dev, "Invalid value of sample lines\n");
315 return -EINVAL;
316 }
317 }
318 return 0;
319}
320
321/* Parameter operations */
322static int ccdc_set_params(void __user *params)
323{
324 struct ccdc_config_params_raw ccdc_raw_params;
325 int x;
326
327 /* only raw module parameters can be set through the IOCTL */
328 if (ccdc_if_type != VPFE_RAW_BAYER)
329 return -EINVAL;
330
331 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
332 if (x) {
333 dev_dbg(dev, "ccdc_set_params: error in copying ccdc"
334 "params, %d\n", x);
335 return -EFAULT;
336 }
337
338 if (!validate_ccdc_param(&ccdc_raw_params)) {
339 memcpy(&ccdc_hw_params_raw.config_params,
340 &ccdc_raw_params,
341 sizeof(ccdc_raw_params));
342 return 0;
343 }
344 return -EINVAL;
345}
346
347/* This function will configure CCDC for YCbCr video capture */
348static void ccdc_config_ycbcr(void)
349{
350 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
351 u32 temp;
352
353 /* first set the CCDC power on defaults values in all registers */
354 dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
355 ccdc_restore_defaults();
356
357 /* configure pixel format & video frame format */
358 temp = (((params->pix_fmt & CCDC_INPUT_MODE_MASK) <<
359 CCDC_INPUT_MODE_SHIFT) |
360 ((params->frm_fmt & CCDC_FRM_FMT_MASK) <<
361 CCDC_FRM_FMT_SHIFT));
362
363 /* setup BT.656 sync mode */
364 if (params->bt656_enable) {
365 regw(CCDC_REC656IF_BT656_EN, REC656IF);
366 /*
367 * configure the FID, VD, HD pin polarity fld,hd pol positive,
368 * vd negative, 8-bit pack mode
369 */
370 temp |= CCDC_VD_POL_NEGATIVE;
371 } else { /* y/c external sync mode */
372 temp |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
373 CCDC_FID_POL_SHIFT) |
374 ((params->hd_pol & CCDC_HD_POL_MASK) <<
375 CCDC_HD_POL_SHIFT) |
376 ((params->vd_pol & CCDC_VD_POL_MASK) <<
377 CCDC_VD_POL_SHIFT));
378 }
379
380 /* pack the data to 8-bit */
381 temp |= CCDC_DATA_PACK_ENABLE;
382
383 regw(temp, MODESET);
384
385 /* configure video window */
386 ccdc_setwin(&params->win, params->frm_fmt, 2);
387
388 /* configure the order of y cb cr in SD-RAM */
389 temp = (params->pix_order << CCDC_Y8POS_SHIFT);
390 temp |= CCDC_LATCH_ON_VSYNC_DISABLE | CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC;
391 regw(temp, CCDCFG);
392
393 /*
394 * configure the horizontal line offset. This is done by rounding up
395 * width to a multiple of 16 pixels and multiply by two to account for
396 * y:cb:cr 4:2:2 data
397 */
398 regw(((params->win.width * 2 + 31) >> 5), HSIZE);
399
400 /* configure the memory line offset */
401 if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED) {
402 /* two fields are interleaved in memory */
403 regw(CCDC_SDOFST_FIELD_INTERLEAVED, SDOFST);
404 }
405
406 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
407}
408
409/*
410 * ccdc_config_black_clamp()
411 * configure parameters for Optical Black Clamp
412 */
413static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
414{
415 u32 val;
416
417 if (!bclamp->b_clamp_enable) {
418 /* configure DCSub */
419 regw(bclamp->dc_sub & CCDC_BLK_DC_SUB_MASK, DCSUB);
420 regw(0x0000, CLAMP);
421 return;
422 }
423 /* Enable the Black clamping, set sample lines and pixels */
424 val = (bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) |
425 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
426 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE;
427 regw(val, CLAMP);
428
429 /* If Black clamping is enable then make dcsub 0 */
430 val = (bclamp->sample_ln & CCDC_NUM_LINE_CALC_MASK)
431 << CCDC_NUM_LINE_CALC_SHIFT;
432 regw(val, DCSUB);
433}
434
435/*
436 * ccdc_config_black_compense()
437 * configure parameters for Black Compensation
438 */
439static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
440{
441 u32 val;
442
443 val = (bcomp->b & CCDC_BLK_COMP_MASK) |
444 ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
445 CCDC_BLK_COMP_GB_COMP_SHIFT);
446 regw(val, BLKCMP1);
447
448 val = ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
449 CCDC_BLK_COMP_GR_COMP_SHIFT) |
450 ((bcomp->r & CCDC_BLK_COMP_MASK) <<
451 CCDC_BLK_COMP_R_COMP_SHIFT);
452 regw(val, BLKCMP0);
453}
454
455/*
456 * ccdc_write_dfc_entry()
457 * write an entry in the dfc table.
458 */
459int ccdc_write_dfc_entry(int index, struct ccdc_vertical_dft *dfc)
460{
461/* TODO This is to be re-visited and adjusted */
462#define DFC_WRITE_WAIT_COUNT 1000
463 u32 val, count = DFC_WRITE_WAIT_COUNT;
464
465 regw(dfc->dft_corr_vert[index], DFCMEM0);
466 regw(dfc->dft_corr_horz[index], DFCMEM1);
467 regw(dfc->dft_corr_sub1[index], DFCMEM2);
468 regw(dfc->dft_corr_sub2[index], DFCMEM3);
469 regw(dfc->dft_corr_sub3[index], DFCMEM4);
470 /* set WR bit to write */
471 val = regr(DFCMEMCTL) | CCDC_DFCMEMCTL_DFCMWR_MASK;
472 regw(val, DFCMEMCTL);
473
474 /*
475 * Assume, it is very short. If we get an error, we need to
476 * adjust this value
477 */
478 while (regr(DFCMEMCTL) & CCDC_DFCMEMCTL_DFCMWR_MASK)
479 count--;
480 /*
481 * TODO We expect the count to be non-zero to be successful. Adjust
482 * the count if write requires more time
483 */
484
485 if (count) {
486 dev_err(dev, "defect table write timeout !!!\n");
487 return -1;
488 }
489 return 0;
490}
491
492/*
493 * ccdc_config_vdfc()
494 * configure parameters for Vertical Defect Correction
495 */
496static int ccdc_config_vdfc(struct ccdc_vertical_dft *dfc)
497{
498 u32 val;
499 int i;
500
501 /* Configure General Defect Correction. The table used is from IPIPE */
502 val = dfc->gen_dft_en & CCDC_DFCCTL_GDFCEN_MASK;
503
504 /* Configure Vertical Defect Correction if needed */
505 if (!dfc->ver_dft_en) {
506 /* Enable only General Defect Correction */
507 regw(val, DFCCTL);
508 return 0;
509 }
510
511 if (dfc->table_size > CCDC_DFT_TABLE_SIZE)
512 return -EINVAL;
513
514 val |= CCDC_DFCCTL_VDFC_DISABLE;
515 val |= (dfc->dft_corr_ctl.vdfcsl & CCDC_DFCCTL_VDFCSL_MASK) <<
516 CCDC_DFCCTL_VDFCSL_SHIFT;
517 val |= (dfc->dft_corr_ctl.vdfcuda & CCDC_DFCCTL_VDFCUDA_MASK) <<
518 CCDC_DFCCTL_VDFCUDA_SHIFT;
519 val |= (dfc->dft_corr_ctl.vdflsft & CCDC_DFCCTL_VDFLSFT_MASK) <<
520 CCDC_DFCCTL_VDFLSFT_SHIFT;
521 regw(val , DFCCTL);
522
523 /* clear address ptr to offset 0 */
524 val = CCDC_DFCMEMCTL_DFCMARST_MASK << CCDC_DFCMEMCTL_DFCMARST_SHIFT;
525
526 /* write defect table entries */
527 for (i = 0; i < dfc->table_size; i++) {
528 /* increment address for non zero index */
529 if (i != 0)
530 val = CCDC_DFCMEMCTL_INC_ADDR;
531 regw(val, DFCMEMCTL);
532 if (ccdc_write_dfc_entry(i, dfc) < 0)
533 return -EFAULT;
534 }
535
536 /* update saturation level and enable dfc */
537 regw(dfc->saturation_ctl & CCDC_VDC_DFCVSAT_MASK, DFCVSAT);
538 val = regr(DFCCTL) | (CCDC_DFCCTL_VDFCEN_MASK <<
539 CCDC_DFCCTL_VDFCEN_SHIFT);
540 regw(val, DFCCTL);
541 return 0;
542}
543
544/*
545 * ccdc_config_csc()
546 * configure parameters for color space conversion
547 * Each register CSCM0-7 has two values in S8Q5 format.
548 */
549static void ccdc_config_csc(struct ccdc_csc *csc)
550{
551 u32 val1, val2;
552 int i;
553
554 if (!csc->enable)
555 return;
556
557 /* Enable the CSC sub-module */
558 regw(CCDC_CSC_ENABLE, CSCCTL);
559
560 /* Converting the co-eff as per the format of the register */
561 for (i = 0; i < CCDC_CSC_COEFF_TABLE_SIZE; i++) {
562 if ((i % 2) == 0) {
563 /* CSCM - LSB */
564 val1 = (csc->coeff[i].integer &
565 CCDC_CSC_COEF_INTEG_MASK)
566 << CCDC_CSC_COEF_INTEG_SHIFT;
567 /*
568 * convert decimal part to binary. Use 2 decimal
569 * precision, user values range from .00 - 0.99
570 */
571 val1 |= (((csc->coeff[i].decimal &
572 CCDC_CSC_COEF_DECIMAL_MASK) *
573 CCDC_CSC_DEC_MAX) / 100);
574 } else {
575
576 /* CSCM - MSB */
577 val2 = (csc->coeff[i].integer &
578 CCDC_CSC_COEF_INTEG_MASK)
579 << CCDC_CSC_COEF_INTEG_SHIFT;
580 val2 |= (((csc->coeff[i].decimal &
581 CCDC_CSC_COEF_DECIMAL_MASK) *
582 CCDC_CSC_DEC_MAX) / 100);
583 val2 <<= CCDC_CSCM_MSB_SHIFT;
584 val2 |= val1;
585 regw(val2, (CSCM0 + ((i - 1) << 1)));
586 }
587 }
588}
589
590/*
591 * ccdc_config_color_patterns()
592 * configure parameters for color patterns
593 */
594static void ccdc_config_color_patterns(struct ccdc_col_pat *pat0,
595 struct ccdc_col_pat *pat1)
596{
597 u32 val;
598
599 val = (pat0->olop | (pat0->olep << 2) | (pat0->elop << 4) |
600 (pat0->elep << 6) | (pat1->olop << 8) | (pat1->olep << 10) |
601 (pat1->elop << 12) | (pat1->elep << 14));
602 regw(val, COLPTN);
603}
604
605/* This function will configure CCDC for Raw mode image capture */
606static int ccdc_config_raw(void)
607{
608 struct ccdc_params_raw *params = &ccdc_hw_params_raw;
609 struct ccdc_config_params_raw *config_params =
610 &ccdc_hw_params_raw.config_params;
611 unsigned int val;
612
613 dev_dbg(dev, "\nStarting ccdc_config_raw...");
614
615 /* restore power on defaults to register */
616 ccdc_restore_defaults();
617
618 /* CCDCFG register:
619 * set CCD Not to swap input since input is RAW data
620 * set FID detection function to Latch at V-Sync
621 * set WENLOG - ccdc valid area to AND
622 * set TRGSEL to WENBIT
623 * set EXTRG to DISABLE
624 * disable latching function on VSYNC - shadowed registers
625 */
626 regw(CCDC_YCINSWP_RAW | CCDC_CCDCFG_FIDMD_LATCH_VSYNC |
627 CCDC_CCDCFG_WENLOG_AND | CCDC_CCDCFG_TRGSEL_WEN |
628 CCDC_CCDCFG_EXTRG_DISABLE | CCDC_LATCH_ON_VSYNC_DISABLE, CCDCFG);
629
630 /*
631 * Set VDHD direction to input, input type to raw input
632 * normal data polarity, do not use external WEN
633 */
634 val = (CCDC_VDHDOUT_INPUT | CCDC_RAW_IP_MODE | CCDC_DATAPOL_NORMAL |
635 CCDC_EXWEN_DISABLE);
636
637 /*
638 * Configure the vertical sync polarity (MODESET.VDPOL), horizontal
639 * sync polarity (MODESET.HDPOL), field id polarity (MODESET.FLDPOL),
640 * frame format(progressive or interlace), & pixel format (Input mode)
641 */
642 val |= (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
643 ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
644 ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
645 ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
646 ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT));
647
648 /* set pack for alaw compression */
649 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
650 config_params->alaw.enable)
651 val |= CCDC_DATA_PACK_ENABLE;
652
653 /* Configure for LPF */
654 if (config_params->lpf_enable)
655 val |= (config_params->lpf_enable & CCDC_LPF_MASK) <<
656 CCDC_LPF_SHIFT;
657
658 /* Configure the data shift */
659 val |= (config_params->datasft & CCDC_DATASFT_MASK) <<
660 CCDC_DATASFT_SHIFT;
661 regw(val , MODESET);
662 dev_dbg(dev, "\nWriting 0x%x to MODESET...\n", val);
663
664 /* Configure the Median Filter threshold */
665 regw((config_params->med_filt_thres) & CCDC_MED_FILT_THRESH, MEDFILT);
666
667 /* Configure GAMMAWD register. defaur 11-2, and Mosaic cfa pattern */
668 val = CCDC_GAMMA_BITS_11_2 << CCDC_GAMMAWD_INPUT_SHIFT |
669 CCDC_CFA_MOSAIC;
670
671 /* Enable and configure aLaw register if needed */
672 if (config_params->alaw.enable) {
673 val |= (CCDC_ALAW_ENABLE |
674 ((config_params->alaw.gama_wd &
675 CCDC_ALAW_GAMA_WD_MASK) <<
676 CCDC_GAMMAWD_INPUT_SHIFT));
677 }
678
679 /* Configure Median filter1 & filter2 */
680 val |= ((config_params->mfilt1 << CCDC_MFILT1_SHIFT) |
681 (config_params->mfilt2 << CCDC_MFILT2_SHIFT));
682
683 regw(val, GAMMAWD);
684 dev_dbg(dev, "\nWriting 0x%x to GAMMAWD...\n", val);
685
686 /* configure video window */
687 ccdc_setwin(&params->win, params->frm_fmt, 1);
688
689 /* Optical Clamp Averaging */
690 ccdc_config_black_clamp(&config_params->blk_clamp);
691
692 /* Black level compensation */
693 ccdc_config_black_compense(&config_params->blk_comp);
694
695 /* Vertical Defect Correction if needed */
696 if (ccdc_config_vdfc(&config_params->vertical_dft) < 0)
697 return -EFAULT;
698
699 /* color space conversion */
700 ccdc_config_csc(&config_params->csc);
701
702 /* color pattern */
703 ccdc_config_color_patterns(&config_params->col_pat_field0,
704 &config_params->col_pat_field1);
705
706 /* Configure the Gain & offset control */
707 ccdc_config_gain_offset();
708
709 dev_dbg(dev, "\nWriting %x to COLPTN...\n", val);
710
711 /* Configure DATAOFST register */
712 val = (config_params->data_offset.horz_offset & CCDC_DATAOFST_MASK) <<
713 CCDC_DATAOFST_H_SHIFT;
714 val |= (config_params->data_offset.vert_offset & CCDC_DATAOFST_MASK) <<
715 CCDC_DATAOFST_V_SHIFT;
716 regw(val, DATAOFST);
717
718 /* configuring HSIZE register */
719 val = (params->horz_flip_enable & CCDC_HSIZE_FLIP_MASK) <<
720 CCDC_HSIZE_FLIP_SHIFT;
721
722 /* If pack 8 is enable then 1 pixel will take 1 byte */
723 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
724 config_params->alaw.enable) {
725 val |= (((params->win.width) + 31) >> 5) &
726 CCDC_HSIZE_VAL_MASK;
727
728 /* adjust to multiple of 32 */
729 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
730 (((params->win.width) + 31) >> 5) &
731 CCDC_HSIZE_VAL_MASK);
732 } else {
733 /* else one pixel will take 2 byte */
734 val |= (((params->win.width * 2) + 31) >> 5) &
735 CCDC_HSIZE_VAL_MASK;
736
737 dev_dbg(dev, "\nWriting 0x%x to HSIZE...\n",
738 (((params->win.width * 2) + 31) >> 5) &
739 CCDC_HSIZE_VAL_MASK);
740 }
741 regw(val, HSIZE);
742
743 /* Configure SDOFST register */
744 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
745 if (params->image_invert_enable) {
746 /* For interlace inverse mode */
747 regw(CCDC_SDOFST_INTERLACE_INVERSE, SDOFST);
748 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
749 CCDC_SDOFST_INTERLACE_INVERSE);
750 } else {
751 /* For interlace non inverse mode */
752 regw(CCDC_SDOFST_INTERLACE_NORMAL, SDOFST);
753 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
754 CCDC_SDOFST_INTERLACE_NORMAL);
755 }
756 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
757 if (params->image_invert_enable) {
758 /* For progessive inverse mode */
759 regw(CCDC_SDOFST_PROGRESSIVE_INVERSE, SDOFST);
760 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
761 CCDC_SDOFST_PROGRESSIVE_INVERSE);
762 } else {
763 /* For progessive non inverse mode */
764 regw(CCDC_SDOFST_PROGRESSIVE_NORMAL, SDOFST);
765 dev_dbg(dev, "\nWriting %x to SDOFST...\n",
766 CCDC_SDOFST_PROGRESSIVE_NORMAL);
767 }
768 }
769 dev_dbg(dev, "\nend of ccdc_config_raw...");
770 return 0;
771}
772
773static int ccdc_configure(void)
774{
775 if (ccdc_if_type == VPFE_RAW_BAYER)
776 return ccdc_config_raw();
777 else
778 ccdc_config_ycbcr();
779 return 0;
780}
781
782static int ccdc_set_buftype(enum ccdc_buftype buf_type)
783{
784 if (ccdc_if_type == VPFE_RAW_BAYER)
785 ccdc_hw_params_raw.buf_type = buf_type;
786 else
787 ccdc_hw_params_ycbcr.buf_type = buf_type;
788 return 0;
789}
790static enum ccdc_buftype ccdc_get_buftype(void)
791{
792 if (ccdc_if_type == VPFE_RAW_BAYER)
793 return ccdc_hw_params_raw.buf_type;
794 return ccdc_hw_params_ycbcr.buf_type;
795}
796
797static int ccdc_enum_pix(u32 *pix, int i)
798{
799 int ret = -EINVAL;
800 if (ccdc_if_type == VPFE_RAW_BAYER) {
801 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
802 *pix = ccdc_raw_bayer_pix_formats[i];
803 ret = 0;
804 }
805 } else {
806 if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
807 *pix = ccdc_raw_yuv_pix_formats[i];
808 ret = 0;
809 }
810 }
811 return ret;
812}
813
814static int ccdc_set_pixel_format(u32 pixfmt)
815{
816 struct ccdc_a_law *alaw =
817 &ccdc_hw_params_raw.config_params.alaw;
818
819 if (ccdc_if_type == VPFE_RAW_BAYER) {
820 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
821 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
822 alaw->enable = 1;
823 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
824 return -EINVAL;
825 } else {
826 if (pixfmt == V4L2_PIX_FMT_YUYV)
827 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
828 else if (pixfmt == V4L2_PIX_FMT_UYVY)
829 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
830 else
831 return -EINVAL;
832 }
833 return 0;
834}
835static u32 ccdc_get_pixel_format(void)
836{
837 struct ccdc_a_law *alaw =
838 &ccdc_hw_params_raw.config_params.alaw;
839 u32 pixfmt;
840
841 if (ccdc_if_type == VPFE_RAW_BAYER)
842 if (alaw->enable)
843 pixfmt = V4L2_PIX_FMT_SBGGR8;
844 else
845 pixfmt = V4L2_PIX_FMT_SBGGR16;
846 else {
847 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
848 pixfmt = V4L2_PIX_FMT_YUYV;
849 else
850 pixfmt = V4L2_PIX_FMT_UYVY;
851 }
852 return pixfmt;
853}
854static int ccdc_set_image_window(struct v4l2_rect *win)
855{
856 if (ccdc_if_type == VPFE_RAW_BAYER)
857 ccdc_hw_params_raw.win = *win;
858 else
859 ccdc_hw_params_ycbcr.win = *win;
860 return 0;
861}
862
863static void ccdc_get_image_window(struct v4l2_rect *win)
864{
865 if (ccdc_if_type == VPFE_RAW_BAYER)
866 *win = ccdc_hw_params_raw.win;
867 else
868 *win = ccdc_hw_params_ycbcr.win;
869}
870
871static unsigned int ccdc_get_line_length(void)
872{
873 struct ccdc_config_params_raw *config_params =
874 &ccdc_hw_params_raw.config_params;
875 unsigned int len;
876
877 if (ccdc_if_type == VPFE_RAW_BAYER) {
878 if ((config_params->alaw.enable) ||
879 (config_params->data_sz == CCDC_DATA_8BITS))
880 len = ccdc_hw_params_raw.win.width;
881 else
882 len = ccdc_hw_params_raw.win.width * 2;
883 } else
884 len = ccdc_hw_params_ycbcr.win.width * 2;
885 return ALIGN(len, 32);
886}
887
888static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
889{
890 if (ccdc_if_type == VPFE_RAW_BAYER)
891 ccdc_hw_params_raw.frm_fmt = frm_fmt;
892 else
893 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
894 return 0;
895}
896
897static enum ccdc_frmfmt ccdc_get_frame_format(void)
898{
899 if (ccdc_if_type == VPFE_RAW_BAYER)
900 return ccdc_hw_params_raw.frm_fmt;
901 else
902 return ccdc_hw_params_ycbcr.frm_fmt;
903}
904
905static int ccdc_getfid(void)
906{
907 return (regr(MODESET) >> 15) & 1;
908}
909
910/* misc operations */
911static inline void ccdc_setfbaddr(unsigned long addr)
912{
913 regw((addr >> 21) & 0x007f, STADRH);
914 regw((addr >> 5) & 0x0ffff, STADRL);
915}
916
917static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
918{
919 ccdc_if_type = params->if_type;
920
921 switch (params->if_type) {
922 case VPFE_BT656:
923 case VPFE_YCBCR_SYNC_16:
924 case VPFE_YCBCR_SYNC_8:
925 ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
926 ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
927 break;
928 default:
929 /* TODO add support for raw bayer here */
930 return -EINVAL;
931 }
932 return 0;
933}
934
935static struct ccdc_hw_device ccdc_hw_dev = {
936 .name = "DM355 CCDC",
937 .owner = THIS_MODULE,
938 .hw_ops = {
939 .open = ccdc_open,
940 .close = ccdc_close,
941 .set_ccdc_base = ccdc_set_ccdc_base,
942 .enable = ccdc_enable,
943 .enable_out_to_sdram = ccdc_enable_output_to_sdram,
944 .set_hw_if_params = ccdc_set_hw_if_params,
945 .set_params = ccdc_set_params,
946 .configure = ccdc_configure,
947 .set_buftype = ccdc_set_buftype,
948 .get_buftype = ccdc_get_buftype,
949 .enum_pix = ccdc_enum_pix,
950 .set_pixel_format = ccdc_set_pixel_format,
951 .get_pixel_format = ccdc_get_pixel_format,
952 .set_frame_format = ccdc_set_frame_format,
953 .get_frame_format = ccdc_get_frame_format,
954 .set_image_window = ccdc_set_image_window,
955 .get_image_window = ccdc_get_image_window,
956 .get_line_length = ccdc_get_line_length,
957 .setfbaddr = ccdc_setfbaddr,
958 .getfid = ccdc_getfid,
959 },
960};
961
962static int dm355_ccdc_init(void)
963{
964 printk(KERN_NOTICE "dm355_ccdc_init\n");
965 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
966 return -1;
967 printk(KERN_NOTICE "%s is registered with vpfe.\n",
968 ccdc_hw_dev.name);
969 return 0;
970}
971
972static void dm355_ccdc_exit(void)
973{
974 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
975}
976
977module_init(dm355_ccdc_init);
978module_exit(dm355_ccdc_exit);
diff --git a/drivers/media/video/davinci/dm355_ccdc_regs.h b/drivers/media/video/davinci/dm355_ccdc_regs.h
new file mode 100644
index 000000000000..d6d2ef0533b5
--- /dev/null
+++ b/drivers/media/video/davinci/dm355_ccdc_regs.h
@@ -0,0 +1,310 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM355_CCDC_REGS_H
19#define _DM355_CCDC_REGS_H
20
21/**************************************************************************\
22* Register OFFSET Definitions
23\**************************************************************************/
24#define SYNCEN 0x00
25#define MODESET 0x04
26#define HDWIDTH 0x08
27#define VDWIDTH 0x0c
28#define PPLN 0x10
29#define LPFR 0x14
30#define SPH 0x18
31#define NPH 0x1c
32#define SLV0 0x20
33#define SLV1 0x24
34#define NLV 0x28
35#define CULH 0x2c
36#define CULV 0x30
37#define HSIZE 0x34
38#define SDOFST 0x38
39#define STADRH 0x3c
40#define STADRL 0x40
41#define CLAMP 0x44
42#define DCSUB 0x48
43#define COLPTN 0x4c
44#define BLKCMP0 0x50
45#define BLKCMP1 0x54
46#define MEDFILT 0x58
47#define RYEGAIN 0x5c
48#define GRCYGAIN 0x60
49#define GBGGAIN 0x64
50#define BMGGAIN 0x68
51#define OFFSET 0x6c
52#define OUTCLIP 0x70
53#define VDINT0 0x74
54#define VDINT1 0x78
55#define RSV0 0x7c
56#define GAMMAWD 0x80
57#define REC656IF 0x84
58#define CCDCFG 0x88
59#define FMTCFG 0x8c
60#define FMTPLEN 0x90
61#define FMTSPH 0x94
62#define FMTLNH 0x98
63#define FMTSLV 0x9c
64#define FMTLNV 0xa0
65#define FMTRLEN 0xa4
66#define FMTHCNT 0xa8
67#define FMT_ADDR_PTR_B 0xac
68#define FMT_ADDR_PTR(i) (FMT_ADDR_PTR_B + (i * 4))
69#define FMTPGM_VF0 0xcc
70#define FMTPGM_VF1 0xd0
71#define FMTPGM_AP0 0xd4
72#define FMTPGM_AP1 0xd8
73#define FMTPGM_AP2 0xdc
74#define FMTPGM_AP3 0xe0
75#define FMTPGM_AP4 0xe4
76#define FMTPGM_AP5 0xe8
77#define FMTPGM_AP6 0xec
78#define FMTPGM_AP7 0xf0
79#define LSCCFG1 0xf4
80#define LSCCFG2 0xf8
81#define LSCH0 0xfc
82#define LSCV0 0x100
83#define LSCKH 0x104
84#define LSCKV 0x108
85#define LSCMEMCTL 0x10c
86#define LSCMEMD 0x110
87#define LSCMEMQ 0x114
88#define DFCCTL 0x118
89#define DFCVSAT 0x11c
90#define DFCMEMCTL 0x120
91#define DFCMEM0 0x124
92#define DFCMEM1 0x128
93#define DFCMEM2 0x12c
94#define DFCMEM3 0x130
95#define DFCMEM4 0x134
96#define CSCCTL 0x138
97#define CSCM0 0x13c
98#define CSCM1 0x140
99#define CSCM2 0x144
100#define CSCM3 0x148
101#define CSCM4 0x14c
102#define CSCM5 0x150
103#define CSCM6 0x154
104#define CSCM7 0x158
105#define DATAOFST 0x15c
106#define CCDC_REG_LAST DATAOFST
107/**************************************************************
108* Define for various register bit mask and shifts for CCDC
109*
110**************************************************************/
111#define CCDC_RAW_IP_MODE 0
112#define CCDC_VDHDOUT_INPUT 0
113#define CCDC_YCINSWP_RAW (0 << 4)
114#define CCDC_EXWEN_DISABLE 0
115#define CCDC_DATAPOL_NORMAL 0
116#define CCDC_CCDCFG_FIDMD_LATCH_VSYNC 0
117#define CCDC_CCDCFG_FIDMD_NO_LATCH_VSYNC (1 << 6)
118#define CCDC_CCDCFG_WENLOG_AND 0
119#define CCDC_CCDCFG_TRGSEL_WEN 0
120#define CCDC_CCDCFG_EXTRG_DISABLE 0
121#define CCDC_CFA_MOSAIC 0
122#define CCDC_Y8POS_SHIFT 11
123
124#define CCDC_VDC_DFCVSAT_MASK 0x3fff
125#define CCDC_DATAOFST_MASK 0x0ff
126#define CCDC_DATAOFST_H_SHIFT 0
127#define CCDC_DATAOFST_V_SHIFT 8
128#define CCDC_GAMMAWD_CFA_MASK 1
129#define CCDC_GAMMAWD_CFA_SHIFT 5
130#define CCDC_GAMMAWD_INPUT_SHIFT 2
131#define CCDC_FID_POL_MASK 1
132#define CCDC_FID_POL_SHIFT 4
133#define CCDC_HD_POL_MASK 1
134#define CCDC_HD_POL_SHIFT 3
135#define CCDC_VD_POL_MASK 1
136#define CCDC_VD_POL_SHIFT 2
137#define CCDC_VD_POL_NEGATIVE (1 << 2)
138#define CCDC_FRM_FMT_MASK 1
139#define CCDC_FRM_FMT_SHIFT 7
140#define CCDC_DATA_SZ_MASK 7
141#define CCDC_DATA_SZ_SHIFT 8
142#define CCDC_VDHDOUT_MASK 1
143#define CCDC_VDHDOUT_SHIFT 0
144#define CCDC_EXWEN_MASK 1
145#define CCDC_EXWEN_SHIFT 5
146#define CCDC_INPUT_MODE_MASK 3
147#define CCDC_INPUT_MODE_SHIFT 12
148#define CCDC_PIX_FMT_MASK 3
149#define CCDC_PIX_FMT_SHIFT 12
150#define CCDC_DATAPOL_MASK 1
151#define CCDC_DATAPOL_SHIFT 6
152#define CCDC_WEN_ENABLE (1 << 1)
153#define CCDC_VDHDEN_ENABLE (1 << 16)
154#define CCDC_LPF_ENABLE (1 << 14)
155#define CCDC_ALAW_ENABLE 1
156#define CCDC_ALAW_GAMA_WD_MASK 7
157#define CCDC_REC656IF_BT656_EN 3
158
159#define CCDC_FMTCFG_FMTMODE_MASK 3
160#define CCDC_FMTCFG_FMTMODE_SHIFT 1
161#define CCDC_FMTCFG_LNUM_MASK 3
162#define CCDC_FMTCFG_LNUM_SHIFT 4
163#define CCDC_FMTCFG_ADDRINC_MASK 7
164#define CCDC_FMTCFG_ADDRINC_SHIFT 8
165
166#define CCDC_CCDCFG_FIDMD_SHIFT 6
167#define CCDC_CCDCFG_WENLOG_SHIFT 8
168#define CCDC_CCDCFG_TRGSEL_SHIFT 9
169#define CCDC_CCDCFG_EXTRG_SHIFT 10
170#define CCDC_CCDCFG_MSBINVI_SHIFT 13
171
172#define CCDC_HSIZE_FLIP_SHIFT 12
173#define CCDC_HSIZE_FLIP_MASK 1
174#define CCDC_HSIZE_VAL_MASK 0xFFF
175#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
176#define CCDC_SDOFST_INTERLACE_INVERSE 0x4B6D
177#define CCDC_SDOFST_INTERLACE_NORMAL 0x0B6D
178#define CCDC_SDOFST_PROGRESSIVE_INVERSE 0x4000
179#define CCDC_SDOFST_PROGRESSIVE_NORMAL 0
180#define CCDC_START_PX_HOR_MASK 0x7FFF
181#define CCDC_NUM_PX_HOR_MASK 0x7FFF
182#define CCDC_START_VER_ONE_MASK 0x7FFF
183#define CCDC_START_VER_TWO_MASK 0x7FFF
184#define CCDC_NUM_LINES_VER 0x7FFF
185
186#define CCDC_BLK_CLAMP_ENABLE (1 << 15)
187#define CCDC_BLK_SGAIN_MASK 0x1F
188#define CCDC_BLK_ST_PXL_MASK 0x1FFF
189#define CCDC_BLK_SAMPLE_LN_MASK 3
190#define CCDC_BLK_SAMPLE_LN_SHIFT 13
191
192#define CCDC_NUM_LINE_CALC_MASK 3
193#define CCDC_NUM_LINE_CALC_SHIFT 14
194
195#define CCDC_BLK_DC_SUB_MASK 0x3FFF
196#define CCDC_BLK_COMP_MASK 0xFF
197#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
198#define CCDC_BLK_COMP_GR_COMP_SHIFT 0
199#define CCDC_BLK_COMP_R_COMP_SHIFT 8
200#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
201#define CCDC_LATCH_ON_VSYNC_ENABLE (0 << 15)
202#define CCDC_FPC_ENABLE (1 << 15)
203#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
204#define CCDC_DATA_PACK_ENABLE (1 << 11)
205#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
206#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
207#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
208#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
209#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
210#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
211#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
212#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
213#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
214#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
215#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
216
217#define CCDC_CSC_COEF_INTEG_MASK 7
218#define CCDC_CSC_COEF_DECIMAL_MASK 0x1f
219#define CCDC_CSC_COEF_INTEG_SHIFT 5
220#define CCDC_CSCM_MSB_SHIFT 8
221#define CCDC_CSC_ENABLE 1
222#define CCDC_CSC_DEC_MAX 32
223
224#define CCDC_MFILT1_SHIFT 10
225#define CCDC_MFILT2_SHIFT 8
226#define CCDC_MED_FILT_THRESH 0x3FFF
227#define CCDC_LPF_MASK 1
228#define CCDC_LPF_SHIFT 14
229#define CCDC_OFFSET_MASK 0x3FF
230#define CCDC_DATASFT_MASK 7
231#define CCDC_DATASFT_SHIFT 8
232
233#define CCDC_DF_ENABLE 1
234
235#define CCDC_FMTPLEN_P0_MASK 0xF
236#define CCDC_FMTPLEN_P1_MASK 0xF
237#define CCDC_FMTPLEN_P2_MASK 7
238#define CCDC_FMTPLEN_P3_MASK 7
239#define CCDC_FMTPLEN_P0_SHIFT 0
240#define CCDC_FMTPLEN_P1_SHIFT 4
241#define CCDC_FMTPLEN_P2_SHIFT 8
242#define CCDC_FMTPLEN_P3_SHIFT 12
243
244#define CCDC_FMTSPH_MASK 0x1FFF
245#define CCDC_FMTLNH_MASK 0x1FFF
246#define CCDC_FMTSLV_MASK 0x1FFF
247#define CCDC_FMTLNV_MASK 0x7FFF
248#define CCDC_FMTRLEN_MASK 0x1FFF
249#define CCDC_FMTHCNT_MASK 0x1FFF
250
251#define CCDC_ADP_INIT_MASK 0x1FFF
252#define CCDC_ADP_LINE_SHIFT 13
253#define CCDC_ADP_LINE_MASK 3
254#define CCDC_FMTPGN_APTR_MASK 7
255
256#define CCDC_DFCCTL_GDFCEN_MASK 1
257#define CCDC_DFCCTL_VDFCEN_MASK 1
258#define CCDC_DFCCTL_VDFC_DISABLE (0 << 4)
259#define CCDC_DFCCTL_VDFCEN_SHIFT 4
260#define CCDC_DFCCTL_VDFCSL_MASK 3
261#define CCDC_DFCCTL_VDFCSL_SHIFT 5
262#define CCDC_DFCCTL_VDFCUDA_MASK 1
263#define CCDC_DFCCTL_VDFCUDA_SHIFT 7
264#define CCDC_DFCCTL_VDFLSFT_MASK 3
265#define CCDC_DFCCTL_VDFLSFT_SHIFT 8
266#define CCDC_DFCMEMCTL_DFCMARST_MASK 1
267#define CCDC_DFCMEMCTL_DFCMARST_SHIFT 2
268#define CCDC_DFCMEMCTL_DFCMWR_MASK 1
269#define CCDC_DFCMEMCTL_DFCMWR_SHIFT 0
270#define CCDC_DFCMEMCTL_INC_ADDR (0 << 2)
271
272#define CCDC_LSCCFG_GFTSF_MASK 7
273#define CCDC_LSCCFG_GFTSF_SHIFT 1
274#define CCDC_LSCCFG_GFTINV_MASK 0xf
275#define CCDC_LSCCFG_GFTINV_SHIFT 4
276#define CCDC_LSC_GFTABLE_SEL_MASK 3
277#define CCDC_LSC_GFTABLE_EPEL_SHIFT 8
278#define CCDC_LSC_GFTABLE_OPEL_SHIFT 10
279#define CCDC_LSC_GFTABLE_EPOL_SHIFT 12
280#define CCDC_LSC_GFTABLE_OPOL_SHIFT 14
281#define CCDC_LSC_GFMODE_MASK 3
282#define CCDC_LSC_GFMODE_SHIFT 4
283#define CCDC_LSC_DISABLE 0
284#define CCDC_LSC_ENABLE 1
285#define CCDC_LSC_TABLE1_SLC 0
286#define CCDC_LSC_TABLE2_SLC 1
287#define CCDC_LSC_TABLE3_SLC 2
288#define CCDC_LSC_MEMADDR_RESET (1 << 2)
289#define CCDC_LSC_MEMADDR_INCR (0 << 2)
290#define CCDC_LSC_FRAC_MASK_T1 0xFF
291#define CCDC_LSC_INT_MASK 3
292#define CCDC_LSC_FRAC_MASK 0x3FFF
293#define CCDC_LSC_CENTRE_MASK 0x3FFF
294#define CCDC_LSC_COEF_MASK 0xff
295#define CCDC_LSC_COEFL_SHIFT 0
296#define CCDC_LSC_COEFU_SHIFT 8
297#define CCDC_GAIN_MASK 0x7FF
298#define CCDC_SYNCEN_VDHDEN_MASK (1 << 0)
299#define CCDC_SYNCEN_WEN_MASK (1 << 1)
300#define CCDC_SYNCEN_WEN_SHIFT 1
301
302/* Power on Defaults in hardware */
303#define MODESET_DEFAULT 0x200
304#define CULH_DEFAULT 0xFFFF
305#define CULV_DEFAULT 0xFF
306#define GAIN_DEFAULT 256
307#define OUTCLIP_DEFAULT 0x3FFF
308#define LSCCFG2_DEFAULT 0xE
309
310#endif
diff --git a/drivers/media/video/davinci/dm644x_ccdc.c b/drivers/media/video/davinci/dm644x_ccdc.c
new file mode 100644
index 000000000000..2f19a919f477
--- /dev/null
+++ b/drivers/media/video/davinci/dm644x_ccdc.c
@@ -0,0 +1,878 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * CCDC hardware module for DM6446
19 * ------------------------------
20 *
21 * This module is for configuring CCD controller of DM6446 VPFE to capture
22 * Raw yuv or Bayer RGB data from a decoder. CCDC has several modules
23 * such as Defect Pixel Correction, Color Space Conversion etc to
24 * pre-process the Raw Bayer RGB data, before writing it to SDRAM. This
25 * module also allows application to configure individual
26 * module parameters through VPFE_CMD_S_CCDC_RAW_PARAMS IOCTL.
27 * To do so, application includes dm644x_ccdc.h and vpfe_capture.h header
28 * files. The setparams() API is called by vpfe_capture driver
29 * to configure module parameters. This file is named DM644x so that other
30 * variants such DM6443 may be supported using the same module.
31 *
32 * TODO: Test Raw bayer parameter settings and bayer capture
33 * Split module parameter structure to module specific ioctl structs
34 * investigate if enum used for user space type definition
35 * to be replaced by #defines or integer
36 */
37#include <linux/platform_device.h>
38#include <linux/uaccess.h>
39#include <linux/videodev2.h>
40#include <media/davinci/dm644x_ccdc.h>
41#include <media/davinci/vpss.h>
42#include "dm644x_ccdc_regs.h"
43#include "ccdc_hw_device.h"
44
45MODULE_LICENSE("GPL");
46MODULE_DESCRIPTION("CCDC Driver for DM6446");
47MODULE_AUTHOR("Texas Instruments");
48
49static struct device *dev;
50
51/* Object for CCDC raw mode */
52static struct ccdc_params_raw ccdc_hw_params_raw = {
53 .pix_fmt = CCDC_PIXFMT_RAW,
54 .frm_fmt = CCDC_FRMFMT_PROGRESSIVE,
55 .win = CCDC_WIN_VGA,
56 .fid_pol = VPFE_PINPOL_POSITIVE,
57 .vd_pol = VPFE_PINPOL_POSITIVE,
58 .hd_pol = VPFE_PINPOL_POSITIVE,
59 .config_params = {
60 .data_sz = CCDC_DATA_10BITS,
61 },
62};
63
64/* Object for CCDC ycbcr mode */
65static struct ccdc_params_ycbcr ccdc_hw_params_ycbcr = {
66 .pix_fmt = CCDC_PIXFMT_YCBCR_8BIT,
67 .frm_fmt = CCDC_FRMFMT_INTERLACED,
68 .win = CCDC_WIN_PAL,
69 .fid_pol = VPFE_PINPOL_POSITIVE,
70 .vd_pol = VPFE_PINPOL_POSITIVE,
71 .hd_pol = VPFE_PINPOL_POSITIVE,
72 .bt656_enable = 1,
73 .pix_order = CCDC_PIXORDER_CBYCRY,
74 .buf_type = CCDC_BUFTYPE_FLD_INTERLEAVED
75};
76
77#define CCDC_MAX_RAW_YUV_FORMATS 2
78
79/* Raw Bayer formats */
80static u32 ccdc_raw_bayer_pix_formats[] =
81 {V4L2_PIX_FMT_SBGGR8, V4L2_PIX_FMT_SBGGR16};
82
83/* Raw YUV formats */
84static u32 ccdc_raw_yuv_pix_formats[] =
85 {V4L2_PIX_FMT_UYVY, V4L2_PIX_FMT_YUYV};
86
87static void *__iomem ccdc_base_addr;
88static int ccdc_addr_size;
89static enum vpfe_hw_if_type ccdc_if_type;
90
91/* register access routines */
92static inline u32 regr(u32 offset)
93{
94 return __raw_readl(ccdc_base_addr + offset);
95}
96
97static inline void regw(u32 val, u32 offset)
98{
99 __raw_writel(val, ccdc_base_addr + offset);
100}
101
102static void ccdc_set_ccdc_base(void *addr, int size)
103{
104 ccdc_base_addr = addr;
105 ccdc_addr_size = size;
106}
107
108static void ccdc_enable(int flag)
109{
110 regw(flag, CCDC_PCR);
111}
112
113static void ccdc_enable_vport(int flag)
114{
115 if (flag)
116 /* enable video port */
117 regw(CCDC_ENABLE_VIDEO_PORT, CCDC_FMTCFG);
118 else
119 regw(CCDC_DISABLE_VIDEO_PORT, CCDC_FMTCFG);
120}
121
122/*
123 * ccdc_setwin()
124 * This function will configure the window size
125 * to be capture in CCDC reg
126 */
127void ccdc_setwin(struct v4l2_rect *image_win,
128 enum ccdc_frmfmt frm_fmt,
129 int ppc)
130{
131 int horz_start, horz_nr_pixels;
132 int vert_start, vert_nr_lines;
133 int val = 0, mid_img = 0;
134
135 dev_dbg(dev, "\nStarting ccdc_setwin...");
136 /*
137 * ppc - per pixel count. indicates how many pixels per cell
138 * output to SDRAM. example, for ycbcr, it is one y and one c, so 2.
139 * raw capture this is 1
140 */
141 horz_start = image_win->left << (ppc - 1);
142 horz_nr_pixels = (image_win->width << (ppc - 1)) - 1;
143 regw((horz_start << CCDC_HORZ_INFO_SPH_SHIFT) | horz_nr_pixels,
144 CCDC_HORZ_INFO);
145
146 vert_start = image_win->top;
147
148 if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
149 vert_nr_lines = (image_win->height >> 1) - 1;
150 vert_start >>= 1;
151 /* Since first line doesn't have any data */
152 vert_start += 1;
153 /* configure VDINT0 */
154 val = (vert_start << CCDC_VDINT_VDINT0_SHIFT);
155 regw(val, CCDC_VDINT);
156
157 } else {
158 /* Since first line doesn't have any data */
159 vert_start += 1;
160 vert_nr_lines = image_win->height - 1;
161 /*
162 * configure VDINT0 and VDINT1. VDINT1 will be at half
163 * of image height
164 */
165 mid_img = vert_start + (image_win->height / 2);
166 val = (vert_start << CCDC_VDINT_VDINT0_SHIFT) |
167 (mid_img & CCDC_VDINT_VDINT1_MASK);
168 regw(val, CCDC_VDINT);
169
170 }
171 regw((vert_start << CCDC_VERT_START_SLV0_SHIFT) | vert_start,
172 CCDC_VERT_START);
173 regw(vert_nr_lines, CCDC_VERT_LINES);
174 dev_dbg(dev, "\nEnd of ccdc_setwin...");
175}
176
177static void ccdc_readregs(void)
178{
179 unsigned int val = 0;
180
181 val = regr(CCDC_ALAW);
182 dev_notice(dev, "\nReading 0x%x to ALAW...\n", val);
183 val = regr(CCDC_CLAMP);
184 dev_notice(dev, "\nReading 0x%x to CLAMP...\n", val);
185 val = regr(CCDC_DCSUB);
186 dev_notice(dev, "\nReading 0x%x to DCSUB...\n", val);
187 val = regr(CCDC_BLKCMP);
188 dev_notice(dev, "\nReading 0x%x to BLKCMP...\n", val);
189 val = regr(CCDC_FPC_ADDR);
190 dev_notice(dev, "\nReading 0x%x to FPC_ADDR...\n", val);
191 val = regr(CCDC_FPC);
192 dev_notice(dev, "\nReading 0x%x to FPC...\n", val);
193 val = regr(CCDC_FMTCFG);
194 dev_notice(dev, "\nReading 0x%x to FMTCFG...\n", val);
195 val = regr(CCDC_COLPTN);
196 dev_notice(dev, "\nReading 0x%x to COLPTN...\n", val);
197 val = regr(CCDC_FMT_HORZ);
198 dev_notice(dev, "\nReading 0x%x to FMT_HORZ...\n", val);
199 val = regr(CCDC_FMT_VERT);
200 dev_notice(dev, "\nReading 0x%x to FMT_VERT...\n", val);
201 val = regr(CCDC_HSIZE_OFF);
202 dev_notice(dev, "\nReading 0x%x to HSIZE_OFF...\n", val);
203 val = regr(CCDC_SDOFST);
204 dev_notice(dev, "\nReading 0x%x to SDOFST...\n", val);
205 val = regr(CCDC_VP_OUT);
206 dev_notice(dev, "\nReading 0x%x to VP_OUT...\n", val);
207 val = regr(CCDC_SYN_MODE);
208 dev_notice(dev, "\nReading 0x%x to SYN_MODE...\n", val);
209 val = regr(CCDC_HORZ_INFO);
210 dev_notice(dev, "\nReading 0x%x to HORZ_INFO...\n", val);
211 val = regr(CCDC_VERT_START);
212 dev_notice(dev, "\nReading 0x%x to VERT_START...\n", val);
213 val = regr(CCDC_VERT_LINES);
214 dev_notice(dev, "\nReading 0x%x to VERT_LINES...\n", val);
215}
216
217static int validate_ccdc_param(struct ccdc_config_params_raw *ccdcparam)
218{
219 if (ccdcparam->alaw.enable) {
220 if ((ccdcparam->alaw.gama_wd > CCDC_GAMMA_BITS_09_0) ||
221 (ccdcparam->alaw.gama_wd < CCDC_GAMMA_BITS_15_6) ||
222 (ccdcparam->alaw.gama_wd < ccdcparam->data_sz)) {
223 dev_dbg(dev, "\nInvalid data line select");
224 return -1;
225 }
226 }
227 return 0;
228}
229
230static int ccdc_update_raw_params(struct ccdc_config_params_raw *raw_params)
231{
232 struct ccdc_config_params_raw *config_params =
233 &ccdc_hw_params_raw.config_params;
234 unsigned int *fpc_virtaddr = NULL;
235 unsigned int *fpc_physaddr = NULL;
236
237 memcpy(config_params, raw_params, sizeof(*raw_params));
238 /*
239 * allocate memory for fault pixel table and copy the user
240 * values to the table
241 */
242 if (!config_params->fault_pxl.enable)
243 return 0;
244
245 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
246 fpc_virtaddr = (unsigned int *)phys_to_virt(
247 (unsigned long)fpc_physaddr);
248 /*
249 * Allocate memory for FPC table if current
250 * FPC table buffer is not big enough to
251 * accomodate FPC Number requested
252 */
253 if (raw_params->fault_pxl.fp_num != config_params->fault_pxl.fp_num) {
254 if (fpc_physaddr != NULL) {
255 free_pages((unsigned long)fpc_physaddr,
256 get_order
257 (config_params->fault_pxl.fp_num *
258 FP_NUM_BYTES));
259 }
260
261 /* Allocate memory for FPC table */
262 fpc_virtaddr =
263 (unsigned int *)__get_free_pages(GFP_KERNEL | GFP_DMA,
264 get_order(raw_params->
265 fault_pxl.fp_num *
266 FP_NUM_BYTES));
267
268 if (fpc_virtaddr == NULL) {
269 dev_dbg(dev,
270 "\nUnable to allocate memory for FPC");
271 return -EFAULT;
272 }
273 fpc_physaddr =
274 (unsigned int *)virt_to_phys((void *)fpc_virtaddr);
275 }
276
277 /* Copy number of fault pixels and FPC table */
278 config_params->fault_pxl.fp_num = raw_params->fault_pxl.fp_num;
279 if (copy_from_user(fpc_virtaddr,
280 (void __user *)raw_params->fault_pxl.fpc_table_addr,
281 config_params->fault_pxl.fp_num * FP_NUM_BYTES)) {
282 dev_dbg(dev, "\n copy_from_user failed");
283 return -EFAULT;
284 }
285 config_params->fault_pxl.fpc_table_addr = (unsigned int)fpc_physaddr;
286 return 0;
287}
288
289static int ccdc_close(struct device *dev)
290{
291 struct ccdc_config_params_raw *config_params =
292 &ccdc_hw_params_raw.config_params;
293 unsigned int *fpc_physaddr = NULL, *fpc_virtaddr = NULL;
294
295 fpc_physaddr = (unsigned int *)config_params->fault_pxl.fpc_table_addr;
296
297 if (fpc_physaddr != NULL) {
298 fpc_virtaddr = (unsigned int *)
299 phys_to_virt((unsigned long)fpc_physaddr);
300 free_pages((unsigned long)fpc_virtaddr,
301 get_order(config_params->fault_pxl.fp_num *
302 FP_NUM_BYTES));
303 }
304 return 0;
305}
306
307/*
308 * ccdc_restore_defaults()
309 * This function will write defaults to all CCDC registers
310 */
311static void ccdc_restore_defaults(void)
312{
313 int i;
314
315 /* disable CCDC */
316 ccdc_enable(0);
317 /* set all registers to default value */
318 for (i = 4; i <= 0x94; i += 4)
319 regw(0, i);
320 regw(CCDC_NO_CULLING, CCDC_CULLING);
321 regw(CCDC_GAMMA_BITS_11_2, CCDC_ALAW);
322}
323
324static int ccdc_open(struct device *device)
325{
326 dev = device;
327 ccdc_restore_defaults();
328 if (ccdc_if_type == VPFE_RAW_BAYER)
329 ccdc_enable_vport(1);
330 return 0;
331}
332
333static void ccdc_sbl_reset(void)
334{
335 vpss_clear_wbl_overflow(VPSS_PCR_CCDC_WBL_O);
336}
337
338/* Parameter operations */
339static int ccdc_set_params(void __user *params)
340{
341 struct ccdc_config_params_raw ccdc_raw_params;
342 int x;
343
344 if (ccdc_if_type != VPFE_RAW_BAYER)
345 return -EINVAL;
346
347 x = copy_from_user(&ccdc_raw_params, params, sizeof(ccdc_raw_params));
348 if (x) {
349 dev_dbg(dev, "ccdc_set_params: error in copying"
350 "ccdc params, %d\n", x);
351 return -EFAULT;
352 }
353
354 if (!validate_ccdc_param(&ccdc_raw_params)) {
355 if (!ccdc_update_raw_params(&ccdc_raw_params))
356 return 0;
357 }
358 return -EINVAL;
359}
360
361/*
362 * ccdc_config_ycbcr()
363 * This function will configure CCDC for YCbCr video capture
364 */
365void ccdc_config_ycbcr(void)
366{
367 struct ccdc_params_ycbcr *params = &ccdc_hw_params_ycbcr;
368 u32 syn_mode;
369
370 dev_dbg(dev, "\nStarting ccdc_config_ycbcr...");
371 /*
372 * first restore the CCDC registers to default values
373 * This is important since we assume default values to be set in
374 * a lot of registers that we didn't touch
375 */
376 ccdc_restore_defaults();
377
378 /*
379 * configure pixel format, frame format, configure video frame
380 * format, enable output to SDRAM, enable internal timing generator
381 * and 8bit pack mode
382 */
383 syn_mode = (((params->pix_fmt & CCDC_SYN_MODE_INPMOD_MASK) <<
384 CCDC_SYN_MODE_INPMOD_SHIFT) |
385 ((params->frm_fmt & CCDC_SYN_FLDMODE_MASK) <<
386 CCDC_SYN_FLDMODE_SHIFT) | CCDC_VDHDEN_ENABLE |
387 CCDC_WEN_ENABLE | CCDC_DATA_PACK_ENABLE);
388
389 /* setup BT.656 sync mode */
390 if (params->bt656_enable) {
391 regw(CCDC_REC656IF_BT656_EN, CCDC_REC656IF);
392
393 /*
394 * configure the FID, VD, HD pin polarity,
395 * fld,hd pol positive, vd negative, 8-bit data
396 */
397 syn_mode |= CCDC_SYN_MODE_VD_POL_NEGATIVE | CCDC_SYN_MODE_8BITS;
398 } else {
399 /* y/c external sync mode */
400 syn_mode |= (((params->fid_pol & CCDC_FID_POL_MASK) <<
401 CCDC_FID_POL_SHIFT) |
402 ((params->hd_pol & CCDC_HD_POL_MASK) <<
403 CCDC_HD_POL_SHIFT) |
404 ((params->vd_pol & CCDC_VD_POL_MASK) <<
405 CCDC_VD_POL_SHIFT));
406 }
407 regw(syn_mode, CCDC_SYN_MODE);
408
409 /* configure video window */
410 ccdc_setwin(&params->win, params->frm_fmt, 2);
411
412 /*
413 * configure the order of y cb cr in SDRAM, and disable latch
414 * internal register on vsync
415 */
416 regw((params->pix_order << CCDC_CCDCFG_Y8POS_SHIFT) |
417 CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
418
419 /*
420 * configure the horizontal line offset. This should be a
421 * on 32 byte bondary. So clear LSB 5 bits
422 */
423 regw(((params->win.width * 2 + 31) & ~0x1f), CCDC_HSIZE_OFF);
424
425 /* configure the memory line offset */
426 if (params->buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
427 /* two fields are interleaved in memory */
428 regw(CCDC_SDOFST_FIELD_INTERLEAVED, CCDC_SDOFST);
429
430 ccdc_sbl_reset();
431 dev_dbg(dev, "\nEnd of ccdc_config_ycbcr...\n");
432 ccdc_readregs();
433}
434
435static void ccdc_config_black_clamp(struct ccdc_black_clamp *bclamp)
436{
437 u32 val;
438
439 if (!bclamp->enable) {
440 /* configure DCSub */
441 val = (bclamp->dc_sub) & CCDC_BLK_DC_SUB_MASK;
442 regw(val, CCDC_DCSUB);
443 dev_dbg(dev, "\nWriting 0x%x to DCSUB...\n", val);
444 regw(CCDC_CLAMP_DEFAULT_VAL, CCDC_CLAMP);
445 dev_dbg(dev, "\nWriting 0x0000 to CLAMP...\n");
446 return;
447 }
448 /*
449 * Configure gain, Start pixel, No of line to be avg,
450 * No of pixel/line to be avg, & Enable the Black clamping
451 */
452 val = ((bclamp->sgain & CCDC_BLK_SGAIN_MASK) |
453 ((bclamp->start_pixel & CCDC_BLK_ST_PXL_MASK) <<
454 CCDC_BLK_ST_PXL_SHIFT) |
455 ((bclamp->sample_ln & CCDC_BLK_SAMPLE_LINE_MASK) <<
456 CCDC_BLK_SAMPLE_LINE_SHIFT) |
457 ((bclamp->sample_pixel & CCDC_BLK_SAMPLE_LN_MASK) <<
458 CCDC_BLK_SAMPLE_LN_SHIFT) | CCDC_BLK_CLAMP_ENABLE);
459 regw(val, CCDC_CLAMP);
460 dev_dbg(dev, "\nWriting 0x%x to CLAMP...\n", val);
461 /* If Black clamping is enable then make dcsub 0 */
462 regw(CCDC_DCSUB_DEFAULT_VAL, CCDC_DCSUB);
463 dev_dbg(dev, "\nWriting 0x00000000 to DCSUB...\n");
464}
465
466static void ccdc_config_black_compense(struct ccdc_black_compensation *bcomp)
467{
468 u32 val;
469
470 val = ((bcomp->b & CCDC_BLK_COMP_MASK) |
471 ((bcomp->gb & CCDC_BLK_COMP_MASK) <<
472 CCDC_BLK_COMP_GB_COMP_SHIFT) |
473 ((bcomp->gr & CCDC_BLK_COMP_MASK) <<
474 CCDC_BLK_COMP_GR_COMP_SHIFT) |
475 ((bcomp->r & CCDC_BLK_COMP_MASK) <<
476 CCDC_BLK_COMP_R_COMP_SHIFT));
477 regw(val, CCDC_BLKCMP);
478}
479
480static void ccdc_config_fpc(struct ccdc_fault_pixel *fpc)
481{
482 u32 val;
483
484 /* Initially disable FPC */
485 val = CCDC_FPC_DISABLE;
486 regw(val, CCDC_FPC);
487
488 if (!fpc->enable)
489 return;
490
491 /* Configure Fault pixel if needed */
492 regw(fpc->fpc_table_addr, CCDC_FPC_ADDR);
493 dev_dbg(dev, "\nWriting 0x%x to FPC_ADDR...\n",
494 (fpc->fpc_table_addr));
495 /* Write the FPC params with FPC disable */
496 val = fpc->fp_num & CCDC_FPC_FPC_NUM_MASK;
497 regw(val, CCDC_FPC);
498
499 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
500 /* read the FPC register */
501 val = regr(CCDC_FPC) | CCDC_FPC_ENABLE;
502 regw(val, CCDC_FPC);
503 dev_dbg(dev, "\nWriting 0x%x to FPC...\n", val);
504}
505
506/*
507 * ccdc_config_raw()
508 * This function will configure CCDC for Raw capture mode
509 */
510void ccdc_config_raw(void)
511{
512 struct ccdc_params_raw *params = &ccdc_hw_params_raw;
513 struct ccdc_config_params_raw *config_params =
514 &ccdc_hw_params_raw.config_params;
515 unsigned int syn_mode = 0;
516 unsigned int val;
517
518 dev_dbg(dev, "\nStarting ccdc_config_raw...");
519
520 /* Reset CCDC */
521 ccdc_restore_defaults();
522
523 /* Disable latching function registers on VSYNC */
524 regw(CCDC_LATCH_ON_VSYNC_DISABLE, CCDC_CCDCFG);
525
526 /*
527 * Configure the vertical sync polarity(SYN_MODE.VDPOL),
528 * horizontal sync polarity (SYN_MODE.HDPOL), frame id polarity
529 * (SYN_MODE.FLDPOL), frame format(progressive or interlace),
530 * data size(SYNMODE.DATSIZ), &pixel format (Input mode), output
531 * SDRAM, enable internal timing generator
532 */
533 syn_mode =
534 (((params->vd_pol & CCDC_VD_POL_MASK) << CCDC_VD_POL_SHIFT) |
535 ((params->hd_pol & CCDC_HD_POL_MASK) << CCDC_HD_POL_SHIFT) |
536 ((params->fid_pol & CCDC_FID_POL_MASK) << CCDC_FID_POL_SHIFT) |
537 ((params->frm_fmt & CCDC_FRM_FMT_MASK) << CCDC_FRM_FMT_SHIFT) |
538 ((config_params->data_sz & CCDC_DATA_SZ_MASK) <<
539 CCDC_DATA_SZ_SHIFT) |
540 ((params->pix_fmt & CCDC_PIX_FMT_MASK) << CCDC_PIX_FMT_SHIFT) |
541 CCDC_WEN_ENABLE | CCDC_VDHDEN_ENABLE);
542
543 /* Enable and configure aLaw register if needed */
544 if (config_params->alaw.enable) {
545 val = ((config_params->alaw.gama_wd &
546 CCDC_ALAW_GAMA_WD_MASK) | CCDC_ALAW_ENABLE);
547 regw(val, CCDC_ALAW);
548 dev_dbg(dev, "\nWriting 0x%x to ALAW...\n", val);
549 }
550
551 /* Configure video window */
552 ccdc_setwin(&params->win, params->frm_fmt, CCDC_PPC_RAW);
553
554 /* Configure Black Clamp */
555 ccdc_config_black_clamp(&config_params->blk_clamp);
556
557 /* Configure Black level compensation */
558 ccdc_config_black_compense(&config_params->blk_comp);
559
560 /* Configure Fault Pixel Correction */
561 ccdc_config_fpc(&config_params->fault_pxl);
562
563 /* If data size is 8 bit then pack the data */
564 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
565 config_params->alaw.enable)
566 syn_mode |= CCDC_DATA_PACK_ENABLE;
567
568#ifdef CONFIG_DM644X_VIDEO_PORT_ENABLE
569 /* enable video port */
570 val = CCDC_ENABLE_VIDEO_PORT;
571#else
572 /* disable video port */
573 val = CCDC_DISABLE_VIDEO_PORT;
574#endif
575
576 if (config_params->data_sz == CCDC_DATA_8BITS)
577 val |= (CCDC_DATA_10BITS & CCDC_FMTCFG_VPIN_MASK)
578 << CCDC_FMTCFG_VPIN_SHIFT;
579 else
580 val |= (config_params->data_sz & CCDC_FMTCFG_VPIN_MASK)
581 << CCDC_FMTCFG_VPIN_SHIFT;
582 /* Write value in FMTCFG */
583 regw(val, CCDC_FMTCFG);
584
585 dev_dbg(dev, "\nWriting 0x%x to FMTCFG...\n", val);
586 /* Configure the color pattern according to mt9t001 sensor */
587 regw(CCDC_COLPTN_VAL, CCDC_COLPTN);
588
589 dev_dbg(dev, "\nWriting 0xBB11BB11 to COLPTN...\n");
590 /*
591 * Configure Data formatter(Video port) pixel selection
592 * (FMT_HORZ, FMT_VERT)
593 */
594 val = ((params->win.left & CCDC_FMT_HORZ_FMTSPH_MASK) <<
595 CCDC_FMT_HORZ_FMTSPH_SHIFT) |
596 (params->win.width & CCDC_FMT_HORZ_FMTLNH_MASK);
597 regw(val, CCDC_FMT_HORZ);
598
599 dev_dbg(dev, "\nWriting 0x%x to FMT_HORZ...\n", val);
600 val = (params->win.top & CCDC_FMT_VERT_FMTSLV_MASK)
601 << CCDC_FMT_VERT_FMTSLV_SHIFT;
602 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
603 val |= (params->win.height) & CCDC_FMT_VERT_FMTLNV_MASK;
604 else
605 val |= (params->win.height >> 1) & CCDC_FMT_VERT_FMTLNV_MASK;
606
607 dev_dbg(dev, "\nparams->win.height 0x%x ...\n",
608 params->win.height);
609 regw(val, CCDC_FMT_VERT);
610
611 dev_dbg(dev, "\nWriting 0x%x to FMT_VERT...\n", val);
612
613 dev_dbg(dev, "\nbelow regw(val, FMT_VERT)...");
614
615 /*
616 * Configure Horizontal offset register. If pack 8 is enabled then
617 * 1 pixel will take 1 byte
618 */
619 if ((config_params->data_sz == CCDC_DATA_8BITS) ||
620 config_params->alaw.enable)
621 regw((params->win.width + CCDC_32BYTE_ALIGN_VAL) &
622 CCDC_HSIZE_OFF_MASK, CCDC_HSIZE_OFF);
623 else
624 /* else one pixel will take 2 byte */
625 regw(((params->win.width * CCDC_TWO_BYTES_PER_PIXEL) +
626 CCDC_32BYTE_ALIGN_VAL) & CCDC_HSIZE_OFF_MASK,
627 CCDC_HSIZE_OFF);
628
629 /* Set value for SDOFST */
630 if (params->frm_fmt == CCDC_FRMFMT_INTERLACED) {
631 if (params->image_invert_enable) {
632 /* For intelace inverse mode */
633 regw(CCDC_INTERLACED_IMAGE_INVERT, CCDC_SDOFST);
634 dev_dbg(dev, "\nWriting 0x4B6D to SDOFST...\n");
635 }
636
637 else {
638 /* For intelace non inverse mode */
639 regw(CCDC_INTERLACED_NO_IMAGE_INVERT, CCDC_SDOFST);
640 dev_dbg(dev, "\nWriting 0x0249 to SDOFST...\n");
641 }
642 } else if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE) {
643 regw(CCDC_PROGRESSIVE_NO_IMAGE_INVERT, CCDC_SDOFST);
644 dev_dbg(dev, "\nWriting 0x0000 to SDOFST...\n");
645 }
646
647 /*
648 * Configure video port pixel selection (VPOUT)
649 * Here -1 is to make the height value less than FMT_VERT.FMTLNV
650 */
651 if (params->frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
652 val = (((params->win.height - 1) & CCDC_VP_OUT_VERT_NUM_MASK))
653 << CCDC_VP_OUT_VERT_NUM_SHIFT;
654 else
655 val =
656 ((((params->win.height >> CCDC_INTERLACED_HEIGHT_SHIFT) -
657 1) & CCDC_VP_OUT_VERT_NUM_MASK)) <<
658 CCDC_VP_OUT_VERT_NUM_SHIFT;
659
660 val |= ((((params->win.width))) & CCDC_VP_OUT_HORZ_NUM_MASK)
661 << CCDC_VP_OUT_HORZ_NUM_SHIFT;
662 val |= (params->win.left) & CCDC_VP_OUT_HORZ_ST_MASK;
663 regw(val, CCDC_VP_OUT);
664
665 dev_dbg(dev, "\nWriting 0x%x to VP_OUT...\n", val);
666 regw(syn_mode, CCDC_SYN_MODE);
667 dev_dbg(dev, "\nWriting 0x%x to SYN_MODE...\n", syn_mode);
668
669 ccdc_sbl_reset();
670 dev_dbg(dev, "\nend of ccdc_config_raw...");
671 ccdc_readregs();
672}
673
674static int ccdc_configure(void)
675{
676 if (ccdc_if_type == VPFE_RAW_BAYER)
677 ccdc_config_raw();
678 else
679 ccdc_config_ycbcr();
680 return 0;
681}
682
683static int ccdc_set_buftype(enum ccdc_buftype buf_type)
684{
685 if (ccdc_if_type == VPFE_RAW_BAYER)
686 ccdc_hw_params_raw.buf_type = buf_type;
687 else
688 ccdc_hw_params_ycbcr.buf_type = buf_type;
689 return 0;
690}
691
692static enum ccdc_buftype ccdc_get_buftype(void)
693{
694 if (ccdc_if_type == VPFE_RAW_BAYER)
695 return ccdc_hw_params_raw.buf_type;
696 return ccdc_hw_params_ycbcr.buf_type;
697}
698
699static int ccdc_enum_pix(u32 *pix, int i)
700{
701 int ret = -EINVAL;
702 if (ccdc_if_type == VPFE_RAW_BAYER) {
703 if (i < ARRAY_SIZE(ccdc_raw_bayer_pix_formats)) {
704 *pix = ccdc_raw_bayer_pix_formats[i];
705 ret = 0;
706 }
707 } else {
708 if (i < ARRAY_SIZE(ccdc_raw_yuv_pix_formats)) {
709 *pix = ccdc_raw_yuv_pix_formats[i];
710 ret = 0;
711 }
712 }
713 return ret;
714}
715
716static int ccdc_set_pixel_format(u32 pixfmt)
717{
718 if (ccdc_if_type == VPFE_RAW_BAYER) {
719 ccdc_hw_params_raw.pix_fmt = CCDC_PIXFMT_RAW;
720 if (pixfmt == V4L2_PIX_FMT_SBGGR8)
721 ccdc_hw_params_raw.config_params.alaw.enable = 1;
722 else if (pixfmt != V4L2_PIX_FMT_SBGGR16)
723 return -EINVAL;
724 } else {
725 if (pixfmt == V4L2_PIX_FMT_YUYV)
726 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_YCBYCR;
727 else if (pixfmt == V4L2_PIX_FMT_UYVY)
728 ccdc_hw_params_ycbcr.pix_order = CCDC_PIXORDER_CBYCRY;
729 else
730 return -EINVAL;
731 }
732 return 0;
733}
734
735static u32 ccdc_get_pixel_format(void)
736{
737 struct ccdc_a_law *alaw =
738 &ccdc_hw_params_raw.config_params.alaw;
739 u32 pixfmt;
740
741 if (ccdc_if_type == VPFE_RAW_BAYER)
742 if (alaw->enable)
743 pixfmt = V4L2_PIX_FMT_SBGGR8;
744 else
745 pixfmt = V4L2_PIX_FMT_SBGGR16;
746 else {
747 if (ccdc_hw_params_ycbcr.pix_order == CCDC_PIXORDER_YCBYCR)
748 pixfmt = V4L2_PIX_FMT_YUYV;
749 else
750 pixfmt = V4L2_PIX_FMT_UYVY;
751 }
752 return pixfmt;
753}
754
755static int ccdc_set_image_window(struct v4l2_rect *win)
756{
757 if (ccdc_if_type == VPFE_RAW_BAYER)
758 ccdc_hw_params_raw.win = *win;
759 else
760 ccdc_hw_params_ycbcr.win = *win;
761 return 0;
762}
763
764static void ccdc_get_image_window(struct v4l2_rect *win)
765{
766 if (ccdc_if_type == VPFE_RAW_BAYER)
767 *win = ccdc_hw_params_raw.win;
768 else
769 *win = ccdc_hw_params_ycbcr.win;
770}
771
772static unsigned int ccdc_get_line_length(void)
773{
774 struct ccdc_config_params_raw *config_params =
775 &ccdc_hw_params_raw.config_params;
776 unsigned int len;
777
778 if (ccdc_if_type == VPFE_RAW_BAYER) {
779 if ((config_params->alaw.enable) ||
780 (config_params->data_sz == CCDC_DATA_8BITS))
781 len = ccdc_hw_params_raw.win.width;
782 else
783 len = ccdc_hw_params_raw.win.width * 2;
784 } else
785 len = ccdc_hw_params_ycbcr.win.width * 2;
786 return ALIGN(len, 32);
787}
788
789static int ccdc_set_frame_format(enum ccdc_frmfmt frm_fmt)
790{
791 if (ccdc_if_type == VPFE_RAW_BAYER)
792 ccdc_hw_params_raw.frm_fmt = frm_fmt;
793 else
794 ccdc_hw_params_ycbcr.frm_fmt = frm_fmt;
795 return 0;
796}
797
798static enum ccdc_frmfmt ccdc_get_frame_format(void)
799{
800 if (ccdc_if_type == VPFE_RAW_BAYER)
801 return ccdc_hw_params_raw.frm_fmt;
802 else
803 return ccdc_hw_params_ycbcr.frm_fmt;
804}
805
806static int ccdc_getfid(void)
807{
808 return (regr(CCDC_SYN_MODE) >> 15) & 1;
809}
810
811/* misc operations */
812static inline void ccdc_setfbaddr(unsigned long addr)
813{
814 regw(addr & 0xffffffe0, CCDC_SDR_ADDR);
815}
816
817static int ccdc_set_hw_if_params(struct vpfe_hw_if_param *params)
818{
819 ccdc_if_type = params->if_type;
820
821 switch (params->if_type) {
822 case VPFE_BT656:
823 case VPFE_YCBCR_SYNC_16:
824 case VPFE_YCBCR_SYNC_8:
825 ccdc_hw_params_ycbcr.vd_pol = params->vdpol;
826 ccdc_hw_params_ycbcr.hd_pol = params->hdpol;
827 break;
828 default:
829 /* TODO add support for raw bayer here */
830 return -EINVAL;
831 }
832 return 0;
833}
834
835static struct ccdc_hw_device ccdc_hw_dev = {
836 .name = "DM6446 CCDC",
837 .owner = THIS_MODULE,
838 .hw_ops = {
839 .open = ccdc_open,
840 .close = ccdc_close,
841 .set_ccdc_base = ccdc_set_ccdc_base,
842 .reset = ccdc_sbl_reset,
843 .enable = ccdc_enable,
844 .set_hw_if_params = ccdc_set_hw_if_params,
845 .set_params = ccdc_set_params,
846 .configure = ccdc_configure,
847 .set_buftype = ccdc_set_buftype,
848 .get_buftype = ccdc_get_buftype,
849 .enum_pix = ccdc_enum_pix,
850 .set_pixel_format = ccdc_set_pixel_format,
851 .get_pixel_format = ccdc_get_pixel_format,
852 .set_frame_format = ccdc_set_frame_format,
853 .get_frame_format = ccdc_get_frame_format,
854 .set_image_window = ccdc_set_image_window,
855 .get_image_window = ccdc_get_image_window,
856 .get_line_length = ccdc_get_line_length,
857 .setfbaddr = ccdc_setfbaddr,
858 .getfid = ccdc_getfid,
859 },
860};
861
862static int dm644x_ccdc_init(void)
863{
864 printk(KERN_NOTICE "dm644x_ccdc_init\n");
865 if (vpfe_register_ccdc_device(&ccdc_hw_dev) < 0)
866 return -1;
867 printk(KERN_NOTICE "%s is registered with vpfe.\n",
868 ccdc_hw_dev.name);
869 return 0;
870}
871
872static void dm644x_ccdc_exit(void)
873{
874 vpfe_unregister_ccdc_device(&ccdc_hw_dev);
875}
876
877module_init(dm644x_ccdc_init);
878module_exit(dm644x_ccdc_exit);
diff --git a/drivers/media/video/davinci/dm644x_ccdc_regs.h b/drivers/media/video/davinci/dm644x_ccdc_regs.h
new file mode 100644
index 000000000000..6e5d05324466
--- /dev/null
+++ b/drivers/media/video/davinci/dm644x_ccdc_regs.h
@@ -0,0 +1,145 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM644X_CCDC_REGS_H
19#define _DM644X_CCDC_REGS_H
20
21/**************************************************************************\
22* Register OFFSET Definitions
23\**************************************************************************/
24#define CCDC_PID 0x0
25#define CCDC_PCR 0x4
26#define CCDC_SYN_MODE 0x8
27#define CCDC_HD_VD_WID 0xc
28#define CCDC_PIX_LINES 0x10
29#define CCDC_HORZ_INFO 0x14
30#define CCDC_VERT_START 0x18
31#define CCDC_VERT_LINES 0x1c
32#define CCDC_CULLING 0x20
33#define CCDC_HSIZE_OFF 0x24
34#define CCDC_SDOFST 0x28
35#define CCDC_SDR_ADDR 0x2c
36#define CCDC_CLAMP 0x30
37#define CCDC_DCSUB 0x34
38#define CCDC_COLPTN 0x38
39#define CCDC_BLKCMP 0x3c
40#define CCDC_FPC 0x40
41#define CCDC_FPC_ADDR 0x44
42#define CCDC_VDINT 0x48
43#define CCDC_ALAW 0x4c
44#define CCDC_REC656IF 0x50
45#define CCDC_CCDCFG 0x54
46#define CCDC_FMTCFG 0x58
47#define CCDC_FMT_HORZ 0x5c
48#define CCDC_FMT_VERT 0x60
49#define CCDC_FMT_ADDR0 0x64
50#define CCDC_FMT_ADDR1 0x68
51#define CCDC_FMT_ADDR2 0x6c
52#define CCDC_FMT_ADDR3 0x70
53#define CCDC_FMT_ADDR4 0x74
54#define CCDC_FMT_ADDR5 0x78
55#define CCDC_FMT_ADDR6 0x7c
56#define CCDC_FMT_ADDR7 0x80
57#define CCDC_PRGEVEN_0 0x84
58#define CCDC_PRGEVEN_1 0x88
59#define CCDC_PRGODD_0 0x8c
60#define CCDC_PRGODD_1 0x90
61#define CCDC_VP_OUT 0x94
62
63
64/***************************************************************
65* Define for various register bit mask and shifts for CCDC
66****************************************************************/
67#define CCDC_FID_POL_MASK 1
68#define CCDC_FID_POL_SHIFT 4
69#define CCDC_HD_POL_MASK 1
70#define CCDC_HD_POL_SHIFT 3
71#define CCDC_VD_POL_MASK 1
72#define CCDC_VD_POL_SHIFT 2
73#define CCDC_HSIZE_OFF_MASK 0xffffffe0
74#define CCDC_32BYTE_ALIGN_VAL 31
75#define CCDC_FRM_FMT_MASK 0x1
76#define CCDC_FRM_FMT_SHIFT 7
77#define CCDC_DATA_SZ_MASK 7
78#define CCDC_DATA_SZ_SHIFT 8
79#define CCDC_PIX_FMT_MASK 3
80#define CCDC_PIX_FMT_SHIFT 12
81#define CCDC_VP2SDR_DISABLE 0xFFFBFFFF
82#define CCDC_WEN_ENABLE (1 << 17)
83#define CCDC_SDR2RSZ_DISABLE 0xFFF7FFFF
84#define CCDC_VDHDEN_ENABLE (1 << 16)
85#define CCDC_LPF_ENABLE (1 << 14)
86#define CCDC_ALAW_ENABLE (1 << 3)
87#define CCDC_ALAW_GAMA_WD_MASK 7
88#define CCDC_BLK_CLAMP_ENABLE (1 << 31)
89#define CCDC_BLK_SGAIN_MASK 0x1F
90#define CCDC_BLK_ST_PXL_MASK 0x7FFF
91#define CCDC_BLK_ST_PXL_SHIFT 10
92#define CCDC_BLK_SAMPLE_LN_MASK 7
93#define CCDC_BLK_SAMPLE_LN_SHIFT 28
94#define CCDC_BLK_SAMPLE_LINE_MASK 7
95#define CCDC_BLK_SAMPLE_LINE_SHIFT 25
96#define CCDC_BLK_DC_SUB_MASK 0x03FFF
97#define CCDC_BLK_COMP_MASK 0xFF
98#define CCDC_BLK_COMP_GB_COMP_SHIFT 8
99#define CCDC_BLK_COMP_GR_COMP_SHIFT 16
100#define CCDC_BLK_COMP_R_COMP_SHIFT 24
101#define CCDC_LATCH_ON_VSYNC_DISABLE (1 << 15)
102#define CCDC_FPC_ENABLE (1 << 15)
103#define CCDC_FPC_DISABLE 0
104#define CCDC_FPC_FPC_NUM_MASK 0x7FFF
105#define CCDC_DATA_PACK_ENABLE (1 << 11)
106#define CCDC_FMTCFG_VPIN_MASK 7
107#define CCDC_FMTCFG_VPIN_SHIFT 12
108#define CCDC_FMT_HORZ_FMTLNH_MASK 0x1FFF
109#define CCDC_FMT_HORZ_FMTSPH_MASK 0x1FFF
110#define CCDC_FMT_HORZ_FMTSPH_SHIFT 16
111#define CCDC_FMT_VERT_FMTLNV_MASK 0x1FFF
112#define CCDC_FMT_VERT_FMTSLV_MASK 0x1FFF
113#define CCDC_FMT_VERT_FMTSLV_SHIFT 16
114#define CCDC_VP_OUT_VERT_NUM_MASK 0x3FFF
115#define CCDC_VP_OUT_VERT_NUM_SHIFT 17
116#define CCDC_VP_OUT_HORZ_NUM_MASK 0x1FFF
117#define CCDC_VP_OUT_HORZ_NUM_SHIFT 4
118#define CCDC_VP_OUT_HORZ_ST_MASK 0xF
119#define CCDC_HORZ_INFO_SPH_SHIFT 16
120#define CCDC_VERT_START_SLV0_SHIFT 16
121#define CCDC_VDINT_VDINT0_SHIFT 16
122#define CCDC_VDINT_VDINT1_MASK 0xFFFF
123#define CCDC_PPC_RAW 1
124#define CCDC_DCSUB_DEFAULT_VAL 0
125#define CCDC_CLAMP_DEFAULT_VAL 0
126#define CCDC_ENABLE_VIDEO_PORT 0x8000
127#define CCDC_DISABLE_VIDEO_PORT 0
128#define CCDC_COLPTN_VAL 0xBB11BB11
129#define CCDC_TWO_BYTES_PER_PIXEL 2
130#define CCDC_INTERLACED_IMAGE_INVERT 0x4B6D
131#define CCDC_INTERLACED_NO_IMAGE_INVERT 0x0249
132#define CCDC_PROGRESSIVE_IMAGE_INVERT 0x4000
133#define CCDC_PROGRESSIVE_NO_IMAGE_INVERT 0
134#define CCDC_INTERLACED_HEIGHT_SHIFT 1
135#define CCDC_SYN_MODE_INPMOD_SHIFT 12
136#define CCDC_SYN_MODE_INPMOD_MASK 3
137#define CCDC_SYN_MODE_8BITS (7 << 8)
138#define CCDC_SYN_FLDMODE_MASK 1
139#define CCDC_SYN_FLDMODE_SHIFT 7
140#define CCDC_REC656IF_BT656_EN 3
141#define CCDC_SYN_MODE_VD_POL_NEGATIVE (1 << 2)
142#define CCDC_CCDCFG_Y8POS_SHIFT 11
143#define CCDC_SDOFST_FIELD_INTERLEAVED 0x249
144#define CCDC_NO_CULLING 0xffff00ff
145#endif
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
new file mode 100644
index 000000000000..402ce43ef38e
--- /dev/null
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -0,0 +1,2124 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * Driver name : VPFE Capture driver
19 * VPFE Capture driver allows applications to capture and stream video
20 * frames on DaVinci SoCs (DM6446, DM355 etc) from a YUV source such as
21 * TVP5146 or Raw Bayer RGB image data from an image sensor
22 * such as Microns' MT9T001, MT9T031 etc.
23 *
24 * These SoCs have, in common, a Video Processing Subsystem (VPSS) that
25 * consists of a Video Processing Front End (VPFE) for capturing
26 * video/raw image data and Video Processing Back End (VPBE) for displaying
27 * YUV data through an in-built analog encoder or Digital LCD port. This
28 * driver is for capture through VPFE. A typical EVM using these SoCs have
29 * following high level configuration.
30 *
31 *
32 * decoder(TVP5146/ YUV/
33 * MT9T001) --> Raw Bayer RGB ---> MUX -> VPFE (CCDC/ISIF)
34 * data input | |
35 * V |
36 * SDRAM |
37 * V
38 * Image Processor
39 * |
40 * V
41 * SDRAM
42 * The data flow happens from a decoder connected to the VPFE over a
43 * YUV embedded (BT.656/BT.1120) or separate sync or raw bayer rgb interface
44 * and to the input of VPFE through an optional MUX (if more inputs are
45 * to be interfaced on the EVM). The input data is first passed through
46 * CCDC (CCD Controller, a.k.a Image Sensor Interface, ISIF). The CCDC
47 * does very little or no processing on YUV data and does pre-process Raw
48 * Bayer RGB data through modules such as Defect Pixel Correction (DFC)
49 * Color Space Conversion (CSC), data gain/offset etc. After this, data
50 * can be written to SDRAM or can be connected to the image processing
51 * block such as IPIPE (on DM355 only).
52 *
53 * Features supported
54 * - MMAP IO
55 * - Capture using TVP5146 over BT.656
56 * - support for interfacing decoders using sub device model
57 * - Work with DM355 or DM6446 CCDC to do Raw Bayer RGB/YUV
58 * data capture to SDRAM.
59 * TODO list
60 * - Support multiple REQBUF after open
61 * - Support for de-allocating buffers through REQBUF
62 * - Support for Raw Bayer RGB capture
63 * - Support for chaining Image Processor
64 * - Support for static allocation of buffers
65 * - Support for USERPTR IO
66 * - Support for STREAMON before QBUF
67 * - Support for control ioctls
68 */
69#include <linux/module.h>
70#include <linux/init.h>
71#include <linux/platform_device.h>
72#include <linux/interrupt.h>
73#include <linux/version.h>
74#include <media/v4l2-common.h>
75#include <linux/io.h>
76#include <media/davinci/vpfe_capture.h>
77#include "ccdc_hw_device.h"
78
79static int debug;
80static u32 numbuffers = 3;
81static u32 bufsize = (720 * 576 * 2);
82
83module_param(numbuffers, uint, S_IRUGO);
84module_param(bufsize, uint, S_IRUGO);
85module_param(debug, int, 0644);
86
87MODULE_PARM_DESC(numbuffers, "buffer count (default:3)");
88MODULE_PARM_DESC(bufsize, "buffer size in bytes (default:720 x 576 x 2)");
89MODULE_PARM_DESC(debug, "Debug level 0-1");
90
91MODULE_DESCRIPTION("VPFE Video for Linux Capture Driver");
92MODULE_LICENSE("GPL");
93MODULE_AUTHOR("Texas Instruments");
94
95/* standard information */
96struct vpfe_standard {
97 v4l2_std_id std_id;
98 unsigned int width;
99 unsigned int height;
100 struct v4l2_fract pixelaspect;
101 /* 0 - progressive, 1 - interlaced */
102 int frame_format;
103};
104
105/* ccdc configuration */
106struct ccdc_config {
107 /* This make sure vpfe is probed and ready to go */
108 int vpfe_probed;
109 /* name of ccdc device */
110 char name[32];
111 /* for storing mem maps for CCDC */
112 int ccdc_addr_size;
113 void *__iomem ccdc_addr;
114};
115
116/* data structures */
117static struct vpfe_config_params config_params = {
118 .min_numbuffers = 3,
119 .numbuffers = 3,
120 .min_bufsize = 720 * 480 * 2,
121 .device_bufsize = 720 * 576 * 2,
122};
123
124/* ccdc device registered */
125static struct ccdc_hw_device *ccdc_dev;
126/* lock for accessing ccdc information */
127static DEFINE_MUTEX(ccdc_lock);
128/* ccdc configuration */
129static struct ccdc_config *ccdc_cfg;
130
131const struct vpfe_standard vpfe_standards[] = {
132 {V4L2_STD_525_60, 720, 480, {11, 10}, 1},
133 {V4L2_STD_625_50, 720, 576, {54, 59}, 1},
134};
135
136/* Used when raw Bayer image from ccdc is directly captured to SDRAM */
137static const struct vpfe_pixel_format vpfe_pix_fmts[] = {
138 {
139 .fmtdesc = {
140 .index = 0,
141 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
142 .description = "Bayer GrRBGb 8bit A-Law compr.",
143 .pixelformat = V4L2_PIX_FMT_SBGGR8,
144 },
145 .bpp = 1,
146 },
147 {
148 .fmtdesc = {
149 .index = 1,
150 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
151 .description = "Bayer GrRBGb - 16bit",
152 .pixelformat = V4L2_PIX_FMT_SBGGR16,
153 },
154 .bpp = 2,
155 },
156 {
157 .fmtdesc = {
158 .index = 2,
159 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
160 .description = "Bayer GrRBGb 8bit DPCM compr.",
161 .pixelformat = V4L2_PIX_FMT_SGRBG10DPCM8,
162 },
163 .bpp = 1,
164 },
165 {
166 .fmtdesc = {
167 .index = 3,
168 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
169 .description = "YCbCr 4:2:2 Interleaved UYVY",
170 .pixelformat = V4L2_PIX_FMT_UYVY,
171 },
172 .bpp = 2,
173 },
174 {
175 .fmtdesc = {
176 .index = 4,
177 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
178 .description = "YCbCr 4:2:2 Interleaved YUYV",
179 .pixelformat = V4L2_PIX_FMT_YUYV,
180 },
181 .bpp = 2,
182 },
183 {
184 .fmtdesc = {
185 .index = 5,
186 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
187 .description = "Y/CbCr 4:2:0 - Semi planar",
188 .pixelformat = V4L2_PIX_FMT_NV12,
189 },
190 .bpp = 1,
191 },
192};
193
194/*
195 * vpfe_lookup_pix_format()
196 * lookup an entry in the vpfe pix format table based on pix_format
197 */
198static const struct vpfe_pixel_format *vpfe_lookup_pix_format(u32 pix_format)
199{
200 int i;
201
202 for (i = 0; i < ARRAY_SIZE(vpfe_pix_fmts); i++) {
203 if (pix_format == vpfe_pix_fmts[i].fmtdesc.pixelformat)
204 return &vpfe_pix_fmts[i];
205 }
206 return NULL;
207}
208
209/*
210 * vpfe_register_ccdc_device. CCDC module calls this to
211 * register with vpfe capture
212 */
213int vpfe_register_ccdc_device(struct ccdc_hw_device *dev)
214{
215 int ret = 0;
216 printk(KERN_NOTICE "vpfe_register_ccdc_device: %s\n", dev->name);
217
218 BUG_ON(!dev->hw_ops.open);
219 BUG_ON(!dev->hw_ops.enable);
220 BUG_ON(!dev->hw_ops.set_hw_if_params);
221 BUG_ON(!dev->hw_ops.configure);
222 BUG_ON(!dev->hw_ops.set_buftype);
223 BUG_ON(!dev->hw_ops.get_buftype);
224 BUG_ON(!dev->hw_ops.enum_pix);
225 BUG_ON(!dev->hw_ops.set_frame_format);
226 BUG_ON(!dev->hw_ops.get_frame_format);
227 BUG_ON(!dev->hw_ops.get_pixel_format);
228 BUG_ON(!dev->hw_ops.set_pixel_format);
229 BUG_ON(!dev->hw_ops.set_params);
230 BUG_ON(!dev->hw_ops.set_image_window);
231 BUG_ON(!dev->hw_ops.get_image_window);
232 BUG_ON(!dev->hw_ops.get_line_length);
233 BUG_ON(!dev->hw_ops.setfbaddr);
234 BUG_ON(!dev->hw_ops.getfid);
235
236 mutex_lock(&ccdc_lock);
237 if (NULL == ccdc_cfg) {
238 /*
239 * TODO. Will this ever happen? if so, we need to fix it.
240 * Proabably we need to add the request to a linked list and
241 * walk through it during vpfe probe
242 */
243 printk(KERN_ERR "vpfe capture not initialized\n");
244 ret = -1;
245 goto unlock;
246 }
247
248 if (strcmp(dev->name, ccdc_cfg->name)) {
249 /* ignore this ccdc */
250 ret = -1;
251 goto unlock;
252 }
253
254 if (ccdc_dev) {
255 printk(KERN_ERR "ccdc already registered\n");
256 ret = -1;
257 goto unlock;
258 }
259
260 ccdc_dev = dev;
261 dev->hw_ops.set_ccdc_base(ccdc_cfg->ccdc_addr,
262 ccdc_cfg->ccdc_addr_size);
263unlock:
264 mutex_unlock(&ccdc_lock);
265 return ret;
266}
267EXPORT_SYMBOL(vpfe_register_ccdc_device);
268
269/*
270 * vpfe_unregister_ccdc_device. CCDC module calls this to
271 * unregister with vpfe capture
272 */
273void vpfe_unregister_ccdc_device(struct ccdc_hw_device *dev)
274{
275 if (NULL == dev) {
276 printk(KERN_ERR "invalid ccdc device ptr\n");
277 return;
278 }
279
280 printk(KERN_NOTICE "vpfe_unregister_ccdc_device, dev->name = %s\n",
281 dev->name);
282
283 if (strcmp(dev->name, ccdc_cfg->name)) {
284 /* ignore this ccdc */
285 return;
286 }
287
288 mutex_lock(&ccdc_lock);
289 ccdc_dev = NULL;
290 mutex_unlock(&ccdc_lock);
291 return;
292}
293EXPORT_SYMBOL(vpfe_unregister_ccdc_device);
294
295/*
296 * vpfe_get_ccdc_image_format - Get image parameters based on CCDC settings
297 */
298static int vpfe_get_ccdc_image_format(struct vpfe_device *vpfe_dev,
299 struct v4l2_format *f)
300{
301 struct v4l2_rect image_win;
302 enum ccdc_buftype buf_type;
303 enum ccdc_frmfmt frm_fmt;
304
305 memset(f, 0, sizeof(*f));
306 f->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
307 ccdc_dev->hw_ops.get_image_window(&image_win);
308 f->fmt.pix.width = image_win.width;
309 f->fmt.pix.height = image_win.height;
310 f->fmt.pix.bytesperline = ccdc_dev->hw_ops.get_line_length();
311 f->fmt.pix.sizeimage = f->fmt.pix.bytesperline *
312 f->fmt.pix.height;
313 buf_type = ccdc_dev->hw_ops.get_buftype();
314 f->fmt.pix.pixelformat = ccdc_dev->hw_ops.get_pixel_format();
315 frm_fmt = ccdc_dev->hw_ops.get_frame_format();
316 if (frm_fmt == CCDC_FRMFMT_PROGRESSIVE)
317 f->fmt.pix.field = V4L2_FIELD_NONE;
318 else if (frm_fmt == CCDC_FRMFMT_INTERLACED) {
319 if (buf_type == CCDC_BUFTYPE_FLD_INTERLEAVED)
320 f->fmt.pix.field = V4L2_FIELD_INTERLACED;
321 else if (buf_type == CCDC_BUFTYPE_FLD_SEPARATED)
322 f->fmt.pix.field = V4L2_FIELD_SEQ_TB;
323 else {
324 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf_type\n");
325 return -EINVAL;
326 }
327 } else {
328 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid frm_fmt\n");
329 return -EINVAL;
330 }
331 return 0;
332}
333
334/*
335 * vpfe_config_ccdc_image_format()
336 * For a pix format, configure ccdc to setup the capture
337 */
338static int vpfe_config_ccdc_image_format(struct vpfe_device *vpfe_dev)
339{
340 enum ccdc_frmfmt frm_fmt = CCDC_FRMFMT_INTERLACED;
341 int ret = 0;
342
343 if (ccdc_dev->hw_ops.set_pixel_format(
344 vpfe_dev->fmt.fmt.pix.pixelformat) < 0) {
345 v4l2_err(&vpfe_dev->v4l2_dev,
346 "couldn't set pix format in ccdc\n");
347 return -EINVAL;
348 }
349 /* configure the image window */
350 ccdc_dev->hw_ops.set_image_window(&vpfe_dev->crop);
351
352 switch (vpfe_dev->fmt.fmt.pix.field) {
353 case V4L2_FIELD_INTERLACED:
354 /* do nothing, since it is default */
355 ret = ccdc_dev->hw_ops.set_buftype(
356 CCDC_BUFTYPE_FLD_INTERLEAVED);
357 break;
358 case V4L2_FIELD_NONE:
359 frm_fmt = CCDC_FRMFMT_PROGRESSIVE;
360 /* buffer type only applicable for interlaced scan */
361 break;
362 case V4L2_FIELD_SEQ_TB:
363 ret = ccdc_dev->hw_ops.set_buftype(
364 CCDC_BUFTYPE_FLD_SEPARATED);
365 break;
366 default:
367 return -EINVAL;
368 }
369
370 /* set the frame format */
371 if (!ret)
372 ret = ccdc_dev->hw_ops.set_frame_format(frm_fmt);
373 return ret;
374}
375/*
376 * vpfe_config_image_format()
377 * For a given standard, this functions sets up the default
378 * pix format & crop values in the vpfe device and ccdc. It first
379 * starts with defaults based values from the standard table.
380 * It then checks if sub device support g_fmt and then override the
381 * values based on that.Sets crop values to match with scan resolution
382 * starting at 0,0. It calls vpfe_config_ccdc_image_format() set the
383 * values in ccdc
384 */
385static int vpfe_config_image_format(struct vpfe_device *vpfe_dev,
386 const v4l2_std_id *std_id)
387{
388 struct vpfe_subdev_info *sdinfo = vpfe_dev->current_subdev;
389 int i, ret = 0;
390
391 for (i = 0; i < ARRAY_SIZE(vpfe_standards); i++) {
392 if (vpfe_standards[i].std_id & *std_id) {
393 vpfe_dev->std_info.active_pixels =
394 vpfe_standards[i].width;
395 vpfe_dev->std_info.active_lines =
396 vpfe_standards[i].height;
397 vpfe_dev->std_info.frame_format =
398 vpfe_standards[i].frame_format;
399 vpfe_dev->std_index = i;
400 break;
401 }
402 }
403
404 if (i == ARRAY_SIZE(vpfe_standards)) {
405 v4l2_err(&vpfe_dev->v4l2_dev, "standard not supported\n");
406 return -EINVAL;
407 }
408
409 vpfe_dev->crop.top = 0;
410 vpfe_dev->crop.left = 0;
411 vpfe_dev->crop.width = vpfe_dev->std_info.active_pixels;
412 vpfe_dev->crop.height = vpfe_dev->std_info.active_lines;
413 vpfe_dev->fmt.fmt.pix.width = vpfe_dev->crop.width;
414 vpfe_dev->fmt.fmt.pix.height = vpfe_dev->crop.height;
415
416 /* first field and frame format based on standard frame format */
417 if (vpfe_dev->std_info.frame_format) {
418 vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
419 /* assume V4L2_PIX_FMT_UYVY as default */
420 vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_UYVY;
421 } else {
422 vpfe_dev->fmt.fmt.pix.field = V4L2_FIELD_NONE;
423 /* assume V4L2_PIX_FMT_SBGGR8 */
424 vpfe_dev->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
425 }
426
427 /* if sub device supports g_fmt, override the defaults */
428 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
429 sdinfo->grp_id, video, g_fmt, &vpfe_dev->fmt);
430
431 if (ret && ret != -ENOIOCTLCMD) {
432 v4l2_err(&vpfe_dev->v4l2_dev,
433 "error in getting g_fmt from sub device\n");
434 return ret;
435 }
436
437 /* Sets the values in CCDC */
438 ret = vpfe_config_ccdc_image_format(vpfe_dev);
439 if (ret)
440 return ret;
441
442 /* Update the values of sizeimage and bytesperline */
443 if (!ret) {
444 vpfe_dev->fmt.fmt.pix.bytesperline =
445 ccdc_dev->hw_ops.get_line_length();
446 vpfe_dev->fmt.fmt.pix.sizeimage =
447 vpfe_dev->fmt.fmt.pix.bytesperline *
448 vpfe_dev->fmt.fmt.pix.height;
449 }
450 return ret;
451}
452
453static int vpfe_initialize_device(struct vpfe_device *vpfe_dev)
454{
455 int ret = 0;
456
457 /* set first input of current subdevice as the current input */
458 vpfe_dev->current_input = 0;
459
460 /* set default standard */
461 vpfe_dev->std_index = 0;
462
463 /* Configure the default format information */
464 ret = vpfe_config_image_format(vpfe_dev,
465 &vpfe_standards[vpfe_dev->std_index].std_id);
466 if (ret)
467 return ret;
468
469 /* now open the ccdc device to initialize it */
470 mutex_lock(&ccdc_lock);
471 if (NULL == ccdc_dev) {
472 v4l2_err(&vpfe_dev->v4l2_dev, "ccdc device not registered\n");
473 ret = -ENODEV;
474 goto unlock;
475 }
476
477 if (!try_module_get(ccdc_dev->owner)) {
478 v4l2_err(&vpfe_dev->v4l2_dev, "Couldn't lock ccdc module\n");
479 ret = -ENODEV;
480 goto unlock;
481 }
482 ret = ccdc_dev->hw_ops.open(vpfe_dev->pdev);
483 if (!ret)
484 vpfe_dev->initialized = 1;
485unlock:
486 mutex_unlock(&ccdc_lock);
487 return ret;
488}
489
490/*
491 * vpfe_open : It creates object of file handle structure and
492 * stores it in private_data member of filepointer
493 */
494static int vpfe_open(struct file *file)
495{
496 struct vpfe_device *vpfe_dev = video_drvdata(file);
497 struct vpfe_fh *fh;
498
499 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_open\n");
500
501 if (!vpfe_dev->cfg->num_subdevs) {
502 v4l2_err(&vpfe_dev->v4l2_dev, "No decoder registered\n");
503 return -ENODEV;
504 }
505
506 /* Allocate memory for the file handle object */
507 fh = kmalloc(sizeof(struct vpfe_fh), GFP_KERNEL);
508 if (NULL == fh) {
509 v4l2_err(&vpfe_dev->v4l2_dev,
510 "unable to allocate memory for file handle object\n");
511 return -ENOMEM;
512 }
513 /* store pointer to fh in private_data member of file */
514 file->private_data = fh;
515 fh->vpfe_dev = vpfe_dev;
516 mutex_lock(&vpfe_dev->lock);
517 /* If decoder is not initialized. initialize it */
518 if (!vpfe_dev->initialized) {
519 if (vpfe_initialize_device(vpfe_dev)) {
520 mutex_unlock(&vpfe_dev->lock);
521 return -ENODEV;
522 }
523 }
524 /* Increment device usrs counter */
525 vpfe_dev->usrs++;
526 /* Set io_allowed member to false */
527 fh->io_allowed = 0;
528 /* Initialize priority of this instance to default priority */
529 fh->prio = V4L2_PRIORITY_UNSET;
530 v4l2_prio_open(&vpfe_dev->prio, &fh->prio);
531 mutex_unlock(&vpfe_dev->lock);
532 return 0;
533}
534
535static void vpfe_schedule_next_buffer(struct vpfe_device *vpfe_dev)
536{
537 unsigned long addr;
538
539 vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
540 struct videobuf_buffer, queue);
541 list_del(&vpfe_dev->next_frm->queue);
542 vpfe_dev->next_frm->state = VIDEOBUF_ACTIVE;
543 addr = videobuf_to_dma_contig(vpfe_dev->next_frm);
544 ccdc_dev->hw_ops.setfbaddr(addr);
545}
546
547static void vpfe_process_buffer_complete(struct vpfe_device *vpfe_dev)
548{
549 struct timeval timevalue;
550
551 do_gettimeofday(&timevalue);
552 vpfe_dev->cur_frm->ts = timevalue;
553 vpfe_dev->cur_frm->state = VIDEOBUF_DONE;
554 vpfe_dev->cur_frm->size = vpfe_dev->fmt.fmt.pix.sizeimage;
555 wake_up_interruptible(&vpfe_dev->cur_frm->done);
556 vpfe_dev->cur_frm = vpfe_dev->next_frm;
557}
558
559/* ISR for VINT0*/
560static irqreturn_t vpfe_isr(int irq, void *dev_id)
561{
562 struct vpfe_device *vpfe_dev = dev_id;
563 enum v4l2_field field;
564 unsigned long addr;
565 int fid;
566
567 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nStarting vpfe_isr...\n");
568 field = vpfe_dev->fmt.fmt.pix.field;
569
570 /* if streaming not started, don't do anything */
571 if (!vpfe_dev->started)
572 return IRQ_HANDLED;
573
574 /* only for 6446 this will be applicable */
575 if (NULL != ccdc_dev->hw_ops.reset)
576 ccdc_dev->hw_ops.reset();
577
578 if (field == V4L2_FIELD_NONE) {
579 /* handle progressive frame capture */
580 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
581 "frame format is progressive...\n");
582 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
583 vpfe_process_buffer_complete(vpfe_dev);
584 return IRQ_HANDLED;
585 }
586
587 /* interlaced or TB capture check which field we are in hardware */
588 fid = ccdc_dev->hw_ops.getfid();
589
590 /* switch the software maintained field id */
591 vpfe_dev->field_id ^= 1;
592 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "field id = %x:%x.\n",
593 fid, vpfe_dev->field_id);
594 if (fid == vpfe_dev->field_id) {
595 /* we are in-sync here,continue */
596 if (fid == 0) {
597 /*
598 * One frame is just being captured. If the next frame
599 * is available, release the current frame and move on
600 */
601 if (vpfe_dev->cur_frm != vpfe_dev->next_frm)
602 vpfe_process_buffer_complete(vpfe_dev);
603 /*
604 * based on whether the two fields are stored
605 * interleavely or separately in memory, reconfigure
606 * the CCDC memory address
607 */
608 if (field == V4L2_FIELD_SEQ_TB) {
609 addr =
610 videobuf_to_dma_contig(vpfe_dev->cur_frm);
611 addr += vpfe_dev->field_off;
612 ccdc_dev->hw_ops.setfbaddr(addr);
613 }
614 return IRQ_HANDLED;
615 }
616 /*
617 * if one field is just being captured configure
618 * the next frame get the next frame from the empty
619 * queue if no frame is available hold on to the
620 * current buffer
621 */
622 spin_lock(&vpfe_dev->dma_queue_lock);
623 if (!list_empty(&vpfe_dev->dma_queue) &&
624 vpfe_dev->cur_frm == vpfe_dev->next_frm)
625 vpfe_schedule_next_buffer(vpfe_dev);
626 spin_unlock(&vpfe_dev->dma_queue_lock);
627 } else if (fid == 0) {
628 /*
629 * out of sync. Recover from any hardware out-of-sync.
630 * May loose one frame
631 */
632 vpfe_dev->field_id = fid;
633 }
634 return IRQ_HANDLED;
635}
636
637/* vdint1_isr - isr handler for VINT1 interrupt */
638static irqreturn_t vdint1_isr(int irq, void *dev_id)
639{
640 struct vpfe_device *vpfe_dev = dev_id;
641
642 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "\nInside vdint1_isr...\n");
643
644 /* if streaming not started, don't do anything */
645 if (!vpfe_dev->started)
646 return IRQ_HANDLED;
647
648 spin_lock(&vpfe_dev->dma_queue_lock);
649 if ((vpfe_dev->fmt.fmt.pix.field == V4L2_FIELD_NONE) &&
650 !list_empty(&vpfe_dev->dma_queue) &&
651 vpfe_dev->cur_frm == vpfe_dev->next_frm)
652 vpfe_schedule_next_buffer(vpfe_dev);
653 spin_unlock(&vpfe_dev->dma_queue_lock);
654 return IRQ_HANDLED;
655}
656
657static void vpfe_detach_irq(struct vpfe_device *vpfe_dev)
658{
659 enum ccdc_frmfmt frame_format;
660
661 frame_format = ccdc_dev->hw_ops.get_frame_format();
662 if (frame_format == CCDC_FRMFMT_PROGRESSIVE)
663 free_irq(IRQ_VDINT1, vpfe_dev);
664}
665
666static int vpfe_attach_irq(struct vpfe_device *vpfe_dev)
667{
668 enum ccdc_frmfmt frame_format;
669
670 frame_format = ccdc_dev->hw_ops.get_frame_format();
671 if (frame_format == CCDC_FRMFMT_PROGRESSIVE) {
672 return request_irq(vpfe_dev->ccdc_irq1, vdint1_isr,
673 IRQF_DISABLED, "vpfe_capture1",
674 vpfe_dev);
675 }
676 return 0;
677}
678
679/* vpfe_stop_ccdc_capture: stop streaming in ccdc/isif */
680static void vpfe_stop_ccdc_capture(struct vpfe_device *vpfe_dev)
681{
682 vpfe_dev->started = 0;
683 ccdc_dev->hw_ops.enable(0);
684 if (ccdc_dev->hw_ops.enable_out_to_sdram)
685 ccdc_dev->hw_ops.enable_out_to_sdram(0);
686}
687
688/*
689 * vpfe_release : This function deletes buffer queue, frees the
690 * buffers and the vpfe file handle
691 */
692static int vpfe_release(struct file *file)
693{
694 struct vpfe_device *vpfe_dev = video_drvdata(file);
695 struct vpfe_fh *fh = file->private_data;
696 struct vpfe_subdev_info *sdinfo;
697 int ret;
698
699 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_release\n");
700
701 /* Get the device lock */
702 mutex_lock(&vpfe_dev->lock);
703 /* if this instance is doing IO */
704 if (fh->io_allowed) {
705 if (vpfe_dev->started) {
706 sdinfo = vpfe_dev->current_subdev;
707 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev,
708 sdinfo->grp_id,
709 video, s_stream, 0);
710 if (ret && (ret != -ENOIOCTLCMD))
711 v4l2_err(&vpfe_dev->v4l2_dev,
712 "stream off failed in subdev\n");
713 vpfe_stop_ccdc_capture(vpfe_dev);
714 vpfe_detach_irq(vpfe_dev);
715 videobuf_streamoff(&vpfe_dev->buffer_queue);
716 }
717 vpfe_dev->io_usrs = 0;
718 vpfe_dev->numbuffers = config_params.numbuffers;
719 }
720
721 /* Decrement device usrs counter */
722 vpfe_dev->usrs--;
723 /* Close the priority */
724 v4l2_prio_close(&vpfe_dev->prio, &fh->prio);
725 /* If this is the last file handle */
726 if (!vpfe_dev->usrs) {
727 vpfe_dev->initialized = 0;
728 if (ccdc_dev->hw_ops.close)
729 ccdc_dev->hw_ops.close(vpfe_dev->pdev);
730 module_put(ccdc_dev->owner);
731 }
732 mutex_unlock(&vpfe_dev->lock);
733 file->private_data = NULL;
734 /* Free memory allocated to file handle object */
735 kfree(fh);
736 return 0;
737}
738
739/*
740 * vpfe_mmap : It is used to map kernel space buffers
741 * into user spaces
742 */
743static int vpfe_mmap(struct file *file, struct vm_area_struct *vma)
744{
745 /* Get the device object and file handle object */
746 struct vpfe_device *vpfe_dev = video_drvdata(file);
747
748 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_mmap\n");
749
750 return videobuf_mmap_mapper(&vpfe_dev->buffer_queue, vma);
751}
752
753/*
754 * vpfe_poll: It is used for select/poll system call
755 */
756static unsigned int vpfe_poll(struct file *file, poll_table *wait)
757{
758 struct vpfe_device *vpfe_dev = video_drvdata(file);
759
760 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_poll\n");
761
762 if (vpfe_dev->started)
763 return videobuf_poll_stream(file,
764 &vpfe_dev->buffer_queue, wait);
765 return 0;
766}
767
768/* vpfe capture driver file operations */
769static const struct v4l2_file_operations vpfe_fops = {
770 .owner = THIS_MODULE,
771 .open = vpfe_open,
772 .release = vpfe_release,
773 .unlocked_ioctl = video_ioctl2,
774 .mmap = vpfe_mmap,
775 .poll = vpfe_poll
776};
777
778/*
779 * vpfe_check_format()
780 * This function adjust the input pixel format as per hardware
781 * capabilities and update the same in pixfmt.
782 * Following algorithm used :-
783 *
784 * If given pixformat is not in the vpfe list of pix formats or not
785 * supported by the hardware, current value of pixformat in the device
786 * is used
787 * If given field is not supported, then current field is used. If field
788 * is different from current, then it is matched with that from sub device.
789 * Minimum height is 2 lines for interlaced or tb field and 1 line for
790 * progressive. Maximum height is clamped to active active lines of scan
791 * Minimum width is 32 bytes in memory and width is clamped to active
792 * pixels of scan.
793 * bytesperline is a multiple of 32.
794 */
795static const struct vpfe_pixel_format *
796 vpfe_check_format(struct vpfe_device *vpfe_dev,
797 struct v4l2_pix_format *pixfmt)
798{
799 u32 min_height = 1, min_width = 32, max_width, max_height;
800 const struct vpfe_pixel_format *vpfe_pix_fmt;
801 u32 pix;
802 int temp, found;
803
804 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
805 if (NULL == vpfe_pix_fmt) {
806 /*
807 * use current pixel format in the vpfe device. We
808 * will find this pix format in the table
809 */
810 pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
811 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
812 }
813
814 /* check if hw supports it */
815 temp = 0;
816 found = 0;
817 while (ccdc_dev->hw_ops.enum_pix(&pix, temp) >= 0) {
818 if (vpfe_pix_fmt->fmtdesc.pixelformat == pix) {
819 found = 1;
820 break;
821 }
822 temp++;
823 }
824
825 if (!found) {
826 /* use current pixel format */
827 pixfmt->pixelformat = vpfe_dev->fmt.fmt.pix.pixelformat;
828 /*
829 * Since this is currently used in the vpfe device, we
830 * will find this pix format in the table
831 */
832 vpfe_pix_fmt = vpfe_lookup_pix_format(pixfmt->pixelformat);
833 }
834
835 /* check what field format is supported */
836 if (pixfmt->field == V4L2_FIELD_ANY) {
837 /* if field is any, use current value as default */
838 pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
839 }
840
841 /*
842 * if field is not same as current field in the vpfe device
843 * try matching the field with the sub device field
844 */
845 if (vpfe_dev->fmt.fmt.pix.field != pixfmt->field) {
846 /*
847 * If field value is not in the supported fields, use current
848 * field used in the device as default
849 */
850 switch (pixfmt->field) {
851 case V4L2_FIELD_INTERLACED:
852 case V4L2_FIELD_SEQ_TB:
853 /* if sub device is supporting progressive, use that */
854 if (!vpfe_dev->std_info.frame_format)
855 pixfmt->field = V4L2_FIELD_NONE;
856 break;
857 case V4L2_FIELD_NONE:
858 if (vpfe_dev->std_info.frame_format)
859 pixfmt->field = V4L2_FIELD_INTERLACED;
860 break;
861
862 default:
863 /* use current field as default */
864 pixfmt->field = vpfe_dev->fmt.fmt.pix.field;
865 break;
866 }
867 }
868
869 /* Now adjust image resolutions supported */
870 if (pixfmt->field == V4L2_FIELD_INTERLACED ||
871 pixfmt->field == V4L2_FIELD_SEQ_TB)
872 min_height = 2;
873
874 max_width = vpfe_dev->std_info.active_pixels;
875 max_height = vpfe_dev->std_info.active_lines;
876 min_width /= vpfe_pix_fmt->bpp;
877
878 v4l2_info(&vpfe_dev->v4l2_dev, "width = %d, height = %d, bpp = %d\n",
879 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp);
880
881 pixfmt->width = clamp((pixfmt->width), min_width, max_width);
882 pixfmt->height = clamp((pixfmt->height), min_height, max_height);
883
884 /* If interlaced, adjust height to be a multiple of 2 */
885 if (pixfmt->field == V4L2_FIELD_INTERLACED)
886 pixfmt->height &= (~1);
887 /*
888 * recalculate bytesperline and sizeimage since width
889 * and height might have changed
890 */
891 pixfmt->bytesperline = (((pixfmt->width * vpfe_pix_fmt->bpp) + 31)
892 & ~31);
893 if (pixfmt->pixelformat == V4L2_PIX_FMT_NV12)
894 pixfmt->sizeimage =
895 pixfmt->bytesperline * pixfmt->height +
896 ((pixfmt->bytesperline * pixfmt->height) >> 1);
897 else
898 pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height;
899
900 v4l2_info(&vpfe_dev->v4l2_dev, "adjusted width = %d, height ="
901 " %d, bpp = %d, bytesperline = %d, sizeimage = %d\n",
902 pixfmt->width, pixfmt->height, vpfe_pix_fmt->bpp,
903 pixfmt->bytesperline, pixfmt->sizeimage);
904 return vpfe_pix_fmt;
905}
906
907static int vpfe_querycap(struct file *file, void *priv,
908 struct v4l2_capability *cap)
909{
910 struct vpfe_device *vpfe_dev = video_drvdata(file);
911
912 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querycap\n");
913
914 cap->version = VPFE_CAPTURE_VERSION_CODE;
915 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
916 strlcpy(cap->driver, CAPTURE_DRV_NAME, sizeof(cap->driver));
917 strlcpy(cap->bus_info, "VPFE", sizeof(cap->bus_info));
918 strlcpy(cap->card, vpfe_dev->cfg->card_name, sizeof(cap->card));
919 return 0;
920}
921
922static int vpfe_g_fmt_vid_cap(struct file *file, void *priv,
923 struct v4l2_format *fmt)
924{
925 struct vpfe_device *vpfe_dev = video_drvdata(file);
926 int ret = 0;
927
928 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
929 /* Fill in the information about format */
930 *fmt = vpfe_dev->fmt;
931 return ret;
932}
933
934static int vpfe_enum_fmt_vid_cap(struct file *file, void *priv,
935 struct v4l2_fmtdesc *fmt)
936{
937 struct vpfe_device *vpfe_dev = video_drvdata(file);
938 const struct vpfe_pixel_format *pix_fmt;
939 int temp_index;
940 u32 pix;
941
942 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_fmt_vid_cap\n");
943
944 if (ccdc_dev->hw_ops.enum_pix(&pix, fmt->index) < 0)
945 return -EINVAL;
946
947 /* Fill in the information about format */
948 pix_fmt = vpfe_lookup_pix_format(pix);
949 if (NULL != pix_fmt) {
950 temp_index = fmt->index;
951 *fmt = pix_fmt->fmtdesc;
952 fmt->index = temp_index;
953 return 0;
954 }
955 return -EINVAL;
956}
957
958static int vpfe_s_fmt_vid_cap(struct file *file, void *priv,
959 struct v4l2_format *fmt)
960{
961 struct vpfe_device *vpfe_dev = video_drvdata(file);
962 const struct vpfe_pixel_format *pix_fmts;
963 int ret = 0;
964
965 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_fmt_vid_cap\n");
966
967 /* If streaming is started, return error */
968 if (vpfe_dev->started) {
969 v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is started\n");
970 return -EBUSY;
971 }
972
973 /* Check for valid frame format */
974 pix_fmts = vpfe_check_format(vpfe_dev, &fmt->fmt.pix);
975
976 if (NULL == pix_fmts)
977 return -EINVAL;
978
979 /* store the pixel format in the device object */
980 ret = mutex_lock_interruptible(&vpfe_dev->lock);
981 if (ret)
982 return ret;
983
984 /* First detach any IRQ if currently attached */
985 vpfe_detach_irq(vpfe_dev);
986 vpfe_dev->fmt = *fmt;
987 /* set image capture parameters in the ccdc */
988 ret = vpfe_config_ccdc_image_format(vpfe_dev);
989 mutex_unlock(&vpfe_dev->lock);
990 return ret;
991}
992
993static int vpfe_try_fmt_vid_cap(struct file *file, void *priv,
994 struct v4l2_format *f)
995{
996 struct vpfe_device *vpfe_dev = video_drvdata(file);
997 const struct vpfe_pixel_format *pix_fmts;
998
999 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_try_fmt_vid_cap\n");
1000
1001 pix_fmts = vpfe_check_format(vpfe_dev, &f->fmt.pix);
1002 if (NULL == pix_fmts)
1003 return -EINVAL;
1004 return 0;
1005}
1006
1007/*
1008 * vpfe_get_subdev_input_index - Get subdev index and subdev input index for a
1009 * given app input index
1010 */
1011static int vpfe_get_subdev_input_index(struct vpfe_device *vpfe_dev,
1012 int *subdev_index,
1013 int *subdev_input_index,
1014 int app_input_index)
1015{
1016 struct vpfe_config *cfg = vpfe_dev->cfg;
1017 struct vpfe_subdev_info *sdinfo;
1018 int i, j = 0;
1019
1020 for (i = 0; i < cfg->num_subdevs; i++) {
1021 sdinfo = &cfg->sub_devs[i];
1022 if (app_input_index < (j + sdinfo->num_inputs)) {
1023 *subdev_index = i;
1024 *subdev_input_index = app_input_index - j;
1025 return 0;
1026 }
1027 j += sdinfo->num_inputs;
1028 }
1029 return -EINVAL;
1030}
1031
1032/*
1033 * vpfe_get_app_input - Get app input index for a given subdev input index
1034 * driver stores the input index of the current sub device and translate it
1035 * when application request the current input
1036 */
1037static int vpfe_get_app_input_index(struct vpfe_device *vpfe_dev,
1038 int *app_input_index)
1039{
1040 struct vpfe_config *cfg = vpfe_dev->cfg;
1041 struct vpfe_subdev_info *sdinfo;
1042 int i, j = 0;
1043
1044 for (i = 0; i < cfg->num_subdevs; i++) {
1045 sdinfo = &cfg->sub_devs[i];
1046 if (!strcmp(sdinfo->name, vpfe_dev->current_subdev->name)) {
1047 if (vpfe_dev->current_input >= sdinfo->num_inputs)
1048 return -1;
1049 *app_input_index = j + vpfe_dev->current_input;
1050 return 0;
1051 }
1052 j += sdinfo->num_inputs;
1053 }
1054 return -EINVAL;
1055}
1056
1057static int vpfe_enum_input(struct file *file, void *priv,
1058 struct v4l2_input *inp)
1059{
1060 struct vpfe_device *vpfe_dev = video_drvdata(file);
1061 struct vpfe_subdev_info *sdinfo;
1062 int subdev, index ;
1063
1064 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_enum_input\n");
1065
1066 if (vpfe_get_subdev_input_index(vpfe_dev,
1067 &subdev,
1068 &index,
1069 inp->index) < 0) {
1070 v4l2_err(&vpfe_dev->v4l2_dev, "input information not found"
1071 " for the subdev\n");
1072 return -EINVAL;
1073 }
1074 sdinfo = &vpfe_dev->cfg->sub_devs[subdev];
1075 memcpy(inp, &sdinfo->inputs[index], sizeof(struct v4l2_input));
1076 return 0;
1077}
1078
1079static int vpfe_g_input(struct file *file, void *priv, unsigned int *index)
1080{
1081 struct vpfe_device *vpfe_dev = video_drvdata(file);
1082
1083 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_input\n");
1084
1085 return vpfe_get_app_input_index(vpfe_dev, index);
1086}
1087
1088
1089static int vpfe_s_input(struct file *file, void *priv, unsigned int index)
1090{
1091 struct vpfe_device *vpfe_dev = video_drvdata(file);
1092 struct vpfe_subdev_info *sdinfo;
1093 int subdev_index, inp_index;
1094 struct vpfe_route *route;
1095 u32 input = 0, output = 0;
1096 int ret = -EINVAL;
1097
1098 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_input\n");
1099
1100 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1101 if (ret)
1102 return ret;
1103
1104 /*
1105 * If streaming is started return device busy
1106 * error
1107 */
1108 if (vpfe_dev->started) {
1109 v4l2_err(&vpfe_dev->v4l2_dev, "Streaming is on\n");
1110 ret = -EBUSY;
1111 goto unlock_out;
1112 }
1113
1114 if (vpfe_get_subdev_input_index(vpfe_dev,
1115 &subdev_index,
1116 &inp_index,
1117 index) < 0) {
1118 v4l2_err(&vpfe_dev->v4l2_dev, "invalid input index\n");
1119 goto unlock_out;
1120 }
1121
1122 sdinfo = &vpfe_dev->cfg->sub_devs[subdev_index];
1123 route = &sdinfo->routes[inp_index];
1124 if (route && sdinfo->can_route) {
1125 input = route->input;
1126 output = route->output;
1127 }
1128
1129 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1130 video, s_routing, input, output, 0);
1131
1132 if (ret) {
1133 v4l2_err(&vpfe_dev->v4l2_dev,
1134 "vpfe_doioctl:error in setting input in decoder\n");
1135 ret = -EINVAL;
1136 goto unlock_out;
1137 }
1138 vpfe_dev->current_subdev = sdinfo;
1139 vpfe_dev->current_input = index;
1140 vpfe_dev->std_index = 0;
1141
1142 /* set the bus/interface parameter for the sub device in ccdc */
1143 ret = ccdc_dev->hw_ops.set_hw_if_params(&sdinfo->ccdc_if_params);
1144 if (ret)
1145 goto unlock_out;
1146
1147 /* set the default image parameters in the device */
1148 ret = vpfe_config_image_format(vpfe_dev,
1149 &vpfe_standards[vpfe_dev->std_index].std_id);
1150unlock_out:
1151 mutex_unlock(&vpfe_dev->lock);
1152 return ret;
1153}
1154
1155static int vpfe_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1156{
1157 struct vpfe_device *vpfe_dev = video_drvdata(file);
1158 struct vpfe_subdev_info *sdinfo;
1159 int ret = 0;
1160
1161 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querystd\n");
1162
1163 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1164 sdinfo = vpfe_dev->current_subdev;
1165 if (ret)
1166 return ret;
1167 /* Call querystd function of decoder device */
1168 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1169 video, querystd, std_id);
1170 mutex_unlock(&vpfe_dev->lock);
1171 return ret;
1172}
1173
1174static int vpfe_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1175{
1176 struct vpfe_device *vpfe_dev = video_drvdata(file);
1177 struct vpfe_subdev_info *sdinfo;
1178 int ret = 0;
1179
1180 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_std\n");
1181
1182 /* Call decoder driver function to set the standard */
1183 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1184 if (ret)
1185 return ret;
1186
1187 sdinfo = vpfe_dev->current_subdev;
1188 /* If streaming is started, return device busy error */
1189 if (vpfe_dev->started) {
1190 v4l2_err(&vpfe_dev->v4l2_dev, "streaming is started\n");
1191 ret = -EBUSY;
1192 goto unlock_out;
1193 }
1194
1195 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1196 core, s_std, *std_id);
1197 if (ret < 0) {
1198 v4l2_err(&vpfe_dev->v4l2_dev, "Failed to set standard\n");
1199 goto unlock_out;
1200 }
1201 ret = vpfe_config_image_format(vpfe_dev, std_id);
1202
1203unlock_out:
1204 mutex_unlock(&vpfe_dev->lock);
1205 return ret;
1206}
1207
1208static int vpfe_g_std(struct file *file, void *priv, v4l2_std_id *std_id)
1209{
1210 struct vpfe_device *vpfe_dev = video_drvdata(file);
1211
1212 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_std\n");
1213
1214 *std_id = vpfe_standards[vpfe_dev->std_index].std_id;
1215 return 0;
1216}
1217/*
1218 * Videobuf operations
1219 */
1220static int vpfe_videobuf_setup(struct videobuf_queue *vq,
1221 unsigned int *count,
1222 unsigned int *size)
1223{
1224 struct vpfe_fh *fh = vq->priv_data;
1225 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1226
1227 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_setup\n");
1228 *size = config_params.device_bufsize;
1229
1230 if (*count < config_params.min_numbuffers)
1231 *count = config_params.min_numbuffers;
1232 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1233 "count=%d, size=%d\n", *count, *size);
1234 return 0;
1235}
1236
1237static int vpfe_videobuf_prepare(struct videobuf_queue *vq,
1238 struct videobuf_buffer *vb,
1239 enum v4l2_field field)
1240{
1241 struct vpfe_fh *fh = vq->priv_data;
1242 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1243
1244 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_prepare\n");
1245
1246 /* If buffer is not initialized, initialize it */
1247 if (VIDEOBUF_NEEDS_INIT == vb->state) {
1248 vb->width = vpfe_dev->fmt.fmt.pix.width;
1249 vb->height = vpfe_dev->fmt.fmt.pix.height;
1250 vb->size = vpfe_dev->fmt.fmt.pix.sizeimage;
1251 vb->field = field;
1252 }
1253 vb->state = VIDEOBUF_PREPARED;
1254 return 0;
1255}
1256
1257static void vpfe_videobuf_queue(struct videobuf_queue *vq,
1258 struct videobuf_buffer *vb)
1259{
1260 /* Get the file handle object and device object */
1261 struct vpfe_fh *fh = vq->priv_data;
1262 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1263 unsigned long flags;
1264
1265 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_buffer_queue\n");
1266
1267 /* add the buffer to the DMA queue */
1268 spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
1269 list_add_tail(&vb->queue, &vpfe_dev->dma_queue);
1270 spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
1271
1272 /* Change state of the buffer */
1273 vb->state = VIDEOBUF_QUEUED;
1274}
1275
1276static void vpfe_videobuf_release(struct videobuf_queue *vq,
1277 struct videobuf_buffer *vb)
1278{
1279 struct vpfe_fh *fh = vq->priv_data;
1280 struct vpfe_device *vpfe_dev = fh->vpfe_dev;
1281 unsigned long flags;
1282
1283 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_videobuf_release\n");
1284
1285 /*
1286 * We need to flush the buffer from the dma queue since
1287 * they are de-allocated
1288 */
1289 spin_lock_irqsave(&vpfe_dev->dma_queue_lock, flags);
1290 INIT_LIST_HEAD(&vpfe_dev->dma_queue);
1291 spin_unlock_irqrestore(&vpfe_dev->dma_queue_lock, flags);
1292 videobuf_dma_contig_free(vq, vb);
1293 vb->state = VIDEOBUF_NEEDS_INIT;
1294}
1295
1296static struct videobuf_queue_ops vpfe_videobuf_qops = {
1297 .buf_setup = vpfe_videobuf_setup,
1298 .buf_prepare = vpfe_videobuf_prepare,
1299 .buf_queue = vpfe_videobuf_queue,
1300 .buf_release = vpfe_videobuf_release,
1301};
1302
1303/*
1304 * vpfe_reqbufs. currently support REQBUF only once opening
1305 * the device.
1306 */
1307static int vpfe_reqbufs(struct file *file, void *priv,
1308 struct v4l2_requestbuffers *req_buf)
1309{
1310 struct vpfe_device *vpfe_dev = video_drvdata(file);
1311 struct vpfe_fh *fh = file->private_data;
1312 int ret = 0;
1313
1314 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs\n");
1315
1316 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != req_buf->type) {
1317 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buffer type\n");
1318 return -EINVAL;
1319 }
1320
1321 if (V4L2_MEMORY_USERPTR == req_buf->memory) {
1322 /* we don't support user ptr IO */
1323 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_reqbufs:"
1324 " USERPTR IO not supported\n");
1325 return -EINVAL;
1326 }
1327
1328 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1329 if (ret)
1330 return ret;
1331
1332 if (vpfe_dev->io_usrs != 0) {
1333 v4l2_err(&vpfe_dev->v4l2_dev, "Only one IO user allowed\n");
1334 ret = -EBUSY;
1335 goto unlock_out;
1336 }
1337
1338 vpfe_dev->memory = req_buf->memory;
1339 videobuf_queue_dma_contig_init(&vpfe_dev->buffer_queue,
1340 &vpfe_videobuf_qops,
1341 NULL,
1342 &vpfe_dev->irqlock,
1343 req_buf->type,
1344 vpfe_dev->fmt.fmt.pix.field,
1345 sizeof(struct videobuf_buffer),
1346 fh);
1347
1348 fh->io_allowed = 1;
1349 vpfe_dev->io_usrs = 1;
1350 INIT_LIST_HEAD(&vpfe_dev->dma_queue);
1351 ret = videobuf_reqbufs(&vpfe_dev->buffer_queue, req_buf);
1352unlock_out:
1353 mutex_unlock(&vpfe_dev->lock);
1354 return ret;
1355}
1356
1357static int vpfe_querybuf(struct file *file, void *priv,
1358 struct v4l2_buffer *buf)
1359{
1360 struct vpfe_device *vpfe_dev = video_drvdata(file);
1361
1362 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_querybuf\n");
1363
1364 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
1365 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1366 return -EINVAL;
1367 }
1368
1369 if (vpfe_dev->memory != V4L2_MEMORY_MMAP) {
1370 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid memory\n");
1371 return -EINVAL;
1372 }
1373 /* Call videobuf_querybuf to get information */
1374 return videobuf_querybuf(&vpfe_dev->buffer_queue, buf);
1375}
1376
1377static int vpfe_qbuf(struct file *file, void *priv,
1378 struct v4l2_buffer *p)
1379{
1380 struct vpfe_device *vpfe_dev = video_drvdata(file);
1381 struct vpfe_fh *fh = file->private_data;
1382
1383 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_qbuf\n");
1384
1385 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != p->type) {
1386 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1387 return -EINVAL;
1388 }
1389
1390 /*
1391 * If this file handle is not allowed to do IO,
1392 * return error
1393 */
1394 if (!fh->io_allowed) {
1395 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1396 return -EACCES;
1397 }
1398 return videobuf_qbuf(&vpfe_dev->buffer_queue, p);
1399}
1400
1401static int vpfe_dqbuf(struct file *file, void *priv,
1402 struct v4l2_buffer *buf)
1403{
1404 struct vpfe_device *vpfe_dev = video_drvdata(file);
1405
1406 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_dqbuf\n");
1407
1408 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf->type) {
1409 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1410 return -EINVAL;
1411 }
1412 return videobuf_dqbuf(&vpfe_dev->buffer_queue,
1413 buf, file->f_flags & O_NONBLOCK);
1414}
1415
1416/*
1417 * vpfe_calculate_offsets : This function calculates buffers offset
1418 * for top and bottom field
1419 */
1420static void vpfe_calculate_offsets(struct vpfe_device *vpfe_dev)
1421{
1422 struct v4l2_rect image_win;
1423
1424 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_calculate_offsets\n");
1425
1426 ccdc_dev->hw_ops.get_image_window(&image_win);
1427 vpfe_dev->field_off = image_win.height * image_win.width;
1428}
1429
1430/* vpfe_start_ccdc_capture: start streaming in ccdc/isif */
1431static void vpfe_start_ccdc_capture(struct vpfe_device *vpfe_dev)
1432{
1433 ccdc_dev->hw_ops.enable(1);
1434 if (ccdc_dev->hw_ops.enable_out_to_sdram)
1435 ccdc_dev->hw_ops.enable_out_to_sdram(1);
1436 vpfe_dev->started = 1;
1437}
1438
1439/*
1440 * vpfe_streamon. Assume the DMA queue is not empty.
1441 * application is expected to call QBUF before calling
1442 * this ioctl. If not, driver returns error
1443 */
1444static int vpfe_streamon(struct file *file, void *priv,
1445 enum v4l2_buf_type buf_type)
1446{
1447 struct vpfe_device *vpfe_dev = video_drvdata(file);
1448 struct vpfe_fh *fh = file->private_data;
1449 struct vpfe_subdev_info *sdinfo;
1450 unsigned long addr;
1451 int ret = 0;
1452
1453 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamon\n");
1454
1455 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
1456 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1457 return -EINVAL;
1458 }
1459
1460 /* If file handle is not allowed IO, return error */
1461 if (!fh->io_allowed) {
1462 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1463 return -EACCES;
1464 }
1465
1466 sdinfo = vpfe_dev->current_subdev;
1467 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1468 video, s_stream, 1);
1469
1470 if (ret && (ret != -ENOIOCTLCMD)) {
1471 v4l2_err(&vpfe_dev->v4l2_dev, "stream on failed in subdev\n");
1472 return -EINVAL;
1473 }
1474
1475 /* If buffer queue is empty, return error */
1476 if (list_empty(&vpfe_dev->buffer_queue.stream)) {
1477 v4l2_err(&vpfe_dev->v4l2_dev, "buffer queue is empty\n");
1478 return -EIO;
1479 }
1480
1481 /* Call videobuf_streamon to start streaming * in videobuf */
1482 ret = videobuf_streamon(&vpfe_dev->buffer_queue);
1483 if (ret)
1484 return ret;
1485
1486
1487 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1488 if (ret)
1489 goto streamoff;
1490 /* Get the next frame from the buffer queue */
1491 vpfe_dev->next_frm = list_entry(vpfe_dev->dma_queue.next,
1492 struct videobuf_buffer, queue);
1493 vpfe_dev->cur_frm = vpfe_dev->next_frm;
1494 /* Remove buffer from the buffer queue */
1495 list_del(&vpfe_dev->cur_frm->queue);
1496 /* Mark state of the current frame to active */
1497 vpfe_dev->cur_frm->state = VIDEOBUF_ACTIVE;
1498 /* Initialize field_id and started member */
1499 vpfe_dev->field_id = 0;
1500 addr = videobuf_to_dma_contig(vpfe_dev->cur_frm);
1501
1502 /* Calculate field offset */
1503 vpfe_calculate_offsets(vpfe_dev);
1504
1505 if (vpfe_attach_irq(vpfe_dev) < 0) {
1506 v4l2_err(&vpfe_dev->v4l2_dev,
1507 "Error in attaching interrupt handle\n");
1508 ret = -EFAULT;
1509 goto unlock_out;
1510 }
1511 if (ccdc_dev->hw_ops.configure() < 0) {
1512 v4l2_err(&vpfe_dev->v4l2_dev,
1513 "Error in configuring ccdc\n");
1514 ret = -EINVAL;
1515 goto unlock_out;
1516 }
1517 ccdc_dev->hw_ops.setfbaddr((unsigned long)(addr));
1518 vpfe_start_ccdc_capture(vpfe_dev);
1519 mutex_unlock(&vpfe_dev->lock);
1520 return ret;
1521unlock_out:
1522 mutex_unlock(&vpfe_dev->lock);
1523streamoff:
1524 ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
1525 return ret;
1526}
1527
1528static int vpfe_streamoff(struct file *file, void *priv,
1529 enum v4l2_buf_type buf_type)
1530{
1531 struct vpfe_device *vpfe_dev = video_drvdata(file);
1532 struct vpfe_fh *fh = file->private_data;
1533 struct vpfe_subdev_info *sdinfo;
1534 int ret = 0;
1535
1536 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_streamoff\n");
1537
1538 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != buf_type) {
1539 v4l2_err(&vpfe_dev->v4l2_dev, "Invalid buf type\n");
1540 return -EINVAL;
1541 }
1542
1543 /* If io is allowed for this file handle, return error */
1544 if (!fh->io_allowed) {
1545 v4l2_err(&vpfe_dev->v4l2_dev, "fh->io_allowed\n");
1546 return -EACCES;
1547 }
1548
1549 /* If streaming is not started, return error */
1550 if (!vpfe_dev->started) {
1551 v4l2_err(&vpfe_dev->v4l2_dev, "device started\n");
1552 return -EINVAL;
1553 }
1554
1555 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1556 if (ret)
1557 return ret;
1558
1559 vpfe_stop_ccdc_capture(vpfe_dev);
1560 vpfe_detach_irq(vpfe_dev);
1561
1562 sdinfo = vpfe_dev->current_subdev;
1563 ret = v4l2_device_call_until_err(&vpfe_dev->v4l2_dev, sdinfo->grp_id,
1564 video, s_stream, 0);
1565
1566 if (ret && (ret != -ENOIOCTLCMD))
1567 v4l2_err(&vpfe_dev->v4l2_dev, "stream off failed in subdev\n");
1568 ret = videobuf_streamoff(&vpfe_dev->buffer_queue);
1569 mutex_unlock(&vpfe_dev->lock);
1570 return ret;
1571}
1572
1573static int vpfe_cropcap(struct file *file, void *priv,
1574 struct v4l2_cropcap *crop)
1575{
1576 struct vpfe_device *vpfe_dev = video_drvdata(file);
1577
1578 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_cropcap\n");
1579
1580 if (vpfe_dev->std_index > ARRAY_SIZE(vpfe_standards))
1581 return -EINVAL;
1582
1583 memset(crop, 0, sizeof(struct v4l2_cropcap));
1584 crop->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1585 crop->bounds.width = crop->defrect.width =
1586 vpfe_standards[vpfe_dev->std_index].width;
1587 crop->bounds.height = crop->defrect.height =
1588 vpfe_standards[vpfe_dev->std_index].height;
1589 crop->pixelaspect = vpfe_standards[vpfe_dev->std_index].pixelaspect;
1590 return 0;
1591}
1592
1593static int vpfe_g_crop(struct file *file, void *priv,
1594 struct v4l2_crop *crop)
1595{
1596 struct vpfe_device *vpfe_dev = video_drvdata(file);
1597
1598 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_crop\n");
1599
1600 crop->c = vpfe_dev->crop;
1601 return 0;
1602}
1603
1604static int vpfe_s_crop(struct file *file, void *priv,
1605 struct v4l2_crop *crop)
1606{
1607 struct vpfe_device *vpfe_dev = video_drvdata(file);
1608 int ret = 0;
1609
1610 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_s_crop\n");
1611
1612 if (vpfe_dev->started) {
1613 /* make sure streaming is not started */
1614 v4l2_err(&vpfe_dev->v4l2_dev,
1615 "Cannot change crop when streaming is ON\n");
1616 return -EBUSY;
1617 }
1618
1619 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1620 if (ret)
1621 return ret;
1622
1623 if (crop->c.top < 0 || crop->c.left < 0) {
1624 v4l2_err(&vpfe_dev->v4l2_dev,
1625 "doesn't support negative values for top & left\n");
1626 ret = -EINVAL;
1627 goto unlock_out;
1628 }
1629
1630 /* adjust the width to 16 pixel boundry */
1631 crop->c.width = ((crop->c.width + 15) & ~0xf);
1632
1633 /* make sure parameters are valid */
1634 if ((crop->c.left + crop->c.width >
1635 vpfe_dev->std_info.active_pixels) ||
1636 (crop->c.top + crop->c.height >
1637 vpfe_dev->std_info.active_lines)) {
1638 v4l2_err(&vpfe_dev->v4l2_dev, "Error in S_CROP params\n");
1639 ret = -EINVAL;
1640 goto unlock_out;
1641 }
1642 ccdc_dev->hw_ops.set_image_window(&crop->c);
1643 vpfe_dev->fmt.fmt.pix.width = crop->c.width;
1644 vpfe_dev->fmt.fmt.pix.height = crop->c.height;
1645 vpfe_dev->fmt.fmt.pix.bytesperline =
1646 ccdc_dev->hw_ops.get_line_length();
1647 vpfe_dev->fmt.fmt.pix.sizeimage =
1648 vpfe_dev->fmt.fmt.pix.bytesperline *
1649 vpfe_dev->fmt.fmt.pix.height;
1650 vpfe_dev->crop = crop->c;
1651unlock_out:
1652 mutex_unlock(&vpfe_dev->lock);
1653 return ret;
1654}
1655
1656
1657static long vpfe_param_handler(struct file *file, void *priv,
1658 int cmd, void *param)
1659{
1660 struct vpfe_device *vpfe_dev = video_drvdata(file);
1661 int ret = 0;
1662
1663 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_param_handler\n");
1664
1665 if (vpfe_dev->started) {
1666 /* only allowed if streaming is not started */
1667 v4l2_err(&vpfe_dev->v4l2_dev, "device already started\n");
1668 return -EBUSY;
1669 }
1670
1671 ret = mutex_lock_interruptible(&vpfe_dev->lock);
1672 if (ret)
1673 return ret;
1674
1675 switch (cmd) {
1676 case VPFE_CMD_S_CCDC_RAW_PARAMS:
1677 v4l2_warn(&vpfe_dev->v4l2_dev,
1678 "VPFE_CMD_S_CCDC_RAW_PARAMS: experimental ioctl\n");
1679 ret = ccdc_dev->hw_ops.set_params(param);
1680 if (ret) {
1681 v4l2_err(&vpfe_dev->v4l2_dev,
1682 "Error in setting parameters in CCDC\n");
1683 goto unlock_out;
1684 }
1685 if (vpfe_get_ccdc_image_format(vpfe_dev, &vpfe_dev->fmt) < 0) {
1686 v4l2_err(&vpfe_dev->v4l2_dev,
1687 "Invalid image format at CCDC\n");
1688 goto unlock_out;
1689 }
1690 break;
1691 default:
1692 ret = -EINVAL;
1693 }
1694unlock_out:
1695 mutex_unlock(&vpfe_dev->lock);
1696 return ret;
1697}
1698
1699
1700/* vpfe capture ioctl operations */
1701static const struct v4l2_ioctl_ops vpfe_ioctl_ops = {
1702 .vidioc_querycap = vpfe_querycap,
1703 .vidioc_g_fmt_vid_cap = vpfe_g_fmt_vid_cap,
1704 .vidioc_enum_fmt_vid_cap = vpfe_enum_fmt_vid_cap,
1705 .vidioc_s_fmt_vid_cap = vpfe_s_fmt_vid_cap,
1706 .vidioc_try_fmt_vid_cap = vpfe_try_fmt_vid_cap,
1707 .vidioc_enum_input = vpfe_enum_input,
1708 .vidioc_g_input = vpfe_g_input,
1709 .vidioc_s_input = vpfe_s_input,
1710 .vidioc_querystd = vpfe_querystd,
1711 .vidioc_s_std = vpfe_s_std,
1712 .vidioc_g_std = vpfe_g_std,
1713 .vidioc_reqbufs = vpfe_reqbufs,
1714 .vidioc_querybuf = vpfe_querybuf,
1715 .vidioc_qbuf = vpfe_qbuf,
1716 .vidioc_dqbuf = vpfe_dqbuf,
1717 .vidioc_streamon = vpfe_streamon,
1718 .vidioc_streamoff = vpfe_streamoff,
1719 .vidioc_cropcap = vpfe_cropcap,
1720 .vidioc_g_crop = vpfe_g_crop,
1721 .vidioc_s_crop = vpfe_s_crop,
1722 .vidioc_default = vpfe_param_handler,
1723};
1724
1725static struct vpfe_device *vpfe_initialize(void)
1726{
1727 struct vpfe_device *vpfe_dev;
1728
1729 /* Default number of buffers should be 3 */
1730 if ((numbuffers > 0) &&
1731 (numbuffers < config_params.min_numbuffers))
1732 numbuffers = config_params.min_numbuffers;
1733
1734 /*
1735 * Set buffer size to min buffers size if invalid buffer size is
1736 * given
1737 */
1738 if (bufsize < config_params.min_bufsize)
1739 bufsize = config_params.min_bufsize;
1740
1741 config_params.numbuffers = numbuffers;
1742
1743 if (numbuffers)
1744 config_params.device_bufsize = bufsize;
1745
1746 /* Allocate memory for device objects */
1747 vpfe_dev = kzalloc(sizeof(*vpfe_dev), GFP_KERNEL);
1748
1749 return vpfe_dev;
1750}
1751
1752static void vpfe_disable_clock(struct vpfe_device *vpfe_dev)
1753{
1754 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1755
1756 clk_disable(vpfe_cfg->vpssclk);
1757 clk_put(vpfe_cfg->vpssclk);
1758 clk_disable(vpfe_cfg->slaveclk);
1759 clk_put(vpfe_cfg->slaveclk);
1760 v4l2_info(vpfe_dev->pdev->driver,
1761 "vpfe vpss master & slave clocks disabled\n");
1762}
1763
1764static int vpfe_enable_clock(struct vpfe_device *vpfe_dev)
1765{
1766 struct vpfe_config *vpfe_cfg = vpfe_dev->cfg;
1767 int ret = -ENOENT;
1768
1769 vpfe_cfg->vpssclk = clk_get(vpfe_dev->pdev, "vpss_master");
1770 if (NULL == vpfe_cfg->vpssclk) {
1771 v4l2_err(vpfe_dev->pdev->driver, "No clock defined for"
1772 "vpss_master\n");
1773 return ret;
1774 }
1775
1776 if (clk_enable(vpfe_cfg->vpssclk)) {
1777 v4l2_err(vpfe_dev->pdev->driver,
1778 "vpfe vpss master clock not enabled\n");
1779 goto out;
1780 }
1781 v4l2_info(vpfe_dev->pdev->driver,
1782 "vpfe vpss master clock enabled\n");
1783
1784 vpfe_cfg->slaveclk = clk_get(vpfe_dev->pdev, "vpss_slave");
1785 if (NULL == vpfe_cfg->slaveclk) {
1786 v4l2_err(vpfe_dev->pdev->driver,
1787 "No clock defined for vpss slave\n");
1788 goto out;
1789 }
1790
1791 if (clk_enable(vpfe_cfg->slaveclk)) {
1792 v4l2_err(vpfe_dev->pdev->driver,
1793 "vpfe vpss slave clock not enabled\n");
1794 goto out;
1795 }
1796 v4l2_info(vpfe_dev->pdev->driver, "vpfe vpss slave clock enabled\n");
1797 return 0;
1798out:
1799 if (vpfe_cfg->vpssclk)
1800 clk_put(vpfe_cfg->vpssclk);
1801 if (vpfe_cfg->slaveclk)
1802 clk_put(vpfe_cfg->slaveclk);
1803
1804 return -1;
1805}
1806
1807/*
1808 * vpfe_probe : This function creates device entries by register
1809 * itself to the V4L2 driver and initializes fields of each
1810 * device objects
1811 */
1812static __init int vpfe_probe(struct platform_device *pdev)
1813{
1814 struct vpfe_subdev_info *sdinfo;
1815 struct vpfe_config *vpfe_cfg;
1816 struct resource *res1;
1817 struct vpfe_device *vpfe_dev;
1818 struct i2c_adapter *i2c_adap;
1819 struct video_device *vfd;
1820 int ret = -ENOMEM, i, j;
1821 int num_subdevs = 0;
1822
1823 /* Get the pointer to the device object */
1824 vpfe_dev = vpfe_initialize();
1825
1826 if (!vpfe_dev) {
1827 v4l2_err(pdev->dev.driver,
1828 "Failed to allocate memory for vpfe_dev\n");
1829 return ret;
1830 }
1831
1832 vpfe_dev->pdev = &pdev->dev;
1833
1834 if (NULL == pdev->dev.platform_data) {
1835 v4l2_err(pdev->dev.driver, "Unable to get vpfe config\n");
1836 ret = -ENOENT;
1837 goto probe_free_dev_mem;
1838 }
1839
1840 vpfe_cfg = pdev->dev.platform_data;
1841 vpfe_dev->cfg = vpfe_cfg;
1842 if (NULL == vpfe_cfg->ccdc ||
1843 NULL == vpfe_cfg->card_name ||
1844 NULL == vpfe_cfg->sub_devs) {
1845 v4l2_err(pdev->dev.driver, "null ptr in vpfe_cfg\n");
1846 ret = -ENOENT;
1847 goto probe_free_dev_mem;
1848 }
1849
1850 /* enable vpss clocks */
1851 ret = vpfe_enable_clock(vpfe_dev);
1852 if (ret)
1853 goto probe_free_dev_mem;
1854
1855 mutex_lock(&ccdc_lock);
1856 /* Allocate memory for ccdc configuration */
1857 ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
1858 if (NULL == ccdc_cfg) {
1859 v4l2_err(pdev->dev.driver,
1860 "Memory allocation failed for ccdc_cfg\n");
1861 goto probe_disable_clock;
1862 }
1863
1864 strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
1865 /* Get VINT0 irq resource */
1866 res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1867 if (!res1) {
1868 v4l2_err(pdev->dev.driver,
1869 "Unable to get interrupt for VINT0\n");
1870 ret = -ENOENT;
1871 goto probe_disable_clock;
1872 }
1873 vpfe_dev->ccdc_irq0 = res1->start;
1874
1875 /* Get VINT1 irq resource */
1876 res1 = platform_get_resource(pdev,
1877 IORESOURCE_IRQ, 1);
1878 if (!res1) {
1879 v4l2_err(pdev->dev.driver,
1880 "Unable to get interrupt for VINT1\n");
1881 ret = -ENOENT;
1882 goto probe_disable_clock;
1883 }
1884 vpfe_dev->ccdc_irq1 = res1->start;
1885
1886 /* Get address base of CCDC */
1887 res1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1888 if (!res1) {
1889 v4l2_err(pdev->dev.driver,
1890 "Unable to get register address map\n");
1891 ret = -ENOENT;
1892 goto probe_disable_clock;
1893 }
1894
1895 ccdc_cfg->ccdc_addr_size = res1->end - res1->start + 1;
1896 if (!request_mem_region(res1->start, ccdc_cfg->ccdc_addr_size,
1897 pdev->dev.driver->name)) {
1898 v4l2_err(pdev->dev.driver,
1899 "Failed request_mem_region for ccdc base\n");
1900 ret = -ENXIO;
1901 goto probe_disable_clock;
1902 }
1903 ccdc_cfg->ccdc_addr = ioremap_nocache(res1->start,
1904 ccdc_cfg->ccdc_addr_size);
1905 if (!ccdc_cfg->ccdc_addr) {
1906 v4l2_err(pdev->dev.driver, "Unable to ioremap ccdc addr\n");
1907 ret = -ENXIO;
1908 goto probe_out_release_mem1;
1909 }
1910
1911 ret = request_irq(vpfe_dev->ccdc_irq0, vpfe_isr, IRQF_DISABLED,
1912 "vpfe_capture0", vpfe_dev);
1913
1914 if (0 != ret) {
1915 v4l2_err(pdev->dev.driver, "Unable to request interrupt\n");
1916 goto probe_out_unmap1;
1917 }
1918
1919 /* Allocate memory for video device */
1920 vfd = video_device_alloc();
1921 if (NULL == vfd) {
1922 ret = -ENOMEM;
1923 v4l2_err(pdev->dev.driver,
1924 "Unable to alloc video device\n");
1925 goto probe_out_release_irq;
1926 }
1927
1928 /* Initialize field of video device */
1929 vfd->release = video_device_release;
1930 vfd->fops = &vpfe_fops;
1931 vfd->ioctl_ops = &vpfe_ioctl_ops;
1932 vfd->minor = -1;
1933 vfd->tvnorms = 0;
1934 vfd->current_norm = V4L2_STD_PAL;
1935 vfd->v4l2_dev = &vpfe_dev->v4l2_dev;
1936 snprintf(vfd->name, sizeof(vfd->name),
1937 "%s_V%d.%d.%d",
1938 CAPTURE_DRV_NAME,
1939 (VPFE_CAPTURE_VERSION_CODE >> 16) & 0xff,
1940 (VPFE_CAPTURE_VERSION_CODE >> 8) & 0xff,
1941 (VPFE_CAPTURE_VERSION_CODE) & 0xff);
1942 /* Set video_dev to the video device */
1943 vpfe_dev->video_dev = vfd;
1944
1945 ret = v4l2_device_register(&pdev->dev, &vpfe_dev->v4l2_dev);
1946 if (ret) {
1947 v4l2_err(pdev->dev.driver,
1948 "Unable to register v4l2 device.\n");
1949 goto probe_out_video_release;
1950 }
1951 v4l2_info(&vpfe_dev->v4l2_dev, "v4l2 device registered\n");
1952 spin_lock_init(&vpfe_dev->irqlock);
1953 spin_lock_init(&vpfe_dev->dma_queue_lock);
1954 mutex_init(&vpfe_dev->lock);
1955
1956 /* Initialize field of the device objects */
1957 vpfe_dev->numbuffers = config_params.numbuffers;
1958
1959 /* Initialize prio member of device object */
1960 v4l2_prio_init(&vpfe_dev->prio);
1961 /* register video device */
1962 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1963 "trying to register vpfe device.\n");
1964 v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev,
1965 "video_dev=%x\n", (int)&vpfe_dev->video_dev);
1966 vpfe_dev->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1967 ret = video_register_device(vpfe_dev->video_dev,
1968 VFL_TYPE_GRABBER, -1);
1969
1970 if (ret) {
1971 v4l2_err(pdev->dev.driver,
1972 "Unable to register video device.\n");
1973 goto probe_out_v4l2_unregister;
1974 }
1975
1976 v4l2_info(&vpfe_dev->v4l2_dev, "video device registered\n");
1977 /* set the driver data in platform device */
1978 platform_set_drvdata(pdev, vpfe_dev);
1979 /* set driver private data */
1980 video_set_drvdata(vpfe_dev->video_dev, vpfe_dev);
1981 i2c_adap = i2c_get_adapter(1);
1982 vpfe_cfg = pdev->dev.platform_data;
1983 num_subdevs = vpfe_cfg->num_subdevs;
1984 vpfe_dev->sd = kmalloc(sizeof(struct v4l2_subdev *) * num_subdevs,
1985 GFP_KERNEL);
1986 if (NULL == vpfe_dev->sd) {
1987 v4l2_err(&vpfe_dev->v4l2_dev,
1988 "unable to allocate memory for subdevice pointers\n");
1989 ret = -ENOMEM;
1990 goto probe_out_video_unregister;
1991 }
1992
1993 for (i = 0; i < num_subdevs; i++) {
1994 struct v4l2_input *inps;
1995
1996 sdinfo = &vpfe_cfg->sub_devs[i];
1997
1998 /* Load up the subdevice */
1999 vpfe_dev->sd[i] =
2000 v4l2_i2c_new_subdev_board(&vpfe_dev->v4l2_dev,
2001 i2c_adap,
2002 sdinfo->name,
2003 &sdinfo->board_info,
2004 NULL);
2005 if (vpfe_dev->sd[i]) {
2006 v4l2_info(&vpfe_dev->v4l2_dev,
2007 "v4l2 sub device %s registered\n",
2008 sdinfo->name);
2009 vpfe_dev->sd[i]->grp_id = sdinfo->grp_id;
2010 /* update tvnorms from the sub devices */
2011 for (j = 0; j < sdinfo->num_inputs; j++) {
2012 inps = &sdinfo->inputs[j];
2013 vfd->tvnorms |= inps->std;
2014 }
2015 } else {
2016 v4l2_info(&vpfe_dev->v4l2_dev,
2017 "v4l2 sub device %s register fails\n",
2018 sdinfo->name);
2019 goto probe_sd_out;
2020 }
2021 }
2022
2023 /* set first sub device as current one */
2024 vpfe_dev->current_subdev = &vpfe_cfg->sub_devs[0];
2025
2026 /* We have at least one sub device to work with */
2027 mutex_unlock(&ccdc_lock);
2028 return 0;
2029
2030probe_sd_out:
2031 kfree(vpfe_dev->sd);
2032probe_out_video_unregister:
2033 video_unregister_device(vpfe_dev->video_dev);
2034probe_out_v4l2_unregister:
2035 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2036probe_out_video_release:
2037 if (vpfe_dev->video_dev->minor == -1)
2038 video_device_release(vpfe_dev->video_dev);
2039probe_out_release_irq:
2040 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2041probe_out_unmap1:
2042 iounmap(ccdc_cfg->ccdc_addr);
2043probe_out_release_mem1:
2044 release_mem_region(res1->start, res1->end - res1->start + 1);
2045probe_disable_clock:
2046 vpfe_disable_clock(vpfe_dev);
2047 mutex_unlock(&ccdc_lock);
2048 kfree(ccdc_cfg);
2049probe_free_dev_mem:
2050 kfree(vpfe_dev);
2051 return ret;
2052}
2053
2054/*
2055 * vpfe_remove : It un-register device from V4L2 driver
2056 */
2057static int vpfe_remove(struct platform_device *pdev)
2058{
2059 struct vpfe_device *vpfe_dev = platform_get_drvdata(pdev);
2060 struct resource *res;
2061
2062 v4l2_info(pdev->dev.driver, "vpfe_remove\n");
2063
2064 free_irq(vpfe_dev->ccdc_irq0, vpfe_dev);
2065 kfree(vpfe_dev->sd);
2066 v4l2_device_unregister(&vpfe_dev->v4l2_dev);
2067 video_unregister_device(vpfe_dev->video_dev);
2068 mutex_lock(&ccdc_lock);
2069 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
2070 release_mem_region(res->start, res->end - res->start + 1);
2071 iounmap(ccdc_cfg->ccdc_addr);
2072 mutex_unlock(&ccdc_lock);
2073 vpfe_disable_clock(vpfe_dev);
2074 kfree(vpfe_dev);
2075 kfree(ccdc_cfg);
2076 return 0;
2077}
2078
2079static int
2080vpfe_suspend(struct device *dev)
2081{
2082 /* add suspend code here later */
2083 return -1;
2084}
2085
2086static int
2087vpfe_resume(struct device *dev)
2088{
2089 /* add resume code here later */
2090 return -1;
2091}
2092
2093static struct dev_pm_ops vpfe_dev_pm_ops = {
2094 .suspend = vpfe_suspend,
2095 .resume = vpfe_resume,
2096};
2097
2098static struct platform_driver vpfe_driver = {
2099 .driver = {
2100 .name = CAPTURE_DRV_NAME,
2101 .owner = THIS_MODULE,
2102 .pm = &vpfe_dev_pm_ops,
2103 },
2104 .probe = vpfe_probe,
2105 .remove = __devexit_p(vpfe_remove),
2106};
2107
2108static __init int vpfe_init(void)
2109{
2110 printk(KERN_NOTICE "vpfe_init\n");
2111 /* Register driver to the kernel */
2112 return platform_driver_register(&vpfe_driver);
2113}
2114
2115/*
2116 * vpfe_cleanup : This function un-registers device driver
2117 */
2118static void vpfe_cleanup(void)
2119{
2120 platform_driver_unregister(&vpfe_driver);
2121}
2122
2123module_init(vpfe_init);
2124module_exit(vpfe_cleanup);
diff --git a/drivers/media/video/davinci/vpif.c b/drivers/media/video/davinci/vpif.c
new file mode 100644
index 000000000000..3b8eac31ecae
--- /dev/null
+++ b/drivers/media/video/davinci/vpif.c
@@ -0,0 +1,296 @@
1/*
2 * vpif - DM646x Video Port Interface driver
3 * VPIF is a receiver and transmitter for video data. It has two channels(0, 1)
4 * that receiveing video byte stream and two channels(2, 3) for video output.
5 * The hardware supports SDTV, HDTV formats, raw data capture.
6 * Currently, the driver supports NTSC and PAL standards.
7 *
8 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation version 2.
13 *
14 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
15 * kind, whether express or implied; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
20#include <linux/init.h>
21#include <linux/module.h>
22#include <linux/platform_device.h>
23#include <linux/spinlock.h>
24#include <linux/kernel.h>
25#include <linux/io.h>
26#include <mach/hardware.h>
27
28#include "vpif.h"
29
30MODULE_DESCRIPTION("TI DaVinci Video Port Interface driver");
31MODULE_LICENSE("GPL");
32
33#define VPIF_CH0_MAX_MODES (22)
34#define VPIF_CH1_MAX_MODES (02)
35#define VPIF_CH2_MAX_MODES (15)
36#define VPIF_CH3_MAX_MODES (02)
37
38static resource_size_t res_len;
39static struct resource *res;
40spinlock_t vpif_lock;
41
42void __iomem *vpif_base;
43
44static inline void vpif_wr_bit(u32 reg, u32 bit, u32 val)
45{
46 if (val)
47 vpif_set_bit(reg, bit);
48 else
49 vpif_clr_bit(reg, bit);
50}
51
52/* This structure is used to keep track of VPIF size register's offsets */
53struct vpif_registers {
54 u32 h_cfg, v_cfg_00, v_cfg_01, v_cfg_02, v_cfg, ch_ctrl;
55 u32 line_offset, vanc0_strt, vanc0_size, vanc1_strt;
56 u32 vanc1_size, width_mask, len_mask;
57 u8 max_modes;
58};
59
60static const struct vpif_registers vpifregs[VPIF_NUM_CHANNELS] = {
61 /* Channel0 */
62 {
63 VPIF_CH0_H_CFG, VPIF_CH0_V_CFG_00, VPIF_CH0_V_CFG_01,
64 VPIF_CH0_V_CFG_02, VPIF_CH0_V_CFG_03, VPIF_CH0_CTRL,
65 VPIF_CH0_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
66 VPIF_CH0_MAX_MODES,
67 },
68 /* Channel1 */
69 {
70 VPIF_CH1_H_CFG, VPIF_CH1_V_CFG_00, VPIF_CH1_V_CFG_01,
71 VPIF_CH1_V_CFG_02, VPIF_CH1_V_CFG_03, VPIF_CH1_CTRL,
72 VPIF_CH1_IMG_ADD_OFST, 0, 0, 0, 0, 0x1FFF, 0xFFF,
73 VPIF_CH1_MAX_MODES,
74 },
75 /* Channel2 */
76 {
77 VPIF_CH2_H_CFG, VPIF_CH2_V_CFG_00, VPIF_CH2_V_CFG_01,
78 VPIF_CH2_V_CFG_02, VPIF_CH2_V_CFG_03, VPIF_CH2_CTRL,
79 VPIF_CH2_IMG_ADD_OFST, VPIF_CH2_VANC0_STRT, VPIF_CH2_VANC0_SIZE,
80 VPIF_CH2_VANC1_STRT, VPIF_CH2_VANC1_SIZE, 0x7FF, 0x7FF,
81 VPIF_CH2_MAX_MODES
82 },
83 /* Channel3 */
84 {
85 VPIF_CH3_H_CFG, VPIF_CH3_V_CFG_00, VPIF_CH3_V_CFG_01,
86 VPIF_CH3_V_CFG_02, VPIF_CH3_V_CFG_03, VPIF_CH3_CTRL,
87 VPIF_CH3_IMG_ADD_OFST, VPIF_CH3_VANC0_STRT, VPIF_CH3_VANC0_SIZE,
88 VPIF_CH3_VANC1_STRT, VPIF_CH3_VANC1_SIZE, 0x7FF, 0x7FF,
89 VPIF_CH3_MAX_MODES
90 },
91};
92
93/* vpif_set_mode_info:
94 * This function is used to set horizontal and vertical config parameters
95 * As per the standard in the channel, configure the values of L1, L3,
96 * L5, L7 L9, L11 in VPIF Register , also write width and height
97 */
98static void vpif_set_mode_info(const struct vpif_channel_config_params *config,
99 u8 channel_id, u8 config_channel_id)
100{
101 u32 value;
102
103 value = (config->eav2sav & vpifregs[config_channel_id].width_mask);
104 value <<= VPIF_CH_LEN_SHIFT;
105 value |= (config->sav2eav & vpifregs[config_channel_id].width_mask);
106 regw(value, vpifregs[channel_id].h_cfg);
107
108 value = (config->l1 & vpifregs[config_channel_id].len_mask);
109 value <<= VPIF_CH_LEN_SHIFT;
110 value |= (config->l3 & vpifregs[config_channel_id].len_mask);
111 regw(value, vpifregs[channel_id].v_cfg_00);
112
113 value = (config->l5 & vpifregs[config_channel_id].len_mask);
114 value <<= VPIF_CH_LEN_SHIFT;
115 value |= (config->l7 & vpifregs[config_channel_id].len_mask);
116 regw(value, vpifregs[channel_id].v_cfg_01);
117
118 value = (config->l9 & vpifregs[config_channel_id].len_mask);
119 value <<= VPIF_CH_LEN_SHIFT;
120 value |= (config->l11 & vpifregs[config_channel_id].len_mask);
121 regw(value, vpifregs[channel_id].v_cfg_02);
122
123 value = (config->vsize & vpifregs[config_channel_id].len_mask);
124 regw(value, vpifregs[channel_id].v_cfg);
125}
126
127/* config_vpif_params
128 * Function to set the parameters of a channel
129 * Mainly modifies the channel ciontrol register
130 * It sets frame format, yc mux mode
131 */
132static void config_vpif_params(struct vpif_params *vpifparams,
133 u8 channel_id, u8 found)
134{
135 const struct vpif_channel_config_params *config = &vpifparams->std_info;
136 u32 value, ch_nip, reg;
137 u8 start, end;
138 int i;
139
140 start = channel_id;
141 end = channel_id + found;
142
143 for (i = start; i < end; i++) {
144 reg = vpifregs[i].ch_ctrl;
145 if (channel_id < 2)
146 ch_nip = VPIF_CAPTURE_CH_NIP;
147 else
148 ch_nip = VPIF_DISPLAY_CH_NIP;
149
150 vpif_wr_bit(reg, ch_nip, config->frm_fmt);
151 vpif_wr_bit(reg, VPIF_CH_YC_MUX_BIT, config->ycmux_mode);
152 vpif_wr_bit(reg, VPIF_CH_INPUT_FIELD_FRAME_BIT,
153 vpifparams->video_params.storage_mode);
154
155 /* Set raster scanning SDR Format */
156 vpif_clr_bit(reg, VPIF_CH_SDR_FMT_BIT);
157 vpif_wr_bit(reg, VPIF_CH_DATA_MODE_BIT, config->capture_format);
158
159 if (channel_id > 1) /* Set the Pixel enable bit */
160 vpif_set_bit(reg, VPIF_DISPLAY_PIX_EN_BIT);
161 else if (config->capture_format) {
162 /* Set the polarity of various pins */
163 vpif_wr_bit(reg, VPIF_CH_FID_POLARITY_BIT,
164 vpifparams->iface.fid_pol);
165 vpif_wr_bit(reg, VPIF_CH_V_VALID_POLARITY_BIT,
166 vpifparams->iface.vd_pol);
167 vpif_wr_bit(reg, VPIF_CH_H_VALID_POLARITY_BIT,
168 vpifparams->iface.hd_pol);
169
170 value = regr(reg);
171 /* Set data width */
172 value &= ((~(unsigned int)(0x3)) <<
173 VPIF_CH_DATA_WIDTH_BIT);
174 value |= ((vpifparams->params.data_sz) <<
175 VPIF_CH_DATA_WIDTH_BIT);
176 regw(value, reg);
177 }
178
179 /* Write the pitch in the driver */
180 regw((vpifparams->video_params.hpitch),
181 vpifregs[i].line_offset);
182 }
183}
184
185/* vpif_set_video_params
186 * This function is used to set video parameters in VPIF register
187 */
188int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id)
189{
190 const struct vpif_channel_config_params *config = &vpifparams->std_info;
191 int found = 1;
192
193 vpif_set_mode_info(config, channel_id, channel_id);
194 if (!config->ycmux_mode) {
195 /* YC are on separate channels (HDTV formats) */
196 vpif_set_mode_info(config, channel_id + 1, channel_id);
197 found = 2;
198 }
199
200 config_vpif_params(vpifparams, channel_id, found);
201
202 regw(0x80, VPIF_REQ_SIZE);
203 regw(0x01, VPIF_EMULATION_CTRL);
204
205 return found;
206}
207EXPORT_SYMBOL(vpif_set_video_params);
208
209void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
210 u8 channel_id)
211{
212 u32 value;
213
214 value = 0x3F8 & (vbiparams->hstart0);
215 value |= 0x3FFFFFF & ((vbiparams->vstart0) << 16);
216 regw(value, vpifregs[channel_id].vanc0_strt);
217
218 value = 0x3F8 & (vbiparams->hstart1);
219 value |= 0x3FFFFFF & ((vbiparams->vstart1) << 16);
220 regw(value, vpifregs[channel_id].vanc1_strt);
221
222 value = 0x3F8 & (vbiparams->hsize0);
223 value |= 0x3FFFFFF & ((vbiparams->vsize0) << 16);
224 regw(value, vpifregs[channel_id].vanc0_size);
225
226 value = 0x3F8 & (vbiparams->hsize1);
227 value |= 0x3FFFFFF & ((vbiparams->vsize1) << 16);
228 regw(value, vpifregs[channel_id].vanc1_size);
229
230}
231EXPORT_SYMBOL(vpif_set_vbi_display_params);
232
233int vpif_channel_getfid(u8 channel_id)
234{
235 return (regr(vpifregs[channel_id].ch_ctrl) & VPIF_CH_FID_MASK)
236 >> VPIF_CH_FID_SHIFT;
237}
238EXPORT_SYMBOL(vpif_channel_getfid);
239
240static int __init vpif_probe(struct platform_device *pdev)
241{
242 int status = 0;
243
244 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
245 if (!res)
246 return -ENOENT;
247
248 res_len = res->end - res->start + 1;
249
250 res = request_mem_region(res->start, res_len, res->name);
251 if (!res)
252 return -EBUSY;
253
254 vpif_base = ioremap(res->start, res_len);
255 if (!vpif_base) {
256 status = -EBUSY;
257 goto fail;
258 }
259
260 spin_lock_init(&vpif_lock);
261 dev_info(&pdev->dev, "vpif probe success\n");
262 return 0;
263
264fail:
265 release_mem_region(res->start, res_len);
266 return status;
267}
268
269static int vpif_remove(struct platform_device *pdev)
270{
271 iounmap(vpif_base);
272 release_mem_region(res->start, res_len);
273 return 0;
274}
275
276static struct platform_driver vpif_driver = {
277 .driver = {
278 .name = "vpif",
279 .owner = THIS_MODULE,
280 },
281 .remove = __devexit_p(vpif_remove),
282 .probe = vpif_probe,
283};
284
285static void vpif_exit(void)
286{
287 platform_driver_unregister(&vpif_driver);
288}
289
290static int __init vpif_init(void)
291{
292 return platform_driver_register(&vpif_driver);
293}
294subsys_initcall(vpif_init);
295module_exit(vpif_exit);
296
diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h
new file mode 100644
index 000000000000..188841b476e0
--- /dev/null
+++ b/drivers/media/video/davinci/vpif.h
@@ -0,0 +1,642 @@
1/*
2 * VPIF header file
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef VPIF_H
17#define VPIF_H
18
19#include <linux/io.h>
20#include <linux/videodev2.h>
21#include <mach/hardware.h>
22#include <mach/dm646x.h>
23
24/* Maximum channel allowed */
25#define VPIF_NUM_CHANNELS (4)
26#define VPIF_CAPTURE_NUM_CHANNELS (2)
27#define VPIF_DISPLAY_NUM_CHANNELS (2)
28
29/* Macros to read/write registers */
30extern void __iomem *vpif_base;
31extern spinlock_t vpif_lock;
32
33#define regr(reg) readl((reg) + vpif_base)
34#define regw(value, reg) writel(value, (reg + vpif_base))
35
36/* Register Addresss Offsets */
37#define VPIF_PID (0x0000)
38#define VPIF_CH0_CTRL (0x0004)
39#define VPIF_CH1_CTRL (0x0008)
40#define VPIF_CH2_CTRL (0x000C)
41#define VPIF_CH3_CTRL (0x0010)
42
43#define VPIF_INTEN (0x0020)
44#define VPIF_INTEN_SET (0x0024)
45#define VPIF_INTEN_CLR (0x0028)
46#define VPIF_STATUS (0x002C)
47#define VPIF_STATUS_CLR (0x0030)
48#define VPIF_EMULATION_CTRL (0x0034)
49#define VPIF_REQ_SIZE (0x0038)
50
51#define VPIF_CH0_TOP_STRT_ADD_LUMA (0x0040)
52#define VPIF_CH0_BTM_STRT_ADD_LUMA (0x0044)
53#define VPIF_CH0_TOP_STRT_ADD_CHROMA (0x0048)
54#define VPIF_CH0_BTM_STRT_ADD_CHROMA (0x004c)
55#define VPIF_CH0_TOP_STRT_ADD_HANC (0x0050)
56#define VPIF_CH0_BTM_STRT_ADD_HANC (0x0054)
57#define VPIF_CH0_TOP_STRT_ADD_VANC (0x0058)
58#define VPIF_CH0_BTM_STRT_ADD_VANC (0x005c)
59#define VPIF_CH0_SP_CFG (0x0060)
60#define VPIF_CH0_IMG_ADD_OFST (0x0064)
61#define VPIF_CH0_HANC_ADD_OFST (0x0068)
62#define VPIF_CH0_H_CFG (0x006c)
63#define VPIF_CH0_V_CFG_00 (0x0070)
64#define VPIF_CH0_V_CFG_01 (0x0074)
65#define VPIF_CH0_V_CFG_02 (0x0078)
66#define VPIF_CH0_V_CFG_03 (0x007c)
67
68#define VPIF_CH1_TOP_STRT_ADD_LUMA (0x0080)
69#define VPIF_CH1_BTM_STRT_ADD_LUMA (0x0084)
70#define VPIF_CH1_TOP_STRT_ADD_CHROMA (0x0088)
71#define VPIF_CH1_BTM_STRT_ADD_CHROMA (0x008c)
72#define VPIF_CH1_TOP_STRT_ADD_HANC (0x0090)
73#define VPIF_CH1_BTM_STRT_ADD_HANC (0x0094)
74#define VPIF_CH1_TOP_STRT_ADD_VANC (0x0098)
75#define VPIF_CH1_BTM_STRT_ADD_VANC (0x009c)
76#define VPIF_CH1_SP_CFG (0x00a0)
77#define VPIF_CH1_IMG_ADD_OFST (0x00a4)
78#define VPIF_CH1_HANC_ADD_OFST (0x00a8)
79#define VPIF_CH1_H_CFG (0x00ac)
80#define VPIF_CH1_V_CFG_00 (0x00b0)
81#define VPIF_CH1_V_CFG_01 (0x00b4)
82#define VPIF_CH1_V_CFG_02 (0x00b8)
83#define VPIF_CH1_V_CFG_03 (0x00bc)
84
85#define VPIF_CH2_TOP_STRT_ADD_LUMA (0x00c0)
86#define VPIF_CH2_BTM_STRT_ADD_LUMA (0x00c4)
87#define VPIF_CH2_TOP_STRT_ADD_CHROMA (0x00c8)
88#define VPIF_CH2_BTM_STRT_ADD_CHROMA (0x00cc)
89#define VPIF_CH2_TOP_STRT_ADD_HANC (0x00d0)
90#define VPIF_CH2_BTM_STRT_ADD_HANC (0x00d4)
91#define VPIF_CH2_TOP_STRT_ADD_VANC (0x00d8)
92#define VPIF_CH2_BTM_STRT_ADD_VANC (0x00dc)
93#define VPIF_CH2_SP_CFG (0x00e0)
94#define VPIF_CH2_IMG_ADD_OFST (0x00e4)
95#define VPIF_CH2_HANC_ADD_OFST (0x00e8)
96#define VPIF_CH2_H_CFG (0x00ec)
97#define VPIF_CH2_V_CFG_00 (0x00f0)
98#define VPIF_CH2_V_CFG_01 (0x00f4)
99#define VPIF_CH2_V_CFG_02 (0x00f8)
100#define VPIF_CH2_V_CFG_03 (0x00fc)
101#define VPIF_CH2_HANC0_STRT (0x0100)
102#define VPIF_CH2_HANC0_SIZE (0x0104)
103#define VPIF_CH2_HANC1_STRT (0x0108)
104#define VPIF_CH2_HANC1_SIZE (0x010c)
105#define VPIF_CH2_VANC0_STRT (0x0110)
106#define VPIF_CH2_VANC0_SIZE (0x0114)
107#define VPIF_CH2_VANC1_STRT (0x0118)
108#define VPIF_CH2_VANC1_SIZE (0x011c)
109
110#define VPIF_CH3_TOP_STRT_ADD_LUMA (0x0140)
111#define VPIF_CH3_BTM_STRT_ADD_LUMA (0x0144)
112#define VPIF_CH3_TOP_STRT_ADD_CHROMA (0x0148)
113#define VPIF_CH3_BTM_STRT_ADD_CHROMA (0x014c)
114#define VPIF_CH3_TOP_STRT_ADD_HANC (0x0150)
115#define VPIF_CH3_BTM_STRT_ADD_HANC (0x0154)
116#define VPIF_CH3_TOP_STRT_ADD_VANC (0x0158)
117#define VPIF_CH3_BTM_STRT_ADD_VANC (0x015c)
118#define VPIF_CH3_SP_CFG (0x0160)
119#define VPIF_CH3_IMG_ADD_OFST (0x0164)
120#define VPIF_CH3_HANC_ADD_OFST (0x0168)
121#define VPIF_CH3_H_CFG (0x016c)
122#define VPIF_CH3_V_CFG_00 (0x0170)
123#define VPIF_CH3_V_CFG_01 (0x0174)
124#define VPIF_CH3_V_CFG_02 (0x0178)
125#define VPIF_CH3_V_CFG_03 (0x017c)
126#define VPIF_CH3_HANC0_STRT (0x0180)
127#define VPIF_CH3_HANC0_SIZE (0x0184)
128#define VPIF_CH3_HANC1_STRT (0x0188)
129#define VPIF_CH3_HANC1_SIZE (0x018c)
130#define VPIF_CH3_VANC0_STRT (0x0190)
131#define VPIF_CH3_VANC0_SIZE (0x0194)
132#define VPIF_CH3_VANC1_STRT (0x0198)
133#define VPIF_CH3_VANC1_SIZE (0x019c)
134
135#define VPIF_IODFT_CTRL (0x01c0)
136
137/* Functions for bit Manipulation */
138static inline void vpif_set_bit(u32 reg, u32 bit)
139{
140 regw((regr(reg)) | (0x01 << bit), reg);
141}
142
143static inline void vpif_clr_bit(u32 reg, u32 bit)
144{
145 regw(((regr(reg)) & ~(0x01 << bit)), reg);
146}
147
148/* Macro for Generating mask */
149#ifdef GENERATE_MASK
150#undef GENERATE_MASK
151#endif
152
153#define GENERATE_MASK(bits, pos) \
154 ((((0xFFFFFFFF) << (32 - bits)) >> (32 - bits)) << pos)
155
156/* Bit positions in the channel control registers */
157#define VPIF_CH_DATA_MODE_BIT (2)
158#define VPIF_CH_YC_MUX_BIT (3)
159#define VPIF_CH_SDR_FMT_BIT (4)
160#define VPIF_CH_HANC_EN_BIT (8)
161#define VPIF_CH_VANC_EN_BIT (9)
162
163#define VPIF_CAPTURE_CH_NIP (10)
164#define VPIF_DISPLAY_CH_NIP (11)
165
166#define VPIF_DISPLAY_PIX_EN_BIT (10)
167
168#define VPIF_CH_INPUT_FIELD_FRAME_BIT (12)
169
170#define VPIF_CH_FID_POLARITY_BIT (15)
171#define VPIF_CH_V_VALID_POLARITY_BIT (14)
172#define VPIF_CH_H_VALID_POLARITY_BIT (13)
173#define VPIF_CH_DATA_WIDTH_BIT (28)
174
175#define VPIF_CH_CLK_EDGE_CTRL_BIT (31)
176
177/* Mask various length */
178#define VPIF_CH_EAVSAV_MASK GENERATE_MASK(13, 0)
179#define VPIF_CH_LEN_MASK GENERATE_MASK(12, 0)
180#define VPIF_CH_WIDTH_MASK GENERATE_MASK(13, 0)
181#define VPIF_CH_LEN_SHIFT (16)
182
183/* VPIF masks for registers */
184#define VPIF_REQ_SIZE_MASK (0x1ff)
185
186/* bit posotion of interrupt vpif_ch_intr register */
187#define VPIF_INTEN_FRAME_CH0 (0x00000001)
188#define VPIF_INTEN_FRAME_CH1 (0x00000002)
189#define VPIF_INTEN_FRAME_CH2 (0x00000004)
190#define VPIF_INTEN_FRAME_CH3 (0x00000008)
191
192/* bit position of clock and channel enable in vpif_chn_ctrl register */
193
194#define VPIF_CH0_CLK_EN (0x00000002)
195#define VPIF_CH0_EN (0x00000001)
196#define VPIF_CH1_CLK_EN (0x00000002)
197#define VPIF_CH1_EN (0x00000001)
198#define VPIF_CH2_CLK_EN (0x00000002)
199#define VPIF_CH2_EN (0x00000001)
200#define VPIF_CH3_CLK_EN (0x00000002)
201#define VPIF_CH3_EN (0x00000001)
202#define VPIF_CH_CLK_EN (0x00000002)
203#define VPIF_CH_EN (0x00000001)
204
205#define VPIF_INT_TOP (0x00)
206#define VPIF_INT_BOTTOM (0x01)
207#define VPIF_INT_BOTH (0x02)
208
209#define VPIF_CH0_INT_CTRL_SHIFT (6)
210#define VPIF_CH1_INT_CTRL_SHIFT (6)
211#define VPIF_CH2_INT_CTRL_SHIFT (6)
212#define VPIF_CH3_INT_CTRL_SHIFT (6)
213#define VPIF_CH_INT_CTRL_SHIFT (6)
214
215/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
216#define channel0_intr_assert() (regw((regr(VPIF_CH0_CTRL)|\
217 (VPIF_INT_BOTH << VPIF_CH0_INT_CTRL_SHIFT)), VPIF_CH0_CTRL))
218
219/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
220#define channel1_intr_assert() (regw((regr(VPIF_CH1_CTRL)|\
221 (VPIF_INT_BOTH << VPIF_CH1_INT_CTRL_SHIFT)), VPIF_CH1_CTRL))
222
223/* enabled interrupt on both the fields on vpid_ch0_ctrl register */
224#define channel2_intr_assert() (regw((regr(VPIF_CH2_CTRL)|\
225 (VPIF_INT_BOTH << VPIF_CH2_INT_CTRL_SHIFT)), VPIF_CH2_CTRL))
226
227/* enabled interrupt on both the fields on vpid_ch1_ctrl register */
228#define channel3_intr_assert() (regw((regr(VPIF_CH3_CTRL)|\
229 (VPIF_INT_BOTH << VPIF_CH3_INT_CTRL_SHIFT)), VPIF_CH3_CTRL))
230
231#define VPIF_CH_FID_MASK (0x20)
232#define VPIF_CH_FID_SHIFT (5)
233
234#define VPIF_NTSC_VBI_START_FIELD0 (1)
235#define VPIF_NTSC_VBI_START_FIELD1 (263)
236#define VPIF_PAL_VBI_START_FIELD0 (624)
237#define VPIF_PAL_VBI_START_FIELD1 (311)
238
239#define VPIF_NTSC_HBI_START_FIELD0 (1)
240#define VPIF_NTSC_HBI_START_FIELD1 (263)
241#define VPIF_PAL_HBI_START_FIELD0 (624)
242#define VPIF_PAL_HBI_START_FIELD1 (311)
243
244#define VPIF_NTSC_VBI_COUNT_FIELD0 (20)
245#define VPIF_NTSC_VBI_COUNT_FIELD1 (19)
246#define VPIF_PAL_VBI_COUNT_FIELD0 (24)
247#define VPIF_PAL_VBI_COUNT_FIELD1 (25)
248
249#define VPIF_NTSC_HBI_COUNT_FIELD0 (263)
250#define VPIF_NTSC_HBI_COUNT_FIELD1 (262)
251#define VPIF_PAL_HBI_COUNT_FIELD0 (312)
252#define VPIF_PAL_HBI_COUNT_FIELD1 (313)
253
254#define VPIF_NTSC_VBI_SAMPLES_PER_LINE (720)
255#define VPIF_PAL_VBI_SAMPLES_PER_LINE (720)
256#define VPIF_NTSC_HBI_SAMPLES_PER_LINE (268)
257#define VPIF_PAL_HBI_SAMPLES_PER_LINE (280)
258
259#define VPIF_CH_VANC_EN (0x20)
260#define VPIF_DMA_REQ_SIZE (0x080)
261#define VPIF_EMULATION_DISABLE (0x01)
262
263extern u8 irq_vpif_capture_channel[VPIF_NUM_CHANNELS];
264
265/* inline function to enable/disable channel0 */
266static inline void enable_channel0(int enable)
267{
268 if (enable)
269 regw((regr(VPIF_CH0_CTRL) | (VPIF_CH0_EN)), VPIF_CH0_CTRL);
270 else
271 regw((regr(VPIF_CH0_CTRL) & (~VPIF_CH0_EN)), VPIF_CH0_CTRL);
272}
273
274/* inline function to enable/disable channel1 */
275static inline void enable_channel1(int enable)
276{
277 if (enable)
278 regw((regr(VPIF_CH1_CTRL) | (VPIF_CH1_EN)), VPIF_CH1_CTRL);
279 else
280 regw((regr(VPIF_CH1_CTRL) & (~VPIF_CH1_EN)), VPIF_CH1_CTRL);
281}
282
283/* inline function to enable interrupt for channel0 */
284static inline void channel0_intr_enable(int enable)
285{
286 unsigned long flags;
287
288 spin_lock_irqsave(&vpif_lock, flags);
289
290 if (enable) {
291 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
292 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
293
294 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH0), VPIF_INTEN);
295 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
296 VPIF_INTEN_SET);
297 } else {
298 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH0)), VPIF_INTEN);
299 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH0),
300 VPIF_INTEN_SET);
301 }
302 spin_unlock_irqrestore(&vpif_lock, flags);
303}
304
305/* inline function to enable interrupt for channel1 */
306static inline void channel1_intr_enable(int enable)
307{
308 unsigned long flags;
309
310 spin_lock_irqsave(&vpif_lock, flags);
311
312 if (enable) {
313 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
314 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
315
316 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH1), VPIF_INTEN);
317 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
318 VPIF_INTEN_SET);
319 } else {
320 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH1)), VPIF_INTEN);
321 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH1),
322 VPIF_INTEN_SET);
323 }
324 spin_unlock_irqrestore(&vpif_lock, flags);
325}
326
327/* inline function to set buffer addresses in case of Y/C non mux mode */
328static inline void ch0_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
329 unsigned long btm_strt_luma,
330 unsigned long top_strt_chroma,
331 unsigned long btm_strt_chroma)
332{
333 regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
334 regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
335 regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
336 regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
337}
338
339/* inline function to set buffer addresses in VPIF registers for video data */
340static inline void ch0_set_videobuf_addr(unsigned long top_strt_luma,
341 unsigned long btm_strt_luma,
342 unsigned long top_strt_chroma,
343 unsigned long btm_strt_chroma)
344{
345 regw(top_strt_luma, VPIF_CH0_TOP_STRT_ADD_LUMA);
346 regw(btm_strt_luma, VPIF_CH0_BTM_STRT_ADD_LUMA);
347 regw(top_strt_chroma, VPIF_CH0_TOP_STRT_ADD_CHROMA);
348 regw(btm_strt_chroma, VPIF_CH0_BTM_STRT_ADD_CHROMA);
349}
350
351static inline void ch1_set_videobuf_addr(unsigned long top_strt_luma,
352 unsigned long btm_strt_luma,
353 unsigned long top_strt_chroma,
354 unsigned long btm_strt_chroma)
355{
356
357 regw(top_strt_luma, VPIF_CH1_TOP_STRT_ADD_LUMA);
358 regw(btm_strt_luma, VPIF_CH1_BTM_STRT_ADD_LUMA);
359 regw(top_strt_chroma, VPIF_CH1_TOP_STRT_ADD_CHROMA);
360 regw(btm_strt_chroma, VPIF_CH1_BTM_STRT_ADD_CHROMA);
361}
362
363static inline void ch0_set_vbi_addr(unsigned long top_vbi,
364 unsigned long btm_vbi, unsigned long a, unsigned long b)
365{
366 regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_VANC);
367 regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_VANC);
368}
369
370static inline void ch0_set_hbi_addr(unsigned long top_vbi,
371 unsigned long btm_vbi, unsigned long a, unsigned long b)
372{
373 regw(top_vbi, VPIF_CH0_TOP_STRT_ADD_HANC);
374 regw(btm_vbi, VPIF_CH0_BTM_STRT_ADD_HANC);
375}
376
377static inline void ch1_set_vbi_addr(unsigned long top_vbi,
378 unsigned long btm_vbi, unsigned long a, unsigned long b)
379{
380 regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_VANC);
381 regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_VANC);
382}
383
384static inline void ch1_set_hbi_addr(unsigned long top_vbi,
385 unsigned long btm_vbi, unsigned long a, unsigned long b)
386{
387 regw(top_vbi, VPIF_CH1_TOP_STRT_ADD_HANC);
388 regw(btm_vbi, VPIF_CH1_BTM_STRT_ADD_HANC);
389}
390
391/* Inline function to enable raw vbi in the given channel */
392static inline void disable_raw_feature(u8 channel_id, u8 index)
393{
394 u32 ctrl_reg;
395 if (0 == channel_id)
396 ctrl_reg = VPIF_CH0_CTRL;
397 else
398 ctrl_reg = VPIF_CH1_CTRL;
399
400 if (1 == index)
401 vpif_clr_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
402 else
403 vpif_clr_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
404}
405
406static inline void enable_raw_feature(u8 channel_id, u8 index)
407{
408 u32 ctrl_reg;
409 if (0 == channel_id)
410 ctrl_reg = VPIF_CH0_CTRL;
411 else
412 ctrl_reg = VPIF_CH1_CTRL;
413
414 if (1 == index)
415 vpif_set_bit(ctrl_reg, VPIF_CH_VANC_EN_BIT);
416 else
417 vpif_set_bit(ctrl_reg, VPIF_CH_HANC_EN_BIT);
418}
419
420/* inline function to enable/disable channel2 */
421static inline void enable_channel2(int enable)
422{
423 if (enable) {
424 regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
425 regw((regr(VPIF_CH2_CTRL) | (VPIF_CH2_EN)), VPIF_CH2_CTRL);
426 } else {
427 regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_CLK_EN)), VPIF_CH2_CTRL);
428 regw((regr(VPIF_CH2_CTRL) & (~VPIF_CH2_EN)), VPIF_CH2_CTRL);
429 }
430}
431
432/* inline function to enable/disable channel3 */
433static inline void enable_channel3(int enable)
434{
435 if (enable) {
436 regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
437 regw((regr(VPIF_CH3_CTRL) | (VPIF_CH3_EN)), VPIF_CH3_CTRL);
438 } else {
439 regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_CLK_EN)), VPIF_CH3_CTRL);
440 regw((regr(VPIF_CH3_CTRL) & (~VPIF_CH3_EN)), VPIF_CH3_CTRL);
441 }
442}
443
444/* inline function to enable interrupt for channel2 */
445static inline void channel2_intr_enable(int enable)
446{
447 unsigned long flags;
448
449 spin_lock_irqsave(&vpif_lock, flags);
450
451 if (enable) {
452 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
453 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
454 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH2), VPIF_INTEN);
455 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
456 VPIF_INTEN_SET);
457 } else {
458 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH2)), VPIF_INTEN);
459 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH2),
460 VPIF_INTEN_SET);
461 }
462 spin_unlock_irqrestore(&vpif_lock, flags);
463}
464
465/* inline function to enable interrupt for channel3 */
466static inline void channel3_intr_enable(int enable)
467{
468 unsigned long flags;
469
470 spin_lock_irqsave(&vpif_lock, flags);
471
472 if (enable) {
473 regw((regr(VPIF_INTEN) | 0x10), VPIF_INTEN);
474 regw((regr(VPIF_INTEN_SET) | 0x10), VPIF_INTEN_SET);
475
476 regw((regr(VPIF_INTEN) | VPIF_INTEN_FRAME_CH3), VPIF_INTEN);
477 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
478 VPIF_INTEN_SET);
479 } else {
480 regw((regr(VPIF_INTEN) & (~VPIF_INTEN_FRAME_CH3)), VPIF_INTEN);
481 regw((regr(VPIF_INTEN_SET) | VPIF_INTEN_FRAME_CH3),
482 VPIF_INTEN_SET);
483 }
484 spin_unlock_irqrestore(&vpif_lock, flags);
485}
486
487/* inline function to enable raw vbi data for channel2 */
488static inline void channel2_raw_enable(int enable, u8 index)
489{
490 u32 mask;
491
492 if (1 == index)
493 mask = VPIF_CH_VANC_EN_BIT;
494 else
495 mask = VPIF_CH_HANC_EN_BIT;
496
497 if (enable)
498 vpif_set_bit(VPIF_CH2_CTRL, mask);
499 else
500 vpif_clr_bit(VPIF_CH2_CTRL, mask);
501}
502
503/* inline function to enable raw vbi data for channel3*/
504static inline void channel3_raw_enable(int enable, u8 index)
505{
506 u32 mask;
507
508 if (1 == index)
509 mask = VPIF_CH_VANC_EN_BIT;
510 else
511 mask = VPIF_CH_HANC_EN_BIT;
512
513 if (enable)
514 vpif_set_bit(VPIF_CH3_CTRL, mask);
515 else
516 vpif_clr_bit(VPIF_CH3_CTRL, mask);
517}
518
519/* inline function to set buffer addresses in case of Y/C non mux mode */
520static inline void ch2_set_videobuf_addr_yc_nmux(unsigned long top_strt_luma,
521 unsigned long btm_strt_luma,
522 unsigned long top_strt_chroma,
523 unsigned long btm_strt_chroma)
524{
525 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
526 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
527 regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
528 regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
529}
530
531/* inline function to set buffer addresses in VPIF registers for video data */
532static inline void ch2_set_videobuf_addr(unsigned long top_strt_luma,
533 unsigned long btm_strt_luma,
534 unsigned long top_strt_chroma,
535 unsigned long btm_strt_chroma)
536{
537 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_LUMA);
538 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_LUMA);
539 regw(top_strt_chroma, VPIF_CH2_TOP_STRT_ADD_CHROMA);
540 regw(btm_strt_chroma, VPIF_CH2_BTM_STRT_ADD_CHROMA);
541}
542
543static inline void ch3_set_videobuf_addr(unsigned long top_strt_luma,
544 unsigned long btm_strt_luma,
545 unsigned long top_strt_chroma,
546 unsigned long btm_strt_chroma)
547{
548 regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_LUMA);
549 regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_LUMA);
550 regw(top_strt_chroma, VPIF_CH3_TOP_STRT_ADD_CHROMA);
551 regw(btm_strt_chroma, VPIF_CH3_BTM_STRT_ADD_CHROMA);
552}
553
554/* inline function to set buffer addresses in VPIF registers for vbi data */
555static inline void ch2_set_vbi_addr(unsigned long top_strt_luma,
556 unsigned long btm_strt_luma,
557 unsigned long top_strt_chroma,
558 unsigned long btm_strt_chroma)
559{
560 regw(top_strt_luma, VPIF_CH2_TOP_STRT_ADD_VANC);
561 regw(btm_strt_luma, VPIF_CH2_BTM_STRT_ADD_VANC);
562}
563
564static inline void ch3_set_vbi_addr(unsigned long top_strt_luma,
565 unsigned long btm_strt_luma,
566 unsigned long top_strt_chroma,
567 unsigned long btm_strt_chroma)
568{
569 regw(top_strt_luma, VPIF_CH3_TOP_STRT_ADD_VANC);
570 regw(btm_strt_luma, VPIF_CH3_BTM_STRT_ADD_VANC);
571}
572
573#define VPIF_MAX_NAME (30)
574
575/* This structure will store size parameters as per the mode selected by user */
576struct vpif_channel_config_params {
577 char name[VPIF_MAX_NAME]; /* Name of the mode */
578 u16 width; /* Indicates width of the image */
579 u16 height; /* Indicates height of the image */
580 u8 fps;
581 u8 frm_fmt; /* Indicates whether this is interlaced
582 * or progressive format */
583 u8 ycmux_mode; /* Indicates whether this mode requires
584 * single or two channels */
585 u16 eav2sav; /* length of sav 2 eav */
586 u16 sav2eav; /* length of sav 2 eav */
587 u16 l1, l3, l5, l7, l9, l11; /* Other parameter configurations */
588 u16 vsize; /* Vertical size of the image */
589 u8 capture_format; /* Indicates whether capture format
590 * is in BT or in CCD/CMOS */
591 u8 vbi_supported; /* Indicates whether this mode
592 * supports capturing vbi or not */
593 u8 hd_sd;
594 v4l2_std_id stdid;
595};
596
597struct vpif_video_params;
598struct vpif_params;
599struct vpif_vbi_params;
600
601int vpif_set_video_params(struct vpif_params *vpifparams, u8 channel_id);
602void vpif_set_vbi_display_params(struct vpif_vbi_params *vbiparams,
603 u8 channel_id);
604int vpif_channel_getfid(u8 channel_id);
605
606enum data_size {
607 _8BITS = 0,
608 _10BITS,
609 _12BITS,
610};
611
612/* Structure for vpif parameters for raw vbi data */
613struct vpif_vbi_params {
614 __u32 hstart0; /* Horizontal start of raw vbi data for first field */
615 __u32 vstart0; /* Vertical start of raw vbi data for first field */
616 __u32 hsize0; /* Horizontal size of raw vbi data for first field */
617 __u32 vsize0; /* Vertical size of raw vbi data for first field */
618 __u32 hstart1; /* Horizontal start of raw vbi data for second field */
619 __u32 vstart1; /* Vertical start of raw vbi data for second field */
620 __u32 hsize1; /* Horizontal size of raw vbi data for second field */
621 __u32 vsize1; /* Vertical size of raw vbi data for second field */
622};
623
624/* structure for vpif parameters */
625struct vpif_video_params {
626 __u8 storage_mode; /* Indicates field or frame mode */
627 unsigned long hpitch;
628 v4l2_std_id stdid;
629};
630
631struct vpif_params {
632 struct vpif_interface iface;
633 struct vpif_video_params video_params;
634 struct vpif_channel_config_params std_info;
635 union param {
636 struct vpif_vbi_params vbi_params;
637 enum data_size data_sz;
638 } params;
639};
640
641#endif /* End of #ifndef VPIF_H */
642
diff --git a/drivers/media/video/davinci/vpif_capture.c b/drivers/media/video/davinci/vpif_capture.c
new file mode 100644
index 000000000000..d947ee5e4eb4
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.c
@@ -0,0 +1,2168 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * TODO : add support for VBI & HBI data service
19 * add static buffer allocation
20 */
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/errno.h>
25#include <linux/fs.h>
26#include <linux/mm.h>
27#include <linux/interrupt.h>
28#include <linux/workqueue.h>
29#include <linux/string.h>
30#include <linux/videodev2.h>
31#include <linux/wait.h>
32#include <linux/time.h>
33#include <linux/i2c.h>
34#include <linux/platform_device.h>
35#include <linux/io.h>
36#include <linux/version.h>
37#include <media/v4l2-device.h>
38#include <media/v4l2-ioctl.h>
39
40#include "vpif_capture.h"
41#include "vpif.h"
42
43MODULE_DESCRIPTION("TI DaVinci VPIF Capture driver");
44MODULE_LICENSE("GPL");
45
46#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
47#define vpif_dbg(level, debug, fmt, arg...) \
48 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
49
50static int debug = 1;
51static u32 ch0_numbuffers = 3;
52static u32 ch1_numbuffers = 3;
53static u32 ch0_bufsize = 1920 * 1080 * 2;
54static u32 ch1_bufsize = 720 * 576 * 2;
55
56module_param(debug, int, 0644);
57module_param(ch0_numbuffers, uint, S_IRUGO);
58module_param(ch1_numbuffers, uint, S_IRUGO);
59module_param(ch0_bufsize, uint, S_IRUGO);
60module_param(ch1_bufsize, uint, S_IRUGO);
61
62MODULE_PARM_DESC(debug, "Debug level 0-1");
63MODULE_PARM_DESC(ch2_numbuffers, "Channel0 buffer count (default:3)");
64MODULE_PARM_DESC(ch3_numbuffers, "Channel1 buffer count (default:3)");
65MODULE_PARM_DESC(ch2_bufsize, "Channel0 buffer size (default:1920 x 1080 x 2)");
66MODULE_PARM_DESC(ch3_bufsize, "Channel1 buffer size (default:720 x 576 x 2)");
67
68static struct vpif_config_params config_params = {
69 .min_numbuffers = 3,
70 .numbuffers[0] = 3,
71 .numbuffers[1] = 3,
72 .min_bufsize[0] = 720 * 480 * 2,
73 .min_bufsize[1] = 720 * 480 * 2,
74 .channel_bufsize[0] = 1920 * 1080 * 2,
75 .channel_bufsize[1] = 720 * 576 * 2,
76};
77
78/* global variables */
79static struct vpif_device vpif_obj = { {NULL} };
80static struct device *vpif_dev;
81
82/**
83 * ch_params: video standard configuration parameters for vpif
84 */
85static const struct vpif_channel_config_params ch_params[] = {
86 {
87 "NTSC_M", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
88 286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
89 },
90 {
91 "PAL_BDGHIK", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
92 336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
93 },
94};
95
96/**
97 * vpif_uservirt_to_phys : translate user/virtual address to phy address
98 * @virtp: user/virtual address
99 *
100 * This inline function is used to convert user space virtual address to
101 * physical address.
102 */
103static inline u32 vpif_uservirt_to_phys(u32 virtp)
104{
105 unsigned long physp = 0;
106 struct mm_struct *mm = current->mm;
107 struct vm_area_struct *vma;
108
109 vma = find_vma(mm, virtp);
110
111 /* For kernel direct-mapped memory, take the easy way */
112 if (virtp >= PAGE_OFFSET)
113 physp = virt_to_phys((void *)virtp);
114 else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff))
115 /**
116 * this will catch, kernel-allocated, mmaped-to-usermode
117 * addresses
118 */
119 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
120 else {
121 /* otherwise, use get_user_pages() for general userland pages */
122 int res, nr_pages = 1;
123 struct page *pages;
124
125 down_read(&current->mm->mmap_sem);
126
127 res = get_user_pages(current, current->mm,
128 virtp, nr_pages, 1, 0, &pages, NULL);
129 up_read(&current->mm->mmap_sem);
130
131 if (res == nr_pages)
132 physp = __pa(page_address(&pages[0]) +
133 (virtp & ~PAGE_MASK));
134 else {
135 vpif_err("get_user_pages failed\n");
136 return 0;
137 }
138 }
139 return physp;
140}
141
142/**
143 * buffer_prepare : callback function for buffer prepare
144 * @q : buffer queue ptr
145 * @vb: ptr to video buffer
146 * @field: field info
147 *
148 * This is the callback function for buffer prepare when videobuf_qbuf()
149 * function is called. The buffer is prepared and user space virtual address
150 * or user address is converted into physical address
151 */
152static int vpif_buffer_prepare(struct videobuf_queue *q,
153 struct videobuf_buffer *vb,
154 enum v4l2_field field)
155{
156 /* Get the file handle object and channel object */
157 struct vpif_fh *fh = q->priv_data;
158 struct channel_obj *ch = fh->channel;
159 struct common_obj *common;
160 unsigned long addr;
161
162
163 vpif_dbg(2, debug, "vpif_buffer_prepare\n");
164
165 common = &ch->common[VPIF_VIDEO_INDEX];
166
167 /* If buffer is not initialized, initialize it */
168 if (VIDEOBUF_NEEDS_INIT == vb->state) {
169 vb->width = common->width;
170 vb->height = common->height;
171 vb->size = vb->width * vb->height;
172 vb->field = field;
173 }
174 vb->state = VIDEOBUF_PREPARED;
175 /**
176 * if user pointer memory mechanism is used, get the physical
177 * address of the buffer
178 */
179 if (V4L2_MEMORY_USERPTR == common->memory) {
180 if (0 == vb->baddr) {
181 vpif_dbg(1, debug, "buffer address is 0\n");
182 return -EINVAL;
183
184 }
185 vb->boff = vpif_uservirt_to_phys(vb->baddr);
186 if (!IS_ALIGNED(vb->boff, 8))
187 goto exit;
188 }
189
190 addr = vb->boff;
191 if (q->streaming) {
192 if (!IS_ALIGNED((addr + common->ytop_off), 8) ||
193 !IS_ALIGNED((addr + common->ybtm_off), 8) ||
194 !IS_ALIGNED((addr + common->ctop_off), 8) ||
195 !IS_ALIGNED((addr + common->cbtm_off), 8))
196 goto exit;
197 }
198 return 0;
199exit:
200 vpif_dbg(1, debug, "buffer_prepare:offset is not aligned to 8 bytes\n");
201 return -EINVAL;
202}
203
204/**
205 * vpif_buffer_setup : Callback function for buffer setup.
206 * @q: buffer queue ptr
207 * @count: number of buffers
208 * @size: size of the buffer
209 *
210 * This callback function is called when reqbuf() is called to adjust
211 * the buffer count and buffer size
212 */
213static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
214 unsigned int *size)
215{
216 /* Get the file handle object and channel object */
217 struct vpif_fh *fh = q->priv_data;
218 struct channel_obj *ch = fh->channel;
219 struct common_obj *common;
220
221 common = &ch->common[VPIF_VIDEO_INDEX];
222
223 vpif_dbg(2, debug, "vpif_buffer_setup\n");
224
225 /* If memory type is not mmap, return */
226 if (V4L2_MEMORY_MMAP != common->memory)
227 return 0;
228
229 /* Calculate the size of the buffer */
230 *size = config_params.channel_bufsize[ch->channel_id];
231
232 if (*count < config_params.min_numbuffers)
233 *count = config_params.min_numbuffers;
234 return 0;
235}
236
237/**
238 * vpif_buffer_queue : Callback function to add buffer to DMA queue
239 * @q: ptr to videobuf_queue
240 * @vb: ptr to videobuf_buffer
241 */
242static void vpif_buffer_queue(struct videobuf_queue *q,
243 struct videobuf_buffer *vb)
244{
245 /* Get the file handle object and channel object */
246 struct vpif_fh *fh = q->priv_data;
247 struct channel_obj *ch = fh->channel;
248 struct common_obj *common;
249
250 common = &ch->common[VPIF_VIDEO_INDEX];
251
252 vpif_dbg(2, debug, "vpif_buffer_queue\n");
253
254 /* add the buffer to the DMA queue */
255 list_add_tail(&vb->queue, &common->dma_queue);
256 /* Change state of the buffer */
257 vb->state = VIDEOBUF_QUEUED;
258}
259
260/**
261 * vpif_buffer_release : Callback function to free buffer
262 * @q: buffer queue ptr
263 * @vb: ptr to video buffer
264 *
265 * This function is called from the videobuf layer to free memory
266 * allocated to the buffers
267 */
268static void vpif_buffer_release(struct videobuf_queue *q,
269 struct videobuf_buffer *vb)
270{
271 /* Get the file handle object and channel object */
272 struct vpif_fh *fh = q->priv_data;
273 struct channel_obj *ch = fh->channel;
274 struct common_obj *common;
275
276 common = &ch->common[VPIF_VIDEO_INDEX];
277
278 videobuf_dma_contig_free(q, vb);
279 vb->state = VIDEOBUF_NEEDS_INIT;
280}
281
282static struct videobuf_queue_ops video_qops = {
283 .buf_setup = vpif_buffer_setup,
284 .buf_prepare = vpif_buffer_prepare,
285 .buf_queue = vpif_buffer_queue,
286 .buf_release = vpif_buffer_release,
287};
288
289static u8 channel_first_int[VPIF_NUMBER_OF_OBJECTS][2] =
290 { {1, 1} };
291
292/**
293 * vpif_process_buffer_complete: process a completed buffer
294 * @common: ptr to common channel object
295 *
296 * This function time stamp the buffer and mark it as DONE. It also
297 * wake up any process waiting on the QUEUE and set the next buffer
298 * as current
299 */
300static void vpif_process_buffer_complete(struct common_obj *common)
301{
302 do_gettimeofday(&common->cur_frm->ts);
303 common->cur_frm->state = VIDEOBUF_DONE;
304 wake_up_interruptible(&common->cur_frm->done);
305 /* Make curFrm pointing to nextFrm */
306 common->cur_frm = common->next_frm;
307}
308
309/**
310 * vpif_schedule_next_buffer: set next buffer address for capture
311 * @common : ptr to common channel object
312 *
313 * This function will get next buffer from the dma queue and
314 * set the buffer address in the vpif register for capture.
315 * the buffer is marked active
316 */
317static void vpif_schedule_next_buffer(struct common_obj *common)
318{
319 unsigned long addr = 0;
320
321 common->next_frm = list_entry(common->dma_queue.next,
322 struct videobuf_buffer, queue);
323 /* Remove that buffer from the buffer queue */
324 list_del(&common->next_frm->queue);
325 common->next_frm->state = VIDEOBUF_ACTIVE;
326 if (V4L2_MEMORY_USERPTR == common->memory)
327 addr = common->next_frm->boff;
328 else
329 addr = videobuf_to_dma_contig(common->next_frm);
330
331 /* Set top and bottom field addresses in VPIF registers */
332 common->set_addr(addr + common->ytop_off,
333 addr + common->ybtm_off,
334 addr + common->ctop_off,
335 addr + common->cbtm_off);
336}
337
338/**
339 * vpif_channel_isr : ISR handler for vpif capture
340 * @irq: irq number
341 * @dev_id: dev_id ptr
342 *
343 * It changes status of the captured buffer, takes next buffer from the queue
344 * and sets its address in VPIF registers
345 */
346static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
347{
348 struct vpif_device *dev = &vpif_obj;
349 struct common_obj *common;
350 struct channel_obj *ch;
351 enum v4l2_field field;
352 int channel_id = 0;
353 int fid = -1, i;
354
355 channel_id = *(int *)(dev_id);
356 ch = dev->dev[channel_id];
357
358 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
359
360 for (i = 0; i < VPIF_NUMBER_OF_OBJECTS; i++) {
361 common = &ch->common[i];
362 /* skip If streaming is not started in this channel */
363 if (0 == common->started)
364 continue;
365
366 /* Check the field format */
367 if (1 == ch->vpifparams.std_info.frm_fmt) {
368 /* Progressive mode */
369 if (list_empty(&common->dma_queue))
370 continue;
371
372 if (!channel_first_int[i][channel_id])
373 vpif_process_buffer_complete(common);
374
375 channel_first_int[i][channel_id] = 0;
376
377 vpif_schedule_next_buffer(common);
378
379
380 channel_first_int[i][channel_id] = 0;
381 } else {
382 /**
383 * Interlaced mode. If it is first interrupt, ignore
384 * it
385 */
386 if (channel_first_int[i][channel_id]) {
387 channel_first_int[i][channel_id] = 0;
388 continue;
389 }
390 if (0 == i) {
391 ch->field_id ^= 1;
392 /* Get field id from VPIF registers */
393 fid = vpif_channel_getfid(ch->channel_id);
394 if (fid != ch->field_id) {
395 /**
396 * If field id does not match stored
397 * field id, make them in sync
398 */
399 if (0 == fid)
400 ch->field_id = fid;
401 return IRQ_HANDLED;
402 }
403 }
404 /* device field id and local field id are in sync */
405 if (0 == fid) {
406 /* this is even field */
407 if (common->cur_frm == common->next_frm)
408 continue;
409
410 /* mark the current buffer as done */
411 vpif_process_buffer_complete(common);
412 } else if (1 == fid) {
413 /* odd field */
414 if (list_empty(&common->dma_queue) ||
415 (common->cur_frm != common->next_frm))
416 continue;
417
418 vpif_schedule_next_buffer(common);
419 }
420 }
421 }
422 return IRQ_HANDLED;
423}
424
425/**
426 * vpif_update_std_info() - update standard related info
427 * @ch: ptr to channel object
428 *
429 * For a given standard selected by application, update values
430 * in the device data structures
431 */
432static int vpif_update_std_info(struct channel_obj *ch)
433{
434 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
435 struct vpif_params *vpifparams = &ch->vpifparams;
436 const struct vpif_channel_config_params *config;
437 struct vpif_channel_config_params *std_info;
438 struct video_obj *vid_ch = &ch->video;
439 int index;
440
441 vpif_dbg(2, debug, "vpif_update_std_info\n");
442
443 std_info = &vpifparams->std_info;
444
445 for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
446 config = &ch_params[index];
447 if (config->stdid & vid_ch->stdid) {
448 memcpy(std_info, config, sizeof(*config));
449 break;
450 }
451 }
452
453 /* standard not found */
454 if (index == ARRAY_SIZE(ch_params))
455 return -EINVAL;
456
457 common->fmt.fmt.pix.width = std_info->width;
458 common->width = std_info->width;
459 common->fmt.fmt.pix.height = std_info->height;
460 common->height = std_info->height;
461 common->fmt.fmt.pix.bytesperline = std_info->width;
462 vpifparams->video_params.hpitch = std_info->width;
463 vpifparams->video_params.storage_mode = std_info->frm_fmt;
464 return 0;
465}
466
467/**
468 * vpif_calculate_offsets : This function calculates buffers offsets
469 * @ch : ptr to channel object
470 *
471 * This function calculates buffer offsets for Y and C in the top and
472 * bottom field
473 */
474static void vpif_calculate_offsets(struct channel_obj *ch)
475{
476 unsigned int hpitch, vpitch, sizeimage;
477 struct video_obj *vid_ch = &(ch->video);
478 struct vpif_params *vpifparams = &ch->vpifparams;
479 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
480 enum v4l2_field field = common->fmt.fmt.pix.field;
481
482 vpif_dbg(2, debug, "vpif_calculate_offsets\n");
483
484 if (V4L2_FIELD_ANY == field) {
485 if (vpifparams->std_info.frm_fmt)
486 vid_ch->buf_field = V4L2_FIELD_NONE;
487 else
488 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
489 } else
490 vid_ch->buf_field = common->fmt.fmt.pix.field;
491
492 if (V4L2_MEMORY_USERPTR == common->memory)
493 sizeimage = common->fmt.fmt.pix.sizeimage;
494 else
495 sizeimage = config_params.channel_bufsize[ch->channel_id];
496
497 hpitch = common->fmt.fmt.pix.bytesperline;
498 vpitch = sizeimage / (hpitch * 2);
499
500 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
501 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
502 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
503 common->ytop_off = 0;
504 common->ybtm_off = hpitch;
505 common->ctop_off = sizeimage / 2;
506 common->cbtm_off = sizeimage / 2 + hpitch;
507 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
508 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
509 common->ytop_off = 0;
510 common->ybtm_off = sizeimage / 4;
511 common->ctop_off = sizeimage / 2;
512 common->cbtm_off = common->ctop_off + sizeimage / 4;
513 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
514 /* Calculate offsets for Y top, Y Bottom, C top and C Bottom */
515 common->ybtm_off = 0;
516 common->ytop_off = sizeimage / 4;
517 common->cbtm_off = sizeimage / 2;
518 common->ctop_off = common->cbtm_off + sizeimage / 4;
519 }
520 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
521 (V4L2_FIELD_INTERLACED == vid_ch->buf_field))
522 vpifparams->video_params.storage_mode = 1;
523 else
524 vpifparams->video_params.storage_mode = 0;
525
526 if (1 == vpifparams->std_info.frm_fmt)
527 vpifparams->video_params.hpitch =
528 common->fmt.fmt.pix.bytesperline;
529 else {
530 if ((field == V4L2_FIELD_ANY)
531 || (field == V4L2_FIELD_INTERLACED))
532 vpifparams->video_params.hpitch =
533 common->fmt.fmt.pix.bytesperline * 2;
534 else
535 vpifparams->video_params.hpitch =
536 common->fmt.fmt.pix.bytesperline;
537 }
538
539 ch->vpifparams.video_params.stdid = vpifparams->std_info.stdid;
540}
541
542/**
543 * vpif_config_format: configure default frame format in the device
544 * ch : ptr to channel object
545 */
546static void vpif_config_format(struct channel_obj *ch)
547{
548 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
549
550 vpif_dbg(2, debug, "vpif_config_format\n");
551
552 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
553 if (config_params.numbuffers[ch->channel_id] == 0)
554 common->memory = V4L2_MEMORY_USERPTR;
555 else
556 common->memory = V4L2_MEMORY_MMAP;
557
558 common->fmt.fmt.pix.sizeimage
559 = config_params.channel_bufsize[ch->channel_id];
560
561 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER)
562 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_SBGGR8;
563 else
564 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
565 common->fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
566}
567
568/**
569 * vpif_get_default_field() - Get default field type based on interface
570 * @vpif_params - ptr to vpif params
571 */
572static inline enum v4l2_field vpif_get_default_field(
573 struct vpif_interface *iface)
574{
575 return (iface->if_type == VPIF_IF_RAW_BAYER) ? V4L2_FIELD_NONE :
576 V4L2_FIELD_INTERLACED;
577}
578
579/**
580 * vpif_check_format() - check given pixel format for compatibility
581 * @ch - channel ptr
582 * @pixfmt - Given pixel format
583 * @update - update the values as per hardware requirement
584 *
585 * Check the application pixel format for S_FMT and update the input
586 * values as per hardware limits for TRY_FMT. The default pixel and
587 * field format is selected based on interface type.
588 */
589static int vpif_check_format(struct channel_obj *ch,
590 struct v4l2_pix_format *pixfmt,
591 int update)
592{
593 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
594 struct vpif_params *vpif_params = &ch->vpifparams;
595 enum v4l2_field field = pixfmt->field;
596 u32 sizeimage, hpitch, vpitch;
597 int ret = -EINVAL;
598
599 vpif_dbg(2, debug, "vpif_check_format\n");
600 /**
601 * first check for the pixel format. If if_type is Raw bayer,
602 * only V4L2_PIX_FMT_SBGGR8 format is supported. Otherwise only
603 * V4L2_PIX_FMT_YUV422P is supported
604 */
605 if (vpif_params->iface.if_type == VPIF_IF_RAW_BAYER) {
606 if (pixfmt->pixelformat != V4L2_PIX_FMT_SBGGR8) {
607 if (!update) {
608 vpif_dbg(2, debug, "invalid pix format\n");
609 goto exit;
610 }
611 pixfmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
612 }
613 } else {
614 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P) {
615 if (!update) {
616 vpif_dbg(2, debug, "invalid pixel format\n");
617 goto exit;
618 }
619 pixfmt->pixelformat = V4L2_PIX_FMT_YUV422P;
620 }
621 }
622
623 if (!(VPIF_VALID_FIELD(field))) {
624 if (!update) {
625 vpif_dbg(2, debug, "invalid field format\n");
626 goto exit;
627 }
628 /**
629 * By default use FIELD_NONE for RAW Bayer capture
630 * and FIELD_INTERLACED for other interfaces
631 */
632 field = vpif_get_default_field(&vpif_params->iface);
633 } else if (field == V4L2_FIELD_ANY)
634 /* unsupported field. Use default */
635 field = vpif_get_default_field(&vpif_params->iface);
636
637 /* validate the hpitch */
638 hpitch = pixfmt->bytesperline;
639 if (hpitch < vpif_params->std_info.width) {
640 if (!update) {
641 vpif_dbg(2, debug, "invalid hpitch\n");
642 goto exit;
643 }
644 hpitch = vpif_params->std_info.width;
645 }
646
647 if (V4L2_MEMORY_USERPTR == common->memory)
648 sizeimage = pixfmt->sizeimage;
649 else
650 sizeimage = config_params.channel_bufsize[ch->channel_id];
651
652 vpitch = sizeimage / (hpitch * 2);
653
654 /* validate the vpitch */
655 if (vpitch < vpif_params->std_info.height) {
656 if (!update) {
657 vpif_dbg(2, debug, "Invalid vpitch\n");
658 goto exit;
659 }
660 vpitch = vpif_params->std_info.height;
661 }
662
663 /* Check for 8 byte alignment */
664 if (!ALIGN(hpitch, 8)) {
665 if (!update) {
666 vpif_dbg(2, debug, "invalid pitch alignment\n");
667 goto exit;
668 }
669 /* adjust to next 8 byte boundary */
670 hpitch = (((hpitch + 7) / 8) * 8);
671 }
672 /* if update is set, modify the bytesperline and sizeimage */
673 if (update) {
674 pixfmt->bytesperline = hpitch;
675 pixfmt->sizeimage = hpitch * vpitch * 2;
676 }
677 /**
678 * Image width and height is always based on current standard width and
679 * height
680 */
681 pixfmt->width = common->fmt.fmt.pix.width;
682 pixfmt->height = common->fmt.fmt.pix.height;
683 return 0;
684exit:
685 return ret;
686}
687
688/**
689 * vpif_config_addr() - function to configure buffer address in vpif
690 * @ch - channel ptr
691 * @muxmode - channel mux mode
692 */
693static void vpif_config_addr(struct channel_obj *ch, int muxmode)
694{
695 struct common_obj *common;
696
697 vpif_dbg(2, debug, "vpif_config_addr\n");
698
699 common = &(ch->common[VPIF_VIDEO_INDEX]);
700
701 if (VPIF_CHANNEL1_VIDEO == ch->channel_id)
702 common->set_addr = ch1_set_videobuf_addr;
703 else if (2 == muxmode)
704 common->set_addr = ch0_set_videobuf_addr_yc_nmux;
705 else
706 common->set_addr = ch0_set_videobuf_addr;
707}
708
709/**
710 * vpfe_mmap : It is used to map kernel space buffers into user spaces
711 * @filep: file pointer
712 * @vma: ptr to vm_area_struct
713 */
714static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
715{
716 /* Get the channel object and file handle object */
717 struct vpif_fh *fh = filep->private_data;
718 struct channel_obj *ch = fh->channel;
719 struct common_obj *common = &(ch->common[VPIF_VIDEO_INDEX]);
720
721 vpif_dbg(2, debug, "vpif_mmap\n");
722
723 return videobuf_mmap_mapper(&common->buffer_queue, vma);
724}
725
726/**
727 * vpif_poll: It is used for select/poll system call
728 * @filep: file pointer
729 * @wait: poll table to wait
730 */
731static unsigned int vpif_poll(struct file *filep, poll_table * wait)
732{
733 int err = 0;
734 struct vpif_fh *fh = filep->private_data;
735 struct channel_obj *channel = fh->channel;
736 struct common_obj *common = &(channel->common[VPIF_VIDEO_INDEX]);
737
738 vpif_dbg(2, debug, "vpif_poll\n");
739
740 if (common->started)
741 err = videobuf_poll_stream(filep, &common->buffer_queue, wait);
742
743 return 0;
744}
745
746/**
747 * vpif_open : vpif open handler
748 * @filep: file ptr
749 *
750 * It creates object of file handle structure and stores it in private_data
751 * member of filepointer
752 */
753static int vpif_open(struct file *filep)
754{
755 struct vpif_capture_config *config = vpif_dev->platform_data;
756 struct video_device *vdev = video_devdata(filep);
757 struct common_obj *common;
758 struct video_obj *vid_ch;
759 struct channel_obj *ch;
760 struct vpif_fh *fh;
761 int i, ret = 0;
762
763 vpif_dbg(2, debug, "vpif_open\n");
764
765 ch = video_get_drvdata(vdev);
766
767 vid_ch = &ch->video;
768 common = &ch->common[VPIF_VIDEO_INDEX];
769
770 if (mutex_lock_interruptible(&common->lock))
771 return -ERESTARTSYS;
772
773 if (NULL == ch->curr_subdev_info) {
774 /**
775 * search through the sub device to see a registered
776 * sub device and make it as current sub device
777 */
778 for (i = 0; i < config->subdev_count; i++) {
779 if (vpif_obj.sd[i]) {
780 /* the sub device is registered */
781 ch->curr_subdev_info = &config->subdev_info[i];
782 /* make first input as the current input */
783 vid_ch->input_idx = 0;
784 break;
785 }
786 }
787 if (i == config->subdev_count) {
788 vpif_err("No sub device registered\n");
789 ret = -ENOENT;
790 goto exit;
791 }
792 }
793
794 /* Allocate memory for the file handle object */
795 fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
796 if (NULL == fh) {
797 vpif_err("unable to allocate memory for file handle object\n");
798 ret = -ENOMEM;
799 goto exit;
800 }
801
802 /* store pointer to fh in private_data member of filep */
803 filep->private_data = fh;
804 fh->channel = ch;
805 fh->initialized = 0;
806 /* If decoder is not initialized. initialize it */
807 if (!ch->initialized) {
808 fh->initialized = 1;
809 ch->initialized = 1;
810 memset(&(ch->vpifparams), 0, sizeof(struct vpif_params));
811 }
812 /* Increment channel usrs counter */
813 ch->usrs++;
814 /* Set io_allowed member to false */
815 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
816 /* Initialize priority of this instance to default priority */
817 fh->prio = V4L2_PRIORITY_UNSET;
818 v4l2_prio_open(&ch->prio, &fh->prio);
819exit:
820 mutex_unlock(&common->lock);
821 return ret;
822}
823
824/**
825 * vpif_release : function to clean up file close
826 * @filep: file pointer
827 *
828 * This function deletes buffer queue, frees the buffers and the vpfe file
829 * handle
830 */
831static int vpif_release(struct file *filep)
832{
833 struct vpif_fh *fh = filep->private_data;
834 struct channel_obj *ch = fh->channel;
835 struct common_obj *common;
836
837 vpif_dbg(2, debug, "vpif_release\n");
838
839 common = &ch->common[VPIF_VIDEO_INDEX];
840
841 if (mutex_lock_interruptible(&common->lock))
842 return -ERESTARTSYS;
843
844 /* if this instance is doing IO */
845 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
846 /* Reset io_usrs member of channel object */
847 common->io_usrs = 0;
848 /* Disable channel as per its device type and channel id */
849 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
850 enable_channel0(0);
851 channel0_intr_enable(0);
852 }
853 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
854 (2 == common->started)) {
855 enable_channel1(0);
856 channel1_intr_enable(0);
857 }
858 common->started = 0;
859 /* Free buffers allocated */
860 videobuf_queue_cancel(&common->buffer_queue);
861 videobuf_mmap_free(&common->buffer_queue);
862 }
863
864 /* Decrement channel usrs counter */
865 ch->usrs--;
866
867 /* unlock mutex on channel object */
868 mutex_unlock(&common->lock);
869
870 /* Close the priority */
871 v4l2_prio_close(&ch->prio, &fh->prio);
872
873 if (fh->initialized)
874 ch->initialized = 0;
875
876 filep->private_data = NULL;
877 kfree(fh);
878 return 0;
879}
880
881/**
882 * vpif_reqbufs() - request buffer handler
883 * @file: file ptr
884 * @priv: file handle
885 * @reqbuf: request buffer structure ptr
886 */
887static int vpif_reqbufs(struct file *file, void *priv,
888 struct v4l2_requestbuffers *reqbuf)
889{
890 struct vpif_fh *fh = priv;
891 struct channel_obj *ch = fh->channel;
892 struct common_obj *common;
893 u8 index = 0;
894 int ret = 0;
895
896 vpif_dbg(2, debug, "vpif_reqbufs\n");
897
898 /**
899 * This file handle has not initialized the channel,
900 * It is not allowed to do settings
901 */
902 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)
903 || (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
904 if (!fh->initialized) {
905 vpif_dbg(1, debug, "Channel Busy\n");
906 return -EBUSY;
907 }
908 }
909
910 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != reqbuf->type)
911 return -EINVAL;
912
913 index = VPIF_VIDEO_INDEX;
914
915 common = &ch->common[index];
916
917 if (mutex_lock_interruptible(&common->lock))
918 return -ERESTARTSYS;
919
920 if (0 != common->io_usrs) {
921 ret = -EBUSY;
922 goto reqbuf_exit;
923 }
924
925 /* Initialize videobuf queue as per the buffer type */
926 videobuf_queue_dma_contig_init(&common->buffer_queue,
927 &video_qops, NULL,
928 &common->irqlock,
929 reqbuf->type,
930 common->fmt.fmt.pix.field,
931 sizeof(struct videobuf_buffer), fh);
932
933 /* Set io allowed member of file handle to TRUE */
934 fh->io_allowed[index] = 1;
935 /* Increment io usrs member of channel object to 1 */
936 common->io_usrs = 1;
937 /* Store type of memory requested in channel object */
938 common->memory = reqbuf->memory;
939 INIT_LIST_HEAD(&common->dma_queue);
940
941 /* Allocate buffers */
942 ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
943
944reqbuf_exit:
945 mutex_unlock(&common->lock);
946 return ret;
947}
948
949/**
950 * vpif_querybuf() - query buffer handler
951 * @file: file ptr
952 * @priv: file handle
953 * @buf: v4l2 buffer structure ptr
954 */
955static int vpif_querybuf(struct file *file, void *priv,
956 struct v4l2_buffer *buf)
957{
958 struct vpif_fh *fh = priv;
959 struct channel_obj *ch = fh->channel;
960 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
961
962 vpif_dbg(2, debug, "vpif_querybuf\n");
963
964 if (common->fmt.type != buf->type)
965 return -EINVAL;
966
967 if (common->memory != V4L2_MEMORY_MMAP) {
968 vpif_dbg(1, debug, "Invalid memory\n");
969 return -EINVAL;
970 }
971
972 return videobuf_querybuf(&common->buffer_queue, buf);
973}
974
975/**
976 * vpif_qbuf() - query buffer handler
977 * @file: file ptr
978 * @priv: file handle
979 * @buf: v4l2 buffer structure ptr
980 */
981static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
982{
983
984 struct vpif_fh *fh = priv;
985 struct channel_obj *ch = fh->channel;
986 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
987 struct v4l2_buffer tbuf = *buf;
988 struct videobuf_buffer *buf1;
989 unsigned long addr = 0;
990 unsigned long flags;
991 int ret = 0;
992
993 vpif_dbg(2, debug, "vpif_qbuf\n");
994
995 if (common->fmt.type != tbuf.type) {
996 vpif_err("invalid buffer type\n");
997 return -EINVAL;
998 }
999
1000 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1001 vpif_err("fh io not allowed \n");
1002 return -EACCES;
1003 }
1004
1005 if (!(list_empty(&common->dma_queue)) ||
1006 (common->cur_frm != common->next_frm) ||
1007 !common->started ||
1008 (common->started && (0 == ch->field_id)))
1009 return videobuf_qbuf(&common->buffer_queue, buf);
1010
1011 /* bufferqueue is empty store buffer address in VPIF registers */
1012 mutex_lock(&common->buffer_queue.vb_lock);
1013 buf1 = common->buffer_queue.bufs[tbuf.index];
1014
1015 if ((buf1->state == VIDEOBUF_QUEUED) ||
1016 (buf1->state == VIDEOBUF_ACTIVE)) {
1017 vpif_err("invalid state\n");
1018 goto qbuf_exit;
1019 }
1020
1021 switch (buf1->memory) {
1022 case V4L2_MEMORY_MMAP:
1023 if (buf1->baddr == 0)
1024 goto qbuf_exit;
1025 break;
1026
1027 case V4L2_MEMORY_USERPTR:
1028 if (tbuf.length < buf1->bsize)
1029 goto qbuf_exit;
1030
1031 if ((VIDEOBUF_NEEDS_INIT != buf1->state)
1032 && (buf1->baddr != tbuf.m.userptr))
1033 vpif_buffer_release(&common->buffer_queue, buf1);
1034 buf1->baddr = tbuf.m.userptr;
1035 break;
1036
1037 default:
1038 goto qbuf_exit;
1039 }
1040
1041 local_irq_save(flags);
1042 ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
1043 common->buffer_queue.field);
1044 if (ret < 0) {
1045 local_irq_restore(flags);
1046 goto qbuf_exit;
1047 }
1048
1049 buf1->state = VIDEOBUF_ACTIVE;
1050
1051 if (V4L2_MEMORY_USERPTR == common->memory)
1052 addr = buf1->boff;
1053 else
1054 addr = videobuf_to_dma_contig(buf1);
1055
1056 common->next_frm = buf1;
1057 common->set_addr(addr + common->ytop_off,
1058 addr + common->ybtm_off,
1059 addr + common->ctop_off,
1060 addr + common->cbtm_off);
1061
1062 local_irq_restore(flags);
1063 list_add_tail(&buf1->stream, &common->buffer_queue.stream);
1064 mutex_unlock(&common->buffer_queue.vb_lock);
1065 return 0;
1066
1067qbuf_exit:
1068 mutex_unlock(&common->buffer_queue.vb_lock);
1069 return -EINVAL;
1070}
1071
1072/**
1073 * vpif_dqbuf() - query buffer handler
1074 * @file: file ptr
1075 * @priv: file handle
1076 * @buf: v4l2 buffer structure ptr
1077 */
1078static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
1079{
1080 struct vpif_fh *fh = priv;
1081 struct channel_obj *ch = fh->channel;
1082 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1083
1084 vpif_dbg(2, debug, "vpif_dqbuf\n");
1085
1086 return videobuf_dqbuf(&common->buffer_queue, buf,
1087 file->f_flags & O_NONBLOCK);
1088}
1089
1090/**
1091 * vpif_streamon() - streamon handler
1092 * @file: file ptr
1093 * @priv: file handle
1094 * @buftype: v4l2 buffer type
1095 */
1096static int vpif_streamon(struct file *file, void *priv,
1097 enum v4l2_buf_type buftype)
1098{
1099
1100 struct vpif_capture_config *config = vpif_dev->platform_data;
1101 struct vpif_fh *fh = priv;
1102 struct channel_obj *ch = fh->channel;
1103 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1104 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1105 struct vpif_params *vpif;
1106 unsigned long addr = 0;
1107 int ret = 0;
1108
1109 vpif_dbg(2, debug, "vpif_streamon\n");
1110
1111 vpif = &ch->vpifparams;
1112
1113 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1114 vpif_dbg(1, debug, "buffer type not supported\n");
1115 return -EINVAL;
1116 }
1117
1118 /* If file handle is not allowed IO, return error */
1119 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1120 vpif_dbg(1, debug, "io not allowed\n");
1121 return -EACCES;
1122 }
1123
1124 /* If Streaming is already started, return error */
1125 if (common->started) {
1126 vpif_dbg(1, debug, "channel->started\n");
1127 return -EBUSY;
1128 }
1129
1130 if ((ch->channel_id == VPIF_CHANNEL0_VIDEO &&
1131 oth_ch->common[VPIF_VIDEO_INDEX].started &&
1132 vpif->std_info.ycmux_mode == 0) ||
1133 ((ch->channel_id == VPIF_CHANNEL1_VIDEO) &&
1134 (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1135 vpif_dbg(1, debug, "other channel is being used\n");
1136 return -EBUSY;
1137 }
1138
1139 ret = vpif_check_format(ch, &common->fmt.fmt.pix, 0);
1140 if (ret)
1141 return ret;
1142
1143 /* Enable streamon on the sub device */
1144 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1145 s_stream, 1);
1146
1147 if (ret && (ret != -ENOIOCTLCMD)) {
1148 vpif_dbg(1, debug, "stream on failed in subdev\n");
1149 return ret;
1150 }
1151
1152 /* Call videobuf_streamon to start streaming in videobuf */
1153 ret = videobuf_streamon(&common->buffer_queue);
1154 if (ret) {
1155 vpif_dbg(1, debug, "videobuf_streamon\n");
1156 return ret;
1157 }
1158
1159 if (mutex_lock_interruptible(&common->lock)) {
1160 ret = -ERESTARTSYS;
1161 goto streamoff_exit;
1162 }
1163
1164 /* If buffer queue is empty, return error */
1165 if (list_empty(&common->dma_queue)) {
1166 vpif_dbg(1, debug, "buffer queue is empty\n");
1167 ret = -EIO;
1168 goto exit;
1169 }
1170
1171 /* Get the next frame from the buffer queue */
1172 common->cur_frm = list_entry(common->dma_queue.next,
1173 struct videobuf_buffer, queue);
1174 common->next_frm = common->cur_frm;
1175
1176 /* Remove buffer from the buffer queue */
1177 list_del(&common->cur_frm->queue);
1178 /* Mark state of the current frame to active */
1179 common->cur_frm->state = VIDEOBUF_ACTIVE;
1180 /* Initialize field_id and started member */
1181 ch->field_id = 0;
1182 common->started = 1;
1183
1184 if (V4L2_MEMORY_USERPTR == common->memory)
1185 addr = common->cur_frm->boff;
1186 else
1187 addr = videobuf_to_dma_contig(common->cur_frm);
1188
1189 /* Calculate the offset for Y and C data in the buffer */
1190 vpif_calculate_offsets(ch);
1191
1192 if ((vpif->std_info.frm_fmt &&
1193 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE) &&
1194 (common->fmt.fmt.pix.field != V4L2_FIELD_ANY))) ||
1195 (!vpif->std_info.frm_fmt &&
1196 (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
1197 vpif_dbg(1, debug, "conflict in field format and std format\n");
1198 ret = -EINVAL;
1199 goto exit;
1200 }
1201
1202 /* configure 1 or 2 channel mode */
1203 ret = config->setup_input_channel_mode(vpif->std_info.ycmux_mode);
1204
1205 if (ret < 0) {
1206 vpif_dbg(1, debug, "can't set vpif channel mode\n");
1207 goto exit;
1208 }
1209
1210 /* Call vpif_set_params function to set the parameters and addresses */
1211 ret = vpif_set_video_params(vpif, ch->channel_id);
1212
1213 if (ret < 0) {
1214 vpif_dbg(1, debug, "can't set video params\n");
1215 goto exit;
1216 }
1217
1218 common->started = ret;
1219 vpif_config_addr(ch, ret);
1220
1221 common->set_addr(addr + common->ytop_off,
1222 addr + common->ybtm_off,
1223 addr + common->ctop_off,
1224 addr + common->cbtm_off);
1225
1226 /**
1227 * Set interrupt for both the fields in VPIF Register enable channel in
1228 * VPIF register
1229 */
1230 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id)) {
1231 channel0_intr_assert();
1232 channel0_intr_enable(1);
1233 enable_channel0(1);
1234 }
1235 if ((VPIF_CHANNEL1_VIDEO == ch->channel_id) ||
1236 (common->started == 2)) {
1237 channel1_intr_assert();
1238 channel1_intr_enable(1);
1239 enable_channel1(1);
1240 }
1241 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
1242 mutex_unlock(&common->lock);
1243 return ret;
1244
1245exit:
1246 mutex_unlock(&common->lock);
1247streamoff_exit:
1248 ret = videobuf_streamoff(&common->buffer_queue);
1249 return ret;
1250}
1251
1252/**
1253 * vpif_streamoff() - streamoff handler
1254 * @file: file ptr
1255 * @priv: file handle
1256 * @buftype: v4l2 buffer type
1257 */
1258static int vpif_streamoff(struct file *file, void *priv,
1259 enum v4l2_buf_type buftype)
1260{
1261
1262 struct vpif_fh *fh = priv;
1263 struct channel_obj *ch = fh->channel;
1264 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1265 int ret;
1266
1267 vpif_dbg(2, debug, "vpif_streamoff\n");
1268
1269 if (buftype != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1270 vpif_dbg(1, debug, "buffer type not supported\n");
1271 return -EINVAL;
1272 }
1273
1274 /* If io is allowed for this file handle, return error */
1275 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1276 vpif_dbg(1, debug, "io not allowed\n");
1277 return -EACCES;
1278 }
1279
1280 /* If streaming is not started, return error */
1281 if (!common->started) {
1282 vpif_dbg(1, debug, "channel->started\n");
1283 return -EINVAL;
1284 }
1285
1286 if (mutex_lock_interruptible(&common->lock))
1287 return -ERESTARTSYS;
1288
1289 /* disable channel */
1290 if (VPIF_CHANNEL0_VIDEO == ch->channel_id) {
1291 enable_channel0(0);
1292 channel0_intr_enable(0);
1293 } else {
1294 enable_channel1(0);
1295 channel1_intr_enable(0);
1296 }
1297
1298 common->started = 0;
1299
1300 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1301 s_stream, 0);
1302
1303 if (ret && (ret != -ENOIOCTLCMD))
1304 vpif_dbg(1, debug, "stream off failed in subdev\n");
1305
1306 mutex_unlock(&common->lock);
1307
1308 return videobuf_streamoff(&common->buffer_queue);
1309}
1310
1311/**
1312 * vpif_map_sub_device_to_input() - Maps sub device to input
1313 * @ch - ptr to channel
1314 * @config - ptr to capture configuration
1315 * @input_index - Given input index from application
1316 * @sub_device_index - index into sd table
1317 *
1318 * lookup the sub device information for a given input index.
1319 * we report all the inputs to application. inputs table also
1320 * has sub device name for the each input
1321 */
1322static struct vpif_subdev_info *vpif_map_sub_device_to_input(
1323 struct channel_obj *ch,
1324 struct vpif_capture_config *vpif_cfg,
1325 int input_index,
1326 int *sub_device_index)
1327{
1328 struct vpif_capture_chan_config *chan_cfg;
1329 struct vpif_subdev_info *subdev_info = NULL;
1330 const char *subdev_name = NULL;
1331 int i;
1332
1333 vpif_dbg(2, debug, "vpif_map_sub_device_to_input\n");
1334
1335 chan_cfg = &vpif_cfg->chan_config[ch->channel_id];
1336
1337 /**
1338 * search through the inputs to find the sub device supporting
1339 * the input
1340 */
1341 for (i = 0; i < chan_cfg->input_count; i++) {
1342 /* For each sub device, loop through input */
1343 if (i == input_index) {
1344 subdev_name = chan_cfg->inputs[i].subdev_name;
1345 break;
1346 }
1347 }
1348
1349 /* if reached maximum. return null */
1350 if (i == chan_cfg->input_count || (NULL == subdev_name))
1351 return subdev_info;
1352
1353 /* loop through the sub device list to get the sub device info */
1354 for (i = 0; i < vpif_cfg->subdev_count; i++) {
1355 subdev_info = &vpif_cfg->subdev_info[i];
1356 if (!strcmp(subdev_info->name, subdev_name))
1357 break;
1358 }
1359
1360 if (i == vpif_cfg->subdev_count)
1361 return subdev_info;
1362
1363 /* check if the sub device is registered */
1364 if (NULL == vpif_obj.sd[i])
1365 return NULL;
1366
1367 *sub_device_index = i;
1368 return subdev_info;
1369}
1370
1371/**
1372 * vpif_querystd() - querystd handler
1373 * @file: file ptr
1374 * @priv: file handle
1375 * @std_id: ptr to std id
1376 *
1377 * This function is called to detect standard at the selected input
1378 */
1379static int vpif_querystd(struct file *file, void *priv, v4l2_std_id *std_id)
1380{
1381 struct vpif_fh *fh = priv;
1382 struct channel_obj *ch = fh->channel;
1383 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1384 int ret = 0;
1385
1386 vpif_dbg(2, debug, "vpif_querystd\n");
1387
1388 if (mutex_lock_interruptible(&common->lock))
1389 return -ERESTARTSYS;
1390
1391 /* Call querystd function of decoder device */
1392 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], video,
1393 querystd, std_id);
1394 if (ret < 0)
1395 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1396
1397 mutex_unlock(&common->lock);
1398 return ret;
1399}
1400
1401/**
1402 * vpif_g_std() - get STD handler
1403 * @file: file ptr
1404 * @priv: file handle
1405 * @std_id: ptr to std id
1406 */
1407static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1408{
1409 struct vpif_fh *fh = priv;
1410 struct channel_obj *ch = fh->channel;
1411
1412 vpif_dbg(2, debug, "vpif_g_std\n");
1413
1414 *std = ch->video.stdid;
1415 return 0;
1416}
1417
1418/**
1419 * vpif_s_std() - set STD handler
1420 * @file: file ptr
1421 * @priv: file handle
1422 * @std_id: ptr to std id
1423 */
1424static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
1425{
1426 struct vpif_fh *fh = priv;
1427 struct channel_obj *ch = fh->channel;
1428 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1429 int ret = 0;
1430
1431 vpif_dbg(2, debug, "vpif_s_std\n");
1432
1433 if (common->started) {
1434 vpif_err("streaming in progress\n");
1435 return -EBUSY;
1436 }
1437
1438 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1439 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1440 if (!fh->initialized) {
1441 vpif_dbg(1, debug, "Channel Busy\n");
1442 return -EBUSY;
1443 }
1444 }
1445
1446 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1447 if (0 != ret)
1448 return ret;
1449
1450 fh->initialized = 1;
1451
1452 /* Call encoder subdevice function to set the standard */
1453 if (mutex_lock_interruptible(&common->lock))
1454 return -ERESTARTSYS;
1455
1456 ch->video.stdid = *std_id;
1457
1458 /* Get the information about the standard */
1459 if (vpif_update_std_info(ch)) {
1460 ret = -EINVAL;
1461 vpif_err("Error getting the standard info\n");
1462 goto s_std_exit;
1463 }
1464
1465 /* Configure the default format information */
1466 vpif_config_format(ch);
1467
1468 /* set standard in the sub device */
1469 ret = v4l2_subdev_call(vpif_obj.sd[ch->curr_sd_index], core,
1470 s_std, *std_id);
1471 if (ret < 0)
1472 vpif_dbg(1, debug, "Failed to set standard for sub devices\n");
1473
1474s_std_exit:
1475 mutex_unlock(&common->lock);
1476 return ret;
1477}
1478
1479/**
1480 * vpif_enum_input() - ENUMINPUT handler
1481 * @file: file ptr
1482 * @priv: file handle
1483 * @input: ptr to input structure
1484 */
1485static int vpif_enum_input(struct file *file, void *priv,
1486 struct v4l2_input *input)
1487{
1488
1489 struct vpif_capture_config *config = vpif_dev->platform_data;
1490 struct vpif_capture_chan_config *chan_cfg;
1491 struct vpif_fh *fh = priv;
1492 struct channel_obj *ch = fh->channel;
1493
1494 chan_cfg = &config->chan_config[ch->channel_id];
1495
1496 if (input->index >= chan_cfg->input_count) {
1497 vpif_dbg(1, debug, "Invalid input index\n");
1498 return -EINVAL;
1499 }
1500
1501 memcpy(input, &chan_cfg->inputs[input->index].input,
1502 sizeof(*input));
1503 return 0;
1504}
1505
1506/**
1507 * vpif_g_input() - Get INPUT handler
1508 * @file: file ptr
1509 * @priv: file handle
1510 * @index: ptr to input index
1511 */
1512static int vpif_g_input(struct file *file, void *priv, unsigned int *index)
1513{
1514 struct vpif_fh *fh = priv;
1515 struct channel_obj *ch = fh->channel;
1516 struct video_obj *vid_ch = &ch->video;
1517
1518 *index = vid_ch->input_idx;
1519
1520 return 0;
1521}
1522
1523/**
1524 * vpif_s_input() - Set INPUT handler
1525 * @file: file ptr
1526 * @priv: file handle
1527 * @index: input index
1528 */
1529static int vpif_s_input(struct file *file, void *priv, unsigned int index)
1530{
1531 struct vpif_capture_config *config = vpif_dev->platform_data;
1532 struct vpif_capture_chan_config *chan_cfg;
1533 struct vpif_fh *fh = priv;
1534 struct channel_obj *ch = fh->channel;
1535 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1536 struct video_obj *vid_ch = &ch->video;
1537 struct vpif_subdev_info *subdev_info;
1538 int ret = 0, sd_index = 0;
1539 u32 input = 0, output = 0;
1540
1541 chan_cfg = &config->chan_config[ch->channel_id];
1542
1543 if (common->started) {
1544 vpif_err("Streaming in progress\n");
1545 return -EBUSY;
1546 }
1547
1548 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1549 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1550 if (!fh->initialized) {
1551 vpif_dbg(1, debug, "Channel Busy\n");
1552 return -EBUSY;
1553 }
1554 }
1555
1556 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1557 if (0 != ret)
1558 return ret;
1559
1560 fh->initialized = 1;
1561 subdev_info = vpif_map_sub_device_to_input(ch, config, index,
1562 &sd_index);
1563 if (NULL == subdev_info) {
1564 vpif_dbg(1, debug,
1565 "couldn't lookup sub device for the input index\n");
1566 return -EINVAL;
1567 }
1568
1569 if (mutex_lock_interruptible(&common->lock))
1570 return -ERESTARTSYS;
1571
1572 /* first setup input path from sub device to vpif */
1573 if (config->setup_input_path) {
1574 ret = config->setup_input_path(ch->channel_id,
1575 subdev_info->name);
1576 if (ret < 0) {
1577 vpif_dbg(1, debug, "couldn't setup input path for the"
1578 " sub device %s, for input index %d\n",
1579 subdev_info->name, index);
1580 goto exit;
1581 }
1582 }
1583
1584 if (subdev_info->can_route) {
1585 input = subdev_info->input;
1586 output = subdev_info->output;
1587 ret = v4l2_subdev_call(vpif_obj.sd[sd_index], video, s_routing,
1588 input, output, 0);
1589 if (ret < 0) {
1590 vpif_dbg(1, debug, "Failed to set input\n");
1591 goto exit;
1592 }
1593 }
1594 vid_ch->input_idx = index;
1595 ch->curr_subdev_info = subdev_info;
1596 ch->curr_sd_index = sd_index;
1597 /* copy interface parameters to vpif */
1598 ch->vpifparams.iface = subdev_info->vpif_if;
1599
1600 /* update tvnorms from the sub device input info */
1601 ch->video_dev->tvnorms = chan_cfg->inputs[index].input.std;
1602
1603exit:
1604 mutex_unlock(&common->lock);
1605 return ret;
1606}
1607
1608/**
1609 * vpif_enum_fmt_vid_cap() - ENUM_FMT handler
1610 * @file: file ptr
1611 * @priv: file handle
1612 * @index: input index
1613 */
1614static int vpif_enum_fmt_vid_cap(struct file *file, void *priv,
1615 struct v4l2_fmtdesc *fmt)
1616{
1617 struct vpif_fh *fh = priv;
1618 struct channel_obj *ch = fh->channel;
1619
1620 if (fmt->index != 0) {
1621 vpif_dbg(1, debug, "Invalid format index\n");
1622 return -EINVAL;
1623 }
1624
1625 /* Fill in the information about format */
1626 if (ch->vpifparams.iface.if_type == VPIF_IF_RAW_BAYER) {
1627 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1628 strcpy(fmt->description, "Raw Mode -Bayer Pattern GrRBGb");
1629 fmt->pixelformat = V4L2_PIX_FMT_SBGGR8;
1630 } else {
1631 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1632 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
1633 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
1634 }
1635 return 0;
1636}
1637
1638/**
1639 * vpif_try_fmt_vid_cap() - TRY_FMT handler
1640 * @file: file ptr
1641 * @priv: file handle
1642 * @fmt: ptr to v4l2 format structure
1643 */
1644static int vpif_try_fmt_vid_cap(struct file *file, void *priv,
1645 struct v4l2_format *fmt)
1646{
1647 struct vpif_fh *fh = priv;
1648 struct channel_obj *ch = fh->channel;
1649 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
1650
1651 return vpif_check_format(ch, pixfmt, 1);
1652}
1653
1654
1655/**
1656 * vpif_g_fmt_vid_cap() - Set INPUT handler
1657 * @file: file ptr
1658 * @priv: file handle
1659 * @fmt: ptr to v4l2 format structure
1660 */
1661static int vpif_g_fmt_vid_cap(struct file *file, void *priv,
1662 struct v4l2_format *fmt)
1663{
1664 struct vpif_fh *fh = priv;
1665 struct channel_obj *ch = fh->channel;
1666 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1667
1668 /* Check the validity of the buffer type */
1669 if (common->fmt.type != fmt->type)
1670 return -EINVAL;
1671
1672 /* Fill in the information about format */
1673 if (mutex_lock_interruptible(&common->lock))
1674 return -ERESTARTSYS;
1675
1676 *fmt = common->fmt;
1677 mutex_unlock(&common->lock);
1678 return 0;
1679}
1680
1681/**
1682 * vpif_s_fmt_vid_cap() - Set FMT handler
1683 * @file: file ptr
1684 * @priv: file handle
1685 * @fmt: ptr to v4l2 format structure
1686 */
1687static int vpif_s_fmt_vid_cap(struct file *file, void *priv,
1688 struct v4l2_format *fmt)
1689{
1690 struct vpif_fh *fh = priv;
1691 struct channel_obj *ch = fh->channel;
1692 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1693 struct v4l2_pix_format *pixfmt;
1694 int ret = 0;
1695
1696 vpif_dbg(2, debug, "VIDIOC_S_FMT\n");
1697
1698 /* If streaming is started, return error */
1699 if (common->started) {
1700 vpif_dbg(1, debug, "Streaming is started\n");
1701 return -EBUSY;
1702 }
1703
1704 if ((VPIF_CHANNEL0_VIDEO == ch->channel_id) ||
1705 (VPIF_CHANNEL1_VIDEO == ch->channel_id)) {
1706 if (!fh->initialized) {
1707 vpif_dbg(1, debug, "Channel Busy\n");
1708 return -EBUSY;
1709 }
1710 }
1711
1712 ret = v4l2_prio_check(&ch->prio, &fh->prio);
1713 if (0 != ret)
1714 return ret;
1715
1716 fh->initialized = 1;
1717
1718 pixfmt = &fmt->fmt.pix;
1719 /* Check for valid field format */
1720 ret = vpif_check_format(ch, pixfmt, 0);
1721
1722 if (ret)
1723 return ret;
1724 /* store the format in the channel object */
1725 if (mutex_lock_interruptible(&common->lock))
1726 return -ERESTARTSYS;
1727
1728 common->fmt = *fmt;
1729 mutex_unlock(&common->lock);
1730
1731 return 0;
1732}
1733
1734/**
1735 * vpif_querycap() - QUERYCAP handler
1736 * @file: file ptr
1737 * @priv: file handle
1738 * @cap: ptr to v4l2_capability structure
1739 */
1740static int vpif_querycap(struct file *file, void *priv,
1741 struct v4l2_capability *cap)
1742{
1743 struct vpif_capture_config *config = vpif_dev->platform_data;
1744
1745 cap->version = VPIF_CAPTURE_VERSION_CODE;
1746 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
1747 strlcpy(cap->driver, "vpif capture", sizeof(cap->driver));
1748 strlcpy(cap->bus_info, "DM646x Platform", sizeof(cap->bus_info));
1749 strlcpy(cap->card, config->card_name, sizeof(cap->card));
1750
1751 return 0;
1752}
1753
1754/**
1755 * vpif_g_priority() - get priority handler
1756 * @file: file ptr
1757 * @priv: file handle
1758 * @prio: ptr to v4l2_priority structure
1759 */
1760static int vpif_g_priority(struct file *file, void *priv,
1761 enum v4l2_priority *prio)
1762{
1763 struct vpif_fh *fh = priv;
1764 struct channel_obj *ch = fh->channel;
1765
1766 *prio = v4l2_prio_max(&ch->prio);
1767
1768 return 0;
1769}
1770
1771/**
1772 * vpif_s_priority() - set priority handler
1773 * @file: file ptr
1774 * @priv: file handle
1775 * @prio: ptr to v4l2_priority structure
1776 */
1777static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1778{
1779 struct vpif_fh *fh = priv;
1780 struct channel_obj *ch = fh->channel;
1781
1782 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1783}
1784
1785/**
1786 * vpif_cropcap() - cropcap handler
1787 * @file: file ptr
1788 * @priv: file handle
1789 * @crop: ptr to v4l2_cropcap structure
1790 */
1791static int vpif_cropcap(struct file *file, void *priv,
1792 struct v4l2_cropcap *crop)
1793{
1794 struct vpif_fh *fh = priv;
1795 struct channel_obj *ch = fh->channel;
1796 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1797
1798 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != crop->type)
1799 return -EINVAL;
1800
1801 crop->bounds.left = 0;
1802 crop->bounds.top = 0;
1803 crop->bounds.height = common->height;
1804 crop->bounds.width = common->width;
1805 crop->defrect = crop->bounds;
1806 return 0;
1807}
1808
1809/* vpif capture ioctl operations */
1810static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1811 .vidioc_querycap = vpif_querycap,
1812 .vidioc_g_priority = vpif_g_priority,
1813 .vidioc_s_priority = vpif_s_priority,
1814 .vidioc_enum_fmt_vid_cap = vpif_enum_fmt_vid_cap,
1815 .vidioc_g_fmt_vid_cap = vpif_g_fmt_vid_cap,
1816 .vidioc_s_fmt_vid_cap = vpif_s_fmt_vid_cap,
1817 .vidioc_try_fmt_vid_cap = vpif_try_fmt_vid_cap,
1818 .vidioc_enum_input = vpif_enum_input,
1819 .vidioc_s_input = vpif_s_input,
1820 .vidioc_g_input = vpif_g_input,
1821 .vidioc_reqbufs = vpif_reqbufs,
1822 .vidioc_querybuf = vpif_querybuf,
1823 .vidioc_querystd = vpif_querystd,
1824 .vidioc_s_std = vpif_s_std,
1825 .vidioc_g_std = vpif_g_std,
1826 .vidioc_qbuf = vpif_qbuf,
1827 .vidioc_dqbuf = vpif_dqbuf,
1828 .vidioc_streamon = vpif_streamon,
1829 .vidioc_streamoff = vpif_streamoff,
1830 .vidioc_cropcap = vpif_cropcap,
1831};
1832
1833/* vpif file operations */
1834static struct v4l2_file_operations vpif_fops = {
1835 .owner = THIS_MODULE,
1836 .open = vpif_open,
1837 .release = vpif_release,
1838 .ioctl = video_ioctl2,
1839 .mmap = vpif_mmap,
1840 .poll = vpif_poll
1841};
1842
1843/* vpif video template */
1844static struct video_device vpif_video_template = {
1845 .name = "vpif",
1846 .fops = &vpif_fops,
1847 .minor = -1,
1848 .ioctl_ops = &vpif_ioctl_ops,
1849};
1850
1851/**
1852 * initialize_vpif() - Initialize vpif data structures
1853 *
1854 * Allocate memory for data structures and initialize them
1855 */
1856static int initialize_vpif(void)
1857{
1858 int err = 0, i, j;
1859 int free_channel_objects_index;
1860
1861 /* Default number of buffers should be 3 */
1862 if ((ch0_numbuffers > 0) &&
1863 (ch0_numbuffers < config_params.min_numbuffers))
1864 ch0_numbuffers = config_params.min_numbuffers;
1865 if ((ch1_numbuffers > 0) &&
1866 (ch1_numbuffers < config_params.min_numbuffers))
1867 ch1_numbuffers = config_params.min_numbuffers;
1868
1869 /* Set buffer size to min buffers size if it is invalid */
1870 if (ch0_bufsize < config_params.min_bufsize[VPIF_CHANNEL0_VIDEO])
1871 ch0_bufsize =
1872 config_params.min_bufsize[VPIF_CHANNEL0_VIDEO];
1873 if (ch1_bufsize < config_params.min_bufsize[VPIF_CHANNEL1_VIDEO])
1874 ch1_bufsize =
1875 config_params.min_bufsize[VPIF_CHANNEL1_VIDEO];
1876
1877 config_params.numbuffers[VPIF_CHANNEL0_VIDEO] = ch0_numbuffers;
1878 config_params.numbuffers[VPIF_CHANNEL1_VIDEO] = ch1_numbuffers;
1879 if (ch0_numbuffers) {
1880 config_params.channel_bufsize[VPIF_CHANNEL0_VIDEO]
1881 = ch0_bufsize;
1882 }
1883 if (ch1_numbuffers) {
1884 config_params.channel_bufsize[VPIF_CHANNEL1_VIDEO]
1885 = ch1_bufsize;
1886 }
1887
1888 /* Allocate memory for six channel objects */
1889 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1890 vpif_obj.dev[i] =
1891 kzalloc(sizeof(*vpif_obj.dev[i]), GFP_KERNEL);
1892 /* If memory allocation fails, return error */
1893 if (!vpif_obj.dev[i]) {
1894 free_channel_objects_index = i;
1895 err = -ENOMEM;
1896 goto vpif_init_free_channel_objects;
1897 }
1898 }
1899 return 0;
1900
1901vpif_init_free_channel_objects:
1902 for (j = 0; j < free_channel_objects_index; j++)
1903 kfree(vpif_obj.dev[j]);
1904 return err;
1905}
1906
1907/**
1908 * vpif_probe : This function probes the vpif capture driver
1909 * @pdev: platform device pointer
1910 *
1911 * This creates device entries by register itself to the V4L2 driver and
1912 * initializes fields of each channel objects
1913 */
1914static __init int vpif_probe(struct platform_device *pdev)
1915{
1916 struct vpif_subdev_info *subdevdata;
1917 struct vpif_capture_config *config;
1918 int i, j, k, m, q, err;
1919 struct i2c_adapter *i2c_adap;
1920 struct channel_obj *ch;
1921 struct common_obj *common;
1922 struct video_device *vfd;
1923 struct resource *res;
1924 int subdev_count;
1925
1926 vpif_dev = &pdev->dev;
1927
1928 err = initialize_vpif();
1929 if (err) {
1930 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
1931 return err;
1932 }
1933
1934 k = 0;
1935 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1936 for (i = res->start; i <= res->end; i++) {
1937 if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
1938 "DM646x_Capture",
1939 (void *)(&vpif_obj.dev[k]->channel_id))) {
1940 err = -EBUSY;
1941 i--;
1942 goto vpif_int_err;
1943 }
1944 }
1945 k++;
1946 }
1947
1948 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
1949 /* Get the pointer to the channel object */
1950 ch = vpif_obj.dev[i];
1951 /* Allocate memory for video device */
1952 vfd = video_device_alloc();
1953 if (NULL == vfd) {
1954 for (j = 0; j < i; j++) {
1955 ch = vpif_obj.dev[j];
1956 video_device_release(ch->video_dev);
1957 }
1958 err = -ENOMEM;
1959 goto vpif_dev_alloc_err;
1960 }
1961
1962 /* Initialize field of video device */
1963 *vfd = vpif_video_template;
1964 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
1965 vfd->release = video_device_release;
1966 snprintf(vfd->name, sizeof(vfd->name),
1967 "DM646x_VPIFCapture_DRIVER_V%d.%d.%d",
1968 (VPIF_CAPTURE_VERSION_CODE >> 16) & 0xff,
1969 (VPIF_CAPTURE_VERSION_CODE >> 8) & 0xff,
1970 (VPIF_CAPTURE_VERSION_CODE) & 0xff);
1971 /* Set video_dev to the video device */
1972 ch->video_dev = vfd;
1973 }
1974
1975 for (j = 0; j < VPIF_CAPTURE_MAX_DEVICES; j++) {
1976 ch = vpif_obj.dev[j];
1977 ch->channel_id = j;
1978 common = &(ch->common[VPIF_VIDEO_INDEX]);
1979 spin_lock_init(&common->irqlock);
1980 mutex_init(&common->lock);
1981 /* Initialize prio member of channel object */
1982 v4l2_prio_init(&ch->prio);
1983 err = video_register_device(ch->video_dev,
1984 VFL_TYPE_GRABBER, (j ? 1 : 0));
1985 if (err)
1986 goto probe_out;
1987
1988 video_set_drvdata(ch->video_dev, ch);
1989
1990 }
1991
1992 i2c_adap = i2c_get_adapter(1);
1993 config = pdev->dev.platform_data;
1994
1995 subdev_count = config->subdev_count;
1996 vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1997 GFP_KERNEL);
1998 if (vpif_obj.sd == NULL) {
1999 vpif_err("unable to allocate memory for subdevice pointers\n");
2000 err = -ENOMEM;
2001 goto probe_out;
2002 }
2003
2004 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
2005 if (err) {
2006 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
2007 goto probe_subdev_out;
2008 }
2009
2010 for (i = 0; i < subdev_count; i++) {
2011 subdevdata = &config->subdev_info[i];
2012 vpif_obj.sd[i] =
2013 v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
2014 i2c_adap,
2015 subdevdata->name,
2016 &subdevdata->board_info,
2017 NULL);
2018
2019 if (!vpif_obj.sd[i]) {
2020 vpif_err("Error registering v4l2 subdevice\n");
2021 goto probe_subdev_out;
2022 }
2023 v4l2_info(&vpif_obj.v4l2_dev, "registered sub device %s\n",
2024 subdevdata->name);
2025
2026 if (vpif_obj.sd[i])
2027 vpif_obj.sd[i]->grp_id = 1 << i;
2028 }
2029 v4l2_info(&vpif_obj.v4l2_dev, "DM646x VPIF Capture driver"
2030 " initialized\n");
2031
2032 return 0;
2033
2034probe_subdev_out:
2035 /* free sub devices memory */
2036 kfree(vpif_obj.sd);
2037
2038 j = VPIF_CAPTURE_MAX_DEVICES;
2039probe_out:
2040 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2041 for (k = 0; k < j; k++) {
2042 /* Get the pointer to the channel object */
2043 ch = vpif_obj.dev[k];
2044 /* Unregister video device */
2045 video_unregister_device(ch->video_dev);
2046 }
2047
2048vpif_dev_alloc_err:
2049 k = VPIF_CAPTURE_MAX_DEVICES-1;
2050 res = platform_get_resource(pdev, IORESOURCE_IRQ, k);
2051 i = res->end;
2052
2053vpif_int_err:
2054 for (q = k; q >= 0; q--) {
2055 for (m = i; m >= (int)res->start; m--)
2056 free_irq(m, (void *)(&vpif_obj.dev[q]->channel_id));
2057
2058 res = platform_get_resource(pdev, IORESOURCE_IRQ, q-1);
2059 if (res)
2060 i = res->end;
2061 }
2062 return err;
2063}
2064
2065/**
2066 * vpif_remove() - driver remove handler
2067 * @device: ptr to platform device structure
2068 *
2069 * The vidoe device is unregistered
2070 */
2071static int vpif_remove(struct platform_device *device)
2072{
2073 int i;
2074 struct channel_obj *ch;
2075
2076 v4l2_device_unregister(&vpif_obj.v4l2_dev);
2077
2078 /* un-register device */
2079 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++) {
2080 /* Get the pointer to the channel object */
2081 ch = vpif_obj.dev[i];
2082 /* Unregister video device */
2083 video_unregister_device(ch->video_dev);
2084 }
2085 return 0;
2086}
2087
2088/**
2089 * vpif_suspend: vpif device suspend
2090 *
2091 * TODO: Add suspend code here
2092 */
2093static int
2094vpif_suspend(struct device *dev)
2095{
2096 return -1;
2097}
2098
2099/**
2100 * vpif_resume: vpif device suspend
2101 *
2102 * TODO: Add resume code here
2103 */
2104static int
2105vpif_resume(struct device *dev)
2106{
2107 return -1;
2108}
2109
2110static struct dev_pm_ops vpif_dev_pm_ops = {
2111 .suspend = vpif_suspend,
2112 .resume = vpif_resume,
2113};
2114
2115static struct platform_driver vpif_driver = {
2116 .driver = {
2117 .name = "vpif_capture",
2118 .owner = THIS_MODULE,
2119 .pm = &vpif_dev_pm_ops,
2120 },
2121 .probe = vpif_probe,
2122 .remove = vpif_remove,
2123};
2124
2125/**
2126 * vpif_init: initialize the vpif driver
2127 *
2128 * This function registers device and driver to the kernel, requests irq
2129 * handler and allocates memory
2130 * for channel objects
2131 */
2132static __init int vpif_init(void)
2133{
2134 return platform_driver_register(&vpif_driver);
2135}
2136
2137/**
2138 * vpif_cleanup : This function clean up the vpif capture resources
2139 *
2140 * This will un-registers device and driver to the kernel, frees
2141 * requested irq handler and de-allocates memory allocated for channel
2142 * objects.
2143 */
2144static void vpif_cleanup(void)
2145{
2146 struct platform_device *pdev;
2147 struct resource *res;
2148 int irq_num;
2149 int i = 0;
2150
2151 pdev = container_of(vpif_dev, struct platform_device, dev);
2152 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
2153 for (irq_num = res->start; irq_num <= res->end; irq_num++)
2154 free_irq(irq_num,
2155 (void *)(&vpif_obj.dev[i]->channel_id));
2156 i++;
2157 }
2158
2159 platform_driver_unregister(&vpif_driver);
2160
2161 kfree(vpif_obj.sd);
2162 for (i = 0; i < VPIF_CAPTURE_MAX_DEVICES; i++)
2163 kfree(vpif_obj.dev[i]);
2164}
2165
2166/* Function for module initialization and cleanup */
2167module_init(vpif_init);
2168module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_capture.h b/drivers/media/video/davinci/vpif_capture.h
new file mode 100644
index 000000000000..4e12ec8cac6f
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_capture.h
@@ -0,0 +1,165 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef VPIF_CAPTURE_H
20#define VPIF_CAPTURE_H
21
22#ifdef __KERNEL__
23
24/* Header files */
25#include <linux/videodev2.h>
26#include <linux/version.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-device.h>
29#include <media/videobuf-core.h>
30#include <media/videobuf-dma-contig.h>
31#include <mach/dm646x.h>
32
33#include "vpif.h"
34
35/* Macros */
36#define VPIF_MAJOR_RELEASE 0
37#define VPIF_MINOR_RELEASE 0
38#define VPIF_BUILD 1
39#define VPIF_CAPTURE_VERSION_CODE ((VPIF_MAJOR_RELEASE << 16) | \
40 (VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
41
42#define VPIF_VALID_FIELD(field) (((V4L2_FIELD_ANY == field) || \
43 (V4L2_FIELD_NONE == field)) || \
44 (((V4L2_FIELD_INTERLACED == field) || \
45 (V4L2_FIELD_SEQ_TB == field)) || \
46 (V4L2_FIELD_SEQ_BT == field)))
47
48#define VPIF_CAPTURE_MAX_DEVICES 2
49#define VPIF_VIDEO_INDEX 0
50#define VPIF_NUMBER_OF_OBJECTS 1
51
52/* Enumerated data type to give id to each device per channel */
53enum vpif_channel_id {
54 VPIF_CHANNEL0_VIDEO = 0,
55 VPIF_CHANNEL1_VIDEO,
56};
57
58struct video_obj {
59 enum v4l2_field buf_field;
60 /* Currently selected or default standard */
61 v4l2_std_id stdid;
62 /* This is to track the last input that is passed to application */
63 u32 input_idx;
64};
65
66struct common_obj {
67 /* Pointer pointing to current v4l2_buffer */
68 struct videobuf_buffer *cur_frm;
69 /* Pointer pointing to current v4l2_buffer */
70 struct videobuf_buffer *next_frm;
71 /*
72 * This field keeps track of type of buffer exchange mechanism
73 * user has selected
74 */
75 enum v4l2_memory memory;
76 /* Used to store pixel format */
77 struct v4l2_format fmt;
78 /* Buffer queue used in video-buf */
79 struct videobuf_queue buffer_queue;
80 /* Queue of filled frames */
81 struct list_head dma_queue;
82 /* Used in video-buf */
83 spinlock_t irqlock;
84 /* lock used to access this structure */
85 struct mutex lock;
86 /* number of users performing IO */
87 u32 io_usrs;
88 /* Indicates whether streaming started */
89 u8 started;
90 /* Function pointer to set the addresses */
91 void (*set_addr) (unsigned long, unsigned long, unsigned long,
92 unsigned long);
93 /* offset where Y top starts from the starting of the buffer */
94 u32 ytop_off;
95 /* offset where Y bottom starts from the starting of the buffer */
96 u32 ybtm_off;
97 /* offset where C top starts from the starting of the buffer */
98 u32 ctop_off;
99 /* offset where C bottom starts from the starting of the buffer */
100 u32 cbtm_off;
101 /* Indicates width of the image data */
102 u32 width;
103 /* Indicates height of the image data */
104 u32 height;
105};
106
107struct channel_obj {
108 /* Identifies video device for this channel */
109 struct video_device *video_dev;
110 /* Used to keep track of state of the priority */
111 struct v4l2_prio_state prio;
112 /* number of open instances of the channel */
113 int usrs;
114 /* Indicates id of the field which is being displayed */
115 u32 field_id;
116 /* flag to indicate whether decoder is initialized */
117 u8 initialized;
118 /* Identifies channel */
119 enum vpif_channel_id channel_id;
120 /* index into sd table */
121 int curr_sd_index;
122 /* ptr to current sub device information */
123 struct vpif_subdev_info *curr_subdev_info;
124 /* vpif configuration params */
125 struct vpif_params vpifparams;
126 /* common object array */
127 struct common_obj common[VPIF_NUMBER_OF_OBJECTS];
128 /* video object */
129 struct video_obj video;
130};
131
132/* File handle structure */
133struct vpif_fh {
134 /* pointer to channel object for opened device */
135 struct channel_obj *channel;
136 /* Indicates whether this file handle is doing IO */
137 u8 io_allowed[VPIF_NUMBER_OF_OBJECTS];
138 /* Used to keep track priority of this instance */
139 enum v4l2_priority prio;
140 /* Used to indicate channel is initialize or not */
141 u8 initialized;
142};
143
144struct vpif_device {
145 struct v4l2_device v4l2_dev;
146 struct channel_obj *dev[VPIF_CAPTURE_NUM_CHANNELS];
147 struct v4l2_subdev **sd;
148};
149
150struct vpif_config_params {
151 u8 min_numbuffers;
152 u8 numbuffers[VPIF_CAPTURE_NUM_CHANNELS];
153 s8 device_type;
154 u32 min_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
155 u32 channel_bufsize[VPIF_CAPTURE_NUM_CHANNELS];
156 u8 default_device[VPIF_CAPTURE_NUM_CHANNELS];
157 u8 max_device_type;
158};
159/* Struct which keeps track of the line numbers for the sliced vbi service */
160struct vpif_service_line {
161 u16 service_id;
162 u16 service_line[2];
163};
164#endif /* End of __KERNEL__ */
165#endif /* VPIF_CAPTURE_H */
diff --git a/drivers/media/video/davinci/vpif_display.c b/drivers/media/video/davinci/vpif_display.c
new file mode 100644
index 000000000000..c015da813dda
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_display.c
@@ -0,0 +1,1656 @@
1/*
2 * vpif-display - VPIF display driver
3 * Display driver for TI DaVinci VPIF
4 *
5 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation version 2.
10 *
11 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
12 * kind, whether express or implied; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/kernel.h>
18#include <linux/init.h>
19#include <linux/module.h>
20#include <linux/errno.h>
21#include <linux/fs.h>
22#include <linux/mm.h>
23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
25#include <linux/string.h>
26#include <linux/videodev2.h>
27#include <linux/wait.h>
28#include <linux/time.h>
29#include <linux/i2c.h>
30#include <linux/platform_device.h>
31#include <linux/io.h>
32#include <linux/version.h>
33
34#include <asm/irq.h>
35#include <asm/page.h>
36
37#include <media/adv7343.h>
38#include <media/v4l2-device.h>
39#include <media/v4l2-ioctl.h>
40
41#include <mach/dm646x.h>
42
43#include "vpif_display.h"
44#include "vpif.h"
45
46MODULE_DESCRIPTION("TI DaVinci VPIF Display driver");
47MODULE_LICENSE("GPL");
48
49#define DM646X_V4L2_STD (V4L2_STD_525_60 | V4L2_STD_625_50)
50
51#define vpif_err(fmt, arg...) v4l2_err(&vpif_obj.v4l2_dev, fmt, ## arg)
52#define vpif_dbg(level, debug, fmt, arg...) \
53 v4l2_dbg(level, debug, &vpif_obj.v4l2_dev, fmt, ## arg)
54
55static int debug = 1;
56static u32 ch2_numbuffers = 3;
57static u32 ch3_numbuffers = 3;
58static u32 ch2_bufsize = 1920 * 1080 * 2;
59static u32 ch3_bufsize = 720 * 576 * 2;
60
61module_param(debug, int, 0644);
62module_param(ch2_numbuffers, uint, S_IRUGO);
63module_param(ch3_numbuffers, uint, S_IRUGO);
64module_param(ch2_bufsize, uint, S_IRUGO);
65module_param(ch3_bufsize, uint, S_IRUGO);
66
67MODULE_PARM_DESC(debug, "Debug level 0-1");
68MODULE_PARM_DESC(ch2_numbuffers, "Channel2 buffer count (default:3)");
69MODULE_PARM_DESC(ch3_numbuffers, "Channel3 buffer count (default:3)");
70MODULE_PARM_DESC(ch2_bufsize, "Channel2 buffer size (default:1920 x 1080 x 2)");
71MODULE_PARM_DESC(ch3_bufsize, "Channel3 buffer size (default:720 x 576 x 2)");
72
73static struct vpif_config_params config_params = {
74 .min_numbuffers = 3,
75 .numbuffers[0] = 3,
76 .numbuffers[1] = 3,
77 .min_bufsize[0] = 720 * 480 * 2,
78 .min_bufsize[1] = 720 * 480 * 2,
79 .channel_bufsize[0] = 1920 * 1080 * 2,
80 .channel_bufsize[1] = 720 * 576 * 2,
81};
82
83static struct vpif_device vpif_obj = { {NULL} };
84static struct device *vpif_dev;
85
86static const struct vpif_channel_config_params ch_params[] = {
87 {
88 "NTSC", 720, 480, 30, 0, 1, 268, 1440, 1, 23, 263, 266,
89 286, 525, 525, 0, 1, 0, V4L2_STD_525_60,
90 },
91 {
92 "PAL", 720, 576, 25, 0, 1, 280, 1440, 1, 23, 311, 313,
93 336, 624, 625, 0, 1, 0, V4L2_STD_625_50,
94 },
95};
96
97/*
98 * vpif_uservirt_to_phys: This function is used to convert user
99 * space virtual address to physical address.
100 */
101static u32 vpif_uservirt_to_phys(u32 virtp)
102{
103 struct mm_struct *mm = current->mm;
104 unsigned long physp = 0;
105 struct vm_area_struct *vma;
106
107 vma = find_vma(mm, virtp);
108
109 /* For kernel direct-mapped memory, take the easy way */
110 if (virtp >= PAGE_OFFSET) {
111 physp = virt_to_phys((void *)virtp);
112 } else if (vma && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
113 /* this will catch, kernel-allocated, mmaped-to-usermode addr */
114 physp = (vma->vm_pgoff << PAGE_SHIFT) + (virtp - vma->vm_start);
115 } else {
116 /* otherwise, use get_user_pages() for general userland pages */
117 int res, nr_pages = 1;
118 struct page *pages;
119 down_read(&current->mm->mmap_sem);
120
121 res = get_user_pages(current, current->mm,
122 virtp, nr_pages, 1, 0, &pages, NULL);
123 up_read(&current->mm->mmap_sem);
124
125 if (res == nr_pages) {
126 physp = __pa(page_address(&pages[0]) +
127 (virtp & ~PAGE_MASK));
128 } else {
129 vpif_err("get_user_pages failed\n");
130 return 0;
131 }
132 }
133
134 return physp;
135}
136
137/*
138 * buffer_prepare: This is the callback function called from videobuf_qbuf()
139 * function the buffer is prepared and user space virtual address is converted
140 * into physical address
141 */
142static int vpif_buffer_prepare(struct videobuf_queue *q,
143 struct videobuf_buffer *vb,
144 enum v4l2_field field)
145{
146 struct vpif_fh *fh = q->priv_data;
147 struct common_obj *common;
148 unsigned long addr;
149
150 common = &fh->channel->common[VPIF_VIDEO_INDEX];
151 if (VIDEOBUF_NEEDS_INIT == vb->state) {
152 vb->width = common->width;
153 vb->height = common->height;
154 vb->size = vb->width * vb->height;
155 vb->field = field;
156 }
157 vb->state = VIDEOBUF_PREPARED;
158
159 /* if user pointer memory mechanism is used, get the physical
160 * address of the buffer */
161 if (V4L2_MEMORY_USERPTR == common->memory) {
162 if (!vb->baddr) {
163 vpif_err("buffer_address is 0\n");
164 return -EINVAL;
165 }
166
167 vb->boff = vpif_uservirt_to_phys(vb->baddr);
168 if (!ISALIGNED(vb->boff))
169 goto buf_align_exit;
170 }
171
172 addr = vb->boff;
173 if (q->streaming && (V4L2_BUF_TYPE_SLICED_VBI_OUTPUT != q->type)) {
174 if (!ISALIGNED(addr + common->ytop_off) ||
175 !ISALIGNED(addr + common->ybtm_off) ||
176 !ISALIGNED(addr + common->ctop_off) ||
177 !ISALIGNED(addr + common->cbtm_off))
178 goto buf_align_exit;
179 }
180 return 0;
181
182buf_align_exit:
183 vpif_err("buffer offset not aligned to 8 bytes\n");
184 return -EINVAL;
185}
186
187/*
188 * vpif_buffer_setup: This function allocates memory for the buffers
189 */
190static int vpif_buffer_setup(struct videobuf_queue *q, unsigned int *count,
191 unsigned int *size)
192{
193 struct vpif_fh *fh = q->priv_data;
194 struct channel_obj *ch = fh->channel;
195 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
196
197 if (V4L2_MEMORY_MMAP != common->memory)
198 return 0;
199
200 *size = config_params.channel_bufsize[ch->channel_id];
201 if (*count < config_params.min_numbuffers)
202 *count = config_params.min_numbuffers;
203
204 return 0;
205}
206
207/*
208 * vpif_buffer_queue: This function adds the buffer to DMA queue
209 */
210static void vpif_buffer_queue(struct videobuf_queue *q,
211 struct videobuf_buffer *vb)
212{
213 struct vpif_fh *fh = q->priv_data;
214 struct common_obj *common;
215
216 common = &fh->channel->common[VPIF_VIDEO_INDEX];
217
218 /* add the buffer to the DMA queue */
219 list_add_tail(&vb->queue, &common->dma_queue);
220 vb->state = VIDEOBUF_QUEUED;
221}
222
223/*
224 * vpif_buffer_release: This function is called from the videobuf layer to
225 * free memory allocated to the buffers
226 */
227static void vpif_buffer_release(struct videobuf_queue *q,
228 struct videobuf_buffer *vb)
229{
230 struct vpif_fh *fh = q->priv_data;
231 struct channel_obj *ch = fh->channel;
232 struct common_obj *common;
233 unsigned int buf_size = 0;
234
235 common = &ch->common[VPIF_VIDEO_INDEX];
236
237 videobuf_dma_contig_free(q, vb);
238 vb->state = VIDEOBUF_NEEDS_INIT;
239
240 if (V4L2_MEMORY_MMAP != common->memory)
241 return;
242
243 buf_size = config_params.channel_bufsize[ch->channel_id];
244}
245
246static struct videobuf_queue_ops video_qops = {
247 .buf_setup = vpif_buffer_setup,
248 .buf_prepare = vpif_buffer_prepare,
249 .buf_queue = vpif_buffer_queue,
250 .buf_release = vpif_buffer_release,
251};
252static u8 channel_first_int[VPIF_NUMOBJECTS][2] = { {1, 1} };
253
254static void process_progressive_mode(struct common_obj *common)
255{
256 unsigned long addr = 0;
257
258 /* Get the next buffer from buffer queue */
259 common->next_frm = list_entry(common->dma_queue.next,
260 struct videobuf_buffer, queue);
261 /* Remove that buffer from the buffer queue */
262 list_del(&common->next_frm->queue);
263 /* Mark status of the buffer as active */
264 common->next_frm->state = VIDEOBUF_ACTIVE;
265
266 /* Set top and bottom field addrs in VPIF registers */
267 addr = videobuf_to_dma_contig(common->next_frm);
268 common->set_addr(addr + common->ytop_off,
269 addr + common->ybtm_off,
270 addr + common->ctop_off,
271 addr + common->cbtm_off);
272}
273
274static void process_interlaced_mode(int fid, struct common_obj *common)
275{
276 /* device field id and local field id are in sync */
277 /* If this is even field */
278 if (0 == fid) {
279 if (common->cur_frm == common->next_frm)
280 return;
281
282 /* one frame is displayed If next frame is
283 * available, release cur_frm and move on */
284 /* Copy frame display time */
285 do_gettimeofday(&common->cur_frm->ts);
286 /* Change status of the cur_frm */
287 common->cur_frm->state = VIDEOBUF_DONE;
288 /* unlock semaphore on cur_frm */
289 wake_up_interruptible(&common->cur_frm->done);
290 /* Make cur_frm pointing to next_frm */
291 common->cur_frm = common->next_frm;
292
293 } else if (1 == fid) { /* odd field */
294 if (list_empty(&common->dma_queue)
295 || (common->cur_frm != common->next_frm)) {
296 return;
297 }
298 /* one field is displayed configure the next
299 * frame if it is available else hold on current
300 * frame */
301 /* Get next from the buffer queue */
302 process_progressive_mode(common);
303
304 }
305}
306
307/*
308 * vpif_channel_isr: It changes status of the displayed buffer, takes next
309 * buffer from the queue and sets its address in VPIF registers
310 */
311static irqreturn_t vpif_channel_isr(int irq, void *dev_id)
312{
313 struct vpif_device *dev = &vpif_obj;
314 struct channel_obj *ch;
315 struct common_obj *common;
316 enum v4l2_field field;
317 int fid = -1, i;
318 int channel_id = 0;
319
320 channel_id = *(int *)(dev_id);
321 ch = dev->dev[channel_id];
322 field = ch->common[VPIF_VIDEO_INDEX].fmt.fmt.pix.field;
323 for (i = 0; i < VPIF_NUMOBJECTS; i++) {
324 common = &ch->common[i];
325 /* If streaming is started in this channel */
326 if (0 == common->started)
327 continue;
328
329 if (1 == ch->vpifparams.std_info.frm_fmt) {
330 if (list_empty(&common->dma_queue))
331 continue;
332
333 /* Progressive mode */
334 if (!channel_first_int[i][channel_id]) {
335 /* Mark status of the cur_frm to
336 * done and unlock semaphore on it */
337 do_gettimeofday(&common->cur_frm->ts);
338 common->cur_frm->state = VIDEOBUF_DONE;
339 wake_up_interruptible(&common->cur_frm->done);
340 /* Make cur_frm pointing to next_frm */
341 common->cur_frm = common->next_frm;
342 }
343
344 channel_first_int[i][channel_id] = 0;
345 process_progressive_mode(common);
346 } else {
347 /* Interlaced mode */
348 /* If it is first interrupt, ignore it */
349
350 if (channel_first_int[i][channel_id]) {
351 channel_first_int[i][channel_id] = 0;
352 continue;
353 }
354
355 if (0 == i) {
356 ch->field_id ^= 1;
357 /* Get field id from VPIF registers */
358 fid = vpif_channel_getfid(ch->channel_id + 2);
359 /* If fid does not match with stored field id */
360 if (fid != ch->field_id) {
361 /* Make them in sync */
362 if (0 == fid)
363 ch->field_id = fid;
364
365 return IRQ_HANDLED;
366 }
367 }
368 process_interlaced_mode(fid, common);
369 }
370 }
371
372 return IRQ_HANDLED;
373}
374
375static int vpif_get_std_info(struct channel_obj *ch)
376{
377 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
378 struct video_obj *vid_ch = &ch->video;
379 struct vpif_params *vpifparams = &ch->vpifparams;
380 struct vpif_channel_config_params *std_info = &vpifparams->std_info;
381 const struct vpif_channel_config_params *config;
382
383 int index;
384
385 std_info->stdid = vid_ch->stdid;
386 if (!std_info)
387 return -1;
388
389 for (index = 0; index < ARRAY_SIZE(ch_params); index++) {
390 config = &ch_params[index];
391 if (config->stdid & std_info->stdid) {
392 memcpy(std_info, config, sizeof(*config));
393 break;
394 }
395 }
396
397 if (index == ARRAY_SIZE(ch_params))
398 return -1;
399
400 common->fmt.fmt.pix.width = std_info->width;
401 common->fmt.fmt.pix.height = std_info->height;
402 vpif_dbg(1, debug, "Pixel details: Width = %d,Height = %d\n",
403 common->fmt.fmt.pix.width, common->fmt.fmt.pix.height);
404
405 /* Set height and width paramateres */
406 ch->common[VPIF_VIDEO_INDEX].height = std_info->height;
407 ch->common[VPIF_VIDEO_INDEX].width = std_info->width;
408
409 return 0;
410}
411
412/*
413 * vpif_calculate_offsets: This function calculates buffers offset for Y and C
414 * in the top and bottom field
415 */
416static void vpif_calculate_offsets(struct channel_obj *ch)
417{
418 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
419 struct vpif_params *vpifparams = &ch->vpifparams;
420 enum v4l2_field field = common->fmt.fmt.pix.field;
421 struct video_obj *vid_ch = &ch->video;
422 unsigned int hpitch, vpitch, sizeimage;
423
424 if (V4L2_FIELD_ANY == common->fmt.fmt.pix.field) {
425 if (ch->vpifparams.std_info.frm_fmt)
426 vid_ch->buf_field = V4L2_FIELD_NONE;
427 else
428 vid_ch->buf_field = V4L2_FIELD_INTERLACED;
429 } else {
430 vid_ch->buf_field = common->fmt.fmt.pix.field;
431 }
432
433 if (V4L2_MEMORY_USERPTR == common->memory)
434 sizeimage = common->fmt.fmt.pix.sizeimage;
435 else
436 sizeimage = config_params.channel_bufsize[ch->channel_id];
437
438 hpitch = common->fmt.fmt.pix.bytesperline;
439 vpitch = sizeimage / (hpitch * 2);
440 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
441 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
442 common->ytop_off = 0;
443 common->ybtm_off = hpitch;
444 common->ctop_off = sizeimage / 2;
445 common->cbtm_off = sizeimage / 2 + hpitch;
446 } else if (V4L2_FIELD_SEQ_TB == vid_ch->buf_field) {
447 common->ytop_off = 0;
448 common->ybtm_off = sizeimage / 4;
449 common->ctop_off = sizeimage / 2;
450 common->cbtm_off = common->ctop_off + sizeimage / 4;
451 } else if (V4L2_FIELD_SEQ_BT == vid_ch->buf_field) {
452 common->ybtm_off = 0;
453 common->ytop_off = sizeimage / 4;
454 common->cbtm_off = sizeimage / 2;
455 common->ctop_off = common->cbtm_off + sizeimage / 4;
456 }
457
458 if ((V4L2_FIELD_NONE == vid_ch->buf_field) ||
459 (V4L2_FIELD_INTERLACED == vid_ch->buf_field)) {
460 vpifparams->video_params.storage_mode = 1;
461 } else {
462 vpifparams->video_params.storage_mode = 0;
463 }
464
465 if (ch->vpifparams.std_info.frm_fmt == 1) {
466 vpifparams->video_params.hpitch =
467 common->fmt.fmt.pix.bytesperline;
468 } else {
469 if ((field == V4L2_FIELD_ANY) ||
470 (field == V4L2_FIELD_INTERLACED))
471 vpifparams->video_params.hpitch =
472 common->fmt.fmt.pix.bytesperline * 2;
473 else
474 vpifparams->video_params.hpitch =
475 common->fmt.fmt.pix.bytesperline;
476 }
477
478 ch->vpifparams.video_params.stdid = ch->vpifparams.std_info.stdid;
479}
480
481static void vpif_config_format(struct channel_obj *ch)
482{
483 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
484
485 common->fmt.fmt.pix.field = V4L2_FIELD_ANY;
486 if (config_params.numbuffers[ch->channel_id] == 0)
487 common->memory = V4L2_MEMORY_USERPTR;
488 else
489 common->memory = V4L2_MEMORY_MMAP;
490
491 common->fmt.fmt.pix.sizeimage =
492 config_params.channel_bufsize[ch->channel_id];
493 common->fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUV422P;
494 common->fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
495}
496
497static int vpif_check_format(struct channel_obj *ch,
498 struct v4l2_pix_format *pixfmt)
499{
500 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
501 enum v4l2_field field = pixfmt->field;
502 u32 sizeimage, hpitch, vpitch;
503
504 if (pixfmt->pixelformat != V4L2_PIX_FMT_YUV422P)
505 goto invalid_fmt_exit;
506
507 if (!(VPIF_VALID_FIELD(field)))
508 goto invalid_fmt_exit;
509
510 if (pixfmt->bytesperline <= 0)
511 goto invalid_pitch_exit;
512
513 if (V4L2_MEMORY_USERPTR == common->memory)
514 sizeimage = pixfmt->sizeimage;
515 else
516 sizeimage = config_params.channel_bufsize[ch->channel_id];
517
518 if (vpif_get_std_info(ch)) {
519 vpif_err("Error getting the standard info\n");
520 return -EINVAL;
521 }
522
523 hpitch = pixfmt->bytesperline;
524 vpitch = sizeimage / (hpitch * 2);
525
526 /* Check for valid value of pitch */
527 if ((hpitch < ch->vpifparams.std_info.width) ||
528 (vpitch < ch->vpifparams.std_info.height))
529 goto invalid_pitch_exit;
530
531 /* Check for 8 byte alignment */
532 if (!ISALIGNED(hpitch)) {
533 vpif_err("invalid pitch alignment\n");
534 return -EINVAL;
535 }
536 pixfmt->width = common->fmt.fmt.pix.width;
537 pixfmt->height = common->fmt.fmt.pix.height;
538
539 return 0;
540
541invalid_fmt_exit:
542 vpif_err("invalid field format\n");
543 return -EINVAL;
544
545invalid_pitch_exit:
546 vpif_err("invalid pitch\n");
547 return -EINVAL;
548}
549
550static void vpif_config_addr(struct channel_obj *ch, int muxmode)
551{
552 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
553
554 if (VPIF_CHANNEL3_VIDEO == ch->channel_id) {
555 common->set_addr = ch3_set_videobuf_addr;
556 } else {
557 if (2 == muxmode)
558 common->set_addr = ch2_set_videobuf_addr_yc_nmux;
559 else
560 common->set_addr = ch2_set_videobuf_addr;
561 }
562}
563
564/*
565 * vpif_mmap: It is used to map kernel space buffers into user spaces
566 */
567static int vpif_mmap(struct file *filep, struct vm_area_struct *vma)
568{
569 struct vpif_fh *fh = filep->private_data;
570 struct common_obj *common = &fh->channel->common[VPIF_VIDEO_INDEX];
571
572 return videobuf_mmap_mapper(&common->buffer_queue, vma);
573}
574
575/*
576 * vpif_poll: It is used for select/poll system call
577 */
578static unsigned int vpif_poll(struct file *filep, poll_table *wait)
579{
580 struct vpif_fh *fh = filep->private_data;
581 struct channel_obj *ch = fh->channel;
582 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
583
584 if (common->started)
585 return videobuf_poll_stream(filep, &common->buffer_queue, wait);
586
587 return 0;
588}
589
590/*
591 * vpif_open: It creates object of file handle structure and stores it in
592 * private_data member of filepointer
593 */
594static int vpif_open(struct file *filep)
595{
596 struct video_device *vdev = video_devdata(filep);
597 struct channel_obj *ch = NULL;
598 struct vpif_fh *fh = NULL;
599
600 ch = video_get_drvdata(vdev);
601 /* Allocate memory for the file handle object */
602 fh = kmalloc(sizeof(struct vpif_fh), GFP_KERNEL);
603 if (fh == NULL) {
604 vpif_err("unable to allocate memory for file handle object\n");
605 return -ENOMEM;
606 }
607
608 /* store pointer to fh in private_data member of filep */
609 filep->private_data = fh;
610 fh->channel = ch;
611 fh->initialized = 0;
612 if (!ch->initialized) {
613 fh->initialized = 1;
614 ch->initialized = 1;
615 memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
616 }
617
618 /* Increment channel usrs counter */
619 atomic_inc(&ch->usrs);
620 /* Set io_allowed[VPIF_VIDEO_INDEX] member to false */
621 fh->io_allowed[VPIF_VIDEO_INDEX] = 0;
622 /* Initialize priority of this instance to default priority */
623 fh->prio = V4L2_PRIORITY_UNSET;
624 v4l2_prio_open(&ch->prio, &fh->prio);
625
626 return 0;
627}
628
629/*
630 * vpif_release: This function deletes buffer queue, frees the buffers and
631 * the vpif file handle
632 */
633static int vpif_release(struct file *filep)
634{
635 struct vpif_fh *fh = filep->private_data;
636 struct channel_obj *ch = fh->channel;
637 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
638
639 if (mutex_lock_interruptible(&common->lock))
640 return -ERESTARTSYS;
641
642 /* if this instance is doing IO */
643 if (fh->io_allowed[VPIF_VIDEO_INDEX]) {
644 /* Reset io_usrs member of channel object */
645 common->io_usrs = 0;
646 /* Disable channel */
647 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
648 enable_channel2(0);
649 channel2_intr_enable(0);
650 }
651 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
652 (2 == common->started)) {
653 enable_channel3(0);
654 channel3_intr_enable(0);
655 }
656 common->started = 0;
657 /* Free buffers allocated */
658 videobuf_queue_cancel(&common->buffer_queue);
659 videobuf_mmap_free(&common->buffer_queue);
660 common->numbuffers =
661 config_params.numbuffers[ch->channel_id];
662 }
663
664 mutex_unlock(&common->lock);
665
666 /* Decrement channel usrs counter */
667 atomic_dec(&ch->usrs);
668 /* If this file handle has initialize encoder device, reset it */
669 if (fh->initialized)
670 ch->initialized = 0;
671
672 /* Close the priority */
673 v4l2_prio_close(&ch->prio, &fh->prio);
674 filep->private_data = NULL;
675 fh->initialized = 0;
676 kfree(fh);
677
678 return 0;
679}
680
681/* functions implementing ioctls */
682
683static int vpif_querycap(struct file *file, void *priv,
684 struct v4l2_capability *cap)
685{
686 struct vpif_display_config *config = vpif_dev->platform_data;
687
688 cap->version = VPIF_DISPLAY_VERSION_CODE;
689 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
690 strlcpy(cap->driver, "vpif display", sizeof(cap->driver));
691 strlcpy(cap->bus_info, "Platform", sizeof(cap->bus_info));
692 strlcpy(cap->card, config->card_name, sizeof(cap->card));
693
694 return 0;
695}
696
697static int vpif_enum_fmt_vid_out(struct file *file, void *priv,
698 struct v4l2_fmtdesc *fmt)
699{
700 if (fmt->index != 0) {
701 vpif_err("Invalid format index\n");
702 return -EINVAL;
703 }
704
705 /* Fill in the information about format */
706 fmt->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
707 strcpy(fmt->description, "YCbCr4:2:2 YC Planar");
708 fmt->pixelformat = V4L2_PIX_FMT_YUV422P;
709
710 return 0;
711}
712
713static int vpif_g_fmt_vid_out(struct file *file, void *priv,
714 struct v4l2_format *fmt)
715{
716 struct vpif_fh *fh = priv;
717 struct channel_obj *ch = fh->channel;
718 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
719
720 /* Check the validity of the buffer type */
721 if (common->fmt.type != fmt->type)
722 return -EINVAL;
723
724 /* Fill in the information about format */
725 if (mutex_lock_interruptible(&common->lock))
726 return -ERESTARTSYS;
727
728 if (vpif_get_std_info(ch)) {
729 vpif_err("Error getting the standard info\n");
730 return -EINVAL;
731 }
732
733 *fmt = common->fmt;
734 mutex_unlock(&common->lock);
735 return 0;
736}
737
738static int vpif_s_fmt_vid_out(struct file *file, void *priv,
739 struct v4l2_format *fmt)
740{
741 struct vpif_fh *fh = priv;
742 struct v4l2_pix_format *pixfmt;
743 struct channel_obj *ch = fh->channel;
744 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
745 int ret = 0;
746
747 if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
748 || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
749 if (!fh->initialized) {
750 vpif_dbg(1, debug, "Channel Busy\n");
751 return -EBUSY;
752 }
753
754 /* Check for the priority */
755 ret = v4l2_prio_check(&ch->prio, &fh->prio);
756 if (0 != ret)
757 return ret;
758 fh->initialized = 1;
759 }
760
761 if (common->started) {
762 vpif_dbg(1, debug, "Streaming in progress\n");
763 return -EBUSY;
764 }
765
766 pixfmt = &fmt->fmt.pix;
767 /* Check for valid field format */
768 ret = vpif_check_format(ch, pixfmt);
769 if (ret)
770 return ret;
771
772 /* store the pix format in the channel object */
773 common->fmt.fmt.pix = *pixfmt;
774 /* store the format in the channel object */
775 if (mutex_lock_interruptible(&common->lock))
776 return -ERESTARTSYS;
777
778 common->fmt = *fmt;
779 mutex_unlock(&common->lock);
780
781 return 0;
782}
783
784static int vpif_try_fmt_vid_out(struct file *file, void *priv,
785 struct v4l2_format *fmt)
786{
787 struct vpif_fh *fh = priv;
788 struct channel_obj *ch = fh->channel;
789 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
790 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
791 int ret = 0;
792
793 ret = vpif_check_format(ch, pixfmt);
794 if (ret) {
795 *pixfmt = common->fmt.fmt.pix;
796 pixfmt->sizeimage = pixfmt->width * pixfmt->height * 2;
797 }
798
799 return ret;
800}
801
802static int vpif_reqbufs(struct file *file, void *priv,
803 struct v4l2_requestbuffers *reqbuf)
804{
805 struct vpif_fh *fh = priv;
806 struct channel_obj *ch = fh->channel;
807 struct common_obj *common;
808 enum v4l2_field field;
809 u8 index = 0;
810 int ret = 0;
811
812 /* This file handle has not initialized the channel,
813 It is not allowed to do settings */
814 if ((VPIF_CHANNEL2_VIDEO == ch->channel_id)
815 || (VPIF_CHANNEL3_VIDEO == ch->channel_id)) {
816 if (!fh->initialized) {
817 vpif_err("Channel Busy\n");
818 return -EBUSY;
819 }
820 }
821
822 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != reqbuf->type)
823 return -EINVAL;
824
825 index = VPIF_VIDEO_INDEX;
826
827 common = &ch->common[index];
828 if (mutex_lock_interruptible(&common->lock))
829 return -ERESTARTSYS;
830
831 if (common->fmt.type != reqbuf->type) {
832 ret = -EINVAL;
833 goto reqbuf_exit;
834 }
835
836 if (0 != common->io_usrs) {
837 ret = -EBUSY;
838 goto reqbuf_exit;
839 }
840
841 if (reqbuf->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
842 if (common->fmt.fmt.pix.field == V4L2_FIELD_ANY)
843 field = V4L2_FIELD_INTERLACED;
844 else
845 field = common->fmt.fmt.pix.field;
846 } else {
847 field = V4L2_VBI_INTERLACED;
848 }
849
850 /* Initialize videobuf queue as per the buffer type */
851 videobuf_queue_dma_contig_init(&common->buffer_queue,
852 &video_qops, NULL,
853 &common->irqlock,
854 reqbuf->type, field,
855 sizeof(struct videobuf_buffer), fh);
856
857 /* Set io allowed member of file handle to TRUE */
858 fh->io_allowed[index] = 1;
859 /* Increment io usrs member of channel object to 1 */
860 common->io_usrs = 1;
861 /* Store type of memory requested in channel object */
862 common->memory = reqbuf->memory;
863 INIT_LIST_HEAD(&common->dma_queue);
864
865 /* Allocate buffers */
866 ret = videobuf_reqbufs(&common->buffer_queue, reqbuf);
867
868reqbuf_exit:
869 mutex_unlock(&common->lock);
870 return ret;
871}
872
873static int vpif_querybuf(struct file *file, void *priv,
874 struct v4l2_buffer *tbuf)
875{
876 struct vpif_fh *fh = priv;
877 struct channel_obj *ch = fh->channel;
878 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
879
880 if (common->fmt.type != tbuf->type)
881 return -EINVAL;
882
883 return videobuf_querybuf(&common->buffer_queue, tbuf);
884}
885
886static int vpif_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
887{
888
889 struct vpif_fh *fh = priv;
890 struct channel_obj *ch = fh->channel;
891 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
892 struct v4l2_buffer tbuf = *buf;
893 struct videobuf_buffer *buf1;
894 unsigned long addr = 0;
895 unsigned long flags;
896 int ret = 0;
897
898 if (common->fmt.type != tbuf.type)
899 return -EINVAL;
900
901 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
902 vpif_err("fh->io_allowed\n");
903 return -EACCES;
904 }
905
906 if (!(list_empty(&common->dma_queue)) ||
907 (common->cur_frm != common->next_frm) ||
908 !(common->started) ||
909 (common->started && (0 == ch->field_id)))
910 return videobuf_qbuf(&common->buffer_queue, buf);
911
912 /* bufferqueue is empty store buffer address in VPIF registers */
913 mutex_lock(&common->buffer_queue.vb_lock);
914 buf1 = common->buffer_queue.bufs[tbuf.index];
915 if (buf1->memory != tbuf.memory) {
916 vpif_err("invalid buffer type\n");
917 goto qbuf_exit;
918 }
919
920 if ((buf1->state == VIDEOBUF_QUEUED) ||
921 (buf1->state == VIDEOBUF_ACTIVE)) {
922 vpif_err("invalid state\n");
923 goto qbuf_exit;
924 }
925
926 switch (buf1->memory) {
927 case V4L2_MEMORY_MMAP:
928 if (buf1->baddr == 0)
929 goto qbuf_exit;
930 break;
931
932 case V4L2_MEMORY_USERPTR:
933 if (tbuf.length < buf1->bsize)
934 goto qbuf_exit;
935
936 if ((VIDEOBUF_NEEDS_INIT != buf1->state)
937 && (buf1->baddr != tbuf.m.userptr))
938 vpif_buffer_release(&common->buffer_queue, buf1);
939 buf1->baddr = tbuf.m.userptr;
940 break;
941
942 default:
943 goto qbuf_exit;
944 }
945
946 local_irq_save(flags);
947 ret = vpif_buffer_prepare(&common->buffer_queue, buf1,
948 common->buffer_queue.field);
949 if (ret < 0) {
950 local_irq_restore(flags);
951 goto qbuf_exit;
952 }
953
954 buf1->state = VIDEOBUF_ACTIVE;
955 addr = buf1->boff;
956 common->next_frm = buf1;
957 if (tbuf.type != V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
958 common->set_addr((addr + common->ytop_off),
959 (addr + common->ybtm_off),
960 (addr + common->ctop_off),
961 (addr + common->cbtm_off));
962 }
963
964 local_irq_restore(flags);
965 list_add_tail(&buf1->stream, &common->buffer_queue.stream);
966 mutex_unlock(&common->buffer_queue.vb_lock);
967 return 0;
968
969qbuf_exit:
970 mutex_unlock(&common->buffer_queue.vb_lock);
971 return -EINVAL;
972}
973
974static int vpif_s_std(struct file *file, void *priv, v4l2_std_id *std_id)
975{
976 struct vpif_fh *fh = priv;
977 struct channel_obj *ch = fh->channel;
978 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
979 int ret = 0;
980
981 if (!(*std_id & DM646X_V4L2_STD))
982 return -EINVAL;
983
984 if (common->started) {
985 vpif_err("streaming in progress\n");
986 return -EBUSY;
987 }
988
989 /* Call encoder subdevice function to set the standard */
990 if (mutex_lock_interruptible(&common->lock))
991 return -ERESTARTSYS;
992
993 ch->video.stdid = *std_id;
994 /* Get the information about the standard */
995 if (vpif_get_std_info(ch)) {
996 vpif_err("Error getting the standard info\n");
997 return -EINVAL;
998 }
999
1000 if ((ch->vpifparams.std_info.width *
1001 ch->vpifparams.std_info.height * 2) >
1002 config_params.channel_bufsize[ch->channel_id]) {
1003 vpif_err("invalid std for this size\n");
1004 ret = -EINVAL;
1005 goto s_std_exit;
1006 }
1007
1008 common->fmt.fmt.pix.bytesperline = common->fmt.fmt.pix.width;
1009 /* Configure the default format information */
1010 vpif_config_format(ch);
1011
1012 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
1013 s_std_output, *std_id);
1014 if (ret < 0) {
1015 vpif_err("Failed to set output standard\n");
1016 goto s_std_exit;
1017 }
1018
1019 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, core,
1020 s_std, *std_id);
1021 if (ret < 0)
1022 vpif_err("Failed to set standard for sub devices\n");
1023
1024s_std_exit:
1025 mutex_unlock(&common->lock);
1026 return ret;
1027}
1028
1029static int vpif_g_std(struct file *file, void *priv, v4l2_std_id *std)
1030{
1031 struct vpif_fh *fh = priv;
1032 struct channel_obj *ch = fh->channel;
1033
1034 *std = ch->video.stdid;
1035 return 0;
1036}
1037
1038static int vpif_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
1039{
1040 struct vpif_fh *fh = priv;
1041 struct channel_obj *ch = fh->channel;
1042 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1043
1044 return videobuf_dqbuf(&common->buffer_queue, p,
1045 (file->f_flags & O_NONBLOCK));
1046}
1047
1048static int vpif_streamon(struct file *file, void *priv,
1049 enum v4l2_buf_type buftype)
1050{
1051 struct vpif_fh *fh = priv;
1052 struct channel_obj *ch = fh->channel;
1053 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1054 struct channel_obj *oth_ch = vpif_obj.dev[!ch->channel_id];
1055 struct vpif_params *vpif = &ch->vpifparams;
1056 struct vpif_display_config *vpif_config_data =
1057 vpif_dev->platform_data;
1058 unsigned long addr = 0;
1059 int ret = 0;
1060
1061 if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1062 vpif_err("buffer type not supported\n");
1063 return -EINVAL;
1064 }
1065
1066 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1067 vpif_err("fh->io_allowed\n");
1068 return -EACCES;
1069 }
1070
1071 /* If Streaming is already started, return error */
1072 if (common->started) {
1073 vpif_err("channel->started\n");
1074 return -EBUSY;
1075 }
1076
1077 if ((ch->channel_id == VPIF_CHANNEL2_VIDEO
1078 && oth_ch->common[VPIF_VIDEO_INDEX].started &&
1079 ch->vpifparams.std_info.ycmux_mode == 0)
1080 || ((ch->channel_id == VPIF_CHANNEL3_VIDEO)
1081 && (2 == oth_ch->common[VPIF_VIDEO_INDEX].started))) {
1082 vpif_err("other channel is using\n");
1083 return -EBUSY;
1084 }
1085
1086 ret = vpif_check_format(ch, &common->fmt.fmt.pix);
1087 if (ret < 0)
1088 return ret;
1089
1090 /* Call videobuf_streamon to start streaming in videobuf */
1091 ret = videobuf_streamon(&common->buffer_queue);
1092 if (ret < 0) {
1093 vpif_err("videobuf_streamon\n");
1094 return ret;
1095 }
1096
1097 if (mutex_lock_interruptible(&common->lock))
1098 return -ERESTARTSYS;
1099
1100 /* If buffer queue is empty, return error */
1101 if (list_empty(&common->dma_queue)) {
1102 vpif_err("buffer queue is empty\n");
1103 ret = -EIO;
1104 goto streamon_exit;
1105 }
1106
1107 /* Get the next frame from the buffer queue */
1108 common->next_frm = common->cur_frm =
1109 list_entry(common->dma_queue.next,
1110 struct videobuf_buffer, queue);
1111
1112 list_del(&common->cur_frm->queue);
1113 /* Mark state of the current frame to active */
1114 common->cur_frm->state = VIDEOBUF_ACTIVE;
1115
1116 /* Initialize field_id and started member */
1117 ch->field_id = 0;
1118 common->started = 1;
1119 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1120 addr = common->cur_frm->boff;
1121 /* Calculate the offset for Y and C data in the buffer */
1122 vpif_calculate_offsets(ch);
1123
1124 if ((ch->vpifparams.std_info.frm_fmt &&
1125 ((common->fmt.fmt.pix.field != V4L2_FIELD_NONE)
1126 && (common->fmt.fmt.pix.field != V4L2_FIELD_ANY)))
1127 || (!ch->vpifparams.std_info.frm_fmt
1128 && (common->fmt.fmt.pix.field == V4L2_FIELD_NONE))) {
1129 vpif_err("conflict in field format and std format\n");
1130 ret = -EINVAL;
1131 goto streamon_exit;
1132 }
1133
1134 /* clock settings */
1135 ret =
1136 vpif_config_data->set_clock(ch->vpifparams.std_info.ycmux_mode,
1137 ch->vpifparams.std_info.hd_sd);
1138 if (ret < 0) {
1139 vpif_err("can't set clock\n");
1140 goto streamon_exit;
1141 }
1142
1143 /* set the parameters and addresses */
1144 ret = vpif_set_video_params(vpif, ch->channel_id + 2);
1145 if (ret < 0)
1146 goto streamon_exit;
1147
1148 common->started = ret;
1149 vpif_config_addr(ch, ret);
1150 common->set_addr((addr + common->ytop_off),
1151 (addr + common->ybtm_off),
1152 (addr + common->ctop_off),
1153 (addr + common->cbtm_off));
1154
1155 /* Set interrupt for both the fields in VPIF
1156 Register enable channel in VPIF register */
1157 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1158 channel2_intr_assert();
1159 channel2_intr_enable(1);
1160 enable_channel2(1);
1161 }
1162
1163 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id)
1164 || (common->started == 2)) {
1165 channel3_intr_assert();
1166 channel3_intr_enable(1);
1167 enable_channel3(1);
1168 }
1169 channel_first_int[VPIF_VIDEO_INDEX][ch->channel_id] = 1;
1170 }
1171
1172streamon_exit:
1173 mutex_unlock(&common->lock);
1174 return ret;
1175}
1176
1177static int vpif_streamoff(struct file *file, void *priv,
1178 enum v4l2_buf_type buftype)
1179{
1180 struct vpif_fh *fh = priv;
1181 struct channel_obj *ch = fh->channel;
1182 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1183
1184 if (buftype != V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1185 vpif_err("buffer type not supported\n");
1186 return -EINVAL;
1187 }
1188
1189 if (!fh->io_allowed[VPIF_VIDEO_INDEX]) {
1190 vpif_err("fh->io_allowed\n");
1191 return -EACCES;
1192 }
1193
1194 if (!common->started) {
1195 vpif_err("channel->started\n");
1196 return -EINVAL;
1197 }
1198
1199 if (mutex_lock_interruptible(&common->lock))
1200 return -ERESTARTSYS;
1201
1202 if (buftype == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
1203 /* disable channel */
1204 if (VPIF_CHANNEL2_VIDEO == ch->channel_id) {
1205 enable_channel2(0);
1206 channel2_intr_enable(0);
1207 }
1208 if ((VPIF_CHANNEL3_VIDEO == ch->channel_id) ||
1209 (2 == common->started)) {
1210 enable_channel3(0);
1211 channel3_intr_enable(0);
1212 }
1213 }
1214
1215 common->started = 0;
1216 mutex_unlock(&common->lock);
1217
1218 return videobuf_streamoff(&common->buffer_queue);
1219}
1220
1221static int vpif_cropcap(struct file *file, void *priv,
1222 struct v4l2_cropcap *crop)
1223{
1224 struct vpif_fh *fh = priv;
1225 struct channel_obj *ch = fh->channel;
1226 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1227 if (V4L2_BUF_TYPE_VIDEO_OUTPUT != crop->type)
1228 return -EINVAL;
1229
1230 crop->bounds.left = crop->bounds.top = 0;
1231 crop->defrect.left = crop->defrect.top = 0;
1232 crop->defrect.height = crop->bounds.height = common->height;
1233 crop->defrect.width = crop->bounds.width = common->width;
1234
1235 return 0;
1236}
1237
1238static int vpif_enum_output(struct file *file, void *fh,
1239 struct v4l2_output *output)
1240{
1241
1242 struct vpif_display_config *config = vpif_dev->platform_data;
1243
1244 if (output->index >= config->output_count) {
1245 vpif_dbg(1, debug, "Invalid output index\n");
1246 return -EINVAL;
1247 }
1248
1249 strcpy(output->name, config->output[output->index]);
1250 output->type = V4L2_OUTPUT_TYPE_ANALOG;
1251 output->std = DM646X_V4L2_STD;
1252
1253 return 0;
1254}
1255
1256static int vpif_s_output(struct file *file, void *priv, unsigned int i)
1257{
1258 struct vpif_fh *fh = priv;
1259 struct channel_obj *ch = fh->channel;
1260 struct video_obj *vid_ch = &ch->video;
1261 struct common_obj *common = &ch->common[VPIF_VIDEO_INDEX];
1262 int ret = 0;
1263
1264 if (mutex_lock_interruptible(&common->lock))
1265 return -ERESTARTSYS;
1266
1267 if (common->started) {
1268 vpif_err("Streaming in progress\n");
1269 ret = -EBUSY;
1270 goto s_output_exit;
1271 }
1272
1273 ret = v4l2_device_call_until_err(&vpif_obj.v4l2_dev, 1, video,
1274 s_routing, 0, i, 0);
1275
1276 if (ret < 0)
1277 vpif_err("Failed to set output standard\n");
1278
1279 vid_ch->output_id = i;
1280
1281s_output_exit:
1282 mutex_unlock(&common->lock);
1283 return ret;
1284}
1285
1286static int vpif_g_output(struct file *file, void *priv, unsigned int *i)
1287{
1288 struct vpif_fh *fh = priv;
1289 struct channel_obj *ch = fh->channel;
1290 struct video_obj *vid_ch = &ch->video;
1291
1292 *i = vid_ch->output_id;
1293
1294 return 0;
1295}
1296
1297static int vpif_g_priority(struct file *file, void *priv, enum v4l2_priority *p)
1298{
1299 struct vpif_fh *fh = priv;
1300 struct channel_obj *ch = fh->channel;
1301
1302 *p = v4l2_prio_max(&ch->prio);
1303
1304 return 0;
1305}
1306
1307static int vpif_s_priority(struct file *file, void *priv, enum v4l2_priority p)
1308{
1309 struct vpif_fh *fh = priv;
1310 struct channel_obj *ch = fh->channel;
1311
1312 return v4l2_prio_change(&ch->prio, &fh->prio, p);
1313}
1314
1315/* vpif display ioctl operations */
1316static const struct v4l2_ioctl_ops vpif_ioctl_ops = {
1317 .vidioc_querycap = vpif_querycap,
1318 .vidioc_g_priority = vpif_g_priority,
1319 .vidioc_s_priority = vpif_s_priority,
1320 .vidioc_enum_fmt_vid_out = vpif_enum_fmt_vid_out,
1321 .vidioc_g_fmt_vid_out = vpif_g_fmt_vid_out,
1322 .vidioc_s_fmt_vid_out = vpif_s_fmt_vid_out,
1323 .vidioc_try_fmt_vid_out = vpif_try_fmt_vid_out,
1324 .vidioc_reqbufs = vpif_reqbufs,
1325 .vidioc_querybuf = vpif_querybuf,
1326 .vidioc_qbuf = vpif_qbuf,
1327 .vidioc_dqbuf = vpif_dqbuf,
1328 .vidioc_streamon = vpif_streamon,
1329 .vidioc_streamoff = vpif_streamoff,
1330 .vidioc_s_std = vpif_s_std,
1331 .vidioc_g_std = vpif_g_std,
1332 .vidioc_enum_output = vpif_enum_output,
1333 .vidioc_s_output = vpif_s_output,
1334 .vidioc_g_output = vpif_g_output,
1335 .vidioc_cropcap = vpif_cropcap,
1336};
1337
1338static const struct v4l2_file_operations vpif_fops = {
1339 .owner = THIS_MODULE,
1340 .open = vpif_open,
1341 .release = vpif_release,
1342 .ioctl = video_ioctl2,
1343 .mmap = vpif_mmap,
1344 .poll = vpif_poll
1345};
1346
1347static struct video_device vpif_video_template = {
1348 .name = "vpif",
1349 .fops = &vpif_fops,
1350 .minor = -1,
1351 .ioctl_ops = &vpif_ioctl_ops,
1352 .tvnorms = DM646X_V4L2_STD,
1353 .current_norm = V4L2_STD_625_50,
1354
1355};
1356
1357/*Configure the channels, buffer sizei, request irq */
1358static int initialize_vpif(void)
1359{
1360 int free_channel_objects_index;
1361 int free_buffer_channel_index;
1362 int free_buffer_index;
1363 int err = 0, i, j;
1364
1365 /* Default number of buffers should be 3 */
1366 if ((ch2_numbuffers > 0) &&
1367 (ch2_numbuffers < config_params.min_numbuffers))
1368 ch2_numbuffers = config_params.min_numbuffers;
1369 if ((ch3_numbuffers > 0) &&
1370 (ch3_numbuffers < config_params.min_numbuffers))
1371 ch3_numbuffers = config_params.min_numbuffers;
1372
1373 /* Set buffer size to min buffers size if invalid buffer size is
1374 * given */
1375 if (ch2_bufsize < config_params.min_bufsize[VPIF_CHANNEL2_VIDEO])
1376 ch2_bufsize =
1377 config_params.min_bufsize[VPIF_CHANNEL2_VIDEO];
1378 if (ch3_bufsize < config_params.min_bufsize[VPIF_CHANNEL3_VIDEO])
1379 ch3_bufsize =
1380 config_params.min_bufsize[VPIF_CHANNEL3_VIDEO];
1381
1382 config_params.numbuffers[VPIF_CHANNEL2_VIDEO] = ch2_numbuffers;
1383
1384 if (ch2_numbuffers) {
1385 config_params.channel_bufsize[VPIF_CHANNEL2_VIDEO] =
1386 ch2_bufsize;
1387 }
1388 config_params.numbuffers[VPIF_CHANNEL3_VIDEO] = ch3_numbuffers;
1389
1390 if (ch3_numbuffers) {
1391 config_params.channel_bufsize[VPIF_CHANNEL3_VIDEO] =
1392 ch3_bufsize;
1393 }
1394
1395 /* Allocate memory for six channel objects */
1396 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1397 vpif_obj.dev[i] =
1398 kmalloc(sizeof(struct channel_obj), GFP_KERNEL);
1399 /* If memory allocation fails, return error */
1400 if (!vpif_obj.dev[i]) {
1401 free_channel_objects_index = i;
1402 err = -ENOMEM;
1403 goto vpif_init_free_channel_objects;
1404 }
1405 }
1406
1407 free_channel_objects_index = VPIF_DISPLAY_MAX_DEVICES;
1408 free_buffer_channel_index = VPIF_DISPLAY_NUM_CHANNELS;
1409 free_buffer_index = config_params.numbuffers[i - 1];
1410
1411 return 0;
1412
1413vpif_init_free_channel_objects:
1414 for (j = 0; j < free_channel_objects_index; j++)
1415 kfree(vpif_obj.dev[j]);
1416 return err;
1417}
1418
1419/*
1420 * vpif_probe: This function creates device entries by register itself to the
1421 * V4L2 driver and initializes fields of each channel objects
1422 */
1423static __init int vpif_probe(struct platform_device *pdev)
1424{
1425 struct vpif_subdev_info *subdevdata;
1426 struct vpif_display_config *config;
1427 int i, j = 0, k, q, m, err = 0;
1428 struct i2c_adapter *i2c_adap;
1429 struct vpif_config *config;
1430 struct common_obj *common;
1431 struct channel_obj *ch;
1432 struct video_device *vfd;
1433 struct resource *res;
1434 int subdev_count;
1435
1436 vpif_dev = &pdev->dev;
1437
1438 err = initialize_vpif();
1439
1440 if (err) {
1441 v4l2_err(vpif_dev->driver, "Error initializing vpif\n");
1442 return err;
1443 }
1444
1445 err = v4l2_device_register(vpif_dev, &vpif_obj.v4l2_dev);
1446 if (err) {
1447 v4l2_err(vpif_dev->driver, "Error registering v4l2 device\n");
1448 return err;
1449 }
1450
1451 k = 0;
1452 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, k))) {
1453 for (i = res->start; i <= res->end; i++) {
1454 if (request_irq(i, vpif_channel_isr, IRQF_DISABLED,
1455 "DM646x_Display",
1456 (void *)(&vpif_obj.dev[k]->channel_id))) {
1457 err = -EBUSY;
1458 goto vpif_int_err;
1459 }
1460 }
1461 k++;
1462 }
1463
1464 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1465
1466 /* Get the pointer to the channel object */
1467 ch = vpif_obj.dev[i];
1468
1469 /* Allocate memory for video device */
1470 vfd = video_device_alloc();
1471 if (vfd == NULL) {
1472 for (j = 0; j < i; j++) {
1473 ch = vpif_obj.dev[j];
1474 video_device_release(ch->video_dev);
1475 }
1476 err = -ENOMEM;
1477 goto vpif_int_err;
1478 }
1479
1480 /* Initialize field of video device */
1481 *vfd = vpif_video_template;
1482 vfd->v4l2_dev = &vpif_obj.v4l2_dev;
1483 vfd->release = video_device_release;
1484 snprintf(vfd->name, sizeof(vfd->name),
1485 "DM646x_VPIFDisplay_DRIVER_V%d.%d.%d",
1486 (VPIF_DISPLAY_VERSION_CODE >> 16) & 0xff,
1487 (VPIF_DISPLAY_VERSION_CODE >> 8) & 0xff,
1488 (VPIF_DISPLAY_VERSION_CODE) & 0xff);
1489
1490 /* Set video_dev to the video device */
1491 ch->video_dev = vfd;
1492 }
1493
1494 for (j = 0; j < VPIF_DISPLAY_MAX_DEVICES; j++) {
1495 ch = vpif_obj.dev[j];
1496 /* Initialize field of the channel objects */
1497 atomic_set(&ch->usrs, 0);
1498 for (k = 0; k < VPIF_NUMOBJECTS; k++) {
1499 ch->common[k].numbuffers = 0;
1500 common = &ch->common[k];
1501 common->io_usrs = 0;
1502 common->started = 0;
1503 spin_lock_init(&common->irqlock);
1504 mutex_init(&common->lock);
1505 common->numbuffers = 0;
1506 common->set_addr = NULL;
1507 common->ytop_off = common->ybtm_off = 0;
1508 common->ctop_off = common->cbtm_off = 0;
1509 common->cur_frm = common->next_frm = NULL;
1510 memset(&common->fmt, 0, sizeof(common->fmt));
1511 common->numbuffers = config_params.numbuffers[k];
1512
1513 }
1514 ch->initialized = 0;
1515 ch->channel_id = j;
1516 if (j < 2)
1517 ch->common[VPIF_VIDEO_INDEX].numbuffers =
1518 config_params.numbuffers[ch->channel_id];
1519 else
1520 ch->common[VPIF_VIDEO_INDEX].numbuffers = 0;
1521
1522 memset(&ch->vpifparams, 0, sizeof(ch->vpifparams));
1523
1524 /* Initialize prio member of channel object */
1525 v4l2_prio_init(&ch->prio);
1526 ch->common[VPIF_VIDEO_INDEX].fmt.type =
1527 V4L2_BUF_TYPE_VIDEO_OUTPUT;
1528
1529 /* register video device */
1530 vpif_dbg(1, debug, "channel=%x,channel->video_dev=%x\n",
1531 (int)ch, (int)&ch->video_dev);
1532
1533 err = video_register_device(ch->video_dev,
1534 VFL_TYPE_GRABBER, (j ? 3 : 2));
1535 if (err < 0)
1536 goto probe_out;
1537
1538 video_set_drvdata(ch->video_dev, ch);
1539 }
1540
1541 i2c_adap = i2c_get_adapter(1);
1542 config = pdev->dev.platform_data;
1543 subdev_count = config->subdev_count;
1544 subdevdata = config->subdevinfo;
1545 vpif_obj.sd = kmalloc(sizeof(struct v4l2_subdev *) * subdev_count,
1546 GFP_KERNEL);
1547 if (vpif_obj.sd == NULL) {
1548 vpif_err("unable to allocate memory for subdevice pointers\n");
1549 err = -ENOMEM;
1550 goto probe_out;
1551 }
1552
1553 for (i = 0; i < subdev_count; i++) {
1554 vpif_obj.sd[i] = v4l2_i2c_new_subdev_board(&vpif_obj.v4l2_dev,
1555 i2c_adap, subdevdata[i].name,
1556 &subdevdata[i].board_info,
1557 NULL);
1558 if (!vpif_obj.sd[i]) {
1559 vpif_err("Error registering v4l2 subdevice\n");
1560 goto probe_subdev_out;
1561 }
1562
1563 if (vpif_obj.sd[i])
1564 vpif_obj.sd[i]->grp_id = 1 << i;
1565 }
1566
1567 return 0;
1568
1569probe_subdev_out:
1570 kfree(vpif_obj.sd);
1571probe_out:
1572 for (k = 0; k < j; k++) {
1573 ch = vpif_obj.dev[k];
1574 video_unregister_device(ch->video_dev);
1575 video_device_release(ch->video_dev);
1576 ch->video_dev = NULL;
1577 }
1578vpif_int_err:
1579 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1580 vpif_err("VPIF IRQ request failed\n");
1581 for (q = k; k >= 0; k--) {
1582 for (m = i; m >= res->start; m--)
1583 free_irq(m, (void *)(&vpif_obj.dev[k]->channel_id));
1584 res = platform_get_resource(pdev, IORESOURCE_IRQ, k-1);
1585 m = res->end;
1586 }
1587
1588 return err;
1589}
1590
1591/*
1592 * vpif_remove: It un-register channels from V4L2 driver
1593 */
1594static int vpif_remove(struct platform_device *device)
1595{
1596 struct channel_obj *ch;
1597 int i;
1598
1599 v4l2_device_unregister(&vpif_obj.v4l2_dev);
1600
1601 /* un-register device */
1602 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++) {
1603 /* Get the pointer to the channel object */
1604 ch = vpif_obj.dev[i];
1605 /* Unregister video device */
1606 video_unregister_device(ch->video_dev);
1607
1608 ch->video_dev = NULL;
1609 }
1610
1611 return 0;
1612}
1613
1614static struct platform_driver vpif_driver = {
1615 .driver = {
1616 .name = "vpif_display",
1617 .owner = THIS_MODULE,
1618 },
1619 .probe = vpif_probe,
1620 .remove = vpif_remove,
1621};
1622
1623static __init int vpif_init(void)
1624{
1625 return platform_driver_register(&vpif_driver);
1626}
1627
1628/*
1629 * vpif_cleanup: This function un-registers device and driver to the kernel,
1630 * frees requested irq handler and de-allocates memory allocated for channel
1631 * objects.
1632 */
1633static void vpif_cleanup(void)
1634{
1635 struct platform_device *pdev;
1636 struct resource *res;
1637 int irq_num;
1638 int i = 0;
1639
1640 pdev = container_of(vpif_dev, struct platform_device, dev);
1641
1642 while ((res = platform_get_resource(pdev, IORESOURCE_IRQ, i))) {
1643 for (irq_num = res->start; irq_num <= res->end; irq_num++)
1644 free_irq(irq_num,
1645 (void *)(&vpif_obj.dev[i]->channel_id));
1646 i++;
1647 }
1648
1649 platform_driver_unregister(&vpif_driver);
1650 kfree(vpif_obj.sd);
1651 for (i = 0; i < VPIF_DISPLAY_MAX_DEVICES; i++)
1652 kfree(vpif_obj.dev[i]);
1653}
1654
1655module_init(vpif_init);
1656module_exit(vpif_cleanup);
diff --git a/drivers/media/video/davinci/vpif_display.h b/drivers/media/video/davinci/vpif_display.h
new file mode 100644
index 000000000000..a2a7cd166bbf
--- /dev/null
+++ b/drivers/media/video/davinci/vpif_display.h
@@ -0,0 +1,175 @@
1/*
2 * DM646x display header file
3 *
4 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
9 *
10 * This program is distributed .as is. WITHOUT ANY WARRANTY of any
11 * kind, whether express or implied; without even the implied warranty
12 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#ifndef DAVINCIHD_DISPLAY_H
17#define DAVINCIHD_DISPLAY_H
18
19/* Header files */
20#include <linux/videodev2.h>
21#include <linux/version.h>
22#include <media/v4l2-common.h>
23#include <media/v4l2-device.h>
24#include <media/videobuf-core.h>
25#include <media/videobuf-dma-contig.h>
26
27#include "vpif.h"
28
29/* Macros */
30#define VPIF_MAJOR_RELEASE (0)
31#define VPIF_MINOR_RELEASE (0)
32#define VPIF_BUILD (1)
33
34#define VPIF_DISPLAY_VERSION_CODE \
35 ((VPIF_MAJOR_RELEASE << 16) | (VPIF_MINOR_RELEASE << 8) | VPIF_BUILD)
36
37#define VPIF_VALID_FIELD(field) \
38 (((V4L2_FIELD_ANY == field) || (V4L2_FIELD_NONE == field)) || \
39 (((V4L2_FIELD_INTERLACED == field) || (V4L2_FIELD_SEQ_TB == field)) || \
40 (V4L2_FIELD_SEQ_BT == field)))
41
42#define VPIF_DISPLAY_MAX_DEVICES (2)
43#define VPIF_SLICED_BUF_SIZE (256)
44#define VPIF_SLICED_MAX_SERVICES (3)
45#define VPIF_VIDEO_INDEX (0)
46#define VPIF_VBI_INDEX (1)
47#define VPIF_HBI_INDEX (2)
48
49/* Setting it to 1 as HBI/VBI support yet to be added , else 3*/
50#define VPIF_NUMOBJECTS (1)
51
52/* Macros */
53#define ISALIGNED(a) (0 == ((a) & 7))
54
55/* enumerated data types */
56/* Enumerated data type to give id to each device per channel */
57enum vpif_channel_id {
58 VPIF_CHANNEL2_VIDEO = 0, /* Channel2 Video */
59 VPIF_CHANNEL3_VIDEO, /* Channel3 Video */
60};
61
62/* structures */
63
64struct video_obj {
65 enum v4l2_field buf_field;
66 u32 latest_only; /* indicate whether to return
67 * most recent displayed frame only */
68 v4l2_std_id stdid; /* Currently selected or default
69 * standard */
70 u32 output_id; /* Current output id */
71};
72
73struct vbi_obj {
74 int num_services;
75 struct vpif_vbi_params vbiparams; /* vpif parameters for the raw
76 * vbi data */
77};
78
79struct common_obj {
80 /* Buffer specific parameters */
81 u8 *fbuffers[VIDEO_MAX_FRAME]; /* List of buffer pointers for
82 * storing frames */
83 u32 numbuffers; /* number of buffers */
84 struct videobuf_buffer *cur_frm; /* Pointer pointing to current
85 * videobuf_buffer */
86 struct videobuf_buffer *next_frm; /* Pointer pointing to next
87 * videobuf_buffer */
88 enum v4l2_memory memory; /* This field keeps track of
89 * type of buffer exchange
90 * method user has selected */
91 struct v4l2_format fmt; /* Used to store the format */
92 struct videobuf_queue buffer_queue; /* Buffer queue used in
93 * video-buf */
94 struct list_head dma_queue; /* Queue of filled frames */
95 spinlock_t irqlock; /* Used in video-buf */
96
97 /* channel specific parameters */
98 struct mutex lock; /* lock used to access this
99 * structure */
100 u32 io_usrs; /* number of users performing
101 * IO */
102 u8 started; /* Indicates whether streaming
103 * started */
104 u32 ytop_off; /* offset of Y top from the
105 * starting of the buffer */
106 u32 ybtm_off; /* offset of Y bottom from the
107 * starting of the buffer */
108 u32 ctop_off; /* offset of C top from the
109 * starting of the buffer */
110 u32 cbtm_off; /* offset of C bottom from the
111 * starting of the buffer */
112 /* Function pointer to set the addresses */
113 void (*set_addr) (unsigned long, unsigned long,
114 unsigned long, unsigned long);
115 u32 height;
116 u32 width;
117};
118
119struct channel_obj {
120 /* V4l2 specific parameters */
121 struct video_device *video_dev; /* Identifies video device for
122 * this channel */
123 struct v4l2_prio_state prio; /* Used to keep track of state of
124 * the priority */
125 atomic_t usrs; /* number of open instances of
126 * the channel */
127 u32 field_id; /* Indicates id of the field
128 * which is being displayed */
129 u8 initialized; /* flag to indicate whether
130 * encoder is initialized */
131
132 enum vpif_channel_id channel_id;/* Identifies channel */
133 struct vpif_params vpifparams;
134 struct common_obj common[VPIF_NUMOBJECTS];
135 struct video_obj video;
136 struct vbi_obj vbi;
137};
138
139/* File handle structure */
140struct vpif_fh {
141 struct channel_obj *channel; /* pointer to channel object for
142 * opened device */
143 u8 io_allowed[VPIF_NUMOBJECTS]; /* Indicates whether this file handle
144 * is doing IO */
145 enum v4l2_priority prio; /* Used to keep track priority of
146 * this instance */
147 u8 initialized; /* Used to keep track of whether this
148 * file handle has initialized
149 * channel or not */
150};
151
152/* vpif device structure */
153struct vpif_device {
154 struct v4l2_device v4l2_dev;
155 struct channel_obj *dev[VPIF_DISPLAY_NUM_CHANNELS];
156 struct v4l2_subdev **sd;
157
158};
159
160struct vpif_config_params {
161 u32 min_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
162 u32 channel_bufsize[VPIF_DISPLAY_NUM_CHANNELS];
163 u8 numbuffers[VPIF_DISPLAY_NUM_CHANNELS];
164 u8 min_numbuffers;
165};
166
167/* Struct which keeps track of the line numbers for the sliced vbi service */
168struct vpif_service_line {
169 u16 service_id;
170 u16 service_line[2];
171 u16 enc_service_id;
172 u8 bytestowrite;
173};
174
175#endif /* DAVINCIHD_DISPLAY_H */
diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c
new file mode 100644
index 000000000000..6d709ca8cfb0
--- /dev/null
+++ b/drivers/media/video/davinci/vpss.c
@@ -0,0 +1,301 @@
1/*
2 * Copyright (C) 2009 Texas Instruments.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 *
18 * common vpss driver for all video drivers.
19 */
20#include <linux/kernel.h>
21#include <linux/sched.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/platform_device.h>
25#include <linux/spinlock.h>
26#include <linux/compiler.h>
27#include <linux/io.h>
28#include <mach/hardware.h>
29#include <media/davinci/vpss.h>
30
31MODULE_LICENSE("GPL");
32MODULE_DESCRIPTION("VPSS Driver");
33MODULE_AUTHOR("Texas Instruments");
34
35/* DM644x defines */
36#define DM644X_SBL_PCR_VPSS (4)
37
38/* vpss BL register offsets */
39#define DM355_VPSSBL_CCDCMUX 0x1c
40/* vpss CLK register offsets */
41#define DM355_VPSSCLK_CLKCTRL 0x04
42/* masks and shifts */
43#define VPSS_HSSISEL_SHIFT 4
44
45/*
46 * vpss operations. Depends on platform. Not all functions are available
47 * on all platforms. The api, first check if a functio is available before
48 * invoking it. In the probe, the function ptrs are intialized based on
49 * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc.
50 */
51struct vpss_hw_ops {
52 /* enable clock */
53 int (*enable_clock)(enum vpss_clock_sel clock_sel, int en);
54 /* select input to ccdc */
55 void (*select_ccdc_source)(enum vpss_ccdc_source_sel src_sel);
56 /* clear wbl overlflow bit */
57 int (*clear_wbl_overflow)(enum vpss_wbl_sel wbl_sel);
58};
59
60/* vpss configuration */
61struct vpss_oper_config {
62 __iomem void *vpss_bl_regs_base;
63 __iomem void *vpss_regs_base;
64 struct resource *r1;
65 resource_size_t len1;
66 struct resource *r2;
67 resource_size_t len2;
68 char vpss_name[32];
69 spinlock_t vpss_lock;
70 struct vpss_hw_ops hw_ops;
71};
72
73static struct vpss_oper_config oper_cfg;
74
75/* register access routines */
76static inline u32 bl_regr(u32 offset)
77{
78 return __raw_readl(oper_cfg.vpss_bl_regs_base + offset);
79}
80
81static inline void bl_regw(u32 val, u32 offset)
82{
83 __raw_writel(val, oper_cfg.vpss_bl_regs_base + offset);
84}
85
86static inline u32 vpss_regr(u32 offset)
87{
88 return __raw_readl(oper_cfg.vpss_regs_base + offset);
89}
90
91static inline void vpss_regw(u32 val, u32 offset)
92{
93 __raw_writel(val, oper_cfg.vpss_regs_base + offset);
94}
95
96static void dm355_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
97{
98 bl_regw(src_sel << VPSS_HSSISEL_SHIFT, DM355_VPSSBL_CCDCMUX);
99}
100
101int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel)
102{
103 if (!oper_cfg.hw_ops.select_ccdc_source)
104 return -1;
105
106 dm355_select_ccdc_source(src_sel);
107 return 0;
108}
109EXPORT_SYMBOL(vpss_select_ccdc_source);
110
111static int dm644x_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
112{
113 u32 mask = 1, val;
114
115 if (wbl_sel < VPSS_PCR_AEW_WBL_0 ||
116 wbl_sel > VPSS_PCR_CCDC_WBL_O)
117 return -1;
118
119 /* writing a 0 clear the overflow */
120 mask = ~(mask << wbl_sel);
121 val = bl_regr(DM644X_SBL_PCR_VPSS) & mask;
122 bl_regw(val, DM644X_SBL_PCR_VPSS);
123 return 0;
124}
125
126int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel)
127{
128 if (!oper_cfg.hw_ops.clear_wbl_overflow)
129 return -1;
130
131 return oper_cfg.hw_ops.clear_wbl_overflow(wbl_sel);
132}
133EXPORT_SYMBOL(vpss_clear_wbl_overflow);
134
135/*
136 * dm355_enable_clock - Enable VPSS Clock
137 * @clock_sel: CLock to be enabled/disabled
138 * @en: enable/disable flag
139 *
140 * This is called to enable or disable a vpss clock
141 */
142static int dm355_enable_clock(enum vpss_clock_sel clock_sel, int en)
143{
144 unsigned long flags;
145 u32 utemp, mask = 0x1, shift = 0;
146
147 switch (clock_sel) {
148 case VPSS_VPBE_CLOCK:
149 /* nothing since lsb */
150 break;
151 case VPSS_VENC_CLOCK_SEL:
152 shift = 2;
153 break;
154 case VPSS_CFALD_CLOCK:
155 shift = 3;
156 break;
157 case VPSS_H3A_CLOCK:
158 shift = 4;
159 break;
160 case VPSS_IPIPE_CLOCK:
161 shift = 5;
162 break;
163 case VPSS_CCDC_CLOCK:
164 shift = 6;
165 break;
166 default:
167 printk(KERN_ERR "dm355_enable_clock:"
168 " Invalid selector: %d\n", clock_sel);
169 return -1;
170 }
171
172 spin_lock_irqsave(&oper_cfg.vpss_lock, flags);
173 utemp = vpss_regr(DM355_VPSSCLK_CLKCTRL);
174 if (!en)
175 utemp &= ~(mask << shift);
176 else
177 utemp |= (mask << shift);
178
179 vpss_regw(utemp, DM355_VPSSCLK_CLKCTRL);
180 spin_unlock_irqrestore(&oper_cfg.vpss_lock, flags);
181 return 0;
182}
183
184int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en)
185{
186 if (!oper_cfg.hw_ops.enable_clock)
187 return -1;
188
189 return oper_cfg.hw_ops.enable_clock(clock_sel, en);
190}
191EXPORT_SYMBOL(vpss_enable_clock);
192
193static int __init vpss_probe(struct platform_device *pdev)
194{
195 int status, dm355 = 0;
196
197 if (!pdev->dev.platform_data) {
198 dev_err(&pdev->dev, "no platform data\n");
199 return -ENOENT;
200 }
201 strcpy(oper_cfg.vpss_name, pdev->dev.platform_data);
202
203 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss"))
204 dm355 = 1;
205 else if (strcmp(oper_cfg.vpss_name, "dm644x_vpss")) {
206 dev_err(&pdev->dev, "vpss driver not supported on"
207 " this platform\n");
208 return -ENODEV;
209 }
210
211 dev_info(&pdev->dev, "%s vpss probed\n", oper_cfg.vpss_name);
212 oper_cfg.r1 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
213 if (!oper_cfg.r1)
214 return -ENOENT;
215
216 oper_cfg.len1 = oper_cfg.r1->end - oper_cfg.r1->start + 1;
217
218 oper_cfg.r1 = request_mem_region(oper_cfg.r1->start, oper_cfg.len1,
219 oper_cfg.r1->name);
220 if (!oper_cfg.r1)
221 return -EBUSY;
222
223 oper_cfg.vpss_bl_regs_base = ioremap(oper_cfg.r1->start, oper_cfg.len1);
224 if (!oper_cfg.vpss_bl_regs_base) {
225 status = -EBUSY;
226 goto fail1;
227 }
228
229 if (dm355) {
230 oper_cfg.r2 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
231 if (!oper_cfg.r2) {
232 status = -ENOENT;
233 goto fail2;
234 }
235 oper_cfg.len2 = oper_cfg.r2->end - oper_cfg.r2->start + 1;
236 oper_cfg.r2 = request_mem_region(oper_cfg.r2->start,
237 oper_cfg.len2,
238 oper_cfg.r2->name);
239 if (!oper_cfg.r2) {
240 status = -EBUSY;
241 goto fail2;
242 }
243
244 oper_cfg.vpss_regs_base = ioremap(oper_cfg.r2->start,
245 oper_cfg.len2);
246 if (!oper_cfg.vpss_regs_base) {
247 status = -EBUSY;
248 goto fail3;
249 }
250 }
251
252 if (dm355) {
253 oper_cfg.hw_ops.enable_clock = dm355_enable_clock;
254 oper_cfg.hw_ops.select_ccdc_source = dm355_select_ccdc_source;
255 } else
256 oper_cfg.hw_ops.clear_wbl_overflow = dm644x_clear_wbl_overflow;
257
258 spin_lock_init(&oper_cfg.vpss_lock);
259 dev_info(&pdev->dev, "%s vpss probe success\n", oper_cfg.vpss_name);
260 return 0;
261
262fail3:
263 release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
264fail2:
265 iounmap(oper_cfg.vpss_bl_regs_base);
266fail1:
267 release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
268 return status;
269}
270
271static int vpss_remove(struct platform_device *pdev)
272{
273 iounmap(oper_cfg.vpss_bl_regs_base);
274 release_mem_region(oper_cfg.r1->start, oper_cfg.len1);
275 if (!strcmp(oper_cfg.vpss_name, "dm355_vpss")) {
276 iounmap(oper_cfg.vpss_regs_base);
277 release_mem_region(oper_cfg.r2->start, oper_cfg.len2);
278 }
279 return 0;
280}
281
282static struct platform_driver vpss_driver = {
283 .driver = {
284 .name = "vpss",
285 .owner = THIS_MODULE,
286 },
287 .remove = __devexit_p(vpss_remove),
288 .probe = vpss_probe,
289};
290
291static void vpss_exit(void)
292{
293 platform_driver_unregister(&vpss_driver);
294}
295
296static int __init vpss_init(void)
297{
298 return platform_driver_register(&vpss_driver);
299}
300subsys_initcall(vpss_init);
301module_exit(vpss_exit);
diff --git a/drivers/media/video/em28xx/Kconfig b/drivers/media/video/em28xx/Kconfig
index 6524b493e033..c7be0e097828 100644
--- a/drivers/media/video/em28xx/Kconfig
+++ b/drivers/media/video/em28xx/Kconfig
@@ -36,6 +36,7 @@ config VIDEO_EM28XX_DVB
36 depends on VIDEO_EM28XX && DVB_CORE 36 depends on VIDEO_EM28XX && DVB_CORE
37 select DVB_LGDT330X if !DVB_FE_CUSTOMISE 37 select DVB_LGDT330X if !DVB_FE_CUSTOMISE
38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE 38 select DVB_ZL10353 if !DVB_FE_CUSTOMISE
39 select DVB_TDA10023 if !DVB_FE_CUSTOMISE
39 select VIDEOBUF_DVB 40 select VIDEOBUF_DVB
40 ---help--- 41 ---help---
41 This adds support for DVB cards based on the 42 This adds support for DVB cards based on the
diff --git a/drivers/media/video/em28xx/Makefile b/drivers/media/video/em28xx/Makefile
index 8137a8c94bfc..d0f093d1d0df 100644
--- a/drivers/media/video/em28xx/Makefile
+++ b/drivers/media/video/em28xx/Makefile
@@ -1,5 +1,5 @@
1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \ 1em28xx-objs := em28xx-video.o em28xx-i2c.o em28xx-cards.o em28xx-core.o \
2 em28xx-input.o 2 em28xx-input.o em28xx-vbi.o
3 3
4em28xx-alsa-objs := em28xx-audio.o 4em28xx-alsa-objs := em28xx-audio.o
5 5
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 7e3c78239fa9..bdb249bd9d5d 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -170,6 +170,19 @@ static struct em28xx_reg_seq pinnacle_hybrid_pro_digital[] = {
170 { -1, -1, -1, -1}, 170 { -1, -1, -1, -1},
171}; 171};
172 172
173/* eb1a:2868 Reddo DVB-C USB TV Box
174 GPIO4 - CU1216L NIM
175 Other GPIOs seems to be don't care. */
176static struct em28xx_reg_seq reddo_dvb_c_usb_box[] = {
177 {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
178 {EM28XX_R08_GPIO, 0xde, 0xff, 10},
179 {EM28XX_R08_GPIO, 0xfe, 0xff, 10},
180 {EM28XX_R08_GPIO, 0xff, 0xff, 10},
181 {EM28XX_R08_GPIO, 0x7f, 0xff, 10},
182 {EM28XX_R08_GPIO, 0x6f, 0xff, 10},
183 {EM28XX_R08_GPIO, 0xff, 0xff, 10},
184 {-1, -1, -1, -1},
185};
173 186
174/* Callback for the most boards */ 187/* Callback for the most boards */
175static struct em28xx_reg_seq default_tuner_gpio[] = { 188static struct em28xx_reg_seq default_tuner_gpio[] = {
@@ -1566,6 +1579,14 @@ struct em28xx_board em28xx_boards[] = {
1566 .gpio = evga_indtube_analog, 1579 .gpio = evga_indtube_analog,
1567 } }, 1580 } },
1568 }, 1581 },
1582 /* eb1a:2868 Empia EM2870 + Philips CU1216L NIM (Philips TDA10023 +
1583 Infineon TUA6034) */
1584 [EM2870_BOARD_REDDO_DVB_C_USB_BOX] = {
1585 .name = "Reddo DVB-C USB TV Box",
1586 .tuner_type = TUNER_ABSENT,
1587 .has_dvb = 1,
1588 .dvb_gpio = reddo_dvb_c_usb_box,
1589 },
1569}; 1590};
1570const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards); 1591const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
1571 1592
@@ -1593,6 +1614,8 @@ struct usb_device_id em28xx_id_table[] = {
1593 .driver_info = EM2820_BOARD_UNKNOWN }, 1614 .driver_info = EM2820_BOARD_UNKNOWN },
1594 { USB_DEVICE(0xeb1a, 0x2883), 1615 { USB_DEVICE(0xeb1a, 0x2883),
1595 .driver_info = EM2820_BOARD_UNKNOWN }, 1616 .driver_info = EM2820_BOARD_UNKNOWN },
1617 { USB_DEVICE(0xeb1a, 0x2868),
1618 .driver_info = EM2820_BOARD_UNKNOWN },
1596 { USB_DEVICE(0xeb1a, 0xe300), 1619 { USB_DEVICE(0xeb1a, 0xe300),
1597 .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U }, 1620 .driver_info = EM2861_BOARD_KWORLD_PVRTV_300U },
1598 { USB_DEVICE(0xeb1a, 0xe303), 1621 { USB_DEVICE(0xeb1a, 0xe303),
@@ -1696,6 +1719,7 @@ static struct em28xx_hash_table em28xx_eeprom_hash[] = {
1696 {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028}, 1719 {0x166a0441, EM2880_BOARD_EMPIRE_DUAL_TV, TUNER_XC2028},
1697 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028}, 1720 {0xcee44a99, EM2882_BOARD_EVGA_INDTUBE, TUNER_XC2028},
1698 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028}, 1721 {0xb8846b20, EM2881_BOARD_PINNACLE_HYBRID_PRO, TUNER_XC2028},
1722 {0x63f653bd, EM2870_BOARD_REDDO_DVB_C_USB_BOX, TUNER_ABSENT},
1699}; 1723};
1700 1724
1701/* I2C devicelist hash table for devices with generic USB IDs */ 1725/* I2C devicelist hash table for devices with generic USB IDs */
@@ -2348,55 +2372,55 @@ void em28xx_card_setup(struct em28xx *dev)
2348 2372
2349 /* request some modules */ 2373 /* request some modules */
2350 if (dev->board.has_msp34xx) 2374 if (dev->board.has_msp34xx)
2351 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2375 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2352 "msp3400", "msp3400", msp3400_addrs); 2376 "msp3400", "msp3400", 0, msp3400_addrs);
2353 2377
2354 if (dev->board.decoder == EM28XX_SAA711X) 2378 if (dev->board.decoder == EM28XX_SAA711X)
2355 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2379 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2356 "saa7115", "saa7115_auto", saa711x_addrs); 2380 "saa7115", "saa7115_auto", 0, saa711x_addrs);
2357 2381
2358 if (dev->board.decoder == EM28XX_TVP5150) 2382 if (dev->board.decoder == EM28XX_TVP5150)
2359 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2383 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2360 "tvp5150", "tvp5150", tvp5150_addrs); 2384 "tvp5150", "tvp5150", 0, tvp5150_addrs);
2361 2385
2362 if (dev->em28xx_sensor == EM28XX_MT9V011) { 2386 if (dev->em28xx_sensor == EM28XX_MT9V011) {
2363 struct v4l2_subdev *sd; 2387 struct v4l2_subdev *sd;
2364 2388
2365 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2389 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2366 &dev->i2c_adap, "mt9v011", "mt9v011", mt9v011_addrs); 2390 &dev->i2c_adap, "mt9v011", "mt9v011", 0, mt9v011_addrs);
2367 v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal); 2391 v4l2_subdev_call(sd, core, s_config, 0, &dev->sensor_xtal);
2368 } 2392 }
2369 2393
2370 2394
2371 if (dev->board.adecoder == EM28XX_TVAUDIO) 2395 if (dev->board.adecoder == EM28XX_TVAUDIO)
2372 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2396 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2373 "tvaudio", "tvaudio", dev->board.tvaudio_addr); 2397 "tvaudio", "tvaudio", dev->board.tvaudio_addr, NULL);
2374 2398
2375 if (dev->board.tuner_type != TUNER_ABSENT) { 2399 if (dev->board.tuner_type != TUNER_ABSENT) {
2376 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT); 2400 int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
2377 2401
2378 if (dev->board.radio.type) 2402 if (dev->board.radio.type)
2379 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2403 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2380 "tuner", "tuner", dev->board.radio_addr); 2404 "tuner", "tuner", dev->board.radio_addr, NULL);
2381 2405
2382 if (has_demod) 2406 if (has_demod)
2383 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2407 v4l2_i2c_new_subdev(&dev->v4l2_dev,
2384 &dev->i2c_adap, "tuner", "tuner", 2408 &dev->i2c_adap, "tuner", "tuner",
2385 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 2409 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
2386 if (dev->tuner_addr == 0) { 2410 if (dev->tuner_addr == 0) {
2387 enum v4l2_i2c_tuner_type type = 2411 enum v4l2_i2c_tuner_type type =
2388 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; 2412 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
2389 struct v4l2_subdev *sd; 2413 struct v4l2_subdev *sd;
2390 2414
2391 sd = v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 2415 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
2392 &dev->i2c_adap, "tuner", "tuner", 2416 &dev->i2c_adap, "tuner", "tuner",
2393 v4l2_i2c_tuner_addrs(type)); 2417 0, v4l2_i2c_tuner_addrs(type));
2394 2418
2395 if (sd) 2419 if (sd)
2396 dev->tuner_addr = v4l2_i2c_subdev_addr(sd); 2420 dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
2397 } else { 2421 } else {
2398 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 2422 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
2399 "tuner", "tuner", dev->tuner_addr); 2423 "tuner", "tuner", dev->tuner_addr, NULL);
2400 } 2424 }
2401 } 2425 }
2402 2426
@@ -2570,7 +2594,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2570 * Default format, used for tvp5150 or saa711x output formats 2594 * Default format, used for tvp5150 or saa711x output formats
2571 */ 2595 */
2572 dev->vinmode = 0x10; 2596 dev->vinmode = 0x10;
2573 dev->vinctl = 0x11; 2597 dev->vinctl = EM28XX_VINCTRL_INTERLACED |
2598 EM28XX_VINCTRL_CCIR656_ENABLE;
2574 2599
2575 /* Do board specific init and eeprom reading */ 2600 /* Do board specific init and eeprom reading */
2576 em28xx_card_setup(dev); 2601 em28xx_card_setup(dev);
@@ -2589,6 +2614,8 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
2589 /* init video dma queues */ 2614 /* init video dma queues */
2590 INIT_LIST_HEAD(&dev->vidq.active); 2615 INIT_LIST_HEAD(&dev->vidq.active);
2591 INIT_LIST_HEAD(&dev->vidq.queued); 2616 INIT_LIST_HEAD(&dev->vidq.queued);
2617 INIT_LIST_HEAD(&dev->vbiq.active);
2618 INIT_LIST_HEAD(&dev->vbiq.queued);
2592 2619
2593 2620
2594 if (dev->board.has_msp34xx) { 2621 if (dev->board.has_msp34xx) {
diff --git a/drivers/media/video/em28xx/em28xx-core.c b/drivers/media/video/em28xx/em28xx-core.c
index 98e140b5d95e..a88257a7d94f 100644
--- a/drivers/media/video/em28xx/em28xx-core.c
+++ b/drivers/media/video/em28xx/em28xx-core.c
@@ -54,6 +54,10 @@ static int alt = EM28XX_PINOUT;
54module_param(alt, int, 0644); 54module_param(alt, int, 0644);
55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint"); 55MODULE_PARM_DESC(alt, "alternate setting to use for video endpoint");
56 56
57static unsigned int disable_vbi;
58module_param(disable_vbi, int, 0644);
59MODULE_PARM_DESC(disable_vbi, "disable vbi support");
60
57/* FIXME */ 61/* FIXME */
58#define em28xx_isocdbg(fmt, arg...) do {\ 62#define em28xx_isocdbg(fmt, arg...) do {\
59 if (core_debug) \ 63 if (core_debug) \
@@ -648,9 +652,24 @@ int em28xx_capture_start(struct em28xx *dev, int start)
648 return rc; 652 return rc;
649} 653}
650 654
655int em28xx_vbi_supported(struct em28xx *dev)
656{
657 /* Modprobe option to manually disable */
658 if (disable_vbi == 1)
659 return 0;
660
661 if (dev->chip_id == CHIP_ID_EM2860 ||
662 dev->chip_id == CHIP_ID_EM2883)
663 return 1;
664
665 /* Version of em28xx that does not support VBI */
666 return 0;
667}
668
651int em28xx_set_outfmt(struct em28xx *dev) 669int em28xx_set_outfmt(struct em28xx *dev)
652{ 670{
653 int ret; 671 int ret;
672 u8 vinctrl;
654 673
655 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT, 674 ret = em28xx_write_reg_bits(dev, EM28XX_R27_OUTFMT,
656 dev->format->reg | 0x20, 0xff); 675 dev->format->reg | 0x20, 0xff);
@@ -661,7 +680,16 @@ int em28xx_set_outfmt(struct em28xx *dev)
661 if (ret < 0) 680 if (ret < 0)
662 return ret; 681 return ret;
663 682
664 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, dev->vinctl); 683 vinctrl = dev->vinctl;
684 if (em28xx_vbi_supported(dev) == 1) {
685 vinctrl |= EM28XX_VINCTRL_VBI_RAW;
686 em28xx_write_reg(dev, EM28XX_R34_VBI_START_H, 0x00);
687 em28xx_write_reg(dev, EM28XX_R35_VBI_START_V, 0x09);
688 em28xx_write_reg(dev, EM28XX_R36_VBI_WIDTH, 0xb4);
689 em28xx_write_reg(dev, EM28XX_R37_VBI_HEIGHT, 0x0c);
690 }
691
692 return em28xx_write_reg(dev, EM28XX_R11_VINCTRL, vinctrl);
665} 693}
666 694
667static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax, 695static int em28xx_accumulator_set(struct em28xx *dev, u8 xmin, u8 xmax,
@@ -732,7 +760,14 @@ int em28xx_resolution_set(struct em28xx *dev)
732 760
733 761
734 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2); 762 em28xx_accumulator_set(dev, 1, (width - 4) >> 2, 1, (height - 4) >> 2);
735 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2); 763
764 /* If we don't set the start position to 4 in VBI mode, we end up
765 with line 21 being YUYV encoded instead of being in 8-bit
766 greyscale */
767 if (em28xx_vbi_supported(dev) == 1)
768 em28xx_capture_area_set(dev, 0, 4, width >> 2, height >> 2);
769 else
770 em28xx_capture_area_set(dev, 0, 0, width >> 2, height >> 2);
736 771
737 return em28xx_scaler_set(dev, dev->hscale, dev->vscale); 772 return em28xx_scaler_set(dev, dev->hscale, dev->vscale);
738} 773}
@@ -844,8 +879,7 @@ EXPORT_SYMBOL_GPL(em28xx_set_mode);
844 */ 879 */
845static void em28xx_irq_callback(struct urb *urb) 880static void em28xx_irq_callback(struct urb *urb)
846{ 881{
847 struct em28xx_dmaqueue *dma_q = urb->context; 882 struct em28xx *dev = urb->context;
848 struct em28xx *dev = container_of(dma_q, struct em28xx, vidq);
849 int rc, i; 883 int rc, i;
850 884
851 switch (urb->status) { 885 switch (urb->status) {
@@ -930,6 +964,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
930 int (*isoc_copy) (struct em28xx *dev, struct urb *urb)) 964 int (*isoc_copy) (struct em28xx *dev, struct urb *urb))
931{ 965{
932 struct em28xx_dmaqueue *dma_q = &dev->vidq; 966 struct em28xx_dmaqueue *dma_q = &dev->vidq;
967 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
933 int i; 968 int i;
934 int sb_size, pipe; 969 int sb_size, pipe;
935 struct urb *urb; 970 struct urb *urb;
@@ -959,7 +994,8 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
959 } 994 }
960 995
961 dev->isoc_ctl.max_pkt_size = max_pkt_size; 996 dev->isoc_ctl.max_pkt_size = max_pkt_size;
962 dev->isoc_ctl.buf = NULL; 997 dev->isoc_ctl.vid_buf = NULL;
998 dev->isoc_ctl.vbi_buf = NULL;
963 999
964 sb_size = max_packets * dev->isoc_ctl.max_pkt_size; 1000 sb_size = max_packets * dev->isoc_ctl.max_pkt_size;
965 1001
@@ -994,7 +1030,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
994 1030
995 usb_fill_int_urb(urb, dev->udev, pipe, 1031 usb_fill_int_urb(urb, dev->udev, pipe,
996 dev->isoc_ctl.transfer_buffer[i], sb_size, 1032 dev->isoc_ctl.transfer_buffer[i], sb_size,
997 em28xx_irq_callback, dma_q, 1); 1033 em28xx_irq_callback, dev, 1);
998 1034
999 urb->number_of_packets = max_packets; 1035 urb->number_of_packets = max_packets;
1000 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP; 1036 urb->transfer_flags = URB_ISO_ASAP | URB_NO_TRANSFER_DMA_MAP;
@@ -1009,6 +1045,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
1009 } 1045 }
1010 1046
1011 init_waitqueue_head(&dma_q->wq); 1047 init_waitqueue_head(&dma_q->wq);
1048 init_waitqueue_head(&vbi_dma_q->wq);
1012 1049
1013 em28xx_capture_start(dev, 1); 1050 em28xx_capture_start(dev, 1);
1014 1051
@@ -1094,7 +1131,7 @@ struct em28xx *em28xx_get_device(int minor,
1094 list_for_each_entry(h, &em28xx_devlist, devlist) { 1131 list_for_each_entry(h, &em28xx_devlist, devlist) {
1095 if (h->vdev->minor == minor) 1132 if (h->vdev->minor == minor)
1096 dev = h; 1133 dev = h;
1097 if (h->vbi_dev->minor == minor) { 1134 if (h->vbi_dev && h->vbi_dev->minor == minor) {
1098 dev = h; 1135 dev = h;
1099 *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE; 1136 *fh_type = V4L2_BUF_TYPE_VBI_CAPTURE;
1100 } 1137 }
diff --git a/drivers/media/video/em28xx/em28xx-dvb.c b/drivers/media/video/em28xx/em28xx-dvb.c
index d603575431b4..db749461e5c6 100644
--- a/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/drivers/media/video/em28xx/em28xx-dvb.c
@@ -33,6 +33,7 @@
33#include "s5h1409.h" 33#include "s5h1409.h"
34#include "mt352.h" 34#include "mt352.h"
35#include "mt352_priv.h" /* FIXME */ 35#include "mt352_priv.h" /* FIXME */
36#include "tda1002x.h"
36 37
37MODULE_DESCRIPTION("driver for em28xx based DVB cards"); 38MODULE_DESCRIPTION("driver for em28xx based DVB cards");
38MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); 39MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
@@ -295,6 +296,11 @@ static struct mt352_config terratec_xs_mt352_cfg = {
295 .demod_init = mt352_terratec_xs_init, 296 .demod_init = mt352_terratec_xs_init,
296}; 297};
297 298
299static struct tda10023_config em28xx_tda10023_config = {
300 .demod_address = 0x0c,
301 .invert = 1,
302};
303
298/* ------------------------------------------------------------------ */ 304/* ------------------------------------------------------------------ */
299 305
300static int attach_xc3028(u8 addr, struct em28xx *dev) 306static int attach_xc3028(u8 addr, struct em28xx *dev)
@@ -549,6 +555,19 @@ static int dvb_init(struct em28xx *dev)
549 } 555 }
550 break; 556 break;
551#endif 557#endif
558 case EM2870_BOARD_REDDO_DVB_C_USB_BOX:
559 /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */
560 dvb->frontend = dvb_attach(tda10023_attach,
561 &em28xx_tda10023_config,
562 &dev->i2c_adap, 0x48);
563 if (dvb->frontend) {
564 if (!dvb_attach(simple_tuner_attach, dvb->frontend,
565 &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) {
566 result = -EINVAL;
567 goto out_free;
568 }
569 }
570 break;
552 default: 571 default:
553 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card" 572 printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card"
554 " isn't supported yet\n", 573 " isn't supported yet\n",
diff --git a/drivers/media/video/em28xx/em28xx-reg.h b/drivers/media/video/em28xx/em28xx-reg.h
index 6bf84bd787df..ed12e7ffcbd0 100644
--- a/drivers/media/video/em28xx/em28xx-reg.h
+++ b/drivers/media/video/em28xx/em28xx-reg.h
@@ -86,7 +86,19 @@
86#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b 86#define EM28XX_XCLK_FREQUENCY_24MHZ 0x0b
87 87
88#define EM28XX_R10_VINMODE 0x10 88#define EM28XX_R10_VINMODE 0x10
89
89#define EM28XX_R11_VINCTRL 0x11 90#define EM28XX_R11_VINCTRL 0x11
91
92/* em28xx Video Input Control Register 0x11 */
93#define EM28XX_VINCTRL_VBI_SLICED 0x80
94#define EM28XX_VINCTRL_VBI_RAW 0x40
95#define EM28XX_VINCTRL_VOUT_MODE_IN 0x20 /* HREF,VREF,VACT in output */
96#define EM28XX_VINCTRL_CCIR656_ENABLE 0x10
97#define EM28XX_VINCTRL_VBI_16BIT_RAW 0x08 /* otherwise 8-bit raw */
98#define EM28XX_VINCTRL_FID_ON_HREF 0x04
99#define EM28XX_VINCTRL_DUAL_EDGE_STROBE 0x02
100#define EM28XX_VINCTRL_INTERLACED 0x01
101
90#define EM28XX_R12_VINENABLE 0x12 /* */ 102#define EM28XX_R12_VINENABLE 0x12 /* */
91 103
92#define EM28XX_R14_GAMMA 0x14 104#define EM28XX_R14_GAMMA 0x14
@@ -135,6 +147,10 @@
135#define EM28XX_R31_HSCALEHIGH 0x31 147#define EM28XX_R31_HSCALEHIGH 0x31
136#define EM28XX_R32_VSCALELOW 0x32 148#define EM28XX_R32_VSCALELOW 0x32
137#define EM28XX_R33_VSCALEHIGH 0x33 149#define EM28XX_R33_VSCALEHIGH 0x33
150#define EM28XX_R34_VBI_START_H 0x34
151#define EM28XX_R35_VBI_START_V 0x35
152#define EM28XX_R36_VBI_WIDTH 0x36
153#define EM28XX_R37_VBI_HEIGHT 0x37
138 154
139#define EM28XX_R40_AC97LSB 0x40 155#define EM28XX_R40_AC97LSB 0x40
140#define EM28XX_R41_AC97MSB 0x41 156#define EM28XX_R41_AC97MSB 0x41
diff --git a/drivers/media/video/em28xx/em28xx-vbi.c b/drivers/media/video/em28xx/em28xx-vbi.c
new file mode 100644
index 000000000000..94943e5a1529
--- /dev/null
+++ b/drivers/media/video/em28xx/em28xx-vbi.c
@@ -0,0 +1,142 @@
1/*
2 em28xx-vbi.c - VBI driver for em28xx
3
4 Copyright (C) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
5
6 This work was sponsored by EyeMagnet Limited.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.
22 */
23
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/slab.h>
28
29#include "em28xx.h"
30
31static unsigned int vbibufs = 5;
32module_param(vbibufs, int, 0644);
33MODULE_PARM_DESC(vbibufs, "number of vbi buffers, range 2-32");
34
35static unsigned int vbi_debug;
36module_param(vbi_debug, int, 0644);
37MODULE_PARM_DESC(vbi_debug, "enable debug messages [vbi]");
38
39#define dprintk(level, fmt, arg...) if (vbi_debug >= level) \
40 printk(KERN_DEBUG "%s: " fmt, dev->core->name , ## arg)
41
42/* ------------------------------------------------------------------ */
43
44static void
45free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
46{
47 struct em28xx_fh *fh = vq->priv_data;
48 struct em28xx *dev = fh->dev;
49 unsigned long flags = 0;
50 if (in_interrupt())
51 BUG();
52
53 /* We used to wait for the buffer to finish here, but this didn't work
54 because, as we were keeping the state as VIDEOBUF_QUEUED,
55 videobuf_queue_cancel marked it as finished for us.
56 (Also, it could wedge forever if the hardware was misconfigured.)
57
58 This should be safe; by the time we get here, the buffer isn't
59 queued anymore. If we ever start marking the buffers as
60 VIDEOBUF_ACTIVE, it won't be, though.
61 */
62 spin_lock_irqsave(&dev->slock, flags);
63 if (dev->isoc_ctl.vbi_buf == buf)
64 dev->isoc_ctl.vbi_buf = NULL;
65 spin_unlock_irqrestore(&dev->slock, flags);
66
67 videobuf_vmalloc_free(&buf->vb);
68 buf->vb.state = VIDEOBUF_NEEDS_INIT;
69}
70
71static int
72vbi_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
73{
74 *size = 720 * 12 * 2;
75 if (0 == *count)
76 *count = vbibufs;
77 if (*count < 2)
78 *count = 2;
79 if (*count > 32)
80 *count = 32;
81 return 0;
82}
83
84static int
85vbi_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
86 enum v4l2_field field)
87{
88 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
89 int rc = 0;
90 unsigned int size;
91
92 size = 720 * 12 * 2;
93
94 buf->vb.size = size;
95
96 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
97 return -EINVAL;
98
99 buf->vb.width = 720;
100 buf->vb.height = 12;
101 buf->vb.field = field;
102
103 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
104 rc = videobuf_iolock(q, &buf->vb, NULL);
105 if (rc < 0)
106 goto fail;
107 }
108
109 buf->vb.state = VIDEOBUF_PREPARED;
110 return 0;
111
112fail:
113 free_buffer(q, buf);
114 return rc;
115}
116
117static void
118vbi_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
119{
120 struct em28xx_buffer *buf = container_of(vb,
121 struct em28xx_buffer,
122 vb);
123 struct em28xx_fh *fh = vq->priv_data;
124 struct em28xx *dev = fh->dev;
125 struct em28xx_dmaqueue *vbiq = &dev->vbiq;
126
127 buf->vb.state = VIDEOBUF_QUEUED;
128 list_add_tail(&buf->vb.queue, &vbiq->active);
129}
130
131static void vbi_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
132{
133 struct em28xx_buffer *buf = container_of(vb, struct em28xx_buffer, vb);
134 free_buffer(q, buf);
135}
136
137struct videobuf_queue_ops em28xx_vbi_qops = {
138 .buf_setup = vbi_setup,
139 .buf_prepare = vbi_prepare,
140 .buf_queue = vbi_queue,
141 .buf_release = vbi_release,
142};
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index a6bdbc21410e..3a1dfb7726f8 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -163,7 +163,24 @@ static inline void buffer_filled(struct em28xx *dev,
163 buf->vb.field_count++; 163 buf->vb.field_count++;
164 do_gettimeofday(&buf->vb.ts); 164 do_gettimeofday(&buf->vb.ts);
165 165
166 dev->isoc_ctl.buf = NULL; 166 dev->isoc_ctl.vid_buf = NULL;
167
168 list_del(&buf->vb.queue);
169 wake_up(&buf->vb.done);
170}
171
172static inline void vbi_buffer_filled(struct em28xx *dev,
173 struct em28xx_dmaqueue *dma_q,
174 struct em28xx_buffer *buf)
175{
176 /* Advice that buffer was filled */
177 em28xx_isocdbg("[%p/%d] wakeup\n", buf, buf->vb.i);
178
179 buf->vb.state = VIDEOBUF_DONE;
180 buf->vb.field_count++;
181 do_gettimeofday(&buf->vb.ts);
182
183 dev->isoc_ctl.vbi_buf = NULL;
167 184
168 list_del(&buf->vb.queue); 185 list_del(&buf->vb.queue);
169 wake_up(&buf->vb.done); 186 wake_up(&buf->vb.done);
@@ -239,7 +256,8 @@ static void em28xx_copy_video(struct em28xx *dev,
239 256
240 if ((char *)startwrite + lencopy > (char *)outp + 257 if ((char *)startwrite + lencopy > (char *)outp +
241 buf->vb.size) { 258 buf->vb.size) {
242 em28xx_isocdbg("Overflow of %zi bytes past buffer end (2)\n", 259 em28xx_isocdbg("Overflow of %zi bytes past buffer end"
260 "(2)\n",
243 ((char *)startwrite + lencopy) - 261 ((char *)startwrite + lencopy) -
244 ((char *)outp + buf->vb.size)); 262 ((char *)outp + buf->vb.size));
245 lencopy = remain = (char *)outp + buf->vb.size - 263 lencopy = remain = (char *)outp + buf->vb.size -
@@ -256,6 +274,63 @@ static void em28xx_copy_video(struct em28xx *dev,
256 dma_q->pos += len; 274 dma_q->pos += len;
257} 275}
258 276
277static void em28xx_copy_vbi(struct em28xx *dev,
278 struct em28xx_dmaqueue *dma_q,
279 struct em28xx_buffer *buf,
280 unsigned char *p,
281 unsigned char *outp, unsigned long len)
282{
283 void *startwrite, *startread;
284 int offset;
285 int bytesperline = 720;
286
287 if (dev == NULL) {
288 em28xx_isocdbg("dev is null\n");
289 return;
290 }
291
292 if (dma_q == NULL) {
293 em28xx_isocdbg("dma_q is null\n");
294 return;
295 }
296 if (buf == NULL) {
297 return;
298 }
299 if (p == NULL) {
300 em28xx_isocdbg("p is null\n");
301 return;
302 }
303 if (outp == NULL) {
304 em28xx_isocdbg("outp is null\n");
305 return;
306 }
307
308 if (dma_q->pos + len > buf->vb.size)
309 len = buf->vb.size - dma_q->pos;
310
311 if ((p[0] == 0x33 && p[1] == 0x95) ||
312 (p[0] == 0x88 && p[1] == 0x88)) {
313 /* Header field, advance past it */
314 p += 4;
315 } else {
316 len += 4;
317 }
318
319 startread = p;
320
321 startwrite = outp + dma_q->pos;
322 offset = dma_q->pos;
323
324 /* Make sure the bottom field populates the second half of the frame */
325 if (buf->top_field == 0) {
326 startwrite += bytesperline * 0x0c;
327 offset += bytesperline * 0x0c;
328 }
329
330 memcpy(startwrite, startread, len);
331 dma_q->pos += len;
332}
333
259static inline void print_err_status(struct em28xx *dev, 334static inline void print_err_status(struct em28xx *dev,
260 int packet, int status) 335 int packet, int status)
261{ 336{
@@ -306,7 +381,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
306 381
307 if (list_empty(&dma_q->active)) { 382 if (list_empty(&dma_q->active)) {
308 em28xx_isocdbg("No active queue to serve\n"); 383 em28xx_isocdbg("No active queue to serve\n");
309 dev->isoc_ctl.buf = NULL; 384 dev->isoc_ctl.vid_buf = NULL;
310 *buf = NULL; 385 *buf = NULL;
311 return; 386 return;
312 } 387 }
@@ -318,7 +393,34 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
318 outp = videobuf_to_vmalloc(&(*buf)->vb); 393 outp = videobuf_to_vmalloc(&(*buf)->vb);
319 memset(outp, 0, (*buf)->vb.size); 394 memset(outp, 0, (*buf)->vb.size);
320 395
321 dev->isoc_ctl.buf = *buf; 396 dev->isoc_ctl.vid_buf = *buf;
397
398 return;
399}
400
401/*
402 * video-buf generic routine to get the next available VBI buffer
403 */
404static inline void vbi_get_next_buf(struct em28xx_dmaqueue *dma_q,
405 struct em28xx_buffer **buf)
406{
407 struct em28xx *dev = container_of(dma_q, struct em28xx, vbiq);
408 char *outp;
409
410 if (list_empty(&dma_q->active)) {
411 em28xx_isocdbg("No active queue to serve\n");
412 dev->isoc_ctl.vbi_buf = NULL;
413 *buf = NULL;
414 return;
415 }
416
417 /* Get the next buffer */
418 *buf = list_entry(dma_q->active.next, struct em28xx_buffer, vb.queue);
419 /* Cleans up buffer - Usefull for testing for frame/URB loss */
420 outp = videobuf_to_vmalloc(&(*buf)->vb);
421 memset(outp, 0x00, (*buf)->vb.size);
422
423 dev->isoc_ctl.vbi_buf = *buf;
322 424
323 return; 425 return;
324} 426}
@@ -329,7 +431,7 @@ static inline void get_next_buf(struct em28xx_dmaqueue *dma_q,
329static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb) 431static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
330{ 432{
331 struct em28xx_buffer *buf; 433 struct em28xx_buffer *buf;
332 struct em28xx_dmaqueue *dma_q = urb->context; 434 struct em28xx_dmaqueue *dma_q = &dev->vidq;
333 unsigned char *outp = NULL; 435 unsigned char *outp = NULL;
334 int i, len = 0, rc = 1; 436 int i, len = 0, rc = 1;
335 unsigned char *p; 437 unsigned char *p;
@@ -346,7 +448,7 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
346 return 0; 448 return 0;
347 } 449 }
348 450
349 buf = dev->isoc_ctl.buf; 451 buf = dev->isoc_ctl.vid_buf;
350 if (buf != NULL) 452 if (buf != NULL)
351 outp = videobuf_to_vmalloc(&buf->vb); 453 outp = videobuf_to_vmalloc(&buf->vb);
352 454
@@ -410,6 +512,153 @@ static inline int em28xx_isoc_copy(struct em28xx *dev, struct urb *urb)
410 return rc; 512 return rc;
411} 513}
412 514
515/* Version of isoc handler that takes into account a mixture of video and
516 VBI data */
517static inline int em28xx_isoc_copy_vbi(struct em28xx *dev, struct urb *urb)
518{
519 struct em28xx_buffer *buf, *vbi_buf;
520 struct em28xx_dmaqueue *dma_q = &dev->vidq;
521 struct em28xx_dmaqueue *vbi_dma_q = &dev->vbiq;
522 unsigned char *outp = NULL;
523 unsigned char *vbioutp = NULL;
524 int i, len = 0, rc = 1;
525 unsigned char *p;
526 int vbi_size;
527
528 if (!dev)
529 return 0;
530
531 if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED))
532 return 0;
533
534 if (urb->status < 0) {
535 print_err_status(dev, -1, urb->status);
536 if (urb->status == -ENOENT)
537 return 0;
538 }
539
540 buf = dev->isoc_ctl.vid_buf;
541 if (buf != NULL)
542 outp = videobuf_to_vmalloc(&buf->vb);
543
544 vbi_buf = dev->isoc_ctl.vbi_buf;
545 if (vbi_buf != NULL)
546 vbioutp = videobuf_to_vmalloc(&vbi_buf->vb);
547
548 for (i = 0; i < urb->number_of_packets; i++) {
549 int status = urb->iso_frame_desc[i].status;
550
551 if (status < 0) {
552 print_err_status(dev, i, status);
553 if (urb->iso_frame_desc[i].status != -EPROTO)
554 continue;
555 }
556
557 len = urb->iso_frame_desc[i].actual_length - 4;
558
559 if (urb->iso_frame_desc[i].actual_length <= 0) {
560 /* em28xx_isocdbg("packet %d is empty",i); - spammy */
561 continue;
562 }
563 if (urb->iso_frame_desc[i].actual_length >
564 dev->max_pkt_size) {
565 em28xx_isocdbg("packet bigger than packet size");
566 continue;
567 }
568
569 p = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
570
571 /* capture type 0 = vbi start
572 capture type 1 = video start
573 capture type 2 = video in progress */
574 if (p[0] == 0x33 && p[1] == 0x95) {
575 dev->capture_type = 0;
576 dev->vbi_read = 0;
577 em28xx_isocdbg("VBI START HEADER!!!\n");
578 dev->cur_field = p[2];
579 }
580
581 /* FIXME: get rid of hard-coded value */
582 vbi_size = 720 * 0x0c;
583
584 if (dev->capture_type == 0) {
585 if (dev->vbi_read >= vbi_size) {
586 /* We've already read all the VBI data, so
587 treat the rest as video */
588 em28xx_isocdbg("dev->vbi_read > vbi_size\n");
589 } else if ((dev->vbi_read + len) < vbi_size) {
590 /* This entire frame is VBI data */
591 if (dev->vbi_read == 0 &&
592 (!(dev->cur_field & 1))) {
593 /* Brand new frame */
594 if (vbi_buf != NULL)
595 vbi_buffer_filled(dev,
596 vbi_dma_q,
597 vbi_buf);
598 vbi_get_next_buf(vbi_dma_q, &vbi_buf);
599 if (vbi_buf == NULL)
600 vbioutp = NULL;
601 else
602 vbioutp = videobuf_to_vmalloc(
603 &vbi_buf->vb);
604 }
605
606 if (dev->vbi_read == 0) {
607 vbi_dma_q->pos = 0;
608 if (vbi_buf != NULL) {
609 if (dev->cur_field & 1)
610 vbi_buf->top_field = 0;
611 else
612 vbi_buf->top_field = 1;
613 }
614 }
615
616 dev->vbi_read += len;
617 em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
618 vbioutp, len);
619 } else {
620 /* Some of this frame is VBI data and some is
621 video data */
622 int vbi_data_len = vbi_size - dev->vbi_read;
623 dev->vbi_read += vbi_data_len;
624 em28xx_copy_vbi(dev, vbi_dma_q, vbi_buf, p,
625 vbioutp, vbi_data_len);
626 dev->capture_type = 1;
627 p += vbi_data_len;
628 len -= vbi_data_len;
629 }
630 }
631
632 if (dev->capture_type == 1) {
633 dev->capture_type = 2;
634 em28xx_isocdbg("Video frame %d, length=%i, %s\n", p[2],
635 len, (p[2] & 1) ? "odd" : "even");
636
637 if (dev->progressive || !(dev->cur_field & 1)) {
638 if (buf != NULL)
639 buffer_filled(dev, dma_q, buf);
640 get_next_buf(dma_q, &buf);
641 if (buf == NULL)
642 outp = NULL;
643 else
644 outp = videobuf_to_vmalloc(&buf->vb);
645 }
646 if (buf != NULL) {
647 if (dev->cur_field & 1)
648 buf->top_field = 0;
649 else
650 buf->top_field = 1;
651 }
652
653 dma_q->pos = 0;
654 }
655 if (buf != NULL && dev->capture_type == 2)
656 em28xx_copy_video(dev, dma_q, buf, p, outp, len);
657 }
658 return rc;
659}
660
661
413/* ------------------------------------------------------------------ 662/* ------------------------------------------------------------------
414 Videobuf operations 663 Videobuf operations
415 ------------------------------------------------------------------*/ 664 ------------------------------------------------------------------*/
@@ -421,7 +670,8 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
421 struct em28xx *dev = fh->dev; 670 struct em28xx *dev = fh->dev;
422 struct v4l2_frequency f; 671 struct v4l2_frequency f;
423 672
424 *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; 673 *size = (fh->dev->width * fh->dev->height * dev->format->depth + 7)
674 >> 3;
425 675
426 if (0 == *count) 676 if (0 == *count)
427 *count = EM28XX_DEF_BUF; 677 *count = EM28XX_DEF_BUF;
@@ -458,8 +708,8 @@ static void free_buffer(struct videobuf_queue *vq, struct em28xx_buffer *buf)
458 VIDEOBUF_ACTIVE, it won't be, though. 708 VIDEOBUF_ACTIVE, it won't be, though.
459 */ 709 */
460 spin_lock_irqsave(&dev->slock, flags); 710 spin_lock_irqsave(&dev->slock, flags);
461 if (dev->isoc_ctl.buf == buf) 711 if (dev->isoc_ctl.vid_buf == buf)
462 dev->isoc_ctl.buf = NULL; 712 dev->isoc_ctl.vid_buf = NULL;
463 spin_unlock_irqrestore(&dev->slock, flags); 713 spin_unlock_irqrestore(&dev->slock, flags);
464 714
465 videobuf_vmalloc_free(&buf->vb); 715 videobuf_vmalloc_free(&buf->vb);
@@ -475,7 +725,8 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
475 struct em28xx *dev = fh->dev; 725 struct em28xx *dev = fh->dev;
476 int rc = 0, urb_init = 0; 726 int rc = 0, urb_init = 0;
477 727
478 buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth + 7) >> 3; 728 buf->vb.size = (fh->dev->width * fh->dev->height * dev->format->depth
729 + 7) >> 3;
479 730
480 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 731 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
481 return -EINVAL; 732 return -EINVAL;
@@ -494,9 +745,16 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
494 urb_init = 1; 745 urb_init = 1;
495 746
496 if (urb_init) { 747 if (urb_init) {
497 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS, 748 if (em28xx_vbi_supported(dev) == 1)
498 EM28XX_NUM_BUFS, dev->max_pkt_size, 749 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
499 em28xx_isoc_copy); 750 EM28XX_NUM_BUFS,
751 dev->max_pkt_size,
752 em28xx_isoc_copy_vbi);
753 else
754 rc = em28xx_init_isoc(dev, EM28XX_NUM_PACKETS,
755 EM28XX_NUM_BUFS,
756 dev->max_pkt_size,
757 em28xx_isoc_copy);
500 if (rc < 0) 758 if (rc < 0)
501 goto fail; 759 goto fail;
502 } 760 }
@@ -578,34 +836,63 @@ static void video_mux(struct em28xx *dev, int index)
578} 836}
579 837
580/* Usage lock check functions */ 838/* Usage lock check functions */
581static int res_get(struct em28xx_fh *fh) 839static int res_get(struct em28xx_fh *fh, unsigned int bit)
582{ 840{
583 struct em28xx *dev = fh->dev; 841 struct em28xx *dev = fh->dev;
584 int rc = 0;
585 842
586 /* This instance already has stream_on */ 843 if (fh->resources & bit)
587 if (fh->stream_on) 844 /* have it already allocated */
588 return rc; 845 return 1;
589 846
590 if (dev->stream_on) 847 /* is it free? */
591 return -EBUSY; 848 mutex_lock(&dev->lock);
849 if (dev->resources & bit) {
850 /* no, someone else uses it */
851 mutex_unlock(&dev->lock);
852 return 0;
853 }
854 /* it's free, grab it */
855 fh->resources |= bit;
856 dev->resources |= bit;
857 em28xx_videodbg("res: get %d\n", bit);
858 mutex_unlock(&dev->lock);
859 return 1;
860}
592 861
593 dev->stream_on = 1; 862static int res_check(struct em28xx_fh *fh, unsigned int bit)
594 fh->stream_on = 1; 863{
595 return rc; 864 return fh->resources & bit;
596} 865}
597 866
598static int res_check(struct em28xx_fh *fh) 867static int res_locked(struct em28xx *dev, unsigned int bit)
599{ 868{
600 return fh->stream_on; 869 return dev->resources & bit;
601} 870}
602 871
603static void res_free(struct em28xx_fh *fh) 872static void res_free(struct em28xx_fh *fh, unsigned int bits)
604{ 873{
605 struct em28xx *dev = fh->dev; 874 struct em28xx *dev = fh->dev;
606 875
607 fh->stream_on = 0; 876 BUG_ON((fh->resources & bits) != bits);
608 dev->stream_on = 0; 877
878 mutex_lock(&dev->lock);
879 fh->resources &= ~bits;
880 dev->resources &= ~bits;
881 em28xx_videodbg("res: put %d\n", bits);
882 mutex_unlock(&dev->lock);
883}
884
885static int get_ressource(struct em28xx_fh *fh)
886{
887 switch (fh->type) {
888 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
889 return EM28XX_RESOURCE_VIDEO;
890 case V4L2_BUF_TYPE_VBI_CAPTURE:
891 return EM28XX_RESOURCE_VBI;
892 default:
893 BUG();
894 return 0;
895 }
609} 896}
610 897
611/* 898/*
@@ -782,7 +1069,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
782 } else { 1069 } else {
783 /* width must even because of the YUYV format 1070 /* width must even because of the YUYV format
784 height must be even because of interlacing */ 1071 height must be even because of interlacing */
785 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh, 1, 0); 1072 v4l_bound_align_image(&width, 48, maxw, 1, &height, 32, maxh,
1073 1, 0);
786 } 1074 }
787 1075
788 get_scale(dev, width, height, &hscale, &vscale); 1076 get_scale(dev, width, height, &hscale, &vscale);
@@ -848,12 +1136,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
848 goto out; 1136 goto out;
849 } 1137 }
850 1138
851 if (dev->stream_on && !fh->stream_on) {
852 em28xx_errdev("%s device in use by another fh\n", __func__);
853 rc = -EBUSY;
854 goto out;
855 }
856
857 rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat, 1139 rc = em28xx_set_video_format(dev, f->fmt.pix.pixelformat,
858 f->fmt.pix.width, f->fmt.pix.height); 1140 f->fmt.pix.width, f->fmt.pix.height);
859 1141
@@ -862,6 +1144,21 @@ out:
862 return rc; 1144 return rc;
863} 1145}
864 1146
1147static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *norm)
1148{
1149 struct em28xx_fh *fh = priv;
1150 struct em28xx *dev = fh->dev;
1151 int rc;
1152
1153 rc = check_dev(dev);
1154 if (rc < 0)
1155 return rc;
1156
1157 *norm = dev->norm;
1158
1159 return 0;
1160}
1161
865static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm) 1162static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
866{ 1163{
867 struct em28xx_fh *fh = priv; 1164 struct em28xx_fh *fh = priv;
@@ -1413,20 +1710,25 @@ static int vidioc_streamon(struct file *file, void *priv,
1413{ 1710{
1414 struct em28xx_fh *fh = priv; 1711 struct em28xx_fh *fh = priv;
1415 struct em28xx *dev = fh->dev; 1712 struct em28xx *dev = fh->dev;
1416 int rc; 1713 int rc = -EINVAL;
1417 1714
1418 rc = check_dev(dev); 1715 rc = check_dev(dev);
1419 if (rc < 0) 1716 if (rc < 0)
1420 return rc; 1717 return rc;
1421 1718
1719 if (unlikely(type != fh->type))
1720 return -EINVAL;
1422 1721
1423 mutex_lock(&dev->lock); 1722 em28xx_videodbg("vidioc_streamon fh=%p t=%d fh->res=%d dev->res=%d\n",
1424 rc = res_get(fh); 1723 fh, type, fh->resources, dev->resources);
1425 1724
1426 if (likely(rc >= 0)) 1725 if (unlikely(!res_get(fh, get_ressource(fh))))
1427 rc = videobuf_streamon(&fh->vb_vidq); 1726 return -EBUSY;
1428 1727
1429 mutex_unlock(&dev->lock); 1728 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1729 rc = videobuf_streamon(&fh->vb_vidq);
1730 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1731 rc = videobuf_streamon(&fh->vb_vbiq);
1430 1732
1431 return rc; 1733 return rc;
1432} 1734}
@@ -1442,17 +1744,22 @@ static int vidioc_streamoff(struct file *file, void *priv,
1442 if (rc < 0) 1744 if (rc < 0)
1443 return rc; 1745 return rc;
1444 1746
1445 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1747 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
1748 fh->type != V4L2_BUF_TYPE_VBI_CAPTURE)
1446 return -EINVAL; 1749 return -EINVAL;
1447 if (type != fh->type) 1750 if (type != fh->type)
1448 return -EINVAL; 1751 return -EINVAL;
1449 1752
1450 mutex_lock(&dev->lock); 1753 em28xx_videodbg("vidioc_streamoff fh=%p t=%d fh->res=%d dev->res=%d\n",
1754 fh, type, fh->resources, dev->resources);
1451 1755
1452 videobuf_streamoff(&fh->vb_vidq); 1756 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1453 res_free(fh); 1757 videobuf_streamoff(&fh->vb_vidq);
1454 1758 res_free(fh, EM28XX_RESOURCE_VIDEO);
1455 mutex_unlock(&dev->lock); 1759 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1760 videobuf_streamoff(&fh->vb_vbiq);
1761 res_free(fh, EM28XX_RESOURCE_VBI);
1762 }
1456 1763
1457 return 0; 1764 return 0;
1458} 1765}
@@ -1474,6 +1781,9 @@ static int vidioc_querycap(struct file *file, void *priv,
1474 V4L2_CAP_VIDEO_CAPTURE | 1781 V4L2_CAP_VIDEO_CAPTURE |
1475 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING; 1782 V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
1476 1783
1784 if (dev->vbi_dev)
1785 cap->capabilities |= V4L2_CAP_VBI_CAPTURE;
1786
1477 if (dev->audio_mode.has_audio) 1787 if (dev->audio_mode.has_audio)
1478 cap->capabilities |= V4L2_CAP_AUDIO; 1788 cap->capabilities |= V4L2_CAP_AUDIO;
1479 1789
@@ -1541,6 +1851,45 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
1541 return 0; 1851 return 0;
1542} 1852}
1543 1853
1854/* RAW VBI ioctls */
1855
1856static int vidioc_g_fmt_vbi_cap(struct file *file, void *priv,
1857 struct v4l2_format *format)
1858{
1859 format->fmt.vbi.samples_per_line = 720;
1860 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1861 format->fmt.vbi.offset = 0;
1862 format->fmt.vbi.flags = 0;
1863
1864 /* Varies by video standard (NTSC, PAL, etc.) */
1865 /* FIXME: hard-coded for NTSC support */
1866 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
1867 format->fmt.vbi.count[0] = 12;
1868 format->fmt.vbi.count[1] = 12;
1869 format->fmt.vbi.start[0] = 10;
1870 format->fmt.vbi.start[1] = 273;
1871
1872 return 0;
1873}
1874
1875static int vidioc_s_fmt_vbi_cap(struct file *file, void *priv,
1876 struct v4l2_format *format)
1877{
1878 format->fmt.vbi.samples_per_line = 720;
1879 format->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
1880 format->fmt.vbi.offset = 0;
1881 format->fmt.vbi.flags = 0;
1882
1883 /* Varies by video standard (NTSC, PAL, etc.) */
1884 /* FIXME: hard-coded for NTSC support */
1885 format->fmt.vbi.sampling_rate = 6750000 * 4 / 2; /* FIXME: ??? */
1886 format->fmt.vbi.count[0] = 12;
1887 format->fmt.vbi.count[1] = 12;
1888 format->fmt.vbi.start[0] = 10;
1889 format->fmt.vbi.start[1] = 273;
1890
1891 return 0;
1892}
1544 1893
1545static int vidioc_reqbufs(struct file *file, void *priv, 1894static int vidioc_reqbufs(struct file *file, void *priv,
1546 struct v4l2_requestbuffers *rb) 1895 struct v4l2_requestbuffers *rb)
@@ -1553,7 +1902,10 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1553 if (rc < 0) 1902 if (rc < 0)
1554 return rc; 1903 return rc;
1555 1904
1556 return videobuf_reqbufs(&fh->vb_vidq, rb); 1905 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1906 return videobuf_reqbufs(&fh->vb_vidq, rb);
1907 else
1908 return videobuf_reqbufs(&fh->vb_vbiq, rb);
1557} 1909}
1558 1910
1559static int vidioc_querybuf(struct file *file, void *priv, 1911static int vidioc_querybuf(struct file *file, void *priv,
@@ -1567,7 +1919,18 @@ static int vidioc_querybuf(struct file *file, void *priv,
1567 if (rc < 0) 1919 if (rc < 0)
1568 return rc; 1920 return rc;
1569 1921
1570 return videobuf_querybuf(&fh->vb_vidq, b); 1922 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1923 return videobuf_querybuf(&fh->vb_vidq, b);
1924 else {
1925 /* FIXME: I'm not sure yet whether this is a bug in zvbi or
1926 the videobuf framework, but we probably shouldn't be
1927 returning a buffer larger than that which was asked for.
1928 At a minimum, it causes a crash in zvbi since it does
1929 a memcpy based on the source buffer length */
1930 int result = videobuf_querybuf(&fh->vb_vbiq, b);
1931 b->length = 17280;
1932 return result;
1933 }
1571} 1934}
1572 1935
1573static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1936static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1580,7 +1943,10 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1580 if (rc < 0) 1943 if (rc < 0)
1581 return rc; 1944 return rc;
1582 1945
1583 return videobuf_qbuf(&fh->vb_vidq, b); 1946 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1947 return videobuf_qbuf(&fh->vb_vidq, b);
1948 else
1949 return videobuf_qbuf(&fh->vb_vbiq, b);
1584} 1950}
1585 1951
1586static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b) 1952static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
@@ -1593,7 +1959,12 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *b)
1593 if (rc < 0) 1959 if (rc < 0)
1594 return rc; 1960 return rc;
1595 1961
1596 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags & O_NONBLOCK); 1962 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1963 return videobuf_dqbuf(&fh->vb_vidq, b, file->f_flags &
1964 O_NONBLOCK);
1965 else
1966 return videobuf_dqbuf(&fh->vb_vbiq, b, file->f_flags &
1967 O_NONBLOCK);
1597} 1968}
1598 1969
1599#ifdef CONFIG_VIDEO_V4L1_COMPAT 1970#ifdef CONFIG_VIDEO_V4L1_COMPAT
@@ -1601,7 +1972,10 @@ static int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
1601{ 1972{
1602 struct em28xx_fh *fh = priv; 1973 struct em28xx_fh *fh = priv;
1603 1974
1604 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8); 1975 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1976 return videobuf_cgmbuf(&fh->vb_vidq, mbuf, 8);
1977 else
1978 return videobuf_cgmbuf(&fh->vb_vbiq, mbuf, 8);
1605} 1979}
1606#endif 1980#endif
1607 1981
@@ -1766,8 +2140,15 @@ static int em28xx_v4l2_open(struct file *filp)
1766 field = V4L2_FIELD_INTERLACED; 2140 field = V4L2_FIELD_INTERLACED;
1767 2141
1768 videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops, 2142 videobuf_queue_vmalloc_init(&fh->vb_vidq, &em28xx_video_qops,
1769 NULL, &dev->slock, fh->type, field, 2143 NULL, &dev->slock,
1770 sizeof(struct em28xx_buffer), fh); 2144 V4L2_BUF_TYPE_VIDEO_CAPTURE, field,
2145 sizeof(struct em28xx_buffer), fh);
2146
2147 videobuf_queue_vmalloc_init(&fh->vb_vbiq, &em28xx_vbi_qops,
2148 NULL, &dev->slock,
2149 V4L2_BUF_TYPE_VBI_CAPTURE,
2150 V4L2_FIELD_SEQ_TB,
2151 sizeof(struct em28xx_buffer), fh);
1771 2152
1772 mutex_unlock(&dev->lock); 2153 mutex_unlock(&dev->lock);
1773 2154
@@ -1824,20 +2205,21 @@ static int em28xx_v4l2_close(struct file *filp)
1824 2205
1825 em28xx_videodbg("users=%d\n", dev->users); 2206 em28xx_videodbg("users=%d\n", dev->users);
1826 2207
2208 if (res_check(fh, EM28XX_RESOURCE_VIDEO)) {
2209 videobuf_stop(&fh->vb_vidq);
2210 res_free(fh, EM28XX_RESOURCE_VIDEO);
2211 }
1827 2212
1828 mutex_lock(&dev->lock); 2213 if (res_check(fh, EM28XX_RESOURCE_VBI)) {
1829 if (res_check(fh)) 2214 videobuf_stop(&fh->vb_vbiq);
1830 res_free(fh); 2215 res_free(fh, EM28XX_RESOURCE_VBI);
2216 }
1831 2217
1832 if (dev->users == 1) { 2218 if (dev->users == 1) {
1833 videobuf_stop(&fh->vb_vidq);
1834 videobuf_mmap_free(&fh->vb_vidq);
1835
1836 /* the device is already disconnect, 2219 /* the device is already disconnect,
1837 free the remaining resources */ 2220 free the remaining resources */
1838 if (dev->state & DEV_DISCONNECTED) { 2221 if (dev->state & DEV_DISCONNECTED) {
1839 em28xx_release_resources(dev); 2222 em28xx_release_resources(dev);
1840 mutex_unlock(&dev->lock);
1841 kfree(dev); 2223 kfree(dev);
1842 return 0; 2224 return 0;
1843 } 2225 }
@@ -1858,10 +2240,12 @@ static int em28xx_v4l2_close(struct file *filp)
1858 "0 (error=%i)\n", errCode); 2240 "0 (error=%i)\n", errCode);
1859 } 2241 }
1860 } 2242 }
2243
2244 videobuf_mmap_free(&fh->vb_vidq);
2245 videobuf_mmap_free(&fh->vb_vbiq);
1861 kfree(fh); 2246 kfree(fh);
1862 dev->users--; 2247 dev->users--;
1863 wake_up_interruptible_nr(&dev->open, 1); 2248 wake_up_interruptible_nr(&dev->open, 1);
1864 mutex_unlock(&dev->lock);
1865 return 0; 2249 return 0;
1866} 2250}
1867 2251
@@ -1886,16 +2270,22 @@ em28xx_v4l2_read(struct file *filp, char __user *buf, size_t count,
1886 */ 2270 */
1887 2271
1888 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 2272 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1889 mutex_lock(&dev->lock); 2273 if (res_locked(dev, EM28XX_RESOURCE_VIDEO))
1890 rc = res_get(fh); 2274 return -EBUSY;
1891 mutex_unlock(&dev->lock);
1892
1893 if (unlikely(rc < 0))
1894 return rc;
1895 2275
1896 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0, 2276 return videobuf_read_stream(&fh->vb_vidq, buf, count, pos, 0,
1897 filp->f_flags & O_NONBLOCK); 2277 filp->f_flags & O_NONBLOCK);
1898 } 2278 }
2279
2280
2281 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
2282 if (!res_get(fh, EM28XX_RESOURCE_VBI))
2283 return -EBUSY;
2284
2285 return videobuf_read_stream(&fh->vb_vbiq, buf, count, pos, 0,
2286 filp->f_flags & O_NONBLOCK);
2287 }
2288
1899 return 0; 2289 return 0;
1900} 2290}
1901 2291
@@ -1913,17 +2303,17 @@ static unsigned int em28xx_v4l2_poll(struct file *filp, poll_table *wait)
1913 if (rc < 0) 2303 if (rc < 0)
1914 return rc; 2304 return rc;
1915 2305
1916 mutex_lock(&dev->lock); 2306 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
1917 rc = res_get(fh); 2307 if (!res_get(fh, EM28XX_RESOURCE_VIDEO))
1918 mutex_unlock(&dev->lock); 2308 return POLLERR;
1919 2309 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
1920 if (unlikely(rc < 0)) 2310 } else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
1921 return POLLERR; 2311 if (!res_get(fh, EM28XX_RESOURCE_VBI))
1922 2312 return POLLERR;
1923 if (V4L2_BUF_TYPE_VIDEO_CAPTURE != fh->type) 2313 return videobuf_poll_stream(filp, &fh->vb_vbiq, wait);
2314 } else {
1924 return POLLERR; 2315 return POLLERR;
1925 2316 }
1926 return videobuf_poll_stream(filp, &fh->vb_vidq, wait);
1927} 2317}
1928 2318
1929/* 2319/*
@@ -1939,14 +2329,10 @@ static int em28xx_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
1939 if (rc < 0) 2329 if (rc < 0)
1940 return rc; 2330 return rc;
1941 2331
1942 mutex_lock(&dev->lock); 2332 if (fh->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1943 rc = res_get(fh); 2333 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1944 mutex_unlock(&dev->lock); 2334 else if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE)
1945 2335 rc = videobuf_mmap_mapper(&fh->vb_vbiq, vma);
1946 if (unlikely(rc < 0))
1947 return rc;
1948
1949 rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
1950 2336
1951 em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n", 2337 em28xx_videodbg("vma start=0x%08lx, size=%ld, ret=%d\n",
1952 (unsigned long)vma->vm_start, 2338 (unsigned long)vma->vm_start,
@@ -1972,6 +2358,8 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1972 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap, 2358 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
1973 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap, 2359 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
1974 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap, 2360 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
2361 .vidioc_g_fmt_vbi_cap = vidioc_g_fmt_vbi_cap,
2362 .vidioc_s_fmt_vbi_cap = vidioc_s_fmt_vbi_cap,
1975 .vidioc_g_audio = vidioc_g_audio, 2363 .vidioc_g_audio = vidioc_g_audio,
1976 .vidioc_s_audio = vidioc_s_audio, 2364 .vidioc_s_audio = vidioc_s_audio,
1977 .vidioc_cropcap = vidioc_cropcap, 2365 .vidioc_cropcap = vidioc_cropcap,
@@ -1984,6 +2372,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1984 .vidioc_querybuf = vidioc_querybuf, 2372 .vidioc_querybuf = vidioc_querybuf,
1985 .vidioc_qbuf = vidioc_qbuf, 2373 .vidioc_qbuf = vidioc_qbuf,
1986 .vidioc_dqbuf = vidioc_dqbuf, 2374 .vidioc_dqbuf = vidioc_dqbuf,
2375 .vidioc_g_std = vidioc_g_std,
1987 .vidioc_s_std = vidioc_s_std, 2376 .vidioc_s_std = vidioc_s_std,
1988 .vidioc_g_parm = vidioc_g_parm, 2377 .vidioc_g_parm = vidioc_g_parm,
1989 .vidioc_s_parm = vidioc_s_parm, 2378 .vidioc_s_parm = vidioc_s_parm,
@@ -2105,13 +2494,10 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2105 dev->mute = 1; 2494 dev->mute = 1;
2106 dev->volume = 0x1f; 2495 dev->volume = 0x1f;
2107 2496
2108 /* enable vbi capturing */
2109
2110/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */ 2497/* em28xx_write_reg(dev, EM28XX_R0E_AUDIOSRC, 0xc0); audio register */
2111 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK); 2498 val = (u8)em28xx_read_reg(dev, EM28XX_R0F_XCLK);
2112 em28xx_write_reg(dev, EM28XX_R0F_XCLK, 2499 em28xx_write_reg(dev, EM28XX_R0F_XCLK,
2113 (EM28XX_XCLK_AUDIO_UNMUTE | val)); 2500 (EM28XX_XCLK_AUDIO_UNMUTE | val));
2114 em28xx_write_reg(dev, EM28XX_R11_VINCTRL, 0x51);
2115 2501
2116 em28xx_set_outfmt(dev); 2502 em28xx_set_outfmt(dev);
2117 em28xx_colorlevels_set_default(dev); 2503 em28xx_colorlevels_set_default(dev);
@@ -2134,14 +2520,17 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2134 } 2520 }
2135 2521
2136 /* Allocate and fill vbi video_device struct */ 2522 /* Allocate and fill vbi video_device struct */
2137 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template, "vbi"); 2523 if (em28xx_vbi_supported(dev) == 1) {
2524 dev->vbi_dev = em28xx_vdev_init(dev, &em28xx_video_template,
2525 "vbi");
2138 2526
2139 /* register v4l2 vbi video_device */ 2527 /* register v4l2 vbi video_device */
2140 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI, 2528 ret = video_register_device(dev->vbi_dev, VFL_TYPE_VBI,
2141 vbi_nr[dev->devno]); 2529 vbi_nr[dev->devno]);
2142 if (ret < 0) { 2530 if (ret < 0) {
2143 em28xx_errdev("unable to register vbi device\n"); 2531 em28xx_errdev("unable to register vbi device\n");
2144 return ret; 2532 return ret;
2533 }
2145 } 2534 }
2146 2535
2147 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) { 2536 if (em28xx_boards[dev->model].radio.type == EM28XX_RADIO) {
@@ -2161,8 +2550,12 @@ int em28xx_register_analog_devices(struct em28xx *dev)
2161 dev->radio_dev->num); 2550 dev->radio_dev->num);
2162 } 2551 }
2163 2552
2164 em28xx_info("V4L2 device registered as /dev/video%d and /dev/vbi%d\n", 2553 em28xx_info("V4L2 video device registered as /dev/video%d\n",
2165 dev->vdev->num, dev->vbi_dev->num); 2554 dev->vdev->num);
2555
2556 if (dev->vbi_dev)
2557 em28xx_info("V4L2 VBI device registered as /dev/vbi%d\n",
2558 dev->vbi_dev->num);
2166 2559
2167 return 0; 2560 return 0;
2168} 2561}
diff --git a/drivers/media/video/em28xx/em28xx.h b/drivers/media/video/em28xx/em28xx.h
index 0f2ba9a40d17..0a73e8bf0d6e 100644
--- a/drivers/media/video/em28xx/em28xx.h
+++ b/drivers/media/video/em28xx/em28xx.h
@@ -109,6 +109,7 @@
109#define EM2882_BOARD_EVGA_INDTUBE 70 109#define EM2882_BOARD_EVGA_INDTUBE 70
110#define EM2820_BOARD_SILVERCREST_WEBCAM 71 110#define EM2820_BOARD_SILVERCREST_WEBCAM 71
111#define EM2861_BOARD_GADMEI_UTV330PLUS 72 111#define EM2861_BOARD_GADMEI_UTV330PLUS 72
112#define EM2870_BOARD_REDDO_DVB_C_USB_BOX 73
112 113
113/* Limits minimum and default number of buffers */ 114/* Limits minimum and default number of buffers */
114#define EM28XX_MIN_BUF 4 115#define EM28XX_MIN_BUF 4
@@ -214,7 +215,8 @@ struct em28xx_usb_isoc_ctl {
214 int tmp_buf_len; 215 int tmp_buf_len;
215 216
216 /* Stores already requested buffers */ 217 /* Stores already requested buffers */
217 struct em28xx_buffer *buf; 218 struct em28xx_buffer *vid_buf;
219 struct em28xx_buffer *vbi_buf;
218 220
219 /* Stores the number of received fields */ 221 /* Stores the number of received fields */
220 int nfields; 222 int nfields;
@@ -443,6 +445,10 @@ enum em28xx_dev_state {
443#define EM28XX_AUDIO 0x10 445#define EM28XX_AUDIO 0x10
444#define EM28XX_DVB 0x20 446#define EM28XX_DVB 0x20
445 447
448/* em28xx resource types (used for res_get/res_lock etc */
449#define EM28XX_RESOURCE_VIDEO 0x01
450#define EM28XX_RESOURCE_VBI 0x02
451
446struct em28xx_audio { 452struct em28xx_audio {
447 char name[50]; 453 char name[50];
448 char *transfer_buffer[EM28XX_AUDIO_BUFS]; 454 char *transfer_buffer[EM28XX_AUDIO_BUFS];
@@ -463,10 +469,11 @@ struct em28xx;
463 469
464struct em28xx_fh { 470struct em28xx_fh {
465 struct em28xx *dev; 471 struct em28xx *dev;
466 unsigned int stream_on:1; /* Locks streams */
467 int radio; 472 int radio;
473 unsigned int resources;
468 474
469 struct videobuf_queue vb_vidq; 475 struct videobuf_queue vb_vidq;
476 struct videobuf_queue vb_vbiq;
470 477
471 enum v4l2_buf_type type; 478 enum v4l2_buf_type type;
472}; 479};
@@ -493,7 +500,6 @@ struct em28xx {
493 /* Vinmode/Vinctl used at the driver */ 500 /* Vinmode/Vinctl used at the driver */
494 int vinmode, vinctl; 501 int vinmode, vinctl;
495 502
496 unsigned int stream_on:1; /* Locks streams */
497 unsigned int has_audio_class:1; 503 unsigned int has_audio_class:1;
498 unsigned int has_alsa_audio:1; 504 unsigned int has_alsa_audio:1;
499 505
@@ -544,6 +550,12 @@ struct em28xx {
544 enum em28xx_dev_state state; 550 enum em28xx_dev_state state;
545 enum em28xx_io_method io; 551 enum em28xx_io_method io;
546 552
553 /* vbi related state tracking */
554 int capture_type;
555 int vbi_read;
556 unsigned char cur_field;
557
558
547 struct work_struct request_module_wk; 559 struct work_struct request_module_wk;
548 560
549 /* locks */ 561 /* locks */
@@ -555,10 +567,14 @@ struct em28xx {
555 struct video_device *vbi_dev; 567 struct video_device *vbi_dev;
556 struct video_device *radio_dev; 568 struct video_device *radio_dev;
557 569
570 /* resources in use */
571 unsigned int resources;
572
558 unsigned char eedata[256]; 573 unsigned char eedata[256];
559 574
560 /* Isoc control struct */ 575 /* Isoc control struct */
561 struct em28xx_dmaqueue vidq; 576 struct em28xx_dmaqueue vidq;
577 struct em28xx_dmaqueue vbiq;
562 struct em28xx_usb_isoc_ctl isoc_ctl; 578 struct em28xx_usb_isoc_ctl isoc_ctl;
563 spinlock_t slock; 579 spinlock_t slock;
564 580
@@ -639,6 +655,7 @@ int em28xx_audio_setup(struct em28xx *dev);
639 655
640int em28xx_colorlevels_set_default(struct em28xx *dev); 656int em28xx_colorlevels_set_default(struct em28xx *dev);
641int em28xx_capture_start(struct em28xx *dev, int start); 657int em28xx_capture_start(struct em28xx *dev, int start);
658int em28xx_vbi_supported(struct em28xx *dev);
642int em28xx_set_outfmt(struct em28xx *dev); 659int em28xx_set_outfmt(struct em28xx *dev);
643int em28xx_resolution_set(struct em28xx *dev); 660int em28xx_resolution_set(struct em28xx *dev);
644int em28xx_set_alternate(struct em28xx *dev); 661int em28xx_set_alternate(struct em28xx *dev);
@@ -686,6 +703,9 @@ void em28xx_deregister_snapshot_button(struct em28xx *dev);
686int em28xx_ir_init(struct em28xx *dev); 703int em28xx_ir_init(struct em28xx *dev);
687int em28xx_ir_fini(struct em28xx *dev); 704int em28xx_ir_fini(struct em28xx *dev);
688 705
706/* Provided by em28xx-vbi.c */
707extern struct videobuf_queue_ops em28xx_vbi_qops;
708
689/* printk macros */ 709/* printk macros */
690 710
691#define em28xx_err(fmt, arg...) do {\ 711#define em28xx_err(fmt, arg...) do {\
diff --git a/drivers/media/video/et61x251/et61x251_core.c b/drivers/media/video/et61x251/et61x251_core.c
index d1c1e457f0b9..74092f436be6 100644
--- a/drivers/media/video/et61x251/et61x251_core.c
+++ b/drivers/media/video/et61x251/et61x251_core.c
@@ -1379,8 +1379,10 @@ et61x251_read(struct file* filp, char __user * buf,
1379 (!list_empty(&cam->outqueue)) || 1379 (!list_empty(&cam->outqueue)) ||
1380 (cam->state & DEV_DISCONNECTED) || 1380 (cam->state & DEV_DISCONNECTED) ||
1381 (cam->state & DEV_MISCONFIGURED), 1381 (cam->state & DEV_MISCONFIGURED),
1382 cam->module_param.frame_timeout * 1382 msecs_to_jiffies(
1383 1000 * msecs_to_jiffies(1) ); 1383 cam->module_param.frame_timeout * 1000
1384 )
1385 );
1384 if (timeout < 0) { 1386 if (timeout < 0) {
1385 mutex_unlock(&cam->fileop_mutex); 1387 mutex_unlock(&cam->fileop_mutex);
1386 return timeout; 1388 return timeout;
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index 8897283b0bb4..fe2e490ebc52 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -19,6 +19,7 @@ if USB_GSPCA && VIDEO_V4L2
19 19
20source "drivers/media/video/gspca/m5602/Kconfig" 20source "drivers/media/video/gspca/m5602/Kconfig"
21source "drivers/media/video/gspca/stv06xx/Kconfig" 21source "drivers/media/video/gspca/stv06xx/Kconfig"
22source "drivers/media/video/gspca/gl860/Kconfig"
22 23
23config USB_GSPCA_CONEX 24config USB_GSPCA_CONEX
24 tristate "Conexant Camera Driver" 25 tristate "Conexant Camera Driver"
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 035616b5e867..b7420818037e 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -58,3 +58,4 @@ gspca_zc3xx-objs := zc3xx.o
58 58
59obj-$(CONFIG_USB_M5602) += m5602/ 59obj-$(CONFIG_USB_M5602) += m5602/
60obj-$(CONFIG_USB_STV06XX) += stv06xx/ 60obj-$(CONFIG_USB_STV06XX) += stv06xx/
61obj-$(CONFIG_USB_GL860) += gl860/
diff --git a/drivers/media/video/gspca/gl860/Kconfig b/drivers/media/video/gspca/gl860/Kconfig
new file mode 100644
index 000000000000..22772f53ec7b
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/Kconfig
@@ -0,0 +1,8 @@
1config USB_GL860
2 tristate "GL860 USB Camera Driver"
3 depends on VIDEO_V4L2 && USB_GSPCA
4 help
5 Say Y here if you want support for cameras based on the GL860 chip.
6
7 To compile this driver as a module, choose M here: the
8 module will be called gspca_gl860.
diff --git a/drivers/media/video/gspca/gl860/Makefile b/drivers/media/video/gspca/gl860/Makefile
new file mode 100644
index 000000000000..13c9403cc87d
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/Makefile
@@ -0,0 +1,10 @@
1obj-$(CONFIG_USB_GL860) += gspca_gl860.o
2
3gspca_gl860-objs := gl860.o \
4 gl860-mi1320.o \
5 gl860-ov2640.o \
6 gl860-ov9655.o \
7 gl860-mi2020.o
8
9EXTRA_CFLAGS += -Idrivers/media/video/gspca
10
diff --git a/drivers/media/video/gspca/gl860/gl860-mi1320.c b/drivers/media/video/gspca/gl860/gl860-mi1320.c
new file mode 100644
index 000000000000..39f6261c1a0c
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-mi1320.c
@@ -0,0 +1,537 @@
1/* @file gl860-mi1320.c
2 * @author Olivier LORIN from my logs
3 * @date 2009-08-27
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Sensor : MI1320 */
20
21#include "gl860.h"
22
23static struct validx tbl_common[] = {
24 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba51, 0x0066}, {0xba02, 0x00f1},
25 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
26 {0xffff, 0xffff},
27 {0xba00, 0x00f0}, {0xba02, 0x00f1}, {0xbafa, 0x0028}, {0xba02, 0x00f1},
28 {0xba00, 0x00f0}, {0xba01, 0x00f1}, {0xbaf0, 0x0006}, {0xba0e, 0x00f1},
29 {0xba70, 0x0006}, {0xba0e, 0x00f1},
30 {0xffff, 0xffff},
31 {0xba74, 0x0006}, {0xba0e, 0x00f1},
32 {0xffff, 0xffff},
33 {0x0061, 0x0000}, {0x0068, 0x000d},
34};
35
36static struct validx tbl_init_at_startup[] = {
37 {0x0000, 0x0000}, {0x0010, 0x0010},
38 {35, 0xffff},
39 {0x0008, 0x00c0}, {0x0001, 0x00c1}, {0x0001, 0x00c2}, {0x0020, 0x0006},
40 {0x006a, 0x000d},
41};
42
43static struct validx tbl_sensor_settings_common[] = {
44 {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0040, 0x0000},
45 {0x006a, 0x0007}, {0x006a, 0x000d}, {0x0063, 0x0006},
46};
47static struct validx tbl_sensor_settings_1280[] = {
48 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
49 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
50};
51static struct validx tbl_sensor_settings_800[] = {
52 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xba5a, 0x0066}, {0xba02, 0x00f1},
53 {0xba05, 0x0067}, {0xba05, 0x00f1}, {0xba20, 0x0065}, {0xba00, 0x00f1},
54};
55static struct validx tbl_sensor_settings_640[] = {
56 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
57 {0xba51, 0x0066}, {0xba02, 0x00f1}, {0xba05, 0x0067}, {0xba05, 0x00f1},
58 {0xba20, 0x0065}, {0xba00, 0x00f1},
59};
60static struct validx tbl_post_unset_alt[] = {
61 {0xba00, 0x00f0}, {0xba00, 0x00f1}, {0xbaa0, 0x0065}, {0xba00, 0x00f1},
62 {0x0061, 0x0000}, {0x0068, 0x000d},
63};
64
65static u8 *tbl_1280[] = {
66 "\x0d\x80\xf1\x08\x03\x04\xf1\x00" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
67 "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
68 "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
69 "\xa9\x04\xf1\x00\xa1\x05\xf1\x00" "\xa4\x04\xf1\x00\xae\x0a\xf1\x08"
70 ,
71 "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
72 "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
73 "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
74 ,
75 "\xd3\x02\xd4\x28\xd5\x01\xd0\x02" "\xd1\x18\xd2\xc1"
76};
77
78static u8 *tbl_800[] = {
79 "\x0d\x80\xf1\x08\x03\x03\xf1\xc0" "\x04\x05\xf1\x02\x05\x00\xf1\xf1"
80 "\x06\x00\xf1\x0d\x20\x01\xf1\x00" "\x21\x84\xf1\x00\x0d\x00\xf1\x08"
81 "\xf0\x00\xf1\x01\x34\x00\xf1\x00" "\x9b\x43\xf1\x00\xa6\x05\xf1\x00"
82 "\xa9\x03\xf1\xc0\xa1\x03\xf1\x20" "\xa4\x02\xf1\x5a\xae\x0a\xf1\x08"
83 ,
84 "\xf0\x00\xf1\x02\x3a\x05\xf1\xf1" "\x3c\x05\xf1\xf1\x59\x01\xf1\x47"
85 "\x5a\x01\xf1\x88\x5c\x0a\xf1\x06" "\x5d\x0e\xf1\x0a\x64\x5e\xf1\x1c"
86 "\xd2\x00\xf1\xcf\xcb\x00\xf1\x01"
87 ,
88 "\xd3\x02\xd4\x18\xd5\x21\xd0\x02" "\xd1\x10\xd2\x59"
89};
90
91static u8 *tbl_640[] = {
92 "\x0d\x80\xf1\x08\x03\x04\xf1\x04" "\x04\x05\xf1\x02\x07\x01\xf1\x7c"
93 "\x08\x00\xf1\x0e\x21\x80\xf1\x00" "\x0d\x00\xf1\x08\xf0\x00\xf1\x01"
94 "\x34\x10\xf1\x10\x3a\x43\xf1\x00" "\xa6\x05\xf1\x02\xa9\x04\xf1\x04"
95 "\xa7\x02\xf1\x81\xaa\x01\xf1\xe2" "\xae\x0c\xf1\x09"
96 ,
97 "\xf0\x00\xf1\x02\x39\x03\xf1\xfc" "\x3b\x04\xf1\x04\x57\x01\xf1\xb6"
98 "\x58\x02\xf1\x0d\x5c\x1f\xf1\x19" "\x5d\x24\xf1\x1e\x64\x5e\xf1\x1c"
99 "\xd2\x00\xf1\x00\xcb\x00\xf1\x01"
100 ,
101 "\xd3\x02\xd4\x10\xd5\x81\xd0\x02" "\xd1\x08\xd2\xe1"
102};
103
104static s32 tbl_sat[] = {0x25, 0x1d, 0x15, 0x0d, 0x05, 0x4d, 0x55, 0x5d, 0x2d};
105static s32 tbl_bright[] = {0, 8, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70};
106static s32 tbl_backlight[] = {0x0e, 0x06, 0x02};
107
108static s32 tbl_cntr1[] = {
109 0x90, 0x98, 0xa0, 0xa8, 0xb0, 0xb8, 0xc0, 0xc8, 0xd0, 0xe0, 0xf0};
110static s32 tbl_cntr2[] = {
111 0x70, 0x68, 0x60, 0x58, 0x50, 0x48, 0x40, 0x38, 0x30, 0x20, 0x10};
112
113static u8 dat_wbalNL[] =
114 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x3b\x04\xf1\x2a\x47\x10\xf1\x10"
115 "\x9d\x3c\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\x91\xf1\x20"
116 "\x9c\x91\xf1\x20\x37\x03\xf1\x00" "\x9d\xc5\xf1\x0f\xf0\x00\xf1\x00";
117
118static u8 dat_wbalLL[] =
119 "\xf0\x00\xf1\x01\x05\x00\xf1\x0c" "\x3b\x04\xf1\x2a\x47\x40\xf1\x40"
120 "\x9d\x20\xf1\xae\xaf\x10\xf1\x00" "\xf0\x00\xf1\x02\x2f\xd1\xf1\x00"
121 "\x9c\xd1\xf1\x00\x37\x03\xf1\x00" "\x9d\xc5\xf1\x3f\xf0\x00\xf1\x00";
122
123static u8 dat_wbalBL[] =
124 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x47\x10\xf1\x30\x9d\x3c\xf1\xae"
125 "\xaf\x10\xf1\x00\xf0\x00\xf1\x02" "\x2f\x91\xf1\x20\x9c\x91\xf1\x20"
126 "\x37\x03\xf1\x00\x9d\xc5\xf1\x2f" "\xf0\x00\xf1\x00";
127
128static u8 dat_hvflip1[] = {0xf0, 0x00, 0xf1, 0x00};
129
130static u8 s000[] =
131 "\x00\x01\x07\x6a\x06\x63\x0d\x6a" "\xc0\x00\x10\x10\xc1\x03\xc2\x42"
132 "\xd8\x04\x58\x00\x04\x02";
133static u8 s001[] =
134 "\x0d\x00\xf1\x0b\x0d\x00\xf1\x08" "\x35\x00\xf1\x22\x68\x00\xf1\x5d"
135 "\xf0\x00\xf1\x01\x06\x70\xf1\x0e" "\xf0\x00\xf1\x02\xdd\x18\xf1\xe0";
136static u8 s002[] =
137 "\x05\x01\xf1\x84\x06\x00\xf1\x44" "\x07\x00\xf1\xbe\x08\x00\xf1\x1e"
138 "\x20\x01\xf1\x03\x21\x84\xf1\x00" "\x22\x0d\xf1\x0f\x24\x80\xf1\x00"
139 "\x34\x18\xf1\x2d\x35\x00\xf1\x22" "\x43\x83\xf1\x83\x59\x00\xf1\xff";
140static u8 s003[] =
141 "\xf0\x00\xf1\x02\x39\x06\xf1\x8c" "\x3a\x06\xf1\x8c\x3b\x03\xf1\xda"
142 "\x3c\x05\xf1\x30\x57\x01\xf1\x0c" "\x58\x01\xf1\x42\x59\x01\xf1\x0c"
143 "\x5a\x01\xf1\x42\x5c\x13\xf1\x0e" "\x5d\x17\xf1\x12\x64\x1e\xf1\x1c";
144static u8 s004[] =
145 "\xf0\x00\xf1\x02\x24\x5f\xf1\x20" "\x28\xea\xf1\x02\x5f\x41\xf1\x43";
146static u8 s005[] =
147 "\x02\x00\xf1\xee\x03\x29\xf1\x1a" "\x04\x02\xf1\xa4\x09\x00\xf1\x68"
148 "\x0a\x00\xf1\x2a\x0b\x00\xf1\x04" "\x0c\x00\xf1\x93\x0d\x00\xf1\x82"
149 "\x0e\x00\xf1\x40\x0f\x00\xf1\x5f" "\x10\x00\xf1\x4e\x11\x00\xf1\x5b";
150static u8 s006[] =
151 "\x15\x00\xf1\xc9\x16\x00\xf1\x5e" "\x17\x00\xf1\x9d\x18\x00\xf1\x06"
152 "\x19\x00\xf1\x89\x1a\x00\xf1\x12" "\x1b\x00\xf1\xa1\x1c\x00\xf1\xe4"
153 "\x1d\x00\xf1\x7a\x1e\x00\xf1\x64" "\xf6\x00\xf1\x5f";
154static u8 s007[] =
155 "\xf0\x00\xf1\x01\x53\x09\xf1\x03" "\x54\x3d\xf1\x1c\x55\x99\xf1\x72"
156 "\x56\xc1\xf1\xb1\x57\xd8\xf1\xce" "\x58\xe0\xf1\x00\xdc\x0a\xf1\x03"
157 "\xdd\x45\xf1\x20\xde\xae\xf1\x82" "\xdf\xdc\xf1\xc9\xe0\xf6\xf1\xea"
158 "\xe1\xff\xf1\x00";
159static u8 s008[] =
160 "\xf0\x00\xf1\x01\x80\x00\xf1\x06" "\x81\xf6\xf1\x08\x82\xfb\xf1\xf7"
161 "\x83\x00\xf1\xfe\xb6\x07\xf1\x03" "\xb7\x18\xf1\x0c\x84\xfb\xf1\x06"
162 "\x85\xfb\xf1\xf9\x86\x00\xf1\xff" "\xb8\x07\xf1\x04\xb9\x16\xf1\x0a";
163static u8 s009[] =
164 "\x87\xfa\xf1\x05\x88\xfc\xf1\xf9" "\x89\x00\xf1\xff\xba\x06\xf1\x03"
165 "\xbb\x17\xf1\x09\x8a\xe8\xf1\x14" "\x8b\xf7\xf1\xf0\x8c\xfd\xf1\xfa"
166 "\x8d\x00\xf1\x00\xbc\x05\xf1\x01" "\xbd\x0c\xf1\x08\xbe\x00\xf1\x14";
167static u8 s010[] =
168 "\x8e\xea\xf1\x13\x8f\xf7\xf1\xf2" "\x90\xfd\xf1\xfa\x91\x00\xf1\x00"
169 "\xbf\x05\xf1\x01\xc0\x0a\xf1\x08" "\xc1\x00\xf1\x0c\x92\xed\xf1\x0f"
170 "\x93\xf9\xf1\xf4\x94\xfe\xf1\xfb" "\x95\x00\xf1\x00\xc2\x04\xf1\x01"
171 "\xc3\x0a\xf1\x07\xc4\x00\xf1\x10";
172static u8 s011[] =
173 "\xf0\x00\xf1\x01\x05\x00\xf1\x06" "\x25\x00\xf1\x55\x34\x10\xf1\x10"
174 "\x35\xf0\xf1\x10\x3a\x02\xf1\x03" "\x3b\x04\xf1\x2a\x9b\x43\xf1\x00"
175 "\xa4\x03\xf1\xc0\xa7\x02\xf1\x81";
176
177static int mi1320_init_at_startup(struct gspca_dev *gspca_dev);
178static int mi1320_configure_alt(struct gspca_dev *gspca_dev);
179static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev);
180static int mi1320_init_post_alt(struct gspca_dev *gspca_dev);
181static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev);
182static int mi1320_sensor_settings(struct gspca_dev *gspca_dev);
183static int mi1320_camera_settings(struct gspca_dev *gspca_dev);
184/*==========================================================================*/
185
186void mi1320_init_settings(struct gspca_dev *gspca_dev)
187{
188 struct sd *sd = (struct sd *) gspca_dev;
189
190 sd->vcur.backlight = 0;
191 sd->vcur.brightness = 0;
192 sd->vcur.sharpness = 6;
193 sd->vcur.contrast = 10;
194 sd->vcur.gamma = 20;
195 sd->vcur.hue = 0;
196 sd->vcur.saturation = 6;
197 sd->vcur.whitebal = 0;
198 sd->vcur.mirror = 0;
199 sd->vcur.flip = 0;
200 sd->vcur.AC50Hz = 1;
201
202 sd->vmax.backlight = 2;
203 sd->vmax.brightness = 8;
204 sd->vmax.sharpness = 7;
205 sd->vmax.contrast = 0; /* 10 but not working with tihs driver */
206 sd->vmax.gamma = 40;
207 sd->vmax.hue = 5 + 1;
208 sd->vmax.saturation = 8;
209 sd->vmax.whitebal = 2;
210 sd->vmax.mirror = 1;
211 sd->vmax.flip = 1;
212 sd->vmax.AC50Hz = 1;
213
214 sd->dev_camera_settings = mi1320_camera_settings;
215 sd->dev_init_at_startup = mi1320_init_at_startup;
216 sd->dev_configure_alt = mi1320_configure_alt;
217 sd->dev_init_pre_alt = mi1320_init_pre_alt;
218 sd->dev_post_unset_alt = mi1320_post_unset_alt;
219}
220
221/*==========================================================================*/
222
223static void common(struct gspca_dev *gspca_dev)
224{
225 s32 n; /* reserved for FETCH macros */
226
227 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 22, s000);
228 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
229 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 32, s001);
230 n = fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
231 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s002);
232 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s003);
233 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 16, s004);
234 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s005);
235 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 44, s006);
236 keep_on_fetching_validx(gspca_dev, tbl_common,
237 ARRAY_SIZE(tbl_common), n);
238 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 52, s007);
239 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s008);
240 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 48, s009);
241 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 56, s010);
242 keep_on_fetching_validx(gspca_dev, tbl_common,
243 ARRAY_SIZE(tbl_common), n);
244 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, s011);
245 keep_on_fetching_validx(gspca_dev, tbl_common,
246 ARRAY_SIZE(tbl_common), n);
247}
248
249static int mi1320_init_at_startup(struct gspca_dev *gspca_dev)
250{
251 fetch_validx(gspca_dev, tbl_init_at_startup,
252 ARRAY_SIZE(tbl_init_at_startup));
253
254 common(gspca_dev);
255
256/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
257
258 return 0;
259}
260
261static int mi1320_init_pre_alt(struct gspca_dev *gspca_dev)
262{
263 struct sd *sd = (struct sd *) gspca_dev;
264
265 sd->mirrorMask = 0;
266
267 sd->vold.backlight = -1;
268 sd->vold.brightness = -1;
269 sd->vold.sharpness = -1;
270 sd->vold.contrast = -1;
271 sd->vold.saturation = -1;
272 sd->vold.gamma = -1;
273 sd->vold.hue = -1;
274 sd->vold.whitebal = -1;
275 sd->vold.mirror = -1;
276 sd->vold.flip = -1;
277 sd->vold.AC50Hz = -1;
278
279 common(gspca_dev);
280
281 mi1320_sensor_settings(gspca_dev);
282
283 mi1320_init_post_alt(gspca_dev);
284
285 return 0;
286}
287
288static int mi1320_init_post_alt(struct gspca_dev *gspca_dev)
289{
290 mi1320_camera_settings(gspca_dev);
291
292 return 0;
293}
294
295static int mi1320_sensor_settings(struct gspca_dev *gspca_dev)
296{
297 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
298
299 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
300
301 fetch_validx(gspca_dev, tbl_sensor_settings_common,
302 ARRAY_SIZE(tbl_sensor_settings_common));
303
304 switch (reso) {
305 case IMAGE_1280:
306 fetch_validx(gspca_dev, tbl_sensor_settings_1280,
307 ARRAY_SIZE(tbl_sensor_settings_1280));
308 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_1280[0]);
309 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_1280[1]);
310 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_1280[2]);
311 break;
312
313 case IMAGE_800:
314 fetch_validx(gspca_dev, tbl_sensor_settings_800,
315 ARRAY_SIZE(tbl_sensor_settings_800));
316 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 64, tbl_800[0]);
317 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_800[1]);
318 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_800[2]);
319 break;
320
321 default:
322 fetch_validx(gspca_dev, tbl_sensor_settings_640,
323 ARRAY_SIZE(tbl_sensor_settings_640));
324 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 60, tbl_640[0]);
325 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 40, tbl_640[1]);
326 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, tbl_640[2]);
327 break;
328 }
329 return 0;
330}
331
332static int mi1320_configure_alt(struct gspca_dev *gspca_dev)
333{
334 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
335
336 switch (reso) {
337 case IMAGE_640:
338 gspca_dev->alt = 3 + 1;
339 break;
340
341 case IMAGE_800:
342 case IMAGE_1280:
343 gspca_dev->alt = 1 + 1;
344 break;
345 }
346 return 0;
347}
348
349int mi1320_camera_settings(struct gspca_dev *gspca_dev)
350{
351 struct sd *sd = (struct sd *) gspca_dev;
352
353 s32 backlight = sd->vcur.backlight;
354 s32 bright = sd->vcur.brightness;
355 s32 sharp = sd->vcur.sharpness;
356 s32 cntr = sd->vcur.contrast;
357 s32 gam = sd->vcur.gamma;
358 s32 hue = sd->vcur.hue;
359 s32 sat = sd->vcur.saturation;
360 s32 wbal = sd->vcur.whitebal;
361 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
362 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
363 s32 freq = (sd->vcur.AC50Hz > 0);
364 s32 i;
365
366 if (freq != sd->vold.AC50Hz) {
367 sd->vold.AC50Hz = freq;
368
369 freq = 2 * (freq == 0);
370 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
371 ctrl_out(gspca_dev, 0x40, 1, 0xba02, 0x00f1, 0, NULL);
372 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x005b, 0, NULL);
373 ctrl_out(gspca_dev, 0x40, 1, 0xba01 + freq, 0x00f1, 0, NULL);
374 }
375
376 if (wbal != sd->vold.whitebal) {
377 sd->vold.whitebal = wbal;
378 if (wbal < 0 || wbal > sd->vmax.whitebal)
379 wbal = 0;
380
381 for (i = 0; i < 2; i++) {
382 if (wbal == 0) { /* Normal light */
383 ctrl_out(gspca_dev, 0x40, 1,
384 0x0010, 0x0010, 0, NULL);
385 ctrl_out(gspca_dev, 0x40, 1,
386 0x0003, 0x00c1, 0, NULL);
387 ctrl_out(gspca_dev, 0x40, 1,
388 0x0042, 0x00c2, 0, NULL);
389 ctrl_out(gspca_dev, 0x40, 3,
390 0xba00, 0x0200, 48, dat_wbalNL);
391 }
392
393 if (wbal == 1) { /* Low light */
394 ctrl_out(gspca_dev, 0x40, 1,
395 0x0010, 0x0010, 0, NULL);
396 ctrl_out(gspca_dev, 0x40, 1,
397 0x0004, 0x00c1, 0, NULL);
398 ctrl_out(gspca_dev, 0x40, 1,
399 0x0043, 0x00c2, 0, NULL);
400 ctrl_out(gspca_dev, 0x40, 3,
401 0xba00, 0x0200, 48, dat_wbalLL);
402 }
403
404 if (wbal == 2) { /* Back light */
405 ctrl_out(gspca_dev, 0x40, 1,
406 0x0010, 0x0010, 0, NULL);
407 ctrl_out(gspca_dev, 0x40, 1,
408 0x0003, 0x00c1, 0, NULL);
409 ctrl_out(gspca_dev, 0x40, 1,
410 0x0042, 0x00c2, 0, NULL);
411 ctrl_out(gspca_dev, 0x40, 3,
412 0xba00, 0x0200, 44, dat_wbalBL);
413 }
414 }
415 }
416
417 if (bright != sd->vold.brightness) {
418 sd->vold.brightness = bright;
419 if (bright < 0 || bright > sd->vmax.brightness)
420 bright = 0;
421
422 bright = tbl_bright[bright];
423 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
424 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
425 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x0034, 0, NULL);
426 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + bright, 0x00f1, 0, NULL);
427 }
428
429 if (sat != sd->vold.saturation) {
430 sd->vold.saturation = sat;
431 if (sat < 0 || sat > sd->vmax.saturation)
432 sat = 0;
433
434 sat = tbl_sat[sat];
435 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
436 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
437 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0025, 0, NULL);
438 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sat, 0x00f1, 0, NULL);
439 }
440
441 if (sharp != sd->vold.sharpness) {
442 sd->vold.sharpness = sharp;
443 if (sharp < 0 || sharp > sd->vmax.sharpness)
444 sharp = 0;
445
446 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
447 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
448 ctrl_out(gspca_dev, 0x40, 1, 0xba00 , 0x0005, 0, NULL);
449 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + sharp, 0x00f1, 0, NULL);
450 }
451
452 if (hue != sd->vold.hue) {
453 /* 0=normal 1=NB 2="sepia" 3=negative 4=other 5=other2 */
454 if (hue < 0 || hue > sd->vmax.hue)
455 hue = 0;
456 if (hue == sd->vmax.hue)
457 sd->swapRB = 1;
458 else
459 sd->swapRB = 0;
460
461 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
462 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
463 ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
464 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
465 0, NULL);
466 }
467
468 if (backlight != sd->vold.backlight) {
469 sd->vold.backlight = backlight;
470 if (backlight < 0 || backlight > sd->vmax.backlight)
471 backlight = 0;
472
473 backlight = tbl_backlight[backlight];
474 for (i = 0; i < 2; i++) {
475 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
476 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
477 ctrl_out(gspca_dev, 0x40, 1, 0xba74, 0x0006, 0, NULL);
478 ctrl_out(gspca_dev, 0x40, 1, 0xba80 + backlight, 0x00f1,
479 0, NULL);
480 }
481 }
482
483 if (hue != sd->vold.hue) {
484 sd->vold.hue = hue;
485
486 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
487 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
488 ctrl_out(gspca_dev, 0x40, 1, 0xba70, 0x00e2, 0, NULL);
489 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + hue * (hue < 6), 0x00f1,
490 0, NULL);
491 }
492
493 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
494 u8 dat_hvflip2[4] = {0x20, 0x01, 0xf1, 0x00};
495 sd->vold.mirror = mirror;
496 sd->vold.flip = flip;
497
498 dat_hvflip2[3] = flip + 2 * mirror;
499 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip1);
500 ctrl_out(gspca_dev, 0x40, 3, 0xba00, 0x0200, 4, dat_hvflip2);
501 }
502
503 if (gam != sd->vold.gamma) {
504 sd->vold.gamma = gam;
505 if (gam < 0 || gam > sd->vmax.gamma)
506 gam = 0;
507
508 gam = 2 * gam;
509 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
510 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
511 ctrl_out(gspca_dev, 0x40, 1, 0xba04 , 0x003b, 0, NULL);
512 ctrl_out(gspca_dev, 0x40, 1, 0xba02 + gam, 0x00f1, 0, NULL);
513 }
514
515 if (cntr != sd->vold.contrast) {
516 sd->vold.contrast = cntr;
517 if (cntr < 0 || cntr > sd->vmax.contrast)
518 cntr = 0;
519
520 ctrl_out(gspca_dev, 0x40, 1, 0xba00, 0x00f0, 0, NULL);
521 ctrl_out(gspca_dev, 0x40, 1, 0xba01, 0x00f1, 0, NULL);
522 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr1[cntr], 0x0035,
523 0, NULL);
524 ctrl_out(gspca_dev, 0x40, 1, 0xba00 + tbl_cntr2[cntr], 0x00f1,
525 0, NULL);
526 }
527
528 return 0;
529}
530
531static void mi1320_post_unset_alt(struct gspca_dev *gspca_dev)
532{
533 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
534
535 fetch_validx(gspca_dev, tbl_post_unset_alt,
536 ARRAY_SIZE(tbl_post_unset_alt));
537}
diff --git a/drivers/media/video/gspca/gl860/gl860-mi2020.c b/drivers/media/video/gspca/gl860/gl860-mi2020.c
new file mode 100644
index 000000000000..ffb09fed3e8c
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-mi2020.c
@@ -0,0 +1,937 @@
1/* @file gl860-mi2020.c
2 * @author Olivier LORIN, from Ice/Soro2005's logs(A), Fret_saw/Hulkie's
3 * logs(B) and Tricid"s logs(C). With the help of Kytrix/BUGabundo/Blazercist.
4 * @date 2009-08-27
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/* Sensor : MI2020 */
21
22#include "gl860.h"
23
24static u8 dat_bright1[] = {0x8c, 0xa2, 0x06};
25static u8 dat_bright3[] = {0x8c, 0xa1, 0x02};
26static u8 dat_bright4[] = {0x90, 0x00, 0x0f};
27static u8 dat_bright5[] = {0x8c, 0xa1, 0x03};
28static u8 dat_bright6[] = {0x90, 0x00, 0x05};
29
30static u8 dat_dummy1[] = {0x90, 0x00, 0x06};
31/*static u8 dummy2[] = {0x8c, 0xa1, 0x02};*/
32/*static u8 dummy3[] = {0x90, 0x00, 0x1f};*/
33
34static u8 dat_hvflip1[] = {0x8c, 0x27, 0x19};
35static u8 dat_hvflip3[] = {0x8c, 0x27, 0x3b};
36static u8 dat_hvflip5[] = {0x8c, 0xa1, 0x03};
37static u8 dat_hvflip6[] = {0x90, 0x00, 0x06};
38
39static u8 dat_freq1[] = { 0x8c, 0xa4, 0x04 };
40
41static u8 dat_multi5[] = { 0x8c, 0xa1, 0x03 };
42static u8 dat_multi6[] = { 0x90, 0x00, 0x05 };
43
44static struct validx tbl_common_a[] = {
45 {0x0000, 0x0000},
46 {1, 0xffff}, /* msleep(35); */
47 {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d}, {0x0000, 0x00c0},
48 {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2}, {0x0004, 0x00d8},
49 {0x0000, 0x0058}, {0x0002, 0x0004}, {0x0041, 0x0000},
50};
51
52static struct validx tbl_common_b[] = {
53 {0x006a, 0x0007},
54 {35, 0xffff},
55 {0x00ef, 0x0006},
56 {35, 0xffff},
57 {0x006a, 0x000d},
58 {35, 0xffff},
59 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0003, 0x00c1}, {0x0042, 0x00c2},
60 {0x0004, 0x00d8}, {0x0000, 0x0058}, {0x0041, 0x0000},
61};
62
63static struct idxdata tbl_common_c[] = {
64 {0x32, "\x02\x00\x08"}, {0x33, "\xf4\x03\x1d"},
65 {6, "\xff\xff\xff"}, /* 12 */
66 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
67 {2, "\xff\xff\xff"}, /* - */
68 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\x22\x23"},
69 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa2\x0f"}, {0x33, "\x90\x00\x0d"},
70 {0x33, "\x8c\xa2\x10"}, {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x11"},
71 {0x33, "\x90\x00\x07"}, {0x33, "\xf4\x03\x1d"}, {0x35, "\xa2\x00\xe2"},
72 {0x33, "\x8c\xab\x05"}, {0x33, "\x90\x00\x01"}, {0x32, "\x6e\x00\x86"},
73 {0x32, "\x70\x0f\xaa"}, {0x32, "\x72\x0f\xe4"}, {0x33, "\x8c\xa3\x4a"},
74 {0x33, "\x90\x00\x5a"}, {0x33, "\x8c\xa3\x4b"}, {0x33, "\x90\x00\xa6"},
75 {0x33, "\x8c\xa3\x61"}, {0x33, "\x90\x00\xc8"}, {0x33, "\x8c\xa3\x62"},
76 {0x33, "\x90\x00\xe1"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
77 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
78 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
79 {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
80 {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
81 {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
82 {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
83 {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
84 {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
85 {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
86 {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
87 {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
88 {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
89 {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
90 {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
91 {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
92 {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
93 {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
94 {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
95 {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
96 {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
97 {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
98 {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
99 {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
100 {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
101 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
102 {1, "\xff\xff\xff"},
103 {0x33, "\x78\x00\x00"},
104 {1, "\xff\xff\xff"},
105 {0x35, "\xb8\x1f\x20"}, {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x10"},
106 {0x33, "\x8c\xa2\x07"}, {0x33, "\x90\x00\x08"}, {0x33, "\x8c\xa2\x42"},
107 {0x33, "\x90\x00\x0b"}, {0x33, "\x8c\xa2\x4a"}, {0x33, "\x90\x00\x8c"},
108 {0x35, "\xba\xfa\x08"}, {0x33, "\x8c\xa2\x02"}, {0x33, "\x90\x00\x22"},
109 {0x33, "\x8c\xa2\x03"}, {0x33, "\x90\x00\xbb"},
110};
111
112static struct idxdata tbl_common_d[] = {
113 {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\xa4\x08"},
114 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x21"},
115 {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\xa4\x0b"},
116 {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\xa0"},
117 {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc0"}, {0x33, "\x8c\x24\x15"},
118 {0x33, "\x90\x00\xa0"}, {0x33, "\x8c\x24\x17"}, {0x33, "\x90\x00\xc0"},
119};
120
121static struct idxdata tbl_common_e[] = {
122 {0x33, "\x8c\xa4\x04"}, {0x33, "\x90\x00\x80"}, {0x33, "\x8c\xa7\x9d"},
123 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa7\x9e"}, {0x33, "\x90\x00\x00"},
124 {0x33, "\x8c\xa2\x0c"}, {0x33, "\x90\x00\x17"}, {0x33, "\x8c\xa2\x15"},
125 {0x33, "\x90\x00\x04"}, {0x33, "\x8c\xa2\x14"}, {0x33, "\x90\x00\x20"},
126 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
127 /* msleep(53); */
128 {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"},
129 {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"}, {0x33, "\x8c\x27\x39"},
130 {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
131 {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"}, {0x33, "\x8c\x27\x03"},
132 {0x33, "\x90\x02\x84"}, {0x33, "\x8c\x27\x05"}, {0x33, "\x90\x01\xe2"},
133 {0x33, "\x8c\x27\x07"}, {0x33, "\x90\x06\x40"}, {0x33, "\x8c\x27\x09"},
134 {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x27\x0d"}, {0x33, "\x90\x00\x00"},
135 {0x33, "\x8c\x27\x0f"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x11"},
136 {0x33, "\x90\x04\xbd"}, {0x33, "\x8c\x27\x13"}, {0x33, "\x90\x06\x4d"},
137 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x17"},
138 {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
139 {0x33, "\x8c\x27\x1b"}, {0x33, "\x90\x02\x4f"}, {0x33, "\x8c\x27\x1d"},
140 {0x33, "\x90\x01\x02"}, {0x33, "\x8c\x27\x1f"}, {0x33, "\x90\x02\x79"},
141 {0x33, "\x8c\x27\x21"}, {0x33, "\x90\x01\x55"}, {0x33, "\x8c\x27\x23"},
142 {0x33, "\x90\x02\x85"}, {0x33, "\x8c\x27\x25"}, {0x33, "\x90\x06\x0f"},
143 {0x33, "\x8c\x27\x27"}, {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x29"},
144 {0x33, "\x90\x20\x20"}, {0x33, "\x8c\x27\x2b"}, {0x33, "\x90\x10\x20"},
145 {0x33, "\x8c\x27\x2d"}, {0x33, "\x90\x20\x07"}, {0x33, "\x8c\x27\x2f"},
146 {0x33, "\x90\x00\x04"}, {0x33, "\x8c\x27\x31"}, {0x33, "\x90\x00\x04"},
147 {0x33, "\x8c\x27\x33"}, {0x33, "\x90\x04\xbb"}, {0x33, "\x8c\x27\x35"},
148 {0x33, "\x90\x06\x4b"}, {0x33, "\x8c\x27\x37"}, {0x33, "\x90\x00\x00"},
149 {0x33, "\x8c\x27\x39"}, {0x33, "\x90\x21\x11"}, {0x33, "\x8c\x27\x3b"},
150 {0x33, "\x90\x00\x24"}, {0x33, "\x8c\x27\x3d"}, {0x33, "\x90\x01\x20"},
151 {0x33, "\x8c\x27\x41"}, {0x33, "\x90\x01\x69"}, {0x33, "\x8c\x27\x45"},
152 {0x33, "\x90\x04\xed"}, {0x33, "\x8c\x27\x47"}, {0x33, "\x90\x09\x4c"},
153 {0x33, "\x8c\x27\x51"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x53"},
154 {0x33, "\x90\x03\x20"}, {0x33, "\x8c\x27\x55"}, {0x33, "\x90\x00\x00"},
155 {0x33, "\x8c\x27\x57"}, {0x33, "\x90\x02\x58"}, {0x33, "\x8c\x27\x5f"},
156 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x61"}, {0x33, "\x90\x06\x40"},
157 {0x33, "\x8c\x27\x63"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x65"},
158 {0x33, "\x90\x04\xb0"}, {0x33, "\x8c\x22\x2e"}, {0x33, "\x90\x00\xa1"},
159 {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa4\x09"},
160 {0x33, "\x90\x00\x21"}, {0x33, "\x8c\xa4\x0a"}, {0x33, "\x90\x00\x25"},
161 {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x27"}, {0x33, "\x8c\x24\x11"},
162 {0x33, "\x90\x00\xa1"}, {0x33, "\x8c\x24\x13"}, {0x33, "\x90\x00\xc1"},
163 {0x33, "\x8c\x24\x15"},
164};
165
166static struct validx tbl_init_at_startup[] = {
167 {0x0000, 0x0000},
168 {53, 0xffff},
169 {0x0010, 0x0010},
170 {53, 0xffff},
171 {0x0008, 0x00c0},
172 {53, 0xffff},
173 {0x0001, 0x00c1},
174 {53, 0xffff},
175 {0x0001, 0x00c2},
176 {53, 0xffff},
177 {0x0020, 0x0006},
178 {53, 0xffff},
179 {0x006a, 0x000d},
180 {53, 0xffff},
181};
182
183static struct idxdata tbl_init_post_alt_low_a[] = {
184 {0x33, "\x8c\x27\x15"}, {0x33, "\x90\x00\x25"}, {0x33, "\x8c\x22\x2e"},
185 {0x33, "\x90\x00\x81"}, {0x33, "\x8c\xa4\x08"}, {0x33, "\x90\x00\x17"},
186 {0x33, "\x8c\xa4\x09"}, {0x33, "\x90\x00\x1a"}, {0x33, "\x8c\xa4\x0a"},
187 {0x33, "\x90\x00\x1d"}, {0x33, "\x8c\xa4\x0b"}, {0x33, "\x90\x00\x20"},
188 {0x33, "\x8c\x24\x11"}, {0x33, "\x90\x00\x81"}, {0x33, "\x8c\x24\x13"},
189 {0x33, "\x90\x00\x9b"},
190};
191
192static struct idxdata tbl_init_post_alt_low_b[] = {
193 {0x33, "\x8c\x27\x03"}, {0x33, "\x90\x03\x24"}, {0x33, "\x8c\x27\x05"},
194 {0x33, "\x90\x02\x58"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
195 {2, "\xff\xff\xff"},
196 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
197 {2, "\xff\xff\xff"},
198};
199
200static struct idxdata tbl_init_post_alt_low_c[] = {
201 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
202 {2, "\xff\xff\xff"},
203 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x20"},
204 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x01"},
205 {0x33, "\x2e\x01\x00"}, {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"},
206 {0x33, "\x90\x00\x00"}, {0x33, "\x8c\x27\x95"}, {0x33, "\x90\x01\x00"},
207 {2, "\xff\xff\xff"},
208 {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x03"},
209 {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
210 {2, "\xff\xff\xff"},
211 {0x33, "\x8c\xa1\x20"}, {0x33, "\x90\x00\x00"}, {0x33, "\x8c\xa1\x03"},
212 {0x33, "\x90\x00\x01"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x00"},
213 {2, "\xff\xff\xff"}, /* - * */
214 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
215 {2, "\xff\xff\xff"},
216 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
217 {2, "\xff\xff\xff"},
218 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
219 {2, "\xff\xff\xff"},
220 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
221 {1, "\xff\xff\xff"},
222};
223
224static struct idxdata tbl_init_post_alt_low_d[] = {
225 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
226 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
227 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
228 {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
229 {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
230 {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
231 {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
232 {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
233 {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
234 {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
235 {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
236 {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
237 {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
238 {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
239 {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
240 {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
241 {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
242 {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
243 {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
244 {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
245 {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
246 {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
247 {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
248 {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
249 {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
250 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"},
251 /* Flip/Mirror h/v=1 */
252 {0x33, "\x90\x00\x3c"}, {0x33, "\x8c\x27\x19"}, {0x33, "\x90\x04\x6c"},
253 {0x33, "\x8c\x27\x3b"}, {0x33, "\x90\x00\x24"}, {0x33, "\x8c\xa1\x03"},
254 {0x33, "\x90\x00\x06"},
255 {130, "\xff\xff\xff"},
256 {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
257 {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"}, {0x33, "\x90\x00\x06"},
258 {100, "\xff\xff\xff"},
259 /* ?? */
260 {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"},
261 {0x33, "\x90\x00\x1f"}, {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
262 {0x33, "\x8c\xa1\x02"}, {0x33, "\x90\x00\x1f"},
263 /* Brigthness=70 */
264 {0x33, "\x8c\xa2\x06"}, {0x33, "\x90\x00\x46"}, {0x33, "\x8c\xa1\x02"},
265 {0x33, "\x90\x00\x0f"}, {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
266 /* Sharpness=20 */
267 {0x32, "\x6c\x14\x08"},
268};
269
270static struct idxdata tbl_init_post_alt_big_a[] = {
271 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
272 {2, "\xff\xff\xff"},
273 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
274 {2, "\xff\xff\xff"},
275 {0x34, "\x1e\x8f\x09"}, {0x34, "\x1c\x01\x28"}, {0x34, "\x1e\x8f\x09"},
276 {0x34, "\x1e\x8f\x09"}, {0x32, "\x14\x06\xe6"}, {0x33, "\x8c\xa1\x03"},
277 {0x33, "\x90\x00\x05"},
278 {2, "\xff\xff\xff"},
279 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"},
280 {2, "\xff\xff\xff"},
281 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x05"},
282 {2, "\xff\xff\xff"},
283 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x06"}, {0x33, "\x8c\xa1\x20"},
284 {0x33, "\x90\x00\x72"}, {0x33, "\x8c\xa1\x30"}, {0x33, "\x90\x00\x03"},
285 {0x33, "\x8c\xa1\x31"}, {0x33, "\x90\x00\x02"}, {0x33, "\x8c\xa1\x32"},
286 {0x33, "\x90\x00\x03"}, {0x33, "\x8c\xa1\x34"}, {0x33, "\x90\x00\x03"},
287 {0x33, "\x8c\xa1\x03"}, {0x33, "\x90\x00\x02"}, {0x33, "\x2e\x01\x00"},
288 {0x34, "\x04\x00\x2a"}, {0x33, "\x8c\xa7\x02"}, {0x33, "\x90\x00\x01"},
289};
290
291static struct idxdata tbl_init_post_alt_big_b[] = {
292 {0x32, "\x10\x01\xf8"}, {0x34, "\xce\x01\xa8"}, {0x34, "\xd0\x66\x33"},
293 {0x34, "\xd2\x31\x9a"}, {0x34, "\xd4\x94\x63"}, {0x34, "\xd6\x4b\x25"},
294 {0x34, "\xd8\x26\x70"}, {0x34, "\xda\x72\x4c"}, {0x34, "\xdc\xff\x04"},
295 {0x34, "\xde\x01\x5b"}, {0x34, "\xe6\x01\x13"}, {0x34, "\xee\x0b\xf0"},
296 {0x34, "\xf6\x0b\xa4"}, {0x35, "\x00\xf6\xe7"}, {0x35, "\x08\x0d\xfd"},
297 {0x35, "\x10\x25\x63"}, {0x35, "\x18\x35\x6c"}, {0x35, "\x20\x42\x7e"},
298 {0x35, "\x28\x19\x44"}, {0x35, "\x30\x39\xd4"}, {0x35, "\x38\xf5\xa8"},
299 {0x35, "\x4c\x07\x90"}, {0x35, "\x44\x07\xb8"}, {0x35, "\x5c\x06\x88"},
300 {0x35, "\x54\x07\xff"}, {0x34, "\xe0\x01\x52"}, {0x34, "\xe8\x00\xcc"},
301 {0x34, "\xf0\x0d\x83"}, {0x34, "\xf8\x0c\xb3"}, {0x35, "\x02\xfe\xba"},
302 {0x35, "\x0a\x04\xe0"}, {0x35, "\x12\x1c\x63"}, {0x35, "\x1a\x2b\x5a"},
303 {0x35, "\x22\x32\x5e"}, {0x35, "\x2a\x0d\x28"}, {0x35, "\x32\x2c\x02"},
304 {0x35, "\x3a\xf4\xfa"}, {0x35, "\x4e\x07\xef"}, {0x35, "\x46\x07\x88"},
305 {0x35, "\x5e\x07\xc1"}, {0x35, "\x56\x04\x64"}, {0x34, "\xe4\x01\x15"},
306 {0x34, "\xec\x00\x82"}, {0x34, "\xf4\x0c\xce"}, {0x34, "\xfc\x0c\xba"},
307 {0x35, "\x06\x1f\x02"}, {0x35, "\x0e\x02\xe3"}, {0x35, "\x16\x1a\x50"},
308 {0x35, "\x1e\x24\x39"}, {0x35, "\x26\x23\x4c"}, {0x35, "\x2e\xf9\x1b"},
309 {0x35, "\x36\x23\x19"}, {0x35, "\x3e\x12\x08"}, {0x35, "\x52\x07\x22"},
310 {0x35, "\x4a\x03\xd3"}, {0x35, "\x62\x06\x54"}, {0x35, "\x5a\x04\x5d"},
311 {0x34, "\xe2\x01\x04"}, {0x34, "\xea\x00\xa0"}, {0x34, "\xf2\x0c\xbc"},
312 {0x34, "\xfa\x0c\x5b"}, {0x35, "\x04\x17\xf2"}, {0x35, "\x0c\x02\x08"},
313 {0x35, "\x14\x28\x43"}, {0x35, "\x1c\x28\x62"}, {0x35, "\x24\x2b\x60"},
314 {0x35, "\x2c\x07\x33"}, {0x35, "\x34\x1f\xb0"}, {0x35, "\x3c\xed\xcd"},
315 {0x35, "\x50\x00\x06"}, {0x35, "\x48\x07\xff"}, {0x35, "\x60\x05\x89"},
316 {0x35, "\x58\x07\xff"}, {0x35, "\x40\x00\xa0"}, {0x35, "\x42\x00\x00"},
317 {0x32, "\x10\x01\xfc"}, {0x33, "\x8c\xa1\x18"}, {0x33, "\x90\x00\x3c"},
318};
319
320static struct idxdata tbl_init_post_alt_big_c[] = {
321 {0x33, "\x8c\xa1\x02"},
322 {0x33, "\x90\x00\x1f"},
323 {0x33, "\x8c\xa1\x02"},
324 {0x33, "\x90\x00\x1f"},
325 {0x33, "\x8c\xa1\x02"},
326 {0x33, "\x90\x00\x1f"},
327 {0x33, "\x8c\xa1\x02"},
328 {0x33, "\x90\x00\x1f"},
329};
330
331static u8 *dat_640 = "\xd0\x02\xd1\x08\xd2\xe1\xd3\x02\xd4\x10\xd5\x81";
332static u8 *dat_800 = "\xd0\x02\xd1\x10\xd2\x57\xd3\x02\xd4\x18\xd5\x21";
333static u8 *dat_1280 = "\xd0\x02\xd1\x20\xd2\x01\xd3\x02\xd4\x28\xd5\x01";
334static u8 *dat_1600 = "\xd0\x02\xd1\x20\xd2\xaf\xd3\x02\xd4\x30\xd5\x41";
335
336static int mi2020_init_at_startup(struct gspca_dev *gspca_dev);
337static int mi2020_configure_alt(struct gspca_dev *gspca_dev);
338static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev);
339static int mi2020_init_post_alt(struct gspca_dev *gspca_dev);
340static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev);
341static int mi2020_camera_settings(struct gspca_dev *gspca_dev);
342/*==========================================================================*/
343
344void mi2020_init_settings(struct gspca_dev *gspca_dev)
345{
346 struct sd *sd = (struct sd *) gspca_dev;
347
348 sd->vcur.backlight = 0;
349 sd->vcur.brightness = 70;
350 sd->vcur.sharpness = 20;
351 sd->vcur.contrast = 0;
352 sd->vcur.gamma = 0;
353 sd->vcur.hue = 0;
354 sd->vcur.saturation = 60;
355 sd->vcur.whitebal = 50;
356 sd->vcur.mirror = 0;
357 sd->vcur.flip = 0;
358 sd->vcur.AC50Hz = 1;
359
360 sd->vmax.backlight = 64;
361 sd->vmax.brightness = 128;
362 sd->vmax.sharpness = 40;
363 sd->vmax.contrast = 3;
364 sd->vmax.gamma = 2;
365 sd->vmax.hue = 0 + 1; /* 200 */
366 sd->vmax.saturation = 0; /* 100 */
367 sd->vmax.whitebal = 0; /* 100 */
368 sd->vmax.mirror = 1;
369 sd->vmax.flip = 1;
370 sd->vmax.AC50Hz = 1;
371 if (_MI2020b_) {
372 sd->vmax.contrast = 0;
373 sd->vmax.gamma = 0;
374 sd->vmax.backlight = 0;
375 }
376
377 sd->dev_camera_settings = mi2020_camera_settings;
378 sd->dev_init_at_startup = mi2020_init_at_startup;
379 sd->dev_configure_alt = mi2020_configure_alt;
380 sd->dev_init_pre_alt = mi2020_init_pre_alt;
381 sd->dev_post_unset_alt = mi2020_post_unset_alt;
382}
383
384/*==========================================================================*/
385
386static void common(struct gspca_dev *gspca_dev)
387{
388 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
389
390 if (_MI2020b_) {
391 fetch_validx(gspca_dev, tbl_common_a, ARRAY_SIZE(tbl_common_a));
392 } else {
393 if (_MI2020_)
394 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x0004, 0, NULL);
395 else
396 ctrl_out(gspca_dev, 0x40, 1, 0x0002, 0x0004, 0, NULL);
397 msleep(35);
398 fetch_validx(gspca_dev, tbl_common_b, ARRAY_SIZE(tbl_common_b));
399 }
400 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x01");
401 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x86\x25\x00");
402 msleep(2); /* - * */
403 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0030, 3, "\x1a\x0a\xcc");
404 if (reso == IMAGE_1600)
405 msleep(2); /* 1600 */
406 fetch_idxdata(gspca_dev, tbl_common_c, ARRAY_SIZE(tbl_common_c));
407
408 if (_MI2020b_ || _MI2020_)
409 fetch_idxdata(gspca_dev, tbl_common_d,
410 ARRAY_SIZE(tbl_common_d));
411
412 fetch_idxdata(gspca_dev, tbl_common_e, ARRAY_SIZE(tbl_common_e));
413 if (_MI2020b_ || _MI2020_) {
414 /* Different from fret */
415 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x78");
416 /* Same as fret */
417 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
418 /* Different from fret */
419 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x90");
420 } else {
421 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x6a");
422 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x24\x17");
423 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x80");
424 }
425 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
426 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x05");
427 msleep(2);
428 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
429 if (reso == IMAGE_1600)
430 msleep(14); /* 1600 */
431 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x06");
432 msleep(2);
433}
434
435static int mi2020_init_at_startup(struct gspca_dev *gspca_dev)
436{
437 u8 c;
438
439 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
440 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &c);
441
442 fetch_validx(gspca_dev, tbl_init_at_startup,
443 ARRAY_SIZE(tbl_init_at_startup));
444
445 common(gspca_dev);
446
447 return 0;
448}
449
450static int mi2020_init_pre_alt(struct gspca_dev *gspca_dev)
451{
452 struct sd *sd = (struct sd *) gspca_dev;
453
454 sd->mirrorMask = 0;
455
456 sd->vold.backlight = -1;
457 sd->vold.brightness = -1;
458 sd->vold.sharpness = -1;
459 sd->vold.contrast = -1;
460 sd->vold.gamma = -1;
461 sd->vold.hue = -1;
462 sd->vold.mirror = -1;
463 sd->vold.flip = -1;
464 sd->vold.AC50Hz = -1;
465
466 mi2020_init_post_alt(gspca_dev);
467
468 return 0;
469}
470
471static int mi2020_init_post_alt(struct gspca_dev *gspca_dev)
472{
473 struct sd *sd = (struct sd *) gspca_dev;
474 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
475
476 s32 backlight = sd->vcur.backlight;
477 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
478 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
479 s32 freq = (sd->vcur.AC50Hz > 0);
480
481 u8 dat_freq2[] = {0x90, 0x00, 0x80};
482 u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
483 u8 dat_multi2[] = {0x90, 0x00, 0x00};
484 u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
485 u8 dat_multi4[] = {0x90, 0x00, 0x00};
486 u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
487 u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
488 u8 c;
489
490 sd->nbIm = -1;
491
492 dat_freq2[2] = freq ? 0xc0 : 0x80;
493 dat_multi1[2] = 0x9d;
494 dat_multi3[2] = dat_multi1[2] + 1;
495 dat_multi4[2] = dat_multi2[2] = backlight;
496 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
497 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
498
499 msleep(200);
500
501 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
502 msleep(3); /* 35 * */
503
504 common(gspca_dev);
505
506 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
507 msleep(70);
508
509 if (_MI2020b_)
510 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
511
512 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
513 ctrl_out(gspca_dev, 0x40, 1, 0x0003, 0x00c1, 0, NULL);
514 ctrl_out(gspca_dev, 0x40, 1, 0x0042, 0x00c2, 0, NULL);
515 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
516
517 switch (reso) {
518 case IMAGE_640:
519 case IMAGE_800:
520 if (reso != IMAGE_800)
521 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
522 12, dat_640);
523 else
524 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
525 12, dat_800);
526
527 if (_MI2020c_)
528 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_a,
529 ARRAY_SIZE(tbl_init_post_alt_low_a));
530
531 if (reso == IMAGE_800)
532 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_b,
533 ARRAY_SIZE(tbl_init_post_alt_low_b));
534
535 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_c,
536 ARRAY_SIZE(tbl_init_post_alt_low_c));
537
538 if (_MI2020b_) {
539 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
540 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
541 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
542 msleep(150);
543 } else if (_MI2020c_) {
544 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
545 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
546 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
547 msleep(120);
548 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
549 msleep(30);
550 } else if (_MI2020_) {
551 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
552 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
553 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
554 msleep(120);
555 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
556 msleep(30);
557 }
558
559 /* AC power frequency */
560 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
561 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
562 msleep(20);
563 /* backlight */
564 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
565 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
566 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
567 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
568 /* at init time but not after */
569 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
570 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
571 /* finish the backlight */
572 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
573 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
574 msleep(5);/* " */
575
576 if (_MI2020c_) {
577 fetch_idxdata(gspca_dev, tbl_init_post_alt_low_d,
578 ARRAY_SIZE(tbl_init_post_alt_low_d));
579 } else {
580 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
581 msleep(14); /* 0xd8 */
582
583 /* flip/mirror */
584 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
585 3, dat_hvflip1);
586 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
587 3, dat_hvflip2);
588 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
589 3, dat_hvflip3);
590 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
591 3, dat_hvflip4);
592 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
593 3, dat_hvflip5);
594 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
595 3, dat_hvflip6);
596 msleep(21);
597 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
598 3, dat_dummy1);
599 msleep(5);
600 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
601 3, dat_dummy1);
602 msleep(5);
603 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
604 3, dat_dummy1);
605 msleep(5);
606 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
607 3, dat_dummy1);
608 msleep(5);
609 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
610 3, dat_dummy1);
611 msleep(5);
612 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
613 3, dat_dummy1);
614 /* end of flip/mirror main part */
615 msleep(246); /* 146 */
616
617 sd->nbIm = 0;
618 }
619 break;
620
621 case IMAGE_1280:
622 case IMAGE_1600:
623 if (reso == IMAGE_1280) {
624 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
625 12, dat_1280);
626 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
627 3, "\x8c\x27\x07");
628 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
629 3, "\x90\x05\x04");
630 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
631 3, "\x8c\x27\x09");
632 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
633 3, "\x90\x04\x02");
634 } else {
635 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
636 12, dat_1600);
637 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
638 3, "\x8c\x27\x07");
639 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
640 3, "\x90\x06\x40");
641 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
642 3, "\x8c\x27\x09");
643 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033,
644 3, "\x90\x04\xb0");
645 }
646
647 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_a,
648 ARRAY_SIZE(tbl_init_post_alt_big_a));
649
650 if (reso == IMAGE_1600)
651 msleep(13); /* 1600 */
652 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\x27\x97");
653 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x01\x00");
654 msleep(53);
655 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
656 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
657 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
658 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
659 if (reso == IMAGE_1600)
660 msleep(13); /* 1600 */
661 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
662 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
663 msleep(53);
664 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
665 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
666 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
667 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
668 if (reso == IMAGE_1600)
669 msleep(13); /* 1600 */
670 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
671 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
672 msleep(53);
673
674 if (_MI2020b_) {
675 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
676 if (reso == IMAGE_1600)
677 msleep(500); /* 1600 */
678 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
679 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
680 msleep(1850);
681 } else if (_MI2020c_ || _MI2020_) {
682 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0010, 0, NULL);
683 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x00c1, 0, NULL);
684 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x00c2, 0, NULL);
685 msleep(1850);
686 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
687 msleep(30);
688 }
689
690 /* AC power frequency */
691 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
692 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
693 msleep(20);
694 /* backlight */
695 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
696 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
697 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
698 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
699 /* at init time but not after */
700 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa2\x0c");
701 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x17");
702 /* finish the backlight */
703 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
704 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
705 msleep(6); /* " */
706
707 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, &c);
708 msleep(14);
709
710 if (_MI2020c_)
711 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_b,
712 ARRAY_SIZE(tbl_init_post_alt_big_b));
713
714 /* flip/mirror */
715 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
716 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
717 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
718 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
719 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
720 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
721 /* end of flip/mirror main part */
722 msleep(16);
723 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
724 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
725 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
726 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
727 if (reso == IMAGE_1600)
728 msleep(25); /* 1600 */
729 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
730 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x00");
731 msleep(103);
732 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x03");
733 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x02");
734 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa1\x20");
735 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x72");
736 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x8c\xa7\x02");
737 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, "\x90\x00\x01");
738 sd->nbIm = 0;
739
740 if (_MI2020c_)
741 fetch_idxdata(gspca_dev, tbl_init_post_alt_big_c,
742 ARRAY_SIZE(tbl_init_post_alt_big_c));
743 }
744
745 sd->vold.mirror = mirror;
746 sd->vold.flip = flip;
747 sd->vold.AC50Hz = freq;
748 sd->vold.backlight = backlight;
749
750 mi2020_camera_settings(gspca_dev);
751
752 return 0;
753}
754
755static int mi2020_configure_alt(struct gspca_dev *gspca_dev)
756{
757 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
758
759 switch (reso) {
760 case IMAGE_640:
761 gspca_dev->alt = 3 + 1;
762 break;
763
764 case IMAGE_800:
765 case IMAGE_1280:
766 case IMAGE_1600:
767 gspca_dev->alt = 1 + 1;
768 break;
769 }
770 return 0;
771}
772
773int mi2020_camera_settings(struct gspca_dev *gspca_dev)
774{
775 struct sd *sd = (struct sd *) gspca_dev;
776
777 s32 backlight = sd->vcur.backlight;
778 s32 bright = sd->vcur.brightness;
779 s32 sharp = sd->vcur.sharpness;
780 s32 cntr = sd->vcur.contrast;
781 s32 gam = sd->vcur.gamma;
782 s32 hue = (sd->vcur.hue > 0);
783 s32 mirror = (((sd->vcur.mirror > 0) ^ sd->mirrorMask) > 0);
784 s32 flip = (((sd->vcur.flip > 0) ^ sd->mirrorMask) > 0);
785 s32 freq = (sd->vcur.AC50Hz > 0);
786
787 u8 dat_sharp[] = {0x6c, 0x00, 0x08};
788 u8 dat_bright2[] = {0x90, 0x00, 0x00};
789 u8 dat_freq2[] = {0x90, 0x00, 0x80};
790 u8 dat_multi1[] = {0x8c, 0xa7, 0x00};
791 u8 dat_multi2[] = {0x90, 0x00, 0x00};
792 u8 dat_multi3[] = {0x8c, 0xa7, 0x00};
793 u8 dat_multi4[] = {0x90, 0x00, 0x00};
794 u8 dat_hvflip2[] = {0x90, 0x04, 0x6c};
795 u8 dat_hvflip4[] = {0x90, 0x00, 0x24};
796
797 /* Less than 4 images received -> too early to set the settings */
798 if (sd->nbIm < 4) {
799 sd->waitSet = 1;
800 return 0;
801 }
802 sd->waitSet = 0;
803
804 if (freq != sd->vold.AC50Hz) {
805 sd->vold.AC50Hz = freq;
806
807 dat_freq2[2] = freq ? 0xc0 : 0x80;
808 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq1);
809 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_freq2);
810 msleep(20);
811 }
812
813 if (mirror != sd->vold.mirror || flip != sd->vold.flip) {
814 sd->vold.mirror = mirror;
815 sd->vold.flip = flip;
816
817 dat_hvflip2[2] = 0x6c + 2 * (1 - flip) + (1 - mirror);
818 dat_hvflip4[2] = 0x24 + 2 * (1 - flip) + (1 - mirror);
819 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip1);
820 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip2);
821 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip3);
822 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip4);
823 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip5);
824 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_hvflip6);
825 msleep(130);
826 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
827 msleep(6);
828 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
829 msleep(6);
830 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
831 msleep(6);
832 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
833 msleep(6);
834 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
835 msleep(6);
836 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_dummy1);
837 msleep(6);
838
839 /* Sometimes present, sometimes not, useful? */
840 /* ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
841 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
842 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
843 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
844 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
845 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);
846 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy2);
847 * ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dummy3);*/
848 }
849
850 if (backlight != sd->vold.backlight) {
851 sd->vold.backlight = backlight;
852 if (backlight < 0 || backlight > sd->vmax.backlight)
853 backlight = 0;
854
855 dat_multi1[2] = 0x9d;
856 dat_multi3[2] = dat_multi1[2] + 1;
857 dat_multi4[2] = dat_multi2[2] = backlight;
858 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
859 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
860 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
861 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
862 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
863 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
864 }
865
866 if (gam != sd->vold.gamma) {
867 sd->vold.gamma = gam;
868 if (gam < 0 || gam > sd->vmax.gamma)
869 gam = 0;
870
871 dat_multi1[2] = 0x6d;
872 dat_multi3[2] = dat_multi1[2] + 1;
873 dat_multi4[2] = dat_multi2[2] = 0x40 + gam;
874 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
875 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
876 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
877 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
878 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
879 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
880 }
881
882 if (cntr != sd->vold.contrast) {
883 sd->vold.contrast = cntr;
884 if (cntr < 0 || cntr > sd->vmax.contrast)
885 cntr = 0;
886
887 dat_multi1[2] = 0x6d;
888 dat_multi3[2] = dat_multi1[2] + 1;
889 dat_multi4[2] = dat_multi2[2] = 0x12 + 16 * cntr;
890 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi1);
891 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi2);
892 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi3);
893 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi4);
894 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi5);
895 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_multi6);
896 }
897
898 if (bright != sd->vold.brightness) {
899 sd->vold.brightness = bright;
900 if (bright < 0 || bright > sd->vmax.brightness)
901 bright = 0;
902
903 dat_bright2[2] = bright;
904 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright1);
905 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright2);
906 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright3);
907 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright4);
908 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright5);
909 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0033, 3, dat_bright6);
910 }
911
912 if (sharp != sd->vold.sharpness) {
913 sd->vold.sharpness = sharp;
914 if (sharp < 0 || sharp > sd->vmax.sharpness)
915 sharp = 0;
916
917 dat_sharp[1] = sharp;
918 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, 0x0032, 3, dat_sharp);
919 }
920
921 if (hue != sd->vold.hue) {
922 sd->swapRB = hue;
923 sd->vold.hue = hue;
924 }
925
926 return 0;
927}
928
929static void mi2020_post_unset_alt(struct gspca_dev *gspca_dev)
930{
931 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
932 msleep(20);
933 if (_MI2020c_ || _MI2020_)
934 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x0000, 0, NULL);
935 else
936 ctrl_out(gspca_dev, 0x40, 1, 0x0041, 0x0000, 0, NULL);
937}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov2640.c b/drivers/media/video/gspca/gl860/gl860-ov2640.c
new file mode 100644
index 000000000000..14b9c373f9f7
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-ov2640.c
@@ -0,0 +1,505 @@
1/* @file gl860-ov2640.c
2 * @author Olivier LORIN, from Malmostoso's logs
3 * @date 2009-08-27
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/* Sensor : OV2640 */
20
21#include "gl860.h"
22
23static u8 dat_init1[] = "\x00\x41\x07\x6a\x06\x61\x0d\x6a" "\x10\x10\xc1\x01";
24static u8 dat_init2[] = {0x61}; /* expected */
25static u8 dat_init3[] = {0x51}; /* expected */
26
27static u8 dat_post[] =
28 "\x00\x41\x07\x6a\x06\xef\x0d\x6a" "\x10\x10\xc1\x01";
29
30static u8 dat_640[] = "\xd0\x01\xd1\x08\xd2\xe0\xd3\x02\xd4\x10\xd5\x81";
31static u8 dat_800[] = "\xd0\x01\xd1\x10\xd2\x58\xd3\x02\xd4\x18\xd5\x21";
32static u8 dat_1280[] = "\xd0\x01\xd1\x18\xd2\xc0\xd3\x02\xd4\x28\xd5\x01";
33static u8 dat_1600[] = "\xd0\x01\xd1\x20\xd2\xb0\xd3\x02\xd4\x30\xd5\x41";
34
35static u8 c50[] = {0x50}; /* expected */
36static u8 c28[] = {0x28}; /* expected */
37static u8 ca8[] = {0xa8}; /* expected */
38
39static struct validx tbl_init_at_startup[] = {
40 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
41 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
42 {0x0050, 0x0000}, {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0061, 0x0006},
43 {0x006a, 0x000d}, {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1},
44 {0x0041, 0x00c2}, {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058},
45 {0x0041, 0x0000}, {0x0061, 0x0000},
46};
47
48static struct validx tbl_common[] = {
49 {0x6000, 0x00ff}, {0x60ff, 0x002c}, {0x60df, 0x002e}, {0x6001, 0x00ff},
50 {0x6080, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
51 {0x6035, 0x003c}, {0x6000, 0x0011}, {0x6028, 0x0004}, {0x60e5, 0x0013},
52 {0x6088, 0x0014}, {0x600c, 0x002c}, {0x6078, 0x0033}, {0x60f7, 0x003b},
53 {0x6000, 0x003e}, {0x6011, 0x0043}, {0x6010, 0x0016}, {0x6082, 0x0039},
54 {0x6088, 0x0035}, {0x600a, 0x0022}, {0x6040, 0x0037}, {0x6000, 0x0023},
55 {0x60a0, 0x0034}, {0x601a, 0x0036}, {0x6002, 0x0006}, {0x60c0, 0x0007},
56 {0x60b7, 0x000d}, {0x6001, 0x000e}, {0x6000, 0x004c}, {0x6081, 0x004a},
57 {0x6099, 0x0021}, {0x6002, 0x0009}, {0x603e, 0x0024}, {0x6034, 0x0025},
58 {0x6081, 0x0026}, {0x6000, 0x0000}, {0x6000, 0x0045}, {0x6000, 0x0010},
59 {0x6000, 0x005c}, {0x6000, 0x0063}, {0x6000, 0x007c}, {0x6070, 0x0061},
60 {0x6080, 0x0062}, {0x6080, 0x0020}, {0x6030, 0x0028}, {0x6000, 0x006c},
61 {0x6000, 0x006e}, {0x6002, 0x0070}, {0x6094, 0x0071}, {0x60c1, 0x0073},
62 {0x6034, 0x003d}, {0x6057, 0x005a}, {0x60bb, 0x004f}, {0x609c, 0x0050},
63 {0x6080, 0x006d}, {0x6002, 0x0039}, {0x6033, 0x003a}, {0x60f1, 0x003b},
64 {0x6031, 0x003c}, {0x6000, 0x00ff}, {0x6014, 0x00e0}, {0x60ff, 0x0076},
65 {0x60a0, 0x0033}, {0x6020, 0x0042}, {0x6018, 0x0043}, {0x6000, 0x004c},
66 {0x60d0, 0x0087}, {0x600f, 0x0088}, {0x6003, 0x00d7}, {0x6010, 0x00d9},
67 {0x6005, 0x00da}, {0x6082, 0x00d3}, {0x60c0, 0x00f9}, {0x6006, 0x0044},
68 {0x6007, 0x00d1}, {0x6002, 0x00d2}, {0x6000, 0x00d2}, {0x6011, 0x00d8},
69 {0x6008, 0x00c8}, {0x6080, 0x00c9}, {0x6008, 0x007c}, {0x6020, 0x007d},
70 {0x6020, 0x007d}, {0x6000, 0x0090}, {0x600e, 0x0091}, {0x601a, 0x0091},
71 {0x6031, 0x0091}, {0x605a, 0x0091}, {0x6069, 0x0091}, {0x6075, 0x0091},
72 {0x607e, 0x0091}, {0x6088, 0x0091}, {0x608f, 0x0091}, {0x6096, 0x0091},
73 {0x60a3, 0x0091}, {0x60af, 0x0091}, {0x60c4, 0x0091}, {0x60d7, 0x0091},
74 {0x60e8, 0x0091}, {0x6020, 0x0091}, {0x6000, 0x0092}, {0x6006, 0x0093},
75 {0x60e3, 0x0093}, {0x6005, 0x0093}, {0x6005, 0x0093}, {0x6000, 0x0093},
76 {0x6004, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
77 {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093}, {0x6000, 0x0093},
78 {0x6000, 0x0096}, {0x6008, 0x0097}, {0x6019, 0x0097}, {0x6002, 0x0097},
79 {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097}, {0x6028, 0x0097},
80 {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6098, 0x0097}, {0x6080, 0x0097},
81 {0x6000, 0x0097}, {0x6000, 0x0097}, {0x60ed, 0x00c3}, {0x609a, 0x00c4},
82 {0x6000, 0x00a4}, {0x6011, 0x00c5}, {0x6051, 0x00c6}, {0x6010, 0x00c7},
83 {0x6066, 0x00b6}, {0x60a5, 0x00b8}, {0x6064, 0x00b7}, {0x607c, 0x00b9},
84 {0x60af, 0x00b3}, {0x6097, 0x00b4}, {0x60ff, 0x00b5}, {0x60c5, 0x00b0},
85 {0x6094, 0x00b1}, {0x600f, 0x00b2}, {0x605c, 0x00c4}, {0x6000, 0x00a8},
86 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x601d, 0x0086}, {0x6000, 0x0050},
87 {0x6090, 0x0051}, {0x6018, 0x0052}, {0x6000, 0x0053}, {0x6000, 0x0054},
88 {0x6088, 0x0055}, {0x6000, 0x0057}, {0x6090, 0x005a}, {0x6018, 0x005b},
89 {0x6005, 0x005c}, {0x60ed, 0x00c3}, {0x6000, 0x007f}, {0x6005, 0x00da},
90 {0x601f, 0x00e5}, {0x6067, 0x00e1}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
91 {0x6000, 0x0005}, {0x6001, 0x00ff}, {0x6000, 0x0000}, {0x6000, 0x0045},
92 {0x6000, 0x0010},
93};
94
95static struct validx tbl_sensor_settings_common_a[] = {
96 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x00ef, 0x0006}, {0x006a, 0x000d},
97 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
98 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0041, 0x0000},
99 {50, 0xffff},
100 {0x0061, 0x0000},
101 {0xffff, 0xffff},
102 {0x6000, 0x00ff}, {0x6000, 0x007c}, {0x6007, 0x007d},
103 {30, 0xffff},
104 {0x0040, 0x0000},
105};
106
107static struct validx tbl_sensor_settings_common_b[] = {
108 {0x6001, 0x00ff}, {0x6038, 0x000c},
109 {10, 0xffff},
110 {0x6000, 0x0011},
111 /* backlight=31/64 */
112 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
113 /* bright=0/256 */
114 {0x6000, 0x00ff}, {0x6009, 0x007c}, {0x6000, 0x007d},
115 /* wbal=64/128 */
116 {0x6000, 0x00ff}, {0x6003, 0x007c}, {0x6040, 0x007d},
117 /* cntr=0/256 */
118 {0x6000, 0x00ff}, {0x6007, 0x007c}, {0x6000, 0x007d},
119 /* sat=128/256 */
120 {0x6000, 0x00ff}, {0x6001, 0x007c}, {0x6080, 0x007d},
121 /* sharpness=0/32 */
122 {0x6000, 0x00ff}, {0x6001, 0x0092}, {0x60c0, 0x0093},
123 /* hue=0/256 */
124 {0x6000, 0x00ff}, {0x6002, 0x007c}, {0x6000, 0x007d},
125 /* gam=32/64 */
126 {0x6000, 0x00ff}, {0x6008, 0x007c}, {0x6020, 0x007d},
127 /* image right up */
128 {0xffff, 0xffff},
129 {15, 0xffff},
130 {0x6001, 0x00ff}, {0x6000, 0x8004},
131 {0xffff, 0xffff},
132 {0x60a8, 0x0004},
133 {15, 0xffff},
134 {0x6001, 0x00ff}, {0x6000, 0x8004},
135 {0xffff, 0xffff},
136 {0x60f8, 0x0004},
137 /* image right up */
138 {0xffff, 0xffff},
139 /* backlight=31/64 */
140 {0x6001, 0x00ff}, {0x603e, 0x0024}, {0x6034, 0x0025},
141};
142
143static struct validx tbl_640[] = {
144 {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
145 {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
146 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
147 {0x6075, 0x0018}, {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032},
148 {0x60bb, 0x004f}, {0x6057, 0x005a}, {0x609c, 0x0050}, {0x6080, 0x006d},
149 {0x6092, 0x0026}, {0x60ff, 0x0020}, {0x6000, 0x0027}, {0x6000, 0x00ff},
150 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c}, {0x603d, 0x0086},
151 {0x6089, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052}, {0x6000, 0x0053},
152 {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057}, {0x60a0, 0x005a},
153 {0x6078, 0x005b}, {0x6000, 0x005c}, {0x6004, 0x00d3}, {0x6000, 0x00e0},
154 {0x60ff, 0x00dd}, {0x60a1, 0x005a},
155};
156
157static struct validx tbl_800[] = {
158 {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0}, {0x6067, 0x00e1},
159 {0x6004, 0x00da}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
160 {0x6001, 0x00ff}, {0x6040, 0x0012}, {0x6000, 0x0011}, {0x6011, 0x0017},
161 {0x6043, 0x0018}, {0x6000, 0x0019}, {0x604b, 0x001a}, {0x6009, 0x0032},
162 {0x60ca, 0x004f}, {0x60a8, 0x0050}, {0x6000, 0x006d}, {0x6038, 0x003d},
163 {0x60c8, 0x0035}, {0x6000, 0x0022}, {0x6092, 0x0026}, {0x60ff, 0x0020},
164 {0x6000, 0x0027}, {0x6000, 0x00ff}, {0x6064, 0x00c0}, {0x604b, 0x00c1},
165 {0x6000, 0x008c}, {0x601d, 0x0086}, {0x6082, 0x00d3}, {0x6000, 0x00e0},
166 {0x60ff, 0x00dd}, {0x6020, 0x008c}, {0x6001, 0x00ff}, {0x6044, 0x0018},
167};
168
169static struct validx tbl_big_a[] = {
170 {0x0002, 0x00c1}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
171 {0x6001, 0x00ff}, {0x6000, 0x0012}, {0x6000, 0x0000}, {0x6000, 0x0045},
172 {0x6000, 0x0010}, {0x6000, 0x0011}, {0x6011, 0x0017}, {0x6075, 0x0018},
173 {0x6001, 0x0019}, {0x6097, 0x001a}, {0x6036, 0x0032}, {0x60bb, 0x004f},
174 {0x609c, 0x0050}, {0x6057, 0x005a}, {0x6080, 0x006d}, {0x6043, 0x000f},
175 {0x608f, 0x0003}, {0x6005, 0x007c}, {0x6081, 0x0026}, {0x6000, 0x00ff},
176 {0x60c8, 0x00c0}, {0x6096, 0x00c1}, {0x6000, 0x008c},
177};
178
179static struct validx tbl_big_b[] = {
180 {0x603d, 0x0086}, {0x6000, 0x0050}, {0x6090, 0x0051}, {0x602c, 0x0052},
181 {0x6000, 0x0053}, {0x6000, 0x0054}, {0x6088, 0x0055}, {0x6000, 0x0057},
182 {0x6040, 0x005a}, {0x60f0, 0x005b}, {0x6001, 0x005c}, {0x6082, 0x00d3},
183 {0x6000, 0x008e},
184};
185
186static struct validx tbl_big_c[] = {
187 {0x6004, 0x00da}, {0x6000, 0x00e0}, {0x6067, 0x00e1}, {0x60ff, 0x00dd},
188 {0x6001, 0x00ff}, {0x6000, 0x00ff}, {0x60f1, 0x00dd}, {0x6004, 0x00e0},
189 {0x6001, 0x00ff}, {0x6000, 0x0011}, {0x6000, 0x00ff}, {0x6010, 0x00c7},
190 {0x6000, 0x0092}, {0x6006, 0x0093}, {0x60e3, 0x0093}, {0x6005, 0x0093},
191 {0x6005, 0x0093}, {0x60ed, 0x00c3}, {0x6000, 0x00a4}, {0x60d0, 0x0087},
192 {0x6003, 0x0096}, {0x600c, 0x0097}, {0x6024, 0x0097}, {0x6030, 0x0097},
193 {0x6028, 0x0097}, {0x6026, 0x0097}, {0x6002, 0x0097}, {0x6001, 0x00ff},
194 {0x6043, 0x000f}, {0x608f, 0x0003}, {0x6000, 0x002d}, {0x6000, 0x002e},
195 {0x600a, 0x0022}, {0x6002, 0x0070}, {0x6008, 0x0014}, {0x6048, 0x0014},
196 {0x6000, 0x00ff}, {0x6000, 0x00e0}, {0x60ff, 0x00dd},
197};
198
199static struct validx tbl_post_unset_alt[] = {
200 {0x006a, 0x000d}, {0x6001, 0x00ff}, {0x6081, 0x0026}, {0x6000, 0x0000},
201 {0x6000, 0x0045}, {0x6000, 0x0010}, {0x6068, 0x000d},
202 {50, 0xffff},
203 {0x0021, 0x0000},
204};
205
206static int ov2640_init_at_startup(struct gspca_dev *gspca_dev);
207static int ov2640_configure_alt(struct gspca_dev *gspca_dev);
208static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev);
209static int ov2640_init_post_alt(struct gspca_dev *gspca_dev);
210static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev);
211static int ov2640_camera_settings(struct gspca_dev *gspca_dev);
212/*==========================================================================*/
213
214void ov2640_init_settings(struct gspca_dev *gspca_dev)
215{
216 struct sd *sd = (struct sd *) gspca_dev;
217
218 sd->vcur.backlight = 32;
219 sd->vcur.brightness = 0;
220 sd->vcur.sharpness = 6;
221 sd->vcur.contrast = 0;
222 sd->vcur.gamma = 32;
223 sd->vcur.hue = 0;
224 sd->vcur.saturation = 128;
225 sd->vcur.whitebal = 64;
226
227 sd->vmax.backlight = 64;
228 sd->vmax.brightness = 255;
229 sd->vmax.sharpness = 31;
230 sd->vmax.contrast = 255;
231 sd->vmax.gamma = 64;
232 sd->vmax.hue = 255 + 1;
233 sd->vmax.saturation = 255;
234 sd->vmax.whitebal = 128;
235 sd->vmax.mirror = 0;
236 sd->vmax.flip = 0;
237 sd->vmax.AC50Hz = 0;
238
239 sd->dev_camera_settings = ov2640_camera_settings;
240 sd->dev_init_at_startup = ov2640_init_at_startup;
241 sd->dev_configure_alt = ov2640_configure_alt;
242 sd->dev_init_pre_alt = ov2640_init_pre_alt;
243 sd->dev_post_unset_alt = ov2640_post_unset_alt;
244}
245
246/*==========================================================================*/
247
248static void common(struct gspca_dev *gspca_dev)
249{
250 fetch_validx(gspca_dev, tbl_common, ARRAY_SIZE(tbl_common));
251}
252
253static int ov2640_init_at_startup(struct gspca_dev *gspca_dev)
254{
255 fetch_validx(gspca_dev, tbl_init_at_startup,
256 ARRAY_SIZE(tbl_init_at_startup));
257
258 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_init1);
259
260 common(gspca_dev);
261
262 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0006, 1, dat_init2);
263
264 ctrl_out(gspca_dev, 0x40, 1, 0x00ef, 0x0006, 0, NULL);
265
266 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, dat_init3);
267
268 ctrl_out(gspca_dev, 0x40, 1, 0x0051, 0x0000, 0, NULL);
269/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL); */
270
271 return 0;
272}
273
274static int ov2640_init_pre_alt(struct gspca_dev *gspca_dev)
275{
276 struct sd *sd = (struct sd *) gspca_dev;
277
278 sd->vold.backlight = -1;
279 sd->vold.brightness = -1;
280 sd->vold.sharpness = -1;
281 sd->vold.contrast = -1;
282 sd->vold.saturation = -1;
283 sd->vold.gamma = -1;
284 sd->vold.hue = -1;
285 sd->vold.whitebal = -1;
286
287 ov2640_init_post_alt(gspca_dev);
288
289 return 0;
290}
291
292static int ov2640_init_post_alt(struct gspca_dev *gspca_dev)
293{
294 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
295 s32 n; /* reserved for FETCH macros */
296
297 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
298
299 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_a,
300 ARRAY_SIZE(tbl_sensor_settings_common_a));
301 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_post);
302 common(gspca_dev);
303 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_a,
304 ARRAY_SIZE(tbl_sensor_settings_common_a), n);
305
306 switch (reso) {
307 case IMAGE_640:
308 n = fetch_validx(gspca_dev, tbl_640, ARRAY_SIZE(tbl_640));
309 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_640);
310 break;
311
312 case IMAGE_800:
313 n = fetch_validx(gspca_dev, tbl_800, ARRAY_SIZE(tbl_800));
314 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 12, dat_800);
315 break;
316
317 case IMAGE_1600:
318 case IMAGE_1280:
319 n = fetch_validx(gspca_dev, tbl_big_a, ARRAY_SIZE(tbl_big_a));
320
321 if (reso == IMAGE_1280) {
322 n = fetch_validx(gspca_dev, tbl_big_b,
323 ARRAY_SIZE(tbl_big_b));
324 } else {
325 ctrl_out(gspca_dev, 0x40, 1, 0x601d, 0x0086, 0, NULL);
326 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00d7, 0, NULL);
327 ctrl_out(gspca_dev, 0x40, 1, 0x6082, 0x00d3, 0, NULL);
328 }
329
330 n = fetch_validx(gspca_dev, tbl_big_c, ARRAY_SIZE(tbl_big_c));
331
332 if (reso == IMAGE_1280) {
333 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
334 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
335 12, dat_1280);
336 } else {
337 ctrl_out(gspca_dev, 0x40, 1, 0x6020, 0x008c, 0, NULL);
338 ctrl_out(gspca_dev, 0x40, 1, 0x6001, 0x00ff, 0, NULL);
339 ctrl_out(gspca_dev, 0x40, 1, 0x6076, 0x0018, 0, NULL);
340 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
341 12, dat_1600);
342 }
343 break;
344 }
345
346 n = fetch_validx(gspca_dev, tbl_sensor_settings_common_b,
347 ARRAY_SIZE(tbl_sensor_settings_common_b));
348 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
349 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
350 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
351 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, c28);
352 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
353 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
354 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x8004, 1, ca8);
355 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
356 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
357 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, c50);
358 keep_on_fetching_validx(gspca_dev, tbl_sensor_settings_common_b,
359 ARRAY_SIZE(tbl_sensor_settings_common_b), n);
360
361 ov2640_camera_settings(gspca_dev);
362
363 return 0;
364}
365
366static int ov2640_configure_alt(struct gspca_dev *gspca_dev)
367{
368 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
369
370 switch (reso) {
371 case IMAGE_640:
372 gspca_dev->alt = 3 + 1;
373 break;
374
375 case IMAGE_800:
376 case IMAGE_1280:
377 case IMAGE_1600:
378 gspca_dev->alt = 1 + 1;
379 break;
380 }
381 return 0;
382}
383
384static int ov2640_camera_settings(struct gspca_dev *gspca_dev)
385{
386 struct sd *sd = (struct sd *) gspca_dev;
387
388 s32 backlight = sd->vcur.backlight;
389 s32 bright = sd->vcur.brightness;
390 s32 sharp = sd->vcur.sharpness;
391 s32 gam = sd->vcur.gamma;
392 s32 cntr = sd->vcur.contrast;
393 s32 sat = sd->vcur.saturation;
394 s32 hue = sd->vcur.hue;
395 s32 wbal = sd->vcur.whitebal;
396
397 if (backlight != sd->vold.backlight) {
398 if (backlight < 0 || backlight > sd->vmax.backlight)
399 backlight = 0;
400
401 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
402 0, NULL);
403 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024,
404 0, NULL);
405 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
406 0, NULL);
407 /* No sd->vold.backlight=backlight; (to be done again later) */
408 }
409
410 if (bright != sd->vold.brightness) {
411 sd->vold.brightness = bright;
412 if (bright < 0 || bright > sd->vmax.brightness)
413 bright = 0;
414
415 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
416 ctrl_out(gspca_dev, 0x40, 1, 0x6009 , 0x007c, 0, NULL);
417 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + bright, 0x007d, 0, NULL);
418 }
419
420 if (wbal != sd->vold.whitebal) {
421 sd->vold.whitebal = wbal;
422 if (wbal < 0 || wbal > sd->vmax.whitebal)
423 wbal = 0;
424
425 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
426 ctrl_out(gspca_dev, 0x40, 1, 0x6003 , 0x007c, 0, NULL);
427 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + wbal, 0x007d, 0, NULL);
428 }
429
430 if (cntr != sd->vold.contrast) {
431 sd->vold.contrast = cntr;
432 if (cntr < 0 || cntr > sd->vmax.contrast)
433 cntr = 0;
434
435 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
436 ctrl_out(gspca_dev, 0x40, 1, 0x6007 , 0x007c, 0, NULL);
437 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + cntr, 0x007d, 0, NULL);
438 }
439
440 if (sat != sd->vold.saturation) {
441 sd->vold.saturation = sat;
442 if (sat < 0 || sat > sd->vmax.saturation)
443 sat = 0;
444
445 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
446 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x007c, 0, NULL);
447 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + sat, 0x007d, 0, NULL);
448 }
449
450 if (sharp != sd->vold.sharpness) {
451 sd->vold.sharpness = sharp;
452 if (sharp < 0 || sharp > sd->vmax.sharpness)
453 sharp = 0;
454
455 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
456 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x0092, 0, NULL);
457 ctrl_out(gspca_dev, 0x40, 1, 0x60c0 + sharp, 0x0093, 0, NULL);
458 }
459
460 if (hue != sd->vold.hue) {
461 sd->vold.hue = hue;
462 if (hue < 0 || hue > sd->vmax.hue)
463 hue = 0;
464
465 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
466 ctrl_out(gspca_dev, 0x40, 1, 0x6002 , 0x007c, 0, NULL);
467 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + hue * (hue < 255), 0x007d,
468 0, NULL);
469 if (hue >= sd->vmax.hue)
470 sd->swapRB = 1;
471 else
472 sd->swapRB = 0;
473 }
474
475 if (gam != sd->vold.gamma) {
476 sd->vold.gamma = gam;
477 if (gam < 0 || gam > sd->vmax.gamma)
478 gam = 0;
479
480 ctrl_out(gspca_dev, 0x40, 1, 0x6000 , 0x00ff, 0, NULL);
481 ctrl_out(gspca_dev, 0x40, 1, 0x6008 , 0x007c, 0, NULL);
482 ctrl_out(gspca_dev, 0x40, 1, 0x6000 + gam, 0x007d, 0, NULL);
483 }
484
485 if (backlight != sd->vold.backlight) {
486 sd->vold.backlight = backlight;
487
488 ctrl_out(gspca_dev, 0x40, 1, 0x6001 , 0x00ff,
489 0, NULL);
490 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight , 0x0024,
491 0, NULL);
492 ctrl_out(gspca_dev, 0x40, 1, 0x601f + backlight - 10, 0x0025,
493 0, NULL);
494 }
495
496 return 0;
497}
498
499static void ov2640_post_unset_alt(struct gspca_dev *gspca_dev)
500{
501 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
502 msleep(20);
503 fetch_validx(gspca_dev, tbl_post_unset_alt,
504 ARRAY_SIZE(tbl_post_unset_alt));
505}
diff --git a/drivers/media/video/gspca/gl860/gl860-ov9655.c b/drivers/media/video/gspca/gl860/gl860-ov9655.c
new file mode 100644
index 000000000000..eda3346f939c
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860-ov9655.c
@@ -0,0 +1,337 @@
1/* @file gl860-ov9655.c
2 * @author Olivier LORIN, from logs done by Simon (Sur3) and Almighurt
3 * on dsd's weblog
4 * @date 2009-08-27
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20/* Sensor : OV9655 */
21
22#include "gl860.h"
23
24static struct validx tbl_init_at_startup[] = {
25 {0x0000, 0x0000}, {0x0010, 0x0010}, {0x0008, 0x00c0}, {0x0001, 0x00c1},
26 {0x0001, 0x00c2}, {0x0020, 0x0006}, {0x006a, 0x000d},
27
28 {0x0040, 0x0000},
29};
30
31static struct validx tbl_commmon[] = {
32 {0x0041, 0x0000}, {0x006a, 0x0007}, {0x0063, 0x0006}, {0x006a, 0x000d},
33 {0x0000, 0x00c0}, {0x0010, 0x0010}, {0x0001, 0x00c1}, {0x0041, 0x00c2},
34 {0x0004, 0x00d8}, {0x0012, 0x0004}, {0x0000, 0x0058}, {0x0040, 0x0000},
35 {0x00f3, 0x0006}, {0x0058, 0x0000}, {0x0048, 0x0000}, {0x0061, 0x0000},
36};
37
38static s32 tbl_length[] = {12, 56, 52, 54, 56, 42, 32, 12};
39
40static u8 *tbl_640[] = {
41 "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
42 ,
43 "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x03\x0b\x57\x0e\x61"
44 "\x0f\x42\x11\x01\x12\x60\x13\x00" "\x14\x3a\x16\x24\x17\x14\x18\x00"
45 "\x19\x01\x1a\x3d\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
46 "\x29\x15\x2a\x00\x2b\x00\x2c\x08"
47 ,
48 "\x32\xff\x33\x00\x34\x3d\x35\x00" "\x36\xfa\x38\x72\x39\x57\x3a\x00"
49 "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc1" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
50 "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xee\x4b\xe7\x4c\xe7"
51 "\x4d\xe7\x4e\xe7"
52 ,
53 "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
54 "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
55 "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x0a\x6b\x5a\x6c\x04"
56 "\x6d\x55\x6e\x00\x6f\x9d"
57 ,
58 "\x70\x15\x71\x78\x72\x00\x73\x00" "\x74\x3a\x75\x35\x76\x01\x77\x02"
59 "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
60 "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
61 "\x8a\x23\x8c\x8d\x90\x7c\x91\x7b"
62 ,
63 "\x9d\x02\x9e\x02\x9f\x74\xa0\x73" "\xa1\x40\xa4\x50\xa5\x68\xa6\x70"
64 "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
65 "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
66 ,
67 "\xbb\xae\xbc\x4f\xbd\x4e\xbe\x6a" "\xbf\x68\xc0\xaa\xc1\xc0\xc2\x01"
68 "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
69 ,
70 "\xd0\x01\xd1\x08\xd2\xe0\xd3\x01" "\xd4\x10\xd5\x80"
71};
72
73static u8 *tbl_800[] = {
74 "\x00\x40\x07\x6a\x06\xf3\x0d\x6a" "\x10\x10\xc1\x01"
75 ,
76 "\x12\x80\x00\x00\x01\x98\x02\x80" "\x03\x12\x04\x01\x0b\x57\x0e\x61"
77 "\x0f\x42\x11\x00\x12\x00\x13\x00" "\x14\x3a\x16\x24\x17\x1b\x18\xbb"
78 "\x19\x01\x1a\x81\x1e\x04\x24\x3c" "\x25\x36\x26\x72\x27\x08\x28\x08"
79 "\x29\x15\x2a\x00\x2b\x00\x2c\x08"
80 ,
81 "\x32\xa4\x33\x00\x34\x3d\x35\x00" "\x36\xf8\x38\x72\x39\x57\x3a\x00"
82 "\x3b\x0c\x3d\x99\x3e\x0c\x3f\xc2" "\x40\xc0\x41\x00\x42\xc0\x43\x0a"
83 "\x44\xf0\x45\x46\x46\x62\x47\x2a" "\x48\x3c\x4a\xec\x4b\xe8\x4c\xe8"
84 "\x4d\xe8\x4e\xe8"
85 ,
86 "\x4f\x98\x50\x98\x51\x00\x52\x28" "\x53\x70\x54\x98\x58\x1a\x59\x85"
87 "\x5a\xa9\x5b\x64\x5c\x84\x5d\x53" "\x5e\x0e\x5f\xf0\x60\xf0\x61\xf0"
88 "\x62\x00\x63\x00\x64\x02\x65\x20" "\x66\x00\x69\x02\x6b\x5a\x6c\x04"
89 "\x6d\x55\x6e\x00\x6f\x9d"
90 ,
91 "\x70\x08\x71\x78\x72\x00\x73\x01" "\x74\x3a\x75\x35\x76\x01\x77\x02"
92 "\x7a\x24\x7b\x04\x7c\x07\x7d\x10" "\x7e\x28\x7f\x36\x80\x44\x81\x52"
93 "\x82\x60\x83\x6c\x84\x78\x85\x8c" "\x86\x9e\x87\xbb\x88\xd2\x89\xe5"
94 "\x8a\x23\x8c\x0d\x90\x90\x91\x90"
95 ,
96 "\x9d\x02\x9e\x02\x9f\x94\xa0\x94" "\xa1\x01\xa4\x50\xa5\x68\xa6\x70"
97 "\xa8\xc1\xa9\xef\xaa\x92\xab\x04" "\xac\x80\xad\x80\xae\x80\xaf\x80"
98 "\xb2\xf2\xb3\x20\xb4\x20\xb5\x00" "\xb6\xaf"
99 ,
100 "\xbb\xae\xbc\x38\xbd\x39\xbe\x01" "\xbf\x01\xc0\xe2\xc1\xc0\xc2\x01"
101 "\xc3\x4e\xc6\x85\xc7\x81\xc9\xe0" "\xca\xe8\xcb\xf0\xcc\xd8\xcd\x93"
102 ,
103 "\xd0\x21\xd1\x18\xd2\xe0\xd3\x01" "\xd4\x28\xd5\x00"
104};
105
106static u8 c04[] = {0x04};
107static u8 dat_post_1[] = "\x04\x00\x10\x20\xa1\x00\x00\x02";
108static u8 dat_post_2[] = "\x10\x10\xc1\x02";
109static u8 dat_post_3[] = "\x04\x00\x10\x7c\xa1\x00\x00\x04";
110static u8 dat_post_4[] = "\x10\x02\xc1\x06";
111static u8 dat_post_5[] = "\x04\x00\x10\x7b\xa1\x00\x00\x08";
112static u8 dat_post_6[] = "\x10\x10\xc1\x05";
113static u8 dat_post_7[] = "\x04\x00\x10\x7c\xa1\x00\x00\x08";
114static u8 dat_post_8[] = "\x04\x00\x10\x7c\xa1\x00\x00\x09";
115
116static struct validx tbl_init_post_alt[] = {
117 {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x603c, 0x00ff},
118 {0x6003, 0x00ff}, {0x6032, 0x00ff}, {0x6032, 0x00ff}, {0x6001, 0x00ff},
119 {0x6000, 0x801e},
120 {0xffff, 0xffff},
121 {0x6004, 0x001e}, {0x6000, 0x801e},
122 {0xffff, 0xffff},
123 {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
124 {0xffff, 0xffff},
125 {0x6004, 0x001e}, {0x6000, 0x801e},
126 {0xffff, 0xffff},
127 {0x6004, 0x001e}, {0x6012, 0x0003},
128 {0xffff, 0xffff},
129 {0x6000, 0x801e},
130 {0xffff, 0xffff},
131 {0x6004, 0x001e}, {0x6000, 0x801e},
132 {0xffff, 0xffff},
133 {0x6004, 0x001e}, {0x6012, 0x0003}, {0x6000, 0x801e},
134 {0xffff, 0xffff},
135 {0x6004, 0x001e}, {0x6000, 0x801e},
136 {0xffff, 0xffff},
137 {0x6004, 0x001e}, {0x6012, 0x0003},
138 {0xffff, 0xffff},
139 {0x6000, 0x801e},
140 {0xffff, 0xffff},
141 {0x6004, 0x001e}, {0x6000, 0x801e},
142 {0xffff, 0xffff},
143 {0x6004, 0x001e}, {0x6012, 0x0003},
144};
145
146static int ov9655_init_at_startup(struct gspca_dev *gspca_dev);
147static int ov9655_configure_alt(struct gspca_dev *gspca_dev);
148static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev);
149static int ov9655_init_post_alt(struct gspca_dev *gspca_dev);
150static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev);
151static int ov9655_camera_settings(struct gspca_dev *gspca_dev);
152/*==========================================================================*/
153
154void ov9655_init_settings(struct gspca_dev *gspca_dev)
155{
156 struct sd *sd = (struct sd *) gspca_dev;
157
158 sd->vcur.backlight = 0;
159 sd->vcur.brightness = 128;
160 sd->vcur.sharpness = 0;
161 sd->vcur.contrast = 0;
162 sd->vcur.gamma = 0;
163 sd->vcur.hue = 0;
164 sd->vcur.saturation = 0;
165 sd->vcur.whitebal = 0;
166
167 sd->vmax.backlight = 0;
168 sd->vmax.brightness = 255;
169 sd->vmax.sharpness = 0;
170 sd->vmax.contrast = 0;
171 sd->vmax.gamma = 0;
172 sd->vmax.hue = 0 + 1;
173 sd->vmax.saturation = 0;
174 sd->vmax.whitebal = 0;
175 sd->vmax.mirror = 0;
176 sd->vmax.flip = 0;
177 sd->vmax.AC50Hz = 0;
178
179 sd->dev_camera_settings = ov9655_camera_settings;
180 sd->dev_init_at_startup = ov9655_init_at_startup;
181 sd->dev_configure_alt = ov9655_configure_alt;
182 sd->dev_init_pre_alt = ov9655_init_pre_alt;
183 sd->dev_post_unset_alt = ov9655_post_unset_alt;
184}
185
186/*==========================================================================*/
187
188static int ov9655_init_at_startup(struct gspca_dev *gspca_dev)
189{
190 fetch_validx(gspca_dev, tbl_init_at_startup,
191 ARRAY_SIZE(tbl_init_at_startup));
192 fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
193/* ctrl_out(gspca_dev, 0x40, 11, 0x0000, 0x0000, 0, NULL);*/
194
195 return 0;
196}
197
198static int ov9655_init_pre_alt(struct gspca_dev *gspca_dev)
199{
200 struct sd *sd = (struct sd *) gspca_dev;
201
202 sd->vold.brightness = -1;
203 sd->vold.hue = -1;
204
205 fetch_validx(gspca_dev, tbl_commmon, ARRAY_SIZE(tbl_commmon));
206
207 ov9655_init_post_alt(gspca_dev);
208
209 return 0;
210}
211
212static int ov9655_init_post_alt(struct gspca_dev *gspca_dev)
213{
214 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
215 s32 n; /* reserved for FETCH macros */
216 s32 i;
217 u8 **tbl;
218
219 ctrl_out(gspca_dev, 0x40, 5, 0x0001, 0x0000, 0, NULL);
220
221 tbl = (reso == IMAGE_640) ? tbl_640 : tbl_800;
222
223 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
224 tbl_length[0], tbl[0]);
225 for (i = 1; i < 7; i++)
226 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200,
227 tbl_length[i], tbl[i]);
228 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200,
229 tbl_length[7], tbl[7]);
230
231 n = fetch_validx(gspca_dev, tbl_init_post_alt,
232 ARRAY_SIZE(tbl_init_post_alt));
233
234 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
235 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
236 ARRAY_SIZE(tbl_init_post_alt), n);
237 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
238 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
239 ARRAY_SIZE(tbl_init_post_alt), n);
240 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
241 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
242 ARRAY_SIZE(tbl_init_post_alt), n);
243 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
244 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
245 ARRAY_SIZE(tbl_init_post_alt), n);
246 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
247 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
248 ARRAY_SIZE(tbl_init_post_alt), n);
249
250 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
251 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
252 ARRAY_SIZE(tbl_init_post_alt), n);
253 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
254 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
255 ARRAY_SIZE(tbl_init_post_alt), n);
256 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
257 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
258 ARRAY_SIZE(tbl_init_post_alt), n);
259 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
260 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
261 ARRAY_SIZE(tbl_init_post_alt), n);
262 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
263 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
264 ARRAY_SIZE(tbl_init_post_alt), n);
265
266 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
267 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
268 ARRAY_SIZE(tbl_init_post_alt), n);
269 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x801e, 1, c04);
270 keep_on_fetching_validx(gspca_dev, tbl_init_post_alt,
271 ARRAY_SIZE(tbl_init_post_alt), n);
272
273 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_1);
274
275 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_2);
276 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_3);
277
278 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_4);
279 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_5);
280
281 ctrl_out(gspca_dev, 0x40, 3, 0x0000, 0x0200, 4, dat_post_6);
282 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_7);
283
284 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_post_8);
285
286 ov9655_camera_settings(gspca_dev);
287
288 return 0;
289}
290
291static int ov9655_configure_alt(struct gspca_dev *gspca_dev)
292{
293 s32 reso = gspca_dev->cam.cam_mode[(s32) gspca_dev->curr_mode].priv;
294
295 switch (reso) {
296 case IMAGE_640:
297 gspca_dev->alt = 1 + 1;
298 break;
299
300 default:
301 gspca_dev->alt = 1 + 1;
302 break;
303 }
304 return 0;
305}
306
307static int ov9655_camera_settings(struct gspca_dev *gspca_dev)
308{
309 struct sd *sd = (struct sd *) gspca_dev;
310
311 u8 dat_bright[] = "\x04\x00\x10\x7c\xa1\x00\x00\x70";
312
313 s32 bright = sd->vcur.brightness;
314 s32 hue = sd->vcur.hue;
315
316 if (bright != sd->vold.brightness) {
317 sd->vold.brightness = bright;
318 if (bright < 0 || bright > sd->vmax.brightness)
319 bright = 0;
320
321 dat_bright[3] = bright;
322 ctrl_out(gspca_dev, 0x40, 3, 0x6000, 0x0200, 8, dat_bright);
323 }
324
325 if (hue != sd->vold.hue) {
326 sd->vold.hue = hue;
327 sd->swapRB = (hue != 0);
328 }
329
330 return 0;
331}
332
333static void ov9655_post_unset_alt(struct gspca_dev *gspca_dev)
334{
335 ctrl_out(gspca_dev, 0x40, 5, 0x0000, 0x0000, 0, NULL);
336 ctrl_out(gspca_dev, 0x40, 1, 0x0061, 0x0000, 0, NULL);
337}
diff --git a/drivers/media/video/gspca/gl860/gl860.c b/drivers/media/video/gspca/gl860/gl860.c
new file mode 100644
index 000000000000..6ef59ac7f502
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860.c
@@ -0,0 +1,785 @@
1/* @file gl860.c
2 * @date 2009-08-27
3 *
4 * Genesys Logic webcam with gl860 subdrivers
5 *
6 * Driver by Olivier Lorin <o.lorin@laposte.net>
7 * GSPCA by Jean-Francois Moine <http://moinejf.free.fr>
8 * Thanks BUGabundo and Malmostoso for your amazing help!
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23#include "gspca.h"
24#include "gl860.h"
25
26MODULE_AUTHOR("Olivier Lorin <lorin@laposte.net>");
27MODULE_DESCRIPTION("GSPCA/Genesys Logic GL860 USB Camera Driver");
28MODULE_LICENSE("GPL");
29
30/*======================== static function declarations ====================*/
31
32static void (*dev_init_settings)(struct gspca_dev *gspca_dev);
33
34static int sd_config(struct gspca_dev *gspca_dev,
35 const struct usb_device_id *id);
36static int sd_init(struct gspca_dev *gspca_dev);
37static int sd_isoc_init(struct gspca_dev *gspca_dev);
38static int sd_start(struct gspca_dev *gspca_dev);
39static void sd_stop0(struct gspca_dev *gspca_dev);
40static void sd_pkt_scan(struct gspca_dev *gspca_dev,
41 struct gspca_frame *frame, u8 *data, s32 len);
42static void sd_callback(struct gspca_dev *gspca_dev);
43
44static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
45 s32 vendor_id, s32 product_id);
46
47/*============================ driver options ==============================*/
48
49static s32 AC50Hz = 0xff;
50module_param(AC50Hz, int, 0644);
51MODULE_PARM_DESC(AC50Hz, " Does AC power frequency is 50Hz? (0/1)");
52
53static char sensor[7];
54module_param_string(sensor, sensor, sizeof(sensor), 0644);
55MODULE_PARM_DESC(sensor,
56 " Driver sensor ('MI1320'/'MI2020'/'OV9655'/'OV2640'/'')");
57
58/*============================ webcam controls =============================*/
59
60/* Functions to get and set a control value */
61#define SD_SETGET(thename) \
62static int sd_set_##thename(struct gspca_dev *gspca_dev, s32 val)\
63{\
64 struct sd *sd = (struct sd *) gspca_dev;\
65\
66 sd->vcur.thename = val;\
67 if (gspca_dev->streaming)\
68 sd->dev_camera_settings(gspca_dev);\
69 return 0;\
70} \
71static int sd_get_##thename(struct gspca_dev *gspca_dev, s32 *val)\
72{\
73 struct sd *sd = (struct sd *) gspca_dev;\
74\
75 *val = sd->vcur.thename;\
76 return 0;\
77}
78
79SD_SETGET(mirror)
80SD_SETGET(flip)
81SD_SETGET(AC50Hz)
82SD_SETGET(backlight)
83SD_SETGET(brightness)
84SD_SETGET(gamma)
85SD_SETGET(hue)
86SD_SETGET(saturation)
87SD_SETGET(sharpness)
88SD_SETGET(whitebal)
89SD_SETGET(contrast)
90
91#define GL860_NCTRLS 11
92
93/* control table */
94static struct ctrl sd_ctrls_mi1320[GL860_NCTRLS];
95static struct ctrl sd_ctrls_mi2020[GL860_NCTRLS];
96static struct ctrl sd_ctrls_mi2020b[GL860_NCTRLS];
97static struct ctrl sd_ctrls_ov2640[GL860_NCTRLS];
98static struct ctrl sd_ctrls_ov9655[GL860_NCTRLS];
99
100#define SET_MY_CTRL(theid, \
101 thetype, thelabel, thename) \
102 if (sd->vmax.thename != 0) {\
103 sd_ctrls[nCtrls].qctrl.id = theid;\
104 sd_ctrls[nCtrls].qctrl.type = thetype;\
105 strcpy(sd_ctrls[nCtrls].qctrl.name, thelabel);\
106 sd_ctrls[nCtrls].qctrl.minimum = 0;\
107 sd_ctrls[nCtrls].qctrl.maximum = sd->vmax.thename;\
108 sd_ctrls[nCtrls].qctrl.default_value = sd->vcur.thename;\
109 sd_ctrls[nCtrls].qctrl.step = \
110 (sd->vmax.thename < 16) ? 1 : sd->vmax.thename/16;\
111 sd_ctrls[nCtrls].set = sd_set_##thename;\
112 sd_ctrls[nCtrls].get = sd_get_##thename;\
113 nCtrls++;\
114 }
115
116static int gl860_build_control_table(struct gspca_dev *gspca_dev)
117{
118 struct sd *sd = (struct sd *) gspca_dev;
119 struct ctrl *sd_ctrls;
120 int nCtrls = 0;
121
122 if (_MI1320_)
123 sd_ctrls = sd_ctrls_mi1320;
124 else if (_MI2020_)
125 sd_ctrls = sd_ctrls_mi2020;
126 else if (_MI2020b_)
127 sd_ctrls = sd_ctrls_mi2020b;
128 else if (_OV2640_)
129 sd_ctrls = sd_ctrls_ov2640;
130 else if (_OV9655_)
131 sd_ctrls = sd_ctrls_ov9655;
132 else
133 return 0;
134
135 memset(sd_ctrls, 0, GL860_NCTRLS * sizeof(struct ctrl));
136
137 SET_MY_CTRL(V4L2_CID_BRIGHTNESS,
138 V4L2_CTRL_TYPE_INTEGER, "Brightness", brightness)
139 SET_MY_CTRL(V4L2_CID_SHARPNESS,
140 V4L2_CTRL_TYPE_INTEGER, "Sharpness", sharpness)
141 SET_MY_CTRL(V4L2_CID_CONTRAST,
142 V4L2_CTRL_TYPE_INTEGER, "Contrast", contrast)
143 SET_MY_CTRL(V4L2_CID_GAMMA,
144 V4L2_CTRL_TYPE_INTEGER, "Gamma", gamma)
145 SET_MY_CTRL(V4L2_CID_HUE,
146 V4L2_CTRL_TYPE_INTEGER, "Palette", hue)
147 SET_MY_CTRL(V4L2_CID_SATURATION,
148 V4L2_CTRL_TYPE_INTEGER, "Saturation", saturation)
149 SET_MY_CTRL(V4L2_CID_WHITE_BALANCE_TEMPERATURE,
150 V4L2_CTRL_TYPE_INTEGER, "White Bal.", whitebal)
151 SET_MY_CTRL(V4L2_CID_BACKLIGHT_COMPENSATION,
152 V4L2_CTRL_TYPE_INTEGER, "Backlight" , backlight)
153
154 SET_MY_CTRL(V4L2_CID_HFLIP,
155 V4L2_CTRL_TYPE_BOOLEAN, "Mirror", mirror)
156 SET_MY_CTRL(V4L2_CID_VFLIP,
157 V4L2_CTRL_TYPE_BOOLEAN, "Flip", flip)
158 SET_MY_CTRL(V4L2_CID_POWER_LINE_FREQUENCY,
159 V4L2_CTRL_TYPE_BOOLEAN, "50Hz", AC50Hz)
160
161 return nCtrls;
162}
163
164/*==================== sud-driver structure initialisation =================*/
165
166static struct sd_desc sd_desc_mi1320 = {
167 .name = MODULE_NAME,
168 .ctrls = sd_ctrls_mi1320,
169 .nctrls = GL860_NCTRLS,
170 .config = sd_config,
171 .init = sd_init,
172 .isoc_init = sd_isoc_init,
173 .start = sd_start,
174 .stop0 = sd_stop0,
175 .pkt_scan = sd_pkt_scan,
176 .dq_callback = sd_callback,
177};
178
179static struct sd_desc sd_desc_mi2020 = {
180 .name = MODULE_NAME,
181 .ctrls = sd_ctrls_mi2020,
182 .nctrls = GL860_NCTRLS,
183 .config = sd_config,
184 .init = sd_init,
185 .isoc_init = sd_isoc_init,
186 .start = sd_start,
187 .stop0 = sd_stop0,
188 .pkt_scan = sd_pkt_scan,
189 .dq_callback = sd_callback,
190};
191
192static struct sd_desc sd_desc_mi2020b = {
193 .name = MODULE_NAME,
194 .ctrls = sd_ctrls_mi2020b,
195 .nctrls = GL860_NCTRLS,
196 .config = sd_config,
197 .init = sd_init,
198 .isoc_init = sd_isoc_init,
199 .start = sd_start,
200 .stop0 = sd_stop0,
201 .pkt_scan = sd_pkt_scan,
202 .dq_callback = sd_callback,
203};
204
205static struct sd_desc sd_desc_ov2640 = {
206 .name = MODULE_NAME,
207 .ctrls = sd_ctrls_ov2640,
208 .nctrls = GL860_NCTRLS,
209 .config = sd_config,
210 .init = sd_init,
211 .isoc_init = sd_isoc_init,
212 .start = sd_start,
213 .stop0 = sd_stop0,
214 .pkt_scan = sd_pkt_scan,
215 .dq_callback = sd_callback,
216};
217
218static struct sd_desc sd_desc_ov9655 = {
219 .name = MODULE_NAME,
220 .ctrls = sd_ctrls_ov9655,
221 .nctrls = GL860_NCTRLS,
222 .config = sd_config,
223 .init = sd_init,
224 .isoc_init = sd_isoc_init,
225 .start = sd_start,
226 .stop0 = sd_stop0,
227 .pkt_scan = sd_pkt_scan,
228 .dq_callback = sd_callback,
229};
230
231/*=========================== sub-driver image sizes =======================*/
232
233static struct v4l2_pix_format mi2020_mode[] = {
234 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
235 .bytesperline = 640,
236 .sizeimage = 640 * 480,
237 .colorspace = V4L2_COLORSPACE_SRGB,
238 .priv = 0
239 },
240 { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
241 .bytesperline = 800,
242 .sizeimage = 800 * 600,
243 .colorspace = V4L2_COLORSPACE_SRGB,
244 .priv = 1
245 },
246 {1280, 1024, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
247 .bytesperline = 1280,
248 .sizeimage = 1280 * 1024,
249 .colorspace = V4L2_COLORSPACE_SRGB,
250 .priv = 2
251 },
252 {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
253 .bytesperline = 1600,
254 .sizeimage = 1600 * 1200,
255 .colorspace = V4L2_COLORSPACE_SRGB,
256 .priv = 3
257 },
258};
259
260static struct v4l2_pix_format ov2640_mode[] = {
261 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
262 .bytesperline = 640,
263 .sizeimage = 640 * 480,
264 .colorspace = V4L2_COLORSPACE_SRGB,
265 .priv = 0
266 },
267 { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
268 .bytesperline = 800,
269 .sizeimage = 800 * 600,
270 .colorspace = V4L2_COLORSPACE_SRGB,
271 .priv = 1
272 },
273 {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
274 .bytesperline = 1280,
275 .sizeimage = 1280 * 960,
276 .colorspace = V4L2_COLORSPACE_SRGB,
277 .priv = 2
278 },
279 {1600, 1200, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
280 .bytesperline = 1600,
281 .sizeimage = 1600 * 1200,
282 .colorspace = V4L2_COLORSPACE_SRGB,
283 .priv = 3
284 },
285};
286
287static struct v4l2_pix_format mi1320_mode[] = {
288 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
289 .bytesperline = 640,
290 .sizeimage = 640 * 480,
291 .colorspace = V4L2_COLORSPACE_SRGB,
292 .priv = 0
293 },
294 { 800, 600, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
295 .bytesperline = 800,
296 .sizeimage = 800 * 600,
297 .colorspace = V4L2_COLORSPACE_SRGB,
298 .priv = 1
299 },
300 {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
301 .bytesperline = 1280,
302 .sizeimage = 1280 * 960,
303 .colorspace = V4L2_COLORSPACE_SRGB,
304 .priv = 2
305 },
306};
307
308static struct v4l2_pix_format ov9655_mode[] = {
309 { 640, 480, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
310 .bytesperline = 640,
311 .sizeimage = 640 * 480,
312 .colorspace = V4L2_COLORSPACE_SRGB,
313 .priv = 0
314 },
315 {1280, 960, V4L2_PIX_FMT_SGBRG8, V4L2_FIELD_NONE,
316 .bytesperline = 1280,
317 .sizeimage = 1280 * 960,
318 .colorspace = V4L2_COLORSPACE_SRGB,
319 .priv = 1
320 },
321};
322
323/*========================= sud-driver functions ===========================*/
324
325/* This function is called at probe time */
326static int sd_config(struct gspca_dev *gspca_dev,
327 const struct usb_device_id *id)
328{
329 struct sd *sd = (struct sd *) gspca_dev;
330 struct cam *cam;
331 s32 vendor_id, product_id;
332
333 /* Get USB VendorID and ProductID */
334 vendor_id = le16_to_cpu(id->idVendor);
335 product_id = le16_to_cpu(id->idProduct);
336
337 sd->nbRightUp = 1;
338 sd->nbIm = -1;
339
340 sd->sensor = 0xff;
341 if (strcmp(sensor, "MI1320") == 0)
342 sd->sensor = ID_MI1320;
343 else if (strcmp(sensor, "OV2640") == 0)
344 sd->sensor = ID_OV2640;
345 else if (strcmp(sensor, "OV9655") == 0)
346 sd->sensor = ID_OV9655;
347 else if (strcmp(sensor, "MI2020") == 0)
348 sd->sensor = ID_MI2020;
349 else if (strcmp(sensor, "MI2020b") == 0)
350 sd->sensor = ID_MI2020b;
351
352 /* Get sensor and set the suitable init/start/../stop functions */
353 if (gl860_guess_sensor(gspca_dev, vendor_id, product_id) == -1)
354 return -1;
355
356 cam = &gspca_dev->cam;
357 gspca_dev->nbalt = 4;
358
359 switch (sd->sensor) {
360 case ID_MI1320:
361 gspca_dev->sd_desc = &sd_desc_mi1320;
362 cam->cam_mode = mi1320_mode;
363 cam->nmodes = ARRAY_SIZE(mi1320_mode);
364 dev_init_settings = mi1320_init_settings;
365 break;
366
367 case ID_MI2020:
368 gspca_dev->sd_desc = &sd_desc_mi2020;
369 cam->cam_mode = mi2020_mode;
370 cam->nmodes = ARRAY_SIZE(mi2020_mode);
371 dev_init_settings = mi2020_init_settings;
372 break;
373
374 case ID_MI2020b:
375 gspca_dev->sd_desc = &sd_desc_mi2020b;
376 cam->cam_mode = mi2020_mode;
377 cam->nmodes = ARRAY_SIZE(mi2020_mode);
378 dev_init_settings = mi2020_init_settings;
379 break;
380
381 case ID_OV2640:
382 gspca_dev->sd_desc = &sd_desc_ov2640;
383 cam->cam_mode = ov2640_mode;
384 cam->nmodes = ARRAY_SIZE(ov2640_mode);
385 dev_init_settings = ov2640_init_settings;
386 break;
387
388 case ID_OV9655:
389 gspca_dev->sd_desc = &sd_desc_ov9655;
390 cam->cam_mode = ov9655_mode;
391 cam->nmodes = ARRAY_SIZE(ov9655_mode);
392 dev_init_settings = ov9655_init_settings;
393 break;
394 }
395
396 dev_init_settings(gspca_dev);
397 if (AC50Hz != 0xff)
398 ((struct sd *) gspca_dev)->vcur.AC50Hz = AC50Hz;
399 gl860_build_control_table(gspca_dev);
400
401 return 0;
402}
403
404/* This function is called at probe time after sd_config */
405static int sd_init(struct gspca_dev *gspca_dev)
406{
407 struct sd *sd = (struct sd *) gspca_dev;
408
409 return sd->dev_init_at_startup(gspca_dev);
410}
411
412/* This function is called before to choose the alt setting */
413static int sd_isoc_init(struct gspca_dev *gspca_dev)
414{
415 struct sd *sd = (struct sd *) gspca_dev;
416
417 return sd->dev_configure_alt(gspca_dev);
418}
419
420/* This function is called to start the webcam */
421static int sd_start(struct gspca_dev *gspca_dev)
422{
423 struct sd *sd = (struct sd *) gspca_dev;
424
425 return sd->dev_init_pre_alt(gspca_dev);
426}
427
428/* This function is called to stop the webcam */
429static void sd_stop0(struct gspca_dev *gspca_dev)
430{
431 struct sd *sd = (struct sd *) gspca_dev;
432
433 return sd->dev_post_unset_alt(gspca_dev);
434}
435
436/* This function is called when an image is being received */
437static void sd_pkt_scan(struct gspca_dev *gspca_dev,
438 struct gspca_frame *frame, u8 *data, s32 len)
439{
440 struct sd *sd = (struct sd *) gspca_dev;
441 static s32 nSkipped;
442
443 s32 mode = (s32) gspca_dev->curr_mode;
444 s32 nToSkip =
445 sd->swapRB * (gspca_dev->cam.cam_mode[mode].bytesperline + 1);
446
447 /* Test only against 0202h, so endianess does not matter */
448 switch (*(s16 *) data) {
449 case 0x0202: /* End of frame, start a new one */
450 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame, data, 0);
451 nSkipped = 0;
452 if (sd->nbIm >= 0 && sd->nbIm < 10)
453 sd->nbIm++;
454 gspca_frame_add(gspca_dev, FIRST_PACKET, frame, data, 0);
455 break;
456
457 default:
458 data += 2;
459 len -= 2;
460 if (nSkipped + len <= nToSkip)
461 nSkipped += len;
462 else {
463 if (nSkipped < nToSkip && nSkipped + len > nToSkip) {
464 data += nToSkip - nSkipped;
465 len -= nToSkip - nSkipped;
466 nSkipped = nToSkip + 1;
467 }
468 gspca_frame_add(gspca_dev,
469 INTER_PACKET, frame, data, len);
470 }
471 break;
472 }
473}
474
475/* This function is called when an image has been read */
476/* This function is used to monitor webcam orientation */
477static void sd_callback(struct gspca_dev *gspca_dev)
478{
479 struct sd *sd = (struct sd *) gspca_dev;
480
481 if (!_OV9655_) {
482 u8 state;
483 u8 upsideDown;
484
485 /* Probe sensor orientation */
486 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0000, 1, (void *)&state);
487
488 /* C8/40 means upside-down (looking backwards) */
489 /* D8/50 means right-up (looking onwards) */
490 upsideDown = (state == 0xc8 || state == 0x40);
491
492 if (upsideDown && sd->nbRightUp > -4) {
493 if (sd->nbRightUp > 0)
494 sd->nbRightUp = 0;
495 if (sd->nbRightUp == -3) {
496 sd->mirrorMask = 1;
497 sd->waitSet = 1;
498 }
499 sd->nbRightUp--;
500 }
501 if (!upsideDown && sd->nbRightUp < 4) {
502 if (sd->nbRightUp < 0)
503 sd->nbRightUp = 0;
504 if (sd->nbRightUp == 3) {
505 sd->mirrorMask = 0;
506 sd->waitSet = 1;
507 }
508 sd->nbRightUp++;
509 }
510 }
511
512 if (sd->waitSet)
513 sd->dev_camera_settings(gspca_dev);
514}
515
516/*=================== USB driver structure initialisation ==================*/
517
518static const __devinitdata struct usb_device_id device_table[] = {
519 {USB_DEVICE(0x05e3, 0x0503)},
520 {USB_DEVICE(0x05e3, 0xf191)},
521 {}
522};
523
524MODULE_DEVICE_TABLE(usb, device_table);
525
526static int sd_probe(struct usb_interface *intf,
527 const struct usb_device_id *id)
528{
529 struct gspca_dev *gspca_dev;
530 s32 ret;
531
532 ret = gspca_dev_probe(intf, id,
533 &sd_desc_mi1320, sizeof(struct sd), THIS_MODULE);
534
535 if (ret >= 0) {
536 gspca_dev = usb_get_intfdata(intf);
537
538 PDEBUG(D_PROBE,
539 "Camera is now controlling video device /dev/video%d",
540 gspca_dev->vdev.minor);
541 }
542
543 return ret;
544}
545
546static void sd_disconnect(struct usb_interface *intf)
547{
548 gspca_disconnect(intf);
549}
550
551static struct usb_driver sd_driver = {
552 .name = MODULE_NAME,
553 .id_table = device_table,
554 .probe = sd_probe,
555 .disconnect = sd_disconnect,
556#ifdef CONFIG_PM
557 .suspend = gspca_suspend,
558 .resume = gspca_resume,
559#endif
560};
561
562/*====================== Init and Exit module functions ====================*/
563
564static int __init sd_mod_init(void)
565{
566 PDEBUG(D_PROBE, "driver startup - version %s", DRIVER_VERSION);
567
568 if (usb_register(&sd_driver) < 0)
569 return -1;
570 PDEBUG(D_PROBE, "driver registered");
571
572 return 0;
573}
574
575static void __exit sd_mod_exit(void)
576{
577 usb_deregister(&sd_driver);
578 PDEBUG(D_PROBE, "driver deregistered");
579}
580
581module_init(sd_mod_init);
582module_exit(sd_mod_exit);
583
584/*==========================================================================*/
585
586int gl860_RTx(struct gspca_dev *gspca_dev,
587 unsigned char pref, u32 req, u16 val, u16 index,
588 s32 len, void *pdata)
589{
590 struct usb_device *udev = gspca_dev->dev;
591 s32 r = 0;
592
593 if (pref == 0x40) { /* Send */
594 if (len > 0) {
595 memcpy(gspca_dev->usb_buf, pdata, len);
596 r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
597 req, pref, val, index,
598 gspca_dev->usb_buf,
599 len, 400 + 200 * (len > 1));
600 } else {
601 r = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
602 req, pref, val, index, NULL, len, 400);
603 }
604 } else { /* Receive */
605 if (len > 0) {
606 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
607 req, pref, val, index,
608 gspca_dev->usb_buf,
609 len, 400 + 200 * (len > 1));
610 memcpy(pdata, gspca_dev->usb_buf, len);
611 } else {
612 r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
613 req, pref, val, index, NULL, len, 400);
614 }
615 }
616
617 if (r < 0)
618 PDEBUG(D_ERR,
619 "ctrl transfer failed %4d "
620 "[p%02x r%d v%04x i%04x len%d]",
621 r, pref, req, val, index, len);
622 else if (len > 1 && r < len)
623 PDEBUG(D_ERR, "short ctrl transfer %d/%d", r, len);
624
625 if ((_MI2020_ || _MI2020b_ || _MI2020c_) && (val || index))
626 msleep(1);
627 if (_OV2640_)
628 msleep(1);
629
630 return r;
631}
632
633int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len)
634{
635 int n;
636
637 for (n = 0; n < len; n++) {
638 if (tbl[n].idx != 0xffff)
639 ctrl_out(gspca_dev, 0x40, 1, tbl[n].val,
640 tbl[n].idx, 0, NULL);
641 else if (tbl[n].val == 0xffff)
642 break;
643 else
644 msleep(tbl[n].val);
645 }
646 return n;
647}
648
649int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
650 int len, int n)
651{
652 while (++n < len) {
653 if (tbl[n].idx != 0xffff)
654 ctrl_out(gspca_dev, 0x40, 1, tbl[n].val, tbl[n].idx,
655 0, NULL);
656 else if (tbl[n].val == 0xffff)
657 break;
658 else
659 msleep(tbl[n].val);
660 }
661 return n;
662}
663
664void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len)
665{
666 int n;
667
668 for (n = 0; n < len; n++) {
669 if (memcmp(tbl[n].data, "\xff\xff\xff", 3) != 0)
670 ctrl_out(gspca_dev, 0x40, 3, 0x7a00, tbl[n].idx,
671 3, tbl[n].data);
672 else
673 msleep(tbl[n].idx);
674 }
675}
676
677static int gl860_guess_sensor(struct gspca_dev *gspca_dev,
678 s32 vendor_id, s32 product_id)
679{
680 struct sd *sd = (struct sd *) gspca_dev;
681 u8 probe, nb26, nb96, nOV, ntry;
682
683 if (product_id == 0xf191)
684 sd->sensor = ID_MI1320;
685
686 if (sd->sensor == 0xff) {
687 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
688 ctrl_in(gspca_dev, 0xc0, 2, 0x0000, 0x0004, 1, &probe);
689
690 ctrl_out(gspca_dev, 0x40, 1, 0x0000, 0x0000, 0, NULL);
691 msleep(3);
692 ctrl_out(gspca_dev, 0x40, 1, 0x0010, 0x0010, 0, NULL);
693 msleep(3);
694 ctrl_out(gspca_dev, 0x40, 1, 0x0008, 0x00c0, 0, NULL);
695 msleep(3);
696 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c1, 0, NULL);
697 msleep(3);
698 ctrl_out(gspca_dev, 0x40, 1, 0x0001, 0x00c2, 0, NULL);
699 msleep(3);
700 ctrl_out(gspca_dev, 0x40, 1, 0x0020, 0x0006, 0, NULL);
701 msleep(3);
702 ctrl_out(gspca_dev, 0x40, 1, 0x006a, 0x000d, 0, NULL);
703 msleep(56);
704
705 nOV = 0;
706 for (ntry = 0; ntry < 4; ntry++) {
707 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000, 0, NULL);
708 msleep(3);
709 ctrl_out(gspca_dev, 0x40, 1, 0x0063, 0x0006, 0, NULL);
710 msleep(3);
711 ctrl_out(gspca_dev, 0x40, 1, 0x7a00, 0x8030, 0, NULL);
712 msleep(10);
713 ctrl_in(gspca_dev, 0xc0, 2, 0x7a00, 0x8030, 1, &probe);
714 PDEBUG(D_PROBE, "1st probe=%02x", probe);
715 if (probe == 0xff)
716 nOV++;
717 }
718
719 if (nOV) {
720 PDEBUG(D_PROBE, "0xff -> sensor OVXXXX");
721 PDEBUG(D_PROBE, "Probing for sensor OV2640 or OV9655");
722
723 nb26 = nb96 = 0;
724 for (ntry = 0; ntry < 4; ntry++) {
725 ctrl_out(gspca_dev, 0x40, 1, 0x0040, 0x0000,
726 0, NULL);
727 msleep(3);
728 ctrl_out(gspca_dev, 0x40, 1, 0x6000, 0x800a,
729 0, NULL);
730 msleep(10);
731 /* Wait for 26(OV2640) or 96(OV9655) */
732 ctrl_in(gspca_dev, 0xc0, 2, 0x6000, 0x800a,
733 1, &probe);
734
735 PDEBUG(D_PROBE, "2nd probe=%02x", probe);
736 if (probe == 0x00)
737 nb26++;
738 if (probe == 0x26 || probe == 0x40) {
739 sd->sensor = ID_OV2640;
740 nb26 += 4;
741 break;
742 }
743 if (probe == 0x96 || probe == 0x55) {
744 sd->sensor = ID_OV9655;
745 nb96 += 4;
746 break;
747 }
748 if (probe == 0xff)
749 nb96++;
750 msleep(3);
751 }
752 if (nb26 < 4 && nb96 < 4) {
753 PDEBUG(D_PROBE, "No relevant answer ");
754 PDEBUG(D_PROBE, "* 1.3Mpixels -> use OV9655");
755 PDEBUG(D_PROBE, "* 2.0Mpixels -> use OV2640");
756 PDEBUG(D_PROBE,
757 "To force a sensor, add that line to "
758 "/etc/modprobe.d/options.conf:");
759 PDEBUG(D_PROBE, "options gspca_gl860 "
760 "sensor=\"OV2640\" or \"OV9655\"");
761 return -1;
762 }
763 } else { /* probe = 0 */
764 PDEBUG(D_PROBE, "No 0xff -> sensor MI2020");
765 sd->sensor = ID_MI2020;
766 }
767 }
768
769 if (_MI1320_) {
770 PDEBUG(D_PROBE, "05e3:f191 sensor MI1320 (1.3M)");
771 } else if (_MI2020_) {
772 PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 (2.0M)");
773 } else if (_MI2020b_) {
774 PDEBUG(D_PROBE, "05e3:0503 sensor MI2020 alt. driver (2.0M)");
775 } else if (_OV9655_) {
776 PDEBUG(D_PROBE, "05e3:0503 sensor OV9655 (1.3M)");
777 } else if (_OV2640_) {
778 PDEBUG(D_PROBE, "05e3:0503 sensor OV2640 (2.0M)");
779 } else {
780 PDEBUG(D_PROBE, "***** Unknown sensor *****");
781 return -1;
782 }
783
784 return 0;
785}
diff --git a/drivers/media/video/gspca/gl860/gl860.h b/drivers/media/video/gspca/gl860/gl860.h
new file mode 100644
index 000000000000..cef4e24c1e61
--- /dev/null
+++ b/drivers/media/video/gspca/gl860/gl860.h
@@ -0,0 +1,108 @@
1/* @file gl860.h
2 * @author Olivier LORIN, tiré du pilote Syntek par Nicolas VIVIEN
3 * @date 2009-08-27
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18#ifndef GL860_DEV_H
19#define GL860_DEV_H
20#include <linux/version.h>
21
22#include "gspca.h"
23
24#define MODULE_NAME "gspca_gl860"
25#define DRIVER_VERSION "0.9d10"
26
27#define ctrl_in gl860_RTx
28#define ctrl_out gl860_RTx
29
30#define ID_MI1320 1
31#define ID_OV2640 2
32#define ID_OV9655 4
33#define ID_MI2020 8
34#define ID_MI2020b 16
35
36#define _MI1320_ (((struct sd *) gspca_dev)->sensor == ID_MI1320)
37#define _MI2020_ (((struct sd *) gspca_dev)->sensor == ID_MI2020)
38#define _MI2020b_ (((struct sd *) gspca_dev)->sensor == ID_MI2020b)
39#define _MI2020c_ 0
40#define _OV2640_ (((struct sd *) gspca_dev)->sensor == ID_OV2640)
41#define _OV9655_ (((struct sd *) gspca_dev)->sensor == ID_OV9655)
42
43#define IMAGE_640 0
44#define IMAGE_800 1
45#define IMAGE_1280 2
46#define IMAGE_1600 3
47
48struct sd_gl860 {
49 u16 backlight;
50 u16 brightness;
51 u16 sharpness;
52 u16 contrast;
53 u16 gamma;
54 u16 hue;
55 u16 saturation;
56 u16 whitebal;
57 u8 mirror;
58 u8 flip;
59 u8 AC50Hz;
60};
61
62/* Specific webcam descriptor */
63struct sd {
64 struct gspca_dev gspca_dev; /* !! must be the first item */
65
66 struct sd_gl860 vcur;
67 struct sd_gl860 vold;
68 struct sd_gl860 vmax;
69
70 int (*dev_configure_alt) (struct gspca_dev *);
71 int (*dev_init_at_startup)(struct gspca_dev *);
72 int (*dev_init_pre_alt) (struct gspca_dev *);
73 void (*dev_post_unset_alt) (struct gspca_dev *);
74 int (*dev_camera_settings)(struct gspca_dev *);
75
76 u8 swapRB;
77 u8 mirrorMask;
78 u8 sensor;
79 s32 nbIm;
80 s32 nbRightUp;
81 u8 waitSet;
82};
83
84struct validx {
85 u16 val;
86 u16 idx;
87};
88
89struct idxdata {
90 u8 idx;
91 u8 data[3];
92};
93
94int fetch_validx(struct gspca_dev *gspca_dev, struct validx *tbl, int len);
95int keep_on_fetching_validx(struct gspca_dev *gspca_dev, struct validx *tbl,
96 int len, int n);
97void fetch_idxdata(struct gspca_dev *gspca_dev, struct idxdata *tbl, int len);
98
99int gl860_RTx(struct gspca_dev *gspca_dev,
100 unsigned char pref, u32 req, u16 val, u16 index,
101 s32 len, void *pdata);
102
103void mi1320_init_settings(struct gspca_dev *);
104void ov2640_init_settings(struct gspca_dev *);
105void ov9655_init_settings(struct gspca_dev *);
106void mi2020_init_settings(struct gspca_dev *);
107
108#endif
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index dbfa3ed6e8ef..a11c97ebeb0f 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -312,6 +312,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
312 312
313 /* create the JPEG header */ 313 /* create the JPEG header */
314 dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL); 314 dev->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
315 if (dev->jpeg_hdr == NULL)
316 return -ENOMEM;
315 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width, 317 jpeg_define(dev->jpeg_hdr, gspca_dev->height, gspca_dev->width,
316 0x21); /* JPEG 422 */ 318 0x21); /* JPEG 422 */
317 jpeg_set_qual(dev->jpeg_hdr, dev->quality); 319 jpeg_set_qual(dev->jpeg_hdr, dev->quality);
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.c b/drivers/media/video/gspca/m5602/m5602_ov7660.c
index 7aafeb7cfa07..2a28b74cb3f9 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.c
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.c
@@ -20,6 +20,18 @@
20 20
21static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val); 21static int ov7660_get_gain(struct gspca_dev *gspca_dev, __s32 *val);
22static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val); 22static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val);
23static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
24 __s32 *val);
25static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
26 __s32 val);
27static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val);
28static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val);
29static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val);
30static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev, __s32 val);
31static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val);
32static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val);
33static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val);
34static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val);
23 35
24const static struct ctrl ov7660_ctrls[] = { 36const static struct ctrl ov7660_ctrls[] = {
25#define GAIN_IDX 1 37#define GAIN_IDX 1
@@ -37,6 +49,79 @@ const static struct ctrl ov7660_ctrls[] = {
37 .set = ov7660_set_gain, 49 .set = ov7660_set_gain,
38 .get = ov7660_get_gain 50 .get = ov7660_get_gain
39 }, 51 },
52#define BLUE_BALANCE_IDX 2
53#define RED_BALANCE_IDX 3
54#define AUTO_WHITE_BALANCE_IDX 4
55 {
56 {
57 .id = V4L2_CID_AUTO_WHITE_BALANCE,
58 .type = V4L2_CTRL_TYPE_BOOLEAN,
59 .name = "auto white balance",
60 .minimum = 0,
61 .maximum = 1,
62 .step = 1,
63 .default_value = 1
64 },
65 .set = ov7660_set_auto_white_balance,
66 .get = ov7660_get_auto_white_balance
67 },
68#define AUTO_GAIN_CTRL_IDX 5
69 {
70 {
71 .id = V4L2_CID_AUTOGAIN,
72 .type = V4L2_CTRL_TYPE_BOOLEAN,
73 .name = "auto gain control",
74 .minimum = 0,
75 .maximum = 1,
76 .step = 1,
77 .default_value = 1
78 },
79 .set = ov7660_set_auto_gain,
80 .get = ov7660_get_auto_gain
81 },
82#define AUTO_EXPOSURE_IDX 6
83 {
84 {
85 .id = V4L2_CID_EXPOSURE_AUTO,
86 .type = V4L2_CTRL_TYPE_BOOLEAN,
87 .name = "auto exposure",
88 .minimum = 0,
89 .maximum = 1,
90 .step = 1,
91 .default_value = 1
92 },
93 .set = ov7660_set_auto_exposure,
94 .get = ov7660_get_auto_exposure
95 },
96#define HFLIP_IDX 7
97 {
98 {
99 .id = V4L2_CID_HFLIP,
100 .type = V4L2_CTRL_TYPE_BOOLEAN,
101 .name = "horizontal flip",
102 .minimum = 0,
103 .maximum = 1,
104 .step = 1,
105 .default_value = 0
106 },
107 .set = ov7660_set_hflip,
108 .get = ov7660_get_hflip
109 },
110#define VFLIP_IDX 8
111 {
112 {
113 .id = V4L2_CID_VFLIP,
114 .type = V4L2_CTRL_TYPE_BOOLEAN,
115 .name = "vertical flip",
116 .minimum = 0,
117 .maximum = 1,
118 .step = 1,
119 .default_value = 0
120 },
121 .set = ov7660_set_vflip,
122 .get = ov7660_get_vflip
123 },
124
40}; 125};
41 126
42static struct v4l2_pix_format ov7660_modes[] = { 127static struct v4l2_pix_format ov7660_modes[] = {
@@ -137,7 +222,7 @@ int ov7660_init(struct sd *sd)
137 } else { 222 } else {
138 data[0] = init_ov7660[i][2]; 223 data[0] = init_ov7660[i][2];
139 err = m5602_write_sensor(sd, 224 err = m5602_write_sensor(sd,
140 init_ov7660[i][1], data, 1); 225 init_ov7660[i][1], data, 1);
141 } 226 }
142 } 227 }
143 228
@@ -148,6 +233,28 @@ int ov7660_init(struct sd *sd)
148 if (err < 0) 233 if (err < 0)
149 return err; 234 return err;
150 235
236 err = ov7660_set_auto_white_balance(&sd->gspca_dev,
237 sensor_settings[AUTO_WHITE_BALANCE_IDX]);
238 if (err < 0)
239 return err;
240
241 err = ov7660_set_auto_gain(&sd->gspca_dev,
242 sensor_settings[AUTO_GAIN_CTRL_IDX]);
243 if (err < 0)
244 return err;
245
246 err = ov7660_set_auto_exposure(&sd->gspca_dev,
247 sensor_settings[AUTO_EXPOSURE_IDX]);
248 if (err < 0)
249 return err;
250 err = ov7660_set_hflip(&sd->gspca_dev,
251 sensor_settings[HFLIP_IDX]);
252 if (err < 0)
253 return err;
254
255 err = ov7660_set_vflip(&sd->gspca_dev,
256 sensor_settings[VFLIP_IDX]);
257
151 return err; 258 return err;
152} 259}
153 260
@@ -194,6 +301,159 @@ static int ov7660_set_gain(struct gspca_dev *gspca_dev, __s32 val)
194 return err; 301 return err;
195} 302}
196 303
304
305static int ov7660_get_auto_white_balance(struct gspca_dev *gspca_dev,
306 __s32 *val)
307{
308 struct sd *sd = (struct sd *) gspca_dev;
309 s32 *sensor_settings = sd->sensor_priv;
310
311 *val = sensor_settings[AUTO_WHITE_BALANCE_IDX];
312 return 0;
313}
314
315static int ov7660_set_auto_white_balance(struct gspca_dev *gspca_dev,
316 __s32 val)
317{
318 int err;
319 u8 i2c_data;
320 struct sd *sd = (struct sd *) gspca_dev;
321 s32 *sensor_settings = sd->sensor_priv;
322
323 PDEBUG(D_V4L2, "Set auto white balance to %d", val);
324
325 sensor_settings[AUTO_WHITE_BALANCE_IDX] = val;
326 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
327 if (err < 0)
328 return err;
329
330 i2c_data = ((i2c_data & 0xfd) | ((val & 0x01) << 1));
331 err = m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
332
333 return err;
334}
335
336static int ov7660_get_auto_gain(struct gspca_dev *gspca_dev, __s32 *val)
337{
338 struct sd *sd = (struct sd *) gspca_dev;
339 s32 *sensor_settings = sd->sensor_priv;
340
341 *val = sensor_settings[AUTO_GAIN_CTRL_IDX];
342 PDEBUG(D_V4L2, "Read auto gain control %d", *val);
343 return 0;
344}
345
346static int ov7660_set_auto_gain(struct gspca_dev *gspca_dev, __s32 val)
347{
348 int err;
349 u8 i2c_data;
350 struct sd *sd = (struct sd *) gspca_dev;
351 s32 *sensor_settings = sd->sensor_priv;
352
353 PDEBUG(D_V4L2, "Set auto gain control to %d", val);
354
355 sensor_settings[AUTO_GAIN_CTRL_IDX] = val;
356 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
357 if (err < 0)
358 return err;
359
360 i2c_data = ((i2c_data & 0xfb) | ((val & 0x01) << 2));
361
362 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
363}
364
365static int ov7660_get_auto_exposure(struct gspca_dev *gspca_dev, __s32 *val)
366{
367 struct sd *sd = (struct sd *) gspca_dev;
368 s32 *sensor_settings = sd->sensor_priv;
369
370 *val = sensor_settings[AUTO_EXPOSURE_IDX];
371 PDEBUG(D_V4L2, "Read auto exposure control %d", *val);
372 return 0;
373}
374
375static int ov7660_set_auto_exposure(struct gspca_dev *gspca_dev,
376 __s32 val)
377{
378 int err;
379 u8 i2c_data;
380 struct sd *sd = (struct sd *) gspca_dev;
381 s32 *sensor_settings = sd->sensor_priv;
382
383 PDEBUG(D_V4L2, "Set auto exposure control to %d", val);
384
385 sensor_settings[AUTO_EXPOSURE_IDX] = val;
386 err = m5602_read_sensor(sd, OV7660_COM8, &i2c_data, 1);
387 if (err < 0)
388 return err;
389
390 i2c_data = ((i2c_data & 0xfe) | ((val & 0x01) << 0));
391
392 return m5602_write_sensor(sd, OV7660_COM8, &i2c_data, 1);
393}
394
395static int ov7660_get_hflip(struct gspca_dev *gspca_dev, __s32 *val)
396{
397 struct sd *sd = (struct sd *) gspca_dev;
398 s32 *sensor_settings = sd->sensor_priv;
399
400 *val = sensor_settings[HFLIP_IDX];
401 PDEBUG(D_V4L2, "Read horizontal flip %d", *val);
402 return 0;
403}
404
405static int ov7660_set_hflip(struct gspca_dev *gspca_dev, __s32 val)
406{
407 int err;
408 u8 i2c_data;
409 struct sd *sd = (struct sd *) gspca_dev;
410 s32 *sensor_settings = sd->sensor_priv;
411
412 PDEBUG(D_V4L2, "Set horizontal flip to %d", val);
413
414 sensor_settings[HFLIP_IDX] = val;
415
416 i2c_data = ((val & 0x01) << 5) |
417 (sensor_settings[VFLIP_IDX] << 4);
418
419 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
420
421 return err;
422}
423
424static int ov7660_get_vflip(struct gspca_dev *gspca_dev, __s32 *val)
425{
426 struct sd *sd = (struct sd *) gspca_dev;
427 s32 *sensor_settings = sd->sensor_priv;
428
429 *val = sensor_settings[VFLIP_IDX];
430 PDEBUG(D_V4L2, "Read vertical flip %d", *val);
431
432 return 0;
433}
434
435static int ov7660_set_vflip(struct gspca_dev *gspca_dev, __s32 val)
436{
437 int err;
438 u8 i2c_data;
439 struct sd *sd = (struct sd *) gspca_dev;
440 s32 *sensor_settings = sd->sensor_priv;
441
442 PDEBUG(D_V4L2, "Set vertical flip to %d", val);
443 sensor_settings[VFLIP_IDX] = val;
444
445 i2c_data = ((val & 0x01) << 4) | (sensor_settings[VFLIP_IDX] << 5);
446 err = m5602_write_sensor(sd, OV7660_MVFP, &i2c_data, 1);
447 if (err < 0)
448 return err;
449
450 /* When vflip is toggled we need to readjust the bridge hsync/vsync */
451 if (gspca_dev->streaming)
452 err = ov7660_start(sd);
453
454 return err;
455}
456
197static void ov7660_dump_registers(struct sd *sd) 457static void ov7660_dump_registers(struct sd *sd)
198{ 458{
199 int address; 459 int address;
diff --git a/drivers/media/video/gspca/m5602/m5602_ov7660.h b/drivers/media/video/gspca/m5602/m5602_ov7660.h
index 3f2c169a93ea..f5588ebe667c 100644
--- a/drivers/media/video/gspca/m5602/m5602_ov7660.h
+++ b/drivers/media/video/gspca/m5602/m5602_ov7660.h
@@ -66,23 +66,23 @@
66#define OV7660_RBIAS 0x2c 66#define OV7660_RBIAS 0x2c
67#define OV7660_HREF 0x32 67#define OV7660_HREF 0x32
68#define OV7660_ADC 0x37 68#define OV7660_ADC 0x37
69#define OV7660_OFON 0x39 69#define OV7660_OFON 0x39
70#define OV7660_TSLB 0x3a 70#define OV7660_TSLB 0x3a
71#define OV7660_COM12 0x3c 71#define OV7660_COM12 0x3c
72#define OV7660_COM13 0x3d 72#define OV7660_COM13 0x3d
73#define OV7660_LCC1 0x62 73#define OV7660_LCC1 0x62
74#define OV7660_LCC2 0x63 74#define OV7660_LCC2 0x63
75#define OV7660_LCC3 0x64 75#define OV7660_LCC3 0x64
76#define OV7660_LCC4 0x65 76#define OV7660_LCC4 0x65
77#define OV7660_LCC5 0x66 77#define OV7660_LCC5 0x66
78#define OV7660_HV 0x69 78#define OV7660_HV 0x69
79#define OV7660_RSVDA1 0xa1 79#define OV7660_RSVDA1 0xa1
80 80
81#define OV7660_DEFAULT_GAIN 0x0e 81#define OV7660_DEFAULT_GAIN 0x0e
82#define OV7660_DEFAULT_RED_GAIN 0x80 82#define OV7660_DEFAULT_RED_GAIN 0x80
83#define OV7660_DEFAULT_BLUE_GAIN 0x80 83#define OV7660_DEFAULT_BLUE_GAIN 0x80
84#define OV7660_DEFAULT_SATURATION 0x00 84#define OV7660_DEFAULT_SATURATION 0x00
85#define OV7660_DEFAULT_EXPOSURE 0x20 85#define OV7660_DEFAULT_EXPOSURE 0x20
86 86
87/* Kernel module parameters */ 87/* Kernel module parameters */
88extern int force_sensor; 88extern int force_sensor;
@@ -149,45 +149,8 @@ static const unsigned char init_ov7660[][4] =
149 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 149 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
150 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d}, 150 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0d},
151 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00}, 151 {BRIDGE, M5602_XB_SENSOR_CTRL, 0x00},
152 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
153 {BRIDGE, M5602_XB_GPIO_DIR, 0x03},
154 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
155 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
156
157 {SENSOR, OV7660_OFON, 0x0c},
158 {SENSOR, OV7660_COM2, 0x11},
159 {SENSOR, OV7660_COM7, 0x05},
160
161 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 152 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
162 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
163 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
164 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
165 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
166 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
167 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
168 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
169 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
170 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
171 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
172 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
173 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
174 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
175 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
176
177 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x02},
178 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
179
180 {SENSOR, OV7660_AECH, OV7660_DEFAULT_EXPOSURE},
181 {SENSOR, OV7660_COM1, 0x00},
182
183 {BRIDGE, M5602_XB_GPIO_DIR, 0x01}, 153 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
184 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
185 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
186 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
187 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
188 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
189 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
190
191 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 154 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
192 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 155 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
193 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 156 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -196,11 +159,8 @@ static const unsigned char init_ov7660[][4] =
196 {BRIDGE, M5602_XB_GPIO_DAT, 0x00}, 159 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
197 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06}, 160 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
198 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00}, 161 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
199
200 {SENSOR, OV7660_COM7, 0x80}, 162 {SENSOR, OV7660_COM7, 0x80},
201 {SENSOR, OV7660_CLKRC, 0x80}, 163 {SENSOR, OV7660_CLKRC, 0x80},
202 {SENSOR, OV7660_BLUE_GAIN, 0x80},
203 {SENSOR, OV7660_RED_GAIN, 0x80},
204 {SENSOR, OV7660_COM9, 0x4c}, 164 {SENSOR, OV7660_COM9, 0x4c},
205 {SENSOR, OV7660_OFON, 0x43}, 165 {SENSOR, OV7660_OFON, 0x43},
206 {SENSOR, OV7660_COM12, 0x28}, 166 {SENSOR, OV7660_COM12, 0x28},
@@ -212,17 +172,17 @@ static const unsigned char init_ov7660[][4] =
212 {SENSOR, OV7660_PSHFT, 0x0b}, 172 {SENSOR, OV7660_PSHFT, 0x0b},
213 {SENSOR, OV7660_VSTART, 0x01}, 173 {SENSOR, OV7660_VSTART, 0x01},
214 {SENSOR, OV7660_VSTOP, 0x7a}, 174 {SENSOR, OV7660_VSTOP, 0x7a},
215 {SENSOR, OV7660_VREF, 0x00}, 175 {SENSOR, OV7660_VSTOP, 0x00},
216 {SENSOR, OV7660_COM7, 0x05}, 176 {SENSOR, OV7660_COM7, 0x05},
217 {SENSOR, OV7660_COM6, 0x4b}, 177 {SENSOR, OV7660_COM6, 0x42},
218 {SENSOR, OV7660_BBIAS, 0x98}, 178 {SENSOR, OV7660_BBIAS, 0x94},
219 {SENSOR, OV7660_GbBIAS, 0x98}, 179 {SENSOR, OV7660_GbBIAS, 0x94},
220 {SENSOR, OV7660_RSVD29, 0x98}, 180 {SENSOR, OV7660_RSVD29, 0x94},
221 {SENSOR, OV7660_RBIAS, 0x98}, 181 {SENSOR, OV7660_RBIAS, 0x94},
222 {SENSOR, OV7660_COM1, 0x00}, 182 {SENSOR, OV7660_COM1, 0x00},
223 {SENSOR, OV7660_AECH, 0x00}, 183 {SENSOR, OV7660_AECH, 0x00},
224 {SENSOR, OV7660_AECHH, 0x00}, 184 {SENSOR, OV7660_AECHH, 0x00},
225 {SENSOR, OV7660_ADC, 0x04}, 185 {SENSOR, OV7660_ADC, 0x05},
226 {SENSOR, OV7660_COM13, 0x00}, 186 {SENSOR, OV7660_COM13, 0x00},
227 {SENSOR, OV7660_RSVDA1, 0x23}, 187 {SENSOR, OV7660_RSVDA1, 0x23},
228 {SENSOR, OV7660_TSLB, 0x0d}, 188 {SENSOR, OV7660_TSLB, 0x0d},
@@ -233,6 +193,47 @@ static const unsigned char init_ov7660[][4] =
233 {SENSOR, OV7660_LCC4, 0x40}, 193 {SENSOR, OV7660_LCC4, 0x40},
234 {SENSOR, OV7660_LCC5, 0x01}, 194 {SENSOR, OV7660_LCC5, 0x01},
235 195
196 {SENSOR, OV7660_AECH, 0x20},
197 {SENSOR, OV7660_COM1, 0x00},
198 {SENSOR, OV7660_OFON, 0x0c},
199 {SENSOR, OV7660_COM2, 0x11},
200 {SENSOR, OV7660_COM7, 0x05},
201 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
202 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
203 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
204 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
205 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
206 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
207 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
208 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
209 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
210 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
211 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
212 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
213 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
214 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
215 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
216 {SENSOR, OV7660_AECH, 0x5f},
217 {SENSOR, OV7660_COM1, 0x03},
218 {SENSOR, OV7660_OFON, 0x0c},
219 {SENSOR, OV7660_COM2, 0x11},
220 {SENSOR, OV7660_COM7, 0x05},
221 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
222 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
223 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
224 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
225 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
226 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
227 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
228 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
229 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
230 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
231 {BRIDGE, M5602_XB_SENSOR_TYPE, 0x0c},
232 {BRIDGE, M5602_XB_GPIO_DIR, 0x05},
233 {BRIDGE, M5602_XB_GPIO_DAT, 0x00},
234 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
235 {BRIDGE, M5602_XB_GPIO_EN_L, 0x00},
236
236 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06}, 237 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x06},
237 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 238 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
238 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0}, 239 {BRIDGE, M5602_XB_ADC_CTRL, 0xc0},
@@ -245,35 +246,18 @@ static const unsigned char init_ov7660[][4] =
245 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 246 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
246 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 247 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
247 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01}, 248 {BRIDGE, M5602_XB_VSYNC_PARA, 0x01},
248 {BRIDGE, M5602_XB_VSYNC_PARA, 0xe0}, /* 480 */ 249 {BRIDGE, M5602_XB_VSYNC_PARA, 0xec},
249 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
250 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 251 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00},
251 {BRIDGE, M5602_XB_SIG_INI, 0x00}, 252 {BRIDGE, M5602_XB_SIG_INI, 0x00},
252 {BRIDGE, M5602_XB_SIG_INI, 0x02}, 253 {BRIDGE, M5602_XB_SIG_INI, 0x02},
253 {BRIDGE, M5602_XB_VSYNC_PARA, 0x00}, 254 {BRIDGE, M5602_XB_HSYNC_PARA, 0x00},
254 {BRIDGE, M5602_XB_VSYNC_PARA, 0x27}, /* 39 */ 255 {BRIDGE, M5602_XB_HSYNC_PARA, 0x27},
255 {BRIDGE, M5602_XB_VSYNC_PARA, 0x02}, 256 {BRIDGE, M5602_XB_HSYNC_PARA, 0x02},
256 {BRIDGE, M5602_XB_VSYNC_PARA, 0xa7}, /* 679 */ 257 {BRIDGE, M5602_XB_HSYNC_PARA, 0xa7},
257 {BRIDGE, M5602_XB_SIG_INI, 0x00}, 258 {BRIDGE, M5602_XB_SIG_INI, 0x00},
258
259 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00}, 259 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x00},
260 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}, 260 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0},
261
262 {SENSOR, OV7660_AECH, 0x20},
263 {SENSOR, OV7660_COM1, 0x00},
264 {SENSOR, OV7660_OFON, 0x0c},
265 {SENSOR, OV7660_COM2, 0x11},
266 {SENSOR, OV7660_COM7, 0x05},
267 {SENSOR, OV7660_BLUE_GAIN, 0x80},
268 {SENSOR, OV7660_RED_GAIN, 0x80},
269
270 {BRIDGE, M5602_XB_GPIO_DIR, 0x01},
271 {BRIDGE, M5602_XB_GPIO_DAT, 0x04},
272 {BRIDGE, M5602_XB_GPIO_EN_H, 0x06},
273 {BRIDGE, M5602_XB_GPIO_DIR_H, 0x06},
274 {BRIDGE, M5602_XB_GPIO_DAT_H, 0x00},
275 {BRIDGE, M5602_XB_SEN_CLK_DIV, 0x08},
276 {BRIDGE, M5602_XB_SEN_CLK_CTRL, 0xb0}
277}; 261};
278 262
279#endif 263#endif
diff --git a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
index 0163903d1c0f..59400e858965 100644
--- a/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
+++ b/drivers/media/video/gspca/m5602/m5602_s5k4aa.c
@@ -47,6 +47,12 @@ static
47 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550") 47 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Xi 2550")
48 } 48 }
49 }, { 49 }, {
50 .ident = "Fujitsu-Siemens Amilo Pa 2548",
51 .matches = {
52 DMI_MATCH(DMI_SYS_VENDOR, "FUJITSU SIEMENS"),
53 DMI_MATCH(DMI_PRODUCT_NAME, "AMILO Pa 2548")
54 }
55 }, {
50 .ident = "MSI GX700", 56 .ident = "MSI GX700",
51 .matches = { 57 .matches = {
52 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 58 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
@@ -54,6 +60,13 @@ static
54 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007") 60 DMI_MATCH(DMI_BIOS_DATE, "07/26/2007")
55 } 61 }
56 }, { 62 }, {
63 .ident = "MSI GX700",
64 .matches = {
65 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
66 DMI_MATCH(DMI_PRODUCT_NAME, "GX700"),
67 DMI_MATCH(DMI_BIOS_DATE, "07/19/2007")
68 }
69 }, {
57 .ident = "MSI GX700/GX705/EX700", 70 .ident = "MSI GX700/GX705/EX700",
58 .matches = { 71 .matches = {
59 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"), 72 DMI_MATCH(DMI_SYS_VENDOR, "Micro-Star International"),
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 7af511b5e9c2..65489d6b0d89 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -50,7 +50,6 @@ int stv06xx_write_bridge(struct sd *sd, u16 address, u16 i2c_data)
50 0x04, 0x40, address, 0, buf, len, 50 0x04, 0x40, address, 0, buf, len,
51 STV06XX_URB_MSG_TIMEOUT); 51 STV06XX_URB_MSG_TIMEOUT);
52 52
53
54 PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d", 53 PDEBUG(D_CONF, "Written 0x%x to address 0x%x, status: %d",
55 i2c_data, address, err); 54 i2c_data, address, err);
56 55
@@ -69,7 +68,7 @@ int stv06xx_read_bridge(struct sd *sd, u16 address, u8 *i2c_data)
69 68
70 *i2c_data = buf[0]; 69 *i2c_data = buf[0];
71 70
72 PDEBUG(D_CONF, "Read 0x%x from address 0x%x, status %d", 71 PDEBUG(D_CONF, "Reading 0x%x from address 0x%x, status %d",
73 *i2c_data, address, err); 72 *i2c_data, address, err);
74 73
75 return (err < 0) ? err : 0; 74 return (err < 0) ? err : 0;
@@ -111,14 +110,14 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
111 struct usb_device *udev = sd->gspca_dev.dev; 110 struct usb_device *udev = sd->gspca_dev.dev;
112 __u8 *buf = sd->gspca_dev.usb_buf; 111 __u8 *buf = sd->gspca_dev.usb_buf;
113 112
114 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len); 113 PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
115 for (i = 0; i < len;) { 114 for (i = 0; i < len;) {
116 /* Build the command buffer */ 115 /* Build the command buffer */
117 memset(buf, 0, I2C_BUFFER_LENGTH); 116 memset(buf, 0, I2C_BUFFER_LENGTH);
118 for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) { 117 for (j = 0; j < I2C_MAX_BYTES && i < len; j++, i++) {
119 buf[j] = data[2*i]; 118 buf[j] = data[2*i];
120 buf[0x10 + j] = data[2*i+1]; 119 buf[0x10 + j] = data[2*i+1];
121 PDEBUG(D_USBO, "I2C: Writing 0x%02x to reg 0x%02x", 120 PDEBUG(D_CONF, "I2C: Writing 0x%02x to reg 0x%02x",
122 data[2*i+1], data[2*i]); 121 data[2*i+1], data[2*i]);
123 } 122 }
124 buf[0x20] = sd->sensor->i2c_addr; 123 buf[0x20] = sd->sensor->i2c_addr;
@@ -128,8 +127,8 @@ int stv06xx_write_sensor_bytes(struct sd *sd, const u8 *data, u8 len)
128 0x04, 0x40, 0x0400, 0, buf, 127 0x04, 0x40, 0x0400, 0, buf,
129 I2C_BUFFER_LENGTH, 128 I2C_BUFFER_LENGTH,
130 STV06XX_URB_MSG_TIMEOUT); 129 STV06XX_URB_MSG_TIMEOUT);
131 if (err < 0) 130 if (err < 0)
132 return err; 131 return err;
133 } 132 }
134 return stv06xx_write_sensor_finish(sd); 133 return stv06xx_write_sensor_finish(sd);
135} 134}
@@ -140,7 +139,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
140 struct usb_device *udev = sd->gspca_dev.dev; 139 struct usb_device *udev = sd->gspca_dev.dev;
141 __u8 *buf = sd->gspca_dev.usb_buf; 140 __u8 *buf = sd->gspca_dev.usb_buf;
142 141
143 PDEBUG(D_USBO, "I2C: Command buffer contains %d entries", len); 142 PDEBUG(D_CONF, "I2C: Command buffer contains %d entries", len);
144 143
145 for (i = 0; i < len;) { 144 for (i = 0; i < len;) {
146 /* Build the command buffer */ 145 /* Build the command buffer */
@@ -149,7 +148,7 @@ int stv06xx_write_sensor_words(struct sd *sd, const u16 *data, u8 len)
149 buf[j] = data[2*i]; 148 buf[j] = data[2*i];
150 buf[0x10 + j * 2] = data[2*i+1]; 149 buf[0x10 + j * 2] = data[2*i+1];
151 buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8; 150 buf[0x10 + j * 2 + 1] = data[2*i+1] >> 8;
152 PDEBUG(D_USBO, "I2C: Writing 0x%04x to reg 0x%02x", 151 PDEBUG(D_CONF, "I2C: Writing 0x%04x to reg 0x%02x",
153 data[2*i+1], data[2*i]); 152 data[2*i+1], data[2*i]);
154 } 153 }
155 buf[0x20] = sd->sensor->i2c_addr; 154 buf[0x20] = sd->sensor->i2c_addr;
@@ -189,7 +188,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
189 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH, 188 0x04, 0x40, 0x1400, 0, buf, I2C_BUFFER_LENGTH,
190 STV06XX_URB_MSG_TIMEOUT); 189 STV06XX_URB_MSG_TIMEOUT);
191 if (err < 0) { 190 if (err < 0) {
192 PDEBUG(D_ERR, "I2C Read: error writing address: %d", err); 191 PDEBUG(D_ERR, "I2C: Read error writing address: %d", err);
193 return err; 192 return err;
194 } 193 }
195 194
@@ -201,7 +200,7 @@ int stv06xx_read_sensor(struct sd *sd, const u8 address, u16 *value)
201 else 200 else
202 *value = buf[0]; 201 *value = buf[0];
203 202
204 PDEBUG(D_USBO, "I2C: Read 0x%x from address 0x%x, status: %d", 203 PDEBUG(D_CONF, "I2C: Read 0x%x from address 0x%x, status: %d",
205 *value, address, err); 204 *value, address, err);
206 205
207 return (err < 0) ? err : 0; 206 return (err < 0) ? err : 0;
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
index e5024c8496ef..706e08dc5254 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.c
@@ -37,7 +37,7 @@ static const struct ctrl hdcs1x00_ctrl[] = {
37 .type = V4L2_CTRL_TYPE_INTEGER, 37 .type = V4L2_CTRL_TYPE_INTEGER,
38 .name = "exposure", 38 .name = "exposure",
39 .minimum = 0x00, 39 .minimum = 0x00,
40 .maximum = 0xffff, 40 .maximum = 0xff,
41 .step = 0x1, 41 .step = 0x1,
42 .default_value = HDCS_DEFAULT_EXPOSURE, 42 .default_value = HDCS_DEFAULT_EXPOSURE,
43 .flags = V4L2_CTRL_FLAG_SLIDER 43 .flags = V4L2_CTRL_FLAG_SLIDER
@@ -74,7 +74,35 @@ static struct v4l2_pix_format hdcs1x00_mode[] = {
74 } 74 }
75}; 75};
76 76
77static const struct ctrl hdcs1020_ctrl[] = {}; 77static const struct ctrl hdcs1020_ctrl[] = {
78 {
79 {
80 .id = V4L2_CID_EXPOSURE,
81 .type = V4L2_CTRL_TYPE_INTEGER,
82 .name = "exposure",
83 .minimum = 0x00,
84 .maximum = 0xffff,
85 .step = 0x1,
86 .default_value = HDCS_DEFAULT_EXPOSURE,
87 .flags = V4L2_CTRL_FLAG_SLIDER
88 },
89 .set = hdcs_set_exposure,
90 .get = hdcs_get_exposure
91 }, {
92 {
93 .id = V4L2_CID_GAIN,
94 .type = V4L2_CTRL_TYPE_INTEGER,
95 .name = "gain",
96 .minimum = 0x00,
97 .maximum = 0xff,
98 .step = 0x1,
99 .default_value = HDCS_DEFAULT_GAIN,
100 .flags = V4L2_CTRL_FLAG_SLIDER
101 },
102 .set = hdcs_set_gain,
103 .get = hdcs_get_gain
104 }
105};
78 106
79static struct v4l2_pix_format hdcs1020_mode[] = { 107static struct v4l2_pix_format hdcs1020_mode[] = {
80 { 108 {
@@ -120,6 +148,7 @@ struct hdcs {
120 } exp; 148 } exp;
121 149
122 int psmp; 150 int psmp;
151 u8 exp_cache, gain_cache;
123}; 152};
124 153
125static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len) 154static int hdcs_reg_write_seq(struct sd *sd, u8 reg, u8 *vals, u8 len)
@@ -205,34 +234,8 @@ static int hdcs_get_exposure(struct gspca_dev *gspca_dev, __s32 *val)
205 struct sd *sd = (struct sd *) gspca_dev; 234 struct sd *sd = (struct sd *) gspca_dev;
206 struct hdcs *hdcs = sd->sensor_priv; 235 struct hdcs *hdcs = sd->sensor_priv;
207 236
208 /* Column time period */ 237 *val = hdcs->exp_cache;
209 int ct;
210 /* Column processing period */
211 int cp;
212 /* Row processing period */
213 int rp;
214 int cycles;
215 int err;
216 int rowexp;
217 u16 data[2];
218
219 err = stv06xx_read_sensor(sd, HDCS_ROWEXPL, &data[0]);
220 if (err < 0)
221 return err;
222
223 err = stv06xx_read_sensor(sd, HDCS_ROWEXPH, &data[1]);
224 if (err < 0)
225 return err;
226
227 rowexp = (data[1] << 8) | data[0];
228
229 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
230 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
231 rp = hdcs->exp.rs + cp;
232 238
233 cycles = rp * rowexp;
234 *val = cycles / HDCS_CLK_FREQ_MHZ;
235 PDEBUG(D_V4L2, "Read exposure %d", *val);
236 return 0; 239 return 0;
237} 240}
238 241
@@ -252,9 +255,12 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
252 within the column processing period */ 255 within the column processing period */
253 int mnct; 256 int mnct;
254 int cycles, err; 257 int cycles, err;
255 u8 exp[4]; 258 u8 exp[14];
256 259
257 cycles = val * HDCS_CLK_FREQ_MHZ; 260 val &= 0xff;
261 hdcs->exp_cache = val;
262
263 cycles = val * HDCS_CLK_FREQ_MHZ * 257;
258 264
259 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2); 265 ct = hdcs->exp.cto + hdcs->psmp + (HDCS_ADC_START_SIG_DUR + 2);
260 cp = hdcs->exp.cto + (hdcs->w * ct / 2); 266 cp = hdcs->exp.cto + (hdcs->w * ct / 2);
@@ -288,73 +294,79 @@ static int hdcs_set_exposure(struct gspca_dev *gspca_dev, __s32 val)
288 srowexp = max_srowexp; 294 srowexp = max_srowexp;
289 295
290 if (IS_1020(sd)) { 296 if (IS_1020(sd)) {
291 exp[0] = rowexp & 0xff; 297 exp[0] = HDCS20_CONTROL;
292 exp[1] = rowexp >> 8; 298 exp[1] = 0x00; /* Stop streaming */
293 exp[2] = (srowexp >> 2) & 0xff; 299 exp[2] = HDCS_ROWEXPL;
294 /* this clears exposure error flag */ 300 exp[3] = rowexp & 0xff;
295 exp[3] = 0x1; 301 exp[4] = HDCS_ROWEXPH;
296 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4); 302 exp[5] = rowexp >> 8;
303 exp[6] = HDCS20_SROWEXP;
304 exp[7] = (srowexp >> 2) & 0xff;
305 exp[8] = HDCS20_ERROR;
306 exp[9] = 0x10; /* Clear exposure error flag*/
307 exp[10] = HDCS20_CONTROL;
308 exp[11] = 0x04; /* Restart streaming */
309 err = stv06xx_write_sensor_bytes(sd, exp, 6);
297 } else { 310 } else {
298 exp[0] = rowexp & 0xff; 311 exp[0] = HDCS00_CONTROL;
299 exp[1] = rowexp >> 8; 312 exp[1] = 0x00; /* Stop streaming */
300 exp[2] = srowexp & 0xff; 313 exp[2] = HDCS_ROWEXPL;
301 exp[3] = srowexp >> 8; 314 exp[3] = rowexp & 0xff;
302 err = hdcs_reg_write_seq(sd, HDCS_ROWEXPL, exp, 4); 315 exp[4] = HDCS_ROWEXPH;
316 exp[5] = rowexp >> 8;
317 exp[6] = HDCS00_SROWEXPL;
318 exp[7] = srowexp & 0xff;
319 exp[8] = HDCS00_SROWEXPH;
320 exp[9] = srowexp >> 8;
321 exp[10] = HDCS_STATUS;
322 exp[11] = 0x10; /* Clear exposure error flag*/
323 exp[12] = HDCS00_CONTROL;
324 exp[13] = 0x04; /* Restart streaming */
325 err = stv06xx_write_sensor_bytes(sd, exp, 7);
303 if (err < 0) 326 if (err < 0)
304 return err; 327 return err;
305
306 /* clear exposure error flag */
307 err = stv06xx_write_sensor(sd,
308 HDCS_STATUS, BIT(4));
309 } 328 }
310 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d", 329 PDEBUG(D_V4L2, "Writing exposure %d, rowexp %d, srowexp %d",
311 val, rowexp, srowexp); 330 val, rowexp, srowexp);
312 return err; 331 return err;
313} 332}
314 333
315static int hdcs_set_gains(struct sd *sd, u8 r, u8 g, u8 b) 334static int hdcs_set_gains(struct sd *sd, u8 g)
316{ 335{
336 struct hdcs *hdcs = sd->sensor_priv;
337 int err;
317 u8 gains[4]; 338 u8 gains[4];
318 339
340 hdcs->gain_cache = g;
341
319 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */ 342 /* the voltage gain Av = (1 + 19 * val / 127) * (1 + bit7) */
320 if (r > 127)
321 r = 0x80 | (r / 2);
322 if (g > 127) 343 if (g > 127)
323 g = 0x80 | (g / 2); 344 g = 0x80 | (g / 2);
324 if (b > 127)
325 b = 0x80 | (b / 2);
326 345
327 gains[0] = g; 346 gains[0] = g;
328 gains[1] = r; 347 gains[1] = g;
329 gains[2] = b; 348 gains[2] = g;
330 gains[3] = g; 349 gains[3] = g;
331 350
332 return hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4); 351 err = hdcs_reg_write_seq(sd, HDCS_ERECPGA, gains, 4);
352 return err;
333} 353}
334 354
335static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val) 355static int hdcs_get_gain(struct gspca_dev *gspca_dev, __s32 *val)
336{ 356{
337 struct sd *sd = (struct sd *) gspca_dev; 357 struct sd *sd = (struct sd *) gspca_dev;
338 int err; 358 struct hdcs *hdcs = sd->sensor_priv;
339 u16 data;
340
341 err = stv06xx_read_sensor(sd, HDCS_ERECPGA, &data);
342 359
343 /* Bit 7 doubles the gain */ 360 *val = hdcs->gain_cache;
344 if (data & 0x80)
345 *val = (data & 0x7f) * 2;
346 else
347 *val = data;
348 361
349 PDEBUG(D_V4L2, "Read gain %d", *val); 362 return 0;
350 return err;
351} 363}
352 364
353static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val) 365static int hdcs_set_gain(struct gspca_dev *gspca_dev, __s32 val)
354{ 366{
355 PDEBUG(D_V4L2, "Writing gain %d", val); 367 PDEBUG(D_V4L2, "Writing gain %d", val);
356 return hdcs_set_gains((struct sd *) gspca_dev, 368 return hdcs_set_gains((struct sd *) gspca_dev,
357 val & 0xff, val & 0xff, val & 0xff); 369 val & 0xff);
358} 370}
359 371
360static int hdcs_set_size(struct sd *sd, 372static int hdcs_set_size(struct sd *sd,
@@ -572,16 +584,15 @@ static int hdcs_init(struct sd *sd)
572 if (err < 0) 584 if (err < 0)
573 return err; 585 return err;
574 586
575 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN, HDCS_DEFAULT_GAIN, 587 err = hdcs_set_gains(sd, HDCS_DEFAULT_GAIN);
576 HDCS_DEFAULT_GAIN);
577 if (err < 0) 588 if (err < 0)
578 return err; 589 return err;
579 590
580 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE); 591 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height);
581 if (err < 0) 592 if (err < 0)
582 return err; 593 return err;
583 594
584 err = hdcs_set_size(sd, hdcs->array.width, hdcs->array.height); 595 err = hdcs_set_exposure(&sd->gspca_dev, HDCS_DEFAULT_EXPOSURE);
585 return err; 596 return err;
586} 597}
587 598
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
index 412f06cf3d5c..37b31c99d956 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_hdcs.h
@@ -124,7 +124,7 @@
124#define HDCS_RUN_ENABLE (1 << 2) 124#define HDCS_RUN_ENABLE (1 << 2)
125#define HDCS_SLEEP_MODE (1 << 1) 125#define HDCS_SLEEP_MODE (1 << 1)
126 126
127#define HDCS_DEFAULT_EXPOSURE 5000 127#define HDCS_DEFAULT_EXPOSURE 48
128#define HDCS_DEFAULT_GAIN 128 128#define HDCS_DEFAULT_GAIN 128
129 129
130static int hdcs_probe_1x00(struct sd *sd); 130static int hdcs_probe_1x00(struct sd *sd);
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
index 87cb5b9ddfa7..c11f06e4ae76 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx_st6422.c
@@ -166,7 +166,7 @@ static int st6422_init(struct sd *sd)
166/* 10 compressed? */ 166/* 10 compressed? */
167 167
168 { 0x1439, 0x00 }, 168 { 0x1439, 0x00 },
169/* antiflimmer?? 0xa2 ger perfekt bild mot monitor */ 169/* anti-noise? 0xa2 gives a perfect image */
170 170
171 { 0x143b, 0x05 }, 171 { 0x143b, 0x05 },
172 { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */ 172 { 0x143c, 0x00 }, /* 0x00-0x01 - ??? */
@@ -197,15 +197,14 @@ static int st6422_init(struct sd *sd)
197 { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */ 197 { 0x1500, 0x50 }, /* 0x00 - 0xFF 0x80 == compr ? */
198 198
199 { 0x1501, 0xaf }, 199 { 0x1501, 0xaf },
200/* high val-> ljus area blir morkare. */ 200/* high val-> light area gets darker */
201/* low val -> ljus area blir ljusare. */ 201/* low val -> light area gets lighter */
202 { 0x1502, 0xc2 }, 202 { 0x1502, 0xc2 },
203/* high val-> ljus area blir morkare. */ 203/* high val-> light area gets darker */
204/* low val -> ljus area blir ljusare. */ 204/* low val -> light area gets lighter */
205 { 0x1503, 0x45 }, 205 { 0x1503, 0x45 },
206/* high val-> ljus area blir morkare. */ 206/* high val-> light area gets darker */
207/* low val -> ljus area blir ljusare. */ 207/* low val -> light area gets lighter */
208
209 { 0x1505, 0x02 }, 208 { 0x1505, 0x02 },
210/* 2 : 324x248 80352 bytes */ 209/* 2 : 324x248 80352 bytes */
211/* 7 : 248x162 40176 bytes */ 210/* 7 : 248x162 40176 bytes */
diff --git a/drivers/media/video/gspca/vc032x.c b/drivers/media/video/gspca/vc032x.c
index 619250e70718..589042f6adbe 100644
--- a/drivers/media/video/gspca/vc032x.c
+++ b/drivers/media/video/gspca/vc032x.c
@@ -2946,7 +2946,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000); 2946 reg_w(gspca_dev->dev, 0x89, 0x058c, 0x0000);
2947 break; 2947 break;
2948 default: 2948 default:
2949 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff); 2949 if (!(sd->flags & FL_SAMSUNG))
2950 reg_w(gspca_dev->dev, 0x89, 0xffff, 0xfdff);
2950 break; 2951 break;
2951 } 2952 }
2952 msleep(100); 2953 msleep(100);
@@ -2964,7 +2965,7 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2964 2965
2965 if (sd->sensor == SENSOR_MI1310_SOC) 2966 if (sd->sensor == SENSOR_MI1310_SOC)
2966 reg_w(dev, 0x89, 0x058c, 0x00ff); 2967 reg_w(dev, 0x89, 0x058c, 0x00ff);
2967 else 2968 else if (!(sd->flags & FL_SAMSUNG))
2968 reg_w(dev, 0x89, 0xffff, 0xffff); 2969 reg_w(dev, 0x89, 0xffff, 0xffff);
2969 reg_w(dev, 0xa0, 0x01, 0xb301); 2970 reg_w(dev, 0xa0, 0x01, 0xb301);
2970 reg_w(dev, 0xa0, 0x09, 0xb003); 2971 reg_w(dev, 0xa0, 0x09, 0xb003);
@@ -2981,7 +2982,7 @@ static void sd_stop0(struct gspca_dev *gspca_dev)
2981/*fixme: is this useful?*/ 2982/*fixme: is this useful?*/
2982 if (sd->sensor == SENSOR_MI1310_SOC) 2983 if (sd->sensor == SENSOR_MI1310_SOC)
2983 reg_w(dev, 0x89, 0x058c, 0x00ff); 2984 reg_w(dev, 0x89, 0x058c, 0x00ff);
2984 else 2985 else if (!(sd->flags & FL_SAMSUNG))
2985 reg_w(dev, 0x89, 0xffff, 0xffff); 2986 reg_w(dev, 0x89, 0xffff, 0xffff);
2986} 2987}
2987 2988
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 63ea0fb66063..463ec3457d7b 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -246,7 +246,7 @@ MODULE_PARM_DESC(newi2c,
246 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n" 246 "\t\t\t-1 is autodetect, 0 is off, 1 is on\n"
247 "\t\t\tDefault is autodetect"); 247 "\t\t\tDefault is autodetect");
248 248
249MODULE_PARM_DESC(ivtv_first_minor, "Set kernel number assigned to first card"); 249MODULE_PARM_DESC(ivtv_first_minor, "Set device node number assigned to first card");
250 250
251MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil"); 251MODULE_AUTHOR("Kevin Thayer, Chris Kennedy, Hans Verkuil");
252MODULE_DESCRIPTION("CX23415/CX23416 driver"); 252MODULE_DESCRIPTION("CX23415/CX23416 driver");
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 8f15a31d3f66..b9c71e61f7d6 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -161,19 +161,19 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
161 return -1; 161 return -1;
162 if (hw == IVTV_HW_TUNER) { 162 if (hw == IVTV_HW_TUNER) {
163 /* special tuner handling */ 163 /* special tuner handling */
164 sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev, 164 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
165 adap, mod, type, 165 adap, mod, type,
166 itv->card_i2c->radio); 166 0, itv->card_i2c->radio);
167 if (sd) 167 if (sd)
168 sd->grp_id = 1 << idx; 168 sd->grp_id = 1 << idx;
169 sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev, 169 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
170 adap, mod, type, 170 adap, mod, type,
171 itv->card_i2c->demod); 171 0, itv->card_i2c->demod);
172 if (sd) 172 if (sd)
173 sd->grp_id = 1 << idx; 173 sd->grp_id = 1 << idx;
174 sd = v4l2_i2c_new_probed_subdev(&itv->v4l2_dev, 174 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
175 adap, mod, type, 175 adap, mod, type,
176 itv->card_i2c->tv); 176 0, itv->card_i2c->tv);
177 if (sd) 177 if (sd)
178 sd->grp_id = 1 << idx; 178 sd->grp_id = 1 << idx;
179 return sd ? 0 : -1; 179 return sd ? 0 : -1;
@@ -181,11 +181,11 @@ int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
181 if (!hw_addrs[idx]) 181 if (!hw_addrs[idx])
182 return -1; 182 return -1;
183 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) { 183 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
184 sd = v4l2_i2c_new_probed_subdev_addr(&itv->v4l2_dev, 184 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
185 adap, mod, type, hw_addrs[idx]); 185 adap, mod, type, 0, I2C_ADDRS(hw_addrs[idx]));
186 } else { 186 } else {
187 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev, 187 sd = v4l2_i2c_new_subdev(&itv->v4l2_dev,
188 adap, mod, type, hw_addrs[idx]); 188 adap, mod, type, hw_addrs[idx], NULL);
189 } 189 }
190 if (sd) 190 if (sd)
191 sd->grp_id = 1 << idx; 191 sd->grp_id = 1 << idx;
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 15da01710efc..67699e3f2aaa 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -261,8 +261,8 @@ static int ivtv_reg_dev(struct ivtv *itv, int type)
261 video_set_drvdata(s->vdev, s); 261 video_set_drvdata(s->vdev, s);
262 262
263 /* Register device. First try the desired minor, then any free one. */ 263 /* Register device. First try the desired minor, then any free one. */
264 if (video_register_device(s->vdev, vfl_type, num)) { 264 if (video_register_device_no_warn(s->vdev, vfl_type, num)) {
265 IVTV_ERR("Couldn't register v4l2 device for %s kernel number %d\n", 265 IVTV_ERR("Couldn't register v4l2 device for %s (device node number %d)\n",
266 s->name, num); 266 s->name, num);
267 video_device_release(s->vdev); 267 video_device_release(s->vdev);
268 s->vdev = NULL; 268 s->vdev = NULL;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 4d794b42d6cd..45388d2ce2fd 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -13,13 +13,13 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/v4l2-common.h> 16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19 19
20/* mt9m001 i2c address 0x5d 20/* mt9m001 i2c address 0x5d
21 * The platform has to define i2c_board_info 21 * The platform has to define ctruct i2c_board_info objects and link to them
22 * and call i2c_register_board_info() */ 22 * from struct soc_camera_link */
23 23
24/* mt9m001 selected register addresses */ 24/* mt9m001 selected register addresses */
25#define MT9M001_CHIP_VERSION 0x00 25#define MT9M001_CHIP_VERSION 0x00
@@ -39,6 +39,13 @@
39#define MT9M001_GLOBAL_GAIN 0x35 39#define MT9M001_GLOBAL_GAIN 0x35
40#define MT9M001_CHIP_ENABLE 0xF1 40#define MT9M001_CHIP_ENABLE 0xF1
41 41
42#define MT9M001_MAX_WIDTH 1280
43#define MT9M001_MAX_HEIGHT 1024
44#define MT9M001_MIN_WIDTH 48
45#define MT9M001_MIN_HEIGHT 32
46#define MT9M001_COLUMN_SKIP 20
47#define MT9M001_ROW_SKIP 12
48
42static const struct soc_camera_data_format mt9m001_colour_formats[] = { 49static const struct soc_camera_data_format mt9m001_colour_formats[] = {
43 /* Order important: first natively supported, 50 /* Order important: first natively supported,
44 * second supported with a GPIO extender */ 51 * second supported with a GPIO extender */
@@ -69,12 +76,20 @@ static const struct soc_camera_data_format mt9m001_monochrome_formats[] = {
69}; 76};
70 77
71struct mt9m001 { 78struct mt9m001 {
72 struct i2c_client *client; 79 struct v4l2_subdev subdev;
73 struct soc_camera_device icd; 80 struct v4l2_rect rect; /* Sensor window */
81 __u32 fourcc;
74 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 82 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
83 unsigned int gain;
84 unsigned int exposure;
75 unsigned char autoexposure; 85 unsigned char autoexposure;
76}; 86};
77 87
88static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
89{
90 return container_of(i2c_get_clientdata(client), struct mt9m001, subdev);
91}
92
78static int reg_read(struct i2c_client *client, const u8 reg) 93static int reg_read(struct i2c_client *client, const u8 reg)
79{ 94{
80 s32 data = i2c_smbus_read_word_data(client, reg); 95 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -109,35 +124,20 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
109 return reg_write(client, reg, ret & ~data); 124 return reg_write(client, reg, ret & ~data);
110} 125}
111 126
112static int mt9m001_init(struct soc_camera_device *icd) 127static int mt9m001_init(struct i2c_client *client)
113{ 128{
114 struct i2c_client *client = to_i2c_client(icd->control);
115 struct soc_camera_link *icl = client->dev.platform_data;
116 int ret; 129 int ret;
117 130
118 dev_dbg(icd->vdev->parent, "%s\n", __func__); 131 dev_dbg(&client->dev, "%s\n", __func__);
119 132
120 if (icl->power) { 133 /*
121 ret = icl->power(&client->dev, 1); 134 * We don't know, whether platform provides reset, issue a soft reset
122 if (ret < 0) { 135 * too. This returns all registers to their default values.
123 dev_err(icd->vdev->parent, 136 */
124 "Platform failed to power-on the camera.\n"); 137 ret = reg_write(client, MT9M001_RESET, 1);
125 return ret; 138 if (!ret)
126 } 139 ret = reg_write(client, MT9M001_RESET, 0);
127 }
128
129 /* The camera could have been already on, we reset it additionally */
130 if (icl->reset)
131 ret = icl->reset(&client->dev);
132 else
133 ret = -ENODEV;
134 140
135 if (ret < 0) {
136 /* Either no platform reset, or platform reset failed */
137 ret = reg_write(client, MT9M001_RESET, 1);
138 if (!ret)
139 ret = reg_write(client, MT9M001_RESET, 0);
140 }
141 /* Disable chip, synchronous option update */ 141 /* Disable chip, synchronous option update */
142 if (!ret) 142 if (!ret)
143 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0); 143 ret = reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
@@ -145,36 +145,12 @@ static int mt9m001_init(struct soc_camera_device *icd)
145 return ret; 145 return ret;
146} 146}
147 147
148static int mt9m001_release(struct soc_camera_device *icd) 148static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
149{ 149{
150 struct i2c_client *client = to_i2c_client(icd->control); 150 struct i2c_client *client = sd->priv;
151 struct soc_camera_link *icl = client->dev.platform_data;
152
153 /* Disable the chip */
154 reg_write(client, MT9M001_OUTPUT_CONTROL, 0);
155
156 if (icl->power)
157 icl->power(&client->dev, 0);
158
159 return 0;
160}
161 151
162static int mt9m001_start_capture(struct soc_camera_device *icd) 152 /* Switch to master "normal" mode or stop sensor readout */
163{ 153 if (reg_write(client, MT9M001_OUTPUT_CONTROL, enable ? 2 : 0) < 0)
164 struct i2c_client *client = to_i2c_client(icd->control);
165
166 /* Switch to master "normal" mode */
167 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 2) < 0)
168 return -EIO;
169 return 0;
170}
171
172static int mt9m001_stop_capture(struct soc_camera_device *icd)
173{
174 struct i2c_client *client = to_i2c_client(icd->control);
175
176 /* Stop sensor readout */
177 if (reg_write(client, MT9M001_OUTPUT_CONTROL, 0) < 0)
178 return -EIO; 154 return -EIO;
179 return 0; 155 return 0;
180} 156}
@@ -182,8 +158,7 @@ static int mt9m001_stop_capture(struct soc_camera_device *icd)
182static int mt9m001_set_bus_param(struct soc_camera_device *icd, 158static int mt9m001_set_bus_param(struct soc_camera_device *icd,
183 unsigned long flags) 159 unsigned long flags)
184{ 160{
185 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 161 struct soc_camera_link *icl = to_soc_camera_link(icd);
186 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
187 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK; 162 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
188 163
189 /* Only one width bit may be set */ 164 /* Only one width bit may be set */
@@ -205,8 +180,7 @@ static int mt9m001_set_bus_param(struct soc_camera_device *icd,
205 180
206static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd) 181static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
207{ 182{
208 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 183 struct soc_camera_link *icl = to_soc_camera_link(icd);
209 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
210 /* MT9M001 has all capture_format parameters fixed */ 184 /* MT9M001 has all capture_format parameters fixed */
211 unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING | 185 unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
212 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 186 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
@@ -220,13 +194,35 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
220 return soc_camera_apply_sensor_flags(icl, flags); 194 return soc_camera_apply_sensor_flags(icl, flags);
221} 195}
222 196
223static int mt9m001_set_crop(struct soc_camera_device *icd, 197static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
224 struct v4l2_rect *rect)
225{ 198{
226 struct i2c_client *client = to_i2c_client(icd->control); 199 struct i2c_client *client = sd->priv;
227 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 200 struct mt9m001 *mt9m001 = to_mt9m001(client);
201 struct v4l2_rect rect = a->c;
202 struct soc_camera_device *icd = client->dev.platform_data;
228 int ret; 203 int ret;
229 const u16 hblank = 9, vblank = 25; 204 const u16 hblank = 9, vblank = 25;
205 unsigned int total_h;
206
207 if (mt9m001->fourcc == V4L2_PIX_FMT_SBGGR8 ||
208 mt9m001->fourcc == V4L2_PIX_FMT_SBGGR16)
209 /*
210 * Bayer format - even number of rows for simplicity,
211 * but let the user play with the top row.
212 */
213 rect.height = ALIGN(rect.height, 2);
214
215 /* Datasheet requirement: see register description */
216 rect.width = ALIGN(rect.width, 2);
217 rect.left = ALIGN(rect.left, 2);
218
219 soc_camera_limit_side(&rect.left, &rect.width,
220 MT9M001_COLUMN_SKIP, MT9M001_MIN_WIDTH, MT9M001_MAX_WIDTH);
221
222 soc_camera_limit_side(&rect.top, &rect.height,
223 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
224
225 total_h = rect.height + icd->y_skip_top + vblank;
230 226
231 /* Blanking and start values - default... */ 227 /* Blanking and start values - default... */
232 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); 228 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -236,66 +232,126 @@ static int mt9m001_set_crop(struct soc_camera_device *icd,
236 /* The caller provides a supported format, as verified per 232 /* The caller provides a supported format, as verified per
237 * call to icd->try_fmt() */ 233 * call to icd->try_fmt() */
238 if (!ret) 234 if (!ret)
239 ret = reg_write(client, MT9M001_COLUMN_START, rect->left); 235 ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
240 if (!ret) 236 if (!ret)
241 ret = reg_write(client, MT9M001_ROW_START, rect->top); 237 ret = reg_write(client, MT9M001_ROW_START, rect.top);
242 if (!ret) 238 if (!ret)
243 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect->width - 1); 239 ret = reg_write(client, MT9M001_WINDOW_WIDTH, rect.width - 1);
244 if (!ret) 240 if (!ret)
245 ret = reg_write(client, MT9M001_WINDOW_HEIGHT, 241 ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
246 rect->height + icd->y_skip_top - 1); 242 rect.height + icd->y_skip_top - 1);
247 if (!ret && mt9m001->autoexposure) { 243 if (!ret && mt9m001->autoexposure) {
248 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, 244 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h);
249 rect->height + icd->y_skip_top + vblank);
250 if (!ret) { 245 if (!ret) {
251 const struct v4l2_queryctrl *qctrl = 246 const struct v4l2_queryctrl *qctrl =
252 soc_camera_find_qctrl(icd->ops, 247 soc_camera_find_qctrl(icd->ops,
253 V4L2_CID_EXPOSURE); 248 V4L2_CID_EXPOSURE);
254 icd->exposure = (524 + (rect->height + icd->y_skip_top + 249 mt9m001->exposure = (524 + (total_h - 1) *
255 vblank - 1) * 250 (qctrl->maximum - qctrl->minimum)) /
256 (qctrl->maximum - qctrl->minimum)) /
257 1048 + qctrl->minimum; 251 1048 + qctrl->minimum;
258 } 252 }
259 } 253 }
260 254
255 if (!ret)
256 mt9m001->rect = rect;
257
261 return ret; 258 return ret;
262} 259}
263 260
264static int mt9m001_set_fmt(struct soc_camera_device *icd, 261static int mt9m001_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
265 struct v4l2_format *f) 262{
263 struct i2c_client *client = sd->priv;
264 struct mt9m001 *mt9m001 = to_mt9m001(client);
265
266 a->c = mt9m001->rect;
267 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
268
269 return 0;
270}
271
272static int mt9m001_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
273{
274 a->bounds.left = MT9M001_COLUMN_SKIP;
275 a->bounds.top = MT9M001_ROW_SKIP;
276 a->bounds.width = MT9M001_MAX_WIDTH;
277 a->bounds.height = MT9M001_MAX_HEIGHT;
278 a->defrect = a->bounds;
279 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
280 a->pixelaspect.numerator = 1;
281 a->pixelaspect.denominator = 1;
282
283 return 0;
284}
285
286static int mt9m001_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
266{ 287{
267 struct v4l2_rect rect = { 288 struct i2c_client *client = sd->priv;
268 .left = icd->x_current, 289 struct mt9m001 *mt9m001 = to_mt9m001(client);
269 .top = icd->y_current, 290 struct v4l2_pix_format *pix = &f->fmt.pix;
270 .width = f->fmt.pix.width, 291
271 .height = f->fmt.pix.height, 292 pix->width = mt9m001->rect.width;
293 pix->height = mt9m001->rect.height;
294 pix->pixelformat = mt9m001->fourcc;
295 pix->field = V4L2_FIELD_NONE;
296 pix->colorspace = V4L2_COLORSPACE_SRGB;
297
298 return 0;
299}
300
301static int mt9m001_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
302{
303 struct i2c_client *client = sd->priv;
304 struct mt9m001 *mt9m001 = to_mt9m001(client);
305 struct v4l2_pix_format *pix = &f->fmt.pix;
306 struct v4l2_crop a = {
307 .c = {
308 .left = mt9m001->rect.left,
309 .top = mt9m001->rect.top,
310 .width = pix->width,
311 .height = pix->height,
312 },
272 }; 313 };
314 int ret;
273 315
274 /* No support for scaling so far, just crop. TODO: use skipping */ 316 /* No support for scaling so far, just crop. TODO: use skipping */
275 return mt9m001_set_crop(icd, &rect); 317 ret = mt9m001_s_crop(sd, &a);
318 if (!ret) {
319 pix->width = mt9m001->rect.width;
320 pix->height = mt9m001->rect.height;
321 mt9m001->fourcc = pix->pixelformat;
322 }
323
324 return ret;
276} 325}
277 326
278static int mt9m001_try_fmt(struct soc_camera_device *icd, 327static int mt9m001_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
279 struct v4l2_format *f)
280{ 328{
329 struct i2c_client *client = sd->priv;
330 struct soc_camera_device *icd = client->dev.platform_data;
281 struct v4l2_pix_format *pix = &f->fmt.pix; 331 struct v4l2_pix_format *pix = &f->fmt.pix;
282 332
283 v4l_bound_align_image(&pix->width, 48, 1280, 1, 333 v4l_bound_align_image(&pix->width, MT9M001_MIN_WIDTH,
284 &pix->height, 32 + icd->y_skip_top, 334 MT9M001_MAX_WIDTH, 1,
285 1024 + icd->y_skip_top, 0, 0); 335 &pix->height, MT9M001_MIN_HEIGHT + icd->y_skip_top,
336 MT9M001_MAX_HEIGHT + icd->y_skip_top, 0, 0);
337
338 if (pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
339 pix->pixelformat == V4L2_PIX_FMT_SBGGR16)
340 pix->height = ALIGN(pix->height - 1, 2);
286 341
287 return 0; 342 return 0;
288} 343}
289 344
290static int mt9m001_get_chip_id(struct soc_camera_device *icd, 345static int mt9m001_g_chip_ident(struct v4l2_subdev *sd,
291 struct v4l2_dbg_chip_ident *id) 346 struct v4l2_dbg_chip_ident *id)
292{ 347{
293 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 348 struct i2c_client *client = sd->priv;
349 struct mt9m001 *mt9m001 = to_mt9m001(client);
294 350
295 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 351 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
296 return -EINVAL; 352 return -EINVAL;
297 353
298 if (id->match.addr != mt9m001->client->addr) 354 if (id->match.addr != client->addr)
299 return -ENODEV; 355 return -ENODEV;
300 356
301 id->ident = mt9m001->model; 357 id->ident = mt9m001->model;
@@ -305,10 +361,10 @@ static int mt9m001_get_chip_id(struct soc_camera_device *icd,
305} 361}
306 362
307#ifdef CONFIG_VIDEO_ADV_DEBUG 363#ifdef CONFIG_VIDEO_ADV_DEBUG
308static int mt9m001_get_register(struct soc_camera_device *icd, 364static int mt9m001_g_register(struct v4l2_subdev *sd,
309 struct v4l2_dbg_register *reg) 365 struct v4l2_dbg_register *reg)
310{ 366{
311 struct i2c_client *client = to_i2c_client(icd->control); 367 struct i2c_client *client = sd->priv;
312 368
313 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 369 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
314 return -EINVAL; 370 return -EINVAL;
@@ -325,10 +381,10 @@ static int mt9m001_get_register(struct soc_camera_device *icd,
325 return 0; 381 return 0;
326} 382}
327 383
328static int mt9m001_set_register(struct soc_camera_device *icd, 384static int mt9m001_s_register(struct v4l2_subdev *sd,
329 struct v4l2_dbg_register *reg) 385 struct v4l2_dbg_register *reg)
330{ 386{
331 struct i2c_client *client = to_i2c_client(icd->control); 387 struct i2c_client *client = sd->priv;
332 388
333 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 389 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
334 return -EINVAL; 390 return -EINVAL;
@@ -381,39 +437,17 @@ static const struct v4l2_queryctrl mt9m001_controls[] = {
381 } 437 }
382}; 438};
383 439
384static int mt9m001_video_probe(struct soc_camera_device *);
385static void mt9m001_video_remove(struct soc_camera_device *);
386static int mt9m001_get_control(struct soc_camera_device *, struct v4l2_control *);
387static int mt9m001_set_control(struct soc_camera_device *, struct v4l2_control *);
388
389static struct soc_camera_ops mt9m001_ops = { 440static struct soc_camera_ops mt9m001_ops = {
390 .owner = THIS_MODULE,
391 .probe = mt9m001_video_probe,
392 .remove = mt9m001_video_remove,
393 .init = mt9m001_init,
394 .release = mt9m001_release,
395 .start_capture = mt9m001_start_capture,
396 .stop_capture = mt9m001_stop_capture,
397 .set_crop = mt9m001_set_crop,
398 .set_fmt = mt9m001_set_fmt,
399 .try_fmt = mt9m001_try_fmt,
400 .set_bus_param = mt9m001_set_bus_param, 441 .set_bus_param = mt9m001_set_bus_param,
401 .query_bus_param = mt9m001_query_bus_param, 442 .query_bus_param = mt9m001_query_bus_param,
402 .controls = mt9m001_controls, 443 .controls = mt9m001_controls,
403 .num_controls = ARRAY_SIZE(mt9m001_controls), 444 .num_controls = ARRAY_SIZE(mt9m001_controls),
404 .get_control = mt9m001_get_control,
405 .set_control = mt9m001_set_control,
406 .get_chip_id = mt9m001_get_chip_id,
407#ifdef CONFIG_VIDEO_ADV_DEBUG
408 .get_register = mt9m001_get_register,
409 .set_register = mt9m001_set_register,
410#endif
411}; 445};
412 446
413static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 447static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
414{ 448{
415 struct i2c_client *client = to_i2c_client(icd->control); 449 struct i2c_client *client = sd->priv;
416 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 450 struct mt9m001 *mt9m001 = to_mt9m001(client);
417 int data; 451 int data;
418 452
419 switch (ctrl->id) { 453 switch (ctrl->id) {
@@ -426,14 +460,21 @@ static int mt9m001_get_control(struct soc_camera_device *icd, struct v4l2_contro
426 case V4L2_CID_EXPOSURE_AUTO: 460 case V4L2_CID_EXPOSURE_AUTO:
427 ctrl->value = mt9m001->autoexposure; 461 ctrl->value = mt9m001->autoexposure;
428 break; 462 break;
463 case V4L2_CID_GAIN:
464 ctrl->value = mt9m001->gain;
465 break;
466 case V4L2_CID_EXPOSURE:
467 ctrl->value = mt9m001->exposure;
468 break;
429 } 469 }
430 return 0; 470 return 0;
431} 471}
432 472
433static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 473static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
434{ 474{
435 struct i2c_client *client = to_i2c_client(icd->control); 475 struct i2c_client *client = sd->priv;
436 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 476 struct mt9m001 *mt9m001 = to_mt9m001(client);
477 struct soc_camera_device *icd = client->dev.platform_data;
437 const struct v4l2_queryctrl *qctrl; 478 const struct v4l2_queryctrl *qctrl;
438 int data; 479 int data;
439 480
@@ -460,7 +501,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
460 unsigned long range = qctrl->default_value - qctrl->minimum; 501 unsigned long range = qctrl->default_value - qctrl->minimum;
461 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 502 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
462 503
463 dev_dbg(&icd->dev, "Setting gain %d\n", data); 504 dev_dbg(&client->dev, "Setting gain %d\n", data);
464 data = reg_write(client, MT9M001_GLOBAL_GAIN, data); 505 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
465 if (data < 0) 506 if (data < 0)
466 return -EIO; 507 return -EIO;
@@ -478,7 +519,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
478 else 519 else
479 data = ((gain - 64) * 7 + 28) / 56 + 96; 520 data = ((gain - 64) * 7 + 28) / 56 + 96;
480 521
481 dev_dbg(&icd->dev, "Setting gain from %d to %d\n", 522 dev_dbg(&client->dev, "Setting gain from %d to %d\n",
482 reg_read(client, MT9M001_GLOBAL_GAIN), data); 523 reg_read(client, MT9M001_GLOBAL_GAIN), data);
483 data = reg_write(client, MT9M001_GLOBAL_GAIN, data); 524 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
484 if (data < 0) 525 if (data < 0)
@@ -486,7 +527,7 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
486 } 527 }
487 528
488 /* Success */ 529 /* Success */
489 icd->gain = ctrl->value; 530 mt9m001->gain = ctrl->value;
490 break; 531 break;
491 case V4L2_CID_EXPOSURE: 532 case V4L2_CID_EXPOSURE:
492 /* mt9m001 has maximum == default */ 533 /* mt9m001 has maximum == default */
@@ -497,23 +538,27 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
497 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 + 538 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
498 range / 2) / range + 1; 539 range / 2) / range + 1;
499 540
500 dev_dbg(&icd->dev, "Setting shutter width from %d to %lu\n", 541 dev_dbg(&client->dev,
501 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter); 542 "Setting shutter width from %d to %lu\n",
543 reg_read(client, MT9M001_SHUTTER_WIDTH),
544 shutter);
502 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) 545 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
503 return -EIO; 546 return -EIO;
504 icd->exposure = ctrl->value; 547 mt9m001->exposure = ctrl->value;
505 mt9m001->autoexposure = 0; 548 mt9m001->autoexposure = 0;
506 } 549 }
507 break; 550 break;
508 case V4L2_CID_EXPOSURE_AUTO: 551 case V4L2_CID_EXPOSURE_AUTO:
509 if (ctrl->value) { 552 if (ctrl->value) {
510 const u16 vblank = 25; 553 const u16 vblank = 25;
511 if (reg_write(client, MT9M001_SHUTTER_WIDTH, icd->height + 554 unsigned int total_h = mt9m001->rect.height +
512 icd->y_skip_top + vblank) < 0) 555 icd->y_skip_top + vblank;
556 if (reg_write(client, MT9M001_SHUTTER_WIDTH,
557 total_h) < 0)
513 return -EIO; 558 return -EIO;
514 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 559 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
515 icd->exposure = (524 + (icd->height + icd->y_skip_top + vblank - 1) * 560 mt9m001->exposure = (524 + (total_h - 1) *
516 (qctrl->maximum - qctrl->minimum)) / 561 (qctrl->maximum - qctrl->minimum)) /
517 1048 + qctrl->minimum; 562 1048 + qctrl->minimum;
518 mt9m001->autoexposure = 1; 563 mt9m001->autoexposure = 1;
519 } else 564 } else
@@ -525,14 +570,14 @@ static int mt9m001_set_control(struct soc_camera_device *icd, struct v4l2_contro
525 570
526/* Interface active, can use i2c. If it fails, it can indeed mean, that 571/* Interface active, can use i2c. If it fails, it can indeed mean, that
527 * this wasn't our capture interface, so, we wait for the right one */ 572 * this wasn't our capture interface, so, we wait for the right one */
528static int mt9m001_video_probe(struct soc_camera_device *icd) 573static int mt9m001_video_probe(struct soc_camera_device *icd,
574 struct i2c_client *client)
529{ 575{
530 struct i2c_client *client = to_i2c_client(icd->control); 576 struct mt9m001 *mt9m001 = to_mt9m001(client);
531 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 577 struct soc_camera_link *icl = to_soc_camera_link(icd);
532 struct soc_camera_link *icl = client->dev.platform_data;
533 s32 data; 578 s32 data;
534 int ret;
535 unsigned long flags; 579 unsigned long flags;
580 int ret;
536 581
537 /* We must have a parent by now. And it cannot be a wrong one. 582 /* We must have a parent by now. And it cannot be a wrong one.
538 * So this entire test is completely redundant. */ 583 * So this entire test is completely redundant. */
@@ -542,7 +587,7 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
542 587
543 /* Enable the chip */ 588 /* Enable the chip */
544 data = reg_write(client, MT9M001_CHIP_ENABLE, 1); 589 data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
545 dev_dbg(&icd->dev, "write: %d\n", data); 590 dev_dbg(&client->dev, "write: %d\n", data);
546 591
547 /* Read out the chip version register */ 592 /* Read out the chip version register */
548 data = reg_read(client, MT9M001_CHIP_VERSION); 593 data = reg_read(client, MT9M001_CHIP_VERSION);
@@ -559,10 +604,9 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
559 icd->formats = mt9m001_monochrome_formats; 604 icd->formats = mt9m001_monochrome_formats;
560 break; 605 break;
561 default: 606 default:
562 ret = -ENODEV; 607 dev_err(&client->dev,
563 dev_err(&icd->dev,
564 "No MT9M001 chip detected, register read %x\n", data); 608 "No MT9M001 chip detected, register read %x\n", data);
565 goto ei2c; 609 return -ENODEV;
566 } 610 }
567 611
568 icd->num_formats = 0; 612 icd->num_formats = 0;
@@ -585,42 +629,72 @@ static int mt9m001_video_probe(struct soc_camera_device *icd)
585 if (flags & SOCAM_DATAWIDTH_8) 629 if (flags & SOCAM_DATAWIDTH_8)
586 icd->num_formats++; 630 icd->num_formats++;
587 631
588 dev_info(&icd->dev, "Detected a MT9M001 chip ID %x (%s)\n", data, 632 mt9m001->fourcc = icd->formats->fourcc;
633
634 dev_info(&client->dev, "Detected a MT9M001 chip ID %x (%s)\n", data,
589 data == 0x8431 ? "C12STM" : "C12ST"); 635 data == 0x8431 ? "C12STM" : "C12ST");
590 636
591 /* Now that we know the model, we can start video */ 637 ret = mt9m001_init(client);
592 ret = soc_camera_video_start(icd); 638 if (ret < 0)
593 if (ret) 639 dev_err(&client->dev, "Failed to initialise the camera\n");
594 goto eisis;
595 640
596 return 0; 641 /* mt9m001_init() has reset the chip, returning registers to defaults */
642 mt9m001->gain = 64;
643 mt9m001->exposure = 255;
597 644
598eisis:
599ei2c:
600 return ret; 645 return ret;
601} 646}
602 647
603static void mt9m001_video_remove(struct soc_camera_device *icd) 648static void mt9m001_video_remove(struct soc_camera_device *icd)
604{ 649{
605 struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); 650 struct soc_camera_link *icl = to_soc_camera_link(icd);
606 struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
607 651
608 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m001->client->addr, 652 dev_dbg(&icd->dev, "Video removed: %p, %p\n",
609 icd->dev.parent, icd->vdev); 653 icd->dev.parent, icd->vdev);
610 soc_camera_video_stop(icd);
611 if (icl->free_bus) 654 if (icl->free_bus)
612 icl->free_bus(icl); 655 icl->free_bus(icl);
613} 656}
614 657
658static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
659 .g_ctrl = mt9m001_g_ctrl,
660 .s_ctrl = mt9m001_s_ctrl,
661 .g_chip_ident = mt9m001_g_chip_ident,
662#ifdef CONFIG_VIDEO_ADV_DEBUG
663 .g_register = mt9m001_g_register,
664 .s_register = mt9m001_s_register,
665#endif
666};
667
668static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
669 .s_stream = mt9m001_s_stream,
670 .s_fmt = mt9m001_s_fmt,
671 .g_fmt = mt9m001_g_fmt,
672 .try_fmt = mt9m001_try_fmt,
673 .s_crop = mt9m001_s_crop,
674 .g_crop = mt9m001_g_crop,
675 .cropcap = mt9m001_cropcap,
676};
677
678static struct v4l2_subdev_ops mt9m001_subdev_ops = {
679 .core = &mt9m001_subdev_core_ops,
680 .video = &mt9m001_subdev_video_ops,
681};
682
615static int mt9m001_probe(struct i2c_client *client, 683static int mt9m001_probe(struct i2c_client *client,
616 const struct i2c_device_id *did) 684 const struct i2c_device_id *did)
617{ 685{
618 struct mt9m001 *mt9m001; 686 struct mt9m001 *mt9m001;
619 struct soc_camera_device *icd; 687 struct soc_camera_device *icd = client->dev.platform_data;
620 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 688 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
621 struct soc_camera_link *icl = client->dev.platform_data; 689 struct soc_camera_link *icl;
622 int ret; 690 int ret;
623 691
692 if (!icd) {
693 dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
694 return -EINVAL;
695 }
696
697 icl = to_soc_camera_link(icd);
624 if (!icl) { 698 if (!icl) {
625 dev_err(&client->dev, "MT9M001 driver needs platform data\n"); 699 dev_err(&client->dev, "MT9M001 driver needs platform data\n");
626 return -EINVAL; 700 return -EINVAL;
@@ -636,43 +710,40 @@ static int mt9m001_probe(struct i2c_client *client,
636 if (!mt9m001) 710 if (!mt9m001)
637 return -ENOMEM; 711 return -ENOMEM;
638 712
639 mt9m001->client = client; 713 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
640 i2c_set_clientdata(client, mt9m001);
641 714
642 /* Second stage probe - when a capture adapter is there */ 715 /* Second stage probe - when a capture adapter is there */
643 icd = &mt9m001->icd; 716 icd->ops = &mt9m001_ops;
644 icd->ops = &mt9m001_ops; 717 icd->y_skip_top = 0;
645 icd->control = &client->dev; 718
646 icd->x_min = 20; 719 mt9m001->rect.left = MT9M001_COLUMN_SKIP;
647 icd->y_min = 12; 720 mt9m001->rect.top = MT9M001_ROW_SKIP;
648 icd->x_current = 20; 721 mt9m001->rect.width = MT9M001_MAX_WIDTH;
649 icd->y_current = 12; 722 mt9m001->rect.height = MT9M001_MAX_HEIGHT;
650 icd->width_min = 48; 723
651 icd->width_max = 1280;
652 icd->height_min = 32;
653 icd->height_max = 1024;
654 icd->y_skip_top = 1;
655 icd->iface = icl->bus_id;
656 /* Simulated autoexposure. If enabled, we calculate shutter width 724 /* Simulated autoexposure. If enabled, we calculate shutter width
657 * ourselves in the driver based on vertical blanking and frame width */ 725 * ourselves in the driver based on vertical blanking and frame width */
658 mt9m001->autoexposure = 1; 726 mt9m001->autoexposure = 1;
659 727
660 ret = soc_camera_device_register(icd); 728 ret = mt9m001_video_probe(icd, client);
661 if (ret) 729 if (ret) {
662 goto eisdr; 730 icd->ops = NULL;
663 731 i2c_set_clientdata(client, NULL);
664 return 0; 732 kfree(mt9m001);
733 }
665 734
666eisdr:
667 kfree(mt9m001);
668 return ret; 735 return ret;
669} 736}
670 737
671static int mt9m001_remove(struct i2c_client *client) 738static int mt9m001_remove(struct i2c_client *client)
672{ 739{
673 struct mt9m001 *mt9m001 = i2c_get_clientdata(client); 740 struct mt9m001 *mt9m001 = to_mt9m001(client);
741 struct soc_camera_device *icd = client->dev.platform_data;
674 742
675 soc_camera_device_unregister(&mt9m001->icd); 743 icd->ops = NULL;
744 mt9m001_video_remove(icd);
745 i2c_set_clientdata(client, NULL);
746 client->driver = NULL;
676 kfree(mt9m001); 747 kfree(mt9m001);
677 748
678 return 0; 749 return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index fc5e2de03766..90da699601ea 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -148,12 +148,12 @@ enum mt9m111_context {
148}; 148};
149 149
150struct mt9m111 { 150struct mt9m111 {
151 struct i2c_client *client; 151 struct v4l2_subdev subdev;
152 struct soc_camera_device icd;
153 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */ 152 int model; /* V4L2_IDENT_MT9M11x* codes from v4l2-chip-ident.h */
154 enum mt9m111_context context; 153 enum mt9m111_context context;
155 struct v4l2_rect rect; 154 struct v4l2_rect rect;
156 u32 pixfmt; 155 u32 pixfmt;
156 unsigned int gain;
157 unsigned char autoexposure; 157 unsigned char autoexposure;
158 unsigned char datawidth; 158 unsigned char datawidth;
159 unsigned int powered:1; 159 unsigned int powered:1;
@@ -166,6 +166,11 @@ struct mt9m111 {
166 unsigned int autowhitebalance:1; 166 unsigned int autowhitebalance:1;
167}; 167};
168 168
169static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
170{
171 return container_of(i2c_get_clientdata(client), struct mt9m111, subdev);
172}
173
169static int reg_page_map_set(struct i2c_client *client, const u16 reg) 174static int reg_page_map_set(struct i2c_client *client, const u16 reg)
170{ 175{
171 int ret; 176 int ret;
@@ -190,7 +195,7 @@ static int mt9m111_reg_read(struct i2c_client *client, const u16 reg)
190 195
191 ret = reg_page_map_set(client, reg); 196 ret = reg_page_map_set(client, reg);
192 if (!ret) 197 if (!ret)
193 ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); 198 ret = swab16(i2c_smbus_read_word_data(client, reg & 0xff));
194 199
195 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret); 200 dev_dbg(&client->dev, "read reg.%03x -> %04x\n", reg, ret);
196 return ret; 201 return ret;
@@ -203,7 +208,7 @@ static int mt9m111_reg_write(struct i2c_client *client, const u16 reg,
203 208
204 ret = reg_page_map_set(client, reg); 209 ret = reg_page_map_set(client, reg);
205 if (!ret) 210 if (!ret)
206 ret = i2c_smbus_write_word_data(client, (reg & 0xff), 211 ret = i2c_smbus_write_word_data(client, reg & 0xff,
207 swab16(data)); 212 swab16(data));
208 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); 213 dev_dbg(&client->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret);
209 return ret; 214 return ret;
@@ -229,10 +234,9 @@ static int mt9m111_reg_clear(struct i2c_client *client, const u16 reg,
229 return mt9m111_reg_write(client, reg, ret & ~data); 234 return mt9m111_reg_write(client, reg, ret & ~data);
230} 235}
231 236
232static int mt9m111_set_context(struct soc_camera_device *icd, 237static int mt9m111_set_context(struct i2c_client *client,
233 enum mt9m111_context ctxt) 238 enum mt9m111_context ctxt)
234{ 239{
235 struct i2c_client *client = to_i2c_client(icd->control);
236 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B 240 int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B
237 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B 241 | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B
238 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B 242 | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B
@@ -246,17 +250,16 @@ static int mt9m111_set_context(struct soc_camera_device *icd,
246 return reg_write(CONTEXT_CONTROL, valA); 250 return reg_write(CONTEXT_CONTROL, valA);
247} 251}
248 252
249static int mt9m111_setup_rect(struct soc_camera_device *icd, 253static int mt9m111_setup_rect(struct i2c_client *client,
250 struct v4l2_rect *rect) 254 struct v4l2_rect *rect)
251{ 255{
252 struct i2c_client *client = to_i2c_client(icd->control); 256 struct mt9m111 *mt9m111 = to_mt9m111(client);
253 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
254 int ret, is_raw_format; 257 int ret, is_raw_format;
255 int width = rect->width; 258 int width = rect->width;
256 int height = rect->height; 259 int height = rect->height;
257 260
258 if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) 261 if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
259 || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) 262 mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)
260 is_raw_format = 1; 263 is_raw_format = 1;
261 else 264 else
262 is_raw_format = 0; 265 is_raw_format = 0;
@@ -292,9 +295,8 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd,
292 return ret; 295 return ret;
293} 296}
294 297
295static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) 298static int mt9m111_setup_pixfmt(struct i2c_client *client, u16 outfmt)
296{ 299{
297 struct i2c_client *client = to_i2c_client(icd->control);
298 int ret; 300 int ret;
299 301
300 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); 302 ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt);
@@ -303,19 +305,19 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt)
303 return ret; 305 return ret;
304} 306}
305 307
306static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) 308static int mt9m111_setfmt_bayer8(struct i2c_client *client)
307{ 309{
308 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); 310 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_PROCESSED_BAYER);
309} 311}
310 312
311static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) 313static int mt9m111_setfmt_bayer10(struct i2c_client *client)
312{ 314{
313 return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); 315 return mt9m111_setup_pixfmt(client, MT9M111_OUTFMT_BYPASS_IFP);
314} 316}
315 317
316static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) 318static int mt9m111_setfmt_rgb565(struct i2c_client *client)
317{ 319{
318 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 320 struct mt9m111 *mt9m111 = to_mt9m111(client);
319 int val = 0; 321 int val = 0;
320 322
321 if (mt9m111->swap_rgb_red_blue) 323 if (mt9m111->swap_rgb_red_blue)
@@ -324,12 +326,12 @@ static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd)
324 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 326 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
325 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; 327 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565;
326 328
327 return mt9m111_setup_pixfmt(icd, val); 329 return mt9m111_setup_pixfmt(client, val);
328} 330}
329 331
330static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) 332static int mt9m111_setfmt_rgb555(struct i2c_client *client)
331{ 333{
332 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 334 struct mt9m111 *mt9m111 = to_mt9m111(client);
333 int val = 0; 335 int val = 0;
334 336
335 if (mt9m111->swap_rgb_red_blue) 337 if (mt9m111->swap_rgb_red_blue)
@@ -338,12 +340,12 @@ static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd)
338 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; 340 val |= MT9M111_OUTFMT_SWAP_RGB_EVEN;
339 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; 341 val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555;
340 342
341 return mt9m111_setup_pixfmt(icd, val); 343 return mt9m111_setup_pixfmt(client, val);
342} 344}
343 345
344static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) 346static int mt9m111_setfmt_yuv(struct i2c_client *client)
345{ 347{
346 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 348 struct mt9m111 *mt9m111 = to_mt9m111(client);
347 int val = 0; 349 int val = 0;
348 350
349 if (mt9m111->swap_yuv_cb_cr) 351 if (mt9m111->swap_yuv_cb_cr)
@@ -351,52 +353,22 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd)
351 if (mt9m111->swap_yuv_y_chromas) 353 if (mt9m111->swap_yuv_y_chromas)
352 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; 354 val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y;
353 355
354 return mt9m111_setup_pixfmt(icd, val); 356 return mt9m111_setup_pixfmt(client, val);
355} 357}
356 358
357static int mt9m111_enable(struct soc_camera_device *icd) 359static int mt9m111_enable(struct i2c_client *client)
358{ 360{
359 struct i2c_client *client = to_i2c_client(icd->control); 361 struct mt9m111 *mt9m111 = to_mt9m111(client);
360 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
361 struct soc_camera_link *icl = client->dev.platform_data;
362 int ret; 362 int ret;
363 363
364 if (icl->power) {
365 ret = icl->power(&client->dev, 1);
366 if (ret < 0) {
367 dev_err(icd->vdev->parent,
368 "Platform failed to power-on the camera.\n");
369 return ret;
370 }
371 }
372
373 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); 364 ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE);
374 if (!ret) 365 if (!ret)
375 mt9m111->powered = 1; 366 mt9m111->powered = 1;
376 return ret; 367 return ret;
377} 368}
378 369
379static int mt9m111_disable(struct soc_camera_device *icd) 370static int mt9m111_reset(struct i2c_client *client)
380{
381 struct i2c_client *client = to_i2c_client(icd->control);
382 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
383 struct soc_camera_link *icl = client->dev.platform_data;
384 int ret;
385
386 ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE);
387 if (!ret)
388 mt9m111->powered = 0;
389
390 if (icl->power)
391 icl->power(&client->dev, 0);
392
393 return ret;
394}
395
396static int mt9m111_reset(struct soc_camera_device *icd)
397{ 371{
398 struct i2c_client *client = to_i2c_client(icd->control);
399 struct soc_camera_link *icl = client->dev.platform_data;
400 int ret; 372 int ret;
401 373
402 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); 374 ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
@@ -406,26 +378,12 @@ static int mt9m111_reset(struct soc_camera_device *icd)
406 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE 378 ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE
407 | MT9M111_RESET_RESET_SOC); 379 | MT9M111_RESET_RESET_SOC);
408 380
409 if (icl->reset)
410 icl->reset(&client->dev);
411
412 return ret; 381 return ret;
413} 382}
414 383
415static int mt9m111_start_capture(struct soc_camera_device *icd)
416{
417 return 0;
418}
419
420static int mt9m111_stop_capture(struct soc_camera_device *icd)
421{
422 return 0;
423}
424
425static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) 384static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
426{ 385{
427 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 386 struct soc_camera_link *icl = to_soc_camera_link(icd);
428 struct soc_camera_link *icl = mt9m111->client->dev.platform_data;
429 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | 387 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
430 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | 388 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
431 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8; 389 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
@@ -438,62 +396,126 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
438 return 0; 396 return 0;
439} 397}
440 398
441static int mt9m111_set_crop(struct soc_camera_device *icd, 399static int mt9m111_make_rect(struct i2c_client *client,
442 struct v4l2_rect *rect) 400 struct v4l2_rect *rect)
443{ 401{
444 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 402 struct mt9m111 *mt9m111 = to_mt9m111(client);
403
404 if (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8 ||
405 mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16) {
406 /* Bayer format - even size lengths */
407 rect->width = ALIGN(rect->width, 2);
408 rect->height = ALIGN(rect->height, 2);
409 /* Let the user play with the starting pixel */
410 }
411
412 /* FIXME: the datasheet doesn't specify minimum sizes */
413 soc_camera_limit_side(&rect->left, &rect->width,
414 MT9M111_MIN_DARK_COLS, 2, MT9M111_MAX_WIDTH);
415
416 soc_camera_limit_side(&rect->top, &rect->height,
417 MT9M111_MIN_DARK_ROWS, 2, MT9M111_MAX_HEIGHT);
418
419 return mt9m111_setup_rect(client, rect);
420}
421
422static int mt9m111_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
423{
424 struct v4l2_rect rect = a->c;
425 struct i2c_client *client = sd->priv;
426 struct mt9m111 *mt9m111 = to_mt9m111(client);
445 int ret; 427 int ret;
446 428
447 dev_dbg(&icd->dev, "%s left=%d, top=%d, width=%d, height=%d\n", 429 dev_dbg(&client->dev, "%s left=%d, top=%d, width=%d, height=%d\n",
448 __func__, rect->left, rect->top, rect->width, 430 __func__, rect.left, rect.top, rect.width, rect.height);
449 rect->height);
450 431
451 ret = mt9m111_setup_rect(icd, rect); 432 ret = mt9m111_make_rect(client, &rect);
452 if (!ret) 433 if (!ret)
453 mt9m111->rect = *rect; 434 mt9m111->rect = rect;
454 return ret; 435 return ret;
455} 436}
456 437
457static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) 438static int mt9m111_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
458{ 439{
459 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 440 struct i2c_client *client = sd->priv;
441 struct mt9m111 *mt9m111 = to_mt9m111(client);
442
443 a->c = mt9m111->rect;
444 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
445
446 return 0;
447}
448
449static int mt9m111_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
450{
451 a->bounds.left = MT9M111_MIN_DARK_COLS;
452 a->bounds.top = MT9M111_MIN_DARK_ROWS;
453 a->bounds.width = MT9M111_MAX_WIDTH;
454 a->bounds.height = MT9M111_MAX_HEIGHT;
455 a->defrect = a->bounds;
456 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
457 a->pixelaspect.numerator = 1;
458 a->pixelaspect.denominator = 1;
459
460 return 0;
461}
462
463static int mt9m111_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
464{
465 struct i2c_client *client = sd->priv;
466 struct mt9m111 *mt9m111 = to_mt9m111(client);
467 struct v4l2_pix_format *pix = &f->fmt.pix;
468
469 pix->width = mt9m111->rect.width;
470 pix->height = mt9m111->rect.height;
471 pix->pixelformat = mt9m111->pixfmt;
472 pix->field = V4L2_FIELD_NONE;
473 pix->colorspace = V4L2_COLORSPACE_SRGB;
474
475 return 0;
476}
477
478static int mt9m111_set_pixfmt(struct i2c_client *client, u32 pixfmt)
479{
480 struct mt9m111 *mt9m111 = to_mt9m111(client);
460 int ret; 481 int ret;
461 482
462 switch (pixfmt) { 483 switch (pixfmt) {
463 case V4L2_PIX_FMT_SBGGR8: 484 case V4L2_PIX_FMT_SBGGR8:
464 ret = mt9m111_setfmt_bayer8(icd); 485 ret = mt9m111_setfmt_bayer8(client);
465 break; 486 break;
466 case V4L2_PIX_FMT_SBGGR16: 487 case V4L2_PIX_FMT_SBGGR16:
467 ret = mt9m111_setfmt_bayer10(icd); 488 ret = mt9m111_setfmt_bayer10(client);
468 break; 489 break;
469 case V4L2_PIX_FMT_RGB555: 490 case V4L2_PIX_FMT_RGB555:
470 ret = mt9m111_setfmt_rgb555(icd); 491 ret = mt9m111_setfmt_rgb555(client);
471 break; 492 break;
472 case V4L2_PIX_FMT_RGB565: 493 case V4L2_PIX_FMT_RGB565:
473 ret = mt9m111_setfmt_rgb565(icd); 494 ret = mt9m111_setfmt_rgb565(client);
474 break; 495 break;
475 case V4L2_PIX_FMT_UYVY: 496 case V4L2_PIX_FMT_UYVY:
476 mt9m111->swap_yuv_y_chromas = 0; 497 mt9m111->swap_yuv_y_chromas = 0;
477 mt9m111->swap_yuv_cb_cr = 0; 498 mt9m111->swap_yuv_cb_cr = 0;
478 ret = mt9m111_setfmt_yuv(icd); 499 ret = mt9m111_setfmt_yuv(client);
479 break; 500 break;
480 case V4L2_PIX_FMT_VYUY: 501 case V4L2_PIX_FMT_VYUY:
481 mt9m111->swap_yuv_y_chromas = 0; 502 mt9m111->swap_yuv_y_chromas = 0;
482 mt9m111->swap_yuv_cb_cr = 1; 503 mt9m111->swap_yuv_cb_cr = 1;
483 ret = mt9m111_setfmt_yuv(icd); 504 ret = mt9m111_setfmt_yuv(client);
484 break; 505 break;
485 case V4L2_PIX_FMT_YUYV: 506 case V4L2_PIX_FMT_YUYV:
486 mt9m111->swap_yuv_y_chromas = 1; 507 mt9m111->swap_yuv_y_chromas = 1;
487 mt9m111->swap_yuv_cb_cr = 0; 508 mt9m111->swap_yuv_cb_cr = 0;
488 ret = mt9m111_setfmt_yuv(icd); 509 ret = mt9m111_setfmt_yuv(client);
489 break; 510 break;
490 case V4L2_PIX_FMT_YVYU: 511 case V4L2_PIX_FMT_YVYU:
491 mt9m111->swap_yuv_y_chromas = 1; 512 mt9m111->swap_yuv_y_chromas = 1;
492 mt9m111->swap_yuv_cb_cr = 1; 513 mt9m111->swap_yuv_cb_cr = 1;
493 ret = mt9m111_setfmt_yuv(icd); 514 ret = mt9m111_setfmt_yuv(client);
494 break; 515 break;
495 default: 516 default:
496 dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); 517 dev_err(&client->dev, "Pixel format not handled : %x\n",
518 pixfmt);
497 ret = -EINVAL; 519 ret = -EINVAL;
498 } 520 }
499 521
@@ -503,10 +525,10 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt)
503 return ret; 525 return ret;
504} 526}
505 527
506static int mt9m111_set_fmt(struct soc_camera_device *icd, 528static int mt9m111_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
507 struct v4l2_format *f)
508{ 529{
509 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 530 struct i2c_client *client = sd->priv;
531 struct mt9m111 *mt9m111 = to_mt9m111(client);
510 struct v4l2_pix_format *pix = &f->fmt.pix; 532 struct v4l2_pix_format *pix = &f->fmt.pix;
511 struct v4l2_rect rect = { 533 struct v4l2_rect rect = {
512 .left = mt9m111->rect.left, 534 .left = mt9m111->rect.left,
@@ -516,40 +538,56 @@ static int mt9m111_set_fmt(struct soc_camera_device *icd,
516 }; 538 };
517 int ret; 539 int ret;
518 540
519 dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", 541 dev_dbg(&client->dev,
520 __func__, pix->pixelformat, rect.left, rect.top, rect.width, 542 "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", __func__,
521 rect.height); 543 pix->pixelformat, rect.left, rect.top, rect.width, rect.height);
522 544
523 ret = mt9m111_setup_rect(icd, &rect); 545 ret = mt9m111_make_rect(client, &rect);
524 if (!ret) 546 if (!ret)
525 ret = mt9m111_set_pixfmt(icd, pix->pixelformat); 547 ret = mt9m111_set_pixfmt(client, pix->pixelformat);
526 if (!ret) 548 if (!ret)
527 mt9m111->rect = rect; 549 mt9m111->rect = rect;
528 return ret; 550 return ret;
529} 551}
530 552
531static int mt9m111_try_fmt(struct soc_camera_device *icd, 553static int mt9m111_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
532 struct v4l2_format *f)
533{ 554{
534 struct v4l2_pix_format *pix = &f->fmt.pix; 555 struct v4l2_pix_format *pix = &f->fmt.pix;
556 bool bayer = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
557 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
558
559 /*
560 * With Bayer format enforce even side lengths, but let the user play
561 * with the starting pixel
562 */
535 563
536 if (pix->height > MT9M111_MAX_HEIGHT) 564 if (pix->height > MT9M111_MAX_HEIGHT)
537 pix->height = MT9M111_MAX_HEIGHT; 565 pix->height = MT9M111_MAX_HEIGHT;
566 else if (pix->height < 2)
567 pix->height = 2;
568 else if (bayer)
569 pix->height = ALIGN(pix->height, 2);
570
538 if (pix->width > MT9M111_MAX_WIDTH) 571 if (pix->width > MT9M111_MAX_WIDTH)
539 pix->width = MT9M111_MAX_WIDTH; 572 pix->width = MT9M111_MAX_WIDTH;
573 else if (pix->width < 2)
574 pix->width = 2;
575 else if (bayer)
576 pix->width = ALIGN(pix->width, 2);
540 577
541 return 0; 578 return 0;
542} 579}
543 580
544static int mt9m111_get_chip_id(struct soc_camera_device *icd, 581static int mt9m111_g_chip_ident(struct v4l2_subdev *sd,
545 struct v4l2_dbg_chip_ident *id) 582 struct v4l2_dbg_chip_ident *id)
546{ 583{
547 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 584 struct i2c_client *client = sd->priv;
585 struct mt9m111 *mt9m111 = to_mt9m111(client);
548 586
549 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 587 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
550 return -EINVAL; 588 return -EINVAL;
551 589
552 if (id->match.addr != mt9m111->client->addr) 590 if (id->match.addr != client->addr)
553 return -ENODEV; 591 return -ENODEV;
554 592
555 id->ident = mt9m111->model; 593 id->ident = mt9m111->model;
@@ -559,11 +597,11 @@ static int mt9m111_get_chip_id(struct soc_camera_device *icd,
559} 597}
560 598
561#ifdef CONFIG_VIDEO_ADV_DEBUG 599#ifdef CONFIG_VIDEO_ADV_DEBUG
562static int mt9m111_get_register(struct soc_camera_device *icd, 600static int mt9m111_g_register(struct v4l2_subdev *sd,
563 struct v4l2_dbg_register *reg) 601 struct v4l2_dbg_register *reg)
564{ 602{
603 struct i2c_client *client = sd->priv;
565 int val; 604 int val;
566 struct i2c_client *client = to_i2c_client(icd->control);
567 605
568 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 606 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
569 return -EINVAL; 607 return -EINVAL;
@@ -580,10 +618,10 @@ static int mt9m111_get_register(struct soc_camera_device *icd,
580 return 0; 618 return 0;
581} 619}
582 620
583static int mt9m111_set_register(struct soc_camera_device *icd, 621static int mt9m111_s_register(struct v4l2_subdev *sd,
584 struct v4l2_dbg_register *reg) 622 struct v4l2_dbg_register *reg)
585{ 623{
586 struct i2c_client *client = to_i2c_client(icd->control); 624 struct i2c_client *client = sd->priv;
587 625
588 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) 626 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff)
589 return -EINVAL; 627 return -EINVAL;
@@ -635,45 +673,21 @@ static const struct v4l2_queryctrl mt9m111_controls[] = {
635 } 673 }
636}; 674};
637 675
638static int mt9m111_video_probe(struct soc_camera_device *);
639static void mt9m111_video_remove(struct soc_camera_device *);
640static int mt9m111_get_control(struct soc_camera_device *,
641 struct v4l2_control *);
642static int mt9m111_set_control(struct soc_camera_device *,
643 struct v4l2_control *);
644static int mt9m111_resume(struct soc_camera_device *icd); 676static int mt9m111_resume(struct soc_camera_device *icd);
645static int mt9m111_init(struct soc_camera_device *icd); 677static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state);
646static int mt9m111_release(struct soc_camera_device *icd);
647 678
648static struct soc_camera_ops mt9m111_ops = { 679static struct soc_camera_ops mt9m111_ops = {
649 .owner = THIS_MODULE, 680 .suspend = mt9m111_suspend,
650 .probe = mt9m111_video_probe,
651 .remove = mt9m111_video_remove,
652 .init = mt9m111_init,
653 .resume = mt9m111_resume, 681 .resume = mt9m111_resume,
654 .release = mt9m111_release,
655 .start_capture = mt9m111_start_capture,
656 .stop_capture = mt9m111_stop_capture,
657 .set_crop = mt9m111_set_crop,
658 .set_fmt = mt9m111_set_fmt,
659 .try_fmt = mt9m111_try_fmt,
660 .query_bus_param = mt9m111_query_bus_param, 682 .query_bus_param = mt9m111_query_bus_param,
661 .set_bus_param = mt9m111_set_bus_param, 683 .set_bus_param = mt9m111_set_bus_param,
662 .controls = mt9m111_controls, 684 .controls = mt9m111_controls,
663 .num_controls = ARRAY_SIZE(mt9m111_controls), 685 .num_controls = ARRAY_SIZE(mt9m111_controls),
664 .get_control = mt9m111_get_control,
665 .set_control = mt9m111_set_control,
666 .get_chip_id = mt9m111_get_chip_id,
667#ifdef CONFIG_VIDEO_ADV_DEBUG
668 .get_register = mt9m111_get_register,
669 .set_register = mt9m111_set_register,
670#endif
671}; 686};
672 687
673static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) 688static int mt9m111_set_flip(struct i2c_client *client, int flip, int mask)
674{ 689{
675 struct i2c_client *client = to_i2c_client(icd->control); 690 struct mt9m111 *mt9m111 = to_mt9m111(client);
676 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
677 int ret; 691 int ret;
678 692
679 if (mt9m111->context == HIGHPOWER) { 693 if (mt9m111->context == HIGHPOWER) {
@@ -691,9 +705,8 @@ static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask)
691 return ret; 705 return ret;
692} 706}
693 707
694static int mt9m111_get_global_gain(struct soc_camera_device *icd) 708static int mt9m111_get_global_gain(struct i2c_client *client)
695{ 709{
696 struct i2c_client *client = to_i2c_client(icd->control);
697 int data; 710 int data;
698 711
699 data = reg_read(GLOBAL_GAIN); 712 data = reg_read(GLOBAL_GAIN);
@@ -703,15 +716,15 @@ static int mt9m111_get_global_gain(struct soc_camera_device *icd)
703 return data; 716 return data;
704} 717}
705 718
706static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) 719static int mt9m111_set_global_gain(struct i2c_client *client, int gain)
707{ 720{
708 struct i2c_client *client = to_i2c_client(icd->control); 721 struct mt9m111 *mt9m111 = to_mt9m111(client);
709 u16 val; 722 u16 val;
710 723
711 if (gain > 63 * 2 * 2) 724 if (gain > 63 * 2 * 2)
712 return -EINVAL; 725 return -EINVAL;
713 726
714 icd->gain = gain; 727 mt9m111->gain = gain;
715 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) 728 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
716 val = (1 << 10) | (1 << 9) | (gain / 4); 729 val = (1 << 10) | (1 << 9) | (gain / 4);
717 else if ((gain >= 64) && (gain < 64 * 2)) 730 else if ((gain >= 64) && (gain < 64 * 2))
@@ -722,10 +735,9 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain)
722 return reg_write(GLOBAL_GAIN, val); 735 return reg_write(GLOBAL_GAIN, val);
723} 736}
724 737
725static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) 738static int mt9m111_set_autoexposure(struct i2c_client *client, int on)
726{ 739{
727 struct i2c_client *client = to_i2c_client(icd->control); 740 struct mt9m111 *mt9m111 = to_mt9m111(client);
728 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
729 int ret; 741 int ret;
730 742
731 if (on) 743 if (on)
@@ -739,10 +751,9 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on)
739 return ret; 751 return ret;
740} 752}
741 753
742static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on) 754static int mt9m111_set_autowhitebalance(struct i2c_client *client, int on)
743{ 755{
744 struct i2c_client *client = to_i2c_client(icd->control); 756 struct mt9m111 *mt9m111 = to_mt9m111(client);
745 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
746 int ret; 757 int ret;
747 758
748 if (on) 759 if (on)
@@ -756,11 +767,10 @@ static int mt9m111_set_autowhitebalance(struct soc_camera_device *icd, int on)
756 return ret; 767 return ret;
757} 768}
758 769
759static int mt9m111_get_control(struct soc_camera_device *icd, 770static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
760 struct v4l2_control *ctrl)
761{ 771{
762 struct i2c_client *client = to_i2c_client(icd->control); 772 struct i2c_client *client = sd->priv;
763 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 773 struct mt9m111 *mt9m111 = to_mt9m111(client);
764 int data; 774 int data;
765 775
766 switch (ctrl->id) { 776 switch (ctrl->id) {
@@ -785,7 +795,7 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
785 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); 795 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
786 break; 796 break;
787 case V4L2_CID_GAIN: 797 case V4L2_CID_GAIN:
788 data = mt9m111_get_global_gain(icd); 798 data = mt9m111_get_global_gain(client);
789 if (data < 0) 799 if (data < 0)
790 return data; 800 return data;
791 ctrl->value = data; 801 ctrl->value = data;
@@ -800,37 +810,36 @@ static int mt9m111_get_control(struct soc_camera_device *icd,
800 return 0; 810 return 0;
801} 811}
802 812
803static int mt9m111_set_control(struct soc_camera_device *icd, 813static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
804 struct v4l2_control *ctrl)
805{ 814{
806 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 815 struct i2c_client *client = sd->priv;
816 struct mt9m111 *mt9m111 = to_mt9m111(client);
807 const struct v4l2_queryctrl *qctrl; 817 const struct v4l2_queryctrl *qctrl;
808 int ret; 818 int ret;
809 819
810 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); 820 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
811
812 if (!qctrl) 821 if (!qctrl)
813 return -EINVAL; 822 return -EINVAL;
814 823
815 switch (ctrl->id) { 824 switch (ctrl->id) {
816 case V4L2_CID_VFLIP: 825 case V4L2_CID_VFLIP:
817 mt9m111->vflip = ctrl->value; 826 mt9m111->vflip = ctrl->value;
818 ret = mt9m111_set_flip(icd, ctrl->value, 827 ret = mt9m111_set_flip(client, ctrl->value,
819 MT9M111_RMB_MIRROR_ROWS); 828 MT9M111_RMB_MIRROR_ROWS);
820 break; 829 break;
821 case V4L2_CID_HFLIP: 830 case V4L2_CID_HFLIP:
822 mt9m111->hflip = ctrl->value; 831 mt9m111->hflip = ctrl->value;
823 ret = mt9m111_set_flip(icd, ctrl->value, 832 ret = mt9m111_set_flip(client, ctrl->value,
824 MT9M111_RMB_MIRROR_COLS); 833 MT9M111_RMB_MIRROR_COLS);
825 break; 834 break;
826 case V4L2_CID_GAIN: 835 case V4L2_CID_GAIN:
827 ret = mt9m111_set_global_gain(icd, ctrl->value); 836 ret = mt9m111_set_global_gain(client, ctrl->value);
828 break; 837 break;
829 case V4L2_CID_EXPOSURE_AUTO: 838 case V4L2_CID_EXPOSURE_AUTO:
830 ret = mt9m111_set_autoexposure(icd, ctrl->value); 839 ret = mt9m111_set_autoexposure(client, ctrl->value);
831 break; 840 break;
832 case V4L2_CID_AUTO_WHITE_BALANCE: 841 case V4L2_CID_AUTO_WHITE_BALANCE:
833 ret = mt9m111_set_autowhitebalance(icd, ctrl->value); 842 ret = mt9m111_set_autowhitebalance(client, ctrl->value);
834 break; 843 break;
835 default: 844 default:
836 ret = -EINVAL; 845 ret = -EINVAL;
@@ -839,62 +848,62 @@ static int mt9m111_set_control(struct soc_camera_device *icd,
839 return ret; 848 return ret;
840} 849}
841 850
842static int mt9m111_restore_state(struct soc_camera_device *icd) 851static int mt9m111_suspend(struct soc_camera_device *icd, pm_message_t state)
843{ 852{
844 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 853 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
845 854 struct mt9m111 *mt9m111 = to_mt9m111(client);
846 mt9m111_set_context(icd, mt9m111->context); 855
847 mt9m111_set_pixfmt(icd, mt9m111->pixfmt); 856 mt9m111->gain = mt9m111_get_global_gain(client);
848 mt9m111_setup_rect(icd, &mt9m111->rect); 857
849 mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 858 return 0;
850 mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); 859}
851 mt9m111_set_global_gain(icd, icd->gain); 860
852 mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 861static int mt9m111_restore_state(struct i2c_client *client)
853 mt9m111_set_autowhitebalance(icd, mt9m111->autowhitebalance); 862{
863 struct mt9m111 *mt9m111 = to_mt9m111(client);
864
865 mt9m111_set_context(client, mt9m111->context);
866 mt9m111_set_pixfmt(client, mt9m111->pixfmt);
867 mt9m111_setup_rect(client, &mt9m111->rect);
868 mt9m111_set_flip(client, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS);
869 mt9m111_set_flip(client, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
870 mt9m111_set_global_gain(client, mt9m111->gain);
871 mt9m111_set_autoexposure(client, mt9m111->autoexposure);
872 mt9m111_set_autowhitebalance(client, mt9m111->autowhitebalance);
854 return 0; 873 return 0;
855} 874}
856 875
857static int mt9m111_resume(struct soc_camera_device *icd) 876static int mt9m111_resume(struct soc_camera_device *icd)
858{ 877{
859 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 878 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
879 struct mt9m111 *mt9m111 = to_mt9m111(client);
860 int ret = 0; 880 int ret = 0;
861 881
862 if (mt9m111->powered) { 882 if (mt9m111->powered) {
863 ret = mt9m111_enable(icd); 883 ret = mt9m111_enable(client);
864 if (!ret) 884 if (!ret)
865 ret = mt9m111_reset(icd); 885 ret = mt9m111_reset(client);
866 if (!ret) 886 if (!ret)
867 ret = mt9m111_restore_state(icd); 887 ret = mt9m111_restore_state(client);
868 } 888 }
869 return ret; 889 return ret;
870} 890}
871 891
872static int mt9m111_init(struct soc_camera_device *icd) 892static int mt9m111_init(struct i2c_client *client)
873{ 893{
874 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 894 struct mt9m111 *mt9m111 = to_mt9m111(client);
875 int ret; 895 int ret;
876 896
877 mt9m111->context = HIGHPOWER; 897 mt9m111->context = HIGHPOWER;
878 ret = mt9m111_enable(icd); 898 ret = mt9m111_enable(client);
879 if (!ret) 899 if (!ret)
880 ret = mt9m111_reset(icd); 900 ret = mt9m111_reset(client);
881 if (!ret) 901 if (!ret)
882 ret = mt9m111_set_context(icd, mt9m111->context); 902 ret = mt9m111_set_context(client, mt9m111->context);
883 if (!ret) 903 if (!ret)
884 ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); 904 ret = mt9m111_set_autoexposure(client, mt9m111->autoexposure);
885 if (ret) 905 if (ret)
886 dev_err(&icd->dev, "mt9m11x init failed: %d\n", ret); 906 dev_err(&client->dev, "mt9m11x init failed: %d\n", ret);
887 return ret;
888}
889
890static int mt9m111_release(struct soc_camera_device *icd)
891{
892 int ret;
893
894 ret = mt9m111_disable(icd);
895 if (ret < 0)
896 dev_err(&icd->dev, "mt9m11x release failed: %d\n", ret);
897
898 return ret; 907 return ret;
899} 908}
900 909
@@ -902,10 +911,10 @@ static int mt9m111_release(struct soc_camera_device *icd)
902 * Interface active, can use i2c. If it fails, it can indeed mean, that 911 * Interface active, can use i2c. If it fails, it can indeed mean, that
903 * this wasn't our capture interface, so, we wait for the right one 912 * this wasn't our capture interface, so, we wait for the right one
904 */ 913 */
905static int mt9m111_video_probe(struct soc_camera_device *icd) 914static int mt9m111_video_probe(struct soc_camera_device *icd,
915 struct i2c_client *client)
906{ 916{
907 struct i2c_client *client = to_i2c_client(icd->control); 917 struct mt9m111 *mt9m111 = to_mt9m111(client);
908 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd);
909 s32 data; 918 s32 data;
910 int ret; 919 int ret;
911 920
@@ -917,10 +926,13 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
917 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) 926 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
918 return -ENODEV; 927 return -ENODEV;
919 928
920 ret = mt9m111_enable(icd); 929 mt9m111->autoexposure = 1;
921 if (ret) 930 mt9m111->autowhitebalance = 1;
922 goto ei2c; 931
923 ret = mt9m111_reset(icd); 932 mt9m111->swap_rgb_even_odd = 1;
933 mt9m111->swap_rgb_red_blue = 1;
934
935 ret = mt9m111_init(client);
924 if (ret) 936 if (ret)
925 goto ei2c; 937 goto ei2c;
926 938
@@ -935,7 +947,7 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
935 break; 947 break;
936 default: 948 default:
937 ret = -ENODEV; 949 ret = -ENODEV;
938 dev_err(&icd->dev, 950 dev_err(&client->dev,
939 "No MT9M11x chip detected, register read %x\n", data); 951 "No MT9M11x chip detected, register read %x\n", data);
940 goto ei2c; 952 goto ei2c;
941 } 953 }
@@ -943,42 +955,51 @@ static int mt9m111_video_probe(struct soc_camera_device *icd)
943 icd->formats = mt9m111_colour_formats; 955 icd->formats = mt9m111_colour_formats;
944 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); 956 icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats);
945 957
946 dev_info(&icd->dev, "Detected a MT9M11x chip ID %x\n", data); 958 dev_info(&client->dev, "Detected a MT9M11x chip ID %x\n", data);
947 959
948 ret = soc_camera_video_start(icd);
949 if (ret)
950 goto eisis;
951
952 mt9m111->autoexposure = 1;
953 mt9m111->autowhitebalance = 1;
954
955 mt9m111->swap_rgb_even_odd = 1;
956 mt9m111->swap_rgb_red_blue = 1;
957
958 return 0;
959eisis:
960ei2c: 960ei2c:
961 return ret; 961 return ret;
962} 962}
963 963
964static void mt9m111_video_remove(struct soc_camera_device *icd) 964static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
965{ 965 .g_ctrl = mt9m111_g_ctrl,
966 struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); 966 .s_ctrl = mt9m111_s_ctrl,
967 .g_chip_ident = mt9m111_g_chip_ident,
968#ifdef CONFIG_VIDEO_ADV_DEBUG
969 .g_register = mt9m111_g_register,
970 .s_register = mt9m111_s_register,
971#endif
972};
967 973
968 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, 974static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
969 mt9m111->icd.dev.parent, mt9m111->icd.vdev); 975 .s_fmt = mt9m111_s_fmt,
970 soc_camera_video_stop(&mt9m111->icd); 976 .g_fmt = mt9m111_g_fmt,
971} 977 .try_fmt = mt9m111_try_fmt,
978 .s_crop = mt9m111_s_crop,
979 .g_crop = mt9m111_g_crop,
980 .cropcap = mt9m111_cropcap,
981};
982
983static struct v4l2_subdev_ops mt9m111_subdev_ops = {
984 .core = &mt9m111_subdev_core_ops,
985 .video = &mt9m111_subdev_video_ops,
986};
972 987
973static int mt9m111_probe(struct i2c_client *client, 988static int mt9m111_probe(struct i2c_client *client,
974 const struct i2c_device_id *did) 989 const struct i2c_device_id *did)
975{ 990{
976 struct mt9m111 *mt9m111; 991 struct mt9m111 *mt9m111;
977 struct soc_camera_device *icd; 992 struct soc_camera_device *icd = client->dev.platform_data;
978 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 993 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
979 struct soc_camera_link *icl = client->dev.platform_data; 994 struct soc_camera_link *icl;
980 int ret; 995 int ret;
981 996
997 if (!icd) {
998 dev_err(&client->dev, "MT9M11x: missing soc-camera data!\n");
999 return -EINVAL;
1000 }
1001
1002 icl = to_soc_camera_link(icd);
982 if (!icl) { 1003 if (!icl) {
983 dev_err(&client->dev, "MT9M11x driver needs platform data\n"); 1004 dev_err(&client->dev, "MT9M11x driver needs platform data\n");
984 return -EINVAL; 1005 return -EINVAL;
@@ -994,38 +1015,35 @@ static int mt9m111_probe(struct i2c_client *client,
994 if (!mt9m111) 1015 if (!mt9m111)
995 return -ENOMEM; 1016 return -ENOMEM;
996 1017
997 mt9m111->client = client; 1018 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
998 i2c_set_clientdata(client, mt9m111);
999 1019
1000 /* Second stage probe - when a capture adapter is there */ 1020 /* Second stage probe - when a capture adapter is there */
1001 icd = &mt9m111->icd; 1021 icd->ops = &mt9m111_ops;
1002 icd->ops = &mt9m111_ops; 1022 icd->y_skip_top = 0;
1003 icd->control = &client->dev; 1023
1004 icd->x_min = MT9M111_MIN_DARK_COLS; 1024 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1005 icd->y_min = MT9M111_MIN_DARK_ROWS; 1025 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
1006 icd->x_current = icd->x_min; 1026 mt9m111->rect.width = MT9M111_MAX_WIDTH;
1007 icd->y_current = icd->y_min; 1027 mt9m111->rect.height = MT9M111_MAX_HEIGHT;
1008 icd->width_min = MT9M111_MIN_DARK_ROWS; 1028
1009 icd->width_max = MT9M111_MAX_WIDTH; 1029 ret = mt9m111_video_probe(icd, client);
1010 icd->height_min = MT9M111_MIN_DARK_COLS; 1030 if (ret) {
1011 icd->height_max = MT9M111_MAX_HEIGHT; 1031 icd->ops = NULL;
1012 icd->y_skip_top = 0; 1032 i2c_set_clientdata(client, NULL);
1013 icd->iface = icl->bus_id; 1033 kfree(mt9m111);
1014 1034 }
1015 ret = soc_camera_device_register(icd);
1016 if (ret)
1017 goto eisdr;
1018 return 0;
1019 1035
1020eisdr:
1021 kfree(mt9m111);
1022 return ret; 1036 return ret;
1023} 1037}
1024 1038
1025static int mt9m111_remove(struct i2c_client *client) 1039static int mt9m111_remove(struct i2c_client *client)
1026{ 1040{
1027 struct mt9m111 *mt9m111 = i2c_get_clientdata(client); 1041 struct mt9m111 *mt9m111 = to_mt9m111(client);
1028 soc_camera_device_unregister(&mt9m111->icd); 1042 struct soc_camera_device *icd = client->dev.platform_data;
1043
1044 icd->ops = NULL;
1045 i2c_set_clientdata(client, NULL);
1046 client->driver = NULL;
1029 kfree(mt9m111); 1047 kfree(mt9m111);
1030 1048
1031 return 0; 1049 return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 4207fb342670..6966f644977e 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -13,13 +13,13 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/v4l2-common.h> 16#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 18#include <media/soc_camera.h>
19 19
20/* mt9t031 i2c address 0x5d 20/* mt9t031 i2c address 0x5d
21 * The platform has to define i2c_board_info 21 * The platform has to define i2c_board_info and link to it from
22 * and call i2c_register_board_info() */ 22 * struct soc_camera_link */
23 23
24/* mt9t031 selected register addresses */ 24/* mt9t031 selected register addresses */
25#define MT9T031_CHIP_VERSION 0x00 25#define MT9T031_CHIP_VERSION 0x00
@@ -47,7 +47,7 @@
47#define MT9T031_MAX_HEIGHT 1536 47#define MT9T031_MAX_HEIGHT 1536
48#define MT9T031_MAX_WIDTH 2048 48#define MT9T031_MAX_WIDTH 2048
49#define MT9T031_MIN_HEIGHT 2 49#define MT9T031_MIN_HEIGHT 2
50#define MT9T031_MIN_WIDTH 2 50#define MT9T031_MIN_WIDTH 18
51#define MT9T031_HORIZONTAL_BLANK 142 51#define MT9T031_HORIZONTAL_BLANK 142
52#define MT9T031_VERTICAL_BLANK 25 52#define MT9T031_VERTICAL_BLANK 25
53#define MT9T031_COLUMN_SKIP 32 53#define MT9T031_COLUMN_SKIP 32
@@ -68,14 +68,21 @@ static const struct soc_camera_data_format mt9t031_colour_formats[] = {
68}; 68};
69 69
70struct mt9t031 { 70struct mt9t031 {
71 struct i2c_client *client; 71 struct v4l2_subdev subdev;
72 struct soc_camera_device icd; 72 struct v4l2_rect rect; /* Sensor window */
73 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ 73 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
74 unsigned char autoexposure;
75 u16 xskip; 74 u16 xskip;
76 u16 yskip; 75 u16 yskip;
76 unsigned int gain;
77 unsigned int exposure;
78 unsigned char autoexposure;
77}; 79};
78 80
81static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
82{
83 return container_of(i2c_get_clientdata(client), struct mt9t031, subdev);
84}
85
79static int reg_read(struct i2c_client *client, const u8 reg) 86static int reg_read(struct i2c_client *client, const u8 reg)
80{ 87{
81 s32 data = i2c_smbus_read_word_data(client, reg); 88 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -136,21 +143,10 @@ static int get_shutter(struct i2c_client *client, u32 *data)
136 return ret < 0 ? ret : 0; 143 return ret < 0 ? ret : 0;
137} 144}
138 145
139static int mt9t031_init(struct soc_camera_device *icd) 146static int mt9t031_idle(struct i2c_client *client)
140{ 147{
141 struct i2c_client *client = to_i2c_client(icd->control);
142 struct soc_camera_link *icl = client->dev.platform_data;
143 int ret; 148 int ret;
144 149
145 if (icl->power) {
146 ret = icl->power(&client->dev, 1);
147 if (ret < 0) {
148 dev_err(icd->vdev->parent,
149 "Platform failed to power-on the camera.\n");
150 return ret;
151 }
152 }
153
154 /* Disable chip output, synchronous option update */ 150 /* Disable chip output, synchronous option update */
155 ret = reg_write(client, MT9T031_RESET, 1); 151 ret = reg_write(client, MT9T031_RESET, 1);
156 if (ret >= 0) 152 if (ret >= 0)
@@ -158,50 +154,39 @@ static int mt9t031_init(struct soc_camera_device *icd)
158 if (ret >= 0) 154 if (ret >= 0)
159 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); 155 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
160 156
161 if (ret < 0 && icl->power)
162 icl->power(&client->dev, 0);
163
164 return ret >= 0 ? 0 : -EIO; 157 return ret >= 0 ? 0 : -EIO;
165} 158}
166 159
167static int mt9t031_release(struct soc_camera_device *icd) 160static int mt9t031_disable(struct i2c_client *client)
168{ 161{
169 struct i2c_client *client = to_i2c_client(icd->control);
170 struct soc_camera_link *icl = client->dev.platform_data;
171
172 /* Disable the chip */ 162 /* Disable the chip */
173 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2); 163 reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
174 164
175 if (icl->power)
176 icl->power(&client->dev, 0);
177
178 return 0; 165 return 0;
179} 166}
180 167
181static int mt9t031_start_capture(struct soc_camera_device *icd) 168static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
182{ 169{
183 struct i2c_client *client = to_i2c_client(icd->control); 170 struct i2c_client *client = sd->priv;
184 171 int ret;
185 /* Switch to master "normal" mode */
186 if (reg_set(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
187 return -EIO;
188 return 0;
189}
190 172
191static int mt9t031_stop_capture(struct soc_camera_device *icd) 173 if (enable)
192{ 174 /* Switch to master "normal" mode */
193 struct i2c_client *client = to_i2c_client(icd->control); 175 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 2);
176 else
177 /* Stop sensor readout */
178 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 2);
194 179
195 /* Stop sensor readout */ 180 if (ret < 0)
196 if (reg_clear(client, MT9T031_OUTPUT_CONTROL, 2) < 0)
197 return -EIO; 181 return -EIO;
182
198 return 0; 183 return 0;
199} 184}
200 185
201static int mt9t031_set_bus_param(struct soc_camera_device *icd, 186static int mt9t031_set_bus_param(struct soc_camera_device *icd,
202 unsigned long flags) 187 unsigned long flags)
203{ 188{
204 struct i2c_client *client = to_i2c_client(icd->control); 189 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
205 190
206 /* The caller should have queried our parameters, check anyway */ 191 /* The caller should have queried our parameters, check anyway */
207 if (flags & ~MT9T031_BUS_PARAM) 192 if (flags & ~MT9T031_BUS_PARAM)
@@ -217,69 +202,73 @@ static int mt9t031_set_bus_param(struct soc_camera_device *icd,
217 202
218static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd) 203static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
219{ 204{
220 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 205 struct soc_camera_link *icl = to_soc_camera_link(icd);
221 struct soc_camera_link *icl = mt9t031->client->dev.platform_data;
222 206
223 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM); 207 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
224} 208}
225 209
226/* Round up minima and round down maxima */ 210/* target must be _even_ */
227static void recalculate_limits(struct soc_camera_device *icd, 211static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
228 u16 xskip, u16 yskip)
229{ 212{
230 icd->x_min = (MT9T031_COLUMN_SKIP + xskip - 1) / xskip; 213 unsigned int skip;
231 icd->y_min = (MT9T031_ROW_SKIP + yskip - 1) / yskip; 214
232 icd->width_min = (MT9T031_MIN_WIDTH + xskip - 1) / xskip; 215 if (*source < target + target / 2) {
233 icd->height_min = (MT9T031_MIN_HEIGHT + yskip - 1) / yskip; 216 *source = target;
234 icd->width_max = MT9T031_MAX_WIDTH / xskip; 217 return 1;
235 icd->height_max = MT9T031_MAX_HEIGHT / yskip; 218 }
219
220 skip = min(max, *source + target / 2) / target;
221 if (skip > 8)
222 skip = 8;
223 *source = target * skip;
224
225 return skip;
236} 226}
237 227
228/* rect is the sensor rectangle, the caller guarantees parameter validity */
238static int mt9t031_set_params(struct soc_camera_device *icd, 229static int mt9t031_set_params(struct soc_camera_device *icd,
239 struct v4l2_rect *rect, u16 xskip, u16 yskip) 230 struct v4l2_rect *rect, u16 xskip, u16 yskip)
240{ 231{
241 struct i2c_client *client = to_i2c_client(icd->control); 232 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
242 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 233 struct mt9t031 *mt9t031 = to_mt9t031(client);
243 int ret; 234 int ret;
244 u16 xbin, ybin, width, height, left, top; 235 u16 xbin, ybin;
245 const u16 hblank = MT9T031_HORIZONTAL_BLANK, 236 const u16 hblank = MT9T031_HORIZONTAL_BLANK,
246 vblank = MT9T031_VERTICAL_BLANK; 237 vblank = MT9T031_VERTICAL_BLANK;
247 238
248 /* Make sure we don't exceed sensor limits */
249 if (rect->left + rect->width > icd->width_max)
250 rect->left = (icd->width_max - rect->width) / 2 + icd->x_min;
251
252 if (rect->top + rect->height > icd->height_max)
253 rect->top = (icd->height_max - rect->height) / 2 + icd->y_min;
254
255 width = rect->width * xskip;
256 height = rect->height * yskip;
257 left = rect->left * xskip;
258 top = rect->top * yskip;
259
260 xbin = min(xskip, (u16)3); 239 xbin = min(xskip, (u16)3);
261 ybin = min(yskip, (u16)3); 240 ybin = min(yskip, (u16)3);
262 241
263 dev_dbg(&icd->dev, "xskip %u, width %u/%u, yskip %u, height %u/%u\n", 242 /*
264 xskip, width, rect->width, yskip, height, rect->height); 243 * Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper.
265 244 * There is always a valid suitably aligned value. The worst case is
266 /* Could just do roundup(rect->left, [xy]bin * 2); but this is cheaper */ 245 * xbin = 3, width = 2048. Then we will start at 36, the last read out
246 * pixel will be 2083, which is < 2085 - first black pixel.
247 *
248 * MT9T031 datasheet imposes window left border alignment, depending on
249 * the selected xskip. Failing to conform to this requirement produces
250 * dark horizontal stripes in the image. However, even obeying to this
251 * requirement doesn't eliminate the stripes in all configurations. They
252 * appear "locally reproducibly," but can differ between tests under
253 * different lighting conditions.
254 */
267 switch (xbin) { 255 switch (xbin) {
268 case 2: 256 case 1:
269 left = (left + 3) & ~3; 257 rect->left &= ~1;
270 break; 258 break;
271 case 3:
272 left = roundup(left, 6);
273 }
274
275 switch (ybin) {
276 case 2: 259 case 2:
277 top = (top + 3) & ~3; 260 rect->left &= ~3;
278 break; 261 break;
279 case 3: 262 case 3:
280 top = roundup(top, 6); 263 rect->left = rect->left > roundup(MT9T031_COLUMN_SKIP, 6) ?
264 (rect->left / 6) * 6 : roundup(MT9T031_COLUMN_SKIP, 6);
281 } 265 }
282 266
267 rect->top &= ~1;
268
269 dev_dbg(&client->dev, "skip %u:%u, rect %ux%u@%u:%u\n",
270 xskip, yskip, rect->width, rect->height, rect->left, rect->top);
271
283 /* Disable register update, reconfigure atomically */ 272 /* Disable register update, reconfigure atomically */
284 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1); 273 ret = reg_set(client, MT9T031_OUTPUT_CONTROL, 1);
285 if (ret < 0) 274 if (ret < 0)
@@ -299,29 +288,30 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
299 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE, 288 ret = reg_write(client, MT9T031_ROW_ADDRESS_MODE,
300 ((ybin - 1) << 4) | (yskip - 1)); 289 ((ybin - 1) << 4) | (yskip - 1));
301 } 290 }
302 dev_dbg(&icd->dev, "new physical left %u, top %u\n", left, top); 291 dev_dbg(&client->dev, "new physical left %u, top %u\n",
292 rect->left, rect->top);
303 293
304 /* The caller provides a supported format, as guaranteed by 294 /* The caller provides a supported format, as guaranteed by
305 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */ 295 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() */
306 if (ret >= 0) 296 if (ret >= 0)
307 ret = reg_write(client, MT9T031_COLUMN_START, left); 297 ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
308 if (ret >= 0) 298 if (ret >= 0)
309 ret = reg_write(client, MT9T031_ROW_START, top); 299 ret = reg_write(client, MT9T031_ROW_START, rect->top);
310 if (ret >= 0) 300 if (ret >= 0)
311 ret = reg_write(client, MT9T031_WINDOW_WIDTH, width - 1); 301 ret = reg_write(client, MT9T031_WINDOW_WIDTH, rect->width - 1);
312 if (ret >= 0) 302 if (ret >= 0)
313 ret = reg_write(client, MT9T031_WINDOW_HEIGHT, 303 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
314 height + icd->y_skip_top - 1); 304 rect->height + icd->y_skip_top - 1);
315 if (ret >= 0 && mt9t031->autoexposure) { 305 if (ret >= 0 && mt9t031->autoexposure) {
316 ret = set_shutter(client, height + icd->y_skip_top + vblank); 306 unsigned int total_h = rect->height + icd->y_skip_top + vblank;
307 ret = set_shutter(client, total_h);
317 if (ret >= 0) { 308 if (ret >= 0) {
318 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 309 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
319 const struct v4l2_queryctrl *qctrl = 310 const struct v4l2_queryctrl *qctrl =
320 soc_camera_find_qctrl(icd->ops, 311 soc_camera_find_qctrl(icd->ops,
321 V4L2_CID_EXPOSURE); 312 V4L2_CID_EXPOSURE);
322 icd->exposure = (shutter_max / 2 + (height + 313 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
323 icd->y_skip_top + vblank - 1) * 314 (qctrl->maximum - qctrl->minimum)) /
324 (qctrl->maximum - qctrl->minimum)) /
325 shutter_max + qctrl->minimum; 315 shutter_max + qctrl->minimum;
326 } 316 }
327 } 317 }
@@ -330,58 +320,99 @@ static int mt9t031_set_params(struct soc_camera_device *icd,
330 if (ret >= 0) 320 if (ret >= 0)
331 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1); 321 ret = reg_clear(client, MT9T031_OUTPUT_CONTROL, 1);
332 322
323 if (ret >= 0) {
324 mt9t031->rect = *rect;
325 mt9t031->xskip = xskip;
326 mt9t031->yskip = yskip;
327 }
328
333 return ret < 0 ? ret : 0; 329 return ret < 0 ? ret : 0;
334} 330}
335 331
336static int mt9t031_set_crop(struct soc_camera_device *icd, 332static int mt9t031_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
337 struct v4l2_rect *rect)
338{ 333{
339 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 334 struct v4l2_rect rect = a->c;
335 struct i2c_client *client = sd->priv;
336 struct mt9t031 *mt9t031 = to_mt9t031(client);
337 struct soc_camera_device *icd = client->dev.platform_data;
338
339 rect.width = ALIGN(rect.width, 2);
340 rect.height = ALIGN(rect.height, 2);
341
342 soc_camera_limit_side(&rect.left, &rect.width,
343 MT9T031_COLUMN_SKIP, MT9T031_MIN_WIDTH, MT9T031_MAX_WIDTH);
344
345 soc_camera_limit_side(&rect.top, &rect.height,
346 MT9T031_ROW_SKIP, MT9T031_MIN_HEIGHT, MT9T031_MAX_HEIGHT);
340 347
341 /* CROP - no change in scaling, or in limits */ 348 return mt9t031_set_params(icd, &rect, mt9t031->xskip, mt9t031->yskip);
342 return mt9t031_set_params(icd, rect, mt9t031->xskip, mt9t031->yskip);
343} 349}
344 350
345static int mt9t031_set_fmt(struct soc_camera_device *icd, 351static int mt9t031_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
346 struct v4l2_format *f)
347{ 352{
348 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 353 struct i2c_client *client = sd->priv;
349 int ret; 354 struct mt9t031 *mt9t031 = to_mt9t031(client);
350 u16 xskip, yskip;
351 struct v4l2_rect rect = {
352 .left = icd->x_current,
353 .top = icd->y_current,
354 .width = f->fmt.pix.width,
355 .height = f->fmt.pix.height,
356 };
357 355
358 /* 356 a->c = mt9t031->rect;
359 * try_fmt has put rectangle within limits. 357 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
360 * S_FMT - use binning and skipping for scaling, recalculate
361 * limits, used for cropping
362 */
363 /* Is this more optimal than just a division? */
364 for (xskip = 8; xskip > 1; xskip--)
365 if (rect.width * xskip <= MT9T031_MAX_WIDTH)
366 break;
367 358
368 for (yskip = 8; yskip > 1; yskip--) 359 return 0;
369 if (rect.height * yskip <= MT9T031_MAX_HEIGHT) 360}
370 break;
371 361
372 recalculate_limits(icd, xskip, yskip); 362static int mt9t031_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
363{
364 a->bounds.left = MT9T031_COLUMN_SKIP;
365 a->bounds.top = MT9T031_ROW_SKIP;
366 a->bounds.width = MT9T031_MAX_WIDTH;
367 a->bounds.height = MT9T031_MAX_HEIGHT;
368 a->defrect = a->bounds;
369 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
370 a->pixelaspect.numerator = 1;
371 a->pixelaspect.denominator = 1;
373 372
374 ret = mt9t031_set_params(icd, &rect, xskip, yskip); 373 return 0;
375 if (!ret) { 374}
376 mt9t031->xskip = xskip;
377 mt9t031->yskip = yskip;
378 }
379 375
380 return ret; 376static int mt9t031_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
377{
378 struct i2c_client *client = sd->priv;
379 struct mt9t031 *mt9t031 = to_mt9t031(client);
380 struct v4l2_pix_format *pix = &f->fmt.pix;
381
382 pix->width = mt9t031->rect.width / mt9t031->xskip;
383 pix->height = mt9t031->rect.height / mt9t031->yskip;
384 pix->pixelformat = V4L2_PIX_FMT_SGRBG10;
385 pix->field = V4L2_FIELD_NONE;
386 pix->colorspace = V4L2_COLORSPACE_SRGB;
387
388 return 0;
389}
390
391static int mt9t031_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
392{
393 struct i2c_client *client = sd->priv;
394 struct mt9t031 *mt9t031 = to_mt9t031(client);
395 struct soc_camera_device *icd = client->dev.platform_data;
396 struct v4l2_pix_format *pix = &f->fmt.pix;
397 u16 xskip, yskip;
398 struct v4l2_rect rect = mt9t031->rect;
399
400 /*
401 * try_fmt has put width and height within limits.
402 * S_FMT: use binning and skipping for scaling
403 */
404 xskip = mt9t031_skip(&rect.width, pix->width, MT9T031_MAX_WIDTH);
405 yskip = mt9t031_skip(&rect.height, pix->height, MT9T031_MAX_HEIGHT);
406
407 /* mt9t031_set_params() doesn't change width and height */
408 return mt9t031_set_params(icd, &rect, xskip, yskip);
381} 409}
382 410
383static int mt9t031_try_fmt(struct soc_camera_device *icd, 411/*
384 struct v4l2_format *f) 412 * If a user window larger than sensor window is requested, we'll increase the
413 * sensor window.
414 */
415static int mt9t031_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
385{ 416{
386 struct v4l2_pix_format *pix = &f->fmt.pix; 417 struct v4l2_pix_format *pix = &f->fmt.pix;
387 418
@@ -392,15 +423,16 @@ static int mt9t031_try_fmt(struct soc_camera_device *icd,
392 return 0; 423 return 0;
393} 424}
394 425
395static int mt9t031_get_chip_id(struct soc_camera_device *icd, 426static int mt9t031_g_chip_ident(struct v4l2_subdev *sd,
396 struct v4l2_dbg_chip_ident *id) 427 struct v4l2_dbg_chip_ident *id)
397{ 428{
398 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 429 struct i2c_client *client = sd->priv;
430 struct mt9t031 *mt9t031 = to_mt9t031(client);
399 431
400 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 432 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
401 return -EINVAL; 433 return -EINVAL;
402 434
403 if (id->match.addr != mt9t031->client->addr) 435 if (id->match.addr != client->addr)
404 return -ENODEV; 436 return -ENODEV;
405 437
406 id->ident = mt9t031->model; 438 id->ident = mt9t031->model;
@@ -410,10 +442,10 @@ static int mt9t031_get_chip_id(struct soc_camera_device *icd,
410} 442}
411 443
412#ifdef CONFIG_VIDEO_ADV_DEBUG 444#ifdef CONFIG_VIDEO_ADV_DEBUG
413static int mt9t031_get_register(struct soc_camera_device *icd, 445static int mt9t031_g_register(struct v4l2_subdev *sd,
414 struct v4l2_dbg_register *reg) 446 struct v4l2_dbg_register *reg)
415{ 447{
416 struct i2c_client *client = to_i2c_client(icd->control); 448 struct i2c_client *client = sd->priv;
417 449
418 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 450 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
419 return -EINVAL; 451 return -EINVAL;
@@ -429,10 +461,10 @@ static int mt9t031_get_register(struct soc_camera_device *icd,
429 return 0; 461 return 0;
430} 462}
431 463
432static int mt9t031_set_register(struct soc_camera_device *icd, 464static int mt9t031_s_register(struct v4l2_subdev *sd,
433 struct v4l2_dbg_register *reg) 465 struct v4l2_dbg_register *reg)
434{ 466{
435 struct i2c_client *client = to_i2c_client(icd->control); 467 struct i2c_client *client = sd->priv;
436 468
437 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 469 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
438 return -EINVAL; 470 return -EINVAL;
@@ -493,39 +525,17 @@ static const struct v4l2_queryctrl mt9t031_controls[] = {
493 } 525 }
494}; 526};
495 527
496static int mt9t031_video_probe(struct soc_camera_device *);
497static void mt9t031_video_remove(struct soc_camera_device *);
498static int mt9t031_get_control(struct soc_camera_device *, struct v4l2_control *);
499static int mt9t031_set_control(struct soc_camera_device *, struct v4l2_control *);
500
501static struct soc_camera_ops mt9t031_ops = { 528static struct soc_camera_ops mt9t031_ops = {
502 .owner = THIS_MODULE,
503 .probe = mt9t031_video_probe,
504 .remove = mt9t031_video_remove,
505 .init = mt9t031_init,
506 .release = mt9t031_release,
507 .start_capture = mt9t031_start_capture,
508 .stop_capture = mt9t031_stop_capture,
509 .set_crop = mt9t031_set_crop,
510 .set_fmt = mt9t031_set_fmt,
511 .try_fmt = mt9t031_try_fmt,
512 .set_bus_param = mt9t031_set_bus_param, 529 .set_bus_param = mt9t031_set_bus_param,
513 .query_bus_param = mt9t031_query_bus_param, 530 .query_bus_param = mt9t031_query_bus_param,
514 .controls = mt9t031_controls, 531 .controls = mt9t031_controls,
515 .num_controls = ARRAY_SIZE(mt9t031_controls), 532 .num_controls = ARRAY_SIZE(mt9t031_controls),
516 .get_control = mt9t031_get_control,
517 .set_control = mt9t031_set_control,
518 .get_chip_id = mt9t031_get_chip_id,
519#ifdef CONFIG_VIDEO_ADV_DEBUG
520 .get_register = mt9t031_get_register,
521 .set_register = mt9t031_set_register,
522#endif
523}; 533};
524 534
525static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 535static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
526{ 536{
527 struct i2c_client *client = to_i2c_client(icd->control); 537 struct i2c_client *client = sd->priv;
528 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 538 struct mt9t031 *mt9t031 = to_mt9t031(client);
529 int data; 539 int data;
530 540
531 switch (ctrl->id) { 541 switch (ctrl->id) {
@@ -544,14 +554,21 @@ static int mt9t031_get_control(struct soc_camera_device *icd, struct v4l2_contro
544 case V4L2_CID_EXPOSURE_AUTO: 554 case V4L2_CID_EXPOSURE_AUTO:
545 ctrl->value = mt9t031->autoexposure; 555 ctrl->value = mt9t031->autoexposure;
546 break; 556 break;
557 case V4L2_CID_GAIN:
558 ctrl->value = mt9t031->gain;
559 break;
560 case V4L2_CID_EXPOSURE:
561 ctrl->value = mt9t031->exposure;
562 break;
547 } 563 }
548 return 0; 564 return 0;
549} 565}
550 566
551static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_control *ctrl) 567static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
552{ 568{
553 struct i2c_client *client = to_i2c_client(icd->control); 569 struct i2c_client *client = sd->priv;
554 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 570 struct mt9t031 *mt9t031 = to_mt9t031(client);
571 struct soc_camera_device *icd = client->dev.platform_data;
555 const struct v4l2_queryctrl *qctrl; 572 const struct v4l2_queryctrl *qctrl;
556 int data; 573 int data;
557 574
@@ -586,7 +603,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
586 unsigned long range = qctrl->default_value - qctrl->minimum; 603 unsigned long range = qctrl->default_value - qctrl->minimum;
587 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 604 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range;
588 605
589 dev_dbg(&icd->dev, "Setting gain %d\n", data); 606 dev_dbg(&client->dev, "Setting gain %d\n", data);
590 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 607 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
591 if (data < 0) 608 if (data < 0)
592 return -EIO; 609 return -EIO;
@@ -606,7 +623,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
606 /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */ 623 /* calculated gain 65..1024 -> (1..120) << 8 + 0x60 */
607 data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60; 624 data = (((gain - 64 + 7) * 32) & 0xff00) | 0x60;
608 625
609 dev_dbg(&icd->dev, "Setting gain from 0x%x to 0x%x\n", 626 dev_dbg(&client->dev, "Set gain from 0x%x to 0x%x\n",
610 reg_read(client, MT9T031_GLOBAL_GAIN), data); 627 reg_read(client, MT9T031_GLOBAL_GAIN), data);
611 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 628 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
612 if (data < 0) 629 if (data < 0)
@@ -614,7 +631,7 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
614 } 631 }
615 632
616 /* Success */ 633 /* Success */
617 icd->gain = ctrl->value; 634 mt9t031->gain = ctrl->value;
618 break; 635 break;
619 case V4L2_CID_EXPOSURE: 636 case V4L2_CID_EXPOSURE:
620 /* mt9t031 has maximum == default */ 637 /* mt9t031 has maximum == default */
@@ -627,11 +644,11 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
627 u32 old; 644 u32 old;
628 645
629 get_shutter(client, &old); 646 get_shutter(client, &old);
630 dev_dbg(&icd->dev, "Setting shutter width from %u to %u\n", 647 dev_dbg(&client->dev, "Set shutter from %u to %u\n",
631 old, shutter); 648 old, shutter);
632 if (set_shutter(client, shutter) < 0) 649 if (set_shutter(client, shutter) < 0)
633 return -EIO; 650 return -EIO;
634 icd->exposure = ctrl->value; 651 mt9t031->exposure = ctrl->value;
635 mt9t031->autoexposure = 0; 652 mt9t031->autoexposure = 0;
636 } 653 }
637 break; 654 break;
@@ -639,13 +656,14 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
639 if (ctrl->value) { 656 if (ctrl->value) {
640 const u16 vblank = MT9T031_VERTICAL_BLANK; 657 const u16 vblank = MT9T031_VERTICAL_BLANK;
641 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 658 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
642 if (set_shutter(client, icd->height + 659 unsigned int total_h = mt9t031->rect.height +
643 icd->y_skip_top + vblank) < 0) 660 icd->y_skip_top + vblank;
661
662 if (set_shutter(client, total_h) < 0)
644 return -EIO; 663 return -EIO;
645 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 664 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
646 icd->exposure = (shutter_max / 2 + (icd->height + 665 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
647 icd->y_skip_top + vblank - 1) * 666 (qctrl->maximum - qctrl->minimum)) /
648 (qctrl->maximum - qctrl->minimum)) /
649 shutter_max + qctrl->minimum; 667 shutter_max + qctrl->minimum;
650 mt9t031->autoexposure = 1; 668 mt9t031->autoexposure = 1;
651 } else 669 } else
@@ -657,22 +675,16 @@ static int mt9t031_set_control(struct soc_camera_device *icd, struct v4l2_contro
657 675
658/* Interface active, can use i2c. If it fails, it can indeed mean, that 676/* Interface active, can use i2c. If it fails, it can indeed mean, that
659 * this wasn't our capture interface, so, we wait for the right one */ 677 * this wasn't our capture interface, so, we wait for the right one */
660static int mt9t031_video_probe(struct soc_camera_device *icd) 678static int mt9t031_video_probe(struct i2c_client *client)
661{ 679{
662 struct i2c_client *client = to_i2c_client(icd->control); 680 struct soc_camera_device *icd = client->dev.platform_data;
663 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 681 struct mt9t031 *mt9t031 = to_mt9t031(client);
664 s32 data; 682 s32 data;
665 int ret; 683 int ret;
666 684
667 /* We must have a parent by now. And it cannot be a wrong one.
668 * So this entire test is completely redundant. */
669 if (!icd->dev.parent ||
670 to_soc_camera_host(icd->dev.parent)->nr != icd->iface)
671 return -ENODEV;
672
673 /* Enable the chip */ 685 /* Enable the chip */
674 data = reg_write(client, MT9T031_CHIP_ENABLE, 1); 686 data = reg_write(client, MT9T031_CHIP_ENABLE, 1);
675 dev_dbg(&icd->dev, "write: %d\n", data); 687 dev_dbg(&client->dev, "write: %d\n", data);
676 688
677 /* Read out the chip version register */ 689 /* Read out the chip version register */
678 data = reg_read(client, MT9T031_CHIP_VERSION); 690 data = reg_read(client, MT9T031_CHIP_VERSION);
@@ -684,44 +696,64 @@ static int mt9t031_video_probe(struct soc_camera_device *icd)
684 icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats); 696 icd->num_formats = ARRAY_SIZE(mt9t031_colour_formats);
685 break; 697 break;
686 default: 698 default:
687 ret = -ENODEV; 699 dev_err(&client->dev,
688 dev_err(&icd->dev,
689 "No MT9T031 chip detected, register read %x\n", data); 700 "No MT9T031 chip detected, register read %x\n", data);
690 goto ei2c; 701 return -ENODEV;
691 } 702 }
692 703
693 dev_info(&icd->dev, "Detected a MT9T031 chip ID %x\n", data); 704 dev_info(&client->dev, "Detected a MT9T031 chip ID %x\n", data);
694 705
695 /* Now that we know the model, we can start video */ 706 ret = mt9t031_idle(client);
696 ret = soc_camera_video_start(icd); 707 if (ret < 0)
697 if (ret) 708 dev_err(&client->dev, "Failed to initialise the camera\n");
698 goto evstart;
699 709
700 return 0; 710 /* mt9t031_idle() has reset the chip to default. */
711 mt9t031->exposure = 255;
712 mt9t031->gain = 64;
701 713
702evstart:
703ei2c:
704 return ret; 714 return ret;
705} 715}
706 716
707static void mt9t031_video_remove(struct soc_camera_device *icd) 717static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
708{ 718 .g_ctrl = mt9t031_g_ctrl,
709 struct mt9t031 *mt9t031 = container_of(icd, struct mt9t031, icd); 719 .s_ctrl = mt9t031_s_ctrl,
720 .g_chip_ident = mt9t031_g_chip_ident,
721#ifdef CONFIG_VIDEO_ADV_DEBUG
722 .g_register = mt9t031_g_register,
723 .s_register = mt9t031_s_register,
724#endif
725};
710 726
711 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9t031->client->addr, 727static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
712 icd->dev.parent, icd->vdev); 728 .s_stream = mt9t031_s_stream,
713 soc_camera_video_stop(icd); 729 .s_fmt = mt9t031_s_fmt,
714} 730 .g_fmt = mt9t031_g_fmt,
731 .try_fmt = mt9t031_try_fmt,
732 .s_crop = mt9t031_s_crop,
733 .g_crop = mt9t031_g_crop,
734 .cropcap = mt9t031_cropcap,
735};
736
737static struct v4l2_subdev_ops mt9t031_subdev_ops = {
738 .core = &mt9t031_subdev_core_ops,
739 .video = &mt9t031_subdev_video_ops,
740};
715 741
716static int mt9t031_probe(struct i2c_client *client, 742static int mt9t031_probe(struct i2c_client *client,
717 const struct i2c_device_id *did) 743 const struct i2c_device_id *did)
718{ 744{
719 struct mt9t031 *mt9t031; 745 struct mt9t031 *mt9t031;
720 struct soc_camera_device *icd; 746 struct soc_camera_device *icd = client->dev.platform_data;
721 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 747 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
722 struct soc_camera_link *icl = client->dev.platform_data; 748 struct soc_camera_link *icl;
723 int ret; 749 int ret;
724 750
751 if (!icd) {
752 dev_err(&client->dev, "MT9T031: missing soc-camera data!\n");
753 return -EINVAL;
754 }
755
756 icl = to_soc_camera_link(icd);
725 if (!icl) { 757 if (!icl) {
726 dev_err(&client->dev, "MT9T031 driver needs platform data\n"); 758 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
727 return -EINVAL; 759 return -EINVAL;
@@ -737,23 +769,17 @@ static int mt9t031_probe(struct i2c_client *client,
737 if (!mt9t031) 769 if (!mt9t031)
738 return -ENOMEM; 770 return -ENOMEM;
739 771
740 mt9t031->client = client; 772 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
741 i2c_set_clientdata(client, mt9t031);
742 773
743 /* Second stage probe - when a capture adapter is there */ 774 /* Second stage probe - when a capture adapter is there */
744 icd = &mt9t031->icd; 775 icd->ops = &mt9t031_ops;
745 icd->ops = &mt9t031_ops; 776 icd->y_skip_top = 0;
746 icd->control = &client->dev; 777
747 icd->x_min = MT9T031_COLUMN_SKIP; 778 mt9t031->rect.left = MT9T031_COLUMN_SKIP;
748 icd->y_min = MT9T031_ROW_SKIP; 779 mt9t031->rect.top = MT9T031_ROW_SKIP;
749 icd->x_current = icd->x_min; 780 mt9t031->rect.width = MT9T031_MAX_WIDTH;
750 icd->y_current = icd->y_min; 781 mt9t031->rect.height = MT9T031_MAX_HEIGHT;
751 icd->width_min = MT9T031_MIN_WIDTH; 782
752 icd->width_max = MT9T031_MAX_WIDTH;
753 icd->height_min = MT9T031_MIN_HEIGHT;
754 icd->height_max = MT9T031_MAX_HEIGHT;
755 icd->y_skip_top = 0;
756 icd->iface = icl->bus_id;
757 /* Simulated autoexposure. If enabled, we calculate shutter width 783 /* Simulated autoexposure. If enabled, we calculate shutter width
758 * ourselves in the driver based on vertical blanking and frame width */ 784 * ourselves in the driver based on vertical blanking and frame width */
759 mt9t031->autoexposure = 1; 785 mt9t031->autoexposure = 1;
@@ -761,24 +787,29 @@ static int mt9t031_probe(struct i2c_client *client,
761 mt9t031->xskip = 1; 787 mt9t031->xskip = 1;
762 mt9t031->yskip = 1; 788 mt9t031->yskip = 1;
763 789
764 ret = soc_camera_device_register(icd); 790 mt9t031_idle(client);
765 if (ret)
766 goto eisdr;
767 791
768 return 0; 792 ret = mt9t031_video_probe(client);
793
794 mt9t031_disable(client);
795
796 if (ret) {
797 icd->ops = NULL;
798 i2c_set_clientdata(client, NULL);
799 kfree(mt9t031);
800 }
769 801
770eisdr:
771 i2c_set_clientdata(client, NULL);
772 kfree(mt9t031);
773 return ret; 802 return ret;
774} 803}
775 804
776static int mt9t031_remove(struct i2c_client *client) 805static int mt9t031_remove(struct i2c_client *client)
777{ 806{
778 struct mt9t031 *mt9t031 = i2c_get_clientdata(client); 807 struct mt9t031 *mt9t031 = to_mt9t031(client);
808 struct soc_camera_device *icd = client->dev.platform_data;
779 809
780 soc_camera_device_unregister(&mt9t031->icd); 810 icd->ops = NULL;
781 i2c_set_clientdata(client, NULL); 811 i2c_set_clientdata(client, NULL);
812 client->driver = NULL;
782 kfree(mt9t031); 813 kfree(mt9t031);
783 814
784 return 0; 815 return 0;
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index dbdcc86ae50d..995607f9d3ba 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,13 +14,13 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16 16
17#include <media/v4l2-common.h> 17#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 18#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20 20
21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 21/* mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
22 * The platform has to define i2c_board_info 22 * The platform has to define ctruct i2c_board_info objects and link to them
23 * and call i2c_register_board_info() */ 23 * from struct soc_camera_link */
24 24
25static char *sensor_type; 25static char *sensor_type;
26module_param(sensor_type, charp, S_IRUGO); 26module_param(sensor_type, charp, S_IRUGO);
@@ -45,7 +45,7 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
45#define MT9V022_PIXEL_OPERATION_MODE 0x0f 45#define MT9V022_PIXEL_OPERATION_MODE 0x0f
46#define MT9V022_LED_OUT_CONTROL 0x1b 46#define MT9V022_LED_OUT_CONTROL 0x1b
47#define MT9V022_ADC_MODE_CONTROL 0x1c 47#define MT9V022_ADC_MODE_CONTROL 0x1c
48#define MT9V022_ANALOG_GAIN 0x34 48#define MT9V022_ANALOG_GAIN 0x35
49#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47 49#define MT9V022_BLACK_LEVEL_CALIB_CTRL 0x47
50#define MT9V022_PIXCLK_FV_LV 0x74 50#define MT9V022_PIXCLK_FV_LV 0x74
51#define MT9V022_DIGITAL_TEST_PATTERN 0x7f 51#define MT9V022_DIGITAL_TEST_PATTERN 0x7f
@@ -55,6 +55,13 @@ MODULE_PARM_DESC(sensor_type, "Sensor type: \"colour\" or \"monochrome\"");
55/* Progressive scan, master, defaults */ 55/* Progressive scan, master, defaults */
56#define MT9V022_CHIP_CONTROL_DEFAULT 0x188 56#define MT9V022_CHIP_CONTROL_DEFAULT 0x188
57 57
58#define MT9V022_MAX_WIDTH 752
59#define MT9V022_MAX_HEIGHT 480
60#define MT9V022_MIN_WIDTH 48
61#define MT9V022_MIN_HEIGHT 32
62#define MT9V022_COLUMN_SKIP 1
63#define MT9V022_ROW_SKIP 4
64
58static const struct soc_camera_data_format mt9v022_colour_formats[] = { 65static const struct soc_camera_data_format mt9v022_colour_formats[] = {
59 /* Order important: first natively supported, 66 /* Order important: first natively supported,
60 * second supported with a GPIO extender */ 67 * second supported with a GPIO extender */
@@ -85,12 +92,18 @@ static const struct soc_camera_data_format mt9v022_monochrome_formats[] = {
85}; 92};
86 93
87struct mt9v022 { 94struct mt9v022 {
88 struct i2c_client *client; 95 struct v4l2_subdev subdev;
89 struct soc_camera_device icd; 96 struct v4l2_rect rect; /* Sensor window */
97 __u32 fourcc;
90 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */ 98 int model; /* V4L2_IDENT_MT9V022* codes from v4l2-chip-ident.h */
91 u16 chip_control; 99 u16 chip_control;
92}; 100};
93 101
102static struct mt9v022 *to_mt9v022(const struct i2c_client *client)
103{
104 return container_of(i2c_get_clientdata(client), struct mt9v022, subdev);
105}
106
94static int reg_read(struct i2c_client *client, const u8 reg) 107static int reg_read(struct i2c_client *client, const u8 reg)
95{ 108{
96 s32 data = i2c_smbus_read_word_data(client, reg); 109 s32 data = i2c_smbus_read_word_data(client, reg);
@@ -125,29 +138,11 @@ static int reg_clear(struct i2c_client *client, const u8 reg,
125 return reg_write(client, reg, ret & ~data); 138 return reg_write(client, reg, ret & ~data);
126} 139}
127 140
128static int mt9v022_init(struct soc_camera_device *icd) 141static int mt9v022_init(struct i2c_client *client)
129{ 142{
130 struct i2c_client *client = to_i2c_client(icd->control); 143 struct mt9v022 *mt9v022 = to_mt9v022(client);
131 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
132 struct soc_camera_link *icl = client->dev.platform_data;
133 int ret; 144 int ret;
134 145
135 if (icl->power) {
136 ret = icl->power(&client->dev, 1);
137 if (ret < 0) {
138 dev_err(icd->vdev->parent,
139 "Platform failed to power-on the camera.\n");
140 return ret;
141 }
142 }
143
144 /*
145 * The camera could have been already on, we hard-reset it additionally,
146 * if available. Soft reset is done in video_probe().
147 */
148 if (icl->reset)
149 icl->reset(&client->dev);
150
151 /* Almost the default mode: master, parallel, simultaneous, and an 146 /* Almost the default mode: master, parallel, simultaneous, and an
152 * undocumented bit 0x200, which is present in table 7, but not in 8, 147 * undocumented bit 0x200, which is present in table 7, but not in 8,
153 * plus snapshot mode to disable scan for now */ 148 * plus snapshot mode to disable scan for now */
@@ -161,6 +156,10 @@ static int mt9v022_init(struct soc_camera_device *icd)
161 /* AEC, AGC on */ 156 /* AEC, AGC on */
162 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3); 157 ret = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x3);
163 if (!ret) 158 if (!ret)
159 ret = reg_write(client, MT9V022_ANALOG_GAIN, 16);
160 if (!ret)
161 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 480);
162 if (!ret)
164 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); 163 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480);
165 if (!ret) 164 if (!ret)
166 /* default - auto */ 165 /* default - auto */
@@ -171,37 +170,19 @@ static int mt9v022_init(struct soc_camera_device *icd)
171 return ret; 170 return ret;
172} 171}
173 172
174static int mt9v022_release(struct soc_camera_device *icd) 173static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
175{ 174{
176 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 175 struct i2c_client *client = sd->priv;
177 struct soc_camera_link *icl = mt9v022->client->dev.platform_data; 176 struct mt9v022 *mt9v022 = to_mt9v022(client);
178
179 if (icl->power)
180 icl->power(&mt9v022->client->dev, 0);
181
182 return 0;
183}
184 177
185static int mt9v022_start_capture(struct soc_camera_device *icd) 178 if (enable)
186{ 179 /* Switch to master "normal" mode */
187 struct i2c_client *client = to_i2c_client(icd->control); 180 mt9v022->chip_control &= ~0x10;
188 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 181 else
189 /* Switch to master "normal" mode */ 182 /* Switch to snapshot mode */
190 mt9v022->chip_control &= ~0x10; 183 mt9v022->chip_control |= 0x10;
191 if (reg_write(client, MT9V022_CHIP_CONTROL,
192 mt9v022->chip_control) < 0)
193 return -EIO;
194 return 0;
195}
196 184
197static int mt9v022_stop_capture(struct soc_camera_device *icd) 185 if (reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control) < 0)
198{
199 struct i2c_client *client = to_i2c_client(icd->control);
200 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd);
201 /* Switch to snapshot mode */
202 mt9v022->chip_control |= 0x10;
203 if (reg_write(client, MT9V022_CHIP_CONTROL,
204 mt9v022->chip_control) < 0)
205 return -EIO; 186 return -EIO;
206 return 0; 187 return 0;
207} 188}
@@ -209,9 +190,9 @@ static int mt9v022_stop_capture(struct soc_camera_device *icd)
209static int mt9v022_set_bus_param(struct soc_camera_device *icd, 190static int mt9v022_set_bus_param(struct soc_camera_device *icd,
210 unsigned long flags) 191 unsigned long flags)
211{ 192{
212 struct i2c_client *client = to_i2c_client(icd->control); 193 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
213 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 194 struct mt9v022 *mt9v022 = to_mt9v022(client);
214 struct soc_camera_link *icl = client->dev.platform_data; 195 struct soc_camera_link *icl = to_soc_camera_link(icd);
215 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK; 196 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
216 int ret; 197 int ret;
217 u16 pixclk = 0; 198 u16 pixclk = 0;
@@ -255,7 +236,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
255 if (ret < 0) 236 if (ret < 0)
256 return ret; 237 return ret;
257 238
258 dev_dbg(&icd->dev, "Calculated pixclk 0x%x, chip control 0x%x\n", 239 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
259 pixclk, mt9v022->chip_control); 240 pixclk, mt9v022->chip_control);
260 241
261 return 0; 242 return 0;
@@ -263,8 +244,7 @@ static int mt9v022_set_bus_param(struct soc_camera_device *icd,
263 244
264static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd) 245static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
265{ 246{
266 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 247 struct soc_camera_link *icl = to_soc_camera_link(icd);
267 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
268 unsigned int width_flag; 248 unsigned int width_flag;
269 249
270 if (icl->query_bus_param) 250 if (icl->query_bus_param)
@@ -280,60 +260,121 @@ static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
280 width_flag; 260 width_flag;
281} 261}
282 262
283static int mt9v022_set_crop(struct soc_camera_device *icd, 263static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
284 struct v4l2_rect *rect)
285{ 264{
286 struct i2c_client *client = to_i2c_client(icd->control); 265 struct i2c_client *client = sd->priv;
266 struct mt9v022 *mt9v022 = to_mt9v022(client);
267 struct v4l2_rect rect = a->c;
268 struct soc_camera_device *icd = client->dev.platform_data;
287 int ret; 269 int ret;
288 270
271 /* Bayer format - even size lengths */
272 if (mt9v022->fourcc == V4L2_PIX_FMT_SBGGR8 ||
273 mt9v022->fourcc == V4L2_PIX_FMT_SBGGR16) {
274 rect.width = ALIGN(rect.width, 2);
275 rect.height = ALIGN(rect.height, 2);
276 /* Let the user play with the starting pixel */
277 }
278
279 soc_camera_limit_side(&rect.left, &rect.width,
280 MT9V022_COLUMN_SKIP, MT9V022_MIN_WIDTH, MT9V022_MAX_WIDTH);
281
282 soc_camera_limit_side(&rect.top, &rect.height,
283 MT9V022_ROW_SKIP, MT9V022_MIN_HEIGHT, MT9V022_MAX_HEIGHT);
284
289 /* Like in example app. Contradicts the datasheet though */ 285 /* Like in example app. Contradicts the datasheet though */
290 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE); 286 ret = reg_read(client, MT9V022_AEC_AGC_ENABLE);
291 if (ret >= 0) { 287 if (ret >= 0) {
292 if (ret & 1) /* Autoexposure */ 288 if (ret & 1) /* Autoexposure */
293 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 289 ret = reg_write(client, MT9V022_MAX_TOTAL_SHUTTER_WIDTH,
294 rect->height + icd->y_skip_top + 43); 290 rect.height + icd->y_skip_top + 43);
295 else 291 else
296 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 292 ret = reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
297 rect->height + icd->y_skip_top + 43); 293 rect.height + icd->y_skip_top + 43);
298 } 294 }
299 /* Setup frame format: defaults apart from width and height */ 295 /* Setup frame format: defaults apart from width and height */
300 if (!ret) 296 if (!ret)
301 ret = reg_write(client, MT9V022_COLUMN_START, rect->left); 297 ret = reg_write(client, MT9V022_COLUMN_START, rect.left);
302 if (!ret) 298 if (!ret)
303 ret = reg_write(client, MT9V022_ROW_START, rect->top); 299 ret = reg_write(client, MT9V022_ROW_START, rect.top);
304 if (!ret) 300 if (!ret)
305 /* Default 94, Phytec driver says: 301 /* Default 94, Phytec driver says:
306 * "width + horizontal blank >= 660" */ 302 * "width + horizontal blank >= 660" */
307 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING, 303 ret = reg_write(client, MT9V022_HORIZONTAL_BLANKING,
308 rect->width > 660 - 43 ? 43 : 304 rect.width > 660 - 43 ? 43 :
309 660 - rect->width); 305 660 - rect.width);
310 if (!ret) 306 if (!ret)
311 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45); 307 ret = reg_write(client, MT9V022_VERTICAL_BLANKING, 45);
312 if (!ret) 308 if (!ret)
313 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect->width); 309 ret = reg_write(client, MT9V022_WINDOW_WIDTH, rect.width);
314 if (!ret) 310 if (!ret)
315 ret = reg_write(client, MT9V022_WINDOW_HEIGHT, 311 ret = reg_write(client, MT9V022_WINDOW_HEIGHT,
316 rect->height + icd->y_skip_top); 312 rect.height + icd->y_skip_top);
317 313
318 if (ret < 0) 314 if (ret < 0)
319 return ret; 315 return ret;
320 316
321 dev_dbg(&icd->dev, "Frame %ux%u pixel\n", rect->width, rect->height); 317 dev_dbg(&client->dev, "Frame %ux%u pixel\n", rect.width, rect.height);
318
319 mt9v022->rect = rect;
320
321 return 0;
322}
323
324static int mt9v022_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
325{
326 struct i2c_client *client = sd->priv;
327 struct mt9v022 *mt9v022 = to_mt9v022(client);
328
329 a->c = mt9v022->rect;
330 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
322 331
323 return 0; 332 return 0;
324} 333}
325 334
326static int mt9v022_set_fmt(struct soc_camera_device *icd, 335static int mt9v022_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
327 struct v4l2_format *f)
328{ 336{
329 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 337 a->bounds.left = MT9V022_COLUMN_SKIP;
338 a->bounds.top = MT9V022_ROW_SKIP;
339 a->bounds.width = MT9V022_MAX_WIDTH;
340 a->bounds.height = MT9V022_MAX_HEIGHT;
341 a->defrect = a->bounds;
342 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
343 a->pixelaspect.numerator = 1;
344 a->pixelaspect.denominator = 1;
345
346 return 0;
347}
348
349static int mt9v022_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
350{
351 struct i2c_client *client = sd->priv;
352 struct mt9v022 *mt9v022 = to_mt9v022(client);
330 struct v4l2_pix_format *pix = &f->fmt.pix; 353 struct v4l2_pix_format *pix = &f->fmt.pix;
331 struct v4l2_rect rect = { 354
332 .left = icd->x_current, 355 pix->width = mt9v022->rect.width;
333 .top = icd->y_current, 356 pix->height = mt9v022->rect.height;
334 .width = pix->width, 357 pix->pixelformat = mt9v022->fourcc;
335 .height = pix->height, 358 pix->field = V4L2_FIELD_NONE;
359 pix->colorspace = V4L2_COLORSPACE_SRGB;
360
361 return 0;
362}
363
364static int mt9v022_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
365{
366 struct i2c_client *client = sd->priv;
367 struct mt9v022 *mt9v022 = to_mt9v022(client);
368 struct v4l2_pix_format *pix = &f->fmt.pix;
369 struct v4l2_crop a = {
370 .c = {
371 .left = mt9v022->rect.left,
372 .top = mt9v022->rect.top,
373 .width = pix->width,
374 .height = pix->height,
375 },
336 }; 376 };
377 int ret;
337 378
338 /* The caller provides a supported format, as verified per call to 379 /* The caller provides a supported format, as verified per call to
339 * icd->try_fmt(), datawidth is from our supported format list */ 380 * icd->try_fmt(), datawidth is from our supported format list */
@@ -356,30 +397,42 @@ static int mt9v022_set_fmt(struct soc_camera_device *icd,
356 } 397 }
357 398
358 /* No support for scaling on this camera, just crop. */ 399 /* No support for scaling on this camera, just crop. */
359 return mt9v022_set_crop(icd, &rect); 400 ret = mt9v022_s_crop(sd, &a);
401 if (!ret) {
402 pix->width = mt9v022->rect.width;
403 pix->height = mt9v022->rect.height;
404 mt9v022->fourcc = pix->pixelformat;
405 }
406
407 return ret;
360} 408}
361 409
362static int mt9v022_try_fmt(struct soc_camera_device *icd, 410static int mt9v022_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
363 struct v4l2_format *f)
364{ 411{
412 struct i2c_client *client = sd->priv;
413 struct soc_camera_device *icd = client->dev.platform_data;
365 struct v4l2_pix_format *pix = &f->fmt.pix; 414 struct v4l2_pix_format *pix = &f->fmt.pix;
415 int align = pix->pixelformat == V4L2_PIX_FMT_SBGGR8 ||
416 pix->pixelformat == V4L2_PIX_FMT_SBGGR16;
366 417
367 v4l_bound_align_image(&pix->width, 48, 752, 2 /* ? */, 418 v4l_bound_align_image(&pix->width, MT9V022_MIN_WIDTH,
368 &pix->height, 32 + icd->y_skip_top, 419 MT9V022_MAX_WIDTH, align,
369 480 + icd->y_skip_top, 0, 0); 420 &pix->height, MT9V022_MIN_HEIGHT + icd->y_skip_top,
421 MT9V022_MAX_HEIGHT + icd->y_skip_top, align, 0);
370 422
371 return 0; 423 return 0;
372} 424}
373 425
374static int mt9v022_get_chip_id(struct soc_camera_device *icd, 426static int mt9v022_g_chip_ident(struct v4l2_subdev *sd,
375 struct v4l2_dbg_chip_ident *id) 427 struct v4l2_dbg_chip_ident *id)
376{ 428{
377 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 429 struct i2c_client *client = sd->priv;
430 struct mt9v022 *mt9v022 = to_mt9v022(client);
378 431
379 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR) 432 if (id->match.type != V4L2_CHIP_MATCH_I2C_ADDR)
380 return -EINVAL; 433 return -EINVAL;
381 434
382 if (id->match.addr != mt9v022->client->addr) 435 if (id->match.addr != client->addr)
383 return -ENODEV; 436 return -ENODEV;
384 437
385 id->ident = mt9v022->model; 438 id->ident = mt9v022->model;
@@ -389,10 +442,10 @@ static int mt9v022_get_chip_id(struct soc_camera_device *icd,
389} 442}
390 443
391#ifdef CONFIG_VIDEO_ADV_DEBUG 444#ifdef CONFIG_VIDEO_ADV_DEBUG
392static int mt9v022_get_register(struct soc_camera_device *icd, 445static int mt9v022_g_register(struct v4l2_subdev *sd,
393 struct v4l2_dbg_register *reg) 446 struct v4l2_dbg_register *reg)
394{ 447{
395 struct i2c_client *client = to_i2c_client(icd->control); 448 struct i2c_client *client = sd->priv;
396 449
397 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 450 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
398 return -EINVAL; 451 return -EINVAL;
@@ -409,10 +462,10 @@ static int mt9v022_get_register(struct soc_camera_device *icd,
409 return 0; 462 return 0;
410} 463}
411 464
412static int mt9v022_set_register(struct soc_camera_device *icd, 465static int mt9v022_s_register(struct v4l2_subdev *sd,
413 struct v4l2_dbg_register *reg) 466 struct v4l2_dbg_register *reg)
414{ 467{
415 struct i2c_client *client = to_i2c_client(icd->control); 468 struct i2c_client *client = sd->priv;
416 469
417 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff) 470 if (reg->match.type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0xff)
418 return -EINVAL; 471 return -EINVAL;
@@ -481,41 +534,22 @@ static const struct v4l2_queryctrl mt9v022_controls[] = {
481 } 534 }
482}; 535};
483 536
484static int mt9v022_video_probe(struct soc_camera_device *);
485static void mt9v022_video_remove(struct soc_camera_device *);
486static int mt9v022_get_control(struct soc_camera_device *, struct v4l2_control *);
487static int mt9v022_set_control(struct soc_camera_device *, struct v4l2_control *);
488
489static struct soc_camera_ops mt9v022_ops = { 537static struct soc_camera_ops mt9v022_ops = {
490 .owner = THIS_MODULE,
491 .probe = mt9v022_video_probe,
492 .remove = mt9v022_video_remove,
493 .init = mt9v022_init,
494 .release = mt9v022_release,
495 .start_capture = mt9v022_start_capture,
496 .stop_capture = mt9v022_stop_capture,
497 .set_crop = mt9v022_set_crop,
498 .set_fmt = mt9v022_set_fmt,
499 .try_fmt = mt9v022_try_fmt,
500 .set_bus_param = mt9v022_set_bus_param, 538 .set_bus_param = mt9v022_set_bus_param,
501 .query_bus_param = mt9v022_query_bus_param, 539 .query_bus_param = mt9v022_query_bus_param,
502 .controls = mt9v022_controls, 540 .controls = mt9v022_controls,
503 .num_controls = ARRAY_SIZE(mt9v022_controls), 541 .num_controls = ARRAY_SIZE(mt9v022_controls),
504 .get_control = mt9v022_get_control,
505 .set_control = mt9v022_set_control,
506 .get_chip_id = mt9v022_get_chip_id,
507#ifdef CONFIG_VIDEO_ADV_DEBUG
508 .get_register = mt9v022_get_register,
509 .set_register = mt9v022_set_register,
510#endif
511}; 542};
512 543
513static int mt9v022_get_control(struct soc_camera_device *icd, 544static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
514 struct v4l2_control *ctrl)
515{ 545{
516 struct i2c_client *client = to_i2c_client(icd->control); 546 struct i2c_client *client = sd->priv;
547 const struct v4l2_queryctrl *qctrl;
548 unsigned long range;
517 int data; 549 int data;
518 550
551 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
552
519 switch (ctrl->id) { 553 switch (ctrl->id) {
520 case V4L2_CID_VFLIP: 554 case V4L2_CID_VFLIP:
521 data = reg_read(client, MT9V022_READ_MODE); 555 data = reg_read(client, MT9V022_READ_MODE);
@@ -541,19 +575,35 @@ static int mt9v022_get_control(struct soc_camera_device *icd,
541 return -EIO; 575 return -EIO;
542 ctrl->value = !!(data & 0x2); 576 ctrl->value = !!(data & 0x2);
543 break; 577 break;
578 case V4L2_CID_GAIN:
579 data = reg_read(client, MT9V022_ANALOG_GAIN);
580 if (data < 0)
581 return -EIO;
582
583 range = qctrl->maximum - qctrl->minimum;
584 ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum;
585
586 break;
587 case V4L2_CID_EXPOSURE:
588 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
589 if (data < 0)
590 return -EIO;
591
592 range = qctrl->maximum - qctrl->minimum;
593 ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum;
594
595 break;
544 } 596 }
545 return 0; 597 return 0;
546} 598}
547 599
548static int mt9v022_set_control(struct soc_camera_device *icd, 600static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
549 struct v4l2_control *ctrl)
550{ 601{
551 int data; 602 int data;
552 struct i2c_client *client = to_i2c_client(icd->control); 603 struct i2c_client *client = sd->priv;
553 const struct v4l2_queryctrl *qctrl; 604 const struct v4l2_queryctrl *qctrl;
554 605
555 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id); 606 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
556
557 if (!qctrl) 607 if (!qctrl)
558 return -EINVAL; 608 return -EINVAL;
559 609
@@ -580,12 +630,9 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
580 return -EINVAL; 630 return -EINVAL;
581 else { 631 else {
582 unsigned long range = qctrl->maximum - qctrl->minimum; 632 unsigned long range = qctrl->maximum - qctrl->minimum;
583 /* Datasheet says 16 to 64. autogain only works properly 633 /* Valid values 16 to 64, 32 to 64 must be even. */
584 * after setting gain to maximum 14. Larger values
585 * produce "white fly" noise effect. On the whole,
586 * manually setting analog gain does no good. */
587 unsigned long gain = ((ctrl->value - qctrl->minimum) * 634 unsigned long gain = ((ctrl->value - qctrl->minimum) *
588 10 + range / 2) / range + 4; 635 48 + range / 2) / range + 16;
589 if (gain >= 32) 636 if (gain >= 32)
590 gain &= ~1; 637 gain &= ~1;
591 /* The user wants to set gain manually, hope, she 638 /* The user wants to set gain manually, hope, she
@@ -594,11 +641,10 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
594 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 641 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
595 return -EIO; 642 return -EIO;
596 643
597 dev_info(&icd->dev, "Setting gain from %d to %lu\n", 644 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
598 reg_read(client, MT9V022_ANALOG_GAIN), gain); 645 reg_read(client, MT9V022_ANALOG_GAIN), gain);
599 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) 646 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0)
600 return -EIO; 647 return -EIO;
601 icd->gain = ctrl->value;
602 } 648 }
603 break; 649 break;
604 case V4L2_CID_EXPOSURE: 650 case V4L2_CID_EXPOSURE:
@@ -615,13 +661,12 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
615 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 661 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0)
616 return -EIO; 662 return -EIO;
617 663
618 dev_dbg(&icd->dev, "Shutter width from %d to %lu\n", 664 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
619 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), 665 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
620 shutter); 666 shutter);
621 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 667 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
622 shutter) < 0) 668 shutter) < 0)
623 return -EIO; 669 return -EIO;
624 icd->exposure = ctrl->value;
625 } 670 }
626 break; 671 break;
627 case V4L2_CID_AUTOGAIN: 672 case V4L2_CID_AUTOGAIN:
@@ -646,11 +691,11 @@ static int mt9v022_set_control(struct soc_camera_device *icd,
646 691
647/* Interface active, can use i2c. If it fails, it can indeed mean, that 692/* Interface active, can use i2c. If it fails, it can indeed mean, that
648 * this wasn't our capture interface, so, we wait for the right one */ 693 * this wasn't our capture interface, so, we wait for the right one */
649static int mt9v022_video_probe(struct soc_camera_device *icd) 694static int mt9v022_video_probe(struct soc_camera_device *icd,
695 struct i2c_client *client)
650{ 696{
651 struct i2c_client *client = to_i2c_client(icd->control); 697 struct mt9v022 *mt9v022 = to_mt9v022(client);
652 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 698 struct soc_camera_link *icl = to_soc_camera_link(icd);
653 struct soc_camera_link *icl = client->dev.platform_data;
654 s32 data; 699 s32 data;
655 int ret; 700 int ret;
656 unsigned long flags; 701 unsigned long flags;
@@ -665,7 +710,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
665 /* must be 0x1311 or 0x1313 */ 710 /* must be 0x1311 or 0x1313 */
666 if (data != 0x1311 && data != 0x1313) { 711 if (data != 0x1311 && data != 0x1313) {
667 ret = -ENODEV; 712 ret = -ENODEV;
668 dev_info(&icd->dev, "No MT9V022 detected, ID register 0x%x\n", 713 dev_info(&client->dev, "No MT9V022 found, ID register 0x%x\n",
669 data); 714 data);
670 goto ei2c; 715 goto ei2c;
671 } 716 }
@@ -677,7 +722,9 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
677 /* 15 clock cycles */ 722 /* 15 clock cycles */
678 udelay(200); 723 udelay(200);
679 if (reg_read(client, MT9V022_RESET)) { 724 if (reg_read(client, MT9V022_RESET)) {
680 dev_err(&icd->dev, "Resetting MT9V022 failed!\n"); 725 dev_err(&client->dev, "Resetting MT9V022 failed!\n");
726 if (ret > 0)
727 ret = -EIO;
681 goto ei2c; 728 goto ei2c;
682 } 729 }
683 730
@@ -694,7 +741,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
694 } 741 }
695 742
696 if (ret < 0) 743 if (ret < 0)
697 goto eisis; 744 goto ei2c;
698 745
699 icd->num_formats = 0; 746 icd->num_formats = 0;
700 747
@@ -716,42 +763,70 @@ static int mt9v022_video_probe(struct soc_camera_device *icd)
716 if (flags & SOCAM_DATAWIDTH_8) 763 if (flags & SOCAM_DATAWIDTH_8)
717 icd->num_formats++; 764 icd->num_formats++;
718 765
719 ret = soc_camera_video_start(icd); 766 mt9v022->fourcc = icd->formats->fourcc;
720 if (ret < 0)
721 goto eisis;
722 767
723 dev_info(&icd->dev, "Detected a MT9V022 chip ID %x, %s sensor\n", 768 dev_info(&client->dev, "Detected a MT9V022 chip ID %x, %s sensor\n",
724 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ? 769 data, mt9v022->model == V4L2_IDENT_MT9V022IX7ATM ?
725 "monochrome" : "colour"); 770 "monochrome" : "colour");
726 771
727 return 0; 772 ret = mt9v022_init(client);
773 if (ret < 0)
774 dev_err(&client->dev, "Failed to initialise the camera\n");
728 775
729eisis:
730ei2c: 776ei2c:
731 return ret; 777 return ret;
732} 778}
733 779
734static void mt9v022_video_remove(struct soc_camera_device *icd) 780static void mt9v022_video_remove(struct soc_camera_device *icd)
735{ 781{
736 struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); 782 struct soc_camera_link *icl = to_soc_camera_link(icd);
737 struct soc_camera_link *icl = mt9v022->client->dev.platform_data;
738 783
739 dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9v022->client->addr, 784 dev_dbg(&icd->dev, "Video removed: %p, %p\n",
740 icd->dev.parent, icd->vdev); 785 icd->dev.parent, icd->vdev);
741 soc_camera_video_stop(icd);
742 if (icl->free_bus) 786 if (icl->free_bus)
743 icl->free_bus(icl); 787 icl->free_bus(icl);
744} 788}
745 789
790static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
791 .g_ctrl = mt9v022_g_ctrl,
792 .s_ctrl = mt9v022_s_ctrl,
793 .g_chip_ident = mt9v022_g_chip_ident,
794#ifdef CONFIG_VIDEO_ADV_DEBUG
795 .g_register = mt9v022_g_register,
796 .s_register = mt9v022_s_register,
797#endif
798};
799
800static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
801 .s_stream = mt9v022_s_stream,
802 .s_fmt = mt9v022_s_fmt,
803 .g_fmt = mt9v022_g_fmt,
804 .try_fmt = mt9v022_try_fmt,
805 .s_crop = mt9v022_s_crop,
806 .g_crop = mt9v022_g_crop,
807 .cropcap = mt9v022_cropcap,
808};
809
810static struct v4l2_subdev_ops mt9v022_subdev_ops = {
811 .core = &mt9v022_subdev_core_ops,
812 .video = &mt9v022_subdev_video_ops,
813};
814
746static int mt9v022_probe(struct i2c_client *client, 815static int mt9v022_probe(struct i2c_client *client,
747 const struct i2c_device_id *did) 816 const struct i2c_device_id *did)
748{ 817{
749 struct mt9v022 *mt9v022; 818 struct mt9v022 *mt9v022;
750 struct soc_camera_device *icd; 819 struct soc_camera_device *icd = client->dev.platform_data;
751 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 820 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
752 struct soc_camera_link *icl = client->dev.platform_data; 821 struct soc_camera_link *icl;
753 int ret; 822 int ret;
754 823
824 if (!icd) {
825 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
826 return -EINVAL;
827 }
828
829 icl = to_soc_camera_link(icd);
755 if (!icl) { 830 if (!icl) {
756 dev_err(&client->dev, "MT9V022 driver needs platform data\n"); 831 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
757 return -EINVAL; 832 return -EINVAL;
@@ -767,40 +842,41 @@ static int mt9v022_probe(struct i2c_client *client,
767 if (!mt9v022) 842 if (!mt9v022)
768 return -ENOMEM; 843 return -ENOMEM;
769 844
845 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
846
770 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 847 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
771 mt9v022->client = client;
772 i2c_set_clientdata(client, mt9v022);
773
774 icd = &mt9v022->icd;
775 icd->ops = &mt9v022_ops;
776 icd->control = &client->dev;
777 icd->x_min = 1;
778 icd->y_min = 4;
779 icd->x_current = 1;
780 icd->y_current = 4;
781 icd->width_min = 48;
782 icd->width_max = 752;
783 icd->height_min = 32;
784 icd->height_max = 480;
785 icd->y_skip_top = 1;
786 icd->iface = icl->bus_id;
787
788 ret = soc_camera_device_register(icd);
789 if (ret)
790 goto eisdr;
791 848
792 return 0; 849 icd->ops = &mt9v022_ops;
850 /*
851 * MT9V022 _really_ corrupts the first read out line.
852 * TODO: verify on i.MX31
853 */
854 icd->y_skip_top = 1;
855
856 mt9v022->rect.left = MT9V022_COLUMN_SKIP;
857 mt9v022->rect.top = MT9V022_ROW_SKIP;
858 mt9v022->rect.width = MT9V022_MAX_WIDTH;
859 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
860
861 ret = mt9v022_video_probe(icd, client);
862 if (ret) {
863 icd->ops = NULL;
864 i2c_set_clientdata(client, NULL);
865 kfree(mt9v022);
866 }
793 867
794eisdr:
795 kfree(mt9v022);
796 return ret; 868 return ret;
797} 869}
798 870
799static int mt9v022_remove(struct i2c_client *client) 871static int mt9v022_remove(struct i2c_client *client)
800{ 872{
801 struct mt9v022 *mt9v022 = i2c_get_clientdata(client); 873 struct mt9v022 *mt9v022 = to_mt9v022(client);
874 struct soc_camera_device *icd = client->dev.platform_data;
802 875
803 soc_camera_device_unregister(&mt9v022->icd); 876 icd->ops = NULL;
877 mt9v022_video_remove(icd);
878 i2c_set_clientdata(client, NULL);
879 client->driver = NULL;
804 kfree(mt9v022); 880 kfree(mt9v022);
805 881
806 return 0; 882 return 0;
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 736c31d23194..5f37952c75cf 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -126,7 +126,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
126{ 126{
127 struct soc_camera_device *icd = vq->priv_data; 127 struct soc_camera_device *icd = vq->priv_data;
128 128
129 *size = icd->width * icd->height * 129 *size = icd->user_width * icd->user_height *
130 ((icd->current_fmt->depth + 7) >> 3); 130 ((icd->current_fmt->depth + 7) >> 3);
131 131
132 if (!*count) 132 if (!*count)
@@ -135,7 +135,7 @@ static int mx1_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
135 while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 135 while (*size * *count > MAX_VIDEO_MEM * 1024 * 1024)
136 (*count)--; 136 (*count)--;
137 137
138 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 138 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
139 139
140 return 0; 140 return 0;
141} 141}
@@ -147,7 +147,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx1_buffer *buf)
147 147
148 BUG_ON(in_interrupt()); 148 BUG_ON(in_interrupt());
149 149
150 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 150 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
151 vb, vb->baddr, vb->bsize); 151 vb, vb->baddr, vb->bsize);
152 152
153 /* This waits until this buffer is out of danger, i.e., until it is no 153 /* This waits until this buffer is out of danger, i.e., until it is no
@@ -165,7 +165,7 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
165 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 165 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
166 int ret; 166 int ret;
167 167
168 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 168 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
169 vb, vb->baddr, vb->bsize); 169 vb, vb->baddr, vb->bsize);
170 170
171 /* Added list head initialization on alloc */ 171 /* Added list head initialization on alloc */
@@ -178,12 +178,12 @@ static int mx1_videobuf_prepare(struct videobuf_queue *vq,
178 buf->inwork = 1; 178 buf->inwork = 1;
179 179
180 if (buf->fmt != icd->current_fmt || 180 if (buf->fmt != icd->current_fmt ||
181 vb->width != icd->width || 181 vb->width != icd->user_width ||
182 vb->height != icd->height || 182 vb->height != icd->user_height ||
183 vb->field != field) { 183 vb->field != field) {
184 buf->fmt = icd->current_fmt; 184 buf->fmt = icd->current_fmt;
185 vb->width = icd->width; 185 vb->width = icd->user_width;
186 vb->height = icd->height; 186 vb->height = icd->user_height;
187 vb->field = field; 187 vb->field = field;
188 vb->state = VIDEOBUF_NEEDS_INIT; 188 vb->state = VIDEOBUF_NEEDS_INIT;
189 } 189 }
@@ -216,10 +216,11 @@ out:
216static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev) 216static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
217{ 217{
218 struct videobuf_buffer *vbuf = &pcdev->active->vb; 218 struct videobuf_buffer *vbuf = &pcdev->active->vb;
219 struct device *dev = pcdev->icd->dev.parent;
219 int ret; 220 int ret;
220 221
221 if (unlikely(!pcdev->active)) { 222 if (unlikely(!pcdev->active)) {
222 dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); 223 dev_err(dev, "DMA End IRQ with no active buffer\n");
223 return -EFAULT; 224 return -EFAULT;
224 } 225 }
225 226
@@ -229,7 +230,7 @@ static int mx1_camera_setup_dma(struct mx1_camera_dev *pcdev)
229 vbuf->size, pcdev->res->start + 230 vbuf->size, pcdev->res->start +
230 CSIRXR, DMA_MODE_READ); 231 CSIRXR, DMA_MODE_READ);
231 if (unlikely(ret)) 232 if (unlikely(ret))
232 dev_err(pcdev->soc_host.dev, "Failed to setup DMA sg list\n"); 233 dev_err(dev, "Failed to setup DMA sg list\n");
233 234
234 return ret; 235 return ret;
235} 236}
@@ -243,7 +244,7 @@ static void mx1_videobuf_queue(struct videobuf_queue *vq,
243 struct mx1_camera_dev *pcdev = ici->priv; 244 struct mx1_camera_dev *pcdev = ici->priv;
244 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 245 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
245 246
246 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 247 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
247 vb, vb->baddr, vb->bsize); 248 vb, vb->baddr, vb->bsize);
248 249
249 list_add_tail(&vb->queue, &pcdev->capture); 250 list_add_tail(&vb->queue, &pcdev->capture);
@@ -270,22 +271,23 @@ static void mx1_videobuf_release(struct videobuf_queue *vq,
270 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb); 271 struct mx1_buffer *buf = container_of(vb, struct mx1_buffer, vb);
271#ifdef DEBUG 272#ifdef DEBUG
272 struct soc_camera_device *icd = vq->priv_data; 273 struct soc_camera_device *icd = vq->priv_data;
274 struct device *dev = icd->dev.parent;
273 275
274 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 276 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
275 vb, vb->baddr, vb->bsize); 277 vb, vb->baddr, vb->bsize);
276 278
277 switch (vb->state) { 279 switch (vb->state) {
278 case VIDEOBUF_ACTIVE: 280 case VIDEOBUF_ACTIVE:
279 dev_dbg(&icd->dev, "%s (active)\n", __func__); 281 dev_dbg(dev, "%s (active)\n", __func__);
280 break; 282 break;
281 case VIDEOBUF_QUEUED: 283 case VIDEOBUF_QUEUED:
282 dev_dbg(&icd->dev, "%s (queued)\n", __func__); 284 dev_dbg(dev, "%s (queued)\n", __func__);
283 break; 285 break;
284 case VIDEOBUF_PREPARED: 286 case VIDEOBUF_PREPARED:
285 dev_dbg(&icd->dev, "%s (prepared)\n", __func__); 287 dev_dbg(dev, "%s (prepared)\n", __func__);
286 break; 288 break;
287 default: 289 default:
288 dev_dbg(&icd->dev, "%s (unknown)\n", __func__); 290 dev_dbg(dev, "%s (unknown)\n", __func__);
289 break; 291 break;
290 } 292 }
291#endif 293#endif
@@ -325,6 +327,7 @@ static void mx1_camera_wakeup(struct mx1_camera_dev *pcdev,
325static void mx1_camera_dma_irq(int channel, void *data) 327static void mx1_camera_dma_irq(int channel, void *data)
326{ 328{
327 struct mx1_camera_dev *pcdev = data; 329 struct mx1_camera_dev *pcdev = data;
330 struct device *dev = pcdev->icd->dev.parent;
328 struct mx1_buffer *buf; 331 struct mx1_buffer *buf;
329 struct videobuf_buffer *vb; 332 struct videobuf_buffer *vb;
330 unsigned long flags; 333 unsigned long flags;
@@ -334,14 +337,14 @@ static void mx1_camera_dma_irq(int channel, void *data)
334 imx_dma_disable(channel); 337 imx_dma_disable(channel);
335 338
336 if (unlikely(!pcdev->active)) { 339 if (unlikely(!pcdev->active)) {
337 dev_err(pcdev->soc_host.dev, "DMA End IRQ with no active buffer\n"); 340 dev_err(dev, "DMA End IRQ with no active buffer\n");
338 goto out; 341 goto out;
339 } 342 }
340 343
341 vb = &pcdev->active->vb; 344 vb = &pcdev->active->vb;
342 buf = container_of(vb, struct mx1_buffer, vb); 345 buf = container_of(vb, struct mx1_buffer, vb);
343 WARN_ON(buf->inwork || list_empty(&vb->queue)); 346 WARN_ON(buf->inwork || list_empty(&vb->queue));
344 dev_dbg(pcdev->soc_host.dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 347 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
345 vb, vb->baddr, vb->bsize); 348 vb, vb->baddr, vb->bsize);
346 349
347 mx1_camera_wakeup(pcdev, vb, buf); 350 mx1_camera_wakeup(pcdev, vb, buf);
@@ -362,7 +365,7 @@ static void mx1_camera_init_videobuf(struct videobuf_queue *q,
362 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 365 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
363 struct mx1_camera_dev *pcdev = ici->priv; 366 struct mx1_camera_dev *pcdev = ici->priv;
364 367
365 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, ici->dev, 368 videobuf_queue_dma_contig_init(q, &mx1_videobuf_ops, icd->dev.parent,
366 &pcdev->lock, 369 &pcdev->lock,
367 V4L2_BUF_TYPE_VIDEO_CAPTURE, 370 V4L2_BUF_TYPE_VIDEO_CAPTURE,
368 V4L2_FIELD_NONE, 371 V4L2_FIELD_NONE,
@@ -381,8 +384,9 @@ static int mclk_get_divisor(struct mx1_camera_dev *pcdev)
381 * they get a nice Oops */ 384 * they get a nice Oops */
382 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1; 385 div = (lcdclk + 2 * mclk - 1) / (2 * mclk) - 1;
383 386
384 dev_dbg(pcdev->soc_host.dev, "System clock %lukHz, target freq %dkHz, " 387 dev_dbg(pcdev->icd->dev.parent,
385 "divisor %lu\n", lcdclk / 1000, mclk / 1000, div); 388 "System clock %lukHz, target freq %dkHz, divisor %lu\n",
389 lcdclk / 1000, mclk / 1000, div);
386 390
387 return div; 391 return div;
388} 392}
@@ -391,7 +395,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
391{ 395{
392 unsigned int csicr1 = CSICR1_EN; 396 unsigned int csicr1 = CSICR1_EN;
393 397
394 dev_dbg(pcdev->soc_host.dev, "Activate device\n"); 398 dev_dbg(pcdev->icd->dev.parent, "Activate device\n");
395 399
396 clk_enable(pcdev->clk); 400 clk_enable(pcdev->clk);
397 401
@@ -407,7 +411,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev)
407 411
408static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) 412static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev)
409{ 413{
410 dev_dbg(pcdev->soc_host.dev, "Deactivate device\n"); 414 dev_dbg(pcdev->icd->dev.parent, "Deactivate device\n");
411 415
412 /* Disable all CSI interface */ 416 /* Disable all CSI interface */
413 __raw_writel(0x00, pcdev->base + CSICR1); 417 __raw_writel(0x00, pcdev->base + CSICR1);
@@ -428,14 +432,12 @@ static int mx1_camera_add_device(struct soc_camera_device *icd)
428 goto ebusy; 432 goto ebusy;
429 } 433 }
430 434
431 dev_info(&icd->dev, "MX1 Camera driver attached to camera %d\n", 435 dev_info(icd->dev.parent, "MX1 Camera driver attached to camera %d\n",
432 icd->devnum); 436 icd->devnum);
433 437
434 mx1_camera_activate(pcdev); 438 mx1_camera_activate(pcdev);
435 ret = icd->ops->init(icd);
436 439
437 if (!ret) 440 pcdev->icd = icd;
438 pcdev->icd = icd;
439 441
440ebusy: 442ebusy:
441 return ret; 443 return ret;
@@ -456,20 +458,20 @@ static void mx1_camera_remove_device(struct soc_camera_device *icd)
456 /* Stop DMA engine */ 458 /* Stop DMA engine */
457 imx_dma_disable(pcdev->dma_chan); 459 imx_dma_disable(pcdev->dma_chan);
458 460
459 dev_info(&icd->dev, "MX1 Camera driver detached from camera %d\n", 461 dev_info(icd->dev.parent, "MX1 Camera driver detached from camera %d\n",
460 icd->devnum); 462 icd->devnum);
461 463
462 icd->ops->release(icd);
463
464 mx1_camera_deactivate(pcdev); 464 mx1_camera_deactivate(pcdev);
465 465
466 pcdev->icd = NULL; 466 pcdev->icd = NULL;
467} 467}
468 468
469static int mx1_camera_set_crop(struct soc_camera_device *icd, 469static int mx1_camera_set_crop(struct soc_camera_device *icd,
470 struct v4l2_rect *rect) 470 struct v4l2_crop *a)
471{ 471{
472 return icd->ops->set_crop(icd, rect); 472 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
473
474 return v4l2_subdev_call(sd, video, s_crop, a);
473} 475}
474 476
475static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 477static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
@@ -539,18 +541,19 @@ static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
539static int mx1_camera_set_fmt(struct soc_camera_device *icd, 541static int mx1_camera_set_fmt(struct soc_camera_device *icd,
540 struct v4l2_format *f) 542 struct v4l2_format *f)
541{ 543{
542 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 544 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
543 const struct soc_camera_format_xlate *xlate; 545 const struct soc_camera_format_xlate *xlate;
544 struct v4l2_pix_format *pix = &f->fmt.pix; 546 struct v4l2_pix_format *pix = &f->fmt.pix;
545 int ret; 547 int ret;
546 548
547 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 549 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
548 if (!xlate) { 550 if (!xlate) {
549 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); 551 dev_warn(icd->dev.parent, "Format %x not found\n",
552 pix->pixelformat);
550 return -EINVAL; 553 return -EINVAL;
551 } 554 }
552 555
553 ret = icd->ops->set_fmt(icd, f); 556 ret = v4l2_subdev_call(sd, video, s_fmt, f);
554 if (!ret) { 557 if (!ret) {
555 icd->buswidth = xlate->buswidth; 558 icd->buswidth = xlate->buswidth;
556 icd->current_fmt = xlate->host_fmt; 559 icd->current_fmt = xlate->host_fmt;
@@ -562,10 +565,11 @@ static int mx1_camera_set_fmt(struct soc_camera_device *icd,
562static int mx1_camera_try_fmt(struct soc_camera_device *icd, 565static int mx1_camera_try_fmt(struct soc_camera_device *icd,
563 struct v4l2_format *f) 566 struct v4l2_format *f)
564{ 567{
568 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
565 /* TODO: limit to mx1 hardware capabilities */ 569 /* TODO: limit to mx1 hardware capabilities */
566 570
567 /* limit to sensor capabilities */ 571 /* limit to sensor capabilities */
568 return icd->ops->try_fmt(icd, f); 572 return v4l2_subdev_call(sd, video, try_fmt, f);
569} 573}
570 574
571static int mx1_camera_reqbufs(struct soc_camera_file *icf, 575static int mx1_camera_reqbufs(struct soc_camera_file *icf,
@@ -737,7 +741,7 @@ static int __init mx1_camera_probe(struct platform_device *pdev)
737 pcdev->soc_host.drv_name = DRIVER_NAME; 741 pcdev->soc_host.drv_name = DRIVER_NAME;
738 pcdev->soc_host.ops = &mx1_soc_camera_host_ops; 742 pcdev->soc_host.ops = &mx1_soc_camera_host_ops;
739 pcdev->soc_host.priv = pcdev; 743 pcdev->soc_host.priv = pcdev;
740 pcdev->soc_host.dev = &pdev->dev; 744 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
741 pcdev->soc_host.nr = pdev->id; 745 pcdev->soc_host.nr = pdev->id;
742 err = soc_camera_host_register(&pcdev->soc_host); 746 err = soc_camera_host_register(&pcdev->soc_host);
743 if (err) 747 if (err)
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index 9770cb7932ca..dff2e5e2d8c6 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -178,7 +178,7 @@ static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf
178 178
179 BUG_ON(in_interrupt()); 179 BUG_ON(in_interrupt());
180 180
181 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 181 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
182 vb, vb->baddr, vb->bsize); 182 vb, vb->baddr, vb->bsize);
183 183
184 /* 184 /*
@@ -220,7 +220,7 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
220 if (!mx3_cam->idmac_channel[0]) 220 if (!mx3_cam->idmac_channel[0])
221 return -EINVAL; 221 return -EINVAL;
222 222
223 *size = icd->width * icd->height * bpp; 223 *size = icd->user_width * icd->user_height * bpp;
224 224
225 if (!*count) 225 if (!*count)
226 *count = 32; 226 *count = 32;
@@ -241,7 +241,7 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
241 struct mx3_camera_buffer *buf = 241 struct mx3_camera_buffer *buf =
242 container_of(vb, struct mx3_camera_buffer, vb); 242 container_of(vb, struct mx3_camera_buffer, vb);
243 /* current_fmt _must_ always be set */ 243 /* current_fmt _must_ always be set */
244 size_t new_size = icd->width * icd->height * 244 size_t new_size = icd->user_width * icd->user_height *
245 ((icd->current_fmt->depth + 7) >> 3); 245 ((icd->current_fmt->depth + 7) >> 3);
246 int ret; 246 int ret;
247 247
@@ -251,12 +251,12 @@ static int mx3_videobuf_prepare(struct videobuf_queue *vq,
251 */ 251 */
252 252
253 if (buf->fmt != icd->current_fmt || 253 if (buf->fmt != icd->current_fmt ||
254 vb->width != icd->width || 254 vb->width != icd->user_width ||
255 vb->height != icd->height || 255 vb->height != icd->user_height ||
256 vb->field != field) { 256 vb->field != field) {
257 buf->fmt = icd->current_fmt; 257 buf->fmt = icd->current_fmt;
258 vb->width = icd->width; 258 vb->width = icd->user_width;
259 vb->height = icd->height; 259 vb->height = icd->user_height;
260 vb->field = field; 260 vb->field = field;
261 if (vb->state != VIDEOBUF_NEEDS_INIT) 261 if (vb->state != VIDEOBUF_NEEDS_INIT)
262 free_buffer(vq, buf); 262 free_buffer(vq, buf);
@@ -354,9 +354,9 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
354 354
355 /* This is the configuration of one sg-element */ 355 /* This is the configuration of one sg-element */
356 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); 356 video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc);
357 video->out_width = icd->width; 357 video->out_width = icd->user_width;
358 video->out_height = icd->height; 358 video->out_height = icd->user_height;
359 video->out_stride = icd->width; 359 video->out_stride = icd->user_width;
360 360
361#ifdef DEBUG 361#ifdef DEBUG
362 /* helps to see what DMA actually has written */ 362 /* helps to see what DMA actually has written */
@@ -375,7 +375,8 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
375 spin_unlock_irq(&mx3_cam->lock); 375 spin_unlock_irq(&mx3_cam->lock);
376 376
377 cookie = txd->tx_submit(txd); 377 cookie = txd->tx_submit(txd);
378 dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg)); 378 dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n",
379 cookie, sg_dma_address(&buf->sg));
379 380
380 spin_lock_irq(&mx3_cam->lock); 381 spin_lock_irq(&mx3_cam->lock);
381 382
@@ -402,9 +403,10 @@ static void mx3_videobuf_release(struct videobuf_queue *vq,
402 container_of(vb, struct mx3_camera_buffer, vb); 403 container_of(vb, struct mx3_camera_buffer, vb);
403 unsigned long flags; 404 unsigned long flags;
404 405
405 dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n", 406 dev_dbg(icd->dev.parent,
407 "Release%s DMA 0x%08x (state %d), queue %sempty\n",
406 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg), 408 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
407 vb->state, list_empty(&vb->queue) ? "" : "not "); 409 vb->state, list_empty(&vb->queue) ? "" : "not ");
408 spin_lock_irqsave(&mx3_cam->lock, flags); 410 spin_lock_irqsave(&mx3_cam->lock, flags);
409 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && 411 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
410 !list_empty(&vb->queue)) { 412 !list_empty(&vb->queue)) {
@@ -431,7 +433,7 @@ static void mx3_camera_init_videobuf(struct videobuf_queue *q,
431 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 433 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
432 struct mx3_camera_dev *mx3_cam = ici->priv; 434 struct mx3_camera_dev *mx3_cam = ici->priv;
433 435
434 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, ici->dev, 436 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, icd->dev.parent,
435 &mx3_cam->lock, 437 &mx3_cam->lock,
436 V4L2_BUF_TYPE_VIDEO_CAPTURE, 438 V4L2_BUF_TYPE_VIDEO_CAPTURE,
437 V4L2_FIELD_NONE, 439 V4L2_FIELD_NONE,
@@ -484,7 +486,7 @@ static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam,
484 486
485 clk_enable(mx3_cam->clk); 487 clk_enable(mx3_cam->clk);
486 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk); 488 rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk);
487 dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate); 489 dev_dbg(icd->dev.parent, "Set SENS_CONF to %x, rate %ld\n", conf, rate);
488 if (rate) 490 if (rate)
489 clk_set_rate(mx3_cam->clk, rate); 491 clk_set_rate(mx3_cam->clk, rate);
490} 492}
@@ -494,29 +496,18 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
494{ 496{
495 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 497 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
496 struct mx3_camera_dev *mx3_cam = ici->priv; 498 struct mx3_camera_dev *mx3_cam = ici->priv;
497 int ret;
498 499
499 if (mx3_cam->icd) { 500 if (mx3_cam->icd)
500 ret = -EBUSY; 501 return -EBUSY;
501 goto ebusy;
502 }
503 502
504 mx3_camera_activate(mx3_cam, icd); 503 mx3_camera_activate(mx3_cam, icd);
505 ret = icd->ops->init(icd);
506 if (ret < 0) {
507 clk_disable(mx3_cam->clk);
508 goto einit;
509 }
510 504
511 mx3_cam->icd = icd; 505 mx3_cam->icd = icd;
512 506
513einit: 507 dev_info(icd->dev.parent, "MX3 Camera driver attached to camera %d\n",
514ebusy: 508 icd->devnum);
515 if (!ret)
516 dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n",
517 icd->devnum);
518 509
519 return ret; 510 return 0;
520} 511}
521 512
522/* Called with .video_lock held */ 513/* Called with .video_lock held */
@@ -533,13 +524,11 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
533 *ichan = NULL; 524 *ichan = NULL;
534 } 525 }
535 526
536 icd->ops->release(icd);
537
538 clk_disable(mx3_cam->clk); 527 clk_disable(mx3_cam->clk);
539 528
540 mx3_cam->icd = NULL; 529 mx3_cam->icd = NULL;
541 530
542 dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n", 531 dev_info(icd->dev.parent, "MX3 Camera driver detached from camera %d\n",
543 icd->devnum); 532 icd->devnum);
544} 533}
545 534
@@ -551,7 +540,8 @@ static bool channel_change_requested(struct soc_camera_device *icd,
551 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 540 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
552 541
553 /* Do buffers have to be re-allocated or channel re-configured? */ 542 /* Do buffers have to be re-allocated or channel re-configured? */
554 return ichan && rect->width * rect->height > icd->width * icd->height; 543 return ichan && rect->width * rect->height >
544 icd->user_width * icd->user_height;
555} 545}
556 546
557static int test_platform_param(struct mx3_camera_dev *mx3_cam, 547static int test_platform_param(struct mx3_camera_dev *mx3_cam,
@@ -599,8 +589,8 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
599 *flags |= SOCAM_DATAWIDTH_4; 589 *flags |= SOCAM_DATAWIDTH_4;
600 break; 590 break;
601 default: 591 default:
602 dev_info(mx3_cam->soc_host.dev, "Unsupported bus width %d\n", 592 dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
603 buswidth); 593 "Unsupported bus width %d\n", buswidth);
604 return -EINVAL; 594 return -EINVAL;
605 } 595 }
606 596
@@ -615,7 +605,7 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
615 unsigned long bus_flags, camera_flags; 605 unsigned long bus_flags, camera_flags;
616 int ret = test_platform_param(mx3_cam, depth, &bus_flags); 606 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
617 607
618 dev_dbg(ici->dev, "requested bus width %d bit: %d\n", depth, ret); 608 dev_dbg(icd->dev.parent, "request bus width %d bit: %d\n", depth, ret);
619 609
620 if (ret < 0) 610 if (ret < 0)
621 return ret; 611 return ret;
@@ -624,7 +614,8 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
624 614
625 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); 615 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags);
626 if (ret < 0) 616 if (ret < 0)
627 dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n", 617 dev_warn(icd->dev.parent,
618 "Flags incompatible: camera %lx, host %lx\n",
628 camera_flags, bus_flags); 619 camera_flags, bus_flags);
629 620
630 return ret; 621 return ret;
@@ -638,7 +629,7 @@ static bool chan_filter(struct dma_chan *chan, void *arg)
638 if (!rq) 629 if (!rq)
639 return false; 630 return false;
640 631
641 pdata = rq->mx3_cam->soc_host.dev->platform_data; 632 pdata = rq->mx3_cam->soc_host.v4l2_dev.dev->platform_data;
642 633
643 return rq->id == chan->chan_id && 634 return rq->id == chan->chan_id &&
644 pdata->dma_dev == chan->device->dev; 635 pdata->dma_dev == chan->device->dev;
@@ -698,7 +689,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
698 xlate->cam_fmt = icd->formats + idx; 689 xlate->cam_fmt = icd->formats + idx;
699 xlate->buswidth = buswidth; 690 xlate->buswidth = buswidth;
700 xlate++; 691 xlate++;
701 dev_dbg(ici->dev, "Providing format %s using %s\n", 692 dev_dbg(icd->dev.parent,
693 "Providing format %s using %s\n",
702 mx3_camera_formats[0].name, 694 mx3_camera_formats[0].name,
703 icd->formats[idx].name); 695 icd->formats[idx].name);
704 } 696 }
@@ -710,7 +702,8 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx,
710 xlate->cam_fmt = icd->formats + idx; 702 xlate->cam_fmt = icd->formats + idx;
711 xlate->buswidth = buswidth; 703 xlate->buswidth = buswidth;
712 xlate++; 704 xlate++;
713 dev_dbg(ici->dev, "Providing format %s using %s\n", 705 dev_dbg(icd->dev.parent,
706 "Providing format %s using %s\n",
714 mx3_camera_formats[0].name, 707 mx3_camera_formats[0].name,
715 icd->formats[idx].name); 708 icd->formats[idx].name);
716 } 709 }
@@ -723,7 +716,7 @@ passthrough:
723 xlate->cam_fmt = icd->formats + idx; 716 xlate->cam_fmt = icd->formats + idx;
724 xlate->buswidth = buswidth; 717 xlate->buswidth = buswidth;
725 xlate++; 718 xlate++;
726 dev_dbg(ici->dev, 719 dev_dbg(icd->dev.parent,
727 "Providing format %s in pass-through mode\n", 720 "Providing format %s in pass-through mode\n",
728 icd->formats[idx].name); 721 icd->formats[idx].name);
729 } 722 }
@@ -733,13 +726,13 @@ passthrough:
733} 726}
734 727
735static void configure_geometry(struct mx3_camera_dev *mx3_cam, 728static void configure_geometry(struct mx3_camera_dev *mx3_cam,
736 struct v4l2_rect *rect) 729 unsigned int width, unsigned int height)
737{ 730{
738 u32 ctrl, width_field, height_field; 731 u32 ctrl, width_field, height_field;
739 732
740 /* Setup frame size - this cannot be changed on-the-fly... */ 733 /* Setup frame size - this cannot be changed on-the-fly... */
741 width_field = rect->width - 1; 734 width_field = width - 1;
742 height_field = rect->height - 1; 735 height_field = height - 1;
743 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE); 736 csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE);
744 737
745 csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1); 738 csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1);
@@ -751,11 +744,6 @@ static void configure_geometry(struct mx3_camera_dev *mx3_cam,
751 ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000; 744 ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000;
752 /* Sensor does the cropping */ 745 /* Sensor does the cropping */
753 csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL); 746 csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL);
754
755 /*
756 * No need to free resources here if we fail, we'll see if we need to
757 * do this next time we are called
758 */
759} 747}
760 748
761static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam) 749static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
@@ -792,25 +780,74 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
792 return 0; 780 return 0;
793} 781}
794 782
783/*
784 * FIXME: learn to use stride != width, then we can keep stride properly aligned
785 * and support arbitrary (even) widths.
786 */
787static inline void stride_align(__s32 *width)
788{
789 if (((*width + 7) & ~7) < 4096)
790 *width = (*width + 7) & ~7;
791 else
792 *width = *width & ~7;
793}
794
795/*
796 * As long as we don't implement host-side cropping and scaling, we can use
797 * default g_crop and cropcap from soc_camera.c
798 */
795static int mx3_camera_set_crop(struct soc_camera_device *icd, 799static int mx3_camera_set_crop(struct soc_camera_device *icd,
796 struct v4l2_rect *rect) 800 struct v4l2_crop *a)
797{ 801{
802 struct v4l2_rect *rect = &a->c;
798 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 803 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
799 struct mx3_camera_dev *mx3_cam = ici->priv; 804 struct mx3_camera_dev *mx3_cam = ici->priv;
805 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
806 struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
807 struct v4l2_pix_format *pix = &f.fmt.pix;
808 int ret;
800 809
801 /* 810 soc_camera_limit_side(&rect->left, &rect->width, 0, 2, 4096);
802 * We now know pixel formats and can decide upon DMA-channel(s) 811 soc_camera_limit_side(&rect->top, &rect->height, 0, 2, 4096);
803 * So far only direct camera-to-memory is supported 812
804 */ 813 ret = v4l2_subdev_call(sd, video, s_crop, a);
805 if (channel_change_requested(icd, rect)) { 814 if (ret < 0)
806 int ret = acquire_dma_channel(mx3_cam); 815 return ret;
816
817 /* The capture device might have changed its output */
818 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
819 if (ret < 0)
820 return ret;
821
822 if (pix->width & 7) {
823 /* Ouch! We can only handle 8-byte aligned width... */
824 stride_align(&pix->width);
825 ret = v4l2_subdev_call(sd, video, s_fmt, &f);
807 if (ret < 0) 826 if (ret < 0)
808 return ret; 827 return ret;
809 } 828 }
810 829
811 configure_geometry(mx3_cam, rect); 830 if (pix->width != icd->user_width || pix->height != icd->user_height) {
831 /*
832 * We now know pixel formats and can decide upon DMA-channel(s)
833 * So far only direct camera-to-memory is supported
834 */
835 if (channel_change_requested(icd, rect)) {
836 int ret = acquire_dma_channel(mx3_cam);
837 if (ret < 0)
838 return ret;
839 }
840
841 configure_geometry(mx3_cam, pix->width, pix->height);
842 }
843
844 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
845 pix->width, pix->height);
812 846
813 return icd->ops->set_crop(icd, rect); 847 icd->user_width = pix->width;
848 icd->user_height = pix->height;
849
850 return ret;
814} 851}
815 852
816static int mx3_camera_set_fmt(struct soc_camera_device *icd, 853static int mx3_camera_set_fmt(struct soc_camera_device *icd,
@@ -818,22 +855,21 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
818{ 855{
819 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 856 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
820 struct mx3_camera_dev *mx3_cam = ici->priv; 857 struct mx3_camera_dev *mx3_cam = ici->priv;
858 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
821 const struct soc_camera_format_xlate *xlate; 859 const struct soc_camera_format_xlate *xlate;
822 struct v4l2_pix_format *pix = &f->fmt.pix; 860 struct v4l2_pix_format *pix = &f->fmt.pix;
823 struct v4l2_rect rect = {
824 .left = icd->x_current,
825 .top = icd->y_current,
826 .width = pix->width,
827 .height = pix->height,
828 };
829 int ret; 861 int ret;
830 862
831 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 863 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
832 if (!xlate) { 864 if (!xlate) {
833 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); 865 dev_warn(icd->dev.parent, "Format %x not found\n",
866 pix->pixelformat);
834 return -EINVAL; 867 return -EINVAL;
835 } 868 }
836 869
870 stride_align(&pix->width);
871 dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height);
872
837 ret = acquire_dma_channel(mx3_cam); 873 ret = acquire_dma_channel(mx3_cam);
838 if (ret < 0) 874 if (ret < 0)
839 return ret; 875 return ret;
@@ -844,21 +880,23 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
844 * mxc_v4l2_s_fmt() 880 * mxc_v4l2_s_fmt()
845 */ 881 */
846 882
847 configure_geometry(mx3_cam, &rect); 883 configure_geometry(mx3_cam, pix->width, pix->height);
848 884
849 ret = icd->ops->set_fmt(icd, f); 885 ret = v4l2_subdev_call(sd, video, s_fmt, f);
850 if (!ret) { 886 if (!ret) {
851 icd->buswidth = xlate->buswidth; 887 icd->buswidth = xlate->buswidth;
852 icd->current_fmt = xlate->host_fmt; 888 icd->current_fmt = xlate->host_fmt;
853 } 889 }
854 890
891 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
892
855 return ret; 893 return ret;
856} 894}
857 895
858static int mx3_camera_try_fmt(struct soc_camera_device *icd, 896static int mx3_camera_try_fmt(struct soc_camera_device *icd,
859 struct v4l2_format *f) 897 struct v4l2_format *f)
860{ 898{
861 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 899 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
862 const struct soc_camera_format_xlate *xlate; 900 const struct soc_camera_format_xlate *xlate;
863 struct v4l2_pix_format *pix = &f->fmt.pix; 901 struct v4l2_pix_format *pix = &f->fmt.pix;
864 __u32 pixfmt = pix->pixelformat; 902 __u32 pixfmt = pix->pixelformat;
@@ -867,7 +905,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
867 905
868 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 906 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
869 if (pixfmt && !xlate) { 907 if (pixfmt && !xlate) {
870 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 908 dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
871 return -EINVAL; 909 return -EINVAL;
872 } 910 }
873 911
@@ -884,7 +922,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
884 /* camera has to see its format, but the user the original one */ 922 /* camera has to see its format, but the user the original one */
885 pix->pixelformat = xlate->cam_fmt->fourcc; 923 pix->pixelformat = xlate->cam_fmt->fourcc;
886 /* limit to sensor capabilities */ 924 /* limit to sensor capabilities */
887 ret = icd->ops->try_fmt(icd, f); 925 ret = v4l2_subdev_call(sd, video, try_fmt, f);
888 pix->pixelformat = xlate->host_fmt->fourcc; 926 pix->pixelformat = xlate->host_fmt->fourcc;
889 927
890 field = pix->field; 928 field = pix->field;
@@ -892,7 +930,7 @@ static int mx3_camera_try_fmt(struct soc_camera_device *icd,
892 if (field == V4L2_FIELD_ANY) { 930 if (field == V4L2_FIELD_ANY) {
893 pix->field = V4L2_FIELD_NONE; 931 pix->field = V4L2_FIELD_NONE;
894 } else if (field != V4L2_FIELD_NONE) { 932 } else if (field != V4L2_FIELD_NONE) {
895 dev_err(&icd->dev, "Field type %d unsupported.\n", field); 933 dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
896 return -EINVAL; 934 return -EINVAL;
897 } 935 }
898 936
@@ -931,14 +969,15 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
931 u32 dw, sens_conf; 969 u32 dw, sens_conf;
932 int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); 970 int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags);
933 const struct soc_camera_format_xlate *xlate; 971 const struct soc_camera_format_xlate *xlate;
972 struct device *dev = icd->dev.parent;
934 973
935 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 974 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
936 if (!xlate) { 975 if (!xlate) {
937 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 976 dev_warn(dev, "Format %x not found\n", pixfmt);
938 return -EINVAL; 977 return -EINVAL;
939 } 978 }
940 979
941 dev_dbg(ici->dev, "requested bus width %d bit: %d\n", 980 dev_dbg(dev, "requested bus width %d bit: %d\n",
942 icd->buswidth, ret); 981 icd->buswidth, ret);
943 982
944 if (ret < 0) 983 if (ret < 0)
@@ -947,9 +986,10 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
947 camera_flags = icd->ops->query_bus_param(icd); 986 camera_flags = icd->ops->query_bus_param(icd);
948 987
949 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 988 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
989 dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
990 camera_flags, bus_flags, common_flags);
950 if (!common_flags) { 991 if (!common_flags) {
951 dev_dbg(ici->dev, "no common flags: camera %lx, host %lx\n", 992 dev_dbg(dev, "no common flags");
952 camera_flags, bus_flags);
953 return -EINVAL; 993 return -EINVAL;
954 } 994 }
955 995
@@ -1002,8 +1042,11 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1002 SOCAM_DATAWIDTH_4; 1042 SOCAM_DATAWIDTH_4;
1003 1043
1004 ret = icd->ops->set_bus_param(icd, common_flags); 1044 ret = icd->ops->set_bus_param(icd, common_flags);
1005 if (ret < 0) 1045 if (ret < 0) {
1046 dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n",
1047 common_flags, ret);
1006 return ret; 1048 return ret;
1049 }
1007 1050
1008 /* 1051 /*
1009 * So far only gated clock mode is supported. Add a line 1052 * So far only gated clock mode is supported. Add a line
@@ -1055,7 +1098,7 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1055 1098
1056 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); 1099 csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF);
1057 1100
1058 dev_dbg(ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); 1101 dev_dbg(dev, "Set SENS_CONF to %x\n", sens_conf | dw);
1059 1102
1060 return 0; 1103 return 0;
1061} 1104}
@@ -1127,8 +1170,9 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1127 INIT_LIST_HEAD(&mx3_cam->capture); 1170 INIT_LIST_HEAD(&mx3_cam->capture);
1128 spin_lock_init(&mx3_cam->lock); 1171 spin_lock_init(&mx3_cam->lock);
1129 1172
1130 base = ioremap(res->start, res->end - res->start + 1); 1173 base = ioremap(res->start, resource_size(res));
1131 if (!base) { 1174 if (!base) {
1175 pr_err("Couldn't map %x@%x\n", resource_size(res), res->start);
1132 err = -ENOMEM; 1176 err = -ENOMEM;
1133 goto eioremap; 1177 goto eioremap;
1134 } 1178 }
@@ -1139,7 +1183,7 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1139 soc_host->drv_name = MX3_CAM_DRV_NAME; 1183 soc_host->drv_name = MX3_CAM_DRV_NAME;
1140 soc_host->ops = &mx3_soc_camera_host_ops; 1184 soc_host->ops = &mx3_soc_camera_host_ops;
1141 soc_host->priv = mx3_cam; 1185 soc_host->priv = mx3_cam;
1142 soc_host->dev = &pdev->dev; 1186 soc_host->v4l2_dev.dev = &pdev->dev;
1143 soc_host->nr = pdev->id; 1187 soc_host->nr = pdev->id;
1144 1188
1145 err = soc_camera_host_register(soc_host); 1189 err = soc_camera_host_register(soc_host);
@@ -1215,3 +1259,4 @@ module_exit(mx3_camera_exit);
1215MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver"); 1259MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver");
1216MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>"); 1260MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");
1217MODULE_LICENSE("GPL v2"); 1261MODULE_LICENSE("GPL v2");
1262MODULE_ALIAS("platform:" MX3_CAM_DRV_NAME);
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index 35890e8b2431..3454070e63f0 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -186,19 +186,19 @@ static int mxb_probe(struct saa7146_dev *dev)
186 } 186 }
187 187
188 mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 188 mxb->saa7111a = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
189 "saa7115", "saa7111", I2C_SAA7111A); 189 "saa7115", "saa7111", I2C_SAA7111A, NULL);
190 mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 190 mxb->tea6420_1 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
191 "tea6420", "tea6420", I2C_TEA6420_1); 191 "tea6420", "tea6420", I2C_TEA6420_1, NULL);
192 mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 192 mxb->tea6420_2 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
193 "tea6420", "tea6420", I2C_TEA6420_2); 193 "tea6420", "tea6420", I2C_TEA6420_2, NULL);
194 mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 194 mxb->tea6415c = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
195 "tea6415c", "tea6415c", I2C_TEA6415C); 195 "tea6415c", "tea6415c", I2C_TEA6415C, NULL);
196 mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 196 mxb->tda9840 = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
197 "tda9840", "tda9840", I2C_TDA9840); 197 "tda9840", "tda9840", I2C_TDA9840, NULL);
198 mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 198 mxb->tuner = v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
199 "tuner", "tuner", I2C_TUNER); 199 "tuner", "tuner", I2C_TUNER, NULL);
200 if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter, 200 if (v4l2_i2c_new_subdev(&dev->v4l2_dev, &mxb->i2c_adapter,
201 "saa5246a", "saa5246a", I2C_SAA5246A)) { 201 "saa5246a", "saa5246a", I2C_SAA5246A, NULL)) {
202 printk(KERN_INFO "mxb: found teletext decoder\n"); 202 printk(KERN_INFO "mxb: found teletext decoder\n");
203 } 203 }
204 204
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 0bce255168bd..eccb40ab7fec 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -22,7 +22,7 @@
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/videodev2.h> 23#include <linux/videodev2.h>
24#include <media/v4l2-chip-ident.h> 24#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-common.h> 25#include <media/v4l2-subdev.h>
26#include <media/soc_camera.h> 26#include <media/soc_camera.h>
27#include <media/ov772x.h> 27#include <media/ov772x.h>
28 28
@@ -382,11 +382,10 @@ struct regval_list {
382}; 382};
383 383
384struct ov772x_color_format { 384struct ov772x_color_format {
385 char *name; 385 const struct soc_camera_data_format *format;
386 __u32 fourcc; 386 u8 dsp3;
387 u8 dsp3; 387 u8 com3;
388 u8 com3; 388 u8 com7;
389 u8 com7;
390}; 389};
391 390
392struct ov772x_win_size { 391struct ov772x_win_size {
@@ -398,14 +397,15 @@ struct ov772x_win_size {
398}; 397};
399 398
400struct ov772x_priv { 399struct ov772x_priv {
400 struct v4l2_subdev subdev;
401 struct ov772x_camera_info *info; 401 struct ov772x_camera_info *info;
402 struct i2c_client *client;
403 struct soc_camera_device icd;
404 const struct ov772x_color_format *fmt; 402 const struct ov772x_color_format *fmt;
405 const struct ov772x_win_size *win; 403 const struct ov772x_win_size *win;
406 int model; 404 int model;
407 unsigned int flag_vflip:1; 405 unsigned short flag_vflip:1;
408 unsigned int flag_hflip:1; 406 unsigned short flag_hflip:1;
407 /* band_filter = COM8[5] ? 256 - BDBASE : 0 */
408 unsigned short band_filter;
409}; 409};
410 410
411#define ENDMARKER { 0xff, 0xff } 411#define ENDMARKER { 0xff, 0xff }
@@ -481,43 +481,43 @@ static const struct soc_camera_data_format ov772x_fmt_lists[] = {
481 */ 481 */
482static const struct ov772x_color_format ov772x_cfmts[] = { 482static const struct ov772x_color_format ov772x_cfmts[] = {
483 { 483 {
484 SETFOURCC(YUYV), 484 .format = &ov772x_fmt_lists[0],
485 .dsp3 = 0x0, 485 .dsp3 = 0x0,
486 .com3 = SWAP_YUV, 486 .com3 = SWAP_YUV,
487 .com7 = OFMT_YUV, 487 .com7 = OFMT_YUV,
488 }, 488 },
489 { 489 {
490 SETFOURCC(YVYU), 490 .format = &ov772x_fmt_lists[1],
491 .dsp3 = UV_ON, 491 .dsp3 = UV_ON,
492 .com3 = SWAP_YUV, 492 .com3 = SWAP_YUV,
493 .com7 = OFMT_YUV, 493 .com7 = OFMT_YUV,
494 }, 494 },
495 { 495 {
496 SETFOURCC(UYVY), 496 .format = &ov772x_fmt_lists[2],
497 .dsp3 = 0x0, 497 .dsp3 = 0x0,
498 .com3 = 0x0, 498 .com3 = 0x0,
499 .com7 = OFMT_YUV, 499 .com7 = OFMT_YUV,
500 }, 500 },
501 { 501 {
502 SETFOURCC(RGB555), 502 .format = &ov772x_fmt_lists[3],
503 .dsp3 = 0x0, 503 .dsp3 = 0x0,
504 .com3 = SWAP_RGB, 504 .com3 = SWAP_RGB,
505 .com7 = FMT_RGB555 | OFMT_RGB, 505 .com7 = FMT_RGB555 | OFMT_RGB,
506 }, 506 },
507 { 507 {
508 SETFOURCC(RGB555X), 508 .format = &ov772x_fmt_lists[4],
509 .dsp3 = 0x0, 509 .dsp3 = 0x0,
510 .com3 = 0x0, 510 .com3 = 0x0,
511 .com7 = FMT_RGB555 | OFMT_RGB, 511 .com7 = FMT_RGB555 | OFMT_RGB,
512 }, 512 },
513 { 513 {
514 SETFOURCC(RGB565), 514 .format = &ov772x_fmt_lists[5],
515 .dsp3 = 0x0, 515 .dsp3 = 0x0,
516 .com3 = SWAP_RGB, 516 .com3 = SWAP_RGB,
517 .com7 = FMT_RGB565 | OFMT_RGB, 517 .com7 = FMT_RGB565 | OFMT_RGB,
518 }, 518 },
519 { 519 {
520 SETFOURCC(RGB565X), 520 .format = &ov772x_fmt_lists[6],
521 .dsp3 = 0x0, 521 .dsp3 = 0x0,
522 .com3 = 0x0, 522 .com3 = 0x0,
523 .com7 = FMT_RGB565 | OFMT_RGB, 523 .com7 = FMT_RGB565 | OFMT_RGB,
@@ -570,6 +570,15 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
570 .step = 1, 570 .step = 1,
571 .default_value = 0, 571 .default_value = 0,
572 }, 572 },
573 {
574 .id = V4L2_CID_BAND_STOP_FILTER,
575 .type = V4L2_CTRL_TYPE_INTEGER,
576 .name = "Band-stop filter",
577 .minimum = 0,
578 .maximum = 256,
579 .step = 1,
580 .default_value = 0,
581 },
573}; 582};
574 583
575 584
@@ -577,6 +586,12 @@ static const struct v4l2_queryctrl ov772x_controls[] = {
577 * general function 586 * general function
578 */ 587 */
579 588
589static struct ov772x_priv *to_ov772x(const struct i2c_client *client)
590{
591 return container_of(i2c_get_clientdata(client), struct ov772x_priv,
592 subdev);
593}
594
580static int ov772x_write_array(struct i2c_client *client, 595static int ov772x_write_array(struct i2c_client *client,
581 const struct regval_list *vals) 596 const struct regval_list *vals)
582{ 597{
@@ -617,58 +632,29 @@ static int ov772x_reset(struct i2c_client *client)
617 * soc_camera_ops function 632 * soc_camera_ops function
618 */ 633 */
619 634
620static int ov772x_init(struct soc_camera_device *icd) 635static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
621{ 636{
622 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 637 struct i2c_client *client = sd->priv;
623 int ret = 0; 638 struct ov772x_priv *priv = to_ov772x(client);
624 639
625 if (priv->info->link.power) { 640 if (!enable) {
626 ret = priv->info->link.power(&priv->client->dev, 1); 641 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
627 if (ret < 0) 642 return 0;
628 return ret;
629 } 643 }
630 644
631 if (priv->info->link.reset)
632 ret = priv->info->link.reset(&priv->client->dev);
633
634 return ret;
635}
636
637static int ov772x_release(struct soc_camera_device *icd)
638{
639 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
640 int ret = 0;
641
642 if (priv->info->link.power)
643 ret = priv->info->link.power(&priv->client->dev, 0);
644
645 return ret;
646}
647
648static int ov772x_start_capture(struct soc_camera_device *icd)
649{
650 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
651
652 if (!priv->win || !priv->fmt) { 645 if (!priv->win || !priv->fmt) {
653 dev_err(&icd->dev, "norm or win select error\n"); 646 dev_err(&client->dev, "norm or win select error\n");
654 return -EPERM; 647 return -EPERM;
655 } 648 }
656 649
657 ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, 0); 650 ov772x_mask_set(client, COM2, SOFT_SLEEP_MODE, 0);
658 651
659 dev_dbg(&icd->dev, 652 dev_dbg(&client->dev, "format %s, win %s\n",
660 "format %s, win %s\n", priv->fmt->name, priv->win->name); 653 priv->fmt->format->name, priv->win->name);
661 654
662 return 0; 655 return 0;
663} 656}
664 657
665static int ov772x_stop_capture(struct soc_camera_device *icd)
666{
667 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
668 ov772x_mask_set(priv->client, COM2, SOFT_SLEEP_MODE, SOFT_SLEEP_MODE);
669 return 0;
670}
671
672static int ov772x_set_bus_param(struct soc_camera_device *icd, 658static int ov772x_set_bus_param(struct soc_camera_device *icd,
673 unsigned long flags) 659 unsigned long flags)
674{ 660{
@@ -677,8 +663,9 @@ static int ov772x_set_bus_param(struct soc_camera_device *icd,
677 663
678static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd) 664static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
679{ 665{
680 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 666 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
681 struct soc_camera_link *icl = &priv->info->link; 667 struct ov772x_priv *priv = i2c_get_clientdata(client);
668 struct soc_camera_link *icl = to_soc_camera_link(icd);
682 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 669 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
683 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 670 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
684 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 671 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -686,10 +673,10 @@ static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
686 return soc_camera_apply_sensor_flags(icl, flags); 673 return soc_camera_apply_sensor_flags(icl, flags);
687} 674}
688 675
689static int ov772x_get_control(struct soc_camera_device *icd, 676static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
690 struct v4l2_control *ctrl)
691{ 677{
692 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 678 struct i2c_client *client = sd->priv;
679 struct ov772x_priv *priv = to_ov772x(client);
693 680
694 switch (ctrl->id) { 681 switch (ctrl->id) {
695 case V4L2_CID_VFLIP: 682 case V4L2_CID_VFLIP:
@@ -698,14 +685,17 @@ static int ov772x_get_control(struct soc_camera_device *icd,
698 case V4L2_CID_HFLIP: 685 case V4L2_CID_HFLIP:
699 ctrl->value = priv->flag_hflip; 686 ctrl->value = priv->flag_hflip;
700 break; 687 break;
688 case V4L2_CID_BAND_STOP_FILTER:
689 ctrl->value = priv->band_filter;
690 break;
701 } 691 }
702 return 0; 692 return 0;
703} 693}
704 694
705static int ov772x_set_control(struct soc_camera_device *icd, 695static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
706 struct v4l2_control *ctrl)
707{ 696{
708 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 697 struct i2c_client *client = sd->priv;
698 struct ov772x_priv *priv = to_ov772x(client);
709 int ret = 0; 699 int ret = 0;
710 u8 val; 700 u8 val;
711 701
@@ -715,24 +705,48 @@ static int ov772x_set_control(struct soc_camera_device *icd,
715 priv->flag_vflip = ctrl->value; 705 priv->flag_vflip = ctrl->value;
716 if (priv->info->flags & OV772X_FLAG_VFLIP) 706 if (priv->info->flags & OV772X_FLAG_VFLIP)
717 val ^= VFLIP_IMG; 707 val ^= VFLIP_IMG;
718 ret = ov772x_mask_set(priv->client, COM3, VFLIP_IMG, val); 708 ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val);
719 break; 709 break;
720 case V4L2_CID_HFLIP: 710 case V4L2_CID_HFLIP:
721 val = ctrl->value ? HFLIP_IMG : 0x00; 711 val = ctrl->value ? HFLIP_IMG : 0x00;
722 priv->flag_hflip = ctrl->value; 712 priv->flag_hflip = ctrl->value;
723 if (priv->info->flags & OV772X_FLAG_HFLIP) 713 if (priv->info->flags & OV772X_FLAG_HFLIP)
724 val ^= HFLIP_IMG; 714 val ^= HFLIP_IMG;
725 ret = ov772x_mask_set(priv->client, COM3, HFLIP_IMG, val); 715 ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val);
716 break;
717 case V4L2_CID_BAND_STOP_FILTER:
718 if ((unsigned)ctrl->value > 256)
719 ctrl->value = 256;
720 if (ctrl->value == priv->band_filter)
721 break;
722 if (!ctrl->value) {
723 /* Switch the filter off, it is on now */
724 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
725 if (!ret)
726 ret = ov772x_mask_set(client, COM8,
727 BNDF_ON_OFF, 0);
728 } else {
729 /* Switch the filter on, set AEC low limit */
730 val = 256 - ctrl->value;
731 ret = ov772x_mask_set(client, COM8,
732 BNDF_ON_OFF, BNDF_ON_OFF);
733 if (!ret)
734 ret = ov772x_mask_set(client, BDBASE,
735 0xff, val);
736 }
737 if (!ret)
738 priv->band_filter = ctrl->value;
726 break; 739 break;
727 } 740 }
728 741
729 return ret; 742 return ret;
730} 743}
731 744
732static int ov772x_get_chip_id(struct soc_camera_device *icd, 745static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
733 struct v4l2_dbg_chip_ident *id) 746 struct v4l2_dbg_chip_ident *id)
734{ 747{
735 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 748 struct i2c_client *client = sd->priv;
749 struct ov772x_priv *priv = to_ov772x(client);
736 750
737 id->ident = priv->model; 751 id->ident = priv->model;
738 id->revision = 0; 752 id->revision = 0;
@@ -741,17 +755,17 @@ static int ov772x_get_chip_id(struct soc_camera_device *icd,
741} 755}
742 756
743#ifdef CONFIG_VIDEO_ADV_DEBUG 757#ifdef CONFIG_VIDEO_ADV_DEBUG
744static int ov772x_get_register(struct soc_camera_device *icd, 758static int ov772x_g_register(struct v4l2_subdev *sd,
745 struct v4l2_dbg_register *reg) 759 struct v4l2_dbg_register *reg)
746{ 760{
747 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 761 struct i2c_client *client = sd->priv;
748 int ret; 762 int ret;
749 763
750 reg->size = 1; 764 reg->size = 1;
751 if (reg->reg > 0xff) 765 if (reg->reg > 0xff)
752 return -EINVAL; 766 return -EINVAL;
753 767
754 ret = i2c_smbus_read_byte_data(priv->client, reg->reg); 768 ret = i2c_smbus_read_byte_data(client, reg->reg);
755 if (ret < 0) 769 if (ret < 0)
756 return ret; 770 return ret;
757 771
@@ -760,21 +774,20 @@ static int ov772x_get_register(struct soc_camera_device *icd,
760 return 0; 774 return 0;
761} 775}
762 776
763static int ov772x_set_register(struct soc_camera_device *icd, 777static int ov772x_s_register(struct v4l2_subdev *sd,
764 struct v4l2_dbg_register *reg) 778 struct v4l2_dbg_register *reg)
765{ 779{
766 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 780 struct i2c_client *client = sd->priv;
767 781
768 if (reg->reg > 0xff || 782 if (reg->reg > 0xff ||
769 reg->val > 0xff) 783 reg->val > 0xff)
770 return -EINVAL; 784 return -EINVAL;
771 785
772 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val); 786 return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
773} 787}
774#endif 788#endif
775 789
776static const struct ov772x_win_size* 790static const struct ov772x_win_size *ov772x_select_win(u32 width, u32 height)
777ov772x_select_win(u32 width, u32 height)
778{ 791{
779 __u32 diff; 792 __u32 diff;
780 const struct ov772x_win_size *win; 793 const struct ov772x_win_size *win;
@@ -793,9 +806,10 @@ ov772x_select_win(u32 width, u32 height)
793 return win; 806 return win;
794} 807}
795 808
796static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height, 809static int ov772x_set_params(struct i2c_client *client,
797 u32 pixfmt) 810 u32 *width, u32 *height, u32 pixfmt)
798{ 811{
812 struct ov772x_priv *priv = to_ov772x(client);
799 int ret = -EINVAL; 813 int ret = -EINVAL;
800 u8 val; 814 u8 val;
801 int i; 815 int i;
@@ -805,7 +819,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
805 */ 819 */
806 priv->fmt = NULL; 820 priv->fmt = NULL;
807 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) { 821 for (i = 0; i < ARRAY_SIZE(ov772x_cfmts); i++) {
808 if (pixfmt == ov772x_cfmts[i].fourcc) { 822 if (pixfmt == ov772x_cfmts[i].format->fourcc) {
809 priv->fmt = ov772x_cfmts + i; 823 priv->fmt = ov772x_cfmts + i;
810 break; 824 break;
811 } 825 }
@@ -816,12 +830,12 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
816 /* 830 /*
817 * select win 831 * select win
818 */ 832 */
819 priv->win = ov772x_select_win(width, height); 833 priv->win = ov772x_select_win(*width, *height);
820 834
821 /* 835 /*
822 * reset hardware 836 * reset hardware
823 */ 837 */
824 ov772x_reset(priv->client); 838 ov772x_reset(client);
825 839
826 /* 840 /*
827 * Edge Ctrl 841 * Edge Ctrl
@@ -835,17 +849,17 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
835 * Remove it when manual mode. 849 * Remove it when manual mode.
836 */ 850 */
837 851
838 ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00); 852 ret = ov772x_mask_set(client, DSPAUTO, EDGE_ACTRL, 0x00);
839 if (ret < 0) 853 if (ret < 0)
840 goto ov772x_set_fmt_error; 854 goto ov772x_set_fmt_error;
841 855
842 ret = ov772x_mask_set(priv->client, 856 ret = ov772x_mask_set(client,
843 EDGE_TRSHLD, EDGE_THRESHOLD_MASK, 857 EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
844 priv->info->edgectrl.threshold); 858 priv->info->edgectrl.threshold);
845 if (ret < 0) 859 if (ret < 0)
846 goto ov772x_set_fmt_error; 860 goto ov772x_set_fmt_error;
847 861
848 ret = ov772x_mask_set(priv->client, 862 ret = ov772x_mask_set(client,
849 EDGE_STRNGT, EDGE_STRENGTH_MASK, 863 EDGE_STRNGT, EDGE_STRENGTH_MASK,
850 priv->info->edgectrl.strength); 864 priv->info->edgectrl.strength);
851 if (ret < 0) 865 if (ret < 0)
@@ -857,13 +871,13 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
857 * 871 *
858 * set upper and lower limit 872 * set upper and lower limit
859 */ 873 */
860 ret = ov772x_mask_set(priv->client, 874 ret = ov772x_mask_set(client,
861 EDGE_UPPER, EDGE_UPPER_MASK, 875 EDGE_UPPER, EDGE_UPPER_MASK,
862 priv->info->edgectrl.upper); 876 priv->info->edgectrl.upper);
863 if (ret < 0) 877 if (ret < 0)
864 goto ov772x_set_fmt_error; 878 goto ov772x_set_fmt_error;
865 879
866 ret = ov772x_mask_set(priv->client, 880 ret = ov772x_mask_set(client,
867 EDGE_LOWER, EDGE_LOWER_MASK, 881 EDGE_LOWER, EDGE_LOWER_MASK,
868 priv->info->edgectrl.lower); 882 priv->info->edgectrl.lower);
869 if (ret < 0) 883 if (ret < 0)
@@ -873,7 +887,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
873 /* 887 /*
874 * set size format 888 * set size format
875 */ 889 */
876 ret = ov772x_write_array(priv->client, priv->win->regs); 890 ret = ov772x_write_array(client, priv->win->regs);
877 if (ret < 0) 891 if (ret < 0)
878 goto ov772x_set_fmt_error; 892 goto ov772x_set_fmt_error;
879 893
@@ -882,7 +896,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
882 */ 896 */
883 val = priv->fmt->dsp3; 897 val = priv->fmt->dsp3;
884 if (val) { 898 if (val) {
885 ret = ov772x_mask_set(priv->client, 899 ret = ov772x_mask_set(client,
886 DSP_CTRL3, UV_MASK, val); 900 DSP_CTRL3, UV_MASK, val);
887 if (ret < 0) 901 if (ret < 0)
888 goto ov772x_set_fmt_error; 902 goto ov772x_set_fmt_error;
@@ -901,7 +915,7 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
901 if (priv->flag_hflip) 915 if (priv->flag_hflip)
902 val ^= HFLIP_IMG; 916 val ^= HFLIP_IMG;
903 917
904 ret = ov772x_mask_set(priv->client, 918 ret = ov772x_mask_set(client,
905 COM3, SWAP_MASK | IMG_MASK, val); 919 COM3, SWAP_MASK | IMG_MASK, val);
906 if (ret < 0) 920 if (ret < 0)
907 goto ov772x_set_fmt_error; 921 goto ov772x_set_fmt_error;
@@ -910,47 +924,99 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
910 * set COM7 924 * set COM7
911 */ 925 */
912 val = priv->win->com7_bit | priv->fmt->com7; 926 val = priv->win->com7_bit | priv->fmt->com7;
913 ret = ov772x_mask_set(priv->client, 927 ret = ov772x_mask_set(client,
914 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK), 928 COM7, (SLCT_MASK | FMT_MASK | OFMT_MASK),
915 val); 929 val);
916 if (ret < 0) 930 if (ret < 0)
917 goto ov772x_set_fmt_error; 931 goto ov772x_set_fmt_error;
918 932
933 /*
934 * set COM8
935 */
936 if (priv->band_filter) {
937 ret = ov772x_mask_set(client, COM8, BNDF_ON_OFF, 1);
938 if (!ret)
939 ret = ov772x_mask_set(client, BDBASE,
940 0xff, 256 - priv->band_filter);
941 if (ret < 0)
942 goto ov772x_set_fmt_error;
943 }
944
945 *width = priv->win->width;
946 *height = priv->win->height;
947
919 return ret; 948 return ret;
920 949
921ov772x_set_fmt_error: 950ov772x_set_fmt_error:
922 951
923 ov772x_reset(priv->client); 952 ov772x_reset(client);
924 priv->win = NULL; 953 priv->win = NULL;
925 priv->fmt = NULL; 954 priv->fmt = NULL;
926 955
927 return ret; 956 return ret;
928} 957}
929 958
930static int ov772x_set_crop(struct soc_camera_device *icd, 959static int ov772x_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
931 struct v4l2_rect *rect)
932{ 960{
933 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 961 a->c.left = 0;
962 a->c.top = 0;
963 a->c.width = VGA_WIDTH;
964 a->c.height = VGA_HEIGHT;
965 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
934 966
935 if (!priv->fmt) 967 return 0;
936 return -EINVAL; 968}
937 969
938 return ov772x_set_params(priv, rect->width, rect->height, 970static int ov772x_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
939 priv->fmt->fourcc); 971{
972 a->bounds.left = 0;
973 a->bounds.top = 0;
974 a->bounds.width = VGA_WIDTH;
975 a->bounds.height = VGA_HEIGHT;
976 a->defrect = a->bounds;
977 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
978 a->pixelaspect.numerator = 1;
979 a->pixelaspect.denominator = 1;
980
981 return 0;
940} 982}
941 983
942static int ov772x_set_fmt(struct soc_camera_device *icd, 984static int ov772x_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
943 struct v4l2_format *f) 985{
986 struct i2c_client *client = sd->priv;
987 struct ov772x_priv *priv = to_ov772x(client);
988 struct v4l2_pix_format *pix = &f->fmt.pix;
989
990 if (!priv->win || !priv->fmt) {
991 u32 width = VGA_WIDTH, height = VGA_HEIGHT;
992 int ret = ov772x_set_params(client, &width, &height,
993 V4L2_PIX_FMT_YUYV);
994 if (ret < 0)
995 return ret;
996 }
997
998 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
999
1000 pix->width = priv->win->width;
1001 pix->height = priv->win->height;
1002 pix->pixelformat = priv->fmt->format->fourcc;
1003 pix->colorspace = priv->fmt->format->colorspace;
1004 pix->field = V4L2_FIELD_NONE;
1005
1006 return 0;
1007}
1008
1009static int ov772x_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
944{ 1010{
945 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 1011 struct i2c_client *client = sd->priv;
946 struct v4l2_pix_format *pix = &f->fmt.pix; 1012 struct v4l2_pix_format *pix = &f->fmt.pix;
947 1013
948 return ov772x_set_params(priv, pix->width, pix->height, 1014 return ov772x_set_params(client, &pix->width, &pix->height,
949 pix->pixelformat); 1015 pix->pixelformat);
950} 1016}
951 1017
952static int ov772x_try_fmt(struct soc_camera_device *icd, 1018static int ov772x_try_fmt(struct v4l2_subdev *sd,
953 struct v4l2_format *f) 1019 struct v4l2_format *f)
954{ 1020{
955 struct v4l2_pix_format *pix = &f->fmt.pix; 1021 struct v4l2_pix_format *pix = &f->fmt.pix;
956 const struct ov772x_win_size *win; 1022 const struct ov772x_win_size *win;
@@ -967,9 +1033,10 @@ static int ov772x_try_fmt(struct soc_camera_device *icd,
967 return 0; 1033 return 0;
968} 1034}
969 1035
970static int ov772x_video_probe(struct soc_camera_device *icd) 1036static int ov772x_video_probe(struct soc_camera_device *icd,
1037 struct i2c_client *client)
971{ 1038{
972 struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd); 1039 struct ov772x_priv *priv = to_ov772x(client);
973 u8 pid, ver; 1040 u8 pid, ver;
974 const char *devname; 1041 const char *devname;
975 1042
@@ -986,7 +1053,7 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
986 */ 1053 */
987 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth && 1054 if (SOCAM_DATAWIDTH_10 != priv->info->buswidth &&
988 SOCAM_DATAWIDTH_8 != priv->info->buswidth) { 1055 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
989 dev_err(&icd->dev, "bus width error\n"); 1056 dev_err(&client->dev, "bus width error\n");
990 return -ENODEV; 1057 return -ENODEV;
991 } 1058 }
992 1059
@@ -996,8 +1063,8 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
996 /* 1063 /*
997 * check and show product ID and manufacturer ID 1064 * check and show product ID and manufacturer ID
998 */ 1065 */
999 pid = i2c_smbus_read_byte_data(priv->client, PID); 1066 pid = i2c_smbus_read_byte_data(client, PID);
1000 ver = i2c_smbus_read_byte_data(priv->client, VER); 1067 ver = i2c_smbus_read_byte_data(client, VER);
1001 1068
1002 switch (VERSION(pid, ver)) { 1069 switch (VERSION(pid, ver)) {
1003 case OV7720: 1070 case OV7720:
@@ -1009,69 +1076,77 @@ static int ov772x_video_probe(struct soc_camera_device *icd)
1009 priv->model = V4L2_IDENT_OV7725; 1076 priv->model = V4L2_IDENT_OV7725;
1010 break; 1077 break;
1011 default: 1078 default:
1012 dev_err(&icd->dev, 1079 dev_err(&client->dev,
1013 "Product ID error %x:%x\n", pid, ver); 1080 "Product ID error %x:%x\n", pid, ver);
1014 return -ENODEV; 1081 return -ENODEV;
1015 } 1082 }
1016 1083
1017 dev_info(&icd->dev, 1084 dev_info(&client->dev,
1018 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 1085 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
1019 devname, 1086 devname,
1020 pid, 1087 pid,
1021 ver, 1088 ver,
1022 i2c_smbus_read_byte_data(priv->client, MIDH), 1089 i2c_smbus_read_byte_data(client, MIDH),
1023 i2c_smbus_read_byte_data(priv->client, MIDL)); 1090 i2c_smbus_read_byte_data(client, MIDL));
1024
1025 return soc_camera_video_start(icd);
1026}
1027 1091
1028static void ov772x_video_remove(struct soc_camera_device *icd) 1092 return 0;
1029{
1030 soc_camera_video_stop(icd);
1031} 1093}
1032 1094
1033static struct soc_camera_ops ov772x_ops = { 1095static struct soc_camera_ops ov772x_ops = {
1034 .owner = THIS_MODULE,
1035 .probe = ov772x_video_probe,
1036 .remove = ov772x_video_remove,
1037 .init = ov772x_init,
1038 .release = ov772x_release,
1039 .start_capture = ov772x_start_capture,
1040 .stop_capture = ov772x_stop_capture,
1041 .set_crop = ov772x_set_crop,
1042 .set_fmt = ov772x_set_fmt,
1043 .try_fmt = ov772x_try_fmt,
1044 .set_bus_param = ov772x_set_bus_param, 1096 .set_bus_param = ov772x_set_bus_param,
1045 .query_bus_param = ov772x_query_bus_param, 1097 .query_bus_param = ov772x_query_bus_param,
1046 .controls = ov772x_controls, 1098 .controls = ov772x_controls,
1047 .num_controls = ARRAY_SIZE(ov772x_controls), 1099 .num_controls = ARRAY_SIZE(ov772x_controls),
1048 .get_control = ov772x_get_control, 1100};
1049 .set_control = ov772x_set_control, 1101
1050 .get_chip_id = ov772x_get_chip_id, 1102static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1103 .g_ctrl = ov772x_g_ctrl,
1104 .s_ctrl = ov772x_s_ctrl,
1105 .g_chip_ident = ov772x_g_chip_ident,
1051#ifdef CONFIG_VIDEO_ADV_DEBUG 1106#ifdef CONFIG_VIDEO_ADV_DEBUG
1052 .get_register = ov772x_get_register, 1107 .g_register = ov772x_g_register,
1053 .set_register = ov772x_set_register, 1108 .s_register = ov772x_s_register,
1054#endif 1109#endif
1055}; 1110};
1056 1111
1112static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1113 .s_stream = ov772x_s_stream,
1114 .g_fmt = ov772x_g_fmt,
1115 .s_fmt = ov772x_s_fmt,
1116 .try_fmt = ov772x_try_fmt,
1117 .cropcap = ov772x_cropcap,
1118 .g_crop = ov772x_g_crop,
1119};
1120
1121static struct v4l2_subdev_ops ov772x_subdev_ops = {
1122 .core = &ov772x_subdev_core_ops,
1123 .video = &ov772x_subdev_video_ops,
1124};
1125
1057/* 1126/*
1058 * i2c_driver function 1127 * i2c_driver function
1059 */ 1128 */
1060 1129
1061static int ov772x_probe(struct i2c_client *client, 1130static int ov772x_probe(struct i2c_client *client,
1062 const struct i2c_device_id *did) 1131 const struct i2c_device_id *did)
1063{ 1132{
1064 struct ov772x_priv *priv; 1133 struct ov772x_priv *priv;
1065 struct ov772x_camera_info *info; 1134 struct ov772x_camera_info *info;
1066 struct soc_camera_device *icd; 1135 struct soc_camera_device *icd = client->dev.platform_data;
1067 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1136 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1137 struct soc_camera_link *icl;
1068 int ret; 1138 int ret;
1069 1139
1070 if (!client->dev.platform_data) 1140 if (!icd) {
1141 dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
1071 return -EINVAL; 1142 return -EINVAL;
1143 }
1072 1144
1073 info = container_of(client->dev.platform_data, 1145 icl = to_soc_camera_link(icd);
1074 struct ov772x_camera_info, link); 1146 if (!icl)
1147 return -EINVAL;
1148
1149 info = container_of(icl, struct ov772x_camera_info, link);
1075 1150
1076 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1151 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1077 dev_err(&adapter->dev, 1152 dev_err(&adapter->dev,
@@ -1084,20 +1159,15 @@ static int ov772x_probe(struct i2c_client *client,
1084 if (!priv) 1159 if (!priv)
1085 return -ENOMEM; 1160 return -ENOMEM;
1086 1161
1087 priv->info = info; 1162 priv->info = info;
1088 priv->client = client;
1089 i2c_set_clientdata(client, priv);
1090 1163
1091 icd = &priv->icd; 1164 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1092 icd->ops = &ov772x_ops;
1093 icd->control = &client->dev;
1094 icd->width_max = MAX_WIDTH;
1095 icd->height_max = MAX_HEIGHT;
1096 icd->iface = priv->info->link.bus_id;
1097 1165
1098 ret = soc_camera_device_register(icd); 1166 icd->ops = &ov772x_ops;
1099 1167
1168 ret = ov772x_video_probe(icd, client);
1100 if (ret) { 1169 if (ret) {
1170 icd->ops = NULL;
1101 i2c_set_clientdata(client, NULL); 1171 i2c_set_clientdata(client, NULL);
1102 kfree(priv); 1172 kfree(priv);
1103 } 1173 }
@@ -1107,9 +1177,10 @@ static int ov772x_probe(struct i2c_client *client,
1107 1177
1108static int ov772x_remove(struct i2c_client *client) 1178static int ov772x_remove(struct i2c_client *client)
1109{ 1179{
1110 struct ov772x_priv *priv = i2c_get_clientdata(client); 1180 struct ov772x_priv *priv = to_ov772x(client);
1181 struct soc_camera_device *icd = client->dev.platform_data;
1111 1182
1112 soc_camera_device_unregister(&priv->icd); 1183 icd->ops = NULL;
1113 i2c_set_clientdata(client, NULL); 1184 i2c_set_clientdata(client, NULL);
1114 kfree(priv); 1185 kfree(priv);
1115 return 0; 1186 return 0;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 336a20eded0f..e4d7c13cab87 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -298,6 +298,7 @@ static struct tda829x_config tda829x_no_probe = {
298 298
299static struct tda18271_config hauppauge_tda18271_dvb_config = { 299static struct tda18271_config hauppauge_tda18271_dvb_config = {
300 .gate = TDA18271_GATE_ANALOG, 300 .gate = TDA18271_GATE_ANALOG,
301 .output_opt = TDA18271_OUTPUT_LT_OFF,
301}; 302};
302 303
303static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap) 304static int pvr2_tda10048_attach(struct pvr2_dvb_adapter *adap)
@@ -393,6 +394,7 @@ static struct tda18271_std_map hauppauge_tda18271_std_map = {
393static struct tda18271_config hauppauge_tda18271_config = { 394static struct tda18271_config hauppauge_tda18271_config = {
394 .std_map = &hauppauge_tda18271_std_map, 395 .std_map = &hauppauge_tda18271_std_map,
395 .gate = TDA18271_GATE_ANALOG, 396 .gate = TDA18271_GATE_ANALOG,
397 .output_opt = TDA18271_OUTPUT_LT_OFF,
396}; 398};
397 399
398static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap) 400static int pvr2_s5h1409_attach(struct pvr2_dvb_adapter *adap)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index cbc388729d77..13639b302700 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2063,8 +2063,8 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2063 return -EINVAL; 2063 return -EINVAL;
2064 } 2064 }
2065 2065
2066 /* Note how the 2nd and 3rd arguments are the same for both 2066 /* Note how the 2nd and 3rd arguments are the same for
2067 * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why? 2067 * v4l2_i2c_new_subdev(). Why?
2068 * Well the 2nd argument is the module name to load, while the 3rd 2068 * Well the 2nd argument is the module name to load, while the 3rd
2069 * argument is documented in the framework as being the "chipid" - 2069 * argument is documented in the framework as being the "chipid" -
2070 * and every other place where I can find examples of this, the 2070 * and every other place where I can find examples of this, the
@@ -2077,15 +2077,15 @@ static int pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
2077 mid, i2caddr[0]); 2077 mid, i2caddr[0]);
2078 sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, 2078 sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
2079 fname, fname, 2079 fname, fname,
2080 i2caddr[0]); 2080 i2caddr[0], NULL);
2081 } else { 2081 } else {
2082 pvr2_trace(PVR2_TRACE_INIT, 2082 pvr2_trace(PVR2_TRACE_INIT,
2083 "Module ID %u:" 2083 "Module ID %u:"
2084 " Setting up with address probe list", 2084 " Setting up with address probe list",
2085 mid); 2085 mid);
2086 sd = v4l2_i2c_new_probed_subdev(&hdw->v4l2_dev, &hdw->i2c_adap, 2086 sd = v4l2_i2c_new_subdev(&hdw->v4l2_dev, &hdw->i2c_adap,
2087 fname, fname, 2087 fname, fname,
2088 i2caddr); 2088 0, i2caddr);
2089 } 2089 }
2090 2090
2091 if (!sd) { 2091 if (!sd) {
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index 016bb45ba0c3..6952e9602d5d 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -225,6 +225,10 @@ struct pxa_camera_dev {
225 u32 save_cicr[5]; 225 u32 save_cicr[5];
226}; 226};
227 227
228struct pxa_cam {
229 unsigned long flags;
230};
231
228static const char *pxa_cam_driver_description = "PXA_Camera"; 232static const char *pxa_cam_driver_description = "PXA_Camera";
229 233
230static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 234static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
@@ -237,9 +241,9 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
237{ 241{
238 struct soc_camera_device *icd = vq->priv_data; 242 struct soc_camera_device *icd = vq->priv_data;
239 243
240 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 244 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
241 245
242 *size = roundup(icd->width * icd->height * 246 *size = roundup(icd->user_width * icd->user_height *
243 ((icd->current_fmt->depth + 7) >> 3), 8); 247 ((icd->current_fmt->depth + 7) >> 3), 8);
244 248
245 if (0 == *count) 249 if (0 == *count)
@@ -259,7 +263,7 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
259 263
260 BUG_ON(in_interrupt()); 264 BUG_ON(in_interrupt());
261 265
262 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 266 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
263 &buf->vb, buf->vb.baddr, buf->vb.bsize); 267 &buf->vb, buf->vb.baddr, buf->vb.bsize);
264 268
265 /* This waits until this buffer is out of danger, i.e., until it is no 269 /* This waits until this buffer is out of danger, i.e., until it is no
@@ -270,7 +274,8 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
270 274
271 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) { 275 for (i = 0; i < ARRAY_SIZE(buf->dmas); i++) {
272 if (buf->dmas[i].sg_cpu) 276 if (buf->dmas[i].sg_cpu)
273 dma_free_coherent(ici->dev, buf->dmas[i].sg_size, 277 dma_free_coherent(ici->v4l2_dev.dev,
278 buf->dmas[i].sg_size,
274 buf->dmas[i].sg_cpu, 279 buf->dmas[i].sg_cpu,
275 buf->dmas[i].sg_dma); 280 buf->dmas[i].sg_dma);
276 buf->dmas[i].sg_cpu = NULL; 281 buf->dmas[i].sg_cpu = NULL;
@@ -325,19 +330,20 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
325 struct scatterlist **sg_first, int *sg_first_ofs) 330 struct scatterlist **sg_first, int *sg_first_ofs)
326{ 331{
327 struct pxa_cam_dma *pxa_dma = &buf->dmas[channel]; 332 struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
333 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
328 struct scatterlist *sg; 334 struct scatterlist *sg;
329 int i, offset, sglen; 335 int i, offset, sglen;
330 int dma_len = 0, xfer_len = 0; 336 int dma_len = 0, xfer_len = 0;
331 337
332 if (pxa_dma->sg_cpu) 338 if (pxa_dma->sg_cpu)
333 dma_free_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, 339 dma_free_coherent(dev, pxa_dma->sg_size,
334 pxa_dma->sg_cpu, pxa_dma->sg_dma); 340 pxa_dma->sg_cpu, pxa_dma->sg_dma);
335 341
336 sglen = calculate_dma_sglen(*sg_first, dma->sglen, 342 sglen = calculate_dma_sglen(*sg_first, dma->sglen,
337 *sg_first_ofs, size); 343 *sg_first_ofs, size);
338 344
339 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc); 345 pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
340 pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->soc_host.dev, pxa_dma->sg_size, 346 pxa_dma->sg_cpu = dma_alloc_coherent(dev, pxa_dma->sg_size,
341 &pxa_dma->sg_dma, GFP_KERNEL); 347 &pxa_dma->sg_dma, GFP_KERNEL);
342 if (!pxa_dma->sg_cpu) 348 if (!pxa_dma->sg_cpu)
343 return -ENOMEM; 349 return -ENOMEM;
@@ -345,7 +351,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
345 pxa_dma->sglen = sglen; 351 pxa_dma->sglen = sglen;
346 offset = *sg_first_ofs; 352 offset = *sg_first_ofs;
347 353
348 dev_dbg(pcdev->soc_host.dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n", 354 dev_dbg(dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
349 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma); 355 *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
350 356
351 357
@@ -368,7 +374,7 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
368 pxa_dma->sg_cpu[i].ddadr = 374 pxa_dma->sg_cpu[i].ddadr =
369 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc); 375 pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
370 376
371 dev_vdbg(pcdev->soc_host.dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n", 377 dev_vdbg(dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
372 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc), 378 pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
373 sg_dma_address(sg) + offset, xfer_len); 379 sg_dma_address(sg) + offset, xfer_len);
374 offset = 0; 380 offset = 0;
@@ -418,11 +424,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
418 struct soc_camera_device *icd = vq->priv_data; 424 struct soc_camera_device *icd = vq->priv_data;
419 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 425 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
420 struct pxa_camera_dev *pcdev = ici->priv; 426 struct pxa_camera_dev *pcdev = ici->priv;
427 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
421 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 428 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
422 int ret; 429 int ret;
423 int size_y, size_u = 0, size_v = 0; 430 int size_y, size_u = 0, size_v = 0;
424 431
425 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 432 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
426 vb, vb->baddr, vb->bsize); 433 vb, vb->baddr, vb->bsize);
427 434
428 /* Added list head initialization on alloc */ 435 /* Added list head initialization on alloc */
@@ -441,12 +448,12 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
441 buf->inwork = 1; 448 buf->inwork = 1;
442 449
443 if (buf->fmt != icd->current_fmt || 450 if (buf->fmt != icd->current_fmt ||
444 vb->width != icd->width || 451 vb->width != icd->user_width ||
445 vb->height != icd->height || 452 vb->height != icd->user_height ||
446 vb->field != field) { 453 vb->field != field) {
447 buf->fmt = icd->current_fmt; 454 buf->fmt = icd->current_fmt;
448 vb->width = icd->width; 455 vb->width = icd->user_width;
449 vb->height = icd->height; 456 vb->height = icd->user_height;
450 vb->field = field; 457 vb->field = field;
451 vb->state = VIDEOBUF_NEEDS_INIT; 458 vb->state = VIDEOBUF_NEEDS_INIT;
452 } 459 }
@@ -480,8 +487,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
480 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y, 487 ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
481 &sg, &next_ofs); 488 &sg, &next_ofs);
482 if (ret) { 489 if (ret) {
483 dev_err(pcdev->soc_host.dev, 490 dev_err(dev, "DMA initialization for Y/RGB failed\n");
484 "DMA initialization for Y/RGB failed\n");
485 goto fail; 491 goto fail;
486 } 492 }
487 493
@@ -490,8 +496,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
490 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1, 496 ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
491 size_u, &sg, &next_ofs); 497 size_u, &sg, &next_ofs);
492 if (ret) { 498 if (ret) {
493 dev_err(pcdev->soc_host.dev, 499 dev_err(dev, "DMA initialization for U failed\n");
494 "DMA initialization for U failed\n");
495 goto fail_u; 500 goto fail_u;
496 } 501 }
497 502
@@ -500,8 +505,7 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
500 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2, 505 ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
501 size_v, &sg, &next_ofs); 506 size_v, &sg, &next_ofs);
502 if (ret) { 507 if (ret) {
503 dev_err(pcdev->soc_host.dev, 508 dev_err(dev, "DMA initialization for V failed\n");
504 "DMA initialization for V failed\n");
505 goto fail_v; 509 goto fail_v;
506 } 510 }
507 511
@@ -514,10 +518,10 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
514 return 0; 518 return 0;
515 519
516fail_v: 520fail_v:
517 dma_free_coherent(pcdev->soc_host.dev, buf->dmas[1].sg_size, 521 dma_free_coherent(dev, buf->dmas[1].sg_size,
518 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma); 522 buf->dmas[1].sg_cpu, buf->dmas[1].sg_dma);
519fail_u: 523fail_u:
520 dma_free_coherent(pcdev->soc_host.dev, buf->dmas[0].sg_size, 524 dma_free_coherent(dev, buf->dmas[0].sg_size,
521 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma); 525 buf->dmas[0].sg_cpu, buf->dmas[0].sg_dma);
522fail: 526fail:
523 free_buffer(vq, buf); 527 free_buffer(vq, buf);
@@ -541,7 +545,8 @@ static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
541 active = pcdev->active; 545 active = pcdev->active;
542 546
543 for (i = 0; i < pcdev->channels; i++) { 547 for (i = 0; i < pcdev->channels; i++) {
544 dev_dbg(pcdev->soc_host.dev, "%s (channel=%d) ddadr=%08x\n", __func__, 548 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
549 "%s (channel=%d) ddadr=%08x\n", __func__,
545 i, active->dmas[i].sg_dma); 550 i, active->dmas[i].sg_dma);
546 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma; 551 DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
547 DCSR(pcdev->dma_chans[i]) = DCSR_RUN; 552 DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
@@ -553,7 +558,8 @@ static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
553 int i; 558 int i;
554 559
555 for (i = 0; i < pcdev->channels; i++) { 560 for (i = 0; i < pcdev->channels; i++) {
556 dev_dbg(pcdev->soc_host.dev, "%s (channel=%d)\n", __func__, i); 561 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
562 "%s (channel=%d)\n", __func__, i);
557 DCSR(pcdev->dma_chans[i]) = 0; 563 DCSR(pcdev->dma_chans[i]) = 0;
558 } 564 }
559} 565}
@@ -589,7 +595,7 @@ static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
589{ 595{
590 unsigned long cicr0, cifr; 596 unsigned long cicr0, cifr;
591 597
592 dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); 598 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
593 /* Reset the FIFOs */ 599 /* Reset the FIFOs */
594 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F; 600 cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
595 __raw_writel(cifr, pcdev->base + CIFR); 601 __raw_writel(cifr, pcdev->base + CIFR);
@@ -609,7 +615,7 @@ static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
609 __raw_writel(cicr0, pcdev->base + CICR0); 615 __raw_writel(cicr0, pcdev->base + CICR0);
610 616
611 pcdev->active = NULL; 617 pcdev->active = NULL;
612 dev_dbg(pcdev->soc_host.dev, "%s\n", __func__); 618 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s\n", __func__);
613} 619}
614 620
615/* Called under spinlock_irqsave(&pcdev->lock, ...) */ 621/* Called under spinlock_irqsave(&pcdev->lock, ...) */
@@ -621,8 +627,8 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
621 struct pxa_camera_dev *pcdev = ici->priv; 627 struct pxa_camera_dev *pcdev = ici->priv;
622 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 628 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
623 629
624 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__, 630 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d active=%p\n",
625 vb, vb->baddr, vb->bsize, pcdev->active); 631 __func__, vb, vb->baddr, vb->bsize, pcdev->active);
626 632
627 list_add_tail(&vb->queue, &pcdev->capture); 633 list_add_tail(&vb->queue, &pcdev->capture);
628 634
@@ -639,22 +645,23 @@ static void pxa_videobuf_release(struct videobuf_queue *vq,
639 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb); 645 struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
640#ifdef DEBUG 646#ifdef DEBUG
641 struct soc_camera_device *icd = vq->priv_data; 647 struct soc_camera_device *icd = vq->priv_data;
648 struct device *dev = icd->dev.parent;
642 649
643 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, 650 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
644 vb, vb->baddr, vb->bsize); 651 vb, vb->baddr, vb->bsize);
645 652
646 switch (vb->state) { 653 switch (vb->state) {
647 case VIDEOBUF_ACTIVE: 654 case VIDEOBUF_ACTIVE:
648 dev_dbg(&icd->dev, "%s (active)\n", __func__); 655 dev_dbg(dev, "%s (active)\n", __func__);
649 break; 656 break;
650 case VIDEOBUF_QUEUED: 657 case VIDEOBUF_QUEUED:
651 dev_dbg(&icd->dev, "%s (queued)\n", __func__); 658 dev_dbg(dev, "%s (queued)\n", __func__);
652 break; 659 break;
653 case VIDEOBUF_PREPARED: 660 case VIDEOBUF_PREPARED:
654 dev_dbg(&icd->dev, "%s (prepared)\n", __func__); 661 dev_dbg(dev, "%s (prepared)\n", __func__);
655 break; 662 break;
656 default: 663 default:
657 dev_dbg(&icd->dev, "%s (unknown)\n", __func__); 664 dev_dbg(dev, "%s (unknown)\n", __func__);
658 break; 665 break;
659 } 666 }
660#endif 667#endif
@@ -674,7 +681,8 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
674 do_gettimeofday(&vb->ts); 681 do_gettimeofday(&vb->ts);
675 vb->field_count++; 682 vb->field_count++;
676 wake_up(&vb->done); 683 wake_up(&vb->done);
677 dev_dbg(pcdev->soc_host.dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb); 684 dev_dbg(pcdev->soc_host.v4l2_dev.dev, "%s dequeud buffer (vb=0x%p)\n",
685 __func__, vb);
678 686
679 if (list_empty(&pcdev->capture)) { 687 if (list_empty(&pcdev->capture)) {
680 pxa_camera_stop_capture(pcdev); 688 pxa_camera_stop_capture(pcdev);
@@ -710,7 +718,8 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
710 for (i = 0; i < pcdev->channels; i++) 718 for (i = 0; i < pcdev->channels; i++)
711 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP) 719 if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
712 is_dma_stopped = 0; 720 is_dma_stopped = 0;
713 dev_dbg(pcdev->soc_host.dev, "%s : top queued buffer=%p, dma_stopped=%d\n", 721 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
722 "%s : top queued buffer=%p, dma_stopped=%d\n",
714 __func__, pcdev->active, is_dma_stopped); 723 __func__, pcdev->active, is_dma_stopped);
715 if (pcdev->active && is_dma_stopped) 724 if (pcdev->active && is_dma_stopped)
716 pxa_camera_start_capture(pcdev); 725 pxa_camera_start_capture(pcdev);
@@ -719,6 +728,7 @@ static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
719static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev, 728static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
720 enum pxa_camera_active_dma act_dma) 729 enum pxa_camera_active_dma act_dma)
721{ 730{
731 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
722 struct pxa_buffer *buf; 732 struct pxa_buffer *buf;
723 unsigned long flags; 733 unsigned long flags;
724 u32 status, camera_status, overrun; 734 u32 status, camera_status, overrun;
@@ -735,13 +745,13 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
735 overrun |= CISR_IFO_1 | CISR_IFO_2; 745 overrun |= CISR_IFO_1 | CISR_IFO_2;
736 746
737 if (status & DCSR_BUSERR) { 747 if (status & DCSR_BUSERR) {
738 dev_err(pcdev->soc_host.dev, "DMA Bus Error IRQ!\n"); 748 dev_err(dev, "DMA Bus Error IRQ!\n");
739 goto out; 749 goto out;
740 } 750 }
741 751
742 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) { 752 if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
743 dev_err(pcdev->soc_host.dev, "Unknown DMA IRQ source, " 753 dev_err(dev, "Unknown DMA IRQ source, status: 0x%08x\n",
744 "status: 0x%08x\n", status); 754 status);
745 goto out; 755 goto out;
746 } 756 }
747 757
@@ -764,7 +774,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
764 buf = container_of(vb, struct pxa_buffer, vb); 774 buf = container_of(vb, struct pxa_buffer, vb);
765 WARN_ON(buf->inwork || list_empty(&vb->queue)); 775 WARN_ON(buf->inwork || list_empty(&vb->queue));
766 776
767 dev_dbg(pcdev->soc_host.dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n", 777 dev_dbg(dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
768 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "", 778 __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
769 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel)); 779 status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
770 780
@@ -775,7 +785,7 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
775 */ 785 */
776 if (camera_status & overrun && 786 if (camera_status & overrun &&
777 !list_is_last(pcdev->capture.next, &pcdev->capture)) { 787 !list_is_last(pcdev->capture.next, &pcdev->capture)) {
778 dev_dbg(pcdev->soc_host.dev, "FIFO overrun! CISR: %x\n", 788 dev_dbg(dev, "FIFO overrun! CISR: %x\n",
779 camera_status); 789 camera_status);
780 pxa_camera_stop_capture(pcdev); 790 pxa_camera_stop_capture(pcdev);
781 pxa_camera_start_capture(pcdev); 791 pxa_camera_start_capture(pcdev);
@@ -830,9 +840,11 @@ static void pxa_camera_init_videobuf(struct videobuf_queue *q,
830 sizeof(struct pxa_buffer), icd); 840 sizeof(struct pxa_buffer), icd);
831} 841}
832 842
833static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev) 843static u32 mclk_get_divisor(struct platform_device *pdev,
844 struct pxa_camera_dev *pcdev)
834{ 845{
835 unsigned long mclk = pcdev->mclk; 846 unsigned long mclk = pcdev->mclk;
847 struct device *dev = &pdev->dev;
836 u32 div; 848 u32 div;
837 unsigned long lcdclk; 849 unsigned long lcdclk;
838 850
@@ -842,7 +854,7 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
842 /* mclk <= ciclk / 4 (27.4.2) */ 854 /* mclk <= ciclk / 4 (27.4.2) */
843 if (mclk > lcdclk / 4) { 855 if (mclk > lcdclk / 4) {
844 mclk = lcdclk / 4; 856 mclk = lcdclk / 4;
845 dev_warn(pcdev->soc_host.dev, "Limiting master clock to %lu\n", mclk); 857 dev_warn(dev, "Limiting master clock to %lu\n", mclk);
846 } 858 }
847 859
848 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */ 860 /* We verify mclk != 0, so if anyone breaks it, here comes their Oops */
@@ -852,8 +864,8 @@ static u32 mclk_get_divisor(struct pxa_camera_dev *pcdev)
852 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 864 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
853 pcdev->mclk = lcdclk / (2 * (div + 1)); 865 pcdev->mclk = lcdclk / (2 * (div + 1));
854 866
855 dev_dbg(pcdev->soc_host.dev, "LCD clock %luHz, target freq %luHz, " 867 dev_dbg(dev, "LCD clock %luHz, target freq %luHz, divisor %u\n",
856 "divisor %u\n", lcdclk, mclk, div); 868 lcdclk, mclk, div);
857 869
858 return div; 870 return div;
859} 871}
@@ -870,14 +882,15 @@ static void recalculate_fifo_timeout(struct pxa_camera_dev *pcdev,
870static void pxa_camera_activate(struct pxa_camera_dev *pcdev) 882static void pxa_camera_activate(struct pxa_camera_dev *pcdev)
871{ 883{
872 struct pxacamera_platform_data *pdata = pcdev->pdata; 884 struct pxacamera_platform_data *pdata = pcdev->pdata;
885 struct device *dev = pcdev->soc_host.v4l2_dev.dev;
873 u32 cicr4 = 0; 886 u32 cicr4 = 0;
874 887
875 dev_dbg(pcdev->soc_host.dev, "Registered platform device at %p data %p\n", 888 dev_dbg(dev, "Registered platform device at %p data %p\n",
876 pcdev, pdata); 889 pcdev, pdata);
877 890
878 if (pdata && pdata->init) { 891 if (pdata && pdata->init) {
879 dev_dbg(pcdev->soc_host.dev, "%s: Init gpios\n", __func__); 892 dev_dbg(dev, "%s: Init gpios\n", __func__);
880 pdata->init(pcdev->soc_host.dev); 893 pdata->init(dev);
881 } 894 }
882 895
883 /* disable all interrupts */ 896 /* disable all interrupts */
@@ -919,7 +932,8 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
919 struct videobuf_buffer *vb; 932 struct videobuf_buffer *vb;
920 933
921 status = __raw_readl(pcdev->base + CISR); 934 status = __raw_readl(pcdev->base + CISR);
922 dev_dbg(pcdev->soc_host.dev, "Camera interrupt status 0x%lx\n", status); 935 dev_dbg(pcdev->soc_host.v4l2_dev.dev,
936 "Camera interrupt status 0x%lx\n", status);
923 937
924 if (!status) 938 if (!status)
925 return IRQ_NONE; 939 return IRQ_NONE;
@@ -951,24 +965,18 @@ static int pxa_camera_add_device(struct soc_camera_device *icd)
951{ 965{
952 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 966 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
953 struct pxa_camera_dev *pcdev = ici->priv; 967 struct pxa_camera_dev *pcdev = ici->priv;
954 int ret;
955 968
956 if (pcdev->icd) { 969 if (pcdev->icd)
957 ret = -EBUSY; 970 return -EBUSY;
958 goto ebusy;
959 }
960
961 dev_info(&icd->dev, "PXA Camera driver attached to camera %d\n",
962 icd->devnum);
963 971
964 pxa_camera_activate(pcdev); 972 pxa_camera_activate(pcdev);
965 ret = icd->ops->init(icd);
966 973
967 if (!ret) 974 pcdev->icd = icd;
968 pcdev->icd = icd;
969 975
970ebusy: 976 dev_info(icd->dev.parent, "PXA Camera driver attached to camera %d\n",
971 return ret; 977 icd->devnum);
978
979 return 0;
972} 980}
973 981
974/* Called with .video_lock held */ 982/* Called with .video_lock held */
@@ -979,7 +987,7 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
979 987
980 BUG_ON(icd != pcdev->icd); 988 BUG_ON(icd != pcdev->icd);
981 989
982 dev_info(&icd->dev, "PXA Camera driver detached from camera %d\n", 990 dev_info(icd->dev.parent, "PXA Camera driver detached from camera %d\n",
983 icd->devnum); 991 icd->devnum);
984 992
985 /* disable capture, disable interrupts */ 993 /* disable capture, disable interrupts */
@@ -990,8 +998,6 @@ static void pxa_camera_remove_device(struct soc_camera_device *icd)
990 DCSR(pcdev->dma_chans[1]) = 0; 998 DCSR(pcdev->dma_chans[1]) = 0;
991 DCSR(pcdev->dma_chans[2]) = 0; 999 DCSR(pcdev->dma_chans[2]) = 0;
992 1000
993 icd->ops->release(icd);
994
995 pxa_camera_deactivate(pcdev); 1001 pxa_camera_deactivate(pcdev);
996 1002
997 pcdev->icd = NULL; 1003 pcdev->icd = NULL;
@@ -1039,57 +1045,17 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
1039 return 0; 1045 return 0;
1040} 1046}
1041 1047
1042static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 1048static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1049 unsigned long flags, __u32 pixfmt)
1043{ 1050{
1044 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1051 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1045 struct pxa_camera_dev *pcdev = ici->priv; 1052 struct pxa_camera_dev *pcdev = ici->priv;
1046 unsigned long dw, bpp, bus_flags, camera_flags, common_flags; 1053 unsigned long dw, bpp;
1047 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0; 1054 u32 cicr0, cicr1, cicr2, cicr3, cicr4 = 0;
1048 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
1049
1050 if (ret < 0)
1051 return ret;
1052
1053 camera_flags = icd->ops->query_bus_param(icd);
1054
1055 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1056 if (!common_flags)
1057 return -EINVAL;
1058
1059 pcdev->channels = 1;
1060
1061 /* Make choises, based on platform preferences */
1062 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
1063 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
1064 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1065 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
1066 else
1067 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
1068 }
1069
1070 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
1071 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
1072 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1073 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
1074 else
1075 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
1076 }
1077
1078 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
1079 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
1080 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1081 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
1082 else
1083 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
1084 }
1085
1086 ret = icd->ops->set_bus_param(icd, common_flags);
1087 if (ret < 0)
1088 return ret;
1089 1055
1090 /* Datawidth is now guaranteed to be equal to one of the three values. 1056 /* Datawidth is now guaranteed to be equal to one of the three values.
1091 * We fix bit-per-pixel equal to data-width... */ 1057 * We fix bit-per-pixel equal to data-width... */
1092 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 1058 switch (flags & SOCAM_DATAWIDTH_MASK) {
1093 case SOCAM_DATAWIDTH_10: 1059 case SOCAM_DATAWIDTH_10:
1094 dw = 4; 1060 dw = 4;
1095 bpp = 0x40; 1061 bpp = 0x40;
@@ -1110,18 +1076,18 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1110 cicr4 |= CICR4_PCLK_EN; 1076 cicr4 |= CICR4_PCLK_EN;
1111 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 1077 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
1112 cicr4 |= CICR4_MCLK_EN; 1078 cicr4 |= CICR4_MCLK_EN;
1113 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) 1079 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
1114 cicr4 |= CICR4_PCP; 1080 cicr4 |= CICR4_PCP;
1115 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) 1081 if (flags & SOCAM_HSYNC_ACTIVE_LOW)
1116 cicr4 |= CICR4_HSP; 1082 cicr4 |= CICR4_HSP;
1117 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 1083 if (flags & SOCAM_VSYNC_ACTIVE_LOW)
1118 cicr4 |= CICR4_VSP; 1084 cicr4 |= CICR4_VSP;
1119 1085
1120 cicr0 = __raw_readl(pcdev->base + CICR0); 1086 cicr0 = __raw_readl(pcdev->base + CICR0);
1121 if (cicr0 & CICR0_ENB) 1087 if (cicr0 & CICR0_ENB)
1122 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0); 1088 __raw_writel(cicr0 & ~CICR0_ENB, pcdev->base + CICR0);
1123 1089
1124 cicr1 = CICR1_PPL_VAL(icd->width - 1) | bpp | dw; 1090 cicr1 = CICR1_PPL_VAL(icd->user_width - 1) | bpp | dw;
1125 1091
1126 switch (pixfmt) { 1092 switch (pixfmt) {
1127 case V4L2_PIX_FMT_YUV422P: 1093 case V4L2_PIX_FMT_YUV422P:
@@ -1150,7 +1116,7 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1150 } 1116 }
1151 1117
1152 cicr2 = 0; 1118 cicr2 = 0;
1153 cicr3 = CICR3_LPF_VAL(icd->height - 1) | 1119 cicr3 = CICR3_LPF_VAL(icd->user_height - 1) |
1154 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top)); 1120 CICR3_BFW_VAL(min((unsigned short)255, icd->y_skip_top));
1155 cicr4 |= pcdev->mclk_divisor; 1121 cicr4 |= pcdev->mclk_divisor;
1156 1122
@@ -1164,6 +1130,59 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1164 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP)); 1130 CICR0_SIM_MP : (CICR0_SL_CAP_EN | CICR0_SIM_SP));
1165 cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK; 1131 cicr0 |= CICR0_DMAEN | CICR0_IRQ_MASK;
1166 __raw_writel(cicr0, pcdev->base + CICR0); 1132 __raw_writel(cicr0, pcdev->base + CICR0);
1133}
1134
1135static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1136{
1137 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1138 struct pxa_camera_dev *pcdev = ici->priv;
1139 unsigned long bus_flags, camera_flags, common_flags;
1140 int ret = test_platform_param(pcdev, icd->buswidth, &bus_flags);
1141 struct pxa_cam *cam = icd->host_priv;
1142
1143 if (ret < 0)
1144 return ret;
1145
1146 camera_flags = icd->ops->query_bus_param(icd);
1147
1148 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
1149 if (!common_flags)
1150 return -EINVAL;
1151
1152 pcdev->channels = 1;
1153
1154 /* Make choises, based on platform preferences */
1155 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
1156 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
1157 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1158 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
1159 else
1160 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
1161 }
1162
1163 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
1164 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
1165 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1166 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
1167 else
1168 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
1169 }
1170
1171 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
1172 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
1173 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1174 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
1175 else
1176 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
1177 }
1178
1179 cam->flags = common_flags;
1180
1181 ret = icd->ops->set_bus_param(icd, common_flags);
1182 if (ret < 0)
1183 return ret;
1184
1185 pxa_camera_setup_cicr(icd, common_flags, pixfmt);
1167 1186
1168 return 0; 1187 return 0;
1169} 1188}
@@ -1227,8 +1246,9 @@ static int required_buswidth(const struct soc_camera_data_format *fmt)
1227static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx, 1246static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1228 struct soc_camera_format_xlate *xlate) 1247 struct soc_camera_format_xlate *xlate)
1229{ 1248{
1230 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1249 struct device *dev = icd->dev.parent;
1231 int formats = 0, buswidth, ret; 1250 int formats = 0, buswidth, ret;
1251 struct pxa_cam *cam;
1232 1252
1233 buswidth = required_buswidth(icd->formats + idx); 1253 buswidth = required_buswidth(icd->formats + idx);
1234 1254
@@ -1239,6 +1259,16 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1239 if (ret < 0) 1259 if (ret < 0)
1240 return 0; 1260 return 0;
1241 1261
1262 if (!icd->host_priv) {
1263 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
1264 if (!cam)
1265 return -ENOMEM;
1266
1267 icd->host_priv = cam;
1268 } else {
1269 cam = icd->host_priv;
1270 }
1271
1242 switch (icd->formats[idx].fourcc) { 1272 switch (icd->formats[idx].fourcc) {
1243 case V4L2_PIX_FMT_UYVY: 1273 case V4L2_PIX_FMT_UYVY:
1244 formats++; 1274 formats++;
@@ -1247,7 +1277,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1247 xlate->cam_fmt = icd->formats + idx; 1277 xlate->cam_fmt = icd->formats + idx;
1248 xlate->buswidth = buswidth; 1278 xlate->buswidth = buswidth;
1249 xlate++; 1279 xlate++;
1250 dev_dbg(ici->dev, "Providing format %s using %s\n", 1280 dev_dbg(dev, "Providing format %s using %s\n",
1251 pxa_camera_formats[0].name, 1281 pxa_camera_formats[0].name,
1252 icd->formats[idx].name); 1282 icd->formats[idx].name);
1253 } 1283 }
@@ -1262,7 +1292,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1262 xlate->cam_fmt = icd->formats + idx; 1292 xlate->cam_fmt = icd->formats + idx;
1263 xlate->buswidth = buswidth; 1293 xlate->buswidth = buswidth;
1264 xlate++; 1294 xlate++;
1265 dev_dbg(ici->dev, "Providing format %s packed\n", 1295 dev_dbg(dev, "Providing format %s packed\n",
1266 icd->formats[idx].name); 1296 icd->formats[idx].name);
1267 } 1297 }
1268 break; 1298 break;
@@ -1274,7 +1304,7 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1274 xlate->cam_fmt = icd->formats + idx; 1304 xlate->cam_fmt = icd->formats + idx;
1275 xlate->buswidth = icd->formats[idx].depth; 1305 xlate->buswidth = icd->formats[idx].depth;
1276 xlate++; 1306 xlate++;
1277 dev_dbg(ici->dev, 1307 dev_dbg(dev,
1278 "Providing format %s in pass-through mode\n", 1308 "Providing format %s in pass-through mode\n",
1279 icd->formats[idx].name); 1309 icd->formats[idx].name);
1280 } 1310 }
@@ -1283,31 +1313,80 @@ static int pxa_camera_get_formats(struct soc_camera_device *icd, int idx,
1283 return formats; 1313 return formats;
1284} 1314}
1285 1315
1316static void pxa_camera_put_formats(struct soc_camera_device *icd)
1317{
1318 kfree(icd->host_priv);
1319 icd->host_priv = NULL;
1320}
1321
1322static int pxa_camera_check_frame(struct v4l2_pix_format *pix)
1323{
1324 /* limit to pxa hardware capabilities */
1325 return pix->height < 32 || pix->height > 2048 || pix->width < 48 ||
1326 pix->width > 2048 || (pix->width & 0x01);
1327}
1328
1286static int pxa_camera_set_crop(struct soc_camera_device *icd, 1329static int pxa_camera_set_crop(struct soc_camera_device *icd,
1287 struct v4l2_rect *rect) 1330 struct v4l2_crop *a)
1288{ 1331{
1332 struct v4l2_rect *rect = &a->c;
1289 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1333 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1290 struct pxa_camera_dev *pcdev = ici->priv; 1334 struct pxa_camera_dev *pcdev = ici->priv;
1335 struct device *dev = icd->dev.parent;
1336 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1291 struct soc_camera_sense sense = { 1337 struct soc_camera_sense sense = {
1292 .master_clock = pcdev->mclk, 1338 .master_clock = pcdev->mclk,
1293 .pixel_clock_max = pcdev->ciclk / 4, 1339 .pixel_clock_max = pcdev->ciclk / 4,
1294 }; 1340 };
1341 struct v4l2_format f;
1342 struct v4l2_pix_format *pix = &f.fmt.pix, pix_tmp;
1343 struct pxa_cam *cam = icd->host_priv;
1295 int ret; 1344 int ret;
1296 1345
1297 /* If PCLK is used to latch data from the sensor, check sense */ 1346 /* If PCLK is used to latch data from the sensor, check sense */
1298 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) 1347 if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN)
1299 icd->sense = &sense; 1348 icd->sense = &sense;
1300 1349
1301 ret = icd->ops->set_crop(icd, rect); 1350 ret = v4l2_subdev_call(sd, video, s_crop, a);
1302 1351
1303 icd->sense = NULL; 1352 icd->sense = NULL;
1304 1353
1305 if (ret < 0) { 1354 if (ret < 0) {
1306 dev_warn(ici->dev, "Failed to crop to %ux%u@%u:%u\n", 1355 dev_warn(dev, "Failed to crop to %ux%u@%u:%u\n",
1307 rect->width, rect->height, rect->left, rect->top); 1356 rect->width, rect->height, rect->left, rect->top);
1308 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1357 return ret;
1358 }
1359
1360 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1361
1362 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
1363 if (ret < 0)
1364 return ret;
1365
1366 pix_tmp = *pix;
1367 if (pxa_camera_check_frame(pix)) {
1368 /*
1369 * Camera cropping produced a frame beyond our capabilities.
1370 * FIXME: just extract a subframe, that we can process.
1371 */
1372 v4l_bound_align_image(&pix->width, 48, 2048, 1,
1373 &pix->height, 32, 2048, 0,
1374 icd->current_fmt->fourcc == V4L2_PIX_FMT_YUV422P ?
1375 4 : 0);
1376 ret = v4l2_subdev_call(sd, video, s_fmt, &f);
1377 if (ret < 0)
1378 return ret;
1379
1380 if (pxa_camera_check_frame(pix)) {
1381 dev_warn(icd->dev.parent,
1382 "Inconsistent state. Use S_FMT to repair\n");
1383 return -EINVAL;
1384 }
1385 }
1386
1387 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1309 if (sense.pixel_clock > sense.pixel_clock_max) { 1388 if (sense.pixel_clock > sense.pixel_clock_max) {
1310 dev_err(ici->dev, 1389 dev_err(dev,
1311 "pixel clock %lu set by the camera too high!", 1390 "pixel clock %lu set by the camera too high!",
1312 sense.pixel_clock); 1391 sense.pixel_clock);
1313 return -EIO; 1392 return -EIO;
@@ -1315,6 +1394,11 @@ static int pxa_camera_set_crop(struct soc_camera_device *icd,
1315 recalculate_fifo_timeout(pcdev, sense.pixel_clock); 1394 recalculate_fifo_timeout(pcdev, sense.pixel_clock);
1316 } 1395 }
1317 1396
1397 icd->user_width = pix->width;
1398 icd->user_height = pix->height;
1399
1400 pxa_camera_setup_cicr(icd, cam->flags, icd->current_fmt->fourcc);
1401
1318 return ret; 1402 return ret;
1319} 1403}
1320 1404
@@ -1323,6 +1407,8 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1323{ 1407{
1324 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1408 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1325 struct pxa_camera_dev *pcdev = ici->priv; 1409 struct pxa_camera_dev *pcdev = ici->priv;
1410 struct device *dev = icd->dev.parent;
1411 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1326 const struct soc_camera_data_format *cam_fmt = NULL; 1412 const struct soc_camera_data_format *cam_fmt = NULL;
1327 const struct soc_camera_format_xlate *xlate = NULL; 1413 const struct soc_camera_format_xlate *xlate = NULL;
1328 struct soc_camera_sense sense = { 1414 struct soc_camera_sense sense = {
@@ -1335,7 +1421,7 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1335 1421
1336 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat); 1422 xlate = soc_camera_xlate_by_fourcc(icd, pix->pixelformat);
1337 if (!xlate) { 1423 if (!xlate) {
1338 dev_warn(ici->dev, "Format %x not found\n", pix->pixelformat); 1424 dev_warn(dev, "Format %x not found\n", pix->pixelformat);
1339 return -EINVAL; 1425 return -EINVAL;
1340 } 1426 }
1341 1427
@@ -1346,16 +1432,21 @@ static int pxa_camera_set_fmt(struct soc_camera_device *icd,
1346 icd->sense = &sense; 1432 icd->sense = &sense;
1347 1433
1348 cam_f.fmt.pix.pixelformat = cam_fmt->fourcc; 1434 cam_f.fmt.pix.pixelformat = cam_fmt->fourcc;
1349 ret = icd->ops->set_fmt(icd, &cam_f); 1435 ret = v4l2_subdev_call(sd, video, s_fmt, f);
1350 1436
1351 icd->sense = NULL; 1437 icd->sense = NULL;
1352 1438
1353 if (ret < 0) { 1439 if (ret < 0) {
1354 dev_warn(ici->dev, "Failed to configure for format %x\n", 1440 dev_warn(dev, "Failed to configure for format %x\n",
1355 pix->pixelformat); 1441 pix->pixelformat);
1442 } else if (pxa_camera_check_frame(pix)) {
1443 dev_warn(dev,
1444 "Camera driver produced an unsupported frame %dx%d\n",
1445 pix->width, pix->height);
1446 ret = -EINVAL;
1356 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { 1447 } else if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) {
1357 if (sense.pixel_clock > sense.pixel_clock_max) { 1448 if (sense.pixel_clock > sense.pixel_clock_max) {
1358 dev_err(ici->dev, 1449 dev_err(dev,
1359 "pixel clock %lu set by the camera too high!", 1450 "pixel clock %lu set by the camera too high!",
1360 sense.pixel_clock); 1451 sense.pixel_clock);
1361 return -EIO; 1452 return -EIO;
@@ -1375,6 +1466,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1375 struct v4l2_format *f) 1466 struct v4l2_format *f)
1376{ 1467{
1377 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1468 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1469 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1378 const struct soc_camera_format_xlate *xlate; 1470 const struct soc_camera_format_xlate *xlate;
1379 struct v4l2_pix_format *pix = &f->fmt.pix; 1471 struct v4l2_pix_format *pix = &f->fmt.pix;
1380 __u32 pixfmt = pix->pixelformat; 1472 __u32 pixfmt = pix->pixelformat;
@@ -1383,7 +1475,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1383 1475
1384 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1476 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1385 if (!xlate) { 1477 if (!xlate) {
1386 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 1478 dev_warn(ici->v4l2_dev.dev, "Format %x not found\n", pixfmt);
1387 return -EINVAL; 1479 return -EINVAL;
1388 } 1480 }
1389 1481
@@ -1395,7 +1487,7 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1395 */ 1487 */
1396 v4l_bound_align_image(&pix->width, 48, 2048, 1, 1488 v4l_bound_align_image(&pix->width, 48, 2048, 1,
1397 &pix->height, 32, 2048, 0, 1489 &pix->height, 32, 2048, 0,
1398 xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P ? 4 : 0); 1490 pixfmt == V4L2_PIX_FMT_YUV422P ? 4 : 0);
1399 1491
1400 pix->bytesperline = pix->width * 1492 pix->bytesperline = pix->width *
1401 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1493 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
@@ -1404,15 +1496,15 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
1404 /* camera has to see its format, but the user the original one */ 1496 /* camera has to see its format, but the user the original one */
1405 pix->pixelformat = xlate->cam_fmt->fourcc; 1497 pix->pixelformat = xlate->cam_fmt->fourcc;
1406 /* limit to sensor capabilities */ 1498 /* limit to sensor capabilities */
1407 ret = icd->ops->try_fmt(icd, f); 1499 ret = v4l2_subdev_call(sd, video, try_fmt, f);
1408 pix->pixelformat = xlate->host_fmt->fourcc; 1500 pix->pixelformat = pixfmt;
1409 1501
1410 field = pix->field; 1502 field = pix->field;
1411 1503
1412 if (field == V4L2_FIELD_ANY) { 1504 if (field == V4L2_FIELD_ANY) {
1413 pix->field = V4L2_FIELD_NONE; 1505 pix->field = V4L2_FIELD_NONE;
1414 } else if (field != V4L2_FIELD_NONE) { 1506 } else if (field != V4L2_FIELD_NONE) {
1415 dev_err(&icd->dev, "Field type %d unsupported.\n", field); 1507 dev_err(icd->dev.parent, "Field type %d unsupported.\n", field);
1416 return -EINVAL; 1508 return -EINVAL;
1417 } 1509 }
1418 1510
@@ -1518,6 +1610,7 @@ static struct soc_camera_host_ops pxa_soc_camera_host_ops = {
1518 .resume = pxa_camera_resume, 1610 .resume = pxa_camera_resume,
1519 .set_crop = pxa_camera_set_crop, 1611 .set_crop = pxa_camera_set_crop,
1520 .get_formats = pxa_camera_get_formats, 1612 .get_formats = pxa_camera_get_formats,
1613 .put_formats = pxa_camera_put_formats,
1521 .set_fmt = pxa_camera_set_fmt, 1614 .set_fmt = pxa_camera_set_fmt,
1522 .try_fmt = pxa_camera_try_fmt, 1615 .try_fmt = pxa_camera_try_fmt,
1523 .init_videobuf = pxa_camera_init_videobuf, 1616 .init_videobuf = pxa_camera_init_videobuf,
@@ -1575,8 +1668,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1575 pcdev->mclk = 20000000; 1668 pcdev->mclk = 20000000;
1576 } 1669 }
1577 1670
1578 pcdev->soc_host.dev = &pdev->dev; 1671 pcdev->mclk_divisor = mclk_get_divisor(pdev, pcdev);
1579 pcdev->mclk_divisor = mclk_get_divisor(pcdev);
1580 1672
1581 INIT_LIST_HEAD(&pcdev->capture); 1673 INIT_LIST_HEAD(&pcdev->capture);
1582 spin_lock_init(&pcdev->lock); 1674 spin_lock_init(&pcdev->lock);
@@ -1641,6 +1733,7 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1641 pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME; 1733 pcdev->soc_host.drv_name = PXA_CAM_DRV_NAME;
1642 pcdev->soc_host.ops = &pxa_soc_camera_host_ops; 1734 pcdev->soc_host.ops = &pxa_soc_camera_host_ops;
1643 pcdev->soc_host.priv = pcdev; 1735 pcdev->soc_host.priv = pcdev;
1736 pcdev->soc_host.v4l2_dev.dev = &pdev->dev;
1644 pcdev->soc_host.nr = pdev->id; 1737 pcdev->soc_host.nr = pdev->id;
1645 1738
1646 err = soc_camera_host_register(&pcdev->soc_host); 1739 err = soc_camera_host_register(&pcdev->soc_host);
@@ -1722,3 +1815,4 @@ module_exit(pxa_camera_exit);
1722MODULE_DESCRIPTION("PXA27x SoC Camera Host driver"); 1815MODULE_DESCRIPTION("PXA27x SoC Camera Host driver");
1723MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>"); 1816MODULE_AUTHOR("Guennadi Liakhovetski <kernel@pengutronix.de>");
1724MODULE_LICENSE("GPL"); 1817MODULE_LICENSE("GPL");
1818MODULE_ALIAS("platform:" PXA_CAM_DRV_NAME);
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 1b29487fd254..71145bff94fa 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -4164,7 +4164,7 @@ struct saa7134_board saa7134_boards[] = {
4164 /*Dmitry Belimov <d.belimov@gmail.com> */ 4164 /*Dmitry Belimov <d.belimov@gmail.com> */
4165 .name = "Beholder BeholdTV 505 RDS", 4165 .name = "Beholder BeholdTV 505 RDS",
4166 .audio_clock = 0x00200000, 4166 .audio_clock = 0x00200000,
4167 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4167 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4168 .radio_type = UNSET, 4168 .radio_type = UNSET,
4169 .tuner_addr = ADDR_UNSET, 4169 .tuner_addr = ADDR_UNSET,
4170 .radio_addr = ADDR_UNSET, 4170 .radio_addr = ADDR_UNSET,
@@ -4229,7 +4229,7 @@ struct saa7134_board saa7134_boards[] = {
4229 /*Dmitry Belimov <d.belimov@gmail.com> */ 4229 /*Dmitry Belimov <d.belimov@gmail.com> */
4230 .name = "Beholder BeholdTV 507 RDS", 4230 .name = "Beholder BeholdTV 507 RDS",
4231 .audio_clock = 0x00187de7, 4231 .audio_clock = 0x00187de7,
4232 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4232 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4233 .radio_type = UNSET, 4233 .radio_type = UNSET,
4234 .tuner_addr = ADDR_UNSET, 4234 .tuner_addr = ADDR_UNSET,
4235 .radio_addr = ADDR_UNSET, 4235 .radio_addr = ADDR_UNSET,
@@ -4380,7 +4380,7 @@ struct saa7134_board saa7134_boards[] = {
4380 /* Andrey Melnikoff <temnota@kmv.ru> */ 4380 /* Andrey Melnikoff <temnota@kmv.ru> */
4381 .name = "Beholder BeholdTV 607 FM", 4381 .name = "Beholder BeholdTV 607 FM",
4382 .audio_clock = 0x00187de7, 4382 .audio_clock = 0x00187de7,
4383 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4383 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4384 .radio_type = UNSET, 4384 .radio_type = UNSET,
4385 .tuner_addr = ADDR_UNSET, 4385 .tuner_addr = ADDR_UNSET,
4386 .radio_addr = ADDR_UNSET, 4386 .radio_addr = ADDR_UNSET,
@@ -4408,7 +4408,7 @@ struct saa7134_board saa7134_boards[] = {
4408 /* Andrey Melnikoff <temnota@kmv.ru> */ 4408 /* Andrey Melnikoff <temnota@kmv.ru> */
4409 .name = "Beholder BeholdTV 609 FM", 4409 .name = "Beholder BeholdTV 609 FM",
4410 .audio_clock = 0x00187de7, 4410 .audio_clock = 0x00187de7,
4411 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4411 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4412 .radio_type = UNSET, 4412 .radio_type = UNSET,
4413 .tuner_addr = ADDR_UNSET, 4413 .tuner_addr = ADDR_UNSET,
4414 .radio_addr = ADDR_UNSET, 4414 .radio_addr = ADDR_UNSET,
@@ -4494,7 +4494,7 @@ struct saa7134_board saa7134_boards[] = {
4494 /* Andrey Melnikoff <temnota@kmv.ru> */ 4494 /* Andrey Melnikoff <temnota@kmv.ru> */
4495 .name = "Beholder BeholdTV 607 RDS", 4495 .name = "Beholder BeholdTV 607 RDS",
4496 .audio_clock = 0x00187de7, 4496 .audio_clock = 0x00187de7,
4497 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4497 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4498 .radio_type = UNSET, 4498 .radio_type = UNSET,
4499 .tuner_addr = ADDR_UNSET, 4499 .tuner_addr = ADDR_UNSET,
4500 .radio_addr = ADDR_UNSET, 4500 .radio_addr = ADDR_UNSET,
@@ -4523,7 +4523,7 @@ struct saa7134_board saa7134_boards[] = {
4523 /* Andrey Melnikoff <temnota@kmv.ru> */ 4523 /* Andrey Melnikoff <temnota@kmv.ru> */
4524 .name = "Beholder BeholdTV 609 RDS", 4524 .name = "Beholder BeholdTV 609 RDS",
4525 .audio_clock = 0x00187de7, 4525 .audio_clock = 0x00187de7,
4526 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4526 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4527 .radio_type = UNSET, 4527 .radio_type = UNSET,
4528 .tuner_addr = ADDR_UNSET, 4528 .tuner_addr = ADDR_UNSET,
4529 .radio_addr = ADDR_UNSET, 4529 .radio_addr = ADDR_UNSET,
@@ -4630,7 +4630,7 @@ struct saa7134_board saa7134_boards[] = {
4630 /* Alexey Osipov <lion-simba@pridelands.ru> */ 4630 /* Alexey Osipov <lion-simba@pridelands.ru> */
4631 .name = "Beholder BeholdTV M6 Extra", 4631 .name = "Beholder BeholdTV M6 Extra",
4632 .audio_clock = 0x00187de7, 4632 .audio_clock = 0x00187de7,
4633 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, /* FIXME to MK5 */ 4633 .tuner_type = TUNER_PHILIPS_FM1216MK5,
4634 .radio_type = UNSET, 4634 .radio_type = UNSET,
4635 .tuner_addr = ADDR_UNSET, 4635 .tuner_addr = ADDR_UNSET,
4636 .radio_addr = ADDR_UNSET, 4636 .radio_addr = ADDR_UNSET,
@@ -5257,6 +5257,27 @@ struct saa7134_board saa7134_boards[] = {
5257 .amux = TV, 5257 .amux = TV,
5258 }, 5258 },
5259 }, 5259 },
5260 [SAA7134_BOARD_ZOLID_HYBRID_PCI] = {
5261 .name = "Zolid Hybrid TV Tuner PCI",
5262 .audio_clock = 0x00187de7,
5263 .tuner_type = TUNER_PHILIPS_TDA8290,
5264 .radio_type = UNSET,
5265 .tuner_addr = ADDR_UNSET,
5266 .radio_addr = ADDR_UNSET,
5267 .tuner_config = 0,
5268 .mpeg = SAA7134_MPEG_DVB,
5269 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5270 .inputs = {{
5271 .name = name_tv,
5272 .vmux = 1,
5273 .amux = TV,
5274 .tv = 1,
5275 } },
5276 .radio = { /* untested */
5277 .name = name_radio,
5278 .amux = TV,
5279 },
5280 },
5260 5281
5261}; 5282};
5262 5283
@@ -6390,6 +6411,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6390 .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */ 6411 .subdevice = 0x0138, /* LifeView FlyTV Prime30 OEM */
6391 .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM, 6412 .driver_data = SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM,
6392 }, { 6413 }, {
6414 .vendor = PCI_VENDOR_ID_PHILIPS,
6415 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6416 .subvendor = PCI_VENDOR_ID_PHILIPS,
6417 .subdevice = 0x2004,
6418 .driver_data = SAA7134_BOARD_ZOLID_HYBRID_PCI,
6419 }, {
6393 /* --- boards without eeprom + subsystem ID --- */ 6420 /* --- boards without eeprom + subsystem ID --- */
6394 .vendor = PCI_VENDOR_ID_PHILIPS, 6421 .vendor = PCI_VENDOR_ID_PHILIPS,
6395 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6422 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
@@ -7208,22 +7235,22 @@ int saa7134_board_init2(struct saa7134_dev *dev)
7208 if (dev->radio_type != UNSET) 7235 if (dev->radio_type != UNSET)
7209 v4l2_i2c_new_subdev(&dev->v4l2_dev, 7236 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7210 &dev->i2c_adap, "tuner", "tuner", 7237 &dev->i2c_adap, "tuner", "tuner",
7211 dev->radio_addr); 7238 dev->radio_addr, NULL);
7212 if (has_demod) 7239 if (has_demod)
7213 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 7240 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7214 &dev->i2c_adap, "tuner", "tuner", 7241 &dev->i2c_adap, "tuner", "tuner",
7215 v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 7242 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
7216 if (dev->tuner_addr == ADDR_UNSET) { 7243 if (dev->tuner_addr == ADDR_UNSET) {
7217 enum v4l2_i2c_tuner_type type = 7244 enum v4l2_i2c_tuner_type type =
7218 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; 7245 has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
7219 7246
7220 v4l2_i2c_new_probed_subdev(&dev->v4l2_dev, 7247 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7221 &dev->i2c_adap, "tuner", "tuner", 7248 &dev->i2c_adap, "tuner", "tuner",
7222 v4l2_i2c_tuner_addrs(type)); 7249 0, v4l2_i2c_tuner_addrs(type));
7223 } else { 7250 } else {
7224 v4l2_i2c_new_subdev(&dev->v4l2_dev, 7251 v4l2_i2c_new_subdev(&dev->v4l2_dev,
7225 &dev->i2c_adap, "tuner", "tuner", 7252 &dev->i2c_adap, "tuner", "tuner",
7226 dev->tuner_addr); 7253 dev->tuner_addr, NULL);
7227 } 7254 }
7228 } 7255 }
7229 7256
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index cb78c956d810..f87757fccc72 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -1000,7 +1000,7 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1000 struct v4l2_subdev *sd = 1000 struct v4l2_subdev *sd =
1001 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap, 1001 v4l2_i2c_new_subdev(&dev->v4l2_dev, &dev->i2c_adap,
1002 "saa6752hs", "saa6752hs", 1002 "saa6752hs", "saa6752hs",
1003 saa7134_boards[dev->board].empress_addr); 1003 saa7134_boards[dev->board].empress_addr, NULL);
1004 1004
1005 if (sd) 1005 if (sd)
1006 sd->grp_id = GRP_EMPRESS; 1006 sd->grp_id = GRP_EMPRESS;
@@ -1009,9 +1009,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
1009 if (saa7134_boards[dev->board].rds_addr) { 1009 if (saa7134_boards[dev->board].rds_addr) {
1010 struct v4l2_subdev *sd; 1010 struct v4l2_subdev *sd;
1011 1011
1012 sd = v4l2_i2c_new_probed_subdev_addr(&dev->v4l2_dev, 1012 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1013 &dev->i2c_adap, "saa6588", "saa6588", 1013 &dev->i2c_adap, "saa6588", "saa6588",
1014 saa7134_boards[dev->board].rds_addr); 1014 0, I2C_ADDRS(saa7134_boards[dev->board].rds_addr));
1015 if (sd) { 1015 if (sd) {
1016 printk(KERN_INFO "%s: found RDS decoder\n", dev->name); 1016 printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
1017 dev->has_rds = 1; 1017 dev->has_rds = 1;
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index ebde21dba7e3..a26e997a9ce6 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -1007,12 +1007,29 @@ static struct tda18271_config hcw_tda18271_config = {
1007 .std_map = &hauppauge_tda18271_std_map, 1007 .std_map = &hauppauge_tda18271_std_map,
1008 .gate = TDA18271_GATE_ANALOG, 1008 .gate = TDA18271_GATE_ANALOG,
1009 .config = 3, 1009 .config = 3,
1010 .output_opt = TDA18271_OUTPUT_LT_OFF,
1010}; 1011};
1011 1012
1012static struct tda829x_config tda829x_no_probe = { 1013static struct tda829x_config tda829x_no_probe = {
1013 .probe_tuner = TDA829X_DONT_PROBE, 1014 .probe_tuner = TDA829X_DONT_PROBE,
1014}; 1015};
1015 1016
1017static struct tda10048_config zolid_tda10048_config = {
1018 .demod_address = 0x10 >> 1,
1019 .output_mode = TDA10048_PARALLEL_OUTPUT,
1020 .fwbulkwritelen = TDA10048_BULKWRITE_200,
1021 .inversion = TDA10048_INVERSION_ON,
1022 .dtv6_if_freq_khz = TDA10048_IF_3300,
1023 .dtv7_if_freq_khz = TDA10048_IF_3500,
1024 .dtv8_if_freq_khz = TDA10048_IF_4000,
1025 .clk_freq_khz = TDA10048_CLK_16000,
1026 .disable_gate_access = 1,
1027};
1028
1029static struct tda18271_config zolid_tda18271_config = {
1030 .gate = TDA18271_GATE_ANALOG,
1031};
1032
1016/* ================================================================== 1033/* ==================================================================
1017 * Core code 1034 * Core code
1018 */ 1035 */
@@ -1488,6 +1505,19 @@ static int dvb_init(struct saa7134_dev *dev)
1488 __func__); 1505 __func__);
1489 1506
1490 break; 1507 break;
1508 case SAA7134_BOARD_ZOLID_HYBRID_PCI:
1509 fe0->dvb.frontend = dvb_attach(tda10048_attach,
1510 &zolid_tda10048_config,
1511 &dev->i2c_adap);
1512 if (fe0->dvb.frontend != NULL) {
1513 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1514 &dev->i2c_adap, 0x4b,
1515 &tda829x_no_probe);
1516 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1517 0x60, &dev->i2c_adap,
1518 &zolid_tda18271_config);
1519 }
1520 break;
1491 default: 1521 default:
1492 wprintk("Huh? unknown DVB card?\n"); 1522 wprintk("Huh? unknown DVB card?\n");
1493 break; 1523 break;
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index e1e83c7b966e..a0e8c62e6ae1 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -251,6 +251,10 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
251 if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir) 251 if (data[10] != 0x6b && data[11] != 0x86 && disable_other_ir)
252 return 0; 252 return 0;
253 253
254 /* Wrong data decode fix */
255 if (data[9] != (unsigned char)(~data[8]))
256 return 0;
257
254 *ir_key = data[9]; 258 *ir_key = data[9];
255 *ir_raw = data[9]; 259 *ir_raw = data[9];
256 260
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index d18bb9643856..6ee3e9b7769e 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -296,6 +296,7 @@ struct saa7134_format {
296#define SAA7134_BOARD_AVERMEDIA_STUDIO_505 170 296#define SAA7134_BOARD_AVERMEDIA_STUDIO_505 170
297#define SAA7134_BOARD_BEHOLD_X7 171 297#define SAA7134_BOARD_BEHOLD_X7 171
298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172 298#define SAA7134_BOARD_ROVERMEDIA_LINK_PRO_FM 172
299#define SAA7134_BOARD_ZOLID_HYBRID_PCI 173
299 300
300#define SAA7134_MAXBOARDS 32 301#define SAA7134_MAXBOARDS 32
301#define SAA7134_INPUT_MAX 8 302#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/Kconfig b/drivers/media/video/saa7164/Kconfig
new file mode 100644
index 000000000000..353263725172
--- /dev/null
+++ b/drivers/media/video/saa7164/Kconfig
@@ -0,0 +1,18 @@
1config VIDEO_SAA7164
2 tristate "NXP SAA7164 support"
3 depends on DVB_CORE && PCI && I2C
4 select I2C_ALGOBIT
5 select FW_LOADER
6 select VIDEO_TUNER
7 select VIDEO_TVEEPROM
8 select VIDEOBUF_DVB
9 select DVB_TDA10048 if !DVB_FE_CUSTOMISE
10 select DVB_S5H1411 if !DVB_FE_CUSTOMISE
11 select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
12 ---help---
13 This is a video4linux driver for NXP SAA7164 based
14 TV cards.
15
16 To compile this driver as a module, choose M here: the
17 module will be called saa7164
18
diff --git a/drivers/media/video/saa7164/Makefile b/drivers/media/video/saa7164/Makefile
new file mode 100644
index 000000000000..4b329fd42add
--- /dev/null
+++ b/drivers/media/video/saa7164/Makefile
@@ -0,0 +1,12 @@
1saa7164-objs := saa7164-cards.o saa7164-core.o saa7164-i2c.o saa7164-dvb.o \
2 saa7164-fw.o saa7164-bus.o saa7164-cmd.o saa7164-api.o \
3 saa7164-buffer.o
4
5obj-$(CONFIG_VIDEO_SAA7164) += saa7164.o
6
7EXTRA_CFLAGS += -Idrivers/media/video
8EXTRA_CFLAGS += -Idrivers/media/common/tuners
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
11
12EXTRA_CFLAGS += $(extra-cflags-y) $(extra-cflags-m)
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
new file mode 100644
index 000000000000..bb6df1b276be
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -0,0 +1,600 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/wait.h>
23
24#include "saa7164.h"
25
26int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode)
27{
28 int ret;
29
30 ret = saa7164_cmd_send(port->dev, port->hwcfg.unitid, SET_CUR,
31 SAA_STATE_CONTROL, sizeof(mode), &mode);
32 if (ret != SAA_OK)
33 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
34
35 return ret;
36}
37
38int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version)
39{
40 int ret;
41
42 ret = saa7164_cmd_send(dev, 0, GET_CUR,
43 GET_FW_VERSION_CONTROL, sizeof(u32), version);
44 if (ret != SAA_OK)
45 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
46
47 return ret;
48}
49
50int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen)
51{
52 u8 reg[] = { 0x0f, 0x00 };
53
54 if (buflen < 128)
55 return -ENOMEM;
56
57 /* Assumption: Hauppauge eeprom is at 0xa0 on on bus 0 */
58 /* TODO: Pull the details from the boards struct */
59 return saa7164_api_i2c_read(&dev->i2c_bus[0], 0xa0 >> 1, sizeof(reg),
60 &reg[0], 128, buf);
61}
62
63
64int saa7164_api_configure_port_mpeg2ts(struct saa7164_dev *dev,
65 struct saa7164_tsport *port,
66 tmComResTSFormatDescrHeader_t *tsfmt)
67{
68 dprintk(DBGLVL_API, " bFormatIndex = 0x%x\n", tsfmt->bFormatIndex);
69 dprintk(DBGLVL_API, " bDataOffset = 0x%x\n", tsfmt->bDataOffset);
70 dprintk(DBGLVL_API, " bPacketLength= 0x%x\n", tsfmt->bPacketLength);
71 dprintk(DBGLVL_API, " bStrideLength= 0x%x\n", tsfmt->bStrideLength);
72 dprintk(DBGLVL_API, " bguid = (....)\n");
73
74 /* Cache the hardware configuration in the port */
75
76 port->bufcounter = port->hwcfg.BARLocation;
77 port->pitch = port->hwcfg.BARLocation + (2 * sizeof(u32));
78 port->bufsize = port->hwcfg.BARLocation + (3 * sizeof(u32));
79 port->bufoffset = port->hwcfg.BARLocation + (4 * sizeof(u32));
80 port->bufptr32l = port->hwcfg.BARLocation +
81 (4 * sizeof(u32)) +
82 (sizeof(u32) * port->hwcfg.buffercount) + sizeof(u32);
83 port->bufptr32h = port->hwcfg.BARLocation +
84 (4 * sizeof(u32)) +
85 (sizeof(u32) * port->hwcfg.buffercount);
86 port->bufptr64 = port->hwcfg.BARLocation +
87 (4 * sizeof(u32)) +
88 (sizeof(u32) * port->hwcfg.buffercount);
89 dprintk(DBGLVL_API, " = port->hwcfg.BARLocation = 0x%x\n",
90 port->hwcfg.BARLocation);
91
92 dprintk(DBGLVL_API, " = VS_FORMAT_MPEGTS (becomes dev->ts[%d])\n",
93 port->nr);
94
95 return 0;
96}
97
98int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
99{
100 struct saa7164_tsport *port = 0;
101 u32 idx, next_offset;
102 int i;
103 tmComResDescrHeader_t *hdr, *t;
104 tmComResExtDevDescrHeader_t *exthdr;
105 tmComResPathDescrHeader_t *pathhdr;
106 tmComResAntTermDescrHeader_t *anttermhdr;
107 tmComResTunerDescrHeader_t *tunerunithdr;
108 tmComResDMATermDescrHeader_t *vcoutputtermhdr;
109 tmComResTSFormatDescrHeader_t *tsfmt;
110 u32 currpath = 0;
111
112 dprintk(DBGLVL_API,
113 "%s(?,?,%d) sizeof(tmComResDescrHeader_t) = %d bytes\n",
114 __func__, len, (u32)sizeof(tmComResDescrHeader_t));
115
116 for (idx = 0; idx < (len - sizeof(tmComResDescrHeader_t)); ) {
117
118 hdr = (tmComResDescrHeader_t *)(buf + idx);
119
120 if (hdr->type != CS_INTERFACE)
121 return SAA_ERR_NOT_SUPPORTED;
122
123 dprintk(DBGLVL_API, "@ 0x%x = \n", idx);
124 switch (hdr->subtype) {
125 case GENERAL_REQUEST:
126 dprintk(DBGLVL_API, " GENERAL_REQUEST\n");
127 break;
128 case VC_TUNER_PATH:
129 dprintk(DBGLVL_API, " VC_TUNER_PATH\n");
130 pathhdr = (tmComResPathDescrHeader_t *)(buf + idx);
131 dprintk(DBGLVL_API, " pathid = 0x%x\n",
132 pathhdr->pathid);
133 currpath = pathhdr->pathid;
134 break;
135 case VC_INPUT_TERMINAL:
136 dprintk(DBGLVL_API, " VC_INPUT_TERMINAL\n");
137 anttermhdr =
138 (tmComResAntTermDescrHeader_t *)(buf + idx);
139 dprintk(DBGLVL_API, " terminalid = 0x%x\n",
140 anttermhdr->terminalid);
141 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
142 anttermhdr->terminaltype);
143 switch (anttermhdr->terminaltype) {
144 case ITT_ANTENNA:
145 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
146 break;
147 case LINE_CONNECTOR:
148 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
149 break;
150 case SPDIF_CONNECTOR:
151 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
152 break;
153 case COMPOSITE_CONNECTOR:
154 dprintk(DBGLVL_API,
155 " = COMPOSITE_CONNECTOR\n");
156 break;
157 case SVIDEO_CONNECTOR:
158 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
159 break;
160 case COMPONENT_CONNECTOR:
161 dprintk(DBGLVL_API,
162 " = COMPONENT_CONNECTOR\n");
163 break;
164 case STANDARD_DMA:
165 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
166 break;
167 default:
168 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
169 anttermhdr->terminaltype);
170 }
171 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
172 anttermhdr->assocterminal);
173 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
174 anttermhdr->iterminal);
175 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
176 anttermhdr->controlsize);
177 break;
178 case VC_OUTPUT_TERMINAL:
179 dprintk(DBGLVL_API, " VC_OUTPUT_TERMINAL\n");
180 vcoutputtermhdr =
181 (tmComResDMATermDescrHeader_t *)(buf + idx);
182 dprintk(DBGLVL_API, " unitid = 0x%x\n",
183 vcoutputtermhdr->unitid);
184 dprintk(DBGLVL_API, " terminaltype = 0x%x\n",
185 vcoutputtermhdr->terminaltype);
186 switch (vcoutputtermhdr->terminaltype) {
187 case ITT_ANTENNA:
188 dprintk(DBGLVL_API, " = ITT_ANTENNA\n");
189 break;
190 case LINE_CONNECTOR:
191 dprintk(DBGLVL_API, " = LINE_CONNECTOR\n");
192 break;
193 case SPDIF_CONNECTOR:
194 dprintk(DBGLVL_API, " = SPDIF_CONNECTOR\n");
195 break;
196 case COMPOSITE_CONNECTOR:
197 dprintk(DBGLVL_API,
198 " = COMPOSITE_CONNECTOR\n");
199 break;
200 case SVIDEO_CONNECTOR:
201 dprintk(DBGLVL_API, " = SVIDEO_CONNECTOR\n");
202 break;
203 case COMPONENT_CONNECTOR:
204 dprintk(DBGLVL_API,
205 " = COMPONENT_CONNECTOR\n");
206 break;
207 case STANDARD_DMA:
208 dprintk(DBGLVL_API, " = STANDARD_DMA\n");
209 break;
210 default:
211 dprintk(DBGLVL_API, " = undefined (0x%x)\n",
212 vcoutputtermhdr->terminaltype);
213 }
214 dprintk(DBGLVL_API, " assocterminal= 0x%x\n",
215 vcoutputtermhdr->assocterminal);
216 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
217 vcoutputtermhdr->sourceid);
218 dprintk(DBGLVL_API, " iterminal = 0x%x\n",
219 vcoutputtermhdr->iterminal);
220 dprintk(DBGLVL_API, " BARLocation = 0x%x\n",
221 vcoutputtermhdr->BARLocation);
222 dprintk(DBGLVL_API, " flags = 0x%x\n",
223 vcoutputtermhdr->flags);
224 dprintk(DBGLVL_API, " interruptid = 0x%x\n",
225 vcoutputtermhdr->interruptid);
226 dprintk(DBGLVL_API, " buffercount = 0x%x\n",
227 vcoutputtermhdr->buffercount);
228 dprintk(DBGLVL_API, " metadatasize = 0x%x\n",
229 vcoutputtermhdr->metadatasize);
230 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
231 vcoutputtermhdr->controlsize);
232 dprintk(DBGLVL_API, " numformats = 0x%x\n",
233 vcoutputtermhdr->numformats);
234
235 t = (tmComResDescrHeader_t *)
236 ((tmComResDMATermDescrHeader_t *)(buf + idx));
237 next_offset = idx + (vcoutputtermhdr->len);
238 for (i = 0; i < vcoutputtermhdr->numformats; i++) {
239 t = (tmComResDescrHeader_t *)
240 (buf + next_offset);
241 switch (t->subtype) {
242 case VS_FORMAT_MPEG2TS:
243 tsfmt =
244 (tmComResTSFormatDescrHeader_t *)t;
245 if (currpath == 1)
246 port = &dev->ts1;
247 else
248 port = &dev->ts2;
249 memcpy(&port->hwcfg, vcoutputtermhdr,
250 sizeof(*vcoutputtermhdr));
251 saa7164_api_configure_port_mpeg2ts(dev,
252 port, tsfmt);
253 break;
254 case VS_FORMAT_MPEG2PS:
255 dprintk(DBGLVL_API,
256 " = VS_FORMAT_MPEG2PS\n");
257 break;
258 case VS_FORMAT_VBI:
259 dprintk(DBGLVL_API,
260 " = VS_FORMAT_VBI\n");
261 break;
262 case VS_FORMAT_RDS:
263 dprintk(DBGLVL_API,
264 " = VS_FORMAT_RDS\n");
265 break;
266 case VS_FORMAT_UNCOMPRESSED:
267 dprintk(DBGLVL_API,
268 " = VS_FORMAT_UNCOMPRESSED\n");
269 break;
270 case VS_FORMAT_TYPE:
271 dprintk(DBGLVL_API,
272 " = VS_FORMAT_TYPE\n");
273 break;
274 default:
275 dprintk(DBGLVL_API,
276 " = undefined (0x%x)\n",
277 t->subtype);
278 }
279 next_offset += t->len;
280 }
281
282 break;
283 case TUNER_UNIT:
284 dprintk(DBGLVL_API, " TUNER_UNIT\n");
285 tunerunithdr =
286 (tmComResTunerDescrHeader_t *)(buf + idx);
287 dprintk(DBGLVL_API, " unitid = 0x%x\n",
288 tunerunithdr->unitid);
289 dprintk(DBGLVL_API, " sourceid = 0x%x\n",
290 tunerunithdr->sourceid);
291 dprintk(DBGLVL_API, " iunit = 0x%x\n",
292 tunerunithdr->iunit);
293 dprintk(DBGLVL_API, " tuningstandards = 0x%x\n",
294 tunerunithdr->tuningstandards);
295 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
296 tunerunithdr->controlsize);
297 dprintk(DBGLVL_API, " controls = 0x%x\n",
298 tunerunithdr->controls);
299 break;
300 case VC_SELECTOR_UNIT:
301 dprintk(DBGLVL_API, " VC_SELECTOR_UNIT\n");
302 break;
303 case VC_PROCESSING_UNIT:
304 dprintk(DBGLVL_API, " VC_PROCESSING_UNIT\n");
305 break;
306 case FEATURE_UNIT:
307 dprintk(DBGLVL_API, " FEATURE_UNIT\n");
308 break;
309 case ENCODER_UNIT:
310 dprintk(DBGLVL_API, " ENCODER_UNIT\n");
311 break;
312 case EXTENSION_UNIT:
313 dprintk(DBGLVL_API, " EXTENSION_UNIT\n");
314 exthdr = (tmComResExtDevDescrHeader_t *)(buf + idx);
315 dprintk(DBGLVL_API, " unitid = 0x%x\n",
316 exthdr->unitid);
317 dprintk(DBGLVL_API, " deviceid = 0x%x\n",
318 exthdr->deviceid);
319 dprintk(DBGLVL_API, " devicetype = 0x%x\n",
320 exthdr->devicetype);
321 if (exthdr->devicetype & 0x1)
322 dprintk(DBGLVL_API, " = Decoder Device\n");
323 if (exthdr->devicetype & 0x2)
324 dprintk(DBGLVL_API, " = GPIO Source\n");
325 if (exthdr->devicetype & 0x4)
326 dprintk(DBGLVL_API, " = Video Decoder\n");
327 if (exthdr->devicetype & 0x8)
328 dprintk(DBGLVL_API, " = Audio Decoder\n");
329 if (exthdr->devicetype & 0x20)
330 dprintk(DBGLVL_API, " = Crossbar\n");
331 if (exthdr->devicetype & 0x40)
332 dprintk(DBGLVL_API, " = Tuner\n");
333 if (exthdr->devicetype & 0x80)
334 dprintk(DBGLVL_API, " = IF PLL\n");
335 if (exthdr->devicetype & 0x100)
336 dprintk(DBGLVL_API, " = Demodulator\n");
337 if (exthdr->devicetype & 0x200)
338 dprintk(DBGLVL_API, " = RDS Decoder\n");
339 if (exthdr->devicetype & 0x400)
340 dprintk(DBGLVL_API, " = Encoder\n");
341 if (exthdr->devicetype & 0x800)
342 dprintk(DBGLVL_API, " = IR Decoder\n");
343 if (exthdr->devicetype & 0x1000)
344 dprintk(DBGLVL_API, " = EEPROM\n");
345 if (exthdr->devicetype & 0x2000)
346 dprintk(DBGLVL_API,
347 " = VBI Decoder\n");
348 if (exthdr->devicetype & 0x10000)
349 dprintk(DBGLVL_API,
350 " = Streaming Device\n");
351 if (exthdr->devicetype & 0x20000)
352 dprintk(DBGLVL_API,
353 " = DRM Device\n");
354 if (exthdr->devicetype & 0x40000000)
355 dprintk(DBGLVL_API,
356 " = Generic Device\n");
357 if (exthdr->devicetype & 0x80000000)
358 dprintk(DBGLVL_API,
359 " = Config Space Device\n");
360 dprintk(DBGLVL_API, " numgpiopins = 0x%x\n",
361 exthdr->numgpiopins);
362 dprintk(DBGLVL_API, " numgpiogroups = 0x%x\n",
363 exthdr->numgpiogroups);
364 dprintk(DBGLVL_API, " controlsize = 0x%x\n",
365 exthdr->controlsize);
366 break;
367 case PVC_INFRARED_UNIT:
368 dprintk(DBGLVL_API, " PVC_INFRARED_UNIT\n");
369 break;
370 case DRM_UNIT:
371 dprintk(DBGLVL_API, " DRM_UNIT\n");
372 break;
373 default:
374 dprintk(DBGLVL_API, "default %d\n", hdr->subtype);
375 }
376
377 dprintk(DBGLVL_API, " 1.%x\n", hdr->len);
378 dprintk(DBGLVL_API, " 2.%x\n", hdr->type);
379 dprintk(DBGLVL_API, " 3.%x\n", hdr->subtype);
380 dprintk(DBGLVL_API, " 4.%x\n", hdr->unitid);
381
382 idx += hdr->len;
383 }
384
385 return 0;
386}
387
388int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
389{
390 int ret;
391 u32 buflen = 0;
392 u8 *buf;
393
394 dprintk(DBGLVL_API, "%s()\n", __func__);
395
396 /* Get the total descriptor length */
397 ret = saa7164_cmd_send(dev, 0, GET_LEN,
398 GET_DESCRIPTORS_CONTROL, sizeof(buflen), &buflen);
399 if (ret != SAA_OK)
400 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
401
402 dprintk(DBGLVL_API, "%s() total descriptor size = %d bytes.\n",
403 __func__, buflen);
404
405 /* Allocate enough storage for all of the descs */
406 buf = kzalloc(buflen, GFP_KERNEL);
407 if (buf == NULL)
408 return SAA_ERR_NO_RESOURCES;
409
410 /* Retrieve them */
411 ret = saa7164_cmd_send(dev, 0, GET_CUR,
412 GET_DESCRIPTORS_CONTROL, buflen, buf);
413 if (ret != SAA_OK) {
414 printk(KERN_ERR "%s() error, ret = 0x%x\n", __func__, ret);
415 goto out;
416 }
417
418 if (debug & DBGLVL_API)
419 saa7164_dumphex16(dev, buf, (buflen/16)*16);
420
421 saa7164_api_dump_subdevs(dev, buf, buflen);
422
423out:
424 kfree(buf);
425 return ret;
426}
427
428int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
429 u32 datalen, u8 *data)
430{
431 struct saa7164_dev *dev = bus->dev;
432 u16 len = 0;
433 int unitid;
434 u32 regval;
435 u8 buf[256];
436 int ret;
437
438 dprintk(DBGLVL_API, "%s()\n", __func__);
439
440 if (reglen > 4)
441 return -EIO;
442
443 if (reglen == 1)
444 regval = *(reg);
445 else
446 if (reglen == 2)
447 regval = ((*(reg) << 8) || *(reg+1));
448 else
449 if (reglen == 3)
450 regval = ((*(reg) << 16) | (*(reg+1) << 8) | *(reg+2));
451 else
452 if (reglen == 4)
453 regval = ((*(reg) << 24) | (*(reg+1) << 16) |
454 (*(reg+2) << 8) | *(reg+3));
455
456 /* Prepare the send buffer */
457 /* Bytes 00-03 source register length
458 * 04-07 source bytes to read
459 * 08... register address
460 */
461 memset(buf, 0, sizeof(buf));
462 memcpy((buf + 2 * sizeof(u32) + 0), reg, reglen);
463 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
464 *((u32 *)(buf + 1 * sizeof(u32))) = datalen;
465
466 unitid = saa7164_i2caddr_to_unitid(bus, addr);
467 if (unitid < 0) {
468 printk(KERN_ERR
469 "%s() error, cannot translate regaddr 0x%x to unitid\n",
470 __func__, addr);
471 return -EIO;
472 }
473
474 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
475 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
476 if (ret != SAA_OK) {
477 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
478 return -EIO;
479 }
480
481 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
482
483 if (debug & DBGLVL_I2C)
484 saa7164_dumphex16(dev, buf, 2 * 16);
485
486 ret = saa7164_cmd_send(bus->dev, unitid, GET_CUR,
487 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
488 if (ret != SAA_OK)
489 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
490 else {
491 if (debug & DBGLVL_I2C)
492 saa7164_dumphex16(dev, buf, sizeof(buf));
493 memcpy(data, (buf + 2 * sizeof(u32) + reglen), datalen);
494 }
495
496 return ret == SAA_OK ? 0 : -EIO;
497}
498
499/* For a given 8 bit i2c address device, write the buffer */
500int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr, u32 datalen,
501 u8 *data)
502{
503 struct saa7164_dev *dev = bus->dev;
504 u16 len = 0;
505 int unitid;
506 int reglen;
507 u8 buf[256];
508 int ret;
509
510 dprintk(DBGLVL_API, "%s()\n", __func__);
511
512 if ((datalen == 0) || (datalen > 232))
513 return -EIO;
514
515 memset(buf, 0, sizeof(buf));
516
517 unitid = saa7164_i2caddr_to_unitid(bus, addr);
518 if (unitid < 0) {
519 printk(KERN_ERR
520 "%s() error, cannot translate regaddr 0x%x to unitid\n",
521 __func__, addr);
522 return -EIO;
523 }
524
525 reglen = saa7164_i2caddr_to_reglen(bus, addr);
526 if (unitid < 0) {
527 printk(KERN_ERR
528 "%s() error, cannot translate regaddr to reglen\n",
529 __func__);
530 return -EIO;
531 }
532
533 ret = saa7164_cmd_send(bus->dev, unitid, GET_LEN,
534 EXU_REGISTER_ACCESS_CONTROL, sizeof(len), &len);
535 if (ret != SAA_OK) {
536 printk(KERN_ERR "%s() error, ret(1) = 0x%x\n", __func__, ret);
537 return -EIO;
538 }
539
540 dprintk(DBGLVL_API, "%s() len = %d bytes\n", __func__, len);
541
542 /* Prepare the send buffer */
543 /* Bytes 00-03 dest register length
544 * 04-07 dest bytes to write
545 * 08... register address
546 */
547 *((u32 *)(buf + 0 * sizeof(u32))) = reglen;
548 *((u32 *)(buf + 1 * sizeof(u32))) = datalen - reglen;
549 memcpy((buf + 2 * sizeof(u32)), data, datalen);
550
551 if (debug & DBGLVL_I2C)
552 saa7164_dumphex16(dev, buf, sizeof(buf));
553
554 ret = saa7164_cmd_send(bus->dev, unitid, SET_CUR,
555 EXU_REGISTER_ACCESS_CONTROL, len, &buf);
556 if (ret != SAA_OK)
557 printk(KERN_ERR "%s() error, ret(2) = 0x%x\n", __func__, ret);
558
559 return ret == SAA_OK ? 0 : -EIO;
560}
561
562
563int saa7164_api_modify_gpio(struct saa7164_dev *dev, u8 unitid,
564 u8 pin, u8 state)
565{
566 int ret;
567 tmComResGPIO_t t;
568
569 dprintk(DBGLVL_API, "%s(0x%x, %d, %d)\n",
570 __func__, unitid, pin, state);
571
572 if ((pin > 7) || (state > 2))
573 return SAA_ERR_BAD_PARAMETER;
574
575 t.pin = pin;
576 t.state = state;
577
578 ret = saa7164_cmd_send(dev, unitid, SET_CUR,
579 EXU_GPIO_CONTROL, sizeof(t), &t);
580 if (ret != SAA_OK)
581 printk(KERN_ERR "%s() error, ret = 0x%x\n",
582 __func__, ret);
583
584 return ret;
585}
586
587int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid,
588 u8 pin)
589{
590 return saa7164_api_modify_gpio(dev, unitid, pin, 1);
591}
592
593int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid,
594 u8 pin)
595{
596 return saa7164_api_modify_gpio(dev, unitid, pin, 0);
597}
598
599
600
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
new file mode 100644
index 000000000000..9ca5c83d165b
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -0,0 +1,155 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "saa7164.h"
23
24/* The PCI address space for buffer handling looks like this:
25
26 +-u32 wide-------------+
27 | +
28 +-u64 wide------------------------------------+
29 + +
30 +----------------------+
31 | CurrentBufferPtr + Pointer to current PCI buffer >-+
32 +----------------------+ |
33 | Unused + |
34 +----------------------+ |
35 | Pitch + = 188 (bytes) |
36 +----------------------+ |
37 | PCI buffer size + = pitch * number of lines (312) |
38 +----------------------+ |
39 |0| Buf0 Write Offset + |
40 +----------------------+ v
41 |1| Buf1 Write Offset + |
42 +----------------------+ |
43 |2| Buf2 Write Offset + |
44 +----------------------+ |
45 |3| Buf3 Write Offset + |
46 +----------------------+ |
47 ... More write offsets |
48 +---------------------------------------------+ |
49 +0| set of ptrs to PCI pagetables + |
50 +---------------------------------------------+ |
51 +1| set of ptrs to PCI pagetables + <--------+
52 +---------------------------------------------+
53 +2| set of ptrs to PCI pagetables +
54 +---------------------------------------------+
55 +3| set of ptrs to PCI pagetables + >--+
56 +---------------------------------------------+ |
57 ... More buffer pointers | +----------------+
58 +->| pt[0] TS data |
59 | +----------------+
60 |
61 | +----------------+
62 +->| pt[1] TS data |
63 | +----------------+
64 | etc
65 */
66
67/* Allocate a new buffer structure and associated PCI space in bytes.
68 * len must be a multiple of sizeof(u64)
69 */
70struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
71 u32 len)
72{
73 struct saa7164_buffer *buf = 0;
74 struct saa7164_dev *dev = port->dev;
75 int i;
76
77 if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
78 log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
79 goto ret;
80 }
81
82 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
83 if (buf == NULL) {
84 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
85 goto ret;
86 }
87
88 buf->port = port;
89 buf->flags = SAA7164_BUFFER_FREE;
90 /* TODO: arg len is being ignored */
91 buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
92 buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
93
94 /* Allocate contiguous memory */
95 buf->cpu = pci_alloc_consistent(port->dev->pci, buf->pci_size,
96 &buf->dma);
97 if (!buf->cpu)
98 goto fail1;
99
100 buf->pt_cpu = pci_alloc_consistent(port->dev->pci, buf->pt_size,
101 &buf->pt_dma);
102 if (!buf->pt_cpu)
103 goto fail2;
104
105 /* init the buffers to a known pattern, easier during debugging */
106 memset(buf->cpu, 0xff, buf->pci_size);
107 memset(buf->pt_cpu, 0xff, buf->pt_size);
108
109 dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p\n", __func__, buf);
110 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
111 buf->cpu, (long)buf->dma, buf->pci_size);
112 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
113 buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
114
115 /* Format the Page Table Entries to point into the data buffer */
116 for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
117
118 *(buf->pt_cpu + i) = buf->dma + (i * 0x1000); /* TODO */
119
120 }
121
122 goto ret;
123
124fail2:
125 pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
126fail1:
127 kfree(buf);
128
129 buf = 0;
130ret:
131 return buf;
132}
133
134int saa7164_buffer_dealloc(struct saa7164_tsport *port,
135 struct saa7164_buffer *buf)
136{
137 struct saa7164_dev *dev = port->dev;
138
139 if ((buf == 0) || (port == 0))
140 return SAA_ERR_BAD_PARAMETER;
141
142 dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n", __func__, buf);
143
144 if (buf->flags != SAA7164_BUFFER_FREE)
145 log_warn(" freeing a non-free buffer\n");
146
147 pci_free_consistent(port->dev->pci, buf->pci_size, buf->cpu, buf->dma);
148 pci_free_consistent(port->dev->pci, buf->pt_size, buf->pt_cpu,
149 buf->pt_dma);
150
151 kfree(buf);
152
153 return SAA_OK;
154}
155
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
new file mode 100644
index 000000000000..83a04640a25a
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -0,0 +1,448 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "saa7164.h"
23
24/* The message bus to/from the firmware is a ring buffer in PCI address
25 * space. Establish the defaults.
26 */
27int saa7164_bus_setup(struct saa7164_dev *dev)
28{
29 tmComResBusInfo_t *b = &dev->bus;
30
31 mutex_init(&b->lock);
32
33 b->Type = TYPE_BUS_PCIe;
34 b->m_wMaxReqSize = SAA_DEVICE_MAXREQUESTSIZE;
35
36 b->m_pdwSetRing = (u8 *)(dev->bmmio +
37 ((u32)dev->busdesc.CommandRing));
38
39 b->m_dwSizeSetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
40
41 b->m_pdwGetRing = (u8 *)(dev->bmmio +
42 ((u32)dev->busdesc.ResponseRing));
43
44 b->m_dwSizeGetRing = SAA_DEVICE_BUFFERBLOCKSIZE;
45
46 b->m_pdwSetWritePos = (u32 *)((u8 *)(dev->bmmio +
47 ((u32)dev->intfdesc.BARLocation) + (2 * sizeof(u64))));
48
49 b->m_pdwSetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos +
50 1 * sizeof(u32));
51
52 b->m_pdwGetWritePos = (u32 *)((u8 *)b->m_pdwSetWritePos +
53 2 * sizeof(u32));
54
55 b->m_pdwGetReadPos = (u32 *)((u8 *)b->m_pdwSetWritePos +
56 3 * sizeof(u32));
57
58 return 0;
59}
60
61void saa7164_bus_dump(struct saa7164_dev *dev)
62{
63 tmComResBusInfo_t *b = &dev->bus;
64
65 dprintk(DBGLVL_BUS, "Dumping the bus structure:\n");
66 dprintk(DBGLVL_BUS, " .type = %d\n", b->Type);
67 dprintk(DBGLVL_BUS, " .dev->bmmio = 0x%p\n", dev->bmmio);
68 dprintk(DBGLVL_BUS, " .m_wMaxReqSize = 0x%x\n", b->m_wMaxReqSize);
69 dprintk(DBGLVL_BUS, " .m_pdwSetRing = 0x%p\n", b->m_pdwSetRing);
70 dprintk(DBGLVL_BUS, " .m_dwSizeSetRing = 0x%x\n", b->m_dwSizeSetRing);
71 dprintk(DBGLVL_BUS, " .m_pdwGetRing = 0x%p\n", b->m_pdwGetRing);
72 dprintk(DBGLVL_BUS, " .m_dwSizeGetRing = 0x%x\n", b->m_dwSizeGetRing);
73
74 dprintk(DBGLVL_BUS, " .m_pdwSetWritePos = 0x%p (0x%08x)\n",
75 b->m_pdwSetWritePos, *b->m_pdwSetWritePos);
76
77 dprintk(DBGLVL_BUS, " .m_pdwSetReadPos = 0x%p (0x%08x)\n",
78 b->m_pdwSetReadPos, *b->m_pdwSetReadPos);
79
80 dprintk(DBGLVL_BUS, " .m_pdwGetWritePos = 0x%p (0x%08x)\n",
81 b->m_pdwGetWritePos, *b->m_pdwGetWritePos);
82
83 dprintk(DBGLVL_BUS, " .m_pdwGetReadPos = 0x%p (0x%08x)\n",
84 b->m_pdwGetReadPos, *b->m_pdwGetReadPos);
85}
86
87void saa7164_bus_dumpmsg(struct saa7164_dev *dev, tmComResInfo_t* m, void *buf)
88{
89 dprintk(DBGLVL_BUS, "Dumping msg structure:\n");
90 dprintk(DBGLVL_BUS, " .id = %d\n", m->id);
91 dprintk(DBGLVL_BUS, " .flags = 0x%x\n", m->flags);
92 dprintk(DBGLVL_BUS, " .size = 0x%x\n", m->size);
93 dprintk(DBGLVL_BUS, " .command = 0x%x\n", m->command);
94 dprintk(DBGLVL_BUS, " .controlselector = 0x%x\n", m->controlselector);
95 dprintk(DBGLVL_BUS, " .seqno = %d\n", m->seqno);
96 if (buf)
97 dprintk(DBGLVL_BUS, " .buffer (ignored)\n");
98}
99
100/*
101 * Places a command or a response on the bus. The implementation does not
102 * know if it is a command or a response it just places the data on the
103 * bus depending on the bus information given in the tmComResBusInfo_t
104 * structure. If the command or response does not fit into the bus ring
105 * buffer it will be refused.
106 *
107 * Return Value:
108 * SAA_OK The function executed successfully.
109 * < 0 One or more members are not initialized.
110 */
111int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
112{
113 tmComResBusInfo_t *bus = &dev->bus;
114 u32 bytes_to_write, read_distance, timeout, curr_srp, curr_swp;
115 u32 new_swp, space_rem;
116 int ret = SAA_ERR_BAD_PARAMETER;
117
118 if (!msg) {
119 printk(KERN_ERR "%s() !msg\n", __func__);
120 return SAA_ERR_BAD_PARAMETER;
121 }
122
123 dprintk(DBGLVL_BUS, "%s()\n", __func__);
124
125 msg->size = cpu_to_le16(msg->size);
126 msg->command = cpu_to_le16(msg->command);
127 msg->controlselector = cpu_to_le16(msg->controlselector);
128
129 if (msg->size > dev->bus.m_wMaxReqSize) {
130 printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
131 __func__);
132 return SAA_ERR_BAD_PARAMETER;
133 }
134
135 if ((msg->size > 0) && (buf == 0)) {
136 printk(KERN_ERR "%s() Missing message buffer\n", __func__);
137 return SAA_ERR_BAD_PARAMETER;
138 }
139
140 /* Lock the bus from any other access */
141 mutex_lock(&bus->lock);
142
143 bytes_to_write = sizeof(*msg) + msg->size;
144 read_distance = 0;
145 timeout = SAA_BUS_TIMEOUT;
146 curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
147 curr_swp = le32_to_cpu(*bus->m_pdwSetWritePos);
148
149 /* Deal with ring wrapping issues */
150 if (curr_srp > curr_swp)
151 /* The ring has not wrapped yet */
152 read_distance = curr_srp - curr_swp;
153 else
154 /* Deal with the wrapped ring */
155 read_distance = (curr_srp + bus->m_dwSizeSetRing) - curr_swp;
156
157 dprintk(DBGLVL_BUS, "%s() bytes_to_write = %d\n", __func__,
158 bytes_to_write);
159
160 dprintk(DBGLVL_BUS, "%s() read_distance = %d\n", __func__,
161 read_distance);
162
163 dprintk(DBGLVL_BUS, "%s() curr_srp = %x\n", __func__, curr_srp);
164 dprintk(DBGLVL_BUS, "%s() curr_swp = %x\n", __func__, curr_swp);
165
166 /* Process the msg and write the content onto the bus */
167 while (bytes_to_write >= read_distance) {
168
169 if (timeout-- == 0) {
170 printk(KERN_ERR "%s() bus timeout\n", __func__);
171 ret = SAA_ERR_NO_RESOURCES;
172 goto out;
173 }
174
175 /* TODO: Review this delay, efficient? */
176 /* Wait, allowing the hardware fetch time */
177 mdelay(1);
178
179 /* Check the space usage again */
180 curr_srp = le32_to_cpu(*bus->m_pdwSetReadPos);
181
182 /* Deal with ring wrapping issues */
183 if (curr_srp > curr_swp)
184 /* Read didn't wrap around the buffer */
185 read_distance = curr_srp - curr_swp;
186 else
187 /* Deal with the wrapped ring */
188 read_distance = (curr_srp + bus->m_dwSizeSetRing) -
189 curr_swp;
190
191 }
192
193 /* Calculate the new write position */
194 new_swp = curr_swp + bytes_to_write;
195
196 dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
197 dprintk(DBGLVL_BUS, "%s() bus->m_dwSizeSetRing = %x\n", __func__,
198 bus->m_dwSizeSetRing);
199
200 /* Mental Note: line 462 tmmhComResBusPCIe.cpp */
201
202 /* Check if we're going to wrap again */
203 if (new_swp > bus->m_dwSizeSetRing) {
204
205 /* Ring wraps */
206 new_swp -= bus->m_dwSizeSetRing;
207
208 space_rem = bus->m_dwSizeSetRing - curr_swp;
209
210 dprintk(DBGLVL_BUS, "%s() space_rem = %x\n", __func__,
211 space_rem);
212
213 dprintk(DBGLVL_BUS, "%s() sizeof(*msg) = %d\n", __func__,
214 (u32)sizeof(*msg));
215
216 if (space_rem < sizeof(*msg)) {
217 dprintk(DBGLVL_BUS, "%s() tr4\n", __func__);
218
219 /* Split the msg into pieces as the ring wraps */
220 memcpy(bus->m_pdwSetRing + curr_swp, msg, space_rem);
221 memcpy(bus->m_pdwSetRing, (u8 *)msg + space_rem,
222 sizeof(*msg) - space_rem);
223
224 memcpy(bus->m_pdwSetRing + sizeof(*msg) - space_rem,
225 buf, msg->size);
226
227 } else if (space_rem == sizeof(*msg)) {
228 dprintk(DBGLVL_BUS, "%s() tr5\n", __func__);
229
230 /* Additional data at the beginning of the ring */
231 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
232 memcpy(bus->m_pdwSetRing, buf, msg->size);
233
234 } else {
235 /* Additional data wraps around the ring */
236 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
237 if (msg->size > 0) {
238 memcpy(bus->m_pdwSetRing + curr_swp +
239 sizeof(*msg), buf, space_rem -
240 sizeof(*msg));
241 memcpy(bus->m_pdwSetRing, (u8 *)buf +
242 space_rem - sizeof(*msg),
243 bytes_to_write - space_rem);
244 }
245
246 }
247
248 } /* (new_swp > bus->m_dwSizeSetRing) */
249 else {
250 dprintk(DBGLVL_BUS, "%s() tr6\n", __func__);
251
252 /* The ring buffer doesn't wrap, two simple copies */
253 memcpy(bus->m_pdwSetRing + curr_swp, msg, sizeof(*msg));
254 memcpy(bus->m_pdwSetRing + curr_swp + sizeof(*msg), buf,
255 msg->size);
256 }
257
258 dprintk(DBGLVL_BUS, "%s() new_swp = %x\n", __func__, new_swp);
259
260 /* TODO: Convert all of the direct PCI writes into
261 * saa7164_writel/b calls for consistency.
262 */
263
264 /* Update the bus write position */
265 *bus->m_pdwSetWritePos = cpu_to_le32(new_swp);
266 ret = SAA_OK;
267
268out:
269 mutex_unlock(&bus->lock);
270 return ret;
271}
272
273/*
274 * Receive a command or a response from the bus. The implementation does not
275 * know if it is a command or a response it simply dequeues the data,
276 * depending on the bus information given in the tmComResBusInfo_t structure.
277 *
278 * Return Value:
279 * 0 The function executed successfully.
280 * < 0 One or more members are not initialized.
281 */
282int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf,
283 int peekonly)
284{
285 tmComResBusInfo_t *bus = &dev->bus;
286 u32 bytes_to_read, write_distance, curr_grp, curr_gwp,
287 new_grp, buf_size, space_rem;
288 tmComResInfo_t msg_tmp;
289 int ret = SAA_ERR_BAD_PARAMETER;
290
291 if (msg == 0)
292 return ret;
293
294 if (msg->size > dev->bus.m_wMaxReqSize) {
295 printk(KERN_ERR "%s() Exceeded dev->bus.m_wMaxReqSize\n",
296 __func__);
297 return ret;
298 }
299
300 if ((peekonly == 0) && (msg->size > 0) && (buf == 0)) {
301 printk(KERN_ERR
302 "%s() Missing msg buf, size should be %d bytes\n",
303 __func__, msg->size);
304 return ret;
305 }
306
307 mutex_lock(&bus->lock);
308
309 /* Peek the bus to see if a msg exists, if it's not what we're expecting
310 * then return cleanly else read the message from the bus.
311 */
312 curr_gwp = le32_to_cpu(*bus->m_pdwGetWritePos);
313 curr_grp = le32_to_cpu(*bus->m_pdwGetReadPos);
314
315 if (curr_gwp == curr_grp) {
316 dprintk(DBGLVL_BUS, "%s() No message on the bus\n", __func__);
317 ret = SAA_ERR_EMPTY;
318 goto out;
319 }
320
321 bytes_to_read = sizeof(*msg);
322
323 /* Calculate write distance to current read position */
324 write_distance = 0;
325 if (curr_gwp >= curr_grp)
326 /* Write doesn't wrap around the ring */
327 write_distance = curr_gwp - curr_grp;
328 else
329 /* Write wraps around the ring */
330 write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
331
332 if (bytes_to_read > write_distance) {
333 printk(KERN_ERR "%s() No message/response found\n", __func__);
334 ret = SAA_ERR_INVALID_COMMAND;
335 goto out;
336 }
337
338 /* Calculate the new read position */
339 new_grp = curr_grp + bytes_to_read;
340 if (new_grp > bus->m_dwSizeGetRing) {
341
342 /* Ring wraps */
343 new_grp -= bus->m_dwSizeGetRing;
344 space_rem = bus->m_dwSizeGetRing - curr_grp;
345
346 memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, space_rem);
347 memcpy((u8 *)&msg_tmp + space_rem, bus->m_pdwGetRing,
348 bytes_to_read - space_rem);
349
350 } else {
351 /* No wrapping */
352 memcpy(&msg_tmp, bus->m_pdwGetRing + curr_grp, bytes_to_read);
353 }
354
355 /* No need to update the read positions, because this was a peek */
356 /* If the caller specifically want to peek, return */
357 if (peekonly) {
358 memcpy(msg, &msg_tmp, sizeof(*msg));
359 goto peekout;
360 }
361
362 /* Check if the command/response matches what is expected */
363 if ((msg_tmp.id != msg->id) || (msg_tmp.command != msg->command) ||
364 (msg_tmp.controlselector != msg->controlselector) ||
365 (msg_tmp.seqno != msg->seqno) || (msg_tmp.size != msg->size)) {
366
367 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
368 saa7164_bus_dumpmsg(dev, msg, buf);
369 saa7164_bus_dumpmsg(dev, &msg_tmp, 0);
370 ret = SAA_ERR_INVALID_COMMAND;
371 goto out;
372 }
373
374 /* Get the actual command and response from the bus */
375 buf_size = msg->size;
376
377 bytes_to_read = sizeof(*msg) + msg->size;
378 /* Calculate write distance to current read position */
379 write_distance = 0;
380 if (curr_gwp >= curr_grp)
381 /* Write doesn't wrap around the ring */
382 write_distance = curr_gwp - curr_grp;
383 else
384 /* Write wraps around the ring */
385 write_distance = curr_gwp + bus->m_dwSizeGetRing - curr_grp;
386
387 if (bytes_to_read > write_distance) {
388 printk(KERN_ERR "%s() Invalid bus state, missing msg "
389 "or mangled ring, faulty H/W / bad code?\n", __func__);
390 ret = SAA_ERR_INVALID_COMMAND;
391 goto out;
392 }
393
394 /* Calculate the new read position */
395 new_grp = curr_grp + bytes_to_read;
396 if (new_grp > bus->m_dwSizeGetRing) {
397
398 /* Ring wraps */
399 new_grp -= bus->m_dwSizeGetRing;
400 space_rem = bus->m_dwSizeGetRing - curr_grp;
401
402 if (space_rem < sizeof(*msg)) {
403 /* msg wraps around the ring */
404 memcpy(msg, bus->m_pdwGetRing + curr_grp, space_rem);
405 memcpy((u8 *)msg + space_rem, bus->m_pdwGetRing,
406 sizeof(*msg) - space_rem);
407 if (buf)
408 memcpy(buf, bus->m_pdwGetRing + sizeof(*msg) -
409 space_rem, buf_size);
410
411 } else if (space_rem == sizeof(*msg)) {
412 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
413 if (buf)
414 memcpy(buf, bus->m_pdwGetRing, buf_size);
415 } else {
416 /* Additional data wraps around the ring */
417 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
418 if (buf) {
419 memcpy(buf, bus->m_pdwGetRing + curr_grp +
420 sizeof(*msg), space_rem - sizeof(*msg));
421 memcpy(buf + space_rem - sizeof(*msg),
422 bus->m_pdwGetRing, bytes_to_read -
423 space_rem);
424 }
425
426 }
427
428 } else {
429 /* No wrapping */
430 memcpy(msg, bus->m_pdwGetRing + curr_grp, sizeof(*msg));
431 if (buf)
432 memcpy(buf, bus->m_pdwGetRing + curr_grp + sizeof(*msg),
433 buf_size);
434 }
435
436 /* Update the read positions, adjusting the ring */
437 *bus->m_pdwGetReadPos = cpu_to_le32(new_grp);
438
439peekout:
440 msg->size = le16_to_cpu(msg->size);
441 msg->command = le16_to_cpu(msg->command);
442 msg->controlselector = le16_to_cpu(msg->controlselector);
443 ret = SAA_OK;
444out:
445 mutex_unlock(&bus->lock);
446 return ret;
447}
448
diff --git a/drivers/media/video/saa7164/saa7164-cards.c b/drivers/media/video/saa7164/saa7164-cards.c
new file mode 100644
index 000000000000..a3c299405f46
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cards.c
@@ -0,0 +1,624 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/pci.h>
25#include <linux/delay.h>
26
27#include "saa7164.h"
28
29/* The Bridge API needs to understand register widths (in bytes) for the
30 * attached I2C devices, so we can simplify the virtual i2c mechansms
31 * and keep the -i2c.c implementation clean.
32 */
33#define REGLEN_8bit 1
34#define REGLEN_16bit 2
35
36struct saa7164_board saa7164_boards[] = {
37 [SAA7164_BOARD_UNKNOWN] = {
38 /* Bridge will not load any firmware, without knowing
39 * the rev this would be fatal. */
40 .name = "Unknown",
41 },
42 [SAA7164_BOARD_UNKNOWN_REV2] = {
43 /* Bridge will load the v2 f/w and dump descriptors */
44 /* Required during new board bringup */
45 .name = "Generic Rev2",
46 .chiprev = SAA7164_CHIP_REV2,
47 },
48 [SAA7164_BOARD_UNKNOWN_REV3] = {
49 /* Bridge will load the v2 f/w and dump descriptors */
50 /* Required during new board bringup */
51 .name = "Generic Rev3",
52 .chiprev = SAA7164_CHIP_REV3,
53 },
54 [SAA7164_BOARD_HAUPPAUGE_HVR2200] = {
55 .name = "Hauppauge WinTV-HVR2200",
56 .porta = SAA7164_MPEG_DVB,
57 .portb = SAA7164_MPEG_DVB,
58 .chiprev = SAA7164_CHIP_REV3,
59 .unit = {{
60 .id = 0x1d,
61 .type = SAA7164_UNIT_EEPROM,
62 .name = "4K EEPROM",
63 .i2c_bus_nr = SAA7164_I2C_BUS_0,
64 .i2c_bus_addr = 0xa0 >> 1,
65 .i2c_reg_len = REGLEN_8bit,
66 }, {
67 .id = 0x04,
68 .type = SAA7164_UNIT_TUNER,
69 .name = "TDA18271-1",
70 .i2c_bus_nr = SAA7164_I2C_BUS_1,
71 .i2c_bus_addr = 0xc0 >> 1,
72 .i2c_reg_len = REGLEN_8bit,
73 }, {
74 .id = 0x1b,
75 .type = SAA7164_UNIT_TUNER,
76 .name = "TDA18271-2",
77 .i2c_bus_nr = SAA7164_I2C_BUS_2,
78 .i2c_bus_addr = 0xc0 >> 1,
79 .i2c_reg_len = REGLEN_8bit,
80 }, {
81 .id = 0x1e,
82 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
83 .name = "TDA10048-1",
84 .i2c_bus_nr = SAA7164_I2C_BUS_1,
85 .i2c_bus_addr = 0x10 >> 1,
86 .i2c_reg_len = REGLEN_8bit,
87 }, {
88 .id = 0x1f,
89 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
90 .name = "TDA10048-2",
91 .i2c_bus_nr = SAA7164_I2C_BUS_2,
92 .i2c_bus_addr = 0x12 >> 1,
93 .i2c_reg_len = REGLEN_8bit,
94 } },
95 },
96 [SAA7164_BOARD_HAUPPAUGE_HVR2200_2] = {
97 .name = "Hauppauge WinTV-HVR2200",
98 .porta = SAA7164_MPEG_DVB,
99 .portb = SAA7164_MPEG_DVB,
100 .chiprev = SAA7164_CHIP_REV2,
101 .unit = {{
102 .id = 0x06,
103 .type = SAA7164_UNIT_EEPROM,
104 .name = "4K EEPROM",
105 .i2c_bus_nr = SAA7164_I2C_BUS_0,
106 .i2c_bus_addr = 0xa0 >> 1,
107 .i2c_reg_len = REGLEN_8bit,
108 }, {
109 .id = 0x04,
110 .type = SAA7164_UNIT_TUNER,
111 .name = "TDA18271-1",
112 .i2c_bus_nr = SAA7164_I2C_BUS_1,
113 .i2c_bus_addr = 0xc0 >> 1,
114 .i2c_reg_len = REGLEN_8bit,
115 }, {
116 .id = 0x05,
117 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
118 .name = "TDA10048-1",
119 .i2c_bus_nr = SAA7164_I2C_BUS_1,
120 .i2c_bus_addr = 0x10 >> 1,
121 .i2c_reg_len = REGLEN_8bit,
122 }, {
123 .id = 0x1e,
124 .type = SAA7164_UNIT_TUNER,
125 .name = "TDA18271-2",
126 .i2c_bus_nr = SAA7164_I2C_BUS_2,
127 .i2c_bus_addr = 0xc0 >> 1,
128 .i2c_reg_len = REGLEN_8bit,
129 }, {
130 .id = 0x1f,
131 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
132 .name = "TDA10048-2",
133 .i2c_bus_nr = SAA7164_I2C_BUS_2,
134 .i2c_bus_addr = 0x12 >> 1,
135 .i2c_reg_len = REGLEN_8bit,
136 } },
137 },
138 [SAA7164_BOARD_HAUPPAUGE_HVR2200_3] = {
139 .name = "Hauppauge WinTV-HVR2200",
140 .porta = SAA7164_MPEG_DVB,
141 .portb = SAA7164_MPEG_DVB,
142 .chiprev = SAA7164_CHIP_REV2,
143 .unit = {{
144 .id = 0x1d,
145 .type = SAA7164_UNIT_EEPROM,
146 .name = "4K EEPROM",
147 .i2c_bus_nr = SAA7164_I2C_BUS_0,
148 .i2c_bus_addr = 0xa0 >> 1,
149 .i2c_reg_len = REGLEN_8bit,
150 }, {
151 .id = 0x04,
152 .type = SAA7164_UNIT_TUNER,
153 .name = "TDA18271-1",
154 .i2c_bus_nr = SAA7164_I2C_BUS_1,
155 .i2c_bus_addr = 0xc0 >> 1,
156 .i2c_reg_len = REGLEN_8bit,
157 }, {
158 .id = 0x05,
159 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
160 .name = "TDA8290-1",
161 .i2c_bus_nr = SAA7164_I2C_BUS_1,
162 .i2c_bus_addr = 0x84 >> 1,
163 .i2c_reg_len = REGLEN_8bit,
164 }, {
165 .id = 0x1b,
166 .type = SAA7164_UNIT_TUNER,
167 .name = "TDA18271-2",
168 .i2c_bus_nr = SAA7164_I2C_BUS_2,
169 .i2c_bus_addr = 0xc0 >> 1,
170 .i2c_reg_len = REGLEN_8bit,
171 }, {
172 .id = 0x1c,
173 .type = SAA7164_UNIT_ANALOG_DEMODULATOR,
174 .name = "TDA8290-2",
175 .i2c_bus_nr = SAA7164_I2C_BUS_2,
176 .i2c_bus_addr = 0x84 >> 1,
177 .i2c_reg_len = REGLEN_8bit,
178 }, {
179 .id = 0x1e,
180 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
181 .name = "TDA10048-1",
182 .i2c_bus_nr = SAA7164_I2C_BUS_1,
183 .i2c_bus_addr = 0x10 >> 1,
184 .i2c_reg_len = REGLEN_8bit,
185 }, {
186 .id = 0x1f,
187 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
188 .name = "TDA10048-2",
189 .i2c_bus_nr = SAA7164_I2C_BUS_2,
190 .i2c_bus_addr = 0x12 >> 1,
191 .i2c_reg_len = REGLEN_8bit,
192 } },
193 },
194 [SAA7164_BOARD_HAUPPAUGE_HVR2250] = {
195 .name = "Hauppauge WinTV-HVR2250",
196 .porta = SAA7164_MPEG_DVB,
197 .portb = SAA7164_MPEG_DVB,
198 .chiprev = SAA7164_CHIP_REV3,
199 .unit = {{
200 .id = 0x22,
201 .type = SAA7164_UNIT_EEPROM,
202 .name = "4K EEPROM",
203 .i2c_bus_nr = SAA7164_I2C_BUS_0,
204 .i2c_bus_addr = 0xa0 >> 1,
205 .i2c_reg_len = REGLEN_8bit,
206 }, {
207 .id = 0x04,
208 .type = SAA7164_UNIT_TUNER,
209 .name = "TDA18271-1",
210 .i2c_bus_nr = SAA7164_I2C_BUS_1,
211 .i2c_bus_addr = 0xc0 >> 1,
212 .i2c_reg_len = REGLEN_8bit,
213 }, {
214 .id = 0x07,
215 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
216 .name = "CX24228/S5H1411-1 (TOP)",
217 .i2c_bus_nr = SAA7164_I2C_BUS_1,
218 .i2c_bus_addr = 0x32 >> 1,
219 .i2c_reg_len = REGLEN_8bit,
220 }, {
221 .id = 0x08,
222 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
223 .name = "CX24228/S5H1411-1 (QAM)",
224 .i2c_bus_nr = SAA7164_I2C_BUS_1,
225 .i2c_bus_addr = 0x34 >> 1,
226 .i2c_reg_len = REGLEN_8bit,
227 }, {
228 .id = 0x1e,
229 .type = SAA7164_UNIT_TUNER,
230 .name = "TDA18271-2",
231 .i2c_bus_nr = SAA7164_I2C_BUS_2,
232 .i2c_bus_addr = 0xc0 >> 1,
233 .i2c_reg_len = REGLEN_8bit,
234 }, {
235 .id = 0x20,
236 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
237 .name = "CX24228/S5H1411-2 (TOP)",
238 .i2c_bus_nr = SAA7164_I2C_BUS_2,
239 .i2c_bus_addr = 0x32 >> 1,
240 .i2c_reg_len = REGLEN_8bit,
241 }, {
242 .id = 0x23,
243 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
244 .name = "CX24228/S5H1411-2 (QAM)",
245 .i2c_bus_nr = SAA7164_I2C_BUS_2,
246 .i2c_bus_addr = 0x34 >> 1,
247 .i2c_reg_len = REGLEN_8bit,
248 } },
249 },
250 [SAA7164_BOARD_HAUPPAUGE_HVR2250_2] = {
251 .name = "Hauppauge WinTV-HVR2250",
252 .porta = SAA7164_MPEG_DVB,
253 .portb = SAA7164_MPEG_DVB,
254 .chiprev = SAA7164_CHIP_REV3,
255 .unit = {{
256 .id = 0x28,
257 .type = SAA7164_UNIT_EEPROM,
258 .name = "4K EEPROM",
259 .i2c_bus_nr = SAA7164_I2C_BUS_0,
260 .i2c_bus_addr = 0xa0 >> 1,
261 .i2c_reg_len = REGLEN_8bit,
262 }, {
263 .id = 0x04,
264 .type = SAA7164_UNIT_TUNER,
265 .name = "TDA18271-1",
266 .i2c_bus_nr = SAA7164_I2C_BUS_1,
267 .i2c_bus_addr = 0xc0 >> 1,
268 .i2c_reg_len = REGLEN_8bit,
269 }, {
270 .id = 0x07,
271 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
272 .name = "CX24228/S5H1411-1 (TOP)",
273 .i2c_bus_nr = SAA7164_I2C_BUS_1,
274 .i2c_bus_addr = 0x32 >> 1,
275 .i2c_reg_len = REGLEN_8bit,
276 }, {
277 .id = 0x08,
278 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
279 .name = "CX24228/S5H1411-1 (QAM)",
280 .i2c_bus_nr = SAA7164_I2C_BUS_1,
281 .i2c_bus_addr = 0x34 >> 1,
282 .i2c_reg_len = REGLEN_8bit,
283 }, {
284 .id = 0x24,
285 .type = SAA7164_UNIT_TUNER,
286 .name = "TDA18271-2",
287 .i2c_bus_nr = SAA7164_I2C_BUS_2,
288 .i2c_bus_addr = 0xc0 >> 1,
289 .i2c_reg_len = REGLEN_8bit,
290 }, {
291 .id = 0x26,
292 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
293 .name = "CX24228/S5H1411-2 (TOP)",
294 .i2c_bus_nr = SAA7164_I2C_BUS_2,
295 .i2c_bus_addr = 0x32 >> 1,
296 .i2c_reg_len = REGLEN_8bit,
297 }, {
298 .id = 0x29,
299 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
300 .name = "CX24228/S5H1411-2 (QAM)",
301 .i2c_bus_nr = SAA7164_I2C_BUS_2,
302 .i2c_bus_addr = 0x34 >> 1,
303 .i2c_reg_len = REGLEN_8bit,
304 } },
305 },
306 [SAA7164_BOARD_HAUPPAUGE_HVR2250_3] = {
307 .name = "Hauppauge WinTV-HVR2250",
308 .porta = SAA7164_MPEG_DVB,
309 .portb = SAA7164_MPEG_DVB,
310 .chiprev = SAA7164_CHIP_REV3,
311 .unit = {{
312 .id = 0x26,
313 .type = SAA7164_UNIT_EEPROM,
314 .name = "4K EEPROM",
315 .i2c_bus_nr = SAA7164_I2C_BUS_0,
316 .i2c_bus_addr = 0xa0 >> 1,
317 .i2c_reg_len = REGLEN_8bit,
318 }, {
319 .id = 0x04,
320 .type = SAA7164_UNIT_TUNER,
321 .name = "TDA18271-1",
322 .i2c_bus_nr = SAA7164_I2C_BUS_1,
323 .i2c_bus_addr = 0xc0 >> 1,
324 .i2c_reg_len = REGLEN_8bit,
325 }, {
326 .id = 0x07,
327 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
328 .name = "CX24228/S5H1411-1 (TOP)",
329 .i2c_bus_nr = SAA7164_I2C_BUS_1,
330 .i2c_bus_addr = 0x32 >> 1,
331 .i2c_reg_len = REGLEN_8bit,
332 }, {
333 .id = 0x08,
334 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
335 .name = "CX24228/S5H1411-1 (QAM)",
336 .i2c_bus_nr = SAA7164_I2C_BUS_1,
337 .i2c_bus_addr = 0x34 >> 1,
338 .i2c_reg_len = REGLEN_8bit,
339 }, {
340 .id = 0x22,
341 .type = SAA7164_UNIT_TUNER,
342 .name = "TDA18271-2",
343 .i2c_bus_nr = SAA7164_I2C_BUS_2,
344 .i2c_bus_addr = 0xc0 >> 1,
345 .i2c_reg_len = REGLEN_8bit,
346 }, {
347 .id = 0x24,
348 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
349 .name = "CX24228/S5H1411-2 (TOP)",
350 .i2c_bus_nr = SAA7164_I2C_BUS_2,
351 .i2c_bus_addr = 0x32 >> 1,
352 .i2c_reg_len = REGLEN_8bit,
353 }, {
354 .id = 0x27,
355 .type = SAA7164_UNIT_DIGITAL_DEMODULATOR,
356 .name = "CX24228/S5H1411-2 (QAM)",
357 .i2c_bus_nr = SAA7164_I2C_BUS_2,
358 .i2c_bus_addr = 0x34 >> 1,
359 .i2c_reg_len = REGLEN_8bit,
360 } },
361 },
362};
363const unsigned int saa7164_bcount = ARRAY_SIZE(saa7164_boards);
364
365/* ------------------------------------------------------------------ */
366/* PCI subsystem IDs */
367
368struct saa7164_subid saa7164_subids[] = {
369 {
370 .subvendor = 0x0070,
371 .subdevice = 0x8880,
372 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
373 }, {
374 .subvendor = 0x0070,
375 .subdevice = 0x8810,
376 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250,
377 }, {
378 .subvendor = 0x0070,
379 .subdevice = 0x8980,
380 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200,
381 }, {
382 .subvendor = 0x0070,
383 .subdevice = 0x8900,
384 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_2,
385 }, {
386 .subvendor = 0x0070,
387 .subdevice = 0x8901,
388 .card = SAA7164_BOARD_HAUPPAUGE_HVR2200_3,
389 }, {
390 .subvendor = 0x0070,
391 .subdevice = 0x88A1,
392 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_3,
393 }, {
394 .subvendor = 0x0070,
395 .subdevice = 0x8891,
396 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
397 }, {
398 .subvendor = 0x0070,
399 .subdevice = 0x8851,
400 .card = SAA7164_BOARD_HAUPPAUGE_HVR2250_2,
401 },
402};
403const unsigned int saa7164_idcount = ARRAY_SIZE(saa7164_subids);
404
405void saa7164_card_list(struct saa7164_dev *dev)
406{
407 int i;
408
409 if (0 == dev->pci->subsystem_vendor &&
410 0 == dev->pci->subsystem_device) {
411 printk(KERN_ERR
412 "%s: Board has no valid PCIe Subsystem ID and can't\n"
413 "%s: be autodetected. Pass card=<n> insmod option to\n"
414 "%s: workaround that. Send complaints to the vendor\n"
415 "%s: of the TV card. Best regards,\n"
416 "%s: -- tux\n",
417 dev->name, dev->name, dev->name, dev->name, dev->name);
418 } else {
419 printk(KERN_ERR
420 "%s: Your board isn't known (yet) to the driver.\n"
421 "%s: Try to pick one of the existing card configs via\n"
422 "%s: card=<n> insmod option. Updating to the latest\n"
423 "%s: version might help as well.\n",
424 dev->name, dev->name, dev->name, dev->name);
425 }
426
427 printk(KERN_ERR "%s: Here are valid choices for the card=<n> insmod "
428 "option:\n", dev->name);
429
430 for (i = 0; i < saa7164_bcount; i++)
431 printk(KERN_ERR "%s: card=%d -> %s\n",
432 dev->name, i, saa7164_boards[i].name);
433}
434
435/* TODO: clean this define up into the -cards.c structs */
436#define PCIEBRIDGE_UNITID 2
437
438void saa7164_gpio_setup(struct saa7164_dev *dev)
439{
440
441
442 switch (dev->board) {
443 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
444 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
445 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
446 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
447 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
448 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
449 /*
450 GPIO 2: s5h1411 / tda10048-1 demod reset
451 GPIO 3: s5h1411 / tda10048-2 demod reset
452 GPIO 7: IRBlaster Zilog reset
453 */
454
455 /* Reset parts by going in and out of reset */
456 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
457 saa7164_api_clear_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
458
459 msleep(10);
460
461 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 2);
462 saa7164_api_set_gpiobit(dev, PCIEBRIDGE_UNITID, 3);
463 break;
464 }
465
466}
467
468static void hauppauge_eeprom(struct saa7164_dev *dev, u8 *eeprom_data)
469{
470 struct tveeprom tv;
471
472 /* TODO: Assumption: eeprom on bus 0 */
473 tveeprom_hauppauge_analog(&dev->i2c_bus[0].i2c_client, &tv,
474 eeprom_data);
475
476 /* Make sure we support the board model */
477 switch (tv.model) {
478 case 88001:
479 /* Development board - Limit circulation */
480 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
481 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
482 case 88021:
483 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
484 * ATSC/QAM (TDA18271/S5H1411) and basic analog, MCE CIR, FM */
485 break;
486 case 88041:
487 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
488 * ATSC/QAM (TDA18271/S5H1411) and basic analog, no IR, FM */
489 break;
490 case 88061:
491 /* WinTV-HVR2250 (PCIe, Retail, full-height bracket)
492 * ATSC/QAM (TDA18271/S5H1411) and basic analog, FM */
493 break;
494 case 89519:
495 case 89609:
496 /* WinTV-HVR2200 (PCIe, Retail, full-height)
497 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
498 break;
499 case 89619:
500 /* WinTV-HVR2200 (PCIe, Retail, half-height)
501 * DVB-T (TDA18271/TDA10048) and basic analog, no IR */
502 break;
503 default:
504 printk(KERN_ERR "%s: Warning: Unknown Hauppauge model #%d\n",
505 dev->name, tv.model);
506 break;
507 }
508
509 printk(KERN_INFO "%s: Hauppauge eeprom: model=%d\n", dev->name,
510 tv.model);
511}
512
513void saa7164_card_setup(struct saa7164_dev *dev)
514{
515 static u8 eeprom[256];
516
517 if (dev->i2c_bus[0].i2c_rc == 0) {
518 if (saa7164_api_read_eeprom(dev, &eeprom[0],
519 sizeof(eeprom)) < 0)
520 return;
521 }
522
523 switch (dev->board) {
524 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
525 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
526 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
527 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
528 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
529 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
530 hauppauge_eeprom(dev, &eeprom[0]);
531 break;
532 }
533}
534
535/* With most other drivers, the kernel expects to communicate with subdrivers
536 * through i2c. This bridge does not allow that, it does not expose any direct
537 * access to I2C. Instead we have to communicate through the device f/w for
538 * register access to 'processing units'. Each unit has a unique
539 * id, regardless of how the physical implementation occurs across
540 * the three physical i2c busses. The being said if we want leverge of
541 * the existing kernel drivers for tuners and demods we have to 'speak i2c',
542 * to this bridge implements 3 virtual i2c buses. This is a helper function
543 * for those.
544 *
545 * Description: Translate the kernels notion of an i2c address and bus into
546 * the appropriate unitid.
547 */
548int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr)
549{
550 /* For a given bus and i2c device address, return the saa7164 unique
551 * unitid. < 0 on error */
552
553 struct saa7164_dev *dev = bus->dev;
554 struct saa7164_unit *unit;
555 int i;
556
557 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
558 unit = &saa7164_boards[dev->board].unit[i];
559
560 if (unit->type == SAA7164_UNIT_UNDEFINED)
561 continue;
562 if ((bus->nr == unit->i2c_bus_nr) &&
563 (addr == unit->i2c_bus_addr))
564 return unit->id;
565 }
566
567 return -1;
568}
569
570/* The 7164 API needs to know the i2c register length in advance.
571 * this is a helper function. Based on a specific chip addr and bus return the
572 * reg length.
573 */
574int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr)
575{
576 /* For a given bus and i2c device address, return the
577 * saa7164 registry address width. < 0 on error
578 */
579
580 struct saa7164_dev *dev = bus->dev;
581 struct saa7164_unit *unit;
582 int i;
583
584 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
585 unit = &saa7164_boards[dev->board].unit[i];
586
587 if (unit->type == SAA7164_UNIT_UNDEFINED)
588 continue;
589
590 if ((bus->nr == unit->i2c_bus_nr) &&
591 (addr == unit->i2c_bus_addr))
592 return unit->i2c_reg_len;
593 }
594
595 return -1;
596}
597/* TODO: implement a 'findeeprom' functio like the above and fix any other
598 * eeprom related todo's in -api.c.
599 */
600
601/* Translate a unitid into a x readable device name, for display purposes. */
602char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid)
603{
604 char *undefed = "UNDEFINED";
605 char *bridge = "BRIDGE";
606 struct saa7164_unit *unit;
607 int i;
608
609 if (unitid == 0)
610 return bridge;
611
612 for (i = 0; i < SAA7164_MAX_UNITS; i++) {
613 unit = &saa7164_boards[dev->board].unit[i];
614
615 if (unit->type == SAA7164_UNIT_UNDEFINED)
616 continue;
617
618 if (unitid == unit->id)
619 return unit->name;
620 }
621
622 return undefed;
623}
624
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
new file mode 100644
index 000000000000..e097f1a0969a
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -0,0 +1,572 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/wait.h>
23
24#include "saa7164.h"
25
26int saa7164_cmd_alloc_seqno(struct saa7164_dev *dev)
27{
28 int i, ret = -1;
29
30 mutex_lock(&dev->lock);
31 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
32 if (dev->cmds[i].inuse == 0) {
33 dev->cmds[i].inuse = 1;
34 dev->cmds[i].signalled = 0;
35 dev->cmds[i].timeout = 0;
36 ret = dev->cmds[i].seqno;
37 break;
38 }
39 }
40 mutex_unlock(&dev->lock);
41
42 return ret;
43}
44
45void saa7164_cmd_free_seqno(struct saa7164_dev *dev, u8 seqno)
46{
47 mutex_lock(&dev->lock);
48 if ((dev->cmds[seqno].inuse == 1) &&
49 (dev->cmds[seqno].seqno == seqno)) {
50 dev->cmds[seqno].inuse = 0;
51 dev->cmds[seqno].signalled = 0;
52 dev->cmds[seqno].timeout = 0;
53 }
54 mutex_unlock(&dev->lock);
55}
56
57void saa7164_cmd_timeout_seqno(struct saa7164_dev *dev, u8 seqno)
58{
59 mutex_lock(&dev->lock);
60 if ((dev->cmds[seqno].inuse == 1) &&
61 (dev->cmds[seqno].seqno == seqno)) {
62 dev->cmds[seqno].timeout = 1;
63 }
64 mutex_unlock(&dev->lock);
65}
66
67u32 saa7164_cmd_timeout_get(struct saa7164_dev *dev, u8 seqno)
68{
69 int ret = 0;
70
71 mutex_lock(&dev->lock);
72 if ((dev->cmds[seqno].inuse == 1) &&
73 (dev->cmds[seqno].seqno == seqno)) {
74 ret = dev->cmds[seqno].timeout;
75 }
76 mutex_unlock(&dev->lock);
77
78 return ret;
79}
80
81/* Commands to the f/w get marshelled to/from this code then onto the PCI
82 * -bus/c running buffer. */
83int saa7164_irq_dequeue(struct saa7164_dev *dev)
84{
85 int ret = SAA_OK;
86 u32 timeout;
87 wait_queue_head_t *q = 0;
88 dprintk(DBGLVL_CMD, "%s()\n", __func__);
89
90 /* While any outstand message on the bus exists... */
91 do {
92
93 /* Peek the msg bus */
94 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
95 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
96 if (ret != SAA_OK)
97 break;
98
99 q = &dev->cmds[tRsp.seqno].wait;
100 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
101 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
102 if (!timeout) {
103 dprintk(DBGLVL_CMD,
104 "%s() signalled seqno(%d) (for dequeue)\n",
105 __func__, tRsp.seqno);
106 dev->cmds[tRsp.seqno].signalled = 1;
107 wake_up(q);
108 } else {
109 printk(KERN_ERR
110 "%s() found timed out command on the bus\n",
111 __func__);
112 }
113 } while (0);
114
115 return ret;
116}
117
118/* Commands to the f/w get marshelled to/from this code then onto the PCI
119 * -bus/c running buffer. */
120int saa7164_cmd_dequeue(struct saa7164_dev *dev)
121{
122 int loop = 1;
123 int ret;
124 u32 timeout;
125 wait_queue_head_t *q = 0;
126 u8 tmp[512];
127 dprintk(DBGLVL_CMD, "%s()\n", __func__);
128
129 while (loop) {
130
131 tmComResInfo_t tRsp = { 0, 0, 0, 0, 0, 0 };
132 ret = saa7164_bus_get(dev, &tRsp, NULL, 1);
133 if (ret == SAA_ERR_EMPTY)
134 return SAA_OK;
135
136 if (ret != SAA_OK)
137 return ret;
138
139 q = &dev->cmds[tRsp.seqno].wait;
140 timeout = saa7164_cmd_timeout_get(dev, tRsp.seqno);
141 dprintk(DBGLVL_CMD, "%s() timeout = %d\n", __func__, timeout);
142 if (timeout) {
143 printk(KERN_ERR "found timed out command on the bus\n");
144
145 /* Clean the bus */
146 ret = saa7164_bus_get(dev, &tRsp, &tmp, 0);
147 printk(KERN_ERR "ret = %x\n", ret);
148 if (ret == SAA_ERR_EMPTY)
149 /* Someone else already fetched the response */
150 return SAA_OK;
151
152 if (ret != SAA_OK)
153 return ret;
154
155 if (tRsp.flags & PVC_CMDFLAG_CONTINUE)
156 printk(KERN_ERR "split response\n");
157 else
158 saa7164_cmd_free_seqno(dev, tRsp.seqno);
159
160 printk(KERN_ERR " timeout continue\n");
161 continue;
162 }
163
164 dprintk(DBGLVL_CMD, "%s() signalled seqno(%d) (for dequeue)\n",
165 __func__, tRsp.seqno);
166 dev->cmds[tRsp.seqno].signalled = 1;
167 wake_up(q);
168 return SAA_OK;
169 }
170
171 return SAA_OK;
172}
173
174int saa7164_cmd_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf)
175{
176 tmComResBusInfo_t *bus = &dev->bus;
177 u8 cmd_sent;
178 u16 size, idx;
179 u32 cmds;
180 void *tmp;
181 int ret = -1;
182
183 if (!msg) {
184 printk(KERN_ERR "%s() !msg\n", __func__);
185 return SAA_ERR_BAD_PARAMETER;
186 }
187
188 mutex_lock(&dev->cmds[msg->id].lock);
189
190 size = msg->size;
191 idx = 0;
192 cmds = size / bus->m_wMaxReqSize;
193 if (size % bus->m_wMaxReqSize == 0)
194 cmds -= 1;
195
196 cmd_sent = 0;
197
198 /* Split the request into smaller chunks */
199 for (idx = 0; idx < cmds; idx++) {
200
201 msg->flags |= SAA_CMDFLAG_CONTINUE;
202 msg->size = bus->m_wMaxReqSize;
203 tmp = buf + idx * bus->m_wMaxReqSize;
204
205 ret = saa7164_bus_set(dev, msg, tmp);
206 if (ret != SAA_OK) {
207 printk(KERN_ERR "%s() set failed %d\n", __func__, ret);
208
209 if (cmd_sent) {
210 ret = SAA_ERR_BUSY;
211 goto out;
212 }
213 ret = SAA_ERR_OVERFLOW;
214 goto out;
215 }
216 cmd_sent = 1;
217 }
218
219 /* If not the last command... */
220 if (idx != 0)
221 msg->flags &= ~SAA_CMDFLAG_CONTINUE;
222
223 msg->size = size - idx * bus->m_wMaxReqSize;
224
225 ret = saa7164_bus_set(dev, msg, buf + idx * bus->m_wMaxReqSize);
226 if (ret != SAA_OK) {
227 printk(KERN_ERR "%s() set last failed %d\n", __func__, ret);
228
229 if (cmd_sent) {
230 ret = SAA_ERR_BUSY;
231 goto out;
232 }
233 ret = SAA_ERR_OVERFLOW;
234 goto out;
235 }
236 ret = SAA_OK;
237
238out:
239 mutex_unlock(&dev->cmds[msg->id].lock);
240 return ret;
241}
242
243/* Wait for a signal event, without holding a mutex. Either return TIMEOUT if
244 * the event never occured, or SAA_OK if it was signaled during the wait.
245 */
246int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
247{
248 wait_queue_head_t *q = 0;
249 int ret = SAA_BUS_TIMEOUT;
250 unsigned long stamp;
251 int r;
252
253 if (debug >= 4)
254 saa7164_bus_dump(dev);
255
256 dprintk(DBGLVL_CMD, "%s(seqno=%d)\n", __func__, seqno);
257
258 mutex_lock(&dev->lock);
259 if ((dev->cmds[seqno].inuse == 1) &&
260 (dev->cmds[seqno].seqno == seqno)) {
261 q = &dev->cmds[seqno].wait;
262 }
263 mutex_unlock(&dev->lock);
264
265 if (q) {
266 /* If we haven't been signalled we need to wait */
267 if (dev->cmds[seqno].signalled == 0) {
268 stamp = jiffies;
269 dprintk(DBGLVL_CMD,
270 "%s(seqno=%d) Waiting (signalled=%d)\n",
271 __func__, seqno, dev->cmds[seqno].signalled);
272
273 /* Wait for signalled to be flagged or timeout */
274 /* In a highly stressed system this can easily extend
275 * into multiple seconds before the deferred worker
276 * is scheduled, and we're woken up via signal.
277 * We typically are signalled in < 50ms but it can
278 * take MUCH longer.
279 */
280 wait_event_timeout(*q, dev->cmds[seqno].signalled, (HZ * waitsecs));
281 r = time_before(jiffies, stamp + (HZ * waitsecs));
282 if (r)
283 ret = SAA_OK;
284 else
285 saa7164_cmd_timeout_seqno(dev, seqno);
286
287 dprintk(DBGLVL_CMD, "%s(seqno=%d) Waiting res = %d "
288 "(signalled=%d)\n", __func__, seqno, r,
289 dev->cmds[seqno].signalled);
290 } else
291 ret = SAA_OK;
292 } else
293 printk(KERN_ERR "%s(seqno=%d) seqno is invalid\n",
294 __func__, seqno);
295
296 return ret;
297}
298
299void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno)
300{
301 int i;
302 dprintk(DBGLVL_CMD, "%s()\n", __func__);
303
304 mutex_lock(&dev->lock);
305 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
306 if (dev->cmds[i].inuse == 1) {
307 dprintk(DBGLVL_CMD,
308 "seqno %d inuse, sig = %d, t/out = %d\n",
309 dev->cmds[i].seqno,
310 dev->cmds[i].signalled,
311 dev->cmds[i].timeout);
312 }
313 }
314
315 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
316 if ((dev->cmds[i].inuse == 1) && ((i == 0) ||
317 (dev->cmds[i].signalled) || (dev->cmds[i].timeout))) {
318 dprintk(DBGLVL_CMD, "%s(seqno=%d) calling wake_up\n",
319 __func__, i);
320 dev->cmds[i].signalled = 1;
321 wake_up(&dev->cmds[i].wait);
322 }
323 }
324 mutex_unlock(&dev->lock);
325}
326
327int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, tmComResCmd_t command,
328 u16 controlselector, u16 size, void *buf)
329{
330 tmComResInfo_t command_t, *pcommand_t;
331 tmComResInfo_t response_t, *presponse_t;
332 u8 errdata[256];
333 u16 resp_dsize;
334 u16 data_recd;
335 u32 loop;
336 int ret;
337 int safety = 0;
338
339 dprintk(DBGLVL_CMD, "%s(unitid = %s (%d) , command = 0x%x, "
340 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
341 command, controlselector);
342
343 if ((size == 0) || (buf == 0)) {
344 printk(KERN_ERR "%s() Invalid param\n", __func__);
345 return SAA_ERR_BAD_PARAMETER;
346 }
347
348 /* Prepare some basic command/response structures */
349 memset(&command_t, 0, sizeof(command_t));
350 memset(&response_t, 0, sizeof(&response_t));
351 pcommand_t = &command_t;
352 presponse_t = &response_t;
353 command_t.id = id;
354 command_t.command = command;
355 command_t.controlselector = controlselector;
356 command_t.size = size;
357
358 /* Allocate a unique sequence number */
359 ret = saa7164_cmd_alloc_seqno(dev);
360 if (ret < 0) {
361 printk(KERN_ERR "%s() No free sequences\n", __func__);
362 ret = SAA_ERR_NO_RESOURCES;
363 goto out;
364 }
365
366 command_t.seqno = (u8)ret;
367
368 /* Send Command */
369 resp_dsize = size;
370 pcommand_t->size = size;
371
372 dprintk(DBGLVL_CMD, "%s() pcommand_t.seqno = %d\n",
373 __func__, pcommand_t->seqno);
374
375 dprintk(DBGLVL_CMD, "%s() pcommand_t.size = %d\n",
376 __func__, pcommand_t->size);
377
378 ret = saa7164_cmd_set(dev, pcommand_t, buf);
379 if (ret != SAA_OK) {
380 printk(KERN_ERR "%s() set command failed %d\n", __func__, ret);
381
382 if (ret != SAA_ERR_BUSY)
383 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
384 else
385 /* Flag a timeout, because at least one
386 * command was sent */
387 saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
388
389 goto out;
390 }
391
392 /* With split responses we have to collect the msgs piece by piece */
393 data_recd = 0;
394 loop = 1;
395 while (loop) {
396 dprintk(DBGLVL_CMD, "%s() loop\n", __func__);
397
398 ret = saa7164_cmd_wait(dev, pcommand_t->seqno);
399 dprintk(DBGLVL_CMD, "%s() loop ret = %d\n", __func__, ret);
400
401 /* if power is down and this is not a power command ... */
402
403 if (ret == SAA_BUS_TIMEOUT) {
404 printk(KERN_ERR "Event timed out\n");
405 saa7164_cmd_timeout_seqno(dev, pcommand_t->seqno);
406 return ret;
407 }
408
409 if (ret != SAA_OK) {
410 printk(KERN_ERR "spurious error\n");
411 return ret;
412 }
413
414 /* Peek response */
415 ret = saa7164_bus_get(dev, presponse_t, NULL, 1);
416 if (ret == SAA_ERR_EMPTY) {
417 dprintk(4, "%s() SAA_ERR_EMPTY\n", __func__);
418 continue;
419 }
420 if (ret != SAA_OK) {
421 printk(KERN_ERR "peek failed\n");
422 return ret;
423 }
424
425 dprintk(DBGLVL_CMD, "%s() presponse_t->seqno = %d\n",
426 __func__, presponse_t->seqno);
427
428 dprintk(DBGLVL_CMD, "%s() presponse_t->flags = 0x%x\n",
429 __func__, presponse_t->flags);
430
431 dprintk(DBGLVL_CMD, "%s() presponse_t->size = %d\n",
432 __func__, presponse_t->size);
433
434 /* Check if the response was for our command */
435 if (presponse_t->seqno != pcommand_t->seqno) {
436
437 dprintk(DBGLVL_CMD,
438 "wrong event: seqno = %d, "
439 "expected seqno = %d, "
440 "will dequeue regardless\n",
441 presponse_t->seqno, pcommand_t->seqno);
442
443 ret = saa7164_cmd_dequeue(dev);
444 if (ret != SAA_OK) {
445 printk(KERN_ERR "dequeue failed, ret = %d\n",
446 ret);
447 if (safety++ > 16) {
448 printk(KERN_ERR
449 "dequeue exceeded, safety exit\n");
450 return SAA_ERR_BUSY;
451 }
452 }
453
454 continue;
455 }
456
457 if ((presponse_t->flags & PVC_RESPONSEFLAG_ERROR) != 0) {
458
459 memset(&errdata[0], 0, sizeof(errdata));
460
461 ret = saa7164_bus_get(dev, presponse_t, &errdata[0], 0);
462 if (ret != SAA_OK) {
463 printk(KERN_ERR "get error(2)\n");
464 return ret;
465 }
466
467 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
468
469 dprintk(DBGLVL_CMD, "%s() errdata %02x%02x%02x%02x\n",
470 __func__, errdata[0], errdata[1], errdata[2],
471 errdata[3]);
472
473 /* Map error codes */
474 dprintk(DBGLVL_CMD, "%s() cmd, error code = 0x%x\n",
475 __func__, errdata[0]);
476
477 switch (errdata[0]) {
478 case PVC_ERRORCODE_INVALID_COMMAND:
479 dprintk(DBGLVL_CMD, "%s() INVALID_COMMAND\n",
480 __func__);
481 ret = SAA_ERR_INVALID_COMMAND;
482 break;
483 case PVC_ERRORCODE_INVALID_DATA:
484 dprintk(DBGLVL_CMD, "%s() INVALID_DATA\n",
485 __func__);
486 ret = SAA_ERR_BAD_PARAMETER;
487 break;
488 case PVC_ERRORCODE_TIMEOUT:
489 dprintk(DBGLVL_CMD, "%s() TIMEOUT\n", __func__);
490 ret = SAA_ERR_TIMEOUT;
491 break;
492 case PVC_ERRORCODE_NAK:
493 dprintk(DBGLVL_CMD, "%s() NAK\n", __func__);
494 ret = SAA_ERR_NULL_PACKET;
495 break;
496 case PVC_ERRORCODE_UNKNOWN:
497 case PVC_ERRORCODE_INVALID_CONTROL:
498 dprintk(DBGLVL_CMD,
499 "%s() UNKNOWN OR INVALID CONTROL\n",
500 __func__);
501 default:
502 dprintk(DBGLVL_CMD, "%s() UNKNOWN\n", __func__);
503 ret = SAA_ERR_NOT_SUPPORTED;
504 }
505
506 /* See of other commands are on the bus */
507 if (saa7164_cmd_dequeue(dev) != SAA_OK)
508 printk(KERN_ERR "dequeue(2) failed\n");
509
510 return ret;
511 }
512
513 /* If response is invalid */
514 if ((presponse_t->id != pcommand_t->id) ||
515 (presponse_t->command != pcommand_t->command) ||
516 (presponse_t->controlselector !=
517 pcommand_t->controlselector) ||
518 (((resp_dsize - data_recd) != presponse_t->size) &&
519 !(presponse_t->flags & PVC_CMDFLAG_CONTINUE)) ||
520 ((resp_dsize - data_recd) < presponse_t->size)) {
521
522 /* Invalid */
523 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
524 ret = saa7164_bus_get(dev, presponse_t, 0, 0);
525 if (ret != SAA_OK) {
526 printk(KERN_ERR "get failed\n");
527 return ret;
528 }
529
530 /* See of other commands are on the bus */
531 if (saa7164_cmd_dequeue(dev) != SAA_OK)
532 printk(KERN_ERR "dequeue(3) failed\n");
533 continue;
534 }
535
536 /* OK, now we're actually getting out correct response */
537 ret = saa7164_bus_get(dev, presponse_t, buf + data_recd, 0);
538 if (ret != SAA_OK) {
539 printk(KERN_ERR "get failed\n");
540 return ret;
541 }
542
543 data_recd = presponse_t->size + data_recd;
544 if (resp_dsize == data_recd) {
545 dprintk(DBGLVL_CMD, "%s() Resp recd\n", __func__);
546 break;
547 }
548
549 /* See of other commands are on the bus */
550 if (saa7164_cmd_dequeue(dev) != SAA_OK)
551 printk(KERN_ERR "dequeue(3) failed\n");
552
553 continue;
554
555 } /* (loop) */
556
557 /* Release the sequence number allocation */
558 saa7164_cmd_free_seqno(dev, pcommand_t->seqno);
559
560 /* if powerdown signal all pending commands */
561
562 dprintk(DBGLVL_CMD, "%s() Calling dequeue then exit\n", __func__);
563
564 /* See of other commands are on the bus */
565 if (saa7164_cmd_dequeue(dev) != SAA_OK)
566 printk(KERN_ERR "dequeue(4) failed\n");
567
568 ret = SAA_OK;
569out:
570 return ret;
571}
572
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
new file mode 100644
index 000000000000..f0dbead188c8
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -0,0 +1,740 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/init.h>
23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/kmod.h>
27#include <linux/kernel.h>
28#include <linux/slab.h>
29#include <linux/interrupt.h>
30#include <linux/delay.h>
31#include <asm/div64.h>
32
33#include "saa7164.h"
34
35MODULE_DESCRIPTION("Driver for NXP SAA7164 based TV cards");
36MODULE_AUTHOR("Steven Toth <stoth@kernellabs.com>");
37MODULE_LICENSE("GPL");
38
39/*
40 1 Basic
41 2
42 4 i2c
43 8 api
44 16 cmd
45 32 bus
46 */
47
48unsigned int debug;
49module_param(debug, int, 0644);
50MODULE_PARM_DESC(debug, "enable debug messages");
51
52unsigned int waitsecs = 10;
53module_param(waitsecs, int, 0644);
54MODULE_PARM_DESC(debug, "timeout on firmware messages");
55
56static unsigned int card[] = {[0 ... (SAA7164_MAXBOARDS - 1)] = UNSET };
57module_param_array(card, int, NULL, 0444);
58MODULE_PARM_DESC(card, "card type");
59
60static unsigned int saa7164_devcount;
61
62static DEFINE_MUTEX(devlist);
63LIST_HEAD(saa7164_devlist);
64
65#define INT_SIZE 16
66
67static void saa7164_work_cmdhandler(struct work_struct *w)
68{
69 struct saa7164_dev *dev = container_of(w, struct saa7164_dev, workcmd);
70
71 /* Wake up any complete commands */
72 saa7164_irq_dequeue(dev);
73}
74
75static void saa7164_buffer_deliver(struct saa7164_buffer *buf)
76{
77 struct saa7164_tsport *port = buf->port;
78
79 /* Feed the transport payload into the kernel demux */
80 dvb_dmx_swfilter_packets(&port->dvb.demux, (u8 *)buf->cpu,
81 SAA7164_TS_NUMBER_OF_LINES);
82
83}
84
85static irqreturn_t saa7164_irq_ts(struct saa7164_tsport *port)
86{
87 struct saa7164_dev *dev = port->dev;
88 struct saa7164_buffer *buf;
89 struct list_head *c, *n;
90 int wp, i = 0, rp;
91
92 /* Find the current write point from the hardware */
93 wp = saa7164_readl(port->bufcounter);
94 if (wp > (port->hwcfg.buffercount - 1))
95 BUG();
96
97 /* Find the previous buffer to the current write point */
98 if (wp == 0)
99 rp = 7;
100 else
101 rp = wp - 1;
102
103 /* Lookup the WP in the buffer list */
104 /* TODO: turn this into a worker thread */
105 list_for_each_safe(c, n, &port->dmaqueue.list) {
106 buf = list_entry(c, struct saa7164_buffer, list);
107 if (i++ > port->hwcfg.buffercount)
108 BUG();
109
110 if (buf->nr == rp) {
111 /* Found the buffer, deal with it */
112 dprintk(DBGLVL_IRQ, "%s() wp: %d processing: %d\n",
113 __func__, wp, rp);
114 saa7164_buffer_deliver(buf);
115 break;
116 }
117
118 }
119 return 0;
120}
121
122/* Primary IRQ handler and dispatch mechanism */
123static irqreturn_t saa7164_irq(int irq, void *dev_id)
124{
125 struct saa7164_dev *dev = dev_id;
126 u32 intid, intstat[INT_SIZE/4];
127 int i, handled = 0, bit;
128
129 if (dev == 0) {
130 printk(KERN_ERR "%s() No device specified\n", __func__);
131 handled = 0;
132 goto out;
133 }
134
135 /* Check that the hardware is accessable. If the status bytes are
136 * 0xFF then the device is not accessable, the the IRQ belongs
137 * to another driver.
138 * 4 x u32 interrupt registers.
139 */
140 for (i = 0; i < INT_SIZE/4; i++) {
141
142 /* TODO: Convert into saa7164_readl() */
143 /* Read the 4 hardware interrupt registers */
144 intstat[i] = saa7164_readl(dev->int_status + (i * 4));
145
146 if (intstat[i])
147 handled = 1;
148 }
149 if (handled == 0)
150 goto out;
151
152 /* For each of the HW interrupt registers */
153 for (i = 0; i < INT_SIZE/4; i++) {
154
155 if (intstat[i]) {
156 /* Each function of the board has it's own interruptid.
157 * Find the function that triggered then call
158 * it's handler.
159 */
160 for (bit = 0; bit < 32; bit++) {
161
162 if (((intstat[i] >> bit) & 0x00000001) == 0)
163 continue;
164
165 /* Calculate the interrupt id (0x00 to 0x7f) */
166
167 intid = (i * 32) + bit;
168 if (intid == dev->intfdesc.bInterruptId) {
169 /* A response to an cmd/api call */
170 schedule_work(&dev->workcmd);
171 } else if (intid ==
172 dev->ts1.hwcfg.interruptid) {
173
174 /* Transport path 1 */
175 saa7164_irq_ts(&dev->ts1);
176
177 } else if (intid ==
178 dev->ts2.hwcfg.interruptid) {
179
180 /* Transport path 2 */
181 saa7164_irq_ts(&dev->ts2);
182
183 } else {
184 /* Find the function */
185 dprintk(DBGLVL_IRQ,
186 "%s() unhandled interrupt "
187 "reg 0x%x bit 0x%x "
188 "intid = 0x%x\n",
189 __func__, i, bit, intid);
190 }
191 }
192
193 /* Ack it */
194 saa7164_writel(dev->int_ack + (i * 4), intstat[i]);
195
196 }
197 }
198out:
199 return IRQ_RETVAL(handled);
200}
201
202void saa7164_getfirmwarestatus(struct saa7164_dev *dev)
203{
204 struct saa7164_fw_status *s = &dev->fw_status;
205
206 dev->fw_status.status = saa7164_readl(SAA_DEVICE_SYSINIT_STATUS);
207 dev->fw_status.mode = saa7164_readl(SAA_DEVICE_SYSINIT_MODE);
208 dev->fw_status.spec = saa7164_readl(SAA_DEVICE_SYSINIT_SPEC);
209 dev->fw_status.inst = saa7164_readl(SAA_DEVICE_SYSINIT_INST);
210 dev->fw_status.cpuload = saa7164_readl(SAA_DEVICE_SYSINIT_CPULOAD);
211 dev->fw_status.remainheap =
212 saa7164_readl(SAA_DEVICE_SYSINIT_REMAINHEAP);
213
214 dprintk(1, "Firmware status:\n");
215 dprintk(1, " .status = 0x%08x\n", s->status);
216 dprintk(1, " .mode = 0x%08x\n", s->mode);
217 dprintk(1, " .spec = 0x%08x\n", s->spec);
218 dprintk(1, " .inst = 0x%08x\n", s->inst);
219 dprintk(1, " .cpuload = 0x%08x\n", s->cpuload);
220 dprintk(1, " .remainheap = 0x%08x\n", s->remainheap);
221}
222
223u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev)
224{
225 u32 reg;
226
227 reg = saa7164_readl(SAA_DEVICE_VERSION);
228 dprintk(1, "Device running firmware version %d.%d.%d.%d (0x%x)\n",
229 (reg & 0x0000fc00) >> 10,
230 (reg & 0x000003e0) >> 5,
231 (reg & 0x0000001f),
232 (reg & 0xffff0000) >> 16,
233 reg);
234
235 return reg;
236}
237
238/* TODO: Debugging func, remove */
239void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len)
240{
241 int i;
242
243 printk(KERN_INFO "--------------------> "
244 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
245
246 for (i = 0; i < len; i += 16)
247 printk(KERN_INFO " [0x%08x] "
248 "%02x %02x %02x %02x %02x %02x %02x %02x "
249 "%02x %02x %02x %02x %02x %02x %02x %02x\n", i,
250 *(buf+i+0), *(buf+i+1), *(buf+i+2), *(buf+i+3),
251 *(buf+i+4), *(buf+i+5), *(buf+i+6), *(buf+i+7),
252 *(buf+i+8), *(buf+i+9), *(buf+i+10), *(buf+i+11),
253 *(buf+i+12), *(buf+i+13), *(buf+i+14), *(buf+i+15));
254}
255
256/* TODO: Debugging func, remove */
257void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr)
258{
259 int i;
260
261 dprintk(1, "--------------------> "
262 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f\n");
263
264 for (i = 0; i < 0x100; i += 16)
265 dprintk(1, "region0[0x%08x] = "
266 "%02x %02x %02x %02x %02x %02x %02x %02x"
267 " %02x %02x %02x %02x %02x %02x %02x %02x\n", i,
268 (u8)saa7164_readb(addr + i + 0),
269 (u8)saa7164_readb(addr + i + 1),
270 (u8)saa7164_readb(addr + i + 2),
271 (u8)saa7164_readb(addr + i + 3),
272 (u8)saa7164_readb(addr + i + 4),
273 (u8)saa7164_readb(addr + i + 5),
274 (u8)saa7164_readb(addr + i + 6),
275 (u8)saa7164_readb(addr + i + 7),
276 (u8)saa7164_readb(addr + i + 8),
277 (u8)saa7164_readb(addr + i + 9),
278 (u8)saa7164_readb(addr + i + 10),
279 (u8)saa7164_readb(addr + i + 11),
280 (u8)saa7164_readb(addr + i + 12),
281 (u8)saa7164_readb(addr + i + 13),
282 (u8)saa7164_readb(addr + i + 14),
283 (u8)saa7164_readb(addr + i + 15)
284 );
285}
286
287static void saa7164_dump_hwdesc(struct saa7164_dev *dev)
288{
289 dprintk(1, "@0x%p hwdesc sizeof(tmComResHWDescr_t) = %d bytes\n",
290 &dev->hwdesc, (u32)sizeof(tmComResHWDescr_t));
291
292 dprintk(1, " .bLength = 0x%x\n", dev->hwdesc.bLength);
293 dprintk(1, " .bDescriptorType = 0x%x\n", dev->hwdesc.bDescriptorType);
294 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
295 dev->hwdesc.bDescriptorSubtype);
296
297 dprintk(1, " .bcdSpecVersion = 0x%x\n", dev->hwdesc.bcdSpecVersion);
298 dprintk(1, " .dwClockFrequency = 0x%x\n", dev->hwdesc.dwClockFrequency);
299 dprintk(1, " .dwClockUpdateRes = 0x%x\n", dev->hwdesc.dwClockUpdateRes);
300 dprintk(1, " .bCapabilities = 0x%x\n", dev->hwdesc.bCapabilities);
301 dprintk(1, " .dwDeviceRegistersLocation = 0x%x\n",
302 dev->hwdesc.dwDeviceRegistersLocation);
303
304 dprintk(1, " .dwHostMemoryRegion = 0x%x\n",
305 dev->hwdesc.dwHostMemoryRegion);
306
307 dprintk(1, " .dwHostMemoryRegionSize = 0x%x\n",
308 dev->hwdesc.dwHostMemoryRegionSize);
309
310 dprintk(1, " .dwHostHibernatMemRegion = 0x%x\n",
311 dev->hwdesc.dwHostHibernatMemRegion);
312
313 dprintk(1, " .dwHostHibernatMemRegionSize = 0x%x\n",
314 dev->hwdesc.dwHostHibernatMemRegionSize);
315}
316
317static void saa7164_dump_intfdesc(struct saa7164_dev *dev)
318{
319 dprintk(1, "@0x%p intfdesc "
320 "sizeof(tmComResInterfaceDescr_t) = %d bytes\n",
321 &dev->intfdesc, (u32)sizeof(tmComResInterfaceDescr_t));
322
323 dprintk(1, " .bLength = 0x%x\n", dev->intfdesc.bLength);
324 dprintk(1, " .bDescriptorType = 0x%x\n", dev->intfdesc.bDescriptorType);
325 dprintk(1, " .bDescriptorSubtype = 0x%x\n",
326 dev->intfdesc.bDescriptorSubtype);
327
328 dprintk(1, " .bFlags = 0x%x\n", dev->intfdesc.bFlags);
329 dprintk(1, " .bInterfaceType = 0x%x\n", dev->intfdesc.bInterfaceType);
330 dprintk(1, " .bInterfaceId = 0x%x\n", dev->intfdesc.bInterfaceId);
331 dprintk(1, " .bBaseInterface = 0x%x\n", dev->intfdesc.bBaseInterface);
332 dprintk(1, " .bInterruptId = 0x%x\n", dev->intfdesc.bInterruptId);
333 dprintk(1, " .bDebugInterruptId = 0x%x\n",
334 dev->intfdesc.bDebugInterruptId);
335
336 dprintk(1, " .BARLocation = 0x%x\n", dev->intfdesc.BARLocation);
337}
338
339static void saa7164_dump_busdesc(struct saa7164_dev *dev)
340{
341 dprintk(1, "@0x%p busdesc sizeof(tmComResBusDescr_t) = %d bytes\n",
342 &dev->busdesc, (u32)sizeof(tmComResBusDescr_t));
343
344 dprintk(1, " .CommandRing = 0x%016Lx\n", dev->busdesc.CommandRing);
345 dprintk(1, " .ResponseRing = 0x%016Lx\n", dev->busdesc.ResponseRing);
346 dprintk(1, " .CommandWrite = 0x%x\n", dev->busdesc.CommandWrite);
347 dprintk(1, " .CommandRead = 0x%x\n", dev->busdesc.CommandRead);
348 dprintk(1, " .ResponseWrite = 0x%x\n", dev->busdesc.ResponseWrite);
349 dprintk(1, " .ResponseRead = 0x%x\n", dev->busdesc.ResponseRead);
350}
351
352/* Much of the hardware configuration and PCI registers are configured
353 * dynamically depending on firmware. We have to cache some initial
354 * structures then use these to locate other important structures
355 * from PCI space.
356 */
357static void saa7164_get_descriptors(struct saa7164_dev *dev)
358{
359 memcpy(&dev->hwdesc, dev->bmmio, sizeof(tmComResHWDescr_t));
360 memcpy(&dev->intfdesc, dev->bmmio + sizeof(tmComResHWDescr_t),
361 sizeof(tmComResInterfaceDescr_t));
362 memcpy(&dev->busdesc, dev->bmmio + dev->intfdesc.BARLocation,
363 sizeof(tmComResBusDescr_t));
364
365 if (dev->hwdesc.bLength != sizeof(tmComResHWDescr_t)) {
366 printk(KERN_ERR "Structure tmComResHWDescr_t is mangled\n");
367 printk(KERN_ERR "Need %x got %d\n", dev->hwdesc.bLength,
368 (u32)sizeof(tmComResHWDescr_t));
369 } else
370 saa7164_dump_hwdesc(dev);
371
372 if (dev->intfdesc.bLength != sizeof(tmComResInterfaceDescr_t)) {
373 printk(KERN_ERR "struct tmComResInterfaceDescr_t is mangled\n");
374 printk(KERN_ERR "Need %x got %d\n", dev->intfdesc.bLength,
375 (u32)sizeof(tmComResInterfaceDescr_t));
376 } else
377 saa7164_dump_intfdesc(dev);
378
379 saa7164_dump_busdesc(dev);
380}
381
382static int saa7164_pci_quirks(struct saa7164_dev *dev)
383{
384 return 0;
385}
386
387static int get_resources(struct saa7164_dev *dev)
388{
389 if (request_mem_region(pci_resource_start(dev->pci, 0),
390 pci_resource_len(dev->pci, 0), dev->name)) {
391
392 if (request_mem_region(pci_resource_start(dev->pci, 2),
393 pci_resource_len(dev->pci, 2), dev->name))
394 return 0;
395 }
396
397 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx or 0x%llx\n",
398 dev->name,
399 (u64)pci_resource_start(dev->pci, 0),
400 (u64)pci_resource_start(dev->pci, 2));
401
402 return -EBUSY;
403}
404
405static int saa7164_dev_setup(struct saa7164_dev *dev)
406{
407 int i;
408
409 mutex_init(&dev->lock);
410 atomic_inc(&dev->refcount);
411 dev->nr = saa7164_devcount++;
412
413 sprintf(dev->name, "saa7164[%d]", dev->nr);
414
415 mutex_lock(&devlist);
416 list_add_tail(&dev->devlist, &saa7164_devlist);
417 mutex_unlock(&devlist);
418
419 /* board config */
420 dev->board = UNSET;
421 if (card[dev->nr] < saa7164_bcount)
422 dev->board = card[dev->nr];
423
424 for (i = 0; UNSET == dev->board && i < saa7164_idcount; i++)
425 if (dev->pci->subsystem_vendor == saa7164_subids[i].subvendor &&
426 dev->pci->subsystem_device ==
427 saa7164_subids[i].subdevice)
428 dev->board = saa7164_subids[i].card;
429
430 if (UNSET == dev->board) {
431 dev->board = SAA7164_BOARD_UNKNOWN;
432 saa7164_card_list(dev);
433 }
434
435 dev->pci_bus = dev->pci->bus->number;
436 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
437
438 /* I2C Defaults / setup */
439 dev->i2c_bus[0].dev = dev;
440 dev->i2c_bus[0].nr = 0;
441 dev->i2c_bus[1].dev = dev;
442 dev->i2c_bus[1].nr = 1;
443 dev->i2c_bus[2].dev = dev;
444 dev->i2c_bus[2].nr = 2;
445
446 /* Transport port A Defaults / setup */
447 dev->ts1.dev = dev;
448 dev->ts1.nr = 0;
449 mutex_init(&dev->ts1.dvb.lock);
450 INIT_LIST_HEAD(&dev->ts1.dmaqueue.list);
451 INIT_LIST_HEAD(&dev->ts1.dummy_dmaqueue.list);
452 mutex_init(&dev->ts1.dmaqueue_lock);
453 mutex_init(&dev->ts1.dummy_dmaqueue_lock);
454
455 /* Transport port B Defaults / setup */
456 dev->ts2.dev = dev;
457 dev->ts2.nr = 1;
458 mutex_init(&dev->ts2.dvb.lock);
459 INIT_LIST_HEAD(&dev->ts2.dmaqueue.list);
460 INIT_LIST_HEAD(&dev->ts2.dummy_dmaqueue.list);
461 mutex_init(&dev->ts2.dmaqueue_lock);
462 mutex_init(&dev->ts2.dummy_dmaqueue_lock);
463
464 if (get_resources(dev) < 0) {
465 printk(KERN_ERR "CORE %s No more PCIe resources for "
466 "subsystem: %04x:%04x\n",
467 dev->name, dev->pci->subsystem_vendor,
468 dev->pci->subsystem_device);
469
470 saa7164_devcount--;
471 return -ENODEV;
472 }
473
474 /* PCI/e allocations */
475 dev->lmmio = ioremap(pci_resource_start(dev->pci, 0),
476 pci_resource_len(dev->pci, 0));
477
478 dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2),
479 pci_resource_len(dev->pci, 2));
480
481 dev->bmmio = (u8 __iomem *)dev->lmmio;
482 dev->bmmio2 = (u8 __iomem *)dev->lmmio2;
483
484 /* Inerrupt and ack register locations offset of bmmio */
485 dev->int_status = 0x183000 + 0xf80;
486 dev->int_ack = 0x183000 + 0xf90;
487
488 printk(KERN_INFO
489 "CORE %s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
490 dev->name, dev->pci->subsystem_vendor,
491 dev->pci->subsystem_device, saa7164_boards[dev->board].name,
492 dev->board, card[dev->nr] == dev->board ?
493 "insmod option" : "autodetected");
494
495 saa7164_pci_quirks(dev);
496
497 return 0;
498}
499
500static void saa7164_dev_unregister(struct saa7164_dev *dev)
501{
502 dprintk(1, "%s()\n", __func__);
503
504 release_mem_region(pci_resource_start(dev->pci, 0),
505 pci_resource_len(dev->pci, 0));
506
507 release_mem_region(pci_resource_start(dev->pci, 2),
508 pci_resource_len(dev->pci, 2));
509
510 if (!atomic_dec_and_test(&dev->refcount))
511 return;
512
513 iounmap(dev->lmmio);
514 iounmap(dev->lmmio2);
515
516 return;
517}
518
519static int __devinit saa7164_initdev(struct pci_dev *pci_dev,
520 const struct pci_device_id *pci_id)
521{
522 struct saa7164_dev *dev;
523 int err, i;
524 u32 version;
525
526 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
527 if (NULL == dev)
528 return -ENOMEM;
529
530 /* pci init */
531 dev->pci = pci_dev;
532 if (pci_enable_device(pci_dev)) {
533 err = -EIO;
534 goto fail_free;
535 }
536
537 if (saa7164_dev_setup(dev) < 0) {
538 err = -EINVAL;
539 goto fail_free;
540 }
541
542 /* print pci info */
543 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
544 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
545 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
546 "latency: %d, mmio: 0x%llx\n", dev->name,
547 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
548 dev->pci_lat,
549 (unsigned long long)pci_resource_start(pci_dev, 0));
550
551 pci_set_master(pci_dev);
552 /* TODO */
553 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
554 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
555 err = -EIO;
556 goto fail_irq;
557 }
558
559 err = request_irq(pci_dev->irq, saa7164_irq,
560 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
561 if (err < 0) {
562 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
563 pci_dev->irq);
564 err = -EIO;
565 goto fail_irq;
566 }
567
568 pci_set_drvdata(pci_dev, dev);
569
570 /* Init the internal command list */
571 for (i = 0; i < SAA_CMD_MAX_MSG_UNITS; i++) {
572 dev->cmds[i].seqno = i;
573 dev->cmds[i].inuse = 0;
574 mutex_init(&dev->cmds[i].lock);
575 init_waitqueue_head(&dev->cmds[i].wait);
576 }
577
578 /* We need a deferred interrupt handler for cmd handling */
579 INIT_WORK(&dev->workcmd, saa7164_work_cmdhandler);
580
581 /* Only load the firmware if we know the board */
582 if (dev->board != SAA7164_BOARD_UNKNOWN) {
583
584 err = saa7164_downloadfirmware(dev);
585 if (err < 0) {
586 printk(KERN_ERR
587 "Failed to boot firmware, no features "
588 "registered\n");
589 goto fail_fw;
590 }
591
592 saa7164_get_descriptors(dev);
593 saa7164_dumpregs(dev, 0);
594 saa7164_getcurrentfirmwareversion(dev);
595 saa7164_getfirmwarestatus(dev);
596 err = saa7164_bus_setup(dev);
597 if (err < 0)
598 printk(KERN_ERR
599 "Failed to setup the bus, will continue\n");
600 saa7164_bus_dump(dev);
601
602 /* Ping the running firmware via the command bus and get the
603 * firmware version, this checks the bus is running OK.
604 */
605 version = 0;
606 if (saa7164_api_get_fw_version(dev, &version) == SAA_OK)
607 dprintk(1, "Bus is operating correctly using "
608 "version %d.%d.%d.%d (0x%x)\n",
609 (version & 0x0000fc00) >> 10,
610 (version & 0x000003e0) >> 5,
611 (version & 0x0000001f),
612 (version & 0xffff0000) >> 16,
613 version);
614 else
615 printk(KERN_ERR
616 "Failed to communicate with the firmware\n");
617
618 /* Bring up the I2C buses */
619 saa7164_i2c_register(&dev->i2c_bus[0]);
620 saa7164_i2c_register(&dev->i2c_bus[1]);
621 saa7164_i2c_register(&dev->i2c_bus[2]);
622 saa7164_gpio_setup(dev);
623 saa7164_card_setup(dev);
624
625
626 /* Parse the dynamic device configuration, find various
627 * media endpoints (MPEG, WMV, PS, TS) and cache their
628 * configuration details into the driver, so we can
629 * reference them later during simething_register() func,
630 * interrupt handlers, deferred work handlers etc.
631 */
632 saa7164_api_enum_subdevs(dev);
633
634 /* Begin to create the video sub-systems and register funcs */
635 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB) {
636 if (saa7164_dvb_register(&dev->ts1) < 0) {
637 printk(KERN_ERR "%s() Failed to register "
638 "dvb adapters on porta\n",
639 __func__);
640 }
641 }
642
643 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB) {
644 if (saa7164_dvb_register(&dev->ts2) < 0) {
645 printk(KERN_ERR"%s() Failed to register "
646 "dvb adapters on portb\n",
647 __func__);
648 }
649 }
650
651 } /* != BOARD_UNKNOWN */
652 else
653 printk(KERN_ERR "%s() Unsupported board detected, "
654 "registering without firmware\n", __func__);
655
656 dprintk(1, "%s() parameter debug = %d\n", __func__, debug);
657 dprintk(1, "%s() parameter waitsecs = %d\n", __func__, waitsecs);
658
659fail_fw:
660 return 0;
661
662fail_irq:
663 saa7164_dev_unregister(dev);
664fail_free:
665 kfree(dev);
666 return err;
667}
668
669static void saa7164_shutdown(struct saa7164_dev *dev)
670{
671 dprintk(1, "%s()\n", __func__);
672}
673
674static void __devexit saa7164_finidev(struct pci_dev *pci_dev)
675{
676 struct saa7164_dev *dev = pci_get_drvdata(pci_dev);
677
678 saa7164_shutdown(dev);
679
680 if (saa7164_boards[dev->board].porta == SAA7164_MPEG_DVB)
681 saa7164_dvb_unregister(&dev->ts1);
682
683 if (saa7164_boards[dev->board].portb == SAA7164_MPEG_DVB)
684 saa7164_dvb_unregister(&dev->ts2);
685
686 saa7164_i2c_unregister(&dev->i2c_bus[0]);
687 saa7164_i2c_unregister(&dev->i2c_bus[1]);
688 saa7164_i2c_unregister(&dev->i2c_bus[2]);
689
690 pci_disable_device(pci_dev);
691
692 /* unregister stuff */
693 free_irq(pci_dev->irq, dev);
694 pci_set_drvdata(pci_dev, NULL);
695
696 mutex_lock(&devlist);
697 list_del(&dev->devlist);
698 mutex_unlock(&devlist);
699
700 saa7164_dev_unregister(dev);
701 kfree(dev);
702}
703
704static struct pci_device_id saa7164_pci_tbl[] = {
705 {
706 /* SAA7164 */
707 .vendor = 0x1131,
708 .device = 0x7164,
709 .subvendor = PCI_ANY_ID,
710 .subdevice = PCI_ANY_ID,
711 }, {
712 /* --- end of list --- */
713 }
714};
715MODULE_DEVICE_TABLE(pci, saa7164_pci_tbl);
716
717static struct pci_driver saa7164_pci_driver = {
718 .name = "saa7164",
719 .id_table = saa7164_pci_tbl,
720 .probe = saa7164_initdev,
721 .remove = __devexit_p(saa7164_finidev),
722 /* TODO */
723 .suspend = NULL,
724 .resume = NULL,
725};
726
727static int saa7164_init(void)
728{
729 printk(KERN_INFO "saa7164 driver loaded\n");
730 return pci_register_driver(&saa7164_pci_driver);
731}
732
733static void saa7164_fini(void)
734{
735 pci_unregister_driver(&saa7164_pci_driver);
736}
737
738module_init(saa7164_init);
739module_exit(saa7164_fini);
740
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
new file mode 100644
index 000000000000..6a2d847d6a88
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -0,0 +1,602 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "saa7164.h"
23
24#include "tda10048.h"
25#include "tda18271.h"
26#include "s5h1411.h"
27
28#define DRIVER_NAME "saa7164"
29
30DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
31
32/* addr is in the card struct, get it from there */
33static struct tda10048_config hauppauge_hvr2200_1_config = {
34 .demod_address = 0x10 >> 1,
35 .output_mode = TDA10048_SERIAL_OUTPUT,
36 .fwbulkwritelen = TDA10048_BULKWRITE_200,
37 .inversion = TDA10048_INVERSION_ON,
38 .dtv6_if_freq_khz = TDA10048_IF_3300,
39 .dtv7_if_freq_khz = TDA10048_IF_3500,
40 .dtv8_if_freq_khz = TDA10048_IF_4000,
41 .clk_freq_khz = TDA10048_CLK_16000,
42};
43static struct tda10048_config hauppauge_hvr2200_2_config = {
44 .demod_address = 0x12 >> 1,
45 .output_mode = TDA10048_SERIAL_OUTPUT,
46 .fwbulkwritelen = TDA10048_BULKWRITE_200,
47 .inversion = TDA10048_INVERSION_ON,
48 .dtv6_if_freq_khz = TDA10048_IF_3300,
49 .dtv7_if_freq_khz = TDA10048_IF_3500,
50 .dtv8_if_freq_khz = TDA10048_IF_4000,
51 .clk_freq_khz = TDA10048_CLK_16000,
52};
53
54static struct tda18271_std_map hauppauge_tda18271_std_map = {
55 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
56 .if_lvl = 6, .rfagc_top = 0x37 },
57 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
58 .if_lvl = 6, .rfagc_top = 0x37 },
59};
60
61static struct tda18271_config hauppauge_hvr22x0_tuner_config = {
62 .std_map = &hauppauge_tda18271_std_map,
63 .gate = TDA18271_GATE_ANALOG,
64 .role = TDA18271_MASTER,
65};
66
67static struct tda18271_config hauppauge_hvr22x0s_tuner_config = {
68 .std_map = &hauppauge_tda18271_std_map,
69 .gate = TDA18271_GATE_ANALOG,
70 .role = TDA18271_SLAVE,
71 .rf_cal_on_startup = 1
72};
73
74static struct s5h1411_config hauppauge_s5h1411_config = {
75 .output_mode = S5H1411_SERIAL_OUTPUT,
76 .gpio = S5H1411_GPIO_ON,
77 .qam_if = S5H1411_IF_4000,
78 .vsb_if = S5H1411_IF_3250,
79 .inversion = S5H1411_INVERSION_ON,
80 .status_mode = S5H1411_DEMODLOCKING,
81 .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
82};
83
84static int saa7164_dvb_stop_tsport(struct saa7164_tsport *port)
85{
86 struct saa7164_dev *dev = port->dev;
87 int ret;
88
89 ret = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
90 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
91 printk(KERN_ERR "%s() stop transition failed, ret = 0x%x\n",
92 __func__, ret);
93 ret = -EIO;
94 } else {
95 dprintk(DBGLVL_DVB, "%s() Stopped\n", __func__);
96 ret = 0;
97 }
98
99 return ret;
100}
101
102static int saa7164_dvb_acquire_tsport(struct saa7164_tsport *port)
103{
104 struct saa7164_dev *dev = port->dev;
105 int ret;
106
107 ret = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
108 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
109 printk(KERN_ERR "%s() acquire transition failed, ret = 0x%x\n",
110 __func__, ret);
111 ret = -EIO;
112 } else {
113 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
114 ret = 0;
115 }
116
117 return ret;
118}
119
120static int saa7164_dvb_pause_tsport(struct saa7164_tsport *port)
121{
122 struct saa7164_dev *dev = port->dev;
123 int ret;
124
125 ret = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
126 if ((ret != SAA_OK) && (ret != SAA_ERR_ALREADY_STOPPED)) {
127 printk(KERN_ERR "%s() pause transition failed, ret = 0x%x\n",
128 __func__, ret);
129 ret = -EIO;
130 } else {
131 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
132 ret = 0;
133 }
134
135 return ret;
136}
137
138/* Firmware is very windows centric, meaning you have to transition
139 * the part through AVStream / KS Windows stages, forwards or backwards.
140 * States are: stopped, acquired (h/w), paused, started.
141 */
142static int saa7164_dvb_stop_streaming(struct saa7164_tsport *port)
143{
144 struct saa7164_dev *dev = port->dev;
145 int ret;
146
147 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
148
149 ret = saa7164_dvb_pause_tsport(port);
150 ret = saa7164_dvb_acquire_tsport(port);
151 ret = saa7164_dvb_stop_tsport(port);
152
153 return ret;
154}
155
156static int saa7164_dvb_cfg_tsport(struct saa7164_tsport *port)
157{
158 tmHWStreamParameters_t *params = &port->hw_streamingparams;
159 struct saa7164_dev *dev = port->dev;
160 struct saa7164_buffer *buf;
161 struct list_head *c, *n;
162 int i = 0;
163
164 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
165
166 saa7164_writel(port->pitch, params->pitch);
167 saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
168
169 dprintk(DBGLVL_DVB, " configured:\n");
170 dprintk(DBGLVL_DVB, " lmmio 0x%p\n", dev->lmmio);
171 dprintk(DBGLVL_DVB, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
172 saa7164_readl(port->bufcounter));
173
174 dprintk(DBGLVL_DVB, " pitch 0x%x = %d\n", port->pitch,
175 saa7164_readl(port->pitch));
176
177 dprintk(DBGLVL_DVB, " bufsize 0x%x = %d\n", port->bufsize,
178 saa7164_readl(port->bufsize));
179
180 dprintk(DBGLVL_DVB, " buffercount = %d\n", port->hwcfg.buffercount);
181 dprintk(DBGLVL_DVB, " bufoffset = 0x%x\n", port->bufoffset);
182 dprintk(DBGLVL_DVB, " bufptr32h = 0x%x\n", port->bufptr32h);
183 dprintk(DBGLVL_DVB, " bufptr32l = 0x%x\n", port->bufptr32l);
184
185 /* Poke the buffers and offsets into PCI space */
186 mutex_lock(&port->dmaqueue_lock);
187 list_for_each_safe(c, n, &port->dmaqueue.list) {
188 buf = list_entry(c, struct saa7164_buffer, list);
189
190 /* TODO: Review this in light of 32v64 assignments */
191 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
192 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i),
193 buf->pt_dma);
194 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
195
196 dprintk(DBGLVL_DVB,
197 " buf[%d] offset 0x%llx (0x%x) "
198 "buf 0x%llx/%llx (0x%x/%x)\n",
199 i,
200 (u64)port->bufoffset + (i * sizeof(u32)),
201 saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
202 (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
203 (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
204 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i)
205 * 2)),
206 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i)
207 * 2)));
208
209 if (i++ > port->hwcfg.buffercount)
210 BUG();
211
212 }
213 mutex_unlock(&port->dmaqueue_lock);
214
215 return 0;
216}
217
218static int saa7164_dvb_start_tsport(struct saa7164_tsport *port)
219{
220 struct saa7164_dev *dev = port->dev;
221 int ret = 0, result;
222
223 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
224
225 saa7164_dvb_cfg_tsport(port);
226
227 /* Acquire the hardware */
228 result = saa7164_api_transition_port(port, SAA_DMASTATE_ACQUIRE);
229 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
230 printk(KERN_ERR "%s() acquire transition failed, res = 0x%x\n",
231 __func__, result);
232
233 /* Stop the hardware, regardless */
234 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
235 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
236 printk(KERN_ERR "%s() acquire/forced stop transition "
237 "failed, res = 0x%x\n", __func__, result);
238 }
239 ret = -EIO;
240 goto out;
241 } else
242 dprintk(DBGLVL_DVB, "%s() Acquired\n", __func__);
243
244 /* Pause the hardware */
245 result = saa7164_api_transition_port(port, SAA_DMASTATE_PAUSE);
246 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
247 printk(KERN_ERR "%s() pause transition failed, res = 0x%x\n",
248 __func__, result);
249
250 /* Stop the hardware, regardless */
251 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
252 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
253 printk(KERN_ERR "%s() pause/forced stop transition "
254 "failed, res = 0x%x\n", __func__, result);
255 }
256
257 ret = -EIO;
258 goto out;
259 } else
260 dprintk(DBGLVL_DVB, "%s() Paused\n", __func__);
261
262 /* Start the hardware */
263 result = saa7164_api_transition_port(port, SAA_DMASTATE_RUN);
264 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
265 printk(KERN_ERR "%s() run transition failed, result = 0x%x\n",
266 __func__, result);
267
268 /* Stop the hardware, regardless */
269 result = saa7164_api_transition_port(port, SAA_DMASTATE_STOP);
270 if ((result != SAA_OK) && (result != SAA_ERR_ALREADY_STOPPED)) {
271 printk(KERN_ERR "%s() run/forced stop transition "
272 "failed, res = 0x%x\n", __func__, result);
273 }
274
275 ret = -EIO;
276 } else
277 dprintk(DBGLVL_DVB, "%s() Running\n", __func__);
278
279out:
280 return ret;
281}
282
283static int saa7164_dvb_start_feed(struct dvb_demux_feed *feed)
284{
285 struct dvb_demux *demux = feed->demux;
286 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
287 struct saa7164_dvb *dvb = &port->dvb;
288 struct saa7164_dev *dev = port->dev;
289 int ret = 0;
290
291 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
292
293 if (!demux->dmx.frontend)
294 return -EINVAL;
295
296 if (dvb) {
297 mutex_lock(&dvb->lock);
298 if (dvb->feeding++ == 0) {
299 /* Start transport */
300 ret = saa7164_dvb_start_tsport(port);
301 }
302 mutex_unlock(&dvb->lock);
303 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
304 __func__, port->nr, dvb->feeding);
305 }
306
307 return ret;
308}
309
310static int saa7164_dvb_stop_feed(struct dvb_demux_feed *feed)
311{
312 struct dvb_demux *demux = feed->demux;
313 struct saa7164_tsport *port = (struct saa7164_tsport *) demux->priv;
314 struct saa7164_dvb *dvb = &port->dvb;
315 struct saa7164_dev *dev = port->dev;
316 int ret = 0;
317
318 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
319
320 if (dvb) {
321 mutex_lock(&dvb->lock);
322 if (--dvb->feeding == 0) {
323 /* Stop transport */
324 ret = saa7164_dvb_stop_streaming(port);
325 }
326 mutex_unlock(&dvb->lock);
327 dprintk(DBGLVL_DVB, "%s(port=%d) now feeding = %d\n",
328 __func__, port->nr, dvb->feeding);
329 }
330
331 return ret;
332}
333
334static int dvb_register(struct saa7164_tsport *port)
335{
336 struct saa7164_dvb *dvb = &port->dvb;
337 struct saa7164_dev *dev = port->dev;
338 struct saa7164_buffer *buf;
339 int result, i;
340
341 dprintk(DBGLVL_DVB, "%s(port=%d)\n", __func__, port->nr);
342
343 /* Sanity check that the PCI configuration space is active */
344 if (port->hwcfg.BARLocation == 0) {
345 result = -ENOMEM;
346 printk(KERN_ERR "%s: dvb_register_adapter failed "
347 "(errno = %d), NO PCI configuration\n",
348 DRIVER_NAME, result);
349 goto fail_adapter;
350 }
351
352 /* Init and establish defaults */
353 port->hw_streamingparams.bitspersample = 8;
354 port->hw_streamingparams.samplesperline = 188;
355 port->hw_streamingparams.numberoflines =
356 (SAA7164_TS_NUMBER_OF_LINES * 188) / 188;
357
358 port->hw_streamingparams.pitch = 188;
359 port->hw_streamingparams.linethreshold = 0;
360 port->hw_streamingparams.pagetablelistvirt = 0;
361 port->hw_streamingparams.pagetablelistphys = 0;
362 port->hw_streamingparams.numpagetables = 2 +
363 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
364
365 port->hw_streamingparams.numpagetableentries = port->hwcfg.buffercount;
366
367 /* Allocate the PCI resources */
368 for (i = 0; i < port->hwcfg.buffercount; i++) {
369 buf = saa7164_buffer_alloc(port,
370 port->hw_streamingparams.numberoflines *
371 port->hw_streamingparams.pitch);
372
373 if (!buf) {
374 result = -ENOMEM;
375 printk(KERN_ERR "%s: dvb_register_adapter failed "
376 "(errno = %d), unable to allocate buffers\n",
377 DRIVER_NAME, result);
378 goto fail_adapter;
379 }
380 buf->nr = i;
381
382 mutex_lock(&port->dmaqueue_lock);
383 list_add_tail(&buf->list, &port->dmaqueue.list);
384 mutex_unlock(&port->dmaqueue_lock);
385 }
386
387 /* register adapter */
388 result = dvb_register_adapter(&dvb->adapter, DRIVER_NAME, THIS_MODULE,
389 &dev->pci->dev, adapter_nr);
390 if (result < 0) {
391 printk(KERN_ERR "%s: dvb_register_adapter failed "
392 "(errno = %d)\n", DRIVER_NAME, result);
393 goto fail_adapter;
394 }
395 dvb->adapter.priv = port;
396
397 /* register frontend */
398 result = dvb_register_frontend(&dvb->adapter, dvb->frontend);
399 if (result < 0) {
400 printk(KERN_ERR "%s: dvb_register_frontend failed "
401 "(errno = %d)\n", DRIVER_NAME, result);
402 goto fail_frontend;
403 }
404
405 /* register demux stuff */
406 dvb->demux.dmx.capabilities =
407 DMX_TS_FILTERING | DMX_SECTION_FILTERING |
408 DMX_MEMORY_BASED_FILTERING;
409 dvb->demux.priv = port;
410 dvb->demux.filternum = 256;
411 dvb->demux.feednum = 256;
412 dvb->demux.start_feed = saa7164_dvb_start_feed;
413 dvb->demux.stop_feed = saa7164_dvb_stop_feed;
414 result = dvb_dmx_init(&dvb->demux);
415 if (result < 0) {
416 printk(KERN_ERR "%s: dvb_dmx_init failed (errno = %d)\n",
417 DRIVER_NAME, result);
418 goto fail_dmx;
419 }
420
421 dvb->dmxdev.filternum = 256;
422 dvb->dmxdev.demux = &dvb->demux.dmx;
423 dvb->dmxdev.capabilities = 0;
424 result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter);
425 if (result < 0) {
426 printk(KERN_ERR "%s: dvb_dmxdev_init failed (errno = %d)\n",
427 DRIVER_NAME, result);
428 goto fail_dmxdev;
429 }
430
431 dvb->fe_hw.source = DMX_FRONTEND_0;
432 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw);
433 if (result < 0) {
434 printk(KERN_ERR "%s: add_frontend failed "
435 "(DMX_FRONTEND_0, errno = %d)\n", DRIVER_NAME, result);
436 goto fail_fe_hw;
437 }
438
439 dvb->fe_mem.source = DMX_MEMORY_FE;
440 result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem);
441 if (result < 0) {
442 printk(KERN_ERR "%s: add_frontend failed "
443 "(DMX_MEMORY_FE, errno = %d)\n", DRIVER_NAME, result);
444 goto fail_fe_mem;
445 }
446
447 result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw);
448 if (result < 0) {
449 printk(KERN_ERR "%s: connect_frontend failed (errno = %d)\n",
450 DRIVER_NAME, result);
451 goto fail_fe_conn;
452 }
453
454 /* register network adapter */
455 dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx);
456 return 0;
457
458fail_fe_conn:
459 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
460fail_fe_mem:
461 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
462fail_fe_hw:
463 dvb_dmxdev_release(&dvb->dmxdev);
464fail_dmxdev:
465 dvb_dmx_release(&dvb->demux);
466fail_dmx:
467 dvb_unregister_frontend(dvb->frontend);
468fail_frontend:
469 dvb_frontend_detach(dvb->frontend);
470 dvb_unregister_adapter(&dvb->adapter);
471fail_adapter:
472 return result;
473}
474
475int saa7164_dvb_unregister(struct saa7164_tsport *port)
476{
477 struct saa7164_dvb *dvb = &port->dvb;
478 struct saa7164_dev *dev = port->dev;
479 struct saa7164_buffer *b;
480 struct list_head *c, *n;
481
482 dprintk(DBGLVL_DVB, "%s()\n", __func__);
483
484 /* Remove any allocated buffers */
485 mutex_lock(&port->dmaqueue_lock);
486 list_for_each_safe(c, n, &port->dmaqueue.list) {
487 b = list_entry(c, struct saa7164_buffer, list);
488 list_del(c);
489 saa7164_buffer_dealloc(port, b);
490 }
491 mutex_unlock(&port->dmaqueue_lock);
492
493 if (dvb->frontend == NULL)
494 return 0;
495
496 dvb_net_release(&dvb->net);
497 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem);
498 dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw);
499 dvb_dmxdev_release(&dvb->dmxdev);
500 dvb_dmx_release(&dvb->demux);
501 dvb_unregister_frontend(dvb->frontend);
502 dvb_frontend_detach(dvb->frontend);
503 dvb_unregister_adapter(&dvb->adapter);
504 return 0;
505}
506
507/* All the DVB attach calls go here, this function get's modified
508 * for each new card.
509 */
510int saa7164_dvb_register(struct saa7164_tsport *port)
511{
512 struct saa7164_dev *dev = port->dev;
513 struct saa7164_dvb *dvb = &port->dvb;
514 struct saa7164_i2c *i2c_bus = NULL;
515 int ret;
516
517 dprintk(DBGLVL_DVB, "%s()\n", __func__);
518
519 /* init frontend */
520 switch (dev->board) {
521 case SAA7164_BOARD_HAUPPAUGE_HVR2200:
522 case SAA7164_BOARD_HAUPPAUGE_HVR2200_2:
523 case SAA7164_BOARD_HAUPPAUGE_HVR2200_3:
524 i2c_bus = &dev->i2c_bus[port->nr + 1];
525 switch (port->nr) {
526 case 0:
527 port->dvb.frontend = dvb_attach(tda10048_attach,
528 &hauppauge_hvr2200_1_config,
529 &i2c_bus->i2c_adap);
530
531 if (port->dvb.frontend != NULL) {
532 /* TODO: addr is in the card struct */
533 dvb_attach(tda18271_attach, port->dvb.frontend,
534 0xc0 >> 1, &i2c_bus->i2c_adap,
535 &hauppauge_hvr22x0_tuner_config);
536 }
537
538 break;
539 case 1:
540 port->dvb.frontend = dvb_attach(tda10048_attach,
541 &hauppauge_hvr2200_2_config,
542 &i2c_bus->i2c_adap);
543
544 if (port->dvb.frontend != NULL) {
545 /* TODO: addr is in the card struct */
546 dvb_attach(tda18271_attach, port->dvb.frontend,
547 0xc0 >> 1, &i2c_bus->i2c_adap,
548 &hauppauge_hvr22x0s_tuner_config);
549 }
550
551 break;
552 }
553 break;
554 case SAA7164_BOARD_HAUPPAUGE_HVR2250:
555 case SAA7164_BOARD_HAUPPAUGE_HVR2250_2:
556 case SAA7164_BOARD_HAUPPAUGE_HVR2250_3:
557 i2c_bus = &dev->i2c_bus[port->nr + 1];
558
559 port->dvb.frontend = dvb_attach(s5h1411_attach,
560 &hauppauge_s5h1411_config,
561 &i2c_bus->i2c_adap);
562
563 if (port->dvb.frontend != NULL) {
564 if (port->nr == 0) {
565 /* Master TDA18271 */
566 /* TODO: addr is in the card struct */
567 dvb_attach(tda18271_attach, port->dvb.frontend,
568 0xc0 >> 1, &i2c_bus->i2c_adap,
569 &hauppauge_hvr22x0_tuner_config);
570 } else {
571 /* Slave TDA18271 */
572 dvb_attach(tda18271_attach, port->dvb.frontend,
573 0xc0 >> 1, &i2c_bus->i2c_adap,
574 &hauppauge_hvr22x0s_tuner_config);
575 }
576 }
577
578 break;
579 default:
580 printk(KERN_ERR "%s: The frontend isn't supported\n",
581 dev->name);
582 break;
583 }
584 if (NULL == dvb->frontend) {
585 printk(KERN_ERR "%s() Frontend initialization failed\n",
586 __func__);
587 return -1;
588 }
589
590 /* Put the analog decoder in standby to keep it quiet */
591
592 /* register everything */
593 ret = dvb_register(port);
594 if (ret < 0) {
595 if (dvb->frontend->ops.release)
596 dvb->frontend->ops.release(dvb->frontend);
597 return ret;
598 }
599
600 return 0;
601}
602
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
new file mode 100644
index 000000000000..ee0af3534ede
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -0,0 +1,613 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/firmware.h>
23
24#include "saa7164.h"
25
26#define SAA7164_REV2_FIRMWARE "v4l-saa7164-1.0.2.fw"
27#define SAA7164_REV2_FIRMWARE_SIZE 3978608
28
29#define SAA7164_REV3_FIRMWARE "v4l-saa7164-1.0.3.fw"
30#define SAA7164_REV3_FIRMWARE_SIZE 3978608
31
32struct fw_header {
33 u32 firmwaresize;
34 u32 bslsize;
35 u32 reserved;
36 u32 version;
37};
38
39int saa7164_dl_wait_ack(struct saa7164_dev *dev, u32 reg)
40{
41 u32 timeout = SAA_DEVICE_TIMEOUT;
42 while ((saa7164_readl(reg) & 0x01) == 0) {
43 timeout -= 10;
44 if (timeout == 0) {
45 printk(KERN_ERR "%s() timeout (no d/l ack)\n",
46 __func__);
47 return -EBUSY;
48 }
49 msleep(100);
50 }
51
52 return 0;
53}
54
55int saa7164_dl_wait_clr(struct saa7164_dev *dev, u32 reg)
56{
57 u32 timeout = SAA_DEVICE_TIMEOUT;
58 while (saa7164_readl(reg) & 0x01) {
59 timeout -= 10;
60 if (timeout == 0) {
61 printk(KERN_ERR "%s() timeout (no d/l clr)\n",
62 __func__);
63 return -EBUSY;
64 }
65 msleep(100);
66 }
67
68 return 0;
69}
70
71/* TODO: move dlflags into dev-> and change to write/readl/b */
72/* TODO: Excessive levels of debug */
73int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
74 u32 dlflags, u8 *dst, u32 dstsize)
75{
76 u32 reg, timeout, offset;
77 u8 *srcbuf = NULL;
78 int ret;
79
80 u32 dlflag = dlflags;
81 u32 dlflag_ack = dlflag + 4;
82 u32 drflag = dlflag_ack + 4;
83 u32 drflag_ack = drflag + 4;
84 u32 bleflag = drflag_ack + 4;
85
86 dprintk(DBGLVL_FW,
87 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
88 __func__, src, srcsize, dlflags, dst, dstsize);
89
90 if ((src == 0) || (dst == 0)) {
91 ret = -EIO;
92 goto out;
93 }
94
95 srcbuf = kzalloc(4 * 1048576, GFP_KERNEL);
96 if (NULL == srcbuf) {
97 ret = -ENOMEM;
98 goto out;
99 }
100
101 if (srcsize > (4*1048576)) {
102 ret = -ENOMEM;
103 goto out;
104 }
105
106 memcpy(srcbuf, src, srcsize);
107
108 dprintk(DBGLVL_FW, "%s() dlflag = 0x%x\n", __func__, dlflag);
109 dprintk(DBGLVL_FW, "%s() dlflag_ack = 0x%x\n", __func__, dlflag_ack);
110 dprintk(DBGLVL_FW, "%s() drflag = 0x%x\n", __func__, drflag);
111 dprintk(DBGLVL_FW, "%s() drflag_ack = 0x%x\n", __func__, drflag_ack);
112 dprintk(DBGLVL_FW, "%s() bleflag = 0x%x\n", __func__, bleflag);
113
114 reg = saa7164_readl(dlflag);
115 dprintk(DBGLVL_FW, "%s() dlflag (0x%x)= 0x%x\n", __func__, dlflag, reg);
116 if (reg == 1)
117 dprintk(DBGLVL_FW,
118 "%s() Download flag already set, please reboot\n",
119 __func__);
120
121 /* Indicate download start */
122 saa7164_writel(dlflag, 1);
123 ret = saa7164_dl_wait_ack(dev, dlflag_ack);
124 if (ret < 0)
125 goto out;
126
127 /* Ack download start, then wait for wait */
128 saa7164_writel(dlflag, 0);
129 ret = saa7164_dl_wait_clr(dev, dlflag_ack);
130 if (ret < 0)
131 goto out;
132
133 /* Deal with the raw firmware, in the appropriate chunk size */
134 for (offset = 0; srcsize > dstsize;
135 srcsize -= dstsize, offset += dstsize) {
136
137 dprintk(DBGLVL_FW, "%s() memcpy %d\n", __func__, dstsize);
138 memcpy(dst, srcbuf + offset, dstsize);
139
140 /* Flag the data as ready */
141 saa7164_writel(drflag, 1);
142 ret = saa7164_dl_wait_ack(dev, drflag_ack);
143 if (ret < 0)
144 goto out;
145
146 /* Wait for indication data was received */
147 saa7164_writel(drflag, 0);
148 ret = saa7164_dl_wait_clr(dev, drflag_ack);
149 if (ret < 0)
150 goto out;
151
152 }
153
154 dprintk(DBGLVL_FW, "%s() memcpy(l) %d\n", __func__, dstsize);
155 /* Write last block to the device */
156 memcpy(dst, srcbuf+offset, srcsize);
157
158 /* Flag the data as ready */
159 saa7164_writel(drflag, 1);
160 ret = saa7164_dl_wait_ack(dev, drflag_ack);
161 if (ret < 0)
162 goto out;
163
164 saa7164_writel(drflag, 0);
165 timeout = 0;
166 while (saa7164_readl(bleflag) != SAA_DEVICE_IMAGE_BOOTING) {
167 if (saa7164_readl(bleflag) & SAA_DEVICE_IMAGE_CORRUPT) {
168 printk(KERN_ERR "%s() image corrupt\n", __func__);
169 ret = -EBUSY;
170 goto out;
171 }
172
173 if (saa7164_readl(bleflag) & SAA_DEVICE_MEMORY_CORRUPT) {
174 printk(KERN_ERR "%s() device memory corrupt\n",
175 __func__);
176 ret = -EBUSY;
177 goto out;
178 }
179
180 msleep(10);
181 if (timeout++ > 60)
182 break;
183 }
184
185 printk(KERN_INFO "%s() Image downloaded, booting...\n", __func__);
186
187 ret = saa7164_dl_wait_clr(dev, drflag_ack);
188 if (ret < 0)
189 goto out;
190
191 printk(KERN_INFO "%s() Image booted successfully.\n", __func__);
192 ret = 0;
193
194out:
195 kfree(srcbuf);
196 return ret;
197}
198
199/* TODO: Excessive debug */
200/* Load the firmware. Optionally it can be in ROM or newer versions
201 * can be on disk, saving the expense of the ROM hardware. */
202int saa7164_downloadfirmware(struct saa7164_dev *dev)
203{
204 /* u32 second_timeout = 60 * SAA_DEVICE_TIMEOUT; */
205 u32 tmp, filesize, version, err_flags, first_timeout, fwlength;
206 u32 second_timeout, updatebootloader = 1, bootloadersize = 0;
207 const struct firmware *fw = NULL;
208 struct fw_header *hdr, *boothdr = NULL, *fwhdr;
209 u32 bootloaderversion = 0, fwloadersize;
210 u8 *bootloaderoffset = NULL, *fwloaderoffset;
211 char *fwname;
212 int ret;
213
214 dprintk(DBGLVL_FW, "%s()\n", __func__);
215
216 if (saa7164_boards[dev->board].chiprev == SAA7164_CHIP_REV2) {
217 fwname = SAA7164_REV2_FIRMWARE;
218 fwlength = SAA7164_REV2_FIRMWARE_SIZE;
219 } else {
220 fwname = SAA7164_REV3_FIRMWARE;
221 fwlength = SAA7164_REV3_FIRMWARE_SIZE;
222 }
223
224 version = saa7164_getcurrentfirmwareversion(dev);
225
226 if (version == 0x00) {
227
228 second_timeout = 100;
229 first_timeout = 100;
230 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
231 dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
232 __func__, err_flags);
233
234 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
235 dprintk(DBGLVL_FW, "%s() err_flags = %x\n",
236 __func__, err_flags);
237 msleep(10);
238
239 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
240 printk(KERN_ERR "%s() firmware corrupt\n",
241 __func__);
242 break;
243 }
244 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
245 printk(KERN_ERR "%s() device memory corrupt\n",
246 __func__);
247 break;
248 }
249 if (err_flags & SAA_DEVICE_NO_IMAGE) {
250 printk(KERN_ERR "%s() no first image\n",
251 __func__);
252 break;
253 }
254 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
255 first_timeout -= 10;
256 if (first_timeout == 0) {
257 printk(KERN_ERR
258 "%s() no first image\n",
259 __func__);
260 break;
261 }
262 } else if (err_flags & SAA_DEVICE_IMAGE_LOADING) {
263 second_timeout -= 10;
264 if (second_timeout == 0) {
265 printk(KERN_ERR
266 "%s() FW load time exceeded\n",
267 __func__);
268 break;
269 }
270 } else {
271 second_timeout -= 10;
272 if (second_timeout == 0) {
273 printk(KERN_ERR
274 "%s() Unknown bootloader flags 0x%x\n",
275 __func__, err_flags);
276 break;
277 }
278 }
279
280 err_flags = saa7164_readl(SAA_BOOTLOADERERROR_FLAGS);
281 } /* While != Booting */
282
283 if (err_flags == SAA_DEVICE_IMAGE_BOOTING) {
284 dprintk(DBGLVL_FW, "%s() Loader 1 has loaded.\n",
285 __func__);
286 first_timeout = SAA_DEVICE_TIMEOUT;
287 second_timeout = 60 * SAA_DEVICE_TIMEOUT;
288 second_timeout = 100;
289
290 err_flags = saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
291 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
292 __func__, err_flags);
293 while (err_flags != SAA_DEVICE_IMAGE_BOOTING) {
294 dprintk(DBGLVL_FW, "%s() err_flags2 = %x\n",
295 __func__, err_flags);
296 msleep(10);
297
298 if (err_flags & SAA_DEVICE_IMAGE_CORRUPT) {
299 printk(KERN_ERR
300 "%s() firmware corrupt\n",
301 __func__);
302 break;
303 }
304 if (err_flags & SAA_DEVICE_MEMORY_CORRUPT) {
305 printk(KERN_ERR
306 "%s() device memory corrupt\n",
307 __func__);
308 break;
309 }
310 if (err_flags & SAA_DEVICE_NO_IMAGE) {
311 printk(KERN_ERR "%s() no first image\n",
312 __func__);
313 break;
314 }
315 if (err_flags & SAA_DEVICE_IMAGE_SEARCHING) {
316 first_timeout -= 10;
317 if (first_timeout == 0) {
318 printk(KERN_ERR
319 "%s() no second image\n",
320 __func__);
321 break;
322 }
323 } else if (err_flags &
324 SAA_DEVICE_IMAGE_LOADING) {
325 second_timeout -= 10;
326 if (second_timeout == 0) {
327 printk(KERN_ERR
328 "%s() FW load time exceeded\n",
329 __func__);
330 break;
331 }
332 } else {
333 second_timeout -= 10;
334 if (second_timeout == 0) {
335 printk(KERN_ERR
336 "%s() Unknown bootloader flags 0x%x\n",
337 __func__, err_flags);
338 break;
339 }
340 }
341
342 err_flags =
343 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS);
344 } /* err_flags != SAA_DEVICE_IMAGE_BOOTING */
345
346 dprintk(DBGLVL_FW, "%s() Loader flags 1:0x%x 2:0x%x.\n",
347 __func__,
348 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS),
349 saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS));
350
351 } /* err_flags == SAA_DEVICE_IMAGE_BOOTING */
352
353 /* It's possible for both firmwares to have booted,
354 * but that doesn't mean they've finished booting yet.
355 */
356 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
357 SAA_DEVICE_IMAGE_BOOTING) &&
358 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
359 SAA_DEVICE_IMAGE_BOOTING)) {
360
361
362 dprintk(DBGLVL_FW, "%s() Loader 2 has loaded.\n",
363 __func__);
364
365 first_timeout = SAA_DEVICE_TIMEOUT;
366 while (first_timeout) {
367 msleep(10);
368
369 version =
370 saa7164_getcurrentfirmwareversion(dev);
371 if (version) {
372 dprintk(DBGLVL_FW,
373 "%s() All f/w loaded successfully\n",
374 __func__);
375 break;
376 } else {
377 first_timeout -= 10;
378 if (first_timeout == 0) {
379 printk(KERN_ERR
380 "%s() FW did not boot\n",
381 __func__);
382 break;
383 }
384 }
385 }
386 }
387 version = saa7164_getcurrentfirmwareversion(dev);
388 } /* version == 0 */
389
390 /* Has the firmware really booted? */
391 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
392 SAA_DEVICE_IMAGE_BOOTING) &&
393 (saa7164_readl(SAA_SECONDSTAGEERROR_FLAGS) ==
394 SAA_DEVICE_IMAGE_BOOTING) && (version == 0)) {
395
396 printk(KERN_ERR
397 "%s() The firmware hung, probably bad firmware\n",
398 __func__);
399
400 /* Tell the second stage loader we have a deadlock */
401 saa7164_writel(SAA_DEVICE_DEADLOCK_DETECTED_OFFSET,
402 SAA_DEVICE_DEADLOCK_DETECTED);
403
404 saa7164_getfirmwarestatus(dev);
405
406 return -ENOMEM;
407 }
408
409 dprintk(DBGLVL_FW, "Device has Firmware Version %d.%d.%d.%d\n",
410 (version & 0x0000fc00) >> 10,
411 (version & 0x000003e0) >> 5,
412 (version & 0x0000001f),
413 (version & 0xffff0000) >> 16);
414
415 /* Load the firmwware from the disk if required */
416 if (version == 0) {
417
418 printk(KERN_INFO "%s() Waiting for firmware upload (%s)\n",
419 __func__, fwname);
420
421 ret = request_firmware(&fw, fwname, &dev->pci->dev);
422 if (ret) {
423 printk(KERN_ERR "%s() Upload failed. "
424 "(file not found?)\n", __func__);
425 return -ENOMEM;
426 }
427
428 printk(KERN_INFO "%s() firmware read %Zu bytes.\n",
429 __func__, fw->size);
430
431 if (fw->size != fwlength) {
432 printk(KERN_ERR "xc5000: firmware incorrect size\n");
433 ret = -ENOMEM;
434 goto out;
435 }
436
437 printk(KERN_INFO "%s() firmware loaded.\n", __func__);
438
439 hdr = (struct fw_header *)fw->data;
440 printk(KERN_INFO "Firmware file header part 1:\n");
441 printk(KERN_INFO " .FirmwareSize = 0x%x\n", hdr->firmwaresize);
442 printk(KERN_INFO " .BSLSize = 0x%x\n", hdr->bslsize);
443 printk(KERN_INFO " .Reserved = 0x%x\n", hdr->reserved);
444 printk(KERN_INFO " .Version = 0x%x\n", hdr->version);
445
446 /* Retreive bootloader if reqd */
447 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0))
448 /* Second bootloader in the firmware file */
449 filesize = hdr->reserved * 16;
450 else
451 filesize = (hdr->firmwaresize + hdr->bslsize) *
452 16 + sizeof(struct fw_header);
453
454 printk(KERN_INFO "%s() SecBootLoader.FileSize = %d\n",
455 __func__, filesize);
456
457 /* Get bootloader (if reqd) and firmware header */
458 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
459 /* Second boot loader is required */
460
461 /* Get the loader header */
462 boothdr = (struct fw_header *)(fw->data +
463 sizeof(struct fw_header));
464
465 bootloaderversion =
466 saa7164_readl(SAA_DEVICE_2ND_VERSION);
467 dprintk(DBGLVL_FW, "Onboard BootLoader:\n");
468 dprintk(DBGLVL_FW, "->Flag 0x%x\n",
469 saa7164_readl(SAA_BOOTLOADERERROR_FLAGS));
470 dprintk(DBGLVL_FW, "->Ack 0x%x\n",
471 saa7164_readl(SAA_DATAREADY_FLAG_ACK));
472 dprintk(DBGLVL_FW, "->FW Version 0x%x\n", version);
473 dprintk(DBGLVL_FW, "->Loader Version 0x%x\n",
474 bootloaderversion);
475
476 if ((saa7164_readl(SAA_BOOTLOADERERROR_FLAGS) ==
477 0x03) && (saa7164_readl(SAA_DATAREADY_FLAG_ACK)
478 == 0x00) && (version == 0x00)) {
479
480 dprintk(DBGLVL_FW, "BootLoader version in "
481 "rom %d.%d.%d.%d\n",
482 (bootloaderversion & 0x0000fc00) >> 10,
483 (bootloaderversion & 0x000003e0) >> 5,
484 (bootloaderversion & 0x0000001f),
485 (bootloaderversion & 0xffff0000) >> 16
486 );
487 dprintk(DBGLVL_FW, "BootLoader version "
488 "in file %d.%d.%d.%d\n",
489 (boothdr->version & 0x0000fc00) >> 10,
490 (boothdr->version & 0x000003e0) >> 5,
491 (boothdr->version & 0x0000001f),
492 (boothdr->version & 0xffff0000) >> 16
493 );
494
495 if (bootloaderversion == boothdr->version)
496 updatebootloader = 0;
497 }
498
499 /* Calculate offset to firmware header */
500 tmp = (boothdr->firmwaresize + boothdr->bslsize) * 16 +
501 (sizeof(struct fw_header) +
502 sizeof(struct fw_header));
503
504 fwhdr = (struct fw_header *)(fw->data+tmp);
505 } else {
506 /* No second boot loader */
507 fwhdr = hdr;
508 }
509
510 dprintk(DBGLVL_FW, "Firmware version in file %d.%d.%d.%d\n",
511 (fwhdr->version & 0x0000fc00) >> 10,
512 (fwhdr->version & 0x000003e0) >> 5,
513 (fwhdr->version & 0x0000001f),
514 (fwhdr->version & 0xffff0000) >> 16
515 );
516
517 if (version == fwhdr->version) {
518 /* No download, firmware already on board */
519 ret = 0;
520 goto out;
521 }
522
523 if ((hdr->firmwaresize == 0) && (hdr->bslsize == 0)) {
524 if (updatebootloader) {
525 /* Get ready to upload the bootloader */
526 bootloadersize = (boothdr->firmwaresize +
527 boothdr->bslsize) * 16 +
528 sizeof(struct fw_header);
529
530 bootloaderoffset = (u8 *)(fw->data +
531 sizeof(struct fw_header));
532
533 dprintk(DBGLVL_FW, "bootloader d/l starts.\n");
534 printk(KERN_INFO "%s() FirmwareSize = 0x%x\n",
535 __func__, boothdr->firmwaresize);
536 printk(KERN_INFO "%s() BSLSize = 0x%x\n",
537 __func__, boothdr->bslsize);
538 printk(KERN_INFO "%s() Reserved = 0x%x\n",
539 __func__, boothdr->reserved);
540 printk(KERN_INFO "%s() Version = 0x%x\n",
541 __func__, boothdr->version);
542 ret = saa7164_downloadimage(
543 dev,
544 bootloaderoffset,
545 bootloadersize,
546 SAA_DOWNLOAD_FLAGS,
547 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
548 SAA_DEVICE_BUFFERBLOCKSIZE);
549 if (ret < 0) {
550 printk(KERN_ERR
551 "bootloader d/l has failed\n");
552 goto out;
553 }
554 dprintk(DBGLVL_FW,
555 "bootloader download complete.\n");
556
557 }
558
559 printk(KERN_ERR "starting firmware download(2)\n");
560 bootloadersize = (boothdr->firmwaresize +
561 boothdr->bslsize) * 16 +
562 sizeof(struct fw_header);
563
564 bootloaderoffset =
565 (u8 *)(fw->data + sizeof(struct fw_header));
566
567 fwloaderoffset = bootloaderoffset + bootloadersize;
568
569 /* TODO: fix this bounds overrun here with old f/ws */
570 fwloadersize = (fwhdr->firmwaresize + fwhdr->bslsize) *
571 16 + sizeof(struct fw_header);
572
573 ret = saa7164_downloadimage(
574 dev,
575 fwloaderoffset,
576 fwloadersize,
577 SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET,
578 dev->bmmio + SAA_DEVICE_2ND_DOWNLOAD_OFFSET,
579 SAA_DEVICE_2ND_BUFFERBLOCKSIZE);
580 if (ret < 0) {
581 printk(KERN_ERR "firmware download failed\n");
582 goto out;
583 }
584 printk(KERN_ERR "firmware download complete.\n");
585
586 } else {
587
588 /* No bootloader update reqd, download firmware only */
589 printk(KERN_ERR "starting firmware download(3)\n");
590
591 ret = saa7164_downloadimage(
592 dev,
593 (u8 *)fw->data,
594 fw->size,
595 SAA_DOWNLOAD_FLAGS,
596 dev->bmmio + SAA_DEVICE_DOWNLOAD_OFFSET,
597 SAA_DEVICE_BUFFERBLOCKSIZE);
598 if (ret < 0) {
599 printk(KERN_ERR "firmware download failed\n");
600 goto out;
601 }
602 printk(KERN_ERR "firmware download complete.\n");
603 }
604 }
605
606 ret = 0;
607
608out:
609 if (fw)
610 release_firmware(fw);
611
612 return ret;
613}
diff --git a/drivers/media/video/saa7164/saa7164-i2c.c b/drivers/media/video/saa7164/saa7164-i2c.c
new file mode 100644
index 000000000000..e1ae9b01bf0f
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-i2c.c
@@ -0,0 +1,141 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/init.h>
25#include <linux/delay.h>
26#include <asm/io.h>
27
28#include "saa7164.h"
29
30static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
31{
32 struct saa7164_i2c *bus = i2c_adap->algo_data;
33 struct saa7164_dev *dev = bus->dev;
34 int i, retval = 0;
35
36 dprintk(DBGLVL_I2C, "%s(num = %d)\n", __func__, num);
37
38 for (i = 0 ; i < num; i++) {
39 dprintk(DBGLVL_I2C, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
40 __func__, num, msgs[i].addr, msgs[i].len);
41 if (msgs[i].flags & I2C_M_RD) {
42 /* Unsupported - Yet*/
43 printk(KERN_ERR "%s() Unsupported - Yet\n", __func__);
44 continue;
45 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
46 msgs[i].addr == msgs[i + 1].addr) {
47 /* write then read from same address */
48
49 retval = saa7164_api_i2c_read(bus, msgs[i].addr,
50 msgs[i].len, msgs[i].buf,
51 msgs[i+1].len, msgs[i+1].buf
52 );
53
54 i++;
55
56 if (retval < 0)
57 goto err;
58 } else {
59 /* write */
60 retval = saa7164_api_i2c_write(bus, msgs[i].addr,
61 msgs[i].len, msgs[i].buf);
62 }
63 if (retval < 0)
64 goto err;
65 }
66 return num;
67
68 err:
69 return retval;
70}
71
72void saa7164_call_i2c_clients(struct saa7164_i2c *bus, unsigned int cmd,
73 void *arg)
74{
75 if (bus->i2c_rc != 0)
76 return;
77
78 i2c_clients_command(&bus->i2c_adap, cmd, arg);
79}
80
81static u32 saa7164_functionality(struct i2c_adapter *adap)
82{
83 return I2C_FUNC_I2C;
84}
85
86static struct i2c_algorithm saa7164_i2c_algo_template = {
87 .master_xfer = i2c_xfer,
88 .functionality = saa7164_functionality,
89};
90
91/* ----------------------------------------------------------------------- */
92
93static struct i2c_adapter saa7164_i2c_adap_template = {
94 .name = "saa7164",
95 .owner = THIS_MODULE,
96 .algo = &saa7164_i2c_algo_template,
97};
98
99static struct i2c_client saa7164_i2c_client_template = {
100 .name = "saa7164 internal",
101};
102
103int saa7164_i2c_register(struct saa7164_i2c *bus)
104{
105 struct saa7164_dev *dev = bus->dev;
106
107 dprintk(DBGLVL_I2C, "%s(bus = %d)\n", __func__, bus->nr);
108
109 memcpy(&bus->i2c_adap, &saa7164_i2c_adap_template,
110 sizeof(bus->i2c_adap));
111
112 memcpy(&bus->i2c_algo, &saa7164_i2c_algo_template,
113 sizeof(bus->i2c_algo));
114
115 memcpy(&bus->i2c_client, &saa7164_i2c_client_template,
116 sizeof(bus->i2c_client));
117
118 bus->i2c_adap.dev.parent = &dev->pci->dev;
119
120 strlcpy(bus->i2c_adap.name, bus->dev->name,
121 sizeof(bus->i2c_adap.name));
122
123 bus->i2c_algo.data = bus;
124 bus->i2c_adap.algo_data = bus;
125 i2c_set_adapdata(&bus->i2c_adap, bus);
126 i2c_add_adapter(&bus->i2c_adap);
127
128 bus->i2c_client.adapter = &bus->i2c_adap;
129
130 if (0 != bus->i2c_rc)
131 printk(KERN_ERR "%s: i2c bus %d register FAILED\n",
132 dev->name, bus->nr);
133
134 return bus->i2c_rc;
135}
136
137int saa7164_i2c_unregister(struct saa7164_i2c *bus)
138{
139 i2c_del_adapter(&bus->i2c_adap);
140 return 0;
141}
diff --git a/drivers/media/video/saa7164/saa7164-reg.h b/drivers/media/video/saa7164/saa7164-reg.h
new file mode 100644
index 000000000000..06be4c13d5b1
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-reg.h
@@ -0,0 +1,166 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/* TODO: Retest the driver with errors expressed as negatives */
23
24/* Result codes */
25#define SAA_OK 0
26#define SAA_ERR_BAD_PARAMETER 0x09
27#define SAA_ERR_NO_RESOURCES 0x0c
28#define SAA_ERR_NOT_SUPPORTED 0x13
29#define SAA_ERR_BUSY 0x15
30#define SAA_ERR_READ 0x17
31#define SAA_ERR_TIMEOUT 0x1f
32#define SAA_ERR_OVERFLOW 0x20
33#define SAA_ERR_EMPTY 0x22
34#define SAA_ERR_NOT_STARTED 0x23
35#define SAA_ERR_ALREADY_STARTED 0x24
36#define SAA_ERR_NOT_STOPPED 0x25
37#define SAA_ERR_ALREADY_STOPPED 0x26
38#define SAA_ERR_INVALID_COMMAND 0x3e
39#define SAA_ERR_NULL_PACKET 0x59
40
41/* Errors and flags from the silicon */
42#define PVC_ERRORCODE_UNKNOWN 0x00
43#define PVC_ERRORCODE_INVALID_COMMAND 0x01
44#define PVC_ERRORCODE_INVALID_CONTROL 0x02
45#define PVC_ERRORCODE_INVALID_DATA 0x03
46#define PVC_ERRORCODE_TIMEOUT 0x04
47#define PVC_ERRORCODE_NAK 0x05
48#define PVC_RESPONSEFLAG_ERROR 0x01
49#define PVC_RESPONSEFLAG_OVERFLOW 0x02
50#define PVC_RESPONSEFLAG_RESET 0x04
51#define PVC_RESPONSEFLAG_INTERFACE 0x08
52#define PVC_RESPONSEFLAG_CONTINUED 0x10
53#define PVC_CMDFLAG_INTERRUPT 0x02
54#define PVC_CMDFLAG_INTERFACE 0x04
55#define PVC_CMDFLAG_SERIALIZE 0x08
56#define PVC_CMDFLAG_CONTINUE 0x10
57
58/* Silicon Commands */
59#define GET_DESCRIPTORS_CONTROL 0x01
60#define GET_STRING_CONTROL 0x03
61#define GET_LANGUAGE_CONTROL 0x05
62#define SET_POWER_CONTROL 0x07
63#define GET_FW_VERSION_CONTROL 0x09
64#define SET_DEBUG_LEVEL_CONTROL 0x0B
65#define GET_DEBUG_DATA_CONTROL 0x0C
66#define GET_PRODUCTION_INFO_CONTROL 0x0D
67
68/* cmd defines */
69#define SAA_CMDFLAG_CONTINUE 0x10
70#define SAA_CMD_MAX_MSG_UNITS 256
71
72/* Some defines */
73#define SAA_BUS_TIMEOUT 50
74#define SAA_DEVICE_TIMEOUT 5000
75#define SAA_DEVICE_MAXREQUESTSIZE 256
76
77/* Register addresses */
78#define SAA_DEVICE_VERSION 0x30
79#define SAA_DOWNLOAD_FLAGS 0x34
80#define SAA_DOWNLOAD_FLAG 0x34
81#define SAA_DOWNLOAD_FLAG_ACK 0x38
82#define SAA_DATAREADY_FLAG 0x3C
83#define SAA_DATAREADY_FLAG_ACK 0x40
84
85/* Boot loader register and bit definitions */
86#define SAA_BOOTLOADERERROR_FLAGS 0x44
87#define SAA_DEVICE_IMAGE_SEARCHING 0x01
88#define SAA_DEVICE_IMAGE_LOADING 0x02
89#define SAA_DEVICE_IMAGE_BOOTING 0x03
90#define SAA_DEVICE_IMAGE_CORRUPT 0x04
91#define SAA_DEVICE_MEMORY_CORRUPT 0x08
92#define SAA_DEVICE_NO_IMAGE 0x10
93
94/* Register addresses */
95#define SAA_DEVICE_2ND_VERSION 0x50
96#define SAA_DEVICE_2ND_DOWNLOADFLAG_OFFSET 0x54
97
98/* Register addresses */
99#define SAA_SECONDSTAGEERROR_FLAGS 0x64
100
101/* Bootloader regs and flags */
102#define SAA_DEVICE_DEADLOCK_DETECTED_OFFSET 0x6C
103#define SAA_DEVICE_DEADLOCK_DETECTED 0xDEADDEAD
104
105/* Basic firmware status registers */
106#define SAA_DEVICE_SYSINIT_STATUS_OFFSET 0x70
107#define SAA_DEVICE_SYSINIT_STATUS 0x70
108#define SAA_DEVICE_SYSINIT_MODE 0x74
109#define SAA_DEVICE_SYSINIT_SPEC 0x78
110#define SAA_DEVICE_SYSINIT_INST 0x7C
111#define SAA_DEVICE_SYSINIT_CPULOAD 0x80
112#define SAA_DEVICE_SYSINIT_REMAINHEAP 0x84
113
114#define SAA_DEVICE_DOWNLOAD_OFFSET 0x1000
115#define SAA_DEVICE_BUFFERBLOCKSIZE 0x1000
116
117#define SAA_DEVICE_2ND_BUFFERBLOCKSIZE 0x100000
118#define SAA_DEVICE_2ND_DOWNLOAD_OFFSET 0x200000
119
120/* Descriptors */
121#define CS_INTERFACE 0x24
122
123/* Descriptor subtypes */
124#define VC_INPUT_TERMINAL 0x02
125#define VC_OUTPUT_TERMINAL 0x03
126#define VC_SELECTOR_UNIT 0x04
127#define VC_PROCESSING_UNIT 0x05
128#define FEATURE_UNIT 0x06
129#define TUNER_UNIT 0x09
130#define ENCODER_UNIT 0x0A
131#define EXTENSION_UNIT 0x0B
132#define VC_TUNER_PATH 0xF0
133#define PVC_HARDWARE_DESCRIPTOR 0xF1
134#define PVC_INTERFACE_DESCRIPTOR 0xF2
135#define PVC_INFRARED_UNIT 0xF3
136#define DRM_UNIT 0xF4
137#define GENERAL_REQUEST 0xF5
138
139/* Format Types */
140#define VS_FORMAT_TYPE 0x02
141#define VS_FORMAT_TYPE_I 0x01
142#define VS_FORMAT_UNCOMPRESSED 0x04
143#define VS_FRAME_UNCOMPRESSED 0x05
144#define VS_FORMAT_MPEG2PS 0x09
145#define VS_FORMAT_MPEG2TS 0x0A
146#define VS_FORMAT_MPEG4SL 0x0B
147#define VS_FORMAT_WM9 0x0C
148#define VS_FORMAT_DIVX 0x0D
149#define VS_FORMAT_VBI 0x0E
150#define VS_FORMAT_RDS 0x0F
151
152/* Device extension commands */
153#define EXU_REGISTER_ACCESS_CONTROL 0x00
154#define EXU_GPIO_CONTROL 0x01
155#define EXU_GPIO_GROUP_CONTROL 0x02
156#define EXU_INTERRUPT_CONTROL 0x03
157
158/* State Transition and args */
159#define SAA_STATE_CONTROL 0x03
160#define SAA_DMASTATE_STOP 0x00
161#define SAA_DMASTATE_ACQUIRE 0x01
162#define SAA_DMASTATE_PAUSE 0x02
163#define SAA_DMASTATE_RUN 0x03
164
165/* Hardware registers */
166
diff --git a/drivers/media/video/saa7164/saa7164-types.h b/drivers/media/video/saa7164/saa7164-types.h
new file mode 100644
index 000000000000..99093f23aae5
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164-types.h
@@ -0,0 +1,287 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/* TODO: Cleanup and shorten the namespace */
23
24/* Some structues are passed directly to/from the firmware and
25 * have strict alignment requirements. This is one of them.
26 */
27typedef struct {
28 u8 bLength;
29 u8 bDescriptorType;
30 u8 bDescriptorSubtype;
31 u16 bcdSpecVersion;
32 u32 dwClockFrequency;
33 u32 dwClockUpdateRes;
34 u8 bCapabilities;
35 u32 dwDeviceRegistersLocation;
36 u32 dwHostMemoryRegion;
37 u32 dwHostMemoryRegionSize;
38 u32 dwHostHibernatMemRegion;
39 u32 dwHostHibernatMemRegionSize;
40} __attribute__((packed)) tmComResHWDescr_t;
41
42/* This is DWORD aligned on windows but I can't find the right
43 * gcc syntax to match the binary data from the device.
44 * I've manually padded with Reserved[3] bytes to match the hardware,
45 * but this could break if GCC decies to pack in a different way.
46 */
47typedef struct {
48 u8 bLength;
49 u8 bDescriptorType;
50 u8 bDescriptorSubtype;
51 u8 bFlags;
52 u8 bInterfaceType;
53 u8 bInterfaceId;
54 u8 bBaseInterface;
55 u8 bInterruptId;
56 u8 bDebugInterruptId;
57 u8 BARLocation;
58 u8 Reserved[3];
59} tmComResInterfaceDescr_t;
60
61typedef struct {
62 u64 CommandRing;
63 u64 ResponseRing;
64 u32 CommandWrite;
65 u32 CommandRead;
66 u32 ResponseWrite;
67 u32 ResponseRead;
68} tmComResBusDescr_t;
69
70typedef enum {
71 NONE = 0,
72 TYPE_BUS_PCI = 1,
73 TYPE_BUS_PCIe = 2,
74 TYPE_BUS_USB = 3,
75 TYPE_BUS_I2C = 4
76} tmBusType_t;
77
78typedef struct {
79 tmBusType_t Type;
80 u16 m_wMaxReqSize;
81 u8 *m_pdwSetRing;
82 u32 m_dwSizeSetRing;
83 u8 *m_pdwGetRing;
84 u32 m_dwSizeGetRing;
85 u32 *m_pdwSetWritePos;
86 u32 *m_pdwSetReadPos;
87 u32 *m_pdwGetWritePos;
88 u32 *m_pdwGetReadPos;
89
90 /* All access is protected */
91 struct mutex lock;
92
93} tmComResBusInfo_t;
94
95typedef struct {
96 u8 id;
97 u8 flags;
98 u16 size;
99 u32 command;
100 u16 controlselector;
101 u8 seqno;
102} __attribute__((packed)) tmComResInfo_t;
103
104typedef enum {
105 SET_CUR = 0x01,
106 GET_CUR = 0x81,
107 GET_MIN = 0x82,
108 GET_MAX = 0x83,
109 GET_RES = 0x84,
110 GET_LEN = 0x85,
111 GET_INFO = 0x86,
112 GET_DEF = 0x87
113} tmComResCmd_t;
114
115struct cmd {
116 u8 seqno;
117 u32 inuse;
118 u32 timeout;
119 u32 signalled;
120 struct mutex lock;
121 wait_queue_head_t wait;
122};
123
124typedef struct {
125 u32 pathid;
126 u32 size;
127 void *descriptor;
128} tmDescriptor_t;
129
130typedef struct {
131 u8 len;
132 u8 type;
133 u8 subtype;
134 u8 unitid;
135} __attribute__((packed)) tmComResDescrHeader_t;
136
137typedef struct {
138 u8 len;
139 u8 type;
140 u8 subtype;
141 u8 unitid;
142 u32 devicetype;
143 u16 deviceid;
144 u32 numgpiopins;
145 u8 numgpiogroups;
146 u8 controlsize;
147} __attribute__((packed)) tmComResExtDevDescrHeader_t;
148
149typedef struct {
150 u32 pin;
151 u8 state;
152} __attribute__((packed)) tmComResGPIO_t;
153
154typedef struct {
155 u8 len;
156 u8 type;
157 u8 subtype;
158 u8 pathid;
159} __attribute__((packed)) tmComResPathDescrHeader_t;
160
161/* terminaltype */
162typedef enum {
163 ITT_ANTENNA = 0x0203,
164 LINE_CONNECTOR = 0x0603,
165 SPDIF_CONNECTOR = 0x0605,
166 COMPOSITE_CONNECTOR = 0x0401,
167 SVIDEO_CONNECTOR = 0x0402,
168 COMPONENT_CONNECTOR = 0x0403,
169 STANDARD_DMA = 0xF101
170} tmComResTermType_t;
171
172typedef struct {
173 u8 len;
174 u8 type;
175 u8 subtype;
176 u8 terminalid;
177 u16 terminaltype;
178 u8 assocterminal;
179 u8 iterminal;
180 u8 controlsize;
181} __attribute__((packed)) tmComResAntTermDescrHeader_t;
182
183typedef struct {
184 u8 len;
185 u8 type;
186 u8 subtype;
187 u8 unitid;
188 u8 sourceid;
189 u8 iunit;
190 u32 tuningstandards;
191 u8 controlsize;
192 u32 controls;
193} __attribute__((packed)) tmComResTunerDescrHeader_t;
194
195typedef enum {
196 /* the buffer does not contain any valid data */
197 TM_BUFFER_FLAG_EMPTY,
198
199 /* the buffer is filled with valid data */
200 TM_BUFFER_FLAG_DONE,
201
202 /* the buffer is the dummy buffer - TODO??? */
203 TM_BUFFER_FLAG_DUMMY_BUFFER
204} tmBufferFlag_t;
205
206typedef struct {
207 u64 *pagetablevirt;
208 u64 pagetablephys;
209 u16 offset;
210 u8 *context;
211 u64 timestamp;
212 tmBufferFlag_t BufferFlag_t;
213 u32 lostbuffers;
214 u32 validbuffers;
215 u64 *dummypagevirt;
216 u64 dummypagephys;
217 u64 *addressvirt;
218} tmBuffer_t;
219
220typedef struct {
221 u32 bitspersample;
222 u32 samplesperline;
223 u32 numberoflines;
224 u32 pitch;
225 u32 linethreshold;
226 u64 **pagetablelistvirt;
227 u64 *pagetablelistphys;
228 u32 numpagetables;
229 u32 numpagetableentries;
230} tmHWStreamParameters_t;
231
232typedef struct {
233 tmHWStreamParameters_t HWStreamParameters_t;
234 u64 qwDummyPageTablePhys;
235 u64 *pDummyPageTableVirt;
236} tmStreamParameters_t;
237
238typedef struct {
239 u8 len;
240 u8 type;
241 u8 subtyle;
242 u8 unitid;
243 u16 terminaltype;
244 u8 assocterminal;
245 u8 sourceid;
246 u8 iterminal;
247 u32 BARLocation;
248 u8 flags;
249 u8 interruptid;
250 u8 buffercount;
251 u8 metadatasize;
252 u8 numformats;
253 u8 controlsize;
254} __attribute__((packed)) tmComResDMATermDescrHeader_t;
255
256/*
257 *
258 * Description:
259 * This is the transport stream format header.
260 *
261 * Settings:
262 * bLength - The size of this descriptor in bytes.
263 * bDescriptorType - CS_INTERFACE.
264 * bDescriptorSubtype - VS_FORMAT_MPEG2TS descriptor subtype.
265 * bFormatIndex - A non-zero constant that uniquely identifies the
266 * format.
267 * bDataOffset - Offset to TSP packet within MPEG-2 TS transport
268 * stride, in bytes.
269 * bPacketLength - Length of TSP packet, in bytes (typically 188).
270 * bStrideLength - Length of MPEG-2 TS transport stride.
271 * guidStrideFormat - A Globally Unique Identifier indicating the
272 * format of the stride data (if any). Set to zeros
273 * if there is no Stride Data, or if the Stride
274 * Data is to be ignored by the application.
275 *
276 */
277typedef struct {
278 u8 len;
279 u8 type;
280 u8 subtype;
281 u8 bFormatIndex;
282 u8 bDataOffset;
283 u8 bPacketLength;
284 u8 bStrideLength;
285 u8 guidStrideFormat[16];
286} __attribute__((packed)) tmComResTSFormatDescrHeader_t;
287
diff --git a/drivers/media/video/saa7164/saa7164.h b/drivers/media/video/saa7164/saa7164.h
new file mode 100644
index 000000000000..6753008a9c9b
--- /dev/null
+++ b/drivers/media/video/saa7164/saa7164.h
@@ -0,0 +1,400 @@
1/*
2 * Driver for the NXP SAA7164 PCIe bridge
3 *
4 * Copyright (c) 2009 Steven Toth <stoth@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22/*
23 Driver architecture
24 *******************
25
26 saa7164_core.c/buffer.c/cards.c/i2c.c/dvb.c
27 | : Standard Linux driver framework for creating
28 | : exposing and managing interfaces to the rest
29 | : of the kernel or userland. Also uses _fw.c to load
30 | : firmware direct into the PCIe bus, bypassing layers.
31 V
32 saa7164_api..() : Translate kernel specific functions/features
33 | : into command buffers.
34 V
35 saa7164_cmd..() : Manages the flow of command packets on/off,
36 | : the bus. Deal with bus errors, timeouts etc.
37 V
38 saa7164_bus..() : Manage a read/write memory ring buffer in the
39 | : PCIe Address space.
40 |
41 | saa7164_fw...() : Load any frimware
42 | | : direct into the device
43 V V
44 <- ----------------- PCIe address space -------------------- ->
45*/
46
47#include <linux/pci.h>
48#include <linux/i2c.h>
49#include <linux/i2c-algo-bit.h>
50#include <linux/kdev_t.h>
51
52#include <media/tuner.h>
53#include <media/tveeprom.h>
54#include <media/videobuf-dma-sg.h>
55#include <media/videobuf-dvb.h>
56
57#include "saa7164-reg.h"
58#include "saa7164-types.h"
59
60#include <linux/version.h>
61#include <linux/mutex.h>
62
63#define SAA7164_MAXBOARDS 8
64
65#define UNSET (-1U)
66#define SAA7164_BOARD_NOAUTO UNSET
67#define SAA7164_BOARD_UNKNOWN 0
68#define SAA7164_BOARD_UNKNOWN_REV2 1
69#define SAA7164_BOARD_UNKNOWN_REV3 2
70#define SAA7164_BOARD_HAUPPAUGE_HVR2250 3
71#define SAA7164_BOARD_HAUPPAUGE_HVR2200 4
72#define SAA7164_BOARD_HAUPPAUGE_HVR2200_2 5
73#define SAA7164_BOARD_HAUPPAUGE_HVR2200_3 6
74#define SAA7164_BOARD_HAUPPAUGE_HVR2250_2 7
75#define SAA7164_BOARD_HAUPPAUGE_HVR2250_3 8
76
77#define SAA7164_MAX_UNITS 8
78#define SAA7164_TS_NUMBER_OF_LINES 312
79#define SAA7164_PT_ENTRIES 16 /* (312 * 188) / 4096 */
80
81#define DBGLVL_FW 4
82#define DBGLVL_DVB 8
83#define DBGLVL_I2C 16
84#define DBGLVL_API 32
85#define DBGLVL_CMD 64
86#define DBGLVL_BUS 128
87#define DBGLVL_IRQ 256
88#define DBGLVL_BUF 512
89
90enum port_t {
91 SAA7164_MPEG_UNDEFINED = 0,
92 SAA7164_MPEG_DVB,
93};
94
95enum saa7164_i2c_bus_nr {
96 SAA7164_I2C_BUS_0 = 0,
97 SAA7164_I2C_BUS_1,
98 SAA7164_I2C_BUS_2,
99};
100
101enum saa7164_buffer_flags {
102 SAA7164_BUFFER_UNDEFINED = 0,
103 SAA7164_BUFFER_FREE,
104 SAA7164_BUFFER_BUSY,
105 SAA7164_BUFFER_FULL
106};
107
108enum saa7164_unit_type {
109 SAA7164_UNIT_UNDEFINED = 0,
110 SAA7164_UNIT_DIGITAL_DEMODULATOR,
111 SAA7164_UNIT_ANALOG_DEMODULATOR,
112 SAA7164_UNIT_TUNER,
113 SAA7164_UNIT_EEPROM,
114 SAA7164_UNIT_ZILOG_IRBLASTER,
115 SAA7164_UNIT_ENCODER,
116};
117
118/* The PCIe bridge doesn't grant direct access to i2c.
119 * Instead, you address i2c devices using a uniqely
120 * allocated 'unitid' value via a messaging API. This
121 * is a problem. The kernel and existing demod/tuner
122 * drivers expect to talk 'i2c', so we have to maintain
123 * a translation layer, and a series of functions to
124 * convert i2c bus + device address into a unit id.
125 */
126struct saa7164_unit {
127 enum saa7164_unit_type type;
128 u8 id;
129 char *name;
130 enum saa7164_i2c_bus_nr i2c_bus_nr;
131 u8 i2c_bus_addr;
132 u8 i2c_reg_len;
133};
134
135struct saa7164_board {
136 char *name;
137 enum port_t porta, portb;
138 enum {
139 SAA7164_CHIP_UNDEFINED = 0,
140 SAA7164_CHIP_REV2,
141 SAA7164_CHIP_REV3,
142 } chiprev;
143 struct saa7164_unit unit[SAA7164_MAX_UNITS];
144};
145
146struct saa7164_subid {
147 u16 subvendor;
148 u16 subdevice;
149 u32 card;
150};
151
152struct saa7164_fw_status {
153
154 /* RISC Core details */
155 u32 status;
156 u32 mode;
157 u32 spec;
158 u32 inst;
159 u32 cpuload;
160 u32 remainheap;
161
162 /* Firmware version */
163 u32 version;
164 u32 major;
165 u32 sub;
166 u32 rel;
167 u32 buildnr;
168};
169
170struct saa7164_dvb {
171 struct mutex lock;
172 struct dvb_adapter adapter;
173 struct dvb_frontend *frontend;
174 struct dvb_demux demux;
175 struct dmxdev dmxdev;
176 struct dmx_frontend fe_hw;
177 struct dmx_frontend fe_mem;
178 struct dvb_net net;
179 int feeding;
180};
181
182struct saa7164_i2c {
183 struct saa7164_dev *dev;
184
185 enum saa7164_i2c_bus_nr nr;
186
187 /* I2C I/O */
188 struct i2c_adapter i2c_adap;
189 struct i2c_algo_bit_data i2c_algo;
190 struct i2c_client i2c_client;
191 u32 i2c_rc;
192};
193
194struct saa7164_tsport;
195
196struct saa7164_buffer {
197 struct list_head list;
198
199 u32 nr;
200
201 struct saa7164_tsport *port;
202
203 /* Hardware Specific */
204 /* PCI Memory allocations */
205 enum saa7164_buffer_flags flags; /* Free, Busy, Full */
206
207 /* A block of page align PCI memory */
208 u32 pci_size; /* PCI allocation size in bytes */
209 u64 *cpu; /* Virtual address */
210 dma_addr_t dma; /* Physical address */
211
212 /* A page table that splits the block into a number of entries */
213 u32 pt_size; /* PCI allocation size in bytes */
214 u64 *pt_cpu; /* Virtual address */
215 dma_addr_t pt_dma; /* Physical address */
216};
217
218struct saa7164_tsport {
219
220 struct saa7164_dev *dev;
221 int nr;
222 enum port_t type;
223
224 struct saa7164_dvb dvb;
225
226 /* HW related stream parameters */
227 tmHWStreamParameters_t hw_streamingparams;
228
229 /* DMA configuration values, is seeded during initialization */
230 tmComResDMATermDescrHeader_t hwcfg;
231
232 /* hardware specific registers */
233 u32 bufcounter;
234 u32 pitch;
235 u32 bufsize;
236 u32 bufoffset;
237 u32 bufptr32l;
238 u32 bufptr32h;
239 u64 bufptr64;
240
241 u32 numpte; /* Number of entries in array, only valid in head */
242 struct mutex dmaqueue_lock;
243 struct mutex dummy_dmaqueue_lock;
244 struct saa7164_buffer dmaqueue;
245 struct saa7164_buffer dummy_dmaqueue;
246
247};
248
249struct saa7164_dev {
250 struct list_head devlist;
251 atomic_t refcount;
252
253 /* pci stuff */
254 struct pci_dev *pci;
255 unsigned char pci_rev, pci_lat;
256 int pci_bus, pci_slot;
257 u32 __iomem *lmmio;
258 u8 __iomem *bmmio;
259 u32 __iomem *lmmio2;
260 u8 __iomem *bmmio2;
261 int pci_irqmask;
262
263 /* board details */
264 int nr;
265 int hwrevision;
266 u32 board;
267 char name[32];
268
269 /* firmware status */
270 struct saa7164_fw_status fw_status;
271
272 tmComResHWDescr_t hwdesc;
273 tmComResInterfaceDescr_t intfdesc;
274 tmComResBusDescr_t busdesc;
275
276 tmComResBusInfo_t bus;
277
278 /* Interrupt status and ack registers */
279 u32 int_status;
280 u32 int_ack;
281
282 struct cmd cmds[SAA_CMD_MAX_MSG_UNITS];
283 struct mutex lock;
284
285 /* I2c related */
286 struct saa7164_i2c i2c_bus[3];
287
288 /* Transport related */
289 struct saa7164_tsport ts1, ts2;
290
291 /* Deferred command/api interrupts handling */
292 struct work_struct workcmd;
293
294};
295
296extern struct list_head saa7164_devlist;
297extern unsigned int waitsecs;
298
299/* ----------------------------------------------------------- */
300/* saa7164-core.c */
301void saa7164_dumpregs(struct saa7164_dev *dev, u32 addr);
302void saa7164_dumphex16(struct saa7164_dev *dev, u8 *buf, int len);
303void saa7164_getfirmwarestatus(struct saa7164_dev *dev);
304u32 saa7164_getcurrentfirmwareversion(struct saa7164_dev *dev);
305
306/* ----------------------------------------------------------- */
307/* saa7164-fw.c */
308int saa7164_downloadfirmware(struct saa7164_dev *dev);
309
310/* ----------------------------------------------------------- */
311/* saa7164-i2c.c */
312extern int saa7164_i2c_register(struct saa7164_i2c *bus);
313extern int saa7164_i2c_unregister(struct saa7164_i2c *bus);
314extern void saa7164_call_i2c_clients(struct saa7164_i2c *bus,
315 unsigned int cmd, void *arg);
316
317/* ----------------------------------------------------------- */
318/* saa7164-bus.c */
319int saa7164_bus_setup(struct saa7164_dev *dev);
320void saa7164_bus_dump(struct saa7164_dev *dev);
321int saa7164_bus_set(struct saa7164_dev *dev, tmComResInfo_t* msg, void *buf);
322int saa7164_bus_get(struct saa7164_dev *dev, tmComResInfo_t* msg,
323 void *buf, int peekonly);
324
325/* ----------------------------------------------------------- */
326/* saa7164-cmd.c */
327int saa7164_cmd_send(struct saa7164_dev *dev,
328 u8 id, tmComResCmd_t command, u16 controlselector,
329 u16 size, void *buf);
330void saa7164_cmd_signal(struct saa7164_dev *dev, u8 seqno);
331int saa7164_irq_dequeue(struct saa7164_dev *dev);
332
333/* ----------------------------------------------------------- */
334/* saa7164-api.c */
335int saa7164_api_get_fw_version(struct saa7164_dev *dev, u32 *version);
336int saa7164_api_enum_subdevs(struct saa7164_dev *dev);
337int saa7164_api_i2c_read(struct saa7164_i2c *bus, u8 addr, u32 reglen, u8 *reg,
338 u32 datalen, u8 *data);
339int saa7164_api_i2c_write(struct saa7164_i2c *bus, u8 addr,
340 u32 datalen, u8 *data);
341int saa7164_api_dif_write(struct saa7164_i2c *bus, u8 addr,
342 u32 datalen, u8 *data);
343int saa7164_api_read_eeprom(struct saa7164_dev *dev, u8 *buf, int buflen);
344int saa7164_api_set_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
345int saa7164_api_clear_gpiobit(struct saa7164_dev *dev, u8 unitid, u8 pin);
346int saa7164_api_transition_port(struct saa7164_tsport *port, u8 mode);
347
348/* ----------------------------------------------------------- */
349/* saa7164-cards.c */
350extern struct saa7164_board saa7164_boards[];
351extern const unsigned int saa7164_bcount;
352
353extern struct saa7164_subid saa7164_subids[];
354extern const unsigned int saa7164_idcount;
355
356extern void saa7164_card_list(struct saa7164_dev *dev);
357extern void saa7164_gpio_setup(struct saa7164_dev *dev);
358extern void saa7164_card_setup(struct saa7164_dev *dev);
359
360extern int saa7164_i2caddr_to_reglen(struct saa7164_i2c *bus, int addr);
361extern int saa7164_i2caddr_to_unitid(struct saa7164_i2c *bus, int addr);
362extern char *saa7164_unitid_name(struct saa7164_dev *dev, u8 unitid);
363
364/* ----------------------------------------------------------- */
365/* saa7164-dvb.c */
366extern int saa7164_dvb_register(struct saa7164_tsport *port);
367extern int saa7164_dvb_unregister(struct saa7164_tsport *port);
368
369/* ----------------------------------------------------------- */
370/* saa7164-buffer.c */
371extern struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_tsport *port,
372 u32 len);
373extern int saa7164_buffer_dealloc(struct saa7164_tsport *port,
374 struct saa7164_buffer *buf);
375
376/* ----------------------------------------------------------- */
377
378extern unsigned int debug;
379#define dprintk(level, fmt, arg...)\
380 do { if (debug & level)\
381 printk(KERN_DEBUG "%s: " fmt, dev->name, ## arg);\
382 } while (0)
383
384#define log_warn(fmt, arg...)\
385 do { \
386 printk(KERN_WARNING "%s: " fmt, dev->name, ## arg);\
387 } while (0)
388
389#define log_err(fmt, arg...)\
390 do { \
391 printk(KERN_ERROR "%s: " fmt, dev->name, ## arg);\
392 } while (0)
393
394#define saa7164_readl(reg) readl(dev->lmmio + ((reg) >> 2))
395#define saa7164_writel(reg, value) writel((value), dev->lmmio + ((reg) >> 2))
396
397
398#define saa7164_readb(reg) readl(dev->bmmio + (reg))
399#define saa7164_writeb(reg, value) writel((value), dev->bmmio + (reg))
400
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 61c47b824083..5ab7c5aefd62 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -74,6 +74,13 @@
74#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */ 74#define CDBYR2 0x98 /* Capture data bottom-field address Y register 2 */
75#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */ 75#define CDBCR2 0x9c /* Capture data bottom-field address C register 2 */
76 76
77#undef DEBUG_GEOMETRY
78#ifdef DEBUG_GEOMETRY
79#define dev_geo dev_info
80#else
81#define dev_geo dev_dbg
82#endif
83
77/* per video frame buffer */ 84/* per video frame buffer */
78struct sh_mobile_ceu_buffer { 85struct sh_mobile_ceu_buffer {
79 struct videobuf_buffer vb; /* v4l buffer must be first */ 86 struct videobuf_buffer vb; /* v4l buffer must be first */
@@ -92,10 +99,21 @@ struct sh_mobile_ceu_dev {
92 spinlock_t lock; 99 spinlock_t lock;
93 struct list_head capture; 100 struct list_head capture;
94 struct videobuf_buffer *active; 101 struct videobuf_buffer *active;
95 int is_interlaced;
96 102
97 struct sh_mobile_ceu_info *pdata; 103 struct sh_mobile_ceu_info *pdata;
98 104
105 u32 cflcr;
106
107 unsigned int is_interlaced:1;
108 unsigned int image_mode:1;
109 unsigned int is_16bit:1;
110};
111
112struct sh_mobile_ceu_cam {
113 struct v4l2_rect ceu_rect;
114 unsigned int cam_width;
115 unsigned int cam_height;
116 const struct soc_camera_data_format *extra_fmt;
99 const struct soc_camera_data_format *camera_fmt; 117 const struct soc_camera_data_format *camera_fmt;
100}; 118};
101 119
@@ -146,7 +164,8 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
146 struct sh_mobile_ceu_dev *pcdev = ici->priv; 164 struct sh_mobile_ceu_dev *pcdev = ici->priv;
147 int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3; 165 int bytes_per_pixel = (icd->current_fmt->depth + 7) >> 3;
148 166
149 *size = PAGE_ALIGN(icd->width * icd->height * bytes_per_pixel); 167 *size = PAGE_ALIGN(icd->user_width * icd->user_height *
168 bytes_per_pixel);
150 169
151 if (0 == *count) 170 if (0 == *count)
152 *count = 2; 171 *count = 2;
@@ -156,7 +175,7 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
156 (*count)--; 175 (*count)--;
157 } 176 }
158 177
159 dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size); 178 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size);
160 179
161 return 0; 180 return 0;
162} 181}
@@ -165,8 +184,9 @@ static void free_buffer(struct videobuf_queue *vq,
165 struct sh_mobile_ceu_buffer *buf) 184 struct sh_mobile_ceu_buffer *buf)
166{ 185{
167 struct soc_camera_device *icd = vq->priv_data; 186 struct soc_camera_device *icd = vq->priv_data;
187 struct device *dev = icd->dev.parent;
168 188
169 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 189 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
170 &buf->vb, buf->vb.baddr, buf->vb.bsize); 190 &buf->vb, buf->vb.baddr, buf->vb.bsize);
171 191
172 if (in_interrupt()) 192 if (in_interrupt())
@@ -174,7 +194,7 @@ static void free_buffer(struct videobuf_queue *vq,
174 194
175 videobuf_waiton(&buf->vb, 0, 0); 195 videobuf_waiton(&buf->vb, 0, 0);
176 videobuf_dma_contig_free(vq, &buf->vb); 196 videobuf_dma_contig_free(vq, &buf->vb);
177 dev_dbg(&icd->dev, "%s freed\n", __func__); 197 dev_dbg(dev, "%s freed\n", __func__);
178 buf->vb.state = VIDEOBUF_NEEDS_INIT; 198 buf->vb.state = VIDEOBUF_NEEDS_INIT;
179} 199}
180 200
@@ -205,7 +225,7 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
205 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 225 phys_addr_top = videobuf_to_dma_contig(pcdev->active);
206 ceu_write(pcdev, CDAYR, phys_addr_top); 226 ceu_write(pcdev, CDAYR, phys_addr_top);
207 if (pcdev->is_interlaced) { 227 if (pcdev->is_interlaced) {
208 phys_addr_bottom = phys_addr_top + icd->width; 228 phys_addr_bottom = phys_addr_top + icd->user_width;
209 ceu_write(pcdev, CDBYR, phys_addr_bottom); 229 ceu_write(pcdev, CDBYR, phys_addr_bottom);
210 } 230 }
211 231
@@ -214,10 +234,12 @@ static void sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
214 case V4L2_PIX_FMT_NV21: 234 case V4L2_PIX_FMT_NV21:
215 case V4L2_PIX_FMT_NV16: 235 case V4L2_PIX_FMT_NV16:
216 case V4L2_PIX_FMT_NV61: 236 case V4L2_PIX_FMT_NV61:
217 phys_addr_top += icd->width * icd->height; 237 phys_addr_top += icd->user_width *
238 icd->user_height;
218 ceu_write(pcdev, CDACR, phys_addr_top); 239 ceu_write(pcdev, CDACR, phys_addr_top);
219 if (pcdev->is_interlaced) { 240 if (pcdev->is_interlaced) {
220 phys_addr_bottom = phys_addr_top + icd->width; 241 phys_addr_bottom = phys_addr_top +
242 icd->user_width;
221 ceu_write(pcdev, CDBCR, phys_addr_bottom); 243 ceu_write(pcdev, CDBCR, phys_addr_bottom);
222 } 244 }
223 } 245 }
@@ -236,7 +258,7 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
236 258
237 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); 259 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb);
238 260
239 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 261 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
240 vb, vb->baddr, vb->bsize); 262 vb, vb->baddr, vb->bsize);
241 263
242 /* Added list head initialization on alloc */ 264 /* Added list head initialization on alloc */
@@ -251,12 +273,12 @@ static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq,
251 BUG_ON(NULL == icd->current_fmt); 273 BUG_ON(NULL == icd->current_fmt);
252 274
253 if (buf->fmt != icd->current_fmt || 275 if (buf->fmt != icd->current_fmt ||
254 vb->width != icd->width || 276 vb->width != icd->user_width ||
255 vb->height != icd->height || 277 vb->height != icd->user_height ||
256 vb->field != field) { 278 vb->field != field) {
257 buf->fmt = icd->current_fmt; 279 buf->fmt = icd->current_fmt;
258 vb->width = icd->width; 280 vb->width = icd->user_width;
259 vb->height = icd->height; 281 vb->height = icd->user_height;
260 vb->field = field; 282 vb->field = field;
261 vb->state = VIDEOBUF_NEEDS_INIT; 283 vb->state = VIDEOBUF_NEEDS_INIT;
262 } 284 }
@@ -289,7 +311,7 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
289 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 311 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
290 struct sh_mobile_ceu_dev *pcdev = ici->priv; 312 struct sh_mobile_ceu_dev *pcdev = ici->priv;
291 313
292 dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 314 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
293 vb, vb->baddr, vb->bsize); 315 vb, vb->baddr, vb->bsize);
294 316
295 vb->state = VIDEOBUF_QUEUED; 317 vb->state = VIDEOBUF_QUEUED;
@@ -304,6 +326,27 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
304static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, 326static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
305 struct videobuf_buffer *vb) 327 struct videobuf_buffer *vb)
306{ 328{
329 struct soc_camera_device *icd = vq->priv_data;
330 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
331 struct sh_mobile_ceu_dev *pcdev = ici->priv;
332 unsigned long flags;
333
334 spin_lock_irqsave(&pcdev->lock, flags);
335
336 if (pcdev->active == vb) {
337 /* disable capture (release DMA buffer), reset */
338 ceu_write(pcdev, CAPSR, 1 << 16);
339 pcdev->active = NULL;
340 }
341
342 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
343 !list_empty(&vb->queue)) {
344 vb->state = VIDEOBUF_ERROR;
345 list_del_init(&vb->queue);
346 }
347
348 spin_unlock_irqrestore(&pcdev->lock, flags);
349
307 free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); 350 free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb));
308} 351}
309 352
@@ -323,6 +366,10 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
323 spin_lock_irqsave(&pcdev->lock, flags); 366 spin_lock_irqsave(&pcdev->lock, flags);
324 367
325 vb = pcdev->active; 368 vb = pcdev->active;
369 if (!vb)
370 /* Stale interrupt from a released buffer */
371 goto out;
372
326 list_del_init(&vb->queue); 373 list_del_init(&vb->queue);
327 374
328 if (!list_empty(&pcdev->capture)) 375 if (!list_empty(&pcdev->capture))
@@ -337,6 +384,8 @@ static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
337 do_gettimeofday(&vb->ts); 384 do_gettimeofday(&vb->ts);
338 vb->field_count++; 385 vb->field_count++;
339 wake_up(&vb->done); 386 wake_up(&vb->done);
387
388out:
340 spin_unlock_irqrestore(&pcdev->lock, flags); 389 spin_unlock_irqrestore(&pcdev->lock, flags);
341 390
342 return IRQ_HANDLED; 391 return IRQ_HANDLED;
@@ -347,28 +396,23 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
347{ 396{
348 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 397 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
349 struct sh_mobile_ceu_dev *pcdev = ici->priv; 398 struct sh_mobile_ceu_dev *pcdev = ici->priv;
350 int ret = -EBUSY;
351 399
352 if (pcdev->icd) 400 if (pcdev->icd)
353 goto err; 401 return -EBUSY;
354 402
355 dev_info(&icd->dev, 403 dev_info(icd->dev.parent,
356 "SuperH Mobile CEU driver attached to camera %d\n", 404 "SuperH Mobile CEU driver attached to camera %d\n",
357 icd->devnum); 405 icd->devnum);
358 406
359 ret = icd->ops->init(icd); 407 clk_enable(pcdev->clk);
360 if (ret)
361 goto err;
362
363 pm_runtime_get_sync(ici->dev);
364 408
365 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ 409 ceu_write(pcdev, CAPSR, 1 << 16); /* reset */
366 while (ceu_read(pcdev, CSTSR) & 1) 410 while (ceu_read(pcdev, CSTSR) & 1)
367 msleep(1); 411 msleep(1);
368 412
369 pcdev->icd = icd; 413 pcdev->icd = icd;
370err: 414
371 return ret; 415 return 0;
372} 416}
373 417
374/* Called with .video_lock held */ 418/* Called with .video_lock held */
@@ -394,25 +438,151 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
394 } 438 }
395 spin_unlock_irqrestore(&pcdev->lock, flags); 439 spin_unlock_irqrestore(&pcdev->lock, flags);
396 440
397 pm_runtime_put_sync(ici->dev); 441 clk_disable(pcdev->clk);
398 442
399 icd->ops->release(icd); 443 dev_info(icd->dev.parent,
400
401 dev_info(&icd->dev,
402 "SuperH Mobile CEU driver detached from camera %d\n", 444 "SuperH Mobile CEU driver detached from camera %d\n",
403 icd->devnum); 445 icd->devnum);
404 446
405 pcdev->icd = NULL; 447 pcdev->icd = NULL;
406} 448}
407 449
450/*
451 * See chapter 29.4.12 "Capture Filter Control Register (CFLCR)"
452 * in SH7722 Hardware Manual
453 */
454static unsigned int size_dst(unsigned int src, unsigned int scale)
455{
456 unsigned int mant_pre = scale >> 12;
457 if (!src || !scale)
458 return src;
459 return ((mant_pre + 2 * (src - 1)) / (2 * mant_pre) - 1) *
460 mant_pre * 4096 / scale + 1;
461}
462
463static u16 calc_scale(unsigned int src, unsigned int *dst)
464{
465 u16 scale;
466
467 if (src == *dst)
468 return 0;
469
470 scale = (src * 4096 / *dst) & ~7;
471
472 while (scale > 4096 && size_dst(src, scale) < *dst)
473 scale -= 8;
474
475 *dst = size_dst(src, scale);
476
477 return scale;
478}
479
480/* rect is guaranteed to not exceed the scaled camera rectangle */
481static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd,
482 unsigned int out_width,
483 unsigned int out_height)
484{
485 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
486 struct sh_mobile_ceu_cam *cam = icd->host_priv;
487 struct v4l2_rect *rect = &cam->ceu_rect;
488 struct sh_mobile_ceu_dev *pcdev = ici->priv;
489 unsigned int height, width, cdwdr_width, in_width, in_height;
490 unsigned int left_offset, top_offset;
491 u32 camor;
492
493 dev_dbg(icd->dev.parent, "Crop %ux%u@%u:%u\n",
494 rect->width, rect->height, rect->left, rect->top);
495
496 left_offset = rect->left;
497 top_offset = rect->top;
498
499 if (pcdev->image_mode) {
500 in_width = rect->width;
501 if (!pcdev->is_16bit) {
502 in_width *= 2;
503 left_offset *= 2;
504 }
505 width = cdwdr_width = out_width;
506 } else {
507 unsigned int w_factor = (icd->current_fmt->depth + 7) >> 3;
508
509 width = out_width * w_factor / 2;
510
511 if (!pcdev->is_16bit)
512 w_factor *= 2;
513
514 in_width = rect->width * w_factor / 2;
515 left_offset = left_offset * w_factor / 2;
516
517 cdwdr_width = width * 2;
518 }
519
520 height = out_height;
521 in_height = rect->height;
522 if (pcdev->is_interlaced) {
523 height /= 2;
524 in_height /= 2;
525 top_offset /= 2;
526 cdwdr_width *= 2;
527 }
528
529 /* Set CAMOR, CAPWR, CFSZR, take care of CDWDR */
530 camor = left_offset | (top_offset << 16);
531
532 dev_geo(icd->dev.parent,
533 "CAMOR 0x%x, CAPWR 0x%x, CFSZR 0x%x, CDWDR 0x%x\n", camor,
534 (in_height << 16) | in_width, (height << 16) | width,
535 cdwdr_width);
536
537 ceu_write(pcdev, CAMOR, camor);
538 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
539 ceu_write(pcdev, CFSZR, (height << 16) | width);
540 ceu_write(pcdev, CDWDR, cdwdr_width);
541}
542
543static u32 capture_save_reset(struct sh_mobile_ceu_dev *pcdev)
544{
545 u32 capsr = ceu_read(pcdev, CAPSR);
546 ceu_write(pcdev, CAPSR, 1 << 16); /* reset, stop capture */
547 return capsr;
548}
549
550static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
551{
552 unsigned long timeout = jiffies + 10 * HZ;
553
554 /*
555 * Wait until the end of the current frame. It can take a long time,
556 * but if it has been aborted by a CAPSR reset, it shoule exit sooner.
557 */
558 while ((ceu_read(pcdev, CSTSR) & 1) && time_before(jiffies, timeout))
559 msleep(1);
560
561 if (time_after(jiffies, timeout)) {
562 dev_err(pcdev->ici.v4l2_dev.dev,
563 "Timeout waiting for frame end! Interface problem?\n");
564 return;
565 }
566
567 /* Wait until reset clears, this shall not hang... */
568 while (ceu_read(pcdev, CAPSR) & (1 << 16))
569 udelay(10);
570
571 /* Anything to restore? */
572 if (capsr & ~(1 << 16))
573 ceu_write(pcdev, CAPSR, capsr);
574}
575
408static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 576static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
409 __u32 pixfmt) 577 __u32 pixfmt)
410{ 578{
411 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 579 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
412 struct sh_mobile_ceu_dev *pcdev = ici->priv; 580 struct sh_mobile_ceu_dev *pcdev = ici->priv;
413 int ret, buswidth, width, height, cfszr_width, cdwdr_width; 581 int ret;
414 unsigned long camera_flags, common_flags, value; 582 unsigned long camera_flags, common_flags, value;
415 int yuv_mode, yuv_lineskip; 583 int yuv_lineskip;
584 struct sh_mobile_ceu_cam *cam = icd->host_priv;
585 u32 capsr = capture_save_reset(pcdev);
416 586
417 camera_flags = icd->ops->query_bus_param(icd); 587 camera_flags = icd->ops->query_bus_param(icd);
418 common_flags = soc_camera_bus_param_compatible(camera_flags, 588 common_flags = soc_camera_bus_param_compatible(camera_flags,
@@ -426,10 +596,10 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
426 596
427 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 597 switch (common_flags & SOCAM_DATAWIDTH_MASK) {
428 case SOCAM_DATAWIDTH_8: 598 case SOCAM_DATAWIDTH_8:
429 buswidth = 8; 599 pcdev->is_16bit = 0;
430 break; 600 break;
431 case SOCAM_DATAWIDTH_16: 601 case SOCAM_DATAWIDTH_16:
432 buswidth = 16; 602 pcdev->is_16bit = 1;
433 break; 603 break;
434 default: 604 default:
435 return -EINVAL; 605 return -EINVAL;
@@ -439,7 +609,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
439 ceu_write(pcdev, CRCMPR, 0); 609 ceu_write(pcdev, CRCMPR, 0);
440 610
441 value = 0x00000010; /* data fetch by default */ 611 value = 0x00000010; /* data fetch by default */
442 yuv_mode = yuv_lineskip = 0; 612 yuv_lineskip = 0;
443 613
444 switch (icd->current_fmt->fourcc) { 614 switch (icd->current_fmt->fourcc) {
445 case V4L2_PIX_FMT_NV12: 615 case V4L2_PIX_FMT_NV12:
@@ -448,8 +618,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
448 /* fall-through */ 618 /* fall-through */
449 case V4L2_PIX_FMT_NV16: 619 case V4L2_PIX_FMT_NV16:
450 case V4L2_PIX_FMT_NV61: 620 case V4L2_PIX_FMT_NV61:
451 yuv_mode = 1; 621 switch (cam->camera_fmt->fourcc) {
452 switch (pcdev->camera_fmt->fourcc) {
453 case V4L2_PIX_FMT_UYVY: 622 case V4L2_PIX_FMT_UYVY:
454 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */ 623 value = 0x00000000; /* Cb0, Y0, Cr0, Y1 */
455 break; 624 break;
@@ -473,36 +642,16 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
473 642
474 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; 643 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
475 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; 644 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
476 value |= buswidth == 16 ? 1 << 12 : 0; 645 value |= pcdev->is_16bit ? 1 << 12 : 0;
477 ceu_write(pcdev, CAMCR, value); 646 ceu_write(pcdev, CAMCR, value);
478 647
479 ceu_write(pcdev, CAPCR, 0x00300000); 648 ceu_write(pcdev, CAPCR, 0x00300000);
480 ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0); 649 ceu_write(pcdev, CAIFR, pcdev->is_interlaced ? 0x101 : 0);
481 650
651 sh_mobile_ceu_set_rect(icd, icd->user_width, icd->user_height);
482 mdelay(1); 652 mdelay(1);
483 653
484 if (yuv_mode) { 654 ceu_write(pcdev, CFLCR, pcdev->cflcr);
485 width = icd->width * 2;
486 width = buswidth == 16 ? width / 2 : width;
487 cfszr_width = cdwdr_width = icd->width;
488 } else {
489 width = icd->width * ((icd->current_fmt->depth + 7) >> 3);
490 width = buswidth == 16 ? width / 2 : width;
491 cfszr_width = buswidth == 8 ? width / 2 : width;
492 cdwdr_width = buswidth == 16 ? width * 2 : width;
493 }
494
495 height = icd->height;
496 if (pcdev->is_interlaced) {
497 height /= 2;
498 cdwdr_width *= 2;
499 }
500
501 ceu_write(pcdev, CAMOR, 0);
502 ceu_write(pcdev, CAPWR, (height << 16) | width);
503 ceu_write(pcdev, CFLCR, 0); /* no scaling */
504 ceu_write(pcdev, CFSZR, (height << 16) | cfszr_width);
505 ceu_write(pcdev, CLFCR, 0); /* no lowpass filter */
506 655
507 /* A few words about byte order (observed in Big Endian mode) 656 /* A few words about byte order (observed in Big Endian mode)
508 * 657 *
@@ -521,10 +670,15 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
521 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */ 670 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
522 671
523 ceu_write(pcdev, CDOCR, value); 672 ceu_write(pcdev, CDOCR, value);
524
525 ceu_write(pcdev, CDWDR, cdwdr_width);
526 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ 673 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
527 674
675 dev_dbg(icd->dev.parent, "S_FMT successful for %c%c%c%c %ux%u\n",
676 pixfmt & 0xff, (pixfmt >> 8) & 0xff,
677 (pixfmt >> 16) & 0xff, (pixfmt >> 24) & 0xff,
678 icd->user_width, icd->user_height);
679
680 capture_restore(pcdev, capsr);
681
528 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */ 682 /* not in bundle mode: skip CBDSR, CDAYR2, CDACR2, CDBYR2, CDBCR2 */
529 return 0; 683 return 0;
530} 684}
@@ -574,24 +728,35 @@ static const struct soc_camera_data_format sh_mobile_ceu_formats[] = {
574static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx, 728static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
575 struct soc_camera_format_xlate *xlate) 729 struct soc_camera_format_xlate *xlate)
576{ 730{
577 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 731 struct device *dev = icd->dev.parent;
578 int ret, k, n; 732 int ret, k, n;
579 int formats = 0; 733 int formats = 0;
734 struct sh_mobile_ceu_cam *cam;
580 735
581 ret = sh_mobile_ceu_try_bus_param(icd); 736 ret = sh_mobile_ceu_try_bus_param(icd);
582 if (ret < 0) 737 if (ret < 0)
583 return 0; 738 return 0;
584 739
740 if (!icd->host_priv) {
741 cam = kzalloc(sizeof(*cam), GFP_KERNEL);
742 if (!cam)
743 return -ENOMEM;
744
745 icd->host_priv = cam;
746 } else {
747 cam = icd->host_priv;
748 }
749
585 /* Beginning of a pass */ 750 /* Beginning of a pass */
586 if (!idx) 751 if (!idx)
587 icd->host_priv = NULL; 752 cam->extra_fmt = NULL;
588 753
589 switch (icd->formats[idx].fourcc) { 754 switch (icd->formats[idx].fourcc) {
590 case V4L2_PIX_FMT_UYVY: 755 case V4L2_PIX_FMT_UYVY:
591 case V4L2_PIX_FMT_VYUY: 756 case V4L2_PIX_FMT_VYUY:
592 case V4L2_PIX_FMT_YUYV: 757 case V4L2_PIX_FMT_YUYV:
593 case V4L2_PIX_FMT_YVYU: 758 case V4L2_PIX_FMT_YVYU:
594 if (icd->host_priv) 759 if (cam->extra_fmt)
595 goto add_single_format; 760 goto add_single_format;
596 761
597 /* 762 /*
@@ -603,7 +768,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
603 * the host_priv pointer and check whether the format you're 768 * the host_priv pointer and check whether the format you're
604 * going to add now is already there. 769 * going to add now is already there.
605 */ 770 */
606 icd->host_priv = (void *)sh_mobile_ceu_formats; 771 cam->extra_fmt = (void *)sh_mobile_ceu_formats;
607 772
608 n = ARRAY_SIZE(sh_mobile_ceu_formats); 773 n = ARRAY_SIZE(sh_mobile_ceu_formats);
609 formats += n; 774 formats += n;
@@ -612,7 +777,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, int idx,
612 xlate->cam_fmt = icd->formats + idx; 777 xlate->cam_fmt = icd->formats + idx;
613 xlate->buswidth = icd->formats[idx].depth; 778 xlate->buswidth = icd->formats[idx].depth;
614 xlate++; 779 xlate++;
615 dev_dbg(ici->dev, "Providing format %s using %s\n", 780 dev_dbg(dev, "Providing format %s using %s\n",
616 sh_mobile_ceu_formats[k].name, 781 sh_mobile_ceu_formats[k].name,
617 icd->formats[idx].name); 782 icd->formats[idx].name);
618 } 783 }
@@ -625,7 +790,7 @@ add_single_format:
625 xlate->cam_fmt = icd->formats + idx; 790 xlate->cam_fmt = icd->formats + idx;
626 xlate->buswidth = icd->formats[idx].depth; 791 xlate->buswidth = icd->formats[idx].depth;
627 xlate++; 792 xlate++;
628 dev_dbg(ici->dev, 793 dev_dbg(dev,
629 "Providing format %s in pass-through mode\n", 794 "Providing format %s in pass-through mode\n",
630 icd->formats[idx].name); 795 icd->formats[idx].name);
631 } 796 }
@@ -634,82 +799,714 @@ add_single_format:
634 return formats; 799 return formats;
635} 800}
636 801
802static void sh_mobile_ceu_put_formats(struct soc_camera_device *icd)
803{
804 kfree(icd->host_priv);
805 icd->host_priv = NULL;
806}
807
808/* Check if any dimension of r1 is smaller than respective one of r2 */
809static bool is_smaller(struct v4l2_rect *r1, struct v4l2_rect *r2)
810{
811 return r1->width < r2->width || r1->height < r2->height;
812}
813
814/* Check if r1 fails to cover r2 */
815static bool is_inside(struct v4l2_rect *r1, struct v4l2_rect *r2)
816{
817 return r1->left > r2->left || r1->top > r2->top ||
818 r1->left + r1->width < r2->left + r2->width ||
819 r1->top + r1->height < r2->top + r2->height;
820}
821
822static unsigned int scale_down(unsigned int size, unsigned int scale)
823{
824 return (size * 4096 + scale / 2) / scale;
825}
826
827static unsigned int scale_up(unsigned int size, unsigned int scale)
828{
829 return (size * scale + 2048) / 4096;
830}
831
832static unsigned int calc_generic_scale(unsigned int input, unsigned int output)
833{
834 return (input * 4096 + output / 2) / output;
835}
836
837static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect)
838{
839 struct v4l2_crop crop;
840 struct v4l2_cropcap cap;
841 int ret;
842
843 crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
844
845 ret = v4l2_subdev_call(sd, video, g_crop, &crop);
846 if (!ret) {
847 *rect = crop.c;
848 return ret;
849 }
850
851 /* Camera driver doesn't support .g_crop(), assume default rectangle */
852 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
853
854 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
855 if (ret < 0)
856 return ret;
857
858 *rect = cap.defrect;
859
860 return ret;
861}
862
863/*
864 * The common for both scaling and cropping iterative approach is:
865 * 1. try if the client can produce exactly what requested by the user
866 * 2. if (1) failed, try to double the client image until we get one big enough
867 * 3. if (2) failed, try to request the maximum image
868 */
869static int client_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *crop,
870 struct v4l2_crop *cam_crop)
871{
872 struct v4l2_rect *rect = &crop->c, *cam_rect = &cam_crop->c;
873 struct device *dev = sd->v4l2_dev->dev;
874 struct v4l2_cropcap cap;
875 int ret;
876 unsigned int width, height;
877
878 v4l2_subdev_call(sd, video, s_crop, crop);
879 ret = client_g_rect(sd, cam_rect);
880 if (ret < 0)
881 return ret;
882
883 /*
884 * Now cam_crop contains the current camera input rectangle, and it must
885 * be within camera cropcap bounds
886 */
887 if (!memcmp(rect, cam_rect, sizeof(*rect))) {
888 /* Even if camera S_CROP failed, but camera rectangle matches */
889 dev_dbg(dev, "Camera S_CROP successful for %ux%u@%u:%u\n",
890 rect->width, rect->height, rect->left, rect->top);
891 return 0;
892 }
893
894 /* Try to fix cropping, that camera hasn't managed to set */
895 dev_geo(dev, "Fix camera S_CROP for %ux%u@%u:%u to %ux%u@%u:%u\n",
896 cam_rect->width, cam_rect->height,
897 cam_rect->left, cam_rect->top,
898 rect->width, rect->height, rect->left, rect->top);
899
900 /* We need sensor maximum rectangle */
901 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
902 if (ret < 0)
903 return ret;
904
905 soc_camera_limit_side(&rect->left, &rect->width, cap.bounds.left, 2,
906 cap.bounds.width);
907 soc_camera_limit_side(&rect->top, &rect->height, cap.bounds.top, 4,
908 cap.bounds.height);
909
910 /*
911 * Popular special case - some cameras can only handle fixed sizes like
912 * QVGA, VGA,... Take care to avoid infinite loop.
913 */
914 width = max(cam_rect->width, 2);
915 height = max(cam_rect->height, 2);
916
917 while (!ret && (is_smaller(cam_rect, rect) ||
918 is_inside(cam_rect, rect)) &&
919 (cap.bounds.width > width || cap.bounds.height > height)) {
920
921 width *= 2;
922 height *= 2;
923
924 cam_rect->width = width;
925 cam_rect->height = height;
926
927 /*
928 * We do not know what capabilities the camera has to set up
929 * left and top borders. We could try to be smarter in iterating
930 * them, e.g., if camera current left is to the right of the
931 * target left, set it to the middle point between the current
932 * left and minimum left. But that would add too much
933 * complexity: we would have to iterate each border separately.
934 */
935 if (cam_rect->left > rect->left)
936 cam_rect->left = cap.bounds.left;
937
938 if (cam_rect->left + cam_rect->width < rect->left + rect->width)
939 cam_rect->width = rect->left + rect->width -
940 cam_rect->left;
941
942 if (cam_rect->top > rect->top)
943 cam_rect->top = cap.bounds.top;
944
945 if (cam_rect->top + cam_rect->height < rect->top + rect->height)
946 cam_rect->height = rect->top + rect->height -
947 cam_rect->top;
948
949 v4l2_subdev_call(sd, video, s_crop, cam_crop);
950 ret = client_g_rect(sd, cam_rect);
951 dev_geo(dev, "Camera S_CROP %d for %ux%u@%u:%u\n", ret,
952 cam_rect->width, cam_rect->height,
953 cam_rect->left, cam_rect->top);
954 }
955
956 /* S_CROP must not modify the rectangle */
957 if (is_smaller(cam_rect, rect) || is_inside(cam_rect, rect)) {
958 /*
959 * The camera failed to configure a suitable cropping,
960 * we cannot use the current rectangle, set to max
961 */
962 *cam_rect = cap.bounds;
963 v4l2_subdev_call(sd, video, s_crop, cam_crop);
964 ret = client_g_rect(sd, cam_rect);
965 dev_geo(dev, "Camera S_CROP %d for max %ux%u@%u:%u\n", ret,
966 cam_rect->width, cam_rect->height,
967 cam_rect->left, cam_rect->top);
968 }
969
970 return ret;
971}
972
973static int get_camera_scales(struct v4l2_subdev *sd, struct v4l2_rect *rect,
974 unsigned int *scale_h, unsigned int *scale_v)
975{
976 struct v4l2_format f;
977 int ret;
978
979 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
980
981 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
982 if (ret < 0)
983 return ret;
984
985 *scale_h = calc_generic_scale(rect->width, f.fmt.pix.width);
986 *scale_v = calc_generic_scale(rect->height, f.fmt.pix.height);
987
988 return 0;
989}
990
991static int get_camera_subwin(struct soc_camera_device *icd,
992 struct v4l2_rect *cam_subrect,
993 unsigned int cam_hscale, unsigned int cam_vscale)
994{
995 struct sh_mobile_ceu_cam *cam = icd->host_priv;
996 struct v4l2_rect *ceu_rect = &cam->ceu_rect;
997
998 if (!ceu_rect->width) {
999 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1000 struct device *dev = icd->dev.parent;
1001 struct v4l2_format f;
1002 struct v4l2_pix_format *pix = &f.fmt.pix;
1003 int ret;
1004 /* First time */
1005
1006 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1007
1008 ret = v4l2_subdev_call(sd, video, g_fmt, &f);
1009 if (ret < 0)
1010 return ret;
1011
1012 dev_geo(dev, "camera fmt %ux%u\n", pix->width, pix->height);
1013
1014 if (pix->width > 2560) {
1015 ceu_rect->width = 2560;
1016 ceu_rect->left = (pix->width - 2560) / 2;
1017 } else {
1018 ceu_rect->width = pix->width;
1019 ceu_rect->left = 0;
1020 }
1021
1022 if (pix->height > 1920) {
1023 ceu_rect->height = 1920;
1024 ceu_rect->top = (pix->height - 1920) / 2;
1025 } else {
1026 ceu_rect->height = pix->height;
1027 ceu_rect->top = 0;
1028 }
1029
1030 dev_geo(dev, "initialised CEU rect %ux%u@%u:%u\n",
1031 ceu_rect->width, ceu_rect->height,
1032 ceu_rect->left, ceu_rect->top);
1033 }
1034
1035 cam_subrect->width = scale_up(ceu_rect->width, cam_hscale);
1036 cam_subrect->left = scale_up(ceu_rect->left, cam_hscale);
1037 cam_subrect->height = scale_up(ceu_rect->height, cam_vscale);
1038 cam_subrect->top = scale_up(ceu_rect->top, cam_vscale);
1039
1040 return 0;
1041}
1042
1043static int client_s_fmt(struct soc_camera_device *icd, struct v4l2_format *f,
1044 bool ceu_can_scale)
1045{
1046 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1047 struct device *dev = icd->dev.parent;
1048 struct v4l2_pix_format *pix = &f->fmt.pix;
1049 unsigned int width = pix->width, height = pix->height, tmp_w, tmp_h;
1050 unsigned int max_width, max_height;
1051 struct v4l2_cropcap cap;
1052 int ret;
1053
1054 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1055
1056 ret = v4l2_subdev_call(sd, video, cropcap, &cap);
1057 if (ret < 0)
1058 return ret;
1059
1060 max_width = min(cap.bounds.width, 2560);
1061 max_height = min(cap.bounds.height, 1920);
1062
1063 ret = v4l2_subdev_call(sd, video, s_fmt, f);
1064 if (ret < 0)
1065 return ret;
1066
1067 dev_geo(dev, "camera scaled to %ux%u\n", pix->width, pix->height);
1068
1069 if ((width == pix->width && height == pix->height) || !ceu_can_scale)
1070 return 0;
1071
1072 /* Camera set a format, but geometry is not precise, try to improve */
1073 tmp_w = pix->width;
1074 tmp_h = pix->height;
1075
1076 /* width <= max_width && height <= max_height - guaranteed by try_fmt */
1077 while ((width > tmp_w || height > tmp_h) &&
1078 tmp_w < max_width && tmp_h < max_height) {
1079 tmp_w = min(2 * tmp_w, max_width);
1080 tmp_h = min(2 * tmp_h, max_height);
1081 pix->width = tmp_w;
1082 pix->height = tmp_h;
1083 ret = v4l2_subdev_call(sd, video, s_fmt, f);
1084 dev_geo(dev, "Camera scaled to %ux%u\n",
1085 pix->width, pix->height);
1086 if (ret < 0) {
1087 /* This shouldn't happen */
1088 dev_err(dev, "Client failed to set format: %d\n", ret);
1089 return ret;
1090 }
1091 }
1092
1093 return 0;
1094}
1095
1096/**
1097 * @rect - camera cropped rectangle
1098 * @sub_rect - CEU cropped rectangle, mapped back to camera input area
1099 * @ceu_rect - on output calculated CEU crop rectangle
1100 */
1101static int client_scale(struct soc_camera_device *icd, struct v4l2_rect *rect,
1102 struct v4l2_rect *sub_rect, struct v4l2_rect *ceu_rect,
1103 struct v4l2_format *f, bool ceu_can_scale)
1104{
1105 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1106 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1107 struct device *dev = icd->dev.parent;
1108 struct v4l2_format f_tmp = *f;
1109 struct v4l2_pix_format *pix_tmp = &f_tmp.fmt.pix;
1110 unsigned int scale_h, scale_v;
1111 int ret;
1112
1113 /* 5. Apply iterative camera S_FMT for camera user window. */
1114 ret = client_s_fmt(icd, &f_tmp, ceu_can_scale);
1115 if (ret < 0)
1116 return ret;
1117
1118 dev_geo(dev, "5: camera scaled to %ux%u\n",
1119 pix_tmp->width, pix_tmp->height);
1120
1121 /* 6. Retrieve camera output window (g_fmt) */
1122
1123 /* unneeded - it is already in "f_tmp" */
1124
1125 /* 7. Calculate new camera scales. */
1126 ret = get_camera_scales(sd, rect, &scale_h, &scale_v);
1127 if (ret < 0)
1128 return ret;
1129
1130 dev_geo(dev, "7: camera scales %u:%u\n", scale_h, scale_v);
1131
1132 cam->cam_width = pix_tmp->width;
1133 cam->cam_height = pix_tmp->height;
1134 f->fmt.pix.width = pix_tmp->width;
1135 f->fmt.pix.height = pix_tmp->height;
1136
1137 /*
1138 * 8. Calculate new CEU crop - apply camera scales to previously
1139 * calculated "effective" crop.
1140 */
1141 ceu_rect->left = scale_down(sub_rect->left, scale_h);
1142 ceu_rect->width = scale_down(sub_rect->width, scale_h);
1143 ceu_rect->top = scale_down(sub_rect->top, scale_v);
1144 ceu_rect->height = scale_down(sub_rect->height, scale_v);
1145
1146 dev_geo(dev, "8: new CEU rect %ux%u@%u:%u\n",
1147 ceu_rect->width, ceu_rect->height,
1148 ceu_rect->left, ceu_rect->top);
1149
1150 return 0;
1151}
1152
1153/* Get combined scales */
1154static int get_scales(struct soc_camera_device *icd,
1155 unsigned int *scale_h, unsigned int *scale_v)
1156{
1157 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1158 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1159 struct v4l2_crop cam_crop;
1160 unsigned int width_in, height_in;
1161 int ret;
1162
1163 cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1164
1165 ret = client_g_rect(sd, &cam_crop.c);
1166 if (ret < 0)
1167 return ret;
1168
1169 ret = get_camera_scales(sd, &cam_crop.c, scale_h, scale_v);
1170 if (ret < 0)
1171 return ret;
1172
1173 width_in = scale_up(cam->ceu_rect.width, *scale_h);
1174 height_in = scale_up(cam->ceu_rect.height, *scale_v);
1175
1176 *scale_h = calc_generic_scale(cam->ceu_rect.width, icd->user_width);
1177 *scale_v = calc_generic_scale(cam->ceu_rect.height, icd->user_height);
1178
1179 return 0;
1180}
1181
1182/*
1183 * CEU can scale and crop, but we don't want to waste bandwidth and kill the
1184 * framerate by always requesting the maximum image from the client. See
1185 * Documentation/video4linux/sh_mobile_camera_ceu.txt for a description of
1186 * scaling and cropping algorithms and for the meaning of referenced here steps.
1187 */
637static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd, 1188static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
638 struct v4l2_rect *rect) 1189 struct v4l2_crop *a)
639{ 1190{
640 return icd->ops->set_crop(icd, rect); 1191 struct v4l2_rect *rect = &a->c;
1192 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1193 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1194 struct v4l2_crop cam_crop;
1195 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1196 struct v4l2_rect *cam_rect = &cam_crop.c, *ceu_rect = &cam->ceu_rect;
1197 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1198 struct device *dev = icd->dev.parent;
1199 struct v4l2_format f;
1200 struct v4l2_pix_format *pix = &f.fmt.pix;
1201 unsigned int scale_comb_h, scale_comb_v, scale_ceu_h, scale_ceu_v,
1202 out_width, out_height;
1203 u32 capsr, cflcr;
1204 int ret;
1205
1206 /* 1. Calculate current combined scales. */
1207 ret = get_scales(icd, &scale_comb_h, &scale_comb_v);
1208 if (ret < 0)
1209 return ret;
1210
1211 dev_geo(dev, "1: combined scales %u:%u\n", scale_comb_h, scale_comb_v);
1212
1213 /* 2. Apply iterative camera S_CROP for new input window. */
1214 ret = client_s_crop(sd, a, &cam_crop);
1215 if (ret < 0)
1216 return ret;
1217
1218 dev_geo(dev, "2: camera cropped to %ux%u@%u:%u\n",
1219 cam_rect->width, cam_rect->height,
1220 cam_rect->left, cam_rect->top);
1221
1222 /* On success cam_crop contains current camera crop */
1223
1224 /*
1225 * 3. If old combined scales applied to new crop produce an impossible
1226 * user window, adjust scales to produce nearest possible window.
1227 */
1228 out_width = scale_down(rect->width, scale_comb_h);
1229 out_height = scale_down(rect->height, scale_comb_v);
1230
1231 if (out_width > 2560)
1232 out_width = 2560;
1233 else if (out_width < 2)
1234 out_width = 2;
1235
1236 if (out_height > 1920)
1237 out_height = 1920;
1238 else if (out_height < 4)
1239 out_height = 4;
1240
1241 dev_geo(dev, "3: Adjusted output %ux%u\n", out_width, out_height);
1242
1243 /* 4. Use G_CROP to retrieve actual input window: already in cam_crop */
1244
1245 /*
1246 * 5. Using actual input window and calculated combined scales calculate
1247 * camera target output window.
1248 */
1249 pix->width = scale_down(cam_rect->width, scale_comb_h);
1250 pix->height = scale_down(cam_rect->height, scale_comb_v);
1251
1252 dev_geo(dev, "5: camera target %ux%u\n", pix->width, pix->height);
1253
1254 /* 6. - 9. */
1255 pix->pixelformat = cam->camera_fmt->fourcc;
1256 pix->colorspace = cam->camera_fmt->colorspace;
1257
1258 capsr = capture_save_reset(pcdev);
1259 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1260
1261 /* Make relative to camera rectangle */
1262 rect->left -= cam_rect->left;
1263 rect->top -= cam_rect->top;
1264
1265 f.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1266
1267 ret = client_scale(icd, cam_rect, rect, ceu_rect, &f,
1268 pcdev->image_mode && !pcdev->is_interlaced);
1269
1270 dev_geo(dev, "6-9: %d\n", ret);
1271
1272 /* 10. Use CEU cropping to crop to the new window. */
1273 sh_mobile_ceu_set_rect(icd, out_width, out_height);
1274
1275 dev_geo(dev, "10: CEU cropped to %ux%u@%u:%u\n",
1276 ceu_rect->width, ceu_rect->height,
1277 ceu_rect->left, ceu_rect->top);
1278
1279 /*
1280 * 11. Calculate CEU scales from camera scales from results of (10) and
1281 * user window from (3)
1282 */
1283 scale_ceu_h = calc_scale(ceu_rect->width, &out_width);
1284 scale_ceu_v = calc_scale(ceu_rect->height, &out_height);
1285
1286 dev_geo(dev, "11: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
1287
1288 /* 12. Apply CEU scales. */
1289 cflcr = scale_ceu_h | (scale_ceu_v << 16);
1290 if (cflcr != pcdev->cflcr) {
1291 pcdev->cflcr = cflcr;
1292 ceu_write(pcdev, CFLCR, cflcr);
1293 }
1294
1295 /* Restore capture */
1296 if (pcdev->active)
1297 capsr |= 1;
1298 capture_restore(pcdev, capsr);
1299
1300 icd->user_width = out_width;
1301 icd->user_height = out_height;
1302
1303 /* Even if only camera cropping succeeded */
1304 return ret;
641} 1305}
642 1306
1307/* Similar to set_crop multistage iterative algorithm */
643static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd, 1308static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
644 struct v4l2_format *f) 1309 struct v4l2_format *f)
645{ 1310{
646 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1311 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
647 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1312 struct sh_mobile_ceu_dev *pcdev = ici->priv;
648 __u32 pixfmt = f->fmt.pix.pixelformat; 1313 struct sh_mobile_ceu_cam *cam = icd->host_priv;
649 const struct soc_camera_format_xlate *xlate; 1314 struct v4l2_pix_format *pix = &f->fmt.pix;
650 struct v4l2_format cam_f = *f; 1315 struct v4l2_format cam_f = *f;
1316 struct v4l2_pix_format *cam_pix = &cam_f.fmt.pix;
1317 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1318 struct device *dev = icd->dev.parent;
1319 __u32 pixfmt = pix->pixelformat;
1320 const struct soc_camera_format_xlate *xlate;
1321 struct v4l2_crop cam_crop;
1322 struct v4l2_rect *cam_rect = &cam_crop.c, cam_subrect, ceu_rect;
1323 unsigned int scale_cam_h, scale_cam_v;
1324 u16 scale_v, scale_h;
651 int ret; 1325 int ret;
1326 bool is_interlaced, image_mode;
1327
1328 switch (pix->field) {
1329 case V4L2_FIELD_INTERLACED:
1330 is_interlaced = true;
1331 break;
1332 case V4L2_FIELD_ANY:
1333 default:
1334 pix->field = V4L2_FIELD_NONE;
1335 /* fall-through */
1336 case V4L2_FIELD_NONE:
1337 is_interlaced = false;
1338 break;
1339 }
652 1340
653 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1341 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
654 if (!xlate) { 1342 if (!xlate) {
655 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 1343 dev_warn(dev, "Format %x not found\n", pixfmt);
656 return -EINVAL; 1344 return -EINVAL;
657 } 1345 }
658 1346
659 cam_f.fmt.pix.pixelformat = xlate->cam_fmt->fourcc; 1347 /* 1. Calculate current camera scales. */
660 ret = icd->ops->set_fmt(icd, &cam_f); 1348 cam_crop.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
661 1349
662 if (!ret) { 1350 ret = client_g_rect(sd, cam_rect);
663 icd->buswidth = xlate->buswidth; 1351 if (ret < 0)
664 icd->current_fmt = xlate->host_fmt; 1352 return ret;
665 pcdev->camera_fmt = xlate->cam_fmt; 1353
1354 ret = get_camera_scales(sd, cam_rect, &scale_cam_h, &scale_cam_v);
1355 if (ret < 0)
1356 return ret;
1357
1358 dev_geo(dev, "1: camera scales %u:%u\n", scale_cam_h, scale_cam_v);
1359
1360 /*
1361 * 2. Calculate "effective" input crop (sensor subwindow) - CEU crop
1362 * scaled back at current camera scales onto input window.
1363 */
1364 ret = get_camera_subwin(icd, &cam_subrect, scale_cam_h, scale_cam_v);
1365 if (ret < 0)
1366 return ret;
1367
1368 dev_geo(dev, "2: subwin %ux%u@%u:%u\n",
1369 cam_subrect.width, cam_subrect.height,
1370 cam_subrect.left, cam_subrect.top);
1371
1372 /*
1373 * 3. Calculate new combined scales from "effective" input window to
1374 * requested user window.
1375 */
1376 scale_h = calc_generic_scale(cam_subrect.width, pix->width);
1377 scale_v = calc_generic_scale(cam_subrect.height, pix->height);
1378
1379 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1380
1381 /*
1382 * 4. Calculate camera output window by applying combined scales to real
1383 * input window.
1384 */
1385 cam_pix->width = scale_down(cam_rect->width, scale_h);
1386 cam_pix->height = scale_down(cam_rect->height, scale_v);
1387 cam_pix->pixelformat = xlate->cam_fmt->fourcc;
1388
1389 switch (pixfmt) {
1390 case V4L2_PIX_FMT_NV12:
1391 case V4L2_PIX_FMT_NV21:
1392 case V4L2_PIX_FMT_NV16:
1393 case V4L2_PIX_FMT_NV61:
1394 image_mode = true;
1395 break;
1396 default:
1397 image_mode = false;
666 } 1398 }
667 1399
668 return ret; 1400 dev_geo(dev, "4: camera output %ux%u\n",
1401 cam_pix->width, cam_pix->height);
1402
1403 /* 5. - 9. */
1404 ret = client_scale(icd, cam_rect, &cam_subrect, &ceu_rect, &cam_f,
1405 image_mode && !is_interlaced);
1406
1407 dev_geo(dev, "5-9: client scale %d\n", ret);
1408
1409 /* Done with the camera. Now see if we can improve the result */
1410
1411 dev_dbg(dev, "Camera %d fmt %ux%u, requested %ux%u\n",
1412 ret, cam_pix->width, cam_pix->height, pix->width, pix->height);
1413 if (ret < 0)
1414 return ret;
1415
1416 /* 10. Use CEU scaling to scale to the requested user window. */
1417
1418 /* We cannot scale up */
1419 if (pix->width > cam_pix->width)
1420 pix->width = cam_pix->width;
1421 if (pix->width > ceu_rect.width)
1422 pix->width = ceu_rect.width;
1423
1424 if (pix->height > cam_pix->height)
1425 pix->height = cam_pix->height;
1426 if (pix->height > ceu_rect.height)
1427 pix->height = ceu_rect.height;
1428
1429 /* Let's rock: scale pix->{width x height} down to width x height */
1430 scale_h = calc_scale(ceu_rect.width, &pix->width);
1431 scale_v = calc_scale(ceu_rect.height, &pix->height);
1432
1433 dev_geo(dev, "10: W: %u : 0x%x = %u, H: %u : 0x%x = %u\n",
1434 ceu_rect.width, scale_h, pix->width,
1435 ceu_rect.height, scale_v, pix->height);
1436
1437 pcdev->cflcr = scale_h | (scale_v << 16);
1438
1439 icd->buswidth = xlate->buswidth;
1440 icd->current_fmt = xlate->host_fmt;
1441 cam->camera_fmt = xlate->cam_fmt;
1442 cam->ceu_rect = ceu_rect;
1443
1444 pcdev->is_interlaced = is_interlaced;
1445 pcdev->image_mode = image_mode;
1446
1447 return 0;
669} 1448}
670 1449
671static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, 1450static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
672 struct v4l2_format *f) 1451 struct v4l2_format *f)
673{ 1452{
674 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
675 struct sh_mobile_ceu_dev *pcdev = ici->priv;
676 const struct soc_camera_format_xlate *xlate; 1453 const struct soc_camera_format_xlate *xlate;
677 __u32 pixfmt = f->fmt.pix.pixelformat; 1454 struct v4l2_pix_format *pix = &f->fmt.pix;
1455 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1456 __u32 pixfmt = pix->pixelformat;
1457 int width, height;
678 int ret; 1458 int ret;
679 1459
680 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1460 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
681 if (!xlate) { 1461 if (!xlate) {
682 dev_warn(ici->dev, "Format %x not found\n", pixfmt); 1462 dev_warn(icd->dev.parent, "Format %x not found\n", pixfmt);
683 return -EINVAL; 1463 return -EINVAL;
684 } 1464 }
685 1465
686 /* FIXME: calculate using depth and bus width */ 1466 /* FIXME: calculate using depth and bus width */
687 1467
688 v4l_bound_align_image(&f->fmt.pix.width, 2, 2560, 1, 1468 v4l_bound_align_image(&pix->width, 2, 2560, 1,
689 &f->fmt.pix.height, 4, 1920, 2, 0); 1469 &pix->height, 4, 1920, 2, 0);
1470
1471 width = pix->width;
1472 height = pix->height;
690 1473
691 f->fmt.pix.bytesperline = f->fmt.pix.width * 1474 pix->bytesperline = pix->width *
692 DIV_ROUND_UP(xlate->host_fmt->depth, 8); 1475 DIV_ROUND_UP(xlate->host_fmt->depth, 8);
693 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline; 1476 pix->sizeimage = pix->height * pix->bytesperline;
1477
1478 pix->pixelformat = xlate->cam_fmt->fourcc;
694 1479
695 /* limit to sensor capabilities */ 1480 /* limit to sensor capabilities */
696 ret = icd->ops->try_fmt(icd, f); 1481 ret = v4l2_subdev_call(sd, video, try_fmt, f);
1482 pix->pixelformat = pixfmt;
697 if (ret < 0) 1483 if (ret < 0)
698 return ret; 1484 return ret;
699 1485
700 switch (f->fmt.pix.field) { 1486 switch (pixfmt) {
701 case V4L2_FIELD_INTERLACED: 1487 case V4L2_PIX_FMT_NV12:
702 pcdev->is_interlaced = 1; 1488 case V4L2_PIX_FMT_NV21:
703 break; 1489 case V4L2_PIX_FMT_NV16:
704 case V4L2_FIELD_ANY: 1490 case V4L2_PIX_FMT_NV61:
705 f->fmt.pix.field = V4L2_FIELD_NONE; 1491 /* FIXME: check against rect_max after converting soc-camera */
706 /* fall-through */ 1492 /* We can scale precisely, need a bigger image from camera */
707 case V4L2_FIELD_NONE: 1493 if (pix->width < width || pix->height < height) {
708 pcdev->is_interlaced = 0; 1494 int tmp_w = pix->width, tmp_h = pix->height;
709 break; 1495 pix->width = 2560;
710 default: 1496 pix->height = 1920;
711 ret = -EINVAL; 1497 ret = v4l2_subdev_call(sd, video, try_fmt, f);
712 break; 1498 if (ret < 0) {
1499 /* Shouldn't actually happen... */
1500 dev_err(icd->dev.parent,
1501 "FIXME: try_fmt() returned %d\n", ret);
1502 pix->width = tmp_w;
1503 pix->height = tmp_h;
1504 }
1505 }
1506 if (pix->width > width)
1507 pix->width = width;
1508 if (pix->height > height)
1509 pix->height = height;
713 } 1510 }
714 1511
715 return ret; 1512 return ret;
@@ -769,7 +1566,7 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
769 1566
770 videobuf_queue_dma_contig_init(q, 1567 videobuf_queue_dma_contig_init(q,
771 &sh_mobile_ceu_videobuf_ops, 1568 &sh_mobile_ceu_videobuf_ops,
772 ici->dev, &pcdev->lock, 1569 icd->dev.parent, &pcdev->lock,
773 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1570 V4L2_BUF_TYPE_VIDEO_CAPTURE,
774 pcdev->is_interlaced ? 1571 pcdev->is_interlaced ?
775 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE, 1572 V4L2_FIELD_INTERLACED : V4L2_FIELD_NONE,
@@ -777,22 +1574,76 @@ static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q,
777 icd); 1574 icd);
778} 1575}
779 1576
1577static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1578 struct v4l2_control *ctrl)
1579{
1580 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1581 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1582 u32 val;
1583
1584 switch (ctrl->id) {
1585 case V4L2_CID_SHARPNESS:
1586 val = ceu_read(pcdev, CLFCR);
1587 ctrl->value = val ^ 1;
1588 return 0;
1589 }
1590 return -ENOIOCTLCMD;
1591}
1592
1593static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
1594 struct v4l2_control *ctrl)
1595{
1596 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1597 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1598
1599 switch (ctrl->id) {
1600 case V4L2_CID_SHARPNESS:
1601 switch (icd->current_fmt->fourcc) {
1602 case V4L2_PIX_FMT_NV12:
1603 case V4L2_PIX_FMT_NV21:
1604 case V4L2_PIX_FMT_NV16:
1605 case V4L2_PIX_FMT_NV61:
1606 ceu_write(pcdev, CLFCR, !ctrl->value);
1607 return 0;
1608 }
1609 return -EINVAL;
1610 }
1611 return -ENOIOCTLCMD;
1612}
1613
1614static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
1615 {
1616 .id = V4L2_CID_SHARPNESS,
1617 .type = V4L2_CTRL_TYPE_BOOLEAN,
1618 .name = "Low-pass filter",
1619 .minimum = 0,
1620 .maximum = 1,
1621 .step = 1,
1622 .default_value = 0,
1623 },
1624};
1625
780static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { 1626static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
781 .owner = THIS_MODULE, 1627 .owner = THIS_MODULE,
782 .add = sh_mobile_ceu_add_device, 1628 .add = sh_mobile_ceu_add_device,
783 .remove = sh_mobile_ceu_remove_device, 1629 .remove = sh_mobile_ceu_remove_device,
784 .get_formats = sh_mobile_ceu_get_formats, 1630 .get_formats = sh_mobile_ceu_get_formats,
1631 .put_formats = sh_mobile_ceu_put_formats,
785 .set_crop = sh_mobile_ceu_set_crop, 1632 .set_crop = sh_mobile_ceu_set_crop,
786 .set_fmt = sh_mobile_ceu_set_fmt, 1633 .set_fmt = sh_mobile_ceu_set_fmt,
787 .try_fmt = sh_mobile_ceu_try_fmt, 1634 .try_fmt = sh_mobile_ceu_try_fmt,
1635 .set_ctrl = sh_mobile_ceu_set_ctrl,
1636 .get_ctrl = sh_mobile_ceu_get_ctrl,
788 .reqbufs = sh_mobile_ceu_reqbufs, 1637 .reqbufs = sh_mobile_ceu_reqbufs,
789 .poll = sh_mobile_ceu_poll, 1638 .poll = sh_mobile_ceu_poll,
790 .querycap = sh_mobile_ceu_querycap, 1639 .querycap = sh_mobile_ceu_querycap,
791 .set_bus_param = sh_mobile_ceu_set_bus_param, 1640 .set_bus_param = sh_mobile_ceu_set_bus_param,
792 .init_videobuf = sh_mobile_ceu_init_videobuf, 1641 .init_videobuf = sh_mobile_ceu_init_videobuf,
1642 .controls = sh_mobile_ceu_controls,
1643 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls),
793}; 1644};
794 1645
795static int sh_mobile_ceu_probe(struct platform_device *pdev) 1646static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
796{ 1647{
797 struct sh_mobile_ceu_dev *pcdev; 1648 struct sh_mobile_ceu_dev *pcdev;
798 struct resource *res; 1649 struct resource *res;
@@ -865,7 +1716,7 @@ static int sh_mobile_ceu_probe(struct platform_device *pdev)
865 pm_runtime_resume(&pdev->dev); 1716 pm_runtime_resume(&pdev->dev);
866 1717
867 pcdev->ici.priv = pcdev; 1718 pcdev->ici.priv = pcdev;
868 pcdev->ici.dev = &pdev->dev; 1719 pcdev->ici.v4l2_dev.dev = &pdev->dev;
869 pcdev->ici.nr = pdev->id; 1720 pcdev->ici.nr = pdev->id;
870 pcdev->ici.drv_name = dev_name(&pdev->dev); 1721 pcdev->ici.drv_name = dev_name(&pdev->dev);
871 pcdev->ici.ops = &sh_mobile_ceu_host_ops; 1722 pcdev->ici.ops = &sh_mobile_ceu_host_ops;
@@ -889,7 +1740,7 @@ exit:
889 return err; 1740 return err;
890} 1741}
891 1742
892static int sh_mobile_ceu_remove(struct platform_device *pdev) 1743static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
893{ 1744{
894 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev); 1745 struct soc_camera_host *soc_host = to_soc_camera_host(&pdev->dev);
895 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host, 1746 struct sh_mobile_ceu_dev *pcdev = container_of(soc_host,
@@ -927,7 +1778,7 @@ static struct platform_driver sh_mobile_ceu_driver = {
927 .pm = &sh_mobile_ceu_dev_pm_ops, 1778 .pm = &sh_mobile_ceu_dev_pm_ops,
928 }, 1779 },
929 .probe = sh_mobile_ceu_probe, 1780 .probe = sh_mobile_ceu_probe,
930 .remove = sh_mobile_ceu_remove, 1781 .remove = __exit_p(sh_mobile_ceu_remove),
931}; 1782};
932 1783
933static int __init sh_mobile_ceu_init(void) 1784static int __init sh_mobile_ceu_init(void)
@@ -946,3 +1797,4 @@ module_exit(sh_mobile_ceu_exit);
946MODULE_DESCRIPTION("SuperH Mobile CEU driver"); 1797MODULE_DESCRIPTION("SuperH Mobile CEU driver");
947MODULE_AUTHOR("Magnus Damm"); 1798MODULE_AUTHOR("Magnus Damm");
948MODULE_LICENSE("GPL"); 1799MODULE_LICENSE("GPL");
1800MODULE_ALIAS("platform:sh_mobile_ceu");
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 23edfdc4d4bc..9d84c94e8a40 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1954,8 +1954,10 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
1954 (!list_empty(&cam->outqueue)) || 1954 (!list_empty(&cam->outqueue)) ||
1955 (cam->state & DEV_DISCONNECTED) || 1955 (cam->state & DEV_DISCONNECTED) ||
1956 (cam->state & DEV_MISCONFIGURED), 1956 (cam->state & DEV_MISCONFIGURED),
1957 cam->module_param.frame_timeout * 1957 msecs_to_jiffies(
1958 1000 * msecs_to_jiffies(1) ); 1958 cam->module_param.frame_timeout * 1000
1959 )
1960 );
1959 if (timeout < 0) { 1961 if (timeout < 0) {
1960 mutex_unlock(&cam->fileop_mutex); 1962 mutex_unlock(&cam->fileop_mutex);
1961 return timeout; 1963 return timeout;
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 9f5ae8167855..59aa7a3694c2 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -21,15 +21,15 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/list.h> 23#include <linux/list.h>
24#include <linux/module.h>
25#include <linux/mutex.h> 24#include <linux/mutex.h>
25#include <linux/module.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/vmalloc.h> 27#include <linux/vmalloc.h>
28 28
29#include <media/soc_camera.h> 29#include <media/soc_camera.h>
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-dev.h>
32#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <media/v4l2-dev.h>
33#include <media/videobuf-core.h> 33#include <media/videobuf-core.h>
34 34
35/* Default to VGA resolution */ 35/* Default to VGA resolution */
@@ -38,7 +38,7 @@
38 38
39static LIST_HEAD(hosts); 39static LIST_HEAD(hosts);
40static LIST_HEAD(devices); 40static LIST_HEAD(devices);
41static DEFINE_MUTEX(list_lock); 41static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
42 42
43const struct soc_camera_data_format *soc_camera_format_by_fourcc( 43const struct soc_camera_data_format *soc_camera_format_by_fourcc(
44 struct soc_camera_device *icd, unsigned int fourcc) 44 struct soc_camera_device *icd, unsigned int fourcc)
@@ -152,12 +152,9 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
152{ 152{
153 struct soc_camera_file *icf = file->private_data; 153 struct soc_camera_file *icf = file->private_data;
154 struct soc_camera_device *icd = icf->icd; 154 struct soc_camera_device *icd = icf->icd;
155 int ret = 0; 155 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
156
157 if (icd->ops->set_std)
158 ret = icd->ops->set_std(icd, a);
159 156
160 return ret; 157 return v4l2_subdev_call(sd, core, s_std, *a);
161} 158}
162 159
163static int soc_camera_reqbufs(struct file *file, void *priv, 160static int soc_camera_reqbufs(struct file *file, void *priv,
@@ -170,8 +167,6 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
170 167
171 WARN_ON(priv != file->private_data); 168 WARN_ON(priv != file->private_data);
172 169
173 dev_dbg(&icd->dev, "%s: %d\n", __func__, p->memory);
174
175 ret = videobuf_reqbufs(&icf->vb_vidq, p); 170 ret = videobuf_reqbufs(&icf->vb_vidq, p);
176 if (ret < 0) 171 if (ret < 0)
177 return ret; 172 return ret;
@@ -209,10 +204,11 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
209 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK); 204 return videobuf_dqbuf(&icf->vb_vidq, p, file->f_flags & O_NONBLOCK);
210} 205}
211 206
207/* Always entered with .video_lock held */
212static int soc_camera_init_user_formats(struct soc_camera_device *icd) 208static int soc_camera_init_user_formats(struct soc_camera_device *icd)
213{ 209{
214 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 210 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
215 int i, fmts = 0; 211 int i, fmts = 0, ret;
216 212
217 if (!ici->ops->get_formats) 213 if (!ici->ops->get_formats)
218 /* 214 /*
@@ -225,8 +221,12 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
225 * First pass - only count formats this host-sensor 221 * First pass - only count formats this host-sensor
226 * configuration can provide 222 * configuration can provide
227 */ 223 */
228 for (i = 0; i < icd->num_formats; i++) 224 for (i = 0; i < icd->num_formats; i++) {
229 fmts += ici->ops->get_formats(icd, i, NULL); 225 ret = ici->ops->get_formats(icd, i, NULL);
226 if (ret < 0)
227 return ret;
228 fmts += ret;
229 }
230 230
231 if (!fmts) 231 if (!fmts)
232 return -ENXIO; 232 return -ENXIO;
@@ -248,20 +248,39 @@ static int soc_camera_init_user_formats(struct soc_camera_device *icd)
248 icd->user_formats[i].cam_fmt = icd->formats + i; 248 icd->user_formats[i].cam_fmt = icd->formats + i;
249 icd->user_formats[i].buswidth = icd->formats[i].depth; 249 icd->user_formats[i].buswidth = icd->formats[i].depth;
250 } else { 250 } else {
251 fmts += ici->ops->get_formats(icd, i, 251 ret = ici->ops->get_formats(icd, i,
252 &icd->user_formats[fmts]); 252 &icd->user_formats[fmts]);
253 if (ret < 0)
254 goto egfmt;
255 fmts += ret;
253 } 256 }
254 257
255 icd->current_fmt = icd->user_formats[0].host_fmt; 258 icd->current_fmt = icd->user_formats[0].host_fmt;
256 259
257 return 0; 260 return 0;
261
262egfmt:
263 icd->num_user_formats = 0;
264 vfree(icd->user_formats);
265 return ret;
258} 266}
259 267
268/* Always entered with .video_lock held */
260static void soc_camera_free_user_formats(struct soc_camera_device *icd) 269static void soc_camera_free_user_formats(struct soc_camera_device *icd)
261{ 270{
271 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
272
273 if (ici->ops->put_formats)
274 ici->ops->put_formats(icd);
275 icd->current_fmt = NULL;
276 icd->num_user_formats = 0;
262 vfree(icd->user_formats); 277 vfree(icd->user_formats);
278 icd->user_formats = NULL;
263} 279}
264 280
281#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
282 ((x) >> 24) & 0xff
283
265/* Called with .vb_lock held */ 284/* Called with .vb_lock held */
266static int soc_camera_set_fmt(struct soc_camera_file *icf, 285static int soc_camera_set_fmt(struct soc_camera_file *icf,
267 struct v4l2_format *f) 286 struct v4l2_format *f)
@@ -271,6 +290,9 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
271 struct v4l2_pix_format *pix = &f->fmt.pix; 290 struct v4l2_pix_format *pix = &f->fmt.pix;
272 int ret; 291 int ret;
273 292
293 dev_dbg(&icd->dev, "S_FMT(%c%c%c%c, %ux%u)\n",
294 pixfmtstr(pix->pixelformat), pix->width, pix->height);
295
274 /* We always call try_fmt() before set_fmt() or set_crop() */ 296 /* We always call try_fmt() before set_fmt() or set_crop() */
275 ret = ici->ops->try_fmt(icd, f); 297 ret = ici->ops->try_fmt(icd, f);
276 if (ret < 0) 298 if (ret < 0)
@@ -281,13 +303,13 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
281 return ret; 303 return ret;
282 } else if (!icd->current_fmt || 304 } else if (!icd->current_fmt ||
283 icd->current_fmt->fourcc != pix->pixelformat) { 305 icd->current_fmt->fourcc != pix->pixelformat) {
284 dev_err(ici->dev, 306 dev_err(&icd->dev,
285 "Host driver hasn't set up current format correctly!\n"); 307 "Host driver hasn't set up current format correctly!\n");
286 return -EINVAL; 308 return -EINVAL;
287 } 309 }
288 310
289 icd->width = pix->width; 311 icd->user_width = pix->width;
290 icd->height = pix->height; 312 icd->user_height = pix->height;
291 icf->vb_vidq.field = 313 icf->vb_vidq.field =
292 icd->field = pix->field; 314 icd->field = pix->field;
293 315
@@ -296,7 +318,7 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
296 f->type); 318 f->type);
297 319
298 dev_dbg(&icd->dev, "set width: %d height: %d\n", 320 dev_dbg(&icd->dev, "set width: %d height: %d\n",
299 icd->width, icd->height); 321 icd->user_width, icd->user_height);
300 322
301 /* set physical bus parameters */ 323 /* set physical bus parameters */
302 return ici->ops->set_bus_param(icd, pix->pixelformat); 324 return ici->ops->set_bus_param(icd, pix->pixelformat);
@@ -304,30 +326,24 @@ static int soc_camera_set_fmt(struct soc_camera_file *icf,
304 326
305static int soc_camera_open(struct file *file) 327static int soc_camera_open(struct file *file)
306{ 328{
307 struct video_device *vdev; 329 struct video_device *vdev = video_devdata(file);
308 struct soc_camera_device *icd; 330 struct soc_camera_device *icd = container_of(vdev->parent,
331 struct soc_camera_device,
332 dev);
333 struct soc_camera_link *icl = to_soc_camera_link(icd);
309 struct soc_camera_host *ici; 334 struct soc_camera_host *ici;
310 struct soc_camera_file *icf; 335 struct soc_camera_file *icf;
311 int ret; 336 int ret;
312 337
313 icf = vmalloc(sizeof(*icf)); 338 if (!icd->ops)
314 if (!icf) 339 /* No device driver attached */
315 return -ENOMEM; 340 return -ENODEV;
316
317 /*
318 * It is safe to dereference these pointers now as long as a user has
319 * the video device open - we are protected by the held cdev reference.
320 */
321 341
322 vdev = video_devdata(file);
323 icd = container_of(vdev->parent, struct soc_camera_device, dev);
324 ici = to_soc_camera_host(icd->dev.parent); 342 ici = to_soc_camera_host(icd->dev.parent);
325 343
326 if (!try_module_get(icd->ops->owner)) { 344 icf = vmalloc(sizeof(*icf));
327 dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); 345 if (!icf)
328 ret = -EINVAL; 346 return -ENOMEM;
329 goto emgd;
330 }
331 347
332 if (!try_module_get(ici->ops->owner)) { 348 if (!try_module_get(ici->ops->owner)) {
333 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 349 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n");
@@ -335,7 +351,10 @@ static int soc_camera_open(struct file *file)
335 goto emgi; 351 goto emgi;
336 } 352 }
337 353
338 /* Protect against icd->remove() until we module_get() both drivers. */ 354 /*
355 * Protect against icd->ops->remove() until we module_get() both
356 * drivers.
357 */
339 mutex_lock(&icd->video_lock); 358 mutex_lock(&icd->video_lock);
340 359
341 icf->icd = icd; 360 icf->icd = icd;
@@ -347,14 +366,24 @@ static int soc_camera_open(struct file *file)
347 struct v4l2_format f = { 366 struct v4l2_format f = {
348 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE, 367 .type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
349 .fmt.pix = { 368 .fmt.pix = {
350 .width = icd->width, 369 .width = icd->user_width,
351 .height = icd->height, 370 .height = icd->user_height,
352 .field = icd->field, 371 .field = icd->field,
353 .pixelformat = icd->current_fmt->fourcc, 372 .pixelformat = icd->current_fmt->fourcc,
354 .colorspace = icd->current_fmt->colorspace, 373 .colorspace = icd->current_fmt->colorspace,
355 }, 374 },
356 }; 375 };
357 376
377 if (icl->power) {
378 ret = icl->power(icd->pdev, 1);
379 if (ret < 0)
380 goto epower;
381 }
382
383 /* The camera could have been already on, try to reset */
384 if (icl->reset)
385 icl->reset(icd->pdev);
386
358 ret = ici->ops->add(icd); 387 ret = ici->ops->add(icd);
359 if (ret < 0) { 388 if (ret < 0) {
360 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret); 389 dev_err(&icd->dev, "Couldn't activate the camera: %d\n", ret);
@@ -367,28 +396,29 @@ static int soc_camera_open(struct file *file)
367 goto esfmt; 396 goto esfmt;
368 } 397 }
369 398
370 mutex_unlock(&icd->video_lock);
371
372 file->private_data = icf; 399 file->private_data = icf;
373 dev_dbg(&icd->dev, "camera device open\n"); 400 dev_dbg(&icd->dev, "camera device open\n");
374 401
375 ici->ops->init_videobuf(&icf->vb_vidq, icd); 402 ici->ops->init_videobuf(&icf->vb_vidq, icd);
376 403
404 mutex_unlock(&icd->video_lock);
405
377 return 0; 406 return 0;
378 407
379 /* 408 /*
380 * First three errors are entered with the .video_lock held 409 * First five errors are entered with the .video_lock held
381 * and use_count == 1 410 * and use_count == 1
382 */ 411 */
383esfmt: 412esfmt:
384 ici->ops->remove(icd); 413 ici->ops->remove(icd);
385eiciadd: 414eiciadd:
415 if (icl->power)
416 icl->power(icd->pdev, 0);
417epower:
386 icd->use_count--; 418 icd->use_count--;
387 mutex_unlock(&icd->video_lock); 419 mutex_unlock(&icd->video_lock);
388 module_put(ici->ops->owner); 420 module_put(ici->ops->owner);
389emgi: 421emgi:
390 module_put(icd->ops->owner);
391emgd:
392 vfree(icf); 422 vfree(icf);
393 return ret; 423 return ret;
394} 424}
@@ -398,21 +428,24 @@ static int soc_camera_close(struct file *file)
398 struct soc_camera_file *icf = file->private_data; 428 struct soc_camera_file *icf = file->private_data;
399 struct soc_camera_device *icd = icf->icd; 429 struct soc_camera_device *icd = icf->icd;
400 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 430 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
401 struct video_device *vdev = icd->vdev;
402 431
403 mutex_lock(&icd->video_lock); 432 mutex_lock(&icd->video_lock);
404 icd->use_count--; 433 icd->use_count--;
405 if (!icd->use_count) 434 if (!icd->use_count) {
435 struct soc_camera_link *icl = to_soc_camera_link(icd);
436
406 ici->ops->remove(icd); 437 ici->ops->remove(icd);
438 if (icl->power)
439 icl->power(icd->pdev, 0);
440 }
407 441
408 mutex_unlock(&icd->video_lock); 442 mutex_unlock(&icd->video_lock);
409 443
410 module_put(icd->ops->owner);
411 module_put(ici->ops->owner); 444 module_put(ici->ops->owner);
412 445
413 vfree(icf); 446 vfree(icf);
414 447
415 dev_dbg(vdev->parent, "camera device close\n"); 448 dev_dbg(&icd->dev, "camera device close\n");
416 449
417 return 0; 450 return 0;
418} 451}
@@ -422,10 +455,9 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
422{ 455{
423 struct soc_camera_file *icf = file->private_data; 456 struct soc_camera_file *icf = file->private_data;
424 struct soc_camera_device *icd = icf->icd; 457 struct soc_camera_device *icd = icf->icd;
425 struct video_device *vdev = icd->vdev;
426 int err = -EINVAL; 458 int err = -EINVAL;
427 459
428 dev_err(vdev->parent, "camera device read not implemented\n"); 460 dev_err(&icd->dev, "camera device read not implemented\n");
429 461
430 return err; 462 return err;
431} 463}
@@ -483,8 +515,8 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
483 515
484 mutex_lock(&icf->vb_vidq.vb_lock); 516 mutex_lock(&icf->vb_vidq.vb_lock);
485 517
486 if (videobuf_queue_is_busy(&icf->vb_vidq)) { 518 if (icf->vb_vidq.bufs[0]) {
487 dev_err(&icd->dev, "S_FMT denied: queue busy\n"); 519 dev_err(&icd->dev, "S_FMT denied: queue initialised\n");
488 ret = -EBUSY; 520 ret = -EBUSY;
489 goto unlock; 521 goto unlock;
490 } 522 }
@@ -525,8 +557,8 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
525 557
526 WARN_ON(priv != file->private_data); 558 WARN_ON(priv != file->private_data);
527 559
528 pix->width = icd->width; 560 pix->width = icd->user_width;
529 pix->height = icd->height; 561 pix->height = icd->user_height;
530 pix->field = icf->vb_vidq.field; 562 pix->field = icf->vb_vidq.field;
531 pix->pixelformat = icd->current_fmt->fourcc; 563 pix->pixelformat = icd->current_fmt->fourcc;
532 pix->bytesperline = pix->width * 564 pix->bytesperline = pix->width *
@@ -555,18 +587,17 @@ static int soc_camera_streamon(struct file *file, void *priv,
555{ 587{
556 struct soc_camera_file *icf = file->private_data; 588 struct soc_camera_file *icf = file->private_data;
557 struct soc_camera_device *icd = icf->icd; 589 struct soc_camera_device *icd = icf->icd;
590 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
558 int ret; 591 int ret;
559 592
560 WARN_ON(priv != file->private_data); 593 WARN_ON(priv != file->private_data);
561 594
562 dev_dbg(&icd->dev, "%s\n", __func__);
563
564 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 595 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
565 return -EINVAL; 596 return -EINVAL;
566 597
567 mutex_lock(&icd->video_lock); 598 mutex_lock(&icd->video_lock);
568 599
569 icd->ops->start_capture(icd); 600 v4l2_subdev_call(sd, video, s_stream, 1);
570 601
571 /* This calls buf_queue from host driver's videobuf_queue_ops */ 602 /* This calls buf_queue from host driver's videobuf_queue_ops */
572 ret = videobuf_streamon(&icf->vb_vidq); 603 ret = videobuf_streamon(&icf->vb_vidq);
@@ -581,11 +612,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
581{ 612{
582 struct soc_camera_file *icf = file->private_data; 613 struct soc_camera_file *icf = file->private_data;
583 struct soc_camera_device *icd = icf->icd; 614 struct soc_camera_device *icd = icf->icd;
615 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
584 616
585 WARN_ON(priv != file->private_data); 617 WARN_ON(priv != file->private_data);
586 618
587 dev_dbg(&icd->dev, "%s\n", __func__);
588
589 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE) 619 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
590 return -EINVAL; 620 return -EINVAL;
591 621
@@ -595,7 +625,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
595 * remaining buffers. When the last buffer is freed, stop capture */ 625 * remaining buffers. When the last buffer is freed, stop capture */
596 videobuf_streamoff(&icf->vb_vidq); 626 videobuf_streamoff(&icf->vb_vidq);
597 627
598 icd->ops->stop_capture(icd); 628 v4l2_subdev_call(sd, video, s_stream, 0);
599 629
600 mutex_unlock(&icd->video_lock); 630 mutex_unlock(&icd->video_lock);
601 631
@@ -607,6 +637,7 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
607{ 637{
608 struct soc_camera_file *icf = file->private_data; 638 struct soc_camera_file *icf = file->private_data;
609 struct soc_camera_device *icd = icf->icd; 639 struct soc_camera_device *icd = icf->icd;
640 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
610 int i; 641 int i;
611 642
612 WARN_ON(priv != file->private_data); 643 WARN_ON(priv != file->private_data);
@@ -614,6 +645,15 @@ static int soc_camera_queryctrl(struct file *file, void *priv,
614 if (!qc->id) 645 if (!qc->id)
615 return -EINVAL; 646 return -EINVAL;
616 647
648 /* First check host controls */
649 for (i = 0; i < ici->ops->num_controls; i++)
650 if (qc->id == ici->ops->controls[i].id) {
651 memcpy(qc, &(ici->ops->controls[i]),
652 sizeof(*qc));
653 return 0;
654 }
655
656 /* Then device controls */
617 for (i = 0; i < icd->ops->num_controls; i++) 657 for (i = 0; i < icd->ops->num_controls; i++)
618 if (qc->id == icd->ops->controls[i].id) { 658 if (qc->id == icd->ops->controls[i].id) {
619 memcpy(qc, &(icd->ops->controls[i]), 659 memcpy(qc, &(icd->ops->controls[i]),
@@ -629,25 +669,19 @@ static int soc_camera_g_ctrl(struct file *file, void *priv,
629{ 669{
630 struct soc_camera_file *icf = file->private_data; 670 struct soc_camera_file *icf = file->private_data;
631 struct soc_camera_device *icd = icf->icd; 671 struct soc_camera_device *icd = icf->icd;
672 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
673 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
674 int ret;
632 675
633 WARN_ON(priv != file->private_data); 676 WARN_ON(priv != file->private_data);
634 677
635 switch (ctrl->id) { 678 if (ici->ops->get_ctrl) {
636 case V4L2_CID_GAIN: 679 ret = ici->ops->get_ctrl(icd, ctrl);
637 if (icd->gain == (unsigned short)~0) 680 if (ret != -ENOIOCTLCMD)
638 return -EINVAL; 681 return ret;
639 ctrl->value = icd->gain;
640 return 0;
641 case V4L2_CID_EXPOSURE:
642 if (icd->exposure == (unsigned short)~0)
643 return -EINVAL;
644 ctrl->value = icd->exposure;
645 return 0;
646 } 682 }
647 683
648 if (icd->ops->get_control) 684 return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
649 return icd->ops->get_control(icd, ctrl);
650 return -EINVAL;
651} 685}
652 686
653static int soc_camera_s_ctrl(struct file *file, void *priv, 687static int soc_camera_s_ctrl(struct file *file, void *priv,
@@ -655,12 +689,19 @@ static int soc_camera_s_ctrl(struct file *file, void *priv,
655{ 689{
656 struct soc_camera_file *icf = file->private_data; 690 struct soc_camera_file *icf = file->private_data;
657 struct soc_camera_device *icd = icf->icd; 691 struct soc_camera_device *icd = icf->icd;
692 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
693 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
694 int ret;
658 695
659 WARN_ON(priv != file->private_data); 696 WARN_ON(priv != file->private_data);
660 697
661 if (icd->ops->set_control) 698 if (ici->ops->set_ctrl) {
662 return icd->ops->set_control(icd, ctrl); 699 ret = ici->ops->set_ctrl(icd, ctrl);
663 return -EINVAL; 700 if (ret != -ENOIOCTLCMD)
701 return ret;
702 }
703
704 return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
664} 705}
665 706
666static int soc_camera_cropcap(struct file *file, void *fh, 707static int soc_camera_cropcap(struct file *file, void *fh,
@@ -668,20 +709,9 @@ static int soc_camera_cropcap(struct file *file, void *fh,
668{ 709{
669 struct soc_camera_file *icf = file->private_data; 710 struct soc_camera_file *icf = file->private_data;
670 struct soc_camera_device *icd = icf->icd; 711 struct soc_camera_device *icd = icf->icd;
712 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
671 713
672 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 714 return ici->ops->cropcap(icd, a);
673 a->bounds.left = icd->x_min;
674 a->bounds.top = icd->y_min;
675 a->bounds.width = icd->width_max;
676 a->bounds.height = icd->height_max;
677 a->defrect.left = icd->x_min;
678 a->defrect.top = icd->y_min;
679 a->defrect.width = DEFAULT_WIDTH;
680 a->defrect.height = DEFAULT_HEIGHT;
681 a->pixelaspect.numerator = 1;
682 a->pixelaspect.denominator = 1;
683
684 return 0;
685} 715}
686 716
687static int soc_camera_g_crop(struct file *file, void *fh, 717static int soc_camera_g_crop(struct file *file, void *fh,
@@ -689,36 +719,53 @@ static int soc_camera_g_crop(struct file *file, void *fh,
689{ 719{
690 struct soc_camera_file *icf = file->private_data; 720 struct soc_camera_file *icf = file->private_data;
691 struct soc_camera_device *icd = icf->icd; 721 struct soc_camera_device *icd = icf->icd;
722 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
723 int ret;
692 724
693 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 725 mutex_lock(&icf->vb_vidq.vb_lock);
694 a->c.left = icd->x_current; 726 ret = ici->ops->get_crop(icd, a);
695 a->c.top = icd->y_current; 727 mutex_unlock(&icf->vb_vidq.vb_lock);
696 a->c.width = icd->width;
697 a->c.height = icd->height;
698 728
699 return 0; 729 return ret;
700} 730}
701 731
732/*
733 * According to the V4L2 API, drivers shall not update the struct v4l2_crop
734 * argument with the actual geometry, instead, the user shall use G_CROP to
735 * retrieve it. However, we expect camera host and client drivers to update
736 * the argument, which we then use internally, but do not return to the user.
737 */
702static int soc_camera_s_crop(struct file *file, void *fh, 738static int soc_camera_s_crop(struct file *file, void *fh,
703 struct v4l2_crop *a) 739 struct v4l2_crop *a)
704{ 740{
705 struct soc_camera_file *icf = file->private_data; 741 struct soc_camera_file *icf = file->private_data;
706 struct soc_camera_device *icd = icf->icd; 742 struct soc_camera_device *icd = icf->icd;
707 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 743 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
744 struct v4l2_rect *rect = &a->c;
745 struct v4l2_crop current_crop;
708 int ret; 746 int ret;
709 747
710 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 748 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
711 return -EINVAL; 749 return -EINVAL;
712 750
751 dev_dbg(&icd->dev, "S_CROP(%ux%u@%u:%u)\n",
752 rect->width, rect->height, rect->left, rect->top);
753
713 /* Cropping is allowed during a running capture, guard consistency */ 754 /* Cropping is allowed during a running capture, guard consistency */
714 mutex_lock(&icf->vb_vidq.vb_lock); 755 mutex_lock(&icf->vb_vidq.vb_lock);
715 756
716 ret = ici->ops->set_crop(icd, &a->c); 757 /* If get_crop fails, we'll let host and / or client drivers decide */
717 if (!ret) { 758 ret = ici->ops->get_crop(icd, &current_crop);
718 icd->width = a->c.width; 759
719 icd->height = a->c.height; 760 /* Prohibit window size change with initialised buffers */
720 icd->x_current = a->c.left; 761 if (icf->vb_vidq.bufs[0] && !ret &&
721 icd->y_current = a->c.top; 762 (a->c.width != current_crop.c.width ||
763 a->c.height != current_crop.c.height)) {
764 dev_err(&icd->dev,
765 "S_CROP denied: queue initialised and sizes differ\n");
766 ret = -EBUSY;
767 } else {
768 ret = ici->ops->set_crop(icd, a);
722 } 769 }
723 770
724 mutex_unlock(&icf->vb_vidq.vb_lock); 771 mutex_unlock(&icf->vb_vidq.vb_lock);
@@ -731,11 +778,9 @@ static int soc_camera_g_chip_ident(struct file *file, void *fh,
731{ 778{
732 struct soc_camera_file *icf = file->private_data; 779 struct soc_camera_file *icf = file->private_data;
733 struct soc_camera_device *icd = icf->icd; 780 struct soc_camera_device *icd = icf->icd;
781 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
734 782
735 if (!icd->ops->get_chip_id) 783 return v4l2_subdev_call(sd, core, g_chip_ident, id);
736 return -EINVAL;
737
738 return icd->ops->get_chip_id(icd, id);
739} 784}
740 785
741#ifdef CONFIG_VIDEO_ADV_DEBUG 786#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -744,11 +789,9 @@ static int soc_camera_g_register(struct file *file, void *fh,
744{ 789{
745 struct soc_camera_file *icf = file->private_data; 790 struct soc_camera_file *icf = file->private_data;
746 struct soc_camera_device *icd = icf->icd; 791 struct soc_camera_device *icd = icf->icd;
792 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
747 793
748 if (!icd->ops->get_register) 794 return v4l2_subdev_call(sd, core, g_register, reg);
749 return -EINVAL;
750
751 return icd->ops->get_register(icd, reg);
752} 795}
753 796
754static int soc_camera_s_register(struct file *file, void *fh, 797static int soc_camera_s_register(struct file *file, void *fh,
@@ -756,37 +799,12 @@ static int soc_camera_s_register(struct file *file, void *fh,
756{ 799{
757 struct soc_camera_file *icf = file->private_data; 800 struct soc_camera_file *icf = file->private_data;
758 struct soc_camera_device *icd = icf->icd; 801 struct soc_camera_device *icd = icf->icd;
802 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
759 803
760 if (!icd->ops->set_register) 804 return v4l2_subdev_call(sd, core, s_register, reg);
761 return -EINVAL;
762
763 return icd->ops->set_register(icd, reg);
764} 805}
765#endif 806#endif
766 807
767static int device_register_link(struct soc_camera_device *icd)
768{
769 int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
770
771 if (!ret)
772 ret = device_register(&icd->dev);
773
774 if (ret < 0) {
775 /* Prevent calling device_unregister() */
776 icd->dev.parent = NULL;
777 dev_err(&icd->dev, "Cannot register device: %d\n", ret);
778 /* Even if probe() was unsuccessful for all registered drivers,
779 * device_register() returns 0, and we add the link, just to
780 * document this camera's control device */
781 } else if (icd->control)
782 /* Have to sysfs_remove_link() before device_unregister()? */
783 if (sysfs_create_link(&icd->dev.kobj, &icd->control->kobj,
784 "control"))
785 dev_warn(&icd->dev,
786 "Failed creating the control symlink\n");
787 return ret;
788}
789
790/* So far this function cannot fail */ 808/* So far this function cannot fail */
791static void scan_add_host(struct soc_camera_host *ici) 809static void scan_add_host(struct soc_camera_host *ici)
792{ 810{
@@ -796,106 +814,193 @@ static void scan_add_host(struct soc_camera_host *ici)
796 814
797 list_for_each_entry(icd, &devices, list) { 815 list_for_each_entry(icd, &devices, list) {
798 if (icd->iface == ici->nr) { 816 if (icd->iface == ici->nr) {
799 icd->dev.parent = ici->dev; 817 int ret;
800 device_register_link(icd); 818 icd->dev.parent = ici->v4l2_dev.dev;
819 dev_set_name(&icd->dev, "%u-%u", icd->iface,
820 icd->devnum);
821 ret = device_register(&icd->dev);
822 if (ret < 0) {
823 icd->dev.parent = NULL;
824 dev_err(&icd->dev,
825 "Cannot register device: %d\n", ret);
826 }
801 } 827 }
802 } 828 }
803 829
804 mutex_unlock(&list_lock); 830 mutex_unlock(&list_lock);
805} 831}
806 832
807/* return: 0 if no match found or a match found and 833#ifdef CONFIG_I2C_BOARDINFO
808 * device_register() successful, error code otherwise */ 834static int soc_camera_init_i2c(struct soc_camera_device *icd,
809static int scan_add_device(struct soc_camera_device *icd) 835 struct soc_camera_link *icl)
810{ 836{
811 struct soc_camera_host *ici; 837 struct i2c_client *client;
812 int ret = 0; 838 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
839 struct i2c_adapter *adap = i2c_get_adapter(icl->i2c_adapter_id);
840 struct v4l2_subdev *subdev;
841 int ret;
813 842
814 mutex_lock(&list_lock); 843 if (!adap) {
844 ret = -ENODEV;
845 dev_err(&icd->dev, "Cannot get I2C adapter #%d. No driver?\n",
846 icl->i2c_adapter_id);
847 goto ei2cga;
848 }
815 849
816 list_add_tail(&icd->list, &devices); 850 icl->board_info->platform_data = icd;
817 851
818 /* Watch out for class_for_each_device / class_find_device API by 852 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
819 * Dave Young <hidave.darkstar@gmail.com> */ 853 icl->module_name, icl->board_info, NULL);
820 list_for_each_entry(ici, &hosts, list) { 854 if (!subdev) {
821 if (icd->iface == ici->nr) { 855 ret = -ENOMEM;
822 ret = 1; 856 goto ei2cnd;
823 icd->dev.parent = ici->dev;
824 break;
825 }
826 } 857 }
827 858
828 mutex_unlock(&list_lock); 859 client = subdev->priv;
829 860
830 if (ret) 861 /* Use to_i2c_client(dev) to recover the i2c client */
831 ret = device_register_link(icd); 862 dev_set_drvdata(&icd->dev, &client->dev);
832 863
864 return 0;
865ei2cnd:
866 i2c_put_adapter(adap);
867ei2cga:
833 return ret; 868 return ret;
834} 869}
835 870
871static void soc_camera_free_i2c(struct soc_camera_device *icd)
872{
873 struct i2c_client *client =
874 to_i2c_client(to_soc_camera_control(icd));
875 dev_set_drvdata(&icd->dev, NULL);
876 v4l2_device_unregister_subdev(i2c_get_clientdata(client));
877 i2c_unregister_device(client);
878 i2c_put_adapter(client->adapter);
879}
880#else
881#define soc_camera_init_i2c(icd, icl) (-ENODEV)
882#define soc_camera_free_i2c(icd) do {} while (0)
883#endif
884
885static int soc_camera_video_start(struct soc_camera_device *icd);
886static int video_dev_create(struct soc_camera_device *icd);
887/* Called during host-driver probe */
836static int soc_camera_probe(struct device *dev) 888static int soc_camera_probe(struct device *dev)
837{ 889{
838 struct soc_camera_device *icd = to_soc_camera_dev(dev); 890 struct soc_camera_device *icd = to_soc_camera_dev(dev);
839 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 891 struct soc_camera_host *ici = to_soc_camera_host(dev->parent);
892 struct soc_camera_link *icl = to_soc_camera_link(icd);
893 struct device *control = NULL;
894 struct v4l2_subdev *sd;
895 struct v4l2_format f = {.type = V4L2_BUF_TYPE_VIDEO_CAPTURE};
840 int ret; 896 int ret;
841 897
842 /* 898 dev_info(dev, "Probing %s\n", dev_name(dev));
843 * Possible race scenario:
844 * modprobe <camera-host-driver> triggers __func__
845 * at this moment respective <camera-sensor-driver> gets rmmod'ed
846 * to protect take module references.
847 */
848 899
849 if (!try_module_get(icd->ops->owner)) { 900 if (icl->power) {
850 dev_err(&icd->dev, "Couldn't lock sensor driver.\n"); 901 ret = icl->power(icd->pdev, 1);
851 ret = -EINVAL; 902 if (ret < 0) {
852 goto emgd; 903 dev_err(dev,
904 "Platform failed to power-on the camera.\n");
905 goto epower;
906 }
853 } 907 }
854 908
855 if (!try_module_get(ici->ops->owner)) { 909 /* The camera could have been already on, try to reset */
856 dev_err(&icd->dev, "Couldn't lock capture bus driver.\n"); 910 if (icl->reset)
911 icl->reset(icd->pdev);
912
913 ret = ici->ops->add(icd);
914 if (ret < 0)
915 goto eadd;
916
917 /* Must have icd->vdev before registering the device */
918 ret = video_dev_create(icd);
919 if (ret < 0)
920 goto evdc;
921
922 /* Non-i2c cameras, e.g., soc_camera_platform, have no board_info */
923 if (icl->board_info) {
924 ret = soc_camera_init_i2c(icd, icl);
925 if (ret < 0)
926 goto eadddev;
927 } else if (!icl->add_device || !icl->del_device) {
857 ret = -EINVAL; 928 ret = -EINVAL;
858 goto emgi; 929 goto eadddev;
930 } else {
931 if (icl->module_name)
932 ret = request_module(icl->module_name);
933
934 ret = icl->add_device(icl, &icd->dev);
935 if (ret < 0)
936 goto eadddev;
937
938 /*
939 * FIXME: this is racy, have to use driver-binding notification,
940 * when it is available
941 */
942 control = to_soc_camera_control(icd);
943 if (!control || !control->driver || !dev_get_drvdata(control) ||
944 !try_module_get(control->driver->owner)) {
945 icl->del_device(icl);
946 goto enodrv;
947 }
859 } 948 }
860 949
950 /* At this point client .probe() should have run already */
951 ret = soc_camera_init_user_formats(icd);
952 if (ret < 0)
953 goto eiufmt;
954
955 icd->field = V4L2_FIELD_ANY;
956
957 /* ..._video_start() will create a device node, so we have to protect */
861 mutex_lock(&icd->video_lock); 958 mutex_lock(&icd->video_lock);
862 959
863 /* We only call ->add() here to activate and probe the camera. 960 ret = soc_camera_video_start(icd);
864 * We shall ->remove() and deactivate it immediately afterwards. */
865 ret = ici->ops->add(icd);
866 if (ret < 0) 961 if (ret < 0)
867 goto eiadd; 962 goto evidstart;
963
964 /* Try to improve our guess of a reasonable window format */
965 sd = soc_camera_to_subdev(icd);
966 if (!v4l2_subdev_call(sd, video, g_fmt, &f)) {
967 icd->user_width = f.fmt.pix.width;
968 icd->user_height = f.fmt.pix.height;
969 }
868 970
869 ret = icd->ops->probe(icd); 971 /* Do we have to sysfs_remove_link() before device_unregister()? */
870 if (ret >= 0) { 972 if (sysfs_create_link(&icd->dev.kobj, &to_soc_camera_control(icd)->kobj,
871 const struct v4l2_queryctrl *qctrl; 973 "control"))
974 dev_warn(&icd->dev, "Failed creating the control symlink\n");
872 975
873 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_GAIN); 976 ici->ops->remove(icd);
874 icd->gain = qctrl ? qctrl->default_value : (unsigned short)~0;
875 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE);
876 icd->exposure = qctrl ? qctrl->default_value :
877 (unsigned short)~0;
878 977
879 ret = soc_camera_init_user_formats(icd); 978 if (icl->power)
880 if (ret < 0) { 979 icl->power(icd->pdev, 0);
881 if (icd->ops->remove)
882 icd->ops->remove(icd);
883 goto eiufmt;
884 }
885 980
886 icd->height = DEFAULT_HEIGHT; 981 mutex_unlock(&icd->video_lock);
887 icd->width = DEFAULT_WIDTH;
888 icd->field = V4L2_FIELD_ANY;
889 }
890 982
983 return 0;
984
985evidstart:
986 mutex_unlock(&icd->video_lock);
987 soc_camera_free_user_formats(icd);
891eiufmt: 988eiufmt:
989 if (icl->board_info) {
990 soc_camera_free_i2c(icd);
991 } else {
992 icl->del_device(icl);
993 module_put(control->driver->owner);
994 }
995enodrv:
996eadddev:
997 video_device_release(icd->vdev);
998evdc:
892 ici->ops->remove(icd); 999 ici->ops->remove(icd);
893eiadd: 1000eadd:
894 mutex_unlock(&icd->video_lock); 1001 if (icl->power)
895 module_put(ici->ops->owner); 1002 icl->power(icd->pdev, 0);
896emgi: 1003epower:
897 module_put(icd->ops->owner);
898emgd:
899 return ret; 1004 return ret;
900} 1005}
901 1006
@@ -904,12 +1009,28 @@ emgd:
904static int soc_camera_remove(struct device *dev) 1009static int soc_camera_remove(struct device *dev)
905{ 1010{
906 struct soc_camera_device *icd = to_soc_camera_dev(dev); 1011 struct soc_camera_device *icd = to_soc_camera_dev(dev);
1012 struct soc_camera_link *icl = to_soc_camera_link(icd);
1013 struct video_device *vdev = icd->vdev;
907 1014
908 mutex_lock(&icd->video_lock); 1015 BUG_ON(!dev->parent);
909 if (icd->ops->remove)
910 icd->ops->remove(icd);
911 mutex_unlock(&icd->video_lock);
912 1016
1017 if (vdev) {
1018 mutex_lock(&icd->video_lock);
1019 video_unregister_device(vdev);
1020 icd->vdev = NULL;
1021 mutex_unlock(&icd->video_lock);
1022 }
1023
1024 if (icl->board_info) {
1025 soc_camera_free_i2c(icd);
1026 } else {
1027 struct device_driver *drv = to_soc_camera_control(icd) ?
1028 to_soc_camera_control(icd)->driver : NULL;
1029 if (drv) {
1030 icl->del_device(icl);
1031 module_put(drv->owner);
1032 }
1033 }
913 soc_camera_free_user_formats(icd); 1034 soc_camera_free_user_formats(icd);
914 1035
915 return 0; 1036 return 0;
@@ -957,14 +1078,33 @@ static void dummy_release(struct device *dev)
957{ 1078{
958} 1079}
959 1080
1081static int default_cropcap(struct soc_camera_device *icd,
1082 struct v4l2_cropcap *a)
1083{
1084 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1085 return v4l2_subdev_call(sd, video, cropcap, a);
1086}
1087
1088static int default_g_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
1089{
1090 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1091 return v4l2_subdev_call(sd, video, g_crop, a);
1092}
1093
1094static int default_s_crop(struct soc_camera_device *icd, struct v4l2_crop *a)
1095{
1096 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1097 return v4l2_subdev_call(sd, video, s_crop, a);
1098}
1099
960int soc_camera_host_register(struct soc_camera_host *ici) 1100int soc_camera_host_register(struct soc_camera_host *ici)
961{ 1101{
962 struct soc_camera_host *ix; 1102 struct soc_camera_host *ix;
1103 int ret;
963 1104
964 if (!ici || !ici->ops || 1105 if (!ici || !ici->ops ||
965 !ici->ops->try_fmt || 1106 !ici->ops->try_fmt ||
966 !ici->ops->set_fmt || 1107 !ici->ops->set_fmt ||
967 !ici->ops->set_crop ||
968 !ici->ops->set_bus_param || 1108 !ici->ops->set_bus_param ||
969 !ici->ops->querycap || 1109 !ici->ops->querycap ||
970 !ici->ops->init_videobuf || 1110 !ici->ops->init_videobuf ||
@@ -972,18 +1112,27 @@ int soc_camera_host_register(struct soc_camera_host *ici)
972 !ici->ops->add || 1112 !ici->ops->add ||
973 !ici->ops->remove || 1113 !ici->ops->remove ||
974 !ici->ops->poll || 1114 !ici->ops->poll ||
975 !ici->dev) 1115 !ici->v4l2_dev.dev)
976 return -EINVAL; 1116 return -EINVAL;
977 1117
1118 if (!ici->ops->set_crop)
1119 ici->ops->set_crop = default_s_crop;
1120 if (!ici->ops->get_crop)
1121 ici->ops->get_crop = default_g_crop;
1122 if (!ici->ops->cropcap)
1123 ici->ops->cropcap = default_cropcap;
1124
978 mutex_lock(&list_lock); 1125 mutex_lock(&list_lock);
979 list_for_each_entry(ix, &hosts, list) { 1126 list_for_each_entry(ix, &hosts, list) {
980 if (ix->nr == ici->nr) { 1127 if (ix->nr == ici->nr) {
981 mutex_unlock(&list_lock); 1128 ret = -EBUSY;
982 return -EBUSY; 1129 goto edevreg;
983 } 1130 }
984 } 1131 }
985 1132
986 dev_set_drvdata(ici->dev, ici); 1133 ret = v4l2_device_register(ici->v4l2_dev.dev, &ici->v4l2_dev);
1134 if (ret < 0)
1135 goto edevreg;
987 1136
988 list_add_tail(&ici->list, &hosts); 1137 list_add_tail(&ici->list, &hosts);
989 mutex_unlock(&list_lock); 1138 mutex_unlock(&list_lock);
@@ -991,6 +1140,10 @@ int soc_camera_host_register(struct soc_camera_host *ici)
991 scan_add_host(ici); 1140 scan_add_host(ici);
992 1141
993 return 0; 1142 return 0;
1143
1144edevreg:
1145 mutex_unlock(&list_lock);
1146 return ret;
994} 1147}
995EXPORT_SYMBOL(soc_camera_host_register); 1148EXPORT_SYMBOL(soc_camera_host_register);
996 1149
@@ -1004,42 +1157,34 @@ void soc_camera_host_unregister(struct soc_camera_host *ici)
1004 list_del(&ici->list); 1157 list_del(&ici->list);
1005 1158
1006 list_for_each_entry(icd, &devices, list) { 1159 list_for_each_entry(icd, &devices, list) {
1007 if (icd->dev.parent == ici->dev) { 1160 if (icd->iface == ici->nr) {
1161 /* The bus->remove will be called */
1008 device_unregister(&icd->dev); 1162 device_unregister(&icd->dev);
1009 /* Not before device_unregister(), .remove 1163 /* Not before device_unregister(), .remove
1010 * needs parent to call ici->ops->remove() */ 1164 * needs parent to call ici->ops->remove() */
1011 icd->dev.parent = NULL; 1165 icd->dev.parent = NULL;
1166
1167 /* If the host module is loaded again, device_register()
1168 * would complain "already initialised" */
1012 memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj)); 1169 memset(&icd->dev.kobj, 0, sizeof(icd->dev.kobj));
1013 } 1170 }
1014 } 1171 }
1015 1172
1016 mutex_unlock(&list_lock); 1173 mutex_unlock(&list_lock);
1017 1174
1018 dev_set_drvdata(ici->dev, NULL); 1175 v4l2_device_unregister(&ici->v4l2_dev);
1019} 1176}
1020EXPORT_SYMBOL(soc_camera_host_unregister); 1177EXPORT_SYMBOL(soc_camera_host_unregister);
1021 1178
1022/* Image capture device */ 1179/* Image capture device */
1023int soc_camera_device_register(struct soc_camera_device *icd) 1180static int soc_camera_device_register(struct soc_camera_device *icd)
1024{ 1181{
1025 struct soc_camera_device *ix; 1182 struct soc_camera_device *ix;
1026 int num = -1, i; 1183 int num = -1, i;
1027 1184
1028 if (!icd || !icd->ops ||
1029 !icd->ops->probe ||
1030 !icd->ops->init ||
1031 !icd->ops->release ||
1032 !icd->ops->start_capture ||
1033 !icd->ops->stop_capture ||
1034 !icd->ops->set_crop ||
1035 !icd->ops->set_fmt ||
1036 !icd->ops->try_fmt ||
1037 !icd->ops->query_bus_param ||
1038 !icd->ops->set_bus_param)
1039 return -EINVAL;
1040
1041 for (i = 0; i < 256 && num < 0; i++) { 1185 for (i = 0; i < 256 && num < 0; i++) {
1042 num = i; 1186 num = i;
1187 /* Check if this index is available on this interface */
1043 list_for_each_entry(ix, &devices, list) { 1188 list_for_each_entry(ix, &devices, list) {
1044 if (ix->iface == icd->iface && ix->devnum == i) { 1189 if (ix->iface == icd->iface && ix->devnum == i) {
1045 num = -1; 1190 num = -1;
@@ -1061,21 +1206,15 @@ int soc_camera_device_register(struct soc_camera_device *icd)
1061 icd->host_priv = NULL; 1206 icd->host_priv = NULL;
1062 mutex_init(&icd->video_lock); 1207 mutex_init(&icd->video_lock);
1063 1208
1064 return scan_add_device(icd); 1209 list_add_tail(&icd->list, &devices);
1210
1211 return 0;
1065} 1212}
1066EXPORT_SYMBOL(soc_camera_device_register);
1067 1213
1068void soc_camera_device_unregister(struct soc_camera_device *icd) 1214static void soc_camera_device_unregister(struct soc_camera_device *icd)
1069{ 1215{
1070 mutex_lock(&list_lock);
1071 list_del(&icd->list); 1216 list_del(&icd->list);
1072
1073 /* The bus->remove will be eventually called */
1074 if (icd->dev.parent)
1075 device_unregister(&icd->dev);
1076 mutex_unlock(&list_lock);
1077} 1217}
1078EXPORT_SYMBOL(soc_camera_device_unregister);
1079 1218
1080static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { 1219static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1081 .vidioc_querycap = soc_camera_querycap, 1220 .vidioc_querycap = soc_camera_querycap,
@@ -1106,23 +1245,13 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1106#endif 1245#endif
1107}; 1246};
1108 1247
1109/* 1248static int video_dev_create(struct soc_camera_device *icd)
1110 * Usually called from the struct soc_camera_ops .probe() method, i.e., from
1111 * soc_camera_probe() above with .video_lock held
1112 */
1113int soc_camera_video_start(struct soc_camera_device *icd)
1114{ 1249{
1115 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1250 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
1116 int err = -ENOMEM; 1251 struct video_device *vdev = video_device_alloc();
1117 struct video_device *vdev;
1118 1252
1119 if (!icd->dev.parent)
1120 return -ENODEV;
1121
1122 vdev = video_device_alloc();
1123 if (!vdev) 1253 if (!vdev)
1124 goto evidallocd; 1254 return -ENOMEM;
1125 dev_dbg(ici->dev, "Allocated video_device %p\n", vdev);
1126 1255
1127 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name)); 1256 strlcpy(vdev->name, ici->drv_name, sizeof(vdev->name));
1128 1257
@@ -1132,87 +1261,93 @@ int soc_camera_video_start(struct soc_camera_device *icd)
1132 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1261 vdev->ioctl_ops = &soc_camera_ioctl_ops;
1133 vdev->release = video_device_release; 1262 vdev->release = video_device_release;
1134 vdev->minor = -1; 1263 vdev->minor = -1;
1135 vdev->tvnorms = V4L2_STD_UNKNOWN, 1264 vdev->tvnorms = V4L2_STD_UNKNOWN;
1136 1265
1137 err = video_register_device(vdev, VFL_TYPE_GRABBER, vdev->minor);
1138 if (err < 0) {
1139 dev_err(vdev->parent, "video_register_device failed\n");
1140 goto evidregd;
1141 }
1142 icd->vdev = vdev; 1266 icd->vdev = vdev;
1143 1267
1144 return 0; 1268 return 0;
1145
1146evidregd:
1147 video_device_release(vdev);
1148evidallocd:
1149 return err;
1150} 1269}
1151EXPORT_SYMBOL(soc_camera_video_start);
1152 1270
1153/* Called from client .remove() methods with .video_lock held */ 1271/*
1154void soc_camera_video_stop(struct soc_camera_device *icd) 1272 * Called from soc_camera_probe() above (with .video_lock held???)
1273 */
1274static int soc_camera_video_start(struct soc_camera_device *icd)
1155{ 1275{
1156 struct video_device *vdev = icd->vdev; 1276 int ret;
1157 1277
1158 dev_dbg(&icd->dev, "%s\n", __func__); 1278 if (!icd->dev.parent)
1279 return -ENODEV;
1159 1280
1160 if (!icd->dev.parent || !vdev) 1281 if (!icd->ops ||
1161 return; 1282 !icd->ops->query_bus_param ||
1283 !icd->ops->set_bus_param)
1284 return -EINVAL;
1285
1286 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER,
1287 icd->vdev->minor);
1288 if (ret < 0) {
1289 dev_err(&icd->dev, "video_register_device failed: %d\n", ret);
1290 return ret;
1291 }
1162 1292
1163 video_unregister_device(vdev); 1293 return 0;
1164 icd->vdev = NULL;
1165} 1294}
1166EXPORT_SYMBOL(soc_camera_video_stop);
1167 1295
1168static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev) 1296static int __devinit soc_camera_pdrv_probe(struct platform_device *pdev)
1169{ 1297{
1170 struct soc_camera_link *icl = pdev->dev.platform_data; 1298 struct soc_camera_link *icl = pdev->dev.platform_data;
1171 struct i2c_adapter *adap; 1299 struct soc_camera_device *icd;
1172 struct i2c_client *client; 1300 int ret;
1173 1301
1174 if (!icl) 1302 if (!icl)
1175 return -EINVAL; 1303 return -EINVAL;
1176 1304
1177 adap = i2c_get_adapter(icl->i2c_adapter_id); 1305 icd = kzalloc(sizeof(*icd), GFP_KERNEL);
1178 if (!adap) { 1306 if (!icd)
1179 dev_warn(&pdev->dev, "Cannot get adapter #%d. No driver?\n",
1180 icl->i2c_adapter_id);
1181 /* -ENODEV and -ENXIO do not produce an error on probe()... */
1182 return -ENOENT;
1183 }
1184
1185 icl->board_info->platform_data = icl;
1186 client = i2c_new_device(adap, icl->board_info);
1187 if (!client) {
1188 i2c_put_adapter(adap);
1189 return -ENOMEM; 1307 return -ENOMEM;
1190 }
1191 1308
1192 platform_set_drvdata(pdev, client); 1309 icd->iface = icl->bus_id;
1310 icd->pdev = &pdev->dev;
1311 platform_set_drvdata(pdev, icd);
1312 icd->dev.platform_data = icl;
1313
1314 ret = soc_camera_device_register(icd);
1315 if (ret < 0)
1316 goto escdevreg;
1317
1318 icd->user_width = DEFAULT_WIDTH;
1319 icd->user_height = DEFAULT_HEIGHT;
1193 1320
1194 return 0; 1321 return 0;
1322
1323escdevreg:
1324 kfree(icd);
1325
1326 return ret;
1195} 1327}
1196 1328
1329/* Only called on rmmod for each platform device, since they are not
1330 * hot-pluggable. Now we know, that all our users - hosts and devices have
1331 * been unloaded already */
1197static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev) 1332static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
1198{ 1333{
1199 struct i2c_client *client = platform_get_drvdata(pdev); 1334 struct soc_camera_device *icd = platform_get_drvdata(pdev);
1200 1335
1201 if (!client) 1336 if (!icd)
1202 return -ENODEV; 1337 return -EINVAL;
1203 1338
1204 i2c_unregister_device(client); 1339 soc_camera_device_unregister(icd);
1205 i2c_put_adapter(client->adapter); 1340
1341 kfree(icd);
1206 1342
1207 return 0; 1343 return 0;
1208} 1344}
1209 1345
1210static struct platform_driver __refdata soc_camera_pdrv = { 1346static struct platform_driver __refdata soc_camera_pdrv = {
1211 .probe = soc_camera_pdrv_probe, 1347 .remove = __devexit_p(soc_camera_pdrv_remove),
1212 .remove = __devexit_p(soc_camera_pdrv_remove), 1348 .driver = {
1213 .driver = { 1349 .name = "soc-camera-pdrv",
1214 .name = "soc-camera-pdrv", 1350 .owner = THIS_MODULE,
1215 .owner = THIS_MODULE,
1216 }, 1351 },
1217}; 1352};
1218 1353
@@ -1225,7 +1360,7 @@ static int __init soc_camera_init(void)
1225 if (ret) 1360 if (ret)
1226 goto edrvr; 1361 goto edrvr;
1227 1362
1228 ret = platform_driver_register(&soc_camera_pdrv); 1363 ret = platform_driver_probe(&soc_camera_pdrv, soc_camera_pdrv_probe);
1229 if (ret) 1364 if (ret)
1230 goto epdr; 1365 goto epdr;
1231 1366
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index c48676356ab7..b6a575ce5da2 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -16,54 +16,32 @@
16#include <linux/delay.h> 16#include <linux/delay.h>
17#include <linux/platform_device.h> 17#include <linux/platform_device.h>
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19#include <media/v4l2-common.h> 19#include <media/v4l2-subdev.h>
20#include <media/soc_camera.h> 20#include <media/soc_camera.h>
21#include <media/soc_camera_platform.h> 21#include <media/soc_camera_platform.h>
22 22
23struct soc_camera_platform_priv { 23struct soc_camera_platform_priv {
24 struct soc_camera_platform_info *info; 24 struct v4l2_subdev subdev;
25 struct soc_camera_device icd;
26 struct soc_camera_data_format format; 25 struct soc_camera_data_format format;
27}; 26};
28 27
29static struct soc_camera_platform_info * 28static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
30soc_camera_platform_get_info(struct soc_camera_device *icd)
31{ 29{
32 struct soc_camera_platform_priv *priv; 30 struct v4l2_subdev *subdev = platform_get_drvdata(pdev);
33 priv = container_of(icd, struct soc_camera_platform_priv, icd); 31 return container_of(subdev, struct soc_camera_platform_priv, subdev);
34 return priv->info;
35}
36
37static int soc_camera_platform_init(struct soc_camera_device *icd)
38{
39 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
40
41 if (p->power)
42 p->power(1);
43
44 return 0;
45}
46
47static int soc_camera_platform_release(struct soc_camera_device *icd)
48{
49 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
50
51 if (p->power)
52 p->power(0);
53
54 return 0;
55} 32}
56 33
57static int soc_camera_platform_start_capture(struct soc_camera_device *icd) 34static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd)
58{ 35{
59 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 36 struct platform_device *pdev =
60 return p->set_capture(p, 1); 37 to_platform_device(to_soc_camera_control(icd));
38 return pdev->dev.platform_data;
61} 39}
62 40
63static int soc_camera_platform_stop_capture(struct soc_camera_device *icd) 41static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
64{ 42{
65 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 43 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
66 return p->set_capture(p, 0); 44 return p->set_capture(p, enable);
67} 45}
68 46
69static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd, 47static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
@@ -75,26 +53,14 @@ static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
75static unsigned long 53static unsigned long
76soc_camera_platform_query_bus_param(struct soc_camera_device *icd) 54soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
77{ 55{
78 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd); 56 struct soc_camera_platform_info *p = get_info(icd);
79 return p->bus_param; 57 return p->bus_param;
80} 58}
81 59
82static int soc_camera_platform_set_crop(struct soc_camera_device *icd, 60static int soc_camera_platform_try_fmt(struct v4l2_subdev *sd,
83 struct v4l2_rect *rect)
84{
85 return 0;
86}
87
88static int soc_camera_platform_set_fmt(struct soc_camera_device *icd,
89 struct v4l2_format *f) 61 struct v4l2_format *f)
90{ 62{
91 return 0; 63 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
92}
93
94static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
95 struct v4l2_format *f)
96{
97 struct soc_camera_platform_info *p = soc_camera_platform_get_info(icd);
98 struct v4l2_pix_format *pix = &f->fmt.pix; 64 struct v4l2_pix_format *pix = &f->fmt.pix;
99 65
100 pix->width = p->format.width; 66 pix->width = p->format.width;
@@ -102,82 +68,99 @@ static int soc_camera_platform_try_fmt(struct soc_camera_device *icd,
102 return 0; 68 return 0;
103} 69}
104 70
105static int soc_camera_platform_video_probe(struct soc_camera_device *icd) 71static void soc_camera_platform_video_probe(struct soc_camera_device *icd,
72 struct platform_device *pdev)
106{ 73{
107 struct soc_camera_platform_priv *priv; 74 struct soc_camera_platform_priv *priv = get_priv(pdev);
108 priv = container_of(icd, struct soc_camera_platform_priv, icd); 75 struct soc_camera_platform_info *p = pdev->dev.platform_data;
109 76
110 priv->format.name = priv->info->format_name; 77 priv->format.name = p->format_name;
111 priv->format.depth = priv->info->format_depth; 78 priv->format.depth = p->format_depth;
112 priv->format.fourcc = priv->info->format.pixelformat; 79 priv->format.fourcc = p->format.pixelformat;
113 priv->format.colorspace = priv->info->format.colorspace; 80 priv->format.colorspace = p->format.colorspace;
114 81
115 icd->formats = &priv->format; 82 icd->formats = &priv->format;
116 icd->num_formats = 1; 83 icd->num_formats = 1;
117
118 return soc_camera_video_start(icd);
119} 84}
120 85
121static void soc_camera_platform_video_remove(struct soc_camera_device *icd) 86static struct v4l2_subdev_core_ops platform_subdev_core_ops;
122{ 87
123 soc_camera_video_stop(icd); 88static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
124} 89 .s_stream = soc_camera_platform_s_stream,
90 .try_fmt = soc_camera_platform_try_fmt,
91};
92
93static struct v4l2_subdev_ops platform_subdev_ops = {
94 .core = &platform_subdev_core_ops,
95 .video = &platform_subdev_video_ops,
96};
125 97
126static struct soc_camera_ops soc_camera_platform_ops = { 98static struct soc_camera_ops soc_camera_platform_ops = {
127 .owner = THIS_MODULE,
128 .probe = soc_camera_platform_video_probe,
129 .remove = soc_camera_platform_video_remove,
130 .init = soc_camera_platform_init,
131 .release = soc_camera_platform_release,
132 .start_capture = soc_camera_platform_start_capture,
133 .stop_capture = soc_camera_platform_stop_capture,
134 .set_crop = soc_camera_platform_set_crop,
135 .set_fmt = soc_camera_platform_set_fmt,
136 .try_fmt = soc_camera_platform_try_fmt,
137 .set_bus_param = soc_camera_platform_set_bus_param, 99 .set_bus_param = soc_camera_platform_set_bus_param,
138 .query_bus_param = soc_camera_platform_query_bus_param, 100 .query_bus_param = soc_camera_platform_query_bus_param,
139}; 101};
140 102
141static int soc_camera_platform_probe(struct platform_device *pdev) 103static int soc_camera_platform_probe(struct platform_device *pdev)
142{ 104{
105 struct soc_camera_host *ici;
143 struct soc_camera_platform_priv *priv; 106 struct soc_camera_platform_priv *priv;
144 struct soc_camera_platform_info *p; 107 struct soc_camera_platform_info *p = pdev->dev.platform_data;
145 struct soc_camera_device *icd; 108 struct soc_camera_device *icd;
146 int ret; 109 int ret;
147 110
148 p = pdev->dev.platform_data;
149 if (!p) 111 if (!p)
150 return -EINVAL; 112 return -EINVAL;
151 113
114 if (!p->dev) {
115 dev_err(&pdev->dev,
116 "Platform has not set soc_camera_device pointer!\n");
117 return -EINVAL;
118 }
119
152 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 120 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
153 if (!priv) 121 if (!priv)
154 return -ENOMEM; 122 return -ENOMEM;
155 123
156 priv->info = p; 124 icd = to_soc_camera_dev(p->dev);
157 platform_set_drvdata(pdev, priv); 125
126 /* soc-camera convention: control's drvdata points to the subdev */
127 platform_set_drvdata(pdev, &priv->subdev);
128 /* Set the control device reference */
129 dev_set_drvdata(&icd->dev, &pdev->dev);
130
131 icd->y_skip_top = 0;
132 icd->ops = &soc_camera_platform_ops;
133
134 ici = to_soc_camera_host(icd->dev.parent);
158 135
159 icd = &priv->icd; 136 soc_camera_platform_video_probe(icd, pdev);
160 icd->ops = &soc_camera_platform_ops;
161 icd->control = &pdev->dev;
162 icd->width_min = 0;
163 icd->width_max = priv->info->format.width;
164 icd->height_min = 0;
165 icd->height_max = priv->info->format.height;
166 icd->y_skip_top = 0;
167 icd->iface = priv->info->iface;
168 137
169 ret = soc_camera_device_register(icd); 138 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
139 v4l2_set_subdevdata(&priv->subdev, p);
140 strncpy(priv->subdev.name, dev_name(&pdev->dev), V4L2_SUBDEV_NAME_SIZE);
141
142 ret = v4l2_device_register_subdev(&ici->v4l2_dev, &priv->subdev);
170 if (ret) 143 if (ret)
171 kfree(priv); 144 goto evdrs;
145
146 return ret;
172 147
148evdrs:
149 icd->ops = NULL;
150 platform_set_drvdata(pdev, NULL);
151 kfree(priv);
173 return ret; 152 return ret;
174} 153}
175 154
176static int soc_camera_platform_remove(struct platform_device *pdev) 155static int soc_camera_platform_remove(struct platform_device *pdev)
177{ 156{
178 struct soc_camera_platform_priv *priv = platform_get_drvdata(pdev); 157 struct soc_camera_platform_priv *priv = get_priv(pdev);
158 struct soc_camera_platform_info *p = pdev->dev.platform_data;
159 struct soc_camera_device *icd = to_soc_camera_dev(p->dev);
179 160
180 soc_camera_device_unregister(&priv->icd); 161 v4l2_device_unregister_subdev(&priv->subdev);
162 icd->ops = NULL;
163 platform_set_drvdata(pdev, NULL);
181 kfree(priv); 164 kfree(priv);
182 return 0; 165 return 0;
183} 166}
@@ -185,6 +168,7 @@ static int soc_camera_platform_remove(struct platform_device *pdev)
185static struct platform_driver soc_camera_platform_driver = { 168static struct platform_driver soc_camera_platform_driver = {
186 .driver = { 169 .driver = {
187 .name = "soc_camera_platform", 170 .name = "soc_camera_platform",
171 .owner = THIS_MODULE,
188 }, 172 },
189 .probe = soc_camera_platform_probe, 173 .probe = soc_camera_platform_probe,
190 .remove = soc_camera_platform_remove, 174 .remove = soc_camera_platform_remove,
@@ -206,3 +190,4 @@ module_exit(soc_camera_platform_module_exit);
206MODULE_DESCRIPTION("SoC Camera Platform driver"); 190MODULE_DESCRIPTION("SoC Camera Platform driver");
207MODULE_AUTHOR("Magnus Damm"); 191MODULE_AUTHOR("Magnus Damm");
208MODULE_LICENSE("GPL v2"); 192MODULE_LICENSE("GPL v2");
193MODULE_ALIAS("platform:soc_camera_platform");
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 2816f1839230..aba92e2313d8 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -29,6 +29,7 @@
29#include "tuner-simple.h" 29#include "tuner-simple.h"
30#include "tda9887.h" 30#include "tda9887.h"
31#include "xc5000.h" 31#include "xc5000.h"
32#include "tda18271.h"
32 33
33#define UNSET (-1U) 34#define UNSET (-1U)
34 35
@@ -420,6 +421,17 @@ static void set_type(struct i2c_client *c, unsigned int type,
420 goto attach_failed; 421 goto attach_failed;
421 break; 422 break;
422 } 423 }
424 case TUNER_NXP_TDA18271:
425 {
426 struct tda18271_config cfg = {
427 .config = t->config,
428 };
429
430 if (!dvb_attach(tda18271_attach, &t->fe, t->i2c->addr,
431 t->i2c->adapter, &cfg))
432 goto attach_failed;
433 break;
434 }
423 default: 435 default:
424 if (!dvb_attach(simple_tuner_attach, &t->fe, 436 if (!dvb_attach(simple_tuner_attach, &t->fe,
425 t->i2c->adapter, t->i2c->addr, t->type)) 437 t->i2c->adapter, t->i2c->addr, t->type))
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 3750f7fadb12..244372627df2 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -31,7 +31,10 @@
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/videodev2.h> 33#include <linux/videodev2.h>
34#include <media/v4l2-int-device.h> 34
35#include <media/v4l2-device.h>
36#include <media/v4l2-common.h>
37#include <media/v4l2-chip-ident.h>
35#include <media/tvp514x.h> 38#include <media/tvp514x.h>
36 39
37#include "tvp514x_regs.h" 40#include "tvp514x_regs.h"
@@ -49,15 +52,11 @@ static int debug;
49module_param(debug, bool, 0644); 52module_param(debug, bool, 0644);
50MODULE_PARM_DESC(debug, "Debug level (0-1)"); 53MODULE_PARM_DESC(debug, "Debug level (0-1)");
51 54
52#define dump_reg(client, reg, val) \ 55MODULE_AUTHOR("Texas Instruments");
53 do { \ 56MODULE_DESCRIPTION("TVP514X linux decoder driver");
54 val = tvp514x_read_reg(client, reg); \ 57MODULE_LICENSE("GPL");
55 v4l_info(client, "Reg(0x%.2X): 0x%.2X\n", reg, val); \
56 } while (0)
57 58
58/** 59/* enum tvp514x_std - enum for supported standards */
59 * enum tvp514x_std - enum for supported standards
60 */
61enum tvp514x_std { 60enum tvp514x_std {
62 STD_NTSC_MJ = 0, 61 STD_NTSC_MJ = 0,
63 STD_PAL_BDGHIN, 62 STD_PAL_BDGHIN,
@@ -65,14 +64,6 @@ enum tvp514x_std {
65}; 64};
66 65
67/** 66/**
68 * enum tvp514x_state - enum for different decoder states
69 */
70enum tvp514x_state {
71 STATE_NOT_DETECTED,
72 STATE_DETECTED
73};
74
75/**
76 * struct tvp514x_std_info - Structure to store standard informations 67 * struct tvp514x_std_info - Structure to store standard informations
77 * @width: Line width in pixels 68 * @width: Line width in pixels
78 * @height:Number of active lines 69 * @height:Number of active lines
@@ -89,33 +80,27 @@ struct tvp514x_std_info {
89static struct tvp514x_reg tvp514x_reg_list_default[0x40]; 80static struct tvp514x_reg tvp514x_reg_list_default[0x40];
90/** 81/**
91 * struct tvp514x_decoder - TVP5146/47 decoder object 82 * struct tvp514x_decoder - TVP5146/47 decoder object
92 * @v4l2_int_device: Slave handle 83 * @sd: Subdevice Slave handle
93 * @tvp514x_slave: Slave pointer which is used by @v4l2_int_device
94 * @tvp514x_regs: copy of hw's regs with preset values. 84 * @tvp514x_regs: copy of hw's regs with preset values.
95 * @pdata: Board specific 85 * @pdata: Board specific
96 * @client: I2C client data
97 * @id: Entry from I2C table
98 * @ver: Chip version 86 * @ver: Chip version
99 * @state: TVP5146/47 decoder state - detected or not-detected 87 * @streaming: TVP5146/47 decoder streaming - enabled or disabled.
100 * @pix: Current pixel format 88 * @pix: Current pixel format
101 * @num_fmts: Number of formats 89 * @num_fmts: Number of formats
102 * @fmt_list: Format list 90 * @fmt_list: Format list
103 * @current_std: Current standard 91 * @current_std: Current standard
104 * @num_stds: Number of standards 92 * @num_stds: Number of standards
105 * @std_list: Standards list 93 * @std_list: Standards list
106 * @route: input and output routing at chip level 94 * @input: Input routing at chip level
95 * @output: Output routing at chip level
107 */ 96 */
108struct tvp514x_decoder { 97struct tvp514x_decoder {
109 struct v4l2_int_device v4l2_int_device; 98 struct v4l2_subdev sd;
110 struct v4l2_int_slave tvp514x_slave;
111 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; 99 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
112 const struct tvp514x_platform_data *pdata; 100 const struct tvp514x_platform_data *pdata;
113 struct i2c_client *client;
114
115 struct i2c_device_id *id;
116 101
117 int ver; 102 int ver;
118 enum tvp514x_state state; 103 int streaming;
119 104
120 struct v4l2_pix_format pix; 105 struct v4l2_pix_format pix;
121 int num_fmts; 106 int num_fmts;
@@ -124,15 +109,18 @@ struct tvp514x_decoder {
124 enum tvp514x_std current_std; 109 enum tvp514x_std current_std;
125 int num_stds; 110 int num_stds;
126 struct tvp514x_std_info *std_list; 111 struct tvp514x_std_info *std_list;
127 112 /* Input and Output Routing parameters */
128 struct v4l2_routing route; 113 u32 input;
114 u32 output;
129}; 115};
130 116
131/* TVP514x default register values */ 117/* TVP514x default register values */
132static struct tvp514x_reg tvp514x_reg_list_default[] = { 118static struct tvp514x_reg tvp514x_reg_list_default[] = {
133 {TOK_WRITE, REG_INPUT_SEL, 0x05}, /* Composite selected */ 119 /* Composite selected */
120 {TOK_WRITE, REG_INPUT_SEL, 0x05},
134 {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F}, 121 {TOK_WRITE, REG_AFE_GAIN_CTRL, 0x0F},
135 {TOK_WRITE, REG_VIDEO_STD, 0x00}, /* Auto mode */ 122 /* Auto mode */
123 {TOK_WRITE, REG_VIDEO_STD, 0x00},
136 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 124 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
137 {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F}, 125 {TOK_SKIP, REG_AUTOSWITCH_MASK, 0x3F},
138 {TOK_WRITE, REG_COLOR_KILLER, 0x10}, 126 {TOK_WRITE, REG_COLOR_KILLER, 0x10},
@@ -145,53 +133,74 @@ static struct tvp514x_reg tvp514x_reg_list_default[] = {
145 {TOK_WRITE, REG_HUE, 0x00}, 133 {TOK_WRITE, REG_HUE, 0x00},
146 {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00}, 134 {TOK_WRITE, REG_CHROMA_CONTROL1, 0x00},
147 {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E}, 135 {TOK_WRITE, REG_CHROMA_CONTROL2, 0x0E},
148 {TOK_SKIP, 0x0F, 0x00}, /* Reserved */ 136 /* Reserved */
137 {TOK_SKIP, 0x0F, 0x00},
149 {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80}, 138 {TOK_WRITE, REG_COMP_PR_SATURATION, 0x80},
150 {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80}, 139 {TOK_WRITE, REG_COMP_Y_CONTRAST, 0x80},
151 {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80}, 140 {TOK_WRITE, REG_COMP_PB_SATURATION, 0x80},
152 {TOK_SKIP, 0x13, 0x00}, /* Reserved */ 141 /* Reserved */
142 {TOK_SKIP, 0x13, 0x00},
153 {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80}, 143 {TOK_WRITE, REG_COMP_Y_BRIGHTNESS, 0x80},
154 {TOK_SKIP, 0x15, 0x00}, /* Reserved */ 144 /* Reserved */
155 {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55}, /* NTSC timing */ 145 {TOK_SKIP, 0x15, 0x00},
146 /* NTSC timing */
147 {TOK_SKIP, REG_AVID_START_PIXEL_LSB, 0x55},
156 {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00}, 148 {TOK_SKIP, REG_AVID_START_PIXEL_MSB, 0x00},
157 {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25}, 149 {TOK_SKIP, REG_AVID_STOP_PIXEL_LSB, 0x25},
158 {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03}, 150 {TOK_SKIP, REG_AVID_STOP_PIXEL_MSB, 0x03},
159 {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00}, /* NTSC timing */ 151 /* NTSC timing */
152 {TOK_SKIP, REG_HSYNC_START_PIXEL_LSB, 0x00},
160 {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00}, 153 {TOK_SKIP, REG_HSYNC_START_PIXEL_MSB, 0x00},
161 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40}, 154 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_LSB, 0x40},
162 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00}, 155 {TOK_SKIP, REG_HSYNC_STOP_PIXEL_MSB, 0x00},
163 {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04}, /* NTSC timing */ 156 /* NTSC timing */
157 {TOK_SKIP, REG_VSYNC_START_LINE_LSB, 0x04},
164 {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00}, 158 {TOK_SKIP, REG_VSYNC_START_LINE_MSB, 0x00},
165 {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07}, 159 {TOK_SKIP, REG_VSYNC_STOP_LINE_LSB, 0x07},
166 {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00}, 160 {TOK_SKIP, REG_VSYNC_STOP_LINE_MSB, 0x00},
167 {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01}, /* NTSC timing */ 161 /* NTSC timing */
162 {TOK_SKIP, REG_VBLK_START_LINE_LSB, 0x01},
168 {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00}, 163 {TOK_SKIP, REG_VBLK_START_LINE_MSB, 0x00},
169 {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15}, 164 {TOK_SKIP, REG_VBLK_STOP_LINE_LSB, 0x15},
170 {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00}, 165 {TOK_SKIP, REG_VBLK_STOP_LINE_MSB, 0x00},
171 {TOK_SKIP, 0x26, 0x00}, /* Reserved */ 166 /* Reserved */
172 {TOK_SKIP, 0x27, 0x00}, /* Reserved */ 167 {TOK_SKIP, 0x26, 0x00},
168 /* Reserved */
169 {TOK_SKIP, 0x27, 0x00},
173 {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC}, 170 {TOK_SKIP, REG_FAST_SWTICH_CONTROL, 0xCC},
174 {TOK_SKIP, 0x29, 0x00}, /* Reserved */ 171 /* Reserved */
172 {TOK_SKIP, 0x29, 0x00},
175 {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00}, 173 {TOK_SKIP, REG_FAST_SWTICH_SCART_DELAY, 0x00},
176 {TOK_SKIP, 0x2B, 0x00}, /* Reserved */ 174 /* Reserved */
175 {TOK_SKIP, 0x2B, 0x00},
177 {TOK_SKIP, REG_SCART_DELAY, 0x00}, 176 {TOK_SKIP, REG_SCART_DELAY, 0x00},
178 {TOK_SKIP, REG_CTI_DELAY, 0x00}, 177 {TOK_SKIP, REG_CTI_DELAY, 0x00},
179 {TOK_SKIP, REG_CTI_CONTROL, 0x00}, 178 {TOK_SKIP, REG_CTI_CONTROL, 0x00},
180 {TOK_SKIP, 0x2F, 0x00}, /* Reserved */ 179 /* Reserved */
181 {TOK_SKIP, 0x30, 0x00}, /* Reserved */ 180 {TOK_SKIP, 0x2F, 0x00},
182 {TOK_SKIP, 0x31, 0x00}, /* Reserved */ 181 /* Reserved */
183 {TOK_WRITE, REG_SYNC_CONTROL, 0x00}, /* HS, VS active high */ 182 {TOK_SKIP, 0x30, 0x00},
184 {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00}, /* 10-bit BT.656 */ 183 /* Reserved */
185 {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11}, /* Enable clk & data */ 184 {TOK_SKIP, 0x31, 0x00},
186 {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE}, /* Enable AVID & FLD */ 185 /* HS, VS active high */
187 {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF}, /* Enable VS & HS */ 186 {TOK_WRITE, REG_SYNC_CONTROL, 0x00},
187 /* 10-bit BT.656 */
188 {TOK_WRITE, REG_OUTPUT_FORMATTER1, 0x00},
189 /* Enable clk & data */
190 {TOK_WRITE, REG_OUTPUT_FORMATTER2, 0x11},
191 /* Enable AVID & FLD */
192 {TOK_WRITE, REG_OUTPUT_FORMATTER3, 0xEE},
193 /* Enable VS & HS */
194 {TOK_WRITE, REG_OUTPUT_FORMATTER4, 0xAF},
188 {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF}, 195 {TOK_WRITE, REG_OUTPUT_FORMATTER5, 0xFF},
189 {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF}, 196 {TOK_WRITE, REG_OUTPUT_FORMATTER6, 0xFF},
190 {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01}, /* Clear status */ 197 /* Clear status */
198 {TOK_WRITE, REG_CLEAR_LOST_LOCK, 0x01},
191 {TOK_TERM, 0, 0}, 199 {TOK_TERM, 0, 0},
192}; 200};
193 201
194/* List of image formats supported by TVP5146/47 decoder 202/**
203 * List of image formats supported by TVP5146/47 decoder
195 * Currently we are using 8 bit mode only, but can be 204 * Currently we are using 8 bit mode only, but can be
196 * extended to 10/20 bit mode. 205 * extended to 10/20 bit mode.
197 */ 206 */
@@ -205,7 +214,7 @@ static const struct v4l2_fmtdesc tvp514x_fmt_list[] = {
205 }, 214 },
206}; 215};
207 216
208/* 217/**
209 * Supported standards - 218 * Supported standards -
210 * 219 *
211 * Currently supports two standards only, need to add support for rest of the 220 * Currently supports two standards only, need to add support for rest of the
@@ -240,35 +249,32 @@ static struct tvp514x_std_info tvp514x_std_list[] = {
240 }, 249 },
241 /* Standard: need to add for additional standard */ 250 /* Standard: need to add for additional standard */
242}; 251};
243/*
244 * Control structure for Auto Gain
245 * This is temporary data, will get replaced once
246 * v4l2_ctrl_query_fill supports it.
247 */
248static const struct v4l2_queryctrl tvp514x_autogain_ctrl = {
249 .id = V4L2_CID_AUTOGAIN,
250 .name = "Gain, Automatic",
251 .type = V4L2_CTRL_TYPE_BOOLEAN,
252 .minimum = 0,
253 .maximum = 1,
254 .step = 1,
255 .default_value = 1,
256};
257 252
258/* 253
259 * Read a value from a register in an TVP5146/47 decoder device. 254static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
255{
256 return container_of(sd, struct tvp514x_decoder, sd);
257}
258
259
260/**
261 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
262 * @sd: ptr to v4l2_subdev struct
263 * @reg: TVP5146/47 register address
264 *
260 * Returns value read if successful, or non-zero (-1) otherwise. 265 * Returns value read if successful, or non-zero (-1) otherwise.
261 */ 266 */
262static int tvp514x_read_reg(struct i2c_client *client, u8 reg) 267static int tvp514x_read_reg(struct v4l2_subdev *sd, u8 reg)
263{ 268{
264 int err; 269 int err, retry = 0;
265 int retry = 0; 270 struct i2c_client *client = v4l2_get_subdevdata(sd);
271
266read_again: 272read_again:
267 273
268 err = i2c_smbus_read_byte_data(client, reg); 274 err = i2c_smbus_read_byte_data(client, reg);
269 if (err == -1) { 275 if (err == -1) {
270 if (retry <= I2C_RETRY_COUNT) { 276 if (retry <= I2C_RETRY_COUNT) {
271 v4l_warn(client, "Read: retry ... %d\n", retry); 277 v4l2_warn(sd, "Read: retry ... %d\n", retry);
272 retry++; 278 retry++;
273 msleep_interruptible(10); 279 msleep_interruptible(10);
274 goto read_again; 280 goto read_again;
@@ -278,20 +284,39 @@ read_again:
278 return err; 284 return err;
279} 285}
280 286
281/* 287/**
288 * dump_reg() - dump the register content of TVP5146/47.
289 * @sd: ptr to v4l2_subdev struct
290 * @reg: TVP5146/47 register address
291 */
292static void dump_reg(struct v4l2_subdev *sd, u8 reg)
293{
294 u32 val;
295
296 val = tvp514x_read_reg(sd, reg);
297 v4l2_info(sd, "Reg(0x%.2X): 0x%.2X\n", reg, val);
298}
299
300/**
301 * tvp514x_write_reg() - Write a value to a register in TVP5146/47
302 * @sd: ptr to v4l2_subdev struct
303 * @reg: TVP5146/47 register address
304 * @val: value to be written to the register
305 *
282 * Write a value to a register in an TVP5146/47 decoder device. 306 * Write a value to a register in an TVP5146/47 decoder device.
283 * Returns zero if successful, or non-zero otherwise. 307 * Returns zero if successful, or non-zero otherwise.
284 */ 308 */
285static int tvp514x_write_reg(struct i2c_client *client, u8 reg, u8 val) 309static int tvp514x_write_reg(struct v4l2_subdev *sd, u8 reg, u8 val)
286{ 310{
287 int err; 311 int err, retry = 0;
288 int retry = 0; 312 struct i2c_client *client = v4l2_get_subdevdata(sd);
313
289write_again: 314write_again:
290 315
291 err = i2c_smbus_write_byte_data(client, reg, val); 316 err = i2c_smbus_write_byte_data(client, reg, val);
292 if (err) { 317 if (err) {
293 if (retry <= I2C_RETRY_COUNT) { 318 if (retry <= I2C_RETRY_COUNT) {
294 v4l_warn(client, "Write: retry ... %d\n", retry); 319 v4l2_warn(sd, "Write: retry ... %d\n", retry);
295 retry++; 320 retry++;
296 msleep_interruptible(10); 321 msleep_interruptible(10);
297 goto write_again; 322 goto write_again;
@@ -301,17 +326,19 @@ write_again:
301 return err; 326 return err;
302} 327}
303 328
304/* 329/**
305 * tvp514x_write_regs : Initializes a list of TVP5146/47 registers 330 * tvp514x_write_regs() : Initializes a list of TVP5146/47 registers
331 * @sd: ptr to v4l2_subdev struct
332 * @reglist: list of TVP5146/47 registers and values
333 *
334 * Initializes a list of TVP5146/47 registers:-
306 * if token is TOK_TERM, then entire write operation terminates 335 * if token is TOK_TERM, then entire write operation terminates
307 * if token is TOK_DELAY, then a delay of 'val' msec is introduced 336 * if token is TOK_DELAY, then a delay of 'val' msec is introduced
308 * if token is TOK_SKIP, then the register write is skipped 337 * if token is TOK_SKIP, then the register write is skipped
309 * if token is TOK_WRITE, then the register write is performed 338 * if token is TOK_WRITE, then the register write is performed
310 *
311 * reglist - list of registers to be written
312 * Returns zero if successful, or non-zero otherwise. 339 * Returns zero if successful, or non-zero otherwise.
313 */ 340 */
314static int tvp514x_write_regs(struct i2c_client *client, 341static int tvp514x_write_regs(struct v4l2_subdev *sd,
315 const struct tvp514x_reg reglist[]) 342 const struct tvp514x_reg reglist[])
316{ 343{
317 int err; 344 int err;
@@ -326,31 +353,33 @@ static int tvp514x_write_regs(struct i2c_client *client,
326 if (next->token == TOK_SKIP) 353 if (next->token == TOK_SKIP)
327 continue; 354 continue;
328 355
329 err = tvp514x_write_reg(client, next->reg, (u8) next->val); 356 err = tvp514x_write_reg(sd, next->reg, (u8) next->val);
330 if (err) { 357 if (err) {
331 v4l_err(client, "Write failed. Err[%d]\n", err); 358 v4l2_err(sd, "Write failed. Err[%d]\n", err);
332 return err; 359 return err;
333 } 360 }
334 } 361 }
335 return 0; 362 return 0;
336} 363}
337 364
338/* 365/**
339 * tvp514x_get_current_std: 366 * tvp514x_get_current_std() : Get the current standard detected by TVP5146/47
340 * Returns the current standard detected by TVP5146/47 367 * @sd: ptr to v4l2_subdev struct
368 *
369 * Get current standard detected by TVP5146/47, STD_INVALID if there is no
370 * standard detected.
341 */ 371 */
342static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder 372static enum tvp514x_std tvp514x_get_current_std(struct v4l2_subdev *sd)
343 *decoder)
344{ 373{
345 u8 std, std_status; 374 u8 std, std_status;
346 375
347 std = tvp514x_read_reg(decoder->client, REG_VIDEO_STD); 376 std = tvp514x_read_reg(sd, REG_VIDEO_STD);
348 if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT) { 377 if ((std & VIDEO_STD_MASK) == VIDEO_STD_AUTO_SWITCH_BIT)
349 /* use the standard status register */ 378 /* use the standard status register */
350 std_status = tvp514x_read_reg(decoder->client, 379 std_status = tvp514x_read_reg(sd, REG_VIDEO_STD_STATUS);
351 REG_VIDEO_STD_STATUS); 380 else
352 } else 381 /* use the standard register itself */
353 std_status = std; /* use the standard register itself */ 382 std_status = std;
354 383
355 switch (std_status & VIDEO_STD_MASK) { 384 switch (std_status & VIDEO_STD_MASK) {
356 case VIDEO_STD_NTSC_MJ_BIT: 385 case VIDEO_STD_NTSC_MJ_BIT:
@@ -366,94 +395,99 @@ static enum tvp514x_std tvp514x_get_current_std(struct tvp514x_decoder
366 return STD_INVALID; 395 return STD_INVALID;
367} 396}
368 397
369/* 398/* TVP5146/47 register dump function */
370 * TVP5146/47 register dump function 399static void tvp514x_reg_dump(struct v4l2_subdev *sd)
371 */
372static void tvp514x_reg_dump(struct tvp514x_decoder *decoder)
373{ 400{
374 u8 value; 401 dump_reg(sd, REG_INPUT_SEL);
375 402 dump_reg(sd, REG_AFE_GAIN_CTRL);
376 dump_reg(decoder->client, REG_INPUT_SEL, value); 403 dump_reg(sd, REG_VIDEO_STD);
377 dump_reg(decoder->client, REG_AFE_GAIN_CTRL, value); 404 dump_reg(sd, REG_OPERATION_MODE);
378 dump_reg(decoder->client, REG_VIDEO_STD, value); 405 dump_reg(sd, REG_COLOR_KILLER);
379 dump_reg(decoder->client, REG_OPERATION_MODE, value); 406 dump_reg(sd, REG_LUMA_CONTROL1);
380 dump_reg(decoder->client, REG_COLOR_KILLER, value); 407 dump_reg(sd, REG_LUMA_CONTROL2);
381 dump_reg(decoder->client, REG_LUMA_CONTROL1, value); 408 dump_reg(sd, REG_LUMA_CONTROL3);
382 dump_reg(decoder->client, REG_LUMA_CONTROL2, value); 409 dump_reg(sd, REG_BRIGHTNESS);
383 dump_reg(decoder->client, REG_LUMA_CONTROL3, value); 410 dump_reg(sd, REG_CONTRAST);
384 dump_reg(decoder->client, REG_BRIGHTNESS, value); 411 dump_reg(sd, REG_SATURATION);
385 dump_reg(decoder->client, REG_CONTRAST, value); 412 dump_reg(sd, REG_HUE);
386 dump_reg(decoder->client, REG_SATURATION, value); 413 dump_reg(sd, REG_CHROMA_CONTROL1);
387 dump_reg(decoder->client, REG_HUE, value); 414 dump_reg(sd, REG_CHROMA_CONTROL2);
388 dump_reg(decoder->client, REG_CHROMA_CONTROL1, value); 415 dump_reg(sd, REG_COMP_PR_SATURATION);
389 dump_reg(decoder->client, REG_CHROMA_CONTROL2, value); 416 dump_reg(sd, REG_COMP_Y_CONTRAST);
390 dump_reg(decoder->client, REG_COMP_PR_SATURATION, value); 417 dump_reg(sd, REG_COMP_PB_SATURATION);
391 dump_reg(decoder->client, REG_COMP_Y_CONTRAST, value); 418 dump_reg(sd, REG_COMP_Y_BRIGHTNESS);
392 dump_reg(decoder->client, REG_COMP_PB_SATURATION, value); 419 dump_reg(sd, REG_AVID_START_PIXEL_LSB);
393 dump_reg(decoder->client, REG_COMP_Y_BRIGHTNESS, value); 420 dump_reg(sd, REG_AVID_START_PIXEL_MSB);
394 dump_reg(decoder->client, REG_AVID_START_PIXEL_LSB, value); 421 dump_reg(sd, REG_AVID_STOP_PIXEL_LSB);
395 dump_reg(decoder->client, REG_AVID_START_PIXEL_MSB, value); 422 dump_reg(sd, REG_AVID_STOP_PIXEL_MSB);
396 dump_reg(decoder->client, REG_AVID_STOP_PIXEL_LSB, value); 423 dump_reg(sd, REG_HSYNC_START_PIXEL_LSB);
397 dump_reg(decoder->client, REG_AVID_STOP_PIXEL_MSB, value); 424 dump_reg(sd, REG_HSYNC_START_PIXEL_MSB);
398 dump_reg(decoder->client, REG_HSYNC_START_PIXEL_LSB, value); 425 dump_reg(sd, REG_HSYNC_STOP_PIXEL_LSB);
399 dump_reg(decoder->client, REG_HSYNC_START_PIXEL_MSB, value); 426 dump_reg(sd, REG_HSYNC_STOP_PIXEL_MSB);
400 dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_LSB, value); 427 dump_reg(sd, REG_VSYNC_START_LINE_LSB);
401 dump_reg(decoder->client, REG_HSYNC_STOP_PIXEL_MSB, value); 428 dump_reg(sd, REG_VSYNC_START_LINE_MSB);
402 dump_reg(decoder->client, REG_VSYNC_START_LINE_LSB, value); 429 dump_reg(sd, REG_VSYNC_STOP_LINE_LSB);
403 dump_reg(decoder->client, REG_VSYNC_START_LINE_MSB, value); 430 dump_reg(sd, REG_VSYNC_STOP_LINE_MSB);
404 dump_reg(decoder->client, REG_VSYNC_STOP_LINE_LSB, value); 431 dump_reg(sd, REG_VBLK_START_LINE_LSB);
405 dump_reg(decoder->client, REG_VSYNC_STOP_LINE_MSB, value); 432 dump_reg(sd, REG_VBLK_START_LINE_MSB);
406 dump_reg(decoder->client, REG_VBLK_START_LINE_LSB, value); 433 dump_reg(sd, REG_VBLK_STOP_LINE_LSB);
407 dump_reg(decoder->client, REG_VBLK_START_LINE_MSB, value); 434 dump_reg(sd, REG_VBLK_STOP_LINE_MSB);
408 dump_reg(decoder->client, REG_VBLK_STOP_LINE_LSB, value); 435 dump_reg(sd, REG_SYNC_CONTROL);
409 dump_reg(decoder->client, REG_VBLK_STOP_LINE_MSB, value); 436 dump_reg(sd, REG_OUTPUT_FORMATTER1);
410 dump_reg(decoder->client, REG_SYNC_CONTROL, value); 437 dump_reg(sd, REG_OUTPUT_FORMATTER2);
411 dump_reg(decoder->client, REG_OUTPUT_FORMATTER1, value); 438 dump_reg(sd, REG_OUTPUT_FORMATTER3);
412 dump_reg(decoder->client, REG_OUTPUT_FORMATTER2, value); 439 dump_reg(sd, REG_OUTPUT_FORMATTER4);
413 dump_reg(decoder->client, REG_OUTPUT_FORMATTER3, value); 440 dump_reg(sd, REG_OUTPUT_FORMATTER5);
414 dump_reg(decoder->client, REG_OUTPUT_FORMATTER4, value); 441 dump_reg(sd, REG_OUTPUT_FORMATTER6);
415 dump_reg(decoder->client, REG_OUTPUT_FORMATTER5, value); 442 dump_reg(sd, REG_CLEAR_LOST_LOCK);
416 dump_reg(decoder->client, REG_OUTPUT_FORMATTER6, value);
417 dump_reg(decoder->client, REG_CLEAR_LOST_LOCK, value);
418} 443}
419 444
420/* 445/**
421 * Configure the TVP5146/47 with the current register settings 446 * tvp514x_configure() - Configure the TVP5146/47 registers
447 * @sd: ptr to v4l2_subdev struct
448 * @decoder: ptr to tvp514x_decoder structure
449 *
422 * Returns zero if successful, or non-zero otherwise. 450 * Returns zero if successful, or non-zero otherwise.
423 */ 451 */
424static int tvp514x_configure(struct tvp514x_decoder *decoder) 452static int tvp514x_configure(struct v4l2_subdev *sd,
453 struct tvp514x_decoder *decoder)
425{ 454{
426 int err; 455 int err;
427 456
428 /* common register initialization */ 457 /* common register initialization */
429 err = 458 err =
430 tvp514x_write_regs(decoder->client, decoder->tvp514x_regs); 459 tvp514x_write_regs(sd, decoder->tvp514x_regs);
431 if (err) 460 if (err)
432 return err; 461 return err;
433 462
434 if (debug) 463 if (debug)
435 tvp514x_reg_dump(decoder); 464 tvp514x_reg_dump(sd);
436 465
437 return 0; 466 return 0;
438} 467}
439 468
440/* 469/**
441 * Detect if an tvp514x is present, and if so which revision. 470 * tvp514x_detect() - Detect if an tvp514x is present, and if so which revision.
471 * @sd: pointer to standard V4L2 sub-device structure
472 * @decoder: pointer to tvp514x_decoder structure
473 *
442 * A device is considered to be detected if the chip ID (LSB and MSB) 474 * A device is considered to be detected if the chip ID (LSB and MSB)
443 * registers match the expected values. 475 * registers match the expected values.
444 * Any value of the rom version register is accepted. 476 * Any value of the rom version register is accepted.
445 * Returns ENODEV error number if no device is detected, or zero 477 * Returns ENODEV error number if no device is detected, or zero
446 * if a device is detected. 478 * if a device is detected.
447 */ 479 */
448static int tvp514x_detect(struct tvp514x_decoder *decoder) 480static int tvp514x_detect(struct v4l2_subdev *sd,
481 struct tvp514x_decoder *decoder)
449{ 482{
450 u8 chip_id_msb, chip_id_lsb, rom_ver; 483 u8 chip_id_msb, chip_id_lsb, rom_ver;
484 struct i2c_client *client = v4l2_get_subdevdata(sd);
451 485
452 chip_id_msb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_MSB); 486 chip_id_msb = tvp514x_read_reg(sd, REG_CHIP_ID_MSB);
453 chip_id_lsb = tvp514x_read_reg(decoder->client, REG_CHIP_ID_LSB); 487 chip_id_lsb = tvp514x_read_reg(sd, REG_CHIP_ID_LSB);
454 rom_ver = tvp514x_read_reg(decoder->client, REG_ROM_VERSION); 488 rom_ver = tvp514x_read_reg(sd, REG_ROM_VERSION);
455 489
456 v4l_dbg(1, debug, decoder->client, 490 v4l2_dbg(1, debug, sd,
457 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n", 491 "chip id detected msb:0x%x lsb:0x%x rom version:0x%x\n",
458 chip_id_msb, chip_id_lsb, rom_ver); 492 chip_id_msb, chip_id_lsb, rom_ver);
459 if ((chip_id_msb != TVP514X_CHIP_ID_MSB) 493 if ((chip_id_msb != TVP514X_CHIP_ID_MSB)
@@ -462,38 +496,30 @@ static int tvp514x_detect(struct tvp514x_decoder *decoder)
462 /* We didn't read the values we expected, so this must not be 496 /* We didn't read the values we expected, so this must not be
463 * an TVP5146/47. 497 * an TVP5146/47.
464 */ 498 */
465 v4l_err(decoder->client, 499 v4l2_err(sd, "chip id mismatch msb:0x%x lsb:0x%x\n",
466 "chip id mismatch msb:0x%x lsb:0x%x\n", 500 chip_id_msb, chip_id_lsb);
467 chip_id_msb, chip_id_lsb);
468 return -ENODEV; 501 return -ENODEV;
469 } 502 }
470 503
471 decoder->ver = rom_ver; 504 decoder->ver = rom_ver;
472 decoder->state = STATE_DETECTED;
473 505
474 v4l_info(decoder->client, 506 v4l2_info(sd, "%s (Version - 0x%.2x) found at 0x%x (%s)\n",
475 "%s found at 0x%x (%s)\n", decoder->client->name, 507 client->name, decoder->ver,
476 decoder->client->addr << 1, 508 client->addr << 1, client->adapter->name);
477 decoder->client->adapter->name);
478 return 0; 509 return 0;
479} 510}
480 511
481/*
482 * Following are decoder interface functions implemented by
483 * TVP5146/47 decoder driver.
484 */
485
486/** 512/**
487 * ioctl_querystd - V4L2 decoder interface handler for VIDIOC_QUERYSTD ioctl 513 * tvp514x_querystd() - V4L2 decoder interface handler for querystd
488 * @s: pointer to standard V4L2 device structure 514 * @sd: pointer to standard V4L2 sub-device structure
489 * @std_id: standard V4L2 std_id ioctl enum 515 * @std_id: standard V4L2 std_id ioctl enum
490 * 516 *
491 * Returns the current standard detected by TVP5146/47. If no active input is 517 * Returns the current standard detected by TVP5146/47. If no active input is
492 * detected, returns -EINVAL 518 * detected, returns -EINVAL
493 */ 519 */
494static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id) 520static int tvp514x_querystd(struct v4l2_subdev *sd, v4l2_std_id *std_id)
495{ 521{
496 struct tvp514x_decoder *decoder = s->priv; 522 struct tvp514x_decoder *decoder = to_decoder(sd);
497 enum tvp514x_std current_std; 523 enum tvp514x_std current_std;
498 enum tvp514x_input input_sel; 524 enum tvp514x_input input_sel;
499 u8 sync_lock_status, lock_mask; 525 u8 sync_lock_status, lock_mask;
@@ -502,11 +528,11 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
502 return -EINVAL; 528 return -EINVAL;
503 529
504 /* get the current standard */ 530 /* get the current standard */
505 current_std = tvp514x_get_current_std(decoder); 531 current_std = tvp514x_get_current_std(sd);
506 if (current_std == STD_INVALID) 532 if (current_std == STD_INVALID)
507 return -EINVAL; 533 return -EINVAL;
508 534
509 input_sel = decoder->route.input; 535 input_sel = decoder->input;
510 536
511 switch (input_sel) { 537 switch (input_sel) {
512 case INPUT_CVBS_VI1A: 538 case INPUT_CVBS_VI1A:
@@ -544,42 +570,39 @@ static int ioctl_querystd(struct v4l2_int_device *s, v4l2_std_id *std_id)
544 return -EINVAL; 570 return -EINVAL;
545 } 571 }
546 /* check whether signal is locked */ 572 /* check whether signal is locked */
547 sync_lock_status = tvp514x_read_reg(decoder->client, REG_STATUS1); 573 sync_lock_status = tvp514x_read_reg(sd, REG_STATUS1);
548 if (lock_mask != (sync_lock_status & lock_mask)) 574 if (lock_mask != (sync_lock_status & lock_mask))
549 return -EINVAL; /* No input detected */ 575 return -EINVAL; /* No input detected */
550 576
551 decoder->current_std = current_std; 577 decoder->current_std = current_std;
552 *std_id = decoder->std_list[current_std].standard.id; 578 *std_id = decoder->std_list[current_std].standard.id;
553 579
554 v4l_dbg(1, debug, decoder->client, "Current STD: %s", 580 v4l2_dbg(1, debug, sd, "Current STD: %s",
555 decoder->std_list[current_std].standard.name); 581 decoder->std_list[current_std].standard.name);
556 return 0; 582 return 0;
557} 583}
558 584
559/** 585/**
560 * ioctl_s_std - V4L2 decoder interface handler for VIDIOC_S_STD ioctl 586 * tvp514x_s_std() - V4L2 decoder interface handler for s_std
561 * @s: pointer to standard V4L2 device structure 587 * @sd: pointer to standard V4L2 sub-device structure
562 * @std_id: standard V4L2 v4l2_std_id ioctl enum 588 * @std_id: standard V4L2 v4l2_std_id ioctl enum
563 * 589 *
564 * If std_id is supported, sets the requested standard. Otherwise, returns 590 * If std_id is supported, sets the requested standard. Otherwise, returns
565 * -EINVAL 591 * -EINVAL
566 */ 592 */
567static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id) 593static int tvp514x_s_std(struct v4l2_subdev *sd, v4l2_std_id std_id)
568{ 594{
569 struct tvp514x_decoder *decoder = s->priv; 595 struct tvp514x_decoder *decoder = to_decoder(sd);
570 int err, i; 596 int err, i;
571 597
572 if (std_id == NULL)
573 return -EINVAL;
574
575 for (i = 0; i < decoder->num_stds; i++) 598 for (i = 0; i < decoder->num_stds; i++)
576 if (*std_id & decoder->std_list[i].standard.id) 599 if (std_id & decoder->std_list[i].standard.id)
577 break; 600 break;
578 601
579 if ((i == decoder->num_stds) || (i == STD_INVALID)) 602 if ((i == decoder->num_stds) || (i == STD_INVALID))
580 return -EINVAL; 603 return -EINVAL;
581 604
582 err = tvp514x_write_reg(decoder->client, REG_VIDEO_STD, 605 err = tvp514x_write_reg(sd, REG_VIDEO_STD,
583 decoder->std_list[i].video_std); 606 decoder->std_list[i].video_std);
584 if (err) 607 if (err)
585 return err; 608 return err;
@@ -588,24 +611,26 @@ static int ioctl_s_std(struct v4l2_int_device *s, v4l2_std_id *std_id)
588 decoder->tvp514x_regs[REG_VIDEO_STD].val = 611 decoder->tvp514x_regs[REG_VIDEO_STD].val =
589 decoder->std_list[i].video_std; 612 decoder->std_list[i].video_std;
590 613
591 v4l_dbg(1, debug, decoder->client, "Standard set to: %s", 614 v4l2_dbg(1, debug, sd, "Standard set to: %s",
592 decoder->std_list[i].standard.name); 615 decoder->std_list[i].standard.name);
593 return 0; 616 return 0;
594} 617}
595 618
596/** 619/**
597 * ioctl_s_routing - V4L2 decoder interface handler for VIDIOC_S_INPUT ioctl 620 * tvp514x_s_routing() - V4L2 decoder interface handler for s_routing
598 * @s: pointer to standard V4L2 device structure 621 * @sd: pointer to standard V4L2 sub-device structure
599 * @index: number of the input 622 * @input: input selector for routing the signal
623 * @output: output selector for routing the signal
624 * @config: config value. Not used
600 * 625 *
601 * If index is valid, selects the requested input. Otherwise, returns -EINVAL if 626 * If index is valid, selects the requested input. Otherwise, returns -EINVAL if
602 * the input is not supported or there is no active signal present in the 627 * the input is not supported or there is no active signal present in the
603 * selected input. 628 * selected input.
604 */ 629 */
605static int ioctl_s_routing(struct v4l2_int_device *s, 630static int tvp514x_s_routing(struct v4l2_subdev *sd,
606 struct v4l2_routing *route) 631 u32 input, u32 output, u32 config)
607{ 632{
608 struct tvp514x_decoder *decoder = s->priv; 633 struct tvp514x_decoder *decoder = to_decoder(sd);
609 int err; 634 int err;
610 enum tvp514x_input input_sel; 635 enum tvp514x_input input_sel;
611 enum tvp514x_output output_sel; 636 enum tvp514x_output output_sel;
@@ -613,20 +638,21 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
613 u8 sync_lock_status, lock_mask; 638 u8 sync_lock_status, lock_mask;
614 int try_count = LOCK_RETRY_COUNT; 639 int try_count = LOCK_RETRY_COUNT;
615 640
616 if ((!route) || (route->input >= INPUT_INVALID) || 641 if ((input >= INPUT_INVALID) ||
617 (route->output >= OUTPUT_INVALID)) 642 (output >= OUTPUT_INVALID))
618 return -EINVAL; /* Index out of bound */ 643 /* Index out of bound */
644 return -EINVAL;
619 645
620 input_sel = route->input; 646 input_sel = input;
621 output_sel = route->output; 647 output_sel = output;
622 648
623 err = tvp514x_write_reg(decoder->client, REG_INPUT_SEL, input_sel); 649 err = tvp514x_write_reg(sd, REG_INPUT_SEL, input_sel);
624 if (err) 650 if (err)
625 return err; 651 return err;
626 652
627 output_sel |= tvp514x_read_reg(decoder->client, 653 output_sel |= tvp514x_read_reg(sd,
628 REG_OUTPUT_FORMATTER1) & 0x7; 654 REG_OUTPUT_FORMATTER1) & 0x7;
629 err = tvp514x_write_reg(decoder->client, REG_OUTPUT_FORMATTER1, 655 err = tvp514x_write_reg(sd, REG_OUTPUT_FORMATTER1,
630 output_sel); 656 output_sel);
631 if (err) 657 if (err)
632 return err; 658 return err;
@@ -637,7 +663,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
637 /* Clear status */ 663 /* Clear status */
638 msleep(LOCK_RETRY_DELAY); 664 msleep(LOCK_RETRY_DELAY);
639 err = 665 err =
640 tvp514x_write_reg(decoder->client, REG_CLEAR_LOST_LOCK, 0x01); 666 tvp514x_write_reg(sd, REG_CLEAR_LOST_LOCK, 0x01);
641 if (err) 667 if (err)
642 return err; 668 return err;
643 669
@@ -672,7 +698,7 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
672 lock_mask = STATUS_HORZ_SYNC_LOCK_BIT | 698 lock_mask = STATUS_HORZ_SYNC_LOCK_BIT |
673 STATUS_VIRT_SYNC_LOCK_BIT; 699 STATUS_VIRT_SYNC_LOCK_BIT;
674 break; 700 break;
675 /*Need to add other interfaces*/ 701 /* Need to add other interfaces*/
676 default: 702 default:
677 return -EINVAL; 703 return -EINVAL;
678 } 704 }
@@ -682,42 +708,41 @@ static int ioctl_s_routing(struct v4l2_int_device *s,
682 msleep(LOCK_RETRY_DELAY); 708 msleep(LOCK_RETRY_DELAY);
683 709
684 /* get the current standard for future reference */ 710 /* get the current standard for future reference */
685 current_std = tvp514x_get_current_std(decoder); 711 current_std = tvp514x_get_current_std(sd);
686 if (current_std == STD_INVALID) 712 if (current_std == STD_INVALID)
687 continue; 713 continue;
688 714
689 sync_lock_status = tvp514x_read_reg(decoder->client, 715 sync_lock_status = tvp514x_read_reg(sd,
690 REG_STATUS1); 716 REG_STATUS1);
691 if (lock_mask == (sync_lock_status & lock_mask)) 717 if (lock_mask == (sync_lock_status & lock_mask))
692 break; /* Input detected */ 718 /* Input detected */
719 break;
693 } 720 }
694 721
695 if ((current_std == STD_INVALID) || (try_count < 0)) 722 if ((current_std == STD_INVALID) || (try_count < 0))
696 return -EINVAL; 723 return -EINVAL;
697 724
698 decoder->current_std = current_std; 725 decoder->current_std = current_std;
699 decoder->route.input = route->input; 726 decoder->input = input;
700 decoder->route.output = route->output; 727 decoder->output = output;
701 728
702 v4l_dbg(1, debug, decoder->client, 729 v4l2_dbg(1, debug, sd, "Input set to: %d, std : %d",
703 "Input set to: %d, std : %d",
704 input_sel, current_std); 730 input_sel, current_std);
705 731
706 return 0; 732 return 0;
707} 733}
708 734
709/** 735/**
710 * ioctl_queryctrl - V4L2 decoder interface handler for VIDIOC_QUERYCTRL ioctl 736 * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
711 * @s: pointer to standard V4L2 device structure 737 * @sd: pointer to standard V4L2 sub-device structure
712 * @qctrl: standard V4L2 v4l2_queryctrl structure 738 * @qctrl: standard V4L2 v4l2_queryctrl structure
713 * 739 *
714 * If the requested control is supported, returns the control information. 740 * If the requested control is supported, returns the control information.
715 * Otherwise, returns -EINVAL if the control is not supported. 741 * Otherwise, returns -EINVAL if the control is not supported.
716 */ 742 */
717static int 743static int
718ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl) 744tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
719{ 745{
720 struct tvp514x_decoder *decoder = s->priv;
721 int err = -EINVAL; 746 int err = -EINVAL;
722 747
723 if (qctrl == NULL) 748 if (qctrl == NULL)
@@ -725,13 +750,13 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
725 750
726 switch (qctrl->id) { 751 switch (qctrl->id) {
727 case V4L2_CID_BRIGHTNESS: 752 case V4L2_CID_BRIGHTNESS:
728 /* Brightness supported is (0-255), 753 /* Brightness supported is (0-255), */
729 */
730 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128); 754 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
731 break; 755 break;
732 case V4L2_CID_CONTRAST: 756 case V4L2_CID_CONTRAST:
733 case V4L2_CID_SATURATION: 757 case V4L2_CID_SATURATION:
734 /* Saturation and Contrast supported is - 758 /**
759 * Saturation and Contrast supported is -
735 * Contrast: 0 - 255 (Default - 128) 760 * Contrast: 0 - 255 (Default - 128)
736 * Saturation: 0 - 255 (Default - 128) 761 * Saturation: 0 - 255 (Default - 128)
737 */ 762 */
@@ -744,30 +769,27 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
744 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0); 769 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
745 break; 770 break;
746 case V4L2_CID_AUTOGAIN: 771 case V4L2_CID_AUTOGAIN:
747 /* Autogain is either 0 or 1*/ 772 /**
748 memcpy(qctrl, &tvp514x_autogain_ctrl, 773 * Auto Gain supported is -
749 sizeof(struct v4l2_queryctrl)); 774 * 0 - 1 (Default - 1)
750 err = 0; 775 */
776 err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
751 break; 777 break;
752 default: 778 default:
753 v4l_err(decoder->client, 779 v4l2_err(sd, "invalid control id %d\n", qctrl->id);
754 "invalid control id %d\n", qctrl->id);
755 return err; 780 return err;
756 } 781 }
757 782
758 v4l_dbg(1, debug, decoder->client, 783 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d",
759 "Query Control: %s : Min - %d, Max - %d, Def - %d", 784 qctrl->name, qctrl->minimum, qctrl->maximum,
760 qctrl->name,
761 qctrl->minimum,
762 qctrl->maximum,
763 qctrl->default_value); 785 qctrl->default_value);
764 786
765 return err; 787 return err;
766} 788}
767 789
768/** 790/**
769 * ioctl_g_ctrl - V4L2 decoder interface handler for VIDIOC_G_CTRL ioctl 791 * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
770 * @s: pointer to standard V4L2 device structure 792 * @sd: pointer to standard V4L2 sub-device structure
771 * @ctrl: pointer to v4l2_control structure 793 * @ctrl: pointer to v4l2_control structure
772 * 794 *
773 * If the requested control is supported, returns the control's current 795 * If the requested control is supported, returns the control's current
@@ -775,9 +797,9 @@ ioctl_queryctrl(struct v4l2_int_device *s, struct v4l2_queryctrl *qctrl)
775 * supported. 797 * supported.
776 */ 798 */
777static int 799static int
778ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) 800tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
779{ 801{
780 struct tvp514x_decoder *decoder = s->priv; 802 struct tvp514x_decoder *decoder = to_decoder(sd);
781 803
782 if (ctrl == NULL) 804 if (ctrl == NULL)
783 return -EINVAL; 805 return -EINVAL;
@@ -811,74 +833,70 @@ ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
811 833
812 break; 834 break;
813 default: 835 default:
814 v4l_err(decoder->client, 836 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
815 "invalid control id %d\n", ctrl->id);
816 return -EINVAL; 837 return -EINVAL;
817 } 838 }
818 839
819 v4l_dbg(1, debug, decoder->client, 840 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d",
820 "Get Control: ID - %d - %d",
821 ctrl->id, ctrl->value); 841 ctrl->id, ctrl->value);
822 return 0; 842 return 0;
823} 843}
824 844
825/** 845/**
826 * ioctl_s_ctrl - V4L2 decoder interface handler for VIDIOC_S_CTRL ioctl 846 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
827 * @s: pointer to standard V4L2 device structure 847 * @sd: pointer to standard V4L2 sub-device structure
828 * @ctrl: pointer to v4l2_control structure 848 * @ctrl: pointer to v4l2_control structure
829 * 849 *
830 * If the requested control is supported, sets the control's current 850 * If the requested control is supported, sets the control's current
831 * value in HW. Otherwise, returns -EINVAL if the control is not supported. 851 * value in HW. Otherwise, returns -EINVAL if the control is not supported.
832 */ 852 */
833static int 853static int
834ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl) 854tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
835{ 855{
836 struct tvp514x_decoder *decoder = s->priv; 856 struct tvp514x_decoder *decoder = to_decoder(sd);
837 int err = -EINVAL, value; 857 int err = -EINVAL, value;
838 858
839 if (ctrl == NULL) 859 if (ctrl == NULL)
840 return err; 860 return err;
841 861
842 value = (__s32) ctrl->value; 862 value = ctrl->value;
843 863
844 switch (ctrl->id) { 864 switch (ctrl->id) {
845 case V4L2_CID_BRIGHTNESS: 865 case V4L2_CID_BRIGHTNESS:
846 if (ctrl->value < 0 || ctrl->value > 255) { 866 if (ctrl->value < 0 || ctrl->value > 255) {
847 v4l_err(decoder->client, 867 v4l2_err(sd, "invalid brightness setting %d\n",
848 "invalid brightness setting %d\n",
849 ctrl->value); 868 ctrl->value);
850 return -ERANGE; 869 return -ERANGE;
851 } 870 }
852 err = tvp514x_write_reg(decoder->client, REG_BRIGHTNESS, 871 err = tvp514x_write_reg(sd, REG_BRIGHTNESS,
853 value); 872 value);
854 if (err) 873 if (err)
855 return err; 874 return err;
875
856 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value; 876 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
857 break; 877 break;
858 case V4L2_CID_CONTRAST: 878 case V4L2_CID_CONTRAST:
859 if (ctrl->value < 0 || ctrl->value > 255) { 879 if (ctrl->value < 0 || ctrl->value > 255) {
860 v4l_err(decoder->client, 880 v4l2_err(sd, "invalid contrast setting %d\n",
861 "invalid contrast setting %d\n",
862 ctrl->value); 881 ctrl->value);
863 return -ERANGE; 882 return -ERANGE;
864 } 883 }
865 err = tvp514x_write_reg(decoder->client, REG_CONTRAST, 884 err = tvp514x_write_reg(sd, REG_CONTRAST, value);
866 value);
867 if (err) 885 if (err)
868 return err; 886 return err;
887
869 decoder->tvp514x_regs[REG_CONTRAST].val = value; 888 decoder->tvp514x_regs[REG_CONTRAST].val = value;
870 break; 889 break;
871 case V4L2_CID_SATURATION: 890 case V4L2_CID_SATURATION:
872 if (ctrl->value < 0 || ctrl->value > 255) { 891 if (ctrl->value < 0 || ctrl->value > 255) {
873 v4l_err(decoder->client, 892 v4l2_err(sd, "invalid saturation setting %d\n",
874 "invalid saturation setting %d\n",
875 ctrl->value); 893 ctrl->value);
876 return -ERANGE; 894 return -ERANGE;
877 } 895 }
878 err = tvp514x_write_reg(decoder->client, REG_SATURATION, 896 err = tvp514x_write_reg(sd, REG_SATURATION, value);
879 value);
880 if (err) 897 if (err)
881 return err; 898 return err;
899
882 decoder->tvp514x_regs[REG_SATURATION].val = value; 900 decoder->tvp514x_regs[REG_SATURATION].val = value;
883 break; 901 break;
884 case V4L2_CID_HUE: 902 case V4L2_CID_HUE:
@@ -889,15 +907,13 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
889 else if (value == 0) 907 else if (value == 0)
890 value = 0; 908 value = 0;
891 else { 909 else {
892 v4l_err(decoder->client, 910 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
893 "invalid hue setting %d\n",
894 ctrl->value);
895 return -ERANGE; 911 return -ERANGE;
896 } 912 }
897 err = tvp514x_write_reg(decoder->client, REG_HUE, 913 err = tvp514x_write_reg(sd, REG_HUE, value);
898 value);
899 if (err) 914 if (err)
900 return err; 915 return err;
916
901 decoder->tvp514x_regs[REG_HUE].val = value; 917 decoder->tvp514x_regs[REG_HUE].val = value;
902 break; 918 break;
903 case V4L2_CID_AUTOGAIN: 919 case V4L2_CID_AUTOGAIN:
@@ -906,41 +922,38 @@ ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *ctrl)
906 else if (value == 0) 922 else if (value == 0)
907 value = 0x0C; 923 value = 0x0C;
908 else { 924 else {
909 v4l_err(decoder->client, 925 v4l2_err(sd, "invalid auto gain setting %d\n",
910 "invalid auto gain setting %d\n",
911 ctrl->value); 926 ctrl->value);
912 return -ERANGE; 927 return -ERANGE;
913 } 928 }
914 err = tvp514x_write_reg(decoder->client, REG_AFE_GAIN_CTRL, 929 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value);
915 value);
916 if (err) 930 if (err)
917 return err; 931 return err;
932
918 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value; 933 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
919 break; 934 break;
920 default: 935 default:
921 v4l_err(decoder->client, 936 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
922 "invalid control id %d\n", ctrl->id);
923 return err; 937 return err;
924 } 938 }
925 939
926 v4l_dbg(1, debug, decoder->client, 940 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d",
927 "Set Control: ID - %d - %d",
928 ctrl->id, ctrl->value); 941 ctrl->id, ctrl->value);
929 942
930 return err; 943 return err;
931} 944}
932 945
933/** 946/**
934 * ioctl_enum_fmt_cap - Implement the CAPTURE buffer VIDIOC_ENUM_FMT ioctl 947 * tvp514x_enum_fmt_cap() - V4L2 decoder interface handler for enum_fmt
935 * @s: pointer to standard V4L2 device structure 948 * @sd: pointer to standard V4L2 sub-device structure
936 * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure 949 * @fmt: standard V4L2 VIDIOC_ENUM_FMT ioctl structure
937 * 950 *
938 * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats 951 * Implement the VIDIOC_ENUM_FMT ioctl to enumerate supported formats
939 */ 952 */
940static int 953static int
941ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt) 954tvp514x_enum_fmt_cap(struct v4l2_subdev *sd, struct v4l2_fmtdesc *fmt)
942{ 955{
943 struct tvp514x_decoder *decoder = s->priv; 956 struct tvp514x_decoder *decoder = to_decoder(sd);
944 int index; 957 int index;
945 958
946 if (fmt == NULL) 959 if (fmt == NULL)
@@ -948,24 +961,25 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
948 961
949 index = fmt->index; 962 index = fmt->index;
950 if ((index >= decoder->num_fmts) || (index < 0)) 963 if ((index >= decoder->num_fmts) || (index < 0))
951 return -EINVAL; /* Index out of bound */ 964 /* Index out of bound */
965 return -EINVAL;
952 966
953 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 967 if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
954 return -EINVAL; /* only capture is supported */ 968 /* only capture is supported */
969 return -EINVAL;
955 970
956 memcpy(fmt, &decoder->fmt_list[index], 971 memcpy(fmt, &decoder->fmt_list[index],
957 sizeof(struct v4l2_fmtdesc)); 972 sizeof(struct v4l2_fmtdesc));
958 973
959 v4l_dbg(1, debug, decoder->client, 974 v4l2_dbg(1, debug, sd, "Current FMT: index - %d (%s)",
960 "Current FMT: index - %d (%s)",
961 decoder->fmt_list[index].index, 975 decoder->fmt_list[index].index,
962 decoder->fmt_list[index].description); 976 decoder->fmt_list[index].description);
963 return 0; 977 return 0;
964} 978}
965 979
966/** 980/**
967 * ioctl_try_fmt_cap - Implement the CAPTURE buffer VIDIOC_TRY_FMT ioctl 981 * tvp514x_try_fmt_cap() - V4L2 decoder interface handler for try_fmt
968 * @s: pointer to standard V4L2 device structure 982 * @sd: pointer to standard V4L2 sub-device structure
969 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure 983 * @f: pointer to standard V4L2 VIDIOC_TRY_FMT ioctl structure
970 * 984 *
971 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This 985 * Implement the VIDIOC_TRY_FMT ioctl for the CAPTURE buffer type. This
@@ -973,9 +987,9 @@ ioctl_enum_fmt_cap(struct v4l2_int_device *s, struct v4l2_fmtdesc *fmt)
973 * without actually making it take effect. 987 * without actually making it take effect.
974 */ 988 */
975static int 989static int
976ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) 990tvp514x_try_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
977{ 991{
978 struct tvp514x_decoder *decoder = s->priv; 992 struct tvp514x_decoder *decoder = to_decoder(sd);
979 int ifmt; 993 int ifmt;
980 struct v4l2_pix_format *pix; 994 struct v4l2_pix_format *pix;
981 enum tvp514x_std current_std; 995 enum tvp514x_std current_std;
@@ -984,12 +998,13 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
984 return -EINVAL; 998 return -EINVAL;
985 999
986 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1000 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1001 /* only capture is supported */
987 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1002 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
988 1003
989 pix = &f->fmt.pix; 1004 pix = &f->fmt.pix;
990 1005
991 /* Calculate height and width based on current standard */ 1006 /* Calculate height and width based on current standard */
992 current_std = tvp514x_get_current_std(decoder); 1007 current_std = tvp514x_get_current_std(sd);
993 if (current_std == STD_INVALID) 1008 if (current_std == STD_INVALID)
994 return -EINVAL; 1009 return -EINVAL;
995 1010
@@ -1003,7 +1018,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1003 break; 1018 break;
1004 } 1019 }
1005 if (ifmt == decoder->num_fmts) 1020 if (ifmt == decoder->num_fmts)
1006 ifmt = 0; /* None of the format matched, select default */ 1021 /* None of the format matched, select default */
1022 ifmt = 0;
1007 pix->pixelformat = decoder->fmt_list[ifmt].pixelformat; 1023 pix->pixelformat = decoder->fmt_list[ifmt].pixelformat;
1008 1024
1009 pix->field = V4L2_FIELD_INTERLACED; 1025 pix->field = V4L2_FIELD_INTERLACED;
@@ -1012,8 +1028,7 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1012 pix->colorspace = V4L2_COLORSPACE_SMPTE170M; 1028 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
1013 pix->priv = 0; 1029 pix->priv = 0;
1014 1030
1015 v4l_dbg(1, debug, decoder->client, 1031 v4l2_dbg(1, debug, sd, "Try FMT: pixelformat - %s, bytesperline - %d"
1016 "Try FMT: pixelformat - %s, bytesperline - %d"
1017 "Width - %d, Height - %d", 1032 "Width - %d, Height - %d",
1018 decoder->fmt_list[ifmt].description, pix->bytesperline, 1033 decoder->fmt_list[ifmt].description, pix->bytesperline,
1019 pix->width, pix->height); 1034 pix->width, pix->height);
@@ -1021,8 +1036,8 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1021} 1036}
1022 1037
1023/** 1038/**
1024 * ioctl_s_fmt_cap - V4L2 decoder interface handler for VIDIOC_S_FMT ioctl 1039 * tvp514x_s_fmt_cap() - V4L2 decoder interface handler for s_fmt
1025 * @s: pointer to standard V4L2 device structure 1040 * @sd: pointer to standard V4L2 sub-device structure
1026 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure 1041 * @f: pointer to standard V4L2 VIDIOC_S_FMT ioctl structure
1027 * 1042 *
1028 * If the requested format is supported, configures the HW to use that 1043 * If the requested format is supported, configures the HW to use that
@@ -1030,9 +1045,9 @@ ioctl_try_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1030 * correctly configured. 1045 * correctly configured.
1031 */ 1046 */
1032static int 1047static int
1033ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) 1048tvp514x_s_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1034{ 1049{
1035 struct tvp514x_decoder *decoder = s->priv; 1050 struct tvp514x_decoder *decoder = to_decoder(sd);
1036 struct v4l2_pix_format *pix; 1051 struct v4l2_pix_format *pix;
1037 int rval; 1052 int rval;
1038 1053
@@ -1040,10 +1055,11 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1040 return -EINVAL; 1055 return -EINVAL;
1041 1056
1042 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1057 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1043 return -EINVAL; /* only capture is supported */ 1058 /* only capture is supported */
1059 return -EINVAL;
1044 1060
1045 pix = &f->fmt.pix; 1061 pix = &f->fmt.pix;
1046 rval = ioctl_try_fmt_cap(s, f); 1062 rval = tvp514x_try_fmt_cap(sd, f);
1047 if (rval) 1063 if (rval)
1048 return rval; 1064 return rval;
1049 1065
@@ -1053,28 +1069,28 @@ ioctl_s_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1053} 1069}
1054 1070
1055/** 1071/**
1056 * ioctl_g_fmt_cap - V4L2 decoder interface handler for ioctl_g_fmt_cap 1072 * tvp514x_g_fmt_cap() - V4L2 decoder interface handler for tvp514x_g_fmt_cap
1057 * @s: pointer to standard V4L2 device structure 1073 * @sd: pointer to standard V4L2 sub-device structure
1058 * @f: pointer to standard V4L2 v4l2_format structure 1074 * @f: pointer to standard V4L2 v4l2_format structure
1059 * 1075 *
1060 * Returns the decoder's current pixel format in the v4l2_format 1076 * Returns the decoder's current pixel format in the v4l2_format
1061 * parameter. 1077 * parameter.
1062 */ 1078 */
1063static int 1079static int
1064ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f) 1080tvp514x_g_fmt_cap(struct v4l2_subdev *sd, struct v4l2_format *f)
1065{ 1081{
1066 struct tvp514x_decoder *decoder = s->priv; 1082 struct tvp514x_decoder *decoder = to_decoder(sd);
1067 1083
1068 if (f == NULL) 1084 if (f == NULL)
1069 return -EINVAL; 1085 return -EINVAL;
1070 1086
1071 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1087 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1072 return -EINVAL; /* only capture is supported */ 1088 /* only capture is supported */
1089 return -EINVAL;
1073 1090
1074 f->fmt.pix = decoder->pix; 1091 f->fmt.pix = decoder->pix;
1075 1092
1076 v4l_dbg(1, debug, decoder->client, 1093 v4l2_dbg(1, debug, sd, "Current FMT: bytesperline - %d"
1077 "Current FMT: bytesperline - %d"
1078 "Width - %d, Height - %d", 1094 "Width - %d, Height - %d",
1079 decoder->pix.bytesperline, 1095 decoder->pix.bytesperline,
1080 decoder->pix.width, decoder->pix.height); 1096 decoder->pix.width, decoder->pix.height);
@@ -1082,16 +1098,16 @@ ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
1082} 1098}
1083 1099
1084/** 1100/**
1085 * ioctl_g_parm - V4L2 decoder interface handler for VIDIOC_G_PARM ioctl 1101 * tvp514x_g_parm() - V4L2 decoder interface handler for g_parm
1086 * @s: pointer to standard V4L2 device structure 1102 * @sd: pointer to standard V4L2 sub-device structure
1087 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure 1103 * @a: pointer to standard V4L2 VIDIOC_G_PARM ioctl structure
1088 * 1104 *
1089 * Returns the decoder's video CAPTURE parameters. 1105 * Returns the decoder's video CAPTURE parameters.
1090 */ 1106 */
1091static int 1107static int
1092ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) 1108tvp514x_g_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1093{ 1109{
1094 struct tvp514x_decoder *decoder = s->priv; 1110 struct tvp514x_decoder *decoder = to_decoder(sd);
1095 struct v4l2_captureparm *cparm; 1111 struct v4l2_captureparm *cparm;
1096 enum tvp514x_std current_std; 1112 enum tvp514x_std current_std;
1097 1113
@@ -1099,13 +1115,14 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1099 return -EINVAL; 1115 return -EINVAL;
1100 1116
1101 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1117 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1102 return -EINVAL; /* only capture is supported */ 1118 /* only capture is supported */
1119 return -EINVAL;
1103 1120
1104 memset(a, 0, sizeof(*a)); 1121 memset(a, 0, sizeof(*a));
1105 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1122 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1106 1123
1107 /* get the current standard */ 1124 /* get the current standard */
1108 current_std = tvp514x_get_current_std(decoder); 1125 current_std = tvp514x_get_current_std(sd);
1109 if (current_std == STD_INVALID) 1126 if (current_std == STD_INVALID)
1110 return -EINVAL; 1127 return -EINVAL;
1111 1128
@@ -1120,17 +1137,17 @@ ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1120} 1137}
1121 1138
1122/** 1139/**
1123 * ioctl_s_parm - V4L2 decoder interface handler for VIDIOC_S_PARM ioctl 1140 * tvp514x_s_parm() - V4L2 decoder interface handler for s_parm
1124 * @s: pointer to standard V4L2 device structure 1141 * @sd: pointer to standard V4L2 sub-device structure
1125 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure 1142 * @a: pointer to standard V4L2 VIDIOC_S_PARM ioctl structure
1126 * 1143 *
1127 * Configures the decoder to use the input parameters, if possible. If 1144 * Configures the decoder to use the input parameters, if possible. If
1128 * not possible, returns the appropriate error code. 1145 * not possible, returns the appropriate error code.
1129 */ 1146 */
1130static int 1147static int
1131ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a) 1148tvp514x_s_parm(struct v4l2_subdev *sd, struct v4l2_streamparm *a)
1132{ 1149{
1133 struct tvp514x_decoder *decoder = s->priv; 1150 struct tvp514x_decoder *decoder = to_decoder(sd);
1134 struct v4l2_fract *timeperframe; 1151 struct v4l2_fract *timeperframe;
1135 enum tvp514x_std current_std; 1152 enum tvp514x_std current_std;
1136 1153
@@ -1138,12 +1155,13 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1138 return -EINVAL; 1155 return -EINVAL;
1139 1156
1140 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1157 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1141 return -EINVAL; /* only capture is supported */ 1158 /* only capture is supported */
1159 return -EINVAL;
1142 1160
1143 timeperframe = &a->parm.capture.timeperframe; 1161 timeperframe = &a->parm.capture.timeperframe;
1144 1162
1145 /* get the current standard */ 1163 /* get the current standard */
1146 current_std = tvp514x_get_current_std(decoder); 1164 current_std = tvp514x_get_current_std(sd);
1147 if (current_std == STD_INVALID) 1165 if (current_std == STD_INVALID)
1148 return -EINVAL; 1166 return -EINVAL;
1149 1167
@@ -1156,111 +1174,58 @@ ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
1156} 1174}
1157 1175
1158/** 1176/**
1159 * ioctl_g_ifparm - V4L2 decoder interface handler for vidioc_int_g_ifparm_num 1177 * tvp514x_s_stream() - V4L2 decoder i/f handler for s_stream
1160 * @s: pointer to standard V4L2 device structure 1178 * @sd: pointer to standard V4L2 sub-device structure
1161 * @p: pointer to standard V4L2 vidioc_int_g_ifparm_num ioctl structure 1179 * @enable: streaming enable or disable
1162 *
1163 * Gets slave interface parameters.
1164 * Calculates the required xclk value to support the requested
1165 * clock parameters in p. This value is returned in the p
1166 * parameter.
1167 */
1168static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
1169{
1170 struct tvp514x_decoder *decoder = s->priv;
1171 int rval;
1172
1173 if (p == NULL)
1174 return -EINVAL;
1175
1176 if (NULL == decoder->pdata->ifparm)
1177 return -EINVAL;
1178
1179 rval = decoder->pdata->ifparm(p);
1180 if (rval) {
1181 v4l_err(decoder->client, "g_ifparm.Err[%d]\n", rval);
1182 return rval;
1183 }
1184
1185 p->u.bt656.clock_curr = TVP514X_XCLK_BT656;
1186
1187 return 0;
1188}
1189
1190/**
1191 * ioctl_g_priv - V4L2 decoder interface handler for vidioc_int_g_priv_num
1192 * @s: pointer to standard V4L2 device structure
1193 * @p: void pointer to hold decoder's private data address
1194 *
1195 * Returns device's (decoder's) private data area address in p parameter
1196 */
1197static int ioctl_g_priv(struct v4l2_int_device *s, void *p)
1198{
1199 struct tvp514x_decoder *decoder = s->priv;
1200
1201 if (NULL == decoder->pdata->priv_data_set)
1202 return -EINVAL;
1203
1204 return decoder->pdata->priv_data_set(p);
1205}
1206
1207/**
1208 * ioctl_s_power - V4L2 decoder interface handler for vidioc_int_s_power_num
1209 * @s: pointer to standard V4L2 device structure
1210 * @on: power state to which device is to be set
1211 * 1180 *
1212 * Sets devices power state to requrested state, if possible. 1181 * Sets streaming to enable or disable, if possible.
1213 */ 1182 */
1214static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on) 1183static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
1215{ 1184{
1216 struct tvp514x_decoder *decoder = s->priv;
1217 int err = 0; 1185 int err = 0;
1186 struct i2c_client *client = v4l2_get_subdevdata(sd);
1187 struct tvp514x_decoder *decoder = to_decoder(sd);
1218 1188
1219 switch (on) { 1189 if (decoder->streaming == enable)
1220 case V4L2_POWER_OFF: 1190 return 0;
1221 /* Power Down Sequence */
1222 err =
1223 tvp514x_write_reg(decoder->client, REG_OPERATION_MODE,
1224 0x01);
1225 /* Disable mux for TVP5146/47 decoder data path */
1226 if (decoder->pdata->power_set)
1227 err |= decoder->pdata->power_set(on);
1228 decoder->state = STATE_NOT_DETECTED;
1229 break;
1230 1191
1231 case V4L2_POWER_STANDBY: 1192 switch (enable) {
1232 if (decoder->pdata->power_set) 1193 case 0:
1233 err = decoder->pdata->power_set(on); 1194 {
1195 /* Power Down Sequence */
1196 err = tvp514x_write_reg(sd, REG_OPERATION_MODE, 0x01);
1197 if (err) {
1198 v4l2_err(sd, "Unable to turn off decoder\n");
1199 return err;
1200 }
1201 decoder->streaming = enable;
1234 break; 1202 break;
1203 }
1204 case 1:
1205 {
1206 struct tvp514x_reg *int_seq = (struct tvp514x_reg *)
1207 client->driver->id_table->driver_data;
1235 1208
1236 case V4L2_POWER_ON: 1209 /* Power Up Sequence */
1237 /* Enable mux for TVP5146/47 decoder data path */ 1210 err = tvp514x_write_regs(sd, int_seq);
1238 if ((decoder->pdata->power_set) && 1211 if (err) {
1239 (decoder->state == STATE_NOT_DETECTED)) { 1212 v4l2_err(sd, "Unable to turn on decoder\n");
1240 int i; 1213 return err;
1241 struct tvp514x_init_seq *int_seq =
1242 (struct tvp514x_init_seq *)
1243 decoder->id->driver_data;
1244
1245 err = decoder->pdata->power_set(on);
1246
1247 /* Power Up Sequence */
1248 for (i = 0; i < int_seq->no_regs; i++) {
1249 err |= tvp514x_write_reg(decoder->client,
1250 int_seq->init_reg_seq[i].reg,
1251 int_seq->init_reg_seq[i].val);
1252 }
1253 /* Detect the sensor is not already detected */
1254 err |= tvp514x_detect(decoder);
1255 if (err) {
1256 v4l_err(decoder->client,
1257 "Unable to detect decoder\n");
1258 return err;
1259 }
1260 } 1214 }
1261 err |= tvp514x_configure(decoder); 1215 /* Detect if not already detected */
1216 err = tvp514x_detect(sd, decoder);
1217 if (err) {
1218 v4l2_err(sd, "Unable to detect decoder\n");
1219 return err;
1220 }
1221 err = tvp514x_configure(sd, decoder);
1222 if (err) {
1223 v4l2_err(sd, "Unable to configure decoder\n");
1224 return err;
1225 }
1226 decoder->streaming = enable;
1262 break; 1227 break;
1263 1228 }
1264 default: 1229 default:
1265 err = -ENODEV; 1230 err = -ENODEV;
1266 break; 1231 break;
@@ -1269,93 +1234,38 @@ static int ioctl_s_power(struct v4l2_int_device *s, enum v4l2_power on)
1269 return err; 1234 return err;
1270} 1235}
1271 1236
1272/** 1237static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
1273 * ioctl_init - V4L2 decoder interface handler for VIDIOC_INT_INIT 1238 .queryctrl = tvp514x_queryctrl,
1274 * @s: pointer to standard V4L2 device structure 1239 .g_ctrl = tvp514x_g_ctrl,
1275 * 1240 .s_ctrl = tvp514x_s_ctrl,
1276 * Initialize the decoder device (calls tvp514x_configure()) 1241 .s_std = tvp514x_s_std,
1277 */ 1242};
1278static int ioctl_init(struct v4l2_int_device *s)
1279{
1280 struct tvp514x_decoder *decoder = s->priv;
1281
1282 /* Set default standard to auto */
1283 decoder->tvp514x_regs[REG_VIDEO_STD].val =
1284 VIDEO_STD_AUTO_SWITCH_BIT;
1285
1286 return tvp514x_configure(decoder);
1287}
1288
1289/**
1290 * ioctl_dev_exit - V4L2 decoder interface handler for vidioc_int_dev_exit_num
1291 * @s: pointer to standard V4L2 device structure
1292 *
1293 * Delinitialise the dev. at slave detach. The complement of ioctl_dev_init.
1294 */
1295static int ioctl_dev_exit(struct v4l2_int_device *s)
1296{
1297 return 0;
1298}
1299
1300/**
1301 * ioctl_dev_init - V4L2 decoder interface handler for vidioc_int_dev_init_num
1302 * @s: pointer to standard V4L2 device structure
1303 *
1304 * Initialise the device when slave attaches to the master. Returns 0 if
1305 * TVP5146/47 device could be found, otherwise returns appropriate error.
1306 */
1307static int ioctl_dev_init(struct v4l2_int_device *s)
1308{
1309 struct tvp514x_decoder *decoder = s->priv;
1310 int err;
1311
1312 err = tvp514x_detect(decoder);
1313 if (err < 0) {
1314 v4l_err(decoder->client,
1315 "Unable to detect decoder\n");
1316 return err;
1317 }
1318
1319 v4l_info(decoder->client,
1320 "chip version 0x%.2x detected\n", decoder->ver);
1321 1243
1322 return 0; 1244static const struct v4l2_subdev_video_ops tvp514x_video_ops = {
1323} 1245 .s_routing = tvp514x_s_routing,
1246 .querystd = tvp514x_querystd,
1247 .enum_fmt = tvp514x_enum_fmt_cap,
1248 .g_fmt = tvp514x_g_fmt_cap,
1249 .try_fmt = tvp514x_try_fmt_cap,
1250 .s_fmt = tvp514x_s_fmt_cap,
1251 .g_parm = tvp514x_g_parm,
1252 .s_parm = tvp514x_s_parm,
1253 .s_stream = tvp514x_s_stream,
1254};
1324 1255
1325static struct v4l2_int_ioctl_desc tvp514x_ioctl_desc[] = { 1256static const struct v4l2_subdev_ops tvp514x_ops = {
1326 {vidioc_int_dev_init_num, (v4l2_int_ioctl_func*) ioctl_dev_init}, 1257 .core = &tvp514x_core_ops,
1327 {vidioc_int_dev_exit_num, (v4l2_int_ioctl_func*) ioctl_dev_exit}, 1258 .video = &tvp514x_video_ops,
1328 {vidioc_int_s_power_num, (v4l2_int_ioctl_func*) ioctl_s_power},
1329 {vidioc_int_g_priv_num, (v4l2_int_ioctl_func*) ioctl_g_priv},
1330 {vidioc_int_g_ifparm_num, (v4l2_int_ioctl_func*) ioctl_g_ifparm},
1331 {vidioc_int_init_num, (v4l2_int_ioctl_func*) ioctl_init},
1332 {vidioc_int_enum_fmt_cap_num,
1333 (v4l2_int_ioctl_func *) ioctl_enum_fmt_cap},
1334 {vidioc_int_try_fmt_cap_num,
1335 (v4l2_int_ioctl_func *) ioctl_try_fmt_cap},
1336 {vidioc_int_g_fmt_cap_num,
1337 (v4l2_int_ioctl_func *) ioctl_g_fmt_cap},
1338 {vidioc_int_s_fmt_cap_num,
1339 (v4l2_int_ioctl_func *) ioctl_s_fmt_cap},
1340 {vidioc_int_g_parm_num, (v4l2_int_ioctl_func *) ioctl_g_parm},
1341 {vidioc_int_s_parm_num, (v4l2_int_ioctl_func *) ioctl_s_parm},
1342 {vidioc_int_queryctrl_num,
1343 (v4l2_int_ioctl_func *) ioctl_queryctrl},
1344 {vidioc_int_g_ctrl_num, (v4l2_int_ioctl_func *) ioctl_g_ctrl},
1345 {vidioc_int_s_ctrl_num, (v4l2_int_ioctl_func *) ioctl_s_ctrl},
1346 {vidioc_int_querystd_num, (v4l2_int_ioctl_func *) ioctl_querystd},
1347 {vidioc_int_s_std_num, (v4l2_int_ioctl_func *) ioctl_s_std},
1348 {vidioc_int_s_video_routing_num,
1349 (v4l2_int_ioctl_func *) ioctl_s_routing},
1350}; 1259};
1351 1260
1352static struct tvp514x_decoder tvp514x_dev = { 1261static struct tvp514x_decoder tvp514x_dev = {
1353 .state = STATE_NOT_DETECTED, 1262 .streaming = 0,
1354 1263
1355 .fmt_list = tvp514x_fmt_list, 1264 .fmt_list = tvp514x_fmt_list,
1356 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list), 1265 .num_fmts = ARRAY_SIZE(tvp514x_fmt_list),
1357 1266
1358 .pix = { /* Default to NTSC 8-bit YUV 422 */ 1267 .pix = {
1268 /* Default to NTSC 8-bit YUV 422 */
1359 .width = NTSC_NUM_ACTIVE_PIXELS, 1269 .width = NTSC_NUM_ACTIVE_PIXELS,
1360 .height = NTSC_NUM_ACTIVE_LINES, 1270 .height = NTSC_NUM_ACTIVE_LINES,
1361 .pixelformat = V4L2_PIX_FMT_UYVY, 1271 .pixelformat = V4L2_PIX_FMT_UYVY,
@@ -1369,20 +1279,13 @@ static struct tvp514x_decoder tvp514x_dev = {
1369 .current_std = STD_NTSC_MJ, 1279 .current_std = STD_NTSC_MJ,
1370 .std_list = tvp514x_std_list, 1280 .std_list = tvp514x_std_list,
1371 .num_stds = ARRAY_SIZE(tvp514x_std_list), 1281 .num_stds = ARRAY_SIZE(tvp514x_std_list),
1372 .v4l2_int_device = { 1282
1373 .module = THIS_MODULE,
1374 .name = TVP514X_MODULE_NAME,
1375 .type = v4l2_int_type_slave,
1376 },
1377 .tvp514x_slave = {
1378 .ioctls = tvp514x_ioctl_desc,
1379 .num_ioctls = ARRAY_SIZE(tvp514x_ioctl_desc),
1380 },
1381}; 1283};
1382 1284
1383/** 1285/**
1384 * tvp514x_probe - decoder driver i2c probe handler 1286 * tvp514x_probe() - decoder driver i2c probe handler
1385 * @client: i2c driver client device structure 1287 * @client: i2c driver client device structure
1288 * @id: i2c driver id table
1386 * 1289 *
1387 * Register decoder as an i2c client device and V4L2 1290 * Register decoder as an i2c client device and V4L2
1388 * device. 1291 * device.
@@ -1391,88 +1294,71 @@ static int
1391tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id) 1294tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1392{ 1295{
1393 struct tvp514x_decoder *decoder; 1296 struct tvp514x_decoder *decoder;
1394 int err; 1297 struct v4l2_subdev *sd;
1395 1298
1396 /* Check if the adapter supports the needed features */ 1299 /* Check if the adapter supports the needed features */
1397 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1300 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1398 return -EIO; 1301 return -EIO;
1399 1302
1303 if (!client->dev.platform_data) {
1304 v4l2_err(client, "No platform data!!\n");
1305 return -ENODEV;
1306 }
1307
1400 decoder = kzalloc(sizeof(*decoder), GFP_KERNEL); 1308 decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
1401 if (!decoder) 1309 if (!decoder)
1402 return -ENOMEM; 1310 return -ENOMEM;
1403 1311
1404 if (!client->dev.platform_data) { 1312 /* Initialize the tvp514x_decoder with default configuration */
1405 v4l_err(client, "No platform data!!\n");
1406 err = -ENODEV;
1407 goto out_free;
1408 }
1409
1410 *decoder = tvp514x_dev; 1313 *decoder = tvp514x_dev;
1411 decoder->v4l2_int_device.priv = decoder; 1314 /* Copy default register configuration */
1412 decoder->pdata = client->dev.platform_data;
1413 decoder->v4l2_int_device.u.slave = &decoder->tvp514x_slave;
1414 memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default, 1315 memcpy(decoder->tvp514x_regs, tvp514x_reg_list_default,
1415 sizeof(tvp514x_reg_list_default)); 1316 sizeof(tvp514x_reg_list_default));
1416 /* 1317
1318 /* Copy board specific information here */
1319 decoder->pdata = client->dev.platform_data;
1320
1321 /**
1417 * Fetch platform specific data, and configure the 1322 * Fetch platform specific data, and configure the
1418 * tvp514x_reg_list[] accordingly. Since this is one 1323 * tvp514x_reg_list[] accordingly. Since this is one
1419 * time configuration, no need to preserve. 1324 * time configuration, no need to preserve.
1420 */ 1325 */
1421 decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |= 1326 decoder->tvp514x_regs[REG_OUTPUT_FORMATTER2].val |=
1422 (decoder->pdata->clk_polarity << 1); 1327 (decoder->pdata->clk_polarity << 1);
1423 decoder->tvp514x_regs[REG_SYNC_CONTROL].val |= 1328 decoder->tvp514x_regs[REG_SYNC_CONTROL].val |=
1424 ((decoder->pdata->hs_polarity << 2) | 1329 ((decoder->pdata->hs_polarity << 2) |
1425 (decoder->pdata->vs_polarity << 3)); 1330 (decoder->pdata->vs_polarity << 3));
1426 /* 1331 /* Set default standard to auto */
1427 * Save the id data, required for power up sequence 1332 decoder->tvp514x_regs[REG_VIDEO_STD].val =
1428 */ 1333 VIDEO_STD_AUTO_SWITCH_BIT;
1429 decoder->id = (struct i2c_device_id *)id;
1430 /* Attach to Master */
1431 strcpy(decoder->v4l2_int_device.u.slave->attach_to,
1432 decoder->pdata->master);
1433 decoder->client = client;
1434 i2c_set_clientdata(client, decoder);
1435 1334
1436 /* Register with V4L2 layer as slave device */ 1335 /* Register with V4L2 layer as slave device */
1437 err = v4l2_int_device_register(&decoder->v4l2_int_device); 1336 sd = &decoder->sd;
1438 if (err) { 1337 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
1439 i2c_set_clientdata(client, NULL); 1338
1440 v4l_err(client, 1339 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
1441 "Unable to register to v4l2. Err[%d]\n", err); 1340
1442 goto out_free;
1443
1444 } else
1445 v4l_info(client, "Registered to v4l2 master %s!!\n",
1446 decoder->pdata->master);
1447 return 0; 1341 return 0;
1448 1342
1449out_free:
1450 kfree(decoder);
1451 return err;
1452} 1343}
1453 1344
1454/** 1345/**
1455 * tvp514x_remove - decoder driver i2c remove handler 1346 * tvp514x_remove() - decoder driver i2c remove handler
1456 * @client: i2c driver client device structure 1347 * @client: i2c driver client device structure
1457 * 1348 *
1458 * Unregister decoder as an i2c client device and V4L2 1349 * Unregister decoder as an i2c client device and V4L2
1459 * device. Complement of tvp514x_probe(). 1350 * device. Complement of tvp514x_probe().
1460 */ 1351 */
1461static int __exit tvp514x_remove(struct i2c_client *client) 1352static int tvp514x_remove(struct i2c_client *client)
1462{ 1353{
1463 struct tvp514x_decoder *decoder = i2c_get_clientdata(client); 1354 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1464 1355 struct tvp514x_decoder *decoder = to_decoder(sd);
1465 if (!client->adapter)
1466 return -ENODEV; /* our client isn't attached */
1467 1356
1468 v4l2_int_device_unregister(&decoder->v4l2_int_device); 1357 v4l2_device_unregister_subdev(sd);
1469 i2c_set_clientdata(client, NULL);
1470 kfree(decoder); 1358 kfree(decoder);
1471 return 0; 1359 return 0;
1472} 1360}
1473/* 1361/* TVP5146 Init/Power on Sequence */
1474 * TVP5146 Init/Power on Sequence
1475 */
1476static const struct tvp514x_reg tvp5146_init_reg_seq[] = { 1362static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
1477 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, 1363 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
1478 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, 1364 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
@@ -1485,14 +1371,10 @@ static const struct tvp514x_reg tvp5146_init_reg_seq[] = {
1485 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, 1371 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
1486 {TOK_WRITE, REG_OPERATION_MODE, 0x01}, 1372 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1487 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 1373 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1374 {TOK_TERM, 0, 0},
1488}; 1375};
1489static const struct tvp514x_init_seq tvp5146_init = { 1376
1490 .no_regs = ARRAY_SIZE(tvp5146_init_reg_seq), 1377/* TVP5147 Init/Power on Sequence */
1491 .init_reg_seq = tvp5146_init_reg_seq,
1492};
1493/*
1494 * TVP5147 Init/Power on Sequence
1495 */
1496static const struct tvp514x_reg tvp5147_init_reg_seq[] = { 1378static const struct tvp514x_reg tvp5147_init_reg_seq[] = {
1497 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02}, 1379 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS1, 0x02},
1498 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00}, 1380 {TOK_WRITE, REG_VBUS_ADDRESS_ACCESS2, 0x00},
@@ -1512,71 +1394,51 @@ static const struct tvp514x_reg tvp5147_init_reg_seq[] = {
1512 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00}, 1394 {TOK_WRITE, REG_VBUS_DATA_ACCESS_NO_VBUS_ADDR_INCR, 0x00},
1513 {TOK_WRITE, REG_OPERATION_MODE, 0x01}, 1395 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1514 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 1396 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1397 {TOK_TERM, 0, 0},
1515}; 1398};
1516static const struct tvp514x_init_seq tvp5147_init = { 1399
1517 .no_regs = ARRAY_SIZE(tvp5147_init_reg_seq), 1400/* TVP5146M2/TVP5147M1 Init/Power on Sequence */
1518 .init_reg_seq = tvp5147_init_reg_seq,
1519};
1520/*
1521 * TVP5146M2/TVP5147M1 Init/Power on Sequence
1522 */
1523static const struct tvp514x_reg tvp514xm_init_reg_seq[] = { 1401static const struct tvp514x_reg tvp514xm_init_reg_seq[] = {
1524 {TOK_WRITE, REG_OPERATION_MODE, 0x01}, 1402 {TOK_WRITE, REG_OPERATION_MODE, 0x01},
1525 {TOK_WRITE, REG_OPERATION_MODE, 0x00}, 1403 {TOK_WRITE, REG_OPERATION_MODE, 0x00},
1404 {TOK_TERM, 0, 0},
1526}; 1405};
1527static const struct tvp514x_init_seq tvp514xm_init = { 1406
1528 .no_regs = ARRAY_SIZE(tvp514xm_init_reg_seq), 1407/**
1529 .init_reg_seq = tvp514xm_init_reg_seq,
1530};
1531/*
1532 * I2C Device Table - 1408 * I2C Device Table -
1533 * 1409 *
1534 * name - Name of the actual device/chip. 1410 * name - Name of the actual device/chip.
1535 * driver_data - Driver data 1411 * driver_data - Driver data
1536 */ 1412 */
1537static const struct i2c_device_id tvp514x_id[] = { 1413static const struct i2c_device_id tvp514x_id[] = {
1538 {"tvp5146", (unsigned long)&tvp5146_init}, 1414 {"tvp5146", (unsigned long)tvp5146_init_reg_seq},
1539 {"tvp5146m2", (unsigned long)&tvp514xm_init}, 1415 {"tvp5146m2", (unsigned long)tvp514xm_init_reg_seq},
1540 {"tvp5147", (unsigned long)&tvp5147_init}, 1416 {"tvp5147", (unsigned long)tvp5147_init_reg_seq},
1541 {"tvp5147m1", (unsigned long)&tvp514xm_init}, 1417 {"tvp5147m1", (unsigned long)tvp514xm_init_reg_seq},
1542 {}, 1418 {},
1543}; 1419};
1544 1420
1545MODULE_DEVICE_TABLE(i2c, tvp514x_id); 1421MODULE_DEVICE_TABLE(i2c, tvp514x_id);
1546 1422
1547static struct i2c_driver tvp514x_i2c_driver = { 1423static struct i2c_driver tvp514x_driver = {
1548 .driver = { 1424 .driver = {
1549 .name = TVP514X_MODULE_NAME, 1425 .owner = THIS_MODULE,
1550 .owner = THIS_MODULE, 1426 .name = TVP514X_MODULE_NAME,
1551 }, 1427 },
1552 .probe = tvp514x_probe, 1428 .probe = tvp514x_probe,
1553 .remove = __exit_p(tvp514x_remove), 1429 .remove = tvp514x_remove,
1554 .id_table = tvp514x_id, 1430 .id_table = tvp514x_id,
1555}; 1431};
1556 1432
1557/**
1558 * tvp514x_init
1559 *
1560 * Module init function
1561 */
1562static int __init tvp514x_init(void) 1433static int __init tvp514x_init(void)
1563{ 1434{
1564 return i2c_add_driver(&tvp514x_i2c_driver); 1435 return i2c_add_driver(&tvp514x_driver);
1565} 1436}
1566 1437
1567/** 1438static void __exit tvp514x_exit(void)
1568 * tvp514x_cleanup
1569 *
1570 * Module exit function
1571 */
1572static void __exit tvp514x_cleanup(void)
1573{ 1439{
1574 i2c_del_driver(&tvp514x_i2c_driver); 1440 i2c_del_driver(&tvp514x_driver);
1575} 1441}
1576 1442
1577module_init(tvp514x_init); 1443module_init(tvp514x_init);
1578module_exit(tvp514x_cleanup); 1444module_exit(tvp514x_exit);
1579
1580MODULE_AUTHOR("Texas Instruments");
1581MODULE_DESCRIPTION("TVP514X linux decoder driver");
1582MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/tvp514x_regs.h b/drivers/media/video/tvp514x_regs.h
index 351620aeecc2..18f29ad0dfe2 100644
--- a/drivers/media/video/tvp514x_regs.h
+++ b/drivers/media/video/tvp514x_regs.h
@@ -284,14 +284,4 @@ struct tvp514x_reg {
284 u32 val; 284 u32 val;
285}; 285};
286 286
287/**
288 * struct tvp514x_init_seq - Structure for TVP5146/47/46M2/47M1 power up
289 * Sequence.
290 * @ no_regs - Number of registers to write for power up sequence.
291 * @ init_reg_seq - Array of registers and respective value to write.
292 */
293struct tvp514x_init_seq {
294 unsigned int no_regs;
295 const struct tvp514x_reg *init_reg_seq;
296};
297#endif /* ifndef _TVP514X_REGS_H */ 287#endif /* ifndef _TVP514X_REGS_H */
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index aa5065ea09ed..269ab044072a 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -24,7 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/videodev2.h> 25#include <linux/videodev2.h>
26#include <media/v4l2-chip-ident.h> 26#include <media/v4l2-chip-ident.h>
27#include <media/v4l2-common.h> 27#include <media/v4l2-subdev.h>
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/tw9910.h> 29#include <media/tw9910.h>
30 30
@@ -223,9 +223,8 @@ struct tw9910_hsync_ctrl {
223}; 223};
224 224
225struct tw9910_priv { 225struct tw9910_priv {
226 struct v4l2_subdev subdev;
226 struct tw9910_video_info *info; 227 struct tw9910_video_info *info;
227 struct i2c_client *client;
228 struct soc_camera_device icd;
229 const struct tw9910_scale_ctrl *scale; 228 const struct tw9910_scale_ctrl *scale;
230}; 229};
231 230
@@ -356,6 +355,12 @@ static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
356/* 355/*
357 * general function 356 * general function
358 */ 357 */
358static struct tw9910_priv *to_tw9910(const struct i2c_client *client)
359{
360 return container_of(i2c_get_clientdata(client), struct tw9910_priv,
361 subdev);
362}
363
359static int tw9910_set_scale(struct i2c_client *client, 364static int tw9910_set_scale(struct i2c_client *client,
360 const struct tw9910_scale_ctrl *scale) 365 const struct tw9910_scale_ctrl *scale)
361{ 366{
@@ -509,44 +514,20 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
509/* 514/*
510 * soc_camera_ops function 515 * soc_camera_ops function
511 */ 516 */
512static int tw9910_init(struct soc_camera_device *icd) 517static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
513{
514 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
515 int ret = 0;
516
517 if (priv->info->link.power) {
518 ret = priv->info->link.power(&priv->client->dev, 1);
519 if (ret < 0)
520 return ret;
521 }
522
523 if (priv->info->link.reset)
524 ret = priv->info->link.reset(&priv->client->dev);
525
526 return ret;
527}
528
529static int tw9910_release(struct soc_camera_device *icd)
530{ 518{
531 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 519 struct i2c_client *client = sd->priv;
532 int ret = 0; 520 struct tw9910_priv *priv = to_tw9910(client);
533
534 if (priv->info->link.power)
535 ret = priv->info->link.power(&priv->client->dev, 0);
536
537 return ret;
538}
539 521
540static int tw9910_start_capture(struct soc_camera_device *icd) 522 if (!enable)
541{ 523 return 0;
542 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd);
543 524
544 if (!priv->scale) { 525 if (!priv->scale) {
545 dev_err(&icd->dev, "norm select error\n"); 526 dev_err(&client->dev, "norm select error\n");
546 return -EPERM; 527 return -EPERM;
547 } 528 }
548 529
549 dev_dbg(&icd->dev, "%s %dx%d\n", 530 dev_dbg(&client->dev, "%s %dx%d\n",
550 priv->scale->name, 531 priv->scale->name,
551 priv->scale->width, 532 priv->scale->width,
552 priv->scale->height); 533 priv->scale->height);
@@ -554,11 +535,6 @@ static int tw9910_start_capture(struct soc_camera_device *icd)
554 return 0; 535 return 0;
555} 536}
556 537
557static int tw9910_stop_capture(struct soc_camera_device *icd)
558{
559 return 0;
560}
561
562static int tw9910_set_bus_param(struct soc_camera_device *icd, 538static int tw9910_set_bus_param(struct soc_camera_device *icd,
563 unsigned long flags) 539 unsigned long flags)
564{ 540{
@@ -567,8 +543,9 @@ static int tw9910_set_bus_param(struct soc_camera_device *icd,
567 543
568static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) 544static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
569{ 545{
570 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 546 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
571 struct soc_camera_link *icl = priv->client->dev.platform_data; 547 struct tw9910_priv *priv = to_tw9910(client);
548 struct soc_camera_link *icl = to_soc_camera_link(icd);
572 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER | 549 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
573 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH | 550 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
574 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth; 551 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -576,21 +553,11 @@ static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd)
576 return soc_camera_apply_sensor_flags(icl, flags); 553 return soc_camera_apply_sensor_flags(icl, flags);
577} 554}
578 555
579static int tw9910_get_chip_id(struct soc_camera_device *icd, 556static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
580 struct v4l2_dbg_chip_ident *id)
581{
582 id->ident = V4L2_IDENT_TW9910;
583 id->revision = 0;
584
585 return 0;
586}
587
588static int tw9910_set_std(struct soc_camera_device *icd,
589 v4l2_std_id *a)
590{ 557{
591 int ret = -EINVAL; 558 int ret = -EINVAL;
592 559
593 if (*a & (V4L2_STD_NTSC | V4L2_STD_PAL)) 560 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL))
594 ret = 0; 561 ret = 0;
595 562
596 return ret; 563 return ret;
@@ -606,17 +573,26 @@ static int tw9910_enum_input(struct soc_camera_device *icd,
606 return 0; 573 return 0;
607} 574}
608 575
576static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
577 struct v4l2_dbg_chip_ident *id)
578{
579 id->ident = V4L2_IDENT_TW9910;
580 id->revision = 0;
581
582 return 0;
583}
584
609#ifdef CONFIG_VIDEO_ADV_DEBUG 585#ifdef CONFIG_VIDEO_ADV_DEBUG
610static int tw9910_get_register(struct soc_camera_device *icd, 586static int tw9910_g_register(struct v4l2_subdev *sd,
611 struct v4l2_dbg_register *reg) 587 struct v4l2_dbg_register *reg)
612{ 588{
613 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 589 struct i2c_client *client = sd->priv;
614 int ret; 590 int ret;
615 591
616 if (reg->reg > 0xff) 592 if (reg->reg > 0xff)
617 return -EINVAL; 593 return -EINVAL;
618 594
619 ret = i2c_smbus_read_byte_data(priv->client, reg->reg); 595 ret = i2c_smbus_read_byte_data(client, reg->reg);
620 if (ret < 0) 596 if (ret < 0)
621 return ret; 597 return ret;
622 598
@@ -628,23 +604,25 @@ static int tw9910_get_register(struct soc_camera_device *icd,
628 return 0; 604 return 0;
629} 605}
630 606
631static int tw9910_set_register(struct soc_camera_device *icd, 607static int tw9910_s_register(struct v4l2_subdev *sd,
632 struct v4l2_dbg_register *reg) 608 struct v4l2_dbg_register *reg)
633{ 609{
634 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 610 struct i2c_client *client = sd->priv;
635 611
636 if (reg->reg > 0xff || 612 if (reg->reg > 0xff ||
637 reg->val > 0xff) 613 reg->val > 0xff)
638 return -EINVAL; 614 return -EINVAL;
639 615
640 return i2c_smbus_write_byte_data(priv->client, reg->reg, reg->val); 616 return i2c_smbus_write_byte_data(client, reg->reg, reg->val);
641} 617}
642#endif 618#endif
643 619
644static int tw9910_set_crop(struct soc_camera_device *icd, 620static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
645 struct v4l2_rect *rect)
646{ 621{
647 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 622 struct v4l2_rect *rect = &a->c;
623 struct i2c_client *client = sd->priv;
624 struct tw9910_priv *priv = to_tw9910(client);
625 struct soc_camera_device *icd = client->dev.platform_data;
648 int ret = -EINVAL; 626 int ret = -EINVAL;
649 u8 val; 627 u8 val;
650 628
@@ -658,8 +636,8 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
658 /* 636 /*
659 * reset hardware 637 * reset hardware
660 */ 638 */
661 tw9910_reset(priv->client); 639 tw9910_reset(client);
662 ret = tw9910_write_array(priv->client, tw9910_default_regs); 640 ret = tw9910_write_array(client, tw9910_default_regs);
663 if (ret < 0) 641 if (ret < 0)
664 goto tw9910_set_fmt_error; 642 goto tw9910_set_fmt_error;
665 643
@@ -670,7 +648,7 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
670 if (SOCAM_DATAWIDTH_16 == priv->info->buswidth) 648 if (SOCAM_DATAWIDTH_16 == priv->info->buswidth)
671 val = LEN; 649 val = LEN;
672 650
673 ret = tw9910_mask_set(priv->client, OPFORM, LEN, val); 651 ret = tw9910_mask_set(client, OPFORM, LEN, val);
674 if (ret < 0) 652 if (ret < 0)
675 goto tw9910_set_fmt_error; 653 goto tw9910_set_fmt_error;
676 654
@@ -698,52 +676,139 @@ static int tw9910_set_crop(struct soc_camera_device *icd,
698 val = 0; 676 val = 0;
699 } 677 }
700 678
701 ret = tw9910_mask_set(priv->client, VBICNTL, RTSEL_MASK, val); 679 ret = tw9910_mask_set(client, VBICNTL, RTSEL_MASK, val);
702 if (ret < 0) 680 if (ret < 0)
703 goto tw9910_set_fmt_error; 681 goto tw9910_set_fmt_error;
704 682
705 /* 683 /*
706 * set scale 684 * set scale
707 */ 685 */
708 ret = tw9910_set_scale(priv->client, priv->scale); 686 ret = tw9910_set_scale(client, priv->scale);
709 if (ret < 0) 687 if (ret < 0)
710 goto tw9910_set_fmt_error; 688 goto tw9910_set_fmt_error;
711 689
712 /* 690 /*
713 * set cropping 691 * set cropping
714 */ 692 */
715 ret = tw9910_set_cropping(priv->client, &tw9910_cropping_ctrl); 693 ret = tw9910_set_cropping(client, &tw9910_cropping_ctrl);
716 if (ret < 0) 694 if (ret < 0)
717 goto tw9910_set_fmt_error; 695 goto tw9910_set_fmt_error;
718 696
719 /* 697 /*
720 * set hsync 698 * set hsync
721 */ 699 */
722 ret = tw9910_set_hsync(priv->client, &tw9910_hsync_ctrl); 700 ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl);
723 if (ret < 0) 701 if (ret < 0)
724 goto tw9910_set_fmt_error; 702 goto tw9910_set_fmt_error;
725 703
704 rect->width = priv->scale->width;
705 rect->height = priv->scale->height;
706 rect->left = 0;
707 rect->top = 0;
708
726 return ret; 709 return ret;
727 710
728tw9910_set_fmt_error: 711tw9910_set_fmt_error:
729 712
730 tw9910_reset(priv->client); 713 tw9910_reset(client);
731 priv->scale = NULL; 714 priv->scale = NULL;
732 715
733 return ret; 716 return ret;
734} 717}
735 718
736static int tw9910_set_fmt(struct soc_camera_device *icd, 719static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
737 struct v4l2_format *f) 720{
721 struct i2c_client *client = sd->priv;
722 struct tw9910_priv *priv = to_tw9910(client);
723
724 if (!priv->scale) {
725 int ret;
726 struct v4l2_crop crop = {
727 .c = {
728 .left = 0,
729 .top = 0,
730 .width = 640,
731 .height = 480,
732 },
733 };
734 ret = tw9910_s_crop(sd, &crop);
735 if (ret < 0)
736 return ret;
737 }
738
739 a->c.left = 0;
740 a->c.top = 0;
741 a->c.width = priv->scale->width;
742 a->c.height = priv->scale->height;
743 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
744
745 return 0;
746}
747
748static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
738{ 749{
750 a->bounds.left = 0;
751 a->bounds.top = 0;
752 a->bounds.width = 768;
753 a->bounds.height = 576;
754 a->defrect.left = 0;
755 a->defrect.top = 0;
756 a->defrect.width = 640;
757 a->defrect.height = 480;
758 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
759 a->pixelaspect.numerator = 1;
760 a->pixelaspect.denominator = 1;
761
762 return 0;
763}
764
765static int tw9910_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
766{
767 struct i2c_client *client = sd->priv;
768 struct tw9910_priv *priv = to_tw9910(client);
769 struct v4l2_pix_format *pix = &f->fmt.pix;
770
771 if (!priv->scale) {
772 int ret;
773 struct v4l2_crop crop = {
774 .c = {
775 .left = 0,
776 .top = 0,
777 .width = 640,
778 .height = 480,
779 },
780 };
781 ret = tw9910_s_crop(sd, &crop);
782 if (ret < 0)
783 return ret;
784 }
785
786 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
787
788 pix->width = priv->scale->width;
789 pix->height = priv->scale->height;
790 pix->pixelformat = V4L2_PIX_FMT_VYUY;
791 pix->colorspace = V4L2_COLORSPACE_SMPTE170M;
792 pix->field = V4L2_FIELD_INTERLACED;
793
794 return 0;
795}
796
797static int tw9910_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
798{
799 struct i2c_client *client = sd->priv;
800 struct tw9910_priv *priv = to_tw9910(client);
739 struct v4l2_pix_format *pix = &f->fmt.pix; 801 struct v4l2_pix_format *pix = &f->fmt.pix;
740 struct v4l2_rect rect = { 802 /* See tw9910_s_crop() - no proper cropping support */
741 .left = icd->x_current, 803 struct v4l2_crop a = {
742 .top = icd->y_current, 804 .c = {
743 .width = pix->width, 805 .left = 0,
744 .height = pix->height, 806 .top = 0,
807 .width = pix->width,
808 .height = pix->height,
809 },
745 }; 810 };
746 int i; 811 int i, ret;
747 812
748 /* 813 /*
749 * check color format 814 * check color format
@@ -755,19 +820,25 @@ static int tw9910_set_fmt(struct soc_camera_device *icd,
755 if (i == ARRAY_SIZE(tw9910_color_fmt)) 820 if (i == ARRAY_SIZE(tw9910_color_fmt))
756 return -EINVAL; 821 return -EINVAL;
757 822
758 return tw9910_set_crop(icd, &rect); 823 ret = tw9910_s_crop(sd, &a);
824 if (!ret) {
825 pix->width = priv->scale->width;
826 pix->height = priv->scale->height;
827 }
828 return ret;
759} 829}
760 830
761static int tw9910_try_fmt(struct soc_camera_device *icd, 831static int tw9910_try_fmt(struct v4l2_subdev *sd, struct v4l2_format *f)
762 struct v4l2_format *f)
763{ 832{
833 struct i2c_client *client = sd->priv;
834 struct soc_camera_device *icd = client->dev.platform_data;
764 struct v4l2_pix_format *pix = &f->fmt.pix; 835 struct v4l2_pix_format *pix = &f->fmt.pix;
765 const struct tw9910_scale_ctrl *scale; 836 const struct tw9910_scale_ctrl *scale;
766 837
767 if (V4L2_FIELD_ANY == pix->field) { 838 if (V4L2_FIELD_ANY == pix->field) {
768 pix->field = V4L2_FIELD_INTERLACED; 839 pix->field = V4L2_FIELD_INTERLACED;
769 } else if (V4L2_FIELD_INTERLACED != pix->field) { 840 } else if (V4L2_FIELD_INTERLACED != pix->field) {
770 dev_err(&icd->dev, "Field type invalid.\n"); 841 dev_err(&client->dev, "Field type invalid.\n");
771 return -EINVAL; 842 return -EINVAL;
772 } 843 }
773 844
@@ -784,11 +855,11 @@ static int tw9910_try_fmt(struct soc_camera_device *icd,
784 return 0; 855 return 0;
785} 856}
786 857
787static int tw9910_video_probe(struct soc_camera_device *icd) 858static int tw9910_video_probe(struct soc_camera_device *icd,
859 struct i2c_client *client)
788{ 860{
789 struct tw9910_priv *priv = container_of(icd, struct tw9910_priv, icd); 861 struct tw9910_priv *priv = to_tw9910(client);
790 s32 val; 862 s32 val;
791 int ret;
792 863
793 /* 864 /*
794 * We must have a parent by now. And it cannot be a wrong one. 865 * We must have a parent by now. And it cannot be a wrong one.
@@ -803,7 +874,7 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
803 */ 874 */
804 if (SOCAM_DATAWIDTH_16 != priv->info->buswidth && 875 if (SOCAM_DATAWIDTH_16 != priv->info->buswidth &&
805 SOCAM_DATAWIDTH_8 != priv->info->buswidth) { 876 SOCAM_DATAWIDTH_8 != priv->info->buswidth) {
806 dev_err(&icd->dev, "bus width error\n"); 877 dev_err(&client->dev, "bus width error\n");
807 return -ENODEV; 878 return -ENODEV;
808 } 879 }
809 880
@@ -813,54 +884,54 @@ static int tw9910_video_probe(struct soc_camera_device *icd)
813 /* 884 /*
814 * check and show Product ID 885 * check and show Product ID
815 */ 886 */
816 val = i2c_smbus_read_byte_data(priv->client, ID); 887 val = i2c_smbus_read_byte_data(client, ID);
888
817 if (0x0B != GET_ID(val) || 889 if (0x0B != GET_ID(val) ||
818 0x00 != GET_ReV(val)) { 890 0x00 != GET_ReV(val)) {
819 dev_err(&icd->dev, 891 dev_err(&client->dev,
820 "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val)); 892 "Product ID error %x:%x\n", GET_ID(val), GET_ReV(val));
821 return -ENODEV; 893 return -ENODEV;
822 } 894 }
823 895
824 dev_info(&icd->dev, 896 dev_info(&client->dev,
825 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val)); 897 "tw9910 Product ID %0x:%0x\n", GET_ID(val), GET_ReV(val));
826 898
827 ret = soc_camera_video_start(icd);
828 if (ret < 0)
829 return ret;
830
831 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; 899 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL;
832 icd->vdev->current_norm = V4L2_STD_NTSC; 900 icd->vdev->current_norm = V4L2_STD_NTSC;
833 901
834 return ret; 902 return 0;
835}
836
837static void tw9910_video_remove(struct soc_camera_device *icd)
838{
839 soc_camera_video_stop(icd);
840} 903}
841 904
842static struct soc_camera_ops tw9910_ops = { 905static struct soc_camera_ops tw9910_ops = {
843 .owner = THIS_MODULE,
844 .probe = tw9910_video_probe,
845 .remove = tw9910_video_remove,
846 .init = tw9910_init,
847 .release = tw9910_release,
848 .start_capture = tw9910_start_capture,
849 .stop_capture = tw9910_stop_capture,
850 .set_crop = tw9910_set_crop,
851 .set_fmt = tw9910_set_fmt,
852 .try_fmt = tw9910_try_fmt,
853 .set_bus_param = tw9910_set_bus_param, 906 .set_bus_param = tw9910_set_bus_param,
854 .query_bus_param = tw9910_query_bus_param, 907 .query_bus_param = tw9910_query_bus_param,
855 .get_chip_id = tw9910_get_chip_id,
856 .set_std = tw9910_set_std,
857 .enum_input = tw9910_enum_input, 908 .enum_input = tw9910_enum_input,
909};
910
911static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
912 .g_chip_ident = tw9910_g_chip_ident,
913 .s_std = tw9910_s_std,
858#ifdef CONFIG_VIDEO_ADV_DEBUG 914#ifdef CONFIG_VIDEO_ADV_DEBUG
859 .get_register = tw9910_get_register, 915 .g_register = tw9910_g_register,
860 .set_register = tw9910_set_register, 916 .s_register = tw9910_s_register,
861#endif 917#endif
862}; 918};
863 919
920static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
921 .s_stream = tw9910_s_stream,
922 .g_fmt = tw9910_g_fmt,
923 .s_fmt = tw9910_s_fmt,
924 .try_fmt = tw9910_try_fmt,
925 .cropcap = tw9910_cropcap,
926 .g_crop = tw9910_g_crop,
927 .s_crop = tw9910_s_crop,
928};
929
930static struct v4l2_subdev_ops tw9910_subdev_ops = {
931 .core = &tw9910_subdev_core_ops,
932 .video = &tw9910_subdev_video_ops,
933};
934
864/* 935/*
865 * i2c_driver function 936 * i2c_driver function
866 */ 937 */
@@ -871,18 +942,24 @@ static int tw9910_probe(struct i2c_client *client,
871{ 942{
872 struct tw9910_priv *priv; 943 struct tw9910_priv *priv;
873 struct tw9910_video_info *info; 944 struct tw9910_video_info *info;
874 struct soc_camera_device *icd; 945 struct soc_camera_device *icd = client->dev.platform_data;
875 const struct tw9910_scale_ctrl *scale; 946 struct i2c_adapter *adapter =
876 int i, ret; 947 to_i2c_adapter(client->dev.parent);
948 struct soc_camera_link *icl;
949 int ret;
950
951 if (!icd) {
952 dev_err(&client->dev, "TW9910: missing soc-camera data!\n");
953 return -EINVAL;
954 }
877 955
878 if (!client->dev.platform_data) 956 icl = to_soc_camera_link(icd);
957 if (!icl)
879 return -EINVAL; 958 return -EINVAL;
880 959
881 info = container_of(client->dev.platform_data, 960 info = container_of(icl, struct tw9910_video_info, link);
882 struct tw9910_video_info, link);
883 961
884 if (!i2c_check_functionality(to_i2c_adapter(client->dev.parent), 962 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
885 I2C_FUNC_SMBUS_BYTE_DATA)) {
886 dev_err(&client->dev, 963 dev_err(&client->dev,
887 "I2C-Adapter doesn't support " 964 "I2C-Adapter doesn't support "
888 "I2C_FUNC_SMBUS_BYTE_DATA\n"); 965 "I2C_FUNC_SMBUS_BYTE_DATA\n");
@@ -894,40 +971,15 @@ static int tw9910_probe(struct i2c_client *client,
894 return -ENOMEM; 971 return -ENOMEM;
895 972
896 priv->info = info; 973 priv->info = info;
897 priv->client = client;
898 i2c_set_clientdata(client, priv);
899 974
900 icd = &priv->icd; 975 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
976
901 icd->ops = &tw9910_ops; 977 icd->ops = &tw9910_ops;
902 icd->control = &client->dev;
903 icd->iface = info->link.bus_id; 978 icd->iface = info->link.bus_id;
904 979
905 /* 980 ret = tw9910_video_probe(icd, client);
906 * set width and height
907 */
908 icd->width_max = tw9910_ntsc_scales[0].width; /* set default */
909 icd->width_min = tw9910_ntsc_scales[0].width;
910 icd->height_max = tw9910_ntsc_scales[0].height;
911 icd->height_min = tw9910_ntsc_scales[0].height;
912
913 scale = tw9910_ntsc_scales;
914 for (i = 0; i < ARRAY_SIZE(tw9910_ntsc_scales); i++) {
915 icd->width_max = max(scale[i].width, icd->width_max);
916 icd->width_min = min(scale[i].width, icd->width_min);
917 icd->height_max = max(scale[i].height, icd->height_max);
918 icd->height_min = min(scale[i].height, icd->height_min);
919 }
920 scale = tw9910_pal_scales;
921 for (i = 0; i < ARRAY_SIZE(tw9910_pal_scales); i++) {
922 icd->width_max = max(scale[i].width, icd->width_max);
923 icd->width_min = min(scale[i].width, icd->width_min);
924 icd->height_max = max(scale[i].height, icd->height_max);
925 icd->height_min = min(scale[i].height, icd->height_min);
926 }
927
928 ret = soc_camera_device_register(icd);
929
930 if (ret) { 981 if (ret) {
982 icd->ops = NULL;
931 i2c_set_clientdata(client, NULL); 983 i2c_set_clientdata(client, NULL);
932 kfree(priv); 984 kfree(priv);
933 } 985 }
@@ -937,9 +989,10 @@ static int tw9910_probe(struct i2c_client *client,
937 989
938static int tw9910_remove(struct i2c_client *client) 990static int tw9910_remove(struct i2c_client *client)
939{ 991{
940 struct tw9910_priv *priv = i2c_get_clientdata(client); 992 struct tw9910_priv *priv = to_tw9910(client);
993 struct soc_camera_device *icd = client->dev.platform_data;
941 994
942 soc_camera_device_unregister(&priv->icd); 995 icd->ops = NULL;
943 i2c_set_clientdata(client, NULL); 996 i2c_set_clientdata(client, NULL);
944 kfree(priv); 997 kfree(priv);
945 return 0; 998 return 0;
diff --git a/drivers/media/video/usbvision/usbvision-i2c.c b/drivers/media/video/usbvision/usbvision-i2c.c
index 1fe5befbbf85..f97fd06d5948 100644
--- a/drivers/media/video/usbvision/usbvision-i2c.c
+++ b/drivers/media/video/usbvision/usbvision-i2c.c
@@ -246,9 +246,9 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
246 switch (usbvision_device_data[usbvision->DevModel].Codec) { 246 switch (usbvision_device_data[usbvision->DevModel].Codec) {
247 case CODEC_SAA7113: 247 case CODEC_SAA7113:
248 case CODEC_SAA7111: 248 case CODEC_SAA7111:
249 v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev, 249 v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
250 &usbvision->i2c_adap, "saa7115", 250 &usbvision->i2c_adap, "saa7115",
251 "saa7115_auto", saa711x_addrs); 251 "saa7115_auto", 0, saa711x_addrs);
252 break; 252 break;
253 } 253 }
254 if (usbvision_device_data[usbvision->DevModel].Tuner == 1) { 254 if (usbvision_device_data[usbvision->DevModel].Tuner == 1) {
@@ -256,16 +256,16 @@ int usbvision_i2c_register(struct usb_usbvision *usbvision)
256 enum v4l2_i2c_tuner_type type; 256 enum v4l2_i2c_tuner_type type;
257 struct tuner_setup tun_setup; 257 struct tuner_setup tun_setup;
258 258
259 sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev, 259 sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
260 &usbvision->i2c_adap, "tuner", 260 &usbvision->i2c_adap, "tuner",
261 "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD)); 261 "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
262 /* depending on whether we found a demod or not, select 262 /* depending on whether we found a demod or not, select
263 the tuner type. */ 263 the tuner type. */
264 type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV; 264 type = sd ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
265 265
266 sd = v4l2_i2c_new_probed_subdev(&usbvision->v4l2_dev, 266 sd = v4l2_i2c_new_subdev(&usbvision->v4l2_dev,
267 &usbvision->i2c_adap, "tuner", 267 &usbvision->i2c_adap, "tuner",
268 "tuner", v4l2_i2c_tuner_addrs(type)); 268 "tuner", 0, v4l2_i2c_tuner_addrs(type));
269 269
270 if (usbvision->tuner_type != -1) { 270 if (usbvision->tuner_type != -1) {
271 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO; 271 tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 5b757f32d997..f960e8ea4f17 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -124,13 +124,14 @@ static int uvc_get_video_ctrl(struct uvc_streaming *stream,
124 int ret; 124 int ret;
125 125
126 size = stream->dev->uvc_version >= 0x0110 ? 34 : 26; 126 size = stream->dev->uvc_version >= 0x0110 ? 34 : 26;
127 if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) &&
128 query == UVC_GET_DEF)
129 return -EIO;
130
127 data = kmalloc(size, GFP_KERNEL); 131 data = kmalloc(size, GFP_KERNEL);
128 if (data == NULL) 132 if (data == NULL)
129 return -ENOMEM; 133 return -ENOMEM;
130 134
131 if ((stream->dev->quirks & UVC_QUIRK_PROBE_DEF) && query == UVC_GET_DEF)
132 return -EIO;
133
134 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum, 135 ret = __uvc_query_ctrl(stream->dev, query, 0, stream->intfnum,
135 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data, 136 probe ? UVC_VS_PROBE_CONTROL : UVC_VS_COMMIT_CONTROL, data,
136 size, UVC_CTRL_STREAMING_TIMEOUT); 137 size, UVC_CTRL_STREAMING_TIMEOUT);
diff --git a/drivers/media/video/v4l1-compat.c b/drivers/media/video/v4l1-compat.c
index 761fbd64db58..0c2105ca611e 100644
--- a/drivers/media/video/v4l1-compat.c
+++ b/drivers/media/video/v4l1-compat.c
@@ -564,10 +564,9 @@ static noinline long v4l1_compat_get_input_info(
564 break; 564 break;
565 } 565 }
566 chan->norm = 0; 566 chan->norm = 0;
567 err = drv(file, VIDIOC_G_STD, &sid); 567 /* Note: G_STD might not be present for radio receivers,
568 if (err < 0) 568 * so we should ignore any errors. */
569 dprintk("VIDIOCGCHAN / VIDIOC_G_STD: %ld\n", err); 569 if (drv(file, VIDIOC_G_STD, &sid) == 0) {
570 if (err == 0) {
571 if (sid & V4L2_STD_PAL) 570 if (sid & V4L2_STD_PAL)
572 chan->norm = VIDEO_MODE_PAL; 571 chan->norm = VIDEO_MODE_PAL;
573 if (sid & V4L2_STD_NTSC) 572 if (sid & V4L2_STD_NTSC)
@@ -776,10 +775,9 @@ static noinline long v4l1_compat_get_tuner(
776 tun->flags |= VIDEO_TUNER_SECAM; 775 tun->flags |= VIDEO_TUNER_SECAM;
777 } 776 }
778 777
779 err = drv(file, VIDIOC_G_STD, &sid); 778 /* Note: G_STD might not be present for radio receivers,
780 if (err < 0) 779 * so we should ignore any errors. */
781 dprintk("VIDIOCGTUNER / VIDIOC_G_STD: %ld\n", err); 780 if (drv(file, VIDIOC_G_STD, &sid) == 0) {
782 if (err == 0) {
783 if (sid & V4L2_STD_PAL) 781 if (sid & V4L2_STD_PAL)
784 tun->mode = VIDEO_MODE_PAL; 782 tun->mode = VIDEO_MODE_PAL;
785 if (sid & V4L2_STD_NTSC) 783 if (sid & V4L2_STD_NTSC)
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 3a0c64935b0e..f5a93ae3cdf9 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -814,139 +814,6 @@ EXPORT_SYMBOL_GPL(v4l2_i2c_subdev_init);
814 814
815 815
816/* Load an i2c sub-device. */ 816/* Load an i2c sub-device. */
817struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
818 struct i2c_adapter *adapter,
819 const char *module_name, const char *client_type, u8 addr)
820{
821 struct v4l2_subdev *sd = NULL;
822 struct i2c_client *client;
823 struct i2c_board_info info;
824
825 BUG_ON(!v4l2_dev);
826
827 if (module_name)
828 request_module(module_name);
829
830 /* Setup the i2c board info with the device type and
831 the device address. */
832 memset(&info, 0, sizeof(info));
833 strlcpy(info.type, client_type, sizeof(info.type));
834 info.addr = addr;
835
836 /* Create the i2c client */
837 client = i2c_new_device(adapter, &info);
838 /* Note: it is possible in the future that
839 c->driver is NULL if the driver is still being loaded.
840 We need better support from the kernel so that we
841 can easily wait for the load to finish. */
842 if (client == NULL || client->driver == NULL)
843 goto error;
844
845 /* Lock the module so we can safely get the v4l2_subdev pointer */
846 if (!try_module_get(client->driver->driver.owner))
847 goto error;
848 sd = i2c_get_clientdata(client);
849
850 /* Register with the v4l2_device which increases the module's
851 use count as well. */
852 if (v4l2_device_register_subdev(v4l2_dev, sd))
853 sd = NULL;
854 /* Decrease the module use count to match the first try_module_get. */
855 module_put(client->driver->driver.owner);
856
857 if (sd) {
858 /* We return errors from v4l2_subdev_call only if we have the
859 callback as the .s_config is not mandatory */
860 int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
861
862 if (err && err != -ENOIOCTLCMD) {
863 v4l2_device_unregister_subdev(sd);
864 sd = NULL;
865 }
866 }
867
868error:
869 /* If we have a client but no subdev, then something went wrong and
870 we must unregister the client. */
871 if (client && sd == NULL)
872 i2c_unregister_device(client);
873 return sd;
874}
875EXPORT_SYMBOL_GPL(v4l2_i2c_new_subdev);
876
877/* Probe and load an i2c sub-device. */
878struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
879 struct i2c_adapter *adapter,
880 const char *module_name, const char *client_type,
881 const unsigned short *addrs)
882{
883 struct v4l2_subdev *sd = NULL;
884 struct i2c_client *client = NULL;
885 struct i2c_board_info info;
886
887 BUG_ON(!v4l2_dev);
888
889 if (module_name)
890 request_module(module_name);
891
892 /* Setup the i2c board info with the device type and
893 the device address. */
894 memset(&info, 0, sizeof(info));
895 strlcpy(info.type, client_type, sizeof(info.type));
896
897 /* Probe and create the i2c client */
898 client = i2c_new_probed_device(adapter, &info, addrs);
899 /* Note: it is possible in the future that
900 c->driver is NULL if the driver is still being loaded.
901 We need better support from the kernel so that we
902 can easily wait for the load to finish. */
903 if (client == NULL || client->driver == NULL)
904 goto error;
905
906 /* Lock the module so we can safely get the v4l2_subdev pointer */
907 if (!try_module_get(client->driver->driver.owner))
908 goto error;
909 sd = i2c_get_clientdata(client);
910
911 /* Register with the v4l2_device which increases the module's
912 use count as well. */
913 if (v4l2_device_register_subdev(v4l2_dev, sd))
914 sd = NULL;
915 /* Decrease the module use count to match the first try_module_get. */
916 module_put(client->driver->driver.owner);
917
918 if (sd) {
919 /* We return errors from v4l2_subdev_call only if we have the
920 callback as the .s_config is not mandatory */
921 int err = v4l2_subdev_call(sd, core, s_config, 0, NULL);
922
923 if (err && err != -ENOIOCTLCMD) {
924 v4l2_device_unregister_subdev(sd);
925 sd = NULL;
926 }
927 }
928
929error:
930 /* If we have a client but no subdev, then something went wrong and
931 we must unregister the client. */
932 if (client && sd == NULL)
933 i2c_unregister_device(client);
934 return sd;
935}
936EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev);
937
938struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
939 struct i2c_adapter *adapter,
940 const char *module_name, const char *client_type, u8 addr)
941{
942 unsigned short addrs[2] = { addr, I2C_CLIENT_END };
943
944 return v4l2_i2c_new_probed_subdev(v4l2_dev, adapter,
945 module_name, client_type, addrs);
946}
947EXPORT_SYMBOL_GPL(v4l2_i2c_new_probed_subdev_addr);
948
949/* Load an i2c sub-device. */
950struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev, 817struct v4l2_subdev *v4l2_i2c_new_subdev_board(struct v4l2_device *v4l2_dev,
951 struct i2c_adapter *adapter, const char *module_name, 818 struct i2c_adapter *adapter, const char *module_name,
952 struct i2c_board_info *info, const unsigned short *probe_addrs) 819 struct i2c_board_info *info, const unsigned short *probe_addrs)
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index a7f1b69a7dab..500cbe9891ac 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -66,7 +66,49 @@ static struct device_attribute video_device_attrs[] = {
66 */ 66 */
67static struct video_device *video_device[VIDEO_NUM_DEVICES]; 67static struct video_device *video_device[VIDEO_NUM_DEVICES];
68static DEFINE_MUTEX(videodev_lock); 68static DEFINE_MUTEX(videodev_lock);
69static DECLARE_BITMAP(video_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES); 69static DECLARE_BITMAP(devnode_nums[VFL_TYPE_MAX], VIDEO_NUM_DEVICES);
70
71/* Device node utility functions */
72
73/* Note: these utility functions all assume that vfl_type is in the range
74 [0, VFL_TYPE_MAX-1]. */
75
76#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
77/* Return the bitmap corresponding to vfl_type. */
78static inline unsigned long *devnode_bits(int vfl_type)
79{
80 /* Any types not assigned to fixed minor ranges must be mapped to
81 one single bitmap for the purposes of finding a free node number
82 since all those unassigned types use the same minor range. */
83 int idx = (vfl_type > VFL_TYPE_VTX) ? VFL_TYPE_MAX - 1 : vfl_type;
84
85 return devnode_nums[idx];
86}
87#else
88/* Return the bitmap corresponding to vfl_type. */
89static inline unsigned long *devnode_bits(int vfl_type)
90{
91 return devnode_nums[vfl_type];
92}
93#endif
94
95/* Mark device node number vdev->num as used */
96static inline void devnode_set(struct video_device *vdev)
97{
98 set_bit(vdev->num, devnode_bits(vdev->vfl_type));
99}
100
101/* Mark device node number vdev->num as unused */
102static inline void devnode_clear(struct video_device *vdev)
103{
104 clear_bit(vdev->num, devnode_bits(vdev->vfl_type));
105}
106
107/* Try to find a free device node number in the range [from, to> */
108static inline int devnode_find(struct video_device *vdev, int from, int to)
109{
110 return find_next_zero_bit(devnode_bits(vdev->vfl_type), to, from);
111}
70 112
71struct video_device *video_device_alloc(void) 113struct video_device *video_device_alloc(void)
72{ 114{
@@ -119,8 +161,8 @@ static void v4l2_device_release(struct device *cd)
119 the release() callback. */ 161 the release() callback. */
120 vdev->cdev = NULL; 162 vdev->cdev = NULL;
121 163
122 /* Mark minor as free */ 164 /* Mark device node number as free */
123 clear_bit(vdev->num, video_nums[vdev->vfl_type]); 165 devnode_clear(vdev);
124 166
125 mutex_unlock(&videodev_lock); 167 mutex_unlock(&videodev_lock);
126 168
@@ -299,32 +341,28 @@ static const struct file_operations v4l2_fops = {
299}; 341};
300 342
301/** 343/**
302 * get_index - assign stream number based on parent device 344 * get_index - assign stream index number based on parent device
303 * @vdev: video_device to assign index number to, vdev->parent should be assigned 345 * @vdev: video_device to assign index number to, vdev->parent should be assigned
304 * @num: -1 if auto assign, requested number otherwise
305 * 346 *
306 * Note that when this is called the new device has not yet been registered 347 * Note that when this is called the new device has not yet been registered
307 * in the video_device array. 348 * in the video_device array, but it was able to obtain a minor number.
349 *
350 * This means that we can always obtain a free stream index number since
351 * the worst case scenario is that there are VIDEO_NUM_DEVICES - 1 slots in
352 * use of the video_device array.
308 * 353 *
309 * Returns -ENFILE if num is already in use, a free index number if 354 * Returns a free index number.
310 * successful.
311 */ 355 */
312static int get_index(struct video_device *vdev, int num) 356static int get_index(struct video_device *vdev)
313{ 357{
314 /* This can be static since this function is called with the global 358 /* This can be static since this function is called with the global
315 videodev_lock held. */ 359 videodev_lock held. */
316 static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES); 360 static DECLARE_BITMAP(used, VIDEO_NUM_DEVICES);
317 int i; 361 int i;
318 362
319 if (num >= VIDEO_NUM_DEVICES) { 363 /* Some drivers do not set the parent. In that case always return 0. */
320 printk(KERN_ERR "videodev: %s num is too large\n", __func__);
321 return -EINVAL;
322 }
323
324 /* Some drivers do not set the parent. In that case always return
325 num or 0. */
326 if (vdev->parent == NULL) 364 if (vdev->parent == NULL)
327 return num >= 0 ? num : 0; 365 return 0;
328 366
329 bitmap_zero(used, VIDEO_NUM_DEVICES); 367 bitmap_zero(used, VIDEO_NUM_DEVICES);
330 368
@@ -335,35 +373,23 @@ static int get_index(struct video_device *vdev, int num)
335 } 373 }
336 } 374 }
337 375
338 if (num >= 0) { 376 return find_first_zero_bit(used, VIDEO_NUM_DEVICES);
339 if (test_bit(num, used))
340 return -ENFILE;
341 return num;
342 }
343
344 i = find_first_zero_bit(used, VIDEO_NUM_DEVICES);
345 return i == VIDEO_NUM_DEVICES ? -ENFILE : i;
346} 377}
347 378
348int video_register_device(struct video_device *vdev, int type, int nr)
349{
350 return video_register_device_index(vdev, type, nr, -1);
351}
352EXPORT_SYMBOL(video_register_device);
353
354/** 379/**
355 * video_register_device_index - register video4linux devices 380 * video_register_device - register video4linux devices
356 * @vdev: video device structure we want to register 381 * @vdev: video device structure we want to register
357 * @type: type of device to register 382 * @type: type of device to register
358 * @nr: which device number (0 == /dev/video0, 1 == /dev/video1, ... 383 * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ...
359 * -1 == first free) 384 * -1 == first free)
360 * @index: stream number based on parent device; 385 * @warn_if_nr_in_use: warn if the desired device node number
361 * -1 if auto assign, requested number otherwise 386 * was already in use and another number was chosen instead.
362 * 387 *
363 * The registration code assigns minor numbers based on the type 388 * The registration code assigns minor numbers and device node numbers
364 * requested. -ENFILE is returned in all the device slots for this 389 * based on the requested type and registers the new device node with
365 * category are full. If not then the minor field is set and the 390 * the kernel.
366 * driver initialize function is called (if non %NULL). 391 * An error is returned if no free minor or device node number could be
392 * found, or if the registration of the device node failed.
367 * 393 *
368 * Zero is returned on success. 394 * Zero is returned on success.
369 * 395 *
@@ -377,8 +403,8 @@ EXPORT_SYMBOL(video_register_device);
377 * 403 *
378 * %VFL_TYPE_RADIO - A radio card 404 * %VFL_TYPE_RADIO - A radio card
379 */ 405 */
380int video_register_device_index(struct video_device *vdev, int type, int nr, 406static int __video_register_device(struct video_device *vdev, int type, int nr,
381 int index) 407 int warn_if_nr_in_use)
382{ 408{
383 int i = 0; 409 int i = 0;
384 int ret; 410 int ret;
@@ -421,7 +447,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
421 if (vdev->v4l2_dev && vdev->v4l2_dev->dev) 447 if (vdev->v4l2_dev && vdev->v4l2_dev->dev)
422 vdev->parent = vdev->v4l2_dev->dev; 448 vdev->parent = vdev->v4l2_dev->dev;
423 449
424 /* Part 2: find a free minor, kernel number and device index. */ 450 /* Part 2: find a free minor, device node number and device index. */
425#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES 451#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
426 /* Keep the ranges for the first four types for historical 452 /* Keep the ranges for the first four types for historical
427 * reasons. 453 * reasons.
@@ -452,21 +478,22 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
452 } 478 }
453#endif 479#endif
454 480
455 /* Pick a minor number */ 481 /* Pick a device node number */
456 mutex_lock(&videodev_lock); 482 mutex_lock(&videodev_lock);
457 nr = find_next_zero_bit(video_nums[type], minor_cnt, nr == -1 ? 0 : nr); 483 nr = devnode_find(vdev, nr == -1 ? 0 : nr, minor_cnt);
458 if (nr == minor_cnt) 484 if (nr == minor_cnt)
459 nr = find_first_zero_bit(video_nums[type], minor_cnt); 485 nr = devnode_find(vdev, 0, minor_cnt);
460 if (nr == minor_cnt) { 486 if (nr == minor_cnt) {
461 printk(KERN_ERR "could not get a free kernel number\n"); 487 printk(KERN_ERR "could not get a free device node number\n");
462 mutex_unlock(&videodev_lock); 488 mutex_unlock(&videodev_lock);
463 return -ENFILE; 489 return -ENFILE;
464 } 490 }
465#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES 491#ifdef CONFIG_VIDEO_FIXED_MINOR_RANGES
466 /* 1-on-1 mapping of kernel number to minor number */ 492 /* 1-on-1 mapping of device node number to minor number */
467 i = nr; 493 i = nr;
468#else 494#else
469 /* The kernel number and minor numbers are independent */ 495 /* The device node number and minor numbers are independent, so
496 we just find the first free minor number. */
470 for (i = 0; i < VIDEO_NUM_DEVICES; i++) 497 for (i = 0; i < VIDEO_NUM_DEVICES; i++)
471 if (video_device[i] == NULL) 498 if (video_device[i] == NULL)
472 break; 499 break;
@@ -478,17 +505,13 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
478#endif 505#endif
479 vdev->minor = i + minor_offset; 506 vdev->minor = i + minor_offset;
480 vdev->num = nr; 507 vdev->num = nr;
481 set_bit(nr, video_nums[type]); 508 devnode_set(vdev);
509
482 /* Should not happen since we thought this minor was free */ 510 /* Should not happen since we thought this minor was free */
483 WARN_ON(video_device[vdev->minor] != NULL); 511 WARN_ON(video_device[vdev->minor] != NULL);
484 ret = vdev->index = get_index(vdev, index); 512 vdev->index = get_index(vdev);
485 mutex_unlock(&videodev_lock); 513 mutex_unlock(&videodev_lock);
486 514
487 if (ret < 0) {
488 printk(KERN_ERR "%s: get_index failed\n", __func__);
489 goto cleanup;
490 }
491
492 /* Part 3: Initialize the character device */ 515 /* Part 3: Initialize the character device */
493 vdev->cdev = cdev_alloc(); 516 vdev->cdev = cdev_alloc();
494 if (vdev->cdev == NULL) { 517 if (vdev->cdev == NULL) {
@@ -517,7 +540,7 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
517 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); 540 vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor);
518 if (vdev->parent) 541 if (vdev->parent)
519 vdev->dev.parent = vdev->parent; 542 vdev->dev.parent = vdev->parent;
520 dev_set_name(&vdev->dev, "%s%d", name_base, nr); 543 dev_set_name(&vdev->dev, "%s%d", name_base, vdev->num);
521 ret = device_register(&vdev->dev); 544 ret = device_register(&vdev->dev);
522 if (ret < 0) { 545 if (ret < 0) {
523 printk(KERN_ERR "%s: device_register failed\n", __func__); 546 printk(KERN_ERR "%s: device_register failed\n", __func__);
@@ -527,6 +550,10 @@ int video_register_device_index(struct video_device *vdev, int type, int nr,
527 reference to the device goes away. */ 550 reference to the device goes away. */
528 vdev->dev.release = v4l2_device_release; 551 vdev->dev.release = v4l2_device_release;
529 552
553 if (nr != -1 && nr != vdev->num && warn_if_nr_in_use)
554 printk(KERN_WARNING "%s: requested %s%d, got %s%d\n",
555 __func__, name_base, nr, name_base, vdev->num);
556
530 /* Part 5: Activate this minor. The char device can now be used. */ 557 /* Part 5: Activate this minor. The char device can now be used. */
531 mutex_lock(&videodev_lock); 558 mutex_lock(&videodev_lock);
532 video_device[vdev->minor] = vdev; 559 video_device[vdev->minor] = vdev;
@@ -537,13 +564,24 @@ cleanup:
537 mutex_lock(&videodev_lock); 564 mutex_lock(&videodev_lock);
538 if (vdev->cdev) 565 if (vdev->cdev)
539 cdev_del(vdev->cdev); 566 cdev_del(vdev->cdev);
540 clear_bit(vdev->num, video_nums[type]); 567 devnode_clear(vdev);
541 mutex_unlock(&videodev_lock); 568 mutex_unlock(&videodev_lock);
542 /* Mark this video device as never having been registered. */ 569 /* Mark this video device as never having been registered. */
543 vdev->minor = -1; 570 vdev->minor = -1;
544 return ret; 571 return ret;
545} 572}
546EXPORT_SYMBOL(video_register_device_index); 573
574int video_register_device(struct video_device *vdev, int type, int nr)
575{
576 return __video_register_device(vdev, type, nr, 1);
577}
578EXPORT_SYMBOL(video_register_device);
579
580int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
581{
582 return __video_register_device(vdev, type, nr, 0);
583}
584EXPORT_SYMBOL(video_register_device_no_warn);
547 585
548/** 586/**
549 * video_unregister_device - unregister a video4linux device 587 * video_unregister_device - unregister a video4linux device
diff --git a/drivers/media/video/vino.c b/drivers/media/video/vino.c
index f3b6e15d91f2..cd6a3446ab7e 100644
--- a/drivers/media/video/vino.c
+++ b/drivers/media/video/vino.c
@@ -4333,11 +4333,11 @@ static int __init vino_module_init(void)
4333 vino_init_stage++; 4333 vino_init_stage++;
4334 4334
4335 vino_drvdata->decoder = 4335 vino_drvdata->decoder =
4336 v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev, 4336 v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4337 &vino_i2c_adapter, "saa7191", "saa7191", 0x45); 4337 "saa7191", "saa7191", 0, I2C_ADDRS(0x45));
4338 vino_drvdata->camera = 4338 vino_drvdata->camera =
4339 v4l2_i2c_new_probed_subdev_addr(&vino_drvdata->v4l2_dev, 4339 v4l2_i2c_new_subdev(&vino_drvdata->v4l2_dev, &vino_i2c_adapter,
4340 &vino_i2c_adapter, "indycam", "indycam", 0x2b); 4340 "indycam", "indycam", 0, I2C_ADDRS(0x2b));
4341 4341
4342 dprintk("init complete!\n"); 4342 dprintk("init complete!\n");
4343 4343
diff --git a/drivers/media/video/w9968cf.c b/drivers/media/video/w9968cf.c
index 602484dd3da9..37fcdc447db5 100644
--- a/drivers/media/video/w9968cf.c
+++ b/drivers/media/video/w9968cf.c
@@ -3515,9 +3515,9 @@ w9968cf_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
3515 w9968cf_turn_on_led(cam); 3515 w9968cf_turn_on_led(cam);
3516 3516
3517 w9968cf_i2c_init(cam); 3517 w9968cf_i2c_init(cam);
3518 cam->sensor_sd = v4l2_i2c_new_probed_subdev(&cam->v4l2_dev, 3518 cam->sensor_sd = v4l2_i2c_new_subdev(&cam->v4l2_dev,
3519 &cam->i2c_adapter, 3519 &cam->i2c_adapter,
3520 "ovcamchip", "ovcamchip", addrs); 3520 "ovcamchip", "ovcamchip", 0, addrs);
3521 3521
3522 usb_set_intfdata(intf, cam); 3522 usb_set_intfdata(intf, cam);
3523 mutex_unlock(&cam->dev_mutex); 3523 mutex_unlock(&cam->dev_mutex);
diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c
index 96971044fc78..b3c6436b33ba 100644
--- a/drivers/media/video/zc0301/zc0301_core.c
+++ b/drivers/media/video/zc0301/zc0301_core.c
@@ -819,8 +819,10 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
819 (!list_empty(&cam->outqueue)) || 819 (!list_empty(&cam->outqueue)) ||
820 (cam->state & DEV_DISCONNECTED) || 820 (cam->state & DEV_DISCONNECTED) ||
821 (cam->state & DEV_MISCONFIGURED), 821 (cam->state & DEV_MISCONFIGURED),
822 cam->module_param.frame_timeout * 822 msecs_to_jiffies(
823 1000 * msecs_to_jiffies(1) ); 823 cam->module_param.frame_timeout * 1000
824 )
825 );
824 if (timeout < 0) { 826 if (timeout < 0) {
825 mutex_unlock(&cam->fileop_mutex); 827 mutex_unlock(&cam->fileop_mutex);
826 return timeout; 828 return timeout;
diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c
index 0c4d9b1f8e6f..be70574870de 100644
--- a/drivers/media/video/zoran/zoran_card.c
+++ b/drivers/media/video/zoran/zoran_card.c
@@ -1357,15 +1357,15 @@ static int __devinit zoran_probe(struct pci_dev *pdev,
1357 goto zr_free_irq; 1357 goto zr_free_irq;
1358 } 1358 }
1359 1359
1360 zr->decoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev, 1360 zr->decoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
1361 &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder, 1361 &zr->i2c_adapter, zr->card.mod_decoder, zr->card.i2c_decoder,
1362 zr->card.addrs_decoder); 1362 0, zr->card.addrs_decoder);
1363 1363
1364 if (zr->card.mod_encoder) 1364 if (zr->card.mod_encoder)
1365 zr->encoder = v4l2_i2c_new_probed_subdev(&zr->v4l2_dev, 1365 zr->encoder = v4l2_i2c_new_subdev(&zr->v4l2_dev,
1366 &zr->i2c_adapter, 1366 &zr->i2c_adapter,
1367 zr->card.mod_encoder, zr->card.i2c_encoder, 1367 zr->card.mod_encoder, zr->card.i2c_encoder,
1368 zr->card.addrs_encoder); 1368 0, zr->card.addrs_encoder);
1369 1369
1370 dprintk(2, 1370 dprintk(2,
1371 KERN_INFO "%s: Initializing videocodec bus...\n", 1371 KERN_INFO "%s: Initializing videocodec bus...\n",
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 10d3fcffe91c..82b34893e5b5 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -47,6 +47,8 @@ source "drivers/staging/slicoss/Kconfig"
47 47
48source "drivers/staging/go7007/Kconfig" 48source "drivers/staging/go7007/Kconfig"
49 49
50source "drivers/staging/cx25821/Kconfig"
51
50source "drivers/staging/usbip/Kconfig" 52source "drivers/staging/usbip/Kconfig"
51 53
52source "drivers/staging/winbond/Kconfig" 54source "drivers/staging/winbond/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index c30093bae621..b1cad0d9ba72 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_STAGING) += staging.o
6obj-$(CONFIG_ET131X) += et131x/ 6obj-$(CONFIG_ET131X) += et131x/
7obj-$(CONFIG_SLICOSS) += slicoss/ 7obj-$(CONFIG_SLICOSS) += slicoss/
8obj-$(CONFIG_VIDEO_GO7007) += go7007/ 8obj-$(CONFIG_VIDEO_GO7007) += go7007/
9obj-$(CONFIG_VIDEO_CX25821) += cx25821/
9obj-$(CONFIG_USB_IP_COMMON) += usbip/ 10obj-$(CONFIG_USB_IP_COMMON) += usbip/
10obj-$(CONFIG_W35UND) += winbond/ 11obj-$(CONFIG_W35UND) += winbond/
11obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 12obj-$(CONFIG_PRISM2_USB) += wlan-ng/
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
new file mode 100644
index 000000000000..df7756a95fad
--- /dev/null
+++ b/drivers/staging/cx25821/Kconfig
@@ -0,0 +1,34 @@
1config VIDEO_CX25821
2 tristate "Conexant cx25821 support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT
4 select I2C_ALGOBIT
5 select VIDEO_BTCX
6 select VIDEO_TVEEPROM
7 select VIDEO_IR
8 select VIDEOBUF_DVB
9 select VIDEOBUF_DMA_SG
10 select VIDEO_CX25840
11 select VIDEO_CX2341X
12 ---help---
13 This is a video4linux driver for Conexant 25821 based
14 TV cards.
15
16 To compile this driver as a module, choose M here: the
17 module will be called cx25821
18
19config VIDEO_CX25821_ALSA
20 tristate "Conexant 25821 DMA audio support"
21 depends on VIDEO_CX25821 && SND && EXPERIMENTAL
22 select SND_PCM
23 ---help---
24 This is a video4linux driver for direct (DMA) audio on
25 Conexant 25821 based capture cards using ALSA.
26
27 It only works with boards with function 01 enabled.
28 To check if your board supports, use lspci -n.
29 If supported, you should see 14f1:8801 or 14f1:8811
30 PCI device.
31
32 To compile this driver as a module, choose M here: the
33 module will be called cx25821-alsa.
34
diff --git a/drivers/staging/cx25821/Makefile b/drivers/staging/cx25821/Makefile
new file mode 100644
index 000000000000..10f87f05d8e8
--- /dev/null
+++ b/drivers/staging/cx25821/Makefile
@@ -0,0 +1,14 @@
1cx25821-objs := cx25821-core.o cx25821-cards.o cx25821-i2c.o cx25821-gpio.o \
2 cx25821-medusa-video.o cx25821-video.o cx25821-video0.o cx25821-video1.o \
3 cx25821-video2.o cx25821-video3.o cx25821-video4.o cx25821-video5.o \
4 cx25821-video6.o cx25821-video7.o cx25821-vidups9.o cx25821-vidups10.o \
5 cx25821-audups11.o cx25821-video-upstream.o cx25821-video-upstream-ch2.o \
6 cx25821-audio-upstream.o cx25821-videoioctl.o
7
8obj-$(CONFIG_VIDEO_CX25821) += cx25821.o
9obj-$(CONFIG_VIDEO_CX25821_ALSA) += cx25821-alsa.o
10
11EXTRA_CFLAGS += -Idrivers/media/video
12EXTRA_CFLAGS += -Idrivers/media/common/tuners
13EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
14EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
new file mode 100644
index 000000000000..a9ba50b9888b
--- /dev/null
+++ b/drivers/staging/cx25821/README
@@ -0,0 +1,6 @@
1Todo:
2 - checkpatch.pl cleanups
3 - sparse cleanups
4
5Please send patches to linux-media@vger.kernel.org
6
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
new file mode 100644
index 000000000000..e0eef12759e4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -0,0 +1,789 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on SAA713x ALSA driver and CX88 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, version 2
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25#include <linux/device.h>
26#include <linux/interrupt.h>
27#include <linux/vmalloc.h>
28#include <linux/dma-mapping.h>
29#include <linux/pci.h>
30
31#include <asm/delay.h>
32#include <sound/core.h>
33#include <sound/pcm.h>
34#include <sound/pcm_params.h>
35#include <sound/control.h>
36#include <sound/initval.h>
37#include <sound/tlv.h>
38
39#include "cx25821.h"
40#include "cx25821-reg.h"
41
42#define AUDIO_SRAM_CHANNEL SRAM_CH08
43
44#define dprintk(level,fmt, arg...) if (debug >= level) \
45 printk(KERN_INFO "%s/1: " fmt, chip->dev->name , ## arg)
46
47#define dprintk_core(level,fmt, arg...) if (debug >= level) \
48 printk(KERN_DEBUG "%s/1: " fmt, chip->dev->name , ## arg)
49
50/****************************************************************************
51 Data type declarations - Can be moded to a header file later
52 ****************************************************************************/
53
54static struct snd_card *snd_cx25821_cards[SNDRV_CARDS];
55static int devno;
56
57struct cx25821_audio_dev {
58 struct cx25821_dev *dev;
59 struct cx25821_dmaqueue q;
60
61 /* pci i/o */
62 struct pci_dev *pci;
63
64 /* audio controls */
65 int irq;
66
67 struct snd_card *card;
68
69 unsigned long iobase;
70 spinlock_t reg_lock;
71 atomic_t count;
72
73 unsigned int dma_size;
74 unsigned int period_size;
75 unsigned int num_periods;
76
77 struct videobuf_dmabuf *dma_risc;
78
79 struct cx25821_buffer *buf;
80
81 struct snd_pcm_substream *substream;
82};
83typedef struct cx25821_audio_dev snd_cx25821_card_t;
84
85
86/****************************************************************************
87 Module global static vars
88 ****************************************************************************/
89
90static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
91static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
92static int enable[SNDRV_CARDS] = { 1,[1 ... (SNDRV_CARDS - 1)] = 1 };
93
94module_param_array(enable, bool, NULL, 0444);
95MODULE_PARM_DESC(enable, "Enable cx25821 soundcard. default enabled.");
96
97module_param_array(index, int, NULL, 0444);
98MODULE_PARM_DESC(index, "Index value for cx25821 capture interface(s).");
99
100/****************************************************************************
101 Module macros
102 ****************************************************************************/
103
104MODULE_DESCRIPTION("ALSA driver module for cx25821 based capture cards");
105MODULE_AUTHOR("Hiep Huynh");
106MODULE_LICENSE("GPL");
107MODULE_SUPPORTED_DEVICE("{{Conexant,25821}"); //"{{Conexant,23881},"
108
109static unsigned int debug;
110module_param(debug, int, 0644);
111MODULE_PARM_DESC(debug, "enable debug messages");
112
113/****************************************************************************
114 Module specific funtions
115 ****************************************************************************/
116/* Constants taken from cx88-reg.h */
117#define AUD_INT_DN_RISCI1 (1 << 0)
118#define AUD_INT_UP_RISCI1 (1 << 1)
119#define AUD_INT_RDS_DN_RISCI1 (1 << 2)
120#define AUD_INT_DN_RISCI2 (1 << 4) /* yes, 3 is skipped */
121#define AUD_INT_UP_RISCI2 (1 << 5)
122#define AUD_INT_RDS_DN_RISCI2 (1 << 6)
123#define AUD_INT_DN_SYNC (1 << 12)
124#define AUD_INT_UP_SYNC (1 << 13)
125#define AUD_INT_RDS_DN_SYNC (1 << 14)
126#define AUD_INT_OPC_ERR (1 << 16)
127#define AUD_INT_BER_IRQ (1 << 20)
128#define AUD_INT_MCHG_IRQ (1 << 21)
129#define GP_COUNT_CONTROL_RESET 0x3
130
131#define PCI_MSK_AUD_EXT (1 << 4)
132#define PCI_MSK_AUD_INT (1 << 3)
133/*
134 * BOARD Specific: Sets audio DMA
135 */
136
137static int _cx25821_start_audio_dma(snd_cx25821_card_t * chip)
138{
139 struct cx25821_buffer *buf = chip->buf;
140 struct cx25821_dev *dev = chip->dev;
141 struct sram_channel *audio_ch =
142 &cx25821_sram_channels[AUDIO_SRAM_CHANNEL];
143 u32 tmp = 0;
144
145 // enable output on the GPIO 0 for the MCLK ADC (Audio)
146 cx25821_set_gpiopin_direction(chip->dev, 0, 0);
147
148 /* Make sure RISC/FIFO are off before changing FIFO/RISC settings */
149 cx_clear(AUD_INT_DMA_CTL,
150 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
151
152 /* setup fifo + format - out channel */
153 cx25821_sram_channel_setup_audio(chip->dev, audio_ch, buf->bpl,
154 buf->risc.dma);
155
156 /* sets bpl size */
157 cx_write(AUD_A_LNGTH, buf->bpl);
158
159 /* reset counter */
160 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET); //GP_COUNT_CONTROL_RESET = 0x3
161 atomic_set(&chip->count, 0);
162
163 //Set the input mode to 16-bit
164 tmp = cx_read(AUD_A_CFG);
165 cx_write(AUD_A_CFG,
166 tmp | FLD_AUD_DST_PK_MODE | FLD_AUD_DST_ENABLE |
167 FLD_AUD_CLK_ENABLE);
168
169 //printk(KERN_INFO "DEBUG: Start audio DMA, %d B/line, cmds_start(0x%x)= %d lines/FIFO, %d periods, %d "
170 // "byte buffer\n", buf->bpl, audio_ch->cmds_start, cx_read(audio_ch->cmds_start + 12)>>1,
171 // chip->num_periods, buf->bpl * chip->num_periods);
172
173 /* Enables corresponding bits at AUD_INT_STAT */
174 cx_write(AUD_A_INT_MSK,
175 FLD_AUD_DST_RISCI1 | FLD_AUD_DST_OF | FLD_AUD_DST_SYNC |
176 FLD_AUD_DST_OPC_ERR);
177
178 /* Clean any pending interrupt bits already set */
179 cx_write(AUD_A_INT_STAT, ~0);
180
181 /* enable audio irqs */
182 cx_set(PCI_INT_MSK, chip->dev->pci_irqmask | PCI_MSK_AUD_INT);
183
184 // Turn on audio downstream fifo and risc enable 0x101
185 tmp = cx_read(AUD_INT_DMA_CTL);
186 cx_set(AUD_INT_DMA_CTL,
187 tmp | (FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN));
188
189 mdelay(100);
190 return 0;
191}
192
193/*
194 * BOARD Specific: Resets audio DMA
195 */
196static int _cx25821_stop_audio_dma(snd_cx25821_card_t * chip)
197{
198 struct cx25821_dev *dev = chip->dev;
199
200 /* stop dma */
201 cx_clear(AUD_INT_DMA_CTL,
202 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
203
204 /* disable irqs */
205 cx_clear(PCI_INT_MSK, PCI_MSK_AUD_INT);
206 cx_clear(AUD_A_INT_MSK,
207 AUD_INT_OPC_ERR | AUD_INT_DN_SYNC | AUD_INT_DN_RISCI2 |
208 AUD_INT_DN_RISCI1);
209
210 return 0;
211}
212
213#define MAX_IRQ_LOOP 50
214
215/*
216 * BOARD Specific: IRQ dma bits
217 */
218static char *cx25821_aud_irqs[32] = {
219 "dn_risci1", "up_risci1", "rds_dn_risc1", /* 0-2 */
220 NULL, /* reserved */
221 "dn_risci2", "up_risci2", "rds_dn_risc2", /* 4-6 */
222 NULL, /* reserved */
223 "dnf_of", "upf_uf", "rds_dnf_uf", /* 8-10 */
224 NULL, /* reserved */
225 "dn_sync", "up_sync", "rds_dn_sync", /* 12-14 */
226 NULL, /* reserved */
227 "opc_err", "par_err", "rip_err", /* 16-18 */
228 "pci_abort", "ber_irq", "mchg_irq" /* 19-21 */
229};
230
231/*
232 * BOARD Specific: Threats IRQ audio specific calls
233 */
234static void cx25821_aud_irq(snd_cx25821_card_t * chip, u32 status, u32 mask)
235{
236 struct cx25821_dev *dev = chip->dev;
237
238 if (0 == (status & mask)) {
239 return;
240 }
241
242 cx_write(AUD_A_INT_STAT, status);
243 if (debug > 1 || (status & mask & ~0xff))
244 cx25821_print_irqbits(dev->name, "irq aud",
245 cx25821_aud_irqs,
246 ARRAY_SIZE(cx25821_aud_irqs), status,
247 mask);
248
249 /* risc op code error */
250 if (status & AUD_INT_OPC_ERR) {
251 printk(KERN_WARNING "WARNING %s/1: Audio risc op code error\n",
252 dev->name);
253
254 cx_clear(AUD_INT_DMA_CTL,
255 FLD_AUD_DST_A_RISC_EN | FLD_AUD_DST_A_FIFO_EN);
256 cx25821_sram_channel_dump_audio(dev,
257 &cx25821_sram_channels
258 [AUDIO_SRAM_CHANNEL]);
259 }
260 if (status & AUD_INT_DN_SYNC) {
261 printk(KERN_WARNING "WARNING %s: Downstream sync error!\n",
262 dev->name);
263 cx_write(AUD_A_GPCNT_CTL, GP_COUNT_CONTROL_RESET);
264 return;
265 }
266
267 /* risc1 downstream */
268 if (status & AUD_INT_DN_RISCI1) {
269 atomic_set(&chip->count, cx_read(AUD_A_GPCNT));
270 snd_pcm_period_elapsed(chip->substream);
271 }
272}
273
274/*
275 * BOARD Specific: Handles IRQ calls
276 */
277static irqreturn_t cx25821_irq(int irq, void *dev_id)
278{
279 snd_cx25821_card_t *chip = dev_id;
280 struct cx25821_dev *dev = chip->dev;
281 u32 status, pci_status;
282 u32 audint_status, audint_mask;
283 int loop, handled = 0;
284 int audint_count = 0;
285
286 audint_status = cx_read(AUD_A_INT_STAT);
287 audint_mask = cx_read(AUD_A_INT_MSK);
288 audint_count = cx_read(AUD_A_GPCNT);
289 status = cx_read(PCI_INT_STAT);
290
291 for (loop = 0; loop < 1; loop++) {
292 status = cx_read(PCI_INT_STAT);
293 if (0 == status) {
294 status = cx_read(PCI_INT_STAT);
295 audint_status = cx_read(AUD_A_INT_STAT);
296 audint_mask = cx_read(AUD_A_INT_MSK);
297
298 if (status) {
299 handled = 1;
300 cx_write(PCI_INT_STAT, status);
301
302 cx25821_aud_irq(chip, audint_status,
303 audint_mask);
304 break;
305 } else
306 goto out;
307 }
308
309 handled = 1;
310 cx_write(PCI_INT_STAT, status);
311
312 cx25821_aud_irq(chip, audint_status, audint_mask);
313 }
314
315 pci_status = cx_read(PCI_INT_STAT);
316
317 if (handled)
318 cx_write(PCI_INT_STAT, pci_status);
319
320 out:
321 return IRQ_RETVAL(handled);
322}
323
324static int dsp_buffer_free(snd_cx25821_card_t * chip)
325{
326 BUG_ON(!chip->dma_size);
327
328 dprintk(2, "Freeing buffer\n");
329 videobuf_sg_dma_unmap(&chip->pci->dev, chip->dma_risc);
330 videobuf_dma_free(chip->dma_risc);
331 btcx_riscmem_free(chip->pci, &chip->buf->risc);
332 kfree(chip->buf);
333
334 chip->dma_risc = NULL;
335 chip->dma_size = 0;
336
337 return 0;
338}
339
340/****************************************************************************
341 ALSA PCM Interface
342 ****************************************************************************/
343
344/*
345 * Digital hardware definition
346 */
347#define DEFAULT_FIFO_SIZE 384
348static struct snd_pcm_hardware snd_cx25821_digital_hw = {
349 .info = SNDRV_PCM_INFO_MMAP |
350 SNDRV_PCM_INFO_INTERLEAVED |
351 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID,
352 .formats = SNDRV_PCM_FMTBIT_S16_LE,
353
354 .rates = SNDRV_PCM_RATE_48000,
355 .rate_min = 48000,
356 .rate_max = 48000,
357 .channels_min = 2,
358 .channels_max = 2,
359 /* Analog audio output will be full of clicks and pops if there
360 are not exactly four lines in the SRAM FIFO buffer. */
361 .period_bytes_min = DEFAULT_FIFO_SIZE / 3,
362 .period_bytes_max = DEFAULT_FIFO_SIZE / 3,
363 .periods_min = 1,
364 .periods_max = AUDIO_LINE_SIZE,
365 .buffer_bytes_max = (AUDIO_LINE_SIZE * AUDIO_LINE_SIZE), //128*128 = 16384 = 1024 * 16
366};
367
368/*
369 * audio pcm capture open callback
370 */
371static int snd_cx25821_pcm_open(struct snd_pcm_substream *substream)
372{
373 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
374 struct snd_pcm_runtime *runtime = substream->runtime;
375 int err;
376 unsigned int bpl = 0;
377
378 if (!chip) {
379 printk(KERN_ERR "DEBUG: cx25821 can't find device struct."
380 " Can't proceed with open\n");
381 return -ENODEV;
382 }
383
384 err =
385 snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_PERIODS);
386 if (err < 0)
387 goto _error;
388
389 chip->substream = substream;
390
391 runtime->hw = snd_cx25821_digital_hw;
392
393 if (cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size !=
394 DEFAULT_FIFO_SIZE) {
395 bpl = cx25821_sram_channels[AUDIO_SRAM_CHANNEL].fifo_size / 3; //since there are 3 audio Clusters
396 bpl &= ~7; /* must be multiple of 8 */
397
398 if (bpl > AUDIO_LINE_SIZE) {
399 bpl = AUDIO_LINE_SIZE;
400 }
401 runtime->hw.period_bytes_min = bpl;
402 runtime->hw.period_bytes_max = bpl;
403 }
404
405 return 0;
406 _error:
407 dprintk(1, "Error opening PCM!\n");
408 return err;
409}
410
411/*
412 * audio close callback
413 */
414static int snd_cx25821_close(struct snd_pcm_substream *substream)
415{
416 return 0;
417}
418
419/*
420 * hw_params callback
421 */
422static int snd_cx25821_hw_params(struct snd_pcm_substream *substream,
423 struct snd_pcm_hw_params *hw_params)
424{
425 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
426 struct videobuf_dmabuf *dma;
427
428 struct cx25821_buffer *buf;
429 int ret;
430
431 if (substream->runtime->dma_area) {
432 dsp_buffer_free(chip);
433 substream->runtime->dma_area = NULL;
434 }
435
436 chip->period_size = params_period_bytes(hw_params);
437 chip->num_periods = params_periods(hw_params);
438 chip->dma_size = chip->period_size * params_periods(hw_params);
439
440 BUG_ON(!chip->dma_size);
441 BUG_ON(chip->num_periods & (chip->num_periods - 1));
442
443 buf = videobuf_sg_alloc(sizeof(*buf));
444 if (NULL == buf)
445 return -ENOMEM;
446
447 if (chip->period_size > AUDIO_LINE_SIZE) {
448 chip->period_size = AUDIO_LINE_SIZE;
449 }
450
451 buf->vb.memory = V4L2_MEMORY_MMAP;
452 buf->vb.field = V4L2_FIELD_NONE;
453 buf->vb.width = chip->period_size;
454 buf->bpl = chip->period_size;
455 buf->vb.height = chip->num_periods;
456 buf->vb.size = chip->dma_size;
457
458 dma = videobuf_to_dma(&buf->vb);
459 videobuf_dma_init(dma);
460
461 ret = videobuf_dma_init_kernel(dma, PCI_DMA_FROMDEVICE,
462 (PAGE_ALIGN(buf->vb.size) >>
463 PAGE_SHIFT));
464 if (ret < 0)
465 goto error;
466
467 ret = videobuf_sg_dma_map(&chip->pci->dev, dma);
468 if (ret < 0)
469 goto error;
470
471 ret =
472 cx25821_risc_databuffer_audio(chip->pci, &buf->risc, dma->sglist,
473 buf->vb.width, buf->vb.height, 1);
474 if (ret < 0) {
475 printk(KERN_INFO
476 "DEBUG: ERROR after cx25821_risc_databuffer_audio() \n");
477 goto error;
478 }
479
480 /* Loop back to start of program */
481 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
482 buf->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
483 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
484
485 buf->vb.state = VIDEOBUF_PREPARED;
486
487 chip->buf = buf;
488 chip->dma_risc = dma;
489
490 substream->runtime->dma_area = chip->dma_risc->vmalloc;
491 substream->runtime->dma_bytes = chip->dma_size;
492 substream->runtime->dma_addr = 0;
493
494 return 0;
495
496 error:
497 kfree(buf);
498 return ret;
499}
500
501/*
502 * hw free callback
503 */
504static int snd_cx25821_hw_free(struct snd_pcm_substream *substream)
505{
506 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
507
508 if (substream->runtime->dma_area) {
509 dsp_buffer_free(chip);
510 substream->runtime->dma_area = NULL;
511 }
512
513 return 0;
514}
515
516/*
517 * prepare callback
518 */
519static int snd_cx25821_prepare(struct snd_pcm_substream *substream)
520{
521 return 0;
522}
523
524/*
525 * trigger callback
526 */
527static int snd_cx25821_card_trigger(struct snd_pcm_substream *substream,
528 int cmd)
529{
530 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
531 int err = 0;
532
533 /* Local interrupts are already disabled by ALSA */
534 spin_lock(&chip->reg_lock);
535
536 switch (cmd) {
537 case SNDRV_PCM_TRIGGER_START:
538 err = _cx25821_start_audio_dma(chip);
539 break;
540 case SNDRV_PCM_TRIGGER_STOP:
541 err = _cx25821_stop_audio_dma(chip);
542 break;
543 default:
544 err = -EINVAL;
545 break;
546 }
547
548 spin_unlock(&chip->reg_lock);
549
550 return err;
551}
552
553/*
554 * pointer callback
555 */
556static snd_pcm_uframes_t snd_cx25821_pointer(struct snd_pcm_substream
557 *substream)
558{
559 snd_cx25821_card_t *chip = snd_pcm_substream_chip(substream);
560 struct snd_pcm_runtime *runtime = substream->runtime;
561 u16 count;
562
563 count = atomic_read(&chip->count);
564
565 return runtime->period_size * (count & (runtime->periods - 1));
566}
567
568/*
569 * page callback (needed for mmap)
570 */
571static struct page *snd_cx25821_page(struct snd_pcm_substream *substream,
572 unsigned long offset)
573{
574 void *pageptr = substream->runtime->dma_area + offset;
575
576 return vmalloc_to_page(pageptr);
577}
578
579/*
580 * operators
581 */
582static struct snd_pcm_ops snd_cx25821_pcm_ops = {
583 .open = snd_cx25821_pcm_open,
584 .close = snd_cx25821_close,
585 .ioctl = snd_pcm_lib_ioctl,
586 .hw_params = snd_cx25821_hw_params,
587 .hw_free = snd_cx25821_hw_free,
588 .prepare = snd_cx25821_prepare,
589 .trigger = snd_cx25821_card_trigger,
590 .pointer = snd_cx25821_pointer,
591 .page = snd_cx25821_page,
592};
593
594/*
595 * ALSA create a PCM device: Called when initializing the board. Sets up the name and hooks up
596 * the callbacks
597 */
598static int snd_cx25821_pcm(snd_cx25821_card_t * chip, int device, char *name)
599{
600 struct snd_pcm *pcm;
601 int err;
602
603 err = snd_pcm_new(chip->card, name, device, 0, 1, &pcm);
604 if (err < 0) {
605 printk(KERN_INFO "ERROR: FAILED snd_pcm_new() in %s\n",
606 __func__);
607 return err;
608 }
609 pcm->private_data = chip;
610 pcm->info_flags = 0;
611 strcpy(pcm->name, name);
612 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_cx25821_pcm_ops);
613
614 return 0;
615}
616
617/****************************************************************************
618 Basic Flow for Sound Devices
619 ****************************************************************************/
620
621/*
622 * PCI ID Table - 14f1:8801 and 14f1:8811 means function 1: Audio
623 * Only boards with eeprom and byte 1 at eeprom=1 have it
624 */
625
626static struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = {
627 {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
628 {0,}
629};
630
631MODULE_DEVICE_TABLE(pci, cx25821_audio_pci_tbl);
632
633/*
634 * Not used in the function snd_cx25821_dev_free so removing
635 * from the file.
636 */
637/*
638static int snd_cx25821_free(snd_cx25821_card_t *chip)
639{
640 if (chip->irq >= 0)
641 free_irq(chip->irq, chip);
642
643 cx25821_dev_unregister(chip->dev);
644 pci_disable_device(chip->pci);
645
646 return 0;
647}
648*/
649
650/*
651 * Component Destructor
652 */
653static void snd_cx25821_dev_free(struct snd_card *card)
654{
655 snd_cx25821_card_t *chip = card->private_data;
656
657 //snd_cx25821_free(chip);
658 snd_card_free(chip->card);
659}
660
661/*
662 * Alsa Constructor - Component probe
663 */
664static int cx25821_audio_initdev(struct cx25821_dev *dev)
665{
666 struct snd_card *card;
667 snd_cx25821_card_t *chip;
668 int err;
669
670 if (devno >= SNDRV_CARDS) {
671 printk(KERN_INFO "DEBUG ERROR: devno >= SNDRV_CARDS %s\n",
672 __func__);
673 return (-ENODEV);
674 }
675
676 if (!enable[devno]) {
677 ++devno;
678 printk(KERN_INFO "DEBUG ERROR: !enable[devno] %s\n", __func__);
679 return (-ENOENT);
680 }
681
682 err = snd_card_create(index[devno], id[devno], THIS_MODULE,
683 sizeof(snd_cx25821_card_t), &card);
684 if (err < 0) {
685 printk(KERN_INFO
686 "DEBUG ERROR: cannot create snd_card_new in %s\n",
687 __func__);
688 return err;
689 }
690
691 strcpy(card->driver, "cx25821");
692
693 /* Card "creation" */
694 card->private_free = snd_cx25821_dev_free;
695 chip = (snd_cx25821_card_t *) card->private_data;
696 spin_lock_init(&chip->reg_lock);
697
698 chip->dev = dev;
699 chip->card = card;
700 chip->pci = dev->pci;
701 chip->iobase = pci_resource_start(dev->pci, 0);
702
703 chip->irq = dev->pci->irq;
704
705 err = request_irq(dev->pci->irq, cx25821_irq,
706 IRQF_SHARED | IRQF_DISABLED, chip->dev->name, chip);
707
708 if (err < 0) {
709 printk(KERN_ERR "ERROR %s: can't get IRQ %d for ALSA\n",
710 chip->dev->name, dev->pci->irq);
711 goto error;
712 }
713
714 if ((err = snd_cx25821_pcm(chip, 0, "cx25821 Digital")) < 0) {
715 printk(KERN_INFO
716 "DEBUG ERROR: cannot create snd_cx25821_pcm %s\n",
717 __func__);
718 goto error;
719 }
720
721 snd_card_set_dev(card, &chip->pci->dev);
722
723 strcpy(card->shortname, "cx25821");
724 sprintf(card->longname, "%s at 0x%lx irq %d", chip->dev->name,
725 chip->iobase, chip->irq);
726 strcpy(card->mixername, "CX25821");
727
728 printk(KERN_INFO "%s/%i: ALSA support for cx25821 boards\n",
729 card->driver, devno);
730
731 err = snd_card_register(card);
732 if (err < 0) {
733 printk(KERN_INFO "DEBUG ERROR: cannot register sound card %s\n",
734 __func__);
735 goto error;
736 }
737
738 snd_cx25821_cards[devno] = card;
739
740 devno++;
741 return 0;
742
743 error:
744 snd_card_free(card);
745 return err;
746}
747
748/****************************************************************************
749 LINUX MODULE INIT
750 ****************************************************************************/
751static void cx25821_audio_fini(void)
752{
753 snd_card_free(snd_cx25821_cards[0]);
754}
755
756/*
757 * Module initializer
758 *
759 * Loops through present saa7134 cards, and assigns an ALSA device
760 * to each one
761 *
762 */
763static int cx25821_alsa_init(void)
764{
765 struct cx25821_dev *dev = NULL;
766 struct list_head *list;
767
768 list_for_each(list, &cx25821_devlist) {
769 dev = list_entry(list, struct cx25821_dev, devlist);
770 cx25821_audio_initdev(dev);
771 }
772
773 if (dev == NULL)
774 printk(KERN_INFO
775 "cx25821 ERROR ALSA: no cx25821 cards found\n");
776
777 return 0;
778
779}
780
781late_initcall(cx25821_alsa_init);
782module_exit(cx25821_audio_fini);
783
784/* ----------------------------------------------------------- */
785/*
786 * Local variables:
787 * c-basic-offset: 8
788 * End:
789 */
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/staging/cx25821/cx25821-audio-upstream.c
new file mode 100644
index 000000000000..ddddf651266b
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.c
@@ -0,0 +1,804 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821-video.h"
24#include "cx25821-audio-upstream.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <linux/delay.h>
35#include <asm/uaccess.h>
36
37MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
38MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
39MODULE_LICENSE("GPL");
40
41static int _intr_msk =
42 FLD_AUD_SRC_RISCI1 | FLD_AUD_SRC_OF | FLD_AUD_SRC_SYNC |
43 FLD_AUD_SRC_OPC_ERR;
44
45int cx25821_sram_channel_setup_upstream_audio(struct cx25821_dev *dev,
46 struct sram_channel *ch,
47 unsigned int bpl, u32 risc)
48{
49 unsigned int i, lines;
50 u32 cdt;
51
52 if (ch->cmds_start == 0) {
53 cx_write(ch->ptr1_reg, 0);
54 cx_write(ch->ptr2_reg, 0);
55 cx_write(ch->cnt2_reg, 0);
56 cx_write(ch->cnt1_reg, 0);
57 return 0;
58 }
59
60 bpl = (bpl + 7) & ~7; /* alignment */
61 cdt = ch->cdt;
62 lines = ch->fifo_size / bpl;
63
64 if (lines > 3) {
65 lines = 3;
66 }
67
68 BUG_ON(lines < 2);
69
70 /* write CDT */
71 for (i = 0; i < lines; i++) {
72 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
73 cx_write(cdt + 16 * i + 4, 0);
74 cx_write(cdt + 16 * i + 8, 0);
75 cx_write(cdt + 16 * i + 12, 0);
76 }
77
78 /* write CMDS */
79 cx_write(ch->cmds_start + 0, risc);
80
81 cx_write(ch->cmds_start + 4, 0);
82 cx_write(ch->cmds_start + 8, cdt);
83 cx_write(ch->cmds_start + 12, AUDIO_CDT_SIZE_QW);
84 cx_write(ch->cmds_start + 16, ch->ctrl_start);
85
86 //IQ size
87 cx_write(ch->cmds_start + 20, AUDIO_IQ_SIZE_DW);
88
89 for (i = 24; i < 80; i += 4)
90 cx_write(ch->cmds_start + i, 0);
91
92 /* fill registers */
93 cx_write(ch->ptr1_reg, ch->fifo_start);
94 cx_write(ch->ptr2_reg, cdt);
95 cx_write(ch->cnt2_reg, AUDIO_CDT_SIZE_QW);
96 cx_write(ch->cnt1_reg, AUDIO_CLUSTER_SIZE_QW - 1);
97
98 return 0;
99}
100
101static __le32 *cx25821_risc_field_upstream_audio(struct cx25821_dev *dev,
102 __le32 * rp,
103 dma_addr_t databuf_phys_addr,
104 unsigned int bpl,
105 int fifo_enable)
106{
107 unsigned int line;
108 struct sram_channel *sram_ch =
109 &dev->sram_channels[dev->_audio_upstream_channel_select];
110 int offset = 0;
111
112 /* scan lines */
113 for (line = 0; line < LINES_PER_AUDIO_BUFFER; line++) {
114 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
115 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
116 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
117
118 // Check if we need to enable the FIFO after the first 3 lines
119 // For the upstream audio channel, the risc engine will enable the FIFO.
120 if (fifo_enable && line == 2) {
121 *(rp++) = RISC_WRITECR;
122 *(rp++) = sram_ch->dma_ctl;
123 *(rp++) = sram_ch->fld_aud_fifo_en;
124 *(rp++) = 0x00000020;
125 }
126
127 offset += AUDIO_LINE_SIZE;
128 }
129
130 return rp;
131}
132
133int cx25821_risc_buffer_upstream_audio(struct cx25821_dev *dev,
134 struct pci_dev *pci,
135 unsigned int bpl, unsigned int lines)
136{
137 __le32 *rp;
138 int fifo_enable = 0;
139 int frame = 0, i = 0;
140 int frame_size = AUDIO_DATA_BUF_SZ;
141 int databuf_offset = 0;
142 int risc_flag = RISC_CNT_INC;
143 dma_addr_t risc_phys_jump_addr;
144
145 /* Virtual address of Risc buffer program */
146 rp = dev->_risc_virt_addr;
147
148 /* sync instruction */
149 *(rp++) = cpu_to_le32(RISC_RESYNC | AUDIO_SYNC_LINE);
150
151 for (frame = 0; frame < NUM_AUDIO_FRAMES; frame++) {
152 databuf_offset = frame_size * frame;
153
154 if (frame == 0) {
155 fifo_enable = 1;
156 risc_flag = RISC_CNT_RESET;
157 } else {
158 fifo_enable = 0;
159 risc_flag = RISC_CNT_INC;
160 }
161
162 //Calculate physical jump address
163 if ((frame + 1) == NUM_AUDIO_FRAMES) {
164 risc_phys_jump_addr =
165 dev->_risc_phys_start_addr +
166 RISC_SYNC_INSTRUCTION_SIZE;
167 } else {
168 risc_phys_jump_addr =
169 dev->_risc_phys_start_addr +
170 RISC_SYNC_INSTRUCTION_SIZE +
171 AUDIO_RISC_DMA_BUF_SIZE * (frame + 1);
172 }
173
174 rp = cx25821_risc_field_upstream_audio(dev, rp,
175 dev->
176 _audiodata_buf_phys_addr
177 + databuf_offset, bpl,
178 fifo_enable);
179
180 if (USE_RISC_NOOP_AUDIO) {
181 for (i = 0; i < NUM_NO_OPS; i++) {
182 *(rp++) = cpu_to_le32(RISC_NOOP);
183 }
184 }
185
186 // Loop to (Nth)FrameRISC or to Start of Risc program & generate IRQ
187 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
188 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
189 *(rp++) = cpu_to_le32(0);
190
191 //Recalculate virtual address based on frame index
192 rp = dev->_risc_virt_addr + RISC_SYNC_INSTRUCTION_SIZE / 4 +
193 (AUDIO_RISC_DMA_BUF_SIZE * (frame + 1) / 4);
194 }
195
196 return 0;
197}
198
199void cx25821_free_memory_audio(struct cx25821_dev *dev)
200{
201 if (dev->_risc_virt_addr) {
202 pci_free_consistent(dev->pci, dev->_audiorisc_size,
203 dev->_risc_virt_addr, dev->_risc_phys_addr);
204 dev->_risc_virt_addr = NULL;
205 }
206
207 if (dev->_audiodata_buf_virt_addr) {
208 pci_free_consistent(dev->pci, dev->_audiodata_buf_size,
209 dev->_audiodata_buf_virt_addr,
210 dev->_audiodata_buf_phys_addr);
211 dev->_audiodata_buf_virt_addr = NULL;
212 }
213}
214
215void cx25821_stop_upstream_audio(struct cx25821_dev *dev)
216{
217 struct sram_channel *sram_ch =
218 &dev->sram_channels[AUDIO_UPSTREAM_SRAM_CHANNEL_B];
219 u32 tmp = 0;
220
221 if (!dev->_audio_is_running) {
222 printk
223 ("cx25821: No audio file is currently running so return!\n");
224 return;
225 }
226 //Disable RISC interrupts
227 cx_write(sram_ch->int_msk, 0);
228
229 //Turn OFF risc and fifo enable in AUD_DMA_CNTRL
230 tmp = cx_read(sram_ch->dma_ctl);
231 cx_write(sram_ch->dma_ctl,
232 tmp & ~(sram_ch->fld_aud_fifo_en | sram_ch->fld_aud_risc_en));
233
234 //Clear data buffer memory
235 if (dev->_audiodata_buf_virt_addr)
236 memset(dev->_audiodata_buf_virt_addr, 0,
237 dev->_audiodata_buf_size);
238
239 dev->_audio_is_running = 0;
240 dev->_is_first_audio_frame = 0;
241 dev->_audioframe_count = 0;
242 dev->_audiofile_status = END_OF_FILE;
243
244 if (dev->_irq_audio_queues) {
245 kfree(dev->_irq_audio_queues);
246 dev->_irq_audio_queues = NULL;
247 }
248
249 if (dev->_audiofilename != NULL)
250 kfree(dev->_audiofilename);
251}
252
253void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev)
254{
255 if (dev->_audio_is_running) {
256 cx25821_stop_upstream_audio(dev);
257 }
258
259 cx25821_free_memory_audio(dev);
260}
261
262int cx25821_get_audio_data(struct cx25821_dev *dev,
263 struct sram_channel *sram_ch)
264{
265 struct file *myfile;
266 int frame_index_temp = dev->_audioframe_index;
267 int i = 0;
268 int line_size = AUDIO_LINE_SIZE;
269 int frame_size = AUDIO_DATA_BUF_SZ;
270 int frame_offset = frame_size * frame_index_temp;
271 ssize_t vfs_read_retval = 0;
272 char mybuf[line_size];
273 loff_t file_offset = dev->_audioframe_count * frame_size;
274 loff_t pos;
275 mm_segment_t old_fs;
276
277 if (dev->_audiofile_status == END_OF_FILE)
278 return 0;
279
280 myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
281
282 if (IS_ERR(myfile)) {
283 const int open_errno = -PTR_ERR(myfile);
284 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
285 __func__, dev->_audiofilename, open_errno);
286 return PTR_ERR(myfile);
287 } else {
288 if (!(myfile->f_op)) {
289 printk("%s: File has no file operations registered!\n",
290 __func__);
291 filp_close(myfile, NULL);
292 return -EIO;
293 }
294
295 if (!myfile->f_op->read) {
296 printk("%s: File has no READ operations registered! \n",
297 __func__);
298 filp_close(myfile, NULL);
299 return -EIO;
300 }
301
302 pos = myfile->f_pos;
303 old_fs = get_fs();
304 set_fs(KERNEL_DS);
305
306 for (i = 0; i < dev->_audio_lines_count; i++) {
307 pos = file_offset;
308
309 vfs_read_retval =
310 vfs_read(myfile, mybuf, line_size, &pos);
311
312 if (vfs_read_retval > 0 && vfs_read_retval == line_size
313 && dev->_audiodata_buf_virt_addr != NULL) {
314 memcpy((void *)(dev->_audiodata_buf_virt_addr +
315 frame_offset / 4), mybuf,
316 vfs_read_retval);
317 }
318
319 file_offset += vfs_read_retval;
320 frame_offset += vfs_read_retval;
321
322 if (vfs_read_retval < line_size) {
323 printk(KERN_INFO
324 "Done: exit %s() since no more bytes to read from Audio file.\n",
325 __func__);
326 break;
327 }
328 }
329
330 if (i > 0)
331 dev->_audioframe_count++;
332
333 dev->_audiofile_status =
334 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
335
336 set_fs(old_fs);
337 filp_close(myfile, NULL);
338 }
339
340 return 0;
341}
342
343static void cx25821_audioups_handler(struct work_struct *work)
344{
345 struct cx25821_dev *dev =
346 container_of(work, struct cx25821_dev, _audio_work_entry);
347
348 if (!dev) {
349 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
350 __func__);
351 return;
352 }
353
354 cx25821_get_audio_data(dev,
355 &dev->sram_channels[dev->
356 _audio_upstream_channel_select]);
357}
358
359int cx25821_openfile_audio(struct cx25821_dev *dev,
360 struct sram_channel *sram_ch)
361{
362 struct file *myfile;
363 int i = 0, j = 0;
364 int line_size = AUDIO_LINE_SIZE;
365 ssize_t vfs_read_retval = 0;
366 char mybuf[line_size];
367 loff_t pos;
368 loff_t offset = (unsigned long)0;
369 mm_segment_t old_fs;
370
371 myfile = filp_open(dev->_audiofilename, O_RDONLY | O_LARGEFILE, 0);
372
373 if (IS_ERR(myfile)) {
374 const int open_errno = -PTR_ERR(myfile);
375 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
376 __func__, dev->_audiofilename, open_errno);
377 return PTR_ERR(myfile);
378 } else {
379 if (!(myfile->f_op)) {
380 printk("%s: File has no file operations registered! \n",
381 __func__);
382 filp_close(myfile, NULL);
383 return -EIO;
384 }
385
386 if (!myfile->f_op->read) {
387 printk("%s: File has no READ operations registered! \n",
388 __func__);
389 filp_close(myfile, NULL);
390 return -EIO;
391 }
392
393 pos = myfile->f_pos;
394 old_fs = get_fs();
395 set_fs(KERNEL_DS);
396
397 for (j = 0; j < NUM_AUDIO_FRAMES; j++) {
398 for (i = 0; i < dev->_audio_lines_count; i++) {
399 pos = offset;
400
401 vfs_read_retval =
402 vfs_read(myfile, mybuf, line_size, &pos);
403
404 if (vfs_read_retval > 0
405 && vfs_read_retval == line_size
406 && dev->_audiodata_buf_virt_addr != NULL) {
407 memcpy((void *)(dev->
408 _audiodata_buf_virt_addr
409 + offset / 4), mybuf,
410 vfs_read_retval);
411 }
412
413 offset += vfs_read_retval;
414
415 if (vfs_read_retval < line_size) {
416 printk(KERN_INFO
417 "Done: exit %s() since no more bytes to read from Audio file.\n",
418 __func__);
419 break;
420 }
421 }
422
423 if (i > 0) {
424 dev->_audioframe_count++;
425 }
426
427 if (vfs_read_retval < line_size) {
428 break;
429 }
430 }
431
432 dev->_audiofile_status =
433 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
434
435 set_fs(old_fs);
436 myfile->f_pos = 0;
437 filp_close(myfile, NULL);
438 }
439
440 return 0;
441}
442
443static int cx25821_audio_upstream_buffer_prepare(struct cx25821_dev *dev,
444 struct sram_channel *sram_ch,
445 int bpl)
446{
447 int ret = 0;
448 dma_addr_t dma_addr;
449 dma_addr_t data_dma_addr;
450
451 cx25821_free_memory_audio(dev);
452
453 dev->_risc_virt_addr =
454 pci_alloc_consistent(dev->pci, dev->audio_upstream_riscbuf_size,
455 &dma_addr);
456 dev->_risc_virt_start_addr = dev->_risc_virt_addr;
457 dev->_risc_phys_start_addr = dma_addr;
458 dev->_risc_phys_addr = dma_addr;
459 dev->_audiorisc_size = dev->audio_upstream_riscbuf_size;
460
461 if (!dev->_risc_virt_addr) {
462 printk
463 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for RISC program! Returning.\n");
464 return -ENOMEM;
465 }
466 //Clear out memory at address
467 memset(dev->_risc_virt_addr, 0, dev->_audiorisc_size);
468
469 //For Audio Data buffer allocation
470 dev->_audiodata_buf_virt_addr =
471 pci_alloc_consistent(dev->pci, dev->audio_upstream_databuf_size,
472 &data_dma_addr);
473 dev->_audiodata_buf_phys_addr = data_dma_addr;
474 dev->_audiodata_buf_size = dev->audio_upstream_databuf_size;
475
476 if (!dev->_audiodata_buf_virt_addr) {
477 printk
478 ("cx25821 ERROR: pci_alloc_consistent() FAILED to allocate memory for data buffer! Returning. \n");
479 return -ENOMEM;
480 }
481 //Clear out memory at address
482 memset(dev->_audiodata_buf_virt_addr, 0, dev->_audiodata_buf_size);
483
484 ret = cx25821_openfile_audio(dev, sram_ch);
485 if (ret < 0)
486 return ret;
487
488 //Creating RISC programs
489 ret =
490 cx25821_risc_buffer_upstream_audio(dev, dev->pci, bpl,
491 dev->_audio_lines_count);
492 if (ret < 0) {
493 printk(KERN_DEBUG
494 "cx25821 ERROR creating audio upstream RISC programs! \n");
495 goto error;
496 }
497
498 return 0;
499
500 error:
501 return ret;
502}
503
504int cx25821_audio_upstream_irq(struct cx25821_dev *dev, int chan_num,
505 u32 status)
506{
507 int i = 0;
508 u32 int_msk_tmp;
509 struct sram_channel *channel = &dev->sram_channels[chan_num];
510 dma_addr_t risc_phys_jump_addr;
511 __le32 *rp;
512
513 if (status & FLD_AUD_SRC_RISCI1) {
514 //Get interrupt_index of the program that interrupted
515 u32 prog_cnt = cx_read(channel->gpcnt);
516
517 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
518 cx_write(channel->int_msk, 0);
519 cx_write(channel->int_stat, cx_read(channel->int_stat));
520
521 spin_lock(&dev->slock);
522
523 while (prog_cnt != dev->_last_index_irq) {
524 //Update _last_index_irq
525 if (dev->_last_index_irq < (NUMBER_OF_PROGRAMS - 1)) {
526 dev->_last_index_irq++;
527 } else {
528 dev->_last_index_irq = 0;
529 }
530
531 dev->_audioframe_index = dev->_last_index_irq;
532
533 queue_work(dev->_irq_audio_queues,
534 &dev->_audio_work_entry);
535 }
536
537 if (dev->_is_first_audio_frame) {
538 dev->_is_first_audio_frame = 0;
539
540 if (dev->_risc_virt_start_addr != NULL) {
541 risc_phys_jump_addr =
542 dev->_risc_phys_start_addr +
543 RISC_SYNC_INSTRUCTION_SIZE +
544 AUDIO_RISC_DMA_BUF_SIZE;
545
546 rp = cx25821_risc_field_upstream_audio(dev,
547 dev->
548 _risc_virt_start_addr
549 + 1,
550 dev->
551 _audiodata_buf_phys_addr,
552 AUDIO_LINE_SIZE,
553 FIFO_DISABLE);
554
555 if (USE_RISC_NOOP_AUDIO) {
556 for (i = 0; i < NUM_NO_OPS; i++) {
557 *(rp++) =
558 cpu_to_le32(RISC_NOOP);
559 }
560 }
561 // Jump to 2nd Audio Frame
562 *(rp++) =
563 cpu_to_le32(RISC_JUMP | RISC_IRQ1 |
564 RISC_CNT_RESET);
565 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
566 *(rp++) = cpu_to_le32(0);
567 }
568 }
569
570 spin_unlock(&dev->slock);
571 } else {
572 if (status & FLD_AUD_SRC_OF)
573 printk("%s: Audio Received Overflow Error Interrupt!\n",
574 __func__);
575
576 if (status & FLD_AUD_SRC_SYNC)
577 printk("%s: Audio Received Sync Error Interrupt!\n",
578 __func__);
579
580 if (status & FLD_AUD_SRC_OPC_ERR)
581 printk("%s: Audio Received OpCode Error Interrupt!\n",
582 __func__);
583
584 // Read and write back the interrupt status register to clear our bits
585 cx_write(channel->int_stat, cx_read(channel->int_stat));
586 }
587
588 if (dev->_audiofile_status == END_OF_FILE) {
589 printk("cx25821: EOF Channel Audio Framecount = %d\n",
590 dev->_audioframe_count);
591 return -1;
592 }
593 //ElSE, set the interrupt mask register, re-enable irq.
594 int_msk_tmp = cx_read(channel->int_msk);
595 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
596
597 return 0;
598}
599
600static irqreturn_t cx25821_upstream_irq_audio(int irq, void *dev_id)
601{
602 struct cx25821_dev *dev = dev_id;
603 u32 msk_stat, audio_status;
604 int handled = 0;
605 struct sram_channel *sram_ch;
606
607 if (!dev)
608 return -1;
609
610 sram_ch = &dev->sram_channels[dev->_audio_upstream_channel_select];
611
612 msk_stat = cx_read(sram_ch->int_mstat);
613 audio_status = cx_read(sram_ch->int_stat);
614
615 // Only deal with our interrupt
616 if (audio_status) {
617 handled =
618 cx25821_audio_upstream_irq(dev,
619 dev->
620 _audio_upstream_channel_select,
621 audio_status);
622 }
623
624 if (handled < 0) {
625 cx25821_stop_upstream_audio(dev);
626 } else {
627 handled += handled;
628 }
629
630 return IRQ_RETVAL(handled);
631}
632
633static void cx25821_wait_fifo_enable(struct cx25821_dev *dev,
634 struct sram_channel *sram_ch)
635{
636 int count = 0;
637 u32 tmp;
638
639 do {
640 //Wait 10 microsecond before checking to see if the FIFO is turned ON.
641 udelay(10);
642
643 tmp = cx_read(sram_ch->dma_ctl);
644
645 if (count++ > 1000) //10 millisecond timeout
646 {
647 printk
648 ("cx25821 ERROR: %s() fifo is NOT turned on. Timeout!\n",
649 __func__);
650 return;
651 }
652
653 } while (!(tmp & sram_ch->fld_aud_fifo_en));
654
655}
656
657int cx25821_start_audio_dma_upstream(struct cx25821_dev *dev,
658 struct sram_channel *sram_ch)
659{
660 u32 tmp = 0;
661 int err = 0;
662
663 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the CMDS.
664 cx_write(sram_ch->cmds_start + 0, dev->_risc_phys_addr);
665 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
666
667 /* reset counter */
668 cx_write(sram_ch->gpcnt_ctl, 3);
669
670 //Set the line length (It looks like we do not need to set the line length)
671 cx_write(sram_ch->aud_length, AUDIO_LINE_SIZE & FLD_AUD_DST_LN_LNGTH);
672
673 //Set the input mode to 16-bit
674 tmp = cx_read(sram_ch->aud_cfg);
675 tmp |=
676 FLD_AUD_SRC_ENABLE | FLD_AUD_DST_PK_MODE | FLD_AUD_CLK_ENABLE |
677 FLD_AUD_MASTER_MODE | FLD_AUD_CLK_SELECT_PLL_D | FLD_AUD_SONY_MODE;
678 cx_write(sram_ch->aud_cfg, tmp);
679
680 // Read and write back the interrupt status register to clear it
681 tmp = cx_read(sram_ch->int_stat);
682 cx_write(sram_ch->int_stat, tmp);
683
684 // Clear our bits from the interrupt status register.
685 cx_write(sram_ch->int_stat, _intr_msk);
686
687 //Set the interrupt mask register, enable irq.
688 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
689 tmp = cx_read(sram_ch->int_msk);
690 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
691
692 err =
693 request_irq(dev->pci->irq, cx25821_upstream_irq_audio,
694 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
695 if (err < 0) {
696 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
697 dev->pci->irq);
698 goto fail_irq;
699 }
700
701 // Start the DMA engine
702 tmp = cx_read(sram_ch->dma_ctl);
703 cx_set(sram_ch->dma_ctl, tmp | sram_ch->fld_aud_risc_en);
704
705 dev->_audio_is_running = 1;
706 dev->_is_first_audio_frame = 1;
707
708 // The fifo_en bit turns on by the first Risc program
709 cx25821_wait_fifo_enable(dev, sram_ch);
710
711 return 0;
712
713 fail_irq:
714 cx25821_dev_unregister(dev);
715 return err;
716}
717
718int cx25821_audio_upstream_init(struct cx25821_dev *dev, int channel_select)
719{
720 struct sram_channel *sram_ch;
721 int retval = 0;
722 int err = 0;
723 int str_length = 0;
724
725 if (dev->_audio_is_running) {
726 printk("Audio Channel is still running so return!\n");
727 return 0;
728 }
729
730 dev->_audio_upstream_channel_select = channel_select;
731 sram_ch = &dev->sram_channels[channel_select];
732
733 //Work queue
734 INIT_WORK(&dev->_audio_work_entry, cx25821_audioups_handler);
735 dev->_irq_audio_queues =
736 create_singlethread_workqueue("cx25821_audioworkqueue");
737
738 if (!dev->_irq_audio_queues) {
739 printk
740 ("cx25821 ERROR: create_singlethread_workqueue() for Audio FAILED!\n");
741 return -ENOMEM;
742 }
743
744 dev->_last_index_irq = 0;
745 dev->_audio_is_running = 0;
746 dev->_audioframe_count = 0;
747 dev->_audiofile_status = RESET_STATUS;
748 dev->_audio_lines_count = LINES_PER_AUDIO_BUFFER;
749 _line_size = AUDIO_LINE_SIZE;
750
751 if (dev->input_audiofilename) {
752 str_length = strlen(dev->input_audiofilename);
753 dev->_audiofilename =
754 (char *)kmalloc(str_length + 1, GFP_KERNEL);
755
756 if (!dev->_audiofilename)
757 goto error;
758
759 memcpy(dev->_audiofilename, dev->input_audiofilename,
760 str_length + 1);
761
762 //Default if filename is empty string
763 if (strcmp(dev->input_audiofilename, "") == 0) {
764 dev->_audiofilename = "/root/audioGOOD.wav";
765 }
766 } else {
767 str_length = strlen(_defaultAudioName);
768 dev->_audiofilename =
769 (char *)kmalloc(str_length + 1, GFP_KERNEL);
770
771 if (!dev->_audiofilename)
772 goto error;
773
774 memcpy(dev->_audiofilename, _defaultAudioName, str_length + 1);
775 }
776
777 retval =
778 cx25821_sram_channel_setup_upstream_audio(dev, sram_ch, _line_size,
779 0);
780
781 dev->audio_upstream_riscbuf_size =
782 AUDIO_RISC_DMA_BUF_SIZE * NUM_AUDIO_PROGS +
783 RISC_SYNC_INSTRUCTION_SIZE;
784 dev->audio_upstream_databuf_size = AUDIO_DATA_BUF_SZ * NUM_AUDIO_PROGS;
785
786 //Allocating buffers and prepare RISC program
787 retval =
788 cx25821_audio_upstream_buffer_prepare(dev, sram_ch, _line_size);
789 if (retval < 0) {
790 printk(KERN_ERR
791 "%s: Failed to set up Audio upstream buffers!\n",
792 dev->name);
793 goto error;
794 }
795 //Start RISC engine
796 cx25821_start_audio_dma_upstream(dev, sram_ch);
797
798 return 0;
799
800 error:
801 cx25821_dev_unregister(dev);
802
803 return err;
804}
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/staging/cx25821/cx25821-audio-upstream.h
new file mode 100644
index 000000000000..ca987addf815
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio-upstream.h
@@ -0,0 +1,57 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define NUM_AUDIO_PROGS 8
27#define NUM_AUDIO_FRAMES 8
28#define END_OF_FILE 0
29#define IN_PROGRESS 1
30#define RESET_STATUS -1
31#define FIFO_DISABLE 0
32#define FIFO_ENABLE 1
33#define NUM_NO_OPS 4
34
35#define RISC_READ_INSTRUCTION_SIZE 12
36#define RISC_JUMP_INSTRUCTION_SIZE 12
37#define RISC_WRITECR_INSTRUCTION_SIZE 16
38#define RISC_SYNC_INSTRUCTION_SIZE 4
39#define DWORD_SIZE 4
40#define AUDIO_SYNC_LINE 4
41
42#define LINES_PER_AUDIO_BUFFER 15
43#define AUDIO_LINE_SIZE 128
44#define AUDIO_DATA_BUF_SZ (AUDIO_LINE_SIZE * LINES_PER_AUDIO_BUFFER)
45
46#define USE_RISC_NOOP_AUDIO 1
47
48#ifdef USE_RISC_NOOP_AUDIO
49#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
50#endif
51
52#ifndef USE_RISC_NOOP_AUDIO
53#define AUDIO_RISC_DMA_BUF_SIZE ( LINES_PER_AUDIO_BUFFER*RISC_READ_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + RISC_JUMP_INSTRUCTION_SIZE)
54#endif
55
56static int _line_size;
57char *_defaultAudioName = "/root/audioGOOD.wav";
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/staging/cx25821/cx25821-audio.h
new file mode 100644
index 000000000000..503f42f036a8
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audio.h
@@ -0,0 +1,57 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __CX25821_AUDIO_H__
24#define __CX25821_AUDIO_H__
25
26#define USE_RISC_NOOP 1
27#define LINES_PER_BUFFER 15
28#define AUDIO_LINE_SIZE 128
29
30//Number of buffer programs to use at once.
31#define NUMBER_OF_PROGRAMS 8
32
33//Max size of the RISC program for a buffer. - worst case is 2 writes per line
34// Space is also added for the 4 no-op instructions added on the end.
35
36#ifndef USE_RISC_NOOP
37#define MAX_BUFFER_PROGRAM_SIZE \
38 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE*4)
39#endif
40
41// MAE 12 July 2005 Try to use NOOP RISC instruction instead
42#ifdef USE_RISC_NOOP
43#define MAX_BUFFER_PROGRAM_SIZE \
44 (2*LINES_PER_BUFFER*RISC_WRITE_INSTRUCTION_SIZE + RISC_NOOP_INSTRUCTION_SIZE*4)
45#endif
46
47//Sizes of various instructions in bytes. Used when adding instructions.
48#define RISC_WRITE_INSTRUCTION_SIZE 12
49#define RISC_JUMP_INSTRUCTION_SIZE 12
50#define RISC_SKIP_INSTRUCTION_SIZE 4
51#define RISC_SYNC_INSTRUCTION_SIZE 4
52#define RISC_WRITECR_INSTRUCTION_SIZE 16
53#define RISC_NOOP_INSTRUCTION_SIZE 4
54
55#define MAX_AUDIO_DMA_BUFFER_SIZE (MAX_BUFFER_PROGRAM_SIZE * NUMBER_OF_PROGRAMS + RISC_SYNC_INSTRUCTION_SIZE)
56
57#endif
diff --git a/drivers/staging/cx25821/cx25821-audups11.c b/drivers/staging/cx25821/cx25821-audups11.c
new file mode 100644
index 000000000000..f78b8912d905
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-audups11.c
@@ -0,0 +1,434 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH11];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH11]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH11]
108 && h->video_dev[SRAM_CH11]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 10;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user * data, size_t count,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO11))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO11)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
197}
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 //stop the risc engine and fifo
205 //cx_write(channel11->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO11)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO11);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO11)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO11);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
268 struct v4l2_format *f)
269{
270 struct cx25821_fh *fh = priv;
271 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
272 int err;
273
274 if (fh) {
275 err = v4l2_prio_check(&dev->prio, &fh->prio);
276 if (0 != err)
277 return err;
278 }
279
280 dprintk(2, "%s()\n", __func__);
281 err = vidioc_try_fmt_vid_cap(file, priv, f);
282
283 if (0 != err)
284 return err;
285 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
286 fh->width = f->fmt.pix.width;
287 fh->height = f->fmt.pix.height;
288 fh->vidq.field = f->fmt.pix.field;
289 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
290 fh->height, fh->vidq.field);
291 cx25821_call_all(dev, video, s_fmt, f);
292 return 0;
293}
294
295static long video_ioctl_upstream11(struct file *file, unsigned int cmd,
296 unsigned long arg)
297{
298 struct cx25821_fh *fh = file->private_data;
299 struct cx25821_dev *dev = fh->dev;
300 int command = 0;
301 struct upstream_user_struct *data_from_user;
302
303 data_from_user = (struct upstream_user_struct *)arg;
304
305 if (!data_from_user) {
306 printk
307 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
308 __func__);
309 return 0;
310 }
311
312 command = data_from_user->command;
313
314 if (command != UPSTREAM_START_AUDIO && command != UPSTREAM_STOP_AUDIO) {
315 return 0;
316 }
317
318 dev->input_filename = data_from_user->input_filename;
319 dev->input_audiofilename = data_from_user->input_filename;
320 dev->vid_stdname = data_from_user->vid_stdname;
321 dev->pixel_format = data_from_user->pixel_format;
322 dev->channel_select = data_from_user->channel_select;
323 dev->command = data_from_user->command;
324
325 switch (command) {
326 case UPSTREAM_START_AUDIO:
327 cx25821_start_upstream_audio(dev, data_from_user);
328 break;
329
330 case UPSTREAM_STOP_AUDIO:
331 cx25821_stop_upstream_audio(dev);
332 break;
333 }
334
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343
344static int vidioc_log_status(struct file *file, void *priv)
345{
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347 char name[32 + 2];
348
349 snprintf(name, sizeof(name), "%s/2", dev->name);
350 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
351 dev->name);
352 cx25821_call_all(dev, core, log_status);
353 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
354 dev->name);
355 return 0;
356}
357
358static int vidioc_s_ctrl(struct file *file, void *priv,
359 struct v4l2_control *ctl)
360{
361 struct cx25821_fh *fh = priv;
362 struct cx25821_dev *dev = fh->dev;
363 int err;
364
365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio);
367 if (0 != err)
368 return err;
369 }
370 return 0;
371}
372
373// exported stuff
374static const struct v4l2_file_operations video_fops = {
375 .owner = THIS_MODULE,
376 .open = video_open,
377 .release = video_release,
378 .read = video_read,
379 .poll = video_poll,
380 .mmap = video_mmap,
381 .ioctl = video_ioctl_upstream11,
382};
383
384static const struct v4l2_ioctl_ops video_ioctl_ops = {
385 .vidioc_querycap = vidioc_querycap,
386 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
387 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
388 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
389 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
390 .vidioc_reqbufs = vidioc_reqbufs,
391 .vidioc_querybuf = vidioc_querybuf,
392 .vidioc_qbuf = vidioc_qbuf,
393 .vidioc_dqbuf = vidioc_dqbuf,
394#ifdef TUNER_FLAG
395 .vidioc_s_std = vidioc_s_std,
396 .vidioc_querystd = vidioc_querystd,
397#endif
398 .vidioc_cropcap = vidioc_cropcap,
399 .vidioc_s_crop = vidioc_s_crop,
400 .vidioc_g_crop = vidioc_g_crop,
401 .vidioc_enum_input = vidioc_enum_input,
402 .vidioc_g_input = vidioc_g_input,
403 .vidioc_s_input = vidioc_s_input,
404 .vidioc_g_ctrl = vidioc_g_ctrl,
405 .vidioc_s_ctrl = vidioc_s_ctrl,
406 .vidioc_queryctrl = vidioc_queryctrl,
407 .vidioc_streamon = vidioc_streamon,
408 .vidioc_streamoff = vidioc_streamoff,
409 .vidioc_log_status = vidioc_log_status,
410 .vidioc_g_priority = vidioc_g_priority,
411 .vidioc_s_priority = vidioc_s_priority,
412#ifdef CONFIG_VIDEO_V4L1_COMPAT
413 .vidiocgmbuf = vidiocgmbuf,
414#endif
415#ifdef TUNER_FLAG
416 .vidioc_g_tuner = vidioc_g_tuner,
417 .vidioc_s_tuner = vidioc_s_tuner,
418 .vidioc_g_frequency = vidioc_g_frequency,
419 .vidioc_s_frequency = vidioc_s_frequency,
420#endif
421#ifdef CONFIG_VIDEO_ADV_DEBUG
422 .vidioc_g_register = vidioc_g_register,
423 .vidioc_s_register = vidioc_s_register,
424#endif
425};
426
427struct video_device cx25821_video_template11 = {
428 .name = "cx25821-audioupstream",
429 .fops = &video_fops,
430 .minor = -1,
431 .ioctl_ops = &video_ioctl_ops,
432 .tvnorms = CX25821_NORMS,
433 .current_norm = V4L2_STD_NTSC_M,
434};
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/staging/cx25821/cx25821-biffuncs.h
new file mode 100644
index 000000000000..9326a7c729ec
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-biffuncs.h
@@ -0,0 +1,45 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _BITFUNCS_H
24#define _BITFUNCS_H
25
26#define SetBit(Bit) (1 << Bit)
27
28inline u8 getBit(u32 sample, u8 index)
29{
30 return (u8) ((sample >> index) & 1);
31}
32
33inline u32 clearBitAtPos(u32 value, u8 bit)
34{
35 return value & ~(1 << bit);
36}
37
38inline u32 setBitAtPos(u32 sample, u8 bit)
39{
40 sample |= (1 << bit);
41 return sample;
42
43}
44
45#endif
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/staging/cx25821/cx25821-cards.c
new file mode 100644
index 000000000000..4d0b9eac3e49
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-cards.c
@@ -0,0 +1,70 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/pci.h>
27#include <linux/delay.h>
28#include <media/cx25840.h>
29
30#include "cx25821.h"
31#include "tuner-xc2028.h"
32
33// board config info
34
35struct cx25821_board cx25821_boards[] = {
36 [UNKNOWN_BOARD] = {
37 .name = "UNKNOWN/GENERIC",
38 // Ensure safe default for unknown boards
39 .clk_freq = 0,
40 },
41
42 [CX25821_BOARD] = {
43 .name = "CX25821",
44 .portb = CX25821_RAW,
45 .portc = CX25821_264,
46 .input[0].type = CX25821_VMUX_COMPOSITE,
47 },
48
49};
50
51const unsigned int cx25821_bcount = ARRAY_SIZE(cx25821_boards);
52
53struct cx25821_subid cx25821_subids[] = {
54 {
55 .subvendor = 0x14f1,
56 .subdevice = 0x0920,
57 .card = CX25821_BOARD,
58 },
59};
60
61void cx25821_card_setup(struct cx25821_dev *dev)
62{
63 static u8 eeprom[256];
64
65 if (dev->i2c_bus[0].i2c_rc == 0) {
66 dev->i2c_bus[0].i2c_client.addr = 0xa0 >> 1;
67 tveeprom_read(&dev->i2c_bus[0].i2c_client, eeprom,
68 sizeof(eeprom));
69 }
70}
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
new file mode 100644
index 000000000000..8aceae5a072e
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -0,0 +1,1551 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/i2c.h>
25#include "cx25821.h"
26#include "cx25821-sram.h"
27#include "cx25821-video.h"
28
29MODULE_DESCRIPTION("Driver for Athena cards");
30MODULE_AUTHOR("Shu Lin - Hiep Huynh");
31MODULE_LICENSE("GPL");
32
33struct list_head cx25821_devlist;
34
35static unsigned int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debug messages");
38
39static unsigned int card[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
40module_param_array(card, int, NULL, 0444);
41MODULE_PARM_DESC(card, "card type");
42
43static unsigned int cx25821_devcount = 0;
44
45static DEFINE_MUTEX(devlist);
46LIST_HEAD(cx25821_devlist);
47
48struct sram_channel cx25821_sram_channels[] = {
49 [SRAM_CH00] = {
50 .i = SRAM_CH00,
51 .name = "VID A",
52 .cmds_start = VID_A_DOWN_CMDS,
53 .ctrl_start = VID_A_IQ,
54 .cdt = VID_A_CDT,
55 .fifo_start = VID_A_DOWN_CLUSTER_1,
56 .fifo_size = (VID_CLUSTER_SIZE << 2),
57 .ptr1_reg = DMA1_PTR1,
58 .ptr2_reg = DMA1_PTR2,
59 .cnt1_reg = DMA1_CNT1,
60 .cnt2_reg = DMA1_CNT2,
61 .int_msk = VID_A_INT_MSK,
62 .int_stat = VID_A_INT_STAT,
63 .int_mstat = VID_A_INT_MSTAT,
64 .dma_ctl = VID_DST_A_DMA_CTL,
65 .gpcnt_ctl = VID_DST_A_GPCNT_CTL,
66 .gpcnt = VID_DST_A_GPCNT,
67 .vip_ctl = VID_DST_A_VIP_CTL,
68 .pix_frmt = VID_DST_A_PIX_FRMT,
69 },
70
71 [SRAM_CH01] = {
72 .i = SRAM_CH01,
73 .name = "VID B",
74 .cmds_start = VID_B_DOWN_CMDS,
75 .ctrl_start = VID_B_IQ,
76 .cdt = VID_B_CDT,
77 .fifo_start = VID_B_DOWN_CLUSTER_1,
78 .fifo_size = (VID_CLUSTER_SIZE << 2),
79 .ptr1_reg = DMA2_PTR1,
80 .ptr2_reg = DMA2_PTR2,
81 .cnt1_reg = DMA2_CNT1,
82 .cnt2_reg = DMA2_CNT2,
83 .int_msk = VID_B_INT_MSK,
84 .int_stat = VID_B_INT_STAT,
85 .int_mstat = VID_B_INT_MSTAT,
86 .dma_ctl = VID_DST_B_DMA_CTL,
87 .gpcnt_ctl = VID_DST_B_GPCNT_CTL,
88 .gpcnt = VID_DST_B_GPCNT,
89 .vip_ctl = VID_DST_B_VIP_CTL,
90 .pix_frmt = VID_DST_B_PIX_FRMT,
91 },
92
93 [SRAM_CH02] = {
94 .i = SRAM_CH02,
95 .name = "VID C",
96 .cmds_start = VID_C_DOWN_CMDS,
97 .ctrl_start = VID_C_IQ,
98 .cdt = VID_C_CDT,
99 .fifo_start = VID_C_DOWN_CLUSTER_1,
100 .fifo_size = (VID_CLUSTER_SIZE << 2),
101 .ptr1_reg = DMA3_PTR1,
102 .ptr2_reg = DMA3_PTR2,
103 .cnt1_reg = DMA3_CNT1,
104 .cnt2_reg = DMA3_CNT2,
105 .int_msk = VID_C_INT_MSK,
106 .int_stat = VID_C_INT_STAT,
107 .int_mstat = VID_C_INT_MSTAT,
108 .dma_ctl = VID_DST_C_DMA_CTL,
109 .gpcnt_ctl = VID_DST_C_GPCNT_CTL,
110 .gpcnt = VID_DST_C_GPCNT,
111 .vip_ctl = VID_DST_C_VIP_CTL,
112 .pix_frmt = VID_DST_C_PIX_FRMT,
113 },
114
115 [SRAM_CH03] = {
116 .i = SRAM_CH03,
117 .name = "VID D",
118 .cmds_start = VID_D_DOWN_CMDS,
119 .ctrl_start = VID_D_IQ,
120 .cdt = VID_D_CDT,
121 .fifo_start = VID_D_DOWN_CLUSTER_1,
122 .fifo_size = (VID_CLUSTER_SIZE << 2),
123 .ptr1_reg = DMA4_PTR1,
124 .ptr2_reg = DMA4_PTR2,
125 .cnt1_reg = DMA4_CNT1,
126 .cnt2_reg = DMA4_CNT2,
127 .int_msk = VID_D_INT_MSK,
128 .int_stat = VID_D_INT_STAT,
129 .int_mstat = VID_D_INT_MSTAT,
130 .dma_ctl = VID_DST_D_DMA_CTL,
131 .gpcnt_ctl = VID_DST_D_GPCNT_CTL,
132 .gpcnt = VID_DST_D_GPCNT,
133 .vip_ctl = VID_DST_D_VIP_CTL,
134 .pix_frmt = VID_DST_D_PIX_FRMT,
135 },
136
137 [SRAM_CH04] = {
138 .i = SRAM_CH04,
139 .name = "VID E",
140 .cmds_start = VID_E_DOWN_CMDS,
141 .ctrl_start = VID_E_IQ,
142 .cdt = VID_E_CDT,
143 .fifo_start = VID_E_DOWN_CLUSTER_1,
144 .fifo_size = (VID_CLUSTER_SIZE << 2),
145 .ptr1_reg = DMA5_PTR1,
146 .ptr2_reg = DMA5_PTR2,
147 .cnt1_reg = DMA5_CNT1,
148 .cnt2_reg = DMA5_CNT2,
149 .int_msk = VID_E_INT_MSK,
150 .int_stat = VID_E_INT_STAT,
151 .int_mstat = VID_E_INT_MSTAT,
152 .dma_ctl = VID_DST_E_DMA_CTL,
153 .gpcnt_ctl = VID_DST_E_GPCNT_CTL,
154 .gpcnt = VID_DST_E_GPCNT,
155 .vip_ctl = VID_DST_E_VIP_CTL,
156 .pix_frmt = VID_DST_E_PIX_FRMT,
157 },
158
159 [SRAM_CH05] = {
160 .i = SRAM_CH05,
161 .name = "VID F",
162 .cmds_start = VID_F_DOWN_CMDS,
163 .ctrl_start = VID_F_IQ,
164 .cdt = VID_F_CDT,
165 .fifo_start = VID_F_DOWN_CLUSTER_1,
166 .fifo_size = (VID_CLUSTER_SIZE << 2),
167 .ptr1_reg = DMA6_PTR1,
168 .ptr2_reg = DMA6_PTR2,
169 .cnt1_reg = DMA6_CNT1,
170 .cnt2_reg = DMA6_CNT2,
171 .int_msk = VID_F_INT_MSK,
172 .int_stat = VID_F_INT_STAT,
173 .int_mstat = VID_F_INT_MSTAT,
174 .dma_ctl = VID_DST_F_DMA_CTL,
175 .gpcnt_ctl = VID_DST_F_GPCNT_CTL,
176 .gpcnt = VID_DST_F_GPCNT,
177 .vip_ctl = VID_DST_F_VIP_CTL,
178 .pix_frmt = VID_DST_F_PIX_FRMT,
179 },
180
181 [SRAM_CH06] = {
182 .i = SRAM_CH06,
183 .name = "VID G",
184 .cmds_start = VID_G_DOWN_CMDS,
185 .ctrl_start = VID_G_IQ,
186 .cdt = VID_G_CDT,
187 .fifo_start = VID_G_DOWN_CLUSTER_1,
188 .fifo_size = (VID_CLUSTER_SIZE << 2),
189 .ptr1_reg = DMA7_PTR1,
190 .ptr2_reg = DMA7_PTR2,
191 .cnt1_reg = DMA7_CNT1,
192 .cnt2_reg = DMA7_CNT2,
193 .int_msk = VID_G_INT_MSK,
194 .int_stat = VID_G_INT_STAT,
195 .int_mstat = VID_G_INT_MSTAT,
196 .dma_ctl = VID_DST_G_DMA_CTL,
197 .gpcnt_ctl = VID_DST_G_GPCNT_CTL,
198 .gpcnt = VID_DST_G_GPCNT,
199 .vip_ctl = VID_DST_G_VIP_CTL,
200 .pix_frmt = VID_DST_G_PIX_FRMT,
201 },
202
203 [SRAM_CH07] = {
204 .i = SRAM_CH07,
205 .name = "VID H",
206 .cmds_start = VID_H_DOWN_CMDS,
207 .ctrl_start = VID_H_IQ,
208 .cdt = VID_H_CDT,
209 .fifo_start = VID_H_DOWN_CLUSTER_1,
210 .fifo_size = (VID_CLUSTER_SIZE << 2),
211 .ptr1_reg = DMA8_PTR1,
212 .ptr2_reg = DMA8_PTR2,
213 .cnt1_reg = DMA8_CNT1,
214 .cnt2_reg = DMA8_CNT2,
215 .int_msk = VID_H_INT_MSK,
216 .int_stat = VID_H_INT_STAT,
217 .int_mstat = VID_H_INT_MSTAT,
218 .dma_ctl = VID_DST_H_DMA_CTL,
219 .gpcnt_ctl = VID_DST_H_GPCNT_CTL,
220 .gpcnt = VID_DST_H_GPCNT,
221 .vip_ctl = VID_DST_H_VIP_CTL,
222 .pix_frmt = VID_DST_H_PIX_FRMT,
223 },
224
225 [SRAM_CH08] = {
226 .name = "audio from",
227 .cmds_start = AUD_A_DOWN_CMDS,
228 .ctrl_start = AUD_A_IQ,
229 .cdt = AUD_A_CDT,
230 .fifo_start = AUD_A_DOWN_CLUSTER_1,
231 .fifo_size = AUDIO_CLUSTER_SIZE * 3,
232 .ptr1_reg = DMA17_PTR1,
233 .ptr2_reg = DMA17_PTR2,
234 .cnt1_reg = DMA17_CNT1,
235 .cnt2_reg = DMA17_CNT2,
236 },
237
238 [SRAM_CH09] = {
239 .i = SRAM_CH09,
240 .name = "VID Upstream I",
241 .cmds_start = VID_I_UP_CMDS,
242 .ctrl_start = VID_I_IQ,
243 .cdt = VID_I_CDT,
244 .fifo_start = VID_I_UP_CLUSTER_1,
245 .fifo_size = (VID_CLUSTER_SIZE << 2),
246 .ptr1_reg = DMA15_PTR1,
247 .ptr2_reg = DMA15_PTR2,
248 .cnt1_reg = DMA15_CNT1,
249 .cnt2_reg = DMA15_CNT2,
250 .int_msk = VID_I_INT_MSK,
251 .int_stat = VID_I_INT_STAT,
252 .int_mstat = VID_I_INT_MSTAT,
253 .dma_ctl = VID_SRC_I_DMA_CTL,
254 .gpcnt_ctl = VID_SRC_I_GPCNT_CTL,
255 .gpcnt = VID_SRC_I_GPCNT,
256
257 .vid_fmt_ctl = VID_SRC_I_FMT_CTL,
258 .vid_active_ctl1 = VID_SRC_I_ACTIVE_CTL1,
259 .vid_active_ctl2 = VID_SRC_I_ACTIVE_CTL2,
260 .vid_cdt_size = VID_SRC_I_CDT_SZ,
261 .irq_bit = 8,
262 },
263
264 [SRAM_CH10] = {
265 .i = SRAM_CH10,
266 .name = "VID Upstream J",
267 .cmds_start = VID_J_UP_CMDS,
268 .ctrl_start = VID_J_IQ,
269 .cdt = VID_J_CDT,
270 .fifo_start = VID_J_UP_CLUSTER_1,
271 .fifo_size = (VID_CLUSTER_SIZE << 2),
272 .ptr1_reg = DMA16_PTR1,
273 .ptr2_reg = DMA16_PTR2,
274 .cnt1_reg = DMA16_CNT1,
275 .cnt2_reg = DMA16_CNT2,
276 .int_msk = VID_J_INT_MSK,
277 .int_stat = VID_J_INT_STAT,
278 .int_mstat = VID_J_INT_MSTAT,
279 .dma_ctl = VID_SRC_J_DMA_CTL,
280 .gpcnt_ctl = VID_SRC_J_GPCNT_CTL,
281 .gpcnt = VID_SRC_J_GPCNT,
282
283 .vid_fmt_ctl = VID_SRC_J_FMT_CTL,
284 .vid_active_ctl1 = VID_SRC_J_ACTIVE_CTL1,
285 .vid_active_ctl2 = VID_SRC_J_ACTIVE_CTL2,
286 .vid_cdt_size = VID_SRC_J_CDT_SZ,
287 .irq_bit = 9,
288 },
289
290 [SRAM_CH11] = {
291 .i = SRAM_CH11,
292 .name = "Audio Upstream Channel B",
293 .cmds_start = AUD_B_UP_CMDS,
294 .ctrl_start = AUD_B_IQ,
295 .cdt = AUD_B_CDT,
296 .fifo_start = AUD_B_UP_CLUSTER_1,
297 .fifo_size = (AUDIO_CLUSTER_SIZE * 3),
298 .ptr1_reg = DMA22_PTR1,
299 .ptr2_reg = DMA22_PTR2,
300 .cnt1_reg = DMA22_CNT1,
301 .cnt2_reg = DMA22_CNT2,
302 .int_msk = AUD_B_INT_MSK,
303 .int_stat = AUD_B_INT_STAT,
304 .int_mstat = AUD_B_INT_MSTAT,
305 .dma_ctl = AUD_INT_DMA_CTL,
306 .gpcnt_ctl = AUD_B_GPCNT_CTL,
307 .gpcnt = AUD_B_GPCNT,
308 .aud_length = AUD_B_LNGTH,
309 .aud_cfg = AUD_B_CFG,
310 .fld_aud_fifo_en = FLD_AUD_SRC_B_FIFO_EN,
311 .fld_aud_risc_en = FLD_AUD_SRC_B_RISC_EN,
312 .irq_bit = 11,
313 },
314};
315
316struct sram_channel *channel0 = &cx25821_sram_channels[SRAM_CH00];
317struct sram_channel *channel1 = &cx25821_sram_channels[SRAM_CH01];
318struct sram_channel *channel2 = &cx25821_sram_channels[SRAM_CH02];
319struct sram_channel *channel3 = &cx25821_sram_channels[SRAM_CH03];
320struct sram_channel *channel4 = &cx25821_sram_channels[SRAM_CH04];
321struct sram_channel *channel5 = &cx25821_sram_channels[SRAM_CH05];
322struct sram_channel *channel6 = &cx25821_sram_channels[SRAM_CH06];
323struct sram_channel *channel7 = &cx25821_sram_channels[SRAM_CH07];
324struct sram_channel *channel9 = &cx25821_sram_channels[SRAM_CH09];
325struct sram_channel *channel10 = &cx25821_sram_channels[SRAM_CH10];
326struct sram_channel *channel11 = &cx25821_sram_channels[SRAM_CH11];
327
328struct cx25821_dmaqueue mpegq;
329
330static int cx25821_risc_decode(u32 risc)
331{
332 static char *instr[16] = {
333 [RISC_SYNC >> 28] = "sync",
334 [RISC_WRITE >> 28] = "write",
335 [RISC_WRITEC >> 28] = "writec",
336 [RISC_READ >> 28] = "read",
337 [RISC_READC >> 28] = "readc",
338 [RISC_JUMP >> 28] = "jump",
339 [RISC_SKIP >> 28] = "skip",
340 [RISC_WRITERM >> 28] = "writerm",
341 [RISC_WRITECM >> 28] = "writecm",
342 [RISC_WRITECR >> 28] = "writecr",
343 };
344 static int incr[16] = {
345 [RISC_WRITE >> 28] = 3,
346 [RISC_JUMP >> 28] = 3,
347 [RISC_SKIP >> 28] = 1,
348 [RISC_SYNC >> 28] = 1,
349 [RISC_WRITERM >> 28] = 3,
350 [RISC_WRITECM >> 28] = 3,
351 [RISC_WRITECR >> 28] = 4,
352 };
353 static char *bits[] = {
354 "12", "13", "14", "resync",
355 "cnt0", "cnt1", "18", "19",
356 "20", "21", "22", "23",
357 "irq1", "irq2", "eol", "sol",
358 };
359 int i;
360
361 printk("0x%08x [ %s", risc,
362 instr[risc >> 28] ? instr[risc >> 28] : "INVALID");
363 for (i = ARRAY_SIZE(bits) - 1; i >= 0; i--) {
364 if (risc & (1 << (i + 12)))
365 printk(" %s", bits[i]);
366 }
367 printk(" count=%d ]\n", risc & 0xfff);
368 return incr[risc >> 28] ? incr[risc >> 28] : 1;
369}
370
371static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
372{
373 struct cx25821_i2c *bus = i2c_adap->algo_data;
374 struct cx25821_dev *dev = bus->dev;
375 return cx_read(bus->reg_stat) & 0x01;
376}
377
378void cx_i2c_read_print(struct cx25821_dev *dev, u32 reg, const char *reg_string)
379{
380 int tmp = 0;
381 u32 value = 0;
382
383 value = cx25821_i2c_read(&dev->i2c_bus[0], reg, &tmp);
384}
385
386static void cx25821_registers_init(struct cx25821_dev *dev)
387{
388 u32 tmp;
389
390 // enable RUN_RISC in Pecos
391 cx_write(DEV_CNTRL2, 0x20);
392
393 // Set the master PCI interrupt masks to enable video, audio, MBIF, and GPIO interrupts
394 // I2C interrupt masking is handled by the I2C objects themselves.
395 cx_write(PCI_INT_MSK, 0x2001FFFF);
396
397 tmp = cx_read(RDR_TLCTL0);
398 tmp &= ~FLD_CFG_RCB_CK_EN; // Clear the RCB_CK_EN bit
399 cx_write(RDR_TLCTL0, tmp);
400
401 // PLL-A setting for the Audio Master Clock
402 cx_write(PLL_A_INT_FRAC, 0x9807A58B);
403
404 // PLL_A_POST = 0x1C, PLL_A_OUT_TO_PIN = 0x1
405 cx_write(PLL_A_POST_STAT_BIST, 0x8000019C);
406
407 // clear reset bit [31]
408 tmp = cx_read(PLL_A_INT_FRAC);
409 cx_write(PLL_A_INT_FRAC, tmp & 0x7FFFFFFF);
410
411 // PLL-B setting for Mobilygen Host Bus Interface
412 cx_write(PLL_B_INT_FRAC, 0x9883A86F);
413
414 // PLL_B_POST = 0xD, PLL_B_OUT_TO_PIN = 0x0
415 cx_write(PLL_B_POST_STAT_BIST, 0x8000018D);
416
417 // clear reset bit [31]
418 tmp = cx_read(PLL_B_INT_FRAC);
419 cx_write(PLL_B_INT_FRAC, tmp & 0x7FFFFFFF);
420
421 // PLL-C setting for video upstream channel
422 cx_write(PLL_C_INT_FRAC, 0x96A0EA3F);
423
424 // PLL_C_POST = 0x3, PLL_C_OUT_TO_PIN = 0x0
425 cx_write(PLL_C_POST_STAT_BIST, 0x80000103);
426
427 // clear reset bit [31]
428 tmp = cx_read(PLL_C_INT_FRAC);
429 cx_write(PLL_C_INT_FRAC, tmp & 0x7FFFFFFF);
430
431 // PLL-D setting for audio upstream channel
432 cx_write(PLL_D_INT_FRAC, 0x98757F5B);
433
434 // PLL_D_POST = 0x13, PLL_D_OUT_TO_PIN = 0x0
435 cx_write(PLL_D_POST_STAT_BIST, 0x80000113);
436
437 // clear reset bit [31]
438 tmp = cx_read(PLL_D_INT_FRAC);
439 cx_write(PLL_D_INT_FRAC, tmp & 0x7FFFFFFF);
440
441 // This selects the PLL C clock source for the video upstream channel I and J
442 tmp = cx_read(VID_CH_CLK_SEL);
443 cx_write(VID_CH_CLK_SEL, (tmp & 0x00FFFFFF) | 0x24000000);
444
445 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
446 //select 656/VIP DST for downstream Channel A - C
447 tmp = cx_read(VID_CH_MODE_SEL);
448 //cx_write( VID_CH_MODE_SEL, tmp | 0x1B0001FF);
449 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
450
451 // enables 656 port I and J as output
452 tmp = cx_read(CLK_RST);
453 tmp |= FLD_USE_ALT_PLL_REF; // use external ALT_PLL_REF pin as its reference clock instead
454 cx_write(CLK_RST, tmp & ~(FLD_VID_I_CLK_NOE | FLD_VID_J_CLK_NOE));
455
456 mdelay(100);
457}
458
459int cx25821_sram_channel_setup(struct cx25821_dev *dev,
460 struct sram_channel *ch,
461 unsigned int bpl, u32 risc)
462{
463 unsigned int i, lines;
464 u32 cdt;
465
466 if (ch->cmds_start == 0) {
467 cx_write(ch->ptr1_reg, 0);
468 cx_write(ch->ptr2_reg, 0);
469 cx_write(ch->cnt2_reg, 0);
470 cx_write(ch->cnt1_reg, 0);
471 return 0;
472 }
473
474 bpl = (bpl + 7) & ~7; /* alignment */
475 cdt = ch->cdt;
476 lines = ch->fifo_size / bpl;
477
478 if (lines > 4) {
479 lines = 4;
480 }
481
482 BUG_ON(lines < 2);
483
484 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
485 cx_write(8 + 4, 8);
486 cx_write(8 + 8, 0);
487
488 /* write CDT */
489 for (i = 0; i < lines; i++) {
490 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
491 cx_write(cdt + 16 * i + 4, 0);
492 cx_write(cdt + 16 * i + 8, 0);
493 cx_write(cdt + 16 * i + 12, 0);
494 }
495
496 //init the first cdt buffer
497 for (i = 0; i < 128; i++)
498 cx_write(ch->fifo_start + 4 * i, i);
499
500 /* write CMDS */
501 if (ch->jumponly) {
502 cx_write(ch->cmds_start + 0, 8);
503 } else {
504 cx_write(ch->cmds_start + 0, risc);
505 }
506
507 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
508 cx_write(ch->cmds_start + 8, cdt);
509 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
510 cx_write(ch->cmds_start + 16, ch->ctrl_start);
511
512 if (ch->jumponly)
513 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
514 else
515 cx_write(ch->cmds_start + 20, 64 >> 2);
516
517 for (i = 24; i < 80; i += 4)
518 cx_write(ch->cmds_start + i, 0);
519
520 /* fill registers */
521 cx_write(ch->ptr1_reg, ch->fifo_start);
522 cx_write(ch->ptr2_reg, cdt);
523 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
524 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
525
526 return 0;
527}
528
529int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
530 struct sram_channel *ch,
531 unsigned int bpl, u32 risc)
532{
533 unsigned int i, lines;
534 u32 cdt;
535
536 if (ch->cmds_start == 0) {
537 cx_write(ch->ptr1_reg, 0);
538 cx_write(ch->ptr2_reg, 0);
539 cx_write(ch->cnt2_reg, 0);
540 cx_write(ch->cnt1_reg, 0);
541 return 0;
542 }
543
544 bpl = (bpl + 7) & ~7; /* alignment */
545 cdt = ch->cdt;
546 lines = ch->fifo_size / bpl;
547
548 if (lines > 3) {
549 lines = 3; //for AUDIO
550 }
551
552 BUG_ON(lines < 2);
553
554 cx_write(8 + 0, RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
555 cx_write(8 + 4, 8);
556 cx_write(8 + 8, 0);
557
558 /* write CDT */
559 for (i = 0; i < lines; i++) {
560 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
561 cx_write(cdt + 16 * i + 4, 0);
562 cx_write(cdt + 16 * i + 8, 0);
563 cx_write(cdt + 16 * i + 12, 0);
564 }
565
566 /* write CMDS */
567 if (ch->jumponly) {
568 cx_write(ch->cmds_start + 0, 8);
569 } else {
570 cx_write(ch->cmds_start + 0, risc);
571 }
572
573 cx_write(ch->cmds_start + 4, 0); /* 64 bits 63-32 */
574 cx_write(ch->cmds_start + 8, cdt);
575 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
576 cx_write(ch->cmds_start + 16, ch->ctrl_start);
577
578 //IQ size
579 if (ch->jumponly) {
580 cx_write(ch->cmds_start + 20, 0x80000000 | (64 >> 2));
581 } else {
582 cx_write(ch->cmds_start + 20, 64 >> 2);
583 }
584
585 //zero out
586 for (i = 24; i < 80; i += 4)
587 cx_write(ch->cmds_start + i, 0);
588
589 /* fill registers */
590 cx_write(ch->ptr1_reg, ch->fifo_start);
591 cx_write(ch->ptr2_reg, cdt);
592 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
593 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
594
595 return 0;
596}
597
598void cx25821_sram_channel_dump(struct cx25821_dev *dev, struct sram_channel *ch)
599{
600 static char *name[] = {
601 "init risc lo",
602 "init risc hi",
603 "cdt base",
604 "cdt size",
605 "iq base",
606 "iq size",
607 "risc pc lo",
608 "risc pc hi",
609 "iq wr ptr",
610 "iq rd ptr",
611 "cdt current",
612 "pci target lo",
613 "pci target hi",
614 "line / byte",
615 };
616 u32 risc;
617 unsigned int i, j, n;
618
619 printk(KERN_WARNING "%s: %s - dma channel status dump\n", dev->name,
620 ch->name);
621 for (i = 0; i < ARRAY_SIZE(name); i++)
622 printk(KERN_WARNING "cmds + 0x%2x: %-15s: 0x%08x\n", i * 4,
623 name[i], cx_read(ch->cmds_start + 4 * i));
624
625 j = i * 4;
626 for (i = 0; i < 4;) {
627 risc = cx_read(ch->cmds_start + 4 * (i + 14));
628 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
629 i += cx25821_risc_decode(risc);
630 }
631
632 for (i = 0; i < (64 >> 2); i += n) {
633 risc = cx_read(ch->ctrl_start + 4 * i);
634 /* No consideration for bits 63-32 */
635
636 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
637 ch->ctrl_start + 4 * i, i);
638 n = cx25821_risc_decode(risc);
639 for (j = 1; j < n; j++) {
640 risc = cx_read(ch->ctrl_start + 4 * (i + j));
641 printk(KERN_WARNING
642 "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
643 4 * (i + j), i + j, risc, j);
644 }
645 }
646
647 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
648 ch->fifo_start, ch->fifo_start + ch->fifo_size);
649 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
650 ch->ctrl_start, ch->ctrl_start + 6 * 16);
651 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
652 cx_read(ch->ptr1_reg));
653 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
654 cx_read(ch->ptr2_reg));
655 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
656 cx_read(ch->cnt1_reg));
657 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
658 cx_read(ch->cnt2_reg));
659}
660
661void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
662 struct sram_channel *ch)
663{
664 static char *name[] = {
665 "init risc lo",
666 "init risc hi",
667 "cdt base",
668 "cdt size",
669 "iq base",
670 "iq size",
671 "risc pc lo",
672 "risc pc hi",
673 "iq wr ptr",
674 "iq rd ptr",
675 "cdt current",
676 "pci target lo",
677 "pci target hi",
678 "line / byte",
679 };
680
681 u32 risc, value, tmp;
682 unsigned int i, j, n;
683
684 printk(KERN_INFO "\n%s: %s - dma Audio channel status dump\n",
685 dev->name, ch->name);
686
687 for (i = 0; i < ARRAY_SIZE(name); i++)
688 printk(KERN_INFO "%s: cmds + 0x%2x: %-15s: 0x%08x\n",
689 dev->name, i * 4, name[i],
690 cx_read(ch->cmds_start + 4 * i));
691
692 j = i * 4;
693 for (i = 0; i < 4;) {
694 risc = cx_read(ch->cmds_start + 4 * (i + 14));
695 printk(KERN_WARNING "cmds + 0x%2x: risc%d: ", j + i * 4, i);
696 i += cx25821_risc_decode(risc);
697 }
698
699 for (i = 0; i < (64 >> 2); i += n) {
700 risc = cx_read(ch->ctrl_start + 4 * i);
701 /* No consideration for bits 63-32 */
702
703 printk(KERN_WARNING "ctrl + 0x%2x (0x%08x): iq %x: ", i * 4,
704 ch->ctrl_start + 4 * i, i);
705 n = cx25821_risc_decode(risc);
706
707 for (j = 1; j < n; j++) {
708 risc = cx_read(ch->ctrl_start + 4 * (i + j));
709 printk(KERN_WARNING
710 "ctrl + 0x%2x : iq %x: 0x%08x [ arg #%d ]\n",
711 4 * (i + j), i + j, risc, j);
712 }
713 }
714
715 printk(KERN_WARNING " : fifo: 0x%08x -> 0x%x\n",
716 ch->fifo_start, ch->fifo_start + ch->fifo_size);
717 printk(KERN_WARNING " : ctrl: 0x%08x -> 0x%x\n",
718 ch->ctrl_start, ch->ctrl_start + 6 * 16);
719 printk(KERN_WARNING " : ptr1_reg: 0x%08x\n",
720 cx_read(ch->ptr1_reg));
721 printk(KERN_WARNING " : ptr2_reg: 0x%08x\n",
722 cx_read(ch->ptr2_reg));
723 printk(KERN_WARNING " : cnt1_reg: 0x%08x\n",
724 cx_read(ch->cnt1_reg));
725 printk(KERN_WARNING " : cnt2_reg: 0x%08x\n",
726 cx_read(ch->cnt2_reg));
727
728 for (i = 0; i < 4; i++) {
729 risc = cx_read(ch->cmds_start + 56 + (i * 4));
730 printk(KERN_WARNING "instruction %d = 0x%x\n", i, risc);
731 }
732
733 //read data from the first cdt buffer
734 risc = cx_read(AUD_A_CDT);
735 printk(KERN_WARNING "\nread cdt loc=0x%x\n", risc);
736 for (i = 0; i < 8; i++) {
737 n = cx_read(risc + i * 4);
738 printk(KERN_WARNING "0x%x ", n);
739 }
740 printk(KERN_WARNING "\n\n");
741
742 value = cx_read(CLK_RST);
743 CX25821_INFO(" CLK_RST = 0x%x \n\n", value);
744
745 value = cx_read(PLL_A_POST_STAT_BIST);
746 CX25821_INFO(" PLL_A_POST_STAT_BIST = 0x%x \n\n", value);
747 value = cx_read(PLL_A_INT_FRAC);
748 CX25821_INFO(" PLL_A_INT_FRAC = 0x%x \n\n", value);
749
750 value = cx_read(PLL_B_POST_STAT_BIST);
751 CX25821_INFO(" PLL_B_POST_STAT_BIST = 0x%x \n\n", value);
752 value = cx_read(PLL_B_INT_FRAC);
753 CX25821_INFO(" PLL_B_INT_FRAC = 0x%x \n\n", value);
754
755 value = cx_read(PLL_C_POST_STAT_BIST);
756 CX25821_INFO(" PLL_C_POST_STAT_BIST = 0x%x \n\n", value);
757 value = cx_read(PLL_C_INT_FRAC);
758 CX25821_INFO(" PLL_C_INT_FRAC = 0x%x \n\n", value);
759
760 value = cx_read(PLL_D_POST_STAT_BIST);
761 CX25821_INFO(" PLL_D_POST_STAT_BIST = 0x%x \n\n", value);
762 value = cx_read(PLL_D_INT_FRAC);
763 CX25821_INFO(" PLL_D_INT_FRAC = 0x%x \n\n", value);
764
765 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
766 CX25821_INFO(" AFE_AB_DIAG_CTRL (0x10900090) = 0x%x \n\n", value);
767}
768
769static void cx25821_shutdown(struct cx25821_dev *dev)
770{
771 int i;
772
773 /* disable RISC controller */
774 cx_write(DEV_CNTRL2, 0);
775
776 /* Disable Video A/B activity */
777 for (i = 0; i < VID_CHANNEL_NUM; i++) {
778 cx_write(dev->sram_channels[i].dma_ctl, 0);
779 cx_write(dev->sram_channels[i].int_msk, 0);
780 }
781
782 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
783 i++) {
784 cx_write(dev->sram_channels[i].dma_ctl, 0);
785 cx_write(dev->sram_channels[i].int_msk, 0);
786 }
787
788 /* Disable Audio activity */
789 cx_write(AUD_INT_DMA_CTL, 0);
790
791 /* Disable Serial port */
792 cx_write(UART_CTL, 0);
793
794 /* Disable Interrupts */
795 cx_write(PCI_INT_MSK, 0);
796 cx_write(AUD_A_INT_MSK, 0);
797}
798
799void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel_select,
800 u32 format)
801{
802 struct sram_channel *ch;
803
804 if (channel_select <= 7 && channel_select >= 0) {
805 ch = &cx25821_sram_channels[channel_select];
806 cx_write(ch->pix_frmt, format);
807 dev->pixel_formats[channel_select] = format;
808 }
809}
810
811static void cx25821_set_vip_mode(struct cx25821_dev *dev,
812 struct sram_channel *ch)
813{
814 cx_write(ch->pix_frmt, PIXEL_FRMT_422);
815 cx_write(ch->vip_ctl, PIXEL_ENGINE_VIP1);
816}
817
818static void cx25821_initialize(struct cx25821_dev *dev)
819{
820 int i;
821
822 dprintk(1, "%s()\n", __func__);
823
824 cx25821_shutdown(dev);
825 cx_write(PCI_INT_STAT, 0xffffffff);
826
827 for (i = 0; i < VID_CHANNEL_NUM; i++)
828 cx_write(dev->sram_channels[i].int_stat, 0xffffffff);
829
830 cx_write(AUD_A_INT_STAT, 0xffffffff);
831 cx_write(AUD_B_INT_STAT, 0xffffffff);
832 cx_write(AUD_C_INT_STAT, 0xffffffff);
833 cx_write(AUD_D_INT_STAT, 0xffffffff);
834 cx_write(AUD_E_INT_STAT, 0xffffffff);
835
836 cx_write(CLK_DELAY, cx_read(CLK_DELAY) & 0x80000000);
837 cx_write(PAD_CTRL, 0x12); //for I2C
838 cx25821_registers_init(dev); //init Pecos registers
839 mdelay(100);
840
841 for (i = 0; i < VID_CHANNEL_NUM; i++) {
842 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
843 cx25821_sram_channel_setup(dev, &dev->sram_channels[i], 1440,
844 0);
845 dev->pixel_formats[i] = PIXEL_FRMT_422;
846 dev->use_cif_resolution[i] = FALSE;
847 }
848
849 //Probably only affect Downstream
850 for (i = VID_UPSTREAM_SRAM_CHANNEL_I; i <= VID_UPSTREAM_SRAM_CHANNEL_J;
851 i++) {
852 cx25821_set_vip_mode(dev, &dev->sram_channels[i]);
853 }
854
855 cx25821_sram_channel_setup_audio(dev, &dev->sram_channels[SRAM_CH08],
856 128, 0);
857
858 cx25821_gpio_init(dev);
859}
860
861static int get_resources(struct cx25821_dev *dev)
862{
863 if (request_mem_region
864 (pci_resource_start(dev->pci, 0), pci_resource_len(dev->pci, 0),
865 dev->name))
866 return 0;
867
868 printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n",
869 dev->name, (unsigned long long)pci_resource_start(dev->pci, 0));
870
871 return -EBUSY;
872}
873
874static void cx25821_dev_checkrevision(struct cx25821_dev *dev)
875{
876 dev->hwrevision = cx_read(RDR_CFG2) & 0xff;
877
878 printk(KERN_INFO "%s() Hardware revision = 0x%02x\n", __func__,
879 dev->hwrevision);
880}
881
882static void cx25821_iounmap(struct cx25821_dev *dev)
883{
884 if (dev == NULL)
885 return;
886
887 /* Releasing IO memory */
888 if (dev->lmmio != NULL) {
889 CX25821_INFO("Releasing lmmio.\n");
890 iounmap(dev->lmmio);
891 dev->lmmio = NULL;
892 }
893}
894
895static int cx25821_dev_setup(struct cx25821_dev *dev)
896{
897 int io_size = 0, i;
898
899 struct video_device *video_template[] = {
900 &cx25821_video_template0,
901 &cx25821_video_template1,
902 &cx25821_video_template2,
903 &cx25821_video_template3,
904 &cx25821_video_template4,
905 &cx25821_video_template5,
906 &cx25821_video_template6,
907 &cx25821_video_template7,
908 &cx25821_video_template9,
909 &cx25821_video_template10,
910 &cx25821_video_template11,
911 &cx25821_videoioctl_template,
912 };
913
914 printk(KERN_INFO "\n***********************************\n");
915 printk(KERN_INFO "cx25821 set up\n");
916 printk(KERN_INFO "***********************************\n\n");
917
918 mutex_init(&dev->lock);
919
920 atomic_inc(&dev->refcount);
921
922 dev->nr = ++cx25821_devcount;
923 sprintf(dev->name, "cx25821[%d]", dev->nr);
924
925 mutex_lock(&devlist);
926 list_add_tail(&dev->devlist, &cx25821_devlist);
927 mutex_unlock(&devlist);
928
929 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
930 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
931
932 if (dev->pci->device != 0x8210) {
933 printk(KERN_INFO
934 "%s() Exiting. Incorrect Hardware device = 0x%02x\n",
935 __func__, dev->pci->device);
936 return -1;
937 } else {
938 printk(KERN_INFO "Athena Hardware device = 0x%02x\n",
939 dev->pci->device);
940 }
941
942 /* Apply a sensible clock frequency for the PCIe bridge */
943 dev->clk_freq = 28000000;
944 dev->sram_channels = cx25821_sram_channels;
945
946 if (dev->nr > 1) {
947 CX25821_INFO("dev->nr > 1!");
948 }
949
950 /* board config */
951 dev->board = 1; //card[dev->nr];
952 dev->_max_num_decoders = MAX_DECODERS;
953
954 dev->pci_bus = dev->pci->bus->number;
955 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
956 dev->pci_irqmask = 0x001f00;
957
958 /* External Master 1 Bus */
959 dev->i2c_bus[0].nr = 0;
960 dev->i2c_bus[0].dev = dev;
961 dev->i2c_bus[0].reg_stat = I2C1_STAT;
962 dev->i2c_bus[0].reg_ctrl = I2C1_CTRL;
963 dev->i2c_bus[0].reg_addr = I2C1_ADDR;
964 dev->i2c_bus[0].reg_rdata = I2C1_RDATA;
965 dev->i2c_bus[0].reg_wdata = I2C1_WDATA;
966 dev->i2c_bus[0].i2c_period = (0x07 << 24); /* 1.95MHz */
967
968
969 if (get_resources(dev) < 0) {
970 printk(KERN_ERR "%s No more PCIe resources for "
971 "subsystem: %04x:%04x\n",
972 dev->name, dev->pci->subsystem_vendor,
973 dev->pci->subsystem_device);
974
975 cx25821_devcount--;
976 return -ENODEV;
977 }
978
979 /* PCIe stuff */
980 dev->base_io_addr = pci_resource_start(dev->pci, 0);
981 io_size = pci_resource_len(dev->pci, 0);
982
983 if (!dev->base_io_addr) {
984 CX25821_ERR("No PCI Memory resources, exiting!\n");
985 return -ENODEV;
986 }
987
988 dev->lmmio = ioremap(dev->base_io_addr, pci_resource_len(dev->pci, 0));
989
990 if (!dev->lmmio) {
991 CX25821_ERR
992 ("ioremap failed, maybe increasing __VMALLOC_RESERVE in page.h\n");
993 cx25821_iounmap(dev);
994 return -ENOMEM;
995 }
996
997 dev->bmmio = (u8 __iomem *) dev->lmmio;
998
999 printk(KERN_INFO "%s: subsystem: %04x:%04x, board: %s [card=%d,%s]\n",
1000 dev->name, dev->pci->subsystem_vendor,
1001 dev->pci->subsystem_device, cx25821_boards[dev->board].name,
1002 dev->board, card[dev->nr] == dev->board ?
1003 "insmod option" : "autodetected");
1004
1005 /* init hardware */
1006 cx25821_initialize(dev);
1007
1008 cx25821_i2c_register(&dev->i2c_bus[0]);
1009// cx25821_i2c_register(&dev->i2c_bus[1]);
1010// cx25821_i2c_register(&dev->i2c_bus[2]);
1011
1012 CX25821_INFO("i2c register! bus->i2c_rc = %d\n",
1013 dev->i2c_bus[0].i2c_rc);
1014
1015 cx25821_card_setup(dev);
1016 medusa_video_init(dev);
1017
1018 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1019 if (cx25821_video_register(dev, i, video_template[i]) < 0) {
1020 printk(KERN_ERR
1021 "%s() Failed to register analog video adapters on VID channel %d\n",
1022 __func__, i);
1023 }
1024 }
1025
1026 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1027 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1028 //Since we don't have template8 for Audio Downstream
1029 if (cx25821_video_register(dev, i, video_template[i - 1]) < 0) {
1030 printk(KERN_ERR
1031 "%s() Failed to register analog video adapters for Upstream channel %d.\n",
1032 __func__, i);
1033 }
1034 }
1035
1036 // register IOCTL device
1037 dev->ioctl_dev =
1038 cx25821_vdev_init(dev, dev->pci, video_template[VIDEO_IOCTL_CH],
1039 "video");
1040
1041 if (video_register_device
1042 (dev->ioctl_dev, VFL_TYPE_GRABBER, VIDEO_IOCTL_CH) < 0) {
1043 cx25821_videoioctl_unregister(dev);
1044 printk(KERN_ERR
1045 "%s() Failed to register video adapter for IOCTL so releasing.\n",
1046 __func__);
1047 }
1048
1049 cx25821_dev_checkrevision(dev);
1050 CX25821_INFO("cx25821 setup done!\n");
1051
1052 return 0;
1053}
1054
1055void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
1056 struct upstream_user_struct *up_data)
1057{
1058 dev->_isNTSC = !strcmp(dev->vid_stdname, "NTSC") ? 1 : 0;
1059
1060 dev->tvnorm = !dev->_isNTSC ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1061 medusa_set_videostandard(dev);
1062
1063 cx25821_vidupstream_init_ch1(dev, dev->channel_select,
1064 dev->pixel_format);
1065}
1066
1067void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
1068 struct upstream_user_struct *up_data)
1069{
1070 dev->_isNTSC_ch2 = !strcmp(dev->vid_stdname_ch2, "NTSC") ? 1 : 0;
1071
1072 dev->tvnorm = !dev->_isNTSC_ch2 ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
1073 medusa_set_videostandard(dev);
1074
1075 cx25821_vidupstream_init_ch2(dev, dev->channel_select_ch2,
1076 dev->pixel_format_ch2);
1077}
1078
1079void cx25821_start_upstream_audio(struct cx25821_dev *dev,
1080 struct upstream_user_struct *up_data)
1081{
1082 cx25821_audio_upstream_init(dev, AUDIO_UPSTREAM_SRAM_CHANNEL_B);
1083}
1084
1085void cx25821_dev_unregister(struct cx25821_dev *dev)
1086{
1087 int i;
1088
1089 if (!dev->base_io_addr)
1090 return;
1091
1092 cx25821_free_mem_upstream_ch1(dev);
1093 cx25821_free_mem_upstream_ch2(dev);
1094 cx25821_free_mem_upstream_audio(dev);
1095
1096 release_mem_region(dev->base_io_addr, pci_resource_len(dev->pci, 0));
1097
1098 if (!atomic_dec_and_test(&dev->refcount))
1099 return;
1100
1101 for (i = 0; i < VID_CHANNEL_NUM; i++)
1102 cx25821_video_unregister(dev, i);
1103
1104 for (i = VID_UPSTREAM_SRAM_CHANNEL_I;
1105 i <= AUDIO_UPSTREAM_SRAM_CHANNEL_B; i++) {
1106 cx25821_video_unregister(dev, i);
1107 }
1108
1109 cx25821_videoioctl_unregister(dev);
1110
1111 cx25821_i2c_unregister(&dev->i2c_bus[0]);
1112 cx25821_iounmap(dev);
1113}
1114
1115static __le32 *cx25821_risc_field(__le32 * rp, struct scatterlist *sglist,
1116 unsigned int offset, u32 sync_line,
1117 unsigned int bpl, unsigned int padding,
1118 unsigned int lines)
1119{
1120 struct scatterlist *sg;
1121 unsigned int line, todo;
1122
1123 /* sync instruction */
1124 if (sync_line != NO_SYNC_LINE) {
1125 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1126 }
1127
1128 /* scan lines */
1129 sg = sglist;
1130 for (line = 0; line < lines; line++) {
1131 while (offset && offset >= sg_dma_len(sg)) {
1132 offset -= sg_dma_len(sg);
1133 sg++;
1134 }
1135 if (bpl <= sg_dma_len(sg) - offset) {
1136 /* fits into current chunk */
1137 *(rp++) =
1138 cpu_to_le32(RISC_WRITE | RISC_SOL | RISC_EOL | bpl);
1139 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1140 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1141 offset += bpl;
1142 } else {
1143 /* scanline needs to be split */
1144 todo = bpl;
1145 *(rp++) =
1146 cpu_to_le32(RISC_WRITE | RISC_SOL |
1147 (sg_dma_len(sg) - offset));
1148 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1149 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1150 todo -= (sg_dma_len(sg) - offset);
1151 offset = 0;
1152 sg++;
1153 while (todo > sg_dma_len(sg)) {
1154 *(rp++) =
1155 cpu_to_le32(RISC_WRITE | sg_dma_len(sg));
1156 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1157 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1158 todo -= sg_dma_len(sg);
1159 sg++;
1160 }
1161 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1162 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1163 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1164 offset += todo;
1165 }
1166
1167 offset += padding;
1168 }
1169
1170 return rp;
1171}
1172
1173int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
1174 struct scatterlist *sglist, unsigned int top_offset,
1175 unsigned int bottom_offset, unsigned int bpl,
1176 unsigned int padding, unsigned int lines)
1177{
1178 u32 instructions;
1179 u32 fields;
1180 __le32 *rp;
1181 int rc;
1182
1183 fields = 0;
1184 if (UNSET != top_offset)
1185 fields++;
1186 if (UNSET != bottom_offset)
1187 fields++;
1188
1189 /* estimate risc mem: worst case is one write per page border +
1190 one write per scan line + syncs + jump (all 2 dwords). Padding
1191 can cause next bpl to start close to a page border. First DMA
1192 region may be smaller than PAGE_SIZE */
1193 /* write and jump need and extra dword */
1194 instructions =
1195 fields * (1 + ((bpl + padding) * lines) / PAGE_SIZE + lines);
1196 instructions += 2;
1197 rc = btcx_riscmem_alloc(pci, risc, instructions * 12);
1198
1199 if (rc < 0)
1200 return rc;
1201
1202 /* write risc instructions */
1203 rp = risc->cpu;
1204
1205 if (UNSET != top_offset) {
1206 rp = cx25821_risc_field(rp, sglist, top_offset, 0, bpl, padding,
1207 lines);
1208 }
1209
1210 if (UNSET != bottom_offset) {
1211 rp = cx25821_risc_field(rp, sglist, bottom_offset, 0x200, bpl,
1212 padding, lines);
1213 }
1214
1215 /* save pointer to jmp instruction address */
1216 risc->jmp = rp;
1217 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1218
1219 return 0;
1220}
1221
1222static __le32 *cx25821_risc_field_audio(__le32 * rp, struct scatterlist *sglist,
1223 unsigned int offset, u32 sync_line,
1224 unsigned int bpl, unsigned int padding,
1225 unsigned int lines, unsigned int lpi)
1226{
1227 struct scatterlist *sg;
1228 unsigned int line, todo, sol;
1229
1230 /* sync instruction */
1231 if (sync_line != NO_SYNC_LINE)
1232 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
1233
1234 /* scan lines */
1235 sg = sglist;
1236 for (line = 0; line < lines; line++) {
1237 while (offset && offset >= sg_dma_len(sg)) {
1238 offset -= sg_dma_len(sg);
1239 sg++;
1240 }
1241
1242 if (lpi && line > 0 && !(line % lpi))
1243 sol = RISC_SOL | RISC_IRQ1 | RISC_CNT_INC;
1244 else
1245 sol = RISC_SOL;
1246
1247 if (bpl <= sg_dma_len(sg) - offset) {
1248 /* fits into current chunk */
1249 *(rp++) =
1250 cpu_to_le32(RISC_WRITE | sol | RISC_EOL | bpl);
1251 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1252 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1253 offset += bpl;
1254 } else {
1255 /* scanline needs to be split */
1256 todo = bpl;
1257 *(rp++) = cpu_to_le32(RISC_WRITE | sol |
1258 (sg_dma_len(sg) - offset));
1259 *(rp++) = cpu_to_le32(sg_dma_address(sg) + offset);
1260 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1261 todo -= (sg_dma_len(sg) - offset);
1262 offset = 0;
1263 sg++;
1264 while (todo > sg_dma_len(sg)) {
1265 *(rp++) = cpu_to_le32(RISC_WRITE |
1266 sg_dma_len(sg));
1267 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1268 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1269 todo -= sg_dma_len(sg);
1270 sg++;
1271 }
1272 *(rp++) = cpu_to_le32(RISC_WRITE | RISC_EOL | todo);
1273 *(rp++) = cpu_to_le32(sg_dma_address(sg));
1274 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1275 offset += todo;
1276 }
1277 offset += padding;
1278 }
1279
1280 return rp;
1281}
1282
1283int cx25821_risc_databuffer_audio(struct pci_dev *pci,
1284 struct btcx_riscmem *risc,
1285 struct scatterlist *sglist,
1286 unsigned int bpl,
1287 unsigned int lines, unsigned int lpi)
1288{
1289 u32 instructions;
1290 __le32 *rp;
1291 int rc;
1292
1293 /* estimate risc mem: worst case is one write per page border +
1294 one write per scan line + syncs + jump (all 2 dwords). Here
1295 there is no padding and no sync. First DMA region may be smaller
1296 than PAGE_SIZE */
1297 /* Jump and write need an extra dword */
1298 instructions = 1 + (bpl * lines) / PAGE_SIZE + lines;
1299 instructions += 1;
1300
1301 if ((rc = btcx_riscmem_alloc(pci, risc, instructions * 12)) < 0)
1302 return rc;
1303
1304 /* write risc instructions */
1305 rp = risc->cpu;
1306 rp = cx25821_risc_field_audio(rp, sglist, 0, NO_SYNC_LINE, bpl, 0,
1307 lines, lpi);
1308
1309 /* save pointer to jmp instruction address */
1310 risc->jmp = rp;
1311 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1312 return 0;
1313}
1314
1315int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
1316 u32 reg, u32 mask, u32 value)
1317{
1318 __le32 *rp;
1319 int rc;
1320
1321 rc = btcx_riscmem_alloc(pci, risc, 4 * 16);
1322
1323 if (rc < 0)
1324 return rc;
1325
1326 /* write risc instructions */
1327 rp = risc->cpu;
1328
1329 *(rp++) = cpu_to_le32(RISC_WRITECR | RISC_IRQ1);
1330 *(rp++) = cpu_to_le32(reg);
1331 *(rp++) = cpu_to_le32(value);
1332 *(rp++) = cpu_to_le32(mask);
1333 *(rp++) = cpu_to_le32(RISC_JUMP);
1334 *(rp++) = cpu_to_le32(risc->dma);
1335 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
1336 return 0;
1337}
1338
1339void cx25821_free_buffer(struct videobuf_queue *q, struct cx25821_buffer *buf)
1340{
1341 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
1342
1343 BUG_ON(in_interrupt());
1344 videobuf_waiton(&buf->vb, 0, 0);
1345 videobuf_dma_unmap(q, dma);
1346 videobuf_dma_free(dma);
1347 btcx_riscmem_free(to_pci_dev(q->dev), &buf->risc);
1348 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1349}
1350
1351static irqreturn_t cx25821_irq(int irq, void *dev_id)
1352{
1353 struct cx25821_dev *dev = dev_id;
1354 u32 pci_status, pci_mask;
1355 u32 vid_status;
1356 int i, handled = 0;
1357 u32 mask[8] = { 1, 2, 4, 8, 16, 32, 64, 128 };
1358
1359 pci_status = cx_read(PCI_INT_STAT);
1360 pci_mask = cx_read(PCI_INT_MSK);
1361
1362 if (pci_status == 0)
1363 goto out;
1364
1365 for (i = 0; i < VID_CHANNEL_NUM; i++) {
1366 if (pci_status & mask[i]) {
1367 vid_status = cx_read(dev->sram_channels[i].int_stat);
1368
1369 if (vid_status)
1370 handled +=
1371 cx25821_video_irq(dev, i, vid_status);
1372
1373 cx_write(PCI_INT_STAT, mask[i]);
1374 }
1375 }
1376
1377 out:
1378 return IRQ_RETVAL(handled);
1379}
1380
1381void cx25821_print_irqbits(char *name, char *tag, char **strings,
1382 int len, u32 bits, u32 mask)
1383{
1384 unsigned int i;
1385
1386 printk(KERN_DEBUG "%s: %s [0x%x]", name, tag, bits);
1387
1388 for (i = 0; i < len; i++) {
1389 if (!(bits & (1 << i)))
1390 continue;
1391 if (strings[i])
1392 printk(" %s", strings[i]);
1393 else
1394 printk(" %d", i);
1395 if (!(mask & (1 << i)))
1396 continue;
1397 printk("*");
1398 }
1399 printk("\n");
1400}
1401
1402struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci)
1403{
1404 struct cx25821_dev *dev = pci_get_drvdata(pci);
1405 return dev;
1406}
1407
1408static int __devinit cx25821_initdev(struct pci_dev *pci_dev,
1409 const struct pci_device_id *pci_id)
1410{
1411 struct cx25821_dev *dev;
1412 int err = 0;
1413
1414 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
1415 if (NULL == dev)
1416 return -ENOMEM;
1417
1418 err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
1419 if (err < 0)
1420 goto fail_free;
1421
1422 /* pci init */
1423 dev->pci = pci_dev;
1424 if (pci_enable_device(pci_dev)) {
1425 err = -EIO;
1426
1427 printk(KERN_INFO "pci enable failed! ");
1428
1429 goto fail_unregister_device;
1430 }
1431
1432 printk(KERN_INFO "cx25821 Athena pci enable ! \n");
1433
1434 if (cx25821_dev_setup(dev) < 0) {
1435 err = -EINVAL;
1436 goto fail_unregister_device;
1437 }
1438
1439 /* print pci info */
1440 pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev);
1441 pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat);
1442 printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, "
1443 "latency: %d, mmio: 0x%llx\n", dev->name,
1444 pci_name(pci_dev), dev->pci_rev, pci_dev->irq,
1445 dev->pci_lat, (unsigned long long)dev->base_io_addr);
1446
1447 pci_set_master(pci_dev);
1448 if (!pci_dma_supported(pci_dev, 0xffffffff)) {
1449 printk("%s/0: Oops: no 32bit PCI DMA ???\n", dev->name);
1450 err = -EIO;
1451 goto fail_irq;
1452 }
1453
1454 err =
1455 request_irq(pci_dev->irq, cx25821_irq, IRQF_SHARED | IRQF_DISABLED,
1456 dev->name, dev);
1457
1458 if (err < 0) {
1459 printk(KERN_ERR "%s: can't get IRQ %d\n", dev->name,
1460 pci_dev->irq);
1461 goto fail_irq;
1462 }
1463
1464 return 0;
1465
1466 fail_irq:
1467 printk(KERN_INFO "cx25821 cx25821_initdev() can't get IRQ ! \n");
1468 cx25821_dev_unregister(dev);
1469
1470 fail_unregister_device:
1471 v4l2_device_unregister(&dev->v4l2_dev);
1472
1473 fail_free:
1474 kfree(dev);
1475 return err;
1476}
1477
1478static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
1479{
1480 struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
1481 struct cx25821_dev *dev = get_cx25821(v4l2_dev);
1482
1483 cx25821_shutdown(dev);
1484 pci_disable_device(pci_dev);
1485
1486 /* unregister stuff */
1487 if (pci_dev->irq)
1488 free_irq(pci_dev->irq, dev);
1489
1490 mutex_lock(&devlist);
1491 list_del(&dev->devlist);
1492 mutex_unlock(&devlist);
1493
1494 cx25821_dev_unregister(dev);
1495 v4l2_device_unregister(v4l2_dev);
1496 kfree(dev);
1497}
1498
1499static struct pci_device_id cx25821_pci_tbl[] = {
1500 {
1501 /* CX25821 Athena */
1502 .vendor = 0x14f1,
1503 .device = 0x8210,
1504 .subvendor = 0x14f1,
1505 .subdevice = 0x0920,
1506 },
1507 {
1508 /* --- end of list --- */
1509 }
1510};
1511
1512MODULE_DEVICE_TABLE(pci, cx25821_pci_tbl);
1513
1514static struct pci_driver cx25821_pci_driver = {
1515 .name = "cx25821",
1516 .id_table = cx25821_pci_tbl,
1517 .probe = cx25821_initdev,
1518 .remove = __devexit_p(cx25821_finidev),
1519 /* TODO */
1520 .suspend = NULL,
1521 .resume = NULL,
1522};
1523
1524static int cx25821_init(void)
1525{
1526 INIT_LIST_HEAD(&cx25821_devlist);
1527 printk(KERN_INFO "cx25821 driver version %d.%d.%d loaded\n",
1528 (CX25821_VERSION_CODE >> 16) & 0xff,
1529 (CX25821_VERSION_CODE >> 8) & 0xff, CX25821_VERSION_CODE & 0xff);
1530 return pci_register_driver(&cx25821_pci_driver);
1531}
1532
1533static void cx25821_fini(void)
1534{
1535 pci_unregister_driver(&cx25821_pci_driver);
1536}
1537
1538EXPORT_SYMBOL(cx25821_devlist);
1539EXPORT_SYMBOL(cx25821_sram_channels);
1540EXPORT_SYMBOL(cx25821_print_irqbits);
1541EXPORT_SYMBOL(cx25821_dev_get);
1542EXPORT_SYMBOL(cx25821_dev_unregister);
1543EXPORT_SYMBOL(cx25821_sram_channel_setup);
1544EXPORT_SYMBOL(cx25821_sram_channel_dump);
1545EXPORT_SYMBOL(cx25821_sram_channel_setup_audio);
1546EXPORT_SYMBOL(cx25821_sram_channel_dump_audio);
1547EXPORT_SYMBOL(cx25821_risc_databuffer_audio);
1548EXPORT_SYMBOL(cx25821_set_gpiopin_direction);
1549
1550module_init(cx25821_init);
1551module_exit(cx25821_fini);
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/staging/cx25821/cx25821-gpio.c
new file mode 100644
index 000000000000..e8a37b47e437
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.c
@@ -0,0 +1,98 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24
25/********************* GPIO stuffs *********************/
26void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
27 int pin_number, int pin_logic_value)
28{
29 int bit = pin_number;
30 u32 gpio_oe_reg = GPIO_LO_OE;
31 u32 gpio_register = 0;
32 u32 value = 0;
33
34 // Check for valid pinNumber
35 if (pin_number >= 47)
36 return;
37
38 if (pin_number > 31) {
39 bit = pin_number - 31;
40 gpio_oe_reg = GPIO_HI_OE;
41 }
42 // Here we will make sure that the GPIOs 0 and 1 are output. keep the rest as is
43 gpio_register = cx_read(gpio_oe_reg);
44
45 if (pin_logic_value == 1) {
46 value = gpio_register | Set_GPIO_Bit(bit);
47 } else {
48 value = gpio_register & Clear_GPIO_Bit(bit);
49 }
50
51 cx_write(gpio_oe_reg, value);
52}
53
54static void cx25821_set_gpiopin_logicvalue(struct cx25821_dev *dev,
55 int pin_number, int pin_logic_value)
56{
57 int bit = pin_number;
58 u32 gpio_reg = GPIO_LO;
59 u32 value = 0;
60
61 // Check for valid pinNumber
62 if (pin_number >= 47)
63 return;
64
65 cx25821_set_gpiopin_direction(dev, pin_number, 0); // change to output direction
66
67 if (pin_number > 31) {
68 bit = pin_number - 31;
69 gpio_reg = GPIO_HI;
70 }
71
72 value = cx_read(gpio_reg);
73
74 if (pin_logic_value == 0) {
75 value &= Clear_GPIO_Bit(bit);
76 } else {
77 value |= Set_GPIO_Bit(bit);
78 }
79
80 cx_write(gpio_reg, value);
81}
82
83void cx25821_gpio_init(struct cx25821_dev *dev)
84{
85 if (dev == NULL) {
86 return;
87 }
88
89 switch (dev->board) {
90 case CX25821_BOARD_CONEXANT_ATHENA10:
91 default:
92 //set GPIO 5 to select the path for Medusa/Athena
93 cx25821_set_gpiopin_logicvalue(dev, 5, 1);
94 mdelay(20);
95 break;
96 }
97
98}
diff --git a/drivers/staging/cx25821/cx25821-gpio.h b/drivers/staging/cx25821/cx25821-gpio.h
new file mode 100644
index 000000000000..ca07644154af
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-gpio.h
@@ -0,0 +1,2 @@
1
2void cx25821_gpio_init(struct athena_dev *dev);
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/staging/cx25821/cx25821-i2c.c
new file mode 100644
index 000000000000..f4f2681d8f1c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-i2c.c
@@ -0,0 +1,419 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821.h"
25#include <linux/i2c.h>
26
27static unsigned int i2c_debug;
28module_param(i2c_debug, int, 0644);
29MODULE_PARM_DESC(i2c_debug, "enable debug messages [i2c]");
30
31static unsigned int i2c_scan = 0;
32module_param(i2c_scan, int, 0444);
33MODULE_PARM_DESC(i2c_scan, "scan i2c bus at insmod time");
34
35#define dprintk(level, fmt, arg...)\
36 do { if (i2c_debug >= level)\
37 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
38 } while (0)
39
40#define I2C_WAIT_DELAY 32
41#define I2C_WAIT_RETRY 64
42
43#define I2C_EXTEND (1 << 3)
44#define I2C_NOSTOP (1 << 4)
45
46static inline int i2c_slave_did_ack(struct i2c_adapter *i2c_adap)
47{
48 struct cx25821_i2c *bus = i2c_adap->algo_data;
49 struct cx25821_dev *dev = bus->dev;
50 return cx_read(bus->reg_stat) & 0x01;
51}
52
53static inline int i2c_is_busy(struct i2c_adapter *i2c_adap)
54{
55 struct cx25821_i2c *bus = i2c_adap->algo_data;
56 struct cx25821_dev *dev = bus->dev;
57 return cx_read(bus->reg_stat) & 0x02 ? 1 : 0;
58}
59
60static int i2c_wait_done(struct i2c_adapter *i2c_adap)
61{
62 int count;
63
64 for (count = 0; count < I2C_WAIT_RETRY; count++) {
65 if (!i2c_is_busy(i2c_adap))
66 break;
67 udelay(I2C_WAIT_DELAY);
68 }
69
70 if (I2C_WAIT_RETRY == count)
71 return 0;
72
73 return 1;
74}
75
76static int i2c_sendbytes(struct i2c_adapter *i2c_adap,
77 const struct i2c_msg *msg, int joined_rlen)
78{
79 struct cx25821_i2c *bus = i2c_adap->algo_data;
80 struct cx25821_dev *dev = bus->dev;
81 u32 wdata, addr, ctrl;
82 int retval, cnt;
83
84 if (joined_rlen)
85 dprintk(1, "%s(msg->wlen=%d, nextmsg->rlen=%d)\n", __func__,
86 msg->len, joined_rlen);
87 else
88 dprintk(1, "%s(msg->len=%d)\n", __func__, msg->len);
89
90 /* Deal with i2c probe functions with zero payload */
91 if (msg->len == 0) {
92 cx_write(bus->reg_addr, msg->addr << 25);
93 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2));
94
95 if (!i2c_wait_done(i2c_adap))
96 return -EIO;
97
98 if (!i2c_slave_did_ack(i2c_adap))
99 return -EIO;
100
101 dprintk(1, "%s() returns 0\n", __func__);
102 return 0;
103 }
104
105 /* dev, reg + first byte */
106 addr = (msg->addr << 25) | msg->buf[0];
107 wdata = msg->buf[0];
108
109 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
110
111 if (msg->len > 1)
112 ctrl |= I2C_NOSTOP | I2C_EXTEND;
113 else if (joined_rlen)
114 ctrl |= I2C_NOSTOP;
115
116 cx_write(bus->reg_addr, addr);
117 cx_write(bus->reg_wdata, wdata);
118 cx_write(bus->reg_ctrl, ctrl);
119
120 retval = i2c_wait_done(i2c_adap);
121 if (retval < 0)
122 goto err;
123
124 if (retval == 0)
125 goto eio;
126
127 if (i2c_debug) {
128 if (!(ctrl & I2C_NOSTOP))
129 printk(" >\n");
130 }
131
132 for (cnt = 1; cnt < msg->len; cnt++) {
133 /* following bytes */
134 wdata = msg->buf[cnt];
135 ctrl = bus->i2c_period | (1 << 12) | (1 << 2);
136
137 if (cnt < msg->len - 1)
138 ctrl |= I2C_NOSTOP | I2C_EXTEND;
139 else if (joined_rlen)
140 ctrl |= I2C_NOSTOP;
141
142 cx_write(bus->reg_addr, addr);
143 cx_write(bus->reg_wdata, wdata);
144 cx_write(bus->reg_ctrl, ctrl);
145
146 retval = i2c_wait_done(i2c_adap);
147 if (retval < 0)
148 goto err;
149
150 if (retval == 0)
151 goto eio;
152
153 if (i2c_debug) {
154 dprintk(1, " %02x", msg->buf[cnt]);
155 if (!(ctrl & I2C_NOSTOP))
156 dprintk(1, " >\n");
157 }
158 }
159
160 return msg->len;
161
162 eio:
163 retval = -EIO;
164 err:
165 if (i2c_debug)
166 printk(KERN_ERR " ERR: %d\n", retval);
167 return retval;
168}
169
170static int i2c_readbytes(struct i2c_adapter *i2c_adap,
171 const struct i2c_msg *msg, int joined)
172{
173 struct cx25821_i2c *bus = i2c_adap->algo_data;
174 struct cx25821_dev *dev = bus->dev;
175 u32 ctrl, cnt;
176 int retval;
177
178 if (i2c_debug && !joined)
179 dprintk(1, "6-%s(msg->len=%d)\n", __func__, msg->len);
180
181 /* Deal with i2c probe functions with zero payload */
182 if (msg->len == 0) {
183 cx_write(bus->reg_addr, msg->addr << 25);
184 cx_write(bus->reg_ctrl, bus->i2c_period | (1 << 2) | 1);
185 if (!i2c_wait_done(i2c_adap))
186 return -EIO;
187 if (!i2c_slave_did_ack(i2c_adap))
188 return -EIO;
189
190 dprintk(1, "%s() returns 0\n", __func__);
191 return 0;
192 }
193
194 if (i2c_debug) {
195 if (joined)
196 dprintk(1, " R");
197 else
198 dprintk(1, " <R %02x", (msg->addr << 1) + 1);
199 }
200
201 for (cnt = 0; cnt < msg->len; cnt++) {
202
203 ctrl = bus->i2c_period | (1 << 12) | (1 << 2) | 1;
204
205 if (cnt < msg->len - 1)
206 ctrl |= I2C_NOSTOP | I2C_EXTEND;
207
208 cx_write(bus->reg_addr, msg->addr << 25);
209 cx_write(bus->reg_ctrl, ctrl);
210
211 retval = i2c_wait_done(i2c_adap);
212 if (retval < 0)
213 goto err;
214 if (retval == 0)
215 goto eio;
216 msg->buf[cnt] = cx_read(bus->reg_rdata) & 0xff;
217
218 if (i2c_debug) {
219 dprintk(1, " %02x", msg->buf[cnt]);
220 if (!(ctrl & I2C_NOSTOP))
221 dprintk(1, " >\n");
222 }
223 }
224
225 return msg->len;
226 eio:
227 retval = -EIO;
228 err:
229 if (i2c_debug)
230 printk(KERN_ERR " ERR: %d\n", retval);
231 return retval;
232}
233
234static int i2c_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
235{
236 struct cx25821_i2c *bus = i2c_adap->algo_data;
237 struct cx25821_dev *dev = bus->dev;
238 int i, retval = 0;
239
240 dprintk(1, "%s(num = %d)\n", __func__, num);
241
242 for (i = 0; i < num; i++) {
243 dprintk(1, "%s(num = %d) addr = 0x%02x len = 0x%x\n",
244 __func__, num, msgs[i].addr, msgs[i].len);
245
246 if (msgs[i].flags & I2C_M_RD) {
247 /* read */
248 retval = i2c_readbytes(i2c_adap, &msgs[i], 0);
249 } else if (i + 1 < num && (msgs[i + 1].flags & I2C_M_RD) &&
250 msgs[i].addr == msgs[i + 1].addr) {
251 /* write then read from same address */
252 retval =
253 i2c_sendbytes(i2c_adap, &msgs[i], msgs[i + 1].len);
254
255 if (retval < 0)
256 goto err;
257 i++;
258 retval = i2c_readbytes(i2c_adap, &msgs[i], 1);
259 } else {
260 /* write */
261 retval = i2c_sendbytes(i2c_adap, &msgs[i], 0);
262 }
263
264 if (retval < 0)
265 goto err;
266 }
267 return num;
268
269 err:
270 return retval;
271}
272
273
274static u32 cx25821_functionality(struct i2c_adapter *adap)
275{
276 return I2C_FUNC_SMBUS_EMUL |
277 I2C_FUNC_I2C |
278 I2C_FUNC_SMBUS_WORD_DATA |
279 I2C_FUNC_SMBUS_READ_WORD_DATA | I2C_FUNC_SMBUS_WRITE_WORD_DATA;
280}
281
282static struct i2c_algorithm cx25821_i2c_algo_template = {
283 .master_xfer = i2c_xfer,
284 .functionality = cx25821_functionality,
285};
286
287static struct i2c_adapter cx25821_i2c_adap_template = {
288 .name = "cx25821",
289 .owner = THIS_MODULE,
290 .algo = &cx25821_i2c_algo_template,
291};
292
293static struct i2c_client cx25821_i2c_client_template = {
294 .name = "cx25821 internal",
295};
296
297/* init + register i2c algo-bit adapter */
298int cx25821_i2c_register(struct cx25821_i2c *bus)
299{
300 struct cx25821_dev *dev = bus->dev;
301
302 dprintk(1, "%s(bus = %d)\n", __func__, bus->nr);
303
304 memcpy(&bus->i2c_adap, &cx25821_i2c_adap_template,
305 sizeof(bus->i2c_adap));
306 memcpy(&bus->i2c_algo, &cx25821_i2c_algo_template,
307 sizeof(bus->i2c_algo));
308 memcpy(&bus->i2c_client, &cx25821_i2c_client_template,
309 sizeof(bus->i2c_client));
310
311 bus->i2c_adap.dev.parent = &dev->pci->dev;
312
313 strlcpy(bus->i2c_adap.name, bus->dev->name, sizeof(bus->i2c_adap.name));
314
315 bus->i2c_algo.data = bus;
316 bus->i2c_adap.algo_data = bus;
317 i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
318 i2c_add_adapter(&bus->i2c_adap);
319
320 bus->i2c_client.adapter = &bus->i2c_adap;
321
322 //set up the I2c
323 bus->i2c_client.addr = (0x88 >> 1);
324
325 return bus->i2c_rc;
326}
327
328int cx25821_i2c_unregister(struct cx25821_i2c *bus)
329{
330 i2c_del_adapter(&bus->i2c_adap);
331 return 0;
332}
333
334void cx25821_av_clk(struct cx25821_dev *dev, int enable)
335{
336 /* write 0 to bus 2 addr 0x144 via i2x_xfer() */
337 char buffer[3];
338 struct i2c_msg msg;
339 dprintk(1, "%s(enabled = %d)\n", __func__, enable);
340
341 /* Register 0x144 */
342 buffer[0] = 0x01;
343 buffer[1] = 0x44;
344 if (enable == 1)
345 buffer[2] = 0x05;
346 else
347 buffer[2] = 0x00;
348
349 msg.addr = 0x44;
350 msg.flags = I2C_M_TEN;
351 msg.len = 3;
352 msg.buf = buffer;
353
354 i2c_xfer(&dev->i2c_bus[0].i2c_adap, &msg, 1);
355}
356
357int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value)
358{
359 struct i2c_client *client = &bus->i2c_client;
360 int retval = 0;
361 int v = 0;
362 u8 addr[2] = { 0, 0 };
363 u8 buf[4] = { 0, 0, 0, 0 };
364
365 struct i2c_msg msgs[2] = {
366 {
367 .addr = client->addr,
368 .flags = 0,
369 .len = 2,
370 .buf = addr,
371 }, {
372 .addr = client->addr,
373 .flags = I2C_M_RD,
374 .len = 4,
375 .buf = buf,
376 }
377 };
378
379 addr[0] = (reg_addr >> 8);
380 addr[1] = (reg_addr & 0xff);
381 msgs[0].addr = 0x44;
382 msgs[1].addr = 0x44;
383
384 retval = i2c_xfer(client->adapter, msgs, 2);
385
386 v = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
387 *value = v;
388
389 return v;
390}
391
392int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value)
393{
394 struct i2c_client *client = &bus->i2c_client;
395 int retval = 0;
396 u8 buf[6] = { 0, 0, 0, 0, 0, 0 };
397
398 struct i2c_msg msgs[1] = {
399 {
400 .addr = client->addr,
401 .flags = 0,
402 .len = 6,
403 .buf = buf,
404 }
405 };
406
407 buf[0] = reg_addr >> 8;
408 buf[1] = reg_addr & 0xff;
409 buf[5] = (value >> 24) & 0xff;
410 buf[4] = (value >> 16) & 0xff;
411 buf[3] = (value >> 8) & 0xff;
412 buf[2] = value & 0xff;
413 client->flags = 0;
414 msgs[0].addr = 0x44;
415
416 retval = i2c_xfer(client->adapter, msgs, 1);
417
418 return retval;
419}
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/staging/cx25821/cx25821-medusa-defines.h
new file mode 100644
index 000000000000..b0d216ba7f81
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-defines.h
@@ -0,0 +1,51 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _MEDUSA_DEF_H_
24#define _MEDUSA_DEF_H_
25
26// Video deocder that we supported
27#define VDEC_A 0
28#define VDEC_B 1
29#define VDEC_C 2
30#define VDEC_D 3
31#define VDEC_E 4
32#define VDEC_F 5
33#define VDEC_G 6
34#define VDEC_H 7
35
36//#define AUTO_SWITCH_BIT[] = { 8, 9, 10, 11, 12, 13, 14, 15 };
37
38// The following bit position enables automatic source switching for decoder A-H.
39// Display index per camera.
40//#define VDEC_INDEX[] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7};
41
42// Select input bit to video decoder A-H.
43//#define CH_SRC_SEL_BIT[] = {24, 25, 26, 27, 28, 29, 30, 31};
44
45// end of display sequence
46#define END_OF_SEQ 0xF;
47
48// registry string size
49#define MAX_REGISTRY_SZ 40;
50
51#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/staging/cx25821/cx25821-medusa-reg.h
new file mode 100644
index 000000000000..12c90f831b22
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-reg.h
@@ -0,0 +1,455 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __MEDUSA_REGISTERS__
24#define __MEDUSA_REGISTERS__
25
26// Serial Slave Registers
27#define HOST_REGISTER1 0x0000
28#define HOST_REGISTER2 0x0001
29
30// Chip Configuration Registers
31#define CHIP_CTRL 0x0100
32#define AFE_AB_CTRL 0x0104
33#define AFE_CD_CTRL 0x0108
34#define AFE_EF_CTRL 0x010C
35#define AFE_GH_CTRL 0x0110
36#define DENC_AB_CTRL 0x0114
37#define BYP_AB_CTRL 0x0118
38#define MON_A_CTRL 0x011C
39#define DISP_SEQ_A 0x0120
40#define DISP_SEQ_B 0x0124
41#define DISP_AB_CNT 0x0128
42#define DISP_CD_CNT 0x012C
43#define DISP_EF_CNT 0x0130
44#define DISP_GH_CNT 0x0134
45#define DISP_IJ_CNT 0x0138
46#define PIN_OE_CTRL 0x013C
47#define PIN_SPD_CTRL 0x0140
48#define PIN_SPD_CTRL2 0x0144
49#define IRQ_STAT_CTRL 0x0148
50#define POWER_CTRL_AB 0x014C
51#define POWER_CTRL_CD 0x0150
52#define POWER_CTRL_EF 0x0154
53#define POWER_CTRL_GH 0x0158
54#define TUNE_CTRL 0x015C
55#define BIAS_CTRL 0x0160
56#define AFE_AB_DIAG_CTRL 0x0164
57#define AFE_CD_DIAG_CTRL 0x0168
58#define AFE_EF_DIAG_CTRL 0x016C
59#define AFE_GH_DIAG_CTRL 0x0170
60#define PLL_AB_DIAG_CTRL 0x0174
61#define PLL_CD_DIAG_CTRL 0x0178
62#define PLL_EF_DIAG_CTRL 0x017C
63#define PLL_GH_DIAG_CTRL 0x0180
64#define TEST_CTRL 0x0184
65#define BIST_STAT 0x0188
66#define BIST_STAT2 0x018C
67#define BIST_VID_PLL_AB_STAT 0x0190
68#define BIST_VID_PLL_CD_STAT 0x0194
69#define BIST_VID_PLL_EF_STAT 0x0198
70#define BIST_VID_PLL_GH_STAT 0x019C
71#define DLL_DIAG_CTRL 0x01A0
72#define DEV_CH_ID_CTRL 0x01A4
73#define ABIST_CTRL_STATUS 0x01A8
74#define ABIST_FREQ 0x01AC
75#define ABIST_GOERT_SHIFT 0x01B0
76#define ABIST_COEF12 0x01B4
77#define ABIST_COEF34 0x01B8
78#define ABIST_COEF56 0x01BC
79#define ABIST_COEF7_SNR 0x01C0
80#define ABIST_ADC_CAL 0x01C4
81#define ABIST_BIN1_VGA0 0x01C8
82#define ABIST_BIN2_VGA1 0x01CC
83#define ABIST_BIN3_VGA2 0x01D0
84#define ABIST_BIN4_VGA3 0x01D4
85#define ABIST_BIN5_VGA4 0x01D8
86#define ABIST_BIN6_VGA5 0x01DC
87#define ABIST_BIN7_VGA6 0x0x1E0
88#define ABIST_CLAMP_A 0x0x1E4
89#define ABIST_CLAMP_B 0x0x1E8
90#define ABIST_CLAMP_C 0x01EC
91#define ABIST_CLAMP_D 0x01F0
92#define ABIST_CLAMP_E 0x01F4
93#define ABIST_CLAMP_F 0x01F8
94
95// Digital Video Encoder A Registers
96#define DENC_A_REG_1 0x0200
97#define DENC_A_REG_2 0x0204
98#define DENC_A_REG_3 0x0208
99#define DENC_A_REG_4 0x020C
100#define DENC_A_REG_5 0x0210
101#define DENC_A_REG_6 0x0214
102#define DENC_A_REG_7 0x0218
103#define DENC_A_REG_8 0x021C
104
105// Digital Video Encoder B Registers
106#define DENC_B_REG_1 0x0300
107#define DENC_B_REG_2 0x0304
108#define DENC_B_REG_3 0x0308
109#define DENC_B_REG_4 0x030C
110#define DENC_B_REG_5 0x0310
111#define DENC_B_REG_6 0x0314
112#define DENC_B_REG_7 0x0318
113#define DENC_B_REG_8 0x031C
114
115// Video Decoder A Registers
116#define MODE_CTRL 0x1000
117#define OUT_CTRL1 0x1004
118#define OUT_CTRL_NS 0x1008
119#define GEN_STAT 0x100C
120#define INT_STAT_MASK 0x1010
121#define LUMA_CTRL 0x1014
122#define CHROMA_CTRL 0x1018
123#define CRUSH_CTRL 0x101C
124#define HORIZ_TIM_CTRL 0x1020
125#define VERT_TIM_CTRL 0x1024
126#define MISC_TIM_CTRL 0x1028
127#define FIELD_COUNT 0x102C
128#define HSCALE_CTRL 0x1030
129#define VSCALE_CTRL 0x1034
130#define MAN_VGA_CTRL 0x1038
131#define MAN_AGC_CTRL 0x103C
132#define DFE_CTRL1 0x1040
133#define DFE_CTRL2 0x1044
134#define DFE_CTRL3 0x1048
135#define PLL_CTRL 0x104C
136#define PLL_CTRL_FAST 0x1050
137#define HTL_CTRL 0x1054
138#define SRC_CFG 0x1058
139#define SC_STEP_SIZE 0x105C
140#define SC_CONVERGE_CTRL 0x1060
141#define SC_LOOP_CTRL 0x1064
142#define COMB_2D_HFS_CFG 0x1068
143#define COMB_2D_HFD_CFG 0x106C
144#define COMB_2D_LF_CFG 0x1070
145#define COMB_2D_BLEND 0x1074
146#define COMB_MISC_CTRL 0x1078
147#define COMB_FLAT_THRESH_CTRL 0x107C
148#define COMB_TEST 0x1080
149#define BP_MISC_CTRL 0x1084
150#define VCR_DET_CTRL 0x1088
151#define NOISE_DET_CTRL 0x108C
152#define COMB_FLAT_NOISE_CTRL 0x1090
153#define VERSION 0x11F8
154#define SOFT_RST_CTRL 0x11FC
155
156// Video Decoder B Registers
157#define VDEC_B_MODE_CTRL 0x1200
158#define VDEC_B_OUT_CTRL1 0x1204
159#define VDEC_B_OUT_CTRL_NS 0x1208
160#define VDEC_B_GEN_STAT 0x120C
161#define VDEC_B_INT_STAT_MASK 0x1210
162#define VDEC_B_LUMA_CTRL 0x1214
163#define VDEC_B_CHROMA_CTRL 0x1218
164#define VDEC_B_CRUSH_CTRL 0x121C
165#define VDEC_B_HORIZ_TIM_CTRL 0x1220
166#define VDEC_B_VERT_TIM_CTRL 0x1224
167#define VDEC_B_MISC_TIM_CTRL 0x1228
168#define VDEC_B_FIELD_COUNT 0x122C
169#define VDEC_B_HSCALE_CTRL 0x1230
170#define VDEC_B_VSCALE_CTRL 0x1234
171#define VDEC_B_MAN_VGA_CTRL 0x1238
172#define VDEC_B_MAN_AGC_CTRL 0x123C
173#define VDEC_B_DFE_CTRL1 0x1240
174#define VDEC_B_DFE_CTRL2 0x1244
175#define VDEC_B_DFE_CTRL3 0x1248
176#define VDEC_B_PLL_CTRL 0x124C
177#define VDEC_B_PLL_CTRL_FAST 0x1250
178#define VDEC_B_HTL_CTRL 0x1254
179#define VDEC_B_SRC_CFG 0x1258
180#define VDEC_B_SC_STEP_SIZE 0x125C
181#define VDEC_B_SC_CONVERGE_CTRL 0x1260
182#define VDEC_B_SC_LOOP_CTRL 0x1264
183#define VDEC_B_COMB_2D_HFS_CFG 0x1268
184#define VDEC_B_COMB_2D_HFD_CFG 0x126C
185#define VDEC_B_COMB_2D_LF_CFG 0x1270
186#define VDEC_B_COMB_2D_BLEND 0x1274
187#define VDEC_B_COMB_MISC_CTRL 0x1278
188#define VDEC_B_COMB_FLAT_THRESH_CTRL 0x127C
189#define VDEC_B_COMB_TEST 0x1280
190#define VDEC_B_BP_MISC_CTRL 0x1284
191#define VDEC_B_VCR_DET_CTRL 0x1288
192#define VDEC_B_NOISE_DET_CTRL 0x128C
193#define VDEC_B_COMB_FLAT_NOISE_CTRL 0x1290
194#define VDEC_B_VERSION 0x13F8
195#define VDEC_B_SOFT_RST_CTRL 0x13FC
196
197// Video Decoder C Registers
198#define VDEC_C_MODE_CTRL 0x1400
199#define VDEC_C_OUT_CTRL1 0x1404
200#define VDEC_C_OUT_CTRL_NS 0x1408
201#define VDEC_C_GEN_STAT 0x140C
202#define VDEC_C_INT_STAT_MASK 0x1410
203#define VDEC_C_LUMA_CTRL 0x1414
204#define VDEC_C_CHROMA_CTRL 0x1418
205#define VDEC_C_CRUSH_CTRL 0x141C
206#define VDEC_C_HORIZ_TIM_CTRL 0x1420
207#define VDEC_C_VERT_TIM_CTRL 0x1424
208#define VDEC_C_MISC_TIM_CTRL 0x1428
209#define VDEC_C_FIELD_COUNT 0x142C
210#define VDEC_C_HSCALE_CTRL 0x1430
211#define VDEC_C_VSCALE_CTRL 0x1434
212#define VDEC_C_MAN_VGA_CTRL 0x1438
213#define VDEC_C_MAN_AGC_CTRL 0x143C
214#define VDEC_C_DFE_CTRL1 0x1440
215#define VDEC_C_DFE_CTRL2 0x1444
216#define VDEC_C_DFE_CTRL3 0x1448
217#define VDEC_C_PLL_CTRL 0x144C
218#define VDEC_C_PLL_CTRL_FAST 0x1450
219#define VDEC_C_HTL_CTRL 0x1454
220#define VDEC_C_SRC_CFG 0x1458
221#define VDEC_C_SC_STEP_SIZE 0x145C
222#define VDEC_C_SC_CONVERGE_CTRL 0x1460
223#define VDEC_C_SC_LOOP_CTRL 0x1464
224#define VDEC_C_COMB_2D_HFS_CFG 0x1468
225#define VDEC_C_COMB_2D_HFD_CFG 0x146C
226#define VDEC_C_COMB_2D_LF_CFG 0x1470
227#define VDEC_C_COMB_2D_BLEND 0x1474
228#define VDEC_C_COMB_MISC_CTRL 0x1478
229#define VDEC_C_COMB_FLAT_THRESH_CTRL 0x147C
230#define VDEC_C_COMB_TEST 0x1480
231#define VDEC_C_BP_MISC_CTRL 0x1484
232#define VDEC_C_VCR_DET_CTRL 0x1488
233#define VDEC_C_NOISE_DET_CTRL 0x148C
234#define VDEC_C_COMB_FLAT_NOISE_CTRL 0x1490
235#define VDEC_C_VERSION 0x15F8
236#define VDEC_C_SOFT_RST_CTRL 0x15FC
237
238// Video Decoder D Registers
239#define VDEC_D_MODE_CTRL 0x1600
240#define VDEC_D_OUT_CTRL1 0x1604
241#define VDEC_D_OUT_CTRL_NS 0x1608
242#define VDEC_D_GEN_STAT 0x160C
243#define VDEC_D_INT_STAT_MASK 0x1610
244#define VDEC_D_LUMA_CTRL 0x1614
245#define VDEC_D_CHROMA_CTRL 0x1618
246#define VDEC_D_CRUSH_CTRL 0x161C
247#define VDEC_D_HORIZ_TIM_CTRL 0x1620
248#define VDEC_D_VERT_TIM_CTRL 0x1624
249#define VDEC_D_MISC_TIM_CTRL 0x1628
250#define VDEC_D_FIELD_COUNT 0x162C
251#define VDEC_D_HSCALE_CTRL 0x1630
252#define VDEC_D_VSCALE_CTRL 0x1634
253#define VDEC_D_MAN_VGA_CTRL 0x1638
254#define VDEC_D_MAN_AGC_CTRL 0x163C
255#define VDEC_D_DFE_CTRL1 0x1640
256#define VDEC_D_DFE_CTRL2 0x1644
257#define VDEC_D_DFE_CTRL3 0x1648
258#define VDEC_D_PLL_CTRL 0x164C
259#define VDEC_D_PLL_CTRL_FAST 0x1650
260#define VDEC_D_HTL_CTRL 0x1654
261#define VDEC_D_SRC_CFG 0x1658
262#define VDEC_D_SC_STEP_SIZE 0x165C
263#define VDEC_D_SC_CONVERGE_CTRL 0x1660
264#define VDEC_D_SC_LOOP_CTRL 0x1664
265#define VDEC_D_COMB_2D_HFS_CFG 0x1668
266#define VDEC_D_COMB_2D_HFD_CFG 0x166C
267#define VDEC_D_COMB_2D_LF_CFG 0x1670
268#define VDEC_D_COMB_2D_BLEND 0x1674
269#define VDEC_D_COMB_MISC_CTRL 0x1678
270#define VDEC_D_COMB_FLAT_THRESH_CTRL 0x167C
271#define VDEC_D_COMB_TEST 0x1680
272#define VDEC_D_BP_MISC_CTRL 0x1684
273#define VDEC_D_VCR_DET_CTRL 0x1688
274#define VDEC_D_NOISE_DET_CTRL 0x168C
275#define VDEC_D_COMB_FLAT_NOISE_CTRL 0x1690
276#define VDEC_D_VERSION 0x17F8
277#define VDEC_D_SOFT_RST_CTRL 0x17FC
278
279// Video Decoder E Registers
280#define VDEC_E_MODE_CTRL 0x1800
281#define VDEC_E_OUT_CTRL1 0x1804
282#define VDEC_E_OUT_CTRL_NS 0x1808
283#define VDEC_E_GEN_STAT 0x180C
284#define VDEC_E_INT_STAT_MASK 0x1810
285#define VDEC_E_LUMA_CTRL 0x1814
286#define VDEC_E_CHROMA_CTRL 0x1818
287#define VDEC_E_CRUSH_CTRL 0x181C
288#define VDEC_E_HORIZ_TIM_CTRL 0x1820
289#define VDEC_E_VERT_TIM_CTRL 0x1824
290#define VDEC_E_MISC_TIM_CTRL 0x1828
291#define VDEC_E_FIELD_COUNT 0x182C
292#define VDEC_E_HSCALE_CTRL 0x1830
293#define VDEC_E_VSCALE_CTRL 0x1834
294#define VDEC_E_MAN_VGA_CTRL 0x1838
295#define VDEC_E_MAN_AGC_CTRL 0x183C
296#define VDEC_E_DFE_CTRL1 0x1840
297#define VDEC_E_DFE_CTRL2 0x1844
298#define VDEC_E_DFE_CTRL3 0x1848
299#define VDEC_E_PLL_CTRL 0x184C
300#define VDEC_E_PLL_CTRL_FAST 0x1850
301#define VDEC_E_HTL_CTRL 0x1854
302#define VDEC_E_SRC_CFG 0x1858
303#define VDEC_E_SC_STEP_SIZE 0x185C
304#define VDEC_E_SC_CONVERGE_CTRL 0x1860
305#define VDEC_E_SC_LOOP_CTRL 0x1864
306#define VDEC_E_COMB_2D_HFS_CFG 0x1868
307#define VDEC_E_COMB_2D_HFD_CFG 0x186C
308#define VDEC_E_COMB_2D_LF_CFG 0x1870
309#define VDEC_E_COMB_2D_BLEND 0x1874
310#define VDEC_E_COMB_MISC_CTRL 0x1878
311#define VDEC_E_COMB_FLAT_THRESH_CTRL 0x187C
312#define VDEC_E_COMB_TEST 0x1880
313#define VDEC_E_BP_MISC_CTRL 0x1884
314#define VDEC_E_VCR_DET_CTRL 0x1888
315#define VDEC_E_NOISE_DET_CTRL 0x188C
316#define VDEC_E_COMB_FLAT_NOISE_CTRL 0x1890
317#define VDEC_E_VERSION 0x19F8
318#define VDEC_E_SOFT_RST_CTRL 0x19FC
319
320// Video Decoder F Registers
321#define VDEC_F_MODE_CTRL 0x1A00
322#define VDEC_F_OUT_CTRL1 0x1A04
323#define VDEC_F_OUT_CTRL_NS 0x1A08
324#define VDEC_F_GEN_STAT 0x1A0C
325#define VDEC_F_INT_STAT_MASK 0x1A10
326#define VDEC_F_LUMA_CTRL 0x1A14
327#define VDEC_F_CHROMA_CTRL 0x1A18
328#define VDEC_F_CRUSH_CTRL 0x1A1C
329#define VDEC_F_HORIZ_TIM_CTRL 0x1A20
330#define VDEC_F_VERT_TIM_CTRL 0x1A24
331#define VDEC_F_MISC_TIM_CTRL 0x1A28
332#define VDEC_F_FIELD_COUNT 0x1A2C
333#define VDEC_F_HSCALE_CTRL 0x1A30
334#define VDEC_F_VSCALE_CTRL 0x1A34
335#define VDEC_F_MAN_VGA_CTRL 0x1A38
336#define VDEC_F_MAN_AGC_CTRL 0x1A3C
337#define VDEC_F_DFE_CTRL1 0x1A40
338#define VDEC_F_DFE_CTRL2 0x1A44
339#define VDEC_F_DFE_CTRL3 0x1A48
340#define VDEC_F_PLL_CTRL 0x1A4C
341#define VDEC_F_PLL_CTRL_FAST 0x1A50
342#define VDEC_F_HTL_CTRL 0x1A54
343#define VDEC_F_SRC_CFG 0x1A58
344#define VDEC_F_SC_STEP_SIZE 0x1A5C
345#define VDEC_F_SC_CONVERGE_CTRL 0x1A60
346#define VDEC_F_SC_LOOP_CTRL 0x1A64
347#define VDEC_F_COMB_2D_HFS_CFG 0x1A68
348#define VDEC_F_COMB_2D_HFD_CFG 0x1A6C
349#define VDEC_F_COMB_2D_LF_CFG 0x1A70
350#define VDEC_F_COMB_2D_BLEND 0x1A74
351#define VDEC_F_COMB_MISC_CTRL 0x1A78
352#define VDEC_F_COMB_FLAT_THRESH_CTRL 0x1A7C
353#define VDEC_F_COMB_TEST 0x1A80
354#define VDEC_F_BP_MISC_CTRL 0x1A84
355#define VDEC_F_VCR_DET_CTRL 0x1A88
356#define VDEC_F_NOISE_DET_CTRL 0x1A8C
357#define VDEC_F_COMB_FLAT_NOISE_CTRL 0x1A90
358#define VDEC_F_VERSION 0x1BF8
359#define VDEC_F_SOFT_RST_CTRL 0x1BFC
360
361// Video Decoder G Registers
362#define VDEC_G_MODE_CTRL 0x1C00
363#define VDEC_G_OUT_CTRL1 0x1C04
364#define VDEC_G_OUT_CTRL_NS 0x1C08
365#define VDEC_G_GEN_STAT 0x1C0C
366#define VDEC_G_INT_STAT_MASK 0x1C10
367#define VDEC_G_LUMA_CTRL 0x1C14
368#define VDEC_G_CHROMA_CTRL 0x1C18
369#define VDEC_G_CRUSH_CTRL 0x1C1C
370#define VDEC_G_HORIZ_TIM_CTRL 0x1C20
371#define VDEC_G_VERT_TIM_CTRL 0x1C24
372#define VDEC_G_MISC_TIM_CTRL 0x1C28
373#define VDEC_G_FIELD_COUNT 0x1C2C
374#define VDEC_G_HSCALE_CTRL 0x1C30
375#define VDEC_G_VSCALE_CTRL 0x1C34
376#define VDEC_G_MAN_VGA_CTRL 0x1C38
377#define VDEC_G_MAN_AGC_CTRL 0x1C3C
378#define VDEC_G_DFE_CTRL1 0x1C40
379#define VDEC_G_DFE_CTRL2 0x1C44
380#define VDEC_G_DFE_CTRL3 0x1C48
381#define VDEC_G_PLL_CTRL 0x1C4C
382#define VDEC_G_PLL_CTRL_FAST 0x1C50
383#define VDEC_G_HTL_CTRL 0x1C54
384#define VDEC_G_SRC_CFG 0x1C58
385#define VDEC_G_SC_STEP_SIZE 0x1C5C
386#define VDEC_G_SC_CONVERGE_CTRL 0x1C60
387#define VDEC_G_SC_LOOP_CTRL 0x1C64
388#define VDEC_G_COMB_2D_HFS_CFG 0x1C68
389#define VDEC_G_COMB_2D_HFD_CFG 0x1C6C
390#define VDEC_G_COMB_2D_LF_CFG 0x1C70
391#define VDEC_G_COMB_2D_BLEND 0x1C74
392#define VDEC_G_COMB_MISC_CTRL 0x1C78
393#define VDEC_G_COMB_FLAT_THRESH_CTRL 0x1C7C
394#define VDEC_G_COMB_TEST 0x1C80
395#define VDEC_G_BP_MISC_CTRL 0x1C84
396#define VDEC_G_VCR_DET_CTRL 0x1C88
397#define VDEC_G_NOISE_DET_CTRL 0x1C8C
398#define VDEC_G_COMB_FLAT_NOISE_CTRL 0x1C90
399#define VDEC_G_VERSION 0x1DF8
400#define VDEC_G_SOFT_RST_CTRL 0x1DFC
401
402// Video Decoder H Registers
403#define VDEC_H_MODE_CTRL 0x1E00
404#define VDEC_H_OUT_CTRL1 0x1E04
405#define VDEC_H_OUT_CTRL_NS 0x1E08
406#define VDEC_H_GEN_STAT 0x1E0C
407#define VDEC_H_INT_STAT_MASK 0x1E1E
408#define VDEC_H_LUMA_CTRL 0x1E14
409#define VDEC_H_CHROMA_CTRL 0x1E18
410#define VDEC_H_CRUSH_CTRL 0x1E1C
411#define VDEC_H_HORIZ_TIM_CTRL 0x1E20
412#define VDEC_H_VERT_TIM_CTRL 0x1E24
413#define VDEC_H_MISC_TIM_CTRL 0x1E28
414#define VDEC_H_FIELD_COUNT 0x1E2C
415#define VDEC_H_HSCALE_CTRL 0x1E30
416#define VDEC_H_VSCALE_CTRL 0x1E34
417#define VDEC_H_MAN_VGA_CTRL 0x1E38
418#define VDEC_H_MAN_AGC_CTRL 0x1E3C
419#define VDEC_H_DFE_CTRL1 0x1E40
420#define VDEC_H_DFE_CTRL2 0x1E44
421#define VDEC_H_DFE_CTRL3 0x1E48
422#define VDEC_H_PLL_CTRL 0x1E4C
423#define VDEC_H_PLL_CTRL_FAST 0x1E50
424#define VDEC_H_HTL_CTRL 0x1E54
425#define VDEC_H_SRC_CFG 0x1E58
426#define VDEC_H_SC_STEP_SIZE 0x1E5C
427#define VDEC_H_SC_CONVERGE_CTRL 0x1E60
428#define VDEC_H_SC_LOOP_CTRL 0x1E64
429#define VDEC_H_COMB_2D_HFS_CFG 0x1E68
430#define VDEC_H_COMB_2D_HFD_CFG 0x1E6C
431#define VDEC_H_COMB_2D_LF_CFG 0x1E70
432#define VDEC_H_COMB_2D_BLEND 0x1E74
433#define VDEC_H_COMB_MISC_CTRL 0x1E78
434#define VDEC_H_COMB_FLAT_THRESH_CTRL 0x1E7C
435#define VDEC_H_COMB_TEST 0x1E80
436#define VDEC_H_BP_MISC_CTRL 0x1E84
437#define VDEC_H_VCR_DET_CTRL 0x1E88
438#define VDEC_H_NOISE_DET_CTRL 0x1E8C
439#define VDEC_H_COMB_FLAT_NOISE_CTRL 0x1E90
440#define VDEC_H_VERSION 0x1FF8
441#define VDEC_H_SOFT_RST_CTRL 0x1FFC
442
443//*****************************************************************************
444// LUMA_CTRL register fields
445#define VDEC_A_BRITE_CTRL 0x1014
446#define VDEC_A_CNTRST_CTRL 0x1015
447#define VDEC_A_PEAK_SEL 0x1016
448
449//*****************************************************************************
450// CHROMA_CTRL register fields
451#define VDEC_A_USAT_CTRL 0x1018
452#define VDEC_A_VSAT_CTRL 0x1019
453#define VDEC_A_HUE_CTRL 0x101A
454
455#endif
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/staging/cx25821/cx25821-medusa-video.c
new file mode 100644
index 000000000000..e4df8134f059
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.c
@@ -0,0 +1,869 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821.h"
24#include "cx25821-medusa-video.h"
25#include "cx25821-biffuncs.h"
26
27/////////////////////////////////////////////////////////////////////////////////////////
28//medusa_enable_bluefield_output()
29//
30// Enable the generation of blue filed output if no video
31//
32static void medusa_enable_bluefield_output(struct cx25821_dev *dev, int channel,
33 int enable)
34{
35 int ret_val = 1;
36 u32 value = 0;
37 u32 tmp = 0;
38 int out_ctrl = OUT_CTRL1;
39 int out_ctrl_ns = OUT_CTRL_NS;
40
41 switch (channel) {
42 default:
43 case VDEC_A:
44 break;
45 case VDEC_B:
46 out_ctrl = VDEC_B_OUT_CTRL1;
47 out_ctrl_ns = VDEC_B_OUT_CTRL_NS;
48 break;
49 case VDEC_C:
50 out_ctrl = VDEC_C_OUT_CTRL1;
51 out_ctrl_ns = VDEC_C_OUT_CTRL_NS;
52 break;
53 case VDEC_D:
54 out_ctrl = VDEC_D_OUT_CTRL1;
55 out_ctrl_ns = VDEC_D_OUT_CTRL_NS;
56 break;
57 case VDEC_E:
58 out_ctrl = VDEC_E_OUT_CTRL1;
59 out_ctrl_ns = VDEC_E_OUT_CTRL_NS;
60 return;
61 case VDEC_F:
62 out_ctrl = VDEC_F_OUT_CTRL1;
63 out_ctrl_ns = VDEC_F_OUT_CTRL_NS;
64 return;
65 case VDEC_G:
66 out_ctrl = VDEC_G_OUT_CTRL1;
67 out_ctrl_ns = VDEC_G_OUT_CTRL_NS;
68 return;
69 case VDEC_H:
70 out_ctrl = VDEC_H_OUT_CTRL1;
71 out_ctrl_ns = VDEC_H_OUT_CTRL_NS;
72 return;
73 }
74
75 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl, &tmp);
76 value &= 0xFFFFFF7F; // clear BLUE_FIELD_EN
77 if (enable)
78 value |= 0x00000080; // set BLUE_FIELD_EN
79 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl, value);
80
81 value = cx25821_i2c_read(&dev->i2c_bus[0], out_ctrl_ns, &tmp);
82 value &= 0xFFFFFF7F;
83 if (enable)
84 value |= 0x00000080; // set BLUE_FIELD_EN
85 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], out_ctrl_ns, value);
86}
87
88static int medusa_initialize_ntsc(struct cx25821_dev *dev)
89{
90 int ret_val = 0;
91 int i = 0;
92 u32 value = 0;
93 u32 tmp = 0;
94
95 mutex_lock(&dev->lock);
96
97 for (i = 0; i < MAX_DECODERS; i++) {
98 // set video format NTSC-M
99 value =
100 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
101 &tmp);
102 value &= 0xFFFFFFF0;
103 value |= 0x10001; // enable the fast locking mode bit[16]
104 ret_val =
105 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
106 value);
107
108 // resolution NTSC 720x480
109 value =
110 cx25821_i2c_read(&dev->i2c_bus[0],
111 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
112 value &= 0x00C00C00;
113 value |= 0x612D0074;
114 ret_val =
115 cx25821_i2c_write(&dev->i2c_bus[0],
116 HORIZ_TIM_CTRL + (0x200 * i), value);
117
118 value =
119 cx25821_i2c_read(&dev->i2c_bus[0],
120 VERT_TIM_CTRL + (0x200 * i), &tmp);
121 value &= 0x00C00C00;
122 value |= 0x1C1E001A; // vblank_cnt + 2 to get camera ID
123 ret_val =
124 cx25821_i2c_write(&dev->i2c_bus[0],
125 VERT_TIM_CTRL + (0x200 * i), value);
126
127 // chroma subcarrier step size
128 ret_val =
129 cx25821_i2c_write(&dev->i2c_bus[0],
130 SC_STEP_SIZE + (0x200 * i), 0x43E00000);
131
132 // enable VIP optional active
133 value =
134 cx25821_i2c_read(&dev->i2c_bus[0],
135 OUT_CTRL_NS + (0x200 * i), &tmp);
136 value &= 0xFFFBFFFF;
137 value |= 0x00040000;
138 ret_val =
139 cx25821_i2c_write(&dev->i2c_bus[0],
140 OUT_CTRL_NS + (0x200 * i), value);
141
142 // enable VIP optional active (VIP_OPT_AL) for direct output.
143 value =
144 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
145 &tmp);
146 value &= 0xFFFBFFFF;
147 value |= 0x00040000;
148 ret_val =
149 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
150 value);
151
152 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
153 // when the input switching rate < 16 fields
154 //
155 value =
156 cx25821_i2c_read(&dev->i2c_bus[0],
157 MISC_TIM_CTRL + (0x200 * i), &tmp);
158 value = setBitAtPos(value, 14); // disable special play detection
159 value = clearBitAtPos(value, 15);
160 ret_val =
161 cx25821_i2c_write(&dev->i2c_bus[0],
162 MISC_TIM_CTRL + (0x200 * i), value);
163
164 // set vbi_gate_en to 0
165 value =
166 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
167 &tmp);
168 value = clearBitAtPos(value, 29);
169 ret_val =
170 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
171 value);
172
173 // Enable the generation of blue field output if no video
174 medusa_enable_bluefield_output(dev, i, 1);
175 }
176
177 for (i = 0; i < MAX_ENCODERS; i++) {
178 // NTSC hclock
179 value =
180 cx25821_i2c_read(&dev->i2c_bus[0],
181 DENC_A_REG_1 + (0x100 * i), &tmp);
182 value &= 0xF000FC00;
183 value |= 0x06B402D0;
184 ret_val =
185 cx25821_i2c_write(&dev->i2c_bus[0],
186 DENC_A_REG_1 + (0x100 * i), value);
187
188 // burst begin and burst end
189 value =
190 cx25821_i2c_read(&dev->i2c_bus[0],
191 DENC_A_REG_2 + (0x100 * i), &tmp);
192 value &= 0xFF000000;
193 value |= 0x007E9054;
194 ret_val =
195 cx25821_i2c_write(&dev->i2c_bus[0],
196 DENC_A_REG_2 + (0x100 * i), value);
197
198 value =
199 cx25821_i2c_read(&dev->i2c_bus[0],
200 DENC_A_REG_3 + (0x100 * i), &tmp);
201 value &= 0xFC00FE00;
202 value |= 0x00EC00F0;
203 ret_val =
204 cx25821_i2c_write(&dev->i2c_bus[0],
205 DENC_A_REG_3 + (0x100 * i), value);
206
207 // set NTSC vblank, no phase alternation, 7.5 IRE pedestal
208 value =
209 cx25821_i2c_read(&dev->i2c_bus[0],
210 DENC_A_REG_4 + (0x100 * i), &tmp);
211 value &= 0x00FCFFFF;
212 value |= 0x13020000;
213 ret_val =
214 cx25821_i2c_write(&dev->i2c_bus[0],
215 DENC_A_REG_4 + (0x100 * i), value);
216
217 value =
218 cx25821_i2c_read(&dev->i2c_bus[0],
219 DENC_A_REG_5 + (0x100 * i), &tmp);
220 value &= 0xFFFF0000;
221 value |= 0x0000E575;
222 ret_val =
223 cx25821_i2c_write(&dev->i2c_bus[0],
224 DENC_A_REG_5 + (0x100 * i), value);
225
226 ret_val =
227 cx25821_i2c_write(&dev->i2c_bus[0],
228 DENC_A_REG_6 + (0x100 * i), 0x009A89C1);
229
230 // Subcarrier Increment
231 ret_val =
232 cx25821_i2c_write(&dev->i2c_bus[0],
233 DENC_A_REG_7 + (0x100 * i), 0x21F07C1F);
234 }
235
236 //set picture resolutions
237 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
238 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 480
239
240 // set Bypass input format to NTSC 525 lines
241 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
242 value |= 0x00080200;
243 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
244
245 mutex_unlock(&dev->lock);
246
247 return ret_val;
248}
249
250static int medusa_PALCombInit(struct cx25821_dev *dev, int dec)
251{
252 int ret_val = -1;
253 u32 value = 0, tmp = 0;
254
255 // Setup for 2D threshold
256 ret_val =
257 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFS_CFG + (0x200 * dec),
258 0x20002861);
259 ret_val =
260 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_HFD_CFG + (0x200 * dec),
261 0x20002861);
262 ret_val =
263 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_LF_CFG + (0x200 * dec),
264 0x200A1023);
265
266 // Setup flat chroma and luma thresholds
267 value =
268 cx25821_i2c_read(&dev->i2c_bus[0],
269 COMB_FLAT_THRESH_CTRL + (0x200 * dec), &tmp);
270 value &= 0x06230000;
271 ret_val =
272 cx25821_i2c_write(&dev->i2c_bus[0],
273 COMB_FLAT_THRESH_CTRL + (0x200 * dec), value);
274
275 // set comb 2D blend
276 ret_val =
277 cx25821_i2c_write(&dev->i2c_bus[0], COMB_2D_BLEND + (0x200 * dec),
278 0x210F0F0F);
279
280 // COMB MISC CONTROL
281 ret_val =
282 cx25821_i2c_write(&dev->i2c_bus[0], COMB_MISC_CTRL + (0x200 * dec),
283 0x41120A7F);
284
285 return ret_val;
286}
287
288static int medusa_initialize_pal(struct cx25821_dev *dev)
289{
290 int ret_val = 0;
291 int i = 0;
292 u32 value = 0;
293 u32 tmp = 0;
294
295 mutex_lock(&dev->lock);
296
297 for (i = 0; i < MAX_DECODERS; i++) {
298 // set video format PAL-BDGHI
299 value =
300 cx25821_i2c_read(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
301 &tmp);
302 value &= 0xFFFFFFF0;
303 value |= 0x10004; // enable the fast locking mode bit[16]
304 ret_val =
305 cx25821_i2c_write(&dev->i2c_bus[0], MODE_CTRL + (0x200 * i),
306 value);
307
308 // resolution PAL 720x576
309 value =
310 cx25821_i2c_read(&dev->i2c_bus[0],
311 HORIZ_TIM_CTRL + (0x200 * i), &tmp);
312 value &= 0x00C00C00;
313 value |= 0x632D007D;
314 ret_val =
315 cx25821_i2c_write(&dev->i2c_bus[0],
316 HORIZ_TIM_CTRL + (0x200 * i), value);
317
318 // vblank656_cnt=x26, vactive_cnt=240h, vblank_cnt=x24
319 value =
320 cx25821_i2c_read(&dev->i2c_bus[0],
321 VERT_TIM_CTRL + (0x200 * i), &tmp);
322 value &= 0x00C00C00;
323 value |= 0x28240026; // vblank_cnt + 2 to get camera ID
324 ret_val =
325 cx25821_i2c_write(&dev->i2c_bus[0],
326 VERT_TIM_CTRL + (0x200 * i), value);
327
328 // chroma subcarrier step size
329 ret_val =
330 cx25821_i2c_write(&dev->i2c_bus[0],
331 SC_STEP_SIZE + (0x200 * i), 0x5411E2D0);
332
333 // enable VIP optional active
334 value =
335 cx25821_i2c_read(&dev->i2c_bus[0],
336 OUT_CTRL_NS + (0x200 * i), &tmp);
337 value &= 0xFFFBFFFF;
338 value |= 0x00040000;
339 ret_val =
340 cx25821_i2c_write(&dev->i2c_bus[0],
341 OUT_CTRL_NS + (0x200 * i), value);
342
343 // enable VIP optional active (VIP_OPT_AL) for direct output.
344 value =
345 cx25821_i2c_read(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
346 &tmp);
347 value &= 0xFFFBFFFF;
348 value |= 0x00040000;
349 ret_val =
350 cx25821_i2c_write(&dev->i2c_bus[0], OUT_CTRL1 + (0x200 * i),
351 value);
352
353 // clear VPRES_VERT_EN bit, fixes the chroma run away problem
354 // when the input switching rate < 16 fields
355 value =
356 cx25821_i2c_read(&dev->i2c_bus[0],
357 MISC_TIM_CTRL + (0x200 * i), &tmp);
358 value = setBitAtPos(value, 14); // disable special play detection
359 value = clearBitAtPos(value, 15);
360 ret_val =
361 cx25821_i2c_write(&dev->i2c_bus[0],
362 MISC_TIM_CTRL + (0x200 * i), value);
363
364 // set vbi_gate_en to 0
365 value =
366 cx25821_i2c_read(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
367 &tmp);
368 value = clearBitAtPos(value, 29);
369 ret_val =
370 cx25821_i2c_write(&dev->i2c_bus[0], DFE_CTRL1 + (0x200 * i),
371 value);
372
373 medusa_PALCombInit(dev, i);
374
375 // Enable the generation of blue field output if no video
376 medusa_enable_bluefield_output(dev, i, 1);
377 }
378
379 for (i = 0; i < MAX_ENCODERS; i++) {
380 // PAL hclock
381 value =
382 cx25821_i2c_read(&dev->i2c_bus[0],
383 DENC_A_REG_1 + (0x100 * i), &tmp);
384 value &= 0xF000FC00;
385 value |= 0x06C002D0;
386 ret_val =
387 cx25821_i2c_write(&dev->i2c_bus[0],
388 DENC_A_REG_1 + (0x100 * i), value);
389
390 // burst begin and burst end
391 value =
392 cx25821_i2c_read(&dev->i2c_bus[0],
393 DENC_A_REG_2 + (0x100 * i), &tmp);
394 value &= 0xFF000000;
395 value |= 0x007E9754;
396 ret_val =
397 cx25821_i2c_write(&dev->i2c_bus[0],
398 DENC_A_REG_2 + (0x100 * i), value);
399
400 // hblank and vactive
401 value =
402 cx25821_i2c_read(&dev->i2c_bus[0],
403 DENC_A_REG_3 + (0x100 * i), &tmp);
404 value &= 0xFC00FE00;
405 value |= 0x00FC0120;
406 ret_val =
407 cx25821_i2c_write(&dev->i2c_bus[0],
408 DENC_A_REG_3 + (0x100 * i), value);
409
410 // set PAL vblank, phase alternation, 0 IRE pedestal
411 value =
412 cx25821_i2c_read(&dev->i2c_bus[0],
413 DENC_A_REG_4 + (0x100 * i), &tmp);
414 value &= 0x00FCFFFF;
415 value |= 0x14010000;
416 ret_val =
417 cx25821_i2c_write(&dev->i2c_bus[0],
418 DENC_A_REG_4 + (0x100 * i), value);
419
420 value =
421 cx25821_i2c_read(&dev->i2c_bus[0],
422 DENC_A_REG_5 + (0x100 * i), &tmp);
423 value &= 0xFFFF0000;
424 value |= 0x0000F078;
425 ret_val =
426 cx25821_i2c_write(&dev->i2c_bus[0],
427 DENC_A_REG_5 + (0x100 * i), value);
428
429 ret_val =
430 cx25821_i2c_write(&dev->i2c_bus[0],
431 DENC_A_REG_6 + (0x100 * i), 0x00A493CF);
432
433 // Subcarrier Increment
434 ret_val =
435 cx25821_i2c_write(&dev->i2c_bus[0],
436 DENC_A_REG_7 + (0x100 * i), 0x2A098ACB);
437 }
438
439 //set picture resolutions
440 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], HSCALE_CTRL, 0x0); //0 - 720
441 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], VSCALE_CTRL, 0x0); //0 - 576
442
443 // set Bypass input format to PAL 625 lines
444 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
445 value &= 0xFFF7FDFF;
446 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
447
448 mutex_unlock(&dev->lock);
449
450 return ret_val;
451}
452
453int medusa_set_videostandard(struct cx25821_dev *dev)
454{
455 int status = STATUS_SUCCESS;
456 u32 value = 0, tmp = 0;
457
458 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK) {
459 status = medusa_initialize_pal(dev);
460 } else {
461 status = medusa_initialize_ntsc(dev);
462 }
463
464 // Enable DENC_A output
465 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_A_REG_4, &tmp);
466 value = setBitAtPos(value, 4);
467 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_A_REG_4, value);
468
469 // Enable DENC_B output
470 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_B_REG_4, &tmp);
471 value = setBitAtPos(value, 4);
472 status = cx25821_i2c_write(&dev->i2c_bus[0], DENC_B_REG_4, value);
473
474 return status;
475}
476
477void medusa_set_resolution(struct cx25821_dev *dev, int width,
478 int decoder_select)
479{
480 int decoder = 0;
481 int decoder_count = 0;
482 int ret_val = 0;
483 u32 hscale = 0x0;
484 u32 vscale = 0x0;
485 const int MAX_WIDTH = 720;
486
487 mutex_lock(&dev->lock);
488
489 // validate the width - cannot be negative
490 if (width > MAX_WIDTH) {
491 printk
492 ("cx25821 %s() : width %d > MAX_WIDTH %d ! resetting to MAX_WIDTH \n",
493 __func__, width, MAX_WIDTH);
494 width = MAX_WIDTH;
495 }
496
497 if (decoder_select <= 7 && decoder_select >= 0) {
498 decoder = decoder_select;
499 decoder_count = decoder_select + 1;
500 } else {
501 decoder = 0;
502 decoder_count = _num_decoders;
503 }
504
505 switch (width) {
506 case 320:
507 hscale = 0x13E34B;
508 vscale = 0x0;
509 break;
510
511 case 352:
512 hscale = 0x10A273;
513 vscale = 0x0;
514 break;
515
516 case 176:
517 hscale = 0x3115B2;
518 vscale = 0x1E00;
519 break;
520
521 case 160:
522 hscale = 0x378D84;
523 vscale = 0x1E00;
524 break;
525
526 default: //720
527 hscale = 0x0;
528 vscale = 0x0;
529 break;
530 }
531
532 for (; decoder < decoder_count; decoder++) {
533 // write scaling values for each decoder
534 ret_val =
535 cx25821_i2c_write(&dev->i2c_bus[0],
536 HSCALE_CTRL + (0x200 * decoder), hscale);
537 ret_val =
538 cx25821_i2c_write(&dev->i2c_bus[0],
539 VSCALE_CTRL + (0x200 * decoder), vscale);
540 }
541
542 mutex_unlock(&dev->lock);
543}
544
545static void medusa_set_decoderduration(struct cx25821_dev *dev, int decoder,
546 int duration)
547{
548 int ret_val = 0;
549 u32 fld_cnt = 0;
550 u32 tmp = 0;
551 u32 disp_cnt_reg = DISP_AB_CNT;
552
553 mutex_lock(&dev->lock);
554
555 // no support
556 if (decoder < VDEC_A && decoder > VDEC_H) {
557 mutex_unlock(&dev->lock);
558 return;
559 }
560
561 switch (decoder) {
562 default:
563 break;
564 case VDEC_C:
565 case VDEC_D:
566 disp_cnt_reg = DISP_CD_CNT;
567 break;
568 case VDEC_E:
569 case VDEC_F:
570 disp_cnt_reg = DISP_EF_CNT;
571 break;
572 case VDEC_G:
573 case VDEC_H:
574 disp_cnt_reg = DISP_GH_CNT;
575 break;
576 }
577
578 _display_field_cnt[decoder] = duration;
579
580 // update hardware
581 fld_cnt = cx25821_i2c_read(&dev->i2c_bus[0], disp_cnt_reg, &tmp);
582
583 if (!(decoder % 2)) // EVEN decoder
584 {
585 fld_cnt &= 0xFFFF0000;
586 fld_cnt |= duration;
587 } else {
588 fld_cnt &= 0x0000FFFF;
589 fld_cnt |= ((u32) duration) << 16;
590 }
591
592 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], disp_cnt_reg, fld_cnt);
593
594 mutex_unlock(&dev->lock);
595}
596
597/////////////////////////////////////////////////////////////////////////////////////////
598// Map to Medusa register setting
599static int mapM(int srcMin,
600 int srcMax, int srcVal, int dstMin, int dstMax, int *dstVal)
601{
602 int numerator;
603 int denominator;
604 int quotient;
605
606 if ((srcMin == srcMax) || (srcVal < srcMin) || (srcVal > srcMax)) {
607 return -1;
608 }
609 // This is the overall expression used:
610 // *dstVal = (srcVal - srcMin)*(dstMax - dstMin) / (srcMax - srcMin) + dstMin;
611 // but we need to account for rounding so below we use the modulus
612 // operator to find the remainder and increment if necessary.
613 numerator = (srcVal - srcMin) * (dstMax - dstMin);
614 denominator = srcMax - srcMin;
615 quotient = numerator / denominator;
616
617 if (2 * (numerator % denominator) >= denominator) {
618 quotient++;
619 }
620
621 *dstVal = quotient + dstMin;
622
623 return 0;
624}
625
626static unsigned long convert_to_twos(long numeric, unsigned long bits_len)
627{
628 unsigned char temp;
629
630 if (numeric >= 0)
631 return numeric;
632 else {
633 temp = ~(abs(numeric) & 0xFF);
634 temp += 1;
635 return temp;
636 }
637}
638
639/////////////////////////////////////////////////////////////////////////////////////////
640int medusa_set_brightness(struct cx25821_dev *dev, int brightness, int decoder)
641{
642 int ret_val = 0;
643 int value = 0;
644 u32 val = 0, tmp = 0;
645
646 mutex_lock(&dev->lock);
647 if ((brightness > VIDEO_PROCAMP_MAX)
648 || (brightness < VIDEO_PROCAMP_MIN)) {
649 mutex_unlock(&dev->lock);
650 return -1;
651 }
652 ret_val =
653 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, brightness,
654 SIGNED_BYTE_MIN, SIGNED_BYTE_MAX, &value);
655 value = convert_to_twos(value, 8);
656 val =
657 cx25821_i2c_read(&dev->i2c_bus[0],
658 VDEC_A_BRITE_CTRL + (0x200 * decoder), &tmp);
659 val &= 0xFFFFFF00;
660 ret_val |=
661 cx25821_i2c_write(&dev->i2c_bus[0],
662 VDEC_A_BRITE_CTRL + (0x200 * decoder),
663 val | value);
664 mutex_unlock(&dev->lock);
665 return ret_val;
666}
667
668/////////////////////////////////////////////////////////////////////////////////////////
669int medusa_set_contrast(struct cx25821_dev *dev, int contrast, int decoder)
670{
671 int ret_val = 0;
672 int value = 0;
673 u32 val = 0, tmp = 0;
674
675 mutex_lock(&dev->lock);
676
677 if ((contrast > VIDEO_PROCAMP_MAX) || (contrast < VIDEO_PROCAMP_MIN)) {
678 mutex_unlock(&dev->lock);
679 return -1;
680 }
681
682 ret_val =
683 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, contrast,
684 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
685 val =
686 cx25821_i2c_read(&dev->i2c_bus[0],
687 VDEC_A_CNTRST_CTRL + (0x200 * decoder), &tmp);
688 val &= 0xFFFFFF00;
689 ret_val |=
690 cx25821_i2c_write(&dev->i2c_bus[0],
691 VDEC_A_CNTRST_CTRL + (0x200 * decoder),
692 val | value);
693
694 mutex_unlock(&dev->lock);
695 return ret_val;
696}
697
698/////////////////////////////////////////////////////////////////////////////////////////
699int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder)
700{
701 int ret_val = 0;
702 int value = 0;
703 u32 val = 0, tmp = 0;
704
705 mutex_lock(&dev->lock);
706
707 if ((hue > VIDEO_PROCAMP_MAX) || (hue < VIDEO_PROCAMP_MIN)) {
708 mutex_unlock(&dev->lock);
709 return -1;
710 }
711
712 ret_val =
713 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, hue, SIGNED_BYTE_MIN,
714 SIGNED_BYTE_MAX, &value);
715
716 value = convert_to_twos(value, 8);
717 val =
718 cx25821_i2c_read(&dev->i2c_bus[0],
719 VDEC_A_HUE_CTRL + (0x200 * decoder), &tmp);
720 val &= 0xFFFFFF00;
721
722 ret_val |=
723 cx25821_i2c_write(&dev->i2c_bus[0],
724 VDEC_A_HUE_CTRL + (0x200 * decoder), val | value);
725
726 mutex_unlock(&dev->lock);
727 return ret_val;
728}
729
730/////////////////////////////////////////////////////////////////////////////////////////
731int medusa_set_saturation(struct cx25821_dev *dev, int saturation, int decoder)
732{
733 int ret_val = 0;
734 int value = 0;
735 u32 val = 0, tmp = 0;
736
737 mutex_lock(&dev->lock);
738
739 if ((saturation > VIDEO_PROCAMP_MAX)
740 || (saturation < VIDEO_PROCAMP_MIN)) {
741 mutex_unlock(&dev->lock);
742 return -1;
743 }
744
745 ret_val =
746 mapM(VIDEO_PROCAMP_MIN, VIDEO_PROCAMP_MAX, saturation,
747 UNSIGNED_BYTE_MIN, UNSIGNED_BYTE_MAX, &value);
748
749 val =
750 cx25821_i2c_read(&dev->i2c_bus[0],
751 VDEC_A_USAT_CTRL + (0x200 * decoder), &tmp);
752 val &= 0xFFFFFF00;
753 ret_val |=
754 cx25821_i2c_write(&dev->i2c_bus[0],
755 VDEC_A_USAT_CTRL + (0x200 * decoder),
756 val | value);
757
758 val =
759 cx25821_i2c_read(&dev->i2c_bus[0],
760 VDEC_A_VSAT_CTRL + (0x200 * decoder), &tmp);
761 val &= 0xFFFFFF00;
762 ret_val |=
763 cx25821_i2c_write(&dev->i2c_bus[0],
764 VDEC_A_VSAT_CTRL + (0x200 * decoder),
765 val | value);
766
767 mutex_unlock(&dev->lock);
768 return ret_val;
769}
770
771/////////////////////////////////////////////////////////////////////////////////////////
772// Program the display sequence and monitor output.
773//
774int medusa_video_init(struct cx25821_dev *dev)
775{
776 u32 value = 0, tmp = 0;
777 int ret_val = 0;
778 int i = 0;
779
780 mutex_lock(&dev->lock);
781
782 _num_decoders = dev->_max_num_decoders;
783
784 // disable Auto source selection on all video decoders
785 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
786 value &= 0xFFFFF0FF;
787 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
788
789 if (ret_val < 0) {
790 mutex_unlock(&dev->lock);
791 return -EINVAL;
792 }
793 // Turn off Master source switch enable
794 value = cx25821_i2c_read(&dev->i2c_bus[0], MON_A_CTRL, &tmp);
795 value &= 0xFFFFFFDF;
796 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], MON_A_CTRL, value);
797
798 if (ret_val < 0) {
799 mutex_unlock(&dev->lock);
800 return -EINVAL;
801 }
802
803 mutex_unlock(&dev->lock);
804
805 for (i = 0; i < _num_decoders; i++) {
806 medusa_set_decoderduration(dev, i, _display_field_cnt[i]);
807 }
808
809 mutex_lock(&dev->lock);
810
811 // Select monitor as DENC A input, power up the DAC
812 value = cx25821_i2c_read(&dev->i2c_bus[0], DENC_AB_CTRL, &tmp);
813 value &= 0xFF70FF70;
814 value |= 0x00090008; // set en_active
815 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], DENC_AB_CTRL, value);
816
817 if (ret_val < 0) {
818 mutex_unlock(&dev->lock);
819 return -EINVAL;
820 }
821 // enable input is VIP/656
822 value = cx25821_i2c_read(&dev->i2c_bus[0], BYP_AB_CTRL, &tmp);
823 value |= 0x00040100; // enable VIP
824 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], BYP_AB_CTRL, value);
825
826 if (ret_val < 0) {
827 mutex_unlock(&dev->lock);
828 return -EINVAL;
829 }
830 // select AFE clock to output mode
831 value = cx25821_i2c_read(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL, &tmp);
832 value &= 0x83FFFFFF;
833 ret_val =
834 cx25821_i2c_write(&dev->i2c_bus[0], AFE_AB_DIAG_CTRL,
835 value | 0x10000000);
836
837 if (ret_val < 0) {
838 mutex_unlock(&dev->lock);
839 return -EINVAL;
840 }
841 // Turn on all of the data out and control output pins.
842 value = cx25821_i2c_read(&dev->i2c_bus[0], PIN_OE_CTRL, &tmp);
843 value &= 0xFEF0FE00;
844 if (_num_decoders == MAX_DECODERS) {
845 // Note: The octal board does not support control pins(bit16-19).
846 // These bits are ignored in the octal board.
847 value |= 0x010001F8; // disable VDEC A-C port, default to Mobilygen Interface
848 } else {
849 value |= 0x010F0108; // disable VDEC A-C port, default to Mobilygen Interface
850 }
851
852 value |= 7;
853 ret_val = cx25821_i2c_write(&dev->i2c_bus[0], PIN_OE_CTRL, value);
854 if (ret_val < 0) {
855 mutex_unlock(&dev->lock);
856 return -EINVAL;
857 }
858
859 mutex_unlock(&dev->lock);
860
861 ret_val = medusa_set_videostandard(dev);
862
863 if (ret_val < 0) {
864 mutex_unlock(&dev->lock);
865 return -EINVAL;
866 }
867
868 return 1;
869}
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/staging/cx25821/cx25821-medusa-video.h
new file mode 100644
index 000000000000..2fab4b2f251c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-medusa-video.h
@@ -0,0 +1,49 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _MEDUSA_VIDEO_H
24#define _MEDUSA_VIDEO_H
25
26#include "cx25821-medusa-defines.h"
27
28// Color control constants
29#define VIDEO_PROCAMP_MIN 0
30#define VIDEO_PROCAMP_MAX 10000
31#define UNSIGNED_BYTE_MIN 0
32#define UNSIGNED_BYTE_MAX 0xFF
33#define SIGNED_BYTE_MIN -128
34#define SIGNED_BYTE_MAX 127
35
36// Default video color settings
37#define SHARPNESS_DEFAULT 50
38#define SATURATION_DEFAULT 5000
39#define BRIGHTNESS_DEFAULT 6200
40#define CONTRAST_DEFAULT 5000
41#define HUE_DEFAULT 5000
42
43unsigned short _num_decoders;
44unsigned short _num_cameras;
45
46unsigned int _video_standard;
47int _display_field_cnt[MAX_DECODERS];
48
49#endif
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/staging/cx25821/cx25821-reg.h
new file mode 100644
index 000000000000..7241e7ee3fd3
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-reg.h
@@ -0,0 +1,1592 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __CX25821_REGISTERS__
24#define __CX25821_REGISTERS__
25
26/* Risc Instructions */
27#define RISC_CNT_INC 0x00010000
28#define RISC_CNT_RESET 0x00030000
29#define RISC_IRQ1 0x01000000
30#define RISC_IRQ2 0x02000000
31#define RISC_EOL 0x04000000
32#define RISC_SOL 0x08000000
33#define RISC_WRITE 0x10000000
34#define RISC_SKIP 0x20000000
35#define RISC_JUMP 0x70000000
36#define RISC_SYNC 0x80000000
37#define RISC_RESYNC 0x80008000
38#define RISC_READ 0x90000000
39#define RISC_WRITERM 0xB0000000
40#define RISC_WRITECM 0xC0000000
41#define RISC_WRITECR 0xD0000000
42#define RISC_WRITEC 0x50000000
43#define RISC_READC 0xA0000000
44
45#define RISC_SYNC_ODD 0x00000000
46#define RISC_SYNC_EVEN 0x00000200
47#define RISC_SYNC_ODD_VBI 0x00000006
48#define RISC_SYNC_EVEN_VBI 0x00000207
49#define RISC_NOOP 0xF0000000
50
51//*****************************************************************************
52// ASB SRAM
53//*****************************************************************************
54#define TX_SRAM 0x000000 // Transmit SRAM
55
56//*****************************************************************************
57#define RX_RAM 0x010000 // Receive SRAM
58
59//*****************************************************************************
60// Application Layer (AL)
61//*****************************************************************************
62#define DEV_CNTRL2 0x040000 // Device control
63#define FLD_RUN_RISC 0x00000020
64
65//*****************************************************************************
66#define PCI_INT_MSK 0x040010 // PCI interrupt mask
67#define PCI_INT_STAT 0x040014 // PCI interrupt status
68#define PCI_INT_MSTAT 0x040018 // PCI interrupt masked status
69#define FLD_HAMMERHEAD_INT (1 << 27)
70#define FLD_UART_INT (1 << 26)
71#define FLD_IRQN_INT (1 << 25)
72#define FLD_TM_INT (1 << 28)
73#define FLD_I2C_3_RACK (1 << 27)
74#define FLD_I2C_3_INT (1 << 26)
75#define FLD_I2C_2_RACK (1 << 25)
76#define FLD_I2C_2_INT (1 << 24)
77#define FLD_I2C_1_RACK (1 << 23)
78#define FLD_I2C_1_INT (1 << 22)
79
80#define FLD_APB_DMA_BERR_INT (1 << 21)
81#define FLD_AL_WR_BERR_INT (1 << 20)
82#define FLD_AL_RD_BERR_INT (1 << 19)
83#define FLD_RISC_WR_BERR_INT (1 << 18)
84#define FLD_RISC_RD_BERR_INT (1 << 17)
85
86#define FLD_VID_I_INT (1 << 8)
87#define FLD_VID_H_INT (1 << 7)
88#define FLD_VID_G_INT (1 << 6)
89#define FLD_VID_F_INT (1 << 5)
90#define FLD_VID_E_INT (1 << 4)
91#define FLD_VID_D_INT (1 << 3)
92#define FLD_VID_C_INT (1 << 2)
93#define FLD_VID_B_INT (1 << 1)
94#define FLD_VID_A_INT (1 << 0)
95
96//*****************************************************************************
97#define VID_A_INT_MSK 0x040020 // Video A interrupt mask
98#define VID_A_INT_STAT 0x040024 // Video A interrupt status
99#define VID_A_INT_MSTAT 0x040028 // Video A interrupt masked status
100#define VID_A_INT_SSTAT 0x04002C // Video A interrupt set status
101
102//*****************************************************************************
103#define VID_B_INT_MSK 0x040030 // Video B interrupt mask
104#define VID_B_INT_STAT 0x040034 // Video B interrupt status
105#define VID_B_INT_MSTAT 0x040038 // Video B interrupt masked status
106#define VID_B_INT_SSTAT 0x04003C // Video B interrupt set status
107
108//*****************************************************************************
109#define VID_C_INT_MSK 0x040040 // Video C interrupt mask
110#define VID_C_INT_STAT 0x040044 // Video C interrupt status
111#define VID_C_INT_MSTAT 0x040048 // Video C interrupt masked status
112#define VID_C_INT_SSTAT 0x04004C // Video C interrupt set status
113
114//*****************************************************************************
115#define VID_D_INT_MSK 0x040050 // Video D interrupt mask
116#define VID_D_INT_STAT 0x040054 // Video D interrupt status
117#define VID_D_INT_MSTAT 0x040058 // Video D interrupt masked status
118#define VID_D_INT_SSTAT 0x04005C // Video D interrupt set status
119
120//*****************************************************************************
121#define VID_E_INT_MSK 0x040060 // Video E interrupt mask
122#define VID_E_INT_STAT 0x040064 // Video E interrupt status
123#define VID_E_INT_MSTAT 0x040068 // Video E interrupt masked status
124#define VID_E_INT_SSTAT 0x04006C // Video E interrupt set status
125
126//*****************************************************************************
127#define VID_F_INT_MSK 0x040070 // Video F interrupt mask
128#define VID_F_INT_STAT 0x040074 // Video F interrupt status
129#define VID_F_INT_MSTAT 0x040078 // Video F interrupt masked status
130#define VID_F_INT_SSTAT 0x04007C // Video F interrupt set status
131
132//*****************************************************************************
133#define VID_G_INT_MSK 0x040080 // Video G interrupt mask
134#define VID_G_INT_STAT 0x040084 // Video G interrupt status
135#define VID_G_INT_MSTAT 0x040088 // Video G interrupt masked status
136#define VID_G_INT_SSTAT 0x04008C // Video G interrupt set status
137
138//*****************************************************************************
139#define VID_H_INT_MSK 0x040090 // Video H interrupt mask
140#define VID_H_INT_STAT 0x040094 // Video H interrupt status
141#define VID_H_INT_MSTAT 0x040098 // Video H interrupt masked status
142#define VID_H_INT_SSTAT 0x04009C // Video H interrupt set status
143
144//*****************************************************************************
145#define VID_I_INT_MSK 0x0400A0 // Video I interrupt mask
146#define VID_I_INT_STAT 0x0400A4 // Video I interrupt status
147#define VID_I_INT_MSTAT 0x0400A8 // Video I interrupt masked status
148#define VID_I_INT_SSTAT 0x0400AC // Video I interrupt set status
149
150//*****************************************************************************
151#define VID_J_INT_MSK 0x0400B0 // Video J interrupt mask
152#define VID_J_INT_STAT 0x0400B4 // Video J interrupt status
153#define VID_J_INT_MSTAT 0x0400B8 // Video J interrupt masked status
154#define VID_J_INT_SSTAT 0x0400BC // Video J interrupt set status
155
156#define FLD_VID_SRC_OPC_ERR 0x00020000
157#define FLD_VID_DST_OPC_ERR 0x00010000
158#define FLD_VID_SRC_SYNC 0x00002000
159#define FLD_VID_DST_SYNC 0x00001000
160#define FLD_VID_SRC_UF 0x00000200
161#define FLD_VID_DST_OF 0x00000100
162#define FLD_VID_SRC_RISC2 0x00000020
163#define FLD_VID_DST_RISC2 0x00000010
164#define FLD_VID_SRC_RISC1 0x00000002
165#define FLD_VID_DST_RISC1 0x00000001
166#define FLD_VID_SRC_ERRORS FLD_VID_SRC_OPC_ERR | FLD_VID_SRC_SYNC | FLD_VID_SRC_UF
167#define FLD_VID_DST_ERRORS FLD_VID_DST_OPC_ERR | FLD_VID_DST_SYNC | FLD_VID_DST_OF
168
169//*****************************************************************************
170#define AUD_A_INT_MSK 0x0400C0 // Audio Int interrupt mask
171#define AUD_A_INT_STAT 0x0400C4 // Audio Int interrupt status
172#define AUD_A_INT_MSTAT 0x0400C8 // Audio Int interrupt masked status
173#define AUD_A_INT_SSTAT 0x0400CC // Audio Int interrupt set status
174
175//*****************************************************************************
176#define AUD_B_INT_MSK 0x0400D0 // Audio Int interrupt mask
177#define AUD_B_INT_STAT 0x0400D4 // Audio Int interrupt status
178#define AUD_B_INT_MSTAT 0x0400D8 // Audio Int interrupt masked status
179#define AUD_B_INT_SSTAT 0x0400DC // Audio Int interrupt set status
180
181//*****************************************************************************
182#define AUD_C_INT_MSK 0x0400E0 // Audio Int interrupt mask
183#define AUD_C_INT_STAT 0x0400E4 // Audio Int interrupt status
184#define AUD_C_INT_MSTAT 0x0400E8 // Audio Int interrupt masked status
185#define AUD_C_INT_SSTAT 0x0400EC // Audio Int interrupt set status
186
187//*****************************************************************************
188#define AUD_D_INT_MSK 0x0400F0 // Audio Int interrupt mask
189#define AUD_D_INT_STAT 0x0400F4 // Audio Int interrupt status
190#define AUD_D_INT_MSTAT 0x0400F8 // Audio Int interrupt masked status
191#define AUD_D_INT_SSTAT 0x0400FC // Audio Int interrupt set status
192
193//*****************************************************************************
194#define AUD_E_INT_MSK 0x040100 // Audio Int interrupt mask
195#define AUD_E_INT_STAT 0x040104 // Audio Int interrupt status
196#define AUD_E_INT_MSTAT 0x040108 // Audio Int interrupt masked status
197#define AUD_E_INT_SSTAT 0x04010C // Audio Int interrupt set status
198
199#define FLD_AUD_SRC_OPC_ERR 0x00020000
200#define FLD_AUD_DST_OPC_ERR 0x00010000
201#define FLD_AUD_SRC_SYNC 0x00002000
202#define FLD_AUD_DST_SYNC 0x00001000
203#define FLD_AUD_SRC_OF 0x00000200
204#define FLD_AUD_DST_OF 0x00000100
205#define FLD_AUD_SRC_RISCI2 0x00000020
206#define FLD_AUD_DST_RISCI2 0x00000010
207#define FLD_AUD_SRC_RISCI1 0x00000002
208#define FLD_AUD_DST_RISCI1 0x00000001
209
210//*****************************************************************************
211#define MBIF_A_INT_MSK 0x040110 // MBIF Int interrupt mask
212#define MBIF_A_INT_STAT 0x040114 // MBIF Int interrupt status
213#define MBIF_A_INT_MSTAT 0x040118 // MBIF Int interrupt masked status
214#define MBIF_A_INT_SSTAT 0x04011C // MBIF Int interrupt set status
215
216//*****************************************************************************
217#define MBIF_B_INT_MSK 0x040120 // MBIF Int interrupt mask
218#define MBIF_B_INT_STAT 0x040124 // MBIF Int interrupt status
219#define MBIF_B_INT_MSTAT 0x040128 // MBIF Int interrupt masked status
220#define MBIF_B_INT_SSTAT 0x04012C // MBIF Int interrupt set status
221
222#define FLD_MBIF_DST_OPC_ERR 0x00010000
223#define FLD_MBIF_DST_SYNC 0x00001000
224#define FLD_MBIF_DST_OF 0x00000100
225#define FLD_MBIF_DST_RISCI2 0x00000010
226#define FLD_MBIF_DST_RISCI1 0x00000001
227
228//*****************************************************************************
229#define AUD_EXT_INT_MSK 0x040060 // Audio Ext interrupt mask
230#define AUD_EXT_INT_STAT 0x040064 // Audio Ext interrupt status
231#define AUD_EXT_INT_MSTAT 0x040068 // Audio Ext interrupt masked status
232#define AUD_EXT_INT_SSTAT 0x04006C // Audio Ext interrupt set status
233#define FLD_AUD_EXT_OPC_ERR 0x00010000
234#define FLD_AUD_EXT_SYNC 0x00001000
235#define FLD_AUD_EXT_OF 0x00000100
236#define FLD_AUD_EXT_RISCI2 0x00000010
237#define FLD_AUD_EXT_RISCI1 0x00000001
238
239//*****************************************************************************
240#define GPIO_LO 0x110010 // Lower of GPIO pins [31:0]
241#define GPIO_HI 0x110014 // Upper WORD of GPIO pins [47:31]
242
243#define GPIO_LO_OE 0x110018 // Lower of GPIO output enable [31:0]
244#define GPIO_HI_OE 0x11001C // Upper word of GPIO output enable [47:32]
245
246#define GPIO_LO_INT_MSK 0x11003C // GPIO interrupt mask
247#define GPIO_LO_INT_STAT 0x110044 // GPIO interrupt status
248#define GPIO_LO_INT_MSTAT 0x11004C // GPIO interrupt masked status
249#define GPIO_LO_ISM_SNS 0x110054 // GPIO interrupt sensitivity
250#define GPIO_LO_ISM_POL 0x11005C // GPIO interrupt polarity
251
252#define GPIO_HI_INT_MSK 0x110040 // GPIO interrupt mask
253#define GPIO_HI_INT_STAT 0x110048 // GPIO interrupt status
254#define GPIO_HI_INT_MSTAT 0x110050 // GPIO interrupt masked status
255#define GPIO_HI_ISM_SNS 0x110058 // GPIO interrupt sensitivity
256#define GPIO_HI_ISM_POL 0x110060 // GPIO interrupt polarity
257
258#define FLD_GPIO43_INT (1 << 11)
259#define FLD_GPIO42_INT (1 << 10)
260#define FLD_GPIO41_INT (1 << 9)
261#define FLD_GPIO40_INT (1 << 8)
262
263#define FLD_GPIO9_INT (1 << 9)
264#define FLD_GPIO8_INT (1 << 8)
265#define FLD_GPIO7_INT (1 << 7)
266#define FLD_GPIO6_INT (1 << 6)
267#define FLD_GPIO5_INT (1 << 5)
268#define FLD_GPIO4_INT (1 << 4)
269#define FLD_GPIO3_INT (1 << 3)
270#define FLD_GPIO2_INT (1 << 2)
271#define FLD_GPIO1_INT (1 << 1)
272#define FLD_GPIO0_INT (1 << 0)
273
274//*****************************************************************************
275#define TC_REQ 0x040090 // Rider PCI Express traFFic class request
276
277//*****************************************************************************
278#define TC_REQ_SET 0x040094 // Rider PCI Express traFFic class request set
279
280//*****************************************************************************
281// Rider
282//*****************************************************************************
283
284// PCI Compatible Header
285//*****************************************************************************
286#define RDR_CFG0 0x050000
287#define RDR_VENDOR_DEVICE_ID_CFG 0x050000
288
289//*****************************************************************************
290#define RDR_CFG1 0x050004
291
292//*****************************************************************************
293#define RDR_CFG2 0x050008
294
295//*****************************************************************************
296#define RDR_CFG3 0x05000C
297
298//*****************************************************************************
299#define RDR_CFG4 0x050010
300
301//*****************************************************************************
302#define RDR_CFG5 0x050014
303
304//*****************************************************************************
305#define RDR_CFG6 0x050018
306
307//*****************************************************************************
308#define RDR_CFG7 0x05001C
309
310//*****************************************************************************
311#define RDR_CFG8 0x050020
312
313//*****************************************************************************
314#define RDR_CFG9 0x050024
315
316//*****************************************************************************
317#define RDR_CFGA 0x050028
318
319//*****************************************************************************
320#define RDR_CFGB 0x05002C
321#define RDR_SUSSYSTEM_ID_CFG 0x05002C
322
323//*****************************************************************************
324#define RDR_CFGC 0x050030
325
326//*****************************************************************************
327#define RDR_CFGD 0x050034
328
329//*****************************************************************************
330#define RDR_CFGE 0x050038
331
332//*****************************************************************************
333#define RDR_CFGF 0x05003C
334
335//*****************************************************************************
336// PCI-Express Capabilities
337//*****************************************************************************
338#define RDR_PECAP 0x050040
339
340//*****************************************************************************
341#define RDR_PEDEVCAP 0x050044
342
343//*****************************************************************************
344#define RDR_PEDEVSC 0x050048
345
346//*****************************************************************************
347#define RDR_PELINKCAP 0x05004C
348
349//*****************************************************************************
350#define RDR_PELINKSC 0x050050
351
352//*****************************************************************************
353#define RDR_PMICAP 0x050080
354
355//*****************************************************************************
356#define RDR_PMCSR 0x050084
357
358//*****************************************************************************
359#define RDR_VPDCAP 0x050090
360
361//*****************************************************************************
362#define RDR_VPDDATA 0x050094
363
364//*****************************************************************************
365#define RDR_MSICAP 0x0500A0
366
367//*****************************************************************************
368#define RDR_MSIARL 0x0500A4
369
370//*****************************************************************************
371#define RDR_MSIARU 0x0500A8
372
373//*****************************************************************************
374#define RDR_MSIDATA 0x0500AC
375
376//*****************************************************************************
377// PCI Express Extended Capabilities
378//*****************************************************************************
379#define RDR_AERXCAP 0x050100
380
381//*****************************************************************************
382#define RDR_AERUESTA 0x050104
383
384//*****************************************************************************
385#define RDR_AERUEMSK 0x050108
386
387//*****************************************************************************
388#define RDR_AERUESEV 0x05010C
389
390//*****************************************************************************
391#define RDR_AERCESTA 0x050110
392
393//*****************************************************************************
394#define RDR_AERCEMSK 0x050114
395
396//*****************************************************************************
397#define RDR_AERCC 0x050118
398
399//*****************************************************************************
400#define RDR_AERHL0 0x05011C
401
402//*****************************************************************************
403#define RDR_AERHL1 0x050120
404
405//*****************************************************************************
406#define RDR_AERHL2 0x050124
407
408//*****************************************************************************
409#define RDR_AERHL3 0x050128
410
411//*****************************************************************************
412#define RDR_VCXCAP 0x050200
413
414//*****************************************************************************
415#define RDR_VCCAP1 0x050204
416
417//*****************************************************************************
418#define RDR_VCCAP2 0x050208
419
420//*****************************************************************************
421#define RDR_VCSC 0x05020C
422
423//*****************************************************************************
424#define RDR_VCR0_CAP 0x050210
425
426//*****************************************************************************
427#define RDR_VCR0_CTRL 0x050214
428
429//*****************************************************************************
430#define RDR_VCR0_STAT 0x050218
431
432//*****************************************************************************
433#define RDR_VCR1_CAP 0x05021C
434
435//*****************************************************************************
436#define RDR_VCR1_CTRL 0x050220
437
438//*****************************************************************************
439#define RDR_VCR1_STAT 0x050224
440
441//*****************************************************************************
442#define RDR_VCR2_CAP 0x050228
443
444//*****************************************************************************
445#define RDR_VCR2_CTRL 0x05022C
446
447//*****************************************************************************
448#define RDR_VCR2_STAT 0x050230
449
450//*****************************************************************************
451#define RDR_VCR3_CAP 0x050234
452
453//*****************************************************************************
454#define RDR_VCR3_CTRL 0x050238
455
456//*****************************************************************************
457#define RDR_VCR3_STAT 0x05023C
458
459//*****************************************************************************
460#define RDR_VCARB0 0x050240
461
462//*****************************************************************************
463#define RDR_VCARB1 0x050244
464
465//*****************************************************************************
466#define RDR_VCARB2 0x050248
467
468//*****************************************************************************
469#define RDR_VCARB3 0x05024C
470
471//*****************************************************************************
472#define RDR_VCARB4 0x050250
473
474//*****************************************************************************
475#define RDR_VCARB5 0x050254
476
477//*****************************************************************************
478#define RDR_VCARB6 0x050258
479
480//*****************************************************************************
481#define RDR_VCARB7 0x05025C
482
483//*****************************************************************************
484#define RDR_RDRSTAT0 0x050300
485
486//*****************************************************************************
487#define RDR_RDRSTAT1 0x050304
488
489//*****************************************************************************
490#define RDR_RDRCTL0 0x050308
491
492//*****************************************************************************
493#define RDR_RDRCTL1 0x05030C
494
495//*****************************************************************************
496// Transaction Layer Registers
497//*****************************************************************************
498#define RDR_TLSTAT0 0x050310
499
500//*****************************************************************************
501#define RDR_TLSTAT1 0x050314
502
503//*****************************************************************************
504#define RDR_TLCTL0 0x050318
505#define FLD_CFG_UR_CPL_MODE 0x00000040
506#define FLD_CFG_CORR_ERR_QUITE 0x00000020
507#define FLD_CFG_RCB_CK_EN 0x00000010
508#define FLD_CFG_BNDRY_CK_EN 0x00000008
509#define FLD_CFG_BYTE_EN_CK_EN 0x00000004
510#define FLD_CFG_RELAX_ORDER_MSK 0x00000002
511#define FLD_CFG_TAG_ORDER_EN 0x00000001
512
513//*****************************************************************************
514#define RDR_TLCTL1 0x05031C
515
516//*****************************************************************************
517#define RDR_REQRCAL 0x050320
518
519//*****************************************************************************
520#define RDR_REQRCAU 0x050324
521
522//*****************************************************************************
523#define RDR_REQEPA 0x050328
524
525//*****************************************************************************
526#define RDR_REQCTRL 0x05032C
527
528//*****************************************************************************
529#define RDR_REQSTAT 0x050330
530
531//*****************************************************************************
532#define RDR_TL_TEST 0x050334
533
534//*****************************************************************************
535#define RDR_VCR01_CTL 0x050348
536
537//*****************************************************************************
538#define RDR_VCR23_CTL 0x05034C
539
540//*****************************************************************************
541#define RDR_RX_VCR0_FC 0x050350
542
543//*****************************************************************************
544#define RDR_RX_VCR1_FC 0x050354
545
546//*****************************************************************************
547#define RDR_RX_VCR2_FC 0x050358
548
549//*****************************************************************************
550#define RDR_RX_VCR3_FC 0x05035C
551
552//*****************************************************************************
553// Data Link Layer Registers
554//*****************************************************************************
555#define RDR_DLLSTAT 0x050360
556
557//*****************************************************************************
558#define RDR_DLLCTRL 0x050364
559
560//*****************************************************************************
561#define RDR_REPLAYTO 0x050368
562
563//*****************************************************************************
564#define RDR_ACKLATTO 0x05036C
565
566//*****************************************************************************
567// MAC Layer Registers
568//*****************************************************************************
569#define RDR_MACSTAT0 0x050380
570
571//*****************************************************************************
572#define RDR_MACSTAT1 0x050384
573
574//*****************************************************************************
575#define RDR_MACCTRL0 0x050388
576
577//*****************************************************************************
578#define RDR_MACCTRL1 0x05038C
579
580//*****************************************************************************
581#define RDR_MACCTRL2 0x050390
582
583//*****************************************************************************
584#define RDR_MAC_LB_DATA 0x050394
585
586//*****************************************************************************
587#define RDR_L0S_EXIT_LAT 0x050398
588
589//*****************************************************************************
590// DMAC
591//*****************************************************************************
592#define DMA1_PTR1 0x100000 // DMA Current Ptr : Ch#1
593
594//*****************************************************************************
595#define DMA2_PTR1 0x100004 // DMA Current Ptr : Ch#2
596
597//*****************************************************************************
598#define DMA3_PTR1 0x100008 // DMA Current Ptr : Ch#3
599
600//*****************************************************************************
601#define DMA4_PTR1 0x10000C // DMA Current Ptr : Ch#4
602
603//*****************************************************************************
604#define DMA5_PTR1 0x100010 // DMA Current Ptr : Ch#5
605
606//*****************************************************************************
607#define DMA6_PTR1 0x100014 // DMA Current Ptr : Ch#6
608
609//*****************************************************************************
610#define DMA7_PTR1 0x100018 // DMA Current Ptr : Ch#7
611
612//*****************************************************************************
613#define DMA8_PTR1 0x10001C // DMA Current Ptr : Ch#8
614
615//*****************************************************************************
616#define DMA9_PTR1 0x100020 // DMA Current Ptr : Ch#9
617
618//*****************************************************************************
619#define DMA10_PTR1 0x100024 // DMA Current Ptr : Ch#10
620
621//*****************************************************************************
622#define DMA11_PTR1 0x100028 // DMA Current Ptr : Ch#11
623
624//*****************************************************************************
625#define DMA12_PTR1 0x10002C // DMA Current Ptr : Ch#12
626
627//*****************************************************************************
628#define DMA13_PTR1 0x100030 // DMA Current Ptr : Ch#13
629
630//*****************************************************************************
631#define DMA14_PTR1 0x100034 // DMA Current Ptr : Ch#14
632
633//*****************************************************************************
634#define DMA15_PTR1 0x100038 // DMA Current Ptr : Ch#15
635
636//*****************************************************************************
637#define DMA16_PTR1 0x10003C // DMA Current Ptr : Ch#16
638
639//*****************************************************************************
640#define DMA17_PTR1 0x100040 // DMA Current Ptr : Ch#17
641
642//*****************************************************************************
643#define DMA18_PTR1 0x100044 // DMA Current Ptr : Ch#18
644
645//*****************************************************************************
646#define DMA19_PTR1 0x100048 // DMA Current Ptr : Ch#19
647
648//*****************************************************************************
649#define DMA20_PTR1 0x10004C // DMA Current Ptr : Ch#20
650
651//*****************************************************************************
652#define DMA21_PTR1 0x100050 // DMA Current Ptr : Ch#21
653
654//*****************************************************************************
655#define DMA22_PTR1 0x100054 // DMA Current Ptr : Ch#22
656
657//*****************************************************************************
658#define DMA23_PTR1 0x100058 // DMA Current Ptr : Ch#23
659
660//*****************************************************************************
661#define DMA24_PTR1 0x10005C // DMA Current Ptr : Ch#24
662
663//*****************************************************************************
664#define DMA25_PTR1 0x100060 // DMA Current Ptr : Ch#25
665
666//*****************************************************************************
667#define DMA26_PTR1 0x100064 // DMA Current Ptr : Ch#26
668
669//*****************************************************************************
670#define DMA1_PTR2 0x100080 // DMA Tab Ptr : Ch#1
671
672//*****************************************************************************
673#define DMA2_PTR2 0x100084 // DMA Tab Ptr : Ch#2
674
675//*****************************************************************************
676#define DMA3_PTR2 0x100088 // DMA Tab Ptr : Ch#3
677
678//*****************************************************************************
679#define DMA4_PTR2 0x10008C // DMA Tab Ptr : Ch#4
680
681//*****************************************************************************
682#define DMA5_PTR2 0x100090 // DMA Tab Ptr : Ch#5
683
684//*****************************************************************************
685#define DMA6_PTR2 0x100094 // DMA Tab Ptr : Ch#6
686
687//*****************************************************************************
688#define DMA7_PTR2 0x100098 // DMA Tab Ptr : Ch#7
689
690//*****************************************************************************
691#define DMA8_PTR2 0x10009C // DMA Tab Ptr : Ch#8
692
693//*****************************************************************************
694#define DMA9_PTR2 0x1000A0 // DMA Tab Ptr : Ch#9
695
696//*****************************************************************************
697#define DMA10_PTR2 0x1000A4 // DMA Tab Ptr : Ch#10
698
699//*****************************************************************************
700#define DMA11_PTR2 0x1000A8 // DMA Tab Ptr : Ch#11
701
702//*****************************************************************************
703#define DMA12_PTR2 0x1000AC // DMA Tab Ptr : Ch#12
704
705//*****************************************************************************
706#define DMA13_PTR2 0x1000B0 // DMA Tab Ptr : Ch#13
707
708//*****************************************************************************
709#define DMA14_PTR2 0x1000B4 // DMA Tab Ptr : Ch#14
710
711//*****************************************************************************
712#define DMA15_PTR2 0x1000B8 // DMA Tab Ptr : Ch#15
713
714//*****************************************************************************
715#define DMA16_PTR2 0x1000BC // DMA Tab Ptr : Ch#16
716
717//*****************************************************************************
718#define DMA17_PTR2 0x1000C0 // DMA Tab Ptr : Ch#17
719
720//*****************************************************************************
721#define DMA18_PTR2 0x1000C4 // DMA Tab Ptr : Ch#18
722
723//*****************************************************************************
724#define DMA19_PTR2 0x1000C8 // DMA Tab Ptr : Ch#19
725
726//*****************************************************************************
727#define DMA20_PTR2 0x1000CC // DMA Tab Ptr : Ch#20
728
729//*****************************************************************************
730#define DMA21_PTR2 0x1000D0 // DMA Tab Ptr : Ch#21
731
732//*****************************************************************************
733#define DMA22_PTR2 0x1000D4 // DMA Tab Ptr : Ch#22
734
735//*****************************************************************************
736#define DMA23_PTR2 0x1000D8 // DMA Tab Ptr : Ch#23
737
738//*****************************************************************************
739#define DMA24_PTR2 0x1000DC // DMA Tab Ptr : Ch#24
740
741//*****************************************************************************
742#define DMA25_PTR2 0x1000E0 // DMA Tab Ptr : Ch#25
743
744//*****************************************************************************
745#define DMA26_PTR2 0x1000E4 // DMA Tab Ptr : Ch#26
746
747//*****************************************************************************
748#define DMA1_CNT1 0x100100 // DMA BuFFer Size : Ch#1
749
750//*****************************************************************************
751#define DMA2_CNT1 0x100104 // DMA BuFFer Size : Ch#2
752
753//*****************************************************************************
754#define DMA3_CNT1 0x100108 // DMA BuFFer Size : Ch#3
755
756//*****************************************************************************
757#define DMA4_CNT1 0x10010C // DMA BuFFer Size : Ch#4
758
759//*****************************************************************************
760#define DMA5_CNT1 0x100110 // DMA BuFFer Size : Ch#5
761
762//*****************************************************************************
763#define DMA6_CNT1 0x100114 // DMA BuFFer Size : Ch#6
764
765//*****************************************************************************
766#define DMA7_CNT1 0x100118 // DMA BuFFer Size : Ch#7
767
768//*****************************************************************************
769#define DMA8_CNT1 0x10011C // DMA BuFFer Size : Ch#8
770
771//*****************************************************************************
772#define DMA9_CNT1 0x100120 // DMA BuFFer Size : Ch#9
773
774//*****************************************************************************
775#define DMA10_CNT1 0x100124 // DMA BuFFer Size : Ch#10
776
777//*****************************************************************************
778#define DMA11_CNT1 0x100128 // DMA BuFFer Size : Ch#11
779
780//*****************************************************************************
781#define DMA12_CNT1 0x10012C // DMA BuFFer Size : Ch#12
782
783//*****************************************************************************
784#define DMA13_CNT1 0x100130 // DMA BuFFer Size : Ch#13
785
786//*****************************************************************************
787#define DMA14_CNT1 0x100134 // DMA BuFFer Size : Ch#14
788
789//*****************************************************************************
790#define DMA15_CNT1 0x100138 // DMA BuFFer Size : Ch#15
791
792//*****************************************************************************
793#define DMA16_CNT1 0x10013C // DMA BuFFer Size : Ch#16
794
795//*****************************************************************************
796#define DMA17_CNT1 0x100140 // DMA BuFFer Size : Ch#17
797
798//*****************************************************************************
799#define DMA18_CNT1 0x100144 // DMA BuFFer Size : Ch#18
800
801//*****************************************************************************
802#define DMA19_CNT1 0x100148 // DMA BuFFer Size : Ch#19
803
804//*****************************************************************************
805#define DMA20_CNT1 0x10014C // DMA BuFFer Size : Ch#20
806
807//*****************************************************************************
808#define DMA21_CNT1 0x100150 // DMA BuFFer Size : Ch#21
809
810//*****************************************************************************
811#define DMA22_CNT1 0x100154 // DMA BuFFer Size : Ch#22
812
813//*****************************************************************************
814#define DMA23_CNT1 0x100158 // DMA BuFFer Size : Ch#23
815
816//*****************************************************************************
817#define DMA24_CNT1 0x10015C // DMA BuFFer Size : Ch#24
818
819//*****************************************************************************
820#define DMA25_CNT1 0x100160 // DMA BuFFer Size : Ch#25
821
822//*****************************************************************************
823#define DMA26_CNT1 0x100164 // DMA BuFFer Size : Ch#26
824
825//*****************************************************************************
826#define DMA1_CNT2 0x100180 // DMA Table Size : Ch#1
827
828//*****************************************************************************
829#define DMA2_CNT2 0x100184 // DMA Table Size : Ch#2
830
831//*****************************************************************************
832#define DMA3_CNT2 0x100188 // DMA Table Size : Ch#3
833
834//*****************************************************************************
835#define DMA4_CNT2 0x10018C // DMA Table Size : Ch#4
836
837//*****************************************************************************
838#define DMA5_CNT2 0x100190 // DMA Table Size : Ch#5
839
840//*****************************************************************************
841#define DMA6_CNT2 0x100194 // DMA Table Size : Ch#6
842
843//*****************************************************************************
844#define DMA7_CNT2 0x100198 // DMA Table Size : Ch#7
845
846//*****************************************************************************
847#define DMA8_CNT2 0x10019C // DMA Table Size : Ch#8
848
849//*****************************************************************************
850#define DMA9_CNT2 0x1001A0 // DMA Table Size : Ch#9
851
852//*****************************************************************************
853#define DMA10_CNT2 0x1001A4 // DMA Table Size : Ch#10
854
855//*****************************************************************************
856#define DMA11_CNT2 0x1001A8 // DMA Table Size : Ch#11
857
858//*****************************************************************************
859#define DMA12_CNT2 0x1001AC // DMA Table Size : Ch#12
860
861//*****************************************************************************
862#define DMA13_CNT2 0x1001B0 // DMA Table Size : Ch#13
863
864//*****************************************************************************
865#define DMA14_CNT2 0x1001B4 // DMA Table Size : Ch#14
866
867//*****************************************************************************
868#define DMA15_CNT2 0x1001B8 // DMA Table Size : Ch#15
869
870//*****************************************************************************
871#define DMA16_CNT2 0x1001BC // DMA Table Size : Ch#16
872
873//*****************************************************************************
874#define DMA17_CNT2 0x1001C0 // DMA Table Size : Ch#17
875
876//*****************************************************************************
877#define DMA18_CNT2 0x1001C4 // DMA Table Size : Ch#18
878
879//*****************************************************************************
880#define DMA19_CNT2 0x1001C8 // DMA Table Size : Ch#19
881
882//*****************************************************************************
883#define DMA20_CNT2 0x1001CC // DMA Table Size : Ch#20
884
885//*****************************************************************************
886#define DMA21_CNT2 0x1001D0 // DMA Table Size : Ch#21
887
888//*****************************************************************************
889#define DMA22_CNT2 0x1001D4 // DMA Table Size : Ch#22
890
891//*****************************************************************************
892#define DMA23_CNT2 0x1001D8 // DMA Table Size : Ch#23
893
894//*****************************************************************************
895#define DMA24_CNT2 0x1001DC // DMA Table Size : Ch#24
896
897//*****************************************************************************
898#define DMA25_CNT2 0x1001E0 // DMA Table Size : Ch#25
899
900//*****************************************************************************
901#define DMA26_CNT2 0x1001E4 // DMA Table Size : Ch#26
902
903//*****************************************************************************
904 // ITG
905//*****************************************************************************
906#define TM_CNT_LDW 0x110000 // Timer : Counter low
907
908//*****************************************************************************
909#define TM_CNT_UW 0x110004 // Timer : Counter high word
910
911//*****************************************************************************
912#define TM_LMT_LDW 0x110008 // Timer : Limit low
913
914//*****************************************************************************
915#define TM_LMT_UW 0x11000C // Timer : Limit high word
916
917//*****************************************************************************
918#define GP0_IO 0x110010 // GPIO output enables data I/O
919#define FLD_GP_OE 0x00FF0000 // GPIO: GP_OE output enable
920#define FLD_GP_IN 0x0000FF00 // GPIO: GP_IN status
921#define FLD_GP_OUT 0x000000FF // GPIO: GP_OUT control
922
923//*****************************************************************************
924#define GPIO_ISM 0x110014 // GPIO interrupt sensitivity mode
925#define FLD_GP_ISM_SNS 0x00000070
926#define FLD_GP_ISM_POL 0x00000007
927
928//*****************************************************************************
929#define SOFT_RESET 0x11001C // Output system reset reg
930#define FLD_PECOS_SOFT_RESET 0x00000001
931
932//*****************************************************************************
933#define MC416_RWD 0x110020 // MC416 GPIO[18:3] pin
934#define MC416_OEN 0x110024 // Output enable of GPIO[18:3]
935#define MC416_CTL 0x110028
936
937//*****************************************************************************
938#define ALT_PIN_OUT_SEL 0x11002C // Alternate GPIO output select
939
940#define FLD_ALT_GPIO_OUT_SEL 0xF0000000
941// 0 Disabled <-- default
942// 1 GPIO[0]
943// 2 GPIO[10]
944// 3 VIP_656_DATA_VAL
945// 4 VIP_656_DATA[0]
946// 5 VIP_656_CLK
947// 6 VIP_656_DATA_EXT[1]
948// 7 VIP_656_DATA_EXT[0]
949// 8 ATT_IF
950
951#define FLD_AUX_PLL_CLK_ALT_SEL 0x0F000000
952// 0 AUX_PLL_CLK<-- default
953// 1 GPIO[2]
954// 2 GPIO[10]
955// 3 VIP_656_DATA_VAL
956// 4 VIP_656_DATA[0]
957// 5 VIP_656_CLK
958// 6 VIP_656_DATA_EXT[1]
959// 7 VIP_656_DATA_EXT[0]
960
961#define FLD_IR_TX_ALT_SEL 0x00F00000
962// 0 IR_TX <-- default
963// 1 GPIO[1]
964// 2 GPIO[10]
965// 3 VIP_656_DATA_VAL
966// 4 VIP_656_DATA[0]
967// 5 VIP_656_CLK
968// 6 VIP_656_DATA_EXT[1]
969// 7 VIP_656_DATA_EXT[0]
970
971#define FLD_IR_RX_ALT_SEL 0x000F0000
972// 0 IR_RX <-- default
973// 1 GPIO[0]
974// 2 GPIO[10]
975// 3 VIP_656_DATA_VAL
976// 4 VIP_656_DATA[0]
977// 5 VIP_656_CLK
978// 6 VIP_656_DATA_EXT[1]
979// 7 VIP_656_DATA_EXT[0]
980
981#define FLD_GPIO10_ALT_SEL 0x0000F000
982// 0 GPIO[10] <-- default
983// 1 GPIO[0]
984// 2 GPIO[10]
985// 3 VIP_656_DATA_VAL
986// 4 VIP_656_DATA[0]
987// 5 VIP_656_CLK
988// 6 VIP_656_DATA_EXT[1]
989// 7 VIP_656_DATA_EXT[0]
990
991#define FLD_GPIO2_ALT_SEL 0x00000F00
992// 0 GPIO[2] <-- default
993// 1 GPIO[1]
994// 2 GPIO[10]
995// 3 VIP_656_DATA_VAL
996// 4 VIP_656_DATA[0]
997// 5 VIP_656_CLK
998// 6 VIP_656_DATA_EXT[1]
999// 7 VIP_656_DATA_EXT[0]
1000
1001#define FLD_GPIO1_ALT_SEL 0x000000F0
1002// 0 GPIO[1] <-- default
1003// 1 GPIO[0]
1004// 2 GPIO[10]
1005// 3 VIP_656_DATA_VAL
1006// 4 VIP_656_DATA[0]
1007// 5 VIP_656_CLK
1008// 6 VIP_656_DATA_EXT[1]
1009// 7 VIP_656_DATA_EXT[0]
1010
1011#define FLD_GPIO0_ALT_SEL 0x0000000F
1012// 0 GPIO[0] <-- default
1013// 1 GPIO[1]
1014// 2 GPIO[10]
1015// 3 VIP_656_DATA_VAL
1016// 4 VIP_656_DATA[0]
1017// 5 VIP_656_CLK
1018// 6 VIP_656_DATA_EXT[1]
1019// 7 VIP_656_DATA_EXT[0]
1020
1021#define ALT_PIN_IN_SEL 0x110030 // Alternate GPIO input select
1022
1023#define FLD_GPIO10_ALT_IN_SEL 0x0000F000
1024// 0 GPIO[10] <-- default
1025// 1 IR_RX
1026// 2 IR_TX
1027// 3 AUX_PLL_CLK
1028// 4 IF_ATT_SEL
1029// 5 GPIO[0]
1030// 6 GPIO[1]
1031// 7 GPIO[2]
1032
1033#define FLD_GPIO2_ALT_IN_SEL 0x00000F00
1034// 0 GPIO[2] <-- default
1035// 1 IR_RX
1036// 2 IR_TX
1037// 3 AUX_PLL_CLK
1038// 4 IF_ATT_SEL
1039
1040#define FLD_GPIO1_ALT_IN_SEL 0x000000F0
1041// 0 GPIO[1] <-- default
1042// 1 IR_RX
1043// 2 IR_TX
1044// 3 AUX_PLL_CLK
1045// 4 IF_ATT_SEL
1046
1047#define FLD_GPIO0_ALT_IN_SEL 0x0000000F
1048// 0 GPIO[0] <-- default
1049// 1 IR_RX
1050// 2 IR_TX
1051// 3 AUX_PLL_CLK
1052// 4 IF_ATT_SEL
1053
1054//*****************************************************************************
1055#define TEST_BUS_CTL1 0x110040 // Test bus control register #1
1056
1057//*****************************************************************************
1058#define TEST_BUS_CTL2 0x110044 // Test bus control register #2
1059
1060//*****************************************************************************
1061#define CLK_DELAY 0x110048 // Clock delay
1062#define FLD_MOE_CLK_DIS 0x80000000 // Disable MoE clock
1063
1064//*****************************************************************************
1065#define PAD_CTRL 0x110068 // Pad drive strength control
1066
1067//*****************************************************************************
1068#define MBIST_CTRL 0x110050 // SRAM memory built-in self test control
1069
1070//*****************************************************************************
1071#define MBIST_STAT 0x110054 // SRAM memory built-in self test status
1072
1073//*****************************************************************************
1074// PLL registers
1075//*****************************************************************************
1076#define PLL_A_INT_FRAC 0x110088
1077#define PLL_A_POST_STAT_BIST 0x11008C
1078#define PLL_B_INT_FRAC 0x110090
1079#define PLL_B_POST_STAT_BIST 0x110094
1080#define PLL_C_INT_FRAC 0x110098
1081#define PLL_C_POST_STAT_BIST 0x11009C
1082#define PLL_D_INT_FRAC 0x1100A0
1083#define PLL_D_POST_STAT_BIST 0x1100A4
1084
1085#define CLK_RST 0x11002C
1086#define FLD_VID_I_CLK_NOE 0x00001000
1087#define FLD_VID_J_CLK_NOE 0x00002000
1088#define FLD_USE_ALT_PLL_REF 0x00004000
1089
1090#define VID_CH_MODE_SEL 0x110078
1091#define VID_CH_CLK_SEL 0x11007C
1092
1093//*****************************************************************************
1094#define VBI_A_DMA 0x130008 // VBI A DMA data port
1095
1096//*****************************************************************************
1097#define VID_A_VIP_CTL 0x130080 // Video A VIP format control
1098#define FLD_VIP_MODE 0x00000001
1099
1100//*****************************************************************************
1101#define VID_A_PIXEL_FRMT 0x130084 // Video A pixel format
1102#define FLD_VID_A_GAMMA_DIS 0x00000008
1103#define FLD_VID_A_FORMAT 0x00000007
1104#define FLD_VID_A_GAMMA_FACTOR 0x00000010
1105
1106//*****************************************************************************
1107#define VID_A_VBI_CTL 0x130088 // Video A VBI miscellaneous control
1108#define FLD_VID_A_VIP_EXT 0x00000003
1109
1110//*****************************************************************************
1111#define VID_B_DMA 0x130100 // Video B DMA data port
1112
1113//*****************************************************************************
1114#define VBI_B_DMA 0x130108 // VBI B DMA data port
1115
1116//*****************************************************************************
1117#define VID_B_SRC_SEL 0x130144 // Video B source select
1118#define FLD_VID_B_SRC_SEL 0x00000000
1119
1120//*****************************************************************************
1121#define VID_B_LNGTH 0x130150 // Video B line length
1122#define FLD_VID_B_LN_LNGTH 0x00000FFF
1123
1124//*****************************************************************************
1125#define VID_B_VIP_CTL 0x130180 // Video B VIP format control
1126
1127//*****************************************************************************
1128#define VID_B_PIXEL_FRMT 0x130184 // Video B pixel format
1129#define FLD_VID_B_GAMMA_DIS 0x00000008
1130#define FLD_VID_B_FORMAT 0x00000007
1131#define FLD_VID_B_GAMMA_FACTOR 0x00000010
1132
1133//*****************************************************************************
1134#define VID_C_DMA 0x130200 // Video C DMA data port
1135
1136//*****************************************************************************
1137#define VID_C_LNGTH 0x130250 // Video C line length
1138#define FLD_VID_C_LN_LNGTH 0x00000FFF
1139
1140//*****************************************************************************
1141// Video Destination Channels
1142//*****************************************************************************
1143
1144#define VID_DST_A_GPCNT 0x130020 // Video A general purpose counter
1145#define VID_DST_B_GPCNT 0x130120 // Video B general purpose counter
1146#define VID_DST_C_GPCNT 0x130220 // Video C general purpose counter
1147#define VID_DST_D_GPCNT 0x130320 // Video D general purpose counter
1148#define VID_DST_E_GPCNT 0x130420 // Video E general purpose counter
1149#define VID_DST_F_GPCNT 0x130520 // Video F general purpose counter
1150#define VID_DST_G_GPCNT 0x130620 // Video G general purpose counter
1151#define VID_DST_H_GPCNT 0x130720 // Video H general purpose counter
1152
1153//*****************************************************************************
1154
1155#define VID_DST_A_GPCNT_CTL 0x130030 // Video A general purpose control
1156#define VID_DST_B_GPCNT_CTL 0x130130 // Video B general purpose control
1157#define VID_DST_C_GPCNT_CTL 0x130230 // Video C general purpose control
1158#define VID_DST_D_GPCNT_CTL 0x130330 // Video D general purpose control
1159#define VID_DST_E_GPCNT_CTL 0x130430 // Video E general purpose control
1160#define VID_DST_F_GPCNT_CTL 0x130530 // Video F general purpose control
1161#define VID_DST_G_GPCNT_CTL 0x130630 // Video G general purpose control
1162#define VID_DST_H_GPCNT_CTL 0x130730 // Video H general purpose control
1163
1164//*****************************************************************************
1165
1166#define VID_DST_A_DMA_CTL 0x130040 // Video A DMA control
1167#define VID_DST_B_DMA_CTL 0x130140 // Video B DMA control
1168#define VID_DST_C_DMA_CTL 0x130240 // Video C DMA control
1169#define VID_DST_D_DMA_CTL 0x130340 // Video D DMA control
1170#define VID_DST_E_DMA_CTL 0x130440 // Video E DMA control
1171#define VID_DST_F_DMA_CTL 0x130540 // Video F DMA control
1172#define VID_DST_G_DMA_CTL 0x130640 // Video G DMA control
1173#define VID_DST_H_DMA_CTL 0x130740 // Video H DMA control
1174
1175#define FLD_VID_RISC_EN 0x00000010
1176#define FLD_VID_FIFO_EN 0x00000001
1177
1178//*****************************************************************************
1179
1180#define VID_DST_A_VIP_CTL 0x130080 // Video A VIP control
1181#define VID_DST_B_VIP_CTL 0x130180 // Video B VIP control
1182#define VID_DST_C_VIP_CTL 0x130280 // Video C VIP control
1183#define VID_DST_D_VIP_CTL 0x130380 // Video D VIP control
1184#define VID_DST_E_VIP_CTL 0x130480 // Video E VIP control
1185#define VID_DST_F_VIP_CTL 0x130580 // Video F VIP control
1186#define VID_DST_G_VIP_CTL 0x130680 // Video G VIP control
1187#define VID_DST_H_VIP_CTL 0x130780 // Video H VIP control
1188
1189//*****************************************************************************
1190
1191#define VID_DST_A_PIX_FRMT 0x130084 // Video A Pixel format
1192#define VID_DST_B_PIX_FRMT 0x130184 // Video B Pixel format
1193#define VID_DST_C_PIX_FRMT 0x130284 // Video C Pixel format
1194#define VID_DST_D_PIX_FRMT 0x130384 // Video D Pixel format
1195#define VID_DST_E_PIX_FRMT 0x130484 // Video E Pixel format
1196#define VID_DST_F_PIX_FRMT 0x130584 // Video F Pixel format
1197#define VID_DST_G_PIX_FRMT 0x130684 // Video G Pixel format
1198#define VID_DST_H_PIX_FRMT 0x130784 // Video H Pixel format
1199
1200//*****************************************************************************
1201// Video Source Channels
1202//*****************************************************************************
1203
1204#define VID_SRC_A_GPCNT_CTL 0x130804 // Video A general purpose control
1205#define VID_SRC_B_GPCNT_CTL 0x130904 // Video B general purpose control
1206#define VID_SRC_C_GPCNT_CTL 0x130A04 // Video C general purpose control
1207#define VID_SRC_D_GPCNT_CTL 0x130B04 // Video D general purpose control
1208#define VID_SRC_E_GPCNT_CTL 0x130C04 // Video E general purpose control
1209#define VID_SRC_F_GPCNT_CTL 0x130D04 // Video F general purpose control
1210#define VID_SRC_I_GPCNT_CTL 0x130E04 // Video I general purpose control
1211#define VID_SRC_J_GPCNT_CTL 0x130F04 // Video J general purpose control
1212
1213//*****************************************************************************
1214
1215#define VID_SRC_A_GPCNT 0x130808 // Video A general purpose counter
1216#define VID_SRC_B_GPCNT 0x130908 // Video B general purpose counter
1217#define VID_SRC_C_GPCNT 0x130A08 // Video C general purpose counter
1218#define VID_SRC_D_GPCNT 0x130B08 // Video D general purpose counter
1219#define VID_SRC_E_GPCNT 0x130C08 // Video E general purpose counter
1220#define VID_SRC_F_GPCNT 0x130D08 // Video F general purpose counter
1221#define VID_SRC_I_GPCNT 0x130E08 // Video I general purpose counter
1222#define VID_SRC_J_GPCNT 0x130F08 // Video J general purpose counter
1223
1224//*****************************************************************************
1225
1226#define VID_SRC_A_DMA_CTL 0x13080C // Video A DMA control
1227#define VID_SRC_B_DMA_CTL 0x13090C // Video B DMA control
1228#define VID_SRC_C_DMA_CTL 0x130A0C // Video C DMA control
1229#define VID_SRC_D_DMA_CTL 0x130B0C // Video D DMA control
1230#define VID_SRC_E_DMA_CTL 0x130C0C // Video E DMA control
1231#define VID_SRC_F_DMA_CTL 0x130D0C // Video F DMA control
1232#define VID_SRC_I_DMA_CTL 0x130E0C // Video I DMA control
1233#define VID_SRC_J_DMA_CTL 0x130F0C // Video J DMA control
1234
1235#define FLD_APB_RISC_EN 0x00000010
1236#define FLD_APB_FIFO_EN 0x00000001
1237
1238//*****************************************************************************
1239
1240#define VID_SRC_A_FMT_CTL 0x130810 // Video A format control
1241#define VID_SRC_B_FMT_CTL 0x130910 // Video B format control
1242#define VID_SRC_C_FMT_CTL 0x130A10 // Video C format control
1243#define VID_SRC_D_FMT_CTL 0x130B10 // Video D format control
1244#define VID_SRC_E_FMT_CTL 0x130C10 // Video E format control
1245#define VID_SRC_F_FMT_CTL 0x130D10 // Video F format control
1246#define VID_SRC_I_FMT_CTL 0x130E10 // Video I format control
1247#define VID_SRC_J_FMT_CTL 0x130F10 // Video J format control
1248
1249//*****************************************************************************
1250
1251#define VID_SRC_A_ACTIVE_CTL1 0x130814 // Video A active control 1
1252#define VID_SRC_B_ACTIVE_CTL1 0x130914 // Video B active control 1
1253#define VID_SRC_C_ACTIVE_CTL1 0x130A14 // Video C active control 1
1254#define VID_SRC_D_ACTIVE_CTL1 0x130B14 // Video D active control 1
1255#define VID_SRC_E_ACTIVE_CTL1 0x130C14 // Video E active control 1
1256#define VID_SRC_F_ACTIVE_CTL1 0x130D14 // Video F active control 1
1257#define VID_SRC_I_ACTIVE_CTL1 0x130E14 // Video I active control 1
1258#define VID_SRC_J_ACTIVE_CTL1 0x130F14 // Video J active control 1
1259
1260//*****************************************************************************
1261
1262#define VID_SRC_A_ACTIVE_CTL2 0x130818 // Video A active control 2
1263#define VID_SRC_B_ACTIVE_CTL2 0x130918 // Video B active control 2
1264#define VID_SRC_C_ACTIVE_CTL2 0x130A18 // Video C active control 2
1265#define VID_SRC_D_ACTIVE_CTL2 0x130B18 // Video D active control 2
1266#define VID_SRC_E_ACTIVE_CTL2 0x130C18 // Video E active control 2
1267#define VID_SRC_F_ACTIVE_CTL2 0x130D18 // Video F active control 2
1268#define VID_SRC_I_ACTIVE_CTL2 0x130E18 // Video I active control 2
1269#define VID_SRC_J_ACTIVE_CTL2 0x130F18 // Video J active control 2
1270
1271//*****************************************************************************
1272
1273#define VID_SRC_A_CDT_SZ 0x13081C // Video A CDT size
1274#define VID_SRC_B_CDT_SZ 0x13091C // Video B CDT size
1275#define VID_SRC_C_CDT_SZ 0x130A1C // Video C CDT size
1276#define VID_SRC_D_CDT_SZ 0x130B1C // Video D CDT size
1277#define VID_SRC_E_CDT_SZ 0x130C1C // Video E CDT size
1278#define VID_SRC_F_CDT_SZ 0x130D1C // Video F CDT size
1279#define VID_SRC_I_CDT_SZ 0x130E1C // Video I CDT size
1280#define VID_SRC_J_CDT_SZ 0x130F1C // Video J CDT size
1281
1282//*****************************************************************************
1283// Audio I/F
1284//*****************************************************************************
1285#define AUD_DST_A_DMA 0x140000 // Audio Int A DMA data port
1286#define AUD_SRC_A_DMA 0x140008 // Audio Int A DMA data port
1287
1288#define AUD_A_GPCNT 0x140010 // Audio Int A gp counter
1289#define FLD_AUD_A_GP_CNT 0x0000FFFF
1290
1291#define AUD_A_GPCNT_CTL 0x140014 // Audio Int A gp control
1292
1293#define AUD_A_LNGTH 0x140018 // Audio Int A line length
1294
1295#define AUD_A_CFG 0x14001C // Audio Int A configuration
1296
1297//*****************************************************************************
1298#define AUD_DST_B_DMA 0x140100 // Audio Int B DMA data port
1299#define AUD_SRC_B_DMA 0x140108 // Audio Int B DMA data port
1300
1301#define AUD_B_GPCNT 0x140110 // Audio Int B gp counter
1302#define FLD_AUD_B_GP_CNT 0x0000FFFF
1303
1304#define AUD_B_GPCNT_CTL 0x140114 // Audio Int B gp control
1305
1306#define AUD_B_LNGTH 0x140118 // Audio Int B line length
1307
1308#define AUD_B_CFG 0x14011C // Audio Int B configuration
1309
1310//*****************************************************************************
1311#define AUD_DST_C_DMA 0x140200 // Audio Int C DMA data port
1312#define AUD_SRC_C_DMA 0x140208 // Audio Int C DMA data port
1313
1314#define AUD_C_GPCNT 0x140210 // Audio Int C gp counter
1315#define FLD_AUD_C_GP_CNT 0x0000FFFF
1316
1317#define AUD_C_GPCNT_CTL 0x140214 // Audio Int C gp control
1318
1319#define AUD_C_LNGTH 0x140218 // Audio Int C line length
1320
1321#define AUD_C_CFG 0x14021C // Audio Int C configuration
1322
1323//*****************************************************************************
1324#define AUD_DST_D_DMA 0x140300 // Audio Int D DMA data port
1325#define AUD_SRC_D_DMA 0x140308 // Audio Int D DMA data port
1326
1327#define AUD_D_GPCNT 0x140310 // Audio Int D gp counter
1328#define FLD_AUD_D_GP_CNT 0x0000FFFF
1329
1330#define AUD_D_GPCNT_CTL 0x140314 // Audio Int D gp control
1331
1332#define AUD_D_LNGTH 0x140318 // Audio Int D line length
1333
1334#define AUD_D_CFG 0x14031C // Audio Int D configuration
1335
1336//*****************************************************************************
1337#define AUD_SRC_E_DMA 0x140400 // Audio Int E DMA data port
1338
1339#define AUD_E_GPCNT 0x140410 // Audio Int E gp counter
1340#define FLD_AUD_E_GP_CNT 0x0000FFFF
1341
1342#define AUD_E_GPCNT_CTL 0x140414 // Audio Int E gp control
1343
1344#define AUD_E_CFG 0x14041C // Audio Int E configuration
1345
1346//*****************************************************************************
1347
1348#define FLD_AUD_DST_LN_LNGTH 0x00000FFF
1349
1350#define FLD_AUD_DST_PK_MODE 0x00004000
1351
1352#define FLD_AUD_CLK_ENABLE 0x00000200
1353
1354#define FLD_AUD_MASTER_MODE 0x00000002
1355
1356#define FLD_AUD_SONY_MODE 0x00000001
1357
1358#define FLD_AUD_CLK_SELECT_PLL_D 0x00001800
1359
1360#define FLD_AUD_DST_ENABLE 0x00020000
1361
1362#define FLD_AUD_SRC_ENABLE 0x00010000
1363
1364//*****************************************************************************
1365#define AUD_INT_DMA_CTL 0x140500 // Audio Int DMA control
1366
1367#define FLD_AUD_SRC_E_RISC_EN 0x00008000
1368#define FLD_AUD_SRC_C_RISC_EN 0x00004000
1369#define FLD_AUD_SRC_B_RISC_EN 0x00002000
1370#define FLD_AUD_SRC_A_RISC_EN 0x00001000
1371
1372#define FLD_AUD_DST_D_RISC_EN 0x00000800
1373#define FLD_AUD_DST_C_RISC_EN 0x00000400
1374#define FLD_AUD_DST_B_RISC_EN 0x00000200
1375#define FLD_AUD_DST_A_RISC_EN 0x00000100
1376
1377#define FLD_AUD_SRC_E_FIFO_EN 0x00000080
1378#define FLD_AUD_SRC_C_FIFO_EN 0x00000040
1379#define FLD_AUD_SRC_B_FIFO_EN 0x00000020
1380#define FLD_AUD_SRC_A_FIFO_EN 0x00000010
1381
1382#define FLD_AUD_DST_D_FIFO_EN 0x00000008
1383#define FLD_AUD_DST_C_FIFO_EN 0x00000004
1384#define FLD_AUD_DST_B_FIFO_EN 0x00000002
1385#define FLD_AUD_DST_A_FIFO_EN 0x00000001
1386
1387//*****************************************************************************
1388//
1389// Mobilygen Interface Registers
1390//
1391//*****************************************************************************
1392// Mobilygen Interface A
1393//*****************************************************************************
1394#define MB_IF_A_DMA 0x150000 // MBIF A DMA data port
1395#define MB_IF_A_GPCN 0x150008 // MBIF A GP counter
1396#define MB_IF_A_GPCN_CTRL 0x15000C
1397#define MB_IF_A_DMA_CTRL 0x150010
1398#define MB_IF_A_LENGTH 0x150014
1399#define MB_IF_A_HDMA_XFER_SZ 0x150018
1400#define MB_IF_A_HCMD 0x15001C
1401#define MB_IF_A_HCONFIG 0x150020
1402#define MB_IF_A_DATA_STRUCT_0 0x150024
1403#define MB_IF_A_DATA_STRUCT_1 0x150028
1404#define MB_IF_A_DATA_STRUCT_2 0x15002C
1405#define MB_IF_A_DATA_STRUCT_3 0x150030
1406#define MB_IF_A_DATA_STRUCT_4 0x150034
1407#define MB_IF_A_DATA_STRUCT_5 0x150038
1408#define MB_IF_A_DATA_STRUCT_6 0x15003C
1409#define MB_IF_A_DATA_STRUCT_7 0x150040
1410#define MB_IF_A_DATA_STRUCT_8 0x150044
1411#define MB_IF_A_DATA_STRUCT_9 0x150048
1412#define MB_IF_A_DATA_STRUCT_A 0x15004C
1413#define MB_IF_A_DATA_STRUCT_B 0x150050
1414#define MB_IF_A_DATA_STRUCT_C 0x150054
1415#define MB_IF_A_DATA_STRUCT_D 0x150058
1416#define MB_IF_A_DATA_STRUCT_E 0x15005C
1417#define MB_IF_A_DATA_STRUCT_F 0x150060
1418//*****************************************************************************
1419// Mobilygen Interface B
1420//*****************************************************************************
1421#define MB_IF_B_DMA 0x160000 // MBIF A DMA data port
1422#define MB_IF_B_GPCN 0x160008 // MBIF A GP counter
1423#define MB_IF_B_GPCN_CTRL 0x16000C
1424#define MB_IF_B_DMA_CTRL 0x160010
1425#define MB_IF_B_LENGTH 0x160014
1426#define MB_IF_B_HDMA_XFER_SZ 0x160018
1427#define MB_IF_B_HCMD 0x16001C
1428#define MB_IF_B_HCONFIG 0x160020
1429#define MB_IF_B_DATA_STRUCT_0 0x160024
1430#define MB_IF_B_DATA_STRUCT_1 0x160028
1431#define MB_IF_B_DATA_STRUCT_2 0x16002C
1432#define MB_IF_B_DATA_STRUCT_3 0x160030
1433#define MB_IF_B_DATA_STRUCT_4 0x160034
1434#define MB_IF_B_DATA_STRUCT_5 0x160038
1435#define MB_IF_B_DATA_STRUCT_6 0x16003C
1436#define MB_IF_B_DATA_STRUCT_7 0x160040
1437#define MB_IF_B_DATA_STRUCT_8 0x160044
1438#define MB_IF_B_DATA_STRUCT_9 0x160048
1439#define MB_IF_B_DATA_STRUCT_A 0x16004C
1440#define MB_IF_B_DATA_STRUCT_B 0x160050
1441#define MB_IF_B_DATA_STRUCT_C 0x160054
1442#define MB_IF_B_DATA_STRUCT_D 0x160058
1443#define MB_IF_B_DATA_STRUCT_E 0x16005C
1444#define MB_IF_B_DATA_STRUCT_F 0x160060
1445
1446// MB_DMA_CTRL
1447#define FLD_MB_IF_RISC_EN 0x00000010
1448#define FLD_MB_IF_FIFO_EN 0x00000001
1449
1450// MB_LENGTH
1451#define FLD_MB_IF_LN_LNGTH 0x00000FFF
1452
1453// MB_HCMD register
1454#define FLD_MB_HCMD_H_GO 0x80000000
1455#define FLD_MB_HCMD_H_BUSY 0x40000000
1456#define FLD_MB_HCMD_H_DMA_HOLD 0x10000000
1457#define FLD_MB_HCMD_H_DMA_BUSY 0x08000000
1458#define FLD_MB_HCMD_H_DMA_TYPE 0x04000000
1459#define FLD_MB_HCMD_H_DMA_XACT 0x02000000
1460#define FLD_MB_HCMD_H_RW_N 0x01000000
1461#define FLD_MB_HCMD_H_ADDR 0x00FF0000
1462#define FLD_MB_HCMD_H_DATA 0x0000FFFF
1463
1464//*****************************************************************************
1465// I2C #1
1466//*****************************************************************************
1467#define I2C1_ADDR 0x180000 // I2C #1 address
1468#define FLD_I2C_DADDR 0xfe000000 // RW [31:25] I2C Device Address
1469 // RO [24] reserved
1470//*****************************************************************************
1471#define FLD_I2C_SADDR 0x00FFFFFF // RW [23:0] I2C Sub-address
1472
1473//*****************************************************************************
1474#define I2C1_WDATA 0x180004 // I2C #1 write data
1475#define FLD_I2C_WDATA 0xFFFFFFFF // RW [31:0]
1476
1477//*****************************************************************************
1478#define I2C1_CTRL 0x180008 // I2C #1 control
1479#define FLD_I2C_PERIOD 0xFF000000 // RW [31:24]
1480#define FLD_I2C_SCL_IN 0x00200000 // RW [21]
1481#define FLD_I2C_SDA_IN 0x00100000 // RW [20]
1482 // RO [19:18] reserved
1483#define FLD_I2C_SCL_OUT 0x00020000 // RW [17]
1484#define FLD_I2C_SDA_OUT 0x00010000 // RW [16]
1485 // RO [15] reserved
1486#define FLD_I2C_DATA_LEN 0x00007000 // RW [14:12]
1487#define FLD_I2C_SADDR_INC 0x00000800 // RW [11]
1488 // RO [10:9] reserved
1489#define FLD_I2C_SADDR_LEN 0x00000300 // RW [9:8]
1490 // RO [7:6] reserved
1491#define FLD_I2C_SOFT 0x00000020 // RW [5]
1492#define FLD_I2C_NOSTOP 0x00000010 // RW [4]
1493#define FLD_I2C_EXTEND 0x00000008 // RW [3]
1494#define FLD_I2C_SYNC 0x00000004 // RW [2]
1495#define FLD_I2C_READ_SA 0x00000002 // RW [1]
1496#define FLD_I2C_READ_WRN 0x00000001 // RW [0]
1497
1498//*****************************************************************************
1499#define I2C1_RDATA 0x18000C // I2C #1 read data
1500#define FLD_I2C_RDATA 0xFFFFFFFF // RO [31:0]
1501
1502//*****************************************************************************
1503#define I2C1_STAT 0x180010 // I2C #1 status
1504#define FLD_I2C_XFER_IN_PROG 0x00000002 // RO [1]
1505#define FLD_I2C_RACK 0x00000001 // RO [0]
1506
1507//*****************************************************************************
1508// I2C #2
1509//*****************************************************************************
1510#define I2C2_ADDR 0x190000 // I2C #2 address
1511
1512//*****************************************************************************
1513#define I2C2_WDATA 0x190004 // I2C #2 write data
1514
1515//*****************************************************************************
1516#define I2C2_CTRL 0x190008 // I2C #2 control
1517
1518//*****************************************************************************
1519#define I2C2_RDATA 0x19000C // I2C #2 read data
1520
1521//*****************************************************************************
1522#define I2C2_STAT 0x190010 // I2C #2 status
1523
1524//*****************************************************************************
1525// I2C #3
1526//*****************************************************************************
1527#define I2C3_ADDR 0x1A0000 // I2C #3 address
1528
1529//*****************************************************************************
1530#define I2C3_WDATA 0x1A0004 // I2C #3 write data
1531
1532//*****************************************************************************
1533#define I2C3_CTRL 0x1A0008 // I2C #3 control
1534
1535//*****************************************************************************
1536#define I2C3_RDATA 0x1A000C // I2C #3 read data
1537
1538//*****************************************************************************
1539#define I2C3_STAT 0x1A0010 // I2C #3 status
1540
1541//*****************************************************************************
1542// UART
1543//*****************************************************************************
1544#define UART_CTL 0x1B0000 // UART Control Register
1545#define FLD_LOOP_BACK_EN (1 << 7) // RW field - default 0
1546#define FLD_RX_TRG_SZ (3 << 2) // RW field - default 0
1547#define FLD_RX_EN (1 << 1) // RW field - default 0
1548#define FLD_TX_EN (1 << 0) // RW field - default 0
1549
1550//*****************************************************************************
1551#define UART_BRD 0x1B0004 // UART Baud Rate Divisor
1552#define FLD_BRD 0x0000FFFF // RW field - default 0x197
1553
1554//*****************************************************************************
1555#define UART_DBUF 0x1B0008 // UART Tx/Rx Data BuFFer
1556#define FLD_DB 0xFFFFFFFF // RW field - default 0
1557
1558//*****************************************************************************
1559#define UART_ISR 0x1B000C // UART Interrupt Status
1560#define FLD_RXD_TIMEOUT_EN (1 << 7) // RW field - default 0
1561#define FLD_FRM_ERR_EN (1 << 6) // RW field - default 0
1562#define FLD_RXD_RDY_EN (1 << 5) // RW field - default 0
1563#define FLD_TXD_EMPTY_EN (1 << 4) // RW field - default 0
1564#define FLD_RXD_OVERFLOW (1 << 3) // RW field - default 0
1565#define FLD_FRM_ERR (1 << 2) // RW field - default 0
1566#define FLD_RXD_RDY (1 << 1) // RW field - default 0
1567#define FLD_TXD_EMPTY (1 << 0) // RW field - default 0
1568
1569//*****************************************************************************
1570#define UART_CNT 0x1B0010 // UART Tx/Rx FIFO Byte Count
1571#define FLD_TXD_CNT (0x1F << 8) // RW field - default 0
1572#define FLD_RXD_CNT (0x1F << 0) // RW field - default 0
1573
1574//*****************************************************************************
1575// Motion Detection
1576#define MD_CH0_GRID_BLOCK_YCNT 0x170014
1577#define MD_CH1_GRID_BLOCK_YCNT 0x170094
1578#define MD_CH2_GRID_BLOCK_YCNT 0x170114
1579#define MD_CH3_GRID_BLOCK_YCNT 0x170194
1580#define MD_CH4_GRID_BLOCK_YCNT 0x170214
1581#define MD_CH5_GRID_BLOCK_YCNT 0x170294
1582#define MD_CH6_GRID_BLOCK_YCNT 0x170314
1583#define MD_CH7_GRID_BLOCK_YCNT 0x170394
1584
1585#define PIXEL_FRMT_422 4
1586#define PIXEL_FRMT_411 5
1587#define PIXEL_FRMT_Y8 6
1588
1589#define PIXEL_ENGINE_VIP1 0
1590#define PIXEL_ENGINE_VIP2 1
1591
1592#endif //Athena_REGISTERS
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/staging/cx25821/cx25821-sram.h
new file mode 100644
index 000000000000..bd677ee22996
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-sram.h
@@ -0,0 +1,261 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef __ATHENA_SRAM_H__
24#define __ATHENA_SRAM_H__
25
26//#define RX_SRAM_START_SIZE = 0; // Start of reserved SRAM
27#define VID_CMDS_SIZE 80 // Video CMDS size in bytes
28#define AUDIO_CMDS_SIZE 80 // AUDIO CMDS size in bytes
29#define MBIF_CMDS_SIZE 80 // MBIF CMDS size in bytes
30
31//#define RX_SRAM_POOL_START_SIZE = 0; // Start of useable RX SRAM for buffers
32#define VID_IQ_SIZE 64 // VID instruction queue size in bytes
33#define MBIF_IQ_SIZE 64
34#define AUDIO_IQ_SIZE 64 // AUD instruction queue size in bytes
35
36#define VID_CDT_SIZE 64 // VID cluster descriptor table size in bytes
37#define MBIF_CDT_SIZE 64 // MBIF/HBI cluster descriptor table size in bytes
38#define AUDIO_CDT_SIZE 48 // AUD cluster descriptor table size in bytes
39
40//#define RX_SRAM_POOL_FREE_SIZE = 16; // Start of available RX SRAM
41//#define RX_SRAM_END_SIZE = 0; // End of RX SRAM
42
43//#define TX_SRAM_POOL_START_SIZE = 0; // Start of transmit pool SRAM
44//#define MSI_DATA_SIZE = 64; // Reserved (MSI Data, RISC working stora
45
46#define VID_CLUSTER_SIZE 1440 // VID cluster data line
47#define AUDIO_CLUSTER_SIZE 128 // AUDIO cluster data line
48#define MBIF_CLUSTER_SIZE 1440 // MBIF/HBI cluster data line
49
50//#define TX_SRAM_POOL_FREE_SIZE = 704; // Start of available TX SRAM
51//#define TX_SRAM_END_SIZE = 0; // End of TX SRAM
52
53// Receive SRAM
54#define RX_SRAM_START 0x10000
55#define VID_A_DOWN_CMDS 0x10000
56#define VID_B_DOWN_CMDS 0x10050
57#define VID_C_DOWN_CMDS 0x100A0
58#define VID_D_DOWN_CMDS 0x100F0
59#define VID_E_DOWN_CMDS 0x10140
60#define VID_F_DOWN_CMDS 0x10190
61#define VID_G_DOWN_CMDS 0x101E0
62#define VID_H_DOWN_CMDS 0x10230
63#define VID_A_UP_CMDS 0x10280
64#define VID_B_UP_CMDS 0x102D0
65#define VID_C_UP_CMDS 0x10320
66#define VID_D_UP_CMDS 0x10370
67#define VID_E_UP_CMDS 0x103C0
68#define VID_F_UP_CMDS 0x10410
69#define VID_I_UP_CMDS 0x10460
70#define VID_J_UP_CMDS 0x104B0
71#define AUD_A_DOWN_CMDS 0x10500
72#define AUD_B_DOWN_CMDS 0x10550
73#define AUD_C_DOWN_CMDS 0x105A0
74#define AUD_D_DOWN_CMDS 0x105F0
75#define AUD_A_UP_CMDS 0x10640
76#define AUD_B_UP_CMDS 0x10690
77#define AUD_C_UP_CMDS 0x106E0
78#define AUD_E_UP_CMDS 0x10730
79#define MBIF_A_DOWN_CMDS 0x10780
80#define MBIF_B_DOWN_CMDS 0x107D0
81#define DMA_SCRATCH_PAD 0x10820 // Scratch pad area from 0x10820 to 0x10B40
82
83//#define RX_SRAM_POOL_START = 0x105B0;
84
85#define VID_A_IQ 0x11000
86#define VID_B_IQ 0x11040
87#define VID_C_IQ 0x11080
88#define VID_D_IQ 0x110C0
89#define VID_E_IQ 0x11100
90#define VID_F_IQ 0x11140
91#define VID_G_IQ 0x11180
92#define VID_H_IQ 0x111C0
93#define VID_I_IQ 0x11200
94#define VID_J_IQ 0x11240
95#define AUD_A_IQ 0x11280
96#define AUD_B_IQ 0x112C0
97#define AUD_C_IQ 0x11300
98#define AUD_D_IQ 0x11340
99#define AUD_E_IQ 0x11380
100#define MBIF_A_IQ 0x11000
101#define MBIF_B_IQ 0x110C0
102
103#define VID_A_CDT 0x10C00
104#define VID_B_CDT 0x10C40
105#define VID_C_CDT 0x10C80
106#define VID_D_CDT 0x10CC0
107#define VID_E_CDT 0x10D00
108#define VID_F_CDT 0x10D40
109#define VID_G_CDT 0x10D80
110#define VID_H_CDT 0x10DC0
111#define VID_I_CDT 0x10E00
112#define VID_J_CDT 0x10E40
113#define AUD_A_CDT 0x10E80
114#define AUD_B_CDT 0x10EB0
115#define AUD_C_CDT 0x10EE0
116#define AUD_D_CDT 0x10F10
117#define AUD_E_CDT 0x10F40
118#define MBIF_A_CDT 0x10C00
119#define MBIF_B_CDT 0x10CC0
120
121// Cluster Buffer for RX
122#define VID_A_UP_CLUSTER_1 0x11400
123#define VID_A_UP_CLUSTER_2 0x119A0
124#define VID_A_UP_CLUSTER_3 0x11F40
125#define VID_A_UP_CLUSTER_4 0x124E0
126
127#define VID_B_UP_CLUSTER_1 0x12A80
128#define VID_B_UP_CLUSTER_2 0x13020
129#define VID_B_UP_CLUSTER_3 0x135C0
130#define VID_B_UP_CLUSTER_4 0x13B60
131
132#define VID_C_UP_CLUSTER_1 0x14100
133#define VID_C_UP_CLUSTER_2 0x146A0
134#define VID_C_UP_CLUSTER_3 0x14C40
135#define VID_C_UP_CLUSTER_4 0x151E0
136
137#define VID_D_UP_CLUSTER_1 0x15780
138#define VID_D_UP_CLUSTER_2 0x15D20
139#define VID_D_UP_CLUSTER_3 0x162C0
140#define VID_D_UP_CLUSTER_4 0x16860
141
142#define VID_E_UP_CLUSTER_1 0x16E00
143#define VID_E_UP_CLUSTER_2 0x173A0
144#define VID_E_UP_CLUSTER_3 0x17940
145#define VID_E_UP_CLUSTER_4 0x17EE0
146
147#define VID_F_UP_CLUSTER_1 0x18480
148#define VID_F_UP_CLUSTER_2 0x18A20
149#define VID_F_UP_CLUSTER_3 0x18FC0
150#define VID_F_UP_CLUSTER_4 0x19560
151
152#define VID_I_UP_CLUSTER_1 0x19B00
153#define VID_I_UP_CLUSTER_2 0x1A0A0
154#define VID_I_UP_CLUSTER_3 0x1A640
155#define VID_I_UP_CLUSTER_4 0x1ABE0
156
157#define VID_J_UP_CLUSTER_1 0x1B180
158#define VID_J_UP_CLUSTER_2 0x1B720
159#define VID_J_UP_CLUSTER_3 0x1BCC0
160#define VID_J_UP_CLUSTER_4 0x1C260
161
162#define AUD_A_UP_CLUSTER_1 0x1C800
163#define AUD_A_UP_CLUSTER_2 0x1C880
164#define AUD_A_UP_CLUSTER_3 0x1C900
165
166#define AUD_B_UP_CLUSTER_1 0x1C980
167#define AUD_B_UP_CLUSTER_2 0x1CA00
168#define AUD_B_UP_CLUSTER_3 0x1CA80
169
170#define AUD_C_UP_CLUSTER_1 0x1CB00
171#define AUD_C_UP_CLUSTER_2 0x1CB80
172#define AUD_C_UP_CLUSTER_3 0x1CC00
173
174#define AUD_E_UP_CLUSTER_1 0x1CC80
175#define AUD_E_UP_CLUSTER_2 0x1CD00
176#define AUD_E_UP_CLUSTER_3 0x1CD80
177
178#define RX_SRAM_POOL_FREE 0x1CE00
179#define RX_SRAM_END 0x1D000
180
181// Free Receive SRAM 144 Bytes
182
183// Transmit SRAM
184#define TX_SRAM_POOL_START 0x00000
185
186#define VID_A_DOWN_CLUSTER_1 0x00040
187#define VID_A_DOWN_CLUSTER_2 0x005E0
188#define VID_A_DOWN_CLUSTER_3 0x00B80
189#define VID_A_DOWN_CLUSTER_4 0x01120
190
191#define VID_B_DOWN_CLUSTER_1 0x016C0
192#define VID_B_DOWN_CLUSTER_2 0x01C60
193#define VID_B_DOWN_CLUSTER_3 0x02200
194#define VID_B_DOWN_CLUSTER_4 0x027A0
195
196#define VID_C_DOWN_CLUSTER_1 0x02D40
197#define VID_C_DOWN_CLUSTER_2 0x032E0
198#define VID_C_DOWN_CLUSTER_3 0x03880
199#define VID_C_DOWN_CLUSTER_4 0x03E20
200
201#define VID_D_DOWN_CLUSTER_1 0x043C0
202#define VID_D_DOWN_CLUSTER_2 0x04960
203#define VID_D_DOWN_CLUSTER_3 0x04F00
204#define VID_D_DOWN_CLUSTER_4 0x054A0
205
206#define VID_E_DOWN_CLUSTER_1 0x05a40
207#define VID_E_DOWN_CLUSTER_2 0x05FE0
208#define VID_E_DOWN_CLUSTER_3 0x06580
209#define VID_E_DOWN_CLUSTER_4 0x06B20
210
211#define VID_F_DOWN_CLUSTER_1 0x070C0
212#define VID_F_DOWN_CLUSTER_2 0x07660
213#define VID_F_DOWN_CLUSTER_3 0x07C00
214#define VID_F_DOWN_CLUSTER_4 0x081A0
215
216#define VID_G_DOWN_CLUSTER_1 0x08740
217#define VID_G_DOWN_CLUSTER_2 0x08CE0
218#define VID_G_DOWN_CLUSTER_3 0x09280
219#define VID_G_DOWN_CLUSTER_4 0x09820
220
221#define VID_H_DOWN_CLUSTER_1 0x09DC0
222#define VID_H_DOWN_CLUSTER_2 0x0A360
223#define VID_H_DOWN_CLUSTER_3 0x0A900
224#define VID_H_DOWN_CLUSTER_4 0x0AEA0
225
226#define AUD_A_DOWN_CLUSTER_1 0x0B500
227#define AUD_A_DOWN_CLUSTER_2 0x0B580
228#define AUD_A_DOWN_CLUSTER_3 0x0B600
229
230#define AUD_B_DOWN_CLUSTER_1 0x0B680
231#define AUD_B_DOWN_CLUSTER_2 0x0B700
232#define AUD_B_DOWN_CLUSTER_3 0x0B780
233
234#define AUD_C_DOWN_CLUSTER_1 0x0B800
235#define AUD_C_DOWN_CLUSTER_2 0x0B880
236#define AUD_C_DOWN_CLUSTER_3 0x0B900
237
238#define AUD_D_DOWN_CLUSTER_1 0x0B980
239#define AUD_D_DOWN_CLUSTER_2 0x0BA00
240#define AUD_D_DOWN_CLUSTER_3 0x0BA80
241
242#define TX_SRAM_POOL_FREE 0x0BB00
243#define TX_SRAM_END 0x0C000
244
245#define BYTES_TO_DWORDS(bcount) ((bcount) >> 2)
246#define BYTES_TO_QWORDS(bcount) ((bcount) >> 3)
247#define BYTES_TO_OWORDS(bcount) ((bcount) >> 4)
248
249#define VID_IQ_SIZE_DW BYTES_TO_DWORDS(VID_IQ_SIZE)
250#define VID_CDT_SIZE_QW BYTES_TO_QWORDS(VID_CDT_SIZE)
251#define VID_CLUSTER_SIZE_OW BYTES_TO_OWORDS(VID_CLUSTER_SIZE)
252
253#define AUDIO_IQ_SIZE_DW BYTES_TO_DWORDS(AUDIO_IQ_SIZE)
254#define AUDIO_CDT_SIZE_QW BYTES_TO_QWORDS(AUDIO_CDT_SIZE)
255#define AUDIO_CLUSTER_SIZE_QW BYTES_TO_QWORDS(AUDIO_CLUSTER_SIZE)
256
257#define MBIF_IQ_SIZE_DW BYTES_TO_DWORDS(MBIF_IQ_SIZE)
258#define MBIF_CDT_SIZE_QW BYTES_TO_QWORDS(MBIF_CDT_SIZE)
259#define MBIF_CLUSTER_SIZE_OW BYTES_TO_OWORDS(MBIF_CLUSTER_SIZE)
260
261#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
new file mode 100644
index 000000000000..c8905e0ac509
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
@@ -0,0 +1,835 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821-video.h"
24#include "cx25821-video-upstream-ch2.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <asm/uaccess.h>
35
36MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
37MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
38MODULE_LICENSE("GPL");
39
40static int _intr_msk =
41 FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
42
43static __le32 *cx25821_update_riscprogram_ch2(struct cx25821_dev *dev,
44 __le32 * rp, unsigned int offset,
45 unsigned int bpl, u32 sync_line,
46 unsigned int lines,
47 int fifo_enable, int field_type)
48{
49 unsigned int line, i;
50 int dist_betwn_starts = bpl * 2;
51
52 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
53
54 if (USE_RISC_NOOP_VIDEO) {
55 for (i = 0; i < NUM_NO_OPS; i++) {
56 *(rp++) = cpu_to_le32(RISC_NOOP);
57 }
58 }
59
60 /* scan lines */
61 for (line = 0; line < lines; line++) {
62 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
63 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr_ch2 + offset);
64 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
65
66 if ((lines <= NTSC_FIELD_HEIGHT)
67 || (line < (NTSC_FIELD_HEIGHT - 1))
68 || !(dev->_isNTSC_ch2)) {
69 offset += dist_betwn_starts;
70 }
71 }
72
73 return rp;
74}
75
76static __le32 *cx25821_risc_field_upstream_ch2(struct cx25821_dev *dev,
77 __le32 * rp,
78 dma_addr_t databuf_phys_addr,
79 unsigned int offset,
80 u32 sync_line, unsigned int bpl,
81 unsigned int lines,
82 int fifo_enable, int field_type)
83{
84 unsigned int line, i;
85 struct sram_channel *sram_ch =
86 &dev->sram_channels[dev->_channel2_upstream_select];
87 int dist_betwn_starts = bpl * 2;
88
89 /* sync instruction */
90 if (sync_line != NO_SYNC_LINE) {
91 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
92 }
93
94 if (USE_RISC_NOOP_VIDEO) {
95 for (i = 0; i < NUM_NO_OPS; i++) {
96 *(rp++) = cpu_to_le32(RISC_NOOP);
97 }
98 }
99
100 /* scan lines */
101 for (line = 0; line < lines; line++) {
102 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
103 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
104 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
105
106 if ((lines <= NTSC_FIELD_HEIGHT)
107 || (line < (NTSC_FIELD_HEIGHT - 1))
108 || !(dev->_isNTSC_ch2)) {
109 offset += dist_betwn_starts;
110 }
111
112 // check if we need to enable the FIFO after the first 4 lines
113 // For the upstream video channel, the risc engine will enable the FIFO.
114 if (fifo_enable && line == 3) {
115 *(rp++) = RISC_WRITECR;
116 *(rp++) = sram_ch->dma_ctl;
117 *(rp++) = FLD_VID_FIFO_EN;
118 *(rp++) = 0x00000001;
119 }
120 }
121
122 return rp;
123}
124
125int cx25821_risc_buffer_upstream_ch2(struct cx25821_dev *dev,
126 struct pci_dev *pci,
127 unsigned int top_offset, unsigned int bpl,
128 unsigned int lines)
129{
130 __le32 *rp;
131 int fifo_enable = 0;
132 int singlefield_lines = lines >> 1; //get line count for single field
133 int odd_num_lines = singlefield_lines;
134 int frame = 0;
135 int frame_size = 0;
136 int databuf_offset = 0;
137 int risc_program_size = 0;
138 int risc_flag = RISC_CNT_RESET;
139 unsigned int bottom_offset = bpl;
140 dma_addr_t risc_phys_jump_addr;
141
142 if (dev->_isNTSC_ch2) {
143 odd_num_lines = singlefield_lines + 1;
144 risc_program_size = FRAME1_VID_PROG_SIZE;
145 frame_size =
146 (bpl ==
147 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
148 FRAME_SIZE_NTSC_Y422;
149 } else {
150 risc_program_size = PAL_VID_PROG_SIZE;
151 frame_size =
152 (bpl ==
153 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
154 }
155
156 /* Virtual address of Risc buffer program */
157 rp = dev->_dma_virt_addr_ch2;
158
159 for (frame = 0; frame < NUM_FRAMES; frame++) {
160 databuf_offset = frame_size * frame;
161
162 if (UNSET != top_offset) {
163 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
164 rp = cx25821_risc_field_upstream_ch2(dev, rp,
165 dev->
166 _data_buf_phys_addr_ch2
167 + databuf_offset,
168 top_offset, 0, bpl,
169 odd_num_lines,
170 fifo_enable,
171 ODD_FIELD);
172 }
173
174 fifo_enable = FIFO_DISABLE;
175
176 //Even field
177 rp = cx25821_risc_field_upstream_ch2(dev, rp,
178 dev->
179 _data_buf_phys_addr_ch2 +
180 databuf_offset,
181 bottom_offset, 0x200, bpl,
182 singlefield_lines,
183 fifo_enable, EVEN_FIELD);
184
185 if (frame == 0) {
186 risc_flag = RISC_CNT_RESET;
187 risc_phys_jump_addr =
188 dev->_dma_phys_start_addr_ch2 + risc_program_size;
189 } else {
190 risc_flag = RISC_CNT_INC;
191 risc_phys_jump_addr = dev->_dma_phys_start_addr_ch2;
192 }
193
194 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
195 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
196 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
197 *(rp++) = cpu_to_le32(0);
198 }
199
200 return 0;
201}
202
203void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev)
204{
205 struct sram_channel *sram_ch =
206 &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_J];
207 u32 tmp = 0;
208
209 if (!dev->_is_running_ch2) {
210 printk
211 ("cx25821: No video file is currently running so return!\n");
212 return;
213 }
214 //Disable RISC interrupts
215 tmp = cx_read(sram_ch->int_msk);
216 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
217
218 //Turn OFF risc and fifo
219 tmp = cx_read(sram_ch->dma_ctl);
220 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
221
222 //Clear data buffer memory
223 if (dev->_data_buf_virt_addr_ch2)
224 memset(dev->_data_buf_virt_addr_ch2, 0,
225 dev->_data_buf_size_ch2);
226
227 dev->_is_running_ch2 = 0;
228 dev->_is_first_frame_ch2 = 0;
229 dev->_frame_count_ch2 = 0;
230 dev->_file_status_ch2 = END_OF_FILE;
231
232 if (dev->_irq_queues_ch2) {
233 kfree(dev->_irq_queues_ch2);
234 dev->_irq_queues_ch2 = NULL;
235 }
236
237 if (dev->_filename_ch2 != NULL)
238 kfree(dev->_filename_ch2);
239
240 tmp = cx_read(VID_CH_MODE_SEL);
241 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
242}
243
244void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev)
245{
246 if (dev->_is_running_ch2) {
247 cx25821_stop_upstream_video_ch2(dev);
248 }
249
250 if (dev->_dma_virt_addr_ch2) {
251 pci_free_consistent(dev->pci, dev->_risc_size_ch2,
252 dev->_dma_virt_addr_ch2,
253 dev->_dma_phys_addr_ch2);
254 dev->_dma_virt_addr_ch2 = NULL;
255 }
256
257 if (dev->_data_buf_virt_addr_ch2) {
258 pci_free_consistent(dev->pci, dev->_data_buf_size_ch2,
259 dev->_data_buf_virt_addr_ch2,
260 dev->_data_buf_phys_addr_ch2);
261 dev->_data_buf_virt_addr_ch2 = NULL;
262 }
263}
264
265int cx25821_get_frame_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
266{
267 struct file *myfile;
268 int frame_index_temp = dev->_frame_index_ch2;
269 int i = 0;
270 int line_size =
271 (dev->_pixel_format_ch2 ==
272 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
273 int frame_size = 0;
274 int frame_offset = 0;
275 ssize_t vfs_read_retval = 0;
276 char mybuf[line_size];
277 loff_t file_offset;
278 loff_t pos;
279 mm_segment_t old_fs;
280
281 if (dev->_file_status_ch2 == END_OF_FILE)
282 return 0;
283
284 if (dev->_isNTSC_ch2) {
285 frame_size =
286 (line_size ==
287 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
288 FRAME_SIZE_NTSC_Y422;
289 } else {
290 frame_size =
291 (line_size ==
292 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
293 }
294
295 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
296 file_offset = dev->_frame_count_ch2 * frame_size;
297
298 myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
299
300 if (IS_ERR(myfile)) {
301 const int open_errno = -PTR_ERR(myfile);
302 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
303 __func__, dev->_filename_ch2, open_errno);
304 return PTR_ERR(myfile);
305 } else {
306 if (!(myfile->f_op)) {
307 printk("%s: File has no file operations registered!",
308 __func__);
309 filp_close(myfile, NULL);
310 return -EIO;
311 }
312
313 if (!myfile->f_op->read) {
314 printk("%s: File has no READ operations registered!",
315 __func__);
316 filp_close(myfile, NULL);
317 return -EIO;
318 }
319
320 pos = myfile->f_pos;
321 old_fs = get_fs();
322 set_fs(KERNEL_DS);
323
324 for (i = 0; i < dev->_lines_count_ch2; i++) {
325 pos = file_offset;
326
327 vfs_read_retval =
328 vfs_read(myfile, mybuf, line_size, &pos);
329
330 if (vfs_read_retval > 0 && vfs_read_retval == line_size
331 && dev->_data_buf_virt_addr_ch2 != NULL) {
332 memcpy((void *)(dev->_data_buf_virt_addr_ch2 +
333 frame_offset / 4), mybuf,
334 vfs_read_retval);
335 }
336
337 file_offset += vfs_read_retval;
338 frame_offset += vfs_read_retval;
339
340 if (vfs_read_retval < line_size) {
341 printk(KERN_INFO
342 "Done: exit %s() since no more bytes to read from Video file.\n",
343 __func__);
344 break;
345 }
346 }
347
348 if (i > 0)
349 dev->_frame_count_ch2++;
350
351 dev->_file_status_ch2 =
352 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
353
354 set_fs(old_fs);
355 filp_close(myfile, NULL);
356 }
357
358 return 0;
359}
360
361static void cx25821_vidups_handler_ch2(struct work_struct *work)
362{
363 struct cx25821_dev *dev =
364 container_of(work, struct cx25821_dev, _irq_work_entry_ch2);
365
366 if (!dev) {
367 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
368 __func__);
369 return;
370 }
371
372 cx25821_get_frame_ch2(dev,
373 &dev->sram_channels[dev->
374 _channel2_upstream_select]);
375}
376
377int cx25821_openfile_ch2(struct cx25821_dev *dev, struct sram_channel *sram_ch)
378{
379 struct file *myfile;
380 int i = 0, j = 0;
381 int line_size =
382 (dev->_pixel_format_ch2 ==
383 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
384 ssize_t vfs_read_retval = 0;
385 char mybuf[line_size];
386 loff_t pos;
387 loff_t offset = (unsigned long)0;
388 mm_segment_t old_fs;
389
390 myfile = filp_open(dev->_filename_ch2, O_RDONLY | O_LARGEFILE, 0);
391
392 if (IS_ERR(myfile)) {
393 const int open_errno = -PTR_ERR(myfile);
394 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
395 __func__, dev->_filename_ch2, open_errno);
396 return PTR_ERR(myfile);
397 } else {
398 if (!(myfile->f_op)) {
399 printk("%s: File has no file operations registered!",
400 __func__);
401 filp_close(myfile, NULL);
402 return -EIO;
403 }
404
405 if (!myfile->f_op->read) {
406 printk
407 ("%s: File has no READ operations registered! Returning.",
408 __func__);
409 filp_close(myfile, NULL);
410 return -EIO;
411 }
412
413 pos = myfile->f_pos;
414 old_fs = get_fs();
415 set_fs(KERNEL_DS);
416
417 for (j = 0; j < NUM_FRAMES; j++) {
418 for (i = 0; i < dev->_lines_count_ch2; i++) {
419 pos = offset;
420
421 vfs_read_retval =
422 vfs_read(myfile, mybuf, line_size, &pos);
423
424 if (vfs_read_retval > 0
425 && vfs_read_retval == line_size
426 && dev->_data_buf_virt_addr_ch2 != NULL) {
427 memcpy((void *)(dev->
428 _data_buf_virt_addr_ch2
429 + offset / 4), mybuf,
430 vfs_read_retval);
431 }
432
433 offset += vfs_read_retval;
434
435 if (vfs_read_retval < line_size) {
436 printk(KERN_INFO
437 "Done: exit %s() since no more bytes to read from Video file.\n",
438 __func__);
439 break;
440 }
441 }
442
443 if (i > 0)
444 dev->_frame_count_ch2++;
445
446 if (vfs_read_retval < line_size) {
447 break;
448 }
449 }
450
451 dev->_file_status_ch2 =
452 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
453
454 set_fs(old_fs);
455 myfile->f_pos = 0;
456 filp_close(myfile, NULL);
457 }
458
459 return 0;
460}
461
462static int cx25821_upstream_buffer_prepare_ch2(struct cx25821_dev *dev,
463 struct sram_channel *sram_ch,
464 int bpl)
465{
466 int ret = 0;
467 dma_addr_t dma_addr;
468 dma_addr_t data_dma_addr;
469
470 if (dev->_dma_virt_addr_ch2 != NULL) {
471 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
472 dev->_dma_virt_addr_ch2,
473 dev->_dma_phys_addr_ch2);
474 }
475
476 dev->_dma_virt_addr_ch2 =
477 pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size_ch2,
478 &dma_addr);
479 dev->_dma_virt_start_addr_ch2 = dev->_dma_virt_addr_ch2;
480 dev->_dma_phys_start_addr_ch2 = dma_addr;
481 dev->_dma_phys_addr_ch2 = dma_addr;
482 dev->_risc_size_ch2 = dev->upstream_riscbuf_size_ch2;
483
484 if (!dev->_dma_virt_addr_ch2) {
485 printk
486 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
487 return -ENOMEM;
488 }
489
490 //Iniitize at this address until n bytes to 0
491 memset(dev->_dma_virt_addr_ch2, 0, dev->_risc_size_ch2);
492
493 if (dev->_data_buf_virt_addr_ch2 != NULL) {
494 pci_free_consistent(dev->pci, dev->upstream_databuf_size_ch2,
495 dev->_data_buf_virt_addr_ch2,
496 dev->_data_buf_phys_addr_ch2);
497 }
498 //For Video Data buffer allocation
499 dev->_data_buf_virt_addr_ch2 =
500 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size_ch2,
501 &data_dma_addr);
502 dev->_data_buf_phys_addr_ch2 = data_dma_addr;
503 dev->_data_buf_size_ch2 = dev->upstream_databuf_size_ch2;
504
505 if (!dev->_data_buf_virt_addr_ch2) {
506 printk
507 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
508 return -ENOMEM;
509 }
510
511 //Initialize at this address until n bytes to 0
512 memset(dev->_data_buf_virt_addr_ch2, 0, dev->_data_buf_size_ch2);
513
514 ret = cx25821_openfile_ch2(dev, sram_ch);
515 if (ret < 0)
516 return ret;
517
518 //Creating RISC programs
519 ret =
520 cx25821_risc_buffer_upstream_ch2(dev, dev->pci, 0, bpl,
521 dev->_lines_count_ch2);
522 if (ret < 0) {
523 printk(KERN_INFO
524 "cx25821: Failed creating Video Upstream Risc programs! \n");
525 goto error;
526 }
527
528 return 0;
529
530 error:
531 return ret;
532}
533
534int cx25821_video_upstream_irq_ch2(struct cx25821_dev *dev, int chan_num,
535 u32 status)
536{
537 u32 int_msk_tmp;
538 struct sram_channel *channel = &dev->sram_channels[chan_num];
539 int singlefield_lines = NTSC_FIELD_HEIGHT;
540 int line_size_in_bytes = Y422_LINE_SZ;
541 int odd_risc_prog_size = 0;
542 dma_addr_t risc_phys_jump_addr;
543 __le32 *rp;
544
545 if (status & FLD_VID_SRC_RISC1) {
546 // We should only process one program per call
547 u32 prog_cnt = cx_read(channel->gpcnt);
548
549 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
550 int_msk_tmp = cx_read(channel->int_msk);
551 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
552 cx_write(channel->int_stat, _intr_msk);
553
554 spin_lock(&dev->slock);
555
556 dev->_frame_index_ch2 = prog_cnt;
557
558 queue_work(dev->_irq_queues_ch2, &dev->_irq_work_entry_ch2);
559
560 if (dev->_is_first_frame_ch2) {
561 dev->_is_first_frame_ch2 = 0;
562
563 if (dev->_isNTSC_ch2) {
564 singlefield_lines += 1;
565 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
566 } else {
567 singlefield_lines = PAL_FIELD_HEIGHT;
568 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
569 }
570
571 if (dev->_dma_virt_start_addr_ch2 != NULL) {
572 line_size_in_bytes =
573 (dev->_pixel_format_ch2 ==
574 PIXEL_FRMT_411) ? Y411_LINE_SZ :
575 Y422_LINE_SZ;
576 risc_phys_jump_addr =
577 dev->_dma_phys_start_addr_ch2 +
578 odd_risc_prog_size;
579
580 rp = cx25821_update_riscprogram_ch2(dev,
581 dev->
582 _dma_virt_start_addr_ch2,
583 TOP_OFFSET,
584 line_size_in_bytes,
585 0x0,
586 singlefield_lines,
587 FIFO_DISABLE,
588 ODD_FIELD);
589
590 // Jump to Even Risc program of 1st Frame
591 *(rp++) = cpu_to_le32(RISC_JUMP);
592 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
593 *(rp++) = cpu_to_le32(0);
594 }
595 }
596
597 spin_unlock(&dev->slock);
598 }
599
600 if (dev->_file_status_ch2 == END_OF_FILE) {
601 printk("cx25821: EOF Channel 2 Framecount = %d\n",
602 dev->_frame_count_ch2);
603 return -1;
604 }
605 //ElSE, set the interrupt mask register, re-enable irq.
606 int_msk_tmp = cx_read(channel->int_msk);
607 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
608
609 return 0;
610}
611
612static irqreturn_t cx25821_upstream_irq_ch2(int irq, void *dev_id)
613{
614 struct cx25821_dev *dev = dev_id;
615 u32 msk_stat, vid_status;
616 int handled = 0;
617 int channel_num = 0;
618 struct sram_channel *sram_ch;
619
620 if (!dev)
621 return -1;
622
623 channel_num = VID_UPSTREAM_SRAM_CHANNEL_J;
624
625 sram_ch = &dev->sram_channels[channel_num];
626
627 msk_stat = cx_read(sram_ch->int_mstat);
628 vid_status = cx_read(sram_ch->int_stat);
629
630 // Only deal with our interrupt
631 if (vid_status) {
632 handled =
633 cx25821_video_upstream_irq_ch2(dev, channel_num,
634 vid_status);
635 }
636
637 if (handled < 0) {
638 cx25821_stop_upstream_video_ch2(dev);
639 } else {
640 handled += handled;
641 }
642
643 return IRQ_RETVAL(handled);
644}
645
646static void cx25821_set_pixelengine_ch2(struct cx25821_dev *dev,
647 struct sram_channel *ch, int pix_format)
648{
649 int width = WIDTH_D1;
650 int height = dev->_lines_count_ch2;
651 int num_lines, odd_num_lines;
652 u32 value;
653 int vip_mode = PIXEL_ENGINE_VIP1;
654
655 value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
656 value &= 0xFFFFFFEF;
657 value |= dev->_isNTSC_ch2 ? 0 : 0x10;
658 cx_write(ch->vid_fmt_ctl, value);
659
660 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
661 cx_write(ch->vid_active_ctl1, width);
662
663 num_lines = (height / 2) & 0x3FF;
664 odd_num_lines = num_lines;
665
666 if (dev->_isNTSC_ch2) {
667 odd_num_lines += 1;
668 }
669
670 value = (num_lines << 16) | odd_num_lines;
671
672 // set number of active lines in field 0 (top) and field 1 (bottom)
673 cx_write(ch->vid_active_ctl2, value);
674
675 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
676}
677
678int cx25821_start_video_dma_upstream_ch2(struct cx25821_dev *dev,
679 struct sram_channel *sram_ch)
680{
681 u32 tmp = 0;
682 int err = 0;
683
684 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
685 tmp = cx_read(VID_CH_MODE_SEL);
686 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
687
688 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
689 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr_ch2);
690 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
691
692 /* reset counter */
693 cx_write(sram_ch->gpcnt_ctl, 3);
694
695 // Clear our bits from the interrupt status register.
696 cx_write(sram_ch->int_stat, _intr_msk);
697
698 //Set the interrupt mask register, enable irq.
699 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
700 tmp = cx_read(sram_ch->int_msk);
701 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
702
703 err =
704 request_irq(dev->pci->irq, cx25821_upstream_irq_ch2,
705 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
706 if (err < 0) {
707 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
708 dev->pci->irq);
709 goto fail_irq;
710 }
711 // Start the DMA engine
712 tmp = cx_read(sram_ch->dma_ctl);
713 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
714
715 dev->_is_running_ch2 = 1;
716 dev->_is_first_frame_ch2 = 1;
717
718 return 0;
719
720 fail_irq:
721 cx25821_dev_unregister(dev);
722 return err;
723}
724
725int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev, int channel_select,
726 int pixel_format)
727{
728 struct sram_channel *sram_ch;
729 u32 tmp;
730 int retval = 0;
731 int err = 0;
732 int data_frame_size = 0;
733 int risc_buffer_size = 0;
734 int str_length = 0;
735
736 if (dev->_is_running_ch2) {
737 printk("Video Channel is still running so return!\n");
738 return 0;
739 }
740
741 dev->_channel2_upstream_select = channel_select;
742 sram_ch = &dev->sram_channels[channel_select];
743
744 INIT_WORK(&dev->_irq_work_entry_ch2, cx25821_vidups_handler_ch2);
745 dev->_irq_queues_ch2 =
746 create_singlethread_workqueue("cx25821_workqueue2");
747
748 if (!dev->_irq_queues_ch2) {
749 printk
750 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
751 return -ENOMEM;
752 }
753 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
754 tmp = cx_read(VID_CH_MODE_SEL);
755 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
756
757 dev->_is_running_ch2 = 0;
758 dev->_frame_count_ch2 = 0;
759 dev->_file_status_ch2 = RESET_STATUS;
760 dev->_lines_count_ch2 = dev->_isNTSC_ch2 ? 480 : 576;
761 dev->_pixel_format_ch2 = pixel_format;
762 dev->_line_size_ch2 =
763 (dev->_pixel_format_ch2 ==
764 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
765 data_frame_size = dev->_isNTSC_ch2 ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
766 risc_buffer_size =
767 dev->_isNTSC_ch2 ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
768
769 if (dev->input_filename_ch2) {
770 str_length = strlen(dev->input_filename_ch2);
771 dev->_filename_ch2 =
772 (char *)kmalloc(str_length + 1, GFP_KERNEL);
773
774 if (!dev->_filename_ch2)
775 goto error;
776
777 memcpy(dev->_filename_ch2, dev->input_filename_ch2,
778 str_length + 1);
779 } else {
780 str_length = strlen(dev->_defaultname_ch2);
781 dev->_filename_ch2 =
782 (char *)kmalloc(str_length + 1, GFP_KERNEL);
783
784 if (!dev->_filename_ch2)
785 goto error;
786
787 memcpy(dev->_filename_ch2, dev->_defaultname_ch2,
788 str_length + 1);
789 }
790
791 //Default if filename is empty string
792 if (strcmp(dev->input_filename_ch2, "") == 0) {
793 if (dev->_isNTSC_ch2) {
794 dev->_filename_ch2 =
795 (dev->_pixel_format_ch2 ==
796 PIXEL_FRMT_411) ? "/root/vid411.yuv" :
797 "/root/vidtest.yuv";
798 } else {
799 dev->_filename_ch2 =
800 (dev->_pixel_format_ch2 ==
801 PIXEL_FRMT_411) ? "/root/pal411.yuv" :
802 "/root/pal422.yuv";
803 }
804 }
805
806 retval =
807 cx25821_sram_channel_setup_upstream(dev, sram_ch,
808 dev->_line_size_ch2, 0);
809
810 /* setup fifo + format */
811 cx25821_set_pixelengine_ch2(dev, sram_ch, dev->_pixel_format_ch2);
812
813 dev->upstream_riscbuf_size_ch2 = risc_buffer_size * 2;
814 dev->upstream_databuf_size_ch2 = data_frame_size * 2;
815
816 //Allocating buffers and prepare RISC program
817 retval =
818 cx25821_upstream_buffer_prepare_ch2(dev, sram_ch,
819 dev->_line_size_ch2);
820 if (retval < 0) {
821 printk(KERN_ERR
822 "%s: Failed to set up Video upstream buffers!\n",
823 dev->name);
824 goto error;
825 }
826
827 cx25821_start_video_dma_upstream_ch2(dev, sram_ch);
828
829 return 0;
830
831 error:
832 cx25821_dev_unregister(dev);
833
834 return err;
835}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
new file mode 100644
index 000000000000..73feea114c1c
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
@@ -0,0 +1,101 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define OPEN_FILE_1 0
27#define NUM_PROGS 8
28#define NUM_FRAMES 2
29#define ODD_FIELD 0
30#define EVEN_FIELD 1
31#define TOP_OFFSET 0
32#define FIFO_DISABLE 0
33#define FIFO_ENABLE 1
34#define TEST_FRAMES 5
35#define END_OF_FILE 0
36#define IN_PROGRESS 1
37#define RESET_STATUS -1
38#define NUM_NO_OPS 5
39
40// PAL and NTSC line sizes and number of lines.
41#define WIDTH_D1 720
42#define NTSC_LINES_PER_FRAME 480
43#define PAL_LINES_PER_FRAME 576
44#define PAL_LINE_SZ 1440
45#define Y422_LINE_SZ 1440
46#define Y411_LINE_SZ 1080
47#define NTSC_FIELD_HEIGHT 240
48#define NTSC_ODD_FLD_LINES 241
49#define PAL_FIELD_HEIGHT 288
50
51#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
52#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
53#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
54#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
55
56#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
57#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
58
59#define RISC_WRITECR_INSTRUCTION_SIZE 16
60#define RISC_SYNC_INSTRUCTION_SIZE 4
61#define JUMP_INSTRUCTION_SIZE 12
62#define MAXSIZE_NO_OPS 36
63#define DWORD_SIZE 4
64
65#define USE_RISC_NOOP_VIDEO 1
66
67#ifdef USE_RISC_NOOP_VIDEO
68#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
69 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
70
71#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
72
73#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
74 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
75
76#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
77 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
78
79#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
80 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
81
82#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
83
84#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
85 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
86#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
87 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
88#endif
89
90#ifndef USE_RISC_NOOP_VIDEO
91#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
92#define PAL_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + PAL_US_VID_PROG_SIZE) )
93#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
94 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
95#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
96#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
97#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
98#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
99#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
100 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
101#endif
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/staging/cx25821/cx25821-video-upstream.c
new file mode 100644
index 000000000000..3d7dd3f66541
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.c
@@ -0,0 +1,894 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include "cx25821-video.h"
24#include "cx25821-video-upstream.h"
25
26#include <linux/fs.h>
27#include <linux/errno.h>
28#include <linux/kernel.h>
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/syscalls.h>
32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <asm/uaccess.h>
35
36MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
37MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
38MODULE_LICENSE("GPL");
39
40static int _intr_msk =
41 FLD_VID_SRC_RISC1 | FLD_VID_SRC_UF | FLD_VID_SRC_SYNC | FLD_VID_SRC_OPC_ERR;
42
43int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
44 struct sram_channel *ch,
45 unsigned int bpl, u32 risc)
46{
47 unsigned int i, lines;
48 u32 cdt;
49
50 if (ch->cmds_start == 0) {
51 cx_write(ch->ptr1_reg, 0);
52 cx_write(ch->ptr2_reg, 0);
53 cx_write(ch->cnt2_reg, 0);
54 cx_write(ch->cnt1_reg, 0);
55 return 0;
56 }
57
58 bpl = (bpl + 7) & ~7; /* alignment */
59 cdt = ch->cdt;
60 lines = ch->fifo_size / bpl;
61
62 if (lines > 4) {
63 lines = 4;
64 }
65
66 BUG_ON(lines < 2);
67
68 /* write CDT */
69 for (i = 0; i < lines; i++) {
70 cx_write(cdt + 16 * i, ch->fifo_start + bpl * i);
71 cx_write(cdt + 16 * i + 4, 0);
72 cx_write(cdt + 16 * i + 8, 0);
73 cx_write(cdt + 16 * i + 12, 0);
74 }
75
76 /* write CMDS */
77 cx_write(ch->cmds_start + 0, risc);
78
79 cx_write(ch->cmds_start + 4, 0);
80 cx_write(ch->cmds_start + 8, cdt);
81 cx_write(ch->cmds_start + 12, (lines * 16) >> 3);
82 cx_write(ch->cmds_start + 16, ch->ctrl_start);
83
84 cx_write(ch->cmds_start + 20, VID_IQ_SIZE_DW);
85
86 for (i = 24; i < 80; i += 4)
87 cx_write(ch->cmds_start + i, 0);
88
89 /* fill registers */
90 cx_write(ch->ptr1_reg, ch->fifo_start);
91 cx_write(ch->ptr2_reg, cdt);
92 cx_write(ch->cnt2_reg, (lines * 16) >> 3);
93 cx_write(ch->cnt1_reg, (bpl >> 3) - 1);
94
95 return 0;
96}
97
98static __le32 *cx25821_update_riscprogram(struct cx25821_dev *dev,
99 __le32 * rp, unsigned int offset,
100 unsigned int bpl, u32 sync_line,
101 unsigned int lines, int fifo_enable,
102 int field_type)
103{
104 unsigned int line, i;
105 int dist_betwn_starts = bpl * 2;
106
107 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
108
109 if (USE_RISC_NOOP_VIDEO) {
110 for (i = 0; i < NUM_NO_OPS; i++) {
111 *(rp++) = cpu_to_le32(RISC_NOOP);
112 }
113 }
114
115 /* scan lines */
116 for (line = 0; line < lines; line++) {
117 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
118 *(rp++) = cpu_to_le32(dev->_data_buf_phys_addr + offset);
119 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
120
121 if ((lines <= NTSC_FIELD_HEIGHT)
122 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
123 offset += dist_betwn_starts;
124 }
125 }
126
127 return rp;
128}
129
130static __le32 *cx25821_risc_field_upstream(struct cx25821_dev *dev, __le32 * rp,
131 dma_addr_t databuf_phys_addr,
132 unsigned int offset, u32 sync_line,
133 unsigned int bpl, unsigned int lines,
134 int fifo_enable, int field_type)
135{
136 unsigned int line, i;
137 struct sram_channel *sram_ch =
138 &dev->sram_channels[dev->_channel_upstream_select];
139 int dist_betwn_starts = bpl * 2;
140
141 /* sync instruction */
142 if (sync_line != NO_SYNC_LINE) {
143 *(rp++) = cpu_to_le32(RISC_RESYNC | sync_line);
144 }
145
146 if (USE_RISC_NOOP_VIDEO) {
147 for (i = 0; i < NUM_NO_OPS; i++) {
148 *(rp++) = cpu_to_le32(RISC_NOOP);
149 }
150 }
151
152 /* scan lines */
153 for (line = 0; line < lines; line++) {
154 *(rp++) = cpu_to_le32(RISC_READ | RISC_SOL | RISC_EOL | bpl);
155 *(rp++) = cpu_to_le32(databuf_phys_addr + offset);
156 *(rp++) = cpu_to_le32(0); /* bits 63-32 */
157
158 if ((lines <= NTSC_FIELD_HEIGHT)
159 || (line < (NTSC_FIELD_HEIGHT - 1)) || !(dev->_isNTSC)) {
160 offset += dist_betwn_starts; //to skip the other field line
161 }
162
163 // check if we need to enable the FIFO after the first 4 lines
164 // For the upstream video channel, the risc engine will enable the FIFO.
165 if (fifo_enable && line == 3) {
166 *(rp++) = RISC_WRITECR;
167 *(rp++) = sram_ch->dma_ctl;
168 *(rp++) = FLD_VID_FIFO_EN;
169 *(rp++) = 0x00000001;
170 }
171 }
172
173 return rp;
174}
175
176int cx25821_risc_buffer_upstream(struct cx25821_dev *dev,
177 struct pci_dev *pci,
178 unsigned int top_offset,
179 unsigned int bpl, unsigned int lines)
180{
181 __le32 *rp;
182 int fifo_enable = 0;
183 int singlefield_lines = lines >> 1; //get line count for single field
184 int odd_num_lines = singlefield_lines;
185 int frame = 0;
186 int frame_size = 0;
187 int databuf_offset = 0;
188 int risc_program_size = 0;
189 int risc_flag = RISC_CNT_RESET;
190 unsigned int bottom_offset = bpl;
191 dma_addr_t risc_phys_jump_addr;
192
193 if (dev->_isNTSC) {
194 odd_num_lines = singlefield_lines + 1;
195 risc_program_size = FRAME1_VID_PROG_SIZE;
196 frame_size =
197 (bpl ==
198 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
199 FRAME_SIZE_NTSC_Y422;
200 } else {
201 risc_program_size = PAL_VID_PROG_SIZE;
202 frame_size =
203 (bpl ==
204 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
205 }
206
207 /* Virtual address of Risc buffer program */
208 rp = dev->_dma_virt_addr;
209
210 for (frame = 0; frame < NUM_FRAMES; frame++) {
211 databuf_offset = frame_size * frame;
212
213 if (UNSET != top_offset) {
214 fifo_enable = (frame == 0) ? FIFO_ENABLE : FIFO_DISABLE;
215 rp = cx25821_risc_field_upstream(dev, rp,
216 dev->
217 _data_buf_phys_addr +
218 databuf_offset,
219 top_offset, 0, bpl,
220 odd_num_lines,
221 fifo_enable,
222 ODD_FIELD);
223 }
224
225 fifo_enable = FIFO_DISABLE;
226
227 //Even Field
228 rp = cx25821_risc_field_upstream(dev, rp,
229 dev->_data_buf_phys_addr +
230 databuf_offset, bottom_offset,
231 0x200, bpl, singlefield_lines,
232 fifo_enable, EVEN_FIELD);
233
234 if (frame == 0) {
235 risc_flag = RISC_CNT_RESET;
236 risc_phys_jump_addr =
237 dev->_dma_phys_start_addr + risc_program_size;
238 } else {
239 risc_phys_jump_addr = dev->_dma_phys_start_addr;
240 risc_flag = RISC_CNT_INC;
241 }
242
243 // Loop to 2ndFrameRISC or to Start of Risc program & generate IRQ
244 *(rp++) = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | risc_flag);
245 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
246 *(rp++) = cpu_to_le32(0);
247 }
248
249 return 0;
250}
251
252void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev)
253{
254 struct sram_channel *sram_ch =
255 &dev->sram_channels[VID_UPSTREAM_SRAM_CHANNEL_I];
256 u32 tmp = 0;
257
258 if (!dev->_is_running) {
259 printk
260 ("cx25821: No video file is currently running so return!\n");
261 return;
262 }
263 //Disable RISC interrupts
264 tmp = cx_read(sram_ch->int_msk);
265 cx_write(sram_ch->int_msk, tmp & ~_intr_msk);
266
267 //Turn OFF risc and fifo enable
268 tmp = cx_read(sram_ch->dma_ctl);
269 cx_write(sram_ch->dma_ctl, tmp & ~(FLD_VID_FIFO_EN | FLD_VID_RISC_EN));
270
271 //Clear data buffer memory
272 if (dev->_data_buf_virt_addr)
273 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
274
275 dev->_is_running = 0;
276 dev->_is_first_frame = 0;
277 dev->_frame_count = 0;
278 dev->_file_status = END_OF_FILE;
279
280 if (dev->_irq_queues) {
281 kfree(dev->_irq_queues);
282 dev->_irq_queues = NULL;
283 }
284
285 if (dev->_filename != NULL)
286 kfree(dev->_filename);
287
288 tmp = cx_read(VID_CH_MODE_SEL);
289 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
290}
291
292void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev)
293{
294 if (dev->_is_running) {
295 cx25821_stop_upstream_video_ch1(dev);
296 }
297
298 if (dev->_dma_virt_addr) {
299 pci_free_consistent(dev->pci, dev->_risc_size,
300 dev->_dma_virt_addr, dev->_dma_phys_addr);
301 dev->_dma_virt_addr = NULL;
302 }
303
304 if (dev->_data_buf_virt_addr) {
305 pci_free_consistent(dev->pci, dev->_data_buf_size,
306 dev->_data_buf_virt_addr,
307 dev->_data_buf_phys_addr);
308 dev->_data_buf_virt_addr = NULL;
309 }
310}
311
312int cx25821_get_frame(struct cx25821_dev *dev, struct sram_channel *sram_ch)
313{
314 struct file *myfile;
315 int frame_index_temp = dev->_frame_index;
316 int i = 0;
317 int line_size =
318 (dev->_pixel_format ==
319 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
320 int frame_size = 0;
321 int frame_offset = 0;
322 ssize_t vfs_read_retval = 0;
323 char mybuf[line_size];
324 loff_t file_offset;
325 loff_t pos;
326 mm_segment_t old_fs;
327
328 if (dev->_file_status == END_OF_FILE)
329 return 0;
330
331 if (dev->_isNTSC) {
332 frame_size =
333 (line_size ==
334 Y411_LINE_SZ) ? FRAME_SIZE_NTSC_Y411 :
335 FRAME_SIZE_NTSC_Y422;
336 } else {
337 frame_size =
338 (line_size ==
339 Y411_LINE_SZ) ? FRAME_SIZE_PAL_Y411 : FRAME_SIZE_PAL_Y422;
340 }
341
342 frame_offset = (frame_index_temp > 0) ? frame_size : 0;
343 file_offset = dev->_frame_count * frame_size;
344
345 myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
346
347 if (IS_ERR(myfile)) {
348 const int open_errno = -PTR_ERR(myfile);
349 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
350 __func__, dev->_filename, open_errno);
351 return PTR_ERR(myfile);
352 } else {
353 if (!(myfile->f_op)) {
354 printk("%s: File has no file operations registered!",
355 __func__);
356 filp_close(myfile, NULL);
357 return -EIO;
358 }
359
360 if (!myfile->f_op->read) {
361 printk("%s: File has no READ operations registered!",
362 __func__);
363 filp_close(myfile, NULL);
364 return -EIO;
365 }
366
367 pos = myfile->f_pos;
368 old_fs = get_fs();
369 set_fs(KERNEL_DS);
370
371 for (i = 0; i < dev->_lines_count; i++) {
372 pos = file_offset;
373
374 vfs_read_retval =
375 vfs_read(myfile, mybuf, line_size, &pos);
376
377 if (vfs_read_retval > 0 && vfs_read_retval == line_size
378 && dev->_data_buf_virt_addr != NULL) {
379 memcpy((void *)(dev->_data_buf_virt_addr +
380 frame_offset / 4), mybuf,
381 vfs_read_retval);
382 }
383
384 file_offset += vfs_read_retval;
385 frame_offset += vfs_read_retval;
386
387 if (vfs_read_retval < line_size) {
388 printk(KERN_INFO
389 "Done: exit %s() since no more bytes to read from Video file.\n",
390 __func__);
391 break;
392 }
393 }
394
395 if (i > 0)
396 dev->_frame_count++;
397
398 dev->_file_status =
399 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
400
401 set_fs(old_fs);
402 filp_close(myfile, NULL);
403 }
404
405 return 0;
406}
407
408static void cx25821_vidups_handler(struct work_struct *work)
409{
410 struct cx25821_dev *dev =
411 container_of(work, struct cx25821_dev, _irq_work_entry);
412
413 if (!dev) {
414 printk("ERROR %s(): since container_of(work_struct) FAILED! \n",
415 __func__);
416 return;
417 }
418
419 cx25821_get_frame(dev,
420 &dev->sram_channels[dev->_channel_upstream_select]);
421}
422
423int cx25821_openfile(struct cx25821_dev *dev, struct sram_channel *sram_ch)
424{
425 struct file *myfile;
426 int i = 0, j = 0;
427 int line_size =
428 (dev->_pixel_format ==
429 PIXEL_FRMT_411) ? Y411_LINE_SZ : Y422_LINE_SZ;
430 ssize_t vfs_read_retval = 0;
431 char mybuf[line_size];
432 loff_t pos;
433 loff_t offset = (unsigned long)0;
434 mm_segment_t old_fs;
435
436 myfile = filp_open(dev->_filename, O_RDONLY | O_LARGEFILE, 0);
437
438 if (IS_ERR(myfile)) {
439 const int open_errno = -PTR_ERR(myfile);
440 printk("%s(): ERROR opening file(%s) with errno = %d! \n",
441 __func__, dev->_filename, open_errno);
442 return PTR_ERR(myfile);
443 } else {
444 if (!(myfile->f_op)) {
445 printk("%s: File has no file operations registered!",
446 __func__);
447 filp_close(myfile, NULL);
448 return -EIO;
449 }
450
451 if (!myfile->f_op->read) {
452 printk
453 ("%s: File has no READ operations registered! Returning.",
454 __func__);
455 filp_close(myfile, NULL);
456 return -EIO;
457 }
458
459 pos = myfile->f_pos;
460 old_fs = get_fs();
461 set_fs(KERNEL_DS);
462
463 for (j = 0; j < NUM_FRAMES; j++) {
464 for (i = 0; i < dev->_lines_count; i++) {
465 pos = offset;
466
467 vfs_read_retval =
468 vfs_read(myfile, mybuf, line_size, &pos);
469
470 if (vfs_read_retval > 0
471 && vfs_read_retval == line_size
472 && dev->_data_buf_virt_addr != NULL) {
473 memcpy((void *)(dev->
474 _data_buf_virt_addr +
475 offset / 4), mybuf,
476 vfs_read_retval);
477 }
478
479 offset += vfs_read_retval;
480
481 if (vfs_read_retval < line_size) {
482 printk(KERN_INFO
483 "Done: exit %s() since no more bytes to read from Video file.\n",
484 __func__);
485 break;
486 }
487 }
488
489 if (i > 0)
490 dev->_frame_count++;
491
492 if (vfs_read_retval < line_size) {
493 break;
494 }
495 }
496
497 dev->_file_status =
498 (vfs_read_retval == line_size) ? IN_PROGRESS : END_OF_FILE;
499
500 set_fs(old_fs);
501 myfile->f_pos = 0;
502 filp_close(myfile, NULL);
503 }
504
505 return 0;
506}
507
508int cx25821_upstream_buffer_prepare(struct cx25821_dev *dev,
509 struct sram_channel *sram_ch, int bpl)
510{
511 int ret = 0;
512 dma_addr_t dma_addr;
513 dma_addr_t data_dma_addr;
514
515 if (dev->_dma_virt_addr != NULL) {
516 pci_free_consistent(dev->pci, dev->upstream_riscbuf_size,
517 dev->_dma_virt_addr, dev->_dma_phys_addr);
518 }
519
520 dev->_dma_virt_addr =
521 pci_alloc_consistent(dev->pci, dev->upstream_riscbuf_size,
522 &dma_addr);
523 dev->_dma_virt_start_addr = dev->_dma_virt_addr;
524 dev->_dma_phys_start_addr = dma_addr;
525 dev->_dma_phys_addr = dma_addr;
526 dev->_risc_size = dev->upstream_riscbuf_size;
527
528 if (!dev->_dma_virt_addr) {
529 printk
530 ("cx25821: FAILED to allocate memory for Risc buffer! Returning.\n");
531 return -ENOMEM;
532 }
533
534 //Clear memory at address
535 memset(dev->_dma_virt_addr, 0, dev->_risc_size);
536
537 if (dev->_data_buf_virt_addr != NULL) {
538 pci_free_consistent(dev->pci, dev->upstream_databuf_size,
539 dev->_data_buf_virt_addr,
540 dev->_data_buf_phys_addr);
541 }
542 //For Video Data buffer allocation
543 dev->_data_buf_virt_addr =
544 pci_alloc_consistent(dev->pci, dev->upstream_databuf_size,
545 &data_dma_addr);
546 dev->_data_buf_phys_addr = data_dma_addr;
547 dev->_data_buf_size = dev->upstream_databuf_size;
548
549 if (!dev->_data_buf_virt_addr) {
550 printk
551 ("cx25821: FAILED to allocate memory for data buffer! Returning.\n");
552 return -ENOMEM;
553 }
554
555 //Clear memory at address
556 memset(dev->_data_buf_virt_addr, 0, dev->_data_buf_size);
557
558 ret = cx25821_openfile(dev, sram_ch);
559 if (ret < 0)
560 return ret;
561
562 //Create RISC programs
563 ret =
564 cx25821_risc_buffer_upstream(dev, dev->pci, 0, bpl,
565 dev->_lines_count);
566 if (ret < 0) {
567 printk(KERN_INFO
568 "cx25821: Failed creating Video Upstream Risc programs! \n");
569 goto error;
570 }
571
572 return 0;
573
574 error:
575 return ret;
576}
577
578int cx25821_video_upstream_irq(struct cx25821_dev *dev, int chan_num,
579 u32 status)
580{
581 u32 int_msk_tmp;
582 struct sram_channel *channel = &dev->sram_channels[chan_num];
583 int singlefield_lines = NTSC_FIELD_HEIGHT;
584 int line_size_in_bytes = Y422_LINE_SZ;
585 int odd_risc_prog_size = 0;
586 dma_addr_t risc_phys_jump_addr;
587 __le32 *rp;
588
589 if (status & FLD_VID_SRC_RISC1) {
590 // We should only process one program per call
591 u32 prog_cnt = cx_read(channel->gpcnt);
592
593 //Since we've identified our IRQ, clear our bits from the interrupt mask and interrupt status registers
594 int_msk_tmp = cx_read(channel->int_msk);
595 cx_write(channel->int_msk, int_msk_tmp & ~_intr_msk);
596 cx_write(channel->int_stat, _intr_msk);
597
598 spin_lock(&dev->slock);
599
600 dev->_frame_index = prog_cnt;
601
602 queue_work(dev->_irq_queues, &dev->_irq_work_entry);
603
604 if (dev->_is_first_frame) {
605 dev->_is_first_frame = 0;
606
607 if (dev->_isNTSC) {
608 singlefield_lines += 1;
609 odd_risc_prog_size = ODD_FLD_NTSC_PROG_SIZE;
610 } else {
611 singlefield_lines = PAL_FIELD_HEIGHT;
612 odd_risc_prog_size = ODD_FLD_PAL_PROG_SIZE;
613 }
614
615 if (dev->_dma_virt_start_addr != NULL) {
616 line_size_in_bytes =
617 (dev->_pixel_format ==
618 PIXEL_FRMT_411) ? Y411_LINE_SZ :
619 Y422_LINE_SZ;
620 risc_phys_jump_addr =
621 dev->_dma_phys_start_addr +
622 odd_risc_prog_size;
623
624 rp = cx25821_update_riscprogram(dev,
625 dev->
626 _dma_virt_start_addr,
627 TOP_OFFSET,
628 line_size_in_bytes,
629 0x0,
630 singlefield_lines,
631 FIFO_DISABLE,
632 ODD_FIELD);
633
634 // Jump to Even Risc program of 1st Frame
635 *(rp++) = cpu_to_le32(RISC_JUMP);
636 *(rp++) = cpu_to_le32(risc_phys_jump_addr);
637 *(rp++) = cpu_to_le32(0);
638 }
639 }
640
641 spin_unlock(&dev->slock);
642 } else {
643 if (status & FLD_VID_SRC_UF)
644 printk
645 ("%s: Video Received Underflow Error Interrupt!\n",
646 __func__);
647
648 if (status & FLD_VID_SRC_SYNC)
649 printk("%s: Video Received Sync Error Interrupt!\n",
650 __func__);
651
652 if (status & FLD_VID_SRC_OPC_ERR)
653 printk("%s: Video Received OpCode Error Interrupt!\n",
654 __func__);
655 }
656
657 if (dev->_file_status == END_OF_FILE) {
658 printk("cx25821: EOF Channel 1 Framecount = %d\n",
659 dev->_frame_count);
660 return -1;
661 }
662 //ElSE, set the interrupt mask register, re-enable irq.
663 int_msk_tmp = cx_read(channel->int_msk);
664 cx_write(channel->int_msk, int_msk_tmp |= _intr_msk);
665
666 return 0;
667}
668
669static irqreturn_t cx25821_upstream_irq(int irq, void *dev_id)
670{
671 struct cx25821_dev *dev = dev_id;
672 u32 msk_stat, vid_status;
673 int handled = 0;
674 int channel_num = 0;
675 struct sram_channel *sram_ch;
676
677 if (!dev)
678 return -1;
679
680 channel_num = VID_UPSTREAM_SRAM_CHANNEL_I;
681
682 sram_ch = &dev->sram_channels[channel_num];
683
684 msk_stat = cx_read(sram_ch->int_mstat);
685 vid_status = cx_read(sram_ch->int_stat);
686
687 // Only deal with our interrupt
688 if (vid_status) {
689 handled =
690 cx25821_video_upstream_irq(dev, channel_num, vid_status);
691 }
692
693 if (handled < 0) {
694 cx25821_stop_upstream_video_ch1(dev);
695 } else {
696 handled += handled;
697 }
698
699 return IRQ_RETVAL(handled);
700}
701
702void cx25821_set_pixelengine(struct cx25821_dev *dev, struct sram_channel *ch,
703 int pix_format)
704{
705 int width = WIDTH_D1;
706 int height = dev->_lines_count;
707 int num_lines, odd_num_lines;
708 u32 value;
709 int vip_mode = OUTPUT_FRMT_656;
710
711 value = ((pix_format & 0x3) << 12) | (vip_mode & 0x7);
712 value &= 0xFFFFFFEF;
713 value |= dev->_isNTSC ? 0 : 0x10;
714 cx_write(ch->vid_fmt_ctl, value);
715
716 // set number of active pixels in each line. Default is 720 pixels in both NTSC and PAL format
717 cx_write(ch->vid_active_ctl1, width);
718
719 num_lines = (height / 2) & 0x3FF;
720 odd_num_lines = num_lines;
721
722 if (dev->_isNTSC) {
723 odd_num_lines += 1;
724 }
725
726 value = (num_lines << 16) | odd_num_lines;
727
728 // set number of active lines in field 0 (top) and field 1 (bottom)
729 cx_write(ch->vid_active_ctl2, value);
730
731 cx_write(ch->vid_cdt_size, VID_CDT_SIZE >> 3);
732}
733
734int cx25821_start_video_dma_upstream(struct cx25821_dev *dev,
735 struct sram_channel *sram_ch)
736{
737 u32 tmp = 0;
738 int err = 0;
739
740 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
741 tmp = cx_read(VID_CH_MODE_SEL);
742 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
743
744 // Set the physical start address of the RISC program in the initial program counter(IPC) member of the cmds.
745 cx_write(sram_ch->cmds_start + 0, dev->_dma_phys_addr);
746 cx_write(sram_ch->cmds_start + 4, 0); /* Risc IPC High 64 bits 63-32 */
747
748 /* reset counter */
749 cx_write(sram_ch->gpcnt_ctl, 3);
750
751 // Clear our bits from the interrupt status register.
752 cx_write(sram_ch->int_stat, _intr_msk);
753
754 //Set the interrupt mask register, enable irq.
755 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << sram_ch->irq_bit));
756 tmp = cx_read(sram_ch->int_msk);
757 cx_write(sram_ch->int_msk, tmp |= _intr_msk);
758
759 err =
760 request_irq(dev->pci->irq, cx25821_upstream_irq,
761 IRQF_SHARED | IRQF_DISABLED, dev->name, dev);
762 if (err < 0) {
763 printk(KERN_ERR "%s: can't get upstream IRQ %d\n", dev->name,
764 dev->pci->irq);
765 goto fail_irq;
766 }
767
768 // Start the DMA engine
769 tmp = cx_read(sram_ch->dma_ctl);
770 cx_set(sram_ch->dma_ctl, tmp | FLD_VID_RISC_EN);
771
772 dev->_is_running = 1;
773 dev->_is_first_frame = 1;
774
775 return 0;
776
777 fail_irq:
778 cx25821_dev_unregister(dev);
779 return err;
780}
781
782int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev, int channel_select,
783 int pixel_format)
784{
785 struct sram_channel *sram_ch;
786 u32 tmp;
787 int retval = 0;
788 int err = 0;
789 int data_frame_size = 0;
790 int risc_buffer_size = 0;
791 int str_length = 0;
792
793 if (dev->_is_running) {
794 printk("Video Channel is still running so return!\n");
795 return 0;
796 }
797
798 dev->_channel_upstream_select = channel_select;
799 sram_ch = &dev->sram_channels[channel_select];
800
801 INIT_WORK(&dev->_irq_work_entry, cx25821_vidups_handler);
802 dev->_irq_queues = create_singlethread_workqueue("cx25821_workqueue");
803
804 if (!dev->_irq_queues) {
805 printk
806 ("cx25821: create_singlethread_workqueue() for Video FAILED!\n");
807 return -ENOMEM;
808 }
809 // 656/VIP SRC Upstream Channel I & J and 7 - Host Bus Interface for channel A-C
810 tmp = cx_read(VID_CH_MODE_SEL);
811 cx_write(VID_CH_MODE_SEL, tmp | 0x1B0001FF);
812
813 dev->_is_running = 0;
814 dev->_frame_count = 0;
815 dev->_file_status = RESET_STATUS;
816 dev->_lines_count = dev->_isNTSC ? 480 : 576;
817 dev->_pixel_format = pixel_format;
818 dev->_line_size =
819 (dev->_pixel_format ==
820 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
821 data_frame_size = dev->_isNTSC ? NTSC_DATA_BUF_SZ : PAL_DATA_BUF_SZ;
822 risc_buffer_size =
823 dev->_isNTSC ? NTSC_RISC_BUF_SIZE : PAL_RISC_BUF_SIZE;
824
825 if (dev->input_filename) {
826 str_length = strlen(dev->input_filename);
827 dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
828
829 if (!dev->_filename)
830 goto error;
831
832 memcpy(dev->_filename, dev->input_filename, str_length + 1);
833 } else {
834 str_length = strlen(dev->_defaultname);
835 dev->_filename = (char *)kmalloc(str_length + 1, GFP_KERNEL);
836
837 if (!dev->_filename)
838 goto error;
839
840 memcpy(dev->_filename, dev->_defaultname, str_length + 1);
841 }
842
843 //Default if filename is empty string
844 if (strcmp(dev->input_filename, "") == 0) {
845 if (dev->_isNTSC) {
846 dev->_filename =
847 (dev->_pixel_format ==
848 PIXEL_FRMT_411) ? "/root/vid411.yuv" :
849 "/root/vidtest.yuv";
850 } else {
851 dev->_filename =
852 (dev->_pixel_format ==
853 PIXEL_FRMT_411) ? "/root/pal411.yuv" :
854 "/root/pal422.yuv";
855 }
856 }
857
858 dev->_is_running = 0;
859 dev->_frame_count = 0;
860 dev->_file_status = RESET_STATUS;
861 dev->_lines_count = dev->_isNTSC ? 480 : 576;
862 dev->_pixel_format = pixel_format;
863 dev->_line_size =
864 (dev->_pixel_format ==
865 PIXEL_FRMT_422) ? (WIDTH_D1 * 2) : (WIDTH_D1 * 3) / 2;
866
867 retval =
868 cx25821_sram_channel_setup_upstream(dev, sram_ch, dev->_line_size,
869 0);
870
871 /* setup fifo + format */
872 cx25821_set_pixelengine(dev, sram_ch, dev->_pixel_format);
873
874 dev->upstream_riscbuf_size = risc_buffer_size * 2;
875 dev->upstream_databuf_size = data_frame_size * 2;
876
877 //Allocating buffers and prepare RISC program
878 retval = cx25821_upstream_buffer_prepare(dev, sram_ch, dev->_line_size);
879 if (retval < 0) {
880 printk(KERN_ERR
881 "%s: Failed to set up Video upstream buffers!\n",
882 dev->name);
883 goto error;
884 }
885
886 cx25821_start_video_dma_upstream(dev, sram_ch);
887
888 return 0;
889
890 error:
891 cx25821_dev_unregister(dev);
892
893 return err;
894}
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/staging/cx25821/cx25821-video-upstream.h
new file mode 100644
index 000000000000..cc9f93842514
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video-upstream.h
@@ -0,0 +1,109 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <hiep.huynh@conexant.com>, <shu.lin@conexant.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 *
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/mutex.h>
24#include <linux/workqueue.h>
25
26#define OUTPUT_FRMT_656 0
27#define OPEN_FILE_1 0
28#define NUM_PROGS 8
29#define NUM_FRAMES 2
30#define ODD_FIELD 0
31#define EVEN_FIELD 1
32#define TOP_OFFSET 0
33#define FIFO_DISABLE 0
34#define FIFO_ENABLE 1
35#define TEST_FRAMES 5
36#define END_OF_FILE 0
37#define IN_PROGRESS 1
38#define RESET_STATUS -1
39#define NUM_NO_OPS 5
40
41// PAL and NTSC line sizes and number of lines.
42#define WIDTH_D1 720
43#define NTSC_LINES_PER_FRAME 480
44#define PAL_LINES_PER_FRAME 576
45#define PAL_LINE_SZ 1440
46#define Y422_LINE_SZ 1440
47#define Y411_LINE_SZ 1080
48#define NTSC_FIELD_HEIGHT 240
49#define NTSC_ODD_FLD_LINES 241
50#define PAL_FIELD_HEIGHT 288
51
52#define FRAME_SIZE_NTSC_Y422 (NTSC_LINES_PER_FRAME * Y422_LINE_SZ)
53#define FRAME_SIZE_NTSC_Y411 (NTSC_LINES_PER_FRAME * Y411_LINE_SZ)
54#define FRAME_SIZE_PAL_Y422 (PAL_LINES_PER_FRAME * Y422_LINE_SZ)
55#define FRAME_SIZE_PAL_Y411 (PAL_LINES_PER_FRAME * Y411_LINE_SZ)
56
57#define NTSC_DATA_BUF_SZ (Y422_LINE_SZ * NTSC_LINES_PER_FRAME)
58#define PAL_DATA_BUF_SZ (Y422_LINE_SZ * PAL_LINES_PER_FRAME)
59
60#define RISC_WRITECR_INSTRUCTION_SIZE 16
61#define RISC_SYNC_INSTRUCTION_SIZE 4
62#define JUMP_INSTRUCTION_SIZE 12
63#define MAXSIZE_NO_OPS 36
64#define DWORD_SIZE 4
65
66#define USE_RISC_NOOP_VIDEO 1
67
68#ifdef USE_RISC_NOOP_VIDEO
69#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
70 RISC_SYNC_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
71
72#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
73
74#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
75 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
76
77#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
78 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
79
80#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + \
81 RISC_WRITECR_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
82
83#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
84 JUMP_INSTRUCTION_SIZE + NUM_NO_OPS*DWORD_SIZE)
85
86#define NTSC_RISC_BUF_SIZE (2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE))
87
88#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
89 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE + 2*NUM_NO_OPS*DWORD_SIZE)
90
91#endif
92
93#ifndef USE_RISC_NOOP_VIDEO
94#define PAL_US_VID_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + \
95 RISC_SYNC_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
96
97#define PAL_RISC_BUF_SIZE (2 * PAL_US_VID_PROG_SIZE)
98
99#define PAL_VID_PROG_SIZE ((PAL_FIELD_HEIGHT*2) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
100 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
101
102#define ODD_FLD_PAL_PROG_SIZE ((PAL_FIELD_HEIGHT) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
103#define ODD_FLD_NTSC_PROG_SIZE ((NTSC_ODD_FLD_LINES) * 3 * DWORD_SIZE + RISC_SYNC_INSTRUCTION_SIZE + RISC_WRITECR_INSTRUCTION_SIZE )
104
105#define NTSC_US_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + 1) * 3 * DWORD_SIZE + RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE)
106#define NTSC_RISC_BUF_SIZE ( 2 * (RISC_SYNC_INSTRUCTION_SIZE + NTSC_US_VID_PROG_SIZE) )
107#define FRAME1_VID_PROG_SIZE ((NTSC_ODD_FLD_LINES + NTSC_FIELD_HEIGHT) * 3 * DWORD_SIZE + 2*RISC_SYNC_INSTRUCTION_SIZE + \
108 RISC_WRITECR_INSTRUCTION_SIZE + JUMP_INSTRUCTION_SIZE )
109#endif
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
new file mode 100644
index 000000000000..8834bc80a5ab
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -0,0 +1,1299 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
27MODULE_AUTHOR("Steven Toth <stoth@linuxtv.org>");
28MODULE_LICENSE("GPL");
29
30static unsigned int video_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
31static unsigned int radio_nr[] = {[0 ... (CX25821_MAXBOARDS - 1)] = UNSET };
32
33module_param_array(video_nr, int, NULL, 0444);
34module_param_array(radio_nr, int, NULL, 0444);
35
36MODULE_PARM_DESC(video_nr, "video device numbers");
37MODULE_PARM_DESC(radio_nr, "radio device numbers");
38
39static unsigned int video_debug = VIDEO_DEBUG;
40module_param(video_debug, int, 0644);
41MODULE_PARM_DESC(video_debug, "enable debug messages [video]");
42
43static unsigned int irq_debug;
44module_param(irq_debug, int, 0644);
45MODULE_PARM_DESC(irq_debug, "enable debug messages [IRQ handler]");
46
47unsigned int vid_limit = 16;
48module_param(vid_limit, int, 0644);
49MODULE_PARM_DESC(vid_limit, "capture memory limit in megabytes");
50
51static void init_controls(struct cx25821_dev *dev, int chan_num);
52
53#define FORMAT_FLAGS_PACKED 0x01
54
55struct cx25821_fmt formats[] = {
56 {
57 .name = "8 bpp, gray",
58 .fourcc = V4L2_PIX_FMT_GREY,
59 .depth = 8,
60 .flags = FORMAT_FLAGS_PACKED,
61 }, {
62 .name = "4:1:1, packed, Y41P",
63 .fourcc = V4L2_PIX_FMT_Y41P,
64 .depth = 12,
65 .flags = FORMAT_FLAGS_PACKED,
66 }, {
67 .name = "4:2:2, packed, YUYV",
68 .fourcc = V4L2_PIX_FMT_YUYV,
69 .depth = 16,
70 .flags = FORMAT_FLAGS_PACKED,
71 }, {
72 .name = "4:2:2, packed, UYVY",
73 .fourcc = V4L2_PIX_FMT_UYVY,
74 .depth = 16,
75 .flags = FORMAT_FLAGS_PACKED,
76 }, {
77 .name = "4:2:0, YUV",
78 .fourcc = V4L2_PIX_FMT_YUV420,
79 .depth = 12,
80 .flags = FORMAT_FLAGS_PACKED,
81 },
82};
83
84int get_format_size(void)
85{
86 return ARRAY_SIZE(formats);
87}
88
89struct cx25821_fmt *format_by_fourcc(unsigned int fourcc)
90{
91 unsigned int i;
92
93 if (fourcc == V4L2_PIX_FMT_Y41P || fourcc == V4L2_PIX_FMT_YUV411P) {
94 return formats + 1;
95 }
96
97 for (i = 0; i < ARRAY_SIZE(formats); i++)
98 if (formats[i].fourcc == fourcc)
99 return formats + i;
100
101 printk(KERN_ERR "%s(0x%08x) NOT FOUND\n", __func__, fourcc);
102 return NULL;
103}
104
105void dump_video_queue(struct cx25821_dev *dev, struct cx25821_dmaqueue *q)
106{
107 struct cx25821_buffer *buf;
108 struct list_head *item;
109 dprintk(1, "%s()\n", __func__);
110
111 if (!list_empty(&q->active)) {
112 list_for_each(item, &q->active)
113 buf = list_entry(item, struct cx25821_buffer, vb.queue);
114 }
115
116 if (!list_empty(&q->queued)) {
117 list_for_each(item, &q->queued)
118 buf = list_entry(item, struct cx25821_buffer, vb.queue);
119 }
120
121}
122
123void cx25821_video_wakeup(struct cx25821_dev *dev, struct cx25821_dmaqueue *q,
124 u32 count)
125{
126 struct cx25821_buffer *buf;
127 int bc;
128
129 for (bc = 0;; bc++) {
130 if (list_empty(&q->active)) {
131 dprintk(1, "bc=%d (=0: active empty)\n", bc);
132 break;
133 }
134
135 buf =
136 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
137
138 /* count comes from the hw and it is 16bit wide --
139 * this trick handles wrap-arounds correctly for
140 * up to 32767 buffers in flight... */
141 if ((s16) (count - buf->count) < 0) {
142 break;
143 }
144
145 do_gettimeofday(&buf->vb.ts);
146 buf->vb.state = VIDEOBUF_DONE;
147 list_del(&buf->vb.queue);
148 wake_up(&buf->vb.done);
149 }
150
151 if (list_empty(&q->active))
152 del_timer(&q->timeout);
153 else
154 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
155 if (bc != 1)
156 printk(KERN_ERR "%s: %d buffers handled (should be 1)\n",
157 __func__, bc);
158}
159
160#ifdef TUNER_FLAG
161int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm)
162{
163 dprintk(1, "%s(norm = 0x%08x) name: [%s]\n", __func__,
164 (unsigned int)norm, v4l2_norm_to_name(norm));
165
166 dev->tvnorm = norm;
167
168 /* Tell the internal A/V decoder */
169 cx25821_call_all(dev, core, s_std, norm);
170
171 return 0;
172}
173#endif
174
175struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
176 struct pci_dev *pci,
177 struct video_device *template,
178 char *type)
179{
180 struct video_device *vfd;
181 dprintk(1, "%s()\n", __func__);
182
183 vfd = video_device_alloc();
184 if (NULL == vfd)
185 return NULL;
186 *vfd = *template;
187 vfd->minor = -1;
188 vfd->v4l2_dev = &dev->v4l2_dev;
189 vfd->release = video_device_release;
190 snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name, type,
191 cx25821_boards[dev->board].name);
192 return vfd;
193}
194
195/*
196static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
197{
198 int i;
199
200 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
201 return -EINVAL;
202 for (i = 0; i < CX25821_CTLS; i++)
203 if (cx25821_ctls[i].v.id == qctrl->id)
204 break;
205 if (i == CX25821_CTLS) {
206 *qctrl = no_ctl;
207 return 0;
208 }
209 *qctrl = cx25821_ctls[i].v;
210 return 0;
211}
212*/
213
214// resource management
215int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bit)
216{
217 dprintk(1, "%s()\n", __func__);
218 if (fh->resources & bit)
219 /* have it already allocated */
220 return 1;
221
222 /* is it free? */
223 mutex_lock(&dev->lock);
224 if (dev->resources & bit) {
225 /* no, someone else uses it */
226 mutex_unlock(&dev->lock);
227 return 0;
228 }
229 /* it's free, grab it */
230 fh->resources |= bit;
231 dev->resources |= bit;
232 dprintk(1, "res: get %d\n", bit);
233 mutex_unlock(&dev->lock);
234 return 1;
235}
236
237int res_check(struct cx25821_fh *fh, unsigned int bit)
238{
239 return fh->resources & bit;
240}
241
242int res_locked(struct cx25821_dev *dev, unsigned int bit)
243{
244 return dev->resources & bit;
245}
246
247void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh, unsigned int bits)
248{
249 BUG_ON((fh->resources & bits) != bits);
250 dprintk(1, "%s()\n", __func__);
251
252 mutex_lock(&dev->lock);
253 fh->resources &= ~bits;
254 dev->resources &= ~bits;
255 dprintk(1, "res: put %d\n", bits);
256 mutex_unlock(&dev->lock);
257}
258
259int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input)
260{
261 struct v4l2_routing route;
262 memset(&route, 0, sizeof(route));
263
264 dprintk(1, "%s() video_mux: %d [vmux=%d, gpio=0x%x,0x%x,0x%x,0x%x]\n",
265 __func__, input, INPUT(input)->vmux, INPUT(input)->gpio0,
266 INPUT(input)->gpio1, INPUT(input)->gpio2, INPUT(input)->gpio3);
267 dev->input = input;
268
269 route.input = INPUT(input)->vmux;
270
271 /* Tell the internal A/V decoder */
272 cx25821_call_all(dev, video, s_routing, INPUT(input)->vmux, 0, 0);
273
274 return 0;
275}
276
277int cx25821_start_video_dma(struct cx25821_dev *dev,
278 struct cx25821_dmaqueue *q,
279 struct cx25821_buffer *buf,
280 struct sram_channel *channel)
281{
282 int tmp = 0;
283
284 /* setup fifo + format */
285 cx25821_sram_channel_setup(dev, channel, buf->bpl, buf->risc.dma);
286
287 /* reset counter */
288 cx_write(channel->gpcnt_ctl, 3);
289 q->count = 1;
290
291 /* enable irq */
292 cx_set(PCI_INT_MSK, cx_read(PCI_INT_MSK) | (1 << channel->i));
293 cx_set(channel->int_msk, 0x11);
294
295 /* start dma */
296 cx_write(channel->dma_ctl, 0x11); /* FIFO and RISC enable */
297
298 /* make sure upstream setting if any is reversed */
299 tmp = cx_read(VID_CH_MODE_SEL);
300 cx_write(VID_CH_MODE_SEL, tmp & 0xFFFFFE00);
301
302 return 0;
303}
304
305int cx25821_restart_video_queue(struct cx25821_dev *dev,
306 struct cx25821_dmaqueue *q,
307 struct sram_channel *channel)
308{
309 struct cx25821_buffer *buf, *prev;
310 struct list_head *item;
311
312 if (!list_empty(&q->active)) {
313 buf =
314 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
315
316 cx25821_start_video_dma(dev, q, buf, channel);
317
318 list_for_each(item, &q->active) {
319 buf = list_entry(item, struct cx25821_buffer, vb.queue);
320 buf->count = q->count++;
321 }
322
323 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
324 return 0;
325 }
326
327 prev = NULL;
328 for (;;) {
329 if (list_empty(&q->queued))
330 return 0;
331
332 buf =
333 list_entry(q->queued.next, struct cx25821_buffer, vb.queue);
334
335 if (NULL == prev) {
336 list_move_tail(&buf->vb.queue, &q->active);
337 cx25821_start_video_dma(dev, q, buf, channel);
338 buf->vb.state = VIDEOBUF_ACTIVE;
339 buf->count = q->count++;
340 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
341 } else if (prev->vb.width == buf->vb.width &&
342 prev->vb.height == buf->vb.height &&
343 prev->fmt == buf->fmt) {
344 list_move_tail(&buf->vb.queue, &q->active);
345 buf->vb.state = VIDEOBUF_ACTIVE;
346 buf->count = q->count++;
347 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
348 prev->risc.jmp[2] = cpu_to_le32(0); /* Bits 63 - 32 */
349 } else {
350 return 0;
351 }
352 prev = buf;
353 }
354}
355
356void cx25821_vid_timeout(unsigned long data)
357{
358 struct cx25821_data *timeout_data = (struct cx25821_data *)data;
359 struct cx25821_dev *dev = timeout_data->dev;
360 struct sram_channel *channel = timeout_data->channel;
361 struct cx25821_dmaqueue *q = &dev->vidq[channel->i];
362 struct cx25821_buffer *buf;
363 unsigned long flags;
364
365 //cx25821_sram_channel_dump(dev, channel);
366 cx_clear(channel->dma_ctl, 0x11);
367
368 spin_lock_irqsave(&dev->slock, flags);
369 while (!list_empty(&q->active)) {
370 buf =
371 list_entry(q->active.next, struct cx25821_buffer, vb.queue);
372 list_del(&buf->vb.queue);
373
374 buf->vb.state = VIDEOBUF_ERROR;
375 wake_up(&buf->vb.done);
376 }
377
378 cx25821_restart_video_queue(dev, q, channel);
379 spin_unlock_irqrestore(&dev->slock, flags);
380}
381
382int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status)
383{
384 u32 count = 0;
385 int handled = 0;
386 u32 mask;
387 struct sram_channel *channel = &dev->sram_channels[chan_num];
388
389 mask = cx_read(channel->int_msk);
390 if (0 == (status & mask))
391 return handled;
392
393 cx_write(channel->int_stat, status);
394
395 /* risc op code error */
396 if (status & (1 << 16)) {
397 printk(KERN_WARNING "%s, %s: video risc op code error\n",
398 dev->name, channel->name);
399 cx_clear(channel->dma_ctl, 0x11);
400 cx25821_sram_channel_dump(dev, channel);
401 }
402
403 /* risc1 y */
404 if (status & FLD_VID_DST_RISC1) {
405 spin_lock(&dev->slock);
406 count = cx_read(channel->gpcnt);
407 cx25821_video_wakeup(dev, &dev->vidq[channel->i], count);
408 spin_unlock(&dev->slock);
409 handled++;
410 }
411
412 /* risc2 y */
413 if (status & 0x10) {
414 dprintk(2, "stopper video\n");
415 spin_lock(&dev->slock);
416 cx25821_restart_video_queue(dev, &dev->vidq[channel->i],
417 channel);
418 spin_unlock(&dev->slock);
419 handled++;
420 }
421 return handled;
422}
423
424void cx25821_videoioctl_unregister(struct cx25821_dev *dev)
425{
426 if (dev->ioctl_dev) {
427 if (dev->ioctl_dev->minor != -1)
428 video_unregister_device(dev->ioctl_dev);
429 else
430 video_device_release(dev->ioctl_dev);
431
432 dev->ioctl_dev = NULL;
433 }
434}
435
436void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num)
437{
438 cx_clear(PCI_INT_MSK, 1);
439
440 if (dev->video_dev[chan_num]) {
441 if (-1 != dev->video_dev[chan_num]->minor)
442 video_unregister_device(dev->video_dev[chan_num]);
443 else
444 video_device_release(dev->video_dev[chan_num]);
445
446 dev->video_dev[chan_num] = NULL;
447
448 btcx_riscmem_free(dev->pci, &dev->vidq[chan_num].stopper);
449
450 printk(KERN_WARNING "device %d released!\n", chan_num);
451 }
452
453}
454
455int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
456 struct video_device *video_template)
457{
458 int err;
459
460 spin_lock_init(&dev->slock);
461
462 //printk(KERN_WARNING "Channel %d\n", chan_num);
463
464#ifdef TUNER_FLAG
465 dev->tvnorm = video_template->current_norm;
466#endif
467
468 /* init video dma queues */
469 dev->timeout_data[chan_num].dev = dev;
470 dev->timeout_data[chan_num].channel = &dev->sram_channels[chan_num];
471 INIT_LIST_HEAD(&dev->vidq[chan_num].active);
472 INIT_LIST_HEAD(&dev->vidq[chan_num].queued);
473 dev->vidq[chan_num].timeout.function = cx25821_vid_timeout;
474 dev->vidq[chan_num].timeout.data =
475 (unsigned long)&dev->timeout_data[chan_num];
476 init_timer(&dev->vidq[chan_num].timeout);
477 cx25821_risc_stopper(dev->pci, &dev->vidq[chan_num].stopper,
478 dev->sram_channels[chan_num].dma_ctl, 0x11, 0);
479
480 /* register v4l devices */
481 dev->video_dev[chan_num] =
482 cx25821_vdev_init(dev, dev->pci, video_template, "video");
483 err =
484 video_register_device(dev->video_dev[chan_num], VFL_TYPE_GRABBER,
485 video_nr[dev->nr]);
486
487 if (err < 0) {
488 goto fail_unreg;
489 }
490 //set PCI interrupt
491 cx_set(PCI_INT_MSK, 0xff);
492
493 /* initial device configuration */
494 mutex_lock(&dev->lock);
495#ifdef TUNER_FLAG
496 cx25821_set_tvnorm(dev, dev->tvnorm);
497#endif
498 mutex_unlock(&dev->lock);
499
500 init_controls(dev, chan_num);
501
502 return 0;
503
504 fail_unreg:
505 cx25821_video_unregister(dev, chan_num);
506 return err;
507}
508
509int buffer_setup(struct videobuf_queue *q, unsigned int *count,
510 unsigned int *size)
511{
512 struct cx25821_fh *fh = q->priv_data;
513
514 *size = fh->fmt->depth * fh->width * fh->height >> 3;
515
516 if (0 == *count)
517 *count = 32;
518
519 while (*size * *count > vid_limit * 1024 * 1024)
520 (*count)--;
521
522 return 0;
523}
524
525int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
526 enum v4l2_field field)
527{
528 struct cx25821_fh *fh = q->priv_data;
529 struct cx25821_dev *dev = fh->dev;
530 struct cx25821_buffer *buf =
531 container_of(vb, struct cx25821_buffer, vb);
532 int rc, init_buffer = 0;
533 u32 line0_offset, line1_offset;
534 struct videobuf_dmabuf *dma = videobuf_to_dma(&buf->vb);
535 int bpl_local = LINE_SIZE_D1;
536 int channel_opened = 0;
537
538 BUG_ON(NULL == fh->fmt);
539 if (fh->width < 48 || fh->width > 720 ||
540 fh->height < 32 || fh->height > 576)
541 return -EINVAL;
542
543 buf->vb.size = (fh->width * fh->height * fh->fmt->depth) >> 3;
544
545 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size)
546 return -EINVAL;
547
548 if (buf->fmt != fh->fmt ||
549 buf->vb.width != fh->width ||
550 buf->vb.height != fh->height || buf->vb.field != field) {
551 buf->fmt = fh->fmt;
552 buf->vb.width = fh->width;
553 buf->vb.height = fh->height;
554 buf->vb.field = field;
555 init_buffer = 1;
556 }
557
558 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
559 init_buffer = 1;
560 rc = videobuf_iolock(q, &buf->vb, NULL);
561 if (0 != rc) {
562 printk(KERN_DEBUG "videobuf_iolock failed!\n");
563 goto fail;
564 }
565 }
566
567 dprintk(1, "init_buffer=%d\n", init_buffer);
568
569 if (init_buffer) {
570
571 channel_opened = dev->channel_opened;
572 channel_opened = (channel_opened < 0
573 || channel_opened > 7) ? 7 : channel_opened;
574
575 if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411)
576 buf->bpl = (buf->fmt->depth * buf->vb.width) >> 3;
577 else
578 buf->bpl = (buf->fmt->depth >> 3) * (buf->vb.width);
579
580 if (dev->pixel_formats[channel_opened] == PIXEL_FRMT_411) {
581 bpl_local = buf->bpl;
582 } else {
583 bpl_local = buf->bpl; //Default
584
585 if (channel_opened >= 0 && channel_opened <= 7) {
586 if (dev->use_cif_resolution[channel_opened]) {
587 if (dev->tvnorm & V4L2_STD_PAL_BG
588 || dev->tvnorm & V4L2_STD_PAL_DK)
589 bpl_local = 352 << 1;
590 else
591 bpl_local =
592 dev->
593 cif_width[channel_opened] <<
594 1;
595 }
596 }
597 }
598
599 switch (buf->vb.field) {
600 case V4L2_FIELD_TOP:
601 cx25821_risc_buffer(dev->pci, &buf->risc,
602 dma->sglist, 0, UNSET,
603 buf->bpl, 0, buf->vb.height);
604 break;
605 case V4L2_FIELD_BOTTOM:
606 cx25821_risc_buffer(dev->pci, &buf->risc,
607 dma->sglist, UNSET, 0,
608 buf->bpl, 0, buf->vb.height);
609 break;
610 case V4L2_FIELD_INTERLACED:
611 /* All other formats are top field first */
612 line0_offset = 0;
613 line1_offset = buf->bpl;
614 dprintk(1, "top field first\n");
615
616 cx25821_risc_buffer(dev->pci, &buf->risc,
617 dma->sglist, line0_offset,
618 bpl_local, bpl_local, bpl_local,
619 buf->vb.height >> 1);
620 break;
621 case V4L2_FIELD_SEQ_TB:
622 cx25821_risc_buffer(dev->pci, &buf->risc,
623 dma->sglist,
624 0, buf->bpl * (buf->vb.height >> 1),
625 buf->bpl, 0, buf->vb.height >> 1);
626 break;
627 case V4L2_FIELD_SEQ_BT:
628 cx25821_risc_buffer(dev->pci, &buf->risc,
629 dma->sglist,
630 buf->bpl * (buf->vb.height >> 1), 0,
631 buf->bpl, 0, buf->vb.height >> 1);
632 break;
633 default:
634 BUG();
635 }
636 }
637
638 dprintk(2, "[%p/%d] buffer_prep - %dx%d %dbpp \"%s\" - dma=0x%08lx\n",
639 buf, buf->vb.i, fh->width, fh->height, fh->fmt->depth,
640 fh->fmt->name, (unsigned long)buf->risc.dma);
641
642 buf->vb.state = VIDEOBUF_PREPARED;
643
644 return 0;
645
646 fail:
647 cx25821_free_buffer(q, buf);
648 return rc;
649}
650
651void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
652{
653 struct cx25821_buffer *buf =
654 container_of(vb, struct cx25821_buffer, vb);
655
656 cx25821_free_buffer(q, buf);
657}
658
659struct videobuf_queue *get_queue(struct cx25821_fh *fh)
660{
661 switch (fh->type) {
662 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
663 return &fh->vidq;
664 default:
665 BUG();
666 return NULL;
667 }
668}
669
670int get_resource(struct cx25821_fh *fh, int resource)
671{
672 switch (fh->type) {
673 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
674 return resource;
675 default:
676 BUG();
677 return 0;
678 }
679}
680
681int video_mmap(struct file *file, struct vm_area_struct *vma)
682{
683 struct cx25821_fh *fh = file->private_data;
684
685 return videobuf_mmap_mapper(get_queue(fh), vma);
686}
687
688/* VIDEO IOCTLS */
689int vidioc_g_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
690{
691 struct cx25821_fh *fh = priv;
692
693 f->fmt.pix.width = fh->width;
694 f->fmt.pix.height = fh->height;
695 f->fmt.pix.field = fh->vidq.field;
696 f->fmt.pix.pixelformat = fh->fmt->fourcc;
697 f->fmt.pix.bytesperline = (f->fmt.pix.width * fh->fmt->depth) >> 3;
698 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
699
700 return 0;
701}
702
703int vidioc_try_fmt_vid_cap(struct file *file, void *priv, struct v4l2_format *f)
704{
705 struct cx25821_fmt *fmt;
706 enum v4l2_field field;
707 unsigned int maxw, maxh;
708
709 fmt = format_by_fourcc(f->fmt.pix.pixelformat);
710 if (NULL == fmt)
711 return -EINVAL;
712
713 field = f->fmt.pix.field;
714 maxw = 720;
715 maxh = 576;
716
717 if (V4L2_FIELD_ANY == field) {
718 field = (f->fmt.pix.height > maxh / 2)
719 ? V4L2_FIELD_INTERLACED : V4L2_FIELD_TOP;
720 }
721
722 switch (field) {
723 case V4L2_FIELD_TOP:
724 case V4L2_FIELD_BOTTOM:
725 maxh = maxh / 2;
726 break;
727 case V4L2_FIELD_INTERLACED:
728 break;
729 default:
730 return -EINVAL;
731 }
732
733 f->fmt.pix.field = field;
734 if (f->fmt.pix.height < 32)
735 f->fmt.pix.height = 32;
736 if (f->fmt.pix.height > maxh)
737 f->fmt.pix.height = maxh;
738 if (f->fmt.pix.width < 48)
739 f->fmt.pix.width = 48;
740 if (f->fmt.pix.width > maxw)
741 f->fmt.pix.width = maxw;
742 f->fmt.pix.width &= ~0x03;
743 f->fmt.pix.bytesperline = (f->fmt.pix.width * fmt->depth) >> 3;
744 f->fmt.pix.sizeimage = f->fmt.pix.height * f->fmt.pix.bytesperline;
745
746 return 0;
747}
748
749int vidioc_querycap(struct file *file, void *priv, struct v4l2_capability *cap)
750{
751 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
752
753 strcpy(cap->driver, "cx25821");
754 strlcpy(cap->card, cx25821_boards[dev->board].name, sizeof(cap->card));
755 sprintf(cap->bus_info, "PCIe:%s", pci_name(dev->pci));
756 cap->version = CX25821_VERSION_CODE;
757 cap->capabilities =
758 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
759 if (UNSET != dev->tuner_type)
760 cap->capabilities |= V4L2_CAP_TUNER;
761 return 0;
762}
763
764int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
765 struct v4l2_fmtdesc *f)
766{
767 if (unlikely(f->index >= ARRAY_SIZE(formats)))
768 return -EINVAL;
769
770 strlcpy(f->description, formats[f->index].name, sizeof(f->description));
771 f->pixelformat = formats[f->index].fourcc;
772
773 return 0;
774}
775
776#ifdef CONFIG_VIDEO_V4L1_COMPAT
777int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf)
778{
779 struct cx25821_fh *fh = priv;
780 struct videobuf_queue *q;
781 struct v4l2_requestbuffers req;
782 unsigned int i;
783 int err;
784
785 q = get_queue(fh);
786 memset(&req, 0, sizeof(req));
787 req.type = q->type;
788 req.count = 8;
789 req.memory = V4L2_MEMORY_MMAP;
790 err = videobuf_reqbufs(q, &req);
791 if (err < 0)
792 return err;
793
794 mbuf->frames = req.count;
795 mbuf->size = 0;
796 for (i = 0; i < mbuf->frames; i++) {
797 mbuf->offsets[i] = q->bufs[i]->boff;
798 mbuf->size += q->bufs[i]->bsize;
799 }
800 return 0;
801}
802#endif
803
804int vidioc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *p)
805{
806 struct cx25821_fh *fh = priv;
807 return videobuf_reqbufs(get_queue(fh), p);
808}
809
810int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
811{
812 struct cx25821_fh *fh = priv;
813 return videobuf_querybuf(get_queue(fh), p);
814}
815
816int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
817{
818 struct cx25821_fh *fh = priv;
819 return videobuf_qbuf(get_queue(fh), p);
820}
821
822int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p)
823{
824 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
825
826 *p = v4l2_prio_max(&dev->prio);
827
828 return 0;
829}
830
831int vidioc_s_priority(struct file *file, void *f, enum v4l2_priority prio)
832{
833 struct cx25821_fh *fh = f;
834 struct cx25821_dev *dev = ((struct cx25821_fh *)f)->dev;
835
836 return v4l2_prio_change(&dev->prio, &fh->prio, prio);
837}
838
839#ifdef TUNER_FLAG
840int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms)
841{
842 struct cx25821_fh *fh = priv;
843 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
844 int err;
845
846 dprintk(1, "%s()\n", __func__);
847
848 if (fh) {
849 err = v4l2_prio_check(&dev->prio, &fh->prio);
850 if (0 != err)
851 return err;
852 }
853
854 if (dev->tvnorm == *tvnorms) {
855 return 0;
856 }
857
858 mutex_lock(&dev->lock);
859 cx25821_set_tvnorm(dev, *tvnorms);
860 mutex_unlock(&dev->lock);
861
862 medusa_set_videostandard(dev);
863
864 return 0;
865}
866#endif
867
868int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i)
869{
870 static const char *iname[] = {
871 [CX25821_VMUX_COMPOSITE] = "Composite",
872 [CX25821_VMUX_SVIDEO] = "S-Video",
873 [CX25821_VMUX_DEBUG] = "for debug only",
874 };
875 unsigned int n;
876 dprintk(1, "%s()\n", __func__);
877
878 n = i->index;
879 if (n > 2)
880 return -EINVAL;
881
882 if (0 == INPUT(n)->type)
883 return -EINVAL;
884
885 memset(i, 0, sizeof(*i));
886 i->index = n;
887 i->type = V4L2_INPUT_TYPE_CAMERA;
888 strcpy(i->name, iname[INPUT(n)->type]);
889
890 i->std = CX25821_NORMS;
891 return 0;
892}
893
894int vidioc_enum_input(struct file *file, void *priv, struct v4l2_input *i)
895{
896 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
897 dprintk(1, "%s()\n", __func__);
898 return cx25821_enum_input(dev, i);
899}
900
901int vidioc_g_input(struct file *file, void *priv, unsigned int *i)
902{
903 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
904
905 *i = dev->input;
906 dprintk(1, "%s() returns %d\n", __func__, *i);
907 return 0;
908}
909
910int vidioc_s_input(struct file *file, void *priv, unsigned int i)
911{
912 struct cx25821_fh *fh = priv;
913 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
914 int err;
915
916 dprintk(1, "%s(%d)\n", __func__, i);
917
918 if (fh) {
919 err = v4l2_prio_check(&dev->prio, &fh->prio);
920 if (0 != err)
921 return err;
922 }
923
924 if (i > 2) {
925 dprintk(1, "%s() -EINVAL\n", __func__);
926 return -EINVAL;
927 }
928
929 mutex_lock(&dev->lock);
930 cx25821_video_mux(dev, i);
931 mutex_unlock(&dev->lock);
932 return 0;
933}
934
935#ifdef TUNER_FLAG
936int vidioc_g_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
937{
938 struct cx25821_fh *fh = priv;
939 struct cx25821_dev *dev = fh->dev;
940
941 f->frequency = dev->freq;
942
943 cx25821_call_all(dev, tuner, g_frequency, f);
944
945 return 0;
946}
947
948int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f)
949{
950 mutex_lock(&dev->lock);
951 dev->freq = f->frequency;
952
953 cx25821_call_all(dev, tuner, s_frequency, f);
954
955 /* When changing channels it is required to reset TVAUDIO */
956 msleep(10);
957
958 mutex_unlock(&dev->lock);
959
960 return 0;
961}
962
963int vidioc_s_frequency(struct file *file, void *priv, struct v4l2_frequency *f)
964{
965 struct cx25821_fh *fh = priv;
966 struct cx25821_dev *dev = fh->dev;
967 int err;
968
969 if (fh) {
970 err = v4l2_prio_check(&dev->prio, &fh->prio);
971 if (0 != err)
972 return err;
973 }
974
975 return cx25821_set_freq(dev, f);
976}
977#endif
978
979#ifdef CONFIG_VIDEO_ADV_DEBUG
980int vidioc_g_register(struct file *file, void *fh,
981 struct v4l2_dbg_register *reg)
982{
983 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
984
985 if (!v4l2_chip_match_host(&reg->match))
986 return -EINVAL;
987
988 cx25821_call_all(dev, core, g_register, reg);
989
990 return 0;
991}
992
993int vidioc_s_register(struct file *file, void *fh,
994 struct v4l2_dbg_register *reg)
995{
996 struct cx25821_dev *dev = ((struct cx25821_fh *)fh)->dev;
997
998 if (!v4l2_chip_match_host(&reg->match))
999 return -EINVAL;
1000
1001 cx25821_call_all(dev, core, s_register, reg);
1002
1003 return 0;
1004}
1005
1006#endif
1007
1008#ifdef TUNER_FLAG
1009int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1010{
1011 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1012
1013 if (unlikely(UNSET == dev->tuner_type))
1014 return -EINVAL;
1015 if (0 != t->index)
1016 return -EINVAL;
1017
1018 strcpy(t->name, "Television");
1019 t->type = V4L2_TUNER_ANALOG_TV;
1020 t->capability = V4L2_TUNER_CAP_NORM;
1021 t->rangehigh = 0xffffffffUL;
1022
1023 t->signal = 0xffff; /* LOCKED */
1024 return 0;
1025}
1026
1027int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
1028{
1029 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1030 struct cx25821_fh *fh = priv;
1031 int err;
1032
1033 if (fh) {
1034 err = v4l2_prio_check(&dev->prio, &fh->prio);
1035 if (0 != err)
1036 return err;
1037 }
1038
1039 dprintk(1, "%s()\n", __func__);
1040 if (UNSET == dev->tuner_type)
1041 return -EINVAL;
1042 if (0 != t->index)
1043 return -EINVAL;
1044
1045 return 0;
1046}
1047
1048#endif
1049// ******************************************************************************************
1050static const struct v4l2_queryctrl no_ctl = {
1051 .name = "42",
1052 .flags = V4L2_CTRL_FLAG_DISABLED,
1053};
1054
1055static struct v4l2_queryctrl cx25821_ctls[] = {
1056 /* --- video --- */
1057 {
1058 .id = V4L2_CID_BRIGHTNESS,
1059 .name = "Brightness",
1060 .minimum = 0,
1061 .maximum = 10000,
1062 .step = 1,
1063 .default_value = 6200,
1064 .type = V4L2_CTRL_TYPE_INTEGER,
1065 }, {
1066 .id = V4L2_CID_CONTRAST,
1067 .name = "Contrast",
1068 .minimum = 0,
1069 .maximum = 10000,
1070 .step = 1,
1071 .default_value = 5000,
1072 .type = V4L2_CTRL_TYPE_INTEGER,
1073 }, {
1074 .id = V4L2_CID_SATURATION,
1075 .name = "Saturation",
1076 .minimum = 0,
1077 .maximum = 10000,
1078 .step = 1,
1079 .default_value = 5000,
1080 .type = V4L2_CTRL_TYPE_INTEGER,
1081 }, {
1082 .id = V4L2_CID_HUE,
1083 .name = "Hue",
1084 .minimum = 0,
1085 .maximum = 10000,
1086 .step = 1,
1087 .default_value = 5000,
1088 .type = V4L2_CTRL_TYPE_INTEGER,
1089 }
1090};
1091static const int CX25821_CTLS = ARRAY_SIZE(cx25821_ctls);
1092
1093static int cx25821_ctrl_query(struct v4l2_queryctrl *qctrl)
1094{
1095 int i;
1096
1097 if (qctrl->id < V4L2_CID_BASE || qctrl->id >= V4L2_CID_LASTP1)
1098 return -EINVAL;
1099 for (i = 0; i < CX25821_CTLS; i++)
1100 if (cx25821_ctls[i].id == qctrl->id)
1101 break;
1102 if (i == CX25821_CTLS) {
1103 *qctrl = no_ctl;
1104 return 0;
1105 }
1106 *qctrl = cx25821_ctls[i];
1107 return 0;
1108}
1109
1110int vidioc_queryctrl(struct file *file, void *priv,
1111 struct v4l2_queryctrl *qctrl)
1112{
1113 return cx25821_ctrl_query(qctrl);
1114}
1115
1116/* ------------------------------------------------------------------ */
1117/* VIDEO CTRL IOCTLS */
1118
1119static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
1120{
1121 unsigned int i;
1122
1123 for (i = 0; i < CX25821_CTLS; i++)
1124 if (cx25821_ctls[i].id == id)
1125 return cx25821_ctls + i;
1126 return NULL;
1127}
1128
1129int vidioc_g_ctrl(struct file *file, void *priv, struct v4l2_control *ctl)
1130{
1131 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1132
1133 const struct v4l2_queryctrl *ctrl;
1134
1135 ctrl = ctrl_by_id(ctl->id);
1136
1137 if (NULL == ctrl)
1138 return -EINVAL;
1139 switch (ctl->id) {
1140 case V4L2_CID_BRIGHTNESS:
1141 ctl->value = dev->ctl_bright;
1142 break;
1143 case V4L2_CID_HUE:
1144 ctl->value = dev->ctl_hue;
1145 break;
1146 case V4L2_CID_CONTRAST:
1147 ctl->value = dev->ctl_contrast;
1148 break;
1149 case V4L2_CID_SATURATION:
1150 ctl->value = dev->ctl_saturation;
1151 break;
1152 }
1153 return 0;
1154}
1155
1156int cx25821_set_control(struct cx25821_dev *dev,
1157 struct v4l2_control *ctl, int chan_num)
1158{
1159 int err;
1160 const struct v4l2_queryctrl *ctrl;
1161
1162 err = -EINVAL;
1163
1164 ctrl = ctrl_by_id(ctl->id);
1165
1166 if (NULL == ctrl)
1167 return err;
1168
1169 switch (ctrl->type) {
1170 case V4L2_CTRL_TYPE_BOOLEAN:
1171 case V4L2_CTRL_TYPE_MENU:
1172 case V4L2_CTRL_TYPE_INTEGER:
1173 if (ctl->value < ctrl->minimum)
1174 ctl->value = ctrl->minimum;
1175 if (ctl->value > ctrl->maximum)
1176 ctl->value = ctrl->maximum;
1177 break;
1178 default:
1179 /* nothing */ ;
1180 };
1181
1182 switch (ctl->id) {
1183 case V4L2_CID_BRIGHTNESS:
1184 dev->ctl_bright = ctl->value;
1185 medusa_set_brightness(dev, ctl->value, chan_num);
1186 break;
1187 case V4L2_CID_HUE:
1188 dev->ctl_hue = ctl->value;
1189 medusa_set_hue(dev, ctl->value, chan_num);
1190 break;
1191 case V4L2_CID_CONTRAST:
1192 dev->ctl_contrast = ctl->value;
1193 medusa_set_contrast(dev, ctl->value, chan_num);
1194 break;
1195 case V4L2_CID_SATURATION:
1196 dev->ctl_saturation = ctl->value;
1197 medusa_set_saturation(dev, ctl->value, chan_num);
1198 break;
1199 }
1200
1201 err = 0;
1202
1203 return err;
1204}
1205
1206static void init_controls(struct cx25821_dev *dev, int chan_num)
1207{
1208 struct v4l2_control ctrl;
1209 int i;
1210 for (i = 0; i < CX25821_CTLS; i++) {
1211 ctrl.id = cx25821_ctls[i].id;
1212 ctrl.value = cx25821_ctls[i].default_value;
1213
1214 cx25821_set_control(dev, &ctrl, chan_num);
1215 }
1216}
1217
1218int vidioc_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cropcap)
1219{
1220 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1221
1222 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1223 return -EINVAL;
1224 cropcap->bounds.top = cropcap->bounds.left = 0;
1225 cropcap->bounds.width = 720;
1226 cropcap->bounds.height = dev->tvnorm == V4L2_STD_PAL_BG ? 576 : 480;
1227 cropcap->pixelaspect.numerator =
1228 dev->tvnorm == V4L2_STD_PAL_BG ? 59 : 10;
1229 cropcap->pixelaspect.denominator =
1230 dev->tvnorm == V4L2_STD_PAL_BG ? 54 : 11;
1231 cropcap->defrect = cropcap->bounds;
1232 return 0;
1233}
1234
1235int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1236{
1237 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
1238 struct cx25821_fh *fh = priv;
1239 int err;
1240
1241 if (fh) {
1242 err = v4l2_prio_check(&dev->prio, &fh->prio);
1243 if (0 != err)
1244 return err;
1245 }
1246 // vidioc_s_crop not supported
1247 return -EINVAL;
1248}
1249
1250int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1251{
1252 // vidioc_g_crop not supported
1253 return -EINVAL;
1254}
1255
1256int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm)
1257{
1258 // medusa does not support video standard sensing of current input
1259 *norm = CX25821_NORMS;
1260
1261 return 0;
1262}
1263
1264int is_valid_width(u32 width, v4l2_std_id tvnorm)
1265{
1266 if (tvnorm == V4L2_STD_PAL_BG) {
1267 if (width == 352 || width == 720)
1268 return 1;
1269 else
1270 return 0;
1271 }
1272
1273 if (tvnorm == V4L2_STD_NTSC_M) {
1274 if (width == 320 || width == 352 || width == 720)
1275 return 1;
1276 else
1277 return 0;
1278 }
1279 return 0;
1280}
1281
1282int is_valid_height(u32 height, v4l2_std_id tvnorm)
1283{
1284 if (tvnorm == V4L2_STD_PAL_BG) {
1285 if (height == 576 || height == 288)
1286 return 1;
1287 else
1288 return 0;
1289 }
1290
1291 if (tvnorm == V4L2_STD_NTSC_M) {
1292 if (height == 480 || height == 240)
1293 return 1;
1294 else
1295 return 0;
1296 }
1297
1298 return 0;
1299}
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/staging/cx25821/cx25821-video.h
new file mode 100644
index 000000000000..4417ff5d90d4
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video.h
@@ -0,0 +1,194 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef CX25821_VIDEO_H_
25#define CX25821_VIDEO_H_
26
27#include <linux/init.h>
28#include <linux/list.h>
29#include <linux/module.h>
30#include <linux/moduleparam.h>
31#include <linux/kmod.h>
32#include <linux/kernel.h>
33#include <linux/slab.h>
34#include <linux/interrupt.h>
35#include <linux/delay.h>
36#include <linux/kthread.h>
37#include <asm/div64.h>
38
39#include "cx25821.h"
40#include <media/v4l2-common.h>
41#include <media/v4l2-ioctl.h>
42
43#ifdef CONFIG_VIDEO_V4L1_COMPAT
44/* Include V4L1 specific functions. Should be removed soon */
45#include <linux/videodev.h>
46#endif
47
48#define TUNER_FLAG
49
50#define VIDEO_DEBUG 0
51
52#define dprintk(level, fmt, arg...)\
53 do { if (VIDEO_DEBUG >= level)\
54 printk(KERN_DEBUG "%s/0: " fmt, dev->name, ## arg);\
55 } while (0)
56
57//For IOCTL to identify running upstream
58#define UPSTREAM_START_VIDEO 700
59#define UPSTREAM_STOP_VIDEO 701
60#define UPSTREAM_START_AUDIO 702
61#define UPSTREAM_STOP_AUDIO 703
62#define UPSTREAM_DUMP_REGISTERS 702
63#define SET_VIDEO_STD 800
64#define SET_PIXEL_FORMAT 1000
65#define ENABLE_CIF_RESOLUTION 1001
66
67#define REG_READ 900
68#define REG_WRITE 901
69#define MEDUSA_READ 910
70#define MEDUSA_WRITE 911
71
72extern struct sram_channel *channel0;
73extern struct sram_channel *channel1;
74extern struct sram_channel *channel2;
75extern struct sram_channel *channel3;
76extern struct sram_channel *channel4;
77extern struct sram_channel *channel5;
78extern struct sram_channel *channel6;
79extern struct sram_channel *channel7;
80extern struct sram_channel *channel9;
81extern struct sram_channel *channel10;
82extern struct sram_channel *channel11;
83extern struct video_device cx25821_video_template0;
84extern struct video_device cx25821_video_template1;
85extern struct video_device cx25821_video_template2;
86extern struct video_device cx25821_video_template3;
87extern struct video_device cx25821_video_template4;
88extern struct video_device cx25821_video_template5;
89extern struct video_device cx25821_video_template6;
90extern struct video_device cx25821_video_template7;
91extern struct video_device cx25821_video_template9;
92extern struct video_device cx25821_video_template10;
93extern struct video_device cx25821_video_template11;
94extern struct video_device cx25821_videoioctl_template;
95//extern const u32 *ctrl_classes[];
96
97extern unsigned int vid_limit;
98
99#define FORMAT_FLAGS_PACKED 0x01
100extern struct cx25821_fmt formats[];
101extern struct cx25821_fmt *format_by_fourcc(unsigned int fourcc);
102extern struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
103
104extern void dump_video_queue(struct cx25821_dev *dev,
105 struct cx25821_dmaqueue *q);
106extern void cx25821_video_wakeup(struct cx25821_dev *dev,
107 struct cx25821_dmaqueue *q, u32 count);
108
109#ifdef TUNER_FLAG
110extern int cx25821_set_tvnorm(struct cx25821_dev *dev, v4l2_std_id norm);
111#endif
112
113extern int res_get(struct cx25821_dev *dev, struct cx25821_fh *fh,
114 unsigned int bit);
115extern int res_check(struct cx25821_fh *fh, unsigned int bit);
116extern int res_locked(struct cx25821_dev *dev, unsigned int bit);
117extern void res_free(struct cx25821_dev *dev, struct cx25821_fh *fh,
118 unsigned int bits);
119extern int cx25821_video_mux(struct cx25821_dev *dev, unsigned int input);
120extern int cx25821_start_video_dma(struct cx25821_dev *dev,
121 struct cx25821_dmaqueue *q,
122 struct cx25821_buffer *buf,
123 struct sram_channel *channel);
124
125extern int cx25821_set_scale(struct cx25821_dev *dev, unsigned int width,
126 unsigned int height, enum v4l2_field field);
127extern int cx25821_video_irq(struct cx25821_dev *dev, int chan_num, u32 status);
128extern void cx25821_video_unregister(struct cx25821_dev *dev, int chan_num);
129extern int cx25821_video_register(struct cx25821_dev *dev, int chan_num,
130 struct video_device *video_template);
131extern int get_format_size(void);
132
133extern int buffer_setup(struct videobuf_queue *q, unsigned int *count,
134 unsigned int *size);
135extern int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
136 enum v4l2_field field);
137extern void buffer_release(struct videobuf_queue *q,
138 struct videobuf_buffer *vb);
139extern struct videobuf_queue *get_queue(struct cx25821_fh *fh);
140extern int get_resource(struct cx25821_fh *fh, int resource);
141extern int video_mmap(struct file *file, struct vm_area_struct *vma);
142extern int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
143 struct v4l2_format *f);
144extern int vidioc_querycap(struct file *file, void *priv,
145 struct v4l2_capability *cap);
146extern int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
147 struct v4l2_fmtdesc *f);
148extern int vidiocgmbuf(struct file *file, void *priv, struct video_mbuf *mbuf);
149extern int vidioc_reqbufs(struct file *file, void *priv,
150 struct v4l2_requestbuffers *p);
151extern int vidioc_querybuf(struct file *file, void *priv,
152 struct v4l2_buffer *p);
153extern int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p);
154extern int vidioc_s_std(struct file *file, void *priv, v4l2_std_id * tvnorms);
155extern int cx25821_enum_input(struct cx25821_dev *dev, struct v4l2_input *i);
156extern int vidioc_enum_input(struct file *file, void *priv,
157 struct v4l2_input *i);
158extern int vidioc_g_input(struct file *file, void *priv, unsigned int *i);
159extern int vidioc_s_input(struct file *file, void *priv, unsigned int i);
160extern int vidioc_g_ctrl(struct file *file, void *priv,
161 struct v4l2_control *ctl);
162extern int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
163 struct v4l2_format *f);
164extern int vidioc_g_frequency(struct file *file, void *priv,
165 struct v4l2_frequency *f);
166extern int cx25821_set_freq(struct cx25821_dev *dev, struct v4l2_frequency *f);
167extern int vidioc_s_frequency(struct file *file, void *priv,
168 struct v4l2_frequency *f);
169extern int vidioc_g_register(struct file *file, void *fh,
170 struct v4l2_dbg_register *reg);
171extern int vidioc_s_register(struct file *file, void *fh,
172 struct v4l2_dbg_register *reg);
173extern int vidioc_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
174extern int vidioc_s_tuner(struct file *file, void *priv, struct v4l2_tuner *t);
175
176extern int is_valid_width(u32 width, v4l2_std_id tvnorm);
177extern int is_valid_height(u32 height, v4l2_std_id tvnorm);
178
179extern int vidioc_g_priority(struct file *file, void *f, enum v4l2_priority *p);
180extern int vidioc_s_priority(struct file *file, void *f,
181 enum v4l2_priority prio);
182
183extern int vidioc_queryctrl(struct file *file, void *priv,
184 struct v4l2_queryctrl *qctrl);
185extern int cx25821_set_control(struct cx25821_dev *dev,
186 struct v4l2_control *ctrl, int chan_num);
187
188extern int vidioc_cropcap(struct file *file, void *fh,
189 struct v4l2_cropcap *cropcap);
190extern int vidioc_s_crop(struct file *file, void *priv, struct v4l2_crop *crop);
191extern int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop);
192
193extern int vidioc_querystd(struct file *file, void *priv, v4l2_std_id * norm);
194#endif
diff --git a/drivers/staging/cx25821/cx25821-video0.c b/drivers/staging/cx25821/cx25821-video0.c
new file mode 100644
index 000000000000..950fac1d7003
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video0.c
@@ -0,0 +1,451 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH00];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH00]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH00]
109 && h->video_dev[SRAM_CH00]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128
129 file->private_data = fh;
130 fh->dev = dev;
131 fh->type = type;
132 fh->width = 720;
133
134 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
135 fh->height = 576;
136 else
137 fh->height = 480;
138
139 dev->channel_opened = SRAM_CH00;
140 pix_format =
141 (dev->pixel_formats[dev->channel_opened] ==
142 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
143 fh->fmt = format_by_fourcc(pix_format);
144
145 v4l2_prio_open(&dev->prio, &fh->prio);
146
147 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
148 &dev->pci->dev, &dev->slock,
149 V4L2_BUF_TYPE_VIDEO_CAPTURE,
150 V4L2_FIELD_INTERLACED,
151 sizeof(struct cx25821_buffer), fh);
152
153 dprintk(1, "post videobuf_queue_init()\n");
154 unlock_kernel();
155
156 return 0;
157}
158
159static ssize_t video_read(struct file *file, char __user * data, size_t count,
160 loff_t * ppos)
161{
162 struct cx25821_fh *fh = file->private_data;
163
164 switch (fh->type) {
165 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
166 if (res_locked(fh->dev, RESOURCE_VIDEO0))
167 return -EBUSY;
168
169 return videobuf_read_one(&fh->vidq, data, count, ppos,
170 file->f_flags & O_NONBLOCK);
171
172 default:
173 BUG();
174 return 0;
175 }
176}
177
178static unsigned int video_poll(struct file *file,
179 struct poll_table_struct *wait)
180{
181 struct cx25821_fh *fh = file->private_data;
182 struct cx25821_buffer *buf;
183
184 if (res_check(fh, RESOURCE_VIDEO0)) {
185 /* streaming capture */
186 if (list_empty(&fh->vidq.stream))
187 return POLLERR;
188 buf = list_entry(fh->vidq.stream.next,
189 struct cx25821_buffer, vb.stream);
190 } else {
191 /* read() capture */
192 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
193 if (NULL == buf)
194 return POLLERR;
195 }
196
197 poll_wait(file, &buf->vb.done, wait);
198 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
199 if (buf->vb.state == VIDEOBUF_DONE) {
200 struct cx25821_dev *dev = fh->dev;
201
202 if (dev && dev->use_cif_resolution[SRAM_CH00]) {
203 u8 cam_id = *((char *)buf->vb.baddr + 3);
204 memcpy((char *)buf->vb.baddr,
205 (char *)buf->vb.baddr + (fh->width * 2),
206 (fh->width * 2));
207 *((char *)buf->vb.baddr + 3) = cam_id;
208 }
209 }
210
211 return POLLIN | POLLRDNORM;
212 }
213
214 return 0;
215}
216
217static int video_release(struct file *file)
218{
219 struct cx25821_fh *fh = file->private_data;
220 struct cx25821_dev *dev = fh->dev;
221
222 //stop the risc engine and fifo
223 cx_write(channel0->dma_ctl, 0); /* FIFO and RISC disable */
224
225 /* stop video capture */
226 if (res_check(fh, RESOURCE_VIDEO0)) {
227 videobuf_queue_cancel(&fh->vidq);
228 res_free(dev, fh, RESOURCE_VIDEO0);
229 }
230
231 if (fh->vidq.read_buf) {
232 buffer_release(&fh->vidq, fh->vidq.read_buf);
233 kfree(fh->vidq.read_buf);
234 }
235
236 videobuf_mmap_free(&fh->vidq);
237
238 v4l2_prio_close(&dev->prio, &fh->prio);
239 file->private_data = NULL;
240 kfree(fh);
241
242 return 0;
243}
244
245static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
246{
247 struct cx25821_fh *fh = priv;
248 struct cx25821_dev *dev = fh->dev;
249
250 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
251 return -EINVAL;
252 }
253
254 if (unlikely(i != fh->type)) {
255 return -EINVAL;
256 }
257
258 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO0)))) {
259 return -EBUSY;
260 }
261
262 return videobuf_streamon(get_queue(fh));
263}
264
265static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
266{
267 struct cx25821_fh *fh = priv;
268 struct cx25821_dev *dev = fh->dev;
269 int err, res;
270
271 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
272 return -EINVAL;
273 if (i != fh->type)
274 return -EINVAL;
275
276 res = get_resource(fh, RESOURCE_VIDEO0);
277 err = videobuf_streamoff(get_queue(fh));
278 if (err < 0)
279 return err;
280 res_free(dev, fh, res);
281 return 0;
282}
283
284static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
285 struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = PIXEL_FRMT_422;
291
292 if (fh) {
293 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297
298 dprintk(2, "%s()\n", __func__);
299 err = vidioc_try_fmt_vid_cap(file, priv, f);
300
301 if (0 != err)
302 return err;
303
304 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
305 fh->vidq.field = f->fmt.pix.field;
306
307 // check if width and height is valid based on set standard
308 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
313 fh->height = f->fmt.pix.height;
314 }
315
316 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
317 pix_format = PIXEL_FRMT_411;
318 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
319 pix_format = PIXEL_FRMT_422;
320 else
321 return -EINVAL;
322
323 cx25821_set_pixel_format(dev, SRAM_CH00, pix_format);
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352) {
327 dev->use_cif_resolution[SRAM_CH00] = 1;
328 } else {
329 dev->use_cif_resolution[SRAM_CH00] = 0;
330 }
331 dev->cif_width[SRAM_CH00] = fh->width;
332 medusa_set_resolution(dev, fh->width, SRAM_CH00);
333
334 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
335 fh->height, fh->vidq.field);
336 cx25821_call_all(dev, video, s_fmt, f);
337
338 return 0;
339}
340
341static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
342{
343 int ret_val = 0;
344 struct cx25821_fh *fh = priv;
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346
347 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
348
349 p->sequence = dev->vidq[SRAM_CH00].count;
350
351 return ret_val;
352}
353
354static int vidioc_log_status(struct file *file, void *priv)
355{
356 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
357 char name[32 + 2];
358
359 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH00];
360 u32 tmp = 0;
361
362 snprintf(name, sizeof(name), "%s/2", dev->name);
363 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
364 dev->name);
365 cx25821_call_all(dev, core, log_status);
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 0 is %s\n",
368 (tmp & 0x11) ? "streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH00);
388}
389
390// exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template0 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
diff --git a/drivers/staging/cx25821/cx25821-video1.c b/drivers/staging/cx25821/cx25821-video1.c
new file mode 100644
index 000000000000..a4dddc684adf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video1.c
@@ -0,0 +1,451 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH01];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH01]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH01]
109 && h->video_dev[SRAM_CH01]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128
129 file->private_data = fh;
130 fh->dev = dev;
131 fh->type = type;
132 fh->width = 720;
133
134 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
135 fh->height = 576;
136 else
137 fh->height = 480;
138
139 dev->channel_opened = SRAM_CH01;
140 pix_format =
141 (dev->pixel_formats[dev->channel_opened] ==
142 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
143 fh->fmt = format_by_fourcc(pix_format);
144
145 v4l2_prio_open(&dev->prio, &fh->prio);
146
147 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
148 &dev->pci->dev, &dev->slock,
149 V4L2_BUF_TYPE_VIDEO_CAPTURE,
150 V4L2_FIELD_INTERLACED,
151 sizeof(struct cx25821_buffer), fh);
152
153 dprintk(1, "post videobuf_queue_init()\n");
154 unlock_kernel();
155
156 return 0;
157}
158
159static ssize_t video_read(struct file *file, char __user * data, size_t count,
160 loff_t * ppos)
161{
162 struct cx25821_fh *fh = file->private_data;
163
164 switch (fh->type) {
165 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
166 if (res_locked(fh->dev, RESOURCE_VIDEO1))
167 return -EBUSY;
168
169 return videobuf_read_one(&fh->vidq, data, count, ppos,
170 file->f_flags & O_NONBLOCK);
171
172 default:
173 BUG();
174 return 0;
175 }
176}
177
178static unsigned int video_poll(struct file *file,
179 struct poll_table_struct *wait)
180{
181 struct cx25821_fh *fh = file->private_data;
182 struct cx25821_buffer *buf;
183
184 if (res_check(fh, RESOURCE_VIDEO1)) {
185 /* streaming capture */
186 if (list_empty(&fh->vidq.stream))
187 return POLLERR;
188 buf = list_entry(fh->vidq.stream.next,
189 struct cx25821_buffer, vb.stream);
190 } else {
191 /* read() capture */
192 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
193 if (NULL == buf)
194 return POLLERR;
195 }
196
197 poll_wait(file, &buf->vb.done, wait);
198 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
199 if (buf->vb.state == VIDEOBUF_DONE) {
200 struct cx25821_dev *dev = fh->dev;
201
202 if (dev && dev->use_cif_resolution[SRAM_CH01]) {
203 u8 cam_id = *((char *)buf->vb.baddr + 3);
204 memcpy((char *)buf->vb.baddr,
205 (char *)buf->vb.baddr + (fh->width * 2),
206 (fh->width * 2));
207 *((char *)buf->vb.baddr + 3) = cam_id;
208 }
209 }
210
211 return POLLIN | POLLRDNORM;
212 }
213
214 return 0;
215}
216
217static int video_release(struct file *file)
218{
219 struct cx25821_fh *fh = file->private_data;
220 struct cx25821_dev *dev = fh->dev;
221
222 //stop the risc engine and fifo
223 cx_write(channel1->dma_ctl, 0); /* FIFO and RISC disable */
224
225 /* stop video capture */
226 if (res_check(fh, RESOURCE_VIDEO1)) {
227 videobuf_queue_cancel(&fh->vidq);
228 res_free(dev, fh, RESOURCE_VIDEO1);
229 }
230
231 if (fh->vidq.read_buf) {
232 buffer_release(&fh->vidq, fh->vidq.read_buf);
233 kfree(fh->vidq.read_buf);
234 }
235
236 videobuf_mmap_free(&fh->vidq);
237
238 v4l2_prio_close(&dev->prio, &fh->prio);
239 file->private_data = NULL;
240 kfree(fh);
241
242 return 0;
243}
244
245static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
246{
247 struct cx25821_fh *fh = priv;
248 struct cx25821_dev *dev = fh->dev;
249
250 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
251 return -EINVAL;
252 }
253
254 if (unlikely(i != fh->type)) {
255 return -EINVAL;
256 }
257
258 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO1)))) {
259 return -EBUSY;
260 }
261
262 return videobuf_streamon(get_queue(fh));
263}
264
265static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
266{
267 struct cx25821_fh *fh = priv;
268 struct cx25821_dev *dev = fh->dev;
269 int err, res;
270
271 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
272 return -EINVAL;
273 if (i != fh->type)
274 return -EINVAL;
275
276 res = get_resource(fh, RESOURCE_VIDEO1);
277 err = videobuf_streamoff(get_queue(fh));
278 if (err < 0)
279 return err;
280 res_free(dev, fh, res);
281 return 0;
282}
283
284static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
285 struct v4l2_format *f)
286{
287 struct cx25821_fh *fh = priv;
288 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
289 int err;
290 int pix_format = 0;
291
292 if (fh) {
293 err = v4l2_prio_check(&dev->prio, &fh->prio);
294 if (0 != err)
295 return err;
296 }
297
298 dprintk(2, "%s()\n", __func__);
299 err = vidioc_try_fmt_vid_cap(file, priv, f);
300
301 if (0 != err)
302 return err;
303
304 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
305 fh->vidq.field = f->fmt.pix.field;
306
307 // check if width and height is valid based on set standard
308 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
309 fh->width = f->fmt.pix.width;
310 }
311
312 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
313 fh->height = f->fmt.pix.height;
314 }
315
316 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
317 pix_format = PIXEL_FRMT_411;
318 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
319 pix_format = PIXEL_FRMT_422;
320 else
321 return -EINVAL;
322
323 cx25821_set_pixel_format(dev, SRAM_CH01, pix_format);
324
325 // check if cif resolution
326 if (fh->width == 320 || fh->width == 352) {
327 dev->use_cif_resolution[SRAM_CH01] = 1;
328 } else {
329 dev->use_cif_resolution[SRAM_CH01] = 0;
330 }
331 dev->cif_width[SRAM_CH01] = fh->width;
332 medusa_set_resolution(dev, fh->width, SRAM_CH01);
333
334 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
335 fh->height, fh->vidq.field);
336 cx25821_call_all(dev, video, s_fmt, f);
337
338 return 0;
339}
340
341static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
342{
343 int ret_val = 0;
344 struct cx25821_fh *fh = priv;
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346
347 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
348
349 p->sequence = dev->vidq[SRAM_CH01].count;
350
351 return ret_val;
352}
353
354static int vidioc_log_status(struct file *file, void *priv)
355{
356 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
357 char name[32 + 2];
358
359 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH01];
360 u32 tmp = 0;
361
362 snprintf(name, sizeof(name), "%s/2", dev->name);
363 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
364 dev->name);
365 cx25821_call_all(dev, core, log_status);
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 1 is %s\n",
368 (tmp & 0x11) ? "streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH01);
388}
389
390//exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template1 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
diff --git a/drivers/staging/cx25821/cx25821-video2.c b/drivers/staging/cx25821/cx25821-video2.c
new file mode 100644
index 000000000000..8e04e253f5d9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video2.c
@@ -0,0 +1,452 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH02];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH02]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH02]
109 && h->video_dev[SRAM_CH02]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH02;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO2))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO2)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH02]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel2->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO2)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO2);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO2)))) {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO2);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH02, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH02] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH02] = 0;
329 }
330 dev->cif_width[SRAM_CH02] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH02);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH02].count;
349
350 return ret_val;
351}
352
353static int vidioc_log_status(struct file *file, void *priv)
354{
355 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
356 char name[32 + 2];
357
358 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH02];
359 u32 tmp = 0;
360
361 snprintf(name, sizeof(name), "%s/2", dev->name);
362 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
363 dev->name);
364
365 cx25821_call_all(dev, core, log_status);
366
367 tmp = cx_read(sram_ch->dma_ctl);
368 printk(KERN_INFO "Video input 2 is %s\n",
369 (tmp & 0x11) ? "streaming" : "stopped");
370 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
371 dev->name);
372 return 0;
373}
374
375static int vidioc_s_ctrl(struct file *file, void *priv,
376 struct v4l2_control *ctl)
377{
378 struct cx25821_fh *fh = priv;
379 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
380 int err;
381
382 if (fh) {
383 err = v4l2_prio_check(&dev->prio, &fh->prio);
384 if (0 != err)
385 return err;
386 }
387
388 return cx25821_set_control(dev, ctl, SRAM_CH02);
389}
390
391// exported stuff
392static const struct v4l2_file_operations video_fops = {
393 .owner = THIS_MODULE,
394 .open = video_open,
395 .release = video_release,
396 .read = video_read,
397 .poll = video_poll,
398 .mmap = video_mmap,
399 .ioctl = video_ioctl2,
400};
401
402static const struct v4l2_ioctl_ops video_ioctl_ops = {
403 .vidioc_querycap = vidioc_querycap,
404 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
405 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
406 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
407 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
408 .vidioc_reqbufs = vidioc_reqbufs,
409 .vidioc_querybuf = vidioc_querybuf,
410 .vidioc_qbuf = vidioc_qbuf,
411 .vidioc_dqbuf = vidioc_dqbuf,
412#ifdef TUNER_FLAG
413 .vidioc_s_std = vidioc_s_std,
414 .vidioc_querystd = vidioc_querystd,
415#endif
416 .vidioc_cropcap = vidioc_cropcap,
417 .vidioc_s_crop = vidioc_s_crop,
418 .vidioc_g_crop = vidioc_g_crop,
419 .vidioc_enum_input = vidioc_enum_input,
420 .vidioc_g_input = vidioc_g_input,
421 .vidioc_s_input = vidioc_s_input,
422 .vidioc_g_ctrl = vidioc_g_ctrl,
423 .vidioc_s_ctrl = vidioc_s_ctrl,
424 .vidioc_queryctrl = vidioc_queryctrl,
425 .vidioc_streamon = vidioc_streamon,
426 .vidioc_streamoff = vidioc_streamoff,
427 .vidioc_log_status = vidioc_log_status,
428 .vidioc_g_priority = vidioc_g_priority,
429 .vidioc_s_priority = vidioc_s_priority,
430#ifdef CONFIG_VIDEO_V4L1_COMPAT
431 .vidiocgmbuf = vidiocgmbuf,
432#endif
433#ifdef TUNER_FLAG
434 .vidioc_g_tuner = vidioc_g_tuner,
435 .vidioc_s_tuner = vidioc_s_tuner,
436 .vidioc_g_frequency = vidioc_g_frequency,
437 .vidioc_s_frequency = vidioc_s_frequency,
438#endif
439#ifdef CONFIG_VIDEO_ADV_DEBUG
440 .vidioc_g_register = vidioc_g_register,
441 .vidioc_s_register = vidioc_s_register,
442#endif
443};
444
445struct video_device cx25821_video_template2 = {
446 .name = "cx25821-video",
447 .fops = &video_fops,
448 .minor = -1,
449 .ioctl_ops = &video_ioctl_ops,
450 .tvnorms = CX25821_NORMS,
451 .current_norm = V4L2_STD_NTSC_M,
452};
diff --git a/drivers/staging/cx25821/cx25821-video3.c b/drivers/staging/cx25821/cx25821-video3.c
new file mode 100644
index 000000000000..8801a8ead904
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video3.c
@@ -0,0 +1,451 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH03];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH03]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH03]
109 && h->video_dev[SRAM_CH03]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH03;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO3))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO3)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH03]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel3->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO3)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO3);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO3)))) {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO3);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH03, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH03] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH03] = 0;
329 }
330 dev->cif_width[SRAM_CH03] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH03);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH03].count;
349
350 return ret_val;
351}
352
353static int vidioc_log_status(struct file *file, void *priv)
354{
355 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
356 char name[32 + 2];
357
358 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH03];
359 u32 tmp = 0;
360
361 snprintf(name, sizeof(name), "%s/2", dev->name);
362 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
363 dev->name);
364 cx25821_call_all(dev, core, log_status);
365
366 tmp = cx_read(sram_ch->dma_ctl);
367 printk(KERN_INFO "Video input 3 is %s\n",
368 (tmp & 0x11) ? "streaming" : "stopped");
369 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
370 dev->name);
371 return 0;
372}
373
374static int vidioc_s_ctrl(struct file *file, void *priv,
375 struct v4l2_control *ctl)
376{
377 struct cx25821_fh *fh = priv;
378 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
379 int err;
380
381 if (fh) {
382 err = v4l2_prio_check(&dev->prio, &fh->prio);
383 if (0 != err)
384 return err;
385 }
386
387 return cx25821_set_control(dev, ctl, SRAM_CH03);
388}
389
390// exported stuff
391static const struct v4l2_file_operations video_fops = {
392 .owner = THIS_MODULE,
393 .open = video_open,
394 .release = video_release,
395 .read = video_read,
396 .poll = video_poll,
397 .mmap = video_mmap,
398 .ioctl = video_ioctl2,
399};
400
401static const struct v4l2_ioctl_ops video_ioctl_ops = {
402 .vidioc_querycap = vidioc_querycap,
403 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
404 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
405 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
406 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
407 .vidioc_reqbufs = vidioc_reqbufs,
408 .vidioc_querybuf = vidioc_querybuf,
409 .vidioc_qbuf = vidioc_qbuf,
410 .vidioc_dqbuf = vidioc_dqbuf,
411#ifdef TUNER_FLAG
412 .vidioc_s_std = vidioc_s_std,
413 .vidioc_querystd = vidioc_querystd,
414#endif
415 .vidioc_cropcap = vidioc_cropcap,
416 .vidioc_s_crop = vidioc_s_crop,
417 .vidioc_g_crop = vidioc_g_crop,
418 .vidioc_enum_input = vidioc_enum_input,
419 .vidioc_g_input = vidioc_g_input,
420 .vidioc_s_input = vidioc_s_input,
421 .vidioc_g_ctrl = vidioc_g_ctrl,
422 .vidioc_s_ctrl = vidioc_s_ctrl,
423 .vidioc_queryctrl = vidioc_queryctrl,
424 .vidioc_streamon = vidioc_streamon,
425 .vidioc_streamoff = vidioc_streamoff,
426 .vidioc_log_status = vidioc_log_status,
427 .vidioc_g_priority = vidioc_g_priority,
428 .vidioc_s_priority = vidioc_s_priority,
429#ifdef CONFIG_VIDEO_V4L1_COMPAT
430 .vidiocgmbuf = vidiocgmbuf,
431#endif
432#ifdef TUNER_FLAG
433 .vidioc_g_tuner = vidioc_g_tuner,
434 .vidioc_s_tuner = vidioc_s_tuner,
435 .vidioc_g_frequency = vidioc_g_frequency,
436 .vidioc_s_frequency = vidioc_s_frequency,
437#endif
438#ifdef CONFIG_VIDEO_ADV_DEBUG
439 .vidioc_g_register = vidioc_g_register,
440 .vidioc_s_register = vidioc_s_register,
441#endif
442};
443
444struct video_device cx25821_video_template3 = {
445 .name = "cx25821-video",
446 .fops = &video_fops,
447 .minor = -1,
448 .ioctl_ops = &video_ioctl_ops,
449 .tvnorms = CX25821_NORMS,
450 .current_norm = V4L2_STD_NTSC_M,
451};
diff --git a/drivers/staging/cx25821/cx25821-video4.c b/drivers/staging/cx25821/cx25821-video4.c
new file mode 100644
index 000000000000..ab0d747138ad
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video4.c
@@ -0,0 +1,450 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH04];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH04]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH04]
109 && h->video_dev[SRAM_CH04]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH04;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
146 &dev->pci->dev, &dev->slock,
147 V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 V4L2_FIELD_INTERLACED,
149 sizeof(struct cx25821_buffer), fh);
150
151 dprintk(1, "post videobuf_queue_init()\n");
152 unlock_kernel();
153
154 return 0;
155}
156
157static ssize_t video_read(struct file *file, char __user * data, size_t count,
158 loff_t * ppos)
159{
160 struct cx25821_fh *fh = file->private_data;
161
162 switch (fh->type) {
163 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
164 if (res_locked(fh->dev, RESOURCE_VIDEO4))
165 return -EBUSY;
166
167 return videobuf_read_one(&fh->vidq, data, count, ppos,
168 file->f_flags & O_NONBLOCK);
169
170 default:
171 BUG();
172 return 0;
173 }
174}
175
176static unsigned int video_poll(struct file *file,
177 struct poll_table_struct *wait)
178{
179 struct cx25821_fh *fh = file->private_data;
180 struct cx25821_buffer *buf;
181
182 if (res_check(fh, RESOURCE_VIDEO4)) {
183 /* streaming capture */
184 if (list_empty(&fh->vidq.stream))
185 return POLLERR;
186 buf = list_entry(fh->vidq.stream.next,
187 struct cx25821_buffer, vb.stream);
188 } else {
189 /* read() capture */
190 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
191 if (NULL == buf)
192 return POLLERR;
193 }
194
195 poll_wait(file, &buf->vb.done, wait);
196 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
197 if (buf->vb.state == VIDEOBUF_DONE) {
198 struct cx25821_dev *dev = fh->dev;
199
200 if (dev && dev->use_cif_resolution[SRAM_CH04]) {
201 u8 cam_id = *((char *)buf->vb.baddr + 3);
202 memcpy((char *)buf->vb.baddr,
203 (char *)buf->vb.baddr + (fh->width * 2),
204 (fh->width * 2));
205 *((char *)buf->vb.baddr + 3) = cam_id;
206 }
207 }
208
209 return POLLIN | POLLRDNORM;
210 }
211
212 return 0;
213}
214
215static int video_release(struct file *file)
216{
217 struct cx25821_fh *fh = file->private_data;
218 struct cx25821_dev *dev = fh->dev;
219
220 //stop the risc engine and fifo
221 cx_write(channel4->dma_ctl, 0); /* FIFO and RISC disable */
222
223 /* stop video capture */
224 if (res_check(fh, RESOURCE_VIDEO4)) {
225 videobuf_queue_cancel(&fh->vidq);
226 res_free(dev, fh, RESOURCE_VIDEO4);
227 }
228
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO4)))) {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO4);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 // check priority
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
307 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH04, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH04] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH04] = 0;
328 }
329 dev->cif_width[SRAM_CH04] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH04);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH04].count;
348
349 return ret_val;
350}
351
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH04];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 4 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH04);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template4 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video5.c b/drivers/staging/cx25821/cx25821-video5.c
new file mode 100644
index 000000000000..7ef0b971f5cf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video5.c
@@ -0,0 +1,450 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH05];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH05]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH05]
109 && h->video_dev[SRAM_CH05]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH05;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO5))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO5)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH05]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel5->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO5)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO5);
228 }
229
230 if (fh->vidq.read_buf) {
231 buffer_release(&fh->vidq, fh->vidq.read_buf);
232 kfree(fh->vidq.read_buf);
233 }
234
235 videobuf_mmap_free(&fh->vidq);
236
237 v4l2_prio_close(&dev->prio, &fh->prio);
238 file->private_data = NULL;
239 kfree(fh);
240
241 return 0;
242}
243
244static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
245{
246 struct cx25821_fh *fh = priv;
247 struct cx25821_dev *dev = fh->dev;
248
249 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
250 return -EINVAL;
251 }
252
253 if (unlikely(i != fh->type)) {
254 return -EINVAL;
255 }
256
257 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO5)))) {
258 return -EBUSY;
259 }
260
261 return videobuf_streamon(get_queue(fh));
262}
263
264static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
265{
266 struct cx25821_fh *fh = priv;
267 struct cx25821_dev *dev = fh->dev;
268 int err, res;
269
270 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
271 return -EINVAL;
272 if (i != fh->type)
273 return -EINVAL;
274
275 res = get_resource(fh, RESOURCE_VIDEO5);
276 err = videobuf_streamoff(get_queue(fh));
277 if (err < 0)
278 return err;
279 res_free(dev, fh, res);
280 return 0;
281}
282
283static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
284 struct v4l2_format *f)
285{
286 struct cx25821_fh *fh = priv;
287 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
288 int err;
289 int pix_format = 0;
290
291 if (fh) {
292 err = v4l2_prio_check(&dev->prio, &fh->prio);
293 if (0 != err)
294 return err;
295 }
296
297 dprintk(2, "%s()\n", __func__);
298 err = vidioc_try_fmt_vid_cap(file, priv, f);
299
300 if (0 != err)
301 return err;
302
303 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
304 fh->vidq.field = f->fmt.pix.field;
305
306 // check if width and height is valid based on set standard
307 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
308 fh->width = f->fmt.pix.width;
309 }
310
311 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
312 fh->height = f->fmt.pix.height;
313 }
314
315 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
316 pix_format = PIXEL_FRMT_411;
317 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
318 pix_format = PIXEL_FRMT_422;
319 else
320 return -EINVAL;
321
322 cx25821_set_pixel_format(dev, SRAM_CH05, pix_format);
323
324 // check if cif resolution
325 if (fh->width == 320 || fh->width == 352) {
326 dev->use_cif_resolution[SRAM_CH05] = 1;
327 } else {
328 dev->use_cif_resolution[SRAM_CH05] = 0;
329 }
330 dev->cif_width[SRAM_CH05] = fh->width;
331 medusa_set_resolution(dev, fh->width, SRAM_CH05);
332
333 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
334 fh->height, fh->vidq.field);
335 cx25821_call_all(dev, video, s_fmt, f);
336
337 return 0;
338}
339
340static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
341{
342 int ret_val = 0;
343 struct cx25821_fh *fh = priv;
344 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
345
346 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
347
348 p->sequence = dev->vidq[SRAM_CH05].count;
349
350 return ret_val;
351}
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH05];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 5 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH05);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template5 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video6.c b/drivers/staging/cx25821/cx25821-video6.c
new file mode 100644
index 000000000000..3c41b49e2ea9
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video6.c
@@ -0,0 +1,450 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH06];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH06]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->video_dev[SRAM_CH06]
109 && h->video_dev[SRAM_CH06]->minor == minor) {
110 dev = h;
111 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
112 }
113 }
114
115 if (NULL == dev) {
116 unlock_kernel();
117 return -ENODEV;
118 }
119
120 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
121
122 /* allocate + initialize per filehandle data */
123 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
124 if (NULL == fh) {
125 unlock_kernel();
126 return -ENOMEM;
127 }
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = SRAM_CH06;
139 pix_format =
140 (dev->pixel_formats[dev->channel_opened] ==
141 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
142 fh->fmt = format_by_fourcc(pix_format);
143
144 v4l2_prio_open(&dev->prio, &fh->prio);
145
146 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
147 &dev->pci->dev, &dev->slock,
148 V4L2_BUF_TYPE_VIDEO_CAPTURE,
149 V4L2_FIELD_INTERLACED,
150 sizeof(struct cx25821_buffer), fh);
151
152 dprintk(1, "post videobuf_queue_init()\n");
153 unlock_kernel();
154
155 return 0;
156}
157
158static ssize_t video_read(struct file *file, char __user * data, size_t count,
159 loff_t * ppos)
160{
161 struct cx25821_fh *fh = file->private_data;
162
163 switch (fh->type) {
164 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
165 if (res_locked(fh->dev, RESOURCE_VIDEO6))
166 return -EBUSY;
167
168 return videobuf_read_one(&fh->vidq, data, count, ppos,
169 file->f_flags & O_NONBLOCK);
170
171 default:
172 BUG();
173 return 0;
174 }
175}
176
177static unsigned int video_poll(struct file *file,
178 struct poll_table_struct *wait)
179{
180 struct cx25821_fh *fh = file->private_data;
181 struct cx25821_buffer *buf;
182
183 if (res_check(fh, RESOURCE_VIDEO6)) {
184 /* streaming capture */
185 if (list_empty(&fh->vidq.stream))
186 return POLLERR;
187 buf = list_entry(fh->vidq.stream.next,
188 struct cx25821_buffer, vb.stream);
189 } else {
190 /* read() capture */
191 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
192 if (NULL == buf)
193 return POLLERR;
194 }
195
196 poll_wait(file, &buf->vb.done, wait);
197 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
198 if (buf->vb.state == VIDEOBUF_DONE) {
199 struct cx25821_dev *dev = fh->dev;
200
201 if (dev && dev->use_cif_resolution[SRAM_CH06]) {
202 u8 cam_id = *((char *)buf->vb.baddr + 3);
203 memcpy((char *)buf->vb.baddr,
204 (char *)buf->vb.baddr + (fh->width * 2),
205 (fh->width * 2));
206 *((char *)buf->vb.baddr + 3) = cam_id;
207 }
208 }
209
210 return POLLIN | POLLRDNORM;
211 }
212
213 return 0;
214}
215
216static int video_release(struct file *file)
217{
218 struct cx25821_fh *fh = file->private_data;
219 struct cx25821_dev *dev = fh->dev;
220
221 //stop the risc engine and fifo
222 cx_write(channel6->dma_ctl, 0); /* FIFO and RISC disable */
223
224 /* stop video capture */
225 if (res_check(fh, RESOURCE_VIDEO6)) {
226 videobuf_queue_cancel(&fh->vidq);
227 res_free(dev, fh, RESOURCE_VIDEO6);
228 }
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO6)))) {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO6);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 if (fh) {
291 err = v4l2_prio_check(&dev->prio, &fh->prio);
292 if (0 != err)
293 return err;
294 }
295
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
307 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH06, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH06] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH06] = 0;
328 }
329 dev->cif_width[SRAM_CH06] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH06);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH06].count;
348
349 return ret_val;
350}
351
352static int vidioc_log_status(struct file *file, void *priv)
353{
354 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
355 char name[32 + 2];
356
357 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH06];
358 u32 tmp = 0;
359
360 snprintf(name, sizeof(name), "%s/2", dev->name);
361 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
362 dev->name);
363 cx25821_call_all(dev, core, log_status);
364
365 tmp = cx_read(sram_ch->dma_ctl);
366 printk(KERN_INFO "Video input 6 is %s\n",
367 (tmp & 0x11) ? "streaming" : "stopped");
368 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
369 dev->name);
370 return 0;
371}
372
373static int vidioc_s_ctrl(struct file *file, void *priv,
374 struct v4l2_control *ctl)
375{
376 struct cx25821_fh *fh = priv;
377 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
378 int err;
379
380 if (fh) {
381 err = v4l2_prio_check(&dev->prio, &fh->prio);
382 if (0 != err)
383 return err;
384 }
385
386 return cx25821_set_control(dev, ctl, SRAM_CH06);
387}
388
389// exported stuff
390static const struct v4l2_file_operations video_fops = {
391 .owner = THIS_MODULE,
392 .open = video_open,
393 .release = video_release,
394 .read = video_read,
395 .poll = video_poll,
396 .mmap = video_mmap,
397 .ioctl = video_ioctl2,
398};
399
400static const struct v4l2_ioctl_ops video_ioctl_ops = {
401 .vidioc_querycap = vidioc_querycap,
402 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
403 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
404 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
405 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
406 .vidioc_reqbufs = vidioc_reqbufs,
407 .vidioc_querybuf = vidioc_querybuf,
408 .vidioc_qbuf = vidioc_qbuf,
409 .vidioc_dqbuf = vidioc_dqbuf,
410#ifdef TUNER_FLAG
411 .vidioc_s_std = vidioc_s_std,
412 .vidioc_querystd = vidioc_querystd,
413#endif
414 .vidioc_cropcap = vidioc_cropcap,
415 .vidioc_s_crop = vidioc_s_crop,
416 .vidioc_g_crop = vidioc_g_crop,
417 .vidioc_enum_input = vidioc_enum_input,
418 .vidioc_g_input = vidioc_g_input,
419 .vidioc_s_input = vidioc_s_input,
420 .vidioc_g_ctrl = vidioc_g_ctrl,
421 .vidioc_s_ctrl = vidioc_s_ctrl,
422 .vidioc_queryctrl = vidioc_queryctrl,
423 .vidioc_streamon = vidioc_streamon,
424 .vidioc_streamoff = vidioc_streamoff,
425 .vidioc_log_status = vidioc_log_status,
426 .vidioc_g_priority = vidioc_g_priority,
427 .vidioc_s_priority = vidioc_s_priority,
428#ifdef CONFIG_VIDEO_V4L1_COMPAT
429 .vidiocgmbuf = vidiocgmbuf,
430#endif
431#ifdef TUNER_FLAG
432 .vidioc_g_tuner = vidioc_g_tuner,
433 .vidioc_s_tuner = vidioc_s_tuner,
434 .vidioc_g_frequency = vidioc_g_frequency,
435 .vidioc_s_frequency = vidioc_s_frequency,
436#endif
437#ifdef CONFIG_VIDEO_ADV_DEBUG
438 .vidioc_g_register = vidioc_g_register,
439 .vidioc_s_register = vidioc_s_register,
440#endif
441};
442
443struct video_device cx25821_video_template6 = {
444 .name = "cx25821-video",
445 .fops = &video_fops,
446 .minor = -1,
447 .ioctl_ops = &video_ioctl_ops,
448 .tvnorms = CX25821_NORMS,
449 .current_norm = V4L2_STD_NTSC_M,
450};
diff --git a/drivers/staging/cx25821/cx25821-video7.c b/drivers/staging/cx25821/cx25821-video7.c
new file mode 100644
index 000000000000..625c9b78a9cf
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-video7.c
@@ -0,0 +1,449 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH07];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41 if (!list_empty(&q->queued)) {
42 list_add_tail(&buf->vb.queue, &q->queued);
43 buf->vb.state = VIDEOBUF_QUEUED;
44 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
45 buf->vb.i);
46
47 } else if (list_empty(&q->active)) {
48 list_add_tail(&buf->vb.queue, &q->active);
49 cx25821_start_video_dma(dev, q, buf,
50 &dev->sram_channels[SRAM_CH07]);
51 buf->vb.state = VIDEOBUF_ACTIVE;
52 buf->count = q->count++;
53 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
54 dprintk(2,
55 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
56 buf, buf->vb.i, buf->count, q->count);
57 } else {
58 prev =
59 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
60 if (prev->vb.width == buf->vb.width
61 && prev->vb.height == buf->vb.height
62 && prev->fmt == buf->fmt) {
63 list_add_tail(&buf->vb.queue, &q->active);
64 buf->vb.state = VIDEOBUF_ACTIVE;
65 buf->count = q->count++;
66 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
67
68 /* 64 bit bits 63-32 */
69 prev->risc.jmp[2] = cpu_to_le32(0);
70 dprintk(2,
71 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
72 buf, buf->vb.i, buf->count);
73
74 } else {
75 list_add_tail(&buf->vb.queue, &q->queued);
76 buf->vb.state = VIDEOBUF_QUEUED;
77 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
78 buf->vb.i);
79 }
80 }
81
82 if (list_empty(&q->active)) {
83 dprintk(2, "active queue empty!\n");
84 }
85}
86
87static struct videobuf_queue_ops cx25821_video_qops = {
88 .buf_setup = buffer_setup,
89 .buf_prepare = buffer_prepare,
90 .buf_queue = buffer_queue,
91 .buf_release = buffer_release,
92};
93
94static int video_open(struct file *file)
95{
96 int minor = video_devdata(file)->minor;
97 struct cx25821_dev *h, *dev = NULL;
98 struct cx25821_fh *fh;
99 struct list_head *list;
100 enum v4l2_buf_type type = 0;
101 u32 pix_format;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH07]
108 && h->video_dev[SRAM_CH07]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127 file->private_data = fh;
128 fh->dev = dev;
129 fh->type = type;
130 fh->width = 720;
131
132 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
133 fh->height = 576;
134 else
135 fh->height = 480;
136
137 dev->channel_opened = SRAM_CH07;
138 pix_format =
139 (dev->pixel_formats[dev->channel_opened] ==
140 PIXEL_FRMT_411) ? V4L2_PIX_FMT_Y41P : V4L2_PIX_FMT_YUYV;
141 fh->fmt = format_by_fourcc(pix_format);
142
143 v4l2_prio_open(&dev->prio, &fh->prio);
144
145 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
146 &dev->pci->dev, &dev->slock,
147 V4L2_BUF_TYPE_VIDEO_CAPTURE,
148 V4L2_FIELD_INTERLACED,
149 sizeof(struct cx25821_buffer), fh);
150
151 dprintk(1, "post videobuf_queue_init()\n");
152 unlock_kernel();
153
154 return 0;
155}
156
157static ssize_t video_read(struct file *file, char __user * data, size_t count,
158 loff_t * ppos)
159{
160 struct cx25821_fh *fh = file->private_data;
161
162 switch (fh->type) {
163 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
164 if (res_locked(fh->dev, RESOURCE_VIDEO7))
165 return -EBUSY;
166
167 return videobuf_read_one(&fh->vidq, data, count, ppos,
168 file->f_flags & O_NONBLOCK);
169
170 default:
171 BUG();
172 return 0;
173 }
174}
175
176static unsigned int video_poll(struct file *file,
177 struct poll_table_struct *wait)
178{
179 struct cx25821_fh *fh = file->private_data;
180 struct cx25821_buffer *buf;
181
182 if (res_check(fh, RESOURCE_VIDEO7)) {
183 /* streaming capture */
184 if (list_empty(&fh->vidq.stream))
185 return POLLERR;
186 buf = list_entry(fh->vidq.stream.next,
187 struct cx25821_buffer, vb.stream);
188 } else {
189 /* read() capture */
190 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
191 if (NULL == buf)
192 return POLLERR;
193 }
194
195 poll_wait(file, &buf->vb.done, wait);
196 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR) {
197 if (buf->vb.state == VIDEOBUF_DONE) {
198 struct cx25821_dev *dev = fh->dev;
199
200 if (dev && dev->use_cif_resolution[SRAM_CH07]) {
201 u8 cam_id = *((char *)buf->vb.baddr + 3);
202 memcpy((char *)buf->vb.baddr,
203 (char *)buf->vb.baddr + (fh->width * 2),
204 (fh->width * 2));
205 *((char *)buf->vb.baddr + 3) = cam_id;
206 }
207 }
208
209 return POLLIN | POLLRDNORM;
210 }
211
212 return 0;
213}
214
215static int video_release(struct file *file)
216{
217 struct cx25821_fh *fh = file->private_data;
218 struct cx25821_dev *dev = fh->dev;
219
220 //stop the risc engine and fifo
221 cx_write(channel7->dma_ctl, 0); /* FIFO and RISC disable */
222
223 /* stop video capture */
224 if (res_check(fh, RESOURCE_VIDEO7)) {
225 videobuf_queue_cancel(&fh->vidq);
226 res_free(dev, fh, RESOURCE_VIDEO7);
227 }
228
229 if (fh->vidq.read_buf) {
230 buffer_release(&fh->vidq, fh->vidq.read_buf);
231 kfree(fh->vidq.read_buf);
232 }
233
234 videobuf_mmap_free(&fh->vidq);
235
236 v4l2_prio_close(&dev->prio, &fh->prio);
237 file->private_data = NULL;
238 kfree(fh);
239
240 return 0;
241}
242
243static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
244{
245 struct cx25821_fh *fh = priv;
246 struct cx25821_dev *dev = fh->dev;
247
248 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
249 return -EINVAL;
250 }
251
252 if (unlikely(i != fh->type)) {
253 return -EINVAL;
254 }
255
256 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO7)))) {
257 return -EBUSY;
258 }
259
260 return videobuf_streamon(get_queue(fh));
261}
262
263static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
264{
265 struct cx25821_fh *fh = priv;
266 struct cx25821_dev *dev = fh->dev;
267 int err, res;
268
269 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
270 return -EINVAL;
271 if (i != fh->type)
272 return -EINVAL;
273
274 res = get_resource(fh, RESOURCE_VIDEO7);
275 err = videobuf_streamoff(get_queue(fh));
276 if (err < 0)
277 return err;
278 res_free(dev, fh, res);
279 return 0;
280}
281
282static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
283 struct v4l2_format *f)
284{
285 struct cx25821_fh *fh = priv;
286 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
287 int err;
288 int pix_format = 0;
289
290 if (fh) {
291 err = v4l2_prio_check(&dev->prio, &fh->prio);
292 if (0 != err)
293 return err;
294 }
295
296 dprintk(2, "%s()\n", __func__);
297 err = vidioc_try_fmt_vid_cap(file, priv, f);
298
299 if (0 != err)
300 return err;
301
302 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
303 fh->vidq.field = f->fmt.pix.field;
304
305 // check if width and height is valid based on set standard
306 if (is_valid_width(f->fmt.pix.width, dev->tvnorm)) {
307 fh->width = f->fmt.pix.width;
308 }
309
310 if (is_valid_height(f->fmt.pix.height, dev->tvnorm)) {
311 fh->height = f->fmt.pix.height;
312 }
313
314 if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_Y41P)
315 pix_format = PIXEL_FRMT_411;
316 else if (f->fmt.pix.pixelformat == V4L2_PIX_FMT_YUYV)
317 pix_format = PIXEL_FRMT_422;
318 else
319 return -EINVAL;
320
321 cx25821_set_pixel_format(dev, SRAM_CH07, pix_format);
322
323 // check if cif resolution
324 if (fh->width == 320 || fh->width == 352) {
325 dev->use_cif_resolution[SRAM_CH07] = 1;
326 } else {
327 dev->use_cif_resolution[SRAM_CH07] = 0;
328 }
329 dev->cif_width[SRAM_CH07] = fh->width;
330 medusa_set_resolution(dev, fh->width, SRAM_CH07);
331
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335
336 return 0;
337}
338
339static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
340{
341 int ret_val = 0;
342 struct cx25821_fh *fh = priv;
343 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
344
345 ret_val = videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
346
347 p->sequence = dev->vidq[SRAM_CH07].count;
348
349 return ret_val;
350}
351static int vidioc_log_status(struct file *file, void *priv)
352{
353 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
354 char name[32 + 2];
355
356 struct sram_channel *sram_ch = &dev->sram_channels[SRAM_CH07];
357 u32 tmp = 0;
358
359 snprintf(name, sizeof(name), "%s/2", dev->name);
360 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
361 dev->name);
362 cx25821_call_all(dev, core, log_status);
363
364 tmp = cx_read(sram_ch->dma_ctl);
365 printk(KERN_INFO "Video input 7 is %s\n",
366 (tmp & 0x11) ? "streaming" : "stopped");
367 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
368 dev->name);
369 return 0;
370}
371
372static int vidioc_s_ctrl(struct file *file, void *priv,
373 struct v4l2_control *ctl)
374{
375 struct cx25821_fh *fh = priv;
376 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
377 int err;
378
379 if (fh) {
380 err = v4l2_prio_check(&dev->prio, &fh->prio);
381 if (0 != err)
382 return err;
383 }
384
385 return cx25821_set_control(dev, ctl, SRAM_CH07);
386}
387
388// exported stuff
389static const struct v4l2_file_operations video_fops = {
390 .owner = THIS_MODULE,
391 .open = video_open,
392 .release = video_release,
393 .read = video_read,
394 .poll = video_poll,
395 .mmap = video_mmap,
396 .ioctl = video_ioctl2,
397};
398
399static const struct v4l2_ioctl_ops video_ioctl_ops = {
400 .vidioc_querycap = vidioc_querycap,
401 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
402 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
403 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
404 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
405 .vidioc_reqbufs = vidioc_reqbufs,
406 .vidioc_querybuf = vidioc_querybuf,
407 .vidioc_qbuf = vidioc_qbuf,
408 .vidioc_dqbuf = vidioc_dqbuf,
409#ifdef TUNER_FLAG
410 .vidioc_s_std = vidioc_s_std,
411 .vidioc_querystd = vidioc_querystd,
412#endif
413 .vidioc_cropcap = vidioc_cropcap,
414 .vidioc_s_crop = vidioc_s_crop,
415 .vidioc_g_crop = vidioc_g_crop,
416 .vidioc_enum_input = vidioc_enum_input,
417 .vidioc_g_input = vidioc_g_input,
418 .vidioc_s_input = vidioc_s_input,
419 .vidioc_g_ctrl = vidioc_g_ctrl,
420 .vidioc_s_ctrl = vidioc_s_ctrl,
421 .vidioc_queryctrl = vidioc_queryctrl,
422 .vidioc_streamon = vidioc_streamon,
423 .vidioc_streamoff = vidioc_streamoff,
424 .vidioc_log_status = vidioc_log_status,
425 .vidioc_g_priority = vidioc_g_priority,
426 .vidioc_s_priority = vidioc_s_priority,
427#ifdef CONFIG_VIDEO_V4L1_COMPAT
428 .vidiocgmbuf = vidiocgmbuf,
429#endif
430#ifdef TUNER_FLAG
431 .vidioc_g_tuner = vidioc_g_tuner,
432 .vidioc_s_tuner = vidioc_s_tuner,
433 .vidioc_g_frequency = vidioc_g_frequency,
434 .vidioc_s_frequency = vidioc_s_frequency,
435#endif
436#ifdef CONFIG_VIDEO_ADV_DEBUG
437 .vidioc_g_register = vidioc_g_register,
438 .vidioc_s_register = vidioc_s_register,
439#endif
440};
441
442struct video_device cx25821_video_template7 = {
443 .name = "cx25821-video",
444 .fops = &video_fops,
445 .minor = -1,
446 .ioctl_ops = &video_ioctl_ops,
447 .tvnorms = CX25821_NORMS,
448 .current_norm = V4L2_STD_NTSC_M,
449};
diff --git a/drivers/staging/cx25821/cx25821-videoioctl.c b/drivers/staging/cx25821/cx25821-videoioctl.c
new file mode 100644
index 000000000000..2a312ce78c63
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-videoioctl.c
@@ -0,0 +1,496 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[VIDEO_IOCTL_CH];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[VIDEO_IOCTL_CH]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102 u32 pix_format;
103
104 lock_kernel();
105 list_for_each(list, &cx25821_devlist) {
106 h = list_entry(list, struct cx25821_dev, devlist);
107
108 if (h->ioctl_dev && h->ioctl_dev->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = VIDEO_IOCTL_CH;
139 pix_format = V4L2_PIX_FMT_YUYV;
140 fh->fmt = format_by_fourcc(pix_format);
141
142 v4l2_prio_open(&dev->prio, &fh->prio);
143
144 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
145 &dev->pci->dev, &dev->slock,
146 V4L2_BUF_TYPE_VIDEO_CAPTURE,
147 V4L2_FIELD_INTERLACED,
148 sizeof(struct cx25821_buffer), fh);
149
150 dprintk(1, "post videobuf_queue_init()\n");
151 unlock_kernel();
152
153 return 0;
154}
155
156static ssize_t video_read(struct file *file, char __user * data, size_t count,
157 loff_t * ppos)
158{
159 struct cx25821_fh *fh = file->private_data;
160
161 switch (fh->type) {
162 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
163 if (res_locked(fh->dev, RESOURCE_VIDEO_IOCTL))
164 return -EBUSY;
165
166 return videobuf_read_one(&fh->vidq, data, count, ppos,
167 file->f_flags & O_NONBLOCK);
168
169 default:
170 BUG();
171 return 0;
172 }
173}
174
175static unsigned int video_poll(struct file *file,
176 struct poll_table_struct *wait)
177{
178 struct cx25821_fh *fh = file->private_data;
179 struct cx25821_buffer *buf;
180
181 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
182 /* streaming capture */
183 if (list_empty(&fh->vidq.stream))
184 return POLLERR;
185 buf = list_entry(fh->vidq.stream.next,
186 struct cx25821_buffer, vb.stream);
187 } else {
188 /* read() capture */
189 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
190 if (NULL == buf)
191 return POLLERR;
192 }
193
194 poll_wait(file, &buf->vb.done, wait);
195 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
196 return POLLIN | POLLRDNORM;
197
198 return 0;
199}
200
201static int video_release(struct file *file)
202{
203 struct cx25821_fh *fh = file->private_data;
204 struct cx25821_dev *dev = fh->dev;
205
206 /* stop video capture */
207 if (res_check(fh, RESOURCE_VIDEO_IOCTL)) {
208 videobuf_queue_cancel(&fh->vidq);
209 res_free(dev, fh, RESOURCE_VIDEO_IOCTL);
210 }
211
212 if (fh->vidq.read_buf) {
213 buffer_release(&fh->vidq, fh->vidq.read_buf);
214 kfree(fh->vidq.read_buf);
215 }
216
217 videobuf_mmap_free(&fh->vidq);
218
219 v4l2_prio_close(&dev->prio, &fh->prio);
220
221 file->private_data = NULL;
222 kfree(fh);
223
224 return 0;
225}
226
227static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
228{
229 struct cx25821_fh *fh = priv;
230 struct cx25821_dev *dev = fh->dev;
231
232 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
233 return -EINVAL;
234 }
235
236 if (unlikely(i != fh->type)) {
237 return -EINVAL;
238 }
239
240 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO_IOCTL)))) {
241 return -EBUSY;
242 }
243
244 return videobuf_streamon(get_queue(fh));
245}
246
247static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
248{
249 struct cx25821_fh *fh = priv;
250 struct cx25821_dev *dev = fh->dev;
251 int err, res;
252
253 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
254 return -EINVAL;
255 if (i != fh->type)
256 return -EINVAL;
257
258 res = get_resource(fh, RESOURCE_VIDEO_IOCTL);
259 err = videobuf_streamoff(get_queue(fh));
260 if (err < 0)
261 return err;
262 res_free(dev, fh, res);
263 return 0;
264}
265
266static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
267 struct v4l2_format *f)
268{
269 struct cx25821_fh *fh = priv;
270 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
271 int err;
272
273 if (fh) {
274 err = v4l2_prio_check(&dev->prio, &fh->prio);
275 if (0 != err)
276 return err;
277 }
278
279 dprintk(2, "%s()\n", __func__);
280 err = vidioc_try_fmt_vid_cap(file, priv, f);
281
282 if (0 != err)
283 return err;
284 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
285 fh->width = f->fmt.pix.width;
286 fh->height = f->fmt.pix.height;
287 fh->vidq.field = f->fmt.pix.field;
288 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
289 fh->height, fh->vidq.field);
290 cx25821_call_all(dev, video, s_fmt, f);
291 return 0;
292}
293
294static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
295{
296 struct cx25821_fh *fh = priv;
297 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
298}
299
300static long video_ioctl_set(struct file *file, unsigned int cmd,
301 unsigned long arg)
302{
303 struct cx25821_fh *fh = file->private_data;
304 struct cx25821_dev *dev = fh->dev;
305 struct downstream_user_struct *data_from_user;
306 int command;
307 int width = 720;
308 int selected_channel = 0, pix_format = 0, i = 0;
309 int cif_enable = 0, cif_width = 0;
310 u32 value = 0;
311
312 data_from_user = (struct downstream_user_struct *)arg;
313
314 if (!data_from_user) {
315 printk("cx25821 in %s(): User data is INVALID. Returning.\n",
316 __func__);
317 return 0;
318 }
319
320 command = data_from_user->command;
321
322 if (command != SET_VIDEO_STD && command != SET_PIXEL_FORMAT
323 && command != ENABLE_CIF_RESOLUTION && command != REG_READ
324 && command != REG_WRITE && command != MEDUSA_READ
325 && command != MEDUSA_WRITE) {
326 return 0;
327 }
328
329 switch (command) {
330 case SET_VIDEO_STD:
331 dev->tvnorm =
332 !strcmp(data_from_user->vid_stdname,
333 "PAL") ? V4L2_STD_PAL_BG : V4L2_STD_NTSC_M;
334 medusa_set_videostandard(dev);
335 break;
336
337 case SET_PIXEL_FORMAT:
338 selected_channel = data_from_user->decoder_select;
339 pix_format = data_from_user->pixel_format;
340
341 if (!(selected_channel <= 7 && selected_channel >= 0)) {
342 selected_channel -= 4;
343 selected_channel = selected_channel % 8;
344 }
345
346 if (selected_channel >= 0)
347 cx25821_set_pixel_format(dev, selected_channel,
348 pix_format);
349
350 break;
351
352 case ENABLE_CIF_RESOLUTION:
353 selected_channel = data_from_user->decoder_select;
354 cif_enable = data_from_user->cif_resolution_enable;
355 cif_width = data_from_user->cif_width;
356
357 if (cif_enable) {
358 if (dev->tvnorm & V4L2_STD_PAL_BG
359 || dev->tvnorm & V4L2_STD_PAL_DK)
360 width = 352;
361 else
362 width = (cif_width == 320
363 || cif_width == 352) ? cif_width : 320;
364 }
365
366 if (!(selected_channel <= 7 && selected_channel >= 0)) {
367 selected_channel -= 4;
368 selected_channel = selected_channel % 8;
369 }
370
371 if (selected_channel <= 7 && selected_channel >= 0) {
372 dev->use_cif_resolution[selected_channel] = cif_enable;
373 dev->cif_width[selected_channel] = width;
374 } else {
375 for (i = 0; i < VID_CHANNEL_NUM; i++) {
376 dev->use_cif_resolution[i] = cif_enable;
377 dev->cif_width[i] = width;
378 }
379 }
380
381 medusa_set_resolution(dev, width, selected_channel);
382 break;
383 case REG_READ:
384 data_from_user->reg_data = cx_read(data_from_user->reg_address);
385 break;
386 case REG_WRITE:
387 cx_write(data_from_user->reg_address, data_from_user->reg_data);
388 break;
389 case MEDUSA_READ:
390 value =
391 cx25821_i2c_read(&dev->i2c_bus[0],
392 (u16) data_from_user->reg_address,
393 &data_from_user->reg_data);
394 break;
395 case MEDUSA_WRITE:
396 cx25821_i2c_write(&dev->i2c_bus[0],
397 (u16) data_from_user->reg_address,
398 data_from_user->reg_data);
399 break;
400 }
401
402 return 0;
403}
404
405static int vidioc_log_status(struct file *file, void *priv)
406{
407 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
408 char name[32 + 2];
409
410 snprintf(name, sizeof(name), "%s/2", dev->name);
411 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
412 dev->name);
413 cx25821_call_all(dev, core, log_status);
414 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
415 dev->name);
416 return 0;
417}
418
419static int vidioc_s_ctrl(struct file *file, void *priv,
420 struct v4l2_control *ctl)
421{
422 struct cx25821_fh *fh = priv;
423 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
424 int err;
425
426 if (fh) {
427 err = v4l2_prio_check(&dev->prio, &fh->prio);
428 if (0 != err)
429 return err;
430 }
431
432 return 0;
433}
434
435// exported stuff
436static const struct v4l2_file_operations video_fops = {
437 .owner = THIS_MODULE,
438 .open = video_open,
439 .release = video_release,
440 .read = video_read,
441 .poll = video_poll,
442 .mmap = video_mmap,
443 .ioctl = video_ioctl_set,
444};
445
446static const struct v4l2_ioctl_ops video_ioctl_ops = {
447 .vidioc_querycap = vidioc_querycap,
448 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
449 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
450 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
451 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
452 .vidioc_reqbufs = vidioc_reqbufs,
453 .vidioc_querybuf = vidioc_querybuf,
454 .vidioc_qbuf = vidioc_qbuf,
455 .vidioc_dqbuf = vidioc_dqbuf,
456#ifdef TUNER_FLAG
457 .vidioc_s_std = vidioc_s_std,
458 .vidioc_querystd = vidioc_querystd,
459#endif
460 .vidioc_cropcap = vidioc_cropcap,
461 .vidioc_s_crop = vidioc_s_crop,
462 .vidioc_g_crop = vidioc_g_crop,
463 .vidioc_enum_input = vidioc_enum_input,
464 .vidioc_g_input = vidioc_g_input,
465 .vidioc_s_input = vidioc_s_input,
466 .vidioc_g_ctrl = vidioc_g_ctrl,
467 .vidioc_s_ctrl = vidioc_s_ctrl,
468 .vidioc_queryctrl = vidioc_queryctrl,
469 .vidioc_streamon = vidioc_streamon,
470 .vidioc_streamoff = vidioc_streamoff,
471 .vidioc_log_status = vidioc_log_status,
472 .vidioc_g_priority = vidioc_g_priority,
473 .vidioc_s_priority = vidioc_s_priority,
474#ifdef CONFIG_VIDEO_V4L1_COMPAT
475 .vidiocgmbuf = vidiocgmbuf,
476#endif
477#ifdef TUNER_FLAG
478 .vidioc_g_tuner = vidioc_g_tuner,
479 .vidioc_s_tuner = vidioc_s_tuner,
480 .vidioc_g_frequency = vidioc_g_frequency,
481 .vidioc_s_frequency = vidioc_s_frequency,
482#endif
483#ifdef CONFIG_VIDEO_ADV_DEBUG
484 .vidioc_g_register = vidioc_g_register,
485 .vidioc_s_register = vidioc_s_register,
486#endif
487};
488
489struct video_device cx25821_videoioctl_template = {
490 .name = "cx25821-videoioctl",
491 .fops = &video_fops,
492 .minor = -1,
493 .ioctl_ops = &video_ioctl_ops,
494 .tvnorms = CX25821_NORMS,
495 .current_norm = V4L2_STD_NTSC_M,
496};
diff --git a/drivers/staging/cx25821/cx25821-vidups10.c b/drivers/staging/cx25821/cx25821-vidups10.c
new file mode 100644
index 000000000000..77b63b060405
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups10.c
@@ -0,0 +1,435 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH10];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH10]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH10]
108 && h->video_dev[SRAM_CH10]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 9;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user * data, size_t count,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO10))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO10)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
197}
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 //stop the risc engine and fifo
205 //cx_write(channel10->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO10)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO10);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO10)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO10);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static long video_ioctl_upstream10(struct file *file, unsigned int cmd,
268 unsigned long arg)
269{
270 struct cx25821_fh *fh = file->private_data;
271 struct cx25821_dev *dev = fh->dev;
272 int command = 0;
273 struct upstream_user_struct *data_from_user;
274
275 data_from_user = (struct upstream_user_struct *)arg;
276
277 if (!data_from_user) {
278 printk
279 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
280 __func__);
281 return 0;
282 }
283
284 command = data_from_user->command;
285
286 if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
287 return 0;
288 }
289
290 dev->input_filename_ch2 = data_from_user->input_filename;
291 dev->input_audiofilename = data_from_user->input_filename;
292 dev->vid_stdname_ch2 = data_from_user->vid_stdname;
293 dev->pixel_format_ch2 = data_from_user->pixel_format;
294 dev->channel_select_ch2 = data_from_user->channel_select;
295 dev->command_ch2 = data_from_user->command;
296
297 switch (command) {
298 case UPSTREAM_START_VIDEO:
299 cx25821_start_upstream_video_ch2(dev, data_from_user);
300 break;
301
302 case UPSTREAM_STOP_VIDEO:
303 cx25821_stop_upstream_video_ch2(dev);
304 break;
305 }
306
307 return 0;
308}
309
310static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
311 struct v4l2_format *f)
312{
313 struct cx25821_fh *fh = priv;
314 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
315 int err;
316
317 if (fh) {
318 err = v4l2_prio_check(&dev->prio, &fh->prio);
319 if (0 != err)
320 return err;
321 }
322
323 dprintk(2, "%s()\n", __func__);
324 err = vidioc_try_fmt_vid_cap(file, priv, f);
325
326 if (0 != err)
327 return err;
328 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
329 fh->width = f->fmt.pix.width;
330 fh->height = f->fmt.pix.height;
331 fh->vidq.field = f->fmt.pix.field;
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343
344static int vidioc_log_status(struct file *file, void *priv)
345{
346 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
347 char name[32 + 2];
348
349 snprintf(name, sizeof(name), "%s/2", dev->name);
350 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
351 dev->name);
352 cx25821_call_all(dev, core, log_status);
353 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
354 dev->name);
355 return 0;
356}
357
358static int vidioc_s_ctrl(struct file *file, void *priv,
359 struct v4l2_control *ctl)
360{
361 struct cx25821_fh *fh = priv;
362 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
363 int err;
364
365 if (fh) {
366 err = v4l2_prio_check(&dev->prio, &fh->prio);
367 if (0 != err)
368 return err;
369 }
370
371 return 0;
372}
373
374//exported stuff
375static const struct v4l2_file_operations video_fops = {
376 .owner = THIS_MODULE,
377 .open = video_open,
378 .release = video_release,
379 .read = video_read,
380 .poll = video_poll,
381 .mmap = video_mmap,
382 .ioctl = video_ioctl_upstream10,
383};
384
385static const struct v4l2_ioctl_ops video_ioctl_ops = {
386 .vidioc_querycap = vidioc_querycap,
387 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
388 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
389 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
390 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
391 .vidioc_reqbufs = vidioc_reqbufs,
392 .vidioc_querybuf = vidioc_querybuf,
393 .vidioc_qbuf = vidioc_qbuf,
394 .vidioc_dqbuf = vidioc_dqbuf,
395#ifdef TUNER_FLAG
396 .vidioc_s_std = vidioc_s_std,
397 .vidioc_querystd = vidioc_querystd,
398#endif
399 .vidioc_cropcap = vidioc_cropcap,
400 .vidioc_s_crop = vidioc_s_crop,
401 .vidioc_g_crop = vidioc_g_crop,
402 .vidioc_enum_input = vidioc_enum_input,
403 .vidioc_g_input = vidioc_g_input,
404 .vidioc_s_input = vidioc_s_input,
405 .vidioc_g_ctrl = vidioc_g_ctrl,
406 .vidioc_s_ctrl = vidioc_s_ctrl,
407 .vidioc_queryctrl = vidioc_queryctrl,
408 .vidioc_streamon = vidioc_streamon,
409 .vidioc_streamoff = vidioc_streamoff,
410 .vidioc_log_status = vidioc_log_status,
411 .vidioc_g_priority = vidioc_g_priority,
412 .vidioc_s_priority = vidioc_s_priority,
413#ifdef CONFIG_VIDEO_V4L1_COMPAT
414 .vidiocgmbuf = vidiocgmbuf,
415#endif
416#ifdef TUNER_FLAG
417 .vidioc_g_tuner = vidioc_g_tuner,
418 .vidioc_s_tuner = vidioc_s_tuner,
419 .vidioc_g_frequency = vidioc_g_frequency,
420 .vidioc_s_frequency = vidioc_s_frequency,
421#endif
422#ifdef CONFIG_VIDEO_ADV_DEBUG
423 .vidioc_g_register = vidioc_g_register,
424 .vidioc_s_register = vidioc_s_register,
425#endif
426};
427
428struct video_device cx25821_video_template10 = {
429 .name = "cx25821-upstream10",
430 .fops = &video_fops,
431 .minor = -1,
432 .ioctl_ops = &video_ioctl_ops,
433 .tvnorms = CX25821_NORMS,
434 .current_norm = V4L2_STD_NTSC_M,
435};
diff --git a/drivers/staging/cx25821/cx25821-vidups9.c b/drivers/staging/cx25821/cx25821-vidups9.c
new file mode 100644
index 000000000000..75c8c1eed2da
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821-vidups9.c
@@ -0,0 +1,433 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "cx25821-video.h"
25
26static void buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
27{
28 struct cx25821_buffer *buf =
29 container_of(vb, struct cx25821_buffer, vb);
30 struct cx25821_buffer *prev;
31 struct cx25821_fh *fh = vq->priv_data;
32 struct cx25821_dev *dev = fh->dev;
33 struct cx25821_dmaqueue *q = &dev->vidq[SRAM_CH09];
34
35 /* add jump to stopper */
36 buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC);
37 buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma);
38 buf->risc.jmp[2] = cpu_to_le32(0); /* bits 63-32 */
39
40 dprintk(2, "jmp to stopper (0x%x)\n", buf->risc.jmp[1]);
41
42 if (!list_empty(&q->queued)) {
43 list_add_tail(&buf->vb.queue, &q->queued);
44 buf->vb.state = VIDEOBUF_QUEUED;
45 dprintk(2, "[%p/%d] buffer_queue - append to queued\n", buf,
46 buf->vb.i);
47
48 } else if (list_empty(&q->active)) {
49 list_add_tail(&buf->vb.queue, &q->active);
50 cx25821_start_video_dma(dev, q, buf,
51 &dev->sram_channels[SRAM_CH09]);
52 buf->vb.state = VIDEOBUF_ACTIVE;
53 buf->count = q->count++;
54 mod_timer(&q->timeout, jiffies + BUFFER_TIMEOUT);
55 dprintk(2,
56 "[%p/%d] buffer_queue - first active, buf cnt = %d, q->count = %d\n",
57 buf, buf->vb.i, buf->count, q->count);
58 } else {
59 prev =
60 list_entry(q->active.prev, struct cx25821_buffer, vb.queue);
61 if (prev->vb.width == buf->vb.width
62 && prev->vb.height == buf->vb.height
63 && prev->fmt == buf->fmt) {
64 list_add_tail(&buf->vb.queue, &q->active);
65 buf->vb.state = VIDEOBUF_ACTIVE;
66 buf->count = q->count++;
67 prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma);
68
69 /* 64 bit bits 63-32 */
70 prev->risc.jmp[2] = cpu_to_le32(0);
71 dprintk(2,
72 "[%p/%d] buffer_queue - append to active, buf->count=%d\n",
73 buf, buf->vb.i, buf->count);
74
75 } else {
76 list_add_tail(&buf->vb.queue, &q->queued);
77 buf->vb.state = VIDEOBUF_QUEUED;
78 dprintk(2, "[%p/%d] buffer_queue - first queued\n", buf,
79 buf->vb.i);
80 }
81 }
82
83 if (list_empty(&q->active)) {
84 dprintk(2, "active queue empty!\n");
85 }
86}
87
88static struct videobuf_queue_ops cx25821_video_qops = {
89 .buf_setup = buffer_setup,
90 .buf_prepare = buffer_prepare,
91 .buf_queue = buffer_queue,
92 .buf_release = buffer_release,
93};
94
95static int video_open(struct file *file)
96{
97 int minor = video_devdata(file)->minor;
98 struct cx25821_dev *h, *dev = NULL;
99 struct cx25821_fh *fh;
100 struct list_head *list;
101 enum v4l2_buf_type type = 0;
102
103 lock_kernel();
104 list_for_each(list, &cx25821_devlist) {
105 h = list_entry(list, struct cx25821_dev, devlist);
106
107 if (h->video_dev[SRAM_CH09]
108 && h->video_dev[SRAM_CH09]->minor == minor) {
109 dev = h;
110 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
111 }
112 }
113
114 if (NULL == dev) {
115 unlock_kernel();
116 return -ENODEV;
117 }
118
119 printk("open minor=%d type=%s\n", minor, v4l2_type_names[type]);
120
121 /* allocate + initialize per filehandle data */
122 fh = kzalloc(sizeof(*fh), GFP_KERNEL);
123 if (NULL == fh) {
124 unlock_kernel();
125 return -ENOMEM;
126 }
127
128 file->private_data = fh;
129 fh->dev = dev;
130 fh->type = type;
131 fh->width = 720;
132
133 if (dev->tvnorm & V4L2_STD_PAL_BG || dev->tvnorm & V4L2_STD_PAL_DK)
134 fh->height = 576;
135 else
136 fh->height = 480;
137
138 dev->channel_opened = 8;
139 fh->fmt = format_by_fourcc(V4L2_PIX_FMT_YUYV);
140
141 v4l2_prio_open(&dev->prio, &fh->prio);
142
143 videobuf_queue_sg_init(&fh->vidq, &cx25821_video_qops,
144 &dev->pci->dev, &dev->slock,
145 V4L2_BUF_TYPE_VIDEO_CAPTURE,
146 V4L2_FIELD_INTERLACED,
147 sizeof(struct cx25821_buffer), fh);
148
149 dprintk(1, "post videobuf_queue_init()\n");
150 unlock_kernel();
151
152 return 0;
153}
154
155static ssize_t video_read(struct file *file, char __user * data, size_t count,
156 loff_t * ppos)
157{
158 struct cx25821_fh *fh = file->private_data;
159
160 switch (fh->type) {
161 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
162 if (res_locked(fh->dev, RESOURCE_VIDEO9))
163 return -EBUSY;
164
165 return videobuf_read_one(&fh->vidq, data, count, ppos,
166 file->f_flags & O_NONBLOCK);
167
168 default:
169 BUG();
170 return 0;
171 }
172}
173
174static unsigned int video_poll(struct file *file,
175 struct poll_table_struct *wait)
176{
177 struct cx25821_fh *fh = file->private_data;
178 struct cx25821_buffer *buf;
179
180 if (res_check(fh, RESOURCE_VIDEO9)) {
181 /* streaming capture */
182 if (list_empty(&fh->vidq.stream))
183 return POLLERR;
184 buf = list_entry(fh->vidq.stream.next,
185 struct cx25821_buffer, vb.stream);
186 } else {
187 /* read() capture */
188 buf = (struct cx25821_buffer *)fh->vidq.read_buf;
189 if (NULL == buf)
190 return POLLERR;
191 }
192
193 poll_wait(file, &buf->vb.done, wait);
194 if (buf->vb.state == VIDEOBUF_DONE || buf->vb.state == VIDEOBUF_ERROR)
195 return POLLIN | POLLRDNORM;
196 return 0;
197}
198
199static int video_release(struct file *file)
200{
201 struct cx25821_fh *fh = file->private_data;
202 struct cx25821_dev *dev = fh->dev;
203
204 //stop the risc engine and fifo
205 //cx_write(channel9->dma_ctl, 0);
206
207 /* stop video capture */
208 if (res_check(fh, RESOURCE_VIDEO9)) {
209 videobuf_queue_cancel(&fh->vidq);
210 res_free(dev, fh, RESOURCE_VIDEO9);
211 }
212
213 if (fh->vidq.read_buf) {
214 buffer_release(&fh->vidq, fh->vidq.read_buf);
215 kfree(fh->vidq.read_buf);
216 }
217
218 videobuf_mmap_free(&fh->vidq);
219
220 v4l2_prio_close(&dev->prio, &fh->prio);
221
222 file->private_data = NULL;
223 kfree(fh);
224
225 return 0;
226}
227
228static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
229{
230 struct cx25821_fh *fh = priv;
231 struct cx25821_dev *dev = fh->dev;
232
233 if (unlikely(fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)) {
234 return -EINVAL;
235 }
236
237 if (unlikely(i != fh->type)) {
238 return -EINVAL;
239 }
240
241 if (unlikely(!res_get(dev, fh, get_resource(fh, RESOURCE_VIDEO9)))) {
242 return -EBUSY;
243 }
244
245 return videobuf_streamon(get_queue(fh));
246}
247
248static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
249{
250 struct cx25821_fh *fh = priv;
251 struct cx25821_dev *dev = fh->dev;
252 int err, res;
253
254 if (fh->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
255 return -EINVAL;
256 if (i != fh->type)
257 return -EINVAL;
258
259 res = get_resource(fh, RESOURCE_VIDEO9);
260 err = videobuf_streamoff(get_queue(fh));
261 if (err < 0)
262 return err;
263 res_free(dev, fh, res);
264 return 0;
265}
266
267static long video_ioctl_upstream9(struct file *file, unsigned int cmd,
268 unsigned long arg)
269{
270 struct cx25821_fh *fh = file->private_data;
271 struct cx25821_dev *dev = fh->dev;
272 int command = 0;
273 struct upstream_user_struct *data_from_user;
274
275 data_from_user = (struct upstream_user_struct *)arg;
276
277 if (!data_from_user) {
278 printk
279 ("cx25821 in %s(): Upstream data is INVALID. Returning.\n",
280 __func__);
281 return 0;
282 }
283
284 command = data_from_user->command;
285
286 if (command != UPSTREAM_START_VIDEO && command != UPSTREAM_STOP_VIDEO) {
287 return 0;
288 }
289
290 dev->input_filename = data_from_user->input_filename;
291 dev->input_audiofilename = data_from_user->input_filename;
292 dev->vid_stdname = data_from_user->vid_stdname;
293 dev->pixel_format = data_from_user->pixel_format;
294 dev->channel_select = data_from_user->channel_select;
295 dev->command = data_from_user->command;
296
297 switch (command) {
298 case UPSTREAM_START_VIDEO:
299 cx25821_start_upstream_video_ch1(dev, data_from_user);
300 break;
301
302 case UPSTREAM_STOP_VIDEO:
303 cx25821_stop_upstream_video_ch1(dev);
304 break;
305 }
306
307 return 0;
308}
309
310static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
311 struct v4l2_format *f)
312{
313 struct cx25821_fh *fh = priv;
314 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
315 int err;
316
317 if (fh) {
318 err = v4l2_prio_check(&dev->prio, &fh->prio);
319 if (0 != err)
320 return err;
321 }
322
323 dprintk(2, "%s()\n", __func__);
324 err = vidioc_try_fmt_vid_cap(file, priv, f);
325
326 if (0 != err)
327 return err;
328 fh->fmt = format_by_fourcc(f->fmt.pix.pixelformat);
329 fh->width = f->fmt.pix.width;
330 fh->height = f->fmt.pix.height;
331 fh->vidq.field = f->fmt.pix.field;
332 dprintk(2, "%s() width=%d height=%d field=%d\n", __func__, fh->width,
333 fh->height, fh->vidq.field);
334 cx25821_call_all(dev, video, s_fmt, f);
335 return 0;
336}
337
338static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
339{
340 struct cx25821_fh *fh = priv;
341 return videobuf_dqbuf(get_queue(fh), p, file->f_flags & O_NONBLOCK);
342}
343static int vidioc_log_status(struct file *file, void *priv)
344{
345 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
346 char name[32 + 2];
347
348 snprintf(name, sizeof(name), "%s/2", dev->name);
349 printk(KERN_INFO "%s/2: ============ START LOG STATUS ============\n",
350 dev->name);
351 cx25821_call_all(dev, core, log_status);
352 printk(KERN_INFO "%s/2: ============= END LOG STATUS =============\n",
353 dev->name);
354 return 0;
355}
356
357static int vidioc_s_ctrl(struct file *file, void *priv,
358 struct v4l2_control *ctl)
359{
360 struct cx25821_dev *dev = ((struct cx25821_fh *)priv)->dev;
361 struct cx25821_fh *fh = priv;
362 int err;
363 if (fh) {
364 err = v4l2_prio_check(&dev->prio, &fh->prio);
365 if (0 != err)
366 return err;
367 }
368
369 return 0;
370}
371
372// exported stuff
373static const struct v4l2_file_operations video_fops = {
374 .owner = THIS_MODULE,
375 .open = video_open,
376 .release = video_release,
377 .read = video_read,
378 .poll = video_poll,
379 .mmap = video_mmap,
380 .ioctl = video_ioctl_upstream9,
381};
382
383static const struct v4l2_ioctl_ops video_ioctl_ops = {
384 .vidioc_querycap = vidioc_querycap,
385 .vidioc_enum_fmt_vid_cap = vidioc_enum_fmt_vid_cap,
386 .vidioc_g_fmt_vid_cap = vidioc_g_fmt_vid_cap,
387 .vidioc_try_fmt_vid_cap = vidioc_try_fmt_vid_cap,
388 .vidioc_s_fmt_vid_cap = vidioc_s_fmt_vid_cap,
389 .vidioc_reqbufs = vidioc_reqbufs,
390 .vidioc_querybuf = vidioc_querybuf,
391 .vidioc_qbuf = vidioc_qbuf,
392 .vidioc_dqbuf = vidioc_dqbuf,
393#ifdef TUNER_FLAG
394 .vidioc_s_std = vidioc_s_std,
395 .vidioc_querystd = vidioc_querystd,
396#endif
397 .vidioc_cropcap = vidioc_cropcap,
398 .vidioc_s_crop = vidioc_s_crop,
399 .vidioc_g_crop = vidioc_g_crop,
400 .vidioc_enum_input = vidioc_enum_input,
401 .vidioc_g_input = vidioc_g_input,
402 .vidioc_s_input = vidioc_s_input,
403 .vidioc_g_ctrl = vidioc_g_ctrl,
404 .vidioc_s_ctrl = vidioc_s_ctrl,
405 .vidioc_queryctrl = vidioc_queryctrl,
406 .vidioc_streamon = vidioc_streamon,
407 .vidioc_streamoff = vidioc_streamoff,
408 .vidioc_log_status = vidioc_log_status,
409 .vidioc_g_priority = vidioc_g_priority,
410 .vidioc_s_priority = vidioc_s_priority,
411#ifdef CONFIG_VIDEO_V4L1_COMPAT
412 .vidiocgmbuf = vidiocgmbuf,
413#endif
414#ifdef TUNER_FLAG
415 .vidioc_g_tuner = vidioc_g_tuner,
416 .vidioc_s_tuner = vidioc_s_tuner,
417 .vidioc_g_frequency = vidioc_g_frequency,
418 .vidioc_s_frequency = vidioc_s_frequency,
419#endif
420#ifdef CONFIG_VIDEO_ADV_DEBUG
421 .vidioc_g_register = vidioc_g_register,
422 .vidioc_s_register = vidioc_s_register,
423#endif
424};
425
426struct video_device cx25821_video_template9 = {
427 .name = "cx25821-upstream9",
428 .fops = &video_fops,
429 .minor = -1,
430 .ioctl_ops = &video_ioctl_ops,
431 .tvnorms = CX25821_NORMS,
432 .current_norm = V4L2_STD_NTSC_M,
433};
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
new file mode 100644
index 000000000000..cf2286d83b6a
--- /dev/null
+++ b/drivers/staging/cx25821/cx25821.h
@@ -0,0 +1,602 @@
1/*
2 * Driver for the Conexant CX25821 PCIe bridge
3 *
4 * Copyright (C) 2009 Conexant Systems Inc.
5 * Authors <shu.lin@conexant.com>, <hiep.huynh@conexant.com>
6 * Based on Steven Toth <stoth@linuxtv.org> cx23885 driver
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#ifndef CX25821_H_
25#define CX25821_H_
26
27#include <linux/pci.h>
28#include <linux/i2c.h>
29#include <linux/i2c-algo-bit.h>
30#include <linux/interrupt.h>
31#include <linux/delay.h>
32#include <linux/sched.h>
33#include <linux/kdev_t.h>
34#include <linux/smp_lock.h>
35
36#include <media/v4l2-common.h>
37#include <media/v4l2-device.h>
38#include <media/tuner.h>
39#include <media/tveeprom.h>
40#include <media/videobuf-dma-sg.h>
41#include <media/videobuf-dvb.h>
42
43#include "btcx-risc.h"
44#include "cx25821-reg.h"
45#include "cx25821-medusa-reg.h"
46#include "cx25821-sram.h"
47#include "cx25821-audio.h"
48#include "media/cx2341x.h"
49
50#include <linux/version.h>
51#include <linux/mutex.h>
52
53#define CX25821_VERSION_CODE KERNEL_VERSION(0, 0, 106)
54
55#define UNSET (-1U)
56#define NO_SYNC_LINE (-1U)
57
58#define CX25821_MAXBOARDS 2
59
60#define TRUE 1
61#define FALSE 0
62#define LINE_SIZE_D1 1440
63
64// Number of decoders and encoders
65#define MAX_DECODERS 8
66#define MAX_ENCODERS 2
67#define QUAD_DECODERS 4
68#define MAX_CAMERAS 16
69
70/* Max number of inputs by card */
71#define MAX_CX25821_INPUT 8
72#define INPUT(nr) (&cx25821_boards[dev->board].input[nr])
73#define RESOURCE_VIDEO0 1
74#define RESOURCE_VIDEO1 2
75#define RESOURCE_VIDEO2 4
76#define RESOURCE_VIDEO3 8
77#define RESOURCE_VIDEO4 16
78#define RESOURCE_VIDEO5 32
79#define RESOURCE_VIDEO6 64
80#define RESOURCE_VIDEO7 128
81#define RESOURCE_VIDEO8 256
82#define RESOURCE_VIDEO9 512
83#define RESOURCE_VIDEO10 1024
84#define RESOURCE_VIDEO11 2048
85#define RESOURCE_VIDEO_IOCTL 4096
86
87#define BUFFER_TIMEOUT (HZ) /* 0.5 seconds */
88
89#define UNKNOWN_BOARD 0
90#define CX25821_BOARD 1
91
92/* Currently supported by the driver */
93#define CX25821_NORMS (\
94 V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_JP | V4L2_STD_NTSC_M_KR | \
95 V4L2_STD_PAL_BG | V4L2_STD_PAL_DK | V4L2_STD_PAL_I | \
96 V4L2_STD_PAL_M | V4L2_STD_PAL_N | V4L2_STD_PAL_H | \
97 V4L2_STD_PAL_Nc )
98
99#define CX25821_BOARD_CONEXANT_ATHENA10 1
100#define MAX_VID_CHANNEL_NUM 12
101#define VID_CHANNEL_NUM 8
102
103struct cx25821_fmt {
104 char *name;
105 u32 fourcc; /* v4l2 format id */
106 int depth;
107 int flags;
108 u32 cxformat;
109};
110
111struct cx25821_ctrl {
112 struct v4l2_queryctrl v;
113 u32 off;
114 u32 reg;
115 u32 mask;
116 u32 shift;
117};
118
119struct cx25821_tvnorm {
120 char *name;
121 v4l2_std_id id;
122 u32 cxiformat;
123 u32 cxoformat;
124};
125
126struct cx25821_fh {
127 struct cx25821_dev *dev;
128 enum v4l2_buf_type type;
129 int radio;
130 u32 resources;
131
132 enum v4l2_priority prio;
133
134 /* video overlay */
135 struct v4l2_window win;
136 struct v4l2_clip *clips;
137 unsigned int nclips;
138
139 /* video capture */
140 struct cx25821_fmt *fmt;
141 unsigned int width, height;
142
143 /* vbi capture */
144 struct videobuf_queue vidq;
145 struct videobuf_queue vbiq;
146
147 /* H264 Encoder specifics ONLY */
148 struct videobuf_queue mpegq;
149 atomic_t v4l_reading;
150};
151
152enum cx25821_itype {
153 CX25821_VMUX_COMPOSITE = 1,
154 CX25821_VMUX_SVIDEO,
155 CX25821_VMUX_DEBUG,
156 CX25821_RADIO,
157};
158
159enum cx25821_src_sel_type {
160 CX25821_SRC_SEL_EXT_656_VIDEO = 0,
161 CX25821_SRC_SEL_PARALLEL_MPEG_VIDEO
162};
163
164/* buffer for one video frame */
165struct cx25821_buffer {
166 /* common v4l buffer stuff -- must be first */
167 struct videobuf_buffer vb;
168
169 /* cx25821 specific */
170 unsigned int bpl;
171 struct btcx_riscmem risc;
172 struct cx25821_fmt *fmt;
173 u32 count;
174};
175
176struct cx25821_input {
177 enum cx25821_itype type;
178 unsigned int vmux;
179 u32 gpio0, gpio1, gpio2, gpio3;
180};
181
182typedef enum {
183 CX25821_UNDEFINED = 0,
184 CX25821_RAW,
185 CX25821_264
186} port_t;
187
188struct cx25821_board {
189 char *name;
190 port_t porta, portb, portc;
191 unsigned int tuner_type;
192 unsigned int radio_type;
193 unsigned char tuner_addr;
194 unsigned char radio_addr;
195
196 u32 clk_freq;
197 struct cx25821_input input[2];
198};
199
200struct cx25821_subid {
201 u16 subvendor;
202 u16 subdevice;
203 u32 card;
204};
205
206struct cx25821_i2c {
207 struct cx25821_dev *dev;
208
209 int nr;
210
211 /* i2c i/o */
212 struct i2c_adapter i2c_adap;
213 struct i2c_algo_bit_data i2c_algo;
214 struct i2c_client i2c_client;
215 u32 i2c_rc;
216
217 /* cx25821 registers used for raw addess */
218 u32 i2c_period;
219 u32 reg_ctrl;
220 u32 reg_stat;
221 u32 reg_addr;
222 u32 reg_rdata;
223 u32 reg_wdata;
224};
225
226struct cx25821_dmaqueue {
227 struct list_head active;
228 struct list_head queued;
229 struct timer_list timeout;
230 struct btcx_riscmem stopper;
231 u32 count;
232};
233
234struct cx25821_data {
235 struct cx25821_dev *dev;
236 struct sram_channel *channel;
237};
238
239struct cx25821_dev {
240 struct list_head devlist;
241 atomic_t refcount;
242 struct v4l2_device v4l2_dev;
243
244 struct v4l2_prio_state prio;
245
246 /* pci stuff */
247 struct pci_dev *pci;
248 unsigned char pci_rev, pci_lat;
249 int pci_bus, pci_slot;
250 u32 base_io_addr;
251 u32 __iomem *lmmio;
252 u8 __iomem *bmmio;
253 int pci_irqmask;
254 int hwrevision;
255
256 u32 clk_freq;
257
258 /* I2C adapters: Master 1 & 2 (External) & Master 3 (Internal only) */
259 struct cx25821_i2c i2c_bus[3];
260
261 int nr;
262 struct mutex lock;
263
264 /* board details */
265 unsigned int board;
266 char name[32];
267
268 /* sram configuration */
269 struct sram_channel *sram_channels;
270
271 /* Analog video */
272 u32 resources;
273 unsigned int input;
274 u32 tvaudio;
275 v4l2_std_id tvnorm;
276 unsigned int tuner_type;
277 unsigned char tuner_addr;
278 unsigned int radio_type;
279 unsigned char radio_addr;
280 unsigned int has_radio;
281 unsigned int videc_type;
282 unsigned char videc_addr;
283 unsigned short _max_num_decoders;
284
285 int ctl_bright;
286 int ctl_contrast;
287 int ctl_hue;
288 int ctl_saturation;
289
290 struct cx25821_data timeout_data[MAX_VID_CHANNEL_NUM];
291
292 /* Analog Audio Upstream */
293 int _audio_is_running;
294 int _audiopixel_format;
295 int _is_first_audio_frame;
296 int _audiofile_status;
297 int _audio_lines_count;
298 int _audioframe_count;
299 int _audio_upstream_channel_select;
300 int _last_index_irq; //The last interrupt index processed.
301
302 __le32 *_risc_audio_jmp_addr;
303 __le32 *_risc_virt_start_addr;
304 __le32 *_risc_virt_addr;
305 dma_addr_t _risc_phys_addr;
306 dma_addr_t _risc_phys_start_addr;
307
308 unsigned int _audiorisc_size;
309 unsigned int _audiodata_buf_size;
310 __le32 *_audiodata_buf_virt_addr;
311 dma_addr_t _audiodata_buf_phys_addr;
312 char *_audiofilename;
313
314 /* V4l */
315 u32 freq;
316 struct video_device *video_dev[MAX_VID_CHANNEL_NUM];
317 struct video_device *vbi_dev;
318 struct video_device *radio_dev;
319 struct video_device *ioctl_dev;
320
321 struct cx25821_dmaqueue vidq[MAX_VID_CHANNEL_NUM];
322 spinlock_t slock;
323
324 /* Video Upstream */
325 int _line_size;
326 int _prog_cnt;
327 int _pixel_format;
328 int _is_first_frame;
329 int _is_running;
330 int _file_status;
331 int _lines_count;
332 int _frame_count;
333 int _channel_upstream_select;
334 unsigned int _risc_size;
335
336 __le32 *_dma_virt_start_addr;
337 __le32 *_dma_virt_addr;
338 dma_addr_t _dma_phys_addr;
339 dma_addr_t _dma_phys_start_addr;
340
341 unsigned int _data_buf_size;
342 __le32 *_data_buf_virt_addr;
343 dma_addr_t _data_buf_phys_addr;
344 char *_filename;
345 char *_defaultname;
346
347 int _line_size_ch2;
348 int _prog_cnt_ch2;
349 int _pixel_format_ch2;
350 int _is_first_frame_ch2;
351 int _is_running_ch2;
352 int _file_status_ch2;
353 int _lines_count_ch2;
354 int _frame_count_ch2;
355 int _channel2_upstream_select;
356 unsigned int _risc_size_ch2;
357
358 __le32 *_dma_virt_start_addr_ch2;
359 __le32 *_dma_virt_addr_ch2;
360 dma_addr_t _dma_phys_addr_ch2;
361 dma_addr_t _dma_phys_start_addr_ch2;
362
363 unsigned int _data_buf_size_ch2;
364 __le32 *_data_buf_virt_addr_ch2;
365 dma_addr_t _data_buf_phys_addr_ch2;
366 char *_filename_ch2;
367 char *_defaultname_ch2;
368
369 /* MPEG Encoder ONLY settings */
370 u32 cx23417_mailbox;
371 struct cx2341x_mpeg_params mpeg_params;
372 struct video_device *v4l_device;
373 atomic_t v4l_reader_count;
374 struct cx25821_tvnorm encodernorm;
375
376 u32 upstream_riscbuf_size;
377 u32 upstream_databuf_size;
378 u32 upstream_riscbuf_size_ch2;
379 u32 upstream_databuf_size_ch2;
380 u32 audio_upstream_riscbuf_size;
381 u32 audio_upstream_databuf_size;
382 int _isNTSC;
383 int _frame_index;
384 int _audioframe_index;
385 struct workqueue_struct *_irq_queues;
386 struct work_struct _irq_work_entry;
387 struct workqueue_struct *_irq_queues_ch2;
388 struct work_struct _irq_work_entry_ch2;
389 struct workqueue_struct *_irq_audio_queues;
390 struct work_struct _audio_work_entry;
391 char *input_filename;
392 char *input_filename_ch2;
393 int _frame_index_ch2;
394 int _isNTSC_ch2;
395 char *vid_stdname_ch2;
396 int pixel_format_ch2;
397 int channel_select_ch2;
398 int command_ch2;
399 char *input_audiofilename;
400 char *vid_stdname;
401 int pixel_format;
402 int channel_select;
403 int command;
404 int pixel_formats[VID_CHANNEL_NUM];
405 int use_cif_resolution[VID_CHANNEL_NUM];
406 int cif_width[VID_CHANNEL_NUM];
407 int channel_opened;
408};
409
410struct upstream_user_struct {
411 char *input_filename;
412 char *vid_stdname;
413 int pixel_format;
414 int channel_select;
415 int command;
416};
417
418struct downstream_user_struct {
419 char *vid_stdname;
420 int pixel_format;
421 int cif_resolution_enable;
422 int cif_width;
423 int decoder_select;
424 int command;
425 int reg_address;
426 int reg_data;
427};
428
429extern struct upstream_user_struct *up_data;
430
431static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
432{
433 return container_of(v4l2_dev, struct cx25821_dev, v4l2_dev);
434}
435
436#define cx25821_call_all(dev, o, f, args...) \
437 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
438
439extern struct list_head cx25821_devlist;
440extern struct cx25821_board cx25821_boards[];
441extern struct cx25821_subid cx25821_subids[];
442
443#define SRAM_CH00 0 /* Video A */
444#define SRAM_CH01 1 /* Video B */
445#define SRAM_CH02 2 /* Video C */
446#define SRAM_CH03 3 /* Video D */
447#define SRAM_CH04 4 /* Video E */
448#define SRAM_CH05 5 /* Video F */
449#define SRAM_CH06 6 /* Video G */
450#define SRAM_CH07 7 /* Video H */
451
452#define SRAM_CH08 8 /* Audio A */
453#define SRAM_CH09 9 /* Video Upstream I */
454#define SRAM_CH10 10 /* Video Upstream J */
455#define SRAM_CH11 11 /* Audio Upstream AUD_CHANNEL_B */
456
457#define VID_UPSTREAM_SRAM_CHANNEL_I SRAM_CH09
458#define VID_UPSTREAM_SRAM_CHANNEL_J SRAM_CH10
459#define AUDIO_UPSTREAM_SRAM_CHANNEL_B SRAM_CH11
460#define VIDEO_IOCTL_CH 11
461
462struct sram_channel {
463 char *name;
464 u32 i;
465 u32 cmds_start;
466 u32 ctrl_start;
467 u32 cdt;
468 u32 fifo_start;
469 u32 fifo_size;
470 u32 ptr1_reg;
471 u32 ptr2_reg;
472 u32 cnt1_reg;
473 u32 cnt2_reg;
474 u32 int_msk;
475 u32 int_stat;
476 u32 int_mstat;
477 u32 dma_ctl;
478 u32 gpcnt_ctl;
479 u32 gpcnt;
480 u32 aud_length;
481 u32 aud_cfg;
482 u32 fld_aud_fifo_en;
483 u32 fld_aud_risc_en;
484
485 //For Upstream Video
486 u32 vid_fmt_ctl;
487 u32 vid_active_ctl1;
488 u32 vid_active_ctl2;
489 u32 vid_cdt_size;
490
491 u32 vip_ctl;
492 u32 pix_frmt;
493 u32 jumponly;
494 u32 irq_bit;
495};
496extern struct sram_channel cx25821_sram_channels[];
497
498#define STATUS_SUCCESS 0
499#define STATUS_UNSUCCESSFUL -1
500
501#define cx_read(reg) readl(dev->lmmio + ((reg)>>2))
502#define cx_write(reg, value) writel((value), dev->lmmio + ((reg)>>2))
503
504#define cx_andor(reg, mask, value) \
505 writel((readl(dev->lmmio+((reg)>>2)) & ~(mask)) |\
506 ((value) & (mask)), dev->lmmio+((reg)>>2))
507
508#define cx_set(reg, bit) cx_andor((reg), (bit), (bit))
509#define cx_clear(reg, bit) cx_andor((reg), (bit), 0)
510
511#define Set_GPIO_Bit(Bit) (1 << Bit)
512#define Clear_GPIO_Bit(Bit) (~(1 << Bit))
513
514#define CX25821_ERR(fmt, args...) printk(KERN_ERR "cx25821(%d): " fmt, dev->board, ## args)
515#define CX25821_WARN(fmt, args...) printk(KERN_WARNING "cx25821(%d): " fmt, dev->board , ## args)
516#define CX25821_INFO(fmt, args...) printk(KERN_INFO "cx25821(%d): " fmt, dev->board , ## args)
517
518extern int cx25821_i2c_register(struct cx25821_i2c *bus);
519extern void cx25821_card_setup(struct cx25821_dev *dev);
520extern int cx25821_ir_init(struct cx25821_dev *dev);
521extern int cx25821_i2c_read(struct cx25821_i2c *bus, u16 reg_addr, int *value);
522extern int cx25821_i2c_write(struct cx25821_i2c *bus, u16 reg_addr, int value);
523extern int cx25821_i2c_unregister(struct cx25821_i2c *bus);
524extern void cx25821_gpio_init(struct cx25821_dev *dev);
525extern void cx25821_set_gpiopin_direction(struct cx25821_dev *dev,
526 int pin_number, int pin_logic_value);
527
528extern int medusa_video_init(struct cx25821_dev *dev);
529extern int medusa_set_videostandard(struct cx25821_dev *dev);
530extern void medusa_set_resolution(struct cx25821_dev *dev, int width,
531 int decoder_select);
532extern int medusa_set_brightness(struct cx25821_dev *dev, int brightness,
533 int decoder);
534extern int medusa_set_contrast(struct cx25821_dev *dev, int contrast,
535 int decoder);
536extern int medusa_set_hue(struct cx25821_dev *dev, int hue, int decoder);
537extern int medusa_set_saturation(struct cx25821_dev *dev, int saturation,
538 int decoder);
539
540extern int cx25821_sram_channel_setup(struct cx25821_dev *dev,
541 struct sram_channel *ch, unsigned int bpl,
542 u32 risc);
543
544extern int cx25821_risc_buffer(struct pci_dev *pci, struct btcx_riscmem *risc,
545 struct scatterlist *sglist,
546 unsigned int top_offset,
547 unsigned int bottom_offset,
548 unsigned int bpl,
549 unsigned int padding, unsigned int lines);
550extern int cx25821_risc_databuffer_audio(struct pci_dev *pci,
551 struct btcx_riscmem *risc,
552 struct scatterlist *sglist,
553 unsigned int bpl,
554 unsigned int lines, unsigned int lpi);
555extern void cx25821_free_buffer(struct videobuf_queue *q,
556 struct cx25821_buffer *buf);
557extern int cx25821_risc_stopper(struct pci_dev *pci, struct btcx_riscmem *risc,
558 u32 reg, u32 mask, u32 value);
559extern void cx25821_sram_channel_dump(struct cx25821_dev *dev,
560 struct sram_channel *ch);
561extern void cx25821_sram_channel_dump_audio(struct cx25821_dev *dev,
562 struct sram_channel *ch);
563
564extern struct cx25821_dev *cx25821_dev_get(struct pci_dev *pci);
565extern void cx25821_print_irqbits(char *name, char *tag, char **strings,
566 int len, u32 bits, u32 mask);
567extern void cx25821_dev_unregister(struct cx25821_dev *dev);
568extern int cx25821_sram_channel_setup_audio(struct cx25821_dev *dev,
569 struct sram_channel *ch,
570 unsigned int bpl, u32 risc);
571
572extern int cx25821_vidupstream_init_ch1(struct cx25821_dev *dev,
573 int channel_select, int pixel_format);
574extern int cx25821_vidupstream_init_ch2(struct cx25821_dev *dev,
575 int channel_select, int pixel_format);
576extern int cx25821_audio_upstream_init(struct cx25821_dev *dev,
577 int channel_select);
578extern void cx25821_free_mem_upstream_ch1(struct cx25821_dev *dev);
579extern void cx25821_free_mem_upstream_ch2(struct cx25821_dev *dev);
580extern void cx25821_free_mem_upstream_audio(struct cx25821_dev *dev);
581extern void cx25821_start_upstream_video_ch1(struct cx25821_dev *dev,
582 struct upstream_user_struct
583 *up_data);
584extern void cx25821_start_upstream_video_ch2(struct cx25821_dev *dev,
585 struct upstream_user_struct
586 *up_data);
587extern void cx25821_start_upstream_audio(struct cx25821_dev *dev,
588 struct upstream_user_struct *up_data);
589extern void cx25821_stop_upstream_video_ch1(struct cx25821_dev *dev);
590extern void cx25821_stop_upstream_video_ch2(struct cx25821_dev *dev);
591extern void cx25821_stop_upstream_audio(struct cx25821_dev *dev);
592extern int cx25821_sram_channel_setup_upstream(struct cx25821_dev *dev,
593 struct sram_channel *ch,
594 unsigned int bpl, u32 risc);
595extern void cx25821_set_pixel_format(struct cx25821_dev *dev, int channel,
596 u32 format);
597extern void cx25821_videoioctl_unregister(struct cx25821_dev *dev);
598extern struct video_device *cx25821_vdev_init(struct cx25821_dev *dev,
599 struct pci_dev *pci,
600 struct video_device *template,
601 char *type);
602#endif
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/go7007/Kconfig
index ca6ade6c4b47..e47f683a323e 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/go7007/Kconfig
@@ -1,5 +1,5 @@
1config VIDEO_GO7007 1config VIDEO_GO7007
2 tristate "Go 7007 support" 2 tristate "WIS GO7007 MPEG encoder support"
3 depends on VIDEO_DEV && PCI && I2C && INPUT 3 depends on VIDEO_DEV && PCI && I2C && INPUT
4 depends on SND 4 depends on SND
5 select VIDEOBUF_DMA_SG 5 select VIDEOBUF_DMA_SG
@@ -10,17 +10,19 @@ config VIDEO_GO7007
10 select CRC32 10 select CRC32
11 default N 11 default N
12 ---help--- 12 ---help---
13 This is a video4linux driver for some weird device... 13 This is a video4linux driver for the WIS GO7007 MPEG
14 encoder chip.
14 15
15 To compile this driver as a module, choose M here: the 16 To compile this driver as a module, choose M here: the
16 module will be called go7007 17 module will be called go7007
17 18
18config VIDEO_GO7007_USB 19config VIDEO_GO7007_USB
19 tristate "Go 7007 USB support" 20 tristate "WIS GO7007 USB support"
20 depends on VIDEO_GO7007 && USB 21 depends on VIDEO_GO7007 && USB
21 default N 22 default N
22 ---help--- 23 ---help---
23 This is a video4linux driver for some weird device... 24 This is a video4linux driver for the WIS GO7007 MPEG
25 encoder chip over USB.
24 26
25 To compile this driver as a module, choose M here: the 27 To compile this driver as a module, choose M here: the
26 module will be called go7007-usb 28 module will be called go7007-usb
@@ -30,8 +32,78 @@ config VIDEO_GO7007_USB_S2250_BOARD
30 depends on VIDEO_GO7007_USB && DVB_USB 32 depends on VIDEO_GO7007_USB && DVB_USB
31 default N 33 default N
32 ---help--- 34 ---help---
33 This is a video4linux driver for the Sensoray 2250/2251 device 35 This is a video4linux driver for the Sensoray 2250/2251 device.
34 36
35 To compile this driver as a module, choose M here: the 37 To compile this driver as a module, choose M here: the
36 module will be called s2250-board 38 module will be called s2250
39
40config VIDEO_GO7007_OV7640
41 tristate "OV7640 subdev support"
42 depends on VIDEO_GO7007
43 default N
44 ---help---
45 This is a video4linux driver for the OV7640 sub-device.
46
47 To compile this driver as a module, choose M here: the
48 module will be called wis-ov7640
49
50config VIDEO_GO7007_SAA7113
51 tristate "SAA7113 subdev support"
52 depends on VIDEO_GO7007
53 default N
54 ---help---
55 This is a video4linux driver for the SAA7113 sub-device.
56
57 To compile this driver as a module, choose M here: the
58 module will be called wis-saa7113
59
60config VIDEO_GO7007_SAA7115
61 tristate "SAA7115 subdev support"
62 depends on VIDEO_GO7007
63 default N
64 ---help---
65 This is a video4linux driver for the SAA7115 sub-device.
66
67 To compile this driver as a module, choose M here: the
68 module will be called wis-saa7115
69
70config VIDEO_GO7007_TW9903
71 tristate "TW9903 subdev support"
72 depends on VIDEO_GO7007
73 default N
74 ---help---
75 This is a video4linux driver for the TW9903 sub-device.
76
77 To compile this driver as a module, choose M here: the
78 module will be called wis-tw9903
79
80config VIDEO_GO7007_UDA1342
81 tristate "UDA1342 subdev support"
82 depends on VIDEO_GO7007
83 default N
84 ---help---
85 This is a video4linux driver for the UDA1342 sub-device.
86
87 To compile this driver as a module, choose M here: the
88 module will be called wis-uda1342
89
90config VIDEO_GO7007_SONY_TUNER
91 tristate "Sony tuner subdev support"
92 depends on VIDEO_GO7007
93 default N
94 ---help---
95 This is a video4linux driver for the Sony Tuner sub-device.
96
97 To compile this driver as a module, choose M here: the
98 module will be called wis-sony-tuner
99
100config VIDEO_GO7007_TW2804
101 tristate "TW2804 subdev support"
102 depends on VIDEO_GO7007
103 default N
104 ---help---
105 This is a video4linux driver for the TW2804 sub-device.
106
107 To compile this driver as a module, choose M here: the
108 module will be called wis-tw2804
37 109
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/go7007/Makefile
index e514b4af6d06..d14ea84a01f6 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/go7007/Makefile
@@ -6,22 +6,34 @@
6obj-$(CONFIG_VIDEO_GO7007) += go7007.o 6obj-$(CONFIG_VIDEO_GO7007) += go7007.o
7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o 7obj-$(CONFIG_VIDEO_GO7007_USB) += go7007-usb.o
8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o 8obj-$(CONFIG_VIDEO_GO7007_USB_S2250_BOARD) += s2250.o
9obj-$(CONFIG_VIDEO_GO7007_SAA7113) += wis-saa7113.o
10obj-$(CONFIG_VIDEO_GO7007_OV7640) += wis-ov7640.o
11obj-$(CONFIG_VIDEO_GO7007_SAA7115) += wis-saa7115.o
12obj-$(CONFIG_VIDEO_GO7007_TW9903) += wis-tw9903.o
13obj-$(CONFIG_VIDEO_GO7007_UDA1342) += wis-uda1342.o
14obj-$(CONFIG_VIDEO_GO7007_SONY_TUNER) += wis-sony-tuner.o
15obj-$(CONFIG_VIDEO_GO7007_TW2804) += wis-tw2804.o
9 16
10go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \ 17go7007-objs += go7007-v4l2.o go7007-driver.o go7007-i2c.o go7007-fw.o \
11 snd-go7007.o wis-saa7113.o 18 snd-go7007.o
12 19
13s2250-objs += s2250-board.o s2250-loader.o 20s2250-objs += s2250-board.o s2250-loader.o
14 21
15# Uncompile when the saa7134 patches get into upstream 22# Uncomment when the saa7134 patches get into upstream
16#ifneq ($(CONFIG_VIDEO_SAA7134),) 23#ifneq ($(CONFIG_VIDEO_SAA7134),)
17#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o 24#obj-$(CONFIG_VIDEO_SAA7134) += saa7134-go7007.o
18#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 25#EXTRA_CFLAGS += -Idrivers/media/video/saa7134 -DSAA7134_MPEG_GO7007=3
19#endif 26#endif
20 27
28# S2250 needs cypress ezusb loader from dvb-usb
21ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),) 29ifneq ($(CONFIG_VIDEO_GO7007_USB_S2250_BOARD),)
22EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb 30EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-usb
23endif 31endif
24 32
25EXTRA_CFLAGS += -Idrivers/staging/saa7134
26EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 33EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
27EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 34EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
35
36# Ubuntu 8.04 has CONFIG_SND undefined, so include lum sound/config.h too
37ifeq ($(CONFIG_SND),)
38EXTRA_CFLAGS += -include sound/config.h
39endif
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c
index 77b1e769ac92..472f4bb08fdc 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/go7007/go7007-driver.c
@@ -27,7 +27,7 @@
27#include <linux/device.h> 27#include <linux/device.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/firmware.h> 29#include <linux/firmware.h>
30#include <linux/semaphore.h> 30#include <linux/mutex.h>
31#include <linux/uaccess.h> 31#include <linux/uaccess.h>
32#include <asm/system.h> 32#include <asm/system.h>
33#include <linux/videodev2.h> 33#include <linux/videodev2.h>
@@ -49,7 +49,7 @@ int go7007_read_interrupt(struct go7007 *go, u16 *value, u16 *data)
49 go->hpi_ops->read_interrupt(go); 49 go->hpi_ops->read_interrupt(go);
50 if (wait_event_timeout(go->interrupt_waitq, 50 if (wait_event_timeout(go->interrupt_waitq,
51 go->interrupt_available, 5*HZ) < 0) { 51 go->interrupt_available, 5*HZ) < 0) {
52 printk(KERN_ERR "go7007: timeout waiting for read interrupt\n"); 52 v4l2_err(go->video_dev, "timeout waiting for read interrupt\n");
53 return -1; 53 return -1;
54 } 54 }
55 if (!go->interrupt_available) 55 if (!go->interrupt_available)
@@ -97,13 +97,12 @@ static int go7007_load_encoder(struct go7007 *go)
97 u16 intr_val, intr_data; 97 u16 intr_val, intr_data;
98 98
99 if (request_firmware(&fw_entry, fw_name, go->dev)) { 99 if (request_firmware(&fw_entry, fw_name, go->dev)) {
100 printk(KERN_ERR 100 v4l2_err(go, "unable to load firmware from file "
101 "go7007: unable to load firmware from file \"%s\"\n", 101 "\"%s\"\n", fw_name);
102 fw_name);
103 return -1; 102 return -1;
104 } 103 }
105 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { 104 if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) {
106 printk(KERN_ERR "go7007: file \"%s\" does not appear to be " 105 v4l2_err(go, "file \"%s\" does not appear to be "
107 "go7007 firmware\n", fw_name); 106 "go7007 firmware\n", fw_name);
108 release_firmware(fw_entry); 107 release_firmware(fw_entry);
109 return -1; 108 return -1;
@@ -111,7 +110,7 @@ static int go7007_load_encoder(struct go7007 *go)
111 fw_len = fw_entry->size - 16; 110 fw_len = fw_entry->size - 16;
112 bounce = kmalloc(fw_len, GFP_KERNEL); 111 bounce = kmalloc(fw_len, GFP_KERNEL);
113 if (bounce == NULL) { 112 if (bounce == NULL) {
114 printk(KERN_ERR "go7007: unable to allocate %d bytes for " 113 v4l2_err(go, "unable to allocate %d bytes for "
115 "firmware transfer\n", fw_len); 114 "firmware transfer\n", fw_len);
116 release_firmware(fw_entry); 115 release_firmware(fw_entry);
117 return -1; 116 return -1;
@@ -122,7 +121,7 @@ static int go7007_load_encoder(struct go7007 *go)
122 go7007_send_firmware(go, bounce, fw_len) < 0 || 121 go7007_send_firmware(go, bounce, fw_len) < 0 ||
123 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 || 122 go7007_read_interrupt(go, &intr_val, &intr_data) < 0 ||
124 (intr_val & ~0x1) != 0x5a5a) { 123 (intr_val & ~0x1) != 0x5a5a) {
125 printk(KERN_ERR "go7007: error transferring firmware\n"); 124 v4l2_err(go, "error transferring firmware\n");
126 rv = -1; 125 rv = -1;
127 } 126 }
128 kfree(bounce); 127 kfree(bounce);
@@ -140,9 +139,9 @@ int go7007_boot_encoder(struct go7007 *go, int init_i2c)
140{ 139{
141 int ret; 140 int ret;
142 141
143 down(&go->hw_lock); 142 mutex_lock(&go->hw_lock);
144 ret = go7007_load_encoder(go); 143 ret = go7007_load_encoder(go);
145 up(&go->hw_lock); 144 mutex_unlock(&go->hw_lock);
146 if (ret < 0) 145 if (ret < 0)
147 return -1; 146 return -1;
148 if (!init_i2c) 147 if (!init_i2c)
@@ -257,9 +256,9 @@ int go7007_register_encoder(struct go7007 *go)
257 256
258 printk(KERN_INFO "go7007: registering new %s\n", go->name); 257 printk(KERN_INFO "go7007: registering new %s\n", go->name);
259 258
260 down(&go->hw_lock); 259 mutex_lock(&go->hw_lock);
261 ret = go7007_init_encoder(go); 260 ret = go7007_init_encoder(go);
262 up(&go->hw_lock); 261 mutex_unlock(&go->hw_lock);
263 if (ret < 0) 262 if (ret < 0)
264 return -1; 263 return -1;
265 264
@@ -316,7 +315,7 @@ int go7007_start_encoder(struct go7007 *go)
316 315
317 if (go7007_send_firmware(go, fw, fw_len) < 0 || 316 if (go7007_send_firmware(go, fw, fw_len) < 0 ||
318 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) { 317 go7007_read_interrupt(go, &intr_val, &intr_data) < 0) {
319 printk(KERN_ERR "go7007: error transferring firmware\n"); 318 v4l2_err(go->video_dev, "error transferring firmware\n");
320 rv = -1; 319 rv = -1;
321 goto start_error; 320 goto start_error;
322 } 321 }
@@ -325,7 +324,7 @@ int go7007_start_encoder(struct go7007 *go)
325 go->parse_length = 0; 324 go->parse_length = 0;
326 go->seen_frame = 0; 325 go->seen_frame = 0;
327 if (go7007_stream_start(go) < 0) { 326 if (go7007_stream_start(go) < 0) {
328 printk(KERN_ERR "go7007: error starting stream transfer\n"); 327 v4l2_err(go->video_dev, "error starting stream transfer\n");
329 rv = -1; 328 rv = -1;
330 goto start_error; 329 goto start_error;
331 } 330 }
@@ -421,7 +420,7 @@ void go7007_parse_video_stream(struct go7007 *go, u8 *buf, int length)
421 for (i = 0; i < length; ++i) { 420 for (i = 0; i < length; ++i) {
422 if (go->active_buf != NULL && 421 if (go->active_buf != NULL &&
423 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) { 422 go->active_buf->bytesused >= GO7007_BUF_SIZE - 3) {
424 printk(KERN_DEBUG "go7007: dropping oversized frame\n"); 423 v4l2_info(go->video_dev, "dropping oversized frame\n");
425 go->active_buf->offset -= go->active_buf->bytesused; 424 go->active_buf->offset -= go->active_buf->bytesused;
426 go->active_buf->bytesused = 0; 425 go->active_buf->bytesused = 0;
427 go->active_buf->modet_active = 0; 426 go->active_buf->modet_active = 0;
@@ -604,7 +603,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev)
604 go->tuner_type = -1; 603 go->tuner_type = -1;
605 go->channel_number = 0; 604 go->channel_number = 0;
606 go->name[0] = 0; 605 go->name[0] = 0;
607 init_MUTEX(&go->hw_lock); 606 mutex_init(&go->hw_lock);
608 init_waitqueue_head(&go->frame_waitq); 607 init_waitqueue_head(&go->frame_waitq);
609 spin_lock_init(&go->spinlock); 608 spin_lock_init(&go->spinlock);
610 go->video_dev = NULL; 609 go->video_dev = NULL;
@@ -669,8 +668,8 @@ void go7007_remove(struct go7007 *go)
669 if (i2c_del_adapter(&go->i2c_adapter) == 0) 668 if (i2c_del_adapter(&go->i2c_adapter) == 0)
670 go->i2c_adapter_online = 0; 669 go->i2c_adapter_online = 0;
671 else 670 else
672 printk(KERN_ERR 671 v4l2_err(go->video_dev,
673 "go7007: error removing I2C adapter!\n"); 672 "error removing I2C adapter!\n");
674 } 673 }
675 674
676 if (go->audio_enabled) 675 if (go->audio_enabled)
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/go7007/go7007-fw.c
index 871ed43e4e05..a8bb264e0074 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/go7007/go7007-fw.c
@@ -1034,7 +1034,8 @@ static int brctrl_to_package(struct go7007 *go,
1034 0xBF1B, framelen[7], 1034 0xBF1B, framelen[7],
1035 0, 0, 1035 0, 0,
1036 1036
1037#if 0 /* Remove once we don't care about matching */ 1037#if 0
1038 /* Remove once we don't care about matching */
1038 0x200e, 0x0000, 1039 0x200e, 0x0000,
1039 0xBF56, 4, 1040 0xBF56, 4,
1040 0xBF57, 0, 1041 0xBF57, 0,
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/go7007/go7007-i2c.c
index c82867fdd28d..b8cfa1a6eaeb 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/go7007/go7007-i2c.c
@@ -24,7 +24,7 @@
24#include <linux/time.h> 24#include <linux/time.h>
25#include <linux/device.h> 25#include <linux/device.h>
26#include <linux/i2c.h> 26#include <linux/i2c.h>
27#include <linux/semaphore.h> 27#include <linux/mutex.h>
28#include <linux/uaccess.h> 28#include <linux/uaccess.h>
29#include <asm/system.h> 29#include <asm/system.h>
30 30
@@ -48,7 +48,7 @@
48 48
49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs 49/* There is only one I2C port on the TW2804 that feeds all four GO7007 VIPs
50 * on the Adlink PCI-MPG24, so access is shared between all of them. */ 50 * on the Adlink PCI-MPG24, so access is shared between all of them. */
51static DECLARE_MUTEX(adlink_mpg24_i2c_lock); 51static DEFINE_MUTEX(adlink_mpg24_i2c_lock);
52 52
53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read, 53static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
54 u16 command, int flags, u8 *data) 54 u16 command, int flags, u8 *data)
@@ -69,11 +69,11 @@ static int go7007_i2c_xfer(struct go7007 *go, u16 addr, int read,
69 *data, command, addr); 69 *data, command, addr);
70#endif 70#endif
71 71
72 down(&go->hw_lock); 72 mutex_lock(&go->hw_lock);
73 73
74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) { 74 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
75 /* Bridge the I2C port on this GO7007 to the shared bus */ 75 /* Bridge the I2C port on this GO7007 to the shared bus */
76 down(&adlink_mpg24_i2c_lock); 76 mutex_lock(&adlink_mpg24_i2c_lock);
77 go7007_write_addr(go, 0x3c82, 0x0020); 77 go7007_write_addr(go, 0x3c82, 0x0020);
78 } 78 }
79 79
@@ -134,9 +134,9 @@ i2c_done:
134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) { 134 if (go->board_id == GO7007_BOARDID_ADLINK_MPG24) {
135 /* Isolate the I2C port on this GO7007 from the shared bus */ 135 /* Isolate the I2C port on this GO7007 from the shared bus */
136 go7007_write_addr(go, 0x3c82, 0x0000); 136 go7007_write_addr(go, 0x3c82, 0x0000);
137 up(&adlink_mpg24_i2c_lock); 137 mutex_unlock(&adlink_mpg24_i2c_lock);
138 } 138 }
139 up(&go->hw_lock); 139 mutex_unlock(&go->hw_lock);
140 return ret; 140 return ret;
141} 141}
142 142
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/go7007/go7007-priv.h
index 178d18119faa..ce9307e3e186 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/go7007/go7007-priv.h
@@ -132,7 +132,7 @@ struct go7007_buffer {
132 132
133struct go7007_file { 133struct go7007_file {
134 struct go7007 *go; 134 struct go7007 *go;
135 struct semaphore lock; 135 struct mutex lock;
136 int buf_count; 136 int buf_count;
137 struct go7007_buffer *bufs; 137 struct go7007_buffer *bufs;
138}; 138};
@@ -170,7 +170,7 @@ struct go7007 {
170 int ref_count; 170 int ref_count;
171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status; 171 enum { STATUS_INIT, STATUS_ONLINE, STATUS_SHUTDOWN } status;
172 spinlock_t spinlock; 172 spinlock_t spinlock;
173 struct semaphore hw_lock; 173 struct mutex hw_lock;
174 int streaming; 174 int streaming;
175 int in_use; 175 int in_use;
176 int audio_enabled; 176 int audio_enabled;
@@ -240,7 +240,7 @@ struct go7007 {
240 unsigned short interrupt_data; 240 unsigned short interrupt_data;
241}; 241};
242 242
243/* All of these must be called with the hpi_lock semaphore held! */ 243/* All of these must be called with the hpi_lock mutex held! */
244#define go7007_interface_reset(go) \ 244#define go7007_interface_reset(go) \
245 ((go)->hpi_ops->interface_reset(go)) 245 ((go)->hpi_ops->interface_reset(go))
246#define go7007_write_interrupt(go, x, y) \ 246#define go7007_write_interrupt(go, x, y) \
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/go7007/go7007-usb.c
index aa4a9e0b9954..ecaa3c989cf4 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/go7007/go7007-usb.c
@@ -33,7 +33,8 @@
33 33
34static unsigned int assume_endura; 34static unsigned int assume_endura;
35module_param(assume_endura, int, 0644); 35module_param(assume_endura, int, 0644);
36MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"); 36MODULE_PARM_DESC(assume_endura, "when probing fails, "
37 "hardware is a Pelco Endura");
37 38
38/* #define GO7007_USB_DEBUG */ 39/* #define GO7007_USB_DEBUG */
39/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */ 40/* #define GO7007_I2C_DEBUG */ /* for debugging the EZ-USB I2C adapter */
@@ -44,12 +45,12 @@ MODULE_PARM_DESC(assume_endura, "when probing fails, hardware is a Pelco Endura"
44 45
45/* 46/*
46 * Pipes on EZ-USB interface: 47 * Pipes on EZ-USB interface:
47 * 0 snd - Control 48 * 0 snd - Control
48 * 0 rcv - Control 49 * 0 rcv - Control
49 * 2 snd - Download firmware (control) 50 * 2 snd - Download firmware (control)
50 * 4 rcv - Read Interrupt (interrupt) 51 * 4 rcv - Read Interrupt (interrupt)
51 * 6 rcv - Read Video (bulk) 52 * 6 rcv - Read Video (bulk)
52 * 8 rcv - Read Audio (bulk) 53 * 8 rcv - Read Audio (bulk)
53 */ 54 */
54 55
55#define GO7007_USB_EZUSB (1<<0) 56#define GO7007_USB_EZUSB (1<<0)
@@ -62,7 +63,7 @@ struct go7007_usb_board {
62 63
63struct go7007_usb { 64struct go7007_usb {
64 struct go7007_usb_board *board; 65 struct go7007_usb_board *board;
65 struct semaphore i2c_lock; 66 struct mutex i2c_lock;
66 struct usb_device *usbdev; 67 struct usb_device *usbdev;
67 struct urb *video_urbs[8]; 68 struct urb *video_urbs[8];
68 struct urb *audio_urbs[8]; 69 struct urb *audio_urbs[8];
@@ -97,7 +98,7 @@ static struct go7007_usb_board board_matrix_ii = {
97 }, 98 },
98 }, 99 },
99 .num_inputs = 2, 100 .num_inputs = 2,
100 .inputs = { 101 .inputs = {
101 { 102 {
102 .video_input = 0, 103 .video_input = 0,
103 .name = "Composite", 104 .name = "Composite",
@@ -134,7 +135,7 @@ static struct go7007_usb_board board_matrix_reload = {
134 }, 135 },
135 }, 136 },
136 .num_inputs = 2, 137 .num_inputs = 2,
137 .inputs = { 138 .inputs = {
138 { 139 {
139 .video_input = 0, 140 .video_input = 0,
140 .name = "Composite", 141 .name = "Composite",
@@ -172,7 +173,7 @@ static struct go7007_usb_board board_star_trek = {
172 }, 173 },
173 }, 174 },
174 .num_inputs = 2, 175 .num_inputs = 2,
175 .inputs = { 176 .inputs = {
176 { 177 {
177 .video_input = 1, 178 .video_input = 1,
178 /* .audio_input = AUDIO_EXTERN, */ 179 /* .audio_input = AUDIO_EXTERN, */
@@ -228,7 +229,7 @@ static struct go7007_usb_board board_px_tv402u = {
228 }, 229 },
229 }, 230 },
230 .num_inputs = 3, 231 .num_inputs = 3,
231 .inputs = { 232 .inputs = {
232 { 233 {
233 .video_input = 1, 234 .video_input = 1,
234 .audio_input = TVAUDIO_INPUT_EXTERN, 235 .audio_input = TVAUDIO_INPUT_EXTERN,
@@ -276,7 +277,7 @@ static struct go7007_usb_board board_xmen = {
276 }, 277 },
277 }, 278 },
278 .num_inputs = 1, 279 .num_inputs = 1,
279 .inputs = { 280 .inputs = {
280 { 281 {
281 .name = "Camera", 282 .name = "Camera",
282 }, 283 },
@@ -309,7 +310,7 @@ static struct go7007_usb_board board_matrix_revolution = {
309 }, 310 },
310 }, 311 },
311 .num_inputs = 2, 312 .num_inputs = 2,
312 .inputs = { 313 .inputs = {
313 { 314 {
314 .video_input = 2, 315 .video_input = 2,
315 .name = "Composite", 316 .name = "Composite",
@@ -341,7 +342,7 @@ static struct go7007_usb_board board_lifeview_lr192 = {
341 GO7007_SENSOR_SCALING, 342 GO7007_SENSOR_SCALING,
342 .num_i2c_devs = 0, 343 .num_i2c_devs = 0,
343 .num_inputs = 1, 344 .num_inputs = 1,
344 .inputs = { 345 .inputs = {
345 { 346 {
346 .video_input = 0, 347 .video_input = 0,
347 .name = "Composite", 348 .name = "Composite",
@@ -367,7 +368,7 @@ static struct go7007_usb_board board_endura = {
367 .sensor_h_offset = 8, 368 .sensor_h_offset = 8,
368 .num_i2c_devs = 0, 369 .num_i2c_devs = 0,
369 .num_inputs = 1, 370 .num_inputs = 1,
370 .inputs = { 371 .inputs = {
371 { 372 {
372 .name = "Camera", 373 .name = "Camera",
373 }, 374 },
@@ -399,7 +400,7 @@ static struct go7007_usb_board board_adlink_mpg24 = {
399 }, 400 },
400 }, 401 },
401 .num_inputs = 1, 402 .num_inputs = 1,
402 .inputs = { 403 .inputs = {
403 { 404 {
404 .name = "Composite", 405 .name = "Composite",
405 }, 406 },
@@ -430,7 +431,7 @@ static struct go7007_usb_board board_sensoray_2250 = {
430 }, 431 },
431 }, 432 },
432 .num_inputs = 2, 433 .num_inputs = 2,
433 .inputs = { 434 .inputs = {
434 { 435 {
435 .video_input = 0, 436 .video_input = 0,
436 .name = "Composite", 437 .name = "Composite",
@@ -734,14 +735,15 @@ static int go7007_usb_read_interrupt(struct go7007 *go)
734static void go7007_usb_read_video_pipe_complete(struct urb *urb) 735static void go7007_usb_read_video_pipe_complete(struct urb *urb)
735{ 736{
736 struct go7007 *go = (struct go7007 *)urb->context; 737 struct go7007 *go = (struct go7007 *)urb->context;
737 int r, status = urb-> status; 738 int r, status = urb->status;
738 739
739 if (!go->streaming) { 740 if (!go->streaming) {
740 wake_up_interruptible(&go->frame_waitq); 741 wake_up_interruptible(&go->frame_waitq);
741 return; 742 return;
742 } 743 }
743 if (status) { 744 if (status) {
744 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n", status); 745 printk(KERN_ERR "go7007-usb: error in video pipe: %d\n",
746 status);
745 return; 747 return;
746 } 748 }
747 if (urb->actual_length != urb->transfer_buffer_length) { 749 if (urb->actual_length != urb->transfer_buffer_length) {
@@ -762,7 +764,8 @@ static void go7007_usb_read_audio_pipe_complete(struct urb *urb)
762 if (!go->streaming) 764 if (!go->streaming)
763 return; 765 return;
764 if (status) { 766 if (status) {
765 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n", status); 767 printk(KERN_ERR "go7007-usb: error in audio pipe: %d\n",
768 status);
766 return; 769 return;
767 } 770 }
768 if (urb->actual_length != urb->transfer_buffer_length) { 771 if (urb->actual_length != urb->transfer_buffer_length) {
@@ -877,7 +880,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
877 if (go->status == STATUS_SHUTDOWN) 880 if (go->status == STATUS_SHUTDOWN)
878 return -1; 881 return -1;
879 882
880 down(&usb->i2c_lock); 883 mutex_lock(&usb->i2c_lock);
881 884
882 for (i = 0; i < num; ++i) { 885 for (i = 0; i < num; ++i) {
883 /* The hardware command is "write some bytes then read some 886 /* The hardware command is "write some bytes then read some
@@ -935,7 +938,7 @@ static int go7007_usb_i2c_master_xfer(struct i2c_adapter *adapter,
935 ret = 0; 938 ret = 0;
936 939
937i2c_done: 940i2c_done:
938 up(&usb->i2c_lock); 941 mutex_unlock(&usb->i2c_lock);
939 return ret; 942 return ret;
940} 943}
941 944
@@ -1017,7 +1020,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1017 break; 1020 break;
1018 case GO7007_BOARDID_SENSORAY_2250: 1021 case GO7007_BOARDID_SENSORAY_2250:
1019 printk(KERN_INFO "Sensoray 2250 found\n"); 1022 printk(KERN_INFO "Sensoray 2250 found\n");
1020 name = "Sensoray 2250/2251\n"; 1023 name = "Sensoray 2250/2251";
1021 board = &board_sensoray_2250; 1024 board = &board_sensoray_2250;
1022 break; 1025 break;
1023 default: 1026 default:
@@ -1065,7 +1068,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1065 if (board->flags & GO7007_USB_EZUSB_I2C) { 1068 if (board->flags & GO7007_USB_EZUSB_I2C) {
1066 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ, 1069 memcpy(&go->i2c_adapter, &go7007_usb_adap_templ,
1067 sizeof(go7007_usb_adap_templ)); 1070 sizeof(go7007_usb_adap_templ));
1068 init_MUTEX(&usb->i2c_lock); 1071 mutex_init(&usb->i2c_lock);
1069 go->i2c_adapter.dev.parent = go->dev; 1072 go->i2c_adapter.dev.parent = go->dev;
1070 i2c_set_adapdata(&go->i2c_adapter, go); 1073 i2c_set_adapdata(&go->i2c_adapter, go);
1071 if (i2c_add_adapter(&go->i2c_adapter) < 0) { 1074 if (i2c_add_adapter(&go->i2c_adapter) < 0) {
@@ -1096,7 +1099,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1096 usb->board = board = &board_endura; 1099 usb->board = board = &board_endura;
1097 go->board_info = &board->main_info; 1100 go->board_info = &board->main_info;
1098 strncpy(go->name, "Pelco Endura", 1101 strncpy(go->name, "Pelco Endura",
1099 sizeof(go->name)); 1102 sizeof(go->name));
1100 } else { 1103 } else {
1101 u16 channel; 1104 u16 channel;
1102 1105
@@ -1154,8 +1157,7 @@ static int go7007_usb_probe(struct usb_interface *intf,
1154 * to the EZ-USB GPIO output pins */ 1157 * to the EZ-USB GPIO output pins */
1155 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0, 1158 if (go7007_usb_vendor_request(go, 0x40, 0x7f02, 0,
1156 NULL, 0, 0) < 0) { 1159 NULL, 0, 0) < 0) {
1157 printk(KERN_ERR 1160 printk(KERN_ERR "go7007-usb: GPIO write failed!\n");
1158 "go7007-usb: GPIO write failed!\n");
1159 goto initfail; 1161 goto initfail;
1160 } 1162 }
1161 } 1163 }
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/go7007/go7007-v4l2.c
index 06cacd37bbd8..4bd353afa596 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/go7007/go7007-v4l2.c
@@ -30,7 +30,7 @@
30#include <media/v4l2-common.h> 30#include <media/v4l2-common.h>
31#include <media/v4l2-ioctl.h> 31#include <media/v4l2-ioctl.h>
32#include <linux/i2c.h> 32#include <linux/i2c.h>
33#include <linux/semaphore.h> 33#include <linux/mutex.h>
34#include <linux/uaccess.h> 34#include <linux/uaccess.h>
35#include <asm/system.h> 35#include <asm/system.h>
36 36
@@ -75,7 +75,7 @@ static int go7007_streamoff(struct go7007 *go)
75 int retval = -EINVAL; 75 int retval = -EINVAL;
76 unsigned long flags; 76 unsigned long flags;
77 77
78 down(&go->hw_lock); 78 mutex_lock(&go->hw_lock);
79 if (go->streaming) { 79 if (go->streaming) {
80 go->streaming = 0; 80 go->streaming = 0;
81 go7007_stream_stop(go); 81 go7007_stream_stop(go);
@@ -85,7 +85,7 @@ static int go7007_streamoff(struct go7007 *go)
85 go7007_reset_encoder(go); 85 go7007_reset_encoder(go);
86 retval = 0; 86 retval = 0;
87 } 87 }
88 up(&go->hw_lock); 88 mutex_unlock(&go->hw_lock);
89 return 0; 89 return 0;
90} 90}
91 91
@@ -101,7 +101,7 @@ static int go7007_open(struct file *file)
101 return -ENOMEM; 101 return -ENOMEM;
102 ++go->ref_count; 102 ++go->ref_count;
103 gofh->go = go; 103 gofh->go = go;
104 init_MUTEX(&gofh->lock); 104 mutex_init(&gofh->lock);
105 gofh->buf_count = 0; 105 gofh->buf_count = 0;
106 file->private_data = gofh; 106 file->private_data = gofh;
107 return 0; 107 return 0;
@@ -383,13 +383,10 @@ static int clip_to_modet_map(struct go7007 *go, int region,
383 } 383 }
384 return 0; 384 return 0;
385} 385}
386#endif
386 387
387static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl) 388static int mpeg_queryctrl(struct v4l2_queryctrl *ctrl)
388{ 389{
389 static const u32 user_ctrls[] = {
390 V4L2_CID_USER_CLASS,
391 0
392 };
393 static const u32 mpeg_ctrls[] = { 390 static const u32 mpeg_ctrls[] = {
394 V4L2_CID_MPEG_CLASS, 391 V4L2_CID_MPEG_CLASS,
395 V4L2_CID_MPEG_STREAM_TYPE, 392 V4L2_CID_MPEG_STREAM_TYPE,
@@ -401,26 +398,15 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
401 0 398 0
402 }; 399 };
403 static const u32 *ctrl_classes[] = { 400 static const u32 *ctrl_classes[] = {
404 user_ctrls,
405 mpeg_ctrls, 401 mpeg_ctrls,
406 NULL 402 NULL
407 }; 403 };
408 404
409 /* The ctrl may already contain the queried i2c controls, 405 ctrl->id = v4l2_ctrl_next(ctrl_classes, ctrl->id);
410 * query the mpeg controls if the existing ctrl id is
411 * greater than the next mpeg ctrl id.
412 */
413 id = v4l2_ctrl_next(ctrl_classes, id);
414 if (id >= ctrl->id && ctrl->name[0])
415 return 0;
416
417 memset(ctrl, 0, sizeof(*ctrl));
418 ctrl->id = id;
419 406
420 switch (ctrl->id) { 407 switch (ctrl->id) {
421 case V4L2_CID_USER_CLASS:
422 case V4L2_CID_MPEG_CLASS: 408 case V4L2_CID_MPEG_CLASS:
423 return v4l2_ctrl_query_fill_std(ctrl); 409 return v4l2_ctrl_query_fill(ctrl, 0, 0, 0, 0);
424 case V4L2_CID_MPEG_STREAM_TYPE: 410 case V4L2_CID_MPEG_STREAM_TYPE:
425 return v4l2_ctrl_query_fill(ctrl, 411 return v4l2_ctrl_query_fill(ctrl,
426 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD, 412 V4L2_MPEG_STREAM_TYPE_MPEG2_DVD,
@@ -437,20 +423,21 @@ static int mpeg_queryctrl(u32 id, struct v4l2_queryctrl *ctrl)
437 V4L2_MPEG_VIDEO_ASPECT_16x9, 1, 423 V4L2_MPEG_VIDEO_ASPECT_16x9, 1,
438 V4L2_MPEG_VIDEO_ASPECT_1x1); 424 V4L2_MPEG_VIDEO_ASPECT_1x1);
439 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 425 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
426 return v4l2_ctrl_query_fill(ctrl, 0, 34, 1, 15);
440 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 427 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
441 return v4l2_ctrl_query_fill_std(ctrl); 428 return v4l2_ctrl_query_fill(ctrl, 0, 1, 1, 0);
442 case V4L2_CID_MPEG_VIDEO_BITRATE: 429 case V4L2_CID_MPEG_VIDEO_BITRATE:
443 return v4l2_ctrl_query_fill(ctrl, 430 return v4l2_ctrl_query_fill(ctrl,
444 64000, 431 64000,
445 10000000, 1, 432 10000000, 1,
446 9800000); 433 1500000);
447 default: 434 default:
448 break; 435 return -EINVAL;
449 } 436 }
450 return -EINVAL; 437 return 0;
451} 438}
452 439
453static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go) 440static int mpeg_s_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
454{ 441{
455 /* pretty sure we can't change any of these while streaming */ 442 /* pretty sure we can't change any of these while streaming */
456 if (go->streaming) 443 if (go->streaming)
@@ -528,6 +515,8 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
528 } 515 }
529 break; 516 break;
530 case V4L2_CID_MPEG_VIDEO_GOP_SIZE: 517 case V4L2_CID_MPEG_VIDEO_GOP_SIZE:
518 if (ctrl->value < 0 || ctrl->value > 34)
519 return -EINVAL;
531 go->gop_size = ctrl->value; 520 go->gop_size = ctrl->value;
532 break; 521 break;
533 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE: 522 case V4L2_CID_MPEG_VIDEO_GOP_CLOSURE:
@@ -547,7 +536,7 @@ static int mpeg_s_control(struct v4l2_control *ctrl, struct go7007 *go)
547 return 0; 536 return 0;
548} 537}
549 538
550static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go) 539static int mpeg_g_ctrl(struct v4l2_control *ctrl, struct go7007 *go)
551{ 540{
552 switch (ctrl->id) { 541 switch (ctrl->id) {
553 case V4L2_CID_MPEG_STREAM_TYPE: 542 case V4L2_CID_MPEG_STREAM_TYPE:
@@ -600,13 +589,11 @@ static int mpeg_g_control(struct v4l2_control *ctrl, struct go7007 *go)
600 } 589 }
601 return 0; 590 return 0;
602} 591}
603#endif
604 592
605static int vidioc_querycap(struct file *file, void *priv, 593static int vidioc_querycap(struct file *file, void *priv,
606 struct v4l2_capability *cap) 594 struct v4l2_capability *cap)
607{ 595{
608 struct go7007_file *gofh = priv; 596 struct go7007 *go = ((struct go7007_file *) priv)->go;
609 struct go7007 *go = gofh->go;
610 597
611 strlcpy(cap->driver, "go7007", sizeof(cap->driver)); 598 strlcpy(cap->driver, "go7007", sizeof(cap->driver));
612 strlcpy(cap->card, go->name, sizeof(cap->card)); 599 strlcpy(cap->card, go->name, sizeof(cap->card));
@@ -653,8 +640,7 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
653static int vidioc_g_fmt_vid_cap(struct file *file, void *priv, 640static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
654 struct v4l2_format *fmt) 641 struct v4l2_format *fmt)
655{ 642{
656 struct go7007_file *gofh = priv; 643 struct go7007 *go = ((struct go7007_file *) priv)->go;
657 struct go7007 *go = gofh->go;
658 644
659 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 645 fmt->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
660 fmt->fmt.pix.width = go->width; 646 fmt->fmt.pix.width = go->width;
@@ -672,8 +658,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
672static int vidioc_try_fmt_vid_cap(struct file *file, void *priv, 658static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
673 struct v4l2_format *fmt) 659 struct v4l2_format *fmt)
674{ 660{
675 struct go7007_file *gofh = priv; 661 struct go7007 *go = ((struct go7007_file *) priv)->go;
676 struct go7007 *go = gofh->go;
677 662
678 return set_capture_size(go, fmt, 1); 663 return set_capture_size(go, fmt, 1);
679} 664}
@@ -681,8 +666,7 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
681static int vidioc_s_fmt_vid_cap(struct file *file, void *priv, 666static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
682 struct v4l2_format *fmt) 667 struct v4l2_format *fmt)
683{ 668{
684 struct go7007_file *gofh = priv; 669 struct go7007 *go = ((struct go7007_file *) priv)->go;
685 struct go7007 *go = gofh->go;
686 670
687 if (go->streaming) 671 if (go->streaming)
688 return -EBUSY; 672 return -EBUSY;
@@ -705,14 +689,14 @@ static int vidioc_reqbufs(struct file *file, void *priv,
705 req->memory != V4L2_MEMORY_MMAP) 689 req->memory != V4L2_MEMORY_MMAP)
706 return -EINVAL; 690 return -EINVAL;
707 691
708 down(&gofh->lock); 692 mutex_lock(&gofh->lock);
709 for (i = 0; i < gofh->buf_count; ++i) 693 for (i = 0; i < gofh->buf_count; ++i)
710 if (gofh->bufs[i].mapped > 0) 694 if (gofh->bufs[i].mapped > 0)
711 goto unlock_and_return; 695 goto unlock_and_return;
712 696
713 down(&go->hw_lock); 697 mutex_lock(&go->hw_lock);
714 if (go->in_use > 0 && gofh->buf_count == 0) { 698 if (go->in_use > 0 && gofh->buf_count == 0) {
715 up(&go->hw_lock); 699 mutex_unlock(&go->hw_lock);
716 goto unlock_and_return; 700 goto unlock_and_return;
717 } 701 }
718 702
@@ -731,7 +715,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
731 GFP_KERNEL); 715 GFP_KERNEL);
732 716
733 if (!gofh->bufs) { 717 if (!gofh->bufs) {
734 up(&go->hw_lock); 718 mutex_unlock(&go->hw_lock);
735 goto unlock_and_return; 719 goto unlock_and_return;
736 } 720 }
737 721
@@ -750,8 +734,8 @@ static int vidioc_reqbufs(struct file *file, void *priv,
750 } 734 }
751 735
752 gofh->buf_count = count; 736 gofh->buf_count = count;
753 up(&go->hw_lock); 737 mutex_unlock(&go->hw_lock);
754 up(&gofh->lock); 738 mutex_unlock(&gofh->lock);
755 739
756 memset(req, 0, sizeof(*req)); 740 memset(req, 0, sizeof(*req));
757 741
@@ -762,7 +746,7 @@ static int vidioc_reqbufs(struct file *file, void *priv,
762 return 0; 746 return 0;
763 747
764unlock_and_return: 748unlock_and_return:
765 up(&gofh->lock); 749 mutex_unlock(&gofh->lock);
766 return retval; 750 return retval;
767} 751}
768 752
@@ -778,7 +762,7 @@ static int vidioc_querybuf(struct file *file, void *priv,
778 762
779 index = buf->index; 763 index = buf->index;
780 764
781 down(&gofh->lock); 765 mutex_lock(&gofh->lock);
782 if (index >= gofh->buf_count) 766 if (index >= gofh->buf_count)
783 goto unlock_and_return; 767 goto unlock_and_return;
784 768
@@ -802,12 +786,12 @@ static int vidioc_querybuf(struct file *file, void *priv,
802 buf->memory = V4L2_MEMORY_MMAP; 786 buf->memory = V4L2_MEMORY_MMAP;
803 buf->m.offset = index * GO7007_BUF_SIZE; 787 buf->m.offset = index * GO7007_BUF_SIZE;
804 buf->length = GO7007_BUF_SIZE; 788 buf->length = GO7007_BUF_SIZE;
805 up(&gofh->lock); 789 mutex_unlock(&gofh->lock);
806 790
807 return 0; 791 return 0;
808 792
809unlock_and_return: 793unlock_and_return:
810 up(&gofh->lock); 794 mutex_unlock(&gofh->lock);
811 return retval; 795 return retval;
812} 796}
813 797
@@ -824,7 +808,7 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
824 buf->memory != V4L2_MEMORY_MMAP) 808 buf->memory != V4L2_MEMORY_MMAP)
825 return retval; 809 return retval;
826 810
827 down(&gofh->lock); 811 mutex_lock(&gofh->lock);
828 if (buf->index < 0 || buf->index >= gofh->buf_count) 812 if (buf->index < 0 || buf->index >= gofh->buf_count)
829 goto unlock_and_return; 813 goto unlock_and_return;
830 814
@@ -865,12 +849,12 @@ static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
865 spin_lock_irqsave(&go->spinlock, flags); 849 spin_lock_irqsave(&go->spinlock, flags);
866 list_add_tail(&gobuf->stream, &go->stream); 850 list_add_tail(&gobuf->stream, &go->stream);
867 spin_unlock_irqrestore(&go->spinlock, flags); 851 spin_unlock_irqrestore(&go->spinlock, flags);
868 up(&gofh->lock); 852 mutex_unlock(&gofh->lock);
869 853
870 return 0; 854 return 0;
871 855
872unlock_and_return: 856unlock_and_return:
873 up(&gofh->lock); 857 mutex_unlock(&gofh->lock);
874 return retval; 858 return retval;
875} 859}
876 860
@@ -890,7 +874,7 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
890 if (buf->memory != V4L2_MEMORY_MMAP) 874 if (buf->memory != V4L2_MEMORY_MMAP)
891 return retval; 875 return retval;
892 876
893 down(&gofh->lock); 877 mutex_lock(&gofh->lock);
894 if (list_empty(&go->stream)) 878 if (list_empty(&go->stream))
895 goto unlock_and_return; 879 goto unlock_and_return;
896 gobuf = list_entry(go->stream.next, 880 gobuf = list_entry(go->stream.next,
@@ -934,11 +918,11 @@ static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *buf)
934 buf->length = GO7007_BUF_SIZE; 918 buf->length = GO7007_BUF_SIZE;
935 buf->reserved = gobuf->modet_active; 919 buf->reserved = gobuf->modet_active;
936 920
937 up(&gofh->lock); 921 mutex_unlock(&gofh->lock);
938 return 0; 922 return 0;
939 923
940unlock_and_return: 924unlock_and_return:
941 up(&gofh->lock); 925 mutex_unlock(&gofh->lock);
942 return retval; 926 return retval;
943} 927}
944 928
@@ -952,8 +936,8 @@ static int vidioc_streamon(struct file *file, void *priv,
952 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 936 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
953 return -EINVAL; 937 return -EINVAL;
954 938
955 down(&gofh->lock); 939 mutex_lock(&gofh->lock);
956 down(&go->hw_lock); 940 mutex_lock(&go->hw_lock);
957 941
958 if (!go->streaming) { 942 if (!go->streaming) {
959 go->streaming = 1; 943 go->streaming = 1;
@@ -964,8 +948,8 @@ static int vidioc_streamon(struct file *file, void *priv,
964 else 948 else
965 retval = 0; 949 retval = 0;
966 } 950 }
967 up(&go->hw_lock); 951 mutex_unlock(&go->hw_lock);
968 up(&gofh->lock); 952 mutex_unlock(&gofh->lock);
969 953
970 return retval; 954 return retval;
971} 955}
@@ -978,9 +962,9 @@ static int vidioc_streamoff(struct file *file, void *priv,
978 962
979 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 963 if (type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
980 return -EINVAL; 964 return -EINVAL;
981 down(&gofh->lock); 965 mutex_lock(&gofh->lock);
982 go7007_streamoff(go); 966 go7007_streamoff(go);
983 up(&gofh->lock); 967 mutex_unlock(&gofh->lock);
984 968
985 return 0; 969 return 0;
986} 970}
@@ -988,22 +972,20 @@ static int vidioc_streamoff(struct file *file, void *priv,
988static int vidioc_queryctrl(struct file *file, void *priv, 972static int vidioc_queryctrl(struct file *file, void *priv,
989 struct v4l2_queryctrl *query) 973 struct v4l2_queryctrl *query)
990{ 974{
991 struct go7007_file *gofh = priv; 975 struct go7007 *go = ((struct go7007_file *) priv)->go;
992 struct go7007 *go = gofh->go;
993 976
994 if (!go->i2c_adapter_online) 977 if (!go->i2c_adapter_online)
995 return -EIO; 978 return -EIO;
996 979
997 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query); 980 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, query);
998 981
999 return (!query->name[0]) ? -EINVAL : 0; 982 return (!query->name[0]) ? mpeg_queryctrl(query) : 0;
1000} 983}
1001 984
1002static int vidioc_g_ctrl(struct file *file, void *priv, 985static int vidioc_g_ctrl(struct file *file, void *priv,
1003 struct v4l2_control *ctrl) 986 struct v4l2_control *ctrl)
1004{ 987{
1005 struct go7007_file *gofh = priv; 988 struct go7007 *go = ((struct go7007_file *) priv)->go;
1006 struct go7007 *go = gofh->go;
1007 struct v4l2_queryctrl query; 989 struct v4l2_queryctrl query;
1008 990
1009 if (!go->i2c_adapter_online) 991 if (!go->i2c_adapter_online)
@@ -1013,7 +995,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1013 query.id = ctrl->id; 995 query.id = ctrl->id;
1014 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); 996 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1015 if (query.name[0] == 0) 997 if (query.name[0] == 0)
1016 return -EINVAL; 998 return mpeg_g_ctrl(ctrl, go);
1017 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl); 999 i2c_clients_command(&go->i2c_adapter, VIDIOC_G_CTRL, ctrl);
1018 1000
1019 return 0; 1001 return 0;
@@ -1022,8 +1004,7 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1022static int vidioc_s_ctrl(struct file *file, void *priv, 1004static int vidioc_s_ctrl(struct file *file, void *priv,
1023 struct v4l2_control *ctrl) 1005 struct v4l2_control *ctrl)
1024{ 1006{
1025 struct go7007_file *gofh = priv; 1007 struct go7007 *go = ((struct go7007_file *) priv)->go;
1026 struct go7007 *go = gofh->go;
1027 struct v4l2_queryctrl query; 1008 struct v4l2_queryctrl query;
1028 1009
1029 if (!go->i2c_adapter_online) 1010 if (!go->i2c_adapter_online)
@@ -1033,7 +1014,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1033 query.id = ctrl->id; 1014 query.id = ctrl->id;
1034 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query); 1015 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYCTRL, &query);
1035 if (query.name[0] == 0) 1016 if (query.name[0] == 0)
1036 return -EINVAL; 1017 return mpeg_s_ctrl(ctrl, go);
1037 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl); 1018 i2c_clients_command(&go->i2c_adapter, VIDIOC_S_CTRL, ctrl);
1038 1019
1039 return 0; 1020 return 0;
@@ -1042,8 +1023,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1042static int vidioc_g_parm(struct file *filp, void *priv, 1023static int vidioc_g_parm(struct file *filp, void *priv,
1043 struct v4l2_streamparm *parm) 1024 struct v4l2_streamparm *parm)
1044{ 1025{
1045 struct go7007_file *gofh = priv; 1026 struct go7007 *go = ((struct go7007_file *) priv)->go;
1046 struct go7007 *go = gofh->go;
1047 struct v4l2_fract timeperframe = { 1027 struct v4l2_fract timeperframe = {
1048 .numerator = 1001 * go->fps_scale, 1028 .numerator = 1001 * go->fps_scale,
1049 .denominator = go->sensor_framerate, 1029 .denominator = go->sensor_framerate,
@@ -1061,8 +1041,7 @@ static int vidioc_g_parm(struct file *filp, void *priv,
1061static int vidioc_s_parm(struct file *filp, void *priv, 1041static int vidioc_s_parm(struct file *filp, void *priv,
1062 struct v4l2_streamparm *parm) 1042 struct v4l2_streamparm *parm)
1063{ 1043{
1064 struct go7007_file *gofh = priv; 1044 struct go7007 *go = ((struct go7007_file *) priv)->go;
1065 struct go7007 *go = gofh->go;
1066 unsigned int n, d; 1045 unsigned int n, d;
1067 1046
1068 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1047 if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1094,8 +1073,7 @@ static int vidioc_s_parm(struct file *filp, void *priv,
1094static int vidioc_enum_framesizes(struct file *filp, void *priv, 1073static int vidioc_enum_framesizes(struct file *filp, void *priv,
1095 struct v4l2_frmsizeenum *fsize) 1074 struct v4l2_frmsizeenum *fsize)
1096{ 1075{
1097 struct go7007_file *gofh = priv; 1076 struct go7007 *go = ((struct go7007_file *) priv)->go;
1098 struct go7007 *go = gofh->go;
1099 1077
1100 /* Return -EINVAL, if it is a TV board */ 1078 /* Return -EINVAL, if it is a TV board */
1101 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1079 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1115,8 +1093,7 @@ static int vidioc_enum_framesizes(struct file *filp, void *priv,
1115static int vidioc_enum_frameintervals(struct file *filp, void *priv, 1093static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1116 struct v4l2_frmivalenum *fival) 1094 struct v4l2_frmivalenum *fival)
1117{ 1095{
1118 struct go7007_file *gofh = priv; 1096 struct go7007 *go = ((struct go7007_file *) priv)->go;
1119 struct go7007 *go = gofh->go;
1120 1097
1121 /* Return -EINVAL, if it is a TV board */ 1098 /* Return -EINVAL, if it is a TV board */
1122 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) || 1099 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) ||
@@ -1133,10 +1110,27 @@ static int vidioc_enum_frameintervals(struct file *filp, void *priv,
1133 return 0; 1110 return 0;
1134} 1111}
1135 1112
1113static int vidioc_g_std(struct file *file, void *priv, v4l2_std_id *std)
1114{
1115 struct go7007 *go = ((struct go7007_file *) priv)->go;
1116
1117 switch (go->standard) {
1118 case GO7007_STD_NTSC:
1119 *std = V4L2_STD_NTSC;
1120 break;
1121 case GO7007_STD_PAL:
1122 *std = V4L2_STD_PAL;
1123 break;
1124 default:
1125 return -EINVAL;
1126 }
1127
1128 return 0;
1129}
1130
1136static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std) 1131static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1137{ 1132{
1138 struct go7007_file *gofh = priv; 1133 struct go7007 *go = ((struct go7007_file *) priv)->go;
1139 struct go7007 *go = gofh->go;
1140 1134
1141 if (go->streaming) 1135 if (go->streaming)
1142 return -EBUSY; 1136 return -EBUSY;
@@ -1178,30 +1172,27 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *std)
1178 return 0; 1172 return 0;
1179} 1173}
1180 1174
1181#if 0 1175static int vidioc_querystd(struct file *file, void *priv, v4l2_std_id *std)
1182 case VIDIOC_QUERYSTD: 1176{
1183 { 1177 struct go7007 *go = ((struct go7007_file *) priv)->go;
1184 v4l2_std_id *std = arg;
1185 1178
1186 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) && 1179 if ((go->board_info->flags & GO7007_BOARD_HAS_TUNER) &&
1187 go->input == go->board_info->num_inputs - 1) { 1180 go->input == go->board_info->num_inputs - 1) {
1188 if (!go->i2c_adapter_online) 1181 if (!go->i2c_adapter_online)
1189 return -EIO; 1182 return -EIO;
1190 i2c_clients_command(&go->i2c_adapter, 1183 i2c_clients_command(&go->i2c_adapter, VIDIOC_QUERYSTD, std);
1191 VIDIOC_QUERYSTD, arg); 1184 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV)
1192 } else if (go->board_info->sensor_flags & GO7007_SENSOR_TV) 1185 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
1193 *std = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM; 1186 else
1194 else 1187 *std = 0;
1195 *std = 0; 1188
1196 return 0; 1189 return 0;
1197 } 1190}
1198#endif
1199 1191
1200static int vidioc_enum_input(struct file *file, void *priv, 1192static int vidioc_enum_input(struct file *file, void *priv,
1201 struct v4l2_input *inp) 1193 struct v4l2_input *inp)
1202{ 1194{
1203 struct go7007_file *gofh = priv; 1195 struct go7007 *go = ((struct go7007_file *) priv)->go;
1204 struct go7007 *go = gofh->go;
1205 1196
1206 if (inp->index >= go->board_info->num_inputs) 1197 if (inp->index >= go->board_info->num_inputs)
1207 return -EINVAL; 1198 return -EINVAL;
@@ -1230,8 +1221,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
1230 1221
1231static int vidioc_g_input(struct file *file, void *priv, unsigned int *input) 1222static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1232{ 1223{
1233 struct go7007_file *gofh = priv; 1224 struct go7007 *go = ((struct go7007_file *) priv)->go;
1234 struct go7007 *go = gofh->go;
1235 1225
1236 *input = go->input; 1226 *input = go->input;
1237 1227
@@ -1240,8 +1230,7 @@ static int vidioc_g_input(struct file *file, void *priv, unsigned int *input)
1240 1230
1241static int vidioc_s_input(struct file *file, void *priv, unsigned int input) 1231static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1242{ 1232{
1243 struct go7007_file *gofh = priv; 1233 struct go7007 *go = ((struct go7007_file *) priv)->go;
1244 struct go7007 *go = gofh->go;
1245 1234
1246 if (input >= go->board_info->num_inputs) 1235 if (input >= go->board_info->num_inputs)
1247 return -EINVAL; 1236 return -EINVAL;
@@ -1262,8 +1251,7 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int input)
1262static int vidioc_g_tuner(struct file *file, void *priv, 1251static int vidioc_g_tuner(struct file *file, void *priv,
1263 struct v4l2_tuner *t) 1252 struct v4l2_tuner *t)
1264{ 1253{
1265 struct go7007_file *gofh = priv; 1254 struct go7007 *go = ((struct go7007_file *) priv)->go;
1266 struct go7007 *go = gofh->go;
1267 1255
1268 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1256 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1269 return -EINVAL; 1257 return -EINVAL;
@@ -1281,8 +1269,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
1281static int vidioc_s_tuner(struct file *file, void *priv, 1269static int vidioc_s_tuner(struct file *file, void *priv,
1282 struct v4l2_tuner *t) 1270 struct v4l2_tuner *t)
1283{ 1271{
1284 struct go7007_file *gofh = priv; 1272 struct go7007 *go = ((struct go7007_file *) priv)->go;
1285 struct go7007 *go = gofh->go;
1286 1273
1287 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1274 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1288 return -EINVAL; 1275 return -EINVAL;
@@ -1308,8 +1295,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
1308static int vidioc_g_frequency(struct file *file, void *priv, 1295static int vidioc_g_frequency(struct file *file, void *priv,
1309 struct v4l2_frequency *f) 1296 struct v4l2_frequency *f)
1310{ 1297{
1311 struct go7007_file *gofh = priv; 1298 struct go7007 *go = ((struct go7007_file *) priv)->go;
1312 struct go7007 *go = gofh->go;
1313 1299
1314 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1300 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1315 return -EINVAL; 1301 return -EINVAL;
@@ -1324,8 +1310,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1324static int vidioc_s_frequency(struct file *file, void *priv, 1310static int vidioc_s_frequency(struct file *file, void *priv,
1325 struct v4l2_frequency *f) 1311 struct v4l2_frequency *f)
1326{ 1312{
1327 struct go7007_file *gofh = priv; 1313 struct go7007 *go = ((struct go7007_file *) priv)->go;
1328 struct go7007 *go = gofh->go;
1329 1314
1330 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER)) 1315 if (!(go->board_info->flags & GO7007_BOARD_HAS_TUNER))
1331 return -EINVAL; 1316 return -EINVAL;
@@ -1340,8 +1325,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1340static int vidioc_cropcap(struct file *file, void *priv, 1325static int vidioc_cropcap(struct file *file, void *priv,
1341 struct v4l2_cropcap *cropcap) 1326 struct v4l2_cropcap *cropcap)
1342{ 1327{
1343 struct go7007_file *gofh = priv; 1328 struct go7007 *go = ((struct go7007_file *) priv)->go;
1344 struct go7007 *go = gofh->go;
1345 1329
1346 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1330 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1347 return -EINVAL; 1331 return -EINVAL;
@@ -1385,8 +1369,7 @@ static int vidioc_cropcap(struct file *file, void *priv,
1385 1369
1386static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop) 1370static int vidioc_g_crop(struct file *file, void *priv, struct v4l2_crop *crop)
1387{ 1371{
1388 struct go7007_file *gofh = priv; 1372 struct go7007 *go = ((struct go7007_file *) priv)->go;
1389 struct go7007 *go = gofh->go;
1390 1373
1391 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1374 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1392 return -EINVAL; 1375 return -EINVAL;
@@ -1734,18 +1717,18 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1734 return -EINVAL; /* only support VM_SHARED mapping */ 1717 return -EINVAL; /* only support VM_SHARED mapping */
1735 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE) 1718 if (vma->vm_end - vma->vm_start != GO7007_BUF_SIZE)
1736 return -EINVAL; /* must map exactly one full buffer */ 1719 return -EINVAL; /* must map exactly one full buffer */
1737 down(&gofh->lock); 1720 mutex_lock(&gofh->lock);
1738 index = vma->vm_pgoff / GO7007_BUF_PAGES; 1721 index = vma->vm_pgoff / GO7007_BUF_PAGES;
1739 if (index >= gofh->buf_count) { 1722 if (index >= gofh->buf_count) {
1740 up(&gofh->lock); 1723 mutex_unlock(&gofh->lock);
1741 return -EINVAL; /* trying to map beyond requested buffers */ 1724 return -EINVAL; /* trying to map beyond requested buffers */
1742 } 1725 }
1743 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) { 1726 if (index * GO7007_BUF_PAGES != vma->vm_pgoff) {
1744 up(&gofh->lock); 1727 mutex_unlock(&gofh->lock);
1745 return -EINVAL; /* offset is not aligned on buffer boundary */ 1728 return -EINVAL; /* offset is not aligned on buffer boundary */
1746 } 1729 }
1747 if (gofh->bufs[index].mapped > 0) { 1730 if (gofh->bufs[index].mapped > 0) {
1748 up(&gofh->lock); 1731 mutex_unlock(&gofh->lock);
1749 return -EBUSY; 1732 return -EBUSY;
1750 } 1733 }
1751 gofh->bufs[index].mapped = 1; 1734 gofh->bufs[index].mapped = 1;
@@ -1754,7 +1737,7 @@ static int go7007_mmap(struct file *file, struct vm_area_struct *vma)
1754 vma->vm_flags |= VM_DONTEXPAND; 1737 vma->vm_flags |= VM_DONTEXPAND;
1755 vma->vm_flags &= ~VM_IO; 1738 vma->vm_flags &= ~VM_IO;
1756 vma->vm_private_data = &gofh->bufs[index]; 1739 vma->vm_private_data = &gofh->bufs[index];
1757 up(&gofh->lock); 1740 mutex_unlock(&gofh->lock);
1758 return 0; 1741 return 0;
1759} 1742}
1760 1743
@@ -1801,7 +1784,9 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
1801 .vidioc_querybuf = vidioc_querybuf, 1784 .vidioc_querybuf = vidioc_querybuf,
1802 .vidioc_qbuf = vidioc_qbuf, 1785 .vidioc_qbuf = vidioc_qbuf,
1803 .vidioc_dqbuf = vidioc_dqbuf, 1786 .vidioc_dqbuf = vidioc_dqbuf,
1787 .vidioc_g_std = vidioc_g_std,
1804 .vidioc_s_std = vidioc_s_std, 1788 .vidioc_s_std = vidioc_s_std,
1789 .vidioc_querystd = vidioc_querystd,
1805 .vidioc_enum_input = vidioc_enum_input, 1790 .vidioc_enum_input = vidioc_enum_input,
1806 .vidioc_g_input = vidioc_g_input, 1791 .vidioc_g_input = vidioc_g_input,
1807 .vidioc_s_input = vidioc_s_input, 1792 .vidioc_s_input = vidioc_s_input,
@@ -1862,7 +1847,7 @@ void go7007_v4l2_remove(struct go7007 *go)
1862{ 1847{
1863 unsigned long flags; 1848 unsigned long flags;
1864 1849
1865 down(&go->hw_lock); 1850 mutex_lock(&go->hw_lock);
1866 if (go->streaming) { 1851 if (go->streaming) {
1867 go->streaming = 0; 1852 go->streaming = 0;
1868 go7007_stream_stop(go); 1853 go7007_stream_stop(go);
@@ -1870,7 +1855,7 @@ void go7007_v4l2_remove(struct go7007 *go)
1870 abort_queued(go); 1855 abort_queued(go);
1871 spin_unlock_irqrestore(&go->spinlock, flags); 1856 spin_unlock_irqrestore(&go->spinlock, flags);
1872 } 1857 }
1873 up(&go->hw_lock); 1858 mutex_unlock(&go->hw_lock);
1874 if (go->video_dev) 1859 if (go->video_dev)
1875 video_unregister_device(go->video_dev); 1860 video_unregister_device(go->video_dev);
1876} 1861}
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/go7007/go7007.txt
index 1c2907c1dc81..06a76da32128 100644
--- a/drivers/staging/go7007/go7007.txt
+++ b/drivers/staging/go7007/go7007.txt
@@ -2,7 +2,7 @@ This is a driver for the WIS GO7007SB multi-format video encoder.
2 2
3Pete Eberlein <pete@sensoray.com> 3Pete Eberlein <pete@sensoray.com>
4 4
5The driver was originally released under the GPL and is currently hosted at: 5The driver was orignally released under the GPL and is currently hosted at:
6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver 6http://nikosapi.org/wiki/index.php/WIS_Go7007_Linux_driver
7The go7007 firmware can be acquired from the package on the site above. 7The go7007 firmware can be acquired from the package on the site above.
8 8
@@ -24,10 +24,10 @@ These should be used instead of the non-standard GO7007 ioctls described
24below. 24below.
25 25
26 26
27The README files from the original package appears below: 27The README files from the orignal package appear below:
28 28
29--------------------------------------------------------------------------- 29---------------------------------------------------------------------------
30 WIS GO7007SB Public Linux Driver 30 WIS GO7007SB Public Linux Driver
31--------------------------------------------------------------------------- 31---------------------------------------------------------------------------
32 32
33 33
@@ -78,23 +78,23 @@ All vendor-built kernels should already be configured properly. However,
78for custom-built kernels, the following options need to be enabled in the 78for custom-built kernels, the following options need to be enabled in the
79kernel as built-in or modules: 79kernel as built-in or modules:
80 80
81 CONFIG_HOTPLUG - Support for hot-pluggable devices 81 CONFIG_HOTPLUG - Support for hot-pluggable devices
82 CONFIG_MODULES - Enable loadable module support 82 CONFIG_MODULES - Enable loadable module support
83 CONFIG_KMOD - Automatic kernel module loading 83 CONFIG_KMOD - Automatic kernel module loading
84 CONFIG_FW_LOADER - Hotplug firmware loading support 84 CONFIG_FW_LOADER - Hotplug firmware loading support
85 CONFIG_I2C - I2C support 85 CONFIG_I2C - I2C support
86 CONFIG_VIDEO_DEV - Video For Linux 86 CONFIG_VIDEO_DEV - Video For Linux
87 CONFIG_SOUND - Sound card support 87 CONFIG_SOUND - Sound card support
88 CONFIG_SND - Advanced Linux Sound Architecture 88 CONFIG_SND - Advanced Linux Sound Architecture
89 CONFIG_USB - Support for Host-side USB 89 CONFIG_USB - Support for Host-side USB
90 CONFIG_USB_DEVICEFS - USB device filesystem 90 CONFIG_USB_DEVICEFS - USB device filesystem
91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support 91 CONFIG_USB_EHCI_HCD - EHCI HCD (USB 2.0) support
92 92
93Additionally, to use the example application, the following options need to 93Additionally, to use the example application, the following options need to
94be enabled in the ALSA section: 94be enabled in the ALSA section:
95 95
96 CONFIG_SND_MIXER_OSS - OSS Mixer API 96 CONFIG_SND_MIXER_OSS - OSS Mixer API
97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API 97 CONFIG_SND_PCM_OSS - OSS PCM (digital audio) API
98 98
99The hotplug scripts, along with the fxload utility, must also be installed. 99The hotplug scripts, along with the fxload utility, must also be installed.
100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>. 100These scripts can be obtained from <http://linux-hotplug.sourceforge.net/>.
@@ -107,7 +107,7 @@ fxload and for loading firmware into the driver using the firmware agent.
107 107
108Most users should be able to compile the driver by simply running: 108Most users should be able to compile the driver by simply running:
109 109
110 $ make 110 $ make
111 111
112in the top-level directory of the driver kit. First the kernel modules 112in the top-level directory of the driver kit. First the kernel modules
113will be built, followed by the example applications. 113will be built, followed by the example applications.
@@ -117,12 +117,12 @@ currently-running kernel, or if the module should be built for a kernel
117other than the currently-running kernel, an additional parameter will need 117other than the currently-running kernel, an additional parameter will need
118to be passed to make to specify the appropriate kernel source directory: 118to be passed to make to specify the appropriate kernel source directory:
119 119
120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3 120 $ make KERNELSRC=/usr/src/linux-2.6.10-custom3
121 121
122Once the compile completes, the driver and firmware files should be 122Once the compile completes, the driver and firmware files should be
123installed by running: 123installed by running:
124 124
125 $ make install 125 $ make install
126 126
127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra" 127The kernel modules will be placed in "/lib/modules/<KERNEL VERSION>/extra"
128and the firmware files will be placed in the appropriate hotplug firmware 128and the firmware files will be placed in the appropriate hotplug firmware
@@ -200,7 +200,7 @@ stereo audio broadcasts on the A2 carrier.
200To verify that the configuration has been placed in the correct location, 200To verify that the configuration has been placed in the correct location,
201execute: 201execute:
202 202
203 $ modprobe -c | grep wis-sony-tuner 203 $ modprobe -c | grep wis-sony-tuner
204 204
205If the configuration line appears, then modprobe will pass the parameters 205If the configuration line appears, then modprobe will pass the parameters
206correctly the next time the wis-sony-tuner module is loaded into the 206correctly the next time the wis-sony-tuner module is loaded into the
@@ -223,7 +223,7 @@ This application will auto-detect the V4L2 and ALSA/OSS device names of the
223hardware and will record video and audio to an AVI file for a specified 223hardware and will record video and audio to an AVI file for a specified
224number of seconds. For example: 224number of seconds. For example:
225 225
226 $ apps/gorecord -duration 60 capture.avi 226 $ apps/gorecord -duration 60 capture.avi
227 227
228If this application does not successfully record an AVI file, the error 228If this application does not successfully record an AVI file, the error
229messages produced by gorecord and recorded in the system log (usually in 229messages produced by gorecord and recorded in the system log (usually in
@@ -286,35 +286,35 @@ features of the GO7007SB encoder, which are described below:
286 286
287 Fields in struct go7007_comp_params: 287 Fields in struct go7007_comp_params:
288 288
289 __u32 The maximum number of frames in each 289 __u32 The maximum number of frames in each
290 gop_size Group Of Pictures; i.e. the maximum 290 gop_size Group Of Pictures; i.e. the maximum
291 number of frames minus one between 291 number of frames minus one between
292 each key frame. 292 each key frame.
293 293
294 __u32 The maximum number of sequential 294 __u32 The maximum number of sequential
295 max_b_frames bidirectionally-predicted frames. 295 max_b_frames bidirectionally-predicted frames.
296 (B-frames are not yet supported.) 296 (B-frames are not yet supported.)
297 297
298 enum go7007_aspect_ratio The aspect ratio to be encoded in the 298 enum go7007_aspect_ratio The aspect ratio to be encoded in the
299 aspect_ratio meta-data of the compressed format. 299 aspect_ratio meta-data of the compressed format.
300 300
301 Choices are: 301 Choices are:
302 GO7007_ASPECT_RATIO_1_1 302 GO7007_ASPECT_RATIO_1_1
303 GO7007_ASPECT_RATIO_4_3_NTSC 303 GO7007_ASPECT_RATIO_4_3_NTSC
304 GO7007_ASPECT_RATIO_4_3_PAL 304 GO7007_ASPECT_RATIO_4_3_PAL
305 GO7007_ASPECT_RATIO_16_9_NTSC 305 GO7007_ASPECT_RATIO_16_9_NTSC
306 GO7007_ASPECT_RATIO_16_9_PAL 306 GO7007_ASPECT_RATIO_16_9_PAL
307 307
308 __u32 Bit-wise OR of control flags (below) 308 __u32 Bit-wise OR of control flags (below)
309 flags 309 flags
310 310
311 Flags in struct go7007_comp_params: 311 Flags in struct go7007_comp_params:
312 312
313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used 313 GO7007_COMP_CLOSED_GOP Only produce self-contained GOPs, used
314 to produce streams appropriate for 314 to produce streams appropriate for
315 random seeking. 315 random seeking.
316 316
317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header. 317 GO7007_COMP_OMIT_SEQ_HEADER Omit the stream sequence header.
318 318
319 319
320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS 320 GO7007IOC_S_MPEG_PARAMS, GO7007IOC_G_MPEG_PARAMS
@@ -337,56 +337,56 @@ features of the GO7007SB encoder, which are described below:
337 337
338 Fields in struct go7007_mpeg_params: 338 Fields in struct go7007_mpeg_params:
339 339
340 enum go7007_mpeg_video_standard 340 enum go7007_mpeg_video_standard
341 mpeg_video_standard The MPEG video standard in which to 341 mpeg_video_standard The MPEG video standard in which to
342 compress the video. 342 compress the video.
343 343
344 Choices are: 344 Choices are:
345 GO7007_MPEG_VIDEO_MPEG1 345 GO7007_MPEG_VIDEO_MPEG1
346 GO7007_MPEG_VIDEO_MPEG2 346 GO7007_MPEG_VIDEO_MPEG2
347 GO7007_MPEG_VIDEO_MPEG4 347 GO7007_MPEG_VIDEO_MPEG4
348 348
349 __u32 Bit-wise OR of control flags (below) 349 __u32 Bit-wise OR of control flags (below)
350 flags 350 flags
351 351
352 __u32 The profile and level indication to be 352 __u32 The profile and level indication to be
353 pali stored in the sequence header. This 353 pali stored in the sequence header. This
354 is only used as an indicator to the 354 is only used as an indicator to the
355 decoder, and does not affect the MPEG 355 decoder, and does not affect the MPEG
356 features used in the video stream. 356 features used in the video stream.
357 Not valid for MPEG1. 357 Not valid for MPEG1.
358 358
359 Choices for MPEG2 are: 359 Choices for MPEG2 are:
360 GO7007_MPEG2_PROFILE_MAIN_MAIN 360 GO7007_MPEG2_PROFILE_MAIN_MAIN
361 361
362 Choices for MPEG4 are: 362 Choices for MPEG4 are:
363 GO7007_MPEG4_PROFILE_S_L0 363 GO7007_MPEG4_PROFILE_S_L0
364 GO7007_MPEG4_PROFILE_S_L1 364 GO7007_MPEG4_PROFILE_S_L1
365 GO7007_MPEG4_PROFILE_S_L2 365 GO7007_MPEG4_PROFILE_S_L2
366 GO7007_MPEG4_PROFILE_S_L3 366 GO7007_MPEG4_PROFILE_S_L3
367 GO7007_MPEG4_PROFILE_ARTS_L1 367 GO7007_MPEG4_PROFILE_ARTS_L1
368 GO7007_MPEG4_PROFILE_ARTS_L2 368 GO7007_MPEG4_PROFILE_ARTS_L2
369 GO7007_MPEG4_PROFILE_ARTS_L3 369 GO7007_MPEG4_PROFILE_ARTS_L3
370 GO7007_MPEG4_PROFILE_ARTS_L4 370 GO7007_MPEG4_PROFILE_ARTS_L4
371 GO7007_MPEG4_PROFILE_AS_L0 371 GO7007_MPEG4_PROFILE_AS_L0
372 GO7007_MPEG4_PROFILE_AS_L1 372 GO7007_MPEG4_PROFILE_AS_L1
373 GO7007_MPEG4_PROFILE_AS_L2 373 GO7007_MPEG4_PROFILE_AS_L2
374 GO7007_MPEG4_PROFILE_AS_L3 374 GO7007_MPEG4_PROFILE_AS_L3
375 GO7007_MPEG4_PROFILE_AS_L4 375 GO7007_MPEG4_PROFILE_AS_L4
376 GO7007_MPEG4_PROFILE_AS_L5 376 GO7007_MPEG4_PROFILE_AS_L5
377 377
378 Flags in struct go7007_mpeg_params: 378 Flags in struct go7007_mpeg_params:
379 379
380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and 380 GO7007_MPEG_FORCE_DVD_MODE Force all compression parameters and
381 bitrate control settings to comply 381 bitrate control settings to comply
382 with DVD MPEG2 stream requirements. 382 with DVD MPEG2 stream requirements.
383 This overrides most compression and 383 This overrides most compression and
384 bitrate settings! 384 bitrate settings!
385 385
386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header. 386 GO7007_MPEG_OMIT_GOP_HEADER Omit the GOP header.
387 387
388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at 388 GO7007_MPEG_REPEAT_SEQHEADER Repeat the MPEG sequence header at
389 the start of each GOP. 389 the start of each GOP.
390 390
391 391
392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE 392 GO7007IOC_S_BITRATE, GO7007IOC_G_BITRATE
@@ -404,7 +404,7 @@ features of the GO7007SB encoder, which are described below:
404 404
405 405
406---------------------------------------------------------------------------- 406----------------------------------------------------------------------------
407 Installing the WIS PCI Voyager Driver 407 Installing the WIS PCI Voyager Driver
408--------------------------------------------------------------------------- 408---------------------------------------------------------------------------
409 409
410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x 410The WIS PCI Voyager driver requires several patches to the Linux 2.6.11.x
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/go7007/s2250-board.c
index 1706fbf06847..8c85a9c3665a 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/go7007/s2250-board.c
@@ -21,12 +21,10 @@
21#include <linux/i2c.h> 21#include <linux/i2c.h>
22#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23#include <media/v4l2-common.h> 23#include <media/v4l2-common.h>
24#include "s2250-loader.h"
24#include "go7007-priv.h" 25#include "go7007-priv.h"
25#include "wis-i2c.h" 26#include "wis-i2c.h"
26 27
27extern int s2250loader_init(void);
28extern void s2250loader_cleanup(void);
29
30#define TLV320_ADDRESS 0x34 28#define TLV320_ADDRESS 0x34
31#define VPX322_ADDR_ANALOGCONTROL1 0x02 29#define VPX322_ADDR_ANALOGCONTROL1 0x02
32#define VPX322_ADDR_BRIGHTNESS0 0x0127 30#define VPX322_ADDR_BRIGHTNESS0 0x0127
@@ -34,7 +32,7 @@ extern void s2250loader_cleanup(void);
34#define VPX322_ADDR_CONTRAST0 0x0128 32#define VPX322_ADDR_CONTRAST0 0x0128
35#define VPX322_ADDR_CONTRAST1 0x0132 33#define VPX322_ADDR_CONTRAST1 0x0132
36#define VPX322_ADDR_HUE 0x00dc 34#define VPX322_ADDR_HUE 0x00dc
37#define VPX322_ADDR_SAT 0x0030 35#define VPX322_ADDR_SAT 0x0030
38 36
39struct go7007_usb_board { 37struct go7007_usb_board {
40 unsigned int flags; 38 unsigned int flags;
@@ -43,7 +41,7 @@ struct go7007_usb_board {
43 41
44struct go7007_usb { 42struct go7007_usb {
45 struct go7007_usb_board *board; 43 struct go7007_usb_board *board;
46 struct semaphore i2c_lock; 44 struct mutex i2c_lock;
47 struct usb_device *usbdev; 45 struct usb_device *usbdev;
48 struct urb *video_urbs[8]; 46 struct urb *video_urbs[8];
49 struct urb *audio_urbs[8]; 47 struct urb *audio_urbs[8];
@@ -114,7 +112,7 @@ static u16 vid_regs_fp_pal[] =
114}; 112};
115 113
116struct s2250 { 114struct s2250 {
117 int std; 115 v4l2_std_id std;
118 int input; 116 int input;
119 int brightness; 117 int brightness;
120 int contrast; 118 int contrast;
@@ -165,7 +163,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
165 return -ENOMEM; 163 return -ENOMEM;
166 164
167 usb = go->hpi_context; 165 usb = go->hpi_context;
168 if (down_interruptible(&usb->i2c_lock) != 0) { 166 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
169 printk(KERN_INFO "i2c lock failed\n"); 167 printk(KERN_INFO "i2c lock failed\n");
170 kfree(buf); 168 kfree(buf);
171 return -EINTR; 169 return -EINTR;
@@ -175,7 +173,7 @@ static int write_reg(struct i2c_client *client, u8 reg, u8 value)
175 buf, 173 buf,
176 16, 1); 174 16, 1);
177 175
178 up(&usb->i2c_lock); 176 mutex_unlock(&usb->i2c_lock);
179 kfree(buf); 177 kfree(buf);
180 return rc; 178 return rc;
181} 179}
@@ -203,19 +201,23 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
203 memset(buf, 0xcd, 6); 201 memset(buf, 0xcd, 6);
204 202
205 usb = go->hpi_context; 203 usb = go->hpi_context;
206 if (down_interruptible(&usb->i2c_lock) != 0) { 204 if (mutex_lock_interruptible(&usb->i2c_lock) != 0) {
207 printk(KERN_INFO "i2c lock failed\n"); 205 printk(KERN_INFO "i2c lock failed\n");
206 kfree(buf);
208 return -EINTR; 207 return -EINTR;
209 } 208 }
210 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) 209 if (go7007_usb_vendor_request(go, 0x57, addr, val, buf, 16, 1) < 0) {
210 kfree(buf);
211 return -EFAULT; 211 return -EFAULT;
212 }
212 213
213 up(&usb->i2c_lock); 214 mutex_unlock(&usb->i2c_lock);
214 if (buf[0] == 0) { 215 if (buf[0] == 0) {
215 unsigned int subaddr, val_read; 216 unsigned int subaddr, val_read;
216 217
217 subaddr = (buf[4] << 8) + buf[5]; 218 subaddr = (buf[4] << 8) + buf[5];
218 val_read = (buf[2] << 8) + buf[3]; 219 val_read = (buf[2] << 8) + buf[3];
220 kfree(buf);
219 if (val_read != val) { 221 if (val_read != val) {
220 printk(KERN_INFO "invalid fp write %x %x\n", 222 printk(KERN_INFO "invalid fp write %x %x\n",
221 val_read, val); 223 val_read, val);
@@ -226,8 +228,10 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
226 subaddr, addr); 228 subaddr, addr);
227 return -EFAULT; 229 return -EFAULT;
228 } 230 }
229 } else 231 } else {
232 kfree(buf);
230 return -EFAULT; 233 return -EFAULT;
234 }
231 235
232 /* save last 12b value */ 236 /* save last 12b value */
233 if (addr == 0x12b) 237 if (addr == 0x12b)
@@ -236,6 +240,45 @@ static int write_reg_fp(struct i2c_client *client, u16 addr, u16 val)
236 return 0; 240 return 0;
237} 241}
238 242
243static int read_reg_fp(struct i2c_client *client, u16 addr, u16 *val)
244{
245 struct go7007 *go = i2c_get_adapdata(client->adapter);
246 struct go7007_usb *usb;
247 u8 *buf;
248
249 if (go == NULL)
250 return -ENODEV;
251
252 if (go->status == STATUS_SHUTDOWN)
253 return -EBUSY;
254
255 buf = kzalloc(16, GFP_KERNEL);
256
257 if (buf == NULL)
258 return -ENOMEM;
259
260
261
262 memset(buf, 0xcd, 6);
263 usb = go->hpi_context;
264 if (down_interruptible(&usb->i2c_lock) != 0) {
265 printk(KERN_INFO "i2c lock failed\n");
266 kfree(buf);
267 return -EINTR;
268 }
269 if (go7007_usb_vendor_request(go, 0x58, addr, 0, buf, 16, 1) < 0) {
270 kfree(buf);
271 return -EFAULT;
272 }
273 up(&usb->i2c_lock);
274
275 *val = (buf[0] << 8) | buf[1];
276 kfree(buf);
277
278 return 0;
279}
280
281
239static int write_regs(struct i2c_client *client, u8 *regs) 282static int write_regs(struct i2c_client *client, u8 *regs)
240{ 283{
241 int i; 284 int i;
@@ -350,14 +393,42 @@ static int s2250_command(struct i2c_client *client,
350 { 393 {
351 struct v4l2_control *ctrl = arg; 394 struct v4l2_control *ctrl = arg;
352 int value1; 395 int value1;
396 u16 oldvalue;
353 397
354 switch (ctrl->id) { 398 switch (ctrl->id) {
355 case V4L2_CID_BRIGHTNESS: 399 case V4L2_CID_BRIGHTNESS:
356 printk(KERN_INFO "s2250: future setting\n"); 400 if (ctrl->value > 100)
357 return -EINVAL; 401 dec->brightness = 100;
402 else if (ctrl->value < 0)
403 dec->brightness = 0;
404 else
405 dec->brightness = ctrl->value;
406 value1 = (dec->brightness - 50) * 255 / 100;
407 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS0, &oldvalue);
408 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS0,
409 value1 | (oldvalue & ~0xff));
410 read_reg_fp(client, VPX322_ADDR_BRIGHTNESS1, &oldvalue);
411 write_reg_fp(client, VPX322_ADDR_BRIGHTNESS1,
412 value1 | (oldvalue & ~0xff));
413 write_reg_fp(client, 0x140, 0x60);
414 break;
358 case V4L2_CID_CONTRAST: 415 case V4L2_CID_CONTRAST:
359 printk(KERN_INFO "s2250: future setting\n"); 416 if (ctrl->value > 100)
360 return -EINVAL; 417 dec->contrast = 100;
418 else if (ctrl->value < 0)
419 dec->contrast = 0;
420 else
421 dec->contrast = ctrl->value;
422 value1 = dec->contrast * 0x40 / 100;
423 if (value1 > 0x3f)
424 value1 = 0x3f; /* max */
425 read_reg_fp(client, VPX322_ADDR_CONTRAST0, &oldvalue);
426 write_reg_fp(client, VPX322_ADDR_CONTRAST0,
427 value1 | (oldvalue & ~0x3f));
428 read_reg_fp(client, VPX322_ADDR_CONTRAST1, &oldvalue);
429 write_reg_fp(client, VPX322_ADDR_CONTRAST1,
430 value1 | (oldvalue & ~0x3f));
431 write_reg_fp(client, 0x140, 0x60);
361 break; 432 break;
362 case V4L2_CID_SATURATION: 433 case V4L2_CID_SATURATION:
363 if (ctrl->value > 127) 434 if (ctrl->value > 127)
@@ -541,7 +612,7 @@ static int s2250_probe(struct i2c_client *client,
541 dec->audio_input = 0; 612 dec->audio_input = 0;
542 write_reg(client, 0x08, 0x02); /* Line In */ 613 write_reg(client, 0x08, 0x02); /* Line In */
543 614
544 if (down_interruptible(&usb->i2c_lock) == 0) { 615 if (mutex_lock_interruptible(&usb->i2c_lock) == 0) {
545 data = kzalloc(16, GFP_KERNEL); 616 data = kzalloc(16, GFP_KERNEL);
546 if (data != NULL) { 617 if (data != NULL) {
547 int rc; 618 int rc;
@@ -560,7 +631,7 @@ static int s2250_probe(struct i2c_client *client,
560 } 631 }
561 kfree(data); 632 kfree(data);
562 } 633 }
563 up(&usb->i2c_lock); 634 mutex_unlock(&usb->i2c_lock);
564 } 635 }
565 636
566 printk("s2250: initialized successfully\n"); 637 printk("s2250: initialized successfully\n");
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/go7007/s2250-loader.c
index bb22347af60e..d7bf82983274 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/go7007/s2250-loader.c
@@ -35,7 +35,7 @@ typedef struct device_extension_s {
35#define MAX_DEVICES 256 35#define MAX_DEVICES 256
36 36
37static pdevice_extension_t s2250_dev_table[MAX_DEVICES]; 37static pdevice_extension_t s2250_dev_table[MAX_DEVICES];
38static DECLARE_MUTEX(s2250_dev_table_mutex); 38static DEFINE_MUTEX(s2250_dev_table_mutex);
39 39
40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref) 40#define to_s2250loader_dev_common(d) container_of(d, device_extension_t, kref)
41static void s2250loader_delete(struct kref *kref) 41static void s2250loader_delete(struct kref *kref)
@@ -67,7 +67,7 @@ static int s2250loader_probe(struct usb_interface *interface,
67 printk(KERN_ERR "can't handle multiple config\n"); 67 printk(KERN_ERR "can't handle multiple config\n");
68 return -1; 68 return -1;
69 } 69 }
70 down(&s2250_dev_table_mutex); 70 mutex_lock(&s2250_dev_table_mutex);
71 71
72 for (minor = 0; minor < MAX_DEVICES; minor++) { 72 for (minor = 0; minor < MAX_DEVICES; minor++) {
73 if (s2250_dev_table[minor] == NULL) 73 if (s2250_dev_table[minor] == NULL)
@@ -96,7 +96,7 @@ static int s2250loader_probe(struct usb_interface *interface,
96 96
97 kref_init(&(s->kref)); 97 kref_init(&(s->kref));
98 98
99 up(&s2250_dev_table_mutex); 99 mutex_unlock(&s2250_dev_table_mutex);
100 100
101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) { 101 if (request_firmware(&fw, S2250_LOADER_FIRMWARE, &usbdev->dev)) {
102 printk(KERN_ERR 102 printk(KERN_ERR
@@ -128,7 +128,7 @@ static int s2250loader_probe(struct usb_interface *interface,
128 return 0; 128 return 0;
129 129
130failed: 130failed:
131 up(&s2250_dev_table_mutex); 131 mutex_unlock(&s2250_dev_table_mutex);
132failed2: 132failed2:
133 if (s) 133 if (s)
134 kref_put(&(s->kref), s2250loader_delete); 134 kref_put(&(s->kref), s2250loader_delete);
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/go7007/snd-go7007.c
index cd19be6c00e0..03c4dfc138a1 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/go7007/snd-go7007.c
@@ -26,7 +26,7 @@
26#include <linux/time.h> 26#include <linux/time.h>
27#include <linux/mm.h> 27#include <linux/mm.h>
28#include <linux/i2c.h> 28#include <linux/i2c.h>
29#include <linux/semaphore.h> 29#include <linux/mutex.h>
30#include <linux/uaccess.h> 30#include <linux/uaccess.h>
31#include <asm/system.h> 31#include <asm/system.h>
32#include <sound/core.h> 32#include <sound/core.h>
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/go7007/wis-tw9903.c
index 6c3427bb6f4c..506dca6e942e 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/go7007/wis-tw9903.c
@@ -111,7 +111,8 @@ static int wis_tw9903_command(struct i2c_client *client,
111 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1)); 111 i2c_smbus_write_byte_data(client, 0x02, 0x40 | (*input << 1));
112 break; 112 break;
113 } 113 }
114#if 0 /* The scaler on this thing seems to be horribly broken */ 114#if 0
115 /* The scaler on this thing seems to be horribly broken */
115 case DECODER_SET_RESOLUTION: 116 case DECODER_SET_RESOLUTION:
116 { 117 {
117 struct video_decoder_resolution *res = arg; 118 struct video_decoder_resolution *res = arg;
diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h
index 51c8d2d49e42..b6cb5425cde3 100644
--- a/include/linux/dvb/frontend.h
+++ b/include/linux/dvb/frontend.h
@@ -173,7 +173,8 @@ typedef enum fe_modulation {
173typedef enum fe_transmit_mode { 173typedef enum fe_transmit_mode {
174 TRANSMISSION_MODE_2K, 174 TRANSMISSION_MODE_2K,
175 TRANSMISSION_MODE_8K, 175 TRANSMISSION_MODE_8K,
176 TRANSMISSION_MODE_AUTO 176 TRANSMISSION_MODE_AUTO,
177 TRANSMISSION_MODE_4K
177} fe_transmit_mode_t; 178} fe_transmit_mode_t;
178 179
179typedef enum fe_bandwidth { 180typedef enum fe_bandwidth {
@@ -268,15 +269,42 @@ struct dvb_frontend_event {
268#define DTV_FE_CAPABILITY 16 269#define DTV_FE_CAPABILITY 16
269#define DTV_DELIVERY_SYSTEM 17 270#define DTV_DELIVERY_SYSTEM 17
270 271
271#define DTV_API_VERSION 35 272/* ISDB-T and ISDB-Tsb */
272#define DTV_API_VERSION 35 273#define DTV_ISDBT_PARTIAL_RECEPTION 18
273#define DTV_CODE_RATE_HP 36 274#define DTV_ISDBT_SOUND_BROADCASTING 19
274#define DTV_CODE_RATE_LP 37
275#define DTV_GUARD_INTERVAL 38
276#define DTV_TRANSMISSION_MODE 39
277#define DTV_HIERARCHY 40
278 275
279#define DTV_MAX_COMMAND DTV_HIERARCHY 276#define DTV_ISDBT_SB_SUBCHANNEL_ID 20
277#define DTV_ISDBT_SB_SEGMENT_IDX 21
278#define DTV_ISDBT_SB_SEGMENT_COUNT 22
279
280#define DTV_ISDBT_LAYERA_FEC 23
281#define DTV_ISDBT_LAYERA_MODULATION 24
282#define DTV_ISDBT_LAYERA_SEGMENT_COUNT 25
283#define DTV_ISDBT_LAYERA_TIME_INTERLEAVING 26
284
285#define DTV_ISDBT_LAYERB_FEC 27
286#define DTV_ISDBT_LAYERB_MODULATION 28
287#define DTV_ISDBT_LAYERB_SEGMENT_COUNT 29
288#define DTV_ISDBT_LAYERB_TIME_INTERLEAVING 30
289
290#define DTV_ISDBT_LAYERC_FEC 31
291#define DTV_ISDBT_LAYERC_MODULATION 32
292#define DTV_ISDBT_LAYERC_SEGMENT_COUNT 33
293#define DTV_ISDBT_LAYERC_TIME_INTERLEAVING 34
294
295#define DTV_API_VERSION 35
296
297#define DTV_CODE_RATE_HP 36
298#define DTV_CODE_RATE_LP 37
299#define DTV_GUARD_INTERVAL 38
300#define DTV_TRANSMISSION_MODE 39
301#define DTV_HIERARCHY 40
302
303#define DTV_ISDBT_LAYER_ENABLED 41
304
305#define DTV_ISDBS_TS_ID 42
306
307#define DTV_MAX_COMMAND DTV_ISDBS_TS_ID
280 308
281typedef enum fe_pilot { 309typedef enum fe_pilot {
282 PILOT_ON, 310 PILOT_ON,
diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h
index 25b823b81734..540b0583d9fb 100644
--- a/include/linux/dvb/version.h
+++ b/include/linux/dvb/version.h
@@ -24,6 +24,6 @@
24#define _DVBVERSION_H_ 24#define _DVBVERSION_H_
25 25
26#define DVB_API_VERSION 5 26#define DVB_API_VERSION 5
27#define DVB_API_VERSION_MINOR 0 27#define DVB_API_VERSION_MINOR 1
28 28
29#endif /*_DVBVERSION_H_*/ 29#endif /*_DVBVERSION_H_*/
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 3689d7d81fe9..b59e78c57161 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -910,9 +910,10 @@ enum v4l2_colorfx {
910 V4L2_COLORFX_SEPIA = 2, 910 V4L2_COLORFX_SEPIA = 2,
911}; 911};
912#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32) 912#define V4L2_CID_AUTOBRIGHTNESS (V4L2_CID_BASE+32)
913#define V4L2_CID_BAND_STOP_FILTER (V4L2_CID_BASE+33)
913 914
914/* last CID + 1 */ 915/* last CID + 1 */
915#define V4L2_CID_LASTP1 (V4L2_CID_BASE+33) 916#define V4L2_CID_LASTP1 (V4L2_CID_BASE+34)
916 917
917/* MPEG-class control IDs defined by V4L2 */ 918/* MPEG-class control IDs defined by V4L2 */
918#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900) 919#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
diff --git a/include/media/davinci/ccdc_types.h b/include/media/davinci/ccdc_types.h
new file mode 100644
index 000000000000..5773874bf266
--- /dev/null
+++ b/include/media/davinci/ccdc_types.h
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 **************************************************************************/
19#ifndef _CCDC_TYPES_H
20#define _CCDC_TYPES_H
21enum ccdc_pixfmt {
22 CCDC_PIXFMT_RAW,
23 CCDC_PIXFMT_YCBCR_16BIT,
24 CCDC_PIXFMT_YCBCR_8BIT
25};
26
27enum ccdc_frmfmt {
28 CCDC_FRMFMT_PROGRESSIVE,
29 CCDC_FRMFMT_INTERLACED
30};
31
32/* PIXEL ORDER IN MEMORY from LSB to MSB */
33/* only applicable for 8-bit input mode */
34enum ccdc_pixorder {
35 CCDC_PIXORDER_YCBYCR,
36 CCDC_PIXORDER_CBYCRY,
37};
38
39enum ccdc_buftype {
40 CCDC_BUFTYPE_FLD_INTERLEAVED,
41 CCDC_BUFTYPE_FLD_SEPARATED
42};
43#endif
diff --git a/include/media/davinci/dm355_ccdc.h b/include/media/davinci/dm355_ccdc.h
new file mode 100644
index 000000000000..df8a7b107477
--- /dev/null
+++ b/include/media/davinci/dm355_ccdc.h
@@ -0,0 +1,321 @@
1/*
2 * Copyright (C) 2005-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM355_CCDC_H
19#define _DM355_CCDC_H
20#include <media/davinci/ccdc_types.h>
21#include <media/davinci/vpfe_types.h>
22
23/* enum for No of pixel per line to be avg. in Black Clamping */
24enum ccdc_sample_length {
25 CCDC_SAMPLE_1PIXELS,
26 CCDC_SAMPLE_2PIXELS,
27 CCDC_SAMPLE_4PIXELS,
28 CCDC_SAMPLE_8PIXELS,
29 CCDC_SAMPLE_16PIXELS
30};
31
32/* enum for No of lines in Black Clamping */
33enum ccdc_sample_line {
34 CCDC_SAMPLE_1LINES,
35 CCDC_SAMPLE_2LINES,
36 CCDC_SAMPLE_4LINES,
37 CCDC_SAMPLE_8LINES,
38 CCDC_SAMPLE_16LINES
39};
40
41/* enum for Alaw gama width */
42enum ccdc_gamma_width {
43 CCDC_GAMMA_BITS_13_4,
44 CCDC_GAMMA_BITS_12_3,
45 CCDC_GAMMA_BITS_11_2,
46 CCDC_GAMMA_BITS_10_1,
47 CCDC_GAMMA_BITS_09_0
48};
49
50enum ccdc_colpats {
51 CCDC_RED,
52 CCDC_GREEN_RED,
53 CCDC_GREEN_BLUE,
54 CCDC_BLUE
55};
56
57struct ccdc_col_pat {
58 enum ccdc_colpats olop;
59 enum ccdc_colpats olep;
60 enum ccdc_colpats elop;
61 enum ccdc_colpats elep;
62};
63
64enum ccdc_datasft {
65 CCDC_DATA_NO_SHIFT,
66 CCDC_DATA_SHIFT_1BIT,
67 CCDC_DATA_SHIFT_2BIT,
68 CCDC_DATA_SHIFT_3BIT,
69 CCDC_DATA_SHIFT_4BIT,
70 CCDC_DATA_SHIFT_5BIT,
71 CCDC_DATA_SHIFT_6BIT
72};
73
74enum ccdc_data_size {
75 CCDC_DATA_16BITS,
76 CCDC_DATA_15BITS,
77 CCDC_DATA_14BITS,
78 CCDC_DATA_13BITS,
79 CCDC_DATA_12BITS,
80 CCDC_DATA_11BITS,
81 CCDC_DATA_10BITS,
82 CCDC_DATA_8BITS
83};
84enum ccdc_mfilt1 {
85 CCDC_NO_MEDIAN_FILTER1,
86 CCDC_AVERAGE_FILTER1,
87 CCDC_MEDIAN_FILTER1
88};
89
90enum ccdc_mfilt2 {
91 CCDC_NO_MEDIAN_FILTER2,
92 CCDC_AVERAGE_FILTER2,
93 CCDC_MEDIAN_FILTER2
94};
95
96/* structure for ALaw */
97struct ccdc_a_law {
98 /* Enable/disable A-Law */
99 unsigned char enable;
100 /* Gama Width Input */
101 enum ccdc_gamma_width gama_wd;
102};
103
104/* structure for Black Clamping */
105struct ccdc_black_clamp {
106 /* only if bClampEnable is TRUE */
107 unsigned char b_clamp_enable;
108 /* only if bClampEnable is TRUE */
109 enum ccdc_sample_length sample_pixel;
110 /* only if bClampEnable is TRUE */
111 enum ccdc_sample_line sample_ln;
112 /* only if bClampEnable is TRUE */
113 unsigned short start_pixel;
114 /* only if bClampEnable is FALSE */
115 unsigned short sgain;
116 unsigned short dc_sub;
117};
118
119/* structure for Black Level Compensation */
120struct ccdc_black_compensation {
121 /* Constant value to subtract from Red component */
122 unsigned char r;
123 /* Constant value to subtract from Gr component */
124 unsigned char gr;
125 /* Constant value to subtract from Blue component */
126 unsigned char b;
127 /* Constant value to subtract from Gb component */
128 unsigned char gb;
129};
130
131struct ccdc_float {
132 int integer;
133 unsigned int decimal;
134};
135
136#define CCDC_CSC_COEFF_TABLE_SIZE 16
137/* structure for color space converter */
138struct ccdc_csc {
139 unsigned char enable;
140 /*
141 * S8Q5. Use 2 decimal precision, user values range from -3.00 to 3.99.
142 * example - to use 1.03, set integer part as 1, and decimal part as 3
143 * to use -1.03, set integer part as -1 and decimal part as 3
144 */
145 struct ccdc_float coeff[CCDC_CSC_COEFF_TABLE_SIZE];
146};
147
148/* Structures for Vertical Defect Correction*/
149enum ccdc_vdf_csl {
150 CCDC_VDF_NORMAL,
151 CCDC_VDF_HORZ_INTERPOL_SAT,
152 CCDC_VDF_HORZ_INTERPOL
153};
154
155enum ccdc_vdf_cuda {
156 CCDC_VDF_WHOLE_LINE_CORRECT,
157 CCDC_VDF_UPPER_DISABLE
158};
159
160enum ccdc_dfc_mwr {
161 CCDC_DFC_MWR_WRITE_COMPLETE,
162 CCDC_DFC_WRITE_REG
163};
164
165enum ccdc_dfc_mrd {
166 CCDC_DFC_READ_COMPLETE,
167 CCDC_DFC_READ_REG
168};
169
170enum ccdc_dfc_ma_rst {
171 CCDC_DFC_INCR_ADDR,
172 CCDC_DFC_CLR_ADDR
173};
174
175enum ccdc_dfc_mclr {
176 CCDC_DFC_CLEAR_COMPLETE,
177 CCDC_DFC_CLEAR
178};
179
180struct ccdc_dft_corr_ctl {
181 enum ccdc_vdf_csl vdfcsl;
182 enum ccdc_vdf_cuda vdfcuda;
183 unsigned int vdflsft;
184};
185
186struct ccdc_dft_corr_mem_ctl {
187 enum ccdc_dfc_mwr dfcmwr;
188 enum ccdc_dfc_mrd dfcmrd;
189 enum ccdc_dfc_ma_rst dfcmarst;
190 enum ccdc_dfc_mclr dfcmclr;
191};
192
193#define CCDC_DFT_TABLE_SIZE 16
194/*
195 * Main Structure for vertical defect correction. Vertical defect
196 * correction can correct upto 16 defects if defects less than 16
197 * then pad the rest with 0
198 */
199struct ccdc_vertical_dft {
200 unsigned char ver_dft_en;
201 unsigned char gen_dft_en;
202 unsigned int saturation_ctl;
203 struct ccdc_dft_corr_ctl dft_corr_ctl;
204 struct ccdc_dft_corr_mem_ctl dft_corr_mem_ctl;
205 int table_size;
206 unsigned int dft_corr_horz[CCDC_DFT_TABLE_SIZE];
207 unsigned int dft_corr_vert[CCDC_DFT_TABLE_SIZE];
208 unsigned int dft_corr_sub1[CCDC_DFT_TABLE_SIZE];
209 unsigned int dft_corr_sub2[CCDC_DFT_TABLE_SIZE];
210 unsigned int dft_corr_sub3[CCDC_DFT_TABLE_SIZE];
211};
212
213struct ccdc_data_offset {
214 unsigned char horz_offset;
215 unsigned char vert_offset;
216};
217
218/*
219 * Structure for CCDC configuration parameters for raw capture mode passed
220 * by application
221 */
222struct ccdc_config_params_raw {
223 /* data shift to be applied before storing */
224 enum ccdc_datasft datasft;
225 /* data size value from 8 to 16 bits */
226 enum ccdc_data_size data_sz;
227 /* median filter for sdram */
228 enum ccdc_mfilt1 mfilt1;
229 enum ccdc_mfilt2 mfilt2;
230 /* low pass filter enable/disable */
231 unsigned char lpf_enable;
232 /* Threshold of median filter */
233 int med_filt_thres;
234 /*
235 * horz and vertical data offset. Appliable for defect correction
236 * and lsc
237 */
238 struct ccdc_data_offset data_offset;
239 /* Structure for Optional A-Law */
240 struct ccdc_a_law alaw;
241 /* Structure for Optical Black Clamp */
242 struct ccdc_black_clamp blk_clamp;
243 /* Structure for Black Compensation */
244 struct ccdc_black_compensation blk_comp;
245 /* struture for vertical Defect Correction Module Configuration */
246 struct ccdc_vertical_dft vertical_dft;
247 /* structure for color space converter Module Configuration */
248 struct ccdc_csc csc;
249 /* color patters for bayer capture */
250 struct ccdc_col_pat col_pat_field0;
251 struct ccdc_col_pat col_pat_field1;
252};
253
254#ifdef __KERNEL__
255#include <linux/io.h>
256
257#define CCDC_WIN_PAL {0, 0, 720, 576}
258#define CCDC_WIN_VGA {0, 0, 640, 480}
259
260struct ccdc_params_ycbcr {
261 /* pixel format */
262 enum ccdc_pixfmt pix_fmt;
263 /* progressive or interlaced frame */
264 enum ccdc_frmfmt frm_fmt;
265 /* video window */
266 struct v4l2_rect win;
267 /* field id polarity */
268 enum vpfe_pin_pol fid_pol;
269 /* vertical sync polarity */
270 enum vpfe_pin_pol vd_pol;
271 /* horizontal sync polarity */
272 enum vpfe_pin_pol hd_pol;
273 /* enable BT.656 embedded sync mode */
274 int bt656_enable;
275 /* cb:y:cr:y or y:cb:y:cr in memory */
276 enum ccdc_pixorder pix_order;
277 /* interleaved or separated fields */
278 enum ccdc_buftype buf_type;
279};
280
281/* Gain applied to Raw Bayer data */
282struct ccdc_gain {
283 unsigned short r_ye;
284 unsigned short gr_cy;
285 unsigned short gb_g;
286 unsigned short b_mg;
287};
288
289/* Structure for CCDC configuration parameters for raw capture mode */
290struct ccdc_params_raw {
291 /* pixel format */
292 enum ccdc_pixfmt pix_fmt;
293 /* progressive or interlaced frame */
294 enum ccdc_frmfmt frm_fmt;
295 /* video window */
296 struct v4l2_rect win;
297 /* field id polarity */
298 enum vpfe_pin_pol fid_pol;
299 /* vertical sync polarity */
300 enum vpfe_pin_pol vd_pol;
301 /* horizontal sync polarity */
302 enum vpfe_pin_pol hd_pol;
303 /* interleaved or separated fields */
304 enum ccdc_buftype buf_type;
305 /* Gain values */
306 struct ccdc_gain gain;
307 /* offset */
308 unsigned int ccdc_offset;
309 /* horizontal flip enable */
310 unsigned char horz_flip_enable;
311 /*
312 * enable to store the image in inverse order in memory
313 * (bottom to top)
314 */
315 unsigned char image_invert_enable;
316 /* Configurable part of raw data */
317 struct ccdc_config_params_raw config_params;
318};
319
320#endif
321#endif /* DM355_CCDC_H */
diff --git a/include/media/davinci/dm644x_ccdc.h b/include/media/davinci/dm644x_ccdc.h
new file mode 100644
index 000000000000..3e178eb52fb3
--- /dev/null
+++ b/include/media/davinci/dm644x_ccdc.h
@@ -0,0 +1,184 @@
1/*
2 * Copyright (C) 2006-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _DM644X_CCDC_H
19#define _DM644X_CCDC_H
20#include <media/davinci/ccdc_types.h>
21#include <media/davinci/vpfe_types.h>
22
23/* enum for No of pixel per line to be avg. in Black Clamping*/
24enum ccdc_sample_length {
25 CCDC_SAMPLE_1PIXELS,
26 CCDC_SAMPLE_2PIXELS,
27 CCDC_SAMPLE_4PIXELS,
28 CCDC_SAMPLE_8PIXELS,
29 CCDC_SAMPLE_16PIXELS
30};
31
32/* enum for No of lines in Black Clamping */
33enum ccdc_sample_line {
34 CCDC_SAMPLE_1LINES,
35 CCDC_SAMPLE_2LINES,
36 CCDC_SAMPLE_4LINES,
37 CCDC_SAMPLE_8LINES,
38 CCDC_SAMPLE_16LINES
39};
40
41/* enum for Alaw gama width */
42enum ccdc_gama_width {
43 CCDC_GAMMA_BITS_15_6,
44 CCDC_GAMMA_BITS_14_5,
45 CCDC_GAMMA_BITS_13_4,
46 CCDC_GAMMA_BITS_12_3,
47 CCDC_GAMMA_BITS_11_2,
48 CCDC_GAMMA_BITS_10_1,
49 CCDC_GAMMA_BITS_09_0
50};
51
52enum ccdc_data_size {
53 CCDC_DATA_16BITS,
54 CCDC_DATA_15BITS,
55 CCDC_DATA_14BITS,
56 CCDC_DATA_13BITS,
57 CCDC_DATA_12BITS,
58 CCDC_DATA_11BITS,
59 CCDC_DATA_10BITS,
60 CCDC_DATA_8BITS
61};
62
63/* structure for ALaw */
64struct ccdc_a_law {
65 /* Enable/disable A-Law */
66 unsigned char enable;
67 /* Gama Width Input */
68 enum ccdc_gama_width gama_wd;
69};
70
71/* structure for Black Clamping */
72struct ccdc_black_clamp {
73 unsigned char enable;
74 /* only if bClampEnable is TRUE */
75 enum ccdc_sample_length sample_pixel;
76 /* only if bClampEnable is TRUE */
77 enum ccdc_sample_line sample_ln;
78 /* only if bClampEnable is TRUE */
79 unsigned short start_pixel;
80 /* only if bClampEnable is TRUE */
81 unsigned short sgain;
82 /* only if bClampEnable is FALSE */
83 unsigned short dc_sub;
84};
85
86/* structure for Black Level Compensation */
87struct ccdc_black_compensation {
88 /* Constant value to subtract from Red component */
89 char r;
90 /* Constant value to subtract from Gr component */
91 char gr;
92 /* Constant value to subtract from Blue component */
93 char b;
94 /* Constant value to subtract from Gb component */
95 char gb;
96};
97
98/* structure for fault pixel correction */
99struct ccdc_fault_pixel {
100 /* Enable or Disable fault pixel correction */
101 unsigned char enable;
102 /* Number of fault pixel */
103 unsigned short fp_num;
104 /* Address of fault pixel table */
105 unsigned int fpc_table_addr;
106};
107
108/* Structure for CCDC configuration parameters for raw capture mode passed
109 * by application
110 */
111struct ccdc_config_params_raw {
112 /* data size value from 8 to 16 bits */
113 enum ccdc_data_size data_sz;
114 /* Structure for Optional A-Law */
115 struct ccdc_a_law alaw;
116 /* Structure for Optical Black Clamp */
117 struct ccdc_black_clamp blk_clamp;
118 /* Structure for Black Compensation */
119 struct ccdc_black_compensation blk_comp;
120 /* Structure for Fault Pixel Module Configuration */
121 struct ccdc_fault_pixel fault_pxl;
122};
123
124
125#ifdef __KERNEL__
126#include <linux/io.h>
127/* Define to enable/disable video port */
128#define FP_NUM_BYTES 4
129/* Define for extra pixel/line and extra lines/frame */
130#define NUM_EXTRAPIXELS 8
131#define NUM_EXTRALINES 8
132
133/* settings for commonly used video formats */
134#define CCDC_WIN_PAL {0, 0, 720, 576}
135/* ntsc square pixel */
136#define CCDC_WIN_VGA {0, 0, (640 + NUM_EXTRAPIXELS), (480 + NUM_EXTRALINES)}
137
138/* Structure for CCDC configuration parameters for raw capture mode */
139struct ccdc_params_raw {
140 /* pixel format */
141 enum ccdc_pixfmt pix_fmt;
142 /* progressive or interlaced frame */
143 enum ccdc_frmfmt frm_fmt;
144 /* video window */
145 struct v4l2_rect win;
146 /* field id polarity */
147 enum vpfe_pin_pol fid_pol;
148 /* vertical sync polarity */
149 enum vpfe_pin_pol vd_pol;
150 /* horizontal sync polarity */
151 enum vpfe_pin_pol hd_pol;
152 /* interleaved or separated fields */
153 enum ccdc_buftype buf_type;
154 /*
155 * enable to store the image in inverse
156 * order in memory(bottom to top)
157 */
158 unsigned char image_invert_enable;
159 /* configurable paramaters */
160 struct ccdc_config_params_raw config_params;
161};
162
163struct ccdc_params_ycbcr {
164 /* pixel format */
165 enum ccdc_pixfmt pix_fmt;
166 /* progressive or interlaced frame */
167 enum ccdc_frmfmt frm_fmt;
168 /* video window */
169 struct v4l2_rect win;
170 /* field id polarity */
171 enum vpfe_pin_pol fid_pol;
172 /* vertical sync polarity */
173 enum vpfe_pin_pol vd_pol;
174 /* horizontal sync polarity */
175 enum vpfe_pin_pol hd_pol;
176 /* enable BT.656 embedded sync mode */
177 int bt656_enable;
178 /* cb:y:cr:y or y:cb:y:cr in memory */
179 enum ccdc_pixorder pix_order;
180 /* interleaved or separated fields */
181 enum ccdc_buftype buf_type;
182};
183#endif
184#endif /* _DM644X_CCDC_H */
diff --git a/include/media/davinci/vpfe_capture.h b/include/media/davinci/vpfe_capture.h
new file mode 100644
index 000000000000..71d8982e13ff
--- /dev/null
+++ b/include/media/davinci/vpfe_capture.h
@@ -0,0 +1,198 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19#ifndef _VPFE_CAPTURE_H
20#define _VPFE_CAPTURE_H
21
22#ifdef __KERNEL__
23
24/* Header files */
25#include <media/v4l2-dev.h>
26#include <linux/videodev2.h>
27#include <linux/clk.h>
28#include <linux/i2c.h>
29#include <media/v4l2-ioctl.h>
30#include <media/v4l2-device.h>
31#include <media/videobuf-dma-contig.h>
32#include <media/davinci/vpfe_types.h>
33
34#define VPFE_CAPTURE_NUM_DECODERS 5
35
36/* Macros */
37#define VPFE_MAJOR_RELEASE 0
38#define VPFE_MINOR_RELEASE 0
39#define VPFE_BUILD 1
40#define VPFE_CAPTURE_VERSION_CODE ((VPFE_MAJOR_RELEASE << 16) | \
41 (VPFE_MINOR_RELEASE << 8) | \
42 VPFE_BUILD)
43
44#define CAPTURE_DRV_NAME "vpfe-capture"
45
46struct vpfe_pixel_format {
47 struct v4l2_fmtdesc fmtdesc;
48 /* bytes per pixel */
49 int bpp;
50};
51
52struct vpfe_std_info {
53 int active_pixels;
54 int active_lines;
55 /* current frame format */
56 int frame_format;
57};
58
59struct vpfe_route {
60 u32 input;
61 u32 output;
62};
63
64struct vpfe_subdev_info {
65 /* Sub device name */
66 char name[32];
67 /* Sub device group id */
68 int grp_id;
69 /* Number of inputs supported */
70 int num_inputs;
71 /* inputs available at the sub device */
72 struct v4l2_input *inputs;
73 /* Sub dev routing information for each input */
74 struct vpfe_route *routes;
75 /* check if sub dev supports routing */
76 int can_route;
77 /* ccdc bus/interface configuration */
78 struct vpfe_hw_if_param ccdc_if_params;
79 /* i2c subdevice board info */
80 struct i2c_board_info board_info;
81};
82
83struct vpfe_config {
84 /* Number of sub devices connected to vpfe */
85 int num_subdevs;
86 /* information about each subdev */
87 struct vpfe_subdev_info *sub_devs;
88 /* evm card info */
89 char *card_name;
90 /* ccdc name */
91 char *ccdc;
92 /* vpfe clock */
93 struct clk *vpssclk;
94 struct clk *slaveclk;
95};
96
97struct vpfe_device {
98 /* V4l2 specific parameters */
99 /* Identifies video device for this channel */
100 struct video_device *video_dev;
101 /* sub devices */
102 struct v4l2_subdev **sd;
103 /* vpfe cfg */
104 struct vpfe_config *cfg;
105 /* V4l2 device */
106 struct v4l2_device v4l2_dev;
107 /* parent device */
108 struct device *pdev;
109 /* Used to keep track of state of the priority */
110 struct v4l2_prio_state prio;
111 /* number of open instances of the channel */
112 u32 usrs;
113 /* Indicates id of the field which is being displayed */
114 u32 field_id;
115 /* flag to indicate whether decoder is initialized */
116 u8 initialized;
117 /* current interface type */
118 struct vpfe_hw_if_param vpfe_if_params;
119 /* ptr to currently selected sub device */
120 struct vpfe_subdev_info *current_subdev;
121 /* current input at the sub device */
122 int current_input;
123 /* Keeps track of the information about the standard */
124 struct vpfe_std_info std_info;
125 /* std index into std table */
126 int std_index;
127 /* CCDC IRQs used when CCDC/ISIF output to SDRAM */
128 unsigned int ccdc_irq0;
129 unsigned int ccdc_irq1;
130 /* number of buffers in fbuffers */
131 u32 numbuffers;
132 /* List of buffer pointers for storing frames */
133 u8 *fbuffers[VIDEO_MAX_FRAME];
134 /* Pointer pointing to current v4l2_buffer */
135 struct videobuf_buffer *cur_frm;
136 /* Pointer pointing to next v4l2_buffer */
137 struct videobuf_buffer *next_frm;
138 /*
139 * This field keeps track of type of buffer exchange mechanism
140 * user has selected
141 */
142 enum v4l2_memory memory;
143 /* Used to store pixel format */
144 struct v4l2_format fmt;
145 /*
146 * used when IMP is chained to store the crop window which
147 * is different from the image window
148 */
149 struct v4l2_rect crop;
150 /* Buffer queue used in video-buf */
151 struct videobuf_queue buffer_queue;
152 /* Queue of filled frames */
153 struct list_head dma_queue;
154 /* Used in video-buf */
155 spinlock_t irqlock;
156 /* IRQ lock for DMA queue */
157 spinlock_t dma_queue_lock;
158 /* lock used to access this structure */
159 struct mutex lock;
160 /* number of users performing IO */
161 u32 io_usrs;
162 /* Indicates whether streaming started */
163 u8 started;
164 /*
165 * offset where second field starts from the starting of the
166 * buffer for field seperated YCbCr formats
167 */
168 u32 field_off;
169};
170
171/* File handle structure */
172struct vpfe_fh {
173 struct vpfe_device *vpfe_dev;
174 /* Indicates whether this file handle is doing IO */
175 u8 io_allowed;
176 /* Used to keep track priority of this instance */
177 enum v4l2_priority prio;
178};
179
180struct vpfe_config_params {
181 u8 min_numbuffers;
182 u8 numbuffers;
183 u32 min_bufsize;
184 u32 device_bufsize;
185};
186
187#endif /* End of __KERNEL__ */
188/**
189 * VPFE_CMD_S_CCDC_RAW_PARAMS - EXPERIMENTAL IOCTL to set raw capture params
190 * This can be used to configure modules such as defect pixel correction,
191 * color space conversion, culling etc. This is an experimental ioctl that
192 * will change in future kernels. So use this ioctl with care !
193 * TODO: This is to be split into multiple ioctls and also explore the
194 * possibility of extending the v4l2 api to include this
195 **/
196#define VPFE_CMD_S_CCDC_RAW_PARAMS _IOW('V', BASE_VIDIOC_PRIVATE + 1, \
197 void *)
198#endif /* _DAVINCI_VPFE_H */
diff --git a/include/media/davinci/vpfe_types.h b/include/media/davinci/vpfe_types.h
new file mode 100644
index 000000000000..76fb74bad08c
--- /dev/null
+++ b/include/media/davinci/vpfe_types.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2008-2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option)any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18#ifndef _VPFE_TYPES_H
19#define _VPFE_TYPES_H
20
21#ifdef __KERNEL__
22
23enum vpfe_pin_pol {
24 VPFE_PINPOL_POSITIVE,
25 VPFE_PINPOL_NEGATIVE
26};
27
28enum vpfe_hw_if_type {
29 /* BT656 - 8 bit */
30 VPFE_BT656,
31 /* BT1120 - 16 bit */
32 VPFE_BT1120,
33 /* Raw Bayer */
34 VPFE_RAW_BAYER,
35 /* YCbCr - 8 bit with external sync */
36 VPFE_YCBCR_SYNC_8,
37 /* YCbCr - 16 bit with external sync */
38 VPFE_YCBCR_SYNC_16,
39 /* BT656 - 10 bit */
40 VPFE_BT656_10BIT
41};
42
43/* interface description */
44struct vpfe_hw_if_param {
45 enum vpfe_hw_if_type if_type;
46 enum vpfe_pin_pol hdpol;
47 enum vpfe_pin_pol vdpol;
48};
49
50#endif
51#endif
diff --git a/include/media/davinci/vpss.h b/include/media/davinci/vpss.h
new file mode 100644
index 000000000000..fcdff745fae2
--- /dev/null
+++ b/include/media/davinci/vpss.h
@@ -0,0 +1,69 @@
1/*
2 * Copyright (C) 2009 Texas Instruments Inc
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 *
18 * vpss - video processing subsystem module header file.
19 *
20 * Include this header file if a driver needs to configure vpss system
21 * module. It exports a set of library functions for video drivers to
22 * configure vpss system module functions such as clock enable/disable,
23 * vpss interrupt mux to arm, and other common vpss system module
24 * functions.
25 */
26#ifndef _VPSS_H
27#define _VPSS_H
28
29/* selector for ccdc input selection on DM355 */
30enum vpss_ccdc_source_sel {
31 VPSS_CCDCIN,
32 VPSS_HSSIIN
33};
34
35/* Used for enable/diable VPSS Clock */
36enum vpss_clock_sel {
37 /* DM355/DM365 */
38 VPSS_CCDC_CLOCK,
39 VPSS_IPIPE_CLOCK,
40 VPSS_H3A_CLOCK,
41 VPSS_CFALD_CLOCK,
42 /*
43 * When using VPSS_VENC_CLOCK_SEL in vpss_enable_clock() api
44 * following applies:-
45 * en = 0 selects ENC_CLK
46 * en = 1 selects ENC_CLK/2
47 */
48 VPSS_VENC_CLOCK_SEL,
49 VPSS_VPBE_CLOCK,
50};
51
52/* select input to ccdc on dm355 */
53int vpss_select_ccdc_source(enum vpss_ccdc_source_sel src_sel);
54/* enable/disable a vpss clock, 0 - success, -1 - failure */
55int vpss_enable_clock(enum vpss_clock_sel clock_sel, int en);
56
57/* wbl reset for dm644x */
58enum vpss_wbl_sel {
59 VPSS_PCR_AEW_WBL_0 = 16,
60 VPSS_PCR_AF_WBL_0,
61 VPSS_PCR_RSZ4_WBL_0,
62 VPSS_PCR_RSZ3_WBL_0,
63 VPSS_PCR_RSZ2_WBL_0,
64 VPSS_PCR_RSZ1_WBL_0,
65 VPSS_PCR_PREV_WBL_0,
66 VPSS_PCR_CCDC_WBL_O,
67};
68int vpss_clear_wbl_overflow(enum vpss_wbl_sel wbl_sel);
69#endif
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 23ecead35e7a..3d74e60032dd 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -16,24 +16,17 @@
16#include <linux/pm.h> 16#include <linux/pm.h>
17#include <linux/videodev2.h> 17#include <linux/videodev2.h>
18#include <media/videobuf-core.h> 18#include <media/videobuf-core.h>
19#include <media/v4l2-device.h>
19 20
20struct soc_camera_device { 21struct soc_camera_device {
21 struct list_head list; 22 struct list_head list;
22 struct device dev; 23 struct device dev;
23 struct device *control; 24 struct device *pdev; /* Platform device */
24 unsigned short width; /* Current window */ 25 s32 user_width;
25 unsigned short height; /* sizes */ 26 s32 user_height;
26 unsigned short x_min; /* Camera capabilities */
27 unsigned short y_min;
28 unsigned short x_current; /* Current window location */
29 unsigned short y_current;
30 unsigned short width_min; 27 unsigned short width_min;
31 unsigned short width_max;
32 unsigned short height_min; 28 unsigned short height_min;
33 unsigned short height_max;
34 unsigned short y_skip_top; /* Lines to skip at the top */ 29 unsigned short y_skip_top; /* Lines to skip at the top */
35 unsigned short gain;
36 unsigned short exposure;
37 unsigned char iface; /* Host number */ 30 unsigned char iface; /* Host number */
38 unsigned char devnum; /* Device number per host */ 31 unsigned char devnum; /* Device number per host */
39 unsigned char buswidth; /* See comment in .c */ 32 unsigned char buswidth; /* See comment in .c */
@@ -46,7 +39,6 @@ struct soc_camera_device {
46 struct soc_camera_format_xlate *user_formats; 39 struct soc_camera_format_xlate *user_formats;
47 int num_user_formats; 40 int num_user_formats;
48 enum v4l2_field field; /* Preserve field over close() */ 41 enum v4l2_field field; /* Preserve field over close() */
49 struct module *owner;
50 void *host_priv; /* Per-device host private data */ 42 void *host_priv; /* Per-device host private data */
51 /* soc_camera.c private count. Only accessed with .video_lock held */ 43 /* soc_camera.c private count. Only accessed with .video_lock held */
52 int use_count; 44 int use_count;
@@ -59,8 +51,8 @@ struct soc_camera_file {
59}; 51};
60 52
61struct soc_camera_host { 53struct soc_camera_host {
54 struct v4l2_device v4l2_dev;
62 struct list_head list; 55 struct list_head list;
63 struct device *dev;
64 unsigned char nr; /* Host number */ 56 unsigned char nr; /* Host number */
65 void *priv; 57 void *priv;
66 const char *drv_name; 58 const char *drv_name;
@@ -73,9 +65,18 @@ struct soc_camera_host_ops {
73 void (*remove)(struct soc_camera_device *); 65 void (*remove)(struct soc_camera_device *);
74 int (*suspend)(struct soc_camera_device *, pm_message_t); 66 int (*suspend)(struct soc_camera_device *, pm_message_t);
75 int (*resume)(struct soc_camera_device *); 67 int (*resume)(struct soc_camera_device *);
68 /*
69 * .get_formats() is called for each client device format, but
70 * .put_formats() is only called once. Further, if any of the calls to
71 * .get_formats() fail, .put_formats() will not be called at all, the
72 * failing .get_formats() must then clean up internally.
73 */
76 int (*get_formats)(struct soc_camera_device *, int, 74 int (*get_formats)(struct soc_camera_device *, int,
77 struct soc_camera_format_xlate *); 75 struct soc_camera_format_xlate *);
78 int (*set_crop)(struct soc_camera_device *, struct v4l2_rect *); 76 void (*put_formats)(struct soc_camera_device *);
77 int (*cropcap)(struct soc_camera_device *, struct v4l2_cropcap *);
78 int (*get_crop)(struct soc_camera_device *, struct v4l2_crop *);
79 int (*set_crop)(struct soc_camera_device *, struct v4l2_crop *);
79 int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *); 80 int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
80 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); 81 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
81 void (*init_videobuf)(struct videobuf_queue *, 82 void (*init_videobuf)(struct videobuf_queue *,
@@ -83,7 +84,11 @@ struct soc_camera_host_ops {
83 int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *); 84 int (*reqbufs)(struct soc_camera_file *, struct v4l2_requestbuffers *);
84 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 85 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
85 int (*set_bus_param)(struct soc_camera_device *, __u32); 86 int (*set_bus_param)(struct soc_camera_device *, __u32);
87 int (*get_ctrl)(struct soc_camera_device *, struct v4l2_control *);
88 int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
86 unsigned int (*poll)(struct file *, poll_table *); 89 unsigned int (*poll)(struct file *, poll_table *);
90 const struct v4l2_queryctrl *controls;
91 int num_controls;
87}; 92};
88 93
89#define SOCAM_SENSOR_INVERT_PCLK (1 << 0) 94#define SOCAM_SENSOR_INVERT_PCLK (1 << 0)
@@ -102,6 +107,12 @@ struct soc_camera_link {
102 int i2c_adapter_id; 107 int i2c_adapter_id;
103 struct i2c_board_info *board_info; 108 struct i2c_board_info *board_info;
104 const char *module_name; 109 const char *module_name;
110 /*
111 * For non-I2C devices platform platform has to provide methods to
112 * add a device to the system and to remove
113 */
114 int (*add_device)(struct soc_camera_link *, struct device *);
115 void (*del_device)(struct soc_camera_link *);
105 /* Optional callbacks to power on or off and reset the sensor */ 116 /* Optional callbacks to power on or off and reset the sensor */
106 int (*power)(struct device *, int); 117 int (*power)(struct device *, int);
107 int (*reset)(struct device *); 118 int (*reset)(struct device *);
@@ -115,27 +126,45 @@ struct soc_camera_link {
115 void (*free_bus)(struct soc_camera_link *); 126 void (*free_bus)(struct soc_camera_link *);
116}; 127};
117 128
118static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) 129static inline struct soc_camera_device *to_soc_camera_dev(
130 const struct device *dev)
119{ 131{
120 return container_of(dev, struct soc_camera_device, dev); 132 return container_of(dev, struct soc_camera_device, dev);
121} 133}
122 134
123static inline struct soc_camera_host *to_soc_camera_host(struct device *dev) 135static inline struct soc_camera_host *to_soc_camera_host(
136 const struct device *dev)
124{ 137{
125 return dev_get_drvdata(dev); 138 struct v4l2_device *v4l2_dev = dev_get_drvdata(dev);
139
140 return container_of(v4l2_dev, struct soc_camera_host, v4l2_dev);
126} 141}
127 142
128extern int soc_camera_host_register(struct soc_camera_host *ici); 143static inline struct soc_camera_link *to_soc_camera_link(
129extern void soc_camera_host_unregister(struct soc_camera_host *ici); 144 const struct soc_camera_device *icd)
130extern int soc_camera_device_register(struct soc_camera_device *icd); 145{
131extern void soc_camera_device_unregister(struct soc_camera_device *icd); 146 return icd->dev.platform_data;
147}
132 148
133extern int soc_camera_video_start(struct soc_camera_device *icd); 149static inline struct device *to_soc_camera_control(
134extern void soc_camera_video_stop(struct soc_camera_device *icd); 150 const struct soc_camera_device *icd)
151{
152 return dev_get_drvdata(&icd->dev);
153}
135 154
136extern const struct soc_camera_data_format *soc_camera_format_by_fourcc( 155static inline struct v4l2_subdev *soc_camera_to_subdev(
156 const struct soc_camera_device *icd)
157{
158 struct device *control = to_soc_camera_control(icd);
159 return dev_get_drvdata(control);
160}
161
162int soc_camera_host_register(struct soc_camera_host *ici);
163void soc_camera_host_unregister(struct soc_camera_host *ici);
164
165const struct soc_camera_data_format *soc_camera_format_by_fourcc(
137 struct soc_camera_device *icd, unsigned int fourcc); 166 struct soc_camera_device *icd, unsigned int fourcc);
138extern const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 167const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
139 struct soc_camera_device *icd, unsigned int fourcc); 168 struct soc_camera_device *icd, unsigned int fourcc);
140 169
141struct soc_camera_data_format { 170struct soc_camera_data_format {
@@ -163,30 +192,11 @@ struct soc_camera_format_xlate {
163}; 192};
164 193
165struct soc_camera_ops { 194struct soc_camera_ops {
166 struct module *owner;
167 int (*probe)(struct soc_camera_device *);
168 void (*remove)(struct soc_camera_device *);
169 int (*suspend)(struct soc_camera_device *, pm_message_t state); 195 int (*suspend)(struct soc_camera_device *, pm_message_t state);
170 int (*resume)(struct soc_camera_device *); 196 int (*resume)(struct soc_camera_device *);
171 int (*init)(struct soc_camera_device *);
172 int (*release)(struct soc_camera_device *);
173 int (*start_capture)(struct soc_camera_device *);
174 int (*stop_capture)(struct soc_camera_device *);
175 int (*set_crop)(struct soc_camera_device *, struct v4l2_rect *);
176 int (*set_fmt)(struct soc_camera_device *, struct v4l2_format *);
177 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
178 unsigned long (*query_bus_param)(struct soc_camera_device *); 197 unsigned long (*query_bus_param)(struct soc_camera_device *);
179 int (*set_bus_param)(struct soc_camera_device *, unsigned long); 198 int (*set_bus_param)(struct soc_camera_device *, unsigned long);
180 int (*get_chip_id)(struct soc_camera_device *,
181 struct v4l2_dbg_chip_ident *);
182 int (*set_std)(struct soc_camera_device *, v4l2_std_id *);
183 int (*enum_input)(struct soc_camera_device *, struct v4l2_input *); 199 int (*enum_input)(struct soc_camera_device *, struct v4l2_input *);
184#ifdef CONFIG_VIDEO_ADV_DEBUG
185 int (*get_register)(struct soc_camera_device *, struct v4l2_dbg_register *);
186 int (*set_register)(struct soc_camera_device *, struct v4l2_dbg_register *);
187#endif
188 int (*get_control)(struct soc_camera_device *, struct v4l2_control *);
189 int (*set_control)(struct soc_camera_device *, struct v4l2_control *);
190 const struct v4l2_queryctrl *controls; 200 const struct v4l2_queryctrl *controls;
191 int num_controls; 201 int num_controls;
192}; 202};
@@ -268,6 +278,21 @@ static inline unsigned long soc_camera_bus_param_compatible(
268 common_flags; 278 common_flags;
269} 279}
270 280
281static inline void soc_camera_limit_side(unsigned int *start,
282 unsigned int *length, unsigned int start_min,
283 unsigned int length_min, unsigned int length_max)
284{
285 if (*length < length_min)
286 *length = length_min;
287 else if (*length > length_max)
288 *length = length_max;
289
290 if (*start < start_min)
291 *start = start_min;
292 else if (*start > start_min + length_max - *length)
293 *start = start_min + length_max - *length;
294}
295
271extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, 296extern unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl,
272 unsigned long flags); 297 unsigned long flags);
273 298
diff --git a/include/media/soc_camera_platform.h b/include/media/soc_camera_platform.h
index 1d092b4678aa..bb70401b8141 100644
--- a/include/media/soc_camera_platform.h
+++ b/include/media/soc_camera_platform.h
@@ -12,15 +12,18 @@
12#define __SOC_CAMERA_H__ 12#define __SOC_CAMERA_H__
13 13
14#include <linux/videodev2.h> 14#include <linux/videodev2.h>
15#include <media/soc_camera.h>
16
17struct device;
15 18
16struct soc_camera_platform_info { 19struct soc_camera_platform_info {
17 int iface; 20 const char *format_name;
18 char *format_name;
19 unsigned long format_depth; 21 unsigned long format_depth;
20 struct v4l2_pix_format format; 22 struct v4l2_pix_format format;
21 unsigned long bus_param; 23 unsigned long bus_param;
22 void (*power)(int); 24 struct device *dev;
23 int (*set_capture)(struct soc_camera_platform_info *info, int enable); 25 int (*set_capture)(struct soc_camera_platform_info *info, int enable);
26 struct soc_camera_link link;
24}; 27};
25 28
26#endif /* __SOC_CAMERA_H__ */ 29#endif /* __SOC_CAMERA_H__ */
diff --git a/include/media/tuner.h b/include/media/tuner.h
index c146f2f530b0..4d5b53ff17db 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -127,6 +127,8 @@
127#define TUNER_PHILIPS_FM1216MK5 79 127#define TUNER_PHILIPS_FM1216MK5 79
128#define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */ 128#define TUNER_PHILIPS_FQ1216LME_MK3 80 /* Active loopthrough, no FM */
129#define TUNER_PARTSNIC_PTI_5NF05 81 129#define TUNER_PARTSNIC_PTI_5NF05 81
130#define TUNER_PHILIPS_CU1216L 82
131#define TUNER_NXP_TDA18271 83
130 132
131/* tv card specific */ 133/* tv card specific */
132#define TDA9887_PRESENT (1<<0) 134#define TDA9887_PRESENT (1<<0)
diff --git a/include/media/tvp514x.h b/include/media/tvp514x.h
index 5e7ee968c6dc..74387e83f5b9 100644
--- a/include/media/tvp514x.h
+++ b/include/media/tvp514x.h
@@ -104,10 +104,6 @@ enum tvp514x_output {
104 * @ vs_polarity: VSYNC Polarity configuration for current interface. 104 * @ vs_polarity: VSYNC Polarity configuration for current interface.
105 */ 105 */
106struct tvp514x_platform_data { 106struct tvp514x_platform_data {
107 char *master;
108 int (*power_set) (enum v4l2_power on);
109 int (*ifparm) (struct v4l2_ifparm *p);
110 int (*priv_data_set) (void *);
111 /* Interface control params */ 107 /* Interface control params */
112 bool clk_polarity; 108 bool clk_polarity;
113 bool hs_polarity; 109 bool hs_polarity;
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 94e908c0d7a0..cf16689adba7 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -135,6 +135,9 @@ enum {
135 /* module adv7175: just ident 7175 */ 135 /* module adv7175: just ident 7175 */
136 V4L2_IDENT_ADV7175 = 7175, 136 V4L2_IDENT_ADV7175 = 7175,
137 137
138 /* module adv7180: just ident 7180 */
139 V4L2_IDENT_ADV7180 = 7180,
140
138 /* module saa7185: just ident 7185 */ 141 /* module saa7185: just ident 7185 */
139 V4L2_IDENT_SAA7185 = 7185, 142 V4L2_IDENT_SAA7185 = 7185,
140 143
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index 33a18426ab9b..1c25b10da34b 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -139,29 +139,23 @@ struct v4l2_subdev_ops;
139/* Load an i2c module and return an initialized v4l2_subdev struct. 139/* Load an i2c module and return an initialized v4l2_subdev struct.
140 Only call request_module if module_name != NULL. 140 Only call request_module if module_name != NULL.
141 The client_type argument is the name of the chip that's on the adapter. */ 141 The client_type argument is the name of the chip that's on the adapter. */
142struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev, 142struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev,
143 struct i2c_adapter *adapter,
144 const char *module_name, const char *client_type, u8 addr);
145/* Probe and load an i2c module and return an initialized v4l2_subdev struct.
146 Only call request_module if module_name != NULL.
147 The client_type argument is the name of the chip that's on the adapter. */
148struct v4l2_subdev *v4l2_i2c_new_probed_subdev(struct v4l2_device *v4l2_dev,
149 struct i2c_adapter *adapter, 143 struct i2c_adapter *adapter,
150 const char *module_name, const char *client_type, 144 const char *module_name, const char *client_type,
151 const unsigned short *addrs); 145 int irq, void *platform_data,
152/* Like v4l2_i2c_new_probed_subdev, except probe for a single address. */ 146 u8 addr, const unsigned short *probe_addrs);
153struct v4l2_subdev *v4l2_i2c_new_probed_subdev_addr(struct v4l2_device *v4l2_dev,
154 struct i2c_adapter *adapter,
155 const char *module_name, const char *client_type, u8 addr);
156 147
157/* Load an i2c module and return an initialized v4l2_subdev struct. 148/* Load an i2c module and return an initialized v4l2_subdev struct.
158 Only call request_module if module_name != NULL. 149 Only call request_module if module_name != NULL.
159 The client_type argument is the name of the chip that's on the adapter. */ 150 The client_type argument is the name of the chip that's on the adapter. */
160struct v4l2_subdev *v4l2_i2c_new_subdev_cfg(struct v4l2_device *v4l2_dev, 151static inline struct v4l2_subdev *v4l2_i2c_new_subdev(struct v4l2_device *v4l2_dev,
161 struct i2c_adapter *adapter, 152 struct i2c_adapter *adapter,
162 const char *module_name, const char *client_type, 153 const char *module_name, const char *client_type,
163 int irq, void *platform_data, 154 u8 addr, const unsigned short *probe_addrs)
164 u8 addr, const unsigned short *probe_addrs); 155{
156 return v4l2_i2c_new_subdev_cfg(v4l2_dev, adapter, module_name,
157 client_type, 0, NULL, addr, probe_addrs);
158}
165 159
166struct i2c_board_info; 160struct i2c_board_info;
167 161
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 2058dd45e915..73c9867d744c 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -100,8 +100,10 @@ struct video_device
100 100
101 Also note that vdev->minor is set to -1 if the registration failed. */ 101 Also note that vdev->minor is set to -1 if the registration failed. */
102int __must_check video_register_device(struct video_device *vdev, int type, int nr); 102int __must_check video_register_device(struct video_device *vdev, int type, int nr);
103int __must_check video_register_device_index(struct video_device *vdev, 103
104 int type, int nr, int index); 104/* Same as video_register_device, but no warning is issued if the desired
105 device node number was already in use. */
106int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr);
105 107
106/* Unregister video devices. Will do nothing if vdev == NULL or 108/* Unregister video devices. Will do nothing if vdev == NULL or
107 vdev->minor < 0. */ 109 vdev->minor < 0. */