aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-bus-media6
-rw-r--r--Documentation/DocBook/Makefile5
-rw-r--r--Documentation/DocBook/media-entities.tmpl59
-rw-r--r--Documentation/DocBook/media.tmpl3
-rw-r--r--Documentation/DocBook/v4l/bayer.pdfbin0 -> 12116 bytes
-rw-r--r--Documentation/DocBook/v4l/bayer.pngbin0 -> 9725 bytes
-rw-r--r--Documentation/DocBook/v4l/common.xml2
-rw-r--r--Documentation/DocBook/v4l/compat.xml26
-rw-r--r--Documentation/DocBook/v4l/dev-capture.xml13
-rw-r--r--Documentation/DocBook/v4l/dev-output.xml13
-rw-r--r--Documentation/DocBook/v4l/dev-subdev.xml313
-rw-r--r--Documentation/DocBook/v4l/func-mmap.xml10
-rw-r--r--Documentation/DocBook/v4l/func-munmap.xml3
-rw-r--r--Documentation/DocBook/v4l/io.xml283
-rw-r--r--Documentation/DocBook/v4l/lirc_device_interface.xml2
-rw-r--r--Documentation/DocBook/v4l/media-controller.xml89
-rw-r--r--Documentation/DocBook/v4l/media-func-close.xml59
-rw-r--r--Documentation/DocBook/v4l/media-func-ioctl.xml116
-rw-r--r--Documentation/DocBook/v4l/media-func-open.xml94
-rw-r--r--Documentation/DocBook/v4l/media-ioc-device-info.xml133
-rw-r--r--Documentation/DocBook/v4l/media-ioc-enum-entities.xml308
-rw-r--r--Documentation/DocBook/v4l/media-ioc-enum-links.xml207
-rw-r--r--Documentation/DocBook/v4l/media-ioc-setup-link.xml93
-rw-r--r--Documentation/DocBook/v4l/nv12mt.gifbin0 -> 2108 bytes
-rw-r--r--Documentation/DocBook/v4l/nv12mt_example.gifbin0 -> 6858 bytes
-rw-r--r--Documentation/DocBook/v4l/pipeline.pdfbin0 -> 20276 bytes
-rw-r--r--Documentation/DocBook/v4l/pipeline.pngbin0 -> 12130 bytes
-rw-r--r--Documentation/DocBook/v4l/pixfmt-nv12m.xml154
-rw-r--r--Documentation/DocBook/v4l/pixfmt-nv12mt.xml74
-rw-r--r--Documentation/DocBook/v4l/pixfmt-srggb12.xml90
-rw-r--r--Documentation/DocBook/v4l/pixfmt-yuv420m.xml162
-rw-r--r--Documentation/DocBook/v4l/pixfmt.xml119
-rw-r--r--Documentation/DocBook/v4l/planar-apis.xml62
-rw-r--r--Documentation/DocBook/v4l/subdev-formats.xml2467
-rw-r--r--Documentation/DocBook/v4l/v4l2.xml30
-rw-r--r--Documentation/DocBook/v4l/videodev2.h.xml141
-rw-r--r--Documentation/DocBook/v4l/vidioc-enum-fmt.xml2
-rw-r--r--Documentation/DocBook/v4l/vidioc-g-fmt.xml15
-rw-r--r--Documentation/DocBook/v4l/vidioc-qbuf.xml24
-rw-r--r--Documentation/DocBook/v4l/vidioc-querybuf.xml14
-rw-r--r--Documentation/DocBook/v4l/vidioc-querycap.xml18
-rw-r--r--Documentation/DocBook/v4l/vidioc-streamon.xml9
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml152
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml154
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml119
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml155
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml180
-rw-r--r--Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml141
-rw-r--r--Documentation/dvb/get_dvb_firmware8
-rw-r--r--Documentation/dvb/lmedm04.txt16
-rw-r--r--Documentation/feature-removal-schedule.txt36
-rw-r--r--Documentation/ioctl/ioctl-number.txt1
-rw-r--r--Documentation/media-framework.txt353
-rw-r--r--Documentation/video4linux/README.ivtv3
-rw-r--r--Documentation/video4linux/gspca.txt10
-rw-r--r--Documentation/video4linux/omap3isp.txt278
-rw-r--r--Documentation/video4linux/v4l2-framework.txt267
-rw-r--r--MAINTAINERS6
-rw-r--r--arch/arm/mach-omap2/devices.c62
-rw-r--r--arch/arm/mach-omap2/devices.h19
-rw-r--r--arch/arm/plat-omap/include/plat/omap34xx.h16
-rw-r--r--drivers/media/Kconfig22
-rw-r--r--drivers/media/Makefile6
-rw-r--r--drivers/media/common/tuners/tda9887.c9
-rw-r--r--drivers/media/common/tuners/tea5761.c33
-rw-r--r--drivers/media/common/tuners/tuner-types.c21
-rw-r--r--drivers/media/common/tuners/tuner-xc2028.c16
-rw-r--r--drivers/media/common/tuners/xc5000.c56
-rw-r--r--drivers/media/common/tuners/xc5000.h1
-rw-r--r--drivers/media/dvb/Kconfig2
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.h1
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig8
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/a800.c8
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.c67
-rw-r--r--drivers/media/dvb/dvb-usb/af9015.h1
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_core.c47
-rw-r--r--drivers/media/dvb/dvb-usb/dib0700_devices.c1381
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h7
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-remote.c2
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--drivers/media/dvb/dvb-usb/dw2102.c590
-rw-r--r--drivers/media/dvb/dvb-usb/lmedm04.c235
-rw-r--r--drivers/media/dvb/dvb-usb/opera1.c33
-rw-r--r--drivers/media/dvb/dvb-usb/technisat-usb2.c807
-rw-r--r--drivers/media/dvb/firewire/Kconfig8
-rw-r--r--drivers/media/dvb/firewire/Makefile5
-rw-r--r--drivers/media/dvb/firewire/firedtv-1394.c300
-rw-r--r--drivers/media/dvb/firewire/firedtv-avc.c15
-rw-r--r--drivers/media/dvb/firewire/firedtv-dvb.c135
-rw-r--r--drivers/media/dvb/firewire/firedtv-fe.c8
-rw-r--r--drivers/media/dvb/firewire/firedtv-fw.c146
-rw-r--r--drivers/media/dvb/firewire/firedtv.h45
-rw-r--r--drivers/media/dvb/frontends/Kconfig15
-rw-r--r--drivers/media/dvb/frontends/Makefile2
-rw-r--r--drivers/media/dvb/frontends/af9013.c55
-rw-r--r--drivers/media/dvb/frontends/dib0090.c1583
-rw-r--r--drivers/media/dvb/frontends/dib0090.h31
-rw-r--r--drivers/media/dvb/frontends/dib7000p.c1945
-rw-r--r--drivers/media/dvb/frontends/dib7000p.h96
-rw-r--r--drivers/media/dvb/frontends/dib8000.c821
-rw-r--r--drivers/media/dvb/frontends/dib8000.h20
-rw-r--r--drivers/media/dvb/frontends/dib9000.c2351
-rw-r--r--drivers/media/dvb/frontends/dib9000.h131
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c279
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h152
-rw-r--r--drivers/media/dvb/frontends/ds3000.c645
-rw-r--r--drivers/media/dvb/frontends/ds3000.h3
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c79
-rw-r--r--drivers/media/dvb/frontends/stv0288.c7
-rw-r--r--drivers/media/dvb/frontends/stv0367.c3459
-rw-r--r--drivers/media/dvb/frontends/stv0367.h66
-rw-r--r--drivers/media/dvb/frontends/stv0367_priv.h212
-rw-r--r--drivers/media/dvb/frontends/stv0367_regs.h3614
-rw-r--r--drivers/media/dvb/frontends/stv0900.h2
-rw-r--r--drivers/media/dvb/frontends/stv0900_core.c27
-rw-r--r--drivers/media/dvb/frontends/stv090x.c295
-rw-r--r--drivers/media/dvb/frontends/stv090x.h16
-rw-r--r--drivers/media/dvb/frontends/stv090x_reg.h16
-rw-r--r--drivers/media/dvb/frontends/zl10036.c10
-rw-r--r--drivers/media/dvb/ngene/Makefile3
-rw-r--r--drivers/media/dvb/ngene/ngene-cards.c179
-rw-r--r--drivers/media/dvb/ngene/ngene-core.c236
-rw-r--r--drivers/media/dvb/ngene/ngene-dvb.c71
-rw-r--r--drivers/media/dvb/ngene/ngene.h24
-rw-r--r--drivers/media/dvb/siano/sms-cards.c2
-rw-r--r--drivers/media/dvb/ttpci/budget-ci.c15
-rw-r--r--drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c1
-rw-r--r--drivers/media/media-device.c382
-rw-r--r--drivers/media/media-devnode.c320
-rw-r--r--drivers/media/media-entity.c536
-rw-r--r--drivers/media/radio/Kconfig4
-rw-r--r--drivers/media/radio/Makefile1
-rw-r--r--drivers/media/radio/dsbr100.c128
-rw-r--r--drivers/media/radio/radio-si4713.c3
-rw-r--r--drivers/media/radio/radio-wl1273.c365
-rw-r--r--drivers/media/radio/si470x/radio-si470x-common.c1
-rw-r--r--drivers/media/radio/wl128x/Kconfig17
-rw-r--r--drivers/media/radio/wl128x/Makefile6
-rw-r--r--drivers/media/radio/wl128x/fmdrv.h244
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.c1677
-rw-r--r--drivers/media/radio/wl128x/fmdrv_common.h402
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.c847
-rw-r--r--drivers/media/radio/wl128x/fmdrv_rx.h59
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.c425
-rw-r--r--drivers/media/radio/wl128x/fmdrv_tx.h37
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.c580
-rw-r--r--drivers/media/radio/wl128x/fmdrv_v4l2.h33
-rw-r--r--drivers/media/rc/Kconfig35
-rw-r--r--drivers/media/rc/Makefile1
-rw-r--r--drivers/media/rc/imon.c11
-rw-r--r--drivers/media/rc/ir-nec-decoder.c10
-rw-r--r--drivers/media/rc/ite-cir.c1736
-rw-r--r--drivers/media/rc/ite-cir.h481
-rw-r--r--drivers/media/rc/keymaps/Makefile6
-rw-r--r--drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c6
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-dvbt.c4
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m135a.c2
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c2
-rw-r--r--drivers/media/rc/keymaps/rc-avermedia-rm-ks.c2
-rw-r--r--drivers/media/rc/keymaps/rc-behold-columbus.c2
-rw-r--r--drivers/media/rc/keymaps/rc-behold.c2
-rw-r--r--drivers/media/rc/keymaps/rc-budget-ci-old.c3
-rw-r--r--drivers/media/rc/keymaps/rc-cinergy.c2
-rw-r--r--drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c2
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv.c4
-rw-r--r--drivers/media/rc/keymaps/rc-encore-enltv2.c2
-rw-r--r--drivers/media/rc/keymaps/rc-flydvb.c4
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge-new.c100
-rw-r--r--drivers/media/rc/keymaps/rc-hauppauge.c (renamed from drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c)190
-rw-r--r--drivers/media/rc/keymaps/rc-imon-mce.c2
-rw-r--r--drivers/media/rc/keymaps/rc-imon-pad.c2
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-315u.c2
-rw-r--r--drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c2
-rw-r--r--drivers/media/rc/keymaps/rc-lme2510.c96
-rw-r--r--drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c2
-rw-r--r--drivers/media/rc/keymaps/rc-nebula.c2
-rw-r--r--drivers/media/rc/keymaps/rc-norwood.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pctv-sedna.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-mk12.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview-new.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pixelview.c2
-rw-r--r--drivers/media/rc/keymaps/rc-pv951.c4
-rw-r--r--drivers/media/rc/keymaps/rc-rc5-tv.c81
-rw-r--r--drivers/media/rc/keymaps/rc-rc6-mce.c2
-rw-r--r--drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c2
-rw-r--r--drivers/media/rc/keymaps/rc-technisat-usb2.c93
-rw-r--r--drivers/media/rc/keymaps/rc-terratec-slim-2.c72
-rw-r--r--drivers/media/rc/keymaps/rc-winfast.c22
-rw-r--r--drivers/media/rc/mceusb.c4
-rw-r--r--drivers/media/video/Kconfig58
-rw-r--r--drivers/media/video/Makefile12
-rw-r--r--drivers/media/video/adv7343.c167
-rw-r--r--drivers/media/video/adv7343_regs.h8
-rw-r--r--drivers/media/video/au0828/au0828-cards.c3
-rw-r--r--drivers/media/video/au0828/au0828-dvb.c3
-rw-r--r--drivers/media/video/au0828/au0828-video.c4
-rw-r--r--drivers/media/video/bt819.c129
-rw-r--r--drivers/media/video/bt8xx/bttv-cards.c2
-rw-r--r--drivers/media/video/bt8xx/bttv-input.c2
-rw-r--r--drivers/media/video/cpia2/cpia2_core.c34
-rw-r--r--drivers/media/video/cpia2/cpia2_v4l.c374
-rw-r--r--drivers/media/video/cs5345.c87
-rw-r--r--drivers/media/video/cx18/cx18-av-audio.c92
-rw-r--r--drivers/media/video/cx18/cx18-av-core.c175
-rw-r--r--drivers/media/video/cx18/cx18-av-core.h12
-rw-r--r--drivers/media/video/cx18/cx18-controls.c285
-rw-r--r--drivers/media/video/cx18/cx18-controls.h7
-rw-r--r--drivers/media/video/cx18/cx18-driver.c31
-rw-r--r--drivers/media/video/cx18/cx18-driver.h16
-rw-r--r--drivers/media/video/cx18/cx18-fileops.c52
-rw-r--r--drivers/media/video/cx18/cx18-i2c.c2
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c152
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.c5
-rw-r--r--drivers/media/video/cx18/cx18-mailbox.h5
-rw-r--r--drivers/media/video/cx18/cx18-streams.c17
-rw-r--r--drivers/media/video/cx18/cx23418.h2
-rw-r--r--drivers/media/video/cx231xx/cx231xx-417.c4
-rw-r--r--drivers/media/video/cx231xx/cx231xx-avcore.c14
-rw-r--r--drivers/media/video/cx231xx/cx231xx-cards.c246
-rw-r--r--drivers/media/video/cx231xx/cx231xx-core.c16
-rw-r--r--drivers/media/video/cx231xx/cx231xx-i2c.c31
-rw-r--r--drivers/media/video/cx231xx/cx231xx-video.c20
-rw-r--r--drivers/media/video/cx231xx/cx231xx.h7
-rw-r--r--drivers/media/video/cx23885/Kconfig12
-rw-r--r--drivers/media/video/cx23885/Makefile1
-rw-r--r--drivers/media/video/cx23885/altera-ci.c838
-rw-r--r--drivers/media/video/cx23885/altera-ci.h100
-rw-r--r--drivers/media/video/cx23885/cx23885-cards.c110
-rw-r--r--drivers/media/video/cx23885/cx23885-core.c37
-rw-r--r--drivers/media/video/cx23885/cx23885-dvb.c175
-rw-r--r--drivers/media/video/cx23885/cx23885-input.c2
-rw-r--r--drivers/media/video/cx23885/cx23885-reg.h1
-rw-r--r--drivers/media/video/cx23885/cx23885-video.c7
-rw-r--r--drivers/media/video/cx23885/cx23885.h7
-rw-r--r--drivers/media/video/cx88/cx88-alsa.c118
-rw-r--r--drivers/media/video/cx88/cx88-cards.c24
-rw-r--r--drivers/media/video/cx88/cx88-dvb.c23
-rw-r--r--drivers/media/video/cx88/cx88-input.c5
-rw-r--r--drivers/media/video/cx88/cx88-tvaudio.c8
-rw-r--r--drivers/media/video/cx88/cx88-video.c78
-rw-r--r--drivers/media/video/cx88/cx88.h14
-rw-r--r--drivers/media/video/davinci/vpfe_capture.c2
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c10
-rw-r--r--drivers/media/video/em28xx/em28xx-video.c33
-rw-r--r--drivers/media/video/gspca/Kconfig19
-rw-r--r--drivers/media/video/gspca/Makefile4
-rw-r--r--drivers/media/video/gspca/autogain_functions.h179
-rw-r--r--drivers/media/video/gspca/cpia1.c37
-rw-r--r--drivers/media/video/gspca/gspca.c16
-rw-r--r--drivers/media/video/gspca/jeilinj.c2
-rw-r--r--drivers/media/video/gspca/nw80x.c2145
-rw-r--r--drivers/media/video/gspca/ov519.c208
-rw-r--r--drivers/media/video/gspca/ov534.c980
-rw-r--r--drivers/media/video/gspca/sn9c20x.c40
-rw-r--r--drivers/media/video/gspca/sonixb.c306
-rw-r--r--drivers/media/video/gspca/sonixj.c353
-rw-r--r--drivers/media/video/gspca/stv06xx/stv06xx.c2
-rw-r--r--drivers/media/video/gspca/vicam.c381
-rw-r--r--drivers/media/video/gspca/zc3xx-reg.h2
-rw-r--r--drivers/media/video/gspca/zc3xx.c128
-rw-r--r--drivers/media/video/hdpvr/hdpvr-i2c.c72
-rw-r--r--drivers/media/video/ir-kbd-i2c.c18
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.h2
-rw-r--r--drivers/media/video/ivtv/ivtv-fileops.c3
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c5
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c159
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c1
-rw-r--r--drivers/media/video/ivtv/ivtv-udma.c7
-rw-r--r--drivers/media/video/ivtv/ivtv-vbi.c2
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c52
-rw-r--r--drivers/media/video/mem2mem_testdev.c231
-rw-r--r--drivers/media/video/meye.c3
-rw-r--r--drivers/media/video/mt9m001.c2
-rw-r--r--drivers/media/video/mt9v022.c4
-rw-r--r--drivers/media/video/mx3_camera.c415
-rw-r--r--drivers/media/video/mxb.c3
-rw-r--r--drivers/media/video/noon010pc30.c792
-rw-r--r--drivers/media/video/omap1_camera.c66
-rw-r--r--drivers/media/video/omap24xxcam.c1
-rw-r--r--drivers/media/video/omap3isp/Makefile13
-rw-r--r--drivers/media/video/omap3isp/cfa_coef_table.h61
-rw-r--r--drivers/media/video/omap3isp/gamma_table.h90
-rw-r--r--drivers/media/video/omap3isp/isp.c2220
-rw-r--r--drivers/media/video/omap3isp/isp.h431
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c2268
-rw-r--r--drivers/media/video/omap3isp/ispccdc.h219
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c1173
-rw-r--r--drivers/media/video/omap3isp/ispccp2.h98
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c1317
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.h166
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.c247
-rw-r--r--drivers/media/video/omap3isp/ispcsiphy.h74
-rw-r--r--drivers/media/video/omap3isp/isph3a.h117
-rw-r--r--drivers/media/video/omap3isp/isph3a_aewb.c374
-rw-r--r--drivers/media/video/omap3isp/isph3a_af.c429
-rw-r--r--drivers/media/video/omap3isp/isphist.c520
-rw-r--r--drivers/media/video/omap3isp/isphist.h40
-rw-r--r--drivers/media/video/omap3isp/isppreview.c2113
-rw-r--r--drivers/media/video/omap3isp/isppreview.h214
-rw-r--r--drivers/media/video/omap3isp/ispqueue.c1153
-rw-r--r--drivers/media/video/omap3isp/ispqueue.h187
-rw-r--r--drivers/media/video/omap3isp/ispreg.h1589
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c1693
-rw-r--r--drivers/media/video/omap3isp/ispresizer.h147
-rw-r--r--drivers/media/video/omap3isp/ispstat.c1092
-rw-r--r--drivers/media/video/omap3isp/ispstat.h169
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c1255
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h202
-rw-r--r--drivers/media/video/omap3isp/luma_enhance_table.h42
-rw-r--r--drivers/media/video/omap3isp/noise_filter_table.h30
-rw-r--r--drivers/media/video/ov6650.c10
-rw-r--r--drivers/media/video/ov9740.c1009
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c18
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.c24
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c84
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c4
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-sysfs.c9
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-v4l2.c2
-rw-r--r--drivers/media/video/pwc/pwc-if.c38
-rw-r--r--drivers/media/video/pwc/pwc-v4l.c1033
-rw-r--r--drivers/media/video/pwc/pwc.h3
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c602
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c1019
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.h180
-rw-r--r--drivers/media/video/s5p-fimc/fimc-reg.c205
-rw-r--r--drivers/media/video/s5p-fimc/regs-fimc.h29
-rw-r--r--drivers/media/video/saa7110.c115
-rw-r--r--drivers/media/video/saa7134/Kconfig1
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c43
-rw-r--r--drivers/media/video/saa7134/saa7134-core.c35
-rw-r--r--drivers/media/video/saa7134/saa7134-empress.c4
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c52
-rw-r--r--drivers/media/video/saa7134/saa7134.h1
-rw-r--r--drivers/media/video/saa7164/saa7164-api.c10
-rw-r--r--drivers/media/video/saa7164/saa7164-buffer.c16
-rw-r--r--drivers/media/video/saa7164/saa7164-bus.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-cmd.c10
-rw-r--r--drivers/media/video/saa7164/saa7164-core.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-dvb.c4
-rw-r--r--drivers/media/video/saa7164/saa7164-encoder.c8
-rw-r--r--drivers/media/video/saa7164/saa7164-fw.c2
-rw-r--r--drivers/media/video/saa7164/saa7164-vbi.c8
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c274
-rw-r--r--drivers/media/video/sh_mobile_csi2.c6
-rw-r--r--drivers/media/video/sn9c102/sn9c102_core.c6
-rw-r--r--drivers/media/video/soc_camera.c156
-rw-r--r--drivers/media/video/soc_mediabus.c16
-rw-r--r--drivers/media/video/tlg2300/pd-video.c4
-rw-r--r--drivers/media/video/tlv320aic23b.c74
-rw-r--r--drivers/media/video/tuner-core.c1205
-rw-r--r--drivers/media/video/tvp514x.c236
-rw-r--r--drivers/media/video/tvp5150.c199
-rw-r--r--drivers/media/video/tvp7002.c117
-rw-r--r--drivers/media/video/uvc/uvc_driver.c8
-rw-r--r--drivers/media/video/uvc/uvc_video.c14
-rw-r--r--drivers/media/video/v4l2-common.c64
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c244
-rw-r--r--drivers/media/video/v4l2-ctrls.c2
-rw-r--r--drivers/media/video/v4l2-dev.c152
-rw-r--r--drivers/media/video/v4l2-device.c101
-rw-r--r--drivers/media/video/v4l2-fh.c47
-rw-r--r--drivers/media/video/v4l2-ioctl.c669
-rw-r--r--drivers/media/video/v4l2-mem2mem.c236
-rw-r--r--drivers/media/video/v4l2-subdev.c332
-rw-r--r--drivers/media/video/via-camera.c147
-rw-r--r--drivers/media/video/videobuf-dma-contig.c2
-rw-r--r--drivers/media/video/videobuf2-core.c1819
-rw-r--r--drivers/media/video/videobuf2-dma-contig.c185
-rw-r--r--drivers/media/video/videobuf2-dma-sg.c294
-rw-r--r--drivers/media/video/videobuf2-memops.c235
-rw-r--r--drivers/media/video/videobuf2-vmalloc.c132
-rw-r--r--drivers/media/video/vivi.c579
-rw-r--r--drivers/media/video/vpx3220.c137
-rw-r--r--drivers/media/video/wm8775.c126
-rw-r--r--drivers/mfd/Kconfig2
-rw-r--r--drivers/mfd/wl1273-core.c147
-rw-r--r--drivers/staging/Kconfig8
-rw-r--r--drivers/staging/Makefile5
-rw-r--r--drivers/staging/altera-stapl/Kconfig8
-rw-r--r--drivers/staging/altera-stapl/Makefile3
-rw-r--r--drivers/staging/altera-stapl/altera-comp.c142
-rw-r--r--drivers/staging/altera-stapl/altera-exprt.h33
-rw-r--r--drivers/staging/altera-stapl/altera-jtag.c1020
-rw-r--r--drivers/staging/altera-stapl/altera-jtag.h113
-rw-r--r--drivers/staging/altera-stapl/altera-lpt.c70
-rw-r--r--drivers/staging/altera-stapl/altera.c2527
-rw-r--r--drivers/staging/cx25821/Kconfig1
-rw-r--r--drivers/staging/cx25821/cx25821-alsa.c2
-rw-r--r--drivers/staging/cx25821/cx25821-core.c16
-rw-r--r--drivers/staging/cx25821/cx25821-video.c9
-rw-r--r--drivers/staging/cx25821/cx25821.h3
-rw-r--r--drivers/staging/cxd2099/Kconfig11
-rw-r--r--drivers/staging/cxd2099/Makefile5
-rw-r--r--drivers/staging/cxd2099/TODO12
-rw-r--r--drivers/staging/cxd2099/cxd2099.c574
-rw-r--r--drivers/staging/cxd2099/cxd2099.h41
-rw-r--r--drivers/staging/dabusb/Kconfig14
-rw-r--r--drivers/staging/dabusb/Makefile2
-rw-r--r--drivers/staging/dabusb/TODO5
-rw-r--r--drivers/staging/dabusb/dabusb.c926
-rw-r--r--drivers/staging/dabusb/dabusb.h80
-rw-r--r--drivers/staging/easycap/easycap_ioctl.c3
-rw-r--r--drivers/staging/lirc/Kconfig12
-rw-r--r--drivers/staging/lirc/Makefile2
-rw-r--r--drivers/staging/lirc/TODO.lirc_zilog51
-rw-r--r--drivers/staging/lirc/lirc_imon.c2
-rw-r--r--drivers/staging/lirc/lirc_it87.c1027
-rw-r--r--drivers/staging/lirc/lirc_it87.h116
-rw-r--r--drivers/staging/lirc/lirc_ite8709.c542
-rw-r--r--drivers/staging/lirc/lirc_sasem.c2
-rw-r--r--drivers/staging/lirc/lirc_zilog.c814
-rw-r--r--drivers/staging/se401/Kconfig13
-rw-r--r--drivers/staging/se401/Makefile1
-rw-r--r--drivers/staging/se401/TODO5
-rw-r--r--drivers/staging/se401/se401.c1492
-rw-r--r--drivers/staging/se401/se401.h236
-rw-r--r--drivers/staging/se401/videodev.h318
-rw-r--r--drivers/staging/tm6000/tm6000-alsa.c13
-rw-r--r--drivers/staging/tm6000/tm6000-cards.c102
-rw-r--r--drivers/staging/tm6000/tm6000-core.c298
-rw-r--r--drivers/staging/tm6000/tm6000-regs.h63
-rw-r--r--drivers/staging/tm6000/tm6000-stds.c35
-rw-r--r--drivers/staging/tm6000/tm6000-video.c344
-rw-r--r--drivers/staging/tm6000/tm6000.h25
-rw-r--r--drivers/staging/usbvideo/Kconfig15
-rw-r--r--drivers/staging/usbvideo/Makefile2
-rw-r--r--drivers/staging/usbvideo/TODO5
-rw-r--r--drivers/staging/usbvideo/usbvideo.c2222
-rw-r--r--drivers/staging/usbvideo/usbvideo.h395
-rw-r--r--drivers/staging/usbvideo/vicam.c946
-rw-r--r--drivers/staging/usbvideo/videodev.h318
-rw-r--r--drivers/video/matrox/matroxfb_base.c3
-rw-r--r--include/linux/Kbuild4
-rw-r--r--include/linux/media.h132
-rw-r--r--include/linux/mfd/wl1273-core.h2
-rw-r--r--include/linux/omap3isp.h646
-rw-r--r--include/linux/v4l2-mediabus.h108
-rw-r--r--include/linux/v4l2-subdev.h141
-rw-r--r--include/linux/videodev2.h146
-rw-r--r--include/media/media-device.h95
-rw-r--r--include/media/media-devnode.h97
-rw-r--r--include/media/media-entity.h151
-rw-r--r--include/media/noon010pc30.h28
-rw-r--r--include/media/rc-map.h6
-rw-r--r--include/media/s5p_fimc.h (renamed from include/media/s3c_fimc.h)27
-rw-r--r--include/media/soc_camera.h24
-rw-r--r--include/media/soc_mediabus.h4
-rw-r--r--include/media/tuner.h16
-rw-r--r--include/media/v4l2-chip-ident.h4
-rw-r--r--include/media/v4l2-common.h15
-rw-r--r--include/media/v4l2-dev.h46
-rw-r--r--include/media/v4l2-device.h24
-rw-r--r--include/media/v4l2-fh.h29
-rw-r--r--include/media/v4l2-ioctl.h18
-rw-r--r--include/media/v4l2-mediabus.h61
-rw-r--r--include/media/v4l2-mem2mem.h58
-rw-r--r--include/media/v4l2-subdev.h113
-rw-r--r--include/media/videobuf2-core.h380
-rw-r--r--include/media/videobuf2-dma-contig.h32
-rw-r--r--include/media/videobuf2-dma-sg.h32
-rw-r--r--include/media/videobuf2-memops.h45
-rw-r--r--include/media/videobuf2-vmalloc.h20
-rw-r--r--include/media/wm8775.h9
-rw-r--r--include/staging/altera.h49
-rw-r--r--sound/soc/codecs/Kconfig2
-rw-r--r--sound/soc/codecs/wl1273.c11
469 files changed, 77749 insertions, 19254 deletions
diff --git a/Documentation/ABI/testing/sysfs-bus-media b/Documentation/ABI/testing/sysfs-bus-media
new file mode 100644
index 000000000000..7057e574154a
--- /dev/null
+++ b/Documentation/ABI/testing/sysfs-bus-media
@@ -0,0 +1,6 @@
1What: /sys/bus/media/devices/.../model
2Date: January 2011
3Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4 linux-media@vger.kernel.org
5Description: Contains the device model name in UTF-8. The device version is
6 is not be appended to the model name.
diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
index 8b6e00a71034..2deb069aedf1 100644
--- a/Documentation/DocBook/Makefile
+++ b/Documentation/DocBook/Makefile
@@ -53,7 +53,10 @@ MAN := $(patsubst %.xml, %.9, $(BOOKS))
53mandocs: $(MAN) 53mandocs: $(MAN)
54 54
55build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \ 55build_images = mkdir -p $(objtree)/Documentation/DocBook/media/ && \
56 cp $(srctree)/Documentation/DocBook/dvb/*.png $(srctree)/Documentation/DocBook/v4l/*.gif $(objtree)/Documentation/DocBook/media/ 56 cp $(srctree)/Documentation/DocBook/dvb/*.png \
57 $(srctree)/Documentation/DocBook/v4l/*.gif \
58 $(srctree)/Documentation/DocBook/v4l/*.png \
59 $(objtree)/Documentation/DocBook/media/
57 60
58xmldoclinks: 61xmldoclinks:
59ifneq ($(objtree),$(srctree)) 62ifneq ($(objtree),$(srctree))
diff --git a/Documentation/DocBook/media-entities.tmpl b/Documentation/DocBook/media-entities.tmpl
index be34dcbe0d90..5d259c632cdf 100644
--- a/Documentation/DocBook/media-entities.tmpl
+++ b/Documentation/DocBook/media-entities.tmpl
@@ -11,6 +11,10 @@
11<!ENTITY func-select "<link linkend='func-select'><function>select()</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>"> 12<!ENTITY func-write "<link linkend='func-write'><function>write()</function></link>">
13 13
14<!ENTITY media-func-close "<link linkend='media-func-close'><function>close()</function></link>">
15<!ENTITY media-func-ioctl "<link linkend='media-func-ioctl'><function>ioctl()</function></link>">
16<!ENTITY media-func-open "<link linkend='media-func-open'><function>open()</function></link>">
17
14<!-- Ioctls --> 18<!-- Ioctls -->
15<!ENTITY VIDIOC-CROPCAP "<link linkend='vidioc-cropcap'><constant>VIDIOC_CROPCAP</constant></link>"> 19<!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>"> 20<!ENTITY VIDIOC-DBG-G-CHIP-IDENT "<link linkend='vidioc-dbg-g-chip-ident'><constant>VIDIOC_DBG_G_CHIP_IDENT</constant></link>">
@@ -82,11 +86,24 @@
82<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>"> 86<!ENTITY VIDIOC-S-PRIORITY "<link linkend='vidioc-g-priority'><constant>VIDIOC_S_PRIORITY</constant></link>">
83<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>"> 87<!ENTITY VIDIOC-S-STD "<link linkend='vidioc-g-std'><constant>VIDIOC_S_STD</constant></link>">
84<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>"> 88<!ENTITY VIDIOC-S-TUNER "<link linkend='vidioc-g-tuner'><constant>VIDIOC_S_TUNER</constant></link>">
89<!ENTITY VIDIOC-SUBDEV-ENUM-FRAME-SIZE "<link linkend='vidioc-subdev-enum-frame-size'><constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant></link>">
90<!ENTITY VIDIOC-SUBDEV-ENUM-MBUS-CODE "<link linkend='vidioc-subdev-enum-mbus-code'><constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant></link>">
91<!ENTITY VIDIOC-SUBDEV-G-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_G_CROP</constant></link>">
92<!ENTITY VIDIOC-SUBDEV-G-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_G_FMT</constant></link>">
93<!ENTITY VIDIOC-SUBDEV-G-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant></link>">
94<!ENTITY VIDIOC-SUBDEV-S-CROP "<link linkend='vidioc-subdev-g-crop'><constant>VIDIOC_SUBDEV_S_CROP</constant></link>">
95<!ENTITY VIDIOC-SUBDEV-S-FMT "<link linkend='vidioc-subdev-g-fmt'><constant>VIDIOC_SUBDEV_S_FMT</constant></link>">
96<!ENTITY VIDIOC-SUBDEV-S-FRAME-INTERVAL "<link linkend='vidioc-subdev-g-frame-interval'><constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></link>">
85<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>"> 97<!ENTITY VIDIOC-TRY-ENCODER-CMD "<link linkend='vidioc-encoder-cmd'><constant>VIDIOC_TRY_ENCODER_CMD</constant></link>">
86<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>"> 98<!ENTITY VIDIOC-TRY-EXT-CTRLS "<link linkend='vidioc-g-ext-ctrls'><constant>VIDIOC_TRY_EXT_CTRLS</constant></link>">
87<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>"> 99<!ENTITY VIDIOC-TRY-FMT "<link linkend='vidioc-g-fmt'><constant>VIDIOC_TRY_FMT</constant></link>">
88<!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>"> 100<!ENTITY VIDIOC-UNSUBSCRIBE-EVENT "<link linkend='vidioc-subscribe-event'><constant>VIDIOC_UNSUBSCRIBE_EVENT</constant></link>">
89 101
102<!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>">
103<!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>">
104<!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>">
105<!ENTITY MEDIA-IOC-SETUP-LINK "<link linkend='media-ioc-setup-link'><constant>MEDIA_IOC_SETUP_LINK</constant></link>">
106
90<!-- Types --> 107<!-- Types -->
91<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>"> 108<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
92 109
@@ -98,6 +115,7 @@
98<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>"> 115<!ENTITY v4l2-field "enum&nbsp;<link linkend='v4l2-field'>v4l2_field</link>">
99<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>"> 116<!ENTITY v4l2-frmivaltypes "enum&nbsp;<link linkend='v4l2-frmivaltypes'>v4l2_frmivaltypes</link>">
100<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>"> 117<!ENTITY v4l2-frmsizetypes "enum&nbsp;<link linkend='v4l2-frmsizetypes'>v4l2_frmsizetypes</link>">
118<!ENTITY v4l2-mbus-pixelcode "enum&nbsp;<link linkend='v4l2-mbus-pixelcode'>v4l2_mbus_pixelcode</link>">
101<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>"> 119<!ENTITY v4l2-memory "enum&nbsp;<link linkend='v4l2-memory'>v4l2_memory</link>">
102<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>"> 120<!ENTITY v4l2-mpeg-audio-ac3-bitrate "enum&nbsp;<link linkend='v4l2-mpeg-audio-ac3-bitrate'>v4l2_mpeg_audio_ac3_bitrate</link>">
103<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>"> 121<!ENTITY v4l2-mpeg-audio-crc "enum&nbsp;<link linkend='v4l2-mpeg-audio-crc'>v4l2_mpeg_audio_crc</link>">
@@ -121,6 +139,7 @@
121<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>"> 139<!ENTITY v4l2-mpeg-video-encoding "enum&nbsp;<link linkend='v4l2-mpeg-video-encoding'>v4l2_mpeg_video_encoding</link>">
122<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>"> 140<!ENTITY v4l2-power-line-frequency "enum&nbsp;<link linkend='v4l2-power-line-frequency'>v4l2_power_line_frequency</link>">
123<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>"> 141<!ENTITY v4l2-priority "enum&nbsp;<link linkend='v4l2-priority'>v4l2_priority</link>">
142<!ENTITY v4l2-subdev-format-whence "enum&nbsp;<link linkend='v4l2-subdev-format-whence'>v4l2_subdev_format_whence</link>">
124<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>"> 143<!ENTITY v4l2-tuner-type "enum&nbsp;<link linkend='v4l2-tuner-type'>v4l2_tuner_type</link>">
125<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>"> 144<!ENTITY v4l2-preemphasis "enum&nbsp;<link linkend='v4l2-preemphasis'>v4l2_preemphasis</link>">
126 145
@@ -129,6 +148,7 @@
129<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>"> 148<!ENTITY v4l2-audioout "struct&nbsp;<link linkend='v4l2-audioout'>v4l2_audioout</link>">
130<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>"> 149<!ENTITY v4l2-bt-timings "struct&nbsp;<link linkend='v4l2-bt-timings'>v4l2_bt_timings</link>">
131<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>"> 150<!ENTITY v4l2-buffer "struct&nbsp;<link linkend='v4l2-buffer'>v4l2_buffer</link>">
151<!ENTITY v4l2-plane "struct&nbsp;<link linkend='v4l2-plane'>v4l2_plane</link>">
132<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>"> 152<!ENTITY v4l2-capability "struct&nbsp;<link linkend='v4l2-capability'>v4l2_capability</link>">
133<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>"> 153<!ENTITY v4l2-captureparm "struct&nbsp;<link linkend='v4l2-captureparm'>v4l2_captureparm</link>">
134<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>"> 154<!ENTITY v4l2-clip "struct&nbsp;<link linkend='v4l2-clip'>v4l2_clip</link>">
@@ -162,11 +182,14 @@
162<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>"> 182<!ENTITY v4l2-hw-freq-seek "struct&nbsp;<link linkend='v4l2-hw-freq-seek'>v4l2_hw_freq_seek</link>">
163<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>"> 183<!ENTITY v4l2-input "struct&nbsp;<link linkend='v4l2-input'>v4l2_input</link>">
164<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>"> 184<!ENTITY v4l2-jpegcompression "struct&nbsp;<link linkend='v4l2-jpegcompression'>v4l2_jpegcompression</link>">
185<!ENTITY v4l2-mbus-framefmt "struct&nbsp;<link linkend='v4l2-mbus-framefmt'>v4l2_mbus_framefmt</link>">
165<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>"> 186<!ENTITY v4l2-modulator "struct&nbsp;<link linkend='v4l2-modulator'>v4l2_modulator</link>">
166<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>"> 187<!ENTITY v4l2-mpeg-vbi-fmt-ivtv "struct&nbsp;<link linkend='v4l2-mpeg-vbi-fmt-ivtv'>v4l2_mpeg_vbi_fmt_ivtv</link>">
167<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>"> 188<!ENTITY v4l2-output "struct&nbsp;<link linkend='v4l2-output'>v4l2_output</link>">
168<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>"> 189<!ENTITY v4l2-outputparm "struct&nbsp;<link linkend='v4l2-outputparm'>v4l2_outputparm</link>">
169<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>"> 190<!ENTITY v4l2-pix-format "struct&nbsp;<link linkend='v4l2-pix-format'>v4l2_pix_format</link>">
191<!ENTITY v4l2-pix-format-mplane "struct&nbsp;<link linkend='v4l2-pix-format-mplane'>v4l2_pix_format_mplane</link>">
192<!ENTITY v4l2-plane-pix-format "struct&nbsp;<link linkend='v4l2-plane-pix-format'>v4l2_plane_pix_format</link>">
170<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>"> 193<!ENTITY v4l2-queryctrl "struct&nbsp;<link linkend='v4l2-queryctrl'>v4l2_queryctrl</link>">
171<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>"> 194<!ENTITY v4l2-querymenu "struct&nbsp;<link linkend='v4l2-querymenu'>v4l2_querymenu</link>">
172<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>"> 195<!ENTITY v4l2-rect "struct&nbsp;<link linkend='v4l2-rect'>v4l2_rect</link>">
@@ -174,6 +197,12 @@
174<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>"> 197<!ENTITY v4l2-sliced-vbi-cap "struct&nbsp;<link linkend='v4l2-sliced-vbi-cap'>v4l2_sliced_vbi_cap</link>">
175<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>"> 198<!ENTITY v4l2-sliced-vbi-data "struct&nbsp;<link linkend='v4l2-sliced-vbi-data'>v4l2_sliced_vbi_data</link>">
176<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>"> 199<!ENTITY v4l2-sliced-vbi-format "struct&nbsp;<link linkend='v4l2-sliced-vbi-format'>v4l2_sliced_vbi_format</link>">
200<!ENTITY v4l2-subdev-frame-interval "struct&nbsp;<link linkend='v4l2-subdev-frame-interval'>v4l2_subdev_frame_interval</link>">
201<!ENTITY v4l2-subdev-frame-interval-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-interval-enum'>v4l2_subdev_frame_interval_enum</link>">
202<!ENTITY v4l2-subdev-frame-size-enum "struct&nbsp;<link linkend='v4l2-subdev-frame-size-enum'>v4l2_subdev_frame_size_enum</link>">
203<!ENTITY v4l2-subdev-crop "struct&nbsp;<link linkend='v4l2-subdev-crop'>v4l2_subdev_crop</link>">
204<!ENTITY v4l2-subdev-format "struct&nbsp;<link linkend='v4l2-subdev-format'>v4l2_subdev_format</link>">
205<!ENTITY v4l2-subdev-mbus-code-enum "struct&nbsp;<link linkend='v4l2-subdev-mbus-code-enum'>v4l2_subdev_mbus_code_enum</link>">
177<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>"> 206<!ENTITY v4l2-standard "struct&nbsp;<link linkend='v4l2-standard'>v4l2_standard</link>">
178<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>"> 207<!ENTITY v4l2-streamparm "struct&nbsp;<link linkend='v4l2-streamparm'>v4l2_streamparm</link>">
179<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>"> 208<!ENTITY v4l2-timecode "struct&nbsp;<link linkend='v4l2-timecode'>v4l2_timecode</link>">
@@ -181,6 +210,12 @@
181<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>"> 210<!ENTITY v4l2-vbi-format "struct&nbsp;<link linkend='v4l2-vbi-format'>v4l2_vbi_format</link>">
182<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>"> 211<!ENTITY v4l2-window "struct&nbsp;<link linkend='v4l2-window'>v4l2_window</link>">
183 212
213<!ENTITY media-device-info "struct&nbsp;<link linkend='media-device-info'>media_device_info</link>">
214<!ENTITY media-entity-desc "struct&nbsp;<link linkend='media-entity-desc'>media_entity_desc</link>">
215<!ENTITY media-links-enum "struct&nbsp;<link linkend='media-links-enum'>media_links_enum</link>">
216<!ENTITY media-pad-desc "struct&nbsp;<link linkend='media-pad-desc'>media_pad_desc</link>">
217<!ENTITY media-link-desc "struct&nbsp;<link linkend='media-link-desc'>media_link_desc</link>">
218
184<!-- Error Codes --> 219<!-- Error Codes -->
185<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code"> 220<!ENTITY EACCES "<errorcode>EACCES</errorcode> error code">
186<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code"> 221<!ENTITY EAGAIN "<errorcode>EAGAIN</errorcode> error code">
@@ -197,11 +232,13 @@
197<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code"> 232<!ENTITY ENXIO "<errorcode>ENXIO</errorcode> error code">
198<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code"> 233<!ENTITY EMFILE "<errorcode>EMFILE</errorcode> error code">
199<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code"> 234<!ENTITY EPERM "<errorcode>EPERM</errorcode> error code">
235<!ENTITY EPIPE "<errorcode>EPIPE</errorcode> error code">
200<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code"> 236<!ENTITY ERANGE "<errorcode>ERANGE</errorcode> error code">
201 237
202<!-- Subsections --> 238<!-- Subsections -->
203<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml"> 239<!ENTITY sub-biblio SYSTEM "v4l/biblio.xml">
204<!ENTITY sub-common SYSTEM "v4l/common.xml"> 240<!ENTITY sub-common SYSTEM "v4l/common.xml">
241<!ENTITY sub-planar-apis SYSTEM "v4l/planar-apis.xml">
205<!ENTITY sub-compat SYSTEM "v4l/compat.xml"> 242<!ENTITY sub-compat SYSTEM "v4l/compat.xml">
206<!ENTITY sub-controls SYSTEM "v4l/controls.xml"> 243<!ENTITY sub-controls SYSTEM "v4l/controls.xml">
207<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml"> 244<!ENTITY sub-dev-capture SYSTEM "v4l/dev-capture.xml">
@@ -215,6 +252,7 @@
215<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml"> 252<!ENTITY sub-dev-raw-vbi SYSTEM "v4l/dev-raw-vbi.xml">
216<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml"> 253<!ENTITY sub-dev-rds SYSTEM "v4l/dev-rds.xml">
217<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml"> 254<!ENTITY sub-dev-sliced-vbi SYSTEM "v4l/dev-sliced-vbi.xml">
255<!ENTITY sub-dev-subdev SYSTEM "v4l/dev-subdev.xml">
218<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml"> 256<!ENTITY sub-dev-teletext SYSTEM "v4l/dev-teletext.xml">
219<!ENTITY sub-driver SYSTEM "v4l/driver.xml"> 257<!ENTITY sub-driver SYSTEM "v4l/driver.xml">
220<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml"> 258<!ENTITY sub-libv4l SYSTEM "v4l/libv4l.xml">
@@ -233,6 +271,8 @@
233<!ENTITY sub-io SYSTEM "v4l/io.xml"> 271<!ENTITY sub-io SYSTEM "v4l/io.xml">
234<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml"> 272<!ENTITY sub-grey SYSTEM "v4l/pixfmt-grey.xml">
235<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml"> 273<!ENTITY sub-nv12 SYSTEM "v4l/pixfmt-nv12.xml">
274<!ENTITY sub-nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
275<!ENTITY sub-nv12mt SYSTEM "v4l/pixfmt-nv12mt.xml">
236<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml"> 276<!ENTITY sub-nv16 SYSTEM "v4l/pixfmt-nv16.xml">
237<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml"> 277<!ENTITY sub-packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
238<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml"> 278<!ENTITY sub-packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
@@ -247,6 +287,7 @@
247<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml"> 287<!ENTITY sub-yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
248<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml"> 288<!ENTITY sub-yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
249<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml"> 289<!ENTITY sub-yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
290<!ENTITY sub-yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml">
250<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> 291<!ENTITY sub-yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
251<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> 292<!ENTITY sub-yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
252<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> 293<!ENTITY sub-yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
@@ -298,6 +339,13 @@
298<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml"> 339<!ENTITY sub-reqbufs SYSTEM "v4l/vidioc-reqbufs.xml">
299<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml"> 340<!ENTITY sub-s-hw-freq-seek SYSTEM "v4l/vidioc-s-hw-freq-seek.xml">
300<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml"> 341<!ENTITY sub-streamon SYSTEM "v4l/vidioc-streamon.xml">
342<!ENTITY sub-subdev-enum-frame-interval SYSTEM "v4l/vidioc-subdev-enum-frame-interval.xml">
343<!ENTITY sub-subdev-enum-frame-size SYSTEM "v4l/vidioc-subdev-enum-frame-size.xml">
344<!ENTITY sub-subdev-enum-mbus-code SYSTEM "v4l/vidioc-subdev-enum-mbus-code.xml">
345<!ENTITY sub-subdev-formats SYSTEM "v4l/subdev-formats.xml">
346<!ENTITY sub-subdev-g-crop SYSTEM "v4l/vidioc-subdev-g-crop.xml">
347<!ENTITY sub-subdev-g-fmt SYSTEM "v4l/vidioc-subdev-g-fmt.xml">
348<!ENTITY sub-subdev-g-frame-interval SYSTEM "v4l/vidioc-subdev-g-frame-interval.xml">
301<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml"> 349<!ENTITY sub-capture-c SYSTEM "v4l/capture.c.xml">
302<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml"> 350<!ENTITY sub-keytable-c SYSTEM "v4l/keytable.c.xml">
303<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml"> 351<!ENTITY sub-v4l2grab-c SYSTEM "v4l/v4l2grab.c.xml">
@@ -321,6 +369,15 @@
321<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl"> 369<!ENTITY sub-media-entities SYSTEM "media-entities.tmpl">
322<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl"> 370<!ENTITY sub-media-indices SYSTEM "media-indices.tmpl">
323 371
372<!ENTITY sub-media-controller SYSTEM "v4l/media-controller.xml">
373<!ENTITY sub-media-open SYSTEM "v4l/media-func-open.xml">
374<!ENTITY sub-media-close SYSTEM "v4l/media-func-close.xml">
375<!ENTITY sub-media-ioctl SYSTEM "v4l/media-func-ioctl.xml">
376<!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml">
377<!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml">
378<!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml">
379<!ENTITY sub-media-ioc-setup-link SYSTEM "v4l/media-ioc-setup-link.xml">
380
324<!-- Function Reference --> 381<!-- Function Reference -->
325<!ENTITY close SYSTEM "v4l/func-close.xml"> 382<!ENTITY close SYSTEM "v4l/func-close.xml">
326<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml"> 383<!ENTITY ioctl SYSTEM "v4l/func-ioctl.xml">
@@ -333,6 +390,7 @@
333<!ENTITY write SYSTEM "v4l/func-write.xml"> 390<!ENTITY write SYSTEM "v4l/func-write.xml">
334<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml"> 391<!ENTITY grey SYSTEM "v4l/pixfmt-grey.xml">
335<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml"> 392<!ENTITY nv12 SYSTEM "v4l/pixfmt-nv12.xml">
393<!ENTITY nv12m SYSTEM "v4l/pixfmt-nv12m.xml">
336<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml"> 394<!ENTITY nv16 SYSTEM "v4l/pixfmt-nv16.xml">
337<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml"> 395<!ENTITY packed-rgb SYSTEM "v4l/pixfmt-packed-rgb.xml">
338<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml"> 396<!ENTITY packed-yuv SYSTEM "v4l/pixfmt-packed-yuv.xml">
@@ -347,6 +405,7 @@
347<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml"> 405<!ENTITY yuv410 SYSTEM "v4l/pixfmt-yuv410.xml">
348<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml"> 406<!ENTITY yuv411p SYSTEM "v4l/pixfmt-yuv411p.xml">
349<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml"> 407<!ENTITY yuv420 SYSTEM "v4l/pixfmt-yuv420.xml">
408<!ENTITY yuv420m SYSTEM "v4l/pixfmt-yuv420m.xml">
350<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml"> 409<!ENTITY yuv422p SYSTEM "v4l/pixfmt-yuv422p.xml">
351<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml"> 410<!ENTITY yuyv SYSTEM "v4l/pixfmt-yuyv.xml">
352<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml"> 411<!ENTITY yvyu SYSTEM "v4l/pixfmt-yvyu.xml">
diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl
index a99088aae1aa..88f2cc680cc2 100644
--- a/Documentation/DocBook/media.tmpl
+++ b/Documentation/DocBook/media.tmpl
@@ -106,6 +106,9 @@ Foundation. A copy of the license is included in the chapter entitled
106&sub-remote_controllers; 106&sub-remote_controllers;
107</chapter> 107</chapter>
108</part> 108</part>
109<part id="media_common">
110&sub-media-controller;
111</part>
109 112
110&sub-fdl-appendix; 113&sub-fdl-appendix;
111 114
diff --git a/Documentation/DocBook/v4l/bayer.pdf b/Documentation/DocBook/v4l/bayer.pdf
new file mode 100644
index 000000000000..905e60e6cd42
--- /dev/null
+++ b/Documentation/DocBook/v4l/bayer.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/bayer.png b/Documentation/DocBook/v4l/bayer.png
new file mode 100644
index 000000000000..9b15fb22e817
--- /dev/null
+++ b/Documentation/DocBook/v4l/bayer.png
Binary files differ
diff --git a/Documentation/DocBook/v4l/common.xml b/Documentation/DocBook/v4l/common.xml
index cea23e1c4fc6..dbab79c215c1 100644
--- a/Documentation/DocBook/v4l/common.xml
+++ b/Documentation/DocBook/v4l/common.xml
@@ -846,6 +846,8 @@ conversion routine or library for integration into applications.</para>
846 </section> 846 </section>
847 </section> 847 </section>
848 848
849 &sub-planar-apis;
850
849 <section id="crop"> 851 <section id="crop">
850 <title>Image Cropping, Insertion and Scaling</title> 852 <title>Image Cropping, Insertion and Scaling</title>
851 853
diff --git a/Documentation/DocBook/v4l/compat.xml b/Documentation/DocBook/v4l/compat.xml
index c9ce61d981f5..9f7cd4f25792 100644
--- a/Documentation/DocBook/v4l/compat.xml
+++ b/Documentation/DocBook/v4l/compat.xml
@@ -1711,8 +1711,8 @@ ioctl would enumerate the available audio inputs. An ioctl to
1711determine the current audio input, if more than one combines with the 1711determine the current audio input, if more than one combines with the
1712current video input, did not exist. So 1712current video input, did not exist. So
1713<constant>VIDIOC_G_AUDIO</constant> was renamed to 1713<constant>VIDIOC_G_AUDIO</constant> was renamed to
1714<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl will be removed in 1714<constant>VIDIOC_G_AUDIO_OLD</constant>, this ioctl was removed on
1715the future. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate 1715Kernel 2.6.39. The &VIDIOC-ENUMAUDIO; ioctl was added to enumerate
1716audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio 1716audio inputs, while &VIDIOC-G-AUDIO; now reports the current audio
1717input.</para> 1717input.</para>
1718 <para>The same changes were made to &VIDIOC-G-AUDOUT; and 1718 <para>The same changes were made to &VIDIOC-G-AUDOUT; and
@@ -1726,7 +1726,7 @@ must be updated to successfully compile again.</para>
1726 <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with 1726 <para>The &VIDIOC-OVERLAY; ioctl was incorrectly defined with
1727write-read parameter. It was changed to write-only, while the write-read 1727write-read parameter. It was changed to write-only, while the write-read
1728version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old 1728version was renamed to <constant>VIDIOC_OVERLAY_OLD</constant>. The old
1729ioctl will be removed in the future. Until further the "videodev" 1729ioctl was removed on Kernel 2.6.39. Until further the "videodev"
1730kernel module will automatically translate to the new version, so drivers 1730kernel module will automatically translate to the new version, so drivers
1731must be recompiled, but not applications.</para> 1731must be recompiled, but not applications.</para>
1732 </listitem> 1732 </listitem>
@@ -1744,7 +1744,7 @@ surface can be seen.</para>
1744defined with write-only parameter, inconsistent with other ioctls 1744defined with write-only parameter, inconsistent with other ioctls
1745modifying their argument. They were changed to write-read, while a 1745modifying their argument. They were changed to write-read, while a
1746<constant>_OLD</constant> suffix was added to the write-only versions. 1746<constant>_OLD</constant> suffix was added to the write-only versions.
1747The old ioctls will be removed in the future. Drivers and 1747The old ioctls were removed on Kernel 2.6.39. Drivers and
1748applications assuming a constant parameter need an update.</para> 1748applications assuming a constant parameter need an update.</para>
1749 </listitem> 1749 </listitem>
1750 </orderedlist> 1750 </orderedlist>
@@ -1815,8 +1815,8 @@ yet to be addressed, for details see <xref
1815 <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined 1815 <para>The &VIDIOC-CROPCAP; ioctl was incorrectly defined
1816with read-only parameter. It is now defined as write-read ioctl, while 1816with read-only parameter. It is now defined as write-read ioctl, while
1817the read-only version was renamed to 1817the read-only version was renamed to
1818<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl will be removed 1818<constant>VIDIOC_CROPCAP_OLD</constant>. The old ioctl was removed
1819in the future.</para> 1819on Kernel 2.6.39.</para>
1820 </listitem> 1820 </listitem>
1821 </orderedlist> 1821 </orderedlist>
1822 </section> 1822 </section>
@@ -2353,6 +2353,20 @@ that used it. It was originally scheduled for removal in 2.6.35.
2353 </listitem> 2353 </listitem>
2354 </orderedlist> 2354 </orderedlist>
2355 </section> 2355 </section>
2356 <section>
2357 <title>V4L2 in Linux 2.6.39</title>
2358 <orderedlist>
2359 <listitem>
2360 <para>The old VIDIOC_*_OLD symbols and V4L1 support were removed.</para>
2361 </listitem>
2362 <listitem>
2363 <para>Multi-planar API added. Does not affect the compatibility of
2364 current drivers and applications. See
2365 <link linkend="planar-apis">multi-planar API</link>
2366 for details.</para>
2367 </listitem>
2368 </orderedlist>
2369 </section>
2356 2370
2357 <section id="other"> 2371 <section id="other">
2358 <title>Relation of V4L2 to other Linux multimedia APIs</title> 2372 <title>Relation of V4L2 to other Linux multimedia APIs</title>
diff --git a/Documentation/DocBook/v4l/dev-capture.xml b/Documentation/DocBook/v4l/dev-capture.xml
index 32807e43f170..2237c661f26a 100644
--- a/Documentation/DocBook/v4l/dev-capture.xml
+++ b/Documentation/DocBook/v4l/dev-capture.xml
@@ -18,7 +18,8 @@ files are used for video output devices.</para>
18 <title>Querying Capabilities</title> 18 <title>Querying Capabilities</title>
19 19
20 <para>Devices supporting the video capture interface set the 20 <para>Devices supporting the video capture interface set the
21<constant>V4L2_CAP_VIDEO_CAPTURE</constant> flag in the 21<constant>V4L2_CAP_VIDEO_CAPTURE</constant> or
22<constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant> flag in the
22<structfield>capabilities</structfield> field of &v4l2-capability; 23<structfield>capabilities</structfield> field of &v4l2-capability;
23returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions 24returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
24they may also support the <link linkend="overlay">video overlay</link> 25they may also support the <link linkend="overlay">video overlay</link>
@@ -64,9 +65,11 @@ linkend="crop" />.</para>
64 65
65 <para>To query the current image format applications set the 66 <para>To query the current image format applications set the
66<structfield>type</structfield> field of a &v4l2-format; to 67<structfield>type</structfield> field of a &v4l2-format; to
67<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> and call the 68<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or
69<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant> and call the
68&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill 70&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
69the &v4l2-pix-format; <structfield>pix</structfield> member of the 71the &v4l2-pix-format; <structfield>pix</structfield> or the
72&v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the
70<structfield>fmt</structfield> union.</para> 73<structfield>fmt</structfield> union.</para>
71 74
72 <para>To request different parameters applications set the 75 <para>To request different parameters applications set the
@@ -84,8 +87,8 @@ adjust the parameters and finally return the actual parameters as
84without disabling I/O or possibly time consuming hardware 87without disabling I/O or possibly time consuming hardware
85preparations.</para> 88preparations.</para>
86 89
87 <para>The contents of &v4l2-pix-format; are discussed in <xref 90 <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane;
88linkend="pixfmt" />. See also the specification of the 91are discussed in <xref linkend="pixfmt" />. See also the specification of the
89<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant> 92<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
90and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video 93and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
91capture devices must implement both the 94capture devices must implement both the
diff --git a/Documentation/DocBook/v4l/dev-output.xml b/Documentation/DocBook/v4l/dev-output.xml
index 63c3c20e5a72..919e22c53854 100644
--- a/Documentation/DocBook/v4l/dev-output.xml
+++ b/Documentation/DocBook/v4l/dev-output.xml
@@ -17,7 +17,8 @@ files are used for video capture devices.</para>
17 <title>Querying Capabilities</title> 17 <title>Querying Capabilities</title>
18 18
19 <para>Devices supporting the video output interface set the 19 <para>Devices supporting the video output interface set the
20<constant>V4L2_CAP_VIDEO_OUTPUT</constant> flag in the 20<constant>V4L2_CAP_VIDEO_OUTPUT</constant> or
21<constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant> flag in the
21<structfield>capabilities</structfield> field of &v4l2-capability; 22<structfield>capabilities</structfield> field of &v4l2-capability;
22returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions 23returned by the &VIDIOC-QUERYCAP; ioctl. As secondary device functions
23they may also support the <link linkend="raw-vbi">raw VBI 24they may also support the <link linkend="raw-vbi">raw VBI
@@ -60,9 +61,11 @@ linkend="crop" />.</para>
60 61
61 <para>To query the current image format applications set the 62 <para>To query the current image format applications set the
62<structfield>type</structfield> field of a &v4l2-format; to 63<structfield>type</structfield> field of a &v4l2-format; to
63<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> and call the 64<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or
65<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant> and call the
64&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill 66&VIDIOC-G-FMT; ioctl with a pointer to this structure. Drivers fill
65the &v4l2-pix-format; <structfield>pix</structfield> member of the 67the &v4l2-pix-format; <structfield>pix</structfield> or the
68&v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member of the
66<structfield>fmt</structfield> union.</para> 69<structfield>fmt</structfield> union.</para>
67 70
68 <para>To request different parameters applications set the 71 <para>To request different parameters applications set the
@@ -80,8 +83,8 @@ adjust the parameters and finally return the actual parameters as
80without disabling I/O or possibly time consuming hardware 83without disabling I/O or possibly time consuming hardware
81preparations.</para> 84preparations.</para>
82 85
83 <para>The contents of &v4l2-pix-format; are discussed in <xref 86 <para>The contents of &v4l2-pix-format; and &v4l2-pix-format-mplane;
84linkend="pixfmt" />. See also the specification of the 87are discussed in <xref linkend="pixfmt" />. See also the specification of the
85<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant> 88<constant>VIDIOC_G_FMT</constant>, <constant>VIDIOC_S_FMT</constant>
86and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video 89and <constant>VIDIOC_TRY_FMT</constant> ioctls for details. Video
87output devices must implement both the 90output devices must implement both the
diff --git a/Documentation/DocBook/v4l/dev-subdev.xml b/Documentation/DocBook/v4l/dev-subdev.xml
new file mode 100644
index 000000000000..21caff6d159b
--- /dev/null
+++ b/Documentation/DocBook/v4l/dev-subdev.xml
@@ -0,0 +1,313 @@
1 <title>Sub-device Interface</title>
2
3 <note>
4 <title>Experimental</title>
5 <para>This is an <link linkend="experimental">experimental</link>
6 interface and may change in the future.</para>
7 </note>
8
9 <para>The complex nature of V4L2 devices, where hardware is often made of
10 several integrated circuits that need to interact with each other in a
11 controlled way, leads to complex V4L2 drivers. The drivers usually reflect
12 the hardware model in software, and model the different hardware components
13 as software blocks called sub-devices.</para>
14
15 <para>V4L2 sub-devices are usually kernel-only objects. If the V4L2 driver
16 implements the media device API, they will automatically inherit from media
17 entities. Applications will be able to enumerate the sub-devices and discover
18 the hardware topology using the media entities, pads and links enumeration
19 API.</para>
20
21 <para>In addition to make sub-devices discoverable, drivers can also choose
22 to make them directly configurable by applications. When both the sub-device
23 driver and the V4L2 device driver support this, sub-devices will feature a
24 character device node on which ioctls can be called to
25 <itemizedlist>
26 <listitem><para>query, read and write sub-devices controls</para></listitem>
27 <listitem><para>subscribe and unsubscribe to events and retrieve them</para></listitem>
28 <listitem><para>negotiate image formats on individual pads</para></listitem>
29 </itemizedlist>
30 </para>
31
32 <para>Sub-device character device nodes, conventionally named
33 <filename>/dev/v4l-subdev*</filename>, use major number 81.</para>
34
35 <section>
36 <title>Controls</title>
37 <para>Most V4L2 controls are implemented by sub-device hardware. Drivers
38 usually merge all controls and expose them through video device nodes.
39 Applications can control all sub-devices through a single interface.</para>
40
41 <para>Complex devices sometimes implement the same control in different
42 pieces of hardware. This situation is common in embedded platforms, where
43 both sensors and image processing hardware implement identical functions,
44 such as contrast adjustment, white balance or faulty pixels correction. As
45 the V4L2 controls API doesn't support several identical controls in a single
46 device, all but one of the identical controls are hidden.</para>
47
48 <para>Applications can access those hidden controls through the sub-device
49 node with the V4L2 control API described in <xref linkend="control" />. The
50 ioctls behave identically as when issued on V4L2 device nodes, with the
51 exception that they deal only with controls implemented in the sub-device.
52 </para>
53
54 <para>Depending on the driver, those controls might also be exposed through
55 one (or several) V4L2 device nodes.</para>
56 </section>
57
58 <section>
59 <title>Events</title>
60 <para>V4L2 sub-devices can notify applications of events as described in
61 <xref linkend="event" />. The API behaves identically as when used on V4L2
62 device nodes, with the exception that it only deals with events generated by
63 the sub-device. Depending on the driver, those events might also be reported
64 on one (or several) V4L2 device nodes.</para>
65 </section>
66
67 <section id="pad-level-formats">
68 <title>Pad-level Formats</title>
69
70 <warning><para>Pad-level formats are only applicable to very complex device that
71 need to expose low-level format configuration to user space. Generic V4L2
72 applications do <emphasis>not</emphasis> need to use the API described in
73 this section.</para></warning>
74
75 <note><para>For the purpose of this section, the term
76 <wordasword>format</wordasword> means the combination of media bus data
77 format, frame width and frame height.</para></note>
78
79 <para>Image formats are typically negotiated on video capture and output
80 devices using the <link linkend="crop">cropping and scaling</link> ioctls.
81 The driver is responsible for configuring every block in the video pipeline
82 according to the requested format at the pipeline input and/or
83 output.</para>
84
85 <para>For complex devices, such as often found in embedded systems,
86 identical image sizes at the output of a pipeline can be achieved using
87 different hardware configurations. One such example is shown on
88 <xref linkend="pipeline-scaling" />, where
89 image scaling can be performed on both the video sensor and the host image
90 processing hardware.</para>
91
92 <figure id="pipeline-scaling">
93 <title>Image Format Negotation on Pipelines</title>
94 <mediaobject>
95 <imageobject>
96 <imagedata fileref="pipeline.pdf" format="PS" />
97 </imageobject>
98 <imageobject>
99 <imagedata fileref="pipeline.png" format="PNG" />
100 </imageobject>
101 <textobject>
102 <phrase>High quality and high speed pipeline configuration</phrase>
103 </textobject>
104 </mediaobject>
105 </figure>
106
107 <para>The sensor scaler is usually of less quality than the host scaler, but
108 scaling on the sensor is required to achieve higher frame rates. Depending
109 on the use case (quality vs. speed), the pipeline must be configured
110 differently. Applications need to configure the formats at every point in
111 the pipeline explicitly.</para>
112
113 <para>Drivers that implement the <link linkend="media-controller-intro">media
114 API</link> can expose pad-level image format configuration to applications.
115 When they do, applications can use the &VIDIOC-SUBDEV-G-FMT; and
116 &VIDIOC-SUBDEV-S-FMT; ioctls. to negotiate formats on a per-pad basis.</para>
117
118 <para>Applications are responsible for configuring coherent parameters on
119 the whole pipeline and making sure that connected pads have compatible
120 formats. The pipeline is checked for formats mismatch at &VIDIOC-STREAMON;
121 time, and an &EPIPE; is then returned if the configuration is
122 invalid.</para>
123
124 <para>Pad-level image format configuration support can be tested by calling
125 the &VIDIOC-SUBDEV-G-FMT; ioctl on pad 0. If the driver returns an &EINVAL;
126 pad-level format configuration is not supported by the sub-device.</para>
127
128 <section>
129 <title>Format Negotiation</title>
130
131 <para>Acceptable formats on pads can (and usually do) depend on a number
132 of external parameters, such as formats on other pads, active links, or
133 even controls. Finding a combination of formats on all pads in a video
134 pipeline, acceptable to both application and driver, can't rely on formats
135 enumeration only. A format negotiation mechanism is required.</para>
136
137 <para>Central to the format negotiation mechanism are the get/set format
138 operations. When called with the <structfield>which</structfield> argument
139 set to <constant>V4L2_SUBDEV_FORMAT_TRY</constant>, the
140 &VIDIOC-SUBDEV-G-FMT; and &VIDIOC-SUBDEV-S-FMT; ioctls operate on a set of
141 formats parameters that are not connected to the hardware configuration.
142 Modifying those 'try' formats leaves the device state untouched (this
143 applies to both the software state stored in the driver and the hardware
144 state stored in the device itself).</para>
145
146 <para>While not kept as part of the device state, try formats are stored
147 in the sub-device file handles. A &VIDIOC-SUBDEV-G-FMT; call will return
148 the last try format set <emphasis>on the same sub-device file
149 handle</emphasis>. Several applications querying the same sub-device at
150 the same time will thus not interact with each other.</para>
151
152 <para>To find out whether a particular format is supported by the device,
153 applications use the &VIDIOC-SUBDEV-S-FMT; ioctl. Drivers verify and, if
154 needed, change the requested <structfield>format</structfield> based on
155 device requirements and return the possibly modified value. Applications
156 can then choose to try a different format or accept the returned value and
157 continue.</para>
158
159 <para>Formats returned by the driver during a negotiation iteration are
160 guaranteed to be supported by the device. In particular, drivers guarantee
161 that a returned format will not be further changed if passed to an
162 &VIDIOC-SUBDEV-S-FMT; call as-is (as long as external parameters, such as
163 formats on other pads or links' configuration are not changed).</para>
164
165 <para>Drivers automatically propagate formats inside sub-devices. When a
166 try or active format is set on a pad, corresponding formats on other pads
167 of the same sub-device can be modified by the driver. Drivers are free to
168 modify formats as required by the device. However, they should comply with
169 the following rules when possible:
170 <itemizedlist>
171 <listitem><para>Formats should be propagated from sink pads to source pads.
172 Modifying a format on a source pad should not modify the format on any
173 sink pad.</para></listitem>
174 <listitem><para>Sub-devices that scale frames using variable scaling factors
175 should reset the scale factors to default values when sink pads formats
176 are modified. If the 1:1 scaling ratio is supported, this means that
177 source pads formats should be reset to the sink pads formats.</para></listitem>
178 </itemizedlist>
179 </para>
180
181 <para>Formats are not propagated across links, as that would involve
182 propagating them from one sub-device file handle to another. Applications
183 must then take care to configure both ends of every link explicitly with
184 compatible formats. Identical formats on the two ends of a link are
185 guaranteed to be compatible. Drivers are free to accept different formats
186 matching device requirements as being compatible.</para>
187
188 <para><xref linkend="sample-pipeline-config" />
189 shows a sample configuration sequence for the pipeline described in
190 <xref linkend="pipeline-scaling" /> (table
191 columns list entity names and pad numbers).</para>
192
193 <table pgwide="0" frame="none" id="sample-pipeline-config">
194 <title>Sample Pipeline Configuration</title>
195 <tgroup cols="3">
196 <colspec colname="what"/>
197 <colspec colname="sensor-0" />
198 <colspec colname="frontend-0" />
199 <colspec colname="frontend-1" />
200 <colspec colname="scaler-0" />
201 <colspec colname="scaler-1" />
202 <thead>
203 <row>
204 <entry></entry>
205 <entry>Sensor/0</entry>
206 <entry>Frontend/0</entry>
207 <entry>Frontend/1</entry>
208 <entry>Scaler/0</entry>
209 <entry>Scaler/1</entry>
210 </row>
211 </thead>
212 <tbody valign="top">
213 <row>
214 <entry>Initial state</entry>
215 <entry>2048x1536</entry>
216 <entry>-</entry>
217 <entry>-</entry>
218 <entry>-</entry>
219 <entry>-</entry>
220 </row>
221 <row>
222 <entry>Configure frontend input</entry>
223 <entry>2048x1536</entry>
224 <entry><emphasis>2048x1536</emphasis></entry>
225 <entry><emphasis>2046x1534</emphasis></entry>
226 <entry>-</entry>
227 <entry>-</entry>
228 </row>
229 <row>
230 <entry>Configure scaler input</entry>
231 <entry>2048x1536</entry>
232 <entry>2048x1536</entry>
233 <entry>2046x1534</entry>
234 <entry><emphasis>2046x1534</emphasis></entry>
235 <entry><emphasis>2046x1534</emphasis></entry>
236 </row>
237 <row>
238 <entry>Configure scaler output</entry>
239 <entry>2048x1536</entry>
240 <entry>2048x1536</entry>
241 <entry>2046x1534</entry>
242 <entry>2046x1534</entry>
243 <entry><emphasis>1280x960</emphasis></entry>
244 </row>
245 </tbody>
246 </tgroup>
247 </table>
248
249 <para>
250 <orderedlist>
251 <listitem><para>Initial state. The sensor output is set to its native 3MP
252 resolution. Resolutions on the host frontend and scaler input and output
253 pads are undefined.</para></listitem>
254 <listitem><para>The application configures the frontend input pad resolution to
255 2048x1536. The driver propagates the format to the frontend output pad.
256 Note that the propagated output format can be different, as in this case,
257 than the input format, as the hardware might need to crop pixels (for
258 instance when converting a Bayer filter pattern to RGB or YUV).</para></listitem>
259 <listitem><para>The application configures the scaler input pad resolution to
260 2046x1534 to match the frontend output resolution. The driver propagates
261 the format to the scaler output pad.</para></listitem>
262 <listitem><para>The application configures the scaler output pad resolution to
263 1280x960.</para></listitem>
264 </orderedlist>
265 </para>
266
267 <para>When satisfied with the try results, applications can set the active
268 formats by setting the <structfield>which</structfield> argument to
269 <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. Active formats are changed
270 exactly as try formats by drivers. To avoid modifying the hardware state
271 during format negotiation, applications should negotiate try formats first
272 and then modify the active settings using the try formats returned during
273 the last negotiation iteration. This guarantees that the active format
274 will be applied as-is by the driver without being modified.
275 </para>
276 </section>
277
278 <section>
279 <title>Cropping and scaling</title>
280
281 <para>Many sub-devices support cropping frames on their input or output
282 pads (or possible even on both). Cropping is used to select the area of
283 interest in an image, typically on a video sensor or video decoder. It can
284 also be used as part of digital zoom implementations to select the area of
285 the image that will be scaled up.</para>
286
287 <para>Crop settings are defined by a crop rectangle and represented in a
288 &v4l2-rect; by the coordinates of the top left corner and the rectangle
289 size. Both the coordinates and sizes are expressed in pixels.</para>
290
291 <para>The crop rectangle is retrieved and set using the
292 &VIDIOC-SUBDEV-G-CROP; and &VIDIOC-SUBDEV-S-CROP; ioctls. Like for pad
293 formats, drivers store try and active crop rectangles. The format
294 negotiation mechanism applies to crop settings as well.</para>
295
296 <para>On input pads, cropping is applied relatively to the current pad
297 format. The pad format represents the image size as received by the
298 sub-device from the previous block in the pipeline, and the crop rectangle
299 represents the sub-image that will be transmitted further inside the
300 sub-device for processing. The crop rectangle be entirely containted
301 inside the input image size.</para>
302
303 <para>Input crop rectangle are reset to their default value when the input
304 image format is modified. Drivers should use the input image size as the
305 crop rectangle default value, but hardware requirements may prevent this.
306 </para>
307
308 <para>Cropping behaviour on output pads is not defined.</para>
309
310 </section>
311 </section>
312
313 &sub-subdev-formats;
diff --git a/Documentation/DocBook/v4l/func-mmap.xml b/Documentation/DocBook/v4l/func-mmap.xml
index 2e2fc3933aea..786732b64bbd 100644
--- a/Documentation/DocBook/v4l/func-mmap.xml
+++ b/Documentation/DocBook/v4l/func-mmap.xml
@@ -45,7 +45,10 @@ just specify a <constant>NULL</constant> pointer here.</para>
45 <listitem> 45 <listitem>
46 <para>Length of the memory area to map. This must be the 46 <para>Length of the memory area to map. This must be the
47same value as returned by the driver in the &v4l2-buffer; 47same value as returned by the driver in the &v4l2-buffer;
48<structfield>length</structfield> field.</para> 48<structfield>length</structfield> field for the
49single-planar API, and the same value as returned by the driver
50in the &v4l2-plane; <structfield>length</structfield> field for the
51multi-planar API.</para>
49 </listitem> 52 </listitem>
50 </varlistentry> 53 </varlistentry>
51 <varlistentry> 54 <varlistentry>
@@ -106,7 +109,10 @@ flag.</para>
106 <listitem> 109 <listitem>
107 <para>Offset of the buffer in device memory. This must be the 110 <para>Offset of the buffer in device memory. This must be the
108same value as returned by the driver in the &v4l2-buffer; 111same value as returned by the driver in the &v4l2-buffer;
109<structfield>m</structfield> union <structfield>offset</structfield> field.</para> 112<structfield>m</structfield> union <structfield>offset</structfield> field for
113the single-planar API, and the same value as returned by the driver
114in the &v4l2-plane; <structfield>m</structfield> union
115<structfield>mem_offset</structfield> field for the multi-planar API.</para>
110 </listitem> 116 </listitem>
111 </varlistentry> 117 </varlistentry>
112 </variablelist> 118 </variablelist>
diff --git a/Documentation/DocBook/v4l/func-munmap.xml b/Documentation/DocBook/v4l/func-munmap.xml
index 502ed49323b0..e2c4190f9bb6 100644
--- a/Documentation/DocBook/v4l/func-munmap.xml
+++ b/Documentation/DocBook/v4l/func-munmap.xml
@@ -37,7 +37,8 @@
37 <para>Length of the mapped buffer. This must be the same 37 <para>Length of the mapped buffer. This must be the same
38value as given to <function>mmap()</function> and returned by the 38value as given to <function>mmap()</function> and returned by the
39driver in the &v4l2-buffer; <structfield>length</structfield> 39driver in the &v4l2-buffer; <structfield>length</structfield>
40field.</para> 40field for the single-planar API and in the &v4l2-plane;
41<structfield>length</structfield> field for the multi-planar API.</para>
41 </listitem> 42 </listitem>
42 </varlistentry> 43 </varlistentry>
43 </variablelist> 44 </variablelist>
diff --git a/Documentation/DocBook/v4l/io.xml b/Documentation/DocBook/v4l/io.xml
index d424886beda0..227e7ac45a06 100644
--- a/Documentation/DocBook/v4l/io.xml
+++ b/Documentation/DocBook/v4l/io.xml
@@ -121,18 +121,22 @@ mapped.</para>
121 <para>Before applications can access the buffers they must map 121 <para>Before applications can access the buffers they must map
122them into their address space with the &func-mmap; function. The 122them into their address space with the &func-mmap; function. The
123location of the buffers in device memory can be determined with the 123location of the buffers in device memory can be determined with the
124&VIDIOC-QUERYBUF; ioctl. The <structfield>m.offset</structfield> and 124&VIDIOC-QUERYBUF; ioctl. In the single-planar API case, the
125<structfield>length</structfield> returned in a &v4l2-buffer; are 125<structfield>m.offset</structfield> and <structfield>length</structfield>
126passed as sixth and second parameter to the 126returned in a &v4l2-buffer; are passed as sixth and second parameter to the
127<function>mmap()</function> function. The offset and length values 127<function>mmap()</function> function. When using the multi-planar API,
128must not be modified. Remember the buffers are allocated in physical 128struct &v4l2-buffer; contains an array of &v4l2-plane; structures, each
129memory, as opposed to virtual memory which can be swapped out to disk. 129containing its own <structfield>m.offset</structfield> and
130Applications should free the buffers as soon as possible with the 130<structfield>length</structfield>. When using the multi-planar API, every
131&func-munmap; function.</para> 131plane of every buffer has to be mapped separately, so the number of
132calls to &func-mmap; should be equal to number of buffers times number of
133planes in each buffer. The offset and length values must not be modified.
134Remember, the buffers are allocated in physical memory, as opposed to virtual
135memory, which can be swapped out to disk. Applications should free the buffers
136as soon as possible with the &func-munmap; function.</para>
132 137
133 <example> 138 <example>
134 <title>Mapping buffers</title> 139 <title>Mapping buffers in the single-planar API</title>
135
136 <programlisting> 140 <programlisting>
137&v4l2-requestbuffers; reqbuf; 141&v4l2-requestbuffers; reqbuf;
138struct { 142struct {
@@ -141,63 +145,145 @@ struct {
141} *buffers; 145} *buffers;
142unsigned int i; 146unsigned int i;
143 147
144memset (&amp;reqbuf, 0, sizeof (reqbuf)); 148memset(&amp;reqbuf, 0, sizeof(reqbuf));
145reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 149reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
146reqbuf.memory = V4L2_MEMORY_MMAP; 150reqbuf.memory = V4L2_MEMORY_MMAP;
147reqbuf.count = 20; 151reqbuf.count = 20;
148 152
149if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) { 153if (-1 == ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf)) {
150 if (errno == EINVAL) 154 if (errno == EINVAL)
151 printf ("Video capturing or mmap-streaming is not supported\n"); 155 printf("Video capturing or mmap-streaming is not supported\n");
152 else 156 else
153 perror ("VIDIOC_REQBUFS"); 157 perror("VIDIOC_REQBUFS");
154 158
155 exit (EXIT_FAILURE); 159 exit(EXIT_FAILURE);
156} 160}
157 161
158/* We want at least five buffers. */ 162/* We want at least five buffers. */
159 163
160if (reqbuf.count &lt; 5) { 164if (reqbuf.count &lt; 5) {
161 /* You may need to free the buffers here. */ 165 /* You may need to free the buffers here. */
162 printf ("Not enough buffer memory\n"); 166 printf("Not enough buffer memory\n");
163 exit (EXIT_FAILURE); 167 exit(EXIT_FAILURE);
164} 168}
165 169
166buffers = calloc (reqbuf.count, sizeof (*buffers)); 170buffers = calloc(reqbuf.count, sizeof(*buffers));
167assert (buffers != NULL); 171assert(buffers != NULL);
168 172
169for (i = 0; i &lt; reqbuf.count; i++) { 173for (i = 0; i &lt; reqbuf.count; i++) {
170 &v4l2-buffer; buffer; 174 &v4l2-buffer; buffer;
171 175
172 memset (&amp;buffer, 0, sizeof (buffer)); 176 memset(&amp;buffer, 0, sizeof(buffer));
173 buffer.type = reqbuf.type; 177 buffer.type = reqbuf.type;
174 buffer.memory = V4L2_MEMORY_MMAP; 178 buffer.memory = V4L2_MEMORY_MMAP;
175 buffer.index = i; 179 buffer.index = i;
176 180
177 if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) { 181 if (-1 == ioctl (fd, &VIDIOC-QUERYBUF;, &amp;buffer)) {
178 perror ("VIDIOC_QUERYBUF"); 182 perror("VIDIOC_QUERYBUF");
179 exit (EXIT_FAILURE); 183 exit(EXIT_FAILURE);
180 } 184 }
181 185
182 buffers[i].length = buffer.length; /* remember for munmap() */ 186 buffers[i].length = buffer.length; /* remember for munmap() */
183 187
184 buffers[i].start = mmap (NULL, buffer.length, 188 buffers[i].start = mmap(NULL, buffer.length,
185 PROT_READ | PROT_WRITE, /* recommended */ 189 PROT_READ | PROT_WRITE, /* recommended */
186 MAP_SHARED, /* recommended */ 190 MAP_SHARED, /* recommended */
187 fd, buffer.m.offset); 191 fd, buffer.m.offset);
188 192
189 if (MAP_FAILED == buffers[i].start) { 193 if (MAP_FAILED == buffers[i].start) {
190 /* If you do not exit here you should unmap() and free() 194 /* If you do not exit here you should unmap() and free()
191 the buffers mapped so far. */ 195 the buffers mapped so far. */
192 perror ("mmap"); 196 perror("mmap");
193 exit (EXIT_FAILURE); 197 exit(EXIT_FAILURE);
198 }
199}
200
201/* Cleanup. */
202
203for (i = 0; i &lt; reqbuf.count; i++)
204 munmap(buffers[i].start, buffers[i].length);
205 </programlisting>
206 </example>
207
208 <example>
209 <title>Mapping buffers in the multi-planar API</title>
210 <programlisting>
211&v4l2-requestbuffers; reqbuf;
212/* Our current format uses 3 planes per buffer */
213#define FMT_NUM_PLANES = 3;
214
215struct {
216 void *start[FMT_NUM_PLANES];
217 size_t length[FMT_NUM_PLANES];
218} *buffers;
219unsigned int i, j;
220
221memset(&amp;reqbuf, 0, sizeof(reqbuf));
222reqbuf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
223reqbuf.memory = V4L2_MEMORY_MMAP;
224reqbuf.count = 20;
225
226if (ioctl(fd, &VIDIOC-REQBUFS;, &amp;reqbuf) &lt; 0) {
227 if (errno == EINVAL)
228 printf("Video capturing or mmap-streaming is not supported\n");
229 else
230 perror("VIDIOC_REQBUFS");
231
232 exit(EXIT_FAILURE);
233}
234
235/* We want at least five buffers. */
236
237if (reqbuf.count &lt; 5) {
238 /* You may need to free the buffers here. */
239 printf("Not enough buffer memory\n");
240 exit(EXIT_FAILURE);
241}
242
243buffers = calloc(reqbuf.count, sizeof(*buffers));
244assert(buffers != NULL);
245
246for (i = 0; i &lt; reqbuf.count; i++) {
247 &v4l2-buffer; buffer;
248 &v4l2-plane; planes[FMT_NUM_PLANES];
249
250 memset(&amp;buffer, 0, sizeof(buffer));
251 buffer.type = reqbuf.type;
252 buffer.memory = V4L2_MEMORY_MMAP;
253 buffer.index = i;
254 /* length in struct v4l2_buffer in multi-planar API stores the size
255 * of planes array. */
256 buffer.length = FMT_NUM_PLANES;
257 buffer.m.planes = planes;
258
259 if (ioctl(fd, &VIDIOC-QUERYBUF;, &amp;buffer) &lt; 0) {
260 perror("VIDIOC_QUERYBUF");
261 exit(EXIT_FAILURE);
262 }
263
264 /* Every plane has to be mapped separately */
265 for (j = 0; j &lt; FMT_NUM_PLANES; j++) {
266 buffers[i].length[j] = buffer.m.planes[j].length; /* remember for munmap() */
267
268 buffers[i].start[j] = mmap(NULL, buffer.m.planes[j].length,
269 PROT_READ | PROT_WRITE, /* recommended */
270 MAP_SHARED, /* recommended */
271 fd, buffer.m.planes[j].m.offset);
272
273 if (MAP_FAILED == buffers[i].start[j]) {
274 /* If you do not exit here you should unmap() and free()
275 the buffers and planes mapped so far. */
276 perror("mmap");
277 exit(EXIT_FAILURE);
278 }
194 } 279 }
195} 280}
196 281
197/* Cleanup. */ 282/* Cleanup. */
198 283
199for (i = 0; i &lt; reqbuf.count; i++) 284for (i = 0; i &lt; reqbuf.count; i++)
200 munmap (buffers[i].start, buffers[i].length); 285 for (j = 0; j &lt; FMT_NUM_PLANES; j++)
286 munmap(buffers[i].start[j], buffers[i].length[j]);
201 </programlisting> 287 </programlisting>
202 </example> 288 </example>
203 289
@@ -286,13 +372,13 @@ pointer method (not only memory mapping) is supported must be
286determined by calling the &VIDIOC-REQBUFS; ioctl.</para> 372determined by calling the &VIDIOC-REQBUFS; ioctl.</para>
287 373
288 <para>This I/O method combines advantages of the read/write and 374 <para>This I/O method combines advantages of the read/write and
289memory mapping methods. Buffers are allocated by the application 375memory mapping methods. Buffers (planes) are allocated by the application
290itself, and can reside for example in virtual or shared memory. Only 376itself, and can reside for example in virtual or shared memory. Only
291pointers to data are exchanged, these pointers and meta-information 377pointers to data are exchanged, these pointers and meta-information
292are passed in &v4l2-buffer;. The driver must be switched 378are passed in &v4l2-buffer; (or in &v4l2-plane; in the multi-planar API case).
293into user pointer I/O mode by calling the &VIDIOC-REQBUFS; with the 379The driver must be switched into user pointer I/O mode by calling the
294desired buffer type. No buffers are allocated beforehands, 380&VIDIOC-REQBUFS; with the desired buffer type. No buffers (planes) are allocated
295consequently they are not indexed and cannot be queried like mapped 381beforehand, consequently they are not indexed and cannot be queried like mapped
296buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para> 382buffers with the <constant>VIDIOC_QUERYBUF</constant> ioctl.</para>
297 383
298 <example> 384 <example>
@@ -316,7 +402,7 @@ if (ioctl (fd, &VIDIOC-REQBUFS;, &amp;reqbuf) == -1) {
316 </programlisting> 402 </programlisting>
317 </example> 403 </example>
318 404
319 <para>Buffer addresses and sizes are passed on the fly with the 405 <para>Buffer (plane) addresses and sizes are passed on the fly with the
320&VIDIOC-QBUF; ioctl. Although buffers are commonly cycled, 406&VIDIOC-QBUF; ioctl. Although buffers are commonly cycled,
321applications can pass different addresses and sizes at each 407applications can pass different addresses and sizes at each
322<constant>VIDIOC_QBUF</constant> call. If required by the hardware the 408<constant>VIDIOC_QBUF</constant> call. If required by the hardware the
@@ -396,11 +482,18 @@ rest should be evident.</para>
396 <title>Buffers</title> 482 <title>Buffers</title>
397 483
398 <para>A buffer contains data exchanged by application and 484 <para>A buffer contains data exchanged by application and
399driver using one of the Streaming I/O methods. Only pointers to 485driver using one of the Streaming I/O methods. In the multi-planar API, the
400buffers are exchanged, the data itself is not copied. These pointers, 486data is held in planes, while the buffer structure acts as a container
401together with meta-information like timestamps or field parity, are 487for the planes. Only pointers to buffers (planes) are exchanged, the data
402stored in a struct <structname>v4l2_buffer</structname>, argument to 488itself is not copied. These pointers, together with meta-information like
403the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.</para> 489timestamps or field parity, are stored in a struct
490<structname>v4l2_buffer</structname>, argument to
491the &VIDIOC-QUERYBUF;, &VIDIOC-QBUF; and &VIDIOC-DQBUF; ioctl.
492In the multi-planar API, some plane-specific members of struct
493<structname>v4l2_buffer</structname>, such as pointers and sizes for each
494plane, are stored in struct <structname>v4l2_plane</structname> instead.
495In that case, struct <structname>v4l2_buffer</structname> contains an array of
496plane structures.</para>
404 497
405 <para>Nominally timestamps refer to the first data byte transmitted. 498 <para>Nominally timestamps refer to the first data byte transmitted.
406In practice however the wide range of hardware covered by the V4L2 API 499In practice however the wide range of hardware covered by the V4L2 API
@@ -551,26 +644,40 @@ in accordance with the selected I/O method.</entry>
551 <entry></entry> 644 <entry></entry>
552 <entry>__u32</entry> 645 <entry>__u32</entry>
553 <entry><structfield>offset</structfield></entry> 646 <entry><structfield>offset</structfield></entry>
554 <entry>When <structfield>memory</structfield> is 647 <entry>For the single-planar API and when
555<constant>V4L2_MEMORY_MMAP</constant> this is the offset of the buffer 648<structfield>memory</structfield> is <constant>V4L2_MEMORY_MMAP</constant> this
556from the start of the device memory. The value is returned by the 649is the offset of the buffer from the start of the device memory. The value is
557driver and apart of serving as parameter to the &func-mmap; function 650returned by the driver and apart of serving as parameter to the &func-mmap;
558not useful for applications. See <xref linkend="mmap" /> for details.</entry> 651function not useful for applications. See <xref linkend="mmap" /> for details
652 </entry>
559 </row> 653 </row>
560 <row> 654 <row>
561 <entry></entry> 655 <entry></entry>
562 <entry>unsigned long</entry> 656 <entry>unsigned long</entry>
563 <entry><structfield>userptr</structfield></entry> 657 <entry><structfield>userptr</structfield></entry>
564 <entry>When <structfield>memory</structfield> is 658 <entry>For the single-planar API and when
565<constant>V4L2_MEMORY_USERPTR</constant> this is a pointer to the 659<structfield>memory</structfield> is <constant>V4L2_MEMORY_USERPTR</constant>
566buffer (casted to unsigned long type) in virtual memory, set by the 660this is a pointer to the buffer (casted to unsigned long type) in virtual
567application. See <xref linkend="userp" /> for details.</entry> 661memory, set by the application. See <xref linkend="userp" /> for details.
662 </entry>
663 </row>
664 <row>
665 <entry></entry>
666 <entry>struct v4l2_plane</entry>
667 <entry><structfield>*planes</structfield></entry>
668 <entry>When using the multi-planar API, contains a userspace pointer
669 to an array of &v4l2-plane;. The size of the array should be put
670 in the <structfield>length</structfield> field of this
671 <structname>v4l2_buffer</structname> structure.</entry>
568 </row> 672 </row>
569 <row> 673 <row>
570 <entry>__u32</entry> 674 <entry>__u32</entry>
571 <entry><structfield>length</structfield></entry> 675 <entry><structfield>length</structfield></entry>
572 <entry></entry> 676 <entry></entry>
573 <entry>Size of the buffer (not the payload) in bytes.</entry> 677 <entry>Size of the buffer (not the payload) in bytes for the
678 single-planar API. For the multi-planar API should contain the
679 number of elements in the <structfield>planes</structfield> array.
680 </entry>
574 </row> 681 </row>
575 <row> 682 <row>
576 <entry>__u32</entry> 683 <entry>__u32</entry>
@@ -596,6 +703,66 @@ should set this to 0.</entry>
596 </tgroup> 703 </tgroup>
597 </table> 704 </table>
598 705
706 <table frame="none" pgwide="1" id="v4l2-plane">
707 <title>struct <structname>v4l2_plane</structname></title>
708 <tgroup cols="4">
709 &cs-ustr;
710 <tbody valign="top">
711 <row>
712 <entry>__u32</entry>
713 <entry><structfield>bytesused</structfield></entry>
714 <entry></entry>
715 <entry>The number of bytes occupied by data in the plane
716 (its payload).</entry>
717 </row>
718 <row>
719 <entry>__u32</entry>
720 <entry><structfield>length</structfield></entry>
721 <entry></entry>
722 <entry>Size in bytes of the plane (not its payload).</entry>
723 </row>
724 <row>
725 <entry>union</entry>
726 <entry><structfield>m</structfield></entry>
727 <entry></entry>
728 <entry></entry>
729 </row>
730 <row>
731 <entry></entry>
732 <entry>__u32</entry>
733 <entry><structfield>mem_offset</structfield></entry>
734 <entry>When the memory type in the containing &v4l2-buffer; is
735 <constant>V4L2_MEMORY_MMAP</constant>, this is the value that
736 should be passed to &func-mmap;, similar to the
737 <structfield>offset</structfield> field in &v4l2-buffer;.</entry>
738 </row>
739 <row>
740 <entry></entry>
741 <entry>__unsigned long</entry>
742 <entry><structfield>userptr</structfield></entry>
743 <entry>When the memory type in the containing &v4l2-buffer; is
744 <constant>V4L2_MEMORY_USERPTR</constant>, this is a userspace
745 pointer to the memory allocated for this plane by an application.
746 </entry>
747 </row>
748 <row>
749 <entry>__u32</entry>
750 <entry><structfield>data_offset</structfield></entry>
751 <entry></entry>
752 <entry>Offset in bytes to video data in the plane, if applicable.
753 </entry>
754 </row>
755 <row>
756 <entry>__u32</entry>
757 <entry><structfield>reserved[11]</structfield></entry>
758 <entry></entry>
759 <entry>Reserved for future use. Should be zeroed by an
760 application.</entry>
761 </row>
762 </tbody>
763 </tgroup>
764 </table>
765
599 <table frame="none" pgwide="1" id="v4l2-buf-type"> 766 <table frame="none" pgwide="1" id="v4l2-buf-type">
600 <title>enum v4l2_buf_type</title> 767 <title>enum v4l2_buf_type</title>
601 <tgroup cols="3"> 768 <tgroup cols="3">
@@ -604,13 +771,27 @@ should set this to 0.</entry>
604 <row> 771 <row>
605 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry> 772 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant></entry>
606 <entry>1</entry> 773 <entry>1</entry>
607 <entry>Buffer of a video capture stream, see <xref 774 <entry>Buffer of a single-planar video capture stream, see <xref
775 linkend="capture" />.</entry>
776 </row>
777 <row>
778 <entry><constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>
779 </entry>
780 <entry>9</entry>
781 <entry>Buffer of a multi-planar video capture stream, see <xref
608 linkend="capture" />.</entry> 782 linkend="capture" />.</entry>
609 </row> 783 </row>
610 <row> 784 <row>
611 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry> 785 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant></entry>
612 <entry>2</entry> 786 <entry>2</entry>
613 <entry>Buffer of a video output stream, see <xref 787 <entry>Buffer of a single-planar video output stream, see <xref
788 linkend="output" />.</entry>
789 </row>
790 <row>
791 <entry><constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>
792 </entry>
793 <entry>10</entry>
794 <entry>Buffer of a multi-planar video output stream, see <xref
614 linkend="output" />.</entry> 795 linkend="output" />.</entry>
615 </row> 796 </row>
616 <row> 797 <row>
diff --git a/Documentation/DocBook/v4l/lirc_device_interface.xml b/Documentation/DocBook/v4l/lirc_device_interface.xml
index 68134c0ab4d1..0e0453f39e73 100644
--- a/Documentation/DocBook/v4l/lirc_device_interface.xml
+++ b/Documentation/DocBook/v4l/lirc_device_interface.xml
@@ -45,7 +45,7 @@ describing an IR signal are read from the chardev.</para>
45<para>The data written to the chardev is a pulse/space sequence of integer 45<para>The data written to the chardev is a pulse/space sequence of integer
46values. Pulses and spaces are only marked implicitly by their position. The 46values. Pulses and spaces are only marked implicitly by their position. The
47data must start and end with a pulse, therefore, the data must always include 47data must start and end with a pulse, therefore, the data must always include
48an unevent number of samples. The write function must block until the data has 48an uneven number of samples. The write function must block until the data has
49been transmitted by the hardware.</para> 49been transmitted by the hardware.</para>
50</section> 50</section>
51 51
diff --git a/Documentation/DocBook/v4l/media-controller.xml b/Documentation/DocBook/v4l/media-controller.xml
new file mode 100644
index 000000000000..2dc25e1d4089
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-controller.xml
@@ -0,0 +1,89 @@
1<partinfo>
2 <authorgroup>
3 <author>
4 <firstname>Laurent</firstname>
5 <surname>Pinchart</surname>
6 <affiliation><address><email>laurent.pinchart@ideasonboard.com</email></address></affiliation>
7 <contrib>Initial version.</contrib>
8 </author>
9 </authorgroup>
10 <copyright>
11 <year>2010</year>
12 <holder>Laurent Pinchart</holder>
13 </copyright>
14
15 <revhistory>
16 <!-- Put document revisions here, newest first. -->
17 <revision>
18 <revnumber>1.0.0</revnumber>
19 <date>2010-11-10</date>
20 <authorinitials>lp</authorinitials>
21 <revremark>Initial revision</revremark>
22 </revision>
23 </revhistory>
24</partinfo>
25
26<title>Media Controller API</title>
27
28<chapter id="media_controller">
29 <title>Media Controller</title>
30
31 <section id="media-controller-intro">
32 <title>Introduction</title>
33 <para>Media devices increasingly handle multiple related functions. Many USB
34 cameras include microphones, video capture hardware can also output video,
35 or SoC camera interfaces also perform memory-to-memory operations similar to
36 video codecs.</para>
37 <para>Independent functions, even when implemented in the same hardware, can
38 be modelled as separate devices. A USB camera with a microphone will be
39 presented to userspace applications as V4L2 and ALSA capture devices. The
40 devices' relationships (when using a webcam, end-users shouldn't have to
41 manually select the associated USB microphone), while not made available
42 directly to applications by the drivers, can usually be retrieved from
43 sysfs.</para>
44 <para>With more and more advanced SoC devices being introduced, the current
45 approach will not scale. Device topologies are getting increasingly complex
46 and can't always be represented by a tree structure. Hardware blocks are
47 shared between different functions, creating dependencies between seemingly
48 unrelated devices.</para>
49 <para>Kernel abstraction APIs such as V4L2 and ALSA provide means for
50 applications to access hardware parameters. As newer hardware expose an
51 increasingly high number of those parameters, drivers need to guess what
52 applications really require based on limited information, thereby
53 implementing policies that belong to userspace.</para>
54 <para>The media controller API aims at solving those problems.</para>
55 </section>
56
57 <section id="media-controller-model">
58 <title>Media device model</title>
59 <para>Discovering a device internal topology, and configuring it at runtime,
60 is one of the goals of the media controller API. To achieve this, hardware
61 devices are modelled as an oriented graph of building blocks called entities
62 connected through pads.</para>
63 <para>An entity is a basic media hardware or software building block. It can
64 correspond to a large variety of logical blocks such as physical hardware
65 devices (CMOS sensor for instance), logical hardware devices (a building
66 block in a System-on-Chip image processing pipeline), DMA channels or
67 physical connectors.</para>
68 <para>A pad is a connection endpoint through which an entity can interact
69 with other entities. Data (not restricted to video) produced by an entity
70 flows from the entity's output to one or more entity inputs. Pads should not
71 be confused with physical pins at chip boundaries.</para>
72 <para>A link is a point-to-point oriented connection between two pads,
73 either on the same entity or on different entities. Data flows from a source
74 pad to a sink pad.</para>
75 </section>
76</chapter>
77
78<appendix id="media-user-func">
79 <title>Function Reference</title>
80 <!-- Keep this alphabetically sorted. -->
81 &sub-media-open;
82 &sub-media-close;
83 &sub-media-ioctl;
84 <!-- All ioctls go here. -->
85 &sub-media-ioc-device-info;
86 &sub-media-ioc-enum-entities;
87 &sub-media-ioc-enum-links;
88 &sub-media-ioc-setup-link;
89</appendix>
diff --git a/Documentation/DocBook/v4l/media-func-close.xml b/Documentation/DocBook/v4l/media-func-close.xml
new file mode 100644
index 000000000000..be149c802aeb
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-func-close.xml
@@ -0,0 +1,59 @@
1<refentry id="media-func-close">
2 <refmeta>
3 <refentrytitle>media close()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>media-close</refname>
9 <refpurpose>Close a media 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 media device. Resources associated with the file descriptor
39 are freed. The device configuration remain unchanged.</para>
40 </refsect1>
41
42 <refsect1>
43 <title>Return Value</title>
44
45 <para><function>close</function> returns 0 on success. On error, -1 is
46 returned, and <varname>errno</varname> is set appropriately. Possible error
47 codes are:</para>
48
49 <variablelist>
50 <varlistentry>
51 <term><errorcode>EBADF</errorcode></term>
52 <listitem>
53 <para><parameter>fd</parameter> is not a valid open file descriptor.
54 </para>
55 </listitem>
56 </varlistentry>
57 </variablelist>
58 </refsect1>
59</refentry>
diff --git a/Documentation/DocBook/v4l/media-func-ioctl.xml b/Documentation/DocBook/v4l/media-func-ioctl.xml
new file mode 100644
index 000000000000..bda8604de15c
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-func-ioctl.xml
@@ -0,0 +1,116 @@
1<refentry id="media-func-ioctl">
2 <refmeta>
3 <refentrytitle>media ioctl()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>media-ioctl</refname>
9 <refpurpose>Control a media 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>Media ioctl request code as defined in the media.h header file,
38 for example MEDIA_IOC_SETUP_LINK.</para>
39 </listitem>
40 </varlistentry>
41 <varlistentry>
42 <term><parameter>argp</parameter></term>
43 <listitem>
44 <para>Pointer to a request-specific structure.</para>
45 </listitem>
46 </varlistentry>
47 </variablelist>
48 </refsect1>
49
50 <refsect1>
51 <title>Description</title>
52 <para>The <function>ioctl()</function> function manipulates media device
53 parameters. The argument <parameter>fd</parameter> must be an open file
54 descriptor.</para>
55 <para>The ioctl <parameter>request</parameter> code specifies the media
56 function to be called. It has encoded in it whether the argument is an
57 input, output or read/write parameter, and the size of the argument
58 <parameter>argp</parameter> in bytes.</para>
59 <para>Macros and structures definitions specifying media ioctl requests and
60 their parameters are located in the media.h header file. All media ioctl
61 requests, their respective function and parameters are specified in
62 <xref linkend="media-user-func" />.</para>
63 </refsect1>
64
65 <refsect1>
66 <title>Return Value</title>
67
68 <para><function>ioctl()</function> returns <returnvalue>0</returnvalue> on
69 success. On failure, <returnvalue>-1</returnvalue> is returned, and the
70 <varname>errno</varname> variable is set appropriately. Generic error codes
71 are listed below, and request-specific error codes are listed in the
72 individual requests descriptions.</para>
73 <para>When an ioctl that takes an output or read/write parameter fails,
74 the parameter remains unmodified.</para>
75
76 <variablelist>
77 <varlistentry>
78 <term><errorcode>EBADF</errorcode></term>
79 <listitem>
80 <para><parameter>fd</parameter> is not a valid open file descriptor.
81 </para>
82 </listitem>
83 </varlistentry>
84 <varlistentry>
85 <term><errorcode>EFAULT</errorcode></term>
86 <listitem>
87 <para><parameter>argp</parameter> references an inaccessible memory
88 area.</para>
89 </listitem>
90 </varlistentry>
91 <varlistentry>
92 <term><errorcode>EINVAL</errorcode></term>
93 <listitem>
94 <para>The <parameter>request</parameter> or the data pointed to by
95 <parameter>argp</parameter> is not valid. This is a very common error
96 code, see the individual ioctl requests listed in
97 <xref linkend="media-user-func" /> for actual causes.</para>
98 </listitem>
99 </varlistentry>
100 <varlistentry>
101 <term><errorcode>ENOMEM</errorcode></term>
102 <listitem>
103 <para>Insufficient kernel memory was available to complete the
104 request.</para>
105 </listitem>
106 </varlistentry>
107 <varlistentry>
108 <term><errorcode>ENOTTY</errorcode></term>
109 <listitem>
110 <para><parameter>fd</parameter> is not associated with a character
111 special device.</para>
112 </listitem>
113 </varlistentry>
114 </variablelist>
115 </refsect1>
116</refentry>
diff --git a/Documentation/DocBook/v4l/media-func-open.xml b/Documentation/DocBook/v4l/media-func-open.xml
new file mode 100644
index 000000000000..f7df034dc9ed
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-func-open.xml
@@ -0,0 +1,94 @@
1<refentry id="media-func-open">
2 <refmeta>
3 <refentrytitle>media open()</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>media-open</refname>
9 <refpurpose>Open a media 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 either <constant>O_RDONLY</constant>
37 or <constant>O_RDWR</constant>. Other flags have no effect.</para>
38 </listitem>
39 </varlistentry>
40 </variablelist>
41 </refsect1>
42 <refsect1>
43 <title>Description</title>
44 <para>To open a media device applications call <function>open()</function>
45 with the desired device name. The function has no side effects; the device
46 configuration remain unchanged.</para>
47 <para>When the device is opened in read-only mode, attemps to modify its
48 configuration will result in an error, and <varname>errno</varname> will be
49 set to <errorcode>EBADF</errorcode>.</para>
50 </refsect1>
51 <refsect1>
52 <title>Return Value</title>
53
54 <para><function>open</function> returns the new file descriptor on success.
55 On error, -1 is returned, and <varname>errno</varname> is set appropriately.
56 Possible error codes are:</para>
57
58 <variablelist>
59 <varlistentry>
60 <term><errorcode>EACCES</errorcode></term>
61 <listitem>
62 <para>The requested access to the file is not allowed.</para>
63 </listitem>
64 </varlistentry>
65 <varlistentry>
66 <term><errorcode>EMFILE</errorcode></term>
67 <listitem>
68 <para>The process already has the maximum number of files open.
69 </para>
70 </listitem>
71 </varlistentry>
72 <varlistentry>
73 <term><errorcode>ENFILE</errorcode></term>
74 <listitem>
75 <para>The system limit on the total number of open files has been
76 reached.</para>
77 </listitem>
78 </varlistentry>
79 <varlistentry>
80 <term><errorcode>ENOMEM</errorcode></term>
81 <listitem>
82 <para>Insufficient kernel memory was available.</para>
83 </listitem>
84 </varlistentry>
85 <varlistentry>
86 <term><errorcode>ENXIO</errorcode></term>
87 <listitem>
88 <para>No device corresponding to this device special file exists.
89 </para>
90 </listitem>
91 </varlistentry>
92 </variablelist>
93 </refsect1>
94</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-device-info.xml b/Documentation/DocBook/v4l/media-ioc-device-info.xml
new file mode 100644
index 000000000000..1f3237351bba
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-device-info.xml
@@ -0,0 +1,133 @@
1<refentry id="media-ioc-device-info">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_DEVICE_INFO</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_DEVICE_INFO</refname>
9 <refpurpose>Query device 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 <paramdef>struct media_device_info *<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>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_DEVICE_INFO</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>All media devices must support the <constant>MEDIA_IOC_DEVICE_INFO</constant>
53 ioctl. To query device information, applications call the ioctl with a
54 pointer to a &media-device-info;. The driver fills the structure and returns
55 the information to the application.
56 The ioctl never fails.</para>
57
58 <table pgwide="1" frame="none" id="media-device-info">
59 <title>struct <structname>media_device_info</structname></title>
60 <tgroup cols="3">
61 &cs-str;
62 <tbody valign="top">
63 <row>
64 <entry>char</entry>
65 <entry><structfield>driver</structfield>[16]</entry>
66 <entry><para>Name of the driver implementing the media API as a
67 NUL-terminated ASCII string. The driver version is stored in the
68 <structfield>driver_version</structfield> field.</para>
69 <para>Driver specific applications can use this information to
70 verify the driver identity. It is also useful to work around
71 known bugs, or to identify drivers in error reports.</para></entry>
72 </row>
73 <row>
74 <entry>char</entry>
75 <entry><structfield>model</structfield>[32]</entry>
76 <entry>Device model name as a NUL-terminated UTF-8 string. The
77 device version is stored in the <structfield>device_version</structfield>
78 field and is not be appended to the model name.</entry>
79 </row>
80 <row>
81 <entry>char</entry>
82 <entry><structfield>serial</structfield>[40]</entry>
83 <entry>Serial number as a NUL-terminated ASCII string.</entry>
84 </row>
85 <row>
86 <entry>char</entry>
87 <entry><structfield>bus_info</structfield>[32]</entry>
88 <entry>Location of the device in the system as a NUL-terminated
89 ASCII string. This includes the bus type name (PCI, USB, ...) and a
90 bus-specific identifier.</entry>
91 </row>
92 <row>
93 <entry>__u32</entry>
94 <entry><structfield>media_version</structfield></entry>
95 <entry>Media API version, formatted with the
96 <constant>KERNEL_VERSION()</constant> macro.</entry>
97 </row>
98 <row>
99 <entry>__u32</entry>
100 <entry><structfield>hw_revision</structfield></entry>
101 <entry>Hardware device revision in a driver-specific format.</entry>
102 </row>
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>media_version</structfield></entry>
106 <entry>Media device driver version, formatted with the
107 <constant>KERNEL_VERSION()</constant> macro. Together with the
108 <structfield>driver</structfield> field this identifies a particular
109 driver.</entry>
110 </row>
111 <row>
112 <entry>__u32</entry>
113 <entry><structfield>reserved</structfield>[31]</entry>
114 <entry>Reserved for future extensions. Drivers and applications must
115 set this array to zero.</entry>
116 </row>
117 </tbody>
118 </tgroup>
119 </table>
120 <para>The <structfield>serial</structfield> and <structfield>bus_info</structfield>
121 fields can be used to distinguish between multiple instances of otherwise
122 identical hardware. The serial number takes precedence when provided and can
123 be assumed to be unique. If the serial number is an empty string, the
124 <structfield>bus_info</structfield> field can be used instead. The
125 <structfield>bus_info</structfield> field is guaranteed to be unique, but
126 can vary across reboots or device unplug/replug.</para>
127 </refsect1>
128
129 <refsect1>
130 <title>Return value</title>
131 <para>This function doesn't return specific error codes.</para>
132 </refsect1>
133</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-enum-entities.xml b/Documentation/DocBook/v4l/media-ioc-enum-entities.xml
new file mode 100644
index 000000000000..576b68b33f2c
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-enum-entities.xml
@@ -0,0 +1,308 @@
1<refentry id="media-ioc-enum-entities">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_ENUM_ENTITIES</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_ENUM_ENTITIES</refname>
9 <refpurpose>Enumerate entities and their properties</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 media_entity_desc *<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>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_ENUM_ENTITIES</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 <para>To query the attributes of an entity, applications set the id field
52 of a &media-entity-desc; structure and call the MEDIA_IOC_ENUM_ENTITIES
53 ioctl with a pointer to this structure. The driver fills the rest of the
54 structure or returns an &EINVAL; when the id is invalid.</para>
55 <para>Entities can be enumerated by or'ing the id with the
56 <constant>MEDIA_ENT_ID_FLAG_NEXT</constant> flag. The driver will return
57 information about the entity with the smallest id strictly larger than the
58 requested one ('next entity'), or the &EINVAL; if there is none.</para>
59 <para>Entity IDs can be non-contiguous. Applications must
60 <emphasis>not</emphasis> try to enumerate entities by calling
61 MEDIA_IOC_ENUM_ENTITIES with increasing id's until they get an error.</para>
62 <para>Two or more entities that share a common non-zero
63 <structfield>group_id</structfield> value are considered as logically
64 grouped. Groups are used to report
65 <itemizedlist>
66 <listitem><para>ALSA, VBI and video nodes that carry the same media
67 stream</para></listitem>
68 <listitem><para>lens and flash controllers associated with a sensor</para></listitem>
69 </itemizedlist>
70 </para>
71
72 <table pgwide="1" frame="none" id="media-entity-desc">
73 <title>struct <structname>media_entity_desc</structname></title>
74 <tgroup cols="5">
75 <colspec colname="c1" />
76 <colspec colname="c2" />
77 <colspec colname="c3" />
78 <colspec colname="c4" />
79 <colspec colname="c5" />
80 <tbody valign="top">
81 <row>
82 <entry>__u32</entry>
83 <entry><structfield>id</structfield></entry>
84 <entry></entry>
85 <entry></entry>
86 <entry>Entity id, set by the application. When the id is or'ed with
87 <constant>MEDIA_ENT_ID_FLAG_NEXT</constant>, the driver clears the
88 flag and returns the first entity with a larger id.</entry>
89 </row>
90 <row>
91 <entry>char</entry>
92 <entry><structfield>name</structfield>[32]</entry>
93 <entry></entry>
94 <entry></entry>
95 <entry>Entity name as an UTF-8 NULL-terminated string.</entry>
96 </row>
97 <row>
98 <entry>__u32</entry>
99 <entry><structfield>type</structfield></entry>
100 <entry></entry>
101 <entry></entry>
102 <entry>Entity type, see <xref linkend="media-entity-type" /> for details.</entry>
103 </row>
104 <row>
105 <entry>__u32</entry>
106 <entry><structfield>revision</structfield></entry>
107 <entry></entry>
108 <entry></entry>
109 <entry>Entity revision in a driver/hardware specific format.</entry>
110 </row>
111 <row>
112 <entry>__u32</entry>
113 <entry><structfield>flags</structfield></entry>
114 <entry></entry>
115 <entry></entry>
116 <entry>Entity flags, see <xref linkend="media-entity-flag" /> for details.</entry>
117 </row>
118 <row>
119 <entry>__u32</entry>
120 <entry><structfield>group_id</structfield></entry>
121 <entry></entry>
122 <entry></entry>
123 <entry>Entity group ID</entry>
124 </row>
125 <row>
126 <entry>__u16</entry>
127 <entry><structfield>pads</structfield></entry>
128 <entry></entry>
129 <entry></entry>
130 <entry>Number of pads</entry>
131 </row>
132 <row>
133 <entry>__u16</entry>
134 <entry><structfield>links</structfield></entry>
135 <entry></entry>
136 <entry></entry>
137 <entry>Total number of outbound links. Inbound links are not counted
138 in this field.</entry>
139 </row>
140 <row>
141 <entry>union</entry>
142 </row>
143 <row>
144 <entry></entry>
145 <entry>struct</entry>
146 <entry><structfield>v4l</structfield></entry>
147 <entry></entry>
148 <entry>Valid for V4L sub-devices and nodes only.</entry>
149 </row>
150 <row>
151 <entry></entry>
152 <entry></entry>
153 <entry>__u32</entry>
154 <entry><structfield>major</structfield></entry>
155 <entry>V4L device node major number. For V4L sub-devices with no
156 device node, set by the driver to 0.</entry>
157 </row>
158 <row>
159 <entry></entry>
160 <entry></entry>
161 <entry>__u32</entry>
162 <entry><structfield>minor</structfield></entry>
163 <entry>V4L device node minor number. For V4L sub-devices with no
164 device node, set by the driver to 0.</entry>
165 </row>
166 <row>
167 <entry></entry>
168 <entry>struct</entry>
169 <entry><structfield>fb</structfield></entry>
170 <entry></entry>
171 <entry>Valid for frame buffer nodes only.</entry>
172 </row>
173 <row>
174 <entry></entry>
175 <entry></entry>
176 <entry>__u32</entry>
177 <entry><structfield>major</structfield></entry>
178 <entry>Frame buffer device node major number.</entry>
179 </row>
180 <row>
181 <entry></entry>
182 <entry></entry>
183 <entry>__u32</entry>
184 <entry><structfield>minor</structfield></entry>
185 <entry>Frame buffer device node minor number.</entry>
186 </row>
187 <row>
188 <entry></entry>
189 <entry>struct</entry>
190 <entry><structfield>alsa</structfield></entry>
191 <entry></entry>
192 <entry>Valid for ALSA devices only.</entry>
193 </row>
194 <row>
195 <entry></entry>
196 <entry></entry>
197 <entry>__u32</entry>
198 <entry><structfield>card</structfield></entry>
199 <entry>ALSA card number</entry>
200 </row>
201 <row>
202 <entry></entry>
203 <entry></entry>
204 <entry>__u32</entry>
205 <entry><structfield>device</structfield></entry>
206 <entry>ALSA device number</entry>
207 </row>
208 <row>
209 <entry></entry>
210 <entry></entry>
211 <entry>__u32</entry>
212 <entry><structfield>subdevice</structfield></entry>
213 <entry>ALSA sub-device number</entry>
214 </row>
215 <row>
216 <entry></entry>
217 <entry>int</entry>
218 <entry><structfield>dvb</structfield></entry>
219 <entry></entry>
220 <entry>DVB card number</entry>
221 </row>
222 <row>
223 <entry></entry>
224 <entry>__u8</entry>
225 <entry><structfield>raw</structfield>[180]</entry>
226 <entry></entry>
227 <entry></entry>
228 </row>
229 </tbody>
230 </tgroup>
231 </table>
232
233 <table frame="none" pgwide="1" id="media-entity-type">
234 <title>Media entity types</title>
235 <tgroup cols="2">
236 <colspec colname="c1"/>
237 <colspec colname="c2"/>
238 <tbody valign="top">
239 <row>
240 <entry><constant>MEDIA_ENT_T_DEVNODE</constant></entry>
241 <entry>Unknown device node</entry>
242 </row>
243 <row>
244 <entry><constant>MEDIA_ENT_T_DEVNODE_V4L</constant></entry>
245 <entry>V4L video, radio or vbi device node</entry>
246 </row>
247 <row>
248 <entry><constant>MEDIA_ENT_T_DEVNODE_FB</constant></entry>
249 <entry>Frame buffer device node</entry>
250 </row>
251 <row>
252 <entry><constant>MEDIA_ENT_T_DEVNODE_ALSA</constant></entry>
253 <entry>ALSA card</entry>
254 </row>
255 <row>
256 <entry><constant>MEDIA_ENT_T_DEVNODE_DVB</constant></entry>
257 <entry>DVB card</entry>
258 </row>
259 <row>
260 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV</constant></entry>
261 <entry>Unknown V4L sub-device</entry>
262 </row>
263 <row>
264 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_SENSOR</constant></entry>
265 <entry>Video sensor</entry>
266 </row>
267 <row>
268 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_FLASH</constant></entry>
269 <entry>Flash controller</entry>
270 </row>
271 <row>
272 <entry><constant>MEDIA_ENT_T_V4L2_SUBDEV_LENS</constant></entry>
273 <entry>Lens controller</entry>
274 </row>
275 </tbody>
276 </tgroup>
277 </table>
278
279 <table frame="none" pgwide="1" id="media-entity-flag">
280 <title>Media entity flags</title>
281 <tgroup cols="2">
282 <colspec colname="c1"/>
283 <colspec colname="c2"/>
284 <tbody valign="top">
285 <row>
286 <entry><constant>MEDIA_ENT_FL_DEFAULT</constant></entry>
287 <entry>Default entity for its type. Used to discover the default
288 audio, VBI and video devices, the default camera sensor, ...</entry>
289 </row>
290 </tbody>
291 </tgroup>
292 </table>
293 </refsect1>
294
295 <refsect1>
296 &return-value;
297
298 <variablelist>
299 <varlistentry>
300 <term><errorcode>EINVAL</errorcode></term>
301 <listitem>
302 <para>The &media-entity-desc; <structfield>id</structfield> references
303 a non-existing entity.</para>
304 </listitem>
305 </varlistentry>
306 </variablelist>
307 </refsect1>
308</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-enum-links.xml b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
new file mode 100644
index 000000000000..d2fc73ef8d56
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-enum-links.xml
@@ -0,0 +1,207 @@
1<refentry id="media-ioc-enum-links">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_ENUM_LINKS</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_ENUM_LINKS</refname>
9 <refpurpose>Enumerate all pads and links for a given entity</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 media_links_enum *<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>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_ENUM_LINKS</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 pads and/or links for a given entity, applications set
53 the entity field of a &media-links-enum; structure and initialize the
54 &media-pad-desc; and &media-link-desc; structure arrays pointed by the
55 <structfield>pads</structfield> and <structfield>links</structfield> fields.
56 They then call the MEDIA_IOC_ENUM_LINKS ioctl with a pointer to this
57 structure.</para>
58 <para>If the <structfield>pads</structfield> field is not NULL, the driver
59 fills the <structfield>pads</structfield> array with information about the
60 entity's pads. The array must have enough room to store all the entity's
61 pads. The number of pads can be retrieved with the &MEDIA-IOC-ENUM-ENTITIES;
62 ioctl.</para>
63 <para>If the <structfield>links</structfield> field is not NULL, the driver
64 fills the <structfield>links</structfield> array with information about the
65 entity's outbound links. The array must have enough room to store all the
66 entity's outbound links. The number of outbound links can be retrieved with
67 the &MEDIA-IOC-ENUM-ENTITIES; ioctl.</para>
68 <para>Only forward links that originate at one of the entity's source pads
69 are returned during the enumeration process.</para>
70
71 <table pgwide="1" frame="none" id="media-links-enum">
72 <title>struct <structname>media_links_enum</structname></title>
73 <tgroup cols="3">
74 &cs-str;
75 <tbody valign="top">
76 <row>
77 <entry>__u32</entry>
78 <entry><structfield>entity</structfield></entry>
79 <entry>Entity id, set by the application.</entry>
80 </row>
81 <row>
82 <entry>struct &media-pad-desc;</entry>
83 <entry>*<structfield>pads</structfield></entry>
84 <entry>Pointer to a pads array allocated by the application. Ignored
85 if NULL.</entry>
86 </row>
87 <row>
88 <entry>struct &media-link-desc;</entry>
89 <entry>*<structfield>links</structfield></entry>
90 <entry>Pointer to a links array allocated by the application. Ignored
91 if NULL.</entry>
92 </row>
93 </tbody>
94 </tgroup>
95 </table>
96
97 <table pgwide="1" frame="none" id="media-pad-desc">
98 <title>struct <structname>media_pad_desc</structname></title>
99 <tgroup cols="3">
100 &cs-str;
101 <tbody valign="top">
102 <row>
103 <entry>__u32</entry>
104 <entry><structfield>entity</structfield></entry>
105 <entry>ID of the entity this pad belongs to.</entry>
106 </row>
107 <row>
108 <entry>__u16</entry>
109 <entry><structfield>index</structfield></entry>
110 <entry>0-based pad index.</entry>
111 </row>
112 <row>
113 <entry>__u32</entry>
114 <entry><structfield>flags</structfield></entry>
115 <entry>Pad flags, see <xref linkend="media-pad-flag" /> for more details.</entry>
116 </row>
117 </tbody>
118 </tgroup>
119 </table>
120
121 <table frame="none" pgwide="1" id="media-pad-flag">
122 <title>Media pad flags</title>
123 <tgroup cols="2">
124 <colspec colname="c1"/>
125 <colspec colname="c2"/>
126 <tbody valign="top">
127 <row>
128 <entry><constant>MEDIA_PAD_FL_SINK</constant></entry>
129 <entry>Input pad, relative to the entity. Input pads sink data and
130 are targets of links.</entry>
131 </row>
132 <row>
133 <entry><constant>MEDIA_PAD_FL_SOURCE</constant></entry>
134 <entry>Output pad, relative to the entity. Output pads source data
135 and are origins of links.</entry>
136 </row>
137 </tbody>
138 </tgroup>
139 </table>
140
141 <table pgwide="1" frame="none" id="media-link-desc">
142 <title>struct <structname>media_links_desc</structname></title>
143 <tgroup cols="3">
144 &cs-str;
145 <tbody valign="top">
146 <row>
147 <entry>struct &media-pad-desc;</entry>
148 <entry><structfield>source</structfield></entry>
149 <entry>Pad at the origin of this link.</entry>
150 </row>
151 <row>
152 <entry>struct &media-pad-desc;</entry>
153 <entry><structfield>sink</structfield></entry>
154 <entry>Pad at the target of this link.</entry>
155 </row>
156 <row>
157 <entry>__u32</entry>
158 <entry><structfield>flags</structfield></entry>
159 <entry>Link flags, see <xref linkend="media-link-flag" /> for more details.</entry>
160 </row>
161 </tbody>
162 </tgroup>
163 </table>
164
165 <table frame="none" pgwide="1" id="media-link-flag">
166 <title>Media link flags</title>
167 <tgroup cols="2">
168 <colspec colname="c1"/>
169 <colspec colname="c2"/>
170 <tbody valign="top">
171 <row>
172 <entry><constant>MEDIA_LNK_FL_ENABLED</constant></entry>
173 <entry>The link is enabled and can be used to transfer media data.
174 When two or more links target a sink pad, only one of them can be
175 enabled at a time.</entry>
176 </row>
177 <row>
178 <entry><constant>MEDIA_LNK_FL_IMMUTABLE</constant></entry>
179 <entry>The link enabled state can't be modified at runtime. An
180 immutable link is always enabled.</entry>
181 </row>
182 <row>
183 <entry><constant>MEDIA_LNK_FL_DYNAMIC</constant></entry>
184 <entry>The link enabled state can be modified during streaming. This
185 flag is set by drivers and is read-only for applications.</entry>
186 </row>
187 </tbody>
188 </tgroup>
189 </table>
190 <para>One and only one of <constant>MEDIA_PAD_FL_SINK</constant> and
191 <constant>MEDIA_PAD_FL_SOURCE</constant> must be set for every pad.</para>
192 </refsect1>
193
194 <refsect1>
195 &return-value;
196
197 <variablelist>
198 <varlistentry>
199 <term><errorcode>EINVAL</errorcode></term>
200 <listitem>
201 <para>The &media-links-enum; <structfield>id</structfield> references
202 a non-existing entity.</para>
203 </listitem>
204 </varlistentry>
205 </variablelist>
206 </refsect1>
207</refentry>
diff --git a/Documentation/DocBook/v4l/media-ioc-setup-link.xml b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
new file mode 100644
index 000000000000..2331e76ded17
--- /dev/null
+++ b/Documentation/DocBook/v4l/media-ioc-setup-link.xml
@@ -0,0 +1,93 @@
1<refentry id="media-ioc-setup-link">
2 <refmeta>
3 <refentrytitle>ioctl MEDIA_IOC_SETUP_LINK</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>MEDIA_IOC_SETUP_LINK</refname>
9 <refpurpose>Modify the properties of a link</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 media_link_desc *<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>File descriptor returned by
31 <link linkend='media-func-open'><function>open()</function></link>.</para>
32 </listitem>
33 </varlistentry>
34 <varlistentry>
35 <term><parameter>request</parameter></term>
36 <listitem>
37 <para>MEDIA_IOC_ENUM_LINKS</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 change link properties applications fill a &media-link-desc; with
53 link identification information (source and sink pad) and the new requested
54 link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to
55 that structure.</para>
56 <para>The only configurable property is the <constant>ENABLED</constant>
57 link flag to enable/disable a link. Links marked with the
58 <constant>IMMUTABLE</constant> link flag can not be enabled or disabled.
59 </para>
60 <para>Link configuration has no side effect on other links. If an enabled
61 link at the sink pad prevents the link from being enabled, the driver
62 returns with an &EBUSY;.</para>
63 <para>Only links marked with the <constant>DYNAMIC</constant> link flag can
64 be enabled/disabled while streaming media data. Attempting to enable or
65 disable a streaming non-dynamic link will return an &EBUSY;.</para>
66 <para>If the specified link can't be found the driver returns with an
67 &EINVAL;.</para>
68 </refsect1>
69
70 <refsect1>
71 &return-value;
72
73 <variablelist>
74 <varlistentry>
75 <term><errorcode>EBUSY</errorcode></term>
76 <listitem>
77 <para>The link properties can't be changed because the link is
78 currently busy. This can be caused, for instance, by an active media
79 stream (audio or video) on the link. The ioctl shouldn't be retried if
80 no other action is performed before to fix the problem.</para>
81 </listitem>
82 </varlistentry>
83 <varlistentry>
84 <term><errorcode>EINVAL</errorcode></term>
85 <listitem>
86 <para>The &media-link-desc; references a non-existing link, or the
87 link is immutable and an attempt to modify its configuration was made.
88 </para>
89 </listitem>
90 </varlistentry>
91 </variablelist>
92 </refsect1>
93</refentry>
diff --git a/Documentation/DocBook/v4l/nv12mt.gif b/Documentation/DocBook/v4l/nv12mt.gif
new file mode 100644
index 000000000000..ef2d4cf8367b
--- /dev/null
+++ b/Documentation/DocBook/v4l/nv12mt.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/nv12mt_example.gif b/Documentation/DocBook/v4l/nv12mt_example.gif
new file mode 100644
index 000000000000..df81d68108ee
--- /dev/null
+++ b/Documentation/DocBook/v4l/nv12mt_example.gif
Binary files differ
diff --git a/Documentation/DocBook/v4l/pipeline.pdf b/Documentation/DocBook/v4l/pipeline.pdf
new file mode 100644
index 000000000000..ee3e37f04b6a
--- /dev/null
+++ b/Documentation/DocBook/v4l/pipeline.pdf
Binary files differ
diff --git a/Documentation/DocBook/v4l/pipeline.png b/Documentation/DocBook/v4l/pipeline.png
new file mode 100644
index 000000000000..f19b86c2c24d
--- /dev/null
+++ b/Documentation/DocBook/v4l/pipeline.png
Binary files differ
diff --git a/Documentation/DocBook/v4l/pixfmt-nv12m.xml b/Documentation/DocBook/v4l/pixfmt-nv12m.xml
new file mode 100644
index 000000000000..c9e166d9ded8
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv12m.xml
@@ -0,0 +1,154 @@
1 <refentry id="V4L2-PIX-FMT-NV12M">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_NV12M ('NV12M')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname> <constant>V4L2_PIX_FMT_NV12M</constant></refname>
8 <refpurpose>Variation of <constant>V4L2_PIX_FMT_NV12</constant> with planes
9 non contiguous in memory. </refpurpose>
10 </refnamediv>
11 <refsect1>
12 <title>Description</title>
13
14 <para>This is a multi-planar, two-plane version of the YUV 4:2:0 format.
15The three components are separated into two sub-images or planes.
16<constant>V4L2_PIX_FMT_NV12M</constant> differs from <constant>V4L2_PIX_FMT_NV12
17</constant> in that the two planes are non-contiguous in memory, i.e. the chroma
18plane do not necessarily immediately follows the luma plane.
19The luminance data occupies the first plane. The Y plane has one byte per pixel.
20In the second plane there is a chrominance data with alternating chroma samples.
21The CbCr plane is the same width, in bytes, as the Y plane (and of the image),
22but is half as tall in pixels. Each CbCr pair belongs to four pixels. For example,
23Cb<subscript>0</subscript>/Cr<subscript>0</subscript> belongs to
24Y'<subscript>00</subscript>, Y'<subscript>01</subscript>,
25Y'<subscript>10</subscript>, Y'<subscript>11</subscript>. </para>
26
27 <para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
28used only in drivers and applications that support the multi-planar API,
29described in <xref linkend="planar-apis"/>. </para>
30
31 <para>If the Y plane has pad bytes after each row, then the
32CbCr plane has as many pad bytes after its rows.</para>
33
34 <example>
35 <title><constant>V4L2_PIX_FMT_NV12M</constant> 4 &times; 4 pixel 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>start0&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>start0&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>start0&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>start0&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></entry>
74 </row>
75 <row>
76 <entry>start1&nbsp;+&nbsp;0:</entry>
77 <entry>Cb<subscript>00</subscript></entry>
78 <entry>Cr<subscript>00</subscript></entry>
79 <entry>Cb<subscript>01</subscript></entry>
80 <entry>Cr<subscript>01</subscript></entry>
81 </row>
82 <row>
83 <entry>start1&nbsp;+&nbsp;4:</entry>
84 <entry>Cb<subscript>10</subscript></entry>
85 <entry>Cr<subscript>10</subscript></entry>
86 <entry>Cb<subscript>11</subscript></entry>
87 <entry>Cr<subscript>11</subscript></entry>
88 </row>
89 </tbody>
90 </tgroup>
91 </informaltable>
92 </para>
93 </formalpara>
94
95 <formalpara>
96 <title>Color Sample Location.</title>
97 <para>
98 <informaltable frame="none">
99 <tgroup cols="7" align="center">
100 <tbody valign="top">
101 <row>
102 <entry></entry>
103 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
104 <entry>2</entry><entry></entry><entry>3</entry>
105 </row>
106 <row>
107 <entry>0</entry>
108 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
109 <entry>Y</entry><entry></entry><entry>Y</entry>
110 </row>
111 <row>
112 <entry></entry>
113 <entry></entry><entry>C</entry><entry></entry><entry></entry>
114 <entry></entry><entry>C</entry><entry></entry>
115 </row>
116 <row>
117 <entry>1</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 </row>
124 <row>
125 <entry>2</entry>
126 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
127 <entry>Y</entry><entry></entry><entry>Y</entry>
128 </row>
129 <row>
130 <entry></entry>
131 <entry></entry><entry>C</entry><entry></entry><entry></entry>
132 <entry></entry><entry>C</entry><entry></entry>
133 </row>
134 <row>
135 <entry>3</entry>
136 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
137 <entry>Y</entry><entry></entry><entry>Y</entry>
138 </row>
139 </tbody>
140 </tgroup>
141 </informaltable>
142 </para>
143 </formalpara>
144 </example>
145 </refsect1>
146 </refentry>
147
148 <!--
149Local Variables:
150mode: sgml
151sgml-parent-document: "pixfmt.sgml"
152indent-tabs-mode: nil
153End:
154 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-nv12mt.xml b/Documentation/DocBook/v4l/pixfmt-nv12mt.xml
new file mode 100644
index 000000000000..7a2855a526c1
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-nv12mt.xml
@@ -0,0 +1,74 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_NV12MT ('TM12')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname id="V4L2-PIX-FMT-NV12MT"><constant>V4L2_PIX_FMT_NV12MT
8</constant></refname>
9 <refpurpose>Formats with &frac12; horizontal and vertical
10chroma resolution. This format has two planes - one for luminance and one for
11chrominance. Chroma samples are interleaved. The difference to
12<constant>V4L2_PIX_FMT_NV12</constant> is the memory layout. Pixels are
13grouped in macroblocks of 64x32 size. The order of macroblocks in memory is
14also not standard.
15 </refpurpose>
16 </refnamediv>
17 <refsect1>
18 <title>Description</title>
19
20 <para>This is the two-plane versions of the YUV 4:2:0 format where data
21is grouped into 64x32 macroblocks. The three components are separated into two
22sub-images or planes. The Y plane has one byte per pixel and pixels are grouped
23into 64x32 macroblocks. The CbCr plane has the same width, in bytes, as the Y
24plane (and the image), but is half as tall in pixels. The chroma plane is also
25grouped into 64x32 macroblocks.</para>
26 <para>Width of the buffer has to be aligned to the multiple of 128, and
27height alignment is 32. Every four adjactent buffers - two horizontally and two
28vertically are grouped together and are located in memory in Z or flipped Z
29order. </para>
30 <para>Layout of macroblocks in memory is presented in the following
31figure.</para>
32 <para><figure id="nv12mt">
33 <title><constant>V4L2_PIX_FMT_NV12MT</constant> macroblock Z shape
34memory layout</title>
35 <mediaobject>
36 <imageobject>
37 <imagedata fileref="nv12mt.gif" format="GIF" />
38 </imageobject>
39 </mediaobject>
40 </figure>
41 The requirement that width is multiple of 128 is implemented because,
42the Z shape cannot be cut in half horizontally. In case the vertical resolution
43of macroblocks is odd then the last row of macroblocks is arranged in a linear
44order. </para>
45 <para>In case of chroma the layout is identical. Cb and Cr samples are
46interleaved. Height of the buffer is aligned to 32.
47 </para>
48 <example>
49 <title>Memory layout of macroblocks in <constant>V4L2_PIX_FMT_NV12
50</constant> format pixel image - extreme case</title>
51 <para>
52 <figure id="nv12mt_ex">
53 <title>Example <constant>V4L2_PIX_FMT_NV12MT</constant> memory
54layout of macroblocks</title>
55 <mediaobject>
56 <imageobject>
57 <imagedata fileref="nv12mt_example.gif" format="GIF" />
58 </imageobject>
59 </mediaobject>
60 </figure>
61 Memory layout of macroblocks of <constant>V4L2_PIX_FMT_NV12MT
62</constant> format in most extreme case.
63 </para>
64 </example>
65 </refsect1>
66 </refentry>
67
68 <!--
69Local Variables:
70mode: sgml
71sgml-parent-document: "pixfmt.sgml"
72indent-tabs-mode: nil
73End:
74 -->
diff --git a/Documentation/DocBook/v4l/pixfmt-srggb12.xml b/Documentation/DocBook/v4l/pixfmt-srggb12.xml
new file mode 100644
index 000000000000..9ba4fb690bc0
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-srggb12.xml
@@ -0,0 +1,90 @@
1 <refentry>
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_SRGGB12 ('RG12'),
4 V4L2_PIX_FMT_SGRBG12 ('BA12'),
5 V4L2_PIX_FMT_SGBRG12 ('GB12'),
6 V4L2_PIX_FMT_SBGGR12 ('BG12'),
7 </refentrytitle>
8 &manvol;
9 </refmeta>
10 <refnamediv>
11 <refname id="V4L2-PIX-FMT-SRGGB12"><constant>V4L2_PIX_FMT_SRGGB12</constant></refname>
12 <refname id="V4L2-PIX-FMT-SGRBG12"><constant>V4L2_PIX_FMT_SGRBG12</constant></refname>
13 <refname id="V4L2-PIX-FMT-SGBRG12"><constant>V4L2_PIX_FMT_SGBRG12</constant></refname>
14 <refname id="V4L2-PIX-FMT-SBGGR12"><constant>V4L2_PIX_FMT_SBGGR12</constant></refname>
15 <refpurpose>12-bit Bayer formats expanded to 16 bits</refpurpose>
16 </refnamediv>
17 <refsect1>
18 <title>Description</title>
19
20 <para>The following four pixel formats are raw sRGB / Bayer formats with
2112 bits per colour. Each colour component is stored in a 16-bit word, with 6
22unused high bits filled with zeros. Each n-pixel row contains n/2 green samples
23and n/2 blue or red samples, with alternating red and blue rows. Bytes are
24stored in memory in little endian order. They are conventionally described
25as GRGR... BGBG..., RGRG... GBGB..., etc. Below is an example of one of these
26formats</para>
27
28 <example>
29 <title><constant>V4L2_PIX_FMT_SBGGR12</constant> 4 &times; 4
30pixel image</title>
31
32 <formalpara>
33 <title>Byte Order.</title>
34 <para>Each cell is one byte, high 6 bits in high bytes are 0.
35 <informaltable frame="none">
36 <tgroup cols="5" align="center">
37 <colspec align="left" colwidth="2*" />
38 <tbody valign="top">
39 <row>
40 <entry>start&nbsp;+&nbsp;0:</entry>
41 <entry>B<subscript>00low</subscript></entry>
42 <entry>B<subscript>00high</subscript></entry>
43 <entry>G<subscript>01low</subscript></entry>
44 <entry>G<subscript>01high</subscript></entry>
45 <entry>B<subscript>02low</subscript></entry>
46 <entry>B<subscript>02high</subscript></entry>
47 <entry>G<subscript>03low</subscript></entry>
48 <entry>G<subscript>03high</subscript></entry>
49 </row>
50 <row>
51 <entry>start&nbsp;+&nbsp;8:</entry>
52 <entry>G<subscript>10low</subscript></entry>
53 <entry>G<subscript>10high</subscript></entry>
54 <entry>R<subscript>11low</subscript></entry>
55 <entry>R<subscript>11high</subscript></entry>
56 <entry>G<subscript>12low</subscript></entry>
57 <entry>G<subscript>12high</subscript></entry>
58 <entry>R<subscript>13low</subscript></entry>
59 <entry>R<subscript>13high</subscript></entry>
60 </row>
61 <row>
62 <entry>start&nbsp;+&nbsp;16:</entry>
63 <entry>B<subscript>20low</subscript></entry>
64 <entry>B<subscript>20high</subscript></entry>
65 <entry>G<subscript>21low</subscript></entry>
66 <entry>G<subscript>21high</subscript></entry>
67 <entry>B<subscript>22low</subscript></entry>
68 <entry>B<subscript>22high</subscript></entry>
69 <entry>G<subscript>23low</subscript></entry>
70 <entry>G<subscript>23high</subscript></entry>
71 </row>
72 <row>
73 <entry>start&nbsp;+&nbsp;24:</entry>
74 <entry>G<subscript>30low</subscript></entry>
75 <entry>G<subscript>30high</subscript></entry>
76 <entry>R<subscript>31low</subscript></entry>
77 <entry>R<subscript>31high</subscript></entry>
78 <entry>G<subscript>32low</subscript></entry>
79 <entry>G<subscript>32high</subscript></entry>
80 <entry>R<subscript>33low</subscript></entry>
81 <entry>R<subscript>33high</subscript></entry>
82 </row>
83 </tbody>
84 </tgroup>
85 </informaltable>
86 </para>
87 </formalpara>
88 </example>
89 </refsect1>
90</refentry>
diff --git a/Documentation/DocBook/v4l/pixfmt-yuv420m.xml b/Documentation/DocBook/v4l/pixfmt-yuv420m.xml
new file mode 100644
index 000000000000..f5d8f57495c8
--- /dev/null
+++ b/Documentation/DocBook/v4l/pixfmt-yuv420m.xml
@@ -0,0 +1,162 @@
1 <refentry id="V4L2-PIX-FMT-YUV420M">
2 <refmeta>
3 <refentrytitle>V4L2_PIX_FMT_YUV420M ('YU12M')</refentrytitle>
4 &manvol;
5 </refmeta>
6 <refnamediv>
7 <refname> <constant>V4L2_PIX_FMT_YUV420M</constant></refname>
8 <refpurpose>Variation of <constant>V4L2_PIX_FMT_YUV420</constant>
9 with planes non contiguous in memory. </refpurpose>
10 </refnamediv>
11
12 <refsect1>
13 <title>Description</title>
14
15 <para>This is a multi-planar format, as opposed to a packed format.
16The three components are separated into three sub- images or planes.
17
18The Y plane is first. The Y plane has one byte per pixel. The Cb data
19constitutes the second plane which is half the width and half
20the height of the Y plane (and of the image). Each Cb belongs to four
21pixels, a two-by-two square of the image. For example,
22Cb<subscript>0</subscript> belongs to Y'<subscript>00</subscript>,
23Y'<subscript>01</subscript>, Y'<subscript>10</subscript>, and
24Y'<subscript>11</subscript>. The Cr data, just like the Cb plane, is
25in the third plane. </para>
26
27 <para>If the Y plane has pad bytes after each row, then the Cb
28and Cr planes have half as many pad bytes after their rows. In other
29words, two Cx rows (including padding) is exactly as long as one Y row
30(including padding).</para>
31
32 <para><constant>V4L2_PIX_FMT_NV12M</constant> is intended to be
33used only in drivers and applications that support the multi-planar API,
34described in <xref linkend="planar-apis"/>. </para>
35
36 <example>
37 <title><constant>V4L2_PIX_FMT_YVU420M</constant> 4 &times; 4
38pixel image</title>
39
40 <formalpara>
41 <title>Byte Order.</title>
42 <para>Each cell is one byte.
43 <informaltable frame="none">
44 <tgroup cols="5" align="center">
45 <colspec align="left" colwidth="2*" />
46 <tbody valign="top">
47 <row>
48 <entry>start0&nbsp;+&nbsp;0:</entry>
49 <entry>Y'<subscript>00</subscript></entry>
50 <entry>Y'<subscript>01</subscript></entry>
51 <entry>Y'<subscript>02</subscript></entry>
52 <entry>Y'<subscript>03</subscript></entry>
53 </row>
54 <row>
55 <entry>start0&nbsp;+&nbsp;4:</entry>
56 <entry>Y'<subscript>10</subscript></entry>
57 <entry>Y'<subscript>11</subscript></entry>
58 <entry>Y'<subscript>12</subscript></entry>
59 <entry>Y'<subscript>13</subscript></entry>
60 </row>
61 <row>
62 <entry>start0&nbsp;+&nbsp;8:</entry>
63 <entry>Y'<subscript>20</subscript></entry>
64 <entry>Y'<subscript>21</subscript></entry>
65 <entry>Y'<subscript>22</subscript></entry>
66 <entry>Y'<subscript>23</subscript></entry>
67 </row>
68 <row>
69 <entry>start0&nbsp;+&nbsp;12:</entry>
70 <entry>Y'<subscript>30</subscript></entry>
71 <entry>Y'<subscript>31</subscript></entry>
72 <entry>Y'<subscript>32</subscript></entry>
73 <entry>Y'<subscript>33</subscript></entry>
74 </row>
75 <row><entry></entry></row>
76 <row>
77 <entry>start1&nbsp;+&nbsp;0:</entry>
78 <entry>Cb<subscript>00</subscript></entry>
79 <entry>Cb<subscript>01</subscript></entry>
80 </row>
81 <row>
82 <entry>start1&nbsp;+&nbsp;2:</entry>
83 <entry>Cb<subscript>10</subscript></entry>
84 <entry>Cb<subscript>11</subscript></entry>
85 </row>
86 <row><entry></entry></row>
87 <row>
88 <entry>start2&nbsp;+&nbsp;0:</entry>
89 <entry>Cr<subscript>00</subscript></entry>
90 <entry>Cr<subscript>01</subscript></entry>
91 </row>
92 <row>
93 <entry>start2&nbsp;+&nbsp;2:</entry>
94 <entry>Cr<subscript>10</subscript></entry>
95 <entry>Cr<subscript>11</subscript></entry>
96 </row>
97 </tbody>
98 </tgroup>
99 </informaltable>
100 </para>
101 </formalpara>
102
103 <formalpara>
104 <title>Color Sample Location.</title>
105 <para>
106 <informaltable frame="none">
107 <tgroup cols="7" align="center">
108 <tbody valign="top">
109 <row>
110 <entry></entry>
111 <entry>0</entry><entry></entry><entry>1</entry><entry></entry>
112 <entry>2</entry><entry></entry><entry>3</entry>
113 </row>
114 <row>
115 <entry>0</entry>
116 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
117 <entry>Y</entry><entry></entry><entry>Y</entry>
118 </row>
119 <row>
120 <entry></entry>
121 <entry></entry><entry>C</entry><entry></entry><entry></entry>
122 <entry></entry><entry>C</entry><entry></entry>
123 </row>
124 <row>
125 <entry>1</entry>
126 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
127 <entry>Y</entry><entry></entry><entry>Y</entry>
128 </row>
129 <row>
130 <entry></entry>
131 </row>
132 <row>
133 <entry>2</entry>
134 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
135 <entry>Y</entry><entry></entry><entry>Y</entry>
136 </row>
137 <row>
138 <entry></entry>
139 <entry></entry><entry>C</entry><entry></entry><entry></entry>
140 <entry></entry><entry>C</entry><entry></entry>
141 </row>
142 <row>
143 <entry>3</entry>
144 <entry>Y</entry><entry></entry><entry>Y</entry><entry></entry>
145 <entry>Y</entry><entry></entry><entry>Y</entry>
146 </row>
147 </tbody>
148 </tgroup>
149 </informaltable>
150 </para>
151 </formalpara>
152 </example>
153 </refsect1>
154 </refentry>
155
156 <!--
157Local Variables:
158mode: sgml
159sgml-parent-document: "pixfmt.sgml"
160indent-tabs-mode: nil
161End:
162 -->
diff --git a/Documentation/DocBook/v4l/pixfmt.xml b/Documentation/DocBook/v4l/pixfmt.xml
index cfffc88d7383..c6fdcbbd1b41 100644
--- a/Documentation/DocBook/v4l/pixfmt.xml
+++ b/Documentation/DocBook/v4l/pixfmt.xml
@@ -2,12 +2,16 @@
2 2
3 <para>The V4L2 API was primarily designed for devices exchanging 3 <para>The V4L2 API was primarily designed for devices exchanging
4image data with applications. The 4image data with applications. The
5<structname>v4l2_pix_format</structname> structure defines the format 5<structname>v4l2_pix_format</structname> and <structname>v4l2_pix_format_mplane
6and layout of an image in memory. Image formats are negotiated with 6</structname> structures define the format and layout of an image in memory.
7the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video 7The former is used with the single-planar API, while the latter is used with the
8multi-planar version (see <xref linkend="planar-apis"/>). Image formats are
9negotiated with the &VIDIOC-S-FMT; ioctl. (The explanations here focus on video
8capturing and output, for overlay frame buffer formats see also 10capturing and output, for overlay frame buffer formats see also
9&VIDIOC-G-FBUF;.)</para> 11&VIDIOC-G-FBUF;.)</para>
10 12
13<section>
14 <title>Single-planar format structure</title>
11 <table pgwide="1" frame="none" id="v4l2-pix-format"> 15 <table pgwide="1" frame="none" id="v4l2-pix-format">
12 <title>struct <structname>v4l2_pix_format</structname></title> 16 <title>struct <structname>v4l2_pix_format</structname></title>
13 <tgroup cols="3"> 17 <tgroup cols="3">
@@ -106,6 +110,98 @@ set this field to zero.</entry>
106 </tbody> 110 </tbody>
107 </tgroup> 111 </tgroup>
108 </table> 112 </table>
113</section>
114
115<section>
116 <title>Multi-planar format structures</title>
117 <para>The <structname>v4l2_plane_pix_format</structname> structures define
118 size and layout for each of the planes in a multi-planar format.
119 The <structname>v4l2_pix_format_mplane</structname> structure contains
120 information common to all planes (such as image width and height) and
121 an array of <structname>v4l2_plane_pix_format</structname> structures,
122 describing all planes of that format.</para>
123 <table pgwide="1" frame="none" id="v4l2-plane-pix-format">
124 <title>struct <structname>vl42_plane_pix_format</structname></title>
125 <tgroup cols="3">
126 &cs-str;
127 <tbody valign="top">
128 <row>
129 <entry>__u32</entry>
130 <entry><structfield>sizeimage</structfield></entry>
131 <entry>Maximum size in bytes required for image data in this plane.
132 </entry>
133 </row>
134 <row>
135 <entry>__u16</entry>
136 <entry><structfield>bytesperline</structfield></entry>
137 <entry>Distance in bytes between the leftmost pixels in two adjacent
138 lines.</entry>
139 </row>
140 <row>
141 <entry>__u16</entry>
142 <entry><structfield>reserved[7]</structfield></entry>
143 <entry>Reserved for future extensions. Should be zeroed by the
144 application.</entry>
145 </row>
146 </tbody>
147 </tgroup>
148 </table>
149 <table pgwide="1" frame="none" id="v4l2-pix-format-mplane">
150 <title>struct <structname>v4l2_pix_format_mplane</structname></title>
151 <tgroup cols="3">
152 &cs-str;
153 <tbody valign="top">
154 <row>
155 <entry>__u32</entry>
156 <entry><structfield>width</structfield></entry>
157 <entry>Image width in pixels.</entry>
158 </row>
159 <row>
160 <entry>__u32</entry>
161 <entry><structfield>height</structfield></entry>
162 <entry>Image height in pixels.</entry>
163 </row>
164 <row>
165 <entry>__u32</entry>
166 <entry><structfield>pixelformat</structfield></entry>
167 <entry>The pixel format. Both single- and multi-planar four character
168codes can be used.</entry>
169 </row>
170 <row>
171 <entry>&v4l2-field;</entry>
172 <entry><structfield>field</structfield></entry>
173 <entry>See &v4l2-pix-format;.</entry>
174 </row>
175 <row>
176 <entry>&v4l2-colorspace;</entry>
177 <entry><structfield>colorspace</structfield></entry>
178 <entry>See &v4l2-pix-format;.</entry>
179 </row>
180 <row>
181 <entry>&v4l2-plane-pix-format;</entry>
182 <entry><structfield>plane_fmt[VIDEO_MAX_PLANES]</structfield></entry>
183 <entry>An array of structures describing format of each plane this
184 pixel format consists of. The number of valid entries in this array
185 has to be put in the <structfield>num_planes</structfield>
186 field.</entry>
187 </row>
188 <row>
189 <entry>__u8</entry>
190 <entry><structfield>num_planes</structfield></entry>
191 <entry>Number of planes (i.e. separate memory buffers) for this format
192 and the number of valid entries in the
193 <structfield>plane_fmt</structfield> array.</entry>
194 </row>
195 <row>
196 <entry>__u8</entry>
197 <entry><structfield>reserved[11]</structfield></entry>
198 <entry>Reserved for future extensions. Should be zeroed by the
199 application.</entry>
200 </row>
201 </tbody>
202 </tgroup>
203 </table>
204</section>
109 205
110 <section> 206 <section>
111 <title>Standard Image Formats</title> 207 <title>Standard Image Formats</title>
@@ -142,11 +238,19 @@ leftmost 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> 238has just as many pad bytes after it as the other rows.</para>
143 239
144 <para>In V4L2 each format has an identifier which looks like 240 <para>In V4L2 each format has an identifier which looks like
145<constant>PIX_FMT_XXX</constant>, defined in the <filename>videodev2.h</filename> 241<constant>PIX_FMT_XXX</constant>, defined in the <link
146header file. These identifiers 242linkend="videodev">videodev.h</link> header file. These identifiers
147represent <link linkend="v4l2-fourcc">four character codes</link> 243represent <link linkend="v4l2-fourcc">four character (FourCC) codes</link>
148which are also listed below, however they are not the same as those 244which are also listed below, however they are not the same as those
149used in the Windows world.</para> 245used in the Windows world.</para>
246
247 <para>For some formats, data is stored in separate, discontiguous
248memory buffers. Those formats are identified by a separate set of FourCC codes
249and are referred to as "multi-planar formats". For example, a YUV422 frame is
250normally stored in one memory buffer, but it can also be placed in two or three
251separate buffers, with Y component in one buffer and CbCr components in another
252in the 2-planar version or with each component in its own buffer in the
2533-planar case. Those sub-buffers are referred to as "planes".</para>
150 </section> 254 </section>
151 255
152 <section id="colorspaces"> 256 <section id="colorspaces">
@@ -599,10 +703,13 @@ information.</para>
599 &sub-vyuy; 703 &sub-vyuy;
600 &sub-y41p; 704 &sub-y41p;
601 &sub-yuv420; 705 &sub-yuv420;
706 &sub-yuv420m;
602 &sub-yuv410; 707 &sub-yuv410;
603 &sub-yuv422p; 708 &sub-yuv422p;
604 &sub-yuv411p; 709 &sub-yuv411p;
605 &sub-nv12; 710 &sub-nv12;
711 &sub-nv12m;
712 &sub-nv12mt;
606 &sub-nv16; 713 &sub-nv16;
607 </section> 714 </section>
608 715
diff --git a/Documentation/DocBook/v4l/planar-apis.xml b/Documentation/DocBook/v4l/planar-apis.xml
new file mode 100644
index 000000000000..878ce2040488
--- /dev/null
+++ b/Documentation/DocBook/v4l/planar-apis.xml
@@ -0,0 +1,62 @@
1<section id="planar-apis">
2 <title>Single- and multi-planar APIs</title>
3
4 <para>Some devices require data for each input or output video frame
5 to be placed in discontiguous memory buffers. In such cases, one
6 video frame has to be addressed using more than one memory address, i.e. one
7 pointer per "plane". A plane is a sub-buffer of the current frame. For
8 examples of such formats see <xref linkend="pixfmt" />.</para>
9
10 <para>Initially, V4L2 API did not support multi-planar buffers and a set of
11 extensions has been introduced to handle them. Those extensions constitute
12 what is being referred to as the "multi-planar API".</para>
13
14 <para>Some of the V4L2 API calls and structures are interpreted differently,
15 depending on whether single- or multi-planar API is being used. An application
16 can choose whether to use one or the other by passing a corresponding buffer
17 type to its ioctl calls. Multi-planar versions of buffer types are suffixed
18 with an `_MPLANE' string. For a list of available multi-planar buffer types
19 see &v4l2-buf-type;.
20 </para>
21
22 <section>
23 <title>Multi-planar formats</title>
24 <para>Multi-planar API introduces new multi-planar formats. Those formats
25 use a separate set of FourCC codes. It is important to distinguish between
26 the multi-planar API and a multi-planar format. Multi-planar API calls can
27 handle all single-planar formats as well (as long as they are passed in
28 multi-planar API structures), while the single-planar API cannot
29 handle multi-planar formats.</para>
30 </section>
31
32 <section>
33 <title>Calls that distinguish between single and multi-planar APIs</title>
34 <variablelist>
35 <varlistentry>
36 <term>&VIDIOC-QUERYCAP;</term>
37 <listitem><para>Two additional multi-planar capabilities are added. They can
38 be set together with non-multi-planar ones for devices that handle
39 both single- and multi-planar formats.</para></listitem>
40 </varlistentry>
41 <varlistentry>
42 <term>&VIDIOC-G-FMT;, &VIDIOC-S-FMT;, &VIDIOC-TRY-FMT;</term>
43 <listitem><para>New structures for describing multi-planar formats are added:
44 &v4l2-pix-format-mplane; and &v4l2-plane-pix-format;. Drivers may
45 define new multi-planar formats, which have distinct FourCC codes from
46 the existing single-planar ones.</para>
47 </listitem>
48 </varlistentry>
49 <varlistentry>
50 <term>&VIDIOC-QBUF;, &VIDIOC-DQBUF;, &VIDIOC-QUERYBUF;</term>
51 <listitem><para>A new &v4l2-plane; structure for describing planes is added.
52 Arrays of this structure are passed in the new
53 <structfield>m.planes</structfield> field of &v4l2-buffer;.</para>
54 </listitem>
55 </varlistentry>
56 <varlistentry>
57 <term>&VIDIOC-REQBUFS;</term>
58 <listitem><para>Will allocate multi-planar buffers as requested.</para></listitem>
59 </varlistentry>
60 </variablelist>
61 </section>
62</section>
diff --git a/Documentation/DocBook/v4l/subdev-formats.xml b/Documentation/DocBook/v4l/subdev-formats.xml
new file mode 100644
index 000000000000..7041127d6dfc
--- /dev/null
+++ b/Documentation/DocBook/v4l/subdev-formats.xml
@@ -0,0 +1,2467 @@
1<section id="v4l2-mbus-format">
2 <title>Media Bus Formats</title>
3
4 <table pgwide="1" frame="none" id="v4l2-mbus-framefmt">
5 <title>struct <structname>v4l2_mbus_framefmt</structname></title>
6 <tgroup cols="3">
7 &cs-str;
8 <tbody valign="top">
9 <row>
10 <entry>__u32</entry>
11 <entry><structfield>width</structfield></entry>
12 <entry>Image width, in pixels.</entry>
13 </row>
14 <row>
15 <entry>__u32</entry>
16 <entry><structfield>height</structfield></entry>
17 <entry>Image height, in pixels.</entry>
18 </row>
19 <row>
20 <entry>__u32</entry>
21 <entry><structfield>code</structfield></entry>
22 <entry>Format code, from &v4l2-mbus-pixelcode;.</entry>
23 </row>
24 <row>
25 <entry>__u32</entry>
26 <entry><structfield>field</structfield></entry>
27 <entry>Field order, from &v4l2-field;. See
28 <xref linkend="field-order" /> for details.</entry>
29 </row>
30 <row>
31 <entry>__u32</entry>
32 <entry><structfield>colorspace</structfield></entry>
33 <entry>Image colorspace, from &v4l2-colorspace;. See
34 <xref linkend="colorspaces" /> for details.</entry>
35 </row>
36 <row>
37 <entry>__u32</entry>
38 <entry><structfield>reserved</structfield>[7]</entry>
39 <entry>Reserved for future extensions. Applications and drivers must
40 set the array to zero.</entry>
41 </row>
42 </tbody>
43 </tgroup>
44 </table>
45
46 <section id="v4l2-mbus-pixelcode">
47 <title>Media Bus Pixel Codes</title>
48
49 <para>The media bus pixel codes describe image formats as flowing over
50 physical busses (both between separate physical components and inside SoC
51 devices). This should not be confused with the V4L2 pixel formats that
52 describe, using four character codes, image formats as stored in memory.
53 </para>
54
55 <para>While there is a relationship between image formats on busses and
56 image formats in memory (a raw Bayer image won't be magically converted to
57 JPEG just by storing it to memory), there is no one-to-one correspondance
58 between them.</para>
59
60 <section>
61 <title>Packed RGB Formats</title>
62
63 <para>Those formats transfer pixel data as red, green and blue components.
64 The format code is made of the following information.
65 <itemizedlist>
66 <listitem><para>The red, green and blue components order code, as encoded in a
67 pixel sample. Possible values are RGB and BGR.</para></listitem>
68 <listitem><para>The number of bits per component, for each component. The values
69 can be different for all components. Common values are 555 and 565.</para>
70 </listitem>
71 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
72 the bus width must be transferred in multiple samples. Common values are
73 1 and 2.</para></listitem>
74 <listitem><para>The bus width.</para></listitem>
75 <listitem><para>For formats where the total number of bits per pixel is smaller
76 than the number of bus samples per pixel times the bus width, a padding
77 value stating if the bytes are padded in their most high order bits
78 (PADHI) or low order bits (PADLO).</para></listitem>
79 <listitem><para>For formats where the number of bus samples per pixel is larger
80 than 1, an endianness value stating if the pixel is transferred MSB first
81 (BE) or LSB first (LE).</para></listitem>
82 </itemizedlist>
83 </para>
84
85 <para>For instance, a format where pixels are encoded as 5-bits red, 5-bits
86 green and 5-bit blue values padded on the high bit, transferred as 2 8-bit
87 samples per pixel with the most significant bits (padding, red and half of
88 the green value) transferred first will be named
89 <constant>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</constant>.
90 </para>
91
92 <para>The following tables list existing packet RGB formats.</para>
93
94 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-rgb">
95 <title>RGB formats</title>
96 <tgroup cols="11">
97 <colspec colname="id" align="left" />
98 <colspec colname="code" align="center"/>
99 <colspec colname="bit" />
100 <colspec colnum="4" colname="b07" align="center" />
101 <colspec colnum="5" colname="b06" align="center" />
102 <colspec colnum="6" colname="b05" align="center" />
103 <colspec colnum="7" colname="b04" align="center" />
104 <colspec colnum="8" colname="b03" align="center" />
105 <colspec colnum="9" colname="b02" align="center" />
106 <colspec colnum="10" colname="b01" align="center" />
107 <colspec colnum="11" colname="b00" align="center" />
108 <spanspec namest="b07" nameend="b00" spanname="b0" />
109 <thead>
110 <row>
111 <entry>Identifier</entry>
112 <entry>Code</entry>
113 <entry></entry>
114 <entry spanname="b0">Data organization</entry>
115 </row>
116 <row>
117 <entry></entry>
118 <entry></entry>
119 <entry>Bit</entry>
120 <entry>7</entry>
121 <entry>6</entry>
122 <entry>5</entry>
123 <entry>4</entry>
124 <entry>3</entry>
125 <entry>2</entry>
126 <entry>1</entry>
127 <entry>0</entry>
128 </row>
129 </thead>
130 <tbody valign="top">
131 <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-BE">
132 <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE</entry>
133 <entry>0x1001</entry>
134 <entry></entry>
135 <entry>0</entry>
136 <entry>0</entry>
137 <entry>0</entry>
138 <entry>0</entry>
139 <entry>r<subscript>3</subscript></entry>
140 <entry>r<subscript>2</subscript></entry>
141 <entry>r<subscript>1</subscript></entry>
142 <entry>r<subscript>0</subscript></entry>
143 </row>
144 <row>
145 <entry></entry>
146 <entry></entry>
147 <entry></entry>
148 <entry>g<subscript>3</subscript></entry>
149 <entry>g<subscript>2</subscript></entry>
150 <entry>g<subscript>1</subscript></entry>
151 <entry>g<subscript>0</subscript></entry>
152 <entry>b<subscript>3</subscript></entry>
153 <entry>b<subscript>2</subscript></entry>
154 <entry>b<subscript>1</subscript></entry>
155 <entry>b<subscript>0</subscript></entry>
156 </row>
157 <row id="V4L2-MBUS-FMT-RGB444-2X8-PADHI-LE">
158 <entry>V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE</entry>
159 <entry>0x1002</entry>
160 <entry></entry>
161 <entry>g<subscript>3</subscript></entry>
162 <entry>g<subscript>2</subscript></entry>
163 <entry>g<subscript>1</subscript></entry>
164 <entry>g<subscript>0</subscript></entry>
165 <entry>b<subscript>3</subscript></entry>
166 <entry>b<subscript>2</subscript></entry>
167 <entry>b<subscript>1</subscript></entry>
168 <entry>b<subscript>0</subscript></entry>
169 </row>
170 <row>
171 <entry></entry>
172 <entry></entry>
173 <entry></entry>
174 <entry>0</entry>
175 <entry>0</entry>
176 <entry>0</entry>
177 <entry>0</entry>
178 <entry>r<subscript>3</subscript></entry>
179 <entry>r<subscript>2</subscript></entry>
180 <entry>r<subscript>1</subscript></entry>
181 <entry>r<subscript>0</subscript></entry>
182 </row>
183 <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-BE">
184 <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE</entry>
185 <entry>0x1003</entry>
186 <entry></entry>
187 <entry>0</entry>
188 <entry>r<subscript>4</subscript></entry>
189 <entry>r<subscript>3</subscript></entry>
190 <entry>r<subscript>2</subscript></entry>
191 <entry>r<subscript>1</subscript></entry>
192 <entry>r<subscript>0</subscript></entry>
193 <entry>g<subscript>4</subscript></entry>
194 <entry>g<subscript>3</subscript></entry>
195 </row>
196 <row>
197 <entry></entry>
198 <entry></entry>
199 <entry></entry>
200 <entry>g<subscript>2</subscript></entry>
201 <entry>g<subscript>1</subscript></entry>
202 <entry>g<subscript>0</subscript></entry>
203 <entry>b<subscript>4</subscript></entry>
204 <entry>b<subscript>3</subscript></entry>
205 <entry>b<subscript>2</subscript></entry>
206 <entry>b<subscript>1</subscript></entry>
207 <entry>b<subscript>0</subscript></entry>
208 </row>
209 <row id="V4L2-MBUS-FMT-RGB555-2X8-PADHI-LE">
210 <entry>V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE</entry>
211 <entry>0x1004</entry>
212 <entry></entry>
213 <entry>g<subscript>2</subscript></entry>
214 <entry>g<subscript>1</subscript></entry>
215 <entry>g<subscript>0</subscript></entry>
216 <entry>b<subscript>4</subscript></entry>
217 <entry>b<subscript>3</subscript></entry>
218 <entry>b<subscript>2</subscript></entry>
219 <entry>b<subscript>1</subscript></entry>
220 <entry>b<subscript>0</subscript></entry>
221 </row>
222 <row>
223 <entry></entry>
224 <entry></entry>
225 <entry></entry>
226 <entry>0</entry>
227 <entry>r<subscript>4</subscript></entry>
228 <entry>r<subscript>3</subscript></entry>
229 <entry>r<subscript>2</subscript></entry>
230 <entry>r<subscript>1</subscript></entry>
231 <entry>r<subscript>0</subscript></entry>
232 <entry>g<subscript>4</subscript></entry>
233 <entry>g<subscript>3</subscript></entry>
234 </row>
235 <row id="V4L2-MBUS-FMT-BGR565-2X8-BE">
236 <entry>V4L2_MBUS_FMT_BGR565_2X8_BE</entry>
237 <entry>0x1005</entry>
238 <entry></entry>
239 <entry>b<subscript>4</subscript></entry>
240 <entry>b<subscript>3</subscript></entry>
241 <entry>b<subscript>2</subscript></entry>
242 <entry>b<subscript>1</subscript></entry>
243 <entry>b<subscript>0</subscript></entry>
244 <entry>g<subscript>5</subscript></entry>
245 <entry>g<subscript>4</subscript></entry>
246 <entry>g<subscript>3</subscript></entry>
247 </row>
248 <row>
249 <entry></entry>
250 <entry></entry>
251 <entry></entry>
252 <entry>g<subscript>2</subscript></entry>
253 <entry>g<subscript>1</subscript></entry>
254 <entry>g<subscript>0</subscript></entry>
255 <entry>r<subscript>4</subscript></entry>
256 <entry>r<subscript>3</subscript></entry>
257 <entry>r<subscript>2</subscript></entry>
258 <entry>r<subscript>1</subscript></entry>
259 <entry>r<subscript>0</subscript></entry>
260 </row>
261 <row id="V4L2-MBUS-FMT-BGR565-2X8-LE">
262 <entry>V4L2_MBUS_FMT_BGR565_2X8_LE</entry>
263 <entry>0x1006</entry>
264 <entry></entry>
265 <entry>g<subscript>2</subscript></entry>
266 <entry>g<subscript>1</subscript></entry>
267 <entry>g<subscript>0</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>
275 <entry></entry>
276 <entry></entry>
277 <entry></entry>
278 <entry>b<subscript>4</subscript></entry>
279 <entry>b<subscript>3</subscript></entry>
280 <entry>b<subscript>2</subscript></entry>
281 <entry>b<subscript>1</subscript></entry>
282 <entry>b<subscript>0</subscript></entry>
283 <entry>g<subscript>5</subscript></entry>
284 <entry>g<subscript>4</subscript></entry>
285 <entry>g<subscript>3</subscript></entry>
286 </row>
287 <row id="V4L2-MBUS-FMT-RGB565-2X8-BE">
288 <entry>V4L2_MBUS_FMT_RGB565_2X8_BE</entry>
289 <entry>0x1007</entry>
290 <entry></entry>
291 <entry>r<subscript>4</subscript></entry>
292 <entry>r<subscript>3</subscript></entry>
293 <entry>r<subscript>2</subscript></entry>
294 <entry>r<subscript>1</subscript></entry>
295 <entry>r<subscript>0</subscript></entry>
296 <entry>g<subscript>5</subscript></entry>
297 <entry>g<subscript>4</subscript></entry>
298 <entry>g<subscript>3</subscript></entry>
299 </row>
300 <row>
301 <entry></entry>
302 <entry></entry>
303 <entry></entry>
304 <entry>g<subscript>2</subscript></entry>
305 <entry>g<subscript>1</subscript></entry>
306 <entry>g<subscript>0</subscript></entry>
307 <entry>b<subscript>4</subscript></entry>
308 <entry>b<subscript>3</subscript></entry>
309 <entry>b<subscript>2</subscript></entry>
310 <entry>b<subscript>1</subscript></entry>
311 <entry>b<subscript>0</subscript></entry>
312 </row>
313 <row id="V4L2-MBUS-FMT-RGB565-2X8-LE">
314 <entry>V4L2_MBUS_FMT_RGB565_2X8_LE</entry>
315 <entry>0x1008</entry>
316 <entry></entry>
317 <entry>g<subscript>2</subscript></entry>
318 <entry>g<subscript>1</subscript></entry>
319 <entry>g<subscript>0</subscript></entry>
320 <entry>b<subscript>4</subscript></entry>
321 <entry>b<subscript>3</subscript></entry>
322 <entry>b<subscript>2</subscript></entry>
323 <entry>b<subscript>1</subscript></entry>
324 <entry>b<subscript>0</subscript></entry>
325 </row>
326 <row>
327 <entry></entry>
328 <entry></entry>
329 <entry></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>g<subscript>5</subscript></entry>
336 <entry>g<subscript>4</subscript></entry>
337 <entry>g<subscript>3</subscript></entry>
338 </row>
339 </tbody>
340 </tgroup>
341 </table>
342 </section>
343
344 <section>
345 <title>Bayer Formats</title>
346
347 <para>Those formats transfer pixel data as red, green and blue components.
348 The format code is made of the following information.
349 <itemizedlist>
350 <listitem><para>The red, green and blue components order code, as encoded in a
351 pixel sample. The possible values are shown in <xref
352 linkend="bayer-patterns" />.</para></listitem>
353 <listitem><para>The number of bits per pixel component. All components are
354 transferred on the same number of bits. Common values are 8, 10 and 12.</para>
355 </listitem>
356 <listitem><para>If the pixel components are DPCM-compressed, a mention of the
357 DPCM compression and the number of bits per compressed pixel component.</para>
358 </listitem>
359 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
360 the bus width must be transferred in multiple samples. Common values are
361 1 and 2.</para></listitem>
362 <listitem><para>The bus width.</para></listitem>
363 <listitem><para>For formats where the total number of bits per pixel is smaller
364 than the number of bus samples per pixel times the bus width, a padding
365 value stating if the bytes are padded in their most high order bits
366 (PADHI) or low order bits (PADLO).</para></listitem>
367 <listitem><para>For formats where the number of bus samples per pixel is larger
368 than 1, an endianness value stating if the pixel is transferred MSB first
369 (BE) or LSB first (LE).</para></listitem>
370 </itemizedlist>
371 </para>
372
373 <para>For instance, a format with uncompressed 10-bit Bayer components
374 arranged in a red, green, green, blue pattern transferred as 2 8-bit
375 samples per pixel with the least significant bits transferred first will
376 be named <constant>V4L2_MBUS_FMT_SRGGB10_2X8_PADHI_LE</constant>.
377 </para>
378
379 <figure id="bayer-patterns">
380 <title>Bayer Patterns</title>
381 <mediaobject>
382 <imageobject>
383 <imagedata fileref="bayer.pdf" format="PS" />
384 </imageobject>
385 <imageobject>
386 <imagedata fileref="bayer.png" format="PNG" />
387 </imageobject>
388 <textobject>
389 <phrase>Bayer filter color patterns</phrase>
390 </textobject>
391 </mediaobject>
392 </figure>
393
394 <para>The following table lists existing packet Bayer formats. The data
395 organization is given as an example for the first pixel only.</para>
396
397 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-bayer">
398 <title>Bayer Formats</title>
399 <tgroup cols="15">
400 <colspec colname="id" align="left" />
401 <colspec colname="code" align="center"/>
402 <colspec colname="bit" />
403 <colspec colnum="4" colname="b11" align="center" />
404 <colspec colnum="5" colname="b10" align="center" />
405 <colspec colnum="6" colname="b09" align="center" />
406 <colspec colnum="7" colname="b08" align="center" />
407 <colspec colnum="8" colname="b07" align="center" />
408 <colspec colnum="9" colname="b06" align="center" />
409 <colspec colnum="10" colname="b05" align="center" />
410 <colspec colnum="11" colname="b04" align="center" />
411 <colspec colnum="12" colname="b03" align="center" />
412 <colspec colnum="13" colname="b02" align="center" />
413 <colspec colnum="14" colname="b01" align="center" />
414 <colspec colnum="15" colname="b00" align="center" />
415 <spanspec namest="b11" nameend="b00" spanname="b0" />
416 <thead>
417 <row>
418 <entry>Identifier</entry>
419 <entry>Code</entry>
420 <entry></entry>
421 <entry spanname="b0">Data organization</entry>
422 </row>
423 <row>
424 <entry></entry>
425 <entry></entry>
426 <entry>Bit</entry>
427 <entry>11</entry>
428 <entry>10</entry>
429 <entry>9</entry>
430 <entry>8</entry>
431 <entry>7</entry>
432 <entry>6</entry>
433 <entry>5</entry>
434 <entry>4</entry>
435 <entry>3</entry>
436 <entry>2</entry>
437 <entry>1</entry>
438 <entry>0</entry>
439 </row>
440 </thead>
441 <tbody valign="top">
442 <row id="V4L2-MBUS-FMT-SBGGR8-1X8">
443 <entry>V4L2_MBUS_FMT_SBGGR8_1X8</entry>
444 <entry>0x3001</entry>
445 <entry></entry>
446 <entry>-</entry>
447 <entry>-</entry>
448 <entry>-</entry>
449 <entry>-</entry>
450 <entry>b<subscript>7</subscript></entry>
451 <entry>b<subscript>6</subscript></entry>
452 <entry>b<subscript>5</subscript></entry>
453 <entry>b<subscript>4</subscript></entry>
454 <entry>b<subscript>3</subscript></entry>
455 <entry>b<subscript>2</subscript></entry>
456 <entry>b<subscript>1</subscript></entry>
457 <entry>b<subscript>0</subscript></entry>
458 </row>
459 <row id="V4L2-MBUS-FMT-SGRBG8-1X8">
460 <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry>
461 <entry>0x3002</entry>
462 <entry></entry>
463 <entry>-</entry>
464 <entry>-</entry>
465 <entry>-</entry>
466 <entry>-</entry>
467 <entry>g<subscript>7</subscript></entry>
468 <entry>g<subscript>6</subscript></entry>
469 <entry>g<subscript>5</subscript></entry>
470 <entry>g<subscript>4</subscript></entry>
471 <entry>g<subscript>3</subscript></entry>
472 <entry>g<subscript>2</subscript></entry>
473 <entry>g<subscript>1</subscript></entry>
474 <entry>g<subscript>0</subscript></entry>
475 </row>
476 <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8">
477 <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry>
478 <entry>0x300b</entry>
479 <entry></entry>
480 <entry>-</entry>
481 <entry>-</entry>
482 <entry>-</entry>
483 <entry>-</entry>
484 <entry>b<subscript>7</subscript></entry>
485 <entry>b<subscript>6</subscript></entry>
486 <entry>b<subscript>5</subscript></entry>
487 <entry>b<subscript>4</subscript></entry>
488 <entry>b<subscript>3</subscript></entry>
489 <entry>b<subscript>2</subscript></entry>
490 <entry>b<subscript>1</subscript></entry>
491 <entry>b<subscript>0</subscript></entry>
492 </row>
493 <row id="V4L2-MBUS-FMT-SGBRG10-DPCM8-1X8">
494 <entry>V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8</entry>
495 <entry>0x300c</entry>
496 <entry></entry>
497 <entry>-</entry>
498 <entry>-</entry>
499 <entry>-</entry>
500 <entry>-</entry>
501 <entry>g<subscript>7</subscript></entry>
502 <entry>g<subscript>6</subscript></entry>
503 <entry>g<subscript>5</subscript></entry>
504 <entry>g<subscript>4</subscript></entry>
505 <entry>g<subscript>3</subscript></entry>
506 <entry>g<subscript>2</subscript></entry>
507 <entry>g<subscript>1</subscript></entry>
508 <entry>g<subscript>0</subscript></entry>
509 </row>
510 <row id="V4L2-MBUS-FMT-SGRBG10-DPCM8-1X8">
511 <entry>V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8</entry>
512 <entry>0x3009</entry>
513 <entry></entry>
514 <entry>-</entry>
515 <entry>-</entry>
516 <entry>-</entry>
517 <entry>-</entry>
518 <entry>g<subscript>7</subscript></entry>
519 <entry>g<subscript>6</subscript></entry>
520 <entry>g<subscript>5</subscript></entry>
521 <entry>g<subscript>4</subscript></entry>
522 <entry>g<subscript>3</subscript></entry>
523 <entry>g<subscript>2</subscript></entry>
524 <entry>g<subscript>1</subscript></entry>
525 <entry>g<subscript>0</subscript></entry>
526 </row>
527 <row id="V4L2-MBUS-FMT-SRGGB10-DPCM8-1X8">
528 <entry>V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8</entry>
529 <entry>0x300d</entry>
530 <entry></entry>
531 <entry>-</entry>
532 <entry>-</entry>
533 <entry>-</entry>
534 <entry>-</entry>
535 <entry>r<subscript>7</subscript></entry>
536 <entry>r<subscript>6</subscript></entry>
537 <entry>r<subscript>5</subscript></entry>
538 <entry>r<subscript>4</subscript></entry>
539 <entry>r<subscript>3</subscript></entry>
540 <entry>r<subscript>2</subscript></entry>
541 <entry>r<subscript>1</subscript></entry>
542 <entry>r<subscript>0</subscript></entry>
543 </row>
544 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-BE">
545 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE</entry>
546 <entry>0x3003</entry>
547 <entry></entry>
548 <entry>-</entry>
549 <entry>-</entry>
550 <entry>-</entry>
551 <entry>-</entry>
552 <entry>0</entry>
553 <entry>0</entry>
554 <entry>0</entry>
555 <entry>0</entry>
556 <entry>0</entry>
557 <entry>0</entry>
558 <entry>b<subscript>9</subscript></entry>
559 <entry>b<subscript>8</subscript></entry>
560 </row>
561 <row>
562 <entry></entry>
563 <entry></entry>
564 <entry></entry>
565 <entry>-</entry>
566 <entry>-</entry>
567 <entry>-</entry>
568 <entry>-</entry>
569 <entry>b<subscript>7</subscript></entry>
570 <entry>b<subscript>6</subscript></entry>
571 <entry>b<subscript>5</subscript></entry>
572 <entry>b<subscript>4</subscript></entry>
573 <entry>b<subscript>3</subscript></entry>
574 <entry>b<subscript>2</subscript></entry>
575 <entry>b<subscript>1</subscript></entry>
576 <entry>b<subscript>0</subscript></entry>
577 </row>
578 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADHI-LE">
579 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE</entry>
580 <entry>0x3004</entry>
581 <entry></entry>
582 <entry>-</entry>
583 <entry>-</entry>
584 <entry>-</entry>
585 <entry>-</entry>
586 <entry>b<subscript>7</subscript></entry>
587 <entry>b<subscript>6</subscript></entry>
588 <entry>b<subscript>5</subscript></entry>
589 <entry>b<subscript>4</subscript></entry>
590 <entry>b<subscript>3</subscript></entry>
591 <entry>b<subscript>2</subscript></entry>
592 <entry>b<subscript>1</subscript></entry>
593 <entry>b<subscript>0</subscript></entry>
594 </row>
595 <row>
596 <entry></entry>
597 <entry></entry>
598 <entry></entry>
599 <entry>-</entry>
600 <entry>-</entry>
601 <entry>-</entry>
602 <entry>-</entry>
603 <entry>0</entry>
604 <entry>0</entry>
605 <entry>0</entry>
606 <entry>0</entry>
607 <entry>0</entry>
608 <entry>0</entry>
609 <entry>b<subscript>9</subscript></entry>
610 <entry>b<subscript>8</subscript></entry>
611 </row>
612 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-BE">
613 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE</entry>
614 <entry>0x3005</entry>
615 <entry></entry>
616 <entry>-</entry>
617 <entry>-</entry>
618 <entry>-</entry>
619 <entry>-</entry>
620 <entry>b<subscript>9</subscript></entry>
621 <entry>b<subscript>8</subscript></entry>
622 <entry>b<subscript>7</subscript></entry>
623 <entry>b<subscript>6</subscript></entry>
624 <entry>b<subscript>5</subscript></entry>
625 <entry>b<subscript>4</subscript></entry>
626 <entry>b<subscript>3</subscript></entry>
627 <entry>b<subscript>2</subscript></entry>
628 </row>
629 <row>
630 <entry></entry>
631 <entry></entry>
632 <entry></entry>
633 <entry>-</entry>
634 <entry>-</entry>
635 <entry>-</entry>
636 <entry>-</entry>
637 <entry>b<subscript>1</subscript></entry>
638 <entry>b<subscript>0</subscript></entry>
639 <entry>0</entry>
640 <entry>0</entry>
641 <entry>0</entry>
642 <entry>0</entry>
643 <entry>0</entry>
644 <entry>0</entry>
645 </row>
646 <row id="V4L2-MBUS-FMT-SBGGR10-2X8-PADLO-LE">
647 <entry>V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE</entry>
648 <entry>0x3006</entry>
649 <entry></entry>
650 <entry>-</entry>
651 <entry>-</entry>
652 <entry>-</entry>
653 <entry>-</entry>
654 <entry>b<subscript>1</subscript></entry>
655 <entry>b<subscript>0</subscript></entry>
656 <entry>0</entry>
657 <entry>0</entry>
658 <entry>0</entry>
659 <entry>0</entry>
660 <entry>0</entry>
661 <entry>0</entry>
662 </row>
663 <row>
664 <entry></entry>
665 <entry></entry>
666 <entry></entry>
667 <entry>-</entry>
668 <entry>-</entry>
669 <entry>-</entry>
670 <entry>-</entry>
671 <entry>b<subscript>9</subscript></entry>
672 <entry>b<subscript>8</subscript></entry>
673 <entry>b<subscript>7</subscript></entry>
674 <entry>b<subscript>6</subscript></entry>
675 <entry>b<subscript>5</subscript></entry>
676 <entry>b<subscript>4</subscript></entry>
677 <entry>b<subscript>3</subscript></entry>
678 <entry>b<subscript>2</subscript></entry>
679 </row>
680 <row id="V4L2-MBUS-FMT-SBGGR10-1X10">
681 <entry>V4L2_MBUS_FMT_SBGGR10_1X10</entry>
682 <entry>0x3007</entry>
683 <entry></entry>
684 <entry>-</entry>
685 <entry>-</entry>
686 <entry>b<subscript>9</subscript></entry>
687 <entry>b<subscript>8</subscript></entry>
688 <entry>b<subscript>7</subscript></entry>
689 <entry>b<subscript>6</subscript></entry>
690 <entry>b<subscript>5</subscript></entry>
691 <entry>b<subscript>4</subscript></entry>
692 <entry>b<subscript>3</subscript></entry>
693 <entry>b<subscript>2</subscript></entry>
694 <entry>b<subscript>1</subscript></entry>
695 <entry>b<subscript>0</subscript></entry>
696 </row>
697 <row id="V4L2-MBUS-FMT-SGBRG10-1X10">
698 <entry>V4L2_MBUS_FMT_SGBRG10_1X10</entry>
699 <entry>0x300e</entry>
700 <entry></entry>
701 <entry>-</entry>
702 <entry>-</entry>
703 <entry>g<subscript>9</subscript></entry>
704 <entry>g<subscript>8</subscript></entry>
705 <entry>g<subscript>7</subscript></entry>
706 <entry>g<subscript>6</subscript></entry>
707 <entry>g<subscript>5</subscript></entry>
708 <entry>g<subscript>4</subscript></entry>
709 <entry>g<subscript>3</subscript></entry>
710 <entry>g<subscript>2</subscript></entry>
711 <entry>g<subscript>1</subscript></entry>
712 <entry>g<subscript>0</subscript></entry>
713 </row>
714 <row id="V4L2-MBUS-FMT-SGRBG10-1X10">
715 <entry>V4L2_MBUS_FMT_SGRBG10_1X10</entry>
716 <entry>0x300a</entry>
717 <entry></entry>
718 <entry>-</entry>
719 <entry>-</entry>
720 <entry>g<subscript>9</subscript></entry>
721 <entry>g<subscript>8</subscript></entry>
722 <entry>g<subscript>7</subscript></entry>
723 <entry>g<subscript>6</subscript></entry>
724 <entry>g<subscript>5</subscript></entry>
725 <entry>g<subscript>4</subscript></entry>
726 <entry>g<subscript>3</subscript></entry>
727 <entry>g<subscript>2</subscript></entry>
728 <entry>g<subscript>1</subscript></entry>
729 <entry>g<subscript>0</subscript></entry>
730 </row>
731 <row id="V4L2-MBUS-FMT-SRGGB10-1X10">
732 <entry>V4L2_MBUS_FMT_SRGGB10_1X10</entry>
733 <entry>0x300f</entry>
734 <entry></entry>
735 <entry>-</entry>
736 <entry>-</entry>
737 <entry>r<subscript>9</subscript></entry>
738 <entry>r<subscript>8</subscript></entry>
739 <entry>r<subscript>7</subscript></entry>
740 <entry>r<subscript>6</subscript></entry>
741 <entry>r<subscript>5</subscript></entry>
742 <entry>r<subscript>4</subscript></entry>
743 <entry>r<subscript>3</subscript></entry>
744 <entry>r<subscript>2</subscript></entry>
745 <entry>r<subscript>1</subscript></entry>
746 <entry>r<subscript>0</subscript></entry>
747 </row>
748 <row id="V4L2-MBUS-FMT-SBGGR12-1X12">
749 <entry>V4L2_MBUS_FMT_SBGGR12_1X12</entry>
750 <entry>0x3008</entry>
751 <entry></entry>
752 <entry>b<subscript>11</subscript></entry>
753 <entry>b<subscript>10</subscript></entry>
754 <entry>b<subscript>9</subscript></entry>
755 <entry>b<subscript>8</subscript></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-MBUS-FMT-SGBRG12-1X12">
766 <entry>V4L2_MBUS_FMT_SGBRG12_1X12</entry>
767 <entry>0x3010</entry>
768 <entry></entry>
769 <entry>g<subscript>11</subscript></entry>
770 <entry>g<subscript>10</subscript></entry>
771 <entry>g<subscript>9</subscript></entry>
772 <entry>g<subscript>8</subscript></entry>
773 <entry>g<subscript>7</subscript></entry>
774 <entry>g<subscript>6</subscript></entry>
775 <entry>g<subscript>5</subscript></entry>
776 <entry>g<subscript>4</subscript></entry>
777 <entry>g<subscript>3</subscript></entry>
778 <entry>g<subscript>2</subscript></entry>
779 <entry>g<subscript>1</subscript></entry>
780 <entry>g<subscript>0</subscript></entry>
781 </row>
782 <row id="V4L2-MBUS-FMT-SGRBG12-1X12">
783 <entry>V4L2_MBUS_FMT_SGRBG12_1X12</entry>
784 <entry>0x3011</entry>
785 <entry></entry>
786 <entry>g<subscript>11</subscript></entry>
787 <entry>g<subscript>10</subscript></entry>
788 <entry>g<subscript>9</subscript></entry>
789 <entry>g<subscript>8</subscript></entry>
790 <entry>g<subscript>7</subscript></entry>
791 <entry>g<subscript>6</subscript></entry>
792 <entry>g<subscript>5</subscript></entry>
793 <entry>g<subscript>4</subscript></entry>
794 <entry>g<subscript>3</subscript></entry>
795 <entry>g<subscript>2</subscript></entry>
796 <entry>g<subscript>1</subscript></entry>
797 <entry>g<subscript>0</subscript></entry>
798 </row>
799 <row id="V4L2-MBUS-FMT-SRGGB12-1X12">
800 <entry>V4L2_MBUS_FMT_SRGGB12_1X12</entry>
801 <entry>0x3012</entry>
802 <entry></entry>
803 <entry>r<subscript>11</subscript></entry>
804 <entry>r<subscript>10</subscript></entry>
805 <entry>r<subscript>9</subscript></entry>
806 <entry>r<subscript>8</subscript></entry>
807 <entry>r<subscript>7</subscript></entry>
808 <entry>r<subscript>6</subscript></entry>
809 <entry>r<subscript>5</subscript></entry>
810 <entry>r<subscript>4</subscript></entry>
811 <entry>r<subscript>3</subscript></entry>
812 <entry>r<subscript>2</subscript></entry>
813 <entry>r<subscript>1</subscript></entry>
814 <entry>r<subscript>0</subscript></entry>
815 </row>
816 </tbody>
817 </tgroup>
818 </table>
819 </section>
820
821 <section>
822 <title>Packed YUV Formats</title>
823
824 <para>Those data formats transfer pixel data as (possibly downsampled) Y, U
825 and V components. The format code is made of the following information.
826 <itemizedlist>
827 <listitem><para>The Y, U and V components order code, as transferred on the
828 bus. Possible values are YUYV, UYVY, YVYU and VYUY.</para></listitem>
829 <listitem><para>The number of bits per pixel component. All components are
830 transferred on the same number of bits. Common values are 8, 10 and 12.</para>
831 </listitem>
832 <listitem><para>The number of bus samples per pixel. Pixels that are wider than
833 the bus width must be transferred in multiple samples. Common values are
834 1, 1.5 (encoded as 1_5) and 2.</para></listitem>
835 <listitem><para>The bus width. When the bus width is larger than the number of
836 bits per pixel component, several components are packed in a single bus
837 sample. The components are ordered as specified by the order code, with
838 components on the left of the code transferred in the high order bits.
839 Common values are 8 and 16.</para>
840 </listitem>
841 </itemizedlist>
842 </para>
843
844 <para>For instance, a format where pixels are encoded as 8-bit YUV values
845 downsampled to 4:2:2 and transferred as 2 8-bit bus samples per pixel in the
846 U, Y, V, Y order will be named <constant>V4L2_MBUS_FMT_UYVY8_2X8</constant>.
847 </para>
848
849 <para>The following table lisst existing packet YUV formats.</para>
850
851 <table pgwide="0" frame="none" id="v4l2-mbus-pixelcode-yuv8">
852 <title>YUV Formats</title>
853 <tgroup cols="23">
854 <colspec colname="id" align="left" />
855 <colspec colname="code" align="center"/>
856 <colspec colname="bit" />
857 <colspec colnum="4" colname="b19" align="center" />
858 <colspec colnum="5" colname="b18" align="center" />
859 <colspec colnum="6" colname="b17" align="center" />
860 <colspec colnum="7" colname="b16" align="center" />
861 <colspec colnum="8" colname="b15" align="center" />
862 <colspec colnum="9" colname="b14" align="center" />
863 <colspec colnum="10" colname="b13" align="center" />
864 <colspec colnum="11" colname="b12" align="center" />
865 <colspec colnum="12" colname="b11" align="center" />
866 <colspec colnum="13" colname="b10" align="center" />
867 <colspec colnum="14" colname="b09" align="center" />
868 <colspec colnum="15" colname="b08" align="center" />
869 <colspec colnum="16" colname="b07" align="center" />
870 <colspec colnum="17" colname="b06" align="center" />
871 <colspec colnum="18" colname="b05" align="center" />
872 <colspec colnum="19" colname="b04" align="center" />
873 <colspec colnum="20" colname="b03" align="center" />
874 <colspec colnum="21" colname="b02" align="center" />
875 <colspec colnum="22" colname="b01" align="center" />
876 <colspec colnum="23" colname="b00" align="center" />
877 <spanspec namest="b19" nameend="b00" spanname="b0" />
878 <thead>
879 <row>
880 <entry>Identifier</entry>
881 <entry>Code</entry>
882 <entry></entry>
883 <entry spanname="b0">Data organization</entry>
884 </row>
885 <row>
886 <entry></entry>
887 <entry></entry>
888 <entry>Bit</entry>
889 <entry>19</entry>
890 <entry>18</entry>
891 <entry>17</entry>
892 <entry>16</entry>
893 <entry>15</entry>
894 <entry>14</entry>
895 <entry>13</entry>
896 <entry>12</entry>
897 <entry>11</entry>
898 <entry>10</entry>
899 <entry>9</entry>
900 <entry>8</entry>
901 <entry>7</entry>
902 <entry>6</entry>
903 <entry>5</entry>
904 <entry>4</entry>
905 <entry>3</entry>
906 <entry>2</entry>
907 <entry>1</entry>
908 <entry>0</entry>
909 </row>
910 </thead>
911 <tbody valign="top">
912 <row id="V4L2-MBUS-FMT-Y8-1X8">
913 <entry>V4L2_MBUS_FMT_Y8_1X8</entry>
914 <entry>0x2001</entry>
915 <entry></entry>
916 <entry>-</entry>
917 <entry>-</entry>
918 <entry>-</entry>
919 <entry>-</entry>
920 <entry>-</entry>
921 <entry>-</entry>
922 <entry>-</entry>
923 <entry>-</entry>
924 <entry>-</entry>
925 <entry>-</entry>
926 <entry>-</entry>
927 <entry>-</entry>
928 <entry>y<subscript>7</subscript></entry>
929 <entry>y<subscript>6</subscript></entry>
930 <entry>y<subscript>5</subscript></entry>
931 <entry>y<subscript>4</subscript></entry>
932 <entry>y<subscript>3</subscript></entry>
933 <entry>y<subscript>2</subscript></entry>
934 <entry>y<subscript>1</subscript></entry>
935 <entry>y<subscript>0</subscript></entry>
936 </row>
937 <row id="V4L2-MBUS-FMT-UYVY8-1_5X8">
938 <entry>V4L2_MBUS_FMT_UYVY8_1_5X8</entry>
939 <entry>0x2002</entry>
940 <entry></entry>
941 <entry>-</entry>
942 <entry>-</entry>
943 <entry>-</entry>
944 <entry>-</entry>
945 <entry>-</entry>
946 <entry>-</entry>
947 <entry>-</entry>
948 <entry>-</entry>
949 <entry>-</entry>
950 <entry>-</entry>
951 <entry>-</entry>
952 <entry>-</entry>
953 <entry>u<subscript>7</subscript></entry>
954 <entry>u<subscript>6</subscript></entry>
955 <entry>u<subscript>5</subscript></entry>
956 <entry>u<subscript>4</subscript></entry>
957 <entry>u<subscript>3</subscript></entry>
958 <entry>u<subscript>2</subscript></entry>
959 <entry>u<subscript>1</subscript></entry>
960 <entry>u<subscript>0</subscript></entry>
961 </row>
962 <row>
963 <entry></entry>
964 <entry></entry>
965 <entry></entry>
966 <entry>-</entry>
967 <entry>-</entry>
968 <entry>-</entry>
969 <entry>-</entry>
970 <entry>-</entry>
971 <entry>-</entry>
972 <entry>-</entry>
973 <entry>-</entry>
974 <entry>-</entry>
975 <entry>-</entry>
976 <entry>-</entry>
977 <entry>-</entry>
978 <entry>y<subscript>7</subscript></entry>
979 <entry>y<subscript>6</subscript></entry>
980 <entry>y<subscript>5</subscript></entry>
981 <entry>y<subscript>4</subscript></entry>
982 <entry>y<subscript>3</subscript></entry>
983 <entry>y<subscript>2</subscript></entry>
984 <entry>y<subscript>1</subscript></entry>
985 <entry>y<subscript>0</subscript></entry>
986 </row>
987 <row>
988 <entry></entry>
989 <entry></entry>
990 <entry></entry>
991 <entry>-</entry>
992 <entry>-</entry>
993 <entry>-</entry>
994 <entry>-</entry>
995 <entry>-</entry>
996 <entry>-</entry>
997 <entry>-</entry>
998 <entry>-</entry>
999 <entry>-</entry>
1000 <entry>-</entry>
1001 <entry>-</entry>
1002 <entry>-</entry>
1003 <entry>y<subscript>7</subscript></entry>
1004 <entry>y<subscript>6</subscript></entry>
1005 <entry>y<subscript>5</subscript></entry>
1006 <entry>y<subscript>4</subscript></entry>
1007 <entry>y<subscript>3</subscript></entry>
1008 <entry>y<subscript>2</subscript></entry>
1009 <entry>y<subscript>1</subscript></entry>
1010 <entry>y<subscript>0</subscript></entry>
1011 </row>
1012 <row>
1013 <entry></entry>
1014 <entry></entry>
1015 <entry></entry>
1016 <entry>-</entry>
1017 <entry>-</entry>
1018 <entry>-</entry>
1019 <entry>-</entry>
1020 <entry>-</entry>
1021 <entry>-</entry>
1022 <entry>-</entry>
1023 <entry>-</entry>
1024 <entry>-</entry>
1025 <entry>-</entry>
1026 <entry>-</entry>
1027 <entry>-</entry>
1028 <entry>v<subscript>7</subscript></entry>
1029 <entry>v<subscript>6</subscript></entry>
1030 <entry>v<subscript>5</subscript></entry>
1031 <entry>v<subscript>4</subscript></entry>
1032 <entry>v<subscript>3</subscript></entry>
1033 <entry>v<subscript>2</subscript></entry>
1034 <entry>v<subscript>1</subscript></entry>
1035 <entry>v<subscript>0</subscript></entry>
1036 </row>
1037 <row>
1038 <entry></entry>
1039 <entry></entry>
1040 <entry></entry>
1041 <entry>-</entry>
1042 <entry>-</entry>
1043 <entry>-</entry>
1044 <entry>-</entry>
1045 <entry>-</entry>
1046 <entry>-</entry>
1047 <entry>-</entry>
1048 <entry>-</entry>
1049 <entry>-</entry>
1050 <entry>-</entry>
1051 <entry>-</entry>
1052 <entry>-</entry>
1053 <entry>y<subscript>7</subscript></entry>
1054 <entry>y<subscript>6</subscript></entry>
1055 <entry>y<subscript>5</subscript></entry>
1056 <entry>y<subscript>4</subscript></entry>
1057 <entry>y<subscript>3</subscript></entry>
1058 <entry>y<subscript>2</subscript></entry>
1059 <entry>y<subscript>1</subscript></entry>
1060 <entry>y<subscript>0</subscript></entry>
1061 </row>
1062 <row>
1063 <entry></entry>
1064 <entry></entry>
1065 <entry></entry>
1066 <entry>-</entry>
1067 <entry>-</entry>
1068 <entry>-</entry>
1069 <entry>-</entry>
1070 <entry>-</entry>
1071 <entry>-</entry>
1072 <entry>-</entry>
1073 <entry>-</entry>
1074 <entry>-</entry>
1075 <entry>-</entry>
1076 <entry>-</entry>
1077 <entry>-</entry>
1078 <entry>y<subscript>7</subscript></entry>
1079 <entry>y<subscript>6</subscript></entry>
1080 <entry>y<subscript>5</subscript></entry>
1081 <entry>y<subscript>4</subscript></entry>
1082 <entry>y<subscript>3</subscript></entry>
1083 <entry>y<subscript>2</subscript></entry>
1084 <entry>y<subscript>1</subscript></entry>
1085 <entry>y<subscript>0</subscript></entry>
1086 </row>
1087 <row id="V4L2-MBUS-FMT-VYUY8-1_5X8">
1088 <entry>V4L2_MBUS_FMT_VYUY8_1_5X8</entry>
1089 <entry>0x2003</entry>
1090 <entry></entry>
1091 <entry>-</entry>
1092 <entry>-</entry>
1093 <entry>-</entry>
1094 <entry>-</entry>
1095 <entry>-</entry>
1096 <entry>-</entry>
1097 <entry>-</entry>
1098 <entry>-</entry>
1099 <entry>-</entry>
1100 <entry>-</entry>
1101 <entry>-</entry>
1102 <entry>-</entry>
1103 <entry>v<subscript>7</subscript></entry>
1104 <entry>v<subscript>6</subscript></entry>
1105 <entry>v<subscript>5</subscript></entry>
1106 <entry>v<subscript>4</subscript></entry>
1107 <entry>v<subscript>3</subscript></entry>
1108 <entry>v<subscript>2</subscript></entry>
1109 <entry>v<subscript>1</subscript></entry>
1110 <entry>v<subscript>0</subscript></entry>
1111 </row>
1112 <row>
1113 <entry></entry>
1114 <entry></entry>
1115 <entry></entry>
1116 <entry>-</entry>
1117 <entry>-</entry>
1118 <entry>-</entry>
1119 <entry>-</entry>
1120 <entry>-</entry>
1121 <entry>-</entry>
1122 <entry>-</entry>
1123 <entry>-</entry>
1124 <entry>-</entry>
1125 <entry>-</entry>
1126 <entry>-</entry>
1127 <entry>-</entry>
1128 <entry>y<subscript>7</subscript></entry>
1129 <entry>y<subscript>6</subscript></entry>
1130 <entry>y<subscript>5</subscript></entry>
1131 <entry>y<subscript>4</subscript></entry>
1132 <entry>y<subscript>3</subscript></entry>
1133 <entry>y<subscript>2</subscript></entry>
1134 <entry>y<subscript>1</subscript></entry>
1135 <entry>y<subscript>0</subscript></entry>
1136 </row>
1137 <row>
1138 <entry></entry>
1139 <entry></entry>
1140 <entry></entry>
1141 <entry>-</entry>
1142 <entry>-</entry>
1143 <entry>-</entry>
1144 <entry>-</entry>
1145 <entry>-</entry>
1146 <entry>-</entry>
1147 <entry>-</entry>
1148 <entry>-</entry>
1149 <entry>-</entry>
1150 <entry>-</entry>
1151 <entry>-</entry>
1152 <entry>-</entry>
1153 <entry>y<subscript>7</subscript></entry>
1154 <entry>y<subscript>6</subscript></entry>
1155 <entry>y<subscript>5</subscript></entry>
1156 <entry>y<subscript>4</subscript></entry>
1157 <entry>y<subscript>3</subscript></entry>
1158 <entry>y<subscript>2</subscript></entry>
1159 <entry>y<subscript>1</subscript></entry>
1160 <entry>y<subscript>0</subscript></entry>
1161 </row>
1162 <row>
1163 <entry></entry>
1164 <entry></entry>
1165 <entry></entry>
1166 <entry>-</entry>
1167 <entry>-</entry>
1168 <entry>-</entry>
1169 <entry>-</entry>
1170 <entry>-</entry>
1171 <entry>-</entry>
1172 <entry>-</entry>
1173 <entry>-</entry>
1174 <entry>-</entry>
1175 <entry>-</entry>
1176 <entry>-</entry>
1177 <entry>-</entry>
1178 <entry>u<subscript>7</subscript></entry>
1179 <entry>u<subscript>6</subscript></entry>
1180 <entry>u<subscript>5</subscript></entry>
1181 <entry>u<subscript>4</subscript></entry>
1182 <entry>u<subscript>3</subscript></entry>
1183 <entry>u<subscript>2</subscript></entry>
1184 <entry>u<subscript>1</subscript></entry>
1185 <entry>u<subscript>0</subscript></entry>
1186 </row>
1187 <row>
1188 <entry></entry>
1189 <entry></entry>
1190 <entry></entry>
1191 <entry>-</entry>
1192 <entry>-</entry>
1193 <entry>-</entry>
1194 <entry>-</entry>
1195 <entry>-</entry>
1196 <entry>-</entry>
1197 <entry>-</entry>
1198 <entry>-</entry>
1199 <entry>-</entry>
1200 <entry>-</entry>
1201 <entry>-</entry>
1202 <entry>-</entry>
1203 <entry>y<subscript>7</subscript></entry>
1204 <entry>y<subscript>6</subscript></entry>
1205 <entry>y<subscript>5</subscript></entry>
1206 <entry>y<subscript>4</subscript></entry>
1207 <entry>y<subscript>3</subscript></entry>
1208 <entry>y<subscript>2</subscript></entry>
1209 <entry>y<subscript>1</subscript></entry>
1210 <entry>y<subscript>0</subscript></entry>
1211 </row>
1212 <row>
1213 <entry></entry>
1214 <entry></entry>
1215 <entry></entry>
1216 <entry>-</entry>
1217 <entry>-</entry>
1218 <entry>-</entry>
1219 <entry>-</entry>
1220 <entry>-</entry>
1221 <entry>-</entry>
1222 <entry>-</entry>
1223 <entry>-</entry>
1224 <entry>-</entry>
1225 <entry>-</entry>
1226 <entry>-</entry>
1227 <entry>-</entry>
1228 <entry>y<subscript>7</subscript></entry>
1229 <entry>y<subscript>6</subscript></entry>
1230 <entry>y<subscript>5</subscript></entry>
1231 <entry>y<subscript>4</subscript></entry>
1232 <entry>y<subscript>3</subscript></entry>
1233 <entry>y<subscript>2</subscript></entry>
1234 <entry>y<subscript>1</subscript></entry>
1235 <entry>y<subscript>0</subscript></entry>
1236 </row>
1237 <row id="V4L2-MBUS-FMT-YUYV8-1_5X8">
1238 <entry>V4L2_MBUS_FMT_YUYV8_1_5X8</entry>
1239 <entry>0x2004</entry>
1240 <entry></entry>
1241 <entry>-</entry>
1242 <entry>-</entry>
1243 <entry>-</entry>
1244 <entry>-</entry>
1245 <entry>-</entry>
1246 <entry>-</entry>
1247 <entry>-</entry>
1248 <entry>-</entry>
1249 <entry>-</entry>
1250 <entry>-</entry>
1251 <entry>-</entry>
1252 <entry>-</entry>
1253 <entry>y<subscript>7</subscript></entry>
1254 <entry>y<subscript>6</subscript></entry>
1255 <entry>y<subscript>5</subscript></entry>
1256 <entry>y<subscript>4</subscript></entry>
1257 <entry>y<subscript>3</subscript></entry>
1258 <entry>y<subscript>2</subscript></entry>
1259 <entry>y<subscript>1</subscript></entry>
1260 <entry>y<subscript>0</subscript></entry>
1261 </row>
1262 <row>
1263 <entry></entry>
1264 <entry></entry>
1265 <entry></entry>
1266 <entry>-</entry>
1267 <entry>-</entry>
1268 <entry>-</entry>
1269 <entry>-</entry>
1270 <entry>-</entry>
1271 <entry>-</entry>
1272 <entry>-</entry>
1273 <entry>-</entry>
1274 <entry>-</entry>
1275 <entry>-</entry>
1276 <entry>-</entry>
1277 <entry>-</entry>
1278 <entry>y<subscript>7</subscript></entry>
1279 <entry>y<subscript>6</subscript></entry>
1280 <entry>y<subscript>5</subscript></entry>
1281 <entry>y<subscript>4</subscript></entry>
1282 <entry>y<subscript>3</subscript></entry>
1283 <entry>y<subscript>2</subscript></entry>
1284 <entry>y<subscript>1</subscript></entry>
1285 <entry>y<subscript>0</subscript></entry>
1286 </row>
1287 <row>
1288 <entry></entry>
1289 <entry></entry>
1290 <entry></entry>
1291 <entry>-</entry>
1292 <entry>-</entry>
1293 <entry>-</entry>
1294 <entry>-</entry>
1295 <entry>-</entry>
1296 <entry>-</entry>
1297 <entry>-</entry>
1298 <entry>-</entry>
1299 <entry>-</entry>
1300 <entry>-</entry>
1301 <entry>-</entry>
1302 <entry>-</entry>
1303 <entry>u<subscript>7</subscript></entry>
1304 <entry>u<subscript>6</subscript></entry>
1305 <entry>u<subscript>5</subscript></entry>
1306 <entry>u<subscript>4</subscript></entry>
1307 <entry>u<subscript>3</subscript></entry>
1308 <entry>u<subscript>2</subscript></entry>
1309 <entry>u<subscript>1</subscript></entry>
1310 <entry>u<subscript>0</subscript></entry>
1311 </row>
1312 <row>
1313 <entry></entry>
1314 <entry></entry>
1315 <entry></entry>
1316 <entry>-</entry>
1317 <entry>-</entry>
1318 <entry>-</entry>
1319 <entry>-</entry>
1320 <entry>-</entry>
1321 <entry>-</entry>
1322 <entry>-</entry>
1323 <entry>-</entry>
1324 <entry>-</entry>
1325 <entry>-</entry>
1326 <entry>-</entry>
1327 <entry>-</entry>
1328 <entry>y<subscript>7</subscript></entry>
1329 <entry>y<subscript>6</subscript></entry>
1330 <entry>y<subscript>5</subscript></entry>
1331 <entry>y<subscript>4</subscript></entry>
1332 <entry>y<subscript>3</subscript></entry>
1333 <entry>y<subscript>2</subscript></entry>
1334 <entry>y<subscript>1</subscript></entry>
1335 <entry>y<subscript>0</subscript></entry>
1336 </row>
1337 <row>
1338 <entry></entry>
1339 <entry></entry>
1340 <entry></entry>
1341 <entry>-</entry>
1342 <entry>-</entry>
1343 <entry>-</entry>
1344 <entry>-</entry>
1345 <entry>-</entry>
1346 <entry>-</entry>
1347 <entry>-</entry>
1348 <entry>-</entry>
1349 <entry>-</entry>
1350 <entry>-</entry>
1351 <entry>-</entry>
1352 <entry>-</entry>
1353 <entry>y<subscript>7</subscript></entry>
1354 <entry>y<subscript>6</subscript></entry>
1355 <entry>y<subscript>5</subscript></entry>
1356 <entry>y<subscript>4</subscript></entry>
1357 <entry>y<subscript>3</subscript></entry>
1358 <entry>y<subscript>2</subscript></entry>
1359 <entry>y<subscript>1</subscript></entry>
1360 <entry>y<subscript>0</subscript></entry>
1361 </row>
1362 <row>
1363 <entry></entry>
1364 <entry></entry>
1365 <entry></entry>
1366 <entry>-</entry>
1367 <entry>-</entry>
1368 <entry>-</entry>
1369 <entry>-</entry>
1370 <entry>-</entry>
1371 <entry>-</entry>
1372 <entry>-</entry>
1373 <entry>-</entry>
1374 <entry>-</entry>
1375 <entry>-</entry>
1376 <entry>-</entry>
1377 <entry>-</entry>
1378 <entry>v<subscript>7</subscript></entry>
1379 <entry>v<subscript>6</subscript></entry>
1380 <entry>v<subscript>5</subscript></entry>
1381 <entry>v<subscript>4</subscript></entry>
1382 <entry>v<subscript>3</subscript></entry>
1383 <entry>v<subscript>2</subscript></entry>
1384 <entry>v<subscript>1</subscript></entry>
1385 <entry>v<subscript>0</subscript></entry>
1386 </row>
1387 <row id="V4L2-MBUS-FMT-YVYU8-1_5X8">
1388 <entry>V4L2_MBUS_FMT_YVYU8_1_5X8</entry>
1389 <entry>0x2005</entry>
1390 <entry></entry>
1391 <entry>-</entry>
1392 <entry>-</entry>
1393 <entry>-</entry>
1394 <entry>-</entry>
1395 <entry>-</entry>
1396 <entry>-</entry>
1397 <entry>-</entry>
1398 <entry>-</entry>
1399 <entry>-</entry>
1400 <entry>-</entry>
1401 <entry>-</entry>
1402 <entry>-</entry>
1403 <entry>y<subscript>7</subscript></entry>
1404 <entry>y<subscript>6</subscript></entry>
1405 <entry>y<subscript>5</subscript></entry>
1406 <entry>y<subscript>4</subscript></entry>
1407 <entry>y<subscript>3</subscript></entry>
1408 <entry>y<subscript>2</subscript></entry>
1409 <entry>y<subscript>1</subscript></entry>
1410 <entry>y<subscript>0</subscript></entry>
1411 </row>
1412 <row>
1413 <entry></entry>
1414 <entry></entry>
1415 <entry></entry>
1416 <entry>-</entry>
1417 <entry>-</entry>
1418 <entry>-</entry>
1419 <entry>-</entry>
1420 <entry>-</entry>
1421 <entry>-</entry>
1422 <entry>-</entry>
1423 <entry>-</entry>
1424 <entry>-</entry>
1425 <entry>-</entry>
1426 <entry>-</entry>
1427 <entry>-</entry>
1428 <entry>y<subscript>7</subscript></entry>
1429 <entry>y<subscript>6</subscript></entry>
1430 <entry>y<subscript>5</subscript></entry>
1431 <entry>y<subscript>4</subscript></entry>
1432 <entry>y<subscript>3</subscript></entry>
1433 <entry>y<subscript>2</subscript></entry>
1434 <entry>y<subscript>1</subscript></entry>
1435 <entry>y<subscript>0</subscript></entry>
1436 </row>
1437 <row>
1438 <entry></entry>
1439 <entry></entry>
1440 <entry></entry>
1441 <entry>-</entry>
1442 <entry>-</entry>
1443 <entry>-</entry>
1444 <entry>-</entry>
1445 <entry>-</entry>
1446 <entry>-</entry>
1447 <entry>-</entry>
1448 <entry>-</entry>
1449 <entry>-</entry>
1450 <entry>-</entry>
1451 <entry>-</entry>
1452 <entry>-</entry>
1453 <entry>v<subscript>7</subscript></entry>
1454 <entry>v<subscript>6</subscript></entry>
1455 <entry>v<subscript>5</subscript></entry>
1456 <entry>v<subscript>4</subscript></entry>
1457 <entry>v<subscript>3</subscript></entry>
1458 <entry>v<subscript>2</subscript></entry>
1459 <entry>v<subscript>1</subscript></entry>
1460 <entry>v<subscript>0</subscript></entry>
1461 </row>
1462 <row>
1463 <entry></entry>
1464 <entry></entry>
1465 <entry></entry>
1466 <entry>-</entry>
1467 <entry>-</entry>
1468 <entry>-</entry>
1469 <entry>-</entry>
1470 <entry>-</entry>
1471 <entry>-</entry>
1472 <entry>-</entry>
1473 <entry>-</entry>
1474 <entry>-</entry>
1475 <entry>-</entry>
1476 <entry>-</entry>
1477 <entry>-</entry>
1478 <entry>y<subscript>7</subscript></entry>
1479 <entry>y<subscript>6</subscript></entry>
1480 <entry>y<subscript>5</subscript></entry>
1481 <entry>y<subscript>4</subscript></entry>
1482 <entry>y<subscript>3</subscript></entry>
1483 <entry>y<subscript>2</subscript></entry>
1484 <entry>y<subscript>1</subscript></entry>
1485 <entry>y<subscript>0</subscript></entry>
1486 </row>
1487 <row>
1488 <entry></entry>
1489 <entry></entry>
1490 <entry></entry>
1491 <entry>-</entry>
1492 <entry>-</entry>
1493 <entry>-</entry>
1494 <entry>-</entry>
1495 <entry>-</entry>
1496 <entry>-</entry>
1497 <entry>-</entry>
1498 <entry>-</entry>
1499 <entry>-</entry>
1500 <entry>-</entry>
1501 <entry>-</entry>
1502 <entry>-</entry>
1503 <entry>y<subscript>7</subscript></entry>
1504 <entry>y<subscript>6</subscript></entry>
1505 <entry>y<subscript>5</subscript></entry>
1506 <entry>y<subscript>4</subscript></entry>
1507 <entry>y<subscript>3</subscript></entry>
1508 <entry>y<subscript>2</subscript></entry>
1509 <entry>y<subscript>1</subscript></entry>
1510 <entry>y<subscript>0</subscript></entry>
1511 </row>
1512 <row>
1513 <entry></entry>
1514 <entry></entry>
1515 <entry></entry>
1516 <entry>-</entry>
1517 <entry>-</entry>
1518 <entry>-</entry>
1519 <entry>-</entry>
1520 <entry>-</entry>
1521 <entry>-</entry>
1522 <entry>-</entry>
1523 <entry>-</entry>
1524 <entry>-</entry>
1525 <entry>-</entry>
1526 <entry>-</entry>
1527 <entry>-</entry>
1528 <entry>u<subscript>7</subscript></entry>
1529 <entry>u<subscript>6</subscript></entry>
1530 <entry>u<subscript>5</subscript></entry>
1531 <entry>u<subscript>4</subscript></entry>
1532 <entry>u<subscript>3</subscript></entry>
1533 <entry>u<subscript>2</subscript></entry>
1534 <entry>u<subscript>1</subscript></entry>
1535 <entry>u<subscript>0</subscript></entry>
1536 </row>
1537 <row id="V4L2-MBUS-FMT-UYVY8-2X8">
1538 <entry>V4L2_MBUS_FMT_UYVY8_2X8</entry>
1539 <entry>0x2006</entry>
1540 <entry></entry>
1541 <entry>-</entry>
1542 <entry>-</entry>
1543 <entry>-</entry>
1544 <entry>-</entry>
1545 <entry>-</entry>
1546 <entry>-</entry>
1547 <entry>-</entry>
1548 <entry>-</entry>
1549 <entry>-</entry>
1550 <entry>-</entry>
1551 <entry>-</entry>
1552 <entry>-</entry>
1553 <entry>u<subscript>7</subscript></entry>
1554 <entry>u<subscript>6</subscript></entry>
1555 <entry>u<subscript>5</subscript></entry>
1556 <entry>u<subscript>4</subscript></entry>
1557 <entry>u<subscript>3</subscript></entry>
1558 <entry>u<subscript>2</subscript></entry>
1559 <entry>u<subscript>1</subscript></entry>
1560 <entry>u<subscript>0</subscript></entry>
1561 </row>
1562 <row>
1563 <entry></entry>
1564 <entry></entry>
1565 <entry></entry>
1566 <entry>-</entry>
1567 <entry>-</entry>
1568 <entry>-</entry>
1569 <entry>-</entry>
1570 <entry>-</entry>
1571 <entry>-</entry>
1572 <entry>-</entry>
1573 <entry>-</entry>
1574 <entry>-</entry>
1575 <entry>-</entry>
1576 <entry>-</entry>
1577 <entry>-</entry>
1578 <entry>y<subscript>7</subscript></entry>
1579 <entry>y<subscript>6</subscript></entry>
1580 <entry>y<subscript>5</subscript></entry>
1581 <entry>y<subscript>4</subscript></entry>
1582 <entry>y<subscript>3</subscript></entry>
1583 <entry>y<subscript>2</subscript></entry>
1584 <entry>y<subscript>1</subscript></entry>
1585 <entry>y<subscript>0</subscript></entry>
1586 </row>
1587 <row>
1588 <entry></entry>
1589 <entry></entry>
1590 <entry></entry>
1591 <entry>-</entry>
1592 <entry>-</entry>
1593 <entry>-</entry>
1594 <entry>-</entry>
1595 <entry>-</entry>
1596 <entry>-</entry>
1597 <entry>-</entry>
1598 <entry>-</entry>
1599 <entry>-</entry>
1600 <entry>-</entry>
1601 <entry>-</entry>
1602 <entry>-</entry>
1603 <entry>v<subscript>7</subscript></entry>
1604 <entry>v<subscript>6</subscript></entry>
1605 <entry>v<subscript>5</subscript></entry>
1606 <entry>v<subscript>4</subscript></entry>
1607 <entry>v<subscript>3</subscript></entry>
1608 <entry>v<subscript>2</subscript></entry>
1609 <entry>v<subscript>1</subscript></entry>
1610 <entry>v<subscript>0</subscript></entry>
1611 </row>
1612 <row>
1613 <entry></entry>
1614 <entry></entry>
1615 <entry></entry>
1616 <entry>-</entry>
1617 <entry>-</entry>
1618 <entry>-</entry>
1619 <entry>-</entry>
1620 <entry>-</entry>
1621 <entry>-</entry>
1622 <entry>-</entry>
1623 <entry>-</entry>
1624 <entry>-</entry>
1625 <entry>-</entry>
1626 <entry>-</entry>
1627 <entry>-</entry>
1628 <entry>y<subscript>7</subscript></entry>
1629 <entry>y<subscript>6</subscript></entry>
1630 <entry>y<subscript>5</subscript></entry>
1631 <entry>y<subscript>4</subscript></entry>
1632 <entry>y<subscript>3</subscript></entry>
1633 <entry>y<subscript>2</subscript></entry>
1634 <entry>y<subscript>1</subscript></entry>
1635 <entry>y<subscript>0</subscript></entry>
1636 </row>
1637 <row id="V4L2-MBUS-FMT-VYUY8-2X8">
1638 <entry>V4L2_MBUS_FMT_VYUY8_2X8</entry>
1639 <entry>0x2007</entry>
1640 <entry></entry>
1641 <entry>-</entry>
1642 <entry>-</entry>
1643 <entry>-</entry>
1644 <entry>-</entry>
1645 <entry>-</entry>
1646 <entry>-</entry>
1647 <entry>-</entry>
1648 <entry>-</entry>
1649 <entry>-</entry>
1650 <entry>-</entry>
1651 <entry>-</entry>
1652 <entry>-</entry>
1653 <entry>v<subscript>7</subscript></entry>
1654 <entry>v<subscript>6</subscript></entry>
1655 <entry>v<subscript>5</subscript></entry>
1656 <entry>v<subscript>4</subscript></entry>
1657 <entry>v<subscript>3</subscript></entry>
1658 <entry>v<subscript>2</subscript></entry>
1659 <entry>v<subscript>1</subscript></entry>
1660 <entry>v<subscript>0</subscript></entry>
1661 </row>
1662 <row>
1663 <entry></entry>
1664 <entry></entry>
1665 <entry></entry>
1666 <entry>-</entry>
1667 <entry>-</entry>
1668 <entry>-</entry>
1669 <entry>-</entry>
1670 <entry>-</entry>
1671 <entry>-</entry>
1672 <entry>-</entry>
1673 <entry>-</entry>
1674 <entry>-</entry>
1675 <entry>-</entry>
1676 <entry>-</entry>
1677 <entry>-</entry>
1678 <entry>y<subscript>7</subscript></entry>
1679 <entry>y<subscript>6</subscript></entry>
1680 <entry>y<subscript>5</subscript></entry>
1681 <entry>y<subscript>4</subscript></entry>
1682 <entry>y<subscript>3</subscript></entry>
1683 <entry>y<subscript>2</subscript></entry>
1684 <entry>y<subscript>1</subscript></entry>
1685 <entry>y<subscript>0</subscript></entry>
1686 </row>
1687 <row>
1688 <entry></entry>
1689 <entry></entry>
1690 <entry></entry>
1691 <entry>-</entry>
1692 <entry>-</entry>
1693 <entry>-</entry>
1694 <entry>-</entry>
1695 <entry>-</entry>
1696 <entry>-</entry>
1697 <entry>-</entry>
1698 <entry>-</entry>
1699 <entry>-</entry>
1700 <entry>-</entry>
1701 <entry>-</entry>
1702 <entry>-</entry>
1703 <entry>u<subscript>7</subscript></entry>
1704 <entry>u<subscript>6</subscript></entry>
1705 <entry>u<subscript>5</subscript></entry>
1706 <entry>u<subscript>4</subscript></entry>
1707 <entry>u<subscript>3</subscript></entry>
1708 <entry>u<subscript>2</subscript></entry>
1709 <entry>u<subscript>1</subscript></entry>
1710 <entry>u<subscript>0</subscript></entry>
1711 </row>
1712 <row>
1713 <entry></entry>
1714 <entry></entry>
1715 <entry></entry>
1716 <entry>-</entry>
1717 <entry>-</entry>
1718 <entry>-</entry>
1719 <entry>-</entry>
1720 <entry>-</entry>
1721 <entry>-</entry>
1722 <entry>-</entry>
1723 <entry>-</entry>
1724 <entry>-</entry>
1725 <entry>-</entry>
1726 <entry>-</entry>
1727 <entry>-</entry>
1728 <entry>y<subscript>7</subscript></entry>
1729 <entry>y<subscript>6</subscript></entry>
1730 <entry>y<subscript>5</subscript></entry>
1731 <entry>y<subscript>4</subscript></entry>
1732 <entry>y<subscript>3</subscript></entry>
1733 <entry>y<subscript>2</subscript></entry>
1734 <entry>y<subscript>1</subscript></entry>
1735 <entry>y<subscript>0</subscript></entry>
1736 </row>
1737 <row id="V4L2-MBUS-FMT-YUYV8-2X8">
1738 <entry>V4L2_MBUS_FMT_YUYV8_2X8</entry>
1739 <entry>0x2008</entry>
1740 <entry></entry>
1741 <entry>-</entry>
1742 <entry>-</entry>
1743 <entry>-</entry>
1744 <entry>-</entry>
1745 <entry>-</entry>
1746 <entry>-</entry>
1747 <entry>-</entry>
1748 <entry>-</entry>
1749 <entry>-</entry>
1750 <entry>-</entry>
1751 <entry>-</entry>
1752 <entry>-</entry>
1753 <entry>y<subscript>7</subscript></entry>
1754 <entry>y<subscript>6</subscript></entry>
1755 <entry>y<subscript>5</subscript></entry>
1756 <entry>y<subscript>4</subscript></entry>
1757 <entry>y<subscript>3</subscript></entry>
1758 <entry>y<subscript>2</subscript></entry>
1759 <entry>y<subscript>1</subscript></entry>
1760 <entry>y<subscript>0</subscript></entry>
1761 </row>
1762 <row>
1763 <entry></entry>
1764 <entry></entry>
1765 <entry></entry>
1766 <entry>-</entry>
1767 <entry>-</entry>
1768 <entry>-</entry>
1769 <entry>-</entry>
1770 <entry>-</entry>
1771 <entry>-</entry>
1772 <entry>-</entry>
1773 <entry>-</entry>
1774 <entry>-</entry>
1775 <entry>-</entry>
1776 <entry>-</entry>
1777 <entry>-</entry>
1778 <entry>u<subscript>7</subscript></entry>
1779 <entry>u<subscript>6</subscript></entry>
1780 <entry>u<subscript>5</subscript></entry>
1781 <entry>u<subscript>4</subscript></entry>
1782 <entry>u<subscript>3</subscript></entry>
1783 <entry>u<subscript>2</subscript></entry>
1784 <entry>u<subscript>1</subscript></entry>
1785 <entry>u<subscript>0</subscript></entry>
1786 </row>
1787 <row>
1788 <entry></entry>
1789 <entry></entry>
1790 <entry></entry>
1791 <entry>-</entry>
1792 <entry>-</entry>
1793 <entry>-</entry>
1794 <entry>-</entry>
1795 <entry>-</entry>
1796 <entry>-</entry>
1797 <entry>-</entry>
1798 <entry>-</entry>
1799 <entry>-</entry>
1800 <entry>-</entry>
1801 <entry>-</entry>
1802 <entry>-</entry>
1803 <entry>y<subscript>7</subscript></entry>
1804 <entry>y<subscript>6</subscript></entry>
1805 <entry>y<subscript>5</subscript></entry>
1806 <entry>y<subscript>4</subscript></entry>
1807 <entry>y<subscript>3</subscript></entry>
1808 <entry>y<subscript>2</subscript></entry>
1809 <entry>y<subscript>1</subscript></entry>
1810 <entry>y<subscript>0</subscript></entry>
1811 </row>
1812 <row>
1813 <entry></entry>
1814 <entry></entry>
1815 <entry></entry>
1816 <entry>-</entry>
1817 <entry>-</entry>
1818 <entry>-</entry>
1819 <entry>-</entry>
1820 <entry>-</entry>
1821 <entry>-</entry>
1822 <entry>-</entry>
1823 <entry>-</entry>
1824 <entry>-</entry>
1825 <entry>-</entry>
1826 <entry>-</entry>
1827 <entry>-</entry>
1828 <entry>v<subscript>7</subscript></entry>
1829 <entry>v<subscript>6</subscript></entry>
1830 <entry>v<subscript>5</subscript></entry>
1831 <entry>v<subscript>4</subscript></entry>
1832 <entry>v<subscript>3</subscript></entry>
1833 <entry>v<subscript>2</subscript></entry>
1834 <entry>v<subscript>1</subscript></entry>
1835 <entry>v<subscript>0</subscript></entry>
1836 </row>
1837 <row id="V4L2-MBUS-FMT-YVYU8-2X8">
1838 <entry>V4L2_MBUS_FMT_YVYU8_2X8</entry>
1839 <entry>0x2009</entry>
1840 <entry></entry>
1841 <entry>-</entry>
1842 <entry>-</entry>
1843 <entry>-</entry>
1844 <entry>-</entry>
1845 <entry>-</entry>
1846 <entry>-</entry>
1847 <entry>-</entry>
1848 <entry>-</entry>
1849 <entry>-</entry>
1850 <entry>-</entry>
1851 <entry>-</entry>
1852 <entry>-</entry>
1853 <entry>y<subscript>7</subscript></entry>
1854 <entry>y<subscript>6</subscript></entry>
1855 <entry>y<subscript>5</subscript></entry>
1856 <entry>y<subscript>4</subscript></entry>
1857 <entry>y<subscript>3</subscript></entry>
1858 <entry>y<subscript>2</subscript></entry>
1859 <entry>y<subscript>1</subscript></entry>
1860 <entry>y<subscript>0</subscript></entry>
1861 </row>
1862 <row>
1863 <entry></entry>
1864 <entry></entry>
1865 <entry></entry>
1866 <entry>-</entry>
1867 <entry>-</entry>
1868 <entry>-</entry>
1869 <entry>-</entry>
1870 <entry>-</entry>
1871 <entry>-</entry>
1872 <entry>-</entry>
1873 <entry>-</entry>
1874 <entry>-</entry>
1875 <entry>-</entry>
1876 <entry>-</entry>
1877 <entry>-</entry>
1878 <entry>v<subscript>7</subscript></entry>
1879 <entry>v<subscript>6</subscript></entry>
1880 <entry>v<subscript>5</subscript></entry>
1881 <entry>v<subscript>4</subscript></entry>
1882 <entry>v<subscript>3</subscript></entry>
1883 <entry>v<subscript>2</subscript></entry>
1884 <entry>v<subscript>1</subscript></entry>
1885 <entry>v<subscript>0</subscript></entry>
1886 </row>
1887 <row>
1888 <entry></entry>
1889 <entry></entry>
1890 <entry></entry>
1891 <entry>-</entry>
1892 <entry>-</entry>
1893 <entry>-</entry>
1894 <entry>-</entry>
1895 <entry>-</entry>
1896 <entry>-</entry>
1897 <entry>-</entry>
1898 <entry>-</entry>
1899 <entry>-</entry>
1900 <entry>-</entry>
1901 <entry>-</entry>
1902 <entry>-</entry>
1903 <entry>y<subscript>7</subscript></entry>
1904 <entry>y<subscript>6</subscript></entry>
1905 <entry>y<subscript>5</subscript></entry>
1906 <entry>y<subscript>4</subscript></entry>
1907 <entry>y<subscript>3</subscript></entry>
1908 <entry>y<subscript>2</subscript></entry>
1909 <entry>y<subscript>1</subscript></entry>
1910 <entry>y<subscript>0</subscript></entry>
1911 </row>
1912 <row>
1913 <entry></entry>
1914 <entry></entry>
1915 <entry></entry>
1916 <entry>-</entry>
1917 <entry>-</entry>
1918 <entry>-</entry>
1919 <entry>-</entry>
1920 <entry>-</entry>
1921 <entry>-</entry>
1922 <entry>-</entry>
1923 <entry>-</entry>
1924 <entry>-</entry>
1925 <entry>-</entry>
1926 <entry>-</entry>
1927 <entry>-</entry>
1928 <entry>u<subscript>7</subscript></entry>
1929 <entry>u<subscript>6</subscript></entry>
1930 <entry>u<subscript>5</subscript></entry>
1931 <entry>u<subscript>4</subscript></entry>
1932 <entry>u<subscript>3</subscript></entry>
1933 <entry>u<subscript>2</subscript></entry>
1934 <entry>u<subscript>1</subscript></entry>
1935 <entry>u<subscript>0</subscript></entry>
1936 </row>
1937 <row id="V4L2-MBUS-FMT-Y10-1X10">
1938 <entry>V4L2_MBUS_FMT_Y10_1X10</entry>
1939 <entry>0x200a</entry>
1940 <entry></entry>
1941 <entry>-</entry>
1942 <entry>-</entry>
1943 <entry>-</entry>
1944 <entry>-</entry>
1945 <entry>-</entry>
1946 <entry>-</entry>
1947 <entry>-</entry>
1948 <entry>-</entry>
1949 <entry>-</entry>
1950 <entry>-</entry>
1951 <entry>y<subscript>9</subscript></entry>
1952 <entry>y<subscript>8</subscript></entry>
1953 <entry>y<subscript>7</subscript></entry>
1954 <entry>y<subscript>6</subscript></entry>
1955 <entry>y<subscript>5</subscript></entry>
1956 <entry>y<subscript>4</subscript></entry>
1957 <entry>y<subscript>3</subscript></entry>
1958 <entry>y<subscript>2</subscript></entry>
1959 <entry>y<subscript>1</subscript></entry>
1960 <entry>y<subscript>0</subscript></entry>
1961 </row>
1962 <row id="V4L2-MBUS-FMT-YUYV10-2X10">
1963 <entry>V4L2_MBUS_FMT_YUYV10_2X10</entry>
1964 <entry>0x200b</entry>
1965 <entry></entry>
1966 <entry>-</entry>
1967 <entry>-</entry>
1968 <entry>-</entry>
1969 <entry>-</entry>
1970 <entry>-</entry>
1971 <entry>-</entry>
1972 <entry>-</entry>
1973 <entry>-</entry>
1974 <entry>-</entry>
1975 <entry>-</entry>
1976 <entry>y<subscript>9</subscript></entry>
1977 <entry>y<subscript>8</subscript></entry>
1978 <entry>y<subscript>7</subscript></entry>
1979 <entry>y<subscript>6</subscript></entry>
1980 <entry>y<subscript>5</subscript></entry>
1981 <entry>y<subscript>4</subscript></entry>
1982 <entry>y<subscript>3</subscript></entry>
1983 <entry>y<subscript>2</subscript></entry>
1984 <entry>y<subscript>1</subscript></entry>
1985 <entry>y<subscript>0</subscript></entry>
1986 </row>
1987 <row>
1988 <entry></entry>
1989 <entry></entry>
1990 <entry></entry>
1991 <entry>-</entry>
1992 <entry>-</entry>
1993 <entry>-</entry>
1994 <entry>-</entry>
1995 <entry>-</entry>
1996 <entry>-</entry>
1997 <entry>-</entry>
1998 <entry>-</entry>
1999 <entry>-</entry>
2000 <entry>-</entry>
2001 <entry>u<subscript>9</subscript></entry>
2002 <entry>u<subscript>8</subscript></entry>
2003 <entry>u<subscript>7</subscript></entry>
2004 <entry>u<subscript>6</subscript></entry>
2005 <entry>u<subscript>5</subscript></entry>
2006 <entry>u<subscript>4</subscript></entry>
2007 <entry>u<subscript>3</subscript></entry>
2008 <entry>u<subscript>2</subscript></entry>
2009 <entry>u<subscript>1</subscript></entry>
2010 <entry>u<subscript>0</subscript></entry>
2011 </row>
2012 <row>
2013 <entry></entry>
2014 <entry></entry>
2015 <entry></entry>
2016 <entry>-</entry>
2017 <entry>-</entry>
2018 <entry>-</entry>
2019 <entry>-</entry>
2020 <entry>-</entry>
2021 <entry>-</entry>
2022 <entry>-</entry>
2023 <entry>-</entry>
2024 <entry>-</entry>
2025 <entry>-</entry>
2026 <entry>y<subscript>9</subscript></entry>
2027 <entry>y<subscript>8</subscript></entry>
2028 <entry>y<subscript>7</subscript></entry>
2029 <entry>y<subscript>6</subscript></entry>
2030 <entry>y<subscript>5</subscript></entry>
2031 <entry>y<subscript>4</subscript></entry>
2032 <entry>y<subscript>3</subscript></entry>
2033 <entry>y<subscript>2</subscript></entry>
2034 <entry>y<subscript>1</subscript></entry>
2035 <entry>y<subscript>0</subscript></entry>
2036 </row>
2037 <row>
2038 <entry></entry>
2039 <entry></entry>
2040 <entry></entry>
2041 <entry>-</entry>
2042 <entry>-</entry>
2043 <entry>-</entry>
2044 <entry>-</entry>
2045 <entry>-</entry>
2046 <entry>-</entry>
2047 <entry>-</entry>
2048 <entry>-</entry>
2049 <entry>-</entry>
2050 <entry>-</entry>
2051 <entry>v<subscript>9</subscript></entry>
2052 <entry>v<subscript>8</subscript></entry>
2053 <entry>v<subscript>7</subscript></entry>
2054 <entry>v<subscript>6</subscript></entry>
2055 <entry>v<subscript>5</subscript></entry>
2056 <entry>v<subscript>4</subscript></entry>
2057 <entry>v<subscript>3</subscript></entry>
2058 <entry>v<subscript>2</subscript></entry>
2059 <entry>v<subscript>1</subscript></entry>
2060 <entry>v<subscript>0</subscript></entry>
2061 </row>
2062 <row id="V4L2-MBUS-FMT-YVYU10-2X10">
2063 <entry>V4L2_MBUS_FMT_YVYU10_2X10</entry>
2064 <entry>0x200c</entry>
2065 <entry></entry>
2066 <entry>-</entry>
2067 <entry>-</entry>
2068 <entry>-</entry>
2069 <entry>-</entry>
2070 <entry>-</entry>
2071 <entry>-</entry>
2072 <entry>-</entry>
2073 <entry>-</entry>
2074 <entry>-</entry>
2075 <entry>-</entry>
2076 <entry>y<subscript>9</subscript></entry>
2077 <entry>y<subscript>8</subscript></entry>
2078 <entry>y<subscript>7</subscript></entry>
2079 <entry>y<subscript>6</subscript></entry>
2080 <entry>y<subscript>5</subscript></entry>
2081 <entry>y<subscript>4</subscript></entry>
2082 <entry>y<subscript>3</subscript></entry>
2083 <entry>y<subscript>2</subscript></entry>
2084 <entry>y<subscript>1</subscript></entry>
2085 <entry>y<subscript>0</subscript></entry>
2086 </row>
2087 <row>
2088 <entry></entry>
2089 <entry></entry>
2090 <entry></entry>
2091 <entry>-</entry>
2092 <entry>-</entry>
2093 <entry>-</entry>
2094 <entry>-</entry>
2095 <entry>-</entry>
2096 <entry>-</entry>
2097 <entry>-</entry>
2098 <entry>-</entry>
2099 <entry>-</entry>
2100 <entry>-</entry>
2101 <entry>v<subscript>9</subscript></entry>
2102 <entry>v<subscript>8</subscript></entry>
2103 <entry>v<subscript>7</subscript></entry>
2104 <entry>v<subscript>6</subscript></entry>
2105 <entry>v<subscript>5</subscript></entry>
2106 <entry>v<subscript>4</subscript></entry>
2107 <entry>v<subscript>3</subscript></entry>
2108 <entry>v<subscript>2</subscript></entry>
2109 <entry>v<subscript>1</subscript></entry>
2110 <entry>v<subscript>0</subscript></entry>
2111 </row>
2112 <row>
2113 <entry></entry>
2114 <entry></entry>
2115 <entry></entry>
2116 <entry>-</entry>
2117 <entry>-</entry>
2118 <entry>-</entry>
2119 <entry>-</entry>
2120 <entry>-</entry>
2121 <entry>-</entry>
2122 <entry>-</entry>
2123 <entry>-</entry>
2124 <entry>-</entry>
2125 <entry>-</entry>
2126 <entry>y<subscript>9</subscript></entry>
2127 <entry>y<subscript>8</subscript></entry>
2128 <entry>y<subscript>7</subscript></entry>
2129 <entry>y<subscript>6</subscript></entry>
2130 <entry>y<subscript>5</subscript></entry>
2131 <entry>y<subscript>4</subscript></entry>
2132 <entry>y<subscript>3</subscript></entry>
2133 <entry>y<subscript>2</subscript></entry>
2134 <entry>y<subscript>1</subscript></entry>
2135 <entry>y<subscript>0</subscript></entry>
2136 </row>
2137 <row>
2138 <entry></entry>
2139 <entry></entry>
2140 <entry></entry>
2141 <entry>-</entry>
2142 <entry>-</entry>
2143 <entry>-</entry>
2144 <entry>-</entry>
2145 <entry>-</entry>
2146 <entry>-</entry>
2147 <entry>-</entry>
2148 <entry>-</entry>
2149 <entry>-</entry>
2150 <entry>-</entry>
2151 <entry>u<subscript>9</subscript></entry>
2152 <entry>u<subscript>8</subscript></entry>
2153 <entry>u<subscript>7</subscript></entry>
2154 <entry>u<subscript>6</subscript></entry>
2155 <entry>u<subscript>5</subscript></entry>
2156 <entry>u<subscript>4</subscript></entry>
2157 <entry>u<subscript>3</subscript></entry>
2158 <entry>u<subscript>2</subscript></entry>
2159 <entry>u<subscript>1</subscript></entry>
2160 <entry>u<subscript>0</subscript></entry>
2161 </row>
2162 <row id="V4L2-MBUS-FMT-UYVY8-1X16">
2163 <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry>
2164 <entry>0x200f</entry>
2165 <entry></entry>
2166 <entry>-</entry>
2167 <entry>-</entry>
2168 <entry>-</entry>
2169 <entry>-</entry>
2170 <entry>u<subscript>7</subscript></entry>
2171 <entry>u<subscript>6</subscript></entry>
2172 <entry>u<subscript>5</subscript></entry>
2173 <entry>u<subscript>4</subscript></entry>
2174 <entry>u<subscript>3</subscript></entry>
2175 <entry>u<subscript>2</subscript></entry>
2176 <entry>u<subscript>1</subscript></entry>
2177 <entry>u<subscript>0</subscript></entry>
2178 <entry>y<subscript>7</subscript></entry>
2179 <entry>y<subscript>6</subscript></entry>
2180 <entry>y<subscript>5</subscript></entry>
2181 <entry>y<subscript>4</subscript></entry>
2182 <entry>y<subscript>3</subscript></entry>
2183 <entry>y<subscript>2</subscript></entry>
2184 <entry>y<subscript>1</subscript></entry>
2185 <entry>y<subscript>0</subscript></entry>
2186 </row>
2187 <row>
2188 <entry></entry>
2189 <entry></entry>
2190 <entry></entry>
2191 <entry>-</entry>
2192 <entry>-</entry>
2193 <entry>-</entry>
2194 <entry>-</entry>
2195 <entry>v<subscript>7</subscript></entry>
2196 <entry>v<subscript>6</subscript></entry>
2197 <entry>v<subscript>5</subscript></entry>
2198 <entry>v<subscript>4</subscript></entry>
2199 <entry>v<subscript>3</subscript></entry>
2200 <entry>v<subscript>2</subscript></entry>
2201 <entry>v<subscript>1</subscript></entry>
2202 <entry>v<subscript>0</subscript></entry>
2203 <entry>y<subscript>7</subscript></entry>
2204 <entry>y<subscript>6</subscript></entry>
2205 <entry>y<subscript>5</subscript></entry>
2206 <entry>y<subscript>4</subscript></entry>
2207 <entry>y<subscript>3</subscript></entry>
2208 <entry>y<subscript>2</subscript></entry>
2209 <entry>y<subscript>1</subscript></entry>
2210 <entry>y<subscript>0</subscript></entry>
2211 </row>
2212 <row id="V4L2-MBUS-FMT-VYUY8-1X16">
2213 <entry>V4L2_MBUS_FMT_VYUY8_1X16</entry>
2214 <entry>0x2010</entry>
2215 <entry></entry>
2216 <entry>-</entry>
2217 <entry>-</entry>
2218 <entry>-</entry>
2219 <entry>-</entry>
2220 <entry>v<subscript>7</subscript></entry>
2221 <entry>v<subscript>6</subscript></entry>
2222 <entry>v<subscript>5</subscript></entry>
2223 <entry>v<subscript>4</subscript></entry>
2224 <entry>v<subscript>3</subscript></entry>
2225 <entry>v<subscript>2</subscript></entry>
2226 <entry>v<subscript>1</subscript></entry>
2227 <entry>v<subscript>0</subscript></entry>
2228 <entry>y<subscript>7</subscript></entry>
2229 <entry>y<subscript>6</subscript></entry>
2230 <entry>y<subscript>5</subscript></entry>
2231 <entry>y<subscript>4</subscript></entry>
2232 <entry>y<subscript>3</subscript></entry>
2233 <entry>y<subscript>2</subscript></entry>
2234 <entry>y<subscript>1</subscript></entry>
2235 <entry>y<subscript>0</subscript></entry>
2236 </row>
2237 <row>
2238 <entry></entry>
2239 <entry></entry>
2240 <entry></entry>
2241 <entry>-</entry>
2242 <entry>-</entry>
2243 <entry>-</entry>
2244 <entry>-</entry>
2245 <entry>u<subscript>7</subscript></entry>
2246 <entry>u<subscript>6</subscript></entry>
2247 <entry>u<subscript>5</subscript></entry>
2248 <entry>u<subscript>4</subscript></entry>
2249 <entry>u<subscript>3</subscript></entry>
2250 <entry>u<subscript>2</subscript></entry>
2251 <entry>u<subscript>1</subscript></entry>
2252 <entry>u<subscript>0</subscript></entry>
2253 <entry>y<subscript>7</subscript></entry>
2254 <entry>y<subscript>6</subscript></entry>
2255 <entry>y<subscript>5</subscript></entry>
2256 <entry>y<subscript>4</subscript></entry>
2257 <entry>y<subscript>3</subscript></entry>
2258 <entry>y<subscript>2</subscript></entry>
2259 <entry>y<subscript>1</subscript></entry>
2260 <entry>y<subscript>0</subscript></entry>
2261 </row>
2262 <row id="V4L2-MBUS-FMT-YUYV8-1X16">
2263 <entry>V4L2_MBUS_FMT_YUYV8_1X16</entry>
2264 <entry>0x2011</entry>
2265 <entry></entry>
2266 <entry>-</entry>
2267 <entry>-</entry>
2268 <entry>-</entry>
2269 <entry>-</entry>
2270 <entry>y<subscript>7</subscript></entry>
2271 <entry>y<subscript>6</subscript></entry>
2272 <entry>y<subscript>5</subscript></entry>
2273 <entry>y<subscript>4</subscript></entry>
2274 <entry>y<subscript>3</subscript></entry>
2275 <entry>y<subscript>2</subscript></entry>
2276 <entry>y<subscript>1</subscript></entry>
2277 <entry>y<subscript>0</subscript></entry>
2278 <entry>u<subscript>7</subscript></entry>
2279 <entry>u<subscript>6</subscript></entry>
2280 <entry>u<subscript>5</subscript></entry>
2281 <entry>u<subscript>4</subscript></entry>
2282 <entry>u<subscript>3</subscript></entry>
2283 <entry>u<subscript>2</subscript></entry>
2284 <entry>u<subscript>1</subscript></entry>
2285 <entry>u<subscript>0</subscript></entry>
2286 </row>
2287 <row>
2288 <entry></entry>
2289 <entry></entry>
2290 <entry></entry>
2291 <entry>-</entry>
2292 <entry>-</entry>
2293 <entry>-</entry>
2294 <entry>-</entry>
2295 <entry>y<subscript>7</subscript></entry>
2296 <entry>y<subscript>6</subscript></entry>
2297 <entry>y<subscript>5</subscript></entry>
2298 <entry>y<subscript>4</subscript></entry>
2299 <entry>y<subscript>3</subscript></entry>
2300 <entry>y<subscript>2</subscript></entry>
2301 <entry>y<subscript>1</subscript></entry>
2302 <entry>y<subscript>0</subscript></entry>
2303 <entry>v<subscript>7</subscript></entry>
2304 <entry>v<subscript>6</subscript></entry>
2305 <entry>v<subscript>5</subscript></entry>
2306 <entry>v<subscript>4</subscript></entry>
2307 <entry>v<subscript>3</subscript></entry>
2308 <entry>v<subscript>2</subscript></entry>
2309 <entry>v<subscript>1</subscript></entry>
2310 <entry>v<subscript>0</subscript></entry>
2311 </row>
2312 <row id="V4L2-MBUS-FMT-YVYU8-1X16">
2313 <entry>V4L2_MBUS_FMT_YVYU8_1X16</entry>
2314 <entry>0x2012</entry>
2315 <entry></entry>
2316 <entry>-</entry>
2317 <entry>-</entry>
2318 <entry>-</entry>
2319 <entry>-</entry>
2320 <entry>y<subscript>7</subscript></entry>
2321 <entry>y<subscript>6</subscript></entry>
2322 <entry>y<subscript>5</subscript></entry>
2323 <entry>y<subscript>4</subscript></entry>
2324 <entry>y<subscript>3</subscript></entry>
2325 <entry>y<subscript>2</subscript></entry>
2326 <entry>y<subscript>1</subscript></entry>
2327 <entry>y<subscript>0</subscript></entry>
2328 <entry>v<subscript>7</subscript></entry>
2329 <entry>v<subscript>6</subscript></entry>
2330 <entry>v<subscript>5</subscript></entry>
2331 <entry>v<subscript>4</subscript></entry>
2332 <entry>v<subscript>3</subscript></entry>
2333 <entry>v<subscript>2</subscript></entry>
2334 <entry>v<subscript>1</subscript></entry>
2335 <entry>v<subscript>0</subscript></entry>
2336 </row>
2337 <row>
2338 <entry></entry>
2339 <entry></entry>
2340 <entry></entry>
2341 <entry>-</entry>
2342 <entry>-</entry>
2343 <entry>-</entry>
2344 <entry>-</entry>
2345 <entry>y<subscript>7</subscript></entry>
2346 <entry>y<subscript>6</subscript></entry>
2347 <entry>y<subscript>5</subscript></entry>
2348 <entry>y<subscript>4</subscript></entry>
2349 <entry>y<subscript>3</subscript></entry>
2350 <entry>y<subscript>2</subscript></entry>
2351 <entry>y<subscript>1</subscript></entry>
2352 <entry>y<subscript>0</subscript></entry>
2353 <entry>u<subscript>7</subscript></entry>
2354 <entry>u<subscript>6</subscript></entry>
2355 <entry>u<subscript>5</subscript></entry>
2356 <entry>u<subscript>4</subscript></entry>
2357 <entry>u<subscript>3</subscript></entry>
2358 <entry>u<subscript>2</subscript></entry>
2359 <entry>u<subscript>1</subscript></entry>
2360 <entry>u<subscript>0</subscript></entry>
2361 </row>
2362 <row id="V4L2-MBUS-FMT-YUYV10-1X20">
2363 <entry>V4L2_MBUS_FMT_YUYV10_1X20</entry>
2364 <entry>0x200d</entry>
2365 <entry></entry>
2366 <entry>y<subscript>9</subscript></entry>
2367 <entry>y<subscript>8</subscript></entry>
2368 <entry>y<subscript>7</subscript></entry>
2369 <entry>y<subscript>6</subscript></entry>
2370 <entry>y<subscript>5</subscript></entry>
2371 <entry>y<subscript>4</subscript></entry>
2372 <entry>y<subscript>3</subscript></entry>
2373 <entry>y<subscript>2</subscript></entry>
2374 <entry>y<subscript>1</subscript></entry>
2375 <entry>y<subscript>0</subscript></entry>
2376 <entry>u<subscript>9</subscript></entry>
2377 <entry>u<subscript>8</subscript></entry>
2378 <entry>u<subscript>7</subscript></entry>
2379 <entry>u<subscript>6</subscript></entry>
2380 <entry>u<subscript>5</subscript></entry>
2381 <entry>u<subscript>4</subscript></entry>
2382 <entry>u<subscript>3</subscript></entry>
2383 <entry>u<subscript>2</subscript></entry>
2384 <entry>u<subscript>1</subscript></entry>
2385 <entry>u<subscript>0</subscript></entry>
2386 </row>
2387 <row>
2388 <entry></entry>
2389 <entry></entry>
2390 <entry></entry>
2391 <entry>y<subscript>9</subscript></entry>
2392 <entry>y<subscript>8</subscript></entry>
2393 <entry>y<subscript>7</subscript></entry>
2394 <entry>y<subscript>6</subscript></entry>
2395 <entry>y<subscript>5</subscript></entry>
2396 <entry>y<subscript>4</subscript></entry>
2397 <entry>y<subscript>3</subscript></entry>
2398 <entry>y<subscript>2</subscript></entry>
2399 <entry>y<subscript>1</subscript></entry>
2400 <entry>y<subscript>0</subscript></entry>
2401 <entry>v<subscript>9</subscript></entry>
2402 <entry>v<subscript>8</subscript></entry>
2403 <entry>v<subscript>7</subscript></entry>
2404 <entry>v<subscript>6</subscript></entry>
2405 <entry>v<subscript>5</subscript></entry>
2406 <entry>v<subscript>4</subscript></entry>
2407 <entry>v<subscript>3</subscript></entry>
2408 <entry>v<subscript>2</subscript></entry>
2409 <entry>v<subscript>1</subscript></entry>
2410 <entry>v<subscript>0</subscript></entry>
2411 </row>
2412 <row id="V4L2-MBUS-FMT-YVYU10-1X20">
2413 <entry>V4L2_MBUS_FMT_YVYU10_1X20</entry>
2414 <entry>0x200e</entry>
2415 <entry></entry>
2416 <entry>y<subscript>9</subscript></entry>
2417 <entry>y<subscript>8</subscript></entry>
2418 <entry>y<subscript>7</subscript></entry>
2419 <entry>y<subscript>6</subscript></entry>
2420 <entry>y<subscript>5</subscript></entry>
2421 <entry>y<subscript>4</subscript></entry>
2422 <entry>y<subscript>3</subscript></entry>
2423 <entry>y<subscript>2</subscript></entry>
2424 <entry>y<subscript>1</subscript></entry>
2425 <entry>y<subscript>0</subscript></entry>
2426 <entry>v<subscript>9</subscript></entry>
2427 <entry>v<subscript>8</subscript></entry>
2428 <entry>v<subscript>7</subscript></entry>
2429 <entry>v<subscript>6</subscript></entry>
2430 <entry>v<subscript>5</subscript></entry>
2431 <entry>v<subscript>4</subscript></entry>
2432 <entry>v<subscript>3</subscript></entry>
2433 <entry>v<subscript>2</subscript></entry>
2434 <entry>v<subscript>1</subscript></entry>
2435 <entry>v<subscript>0</subscript></entry>
2436 </row>
2437 <row>
2438 <entry></entry>
2439 <entry></entry>
2440 <entry></entry>
2441 <entry>y<subscript>9</subscript></entry>
2442 <entry>y<subscript>8</subscript></entry>
2443 <entry>y<subscript>7</subscript></entry>
2444 <entry>y<subscript>6</subscript></entry>
2445 <entry>y<subscript>5</subscript></entry>
2446 <entry>y<subscript>4</subscript></entry>
2447 <entry>y<subscript>3</subscript></entry>
2448 <entry>y<subscript>2</subscript></entry>
2449 <entry>y<subscript>1</subscript></entry>
2450 <entry>y<subscript>0</subscript></entry>
2451 <entry>u<subscript>9</subscript></entry>
2452 <entry>u<subscript>8</subscript></entry>
2453 <entry>u<subscript>7</subscript></entry>
2454 <entry>u<subscript>6</subscript></entry>
2455 <entry>u<subscript>5</subscript></entry>
2456 <entry>u<subscript>4</subscript></entry>
2457 <entry>u<subscript>3</subscript></entry>
2458 <entry>u<subscript>2</subscript></entry>
2459 <entry>u<subscript>1</subscript></entry>
2460 <entry>u<subscript>0</subscript></entry>
2461 </row>
2462 </tbody>
2463 </tgroup>
2464 </table>
2465 </section>
2466 </section>
2467</section>
diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml
index 9288af96de34..a7fd76d0dac1 100644
--- a/Documentation/DocBook/v4l/v4l2.xml
+++ b/Documentation/DocBook/v4l/v4l2.xml
@@ -85,6 +85,17 @@ Remote Controller chapter.</contrib>
85 </address> 85 </address>
86 </affiliation> 86 </affiliation>
87 </author> 87 </author>
88
89 <author>
90 <firstname>Pawel</firstname>
91 <surname>Osciak</surname>
92 <contrib>Designed and documented the multi-planar API.</contrib>
93 <affiliation>
94 <address>
95 <email>pawel AT osciak.com</email>
96 </address>
97 </affiliation>
98 </author>
88 </authorgroup> 99 </authorgroup>
89 100
90 <copyright> 101 <copyright>
@@ -102,7 +113,8 @@ Remote Controller chapter.</contrib>
102 <year>2010</year> 113 <year>2010</year>
103 <year>2011</year> 114 <year>2011</year>
104 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin 115 <holder>Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin
105Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab</holder> 116Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab,
117 Pawel Osciak</holder>
106 </copyright> 118 </copyright>
107 <legalnotice> 119 <legalnotice>
108 <para>Except when explicitly stated as GPL, programming examples within 120 <para>Except when explicitly stated as GPL, programming examples within
@@ -116,6 +128,13 @@ structs, ioctls) must be noted in more detail in the history chapter
116applications. --> 128applications. -->
117 129
118 <revision> 130 <revision>
131 <revnumber>2.6.39</revnumber>
132 <date>2011-03-01</date>
133 <authorinitials>mcc, po</authorinitials>
134 <revremark>Removed VIDIOC_*_OLD from videodev2.h header and update it to reflect latest changes. Added the <link linkend="planar-apis">multi-planar API</link>.</revremark>
135 </revision>
136
137 <revision>
119 <revnumber>2.6.37</revnumber> 138 <revnumber>2.6.37</revnumber>
120 <date>2010-08-06</date> 139 <date>2010-08-06</date>
121 <authorinitials>hv</authorinitials> 140 <authorinitials>hv</authorinitials>
@@ -382,7 +401,7 @@ and discussions on the V4L mailing list.</revremark>
382</partinfo> 401</partinfo>
383 402
384<title>Video for Linux Two API Specification</title> 403<title>Video for Linux Two API Specification</title>
385 <subtitle>Revision 2.6.38</subtitle> 404 <subtitle>Revision 2.6.39</subtitle>
386 405
387 <chapter id="common"> 406 <chapter id="common">
388 &sub-common; 407 &sub-common;
@@ -411,6 +430,7 @@ and discussions on the V4L mailing list.</revremark>
411 <section id="radio"> &sub-dev-radio; </section> 430 <section id="radio"> &sub-dev-radio; </section>
412 <section id="rds"> &sub-dev-rds; </section> 431 <section id="rds"> &sub-dev-rds; </section>
413 <section id="event"> &sub-dev-event; </section> 432 <section id="event"> &sub-dev-event; </section>
433 <section id="subdev"> &sub-dev-subdev; </section>
414 </chapter> 434 </chapter>
415 435
416 <chapter id="driver"> 436 <chapter id="driver">
@@ -478,6 +498,12 @@ and discussions on the V4L mailing list.</revremark>
478 &sub-reqbufs; 498 &sub-reqbufs;
479 &sub-s-hw-freq-seek; 499 &sub-s-hw-freq-seek;
480 &sub-streamon; 500 &sub-streamon;
501 &sub-subdev-enum-frame-interval;
502 &sub-subdev-enum-frame-size;
503 &sub-subdev-enum-mbus-code;
504 &sub-subdev-g-crop;
505 &sub-subdev-g-fmt;
506 &sub-subdev-g-frame-interval;
481 &sub-subscribe-event; 507 &sub-subscribe-event;
482 <!-- End of ioctls. --> 508 <!-- End of ioctls. -->
483 &sub-mmap; 509 &sub-mmap;
diff --git a/Documentation/DocBook/v4l/videodev2.h.xml b/Documentation/DocBook/v4l/videodev2.h.xml
index 325b23b6964c..2b796a2ee98a 100644
--- a/Documentation/DocBook/v4l/videodev2.h.xml
+++ b/Documentation/DocBook/v4l/videodev2.h.xml
@@ -71,6 +71,7 @@
71 * Moved from videodev.h 71 * Moved from videodev.h
72 */ 72 */
73#define VIDEO_MAX_FRAME 32 73#define VIDEO_MAX_FRAME 32
74#define VIDEO_MAX_PLANES 8
74 75
75#ifndef __KERNEL__ 76#ifndef __KERNEL__
76 77
@@ -158,9 +159,23 @@ enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> {
158 /* Experimental */ 159 /* Experimental */
159 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, 160 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
160#endif 161#endif
162 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
163 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
161 V4L2_BUF_TYPE_PRIVATE = 0x80, 164 V4L2_BUF_TYPE_PRIVATE = 0x80,
162}; 165};
163 166
167#define V4L2_TYPE_IS_MULTIPLANAR(type) \
168 ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \
169 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
170
171#define V4L2_TYPE_IS_OUTPUT(type) \
172 ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \
173 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \
174 || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \
175 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \
176 || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \
177 || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
178
164enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> { 179enum <link linkend="v4l2-tuner-type">v4l2_tuner_type</link> {
165 V4L2_TUNER_RADIO = 1, 180 V4L2_TUNER_RADIO = 1,
166 V4L2_TUNER_ANALOG_TV = 2, 181 V4L2_TUNER_ANALOG_TV = 2,
@@ -246,6 +261,11 @@ struct <link linkend="v4l2-capability">v4l2_capability</link> {
246#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ 261#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
247#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ 262#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
248 263
264/* Is a video capture device that supports multiplanar formats */
265#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
266/* Is a video output device that supports multiplanar formats */
267#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
268
249#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 269#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
250#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 270#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
251#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ 271#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
@@ -320,6 +340,13 @@ struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> {
320#define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link> v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ 340#define <link linkend="V4L2-PIX-FMT-NV16">V4L2_PIX_FMT_NV16</link> v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
321#define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link> v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ 341#define <link linkend="V4L2-PIX-FMT-NV61">V4L2_PIX_FMT_NV61</link> v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
322 342
343/* two non contiguous planes - one Y, one Cr + Cb interleaved */
344#define <link linkend="V4L2-PIX-FMT-NV12M">V4L2_PIX_FMT_NV12M</link> v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
345#define <link linkend="V4L2-PIX-FMT-NV12MT">V4L2_PIX_FMT_NV12MT</link> v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
346
347/* three non contiguous planes - Y, Cb, Cr */
348#define <link linkend="V4L2-PIX-FMT-YUV420M">V4L2_PIX_FMT_YUV420M</link> v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
349
323/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ 350/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
324#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ 351#define <link linkend="V4L2-PIX-FMT-SBGGR8">V4L2_PIX_FMT_SBGGR8</link> v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
325#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ 352#define <link linkend="V4L2-PIX-FMT-SGBRG8">V4L2_PIX_FMT_SGBRG8</link> v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
@@ -518,6 +545,62 @@ struct <link linkend="v4l2-requestbuffers">v4l2_requestbuffers</link> {
518 __u32 reserved[2]; 545 __u32 reserved[2];
519}; 546};
520 547
548/**
549 * struct <link linkend="v4l2-plane">v4l2_plane</link> - plane info for multi-planar buffers
550 * @bytesused: number of bytes occupied by data in the plane (payload)
551 * @length: size of this plane (NOT the payload) in bytes
552 * @mem_offset: when memory in the associated struct <link linkend="v4l2-buffer">v4l2_buffer</link> is
553 * V4L2_MEMORY_MMAP, equals the offset from the start of
554 * the device memory for this plane (or is a "cookie" that
555 * should be passed to mmap() called on the video node)
556 * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
557 * pointing to this plane
558 * @data_offset: offset in the plane to the start of data; usually 0,
559 * unless there is a header in front of the data
560 *
561 * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
562 * with two planes can have one plane for Y, and another for interleaved CbCr
563 * components. Each plane can reside in a separate memory buffer, or even in
564 * a completely separate memory node (e.g. in embedded devices).
565 */
566struct <link linkend="v4l2-plane">v4l2_plane</link> {
567 __u32 bytesused;
568 __u32 length;
569 union {
570 __u32 mem_offset;
571 unsigned long userptr;
572 } m;
573 __u32 data_offset;
574 __u32 reserved[11];
575};
576
577/**
578 * struct <link linkend="v4l2-buffer">v4l2_buffer</link> - video buffer info
579 * @index: id number of the buffer
580 * @type: buffer type (type == *_MPLANE for multiplanar buffers)
581 * @bytesused: number of bytes occupied by data in the buffer (payload);
582 * unused (set to 0) for multiplanar buffers
583 * @flags: buffer informational flags
584 * @field: field order of the image in the buffer
585 * @timestamp: frame timestamp
586 * @timecode: frame timecode
587 * @sequence: sequence count of this frame
588 * @memory: the method, in which the actual video data is passed
589 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
590 * offset from the start of the device memory for this plane,
591 * (or a "cookie" that should be passed to mmap() as offset)
592 * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
593 * a userspace pointer pointing to this buffer
594 * @planes: for multiplanar buffers; userspace pointer to the array of plane
595 * info structs for this buffer
596 * @length: size in bytes of the buffer (NOT its payload) for single-plane
597 * buffers (when type != *_MPLANE); number of elements in the
598 * planes array for multi-plane buffers
599 * @input: input number from which the video data has has been captured
600 *
601 * Contains data exchanged by application and driver using one of the Streaming
602 * I/O methods.
603 */
521struct <link linkend="v4l2-buffer">v4l2_buffer</link> { 604struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
522 __u32 index; 605 __u32 index;
523 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type; 606 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
@@ -533,6 +616,7 @@ struct <link linkend="v4l2-buffer">v4l2_buffer</link> {
533 union { 616 union {
534 __u32 offset; 617 __u32 offset;
535 unsigned long userptr; 618 unsigned long userptr;
619 struct <link linkend="v4l2-plane">v4l2_plane</link> *planes;
536 } m; 620 } m;
537 __u32 length; 621 __u32 length;
538 __u32 input; 622 __u32 input;
@@ -1623,12 +1707,56 @@ struct <link linkend="v4l2-mpeg-vbi-fmt-ivtv">v4l2_mpeg_vbi_fmt_ivtv</link> {
1623 * A G G R E G A T E S T R U C T U R E S 1707 * A G G R E G A T E S T R U C T U R E S
1624 */ 1708 */
1625 1709
1626/* Stream data format 1710/**
1711 * struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> - additional, per-plane format definition
1712 * @sizeimage: maximum size in bytes required for data, for which
1713 * this plane will be used
1714 * @bytesperline: distance in bytes between the leftmost pixels in two
1715 * adjacent lines
1716 */
1717struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> {
1718 __u32 sizeimage;
1719 __u16 bytesperline;
1720 __u16 reserved[7];
1721} __attribute__ ((packed));
1722
1723/**
1724 * struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> - multiplanar format definition
1725 * @width: image width in pixels
1726 * @height: image height in pixels
1727 * @pixelformat: little endian four character code (fourcc)
1728 * @field: field order (for interlaced video)
1729 * @colorspace: supplemental to pixelformat
1730 * @plane_fmt: per-plane information
1731 * @num_planes: number of planes for this format
1732 */
1733struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> {
1734 __u32 width;
1735 __u32 height;
1736 __u32 pixelformat;
1737 enum <link linkend="v4l2-field">v4l2_field</link> field;
1738 enum <link linkend="v4l2-colorspace">v4l2_colorspace</link> colorspace;
1739
1740 struct <link linkend="v4l2-plane-pix-format">v4l2_plane_pix_format</link> plane_fmt[VIDEO_MAX_PLANES];
1741 __u8 num_planes;
1742 __u8 reserved[11];
1743} __attribute__ ((packed));
1744
1745/**
1746 * struct <link linkend="v4l2-format">v4l2_format</link> - stream data format
1747 * @type: type of the data stream
1748 * @pix: definition of an image format
1749 * @pix_mp: definition of a multiplanar image format
1750 * @win: definition of an overlaid image
1751 * @vbi: raw VBI capture or output parameters
1752 * @sliced: sliced VBI capture or output parameters
1753 * @raw_data: placeholder for future extensions and custom formats
1627 */ 1754 */
1628struct <link linkend="v4l2-format">v4l2_format</link> { 1755struct <link linkend="v4l2-format">v4l2_format</link> {
1629 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type; 1756 enum <link linkend="v4l2-buf-type">v4l2_buf_type</link> type;
1630 union { 1757 union {
1631 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ 1758 struct <link linkend="v4l2-pix-format">v4l2_pix_format</link> pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
1759 struct <link linkend="v4l2-pix-format-mplane">v4l2_pix_format_mplane</link> pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
1632 struct <link linkend="v4l2-window">v4l2_window</link> win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ 1760 struct <link linkend="v4l2-window">v4l2_window</link> win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
1633 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ 1761 struct <link linkend="v4l2-vbi-format">v4l2_vbi_format</link> vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
1634 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ 1762 struct <link linkend="v4l2-sliced-vbi-format">v4l2_sliced_vbi_format</link> sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
@@ -1636,7 +1764,6 @@ struct <link linkend="v4l2-format">v4l2_format</link> {
1636 } fmt; 1764 } fmt;
1637}; 1765};
1638 1766
1639
1640/* Stream type-dependent parameters 1767/* Stream type-dependent parameters
1641 */ 1768 */
1642struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> { 1769struct <link linkend="v4l2-streamparm">v4l2_streamparm</link> {
@@ -1809,16 +1936,6 @@ struct <link linkend="v4l2-dbg-chip-ident">v4l2_dbg_chip_ident</link> {
1809/* Reminder: when adding new ioctls please add support for them to 1936/* Reminder: when adding new ioctls please add support for them to
1810 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 1937 drivers/media/video/v4l2-compat-ioctl32.c as well! */
1811 1938
1812#ifdef __OLD_VIDIOC_
1813/* for compatibility, will go away some day */
1814#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
1815#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct <link linkend="v4l2-streamparm">v4l2_streamparm</link>)
1816#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct <link linkend="v4l2-control">v4l2_control</link>)
1817#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct <link linkend="v4l2-audio">v4l2_audio</link>)
1818#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct <link linkend="v4l2-audioout">v4l2_audioout</link>)
1819#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct <link linkend="v4l2-cropcap">v4l2_cropcap</link>)
1820#endif
1821
1822#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ 1939#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
1823 1940
1824#endif /* __LINUX_VIDEODEV2_H */ 1941#endif /* __LINUX_VIDEODEV2_H */
diff --git a/Documentation/DocBook/v4l/vidioc-enum-fmt.xml b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
index 960d44615ca6..71d373b6d36a 100644
--- a/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
+++ b/Documentation/DocBook/v4l/vidioc-enum-fmt.xml
@@ -76,7 +76,9 @@ pixelformat</structfield> field.</entry>
76 <entry>Type of the data stream, set by the application. 76 <entry>Type of the data stream, set by the application.
77Only these types are valid here: 77Only these types are valid here:
78<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>, 78<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>,
79<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>,
79<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>, 80<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
81<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>,
80<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver 82<constant>V4L2_BUF_TYPE_VIDEO_OVERLAY</constant>, and custom (driver
81defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant> 83defined) types with code <constant>V4L2_BUF_TYPE_PRIVATE</constant>
82and higher.</entry> 84and higher.</entry>
diff --git a/Documentation/DocBook/v4l/vidioc-g-fmt.xml b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
index 7c7d1b72c40d..a4ae59b664eb 100644
--- a/Documentation/DocBook/v4l/vidioc-g-fmt.xml
+++ b/Documentation/DocBook/v4l/vidioc-g-fmt.xml
@@ -60,11 +60,13 @@ application.</para>
60<structfield>type</structfield> field of a struct 60<structfield>type</structfield> field of a struct
61<structname>v4l2_format</structname> to the respective buffer (stream) 61<structname>v4l2_format</structname> to the respective buffer (stream)
62type. For example video capture devices use 62type. For example video capture devices use
63<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant>. When the application 63<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE</constant> or
64<constant>V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE</constant>. When the application
64calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to 65calls the <constant>VIDIOC_G_FMT</constant> ioctl with a pointer to
65this structure the driver fills the respective member of the 66this structure the driver fills the respective member of the
66<structfield>fmt</structfield> union. In case of video capture devices 67<structfield>fmt</structfield> union. In case of video capture devices
67that is the &v4l2-pix-format; <structfield>pix</structfield> member. 68that is either the &v4l2-pix-format; <structfield>pix</structfield> or
69the &v4l2-pix-format-mplane; <structfield>pix_mp</structfield> member.
68When the requested buffer type is not supported drivers return an 70When the requested buffer type is not supported drivers return an
69&EINVAL;.</para> 71&EINVAL;.</para>
70 72
@@ -134,6 +136,15 @@ devices.</entry>
134 </row> 136 </row>
135 <row> 137 <row>
136 <entry></entry> 138 <entry></entry>
139 <entry>&v4l2-pix-format-mplane;</entry>
140 <entry><structfield>pix_mp</structfield></entry>
141 <entry>Definition of an image format, see <xref
142 linkend="pixfmt" />, used by video capture and output
143devices that support the <link linkend="planar-apis">multi-planar
144version of the API</link>.</entry>
145 </row>
146 <row>
147 <entry></entry>
137 <entry>&v4l2-window;</entry> 148 <entry>&v4l2-window;</entry>
138 <entry><structfield>win</structfield></entry> 149 <entry><structfield>win</structfield></entry>
139 <entry>Definition of an overlaid image, see <xref 150 <entry>Definition of an overlaid image, see <xref
diff --git a/Documentation/DocBook/v4l/vidioc-qbuf.xml b/Documentation/DocBook/v4l/vidioc-qbuf.xml
index ab691ebf3b93..f2b11f8a4031 100644
--- a/Documentation/DocBook/v4l/vidioc-qbuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-qbuf.xml
@@ -64,7 +64,8 @@ zero to the number of buffers allocated with &VIDIOC-REQBUFS;
64contents of the struct <structname>v4l2_buffer</structname> returned 64contents of the struct <structname>v4l2_buffer</structname> returned
65by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is 65by a &VIDIOC-QUERYBUF; ioctl will do as well. When the buffer is
66intended for output (<structfield>type</structfield> is 66intended for output (<structfield>type</structfield> is
67<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant> or 67<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT</constant>,
68<constant>V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE</constant>, or
68<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also 69<constant>V4L2_BUF_TYPE_VBI_OUTPUT</constant>) applications must also
69initialize the <structfield>bytesused</structfield>, 70initialize the <structfield>bytesused</structfield>,
70<structfield>field</structfield> and 71<structfield>field</structfield> and
@@ -75,7 +76,11 @@ supports capturing from specific video inputs and you want to specify a video
75input, then <structfield>flags</structfield> should be set to 76input, then <structfield>flags</structfield> should be set to
76<constant>V4L2_BUF_FLAG_INPUT</constant> and the field 77<constant>V4L2_BUF_FLAG_INPUT</constant> and the field
77<structfield>input</structfield> must be initialized to the desired input. 78<structfield>input</structfield> must be initialized to the desired input.
78The <structfield>reserved</structfield> field must be set to 0. 79The <structfield>reserved</structfield> field must be set to 0. When using
80the <link linkend="planar-apis">multi-planar API</link>, the
81<structfield>m.planes</structfield> field must contain a userspace pointer
82to a filled-in array of &v4l2-plane; and the <structfield>length</structfield>
83field must be set to the number of elements in that array.
79</para> 84</para>
80 85
81 <para>To enqueue a <link linkend="mmap">memory mapped</link> 86 <para>To enqueue a <link linkend="mmap">memory mapped</link>
@@ -93,10 +98,13 @@ structure the driver sets the
93buffer applications set the <structfield>memory</structfield> 98buffer applications set the <structfield>memory</structfield>
94field to <constant>V4L2_MEMORY_USERPTR</constant>, the 99field to <constant>V4L2_MEMORY_USERPTR</constant>, the
95<structfield>m.userptr</structfield> field to the address of the 100<structfield>m.userptr</structfield> field to the address of the
96buffer and <structfield>length</structfield> to its size. 101buffer and <structfield>length</structfield> to its size. When the multi-planar
97When <constant>VIDIOC_QBUF</constant> is called with a pointer to this 102API is used, <structfield>m.userptr</structfield> and
98structure the driver sets the <constant>V4L2_BUF_FLAG_QUEUED</constant> 103<structfield>length</structfield> members of the passed array of &v4l2-plane;
99flag and clears the <constant>V4L2_BUF_FLAG_MAPPED</constant> and 104have to be used instead. When <constant>VIDIOC_QBUF</constant> is called with
105a pointer to this structure the driver sets the
106<constant>V4L2_BUF_FLAG_QUEUED</constant> flag and clears the
107<constant>V4L2_BUF_FLAG_MAPPED</constant> and
100<constant>V4L2_BUF_FLAG_DONE</constant> flags in the 108<constant>V4L2_BUF_FLAG_DONE</constant> flags in the
101<structfield>flags</structfield> field, or it returns an error code. 109<structfield>flags</structfield> field, or it returns an error code.
102This ioctl locks the memory pages of the buffer in physical memory, 110This ioctl locks the memory pages of the buffer in physical memory,
@@ -115,7 +123,9 @@ remaining fields or returns an error code. The driver may also set
115<constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield> 123<constant>V4L2_BUF_FLAG_ERROR</constant> in the <structfield>flags</structfield>
116field. It indicates a non-critical (recoverable) streaming error. In such case 124field. It indicates a non-critical (recoverable) streaming error. In such case
117the application may continue as normal, but should be aware that data in the 125the application may continue as normal, but should be aware that data in the
118dequeued buffer might be corrupted.</para> 126dequeued buffer might be corrupted. When using the multi-planar API, the
127planes array does not have to be passed; the <structfield>m.planes</structfield>
128member must be set to NULL in that case.</para>
119 129
120 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no 130 <para>By default <constant>VIDIOC_DQBUF</constant> blocks when no
121buffer is in the outgoing queue. When the 131buffer is in the outgoing queue. When the
diff --git a/Documentation/DocBook/v4l/vidioc-querybuf.xml b/Documentation/DocBook/v4l/vidioc-querybuf.xml
index e649805a4908..5c104d42d31c 100644
--- a/Documentation/DocBook/v4l/vidioc-querybuf.xml
+++ b/Documentation/DocBook/v4l/vidioc-querybuf.xml
@@ -61,6 +61,10 @@ buffer at any time after buffers have been allocated with the
61to the number of buffers allocated with &VIDIOC-REQBUFS; 61to the number of buffers allocated with &VIDIOC-REQBUFS;
62 (&v4l2-requestbuffers; <structfield>count</structfield>) minus one. 62 (&v4l2-requestbuffers; <structfield>count</structfield>) minus one.
63The <structfield>reserved</structfield> field should to set to 0. 63The <structfield>reserved</structfield> field should to set to 0.
64When using the <link linkend="planar-apis">multi-planar API</link>, the
65<structfield>m.planes</structfield> field must contain a userspace pointer to an
66array of &v4l2-plane; and the <structfield>length</structfield> field has
67to be set to the number of elements in that array.
64After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to 68After calling <constant>VIDIOC_QUERYBUF</constant> with a pointer to
65 this structure drivers return an error code or fill the rest of 69 this structure drivers return an error code or fill the rest of
66the structure.</para> 70the structure.</para>
@@ -70,11 +74,13 @@ the structure.</para>
70<constant>V4L2_BUF_FLAG_QUEUED</constant> and 74<constant>V4L2_BUF_FLAG_QUEUED</constant> and
71<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The 75<constant>V4L2_BUF_FLAG_DONE</constant> flags will be valid. The
72<structfield>memory</structfield> field will be set to the current 76<structfield>memory</structfield> field will be set to the current
73I/O method, the <structfield>m.offset</structfield> 77I/O method. For the single-planar API, the <structfield>m.offset</structfield>
74contains the offset of the buffer from the start of the device memory, 78contains the offset of the buffer from the start of the device memory,
75the <structfield>length</structfield> field its size. The driver may 79the <structfield>length</structfield> field its size. For the multi-planar API,
76or may not set the remaining fields and flags, they are meaningless in 80fields <structfield>m.mem_offset</structfield> and
77this context.</para> 81<structfield>length</structfield> in the <structfield>m.planes</structfield>
82array elements will be used instead. The driver may or may not set the remaining
83fields and flags, they are meaningless in this context.</para>
78 84
79 <para>The <structname>v4l2_buffer</structname> structure is 85 <para>The <structname>v4l2_buffer</structname> structure is
80 specified in <xref linkend="buffer" />.</para> 86 specified in <xref linkend="buffer" />.</para>
diff --git a/Documentation/DocBook/v4l/vidioc-querycap.xml b/Documentation/DocBook/v4l/vidioc-querycap.xml
index d499da93a450..f29f1b86213c 100644
--- a/Documentation/DocBook/v4l/vidioc-querycap.xml
+++ b/Documentation/DocBook/v4l/vidioc-querycap.xml
@@ -142,16 +142,30 @@ this array to zero.</entry>
142 <row> 142 <row>
143 <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry> 143 <entry><constant>V4L2_CAP_VIDEO_CAPTURE</constant></entry>
144 <entry>0x00000001</entry> 144 <entry>0x00000001</entry>
145 <entry>The device supports the <link 145 <entry>The device supports the single-planar API through the <link
146linkend="capture">Video Capture</link> interface.</entry> 146linkend="capture">Video Capture</link> interface.</entry>
147 </row> 147 </row>
148 <row> 148 <row>
149 <entry><constant>V4L2_CAP_VIDEO_CAPTURE_MPLANE</constant></entry>
150 <entry>0x00001000</entry>
151 <entry>The device supports the
152 <link linkend="planar-apis">multi-planar API</link> through the
153 <link linkend="capture">Video Capture</link> interface.</entry>
154 </row>
155 <row>
149 <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry> 156 <entry><constant>V4L2_CAP_VIDEO_OUTPUT</constant></entry>
150 <entry>0x00000002</entry> 157 <entry>0x00000002</entry>
151 <entry>The device supports the <link 158 <entry>The device supports the single-planar API through the <link
152linkend="output">Video Output</link> interface.</entry> 159linkend="output">Video Output</link> interface.</entry>
153 </row> 160 </row>
154 <row> 161 <row>
162 <entry><constant>V4L2_CAP_VIDEO_OUTPUT_MPLANE</constant></entry>
163 <entry>0x00002000</entry>
164 <entry>The device supports the
165 <link linkend="planar-apis">multi-planar API</link> through the
166 <link linkend="output">Video Output</link> interface.</entry>
167 </row>
168 <row>
155 <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry> 169 <entry><constant>V4L2_CAP_VIDEO_OVERLAY</constant></entry>
156 <entry>0x00000004</entry> 170 <entry>0x00000004</entry>
157 <entry>The device supports the <link 171 <entry>The device supports the <link
diff --git a/Documentation/DocBook/v4l/vidioc-streamon.xml b/Documentation/DocBook/v4l/vidioc-streamon.xml
index e42bff1f2c0a..75ed39bf4d2b 100644
--- a/Documentation/DocBook/v4l/vidioc-streamon.xml
+++ b/Documentation/DocBook/v4l/vidioc-streamon.xml
@@ -93,6 +93,15 @@ synchronize with other events.</para>
93been allocated (memory mapping) or enqueued (output) yet.</para> 93been allocated (memory mapping) or enqueued (output) yet.</para>
94 </listitem> 94 </listitem>
95 </varlistentry> 95 </varlistentry>
96 <varlistentry>
97 <term><errorcode>EPIPE</errorcode></term>
98 <listitem>
99 <para>The driver implements <link
100 linkend="pad-level-formats">pad-level format configuration</link> and
101 the pipeline configuration is invalid.
102 </para>
103 </listitem>
104 </varlistentry>
96 </variablelist> 105 </variablelist>
97 </refsect1> 106 </refsect1>
98</refentry> 107</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
new file mode 100644
index 000000000000..2f8f4f0a0235
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-interval.xml
@@ -0,0 +1,152 @@
1<refentry id="vidioc-subdev-enum-frame-interval">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</refname>
9 <refpurpose>Enumerate frame intervals</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_subdev_frame_interval_enum *
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_SUBDEV_ENUM_FRAME_INTERVAL</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 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>This ioctl lets applications enumerate available frame intervals on a
59 given sub-device pad. Frame intervals only makes sense for sub-devices that
60 can control the frame period on their own. This includes, for instance,
61 image sensors and TV tuners.</para>
62
63 <para>For the common use case of image sensors, the frame intervals
64 available on the sub-device output pad depend on the frame format and size
65 on the same pad. Applications must thus specify the desired format and size
66 when enumerating frame intervals.</para>
67
68 <para>To enumerate frame intervals applications initialize the
69 <structfield>index</structfield>, <structfield>pad</structfield>,
70 <structfield>code</structfield>, <structfield>width</structfield> and
71 <structfield>height</structfield> fields of
72 &v4l2-subdev-frame-interval-enum; and call the
73 <constant>VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL</constant> ioctl with a pointer
74 to this structure. Drivers fill the rest of the structure or return
75 an &EINVAL; if one of the input fields is invalid. All frame intervals are
76 enumerable by beginning at index zero and incrementing by one until
77 <errorcode>EINVAL</errorcode> is returned.</para>
78
79 <para>Available frame intervals may depend on the current 'try' formats
80 at other pads of the sub-device, as well as on the current active links. See
81 &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
82
83 <para>Sub-devices that support the frame interval enumeration ioctl should
84 implemented it on a single pad only. Its behaviour when supported on
85 multiple pads of the same sub-device is not defined.</para>
86
87 <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval-enum">
88 <title>struct <structname>v4l2_subdev_frame_interval_enum</structname></title>
89 <tgroup cols="3">
90 &cs-str;
91 <tbody valign="top">
92 <row>
93 <entry>__u32</entry>
94 <entry><structfield>index</structfield></entry>
95 <entry>Number of the format in the enumeration, set by the
96 application.</entry>
97 </row>
98 <row>
99 <entry>__u32</entry>
100 <entry><structfield>pad</structfield></entry>
101 <entry>Pad number as reported by the media controller API.</entry>
102 </row>
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>code</structfield></entry>
106 <entry>The media bus format code, as defined in
107 <xref linkend="v4l2-mbus-format" />.</entry>
108 </row>
109 <row>
110 <entry>__u32</entry>
111 <entry><structfield>width</structfield></entry>
112 <entry>Frame width, in pixels.</entry>
113 </row>
114 <row>
115 <entry>__u32</entry>
116 <entry><structfield>height</structfield></entry>
117 <entry>Frame height, in pixels.</entry>
118 </row>
119 <row>
120 <entry>&v4l2-fract;</entry>
121 <entry><structfield>interval</structfield></entry>
122 <entry>Period, in seconds, between consecutive video frames.</entry>
123 </row>
124 <row>
125 <entry>__u32</entry>
126 <entry><structfield>reserved</structfield>[9]</entry>
127 <entry>Reserved for future extensions. Applications and drivers must
128 set the array to zero.</entry>
129 </row>
130 </tbody>
131 </tgroup>
132 </table>
133 </refsect1>
134
135 <refsect1>
136 &return-value;
137
138 <variablelist>
139 <varlistentry>
140 <term><errorcode>EINVAL</errorcode></term>
141 <listitem>
142 <para>The &v4l2-subdev-frame-interval-enum;
143 <structfield>pad</structfield> references a non-existing pad, one of
144 the <structfield>code</structfield>, <structfield>width</structfield>
145 or <structfield>height</structfield> fields are invalid for the given
146 pad or the <structfield>index</structfield> field is out of bounds.
147 </para>
148 </listitem>
149 </varlistentry>
150 </variablelist>
151 </refsect1>
152</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
new file mode 100644
index 000000000000..79ce42b7c60c
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-frame-size.xml
@@ -0,0 +1,154 @@
1<refentry id="vidioc-subdev-enum-frame-size">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</refname>
9 <refpurpose>Enumerate media bus frame sizes</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_subdev_frame_size_enum *
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_SUBDEV_ENUM_FRAME_SIZE</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 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>This ioctl allows applications to enumerate all frame sizes
59 supported by a sub-device on the given pad for the given media bus format.
60 Supported formats can be retrieved with the &VIDIOC-SUBDEV-ENUM-MBUS-CODE;
61 ioctl.</para>
62
63 <para>To enumerate frame sizes applications initialize the
64 <structfield>pad</structfield>, <structfield>code</structfield> and
65 <structfield>index</structfield> fields of the
66 &v4l2-subdev-mbus-code-enum; and call the
67 <constant>VIDIOC_SUBDEV_ENUM_FRAME_SIZE</constant> ioctl with a pointer to
68 the structure. Drivers fill the minimum and maximum frame sizes or return
69 an &EINVAL; if one of the input parameters is invalid.</para>
70
71 <para>Sub-devices that only support discrete frame sizes (such as most
72 sensors) will return one or more frame sizes with identical minimum and
73 maximum values.</para>
74
75 <para>Not all possible sizes in given [minimum, maximum] ranges need to be
76 supported. For instance, a scaler that uses a fixed-point scaling ratio
77 might not be able to produce every frame size between the minimum and
78 maximum values. Applications must use the &VIDIOC-SUBDEV-S-FMT; ioctl to
79 try the sub-device for an exact supported frame size.</para>
80
81 <para>Available frame sizes may depend on the current 'try' formats at other
82 pads of the sub-device, as well as on the current active links and the
83 current values of V4L2 controls. See &VIDIOC-SUBDEV-G-FMT; for more
84 information about try formats.</para>
85
86 <table pgwide="1" frame="none" id="v4l2-subdev-frame-size-enum">
87 <title>struct <structname>v4l2_subdev_frame_size_enum</structname></title>
88 <tgroup cols="3">
89 &cs-str;
90 <tbody valign="top">
91 <row>
92 <entry>__u32</entry>
93 <entry><structfield>index</structfield></entry>
94 <entry>Number of the format in the enumeration, set by the
95 application.</entry>
96 </row>
97 <row>
98 <entry>__u32</entry>
99 <entry><structfield>pad</structfield></entry>
100 <entry>Pad number as reported by the media controller API.</entry>
101 </row>
102 <row>
103 <entry>__u32</entry>
104 <entry><structfield>code</structfield></entry>
105 <entry>The media bus format code, as defined in
106 <xref linkend="v4l2-mbus-format" />.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>min_width</structfield></entry>
111 <entry>Minimum frame width, in pixels.</entry>
112 </row>
113 <row>
114 <entry>__u32</entry>
115 <entry><structfield>max_width</structfield></entry>
116 <entry>Maximum frame width, in pixels.</entry>
117 </row>
118 <row>
119 <entry>__u32</entry>
120 <entry><structfield>min_height</structfield></entry>
121 <entry>Minimum frame height, in pixels.</entry>
122 </row>
123 <row>
124 <entry>__u32</entry>
125 <entry><structfield>max_height</structfield></entry>
126 <entry>Maximum frame height, in pixels.</entry>
127 </row>
128 <row>
129 <entry>__u32</entry>
130 <entry><structfield>reserved</structfield>[9]</entry>
131 <entry>Reserved for future extensions. Applications and drivers must
132 set the array to zero.</entry>
133 </row>
134 </tbody>
135 </tgroup>
136 </table>
137 </refsect1>
138
139 <refsect1>
140 &return-value;
141
142 <variablelist>
143 <varlistentry>
144 <term><errorcode>EINVAL</errorcode></term>
145 <listitem>
146 <para>The &v4l2-subdev-frame-size-enum; <structfield>pad</structfield>
147 references a non-existing pad, the <structfield>code</structfield> is
148 invalid for the given pad or the <structfield>index</structfield>
149 field is out of bounds.</para>
150 </listitem>
151 </varlistentry>
152 </variablelist>
153 </refsect1>
154</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml b/Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
new file mode 100644
index 000000000000..a6b3432449f6
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-enum-mbus-code.xml
@@ -0,0 +1,119 @@
1<refentry id="vidioc-subdev-enum-mbus-code">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_ENUM_MBUS_CODE</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_ENUM_MBUS_CODE</refname>
9 <refpurpose>Enumerate media bus 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_subdev_mbus_code_enum *
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_SUBDEV_ENUM_MBUS_CODE</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 <para>This is an <link linkend="experimental">experimental</link>
55 interface and may change in the future.</para>
56 </note>
57
58 <para>To enumerate media bus formats available at a given sub-device pad
59 applications initialize the <structfield>pad</structfield> and
60 <structfield>index</structfield> fields of &v4l2-subdev-mbus-code-enum; and
61 call the <constant>VIDIOC_SUBDEV_ENUM_MBUS_CODE</constant> ioctl with a
62 pointer to this structure. Drivers fill the rest of the structure or return
63 an &EINVAL; if either the <structfield>pad</structfield> or
64 <structfield>index</structfield> are invalid. All media bus formats are
65 enumerable by beginning at index zero and incrementing by one until
66 <errorcode>EINVAL</errorcode> is returned.</para>
67
68 <para>Available media bus formats may depend on the current 'try' formats
69 at other pads of the sub-device, as well as on the current active links. See
70 &VIDIOC-SUBDEV-G-FMT; for more information about the try formats.</para>
71
72 <table pgwide="1" frame="none" id="v4l2-subdev-mbus-code-enum">
73 <title>struct <structname>v4l2_subdev_mbus_code_enum</structname></title>
74 <tgroup cols="3">
75 &cs-str;
76 <tbody valign="top">
77 <row>
78 <entry>__u32</entry>
79 <entry><structfield>pad</structfield></entry>
80 <entry>Pad number as reported by the media controller API.</entry>
81 </row>
82 <row>
83 <entry>__u32</entry>
84 <entry><structfield>index</structfield></entry>
85 <entry>Number of the format in the enumeration, set by the
86 application.</entry>
87 </row>
88 <row>
89 <entry>__u32</entry>
90 <entry><structfield>code</structfield></entry>
91 <entry>The media bus format code, as defined in
92 <xref linkend="v4l2-mbus-format" />.</entry>
93 </row>
94 <row>
95 <entry>__u32</entry>
96 <entry><structfield>reserved</structfield>[9]</entry>
97 <entry>Reserved for future extensions. Applications and drivers must
98 set the array to zero.</entry>
99 </row>
100 </tbody>
101 </tgroup>
102 </table>
103 </refsect1>
104
105 <refsect1>
106 &return-value;
107
108 <variablelist>
109 <varlistentry>
110 <term><errorcode>EINVAL</errorcode></term>
111 <listitem>
112 <para>The &v4l2-subdev-mbus-code-enum; <structfield>pad</structfield>
113 references a non-existing pad, or the <structfield>index</structfield>
114 field is out of bounds.</para>
115 </listitem>
116 </varlistentry>
117 </variablelist>
118 </refsect1>
119</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
new file mode 100644
index 000000000000..06197323a8cc
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-crop.xml
@@ -0,0 +1,155 @@
1<refentry id="vidioc-subdev-g-crop">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_CROP, VIDIOC_SUBDEV_S_CROP</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_CROP</refname>
9 <refname>VIDIOC_SUBDEV_S_CROP</refname>
10 <refpurpose>Get or set the crop rectangle on a subdev pad</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_subdev_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_subdev_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_SUBDEV_G_CROP, VIDIOC_SUBDEV_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 <note>
61 <title>Experimental</title>
62 <para>This is an <link linkend="experimental">experimental</link>
63 interface and may change in the future.</para>
64 </note>
65
66 <para>To retrieve the current crop rectangle applications set the
67 <structfield>pad</structfield> field of a &v4l2-subdev-crop; to the
68 desired pad number as reported by the media API and the
69 <structfield>which</structfield> field to
70 <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. They then call the
71 <constant>VIDIOC_SUBDEV_G_CROP</constant> ioctl with a pointer to this
72 structure. The driver fills the members of the <structfield>rect</structfield>
73 field or returns &EINVAL; if the input arguments are invalid, or if cropping
74 is not supported on the given pad.</para>
75
76 <para>To change the current crop rectangle applications set both the
77 <structfield>pad</structfield> and <structfield>which</structfield> fields
78 and all members of the <structfield>rect</structfield> field. They then call
79 the <constant>VIDIOC_SUBDEV_S_CROP</constant> ioctl with a pointer to this
80 structure. The driver verifies the requested crop rectangle, adjusts it
81 based on the hardware capabilities and configures the device. Upon return
82 the &v4l2-subdev-crop; contains the current format as would be returned
83 by a <constant>VIDIOC_SUBDEV_G_CROP</constant> call.</para>
84
85 <para>Applications can query the device capabilities by setting the
86 <structfield>which</structfield> to
87 <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' crop
88 rectangles are not applied to the device by the driver, but are mangled
89 exactly as active crop rectangles and stored in the sub-device file handle.
90 Two applications querying the same sub-device would thus not interact with
91 each other.</para>
92
93 <para>Drivers must not return an error solely because the requested crop
94 rectangle doesn't match the device capabilities. They must instead modify
95 the rectangle to match what the hardware can provide. The modified format
96 should be as close as possible to the original request.</para>
97
98 <table pgwide="1" frame="none" id="v4l2-subdev-crop">
99 <title>struct <structname>v4l2_subdev_crop</structname></title>
100 <tgroup cols="3">
101 &cs-str;
102 <tbody valign="top">
103 <row>
104 <entry>__u32</entry>
105 <entry><structfield>pad</structfield></entry>
106 <entry>Pad number as reported by the media framework.</entry>
107 </row>
108 <row>
109 <entry>__u32</entry>
110 <entry><structfield>which</structfield></entry>
111 <entry>Crop rectangle to get or set, from
112 &v4l2-subdev-format-whence;.</entry>
113 </row>
114 <row>
115 <entry>&v4l2-rect;</entry>
116 <entry><structfield>rect</structfield></entry>
117 <entry>Crop rectangle boundaries, in pixels.</entry>
118 </row>
119 <row>
120 <entry>__u32</entry>
121 <entry><structfield>reserved</structfield>[8]</entry>
122 <entry>Reserved for future extensions. Applications and drivers must
123 set the array to zero.</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 crop rectangle can't be changed because the pad is currently
138 busy. This can be caused, for instance, by an active video stream on
139 the pad. The ioctl must not be retried without performing another
140 action to fix the problem first. Only returned by
141 <constant>VIDIOC_SUBDEV_S_CROP</constant></para>
142 </listitem>
143 </varlistentry>
144 <varlistentry>
145 <term><errorcode>EINVAL</errorcode></term>
146 <listitem>
147 <para>The &v4l2-subdev-crop; <structfield>pad</structfield>
148 references a non-existing pad, the <structfield>which</structfield>
149 field references a non-existing format, or cropping is not supported
150 on the given subdev pad.</para>
151 </listitem>
152 </varlistentry>
153 </variablelist>
154 </refsect1>
155</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
new file mode 100644
index 000000000000..f367c570c530
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-fmt.xml
@@ -0,0 +1,180 @@
1<refentry id="vidioc-subdev-g-fmt">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_FMT</refname>
9 <refname>VIDIOC_SUBDEV_S_FMT</refname>
10 <refpurpose>Get or set the data format on a subdev pad</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_subdev_format *<parameter>argp</parameter>
20 </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_SUBDEV_G_FMT, VIDIOC_SUBDEV_S_FMT</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 <note>
54 <title>Experimental</title>
55 <para>This is an <link linkend="experimental">experimental</link>
56 interface and may change in the future.</para>
57 </note>
58
59 <para>These ioctls are used to negotiate the frame format at specific
60 subdev pads in the image pipeline.</para>
61
62 <para>To retrieve the current format applications set the
63 <structfield>pad</structfield> field of a &v4l2-subdev-format; to the
64 desired pad number as reported by the media API and the
65 <structfield>which</structfield> field to
66 <constant>V4L2_SUBDEV_FORMAT_ACTIVE</constant>. When they call the
67 <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl with a pointer to this
68 structure the driver fills the members of the <structfield>format</structfield>
69 field.</para>
70
71 <para>To change the current format applications set both the
72 <structfield>pad</structfield> and <structfield>which</structfield> fields
73 and all members of the <structfield>format</structfield> field. When they
74 call the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl with a pointer to this
75 structure the driver verifies the requested format, adjusts it based on the
76 hardware capabilities and configures the device. Upon return the
77 &v4l2-subdev-format; contains the current format as would be returned by a
78 <constant>VIDIOC_SUBDEV_G_FMT</constant> call.</para>
79
80 <para>Applications can query the device capabilities by setting the
81 <structfield>which</structfield> to
82 <constant>V4L2_SUBDEV_FORMAT_TRY</constant>. When set, 'try' formats are not
83 applied to the device by the driver, but are changed exactly as active
84 formats and stored in the sub-device file handle. Two applications querying
85 the same sub-device would thus not interact with each other.</para>
86
87 <para>For instance, to try a format at the output pad of a sub-device,
88 applications would first set the try format at the sub-device input with the
89 <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl. They would then either
90 retrieve the default format at the output pad with the
91 <constant>VIDIOC_SUBDEV_G_FMT</constant> ioctl, or set the desired output
92 pad format with the <constant>VIDIOC_SUBDEV_S_FMT</constant> ioctl and check
93 the returned value.</para>
94
95 <para>Try formats do not depend on active formats, but can depend on the
96 current links configuration or sub-device controls value. For instance, a
97 low-pass noise filter might crop pixels at the frame boundaries, modifying
98 its output frame size.</para>
99
100 <para>Drivers must not return an error solely because the requested format
101 doesn't match the device capabilities. They must instead modify the format
102 to match what the hardware can provide. The modified format should be as
103 close as possible to the original request.</para>
104
105 <table pgwide="1" frame="none" id="v4l2-subdev-format">
106 <title>struct <structname>v4l2_subdev_format</structname></title>
107 <tgroup cols="3">
108 &cs-str;
109 <tbody valign="top">
110 <row>
111 <entry>__u32</entry>
112 <entry><structfield>pad</structfield></entry>
113 <entry>Pad number as reported by the media controller API.</entry>
114 </row>
115 <row>
116 <entry>__u32</entry>
117 <entry><structfield>which</structfield></entry>
118 <entry>Format to modified, from &v4l2-subdev-format-whence;.</entry>
119 </row>
120 <row>
121 <entry>&v4l2-mbus-framefmt;</entry>
122 <entry><structfield>format</structfield></entry>
123 <entry>Definition of an image format, see <xref
124 linkend="v4l2-mbus-framefmt" /> for details.</entry>
125 </row>
126 <row>
127 <entry>__u32</entry>
128 <entry><structfield>reserved</structfield>[8]</entry>
129 <entry>Reserved for future extensions. Applications and drivers must
130 set the array to zero.</entry>
131 </row>
132 </tbody>
133 </tgroup>
134 </table>
135
136 <table pgwide="1" frame="none" id="v4l2-subdev-format-whence">
137 <title>enum <structname>v4l2_subdev_format_whence</structname></title>
138 <tgroup cols="3">
139 &cs-def;
140 <tbody valign="top">
141 <row>
142 <entry>V4L2_SUBDEV_FORMAT_TRY</entry>
143 <entry>0</entry>
144 <entry>Try formats, used for querying device capabilities.</entry>
145 </row>
146 <row>
147 <entry>V4L2_SUBDEV_FORMAT_ACTIVE</entry>
148 <entry>1</entry>
149 <entry>Active formats, applied to the hardware.</entry>
150 </row>
151 </tbody>
152 </tgroup>
153 </table>
154 </refsect1>
155
156 <refsect1>
157 &return-value;
158
159 <variablelist>
160 <varlistentry>
161 <term><errorcode>EBUSY</errorcode></term>
162 <listitem>
163 <para>The format can't be changed because the pad is currently busy.
164 This can be caused, for instance, by an active video stream on the
165 pad. The ioctl must not be retried without performing another action
166 to fix the problem first. Only returned by
167 <constant>VIDIOC_SUBDEV_S_FMT</constant></para>
168 </listitem>
169 </varlistentry>
170 <varlistentry>
171 <term><errorcode>EINVAL</errorcode></term>
172 <listitem>
173 <para>The &v4l2-subdev-format; <structfield>pad</structfield>
174 references a non-existing pad, or the <structfield>which</structfield>
175 field references a non-existing format.</para>
176 </listitem>
177 </varlistentry>
178 </variablelist>
179 </refsect1>
180</refentry>
diff --git a/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml b/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
new file mode 100644
index 000000000000..0bc3ea22d31f
--- /dev/null
+++ b/Documentation/DocBook/v4l/vidioc-subdev-g-frame-interval.xml
@@ -0,0 +1,141 @@
1<refentry id="vidioc-subdev-g-frame-interval">
2 <refmeta>
3 <refentrytitle>ioctl VIDIOC_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</refentrytitle>
4 &manvol;
5 </refmeta>
6
7 <refnamediv>
8 <refname>VIDIOC_SUBDEV_G_FRAME_INTERVAL</refname>
9 <refname>VIDIOC_SUBDEV_S_FRAME_INTERVAL</refname>
10 <refpurpose>Get or set the frame interval on a subdev pad</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_subdev_frame_interval *<parameter>argp</parameter>
20 </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_SUBDEV_G_FRAME_INTERVAL, VIDIOC_SUBDEV_S_FRAME_INTERVAL</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 <note>
54 <title>Experimental</title>
55 <para>This is an <link linkend="experimental">experimental</link>
56 interface and may change in the future.</para>
57 </note>
58
59 <para>These ioctls are used to get and set the frame interval at specific
60 subdev pads in the image pipeline. The frame interval only makes sense for
61 sub-devices that can control the frame period on their own. This includes,
62 for instance, image sensors and TV tuners. Sub-devices that don't support
63 frame intervals must not implement these ioctls.</para>
64
65 <para>To retrieve the current frame interval applications set the
66 <structfield>pad</structfield> field of a &v4l2-subdev-frame-interval; to
67 the desired pad number as reported by the media controller API. When they
68 call the <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> ioctl with a
69 pointer to this structure the driver fills the members of the
70 <structfield>interval</structfield> field.</para>
71
72 <para>To change the current frame interval applications set both the
73 <structfield>pad</structfield> field and all members of the
74 <structfield>interval</structfield> field. When they call the
75 <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant> ioctl with a pointer to
76 this structure the driver verifies the requested interval, adjusts it based
77 on the hardware capabilities and configures the device. Upon return the
78 &v4l2-subdev-frame-interval; contains the current frame interval as would be
79 returned by a <constant>VIDIOC_SUBDEV_G_FRAME_INTERVAL</constant> call.
80 </para>
81
82 <para>Drivers must not return an error solely because the requested interval
83 doesn't match the device capabilities. They must instead modify the interval
84 to match what the hardware can provide. The modified interval should be as
85 close as possible to the original request.</para>
86
87 <para>Sub-devices that support the frame interval ioctls should implement
88 them on a single pad only. Their behaviour when supported on multiple pads
89 of the same sub-device is not defined.</para>
90
91 <table pgwide="1" frame="none" id="v4l2-subdev-frame-interval">
92 <title>struct <structname>v4l2_subdev_frame_interval</structname></title>
93 <tgroup cols="3">
94 &cs-str;
95 <tbody valign="top">
96 <row>
97 <entry>__u32</entry>
98 <entry><structfield>pad</structfield></entry>
99 <entry>Pad number as reported by the media controller API.</entry>
100 </row>
101 <row>
102 <entry>&v4l2-fract;</entry>
103 <entry><structfield>interval</structfield></entry>
104 <entry>Period, in seconds, between consecutive video frames.</entry>
105 </row>
106 <row>
107 <entry>__u32</entry>
108 <entry><structfield>reserved</structfield>[9]</entry>
109 <entry>Reserved for future extensions. Applications and drivers must
110 set the array to zero.</entry>
111 </row>
112 </tbody>
113 </tgroup>
114 </table>
115 </refsect1>
116
117 <refsect1>
118 &return-value;
119
120 <variablelist>
121 <varlistentry>
122 <term><errorcode>EBUSY</errorcode></term>
123 <listitem>
124 <para>The frame interval can't be changed because the pad is currently
125 busy. This can be caused, for instance, by an active video stream on
126 the pad. The ioctl must not be retried without performing another
127 action to fix the problem first. Only returned by
128 <constant>VIDIOC_SUBDEV_S_FRAME_INTERVAL</constant></para>
129 </listitem>
130 </varlistentry>
131 <varlistentry>
132 <term><errorcode>EINVAL</errorcode></term>
133 <listitem>
134 <para>The &v4l2-subdev-frame-interval; <structfield>pad</structfield>
135 references a non-existing pad, or the pad doesn't support frame
136 intervals.</para>
137 </listitem>
138 </varlistentry>
139 </variablelist>
140 </refsect1>
141</refentry>
diff --git a/Documentation/dvb/get_dvb_firmware b/Documentation/dvb/get_dvb_firmware
index 59690de8ebfe..3348d313fbe0 100644
--- a/Documentation/dvb/get_dvb_firmware
+++ b/Documentation/dvb/get_dvb_firmware
@@ -556,6 +556,9 @@ sub ngene {
556 my $hash1 = "d798d5a757121174f0dbc5f2833c0c85"; 556 my $hash1 = "d798d5a757121174f0dbc5f2833c0c85";
557 my $file2 = "ngene_17.fw"; 557 my $file2 = "ngene_17.fw";
558 my $hash2 = "26b687136e127b8ac24b81e0eeafc20b"; 558 my $hash2 = "26b687136e127b8ac24b81e0eeafc20b";
559 my $url2 = "http://l4m-daten.de/downloads/firmware/dvb-s2/linux/all/";
560 my $file3 = "ngene_18.fw";
561 my $hash3 = "ebce3ea769a53e3e0b0197c3b3f127e3";
559 562
560 checkstandard(); 563 checkstandard();
561 564
@@ -565,7 +568,10 @@ sub ngene {
565 wgetfile($file2, $url . $file2); 568 wgetfile($file2, $url . $file2);
566 verify($file2, $hash2); 569 verify($file2, $hash2);
567 570
568 "$file1, $file2"; 571 wgetfile($file3, $url2 . $file3);
572 verify($file3, $hash3);
573
574 "$file1, $file2, $file3";
569} 575}
570 576
571sub az6027{ 577sub az6027{
diff --git a/Documentation/dvb/lmedm04.txt b/Documentation/dvb/lmedm04.txt
index 641886504201..10b5f0411386 100644
--- a/Documentation/dvb/lmedm04.txt
+++ b/Documentation/dvb/lmedm04.txt
@@ -4,7 +4,7 @@ following file(s) to this directory.
4for DM04+/QQBOX LME2510C (Sharp 7395 Tuner) 4for DM04+/QQBOX LME2510C (Sharp 7395 Tuner)
5------------------------------------------- 5-------------------------------------------
6 6
7The Sharp 7395 driver can be found in windows/system32/driver 7The Sharp 7395 driver can be found in windows/system32/drivers
8 8
9US2A0D.sys (dated 17 Mar 2009) 9US2A0D.sys (dated 17 Mar 2009)
10 10
@@ -44,7 +44,7 @@ and run
44 44
45 45
46Other LG firmware can be extracted manually from US280D.sys 46Other LG firmware can be extracted manually from US280D.sys
47only found in windows/system32/driver. 47only found in windows/system32/drivers
48 48
49dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw 49dd if=US280D.sys ibs=1 skip=42360 count=3924 of=dvb-usb-lme2510-lg.fw
50 50
@@ -55,4 +55,16 @@ dd if=US280D.sys ibs=1 skip=35200 count=3850 of=dvb-usb-lme2510c-lg.fw
55 55
56--------------------------------------------------------------------- 56---------------------------------------------------------------------
57 57
58The Sharp 0194 tuner driver can be found in windows/system32/drivers
59
60US290D.sys (dated 09 Apr 2009)
61
62For LME2510
63dd if=US290D.sys ibs=1 skip=36856 count=3976 of=dvb-usb-lme2510-s0194.fw
64
65
66For LME2510C
67dd if=US290D.sys ibs=1 skip=33152 count=3697 of=dvb-usb-lme2510c-s0194.fw
68
69
58Copy the firmware file(s) to /lib/firmware 70Copy the firmware file(s) to /lib/firmware
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index 75c37e4c3d75..274b32d12532 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -108,42 +108,6 @@ Who: Pavel Machek <pavel@ucw.cz>
108 108
109--------------------------- 109---------------------------
110 110
111What: Video4Linux obsolete drivers using V4L1 API
112When: kernel 2.6.39
113Files: drivers/staging/se401/* drivers/staging/usbvideo/*
114Check: drivers/staging/se401/se401.c drivers/staging/usbvideo/usbvideo.c
115Why: There are some drivers still using V4L1 API, despite all efforts we've done
116 to migrate. Those drivers are for obsolete hardware that the old maintainer
117 didn't care (or not have the hardware anymore), and that no other developer
118 could find any hardware to buy. They probably have no practical usage today,
119 and people with such old hardware could probably keep using an older version
120 of the kernel. Those drivers will be moved to staging on 2.6.38 and, if nobody
121 cares enough to port and test them with V4L2 API, they'll be removed on 2.6.39.
122Who: Mauro Carvalho Chehab <mchehab@infradead.org>
123
124---------------------------
125
126What: Video4Linux: Remove obsolete ioctl's
127When: kernel 2.6.39
128Files: include/media/videodev2.h
129Why: Some ioctl's were defined wrong on 2.6.2 and 2.6.6, using the wrong
130 type of R/W arguments. They were fixed, but the old ioctl names are
131 still there, maintained to avoid breaking binary compatibility:
132 #define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
133 #define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
134 #define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
135 #define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
136 #define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
137 #define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
138 There's no sense on preserving those forever, as it is very doubtful
139 that someone would try to use a such old binary with a modern kernel.
140 Removing them will allow us to remove some magic done at the V4L ioctl
141 handler.
142
143Who: Mauro Carvalho Chehab <mchehab@infradead.org>
144
145---------------------------
146
147What: sys_sysctl 111What: sys_sysctl
148When: September 2010 112When: September 2010
149Option: CONFIG_SYSCTL_SYSCALL 113Option: CONFIG_SYSCTL_SYSCALL
diff --git a/Documentation/ioctl/ioctl-number.txt b/Documentation/ioctl/ioctl-number.txt
index e68543f767d5..a0a5d82b6b0b 100644
--- a/Documentation/ioctl/ioctl-number.txt
+++ b/Documentation/ioctl/ioctl-number.txt
@@ -273,6 +273,7 @@ Code Seq#(hex) Include File Comments
273'z' 40-7F CAN bus card conflict! 273'z' 40-7F CAN bus card conflict!
274 <mailto:oe@port.de> 274 <mailto:oe@port.de>
275'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict! 275'z' 10-4F drivers/s390/crypto/zcrypt_api.h conflict!
276'|' 00-7F linux/media.h
2760x80 00-1F linux/fb.h 2770x80 00-1F linux/fb.h
2770x89 00-06 arch/x86/include/asm/sockios.h 2780x89 00-06 arch/x86/include/asm/sockios.h
2780x89 0B-DF linux/sockios.h 2790x89 0B-DF linux/sockios.h
diff --git a/Documentation/media-framework.txt b/Documentation/media-framework.txt
new file mode 100644
index 000000000000..fd48add02cb0
--- /dev/null
+++ b/Documentation/media-framework.txt
@@ -0,0 +1,353 @@
1Linux kernel media framework
2============================
3
4This document describes the Linux kernel media framework, its data structures,
5functions and their usage.
6
7
8Introduction
9------------
10
11The media controller API is documented in DocBook format in
12Documentation/DocBook/v4l/media-controller.xml. This document will focus on
13the kernel-side implementation of the media framework.
14
15
16Abstract media device model
17---------------------------
18
19Discovering a device internal topology, and configuring it at runtime, is one
20of the goals of the media framework. To achieve this, hardware devices are
21modeled as an oriented graph of building blocks called entities connected
22through pads.
23
24An entity is a basic media hardware building block. It can correspond to
25a large variety of logical blocks such as physical hardware devices
26(CMOS sensor for instance), logical hardware devices (a building block
27in a System-on-Chip image processing pipeline), DMA channels or physical
28connectors.
29
30A pad is a connection endpoint through which an entity can interact with
31other entities. Data (not restricted to video) produced by an entity
32flows from the entity's output to one or more entity inputs. Pads should
33not be confused with physical pins at chip boundaries.
34
35A link is a point-to-point oriented connection between two pads, either
36on the same entity or on different entities. Data flows from a source
37pad to a sink pad.
38
39
40Media device
41------------
42
43A media device is represented by a struct media_device instance, defined in
44include/media/media-device.h. Allocation of the structure is handled by the
45media device driver, usually by embedding the media_device instance in a
46larger driver-specific structure.
47
48Drivers register media device instances by calling
49
50 media_device_register(struct media_device *mdev);
51
52The caller is responsible for initializing the media_device structure before
53registration. The following fields must be set:
54
55 - dev must point to the parent device (usually a pci_dev, usb_interface or
56 platform_device instance).
57
58 - model must be filled with the device model name as a NUL-terminated UTF-8
59 string. The device/model revision must not be stored in this field.
60
61The following fields are optional:
62
63 - serial is a unique serial number stored as a NUL-terminated ASCII string.
64 The field is big enough to store a GUID in text form. If the hardware
65 doesn't provide a unique serial number this field must be left empty.
66
67 - bus_info represents the location of the device in the system as a
68 NUL-terminated ASCII string. For PCI/PCIe devices bus_info must be set to
69 "PCI:" (or "PCIe:") followed by the value of pci_name(). For USB devices,
70 the usb_make_path() function must be used. This field is used by
71 applications to distinguish between otherwise identical devices that don't
72 provide a serial number.
73
74 - hw_revision is the hardware device revision in a driver-specific format.
75 When possible the revision should be formatted with the KERNEL_VERSION
76 macro.
77
78 - driver_version is formatted with the KERNEL_VERSION macro. The version
79 minor must be incremented when new features are added to the userspace API
80 without breaking binary compatibility. The version major must be
81 incremented when binary compatibility is broken.
82
83Upon successful registration a character device named media[0-9]+ is created.
84The device major and minor numbers are dynamic. The model name is exported as
85a sysfs attribute.
86
87Drivers unregister media device instances by calling
88
89 media_device_unregister(struct media_device *mdev);
90
91Unregistering a media device that hasn't been registered is *NOT* safe.
92
93
94Entities, pads and links
95------------------------
96
97- Entities
98
99Entities are represented by a struct media_entity instance, defined in
100include/media/media-entity.h. The structure is usually embedded into a
101higher-level structure, such as a v4l2_subdev or video_device instance,
102although drivers can allocate entities directly.
103
104Drivers initialize entities by calling
105
106 media_entity_init(struct media_entity *entity, u16 num_pads,
107 struct media_pad *pads, u16 extra_links);
108
109The media_entity name, type, flags, revision and group_id fields can be
110initialized before or after calling media_entity_init. Entities embedded in
111higher-level standard structures can have some of those fields set by the
112higher-level framework.
113
114As the number of pads is known in advance, the pads array is not allocated
115dynamically but is managed by the entity driver. Most drivers will embed the
116pads array in a driver-specific structure, avoiding dynamic allocation.
117
118Drivers must set the direction of every pad in the pads array before calling
119media_entity_init. The function will initialize the other pads fields.
120
121Unlike the number of pads, the total number of links isn't always known in
122advance by the entity driver. As an initial estimate, media_entity_init
123pre-allocates a number of links equal to the number of pads plus an optional
124number of extra links. The links array will be reallocated if it grows beyond
125the initial estimate.
126
127Drivers register entities with a media device by calling
128
129 media_device_register_entity(struct media_device *mdev,
130 struct media_entity *entity);
131
132Entities are identified by a unique positive integer ID. Drivers can provide an
133ID by filling the media_entity id field prior to registration, or request the
134media controller framework to assign an ID automatically. Drivers that provide
135IDs manually must ensure that all IDs are unique. IDs are not guaranteed to be
136contiguous even when they are all assigned automatically by the framework.
137
138Drivers unregister entities by calling
139
140 media_device_unregister_entity(struct media_entity *entity);
141
142Unregistering an entity will not change the IDs of the other entities, and the
143ID will never be reused for a newly registered entity.
144
145When a media device is unregistered, all its entities are unregistered
146automatically. No manual entities unregistration is then required.
147
148Drivers free resources associated with an entity by calling
149
150 media_entity_cleanup(struct media_entity *entity);
151
152This function must be called during the cleanup phase after unregistering the
153entity. Note that the media_entity instance itself must be freed explicitly by
154the driver if required.
155
156Entities have flags that describe the entity capabilities and state.
157
158 MEDIA_ENT_FL_DEFAULT indicates the default entity for a given type.
159 This can be used to report the default audio and video devices or the
160 default camera sensor.
161
162Logical entity groups can be defined by setting the group ID of all member
163entities to the same non-zero value. An entity group serves no purpose in the
164kernel, but is reported to userspace during entities enumeration. The group_id
165field belongs to the media device driver and must not by touched by entity
166drivers.
167
168Media device drivers should define groups if several entities are logically
169bound together. Example usages include reporting
170
171 - ALSA, VBI and video nodes that carry the same media stream
172 - lens and flash controllers associated with a sensor
173
174- Pads
175
176Pads are represented by a struct media_pad instance, defined in
177include/media/media-entity.h. Each entity stores its pads in a pads array
178managed by the entity driver. Drivers usually embed the array in a
179driver-specific structure.
180
181Pads are identified by their entity and their 0-based index in the pads array.
182Both information are stored in the media_pad structure, making the media_pad
183pointer the canonical way to store and pass link references.
184
185Pads have flags that describe the pad capabilities and state.
186
187 MEDIA_PAD_FL_SINK indicates that the pad supports sinking data.
188 MEDIA_PAD_FL_SOURCE indicates that the pad supports sourcing data.
189
190One and only one of MEDIA_PAD_FL_SINK and MEDIA_PAD_FL_SOURCE must be set for
191each pad.
192
193- Links
194
195Links are represented by a struct media_link instance, defined in
196include/media/media-entity.h. Each entity stores all links originating at or
197targetting any of its pads in a links array. A given link is thus stored
198twice, once in the source entity and once in the target entity. The array is
199pre-allocated and grows dynamically as needed.
200
201Drivers create links by calling
202
203 media_entity_create_link(struct media_entity *source, u16 source_pad,
204 struct media_entity *sink, u16 sink_pad,
205 u32 flags);
206
207An entry in the link array of each entity is allocated and stores pointers
208to source and sink pads.
209
210Links have flags that describe the link capabilities and state.
211
212 MEDIA_LNK_FL_ENABLED indicates that the link is enabled and can be used
213 to transfer media data. When two or more links target a sink pad, only
214 one of them can be enabled at a time.
215 MEDIA_LNK_FL_IMMUTABLE indicates that the link enabled state can't be
216 modified at runtime. If MEDIA_LNK_FL_IMMUTABLE is set, then
217 MEDIA_LNK_FL_ENABLED must also be set since an immutable link is always
218 enabled.
219
220
221Graph traversal
222---------------
223
224The media framework provides APIs to iterate over entities in a graph.
225
226To iterate over all entities belonging to a media device, drivers can use the
227media_device_for_each_entity macro, defined in include/media/media-device.h.
228
229 struct media_entity *entity;
230
231 media_device_for_each_entity(entity, mdev) {
232 /* entity will point to each entity in turn */
233 ...
234 }
235
236Drivers might also need to iterate over all entities in a graph that can be
237reached only through enabled links starting at a given entity. The media
238framework provides a depth-first graph traversal API for that purpose.
239
240Note that graphs with cycles (whether directed or undirected) are *NOT*
241supported by the graph traversal API. To prevent infinite loops, the graph
242traversal code limits the maximum depth to MEDIA_ENTITY_ENUM_MAX_DEPTH,
243currently defined as 16.
244
245Drivers initiate a graph traversal by calling
246
247 media_entity_graph_walk_start(struct media_entity_graph *graph,
248 struct media_entity *entity);
249
250The graph structure, provided by the caller, is initialized to start graph
251traversal at the given entity.
252
253Drivers can then retrieve the next entity by calling
254
255 media_entity_graph_walk_next(struct media_entity_graph *graph);
256
257When the graph traversal is complete the function will return NULL.
258
259Graph traversal can be interrupted at any moment. No cleanup function call is
260required and the graph structure can be freed normally.
261
262Helper functions can be used to find a link between two given pads, or a pad
263connected to another pad through an enabled link
264
265 media_entity_find_link(struct media_pad *source,
266 struct media_pad *sink);
267
268 media_entity_remote_source(struct media_pad *pad);
269
270Refer to the kerneldoc documentation for more information.
271
272
273Use count and power handling
274----------------------------
275
276Due to the wide differences between drivers regarding power management needs,
277the media controller does not implement power management. However, the
278media_entity structure includes a use_count field that media drivers can use to
279track the number of users of every entity for power management needs.
280
281The use_count field is owned by media drivers and must not be touched by entity
282drivers. Access to the field must be protected by the media device graph_mutex
283lock.
284
285
286Links setup
287-----------
288
289Link properties can be modified at runtime by calling
290
291 media_entity_setup_link(struct media_link *link, u32 flags);
292
293The flags argument contains the requested new link flags.
294
295The only configurable property is the ENABLED link flag to enable/disable a
296link. Links marked with the IMMUTABLE link flag can not be enabled or disabled.
297
298When a link is enabled or disabled, the media framework calls the
299link_setup operation for the two entities at the source and sink of the link,
300in that order. If the second link_setup call fails, another link_setup call is
301made on the first entity to restore the original link flags.
302
303Media device drivers can be notified of link setup operations by setting the
304media_device::link_notify pointer to a callback function. If provided, the
305notification callback will be called before enabling and after disabling
306links.
307
308Entity drivers must implement the link_setup operation if any of their links
309is non-immutable. The operation must either configure the hardware or store
310the configuration information to be applied later.
311
312Link configuration must not have any side effect on other links. If an enabled
313link at a sink pad prevents another link at the same pad from being disabled,
314the link_setup operation must return -EBUSY and can't implicitly disable the
315first enabled link.
316
317
318Pipelines and media streams
319---------------------------
320
321When starting streaming, drivers must notify all entities in the pipeline to
322prevent link states from being modified during streaming by calling
323
324 media_entity_pipeline_start(struct media_entity *entity,
325 struct media_pipeline *pipe);
326
327The function will mark all entities connected to the given entity through
328enabled links, either directly or indirectly, as streaming.
329
330The media_pipeline instance pointed to by the pipe argument will be stored in
331every entity in the pipeline. Drivers should embed the media_pipeline structure
332in higher-level pipeline structures and can then access the pipeline through
333the media_entity pipe field.
334
335Calls to media_entity_pipeline_start() can be nested. The pipeline pointer must
336be identical for all nested calls to the function.
337
338When stopping the stream, drivers must notify the entities with
339
340 media_entity_pipeline_stop(struct media_entity *entity);
341
342If multiple calls to media_entity_pipeline_start() have been made the same
343number of media_entity_pipeline_stop() calls are required to stop streaming. The
344media_entity pipe field is reset to NULL on the last nested stop call.
345
346Link configuration will fail with -EBUSY by default if either end of the link is
347a streaming entity. Links that can be modified while streaming must be marked
348with the MEDIA_LNK_FL_DYNAMIC flag.
349
350If other operations need to be disallowed on streaming entities (such as
351changing entities configuration parameters) drivers can explictly check the
352media_entity stream_count field to find out if an entity is streaming. This
353operation must be done with the media_device graph_mutex held.
diff --git a/Documentation/video4linux/README.ivtv b/Documentation/video4linux/README.ivtv
index 42b06686eb78..2579b5b709ed 100644
--- a/Documentation/video4linux/README.ivtv
+++ b/Documentation/video4linux/README.ivtv
@@ -36,8 +36,7 @@ Additional features for the PVR-350 (CX23415 based):
36 * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the 36 * Provides comprehensive OSD (On Screen Display: ie. graphics overlaying the
37 video signal) 37 video signal)
38 * Provides a framebuffer (allowing X applications to appear on the video 38 * Provides a framebuffer (allowing X applications to appear on the video
39 device) (this framebuffer is not yet part of the kernel. In the meantime it 39 device)
40 is available from www.ivtvdriver.org).
41 * Supports raw YUV output. 40 * Supports raw YUV output.
42 41
43IMPORTANT: In case of problems first read this page: 42IMPORTANT: In case of problems first read this page:
diff --git a/Documentation/video4linux/gspca.txt b/Documentation/video4linux/gspca.txt
index 261776e0c5e1..5c542e60f51d 100644
--- a/Documentation/video4linux/gspca.txt
+++ b/Documentation/video4linux/gspca.txt
@@ -103,6 +103,7 @@ spca561 046d:092d Logitech QC Elch2
103spca561 046d:092e Logitech QC Elch2 103spca561 046d:092e Logitech QC Elch2
104spca561 046d:092f Logitech QuickCam Express Plus 104spca561 046d:092f Logitech QuickCam Express Plus
105sunplus 046d:0960 Logitech ClickSmart 420 105sunplus 046d:0960 Logitech ClickSmart 420
106nw80x 046d:d001 Logitech QuickCam Pro (dark focus ring)
106sunplus 0471:0322 Philips DMVC1300K 107sunplus 0471:0322 Philips DMVC1300K
107zc3xx 0471:0325 Philips SPC 200 NC 108zc3xx 0471:0325 Philips SPC 200 NC
108zc3xx 0471:0326 Philips SPC 300 NC 109zc3xx 0471:0326 Philips SPC 300 NC
@@ -150,10 +151,12 @@ sunplus 04fc:5330 Digitrex 2110
150sunplus 04fc:5360 Sunplus Generic 151sunplus 04fc:5360 Sunplus Generic
151spca500 04fc:7333 PalmPixDC85 152spca500 04fc:7333 PalmPixDC85
152sunplus 04fc:ffff Pure DigitalDakota 153sunplus 04fc:ffff Pure DigitalDakota
154nw80x 0502:d001 DVC V6
153spca501 0506:00df 3Com HomeConnect Lite 155spca501 0506:00df 3Com HomeConnect Lite
154sunplus 052b:1507 Megapixel 5 Pretec DC-1007 156sunplus 052b:1507 Megapixel 5 Pretec DC-1007
155sunplus 052b:1513 Megapix V4 157sunplus 052b:1513 Megapix V4
156sunplus 052b:1803 MegaImage VI 158sunplus 052b:1803 MegaImage VI
159nw80x 052b:d001 EZCam Pro p35u
157tv8532 0545:808b Veo Stingray 160tv8532 0545:808b Veo Stingray
158tv8532 0545:8333 Veo Stingray 161tv8532 0545:8333 Veo Stingray
159sunplus 0546:3155 Polaroid PDC3070 162sunplus 0546:3155 Polaroid PDC3070
@@ -177,6 +180,7 @@ sunplus 055f:c530 Mustek Gsmart LCD 3
177sunplus 055f:c540 Gsmart D30 180sunplus 055f:c540 Gsmart D30
178sunplus 055f:c630 Mustek MDC4000 181sunplus 055f:c630 Mustek MDC4000
179sunplus 055f:c650 Mustek MDC5500Z 182sunplus 055f:c650 Mustek MDC5500Z
183nw80x 055f:d001 Mustek Wcam 300 mini
180zc3xx 055f:d003 Mustek WCam300A 184zc3xx 055f:d003 Mustek WCam300A
181zc3xx 055f:d004 Mustek WCam300 AN 185zc3xx 055f:d004 Mustek WCam300 AN
182conex 0572:0041 Creative Notebook cx11646 186conex 0572:0041 Creative Notebook cx11646
@@ -195,14 +199,20 @@ gl860 05e3:0503 Genesys Logic PC Camera
195gl860 05e3:f191 Genesys Logic PC Camera 199gl860 05e3:f191 Genesys Logic PC Camera
196spca561 060b:a001 Maxell Compact Pc PM3 200spca561 060b:a001 Maxell Compact Pc PM3
197zc3xx 0698:2003 CTX M730V built in 201zc3xx 0698:2003 CTX M730V built in
202nw80x 06a5:0000 Typhoon Webcam 100 USB
203nw80x 06a5:d001 Divio based webcams
204nw80x 06a5:d800 Divio Chicony TwinkleCam, Trust SpaceCam
198spca500 06bd:0404 Agfa CL20 205spca500 06bd:0404 Agfa CL20
199spca500 06be:0800 Optimedia 206spca500 06be:0800 Optimedia
207nw80x 06be:d001 EZCam Pro p35u
200sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom 208sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
201spca506 06e1:a190 ADS Instant VCD 209spca506 06e1:a190 ADS Instant VCD
210ov534 06f8:3002 Hercules Blog Webcam
202ov534_9 06f8:3003 Hercules Dualpix HD Weblog 211ov534_9 06f8:3003 Hercules Dualpix HD Weblog
203sonixj 06f8:3004 Hercules Classic Silver 212sonixj 06f8:3004 Hercules Classic Silver
204sonixj 06f8:3008 Hercules Deluxe Optical Glass 213sonixj 06f8:3008 Hercules Deluxe Optical Glass
205pac7302 06f8:3009 Hercules Classic Link 214pac7302 06f8:3009 Hercules Classic Link
215nw80x 0728:d001 AVerMedia Camguard
206spca508 0733:0110 ViewQuest VQ110 216spca508 0733:0110 ViewQuest VQ110
207spca501 0733:0401 Intel Create and Share 217spca501 0733:0401 Intel Create and Share
208spca501 0733:0402 ViewQuest M318B 218spca501 0733:0402 ViewQuest M318B
diff --git a/Documentation/video4linux/omap3isp.txt b/Documentation/video4linux/omap3isp.txt
new file mode 100644
index 000000000000..69be2c782b98
--- /dev/null
+++ b/Documentation/video4linux/omap3isp.txt
@@ -0,0 +1,278 @@
1OMAP 3 Image Signal Processor (ISP) driver
2
3Copyright (C) 2010 Nokia Corporation
4Copyright (C) 2009 Texas Instruments, Inc.
5
6Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 Sakari Ailus <sakari.ailus@iki.fi>
8 David Cohen <dacohen@gmail.com>
9
10
11Introduction
12============
13
14This file documents the Texas Instruments OMAP 3 Image Signal Processor (ISP)
15driver located under drivers/media/video/omap3isp. The original driver was
16written by Texas Instruments but since that it has been rewritten (twice) at
17Nokia.
18
19The driver has been successfully used on the following versions of OMAP 3:
20
21 3430
22 3530
23 3630
24
25The driver implements V4L2, Media controller and v4l2_subdev interfaces.
26Sensor, lens and flash drivers using the v4l2_subdev interface in the kernel
27are supported.
28
29
30Split to subdevs
31================
32
33The OMAP 3 ISP is split into V4L2 subdevs, each of the blocks inside the ISP
34having one subdev to represent it. Each of the subdevs provide a V4L2 subdev
35interface to userspace.
36
37 OMAP3 ISP CCP2
38 OMAP3 ISP CSI2a
39 OMAP3 ISP CCDC
40 OMAP3 ISP preview
41 OMAP3 ISP resizer
42 OMAP3 ISP AEWB
43 OMAP3 ISP AF
44 OMAP3 ISP histogram
45
46Each possible link in the ISP is modelled by a link in the Media controller
47interface. For an example program see [2].
48
49
50Controlling the OMAP 3 ISP
51==========================
52
53In general, the settings given to the OMAP 3 ISP take effect at the beginning
54of the following frame. This is done when the module becomes idle during the
55vertical blanking period on the sensor. In memory-to-memory operation the pipe
56is run one frame at a time. Applying the settings is done between the frames.
57
58All the blocks in the ISP, excluding the CSI-2 and possibly the CCP2 receiver,
59insist on receiving complete frames. Sensors must thus never send the ISP
60partial frames.
61
62Autoidle does have issues with some ISP blocks on the 3430, at least.
63Autoidle is only enabled on 3630 when the omap3isp module parameter autoidle
64is non-zero.
65
66
67Events
68======
69
70The OMAP 3 ISP driver does support the V4L2 event interface on CCDC and
71statistics (AEWB, AF and histogram) subdevs.
72
73The CCDC subdev produces V4L2_EVENT_OMAP3ISP_HS_VS type event on HS_VS
74interrupt which is used to signal frame start. The event is triggered exactly
75when the reception of the first line of the frame starts in the CCDC module.
76The event can be subscribed on the CCDC subdev.
77
78(When using parallel interface one must pay account to correct configuration
79of the VS signal polarity. This is automatically correct when using the serial
80receivers.)
81
82Each of the statistics subdevs is able to produce events. An event is
83generated whenever a statistics buffer can be dequeued by a user space
84application using the VIDIOC_OMAP3ISP_STAT_REQ IOCTL. The events available
85are:
86
87 V4L2_EVENT_OMAP3ISP_AEWB
88 V4L2_EVENT_OMAP3ISP_AF
89 V4L2_EVENT_OMAP3ISP_HIST
90
91The type of the event data is struct omap3isp_stat_event_status for these
92ioctls. If there is an error calculating the statistics, there will be an
93event as usual, but no related statistics buffer. In this case
94omap3isp_stat_event_status.buf_err is set to non-zero.
95
96
97Private IOCTLs
98==============
99
100The OMAP 3 ISP driver supports standard V4L2 IOCTLs and controls where
101possible and practical. Much of the functions provided by the ISP, however,
102does not fall under the standard IOCTLs --- gamma tables and configuration of
103statistics collection are examples of such.
104
105In general, there is a private ioctl for configuring each of the blocks
106containing hardware-dependent functions.
107
108The following private IOCTLs are supported:
109
110 VIDIOC_OMAP3ISP_CCDC_CFG
111 VIDIOC_OMAP3ISP_PRV_CFG
112 VIDIOC_OMAP3ISP_AEWB_CFG
113 VIDIOC_OMAP3ISP_HIST_CFG
114 VIDIOC_OMAP3ISP_AF_CFG
115 VIDIOC_OMAP3ISP_STAT_REQ
116 VIDIOC_OMAP3ISP_STAT_EN
117
118The parameter structures used by these ioctls are described in
119include/linux/omap3isp.h. The detailed functions of the ISP itself related to
120a given ISP block is described in the Technical Reference Manuals (TRMs) ---
121see the end of the document for those.
122
123While it is possible to use the ISP driver without any use of these private
124IOCTLs it is not possible to obtain optimal image quality this way. The AEWB,
125AF and histogram modules cannot be used without configuring them using the
126appropriate private IOCTLs.
127
128
129CCDC and preview block IOCTLs
130=============================
131
132The VIDIOC_OMAP3ISP_CCDC_CFG and VIDIOC_OMAP3ISP_PRV_CFG IOCTLs are used to
133configure, enable and disable functions in the CCDC and preview blocks,
134respectively. Both IOCTLs control several functions in the blocks they
135control. VIDIOC_OMAP3ISP_CCDC_CFG IOCTL accepts a pointer to struct
136omap3isp_ccdc_update_config as its argument. Similarly VIDIOC_OMAP3ISP_PRV_CFG
137accepts a pointer to struct omap3isp_prev_update_config. The definition of
138both structures is available in [1].
139
140The update field in the structures tells whether to update the configuration
141for the specific function and the flag tells whether to enable or disable the
142function.
143
144The update and flag bit masks accept the following values. Each separate
145functions in the CCDC and preview blocks is associated with a flag (either
146disable or enable; part of the flag field in the structure) and a pointer to
147configuration data for the function.
148
149Valid values for the update and flag fields are listed here for
150VIDIOC_OMAP3ISP_CCDC_CFG. Values may be or'ed to configure more than one
151function in the same IOCTL call.
152
153 OMAP3ISP_CCDC_ALAW
154 OMAP3ISP_CCDC_LPF
155 OMAP3ISP_CCDC_BLCLAMP
156 OMAP3ISP_CCDC_BCOMP
157 OMAP3ISP_CCDC_FPC
158 OMAP3ISP_CCDC_CULL
159 OMAP3ISP_CCDC_CONFIG_LSC
160 OMAP3ISP_CCDC_TBL_LSC
161
162The corresponding values for the VIDIOC_OMAP3ISP_PRV_CFG are here:
163
164 OMAP3ISP_PREV_LUMAENH
165 OMAP3ISP_PREV_INVALAW
166 OMAP3ISP_PREV_HRZ_MED
167 OMAP3ISP_PREV_CFA
168 OMAP3ISP_PREV_CHROMA_SUPP
169 OMAP3ISP_PREV_WB
170 OMAP3ISP_PREV_BLKADJ
171 OMAP3ISP_PREV_RGB2RGB
172 OMAP3ISP_PREV_COLOR_CONV
173 OMAP3ISP_PREV_YC_LIMIT
174 OMAP3ISP_PREV_DEFECT_COR
175 OMAP3ISP_PREV_GAMMABYPASS
176 OMAP3ISP_PREV_DRK_FRM_CAPTURE
177 OMAP3ISP_PREV_DRK_FRM_SUBTRACT
178 OMAP3ISP_PREV_LENS_SHADING
179 OMAP3ISP_PREV_NF
180 OMAP3ISP_PREV_GAMMA
181
182The associated configuration pointer for the function may not be NULL when
183enabling the function. When disabling a function the configuration pointer is
184ignored.
185
186
187Statistic blocks IOCTLs
188=======================
189
190The statistics subdevs do offer more dynamic configuration options than the
191other subdevs. They can be enabled, disable and reconfigured when the pipeline
192is in streaming state.
193
194The statistics blocks always get the input image data from the CCDC (as the
195histogram memory read isn't implemented). The statistics are dequeueable by
196the user from the statistics subdev nodes using private IOCTLs.
197
198The private IOCTLs offered by the AEWB, AF and histogram subdevs are heavily
199reflected by the register level interface offered by the ISP hardware. There
200are aspects that are purely related to the driver implementation and these are
201discussed next.
202
203VIDIOC_OMAP3ISP_STAT_EN
204-----------------------
205
206This private IOCTL enables/disables a statistic module. If this request is
207done before streaming, it will take effect as soon as the pipeline starts to
208stream. If the pipeline is already streaming, it will take effect as soon as
209the CCDC becomes idle.
210
211VIDIOC_OMAP3ISP_AEWB_CFG, VIDIOC_OMAP3ISP_HIST_CFG and VIDIOC_OMAP3ISP_AF_CFG
212-----------------------------------------------------------------------------
213
214Those IOCTLs are used to configure the modules. They require user applications
215to have an in-depth knowledge of the hardware. Most of the fields explanation
216can be found on OMAP's TRMs. The two following fields common to all the above
217configure private IOCTLs require explanation for better understanding as they
218are not part of the TRM.
219
220omap3isp_[h3a_af/h3a_aewb/hist]_config.buf_size:
221
222The modules handle their buffers internally. The necessary buffer size for the
223module's data output depends on the requested configuration. Although the
224driver supports reconfiguration while streaming, it does not support a
225reconfiguration which requires bigger buffer size than what is already
226internally allocated if the module is enabled. It will return -EBUSY on this
227case. In order to avoid such condition, either disable/reconfigure/enable the
228module or request the necessary buffer size during the first configuration
229while the module is disabled.
230
231The internal buffer size allocation considers the requested configuration's
232minimum buffer size and the value set on buf_size field. If buf_size field is
233out of [minimum, maximum] buffer size range, it's clamped to fit in there.
234The driver then selects the biggest value. The corrected buf_size value is
235written back to user application.
236
237omap3isp_[h3a_af/h3a_aewb/hist]_config.config_counter:
238
239As the configuration doesn't take effect synchronously to the request, the
240driver must provide a way to track this information to provide more accurate
241data. After a configuration is requested, the config_counter returned to user
242space application will be an unique value associated to that request. When
243user application receives an event for buffer availability or when a new
244buffer is requested, this config_counter is used to match a buffer data and a
245configuration.
246
247VIDIOC_OMAP3ISP_STAT_REQ
248------------------------
249
250Send to user space the oldest data available in the internal buffer queue and
251discards such buffer afterwards. The field omap3isp_stat_data.frame_number
252matches with the video buffer's field_count.
253
254
255Technical reference manuals (TRMs) and other documentation
256==========================================================
257
258OMAP 3430 TRM:
259<URL:http://focus.ti.com/pdfs/wtbu/OMAP34xx_ES3.1.x_PUBLIC_TRM_vZM.zip>
260Referenced 2011-03-05.
261
262OMAP 35xx TRM:
263<URL:http://www.ti.com/litv/pdf/spruf98o> Referenced 2011-03-05.
264
265OMAP 3630 TRM:
266<URL:http://focus.ti.com/pdfs/wtbu/OMAP36xx_ES1.x_PUBLIC_TRM_vQ.zip>
267Referenced 2011-03-05.
268
269DM 3730 TRM:
270<URL:http://www.ti.com/litv/pdf/sprugn4h> Referenced 2011-03-06.
271
272
273References
274==========
275
276[1] include/linux/omap3isp.h
277
278[2] http://git.ideasonboard.org/?p=media-ctl.git;a=summary
diff --git a/Documentation/video4linux/v4l2-framework.txt b/Documentation/video4linux/v4l2-framework.txt
index f22f35c271f3..3b15608ee070 100644
--- a/Documentation/video4linux/v4l2-framework.txt
+++ b/Documentation/video4linux/v4l2-framework.txt
@@ -71,6 +71,10 @@ sub-device instances, the video_device struct stores V4L2 device node data
71and in the future a v4l2_fh struct will keep track of filehandle instances 71and in the future a v4l2_fh struct will keep track of filehandle instances
72(this is not yet implemented). 72(this is not yet implemented).
73 73
74The V4L2 framework also optionally integrates with the media framework. If a
75driver sets the struct v4l2_device mdev field, sub-devices and video nodes
76will automatically appear in the media framework as entities.
77
74 78
75struct v4l2_device 79struct v4l2_device
76------------------ 80------------------
@@ -83,11 +87,20 @@ You must register the device instance:
83 87
84 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev); 88 v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev);
85 89
86Registration will initialize the v4l2_device struct and link dev->driver_data 90Registration will initialize the v4l2_device struct. If the dev->driver_data
87to v4l2_dev. If v4l2_dev->name is empty then it will be set to a value derived 91field is NULL, it will be linked to v4l2_dev.
88from dev (driver name followed by the bus_id, to be precise). If you set it 92
89up before calling v4l2_device_register then it will be untouched. If dev is 93Drivers that want integration with the media device framework need to set
90NULL, then you *must* setup v4l2_dev->name before calling v4l2_device_register. 94dev->driver_data manually to point to the driver-specific device structure
95that embed the struct v4l2_device instance. This is achieved by a
96dev_set_drvdata() call before registering the V4L2 device instance. They must
97also set the struct v4l2_device mdev field to point to a properly initialized
98and registered media_device instance.
99
100If v4l2_dev->name is empty then it will be set to a value derived from dev
101(driver name followed by the bus_id, to be precise). If you set it up before
102calling v4l2_device_register then it will be untouched. If dev is NULL, then
103you *must* setup v4l2_dev->name before calling v4l2_device_register.
91 104
92You can use v4l2_device_set_name() to set the name based on a driver name and 105You can use v4l2_device_set_name() to set the name based on a driver name and
93a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1, 106a driver-global atomic_t instance. This will generate names like ivtv0, ivtv1,
@@ -108,6 +121,7 @@ You unregister with:
108 121
109 v4l2_device_unregister(struct v4l2_device *v4l2_dev); 122 v4l2_device_unregister(struct v4l2_device *v4l2_dev);
110 123
124If the dev->driver_data field points to v4l2_dev, it will be reset to NULL.
111Unregistering will also automatically unregister all subdevs from the device. 125Unregistering will also automatically unregister all subdevs from the device.
112 126
113If you have a hotpluggable device (e.g. a USB device), then when a disconnect 127If you have a hotpluggable device (e.g. a USB device), then when a disconnect
@@ -167,6 +181,21 @@ static int __devinit drv_probe(struct pci_dev *pdev,
167 state->instance = atomic_inc_return(&drv_instance) - 1; 181 state->instance = atomic_inc_return(&drv_instance) - 1;
168} 182}
169 183
184If you have multiple device nodes then it can be difficult to know when it is
185safe to unregister v4l2_device. For this purpose v4l2_device has refcounting
186support. The refcount is increased whenever video_register_device is called and
187it is decreased whenever that device node is released. When the refcount reaches
188zero, then the v4l2_device release() callback is called. You can do your final
189cleanup there.
190
191If other device nodes (e.g. ALSA) are created, then you can increase and
192decrease the refcount manually as well by calling:
193
194void v4l2_device_get(struct v4l2_device *v4l2_dev);
195
196or:
197
198int v4l2_device_put(struct v4l2_device *v4l2_dev);
170 199
171struct v4l2_subdev 200struct v4l2_subdev
172------------------ 201------------------
@@ -254,6 +283,26 @@ A sub-device driver initializes the v4l2_subdev struct using:
254Afterwards you need to initialize subdev->name with a unique name and set the 283Afterwards you need to initialize subdev->name with a unique name and set the
255module owner. This is done for you if you use the i2c helper functions. 284module owner. This is done for you if you use the i2c helper functions.
256 285
286If integration with the media framework is needed, you must initialize the
287media_entity struct embedded in the v4l2_subdev struct (entity field) by
288calling media_entity_init():
289
290 struct media_pad *pads = &my_sd->pads;
291 int err;
292
293 err = media_entity_init(&sd->entity, npads, pads, 0);
294
295The pads array must have been previously initialized. There is no need to
296manually set the struct media_entity type and name fields, but the revision
297field must be initialized if needed.
298
299A reference to the entity will be automatically acquired/released when the
300subdev device node (if any) is opened/closed.
301
302Don't forget to cleanup the media entity before the sub-device is destroyed:
303
304 media_entity_cleanup(&sd->entity);
305
257A device (bridge) driver needs to register the v4l2_subdev with the 306A device (bridge) driver needs to register the v4l2_subdev with the
258v4l2_device: 307v4l2_device:
259 308
@@ -263,6 +312,9 @@ This can fail if the subdev module disappeared before it could be registered.
263After this function was called successfully the subdev->dev field points to 312After this function was called successfully the subdev->dev field points to
264the v4l2_device. 313the v4l2_device.
265 314
315If the v4l2_device parent device has a non-NULL mdev field, the sub-device
316entity will be automatically registered with the media device.
317
266You can unregister a sub-device using: 318You can unregister a sub-device using:
267 319
268 v4l2_device_unregister_subdev(sd); 320 v4l2_device_unregister_subdev(sd);
@@ -319,6 +371,61 @@ controlled through GPIO pins. This distinction is only relevant when setting
319up the device, but once the subdev is registered it is completely transparent. 371up the device, but once the subdev is registered it is completely transparent.
320 372
321 373
374V4L2 sub-device userspace API
375-----------------------------
376
377Beside exposing a kernel API through the v4l2_subdev_ops structure, V4L2
378sub-devices can also be controlled directly by userspace applications.
379
380Device nodes named v4l-subdevX can be created in /dev to access sub-devices
381directly. If a sub-device supports direct userspace configuration it must set
382the V4L2_SUBDEV_FL_HAS_DEVNODE flag before being registered.
383
384After registering sub-devices, the v4l2_device driver can create device nodes
385for all registered sub-devices marked with V4L2_SUBDEV_FL_HAS_DEVNODE by calling
386v4l2_device_register_subdev_nodes(). Those device nodes will be automatically
387removed when sub-devices are unregistered.
388
389The device node handles a subset of the V4L2 API.
390
391VIDIOC_QUERYCTRL
392VIDIOC_QUERYMENU
393VIDIOC_G_CTRL
394VIDIOC_S_CTRL
395VIDIOC_G_EXT_CTRLS
396VIDIOC_S_EXT_CTRLS
397VIDIOC_TRY_EXT_CTRLS
398
399 The controls ioctls are identical to the ones defined in V4L2. They
400 behave identically, with the only exception that they deal only with
401 controls implemented in the sub-device. Depending on the driver, those
402 controls can be also be accessed through one (or several) V4L2 device
403 nodes.
404
405VIDIOC_DQEVENT
406VIDIOC_SUBSCRIBE_EVENT
407VIDIOC_UNSUBSCRIBE_EVENT
408
409 The events ioctls are identical to the ones defined in V4L2. They
410 behave identically, with the only exception that they deal only with
411 events generated by the sub-device. Depending on the driver, those
412 events can also be reported by one (or several) V4L2 device nodes.
413
414 Sub-device drivers that want to use events need to set the
415 V4L2_SUBDEV_USES_EVENTS v4l2_subdev::flags and initialize
416 v4l2_subdev::nevents to events queue depth before registering the
417 sub-device. After registration events can be queued as usual on the
418 v4l2_subdev::devnode device node.
419
420 To properly support events, the poll() file operation is also
421 implemented.
422
423Private ioctls
424
425 All ioctls not in the above list are passed directly to the sub-device
426 driver through the core::ioctl operation.
427
428
322I2C sub-device drivers 429I2C sub-device drivers
323---------------------- 430----------------------
324 431
@@ -457,6 +564,10 @@ You should also set these fields:
457 Otherwise you give it a pointer to a struct mutex_lock and before any 564 Otherwise you give it a pointer to a struct mutex_lock and before any
458 of the v4l2_file_operations is called this lock will be taken by the 565 of the v4l2_file_operations is called this lock will be taken by the
459 core and released afterwards. 566 core and released afterwards.
567- prio: keeps track of the priorities. Used to implement VIDIOC_G/S_PRIORITY.
568 If left to NULL, then it will use the struct v4l2_prio_state in v4l2_device.
569 If you want to have a separate priority state per (group of) device node(s),
570 then you can point it to your own struct v4l2_prio_state.
460- parent: you only set this if v4l2_device was registered with NULL as 571- parent: you only set this if v4l2_device was registered with NULL as
461 the parent device struct. This only happens in cases where one hardware 572 the parent device struct. This only happens in cases where one hardware
462 device has multiple PCI devices that all share the same v4l2_device core. 573 device has multiple PCI devices that all share the same v4l2_device core.
@@ -466,13 +577,34 @@ You should also set these fields:
466 (cx8802). Since the v4l2_device cannot be associated with a particular 577 (cx8802). Since the v4l2_device cannot be associated with a particular
467 PCI device it is setup without a parent device. But when the struct 578 PCI device it is setup without a parent device. But when the struct
468 video_device is setup you do know which parent PCI device to use. 579 video_device is setup you do know which parent PCI device to use.
580- flags: optional. Set to V4L2_FL_USE_FH_PRIO if you want to let the framework
581 handle the VIDIOC_G/S_PRIORITY ioctls. This requires that you use struct
582 v4l2_fh. Eventually this flag will disappear once all drivers use the core
583 priority handling. But for now it has to be set explicitly.
469 584
470If you use v4l2_ioctl_ops, then you should set either .unlocked_ioctl or 585If you use v4l2_ioctl_ops, then you should set .unlocked_ioctl to video_ioctl2
471.ioctl to video_ioctl2 in your v4l2_file_operations struct. 586in your v4l2_file_operations struct.
587
588Do not use .ioctl! This is deprecated and will go away in the future.
472 589
473The v4l2_file_operations struct is a subset of file_operations. The main 590The v4l2_file_operations struct is a subset of file_operations. The main
474difference is that the inode argument is omitted since it is never used. 591difference is that the inode argument is omitted since it is never used.
475 592
593If integration with the media framework is needed, you must initialize the
594media_entity struct embedded in the video_device struct (entity field) by
595calling media_entity_init():
596
597 struct media_pad *pad = &my_vdev->pad;
598 int err;
599
600 err = media_entity_init(&vdev->entity, 1, pad, 0);
601
602The pads array must have been previously initialized. There is no need to
603manually set the struct media_entity type and name fields.
604
605A reference to the entity will be automatically acquired/released when the
606video device is opened/closed.
607
476v4l2_file_operations and locking 608v4l2_file_operations and locking
477-------------------------------- 609--------------------------------
478 610
@@ -502,6 +634,9 @@ for you.
502 return err; 634 return err;
503 } 635 }
504 636
637If the v4l2_device parent device has a non-NULL mdev field, the video device
638entity will be automatically registered with the media device.
639
505Which device is registered depends on the type argument. The following 640Which device is registered depends on the type argument. The following
506types exist: 641types exist:
507 642
@@ -577,6 +712,13 @@ release, of course) will return an error as well.
577When the last user of the video device node exits, then the vdev->release() 712When the last user of the video device node exits, then the vdev->release()
578callback is called and you can do the final cleanup there. 713callback is called and you can do the final cleanup there.
579 714
715Don't forget to cleanup the media entity associated with the video device if
716it has been initialized:
717
718 media_entity_cleanup(&vdev->entity);
719
720This can be done from the release callback.
721
580 722
581video_device helper functions 723video_device helper functions
582----------------------------- 724-----------------------------
@@ -636,39 +778,25 @@ struct v4l2_fh
636-------------- 778--------------
637 779
638struct v4l2_fh provides a way to easily keep file handle specific data 780struct v4l2_fh provides a way to easily keep file handle specific data
639that is used by the V4L2 framework. Using v4l2_fh is optional for 781that is used by the V4L2 framework. New drivers must use struct v4l2_fh
640drivers. 782since it is also used to implement priority handling (VIDIOC_G/S_PRIORITY)
783if the video_device flag V4L2_FL_USE_FH_PRIO is also set.
641 784
642The users of v4l2_fh (in the V4L2 framework, not the driver) know 785The users of v4l2_fh (in the V4L2 framework, not the driver) know
643whether a driver uses v4l2_fh as its file->private_data pointer by 786whether a driver uses v4l2_fh as its file->private_data pointer by
644testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. 787testing the V4L2_FL_USES_V4L2_FH bit in video_device->flags. This bit is
645 788set whenever v4l2_fh_init() is called.
646Useful functions:
647
648- v4l2_fh_init()
649
650 Initialise the file handle. This *MUST* be performed in the driver's
651 v4l2_file_operations->open() handler.
652
653- v4l2_fh_add()
654 789
655 Add a v4l2_fh to video_device file handle list. May be called after 790struct v4l2_fh is allocated as a part of the driver's own file handle
656 initialising the file handle. 791structure and file->private_data is set to it in the driver's open
657 792function by the driver.
658- v4l2_fh_del()
659
660 Unassociate the file handle from video_device(). The file handle
661 exit function may now be called.
662 793
663- v4l2_fh_exit() 794In many cases the struct v4l2_fh will be embedded in a larger structure.
795In that case you should call v4l2_fh_init+v4l2_fh_add in open() and
796v4l2_fh_del+v4l2_fh_exit in release().
664 797
665 Uninitialise the file handle. After uninitialisation the v4l2_fh 798Drivers can extract their own file handle structure by using the container_of
666 memory can be freed. 799macro. Example:
667
668struct v4l2_fh is allocated as a part of the driver's own file handle
669structure and is set to file->private_data in the driver's open
670function by the driver. Drivers can extract their own file handle
671structure by using the container_of macro. Example:
672 800
673struct my_fh { 801struct my_fh {
674 int blah; 802 int blah;
@@ -685,15 +813,21 @@ int my_open(struct file *file)
685 813
686 ... 814 ...
687 815
816 my_fh = kzalloc(sizeof(*my_fh), GFP_KERNEL);
817
818 ...
819
688 ret = v4l2_fh_init(&my_fh->fh, vfd); 820 ret = v4l2_fh_init(&my_fh->fh, vfd);
689 if (ret) 821 if (ret) {
822 kfree(my_fh);
690 return ret; 823 return ret;
824 }
691 825
692 v4l2_fh_add(&my_fh->fh); 826 ...
693 827
694 file->private_data = &my_fh->fh; 828 file->private_data = &my_fh->fh;
695 829 v4l2_fh_add(&my_fh->fh);
696 ... 830 return 0;
697} 831}
698 832
699int my_release(struct file *file) 833int my_release(struct file *file)
@@ -702,8 +836,65 @@ int my_release(struct file *file)
702 struct my_fh *my_fh = container_of(fh, struct my_fh, fh); 836 struct my_fh *my_fh = container_of(fh, struct my_fh, fh);
703 837
704 ... 838 ...
839 v4l2_fh_del(&my_fh->fh);
840 v4l2_fh_exit(&my_fh->fh);
841 kfree(my_fh);
842 return 0;
705} 843}
706 844
845Below is a short description of the v4l2_fh functions used:
846
847int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
848
849 Initialise the file handle. This *MUST* be performed in the driver's
850 v4l2_file_operations->open() handler.
851
852void v4l2_fh_add(struct v4l2_fh *fh)
853
854 Add a v4l2_fh to video_device file handle list. Must be called once the
855 file handle is completely initialized.
856
857void v4l2_fh_del(struct v4l2_fh *fh)
858
859 Unassociate the file handle from video_device(). The file handle
860 exit function may now be called.
861
862void v4l2_fh_exit(struct v4l2_fh *fh)
863
864 Uninitialise the file handle. After uninitialisation the v4l2_fh
865 memory can be freed.
866
867
868If struct v4l2_fh is not embedded, then you can use these helper functions:
869
870int v4l2_fh_open(struct file *filp)
871
872 This allocates a struct v4l2_fh, initializes it and adds it to the struct
873 video_device associated with the file struct.
874
875int v4l2_fh_release(struct file *filp)
876
877 This deletes it from the struct video_device associated with the file
878 struct, uninitialised the v4l2_fh and frees it.
879
880These two functions can be plugged into the v4l2_file_operation's open() and
881release() ops.
882
883
884Several drivers need to do something when the first file handle is opened and
885when the last file handle closes. Two helper functions were added to check
886whether the v4l2_fh struct is the only open filehandle of the associated
887device node:
888
889int v4l2_fh_is_singular(struct v4l2_fh *fh)
890
891 Returns 1 if the file handle is the only open file handle, else 0.
892
893int v4l2_fh_is_singular_file(struct file *filp)
894
895 Same, but it calls v4l2_fh_is_singular with filp->private_data.
896
897
707V4L2 events 898V4L2 events
708----------- 899-----------
709 900
diff --git a/MAINTAINERS b/MAINTAINERS
index 2f122abecd4f..749f9cd38089 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4582,6 +4582,12 @@ L: linux-omap@vger.kernel.org
4582S: Maintained 4582S: Maintained
4583F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c 4583F: arch/arm/mach-omap2/omap_hwmod_44xx_data.c
4584 4584
4585OMAP IMAGE SIGNAL PROCESSOR (ISP)
4586M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
4587L: linux-media@vger.kernel.org
4588S: Maintained
4589F: drivers/media/video/omap3isp/*
4590
4585OMAP USB SUPPORT 4591OMAP USB SUPPORT
4586M: Felipe Balbi <balbi@ti.com> 4592M: Felipe Balbi <balbi@ti.com>
4587M: David Brownell <dbrownell@users.sourceforge.net> 4593M: David Brownell <dbrownell@users.sourceforge.net>
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index 0d2d6a9c303c..e97851492847 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -35,6 +35,7 @@
35 35
36#include "mux.h" 36#include "mux.h"
37#include "control.h" 37#include "control.h"
38#include "devices.h"
38 39
39#define L3_MODULES_MAX_LEN 12 40#define L3_MODULES_MAX_LEN 12
40#define L3_MODULES 3 41#define L3_MODULES 3
@@ -102,7 +103,7 @@ postcore_initcall(omap4_l3_init);
102 103
103#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE) 104#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
104 105
105static struct resource cam_resources[] = { 106static struct resource omap2cam_resources[] = {
106 { 107 {
107 .start = OMAP24XX_CAMERA_BASE, 108 .start = OMAP24XX_CAMERA_BASE,
108 .end = OMAP24XX_CAMERA_BASE + 0xfff, 109 .end = OMAP24XX_CAMERA_BASE + 0xfff,
@@ -114,19 +115,13 @@ static struct resource cam_resources[] = {
114 } 115 }
115}; 116};
116 117
117static struct platform_device omap_cam_device = { 118static struct platform_device omap2cam_device = {
118 .name = "omap24xxcam", 119 .name = "omap24xxcam",
119 .id = -1, 120 .id = -1,
120 .num_resources = ARRAY_SIZE(cam_resources), 121 .num_resources = ARRAY_SIZE(omap2cam_resources),
121 .resource = cam_resources, 122 .resource = omap2cam_resources,
122}; 123};
123 124#endif
124static inline void omap_init_camera(void)
125{
126 platform_device_register(&omap_cam_device);
127}
128
129#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
130 125
131static struct resource omap3isp_resources[] = { 126static struct resource omap3isp_resources[] = {
132 { 127 {
@@ -135,11 +130,6 @@ static struct resource omap3isp_resources[] = {
135 .flags = IORESOURCE_MEM, 130 .flags = IORESOURCE_MEM,
136 }, 131 },
137 { 132 {
138 .start = OMAP3430_ISP_CBUFF_BASE,
139 .end = OMAP3430_ISP_CBUFF_END,
140 .flags = IORESOURCE_MEM,
141 },
142 {
143 .start = OMAP3430_ISP_CCP2_BASE, 133 .start = OMAP3430_ISP_CCP2_BASE,
144 .end = OMAP3430_ISP_CCP2_END, 134 .end = OMAP3430_ISP_CCP2_END,
145 .flags = IORESOURCE_MEM, 135 .flags = IORESOURCE_MEM,
@@ -175,13 +165,33 @@ static struct resource omap3isp_resources[] = {
175 .flags = IORESOURCE_MEM, 165 .flags = IORESOURCE_MEM,
176 }, 166 },
177 { 167 {
178 .start = OMAP3430_ISP_CSI2A_BASE, 168 .start = OMAP3430_ISP_CSI2A_REGS1_BASE,
179 .end = OMAP3430_ISP_CSI2A_END, 169 .end = OMAP3430_ISP_CSI2A_REGS1_END,
170 .flags = IORESOURCE_MEM,
171 },
172 {
173 .start = OMAP3430_ISP_CSIPHY2_BASE,
174 .end = OMAP3430_ISP_CSIPHY2_END,
175 .flags = IORESOURCE_MEM,
176 },
177 {
178 .start = OMAP3630_ISP_CSI2A_REGS2_BASE,
179 .end = OMAP3630_ISP_CSI2A_REGS2_END,
180 .flags = IORESOURCE_MEM,
181 },
182 {
183 .start = OMAP3630_ISP_CSI2C_REGS1_BASE,
184 .end = OMAP3630_ISP_CSI2C_REGS1_END,
185 .flags = IORESOURCE_MEM,
186 },
187 {
188 .start = OMAP3630_ISP_CSIPHY1_BASE,
189 .end = OMAP3630_ISP_CSIPHY1_END,
180 .flags = IORESOURCE_MEM, 190 .flags = IORESOURCE_MEM,
181 }, 191 },
182 { 192 {
183 .start = OMAP3430_ISP_CSI2PHY_BASE, 193 .start = OMAP3630_ISP_CSI2C_REGS2_BASE,
184 .end = OMAP3430_ISP_CSI2PHY_END, 194 .end = OMAP3630_ISP_CSI2C_REGS2_END,
185 .flags = IORESOURCE_MEM, 195 .flags = IORESOURCE_MEM,
186 }, 196 },
187 { 197 {
@@ -197,15 +207,19 @@ static struct platform_device omap3isp_device = {
197 .resource = omap3isp_resources, 207 .resource = omap3isp_resources,
198}; 208};
199 209
200static inline void omap_init_camera(void) 210int omap3_init_camera(struct isp_platform_data *pdata)
201{ 211{
202 platform_device_register(&omap3isp_device); 212 omap3isp_device.dev.platform_data = pdata;
213 return platform_device_register(&omap3isp_device);
203} 214}
204#else 215
205static inline void omap_init_camera(void) 216static inline void omap_init_camera(void)
206{ 217{
207} 218#if defined(CONFIG_VIDEO_OMAP2) || defined(CONFIG_VIDEO_OMAP2_MODULE)
219 if (cpu_is_omap24xx())
220 platform_device_register(&omap2cam_device);
208#endif 221#endif
222}
209 223
210struct omap_device_pm_latency omap_keyboard_latency[] = { 224struct omap_device_pm_latency omap_keyboard_latency[] = {
211 { 225 {
diff --git a/arch/arm/mach-omap2/devices.h b/arch/arm/mach-omap2/devices.h
new file mode 100644
index 000000000000..f61eb6e5d136
--- /dev/null
+++ b/arch/arm/mach-omap2/devices.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-omap2/devices.h
3 *
4 * OMAP2 platform device setup/initialization
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
12#ifndef __ARCH_ARM_MACH_OMAP_DEVICES_H
13#define __ARCH_ARM_MACH_OMAP_DEVICES_H
14
15struct isp_platform_data;
16
17int omap3_init_camera(struct isp_platform_data *pdata);
18
19#endif
diff --git a/arch/arm/plat-omap/include/plat/omap34xx.h b/arch/arm/plat-omap/include/plat/omap34xx.h
index 98fc8b4a4cc4..b9e85886b9d6 100644
--- a/arch/arm/plat-omap/include/plat/omap34xx.h
+++ b/arch/arm/plat-omap/include/plat/omap34xx.h
@@ -56,8 +56,12 @@
56#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000) 56#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
57#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200) 57#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
58#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400) 58#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
59#define OMAP3430_ISP_CSI2A_BASE (OMAP3430_ISP_BASE + 0x1800) 59#define OMAP3430_ISP_CSI2A_REGS1_BASE (OMAP3430_ISP_BASE + 0x1800)
60#define OMAP3430_ISP_CSI2PHY_BASE (OMAP3430_ISP_BASE + 0x1970) 60#define OMAP3430_ISP_CSIPHY2_BASE (OMAP3430_ISP_BASE + 0x1970)
61#define OMAP3630_ISP_CSI2A_REGS2_BASE (OMAP3430_ISP_BASE + 0x19C0)
62#define OMAP3630_ISP_CSI2C_REGS1_BASE (OMAP3430_ISP_BASE + 0x1C00)
63#define OMAP3630_ISP_CSIPHY1_BASE (OMAP3430_ISP_BASE + 0x1D70)
64#define OMAP3630_ISP_CSI2C_REGS2_BASE (OMAP3430_ISP_BASE + 0x1DC0)
61 65
62#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F) 66#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
63#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077) 67#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
@@ -69,8 +73,12 @@
69#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB) 73#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
70#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB) 74#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
71#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F) 75#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
72#define OMAP3430_ISP_CSI2A_END (OMAP3430_ISP_CSI2A_BASE + 0x16F) 76#define OMAP3430_ISP_CSI2A_REGS1_END (OMAP3430_ISP_CSI2A_REGS1_BASE + 0x16F)
73#define OMAP3430_ISP_CSI2PHY_END (OMAP3430_ISP_CSI2PHY_BASE + 0x007) 77#define OMAP3430_ISP_CSIPHY2_END (OMAP3430_ISP_CSIPHY2_BASE + 0x00B)
78#define OMAP3630_ISP_CSI2A_REGS2_END (OMAP3630_ISP_CSI2A_REGS2_BASE + 0x3F)
79#define OMAP3630_ISP_CSI2C_REGS1_END (OMAP3630_ISP_CSI2C_REGS1_BASE + 0x16F)
80#define OMAP3630_ISP_CSIPHY1_END (OMAP3630_ISP_CSIPHY1_BASE + 0x00B)
81#define OMAP3630_ISP_CSI2C_REGS2_END (OMAP3630_ISP_CSI2C_REGS2_BASE + 0x3F)
74 82
75#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000) 83#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
76#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000) 84#define OMAP34XX_USBTLL_BASE (L4_34XX_BASE + 0x62000)
diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig
index 81b3ba83cc65..6995940b633a 100644
--- a/drivers/media/Kconfig
+++ b/drivers/media/Kconfig
@@ -14,6 +14,19 @@ if MEDIA_SUPPORT
14comment "Multimedia core support" 14comment "Multimedia core support"
15 15
16# 16#
17# Media controller
18#
19
20config MEDIA_CONTROLLER
21 bool "Media Controller API (EXPERIMENTAL)"
22 depends on EXPERIMENTAL
23 ---help---
24 Enable the media controller API used to query media devices internal
25 topology and configure it dynamically.
26
27 This API is mostly used by camera interfaces in embedded platforms.
28
29#
17# V4L core and enabled API's 30# V4L core and enabled API's
18# 31#
19 32
@@ -40,6 +53,15 @@ config VIDEO_V4L2_COMMON
40 depends on (I2C || I2C=n) && VIDEO_DEV 53 depends on (I2C || I2C=n) && VIDEO_DEV
41 default (I2C || I2C=n) && VIDEO_DEV 54 default (I2C || I2C=n) && VIDEO_DEV
42 55
56config VIDEO_V4L2_SUBDEV_API
57 bool "V4L2 sub-device userspace API (EXPERIMENTAL)"
58 depends on VIDEO_DEV && MEDIA_CONTROLLER && EXPERIMENTAL
59 ---help---
60 Enables the V4L2 sub-device pad-level userspace API used to configure
61 video format, size and frame rate between hardware blocks.
62
63 This API is mostly used by camera interfaces in embedded platforms.
64
43# 65#
44# DVB Core 66# DVB Core
45# 67#
diff --git a/drivers/media/Makefile b/drivers/media/Makefile
index b603ea645ede..64755c99ded2 100644
--- a/drivers/media/Makefile
+++ b/drivers/media/Makefile
@@ -2,6 +2,12 @@
2# Makefile for the kernel multimedia device drivers. 2# Makefile for the kernel multimedia device drivers.
3# 3#
4 4
5media-objs := media-device.o media-devnode.o media-entity.o
6
7ifeq ($(CONFIG_MEDIA_CONTROLLER),y)
8 obj-$(CONFIG_MEDIA_SUPPORT) += media.o
9endif
10
5obj-y += common/ rc/ video/ 11obj-y += common/ rc/ video/
6 12
7obj-$(CONFIG_VIDEO_DEV) += radio/ 13obj-$(CONFIG_VIDEO_DEV) += radio/
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index bf14bd79e2fc..cdb645d57438 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -36,6 +36,8 @@ struct tda9887_priv {
36 unsigned int mode; 36 unsigned int mode;
37 unsigned int audmode; 37 unsigned int audmode;
38 v4l2_std_id std; 38 v4l2_std_id std;
39
40 bool standby;
39}; 41};
40 42
41/* ---------------------------------------------------------------------- */ 43/* ---------------------------------------------------------------------- */
@@ -568,7 +570,7 @@ static void tda9887_configure(struct dvb_frontend *fe)
568 tda9887_do_config(fe); 570 tda9887_do_config(fe);
569 tda9887_set_insmod(fe); 571 tda9887_set_insmod(fe);
570 572
571 if (priv->mode == T_STANDBY) 573 if (priv->standby)
572 priv->data[1] |= cForcedMuteAudioON; 574 priv->data[1] |= cForcedMuteAudioON;
573 575
574 tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n", 576 tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
@@ -616,7 +618,7 @@ static void tda9887_standby(struct dvb_frontend *fe)
616{ 618{
617 struct tda9887_priv *priv = fe->analog_demod_priv; 619 struct tda9887_priv *priv = fe->analog_demod_priv;
618 620
619 priv->mode = T_STANDBY; 621 priv->standby = true;
620 622
621 tda9887_configure(fe); 623 tda9887_configure(fe);
622} 624}
@@ -626,6 +628,7 @@ static void tda9887_set_params(struct dvb_frontend *fe,
626{ 628{
627 struct tda9887_priv *priv = fe->analog_demod_priv; 629 struct tda9887_priv *priv = fe->analog_demod_priv;
628 630
631 priv->standby = false;
629 priv->mode = params->mode; 632 priv->mode = params->mode;
630 priv->audmode = params->audmode; 633 priv->audmode = params->audmode;
631 priv->std = params->std; 634 priv->std = params->std;
@@ -686,7 +689,7 @@ struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
686 return NULL; 689 return NULL;
687 case 1: 690 case 1:
688 fe->analog_demod_priv = priv; 691 fe->analog_demod_priv = priv;
689 priv->mode = T_STANDBY; 692 priv->standby = true;
690 tuner_info("tda988[5/6/7] found\n"); 693 tuner_info("tda988[5/6/7] found\n");
691 break; 694 break;
692 default: 695 default:
diff --git a/drivers/media/common/tuners/tea5761.c b/drivers/media/common/tuners/tea5761.c
index 925399dffbed..bf78cb9fc52c 100644
--- a/drivers/media/common/tuners/tea5761.c
+++ b/drivers/media/common/tuners/tea5761.c
@@ -23,6 +23,7 @@ struct tea5761_priv {
23 struct tuner_i2c_props i2c_props; 23 struct tuner_i2c_props i2c_props;
24 24
25 u32 frequency; 25 u32 frequency;
26 bool standby;
26}; 27};
27 28
28/*****************************************************************************/ 29/*****************************************************************************/
@@ -135,18 +136,19 @@ static void tea5761_status_dump(unsigned char *buffer)
135} 136}
136 137
137/* Freq should be specifyed at 62.5 Hz */ 138/* Freq should be specifyed at 62.5 Hz */
138static int set_radio_freq(struct dvb_frontend *fe, 139static int __set_radio_freq(struct dvb_frontend *fe,
139 struct analog_parameters *params) 140 unsigned int freq,
141 bool mono)
140{ 142{
141 struct tea5761_priv *priv = fe->tuner_priv; 143 struct tea5761_priv *priv = fe->tuner_priv;
142 unsigned int frq = params->frequency; 144 unsigned int frq = freq;
143 unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 }; 145 unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
144 unsigned div; 146 unsigned div;
145 int rc; 147 int rc;
146 148
147 tuner_dbg("radio freq counter %d\n", frq); 149 tuner_dbg("radio freq counter %d\n", frq);
148 150
149 if (params->mode == T_STANDBY) { 151 if (priv->standby) {
150 tuner_dbg("TEA5761 set to standby mode\n"); 152 tuner_dbg("TEA5761 set to standby mode\n");
151 buffer[5] |= TEA5761_TNCTRL_MU; 153 buffer[5] |= TEA5761_TNCTRL_MU;
152 } else { 154 } else {
@@ -154,7 +156,7 @@ static int set_radio_freq(struct dvb_frontend *fe,
154 } 156 }
155 157
156 158
157 if (params->audmode == V4L2_TUNER_MODE_MONO) { 159 if (mono) {
158 tuner_dbg("TEA5761 set to mono\n"); 160 tuner_dbg("TEA5761 set to mono\n");
159 buffer[5] |= TEA5761_TNCTRL_MST; 161 buffer[5] |= TEA5761_TNCTRL_MST;
160 } else { 162 } else {
@@ -176,6 +178,26 @@ static int set_radio_freq(struct dvb_frontend *fe,
176 return 0; 178 return 0;
177} 179}
178 180
181static int set_radio_freq(struct dvb_frontend *fe,
182 struct analog_parameters *params)
183{
184 struct tea5761_priv *priv = fe->analog_demod_priv;
185
186 priv->standby = false;
187
188 return __set_radio_freq(fe, params->frequency,
189 params->audmode == V4L2_TUNER_MODE_MONO);
190}
191
192static int set_radio_sleep(struct dvb_frontend *fe)
193{
194 struct tea5761_priv *priv = fe->analog_demod_priv;
195
196 priv->standby = true;
197
198 return __set_radio_freq(fe, priv->frequency, false);
199}
200
179static int tea5761_read_status(struct dvb_frontend *fe, char *buffer) 201static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
180{ 202{
181 struct tea5761_priv *priv = fe->tuner_priv; 203 struct tea5761_priv *priv = fe->tuner_priv;
@@ -284,6 +306,7 @@ static struct dvb_tuner_ops tea5761_tuner_ops = {
284 .name = "tea5761", // Philips TEA5761HN FM Radio 306 .name = "tea5761", // Philips TEA5761HN FM Radio
285 }, 307 },
286 .set_analog_params = set_radio_freq, 308 .set_analog_params = set_radio_freq,
309 .sleep = set_radio_sleep,
287 .release = tea5761_release, 310 .release = tea5761_release,
288 .get_frequency = tea5761_get_frequency, 311 .get_frequency = tea5761_get_frequency,
289 .get_status = tea5761_get_status, 312 .get_status = tea5761_get_status,
diff --git a/drivers/media/common/tuners/tuner-types.c b/drivers/media/common/tuners/tuner-types.c
index 58a513bcd747..afba6dc5e080 100644
--- a/drivers/media/common/tuners/tuner-types.c
+++ b/drivers/media/common/tuners/tuner-types.c
@@ -971,6 +971,22 @@ static struct tuner_params tuner_tena_9533_di_params[] = {
971 }, 971 },
972}; 972};
973 973
974/* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */
975
976static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = {
977 { 16 * 166.25 /*MHz*/, 0x86, 0x01, },
978 { 16 * 466.25 /*MHz*/, 0x86, 0x02, },
979 { 16 * 999.99 , 0x86, 0x08, },
980};
981
982static struct tuner_params tuner_tena_tnf_5337_params[] = {
983 {
984 .type = TUNER_PARAM_TYPE_NTSC,
985 .ranges = tuner_tena_tnf_5337_ntsc_ranges,
986 .count = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges),
987 },
988};
989
974/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */ 990/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
975 991
976static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = { 992static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
@@ -1842,6 +1858,11 @@ struct tunertype tuners[] = {
1842 .params = tuner_philips_fq1236_mk5_params, 1858 .params = tuner_philips_fq1236_mk5_params,
1843 .count = ARRAY_SIZE(tuner_philips_fq1236_mk5_params), 1859 .count = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
1844 }, 1860 },
1861 [TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */
1862 .name = "Tena TNF5337 MFD",
1863 .params = tuner_tena_tnf_5337_params,
1864 .count = ARRAY_SIZE(tuner_tena_tnf_5337_params),
1865 },
1845}; 1866};
1846EXPORT_SYMBOL(tuners); 1867EXPORT_SYMBOL(tuners);
1847 1868
diff --git a/drivers/media/common/tuners/tuner-xc2028.c b/drivers/media/common/tuners/tuner-xc2028.c
index b6ce528e1889..16fba6b59616 100644
--- a/drivers/media/common/tuners/tuner-xc2028.c
+++ b/drivers/media/common/tuners/tuner-xc2028.c
@@ -685,7 +685,7 @@ static int check_firmware(struct dvb_frontend *fe, unsigned int type,
685{ 685{
686 struct xc2028_data *priv = fe->tuner_priv; 686 struct xc2028_data *priv = fe->tuner_priv;
687 struct firmware_properties new_fw; 687 struct firmware_properties new_fw;
688 int rc = 0, is_retry = 0; 688 int rc = 0, retry_count = 0;
689 u16 version, hwmodel; 689 u16 version, hwmodel;
690 v4l2_std_id std0; 690 v4l2_std_id std0;
691 691
@@ -855,9 +855,9 @@ read_not_reliable:
855 855
856fail: 856fail:
857 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw)); 857 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
858 if (!is_retry) { 858 if (retry_count < 8) {
859 msleep(50); 859 msleep(50);
860 is_retry = 1; 860 retry_count++;
861 tuner_dbg("Retrying firmware load\n"); 861 tuner_dbg("Retrying firmware load\n");
862 goto retry; 862 goto retry;
863 } 863 }
@@ -907,7 +907,7 @@ ret:
907#define DIV 15625 907#define DIV 15625
908 908
909static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */, 909static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
910 enum tuner_mode new_mode, 910 enum v4l2_tuner_type new_type,
911 unsigned int type, 911 unsigned int type,
912 v4l2_std_id std, 912 v4l2_std_id std,
913 u16 int_freq) 913 u16 int_freq)
@@ -933,7 +933,7 @@ static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
933 * that xc2028 will be in a safe state. 933 * that xc2028 will be in a safe state.
934 * Maybe this might also be needed for DTV. 934 * Maybe this might also be needed for DTV.
935 */ 935 */
936 if (new_mode == T_ANALOG_TV) { 936 if (new_type == V4L2_TUNER_ANALOG_TV) {
937 rc = send_seq(priv, {0x00, 0x00}); 937 rc = send_seq(priv, {0x00, 0x00});
938 938
939 /* Analog modes require offset = 0 */ 939 /* Analog modes require offset = 0 */
@@ -1054,7 +1054,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
1054 if (priv->ctrl.input1) 1054 if (priv->ctrl.input1)
1055 type |= INPUT1; 1055 type |= INPUT1;
1056 return generic_set_freq(fe, (625l * p->frequency) / 10, 1056 return generic_set_freq(fe, (625l * p->frequency) / 10,
1057 T_RADIO, type, 0, 0); 1057 V4L2_TUNER_RADIO, type, 0, 0);
1058 } 1058 }
1059 1059
1060 /* if std is not defined, choose one */ 1060 /* if std is not defined, choose one */
@@ -1069,7 +1069,7 @@ static int xc2028_set_analog_freq(struct dvb_frontend *fe,
1069 p->std |= parse_audio_std_option(); 1069 p->std |= parse_audio_std_option();
1070 1070
1071 return generic_set_freq(fe, 62500l * p->frequency, 1071 return generic_set_freq(fe, 62500l * p->frequency,
1072 T_ANALOG_TV, type, p->std, 0); 1072 V4L2_TUNER_ANALOG_TV, type, p->std, 0);
1073} 1073}
1074 1074
1075static int xc2028_set_params(struct dvb_frontend *fe, 1075static int xc2028_set_params(struct dvb_frontend *fe,
@@ -1174,7 +1174,7 @@ static int xc2028_set_params(struct dvb_frontend *fe,
1174 } 1174 }
1175 1175
1176 return generic_set_freq(fe, p->frequency, 1176 return generic_set_freq(fe, p->frequency,
1177 T_DIGITAL_TV, type, 0, demod); 1177 V4L2_TUNER_DIGITAL_TV, type, 0, demod);
1178} 1178}
1179 1179
1180static int xc2028_sleep(struct dvb_frontend *fe) 1180static int xc2028_sleep(struct dvb_frontend *fe)
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index 76ac5cd84af7..1e28f7dcb26b 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -65,7 +65,7 @@ struct xc5000_priv {
65}; 65};
66 66
67/* Misc Defines */ 67/* Misc Defines */
68#define MAX_TV_STANDARD 23 68#define MAX_TV_STANDARD 24
69#define XC_MAX_I2C_WRITE_LENGTH 64 69#define XC_MAX_I2C_WRITE_LENGTH 64
70 70
71/* Signal Types */ 71/* Signal Types */
@@ -92,6 +92,8 @@ struct xc5000_priv {
92#define XREG_IF_OUT 0x05 92#define XREG_IF_OUT 0x05
93#define XREG_SEEK_MODE 0x07 93#define XREG_SEEK_MODE 0x07
94#define XREG_POWER_DOWN 0x0A /* Obsolete */ 94#define XREG_POWER_DOWN 0x0A /* Obsolete */
95/* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */
96#define XREG_OUTPUT_AMP 0x0B
95#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */ 97#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
96#define XREG_SMOOTHEDCVBS 0x0E 98#define XREG_SMOOTHEDCVBS 0x0E
97#define XREG_XTALFREQ 0x0F 99#define XREG_XTALFREQ 0x0F
@@ -173,6 +175,7 @@ struct XC_TV_STANDARD {
173#define DTV7 20 175#define DTV7 20
174#define FM_Radio_INPUT2 21 176#define FM_Radio_INPUT2 21
175#define FM_Radio_INPUT1 22 177#define FM_Radio_INPUT1 22
178#define FM_Radio_INPUT1_MONO 23
176 179
177static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = { 180static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
178 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020}, 181 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
@@ -197,7 +200,8 @@ static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
197 {"DTV7/8", 0x00C0, 0x801B}, 200 {"DTV7/8", 0x00C0, 0x801B},
198 {"DTV7", 0x00C0, 0x8007}, 201 {"DTV7", 0x00C0, 0x8007},
199 {"FM Radio-INPUT2", 0x9802, 0x9002}, 202 {"FM Radio-INPUT2", 0x9802, 0x9002},
200 {"FM Radio-INPUT1", 0x0208, 0x9002} 203 {"FM Radio-INPUT1", 0x0208, 0x9002},
204 {"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
201}; 205};
202 206
203static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe); 207static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
@@ -683,6 +687,24 @@ static int xc5000_set_params(struct dvb_frontend *fe,
683 return -EINVAL; 687 return -EINVAL;
684 } 688 }
685 priv->rf_mode = XC_RF_MODE_AIR; 689 priv->rf_mode = XC_RF_MODE_AIR;
690 } else if (fe->ops.info.type == FE_QAM) {
691 dprintk(1, "%s() QAM\n", __func__);
692 switch (params->u.qam.modulation) {
693 case QAM_16:
694 case QAM_32:
695 case QAM_64:
696 case QAM_128:
697 case QAM_256:
698 case QAM_AUTO:
699 dprintk(1, "%s() QAM modulation\n", __func__);
700 priv->bandwidth = BANDWIDTH_8_MHZ;
701 priv->video_standard = DTV7_8;
702 priv->freq_hz = params->frequency - 2750000;
703 priv->rf_mode = XC_RF_MODE_CABLE;
704 break;
705 default:
706 return -EINVAL;
707 }
686 } else { 708 } else {
687 printk(KERN_ERR "xc5000 modulation type not supported!\n"); 709 printk(KERN_ERR "xc5000 modulation type not supported!\n");
688 return -EINVAL; 710 return -EINVAL;
@@ -714,6 +736,8 @@ static int xc5000_set_params(struct dvb_frontend *fe,
714 return -EIO; 736 return -EIO;
715 } 737 }
716 738
739 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
740
717 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL); 741 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
718 742
719 if (debug) 743 if (debug)
@@ -818,6 +842,8 @@ tune_channel:
818 return -EREMOTEIO; 842 return -EREMOTEIO;
819 } 843 }
820 844
845 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
846
821 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); 847 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
822 848
823 if (debug) 849 if (debug)
@@ -845,6 +871,8 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
845 radio_input = FM_Radio_INPUT1; 871 radio_input = FM_Radio_INPUT1;
846 else if (priv->radio_input == XC5000_RADIO_FM2) 872 else if (priv->radio_input == XC5000_RADIO_FM2)
847 radio_input = FM_Radio_INPUT2; 873 radio_input = FM_Radio_INPUT2;
874 else if (priv->radio_input == XC5000_RADIO_FM1_MONO)
875 radio_input = FM_Radio_INPUT1_MONO;
848 else { 876 else {
849 dprintk(1, "%s() unknown radio input %d\n", __func__, 877 dprintk(1, "%s() unknown radio input %d\n", __func__,
850 priv->radio_input); 878 priv->radio_input);
@@ -871,6 +899,12 @@ static int xc5000_set_radio_freq(struct dvb_frontend *fe,
871 return -EREMOTEIO; 899 return -EREMOTEIO;
872 } 900 }
873 901
902 if ((priv->radio_input == XC5000_RADIO_FM1) ||
903 (priv->radio_input == XC5000_RADIO_FM2))
904 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
905 else if (priv->radio_input == XC5000_RADIO_FM1_MONO)
906 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06);
907
874 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG); 908 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
875 909
876 return 0; 910 return 0;
@@ -1021,6 +1055,23 @@ static int xc5000_release(struct dvb_frontend *fe)
1021 return 0; 1055 return 0;
1022} 1056}
1023 1057
1058static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
1059{
1060 struct xc5000_priv *priv = fe->tuner_priv;
1061 struct xc5000_config *p = priv_cfg;
1062
1063 dprintk(1, "%s()\n", __func__);
1064
1065 if (p->if_khz)
1066 priv->if_khz = p->if_khz;
1067
1068 if (p->radio_input)
1069 priv->radio_input = p->radio_input;
1070
1071 return 0;
1072}
1073
1074
1024static const struct dvb_tuner_ops xc5000_tuner_ops = { 1075static const struct dvb_tuner_ops xc5000_tuner_ops = {
1025 .info = { 1076 .info = {
1026 .name = "Xceive XC5000", 1077 .name = "Xceive XC5000",
@@ -1033,6 +1084,7 @@ static const struct dvb_tuner_ops xc5000_tuner_ops = {
1033 .init = xc5000_init, 1084 .init = xc5000_init,
1034 .sleep = xc5000_sleep, 1085 .sleep = xc5000_sleep,
1035 1086
1087 .set_config = xc5000_set_config,
1036 .set_params = xc5000_set_params, 1088 .set_params = xc5000_set_params,
1037 .set_analog_params = xc5000_set_analog_params, 1089 .set_analog_params = xc5000_set_analog_params,
1038 .get_frequency = xc5000_get_frequency, 1090 .get_frequency = xc5000_get_frequency,
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index 3756e73649be..e2957451b532 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -40,6 +40,7 @@ struct xc5000_config {
40#define XC5000_RADIO_NOT_CONFIGURED 0 40#define XC5000_RADIO_NOT_CONFIGURED 0
41#define XC5000_RADIO_FM1 1 41#define XC5000_RADIO_FM1 1
42#define XC5000_RADIO_FM2 2 42#define XC5000_RADIO_FM2 2
43#define XC5000_RADIO_FM1_MONO 3
43 44
44/* For each bridge framework, when it attaches either analog or digital, 45/* For each bridge framework, when it attaches either analog or digital,
45 * it has to store a reference back to its _core equivalent structure, 46 * it has to store a reference back to its _core equivalent structure,
diff --git a/drivers/media/dvb/Kconfig b/drivers/media/dvb/Kconfig
index 161ccfd471cb..ee214c3b63d7 100644
--- a/drivers/media/dvb/Kconfig
+++ b/drivers/media/dvb/Kconfig
@@ -65,7 +65,7 @@ comment "Supported SDMC DM1105 Adapters"
65source "drivers/media/dvb/dm1105/Kconfig" 65source "drivers/media/dvb/dm1105/Kconfig"
66 66
67comment "Supported FireWire (IEEE 1394) Adapters" 67comment "Supported FireWire (IEEE 1394) Adapters"
68 depends on DVB_CORE && IEEE1394 68 depends on DVB_CORE && FIREWIRE
69source "drivers/media/dvb/firewire/Kconfig" 69source "drivers/media/dvb/firewire/Kconfig"
70 70
71comment "Supported Earthsoft PT1 Adapters" 71comment "Supported Earthsoft PT1 Adapters"
diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.h b/drivers/media/dvb/dvb-core/dvb_frontend.h
index f9f19be77181..3b860504bf04 100644
--- a/drivers/media/dvb/dvb-core/dvb_frontend.h
+++ b/drivers/media/dvb/dvb-core/dvb_frontend.h
@@ -239,7 +239,6 @@ struct analog_demod_ops {
239 void (*set_params)(struct dvb_frontend *fe, 239 void (*set_params)(struct dvb_frontend *fe,
240 struct analog_parameters *params); 240 struct analog_parameters *params);
241 int (*has_signal)(struct dvb_frontend *fe); 241 int (*has_signal)(struct dvb_frontend *fe);
242 int (*is_stereo)(struct dvb_frontend *fe);
243 int (*get_afc)(struct dvb_frontend *fe); 242 int (*get_afc)(struct dvb_frontend *fe);
244 void (*tuner_status)(struct dvb_frontend *fe); 243 void (*tuner_status)(struct dvb_frontend *fe);
245 void (*standby)(struct dvb_frontend *fe); 244 void (*standby)(struct dvb_frontend *fe);
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index 3d48ba019342..fe4f894183ff 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -358,3 +358,11 @@ config DVB_USB_LME2510
358 select DVB_IX2505V if !DVB_FE_CUSTOMISE 358 select DVB_IX2505V if !DVB_FE_CUSTOMISE
359 help 359 help
360 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 . 360 Say Y here to support the LME DM04/QQBOX DVB-S USB2.0 .
361
362config DVB_USB_TECHNISAT_USB2
363 tristate "Technisat DVB-S/S2 USB2.0 support"
364 depends on DVB_USB
365 select DVB_STB0899 if !DVB_FE_CUSTOMISE
366 select DVB_STB6100 if !DVB_FE_CUSTOMISE
367 help
368 Say Y here to support the Technisat USB2 DVB-S/S2 device
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 5b1d12f2d591..4bac13da0c39 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -91,6 +91,9 @@ obj-$(CONFIG_DVB_USB_AZ6027) += dvb-usb-az6027.o
91dvb-usb-lmedm04-objs = lmedm04.o 91dvb-usb-lmedm04-objs = lmedm04.o
92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o 92obj-$(CONFIG_DVB_USB_LME2510) += dvb-usb-lmedm04.o
93 93
94dvb-usb-technisat-usb2-objs = technisat-usb2.o
95obj-$(CONFIG_DVB_USB_TECHNISAT_USB2) += dvb-usb-technisat-usb2.o
96
94EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 97EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
95# due to tuner-xc3028 98# due to tuner-xc3028
96EXTRA_CFLAGS += -Idrivers/media/common/tuners 99EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c
index 53b93a4b6f8a..f8e9bf116f21 100644
--- a/drivers/media/dvb/dvb-usb/a800.c
+++ b/drivers/media/dvb/dvb-usb/a800.c
@@ -38,8 +38,8 @@ static int a800_identify_state(struct usb_device *udev, struct dvb_usb_device_pr
38} 38}
39 39
40static struct rc_map_table rc_map_a800_table[] = { 40static struct rc_map_table rc_map_a800_table[] = {
41 { 0x0201, KEY_PROG1 }, /* SOURCE */ 41 { 0x0201, KEY_MODE }, /* SOURCE */
42 { 0x0200, KEY_POWER }, /* POWER */ 42 { 0x0200, KEY_POWER2 }, /* POWER */
43 { 0x0205, KEY_1 }, /* 1 */ 43 { 0x0205, KEY_1 }, /* 1 */
44 { 0x0206, KEY_2 }, /* 2 */ 44 { 0x0206, KEY_2 }, /* 2 */
45 { 0x0207, KEY_3 }, /* 3 */ 45 { 0x0207, KEY_3 }, /* 3 */
@@ -52,8 +52,8 @@ static struct rc_map_table rc_map_a800_table[] = {
52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */ 52 { 0x0212, KEY_LEFT }, /* L / DISPLAY */
53 { 0x0211, KEY_0 }, /* 0 */ 53 { 0x0211, KEY_0 }, /* 0 */
54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */ 54 { 0x0213, KEY_RIGHT }, /* R / CH RTN */
55 { 0x0217, KEY_PROG2 }, /* SNAP SHOT */ 55 { 0x0217, KEY_CAMERA }, /* SNAP SHOT */
56 { 0x0210, KEY_PROG3 }, /* 16-CH PREV */ 56 { 0x0210, KEY_LAST }, /* 16-CH PREV */
57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */ 57 { 0x021e, KEY_VOLUMEDOWN }, /* VOL DOWN */
58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */ 58 { 0x020c, KEY_ZOOM }, /* FULL SCREEN */
59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */ 59 { 0x021f, KEY_VOLUMEUP }, /* VOL UP */
diff --git a/drivers/media/dvb/dvb-usb/af9015.c b/drivers/media/dvb/dvb-usb/af9015.c
index 8671ca362c81..100ebc37e99e 100644
--- a/drivers/media/dvb/dvb-usb/af9015.c
+++ b/drivers/media/dvb/dvb-usb/af9015.c
@@ -479,6 +479,7 @@ static int af9015_init_endpoint(struct dvb_usb_device *d)
479 ret = af9015_set_reg_bit(d, 0xd50b, 0); 479 ret = af9015_set_reg_bit(d, 0xd50b, 0);
480 else 480 else
481 ret = af9015_clear_reg_bit(d, 0xd50b, 0); 481 ret = af9015_clear_reg_bit(d, 0xd50b, 0);
482
482error: 483error:
483 if (ret) 484 if (ret)
484 err("endpoint init failed:%d", ret); 485 err("endpoint init failed:%d", ret);
@@ -611,6 +612,11 @@ static int af9015_init(struct dvb_usb_device *d)
611 int ret; 612 int ret;
612 deb_info("%s:\n", __func__); 613 deb_info("%s:\n", __func__);
613 614
615 /* init RC canary */
616 ret = af9015_write_reg(d, 0x98e9, 0xff);
617 if (ret)
618 goto error;
619
614 ret = af9015_init_endpoint(d); 620 ret = af9015_init_endpoint(d);
615 if (ret) 621 if (ret)
616 goto error; 622 goto error;
@@ -659,9 +665,8 @@ error:
659static int af9015_download_firmware(struct usb_device *udev, 665static int af9015_download_firmware(struct usb_device *udev,
660 const struct firmware *fw) 666 const struct firmware *fw)
661{ 667{
662 int i, len, packets, remainder, ret; 668 int i, len, remaining, ret;
663 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL}; 669 struct req_t req = {DOWNLOAD_FIRMWARE, 0, 0, 0, 0, 0, NULL};
664 u16 addr = 0x5100; /* firmware start address */
665 u16 checksum = 0; 670 u16 checksum = 0;
666 671
667 deb_info("%s:\n", __func__); 672 deb_info("%s:\n", __func__);
@@ -673,24 +678,20 @@ static int af9015_download_firmware(struct usb_device *udev,
673 af9015_config.firmware_size = fw->size; 678 af9015_config.firmware_size = fw->size;
674 af9015_config.firmware_checksum = checksum; 679 af9015_config.firmware_checksum = checksum;
675 680
676 #define FW_PACKET_MAX_DATA 55 681 #define FW_ADDR 0x5100 /* firmware start address */
677 682 #define LEN_MAX 55 /* max packet size */
678 packets = fw->size / FW_PACKET_MAX_DATA; 683 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
679 remainder = fw->size % FW_PACKET_MAX_DATA; 684 len = remaining;
680 len = FW_PACKET_MAX_DATA; 685 if (len > LEN_MAX)
681 for (i = 0; i <= packets; i++) { 686 len = LEN_MAX;
682 if (i == packets) /* set size of the last packet */
683 len = remainder;
684 687
685 req.data_len = len; 688 req.data_len = len;
686 req.data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA); 689 req.data = (u8 *) &fw->data[fw->size - remaining];
687 req.addr = addr; 690 req.addr = FW_ADDR + fw->size - remaining;
688 addr += FW_PACKET_MAX_DATA;
689 691
690 ret = af9015_rw_udev(udev, &req); 692 ret = af9015_rw_udev(udev, &req);
691 if (ret) { 693 if (ret) {
692 err("firmware download failed at packet %d with " \ 694 err("firmware download failed:%d", ret);
693 "code %d", i, ret);
694 goto error; 695 goto error;
695 } 696 }
696 } 697 }
@@ -738,6 +739,8 @@ static const struct af9015_rc_setup af9015_rc_setup_hashes[] = {
738}; 739};
739 740
740static const struct af9015_rc_setup af9015_rc_setup_usbids[] = { 741static const struct af9015_rc_setup af9015_rc_setup_usbids[] = {
742 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_RC,
743 RC_MAP_TERRATEC_SLIM_2 },
741 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC, 744 { (USB_VID_TERRATEC << 16) + USB_PID_TERRATEC_CINERGY_T_STICK_DUAL_RC,
742 RC_MAP_TERRATEC_SLIM }, 745 RC_MAP_TERRATEC_SLIM },
743 { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700, 746 { (USB_VID_VISIONPLUS << 16) + USB_PID_AZUREWAVE_AD_TU700,
@@ -1016,22 +1019,38 @@ static int af9015_rc_query(struct dvb_usb_device *d)
1016{ 1019{
1017 struct af9015_state *priv = d->priv; 1020 struct af9015_state *priv = d->priv;
1018 int ret; 1021 int ret;
1019 u8 buf[16]; 1022 u8 buf[17];
1020 1023
1021 /* read registers needed to detect remote controller code */ 1024 /* read registers needed to detect remote controller code */
1022 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf)); 1025 ret = af9015_read_regs(d, 0x98d9, buf, sizeof(buf));
1023 if (ret) 1026 if (ret)
1024 goto error; 1027 goto error;
1025 1028
1026 if (buf[14] || buf[15]) { 1029 /* If any of these are non-zero, assume invalid data */
1030 if (buf[1] || buf[2] || buf[3])
1031 return ret;
1032
1033 /* Check for repeat of previous code */
1034 if ((priv->rc_repeat != buf[6] || buf[0]) &&
1035 !memcmp(&buf[12], priv->rc_last, 4)) {
1036 deb_rc("%s: key repeated\n", __func__);
1037 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1038 priv->rc_repeat = buf[6];
1039 return ret;
1040 }
1041
1042 /* Only process key if canary killed */
1043 if (buf[16] != 0xff && buf[0] != 0x01) {
1027 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__, 1044 deb_rc("%s: key pressed %02x %02x %02x %02x\n", __func__,
1028 buf[12], buf[13], buf[14], buf[15]); 1045 buf[12], buf[13], buf[14], buf[15]);
1029 1046
1030 /* clean IR code from mem */ 1047 /* Reset the canary */
1031 ret = af9015_write_regs(d, 0x98e5, "\x00\x00\x00\x00", 4); 1048 ret = af9015_write_reg(d, 0x98e9, 0xff);
1032 if (ret) 1049 if (ret)
1033 goto error; 1050 goto error;
1034 1051
1052 /* Remember this key */
1053 memcpy(priv->rc_last, &buf[12], 4);
1035 if (buf[14] == (u8) ~buf[15]) { 1054 if (buf[14] == (u8) ~buf[15]) {
1036 if (buf[12] == (u8) ~buf[13]) { 1055 if (buf[12] == (u8) ~buf[13]) {
1037 /* NEC */ 1056 /* NEC */
@@ -1041,15 +1060,17 @@ static int af9015_rc_query(struct dvb_usb_device *d)
1041 priv->rc_keycode = buf[12] << 16 | 1060 priv->rc_keycode = buf[12] << 16 |
1042 buf[13] << 8 | buf[14]; 1061 buf[13] << 8 | buf[14];
1043 } 1062 }
1044 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1045 } else { 1063 } else {
1046 priv->rc_keycode = 0; /* clear just for sure */ 1064 /* 32 bit NEC */
1065 priv->rc_keycode = buf[12] << 24 | buf[13] << 16 |
1066 buf[14] << 8 | buf[15];
1047 } 1067 }
1048 } else if (priv->rc_repeat != buf[6] || buf[0]) {
1049 deb_rc("%s: key repeated\n", __func__);
1050 rc_keydown(d->rc_dev, priv->rc_keycode, 0); 1068 rc_keydown(d->rc_dev, priv->rc_keycode, 0);
1051 } else { 1069 } else {
1052 deb_rc("%s: no key press\n", __func__); 1070 deb_rc("%s: no key press\n", __func__);
1071 /* Invalidate last keypress */
1072 /* Not really needed, but helps with debug */
1073 priv->rc_last[2] = priv->rc_last[3];
1053 } 1074 }
1054 1075
1055 priv->rc_repeat = buf[6]; 1076 priv->rc_repeat = buf[6];
diff --git a/drivers/media/dvb/dvb-usb/af9015.h b/drivers/media/dvb/dvb-usb/af9015.h
index f20cfa6ed690..beb3004f00ba 100644
--- a/drivers/media/dvb/dvb-usb/af9015.h
+++ b/drivers/media/dvb/dvb-usb/af9015.h
@@ -102,6 +102,7 @@ struct af9015_state {
102 struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */ 102 struct i2c_adapter i2c_adap; /* I2C adapter for 2nd FE */
103 u8 rc_repeat; 103 u8 rc_repeat;
104 u32 rc_keycode; 104 u32 rc_keycode;
105 u8 rc_last[4];
105}; 106};
106 107
107struct af9015_config { 108struct af9015_config {
diff --git a/drivers/media/dvb/dvb-usb/dib0700.h b/drivers/media/dvb/dvb-usb/dib0700.h
index 3537d65c04bc..b2a87f2c2c3e 100644
--- a/drivers/media/dvb/dvb-usb/dib0700.h
+++ b/drivers/media/dvb/dvb-usb/dib0700.h
@@ -32,6 +32,7 @@ extern int dvb_usb_dib0700_debug;
32 // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog) 32 // 1 Byte: 4MSB(1 = enable streaming, 0 = disable streaming) 4LSB(Video Mode: 0 = MPEG2 188Bytes, 1 = Analog)
33 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1) 33 // 2 Byte: MPEG2 mode: 4MSB(1 = Master Mode, 0 = Slave Mode) 4LSB(Channel 1 = bit0, Channel 2 = bit1)
34 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " ) 34 // 2 Byte: Analog mode: 4MSB(0 = 625 lines, 1 = 525 lines) 4LSB( " " )
35#define REQUEST_SET_I2C_PARAM 0x10
35#define REQUEST_SET_RC 0x11 36#define REQUEST_SET_RC 0x11
36#define REQUEST_NEW_I2C_READ 0x12 37#define REQUEST_NEW_I2C_READ 0x12
37#define REQUEST_NEW_I2C_WRITE 0x13 38#define REQUEST_NEW_I2C_WRITE 0x13
@@ -61,6 +62,7 @@ extern struct i2c_algorithm dib0700_i2c_algo;
61extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props, 62extern int dib0700_identify_state(struct usb_device *udev, struct dvb_usb_device_properties *props,
62 struct dvb_usb_device_description **desc, int *cold); 63 struct dvb_usb_device_description **desc, int *cold);
63extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type); 64extern int dib0700_change_protocol(struct rc_dev *dev, u64 rc_type);
65extern int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz);
64 66
65extern int dib0700_device_count; 67extern int dib0700_device_count;
66extern int dvb_usb_dib0700_ir_proto; 68extern int dvb_usb_dib0700_ir_proto;
diff --git a/drivers/media/dvb/dvb-usb/dib0700_core.c b/drivers/media/dvb/dvb-usb/dib0700_core.c
index 98ffb40728e3..b79af68c54ae 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_core.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_core.c
@@ -186,7 +186,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
186 msg[i].len, 186 msg[i].len,
187 USB_CTRL_GET_TIMEOUT); 187 USB_CTRL_GET_TIMEOUT);
188 if (result < 0) { 188 if (result < 0) {
189 err("i2c read error (status = %d)\n", result); 189 deb_info("i2c read error (status = %d)\n", result);
190 break; 190 break;
191 } 191 }
192 192
@@ -215,7 +215,7 @@ static int dib0700_i2c_xfer_new(struct i2c_adapter *adap, struct i2c_msg *msg,
215 0, 0, buf, msg[i].len + 4, 215 0, 0, buf, msg[i].len + 4,
216 USB_CTRL_GET_TIMEOUT); 216 USB_CTRL_GET_TIMEOUT);
217 if (result < 0) { 217 if (result < 0) {
218 err("i2c write error (status = %d)\n", result); 218 deb_info("i2c write error (status = %d)\n", result);
219 break; 219 break;
220 } 220 }
221 } 221 }
@@ -328,6 +328,31 @@ static int dib0700_set_clock(struct dvb_usb_device *d, u8 en_pll,
328 return dib0700_ctrl_wr(d, b, 10); 328 return dib0700_ctrl_wr(d, b, 10);
329} 329}
330 330
331int dib0700_set_i2c_speed(struct dvb_usb_device *d, u16 scl_kHz)
332{
333 u16 divider;
334 u8 b[8];
335
336 if (scl_kHz == 0)
337 return -EINVAL;
338
339 b[0] = REQUEST_SET_I2C_PARAM;
340 divider = (u16) (30000 / scl_kHz);
341 b[2] = (u8) (divider >> 8);
342 b[3] = (u8) (divider & 0xff);
343 divider = (u16) (72000 / scl_kHz);
344 b[4] = (u8) (divider >> 8);
345 b[5] = (u8) (divider & 0xff);
346 divider = (u16) (72000 / scl_kHz); /* clock: 72MHz */
347 b[6] = (u8) (divider >> 8);
348 b[7] = (u8) (divider & 0xff);
349
350 deb_info("setting I2C speed: %04x %04x %04x (%d kHz).",
351 (b[2] << 8) | (b[3]), (b[4] << 8) | b[5], (b[6] << 8) | b[7], scl_kHz);
352 return dib0700_ctrl_wr(d, b, 8);
353}
354
355
331int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3) 356int dib0700_ctrl_clock(struct dvb_usb_device *d, u32 clk_MHz, u8 clock_out_gp3)
332{ 357{
333 switch (clk_MHz) { 358 switch (clk_MHz) {
@@ -459,10 +484,20 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
459 484
460 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id); 485 deb_info("modifying (%d) streaming state for %d\n", onoff, adap->id);
461 486
462 if (onoff) 487 st->channel_state &= ~0x3;
463 st->channel_state |= 1 << adap->id; 488 if ((adap->stream.props.endpoint != 2)
464 else 489 && (adap->stream.props.endpoint != 3)) {
465 st->channel_state &= ~(1 << adap->id); 490 deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->stream.props.endpoint);
491 if (onoff)
492 st->channel_state |= 1 << (adap->id);
493 else
494 st->channel_state |= 1 << ~(adap->id);
495 } else {
496 if (onoff)
497 st->channel_state |= 1 << (adap->stream.props.endpoint-2);
498 else
499 st->channel_state |= 1 << (3-adap->stream.props.endpoint);
500 }
466 501
467 b[2] |= st->channel_state; 502 b[2] |= st->channel_state;
468 503
diff --git a/drivers/media/dvb/dvb-usb/dib0700_devices.c b/drivers/media/dvb/dvb-usb/dib0700_devices.c
index 193cdb77b76a..97af266d7f1d 100644
--- a/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -12,6 +12,7 @@
12#include "dib7000m.h" 12#include "dib7000m.h"
13#include "dib7000p.h" 13#include "dib7000p.h"
14#include "dib8000.h" 14#include "dib8000.h"
15#include "dib9000.h"
15#include "mt2060.h" 16#include "mt2060.h"
16#include "mt2266.h" 17#include "mt2266.h"
17#include "tuner-xc2028.h" 18#include "tuner-xc2028.h"
@@ -29,6 +30,7 @@ MODULE_PARM_DESC(force_lna_activation, "force the activation of Low-Noise-Amplif
29 30
30struct dib0700_adapter_state { 31struct dib0700_adapter_state {
31 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *); 32 int (*set_param_save) (struct dvb_frontend *, struct dvb_frontend_parameters *);
33 const struct firmware *frontend_firmware;
32}; 34};
33 35
34/* Hauppauge Nova-T 500 (aka Bristol) 36/* Hauppauge Nova-T 500 (aka Bristol)
@@ -1243,13 +1245,13 @@ static int dib807x_tuner_attach(struct dvb_usb_adapter *adap)
1243static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index, 1245static int stk80xx_pid_filter(struct dvb_usb_adapter *adapter, int index,
1244 u16 pid, int onoff) 1246 u16 pid, int onoff)
1245{ 1247{
1246 return dib8000_pid_filter(adapter->fe, index, pid, onoff); 1248 return dib8000_pid_filter(adapter->fe, index, pid, onoff);
1247} 1249}
1248 1250
1249static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter, 1251static int stk80xx_pid_filter_ctrl(struct dvb_usb_adapter *adapter,
1250 int onoff) 1252 int onoff)
1251{ 1253{
1252 return dib8000_pid_filter_ctrl(adapter->fe, onoff); 1254 return dib8000_pid_filter_ctrl(adapter->fe, onoff);
1253} 1255}
1254 1256
1255/* STK807x */ 1257/* STK807x */
@@ -1321,11 +1323,11 @@ static int stk807xpvr_frontend_attach1(struct dvb_usb_adapter *adap)
1321 1323
1322/* STK8096GP */ 1324/* STK8096GP */
1323struct dibx000_agc_config dib8090_agc_config[2] = { 1325struct dibx000_agc_config dib8090_agc_config[2] = {
1324 { 1326 {
1325 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND, 1327 BAND_UHF | BAND_VHF | BAND_LBAND | BAND_SBAND,
1326 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, 1328 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1327 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, 1329 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1328 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ 1330 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1329 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) 1331 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1330 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), 1332 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1331 1333
@@ -1362,12 +1364,12 @@ struct dibx000_agc_config dib8090_agc_config[2] = {
1362 51, 1364 51,
1363 1365
1364 0, 1366 0,
1365 }, 1367 },
1366 { 1368 {
1367 BAND_CBAND, 1369 BAND_CBAND,
1368 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, 1370 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1,
1369 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0, 1371 * P_agc_inv_pwm1=0, P_agc_inv_pwm2=0, P_agc_inh_dc_rv_est=0,
1370 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */ 1372 * P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
1371 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) 1373 (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8)
1372 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0), 1374 | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
1373 1375
@@ -1404,135 +1406,153 @@ struct dibx000_agc_config dib8090_agc_config[2] = {
1404 51, 1406 51,
1405 1407
1406 0, 1408 0,
1407 } 1409 }
1408}; 1410};
1409 1411
1410static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = { 1412static struct dibx000_bandwidth_config dib8090_pll_config_12mhz = {
1411 54000, 13500, 1413 54000, 13500,
1412 1, 18, 3, 1, 0, 1414 1, 18, 3, 1, 0,
1413 0, 0, 1, 1, 2, 1415 0, 0, 1, 1, 2,
1414 (3 << 14) | (1 << 12) | (599 << 0), 1416 (3 << 14) | (1 << 12) | (599 << 0),
1415 (0 << 25) | 0, 1417 (0 << 25) | 0,
1416 20199727, 1418 20199727,
1417 12000000, 1419 12000000,
1418}; 1420};
1419 1421
1420static int dib8090_get_adc_power(struct dvb_frontend *fe) 1422static int dib8090_get_adc_power(struct dvb_frontend *fe)
1421{ 1423{
1422 return dib8000_get_adc_power(fe, 1); 1424 return dib8000_get_adc_power(fe, 1);
1423} 1425}
1424 1426
1425static struct dib8000_config dib809x_dib8000_config = { 1427static struct dib8000_config dib809x_dib8000_config[2] = {
1426 .output_mpeg2_in_188_bytes = 1, 1428 {
1427 1429 .output_mpeg2_in_188_bytes = 1,
1428 .agc_config_count = 2, 1430
1429 .agc = dib8090_agc_config, 1431 .agc_config_count = 2,
1430 .agc_control = dib0090_dcc_freq, 1432 .agc = dib8090_agc_config,
1431 .pll = &dib8090_pll_config_12mhz, 1433 .agc_control = dib0090_dcc_freq,
1432 .tuner_is_baseband = 1, 1434 .pll = &dib8090_pll_config_12mhz,
1433 1435 .tuner_is_baseband = 1,
1434 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS, 1436
1435 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES, 1437 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1436 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS, 1438 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1437 1439 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1438 .hostbus_diversity = 1, 1440
1439 .div_cfg = 0x31, 1441 .hostbus_diversity = 1,
1440 .output_mode = OUTMODE_MPEG2_FIFO, 1442 .div_cfg = 0x31,
1441 .drives = 0x2d98, 1443 .output_mode = OUTMODE_MPEG2_FIFO,
1442 .diversity_delay = 144, 1444 .drives = 0x2d98,
1443 .refclksel = 3, 1445 .diversity_delay = 48,
1446 .refclksel = 3,
1447 }, {
1448 .output_mpeg2_in_188_bytes = 1,
1449
1450 .agc_config_count = 2,
1451 .agc = dib8090_agc_config,
1452 .agc_control = dib0090_dcc_freq,
1453 .pll = &dib8090_pll_config_12mhz,
1454 .tuner_is_baseband = 1,
1455
1456 .gpio_dir = DIB8000_GPIO_DEFAULT_DIRECTIONS,
1457 .gpio_val = DIB8000_GPIO_DEFAULT_VALUES,
1458 .gpio_pwm_pos = DIB8000_GPIO_DEFAULT_PWM_POS,
1459
1460 .hostbus_diversity = 1,
1461 .div_cfg = 0x31,
1462 .output_mode = OUTMODE_DIVERSITY,
1463 .drives = 0x2d08,
1464 .diversity_delay = 1,
1465 .refclksel = 3,
1466 }
1467};
1468
1469static struct dib0090_wbd_slope dib8090_wbd_table[] = {
1470 /* max freq ; cold slope ; cold offset ; warm slope ; warm offset ; wbd gain */
1471 { 120, 0, 500, 0, 500, 4 }, /* CBAND */
1472 { 170, 0, 450, 0, 450, 4 }, /* CBAND */
1473 { 380, 48, 373, 28, 259, 6 }, /* VHF */
1474 { 860, 34, 700, 36, 616, 6 }, /* high UHF */
1475 { 0xFFFF, 34, 700, 36, 616, 6 }, /* default */
1444}; 1476};
1445 1477
1446static struct dib0090_config dib809x_dib0090_config = { 1478static struct dib0090_config dib809x_dib0090_config = {
1447 .io.pll_bypass = 1, 1479 .io.pll_bypass = 1,
1448 .io.pll_range = 1, 1480 .io.pll_range = 1,
1449 .io.pll_prediv = 1, 1481 .io.pll_prediv = 1,
1450 .io.pll_loopdiv = 20, 1482 .io.pll_loopdiv = 20,
1451 .io.adc_clock_ratio = 8, 1483 .io.adc_clock_ratio = 8,
1452 .io.pll_int_loop_filt = 0, 1484 .io.pll_int_loop_filt = 0,
1453 .io.clock_khz = 12000, 1485 .io.clock_khz = 12000,
1454 .reset = dib80xx_tuner_reset, 1486 .reset = dib80xx_tuner_reset,
1455 .sleep = dib80xx_tuner_sleep, 1487 .sleep = dib80xx_tuner_sleep,
1456 .clkouttobamse = 1, 1488 .clkouttobamse = 1,
1457 .analog_output = 1, 1489 .analog_output = 1,
1458 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS, 1490 .i2c_address = DEFAULT_DIB0090_I2C_ADDRESS,
1459 .wbd_vhf_offset = 100, 1491 .use_pwm_agc = 1,
1460 .wbd_cband_offset = 450, 1492 .clkoutdrive = 1,
1461 .use_pwm_agc = 1, 1493 .get_adc_power = dib8090_get_adc_power,
1462 .clkoutdrive = 1, 1494 .freq_offset_khz_uhf = -63,
1463 .get_adc_power = dib8090_get_adc_power,
1464 .freq_offset_khz_uhf = 0,
1465 .freq_offset_khz_vhf = -143, 1495 .freq_offset_khz_vhf = -143,
1496 .wbd = dib8090_wbd_table,
1497 .fref_clock_ratio = 6,
1466}; 1498};
1467 1499
1468static int dib8096_set_param_override(struct dvb_frontend *fe, 1500static int dib8096_set_param_override(struct dvb_frontend *fe,
1469 struct dvb_frontend_parameters *fep) 1501 struct dvb_frontend_parameters *fep)
1470{ 1502{
1471 struct dvb_usb_adapter *adap = fe->dvb->priv; 1503 struct dvb_usb_adapter *adap = fe->dvb->priv;
1472 struct dib0700_adapter_state *state = adap->priv; 1504 struct dib0700_adapter_state *state = adap->priv;
1473 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000); 1505 u8 band = BAND_OF_FREQUENCY(fep->frequency/1000);
1474 u16 offset; 1506 u16 target;
1475 int ret = 0; 1507 int ret = 0;
1476 enum frontend_tune_state tune_state = CT_SHUTDOWN; 1508 enum frontend_tune_state tune_state = CT_SHUTDOWN;
1477 u16 ltgain, rf_gain_limit; 1509 u16 ltgain, rf_gain_limit;
1478 1510
1479 ret = state->set_param_save(fe, fep); 1511 ret = state->set_param_save(fe, fep);
1480 if (ret < 0) 1512 if (ret < 0)
1481 return ret; 1513 return ret;
1482 1514
1483 switch (band) { 1515 target = (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2;
1484 case BAND_VHF: 1516 dib8000_set_wbd_ref(fe, target);
1485 offset = 100; 1517
1486 break; 1518
1487 case BAND_UHF: 1519 if (band == BAND_CBAND) {
1488 offset = 550; 1520 deb_info("tuning in CBAND - soft-AGC startup\n");
1489 break; 1521 dib0090_set_tune_state(fe, CT_AGC_START);
1490 default: 1522 do {
1491 offset = 0; 1523 ret = dib0090_gain_control(fe);
1492 break; 1524 msleep(ret);
1493 } 1525 tune_state = dib0090_get_tune_state(fe);
1494 offset += (dib0090_get_wbd_offset(fe) * 8 * 18 / 33 + 1) / 2; 1526 if (tune_state == CT_AGC_STEP_0)
1495 dib8000_set_wbd_ref(fe, offset); 1527 dib8000_set_gpio(fe, 6, 0, 1);
1496 1528 else if (tune_state == CT_AGC_STEP_1) {
1497 1529 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1498 if (band == BAND_CBAND) { 1530 if (rf_gain_limit == 0)
1499 deb_info("tuning in CBAND - soft-AGC startup\n"); 1531 dib8000_set_gpio(fe, 6, 0, 0);
1500 /* TODO specific wbd target for dib0090 - needed for startup ? */ 1532 }
1501 dib0090_set_tune_state(fe, CT_AGC_START); 1533 } while (tune_state < CT_AGC_STOP);
1502 do { 1534 dib0090_pwm_gain_reset(fe);
1503 ret = dib0090_gain_control(fe); 1535 dib8000_pwm_agc_reset(fe);
1504 msleep(ret); 1536 dib8000_set_tune_state(fe, CT_DEMOD_START);
1505 tune_state = dib0090_get_tune_state(fe); 1537 } else {
1506 if (tune_state == CT_AGC_STEP_0) 1538 deb_info("not tuning in CBAND - standard AGC startup\n");
1507 dib8000_set_gpio(fe, 6, 0, 1); 1539 dib0090_pwm_gain_reset(fe);
1508 else if (tune_state == CT_AGC_STEP_1) { 1540 }
1509 dib0090_get_current_gain(fe, NULL, NULL, &rf_gain_limit, &ltgain);
1510 if (rf_gain_limit == 0)
1511 dib8000_set_gpio(fe, 6, 0, 0);
1512 }
1513 } while (tune_state < CT_AGC_STOP);
1514 dib0090_pwm_gain_reset(fe);
1515 dib8000_pwm_agc_reset(fe);
1516 dib8000_set_tune_state(fe, CT_DEMOD_START);
1517 } else {
1518 deb_info("not tuning in CBAND - standard AGC startup\n");
1519 dib0090_pwm_gain_reset(fe);
1520 }
1521 1541
1522 return 0; 1542 return 0;
1523} 1543}
1524 1544
1525static int dib809x_tuner_attach(struct dvb_usb_adapter *adap) 1545static int dib809x_tuner_attach(struct dvb_usb_adapter *adap)
1526{ 1546{
1527 struct dib0700_adapter_state *st = adap->priv; 1547 struct dib0700_adapter_state *st = adap->priv;
1528 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1); 1548 struct i2c_adapter *tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1529 1549
1530 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL) 1550 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1531 return -ENODEV; 1551 return -ENODEV;
1532 1552
1533 st->set_param_save = adap->fe->ops.tuner_ops.set_params; 1553 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1534 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override; 1554 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1535 return 0; 1555 return 0;
1536} 1556}
1537 1557
1538static int stk809x_frontend_attach(struct dvb_usb_adapter *adap) 1558static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
@@ -1554,11 +1574,931 @@ static int stk809x_frontend_attach(struct dvb_usb_adapter *adap)
1554 1574
1555 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80); 1575 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 1, 18, 0x80);
1556 1576
1557 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config); 1577 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1578
1579 return adap->fe == NULL ? -ENODEV : 0;
1580}
1581
1582static int nim8096md_tuner_attach(struct dvb_usb_adapter *adap)
1583{
1584 struct dib0700_adapter_state *st = adap->priv;
1585 struct i2c_adapter *tun_i2c;
1586 struct dvb_frontend *fe_slave = dib8000_get_slave_frontend(adap->fe, 1);
1587
1588 if (fe_slave) {
1589 tun_i2c = dib8000_get_i2c_master(fe_slave, DIBX000_I2C_INTERFACE_TUNER, 1);
1590 if (dvb_attach(dib0090_register, fe_slave, tun_i2c, &dib809x_dib0090_config) == NULL)
1591 return -ENODEV;
1592 fe_slave->dvb = adap->fe->dvb;
1593 fe_slave->ops.tuner_ops.set_params = dib8096_set_param_override;
1594 }
1595 tun_i2c = dib8000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_TUNER, 1);
1596 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &dib809x_dib0090_config) == NULL)
1597 return -ENODEV;
1598
1599 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
1600 adap->fe->ops.tuner_ops.set_params = dib8096_set_param_override;
1601
1602 return 0;
1603}
1604
1605static int nim8096md_frontend_attach(struct dvb_usb_adapter *adap)
1606{
1607 struct dvb_frontend *fe_slave;
1608
1609 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 0);
1610 msleep(20);
1611 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1612 msleep(1000);
1613 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1614 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1615 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1616
1617 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1618
1619 dib0700_ctrl_clock(adap->dev, 72, 1);
1620
1621 msleep(20);
1622 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1623 msleep(20);
1624 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1625
1626 dib8000_i2c_enumeration(&adap->dev->i2c_adap, 2, 18, 0x80);
1627
1628 adap->fe = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x80, &dib809x_dib8000_config[0]);
1629 if (adap->fe == NULL)
1630 return -ENODEV;
1631
1632 fe_slave = dvb_attach(dib8000_attach, &adap->dev->i2c_adap, 0x82, &dib809x_dib8000_config[1]);
1633 dib8000_set_slave_frontend(adap->fe, fe_slave);
1634
1635 return fe_slave == NULL ? -ENODEV : 0;
1636}
1637
1638/* STK9090M */
1639static int dib90x0_pid_filter(struct dvb_usb_adapter *adapter, int index, u16 pid, int onoff)
1640{
1641 return dib9000_fw_pid_filter(adapter->fe, index, pid, onoff);
1642}
1643
1644static int dib90x0_pid_filter_ctrl(struct dvb_usb_adapter *adapter, int onoff)
1645{
1646 return dib9000_fw_pid_filter_ctrl(adapter->fe, onoff);
1647}
1648
1649static int dib90x0_tuner_reset(struct dvb_frontend *fe, int onoff)
1650{
1651 return dib9000_set_gpio(fe, 5, 0, !onoff);
1652}
1653
1654static int dib90x0_tuner_sleep(struct dvb_frontend *fe, int onoff)
1655{
1656 return dib9000_set_gpio(fe, 0, 0, onoff);
1657}
1658
1659static int dib01x0_pmu_update(struct i2c_adapter *i2c, u16 *data, u8 len)
1660{
1661 u8 wb[4] = { 0xc >> 8, 0xc & 0xff, 0, 0 };
1662 u8 rb[2];
1663 struct i2c_msg msg[2] = {
1664 {.addr = 0x1e >> 1, .flags = 0, .buf = wb, .len = 2},
1665 {.addr = 0x1e >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
1666 };
1667 u8 index_data;
1668
1669 dibx000_i2c_set_speed(i2c, 250);
1670
1671 if (i2c_transfer(i2c, msg, 2) != 2)
1672 return -EIO;
1673
1674 switch (rb[0] << 8 | rb[1]) {
1675 case 0:
1676 deb_info("Found DiB0170 rev1: This version of DiB0170 is not supported any longer.\n");
1677 return -EIO;
1678 case 1:
1679 deb_info("Found DiB0170 rev2");
1680 break;
1681 case 2:
1682 deb_info("Found DiB0190 rev2");
1683 break;
1684 default:
1685 deb_info("DiB01x0 not found");
1686 return -EIO;
1687 }
1688
1689 for (index_data = 0; index_data < len; index_data += 2) {
1690 wb[2] = (data[index_data + 1] >> 8) & 0xff;
1691 wb[3] = (data[index_data + 1]) & 0xff;
1692
1693 if (data[index_data] == 0) {
1694 wb[0] = (data[index_data] >> 8) & 0xff;
1695 wb[1] = (data[index_data]) & 0xff;
1696 msg[0].len = 2;
1697 if (i2c_transfer(i2c, msg, 2) != 2)
1698 return -EIO;
1699 wb[2] |= rb[0];
1700 wb[3] |= rb[1] & ~(3 << 4);
1701 }
1702
1703 wb[0] = (data[index_data] >> 8)&0xff;
1704 wb[1] = (data[index_data])&0xff;
1705 msg[0].len = 4;
1706 if (i2c_transfer(i2c, &msg[0], 1) != 1)
1707 return -EIO;
1708 }
1709 return 0;
1710}
1711
1712static struct dib9000_config stk9090m_config = {
1713 .output_mpeg2_in_188_bytes = 1,
1714 .output_mode = OUTMODE_MPEG2_FIFO,
1715 .vcxo_timer = 279620,
1716 .timing_frequency = 20452225,
1717 .demod_clock_khz = 60000,
1718 .xtal_clock_khz = 30000,
1719 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1720 .subband = {
1721 2,
1722 {
1723 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0008 } }, /* GPIO 3 to 1 for VHF */
1724 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0008, 0x0000, 0x0000 } }, /* GPIO 3 to 0 for UHF */
1725 { 0 },
1726 },
1727 },
1728 .gpio_function = {
1729 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1730 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1731 },
1732};
1733
1734static struct dib9000_config nim9090md_config[2] = {
1735 {
1736 .output_mpeg2_in_188_bytes = 1,
1737 .output_mode = OUTMODE_MPEG2_FIFO,
1738 .vcxo_timer = 279620,
1739 .timing_frequency = 20452225,
1740 .demod_clock_khz = 60000,
1741 .xtal_clock_khz = 30000,
1742 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1743 }, {
1744 .output_mpeg2_in_188_bytes = 1,
1745 .output_mode = OUTMODE_DIVERSITY,
1746 .vcxo_timer = 279620,
1747 .timing_frequency = 20452225,
1748 .demod_clock_khz = 60000,
1749 .xtal_clock_khz = 30000,
1750 .if_drives = (0 << 15) | (1 << 13) | (0 << 12) | (3 << 10) | (0 << 9) | (1 << 7) | (0 << 6) | (0 << 4) | (1 << 3) | (1 << 1) | (0),
1751 .subband = {
1752 2,
1753 {
1754 { 240, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0006 } }, /* GPIO 1 and 2 to 1 for VHF */
1755 { 890, { BOARD_GPIO_COMPONENT_DEMOD, BOARD_GPIO_FUNCTION_SUBBAND_GPIO, 0x0006, 0x0000, 0x0000 } }, /* GPIO 1 and 2 to 0 for UHF */
1756 { 0 },
1757 },
1758 },
1759 .gpio_function = {
1760 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_ON, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = (0x10 & ~0x1) | 0x20 },
1761 { .component = BOARD_GPIO_COMPONENT_DEMOD, .function = BOARD_GPIO_FUNCTION_COMPONENT_OFF, .mask = 0x10 | 0x21, .direction = 0 & ~0x21, .value = 0 | 0x21 },
1762 },
1763 }
1764};
1765
1766static struct dib0090_config dib9090_dib0090_config = {
1767 .io.pll_bypass = 0,
1768 .io.pll_range = 1,
1769 .io.pll_prediv = 1,
1770 .io.pll_loopdiv = 8,
1771 .io.adc_clock_ratio = 8,
1772 .io.pll_int_loop_filt = 0,
1773 .io.clock_khz = 30000,
1774 .reset = dib90x0_tuner_reset,
1775 .sleep = dib90x0_tuner_sleep,
1776 .clkouttobamse = 0,
1777 .analog_output = 0,
1778 .use_pwm_agc = 0,
1779 .clkoutdrive = 0,
1780 .freq_offset_khz_uhf = 0,
1781 .freq_offset_khz_vhf = 0,
1782};
1783
1784static struct dib0090_config nim9090md_dib0090_config[2] = {
1785 {
1786 .io.pll_bypass = 0,
1787 .io.pll_range = 1,
1788 .io.pll_prediv = 1,
1789 .io.pll_loopdiv = 8,
1790 .io.adc_clock_ratio = 8,
1791 .io.pll_int_loop_filt = 0,
1792 .io.clock_khz = 30000,
1793 .reset = dib90x0_tuner_reset,
1794 .sleep = dib90x0_tuner_sleep,
1795 .clkouttobamse = 1,
1796 .analog_output = 0,
1797 .use_pwm_agc = 0,
1798 .clkoutdrive = 0,
1799 .freq_offset_khz_uhf = 0,
1800 .freq_offset_khz_vhf = 0,
1801 }, {
1802 .io.pll_bypass = 0,
1803 .io.pll_range = 1,
1804 .io.pll_prediv = 1,
1805 .io.pll_loopdiv = 8,
1806 .io.adc_clock_ratio = 8,
1807 .io.pll_int_loop_filt = 0,
1808 .io.clock_khz = 30000,
1809 .reset = dib90x0_tuner_reset,
1810 .sleep = dib90x0_tuner_sleep,
1811 .clkouttobamse = 0,
1812 .analog_output = 0,
1813 .use_pwm_agc = 0,
1814 .clkoutdrive = 0,
1815 .freq_offset_khz_uhf = 0,
1816 .freq_offset_khz_vhf = 0,
1817 }
1818};
1819
1820
1821static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap)
1822{
1823 struct dib0700_adapter_state *state = adap->priv;
1824 struct dib0700_state *st = adap->dev->priv;
1825 u32 fw_version;
1826
1827 /* Make use of the new i2c functions from FW 1.20 */
1828 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
1829 if (fw_version >= 0x10200)
1830 st->fw_use_new_i2c_api = 1;
1831 dib0700_set_i2c_speed(adap->dev, 340);
1832
1833 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1834 msleep(20);
1835 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1836 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1837 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1838 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1839
1840 dib0700_ctrl_clock(adap->dev, 72, 1);
1841
1842 msleep(20);
1843 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1844 msleep(20);
1845 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1846
1847 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80);
1848
1849 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
1850 deb_info("%s: Upload failed. (file not found?)\n", __func__);
1851 return -ENODEV;
1852 } else {
1853 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
1854 }
1855 stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size;
1856 stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data;
1857
1858 adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &stk9090m_config);
1859
1860 return adap->fe == NULL ? -ENODEV : 0;
1861}
1862
1863static int dib9090_tuner_attach(struct dvb_usb_adapter *adap)
1864{
1865 struct dib0700_adapter_state *state = adap->priv;
1866 struct i2c_adapter *i2c = dib9000_get_tuner_interface(adap->fe);
1867 u16 data_dib190[10] = {
1868 1, 0x1374,
1869 2, 0x01a2,
1870 7, 0x0020,
1871 0, 0x00ef,
1872 8, 0x0486,
1873 };
1874
1875 if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &dib9090_dib0090_config) == NULL)
1876 return -ENODEV;
1877 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
1878 if (dib01x0_pmu_update(i2c, data_dib190, 10) != 0)
1879 return -ENODEV;
1880 dib0700_set_i2c_speed(adap->dev, 2000);
1881 if (dib9000_firmware_post_pll_init(adap->fe) < 0)
1882 return -ENODEV;
1883 release_firmware(state->frontend_firmware);
1884 return 0;
1885}
1886
1887static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap)
1888{
1889 struct dib0700_adapter_state *state = adap->priv;
1890 struct dib0700_state *st = adap->dev->priv;
1891 struct i2c_adapter *i2c;
1892 struct dvb_frontend *fe_slave;
1893 u32 fw_version;
1894
1895 /* Make use of the new i2c functions from FW 1.20 */
1896 dib0700_get_version(adap->dev, NULL, NULL, &fw_version, NULL);
1897 if (fw_version >= 0x10200)
1898 st->fw_use_new_i2c_api = 1;
1899 dib0700_set_i2c_speed(adap->dev, 340);
1900
1901 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
1902 msleep(20);
1903 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
1904 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
1905 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
1906 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
1907
1908 dib0700_ctrl_clock(adap->dev, 72, 1);
1909
1910 msleep(20);
1911 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
1912 msleep(20);
1913 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
1914
1915 if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) {
1916 deb_info("%s: Upload failed. (file not found?)\n", __func__);
1917 return -EIO;
1918 } else {
1919 deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size);
1920 }
1921 nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size;
1922 nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data;
1923 nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size;
1924 nim9090md_config[1].microcode_B_fe_buffer = state->frontend_firmware->data;
1925
1926 dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, 0x80);
1927 adap->fe = dvb_attach(dib9000_attach, &adap->dev->i2c_adap, 0x80, &nim9090md_config[0]);
1928
1929 if (adap->fe == NULL)
1930 return -ENODEV;
1931
1932 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_3_4, 0);
1933 dib9000_i2c_enumeration(i2c, 1, 0x12, 0x82);
1934
1935 fe_slave = dvb_attach(dib9000_attach, i2c, 0x82, &nim9090md_config[1]);
1936 dib9000_set_slave_frontend(adap->fe, fe_slave);
1937
1938 return fe_slave == NULL ? -ENODEV : 0;
1939}
1940
1941static int nim9090md_tuner_attach(struct dvb_usb_adapter *adap)
1942{
1943 struct dib0700_adapter_state *state = adap->priv;
1944 struct i2c_adapter *i2c;
1945 struct dvb_frontend *fe_slave;
1946 u16 data_dib190[10] = {
1947 1, 0x5374,
1948 2, 0x01ae,
1949 7, 0x0020,
1950 0, 0x00ef,
1951 8, 0x0406,
1952 };
1953 i2c = dib9000_get_tuner_interface(adap->fe);
1954 if (dvb_attach(dib0090_fw_register, adap->fe, i2c, &nim9090md_dib0090_config[0]) == NULL)
1955 return -ENODEV;
1956 i2c = dib9000_get_i2c_master(adap->fe, DIBX000_I2C_INTERFACE_GPIO_1_2, 0);
1957 if (dib01x0_pmu_update(i2c, data_dib190, 10) < 0)
1958 return -ENODEV;
1959 dib0700_set_i2c_speed(adap->dev, 2000);
1960 if (dib9000_firmware_post_pll_init(adap->fe) < 0)
1961 return -ENODEV;
1962
1963 fe_slave = dib9000_get_slave_frontend(adap->fe, 1);
1964 if (fe_slave != NULL) {
1965 i2c = dib9000_get_component_bus_interface(adap->fe);
1966 dib9000_set_i2c_adapter(fe_slave, i2c);
1967
1968 i2c = dib9000_get_tuner_interface(fe_slave);
1969 if (dvb_attach(dib0090_fw_register, fe_slave, i2c, &nim9090md_dib0090_config[1]) == NULL)
1970 return -ENODEV;
1971 fe_slave->dvb = adap->fe->dvb;
1972 dib9000_fw_set_component_bus_speed(adap->fe, 2000);
1973 if (dib9000_firmware_post_pll_init(fe_slave) < 0)
1974 return -ENODEV;
1975 }
1976 release_firmware(state->frontend_firmware);
1977
1978 return 0;
1979}
1980
1981/* NIM7090 */
1982struct dib7090p_best_adc {
1983 u32 timf;
1984 u32 pll_loopdiv;
1985 u32 pll_prediv;
1986};
1987
1988static int dib7090p_get_best_sampling(struct dvb_frontend *fe , struct dib7090p_best_adc *adc)
1989{
1990 u8 spur = 0, prediv = 0, loopdiv = 0, min_prediv = 1, max_prediv = 1;
1991
1992 u16 xtal = 12000;
1993 u32 fcp_min = 1900; /* PLL Minimum Frequency comparator KHz */
1994 u32 fcp_max = 20000; /* PLL Maximum Frequency comparator KHz */
1995 u32 fdem_max = 76000;
1996 u32 fdem_min = 69500;
1997 u32 fcp = 0, fs = 0, fdem = 0;
1998 u32 harmonic_id = 0;
1999
2000 adc->pll_loopdiv = loopdiv;
2001 adc->pll_prediv = prediv;
2002 adc->timf = 0;
2003
2004 deb_info("bandwidth = %d fdem_min =%d", fe->dtv_property_cache.bandwidth_hz, fdem_min);
2005
2006 /* Find Min and Max prediv */
2007 while ((xtal/max_prediv) >= fcp_min)
2008 max_prediv++;
2009
2010 max_prediv--;
2011 min_prediv = max_prediv;
2012 while ((xtal/min_prediv) <= fcp_max) {
2013 min_prediv--;
2014 if (min_prediv == 1)
2015 break;
2016 }
2017 deb_info("MIN prediv = %d : MAX prediv = %d", min_prediv, max_prediv);
2018
2019 min_prediv = 2;
2020
2021 for (prediv = min_prediv ; prediv < max_prediv; prediv++) {
2022 fcp = xtal / prediv;
2023 if (fcp > fcp_min && fcp < fcp_max) {
2024 for (loopdiv = 1 ; loopdiv < 64 ; loopdiv++) {
2025 fdem = ((xtal/prediv) * loopdiv);
2026 fs = fdem / 4;
2027 /* test min/max system restrictions */
2028
2029 if ((fdem >= fdem_min) && (fdem <= fdem_max) && (fs >= fe->dtv_property_cache.bandwidth_hz/1000)) {
2030 spur = 0;
2031 /* test fs harmonics positions */
2032 for (harmonic_id = (fe->dtv_property_cache.frequency / (1000*fs)) ; harmonic_id <= ((fe->dtv_property_cache.frequency / (1000*fs))+1) ; harmonic_id++) {
2033 if (((fs*harmonic_id) >= ((fe->dtv_property_cache.frequency/1000) - (fe->dtv_property_cache.bandwidth_hz/2000))) && ((fs*harmonic_id) <= ((fe->dtv_property_cache.frequency/1000) + (fe->dtv_property_cache.bandwidth_hz/2000)))) {
2034 spur = 1;
2035 break;
2036 }
2037 }
2038
2039 if (!spur) {
2040 adc->pll_loopdiv = loopdiv;
2041 adc->pll_prediv = prediv;
2042 adc->timf = 2396745143UL/fdem*(1 << 9);
2043 adc->timf += ((2396745143UL%fdem) << 9)/fdem;
2044 deb_info("loopdiv=%i prediv=%i timf=%i", loopdiv, prediv, adc->timf);
2045 break;
2046 }
2047 }
2048 }
2049 }
2050 if (!spur)
2051 break;
2052 }
2053
2054
2055 if (adc->pll_loopdiv == 0 && adc->pll_prediv == 0)
2056 return -EINVAL;
2057 else
2058 return 0;
2059}
2060
2061static int dib7090_agc_startup(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
2062{
2063 struct dvb_usb_adapter *adap = fe->dvb->priv;
2064 struct dib0700_adapter_state *state = adap->priv;
2065 struct dibx000_bandwidth_config pll;
2066 u16 target;
2067 struct dib7090p_best_adc adc;
2068 int ret;
2069
2070 ret = state->set_param_save(fe, fep);
2071 if (ret < 0)
2072 return ret;
2073
2074 memset(&pll, 0, sizeof(struct dibx000_bandwidth_config));
2075 dib0090_pwm_gain_reset(fe);
2076 target = (dib0090_get_wbd_offset(fe) * 8 + 1) / 2;
2077 dib7000p_set_wbd_ref(fe, target);
2078
2079 if (dib7090p_get_best_sampling(fe, &adc) == 0) {
2080 pll.pll_ratio = adc.pll_loopdiv;
2081 pll.pll_prediv = adc.pll_prediv;
2082
2083 dib7000p_update_pll(fe, &pll);
2084 dib7000p_ctrl_timf(fe, DEMOD_TIMF_SET, adc.timf);
2085 }
2086 return 0;
2087}
2088
2089static struct dib0090_wbd_slope dib7090_wbd_table[] = {
2090 { 380, 81, 850, 64, 540, 4},
2091 { 860, 51, 866, 21, 375, 4},
2092 {1700, 0, 250, 0, 100, 6},
2093 {2600, 0, 250, 0, 100, 6},
2094 { 0xFFFF, 0, 0, 0, 0, 0},
2095};
2096
2097struct dibx000_agc_config dib7090_agc_config[2] = {
2098 {
2099 .band_caps = BAND_UHF,
2100 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2101 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2102 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2103
2104 .inv_gain = 687,
2105 .time_stabiliz = 10,
2106
2107 .alpha_level = 0,
2108 .thlock = 118,
2109
2110 .wbd_inv = 0,
2111 .wbd_ref = 1200,
2112 .wbd_sel = 3,
2113 .wbd_alpha = 5,
2114
2115 .agc1_max = 65535,
2116 .agc1_min = 0,
2117
2118 .agc2_max = 65535,
2119 .agc2_min = 0,
2120
2121 .agc1_pt1 = 0,
2122 .agc1_pt2 = 32,
2123 .agc1_pt3 = 114,
2124 .agc1_slope1 = 143,
2125 .agc1_slope2 = 144,
2126 .agc2_pt1 = 114,
2127 .agc2_pt2 = 227,
2128 .agc2_slope1 = 116,
2129 .agc2_slope2 = 117,
2130
2131 .alpha_mant = 18,
2132 .alpha_exp = 0,
2133 .beta_mant = 20,
2134 .beta_exp = 59,
2135
2136 .perform_agc_softsplit = 0,
2137 } , {
2138 .band_caps = BAND_FM | BAND_VHF | BAND_CBAND,
2139 /* P_agc_use_sd_mod1=0, P_agc_use_sd_mod2=0, P_agc_freq_pwm_div=1, P_agc_inv_pwm1=0, P_agc_inv_pwm2=0,
2140 * P_agc_inh_dc_rv_est=0, P_agc_time_est=3, P_agc_freeze=0, P_agc_nb_est=5, P_agc_write=0 */
2141 .setup = (0 << 15) | (0 << 14) | (5 << 11) | (0 << 10) | (0 << 9) | (0 << 8) | (3 << 5) | (0 << 4) | (5 << 1) | (0 << 0),
2142
2143 .inv_gain = 732,
2144 .time_stabiliz = 10,
2145
2146 .alpha_level = 0,
2147 .thlock = 118,
2148
2149 .wbd_inv = 0,
2150 .wbd_ref = 1200,
2151 .wbd_sel = 3,
2152 .wbd_alpha = 5,
2153
2154 .agc1_max = 65535,
2155 .agc1_min = 0,
2156
2157 .agc2_max = 65535,
2158 .agc2_min = 0,
2159
2160 .agc1_pt1 = 0,
2161 .agc1_pt2 = 0,
2162 .agc1_pt3 = 98,
2163 .agc1_slope1 = 0,
2164 .agc1_slope2 = 167,
2165 .agc1_pt1 = 98,
2166 .agc2_pt2 = 255,
2167 .agc2_slope1 = 104,
2168 .agc2_slope2 = 0,
2169
2170 .alpha_mant = 18,
2171 .alpha_exp = 0,
2172 .beta_mant = 20,
2173 .beta_exp = 59,
2174
2175 .perform_agc_softsplit = 0,
2176 }
2177};
2178
2179static struct dibx000_bandwidth_config dib7090_clock_config_12_mhz = {
2180 60000, 15000,
2181 1, 5, 0, 0, 0,
2182 0, 0, 1, 1, 2,
2183 (3 << 14) | (1 << 12) | (524 << 0),
2184 (0 << 25) | 0,
2185 20452225,
2186 15000000,
2187};
2188
2189static struct dib7000p_config nim7090_dib7000p_config = {
2190 .output_mpeg2_in_188_bytes = 1,
2191 .hostbus_diversity = 1,
2192 .tuner_is_baseband = 1,
2193 .update_lna = NULL,
2194
2195 .agc_config_count = 2,
2196 .agc = dib7090_agc_config,
2197
2198 .bw = &dib7090_clock_config_12_mhz,
2199
2200 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2201 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2202 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2203
2204 .pwm_freq_div = 0,
2205
2206 .agc_control = dib7090_agc_restart,
2207
2208 .spur_protect = 0,
2209 .disable_sample_and_hold = 0,
2210 .enable_current_mirror = 0,
2211 .diversity_delay = 0,
2212
2213 .output_mode = OUTMODE_MPEG2_FIFO,
2214 .enMpegOutput = 1,
2215};
2216
2217static struct dib7000p_config tfe7090pvr_dib7000p_config[2] = {
2218 {
2219 .output_mpeg2_in_188_bytes = 1,
2220 .hostbus_diversity = 1,
2221 .tuner_is_baseband = 1,
2222 .update_lna = NULL,
2223
2224 .agc_config_count = 2,
2225 .agc = dib7090_agc_config,
2226
2227 .bw = &dib7090_clock_config_12_mhz,
2228
2229 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2230 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2231 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2232
2233 .pwm_freq_div = 0,
2234
2235 .agc_control = dib7090_agc_restart,
2236
2237 .spur_protect = 0,
2238 .disable_sample_and_hold = 0,
2239 .enable_current_mirror = 0,
2240 .diversity_delay = 0,
2241
2242 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2243 .default_i2c_addr = 0x90,
2244 .enMpegOutput = 1,
2245 }, {
2246 .output_mpeg2_in_188_bytes = 1,
2247 .hostbus_diversity = 1,
2248 .tuner_is_baseband = 1,
2249 .update_lna = NULL,
2250
2251 .agc_config_count = 2,
2252 .agc = dib7090_agc_config,
2253
2254 .bw = &dib7090_clock_config_12_mhz,
2255
2256 .gpio_dir = DIB7000P_GPIO_DEFAULT_DIRECTIONS,
2257 .gpio_val = DIB7000P_GPIO_DEFAULT_VALUES,
2258 .gpio_pwm_pos = DIB7000P_GPIO_DEFAULT_PWM_POS,
2259
2260 .pwm_freq_div = 0,
2261
2262 .agc_control = dib7090_agc_restart,
2263
2264 .spur_protect = 0,
2265 .disable_sample_and_hold = 0,
2266 .enable_current_mirror = 0,
2267 .diversity_delay = 0,
2268
2269 .output_mode = OUTMODE_MPEG2_PAR_GATED_CLK,
2270 .default_i2c_addr = 0x92,
2271 .enMpegOutput = 0,
2272 }
2273};
2274
2275static const struct dib0090_config nim7090_dib0090_config = {
2276 .io.clock_khz = 12000,
2277 .io.pll_bypass = 0,
2278 .io.pll_range = 0,
2279 .io.pll_prediv = 3,
2280 .io.pll_loopdiv = 6,
2281 .io.adc_clock_ratio = 0,
2282 .io.pll_int_loop_filt = 0,
2283 .reset = dib7090_tuner_sleep,
2284 .sleep = dib7090_tuner_sleep,
2285
2286 .freq_offset_khz_uhf = 0,
2287 .freq_offset_khz_vhf = 0,
2288
2289 .get_adc_power = dib7090_get_adc_power,
2290
2291 .clkouttobamse = 1,
2292 .analog_output = 0,
2293
2294 .wbd_vhf_offset = 0,
2295 .wbd_cband_offset = 0,
2296 .use_pwm_agc = 1,
2297 .clkoutdrive = 0,
2298
2299 .fref_clock_ratio = 0,
2300
2301 .wbd = dib7090_wbd_table,
2302
2303 .ls_cfg_pad_drv = 0,
2304 .data_tx_drv = 0,
2305 .low_if = NULL,
2306 .in_soc = 1,
2307};
2308
2309static const struct dib0090_config tfe7090pvr_dib0090_config[2] = {
2310 {
2311 .io.clock_khz = 12000,
2312 .io.pll_bypass = 0,
2313 .io.pll_range = 0,
2314 .io.pll_prediv = 3,
2315 .io.pll_loopdiv = 6,
2316 .io.adc_clock_ratio = 0,
2317 .io.pll_int_loop_filt = 0,
2318 .reset = dib7090_tuner_sleep,
2319 .sleep = dib7090_tuner_sleep,
2320
2321 .freq_offset_khz_uhf = 50,
2322 .freq_offset_khz_vhf = 70,
2323
2324 .get_adc_power = dib7090_get_adc_power,
2325
2326 .clkouttobamse = 1,
2327 .analog_output = 0,
2328
2329 .wbd_vhf_offset = 0,
2330 .wbd_cband_offset = 0,
2331 .use_pwm_agc = 1,
2332 .clkoutdrive = 0,
2333
2334 .fref_clock_ratio = 0,
2335
2336 .wbd = dib7090_wbd_table,
2337
2338 .ls_cfg_pad_drv = 0,
2339 .data_tx_drv = 0,
2340 .low_if = NULL,
2341 .in_soc = 1,
2342 }, {
2343 .io.clock_khz = 12000,
2344 .io.pll_bypass = 0,
2345 .io.pll_range = 0,
2346 .io.pll_prediv = 3,
2347 .io.pll_loopdiv = 6,
2348 .io.adc_clock_ratio = 0,
2349 .io.pll_int_loop_filt = 0,
2350 .reset = dib7090_tuner_sleep,
2351 .sleep = dib7090_tuner_sleep,
2352
2353 .freq_offset_khz_uhf = -50,
2354 .freq_offset_khz_vhf = -70,
2355
2356 .get_adc_power = dib7090_get_adc_power,
2357
2358 .clkouttobamse = 1,
2359 .analog_output = 0,
2360
2361 .wbd_vhf_offset = 0,
2362 .wbd_cband_offset = 0,
2363 .use_pwm_agc = 1,
2364 .clkoutdrive = 0,
2365
2366 .fref_clock_ratio = 0,
2367
2368 .wbd = dib7090_wbd_table,
2369
2370 .ls_cfg_pad_drv = 0,
2371 .data_tx_drv = 0,
2372 .low_if = NULL,
2373 .in_soc = 1,
2374 }
2375};
2376
2377static int nim7090_frontend_attach(struct dvb_usb_adapter *adap)
2378{
2379 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2380 msleep(20);
2381 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2382 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2383 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2384 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2385
2386 msleep(20);
2387 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2388 msleep(20);
2389 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2390
2391 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, &nim7090_dib7000p_config) != 0) {
2392 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2393 return -ENODEV;
2394 }
2395 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x80, &nim7090_dib7000p_config);
1558 2396
1559 return adap->fe == NULL ? -ENODEV : 0; 2397 return adap->fe == NULL ? -ENODEV : 0;
1560} 2398}
1561 2399
2400static int nim7090_tuner_attach(struct dvb_usb_adapter *adap)
2401{
2402 struct dib0700_adapter_state *st = adap->priv;
2403 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2404
2405 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &nim7090_dib0090_config) == NULL)
2406 return -ENODEV;
2407
2408 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2409
2410 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2411 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2412 return 0;
2413}
2414
2415static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
2416{
2417 struct dib0700_state *st = adap->dev->priv;
2418
2419 /* The TFE7090 requires the dib0700 to not be in master mode */
2420 st->disable_streaming_master_mode = 1;
2421
2422 dib0700_set_gpio(adap->dev, GPIO6, GPIO_OUT, 1);
2423 msleep(20);
2424 dib0700_set_gpio(adap->dev, GPIO9, GPIO_OUT, 1);
2425 dib0700_set_gpio(adap->dev, GPIO4, GPIO_OUT, 1);
2426 dib0700_set_gpio(adap->dev, GPIO7, GPIO_OUT, 1);
2427 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 0);
2428
2429 msleep(20);
2430 dib0700_set_gpio(adap->dev, GPIO10, GPIO_OUT, 1);
2431 msleep(20);
2432 dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1);
2433
2434 /* initialize IC 0 */
2435 if (dib7000p_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x20, &tfe7090pvr_dib7000p_config[0]) != 0) {
2436 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2437 return -ENODEV;
2438 }
2439
2440 dib0700_set_i2c_speed(adap->dev, 340);
2441 adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
2442
2443 dib7090_slave_reset(adap->fe);
2444
2445 if (adap->fe == NULL)
2446 return -ENODEV;
2447
2448 return 0;
2449}
2450
2451static int tfe7090pvr_frontend1_attach(struct dvb_usb_adapter *adap)
2452{
2453 struct i2c_adapter *i2c;
2454
2455 if (adap->dev->adapter[0].fe == NULL) {
2456 err("the master dib7090 has to be initialized first");
2457 return -ENODEV; /* the master device has not been initialized */
2458 }
2459
2460 i2c = dib7000p_get_i2c_master(adap->dev->adapter[0].fe, DIBX000_I2C_INTERFACE_GPIO_6_7, 1);
2461 if (dib7000p_i2c_enumeration(i2c, 1, 0x10, &tfe7090pvr_dib7000p_config[1]) != 0) {
2462 err("%s: dib7000p_i2c_enumeration failed. Cannot continue\n", __func__);
2463 return -ENODEV;
2464 }
2465
2466 adap->fe = dvb_attach(dib7000p_attach, i2c, 0x92, &tfe7090pvr_dib7000p_config[1]);
2467 dib0700_set_i2c_speed(adap->dev, 200);
2468
2469 return adap->fe == NULL ? -ENODEV : 0;
2470}
2471
2472static int tfe7090pvr_tuner0_attach(struct dvb_usb_adapter *adap)
2473{
2474 struct dib0700_adapter_state *st = adap->priv;
2475 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2476
2477 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[0]) == NULL)
2478 return -ENODEV;
2479
2480 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2481
2482 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2483 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2484 return 0;
2485}
2486
2487static int tfe7090pvr_tuner1_attach(struct dvb_usb_adapter *adap)
2488{
2489 struct dib0700_adapter_state *st = adap->priv;
2490 struct i2c_adapter *tun_i2c = dib7090_get_i2c_tuner(adap->fe);
2491
2492 if (dvb_attach(dib0090_register, adap->fe, tun_i2c, &tfe7090pvr_dib0090_config[1]) == NULL)
2493 return -ENODEV;
2494
2495 dib7000p_set_gpio(adap->fe, 8, 0, 1);
2496
2497 st->set_param_save = adap->fe->ops.tuner_ops.set_params;
2498 adap->fe->ops.tuner_ops.set_params = dib7090_agc_startup;
2499 return 0;
2500}
2501
1562/* STK7070PD */ 2502/* STK7070PD */
1563static struct dib7000p_config stk7070pd_dib7000p_config[2] = { 2503static struct dib7000p_config stk7070pd_dib7000p_config[2] = {
1564 { 2504 {
@@ -1856,6 +2796,12 @@ struct usb_device_id dib0700_usb_id_table[] = {
1856 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) }, 2796 { USB_DEVICE(USB_VID_PINNACLE, USB_PID_PINNACLE_PCTV282E) },
1857 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) }, 2797 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_STK8096GP) },
1858 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) }, 2798 { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DIVERSITY) },
2799 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090M) },
2800/* 70 */{ USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM8096MD) },
2801 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM9090MD) },
2802 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_NIM7090) },
2803 { USB_DEVICE(USB_VID_DIBCOM, USB_PID_DIBCOM_TFE7090PVR) },
2804 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2) },
1859 { 0 } /* Terminating entry */ 2805 { 0 } /* Terminating entry */
1860}; 2806};
1861MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table); 2807MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -2465,7 +3411,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2465 }, 3411 },
2466 }, 3412 },
2467 3413
2468 .num_device_descs = 2, 3414 .num_device_descs = 3,
2469 .devices = { 3415 .devices = {
2470 { "DiBcom STK7770P reference design", 3416 { "DiBcom STK7770P reference design",
2471 { &dib0700_usb_id_table[59], NULL }, 3417 { &dib0700_usb_id_table[59], NULL },
@@ -2477,6 +3423,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2477 &dib0700_usb_id_table[60], NULL}, 3423 &dib0700_usb_id_table[60], NULL},
2478 { NULL }, 3424 { NULL },
2479 }, 3425 },
3426 { "TechniSat AirStar TeleStick 2",
3427 { &dib0700_usb_id_table[74], NULL },
3428 { NULL },
3429 },
2480 }, 3430 },
2481 3431
2482 .rc.core = { 3432 .rc.core = {
@@ -2619,6 +3569,205 @@ struct dvb_usb_device_properties dib0700_devices[] = {
2619 RC_TYPE_NEC, 3569 RC_TYPE_NEC,
2620 .change_protocol = dib0700_change_protocol, 3570 .change_protocol = dib0700_change_protocol,
2621 }, 3571 },
3572 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3573 .num_adapters = 1,
3574 .adapter = {
3575 {
3576 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3577 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3578 .pid_filter_count = 32,
3579 .pid_filter = dib90x0_pid_filter,
3580 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
3581 .frontend_attach = stk9090m_frontend_attach,
3582 .tuner_attach = dib9090_tuner_attach,
3583
3584 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3585
3586 .size_of_priv =
3587 sizeof(struct dib0700_adapter_state),
3588 },
3589 },
3590
3591 .num_device_descs = 1,
3592 .devices = {
3593 { "DiBcom STK9090M reference design",
3594 { &dib0700_usb_id_table[69], NULL },
3595 { NULL },
3596 },
3597 },
3598
3599 .rc.core = {
3600 .rc_interval = DEFAULT_RC_INTERVAL,
3601 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3602 .module_name = "dib0700",
3603 .rc_query = dib0700_rc_query_old_firmware,
3604 .allowed_protos = RC_TYPE_RC5 |
3605 RC_TYPE_RC6 |
3606 RC_TYPE_NEC,
3607 .change_protocol = dib0700_change_protocol,
3608 },
3609 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3610 .num_adapters = 1,
3611 .adapter = {
3612 {
3613 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3614 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3615 .pid_filter_count = 32,
3616 .pid_filter = stk80xx_pid_filter,
3617 .pid_filter_ctrl = stk80xx_pid_filter_ctrl,
3618 .frontend_attach = nim8096md_frontend_attach,
3619 .tuner_attach = nim8096md_tuner_attach,
3620
3621 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3622
3623 .size_of_priv =
3624 sizeof(struct dib0700_adapter_state),
3625 },
3626 },
3627
3628 .num_device_descs = 1,
3629 .devices = {
3630 { "DiBcom NIM8096MD reference design",
3631 { &dib0700_usb_id_table[70], NULL },
3632 { NULL },
3633 },
3634 },
3635
3636 .rc.core = {
3637 .rc_interval = DEFAULT_RC_INTERVAL,
3638 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3639 .module_name = "dib0700",
3640 .rc_query = dib0700_rc_query_old_firmware,
3641 .allowed_protos = RC_TYPE_RC5 |
3642 RC_TYPE_RC6 |
3643 RC_TYPE_NEC,
3644 .change_protocol = dib0700_change_protocol,
3645 },
3646 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3647 .num_adapters = 1,
3648 .adapter = {
3649 {
3650 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3651 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3652 .pid_filter_count = 32,
3653 .pid_filter = dib90x0_pid_filter,
3654 .pid_filter_ctrl = dib90x0_pid_filter_ctrl,
3655 .frontend_attach = nim9090md_frontend_attach,
3656 .tuner_attach = nim9090md_tuner_attach,
3657
3658 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3659
3660 .size_of_priv =
3661 sizeof(struct dib0700_adapter_state),
3662 },
3663 },
3664
3665 .num_device_descs = 1,
3666 .devices = {
3667 { "DiBcom NIM9090MD reference design",
3668 { &dib0700_usb_id_table[71], NULL },
3669 { NULL },
3670 },
3671 },
3672
3673 .rc.core = {
3674 .rc_interval = DEFAULT_RC_INTERVAL,
3675 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3676 .module_name = "dib0700",
3677 .rc_query = dib0700_rc_query_old_firmware,
3678 .allowed_protos = RC_TYPE_RC5 |
3679 RC_TYPE_RC6 |
3680 RC_TYPE_NEC,
3681 .change_protocol = dib0700_change_protocol,
3682 },
3683 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3684 .num_adapters = 1,
3685 .adapter = {
3686 {
3687 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3688 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3689 .pid_filter_count = 32,
3690 .pid_filter = stk70x0p_pid_filter,
3691 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3692 .frontend_attach = nim7090_frontend_attach,
3693 .tuner_attach = nim7090_tuner_attach,
3694
3695 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3696
3697 .size_of_priv =
3698 sizeof(struct dib0700_adapter_state),
3699 },
3700 },
3701
3702 .num_device_descs = 1,
3703 .devices = {
3704 { "DiBcom NIM7090 reference design",
3705 { &dib0700_usb_id_table[72], NULL },
3706 { NULL },
3707 },
3708 },
3709
3710 .rc.core = {
3711 .rc_interval = DEFAULT_RC_INTERVAL,
3712 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3713 .module_name = "dib0700",
3714 .rc_query = dib0700_rc_query_old_firmware,
3715 .allowed_protos = RC_TYPE_RC5 |
3716 RC_TYPE_RC6 |
3717 RC_TYPE_NEC,
3718 .change_protocol = dib0700_change_protocol,
3719 },
3720 }, { DIB0700_DEFAULT_DEVICE_PROPERTIES,
3721 .num_adapters = 2,
3722 .adapter = {
3723 {
3724 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3725 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3726 .pid_filter_count = 32,
3727 .pid_filter = stk70x0p_pid_filter,
3728 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3729 .frontend_attach = tfe7090pvr_frontend0_attach,
3730 .tuner_attach = tfe7090pvr_tuner0_attach,
3731
3732 DIB0700_DEFAULT_STREAMING_CONFIG(0x03),
3733
3734 .size_of_priv =
3735 sizeof(struct dib0700_adapter_state),
3736 },
3737 {
3738 .caps = DVB_USB_ADAP_HAS_PID_FILTER |
3739 DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
3740 .pid_filter_count = 32,
3741 .pid_filter = stk70x0p_pid_filter,
3742 .pid_filter_ctrl = stk70x0p_pid_filter_ctrl,
3743 .frontend_attach = tfe7090pvr_frontend1_attach,
3744 .tuner_attach = tfe7090pvr_tuner1_attach,
3745
3746 DIB0700_DEFAULT_STREAMING_CONFIG(0x02),
3747
3748 .size_of_priv =
3749 sizeof(struct dib0700_adapter_state),
3750 },
3751 },
3752
3753 .num_device_descs = 1,
3754 .devices = {
3755 { "DiBcom TFE7090PVR reference design",
3756 { &dib0700_usb_id_table[73], NULL },
3757 { NULL },
3758 },
3759 },
3760
3761 .rc.core = {
3762 .rc_interval = DEFAULT_RC_INTERVAL,
3763 .rc_codes = RC_MAP_DIB0700_RC5_TABLE,
3764 .module_name = "dib0700",
3765 .rc_query = dib0700_rc_query_old_firmware,
3766 .allowed_protos = RC_TYPE_RC5 |
3767 RC_TYPE_RC6 |
3768 RC_TYPE_NEC,
3769 .change_protocol = dib0700_change_protocol,
3770 },
2622 }, 3771 },
2623}; 3772};
2624 3773
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index f2dbce7edb3b..f6344cdd360f 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -176,7 +176,7 @@ static struct rc_map_table rc_map_digitv_table[] = {
176 { 0xaf59, KEY_AUX }, 176 { 0xaf59, KEY_AUX },
177 { 0x5f5a, KEY_DVD }, 177 { 0x5f5a, KEY_DVD },
178 { 0x6f5a, KEY_POWER }, 178 { 0x6f5a, KEY_POWER },
179 { 0x9f5a, KEY_MHP }, /* labelled 'Picture' */ 179 { 0x9f5a, KEY_CAMERA }, /* labelled 'Picture' */
180 { 0xaf5a, KEY_AUDIO }, 180 { 0xaf5a, KEY_AUDIO },
181 { 0x5f65, KEY_INFO }, 181 { 0x5f65, KEY_INFO },
182 { 0x6f65, KEY_F13 }, /* 16:9 */ 182 { 0x6f65, KEY_F13 }, /* 16:9 */
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 1a6310b61923..3a8b7446b7b0 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -106,8 +106,13 @@
106#define USB_PID_DIBCOM_STK807XP 0x1f90 106#define USB_PID_DIBCOM_STK807XP 0x1f90
107#define USB_PID_DIBCOM_STK807XPVR 0x1f98 107#define USB_PID_DIBCOM_STK807XPVR 0x1f98
108#define USB_PID_DIBCOM_STK8096GP 0x1fa0 108#define USB_PID_DIBCOM_STK8096GP 0x1fa0
109#define USB_PID_DIBCOM_NIM8096MD 0x1fa8
109#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131 110#define USB_PID_DIBCOM_ANCHOR_2135_COLD 0x2131
110#define USB_PID_DIBCOM_STK7770P 0x1e80 111#define USB_PID_DIBCOM_STK7770P 0x1e80
112#define USB_PID_DIBCOM_NIM7090 0x1bb2
113#define USB_PID_DIBCOM_TFE7090PVR 0x1bb4
114#define USB_PID_DIBCOM_NIM9090M 0x2383
115#define USB_PID_DIBCOM_NIM9090MD 0x2384
111#define USB_PID_DPOSH_M9206_COLD 0x9206 116#define USB_PID_DPOSH_M9206_COLD 0x9206
112#define USB_PID_DPOSH_M9206_WARM 0xa090 117#define USB_PID_DPOSH_M9206_WARM 0xa090
113#define USB_PID_E3C_EC168 0x1689 118#define USB_PID_E3C_EC168 0x1689
@@ -312,4 +317,6 @@
312#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac 317#define USB_PID_TERRATEC_DVBS2CI_V2 0x10ac
313#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001 318#define USB_PID_TECHNISAT_USB2_HDCI_V1 0x0001
314#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002 319#define USB_PID_TECHNISAT_USB2_HDCI_V2 0x0002
320#define USB_PID_TECHNISAT_AIRSTAR_TELESTICK_2 0x0004
321#define USB_PID_TECHNISAT_USB2_DVB_S2 0x0500
315#endif 322#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
index b2b9415d874d..41bacff24960 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-remote.c
@@ -273,7 +273,7 @@ static int rc_core_dvb_usb_remote_init(struct dvb_usb_device *d)
273 dev->map_name = d->props.rc.core.rc_codes; 273 dev->map_name = d->props.rc.core.rc_codes;
274 dev->change_protocol = d->props.rc.core.change_protocol; 274 dev->change_protocol = d->props.rc.core.change_protocol;
275 dev->allowed_protos = d->props.rc.core.allowed_protos; 275 dev->allowed_protos = d->props.rc.core.allowed_protos;
276 dev->driver_type = RC_DRIVER_SCANCODE; 276 dev->driver_type = d->props.rc.core.driver_type;
277 usb_to_input_id(d->udev, &dev->input_id); 277 usb_to_input_id(d->udev, &dev->input_id);
278 dev->input_name = "IR-receiver inside an USB DVB receiver"; 278 dev->input_name = "IR-receiver inside an USB DVB receiver";
279 dev->input_phys = d->rc_phys; 279 dev->input_phys = d->rc_phys;
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index 65fa9268e7f7..76a80968482a 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -181,6 +181,7 @@ struct dvb_rc_legacy {
181 * @rc_codes: name of rc codes table 181 * @rc_codes: name of rc codes table
182 * @protocol: type of protocol(s) currently used by the driver 182 * @protocol: type of protocol(s) currently used by the driver
183 * @allowed_protos: protocol(s) supported by the driver 183 * @allowed_protos: protocol(s) supported by the driver
184 * @driver_type: Used to point if a device supports raw mode
184 * @change_protocol: callback to change protocol 185 * @change_protocol: callback to change protocol
185 * @rc_query: called to query an event event. 186 * @rc_query: called to query an event event.
186 * @rc_interval: time in ms between two queries. 187 * @rc_interval: time in ms between two queries.
@@ -190,6 +191,7 @@ struct dvb_rc {
190 char *rc_codes; 191 char *rc_codes;
191 u64 protocol; 192 u64 protocol;
192 u64 allowed_protos; 193 u64 allowed_protos;
194 enum rc_driver_type driver_type;
193 int (*change_protocol)(struct rc_dev *dev, u64 rc_type); 195 int (*change_protocol)(struct rc_dev *dev, u64 rc_type);
194 char *module_name; 196 char *module_name;
195 int (*rc_query) (struct dvb_usb_device *d); 197 int (*rc_query) (struct dvb_usb_device *d);
diff --git a/drivers/media/dvb/dvb-usb/dw2102.c b/drivers/media/dvb/dvb-usb/dw2102.c
index 2c307ba0d28b..f5b9da18f611 100644
--- a/drivers/media/dvb/dvb-usb/dw2102.c
+++ b/drivers/media/dvb/dvb-usb/dw2102.c
@@ -1,15 +1,16 @@
1/* DVB USB framework compliant Linux driver for the 1/* DVB USB framework compliant Linux driver for the
2* DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101, 2 * DVBWorld DVB-S 2101, 2102, DVB-S2 2104, DVB-C 3101,
3* TeVii S600, S630, S650, 3 * TeVii S600, S630, S650, S660, S480,
4* Prof 1100, 7500 Cards 4 * Prof 1100, 7500,
5* Copyright (C) 2008,2009 Igor M. Liplianin (liplianin@me.by) 5 * Geniatech SU3000 Cards
6* 6 * Copyright (C) 2008-2011 Igor M. Liplianin (liplianin@me.by)
7* This program is free software; you can redistribute it and/or modify it 7 *
8* under the terms of the GNU General Public License as published by the 8 * This program is free software; you can redistribute it and/or modify it
9* Free Software Foundation, version 2. 9 * under the terms of the GNU General Public License as published by the
10* 10 * Free Software Foundation, version 2.
11* see Documentation/dvb/README.dvb-usb for more information 11 *
12*/ 12 * see Documentation/dvb/README.dvb-usb for more information
13 */
13#include "dw2102.h" 14#include "dw2102.h"
14#include "si21xx.h" 15#include "si21xx.h"
15#include "stv0299.h" 16#include "stv0299.h"
@@ -55,6 +56,14 @@
55#define USB_PID_TEVII_S660 0xd660 56#define USB_PID_TEVII_S660 0xd660
56#endif 57#endif
57 58
59#ifndef USB_PID_TEVII_S480_1
60#define USB_PID_TEVII_S480_1 0xd481
61#endif
62
63#ifndef USB_PID_TEVII_S480_2
64#define USB_PID_TEVII_S480_2 0xd482
65#endif
66
58#ifndef USB_PID_PROF_1100 67#ifndef USB_PID_PROF_1100
59#define USB_PID_PROF_1100 0xb012 68#define USB_PID_PROF_1100 0xb012
60#endif 69#endif
@@ -67,7 +76,9 @@
67#define REG_21_SYMBOLRATE_BYTE2 0x21 76#define REG_21_SYMBOLRATE_BYTE2 0x21
68/* on my own*/ 77/* on my own*/
69#define DW2102_VOLTAGE_CTRL (0x1800) 78#define DW2102_VOLTAGE_CTRL (0x1800)
79#define SU3000_STREAM_CTRL (0x1900)
70#define DW2102_RC_QUERY (0x1a00) 80#define DW2102_RC_QUERY (0x1a00)
81#define DW2102_LED_CTRL (0x1b00)
71 82
72#define err_str "did not find the firmware file. (%s) " \ 83#define err_str "did not find the firmware file. (%s) " \
73 "Please see linux/Documentation/dvb/ for more details " \ 84 "Please see linux/Documentation/dvb/ for more details " \
@@ -78,6 +89,14 @@ struct rc_map_dvb_usb_table_table {
78 int rc_keys_size; 89 int rc_keys_size;
79}; 90};
80 91
92struct su3000_state {
93 u8 initialized;
94};
95
96struct s6x0_state {
97 int (*old_set_voltage)(struct dvb_frontend *f, fe_sec_voltage_t v);
98};
99
81/* debug */ 100/* debug */
82static int dvb_usb_dw2102_debug; 101static int dvb_usb_dw2102_debug;
83module_param_named(debug, dvb_usb_dw2102_debug, int, 0644); 102module_param_named(debug, dvb_usb_dw2102_debug, int, 0644);
@@ -87,7 +106,8 @@ MODULE_PARM_DESC(debug, "set debugging level (1=info 2=xfer 4=rc(or-able))."
87/* keymaps */ 106/* keymaps */
88static int ir_keymap; 107static int ir_keymap;
89module_param_named(keymap, ir_keymap, int, 0644); 108module_param_named(keymap, ir_keymap, int, 0644);
90MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."); 109MODULE_PARM_DESC(keymap, "set keymap 0=default 1=dvbworld 2=tevii 3=tbs ..."
110 " 256=none");
91 111
92/* demod probe */ 112/* demod probe */
93static int demod_probe = 1; 113static int demod_probe = 1;
@@ -136,8 +156,7 @@ static int dw2102_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
136 /* read stv0299 register */ 156 /* read stv0299 register */
137 value = msg[0].buf[0];/* register */ 157 value = msg[0].buf[0];/* register */
138 for (i = 0; i < msg[1].len; i++) { 158 for (i = 0; i < msg[1].len; i++) {
139 value = value + i; 159 ret = dw210x_op_rw(d->udev, 0xb5, value + i, 0,
140 ret = dw210x_op_rw(d->udev, 0xb5, value, 0,
141 buf6, 2, DW210X_READ_MSG); 160 buf6, 2, DW210X_READ_MSG);
142 msg[1].buf[i] = buf6[0]; 161 msg[1].buf[i] = buf6[0];
143 } 162 }
@@ -483,10 +502,10 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
483 for (j = 0; j < num; j++) { 502 for (j = 0; j < num; j++) {
484 switch (msg[j].addr) { 503 switch (msg[j].addr) {
485 case (DW2102_RC_QUERY): { 504 case (DW2102_RC_QUERY): {
486 u8 ibuf[4]; 505 u8 ibuf[5];
487 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0, 506 ret = dw210x_op_rw(d->udev, 0xb8, 0, 0,
488 ibuf, 4, DW210X_READ_MSG); 507 ibuf, 5, DW210X_READ_MSG);
489 memcpy(msg[j].buf, ibuf + 1, 2); 508 memcpy(msg[j].buf, ibuf + 3, 2);
490 break; 509 break;
491 } 510 }
492 case (DW2102_VOLTAGE_CTRL): { 511 case (DW2102_VOLTAGE_CTRL): {
@@ -502,6 +521,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
502 obuf, 2, DW210X_WRITE_MSG); 521 obuf, 2, DW210X_WRITE_MSG);
503 break; 522 break;
504 } 523 }
524 case (DW2102_LED_CTRL): {
525 u8 obuf[2];
526
527 obuf[0] = 5;
528 obuf[1] = msg[j].buf[0];
529 ret = dw210x_op_rw(d->udev, 0x8a, 0, 0,
530 obuf, 2, DW210X_WRITE_MSG);
531 break;
532 }
505 /*case 0x55: cx24116 533 /*case 0x55: cx24116
506 case 0x6a: stv0903 534 case 0x6a: stv0903
507 case 0x68: ds3000, stv0903 535 case 0x68: ds3000, stv0903
@@ -535,14 +563,15 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
535 i += 16; 563 i += 16;
536 len -= 16; 564 len -= 16;
537 } while (len > 0); 565 } while (len > 0);
538 } else if ((udev->descriptor.idProduct == 0x7500) 566 } else if (j < (num - 1)) {
539 && (j < (num - 1))) {
540 /* write register addr before read */ 567 /* write register addr before read */
541 u8 obuf[msg[j].len + 2]; 568 u8 obuf[msg[j].len + 2];
542 obuf[0] = msg[j + 1].len; 569 obuf[0] = msg[j + 1].len;
543 obuf[1] = (msg[j].addr << 1); 570 obuf[1] = (msg[j].addr << 1);
544 memcpy(obuf + 2, msg[j].buf, msg[j].len); 571 memcpy(obuf + 2, msg[j].buf, msg[j].len);
545 ret = dw210x_op_rw(d->udev, 0x92, 0, 0, 572 ret = dw210x_op_rw(d->udev,
573 udev->descriptor.idProduct ==
574 0x7500 ? 0x92 : 0x90, 0, 0,
546 obuf, msg[j].len + 2, 575 obuf, msg[j].len + 2,
547 DW210X_WRITE_MSG); 576 DW210X_WRITE_MSG);
548 break; 577 break;
@@ -552,8 +581,7 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
552 obuf[0] = msg[j].len + 1; 581 obuf[0] = msg[j].len + 1;
553 obuf[1] = (msg[j].addr << 1); 582 obuf[1] = (msg[j].addr << 1);
554 memcpy(obuf + 2, msg[j].buf, msg[j].len); 583 memcpy(obuf + 2, msg[j].buf, msg[j].len);
555 ret = dw210x_op_rw(d->udev, 584 ret = dw210x_op_rw(d->udev, 0x80, 0, 0,
556 (num > 1 ? 0x90 : 0x80), 0, 0,
557 obuf, msg[j].len + 2, 585 obuf, msg[j].len + 2,
558 DW210X_WRITE_MSG); 586 DW210X_WRITE_MSG);
559 break; 587 break;
@@ -561,14 +589,76 @@ static int s6x0_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
561 break; 589 break;
562 } 590 }
563 } 591 }
564
565 msleep(3);
566 } 592 }
567 593
568 mutex_unlock(&d->i2c_mutex); 594 mutex_unlock(&d->i2c_mutex);
569 return num; 595 return num;
570} 596}
571 597
598static int su3000_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg msg[],
599 int num)
600{
601 struct dvb_usb_device *d = i2c_get_adapdata(adap);
602 u8 obuf[0x40], ibuf[0x40];
603
604 if (!d)
605 return -ENODEV;
606 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
607 return -EAGAIN;
608
609 switch (num) {
610 case 1:
611 switch (msg[0].addr) {
612 case SU3000_STREAM_CTRL:
613 obuf[0] = msg[0].buf[0] + 0x36;
614 obuf[1] = 3;
615 obuf[2] = 0;
616 if (dvb_usb_generic_rw(d, obuf, 3, ibuf, 0, 0) < 0)
617 err("i2c transfer failed.");
618 break;
619 case DW2102_RC_QUERY:
620 obuf[0] = 0x10;
621 if (dvb_usb_generic_rw(d, obuf, 1, ibuf, 2, 0) < 0)
622 err("i2c transfer failed.");
623 msg[0].buf[1] = ibuf[0];
624 msg[0].buf[0] = ibuf[1];
625 break;
626 default:
627 /* always i2c write*/
628 obuf[0] = 0x08;
629 obuf[1] = msg[0].addr;
630 obuf[2] = msg[0].len;
631
632 memcpy(&obuf[3], msg[0].buf, msg[0].len);
633
634 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 3,
635 ibuf, 1, 0) < 0)
636 err("i2c transfer failed.");
637
638 }
639 break;
640 case 2:
641 /* always i2c read */
642 obuf[0] = 0x09;
643 obuf[1] = msg[0].len;
644 obuf[2] = msg[1].len;
645 obuf[3] = msg[0].addr;
646 memcpy(&obuf[4], msg[0].buf, msg[0].len);
647
648 if (dvb_usb_generic_rw(d, obuf, msg[0].len + 4,
649 ibuf, msg[1].len + 1, 0) < 0)
650 err("i2c transfer failed.");
651
652 memcpy(msg[1].buf, &ibuf[1], msg[1].len);
653 break;
654 default:
655 warn("more than 2 i2c messages at a time is not handled yet.");
656 break;
657 }
658 mutex_unlock(&d->i2c_mutex);
659 return num;
660}
661
572static u32 dw210x_i2c_func(struct i2c_adapter *adapter) 662static u32 dw210x_i2c_func(struct i2c_adapter *adapter)
573{ 663{
574 return I2C_FUNC_I2C; 664 return I2C_FUNC_I2C;
@@ -604,6 +694,11 @@ static struct i2c_algorithm s6x0_i2c_algo = {
604 .functionality = dw210x_i2c_func, 694 .functionality = dw210x_i2c_func,
605}; 695};
606 696
697static struct i2c_algorithm su3000_i2c_algo = {
698 .master_xfer = su3000_i2c_transfer,
699 .functionality = dw210x_i2c_func,
700};
701
607static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6]) 702static int dw210x_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
608{ 703{
609 int i; 704 int i;
@@ -668,6 +763,82 @@ static int s6x0_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
668 return 0; 763 return 0;
669}; 764};
670 765
766static int su3000_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
767{
768 static u8 command_start[] = {0x00};
769 static u8 command_stop[] = {0x01};
770 struct i2c_msg msg = {
771 .addr = SU3000_STREAM_CTRL,
772 .flags = 0,
773 .buf = onoff ? command_start : command_stop,
774 .len = 1
775 };
776
777 i2c_transfer(&adap->dev->i2c_adap, &msg, 1);
778
779 return 0;
780}
781
782static int su3000_power_ctrl(struct dvb_usb_device *d, int i)
783{
784 struct su3000_state *state = (struct su3000_state *)d->priv;
785 u8 obuf[] = {0xde, 0};
786
787 info("%s: %d, initialized %d\n", __func__, i, state->initialized);
788
789 if (i && !state->initialized) {
790 state->initialized = 1;
791 /* reset board */
792 dvb_usb_generic_rw(d, obuf, 2, NULL, 0, 0);
793 }
794
795 return 0;
796}
797
798static int su3000_read_mac_address(struct dvb_usb_device *d, u8 mac[6])
799{
800 int i;
801 u8 obuf[] = { 0x1f, 0xf0 };
802 u8 ibuf[] = { 0 };
803 struct i2c_msg msg[] = {
804 {
805 .addr = 0x51,
806 .flags = 0,
807 .buf = obuf,
808 .len = 2,
809 }, {
810 .addr = 0x51,
811 .flags = I2C_M_RD,
812 .buf = ibuf,
813 .len = 1,
814
815 }
816 };
817
818 for (i = 0; i < 6; i++) {
819 obuf[1] = 0xf0 + i;
820 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
821 break;
822 else
823 mac[i] = ibuf[0];
824
825 debug_dump(mac, 6, printk);
826 }
827
828 return 0;
829}
830
831static int su3000_identify_state(struct usb_device *udev,
832 struct dvb_usb_device_properties *props,
833 struct dvb_usb_device_description **desc,
834 int *cold)
835{
836 info("%s\n", __func__);
837
838 *cold = 0;
839 return 0;
840}
841
671static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 842static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
672{ 843{
673 static u8 command_13v[] = {0x00, 0x01}; 844 static u8 command_13v[] = {0x00, 0x01};
@@ -692,6 +863,37 @@ static int dw210x_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
692 return 0; 863 return 0;
693} 864}
694 865
866static int s660_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
867{
868 struct dvb_usb_adapter *d =
869 (struct dvb_usb_adapter *)(fe->dvb->priv);
870 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
871
872 dw210x_set_voltage(fe, voltage);
873 if (st->old_set_voltage)
874 st->old_set_voltage(fe, voltage);
875
876 return 0;
877}
878
879static void dw210x_led_ctrl(struct dvb_frontend *fe, int offon)
880{
881 static u8 led_off[] = { 0 };
882 static u8 led_on[] = { 1 };
883 struct i2c_msg msg = {
884 .addr = DW2102_LED_CTRL,
885 .flags = 0,
886 .buf = led_off,
887 .len = 1
888 };
889 struct dvb_usb_adapter *udev_adap =
890 (struct dvb_usb_adapter *)(fe->dvb->priv);
891
892 if (offon)
893 msg.buf = led_on;
894 i2c_transfer(&udev_adap->dev->i2c_adap, &msg, 1);
895}
896
695static struct stv0299_config sharp_z0194a_config = { 897static struct stv0299_config sharp_z0194a_config = {
696 .demod_address = 0x68, 898 .demod_address = 0x68,
697 .inittab = sharp_z0194a_inittab, 899 .inittab = sharp_z0194a_inittab,
@@ -771,6 +973,12 @@ static struct stv0900_config prof_7500_stv0900_config = {
771 .tun1_adc = 0,/* 2 Vpp */ 973 .tun1_adc = 0,/* 2 Vpp */
772 .path1_mode = 3, 974 .path1_mode = 3,
773 .tun1_type = 3, 975 .tun1_type = 3,
976 .set_lock_led = dw210x_led_ctrl,
977};
978
979static struct ds3000_config su3000_ds3000_config = {
980 .demod_address = 0x68,
981 .ci_mode = 1,
774}; 982};
775 983
776static int dw2104_frontend_attach(struct dvb_usb_adapter *d) 984static int dw2104_frontend_attach(struct dvb_usb_adapter *d)
@@ -885,7 +1093,7 @@ static int dw3101_frontend_attach(struct dvb_usb_adapter *d)
885 return -EIO; 1093 return -EIO;
886} 1094}
887 1095
888static int s6x0_frontend_attach(struct dvb_usb_adapter *d) 1096static int zl100313_frontend_attach(struct dvb_usb_adapter *d)
889{ 1097{
890 d->fe = dvb_attach(mt312_attach, &zl313_config, 1098 d->fe = dvb_attach(mt312_attach, &zl313_config,
891 &d->dev->i2c_adap); 1099 &d->dev->i2c_adap);
@@ -898,41 +1106,108 @@ static int s6x0_frontend_attach(struct dvb_usb_adapter *d)
898 } 1106 }
899 } 1107 }
900 1108
1109 return -EIO;
1110}
1111
1112static int stv0288_frontend_attach(struct dvb_usb_adapter *d)
1113{
1114 u8 obuf[] = {7, 1};
1115
901 d->fe = dvb_attach(stv0288_attach, &earda_config, 1116 d->fe = dvb_attach(stv0288_attach, &earda_config,
902 &d->dev->i2c_adap); 1117 &d->dev->i2c_adap);
903 if (d->fe != NULL) { 1118
904 if (dvb_attach(stb6000_attach, d->fe, 0x61, 1119 if (d->fe == NULL)
905 &d->dev->i2c_adap)) { 1120 return -EIO;
906 d->fe->ops.set_voltage = dw210x_set_voltage; 1121
907 info("Attached stv0288+stb6000!\n"); 1122 if (NULL == dvb_attach(stb6000_attach, d->fe, 0x61, &d->dev->i2c_adap))
908 return 0; 1123 return -EIO;
909 } 1124
910 } 1125 d->fe->ops.set_voltage = dw210x_set_voltage;
1126
1127 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1128
1129 info("Attached stv0288+stb6000!\n");
1130
1131 return 0;
1132
1133}
1134
1135static int ds3000_frontend_attach(struct dvb_usb_adapter *d)
1136{
1137 struct s6x0_state *st = (struct s6x0_state *)d->dev->priv;
1138 u8 obuf[] = {7, 1};
911 1139
912 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config, 1140 d->fe = dvb_attach(ds3000_attach, &dw2104_ds3000_config,
913 &d->dev->i2c_adap); 1141 &d->dev->i2c_adap);
914 if (d->fe != NULL) {
915 d->fe->ops.set_voltage = dw210x_set_voltage;
916 info("Attached ds3000+ds2020!\n");
917 return 0;
918 }
919 1142
920 return -EIO; 1143 if (d->fe == NULL)
1144 return -EIO;
1145
1146 st->old_set_voltage = d->fe->ops.set_voltage;
1147 d->fe->ops.set_voltage = s660_set_voltage;
1148
1149 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1150
1151 info("Attached ds3000+ds2020!\n");
1152
1153 return 0;
921} 1154}
922 1155
923static int prof_7500_frontend_attach(struct dvb_usb_adapter *d) 1156static int prof_7500_frontend_attach(struct dvb_usb_adapter *d)
924{ 1157{
1158 u8 obuf[] = {7, 1};
1159
925 d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config, 1160 d->fe = dvb_attach(stv0900_attach, &prof_7500_stv0900_config,
926 &d->dev->i2c_adap, 0); 1161 &d->dev->i2c_adap, 0);
927 if (d->fe == NULL) 1162 if (d->fe == NULL)
928 return -EIO; 1163 return -EIO;
1164
929 d->fe->ops.set_voltage = dw210x_set_voltage; 1165 d->fe->ops.set_voltage = dw210x_set_voltage;
930 1166
1167 dw210x_op_rw(d->dev->udev, 0x8a, 0, 0, obuf, 2, DW210X_WRITE_MSG);
1168
931 info("Attached STV0900+STB6100A!\n"); 1169 info("Attached STV0900+STB6100A!\n");
932 1170
933 return 0; 1171 return 0;
934} 1172}
935 1173
1174static int su3000_frontend_attach(struct dvb_usb_adapter *d)
1175{
1176 u8 obuf[3] = { 0xe, 0x80, 0 };
1177 u8 ibuf[] = { 0 };
1178
1179 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1180 err("command 0x0e transfer failed.");
1181
1182 obuf[0] = 0xe;
1183 obuf[1] = 0x83;
1184 obuf[2] = 0;
1185
1186 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1187 err("command 0x0e transfer failed.");
1188
1189 obuf[0] = 0xe;
1190 obuf[1] = 0x83;
1191 obuf[2] = 1;
1192
1193 if (dvb_usb_generic_rw(d->dev, obuf, 3, ibuf, 1, 0) < 0)
1194 err("command 0x0e transfer failed.");
1195
1196 obuf[0] = 0x51;
1197
1198 if (dvb_usb_generic_rw(d->dev, obuf, 1, ibuf, 1, 0) < 0)
1199 err("command 0x51 transfer failed.");
1200
1201 d->fe = dvb_attach(ds3000_attach, &su3000_ds3000_config,
1202 &d->dev->i2c_adap);
1203 if (d->fe == NULL)
1204 return -EIO;
1205
1206 info("Attached DS3000!\n");
1207
1208 return 0;
1209}
1210
936static int dw2102_tuner_attach(struct dvb_usb_adapter *adap) 1211static int dw2102_tuner_attach(struct dvb_usb_adapter *adap)
937{ 1212{
938 dvb_attach(dvb_pll_attach, adap->fe, 0x60, 1213 dvb_attach(dvb_pll_attach, adap->fe, 0x60,
@@ -949,8 +1224,8 @@ static int dw3101_tuner_attach(struct dvb_usb_adapter *adap)
949} 1224}
950 1225
951static struct rc_map_table rc_map_dw210x_table[] = { 1226static struct rc_map_table rc_map_dw210x_table[] = {
952 { 0xf80a, KEY_Q }, /*power*/ 1227 { 0xf80a, KEY_POWER2 }, /*power*/
953 { 0xf80c, KEY_M }, /*mute*/ 1228 { 0xf80c, KEY_MUTE }, /*mute*/
954 { 0xf811, KEY_1 }, 1229 { 0xf811, KEY_1 },
955 { 0xf812, KEY_2 }, 1230 { 0xf812, KEY_2 },
956 { 0xf813, KEY_3 }, 1231 { 0xf813, KEY_3 },
@@ -961,25 +1236,25 @@ static struct rc_map_table rc_map_dw210x_table[] = {
961 { 0xf818, KEY_8 }, 1236 { 0xf818, KEY_8 },
962 { 0xf819, KEY_9 }, 1237 { 0xf819, KEY_9 },
963 { 0xf810, KEY_0 }, 1238 { 0xf810, KEY_0 },
964 { 0xf81c, KEY_PAGEUP }, /*ch+*/ 1239 { 0xf81c, KEY_CHANNELUP }, /*ch+*/
965 { 0xf80f, KEY_PAGEDOWN }, /*ch-*/ 1240 { 0xf80f, KEY_CHANNELDOWN }, /*ch-*/
966 { 0xf81a, KEY_O }, /*vol+*/ 1241 { 0xf81a, KEY_VOLUMEUP }, /*vol+*/
967 { 0xf80e, KEY_Z }, /*vol-*/ 1242 { 0xf80e, KEY_VOLUMEDOWN }, /*vol-*/
968 { 0xf804, KEY_R }, /*rec*/ 1243 { 0xf804, KEY_RECORD }, /*rec*/
969 { 0xf809, KEY_D }, /*fav*/ 1244 { 0xf809, KEY_FAVORITES }, /*fav*/
970 { 0xf808, KEY_BACKSPACE }, /*rewind*/ 1245 { 0xf808, KEY_REWIND }, /*rewind*/
971 { 0xf807, KEY_A }, /*fast*/ 1246 { 0xf807, KEY_FASTFORWARD }, /*fast*/
972 { 0xf80b, KEY_P }, /*pause*/ 1247 { 0xf80b, KEY_PAUSE }, /*pause*/
973 { 0xf802, KEY_ESC }, /*cancel*/ 1248 { 0xf802, KEY_ESC }, /*cancel*/
974 { 0xf803, KEY_G }, /*tab*/ 1249 { 0xf803, KEY_TAB }, /*tab*/
975 { 0xf800, KEY_UP }, /*up*/ 1250 { 0xf800, KEY_UP }, /*up*/
976 { 0xf81f, KEY_ENTER }, /*ok*/ 1251 { 0xf81f, KEY_OK }, /*ok*/
977 { 0xf801, KEY_DOWN }, /*down*/ 1252 { 0xf801, KEY_DOWN }, /*down*/
978 { 0xf805, KEY_C }, /*cap*/ 1253 { 0xf805, KEY_CAMERA }, /*cap*/
979 { 0xf806, KEY_S }, /*stop*/ 1254 { 0xf806, KEY_STOP }, /*stop*/
980 { 0xf840, KEY_F }, /*full*/ 1255 { 0xf840, KEY_ZOOM }, /*full*/
981 { 0xf81e, KEY_W }, /*tvmode*/ 1256 { 0xf81e, KEY_TV }, /*tvmode*/
982 { 0xf81b, KEY_B }, /*recall*/ 1257 { 0xf81b, KEY_LAST }, /*recall*/
983}; 1258};
984 1259
985static struct rc_map_table rc_map_tevii_table[] = { 1260static struct rc_map_table rc_map_tevii_table[] = {
@@ -1067,10 +1342,49 @@ static struct rc_map_table rc_map_tbs_table[] = {
1067 { 0xf89b, KEY_MODE } 1342 { 0xf89b, KEY_MODE }
1068}; 1343};
1069 1344
1345static struct rc_map_table rc_map_su3000_table[] = {
1346 { 0x25, KEY_POWER }, /* right-bottom Red */
1347 { 0x0a, KEY_MUTE }, /* -/-- */
1348 { 0x01, KEY_1 },
1349 { 0x02, KEY_2 },
1350 { 0x03, KEY_3 },
1351 { 0x04, KEY_4 },
1352 { 0x05, KEY_5 },
1353 { 0x06, KEY_6 },
1354 { 0x07, KEY_7 },
1355 { 0x08, KEY_8 },
1356 { 0x09, KEY_9 },
1357 { 0x00, KEY_0 },
1358 { 0x20, KEY_UP }, /* CH+ */
1359 { 0x21, KEY_DOWN }, /* CH+ */
1360 { 0x12, KEY_VOLUMEUP }, /* Brightness Up */
1361 { 0x13, KEY_VOLUMEDOWN },/* Brightness Down */
1362 { 0x1f, KEY_RECORD },
1363 { 0x17, KEY_PLAY },
1364 { 0x16, KEY_PAUSE },
1365 { 0x0b, KEY_STOP },
1366 { 0x27, KEY_FASTFORWARD },/* >> */
1367 { 0x26, KEY_REWIND }, /* << */
1368 { 0x0d, KEY_OK }, /* Mute */
1369 { 0x11, KEY_LEFT }, /* VOL- */
1370 { 0x10, KEY_RIGHT }, /* VOL+ */
1371 { 0x29, KEY_BACK }, /* button under 9 */
1372 { 0x2c, KEY_MENU }, /* TTX */
1373 { 0x2b, KEY_EPG }, /* EPG */
1374 { 0x1e, KEY_RED }, /* OSD */
1375 { 0x0e, KEY_GREEN }, /* Window */
1376 { 0x2d, KEY_YELLOW }, /* button under << */
1377 { 0x0f, KEY_BLUE }, /* bottom yellow button */
1378 { 0x14, KEY_AUDIO }, /* Snapshot */
1379 { 0x38, KEY_TV }, /* TV/Radio */
1380 { 0x0c, KEY_ESC } /* upper Red buttton */
1381};
1382
1070static struct rc_map_dvb_usb_table_table keys_tables[] = { 1383static struct rc_map_dvb_usb_table_table keys_tables[] = {
1071 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) }, 1384 { rc_map_dw210x_table, ARRAY_SIZE(rc_map_dw210x_table) },
1072 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) }, 1385 { rc_map_tevii_table, ARRAY_SIZE(rc_map_tevii_table) },
1073 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) }, 1386 { rc_map_tbs_table, ARRAY_SIZE(rc_map_tbs_table) },
1387 { rc_map_su3000_table, ARRAY_SIZE(rc_map_su3000_table) },
1074}; 1388};
1075 1389
1076static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state) 1390static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
@@ -1089,7 +1403,8 @@ static int dw2102_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
1089 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) { 1403 if ((ir_keymap > 0) && (ir_keymap <= ARRAY_SIZE(keys_tables))) {
1090 keymap = keys_tables[ir_keymap - 1].rc_keys ; 1404 keymap = keys_tables[ir_keymap - 1].rc_keys ;
1091 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size; 1405 keymap_size = keys_tables[ir_keymap - 1].rc_keys_size;
1092 } 1406 } else if (ir_keymap > ARRAY_SIZE(keys_tables))
1407 return 0; /* none */
1093 1408
1094 *state = REMOTE_NO_KEY_PRESSED; 1409 *state = REMOTE_NO_KEY_PRESSED;
1095 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) { 1410 if (d->props.i2c_algo->master_xfer(&d->i2c_adap, &msg, 1) == 1) {
@@ -1125,6 +1440,11 @@ static struct usb_device_id dw2102_table[] = {
1125 {USB_DEVICE(0x3011, USB_PID_PROF_1100)}, 1440 {USB_DEVICE(0x3011, USB_PID_PROF_1100)},
1126 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)}, 1441 {USB_DEVICE(0x9022, USB_PID_TEVII_S660)},
1127 {USB_DEVICE(0x3034, 0x7500)}, 1442 {USB_DEVICE(0x3034, 0x7500)},
1443 {USB_DEVICE(0x1f4d, 0x3000)},
1444 {USB_DEVICE(USB_VID_TERRATEC, 0x00a8)},
1445 {USB_DEVICE(0x9022, USB_PID_TEVII_S480_1)},
1446 {USB_DEVICE(0x9022, USB_PID_TEVII_S480_2)},
1447 {USB_DEVICE(0x1f4d, 0x3100)},
1128 { } 1448 { }
1129}; 1449};
1130 1450
@@ -1184,11 +1504,6 @@ static int dw2102_load_firmware(struct usb_device *dev,
1184 } 1504 }
1185 /* init registers */ 1505 /* init registers */
1186 switch (dev->descriptor.idProduct) { 1506 switch (dev->descriptor.idProduct) {
1187 case USB_PID_PROF_1100:
1188 s6x0_properties.rc.legacy.rc_map_table = rc_map_tbs_table;
1189 s6x0_properties.rc.legacy.rc_map_size =
1190 ARRAY_SIZE(rc_map_tbs_table);
1191 break;
1192 case USB_PID_TEVII_S650: 1507 case USB_PID_TEVII_S650:
1193 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table; 1508 dw2104_properties.rc.legacy.rc_map_table = rc_map_tevii_table;
1194 dw2104_properties.rc.legacy.rc_map_size = 1509 dw2104_properties.rc.legacy.rc_map_size =
@@ -1271,8 +1586,6 @@ static struct dvb_usb_device_properties dw2102_properties = {
1271 .adapter = { 1586 .adapter = {
1272 { 1587 {
1273 .frontend_attach = dw2102_frontend_attach, 1588 .frontend_attach = dw2102_frontend_attach,
1274 .streaming_ctrl = NULL,
1275 .tuner_attach = NULL,
1276 .stream = { 1589 .stream = {
1277 .type = USB_BULK, 1590 .type = USB_BULK,
1278 .count = 8, 1591 .count = 8,
@@ -1324,8 +1637,6 @@ static struct dvb_usb_device_properties dw2104_properties = {
1324 .adapter = { 1637 .adapter = {
1325 { 1638 {
1326 .frontend_attach = dw2104_frontend_attach, 1639 .frontend_attach = dw2104_frontend_attach,
1327 .streaming_ctrl = NULL,
1328 /*.tuner_attach = dw2104_tuner_attach,*/
1329 .stream = { 1640 .stream = {
1330 .type = USB_BULK, 1641 .type = USB_BULK,
1331 .count = 8, 1642 .count = 8,
@@ -1373,7 +1684,6 @@ static struct dvb_usb_device_properties dw3101_properties = {
1373 .adapter = { 1684 .adapter = {
1374 { 1685 {
1375 .frontend_attach = dw3101_frontend_attach, 1686 .frontend_attach = dw3101_frontend_attach,
1376 .streaming_ctrl = NULL,
1377 .tuner_attach = dw3101_tuner_attach, 1687 .tuner_attach = dw3101_tuner_attach,
1378 .stream = { 1688 .stream = {
1379 .type = USB_BULK, 1689 .type = USB_BULK,
@@ -1399,6 +1709,7 @@ static struct dvb_usb_device_properties dw3101_properties = {
1399static struct dvb_usb_device_properties s6x0_properties = { 1709static struct dvb_usb_device_properties s6x0_properties = {
1400 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1710 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1401 .usb_ctrl = DEVICE_SPECIFIC, 1711 .usb_ctrl = DEVICE_SPECIFIC,
1712 .size_of_priv = sizeof(struct s6x0_state),
1402 .firmware = "dvb-usb-s630.fw", 1713 .firmware = "dvb-usb-s630.fw",
1403 .no_reconnect = 1, 1714 .no_reconnect = 1,
1404 1715
@@ -1416,9 +1727,7 @@ static struct dvb_usb_device_properties s6x0_properties = {
1416 .read_mac_address = s6x0_read_mac_address, 1727 .read_mac_address = s6x0_read_mac_address,
1417 .adapter = { 1728 .adapter = {
1418 { 1729 {
1419 .frontend_attach = s6x0_frontend_attach, 1730 .frontend_attach = zl100313_frontend_attach,
1420 .streaming_ctrl = NULL,
1421 .tuner_attach = NULL,
1422 .stream = { 1731 .stream = {
1423 .type = USB_BULK, 1732 .type = USB_BULK,
1424 .count = 8, 1733 .count = 8,
@@ -1431,23 +1740,41 @@ static struct dvb_usb_device_properties s6x0_properties = {
1431 }, 1740 },
1432 } 1741 }
1433 }, 1742 },
1434 .num_device_descs = 3, 1743 .num_device_descs = 1,
1435 .devices = { 1744 .devices = {
1436 {"TeVii S630 USB", 1745 {"TeVii S630 USB",
1437 {&dw2102_table[6], NULL}, 1746 {&dw2102_table[6], NULL},
1438 {NULL}, 1747 {NULL},
1439 }, 1748 },
1440 {"Prof 1100 USB ",
1441 {&dw2102_table[7], NULL},
1442 {NULL},
1443 },
1444 {"TeVii S660 USB",
1445 {&dw2102_table[8], NULL},
1446 {NULL},
1447 },
1448 } 1749 }
1449}; 1750};
1450 1751
1752struct dvb_usb_device_properties *p1100;
1753static struct dvb_usb_device_description d1100 = {
1754 "Prof 1100 USB ",
1755 {&dw2102_table[7], NULL},
1756 {NULL},
1757};
1758
1759struct dvb_usb_device_properties *s660;
1760static struct dvb_usb_device_description d660 = {
1761 "TeVii S660 USB",
1762 {&dw2102_table[8], NULL},
1763 {NULL},
1764};
1765
1766static struct dvb_usb_device_description d480_1 = {
1767 "TeVii S480.1 USB",
1768 {&dw2102_table[12], NULL},
1769 {NULL},
1770};
1771
1772static struct dvb_usb_device_description d480_2 = {
1773 "TeVii S480.2 USB",
1774 {&dw2102_table[13], NULL},
1775 {NULL},
1776};
1777
1451struct dvb_usb_device_properties *p7500; 1778struct dvb_usb_device_properties *p7500;
1452static struct dvb_usb_device_description d7500 = { 1779static struct dvb_usb_device_description d7500 = {
1453 "Prof 7500 USB DVB-S2", 1780 "Prof 7500 USB DVB-S2",
@@ -1455,17 +1782,97 @@ static struct dvb_usb_device_description d7500 = {
1455 {NULL}, 1782 {NULL},
1456}; 1783};
1457 1784
1785static struct dvb_usb_device_properties su3000_properties = {
1786 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1787 .usb_ctrl = DEVICE_SPECIFIC,
1788 .size_of_priv = sizeof(struct su3000_state),
1789 .power_ctrl = su3000_power_ctrl,
1790 .num_adapters = 1,
1791 .identify_state = su3000_identify_state,
1792 .i2c_algo = &su3000_i2c_algo,
1793
1794 .rc.legacy = {
1795 .rc_map_table = rc_map_su3000_table,
1796 .rc_map_size = ARRAY_SIZE(rc_map_su3000_table),
1797 .rc_interval = 150,
1798 .rc_query = dw2102_rc_query,
1799 },
1800
1801 .read_mac_address = su3000_read_mac_address,
1802
1803 .generic_bulk_ctrl_endpoint = 0x01,
1804
1805 .adapter = {
1806 {
1807 .streaming_ctrl = su3000_streaming_ctrl,
1808 .frontend_attach = su3000_frontend_attach,
1809 .stream = {
1810 .type = USB_BULK,
1811 .count = 8,
1812 .endpoint = 0x82,
1813 .u = {
1814 .bulk = {
1815 .buffersize = 4096,
1816 }
1817 }
1818 }
1819 }
1820 },
1821 .num_device_descs = 3,
1822 .devices = {
1823 { "SU3000HD DVB-S USB2.0",
1824 { &dw2102_table[10], NULL },
1825 { NULL },
1826 },
1827 { "Terratec Cinergy S2 USB HD",
1828 { &dw2102_table[11], NULL },
1829 { NULL },
1830 },
1831 { "X3M TV SPC1400HD PCI",
1832 { &dw2102_table[14], NULL },
1833 { NULL },
1834 },
1835 }
1836};
1837
1458static int dw2102_probe(struct usb_interface *intf, 1838static int dw2102_probe(struct usb_interface *intf,
1459 const struct usb_device_id *id) 1839 const struct usb_device_id *id)
1460{ 1840{
1841 p1100 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1842 if (!p1100)
1843 return -ENOMEM;
1844 /* copy default structure */
1845 memcpy(p1100, &s6x0_properties,
1846 sizeof(struct dvb_usb_device_properties));
1847 /* fill only different fields */
1848 p1100->firmware = "dvb-usb-p1100.fw";
1849 p1100->devices[0] = d1100;
1850 p1100->rc.legacy.rc_map_table = rc_map_tbs_table;
1851 p1100->rc.legacy.rc_map_size = ARRAY_SIZE(rc_map_tbs_table);
1852 p1100->adapter->frontend_attach = stv0288_frontend_attach;
1853
1854 s660 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1855 if (!s660) {
1856 kfree(p1100);
1857 return -ENOMEM;
1858 }
1859 memcpy(s660, &s6x0_properties,
1860 sizeof(struct dvb_usb_device_properties));
1861 s660->firmware = "dvb-usb-s660.fw";
1862 s660->num_device_descs = 3;
1863 s660->devices[0] = d660;
1864 s660->devices[1] = d480_1;
1865 s660->devices[2] = d480_2;
1866 s660->adapter->frontend_attach = ds3000_frontend_attach;
1461 1867
1462 p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL); 1868 p7500 = kzalloc(sizeof(struct dvb_usb_device_properties), GFP_KERNEL);
1463 if (!p7500) 1869 if (!p7500) {
1870 kfree(p1100);
1871 kfree(s660);
1464 return -ENOMEM; 1872 return -ENOMEM;
1465 /* copy default structure */ 1873 }
1466 memcpy(p7500, &s6x0_properties, 1874 memcpy(p7500, &s6x0_properties,
1467 sizeof(struct dvb_usb_device_properties)); 1875 sizeof(struct dvb_usb_device_properties));
1468 /* fill only different fields */
1469 p7500->firmware = "dvb-usb-p7500.fw"; 1876 p7500->firmware = "dvb-usb-p7500.fw";
1470 p7500->devices[0] = d7500; 1877 p7500->devices[0] = d7500;
1471 p7500->rc.legacy.rc_map_table = rc_map_tbs_table; 1878 p7500->rc.legacy.rc_map_table = rc_map_tbs_table;
@@ -1480,8 +1887,14 @@ static int dw2102_probe(struct usb_interface *intf,
1480 THIS_MODULE, NULL, adapter_nr) || 1887 THIS_MODULE, NULL, adapter_nr) ||
1481 0 == dvb_usb_device_init(intf, &s6x0_properties, 1888 0 == dvb_usb_device_init(intf, &s6x0_properties,
1482 THIS_MODULE, NULL, adapter_nr) || 1889 THIS_MODULE, NULL, adapter_nr) ||
1890 0 == dvb_usb_device_init(intf, p1100,
1891 THIS_MODULE, NULL, adapter_nr) ||
1892 0 == dvb_usb_device_init(intf, s660,
1893 THIS_MODULE, NULL, adapter_nr) ||
1483 0 == dvb_usb_device_init(intf, p7500, 1894 0 == dvb_usb_device_init(intf, p7500,
1484 THIS_MODULE, NULL, adapter_nr)) 1895 THIS_MODULE, NULL, adapter_nr) ||
1896 0 == dvb_usb_device_init(intf, &su3000_properties,
1897 THIS_MODULE, NULL, adapter_nr))
1485 return 0; 1898 return 0;
1486 1899
1487 return -ENODEV; 1900 return -ENODEV;
@@ -1514,7 +1927,8 @@ module_exit(dw2102_module_exit);
1514MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by"); 1927MODULE_AUTHOR("Igor M. Liplianin (c) liplianin@me.by");
1515MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104," 1928MODULE_DESCRIPTION("Driver for DVBWorld DVB-S 2101, 2102, DVB-S2 2104,"
1516 " DVB-C 3101 USB2.0," 1929 " DVB-C 3101 USB2.0,"
1517 " TeVii S600, S630, S650, S660 USB2.0," 1930 " TeVii S600, S630, S650, S660, S480,"
1518 " Prof 1100, 7500 USB2.0 devices"); 1931 " Prof 1100, 7500 USB2.0,"
1932 " Geniatech SU3000 devices");
1519MODULE_VERSION("0.1"); 1933MODULE_VERSION("0.1");
1520MODULE_LICENSE("GPL"); 1934MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/lmedm04.c b/drivers/media/dvb/dvb-usb/lmedm04.c
index 46ccd01a7696..cd26e7c1536a 100644
--- a/drivers/media/dvb/dvb-usb/lmedm04.c
+++ b/drivers/media/dvb/dvb-usb/lmedm04.c
@@ -2,7 +2,9 @@
2 * 2 *
3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395 3 * DM04/QQBOX DVB-S USB BOX LME2510C + SHARP:BS2F7HZ7395
4 * LME2510C + LG TDQY-P001F 4 * LME2510C + LG TDQY-P001F
5 * LME2510C + BS2F7HZ0194
5 * LME2510 + LG TDQY-P001F 6 * LME2510 + LG TDQY-P001F
7 * LME2510 + BS2F7HZ0194
6 * 8 *
7 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395) 9 * MVB7395 (LME2510C+SHARP:BS2F7HZ7395)
8 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V) 10 * SHARP:BS2F7HZ7395 = (STV0288+Sharp IX2505V)
@@ -12,20 +14,22 @@
12 * 14 *
13 * MVB0001F (LME2510C+LGTDQT-P001F) 15 * MVB0001F (LME2510C+LGTDQT-P001F)
14 * 16 *
17 * MV0194 (LME2510+SHARP:BS2F7HZ0194)
18 * SHARP:BS2F7HZ0194 = (STV0299+IX2410)
19 *
20 * MVB0194 (LME2510C+SHARP0194)
21 *
15 * For firmware see Documentation/dvb/lmedm04.txt 22 * For firmware see Documentation/dvb/lmedm04.txt
16 * 23 *
17 * I2C addresses: 24 * I2C addresses:
18 * 0xd0 - STV0288 - Demodulator 25 * 0xd0 - STV0288 - Demodulator
19 * 0xc0 - Sharp IX2505V - Tuner 26 * 0xc0 - Sharp IX2505V - Tuner
20 * --or-- 27 * --
21 * 0x1c - TDA10086 - Demodulator 28 * 0x1c - TDA10086 - Demodulator
22 * 0xc0 - TDA8263 - Tuner 29 * 0xc0 - TDA8263 - Tuner
23 * 30 * --
24 * ***Please Note*** 31 * 0xd0 - STV0299 - Demodulator
25 * There are other variants of the DM04 32 * 0xc0 - IX2410 - Tuner
26 * ***NOT SUPPORTED***
27 * MV0194 (LME2510+SHARP0194)
28 * MVB0194 (LME2510C+SHARP0194)
29 * 33 *
30 * 34 *
31 * VID = 3344 PID LME2510=1122 LME2510C=1120 35 * VID = 3344 PID LME2510=1122 LME2510C=1120
@@ -55,6 +59,9 @@
55 * 59 *
56 * QQbox suffers from noise on LNB voltage. 60 * QQbox suffers from noise on LNB voltage.
57 * 61 *
62 * LME2510: SHARP:BS2F7HZ0194(MV0194) cannot cold reset and share system
63 * with other tuners. After a cold reset streaming will not start.
64 *
58 * PID functions have been removed from this driver version due to 65 * PID functions have been removed from this driver version due to
59 * problems with different firmware and application versions. 66 * problems with different firmware and application versions.
60 */ 67 */
@@ -69,6 +76,9 @@
69#include "tda10086.h" 76#include "tda10086.h"
70#include "stv0288.h" 77#include "stv0288.h"
71#include "ix2505v.h" 78#include "ix2505v.h"
79#include "stv0299.h"
80#include "dvb-pll.h"
81#include "z0194a.h"
72 82
73 83
74 84
@@ -96,8 +106,11 @@ MODULE_PARM_DESC(firmware, "set default firmware 0=Sharp7395 1=LG");
96 106
97 107
98DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 108DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
109
110#define TUNER_DEFAULT 0x0
99#define TUNER_LG 0x1 111#define TUNER_LG 0x1
100#define TUNER_S7395 0x2 112#define TUNER_S7395 0x2
113#define TUNER_S0194 0x3
101 114
102struct lme2510_state { 115struct lme2510_state {
103 u8 id; 116 u8 id;
@@ -191,7 +204,7 @@ static int lme2510_stream_restart(struct dvb_usb_device *d)
191 rbuff, sizeof(rbuff)); 204 rbuff, sizeof(rbuff));
192 return ret; 205 return ret;
193} 206}
194static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u16 keypress) 207static int lme2510_remote_keypress(struct dvb_usb_adapter *adap, u32 keypress)
195{ 208{
196 struct dvb_usb_device *d = adap->dev; 209 struct dvb_usb_device *d = adap->dev;
197 210
@@ -237,7 +250,8 @@ static void lme2510_int_response(struct urb *lme_urb)
237 case 0xaa: 250 case 0xaa:
238 debug_data_snipet(1, "INT Remote data snipet in", ibuf); 251 debug_data_snipet(1, "INT Remote data snipet in", ibuf);
239 lme2510_remote_keypress(adap, 252 lme2510_remote_keypress(adap,
240 (u16)(ibuf[4]<<8)+ibuf[5]); 253 (u32)(ibuf[2] << 24) + (ibuf[3] << 16) +
254 (ibuf[4] << 8) + ibuf[5]);
241 break; 255 break;
242 case 0xbb: 256 case 0xbb:
243 switch (st->tuner_config) { 257 switch (st->tuner_config) {
@@ -249,6 +263,7 @@ static void lme2510_int_response(struct urb *lme_urb)
249 st->time_key = ibuf[7]; 263 st->time_key = ibuf[7];
250 break; 264 break;
251 case TUNER_S7395: 265 case TUNER_S7395:
266 case TUNER_S0194:
252 /* Tweak for earlier firmware*/ 267 /* Tweak for earlier firmware*/
253 if (ibuf[1] == 0x03) { 268 if (ibuf[1] == 0x03) {
254 if (ibuf[2] > 1) 269 if (ibuf[2] > 1)
@@ -364,6 +379,18 @@ static int lme2510_msg(struct dvb_usb_device *d,
364 msleep(5); 379 msleep(5);
365 } 380 }
366 break; 381 break;
382 case TUNER_S0194:
383 if (wbuf[2] == 0xd0) {
384 if (wbuf[3] == 0x1b) {
385 st->signal_lock = rbuf[1];
386 if ((st->stream_on & 1) &&
387 (st->signal_lock & 0x8)) {
388 lme2510_stream_restart(d);
389 st->i2c_talk_onoff = 0;
390 }
391 }
392 }
393 break;
367 default: 394 default:
368 break; 395 break;
369 } 396 }
@@ -423,6 +450,34 @@ static int lme2510_msg(struct dvb_usb_device *d,
423 break; 450 break;
424 } 451 }
425 break; 452 break;
453 case TUNER_S0194:
454 switch (wbuf[3]) {
455 case 0x18:
456 rbuf[0] = 0x55;
457 rbuf[1] = (st->signal_level & 0x80)
458 ? 0 : (st->signal_level * 2);
459 break;
460 case 0x24:
461 rbuf[0] = 0x55;
462 rbuf[1] = st->signal_sn;
463 break;
464 case 0x1b:
465 rbuf[0] = 0x55;
466 rbuf[1] = st->signal_lock;
467 break;
468 case 0x19:
469 case 0x25:
470 case 0x1e:
471 case 0x1d:
472 rbuf[0] = 0x55;
473 rbuf[1] = 0x00;
474 break;
475 default:
476 lme2510_usb_talk(d, wbuf, wlen, rbuf, rlen);
477 st->i2c_talk_onoff = 1;
478 break;
479 }
480 break;
426 default: 481 default:
427 break; 482 break;
428 } 483 }
@@ -517,17 +572,14 @@ static int lme2510_identify_state(struct usb_device *udev,
517 struct dvb_usb_device_description **desc, 572 struct dvb_usb_device_description **desc,
518 int *cold) 573 int *cold)
519{ 574{
520 if (lme2510_return_status(udev) == 0x44) 575 *cold = 0;
521 *cold = 1;
522 else
523 *cold = 0;
524 return 0; 576 return 0;
525} 577}
526 578
527static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) 579static int lme2510_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
528{ 580{
529 struct lme2510_state *st = adap->dev->priv; 581 struct lme2510_state *st = adap->dev->priv;
530 static u8 clear_reg_3[] = LME_CLEAR_PID; 582 static u8 clear_reg_3[] = LME_CLEAR_PID;
531 static u8 rbuf[1]; 583 static u8 rbuf[1];
532 int ret = 0, rlen = sizeof(rbuf); 584 int ret = 0, rlen = sizeof(rbuf);
533 585
@@ -658,9 +710,6 @@ static int lme2510_download_firmware(struct usb_device *dev,
658 return (ret < 0) ? -ENODEV : 0; 710 return (ret < 0) ? -ENODEV : 0;
659} 711}
660 712
661/* Default firmware for LME2510C */
662char lme_firmware[50] = "dvb-usb-lme2510c-s7395.fw";
663
664static void lme_coldreset(struct usb_device *dev) 713static void lme_coldreset(struct usb_device *dev)
665{ 714{
666 int ret = 0, len_in; 715 int ret = 0, len_in;
@@ -678,49 +727,83 @@ static void lme_coldreset(struct usb_device *dev)
678static int lme_firmware_switch(struct usb_device *udev, int cold) 727static int lme_firmware_switch(struct usb_device *udev, int cold)
679{ 728{
680 const struct firmware *fw = NULL; 729 const struct firmware *fw = NULL;
681 char lme2510c_s7395[] = "dvb-usb-lme2510c-s7395.fw"; 730 const char fw_c_s7395[] = "dvb-usb-lme2510c-s7395.fw";
682 char lme2510c_lg[] = "dvb-usb-lme2510c-lg.fw"; 731 const char fw_c_lg[] = "dvb-usb-lme2510c-lg.fw";
683 char *firm_msg[] = {"Loading", "Switching to"}; 732 const char fw_c_s0194[] = "dvb-usb-lme2510c-s0194.fw";
684 int ret; 733 const char fw_lg[] = "dvb-usb-lme2510-lg.fw";
734 const char fw_s0194[] = "dvb-usb-lme2510-s0194.fw";
735 const char *fw_lme;
736 int ret, cold_fw;
685 737
686 cold = (cold > 0) ? (cold & 1) : 0; 738 cold = (cold > 0) ? (cold & 1) : 0;
687 739
688 if (udev->descriptor.idProduct == 0x1122) 740 cold_fw = !cold;
689 return 0;
690 741
691 switch (dvb_usb_lme2510_firmware) { 742 if (udev->descriptor.idProduct == 0x1122) {
692 case 0: 743 switch (dvb_usb_lme2510_firmware) {
693 default: 744 default:
694 memcpy(&lme_firmware, lme2510c_s7395, sizeof(lme2510c_s7395)); 745 dvb_usb_lme2510_firmware = TUNER_S0194;
695 ret = request_firmware(&fw, lme_firmware, &udev->dev); 746 case TUNER_S0194:
696 if (ret == 0) { 747 fw_lme = fw_s0194;
697 info("FRM %s S7395 Firmware", firm_msg[cold]); 748 ret = request_firmware(&fw, fw_lme, &udev->dev);
749 if (ret == 0) {
750 cold = 0;/*lme2510-s0194 cannot cold reset*/
751 break;
752 }
753 dvb_usb_lme2510_firmware = TUNER_LG;
754 case TUNER_LG:
755 fw_lme = fw_lg;
756 ret = request_firmware(&fw, fw_lme, &udev->dev);
757 if (ret == 0)
758 break;
759 info("FRM No Firmware Found - please install");
760 dvb_usb_lme2510_firmware = TUNER_DEFAULT;
761 cold = 0;
762 cold_fw = 0;
698 break; 763 break;
699 } 764 }
700 if (cold == 0) 765 } else {
701 dvb_usb_lme2510_firmware = 1; 766 switch (dvb_usb_lme2510_firmware) {
702 else 767 default:
768 dvb_usb_lme2510_firmware = TUNER_S7395;
769 case TUNER_S7395:
770 fw_lme = fw_c_s7395;
771 ret = request_firmware(&fw, fw_lme, &udev->dev);
772 if (ret == 0)
773 break;
774 dvb_usb_lme2510_firmware = TUNER_LG;
775 case TUNER_LG:
776 fw_lme = fw_c_lg;
777 ret = request_firmware(&fw, fw_lme, &udev->dev);
778 if (ret == 0)
779 break;
780 dvb_usb_lme2510_firmware = TUNER_S0194;
781 case TUNER_S0194:
782 fw_lme = fw_c_s0194;
783 ret = request_firmware(&fw, fw_lme, &udev->dev);
784 if (ret == 0)
785 break;
786 info("FRM No Firmware Found - please install");
787 dvb_usb_lme2510_firmware = TUNER_DEFAULT;
703 cold = 0; 788 cold = 0;
704 case 1: 789 cold_fw = 0;
705 memcpy(&lme_firmware, lme2510c_lg, sizeof(lme2510c_lg));
706 ret = request_firmware(&fw, lme_firmware, &udev->dev);
707 if (ret == 0) {
708 info("FRM %s LG Firmware", firm_msg[cold]);
709 break; 790 break;
710 } 791 }
711 info("FRM No Firmware Found - please install");
712 dvb_usb_lme2510_firmware = 0;
713 cold = 0;
714 break;
715 } 792 }
716 793
717 release_firmware(fw); 794 if (cold_fw) {
795 info("FRM Loading %s file", fw_lme);
796 ret = lme2510_download_firmware(udev, fw);
797 }
718 798
719 if (cold) { 799 if (cold) {
800 info("FRM Changing to %s firmware", fw_lme);
720 lme_coldreset(udev); 801 lme_coldreset(udev);
721 return -ENODEV; 802 return -ENODEV;
722 } 803 }
723 804
805 release_firmware(fw);
806
724 return ret; 807 return ret;
725} 808}
726 809
@@ -758,6 +841,18 @@ static struct ix2505v_config lme_tuner = {
758 .tuner_chargepump = 0x3, 841 .tuner_chargepump = 0x3,
759}; 842};
760 843
844static struct stv0299_config sharp_z0194_config = {
845 .demod_address = 0xd0,
846 .inittab = sharp_z0194a_inittab,
847 .mclk = 88000000UL,
848 .invert = 0,
849 .skip_reinit = 0,
850 .lock_output = STV0299_LOCKOUTPUT_1,
851 .volt13_op0_op1 = STV0299_VOLT13_OP1,
852 .min_delay_ms = 100,
853 .set_symbol_rate = sharp_z0194a_set_symbol_rate,
854};
855
761static int dm04_lme2510_set_voltage(struct dvb_frontend *fe, 856static int dm04_lme2510_set_voltage(struct dvb_frontend *fe,
762 fe_sec_voltage_t voltage) 857 fe_sec_voltage_t voltage)
763{ 858{
@@ -793,7 +888,8 @@ static int lme_name(struct dvb_usb_adapter *adap)
793{ 888{
794 struct lme2510_state *st = adap->dev->priv; 889 struct lme2510_state *st = adap->dev->priv;
795 const char *desc = adap->dev->desc->name; 890 const char *desc = adap->dev->desc->name;
796 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395"}; 891 char *fe_name[] = {"", " LG TDQY-P001F", " SHARP:BS2F7HZ7395",
892 " SHARP:BS2F7HZ0194"};
797 char *name = adap->fe->ops.info.name; 893 char *name = adap->fe->ops.info.name;
798 894
799 strlcpy(name, desc, 128); 895 strlcpy(name, desc, 128);
@@ -820,26 +916,40 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
820 st->i2c_tuner_gate_r = 4; 916 st->i2c_tuner_gate_r = 4;
821 st->i2c_tuner_addr = 0xc0; 917 st->i2c_tuner_addr = 0xc0;
822 st->tuner_config = TUNER_LG; 918 st->tuner_config = TUNER_LG;
823 if (dvb_usb_lme2510_firmware != 1) { 919 if (dvb_usb_lme2510_firmware != TUNER_LG) {
824 dvb_usb_lme2510_firmware = 1; 920 dvb_usb_lme2510_firmware = TUNER_LG;
825 ret = lme_firmware_switch(adap->dev->udev, 1); 921 ret = lme_firmware_switch(adap->dev->udev, 1);
826 } else /*stops LG/Sharp multi tuner problems*/ 922 }
827 dvb_usb_lme2510_firmware = 0; 923 goto end;
924 }
925
926 st->i2c_gate = 4;
927 adap->fe = dvb_attach(stv0299_attach, &sharp_z0194_config,
928 &adap->dev->i2c_adap);
929 if (adap->fe) {
930 info("FE Found Stv0299");
931 st->i2c_tuner_gate_w = 4;
932 st->i2c_tuner_gate_r = 5;
933 st->i2c_tuner_addr = 0xc0;
934 st->tuner_config = TUNER_S0194;
935 if (dvb_usb_lme2510_firmware != TUNER_S0194) {
936 dvb_usb_lme2510_firmware = TUNER_S0194;
937 ret = lme_firmware_switch(adap->dev->udev, 1);
938 }
828 goto end; 939 goto end;
829 } 940 }
830 941
831 st->i2c_gate = 5; 942 st->i2c_gate = 5;
832 adap->fe = dvb_attach(stv0288_attach, &lme_config, 943 adap->fe = dvb_attach(stv0288_attach, &lme_config,
833 &adap->dev->i2c_adap); 944 &adap->dev->i2c_adap);
834
835 if (adap->fe) { 945 if (adap->fe) {
836 info("FE Found Stv0288"); 946 info("FE Found Stv0288");
837 st->i2c_tuner_gate_w = 4; 947 st->i2c_tuner_gate_w = 4;
838 st->i2c_tuner_gate_r = 5; 948 st->i2c_tuner_gate_r = 5;
839 st->i2c_tuner_addr = 0xc0; 949 st->i2c_tuner_addr = 0xc0;
840 st->tuner_config = TUNER_S7395; 950 st->tuner_config = TUNER_S7395;
841 if (dvb_usb_lme2510_firmware != 0) { 951 if (dvb_usb_lme2510_firmware != TUNER_S7395) {
842 dvb_usb_lme2510_firmware = 0; 952 dvb_usb_lme2510_firmware = TUNER_S7395;
843 ret = lme_firmware_switch(adap->dev->udev, 1); 953 ret = lme_firmware_switch(adap->dev->udev, 1);
844 } 954 }
845 } else { 955 } else {
@@ -847,6 +957,7 @@ static int dm04_lme2510_frontend_attach(struct dvb_usb_adapter *adap)
847 return -ENODEV; 957 return -ENODEV;
848 } 958 }
849 959
960
850end: if (ret) { 961end: if (ret) {
851 kfree(adap->fe); 962 kfree(adap->fe);
852 adap->fe = NULL; 963 adap->fe = NULL;
@@ -855,14 +966,13 @@ end: if (ret) {
855 966
856 adap->fe->ops.set_voltage = dm04_lme2510_set_voltage; 967 adap->fe->ops.set_voltage = dm04_lme2510_set_voltage;
857 ret = lme_name(adap); 968 ret = lme_name(adap);
858
859 return ret; 969 return ret;
860} 970}
861 971
862static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap) 972static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
863{ 973{
864 struct lme2510_state *st = adap->dev->priv; 974 struct lme2510_state *st = adap->dev->priv;
865 char *tun_msg[] = {"", "TDA8263", "IX2505V"}; 975 char *tun_msg[] = {"", "TDA8263", "IX2505V", "DVB_PLL_OPERA"};
866 int ret = 0; 976 int ret = 0;
867 977
868 switch (st->tuner_config) { 978 switch (st->tuner_config) {
@@ -876,6 +986,11 @@ static int dm04_lme2510_tuner(struct dvb_usb_adapter *adap)
876 &adap->dev->i2c_adap)) 986 &adap->dev->i2c_adap))
877 ret = st->tuner_config; 987 ret = st->tuner_config;
878 break; 988 break;
989 case TUNER_S0194:
990 if (dvb_attach(dvb_pll_attach , adap->fe, 0xc0,
991 &adap->dev->i2c_adap, DVB_PLL_OPERA1))
992 ret = st->tuner_config;
993 break;
879 default: 994 default:
880 break; 995 break;
881 } 996 }
@@ -936,7 +1051,10 @@ static int lme2510_probe(struct usb_interface *intf,
936 return -ENODEV; 1051 return -ENODEV;
937 } 1052 }
938 1053
939 lme_firmware_switch(udev, 0); 1054 if (lme2510_return_status(udev) == 0x44) {
1055 lme_firmware_switch(udev, 0);
1056 return -ENODEV;
1057 }
940 1058
941 if (0 == dvb_usb_device_init(intf, &lme2510_properties, 1059 if (0 == dvb_usb_device_init(intf, &lme2510_properties,
942 THIS_MODULE, NULL, adapter_nr)) { 1060 THIS_MODULE, NULL, adapter_nr)) {
@@ -964,10 +1082,6 @@ MODULE_DEVICE_TABLE(usb, lme2510_table);
964 1082
965static struct dvb_usb_device_properties lme2510_properties = { 1083static struct dvb_usb_device_properties lme2510_properties = {
966 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1084 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
967 .usb_ctrl = DEVICE_SPECIFIC,
968 .download_firmware = lme2510_download_firmware,
969 .firmware = "dvb-usb-lme2510-lg.fw",
970
971 .size_of_priv = sizeof(struct lme2510_state), 1085 .size_of_priv = sizeof(struct lme2510_state),
972 .num_adapters = 1, 1086 .num_adapters = 1,
973 .adapter = { 1087 .adapter = {
@@ -1004,9 +1118,6 @@ static struct dvb_usb_device_properties lme2510_properties = {
1004 1118
1005static struct dvb_usb_device_properties lme2510c_properties = { 1119static struct dvb_usb_device_properties lme2510c_properties = {
1006 .caps = DVB_USB_IS_AN_I2C_ADAPTER, 1120 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
1007 .usb_ctrl = DEVICE_SPECIFIC,
1008 .download_firmware = lme2510_download_firmware,
1009 .firmware = (const char *)&lme_firmware,
1010 .size_of_priv = sizeof(struct lme2510_state), 1121 .size_of_priv = sizeof(struct lme2510_state),
1011 .num_adapters = 1, 1122 .num_adapters = 1,
1012 .adapter = { 1123 .adapter = {
@@ -1109,5 +1220,5 @@ module_exit(lme2510_module_exit);
1109 1220
1110MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 1221MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
1111MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0"); 1222MODULE_DESCRIPTION("LME2510(C) DVB-S USB2.0");
1112MODULE_VERSION("1.75"); 1223MODULE_VERSION("1.80");
1113MODULE_LICENSE("GPL"); 1224MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/opera1.c b/drivers/media/dvb/dvb-usb/opera1.c
index 1f1b7d6980a5..7e569f4dd80b 100644
--- a/drivers/media/dvb/dvb-usb/opera1.c
+++ b/drivers/media/dvb/dvb-usb/opera1.c
@@ -342,23 +342,22 @@ static struct rc_map_table rc_map_opera1_table[] = {
342 {0x49b6, KEY_8}, 342 {0x49b6, KEY_8},
343 {0x05fa, KEY_9}, 343 {0x05fa, KEY_9},
344 {0x45ba, KEY_0}, 344 {0x45ba, KEY_0},
345 {0x09f6, KEY_UP}, /*chanup */ 345 {0x09f6, KEY_CHANNELUP}, /*chanup */
346 {0x1be5, KEY_DOWN}, /*chandown */ 346 {0x1be5, KEY_CHANNELDOWN}, /*chandown */
347 {0x5da3, KEY_LEFT}, /*voldown */ 347 {0x5da3, KEY_VOLUMEDOWN}, /*voldown */
348 {0x5fa1, KEY_RIGHT}, /*volup */ 348 {0x5fa1, KEY_VOLUMEUP}, /*volup */
349 {0x07f8, KEY_SPACE}, /*tab */ 349 {0x07f8, KEY_SPACE}, /*tab */
350 {0x1fe1, KEY_ENTER}, /*play ok */ 350 {0x1fe1, KEY_OK}, /*play ok */
351 {0x1be4, KEY_Z}, /*zoom */ 351 {0x1be4, KEY_ZOOM}, /*zoom */
352 {0x59a6, KEY_M}, /*mute */ 352 {0x59a6, KEY_MUTE}, /*mute */
353 {0x5ba5, KEY_F}, /*tv/f */ 353 {0x5ba5, KEY_RADIO}, /*tv/f */
354 {0x19e7, KEY_R}, /*rec */ 354 {0x19e7, KEY_RECORD}, /*rec */
355 {0x01fe, KEY_S}, /*Stop */ 355 {0x01fe, KEY_STOP}, /*Stop */
356 {0x03fd, KEY_P}, /*pause */ 356 {0x03fd, KEY_PAUSE}, /*pause */
357 {0x03fc, KEY_W}, /*<- -> */ 357 {0x03fc, KEY_SCREEN}, /*<- -> */
358 {0x07f9, KEY_C}, /*capture */ 358 {0x07f9, KEY_CAMERA}, /*capture */
359 {0x47b9, KEY_Q}, /*exit */ 359 {0x47b9, KEY_ESC}, /*exit */
360 {0x43bc, KEY_O}, /*power */ 360 {0x43bc, KEY_POWER2}, /*power */
361
362}; 361};
363 362
364static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state) 363static int opera1_rc_query(struct dvb_usb_device *dev, u32 * event, int *state)
diff --git a/drivers/media/dvb/dvb-usb/technisat-usb2.c b/drivers/media/dvb/dvb-usb/technisat-usb2.c
new file mode 100644
index 000000000000..08f8842ad280
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/technisat-usb2.c
@@ -0,0 +1,807 @@
1/*
2 * Linux driver for Technisat DVB-S/S2 USB 2.0 device
3 *
4 * Copyright (C) 2010 Patrick Boettcher,
5 * Kernel Labs Inc. PO Box 745, St James, NY 11780
6 *
7 * Development was sponsored by Technisat Digital UK Limited, whose
8 * registered office is Witan Gate House 500 - 600 Witan Gate West,
9 * Milton Keynes, MK9 1SH
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of the
14 * License, or (at your option) any later version.
15 *
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 * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
22 * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
23 * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
24 * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
25 * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
26 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
27 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
28 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
29 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
30 * GNU General Public License for more details.
31 */
32
33#define DVB_USB_LOG_PREFIX "technisat-usb2"
34#include "dvb-usb.h"
35
36#include "stv6110x.h"
37#include "stv090x.h"
38
39/* module parameters */
40DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
41
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug,
45 "set debugging level (bit-mask: 1=info,2=eeprom,4=i2c,8=rc)." \
46 DVB_USB_DEBUG_STATUS);
47
48/* disables all LED control command and
49 * also does not start the signal polling thread */
50static int disable_led_control;
51module_param(disable_led_control, int, 0444);
52MODULE_PARM_DESC(disable_led_control,
53 "disable LED control of the device "
54 "(default: 0 - LED control is active).");
55
56/* device private data */
57struct technisat_usb2_state {
58 struct dvb_usb_device *dev;
59 struct delayed_work green_led_work;
60 u8 power_state;
61
62 u16 last_scan_code;
63};
64
65/* debug print helpers */
66#define deb_info(args...) dprintk(debug, 0x01, args)
67#define deb_eeprom(args...) dprintk(debug, 0x02, args)
68#define deb_i2c(args...) dprintk(debug, 0x04, args)
69#define deb_rc(args...) dprintk(debug, 0x08, args)
70
71/* vendor requests */
72#define SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST 0xB3
73#define SET_FRONT_END_RESET_VENDOR_REQUEST 0xB4
74#define GET_VERSION_INFO_VENDOR_REQUEST 0xB5
75#define SET_GREEN_LED_VENDOR_REQUEST 0xB6
76#define SET_RED_LED_VENDOR_REQUEST 0xB7
77#define GET_IR_DATA_VENDOR_REQUEST 0xB8
78#define SET_LED_TIMER_DIVIDER_VENDOR_REQUEST 0xB9
79#define SET_USB_REENUMERATION 0xBA
80
81/* i2c-access methods */
82#define I2C_SPEED_100KHZ_BIT 0x40
83
84#define I2C_STATUS_NAK 7
85#define I2C_STATUS_OK 8
86
87static int technisat_usb2_i2c_access(struct usb_device *udev,
88 u8 device_addr, u8 *tx, u8 txlen, u8 *rx, u8 rxlen)
89{
90 u8 b[64];
91 int ret, actual_length;
92
93 deb_i2c("i2c-access: %02x, tx: ", device_addr);
94 debug_dump(tx, txlen, deb_i2c);
95 deb_i2c(" ");
96
97 if (txlen > 62) {
98 err("i2c TX buffer can't exceed 62 bytes (dev 0x%02x)",
99 device_addr);
100 txlen = 62;
101 }
102 if (rxlen > 62) {
103 err("i2c RX buffer can't exceed 62 bytes (dev 0x%02x)",
104 device_addr);
105 txlen = 62;
106 }
107
108 b[0] = I2C_SPEED_100KHZ_BIT;
109 b[1] = device_addr << 1;
110
111 if (rx != NULL) {
112 b[0] |= rxlen;
113 b[1] |= 1;
114 }
115
116 memcpy(&b[2], tx, txlen);
117 ret = usb_bulk_msg(udev,
118 usb_sndbulkpipe(udev, 0x01),
119 b, 2 + txlen,
120 NULL, 1000);
121
122 if (ret < 0) {
123 err("i2c-error: out failed %02x = %d", device_addr, ret);
124 return -ENODEV;
125 }
126
127 ret = usb_bulk_msg(udev,
128 usb_rcvbulkpipe(udev, 0x01),
129 b, 64, &actual_length, 1000);
130 if (ret < 0) {
131 err("i2c-error: in failed %02x = %d", device_addr, ret);
132 return -ENODEV;
133 }
134
135 if (b[0] != I2C_STATUS_OK) {
136 err("i2c-error: %02x = %d", device_addr, b[0]);
137 /* handle tuner-i2c-nak */
138 if (!(b[0] == I2C_STATUS_NAK &&
139 device_addr == 0x60
140 /* && device_is_technisat_usb2 */))
141 return -ENODEV;
142 }
143
144 deb_i2c("status: %d, ", b[0]);
145
146 if (rx != NULL) {
147 memcpy(rx, &b[2], rxlen);
148
149 deb_i2c("rx (%d): ", rxlen);
150 debug_dump(rx, rxlen, deb_i2c);
151 }
152
153 deb_i2c("\n");
154
155 return 0;
156}
157
158static int technisat_usb2_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msg,
159 int num)
160{
161 int ret = 0, i;
162 struct dvb_usb_device *d = i2c_get_adapdata(adap);
163
164 /* Ensure nobody else hits the i2c bus while we're sending our
165 sequence of messages, (such as the remote control thread) */
166 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
167 return -EAGAIN;
168
169 for (i = 0; i < num; i++) {
170 if (i+1 < num && msg[i+1].flags & I2C_M_RD) {
171 ret = technisat_usb2_i2c_access(d->udev, msg[i+1].addr,
172 msg[i].buf, msg[i].len,
173 msg[i+1].buf, msg[i+1].len);
174 if (ret != 0)
175 break;
176 i++;
177 } else {
178 ret = technisat_usb2_i2c_access(d->udev, msg[i].addr,
179 msg[i].buf, msg[i].len,
180 NULL, 0);
181 if (ret != 0)
182 break;
183 }
184 }
185
186 if (ret == 0)
187 ret = i;
188
189 mutex_unlock(&d->i2c_mutex);
190
191 return ret;
192}
193
194static u32 technisat_usb2_i2c_func(struct i2c_adapter *adapter)
195{
196 return I2C_FUNC_I2C;
197}
198
199static struct i2c_algorithm technisat_usb2_i2c_algo = {
200 .master_xfer = technisat_usb2_i2c_xfer,
201 .functionality = technisat_usb2_i2c_func,
202};
203
204#if 0
205static void technisat_usb2_frontend_reset(struct usb_device *udev)
206{
207 usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
208 SET_FRONT_END_RESET_VENDOR_REQUEST,
209 USB_TYPE_VENDOR | USB_DIR_OUT,
210 10, 0,
211 NULL, 0, 500);
212}
213#endif
214
215/* LED control */
216enum technisat_usb2_led_state {
217 LED_OFF,
218 LED_BLINK,
219 LED_ON,
220 LED_UNDEFINED
221};
222
223static int technisat_usb2_set_led(struct dvb_usb_device *d, int red, enum technisat_usb2_led_state state)
224{
225 int ret;
226
227 u8 led[8] = {
228 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
229 0
230 };
231
232 if (disable_led_control && state != LED_OFF)
233 return 0;
234
235 switch (state) {
236 case LED_ON:
237 led[1] = 0x82;
238 break;
239 case LED_BLINK:
240 led[1] = 0x82;
241 if (red) {
242 led[2] = 0x02;
243 led[3] = 10;
244 led[4] = 10;
245 } else {
246 led[2] = 0xff;
247 led[3] = 50;
248 led[4] = 50;
249 }
250 led[5] = 1;
251 break;
252
253 default:
254 case LED_OFF:
255 led[1] = 0x80;
256 break;
257 }
258
259 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
260 return -EAGAIN;
261
262 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
263 red ? SET_RED_LED_VENDOR_REQUEST : SET_GREEN_LED_VENDOR_REQUEST,
264 USB_TYPE_VENDOR | USB_DIR_OUT,
265 0, 0,
266 led, sizeof(led), 500);
267
268 mutex_unlock(&d->i2c_mutex);
269 return ret;
270}
271
272static int technisat_usb2_set_led_timer(struct dvb_usb_device *d, u8 red, u8 green)
273{
274 int ret;
275 u8 b = 0;
276
277 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
278 return -EAGAIN;
279
280 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
281 SET_LED_TIMER_DIVIDER_VENDOR_REQUEST,
282 USB_TYPE_VENDOR | USB_DIR_OUT,
283 (red << 8) | green, 0,
284 &b, 1, 500);
285
286 mutex_unlock(&d->i2c_mutex);
287
288 return ret;
289}
290
291static void technisat_usb2_green_led_control(struct work_struct *work)
292{
293 struct technisat_usb2_state *state =
294 container_of(work, struct technisat_usb2_state, green_led_work.work);
295 struct dvb_frontend *fe = state->dev->adapter[0].fe;
296
297 if (state->power_state == 0)
298 goto schedule;
299
300 if (fe != NULL) {
301 enum fe_status status;
302
303 if (fe->ops.read_status(fe, &status) != 0)
304 goto schedule;
305
306 if (status & FE_HAS_LOCK) {
307 u32 ber;
308
309 if (fe->ops.read_ber(fe, &ber) != 0)
310 goto schedule;
311
312 if (ber > 1000)
313 technisat_usb2_set_led(state->dev, 0, LED_BLINK);
314 else
315 technisat_usb2_set_led(state->dev, 0, LED_ON);
316 } else
317 technisat_usb2_set_led(state->dev, 0, LED_OFF);
318 }
319
320schedule:
321 schedule_delayed_work(&state->green_led_work,
322 msecs_to_jiffies(500));
323}
324
325/* method to find out whether the firmware has to be downloaded or not */
326static int technisat_usb2_identify_state(struct usb_device *udev,
327 struct dvb_usb_device_properties *props,
328 struct dvb_usb_device_description **desc, int *cold)
329{
330 int ret;
331 u8 version[3];
332
333 /* first select the interface */
334 if (usb_set_interface(udev, 0, 1) != 0)
335 err("could not set alternate setting to 0");
336 else
337 info("set alternate setting");
338
339 *cold = 0; /* by default do not download a firmware - just in case something is wrong */
340
341 ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
342 GET_VERSION_INFO_VENDOR_REQUEST,
343 USB_TYPE_VENDOR | USB_DIR_IN,
344 0, 0,
345 version, sizeof(version), 500);
346
347 if (ret < 0)
348 *cold = 1;
349 else {
350 info("firmware version: %d.%d", version[1], version[2]);
351 *cold = 0;
352 }
353
354 return 0;
355}
356
357/* power control */
358static int technisat_usb2_power_ctrl(struct dvb_usb_device *d, int level)
359{
360 struct technisat_usb2_state *state = d->priv;
361
362 state->power_state = level;
363
364 if (disable_led_control)
365 return 0;
366
367 /* green led is turned off in any case - will be turned on when tuning */
368 technisat_usb2_set_led(d, 0, LED_OFF);
369 /* red led is turned on all the time */
370 technisat_usb2_set_led(d, 1, LED_ON);
371 return 0;
372}
373
374/* mac address reading - from the eeprom */
375#if 0
376static void technisat_usb2_eeprom_dump(struct dvb_usb_device *d)
377{
378 u8 reg;
379 u8 b[16];
380 int i, j;
381
382 /* full EEPROM dump */
383 for (j = 0; j < 256 * 4; j += 16) {
384 reg = j;
385 if (technisat_usb2_i2c_access(d->udev, 0x50 + j / 256, &reg, 1, b, 16) != 0)
386 break;
387
388 deb_eeprom("EEPROM: %01x%02x: ", j / 256, reg);
389 for (i = 0; i < 16; i++)
390 deb_eeprom("%02x ", b[i]);
391 deb_eeprom("\n");
392 }
393}
394#endif
395
396static u8 technisat_usb2_calc_lrc(const u8 *b, u16 length)
397{
398 u8 lrc = 0;
399 while (--length)
400 lrc ^= *b++;
401 return lrc;
402}
403
404static int technisat_usb2_eeprom_lrc_read(struct dvb_usb_device *d,
405 u16 offset, u8 *b, u16 length, u8 tries)
406{
407 u8 bo = offset & 0xff;
408 struct i2c_msg msg[] = {
409 {
410 .addr = 0x50 | ((offset >> 8) & 0x3),
411 .buf = &bo,
412 .len = 1
413 }, {
414 .addr = 0x50 | ((offset >> 8) & 0x3),
415 .flags = I2C_M_RD,
416 .buf = b,
417 .len = length
418 }
419 };
420
421 while (tries--) {
422 int status;
423
424 if (i2c_transfer(&d->i2c_adap, msg, 2) != 2)
425 break;
426
427 status =
428 technisat_usb2_calc_lrc(b, length - 1) == b[length - 1];
429
430 if (status)
431 return 0;
432 }
433
434 return -EREMOTEIO;
435}
436
437#define EEPROM_MAC_START 0x3f8
438#define EEPROM_MAC_TOTAL 8
439static int technisat_usb2_read_mac_address(struct dvb_usb_device *d,
440 u8 mac[])
441{
442 u8 buf[EEPROM_MAC_TOTAL];
443
444 if (technisat_usb2_eeprom_lrc_read(d, EEPROM_MAC_START,
445 buf, EEPROM_MAC_TOTAL, 4) != 0)
446 return -ENODEV;
447
448 memcpy(mac, buf, 6);
449 return 0;
450}
451
452/* frontend attach */
453static int technisat_usb2_set_voltage(struct dvb_frontend *fe,
454 fe_sec_voltage_t voltage)
455{
456 int i;
457 u8 gpio[3] = { 0 }; /* 0 = 2, 1 = 3, 2 = 4 */
458
459 gpio[2] = 1; /* high - voltage ? */
460
461 switch (voltage) {
462 case SEC_VOLTAGE_13:
463 gpio[0] = 1;
464 break;
465 case SEC_VOLTAGE_18:
466 gpio[0] = 1;
467 gpio[1] = 1;
468 break;
469 default:
470 case SEC_VOLTAGE_OFF:
471 break;
472 }
473
474 for (i = 0; i < 3; i++)
475 if (stv090x_set_gpio(fe, i+2, 0, gpio[i], 0) != 0)
476 return -EREMOTEIO;
477 return 0;
478}
479
480static struct stv090x_config technisat_usb2_stv090x_config = {
481 .device = STV0903,
482 .demod_mode = STV090x_SINGLE,
483 .clk_mode = STV090x_CLK_EXT,
484
485 .xtal = 8000000,
486 .address = 0x68,
487
488 .ts1_mode = STV090x_TSMODE_DVBCI,
489 .ts1_clk = 13400000,
490 .ts1_tei = 1,
491
492 .repeater_level = STV090x_RPTLEVEL_64,
493
494 .tuner_bbgain = 6,
495};
496
497static struct stv6110x_config technisat_usb2_stv6110x_config = {
498 .addr = 0x60,
499 .refclk = 16000000,
500 .clk_div = 2,
501};
502
503static int technisat_usb2_frontend_attach(struct dvb_usb_adapter *a)
504{
505 struct usb_device *udev = a->dev->udev;
506 int ret;
507
508 a->fe = dvb_attach(stv090x_attach, &technisat_usb2_stv090x_config,
509 &a->dev->i2c_adap, STV090x_DEMODULATOR_0);
510
511 if (a->fe) {
512 struct stv6110x_devctl *ctl;
513
514 ctl = dvb_attach(stv6110x_attach,
515 a->fe,
516 &technisat_usb2_stv6110x_config,
517 &a->dev->i2c_adap);
518
519 if (ctl) {
520 technisat_usb2_stv090x_config.tuner_init = ctl->tuner_init;
521 technisat_usb2_stv090x_config.tuner_sleep = ctl->tuner_sleep;
522 technisat_usb2_stv090x_config.tuner_set_mode = ctl->tuner_set_mode;
523 technisat_usb2_stv090x_config.tuner_set_frequency = ctl->tuner_set_frequency;
524 technisat_usb2_stv090x_config.tuner_get_frequency = ctl->tuner_get_frequency;
525 technisat_usb2_stv090x_config.tuner_set_bandwidth = ctl->tuner_set_bandwidth;
526 technisat_usb2_stv090x_config.tuner_get_bandwidth = ctl->tuner_get_bandwidth;
527 technisat_usb2_stv090x_config.tuner_set_bbgain = ctl->tuner_set_bbgain;
528 technisat_usb2_stv090x_config.tuner_get_bbgain = ctl->tuner_get_bbgain;
529 technisat_usb2_stv090x_config.tuner_set_refclk = ctl->tuner_set_refclk;
530 technisat_usb2_stv090x_config.tuner_get_status = ctl->tuner_get_status;
531
532 /* call the init function once to initialize
533 tuner's clock output divider and demod's
534 master clock */
535 if (a->fe->ops.init)
536 a->fe->ops.init(a->fe);
537
538 if (mutex_lock_interruptible(&a->dev->i2c_mutex) < 0)
539 return -EAGAIN;
540
541 ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
542 SET_IFCLK_TO_EXTERNAL_TSCLK_VENDOR_REQUEST,
543 USB_TYPE_VENDOR | USB_DIR_OUT,
544 0, 0,
545 NULL, 0, 500);
546 mutex_unlock(&a->dev->i2c_mutex);
547
548 if (ret != 0)
549 err("could not set IF_CLK to external");
550
551 a->fe->ops.set_voltage = technisat_usb2_set_voltage;
552
553 /* if everything was successful assign a nice name to the frontend */
554 strlcpy(a->fe->ops.info.name, a->dev->desc->name,
555 sizeof(a->fe->ops.info.name));
556 } else {
557 dvb_frontend_detach(a->fe);
558 a->fe = NULL;
559 }
560 }
561
562 technisat_usb2_set_led_timer(a->dev, 1, 1);
563
564 return a->fe == NULL ? -ENODEV : 0;
565}
566
567/* Remote control */
568
569/* the device is giving providing raw IR-signals to the host mapping
570 * it only to one remote control is just the default implementation
571 */
572#define NOMINAL_IR_BIT_TRANSITION_TIME_US 889
573#define NOMINAL_IR_BIT_TIME_US (2 * NOMINAL_IR_BIT_TRANSITION_TIME_US)
574
575#define FIRMWARE_CLOCK_TICK 83333
576#define FIRMWARE_CLOCK_DIVISOR 256
577
578#define IR_PERCENT_TOLERANCE 15
579
580#define NOMINAL_IR_BIT_TRANSITION_TICKS ((NOMINAL_IR_BIT_TRANSITION_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
581#define NOMINAL_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICKS / FIRMWARE_CLOCK_DIVISOR)
582
583#define NOMINAL_IR_BIT_TIME_TICKS ((NOMINAL_IR_BIT_TIME_US * 1000 * 1000) / FIRMWARE_CLOCK_TICK)
584#define NOMINAL_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICKS / FIRMWARE_CLOCK_DIVISOR)
585
586#define MINIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT - ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
587#define MAXIMUM_IR_BIT_TRANSITION_TICK_COUNT (NOMINAL_IR_BIT_TRANSITION_TICK_COUNT + ((NOMINAL_IR_BIT_TRANSITION_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
588
589#define MINIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT - ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
590#define MAXIMUM_IR_BIT_TIME_TICK_COUNT (NOMINAL_IR_BIT_TIME_TICK_COUNT + ((NOMINAL_IR_BIT_TIME_TICK_COUNT * IR_PERCENT_TOLERANCE) / 100))
591
592static int technisat_usb2_get_ir(struct dvb_usb_device *d)
593{
594 u8 buf[62], *b;
595 int ret;
596 struct ir_raw_event ev;
597
598 buf[0] = GET_IR_DATA_VENDOR_REQUEST;
599 buf[1] = 0x08;
600 buf[2] = 0x8f;
601 buf[3] = MINIMUM_IR_BIT_TRANSITION_TICK_COUNT;
602 buf[4] = MAXIMUM_IR_BIT_TIME_TICK_COUNT;
603
604 if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
605 return -EAGAIN;
606 ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev, 0),
607 GET_IR_DATA_VENDOR_REQUEST,
608 USB_TYPE_VENDOR | USB_DIR_OUT,
609 0, 0,
610 buf, 5, 500);
611 if (ret < 0)
612 goto unlock;
613
614 buf[1] = 0;
615 buf[2] = 0;
616 ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0),
617 GET_IR_DATA_VENDOR_REQUEST,
618 USB_TYPE_VENDOR | USB_DIR_IN,
619 0x8080, 0,
620 buf, sizeof(buf), 500);
621
622unlock:
623 mutex_unlock(&d->i2c_mutex);
624
625 if (ret < 0)
626 return ret;
627
628 if (ret == 1)
629 return 0; /* no key pressed */
630
631 /* decoding */
632 b = buf+1;
633
634#if 0
635 deb_rc("RC: %d ", ret);
636 debug_dump(b, ret, deb_rc);
637#endif
638
639 ev.pulse = 0;
640 while (1) {
641 ev.pulse = !ev.pulse;
642 ev.duration = (*b * FIRMWARE_CLOCK_DIVISOR * FIRMWARE_CLOCK_TICK) / 1000;
643 ir_raw_event_store(d->rc_dev, &ev);
644
645 b++;
646 if (*b == 0xff) {
647 ev.pulse = 0;
648 ev.duration = 888888*2;
649 ir_raw_event_store(d->rc_dev, &ev);
650 break;
651 }
652 }
653
654 ir_raw_event_handle(d->rc_dev);
655
656 return 1;
657}
658
659static int technisat_usb2_rc_query(struct dvb_usb_device *d)
660{
661 int ret = technisat_usb2_get_ir(d);
662
663 if (ret < 0)
664 return ret;
665
666 if (ret == 0)
667 return 0;
668
669 if (!disable_led_control)
670 technisat_usb2_set_led(d, 1, LED_BLINK);
671
672 return 0;
673}
674
675/* DVB-USB and USB stuff follows */
676static struct usb_device_id technisat_usb2_id_table[] = {
677 { USB_DEVICE(USB_VID_TECHNISAT, USB_PID_TECHNISAT_USB2_DVB_S2) },
678 { 0 } /* Terminating entry */
679};
680
681/* device description */
682static struct dvb_usb_device_properties technisat_usb2_devices = {
683 .caps = DVB_USB_IS_AN_I2C_ADAPTER,
684
685 .usb_ctrl = CYPRESS_FX2,
686
687 .identify_state = technisat_usb2_identify_state,
688 .firmware = "dvb-usb-SkyStar_USB_HD_FW_v17_63.HEX.fw",
689
690 .size_of_priv = sizeof(struct technisat_usb2_state),
691
692 .i2c_algo = &technisat_usb2_i2c_algo,
693
694 .power_ctrl = technisat_usb2_power_ctrl,
695 .read_mac_address = technisat_usb2_read_mac_address,
696
697 .num_adapters = 1,
698 .adapter = {
699 {
700 .frontend_attach = technisat_usb2_frontend_attach,
701
702 .stream = {
703 .type = USB_ISOC,
704 .count = 8,
705 .endpoint = 0x2,
706 .u = {
707 .isoc = {
708 .framesperurb = 32,
709 .framesize = 2048,
710 .interval = 3,
711 }
712 }
713 },
714
715 .size_of_priv = 0,
716 },
717 },
718
719 .num_device_descs = 1,
720 .devices = {
721 { "Technisat SkyStar USB HD (DVB-S/S2)",
722 { &technisat_usb2_id_table[0], NULL },
723 { NULL },
724 },
725 },
726
727 .rc.core = {
728 .rc_interval = 100,
729 .rc_codes = RC_MAP_TECHNISAT_USB2,
730 .module_name = "technisat-usb2",
731 .rc_query = technisat_usb2_rc_query,
732 .allowed_protos = RC_TYPE_ALL,
733 .driver_type = RC_DRIVER_IR_RAW,
734 }
735};
736
737static int technisat_usb2_probe(struct usb_interface *intf,
738 const struct usb_device_id *id)
739{
740 struct dvb_usb_device *dev;
741
742 if (dvb_usb_device_init(intf, &technisat_usb2_devices, THIS_MODULE,
743 &dev, adapter_nr) != 0)
744 return -ENODEV;
745
746 if (dev) {
747 struct technisat_usb2_state *state = dev->priv;
748 state->dev = dev;
749
750 if (!disable_led_control) {
751 INIT_DELAYED_WORK(&state->green_led_work,
752 technisat_usb2_green_led_control);
753 schedule_delayed_work(&state->green_led_work,
754 msecs_to_jiffies(500));
755 }
756 }
757
758 return 0;
759}
760
761static void technisat_usb2_disconnect(struct usb_interface *intf)
762{
763 struct dvb_usb_device *dev = usb_get_intfdata(intf);
764
765 /* work and stuff was only created when the device is is hot-state */
766 if (dev != NULL) {
767 struct technisat_usb2_state *state = dev->priv;
768 if (state != NULL) {
769 cancel_delayed_work_sync(&state->green_led_work);
770 flush_scheduled_work();
771 }
772 }
773
774 dvb_usb_device_exit(intf);
775}
776
777static struct usb_driver technisat_usb2_driver = {
778 .name = "dvb_usb_technisat_usb2",
779 .probe = technisat_usb2_probe,
780 .disconnect = technisat_usb2_disconnect,
781 .id_table = technisat_usb2_id_table,
782};
783
784/* module stuff */
785static int __init technisat_usb2_module_init(void)
786{
787 int result = usb_register(&technisat_usb2_driver);
788 if (result) {
789 err("usb_register failed. Code %d", result);
790 return result;
791 }
792
793 return 0;
794}
795
796static void __exit technisat_usb2_module_exit(void)
797{
798 usb_deregister(&technisat_usb2_driver);
799}
800
801module_init(technisat_usb2_module_init);
802module_exit(technisat_usb2_module_exit);
803
804MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
805MODULE_DESCRIPTION("Driver for Technisat DVB-S/S2 USB 2.0 device");
806MODULE_VERSION("1.0");
807MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/firewire/Kconfig b/drivers/media/dvb/firewire/Kconfig
index 4afa29256df1..f3e9448c3955 100644
--- a/drivers/media/dvb/firewire/Kconfig
+++ b/drivers/media/dvb/firewire/Kconfig
@@ -1,6 +1,6 @@
1config DVB_FIREDTV 1config DVB_FIREDTV
2 tristate "FireDTV and FloppyDTV" 2 tristate "FireDTV and FloppyDTV"
3 depends on DVB_CORE && (FIREWIRE || IEEE1394) 3 depends on DVB_CORE && FIREWIRE
4 help 4 help
5 Support for DVB receivers from Digital Everywhere 5 Support for DVB receivers from Digital Everywhere
6 which are connected via IEEE 1394 (FireWire). 6 which are connected via IEEE 1394 (FireWire).
@@ -13,12 +13,6 @@ config DVB_FIREDTV
13 13
14if DVB_FIREDTV 14if DVB_FIREDTV
15 15
16config DVB_FIREDTV_FIREWIRE
17 def_bool FIREWIRE = y || (FIREWIRE = m && DVB_FIREDTV = m)
18
19config DVB_FIREDTV_IEEE1394
20 def_bool IEEE1394 = y || (IEEE1394 = m && DVB_FIREDTV = m)
21
22config DVB_FIREDTV_INPUT 16config DVB_FIREDTV_INPUT
23 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m) 17 def_bool INPUT = y || (INPUT = m && DVB_FIREDTV = m)
24 18
diff --git a/drivers/media/dvb/firewire/Makefile b/drivers/media/dvb/firewire/Makefile
index da84203d51c6..357b3aab186b 100644
--- a/drivers/media/dvb/firewire/Makefile
+++ b/drivers/media/dvb/firewire/Makefile
@@ -1,9 +1,6 @@
1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o 1obj-$(CONFIG_DVB_FIREDTV) += firedtv.o
2 2
3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o 3firedtv-y := firedtv-avc.o firedtv-ci.o firedtv-dvb.o firedtv-fe.o firedtv-fw.o
4firedtv-$(CONFIG_DVB_FIREDTV_FIREWIRE) += firedtv-fw.o
5firedtv-$(CONFIG_DVB_FIREDTV_IEEE1394) += firedtv-1394.o
6firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o 4firedtv-$(CONFIG_DVB_FIREDTV_INPUT) += firedtv-rc.o
7 5
8ccflags-y += -Idrivers/media/dvb/dvb-core 6ccflags-y += -Idrivers/media/dvb/dvb-core
9ccflags-$(CONFIG_DVB_FIREDTV_IEEE1394) += -Idrivers/ieee1394
diff --git a/drivers/media/dvb/firewire/firedtv-1394.c b/drivers/media/dvb/firewire/firedtv-1394.c
deleted file mode 100644
index b34ca7afb0e6..000000000000
--- a/drivers/media/dvb/firewire/firedtv-1394.c
+++ /dev/null
@@ -1,300 +0,0 @@
1/*
2 * FireDTV driver -- ieee1394 I/O backend
3 *
4 * Copyright (C) 2004 Andreas Monitzer <andy@monitzer.com>
5 * Copyright (C) 2007-2008 Ben Backx <ben@bbackx.com>
6 * Copyright (C) 2008 Henrik Kurelid <henrik@kurelid.se>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 */
13
14#include <linux/device.h>
15#include <linux/errno.h>
16#include <linux/kernel.h>
17#include <linux/list.h>
18#include <linux/slab.h>
19#include <linux/spinlock.h>
20#include <linux/types.h>
21
22#include <dma.h>
23#include <csr1212.h>
24#include <highlevel.h>
25#include <hosts.h>
26#include <ieee1394.h>
27#include <iso.h>
28#include <nodemgr.h>
29
30#include <dvb_demux.h>
31
32#include "firedtv.h"
33
34static LIST_HEAD(node_list);
35static DEFINE_SPINLOCK(node_list_lock);
36
37#define CIP_HEADER_SIZE 8
38#define MPEG2_TS_HEADER_SIZE 4
39#define MPEG2_TS_SOURCE_PACKET_SIZE (4 + 188)
40
41static void rawiso_activity_cb(struct hpsb_iso *iso)
42{
43 struct firedtv *f, *fdtv = NULL;
44 unsigned int i, num, packet;
45 unsigned char *buf;
46 unsigned long flags;
47 int count;
48
49 spin_lock_irqsave(&node_list_lock, flags);
50 list_for_each_entry(f, &node_list, list)
51 if (f->backend_data == iso) {
52 fdtv = f;
53 break;
54 }
55 spin_unlock_irqrestore(&node_list_lock, flags);
56
57 packet = iso->first_packet;
58 num = hpsb_iso_n_ready(iso);
59
60 if (!fdtv) {
61 pr_err("received at unknown iso channel\n");
62 goto out;
63 }
64
65 for (i = 0; i < num; i++, packet = (packet + 1) % iso->buf_packets) {
66 buf = dma_region_i(&iso->data_buf, unsigned char,
67 iso->infos[packet].offset + CIP_HEADER_SIZE);
68 count = (iso->infos[packet].len - CIP_HEADER_SIZE) /
69 MPEG2_TS_SOURCE_PACKET_SIZE;
70
71 /* ignore empty packet */
72 if (iso->infos[packet].len <= CIP_HEADER_SIZE)
73 continue;
74
75 while (count--) {
76 if (buf[MPEG2_TS_HEADER_SIZE] == 0x47)
77 dvb_dmx_swfilter_packets(&fdtv->demux,
78 &buf[MPEG2_TS_HEADER_SIZE], 1);
79 else
80 dev_err(fdtv->device,
81 "skipping invalid packet\n");
82 buf += MPEG2_TS_SOURCE_PACKET_SIZE;
83 }
84 }
85out:
86 hpsb_iso_recv_release_packets(iso, num);
87}
88
89static inline struct node_entry *node_of(struct firedtv *fdtv)
90{
91 return container_of(fdtv->device, struct unit_directory, device)->ne;
92}
93
94static int node_lock(struct firedtv *fdtv, u64 addr, void *data)
95{
96 quadlet_t *d = data;
97 int ret;
98
99 ret = hpsb_node_lock(node_of(fdtv), addr,
100 EXTCODE_COMPARE_SWAP, &d[1], d[0]);
101 d[0] = d[1];
102
103 return ret;
104}
105
106static int node_read(struct firedtv *fdtv, u64 addr, void *data)
107{
108 return hpsb_node_read(node_of(fdtv), addr, data, 4);
109}
110
111static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
112{
113 return hpsb_node_write(node_of(fdtv), addr, data, len);
114}
115
116#define FDTV_ISO_BUFFER_PACKETS 256
117#define FDTV_ISO_BUFFER_SIZE (FDTV_ISO_BUFFER_PACKETS * 200)
118
119static int start_iso(struct firedtv *fdtv)
120{
121 struct hpsb_iso *iso_handle;
122 int ret;
123
124 iso_handle = hpsb_iso_recv_init(node_of(fdtv)->host,
125 FDTV_ISO_BUFFER_SIZE, FDTV_ISO_BUFFER_PACKETS,
126 fdtv->isochannel, HPSB_ISO_DMA_DEFAULT,
127 -1, /* stat.config.irq_interval */
128 rawiso_activity_cb);
129 if (iso_handle == NULL) {
130 dev_err(fdtv->device, "cannot initialize iso receive\n");
131 return -ENOMEM;
132 }
133 fdtv->backend_data = iso_handle;
134
135 ret = hpsb_iso_recv_start(iso_handle, -1, -1, 0);
136 if (ret != 0) {
137 dev_err(fdtv->device, "cannot start iso receive\n");
138 hpsb_iso_shutdown(iso_handle);
139 fdtv->backend_data = NULL;
140 }
141 return ret;
142}
143
144static void stop_iso(struct firedtv *fdtv)
145{
146 struct hpsb_iso *iso_handle = fdtv->backend_data;
147
148 if (iso_handle != NULL) {
149 hpsb_iso_stop(iso_handle);
150 hpsb_iso_shutdown(iso_handle);
151 }
152 fdtv->backend_data = NULL;
153}
154
155static const struct firedtv_backend fdtv_1394_backend = {
156 .lock = node_lock,
157 .read = node_read,
158 .write = node_write,
159 .start_iso = start_iso,
160 .stop_iso = stop_iso,
161};
162
163static void fcp_request(struct hpsb_host *host, int nodeid, int direction,
164 int cts, u8 *data, size_t length)
165{
166 struct firedtv *f, *fdtv = NULL;
167 unsigned long flags;
168 int su;
169
170 if (length == 0 || (data[0] & 0xf0) != 0)
171 return;
172
173 su = data[1] & 0x7;
174
175 spin_lock_irqsave(&node_list_lock, flags);
176 list_for_each_entry(f, &node_list, list)
177 if (node_of(f)->host == host &&
178 node_of(f)->nodeid == nodeid &&
179 (f->subunit == su || (f->subunit == 0 && su == 0x7))) {
180 fdtv = f;
181 break;
182 }
183 spin_unlock_irqrestore(&node_list_lock, flags);
184
185 if (fdtv)
186 avc_recv(fdtv, data, length);
187}
188
189static int node_probe(struct device *dev)
190{
191 struct unit_directory *ud =
192 container_of(dev, struct unit_directory, device);
193 struct firedtv *fdtv;
194 int kv_len, err;
195 void *kv_str;
196
197 if (ud->model_name_kv) {
198 kv_len = (ud->model_name_kv->value.leaf.len - 2) * 4;
199 kv_str = CSR1212_TEXTUAL_DESCRIPTOR_LEAF_DATA(ud->model_name_kv);
200 } else {
201 kv_len = 0;
202 kv_str = NULL;
203 }
204 fdtv = fdtv_alloc(dev, &fdtv_1394_backend, kv_str, kv_len);
205 if (!fdtv)
206 return -ENOMEM;
207
208 /*
209 * Work around a bug in udev's path_id script: Use the fw-host's dev
210 * instead of the unit directory's dev as parent of the input device.
211 */
212 err = fdtv_register_rc(fdtv, dev->parent->parent);
213 if (err)
214 goto fail_free;
215
216 spin_lock_irq(&node_list_lock);
217 list_add_tail(&fdtv->list, &node_list);
218 spin_unlock_irq(&node_list_lock);
219
220 err = avc_identify_subunit(fdtv);
221 if (err)
222 goto fail;
223
224 err = fdtv_dvb_register(fdtv);
225 if (err)
226 goto fail;
227
228 avc_register_remote_control(fdtv);
229
230 return 0;
231fail:
232 spin_lock_irq(&node_list_lock);
233 list_del(&fdtv->list);
234 spin_unlock_irq(&node_list_lock);
235 fdtv_unregister_rc(fdtv);
236fail_free:
237 kfree(fdtv);
238
239 return err;
240}
241
242static int node_remove(struct device *dev)
243{
244 struct firedtv *fdtv = dev_get_drvdata(dev);
245
246 fdtv_dvb_unregister(fdtv);
247
248 spin_lock_irq(&node_list_lock);
249 list_del(&fdtv->list);
250 spin_unlock_irq(&node_list_lock);
251
252 fdtv_unregister_rc(fdtv);
253 kfree(fdtv);
254
255 return 0;
256}
257
258static int node_update(struct unit_directory *ud)
259{
260 struct firedtv *fdtv = dev_get_drvdata(&ud->device);
261
262 if (fdtv->isochannel >= 0)
263 cmp_establish_pp_connection(fdtv, fdtv->subunit,
264 fdtv->isochannel);
265 return 0;
266}
267
268static struct hpsb_protocol_driver fdtv_driver = {
269 .name = "firedtv",
270 .id_table = fdtv_id_table,
271 .update = node_update,
272 .driver = {
273 .probe = node_probe,
274 .remove = node_remove,
275 },
276};
277
278static struct hpsb_highlevel fdtv_highlevel = {
279 .name = "firedtv",
280 .fcp_request = fcp_request,
281};
282
283int __init fdtv_1394_init(void)
284{
285 int ret;
286
287 hpsb_register_highlevel(&fdtv_highlevel);
288 ret = hpsb_register_protocol(&fdtv_driver);
289 if (ret) {
290 printk(KERN_ERR "firedtv: failed to register protocol\n");
291 hpsb_unregister_highlevel(&fdtv_highlevel);
292 }
293 return ret;
294}
295
296void __exit fdtv_1394_exit(void)
297{
298 hpsb_unregister_protocol(&fdtv_driver);
299 hpsb_unregister_highlevel(&fdtv_highlevel);
300}
diff --git a/drivers/media/dvb/firewire/firedtv-avc.c b/drivers/media/dvb/firewire/firedtv-avc.c
index f0f1842fab60..fc5ccd8c923a 100644
--- a/drivers/media/dvb/firewire/firedtv-avc.c
+++ b/drivers/media/dvb/firewire/firedtv-avc.c
@@ -241,8 +241,8 @@ static int avc_write(struct firedtv *fdtv)
241 if (unlikely(avc_debug)) 241 if (unlikely(avc_debug))
242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length); 242 debug_fcp(fdtv->avc_data, fdtv->avc_data_length);
243 243
244 err = fdtv->backend->write(fdtv, FCP_COMMAND_REGISTER, 244 err = fdtv_write(fdtv, FCP_COMMAND_REGISTER,
245 fdtv->avc_data, fdtv->avc_data_length); 245 fdtv->avc_data, fdtv->avc_data_length);
246 if (err) { 246 if (err) {
247 dev_err(fdtv->device, "FCP command write failed\n"); 247 dev_err(fdtv->device, "FCP command write failed\n");
248 248
@@ -1322,7 +1322,7 @@ static int cmp_read(struct firedtv *fdtv, u64 addr, __be32 *data)
1322 1322
1323 mutex_lock(&fdtv->avc_mutex); 1323 mutex_lock(&fdtv->avc_mutex);
1324 1324
1325 ret = fdtv->backend->read(fdtv, addr, data); 1325 ret = fdtv_read(fdtv, addr, data);
1326 if (ret < 0) 1326 if (ret < 0)
1327 dev_err(fdtv->device, "CMP: read I/O error\n"); 1327 dev_err(fdtv->device, "CMP: read I/O error\n");
1328 1328
@@ -1340,7 +1340,7 @@ static int cmp_lock(struct firedtv *fdtv, u64 addr, __be32 data[])
1340 /* data[] is stack-allocated and should not be DMA-mapped. */ 1340 /* data[] is stack-allocated and should not be DMA-mapped. */
1341 memcpy(fdtv->avc_data, data, 8); 1341 memcpy(fdtv->avc_data, data, 8);
1342 1342
1343 ret = fdtv->backend->lock(fdtv, addr, fdtv->avc_data); 1343 ret = fdtv_lock(fdtv, addr, fdtv->avc_data);
1344 if (ret < 0) 1344 if (ret < 0)
1345 dev_err(fdtv->device, "CMP: lock I/O error\n"); 1345 dev_err(fdtv->device, "CMP: lock I/O error\n");
1346 else 1346 else
@@ -1405,10 +1405,7 @@ repeat:
1405 /* FIXME: this is for the worst case - optimize */ 1405 /* FIXME: this is for the worst case - optimize */
1406 set_opcr_overhead_id(opcr, 0); 1406 set_opcr_overhead_id(opcr, 0);
1407 1407
1408 /* 1408 /* FIXME: allocate isochronous channel and bandwidth at IRM */
1409 * FIXME: allocate isochronous channel and bandwidth at IRM
1410 * fdtv->backend->alloc_resources(fdtv, channels_mask, bw);
1411 */
1412 } 1409 }
1413 1410
1414 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1); 1411 set_opcr_p2p_connections(opcr, get_opcr_p2p_connections(*opcr) + 1);
@@ -1424,8 +1421,6 @@ repeat:
1424 /* 1421 /*
1425 * FIXME: if old_opcr.P2P_Connections > 0, 1422 * FIXME: if old_opcr.P2P_Connections > 0,
1426 * deallocate isochronous channel and bandwidth at IRM 1423 * deallocate isochronous channel and bandwidth at IRM
1427 * if (...)
1428 * fdtv->backend->dealloc_resources(fdtv, channel, bw);
1429 */ 1424 */
1430 1425
1431 if (++attempts < 6) /* arbitrary limit */ 1426 if (++attempts < 6) /* arbitrary limit */
diff --git a/drivers/media/dvb/firewire/firedtv-dvb.c b/drivers/media/dvb/firewire/firedtv-dvb.c
index 079e8c5b0475..fd8bbbfa5c59 100644
--- a/drivers/media/dvb/firewire/firedtv-dvb.c
+++ b/drivers/media/dvb/firewire/firedtv-dvb.c
@@ -14,14 +14,9 @@
14#include <linux/device.h> 14#include <linux/device.h>
15#include <linux/errno.h> 15#include <linux/errno.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/mod_devicetable.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/mutex.h> 18#include <linux/mutex.h>
20#include <linux/slab.h>
21#include <linux/string.h>
22#include <linux/types.h> 19#include <linux/types.h>
23#include <linux/wait.h>
24#include <linux/workqueue.h>
25 20
26#include <dmxdev.h> 21#include <dmxdev.h>
27#include <dvb_demux.h> 22#include <dvb_demux.h>
@@ -166,11 +161,11 @@ int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
166 161
167DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); 162DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
168 163
169int fdtv_dvb_register(struct firedtv *fdtv) 164int fdtv_dvb_register(struct firedtv *fdtv, const char *name)
170{ 165{
171 int err; 166 int err;
172 167
173 err = dvb_register_adapter(&fdtv->adapter, fdtv_model_names[fdtv->type], 168 err = dvb_register_adapter(&fdtv->adapter, name,
174 THIS_MODULE, fdtv->device, adapter_nr); 169 THIS_MODULE, fdtv->device, adapter_nr);
175 if (err < 0) 170 if (err < 0)
176 goto fail_log; 171 goto fail_log;
@@ -210,7 +205,7 @@ int fdtv_dvb_register(struct firedtv *fdtv)
210 205
211 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx); 206 dvb_net_init(&fdtv->adapter, &fdtv->dvbnet, &fdtv->demux.dmx);
212 207
213 fdtv_frontend_init(fdtv); 208 fdtv_frontend_init(fdtv, name);
214 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe); 209 err = dvb_register_frontend(&fdtv->adapter, &fdtv->fe);
215 if (err) 210 if (err)
216 goto fail_net_release; 211 goto fail_net_release;
@@ -248,127 +243,3 @@ void fdtv_dvb_unregister(struct firedtv *fdtv)
248 dvb_dmx_release(&fdtv->demux); 243 dvb_dmx_release(&fdtv->demux);
249 dvb_unregister_adapter(&fdtv->adapter); 244 dvb_unregister_adapter(&fdtv->adapter);
250} 245}
251
252const char *fdtv_model_names[] = {
253 [FIREDTV_UNKNOWN] = "unknown type",
254 [FIREDTV_DVB_S] = "FireDTV S/CI",
255 [FIREDTV_DVB_C] = "FireDTV C/CI",
256 [FIREDTV_DVB_T] = "FireDTV T/CI",
257 [FIREDTV_DVB_S2] = "FireDTV S2 ",
258};
259
260struct firedtv *fdtv_alloc(struct device *dev,
261 const struct firedtv_backend *backend,
262 const char *name, size_t name_len)
263{
264 struct firedtv *fdtv;
265 int i;
266
267 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
268 if (!fdtv)
269 return NULL;
270
271 dev_set_drvdata(dev, fdtv);
272 fdtv->device = dev;
273 fdtv->isochannel = -1;
274 fdtv->voltage = 0xff;
275 fdtv->tone = 0xff;
276 fdtv->backend = backend;
277
278 mutex_init(&fdtv->avc_mutex);
279 init_waitqueue_head(&fdtv->avc_wait);
280 mutex_init(&fdtv->demux_mutex);
281 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
282
283 for (i = ARRAY_SIZE(fdtv_model_names); --i; )
284 if (strlen(fdtv_model_names[i]) <= name_len &&
285 strncmp(name, fdtv_model_names[i], name_len) == 0)
286 break;
287 fdtv->type = i;
288
289 return fdtv;
290}
291
292#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
293 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
294
295#define DIGITAL_EVERYWHERE_OUI 0x001287
296#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
297#define AVC_SW_VERSION_ENTRY 0x010001
298
299const struct ieee1394_device_id fdtv_id_table[] = {
300 {
301 /* FloppyDTV S/CI and FloppyDTV S2 */
302 .match_flags = MATCH_FLAGS,
303 .vendor_id = DIGITAL_EVERYWHERE_OUI,
304 .model_id = 0x000024,
305 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
306 .version = AVC_SW_VERSION_ENTRY,
307 }, {
308 /* FloppyDTV T/CI */
309 .match_flags = MATCH_FLAGS,
310 .vendor_id = DIGITAL_EVERYWHERE_OUI,
311 .model_id = 0x000025,
312 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
313 .version = AVC_SW_VERSION_ENTRY,
314 }, {
315 /* FloppyDTV C/CI */
316 .match_flags = MATCH_FLAGS,
317 .vendor_id = DIGITAL_EVERYWHERE_OUI,
318 .model_id = 0x000026,
319 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
320 .version = AVC_SW_VERSION_ENTRY,
321 }, {
322 /* FireDTV S/CI and FloppyDTV S2 */
323 .match_flags = MATCH_FLAGS,
324 .vendor_id = DIGITAL_EVERYWHERE_OUI,
325 .model_id = 0x000034,
326 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
327 .version = AVC_SW_VERSION_ENTRY,
328 }, {
329 /* FireDTV T/CI */
330 .match_flags = MATCH_FLAGS,
331 .vendor_id = DIGITAL_EVERYWHERE_OUI,
332 .model_id = 0x000035,
333 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
334 .version = AVC_SW_VERSION_ENTRY,
335 }, {
336 /* FireDTV C/CI */
337 .match_flags = MATCH_FLAGS,
338 .vendor_id = DIGITAL_EVERYWHERE_OUI,
339 .model_id = 0x000036,
340 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
341 .version = AVC_SW_VERSION_ENTRY,
342 }, {}
343};
344MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
345
346static int __init fdtv_init(void)
347{
348 int ret;
349
350 ret = fdtv_fw_init();
351 if (ret < 0)
352 return ret;
353
354 ret = fdtv_1394_init();
355 if (ret < 0)
356 fdtv_fw_exit();
357
358 return ret;
359}
360
361static void __exit fdtv_exit(void)
362{
363 fdtv_1394_exit();
364 fdtv_fw_exit();
365}
366
367module_init(fdtv_init);
368module_exit(fdtv_exit);
369
370MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
371MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
372MODULE_DESCRIPTION("FireDTV DVB Driver");
373MODULE_LICENSE("GPL");
374MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv-fe.c b/drivers/media/dvb/firewire/firedtv-fe.c
index d10920e2f3a2..8748a61be73d 100644
--- a/drivers/media/dvb/firewire/firedtv-fe.c
+++ b/drivers/media/dvb/firewire/firedtv-fe.c
@@ -36,14 +36,14 @@ static int fdtv_dvb_init(struct dvb_frontend *fe)
36 return err; 36 return err;
37 } 37 }
38 38
39 return fdtv->backend->start_iso(fdtv); 39 return fdtv_start_iso(fdtv);
40} 40}
41 41
42static int fdtv_sleep(struct dvb_frontend *fe) 42static int fdtv_sleep(struct dvb_frontend *fe)
43{ 43{
44 struct firedtv *fdtv = fe->sec_priv; 44 struct firedtv *fdtv = fe->sec_priv;
45 45
46 fdtv->backend->stop_iso(fdtv); 46 fdtv_stop_iso(fdtv);
47 cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel); 47 cmp_break_pp_connection(fdtv, fdtv->subunit, fdtv->isochannel);
48 fdtv->isochannel = -1; 48 fdtv->isochannel = -1;
49 return 0; 49 return 0;
@@ -165,7 +165,7 @@ static int fdtv_set_property(struct dvb_frontend *fe, struct dtv_property *tvp)
165 return 0; 165 return 0;
166} 166}
167 167
168void fdtv_frontend_init(struct firedtv *fdtv) 168void fdtv_frontend_init(struct firedtv *fdtv, const char *name)
169{ 169{
170 struct dvb_frontend_ops *ops = &fdtv->fe.ops; 170 struct dvb_frontend_ops *ops = &fdtv->fe.ops;
171 struct dvb_frontend_info *fi = &ops->info; 171 struct dvb_frontend_info *fi = &ops->info;
@@ -266,7 +266,7 @@ void fdtv_frontend_init(struct firedtv *fdtv)
266 dev_err(fdtv->device, "no frontend for model type %d\n", 266 dev_err(fdtv->device, "no frontend for model type %d\n",
267 fdtv->type); 267 fdtv->type);
268 } 268 }
269 strcpy(fi->name, fdtv_model_names[fdtv->type]); 269 strcpy(fi->name, name);
270 270
271 fdtv->fe.dvb = &fdtv->adapter; 271 fdtv->fe.dvb = &fdtv->adapter;
272 fdtv->fe.sec_priv = fdtv; 272 fdtv->fe.sec_priv = fdtv;
diff --git a/drivers/media/dvb/firewire/firedtv-fw.c b/drivers/media/dvb/firewire/firedtv-fw.c
index 7424b0493f9d..8022b743af91 100644
--- a/drivers/media/dvb/firewire/firedtv-fw.c
+++ b/drivers/media/dvb/firewire/firedtv-fw.c
@@ -9,11 +9,18 @@
9#include <linux/kernel.h> 9#include <linux/kernel.h>
10#include <linux/list.h> 10#include <linux/list.h>
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/mod_devicetable.h>
13#include <linux/module.h>
14#include <linux/mutex.h>
12#include <linux/slab.h> 15#include <linux/slab.h>
13#include <linux/spinlock.h> 16#include <linux/spinlock.h>
17#include <linux/string.h>
14#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/wait.h>
20#include <linux/workqueue.h>
15 21
16#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/system.h>
17 24
18#include <dvb_demux.h> 25#include <dvb_demux.h>
19 26
@@ -41,17 +48,17 @@ static int node_req(struct firedtv *fdtv, u64 addr, void *data, size_t len,
41 return rcode != RCODE_COMPLETE ? -EIO : 0; 48 return rcode != RCODE_COMPLETE ? -EIO : 0;
42} 49}
43 50
44static int node_lock(struct firedtv *fdtv, u64 addr, void *data) 51int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data)
45{ 52{
46 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP); 53 return node_req(fdtv, addr, data, 8, TCODE_LOCK_COMPARE_SWAP);
47} 54}
48 55
49static int node_read(struct firedtv *fdtv, u64 addr, void *data) 56int fdtv_read(struct firedtv *fdtv, u64 addr, void *data)
50{ 57{
51 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST); 58 return node_req(fdtv, addr, data, 4, TCODE_READ_QUADLET_REQUEST);
52} 59}
53 60
54static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len) 61int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
55{ 62{
56 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST); 63 return node_req(fdtv, addr, data, len, TCODE_WRITE_BLOCK_REQUEST);
57} 64}
@@ -67,7 +74,7 @@ static int node_write(struct firedtv *fdtv, u64 addr, void *data, size_t len)
67#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE) 74#define N_PAGES DIV_ROUND_UP(N_PACKETS, PACKETS_PER_PAGE)
68#define IRQ_INTERVAL 16 75#define IRQ_INTERVAL 16
69 76
70struct firedtv_receive_context { 77struct fdtv_ir_context {
71 struct fw_iso_context *context; 78 struct fw_iso_context *context;
72 struct fw_iso_buffer buffer; 79 struct fw_iso_buffer buffer;
73 int interrupt_packet; 80 int interrupt_packet;
@@ -75,7 +82,7 @@ struct firedtv_receive_context {
75 char *pages[N_PAGES]; 82 char *pages[N_PAGES];
76}; 83};
77 84
78static int queue_iso(struct firedtv_receive_context *ctx, int index) 85static int queue_iso(struct fdtv_ir_context *ctx, int index)
79{ 86{
80 struct fw_iso_packet p; 87 struct fw_iso_packet p;
81 88
@@ -92,7 +99,7 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
92 size_t header_length, void *header, void *data) 99 size_t header_length, void *header, void *data)
93{ 100{
94 struct firedtv *fdtv = data; 101 struct firedtv *fdtv = data;
95 struct firedtv_receive_context *ctx = fdtv->backend_data; 102 struct fdtv_ir_context *ctx = fdtv->ir_context;
96 __be32 *h, *h_end; 103 __be32 *h, *h_end;
97 int length, err, i = ctx->current_packet; 104 int length, err, i = ctx->current_packet;
98 char *p, *p_end; 105 char *p, *p_end;
@@ -121,9 +128,9 @@ static void handle_iso(struct fw_iso_context *context, u32 cycle,
121 ctx->current_packet = i; 128 ctx->current_packet = i;
122} 129}
123 130
124static int start_iso(struct firedtv *fdtv) 131int fdtv_start_iso(struct firedtv *fdtv)
125{ 132{
126 struct firedtv_receive_context *ctx; 133 struct fdtv_ir_context *ctx;
127 struct fw_device *device = device_of(fdtv); 134 struct fw_device *device = device_of(fdtv);
128 int i, err; 135 int i, err;
129 136
@@ -161,7 +168,7 @@ static int start_iso(struct firedtv *fdtv)
161 if (err) 168 if (err)
162 goto fail; 169 goto fail;
163 170
164 fdtv->backend_data = ctx; 171 fdtv->ir_context = ctx;
165 172
166 return 0; 173 return 0;
167fail: 174fail:
@@ -174,9 +181,9 @@ fail_free:
174 return err; 181 return err;
175} 182}
176 183
177static void stop_iso(struct firedtv *fdtv) 184void fdtv_stop_iso(struct firedtv *fdtv)
178{ 185{
179 struct firedtv_receive_context *ctx = fdtv->backend_data; 186 struct fdtv_ir_context *ctx = fdtv->ir_context;
180 187
181 fw_iso_context_stop(ctx->context); 188 fw_iso_context_stop(ctx->context);
182 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card); 189 fw_iso_buffer_destroy(&ctx->buffer, device_of(fdtv)->card);
@@ -184,14 +191,6 @@ static void stop_iso(struct firedtv *fdtv)
184 kfree(ctx); 191 kfree(ctx);
185} 192}
186 193
187static const struct firedtv_backend backend = {
188 .lock = node_lock,
189 .read = node_read,
190 .write = node_write,
191 .start_iso = start_iso,
192 .stop_iso = stop_iso,
193};
194
195static void handle_fcp(struct fw_card *card, struct fw_request *request, 194static void handle_fcp(struct fw_card *card, struct fw_request *request,
196 int tcode, int destination, int source, int generation, 195 int tcode, int destination, int source, int generation,
197 unsigned long long offset, void *payload, size_t length, 196 unsigned long long offset, void *payload, size_t length,
@@ -238,6 +237,14 @@ static const struct fw_address_region fcp_region = {
238 .end = CSR_REGISTER_BASE + CSR_FCP_END, 237 .end = CSR_REGISTER_BASE + CSR_FCP_END,
239}; 238};
240 239
240static const char * const model_names[] = {
241 [FIREDTV_UNKNOWN] = "unknown type",
242 [FIREDTV_DVB_S] = "FireDTV S/CI",
243 [FIREDTV_DVB_C] = "FireDTV C/CI",
244 [FIREDTV_DVB_T] = "FireDTV T/CI",
245 [FIREDTV_DVB_S2] = "FireDTV S2 ",
246};
247
241/* Adjust the template string if models with longer names appear. */ 248/* Adjust the template string if models with longer names appear. */
242#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????") 249#define MAX_MODEL_NAME_LEN sizeof("FireDTV ????")
243 250
@@ -245,15 +252,31 @@ static int node_probe(struct device *dev)
245{ 252{
246 struct firedtv *fdtv; 253 struct firedtv *fdtv;
247 char name[MAX_MODEL_NAME_LEN]; 254 char name[MAX_MODEL_NAME_LEN];
248 int name_len, err; 255 int name_len, i, err;
249
250 name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
251 name, sizeof(name));
252 256
253 fdtv = fdtv_alloc(dev, &backend, name, name_len >= 0 ? name_len : 0); 257 fdtv = kzalloc(sizeof(*fdtv), GFP_KERNEL);
254 if (!fdtv) 258 if (!fdtv)
255 return -ENOMEM; 259 return -ENOMEM;
256 260
261 dev_set_drvdata(dev, fdtv);
262 fdtv->device = dev;
263 fdtv->isochannel = -1;
264 fdtv->voltage = 0xff;
265 fdtv->tone = 0xff;
266
267 mutex_init(&fdtv->avc_mutex);
268 init_waitqueue_head(&fdtv->avc_wait);
269 mutex_init(&fdtv->demux_mutex);
270 INIT_WORK(&fdtv->remote_ctrl_work, avc_remote_ctrl_work);
271
272 name_len = fw_csr_string(fw_unit(dev)->directory, CSR_MODEL,
273 name, sizeof(name));
274 for (i = ARRAY_SIZE(model_names); --i; )
275 if (strlen(model_names[i]) <= name_len &&
276 strncmp(name, model_names[i], name_len) == 0)
277 break;
278 fdtv->type = i;
279
257 err = fdtv_register_rc(fdtv, dev); 280 err = fdtv_register_rc(fdtv, dev);
258 if (err) 281 if (err)
259 goto fail_free; 282 goto fail_free;
@@ -266,7 +289,7 @@ static int node_probe(struct device *dev)
266 if (err) 289 if (err)
267 goto fail; 290 goto fail;
268 291
269 err = fdtv_dvb_register(fdtv); 292 err = fdtv_dvb_register(fdtv, model_names[fdtv->type]);
270 if (err) 293 if (err)
271 goto fail; 294 goto fail;
272 295
@@ -309,6 +332,60 @@ static void node_update(struct fw_unit *unit)
309 fdtv->isochannel); 332 fdtv->isochannel);
310} 333}
311 334
335#define MATCH_FLAGS (IEEE1394_MATCH_VENDOR_ID | IEEE1394_MATCH_MODEL_ID | \
336 IEEE1394_MATCH_SPECIFIER_ID | IEEE1394_MATCH_VERSION)
337
338#define DIGITAL_EVERYWHERE_OUI 0x001287
339#define AVC_UNIT_SPEC_ID_ENTRY 0x00a02d
340#define AVC_SW_VERSION_ENTRY 0x010001
341
342static const struct ieee1394_device_id fdtv_id_table[] = {
343 {
344 /* FloppyDTV S/CI and FloppyDTV S2 */
345 .match_flags = MATCH_FLAGS,
346 .vendor_id = DIGITAL_EVERYWHERE_OUI,
347 .model_id = 0x000024,
348 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
349 .version = AVC_SW_VERSION_ENTRY,
350 }, {
351 /* FloppyDTV T/CI */
352 .match_flags = MATCH_FLAGS,
353 .vendor_id = DIGITAL_EVERYWHERE_OUI,
354 .model_id = 0x000025,
355 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
356 .version = AVC_SW_VERSION_ENTRY,
357 }, {
358 /* FloppyDTV C/CI */
359 .match_flags = MATCH_FLAGS,
360 .vendor_id = DIGITAL_EVERYWHERE_OUI,
361 .model_id = 0x000026,
362 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
363 .version = AVC_SW_VERSION_ENTRY,
364 }, {
365 /* FireDTV S/CI and FloppyDTV S2 */
366 .match_flags = MATCH_FLAGS,
367 .vendor_id = DIGITAL_EVERYWHERE_OUI,
368 .model_id = 0x000034,
369 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
370 .version = AVC_SW_VERSION_ENTRY,
371 }, {
372 /* FireDTV T/CI */
373 .match_flags = MATCH_FLAGS,
374 .vendor_id = DIGITAL_EVERYWHERE_OUI,
375 .model_id = 0x000035,
376 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
377 .version = AVC_SW_VERSION_ENTRY,
378 }, {
379 /* FireDTV C/CI */
380 .match_flags = MATCH_FLAGS,
381 .vendor_id = DIGITAL_EVERYWHERE_OUI,
382 .model_id = 0x000036,
383 .specifier_id = AVC_UNIT_SPEC_ID_ENTRY,
384 .version = AVC_SW_VERSION_ENTRY,
385 }, {}
386};
387MODULE_DEVICE_TABLE(ieee1394, fdtv_id_table);
388
312static struct fw_driver fdtv_driver = { 389static struct fw_driver fdtv_driver = {
313 .driver = { 390 .driver = {
314 .owner = THIS_MODULE, 391 .owner = THIS_MODULE,
@@ -321,7 +398,7 @@ static struct fw_driver fdtv_driver = {
321 .id_table = fdtv_id_table, 398 .id_table = fdtv_id_table,
322}; 399};
323 400
324int __init fdtv_fw_init(void) 401static int __init fdtv_init(void)
325{ 402{
326 int ret; 403 int ret;
327 404
@@ -329,11 +406,24 @@ int __init fdtv_fw_init(void)
329 if (ret < 0) 406 if (ret < 0)
330 return ret; 407 return ret;
331 408
332 return driver_register(&fdtv_driver.driver); 409 ret = driver_register(&fdtv_driver.driver);
410 if (ret < 0)
411 fw_core_remove_address_handler(&fcp_handler);
412
413 return ret;
333} 414}
334 415
335void fdtv_fw_exit(void) 416static void __exit fdtv_exit(void)
336{ 417{
337 driver_unregister(&fdtv_driver.driver); 418 driver_unregister(&fdtv_driver.driver);
338 fw_core_remove_address_handler(&fcp_handler); 419 fw_core_remove_address_handler(&fcp_handler);
339} 420}
421
422module_init(fdtv_init);
423module_exit(fdtv_exit);
424
425MODULE_AUTHOR("Andreas Monitzer <andy@monitzer.com>");
426MODULE_AUTHOR("Ben Backx <ben@bbackx.com>");
427MODULE_DESCRIPTION("FireDTV DVB Driver");
428MODULE_LICENSE("GPL");
429MODULE_SUPPORTED_DEVICE("FireDTV DVB");
diff --git a/drivers/media/dvb/firewire/firedtv.h b/drivers/media/dvb/firewire/firedtv.h
index 78cc28f36914..bd00b04e079d 100644
--- a/drivers/media/dvb/firewire/firedtv.h
+++ b/drivers/media/dvb/firewire/firedtv.h
@@ -70,15 +70,7 @@ enum model_type {
70 70
71struct device; 71struct device;
72struct input_dev; 72struct input_dev;
73struct firedtv; 73struct fdtv_ir_context;
74
75struct firedtv_backend {
76 int (*lock)(struct firedtv *fdtv, u64 addr, void *data);
77 int (*read)(struct firedtv *fdtv, u64 addr, void *data);
78 int (*write)(struct firedtv *fdtv, u64 addr, void *data, size_t len);
79 int (*start_iso)(struct firedtv *fdtv);
80 void (*stop_iso)(struct firedtv *fdtv);
81};
82 74
83struct firedtv { 75struct firedtv {
84 struct device *device; 76 struct device *device;
@@ -104,12 +96,11 @@ struct firedtv {
104 enum model_type type; 96 enum model_type type;
105 char subunit; 97 char subunit;
106 char isochannel; 98 char isochannel;
99 struct fdtv_ir_context *ir_context;
100
107 fe_sec_voltage_t voltage; 101 fe_sec_voltage_t voltage;
108 fe_sec_tone_mode_t tone; 102 fe_sec_tone_mode_t tone;
109 103
110 const struct firedtv_backend *backend;
111 void *backend_data;
112
113 struct mutex demux_mutex; 104 struct mutex demux_mutex;
114 unsigned long channel_active; 105 unsigned long channel_active;
115 u16 channel_pid[16]; 106 u16 channel_pid[16];
@@ -118,15 +109,6 @@ struct firedtv {
118 u8 avc_data[512]; 109 u8 avc_data[512];
119}; 110};
120 111
121/* firedtv-1394.c */
122#ifdef CONFIG_DVB_FIREDTV_IEEE1394
123int fdtv_1394_init(void);
124void fdtv_1394_exit(void);
125#else
126static inline int fdtv_1394_init(void) { return 0; }
127static inline void fdtv_1394_exit(void) {}
128#endif
129
130/* firedtv-avc.c */ 112/* firedtv-avc.c */
131int avc_recv(struct firedtv *fdtv, void *data, size_t length); 113int avc_recv(struct firedtv *fdtv, void *data, size_t length);
132int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat); 114int avc_tuner_status(struct firedtv *fdtv, struct firedtv_tuner_status *stat);
@@ -158,25 +140,18 @@ void fdtv_ca_release(struct firedtv *fdtv);
158/* firedtv-dvb.c */ 140/* firedtv-dvb.c */
159int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed); 141int fdtv_start_feed(struct dvb_demux_feed *dvbdmxfeed);
160int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed); 142int fdtv_stop_feed(struct dvb_demux_feed *dvbdmxfeed);
161int fdtv_dvb_register(struct firedtv *fdtv); 143int fdtv_dvb_register(struct firedtv *fdtv, const char *name);
162void fdtv_dvb_unregister(struct firedtv *fdtv); 144void fdtv_dvb_unregister(struct firedtv *fdtv);
163struct firedtv *fdtv_alloc(struct device *dev,
164 const struct firedtv_backend *backend,
165 const char *name, size_t name_len);
166extern const char *fdtv_model_names[];
167extern const struct ieee1394_device_id fdtv_id_table[];
168 145
169/* firedtv-fe.c */ 146/* firedtv-fe.c */
170void fdtv_frontend_init(struct firedtv *fdtv); 147void fdtv_frontend_init(struct firedtv *fdtv, const char *name);
171 148
172/* firedtv-fw.c */ 149/* firedtv-fw.c */
173#ifdef CONFIG_DVB_FIREDTV_FIREWIRE 150int fdtv_lock(struct firedtv *fdtv, u64 addr, void *data);
174int fdtv_fw_init(void); 151int fdtv_read(struct firedtv *fdtv, u64 addr, void *data);
175void fdtv_fw_exit(void); 152int fdtv_write(struct firedtv *fdtv, u64 addr, void *data, size_t len);
176#else 153int fdtv_start_iso(struct firedtv *fdtv);
177static inline int fdtv_fw_init(void) { return 0; } 154void fdtv_stop_iso(struct firedtv *fdtv);
178static inline void fdtv_fw_exit(void) {}
179#endif
180 155
181/* firedtv-rc.c */ 156/* firedtv-rc.c */
182#ifdef CONFIG_DVB_FIREDTV_INPUT 157#ifdef CONFIG_DVB_FIREDTV_INPUT
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index b8519ba511e5..83093d1f4f74 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -349,6 +349,14 @@ config DVB_DIB7000P
349 A DVB-T tuner module. Designed for mobile usage. Say Y when you want 349 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
350 to support this frontend. 350 to support this frontend.
351 351
352config DVB_DIB9000
353 tristate "DiBcom 9000"
354 depends on DVB_CORE && I2C
355 default m if DVB_FE_CUSTOMISE
356 help
357 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
358 to support this frontend.
359
352config DVB_TDA10048 360config DVB_TDA10048
353 tristate "Philips TDA10048HN based" 361 tristate "Philips TDA10048HN based"
354 depends on DVB_CORE && I2C 362 depends on DVB_CORE && I2C
@@ -370,6 +378,13 @@ config DVB_EC100
370 help 378 help
371 Say Y when you want to support this frontend. 379 Say Y when you want to support this frontend.
372 380
381config DVB_STV0367
382 tristate "ST STV0367 based"
383 depends on DVB_CORE && I2C
384 default m if DVB_FE_CUSTOMISE
385 help
386 A DVB-T/C tuner module. Say Y when you want to support this frontend.
387
373comment "DVB-C (cable) frontends" 388comment "DVB-C (cable) frontends"
374 depends on DVB_CORE 389 depends on DVB_CORE
375 390
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index b1d9525aa7e3..3b0c4bdc4b2b 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -24,6 +24,7 @@ obj-$(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_DIB8000) += dib8000.o dibx000_common.o
27obj-$(CONFIG_DVB_DIB9000) += dib9000.o dibx000_common.o
27obj-$(CONFIG_DVB_MT312) += mt312.o 28obj-$(CONFIG_DVB_MT312) += mt312.o
28obj-$(CONFIG_DVB_VES1820) += ves1820.o 29obj-$(CONFIG_DVB_VES1820) += ves1820.o
29obj-$(CONFIG_DVB_VES1X93) += ves1x93.o 30obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -83,3 +84,4 @@ obj-$(CONFIG_DVB_DS3000) += ds3000.o
83obj-$(CONFIG_DVB_MB86A16) += mb86a16.o 84obj-$(CONFIG_DVB_MB86A16) += mb86a16.o
84obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o 85obj-$(CONFIG_DVB_MB86A20S) += mb86a20s.o
85obj-$(CONFIG_DVB_IX2505V) += ix2505v.o 86obj-$(CONFIG_DVB_IX2505V) += ix2505v.o
87obj-$(CONFIG_DVB_STV0367) += stv0367.o
diff --git a/drivers/media/dvb/frontends/af9013.c b/drivers/media/dvb/frontends/af9013.c
index ba25fa0b0fc2..345311c33383 100644
--- a/drivers/media/dvb/frontends/af9013.c
+++ b/drivers/media/dvb/frontends/af9013.c
@@ -1323,13 +1323,11 @@ static struct dvb_frontend_ops af9013_ops;
1323 1323
1324static int af9013_download_firmware(struct af9013_state *state) 1324static int af9013_download_firmware(struct af9013_state *state)
1325{ 1325{
1326 int i, len, packets, remainder, ret; 1326 int i, len, remaining, ret;
1327 const struct firmware *fw; 1327 const struct firmware *fw;
1328 u16 addr = 0x5100; /* firmware start address */
1329 u16 checksum = 0; 1328 u16 checksum = 0;
1330 u8 val; 1329 u8 val;
1331 u8 fw_params[4]; 1330 u8 fw_params[4];
1332 u8 *data;
1333 u8 *fw_file = AF9013_DEFAULT_FIRMWARE; 1331 u8 *fw_file = AF9013_DEFAULT_FIRMWARE;
1334 1332
1335 msleep(100); 1333 msleep(100);
@@ -1373,21 +1371,18 @@ static int af9013_download_firmware(struct af9013_state *state)
1373 if (ret) 1371 if (ret)
1374 goto error_release; 1372 goto error_release;
1375 1373
1376 #define FW_PACKET_MAX_DATA 16 1374 #define FW_ADDR 0x5100 /* firmware start address */
1377 1375 #define LEN_MAX 16 /* max packet size */
1378 packets = fw->size / FW_PACKET_MAX_DATA; 1376 for (remaining = fw->size; remaining > 0; remaining -= LEN_MAX) {
1379 remainder = fw->size % FW_PACKET_MAX_DATA; 1377 len = remaining;
1380 len = FW_PACKET_MAX_DATA; 1378 if (len > LEN_MAX)
1381 for (i = 0; i <= packets; i++) { 1379 len = LEN_MAX;
1382 if (i == packets) /* set size of the last packet */
1383 len = remainder;
1384
1385 data = (u8 *)(fw->data + i * FW_PACKET_MAX_DATA);
1386 ret = af9013_write_ofsm_regs(state, addr, data, len);
1387 addr += FW_PACKET_MAX_DATA;
1388 1380
1381 ret = af9013_write_ofsm_regs(state,
1382 FW_ADDR + fw->size - remaining,
1383 (u8 *) &fw->data[fw->size - remaining], len);
1389 if (ret) { 1384 if (ret) {
1390 err("firmware download failed at %d with %d", i, ret); 1385 err("firmware download failed:%d", ret);
1391 goto error_release; 1386 goto error_release;
1392 } 1387 }
1393 } 1388 }
@@ -1466,20 +1461,6 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1466 state->i2c = i2c; 1461 state->i2c = i2c;
1467 memcpy(&state->config, config, sizeof(struct af9013_config)); 1462 memcpy(&state->config, config, sizeof(struct af9013_config));
1468 1463
1469 /* chip version */
1470 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1471 if (ret)
1472 goto error;
1473
1474 /* ROM version */
1475 for (i = 0; i < 2; i++) {
1476 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1477 if (ret)
1478 goto error;
1479 }
1480 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1481 buf[2], buf[0], buf[1]);
1482
1483 /* download firmware */ 1464 /* download firmware */
1484 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) { 1465 if (state->config.output_mode != AF9013_OUTPUT_MODE_USB) {
1485 ret = af9013_download_firmware(state); 1466 ret = af9013_download_firmware(state);
@@ -1495,6 +1476,20 @@ struct dvb_frontend *af9013_attach(const struct af9013_config *config,
1495 } 1476 }
1496 info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]); 1477 info("firmware version:%d.%d.%d.%d", buf[0], buf[1], buf[2], buf[3]);
1497 1478
1479 /* chip version */
1480 ret = af9013_read_reg_bits(state, 0xd733, 4, 4, &buf[2]);
1481 if (ret)
1482 goto error;
1483
1484 /* ROM version */
1485 for (i = 0; i < 2; i++) {
1486 ret = af9013_read_reg(state, 0x116b + i, &buf[i]);
1487 if (ret)
1488 goto error;
1489 }
1490 deb_info("%s: chip version:%d ROM version:%d.%d\n", __func__,
1491 buf[2], buf[0], buf[1]);
1492
1498 /* settings for mp2if */ 1493 /* settings for mp2if */
1499 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) { 1494 if (state->config.output_mode == AF9013_OUTPUT_MODE_USB) {
1500 /* AF9015 split PSB to 1.5k + 0.5k */ 1495 /* AF9015 split PSB to 1.5k + 0.5k */
diff --git a/drivers/media/dvb/frontends/dib0090.c b/drivers/media/dvb/frontends/dib0090.c
index 65240b7801e8..52ff1a252a90 100644
--- a/drivers/media/dvb/frontends/dib0090.c
+++ b/drivers/media/dvb/frontends/dib0090.c
@@ -45,6 +45,7 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
45 } \ 45 } \
46} while (0) 46} while (0)
47 47
48#define CONFIG_SYS_DVBT
48#define CONFIG_SYS_ISDBT 49#define CONFIG_SYS_ISDBT
49#define CONFIG_BAND_CBAND 50#define CONFIG_BAND_CBAND
50#define CONFIG_BAND_VHF 51#define CONFIG_BAND_VHF
@@ -76,6 +77,34 @@ MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
76#define EN_SBD 0x44E9 77#define EN_SBD 0x44E9
77#define EN_CAB 0x88E9 78#define EN_CAB 0x88E9
78 79
80/* Calibration defines */
81#define DC_CAL 0x1
82#define WBD_CAL 0x2
83#define TEMP_CAL 0x4
84#define CAPTRIM_CAL 0x8
85
86#define KROSUS_PLL_LOCKED 0x800
87#define KROSUS 0x2
88
89/* Use those defines to identify SOC version */
90#define SOC 0x02
91#define SOC_7090_P1G_11R1 0x82
92#define SOC_7090_P1G_21R1 0x8a
93#define SOC_8090_P1G_11R1 0x86
94#define SOC_8090_P1G_21R1 0x8e
95
96/* else use thos ones to check */
97#define P1A_B 0x0
98#define P1C 0x1
99#define P1D_E_F 0x3
100#define P1G 0x7
101#define P1G_21R2 0xf
102
103#define MP001 0x1 /* Single 9090/8096 */
104#define MP005 0x4 /* Single Sband */
105#define MP008 0x6 /* Dual diversity VHF-UHF-LBAND */
106#define MP009 0x7 /* Dual diversity 29098 CBAND-UHF-LBAND-SBAND */
107
79#define pgm_read_word(w) (*w) 108#define pgm_read_word(w) (*w)
80 109
81struct dc_calibration; 110struct dc_calibration;
@@ -84,7 +113,7 @@ struct dib0090_tuning {
84 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */ 113 u32 max_freq; /* for every frequency less than or equal to that field: this information is correct */
85 u8 switch_trim; 114 u8 switch_trim;
86 u8 lna_tune; 115 u8 lna_tune;
87 u8 lna_bias; 116 u16 lna_bias;
88 u16 v2i; 117 u16 v2i;
89 u16 mix; 118 u16 mix;
90 u16 load; 119 u16 load;
@@ -99,13 +128,19 @@ struct dib0090_pll {
99 u8 topresc; 128 u8 topresc;
100}; 129};
101 130
131struct dib0090_identity {
132 u8 version;
133 u8 product;
134 u8 p1g;
135 u8 in_soc;
136};
137
102struct dib0090_state { 138struct dib0090_state {
103 struct i2c_adapter *i2c; 139 struct i2c_adapter *i2c;
104 struct dvb_frontend *fe; 140 struct dvb_frontend *fe;
105 const struct dib0090_config *config; 141 const struct dib0090_config *config;
106 142
107 u8 current_band; 143 u8 current_band;
108 u16 revision;
109 enum frontend_tune_state tune_state; 144 enum frontend_tune_state tune_state;
110 u32 current_rf; 145 u32 current_rf;
111 146
@@ -143,7 +178,26 @@ struct dib0090_state {
143 u8 tuner_is_tuned; 178 u8 tuner_is_tuned;
144 u8 agc_freeze; 179 u8 agc_freeze;
145 180
146 u8 reset; 181 struct dib0090_identity identity;
182
183 u32 rf_request;
184 u8 current_standard;
185
186 u8 calibrate;
187 u32 rest;
188 u16 bias;
189 s16 temperature;
190
191 u8 wbd_calibration_gain;
192 const struct dib0090_wbd_slope *current_wbd_table;
193 u16 wbdmux;
194};
195
196struct dib0090_fw_state {
197 struct i2c_adapter *i2c;
198 struct dvb_frontend *fe;
199 struct dib0090_identity identity;
200 const struct dib0090_config *config;
147}; 201};
148 202
149static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg) 203static u16 dib0090_read_reg(struct dib0090_state *state, u8 reg)
@@ -171,6 +225,28 @@ static int dib0090_write_reg(struct dib0090_state *state, u32 reg, u16 val)
171 return 0; 225 return 0;
172} 226}
173 227
228static u16 dib0090_fw_read_reg(struct dib0090_fw_state *state, u8 reg)
229{
230 u8 b[2];
231 struct i2c_msg msg = {.addr = reg, .flags = I2C_M_RD, .buf = b, .len = 2 };
232 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
233 printk(KERN_WARNING "DiB0090 I2C read failed\n");
234 return 0;
235 }
236 return (b[0] << 8) | b[1];
237}
238
239static int dib0090_fw_write_reg(struct dib0090_fw_state *state, u8 reg, u16 val)
240{
241 u8 b[2] = { val >> 8, val & 0xff };
242 struct i2c_msg msg = {.addr = reg, .flags = 0, .buf = b, .len = 2 };
243 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
244 printk(KERN_WARNING "DiB0090 I2C write failed\n");
245 return -EREMOTEIO;
246 }
247 return 0;
248}
249
174#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0) 250#define HARD_RESET(state) do { if (cfg->reset) { if (cfg->sleep) cfg->sleep(fe, 0); msleep(10); cfg->reset(fe, 1); msleep(10); cfg->reset(fe, 0); msleep(10); } } while (0)
175#define ADC_TARGET -220 251#define ADC_TARGET -220
176#define GAIN_ALPHA 5 252#define GAIN_ALPHA 5
@@ -183,89 +259,327 @@ static void dib0090_write_regs(struct dib0090_state *state, u8 r, const u16 * b,
183 } while (--c); 259 } while (--c);
184} 260}
185 261
186static u16 dib0090_identify(struct dvb_frontend *fe) 262static int dib0090_identify(struct dvb_frontend *fe)
187{ 263{
188 struct dib0090_state *state = fe->tuner_priv; 264 struct dib0090_state *state = fe->tuner_priv;
189 u16 v; 265 u16 v;
266 struct dib0090_identity *identity = &state->identity;
190 267
191 v = dib0090_read_reg(state, 0x1a); 268 v = dib0090_read_reg(state, 0x1a);
192 269
193#ifdef FIRMWARE_FIREFLY 270 identity->p1g = 0;
194 /* pll is not locked locked */ 271 identity->in_soc = 0;
195 if (!(v & 0x800)) 272
196 dprintk("FE%d : Identification : pll is not yet locked", fe->id); 273 dprintk("Tuner identification (Version = 0x%04x)", v);
197#endif
198 274
199 /* without PLL lock info */ 275 /* without PLL lock info */
200 v &= 0x3ff; 276 v &= ~KROSUS_PLL_LOCKED;
201 dprintk("P/V: %04x:", v);
202 277
203 if ((v >> 8) & 0xf) 278 identity->version = v & 0xff;
204 dprintk("FE%d : Product ID = 0x%x : KROSUS", fe->id, (v >> 8) & 0xf); 279 identity->product = (v >> 8) & 0xf;
205 else 280
206 return 0xff; 281 if (identity->product != KROSUS)
207 282 goto identification_error;
208 v &= 0xff; 283
209 if (((v >> 5) & 0x7) == 0x1) 284 if ((identity->version & 0x3) == SOC) {
210 dprintk("FE%d : MP001 : 9090/8096", fe->id); 285 identity->in_soc = 1;
211 else if (((v >> 5) & 0x7) == 0x4) 286 switch (identity->version) {
212 dprintk("FE%d : MP005 : Single Sband", fe->id); 287 case SOC_8090_P1G_11R1:
213 else if (((v >> 5) & 0x7) == 0x6) 288 dprintk("SOC 8090 P1-G11R1 Has been detected");
214 dprintk("FE%d : MP008 : diversity VHF-UHF-LBAND", fe->id); 289 identity->p1g = 1;
215 else if (((v >> 5) & 0x7) == 0x7) 290 break;
216 dprintk("FE%d : MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND", fe->id); 291 case SOC_8090_P1G_21R1:
217 else 292 dprintk("SOC 8090 P1-G21R1 Has been detected");
218 return 0xff; 293 identity->p1g = 1;
219 294 break;
220 /* revision only */ 295 case SOC_7090_P1G_11R1:
221 if ((v & 0x1f) == 0x3) 296 dprintk("SOC 7090 P1-G11R1 Has been detected");
222 dprintk("FE%d : P1-D/E/F detected", fe->id); 297 identity->p1g = 1;
223 else if ((v & 0x1f) == 0x1) 298 break;
224 dprintk("FE%d : P1C detected", fe->id); 299 case SOC_7090_P1G_21R1:
225 else if ((v & 0x1f) == 0x0) { 300 dprintk("SOC 7090 P1-G21R1 Has been detected");
226#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 301 identity->p1g = 1;
227 dprintk("FE%d : P1-A/B detected: using previous driver - support will be removed soon", fe->id); 302 break;
228 dib0090_p1b_register(fe); 303 default:
229#else 304 goto identification_error;
230 dprintk("FE%d : P1-A/B detected: driver is deactivated - not available", fe->id); 305 }
231 return 0xff; 306 } else {
232#endif 307 switch ((identity->version >> 5) & 0x7) {
308 case MP001:
309 dprintk("MP001 : 9090/8096");
310 break;
311 case MP005:
312 dprintk("MP005 : Single Sband");
313 break;
314 case MP008:
315 dprintk("MP008 : diversity VHF-UHF-LBAND");
316 break;
317 case MP009:
318 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
319 break;
320 default:
321 goto identification_error;
322 }
323
324 switch (identity->version & 0x1f) {
325 case P1G_21R2:
326 dprintk("P1G_21R2 detected");
327 identity->p1g = 1;
328 break;
329 case P1G:
330 dprintk("P1G detected");
331 identity->p1g = 1;
332 break;
333 case P1D_E_F:
334 dprintk("P1D/E/F detected");
335 break;
336 case P1C:
337 dprintk("P1C detected");
338 break;
339 case P1A_B:
340 dprintk("P1-A/B detected: driver is deactivated - not available");
341 goto identification_error;
342 break;
343 default:
344 goto identification_error;
345 }
233 } 346 }
234 347
235 return v; 348 return 0;
349
350identification_error:
351 return -EIO;
352}
353
354static int dib0090_fw_identify(struct dvb_frontend *fe)
355{
356 struct dib0090_fw_state *state = fe->tuner_priv;
357 struct dib0090_identity *identity = &state->identity;
358
359 u16 v = dib0090_fw_read_reg(state, 0x1a);
360 identity->p1g = 0;
361 identity->in_soc = 0;
362
363 dprintk("FE: Tuner identification (Version = 0x%04x)", v);
364
365 /* without PLL lock info */
366 v &= ~KROSUS_PLL_LOCKED;
367
368 identity->version = v & 0xff;
369 identity->product = (v >> 8) & 0xf;
370
371 if (identity->product != KROSUS)
372 goto identification_error;
373
374 if ((identity->version & 0x3) == SOC) {
375 identity->in_soc = 1;
376 switch (identity->version) {
377 case SOC_8090_P1G_11R1:
378 dprintk("SOC 8090 P1-G11R1 Has been detected");
379 identity->p1g = 1;
380 break;
381 case SOC_8090_P1G_21R1:
382 dprintk("SOC 8090 P1-G21R1 Has been detected");
383 identity->p1g = 1;
384 break;
385 case SOC_7090_P1G_11R1:
386 dprintk("SOC 7090 P1-G11R1 Has been detected");
387 identity->p1g = 1;
388 break;
389 case SOC_7090_P1G_21R1:
390 dprintk("SOC 7090 P1-G21R1 Has been detected");
391 identity->p1g = 1;
392 break;
393 default:
394 goto identification_error;
395 }
396 } else {
397 switch ((identity->version >> 5) & 0x7) {
398 case MP001:
399 dprintk("MP001 : 9090/8096");
400 break;
401 case MP005:
402 dprintk("MP005 : Single Sband");
403 break;
404 case MP008:
405 dprintk("MP008 : diversity VHF-UHF-LBAND");
406 break;
407 case MP009:
408 dprintk("MP009 : diversity 29098 CBAND-UHF-LBAND-SBAND");
409 break;
410 default:
411 goto identification_error;
412 }
413
414 switch (identity->version & 0x1f) {
415 case P1G_21R2:
416 dprintk("P1G_21R2 detected");
417 identity->p1g = 1;
418 break;
419 case P1G:
420 dprintk("P1G detected");
421 identity->p1g = 1;
422 break;
423 case P1D_E_F:
424 dprintk("P1D/E/F detected");
425 break;
426 case P1C:
427 dprintk("P1C detected");
428 break;
429 case P1A_B:
430 dprintk("P1-A/B detected: driver is deactivated - not available");
431 goto identification_error;
432 break;
433 default:
434 goto identification_error;
435 }
436 }
437
438 return 0;
439
440identification_error:
441 return -EIO;;
236} 442}
237 443
238static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg) 444static void dib0090_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
239{ 445{
240 struct dib0090_state *state = fe->tuner_priv; 446 struct dib0090_state *state = fe->tuner_priv;
447 u16 PllCfg, i, v;
241 448
242 HARD_RESET(state); 449 HARD_RESET(state);
243 450
244 dib0090_write_reg(state, 0x24, EN_PLL); 451 dib0090_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
245 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */ 452 dib0090_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
246 453
247 /* adcClkOutRatio=8->7, release reset */ 454 if (!cfg->in_soc) {
248 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0); 455 /* adcClkOutRatio=8->7, release reset */
456 dib0090_write_reg(state, 0x20, ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (0 << 4) | 0);
457 if (cfg->clkoutdrive != 0)
458 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
459 | (cfg->clkoutdrive << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
460 else
461 dib0090_write_reg(state, 0x23, (0 << 15) | ((!cfg->analog_output) << 14) | (2 << 10) | (1 << 9) | (0 << 8)
462 | (7 << 5) | (cfg->clkouttobamse << 4) | (0 << 2) | (0));
463 }
464
465 /* Read Pll current config * */
466 PllCfg = dib0090_read_reg(state, 0x21);
467
468 /** Reconfigure PLL if current setting is different from default setting **/
469 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && (!cfg->in_soc)
470 && !cfg->io.pll_bypass) {
471
472 /* Set Bypass mode */
473 PllCfg |= (1 << 15);
474 dib0090_write_reg(state, 0x21, PllCfg);
475
476 /* Set Reset Pll */
477 PllCfg &= ~(1 << 13);
478 dib0090_write_reg(state, 0x21, PllCfg);
479
480 /*** Set new Pll configuration in bypass and reset state ***/
481 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
482 dib0090_write_reg(state, 0x21, PllCfg);
483
484 /* Remove Reset Pll */
485 PllCfg |= (1 << 13);
486 dib0090_write_reg(state, 0x21, PllCfg);
487
488 /*** Wait for PLL lock ***/
489 i = 100;
490 do {
491 v = !!(dib0090_read_reg(state, 0x1a) & 0x800);
492 if (v)
493 break;
494 } while (--i);
495
496 if (i == 0) {
497 dprintk("Pll: Unable to lock Pll");
498 return;
499 }
500
501 /* Finally Remove Bypass mode */
502 PllCfg &= ~(1 << 15);
503 dib0090_write_reg(state, 0x21, PllCfg);
504 }
505
506 if (cfg->io.pll_bypass) {
507 PllCfg |= (cfg->io.pll_bypass << 15);
508 dib0090_write_reg(state, 0x21, PllCfg);
509 }
510}
511
512static int dib0090_fw_reset_digital(struct dvb_frontend *fe, const struct dib0090_config *cfg)
513{
514 struct dib0090_fw_state *state = fe->tuner_priv;
515 u16 PllCfg;
516 u16 v;
517 int i;
518
519 dprintk("fw reset digital");
520 HARD_RESET(state);
521
522 dib0090_fw_write_reg(state, 0x24, EN_PLL | EN_CRYSTAL);
523 dib0090_fw_write_reg(state, 0x1b, EN_DIGCLK | EN_PLL | EN_CRYSTAL); /* PLL, DIG_CLK and CRYSTAL remain */
524
525 dib0090_fw_write_reg(state, 0x20,
526 ((cfg->io.adc_clock_ratio - 1) << 11) | (0 << 10) | (1 << 9) | (1 << 8) | (cfg->data_tx_drv << 4) | cfg->ls_cfg_pad_drv);
527
528 v = (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 9) | (0 << 8) | (cfg->clkouttobamse << 4) | (0 << 2) | (0);
249 if (cfg->clkoutdrive != 0) 529 if (cfg->clkoutdrive != 0)
250 dib0090_write_reg(state, 0x23, 530 v |= cfg->clkoutdrive << 5;
251 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (cfg->clkoutdrive << 5) | (cfg->
252 clkouttobamse
253 << 4) | (0
254 <<
255 2)
256 | (0));
257 else 531 else
258 dib0090_write_reg(state, 0x23, 532 v |= 7 << 5;
259 (0 << 15) | ((!cfg->analog_output) << 14) | (1 << 10) | (1 << 9) | (0 << 8) | (7 << 5) | (cfg-> 533
260 clkouttobamse << 4) | (0 534 v |= 2 << 10;
261 << 535 dib0090_fw_write_reg(state, 0x23, v);
262 2) 536
263 | (0)); 537 /* Read Pll current config * */
538 PllCfg = dib0090_fw_read_reg(state, 0x21);
539
540 /** Reconfigure PLL if current setting is different from default setting **/
541 if ((PllCfg & 0x1FFF) != ((cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)) && !cfg->io.pll_bypass) {
264 542
265 /* enable pll, de-activate reset, ratio: 2/1 = 60MHz */ 543 /* Set Bypass mode */
266 dib0090_write_reg(state, 0x21, 544 PllCfg |= (1 << 15);
267 (cfg->io.pll_bypass << 15) | (1 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv)); 545 dib0090_fw_write_reg(state, 0x21, PllCfg);
268 546
547 /* Set Reset Pll */
548 PllCfg &= ~(1 << 13);
549 dib0090_fw_write_reg(state, 0x21, PllCfg);
550
551 /*** Set new Pll configuration in bypass and reset state ***/
552 PllCfg = (1 << 15) | (0 << 13) | (cfg->io.pll_range << 12) | (cfg->io.pll_loopdiv << 6) | (cfg->io.pll_prediv);
553 dib0090_fw_write_reg(state, 0x21, PllCfg);
554
555 /* Remove Reset Pll */
556 PllCfg |= (1 << 13);
557 dib0090_fw_write_reg(state, 0x21, PllCfg);
558
559 /*** Wait for PLL lock ***/
560 i = 100;
561 do {
562 v = !!(dib0090_fw_read_reg(state, 0x1a) & 0x800);
563 if (v)
564 break;
565 } while (--i);
566
567 if (i == 0) {
568 dprintk("Pll: Unable to lock Pll");
569 return -EIO;
570 }
571
572 /* Finally Remove Bypass mode */
573 PllCfg &= ~(1 << 15);
574 dib0090_fw_write_reg(state, 0x21, PllCfg);
575 }
576
577 if (cfg->io.pll_bypass) {
578 PllCfg |= (cfg->io.pll_bypass << 15);
579 dib0090_fw_write_reg(state, 0x21, PllCfg);
580 }
581
582 return dib0090_fw_identify(fe);
269} 583}
270 584
271static int dib0090_wakeup(struct dvb_frontend *fe) 585static int dib0090_wakeup(struct dvb_frontend *fe)
@@ -273,6 +587,9 @@ static int dib0090_wakeup(struct dvb_frontend *fe)
273 struct dib0090_state *state = fe->tuner_priv; 587 struct dib0090_state *state = fe->tuner_priv;
274 if (state->config->sleep) 588 if (state->config->sleep)
275 state->config->sleep(fe, 0); 589 state->config->sleep(fe, 0);
590
591 /* enable dataTX in case we have been restarted in the wrong moment */
592 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
276 return 0; 593 return 0;
277} 594}
278 595
@@ -292,8 +609,75 @@ void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
292 else 609 else
293 dib0090_write_reg(state, 0x04, 1); 610 dib0090_write_reg(state, 0x04, 1);
294} 611}
612
295EXPORT_SYMBOL(dib0090_dcc_freq); 613EXPORT_SYMBOL(dib0090_dcc_freq);
296 614
615static const u16 bb_ramp_pwm_normal_socs[] = {
616 550, /* max BB gain in 10th of dB */
617 (1 << 9) | 8, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> BB_RAMP2 */
618 440,
619 (4 << 9) | 0, /* BB_RAMP3 = 26dB */
620 (0 << 9) | 208, /* BB_RAMP4 */
621 (4 << 9) | 208, /* BB_RAMP5 = 29dB */
622 (0 << 9) | 440, /* BB_RAMP6 */
623};
624
625static const u16 rf_ramp_pwm_cband_7090[] = {
626 280, /* max RF gain in 10th of dB */
627 18, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
628 504, /* ramp_max = maximum X used on the ramp */
629 (29 << 10) | 364, /* RF_RAMP5, LNA 1 = 8dB */
630 (0 << 10) | 504, /* RF_RAMP6, LNA 1 */
631 (60 << 10) | 228, /* RF_RAMP7, LNA 2 = 7.7dB */
632 (0 << 10) | 364, /* RF_RAMP8, LNA 2 */
633 (34 << 10) | 109, /* GAIN_4_1, LNA 3 = 6.8dB */
634 (0 << 10) | 228, /* GAIN_4_2, LNA 3 */
635 (37 << 10) | 0, /* RF_RAMP3, LNA 4 = 6.2dB */
636 (0 << 10) | 109, /* RF_RAMP4, LNA 4 */
637};
638
639static const u16 rf_ramp_pwm_cband_8090[] = {
640 345, /* max RF gain in 10th of dB */
641 29, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
642 1000, /* ramp_max = maximum X used on the ramp */
643 (35 << 10) | 772, /* RF_RAMP3, LNA 1 = 8dB */
644 (0 << 10) | 1000, /* RF_RAMP4, LNA 1 */
645 (58 << 10) | 496, /* RF_RAMP5, LNA 2 = 9.5dB */
646 (0 << 10) | 772, /* RF_RAMP6, LNA 2 */
647 (27 << 10) | 200, /* RF_RAMP7, LNA 3 = 10.5dB */
648 (0 << 10) | 496, /* RF_RAMP8, LNA 3 */
649 (40 << 10) | 0, /* GAIN_4_1, LNA 4 = 7dB */
650 (0 << 10) | 200, /* GAIN_4_2, LNA 4 */
651};
652
653static const u16 rf_ramp_pwm_uhf_7090[] = {
654 407, /* max RF gain in 10th of dB */
655 13, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
656 529, /* ramp_max = maximum X used on the ramp */
657 (23 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
658 (0 << 10) | 176, /* RF_RAMP4, LNA 1 */
659 (63 << 10) | 400, /* RF_RAMP5, LNA 2 = 8dB */
660 (0 << 10) | 529, /* RF_RAMP6, LNA 2 */
661 (48 << 10) | 316, /* RF_RAMP7, LNA 3 = 6.8dB */
662 (0 << 10) | 400, /* RF_RAMP8, LNA 3 */
663 (29 << 10) | 176, /* GAIN_4_1, LNA 4 = 11.5dB */
664 (0 << 10) | 316, /* GAIN_4_2, LNA 4 */
665};
666
667static const u16 rf_ramp_pwm_uhf_8090[] = {
668 388, /* max RF gain in 10th of dB */
669 26, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> RF_RAMP2 */
670 1008, /* ramp_max = maximum X used on the ramp */
671 (11 << 10) | 0, /* RF_RAMP3, LNA 1 = 14.7dB */
672 (0 << 10) | 369, /* RF_RAMP4, LNA 1 */
673 (41 << 10) | 809, /* RF_RAMP5, LNA 2 = 8dB */
674 (0 << 10) | 1008, /* RF_RAMP6, LNA 2 */
675 (27 << 10) | 659, /* RF_RAMP7, LNA 3 = 6dB */
676 (0 << 10) | 809, /* RF_RAMP8, LNA 3 */
677 (14 << 10) | 369, /* GAIN_4_1, LNA 4 = 11.5dB */
678 (0 << 10) | 659, /* GAIN_4_2, LNA 4 */
679};
680
297static const u16 rf_ramp_pwm_cband[] = { 681static const u16 rf_ramp_pwm_cband[] = {
298 0, /* max RF gain in 10th of dB */ 682 0, /* max RF gain in 10th of dB */
299 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */ 683 0, /* ramp_slope = 1dB of gain -> clock_ticks_per_db = clk_khz / ramp_slope -> 0x2b */
@@ -326,6 +710,16 @@ static const u16 rf_ramp_uhf[] = {
326 0, 0, 127, /* CBAND : 0.0 dB */ 710 0, 0, 127, /* CBAND : 0.0 dB */
327}; 711};
328 712
713static const u16 rf_ramp_cband_broadmatching[] = /* for p1G only */
714{
715 314, /* Calibrated at 200MHz order has been changed g4-g3-g2-g1 */
716 84, 314, 127, /* LNA1 */
717 80, 230, 255, /* LNA2 */
718 80, 150, 127, /* LNA3 It was measured 12dB, do not lock if 120 */
719 70, 70, 127, /* LNA4 */
720 0, 0, 127, /* CBAND */
721};
722
329static const u16 rf_ramp_cband[] = { 723static const u16 rf_ramp_cband[] = {
330 332, /* max RF gain in 10th of dB */ 724 332, /* max RF gain in 10th of dB */
331 132, 252, 127, /* LNA1, dB */ 725 132, 252, 127, /* LNA1, dB */
@@ -380,8 +774,8 @@ static const u16 bb_ramp_pwm_normal[] = {
380}; 774};
381 775
382struct slope { 776struct slope {
383 int16_t range; 777 s16 range;
384 int16_t slope; 778 s16 slope;
385}; 779};
386static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val) 780static u16 slopes_to_scale(const struct slope *slopes, u8 num, s16 val)
387{ 781{
@@ -597,19 +991,39 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
597#endif 991#endif
598#ifdef CONFIG_BAND_CBAND 992#ifdef CONFIG_BAND_CBAND
599 if (state->current_band == BAND_CBAND) { 993 if (state->current_band == BAND_CBAND) {
600 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband); 994 if (state->identity.in_soc) {
601 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 995 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
996 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
997 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_8090);
998 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
999 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband_7090);
1000 } else {
1001 dib0090_set_rframp_pwm(state, rf_ramp_pwm_cband);
1002 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1003 }
602 } else 1004 } else
603#endif 1005#endif
604#ifdef CONFIG_BAND_VHF 1006#ifdef CONFIG_BAND_VHF
605 if (state->current_band == BAND_VHF) { 1007 if (state->current_band == BAND_VHF) {
606 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf); 1008 if (state->identity.in_soc) {
607 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 1009 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1010 } else {
1011 dib0090_set_rframp_pwm(state, rf_ramp_pwm_vhf);
1012 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1013 }
608 } else 1014 } else
609#endif 1015#endif
610 { 1016 {
611 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf); 1017 if (state->identity.in_soc) {
612 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal); 1018 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1019 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_8090);
1020 else if (state->identity.version == SOC_7090_P1G_11R1 || state->identity.version == SOC_7090_P1G_21R1)
1021 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf_7090);
1022 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal_socs);
1023 } else {
1024 dib0090_set_rframp_pwm(state, rf_ramp_pwm_uhf);
1025 dib0090_set_bbramp_pwm(state, bb_ramp_pwm_normal);
1026 }
613 } 1027 }
614 1028
615 if (state->rf_ramp[0] != 0) 1029 if (state->rf_ramp[0] != 0)
@@ -617,11 +1031,21 @@ void dib0090_pwm_gain_reset(struct dvb_frontend *fe)
617 else 1031 else
618 dib0090_write_reg(state, 0x32, (0 << 11)); 1032 dib0090_write_reg(state, 0x32, (0 << 11));
619 1033
1034 dib0090_write_reg(state, 0x04, 0x01);
620 dib0090_write_reg(state, 0x39, (1 << 10)); 1035 dib0090_write_reg(state, 0x39, (1 << 10));
621 } 1036 }
622} 1037}
1038
623EXPORT_SYMBOL(dib0090_pwm_gain_reset); 1039EXPORT_SYMBOL(dib0090_pwm_gain_reset);
624 1040
1041static u32 dib0090_get_slow_adc_val(struct dib0090_state *state)
1042{
1043 u16 adc_val = dib0090_read_reg(state, 0x1d);
1044 if (state->identity.in_soc)
1045 adc_val >>= 2;
1046 return adc_val;
1047}
1048
625int dib0090_gain_control(struct dvb_frontend *fe) 1049int dib0090_gain_control(struct dvb_frontend *fe)
626{ 1050{
627 struct dib0090_state *state = fe->tuner_priv; 1051 struct dib0090_state *state = fe->tuner_priv;
@@ -643,18 +1067,21 @@ int dib0090_gain_control(struct dvb_frontend *fe)
643 } else 1067 } else
644#endif 1068#endif
645#ifdef CONFIG_BAND_VHF 1069#ifdef CONFIG_BAND_VHF
646 if (state->current_band == BAND_VHF) { 1070 if (state->current_band == BAND_VHF && !state->identity.p1g) {
647 dib0090_set_rframp(state, rf_ramp_vhf); 1071 dib0090_set_rframp(state, rf_ramp_vhf);
648 dib0090_set_bbramp(state, bb_ramp_boost); 1072 dib0090_set_bbramp(state, bb_ramp_boost);
649 } else 1073 } else
650#endif 1074#endif
651#ifdef CONFIG_BAND_CBAND 1075#ifdef CONFIG_BAND_CBAND
652 if (state->current_band == BAND_CBAND) { 1076 if (state->current_band == BAND_CBAND && !state->identity.p1g) {
653 dib0090_set_rframp(state, rf_ramp_cband); 1077 dib0090_set_rframp(state, rf_ramp_cband);
654 dib0090_set_bbramp(state, bb_ramp_boost); 1078 dib0090_set_bbramp(state, bb_ramp_boost);
655 } else 1079 } else
656#endif 1080#endif
657 { 1081 if ((state->current_band == BAND_CBAND || state->current_band == BAND_VHF) && state->identity.p1g) {
1082 dib0090_set_rframp(state, rf_ramp_cband_broadmatching);
1083 dib0090_set_bbramp(state, bb_ramp_boost);
1084 } else {
658 dib0090_set_rframp(state, rf_ramp_uhf); 1085 dib0090_set_rframp(state, rf_ramp_uhf);
659 dib0090_set_bbramp(state, bb_ramp_boost); 1086 dib0090_set_bbramp(state, bb_ramp_boost);
660 } 1087 }
@@ -669,17 +1096,25 @@ int dib0090_gain_control(struct dvb_frontend *fe)
669 1096
670 *tune_state = CT_AGC_STEP_0; 1097 *tune_state = CT_AGC_STEP_0;
671 } else if (!state->agc_freeze) { 1098 } else if (!state->agc_freeze) {
672 s16 wbd; 1099 s16 wbd = 0, i, cnt;
673 1100
674 int adc; 1101 int adc;
675 wbd_val = dib0090_read_reg(state, 0x1d); 1102 wbd_val = dib0090_get_slow_adc_val(state);
676 1103
677 /* read and calc the wbd power */ 1104 if (*tune_state == CT_AGC_STEP_0)
678 wbd = dib0090_wbd_to_db(state, wbd_val); 1105 cnt = 5;
1106 else
1107 cnt = 1;
1108
1109 for (i = 0; i < cnt; i++) {
1110 wbd_val = dib0090_get_slow_adc_val(state);
1111 wbd += dib0090_wbd_to_db(state, wbd_val);
1112 }
1113 wbd /= cnt;
679 wbd_error = state->wbd_target - wbd; 1114 wbd_error = state->wbd_target - wbd;
680 1115
681 if (*tune_state == CT_AGC_STEP_0) { 1116 if (*tune_state == CT_AGC_STEP_0) {
682 if (wbd_error < 0 && state->rf_gain_limit > 0) { 1117 if (wbd_error < 0 && state->rf_gain_limit > 0 && !state->identity.p1g) {
683#ifdef CONFIG_BAND_CBAND 1118#ifdef CONFIG_BAND_CBAND
684 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */ 1119 /* in case of CBAND tune reduce first the lt_gain2 before adjusting the RF gain */
685 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7; 1120 u8 ltg2 = (state->rf_lt_def >> 10) & 0x7;
@@ -700,39 +1135,39 @@ int dib0090_gain_control(struct dvb_frontend *fe)
700 adc_error = (s16) (((s32) ADC_TARGET) - adc); 1135 adc_error = (s16) (((s32) ADC_TARGET) - adc);
701#ifdef CONFIG_STANDARD_DAB 1136#ifdef CONFIG_STANDARD_DAB
702 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB) 1137 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DAB)
703 adc_error += 130; 1138 adc_error -= 10;
704#endif 1139#endif
705#ifdef CONFIG_STANDARD_DVBT 1140#ifdef CONFIG_STANDARD_DVBT
706 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT && 1141 if (state->fe->dtv_property_cache.delivery_system == STANDARD_DVBT &&
707 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16)) 1142 (state->fe->dtv_property_cache.modulation == QAM_64 || state->fe->dtv_property_cache.modulation == QAM_16))
708 adc_error += 60; 1143 adc_error += 60;
709#endif 1144#endif
710#ifdef CONFIG_SYS_ISDBT 1145#ifdef CONFIG_SYS_ISDBT
711 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count > 1146 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT) && (((state->fe->dtv_property_cache.layer[0].segment_count >
712 0) 1147 0)
713 && 1148 &&
714 ((state->fe->dtv_property_cache.layer[0].modulation == 1149 ((state->fe->dtv_property_cache.layer[0].modulation ==
715 QAM_64) 1150 QAM_64)
716 || (state->fe->dtv_property_cache.layer[0]. 1151 || (state->fe->dtv_property_cache.
717 modulation == QAM_16))) 1152 layer[0].modulation == QAM_16)))
718 || 1153 ||
719 ((state->fe->dtv_property_cache.layer[1].segment_count > 1154 ((state->fe->dtv_property_cache.layer[1].segment_count >
720 0) 1155 0)
721 && 1156 &&
722 ((state->fe->dtv_property_cache.layer[1].modulation == 1157 ((state->fe->dtv_property_cache.layer[1].modulation ==
723 QAM_64) 1158 QAM_64)
724 || (state->fe->dtv_property_cache.layer[1]. 1159 || (state->fe->dtv_property_cache.
725 modulation == QAM_16))) 1160 layer[1].modulation == QAM_16)))
726 || 1161 ||
727 ((state->fe->dtv_property_cache.layer[2].segment_count > 1162 ((state->fe->dtv_property_cache.layer[2].segment_count >
728 0) 1163 0)
729 && 1164 &&
730 ((state->fe->dtv_property_cache.layer[2].modulation == 1165 ((state->fe->dtv_property_cache.layer[2].modulation ==
731 QAM_64) 1166 QAM_64)
732 || (state->fe->dtv_property_cache.layer[2]. 1167 || (state->fe->dtv_property_cache.
733 modulation == QAM_16))) 1168 layer[2].modulation == QAM_16)))
734 ) 1169 )
735 ) 1170 )
736 adc_error += 60; 1171 adc_error += 60;
737#endif 1172#endif
738 1173
@@ -760,9 +1195,9 @@ int dib0090_gain_control(struct dvb_frontend *fe)
760 } 1195 }
761#ifdef DEBUG_AGC 1196#ifdef DEBUG_AGC
762 dprintk 1197 dprintk
763 ("FE: %d, tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm", 1198 ("tune state %d, ADC = %3ddB (ADC err %3d) WBD %3ddB (WBD err %3d, WBD val SADC: %4d), RFGainLimit (TOP): %3d, signal: %3ddBm",
764 (u32) fe->id, (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val, 1199 (u32) *tune_state, (u32) adc, (u32) adc_error, (u32) wbd, (u32) wbd_error, (u32) wbd_val,
765 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA)); 1200 (u32) state->rf_gain_limit >> WBD_ALPHA, (s32) 200 + adc - (state->current_gain >> GAIN_ALPHA));
766#endif 1201#endif
767 } 1202 }
768 1203
@@ -771,6 +1206,7 @@ int dib0090_gain_control(struct dvb_frontend *fe)
771 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly); 1206 dib0090_gain_apply(state, adc_error, wbd_error, apply_gain_immediatly);
772 return ret; 1207 return ret;
773} 1208}
1209
774EXPORT_SYMBOL(dib0090_gain_control); 1210EXPORT_SYMBOL(dib0090_gain_control);
775 1211
776void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt) 1212void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 * rf_gain_limit, u16 * rflt)
@@ -785,13 +1221,47 @@ void dib0090_get_current_gain(struct dvb_frontend *fe, u16 * rf, u16 * bb, u16 *
785 if (rflt) 1221 if (rflt)
786 *rflt = (state->rf_lt_def >> 10) & 0x7; 1222 *rflt = (state->rf_lt_def >> 10) & 0x7;
787} 1223}
1224
788EXPORT_SYMBOL(dib0090_get_current_gain); 1225EXPORT_SYMBOL(dib0090_get_current_gain);
789 1226
790u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner) 1227u16 dib0090_get_wbd_offset(struct dvb_frontend *fe)
791{ 1228{
792 struct dib0090_state *st = tuner->tuner_priv; 1229 struct dib0090_state *state = fe->tuner_priv;
793 return st->wbd_offset; 1230 u32 f_MHz = state->fe->dtv_property_cache.frequency / 1000000;
1231 s32 current_temp = state->temperature;
1232 s32 wbd_thot, wbd_tcold;
1233 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1234
1235 while (f_MHz > wbd->max_freq)
1236 wbd++;
1237
1238 dprintk("using wbd-table-entry with max freq %d", wbd->max_freq);
1239
1240 if (current_temp < 0)
1241 current_temp = 0;
1242 if (current_temp > 128)
1243 current_temp = 128;
1244
1245 state->wbdmux &= ~(7 << 13);
1246 if (wbd->wbd_gain != 0)
1247 state->wbdmux |= (wbd->wbd_gain << 13);
1248 else
1249 state->wbdmux |= (4 << 13);
1250
1251 dib0090_write_reg(state, 0x10, state->wbdmux);
1252
1253 wbd_thot = wbd->offset_hot - (((u32) wbd->slope_hot * f_MHz) >> 6);
1254 wbd_tcold = wbd->offset_cold - (((u32) wbd->slope_cold * f_MHz) >> 6);
1255
1256 wbd_tcold += ((wbd_thot - wbd_tcold) * current_temp) >> 7;
1257
1258 state->wbd_target = dib0090_wbd_to_db(state, state->wbd_offset + wbd_tcold);
1259 dprintk("wbd-target: %d dB", (u32) state->wbd_target);
1260 dprintk("wbd offset applied is %d", wbd_tcold);
1261
1262 return state->wbd_offset + wbd_tcold;
794} 1263}
1264
795EXPORT_SYMBOL(dib0090_get_wbd_offset); 1265EXPORT_SYMBOL(dib0090_get_wbd_offset);
796 1266
797static const u16 dib0090_defaults[] = { 1267static const u16 dib0090_defaults[] = {
@@ -801,7 +1271,7 @@ static const u16 dib0090_defaults[] = {
801 0x99a0, 1271 0x99a0,
802 0x6008, 1272 0x6008,
803 0x0000, 1273 0x0000,
804 0x8acb, 1274 0x8bcb,
805 0x0000, 1275 0x0000,
806 0x0405, 1276 0x0405,
807 0x0000, 1277 0x0000,
@@ -829,8 +1299,6 @@ static const u16 dib0090_defaults[] = {
829 1, 0x39, 1299 1, 0x39,
830 0x0000, 1300 0x0000,
831 1301
832 1, 0x1b,
833 EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL,
834 2, 0x1e, 1302 2, 0x1e,
835 0x07FF, 1303 0x07FF,
836 0x0007, 1304 0x0007,
@@ -844,50 +1312,125 @@ static const u16 dib0090_defaults[] = {
844 0 1312 0
845}; 1313};
846 1314
847static int dib0090_reset(struct dvb_frontend *fe) 1315static const u16 dib0090_p1g_additionnal_defaults[] = {
848{ 1316 1, 0x05,
849 struct dib0090_state *state = fe->tuner_priv; 1317 0xabcd,
850 u16 l, r, *n;
851 1318
852 dib0090_reset_digital(fe, state->config); 1319 1, 0x11,
853 state->revision = dib0090_identify(fe); 1320 0x00b4,
854 1321
855 /* Revision definition */ 1322 1, 0x1c,
856 if (state->revision == 0xff) 1323 0xfffd,
857 return -EINVAL;
858#ifdef EFUSE
859 else if ((state->revision & 0x1f) >= 3) /* Update the efuse : Only available for KROSUS > P1C */
860 dib0090_set_EFUSE(state);
861#endif
862 1324
863#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT 1325 1, 0x40,
864 if (!(state->revision & 0x1)) /* it is P1B - reset is already done */ 1326 0x108,
865 return 0; 1327 0
866#endif 1328};
1329
1330static void dib0090_set_default_config(struct dib0090_state *state, const u16 * n)
1331{
1332 u16 l, r;
867 1333
868 /* Upload the default values */
869 n = (u16 *) dib0090_defaults;
870 l = pgm_read_word(n++); 1334 l = pgm_read_word(n++);
871 while (l) { 1335 while (l) {
872 r = pgm_read_word(n++); 1336 r = pgm_read_word(n++);
873 do { 1337 do {
874 /* DEBUG_TUNER */
875 /* dprintk("%d, %d, %d", l, r, pgm_read_word(n)); */
876 dib0090_write_reg(state, r, pgm_read_word(n++)); 1338 dib0090_write_reg(state, r, pgm_read_word(n++));
877 r++; 1339 r++;
878 } while (--l); 1340 } while (--l);
879 l = pgm_read_word(n++); 1341 l = pgm_read_word(n++);
880 } 1342 }
1343}
1344
1345#define CAP_VALUE_MIN (u8) 9
1346#define CAP_VALUE_MAX (u8) 40
1347#define HR_MIN (u8) 25
1348#define HR_MAX (u8) 40
1349#define POLY_MIN (u8) 0
1350#define POLY_MAX (u8) 8
1351
1352void dib0090_set_EFUSE(struct dib0090_state *state)
1353{
1354 u8 c, h, n;
1355 u16 e2, e4;
1356 u16 cal;
1357
1358 e2 = dib0090_read_reg(state, 0x26);
1359 e4 = dib0090_read_reg(state, 0x28);
1360
1361 if ((state->identity.version == P1D_E_F) ||
1362 (state->identity.version == P1G) || (e2 == 0xffff)) {
1363
1364 dib0090_write_reg(state, 0x22, 0x10);
1365 cal = (dib0090_read_reg(state, 0x22) >> 6) & 0x3ff;
1366
1367 if ((cal < 670) || (cal == 1023))
1368 cal = 850;
1369 n = 165 - ((cal * 10)>>6) ;
1370 e2 = e4 = (3<<12) | (34<<6) | (n);
1371 }
1372
1373 if (e2 != e4)
1374 e2 &= e4; /* Remove the redundancy */
1375
1376 if (e2 != 0xffff) {
1377 c = e2 & 0x3f;
1378 n = (e2 >> 12) & 0xf;
1379 h = (e2 >> 6) & 0x3f;
1380
1381 if ((c >= CAP_VALUE_MAX) || (c <= CAP_VALUE_MIN))
1382 c = 32;
1383 if ((h >= HR_MAX) || (h <= HR_MIN))
1384 h = 34;
1385 if ((n >= POLY_MAX) || (n <= POLY_MIN))
1386 n = 3;
1387
1388 dib0090_write_reg(state, 0x13, (h << 10)) ;
1389 e2 = (n<<11) | ((h>>2)<<6) | (c);
1390 dib0090_write_reg(state, 0x2, e2) ; /* Load the BB_2 */
1391 }
1392}
1393
1394static int dib0090_reset(struct dvb_frontend *fe)
1395{
1396 struct dib0090_state *state = fe->tuner_priv;
1397
1398 dib0090_reset_digital(fe, state->config);
1399 if (dib0090_identify(fe) < 0)
1400 return -EIO;
1401
1402#ifdef CONFIG_TUNER_DIB0090_P1B_SUPPORT
1403 if (!(state->identity.version & 0x1)) /* it is P1B - reset is already done */
1404 return 0;
1405#endif
1406
1407 if (!state->identity.in_soc) {
1408 if ((dib0090_read_reg(state, 0x1a) >> 5) & 0x2)
1409 dib0090_write_reg(state, 0x1b, (EN_IQADC | EN_BB | EN_BIAS | EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1410 else
1411 dib0090_write_reg(state, 0x1b, (EN_DIGCLK | EN_PLL | EN_CRYSTAL));
1412 }
1413
1414 dib0090_set_default_config(state, dib0090_defaults);
1415
1416 if (state->identity.in_soc)
1417 dib0090_write_reg(state, 0x18, 0x2910); /* charge pump current = 0 */
1418
1419 if (state->identity.p1g)
1420 dib0090_set_default_config(state, dib0090_p1g_additionnal_defaults);
1421
1422 /* Update the efuse : Only available for KROSUS > P1C and SOC as well*/
1423 if (((state->identity.version & 0x1f) >= P1D_E_F) || (state->identity.in_soc))
1424 dib0090_set_EFUSE(state);
881 1425
882 /* Congigure in function of the crystal */ 1426 /* Congigure in function of the crystal */
883 if (state->config->io.clock_khz >= 24000) 1427 if (state->config->io.clock_khz >= 24000)
884 l = 1; 1428 dib0090_write_reg(state, 0x14, 1);
885 else 1429 else
886 l = 2; 1430 dib0090_write_reg(state, 0x14, 2);
887 dib0090_write_reg(state, 0x14, l);
888 dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1); 1431 dprintk("Pll lock : %d", (dib0090_read_reg(state, 0x1a) >> 11) & 0x1);
889 1432
890 state->reset = 3; /* enable iq-offset-calibration and wbd-calibration when tuning next time */ 1433 state->calibrate = DC_CAL | WBD_CAL | TEMP_CAL; /* enable iq-offset-calibration and wbd-calibration when tuning next time */
891 1434
892 return 0; 1435 return 0;
893} 1436}
@@ -927,11 +1470,11 @@ static int dib0090_get_offset(struct dib0090_state *state, enum frontend_tune_st
927} 1470}
928 1471
929struct dc_calibration { 1472struct dc_calibration {
930 uint8_t addr; 1473 u8 addr;
931 uint8_t offset; 1474 u8 offset;
932 uint8_t pga:1; 1475 u8 pga:1;
933 uint16_t bb1; 1476 u16 bb1;
934 uint8_t i:1; 1477 u8 i:1;
935}; 1478};
936 1479
937static const struct dc_calibration dc_table[] = { 1480static const struct dc_calibration dc_table[] = {
@@ -944,6 +1487,17 @@ static const struct dc_calibration dc_table[] = {
944 {0}, 1487 {0},
945}; 1488};
946 1489
1490static const struct dc_calibration dc_p1g_table[] = {
1491 /* Step1 BB gain1= 26 with boost 1, gain 2 = 0 */
1492 /* addr ; trim reg offset ; pga ; CTRL_BB1 value ; i or q */
1493 {0x06, 5, 1, (1 << 13) | (0 << 8) | (15 << 3), 1},
1494 {0x07, 11, 1, (1 << 13) | (0 << 8) | (15 << 3), 0},
1495 /* Step 2 BB gain 1 = 26 with boost = 1 & gain 2 = 29 */
1496 {0x06, 0, 0, (1 << 13) | (29 << 8) | (15 << 3), 1},
1497 {0x06, 10, 0, (1 << 13) | (29 << 8) | (15 << 3), 0},
1498 {0},
1499};
1500
947static void dib0090_set_trim(struct dib0090_state *state) 1501static void dib0090_set_trim(struct dib0090_state *state)
948{ 1502{
949 u16 *val; 1503 u16 *val;
@@ -962,41 +1516,45 @@ static void dib0090_set_trim(struct dib0090_state *state)
962static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1516static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
963{ 1517{
964 int ret = 0; 1518 int ret = 0;
1519 u16 reg;
965 1520
966 switch (*tune_state) { 1521 switch (*tune_state) {
967
968 case CT_TUNER_START: 1522 case CT_TUNER_START:
969 /* init */ 1523 dprintk("Start DC offset calibration");
970 dprintk("Internal DC calibration");
971
972 /* the LNA is off */
973 dib0090_write_reg(state, 0x24, 0x02ed);
974 1524
975 /* force vcm2 = 0.8V */ 1525 /* force vcm2 = 0.8V */
976 state->bb6 = 0; 1526 state->bb6 = 0;
977 state->bb7 = 0x040d; 1527 state->bb7 = 0x040d;
978 1528
1529 /* the LNA AND LO are off */
1530 reg = dib0090_read_reg(state, 0x24) & 0x0ffb; /* shutdown lna and lo */
1531 dib0090_write_reg(state, 0x24, reg);
1532
1533 state->wbdmux = dib0090_read_reg(state, 0x10);
1534 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x7 << 3) | 0x3);
1535 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
1536
979 state->dc = dc_table; 1537 state->dc = dc_table;
980 1538
1539 if (state->identity.p1g)
1540 state->dc = dc_p1g_table;
981 *tune_state = CT_TUNER_STEP_0; 1541 *tune_state = CT_TUNER_STEP_0;
982 1542
983 /* fall through */ 1543 /* fall through */
984 1544
985 case CT_TUNER_STEP_0: 1545 case CT_TUNER_STEP_0:
1546 dprintk("Sart/continue DC calibration for %s path", (state->dc->i == 1) ? "I" : "Q");
986 dib0090_write_reg(state, 0x01, state->dc->bb1); 1547 dib0090_write_reg(state, 0x01, state->dc->bb1);
987 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7)); 1548 dib0090_write_reg(state, 0x07, state->bb7 | (state->dc->i << 7));
988 1549
989 state->step = 0; 1550 state->step = 0;
990
991 state->min_adc_diff = 1023; 1551 state->min_adc_diff = 1023;
992
993 *tune_state = CT_TUNER_STEP_1; 1552 *tune_state = CT_TUNER_STEP_1;
994 ret = 50; 1553 ret = 50;
995 break; 1554 break;
996 1555
997 case CT_TUNER_STEP_1: 1556 case CT_TUNER_STEP_1:
998 dib0090_set_trim(state); 1557 dib0090_set_trim(state);
999
1000 *tune_state = CT_TUNER_STEP_2; 1558 *tune_state = CT_TUNER_STEP_2;
1001 break; 1559 break;
1002 1560
@@ -1007,7 +1565,13 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1007 break; 1565 break;
1008 1566
1009 case CT_TUNER_STEP_5: /* found an offset */ 1567 case CT_TUNER_STEP_5: /* found an offset */
1010 dprintk("FE%d: IQC read=%d, current=%x", state->fe->id, (u32) state->adc_diff, state->step); 1568 dprintk("adc_diff = %d, current step= %d", (u32) state->adc_diff, state->step);
1569 if (state->step == 0 && state->adc_diff < 0) {
1570 state->min_adc_diff = -1023;
1571 dprintk("Change of sign of the minimum adc diff");
1572 }
1573
1574 dprintk("adc_diff = %d, min_adc_diff = %d current_step = %d", state->adc_diff, state->min_adc_diff, state->step);
1011 1575
1012 /* first turn for this frequency */ 1576 /* first turn for this frequency */
1013 if (state->step == 0) { 1577 if (state->step == 0) {
@@ -1017,20 +1581,21 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1017 state->step = 0x10; 1581 state->step = 0x10;
1018 } 1582 }
1019 1583
1020 state->adc_diff = ABS(state->adc_diff); 1584 /* Look for a change of Sign in the Adc_diff.min_adc_diff is used to STORE the setp N-1 */
1021 1585 if ((state->adc_diff & 0x8000) == (state->min_adc_diff & 0x8000) && steps(state->step) < 15) {
1022 if (state->adc_diff < state->min_adc_diff && steps(state->step) < 15) { /* stop search when the delta to 0 is increasing */ 1586 /* stop search when the delta the sign is changing and Steps =15 and Step=0 is force for continuance */
1023 state->step++; 1587 state->step++;
1024 state->min_adc_diff = state->adc_diff; 1588 state->min_adc_diff = state->adc_diff;
1025 *tune_state = CT_TUNER_STEP_1; 1589 *tune_state = CT_TUNER_STEP_1;
1026 } else { 1590 } else {
1027
1028 /* the minimum was what we have seen in the step before */ 1591 /* the minimum was what we have seen in the step before */
1029 state->step--; 1592 if (ABS(state->adc_diff) > ABS(state->min_adc_diff)) {
1030 dib0090_set_trim(state); 1593 dprintk("Since adc_diff N = %d > adc_diff step N-1 = %d, Come back one step", state->adc_diff, state->min_adc_diff);
1594 state->step--;
1595 }
1031 1596
1032 dprintk("FE%d: BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->fe->id, state->dc->addr, state->adc_diff, 1597 dib0090_set_trim(state);
1033 state->step); 1598 dprintk("BB Offset Cal, BBreg=%hd,Offset=%hd,Value Set=%hd", state->dc->addr, state->adc_diff, state->step);
1034 1599
1035 state->dc++; 1600 state->dc++;
1036 if (state->dc->addr == 0) /* done */ 1601 if (state->dc->addr == 0) /* done */
@@ -1045,7 +1610,7 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1045 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008); 1610 dib0090_write_reg(state, 0x07, state->bb7 & ~0x0008);
1046 dib0090_write_reg(state, 0x1f, 0x7); 1611 dib0090_write_reg(state, 0x1f, 0x7);
1047 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1612 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
1048 state->reset &= ~0x1; 1613 state->calibrate &= ~DC_CAL;
1049 default: 1614 default:
1050 break; 1615 break;
1051 } 1616 }
@@ -1054,21 +1619,43 @@ static int dib0090_dc_offset_calibration(struct dib0090_state *state, enum front
1054 1619
1055static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state) 1620static int dib0090_wbd_calibration(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1056{ 1621{
1622 u8 wbd_gain;
1623 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1624
1057 switch (*tune_state) { 1625 switch (*tune_state) {
1058 case CT_TUNER_START: 1626 case CT_TUNER_START:
1059 /* WBD-mode=log, Bias=2, Gain=6, Testmode=1, en=1, WBDMUX=1 */ 1627 while (state->current_rf / 1000 > wbd->max_freq)
1060 dib0090_write_reg(state, 0x10, 0xdb09 | (1 << 10)); 1628 wbd++;
1061 dib0090_write_reg(state, 0x24, EN_UHF & 0x0fff); 1629 if (wbd->wbd_gain != 0)
1630 wbd_gain = wbd->wbd_gain;
1631 else {
1632 wbd_gain = 4;
1633#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1634 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND))
1635 wbd_gain = 2;
1636#endif
1637 }
1638
1639 if (wbd_gain == state->wbd_calibration_gain) { /* the WBD calibration has already been done */
1640 *tune_state = CT_TUNER_START;
1641 state->calibrate &= ~WBD_CAL;
1642 return 0;
1643 }
1644
1645 dib0090_write_reg(state, 0x10, 0x1b81 | (1 << 10) | (wbd_gain << 13) | (1 << 3));
1062 1646
1647 dib0090_write_reg(state, 0x24, ((EN_UHF & 0x0fff) | (1 << 1)));
1063 *tune_state = CT_TUNER_STEP_0; 1648 *tune_state = CT_TUNER_STEP_0;
1649 state->wbd_calibration_gain = wbd_gain;
1064 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */ 1650 return 90; /* wait for the WBDMUX to switch and for the ADC to sample */
1651
1065 case CT_TUNER_STEP_0: 1652 case CT_TUNER_STEP_0:
1066 state->wbd_offset = dib0090_read_reg(state, 0x1d); 1653 state->wbd_offset = dib0090_get_slow_adc_val(state);
1067 dprintk("WBD calibration offset = %d", state->wbd_offset); 1654 dprintk("WBD calibration offset = %d", state->wbd_offset);
1068
1069 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */ 1655 *tune_state = CT_TUNER_START; /* reset done -> real tuning can now begin */
1070 state->reset &= ~0x2; 1656 state->calibrate &= ~WBD_CAL;
1071 break; 1657 break;
1658
1072 default: 1659 default:
1073 break; 1660 break;
1074 } 1661 }
@@ -1092,6 +1679,15 @@ static void dib0090_set_bandwidth(struct dib0090_state *state)
1092 state->bb_1_def |= tmp; 1679 state->bb_1_def |= tmp;
1093 1680
1094 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */ 1681 dib0090_write_reg(state, 0x01, state->bb_1_def); /* be sure that we have the right bb-filter */
1682
1683 dib0090_write_reg(state, 0x03, 0x6008); /* = 0x6008 : vcm3_trim = 1 ; filter2_gm1_trim = 8 ; filter2_cutoff_freq = 0 */
1684 dib0090_write_reg(state, 0x04, 0x1); /* 0 = 1KHz ; 1 = 50Hz ; 2 = 150Hz ; 3 = 50KHz ; 4 = servo fast */
1685 if (state->identity.in_soc) {
1686 dib0090_write_reg(state, 0x05, 0x9bcf); /* attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 1 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 15 */
1687 } else {
1688 dib0090_write_reg(state, 0x02, (5 << 11) | (8 << 6) | (22 & 0x3f)); /* 22 = cap_value */
1689 dib0090_write_reg(state, 0x05, 0xabcd); /* = 0xabcd : attenuator_ibias_tri = 2 ; input_stage_ibias_tr = 2 ; nc = 11 ; ext_gm_trim = 1 ; obuf_ibias_trim = 4 ; filter13_gm2_ibias_t = 13 */
1690 }
1095} 1691}
1096 1692
1097static const struct dib0090_pll dib0090_pll_table[] = { 1693static const struct dib0090_pll dib0090_pll_table[] = {
@@ -1180,6 +1776,255 @@ static const struct dib0090_tuning dib0090_tuning_table[] = {
1180#endif 1776#endif
1181}; 1777};
1182 1778
1779static const struct dib0090_tuning dib0090_p1g_tuning_table[] = {
1780#ifdef CONFIG_BAND_CBAND
1781 {170000, 4, 1, 0x820f, 0x300, 0x2d22, 0x82cb, EN_CAB},
1782#endif
1783#ifdef CONFIG_BAND_VHF
1784 {184000, 1, 1, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1785 {227000, 1, 3, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1786 {380000, 1, 7, 15, 0x300, 0x4d12, 0xb94e, EN_VHF},
1787#endif
1788#ifdef CONFIG_BAND_UHF
1789 {510000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1790 {540000, 2, 1, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1791 {600000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1792 {630000, 2, 4, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1793 {680000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1794 {720000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1795 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1796#endif
1797#ifdef CONFIG_BAND_LBAND
1798 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1799 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1800 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1801#endif
1802#ifdef CONFIG_BAND_SBAND
1803 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1804 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1805#endif
1806};
1807
1808static const struct dib0090_pll dib0090_p1g_pll_table[] = {
1809#ifdef CONFIG_BAND_CBAND
1810 {57000, 0, 11, 48, 6},
1811 {70000, 1, 11, 48, 6},
1812 {86000, 0, 10, 32, 4},
1813 {105000, 1, 10, 32, 4},
1814 {115000, 0, 9, 24, 6},
1815 {140000, 1, 9, 24, 6},
1816 {170000, 0, 8, 16, 4},
1817#endif
1818#ifdef CONFIG_BAND_VHF
1819 {200000, 1, 8, 16, 4},
1820 {230000, 0, 7, 12, 6},
1821 {280000, 1, 7, 12, 6},
1822 {340000, 0, 6, 8, 4},
1823 {380000, 1, 6, 8, 4},
1824 {455000, 0, 5, 6, 6},
1825#endif
1826#ifdef CONFIG_BAND_UHF
1827 {580000, 1, 5, 6, 6},
1828 {680000, 0, 4, 4, 4},
1829 {860000, 1, 4, 4, 4},
1830#endif
1831#ifdef CONFIG_BAND_LBAND
1832 {1800000, 1, 2, 2, 4},
1833#endif
1834#ifdef CONFIG_BAND_SBAND
1835 {2900000, 0, 1, 1, 6},
1836#endif
1837};
1838
1839static const struct dib0090_tuning dib0090_p1g_tuning_table_fm_vhf_on_cband[] = {
1840#ifdef CONFIG_BAND_CBAND
1841 {184000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1842 {227000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1843 {380000, 4, 3, 0x4187, 0x2c0, 0x2d22, 0x81cb, EN_CAB},
1844#endif
1845#ifdef CONFIG_BAND_UHF
1846 {520000, 2, 0, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1847 {550000, 2, 2, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1848 {650000, 2, 3, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1849 {750000, 2, 5, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1850 {850000, 2, 6, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1851 {900000, 2, 7, 15, 0x300, 0x1d12, 0xb9ce, EN_UHF},
1852#endif
1853#ifdef CONFIG_BAND_LBAND
1854 {1500000, 4, 0, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1855 {1600000, 4, 1, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1856 {1800000, 4, 3, 20, 0x300, 0x1912, 0x82c9, EN_LBD},
1857#endif
1858#ifdef CONFIG_BAND_SBAND
1859 {2300000, 1, 4, 20, 0x300, 0x2d2A, 0x82c7, EN_SBD},
1860 {2900000, 1, 7, 20, 0x280, 0x2deb, 0x8347, EN_SBD},
1861#endif
1862};
1863
1864static const struct dib0090_tuning dib0090_tuning_table_cband_7090[] = {
1865#ifdef CONFIG_BAND_CBAND
1866 {300000, 4, 3, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1867 {380000, 4, 10, 0x018F, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1868 {570000, 4, 10, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1869 {858000, 4, 5, 0x8190, 0x2c0, 0x2d22, 0xb9ce, EN_CAB},
1870#endif
1871};
1872
1873static int dib0090_captrim_search(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1874{
1875 int ret = 0;
1876 u16 lo4 = 0xe900;
1877
1878 s16 adc_target;
1879 u16 adc;
1880 s8 step_sign;
1881 u8 force_soft_search = 0;
1882
1883 if (state->identity.version == SOC_8090_P1G_11R1 || state->identity.version == SOC_8090_P1G_21R1)
1884 force_soft_search = 1;
1885
1886 if (*tune_state == CT_TUNER_START) {
1887 dprintk("Start Captrim search : %s", (force_soft_search == 1) ? "FORCE SOFT SEARCH" : "AUTO");
1888 dib0090_write_reg(state, 0x10, 0x2B1);
1889 dib0090_write_reg(state, 0x1e, 0x0032);
1890
1891 if (!state->tuner_is_tuned) {
1892 /* prepare a complete captrim */
1893 if (!state->identity.p1g || force_soft_search)
1894 state->step = state->captrim = state->fcaptrim = 64;
1895
1896 state->current_rf = state->rf_request;
1897 } else { /* we are already tuned to this frequency - the configuration is correct */
1898 if (!state->identity.p1g || force_soft_search) {
1899 /* do a minimal captrim even if the frequency has not changed */
1900 state->step = 4;
1901 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
1902 }
1903 }
1904 state->adc_diff = 3000;
1905 *tune_state = CT_TUNER_STEP_0;
1906
1907 } else if (*tune_state == CT_TUNER_STEP_0) {
1908 if (state->identity.p1g && !force_soft_search) {
1909 u8 ratio = 31;
1910
1911 dib0090_write_reg(state, 0x40, (3 << 7) | (ratio << 2) | (1 << 1) | 1);
1912 dib0090_read_reg(state, 0x40);
1913 ret = 50;
1914 } else {
1915 state->step /= 2;
1916 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
1917
1918 if (state->identity.in_soc)
1919 ret = 25;
1920 }
1921 *tune_state = CT_TUNER_STEP_1;
1922
1923 } else if (*tune_state == CT_TUNER_STEP_1) {
1924 if (state->identity.p1g && !force_soft_search) {
1925 dib0090_write_reg(state, 0x40, 0x18c | (0 << 1) | 0);
1926 dib0090_read_reg(state, 0x40);
1927
1928 state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7F;
1929 dprintk("***Final Captrim= 0x%x", state->fcaptrim);
1930 *tune_state = CT_TUNER_STEP_3;
1931
1932 } else {
1933 /* MERGE for all krosus before P1G */
1934 adc = dib0090_get_slow_adc_val(state);
1935 dprintk("CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) state->captrim, (u32) adc, (u32) (adc) * (u32) 1800 / (u32) 1024);
1936
1937 if (state->rest == 0 || state->identity.in_soc) { /* Just for 8090P SOCS where auto captrim HW bug : TO CHECK IN ACI for SOCS !!! if 400 for 8090p SOC => tune issue !!! */
1938 adc_target = 200;
1939 } else
1940 adc_target = 400;
1941
1942 if (adc >= adc_target) {
1943 adc -= adc_target;
1944 step_sign = -1;
1945 } else {
1946 adc = adc_target - adc;
1947 step_sign = 1;
1948 }
1949
1950 if (adc < state->adc_diff) {
1951 dprintk("CAPTRIM=%d is closer to target (%d/%d)", (u32) state->captrim, (u32) adc, (u32) state->adc_diff);
1952 state->adc_diff = adc;
1953 state->fcaptrim = state->captrim;
1954 }
1955
1956 state->captrim += step_sign * state->step;
1957 if (state->step >= 1)
1958 *tune_state = CT_TUNER_STEP_0;
1959 else
1960 *tune_state = CT_TUNER_STEP_2;
1961
1962 ret = 25;
1963 }
1964 } else if (*tune_state == CT_TUNER_STEP_2) { /* this step is only used by krosus < P1G */
1965 /*write the final cptrim config */
1966 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
1967
1968 *tune_state = CT_TUNER_STEP_3;
1969
1970 } else if (*tune_state == CT_TUNER_STEP_3) {
1971 state->calibrate &= ~CAPTRIM_CAL;
1972 *tune_state = CT_TUNER_STEP_0;
1973 }
1974
1975 return ret;
1976}
1977
1978static int dib0090_get_temperature(struct dib0090_state *state, enum frontend_tune_state *tune_state)
1979{
1980 int ret = 15;
1981 s16 val;
1982
1983 switch (*tune_state) {
1984 case CT_TUNER_START:
1985 state->wbdmux = dib0090_read_reg(state, 0x10);
1986 dib0090_write_reg(state, 0x10, (state->wbdmux & ~(0xff << 3)) | (0x8 << 3));
1987
1988 state->bias = dib0090_read_reg(state, 0x13);
1989 dib0090_write_reg(state, 0x13, state->bias | (0x3 << 8));
1990
1991 *tune_state = CT_TUNER_STEP_0;
1992 /* wait for the WBDMUX to switch and for the ADC to sample */
1993 break;
1994
1995 case CT_TUNER_STEP_0:
1996 state->adc_diff = dib0090_get_slow_adc_val(state);
1997 dib0090_write_reg(state, 0x13, (state->bias & ~(0x3 << 8)) | (0x2 << 8));
1998 *tune_state = CT_TUNER_STEP_1;
1999 break;
2000
2001 case CT_TUNER_STEP_1:
2002 val = dib0090_get_slow_adc_val(state);
2003 state->temperature = ((s16) ((val - state->adc_diff) * 180) >> 8) + 55;
2004
2005 dprintk("temperature: %d C", state->temperature - 30);
2006
2007 *tune_state = CT_TUNER_STEP_2;
2008 break;
2009
2010 case CT_TUNER_STEP_2:
2011 dib0090_write_reg(state, 0x13, state->bias);
2012 dib0090_write_reg(state, 0x10, state->wbdmux); /* write back original WBDMUX */
2013
2014 *tune_state = CT_TUNER_START;
2015 state->calibrate &= ~TEMP_CAL;
2016 if (state->config->analog_output == 0)
2017 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2018
2019 break;
2020
2021 default:
2022 ret = 0;
2023 break;
2024 }
2025 return ret;
2026}
2027
1183#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */ 2028#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
1184static int dib0090_tune(struct dvb_frontend *fe) 2029static int dib0090_tune(struct dvb_frontend *fe)
1185{ 2030{
@@ -1188,87 +2033,131 @@ static int dib0090_tune(struct dvb_frontend *fe)
1188 const struct dib0090_pll *pll = state->current_pll_table_index; 2033 const struct dib0090_pll *pll = state->current_pll_table_index;
1189 enum frontend_tune_state *tune_state = &state->tune_state; 2034 enum frontend_tune_state *tune_state = &state->tune_state;
1190 2035
1191 u32 rf; 2036 u16 lo5, lo6, Den, tmp;
1192 u16 lo4 = 0xe900, lo5, lo6, Den;
1193 u32 FBDiv, Rest, FREF, VCOF_kHz = 0; 2037 u32 FBDiv, Rest, FREF, VCOF_kHz = 0;
1194 u16 tmp, adc;
1195 int8_t step_sign;
1196 int ret = 10; /* 1ms is the default delay most of the time */ 2038 int ret = 10; /* 1ms is the default delay most of the time */
1197 u8 c, i; 2039 u8 c, i;
1198 2040
1199 state->current_band = (u8) BAND_OF_FREQUENCY(fe->dtv_property_cache.frequency / 1000); 2041 /************************* VCO ***************************/
1200 rf = fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
1201 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->freq_offset_khz_vhf);
1202 /* in any case we first need to do a reset if needed */
1203 if (state->reset & 0x1)
1204 return dib0090_dc_offset_calibration(state, tune_state);
1205 else if (state->reset & 0x2)
1206 return dib0090_wbd_calibration(state, tune_state);
1207
1208 /************************* VCO ***************************/
1209 /* Default values for FG */ 2042 /* Default values for FG */
1210 /* from these are needed : */ 2043 /* from these are needed : */
1211 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */ 2044 /* Cp,HFdiv,VCOband,SD,Num,Den,FB and REFDiv */
1212 2045
1213#ifdef CONFIG_SYS_ISDBT 2046 /* in any case we first need to do a calibration if needed */
1214 if (state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1) 2047 if (*tune_state == CT_TUNER_START) {
1215 rf += 850; 2048 /* deactivate DataTX before some calibrations */
1216#endif 2049 if (state->calibrate & (DC_CAL | TEMP_CAL | WBD_CAL))
2050 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) & ~(1 << 14));
2051 else
2052 /* Activate DataTX in case a calibration has been done before */
2053 if (state->config->analog_output == 0)
2054 dib0090_write_reg(state, 0x23, dib0090_read_reg(state, 0x23) | (1 << 14));
2055 }
1217 2056
1218 if (state->current_rf != rf) { 2057 if (state->calibrate & DC_CAL)
1219 state->tuner_is_tuned = 0; 2058 return dib0090_dc_offset_calibration(state, tune_state);
2059 else if (state->calibrate & WBD_CAL) {
2060 if (state->current_rf == 0)
2061 state->current_rf = state->fe->dtv_property_cache.frequency / 1000;
2062 return dib0090_wbd_calibration(state, tune_state);
2063 } else if (state->calibrate & TEMP_CAL)
2064 return dib0090_get_temperature(state, tune_state);
2065 else if (state->calibrate & CAPTRIM_CAL)
2066 return dib0090_captrim_search(state, tune_state);
1220 2067
1221 tune = dib0090_tuning_table; 2068 if (*tune_state == CT_TUNER_START) {
2069 /* if soc and AGC pwm control, disengage mux to be able to R/W access to 0x01 register to set the right filter (cutoff_freq_select) during the tune sequence, otherwise, SOC SERPAR error when accessing to 0x01 */
2070 if (state->config->use_pwm_agc && state->identity.in_soc) {
2071 tmp = dib0090_read_reg(state, 0x39);
2072 if ((tmp >> 10) & 0x1)
2073 dib0090_write_reg(state, 0x39, tmp & ~(1 << 10));
2074 }
1222 2075
1223 tmp = (state->revision >> 5) & 0x7; 2076 state->current_band = (u8) BAND_OF_FREQUENCY(state->fe->dtv_property_cache.frequency / 1000);
1224 if (tmp == 0x4 || tmp == 0x7) { 2077 state->rf_request =
1225 /* CBAND tuner version for VHF */ 2078 state->fe->dtv_property_cache.frequency / 1000 + (state->current_band ==
1226 if (state->current_band == BAND_FM || state->current_band == BAND_VHF) { 2079 BAND_UHF ? state->config->freq_offset_khz_uhf : state->config->
1227 /* Force CBAND */ 2080 freq_offset_khz_vhf);
1228 state->current_band = BAND_CBAND; 2081
1229 tune = dib0090_tuning_table_fm_vhf_on_cband; 2082 /* in ISDB-T 1seg we shift tuning frequency */
2083 if ((state->fe->dtv_property_cache.delivery_system == SYS_ISDBT && state->fe->dtv_property_cache.isdbt_sb_mode == 1
2084 && state->fe->dtv_property_cache.isdbt_partial_reception == 0)) {
2085 const struct dib0090_low_if_offset_table *LUT_offset = state->config->low_if;
2086 u8 found_offset = 0;
2087 u32 margin_khz = 100;
2088
2089 if (LUT_offset != NULL) {
2090 while (LUT_offset->RF_freq != 0xffff) {
2091 if (((state->rf_request > (LUT_offset->RF_freq - margin_khz))
2092 && (state->rf_request < (LUT_offset->RF_freq + margin_khz)))
2093 && LUT_offset->std == state->fe->dtv_property_cache.delivery_system) {
2094 state->rf_request += LUT_offset->offset_khz;
2095 found_offset = 1;
2096 break;
2097 }
2098 LUT_offset++;
2099 }
1230 } 2100 }
2101
2102 if (found_offset == 0)
2103 state->rf_request += 400;
1231 } 2104 }
2105 if (state->current_rf != state->rf_request || (state->current_standard != state->fe->dtv_property_cache.delivery_system)) {
2106 state->tuner_is_tuned = 0;
2107 state->current_rf = 0;
2108 state->current_standard = 0;
1232 2109
1233 pll = dib0090_pll_table; 2110 tune = dib0090_tuning_table;
1234 /* Look for the interval */ 2111 if (state->identity.p1g)
1235 while (rf > tune->max_freq) 2112 tune = dib0090_p1g_tuning_table;
1236 tune++;
1237 while (rf > pll->max_freq)
1238 pll++;
1239 state->current_tune_table_index = tune;
1240 state->current_pll_table_index = pll;
1241 }
1242 2113
1243 if (*tune_state == CT_TUNER_START) { 2114 tmp = (state->identity.version >> 5) & 0x7;
1244 2115
1245 if (state->tuner_is_tuned == 0) 2116 if (state->identity.in_soc) {
1246 state->current_rf = 0; 2117 if (state->config->force_cband_input) { /* Use the CBAND input for all band */
2118 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF
2119 || state->current_band & BAND_UHF) {
2120 state->current_band = BAND_CBAND;
2121 tune = dib0090_tuning_table_cband_7090;
2122 }
2123 } else { /* Use the CBAND input for all band under UHF */
2124 if (state->current_band & BAND_CBAND || state->current_band & BAND_FM || state->current_band & BAND_VHF) {
2125 state->current_band = BAND_CBAND;
2126 tune = dib0090_tuning_table_cband_7090;
2127 }
2128 }
2129 } else
2130 if (tmp == 0x4 || tmp == 0x7) {
2131 /* CBAND tuner version for VHF */
2132 if (state->current_band == BAND_FM || state->current_band == BAND_CBAND || state->current_band == BAND_VHF) {
2133 state->current_band = BAND_CBAND; /* Force CBAND */
2134
2135 tune = dib0090_tuning_table_fm_vhf_on_cband;
2136 if (state->identity.p1g)
2137 tune = dib0090_p1g_tuning_table_fm_vhf_on_cband;
2138 }
2139 }
1247 2140
1248 if (state->current_rf != rf) { 2141 pll = dib0090_pll_table;
2142 if (state->identity.p1g)
2143 pll = dib0090_p1g_pll_table;
1249 2144
1250 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim)); 2145 /* Look for the interval */
2146 while (state->rf_request > tune->max_freq)
2147 tune++;
2148 while (state->rf_request > pll->max_freq)
2149 pll++;
1251 2150
1252 /* external loop filter, otherwise: 2151 state->current_tune_table_index = tune;
1253 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4; 2152 state->current_pll_table_index = pll;
1254 * lo6 = 0x0e34 */
1255 if (pll->vco_band)
1256 lo5 = 0x049e;
1257 else if (state->config->analog_output)
1258 lo5 = 0x041d;
1259 else
1260 lo5 = 0x041c;
1261
1262 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
1263 2153
1264 if (!state->config->io.pll_int_loop_filt) 2154 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->switch_trim));
1265 lo6 = 0xff28;
1266 else
1267 lo6 = (state->config->io.pll_int_loop_filt << 3);
1268 2155
1269 VCOF_kHz = (pll->hfdiv * rf) * 2; 2156 VCOF_kHz = (pll->hfdiv * state->rf_request) * 2;
1270 2157
1271 FREF = state->config->io.clock_khz; 2158 FREF = state->config->io.clock_khz;
2159 if (state->config->fref_clock_ratio != 0)
2160 FREF /= state->config->fref_clock_ratio;
1272 2161
1273 FBDiv = (VCOF_kHz / pll->topresc / FREF); 2162 FBDiv = (VCOF_kHz / pll->topresc / FREF);
1274 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF; 2163 Rest = (VCOF_kHz / pll->topresc) - FBDiv * FREF;
@@ -1283,144 +2172,132 @@ static int dib0090_tune(struct dvb_frontend *fe)
1283 } else if (Rest > (FREF - 2 * LPF)) 2172 } else if (Rest > (FREF - 2 * LPF))
1284 Rest = FREF - 2 * LPF; 2173 Rest = FREF - 2 * LPF;
1285 Rest = (Rest * 6528) / (FREF / 10); 2174 Rest = (Rest * 6528) / (FREF / 10);
2175 state->rest = Rest;
1286 2176
1287 Den = 1; 2177 /* external loop filter, otherwise:
2178 * lo5 = (0 << 15) | (0 << 12) | (0 << 11) | (3 << 9) | (4 << 6) | (3 << 4) | 4;
2179 * lo6 = 0x0e34 */
2180
2181 if (Rest == 0) {
2182 if (pll->vco_band)
2183 lo5 = 0x049f;
2184 else
2185 lo5 = 0x041f;
2186 } else {
2187 if (pll->vco_band)
2188 lo5 = 0x049e;
2189 else if (state->config->analog_output)
2190 lo5 = 0x041d;
2191 else
2192 lo5 = 0x041c;
2193 }
2194
2195 if (state->identity.p1g) { /* Bias is done automatically in P1G */
2196 if (state->identity.in_soc) {
2197 if (state->identity.version == SOC_8090_P1G_11R1)
2198 lo5 = 0x46f;
2199 else
2200 lo5 = 0x42f;
2201 } else
2202 lo5 = 0x42c;
2203 }
2204
2205 lo5 |= (pll->hfdiv_code << 11) | (pll->vco_band << 7); /* bit 15 is the split to the slave, we do not do it here */
1288 2206
1289 dprintk(" ***** ******* Rest value = %d", Rest); 2207 if (!state->config->io.pll_int_loop_filt) {
2208 if (state->identity.in_soc)
2209 lo6 = 0xff98;
2210 else if (state->identity.p1g || (Rest == 0))
2211 lo6 = 0xfff8;
2212 else
2213 lo6 = 0xff28;
2214 } else
2215 lo6 = (state->config->io.pll_int_loop_filt << 3);
2216
2217 Den = 1;
1290 2218
1291 if (Rest > 0) { 2219 if (Rest > 0) {
1292 if (state->config->analog_output) 2220 if (state->config->analog_output)
1293 lo6 |= (1 << 2) | 2; 2221 lo6 |= (1 << 2) | 2;
1294 else 2222 else {
1295 lo6 |= (1 << 2) | 1; 2223 if (state->identity.in_soc)
2224 lo6 |= (1 << 2) | 2;
2225 else
2226 lo6 |= (1 << 2) | 2;
2227 }
1296 Den = 255; 2228 Den = 255;
1297 } 2229 }
1298#ifdef CONFIG_BAND_SBAND
1299 if (state->current_band == BAND_SBAND)
1300 lo6 &= 0xfffb;
1301#endif
1302
1303 dib0090_write_reg(state, 0x15, (u16) FBDiv); 2230 dib0090_write_reg(state, 0x15, (u16) FBDiv);
1304 2231 if (state->config->fref_clock_ratio != 0)
1305 dib0090_write_reg(state, 0x16, (Den << 8) | 1); 2232 dib0090_write_reg(state, 0x16, (Den << 8) | state->config->fref_clock_ratio);
1306 2233 else
2234 dib0090_write_reg(state, 0x16, (Den << 8) | 1);
1307 dib0090_write_reg(state, 0x17, (u16) Rest); 2235 dib0090_write_reg(state, 0x17, (u16) Rest);
1308
1309 dib0090_write_reg(state, 0x19, lo5); 2236 dib0090_write_reg(state, 0x19, lo5);
1310
1311 dib0090_write_reg(state, 0x1c, lo6); 2237 dib0090_write_reg(state, 0x1c, lo6);
1312 2238
1313 lo6 = tune->tuner_enable; 2239 lo6 = tune->tuner_enable;
1314 if (state->config->analog_output) 2240 if (state->config->analog_output)
1315 lo6 = (lo6 & 0xff9f) | 0x2; 2241 lo6 = (lo6 & 0xff9f) | 0x2;
1316 2242
1317 dib0090_write_reg(state, 0x24, lo6 | EN_LO 2243 dib0090_write_reg(state, 0x24, lo6 | EN_LO | state->config->use_pwm_agc * EN_CRYSTAL);
1318#ifdef CONFIG_DIB0090_USE_PWM_AGC
1319 | state->config->use_pwm_agc * EN_CRYSTAL
1320#endif
1321 );
1322
1323 state->current_rf = rf;
1324
1325 /* prepare a complete captrim */
1326 state->step = state->captrim = state->fcaptrim = 64;
1327
1328 } else { /* we are already tuned to this frequency - the configuration is correct */
1329 2244
1330 /* do a minimal captrim even if the frequency has not changed */
1331 state->step = 4;
1332 state->captrim = state->fcaptrim = dib0090_read_reg(state, 0x18) & 0x7f;
1333 } 2245 }
1334 state->adc_diff = 3000;
1335
1336 dib0090_write_reg(state, 0x10, 0x2B1);
1337 2246
1338 dib0090_write_reg(state, 0x1e, 0x0032); 2247 state->current_rf = state->rf_request;
2248 state->current_standard = state->fe->dtv_property_cache.delivery_system;
1339 2249
1340 ret = 20; 2250 ret = 20;
1341 *tune_state = CT_TUNER_STEP_1; 2251 state->calibrate = CAPTRIM_CAL; /* captrim serach now */
1342 } else if (*tune_state == CT_TUNER_STEP_0) { 2252 }
1343 /* nothing */
1344 } else if (*tune_state == CT_TUNER_STEP_1) {
1345 state->step /= 2;
1346 dib0090_write_reg(state, 0x18, lo4 | state->captrim);
1347 *tune_state = CT_TUNER_STEP_2;
1348 } else if (*tune_state == CT_TUNER_STEP_2) {
1349 2253
1350 adc = dib0090_read_reg(state, 0x1d); 2254 else if (*tune_state == CT_TUNER_STEP_0) { /* Warning : because of captrim cal, if you change this step, change it also in _cal.c file because it is the step following captrim cal state machine */
1351 dprintk("FE %d CAPTRIM=%d; ADC = %d (ADC) & %dmV", (u32) fe->id, (u32) state->captrim, (u32) adc, 2255 const struct dib0090_wbd_slope *wbd = state->current_wbd_table;
1352 (u32) (adc) * (u32) 1800 / (u32) 1024);
1353 2256
1354 if (adc >= 400) { 2257 while (state->current_rf / 1000 > wbd->max_freq)
1355 adc -= 400; 2258 wbd++;
1356 step_sign = -1;
1357 } else {
1358 adc = 400 - adc;
1359 step_sign = 1;
1360 }
1361 2259
1362 if (adc < state->adc_diff) { 2260 dib0090_write_reg(state, 0x1e, 0x07ff);
1363 dprintk("FE %d CAPTRIM=%d is closer to target (%d/%d)", (u32) fe->id, (u32) state->captrim, (u32) adc, (u32) state->adc_diff); 2261 dprintk("Final Captrim: %d", (u32) state->fcaptrim);
1364 state->adc_diff = adc; 2262 dprintk("HFDIV code: %d", (u32) pll->hfdiv_code);
1365 state->fcaptrim = state->captrim; 2263 dprintk("VCO = %d", (u32) pll->vco_band);
1366 2264 dprintk("VCOF in kHz: %d ((%d*%d) << 1))", (u32) ((pll->hfdiv * state->rf_request) * 2), (u32) pll->hfdiv, (u32) state->rf_request);
1367 } 2265 dprintk("REFDIV: %d, FREF: %d", (u32) 1, (u32) state->config->io.clock_khz);
2266 dprintk("FBDIV: %d, Rest: %d", (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
2267 dprintk("Num: %d, Den: %d, SD: %d", (u32) dib0090_read_reg(state, 0x17), (u32) (dib0090_read_reg(state, 0x16) >> 8),
2268 (u32) dib0090_read_reg(state, 0x1c) & 0x3);
1368 2269
1369 state->captrim += step_sign * state->step; 2270#define WBD 0x781 /* 1 1 1 1 0000 0 0 1 */
1370 if (state->step >= 1) 2271 c = 4;
1371 *tune_state = CT_TUNER_STEP_1; 2272 i = 3;
1372 else
1373 *tune_state = CT_TUNER_STEP_3;
1374 2273
1375 ret = 15; 2274 if (wbd->wbd_gain != 0)
1376 } else if (*tune_state == CT_TUNER_STEP_3) { 2275 c = wbd->wbd_gain;
1377 /*write the final cptrim config */
1378 dib0090_write_reg(state, 0x18, lo4 | state->fcaptrim);
1379 2276
1380#ifdef CONFIG_TUNER_DIB0090_CAPTRIM_MEMORY 2277 state->wbdmux = (c << 13) | (i << 11) | (WBD | (state->config->use_pwm_agc << 1));
1381 state->memory[state->memory_index].cap = state->fcaptrim; 2278 dib0090_write_reg(state, 0x10, state->wbdmux);
1382#endif
1383 2279
1384 *tune_state = CT_TUNER_STEP_4; 2280 if ((tune->tuner_enable == EN_CAB) && state->identity.p1g) {
1385 } else if (*tune_state == CT_TUNER_STEP_4) { 2281 dprintk("P1G : The cable band is selected and lna_tune = %d", tune->lna_tune);
1386 dib0090_write_reg(state, 0x1e, 0x07ff); 2282 dib0090_write_reg(state, 0x09, tune->lna_bias);
1387 2283 dib0090_write_reg(state, 0x0b, 0xb800 | (tune->lna_tune << 6) | (tune->switch_trim));
1388 dprintk("FE %d Final Captrim: %d", (u32) fe->id, (u32) state->fcaptrim); 2284 } else
1389 dprintk("FE %d HFDIV code: %d", (u32) fe->id, (u32) pll->hfdiv_code); 2285 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | tune->lna_bias);
1390 dprintk("FE %d VCO = %d", (u32) fe->id, (u32) pll->vco_band);
1391 dprintk("FE %d VCOF in kHz: %d ((%d*%d) << 1))", (u32) fe->id, (u32) ((pll->hfdiv * rf) * 2), (u32) pll->hfdiv, (u32) rf);
1392 dprintk("FE %d REFDIV: %d, FREF: %d", (u32) fe->id, (u32) 1, (u32) state->config->io.clock_khz);
1393 dprintk("FE %d FBDIV: %d, Rest: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x15), (u32) dib0090_read_reg(state, 0x17));
1394 dprintk("FE %d Num: %d, Den: %d, SD: %d", (u32) fe->id, (u32) dib0090_read_reg(state, 0x17),
1395 (u32) (dib0090_read_reg(state, 0x16) >> 8), (u32) dib0090_read_reg(state, 0x1c) & 0x3);
1396 2286
1397 c = 4;
1398 i = 3;
1399#if defined(CONFIG_BAND_LBAND) || defined(CONFIG_BAND_SBAND)
1400 if ((state->current_band == BAND_LBAND) || (state->current_band == BAND_SBAND)) {
1401 c = 2;
1402 i = 2;
1403 }
1404#endif
1405 dib0090_write_reg(state, 0x10, (c << 13) | (i << 11) | (WBD
1406#ifdef CONFIG_DIB0090_USE_PWM_AGC
1407 | (state->config->use_pwm_agc << 1)
1408#endif
1409 ));
1410 dib0090_write_reg(state, 0x09, (tune->lna_tune << 5) | (tune->lna_bias << 0));
1411 dib0090_write_reg(state, 0x0c, tune->v2i); 2287 dib0090_write_reg(state, 0x0c, tune->v2i);
1412 dib0090_write_reg(state, 0x0d, tune->mix); 2288 dib0090_write_reg(state, 0x0d, tune->mix);
1413 dib0090_write_reg(state, 0x0e, tune->load); 2289 dib0090_write_reg(state, 0x0e, tune->load);
2290 *tune_state = CT_TUNER_STEP_1;
1414 2291
1415 *tune_state = CT_TUNER_STEP_5; 2292 } else if (*tune_state == CT_TUNER_STEP_1) {
1416 } else if (*tune_state == CT_TUNER_STEP_5) {
1417
1418 /* initialize the lt gain register */ 2293 /* initialize the lt gain register */
1419 state->rf_lt_def = 0x7c00; 2294 state->rf_lt_def = 0x7c00;
1420 dib0090_write_reg(state, 0x0f, state->rf_lt_def);
1421 2295
1422 dib0090_set_bandwidth(state); 2296 dib0090_set_bandwidth(state);
1423 state->tuner_is_tuned = 1; 2297 state->tuner_is_tuned = 1;
2298
2299 state->calibrate |= WBD_CAL;
2300 state->calibrate |= TEMP_CAL;
1424 *tune_state = CT_TUNER_STOP; 2301 *tune_state = CT_TUNER_STOP;
1425 } else 2302 } else
1426 ret = FE_CALLBACK_TIME_NEVER; 2303 ret = FE_CALLBACK_TIME_NEVER;
@@ -1440,6 +2317,7 @@ enum frontend_tune_state dib0090_get_tune_state(struct dvb_frontend *fe)
1440 2317
1441 return state->tune_state; 2318 return state->tune_state;
1442} 2319}
2320
1443EXPORT_SYMBOL(dib0090_get_tune_state); 2321EXPORT_SYMBOL(dib0090_get_tune_state);
1444 2322
1445int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state) 2323int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
@@ -1449,6 +2327,7 @@ int dib0090_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun
1449 state->tune_state = tune_state; 2327 state->tune_state = tune_state;
1450 return 0; 2328 return 0;
1451} 2329}
2330
1452EXPORT_SYMBOL(dib0090_set_tune_state); 2331EXPORT_SYMBOL(dib0090_set_tune_state);
1453 2332
1454static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency) 2333static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
@@ -1462,7 +2341,7 @@ static int dib0090_get_frequency(struct dvb_frontend *fe, u32 * frequency)
1462static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p) 2341static int dib0090_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
1463{ 2342{
1464 struct dib0090_state *state = fe->tuner_priv; 2343 struct dib0090_state *state = fe->tuner_priv;
1465 uint32_t ret; 2344 u32 ret;
1466 2345
1467 state->tune_state = CT_TUNER_START; 2346 state->tune_state = CT_TUNER_START;
1468 2347
@@ -1492,6 +2371,29 @@ static const struct dvb_tuner_ops dib0090_ops = {
1492 .get_frequency = dib0090_get_frequency, 2371 .get_frequency = dib0090_get_frequency,
1493}; 2372};
1494 2373
2374static const struct dvb_tuner_ops dib0090_fw_ops = {
2375 .info = {
2376 .name = "DiBcom DiB0090",
2377 .frequency_min = 45000000,
2378 .frequency_max = 860000000,
2379 .frequency_step = 1000,
2380 },
2381 .release = dib0090_release,
2382
2383 .init = NULL,
2384 .sleep = NULL,
2385 .set_params = NULL,
2386 .get_frequency = NULL,
2387};
2388
2389static const struct dib0090_wbd_slope dib0090_wbd_table_default[] = {
2390 {470, 0, 250, 0, 100, 4},
2391 {860, 51, 866, 21, 375, 4},
2392 {1700, 0, 800, 0, 850, 4},
2393 {2900, 0, 250, 0, 100, 6},
2394 {0xFFFF, 0, 0, 0, 0, 0},
2395};
2396
1495struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config) 2397struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
1496{ 2398{
1497 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL); 2399 struct dib0090_state *st = kzalloc(sizeof(struct dib0090_state), GFP_KERNEL);
@@ -1503,6 +2405,11 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte
1503 st->fe = fe; 2405 st->fe = fe;
1504 fe->tuner_priv = st; 2406 fe->tuner_priv = st;
1505 2407
2408 if (config->wbd == NULL)
2409 st->current_wbd_table = dib0090_wbd_table_default;
2410 else
2411 st->current_wbd_table = config->wbd;
2412
1506 if (dib0090_reset(fe) != 0) 2413 if (dib0090_reset(fe) != 0)
1507 goto free_mem; 2414 goto free_mem;
1508 2415
@@ -1515,8 +2422,34 @@ struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapte
1515 fe->tuner_priv = NULL; 2422 fe->tuner_priv = NULL;
1516 return NULL; 2423 return NULL;
1517} 2424}
2425
1518EXPORT_SYMBOL(dib0090_register); 2426EXPORT_SYMBOL(dib0090_register);
1519 2427
2428struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config)
2429{
2430 struct dib0090_fw_state *st = kzalloc(sizeof(struct dib0090_fw_state), GFP_KERNEL);
2431 if (st == NULL)
2432 return NULL;
2433
2434 st->config = config;
2435 st->i2c = i2c;
2436 st->fe = fe;
2437 fe->tuner_priv = st;
2438
2439 if (dib0090_fw_reset_digital(fe, st->config) != 0)
2440 goto free_mem;
2441
2442 dprintk("DiB0090 FW: successfully identified");
2443 memcpy(&fe->ops.tuner_ops, &dib0090_fw_ops, sizeof(struct dvb_tuner_ops));
2444
2445 return fe;
2446free_mem:
2447 kfree(st);
2448 fe->tuner_priv = NULL;
2449 return NULL;
2450}
2451EXPORT_SYMBOL(dib0090_fw_register);
2452
1520MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 2453MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1521MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>"); 2454MODULE_AUTHOR("Olivier Grenie <olivier.grenie@dibcom.fr>");
1522MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner"); 2455MODULE_DESCRIPTION("Driver for the DiBcom 0090 base-band RF Tuner");
diff --git a/drivers/media/dvb/frontends/dib0090.h b/drivers/media/dvb/frontends/dib0090.h
index aa7711e88776..13d85244ec16 100644
--- a/drivers/media/dvb/frontends/dib0090.h
+++ b/drivers/media/dvb/frontends/dib0090.h
@@ -27,6 +27,21 @@ struct dib0090_io_config {
27 u16 pll_int_loop_filt; 27 u16 pll_int_loop_filt;
28}; 28};
29 29
30struct dib0090_wbd_slope {
31 u16 max_freq; /* for every frequency less than or equal to that field: this information is correct */
32 u16 slope_cold;
33 u16 offset_cold;
34 u16 slope_hot;
35 u16 offset_hot;
36 u8 wbd_gain;
37};
38
39struct dib0090_low_if_offset_table {
40 int std;
41 u32 RF_freq;
42 s32 offset_khz;
43};
44
30struct dib0090_config { 45struct dib0090_config {
31 struct dib0090_io_config io; 46 struct dib0090_io_config io;
32 int (*reset) (struct dvb_frontend *, int); 47 int (*reset) (struct dvb_frontend *, int);
@@ -47,10 +62,20 @@ struct dib0090_config {
47 u16 wbd_cband_offset; 62 u16 wbd_cband_offset;
48 u8 use_pwm_agc; 63 u8 use_pwm_agc;
49 u8 clkoutdrive; 64 u8 clkoutdrive;
65
66 u8 ls_cfg_pad_drv;
67 u8 data_tx_drv;
68
69 u8 in_soc;
70 const struct dib0090_low_if_offset_table *low_if;
71 u8 fref_clock_ratio;
72 u16 force_cband_input;
73 struct dib0090_wbd_slope *wbd;
50}; 74};
51 75
52#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE)) 76#if defined(CONFIG_DVB_TUNER_DIB0090) || (defined(CONFIG_DVB_TUNER_DIB0090_MODULE) && defined(MODULE))
53extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config); 77extern struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
78extern struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, const struct dib0090_config *config);
54extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast); 79extern void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast);
55extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe); 80extern void dib0090_pwm_gain_reset(struct dvb_frontend *fe);
56extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner); 81extern u16 dib0090_get_wbd_offset(struct dvb_frontend *tuner);
@@ -65,6 +90,12 @@ static inline struct dvb_frontend *dib0090_register(struct dvb_frontend *fe, str
65 return NULL; 90 return NULL;
66} 91}
67 92
93static inline struct dvb_frontend *dib0090_fw_register(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0090_config *config)
94{
95 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
96 return NULL;
97}
98
68static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast) 99static inline void dib0090_dcc_freq(struct dvb_frontend *fe, u8 fast)
69{ 100{
70 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 101 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
diff --git a/drivers/media/dvb/frontends/dib7000p.c b/drivers/media/dvb/frontends/dib7000p.c
index 6aa02cb80733..900af60b9d36 100644
--- a/drivers/media/dvb/frontends/dib7000p.c
+++ b/drivers/media/dvb/frontends/dib7000p.c
@@ -26,24 +26,29 @@ MODULE_PARM_DESC(buggy_sfn_workaround, "Enable work-around for buggy SFNs (defau
26 26
27#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0) 27#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB7000P: "); printk(args); printk("\n"); } } while (0)
28 28
29struct i2c_device {
30 struct i2c_adapter *i2c_adap;
31 u8 i2c_addr;
32};
33
29struct dib7000p_state { 34struct dib7000p_state {
30 struct dvb_frontend demod; 35 struct dvb_frontend demod;
31 struct dib7000p_config cfg; 36 struct dib7000p_config cfg;
32 37
33 u8 i2c_addr; 38 u8 i2c_addr;
34 struct i2c_adapter *i2c_adap; 39 struct i2c_adapter *i2c_adap;
35 40
36 struct dibx000_i2c_master i2c_master; 41 struct dibx000_i2c_master i2c_master;
37 42
38 u16 wbd_ref; 43 u16 wbd_ref;
39 44
40 u8 current_band; 45 u8 current_band;
41 u32 current_bandwidth; 46 u32 current_bandwidth;
42 struct dibx000_agc_config *current_agc; 47 struct dibx000_agc_config *current_agc;
43 u32 timf; 48 u32 timf;
44 49
45 u8 div_force_off : 1; 50 u8 div_force_off:1;
46 u8 div_state : 1; 51 u8 div_state:1;
47 u16 div_sync_wait; 52 u16 div_sync_wait;
48 53
49 u8 agc_state; 54 u8 agc_state;
@@ -51,7 +56,13 @@ struct dib7000p_state {
51 u16 gpio_dir; 56 u16 gpio_dir;
52 u16 gpio_val; 57 u16 gpio_val;
53 58
54 u8 sfn_workaround_active :1; 59 u8 sfn_workaround_active:1;
60
61#define SOC7090 0x7090
62 u16 version;
63
64 u16 tuner_enable;
65 struct i2c_adapter dib7090_tuner_adap;
55}; 66};
56 67
57enum dib7000p_power_mode { 68enum dib7000p_power_mode {
@@ -60,17 +71,20 @@ enum dib7000p_power_mode {
60 DIB7000P_POWER_INTERFACE_ONLY, 71 DIB7000P_POWER_INTERFACE_ONLY,
61}; 72};
62 73
74static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode);
75static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff);
76
63static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg) 77static u16 dib7000p_read_word(struct dib7000p_state *state, u16 reg)
64{ 78{
65 u8 wb[2] = { reg >> 8, reg & 0xff }; 79 u8 wb[2] = { reg >> 8, reg & 0xff };
66 u8 rb[2]; 80 u8 rb[2];
67 struct i2c_msg msg[2] = { 81 struct i2c_msg msg[2] = {
68 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 }, 82 {.addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
69 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 }, 83 {.addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2},
70 }; 84 };
71 85
72 if (i2c_transfer(state->i2c_adap, msg, 2) != 2) 86 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
73 dprintk("i2c read error on %d",reg); 87 dprintk("i2c read error on %d", reg);
74 88
75 return (rb[0] << 8) | rb[1]; 89 return (rb[0] << 8) | rb[1];
76} 90}
@@ -86,7 +100,8 @@ static int dib7000p_write_word(struct dib7000p_state *state, u16 reg, u16 val)
86 }; 100 };
87 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 101 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
88} 102}
89static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf) 103
104static void dib7000p_write_tab(struct dib7000p_state *state, u16 * buf)
90{ 105{
91 u16 l = 0, r, *n; 106 u16 l = 0, r, *n;
92 n = buf; 107 n = buf;
@@ -104,54 +119,54 @@ static void dib7000p_write_tab(struct dib7000p_state *state, u16 *buf)
104 119
105static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode) 120static int dib7000p_set_output_mode(struct dib7000p_state *state, int mode)
106{ 121{
107 int ret = 0; 122 int ret = 0;
108 u16 outreg, fifo_threshold, smo_mode; 123 u16 outreg, fifo_threshold, smo_mode;
109 124
110 outreg = 0; 125 outreg = 0;
111 fifo_threshold = 1792; 126 fifo_threshold = 1792;
112 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1); 127 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
113 128
114 dprintk( "setting output mode for demod %p to %d", 129 dprintk("setting output mode for demod %p to %d", &state->demod, mode);
115 &state->demod, mode);
116 130
117 switch (mode) { 131 switch (mode) {
118 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 132 case OUTMODE_MPEG2_PAR_GATED_CLK:
119 outreg = (1 << 10); /* 0x0400 */ 133 outreg = (1 << 10); /* 0x0400 */
120 break; 134 break;
121 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock 135 case OUTMODE_MPEG2_PAR_CONT_CLK:
122 outreg = (1 << 10) | (1 << 6); /* 0x0440 */ 136 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
123 break; 137 break;
124 case OUTMODE_MPEG2_SERIAL: // STBs with serial input 138 case OUTMODE_MPEG2_SERIAL:
125 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */ 139 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0480 */
126 break; 140 break;
127 case OUTMODE_DIVERSITY: 141 case OUTMODE_DIVERSITY:
128 if (state->cfg.hostbus_diversity) 142 if (state->cfg.hostbus_diversity)
129 outreg = (1 << 10) | (4 << 6); /* 0x0500 */ 143 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
130 else 144 else
131 outreg = (1 << 11); 145 outreg = (1 << 11);
132 break; 146 break;
133 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding 147 case OUTMODE_MPEG2_FIFO:
134 smo_mode |= (3 << 1); 148 smo_mode |= (3 << 1);
135 fifo_threshold = 512; 149 fifo_threshold = 512;
136 outreg = (1 << 10) | (5 << 6); 150 outreg = (1 << 10) | (5 << 6);
137 break; 151 break;
138 case OUTMODE_ANALOG_ADC: 152 case OUTMODE_ANALOG_ADC:
139 outreg = (1 << 10) | (3 << 6); 153 outreg = (1 << 10) | (3 << 6);
140 break; 154 break;
141 case OUTMODE_HIGH_Z: // disable 155 case OUTMODE_HIGH_Z:
142 outreg = 0; 156 outreg = 0;
143 break; 157 break;
144 default: 158 default:
145 dprintk( "Unhandled output_mode passed to be set for demod %p",&state->demod); 159 dprintk("Unhandled output_mode passed to be set for demod %p", &state->demod);
146 break; 160 break;
147 } 161 }
148 162
149 if (state->cfg.output_mpeg2_in_188_bytes) 163 if (state->cfg.output_mpeg2_in_188_bytes)
150 smo_mode |= (1 << 5) ; 164 smo_mode |= (1 << 5);
151 165
152 ret |= dib7000p_write_word(state, 235, smo_mode); 166 ret |= dib7000p_write_word(state, 235, smo_mode);
153 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */ 167 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
154 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */ 168 if (state->version != SOC7090)
169 ret |= dib7000p_write_word(state, 1286, outreg); /* P_Div_active */
155 170
156 return ret; 171 return ret;
157} 172}
@@ -161,13 +176,13 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
161 struct dib7000p_state *state = demod->demodulator_priv; 176 struct dib7000p_state *state = demod->demodulator_priv;
162 177
163 if (state->div_force_off) { 178 if (state->div_force_off) {
164 dprintk( "diversity combination deactivated - forced by COFDM parameters"); 179 dprintk("diversity combination deactivated - forced by COFDM parameters");
165 onoff = 0; 180 onoff = 0;
166 dib7000p_write_word(state, 207, 0); 181 dib7000p_write_word(state, 207, 0);
167 } else 182 } else
168 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0)); 183 dib7000p_write_word(state, 207, (state->div_sync_wait << 4) | (1 << 2) | (2 << 0));
169 184
170 state->div_state = (u8)onoff; 185 state->div_state = (u8) onoff;
171 186
172 if (onoff) { 187 if (onoff) {
173 dib7000p_write_word(state, 204, 6); 188 dib7000p_write_word(state, 204, 6);
@@ -184,37 +199,48 @@ static int dib7000p_set_diversity_in(struct dvb_frontend *demod, int onoff)
184static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode) 199static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_power_mode mode)
185{ 200{
186 /* by default everything is powered off */ 201 /* by default everything is powered off */
187 u16 reg_774 = 0xffff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, 202 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0x0007, reg_899 = 0x0003, reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
188 reg_1280 = (0xfe00) | (dib7000p_read_word(state, 1280) & 0x01ff);
189 203
190 /* now, depending on the requested mode, we power on */ 204 /* now, depending on the requested mode, we power on */
191 switch (mode) { 205 switch (mode) {
192 /* power up everything in the demod */ 206 /* power up everything in the demod */
193 case DIB7000P_POWER_ALL: 207 case DIB7000P_POWER_ALL:
194 reg_774 = 0x0000; reg_775 = 0x0000; reg_776 = 0x0; reg_899 = 0x0; reg_1280 &= 0x01ff; 208 reg_774 = 0x0000;
195 break; 209 reg_775 = 0x0000;
196 210 reg_776 = 0x0;
197 case DIB7000P_POWER_ANALOG_ADC: 211 reg_899 = 0x0;
198 /* dem, cfg, iqc, sad, agc */ 212 if (state->version == SOC7090)
199 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9)); 213 reg_1280 &= 0x001f;
200 /* nud */ 214 else
201 reg_776 &= ~((1 << 0)); 215 reg_1280 &= 0x01ff;
202 /* Dout */ 216 break;
217
218 case DIB7000P_POWER_ANALOG_ADC:
219 /* dem, cfg, iqc, sad, agc */
220 reg_774 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10) | (1 << 9));
221 /* nud */
222 reg_776 &= ~((1 << 0));
223 /* Dout */
224 if (state->version != SOC7090)
203 reg_1280 &= ~((1 << 11)); 225 reg_1280 &= ~((1 << 11));
204 /* fall through wanted to enable the interfaces */ 226 reg_1280 &= ~(1 << 6);
227 /* fall through wanted to enable the interfaces */
205 228
206 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */ 229 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO) */
207 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */ 230 case DIB7000P_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C */
231 if (state->version == SOC7090)
232 reg_1280 &= ~((1 << 7) | (1 << 5));
233 else
208 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10)); 234 reg_1280 &= ~((1 << 14) | (1 << 13) | (1 << 12) | (1 << 10));
209 break; 235 break;
210 236
211/* TODO following stuff is just converted from the dib7000-driver - check when is used what */ 237/* TODO following stuff is just converted from the dib7000-driver - check when is used what */
212 } 238 }
213 239
214 dib7000p_write_word(state, 774, reg_774); 240 dib7000p_write_word(state, 774, reg_774);
215 dib7000p_write_word(state, 775, reg_775); 241 dib7000p_write_word(state, 775, reg_775);
216 dib7000p_write_word(state, 776, reg_776); 242 dib7000p_write_word(state, 776, reg_776);
217 dib7000p_write_word(state, 899, reg_899); 243 dib7000p_write_word(state, 899, reg_899);
218 dib7000p_write_word(state, 1280, reg_1280); 244 dib7000p_write_word(state, 1280, reg_1280);
219 245
220 return 0; 246 return 0;
@@ -222,40 +248,57 @@ static int dib7000p_set_power_mode(struct dib7000p_state *state, enum dib7000p_p
222 248
223static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no) 249static void dib7000p_set_adc_state(struct dib7000p_state *state, enum dibx000_adc_states no)
224{ 250{
225 u16 reg_908 = dib7000p_read_word(state, 908), 251 u16 reg_908 = dib7000p_read_word(state, 908), reg_909 = dib7000p_read_word(state, 909);
226 reg_909 = dib7000p_read_word(state, 909); 252 u16 reg;
227 253
228 switch (no) { 254 switch (no) {
229 case DIBX000_SLOW_ADC_ON: 255 case DIBX000_SLOW_ADC_ON:
256 if (state->version == SOC7090) {
257 reg = dib7000p_read_word(state, 1925);
258
259 dib7000p_write_word(state, 1925, reg | (1 << 4) | (1 << 2)); /* en_slowAdc = 1 & reset_sladc = 1 */
260
261 reg = dib7000p_read_word(state, 1925); /* read acces to make it works... strange ... */
262 msleep(200);
263 dib7000p_write_word(state, 1925, reg & ~(1 << 4)); /* en_slowAdc = 1 & reset_sladc = 0 */
264
265 reg = dib7000p_read_word(state, 72) & ~((0x3 << 14) | (0x3 << 12));
266 dib7000p_write_word(state, 72, reg | (1 << 14) | (3 << 12) | 524); /* ref = Vin1 => Vbg ; sel = Vin0 or Vin3 ; (Vin2 = Vcm) */
267 } else {
230 reg_909 |= (1 << 1) | (1 << 0); 268 reg_909 |= (1 << 1) | (1 << 0);
231 dib7000p_write_word(state, 909, reg_909); 269 dib7000p_write_word(state, 909, reg_909);
232 reg_909 &= ~(1 << 1); 270 reg_909 &= ~(1 << 1);
233 break; 271 }
272 break;
234 273
235 case DIBX000_SLOW_ADC_OFF: 274 case DIBX000_SLOW_ADC_OFF:
236 reg_909 |= (1 << 1) | (1 << 0); 275 if (state->version == SOC7090) {
237 break; 276 reg = dib7000p_read_word(state, 1925);
277 dib7000p_write_word(state, 1925, (reg & ~(1 << 2)) | (1 << 4)); /* reset_sladc = 1 en_slowAdc = 0 */
278 } else
279 reg_909 |= (1 << 1) | (1 << 0);
280 break;
238 281
239 case DIBX000_ADC_ON: 282 case DIBX000_ADC_ON:
240 reg_908 &= 0x0fff; 283 reg_908 &= 0x0fff;
241 reg_909 &= 0x0003; 284 reg_909 &= 0x0003;
242 break; 285 break;
243 286
244 case DIBX000_ADC_OFF: // leave the VBG voltage on 287 case DIBX000_ADC_OFF:
245 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12); 288 reg_908 |= (1 << 14) | (1 << 13) | (1 << 12);
246 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2); 289 reg_909 |= (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2);
247 break; 290 break;
248 291
249 case DIBX000_VBG_ENABLE: 292 case DIBX000_VBG_ENABLE:
250 reg_908 &= ~(1 << 15); 293 reg_908 &= ~(1 << 15);
251 break; 294 break;
252 295
253 case DIBX000_VBG_DISABLE: 296 case DIBX000_VBG_DISABLE:
254 reg_908 |= (1 << 15); 297 reg_908 |= (1 << 15);
255 break; 298 break;
256 299
257 default: 300 default:
258 break; 301 break;
259 } 302 }
260 303
261// dprintk( "908: %x, 909: %x\n", reg_908, reg_909); 304// dprintk( "908: %x, 909: %x\n", reg_908, reg_909);
@@ -275,17 +318,17 @@ static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
275 state->current_bandwidth = bw; 318 state->current_bandwidth = bw;
276 319
277 if (state->timf == 0) { 320 if (state->timf == 0) {
278 dprintk( "using default timf"); 321 dprintk("using default timf");
279 timf = state->cfg.bw->timf; 322 timf = state->cfg.bw->timf;
280 } else { 323 } else {
281 dprintk( "using updated timf"); 324 dprintk("using updated timf");
282 timf = state->timf; 325 timf = state->timf;
283 } 326 }
284 327
285 timf = timf * (bw / 50) / 160; 328 timf = timf * (bw / 50) / 160;
286 329
287 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff)); 330 dib7000p_write_word(state, 23, (u16) ((timf >> 16) & 0xffff));
288 dib7000p_write_word(state, 24, (u16) ((timf ) & 0xffff)); 331 dib7000p_write_word(state, 24, (u16) ((timf) & 0xffff));
289 332
290 return 0; 333 return 0;
291} 334}
@@ -293,9 +336,12 @@ static int dib7000p_set_bandwidth(struct dib7000p_state *state, u32 bw)
293static int dib7000p_sad_calib(struct dib7000p_state *state) 336static int dib7000p_sad_calib(struct dib7000p_state *state)
294{ 337{
295/* internal */ 338/* internal */
296// dib7000p_write_word(state, 72, (3 << 14) | (1 << 12) | (524 << 0)); // sampling clock of the SAD is writting in set_bandwidth
297 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0)); 339 dib7000p_write_word(state, 73, (0 << 1) | (0 << 0));
298 dib7000p_write_word(state, 74, 776); // 0.625*3.3 / 4096 340
341 if (state->version == SOC7090)
342 dib7000p_write_word(state, 74, 2048);
343 else
344 dib7000p_write_word(state, 74, 776);
299 345
300 /* do the calibration */ 346 /* do the calibration */
301 dib7000p_write_word(state, 73, (1 << 0)); 347 dib7000p_write_word(state, 73, (1 << 0));
@@ -314,37 +360,91 @@ int dib7000p_set_wbd_ref(struct dvb_frontend *demod, u16 value)
314 state->wbd_ref = value; 360 state->wbd_ref = value;
315 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value); 361 return dib7000p_write_word(state, 105, (dib7000p_read_word(state, 105) & 0xf000) | value);
316} 362}
317
318EXPORT_SYMBOL(dib7000p_set_wbd_ref); 363EXPORT_SYMBOL(dib7000p_set_wbd_ref);
364
319static void dib7000p_reset_pll(struct dib7000p_state *state) 365static void dib7000p_reset_pll(struct dib7000p_state *state)
320{ 366{
321 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0]; 367 struct dibx000_bandwidth_config *bw = &state->cfg.bw[0];
322 u16 clk_cfg0; 368 u16 clk_cfg0;
323 369
324 /* force PLL bypass */ 370 if (state->version == SOC7090) {
325 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) | 371 dib7000p_write_word(state, 1856, (!bw->pll_reset << 13) | (bw->pll_range << 12) | (bw->pll_ratio << 6) | (bw->pll_prediv));
326 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | 372
327 (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0); 373 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
374 ;
328 375
329 dib7000p_write_word(state, 900, clk_cfg0); 376 dib7000p_write_word(state, 1857, dib7000p_read_word(state, 1857) | (!bw->pll_bypass << 15));
377 } else {
378 /* force PLL bypass */
379 clk_cfg0 = (1 << 15) | ((bw->pll_ratio & 0x3f) << 9) |
380 (bw->modulo << 7) | (bw->ADClkSrc << 6) | (bw->IO_CLK_en_core << 5) | (bw->bypclk_div << 2) | (bw->enable_refdiv << 1) | (0 << 0);
381
382 dib7000p_write_word(state, 900, clk_cfg0);
330 383
331 /* P_pll_cfg */ 384 /* P_pll_cfg */
332 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset); 385 dib7000p_write_word(state, 903, (bw->pll_prediv << 5) | (((bw->pll_ratio >> 6) & 0x3) << 3) | (bw->pll_range << 1) | bw->pll_reset);
333 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff); 386 clk_cfg0 = (bw->pll_bypass << 15) | (clk_cfg0 & 0x7fff);
334 dib7000p_write_word(state, 900, clk_cfg0); 387 dib7000p_write_word(state, 900, clk_cfg0);
388 }
335 389
336 dib7000p_write_word(state, 18, (u16) (((bw->internal*1000) >> 16) & 0xffff)); 390 dib7000p_write_word(state, 18, (u16) (((bw->internal * 1000) >> 16) & 0xffff));
337 dib7000p_write_word(state, 19, (u16) ( (bw->internal*1000 ) & 0xffff)); 391 dib7000p_write_word(state, 19, (u16) ((bw->internal * 1000) & 0xffff));
338 dib7000p_write_word(state, 21, (u16) ( (bw->ifreq >> 16) & 0xffff)); 392 dib7000p_write_word(state, 21, (u16) ((bw->ifreq >> 16) & 0xffff));
339 dib7000p_write_word(state, 22, (u16) ( (bw->ifreq ) & 0xffff)); 393 dib7000p_write_word(state, 22, (u16) ((bw->ifreq) & 0xffff));
340 394
341 dib7000p_write_word(state, 72, bw->sad_cfg); 395 dib7000p_write_word(state, 72, bw->sad_cfg);
342} 396}
343 397
398static u32 dib7000p_get_internal_freq(struct dib7000p_state *state)
399{
400 u32 internal = (u32) dib7000p_read_word(state, 18) << 16;
401 internal |= (u32) dib7000p_read_word(state, 19);
402 internal /= 1000;
403
404 return internal;
405}
406
407int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
408{
409 struct dib7000p_state *state = fe->demodulator_priv;
410 u16 reg_1857, reg_1856 = dib7000p_read_word(state, 1856);
411 u8 loopdiv, prediv;
412 u32 internal, xtal;
413
414 /* get back old values */
415 prediv = reg_1856 & 0x3f;
416 loopdiv = (reg_1856 >> 6) & 0x3f;
417
418 if ((bw != NULL) && (bw->pll_prediv != prediv || bw->pll_ratio != loopdiv)) {
419 dprintk("Updating pll (prediv: old = %d new = %d ; loopdiv : old = %d new = %d)", prediv, bw->pll_prediv, loopdiv, bw->pll_ratio);
420 reg_1856 &= 0xf000;
421 reg_1857 = dib7000p_read_word(state, 1857);
422 dib7000p_write_word(state, 1857, reg_1857 & ~(1 << 15));
423
424 dib7000p_write_word(state, 1856, reg_1856 | ((bw->pll_ratio & 0x3f) << 6) | (bw->pll_prediv & 0x3f));
425
426 /* write new system clk into P_sec_len */
427 internal = dib7000p_get_internal_freq(state);
428 xtal = (internal / loopdiv) * prediv;
429 internal = 1000 * (xtal / bw->pll_prediv) * bw->pll_ratio; /* new internal */
430 dib7000p_write_word(state, 18, (u16) ((internal >> 16) & 0xffff));
431 dib7000p_write_word(state, 19, (u16) (internal & 0xffff));
432
433 dib7000p_write_word(state, 1857, reg_1857 | (1 << 15));
434
435 while (((dib7000p_read_word(state, 1856) >> 15) & 0x1) != 1)
436 dprintk("Waiting for PLL to lock");
437
438 return 0;
439 }
440 return -EIO;
441}
442EXPORT_SYMBOL(dib7000p_update_pll);
443
344static int dib7000p_reset_gpio(struct dib7000p_state *st) 444static int dib7000p_reset_gpio(struct dib7000p_state *st)
345{ 445{
346 /* reset the GPIOs */ 446 /* reset the GPIOs */
347 dprintk( "gpio dir: %x: val: %x, pwm_pos: %x",st->gpio_dir, st->gpio_val,st->cfg.gpio_pwm_pos); 447 dprintk("gpio dir: %x: val: %x, pwm_pos: %x", st->gpio_dir, st->gpio_val, st->cfg.gpio_pwm_pos);
348 448
349 dib7000p_write_word(st, 1029, st->gpio_dir); 449 dib7000p_write_word(st, 1029, st->gpio_dir);
350 dib7000p_write_word(st, 1030, st->gpio_val); 450 dib7000p_write_word(st, 1030, st->gpio_val);
@@ -360,13 +460,13 @@ static int dib7000p_reset_gpio(struct dib7000p_state *st)
360static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val) 460static int dib7000p_cfg_gpio(struct dib7000p_state *st, u8 num, u8 dir, u8 val)
361{ 461{
362 st->gpio_dir = dib7000p_read_word(st, 1029); 462 st->gpio_dir = dib7000p_read_word(st, 1029);
363 st->gpio_dir &= ~(1 << num); /* reset the direction bit */ 463 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
364 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */ 464 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
365 dib7000p_write_word(st, 1029, st->gpio_dir); 465 dib7000p_write_word(st, 1029, st->gpio_dir);
366 466
367 st->gpio_val = dib7000p_read_word(st, 1030); 467 st->gpio_val = dib7000p_read_word(st, 1030);
368 st->gpio_val &= ~(1 << num); /* reset the direction bit */ 468 st->gpio_val &= ~(1 << num); /* reset the direction bit */
369 st->gpio_val |= (val & 0x01) << num; /* set the new value */ 469 st->gpio_val |= (val & 0x01) << num; /* set the new value */
370 dib7000p_write_word(st, 1030, st->gpio_val); 470 dib7000p_write_word(st, 1030, st->gpio_val);
371 471
372 return 0; 472 return 0;
@@ -377,96 +477,94 @@ int dib7000p_set_gpio(struct dvb_frontend *demod, u8 num, u8 dir, u8 val)
377 struct dib7000p_state *state = demod->demodulator_priv; 477 struct dib7000p_state *state = demod->demodulator_priv;
378 return dib7000p_cfg_gpio(state, num, dir, val); 478 return dib7000p_cfg_gpio(state, num, dir, val);
379} 479}
380
381EXPORT_SYMBOL(dib7000p_set_gpio); 480EXPORT_SYMBOL(dib7000p_set_gpio);
382static u16 dib7000p_defaults[] =
383 481
384{ 482static u16 dib7000p_defaults[] = {
385 // auto search configuration 483 // auto search configuration
386 3, 2, 484 3, 2,
387 0x0004, 485 0x0004,
388 0x1000, 486 0x1000,
389 0x0814, /* Equal Lock */ 487 0x0814, /* Equal Lock */
390 488
391 12, 6, 489 12, 6,
392 0x001b, 490 0x001b,
393 0x7740, 491 0x7740,
394 0x005b, 492 0x005b,
395 0x8d80, 493 0x8d80,
396 0x01c9, 494 0x01c9,
397 0xc380, 495 0xc380,
398 0x0000, 496 0x0000,
399 0x0080, 497 0x0080,
400 0x0000, 498 0x0000,
401 0x0090, 499 0x0090,
402 0x0001, 500 0x0001,
403 0xd4c0, 501 0xd4c0,
404 502
405 1, 26, 503 1, 26,
406 0x6680, // P_timf_alpha=6, P_corm_alpha=6, P_corm_thres=128 default: 6,4,26 504 0x6680,
407 505
408 /* set ADC level to -16 */ 506 /* set ADC level to -16 */
409 11, 79, 507 11, 79,
410 (1 << 13) - 825 - 117, 508 (1 << 13) - 825 - 117,
411 (1 << 13) - 837 - 117, 509 (1 << 13) - 837 - 117,
412 (1 << 13) - 811 - 117, 510 (1 << 13) - 811 - 117,
413 (1 << 13) - 766 - 117, 511 (1 << 13) - 766 - 117,
414 (1 << 13) - 737 - 117, 512 (1 << 13) - 737 - 117,
415 (1 << 13) - 693 - 117, 513 (1 << 13) - 693 - 117,
416 (1 << 13) - 648 - 117, 514 (1 << 13) - 648 - 117,
417 (1 << 13) - 619 - 117, 515 (1 << 13) - 619 - 117,
418 (1 << 13) - 575 - 117, 516 (1 << 13) - 575 - 117,
419 (1 << 13) - 531 - 117, 517 (1 << 13) - 531 - 117,
420 (1 << 13) - 501 - 117, 518 (1 << 13) - 501 - 117,
421 519
422 1, 142, 520 1, 142,
423 0x0410, // P_palf_filter_on=1, P_palf_filter_freeze=0, P_palf_alpha_regul=16 521 0x0410,
424 522
425 /* disable power smoothing */ 523 /* disable power smoothing */
426 8, 145, 524 8, 145,
427 0, 525 0,
428 0, 526 0,
429 0, 527 0,
430 0, 528 0,
431 0, 529 0,
432 0, 530 0,
433 0, 531 0,
434 0, 532 0,
435 533
436 1, 154, 534 1, 154,
437 1 << 13, // P_fft_freq_dir=1, P_fft_nb_to_cut=0 535 1 << 13,
438 536
439 1, 168, 537 1, 168,
440 0x0ccd, // P_pha3_thres, default 0x3000 538 0x0ccd,
441
442// 1, 169,
443// 0x0010, // P_cti_use_cpe=0, P_cti_use_prog=0, P_cti_win_len=16, default: 0x0010
444 539
445 1, 183, 540 1, 183,
446 0x200f, // P_cspu_regul=512, P_cspu_win_cut=15, default: 0x2005 541 0x200f,
542
543 1, 212,
544 0x169,
447 545
448 5, 187, 546 5, 187,
449 0x023d, // P_adp_regul_cnt=573, default: 410 547 0x023d,
450 0x00a4, // P_adp_noise_cnt= 548 0x00a4,
451 0x00a4, // P_adp_regul_ext 549 0x00a4,
452 0x7ff0, // P_adp_noise_ext 550 0x7ff0,
453 0x3ccc, // P_adp_fil 551 0x3ccc,
454 552
455 1, 198, 553 1, 198,
456 0x800, // P_equal_thres_wgn 554 0x800,
457 555
458 1, 222, 556 1, 222,
459 0x0010, // P_fec_ber_rs_len=2 557 0x0010,
460 558
461 1, 235, 559 1, 235,
462 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard 560 0x0062,
463 561
464 2, 901, 562 2, 901,
465 0x0006, // P_clk_cfg1 563 0x0006,
466 (3 << 10) | (1 << 6), // P_divclksel=3 P_divbitsel=1 564 (3 << 10) | (1 << 6),
467 565
468 1, 905, 566 1, 905,
469 0x2c8e, // Tuner IO bank: max drive (14mA) + divout pads max drive 567 0x2c8e,
470 568
471 0, 569 0,
472}; 570};
@@ -475,51 +573,64 @@ static int dib7000p_demod_reset(struct dib7000p_state *state)
475{ 573{
476 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 574 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
477 575
576 if (state->version == SOC7090)
577 dibx000_reset_i2c_master(&state->i2c_master);
578
478 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE); 579 dib7000p_set_adc_state(state, DIBX000_VBG_ENABLE);
479 580
480 /* restart all parts */ 581 /* restart all parts */
481 dib7000p_write_word(state, 770, 0xffff); 582 dib7000p_write_word(state, 770, 0xffff);
482 dib7000p_write_word(state, 771, 0xffff); 583 dib7000p_write_word(state, 771, 0xffff);
483 dib7000p_write_word(state, 772, 0x001f); 584 dib7000p_write_word(state, 772, 0x001f);
484 dib7000p_write_word(state, 898, 0x0003); 585 dib7000p_write_word(state, 898, 0x0003);
485 /* except i2c, sdio, gpio - control interfaces */ 586 dib7000p_write_word(state, 1280, 0x001f - ((1 << 4) | (1 << 3)));
486 dib7000p_write_word(state, 1280, 0x01fc - ((1 << 7) | (1 << 6) | (1 << 5)) ); 587
487 588 dib7000p_write_word(state, 770, 0);
488 dib7000p_write_word(state, 770, 0); 589 dib7000p_write_word(state, 771, 0);
489 dib7000p_write_word(state, 771, 0); 590 dib7000p_write_word(state, 772, 0);
490 dib7000p_write_word(state, 772, 0); 591 dib7000p_write_word(state, 898, 0);
491 dib7000p_write_word(state, 898, 0);
492 dib7000p_write_word(state, 1280, 0); 592 dib7000p_write_word(state, 1280, 0);
493 593
494 /* default */ 594 /* default */
495 dib7000p_reset_pll(state); 595 dib7000p_reset_pll(state);
496 596
497 if (dib7000p_reset_gpio(state) != 0) 597 if (dib7000p_reset_gpio(state) != 0)
498 dprintk( "GPIO reset was not successful."); 598 dprintk("GPIO reset was not successful.");
499
500 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
501 dprintk( "OUTPUT_MODE could not be reset.");
502 599
503 /* unforce divstr regardless whether i2c enumeration was done or not */ 600 if (state->version == SOC7090) {
504 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1) ); 601 dib7000p_write_word(state, 899, 0);
505 602
506 dib7000p_set_bandwidth(state, 8000); 603 /* impulse noise */
604 dib7000p_write_word(state, 42, (1<<5) | 3); /* P_iqc_thsat_ipc = 1 ; P_iqc_win2 = 3 */
605 dib7000p_write_word(state, 43, 0x2d4); /*-300 fag P_iqc_dect_min = -280 */
606 dib7000p_write_word(state, 44, 300); /* 300 fag P_iqc_dect_min = +280 */
607 dib7000p_write_word(state, 273, (1<<6) | 30);
608 }
609 if (dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) != 0)
610 dprintk("OUTPUT_MODE could not be reset.");
507 611
508 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 612 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
509 dib7000p_sad_calib(state); 613 dib7000p_sad_calib(state);
510 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF); 614 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_OFF);
511 615
512 // P_iqc_alpha_pha, P_iqc_alpha_amp_dcc_alpha, ... 616 /* unforce divstr regardless whether i2c enumeration was done or not */
513 if(state->cfg.tuner_is_baseband) 617 dib7000p_write_word(state, 1285, dib7000p_read_word(state, 1285) & ~(1 << 1));
514 dib7000p_write_word(state, 36,0x0755); 618
515 else 619 dib7000p_set_bandwidth(state, 8000);
516 dib7000p_write_word(state, 36,0x1f55); 620
621 if (state->version == SOC7090) {
622 dib7000p_write_word(state, 36, 0x5755);/* P_iqc_impnc_on =1 & P_iqc_corr_inh = 1 for impulsive noise */
623 } else {
624 if (state->cfg.tuner_is_baseband)
625 dib7000p_write_word(state, 36, 0x0755);
626 else
627 dib7000p_write_word(state, 36, 0x1f55);
628 }
517 629
518 dib7000p_write_tab(state, dib7000p_defaults); 630 dib7000p_write_tab(state, dib7000p_defaults);
519 631
520 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 632 dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
521 633
522
523 return 0; 634 return 0;
524} 635}
525 636
@@ -527,9 +638,9 @@ static void dib7000p_pll_clk_cfg(struct dib7000p_state *state)
527{ 638{
528 u16 tmp = 0; 639 u16 tmp = 0;
529 tmp = dib7000p_read_word(state, 903); 640 tmp = dib7000p_read_word(state, 903);
530 dib7000p_write_word(state, 903, (tmp | 0x1)); //pwr-up pll 641 dib7000p_write_word(state, 903, (tmp | 0x1));
531 tmp = dib7000p_read_word(state, 900); 642 tmp = dib7000p_read_word(state, 900);
532 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6)); //use High freq clock 643 dib7000p_write_word(state, 900, (tmp & 0x7fff) | (1 << 6));
533} 644}
534 645
535static void dib7000p_restart_agc(struct dib7000p_state *state) 646static void dib7000p_restart_agc(struct dib7000p_state *state)
@@ -543,11 +654,9 @@ static int dib7000p_update_lna(struct dib7000p_state *state)
543{ 654{
544 u16 dyn_gain; 655 u16 dyn_gain;
545 656
546 // when there is no LNA to program return immediatly
547 if (state->cfg.update_lna) { 657 if (state->cfg.update_lna) {
548 // read dyn_gain here (because it is demod-dependent and not fe)
549 dyn_gain = dib7000p_read_word(state, 394); 658 dyn_gain = dib7000p_read_word(state, 394);
550 if (state->cfg.update_lna(&state->demod,dyn_gain)) { // LNA has changed 659 if (state->cfg.update_lna(&state->demod, dyn_gain)) {
551 dib7000p_restart_agc(state); 660 dib7000p_restart_agc(state);
552 return 1; 661 return 1;
553 } 662 }
@@ -571,24 +680,24 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
571 } 680 }
572 681
573 if (agc == NULL) { 682 if (agc == NULL) {
574 dprintk( "no valid AGC configuration found for band 0x%02x",band); 683 dprintk("no valid AGC configuration found for band 0x%02x", band);
575 return -EINVAL; 684 return -EINVAL;
576 } 685 }
577 686
578 state->current_agc = agc; 687 state->current_agc = agc;
579 688
580 /* AGC */ 689 /* AGC */
581 dib7000p_write_word(state, 75 , agc->setup ); 690 dib7000p_write_word(state, 75, agc->setup);
582 dib7000p_write_word(state, 76 , agc->inv_gain ); 691 dib7000p_write_word(state, 76, agc->inv_gain);
583 dib7000p_write_word(state, 77 , agc->time_stabiliz ); 692 dib7000p_write_word(state, 77, agc->time_stabiliz);
584 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock); 693 dib7000p_write_word(state, 100, (agc->alpha_level << 12) | agc->thlock);
585 694
586 // Demod AGC loop configuration 695 // Demod AGC loop configuration
587 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp); 696 dib7000p_write_word(state, 101, (agc->alpha_mant << 5) | agc->alpha_exp);
588 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp); 697 dib7000p_write_word(state, 102, (agc->beta_mant << 6) | agc->beta_exp);
589 698
590 /* AGC continued */ 699 /* AGC continued */
591 dprintk( "WBD: ref: %d, sel: %d, active: %d, alpha: %d", 700 dprintk("WBD: ref: %d, sel: %d, active: %d, alpha: %d",
592 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel); 701 state->wbd_ref != 0 ? state->wbd_ref : agc->wbd_ref, agc->wbd_sel, !agc->perform_agc_softsplit, agc->wbd_sel);
593 702
594 if (state->wbd_ref != 0) 703 if (state->wbd_ref != 0)
@@ -598,101 +707,135 @@ static int dib7000p_set_agc_config(struct dib7000p_state *state, u8 band)
598 707
599 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8)); 708 dib7000p_write_word(state, 106, (agc->wbd_sel << 13) | (agc->wbd_alpha << 9) | (agc->perform_agc_softsplit << 8));
600 709
601 dib7000p_write_word(state, 107, agc->agc1_max); 710 dib7000p_write_word(state, 107, agc->agc1_max);
602 dib7000p_write_word(state, 108, agc->agc1_min); 711 dib7000p_write_word(state, 108, agc->agc1_min);
603 dib7000p_write_word(state, 109, agc->agc2_max); 712 dib7000p_write_word(state, 109, agc->agc2_max);
604 dib7000p_write_word(state, 110, agc->agc2_min); 713 dib7000p_write_word(state, 110, agc->agc2_min);
605 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2); 714 dib7000p_write_word(state, 111, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
606 dib7000p_write_word(state, 112, agc->agc1_pt3); 715 dib7000p_write_word(state, 112, agc->agc1_pt3);
607 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2); 716 dib7000p_write_word(state, 113, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
608 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2); 717 dib7000p_write_word(state, 114, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
609 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2); 718 dib7000p_write_word(state, 115, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
610 return 0; 719 return 0;
611} 720}
612 721
722static void dib7000p_set_dds(struct dib7000p_state *state, s32 offset_khz)
723{
724 u32 internal = dib7000p_get_internal_freq(state);
725 s32 unit_khz_dds_val = 67108864 / (internal); /* 2**26 / Fsampling is the unit 1KHz offset */
726 u32 abs_offset_khz = ABS(offset_khz);
727 u32 dds = state->cfg.bw->ifreq & 0x1ffffff;
728 u8 invert = !!(state->cfg.bw->ifreq & (1 << 25));
729
730 dprintk("setting a frequency offset of %dkHz internal freq = %d invert = %d", offset_khz, internal, invert);
731
732 if (offset_khz < 0)
733 unit_khz_dds_val *= -1;
734
735 /* IF tuner */
736 if (invert)
737 dds -= (abs_offset_khz * unit_khz_dds_val); /* /100 because of /100 on the unit_khz_dds_val line calc for better accuracy */
738 else
739 dds += (abs_offset_khz * unit_khz_dds_val);
740
741 if (abs_offset_khz <= (internal / 2)) { /* Max dds offset is the half of the demod freq */
742 dib7000p_write_word(state, 21, (u16) (((dds >> 16) & 0x1ff) | (0 << 10) | (invert << 9)));
743 dib7000p_write_word(state, 22, (u16) (dds & 0xffff));
744 }
745}
746
613static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 747static int dib7000p_agc_startup(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
614{ 748{
615 struct dib7000p_state *state = demod->demodulator_priv; 749 struct dib7000p_state *state = demod->demodulator_priv;
616 int ret = -1; 750 int ret = -1;
617 u8 *agc_state = &state->agc_state; 751 u8 *agc_state = &state->agc_state;
618 u8 agc_split; 752 u8 agc_split;
753 u16 reg;
754 u32 upd_demod_gain_period = 0x1000;
619 755
620 switch (state->agc_state) { 756 switch (state->agc_state) {
621 case 0: 757 case 0:
622 // set power-up level: interf+analog+AGC 758 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
623 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 759 if (state->version == SOC7090) {
760 reg = dib7000p_read_word(state, 0x79b) & 0xff00;
761 dib7000p_write_word(state, 0x79a, upd_demod_gain_period & 0xFFFF); /* lsb */
762 dib7000p_write_word(state, 0x79b, reg | (1 << 14) | ((upd_demod_gain_period >> 16) & 0xFF));
763
764 /* enable adc i & q */
765 reg = dib7000p_read_word(state, 0x780);
766 dib7000p_write_word(state, 0x780, (reg | (0x3)) & (~(1 << 7)));
767 } else {
624 dib7000p_set_adc_state(state, DIBX000_ADC_ON); 768 dib7000p_set_adc_state(state, DIBX000_ADC_ON);
625 dib7000p_pll_clk_cfg(state); 769 dib7000p_pll_clk_cfg(state);
770 }
626 771
627 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency/1000)) != 0) 772 if (dib7000p_set_agc_config(state, BAND_OF_FREQUENCY(ch->frequency / 1000)) != 0)
628 return -1; 773 return -1;
629
630 ret = 7;
631 (*agc_state)++;
632 break;
633 774
634 case 1: 775 dib7000p_set_dds(state, 0);
635 // AGC initialization 776 ret = 7;
636 if (state->cfg.agc_control) 777 (*agc_state)++;
637 state->cfg.agc_control(&state->demod, 1); 778 break;
638
639 dib7000p_write_word(state, 78, 32768);
640 if (!state->current_agc->perform_agc_softsplit) {
641 /* we are using the wbd - so slow AGC startup */
642 /* force 0 split on WBD and restart AGC */
643 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
644 (*agc_state)++;
645 ret = 5;
646 } else {
647 /* default AGC startup */
648 (*agc_state) = 4;
649 /* wait AGC rough lock time */
650 ret = 7;
651 }
652 779
653 dib7000p_restart_agc(state); 780 case 1:
654 break; 781 if (state->cfg.agc_control)
782 state->cfg.agc_control(&state->demod, 1);
655 783
656 case 2: /* fast split search path after 5sec */ 784 dib7000p_write_word(state, 78, 32768);
657 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */ 785 if (!state->current_agc->perform_agc_softsplit) {
658 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */ 786 /* we are using the wbd - so slow AGC startup */
787 /* force 0 split on WBD and restart AGC */
788 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | (1 << 8));
659 (*agc_state)++; 789 (*agc_state)++;
660 ret = 14; 790 ret = 5;
661 break; 791 } else {
792 /* default AGC startup */
793 (*agc_state) = 4;
794 /* wait AGC rough lock time */
795 ret = 7;
796 }
662 797
663 case 3: /* split search ended */ 798 dib7000p_restart_agc(state);
664 agc_split = (u8)dib7000p_read_word(state, 396); /* store the split value for the next time */ 799 break;
665 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
666 800
667 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */ 801 case 2: /* fast split search path after 5sec */
668 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */ 802 dib7000p_write_word(state, 75, state->current_agc->setup | (1 << 4)); /* freeze AGC loop */
803 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (2 << 9) | (0 << 8)); /* fast split search 0.25kHz */
804 (*agc_state)++;
805 ret = 14;
806 break;
669 807
670 dib7000p_restart_agc(state); 808 case 3: /* split search ended */
809 agc_split = (u8) dib7000p_read_word(state, 396); /* store the split value for the next time */
810 dib7000p_write_word(state, 78, dib7000p_read_word(state, 394)); /* set AGC gain start value */
671 811
672 dprintk( "SPLIT %p: %hd", demod, agc_split); 812 dib7000p_write_word(state, 75, state->current_agc->setup); /* std AGC loop */
813 dib7000p_write_word(state, 106, (state->current_agc->wbd_sel << 13) | (state->current_agc->wbd_alpha << 9) | agc_split); /* standard split search */
673 814
674 (*agc_state)++; 815 dib7000p_restart_agc(state);
675 ret = 5;
676 break;
677 816
678 case 4: /* LNA startup */ 817 dprintk("SPLIT %p: %hd", demod, agc_split);
679 // wait AGC accurate lock time
680 ret = 7;
681 818
682 if (dib7000p_update_lna(state)) 819 (*agc_state)++;
683 // wait only AGC rough lock time 820 ret = 5;
684 ret = 5; 821 break;
685 else // nothing was done, go to the next state
686 (*agc_state)++;
687 break;
688 822
689 case 5: 823 case 4: /* LNA startup */
690 if (state->cfg.agc_control) 824 ret = 7;
691 state->cfg.agc_control(&state->demod, 0); 825
826 if (dib7000p_update_lna(state))
827 ret = 5;
828 else
692 (*agc_state)++; 829 (*agc_state)++;
693 break; 830 break;
694 default: 831
695 break; 832 case 5:
833 if (state->cfg.agc_control)
834 state->cfg.agc_control(&state->demod, 0);
835 (*agc_state)++;
836 break;
837 default:
838 break;
696 } 839 }
697 return ret; 840 return ret;
698} 841}
@@ -703,45 +846,89 @@ static void dib7000p_update_timf(struct dib7000p_state *state)
703 state->timf = timf * 160 / (state->current_bandwidth / 50); 846 state->timf = timf * 160 / (state->current_bandwidth / 50);
704 dib7000p_write_word(state, 23, (u16) (timf >> 16)); 847 dib7000p_write_word(state, 23, (u16) (timf >> 16));
705 dib7000p_write_word(state, 24, (u16) (timf & 0xffff)); 848 dib7000p_write_word(state, 24, (u16) (timf & 0xffff));
706 dprintk( "updated timf_frequency: %d (default: %d)",state->timf, state->cfg.bw->timf); 849 dprintk("updated timf_frequency: %d (default: %d)", state->timf, state->cfg.bw->timf);
850
851}
707 852
853u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
854{
855 struct dib7000p_state *state = fe->demodulator_priv;
856 switch (op) {
857 case DEMOD_TIMF_SET:
858 state->timf = timf;
859 break;
860 case DEMOD_TIMF_UPDATE:
861 dib7000p_update_timf(state);
862 break;
863 case DEMOD_TIMF_GET:
864 break;
865 }
866 dib7000p_set_bandwidth(state, state->current_bandwidth);
867 return state->timf;
708} 868}
869EXPORT_SYMBOL(dib7000p_ctrl_timf);
709 870
710static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq) 871static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_frontend_parameters *ch, u8 seq)
711{ 872{
712 u16 value, est[4]; 873 u16 value, est[4];
713 874
714 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 875 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
715 876
716 /* nfft, guard, qam, alpha */ 877 /* nfft, guard, qam, alpha */
717 value = 0; 878 value = 0;
718 switch (ch->u.ofdm.transmission_mode) { 879 switch (ch->u.ofdm.transmission_mode) {
719 case TRANSMISSION_MODE_2K: value |= (0 << 7); break; 880 case TRANSMISSION_MODE_2K:
720 case TRANSMISSION_MODE_4K: value |= (2 << 7); break; 881 value |= (0 << 7);
721 default: 882 break;
722 case TRANSMISSION_MODE_8K: value |= (1 << 7); break; 883 case TRANSMISSION_MODE_4K:
884 value |= (2 << 7);
885 break;
886 default:
887 case TRANSMISSION_MODE_8K:
888 value |= (1 << 7);
889 break;
723 } 890 }
724 switch (ch->u.ofdm.guard_interval) { 891 switch (ch->u.ofdm.guard_interval) {
725 case GUARD_INTERVAL_1_32: value |= (0 << 5); break; 892 case GUARD_INTERVAL_1_32:
726 case GUARD_INTERVAL_1_16: value |= (1 << 5); break; 893 value |= (0 << 5);
727 case GUARD_INTERVAL_1_4: value |= (3 << 5); break; 894 break;
728 default: 895 case GUARD_INTERVAL_1_16:
729 case GUARD_INTERVAL_1_8: value |= (2 << 5); break; 896 value |= (1 << 5);
897 break;
898 case GUARD_INTERVAL_1_4:
899 value |= (3 << 5);
900 break;
901 default:
902 case GUARD_INTERVAL_1_8:
903 value |= (2 << 5);
904 break;
730 } 905 }
731 switch (ch->u.ofdm.constellation) { 906 switch (ch->u.ofdm.constellation) {
732 case QPSK: value |= (0 << 3); break; 907 case QPSK:
733 case QAM_16: value |= (1 << 3); break; 908 value |= (0 << 3);
734 default: 909 break;
735 case QAM_64: value |= (2 << 3); break; 910 case QAM_16:
911 value |= (1 << 3);
912 break;
913 default:
914 case QAM_64:
915 value |= (2 << 3);
916 break;
736 } 917 }
737 switch (HIERARCHY_1) { 918 switch (HIERARCHY_1) {
738 case HIERARCHY_2: value |= 2; break; 919 case HIERARCHY_2:
739 case HIERARCHY_4: value |= 4; break; 920 value |= 2;
740 default: 921 break;
741 case HIERARCHY_1: value |= 1; break; 922 case HIERARCHY_4:
923 value |= 4;
924 break;
925 default:
926 case HIERARCHY_1:
927 value |= 1;
928 break;
742 } 929 }
743 dib7000p_write_word(state, 0, value); 930 dib7000p_write_word(state, 0, value);
744 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */ 931 dib7000p_write_word(state, 5, (seq << 4) | 1); /* do not force tps, search list 0 */
745 932
746 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */ 933 /* P_dintl_native, P_dintlv_inv, P_hrch, P_code_rate, P_select_hp */
747 value = 0; 934 value = 0;
@@ -752,39 +939,63 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
752 if (1 == 1) 939 if (1 == 1)
753 value |= 1; 940 value |= 1;
754 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) { 941 switch ((ch->u.ofdm.hierarchy_information == 0 || 1 == 1) ? ch->u.ofdm.code_rate_HP : ch->u.ofdm.code_rate_LP) {
755 case FEC_2_3: value |= (2 << 1); break; 942 case FEC_2_3:
756 case FEC_3_4: value |= (3 << 1); break; 943 value |= (2 << 1);
757 case FEC_5_6: value |= (5 << 1); break; 944 break;
758 case FEC_7_8: value |= (7 << 1); break; 945 case FEC_3_4:
759 default: 946 value |= (3 << 1);
760 case FEC_1_2: value |= (1 << 1); break; 947 break;
948 case FEC_5_6:
949 value |= (5 << 1);
950 break;
951 case FEC_7_8:
952 value |= (7 << 1);
953 break;
954 default:
955 case FEC_1_2:
956 value |= (1 << 1);
957 break;
761 } 958 }
762 dib7000p_write_word(state, 208, value); 959 dib7000p_write_word(state, 208, value);
763 960
764 /* offset loop parameters */ 961 /* offset loop parameters */
765 dib7000p_write_word(state, 26, 0x6680); // timf(6xxx) 962 dib7000p_write_word(state, 26, 0x6680);
766 dib7000p_write_word(state, 32, 0x0003); // pha_off_max(xxx3) 963 dib7000p_write_word(state, 32, 0x0003);
767 dib7000p_write_word(state, 29, 0x1273); // isi 964 dib7000p_write_word(state, 29, 0x1273);
768 dib7000p_write_word(state, 33, 0x0005); // sfreq(xxx5) 965 dib7000p_write_word(state, 33, 0x0005);
769 966
770 /* P_dvsy_sync_wait */ 967 /* P_dvsy_sync_wait */
771 switch (ch->u.ofdm.transmission_mode) { 968 switch (ch->u.ofdm.transmission_mode) {
772 case TRANSMISSION_MODE_8K: value = 256; break; 969 case TRANSMISSION_MODE_8K:
773 case TRANSMISSION_MODE_4K: value = 128; break; 970 value = 256;
774 case TRANSMISSION_MODE_2K: 971 break;
775 default: value = 64; break; 972 case TRANSMISSION_MODE_4K:
973 value = 128;
974 break;
975 case TRANSMISSION_MODE_2K:
976 default:
977 value = 64;
978 break;
776 } 979 }
777 switch (ch->u.ofdm.guard_interval) { 980 switch (ch->u.ofdm.guard_interval) {
778 case GUARD_INTERVAL_1_16: value *= 2; break; 981 case GUARD_INTERVAL_1_16:
779 case GUARD_INTERVAL_1_8: value *= 4; break; 982 value *= 2;
780 case GUARD_INTERVAL_1_4: value *= 8; break; 983 break;
781 default: 984 case GUARD_INTERVAL_1_8:
782 case GUARD_INTERVAL_1_32: value *= 1; break; 985 value *= 4;
986 break;
987 case GUARD_INTERVAL_1_4:
988 value *= 8;
989 break;
990 default:
991 case GUARD_INTERVAL_1_32:
992 value *= 1;
993 break;
783 } 994 }
784 if (state->cfg.diversity_delay == 0) 995 if (state->cfg.diversity_delay == 0)
785 state->div_sync_wait = (value * 3) / 2 + 48; // add 50% SFN margin + compensate for one DVSY-fifo 996 state->div_sync_wait = (value * 3) / 2 + 48;
786 else 997 else
787 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay; // add 50% SFN margin + compensate for one DVSY-fifo 998 state->div_sync_wait = (value * 3) / 2 + state->cfg.diversity_delay;
788 999
789 /* deactive the possibility of diversity reception if extended interleaver */ 1000 /* deactive the possibility of diversity reception if extended interleaver */
790 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K; 1001 state->div_force_off = !1 && ch->u.ofdm.transmission_mode != TRANSMISSION_MODE_8K;
@@ -792,24 +1003,24 @@ static void dib7000p_set_channel(struct dib7000p_state *state, struct dvb_fronte
792 1003
793 /* channel estimation fine configuration */ 1004 /* channel estimation fine configuration */
794 switch (ch->u.ofdm.constellation) { 1005 switch (ch->u.ofdm.constellation) {
795 case QAM_64: 1006 case QAM_64:
796 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */ 1007 est[0] = 0x0148; /* P_adp_regul_cnt 0.04 */
797 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */ 1008 est[1] = 0xfff0; /* P_adp_noise_cnt -0.002 */
798 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 1009 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
799 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */ 1010 est[3] = 0xfff8; /* P_adp_noise_ext -0.001 */
800 break; 1011 break;
801 case QAM_16: 1012 case QAM_16:
802 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */ 1013 est[0] = 0x023d; /* P_adp_regul_cnt 0.07 */
803 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */ 1014 est[1] = 0xffdf; /* P_adp_noise_cnt -0.004 */
804 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */ 1015 est[2] = 0x00a4; /* P_adp_regul_ext 0.02 */
805 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */ 1016 est[3] = 0xfff0; /* P_adp_noise_ext -0.002 */
806 break; 1017 break;
807 default: 1018 default:
808 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */ 1019 est[0] = 0x099a; /* P_adp_regul_cnt 0.3 */
809 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */ 1020 est[1] = 0xffae; /* P_adp_noise_cnt -0.01 */
810 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */ 1021 est[2] = 0x0333; /* P_adp_regul_ext 0.1 */
811 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */ 1022 est[3] = 0xfff8; /* P_adp_noise_ext -0.002 */
812 break; 1023 break;
813 } 1024 }
814 for (value = 0; value < 4; value++) 1025 for (value = 0; value < 4; value++)
815 dib7000p_write_word(state, 187 + value, est[value]); 1026 dib7000p_write_word(state, 187 + value, est[value]);
@@ -820,14 +1031,15 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron
820 struct dib7000p_state *state = demod->demodulator_priv; 1031 struct dib7000p_state *state = demod->demodulator_priv;
821 struct dvb_frontend_parameters schan; 1032 struct dvb_frontend_parameters schan;
822 u32 value, factor; 1033 u32 value, factor;
1034 u32 internal = dib7000p_get_internal_freq(state);
823 1035
824 schan = *ch; 1036 schan = *ch;
825 schan.u.ofdm.constellation = QAM_64; 1037 schan.u.ofdm.constellation = QAM_64;
826 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32; 1038 schan.u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
827 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; 1039 schan.u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
828 schan.u.ofdm.code_rate_HP = FEC_2_3; 1040 schan.u.ofdm.code_rate_HP = FEC_2_3;
829 schan.u.ofdm.code_rate_LP = FEC_3_4; 1041 schan.u.ofdm.code_rate_LP = FEC_3_4;
830 schan.u.ofdm.hierarchy_information = 0; 1042 schan.u.ofdm.hierarchy_information = 0;
831 1043
832 dib7000p_set_channel(state, &schan, 7); 1044 dib7000p_set_channel(state, &schan, 7);
833 1045
@@ -837,16 +1049,15 @@ static int dib7000p_autosearch_start(struct dvb_frontend *demod, struct dvb_fron
837 else 1049 else
838 factor = 6; 1050 factor = 6;
839 1051
840 // always use the setting for 8MHz here lock_time for 7,6 MHz are longer 1052 value = 30 * internal * factor;
841 value = 30 * state->cfg.bw->internal * factor; 1053 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff));
842 dib7000p_write_word(state, 6, (u16) ((value >> 16) & 0xffff)); // lock0 wait time 1054 dib7000p_write_word(state, 7, (u16) (value & 0xffff));
843 dib7000p_write_word(state, 7, (u16) (value & 0xffff)); // lock0 wait time 1055 value = 100 * internal * factor;
844 value = 100 * state->cfg.bw->internal * factor; 1056 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff));
845 dib7000p_write_word(state, 8, (u16) ((value >> 16) & 0xffff)); // lock1 wait time 1057 dib7000p_write_word(state, 9, (u16) (value & 0xffff));
846 dib7000p_write_word(state, 9, (u16) (value & 0xffff)); // lock1 wait time 1058 value = 500 * internal * factor;
847 value = 500 * state->cfg.bw->internal * factor; 1059 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff));
848 dib7000p_write_word(state, 10, (u16) ((value >> 16) & 0xffff)); // lock2 wait time 1060 dib7000p_write_word(state, 11, (u16) (value & 0xffff));
849 dib7000p_write_word(state, 11, (u16) (value & 0xffff)); // lock2 wait time
850 1061
851 value = dib7000p_read_word(state, 0); 1062 value = dib7000p_read_word(state, 0);
852 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value)); 1063 dib7000p_write_word(state, 0, (u16) ((1 << 9) | value));
@@ -861,101 +1072,101 @@ static int dib7000p_autosearch_is_irq(struct dvb_frontend *demod)
861 struct dib7000p_state *state = demod->demodulator_priv; 1072 struct dib7000p_state *state = demod->demodulator_priv;
862 u16 irq_pending = dib7000p_read_word(state, 1284); 1073 u16 irq_pending = dib7000p_read_word(state, 1284);
863 1074
864 if (irq_pending & 0x1) // failed 1075 if (irq_pending & 0x1)
865 return 1; 1076 return 1;
866 1077
867 if (irq_pending & 0x2) // succeeded 1078 if (irq_pending & 0x2)
868 return 2; 1079 return 2;
869 1080
870 return 0; // still pending 1081 return 0;
871} 1082}
872 1083
873static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw) 1084static void dib7000p_spur_protect(struct dib7000p_state *state, u32 rf_khz, u32 bw)
874{ 1085{
875 static s16 notch[]={16143, 14402, 12238, 9713, 6902, 3888, 759, -2392}; 1086 static s16 notch[] = { 16143, 14402, 12238, 9713, 6902, 3888, 759, -2392 };
876 static u8 sine [] ={0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22, 1087 static u8 sine[] = { 0, 2, 3, 5, 6, 8, 9, 11, 13, 14, 16, 17, 19, 20, 22,
877 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51, 1088 24, 25, 27, 28, 30, 31, 33, 34, 36, 38, 39, 41, 42, 44, 45, 47, 48, 50, 51,
878 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80, 1089 53, 55, 56, 58, 59, 61, 62, 64, 65, 67, 68, 70, 71, 73, 74, 76, 77, 79, 80,
879 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105, 1090 82, 83, 85, 86, 88, 89, 91, 92, 94, 95, 97, 98, 99, 101, 102, 104, 105,
880 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126, 1091 107, 108, 109, 111, 112, 114, 115, 117, 118, 119, 121, 122, 123, 125, 126,
881 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146, 1092 128, 129, 130, 132, 133, 134, 136, 137, 138, 140, 141, 142, 144, 145, 146,
882 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165, 1093 147, 149, 150, 151, 152, 154, 155, 156, 157, 159, 160, 161, 162, 164, 165,
883 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182, 1094 166, 167, 168, 170, 171, 172, 173, 174, 175, 177, 178, 179, 180, 181, 182,
884 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 1095 183, 184, 185, 186, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198,
885 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212, 1096 199, 200, 201, 202, 203, 204, 205, 206, 207, 207, 208, 209, 210, 211, 212,
886 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224, 1097 213, 214, 215, 215, 216, 217, 218, 219, 220, 220, 221, 222, 223, 224, 224,
887 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235, 1098 225, 226, 227, 227, 228, 229, 229, 230, 231, 231, 232, 233, 233, 234, 235,
888 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243, 1099 235, 236, 237, 237, 238, 238, 239, 239, 240, 241, 241, 242, 242, 243, 243,
889 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249, 1100 244, 244, 245, 245, 245, 246, 246, 247, 247, 248, 248, 248, 249, 249, 249,
890 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254, 1101 250, 250, 250, 251, 251, 251, 252, 252, 252, 252, 253, 253, 253, 253, 254,
891 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1102 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
892 255, 255, 255, 255, 255, 255}; 1103 255, 255, 255, 255, 255, 255
1104 };
893 1105
894 u32 xtal = state->cfg.bw->xtal_hz / 1000; 1106 u32 xtal = state->cfg.bw->xtal_hz / 1000;
895 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz; 1107 int f_rel = DIV_ROUND_CLOSEST(rf_khz, xtal) * xtal - rf_khz;
896 int k; 1108 int k;
897 int coef_re[8],coef_im[8]; 1109 int coef_re[8], coef_im[8];
898 int bw_khz = bw; 1110 int bw_khz = bw;
899 u32 pha; 1111 u32 pha;
900 1112
901 dprintk( "relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal); 1113 dprintk("relative position of the Spur: %dk (RF: %dk, XTAL: %dk)", f_rel, rf_khz, xtal);
902
903 1114
904 if (f_rel < -bw_khz/2 || f_rel > bw_khz/2) 1115 if (f_rel < -bw_khz / 2 || f_rel > bw_khz / 2)
905 return; 1116 return;
906 1117
907 bw_khz /= 100; 1118 bw_khz /= 100;
908 1119
909 dib7000p_write_word(state, 142 ,0x0610); 1120 dib7000p_write_word(state, 142, 0x0610);
910 1121
911 for (k = 0; k < 8; k++) { 1122 for (k = 0; k < 8; k++) {
912 pha = ((f_rel * (k+1) * 112 * 80/bw_khz) /1000) & 0x3ff; 1123 pha = ((f_rel * (k + 1) * 112 * 80 / bw_khz) / 1000) & 0x3ff;
913 1124
914 if (pha==0) { 1125 if (pha == 0) {
915 coef_re[k] = 256; 1126 coef_re[k] = 256;
916 coef_im[k] = 0; 1127 coef_im[k] = 0;
917 } else if(pha < 256) { 1128 } else if (pha < 256) {
918 coef_re[k] = sine[256-(pha&0xff)]; 1129 coef_re[k] = sine[256 - (pha & 0xff)];
919 coef_im[k] = sine[pha&0xff]; 1130 coef_im[k] = sine[pha & 0xff];
920 } else if (pha == 256) { 1131 } else if (pha == 256) {
921 coef_re[k] = 0; 1132 coef_re[k] = 0;
922 coef_im[k] = 256; 1133 coef_im[k] = 256;
923 } else if (pha < 512) { 1134 } else if (pha < 512) {
924 coef_re[k] = -sine[pha&0xff]; 1135 coef_re[k] = -sine[pha & 0xff];
925 coef_im[k] = sine[256 - (pha&0xff)]; 1136 coef_im[k] = sine[256 - (pha & 0xff)];
926 } else if (pha == 512) { 1137 } else if (pha == 512) {
927 coef_re[k] = -256; 1138 coef_re[k] = -256;
928 coef_im[k] = 0; 1139 coef_im[k] = 0;
929 } else if (pha < 768) { 1140 } else if (pha < 768) {
930 coef_re[k] = -sine[256-(pha&0xff)]; 1141 coef_re[k] = -sine[256 - (pha & 0xff)];
931 coef_im[k] = -sine[pha&0xff]; 1142 coef_im[k] = -sine[pha & 0xff];
932 } else if (pha == 768) { 1143 } else if (pha == 768) {
933 coef_re[k] = 0; 1144 coef_re[k] = 0;
934 coef_im[k] = -256; 1145 coef_im[k] = -256;
935 } else { 1146 } else {
936 coef_re[k] = sine[pha&0xff]; 1147 coef_re[k] = sine[pha & 0xff];
937 coef_im[k] = -sine[256 - (pha&0xff)]; 1148 coef_im[k] = -sine[256 - (pha & 0xff)];
938 } 1149 }
939 1150
940 coef_re[k] *= notch[k]; 1151 coef_re[k] *= notch[k];
941 coef_re[k] += (1<<14); 1152 coef_re[k] += (1 << 14);
942 if (coef_re[k] >= (1<<24)) 1153 if (coef_re[k] >= (1 << 24))
943 coef_re[k] = (1<<24) - 1; 1154 coef_re[k] = (1 << 24) - 1;
944 coef_re[k] /= (1<<15); 1155 coef_re[k] /= (1 << 15);
945 1156
946 coef_im[k] *= notch[k]; 1157 coef_im[k] *= notch[k];
947 coef_im[k] += (1<<14); 1158 coef_im[k] += (1 << 14);
948 if (coef_im[k] >= (1<<24)) 1159 if (coef_im[k] >= (1 << 24))
949 coef_im[k] = (1<<24)-1; 1160 coef_im[k] = (1 << 24) - 1;
950 coef_im[k] /= (1<<15); 1161 coef_im[k] /= (1 << 15);
951 1162
952 dprintk( "PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]); 1163 dprintk("PALF COEF: %d re: %d im: %d", k, coef_re[k], coef_im[k]);
953 1164
954 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); 1165 dib7000p_write_word(state, 143, (0 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
955 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff); 1166 dib7000p_write_word(state, 144, coef_im[k] & 0x3ff);
956 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff)); 1167 dib7000p_write_word(state, 143, (1 << 14) | (k << 10) | (coef_re[k] & 0x3ff));
957 } 1168 }
958 dib7000p_write_word(state,143 ,0); 1169 dib7000p_write_word(state, 143, 0);
959} 1170}
960 1171
961static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch) 1172static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_parameters *ch)
@@ -976,11 +1187,11 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
976 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */ 1187 /* P_ctrl_inh_cor=0, P_ctrl_alpha_cor=4, P_ctrl_inh_isi=0, P_ctrl_alpha_isi=3, P_ctrl_inh_cor4=1, P_ctrl_alpha_cor4=3 */
977 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3); 1188 tmp = (0 << 14) | (4 << 10) | (0 << 9) | (3 << 5) | (1 << 4) | (0x3);
978 if (state->sfn_workaround_active) { 1189 if (state->sfn_workaround_active) {
979 dprintk( "SFN workaround is active"); 1190 dprintk("SFN workaround is active");
980 tmp |= (1 << 9); 1191 tmp |= (1 << 9);
981 dib7000p_write_word(state, 166, 0x4000); // P_pha3_force_pha_shift 1192 dib7000p_write_word(state, 166, 0x4000);
982 } else { 1193 } else {
983 dib7000p_write_word(state, 166, 0x0000); // P_pha3_force_pha_shift 1194 dib7000p_write_word(state, 166, 0x0000);
984 } 1195 }
985 dib7000p_write_word(state, 29, tmp); 1196 dib7000p_write_word(state, 29, tmp);
986 1197
@@ -993,51 +1204,72 @@ static int dib7000p_tune(struct dvb_frontend *demod, struct dvb_frontend_paramet
993 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */ 1204 /* P_timf_alpha, P_corm_alpha=6, P_corm_thres=0x80 */
994 tmp = (6 << 8) | 0x80; 1205 tmp = (6 << 8) | 0x80;
995 switch (ch->u.ofdm.transmission_mode) { 1206 switch (ch->u.ofdm.transmission_mode) {
996 case TRANSMISSION_MODE_2K: tmp |= (7 << 12); break; 1207 case TRANSMISSION_MODE_2K:
997 case TRANSMISSION_MODE_4K: tmp |= (8 << 12); break; 1208 tmp |= (2 << 12);
998 default: 1209 break;
999 case TRANSMISSION_MODE_8K: tmp |= (9 << 12); break; 1210 case TRANSMISSION_MODE_4K:
1211 tmp |= (3 << 12);
1212 break;
1213 default:
1214 case TRANSMISSION_MODE_8K:
1215 tmp |= (4 << 12);
1216 break;
1000 } 1217 }
1001 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */ 1218 dib7000p_write_word(state, 26, tmp); /* timf_a(6xxx) */
1002 1219
1003 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */ 1220 /* P_ctrl_freeze_pha_shift=0, P_ctrl_pha_off_max */
1004 tmp = (0 << 4); 1221 tmp = (0 << 4);
1005 switch (ch->u.ofdm.transmission_mode) { 1222 switch (ch->u.ofdm.transmission_mode) {
1006 case TRANSMISSION_MODE_2K: tmp |= 0x6; break; 1223 case TRANSMISSION_MODE_2K:
1007 case TRANSMISSION_MODE_4K: tmp |= 0x7; break; 1224 tmp |= 0x6;
1008 default: 1225 break;
1009 case TRANSMISSION_MODE_8K: tmp |= 0x8; break; 1226 case TRANSMISSION_MODE_4K:
1227 tmp |= 0x7;
1228 break;
1229 default:
1230 case TRANSMISSION_MODE_8K:
1231 tmp |= 0x8;
1232 break;
1010 } 1233 }
1011 dib7000p_write_word(state, 32, tmp); 1234 dib7000p_write_word(state, 32, tmp);
1012 1235
1013 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */ 1236 /* P_ctrl_sfreq_inh=0, P_ctrl_sfreq_step */
1014 tmp = (0 << 4); 1237 tmp = (0 << 4);
1015 switch (ch->u.ofdm.transmission_mode) { 1238 switch (ch->u.ofdm.transmission_mode) {
1016 case TRANSMISSION_MODE_2K: tmp |= 0x6; break; 1239 case TRANSMISSION_MODE_2K:
1017 case TRANSMISSION_MODE_4K: tmp |= 0x7; break; 1240 tmp |= 0x6;
1018 default: 1241 break;
1019 case TRANSMISSION_MODE_8K: tmp |= 0x8; break; 1242 case TRANSMISSION_MODE_4K:
1243 tmp |= 0x7;
1244 break;
1245 default:
1246 case TRANSMISSION_MODE_8K:
1247 tmp |= 0x8;
1248 break;
1020 } 1249 }
1021 dib7000p_write_word(state, 33, tmp); 1250 dib7000p_write_word(state, 33, tmp);
1022 1251
1023 tmp = dib7000p_read_word(state,509); 1252 tmp = dib7000p_read_word(state, 509);
1024 if (!((tmp >> 6) & 0x1)) { 1253 if (!((tmp >> 6) & 0x1)) {
1025 /* restart the fec */ 1254 /* restart the fec */
1026 tmp = dib7000p_read_word(state,771); 1255 tmp = dib7000p_read_word(state, 771);
1027 dib7000p_write_word(state, 771, tmp | (1 << 1)); 1256 dib7000p_write_word(state, 771, tmp | (1 << 1));
1028 dib7000p_write_word(state, 771, tmp); 1257 dib7000p_write_word(state, 771, tmp);
1029 msleep(10); 1258 msleep(40);
1030 tmp = dib7000p_read_word(state,509); 1259 tmp = dib7000p_read_word(state, 509);
1031 } 1260 }
1032
1033 // we achieved a lock - it's time to update the osc freq 1261 // we achieved a lock - it's time to update the osc freq
1034 if ((tmp >> 6) & 0x1) 1262 if ((tmp >> 6) & 0x1) {
1035 dib7000p_update_timf(state); 1263 dib7000p_update_timf(state);
1264 /* P_timf_alpha += 2 */
1265 tmp = dib7000p_read_word(state, 26);
1266 dib7000p_write_word(state, 26, (tmp & ~(0xf << 12)) | ((((tmp >> 12) & 0xf) + 5) << 12));
1267 }
1036 1268
1037 if (state->cfg.spur_protect) 1269 if (state->cfg.spur_protect)
1038 dib7000p_spur_protect(state, ch->frequency/1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 1270 dib7000p_spur_protect(state, ch->frequency / 1000, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1039 1271
1040 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth)); 1272 dib7000p_set_bandwidth(state, BANDWIDTH_TO_KHZ(ch->u.ofdm.bandwidth));
1041 return 0; 1273 return 0;
1042} 1274}
1043 1275
@@ -1046,63 +1278,82 @@ static int dib7000p_wakeup(struct dvb_frontend *demod)
1046 struct dib7000p_state *state = demod->demodulator_priv; 1278 struct dib7000p_state *state = demod->demodulator_priv;
1047 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL); 1279 dib7000p_set_power_mode(state, DIB7000P_POWER_ALL);
1048 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON); 1280 dib7000p_set_adc_state(state, DIBX000_SLOW_ADC_ON);
1281 if (state->version == SOC7090)
1282 dib7000p_sad_calib(state);
1049 return 0; 1283 return 0;
1050} 1284}
1051 1285
1052static int dib7000p_sleep(struct dvb_frontend *demod) 1286static int dib7000p_sleep(struct dvb_frontend *demod)
1053{ 1287{
1054 struct dib7000p_state *state = demod->demodulator_priv; 1288 struct dib7000p_state *state = demod->demodulator_priv;
1289 if (state->version == SOC7090)
1290 return dib7090_set_output_mode(demod, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1055 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY); 1291 return dib7000p_set_output_mode(state, OUTMODE_HIGH_Z) | dib7000p_set_power_mode(state, DIB7000P_POWER_INTERFACE_ONLY);
1056} 1292}
1057 1293
1058static int dib7000p_identify(struct dib7000p_state *st) 1294static int dib7000p_identify(struct dib7000p_state *st)
1059{ 1295{
1060 u16 value; 1296 u16 value;
1061 dprintk( "checking demod on I2C address: %d (%x)", 1297 dprintk("checking demod on I2C address: %d (%x)", st->i2c_addr, st->i2c_addr);
1062 st->i2c_addr, st->i2c_addr);
1063 1298
1064 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) { 1299 if ((value = dib7000p_read_word(st, 768)) != 0x01b3) {
1065 dprintk( "wrong Vendor ID (read=0x%x)",value); 1300 dprintk("wrong Vendor ID (read=0x%x)", value);
1066 return -EREMOTEIO; 1301 return -EREMOTEIO;
1067 } 1302 }
1068 1303
1069 if ((value = dib7000p_read_word(st, 769)) != 0x4000) { 1304 if ((value = dib7000p_read_word(st, 769)) != 0x4000) {
1070 dprintk( "wrong Device ID (%x)",value); 1305 dprintk("wrong Device ID (%x)", value);
1071 return -EREMOTEIO; 1306 return -EREMOTEIO;
1072 } 1307 }
1073 1308
1074 return 0; 1309 return 0;
1075} 1310}
1076 1311
1077 1312static int dib7000p_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1078static int dib7000p_get_frontend(struct dvb_frontend* fe,
1079 struct dvb_frontend_parameters *fep)
1080{ 1313{
1081 struct dib7000p_state *state = fe->demodulator_priv; 1314 struct dib7000p_state *state = fe->demodulator_priv;
1082 u16 tps = dib7000p_read_word(state,463); 1315 u16 tps = dib7000p_read_word(state, 463);
1083 1316
1084 fep->inversion = INVERSION_AUTO; 1317 fep->inversion = INVERSION_AUTO;
1085 1318
1086 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth); 1319 fep->u.ofdm.bandwidth = BANDWIDTH_TO_INDEX(state->current_bandwidth);
1087 1320
1088 switch ((tps >> 8) & 0x3) { 1321 switch ((tps >> 8) & 0x3) {
1089 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break; 1322 case 0:
1090 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break; 1323 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K;
1091 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */ 1324 break;
1325 case 1:
1326 fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K;
1327 break;
1328 /* case 2: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_4K; break; */
1092 } 1329 }
1093 1330
1094 switch (tps & 0x3) { 1331 switch (tps & 0x3) {
1095 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break; 1332 case 0:
1096 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break; 1333 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32;
1097 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break; 1334 break;
1098 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break; 1335 case 1:
1336 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16;
1337 break;
1338 case 2:
1339 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8;
1340 break;
1341 case 3:
1342 fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4;
1343 break;
1099 } 1344 }
1100 1345
1101 switch ((tps >> 14) & 0x3) { 1346 switch ((tps >> 14) & 0x3) {
1102 case 0: fep->u.ofdm.constellation = QPSK; break; 1347 case 0:
1103 case 1: fep->u.ofdm.constellation = QAM_16; break; 1348 fep->u.ofdm.constellation = QPSK;
1104 case 2: 1349 break;
1105 default: fep->u.ofdm.constellation = QAM_64; break; 1350 case 1:
1351 fep->u.ofdm.constellation = QAM_16;
1352 break;
1353 case 2:
1354 default:
1355 fep->u.ofdm.constellation = QAM_64;
1356 break;
1106 } 1357 }
1107 1358
1108 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */ 1359 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
@@ -1110,22 +1361,42 @@ static int dib7000p_get_frontend(struct dvb_frontend* fe,
1110 1361
1111 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE; 1362 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
1112 switch ((tps >> 5) & 0x7) { 1363 switch ((tps >> 5) & 0x7) {
1113 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break; 1364 case 1:
1114 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break; 1365 fep->u.ofdm.code_rate_HP = FEC_1_2;
1115 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break; 1366 break;
1116 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break; 1367 case 2:
1117 case 7: 1368 fep->u.ofdm.code_rate_HP = FEC_2_3;
1118 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break; 1369 break;
1370 case 3:
1371 fep->u.ofdm.code_rate_HP = FEC_3_4;
1372 break;
1373 case 5:
1374 fep->u.ofdm.code_rate_HP = FEC_5_6;
1375 break;
1376 case 7:
1377 default:
1378 fep->u.ofdm.code_rate_HP = FEC_7_8;
1379 break;
1119 1380
1120 } 1381 }
1121 1382
1122 switch ((tps >> 2) & 0x7) { 1383 switch ((tps >> 2) & 0x7) {
1123 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break; 1384 case 1:
1124 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break; 1385 fep->u.ofdm.code_rate_LP = FEC_1_2;
1125 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break; 1386 break;
1126 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break; 1387 case 2:
1127 case 7: 1388 fep->u.ofdm.code_rate_LP = FEC_2_3;
1128 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break; 1389 break;
1390 case 3:
1391 fep->u.ofdm.code_rate_LP = FEC_3_4;
1392 break;
1393 case 5:
1394 fep->u.ofdm.code_rate_LP = FEC_5_6;
1395 break;
1396 case 7:
1397 default:
1398 fep->u.ofdm.code_rate_LP = FEC_7_8;
1399 break;
1129 } 1400 }
1130 1401
1131 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */ 1402 /* native interleaver: (dib7000p_read_word(state, 464) >> 5) & 0x1 */
@@ -1133,15 +1404,18 @@ static int dib7000p_get_frontend(struct dvb_frontend* fe,
1133 return 0; 1404 return 0;
1134} 1405}
1135 1406
1136static int dib7000p_set_frontend(struct dvb_frontend* fe, 1407static int dib7000p_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1137 struct dvb_frontend_parameters *fep)
1138{ 1408{
1139 struct dib7000p_state *state = fe->demodulator_priv; 1409 struct dib7000p_state *state = fe->demodulator_priv;
1140 int time, ret; 1410 int time, ret;
1141 1411
1142 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z); 1412 if (state->version == SOC7090) {
1413 dib7090_set_diversity_in(fe, 0);
1414 dib7090_set_output_mode(fe, OUTMODE_HIGH_Z);
1415 } else
1416 dib7000p_set_output_mode(state, OUTMODE_HIGH_Z);
1143 1417
1144 /* maybe the parameter has been changed */ 1418 /* maybe the parameter has been changed */
1145 state->sfn_workaround_active = buggy_sfn_workaround; 1419 state->sfn_workaround_active = buggy_sfn_workaround;
1146 1420
1147 if (fe->ops.tuner_ops.set_params) 1421 if (fe->ops.tuner_ops.set_params)
@@ -1156,9 +1430,7 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
1156 } while (time != -1); 1430 } while (time != -1);
1157 1431
1158 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO || 1432 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1159 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || 1433 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1160 fep->u.ofdm.constellation == QAM_AUTO ||
1161 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1162 int i = 800, found; 1434 int i = 800, found;
1163 1435
1164 dib7000p_autosearch_start(fe, fep); 1436 dib7000p_autosearch_start(fe, fep);
@@ -1167,9 +1439,9 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
1167 found = dib7000p_autosearch_is_irq(fe); 1439 found = dib7000p_autosearch_is_irq(fe);
1168 } while (found == 0 && i--); 1440 } while (found == 0 && i--);
1169 1441
1170 dprintk("autosearch returns: %d",found); 1442 dprintk("autosearch returns: %d", found);
1171 if (found == 0 || found == 1) 1443 if (found == 0 || found == 1)
1172 return 0; // no channel found 1444 return 0;
1173 1445
1174 dib7000p_get_frontend(fe, fep); 1446 dib7000p_get_frontend(fe, fep);
1175 } 1447 }
@@ -1177,11 +1449,15 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
1177 ret = dib7000p_tune(fe, fep); 1449 ret = dib7000p_tune(fe, fep);
1178 1450
1179 /* make this a config parameter */ 1451 /* make this a config parameter */
1180 dib7000p_set_output_mode(state, state->cfg.output_mode); 1452 if (state->version == SOC7090)
1181 return ret; 1453 dib7090_set_output_mode(fe, state->cfg.output_mode);
1454 else
1455 dib7000p_set_output_mode(state, state->cfg.output_mode);
1456
1457 return ret;
1182} 1458}
1183 1459
1184static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat) 1460static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t * stat)
1185{ 1461{
1186 struct dib7000p_state *state = fe->demodulator_priv; 1462 struct dib7000p_state *state = fe->demodulator_priv;
1187 u16 lock = dib7000p_read_word(state, 509); 1463 u16 lock = dib7000p_read_word(state, 509);
@@ -1196,27 +1472,27 @@ static int dib7000p_read_status(struct dvb_frontend *fe, fe_status_t *stat)
1196 *stat |= FE_HAS_VITERBI; 1472 *stat |= FE_HAS_VITERBI;
1197 if (lock & 0x0010) 1473 if (lock & 0x0010)
1198 *stat |= FE_HAS_SYNC; 1474 *stat |= FE_HAS_SYNC;
1199 if ((lock & 0x0038) == 0x38) 1475 if ((lock & 0x0038) == 0x38)
1200 *stat |= FE_HAS_LOCK; 1476 *stat |= FE_HAS_LOCK;
1201 1477
1202 return 0; 1478 return 0;
1203} 1479}
1204 1480
1205static int dib7000p_read_ber(struct dvb_frontend *fe, u32 *ber) 1481static int dib7000p_read_ber(struct dvb_frontend *fe, u32 * ber)
1206{ 1482{
1207 struct dib7000p_state *state = fe->demodulator_priv; 1483 struct dib7000p_state *state = fe->demodulator_priv;
1208 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501); 1484 *ber = (dib7000p_read_word(state, 500) << 16) | dib7000p_read_word(state, 501);
1209 return 0; 1485 return 0;
1210} 1486}
1211 1487
1212static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 *unc) 1488static int dib7000p_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
1213{ 1489{
1214 struct dib7000p_state *state = fe->demodulator_priv; 1490 struct dib7000p_state *state = fe->demodulator_priv;
1215 *unc = dib7000p_read_word(state, 506); 1491 *unc = dib7000p_read_word(state, 506);
1216 return 0; 1492 return 0;
1217} 1493}
1218 1494
1219static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength) 1495static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
1220{ 1496{
1221 struct dib7000p_state *state = fe->demodulator_priv; 1497 struct dib7000p_state *state = fe->demodulator_priv;
1222 u16 val = dib7000p_read_word(state, 394); 1498 u16 val = dib7000p_read_word(state, 394);
@@ -1224,7 +1500,7 @@ static int dib7000p_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
1224 return 0; 1500 return 0;
1225} 1501}
1226 1502
1227static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr) 1503static int dib7000p_read_snr(struct dvb_frontend *fe, u16 * snr)
1228{ 1504{
1229 struct dib7000p_state *state = fe->demodulator_priv; 1505 struct dib7000p_state *state = fe->demodulator_priv;
1230 u16 val; 1506 u16 val;
@@ -1240,19 +1516,17 @@ static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1240 noise_exp -= 0x40; 1516 noise_exp -= 0x40;
1241 1517
1242 signal_mant = (val >> 6) & 0xFF; 1518 signal_mant = (val >> 6) & 0xFF;
1243 signal_exp = (val & 0x3F); 1519 signal_exp = (val & 0x3F);
1244 if ((signal_exp & 0x20) != 0) 1520 if ((signal_exp & 0x20) != 0)
1245 signal_exp -= 0x40; 1521 signal_exp -= 0x40;
1246 1522
1247 if (signal_mant != 0) 1523 if (signal_mant != 0)
1248 result = intlog10(2) * 10 * signal_exp + 10 * 1524 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant);
1249 intlog10(signal_mant);
1250 else 1525 else
1251 result = intlog10(2) * 10 * signal_exp - 100; 1526 result = intlog10(2) * 10 * signal_exp - 100;
1252 1527
1253 if (noise_mant != 0) 1528 if (noise_mant != 0)
1254 result -= intlog10(2) * 10 * noise_exp + 10 * 1529 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant);
1255 intlog10(noise_mant);
1256 else 1530 else
1257 result -= intlog10(2) * 10 * noise_exp - 100; 1531 result -= intlog10(2) * 10 * noise_exp - 100;
1258 1532
@@ -1260,7 +1534,7 @@ static int dib7000p_read_snr(struct dvb_frontend* fe, u16 *snr)
1260 return 0; 1534 return 0;
1261} 1535}
1262 1536
1263static int dib7000p_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 1537static int dib7000p_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1264{ 1538{
1265 tune->min_delay_ms = 1000; 1539 tune->min_delay_ms = 1000;
1266 return 0; 1540 return 0;
@@ -1270,6 +1544,7 @@ static void dib7000p_release(struct dvb_frontend *demod)
1270{ 1544{
1271 struct dib7000p_state *st = demod->demodulator_priv; 1545 struct dib7000p_state *st = demod->demodulator_priv;
1272 dibx000_exit_i2c_master(&st->i2c_master); 1546 dibx000_exit_i2c_master(&st->i2c_master);
1547 i2c_del_adapter(&st->dib7090_tuner_adap);
1273 kfree(st); 1548 kfree(st);
1274} 1549}
1275 1550
@@ -1277,8 +1552,8 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1277{ 1552{
1278 u8 tx[2], rx[2]; 1553 u8 tx[2], rx[2];
1279 struct i2c_msg msg[2] = { 1554 struct i2c_msg msg[2] = {
1280 { .addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2 }, 1555 {.addr = 18 >> 1, .flags = 0, .buf = tx, .len = 2},
1281 { .addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2 }, 1556 {.addr = 18 >> 1, .flags = I2C_M_RD, .buf = rx, .len = 2},
1282 }; 1557 };
1283 1558
1284 tx[0] = 0x03; 1559 tx[0] = 0x03;
@@ -1303,7 +1578,7 @@ int dib7000pc_detection(struct i2c_adapter *i2c_adap)
1303} 1578}
1304EXPORT_SYMBOL(dib7000pc_detection); 1579EXPORT_SYMBOL(dib7000pc_detection);
1305 1580
1306struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating) 1581struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *demod, enum dibx000_i2c_interface intf, int gating)
1307{ 1582{
1308 struct dib7000p_state *st = demod->demodulator_priv; 1583 struct dib7000p_state *st = demod->demodulator_priv;
1309 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating); 1584 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
@@ -1312,19 +1587,19 @@ EXPORT_SYMBOL(dib7000p_get_i2c_master);
1312 1587
1313int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) 1588int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1314{ 1589{
1315 struct dib7000p_state *state = fe->demodulator_priv; 1590 struct dib7000p_state *state = fe->demodulator_priv;
1316 u16 val = dib7000p_read_word(state, 235) & 0xffef; 1591 u16 val = dib7000p_read_word(state, 235) & 0xffef;
1317 val |= (onoff & 0x1) << 4; 1592 val |= (onoff & 0x1) << 4;
1318 dprintk("PID filter enabled %d", onoff); 1593 dprintk("PID filter enabled %d", onoff);
1319 return dib7000p_write_word(state, 235, val); 1594 return dib7000p_write_word(state, 235, val);
1320} 1595}
1321EXPORT_SYMBOL(dib7000p_pid_filter_ctrl); 1596EXPORT_SYMBOL(dib7000p_pid_filter_ctrl);
1322 1597
1323int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 1598int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1324{ 1599{
1325 struct dib7000p_state *state = fe->demodulator_priv; 1600 struct dib7000p_state *state = fe->demodulator_priv;
1326 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff); 1601 dprintk("PID filter: index %x, PID %d, OnOff %d", id, pid, onoff);
1327 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0); 1602 return dib7000p_write_word(state, 241 + id, onoff ? (1 << 13) | pid : 0);
1328} 1603}
1329EXPORT_SYMBOL(dib7000p_pid_filter); 1604EXPORT_SYMBOL(dib7000p_pid_filter);
1330 1605
@@ -1340,16 +1615,19 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1340 1615
1341 dpst->i2c_adap = i2c; 1616 dpst->i2c_adap = i2c;
1342 1617
1343 for (k = no_of_demods-1; k >= 0; k--) { 1618 for (k = no_of_demods - 1; k >= 0; k--) {
1344 dpst->cfg = cfg[k]; 1619 dpst->cfg = cfg[k];
1345 1620
1346 /* designated i2c address */ 1621 /* designated i2c address */
1347 new_addr = (0x40 + k) << 1; 1622 if (cfg[k].default_i2c_addr != 0)
1623 new_addr = cfg[k].default_i2c_addr + (k << 1);
1624 else
1625 new_addr = (0x40 + k) << 1;
1348 dpst->i2c_addr = new_addr; 1626 dpst->i2c_addr = new_addr;
1349 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */ 1627 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1350 if (dib7000p_identify(dpst) != 0) { 1628 if (dib7000p_identify(dpst) != 0) {
1351 dpst->i2c_addr = default_addr; 1629 dpst->i2c_addr = default_addr;
1352 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */ 1630 dib7000p_write_word(dpst, 1287, 0x0003); /* sram lead in, rdy */
1353 if (dib7000p_identify(dpst) != 0) { 1631 if (dib7000p_identify(dpst) != 0) {
1354 dprintk("DiB7000P #%d: not identified\n", k); 1632 dprintk("DiB7000P #%d: not identified\n", k);
1355 kfree(dpst); 1633 kfree(dpst);
@@ -1368,7 +1646,10 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1368 1646
1369 for (k = 0; k < no_of_demods; k++) { 1647 for (k = 0; k < no_of_demods; k++) {
1370 dpst->cfg = cfg[k]; 1648 dpst->cfg = cfg[k];
1371 dpst->i2c_addr = (0x40 + k) << 1; 1649 if (cfg[k].default_i2c_addr != 0)
1650 dpst->i2c_addr = (cfg[k].default_i2c_addr + k) << 1;
1651 else
1652 dpst->i2c_addr = (0x40 + k) << 1;
1372 1653
1373 // unforce divstr 1654 // unforce divstr
1374 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2); 1655 dib7000p_write_word(dpst, 1285, dpst->i2c_addr << 2);
@@ -1382,8 +1663,613 @@ int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 defau
1382} 1663}
1383EXPORT_SYMBOL(dib7000p_i2c_enumeration); 1664EXPORT_SYMBOL(dib7000p_i2c_enumeration);
1384 1665
1666static const s32 lut_1000ln_mant[] = {
1667 6908, 6956, 7003, 7047, 7090, 7131, 7170, 7208, 7244, 7279, 7313, 7346, 7377, 7408, 7438, 7467, 7495, 7523, 7549, 7575, 7600
1668};
1669
1670static s32 dib7000p_get_adc_power(struct dvb_frontend *fe)
1671{
1672 struct dib7000p_state *state = fe->demodulator_priv;
1673 u32 tmp_val = 0, exp = 0, mant = 0;
1674 s32 pow_i;
1675 u16 buf[2];
1676 u8 ix = 0;
1677
1678 buf[0] = dib7000p_read_word(state, 0x184);
1679 buf[1] = dib7000p_read_word(state, 0x185);
1680 pow_i = (buf[0] << 16) | buf[1];
1681 dprintk("raw pow_i = %d", pow_i);
1682
1683 tmp_val = pow_i;
1684 while (tmp_val >>= 1)
1685 exp++;
1686
1687 mant = (pow_i * 1000 / (1 << exp));
1688 dprintk(" mant = %d exp = %d", mant / 1000, exp);
1689
1690 ix = (u8) ((mant - 1000) / 100); /* index of the LUT */
1691 dprintk(" ix = %d", ix);
1692
1693 pow_i = (lut_1000ln_mant[ix] + 693 * (exp - 20) - 6908);
1694 pow_i = (pow_i << 8) / 1000;
1695 dprintk(" pow_i = %d", pow_i);
1696
1697 return pow_i;
1698}
1699
1700static int map_addr_to_serpar_number(struct i2c_msg *msg)
1701{
1702 if ((msg->buf[0] <= 15))
1703 msg->buf[0] -= 1;
1704 else if (msg->buf[0] == 17)
1705 msg->buf[0] = 15;
1706 else if (msg->buf[0] == 16)
1707 msg->buf[0] = 17;
1708 else if (msg->buf[0] == 19)
1709 msg->buf[0] = 16;
1710 else if (msg->buf[0] >= 21 && msg->buf[0] <= 25)
1711 msg->buf[0] -= 3;
1712 else if (msg->buf[0] == 28)
1713 msg->buf[0] = 23;
1714 else
1715 return -EINVAL;
1716 return 0;
1717}
1718
1719static int w7090p_tuner_write_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1720{
1721 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1722 u8 n_overflow = 1;
1723 u16 i = 1000;
1724 u16 serpar_num = msg[0].buf[0];
1725
1726 while (n_overflow == 1 && i) {
1727 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1728 i--;
1729 if (i == 0)
1730 dprintk("Tuner ITF: write busy (overflow)");
1731 }
1732 dib7000p_write_word(state, 1985, (1 << 6) | (serpar_num & 0x3f));
1733 dib7000p_write_word(state, 1986, (msg[0].buf[1] << 8) | msg[0].buf[2]);
1734
1735 return num;
1736}
1737
1738static int w7090p_tuner_read_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1739{
1740 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1741 u8 n_overflow = 1, n_empty = 1;
1742 u16 i = 1000;
1743 u16 serpar_num = msg[0].buf[0];
1744 u16 read_word;
1745
1746 while (n_overflow == 1 && i) {
1747 n_overflow = (dib7000p_read_word(state, 1984) >> 1) & 0x1;
1748 i--;
1749 if (i == 0)
1750 dprintk("TunerITF: read busy (overflow)");
1751 }
1752 dib7000p_write_word(state, 1985, (0 << 6) | (serpar_num & 0x3f));
1753
1754 i = 1000;
1755 while (n_empty == 1 && i) {
1756 n_empty = dib7000p_read_word(state, 1984) & 0x1;
1757 i--;
1758 if (i == 0)
1759 dprintk("TunerITF: read busy (empty)");
1760 }
1761 read_word = dib7000p_read_word(state, 1987);
1762 msg[1].buf[0] = (read_word >> 8) & 0xff;
1763 msg[1].buf[1] = (read_word) & 0xff;
1764
1765 return num;
1766}
1767
1768static int w7090p_tuner_rw_serpar(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1769{
1770 if (map_addr_to_serpar_number(&msg[0]) == 0) { /* else = Tuner regs to ignore : DIG_CFG, CTRL_RF_LT, PLL_CFG, PWM1_REG, ADCCLK, DIG_CFG_3; SLEEP_EN... */
1771 if (num == 1) { /* write */
1772 return w7090p_tuner_write_serpar(i2c_adap, msg, 1);
1773 } else { /* read */
1774 return w7090p_tuner_read_serpar(i2c_adap, msg, 2);
1775 }
1776 }
1777 return num;
1778}
1779
1780int dib7090p_rw_on_apb(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num, u16 apb_address)
1781{
1782 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1783 u16 word;
1784
1785 if (num == 1) { /* write */
1786 dib7000p_write_word(state, apb_address, ((msg[0].buf[1] << 8) | (msg[0].buf[2])));
1787 } else {
1788 word = dib7000p_read_word(state, apb_address);
1789 msg[1].buf[0] = (word >> 8) & 0xff;
1790 msg[1].buf[1] = (word) & 0xff;
1791 }
1792
1793 return num;
1794}
1795
1796static int dib7090_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1797{
1798 struct dib7000p_state *state = i2c_get_adapdata(i2c_adap);
1799
1800 u16 apb_address = 0, word;
1801 int i = 0;
1802 switch (msg[0].buf[0]) {
1803 case 0x12:
1804 apb_address = 1920;
1805 break;
1806 case 0x14:
1807 apb_address = 1921;
1808 break;
1809 case 0x24:
1810 apb_address = 1922;
1811 break;
1812 case 0x1a:
1813 apb_address = 1923;
1814 break;
1815 case 0x22:
1816 apb_address = 1924;
1817 break;
1818 case 0x33:
1819 apb_address = 1926;
1820 break;
1821 case 0x34:
1822 apb_address = 1927;
1823 break;
1824 case 0x35:
1825 apb_address = 1928;
1826 break;
1827 case 0x36:
1828 apb_address = 1929;
1829 break;
1830 case 0x37:
1831 apb_address = 1930;
1832 break;
1833 case 0x38:
1834 apb_address = 1931;
1835 break;
1836 case 0x39:
1837 apb_address = 1932;
1838 break;
1839 case 0x2a:
1840 apb_address = 1935;
1841 break;
1842 case 0x2b:
1843 apb_address = 1936;
1844 break;
1845 case 0x2c:
1846 apb_address = 1937;
1847 break;
1848 case 0x2d:
1849 apb_address = 1938;
1850 break;
1851 case 0x2e:
1852 apb_address = 1939;
1853 break;
1854 case 0x2f:
1855 apb_address = 1940;
1856 break;
1857 case 0x30:
1858 apb_address = 1941;
1859 break;
1860 case 0x31:
1861 apb_address = 1942;
1862 break;
1863 case 0x32:
1864 apb_address = 1943;
1865 break;
1866 case 0x3e:
1867 apb_address = 1944;
1868 break;
1869 case 0x3f:
1870 apb_address = 1945;
1871 break;
1872 case 0x40:
1873 apb_address = 1948;
1874 break;
1875 case 0x25:
1876 apb_address = 914;
1877 break;
1878 case 0x26:
1879 apb_address = 915;
1880 break;
1881 case 0x27:
1882 apb_address = 916;
1883 break;
1884 case 0x28:
1885 apb_address = 917;
1886 break;
1887 case 0x1d:
1888 i = ((dib7000p_read_word(state, 72) >> 12) & 0x3);
1889 word = dib7000p_read_word(state, 384 + i);
1890 msg[1].buf[0] = (word >> 8) & 0xff;
1891 msg[1].buf[1] = (word) & 0xff;
1892 return num;
1893 case 0x1f:
1894 if (num == 1) { /* write */
1895 word = (u16) ((msg[0].buf[1] << 8) | msg[0].buf[2]);
1896 word &= 0x3;
1897 word = (dib7000p_read_word(state, 72) & ~(3 << 12)) | (word << 12);
1898 dib7000p_write_word(state, 72, word); /* Set the proper input */
1899 return num;
1900 }
1901 }
1902
1903 if (apb_address != 0) /* R/W acces via APB */
1904 return dib7090p_rw_on_apb(i2c_adap, msg, num, apb_address);
1905 else /* R/W access via SERPAR */
1906 return w7090p_tuner_rw_serpar(i2c_adap, msg, num);
1907
1908 return 0;
1909}
1910
1911static u32 dib7000p_i2c_func(struct i2c_adapter *adapter)
1912{
1913 return I2C_FUNC_I2C;
1914}
1915
1916static struct i2c_algorithm dib7090_tuner_xfer_algo = {
1917 .master_xfer = dib7090_tuner_xfer,
1918 .functionality = dib7000p_i2c_func,
1919};
1920
1921struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
1922{
1923 struct dib7000p_state *st = fe->demodulator_priv;
1924 return &st->dib7090_tuner_adap;
1925}
1926EXPORT_SYMBOL(dib7090_get_i2c_tuner);
1927
1928static int dib7090_host_bus_drive(struct dib7000p_state *state, u8 drive)
1929{
1930 u16 reg;
1931
1932 /* drive host bus 2, 3, 4 */
1933 reg = dib7000p_read_word(state, 1798) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1934 reg |= (drive << 12) | (drive << 6) | drive;
1935 dib7000p_write_word(state, 1798, reg);
1936
1937 /* drive host bus 5,6 */
1938 reg = dib7000p_read_word(state, 1799) & ~((0x7 << 2) | (0x7 << 8));
1939 reg |= (drive << 8) | (drive << 2);
1940 dib7000p_write_word(state, 1799, reg);
1941
1942 /* drive host bus 7, 8, 9 */
1943 reg = dib7000p_read_word(state, 1800) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1944 reg |= (drive << 12) | (drive << 6) | drive;
1945 dib7000p_write_word(state, 1800, reg);
1946
1947 /* drive host bus 10, 11 */
1948 reg = dib7000p_read_word(state, 1801) & ~((0x7 << 2) | (0x7 << 8));
1949 reg |= (drive << 8) | (drive << 2);
1950 dib7000p_write_word(state, 1801, reg);
1951
1952 /* drive host bus 12, 13, 14 */
1953 reg = dib7000p_read_word(state, 1802) & ~((0x7) | (0x7 << 6) | (0x7 << 12));
1954 reg |= (drive << 12) | (drive << 6) | drive;
1955 dib7000p_write_word(state, 1802, reg);
1956
1957 return 0;
1958}
1959
1960static u32 dib7090_calcSyncFreq(u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 syncSize)
1961{
1962 u32 quantif = 3;
1963 u32 nom = (insertExtSynchro * P_Kin + syncSize);
1964 u32 denom = P_Kout;
1965 u32 syncFreq = ((nom << quantif) / denom);
1966
1967 if ((syncFreq & ((1 << quantif) - 1)) != 0)
1968 syncFreq = (syncFreq >> quantif) + 1;
1969 else
1970 syncFreq = (syncFreq >> quantif);
1971
1972 if (syncFreq != 0)
1973 syncFreq = syncFreq - 1;
1974
1975 return syncFreq;
1976}
1977
1978static int dib7090_cfg_DibTx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 insertExtSynchro, u32 synchroMode, u32 syncWord, u32 syncSize)
1979{
1980 u8 index_buf;
1981 u16 rx_copy_buf[22];
1982
1983 dprintk("Configure DibStream Tx");
1984 for (index_buf = 0; index_buf < 22; index_buf++)
1985 rx_copy_buf[index_buf] = dib7000p_read_word(state, 1536+index_buf);
1986
1987 dib7000p_write_word(state, 1615, 1);
1988 dib7000p_write_word(state, 1603, P_Kin);
1989 dib7000p_write_word(state, 1605, P_Kout);
1990 dib7000p_write_word(state, 1606, insertExtSynchro);
1991 dib7000p_write_word(state, 1608, synchroMode);
1992 dib7000p_write_word(state, 1609, (syncWord >> 16) & 0xffff);
1993 dib7000p_write_word(state, 1610, syncWord & 0xffff);
1994 dib7000p_write_word(state, 1612, syncSize);
1995 dib7000p_write_word(state, 1615, 0);
1996
1997 for (index_buf = 0; index_buf < 22; index_buf++)
1998 dib7000p_write_word(state, 1536+index_buf, rx_copy_buf[index_buf]);
1999
2000 return 0;
2001}
2002
2003static int dib7090_cfg_DibRx(struct dib7000p_state *state, u32 P_Kin, u32 P_Kout, u32 synchroMode, u32 insertExtSynchro, u32 syncWord, u32 syncSize,
2004 u32 dataOutRate)
2005{
2006 u32 syncFreq;
2007
2008 dprintk("Configure DibStream Rx");
2009 if ((P_Kin != 0) && (P_Kout != 0)) {
2010 syncFreq = dib7090_calcSyncFreq(P_Kin, P_Kout, insertExtSynchro, syncSize);
2011 dib7000p_write_word(state, 1542, syncFreq);
2012 }
2013 dib7000p_write_word(state, 1554, 1);
2014 dib7000p_write_word(state, 1536, P_Kin);
2015 dib7000p_write_word(state, 1537, P_Kout);
2016 dib7000p_write_word(state, 1539, synchroMode);
2017 dib7000p_write_word(state, 1540, (syncWord >> 16) & 0xffff);
2018 dib7000p_write_word(state, 1541, syncWord & 0xffff);
2019 dib7000p_write_word(state, 1543, syncSize);
2020 dib7000p_write_word(state, 1544, dataOutRate);
2021 dib7000p_write_word(state, 1554, 0);
2022
2023 return 0;
2024}
2025
2026static int dib7090_enDivOnHostBus(struct dib7000p_state *state)
2027{
2028 u16 reg;
2029
2030 dprintk("Enable Diversity on host bus");
2031 reg = (1 << 8) | (1 << 5);
2032 dib7000p_write_word(state, 1288, reg);
2033
2034 return dib7090_cfg_DibTx(state, 5, 5, 0, 0, 0, 0);
2035}
2036
2037static int dib7090_enAdcOnHostBus(struct dib7000p_state *state)
2038{
2039 u16 reg;
2040
2041 dprintk("Enable ADC on host bus");
2042 reg = (1 << 7) | (1 << 5);
2043 dib7000p_write_word(state, 1288, reg);
2044
2045 return dib7090_cfg_DibTx(state, 20, 5, 10, 0, 0, 0);
2046}
2047
2048static int dib7090_enMpegOnHostBus(struct dib7000p_state *state)
2049{
2050 u16 reg;
2051
2052 dprintk("Enable Mpeg on host bus");
2053 reg = (1 << 9) | (1 << 5);
2054 dib7000p_write_word(state, 1288, reg);
2055
2056 return dib7090_cfg_DibTx(state, 8, 5, 0, 0, 0, 0);
2057}
2058
2059static int dib7090_enMpegInput(struct dib7000p_state *state)
2060{
2061 dprintk("Enable Mpeg input");
2062 return dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2063}
2064
2065static int dib7090_enMpegMux(struct dib7000p_state *state, u16 pulseWidth, u16 enSerialMode, u16 enSerialClkDiv2)
2066{
2067 u16 reg = (1 << 7) | ((pulseWidth & 0x1f) << 2) | ((enSerialMode & 0x1) << 1) | (enSerialClkDiv2 & 0x1);
2068
2069 dprintk("Enable Mpeg mux");
2070 dib7000p_write_word(state, 1287, reg);
2071
2072 reg &= ~(1 << 7);
2073 dib7000p_write_word(state, 1287, reg);
2074
2075 reg = (1 << 4);
2076 dib7000p_write_word(state, 1288, reg);
2077
2078 return 0;
2079}
2080
2081static int dib7090_disableMpegMux(struct dib7000p_state *state)
2082{
2083 u16 reg;
2084
2085 dprintk("Disable Mpeg mux");
2086 dib7000p_write_word(state, 1288, 0);
2087
2088 reg = dib7000p_read_word(state, 1287);
2089 reg &= ~(1 << 7);
2090 dib7000p_write_word(state, 1287, reg);
2091
2092 return 0;
2093}
2094
2095static int dib7090_set_input_mode(struct dvb_frontend *fe, int mode)
2096{
2097 struct dib7000p_state *state = fe->demodulator_priv;
2098
2099 switch (mode) {
2100 case INPUT_MODE_DIVERSITY:
2101 dprintk("Enable diversity INPUT");
2102 dib7090_cfg_DibRx(state, 5, 5, 0, 0, 0, 0, 0);
2103 break;
2104 case INPUT_MODE_MPEG:
2105 dprintk("Enable Mpeg INPUT");
2106 dib7090_cfg_DibRx(state, 8, 5, 0, 0, 0, 8, 0); /*outputRate = 8 */
2107 break;
2108 case INPUT_MODE_OFF:
2109 default:
2110 dprintk("Disable INPUT");
2111 dib7090_cfg_DibRx(state, 0, 0, 0, 0, 0, 0, 0);
2112 break;
2113 }
2114 return 0;
2115}
2116
2117static int dib7090_set_diversity_in(struct dvb_frontend *fe, int onoff)
2118{
2119 switch (onoff) {
2120 case 0: /* only use the internal way - not the diversity input */
2121 dib7090_set_input_mode(fe, INPUT_MODE_MPEG);
2122 break;
2123 case 1: /* both ways */
2124 case 2: /* only the diversity input */
2125 dib7090_set_input_mode(fe, INPUT_MODE_DIVERSITY);
2126 break;
2127 }
2128
2129 return 0;
2130}
2131
2132static int dib7090_set_output_mode(struct dvb_frontend *fe, int mode)
2133{
2134 struct dib7000p_state *state = fe->demodulator_priv;
2135
2136 u16 outreg, smo_mode, fifo_threshold;
2137 u8 prefer_mpeg_mux_use = 1;
2138 int ret = 0;
2139
2140 dib7090_host_bus_drive(state, 1);
2141
2142 fifo_threshold = 1792;
2143 smo_mode = (dib7000p_read_word(state, 235) & 0x0050) | (1 << 1);
2144 outreg = dib7000p_read_word(state, 1286) & ~((1 << 10) | (0x7 << 6) | (1 << 1));
2145
2146 switch (mode) {
2147 case OUTMODE_HIGH_Z:
2148 outreg = 0;
2149 break;
2150
2151 case OUTMODE_MPEG2_SERIAL:
2152 if (prefer_mpeg_mux_use) {
2153 dprintk("Sip 7090P setting output mode TS_SERIAL using Mpeg Mux");
2154 dib7090_enMpegOnHostBus(state);
2155 dib7090_enMpegInput(state);
2156 if (state->cfg.enMpegOutput == 1)
2157 dib7090_enMpegMux(state, 3, 1, 1);
2158
2159 } else { /* Use Smooth block */
2160 dprintk("Sip 7090P setting output mode TS_SERIAL using Smooth bloc");
2161 dib7090_disableMpegMux(state);
2162 dib7000p_write_word(state, 1288, (1 << 6));
2163 outreg |= (2 << 6) | (0 << 1);
2164 }
2165 break;
2166
2167 case OUTMODE_MPEG2_PAR_GATED_CLK:
2168 if (prefer_mpeg_mux_use) {
2169 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Mpeg Mux");
2170 dib7090_enMpegOnHostBus(state);
2171 dib7090_enMpegInput(state);
2172 if (state->cfg.enMpegOutput == 1)
2173 dib7090_enMpegMux(state, 2, 0, 0);
2174 } else { /* Use Smooth block */
2175 dprintk("Sip 7090P setting output mode TS_PARALLEL_GATED using Smooth block");
2176 dib7090_disableMpegMux(state);
2177 dib7000p_write_word(state, 1288, (1 << 6));
2178 outreg |= (0 << 6);
2179 }
2180 break;
2181
2182 case OUTMODE_MPEG2_PAR_CONT_CLK: /* Using Smooth block only */
2183 dprintk("Sip 7090P setting output mode TS_PARALLEL_CONT using Smooth block");
2184 dib7090_disableMpegMux(state);
2185 dib7000p_write_word(state, 1288, (1 << 6));
2186 outreg |= (1 << 6);
2187 break;
2188
2189 case OUTMODE_MPEG2_FIFO: /* Using Smooth block because not supported by new Mpeg Mux bloc */
2190 dprintk("Sip 7090P setting output mode TS_FIFO using Smooth block");
2191 dib7090_disableMpegMux(state);
2192 dib7000p_write_word(state, 1288, (1 << 6));
2193 outreg |= (5 << 6);
2194 smo_mode |= (3 << 1);
2195 fifo_threshold = 512;
2196 break;
2197
2198 case OUTMODE_DIVERSITY:
2199 dprintk("Sip 7090P setting output mode MODE_DIVERSITY");
2200 dib7090_disableMpegMux(state);
2201 dib7090_enDivOnHostBus(state);
2202 break;
2203
2204 case OUTMODE_ANALOG_ADC:
2205 dprintk("Sip 7090P setting output mode MODE_ANALOG_ADC");
2206 dib7090_enAdcOnHostBus(state);
2207 break;
2208 }
2209
2210 if (state->cfg.output_mpeg2_in_188_bytes)
2211 smo_mode |= (1 << 5);
2212
2213 ret |= dib7000p_write_word(state, 235, smo_mode);
2214 ret |= dib7000p_write_word(state, 236, fifo_threshold); /* synchronous fread */
2215 ret |= dib7000p_write_word(state, 1286, outreg | (1 << 10)); /* allways set Dout active = 1 !!! */
2216
2217 return ret;
2218}
2219
2220int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
2221{
2222 struct dib7000p_state *state = fe->demodulator_priv;
2223 u16 en_cur_state;
2224
2225 dprintk("sleep dib7090: %d", onoff);
2226
2227 en_cur_state = dib7000p_read_word(state, 1922);
2228
2229 if (en_cur_state > 0xff)
2230 state->tuner_enable = en_cur_state;
2231
2232 if (onoff)
2233 en_cur_state &= 0x00ff;
2234 else {
2235 if (state->tuner_enable != 0)
2236 en_cur_state = state->tuner_enable;
2237 }
2238
2239 dib7000p_write_word(state, 1922, en_cur_state);
2240
2241 return 0;
2242}
2243EXPORT_SYMBOL(dib7090_tuner_sleep);
2244
2245int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
2246{
2247 dprintk("AGC restart callback: %d", restart);
2248 return 0;
2249}
2250EXPORT_SYMBOL(dib7090_agc_restart);
2251
2252int dib7090_get_adc_power(struct dvb_frontend *fe)
2253{
2254 return dib7000p_get_adc_power(fe);
2255}
2256EXPORT_SYMBOL(dib7090_get_adc_power);
2257
2258int dib7090_slave_reset(struct dvb_frontend *fe)
2259{
2260 struct dib7000p_state *state = fe->demodulator_priv;
2261 u16 reg;
2262
2263 reg = dib7000p_read_word(state, 1794);
2264 dib7000p_write_word(state, 1794, reg | (4 << 12));
2265
2266 dib7000p_write_word(state, 1032, 0xffff);
2267 return 0;
2268}
2269EXPORT_SYMBOL(dib7090_slave_reset);
2270
1385static struct dvb_frontend_ops dib7000p_ops; 2271static struct dvb_frontend_ops dib7000p_ops;
1386struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg) 2272struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
1387{ 2273{
1388 struct dvb_frontend *demod; 2274 struct dvb_frontend *demod;
1389 struct dib7000p_state *st; 2275 struct dib7000p_state *st;
@@ -1400,28 +2286,41 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
1400 /* Ensure the output mode remains at the previous default if it's 2286 /* Ensure the output mode remains at the previous default if it's
1401 * not specifically set by the caller. 2287 * not specifically set by the caller.
1402 */ 2288 */
1403 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && 2289 if ((st->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1404 (st->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
1405 st->cfg.output_mode = OUTMODE_MPEG2_FIFO; 2290 st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
1406 2291
1407 demod = &st->demod; 2292 demod = &st->demod;
1408 demod->demodulator_priv = st; 2293 demod->demodulator_priv = st;
1409 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops)); 2294 memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
1410 2295
1411 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */ 2296 dib7000p_write_word(st, 1287, 0x0003); /* sram lead in, rdy */
1412 2297
1413 if (dib7000p_identify(st) != 0) 2298 if (dib7000p_identify(st) != 0)
1414 goto error; 2299 goto error;
1415 2300
2301 st->version = dib7000p_read_word(st, 897);
2302
1416 /* FIXME: make sure the dev.parent field is initialized, or else 2303 /* FIXME: make sure the dev.parent field is initialized, or else
1417 request_firmware() will hit an OOPS (this should be moved somewhere 2304 request_firmware() will hit an OOPS (this should be moved somewhere
1418 more common) */ 2305 more common) */
1419 st->i2c_master.gated_tuner_i2c_adap.dev.parent = i2c_adap->dev.parent;
1420 2306
1421 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr); 2307 dibx000_init_i2c_master(&st->i2c_master, DIB7000P, st->i2c_adap, st->i2c_addr);
1422 2308
2309 /* init 7090 tuner adapter */
2310 strncpy(st->dib7090_tuner_adap.name, "DiB7090 tuner interface", sizeof(st->dib7090_tuner_adap.name));
2311 st->dib7090_tuner_adap.algo = &dib7090_tuner_xfer_algo;
2312 st->dib7090_tuner_adap.algo_data = NULL;
2313 st->dib7090_tuner_adap.dev.parent = st->i2c_adap->dev.parent;
2314 i2c_set_adapdata(&st->dib7090_tuner_adap, st);
2315 i2c_add_adapter(&st->dib7090_tuner_adap);
2316
1423 dib7000p_demod_reset(st); 2317 dib7000p_demod_reset(st);
1424 2318
2319 if (st->version == SOC7090) {
2320 dib7090_set_output_mode(demod, st->cfg.output_mode);
2321 dib7090_set_diversity_in(demod, 0);
2322 }
2323
1425 return demod; 2324 return demod;
1426 2325
1427error: 2326error:
@@ -1432,37 +2331,35 @@ EXPORT_SYMBOL(dib7000p_attach);
1432 2331
1433static struct dvb_frontend_ops dib7000p_ops = { 2332static struct dvb_frontend_ops dib7000p_ops = {
1434 .info = { 2333 .info = {
1435 .name = "DiBcom 7000PC", 2334 .name = "DiBcom 7000PC",
1436 .type = FE_OFDM, 2335 .type = FE_OFDM,
1437 .frequency_min = 44250000, 2336 .frequency_min = 44250000,
1438 .frequency_max = 867250000, 2337 .frequency_max = 867250000,
1439 .frequency_stepsize = 62500, 2338 .frequency_stepsize = 62500,
1440 .caps = FE_CAN_INVERSION_AUTO | 2339 .caps = FE_CAN_INVERSION_AUTO |
1441 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 2340 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
1442 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 2341 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
1443 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 2342 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
1444 FE_CAN_TRANSMISSION_MODE_AUTO | 2343 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
1445 FE_CAN_GUARD_INTERVAL_AUTO | 2344 },
1446 FE_CAN_RECOVER | 2345
1447 FE_CAN_HIERARCHY_AUTO, 2346 .release = dib7000p_release,
1448 }, 2347
1449 2348 .init = dib7000p_wakeup,
1450 .release = dib7000p_release, 2349 .sleep = dib7000p_sleep,
1451 2350
1452 .init = dib7000p_wakeup, 2351 .set_frontend = dib7000p_set_frontend,
1453 .sleep = dib7000p_sleep, 2352 .get_tune_settings = dib7000p_fe_get_tune_settings,
1454 2353 .get_frontend = dib7000p_get_frontend,
1455 .set_frontend = dib7000p_set_frontend, 2354
1456 .get_tune_settings = dib7000p_fe_get_tune_settings, 2355 .read_status = dib7000p_read_status,
1457 .get_frontend = dib7000p_get_frontend, 2356 .read_ber = dib7000p_read_ber,
1458
1459 .read_status = dib7000p_read_status,
1460 .read_ber = dib7000p_read_ber,
1461 .read_signal_strength = dib7000p_read_signal_strength, 2357 .read_signal_strength = dib7000p_read_signal_strength,
1462 .read_snr = dib7000p_read_snr, 2358 .read_snr = dib7000p_read_snr,
1463 .read_ucblocks = dib7000p_read_unc_blocks, 2359 .read_ucblocks = dib7000p_read_unc_blocks,
1464}; 2360};
1465 2361
2362MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
1466MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>"); 2363MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
1467MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator"); 2364MODULE_DESCRIPTION("Driver for the DiBcom 7000PC COFDM demodulator");
1468MODULE_LICENSE("GPL"); 2365MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib7000p.h b/drivers/media/dvb/frontends/dib7000p.h
index da17345bf5bd..0179f9474bac 100644
--- a/drivers/media/dvb/frontends/dib7000p.h
+++ b/drivers/media/dvb/frontends/dib7000p.h
@@ -33,59 +33,54 @@ struct dib7000p_config {
33 int (*agc_control) (struct dvb_frontend *, u8 before); 33 int (*agc_control) (struct dvb_frontend *, u8 before);
34 34
35 u8 output_mode; 35 u8 output_mode;
36 u8 disable_sample_and_hold : 1; 36 u8 disable_sample_and_hold:1;
37 37
38 u8 enable_current_mirror : 1; 38 u8 enable_current_mirror:1;
39 u8 diversity_delay; 39 u16 diversity_delay;
40 40
41 u8 default_i2c_addr;
42 u8 enMpegOutput:1;
41}; 43};
42 44
43#define DEFAULT_DIB7000P_I2C_ADDRESS 18 45#define DEFAULT_DIB7000P_I2C_ADDRESS 18
44 46
45#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \ 47#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && \
46 defined(MODULE)) 48 defined(MODULE))
47extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, 49extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
48 u8 i2c_addr, 50extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
49 struct dib7000p_config *cfg); 51extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
50extern struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *,
51 enum dibx000_i2c_interface,
52 int);
53extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c,
54 int no_of_demods, u8 default_addr,
55 struct dib7000p_config cfg[]);
56extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val); 52extern int dib7000p_set_gpio(struct dvb_frontend *, u8 num, u8 dir, u8 val);
57extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value); 53extern int dib7000p_set_wbd_ref(struct dvb_frontend *, u16 value);
58extern int dib7000pc_detection(struct i2c_adapter *i2c_adap); 54extern int dib7000pc_detection(struct i2c_adapter *i2c_adap);
59extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff); 55extern int dib7000p_pid_filter(struct dvb_frontend *, u8 id, u16 pid, u8 onoff);
60extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff); 56extern int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
57extern int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw);
58extern u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf);
59extern int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart);
60extern int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff);
61extern int dib7090_get_adc_power(struct dvb_frontend *fe);
62extern struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe);
63extern int dib7090_slave_reset(struct dvb_frontend *fe);
61#else 64#else
62static inline 65static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg)
63struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
64 struct dib7000p_config *cfg)
65{ 66{
66 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
67 return NULL; 68 return NULL;
68} 69}
69 70
70static inline 71static inline struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface i, int x)
71struct i2c_adapter *dib7000p_get_i2c_master(struct dvb_frontend *fe,
72 enum dibx000_i2c_interface i,
73 int x)
74{ 72{
75 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
76 return NULL; 74 return NULL;
77} 75}
78 76
79static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, 77static inline int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[])
80 int no_of_demods, u8 default_addr,
81 struct dib7000p_config cfg[])
82{ 78{
83 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 79 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
84 return -ENODEV; 80 return -ENODEV;
85} 81}
86 82
87static inline int dib7000p_set_gpio(struct dvb_frontend *fe, 83static inline int dib7000p_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
88 u8 num, u8 dir, u8 val)
89{ 84{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 85 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return -ENODEV; 86 return -ENODEV;
@@ -102,16 +97,59 @@ static inline int dib7000pc_detection(struct i2c_adapter *i2c_adap)
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 97 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return -ENODEV; 98 return -ENODEV;
104} 99}
100
105static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 101static inline int dib7000p_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
106{ 102{
107 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 103 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
108 return -ENODEV; 104 return -ENODEV;
109} 105}
110 106
111static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff) 107static inline int dib7000p_pid_filter_ctrl(struct dvb_frontend *fe, uint8_t onoff)
112{ 108{
113 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 109 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
114 return -ENODEV; 110 return -ENODEV;
111}
112
113static inline int dib7000p_update_pll(struct dvb_frontend *fe, struct dibx000_bandwidth_config *bw)
114{
115 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
116 return -ENODEV;
117}
118
119static inline u32 dib7000p_ctrl_timf(struct dvb_frontend *fe, u8 op, u32 timf)
120{
121 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
122 return 0;
123}
124
125static inline int dib7090_agc_restart(struct dvb_frontend *fe, u8 restart)
126{
127 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
128 return -ENODEV;
129}
130
131static inline int dib7090_tuner_sleep(struct dvb_frontend *fe, int onoff)
132{
133 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
134 return -ENODEV;
135}
136
137static inline int dib7090_get_adc_power(struct dvb_frontend *fe)
138{
139 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
140 return -ENODEV;
141}
142
143static inline struct i2c_adapter *dib7090_get_i2c_tuner(struct dvb_frontend *fe)
144{
145 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
146 return NULL;
147}
148
149static inline int dib7090_slave_reset(struct dvb_frontend *fe)
150{
151 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
152 return -ENODEV;
115} 153}
116#endif 154#endif
117 155
diff --git a/drivers/media/dvb/frontends/dib8000.c b/drivers/media/dvb/frontends/dib8000.c
index df17b91b3250..c1c3e26906e2 100644
--- a/drivers/media/dvb/frontends/dib8000.c
+++ b/drivers/media/dvb/frontends/dib8000.c
@@ -22,6 +22,7 @@
22#define LAYER_C 3 22#define LAYER_C 3
23 23
24#define FE_CALLBACK_TIME_NEVER 0xffffffff 24#define FE_CALLBACK_TIME_NEVER 0xffffffff
25#define MAX_NUMBER_OF_FRONTENDS 6
25 26
26static int debug; 27static int debug;
27module_param(debug, int, 0644); 28module_param(debug, int, 0644);
@@ -37,7 +38,6 @@ struct i2c_device {
37}; 38};
38 39
39struct dib8000_state { 40struct dib8000_state {
40 struct dvb_frontend fe;
41 struct dib8000_config cfg; 41 struct dib8000_config cfg;
42 42
43 struct i2c_device i2c; 43 struct i2c_device i2c;
@@ -68,6 +68,8 @@ struct dib8000_state {
68 u8 isdbt_cfg_loaded; 68 u8 isdbt_cfg_loaded;
69 enum frontend_tune_state tune_state; 69 enum frontend_tune_state tune_state;
70 u32 status; 70 u32 status;
71
72 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
71}; 73};
72 74
73enum dib8000_power_mode { 75enum dib8000_power_mode {
@@ -122,111 +124,111 @@ static int dib8000_write_word(struct dib8000_state *state, u16 reg, u16 val)
122 return dib8000_i2c_write16(&state->i2c, reg, val); 124 return dib8000_i2c_write16(&state->i2c, reg, val);
123} 125}
124 126
125static const int16_t coeff_2k_sb_1seg_dqpsk[8] = { 127static const s16 coeff_2k_sb_1seg_dqpsk[8] = {
126 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c, 128 (769 << 5) | 0x0a, (745 << 5) | 0x03, (595 << 5) | 0x0d, (769 << 5) | 0x0a, (920 << 5) | 0x09, (784 << 5) | 0x02, (519 << 5) | 0x0c,
127 (920 << 5) | 0x09 129 (920 << 5) | 0x09
128}; 130};
129 131
130static const int16_t coeff_2k_sb_1seg[8] = { 132static const s16 coeff_2k_sb_1seg[8] = {
131 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f 133 (692 << 5) | 0x0b, (683 << 5) | 0x01, (519 << 5) | 0x09, (692 << 5) | 0x0b, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f, 0 | 0x1f
132}; 134};
133 135
134static const int16_t coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = { 136static const s16 coeff_2k_sb_3seg_0dqpsk_1dqpsk[8] = {
135 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11, 137 (832 << 5) | 0x10, (912 << 5) | 0x05, (900 << 5) | 0x12, (832 << 5) | 0x10, (-931 << 5) | 0x0f, (912 << 5) | 0x04, (807 << 5) | 0x11,
136 (-931 << 5) | 0x0f 138 (-931 << 5) | 0x0f
137}; 139};
138 140
139static const int16_t coeff_2k_sb_3seg_0dqpsk[8] = { 141static const s16 coeff_2k_sb_3seg_0dqpsk[8] = {
140 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e, 142 (622 << 5) | 0x0c, (941 << 5) | 0x04, (796 << 5) | 0x10, (622 << 5) | 0x0c, (982 << 5) | 0x0c, (519 << 5) | 0x02, (572 << 5) | 0x0e,
141 (982 << 5) | 0x0c 143 (982 << 5) | 0x0c
142}; 144};
143 145
144static const int16_t coeff_2k_sb_3seg_1dqpsk[8] = { 146static const s16 coeff_2k_sb_3seg_1dqpsk[8] = {
145 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12, 147 (699 << 5) | 0x14, (607 << 5) | 0x04, (944 << 5) | 0x13, (699 << 5) | 0x14, (-720 << 5) | 0x0d, (640 << 5) | 0x03, (866 << 5) | 0x12,
146 (-720 << 5) | 0x0d 148 (-720 << 5) | 0x0d
147}; 149};
148 150
149static const int16_t coeff_2k_sb_3seg[8] = { 151static const s16 coeff_2k_sb_3seg[8] = {
150 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e, 152 (664 << 5) | 0x0c, (925 << 5) | 0x03, (937 << 5) | 0x10, (664 << 5) | 0x0c, (-610 << 5) | 0x0a, (697 << 5) | 0x01, (836 << 5) | 0x0e,
151 (-610 << 5) | 0x0a 153 (-610 << 5) | 0x0a
152}; 154};
153 155
154static const int16_t coeff_4k_sb_1seg_dqpsk[8] = { 156static const s16 coeff_4k_sb_1seg_dqpsk[8] = {
155 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f, 157 (-955 << 5) | 0x0e, (687 << 5) | 0x04, (818 << 5) | 0x10, (-955 << 5) | 0x0e, (-922 << 5) | 0x0d, (750 << 5) | 0x03, (665 << 5) | 0x0f,
156 (-922 << 5) | 0x0d 158 (-922 << 5) | 0x0d
157}; 159};
158 160
159static const int16_t coeff_4k_sb_1seg[8] = { 161static const s16 coeff_4k_sb_1seg[8] = {
160 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d, 162 (638 << 5) | 0x0d, (683 << 5) | 0x02, (638 << 5) | 0x0d, (638 << 5) | 0x0d, (-655 << 5) | 0x0a, (517 << 5) | 0x00, (698 << 5) | 0x0d,
161 (-655 << 5) | 0x0a 163 (-655 << 5) | 0x0a
162}; 164};
163 165
164static const int16_t coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = { 166static const s16 coeff_4k_sb_3seg_0dqpsk_1dqpsk[8] = {
165 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14, 167 (-707 << 5) | 0x14, (910 << 5) | 0x06, (889 << 5) | 0x16, (-707 << 5) | 0x14, (-958 << 5) | 0x13, (993 << 5) | 0x05, (523 << 5) | 0x14,
166 (-958 << 5) | 0x13 168 (-958 << 5) | 0x13
167}; 169};
168 170
169static const int16_t coeff_4k_sb_3seg_0dqpsk[8] = { 171static const s16 coeff_4k_sb_3seg_0dqpsk[8] = {
170 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12, 172 (-723 << 5) | 0x13, (910 << 5) | 0x05, (777 << 5) | 0x14, (-723 << 5) | 0x13, (-568 << 5) | 0x0f, (547 << 5) | 0x03, (696 << 5) | 0x12,
171 (-568 << 5) | 0x0f 173 (-568 << 5) | 0x0f
172}; 174};
173 175
174static const int16_t coeff_4k_sb_3seg_1dqpsk[8] = { 176static const s16 coeff_4k_sb_3seg_1dqpsk[8] = {
175 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14, 177 (-940 << 5) | 0x15, (607 << 5) | 0x05, (915 << 5) | 0x16, (-940 << 5) | 0x15, (-848 << 5) | 0x13, (683 << 5) | 0x04, (543 << 5) | 0x14,
176 (-848 << 5) | 0x13 178 (-848 << 5) | 0x13
177}; 179};
178 180
179static const int16_t coeff_4k_sb_3seg[8] = { 181static const s16 coeff_4k_sb_3seg[8] = {
180 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12, 182 (612 << 5) | 0x12, (910 << 5) | 0x04, (864 << 5) | 0x14, (612 << 5) | 0x12, (-869 << 5) | 0x13, (683 << 5) | 0x02, (869 << 5) | 0x12,
181 (-869 << 5) | 0x13 183 (-869 << 5) | 0x13
182}; 184};
183 185
184static const int16_t coeff_8k_sb_1seg_dqpsk[8] = { 186static const s16 coeff_8k_sb_1seg_dqpsk[8] = {
185 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13, 187 (-835 << 5) | 0x12, (684 << 5) | 0x05, (735 << 5) | 0x14, (-835 << 5) | 0x12, (-598 << 5) | 0x10, (781 << 5) | 0x04, (739 << 5) | 0x13,
186 (-598 << 5) | 0x10 188 (-598 << 5) | 0x10
187}; 189};
188 190
189static const int16_t coeff_8k_sb_1seg[8] = { 191static const s16 coeff_8k_sb_1seg[8] = {
190 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f, 192 (673 << 5) | 0x0f, (683 << 5) | 0x03, (808 << 5) | 0x12, (673 << 5) | 0x0f, (585 << 5) | 0x0f, (512 << 5) | 0x01, (780 << 5) | 0x0f,
191 (585 << 5) | 0x0f 193 (585 << 5) | 0x0f
192}; 194};
193 195
194static const int16_t coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = { 196static const s16 coeff_8k_sb_3seg_0dqpsk_1dqpsk[8] = {
195 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18, 197 (863 << 5) | 0x17, (930 << 5) | 0x07, (878 << 5) | 0x19, (863 << 5) | 0x17, (0 << 5) | 0x14, (521 << 5) | 0x05, (980 << 5) | 0x18,
196 (0 << 5) | 0x14 198 (0 << 5) | 0x14
197}; 199};
198 200
199static const int16_t coeff_8k_sb_3seg_0dqpsk[8] = { 201static const s16 coeff_8k_sb_3seg_0dqpsk[8] = {
200 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15, 202 (-924 << 5) | 0x17, (910 << 5) | 0x06, (774 << 5) | 0x17, (-924 << 5) | 0x17, (-877 << 5) | 0x15, (565 << 5) | 0x04, (553 << 5) | 0x15,
201 (-877 << 5) | 0x15 203 (-877 << 5) | 0x15
202}; 204};
203 205
204static const int16_t coeff_8k_sb_3seg_1dqpsk[8] = { 206static const s16 coeff_8k_sb_3seg_1dqpsk[8] = {
205 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18, 207 (-921 << 5) | 0x19, (607 << 5) | 0x06, (881 << 5) | 0x19, (-921 << 5) | 0x19, (-921 << 5) | 0x14, (713 << 5) | 0x05, (1018 << 5) | 0x18,
206 (-921 << 5) | 0x14 208 (-921 << 5) | 0x14
207}; 209};
208 210
209static const int16_t coeff_8k_sb_3seg[8] = { 211static const s16 coeff_8k_sb_3seg[8] = {
210 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15, 212 (514 << 5) | 0x14, (910 << 5) | 0x05, (861 << 5) | 0x17, (514 << 5) | 0x14, (690 << 5) | 0x14, (683 << 5) | 0x03, (662 << 5) | 0x15,
211 (690 << 5) | 0x14 213 (690 << 5) | 0x14
212}; 214};
213 215
214static const int16_t ana_fe_coeff_3seg[24] = { 216static const s16 ana_fe_coeff_3seg[24] = {
215 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017 217 81, 80, 78, 74, 68, 61, 54, 45, 37, 28, 19, 11, 4, 1022, 1017, 1013, 1010, 1008, 1008, 1008, 1008, 1010, 1014, 1017
216}; 218};
217 219
218static const int16_t ana_fe_coeff_1seg[24] = { 220static const s16 ana_fe_coeff_1seg[24] = {
219 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003 221 249, 226, 164, 82, 5, 981, 970, 988, 1018, 20, 31, 26, 8, 1012, 1000, 1018, 1012, 8, 15, 14, 9, 3, 1017, 1003
220}; 222};
221 223
222static const int16_t ana_fe_coeff_13seg[24] = { 224static const s16 ana_fe_coeff_13seg[24] = {
223 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1 225 396, 305, 105, -51, -77, -12, 41, 31, -11, -30, -11, 14, 15, -2, -13, -7, 5, 8, 1, -6, -7, -3, 0, 1
224}; 226};
225 227
226static u16 fft_to_mode(struct dib8000_state *state) 228static u16 fft_to_mode(struct dib8000_state *state)
227{ 229{
228 u16 mode; 230 u16 mode;
229 switch (state->fe.dtv_property_cache.transmission_mode) { 231 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
230 case TRANSMISSION_MODE_2K: 232 case TRANSMISSION_MODE_2K:
231 mode = 1; 233 mode = 1;
232 break; 234 break;
@@ -249,16 +251,18 @@ static void dib8000_set_acquisition_mode(struct dib8000_state *state)
249 dprintk("acquisition mode activated"); 251 dprintk("acquisition mode activated");
250 dib8000_write_word(state, 298, nud); 252 dib8000_write_word(state, 298, nud);
251} 253}
252 254static int dib8000_set_output_mode(struct dvb_frontend *fe, int mode)
253static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
254{ 255{
256 struct dib8000_state *state = fe->demodulator_priv;
257
255 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */ 258 u16 outreg, fifo_threshold, smo_mode, sram = 0x0205; /* by default SDRAM deintlv is enabled */
256 259
257 outreg = 0; 260 outreg = 0;
258 fifo_threshold = 1792; 261 fifo_threshold = 1792;
259 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1); 262 smo_mode = (dib8000_read_word(state, 299) & 0x0050) | (1 << 1);
260 263
261 dprintk("-I- Setting output mode for demod %p to %d", &state->fe, mode); 264 dprintk("-I- Setting output mode for demod %p to %d",
265 &state->fe[0], mode);
262 266
263 switch (mode) { 267 switch (mode) {
264 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock 268 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
@@ -292,7 +296,8 @@ static int dib8000_set_output_mode(struct dib8000_state *state, int mode)
292 break; 296 break;
293 297
294 default: 298 default:
295 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe); 299 dprintk("Unhandled output_mode passed to be set for demod %p",
300 &state->fe[0]);
296 return -EINVAL; 301 return -EINVAL;
297 } 302 }
298 303
@@ -342,7 +347,8 @@ static void dib8000_set_power_mode(struct dib8000_state *state, enum dib8000_pow
342{ 347{
343 /* by default everything is going to be powered off */ 348 /* by default everything is going to be powered off */
344 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff, 349 u16 reg_774 = 0x3fff, reg_775 = 0xffff, reg_776 = 0xffff,
345 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3, reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00; 350 reg_900 = (dib8000_read_word(state, 900) & 0xfffc) | 0x3,
351 reg_1280 = (dib8000_read_word(state, 1280) & 0x00ff) | 0xff00;
346 352
347 /* now, depending on the requested mode, we power on */ 353 /* now, depending on the requested mode, we power on */
348 switch (mode) { 354 switch (mode) {
@@ -411,8 +417,9 @@ static int dib8000_set_adc_state(struct dib8000_state *state, enum dibx000_adc_s
411 return ret; 417 return ret;
412} 418}
413 419
414static int dib8000_set_bandwidth(struct dib8000_state *state, u32 bw) 420static int dib8000_set_bandwidth(struct dvb_frontend *fe, u32 bw)
415{ 421{
422 struct dib8000_state *state = fe->demodulator_priv;
416 u32 timf; 423 u32 timf;
417 424
418 if (bw == 0) 425 if (bw == 0)
@@ -478,7 +485,8 @@ static void dib8000_reset_pll(struct dib8000_state *state)
478 485
479 // clk_cfg1 486 // clk_cfg1
480 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) | 487 clk_cfg1 = (1 << 10) | (0 << 9) | (pll->IO_CLK_en_core << 8) |
481 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) | (pll->pll_range << 1) | (pll->pll_reset << 0); 488 (pll->bypclk_div << 5) | (pll->enable_refdiv << 4) | (1 << 3) |
489 (pll->pll_range << 1) | (pll->pll_reset << 0);
482 490
483 dib8000_write_word(state, 902, clk_cfg1); 491 dib8000_write_word(state, 902, clk_cfg1);
484 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3); 492 clk_cfg1 = (clk_cfg1 & 0xfff7) | (pll->pll_bypass << 3);
@@ -488,11 +496,12 @@ static void dib8000_reset_pll(struct dib8000_state *state)
488 496
489 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */ 497 /* smpl_cfg: P_refclksel=2, P_ensmplsel=1 nodivsmpl=1 */
490 if (state->cfg.pll->ADClkSrc == 0) 498 if (state->cfg.pll->ADClkSrc == 0)
491 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 499 dib8000_write_word(state, 904, (0 << 15) | (0 << 12) | (0 << 10) |
500 (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
492 else if (state->cfg.refclksel != 0) 501 else if (state->cfg.refclksel != 0)
493 dib8000_write_word(state, 904, 502 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) |
494 (0 << 15) | (1 << 12) | ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) | (pll-> 503 ((state->cfg.refclksel & 0x3) << 10) | (pll->modulo << 8) |
495 ADClkSrc << 7) | (0 << 1)); 504 (pll->ADClkSrc << 7) | (0 << 1));
496 else 505 else
497 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1)); 506 dib8000_write_word(state, 904, (0 << 15) | (1 << 12) | (3 << 10) | (pll->modulo << 8) | (pll->ADClkSrc << 7) | (0 << 1));
498 507
@@ -560,7 +569,7 @@ static const u16 dib8000_defaults[] = {
560 0xd4c0, 569 0xd4c0,
561 570
562 /*1, 32, 571 /*1, 32,
563 0x6680 // P_corm_thres Lock algorithms configuration */ 572 0x6680 // P_corm_thres Lock algorithms configuration */
564 573
565 11, 80, /* set ADC level to -16 */ 574 11, 80, /* set ADC level to -16 */
566 (1 << 13) - 825 - 117, 575 (1 << 13) - 825 - 117,
@@ -623,14 +632,14 @@ static const u16 dib8000_defaults[] = {
623 1, 285, 632 1, 285,
624 0x0020, //p_fec_ 633 0x0020, //p_fec_
625 1, 299, 634 1, 299,
626 0x0062, // P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard 635 0x0062, /* P_smo_mode, P_smo_rs_discard, P_smo_fifo_flush, P_smo_pid_parse, P_smo_error_discard */
627 636
628 1, 338, 637 1, 338,
629 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1 638 (1 << 12) | // P_ctrl_corm_thres4pre_freq_inh=1
630 (1 << 10) | // P_ctrl_pre_freq_mode_sat=1 639 (1 << 10) |
631 (0 << 9) | // P_ctrl_pre_freq_inh=0 640 (0 << 9) | /* P_ctrl_pre_freq_inh=0 */
632 (3 << 5) | // P_ctrl_pre_freq_step=3 641 (3 << 5) | /* P_ctrl_pre_freq_step=3 */
633 (1 << 0), // P_pre_freq_win_len=1 642 (1 << 0), /* P_pre_freq_win_len=1 */
634 643
635 1, 903, 644 1, 903,
636 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW) 645 (0 << 4) | 2, // P_divclksel=0 P_divbitsel=2 (was clk=3,bit=1 for MPW)
@@ -717,7 +726,7 @@ static int dib8000_reset(struct dvb_frontend *fe)
717 if (dib8000_reset_gpio(state) != 0) 726 if (dib8000_reset_gpio(state) != 0)
718 dprintk("GPIO reset was not successful."); 727 dprintk("GPIO reset was not successful.");
719 728
720 if (dib8000_set_output_mode(state, OUTMODE_HIGH_Z) != 0) 729 if (dib8000_set_output_mode(fe, OUTMODE_HIGH_Z) != 0)
721 dprintk("OUTPUT_MODE could not be resetted."); 730 dprintk("OUTPUT_MODE could not be resetted.");
722 731
723 state->current_agc = NULL; 732 state->current_agc = NULL;
@@ -752,7 +761,7 @@ static int dib8000_reset(struct dvb_frontend *fe)
752 /* unforce divstr regardless whether i2c enumeration was done or not */ 761 /* unforce divstr regardless whether i2c enumeration was done or not */
753 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1)); 762 dib8000_write_word(state, 1285, dib8000_read_word(state, 1285) & ~(1 << 1));
754 763
755 dib8000_set_bandwidth(state, 6000); 764 dib8000_set_bandwidth(fe, 6000);
756 765
757 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON); 766 dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON);
758 dib8000_sad_calib(state); 767 dib8000_sad_calib(state);
@@ -778,7 +787,7 @@ static int dib8000_update_lna(struct dib8000_state *state)
778 // read dyn_gain here (because it is demod-dependent and not tuner) 787 // read dyn_gain here (because it is demod-dependent and not tuner)
779 dyn_gain = dib8000_read_word(state, 390); 788 dyn_gain = dib8000_read_word(state, 390);
780 789
781 if (state->cfg.update_lna(&state->fe, dyn_gain)) { // LNA has changed 790 if (state->cfg.update_lna(state->fe[0], dyn_gain)) {
782 dib8000_restart_agc(state); 791 dib8000_restart_agc(state);
783 return 1; 792 return 1;
784 } 793 }
@@ -865,7 +874,8 @@ static int dib8000_agc_soft_split(struct dib8000_state *state)
865 split_offset = state->current_agc->split.max; 874 split_offset = state->current_agc->split.max;
866 else 875 else
867 split_offset = state->current_agc->split.max * 876 split_offset = state->current_agc->split.max *
868 (agc - state->current_agc->split.min_thres) / (state->current_agc->split.max_thres - state->current_agc->split.min_thres); 877 (agc - state->current_agc->split.min_thres) /
878 (state->current_agc->split.max_thres - state->current_agc->split.min_thres);
869 879
870 dprintk("AGC split_offset: %d", split_offset); 880 dprintk("AGC split_offset: %d", split_offset);
871 881
@@ -900,7 +910,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
900 case CT_AGC_STEP_0: 910 case CT_AGC_STEP_0:
901 //AGC initialization 911 //AGC initialization
902 if (state->cfg.agc_control) 912 if (state->cfg.agc_control)
903 state->cfg.agc_control(&state->fe, 1); 913 state->cfg.agc_control(fe, 1);
904 914
905 dib8000_restart_agc(state); 915 dib8000_restart_agc(state);
906 916
@@ -924,7 +934,7 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
924 dib8000_agc_soft_split(state); 934 dib8000_agc_soft_split(state);
925 935
926 if (state->cfg.agc_control) 936 if (state->cfg.agc_control)
927 state->cfg.agc_control(&state->fe, 0); 937 state->cfg.agc_control(fe, 0);
928 938
929 *tune_state = CT_AGC_STOP; 939 *tune_state = CT_AGC_STOP;
930 break; 940 break;
@@ -936,29 +946,28 @@ static int dib8000_agc_startup(struct dvb_frontend *fe)
936 946
937} 947}
938 948
939static const int32_t lut_1000ln_mant[] = 949static const s32 lut_1000ln_mant[] =
940{ 950{
941 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600 951 908, 7003, 7090, 7170, 7244, 7313, 7377, 7438, 7495, 7549, 7600
942}; 952};
943 953
944int32_t dib8000_get_adc_power(struct dvb_frontend *fe, uint8_t mode) 954s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
945{ 955{
946 struct dib8000_state *state = fe->demodulator_priv; 956 struct dib8000_state *state = fe->demodulator_priv;
947 uint32_t ix = 0, tmp_val = 0, exp = 0, mant = 0; 957 u32 ix = 0, tmp_val = 0, exp = 0, mant = 0;
948 int32_t val; 958 s32 val;
949 959
950 val = dib8000_read32(state, 384); 960 val = dib8000_read32(state, 384);
951 /* mode = 1 : ln_agcpower calc using mant-exp conversion and mantis look up table */ 961 if (mode) {
952 if (mode) { 962 tmp_val = val;
953 tmp_val = val; 963 while (tmp_val >>= 1)
954 while (tmp_val >>= 1) 964 exp++;
955 exp++; 965 mant = (val * 1000 / (1<<exp));
956 mant = (val * 1000 / (1<<exp)); 966 ix = (u8)((mant-1000)/100); /* index of the LUT */
957 ix = (uint8_t)((mant-1000)/100); /* index of the LUT */ 967 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908);
958 val = (lut_1000ln_mant[ix] + 693*(exp-20) - 6908); /* 1000 * ln(adcpower_real) ; 693 = 1000ln(2) ; 6908 = 1000*ln(1000) ; 20 comes from adc_real = adc_pow_int / 2**20 */ 968 val = (val*256)/1000;
959 val = (val*256)/1000; 969 }
960 } 970 return val;
961 return val;
962} 971}
963EXPORT_SYMBOL(dib8000_get_adc_power); 972EXPORT_SYMBOL(dib8000_get_adc_power);
964 973
@@ -1002,22 +1011,23 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1002 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60); 1011 dib8000_write_word(state, 285, dib8000_read_word(state, 285) & 0x60);
1003 1012
1004 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec 1013 i = dib8000_read_word(state, 26) & 1; // P_dds_invspec
1005 dib8000_write_word(state, 26, state->fe.dtv_property_cache.inversion ^ i); 1014 dib8000_write_word(state, 26, state->fe[0]->dtv_property_cache.inversion^i);
1006 1015
1007 if (state->fe.dtv_property_cache.isdbt_sb_mode) { 1016 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1008 //compute new dds_freq for the seg and adjust prbs 1017 //compute new dds_freq for the seg and adjust prbs
1009 int seg_offset = 1018 int seg_offset =
1010 state->fe.dtv_property_cache.isdbt_sb_segment_idx - (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) - 1019 state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx -
1011 (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2); 1020 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) -
1021 (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2);
1012 int clk = state->cfg.pll->internal; 1022 int clk = state->cfg.pll->internal;
1013 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26) 1023 u32 segtodds = ((u32) (430 << 23) / clk) << 3; // segtodds = SegBW / Fclk * pow(2,26)
1014 int dds_offset = seg_offset * segtodds; 1024 int dds_offset = seg_offset * segtodds;
1015 int new_dds, sub_channel; 1025 int new_dds, sub_channel;
1016 if ((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) // if even 1026 if ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1017 dds_offset -= (int)(segtodds / 2); 1027 dds_offset -= (int)(segtodds / 2);
1018 1028
1019 if (state->cfg.pll->ifreq == 0) { 1029 if (state->cfg.pll->ifreq == 0) {
1020 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) { 1030 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0) {
1021 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1); 1031 dib8000_write_word(state, 26, dib8000_read_word(state, 26) | 1);
1022 new_dds = dds_offset; 1032 new_dds = dds_offset;
1023 } else 1033 } else
@@ -1027,35 +1037,35 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1027 // - the segment of center frequency with an odd total number of segments 1037 // - the segment of center frequency with an odd total number of segments
1028 // - the segment to the left of center frequency with an even total number of segments 1038 // - the segment to the left of center frequency with an even total number of segments
1029 // - the segment to the right of center frequency with an even total number of segments 1039 // - the segment to the right of center frequency with an even total number of segments
1030 if ((state->fe.dtv_property_cache.delivery_system == SYS_ISDBT) && (state->fe.dtv_property_cache.isdbt_sb_mode == 1) 1040 if ((state->fe[0]->dtv_property_cache.delivery_system == SYS_ISDBT)
1031 && 1041 && (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1032 (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) 1042 && (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1033 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == 1043 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1034 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 1044 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1035 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1045 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1036 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == (state->fe.dtv_property_cache.isdbt_sb_segment_count / 2))) 1046 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx == (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2)))
1037 || (((state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) == 0) 1047 || (((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2) == 0)
1038 && (state->fe.dtv_property_cache.isdbt_sb_segment_idx == 1048 && (state->fe[0]->dtv_property_cache.isdbt_sb_segment_idx ==
1039 ((state->fe.dtv_property_cache.isdbt_sb_segment_count / 2) + 1))) 1049 ((state->fe[0]->dtv_property_cache.isdbt_sb_segment_count / 2) + 1)))
1040 )) { 1050 )) {
1041 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26) 1051 new_dds -= ((u32) (850 << 22) / clk) << 4; // new_dds = 850 (freq shift in KHz) / Fclk * pow(2,26)
1042 } 1052 }
1043 } else { 1053 } else {
1044 if ((state->fe.dtv_property_cache.inversion ^ i) == 0) 1054 if ((state->fe[0]->dtv_property_cache.inversion ^ i) == 0)
1045 new_dds = state->cfg.pll->ifreq - dds_offset; 1055 new_dds = state->cfg.pll->ifreq - dds_offset;
1046 else 1056 else
1047 new_dds = state->cfg.pll->ifreq + dds_offset; 1057 new_dds = state->cfg.pll->ifreq + dds_offset;
1048 } 1058 }
1049 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff)); 1059 dib8000_write_word(state, 27, (u16) ((new_dds >> 16) & 0x01ff));
1050 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff)); 1060 dib8000_write_word(state, 28, (u16) (new_dds & 0xffff));
1051 if (state->fe.dtv_property_cache.isdbt_sb_segment_count % 2) // if odd 1061 if (state->fe[0]->dtv_property_cache.isdbt_sb_segment_count % 2)
1052 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3; 1062 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset) + 1) % 41) / 3;
1053 else // if even 1063 else
1054 sub_channel = ((state->fe.dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3; 1064 sub_channel = ((state->fe[0]->dtv_property_cache.isdbt_sb_subchannel + (3 * seg_offset)) % 41) / 3;
1055 sub_channel -= 6; 1065 sub_channel -= 6;
1056 1066
1057 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K 1067 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K
1058 || state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) { 1068 || state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_4K) {
1059 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1 1069 dib8000_write_word(state, 219, dib8000_read_word(state, 219) | 0x1); //adp_pass =1
1060 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1 1070 dib8000_write_word(state, 190, dib8000_read_word(state, 190) | (0x1 << 14)); //pha3_force_pha_shift = 1
1061 } else { 1071 } else {
@@ -1063,7 +1073,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1063 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0 1073 dib8000_write_word(state, 190, dib8000_read_word(state, 190) & 0xbfff); //pha3_force_pha_shift = 0
1064 } 1074 }
1065 1075
1066 switch (state->fe.dtv_property_cache.transmission_mode) { 1076 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1067 case TRANSMISSION_MODE_2K: 1077 case TRANSMISSION_MODE_2K:
1068 switch (sub_channel) { 1078 switch (sub_channel) {
1069 case -6: 1079 case -6:
@@ -1209,7 +1219,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1209 } 1219 }
1210 break; 1220 break;
1211 } 1221 }
1212 } else { // if not state->fe.dtv_property_cache.isdbt_sb_mode 1222 } else {
1213 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff)); 1223 dib8000_write_word(state, 27, (u16) ((state->cfg.pll->ifreq >> 16) & 0x01ff));
1214 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff)); 1224 dib8000_write_word(state, 28, (u16) (state->cfg.pll->ifreq & 0xffff));
1215 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003)); 1225 dib8000_write_word(state, 26, (u16) ((state->cfg.pll->ifreq >> 25) & 0x0003));
@@ -1218,7 +1228,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1218 dib8000_write_word(state, 10, (seq << 4)); 1228 dib8000_write_word(state, 10, (seq << 4));
1219 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000); 1229 // dib8000_write_word(state, 287, (dib8000_read_word(state, 287) & 0xe000) | 0x1000);
1220 1230
1221 switch (state->fe.dtv_property_cache.guard_interval) { 1231 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1222 case GUARD_INTERVAL_1_32: 1232 case GUARD_INTERVAL_1_32:
1223 guard = 0; 1233 guard = 0;
1224 break; 1234 break;
@@ -1238,7 +1248,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1238 1248
1239 max_constellation = DQPSK; 1249 max_constellation = DQPSK;
1240 for (i = 0; i < 3; i++) { 1250 for (i = 0; i < 3; i++) {
1241 switch (state->fe.dtv_property_cache.layer[i].modulation) { 1251 switch (state->fe[0]->dtv_property_cache.layer[i].modulation) {
1242 case DQPSK: 1252 case DQPSK:
1243 constellation = 0; 1253 constellation = 0;
1244 break; 1254 break;
@@ -1254,7 +1264,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1254 break; 1264 break;
1255 } 1265 }
1256 1266
1257 switch (state->fe.dtv_property_cache.layer[i].fec) { 1267 switch (state->fe[0]->dtv_property_cache.layer[i].fec) {
1258 case FEC_1_2: 1268 case FEC_1_2:
1259 crate = 1; 1269 crate = 1;
1260 break; 1270 break;
@@ -1273,26 +1283,26 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1273 break; 1283 break;
1274 } 1284 }
1275 1285
1276 if ((state->fe.dtv_property_cache.layer[i].interleaving > 0) && 1286 if ((state->fe[0]->dtv_property_cache.layer[i].interleaving > 0) &&
1277 ((state->fe.dtv_property_cache.layer[i].interleaving <= 3) || 1287 ((state->fe[0]->dtv_property_cache.layer[i].interleaving <= 3) ||
1278 (state->fe.dtv_property_cache.layer[i].interleaving == 4 && state->fe.dtv_property_cache.isdbt_sb_mode == 1)) 1288 (state->fe[0]->dtv_property_cache.layer[i].interleaving == 4 && state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1))
1279 ) 1289 )
1280 timeI = state->fe.dtv_property_cache.layer[i].interleaving; 1290 timeI = state->fe[0]->dtv_property_cache.layer[i].interleaving;
1281 else 1291 else
1282 timeI = 0; 1292 timeI = 0;
1283 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe.dtv_property_cache.layer[i].segment_count & 0xf) << 6) | 1293 dib8000_write_word(state, 2 + i, (constellation << 10) | ((state->fe[0]->dtv_property_cache.layer[i].segment_count & 0xf) << 6) |
1284 (crate << 3) | timeI); 1294 (crate << 3) | timeI);
1285 if (state->fe.dtv_property_cache.layer[i].segment_count > 0) { 1295 if (state->fe[0]->dtv_property_cache.layer[i].segment_count > 0) {
1286 switch (max_constellation) { 1296 switch (max_constellation) {
1287 case DQPSK: 1297 case DQPSK:
1288 case QPSK: 1298 case QPSK:
1289 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_16 || 1299 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_16 ||
1290 state->fe.dtv_property_cache.layer[i].modulation == QAM_64) 1300 state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1291 max_constellation = state->fe.dtv_property_cache.layer[i].modulation; 1301 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1292 break; 1302 break;
1293 case QAM_16: 1303 case QAM_16:
1294 if (state->fe.dtv_property_cache.layer[i].modulation == QAM_64) 1304 if (state->fe[0]->dtv_property_cache.layer[i].modulation == QAM_64)
1295 max_constellation = state->fe.dtv_property_cache.layer[i].modulation; 1305 max_constellation = state->fe[0]->dtv_property_cache.layer[i].modulation;
1296 break; 1306 break;
1297 } 1307 }
1298 } 1308 }
@@ -1303,34 +1313,34 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1303 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/ 1313 //dib8000_write_word(state, 5, 13); /*p_last_seg = 13*/
1304 1314
1305 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) | 1315 dib8000_write_word(state, 274, (dib8000_read_word(state, 274) & 0xffcf) |
1306 ((state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe.dtv_property_cache. 1316 ((state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 5) | ((state->fe[0]->dtv_property_cache.
1307 isdbt_sb_mode & 1) << 4)); 1317 isdbt_sb_mode & 1) << 4));
1308 1318
1309 dprintk("mode = %d ; guard = %d", mode, state->fe.dtv_property_cache.guard_interval); 1319 dprintk("mode = %d ; guard = %d", mode, state->fe[0]->dtv_property_cache.guard_interval);
1310 1320
1311 /* signal optimization parameter */ 1321 /* signal optimization parameter */
1312 1322
1313 if (state->fe.dtv_property_cache.isdbt_partial_reception) { 1323 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception) {
1314 seg_diff_mask = (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0]; 1324 seg_diff_mask = (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) << permu_seg[0];
1315 for (i = 1; i < 3; i++) 1325 for (i = 1; i < 3; i++)
1316 nbseg_diff += 1326 nbseg_diff +=
1317 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; 1327 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1318 for (i = 0; i < nbseg_diff; i++) 1328 for (i = 0; i < nbseg_diff; i++)
1319 seg_diff_mask |= 1 << permu_seg[i + 1]; 1329 seg_diff_mask |= 1 << permu_seg[i + 1];
1320 } else { 1330 } else {
1321 for (i = 0; i < 3; i++) 1331 for (i = 0; i < 3; i++)
1322 nbseg_diff += 1332 nbseg_diff +=
1323 (state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * state->fe.dtv_property_cache.layer[i].segment_count; 1333 (state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * state->fe[0]->dtv_property_cache.layer[i].segment_count;
1324 for (i = 0; i < nbseg_diff; i++) 1334 for (i = 0; i < nbseg_diff; i++)
1325 seg_diff_mask |= 1 << permu_seg[i]; 1335 seg_diff_mask |= 1 << permu_seg[i];
1326 } 1336 }
1327 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask); 1337 dprintk("nbseg_diff = %X (%d)", seg_diff_mask, seg_diff_mask);
1328 1338
1329 state->differential_constellation = (seg_diff_mask != 0); 1339 state->differential_constellation = (seg_diff_mask != 0);
1330 dib8000_set_diversity_in(&state->fe, state->diversity_onoff); 1340 dib8000_set_diversity_in(state->fe[0], state->diversity_onoff);
1331 1341
1332 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb 1342 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1333 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments 1343 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1334 seg_mask13 = 0x00E0; 1344 seg_mask13 = 0x00E0;
1335 else // 1-segment 1345 else // 1-segment
1336 seg_mask13 = 0x0040; 1346 seg_mask13 = 0x0040;
@@ -1340,7 +1350,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1340 // WRITE: Mode & Diff mask 1350 // WRITE: Mode & Diff mask
1341 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask); 1351 dib8000_write_word(state, 0, (mode << 13) | seg_diff_mask);
1342 1352
1343 if ((seg_diff_mask) || (state->fe.dtv_property_cache.isdbt_sb_mode)) 1353 if ((seg_diff_mask) || (state->fe[0]->dtv_property_cache.isdbt_sb_mode))
1344 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200); 1354 dib8000_write_word(state, 268, (dib8000_read_word(state, 268) & 0xF9FF) | 0x0200);
1345 else 1355 else
1346 dib8000_write_word(state, 268, (2 << 9) | 39); //init value 1356 dib8000_write_word(state, 268, (2 << 9) | 39); //init value
@@ -1351,26 +1361,25 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1351 1361
1352 dib8000_write_word(state, 353, seg_mask13); // ADDR 353 1362 dib8000_write_word(state, 353, seg_mask13); // ADDR 353
1353 1363
1354/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */ 1364/* // P_small_narrow_band=0, P_small_last_seg=13, P_small_offset_num_car=5 */
1355 // dib8000_write_word(state, 351, (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5 );
1356 1365
1357 // ---- SMALL ---- 1366 // ---- SMALL ----
1358 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1367 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1359 switch (state->fe.dtv_property_cache.transmission_mode) { 1368 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1360 case TRANSMISSION_MODE_2K: 1369 case TRANSMISSION_MODE_2K:
1361 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg 1370 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1362 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK 1371 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1363 ncoeff = coeff_2k_sb_1seg_dqpsk; 1372 ncoeff = coeff_2k_sb_1seg_dqpsk;
1364 else // QPSK or QAM 1373 else // QPSK or QAM
1365 ncoeff = coeff_2k_sb_1seg; 1374 ncoeff = coeff_2k_sb_1seg;
1366 } else { // 3-segments 1375 } else { // 3-segments
1367 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment 1376 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1368 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments 1377 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1369 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk; 1378 ncoeff = coeff_2k_sb_3seg_0dqpsk_1dqpsk;
1370 else // QPSK or QAM on external segments 1379 else // QPSK or QAM on external segments
1371 ncoeff = coeff_2k_sb_3seg_0dqpsk; 1380 ncoeff = coeff_2k_sb_3seg_0dqpsk;
1372 } else { // QPSK or QAM on central segment 1381 } else { // QPSK or QAM on central segment
1373 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) // DQPSK on external segments 1382 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK)
1374 ncoeff = coeff_2k_sb_3seg_1dqpsk; 1383 ncoeff = coeff_2k_sb_3seg_1dqpsk;
1375 else // QPSK or QAM on external segments 1384 else // QPSK or QAM on external segments
1376 ncoeff = coeff_2k_sb_3seg; 1385 ncoeff = coeff_2k_sb_3seg;
@@ -1379,20 +1388,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1379 break; 1388 break;
1380 1389
1381 case TRANSMISSION_MODE_4K: 1390 case TRANSMISSION_MODE_4K:
1382 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg 1391 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1383 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK 1392 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1384 ncoeff = coeff_4k_sb_1seg_dqpsk; 1393 ncoeff = coeff_4k_sb_1seg_dqpsk;
1385 else // QPSK or QAM 1394 else // QPSK or QAM
1386 ncoeff = coeff_4k_sb_1seg; 1395 ncoeff = coeff_4k_sb_1seg;
1387 } else { // 3-segments 1396 } else { // 3-segments
1388 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment 1397 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1389 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1398 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1390 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk; 1399 ncoeff = coeff_4k_sb_3seg_0dqpsk_1dqpsk;
1391 } else { // QPSK or QAM on external segments 1400 } else { // QPSK or QAM on external segments
1392 ncoeff = coeff_4k_sb_3seg_0dqpsk; 1401 ncoeff = coeff_4k_sb_3seg_0dqpsk;
1393 } 1402 }
1394 } else { // QPSK or QAM on central segment 1403 } else { // QPSK or QAM on central segment
1395 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1404 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1396 ncoeff = coeff_4k_sb_3seg_1dqpsk; 1405 ncoeff = coeff_4k_sb_3seg_1dqpsk;
1397 } else // QPSK or QAM on external segments 1406 } else // QPSK or QAM on external segments
1398 ncoeff = coeff_4k_sb_3seg; 1407 ncoeff = coeff_4k_sb_3seg;
@@ -1403,20 +1412,20 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1403 case TRANSMISSION_MODE_AUTO: 1412 case TRANSMISSION_MODE_AUTO:
1404 case TRANSMISSION_MODE_8K: 1413 case TRANSMISSION_MODE_8K:
1405 default: 1414 default:
1406 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // 1-seg 1415 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1407 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) // DQPSK 1416 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK)
1408 ncoeff = coeff_8k_sb_1seg_dqpsk; 1417 ncoeff = coeff_8k_sb_1seg_dqpsk;
1409 else // QPSK or QAM 1418 else // QPSK or QAM
1410 ncoeff = coeff_8k_sb_1seg; 1419 ncoeff = coeff_8k_sb_1seg;
1411 } else { // 3-segments 1420 } else { // 3-segments
1412 if (state->fe.dtv_property_cache.layer[0].modulation == DQPSK) { // DQPSK on central segment 1421 if (state->fe[0]->dtv_property_cache.layer[0].modulation == DQPSK) {
1413 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1422 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1414 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk; 1423 ncoeff = coeff_8k_sb_3seg_0dqpsk_1dqpsk;
1415 } else { // QPSK or QAM on external segments 1424 } else { // QPSK or QAM on external segments
1416 ncoeff = coeff_8k_sb_3seg_0dqpsk; 1425 ncoeff = coeff_8k_sb_3seg_0dqpsk;
1417 } 1426 }
1418 } else { // QPSK or QAM on central segment 1427 } else { // QPSK or QAM on central segment
1419 if (state->fe.dtv_property_cache.layer[1].modulation == DQPSK) { // DQPSK on external segments 1428 if (state->fe[0]->dtv_property_cache.layer[1].modulation == DQPSK) {
1420 ncoeff = coeff_8k_sb_3seg_1dqpsk; 1429 ncoeff = coeff_8k_sb_3seg_1dqpsk;
1421 } else // QPSK or QAM on external segments 1430 } else // QPSK or QAM on external segments
1422 ncoeff = coeff_8k_sb_3seg; 1431 ncoeff = coeff_8k_sb_3seg;
@@ -1430,22 +1439,22 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1430 1439
1431 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5 1440 // P_small_coef_ext_enable=ISDB-Tsb, P_small_narrow_band=ISDB-Tsb, P_small_last_seg=13, P_small_offset_num_car=5
1432 dib8000_write_word(state, 351, 1441 dib8000_write_word(state, 351,
1433 (state->fe.dtv_property_cache.isdbt_sb_mode << 9) | (state->fe.dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5); 1442 (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 9) | (state->fe[0]->dtv_property_cache.isdbt_sb_mode << 8) | (13 << 4) | 5);
1434 1443
1435 // ---- COFF ---- 1444 // ---- COFF ----
1436 // Carloff, the most robust 1445 // Carloff, the most robust
1437 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // Sound Broadcasting mode - use both TMCC and AC pilots 1446 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1438 1447
1439 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64 1448 // P_coff_cpil_alpha=4, P_coff_inh=0, P_coff_cpil_winlen=64
1440 // 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 1449 // 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
1441 dib8000_write_word(state, 187, 1450 dib8000_write_word(state, 187,
1442 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe.dtv_property_cache.isdbt_partial_reception & 1) << 2) 1451 (4 << 12) | (0 << 11) | (63 << 5) | (0x3 << 3) | ((~state->fe[0]->dtv_property_cache.isdbt_partial_reception & 1) << 2)
1443 | 0x3); 1452 | 0x3);
1444 1453
1445/* // P_small_coef_ext_enable = 1 */ 1454/* // P_small_coef_ext_enable = 1 */
1446/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */ 1455/* dib8000_write_word(state, 351, dib8000_read_word(state, 351) | 0x200); */
1447 1456
1448 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg 1457 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1449 1458
1450 // 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) 1459 // 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)
1451 if (mode == 3) 1460 if (mode == 3)
@@ -1469,10 +1478,10 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1469 dib8000_write_word(state, 186, 80); 1478 dib8000_write_word(state, 186, 80);
1470 } else { // Sound Broadcasting mode 3 seg 1479 } else { // Sound Broadcasting mode 3 seg
1471 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15 1480 // P_coff_one_seg_sym= 1, P_coff_one_seg_width= 1, P_coff_winlen=63, P_coff_thres_lock=15
1472 /* if (mode == 3) */ 1481 /* if (mode == 3) */
1473 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */ 1482 /* dib8000_write_word(state, 180, 0x2fca | ((0) << 14)); */
1474 /* else */ 1483 /* else */
1475 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */ 1484 /* dib8000_write_word(state, 180, 0x2fca | ((1) << 14)); */
1476 dib8000_write_word(state, 180, 0x1fcf | (1 << 14)); 1485 dib8000_write_word(state, 180, 0x1fcf | (1 << 14));
1477 1486
1478 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1, 1487 // P_ctrl_corm_thres4pre_freq_inh = 1, P_ctrl_pre_freq_mode_sat=1,
@@ -1509,7 +1518,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1509 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0)); 1518 dib8000_write_word(state, 341, (4 << 3) | (1 << 2) | (1 << 1) | (1 << 0));
1510 } 1519 }
1511 // ---- FFT ---- 1520 // ---- FFT ----
1512 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 && state->fe.dtv_property_cache.isdbt_partial_reception == 0) // 1-seg 1521 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 && state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1513 dib8000_write_word(state, 178, 64); // P_fft_powrange=64 1522 dib8000_write_word(state, 178, 64); // P_fft_powrange=64
1514 else 1523 else
1515 dib8000_write_word(state, 178, 32); // P_fft_powrange=32 1524 dib8000_write_word(state, 178, 32); // P_fft_powrange=32
@@ -1518,12 +1527,12 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1518 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed) 1527 * 6bits; p_coff_thres_lock 6bits (for coff lock if needed)
1519 */ 1528 */
1520 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13)) 1529 /* if ( ( nbseg_diff>0)&&(nbseg_diff<13))
1521 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */ 1530 dib8000_write_word(state, 187, (dib8000_read_word(state, 187) & 0xfffb) | (1 << 3)); */
1522 1531
1523 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */ 1532 dib8000_write_word(state, 189, ~seg_mask13 | seg_diff_mask); /* P_lmod4_seg_inh */
1524 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */ 1533 dib8000_write_word(state, 192, ~seg_mask13 | seg_diff_mask); /* P_pha3_seg_inh */
1525 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */ 1534 dib8000_write_word(state, 225, ~seg_mask13 | seg_diff_mask); /* P_tac_seg_inh */
1526 if ((!state->fe.dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0)) 1535 if ((!state->fe[0]->dtv_property_cache.isdbt_sb_mode) && (state->cfg.pll->ifreq == 0))
1527 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */ 1536 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask | 0x40); /* P_equal_noise_seg_inh */
1528 else 1537 else
1529 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */ 1538 dib8000_write_word(state, 266, ~seg_mask13 | seg_diff_mask); /* P_equal_noise_seg_inh */
@@ -1538,8 +1547,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1538 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */ 1547 dib8000_write_word(state, 211, seg_mask13 & (~seg_diff_mask)); /* P_des_seg_enabled */
1539 1548
1540 /* offset loop parameters */ 1549 /* offset loop parameters */
1541 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1550 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1542 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg 1551 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1543 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */ 1552 /* P_timf_alpha = (11-P_mode), P_corm_alpha=6, P_corm_thres=0x80 */
1544 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40); 1553 dib8000_write_word(state, 32, ((11 - mode) << 12) | (6 << 8) | 0x40);
1545 1554
@@ -1551,8 +1560,8 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1551 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */ 1560 /* P_timf_alpha = (9-P_mode, P_corm_alpha=6, P_corm_thres=0x80 */
1552 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80); 1561 dib8000_write_word(state, 32, ((9 - mode) << 12) | (6 << 8) | 0x80);
1553 1562
1554 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1563 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1555 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg 1564 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1556 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */ 1565 /* P_ctrl_pha_off_max=3 P_ctrl_sfreq_inh =0 P_ctrl_sfreq_step = (11-P_mode) */
1557 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode)); 1566 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (10 - mode));
1558 1567
@@ -1564,7 +1573,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1564 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode)); 1573 dib8000_write_word(state, 37, (3 << 5) | (0 << 4) | (8 - mode));
1565 1574
1566 /* P_dvsy_sync_wait - reuse mode */ 1575 /* P_dvsy_sync_wait - reuse mode */
1567 switch (state->fe.dtv_property_cache.transmission_mode) { 1576 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1568 case TRANSMISSION_MODE_8K: 1577 case TRANSMISSION_MODE_8K:
1569 mode = 256; 1578 mode = 256;
1570 break; 1579 break;
@@ -1624,15 +1633,15 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1624 } 1633 }
1625 1634
1626 // ---- ANA_FE ---- 1635 // ---- ANA_FE ----
1627 if (state->fe.dtv_property_cache.isdbt_sb_mode) { 1636 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1628 if (state->fe.dtv_property_cache.isdbt_partial_reception == 1) // 3-segments 1637 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 1)
1629 ana_fe = ana_fe_coeff_3seg; 1638 ana_fe = ana_fe_coeff_3seg;
1630 else // 1-segment 1639 else // 1-segment
1631 ana_fe = ana_fe_coeff_1seg; 1640 ana_fe = ana_fe_coeff_1seg;
1632 } else 1641 } else
1633 ana_fe = ana_fe_coeff_13seg; 1642 ana_fe = ana_fe_coeff_13seg;
1634 1643
1635 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0) 1644 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1 || state->isdbt_cfg_loaded == 0)
1636 for (mode = 0; mode < 24; mode++) 1645 for (mode = 0; mode < 24; mode++)
1637 dib8000_write_word(state, 117 + mode, ana_fe[mode]); 1646 dib8000_write_word(state, 117 + mode, ana_fe[mode]);
1638 1647
@@ -1648,11 +1657,11 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1648 // "P_cspu_left_edge" not used => do not care 1657 // "P_cspu_left_edge" not used => do not care
1649 // "P_cspu_right_edge" not used => do not care 1658 // "P_cspu_right_edge" not used => do not care
1650 1659
1651 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { // ISDB-Tsb 1660 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1652 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1 1661 dib8000_write_word(state, 228, 1); // P_2d_mode_byp=1
1653 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0 1662 dib8000_write_word(state, 205, dib8000_read_word(state, 205) & 0xfff0); // P_cspu_win_cut = 0
1654 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0 // 1-segment 1663 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0
1655 && state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) { 1664 && state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_2K) {
1656 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0 1665 //dib8000_write_word(state, 219, dib8000_read_word(state, 219) & 0xfffe); // P_adp_pass = 0
1657 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15 1666 dib8000_write_word(state, 265, 15); // P_equal_noise_sel = 15
1658 } 1667 }
@@ -1664,7 +1673,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1664 // ---- TMCC ---- 1673 // ---- TMCC ----
1665 for (i = 0; i < 3; i++) 1674 for (i = 0; i < 3; i++)
1666 tmcc_pow += 1675 tmcc_pow +=
1667 (((state->fe.dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe.dtv_property_cache.layer[i].segment_count); 1676 (((state->fe[0]->dtv_property_cache.layer[i].modulation == DQPSK) * 4 + 1) * state->fe[0]->dtv_property_cache.layer[i].segment_count);
1668 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9); 1677 // Quantif of "P_tmcc_dec_thres_?k" is (0, 5+mode, 9);
1669 // Threshold is set at 1/4 of max power. 1678 // Threshold is set at 1/4 of max power.
1670 tmcc_pow *= (1 << (9 - 2)); 1679 tmcc_pow *= (1 << (9 - 2));
@@ -1678,7 +1687,7 @@ static void dib8000_set_channel(struct dib8000_state *state, u8 seq, u8 autosear
1678 if (state->isdbt_cfg_loaded == 0) 1687 if (state->isdbt_cfg_loaded == 0)
1679 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */ 1688 dib8000_write_word(state, 250, 3285); /*p_2d_hspeed_thr0 */
1680 1689
1681 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) 1690 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1)
1682 state->isdbt_cfg_loaded = 0; 1691 state->isdbt_cfg_loaded = 0;
1683 else 1692 else
1684 state->isdbt_cfg_loaded = 1; 1693 state->isdbt_cfg_loaded = 1;
@@ -1693,38 +1702,38 @@ static int dib8000_autosearch_start(struct dvb_frontend *fe)
1693 1702
1694 int slist = 0; 1703 int slist = 0;
1695 1704
1696 state->fe.dtv_property_cache.inversion = 0; 1705 state->fe[0]->dtv_property_cache.inversion = 0;
1697 if (!state->fe.dtv_property_cache.isdbt_sb_mode) 1706 if (!state->fe[0]->dtv_property_cache.isdbt_sb_mode)
1698 state->fe.dtv_property_cache.layer[0].segment_count = 13; 1707 state->fe[0]->dtv_property_cache.layer[0].segment_count = 13;
1699 state->fe.dtv_property_cache.layer[0].modulation = QAM_64; 1708 state->fe[0]->dtv_property_cache.layer[0].modulation = QAM_64;
1700 state->fe.dtv_property_cache.layer[0].fec = FEC_2_3; 1709 state->fe[0]->dtv_property_cache.layer[0].fec = FEC_2_3;
1701 state->fe.dtv_property_cache.layer[0].interleaving = 0; 1710 state->fe[0]->dtv_property_cache.layer[0].interleaving = 0;
1702 1711
1703 //choose the right list, in sb, always do everything 1712 //choose the right list, in sb, always do everything
1704 if (state->fe.dtv_property_cache.isdbt_sb_mode) { 1713 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode) {
1705 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; 1714 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1706 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; 1715 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1707 slist = 7; 1716 slist = 7;
1708 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); 1717 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13));
1709 } else { 1718 } else {
1710 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) { 1719 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) {
1711 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { 1720 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1712 slist = 7; 1721 slist = 7;
1713 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2 1722 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 to have autosearch start ok with mode2
1714 } else 1723 } else
1715 slist = 3; 1724 slist = 3;
1716 } else { 1725 } else {
1717 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) { 1726 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) {
1718 slist = 2; 1727 slist = 2;
1719 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1 1728 dib8000_write_word(state, 0, (dib8000_read_word(state, 0) & 0x9fff) | (1 << 13)); // P_mode = 1
1720 } else 1729 } else
1721 slist = 0; 1730 slist = 0;
1722 } 1731 }
1723 1732
1724 if (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) 1733 if (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO)
1725 state->fe.dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K; 1734 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1726 if (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) 1735 if (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO)
1727 state->fe.dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8; 1736 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1728 1737
1729 dprintk("using list for autosearch : %d", slist); 1738 dprintk("using list for autosearch : %d", slist);
1730 dib8000_set_channel(state, (unsigned char)slist, 1); 1739 dib8000_set_channel(state, (unsigned char)slist, 1);
@@ -1786,7 +1795,7 @@ static int dib8000_tune(struct dvb_frontend *fe)
1786 if (state == NULL) 1795 if (state == NULL)
1787 return -EINVAL; 1796 return -EINVAL;
1788 1797
1789 dib8000_set_bandwidth(state, state->fe.dtv_property_cache.bandwidth_hz / 1000); 1798 dib8000_set_bandwidth(fe, state->fe[0]->dtv_property_cache.bandwidth_hz / 1000);
1790 dib8000_set_channel(state, 0, 0); 1799 dib8000_set_channel(state, 0, 0);
1791 1800
1792 // restart demod 1801 // restart demod
@@ -1799,17 +1808,16 @@ static int dib8000_tune(struct dvb_frontend *fe)
1799 1808
1800 // never achieved a lock before - wait for timfreq to update 1809 // never achieved a lock before - wait for timfreq to update
1801 if (state->timf == 0) { 1810 if (state->timf == 0) {
1802 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1811 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1803 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) // Sound Broadcasting mode 1 seg 1812 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0)
1804 msleep(300); 1813 msleep(300);
1805 else // Sound Broadcasting mode 3 seg 1814 else // Sound Broadcasting mode 3 seg
1806 msleep(500); 1815 msleep(500);
1807 } else // 13 seg 1816 } else // 13 seg
1808 msleep(200); 1817 msleep(200);
1809 } 1818 }
1810 //dump_reg(state); 1819 if (state->fe[0]->dtv_property_cache.isdbt_sb_mode == 1) {
1811 if (state->fe.dtv_property_cache.isdbt_sb_mode == 1) { 1820 if (state->fe[0]->dtv_property_cache.isdbt_partial_reception == 0) {
1812 if (state->fe.dtv_property_cache.isdbt_partial_reception == 0) { // Sound Broadcasting mode 1 seg
1813 1821
1814 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */ 1822 /* P_timf_alpha = (13-P_mode) , P_corm_alpha=6, P_corm_thres=0x40 alpha to check on board */
1815 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40); 1823 dib8000_write_word(state, 32, ((13 - mode) << 12) | (6 << 8) | 0x40);
@@ -1854,26 +1862,38 @@ static int dib8000_tune(struct dvb_frontend *fe)
1854static int dib8000_wakeup(struct dvb_frontend *fe) 1862static int dib8000_wakeup(struct dvb_frontend *fe)
1855{ 1863{
1856 struct dib8000_state *state = fe->demodulator_priv; 1864 struct dib8000_state *state = fe->demodulator_priv;
1865 u8 index_frontend;
1866 int ret;
1857 1867
1858 dib8000_set_power_mode(state, DIB8000M_POWER_ALL); 1868 dib8000_set_power_mode(state, DIB8000M_POWER_ALL);
1859 dib8000_set_adc_state(state, DIBX000_ADC_ON); 1869 dib8000_set_adc_state(state, DIBX000_ADC_ON);
1860 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0) 1870 if (dib8000_set_adc_state(state, DIBX000_SLOW_ADC_ON) != 0)
1861 dprintk("could not start Slow ADC"); 1871 dprintk("could not start Slow ADC");
1862 1872
1873 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1874 ret = state->fe[index_frontend]->ops.init(state->fe[index_frontend]);
1875 if (ret < 0)
1876 return ret;
1877 }
1878
1863 return 0; 1879 return 0;
1864} 1880}
1865 1881
1866static int dib8000_sleep(struct dvb_frontend *fe) 1882static int dib8000_sleep(struct dvb_frontend *fe)
1867{ 1883{
1868 struct dib8000_state *st = fe->demodulator_priv; 1884 struct dib8000_state *state = fe->demodulator_priv;
1869 if (1) { 1885 u8 index_frontend;
1870 dib8000_set_output_mode(st, OUTMODE_HIGH_Z); 1886 int ret;
1871 dib8000_set_power_mode(st, DIB8000M_POWER_INTERFACE_ONLY);
1872 return dib8000_set_adc_state(st, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(st, DIBX000_ADC_OFF);
1873 } else {
1874 1887
1875 return 0; 1888 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1889 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1890 if (ret < 0)
1891 return ret;
1876 } 1892 }
1893
1894 dib8000_set_output_mode(fe, OUTMODE_HIGH_Z);
1895 dib8000_set_power_mode(state, DIB8000M_POWER_INTERFACE_ONLY);
1896 return dib8000_set_adc_state(state, DIBX000_SLOW_ADC_OFF) | dib8000_set_adc_state(state, DIBX000_ADC_OFF);
1877} 1897}
1878 1898
1879enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe) 1899enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe)
@@ -1891,16 +1911,40 @@ int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tun
1891} 1911}
1892EXPORT_SYMBOL(dib8000_set_tune_state); 1912EXPORT_SYMBOL(dib8000_set_tune_state);
1893 1913
1894
1895
1896
1897static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 1914static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1898{ 1915{
1899 struct dib8000_state *state = fe->demodulator_priv; 1916 struct dib8000_state *state = fe->demodulator_priv;
1900 u16 i, val = 0; 1917 u16 i, val = 0;
1918 fe_status_t stat;
1919 u8 index_frontend, sub_index_frontend;
1901 1920
1902 fe->dtv_property_cache.bandwidth_hz = 6000000; 1921 fe->dtv_property_cache.bandwidth_hz = 6000000;
1903 1922
1923 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1924 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1925 if (stat&FE_HAS_SYNC) {
1926 dprintk("TMCC lock on the slave%i", index_frontend);
1927 /* synchronize the cache with the other frontends */
1928 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1929 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL); sub_index_frontend++) {
1930 if (sub_index_frontend != index_frontend) {
1931 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_sb_mode = state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode;
1932 state->fe[sub_index_frontend]->dtv_property_cache.inversion = state->fe[index_frontend]->dtv_property_cache.inversion;
1933 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode = state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1934 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval = state->fe[index_frontend]->dtv_property_cache.guard_interval;
1935 state->fe[sub_index_frontend]->dtv_property_cache.isdbt_partial_reception = state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception;
1936 for (i = 0; i < 3; i++) {
1937 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].segment_count = state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count;
1938 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].interleaving = state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving;
1939 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].fec = state->fe[index_frontend]->dtv_property_cache.layer[i].fec;
1940 state->fe[sub_index_frontend]->dtv_property_cache.layer[i].modulation = state->fe[index_frontend]->dtv_property_cache.layer[i].modulation;
1941 }
1942 }
1943 }
1944 return 0;
1945 }
1946 }
1947
1904 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1; 1948 fe->dtv_property_cache.isdbt_sb_mode = dib8000_read_word(state, 508) & 0x1;
1905 1949
1906 val = dib8000_read_word(state, 570); 1950 val = dib8000_read_word(state, 570);
@@ -1992,112 +2036,200 @@ static int dib8000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_par
1992 break; 2036 break;
1993 } 2037 }
1994 } 2038 }
2039
2040 /* synchronize the cache with the other frontends */
2041 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2042 state->fe[index_frontend]->dtv_property_cache.isdbt_sb_mode = fe->dtv_property_cache.isdbt_sb_mode;
2043 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
2044 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
2045 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
2046 state->fe[index_frontend]->dtv_property_cache.isdbt_partial_reception = fe->dtv_property_cache.isdbt_partial_reception;
2047 for (i = 0; i < 3; i++) {
2048 state->fe[index_frontend]->dtv_property_cache.layer[i].segment_count = fe->dtv_property_cache.layer[i].segment_count;
2049 state->fe[index_frontend]->dtv_property_cache.layer[i].interleaving = fe->dtv_property_cache.layer[i].interleaving;
2050 state->fe[index_frontend]->dtv_property_cache.layer[i].fec = fe->dtv_property_cache.layer[i].fec;
2051 state->fe[index_frontend]->dtv_property_cache.layer[i].modulation = fe->dtv_property_cache.layer[i].modulation;
2052 }
2053 }
1995 return 0; 2054 return 0;
1996} 2055}
1997 2056
1998static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) 2057static int dib8000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1999{ 2058{
2000 struct dib8000_state *state = fe->demodulator_priv; 2059 struct dib8000_state *state = fe->demodulator_priv;
2060 u8 nbr_pending, exit_condition, index_frontend;
2061 s8 index_frontend_success = -1;
2001 int time, ret; 2062 int time, ret;
2063 int time_slave = FE_CALLBACK_TIME_NEVER;
2002 2064
2003 fe->dtv_property_cache.delivery_system = SYS_ISDBT; 2065 if (state->fe[0]->dtv_property_cache.frequency == 0) {
2066 dprintk("dib8000: must at least specify frequency ");
2067 return 0;
2068 }
2004 2069
2005 dib8000_set_output_mode(state, OUTMODE_HIGH_Z); 2070 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
2071 dprintk("dib8000: no bandwidth specified, set to default ");
2072 state->fe[0]->dtv_property_cache.bandwidth_hz = 6000000;
2073 }
2074
2075 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2076 /* synchronization of the cache */
2077 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_ISDBT;
2078 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
2079
2080 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
2081 if (state->fe[index_frontend]->ops.tuner_ops.set_params)
2082 state->fe[index_frontend]->ops.tuner_ops.set_params(state->fe[index_frontend], fep);
2006 2083
2007 if (fe->ops.tuner_ops.set_params) 2084 dib8000_set_tune_state(state->fe[index_frontend], CT_AGC_START);
2008 fe->ops.tuner_ops.set_params(fe, fep); 2085 }
2009 2086
2010 /* start up the AGC */ 2087 /* start up the AGC */
2011 state->tune_state = CT_AGC_START;
2012 do { 2088 do {
2013 time = dib8000_agc_startup(fe); 2089 time = dib8000_agc_startup(state->fe[0]);
2090 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2091 time_slave = dib8000_agc_startup(state->fe[index_frontend]);
2092 if (time == FE_CALLBACK_TIME_NEVER)
2093 time = time_slave;
2094 else if ((time_slave != FE_CALLBACK_TIME_NEVER) && (time_slave > time))
2095 time = time_slave;
2096 }
2014 if (time != FE_CALLBACK_TIME_NEVER) 2097 if (time != FE_CALLBACK_TIME_NEVER)
2015 msleep(time / 10); 2098 msleep(time / 10);
2016 else 2099 else
2017 break; 2100 break;
2018 } while (state->tune_state != CT_AGC_STOP); 2101 exit_condition = 1;
2019 2102 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2020 if (state->fe.dtv_property_cache.frequency == 0) { 2103 if (dib8000_get_tune_state(state->fe[index_frontend]) != CT_AGC_STOP) {
2021 dprintk("dib8000: must at least specify frequency "); 2104 exit_condition = 0;
2022 return 0; 2105 break;
2023 } 2106 }
2024 2107 }
2025 if (state->fe.dtv_property_cache.bandwidth_hz == 0) { 2108 } while (exit_condition == 0);
2026 dprintk("dib8000: no bandwidth specified, set to default "); 2109
2027 state->fe.dtv_property_cache.bandwidth_hz = 6000000; 2110 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2028 } 2111 dib8000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
2112
2113 if ((state->fe[0]->dtv_property_cache.delivery_system != SYS_ISDBT) ||
2114 (state->fe[0]->dtv_property_cache.inversion == INVERSION_AUTO) ||
2115 (state->fe[0]->dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2116 (state->fe[0]->dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2117 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2118 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0xff) &&
2119 (state->fe[0]->dtv_property_cache.layer[0].segment_count != 0) &&
2120 ((state->fe[0]->dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2121 (state->fe[0]->dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2122 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2123 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0xff) &&
2124 (state->fe[0]->dtv_property_cache.layer[1].segment_count != 0) &&
2125 ((state->fe[0]->dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2126 (state->fe[0]->dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2127 (((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2128 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0xff) &&
2129 (state->fe[0]->dtv_property_cache.layer[2].segment_count != 0) &&
2130 ((state->fe[0]->dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2131 (state->fe[0]->dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2132 (((state->fe[0]->dtv_property_cache.layer[0].segment_count == 0) ||
2133 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2134 ((state->fe[0]->dtv_property_cache.layer[1].segment_count == 0) ||
2135 ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2136 ((state->fe[0]->dtv_property_cache.layer[2].segment_count == 0) || ((state->fe[0]->dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2137 int i = 80000;
2138 u8 found = 0;
2139 u8 tune_failed = 0;
2140
2141 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2142 dib8000_set_bandwidth(state->fe[index_frontend], fe->dtv_property_cache.bandwidth_hz / 1000);
2143 dib8000_autosearch_start(state->fe[index_frontend]);
2144 }
2029 2145
2030 state->tune_state = CT_DEMOD_START;
2031
2032 if ((state->fe.dtv_property_cache.delivery_system != SYS_ISDBT) ||
2033 (state->fe.dtv_property_cache.inversion == INVERSION_AUTO) ||
2034 (state->fe.dtv_property_cache.transmission_mode == TRANSMISSION_MODE_AUTO) ||
2035 (state->fe.dtv_property_cache.guard_interval == GUARD_INTERVAL_AUTO) ||
2036 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) != 0) &&
2037 (state->fe.dtv_property_cache.layer[0].segment_count != 0xff) &&
2038 (state->fe.dtv_property_cache.layer[0].segment_count != 0) &&
2039 ((state->fe.dtv_property_cache.layer[0].modulation == QAM_AUTO) ||
2040 (state->fe.dtv_property_cache.layer[0].fec == FEC_AUTO))) ||
2041 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 1)) != 0) &&
2042 (state->fe.dtv_property_cache.layer[1].segment_count != 0xff) &&
2043 (state->fe.dtv_property_cache.layer[1].segment_count != 0) &&
2044 ((state->fe.dtv_property_cache.layer[1].modulation == QAM_AUTO) ||
2045 (state->fe.dtv_property_cache.layer[1].fec == FEC_AUTO))) ||
2046 (((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 2)) != 0) &&
2047 (state->fe.dtv_property_cache.layer[2].segment_count != 0xff) &&
2048 (state->fe.dtv_property_cache.layer[2].segment_count != 0) &&
2049 ((state->fe.dtv_property_cache.layer[2].modulation == QAM_AUTO) ||
2050 (state->fe.dtv_property_cache.layer[2].fec == FEC_AUTO))) ||
2051 (((state->fe.dtv_property_cache.layer[0].segment_count == 0) ||
2052 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (1 << 0)) == 0)) &&
2053 ((state->fe.dtv_property_cache.layer[1].segment_count == 0) ||
2054 ((state->fe.dtv_property_cache.isdbt_layer_enabled & (2 << 0)) == 0)) &&
2055 ((state->fe.dtv_property_cache.layer[2].segment_count == 0) || ((state->fe.dtv_property_cache.isdbt_layer_enabled & (3 << 0)) == 0)))) {
2056 int i = 800, found;
2057
2058 dib8000_set_bandwidth(state, fe->dtv_property_cache.bandwidth_hz / 1000);
2059 dib8000_autosearch_start(fe);
2060 do { 2146 do {
2061 msleep(10); 2147 msleep(20);
2062 found = dib8000_autosearch_irq(fe); 2148 nbr_pending = 0;
2063 } while (found == 0 && i--); 2149 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
2150 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2151 if (((tune_failed >> index_frontend) & 0x1) == 0) {
2152 found = dib8000_autosearch_irq(state->fe[index_frontend]);
2153 switch (found) {
2154 case 0: /* tune pending */
2155 nbr_pending++;
2156 break;
2157 case 2:
2158 dprintk("autosearch succeed on the frontend%i", index_frontend);
2159 exit_condition = 2;
2160 index_frontend_success = index_frontend;
2161 break;
2162 default:
2163 dprintk("unhandled autosearch result");
2164 case 1:
2165 dprintk("autosearch failed for the frontend%i", index_frontend);
2166 break;
2167 }
2168 }
2169 }
2064 2170
2065 dprintk("Frequency %d Hz, autosearch returns: %d", fep->frequency, found); 2171 /* if all tune are done and no success, exit: tune failed */
2172 if ((nbr_pending == 0) && (exit_condition == 0))
2173 exit_condition = 1;
2174 } while ((exit_condition == 0) && i--);
2066 2175
2067 if (found == 0 || found == 1) 2176 if (exit_condition == 1) { /* tune failed */
2068 return 0; // no channel found 2177 dprintk("tune failed");
2178 return 0;
2179 }
2180
2181 dprintk("tune success on frontend%i", index_frontend_success);
2069 2182
2070 dib8000_get_frontend(fe, fep); 2183 dib8000_get_frontend(fe, fep);
2071 } 2184 }
2072 2185
2073 ret = dib8000_tune(fe); 2186 for (index_frontend = 0, ret = 0; (ret >= 0) && (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2187 ret = dib8000_tune(state->fe[index_frontend]);
2188
2189 /* set output mode and diversity input */
2190 dib8000_set_output_mode(state->fe[0], state->cfg.output_mode);
2191 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2192 dib8000_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
2193 dib8000_set_diversity_in(state->fe[index_frontend-1], 1);
2194 }
2074 2195
2075 /* make this a config parameter */ 2196 /* turn off the diversity of the last chip */
2076 dib8000_set_output_mode(state, state->cfg.output_mode); 2197 dib8000_set_diversity_in(state->fe[index_frontend-1], 0);
2077 2198
2078 return ret; 2199 return ret;
2079} 2200}
2080 2201
2202static u16 dib8000_read_lock(struct dvb_frontend *fe)
2203{
2204 struct dib8000_state *state = fe->demodulator_priv;
2205
2206 return dib8000_read_word(state, 568);
2207}
2208
2081static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat) 2209static int dib8000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2082{ 2210{
2083 struct dib8000_state *state = fe->demodulator_priv; 2211 struct dib8000_state *state = fe->demodulator_priv;
2084 u16 lock = dib8000_read_word(state, 568); 2212 u16 lock_slave = 0, lock = dib8000_read_word(state, 568);
2213 u8 index_frontend;
2214
2215 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2216 lock_slave |= dib8000_read_lock(state->fe[index_frontend]);
2085 2217
2086 *stat = 0; 2218 *stat = 0;
2087 2219
2088 if ((lock >> 13) & 1) 2220 if (((lock >> 13) & 1) || ((lock_slave >> 13) & 1))
2089 *stat |= FE_HAS_SIGNAL; 2221 *stat |= FE_HAS_SIGNAL;
2090 2222
2091 if ((lock >> 8) & 1) /* Equal */ 2223 if (((lock >> 8) & 1) || ((lock_slave >> 8) & 1)) /* Equal */
2092 *stat |= FE_HAS_CARRIER; 2224 *stat |= FE_HAS_CARRIER;
2093 2225
2094 if (((lock >> 1) & 0xf) == 0xf) /* TMCC_SYNC */ 2226 if ((((lock >> 1) & 0xf) == 0xf) || (((lock_slave >> 1) & 0xf) == 0xf)) /* TMCC_SYNC */
2095 *stat |= FE_HAS_SYNC; 2227 *stat |= FE_HAS_SYNC;
2096 2228
2097 if (((lock >> 12) & 1) && ((lock >> 5) & 7)) /* FEC MPEG */ 2229 if ((((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) && ((lock >> 5) & 7)) /* FEC MPEG */
2098 *stat |= FE_HAS_LOCK; 2230 *stat |= FE_HAS_LOCK;
2099 2231
2100 if ((lock >> 12) & 1) { 2232 if (((lock >> 12) & 1) || ((lock_slave >> 12) & 1)) {
2101 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */ 2233 lock = dib8000_read_word(state, 554); /* Viterbi Layer A */
2102 if (lock & 0x01) 2234 if (lock & 0x01)
2103 *stat |= FE_HAS_VITERBI; 2235 *stat |= FE_HAS_VITERBI;
@@ -2131,44 +2263,120 @@ static int dib8000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2131static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength) 2263static int dib8000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2132{ 2264{
2133 struct dib8000_state *state = fe->demodulator_priv; 2265 struct dib8000_state *state = fe->demodulator_priv;
2134 u16 val = dib8000_read_word(state, 390); 2266 u8 index_frontend;
2135 *strength = 65535 - val; 2267 u16 val;
2268
2269 *strength = 0;
2270 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2271 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2272 if (val > 65535 - *strength)
2273 *strength = 65535;
2274 else
2275 *strength += val;
2276 }
2277
2278 val = 65535 - dib8000_read_word(state, 390);
2279 if (val > 65535 - *strength)
2280 *strength = 65535;
2281 else
2282 *strength += val;
2136 return 0; 2283 return 0;
2137} 2284}
2138 2285
2139static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr) 2286static u32 dib8000_get_snr(struct dvb_frontend *fe)
2140{ 2287{
2141 struct dib8000_state *state = fe->demodulator_priv; 2288 struct dib8000_state *state = fe->demodulator_priv;
2289 u32 n, s, exp;
2142 u16 val; 2290 u16 val;
2143 s32 signal_mant, signal_exp, noise_mant, noise_exp;
2144 u32 result = 0;
2145 2291
2146 val = dib8000_read_word(state, 542); 2292 val = dib8000_read_word(state, 542);
2147 noise_mant = (val >> 6) & 0xff; 2293 n = (val >> 6) & 0xff;
2148 noise_exp = (val & 0x3f); 2294 exp = (val & 0x3f);
2295 if ((exp & 0x20) != 0)
2296 exp -= 0x40;
2297 n <<= exp+16;
2149 2298
2150 val = dib8000_read_word(state, 543); 2299 val = dib8000_read_word(state, 543);
2151 signal_mant = (val >> 6) & 0xff; 2300 s = (val >> 6) & 0xff;
2152 signal_exp = (val & 0x3f); 2301 exp = (val & 0x3f);
2302 if ((exp & 0x20) != 0)
2303 exp -= 0x40;
2304 s <<= exp+16;
2305
2306 if (n > 0) {
2307 u32 t = (s/n) << 16;
2308 return t + ((s << 16) - n*t) / n;
2309 }
2310 return 0xffffffff;
2311}
2153 2312
2154 if ((noise_exp & 0x20) != 0) 2313static int dib8000_read_snr(struct dvb_frontend *fe, u16 * snr)
2155 noise_exp -= 0x40; 2314{
2156 if ((signal_exp & 0x20) != 0) 2315 struct dib8000_state *state = fe->demodulator_priv;
2157 signal_exp -= 0x40; 2316 u8 index_frontend;
2317 u32 snr_master;
2158 2318
2159 if (signal_mant != 0) 2319 snr_master = dib8000_get_snr(fe);
2160 result = intlog10(2) * 10 * signal_exp + 10 * intlog10(signal_mant); 2320 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2161 else 2321 snr_master += dib8000_get_snr(state->fe[index_frontend]);
2162 result = intlog10(2) * 10 * signal_exp - 100; 2322
2163 if (noise_mant != 0) 2323 if (snr_master != 0) {
2164 result -= intlog10(2) * 10 * noise_exp + 10 * intlog10(noise_mant); 2324 snr_master = 10*intlog10(snr_master>>16);
2325 *snr = snr_master / ((1 << 24) / 10);
2326 }
2165 else 2327 else
2166 result -= intlog10(2) * 10 * noise_exp - 100; 2328 *snr = 0;
2167 2329
2168 *snr = result / ((1 << 24) / 10);
2169 return 0; 2330 return 0;
2170} 2331}
2171 2332
2333int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2334{
2335 struct dib8000_state *state = fe->demodulator_priv;
2336 u8 index_frontend = 1;
2337
2338 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2339 index_frontend++;
2340 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2341 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2342 state->fe[index_frontend] = fe_slave;
2343 return 0;
2344 }
2345
2346 dprintk("too many slave frontend");
2347 return -ENOMEM;
2348}
2349EXPORT_SYMBOL(dib8000_set_slave_frontend);
2350
2351int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
2352{
2353 struct dib8000_state *state = fe->demodulator_priv;
2354 u8 index_frontend = 1;
2355
2356 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2357 index_frontend++;
2358 if (index_frontend != 1) {
2359 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend-1], index_frontend-1);
2360 state->fe[index_frontend] = NULL;
2361 return 0;
2362 }
2363
2364 dprintk("no frontend to be removed");
2365 return -ENODEV;
2366}
2367EXPORT_SYMBOL(dib8000_remove_slave_frontend);
2368
2369struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2370{
2371 struct dib8000_state *state = fe->demodulator_priv;
2372
2373 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2374 return NULL;
2375 return state->fe[slave_index];
2376}
2377EXPORT_SYMBOL(dib8000_get_slave_frontend);
2378
2379
2172int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr) 2380int dib8000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
2173{ 2381{
2174 int k = 0; 2382 int k = 0;
@@ -2227,7 +2435,13 @@ static int dib8000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_fron
2227static void dib8000_release(struct dvb_frontend *fe) 2435static void dib8000_release(struct dvb_frontend *fe)
2228{ 2436{
2229 struct dib8000_state *st = fe->demodulator_priv; 2437 struct dib8000_state *st = fe->demodulator_priv;
2438 u8 index_frontend;
2439
2440 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
2441 dvb_frontend_detach(st->fe[index_frontend]);
2442
2230 dibx000_exit_i2c_master(&st->i2c_master); 2443 dibx000_exit_i2c_master(&st->i2c_master);
2444 kfree(st->fe[0]);
2231 kfree(st); 2445 kfree(st);
2232} 2446}
2233 2447
@@ -2242,19 +2456,19 @@ EXPORT_SYMBOL(dib8000_get_i2c_master);
2242int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff) 2456int dib8000_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
2243{ 2457{
2244 struct dib8000_state *st = fe->demodulator_priv; 2458 struct dib8000_state *st = fe->demodulator_priv;
2245 u16 val = dib8000_read_word(st, 299) & 0xffef; 2459 u16 val = dib8000_read_word(st, 299) & 0xffef;
2246 val |= (onoff & 0x1) << 4; 2460 val |= (onoff & 0x1) << 4;
2247 2461
2248 dprintk("pid filter enabled %d", onoff); 2462 dprintk("pid filter enabled %d", onoff);
2249 return dib8000_write_word(st, 299, val); 2463 return dib8000_write_word(st, 299, val);
2250} 2464}
2251EXPORT_SYMBOL(dib8000_pid_filter_ctrl); 2465EXPORT_SYMBOL(dib8000_pid_filter_ctrl);
2252 2466
2253int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff) 2467int dib8000_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
2254{ 2468{
2255 struct dib8000_state *st = fe->demodulator_priv; 2469 struct dib8000_state *st = fe->demodulator_priv;
2256 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff); 2470 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
2257 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0); 2471 return dib8000_write_word(st, 305 + id, onoff ? (1 << 13) | pid : 0);
2258} 2472}
2259EXPORT_SYMBOL(dib8000_pid_filter); 2473EXPORT_SYMBOL(dib8000_pid_filter);
2260 2474
@@ -2298,6 +2512,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
2298 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL); 2512 state = kzalloc(sizeof(struct dib8000_state), GFP_KERNEL);
2299 if (state == NULL) 2513 if (state == NULL)
2300 return NULL; 2514 return NULL;
2515 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2516 if (fe == NULL)
2517 goto error;
2301 2518
2302 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config)); 2519 memcpy(&state->cfg, cfg, sizeof(struct dib8000_config));
2303 state->i2c.adap = i2c_adap; 2520 state->i2c.adap = i2c_adap;
@@ -2311,9 +2528,9 @@ struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, s
2311 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK)) 2528 if ((state->cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (state->cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2312 state->cfg.output_mode = OUTMODE_MPEG2_FIFO; 2529 state->cfg.output_mode = OUTMODE_MPEG2_FIFO;
2313 2530
2314 fe = &state->fe; 2531 state->fe[0] = fe;
2315 fe->demodulator_priv = state; 2532 fe->demodulator_priv = state;
2316 memcpy(&state->fe.ops, &dib8000_ops, sizeof(struct dvb_frontend_ops)); 2533 memcpy(&state->fe[0]->ops, &dib8000_ops, sizeof(struct dvb_frontend_ops));
2317 2534
2318 state->timf_default = cfg->pll->timf; 2535 state->timf_default = cfg->pll->timf;
2319 2536
diff --git a/drivers/media/dvb/frontends/dib8000.h b/drivers/media/dvb/frontends/dib8000.h
index e0a9ded11df4..617f9eba3a09 100644
--- a/drivers/media/dvb/frontends/dib8000.h
+++ b/drivers/media/dvb/frontends/dib8000.h
@@ -50,6 +50,9 @@ extern int dib8000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_st
50extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe); 50extern enum frontend_tune_state dib8000_get_tune_state(struct dvb_frontend *fe);
51extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe); 51extern void dib8000_pwm_agc_reset(struct dvb_frontend *fe);
52extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode); 52extern s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode);
53extern int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
54extern int dib8000_remove_slave_frontend(struct dvb_frontend *fe);
55extern struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
53#else 56#else
54static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg) 57static inline struct dvb_frontend *dib8000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib8000_config *cfg)
55{ 58{
@@ -111,6 +114,23 @@ static inline s32 dib8000_get_adc_power(struct dvb_frontend *fe, u8 mode)
111 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 114 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
112 return 0; 115 return 0;
113} 116}
117static inline int dib8000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
118{
119 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
120 return -ENODEV;
121}
122
123int dib8000_remove_slave_frontend(struct dvb_frontend *fe)
124{
125 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
126 return -ENODEV;
127}
128
129static inline struct dvb_frontend *dib8000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
130{
131 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
132 return NULL;
133}
114#endif 134#endif
115 135
116#endif 136#endif
diff --git a/drivers/media/dvb/frontends/dib9000.c b/drivers/media/dvb/frontends/dib9000.c
new file mode 100644
index 000000000000..91518761a2da
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib9000.c
@@ -0,0 +1,2351 @@
1/*
2 * Linux-DVB Driver for DiBcom's DiB9000 and demodulator-family.
3 *
4 * Copyright (C) 2005-10 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 <linux/mutex.h>
13
14#include "dvb_math.h"
15#include "dvb_frontend.h"
16
17#include "dib9000.h"
18#include "dibx000_common.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
23
24#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB9000: "); printk(args); printk("\n"); } } while (0)
25#define MAX_NUMBER_OF_FRONTENDS 6
26
27struct i2c_device {
28 struct i2c_adapter *i2c_adap;
29 u8 i2c_addr;
30};
31
32/* lock */
33#define DIB_LOCK struct mutex
34#define DibAcquireLock(lock) do { if (mutex_lock_interruptible(lock) < 0) dprintk("could not get the lock"); } while (0)
35#define DibReleaseLock(lock) mutex_unlock(lock)
36#define DibInitLock(lock) mutex_init(lock)
37#define DibFreeLock(lock)
38
39struct dib9000_state {
40 struct i2c_device i2c;
41
42 struct dibx000_i2c_master i2c_master;
43 struct i2c_adapter tuner_adap;
44 struct i2c_adapter component_bus;
45
46 u16 revision;
47 u8 reg_offs;
48
49 enum frontend_tune_state tune_state;
50 u32 status;
51 struct dvb_frontend_parametersContext channel_status;
52
53 u8 fe_id;
54
55#define DIB9000_GPIO_DEFAULT_DIRECTIONS 0xffff
56 u16 gpio_dir;
57#define DIB9000_GPIO_DEFAULT_VALUES 0x0000
58 u16 gpio_val;
59#define DIB9000_GPIO_DEFAULT_PWM_POS 0xffff
60 u16 gpio_pwm_pos;
61
62 union { /* common for all chips */
63 struct {
64 u8 mobile_mode:1;
65 } host;
66
67 struct {
68 struct dib9000_fe_memory_map {
69 u16 addr;
70 u16 size;
71 } fe_mm[18];
72 u8 memcmd;
73
74 DIB_LOCK mbx_if_lock; /* to protect read/write operations */
75 DIB_LOCK mbx_lock; /* to protect the whole mailbox handling */
76
77 DIB_LOCK mem_lock; /* to protect the memory accesses */
78 DIB_LOCK mem_mbx_lock; /* to protect the memory-based mailbox */
79
80#define MBX_MAX_WORDS (256 - 200 - 2)
81#define DIB9000_MSG_CACHE_SIZE 2
82 u16 message_cache[DIB9000_MSG_CACHE_SIZE][MBX_MAX_WORDS];
83 u8 fw_is_running;
84 } risc;
85 } platform;
86
87 union { /* common for all platforms */
88 struct {
89 struct dib9000_config cfg;
90 } d9;
91 } chip;
92
93 struct dvb_frontend *fe[MAX_NUMBER_OF_FRONTENDS];
94 u16 component_bus_speed;
95};
96
97u32 fe_info[44] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
98 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
99 0, 0, 0
100};
101
102enum dib9000_power_mode {
103 DIB9000_POWER_ALL = 0,
104
105 DIB9000_POWER_NO,
106 DIB9000_POWER_INTERF_ANALOG_AGC,
107 DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD,
108 DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD,
109 DIB9000_POWER_INTERFACE_ONLY,
110};
111
112enum dib9000_out_messages {
113 OUT_MSG_HBM_ACK,
114 OUT_MSG_HOST_BUF_FAIL,
115 OUT_MSG_REQ_VERSION,
116 OUT_MSG_BRIDGE_I2C_W,
117 OUT_MSG_BRIDGE_I2C_R,
118 OUT_MSG_BRIDGE_APB_W,
119 OUT_MSG_BRIDGE_APB_R,
120 OUT_MSG_SCAN_CHANNEL,
121 OUT_MSG_MONIT_DEMOD,
122 OUT_MSG_CONF_GPIO,
123 OUT_MSG_DEBUG_HELP,
124 OUT_MSG_SUBBAND_SEL,
125 OUT_MSG_ENABLE_TIME_SLICE,
126 OUT_MSG_FE_FW_DL,
127 OUT_MSG_FE_CHANNEL_SEARCH,
128 OUT_MSG_FE_CHANNEL_TUNE,
129 OUT_MSG_FE_SLEEP,
130 OUT_MSG_FE_SYNC,
131 OUT_MSG_CTL_MONIT,
132
133 OUT_MSG_CONF_SVC,
134 OUT_MSG_SET_HBM,
135 OUT_MSG_INIT_DEMOD,
136 OUT_MSG_ENABLE_DIVERSITY,
137 OUT_MSG_SET_OUTPUT_MODE,
138 OUT_MSG_SET_PRIORITARY_CHANNEL,
139 OUT_MSG_ACK_FRG,
140 OUT_MSG_INIT_PMU,
141};
142
143enum dib9000_in_messages {
144 IN_MSG_DATA,
145 IN_MSG_FRAME_INFO,
146 IN_MSG_CTL_MONIT,
147 IN_MSG_ACK_FREE_ITEM,
148 IN_MSG_DEBUG_BUF,
149 IN_MSG_MPE_MONITOR,
150 IN_MSG_RAWTS_MONITOR,
151 IN_MSG_END_BRIDGE_I2C_RW,
152 IN_MSG_END_BRIDGE_APB_RW,
153 IN_MSG_VERSION,
154 IN_MSG_END_OF_SCAN,
155 IN_MSG_MONIT_DEMOD,
156 IN_MSG_ERROR,
157 IN_MSG_FE_FW_DL_DONE,
158 IN_MSG_EVENT,
159 IN_MSG_ACK_CHANGE_SVC,
160 IN_MSG_HBM_PROF,
161};
162
163/* memory_access requests */
164#define FE_MM_W_CHANNEL 0
165#define FE_MM_W_FE_INFO 1
166#define FE_MM_RW_SYNC 2
167
168#define FE_SYNC_CHANNEL 1
169#define FE_SYNC_W_GENERIC_MONIT 2
170#define FE_SYNC_COMPONENT_ACCESS 3
171
172#define FE_MM_R_CHANNEL_SEARCH_STATE 3
173#define FE_MM_R_CHANNEL_UNION_CONTEXT 4
174#define FE_MM_R_FE_INFO 5
175#define FE_MM_R_FE_MONITOR 6
176
177#define FE_MM_W_CHANNEL_HEAD 7
178#define FE_MM_W_CHANNEL_UNION 8
179#define FE_MM_W_CHANNEL_CONTEXT 9
180#define FE_MM_R_CHANNEL_UNION 10
181#define FE_MM_R_CHANNEL_CONTEXT 11
182#define FE_MM_R_CHANNEL_TUNE_STATE 12
183
184#define FE_MM_R_GENERIC_MONITORING_SIZE 13
185#define FE_MM_W_GENERIC_MONITORING 14
186#define FE_MM_R_GENERIC_MONITORING 15
187
188#define FE_MM_W_COMPONENT_ACCESS 16
189#define FE_MM_RW_COMPONENT_ACCESS_BUFFER 17
190static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len);
191static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len);
192
193static u16 to_fw_output_mode(u16 mode)
194{
195 switch (mode) {
196 case OUTMODE_HIGH_Z:
197 return 0;
198 case OUTMODE_MPEG2_PAR_GATED_CLK:
199 return 4;
200 case OUTMODE_MPEG2_PAR_CONT_CLK:
201 return 8;
202 case OUTMODE_MPEG2_SERIAL:
203 return 16;
204 case OUTMODE_DIVERSITY:
205 return 128;
206 case OUTMODE_MPEG2_FIFO:
207 return 2;
208 case OUTMODE_ANALOG_ADC:
209 return 1;
210 default:
211 return 0;
212 }
213}
214
215static u16 dib9000_read16_attr(struct dib9000_state *state, u16 reg, u8 * b, u32 len, u16 attribute)
216{
217 u32 chunk_size = 126;
218 u32 l;
219 int ret;
220 u8 wb[2] = { reg >> 8, reg & 0xff };
221 struct i2c_msg msg[2] = {
222 {.addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
223 {.addr = state->i2c.i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = len},
224 };
225
226 if (state->platform.risc.fw_is_running && (reg < 1024))
227 return dib9000_risc_apb_access_read(state, reg, attribute, NULL, 0, b, len);
228
229 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
230 wb[0] |= (1 << 5);
231 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
232 wb[0] |= (1 << 4);
233
234 do {
235 l = len < chunk_size ? len : chunk_size;
236 msg[1].len = l;
237 msg[1].buf = b;
238 ret = i2c_transfer(state->i2c.i2c_adap, msg, 2) != 2 ? -EREMOTEIO : 0;
239 if (ret != 0) {
240 dprintk("i2c read error on %d", reg);
241 return -EREMOTEIO;
242 }
243
244 b += l;
245 len -= l;
246
247 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
248 reg += l / 2;
249 } while ((ret == 0) && len);
250
251 return 0;
252}
253
254static u16 dib9000_i2c_read16(struct i2c_device *i2c, u16 reg)
255{
256 u8 b[2];
257 u8 wb[2] = { reg >> 8, reg & 0xff };
258 struct i2c_msg msg[2] = {
259 {.addr = i2c->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2},
260 {.addr = i2c->i2c_addr >> 1, .flags = I2C_M_RD, .buf = b, .len = 2},
261 };
262
263 if (i2c_transfer(i2c->i2c_adap, msg, 2) != 2) {
264 dprintk("read register %x error", reg);
265 return 0;
266 }
267
268 return (b[0] << 8) | b[1];
269}
270
271static inline u16 dib9000_read_word(struct dib9000_state *state, u16 reg)
272{
273 u8 b[2];
274 if (dib9000_read16_attr(state, reg, b, 2, 0) != 0)
275 return 0;
276 return (b[0] << 8 | b[1]);
277}
278
279static inline u16 dib9000_read_word_attr(struct dib9000_state *state, u16 reg, u16 attribute)
280{
281 u8 b[2];
282 if (dib9000_read16_attr(state, reg, b, 2, attribute) != 0)
283 return 0;
284 return (b[0] << 8 | b[1]);
285}
286
287#define dib9000_read16_noinc_attr(state, reg, b, len, attribute) dib9000_read16_attr(state, reg, b, len, (attribute) | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
288
289static u16 dib9000_write16_attr(struct dib9000_state *state, u16 reg, const u8 * buf, u32 len, u16 attribute)
290{
291 u8 b[255];
292 u32 chunk_size = 126;
293 u32 l;
294 int ret;
295
296 struct i2c_msg msg = {
297 .addr = state->i2c.i2c_addr >> 1, .flags = 0, .buf = b, .len = len + 2
298 };
299
300 if (state->platform.risc.fw_is_running && (reg < 1024)) {
301 if (dib9000_risc_apb_access_write
302 (state, reg, DATA_BUS_ACCESS_MODE_16BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | attribute, buf, len) != 0)
303 return -EINVAL;
304 return 0;
305 }
306
307 b[0] = (reg >> 8) & 0xff;
308 b[1] = (reg) & 0xff;
309
310 if (attribute & DATA_BUS_ACCESS_MODE_8BIT)
311 b[0] |= (1 << 5);
312 if (attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
313 b[0] |= (1 << 4);
314
315 do {
316 l = len < chunk_size ? len : chunk_size;
317 msg.len = l + 2;
318 memcpy(&b[2], buf, l);
319
320 ret = i2c_transfer(state->i2c.i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
321
322 buf += l;
323 len -= l;
324
325 if (!(attribute & DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT))
326 reg += l / 2;
327 } while ((ret == 0) && len);
328
329 return ret;
330}
331
332static int dib9000_i2c_write16(struct i2c_device *i2c, u16 reg, u16 val)
333{
334 u8 b[4] = { (reg >> 8) & 0xff, reg & 0xff, (val >> 8) & 0xff, val & 0xff };
335 struct i2c_msg msg = {
336 .addr = i2c->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
337 };
338
339 return i2c_transfer(i2c->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
340}
341
342static inline int dib9000_write_word(struct dib9000_state *state, u16 reg, u16 val)
343{
344 u8 b[2] = { val >> 8, val & 0xff };
345 return dib9000_write16_attr(state, reg, b, 2, 0);
346}
347
348static inline int dib9000_write_word_attr(struct dib9000_state *state, u16 reg, u16 val, u16 attribute)
349{
350 u8 b[2] = { val >> 8, val & 0xff };
351 return dib9000_write16_attr(state, reg, b, 2, attribute);
352}
353
354#define dib9000_write(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, 0)
355#define dib9000_write16_noinc(state, reg, buf, len) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
356#define dib9000_write16_noinc_attr(state, reg, buf, len, attribute) dib9000_write16_attr(state, reg, buf, len, DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT | (attribute))
357
358#define dib9000_mbx_send(state, id, data, len) dib9000_mbx_send_attr(state, id, data, len, 0)
359#define dib9000_mbx_get_message(state, id, msg, len) dib9000_mbx_get_message_attr(state, id, msg, len, 0)
360
361#define MAC_IRQ (1 << 1)
362#define IRQ_POL_MSK (1 << 4)
363
364#define dib9000_risc_mem_read_chunks(state, b, len) dib9000_read16_attr(state, 1063, b, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
365#define dib9000_risc_mem_write_chunks(state, buf, len) dib9000_write16_attr(state, 1063, buf, len, DATA_BUS_ACCESS_MODE_8BIT | DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT)
366
367static void dib9000_risc_mem_setup_cmd(struct dib9000_state *state, u32 addr, u32 len, u8 reading)
368{
369 u8 b[14] = { 0 };
370
371/* dprintk("%d memcmd: %d %d %d\n", state->fe_id, addr, addr+len, len); */
372/* b[0] = 0 << 7; */
373 b[1] = 1;
374
375/* b[2] = 0; */
376/* b[3] = 0; */
377 b[4] = (u8) (addr >> 8);
378 b[5] = (u8) (addr & 0xff);
379
380/* b[10] = 0; */
381/* b[11] = 0; */
382 b[12] = (u8) (addr >> 8);
383 b[13] = (u8) (addr & 0xff);
384
385 addr += len;
386/* b[6] = 0; */
387/* b[7] = 0; */
388 b[8] = (u8) (addr >> 8);
389 b[9] = (u8) (addr & 0xff);
390
391 dib9000_write(state, 1056, b, 14);
392 if (reading)
393 dib9000_write_word(state, 1056, (1 << 15) | 1);
394 state->platform.risc.memcmd = -1; /* if it was called directly reset it - to force a future setup-call to set it */
395}
396
397static void dib9000_risc_mem_setup(struct dib9000_state *state, u8 cmd)
398{
399 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd & 0x7f];
400 /* decide whether we need to "refresh" the memory controller */
401 if (state->platform.risc.memcmd == cmd && /* same command */
402 !(cmd & 0x80 && m->size < 67)) /* and we do not want to read something with less than 67 bytes looping - working around a bug in the memory controller */
403 return;
404 dib9000_risc_mem_setup_cmd(state, m->addr, m->size, cmd & 0x80);
405 state->platform.risc.memcmd = cmd;
406}
407
408static int dib9000_risc_mem_read(struct dib9000_state *state, u8 cmd, u8 * b, u16 len)
409{
410 if (!state->platform.risc.fw_is_running)
411 return -EIO;
412
413 DibAcquireLock(&state->platform.risc.mem_lock);
414 dib9000_risc_mem_setup(state, cmd | 0x80);
415 dib9000_risc_mem_read_chunks(state, b, len);
416 DibReleaseLock(&state->platform.risc.mem_lock);
417 return 0;
418}
419
420static int dib9000_risc_mem_write(struct dib9000_state *state, u8 cmd, const u8 * b)
421{
422 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[cmd];
423 if (!state->platform.risc.fw_is_running)
424 return -EIO;
425
426 DibAcquireLock(&state->platform.risc.mem_lock);
427 dib9000_risc_mem_setup(state, cmd);
428 dib9000_risc_mem_write_chunks(state, b, m->size);
429 DibReleaseLock(&state->platform.risc.mem_lock);
430 return 0;
431}
432
433static int dib9000_firmware_download(struct dib9000_state *state, u8 risc_id, u16 key, const u8 * code, u32 len)
434{
435 u16 offs;
436
437 if (risc_id == 1)
438 offs = 16;
439 else
440 offs = 0;
441
442 /* config crtl reg */
443 dib9000_write_word(state, 1024 + offs, 0x000f);
444 dib9000_write_word(state, 1025 + offs, 0);
445 dib9000_write_word(state, 1031 + offs, key);
446
447 dprintk("going to download %dB of microcode", len);
448 if (dib9000_write16_noinc(state, 1026 + offs, (u8 *) code, (u16) len) != 0) {
449 dprintk("error while downloading microcode for RISC %c", 'A' + risc_id);
450 return -EIO;
451 }
452
453 dprintk("Microcode for RISC %c loaded", 'A' + risc_id);
454
455 return 0;
456}
457
458static int dib9000_mbx_host_init(struct dib9000_state *state, u8 risc_id)
459{
460 u16 mbox_offs;
461 u16 reset_reg;
462 u16 tries = 1000;
463
464 if (risc_id == 1)
465 mbox_offs = 16;
466 else
467 mbox_offs = 0;
468
469 /* Reset mailbox */
470 dib9000_write_word(state, 1027 + mbox_offs, 0x8000);
471
472 /* Read reset status */
473 do {
474 reset_reg = dib9000_read_word(state, 1027 + mbox_offs);
475 msleep(100);
476 } while ((reset_reg & 0x8000) && --tries);
477
478 if (reset_reg & 0x8000) {
479 dprintk("MBX: init ERROR, no response from RISC %c", 'A' + risc_id);
480 return -EIO;
481 }
482 dprintk("MBX: initialized");
483 return 0;
484}
485
486#define MAX_MAILBOX_TRY 100
487static int dib9000_mbx_send_attr(struct dib9000_state *state, u8 id, u16 * data, u8 len, u16 attr)
488{
489 u8 *d, b[2];
490 u16 tmp;
491 u16 size;
492 u32 i;
493 int ret = 0;
494
495 if (!state->platform.risc.fw_is_running)
496 return -EINVAL;
497
498 DibAcquireLock(&state->platform.risc.mbx_if_lock);
499 tmp = MAX_MAILBOX_TRY;
500 do {
501 size = dib9000_read_word_attr(state, 1043, attr) & 0xff;
502 if ((size + len + 1) > MBX_MAX_WORDS && --tmp) {
503 dprintk("MBX: RISC mbx full, retrying");
504 msleep(100);
505 } else
506 break;
507 } while (1);
508
509 /*dprintk( "MBX: size: %d", size); */
510
511 if (tmp == 0) {
512 ret = -EINVAL;
513 goto out;
514 }
515#ifdef DUMP_MSG
516 dprintk("--> %02x %d ", id, len + 1);
517 for (i = 0; i < len; i++)
518 dprintk("%04x ", data[i]);
519 dprintk("\n");
520#endif
521
522 /* byte-order conversion - works on big (where it is not necessary) or little endian */
523 d = (u8 *) data;
524 for (i = 0; i < len; i++) {
525 tmp = data[i];
526 *d++ = tmp >> 8;
527 *d++ = tmp & 0xff;
528 }
529
530 /* write msg */
531 b[0] = id;
532 b[1] = len + 1;
533 if (dib9000_write16_noinc_attr(state, 1045, b, 2, attr) != 0 || dib9000_write16_noinc_attr(state, 1045, (u8 *) data, len * 2, attr) != 0) {
534 ret = -EIO;
535 goto out;
536 }
537
538 /* update register nb_mes_in_RX */
539 ret = (u8) dib9000_write_word_attr(state, 1043, 1 << 14, attr);
540
541out:
542 DibReleaseLock(&state->platform.risc.mbx_if_lock);
543
544 return ret;
545}
546
547static u8 dib9000_mbx_read(struct dib9000_state *state, u16 * data, u8 risc_id, u16 attr)
548{
549#ifdef DUMP_MSG
550 u16 *d = data;
551#endif
552
553 u16 tmp, i;
554 u8 size;
555 u8 mc_base;
556
557 if (!state->platform.risc.fw_is_running)
558 return 0;
559
560 DibAcquireLock(&state->platform.risc.mbx_if_lock);
561 if (risc_id == 1)
562 mc_base = 16;
563 else
564 mc_base = 0;
565
566 /* Length and type in the first word */
567 *data = dib9000_read_word_attr(state, 1029 + mc_base, attr);
568
569 size = *data & 0xff;
570 if (size <= MBX_MAX_WORDS) {
571 data++;
572 size--; /* Initial word already read */
573
574 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, size * 2, attr);
575
576 /* to word conversion */
577 for (i = 0; i < size; i++) {
578 tmp = *data;
579 *data = (tmp >> 8) | (tmp << 8);
580 data++;
581 }
582
583#ifdef DUMP_MSG
584 dprintk("<-- ");
585 for (i = 0; i < size + 1; i++)
586 dprintk("%04x ", d[i]);
587 dprintk("\n");
588#endif
589 } else {
590 dprintk("MBX: message is too big for message cache (%d), flushing message", size);
591 size--; /* Initial word already read */
592 while (size--)
593 dib9000_read16_noinc_attr(state, 1029 + mc_base, (u8 *) data, 2, attr);
594 }
595 /* Update register nb_mes_in_TX */
596 dib9000_write_word_attr(state, 1028 + mc_base, 1 << 14, attr);
597
598 DibReleaseLock(&state->platform.risc.mbx_if_lock);
599
600 return size + 1;
601}
602
603static int dib9000_risc_debug_buf(struct dib9000_state *state, u16 * data, u8 size)
604{
605 u32 ts = data[1] << 16 | data[0];
606 char *b = (char *)&data[2];
607
608 b[2 * (size - 2) - 1] = '\0'; /* Bullet proof the buffer */
609 if (*b == '~') {
610 b++;
611 dprintk(b);
612 } else
613 dprintk("RISC%d: %d.%04d %s", state->fe_id, ts / 10000, ts % 10000, *b ? b : "<emtpy>");
614 return 1;
615}
616
617static int dib9000_mbx_fetch_to_cache(struct dib9000_state *state, u16 attr)
618{
619 int i;
620 u8 size;
621 u16 *block;
622 /* find a free slot */
623 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
624 block = state->platform.risc.message_cache[i];
625 if (*block == 0) {
626 size = dib9000_mbx_read(state, block, 1, attr);
627
628/* dprintk( "MBX: fetched %04x message to cache", *block); */
629
630 switch (*block >> 8) {
631 case IN_MSG_DEBUG_BUF:
632 dib9000_risc_debug_buf(state, block + 1, size); /* debug-messages are going to be printed right away */
633 *block = 0; /* free the block */
634 break;
635#if 0
636 case IN_MSG_DATA: /* FE-TRACE */
637 dib9000_risc_data_process(state, block + 1, size);
638 *block = 0;
639 break;
640#endif
641 default:
642 break;
643 }
644
645 return 1;
646 }
647 }
648 dprintk("MBX: no free cache-slot found for new message...");
649 return -1;
650}
651
652static u8 dib9000_mbx_count(struct dib9000_state *state, u8 risc_id, u16 attr)
653{
654 if (risc_id == 0)
655 return (u8) (dib9000_read_word_attr(state, 1028, attr) >> 10) & 0x1f; /* 5 bit field */
656 else
657 return (u8) (dib9000_read_word_attr(state, 1044, attr) >> 8) & 0x7f; /* 7 bit field */
658}
659
660static int dib9000_mbx_process(struct dib9000_state *state, u16 attr)
661{
662 int ret = 0;
663 u16 tmp;
664
665 if (!state->platform.risc.fw_is_running)
666 return -1;
667
668 DibAcquireLock(&state->platform.risc.mbx_lock);
669
670 if (dib9000_mbx_count(state, 1, attr)) /* 1=RiscB */
671 ret = dib9000_mbx_fetch_to_cache(state, attr);
672
673 tmp = dib9000_read_word_attr(state, 1229, attr); /* Clear the IRQ */
674/* if (tmp) */
675/* dprintk( "cleared IRQ: %x", tmp); */
676 DibReleaseLock(&state->platform.risc.mbx_lock);
677
678 return ret;
679}
680
681static int dib9000_mbx_get_message_attr(struct dib9000_state *state, u16 id, u16 * msg, u8 * size, u16 attr)
682{
683 u8 i;
684 u16 *block;
685 u16 timeout = 30;
686
687 *msg = 0;
688 do {
689 /* dib9000_mbx_get_from_cache(); */
690 for (i = 0; i < DIB9000_MSG_CACHE_SIZE; i++) {
691 block = state->platform.risc.message_cache[i];
692 if ((*block >> 8) == id) {
693 *size = (*block & 0xff) - 1;
694 memcpy(msg, block + 1, (*size) * 2);
695 *block = 0; /* free the block */
696 i = 0; /* signal that we found a message */
697 break;
698 }
699 }
700
701 if (i == 0)
702 break;
703
704 if (dib9000_mbx_process(state, attr) == -1) /* try to fetch one message - if any */
705 return -1;
706
707 } while (--timeout);
708
709 if (timeout == 0) {
710 dprintk("waiting for message %d timed out", id);
711 return -1;
712 }
713
714 return i == 0;
715}
716
717static int dib9000_risc_check_version(struct dib9000_state *state)
718{
719 u8 r[4];
720 u8 size;
721 u16 fw_version = 0;
722
723 if (dib9000_mbx_send(state, OUT_MSG_REQ_VERSION, &fw_version, 1) != 0)
724 return -EIO;
725
726 if (dib9000_mbx_get_message(state, IN_MSG_VERSION, (u16 *) r, &size) < 0)
727 return -EIO;
728
729 fw_version = (r[0] << 8) | r[1];
730 dprintk("RISC: ver: %d.%02d (IC: %d)", fw_version >> 10, fw_version & 0x3ff, (r[2] << 8) | r[3]);
731
732 if ((fw_version >> 10) != 7)
733 return -EINVAL;
734
735 switch (fw_version & 0x3ff) {
736 case 11:
737 case 12:
738 case 14:
739 case 15:
740 case 16:
741 case 17:
742 break;
743 default:
744 dprintk("RISC: invalid firmware version");
745 return -EINVAL;
746 }
747
748 dprintk("RISC: valid firmware version");
749 return 0;
750}
751
752static int dib9000_fw_boot(struct dib9000_state *state, const u8 * codeA, u32 lenA, const u8 * codeB, u32 lenB)
753{
754 /* Reconfig pool mac ram */
755 dib9000_write_word(state, 1225, 0x02); /* A: 8k C, 4 k D - B: 32k C 6 k D - IRAM 96k */
756 dib9000_write_word(state, 1226, 0x05);
757
758 /* Toggles IP crypto to Host APB interface. */
759 dib9000_write_word(state, 1542, 1);
760
761 /* Set jump and no jump in the dma box */
762 dib9000_write_word(state, 1074, 0);
763 dib9000_write_word(state, 1075, 0);
764
765 /* Set MAC as APB Master. */
766 dib9000_write_word(state, 1237, 0);
767
768 /* Reset the RISCs */
769 if (codeA != NULL)
770 dib9000_write_word(state, 1024, 2);
771 else
772 dib9000_write_word(state, 1024, 15);
773 if (codeB != NULL)
774 dib9000_write_word(state, 1040, 2);
775
776 if (codeA != NULL)
777 dib9000_firmware_download(state, 0, 0x1234, codeA, lenA);
778 if (codeB != NULL)
779 dib9000_firmware_download(state, 1, 0x1234, codeB, lenB);
780
781 /* Run the RISCs */
782 if (codeA != NULL)
783 dib9000_write_word(state, 1024, 0);
784 if (codeB != NULL)
785 dib9000_write_word(state, 1040, 0);
786
787 if (codeA != NULL)
788 if (dib9000_mbx_host_init(state, 0) != 0)
789 return -EIO;
790 if (codeB != NULL)
791 if (dib9000_mbx_host_init(state, 1) != 0)
792 return -EIO;
793
794 msleep(100);
795 state->platform.risc.fw_is_running = 1;
796
797 if (dib9000_risc_check_version(state) != 0)
798 return -EINVAL;
799
800 state->platform.risc.memcmd = 0xff;
801 return 0;
802}
803
804static u16 dib9000_identify(struct i2c_device *client)
805{
806 u16 value;
807
808 value = dib9000_i2c_read16(client, 896);
809 if (value != 0x01b3) {
810 dprintk("wrong Vendor ID (0x%x)", value);
811 return 0;
812 }
813
814 value = dib9000_i2c_read16(client, 897);
815 if (value != 0x4000 && value != 0x4001 && value != 0x4002 && value != 0x4003 && value != 0x4004 && value != 0x4005) {
816 dprintk("wrong Device ID (0x%x)", value);
817 return 0;
818 }
819
820 /* protect this driver to be used with 7000PC */
821 if (value == 0x4000 && dib9000_i2c_read16(client, 769) == 0x4000) {
822 dprintk("this driver does not work with DiB7000PC");
823 return 0;
824 }
825
826 switch (value) {
827 case 0x4000:
828 dprintk("found DiB7000MA/PA/MB/PB");
829 break;
830 case 0x4001:
831 dprintk("found DiB7000HC");
832 break;
833 case 0x4002:
834 dprintk("found DiB7000MC");
835 break;
836 case 0x4003:
837 dprintk("found DiB9000A");
838 break;
839 case 0x4004:
840 dprintk("found DiB9000H");
841 break;
842 case 0x4005:
843 dprintk("found DiB9000M");
844 break;
845 }
846
847 return value;
848}
849
850static void dib9000_set_power_mode(struct dib9000_state *state, enum dib9000_power_mode mode)
851{
852 /* by default everything is going to be powered off */
853 u16 reg_903 = 0x3fff, reg_904 = 0xffff, reg_905 = 0xffff, reg_906;
854 u8 offset;
855
856 if (state->revision == 0x4003 || state->revision == 0x4004 || state->revision == 0x4005)
857 offset = 1;
858 else
859 offset = 0;
860
861 reg_906 = dib9000_read_word(state, 906 + offset) | 0x3; /* keep settings for RISC */
862
863 /* now, depending on the requested mode, we power on */
864 switch (mode) {
865 /* power up everything in the demod */
866 case DIB9000_POWER_ALL:
867 reg_903 = 0x0000;
868 reg_904 = 0x0000;
869 reg_905 = 0x0000;
870 reg_906 = 0x0000;
871 break;
872
873 /* just leave power on the control-interfaces: GPIO and (I2C or SDIO or SRAM) */
874 case DIB9000_POWER_INTERFACE_ONLY: /* TODO power up either SDIO or I2C or SRAM */
875 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 2));
876 break;
877
878 case DIB9000_POWER_INTERF_ANALOG_AGC:
879 reg_903 &= ~((1 << 15) | (1 << 14) | (1 << 11) | (1 << 10));
880 reg_905 &= ~((1 << 7) | (1 << 6) | (1 << 5) | (1 << 4) | (1 << 2));
881 reg_906 &= ~((1 << 0));
882 break;
883
884 case DIB9000_POWER_COR4_DINTLV_ICIRM_EQUAL_CFROD:
885 reg_903 = 0x0000;
886 reg_904 = 0x801f;
887 reg_905 = 0x0000;
888 reg_906 &= ~((1 << 0));
889 break;
890
891 case DIB9000_POWER_COR4_CRY_ESRAM_MOUT_NUD:
892 reg_903 = 0x0000;
893 reg_904 = 0x8000;
894 reg_905 = 0x010b;
895 reg_906 &= ~((1 << 0));
896 break;
897 default:
898 case DIB9000_POWER_NO:
899 break;
900 }
901
902 /* always power down unused parts */
903 if (!state->platform.host.mobile_mode)
904 reg_904 |= (1 << 7) | (1 << 6) | (1 << 4) | (1 << 2) | (1 << 1);
905
906 /* P_sdio_select_clk = 0 on MC and after */
907 if (state->revision != 0x4000)
908 reg_906 <<= 1;
909
910 dib9000_write_word(state, 903 + offset, reg_903);
911 dib9000_write_word(state, 904 + offset, reg_904);
912 dib9000_write_word(state, 905 + offset, reg_905);
913 dib9000_write_word(state, 906 + offset, reg_906);
914}
915
916static int dib9000_fw_reset(struct dvb_frontend *fe)
917{
918 struct dib9000_state *state = fe->demodulator_priv;
919
920 dib9000_write_word(state, 1817, 0x0003);
921
922 dib9000_write_word(state, 1227, 1);
923 dib9000_write_word(state, 1227, 0);
924
925 switch ((state->revision = dib9000_identify(&state->i2c))) {
926 case 0x4003:
927 case 0x4004:
928 case 0x4005:
929 state->reg_offs = 1;
930 break;
931 default:
932 return -EINVAL;
933 }
934
935 /* reset the i2c-master to use the host interface */
936 dibx000_reset_i2c_master(&state->i2c_master);
937
938 dib9000_set_power_mode(state, DIB9000_POWER_ALL);
939
940 /* unforce divstr regardless whether i2c enumeration was done or not */
941 dib9000_write_word(state, 1794, dib9000_read_word(state, 1794) & ~(1 << 1));
942 dib9000_write_word(state, 1796, 0);
943 dib9000_write_word(state, 1805, 0x805);
944
945 /* restart all parts */
946 dib9000_write_word(state, 898, 0xffff);
947 dib9000_write_word(state, 899, 0xffff);
948 dib9000_write_word(state, 900, 0x0001);
949 dib9000_write_word(state, 901, 0xff19);
950 dib9000_write_word(state, 902, 0x003c);
951
952 dib9000_write_word(state, 898, 0);
953 dib9000_write_word(state, 899, 0);
954 dib9000_write_word(state, 900, 0);
955 dib9000_write_word(state, 901, 0);
956 dib9000_write_word(state, 902, 0);
957
958 dib9000_write_word(state, 911, state->chip.d9.cfg.if_drives);
959
960 dib9000_set_power_mode(state, DIB9000_POWER_INTERFACE_ONLY);
961
962 return 0;
963}
964
965static int dib9000_risc_apb_access_read(struct dib9000_state *state, u32 address, u16 attribute, const u8 * tx, u32 txlen, u8 * b, u32 len)
966{
967 u16 mb[10];
968 u8 i, s;
969
970 if (address >= 1024 || !state->platform.risc.fw_is_running)
971 return -EINVAL;
972
973 /* dprintk( "APB access thru rd fw %d %x", address, attribute); */
974
975 mb[0] = (u16) address;
976 mb[1] = len / 2;
977 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_R, mb, 2, attribute);
978 switch (dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute)) {
979 case 1:
980 s--;
981 for (i = 0; i < s; i++) {
982 b[i * 2] = (mb[i + 1] >> 8) & 0xff;
983 b[i * 2 + 1] = (mb[i + 1]) & 0xff;
984 }
985 return 0;
986 default:
987 return -EIO;
988 }
989 return -EIO;
990}
991
992static int dib9000_risc_apb_access_write(struct dib9000_state *state, u32 address, u16 attribute, const u8 * b, u32 len)
993{
994 u16 mb[10];
995 u8 s, i;
996
997 if (address >= 1024 || !state->platform.risc.fw_is_running)
998 return -EINVAL;
999
1000 /* dprintk( "APB access thru wr fw %d %x", address, attribute); */
1001
1002 mb[0] = (unsigned short)address;
1003 for (i = 0; i < len && i < 20; i += 2)
1004 mb[1 + (i / 2)] = (b[i] << 8 | b[i + 1]);
1005
1006 dib9000_mbx_send_attr(state, OUT_MSG_BRIDGE_APB_W, mb, 1 + len / 2, attribute);
1007 return dib9000_mbx_get_message_attr(state, IN_MSG_END_BRIDGE_APB_RW, mb, &s, attribute) == 1 ? 0 : -EINVAL;
1008}
1009
1010static int dib9000_fw_memmbx_sync(struct dib9000_state *state, u8 i)
1011{
1012 u8 index_loop = 10;
1013
1014 if (!state->platform.risc.fw_is_running)
1015 return 0;
1016 dib9000_risc_mem_write(state, FE_MM_RW_SYNC, &i);
1017 do {
1018 dib9000_risc_mem_read(state, FE_MM_RW_SYNC, &i, 1);
1019 } while (i && index_loop--);
1020
1021 if (index_loop > 0)
1022 return 0;
1023 return -EIO;
1024}
1025
1026static int dib9000_fw_init(struct dib9000_state *state)
1027{
1028 struct dibGPIOFunction *f;
1029 u16 b[40] = { 0 };
1030 u8 i;
1031 u8 size;
1032
1033 if (dib9000_fw_boot(state, NULL, 0, state->chip.d9.cfg.microcode_B_fe_buffer, state->chip.d9.cfg.microcode_B_fe_size) != 0)
1034 return -EIO;
1035
1036 /* initialize the firmware */
1037 for (i = 0; i < ARRAY_SIZE(state->chip.d9.cfg.gpio_function); i++) {
1038 f = &state->chip.d9.cfg.gpio_function[i];
1039 if (f->mask) {
1040 switch (f->function) {
1041 case BOARD_GPIO_FUNCTION_COMPONENT_ON:
1042 b[0] = (u16) f->mask;
1043 b[1] = (u16) f->direction;
1044 b[2] = (u16) f->value;
1045 break;
1046 case BOARD_GPIO_FUNCTION_COMPONENT_OFF:
1047 b[3] = (u16) f->mask;
1048 b[4] = (u16) f->direction;
1049 b[5] = (u16) f->value;
1050 break;
1051 }
1052 }
1053 }
1054 if (dib9000_mbx_send(state, OUT_MSG_CONF_GPIO, b, 15) != 0)
1055 return -EIO;
1056
1057 /* subband */
1058 b[0] = state->chip.d9.cfg.subband.size; /* type == 0 -> GPIO - PWM not yet supported */
1059 for (i = 0; i < state->chip.d9.cfg.subband.size; i++) {
1060 b[1 + i * 4] = state->chip.d9.cfg.subband.subband[i].f_mhz;
1061 b[2 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.mask;
1062 b[3 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.direction;
1063 b[4 + i * 4] = (u16) state->chip.d9.cfg.subband.subband[i].gpio.value;
1064 }
1065 b[1 + i * 4] = 0; /* fe_id */
1066 if (dib9000_mbx_send(state, OUT_MSG_SUBBAND_SEL, b, 2 + 4 * i) != 0)
1067 return -EIO;
1068
1069 /* 0 - id, 1 - no_of_frontends */
1070 b[0] = (0 << 8) | 1;
1071 /* 0 = i2c-address demod, 0 = tuner */
1072 b[1] = (0 << 8) | (0);
1073 b[2] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000) >> 16) & 0xffff);
1074 b[3] = (u16) (((state->chip.d9.cfg.xtal_clock_khz * 1000)) & 0xffff);
1075 b[4] = (u16) ((state->chip.d9.cfg.vcxo_timer >> 16) & 0xffff);
1076 b[5] = (u16) ((state->chip.d9.cfg.vcxo_timer) & 0xffff);
1077 b[6] = (u16) ((state->chip.d9.cfg.timing_frequency >> 16) & 0xffff);
1078 b[7] = (u16) ((state->chip.d9.cfg.timing_frequency) & 0xffff);
1079 b[29] = state->chip.d9.cfg.if_drives;
1080 if (dib9000_mbx_send(state, OUT_MSG_INIT_DEMOD, b, ARRAY_SIZE(b)) != 0)
1081 return -EIO;
1082
1083 if (dib9000_mbx_send(state, OUT_MSG_FE_FW_DL, NULL, 0) != 0)
1084 return -EIO;
1085
1086 if (dib9000_mbx_get_message(state, IN_MSG_FE_FW_DL_DONE, b, &size) < 0)
1087 return -EIO;
1088
1089 if (size > ARRAY_SIZE(b)) {
1090 dprintk("error : firmware returned %dbytes needed but the used buffer has only %dbytes\n Firmware init ABORTED", size,
1091 (int)ARRAY_SIZE(b));
1092 return -EINVAL;
1093 }
1094
1095 for (i = 0; i < size; i += 2) {
1096 state->platform.risc.fe_mm[i / 2].addr = b[i + 0];
1097 state->platform.risc.fe_mm[i / 2].size = b[i + 1];
1098 }
1099
1100 return 0;
1101}
1102
1103static void dib9000_fw_set_channel_head(struct dib9000_state *state, struct dvb_frontend_parameters *ch)
1104{
1105 u8 b[9];
1106 u32 freq = state->fe[0]->dtv_property_cache.frequency / 1000;
1107 if (state->fe_id % 2)
1108 freq += 101;
1109
1110 b[0] = (u8) ((freq >> 0) & 0xff);
1111 b[1] = (u8) ((freq >> 8) & 0xff);
1112 b[2] = (u8) ((freq >> 16) & 0xff);
1113 b[3] = (u8) ((freq >> 24) & 0xff);
1114 b[4] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 0) & 0xff);
1115 b[5] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 8) & 0xff);
1116 b[6] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 16) & 0xff);
1117 b[7] = (u8) ((state->fe[0]->dtv_property_cache.bandwidth_hz / 1000 >> 24) & 0xff);
1118 b[8] = 0x80; /* do not wait for CELL ID when doing autosearch */
1119 if (state->fe[0]->dtv_property_cache.delivery_system == SYS_DVBT)
1120 b[8] |= 1;
1121 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_HEAD, b);
1122}
1123
1124static int dib9000_fw_get_channel(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel)
1125{
1126 struct dib9000_state *state = fe->demodulator_priv;
1127 struct dibDVBTChannel {
1128 s8 spectrum_inversion;
1129
1130 s8 nfft;
1131 s8 guard;
1132 s8 constellation;
1133
1134 s8 hrch;
1135 s8 alpha;
1136 s8 code_rate_hp;
1137 s8 code_rate_lp;
1138 s8 select_hp;
1139
1140 s8 intlv_native;
1141 };
1142 struct dibDVBTChannel ch;
1143 int ret = 0;
1144
1145 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
1146 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0) {
1147 goto error;
1148 ret = -EIO;
1149 }
1150
1151 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_UNION, (u8 *) &ch, sizeof(struct dibDVBTChannel));
1152
1153 switch (ch.spectrum_inversion & 0x7) {
1154 case 1:
1155 state->fe[0]->dtv_property_cache.inversion = INVERSION_ON;
1156 break;
1157 case 0:
1158 state->fe[0]->dtv_property_cache.inversion = INVERSION_OFF;
1159 break;
1160 default:
1161 case -1:
1162 state->fe[0]->dtv_property_cache.inversion = INVERSION_AUTO;
1163 break;
1164 }
1165 switch (ch.nfft) {
1166 case 0:
1167 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_2K;
1168 break;
1169 case 2:
1170 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_4K;
1171 break;
1172 case 1:
1173 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_8K;
1174 break;
1175 default:
1176 case -1:
1177 state->fe[0]->dtv_property_cache.transmission_mode = TRANSMISSION_MODE_AUTO;
1178 break;
1179 }
1180 switch (ch.guard) {
1181 case 0:
1182 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_32;
1183 break;
1184 case 1:
1185 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_16;
1186 break;
1187 case 2:
1188 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_8;
1189 break;
1190 case 3:
1191 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_1_4;
1192 break;
1193 default:
1194 case -1:
1195 state->fe[0]->dtv_property_cache.guard_interval = GUARD_INTERVAL_AUTO;
1196 break;
1197 }
1198 switch (ch.constellation) {
1199 case 2:
1200 state->fe[0]->dtv_property_cache.modulation = QAM_64;
1201 break;
1202 case 1:
1203 state->fe[0]->dtv_property_cache.modulation = QAM_16;
1204 break;
1205 case 0:
1206 state->fe[0]->dtv_property_cache.modulation = QPSK;
1207 break;
1208 default:
1209 case -1:
1210 state->fe[0]->dtv_property_cache.modulation = QAM_AUTO;
1211 break;
1212 }
1213 switch (ch.hrch) {
1214 case 0:
1215 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_NONE;
1216 break;
1217 case 1:
1218 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_1;
1219 break;
1220 default:
1221 case -1:
1222 state->fe[0]->dtv_property_cache.hierarchy = HIERARCHY_AUTO;
1223 break;
1224 }
1225 switch (ch.code_rate_hp) {
1226 case 1:
1227 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_1_2;
1228 break;
1229 case 2:
1230 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_2_3;
1231 break;
1232 case 3:
1233 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_3_4;
1234 break;
1235 case 5:
1236 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_5_6;
1237 break;
1238 case 7:
1239 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_7_8;
1240 break;
1241 default:
1242 case -1:
1243 state->fe[0]->dtv_property_cache.code_rate_HP = FEC_AUTO;
1244 break;
1245 }
1246 switch (ch.code_rate_lp) {
1247 case 1:
1248 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_1_2;
1249 break;
1250 case 2:
1251 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_2_3;
1252 break;
1253 case 3:
1254 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_3_4;
1255 break;
1256 case 5:
1257 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_5_6;
1258 break;
1259 case 7:
1260 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_7_8;
1261 break;
1262 default:
1263 case -1:
1264 state->fe[0]->dtv_property_cache.code_rate_LP = FEC_AUTO;
1265 break;
1266 }
1267
1268error:
1269 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1270 return ret;
1271}
1272
1273static int dib9000_fw_set_channel_union(struct dvb_frontend *fe, struct dvb_frontend_parameters *channel)
1274{
1275 struct dib9000_state *state = fe->demodulator_priv;
1276 struct dibDVBTChannel {
1277 s8 spectrum_inversion;
1278
1279 s8 nfft;
1280 s8 guard;
1281 s8 constellation;
1282
1283 s8 hrch;
1284 s8 alpha;
1285 s8 code_rate_hp;
1286 s8 code_rate_lp;
1287 s8 select_hp;
1288
1289 s8 intlv_native;
1290 };
1291 struct dibDVBTChannel ch;
1292
1293 switch (state->fe[0]->dtv_property_cache.inversion) {
1294 case INVERSION_ON:
1295 ch.spectrum_inversion = 1;
1296 break;
1297 case INVERSION_OFF:
1298 ch.spectrum_inversion = 0;
1299 break;
1300 default:
1301 case INVERSION_AUTO:
1302 ch.spectrum_inversion = -1;
1303 break;
1304 }
1305 switch (state->fe[0]->dtv_property_cache.transmission_mode) {
1306 case TRANSMISSION_MODE_2K:
1307 ch.nfft = 0;
1308 break;
1309 case TRANSMISSION_MODE_4K:
1310 ch.nfft = 2;
1311 break;
1312 case TRANSMISSION_MODE_8K:
1313 ch.nfft = 1;
1314 break;
1315 default:
1316 case TRANSMISSION_MODE_AUTO:
1317 ch.nfft = 1;
1318 break;
1319 }
1320 switch (state->fe[0]->dtv_property_cache.guard_interval) {
1321 case GUARD_INTERVAL_1_32:
1322 ch.guard = 0;
1323 break;
1324 case GUARD_INTERVAL_1_16:
1325 ch.guard = 1;
1326 break;
1327 case GUARD_INTERVAL_1_8:
1328 ch.guard = 2;
1329 break;
1330 case GUARD_INTERVAL_1_4:
1331 ch.guard = 3;
1332 break;
1333 default:
1334 case GUARD_INTERVAL_AUTO:
1335 ch.guard = -1;
1336 break;
1337 }
1338 switch (state->fe[0]->dtv_property_cache.modulation) {
1339 case QAM_64:
1340 ch.constellation = 2;
1341 break;
1342 case QAM_16:
1343 ch.constellation = 1;
1344 break;
1345 case QPSK:
1346 ch.constellation = 0;
1347 break;
1348 default:
1349 case QAM_AUTO:
1350 ch.constellation = -1;
1351 break;
1352 }
1353 switch (state->fe[0]->dtv_property_cache.hierarchy) {
1354 case HIERARCHY_NONE:
1355 ch.hrch = 0;
1356 break;
1357 case HIERARCHY_1:
1358 case HIERARCHY_2:
1359 case HIERARCHY_4:
1360 ch.hrch = 1;
1361 break;
1362 default:
1363 case HIERARCHY_AUTO:
1364 ch.hrch = -1;
1365 break;
1366 }
1367 ch.alpha = 1;
1368 switch (state->fe[0]->dtv_property_cache.code_rate_HP) {
1369 case FEC_1_2:
1370 ch.code_rate_hp = 1;
1371 break;
1372 case FEC_2_3:
1373 ch.code_rate_hp = 2;
1374 break;
1375 case FEC_3_4:
1376 ch.code_rate_hp = 3;
1377 break;
1378 case FEC_5_6:
1379 ch.code_rate_hp = 5;
1380 break;
1381 case FEC_7_8:
1382 ch.code_rate_hp = 7;
1383 break;
1384 default:
1385 case FEC_AUTO:
1386 ch.code_rate_hp = -1;
1387 break;
1388 }
1389 switch (state->fe[0]->dtv_property_cache.code_rate_LP) {
1390 case FEC_1_2:
1391 ch.code_rate_lp = 1;
1392 break;
1393 case FEC_2_3:
1394 ch.code_rate_lp = 2;
1395 break;
1396 case FEC_3_4:
1397 ch.code_rate_lp = 3;
1398 break;
1399 case FEC_5_6:
1400 ch.code_rate_lp = 5;
1401 break;
1402 case FEC_7_8:
1403 ch.code_rate_lp = 7;
1404 break;
1405 default:
1406 case FEC_AUTO:
1407 ch.code_rate_lp = -1;
1408 break;
1409 }
1410 ch.select_hp = 1;
1411 ch.intlv_native = 1;
1412
1413 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_UNION, (u8 *) &ch);
1414
1415 return 0;
1416}
1417
1418static int dib9000_fw_tune(struct dvb_frontend *fe, struct dvb_frontend_parameters *ch)
1419{
1420 struct dib9000_state *state = fe->demodulator_priv;
1421 int ret = 10, search = state->channel_status.status == CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1422 s8 i;
1423
1424 switch (state->tune_state) {
1425 case CT_DEMOD_START:
1426 dib9000_fw_set_channel_head(state, ch);
1427
1428 /* write the channel context - a channel is initialized to 0, so it is OK */
1429 dib9000_risc_mem_write(state, FE_MM_W_CHANNEL_CONTEXT, (u8 *) fe_info);
1430 dib9000_risc_mem_write(state, FE_MM_W_FE_INFO, (u8 *) fe_info);
1431
1432 if (search)
1433 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_SEARCH, NULL, 0);
1434 else {
1435 dib9000_fw_set_channel_union(fe, ch);
1436 dib9000_mbx_send(state, OUT_MSG_FE_CHANNEL_TUNE, NULL, 0);
1437 }
1438 state->tune_state = CT_DEMOD_STEP_1;
1439 break;
1440 case CT_DEMOD_STEP_1:
1441 if (search)
1442 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_SEARCH_STATE, (u8 *) &i, 1);
1443 else
1444 dib9000_risc_mem_read(state, FE_MM_R_CHANNEL_TUNE_STATE, (u8 *) &i, 1);
1445 switch (i) { /* something happened */
1446 case 0:
1447 break;
1448 case -2: /* tps locks are "slower" than MPEG locks -> even in autosearch data is OK here */
1449 if (search)
1450 state->status = FE_STATUS_DEMOD_SUCCESS;
1451 else {
1452 state->tune_state = CT_DEMOD_STOP;
1453 state->status = FE_STATUS_LOCKED;
1454 }
1455 break;
1456 default:
1457 state->status = FE_STATUS_TUNE_FAILED;
1458 state->tune_state = CT_DEMOD_STOP;
1459 break;
1460 }
1461 break;
1462 default:
1463 ret = FE_CALLBACK_TIME_NEVER;
1464 break;
1465 }
1466
1467 return ret;
1468}
1469
1470static int dib9000_fw_set_diversity_in(struct dvb_frontend *fe, int onoff)
1471{
1472 struct dib9000_state *state = fe->demodulator_priv;
1473 u16 mode = (u16) onoff;
1474 return dib9000_mbx_send(state, OUT_MSG_ENABLE_DIVERSITY, &mode, 1);
1475}
1476
1477static int dib9000_fw_set_output_mode(struct dvb_frontend *fe, int mode)
1478{
1479 struct dib9000_state *state = fe->demodulator_priv;
1480 u16 outreg, smo_mode;
1481
1482 dprintk("setting output mode for demod %p to %d", fe, mode);
1483
1484 switch (mode) {
1485 case OUTMODE_MPEG2_PAR_GATED_CLK:
1486 outreg = (1 << 10); /* 0x0400 */
1487 break;
1488 case OUTMODE_MPEG2_PAR_CONT_CLK:
1489 outreg = (1 << 10) | (1 << 6); /* 0x0440 */
1490 break;
1491 case OUTMODE_MPEG2_SERIAL:
1492 outreg = (1 << 10) | (2 << 6) | (0 << 1); /* 0x0482 */
1493 break;
1494 case OUTMODE_DIVERSITY:
1495 outreg = (1 << 10) | (4 << 6); /* 0x0500 */
1496 break;
1497 case OUTMODE_MPEG2_FIFO:
1498 outreg = (1 << 10) | (5 << 6);
1499 break;
1500 case OUTMODE_HIGH_Z:
1501 outreg = 0;
1502 break;
1503 default:
1504 dprintk("Unhandled output_mode passed to be set for demod %p", &state->fe[0]);
1505 return -EINVAL;
1506 }
1507
1508 dib9000_write_word(state, 1795, outreg);
1509
1510 switch (mode) {
1511 case OUTMODE_MPEG2_PAR_GATED_CLK:
1512 case OUTMODE_MPEG2_PAR_CONT_CLK:
1513 case OUTMODE_MPEG2_SERIAL:
1514 case OUTMODE_MPEG2_FIFO:
1515 smo_mode = (dib9000_read_word(state, 295) & 0x0010) | (1 << 1);
1516 if (state->chip.d9.cfg.output_mpeg2_in_188_bytes)
1517 smo_mode |= (1 << 5);
1518 dib9000_write_word(state, 295, smo_mode);
1519 break;
1520 }
1521
1522 outreg = to_fw_output_mode(mode);
1523 return dib9000_mbx_send(state, OUT_MSG_SET_OUTPUT_MODE, &outreg, 1);
1524}
1525
1526static int dib9000_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1527{
1528 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1529 u16 i, len, t, index_msg;
1530
1531 for (index_msg = 0; index_msg < num; index_msg++) {
1532 if (msg[index_msg].flags & I2C_M_RD) { /* read */
1533 len = msg[index_msg].len;
1534 if (len > 16)
1535 len = 16;
1536
1537 if (dib9000_read_word(state, 790) != 0)
1538 dprintk("TunerITF: read busy");
1539
1540 dib9000_write_word(state, 784, (u16) (msg[index_msg].addr));
1541 dib9000_write_word(state, 787, (len / 2) - 1);
1542 dib9000_write_word(state, 786, 1); /* start read */
1543
1544 i = 1000;
1545 while (dib9000_read_word(state, 790) != (len / 2) && i)
1546 i--;
1547
1548 if (i == 0)
1549 dprintk("TunerITF: read failed");
1550
1551 for (i = 0; i < len; i += 2) {
1552 t = dib9000_read_word(state, 785);
1553 msg[index_msg].buf[i] = (t >> 8) & 0xff;
1554 msg[index_msg].buf[i + 1] = (t) & 0xff;
1555 }
1556 if (dib9000_read_word(state, 790) != 0)
1557 dprintk("TunerITF: read more data than expected");
1558 } else {
1559 i = 1000;
1560 while (dib9000_read_word(state, 789) && i)
1561 i--;
1562 if (i == 0)
1563 dprintk("TunerITF: write busy");
1564
1565 len = msg[index_msg].len;
1566 if (len > 16)
1567 len = 16;
1568
1569 for (i = 0; i < len; i += 2)
1570 dib9000_write_word(state, 785, (msg[index_msg].buf[i] << 8) | msg[index_msg].buf[i + 1]);
1571 dib9000_write_word(state, 784, (u16) msg[index_msg].addr);
1572 dib9000_write_word(state, 787, (len / 2) - 1);
1573 dib9000_write_word(state, 786, 0); /* start write */
1574
1575 i = 1000;
1576 while (dib9000_read_word(state, 791) > 0 && i)
1577 i--;
1578 if (i == 0)
1579 dprintk("TunerITF: write failed");
1580 }
1581 }
1582 return num;
1583}
1584
1585int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
1586{
1587 struct dib9000_state *state = fe->demodulator_priv;
1588
1589 state->component_bus_speed = speed;
1590 return 0;
1591}
1592EXPORT_SYMBOL(dib9000_fw_set_component_bus_speed);
1593
1594static int dib9000_fw_component_bus_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
1595{
1596 struct dib9000_state *state = i2c_get_adapdata(i2c_adap);
1597 u8 type = 0; /* I2C */
1598 u8 port = DIBX000_I2C_INTERFACE_GPIO_3_4;
1599 u16 scl = state->component_bus_speed; /* SCL frequency */
1600 struct dib9000_fe_memory_map *m = &state->platform.risc.fe_mm[FE_MM_RW_COMPONENT_ACCESS_BUFFER];
1601 u8 p[13] = { 0 };
1602
1603 p[0] = type;
1604 p[1] = port;
1605 p[2] = msg[0].addr << 1;
1606
1607 p[3] = (u8) scl & 0xff; /* scl */
1608 p[4] = (u8) (scl >> 8);
1609
1610 p[7] = 0;
1611 p[8] = 0;
1612
1613 p[9] = (u8) (msg[0].len);
1614 p[10] = (u8) (msg[0].len >> 8);
1615 if ((num > 1) && (msg[1].flags & I2C_M_RD)) {
1616 p[11] = (u8) (msg[1].len);
1617 p[12] = (u8) (msg[1].len >> 8);
1618 } else {
1619 p[11] = 0;
1620 p[12] = 0;
1621 }
1622
1623 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
1624
1625 dib9000_risc_mem_write(state, FE_MM_W_COMPONENT_ACCESS, p);
1626
1627 { /* write-part */
1628 dib9000_risc_mem_setup_cmd(state, m->addr, msg[0].len, 0);
1629 dib9000_risc_mem_write_chunks(state, msg[0].buf, msg[0].len);
1630 }
1631
1632 /* do the transaction */
1633 if (dib9000_fw_memmbx_sync(state, FE_SYNC_COMPONENT_ACCESS) < 0) {
1634 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1635 return 0;
1636 }
1637
1638 /* read back any possible result */
1639 if ((num > 1) && (msg[1].flags & I2C_M_RD))
1640 dib9000_risc_mem_read(state, FE_MM_RW_COMPONENT_ACCESS_BUFFER, msg[1].buf, msg[1].len);
1641
1642 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
1643
1644 return num;
1645}
1646
1647static u32 dib9000_i2c_func(struct i2c_adapter *adapter)
1648{
1649 return I2C_FUNC_I2C;
1650}
1651
1652static struct i2c_algorithm dib9000_tuner_algo = {
1653 .master_xfer = dib9000_tuner_xfer,
1654 .functionality = dib9000_i2c_func,
1655};
1656
1657static struct i2c_algorithm dib9000_component_bus_algo = {
1658 .master_xfer = dib9000_fw_component_bus_xfer,
1659 .functionality = dib9000_i2c_func,
1660};
1661
1662struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
1663{
1664 struct dib9000_state *st = fe->demodulator_priv;
1665 return &st->tuner_adap;
1666}
1667EXPORT_SYMBOL(dib9000_get_tuner_interface);
1668
1669struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
1670{
1671 struct dib9000_state *st = fe->demodulator_priv;
1672 return &st->component_bus;
1673}
1674EXPORT_SYMBOL(dib9000_get_component_bus_interface);
1675
1676struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
1677{
1678 struct dib9000_state *st = fe->demodulator_priv;
1679 return dibx000_get_i2c_adapter(&st->i2c_master, intf, gating);
1680}
1681EXPORT_SYMBOL(dib9000_get_i2c_master);
1682
1683int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
1684{
1685 struct dib9000_state *st = fe->demodulator_priv;
1686
1687 st->i2c.i2c_adap = i2c;
1688 return 0;
1689}
1690EXPORT_SYMBOL(dib9000_set_i2c_adapter);
1691
1692static int dib9000_cfg_gpio(struct dib9000_state *st, u8 num, u8 dir, u8 val)
1693{
1694 st->gpio_dir = dib9000_read_word(st, 773);
1695 st->gpio_dir &= ~(1 << num); /* reset the direction bit */
1696 st->gpio_dir |= (dir & 0x1) << num; /* set the new direction */
1697 dib9000_write_word(st, 773, st->gpio_dir);
1698
1699 st->gpio_val = dib9000_read_word(st, 774);
1700 st->gpio_val &= ~(1 << num); /* reset the direction bit */
1701 st->gpio_val |= (val & 0x01) << num; /* set the new value */
1702 dib9000_write_word(st, 774, st->gpio_val);
1703
1704 dprintk("gpio dir: %04x: gpio val: %04x", st->gpio_dir, st->gpio_val);
1705
1706 return 0;
1707}
1708
1709int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
1710{
1711 struct dib9000_state *state = fe->demodulator_priv;
1712 return dib9000_cfg_gpio(state, num, dir, val);
1713}
1714EXPORT_SYMBOL(dib9000_set_gpio);
1715
1716int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
1717{
1718 struct dib9000_state *state = fe->demodulator_priv;
1719 u16 val = dib9000_read_word(state, 294 + 1) & 0xffef;
1720 val |= (onoff & 0x1) << 4;
1721
1722 dprintk("PID filter enabled %d", onoff);
1723 return dib9000_write_word(state, 294 + 1, val);
1724}
1725EXPORT_SYMBOL(dib9000_fw_pid_filter_ctrl);
1726
1727int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
1728{
1729 struct dib9000_state *state = fe->demodulator_priv;
1730 dprintk("Index %x, PID %d, OnOff %d", id, pid, onoff);
1731 return dib9000_write_word(state, 300 + 1 + id, onoff ? (1 << 13) | pid : 0);
1732}
1733EXPORT_SYMBOL(dib9000_fw_pid_filter);
1734
1735int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
1736{
1737 struct dib9000_state *state = fe->demodulator_priv;
1738 return dib9000_fw_init(state);
1739}
1740EXPORT_SYMBOL(dib9000_firmware_post_pll_init);
1741
1742static void dib9000_release(struct dvb_frontend *demod)
1743{
1744 struct dib9000_state *st = demod->demodulator_priv;
1745 u8 index_frontend;
1746
1747 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (st->fe[index_frontend] != NULL); index_frontend++)
1748 dvb_frontend_detach(st->fe[index_frontend]);
1749
1750 DibFreeLock(&state->platform.risc.mbx_if_lock);
1751 DibFreeLock(&state->platform.risc.mbx_lock);
1752 DibFreeLock(&state->platform.risc.mem_lock);
1753 DibFreeLock(&state->platform.risc.mem_mbx_lock);
1754 dibx000_exit_i2c_master(&st->i2c_master);
1755
1756 i2c_del_adapter(&st->tuner_adap);
1757 i2c_del_adapter(&st->component_bus);
1758 kfree(st->fe[0]);
1759 kfree(st);
1760}
1761
1762static int dib9000_wakeup(struct dvb_frontend *fe)
1763{
1764 return 0;
1765}
1766
1767static int dib9000_sleep(struct dvb_frontend *fe)
1768{
1769 struct dib9000_state *state = fe->demodulator_priv;
1770 u8 index_frontend;
1771 int ret;
1772
1773 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1774 ret = state->fe[index_frontend]->ops.sleep(state->fe[index_frontend]);
1775 if (ret < 0)
1776 return ret;
1777 }
1778 return dib9000_mbx_send(state, OUT_MSG_FE_SLEEP, NULL, 0);
1779}
1780
1781static int dib9000_fe_get_tune_settings(struct dvb_frontend *fe, struct dvb_frontend_tune_settings *tune)
1782{
1783 tune->min_delay_ms = 1000;
1784 return 0;
1785}
1786
1787static int dib9000_get_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1788{
1789 struct dib9000_state *state = fe->demodulator_priv;
1790 u8 index_frontend, sub_index_frontend;
1791 fe_status_t stat;
1792 int ret;
1793
1794 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1795 state->fe[index_frontend]->ops.read_status(state->fe[index_frontend], &stat);
1796 if (stat & FE_HAS_SYNC) {
1797 dprintk("TPS lock on the slave%i", index_frontend);
1798
1799 /* synchronize the cache with the other frontends */
1800 state->fe[index_frontend]->ops.get_frontend(state->fe[index_frontend], fep);
1801 for (sub_index_frontend = 0; (sub_index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[sub_index_frontend] != NULL);
1802 sub_index_frontend++) {
1803 if (sub_index_frontend != index_frontend) {
1804 state->fe[sub_index_frontend]->dtv_property_cache.modulation =
1805 state->fe[index_frontend]->dtv_property_cache.modulation;
1806 state->fe[sub_index_frontend]->dtv_property_cache.inversion =
1807 state->fe[index_frontend]->dtv_property_cache.inversion;
1808 state->fe[sub_index_frontend]->dtv_property_cache.transmission_mode =
1809 state->fe[index_frontend]->dtv_property_cache.transmission_mode;
1810 state->fe[sub_index_frontend]->dtv_property_cache.guard_interval =
1811 state->fe[index_frontend]->dtv_property_cache.guard_interval;
1812 state->fe[sub_index_frontend]->dtv_property_cache.hierarchy =
1813 state->fe[index_frontend]->dtv_property_cache.hierarchy;
1814 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_HP =
1815 state->fe[index_frontend]->dtv_property_cache.code_rate_HP;
1816 state->fe[sub_index_frontend]->dtv_property_cache.code_rate_LP =
1817 state->fe[index_frontend]->dtv_property_cache.code_rate_LP;
1818 state->fe[sub_index_frontend]->dtv_property_cache.rolloff =
1819 state->fe[index_frontend]->dtv_property_cache.rolloff;
1820 }
1821 }
1822 return 0;
1823 }
1824 }
1825
1826 /* get the channel from master chip */
1827 ret = dib9000_fw_get_channel(fe, fep);
1828 if (ret != 0)
1829 return ret;
1830
1831 /* synchronize the cache with the other frontends */
1832 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1833 state->fe[index_frontend]->dtv_property_cache.inversion = fe->dtv_property_cache.inversion;
1834 state->fe[index_frontend]->dtv_property_cache.transmission_mode = fe->dtv_property_cache.transmission_mode;
1835 state->fe[index_frontend]->dtv_property_cache.guard_interval = fe->dtv_property_cache.guard_interval;
1836 state->fe[index_frontend]->dtv_property_cache.modulation = fe->dtv_property_cache.modulation;
1837 state->fe[index_frontend]->dtv_property_cache.hierarchy = fe->dtv_property_cache.hierarchy;
1838 state->fe[index_frontend]->dtv_property_cache.code_rate_HP = fe->dtv_property_cache.code_rate_HP;
1839 state->fe[index_frontend]->dtv_property_cache.code_rate_LP = fe->dtv_property_cache.code_rate_LP;
1840 state->fe[index_frontend]->dtv_property_cache.rolloff = fe->dtv_property_cache.rolloff;
1841 }
1842
1843 return 0;
1844}
1845
1846static int dib9000_set_tune_state(struct dvb_frontend *fe, enum frontend_tune_state tune_state)
1847{
1848 struct dib9000_state *state = fe->demodulator_priv;
1849 state->tune_state = tune_state;
1850 if (tune_state == CT_DEMOD_START)
1851 state->status = FE_STATUS_TUNE_PENDING;
1852
1853 return 0;
1854}
1855
1856static u32 dib9000_get_status(struct dvb_frontend *fe)
1857{
1858 struct dib9000_state *state = fe->demodulator_priv;
1859 return state->status;
1860}
1861
1862static int dib9000_set_channel_status(struct dvb_frontend *fe, struct dvb_frontend_parametersContext *channel_status)
1863{
1864 struct dib9000_state *state = fe->demodulator_priv;
1865
1866 memcpy(&state->channel_status, channel_status, sizeof(struct dvb_frontend_parametersContext));
1867 return 0;
1868}
1869
1870static int dib9000_set_frontend(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
1871{
1872 struct dib9000_state *state = fe->demodulator_priv;
1873 int sleep_time, sleep_time_slave;
1874 u32 frontend_status;
1875 u8 nbr_pending, exit_condition, index_frontend, index_frontend_success;
1876 struct dvb_frontend_parametersContext channel_status;
1877
1878 /* check that the correct parameters are set */
1879 if (state->fe[0]->dtv_property_cache.frequency == 0) {
1880 dprintk("dib9000: must specify frequency ");
1881 return 0;
1882 }
1883
1884 if (state->fe[0]->dtv_property_cache.bandwidth_hz == 0) {
1885 dprintk("dib9000: must specify bandwidth ");
1886 return 0;
1887 }
1888 fe->dtv_property_cache.delivery_system = SYS_DVBT;
1889
1890 /* set the master status */
1891 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
1892 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO || fep->u.ofdm.constellation == QAM_AUTO || fep->u.ofdm.code_rate_HP == FEC_AUTO) {
1893 /* no channel specified, autosearch the channel */
1894 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_UNKNOWN;
1895 } else
1896 state->channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
1897
1898 /* set mode and status for the different frontends */
1899 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1900 dib9000_fw_set_diversity_in(state->fe[index_frontend], 1);
1901
1902 /* synchronization of the cache */
1903 memcpy(&state->fe[index_frontend]->dtv_property_cache, &fe->dtv_property_cache, sizeof(struct dtv_frontend_properties));
1904
1905 state->fe[index_frontend]->dtv_property_cache.delivery_system = SYS_DVBT;
1906 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_HIGH_Z);
1907
1908 dib9000_set_channel_status(state->fe[index_frontend], &state->channel_status);
1909 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
1910 }
1911
1912 /* actual tune */
1913 exit_condition = 0; /* 0: tune pending; 1: tune failed; 2:tune success */
1914 index_frontend_success = 0;
1915 do {
1916 sleep_time = dib9000_fw_tune(state->fe[0], NULL);
1917 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1918 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL);
1919 if (sleep_time == FE_CALLBACK_TIME_NEVER)
1920 sleep_time = sleep_time_slave;
1921 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
1922 sleep_time = sleep_time_slave;
1923 }
1924 if (sleep_time != FE_CALLBACK_TIME_NEVER)
1925 msleep(sleep_time / 10);
1926 else
1927 break;
1928
1929 nbr_pending = 0;
1930 exit_condition = 0;
1931 index_frontend_success = 0;
1932 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1933 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
1934 if (frontend_status > -FE_STATUS_TUNE_PENDING) {
1935 exit_condition = 2; /* tune success */
1936 index_frontend_success = index_frontend;
1937 break;
1938 }
1939 if (frontend_status == -FE_STATUS_TUNE_PENDING)
1940 nbr_pending++; /* some frontends are still tuning */
1941 }
1942 if ((exit_condition != 2) && (nbr_pending == 0))
1943 exit_condition = 1; /* if all tune are done and no success, exit: tune failed */
1944
1945 } while (exit_condition == 0);
1946
1947 /* check the tune result */
1948 if (exit_condition == 1) { /* tune failed */
1949 dprintk("tune failed");
1950 return 0;
1951 }
1952
1953 dprintk("tune success on frontend%i", index_frontend_success);
1954
1955 /* synchronize all the channel cache */
1956 dib9000_get_frontend(state->fe[0], fep);
1957
1958 /* retune the other frontends with the found channel */
1959 channel_status.status = CHANNEL_STATUS_PARAMETERS_SET;
1960 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1961 /* only retune the frontends which was not tuned success */
1962 if (index_frontend != index_frontend_success) {
1963 dib9000_set_channel_status(state->fe[index_frontend], &channel_status);
1964 dib9000_set_tune_state(state->fe[index_frontend], CT_DEMOD_START);
1965 }
1966 }
1967 do {
1968 sleep_time = FE_CALLBACK_TIME_NEVER;
1969 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1970 if (index_frontend != index_frontend_success) {
1971 sleep_time_slave = dib9000_fw_tune(state->fe[index_frontend], NULL);
1972 if (sleep_time == FE_CALLBACK_TIME_NEVER)
1973 sleep_time = sleep_time_slave;
1974 else if ((sleep_time_slave != FE_CALLBACK_TIME_NEVER) && (sleep_time_slave > sleep_time))
1975 sleep_time = sleep_time_slave;
1976 }
1977 }
1978 if (sleep_time != FE_CALLBACK_TIME_NEVER)
1979 msleep(sleep_time / 10);
1980 else
1981 break;
1982
1983 nbr_pending = 0;
1984 for (index_frontend = 0; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
1985 if (index_frontend != index_frontend_success) {
1986 frontend_status = -dib9000_get_status(state->fe[index_frontend]);
1987 if ((index_frontend != index_frontend_success) && (frontend_status == -FE_STATUS_TUNE_PENDING))
1988 nbr_pending++; /* some frontends are still tuning */
1989 }
1990 }
1991 } while (nbr_pending != 0);
1992
1993 /* set the output mode */
1994 dib9000_fw_set_output_mode(state->fe[0], state->chip.d9.cfg.output_mode);
1995 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
1996 dib9000_fw_set_output_mode(state->fe[index_frontend], OUTMODE_DIVERSITY);
1997
1998 /* turn off the diversity for the last frontend */
1999 dib9000_fw_set_diversity_in(state->fe[index_frontend - 1], 0);
2000
2001 return 0;
2002}
2003
2004static u16 dib9000_read_lock(struct dvb_frontend *fe)
2005{
2006 struct dib9000_state *state = fe->demodulator_priv;
2007
2008 return dib9000_read_word(state, 535);
2009}
2010
2011static int dib9000_read_status(struct dvb_frontend *fe, fe_status_t * stat)
2012{
2013 struct dib9000_state *state = fe->demodulator_priv;
2014 u8 index_frontend;
2015 u16 lock = 0, lock_slave = 0;
2016
2017 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2018 lock_slave |= dib9000_read_lock(state->fe[index_frontend]);
2019
2020 lock = dib9000_read_word(state, 535);
2021
2022 *stat = 0;
2023
2024 if ((lock & 0x8000) || (lock_slave & 0x8000))
2025 *stat |= FE_HAS_SIGNAL;
2026 if ((lock & 0x3000) || (lock_slave & 0x3000))
2027 *stat |= FE_HAS_CARRIER;
2028 if ((lock & 0x0100) || (lock_slave & 0x0100))
2029 *stat |= FE_HAS_VITERBI;
2030 if (((lock & 0x0038) == 0x38) || ((lock_slave & 0x0038) == 0x38))
2031 *stat |= FE_HAS_SYNC;
2032 if ((lock & 0x0008) || (lock_slave & 0x0008))
2033 *stat |= FE_HAS_LOCK;
2034
2035 return 0;
2036}
2037
2038static int dib9000_read_ber(struct dvb_frontend *fe, u32 * ber)
2039{
2040 struct dib9000_state *state = fe->demodulator_priv;
2041 u16 c[16];
2042
2043 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2044 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2045 return -EIO;
2046 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2047 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2048
2049 *ber = c[10] << 16 | c[11];
2050 return 0;
2051}
2052
2053static int dib9000_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
2054{
2055 struct dib9000_state *state = fe->demodulator_priv;
2056 u8 index_frontend;
2057 u16 c[16];
2058 u16 val;
2059
2060 *strength = 0;
2061 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++) {
2062 state->fe[index_frontend]->ops.read_signal_strength(state->fe[index_frontend], &val);
2063 if (val > 65535 - *strength)
2064 *strength = 65535;
2065 else
2066 *strength += val;
2067 }
2068
2069 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2070 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2071 return -EIO;
2072 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2073 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2074
2075 val = 65535 - c[4];
2076 if (val > 65535 - *strength)
2077 *strength = 65535;
2078 else
2079 *strength += val;
2080 return 0;
2081}
2082
2083static u32 dib9000_get_snr(struct dvb_frontend *fe)
2084{
2085 struct dib9000_state *state = fe->demodulator_priv;
2086 u16 c[16];
2087 u32 n, s, exp;
2088 u16 val;
2089
2090 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2091 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2092 return -EIO;
2093 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2094 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2095
2096 val = c[7];
2097 n = (val >> 4) & 0xff;
2098 exp = ((val & 0xf) << 2);
2099 val = c[8];
2100 exp += ((val >> 14) & 0x3);
2101 if ((exp & 0x20) != 0)
2102 exp -= 0x40;
2103 n <<= exp + 16;
2104
2105 s = (val >> 6) & 0xFF;
2106 exp = (val & 0x3F);
2107 if ((exp & 0x20) != 0)
2108 exp -= 0x40;
2109 s <<= exp + 16;
2110
2111 if (n > 0) {
2112 u32 t = (s / n) << 16;
2113 return t + ((s << 16) - n * t) / n;
2114 }
2115 return 0xffffffff;
2116}
2117
2118static int dib9000_read_snr(struct dvb_frontend *fe, u16 * snr)
2119{
2120 struct dib9000_state *state = fe->demodulator_priv;
2121 u8 index_frontend;
2122 u32 snr_master;
2123
2124 snr_master = dib9000_get_snr(fe);
2125 for (index_frontend = 1; (index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL); index_frontend++)
2126 snr_master += dib9000_get_snr(state->fe[index_frontend]);
2127
2128 if ((snr_master >> 16) != 0) {
2129 snr_master = 10 * intlog10(snr_master >> 16);
2130 *snr = snr_master / ((1 << 24) / 10);
2131 } else
2132 *snr = 0;
2133
2134 return 0;
2135}
2136
2137static int dib9000_read_unc_blocks(struct dvb_frontend *fe, u32 * unc)
2138{
2139 struct dib9000_state *state = fe->demodulator_priv;
2140 u16 c[16];
2141
2142 DibAcquireLock(&state->platform.risc.mem_mbx_lock);
2143 if (dib9000_fw_memmbx_sync(state, FE_SYNC_CHANNEL) < 0)
2144 return -EIO;
2145 dib9000_risc_mem_read(state, FE_MM_R_FE_MONITOR, (u8 *) c, sizeof(c));
2146 DibReleaseLock(&state->platform.risc.mem_mbx_lock);
2147
2148 *unc = c[12];
2149 return 0;
2150}
2151
2152int dib9000_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, u8 first_addr)
2153{
2154 int k = 0;
2155 u8 new_addr = 0;
2156 struct i2c_device client = {.i2c_adap = i2c };
2157
2158 client.i2c_addr = default_addr + 16;
2159 dib9000_i2c_write16(&client, 1796, 0x0);
2160
2161 for (k = no_of_demods - 1; k >= 0; k--) {
2162 /* designated i2c address */
2163 new_addr = first_addr + (k << 1);
2164 client.i2c_addr = default_addr;
2165
2166 dib9000_i2c_write16(&client, 1817, 3);
2167 dib9000_i2c_write16(&client, 1796, 0);
2168 dib9000_i2c_write16(&client, 1227, 1);
2169 dib9000_i2c_write16(&client, 1227, 0);
2170
2171 client.i2c_addr = new_addr;
2172 dib9000_i2c_write16(&client, 1817, 3);
2173 dib9000_i2c_write16(&client, 1796, 0);
2174 dib9000_i2c_write16(&client, 1227, 1);
2175 dib9000_i2c_write16(&client, 1227, 0);
2176
2177 if (dib9000_identify(&client) == 0) {
2178 client.i2c_addr = default_addr;
2179 if (dib9000_identify(&client) == 0) {
2180 dprintk("DiB9000 #%d: not identified", k);
2181 return -EIO;
2182 }
2183 }
2184
2185 dib9000_i2c_write16(&client, 1795, (1 << 10) | (4 << 6));
2186 dib9000_i2c_write16(&client, 1794, (new_addr << 2) | 2);
2187
2188 dprintk("IC %d initialized (to i2c_address 0x%x)", k, new_addr);
2189 }
2190
2191 for (k = 0; k < no_of_demods; k++) {
2192 new_addr = first_addr | (k << 1);
2193 client.i2c_addr = new_addr;
2194
2195 dib9000_i2c_write16(&client, 1794, (new_addr << 2));
2196 dib9000_i2c_write16(&client, 1795, 0);
2197 }
2198
2199 return 0;
2200}
2201EXPORT_SYMBOL(dib9000_i2c_enumeration);
2202
2203int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
2204{
2205 struct dib9000_state *state = fe->demodulator_priv;
2206 u8 index_frontend = 1;
2207
2208 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2209 index_frontend++;
2210 if (index_frontend < MAX_NUMBER_OF_FRONTENDS) {
2211 dprintk("set slave fe %p to index %i", fe_slave, index_frontend);
2212 state->fe[index_frontend] = fe_slave;
2213 return 0;
2214 }
2215
2216 dprintk("too many slave frontend");
2217 return -ENOMEM;
2218}
2219EXPORT_SYMBOL(dib9000_set_slave_frontend);
2220
2221int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
2222{
2223 struct dib9000_state *state = fe->demodulator_priv;
2224 u8 index_frontend = 1;
2225
2226 while ((index_frontend < MAX_NUMBER_OF_FRONTENDS) && (state->fe[index_frontend] != NULL))
2227 index_frontend++;
2228 if (index_frontend != 1) {
2229 dprintk("remove slave fe %p (index %i)", state->fe[index_frontend - 1], index_frontend - 1);
2230 state->fe[index_frontend] = NULL;
2231 return 0;
2232 }
2233
2234 dprintk("no frontend to be removed");
2235 return -ENODEV;
2236}
2237EXPORT_SYMBOL(dib9000_remove_slave_frontend);
2238
2239struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
2240{
2241 struct dib9000_state *state = fe->demodulator_priv;
2242
2243 if (slave_index >= MAX_NUMBER_OF_FRONTENDS)
2244 return NULL;
2245 return state->fe[slave_index];
2246}
2247EXPORT_SYMBOL(dib9000_get_slave_frontend);
2248
2249static struct dvb_frontend_ops dib9000_ops;
2250struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg)
2251{
2252 struct dvb_frontend *fe;
2253 struct dib9000_state *st;
2254 st = kzalloc(sizeof(struct dib9000_state), GFP_KERNEL);
2255 if (st == NULL)
2256 return NULL;
2257 fe = kzalloc(sizeof(struct dvb_frontend), GFP_KERNEL);
2258 if (fe == NULL)
2259 return NULL;
2260
2261 memcpy(&st->chip.d9.cfg, cfg, sizeof(struct dib9000_config));
2262 st->i2c.i2c_adap = i2c_adap;
2263 st->i2c.i2c_addr = i2c_addr;
2264
2265 st->gpio_dir = DIB9000_GPIO_DEFAULT_DIRECTIONS;
2266 st->gpio_val = DIB9000_GPIO_DEFAULT_VALUES;
2267 st->gpio_pwm_pos = DIB9000_GPIO_DEFAULT_PWM_POS;
2268
2269 DibInitLock(&st->platform.risc.mbx_if_lock);
2270 DibInitLock(&st->platform.risc.mbx_lock);
2271 DibInitLock(&st->platform.risc.mem_lock);
2272 DibInitLock(&st->platform.risc.mem_mbx_lock);
2273
2274 st->fe[0] = fe;
2275 fe->demodulator_priv = st;
2276 memcpy(&st->fe[0]->ops, &dib9000_ops, sizeof(struct dvb_frontend_ops));
2277
2278 /* Ensure the output mode remains at the previous default if it's
2279 * not specifically set by the caller.
2280 */
2281 if ((st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_SERIAL) && (st->chip.d9.cfg.output_mode != OUTMODE_MPEG2_PAR_GATED_CLK))
2282 st->chip.d9.cfg.output_mode = OUTMODE_MPEG2_FIFO;
2283
2284 if (dib9000_identify(&st->i2c) == 0)
2285 goto error;
2286
2287 dibx000_init_i2c_master(&st->i2c_master, DIB7000MC, st->i2c.i2c_adap, st->i2c.i2c_addr);
2288
2289 st->tuner_adap.dev.parent = i2c_adap->dev.parent;
2290 strncpy(st->tuner_adap.name, "DIB9000_FW TUNER ACCESS", sizeof(st->tuner_adap.name));
2291 st->tuner_adap.algo = &dib9000_tuner_algo;
2292 st->tuner_adap.algo_data = NULL;
2293 i2c_set_adapdata(&st->tuner_adap, st);
2294 if (i2c_add_adapter(&st->tuner_adap) < 0)
2295 goto error;
2296
2297 st->component_bus.dev.parent = i2c_adap->dev.parent;
2298 strncpy(st->component_bus.name, "DIB9000_FW COMPONENT BUS ACCESS", sizeof(st->component_bus.name));
2299 st->component_bus.algo = &dib9000_component_bus_algo;
2300 st->component_bus.algo_data = NULL;
2301 st->component_bus_speed = 340;
2302 i2c_set_adapdata(&st->component_bus, st);
2303 if (i2c_add_adapter(&st->component_bus) < 0)
2304 goto component_bus_add_error;
2305
2306 dib9000_fw_reset(fe);
2307
2308 return fe;
2309
2310component_bus_add_error:
2311 i2c_del_adapter(&st->tuner_adap);
2312error:
2313 kfree(st);
2314 return NULL;
2315}
2316EXPORT_SYMBOL(dib9000_attach);
2317
2318static struct dvb_frontend_ops dib9000_ops = {
2319 .info = {
2320 .name = "DiBcom 9000",
2321 .type = FE_OFDM,
2322 .frequency_min = 44250000,
2323 .frequency_max = 867250000,
2324 .frequency_stepsize = 62500,
2325 .caps = FE_CAN_INVERSION_AUTO |
2326 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
2327 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
2328 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
2329 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_RECOVER | FE_CAN_HIERARCHY_AUTO,
2330 },
2331
2332 .release = dib9000_release,
2333
2334 .init = dib9000_wakeup,
2335 .sleep = dib9000_sleep,
2336
2337 .set_frontend = dib9000_set_frontend,
2338 .get_tune_settings = dib9000_fe_get_tune_settings,
2339 .get_frontend = dib9000_get_frontend,
2340
2341 .read_status = dib9000_read_status,
2342 .read_ber = dib9000_read_ber,
2343 .read_signal_strength = dib9000_read_signal_strength,
2344 .read_snr = dib9000_read_snr,
2345 .read_ucblocks = dib9000_read_unc_blocks,
2346};
2347
2348MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
2349MODULE_AUTHOR("Olivier Grenie <ogrenie@dibcom.fr>");
2350MODULE_DESCRIPTION("Driver for the DiBcom 9000 COFDM demodulator");
2351MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib9000.h b/drivers/media/dvb/frontends/dib9000.h
new file mode 100644
index 000000000000..b5781a48034c
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib9000.h
@@ -0,0 +1,131 @@
1#ifndef DIB9000_H
2#define DIB9000_H
3
4#include "dibx000_common.h"
5
6struct dib9000_config {
7 u8 dvbt_mode;
8 u8 output_mpeg2_in_188_bytes;
9 u8 hostbus_diversity;
10 struct dibx000_bandwidth_config *bw;
11
12 u16 if_drives;
13
14 u32 timing_frequency;
15 u32 xtal_clock_khz;
16 u32 vcxo_timer;
17 u32 demod_clock_khz;
18
19 const u8 *microcode_B_fe_buffer;
20 u32 microcode_B_fe_size;
21
22 struct dibGPIOFunction gpio_function[2];
23 struct dibSubbandSelection subband;
24
25 u8 output_mode;
26};
27
28#define DEFAULT_DIB9000_I2C_ADDRESS 18
29
30#if defined(CONFIG_DVB_DIB9000) || (defined(CONFIG_DVB_DIB9000_MODULE) && defined(MODULE))
31extern struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, const struct dib9000_config *cfg);
32extern int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr);
33extern struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe);
34extern struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating);
35extern int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val);
36extern int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff);
37extern int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff);
38extern int dib9000_firmware_post_pll_init(struct dvb_frontend *fe);
39extern int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave);
40extern int dib9000_remove_slave_frontend(struct dvb_frontend *fe);
41extern struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index);
42extern struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe);
43extern int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c);
44extern int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed);
45#else
46static inline struct dvb_frontend *dib9000_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib9000_config *cfg)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL;
50}
51
52static inline struct i2c_adapter *dib9000_get_i2c_master(struct dvb_frontend *fe, enum dibx000_i2c_interface intf, int gating)
53{
54 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
55 return NULL;
56}
57
58static inline int dib9000_i2c_enumeration(struct i2c_adapter *host, int no_of_demods, u8 default_addr, u8 first_addr)
59{
60 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
61 return -ENODEV;
62}
63
64static inline struct i2c_adapter *dib9000_get_tuner_interface(struct dvb_frontend *fe)
65{
66 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
67 return NULL;
68}
69
70static inline int dib9000_set_gpio(struct dvb_frontend *fe, u8 num, u8 dir, u8 val)
71{
72 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
73 return -ENODEV;
74}
75
76static inline int dib9000_fw_pid_filter_ctrl(struct dvb_frontend *fe, u8 onoff)
77{
78 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
79 return -ENODEV;
80}
81
82static inline int dib9000_fw_pid_filter(struct dvb_frontend *fe, u8 id, u16 pid, u8 onoff)
83{
84 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
85 return -ENODEV;
86}
87
88static inline int dib9000_firmware_post_pll_init(struct dvb_frontend *fe)
89{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return -ENODEV;
92}
93
94static inline int dib9000_set_slave_frontend(struct dvb_frontend *fe, struct dvb_frontend *fe_slave)
95{
96 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
97 return -ENODEV;
98}
99
100int dib9000_remove_slave_frontend(struct dvb_frontend *fe)
101{
102 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
103 return -ENODEV;
104}
105
106static inline struct dvb_frontend *dib9000_get_slave_frontend(struct dvb_frontend *fe, int slave_index)
107{
108 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
109 return NULL;
110}
111
112static inline struct i2c_adapter *dib9000_get_component_bus_interface(struct dvb_frontend *fe)
113{
114 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
115 return NULL;
116}
117
118static inline int dib9000_set_i2c_adapter(struct dvb_frontend *fe, struct i2c_adapter *i2c)
119{
120 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
121 return -ENODEV;
122}
123
124static inline int dib9000_fw_set_component_bus_speed(struct dvb_frontend *fe, u16 speed)
125{
126 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
127 return -ENODEV;
128}
129#endif
130
131#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
index 2311c0a3406c..f6938f97feb4 100644
--- a/drivers/media/dvb/frontends/dibx000_common.c
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -17,9 +17,145 @@ static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
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
20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0; 21 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
21} 22}
22 23
24static u16 dibx000_read_word(struct dibx000_i2c_master *mst, u16 reg)
25{
26 u8 wb[2] = { reg >> 8, reg & 0xff };
27 u8 rb[2];
28 struct i2c_msg msg[2] = {
29 {.addr = mst->i2c_addr, .flags = 0, .buf = wb, .len = 2},
30 {.addr = mst->i2c_addr, .flags = I2C_M_RD, .buf = rb, .len = 2},
31 };
32
33 if (i2c_transfer(mst->i2c_adap, msg, 2) != 2)
34 dprintk("i2c read error on %d", reg);
35
36 return (rb[0] << 8) | rb[1];
37}
38
39static int dibx000_is_i2c_done(struct dibx000_i2c_master *mst)
40{
41 int i = 100;
42 u16 status;
43
44 while (((status = dibx000_read_word(mst, mst->base_reg + 2)) & 0x0100) == 0 && --i > 0)
45 ;
46
47 /* i2c timed out */
48 if (i == 0)
49 return -EREMOTEIO;
50
51 /* no acknowledge */
52 if ((status & 0x0080) == 0)
53 return -EREMOTEIO;
54
55 return 0;
56}
57
58static int dibx000_master_i2c_write(struct dibx000_i2c_master *mst, struct i2c_msg *msg, u8 stop)
59{
60 u16 data;
61 u16 da;
62 u16 i;
63 u16 txlen = msg->len, len;
64 const u8 *b = msg->buf;
65
66 while (txlen) {
67 dibx000_read_word(mst, mst->base_reg + 2);
68
69 len = txlen > 8 ? 8 : txlen;
70 for (i = 0; i < len; i += 2) {
71 data = *b++ << 8;
72 if (i+1 < len)
73 data |= *b++;
74 dibx000_write_word(mst, mst->base_reg, data);
75 }
76 da = (((u8) (msg->addr)) << 9) |
77 (1 << 8) |
78 (1 << 7) |
79 (0 << 6) |
80 (0 << 5) |
81 ((len & 0x7) << 2) |
82 (0 << 1) |
83 (0 << 0);
84
85 if (txlen == msg->len)
86 da |= 1 << 5; /* start */
87
88 if (txlen-len == 0 && stop)
89 da |= 1 << 6; /* stop */
90
91 dibx000_write_word(mst, mst->base_reg+1, da);
92
93 if (dibx000_is_i2c_done(mst) != 0)
94 return -EREMOTEIO;
95 txlen -= len;
96 }
97
98 return 0;
99}
100
101static int dibx000_master_i2c_read(struct dibx000_i2c_master *mst, struct i2c_msg *msg)
102{
103 u16 da;
104 u8 *b = msg->buf;
105 u16 rxlen = msg->len, len;
106
107 while (rxlen) {
108 len = rxlen > 8 ? 8 : rxlen;
109 da = (((u8) (msg->addr)) << 9) |
110 (1 << 8) |
111 (1 << 7) |
112 (0 << 6) |
113 (0 << 5) |
114 ((len & 0x7) << 2) |
115 (1 << 1) |
116 (0 << 0);
117
118 if (rxlen == msg->len)
119 da |= 1 << 5; /* start */
120
121 if (rxlen-len == 0)
122 da |= 1 << 6; /* stop */
123 dibx000_write_word(mst, mst->base_reg+1, da);
124
125 if (dibx000_is_i2c_done(mst) != 0)
126 return -EREMOTEIO;
127
128 rxlen -= len;
129
130 while (len) {
131 da = dibx000_read_word(mst, mst->base_reg);
132 *b++ = (da >> 8) & 0xff;
133 len--;
134 if (len >= 1) {
135 *b++ = da & 0xff;
136 len--;
137 }
138 }
139 }
140
141 return 0;
142}
143
144int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed)
145{
146 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
147
148 if (mst->device_rev < DIB7000MC && speed < 235)
149 speed = 235;
150 return dibx000_write_word(mst, mst->base_reg + 3, (u16)(60000 / speed));
151
152}
153EXPORT_SYMBOL(dibx000_i2c_set_speed);
154
155static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
156{
157 return I2C_FUNC_I2C;
158}
23 159
24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, 160static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
25 enum dibx000_i2c_interface intf) 161 enum dibx000_i2c_interface intf)
@@ -32,6 +168,60 @@ static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst,
32 return 0; 168 return 0;
33} 169}
34 170
171static int dibx000_i2c_master_xfer_gpio12(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
172{
173 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
174 int msg_index;
175 int ret = 0;
176
177 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_1_2);
178 for (msg_index = 0; msg_index < num; msg_index++) {
179 if (msg[msg_index].flags & I2C_M_RD) {
180 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
181 if (ret != 0)
182 return 0;
183 } else {
184 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
185 if (ret != 0)
186 return 0;
187 }
188 }
189
190 return num;
191}
192
193static int dibx000_i2c_master_xfer_gpio34(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
194{
195 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
196 int msg_index;
197 int ret = 0;
198
199 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_3_4);
200 for (msg_index = 0; msg_index < num; msg_index++) {
201 if (msg[msg_index].flags & I2C_M_RD) {
202 ret = dibx000_master_i2c_read(mst, &msg[msg_index]);
203 if (ret != 0)
204 return 0;
205 } else {
206 ret = dibx000_master_i2c_write(mst, &msg[msg_index], 1);
207 if (ret != 0)
208 return 0;
209 }
210 }
211
212 return num;
213}
214
215static struct i2c_algorithm dibx000_i2c_master_gpio12_xfer_algo = {
216 .master_xfer = dibx000_i2c_master_xfer_gpio12,
217 .functionality = dibx000_i2c_func,
218};
219
220static struct i2c_algorithm dibx000_i2c_master_gpio34_xfer_algo = {
221 .master_xfer = dibx000_i2c_master_xfer_gpio34,
222 .functionality = dibx000_i2c_func,
223};
224
35static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], 225static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
36 u8 addr, int onoff) 226 u8 addr, int onoff)
37{ 227{
@@ -54,11 +244,37 @@ static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4],
54 return 0; 244 return 0;
55} 245}
56 246
57static u32 dibx000_i2c_func(struct i2c_adapter *adapter) 247static int dibx000_i2c_gated_gpio67_xfer(struct i2c_adapter *i2c_adap,
248 struct i2c_msg msg[], int num)
58{ 249{
59 return I2C_FUNC_I2C; 250 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
251 struct i2c_msg m[2 + num];
252 u8 tx_open[4], tx_close[4];
253
254 memset(m, 0, sizeof(struct i2c_msg) * (2 + num));
255
256 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_GPIO_6_7);
257
258 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
259 m[0].addr = mst->i2c_addr;
260 m[0].buf = tx_open;
261 m[0].len = 4;
262
263 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
264
265 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
266 m[num + 1].addr = mst->i2c_addr;
267 m[num + 1].buf = tx_close;
268 m[num + 1].len = 4;
269
270 return i2c_transfer(mst->i2c_adap, m, 2 + num) == 2 + num ? num : -EIO;
60} 271}
61 272
273static struct i2c_algorithm dibx000_i2c_gated_gpio67_algo = {
274 .master_xfer = dibx000_i2c_gated_gpio67_xfer,
275 .functionality = dibx000_i2c_func,
276};
277
62static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, 278static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap,
63 struct i2c_msg msg[], int num) 279 struct i2c_msg msg[], int num)
64{ 280{
@@ -91,8 +307,8 @@ static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
91}; 307};
92 308
93struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, 309struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
94 enum dibx000_i2c_interface intf, 310 enum dibx000_i2c_interface intf,
95 int gating) 311 int gating)
96{ 312{
97 struct i2c_adapter *i2c = NULL; 313 struct i2c_adapter *i2c = NULL;
98 314
@@ -101,6 +317,18 @@ struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst,
101 if (gating) 317 if (gating)
102 i2c = &mst->gated_tuner_i2c_adap; 318 i2c = &mst->gated_tuner_i2c_adap;
103 break; 319 break;
320 case DIBX000_I2C_INTERFACE_GPIO_1_2:
321 if (!gating)
322 i2c = &mst->master_i2c_adap_gpio12;
323 break;
324 case DIBX000_I2C_INTERFACE_GPIO_3_4:
325 if (!gating)
326 i2c = &mst->master_i2c_adap_gpio34;
327 break;
328 case DIBX000_I2C_INTERFACE_GPIO_6_7:
329 if (gating)
330 i2c = &mst->master_i2c_adap_gpio67;
331 break;
104 default: 332 default:
105 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n"); 333 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
106 break; 334 break;
@@ -126,8 +354,8 @@ void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst)
126EXPORT_SYMBOL(dibx000_reset_i2c_master); 354EXPORT_SYMBOL(dibx000_reset_i2c_master);
127 355
128static int i2c_adapter_init(struct i2c_adapter *i2c_adap, 356static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
129 struct i2c_algorithm *algo, const char *name, 357 struct i2c_algorithm *algo, const char *name,
130 struct dibx000_i2c_master *mst) 358 struct dibx000_i2c_master *mst)
131{ 359{
132 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name)); 360 strncpy(i2c_adap->name, name, sizeof(i2c_adap->name));
133 i2c_adap->algo = algo; 361 i2c_adap->algo = algo;
@@ -139,7 +367,7 @@ static int i2c_adapter_init(struct i2c_adapter *i2c_adap,
139} 367}
140 368
141int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, 369int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
142 struct i2c_adapter *i2c_adap, u8 i2c_addr) 370 struct i2c_adapter *i2c_adap, u8 i2c_addr)
143{ 371{
144 u8 tx[4]; 372 u8 tx[4];
145 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 }; 373 struct i2c_msg m = {.addr = i2c_addr >> 1,.buf = tx,.len = 4 };
@@ -153,11 +381,33 @@ int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev,
153 else 381 else
154 mst->base_reg = 768; 382 mst->base_reg = 768;
155 383
384 mst->gated_tuner_i2c_adap.dev.parent = mst->i2c_adap->dev.parent;
385 if (i2c_adapter_init
386 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo,
387 "DiBX000 tuner I2C bus", mst) != 0)
388 printk(KERN_ERR
389 "DiBX000: could not initialize the tuner i2c_adapter\n");
390
391 mst->master_i2c_adap_gpio12.dev.parent = mst->i2c_adap->dev.parent;
392 if (i2c_adapter_init
393 (&mst->master_i2c_adap_gpio12, &dibx000_i2c_master_gpio12_xfer_algo,
394 "DiBX000 master GPIO12 I2C bus", mst) != 0)
395 printk(KERN_ERR
396 "DiBX000: could not initialize the master i2c_adapter\n");
397
398 mst->master_i2c_adap_gpio34.dev.parent = mst->i2c_adap->dev.parent;
399 if (i2c_adapter_init
400 (&mst->master_i2c_adap_gpio34, &dibx000_i2c_master_gpio34_xfer_algo,
401 "DiBX000 master GPIO34 I2C bus", mst) != 0)
402 printk(KERN_ERR
403 "DiBX000: could not initialize the master i2c_adapter\n");
404
405 mst->master_i2c_adap_gpio67.dev.parent = mst->i2c_adap->dev.parent;
156 if (i2c_adapter_init 406 if (i2c_adapter_init
157 (&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, 407 (&mst->master_i2c_adap_gpio67, &dibx000_i2c_gated_gpio67_algo,
158 "DiBX000 tuner I2C bus", mst) != 0) 408 "DiBX000 master GPIO67 I2C bus", mst) != 0)
159 printk(KERN_ERR 409 printk(KERN_ERR
160 "DiBX000: could not initialize the tuner i2c_adapter\n"); 410 "DiBX000: could not initialize the master i2c_adapter\n");
161 411
162 /* initialize the i2c-master by closing the gate */ 412 /* initialize the i2c-master by closing the gate */
163 dibx000_i2c_gate_ctrl(mst, tx, 0, 0); 413 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
@@ -170,16 +420,19 @@ EXPORT_SYMBOL(dibx000_init_i2c_master);
170void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst) 420void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
171{ 421{
172 i2c_del_adapter(&mst->gated_tuner_i2c_adap); 422 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
423 i2c_del_adapter(&mst->master_i2c_adap_gpio12);
424 i2c_del_adapter(&mst->master_i2c_adap_gpio34);
425 i2c_del_adapter(&mst->master_i2c_adap_gpio67);
173} 426}
174EXPORT_SYMBOL(dibx000_exit_i2c_master); 427EXPORT_SYMBOL(dibx000_exit_i2c_master);
175 428
176 429
177u32 systime(void) 430u32 systime(void)
178{ 431{
179 struct timespec t; 432 struct timespec t;
180 433
181 t = current_kernel_time(); 434 t = current_kernel_time();
182 return (t.tv_sec * 10000) + (t.tv_nsec / 100000); 435 return (t.tv_sec * 10000) + (t.tv_nsec / 100000);
183} 436}
184EXPORT_SYMBOL(systime); 437EXPORT_SYMBOL(systime);
185 438
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
index 4f5d141a308d..977d343369aa 100644
--- a/drivers/media/dvb/frontends/dibx000_common.h
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -4,7 +4,8 @@
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 DIBX000_I2C_INTERFACE_GPIO_6_7 = 3
8}; 9};
9 10
10struct dibx000_i2c_master { 11struct dibx000_i2c_master {
@@ -17,8 +18,11 @@ struct dibx000_i2c_master {
17 18
18 enum dibx000_i2c_interface selected_interface; 19 enum dibx000_i2c_interface selected_interface;
19 20
20// struct i2c_adapter tuner_i2c_adap; 21/* struct i2c_adapter tuner_i2c_adap; */
21 struct i2c_adapter gated_tuner_i2c_adap; 22 struct i2c_adapter gated_tuner_i2c_adap;
23 struct i2c_adapter master_i2c_adap_gpio12;
24 struct i2c_adapter master_i2c_adap_gpio34;
25 struct i2c_adapter master_i2c_adap_gpio67;
22 26
23 struct i2c_adapter *i2c_adap; 27 struct i2c_adapter *i2c_adap;
24 u8 i2c_addr; 28 u8 i2c_addr;
@@ -27,14 +31,15 @@ struct dibx000_i2c_master {
27}; 31};
28 32
29extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, 33extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst,
30 u16 device_rev, struct i2c_adapter *i2c_adap, 34 u16 device_rev, struct i2c_adapter *i2c_adap,
31 u8 i2c_addr); 35 u8 i2c_addr);
32extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master 36extern struct i2c_adapter *dibx000_get_i2c_adapter(struct dibx000_i2c_master
33 *mst, 37 *mst,
34 enum dibx000_i2c_interface 38 enum dibx000_i2c_interface
35 intf, int gating); 39 intf, int gating);
36extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst); 40extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
37extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst); 41extern void dibx000_reset_i2c_master(struct dibx000_i2c_master *mst);
42extern int dibx000_i2c_set_speed(struct i2c_adapter *i2c_adap, u16 speed);
38 43
39extern u32 systime(void); 44extern u32 systime(void);
40 45
@@ -42,7 +47,7 @@ extern u32 systime(void);
42#define BAND_UHF 0x02 47#define BAND_UHF 0x02
43#define BAND_VHF 0x04 48#define BAND_VHF 0x04
44#define BAND_SBAND 0x08 49#define BAND_SBAND 0x08
45#define BAND_FM 0x10 50#define BAND_FM 0x10
46#define BAND_CBAND 0x20 51#define BAND_CBAND 0x20
47 52
48#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \ 53#define BAND_OF_FREQUENCY(freq_kHz) ((freq_kHz) <= 170000 ? BAND_CBAND : \
@@ -135,9 +140,9 @@ enum dibx000_adc_states {
135 DIBX000_VBG_DISABLE, 140 DIBX000_VBG_DISABLE,
136}; 141};
137 142
138#define BANDWIDTH_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \ 143#define BANDWIDTH_TO_KHZ(v) ((v) == BANDWIDTH_8_MHZ ? 8000 : \
139 (v) == BANDWIDTH_7_MHZ ? 7000 : \ 144 (v) == BANDWIDTH_7_MHZ ? 7000 : \
140 (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 ) 145 (v) == BANDWIDTH_6_MHZ ? 6000 : 8000)
141 146
142#define BANDWIDTH_TO_INDEX(v) ( \ 147#define BANDWIDTH_TO_INDEX(v) ( \
143 (v) == 8000 ? BANDWIDTH_8_MHZ : \ 148 (v) == 8000 ? BANDWIDTH_8_MHZ : \
@@ -153,53 +158,57 @@ enum dibx000_adc_states {
153#define OUTMODE_MPEG2_FIFO 5 158#define OUTMODE_MPEG2_FIFO 5
154#define OUTMODE_ANALOG_ADC 6 159#define OUTMODE_ANALOG_ADC 6
155 160
161#define INPUT_MODE_OFF 0x11
162#define INPUT_MODE_DIVERSITY 0x12
163#define INPUT_MODE_MPEG 0x13
164
156enum frontend_tune_state { 165enum frontend_tune_state {
157 CT_TUNER_START = 10, 166 CT_TUNER_START = 10,
158 CT_TUNER_STEP_0, 167 CT_TUNER_STEP_0,
159 CT_TUNER_STEP_1, 168 CT_TUNER_STEP_1,
160 CT_TUNER_STEP_2, 169 CT_TUNER_STEP_2,
161 CT_TUNER_STEP_3, 170 CT_TUNER_STEP_3,
162 CT_TUNER_STEP_4, 171 CT_TUNER_STEP_4,
163 CT_TUNER_STEP_5, 172 CT_TUNER_STEP_5,
164 CT_TUNER_STEP_6, 173 CT_TUNER_STEP_6,
165 CT_TUNER_STEP_7, 174 CT_TUNER_STEP_7,
166 CT_TUNER_STOP, 175 CT_TUNER_STOP,
167 176
168 CT_AGC_START = 20, 177 CT_AGC_START = 20,
169 CT_AGC_STEP_0, 178 CT_AGC_STEP_0,
170 CT_AGC_STEP_1, 179 CT_AGC_STEP_1,
171 CT_AGC_STEP_2, 180 CT_AGC_STEP_2,
172 CT_AGC_STEP_3, 181 CT_AGC_STEP_3,
173 CT_AGC_STEP_4, 182 CT_AGC_STEP_4,
174 CT_AGC_STOP, 183 CT_AGC_STOP,
175 184
176 CT_DEMOD_START = 30, 185 CT_DEMOD_START = 30,
177 CT_DEMOD_STEP_1, 186 CT_DEMOD_STEP_1,
178 CT_DEMOD_STEP_2, 187 CT_DEMOD_STEP_2,
179 CT_DEMOD_STEP_3, 188 CT_DEMOD_STEP_3,
180 CT_DEMOD_STEP_4, 189 CT_DEMOD_STEP_4,
181 CT_DEMOD_STEP_5, 190 CT_DEMOD_STEP_5,
182 CT_DEMOD_STEP_6, 191 CT_DEMOD_STEP_6,
183 CT_DEMOD_STEP_7, 192 CT_DEMOD_STEP_7,
184 CT_DEMOD_STEP_8, 193 CT_DEMOD_STEP_8,
185 CT_DEMOD_STEP_9, 194 CT_DEMOD_STEP_9,
186 CT_DEMOD_STEP_10, 195 CT_DEMOD_STEP_10,
187 CT_DEMOD_SEARCH_NEXT = 41, 196 CT_DEMOD_SEARCH_NEXT = 41,
188 CT_DEMOD_STEP_LOCKED, 197 CT_DEMOD_STEP_LOCKED,
189 CT_DEMOD_STOP, 198 CT_DEMOD_STOP,
190 199
191 CT_DONE = 100, 200 CT_DONE = 100,
192 CT_SHUTDOWN, 201 CT_SHUTDOWN,
193 202
194}; 203};
195 204
196struct dvb_frontend_parametersContext { 205struct dvb_frontend_parametersContext {
197#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01 206#define CHANNEL_STATUS_PARAMETERS_UNKNOWN 0x01
198#define CHANNEL_STATUS_PARAMETERS_SET 0x02 207#define CHANNEL_STATUS_PARAMETERS_SET 0x02
199 u8 status; 208 u8 status;
200 u32 tune_time_estimation[2]; 209 u32 tune_time_estimation[2];
201 s32 tps_available; 210 s32 tps_available;
202 u16 tps[9]; 211 u16 tps[9];
203}; 212};
204 213
205#define FE_STATUS_TUNE_FAILED 0 214#define FE_STATUS_TUNE_FAILED 0
@@ -216,4 +225,49 @@ struct dvb_frontend_parametersContext {
216 225
217#define ABS(x) ((x < 0) ? (-x) : (x)) 226#define ABS(x) ((x < 0) ? (-x) : (x))
218 227
228#define DATA_BUS_ACCESS_MODE_8BIT 0x01
229#define DATA_BUS_ACCESS_MODE_16BIT 0x02
230#define DATA_BUS_ACCESS_MODE_NO_ADDRESS_INCREMENT 0x10
231
232struct dibGPIOFunction {
233#define BOARD_GPIO_COMPONENT_BUS_ADAPTER 1
234#define BOARD_GPIO_COMPONENT_DEMOD 2
235 u8 component;
236
237#define BOARD_GPIO_FUNCTION_BOARD_ON 1
238#define BOARD_GPIO_FUNCTION_BOARD_OFF 2
239#define BOARD_GPIO_FUNCTION_COMPONENT_ON 3
240#define BOARD_GPIO_FUNCTION_COMPONENT_OFF 4
241#define BOARD_GPIO_FUNCTION_SUBBAND_PWM 5
242#define BOARD_GPIO_FUNCTION_SUBBAND_GPIO 6
243 u8 function;
244
245/* mask, direction and value are used specify which GPIO to change GPIO0
246 * is LSB and possible GPIO31 is MSB. The same bit-position as in the
247 * mask is used for the direction and the value. Direction == 1 is OUT,
248 * 0 == IN. For direction "OUT" value is either 1 or 0, for direction IN
249 * value has no meaning.
250 *
251 * In case of BOARD_GPIO_FUNCTION_PWM mask is giving the GPIO to be
252 * used to do the PWM. Direction gives the PWModulator to be used.
253 * Value gives the PWM value in device-dependent scale.
254 */
255 u32 mask;
256 u32 direction;
257 u32 value;
258};
259
260#define MAX_NB_SUBBANDS 8
261struct dibSubbandSelection {
262 u8 size; /* Actual number of subbands. */
263 struct {
264 u16 f_mhz;
265 struct dibGPIOFunction gpio;
266 } subband[MAX_NB_SUBBANDS];
267};
268
269#define DEMOD_TIMF_SET 0x00
270#define DEMOD_TIMF_GET 0x01
271#define DEMOD_TIMF_UPDATE 0x02
272
219#endif 273#endif
diff --git a/drivers/media/dvb/frontends/ds3000.c b/drivers/media/dvb/frontends/ds3000.c
index fc61d9230db8..90bf573308b0 100644
--- a/drivers/media/dvb/frontends/ds3000.c
+++ b/drivers/media/dvb/frontends/ds3000.c
@@ -229,31 +229,11 @@ static u8 ds3000_dvbs2_init_tab[] = {
229 0xb8, 0x00, 229 0xb8, 0x00,
230}; 230};
231 231
232/* DS3000 doesn't need some parameters as input and auto-detects them */
233/* save input from the application of those parameters */
234struct ds3000_tuning {
235 u32 frequency;
236 u32 symbol_rate;
237 fe_spectral_inversion_t inversion;
238 enum fe_code_rate fec;
239
240 /* input values */
241 u8 inversion_val;
242 fe_modulation_t delivery;
243 u8 rolloff;
244};
245
246struct ds3000_state { 232struct ds3000_state {
247 struct i2c_adapter *i2c; 233 struct i2c_adapter *i2c;
248 const struct ds3000_config *config; 234 const struct ds3000_config *config;
249
250 struct dvb_frontend frontend; 235 struct dvb_frontend frontend;
251
252 struct ds3000_tuning dcur;
253 struct ds3000_tuning dnxt;
254
255 u8 skip_fw_load; 236 u8 skip_fw_load;
256
257 /* previous uncorrected block counter for DVB-S2 */ 237 /* previous uncorrected block counter for DVB-S2 */
258 u16 prevUCBS2; 238 u16 prevUCBS2;
259}; 239};
@@ -305,7 +285,7 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
305 struct i2c_msg msg; 285 struct i2c_msg msg;
306 u8 *buf; 286 u8 *buf;
307 287
308 buf = kmalloc(3, GFP_KERNEL); 288 buf = kmalloc(33, GFP_KERNEL);
309 if (buf == NULL) { 289 if (buf == NULL) {
310 printk(KERN_ERR "Unable to kmalloc\n"); 290 printk(KERN_ERR "Unable to kmalloc\n");
311 ret = -ENOMEM; 291 ret = -ENOMEM;
@@ -317,10 +297,10 @@ static int ds3000_writeFW(struct ds3000_state *state, int reg,
317 msg.addr = state->config->demod_address; 297 msg.addr = state->config->demod_address;
318 msg.flags = 0; 298 msg.flags = 0;
319 msg.buf = buf; 299 msg.buf = buf;
320 msg.len = 3; 300 msg.len = 33;
321 301
322 for (i = 0; i < len; i += 2) { 302 for (i = 0; i < len; i += 32) {
323 memcpy(buf + 1, data + i, 2); 303 memcpy(buf + 1, data + i, 32);
324 304
325 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len); 305 dprintk("%s: write reg 0x%02x, len = %d\n", __func__, reg, len);
326 306
@@ -401,45 +381,6 @@ static int ds3000_tuner_readreg(struct ds3000_state *state, u8 reg)
401 return b1[0]; 381 return b1[0];
402} 382}
403 383
404static int ds3000_set_inversion(struct ds3000_state *state,
405 fe_spectral_inversion_t inversion)
406{
407 dprintk("%s(%d)\n", __func__, inversion);
408
409 switch (inversion) {
410 case INVERSION_OFF:
411 case INVERSION_ON:
412 case INVERSION_AUTO:
413 break;
414 default:
415 return -EINVAL;
416 }
417
418 state->dnxt.inversion = inversion;
419
420 return 0;
421}
422
423static int ds3000_set_symbolrate(struct ds3000_state *state, u32 rate)
424{
425 int ret = 0;
426
427 dprintk("%s()\n", __func__);
428
429 dprintk("%s() symbol_rate = %d\n", __func__, state->dnxt.symbol_rate);
430
431 /* check if symbol rate is within limits */
432 if ((state->dnxt.symbol_rate >
433 state->frontend.ops.info.symbol_rate_max) ||
434 (state->dnxt.symbol_rate <
435 state->frontend.ops.info.symbol_rate_min))
436 ret = -EOPNOTSUPP;
437
438 state->dnxt.symbol_rate = rate;
439
440 return ret;
441}
442
443static int ds3000_load_firmware(struct dvb_frontend *fe, 384static int ds3000_load_firmware(struct dvb_frontend *fe,
444 const struct firmware *fw); 385 const struct firmware *fw);
445 386
@@ -509,23 +450,31 @@ static int ds3000_load_firmware(struct dvb_frontend *fe,
509 return 0; 450 return 0;
510} 451}
511 452
512static void ds3000_dump_registers(struct dvb_frontend *fe) 453static int ds3000_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
513{ 454{
514 struct ds3000_state *state = fe->demodulator_priv; 455 struct ds3000_state *state = fe->demodulator_priv;
515 int x, y, reg = 0, val; 456 u8 data;
516 457
517 for (y = 0; y < 16; y++) { 458 dprintk("%s(%d)\n", __func__, voltage);
518 dprintk("%s: %02x: ", __func__, y); 459
519 for (x = 0; x < 16; x++) { 460 data = ds3000_readreg(state, 0xa2);
520 reg = (y << 4) + x; 461 data |= 0x03; /* bit0 V/H, bit1 off/on */
521 val = ds3000_readreg(state, reg); 462
522 if (x != 15) 463 switch (voltage) {
523 dprintk("%02x ", val); 464 case SEC_VOLTAGE_18:
524 else 465 data &= ~0x03;
525 dprintk("%02x\n", val); 466 break;
526 } 467 case SEC_VOLTAGE_13:
468 data &= ~0x03;
469 data |= 0x01;
470 break;
471 case SEC_VOLTAGE_OFF:
472 break;
527 } 473 }
528 dprintk("%s: -- DS3000 DUMP DONE --\n", __func__); 474
475 ds3000_writereg(state, 0xa2, data);
476
477 return 0;
529} 478}
530 479
531static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status) 480static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
@@ -562,16 +511,6 @@ static int ds3000_read_status(struct dvb_frontend *fe, fe_status_t* status)
562 return 0; 511 return 0;
563} 512}
564 513
565#define FE_IS_TUNED (FE_HAS_SIGNAL + FE_HAS_LOCK)
566static int ds3000_is_tuned(struct dvb_frontend *fe)
567{
568 fe_status_t tunerstat;
569
570 ds3000_read_status(fe, &tunerstat);
571
572 return ((tunerstat & FE_IS_TUNED) == FE_IS_TUNED);
573}
574
575/* read DS3000 BER value */ 514/* read DS3000 BER value */
576static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber) 515static int ds3000_read_ber(struct dvb_frontend *fe, u32* ber)
577{ 516{
@@ -792,13 +731,6 @@ static int ds3000_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
792 return 0; 731 return 0;
793} 732}
794 733
795/* Overwrite the current tuning params, we are about to tune */
796static void ds3000_clone_params(struct dvb_frontend *fe)
797{
798 struct ds3000_state *state = fe->demodulator_priv;
799 memcpy(&state->dcur, &state->dnxt, sizeof(state->dcur));
800}
801
802static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone) 734static int ds3000_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
803{ 735{
804 struct ds3000_state *state = fe->demodulator_priv; 736 struct ds3000_state *state = fe->demodulator_priv;
@@ -1016,287 +948,298 @@ static int ds3000_get_property(struct dvb_frontend *fe,
1016 return 0; 948 return 0;
1017} 949}
1018 950
1019static int ds3000_tune(struct dvb_frontend *fe, 951static int ds3000_set_carrier_offset(struct dvb_frontend *fe,
952 s32 carrier_offset_khz)
953{
954 struct ds3000_state *state = fe->demodulator_priv;
955 s32 tmp;
956
957 tmp = carrier_offset_khz;
958 tmp *= 65536;
959 tmp = (2 * tmp + DS3000_SAMPLE_RATE) / (2 * DS3000_SAMPLE_RATE);
960
961 if (tmp < 0)
962 tmp += 65536;
963
964 ds3000_writereg(state, 0x5f, tmp >> 8);
965 ds3000_writereg(state, 0x5e, tmp & 0xff);
966
967 return 0;
968}
969
970static int ds3000_set_frontend(struct dvb_frontend *fe,
1020 struct dvb_frontend_parameters *p) 971 struct dvb_frontend_parameters *p)
1021{ 972{
1022 struct ds3000_state *state = fe->demodulator_priv; 973 struct ds3000_state *state = fe->demodulator_priv;
1023 struct dtv_frontend_properties *c = &fe->dtv_property_cache; 974 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1024 975
1025 int ret = 0, retune, i; 976 int i;
1026 u8 status, mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf; 977 fe_status_t status;
978 u8 mlpf, mlpf_new, mlpf_max, mlpf_min, nlpf, div4;
979 s32 offset_khz;
1027 u16 value, ndiv; 980 u16 value, ndiv;
1028 u32 f3db; 981 u32 f3db;
1029 982
1030 dprintk("%s() ", __func__); 983 dprintk("%s() ", __func__);
1031 984
1032 /* Load the firmware if required */ 985 if (state->config->set_ts_params)
1033 ret = ds3000_firmware_ondemand(fe); 986 state->config->set_ts_params(fe, 0);
1034 if (ret != 0) { 987 /* Tune */
1035 printk(KERN_ERR "%s: Unable initialise the firmware\n", 988 /* unknown */
1036 __func__); 989 ds3000_tuner_writereg(state, 0x07, 0x02);
1037 return ret; 990 ds3000_tuner_writereg(state, 0x10, 0x00);
991 ds3000_tuner_writereg(state, 0x60, 0x79);
992 ds3000_tuner_writereg(state, 0x08, 0x01);
993 ds3000_tuner_writereg(state, 0x00, 0x01);
994 div4 = 0;
995
996 /* calculate and set freq divider */
997 if (p->frequency < 1146000) {
998 ds3000_tuner_writereg(state, 0x10, 0x11);
999 div4 = 1;
1000 ndiv = ((p->frequency * (6 + 8) * 4) +
1001 (DS3000_XTAL_FREQ / 2)) /
1002 DS3000_XTAL_FREQ - 1024;
1003 } else {
1004 ds3000_tuner_writereg(state, 0x10, 0x01);
1005 ndiv = ((p->frequency * (6 + 8) * 2) +
1006 (DS3000_XTAL_FREQ / 2)) /
1007 DS3000_XTAL_FREQ - 1024;
1038 } 1008 }
1039 1009
1040 state->dnxt.delivery = c->modulation; 1010 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8);
1041 state->dnxt.frequency = c->frequency; 1011 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff);
1042 state->dnxt.rolloff = 2; /* fixme */ 1012
1043 state->dnxt.fec = c->fec_inner; 1013 /* set pll */
1014 ds3000_tuner_writereg(state, 0x03, 0x06);
1015 ds3000_tuner_writereg(state, 0x51, 0x0f);
1016 ds3000_tuner_writereg(state, 0x51, 0x1f);
1017 ds3000_tuner_writereg(state, 0x50, 0x10);
1018 ds3000_tuner_writereg(state, 0x50, 0x00);
1019 msleep(5);
1020
1021 /* unknown */
1022 ds3000_tuner_writereg(state, 0x51, 0x17);
1023 ds3000_tuner_writereg(state, 0x51, 0x1f);
1024 ds3000_tuner_writereg(state, 0x50, 0x08);
1025 ds3000_tuner_writereg(state, 0x50, 0x00);
1026 msleep(5);
1027
1028 value = ds3000_tuner_readreg(state, 0x3d);
1029 value &= 0x0f;
1030 if ((value > 4) && (value < 15)) {
1031 value -= 3;
1032 if (value < 4)
1033 value = 4;
1034 value = ((value << 3) | 0x01) & 0x79;
1035 }
1044 1036
1045 ret = ds3000_set_inversion(state, p->inversion); 1037 ds3000_tuner_writereg(state, 0x60, value);
1046 if (ret != 0) 1038 ds3000_tuner_writereg(state, 0x51, 0x17);
1047 return ret; 1039 ds3000_tuner_writereg(state, 0x51, 0x1f);
1040 ds3000_tuner_writereg(state, 0x50, 0x08);
1041 ds3000_tuner_writereg(state, 0x50, 0x00);
1042
1043 /* set low-pass filter period */
1044 ds3000_tuner_writereg(state, 0x04, 0x2e);
1045 ds3000_tuner_writereg(state, 0x51, 0x1b);
1046 ds3000_tuner_writereg(state, 0x51, 0x1f);
1047 ds3000_tuner_writereg(state, 0x50, 0x04);
1048 ds3000_tuner_writereg(state, 0x50, 0x00);
1049 msleep(5);
1050
1051 f3db = ((c->symbol_rate / 1000) << 2) / 5 + 2000;
1052 if ((c->symbol_rate / 1000) < 5000)
1053 f3db += 3000;
1054 if (f3db < 7000)
1055 f3db = 7000;
1056 if (f3db > 40000)
1057 f3db = 40000;
1058
1059 /* set low-pass filter baseband */
1060 value = ds3000_tuner_readreg(state, 0x26);
1061 mlpf = 0x2e * 207 / ((value << 1) + 151);
1062 mlpf_max = mlpf * 135 / 100;
1063 mlpf_min = mlpf * 78 / 100;
1064 if (mlpf_max > 63)
1065 mlpf_max = 63;
1066
1067 /* rounded to the closest integer */
1068 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1069 / (2766 * DS3000_XTAL_FREQ);
1070 if (nlpf > 23)
1071 nlpf = 23;
1072 if (nlpf < 1)
1073 nlpf = 1;
1074
1075 /* rounded to the closest integer */
1076 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1077 (1000 * f3db / 2)) / (1000 * f3db);
1078
1079 if (mlpf_new < mlpf_min) {
1080 nlpf++;
1081 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1082 (1000 * f3db / 2)) / (1000 * f3db);
1083 }
1048 1084
1049 ret = ds3000_set_symbolrate(state, c->symbol_rate); 1085 if (mlpf_new > mlpf_max)
1050 if (ret != 0) 1086 mlpf_new = mlpf_max;
1051 return ret; 1087
1088 ds3000_tuner_writereg(state, 0x04, mlpf_new);
1089 ds3000_tuner_writereg(state, 0x06, nlpf);
1090 ds3000_tuner_writereg(state, 0x51, 0x1b);
1091 ds3000_tuner_writereg(state, 0x51, 0x1f);
1092 ds3000_tuner_writereg(state, 0x50, 0x04);
1093 ds3000_tuner_writereg(state, 0x50, 0x00);
1094 msleep(5);
1095
1096 /* unknown */
1097 ds3000_tuner_writereg(state, 0x51, 0x1e);
1098 ds3000_tuner_writereg(state, 0x51, 0x1f);
1099 ds3000_tuner_writereg(state, 0x50, 0x01);
1100 ds3000_tuner_writereg(state, 0x50, 0x00);
1101 msleep(60);
1102
1103 offset_khz = (ndiv - ndiv % 2 + 1024) * DS3000_XTAL_FREQ
1104 / (6 + 8) / (div4 + 1) / 2 - p->frequency;
1105
1106 /* ds3000 global reset */
1107 ds3000_writereg(state, 0x07, 0x80);
1108 ds3000_writereg(state, 0x07, 0x00);
1109 /* ds3000 build-in uC reset */
1110 ds3000_writereg(state, 0xb2, 0x01);
1111 /* ds3000 software reset */
1112 ds3000_writereg(state, 0x00, 0x01);
1052 1113
1053 /* discard the 'current' tuning parameters and prepare to tune */ 1114 switch (c->delivery_system) {
1054 ds3000_clone_params(fe); 1115 case SYS_DVBS:
1055 1116 /* initialise the demod in DVB-S mode */
1056 retune = 1; /* try 1 times */ 1117 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2)
1057 dprintk("%s: retune = %d\n", __func__, retune); 1118 ds3000_writereg(state,
1058 dprintk("%s: frequency = %d\n", __func__, state->dcur.frequency); 1119 ds3000_dvbs_init_tab[i],
1059 dprintk("%s: symbol_rate = %d\n", __func__, state->dcur.symbol_rate); 1120 ds3000_dvbs_init_tab[i + 1]);
1060 dprintk("%s: FEC = %d \n", __func__, 1121 value = ds3000_readreg(state, 0xfe);
1061 state->dcur.fec); 1122 value &= 0xc0;
1062 dprintk("%s: Inversion = %d\n", __func__, state->dcur.inversion); 1123 value |= 0x1b;
1063 1124 ds3000_writereg(state, 0xfe, value);
1064 do { 1125 break;
1065 /* Reset status register */ 1126 case SYS_DVBS2:
1066 status = 0; 1127 /* initialise the demod in DVB-S2 mode */
1067 /* Tune */ 1128 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1068 /* TS2020 init */ 1129 ds3000_writereg(state,
1069 ds3000_tuner_writereg(state, 0x42, 0x73); 1130 ds3000_dvbs2_init_tab[i],
1070 ds3000_tuner_writereg(state, 0x05, 0x01); 1131 ds3000_dvbs2_init_tab[i + 1]);
1071 ds3000_tuner_writereg(state, 0x62, 0xf5); 1132 ds3000_writereg(state, 0xfe, 0x98);
1072 /* unknown */ 1133 break;
1073 ds3000_tuner_writereg(state, 0x07, 0x02); 1134 default:
1074 ds3000_tuner_writereg(state, 0x10, 0x00); 1135 return 1;
1075 ds3000_tuner_writereg(state, 0x60, 0x79); 1136 }
1076 ds3000_tuner_writereg(state, 0x08, 0x01);
1077 ds3000_tuner_writereg(state, 0x00, 0x01);
1078 /* calculate and set freq divider */
1079 if (state->dcur.frequency < 1146000) {
1080 ds3000_tuner_writereg(state, 0x10, 0x11);
1081 ndiv = ((state->dcur.frequency * (6 + 8) * 4) +
1082 (DS3000_XTAL_FREQ / 2)) /
1083 DS3000_XTAL_FREQ - 1024;
1084 } else {
1085 ds3000_tuner_writereg(state, 0x10, 0x01);
1086 ndiv = ((state->dcur.frequency * (6 + 8) * 2) +
1087 (DS3000_XTAL_FREQ / 2)) /
1088 DS3000_XTAL_FREQ - 1024;
1089 }
1090 1137
1091 ds3000_tuner_writereg(state, 0x01, (ndiv & 0x0f00) >> 8); 1138 /* enable 27MHz clock output */
1092 ds3000_tuner_writereg(state, 0x02, ndiv & 0x00ff); 1139 ds3000_writereg(state, 0x29, 0x80);
1093 1140 /* enable ac coupling */
1094 /* set pll */ 1141 ds3000_writereg(state, 0x25, 0x8a);
1095 ds3000_tuner_writereg(state, 0x03, 0x06); 1142
1096 ds3000_tuner_writereg(state, 0x51, 0x0f); 1143 /* enhance symbol rate performance */
1097 ds3000_tuner_writereg(state, 0x51, 0x1f); 1144 if ((c->symbol_rate / 1000) <= 5000) {
1098 ds3000_tuner_writereg(state, 0x50, 0x10); 1145 value = 29777 / (c->symbol_rate / 1000) + 1;
1099 ds3000_tuner_writereg(state, 0x50, 0x00); 1146 if (value % 2 != 0)
1100 msleep(5); 1147 value++;
1101 1148 ds3000_writereg(state, 0xc3, 0x0d);
1102 /* unknown */ 1149 ds3000_writereg(state, 0xc8, value);
1103 ds3000_tuner_writereg(state, 0x51, 0x17); 1150 ds3000_writereg(state, 0xc4, 0x10);
1104 ds3000_tuner_writereg(state, 0x51, 0x1f); 1151 ds3000_writereg(state, 0xc7, 0x0e);
1105 ds3000_tuner_writereg(state, 0x50, 0x08); 1152 } else if ((c->symbol_rate / 1000) <= 10000) {
1106 ds3000_tuner_writereg(state, 0x50, 0x00); 1153 value = 92166 / (c->symbol_rate / 1000) + 1;
1107 msleep(5); 1154 if (value % 2 != 0)
1108 1155 value++;
1109 value = ds3000_tuner_readreg(state, 0x3d); 1156 ds3000_writereg(state, 0xc3, 0x07);
1110 value &= 0x0f; 1157 ds3000_writereg(state, 0xc8, value);
1111 if ((value > 4) && (value < 15)) { 1158 ds3000_writereg(state, 0xc4, 0x09);
1112 value -= 3; 1159 ds3000_writereg(state, 0xc7, 0x12);
1113 if (value < 4) 1160 } else if ((c->symbol_rate / 1000) <= 20000) {
1114 value = 4; 1161 value = 64516 / (c->symbol_rate / 1000) + 1;
1115 value = ((value << 3) | 0x01) & 0x79; 1162 ds3000_writereg(state, 0xc3, value);
1116 } 1163 ds3000_writereg(state, 0xc8, 0x0e);
1164 ds3000_writereg(state, 0xc4, 0x07);
1165 ds3000_writereg(state, 0xc7, 0x18);
1166 } else {
1167 value = 129032 / (c->symbol_rate / 1000) + 1;
1168 ds3000_writereg(state, 0xc3, value);
1169 ds3000_writereg(state, 0xc8, 0x0a);
1170 ds3000_writereg(state, 0xc4, 0x05);
1171 ds3000_writereg(state, 0xc7, 0x24);
1172 }
1117 1173
1118 ds3000_tuner_writereg(state, 0x60, value); 1174 /* normalized symbol rate rounded to the closest integer */
1119 ds3000_tuner_writereg(state, 0x51, 0x17); 1175 value = (((c->symbol_rate / 1000) << 16) +
1120 ds3000_tuner_writereg(state, 0x51, 0x1f); 1176 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1121 ds3000_tuner_writereg(state, 0x50, 0x08); 1177 ds3000_writereg(state, 0x61, value & 0x00ff);
1122 ds3000_tuner_writereg(state, 0x50, 0x00); 1178 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1123
1124 /* set low-pass filter period */
1125 ds3000_tuner_writereg(state, 0x04, 0x2e);
1126 ds3000_tuner_writereg(state, 0x51, 0x1b);
1127 ds3000_tuner_writereg(state, 0x51, 0x1f);
1128 ds3000_tuner_writereg(state, 0x50, 0x04);
1129 ds3000_tuner_writereg(state, 0x50, 0x00);
1130 msleep(5);
1131
1132 f3db = ((state->dcur.symbol_rate / 1000) << 2) / 5 + 2000;
1133 if ((state->dcur.symbol_rate / 1000) < 5000)
1134 f3db += 3000;
1135 if (f3db < 7000)
1136 f3db = 7000;
1137 if (f3db > 40000)
1138 f3db = 40000;
1139
1140 /* set low-pass filter baseband */
1141 value = ds3000_tuner_readreg(state, 0x26);
1142 mlpf = 0x2e * 207 / ((value << 1) + 151);
1143 mlpf_max = mlpf * 135 / 100;
1144 mlpf_min = mlpf * 78 / 100;
1145 if (mlpf_max > 63)
1146 mlpf_max = 63;
1147
1148 /* rounded to the closest integer */
1149 nlpf = ((mlpf * f3db * 1000) + (2766 * DS3000_XTAL_FREQ / 2))
1150 / (2766 * DS3000_XTAL_FREQ);
1151 if (nlpf > 23)
1152 nlpf = 23;
1153 if (nlpf < 1)
1154 nlpf = 1;
1155
1156 /* rounded to the closest integer */
1157 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) +
1158 (1000 * f3db / 2)) / (1000 * f3db);
1159 1179
1160 if (mlpf_new < mlpf_min) { 1180 /* co-channel interference cancellation disabled */
1161 nlpf++; 1181 ds3000_writereg(state, 0x56, 0x00);
1162 mlpf_new = ((DS3000_XTAL_FREQ * nlpf * 2766) + 1182
1163 (1000 * f3db / 2)) / (1000 * f3db); 1183 /* equalizer disabled */
1164 } 1184 ds3000_writereg(state, 0x76, 0x00);
1165 1185
1166 if (mlpf_new > mlpf_max) 1186 /*ds3000_writereg(state, 0x08, 0x03);
1167 mlpf_new = mlpf_max; 1187 ds3000_writereg(state, 0xfd, 0x22);
1168 1188 ds3000_writereg(state, 0x08, 0x07);
1169 ds3000_tuner_writereg(state, 0x04, mlpf_new); 1189 ds3000_writereg(state, 0xfd, 0x42);
1170 ds3000_tuner_writereg(state, 0x06, nlpf); 1190 ds3000_writereg(state, 0x08, 0x07);*/
1171 ds3000_tuner_writereg(state, 0x51, 0x1b);
1172 ds3000_tuner_writereg(state, 0x51, 0x1f);
1173 ds3000_tuner_writereg(state, 0x50, 0x04);
1174 ds3000_tuner_writereg(state, 0x50, 0x00);
1175 msleep(5);
1176
1177 /* unknown */
1178 ds3000_tuner_writereg(state, 0x51, 0x1e);
1179 ds3000_tuner_writereg(state, 0x51, 0x1f);
1180 ds3000_tuner_writereg(state, 0x50, 0x01);
1181 ds3000_tuner_writereg(state, 0x50, 0x00);
1182 msleep(60);
1183
1184 /* ds3000 global reset */
1185 ds3000_writereg(state, 0x07, 0x80);
1186 ds3000_writereg(state, 0x07, 0x00);
1187 /* ds3000 build-in uC reset */
1188 ds3000_writereg(state, 0xb2, 0x01);
1189 /* ds3000 software reset */
1190 ds3000_writereg(state, 0x00, 0x01);
1191 1191
1192 if (state->config->ci_mode) {
1192 switch (c->delivery_system) { 1193 switch (c->delivery_system) {
1193 case SYS_DVBS: 1194 case SYS_DVBS:
1194 /* initialise the demod in DVB-S mode */ 1195 default:
1195 for (i = 0; i < sizeof(ds3000_dvbs_init_tab); i += 2) 1196 ds3000_writereg(state, 0xfd, 0x80);
1196 ds3000_writereg(state, 1197 break;
1197 ds3000_dvbs_init_tab[i],
1198 ds3000_dvbs_init_tab[i + 1]);
1199 value = ds3000_readreg(state, 0xfe);
1200 value &= 0xc0;
1201 value |= 0x1b;
1202 ds3000_writereg(state, 0xfe, value);
1203 break;
1204 case SYS_DVBS2: 1198 case SYS_DVBS2:
1205 /* initialise the demod in DVB-S2 mode */ 1199 ds3000_writereg(state, 0xfd, 0x01);
1206 for (i = 0; i < sizeof(ds3000_dvbs2_init_tab); i += 2)
1207 ds3000_writereg(state,
1208 ds3000_dvbs2_init_tab[i],
1209 ds3000_dvbs2_init_tab[i + 1]);
1210 ds3000_writereg(state, 0xfe, 0x54);
1211 break; 1200 break;
1212 default:
1213 return 1;
1214 } 1201 }
1202 }
1215 1203
1216 /* enable 27MHz clock output */ 1204 /* ds3000 out of software reset */
1217 ds3000_writereg(state, 0x29, 0x80); 1205 ds3000_writereg(state, 0x00, 0x00);
1218 /* enable ac coupling */ 1206 /* start ds3000 build-in uC */
1219 ds3000_writereg(state, 0x25, 0x8a); 1207 ds3000_writereg(state, 0xb2, 0x00);
1220
1221 /* enhance symbol rate performance */
1222 if ((state->dcur.symbol_rate / 1000) <= 5000) {
1223 value = 29777 / (state->dcur.symbol_rate / 1000) + 1;
1224 if (value % 2 != 0)
1225 value++;
1226 ds3000_writereg(state, 0xc3, 0x0d);
1227 ds3000_writereg(state, 0xc8, value);
1228 ds3000_writereg(state, 0xc4, 0x10);
1229 ds3000_writereg(state, 0xc7, 0x0e);
1230 } else if ((state->dcur.symbol_rate / 1000) <= 10000) {
1231 value = 92166 / (state->dcur.symbol_rate / 1000) + 1;
1232 if (value % 2 != 0)
1233 value++;
1234 ds3000_writereg(state, 0xc3, 0x07);
1235 ds3000_writereg(state, 0xc8, value);
1236 ds3000_writereg(state, 0xc4, 0x09);
1237 ds3000_writereg(state, 0xc7, 0x12);
1238 } else if ((state->dcur.symbol_rate / 1000) <= 20000) {
1239 value = 64516 / (state->dcur.symbol_rate / 1000) + 1;
1240 ds3000_writereg(state, 0xc3, value);
1241 ds3000_writereg(state, 0xc8, 0x0e);
1242 ds3000_writereg(state, 0xc4, 0x07);
1243 ds3000_writereg(state, 0xc7, 0x18);
1244 } else {
1245 value = 129032 / (state->dcur.symbol_rate / 1000) + 1;
1246 ds3000_writereg(state, 0xc3, value);
1247 ds3000_writereg(state, 0xc8, 0x0a);
1248 ds3000_writereg(state, 0xc4, 0x05);
1249 ds3000_writereg(state, 0xc7, 0x24);
1250 }
1251 1208
1252 /* normalized symbol rate rounded to the closest integer */ 1209 ds3000_set_carrier_offset(fe, offset_khz);
1253 value = (((state->dcur.symbol_rate / 1000) << 16) +
1254 (DS3000_SAMPLE_RATE / 2)) / DS3000_SAMPLE_RATE;
1255 ds3000_writereg(state, 0x61, value & 0x00ff);
1256 ds3000_writereg(state, 0x62, (value & 0xff00) >> 8);
1257
1258 /* co-channel interference cancellation disabled */
1259 ds3000_writereg(state, 0x56, 0x00);
1260
1261 /* equalizer disabled */
1262 ds3000_writereg(state, 0x76, 0x00);
1263
1264 /*ds3000_writereg(state, 0x08, 0x03);
1265 ds3000_writereg(state, 0xfd, 0x22);
1266 ds3000_writereg(state, 0x08, 0x07);
1267 ds3000_writereg(state, 0xfd, 0x42);
1268 ds3000_writereg(state, 0x08, 0x07);*/
1269
1270 /* ds3000 out of software reset */
1271 ds3000_writereg(state, 0x00, 0x00);
1272 /* start ds3000 build-in uC */
1273 ds3000_writereg(state, 0xb2, 0x00);
1274
1275 /* TODO: calculate and set carrier offset */
1276
1277 /* wait before retrying */
1278 for (i = 0; i < 30 ; i++) {
1279 if (ds3000_is_tuned(fe)) {
1280 dprintk("%s: Tuned\n", __func__);
1281 ds3000_dump_registers(fe);
1282 goto tuned;
1283 }
1284 msleep(1);
1285 }
1286 1210
1287 dprintk("%s: Not tuned\n", __func__); 1211 for (i = 0; i < 30 ; i++) {
1288 ds3000_dump_registers(fe); 1212 ds3000_read_status(fe, &status);
1213 if (status && FE_HAS_LOCK)
1214 break;
1289 1215
1290 } while (--retune); 1216 msleep(10);
1217 }
1291 1218
1292tuned: 1219 return 0;
1293 return ret; 1220}
1221
1222static int ds3000_tune(struct dvb_frontend *fe,
1223 struct dvb_frontend_parameters *p,
1224 unsigned int mode_flags,
1225 unsigned int *delay,
1226 fe_status_t *status)
1227{
1228 if (p) {
1229 int ret = ds3000_set_frontend(fe, p);
1230 if (ret)
1231 return ret;
1232 }
1233
1234 *delay = HZ / 5;
1235
1236 return ds3000_read_status(fe, status);
1294} 1237}
1295 1238
1296static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe) 1239static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1297{ 1240{
1298 dprintk("%s()\n", __func__); 1241 dprintk("%s()\n", __func__);
1299 return DVBFE_ALGO_SW; 1242 return DVBFE_ALGO_HW;
1300} 1243}
1301 1244
1302/* 1245/*
@@ -1306,7 +1249,25 @@ static enum dvbfe_algo ds3000_get_algo(struct dvb_frontend *fe)
1306 */ 1249 */
1307static int ds3000_initfe(struct dvb_frontend *fe) 1250static int ds3000_initfe(struct dvb_frontend *fe)
1308{ 1251{
1252 struct ds3000_state *state = fe->demodulator_priv;
1253 int ret;
1254
1309 dprintk("%s()\n", __func__); 1255 dprintk("%s()\n", __func__);
1256 /* hard reset */
1257 ds3000_writereg(state, 0x08, 0x01 | ds3000_readreg(state, 0x08));
1258 msleep(1);
1259
1260 /* TS2020 init */
1261 ds3000_tuner_writereg(state, 0x42, 0x73);
1262 ds3000_tuner_writereg(state, 0x05, 0x01);
1263 ds3000_tuner_writereg(state, 0x62, 0xf5);
1264 /* Load the firmware if required */
1265 ret = ds3000_firmware_ondemand(fe);
1266 if (ret != 0) {
1267 printk(KERN_ERR "%s: Unable initialize firmware\n", __func__);
1268 return ret;
1269 }
1270
1310 return 0; 1271 return 0;
1311} 1272}
1312 1273
@@ -1345,6 +1306,7 @@ static struct dvb_frontend_ops ds3000_ops = {
1345 .read_signal_strength = ds3000_read_signal_strength, 1306 .read_signal_strength = ds3000_read_signal_strength,
1346 .read_snr = ds3000_read_snr, 1307 .read_snr = ds3000_read_snr,
1347 .read_ucblocks = ds3000_read_ucblocks, 1308 .read_ucblocks = ds3000_read_ucblocks,
1309 .set_voltage = ds3000_set_voltage,
1348 .set_tone = ds3000_set_tone, 1310 .set_tone = ds3000_set_tone,
1349 .diseqc_send_master_cmd = ds3000_send_diseqc_msg, 1311 .diseqc_send_master_cmd = ds3000_send_diseqc_msg,
1350 .diseqc_send_burst = ds3000_diseqc_send_burst, 1312 .diseqc_send_burst = ds3000_diseqc_send_burst,
@@ -1352,7 +1314,8 @@ static struct dvb_frontend_ops ds3000_ops = {
1352 1314
1353 .set_property = ds3000_set_property, 1315 .set_property = ds3000_set_property,
1354 .get_property = ds3000_get_property, 1316 .get_property = ds3000_get_property,
1355 .set_frontend = ds3000_tune, 1317 .set_frontend = ds3000_set_frontend,
1318 .tune = ds3000_tune,
1356}; 1319};
1357 1320
1358module_param(debug, int, 0644); 1321module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/ds3000.h b/drivers/media/dvb/frontends/ds3000.h
index 67f67038740a..1b736888ea37 100644
--- a/drivers/media/dvb/frontends/ds3000.h
+++ b/drivers/media/dvb/frontends/ds3000.h
@@ -27,6 +27,9 @@
27struct ds3000_config { 27struct ds3000_config {
28 /* the demodulator's i2c address */ 28 /* the demodulator's i2c address */
29 u8 demod_address; 29 u8 demod_address;
30 u8 ci_mode;
31 /* Set device param to start dma */
32 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
30}; 33};
31 34
32#if defined(CONFIG_DVB_DS3000) || \ 35#if defined(CONFIG_DVB_DS3000) || \
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 4d4d0bb5920a..62a65efdf8d6 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -64,6 +64,7 @@ struct dvb_pll_desc {
64 void (*set)(struct dvb_frontend *fe, u8 *buf, 64 void (*set)(struct dvb_frontend *fe, u8 *buf,
65 const struct dvb_frontend_parameters *params); 65 const struct dvb_frontend_parameters *params);
66 u8 *initdata; 66 u8 *initdata;
67 u8 *initdata2;
67 u8 *sleepdata; 68 u8 *sleepdata;
68 int count; 69 int count;
69 struct { 70 struct {
@@ -321,26 +322,73 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = {
321static void opera1_bw(struct dvb_frontend *fe, u8 *buf, 322static void opera1_bw(struct dvb_frontend *fe, u8 *buf,
322 const struct dvb_frontend_parameters *params) 323 const struct dvb_frontend_parameters *params)
323{ 324{
324 if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) 325 struct dvb_pll_priv *priv = fe->tuner_priv;
325 buf[2] |= 0x08; 326 u32 b_w = (params->u.qpsk.symbol_rate * 27) / 32000;
327 struct i2c_msg msg = {
328 .addr = priv->pll_i2c_address,
329 .flags = 0,
330 .buf = buf,
331 .len = 4
332 };
333 int result;
334 u8 lpf;
335
336 if (fe->ops.i2c_gate_ctrl)
337 fe->ops.i2c_gate_ctrl(fe, 1);
338
339 result = i2c_transfer(priv->i2c, &msg, 1);
340 if (result != 1)
341 printk(KERN_ERR "%s: i2c_transfer failed:%d",
342 __func__, result);
343
344 if (b_w <= 10000)
345 lpf = 0xc;
346 else if (b_w <= 12000)
347 lpf = 0x2;
348 else if (b_w <= 14000)
349 lpf = 0xa;
350 else if (b_w <= 16000)
351 lpf = 0x6;
352 else if (b_w <= 18000)
353 lpf = 0xe;
354 else if (b_w <= 20000)
355 lpf = 0x1;
356 else if (b_w <= 22000)
357 lpf = 0x9;
358 else if (b_w <= 24000)
359 lpf = 0x5;
360 else if (b_w <= 26000)
361 lpf = 0xd;
362 else if (b_w <= 28000)
363 lpf = 0x3;
364 else
365 lpf = 0xb;
366 buf[2] ^= 0x1c; /* Flip bits 3-5 */
367 /* Set lpf */
368 buf[2] |= ((lpf >> 2) & 0x3) << 3;
369 buf[3] |= (lpf & 0x3) << 2;
370
371 return;
326} 372}
327 373
328static struct dvb_pll_desc dvb_pll_opera1 = { 374static struct dvb_pll_desc dvb_pll_opera1 = {
329 .name = "Opera Tuner", 375 .name = "Opera Tuner",
330 .min = 900000, 376 .min = 900000,
331 .max = 2250000, 377 .max = 2250000,
378 .initdata = (u8[]){ 4, 0x08, 0xe5, 0xe1, 0x00 },
379 .initdata2 = (u8[]){ 4, 0x08, 0xe5, 0xe5, 0x00 },
332 .iffreq= 0, 380 .iffreq= 0,
333 .set = opera1_bw, 381 .set = opera1_bw,
334 .count = 8, 382 .count = 8,
335 .entries = { 383 .entries = {
336 { 1064000, 500, 0xe5, 0xc6 }, 384 { 1064000, 500, 0xf9, 0xc2 },
337 { 1169000, 500, 0xe5, 0xe6 }, 385 { 1169000, 500, 0xf9, 0xe2 },
338 { 1299000, 500, 0xe5, 0x24 }, 386 { 1299000, 500, 0xf9, 0x20 },
339 { 1444000, 500, 0xe5, 0x44 }, 387 { 1444000, 500, 0xf9, 0x40 },
340 { 1606000, 500, 0xe5, 0x64 }, 388 { 1606000, 500, 0xf9, 0x60 },
341 { 1777000, 500, 0xe5, 0x84 }, 389 { 1777000, 500, 0xf9, 0x80 },
342 { 1941000, 500, 0xe5, 0xa4 }, 390 { 1941000, 500, 0xf9, 0xa0 },
343 { 2250000, 500, 0xe5, 0xc4 }, 391 { 2250000, 500, 0xf9, 0xc0 },
344 } 392 }
345}; 393};
346 394
@@ -648,8 +696,17 @@ static int dvb_pll_init(struct dvb_frontend *fe)
648 int result; 696 int result;
649 if (fe->ops.i2c_gate_ctrl) 697 if (fe->ops.i2c_gate_ctrl)
650 fe->ops.i2c_gate_ctrl(fe, 1); 698 fe->ops.i2c_gate_ctrl(fe, 1);
651 if ((result = i2c_transfer(priv->i2c, &msg, 1)) != 1) { 699 result = i2c_transfer(priv->i2c, &msg, 1);
700 if (result != 1)
652 return result; 701 return result;
702 if (priv->pll_desc->initdata2) {
703 msg.buf = priv->pll_desc->initdata2 + 1;
704 msg.len = priv->pll_desc->initdata2[0];
705 if (fe->ops.i2c_gate_ctrl)
706 fe->ops.i2c_gate_ctrl(fe, 1);
707 result = i2c_transfer(priv->i2c, &msg, 1);
708 if (result != 1)
709 return result;
653 } 710 }
654 return 0; 711 return 0;
655 } 712 }
diff --git a/drivers/media/dvb/frontends/stv0288.c b/drivers/media/dvb/frontends/stv0288.c
index 63db8fd2754c..e3fe17fd96fb 100644
--- a/drivers/media/dvb/frontends/stv0288.c
+++ b/drivers/media/dvb/frontends/stv0288.c
@@ -367,8 +367,11 @@ static int stv0288_read_status(struct dvb_frontend *fe, fe_status_t *status)
367 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync); 367 dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
368 368
369 *status = 0; 369 *status = 0;
370 370 if (sync & 0x80)
371 if ((sync & 0x08) == 0x08) { 371 *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
372 if (sync & 0x10)
373 *status |= FE_HAS_VITERBI;
374 if (sync & 0x08) {
372 *status |= FE_HAS_LOCK; 375 *status |= FE_HAS_LOCK;
373 dprintk("stv0288 has locked\n"); 376 dprintk("stv0288 has locked\n");
374 } 377 }
diff --git a/drivers/media/dvb/frontends/stv0367.c b/drivers/media/dvb/frontends/stv0367.c
new file mode 100644
index 000000000000..4e0e6a873b8c
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367.c
@@ -0,0 +1,3459 @@
1/*
2 * stv0367.c
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30#include <linux/i2c.h>
31
32#include "stv0367.h"
33#include "stv0367_regs.h"
34#include "stv0367_priv.h"
35
36static int stvdebug;
37module_param_named(debug, stvdebug, int, 0644);
38
39static int i2cdebug;
40module_param_named(i2c_debug, i2cdebug, int, 0644);
41
42#define dprintk(args...) \
43 do { \
44 if (stvdebug) \
45 printk(KERN_DEBUG args); \
46 } while (0)
47 /* DVB-C */
48
49struct stv0367cab_state {
50 enum stv0367_cab_signal_type state;
51 u32 mclk;
52 u32 adc_clk;
53 s32 search_range;
54 s32 derot_offset;
55 /* results */
56 int locked; /* channel found */
57 u32 freq_khz; /* found frequency (in kHz) */
58 u32 symbol_rate; /* found symbol rate (in Bds) */
59 enum stv0367cab_mod modulation; /* modulation */
60 fe_spectral_inversion_t spect_inv; /* Spectrum Inversion */
61};
62
63struct stv0367ter_state {
64 /* DVB-T */
65 enum stv0367_ter_signal_type state;
66 enum stv0367_ter_if_iq_mode if_iq_mode;
67 enum stv0367_ter_mode mode;/* mode 2K or 8K */
68 fe_guard_interval_t guard;
69 enum stv0367_ter_hierarchy hierarchy;
70 u32 frequency;
71 fe_spectral_inversion_t sense; /* current search spectrum */
72 u8 force; /* force mode/guard */
73 u8 bw; /* channel width 6, 7 or 8 in MHz */
74 u8 pBW; /* channel width used during previous lock */
75 u32 pBER;
76 u32 pPER;
77 u32 ucblocks;
78 s8 echo_pos; /* echo position */
79 u8 first_lock;
80 u8 unlock_counter;
81 u32 agc_val;
82};
83
84struct stv0367_state {
85 struct dvb_frontend fe;
86 struct i2c_adapter *i2c;
87 /* config settings */
88 const struct stv0367_config *config;
89 u8 chip_id;
90 /* DVB-C */
91 struct stv0367cab_state *cab_state;
92 /* DVB-T */
93 struct stv0367ter_state *ter_state;
94};
95
96struct st_register {
97 u16 addr;
98 u8 value;
99};
100
101/* values for STV4100 XTAL=30M int clk=53.125M*/
102static struct st_register def0367ter[STV0367TER_NBREGS] = {
103 {R367TER_ID, 0x60},
104 {R367TER_I2CRPT, 0xa0},
105 /* {R367TER_I2CRPT, 0x22},*/
106 {R367TER_TOPCTRL, 0x00},/* for xc5000; was 0x02 */
107 {R367TER_IOCFG0, 0x40},
108 {R367TER_DAC0R, 0x00},
109 {R367TER_IOCFG1, 0x00},
110 {R367TER_DAC1R, 0x00},
111 {R367TER_IOCFG2, 0x62},
112 {R367TER_SDFR, 0x00},
113 {R367TER_STATUS, 0xf8},
114 {R367TER_AUX_CLK, 0x0a},
115 {R367TER_FREESYS1, 0x00},
116 {R367TER_FREESYS2, 0x00},
117 {R367TER_FREESYS3, 0x00},
118 {R367TER_GPIO_CFG, 0x55},
119 {R367TER_GPIO_CMD, 0x00},
120 {R367TER_AGC2MAX, 0xff},
121 {R367TER_AGC2MIN, 0x00},
122 {R367TER_AGC1MAX, 0xff},
123 {R367TER_AGC1MIN, 0x00},
124 {R367TER_AGCR, 0xbc},
125 {R367TER_AGC2TH, 0x00},
126 {R367TER_AGC12C, 0x00},
127 {R367TER_AGCCTRL1, 0x85},
128 {R367TER_AGCCTRL2, 0x1f},
129 {R367TER_AGC1VAL1, 0x00},
130 {R367TER_AGC1VAL2, 0x00},
131 {R367TER_AGC2VAL1, 0x6f},
132 {R367TER_AGC2VAL2, 0x05},
133 {R367TER_AGC2PGA, 0x00},
134 {R367TER_OVF_RATE1, 0x00},
135 {R367TER_OVF_RATE2, 0x00},
136 {R367TER_GAIN_SRC1, 0xaa},/* for xc5000; was 0x2b */
137 {R367TER_GAIN_SRC2, 0xd6},/* for xc5000; was 0x04 */
138 {R367TER_INC_DEROT1, 0x55},
139 {R367TER_INC_DEROT2, 0x55},
140 {R367TER_PPM_CPAMP_DIR, 0x2c},
141 {R367TER_PPM_CPAMP_INV, 0x00},
142 {R367TER_FREESTFE_1, 0x00},
143 {R367TER_FREESTFE_2, 0x1c},
144 {R367TER_DCOFFSET, 0x00},
145 {R367TER_EN_PROCESS, 0x05},
146 {R367TER_SDI_SMOOTHER, 0x80},
147 {R367TER_FE_LOOP_OPEN, 0x1c},
148 {R367TER_FREQOFF1, 0x00},
149 {R367TER_FREQOFF2, 0x00},
150 {R367TER_FREQOFF3, 0x00},
151 {R367TER_TIMOFF1, 0x00},
152 {R367TER_TIMOFF2, 0x00},
153 {R367TER_EPQ, 0x02},
154 {R367TER_EPQAUTO, 0x01},
155 {R367TER_SYR_UPDATE, 0xf5},
156 {R367TER_CHPFREE, 0x00},
157 {R367TER_PPM_STATE_MAC, 0x23},
158 {R367TER_INR_THRESHOLD, 0xff},
159 {R367TER_EPQ_TPS_ID_CELL, 0xf9},
160 {R367TER_EPQ_CFG, 0x00},
161 {R367TER_EPQ_STATUS, 0x01},
162 {R367TER_AUTORELOCK, 0x81},
163 {R367TER_BER_THR_VMSB, 0x00},
164 {R367TER_BER_THR_MSB, 0x00},
165 {R367TER_BER_THR_LSB, 0x00},
166 {R367TER_CCD, 0x83},
167 {R367TER_SPECTR_CFG, 0x00},
168 {R367TER_CHC_DUMMY, 0x18},
169 {R367TER_INC_CTL, 0x88},
170 {R367TER_INCTHRES_COR1, 0xb4},
171 {R367TER_INCTHRES_COR2, 0x96},
172 {R367TER_INCTHRES_DET1, 0x0e},
173 {R367TER_INCTHRES_DET2, 0x11},
174 {R367TER_IIR_CELLNB, 0x8d},
175 {R367TER_IIRCX_COEFF1_MSB, 0x00},
176 {R367TER_IIRCX_COEFF1_LSB, 0x00},
177 {R367TER_IIRCX_COEFF2_MSB, 0x09},
178 {R367TER_IIRCX_COEFF2_LSB, 0x18},
179 {R367TER_IIRCX_COEFF3_MSB, 0x14},
180 {R367TER_IIRCX_COEFF3_LSB, 0x9c},
181 {R367TER_IIRCX_COEFF4_MSB, 0x00},
182 {R367TER_IIRCX_COEFF4_LSB, 0x00},
183 {R367TER_IIRCX_COEFF5_MSB, 0x36},
184 {R367TER_IIRCX_COEFF5_LSB, 0x42},
185 {R367TER_FEPATH_CFG, 0x00},
186 {R367TER_PMC1_FUNC, 0x65},
187 {R367TER_PMC1_FOR, 0x00},
188 {R367TER_PMC2_FUNC, 0x00},
189 {R367TER_STATUS_ERR_DA, 0xe0},
190 {R367TER_DIG_AGC_R, 0xfe},
191 {R367TER_COMAGC_TARMSB, 0x0b},
192 {R367TER_COM_AGC_TAR_ENMODE, 0x41},
193 {R367TER_COM_AGC_CFG, 0x3e},
194 {R367TER_COM_AGC_GAIN1, 0x39},
195 {R367TER_AUT_AGC_TARGETMSB, 0x0b},
196 {R367TER_LOCK_DET_MSB, 0x01},
197 {R367TER_AGCTAR_LOCK_LSBS, 0x40},
198 {R367TER_AUT_GAIN_EN, 0xf4},
199 {R367TER_AUT_CFG, 0xf0},
200 {R367TER_LOCKN, 0x23},
201 {R367TER_INT_X_3, 0x00},
202 {R367TER_INT_X_2, 0x03},
203 {R367TER_INT_X_1, 0x8d},
204 {R367TER_INT_X_0, 0xa0},
205 {R367TER_MIN_ERRX_MSB, 0x00},
206 {R367TER_COR_CTL, 0x23},
207 {R367TER_COR_STAT, 0xf6},
208 {R367TER_COR_INTEN, 0x00},
209 {R367TER_COR_INTSTAT, 0x3f},
210 {R367TER_COR_MODEGUARD, 0x03},
211 {R367TER_AGC_CTL, 0x08},
212 {R367TER_AGC_MANUAL1, 0x00},
213 {R367TER_AGC_MANUAL2, 0x00},
214 {R367TER_AGC_TARG, 0x16},
215 {R367TER_AGC_GAIN1, 0x53},
216 {R367TER_AGC_GAIN2, 0x1d},
217 {R367TER_RESERVED_1, 0x00},
218 {R367TER_RESERVED_2, 0x00},
219 {R367TER_RESERVED_3, 0x00},
220 {R367TER_CAS_CTL, 0x44},
221 {R367TER_CAS_FREQ, 0xb3},
222 {R367TER_CAS_DAGCGAIN, 0x12},
223 {R367TER_SYR_CTL, 0x04},
224 {R367TER_SYR_STAT, 0x10},
225 {R367TER_SYR_NCO1, 0x00},
226 {R367TER_SYR_NCO2, 0x00},
227 {R367TER_SYR_OFFSET1, 0x00},
228 {R367TER_SYR_OFFSET2, 0x00},
229 {R367TER_FFT_CTL, 0x00},
230 {R367TER_SCR_CTL, 0x70},
231 {R367TER_PPM_CTL1, 0xf8},
232 {R367TER_TRL_CTL, 0x14},/* for xc5000; was 0xac */
233 {R367TER_TRL_NOMRATE1, 0xae},/* for xc5000; was 0x1e */
234 {R367TER_TRL_NOMRATE2, 0x56},/* for xc5000; was 0x58 */
235 {R367TER_TRL_TIME1, 0x1d},
236 {R367TER_TRL_TIME2, 0xfc},
237 {R367TER_CRL_CTL, 0x24},
238 {R367TER_CRL_FREQ1, 0xad},
239 {R367TER_CRL_FREQ2, 0x9d},
240 {R367TER_CRL_FREQ3, 0xff},
241 {R367TER_CHC_CTL, 0x01},
242 {R367TER_CHC_SNR, 0xf0},
243 {R367TER_BDI_CTL, 0x00},
244 {R367TER_DMP_CTL, 0x00},
245 {R367TER_TPS_RCVD1, 0x30},
246 {R367TER_TPS_RCVD2, 0x02},
247 {R367TER_TPS_RCVD3, 0x01},
248 {R367TER_TPS_RCVD4, 0x00},
249 {R367TER_TPS_ID_CELL1, 0x00},
250 {R367TER_TPS_ID_CELL2, 0x00},
251 {R367TER_TPS_RCVD5_SET1, 0x02},
252 {R367TER_TPS_SET2, 0x02},
253 {R367TER_TPS_SET3, 0x01},
254 {R367TER_TPS_CTL, 0x00},
255 {R367TER_CTL_FFTOSNUM, 0x34},
256 {R367TER_TESTSELECT, 0x09},
257 {R367TER_MSC_REV, 0x0a},
258 {R367TER_PIR_CTL, 0x00},
259 {R367TER_SNR_CARRIER1, 0xa1},
260 {R367TER_SNR_CARRIER2, 0x9a},
261 {R367TER_PPM_CPAMP, 0x2c},
262 {R367TER_TSM_AP0, 0x00},
263 {R367TER_TSM_AP1, 0x00},
264 {R367TER_TSM_AP2 , 0x00},
265 {R367TER_TSM_AP3, 0x00},
266 {R367TER_TSM_AP4, 0x00},
267 {R367TER_TSM_AP5, 0x00},
268 {R367TER_TSM_AP6, 0x00},
269 {R367TER_TSM_AP7, 0x00},
270 {R367TER_TSTRES, 0x00},
271 {R367TER_ANACTRL, 0x0D},/* PLL stoped, restart at init!!! */
272 {R367TER_TSTBUS, 0x00},
273 {R367TER_TSTRATE, 0x00},
274 {R367TER_CONSTMODE, 0x01},
275 {R367TER_CONSTCARR1, 0x00},
276 {R367TER_CONSTCARR2, 0x00},
277 {R367TER_ICONSTEL, 0x0a},
278 {R367TER_QCONSTEL, 0x15},
279 {R367TER_TSTBISTRES0, 0x00},
280 {R367TER_TSTBISTRES1, 0x00},
281 {R367TER_TSTBISTRES2, 0x28},
282 {R367TER_TSTBISTRES3, 0x00},
283 {R367TER_RF_AGC1, 0xff},
284 {R367TER_RF_AGC2, 0x83},
285 {R367TER_ANADIGCTRL, 0x19},
286 {R367TER_PLLMDIV, 0x01},/* for xc5000; was 0x0c */
287 {R367TER_PLLNDIV, 0x06},/* for xc5000; was 0x55 */
288 {R367TER_PLLSETUP, 0x18},
289 {R367TER_DUAL_AD12, 0x0C},/* for xc5000 AGC voltage 1.6V */
290 {R367TER_TSTBIST, 0x00},
291 {R367TER_PAD_COMP_CTRL, 0x00},
292 {R367TER_PAD_COMP_WR, 0x00},
293 {R367TER_PAD_COMP_RD, 0xe0},
294 {R367TER_SYR_TARGET_FFTADJT_MSB, 0x00},
295 {R367TER_SYR_TARGET_FFTADJT_LSB, 0x00},
296 {R367TER_SYR_TARGET_CHCADJT_MSB, 0x00},
297 {R367TER_SYR_TARGET_CHCADJT_LSB, 0x00},
298 {R367TER_SYR_FLAG, 0x00},
299 {R367TER_CRL_TARGET1, 0x00},
300 {R367TER_CRL_TARGET2, 0x00},
301 {R367TER_CRL_TARGET3, 0x00},
302 {R367TER_CRL_TARGET4, 0x00},
303 {R367TER_CRL_FLAG, 0x00},
304 {R367TER_TRL_TARGET1, 0x00},
305 {R367TER_TRL_TARGET2, 0x00},
306 {R367TER_TRL_CHC, 0x00},
307 {R367TER_CHC_SNR_TARG, 0x00},
308 {R367TER_TOP_TRACK, 0x00},
309 {R367TER_TRACKER_FREE1, 0x00},
310 {R367TER_ERROR_CRL1, 0x00},
311 {R367TER_ERROR_CRL2, 0x00},
312 {R367TER_ERROR_CRL3, 0x00},
313 {R367TER_ERROR_CRL4, 0x00},
314 {R367TER_DEC_NCO1, 0x2c},
315 {R367TER_DEC_NCO2, 0x0f},
316 {R367TER_DEC_NCO3, 0x20},
317 {R367TER_SNR, 0xf1},
318 {R367TER_SYR_FFTADJ1, 0x00},
319 {R367TER_SYR_FFTADJ2, 0x00},
320 {R367TER_SYR_CHCADJ1, 0x00},
321 {R367TER_SYR_CHCADJ2, 0x00},
322 {R367TER_SYR_OFF, 0x00},
323 {R367TER_PPM_OFFSET1, 0x00},
324 {R367TER_PPM_OFFSET2, 0x03},
325 {R367TER_TRACKER_FREE2, 0x00},
326 {R367TER_DEBG_LT10, 0x00},
327 {R367TER_DEBG_LT11, 0x00},
328 {R367TER_DEBG_LT12, 0x00},
329 {R367TER_DEBG_LT13, 0x00},
330 {R367TER_DEBG_LT14, 0x00},
331 {R367TER_DEBG_LT15, 0x00},
332 {R367TER_DEBG_LT16, 0x00},
333 {R367TER_DEBG_LT17, 0x00},
334 {R367TER_DEBG_LT18, 0x00},
335 {R367TER_DEBG_LT19, 0x00},
336 {R367TER_DEBG_LT1A, 0x00},
337 {R367TER_DEBG_LT1B, 0x00},
338 {R367TER_DEBG_LT1C, 0x00},
339 {R367TER_DEBG_LT1D, 0x00},
340 {R367TER_DEBG_LT1E, 0x00},
341 {R367TER_DEBG_LT1F, 0x00},
342 {R367TER_RCCFGH, 0x00},
343 {R367TER_RCCFGM, 0x00},
344 {R367TER_RCCFGL, 0x00},
345 {R367TER_RCINSDELH, 0x00},
346 {R367TER_RCINSDELM, 0x00},
347 {R367TER_RCINSDELL, 0x00},
348 {R367TER_RCSTATUS, 0x00},
349 {R367TER_RCSPEED, 0x6f},
350 {R367TER_RCDEBUGM, 0xe7},
351 {R367TER_RCDEBUGL, 0x9b},
352 {R367TER_RCOBSCFG, 0x00},
353 {R367TER_RCOBSM, 0x00},
354 {R367TER_RCOBSL, 0x00},
355 {R367TER_RCFECSPY, 0x00},
356 {R367TER_RCFSPYCFG, 0x00},
357 {R367TER_RCFSPYDATA, 0x00},
358 {R367TER_RCFSPYOUT, 0x00},
359 {R367TER_RCFSTATUS, 0x00},
360 {R367TER_RCFGOODPACK, 0x00},
361 {R367TER_RCFPACKCNT, 0x00},
362 {R367TER_RCFSPYMISC, 0x00},
363 {R367TER_RCFBERCPT4, 0x00},
364 {R367TER_RCFBERCPT3, 0x00},
365 {R367TER_RCFBERCPT2, 0x00},
366 {R367TER_RCFBERCPT1, 0x00},
367 {R367TER_RCFBERCPT0, 0x00},
368 {R367TER_RCFBERERR2, 0x00},
369 {R367TER_RCFBERERR1, 0x00},
370 {R367TER_RCFBERERR0, 0x00},
371 {R367TER_RCFSTATESM, 0x00},
372 {R367TER_RCFSTATESL, 0x00},
373 {R367TER_RCFSPYBER, 0x00},
374 {R367TER_RCFSPYDISTM, 0x00},
375 {R367TER_RCFSPYDISTL, 0x00},
376 {R367TER_RCFSPYOBS7, 0x00},
377 {R367TER_RCFSPYOBS6, 0x00},
378 {R367TER_RCFSPYOBS5, 0x00},
379 {R367TER_RCFSPYOBS4, 0x00},
380 {R367TER_RCFSPYOBS3, 0x00},
381 {R367TER_RCFSPYOBS2, 0x00},
382 {R367TER_RCFSPYOBS1, 0x00},
383 {R367TER_RCFSPYOBS0, 0x00},
384 {R367TER_TSGENERAL, 0x00},
385 {R367TER_RC1SPEED, 0x6f},
386 {R367TER_TSGSTATUS, 0x18},
387 {R367TER_FECM, 0x01},
388 {R367TER_VTH12, 0xff},
389 {R367TER_VTH23, 0xa1},
390 {R367TER_VTH34, 0x64},
391 {R367TER_VTH56, 0x40},
392 {R367TER_VTH67, 0x00},
393 {R367TER_VTH78, 0x2c},
394 {R367TER_VITCURPUN, 0x12},
395 {R367TER_VERROR, 0x01},
396 {R367TER_PRVIT, 0x3f},
397 {R367TER_VAVSRVIT, 0x00},
398 {R367TER_VSTATUSVIT, 0xbd},
399 {R367TER_VTHINUSE, 0xa1},
400 {R367TER_KDIV12, 0x20},
401 {R367TER_KDIV23, 0x40},
402 {R367TER_KDIV34, 0x20},
403 {R367TER_KDIV56, 0x30},
404 {R367TER_KDIV67, 0x00},
405 {R367TER_KDIV78, 0x30},
406 {R367TER_SIGPOWER, 0x54},
407 {R367TER_DEMAPVIT, 0x40},
408 {R367TER_VITSCALE, 0x00},
409 {R367TER_FFEC1PRG, 0x00},
410 {R367TER_FVITCURPUN, 0x12},
411 {R367TER_FVERROR, 0x01},
412 {R367TER_FVSTATUSVIT, 0xbd},
413 {R367TER_DEBUG_LT1, 0x00},
414 {R367TER_DEBUG_LT2, 0x00},
415 {R367TER_DEBUG_LT3, 0x00},
416 {R367TER_TSTSFMET, 0x00},
417 {R367TER_SELOUT, 0x00},
418 {R367TER_TSYNC, 0x00},
419 {R367TER_TSTERR, 0x00},
420 {R367TER_TSFSYNC, 0x00},
421 {R367TER_TSTSFERR, 0x00},
422 {R367TER_TSTTSSF1, 0x01},
423 {R367TER_TSTTSSF2, 0x1f},
424 {R367TER_TSTTSSF3, 0x00},
425 {R367TER_TSTTS1, 0x00},
426 {R367TER_TSTTS2, 0x1f},
427 {R367TER_TSTTS3, 0x01},
428 {R367TER_TSTTS4, 0x00},
429 {R367TER_TSTTSRC, 0x00},
430 {R367TER_TSTTSRS, 0x00},
431 {R367TER_TSSTATEM, 0xb0},
432 {R367TER_TSSTATEL, 0x40},
433 {R367TER_TSCFGH, 0xC0},
434 {R367TER_TSCFGM, 0xc0},/* for xc5000; was 0x00 */
435 {R367TER_TSCFGL, 0x20},
436 {R367TER_TSSYNC, 0x00},
437 {R367TER_TSINSDELH, 0x00},
438 {R367TER_TSINSDELM, 0x00},
439 {R367TER_TSINSDELL, 0x00},
440 {R367TER_TSDIVN, 0x03},
441 {R367TER_TSDIVPM, 0x00},
442 {R367TER_TSDIVPL, 0x00},
443 {R367TER_TSDIVQM, 0x00},
444 {R367TER_TSDIVQL, 0x00},
445 {R367TER_TSDILSTKM, 0x00},
446 {R367TER_TSDILSTKL, 0x00},
447 {R367TER_TSSPEED, 0x40},/* for xc5000; was 0x6f */
448 {R367TER_TSSTATUS, 0x81},
449 {R367TER_TSSTATUS2, 0x6a},
450 {R367TER_TSBITRATEM, 0x0f},
451 {R367TER_TSBITRATEL, 0xc6},
452 {R367TER_TSPACKLENM, 0x00},
453 {R367TER_TSPACKLENL, 0xfc},
454 {R367TER_TSBLOCLENM, 0x0a},
455 {R367TER_TSBLOCLENL, 0x80},
456 {R367TER_TSDLYH, 0x90},
457 {R367TER_TSDLYM, 0x68},
458 {R367TER_TSDLYL, 0x01},
459 {R367TER_TSNPDAV, 0x00},
460 {R367TER_TSBUFSTATH, 0x00},
461 {R367TER_TSBUFSTATM, 0x00},
462 {R367TER_TSBUFSTATL, 0x00},
463 {R367TER_TSDEBUGM, 0xcf},
464 {R367TER_TSDEBUGL, 0x1e},
465 {R367TER_TSDLYSETH, 0x00},
466 {R367TER_TSDLYSETM, 0x68},
467 {R367TER_TSDLYSETL, 0x00},
468 {R367TER_TSOBSCFG, 0x00},
469 {R367TER_TSOBSM, 0x47},
470 {R367TER_TSOBSL, 0x1f},
471 {R367TER_ERRCTRL1, 0x95},
472 {R367TER_ERRCNT1H, 0x80},
473 {R367TER_ERRCNT1M, 0x00},
474 {R367TER_ERRCNT1L, 0x00},
475 {R367TER_ERRCTRL2, 0x95},
476 {R367TER_ERRCNT2H, 0x00},
477 {R367TER_ERRCNT2M, 0x00},
478 {R367TER_ERRCNT2L, 0x00},
479 {R367TER_FECSPY, 0x88},
480 {R367TER_FSPYCFG, 0x2c},
481 {R367TER_FSPYDATA, 0x3a},
482 {R367TER_FSPYOUT, 0x06},
483 {R367TER_FSTATUS, 0x61},
484 {R367TER_FGOODPACK, 0xff},
485 {R367TER_FPACKCNT, 0xff},
486 {R367TER_FSPYMISC, 0x66},
487 {R367TER_FBERCPT4, 0x00},
488 {R367TER_FBERCPT3, 0x00},
489 {R367TER_FBERCPT2, 0x36},
490 {R367TER_FBERCPT1, 0x36},
491 {R367TER_FBERCPT0, 0x14},
492 {R367TER_FBERERR2, 0x00},
493 {R367TER_FBERERR1, 0x03},
494 {R367TER_FBERERR0, 0x28},
495 {R367TER_FSTATESM, 0x00},
496 {R367TER_FSTATESL, 0x02},
497 {R367TER_FSPYBER, 0x00},
498 {R367TER_FSPYDISTM, 0x01},
499 {R367TER_FSPYDISTL, 0x9f},
500 {R367TER_FSPYOBS7, 0xc9},
501 {R367TER_FSPYOBS6, 0x99},
502 {R367TER_FSPYOBS5, 0x08},
503 {R367TER_FSPYOBS4, 0xec},
504 {R367TER_FSPYOBS3, 0x01},
505 {R367TER_FSPYOBS2, 0x0f},
506 {R367TER_FSPYOBS1, 0xf5},
507 {R367TER_FSPYOBS0, 0x08},
508 {R367TER_SFDEMAP, 0x40},
509 {R367TER_SFERROR, 0x00},
510 {R367TER_SFAVSR, 0x30},
511 {R367TER_SFECSTATUS, 0xcc},
512 {R367TER_SFKDIV12, 0x20},
513 {R367TER_SFKDIV23, 0x40},
514 {R367TER_SFKDIV34, 0x20},
515 {R367TER_SFKDIV56, 0x20},
516 {R367TER_SFKDIV67, 0x00},
517 {R367TER_SFKDIV78, 0x20},
518 {R367TER_SFDILSTKM, 0x00},
519 {R367TER_SFDILSTKL, 0x00},
520 {R367TER_SFSTATUS, 0xb5},
521 {R367TER_SFDLYH, 0x90},
522 {R367TER_SFDLYM, 0x60},
523 {R367TER_SFDLYL, 0x01},
524 {R367TER_SFDLYSETH, 0xc0},
525 {R367TER_SFDLYSETM, 0x60},
526 {R367TER_SFDLYSETL, 0x00},
527 {R367TER_SFOBSCFG, 0x00},
528 {R367TER_SFOBSM, 0x47},
529 {R367TER_SFOBSL, 0x05},
530 {R367TER_SFECINFO, 0x40},
531 {R367TER_SFERRCTRL, 0x74},
532 {R367TER_SFERRCNTH, 0x80},
533 {R367TER_SFERRCNTM , 0x00},
534 {R367TER_SFERRCNTL, 0x00},
535 {R367TER_SYMBRATEM, 0x2f},
536 {R367TER_SYMBRATEL, 0x50},
537 {R367TER_SYMBSTATUS, 0x7f},
538 {R367TER_SYMBCFG, 0x00},
539 {R367TER_SYMBFIFOM, 0xf4},
540 {R367TER_SYMBFIFOL, 0x0d},
541 {R367TER_SYMBOFFSM, 0xf0},
542 {R367TER_SYMBOFFSL, 0x2d},
543 {R367TER_DEBUG_LT4, 0x00},
544 {R367TER_DEBUG_LT5, 0x00},
545 {R367TER_DEBUG_LT6, 0x00},
546 {R367TER_DEBUG_LT7, 0x00},
547 {R367TER_DEBUG_LT8, 0x00},
548 {R367TER_DEBUG_LT9, 0x00},
549};
550
551#define RF_LOOKUP_TABLE_SIZE 31
552#define RF_LOOKUP_TABLE2_SIZE 16
553/* RF Level (for RF AGC->AGC1) Lookup Table, depends on the board and tuner.*/
554s32 stv0367cab_RF_LookUp1[RF_LOOKUP_TABLE_SIZE][RF_LOOKUP_TABLE_SIZE] = {
555 {/*AGC1*/
556 48, 50, 51, 53, 54, 56, 57, 58, 60, 61, 62, 63,
557 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
558 76, 77, 78, 80, 83, 85, 88,
559 }, {/*RF(dbm)*/
560 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,
561 34, 35, 36, 37, 38, 39, 41, 42, 43, 44, 46, 47,
562 49, 50, 52, 53, 54, 55, 56,
563 }
564};
565/* RF Level (for IF AGC->AGC2) Lookup Table, depends on the board and tuner.*/
566s32 stv0367cab_RF_LookUp2[RF_LOOKUP_TABLE2_SIZE][RF_LOOKUP_TABLE2_SIZE] = {
567 {/*AGC2*/
568 28, 29, 31, 32, 34, 35, 36, 37,
569 38, 39, 40, 41, 42, 43, 44, 45,
570 }, {/*RF(dbm)*/
571 57, 58, 59, 60, 61, 62, 63, 64,
572 65, 66, 67, 68, 69, 70, 71, 72,
573 }
574};
575
576static struct st_register def0367cab[STV0367CAB_NBREGS] = {
577 {R367CAB_ID, 0x60},
578 {R367CAB_I2CRPT, 0xa0},
579 /*{R367CAB_I2CRPT, 0x22},*/
580 {R367CAB_TOPCTRL, 0x10},
581 {R367CAB_IOCFG0, 0x80},
582 {R367CAB_DAC0R, 0x00},
583 {R367CAB_IOCFG1, 0x00},
584 {R367CAB_DAC1R, 0x00},
585 {R367CAB_IOCFG2, 0x00},
586 {R367CAB_SDFR, 0x00},
587 {R367CAB_AUX_CLK, 0x00},
588 {R367CAB_FREESYS1, 0x00},
589 {R367CAB_FREESYS2, 0x00},
590 {R367CAB_FREESYS3, 0x00},
591 {R367CAB_GPIO_CFG, 0x55},
592 {R367CAB_GPIO_CMD, 0x01},
593 {R367CAB_TSTRES, 0x00},
594 {R367CAB_ANACTRL, 0x0d},/* was 0x00 need to check - I.M.L.*/
595 {R367CAB_TSTBUS, 0x00},
596 {R367CAB_RF_AGC1, 0xea},
597 {R367CAB_RF_AGC2, 0x82},
598 {R367CAB_ANADIGCTRL, 0x0b},
599 {R367CAB_PLLMDIV, 0x01},
600 {R367CAB_PLLNDIV, 0x08},
601 {R367CAB_PLLSETUP, 0x18},
602 {R367CAB_DUAL_AD12, 0x0C}, /* for xc5000 AGC voltage 1.6V */
603 {R367CAB_TSTBIST, 0x00},
604 {R367CAB_CTRL_1, 0x00},
605 {R367CAB_CTRL_2, 0x03},
606 {R367CAB_IT_STATUS1, 0x2b},
607 {R367CAB_IT_STATUS2, 0x08},
608 {R367CAB_IT_EN1, 0x00},
609 {R367CAB_IT_EN2, 0x00},
610 {R367CAB_CTRL_STATUS, 0x04},
611 {R367CAB_TEST_CTL, 0x00},
612 {R367CAB_AGC_CTL, 0x73},
613 {R367CAB_AGC_IF_CFG, 0x50},
614 {R367CAB_AGC_RF_CFG, 0x00},
615 {R367CAB_AGC_PWM_CFG, 0x03},
616 {R367CAB_AGC_PWR_REF_L, 0x5a},
617 {R367CAB_AGC_PWR_REF_H, 0x00},
618 {R367CAB_AGC_RF_TH_L, 0xff},
619 {R367CAB_AGC_RF_TH_H, 0x07},
620 {R367CAB_AGC_IF_LTH_L, 0x00},
621 {R367CAB_AGC_IF_LTH_H, 0x08},
622 {R367CAB_AGC_IF_HTH_L, 0xff},
623 {R367CAB_AGC_IF_HTH_H, 0x07},
624 {R367CAB_AGC_PWR_RD_L, 0xa0},
625 {R367CAB_AGC_PWR_RD_M, 0xe9},
626 {R367CAB_AGC_PWR_RD_H, 0x03},
627 {R367CAB_AGC_PWM_IFCMD_L, 0xe4},
628 {R367CAB_AGC_PWM_IFCMD_H, 0x00},
629 {R367CAB_AGC_PWM_RFCMD_L, 0xff},
630 {R367CAB_AGC_PWM_RFCMD_H, 0x07},
631 {R367CAB_IQDEM_CFG, 0x01},
632 {R367CAB_MIX_NCO_LL, 0x22},
633 {R367CAB_MIX_NCO_HL, 0x96},
634 {R367CAB_MIX_NCO_HH, 0x55},
635 {R367CAB_SRC_NCO_LL, 0xff},
636 {R367CAB_SRC_NCO_LH, 0x0c},
637 {R367CAB_SRC_NCO_HL, 0xf5},
638 {R367CAB_SRC_NCO_HH, 0x20},
639 {R367CAB_IQDEM_GAIN_SRC_L, 0x06},
640 {R367CAB_IQDEM_GAIN_SRC_H, 0x01},
641 {R367CAB_IQDEM_DCRM_CFG_LL, 0xfe},
642 {R367CAB_IQDEM_DCRM_CFG_LH, 0xff},
643 {R367CAB_IQDEM_DCRM_CFG_HL, 0x0f},
644 {R367CAB_IQDEM_DCRM_CFG_HH, 0x00},
645 {R367CAB_IQDEM_ADJ_COEFF0, 0x34},
646 {R367CAB_IQDEM_ADJ_COEFF1, 0xae},
647 {R367CAB_IQDEM_ADJ_COEFF2, 0x46},
648 {R367CAB_IQDEM_ADJ_COEFF3, 0x77},
649 {R367CAB_IQDEM_ADJ_COEFF4, 0x96},
650 {R367CAB_IQDEM_ADJ_COEFF5, 0x69},
651 {R367CAB_IQDEM_ADJ_COEFF6, 0xc7},
652 {R367CAB_IQDEM_ADJ_COEFF7, 0x01},
653 {R367CAB_IQDEM_ADJ_EN, 0x04},
654 {R367CAB_IQDEM_ADJ_AGC_REF, 0x94},
655 {R367CAB_ALLPASSFILT1, 0xc9},
656 {R367CAB_ALLPASSFILT2, 0x2d},
657 {R367CAB_ALLPASSFILT3, 0xa3},
658 {R367CAB_ALLPASSFILT4, 0xfb},
659 {R367CAB_ALLPASSFILT5, 0xf6},
660 {R367CAB_ALLPASSFILT6, 0x45},
661 {R367CAB_ALLPASSFILT7, 0x6f},
662 {R367CAB_ALLPASSFILT8, 0x7e},
663 {R367CAB_ALLPASSFILT9, 0x05},
664 {R367CAB_ALLPASSFILT10, 0x0a},
665 {R367CAB_ALLPASSFILT11, 0x51},
666 {R367CAB_TRL_AGC_CFG, 0x20},
667 {R367CAB_TRL_LPF_CFG, 0x28},
668 {R367CAB_TRL_LPF_ACQ_GAIN, 0x44},
669 {R367CAB_TRL_LPF_TRK_GAIN, 0x22},
670 {R367CAB_TRL_LPF_OUT_GAIN, 0x03},
671 {R367CAB_TRL_LOCKDET_LTH, 0x04},
672 {R367CAB_TRL_LOCKDET_HTH, 0x11},
673 {R367CAB_TRL_LOCKDET_TRGVAL, 0x20},
674 {R367CAB_IQ_QAM, 0x01},
675 {R367CAB_FSM_STATE, 0xa0},
676 {R367CAB_FSM_CTL, 0x08},
677 {R367CAB_FSM_STS, 0x0c},
678 {R367CAB_FSM_SNR0_HTH, 0x00},
679 {R367CAB_FSM_SNR1_HTH, 0x00},
680 {R367CAB_FSM_SNR2_HTH, 0x23},/* 0x00 */
681 {R367CAB_FSM_SNR0_LTH, 0x00},
682 {R367CAB_FSM_SNR1_LTH, 0x00},
683 {R367CAB_FSM_EQA1_HTH, 0x00},
684 {R367CAB_FSM_TEMPO, 0x32},
685 {R367CAB_FSM_CONFIG, 0x03},
686 {R367CAB_EQU_I_TESTTAP_L, 0x11},
687 {R367CAB_EQU_I_TESTTAP_M, 0x00},
688 {R367CAB_EQU_I_TESTTAP_H, 0x00},
689 {R367CAB_EQU_TESTAP_CFG, 0x00},
690 {R367CAB_EQU_Q_TESTTAP_L, 0xff},
691 {R367CAB_EQU_Q_TESTTAP_M, 0x00},
692 {R367CAB_EQU_Q_TESTTAP_H, 0x00},
693 {R367CAB_EQU_TAP_CTRL, 0x00},
694 {R367CAB_EQU_CTR_CRL_CONTROL_L, 0x11},
695 {R367CAB_EQU_CTR_CRL_CONTROL_H, 0x05},
696 {R367CAB_EQU_CTR_HIPOW_L, 0x00},
697 {R367CAB_EQU_CTR_HIPOW_H, 0x00},
698 {R367CAB_EQU_I_EQU_LO, 0xef},
699 {R367CAB_EQU_I_EQU_HI, 0x00},
700 {R367CAB_EQU_Q_EQU_LO, 0xee},
701 {R367CAB_EQU_Q_EQU_HI, 0x00},
702 {R367CAB_EQU_MAPPER, 0xc5},
703 {R367CAB_EQU_SWEEP_RATE, 0x80},
704 {R367CAB_EQU_SNR_LO, 0x64},
705 {R367CAB_EQU_SNR_HI, 0x03},
706 {R367CAB_EQU_GAMMA_LO, 0x00},
707 {R367CAB_EQU_GAMMA_HI, 0x00},
708 {R367CAB_EQU_ERR_GAIN, 0x36},
709 {R367CAB_EQU_RADIUS, 0xaa},
710 {R367CAB_EQU_FFE_MAINTAP, 0x00},
711 {R367CAB_EQU_FFE_LEAKAGE, 0x63},
712 {R367CAB_EQU_FFE_MAINTAP_POS, 0xdf},
713 {R367CAB_EQU_GAIN_WIDE, 0x88},
714 {R367CAB_EQU_GAIN_NARROW, 0x41},
715 {R367CAB_EQU_CTR_LPF_GAIN, 0xd1},
716 {R367CAB_EQU_CRL_LPF_GAIN, 0xa7},
717 {R367CAB_EQU_GLOBAL_GAIN, 0x06},
718 {R367CAB_EQU_CRL_LD_SEN, 0x85},
719 {R367CAB_EQU_CRL_LD_VAL, 0xe2},
720 {R367CAB_EQU_CRL_TFR, 0x20},
721 {R367CAB_EQU_CRL_BISTH_LO, 0x00},
722 {R367CAB_EQU_CRL_BISTH_HI, 0x00},
723 {R367CAB_EQU_SWEEP_RANGE_LO, 0x00},
724 {R367CAB_EQU_SWEEP_RANGE_HI, 0x00},
725 {R367CAB_EQU_CRL_LIMITER, 0x40},
726 {R367CAB_EQU_MODULUS_MAP, 0x90},
727 {R367CAB_EQU_PNT_GAIN, 0xa7},
728 {R367CAB_FEC_AC_CTR_0, 0x16},
729 {R367CAB_FEC_AC_CTR_1, 0x0b},
730 {R367CAB_FEC_AC_CTR_2, 0x88},
731 {R367CAB_FEC_AC_CTR_3, 0x02},
732 {R367CAB_FEC_STATUS, 0x12},
733 {R367CAB_RS_COUNTER_0, 0x7d},
734 {R367CAB_RS_COUNTER_1, 0xd0},
735 {R367CAB_RS_COUNTER_2, 0x19},
736 {R367CAB_RS_COUNTER_3, 0x0b},
737 {R367CAB_RS_COUNTER_4, 0xa3},
738 {R367CAB_RS_COUNTER_5, 0x00},
739 {R367CAB_BERT_0, 0x01},
740 {R367CAB_BERT_1, 0x25},
741 {R367CAB_BERT_2, 0x41},
742 {R367CAB_BERT_3, 0x39},
743 {R367CAB_OUTFORMAT_0, 0xc2},
744 {R367CAB_OUTFORMAT_1, 0x22},
745 {R367CAB_SMOOTHER_2, 0x28},
746 {R367CAB_TSMF_CTRL_0, 0x01},
747 {R367CAB_TSMF_CTRL_1, 0xc6},
748 {R367CAB_TSMF_CTRL_3, 0x43},
749 {R367CAB_TS_ON_ID_0, 0x00},
750 {R367CAB_TS_ON_ID_1, 0x00},
751 {R367CAB_TS_ON_ID_2, 0x00},
752 {R367CAB_TS_ON_ID_3, 0x00},
753 {R367CAB_RE_STATUS_0, 0x00},
754 {R367CAB_RE_STATUS_1, 0x00},
755 {R367CAB_RE_STATUS_2, 0x00},
756 {R367CAB_RE_STATUS_3, 0x00},
757 {R367CAB_TS_STATUS_0, 0x00},
758 {R367CAB_TS_STATUS_1, 0x00},
759 {R367CAB_TS_STATUS_2, 0xa0},
760 {R367CAB_TS_STATUS_3, 0x00},
761 {R367CAB_T_O_ID_0, 0x00},
762 {R367CAB_T_O_ID_1, 0x00},
763 {R367CAB_T_O_ID_2, 0x00},
764 {R367CAB_T_O_ID_3, 0x00},
765};
766
767static
768int stv0367_writeregs(struct stv0367_state *state, u16 reg, u8 *data, int len)
769{
770 u8 buf[len + 2];
771 struct i2c_msg msg = {
772 .addr = state->config->demod_address,
773 .flags = 0,
774 .buf = buf,
775 .len = len + 2
776 };
777 int ret;
778
779 buf[0] = MSB(reg);
780 buf[1] = LSB(reg);
781 memcpy(buf + 2, data, len);
782
783 if (i2cdebug)
784 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, buf[2]);
785
786 ret = i2c_transfer(state->i2c, &msg, 1);
787 if (ret != 1)
788 printk(KERN_ERR "%s: i2c write error!\n", __func__);
789
790 return (ret != 1) ? -EREMOTEIO : 0;
791}
792
793static int stv0367_writereg(struct stv0367_state *state, u16 reg, u8 data)
794{
795 return stv0367_writeregs(state, reg, &data, 1);
796}
797
798static u8 stv0367_readreg(struct stv0367_state *state, u16 reg)
799{
800 u8 b0[] = { 0, 0 };
801 u8 b1[] = { 0 };
802 struct i2c_msg msg[] = {
803 {
804 .addr = state->config->demod_address,
805 .flags = 0,
806 .buf = b0,
807 .len = 2
808 }, {
809 .addr = state->config->demod_address,
810 .flags = I2C_M_RD,
811 .buf = b1,
812 .len = 1
813 }
814 };
815 int ret;
816
817 b0[0] = MSB(reg);
818 b0[1] = LSB(reg);
819
820 ret = i2c_transfer(state->i2c, msg, 2);
821 if (ret != 2)
822 printk(KERN_ERR "%s: i2c read error\n", __func__);
823
824 if (i2cdebug)
825 printk(KERN_DEBUG "%s: %02x: %02x\n", __func__, reg, b1[0]);
826
827 return b1[0];
828}
829
830static void extract_mask_pos(u32 label, u8 *mask, u8 *pos)
831{
832 u8 position = 0, i = 0;
833
834 (*mask) = label & 0xff;
835
836 while ((position == 0) && (i < 8)) {
837 position = ((*mask) >> i) & 0x01;
838 i++;
839 }
840
841 (*pos) = (i - 1);
842}
843
844static void stv0367_writebits(struct stv0367_state *state, u32 label, u8 val)
845{
846 u8 reg, mask, pos;
847
848 reg = stv0367_readreg(state, (label >> 16) & 0xffff);
849 extract_mask_pos(label, &mask, &pos);
850
851 val = mask & (val << pos);
852
853 reg = (reg & (~mask)) | val;
854 stv0367_writereg(state, (label >> 16) & 0xffff, reg);
855
856}
857
858static void stv0367_setbits(u8 *reg, u32 label, u8 val)
859{
860 u8 mask, pos;
861
862 extract_mask_pos(label, &mask, &pos);
863
864 val = mask & (val << pos);
865
866 (*reg) = ((*reg) & (~mask)) | val;
867}
868
869static u8 stv0367_readbits(struct stv0367_state *state, u32 label)
870{
871 u8 val = 0xff;
872 u8 mask, pos;
873
874 extract_mask_pos(label, &mask, &pos);
875
876 val = stv0367_readreg(state, label >> 16);
877 val = (val & mask) >> pos;
878
879 return val;
880}
881
882u8 stv0367_getbits(u8 reg, u32 label)
883{
884 u8 mask, pos;
885
886 extract_mask_pos(label, &mask, &pos);
887
888 return (reg & mask) >> pos;
889}
890
891static int stv0367ter_gate_ctrl(struct dvb_frontend *fe, int enable)
892{
893 struct stv0367_state *state = fe->demodulator_priv;
894 u8 tmp = stv0367_readreg(state, R367TER_I2CRPT);
895
896 dprintk("%s:\n", __func__);
897
898 if (enable) {
899 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 0);
900 stv0367_setbits(&tmp, F367TER_I2CT_ON, 1);
901 } else {
902 stv0367_setbits(&tmp, F367TER_STOP_ENABLE, 1);
903 stv0367_setbits(&tmp, F367TER_I2CT_ON, 0);
904 }
905
906 stv0367_writereg(state, R367TER_I2CRPT, tmp);
907
908 return 0;
909}
910
911static u32 stv0367_get_tuner_freq(struct dvb_frontend *fe)
912{
913 struct dvb_frontend_ops *frontend_ops = NULL;
914 struct dvb_tuner_ops *tuner_ops = NULL;
915 u32 freq = 0;
916 int err = 0;
917
918 dprintk("%s:\n", __func__);
919
920
921 if (&fe->ops)
922 frontend_ops = &fe->ops;
923 if (&frontend_ops->tuner_ops)
924 tuner_ops = &frontend_ops->tuner_ops;
925 if (tuner_ops->get_frequency) {
926 err = tuner_ops->get_frequency(fe, &freq);
927 if (err < 0) {
928 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
929 return err;
930 }
931
932 dprintk("%s: frequency=%d\n", __func__, freq);
933
934 } else
935 return -1;
936
937 return freq;
938}
939
940static u16 CellsCoeffs_8MHz_367cofdm[3][6][5] = {
941 {
942 {0x10EF, 0xE205, 0x10EF, 0xCE49, 0x6DA7}, /* CELL 1 COEFFS 27M*/
943 {0x2151, 0xc557, 0x2151, 0xc705, 0x6f93}, /* CELL 2 COEFFS */
944 {0x2503, 0xc000, 0x2503, 0xc375, 0x7194}, /* CELL 3 COEFFS */
945 {0x20E9, 0xca94, 0x20e9, 0xc153, 0x7194}, /* CELL 4 COEFFS */
946 {0x06EF, 0xF852, 0x06EF, 0xC057, 0x7207}, /* CELL 5 COEFFS */
947 {0x0000, 0x0ECC, 0x0ECC, 0x0000, 0x3647} /* CELL 6 COEFFS */
948 }, {
949 {0x10A0, 0xE2AF, 0x10A1, 0xCE76, 0x6D6D}, /* CELL 1 COEFFS 25M*/
950 {0x20DC, 0xC676, 0x20D9, 0xC80A, 0x6F29},
951 {0x2532, 0xC000, 0x251D, 0xC391, 0x706F},
952 {0x1F7A, 0xCD2B, 0x2032, 0xC15E, 0x711F},
953 {0x0698, 0xFA5E, 0x0568, 0xC059, 0x7193},
954 {0x0000, 0x0918, 0x149C, 0x0000, 0x3642} /* CELL 6 COEFFS */
955 }, {
956 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
957 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
958 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
959 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
960 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
961 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
962 }
963};
964
965static u16 CellsCoeffs_7MHz_367cofdm[3][6][5] = {
966 {
967 {0x12CA, 0xDDAF, 0x12CA, 0xCCEB, 0x6FB1}, /* CELL 1 COEFFS 27M*/
968 {0x2329, 0xC000, 0x2329, 0xC6B0, 0x725F}, /* CELL 2 COEFFS */
969 {0x2394, 0xC000, 0x2394, 0xC2C7, 0x7410}, /* CELL 3 COEFFS */
970 {0x251C, 0xC000, 0x251C, 0xC103, 0x74D9}, /* CELL 4 COEFFS */
971 {0x0804, 0xF546, 0x0804, 0xC040, 0x7544}, /* CELL 5 COEFFS */
972 {0x0000, 0x0CD9, 0x0CD9, 0x0000, 0x370A} /* CELL 6 COEFFS */
973 }, {
974 {0x1285, 0xDE47, 0x1285, 0xCD17, 0x6F76}, /*25M*/
975 {0x234C, 0xC000, 0x2348, 0xC6DA, 0x7206},
976 {0x23B4, 0xC000, 0x23AC, 0xC2DB, 0x73B3},
977 {0x253D, 0xC000, 0x25B6, 0xC10B, 0x747F},
978 {0x0721, 0xF79C, 0x065F, 0xC041, 0x74EB},
979 {0x0000, 0x08FA, 0x1162, 0x0000, 0x36FF}
980 }, {
981 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
982 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
983 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
984 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
985 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
986 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
987 }
988};
989
990static u16 CellsCoeffs_6MHz_367cofdm[3][6][5] = {
991 {
992 {0x1699, 0xD5B8, 0x1699, 0xCBC3, 0x713B}, /* CELL 1 COEFFS 27M*/
993 {0x2245, 0xC000, 0x2245, 0xC568, 0x74D5}, /* CELL 2 COEFFS */
994 {0x227F, 0xC000, 0x227F, 0xC1FC, 0x76C6}, /* CELL 3 COEFFS */
995 {0x235E, 0xC000, 0x235E, 0xC0A7, 0x778A}, /* CELL 4 COEFFS */
996 {0x0ECB, 0xEA0B, 0x0ECB, 0xC027, 0x77DD}, /* CELL 5 COEFFS */
997 {0x0000, 0x0B68, 0x0B68, 0x0000, 0xC89A}, /* CELL 6 COEFFS */
998 }, {
999 {0x1655, 0xD64E, 0x1658, 0xCBEF, 0x70FE}, /*25M*/
1000 {0x225E, 0xC000, 0x2256, 0xC589, 0x7489},
1001 {0x2293, 0xC000, 0x2295, 0xC209, 0x767E},
1002 {0x2377, 0xC000, 0x23AA, 0xC0AB, 0x7746},
1003 {0x0DC7, 0xEBC8, 0x0D07, 0xC027, 0x7799},
1004 {0x0000, 0x0888, 0x0E9C, 0x0000, 0x3757}
1005
1006 }, {
1007 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}, /* 30M */
1008 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1009 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1010 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1011 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000},
1012 {0x0000, 0x0000, 0x0000, 0x0000, 0x0000}
1013 }
1014};
1015
1016static u32 stv0367ter_get_mclk(struct stv0367_state *state, u32 ExtClk_Hz)
1017{
1018 u32 mclk_Hz = 0; /* master clock frequency (Hz) */
1019 u32 m, n, p;
1020
1021 dprintk("%s:\n", __func__);
1022
1023 if (stv0367_readbits(state, F367TER_BYPASS_PLLXN) == 0) {
1024 n = (u32)stv0367_readbits(state, F367TER_PLL_NDIV);
1025 if (n == 0)
1026 n = n + 1;
1027
1028 m = (u32)stv0367_readbits(state, F367TER_PLL_MDIV);
1029 if (m == 0)
1030 m = m + 1;
1031
1032 p = (u32)stv0367_readbits(state, F367TER_PLL_PDIV);
1033 if (p > 5)
1034 p = 5;
1035
1036 mclk_Hz = ((ExtClk_Hz / 2) * n) / (m * (1 << p));
1037
1038 dprintk("N=%d M=%d P=%d mclk_Hz=%d ExtClk_Hz=%d\n",
1039 n, m, p, mclk_Hz, ExtClk_Hz);
1040 } else
1041 mclk_Hz = ExtClk_Hz;
1042
1043 dprintk("%s: mclk_Hz=%d\n", __func__, mclk_Hz);
1044
1045 return mclk_Hz;
1046}
1047
1048static int stv0367ter_filt_coeff_init(struct stv0367_state *state,
1049 u16 CellsCoeffs[3][6][5], u32 DemodXtal)
1050{
1051 int i, j, k, freq;
1052
1053 dprintk("%s:\n", __func__);
1054
1055 freq = stv0367ter_get_mclk(state, DemodXtal);
1056
1057 if (freq == 53125000)
1058 k = 1; /* equivalent to Xtal 25M on 362*/
1059 else if (freq == 54000000)
1060 k = 0; /* equivalent to Xtal 27M on 362*/
1061 else if (freq == 52500000)
1062 k = 2; /* equivalent to Xtal 30M on 362*/
1063 else
1064 return 0;
1065
1066 for (i = 1; i <= 6; i++) {
1067 stv0367_writebits(state, F367TER_IIR_CELL_NB, i - 1);
1068
1069 for (j = 1; j <= 5; j++) {
1070 stv0367_writereg(state,
1071 (R367TER_IIRCX_COEFF1_MSB + 2 * (j - 1)),
1072 MSB(CellsCoeffs[k][i-1][j-1]));
1073 stv0367_writereg(state,
1074 (R367TER_IIRCX_COEFF1_LSB + 2 * (j - 1)),
1075 LSB(CellsCoeffs[k][i-1][j-1]));
1076 }
1077 }
1078
1079 return 1;
1080
1081}
1082
1083static void stv0367ter_agc_iir_lock_detect_set(struct stv0367_state *state)
1084{
1085 dprintk("%s:\n", __func__);
1086
1087 stv0367_writebits(state, F367TER_LOCK_DETECT_LSB, 0x00);
1088
1089 /* Lock detect 1 */
1090 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x00);
1091 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1092 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1093
1094 /* Lock detect 2 */
1095 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x01);
1096 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x06);
1097 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x04);
1098
1099 /* Lock detect 3 */
1100 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x02);
1101 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1102 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1103
1104 /* Lock detect 4 */
1105 stv0367_writebits(state, F367TER_LOCK_DETECT_CHOICE, 0x03);
1106 stv0367_writebits(state, F367TER_LOCK_DETECT_MSB, 0x01);
1107 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_LSB, 0x00);
1108
1109}
1110
1111static int stv0367_iir_filt_init(struct stv0367_state *state, u8 Bandwidth,
1112 u32 DemodXtalValue)
1113{
1114 dprintk("%s:\n", __func__);
1115
1116 stv0367_writebits(state, F367TER_NRST_IIR, 0);
1117
1118 switch (Bandwidth) {
1119 case 6:
1120 if (!stv0367ter_filt_coeff_init(state,
1121 CellsCoeffs_6MHz_367cofdm,
1122 DemodXtalValue))
1123 return 0;
1124 break;
1125 case 7:
1126 if (!stv0367ter_filt_coeff_init(state,
1127 CellsCoeffs_7MHz_367cofdm,
1128 DemodXtalValue))
1129 return 0;
1130 break;
1131 case 8:
1132 if (!stv0367ter_filt_coeff_init(state,
1133 CellsCoeffs_8MHz_367cofdm,
1134 DemodXtalValue))
1135 return 0;
1136 break;
1137 default:
1138 return 0;
1139 }
1140
1141 stv0367_writebits(state, F367TER_NRST_IIR, 1);
1142
1143 return 1;
1144}
1145
1146static void stv0367ter_agc_iir_rst(struct stv0367_state *state)
1147{
1148
1149 u8 com_n;
1150
1151 dprintk("%s:\n", __func__);
1152
1153 com_n = stv0367_readbits(state, F367TER_COM_N);
1154
1155 stv0367_writebits(state, F367TER_COM_N, 0x07);
1156
1157 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x00);
1158 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x00);
1159
1160 stv0367_writebits(state, F367TER_COM_SOFT_RSTN, 0x01);
1161 stv0367_writebits(state, F367TER_COM_AGC_ON, 0x01);
1162
1163 stv0367_writebits(state, F367TER_COM_N, com_n);
1164
1165}
1166
1167static int stv0367ter_duration(s32 mode, int tempo1, int tempo2, int tempo3)
1168{
1169 int local_tempo = 0;
1170 switch (mode) {
1171 case 0:
1172 local_tempo = tempo1;
1173 break;
1174 case 1:
1175 local_tempo = tempo2;
1176 break ;
1177
1178 case 2:
1179 local_tempo = tempo3;
1180 break;
1181
1182 default:
1183 break;
1184 }
1185 /* msleep(local_tempo); */
1186 return local_tempo;
1187}
1188
1189static enum
1190stv0367_ter_signal_type stv0367ter_check_syr(struct stv0367_state *state)
1191{
1192 int wd = 100;
1193 unsigned short int SYR_var;
1194 s32 SYRStatus;
1195
1196 dprintk("%s:\n", __func__);
1197
1198 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1199
1200 while ((!SYR_var) && (wd > 0)) {
1201 usleep_range(2000, 3000);
1202 wd -= 2;
1203 SYR_var = stv0367_readbits(state, F367TER_SYR_LOCK);
1204 }
1205
1206 if (!SYR_var)
1207 SYRStatus = FE_TER_NOSYMBOL;
1208 else
1209 SYRStatus = FE_TER_SYMBOLOK;
1210
1211 dprintk("stv0367ter_check_syr SYRStatus %s\n",
1212 SYR_var == 0 ? "No Symbol" : "OK");
1213
1214 return SYRStatus;
1215}
1216
1217static enum
1218stv0367_ter_signal_type stv0367ter_check_cpamp(struct stv0367_state *state,
1219 s32 FFTmode)
1220{
1221
1222 s32 CPAMPvalue = 0, CPAMPStatus, CPAMPMin;
1223 int wd = 0;
1224
1225 dprintk("%s:\n", __func__);
1226
1227 switch (FFTmode) {
1228 case 0: /*2k mode*/
1229 CPAMPMin = 20;
1230 wd = 10;
1231 break;
1232 case 1: /*8k mode*/
1233 CPAMPMin = 80;
1234 wd = 55;
1235 break;
1236 case 2: /*4k mode*/
1237 CPAMPMin = 40;
1238 wd = 30;
1239 break;
1240 default:
1241 CPAMPMin = 0xffff; /*drives to NOCPAMP */
1242 break;
1243 }
1244
1245 dprintk("%s: CPAMPMin=%d wd=%d\n", __func__, CPAMPMin, wd);
1246
1247 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1248 while ((CPAMPvalue < CPAMPMin) && (wd > 0)) {
1249 usleep_range(1000, 2000);
1250 wd -= 1;
1251 CPAMPvalue = stv0367_readbits(state, F367TER_PPM_CPAMP_DIRECT);
1252 /*dprintk("CPAMPvalue= %d at wd=%d\n",CPAMPvalue,wd); */
1253 }
1254 dprintk("******last CPAMPvalue= %d at wd=%d\n", CPAMPvalue, wd);
1255 if (CPAMPvalue < CPAMPMin) {
1256 CPAMPStatus = FE_TER_NOCPAMP;
1257 printk(KERN_ERR "CPAMP failed\n");
1258 } else {
1259 printk(KERN_ERR "CPAMP OK !\n");
1260 CPAMPStatus = FE_TER_CPAMPOK;
1261 }
1262
1263 return CPAMPStatus;
1264}
1265
1266enum
1267stv0367_ter_signal_type stv0367ter_lock_algo(struct stv0367_state *state)
1268{
1269 enum stv0367_ter_signal_type ret_flag;
1270 short int wd, tempo;
1271 u8 try, u_var1 = 0, u_var2 = 0, u_var3 = 0, u_var4 = 0, mode, guard;
1272 u8 tmp, tmp2;
1273
1274 dprintk("%s:\n", __func__);
1275
1276 if (state == NULL)
1277 return FE_TER_SWNOK;
1278
1279 try = 0;
1280 do {
1281 ret_flag = FE_TER_LOCKOK;
1282
1283 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1284
1285 if (state->config->if_iq_mode != 0)
1286 stv0367_writebits(state, F367TER_COM_N, 0x07);
1287
1288 stv0367_writebits(state, F367TER_GUARD, 3);/* suggest 2k 1/4 */
1289 stv0367_writebits(state, F367TER_MODE, 0);
1290 stv0367_writebits(state, F367TER_SYR_TR_DIS, 0);
1291 usleep_range(5000, 10000);
1292
1293 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1294
1295
1296 if (stv0367ter_check_syr(state) == FE_TER_NOSYMBOL)
1297 return FE_TER_NOSYMBOL;
1298 else { /*
1299 if chip locked on wrong mode first try,
1300 it must lock correctly second try */
1301 mode = stv0367_readbits(state, F367TER_SYR_MODE);
1302 if (stv0367ter_check_cpamp(state, mode) ==
1303 FE_TER_NOCPAMP) {
1304 if (try == 0)
1305 ret_flag = FE_TER_NOCPAMP;
1306
1307 }
1308 }
1309
1310 try++;
1311 } while ((try < 10) && (ret_flag != FE_TER_LOCKOK));
1312
1313 tmp = stv0367_readreg(state, R367TER_SYR_STAT);
1314 tmp2 = stv0367_readreg(state, R367TER_STATUS);
1315 dprintk("state=%p\n", state);
1316 dprintk("LOCK OK! mode=%d SYR_STAT=0x%x R367TER_STATUS=0x%x\n",
1317 mode, tmp, tmp2);
1318
1319 tmp = stv0367_readreg(state, R367TER_PRVIT);
1320 tmp2 = stv0367_readreg(state, R367TER_I2CRPT);
1321 dprintk("PRVIT=0x%x I2CRPT=0x%x\n", tmp, tmp2);
1322
1323 tmp = stv0367_readreg(state, R367TER_GAIN_SRC1);
1324 dprintk("GAIN_SRC1=0x%x\n", tmp);
1325
1326 if ((mode != 0) && (mode != 1) && (mode != 2))
1327 return FE_TER_SWNOK;
1328
1329 /*guard=stv0367_readbits(state,F367TER_SYR_GUARD); */
1330
1331 /*supress EPQ auto for SYR_GARD 1/16 or 1/32
1332 and set channel predictor in automatic */
1333#if 0
1334 switch (guard) {
1335
1336 case 0:
1337 case 1:
1338 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1339 stv0367_writereg(state, R367TER_CHC_CTL, 0x01);
1340 break;
1341 case 2:
1342 case 3:
1343 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1344 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1345 break;
1346
1347 default:
1348 return FE_TER_SWNOK;
1349 }
1350#endif
1351
1352 /*reset fec an reedsolo FOR 367 only*/
1353 stv0367_writebits(state, F367TER_RST_SFEC, 1);
1354 stv0367_writebits(state, F367TER_RST_REEDSOLO, 1);
1355 usleep_range(1000, 2000);
1356 stv0367_writebits(state, F367TER_RST_SFEC, 0);
1357 stv0367_writebits(state, F367TER_RST_REEDSOLO, 0);
1358
1359 u_var1 = stv0367_readbits(state, F367TER_LK);
1360 u_var2 = stv0367_readbits(state, F367TER_PRF);
1361 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1362 /* u_var4=stv0367_readbits(state,F367TER_TSFIFO_LINEOK); */
1363
1364 wd = stv0367ter_duration(mode, 125, 500, 250);
1365 tempo = stv0367ter_duration(mode, 4, 16, 8);
1366
1367 /*while ( ((!u_var1)||(!u_var2)||(!u_var3)||(!u_var4)) && (wd>=0)) */
1368 while (((!u_var1) || (!u_var2) || (!u_var3)) && (wd >= 0)) {
1369 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1370 wd -= tempo;
1371 u_var1 = stv0367_readbits(state, F367TER_LK);
1372 u_var2 = stv0367_readbits(state, F367TER_PRF);
1373 u_var3 = stv0367_readbits(state, F367TER_TPS_LOCK);
1374 /*u_var4=stv0367_readbits(state, F367TER_TSFIFO_LINEOK); */
1375 }
1376
1377 if (!u_var1)
1378 return FE_TER_NOLOCK;
1379
1380
1381 if (!u_var2)
1382 return FE_TER_NOPRFOUND;
1383
1384 if (!u_var3)
1385 return FE_TER_NOTPS;
1386
1387 guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1388 stv0367_writereg(state, R367TER_CHC_CTL, 0x11);
1389 switch (guard) {
1390 case 0:
1391 case 1:
1392 stv0367_writebits(state, F367TER_AUTO_LE_EN, 0);
1393 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x1);*/
1394 stv0367_writebits(state, F367TER_SYR_FILTER, 0);
1395 break;
1396 case 2:
1397 case 3:
1398 stv0367_writebits(state, F367TER_AUTO_LE_EN, 1);
1399 /*stv0367_writereg(state,R367TER_CHC_CTL, 0x11);*/
1400 stv0367_writebits(state, F367TER_SYR_FILTER, 1);
1401 break;
1402
1403 default:
1404 return FE_TER_SWNOK;
1405 }
1406
1407 /* apply Sfec workaround if 8K 64QAM CR!=1/2*/
1408 if ((stv0367_readbits(state, F367TER_TPS_CONST) == 2) &&
1409 (mode == 1) &&
1410 (stv0367_readbits(state, F367TER_TPS_HPCODE) != 0)) {
1411 stv0367_writereg(state, R367TER_SFDLYSETH, 0xc0);
1412 stv0367_writereg(state, R367TER_SFDLYSETM, 0x60);
1413 stv0367_writereg(state, R367TER_SFDLYSETL, 0x0);
1414 } else
1415 stv0367_writereg(state, R367TER_SFDLYSETH, 0x0);
1416
1417 wd = stv0367ter_duration(mode, 125, 500, 250);
1418 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1419
1420 while ((!u_var4) && (wd >= 0)) {
1421 usleep_range(1000 * tempo, 1000 * (tempo + 1));
1422 wd -= tempo;
1423 u_var4 = stv0367_readbits(state, F367TER_TSFIFO_LINEOK);
1424 }
1425
1426 if (!u_var4)
1427 return FE_TER_NOLOCK;
1428
1429 /* for 367 leave COM_N at 0x7 for IQ_mode*/
1430 /*if(ter_state->if_iq_mode!=FE_TER_NORMAL_IF_TUNER) {
1431 tempo=0;
1432 while ((stv0367_readbits(state,F367TER_COM_USEGAINTRK)!=1) &&
1433 (stv0367_readbits(state,F367TER_COM_AGCLOCK)!=1)&&(tempo<100)) {
1434 ChipWaitOrAbort(state,1);
1435 tempo+=1;
1436 }
1437
1438 stv0367_writebits(state,F367TER_COM_N,0x17);
1439 } */
1440
1441 stv0367_writebits(state, F367TER_SYR_TR_DIS, 1);
1442
1443 dprintk("FE_TER_LOCKOK !!!\n");
1444
1445 return FE_TER_LOCKOK;
1446
1447}
1448
1449static void stv0367ter_set_ts_mode(struct stv0367_state *state,
1450 enum stv0367_ts_mode PathTS)
1451{
1452
1453 dprintk("%s:\n", __func__);
1454
1455 if (state == NULL)
1456 return;
1457
1458 stv0367_writebits(state, F367TER_TS_DIS, 0);
1459 switch (PathTS) {
1460 default:
1461 /*for removing warning :default we can assume in parallel mode*/
1462 case STV0367_PARALLEL_PUNCT_CLOCK:
1463 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 0);
1464 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 0);
1465 break;
1466 case STV0367_SERIAL_PUNCT_CLOCK:
1467 stv0367_writebits(state, F367TER_TSFIFO_SERIAL, 1);
1468 stv0367_writebits(state, F367TER_TSFIFO_DVBCI, 1);
1469 break;
1470 }
1471}
1472
1473static void stv0367ter_set_clk_pol(struct stv0367_state *state,
1474 enum stv0367_clk_pol clock)
1475{
1476
1477 dprintk("%s:\n", __func__);
1478
1479 if (state == NULL)
1480 return;
1481
1482 switch (clock) {
1483 case STV0367_RISINGEDGE_CLOCK:
1484 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 1);
1485 break;
1486 case STV0367_FALLINGEDGE_CLOCK:
1487 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1488 break;
1489 /*case FE_TER_CLOCK_POLARITY_DEFAULT:*/
1490 default:
1491 stv0367_writebits(state, F367TER_TS_BYTE_CLK_INV, 0);
1492 break;
1493 }
1494}
1495
1496#if 0
1497static void stv0367ter_core_sw(struct stv0367_state *state)
1498{
1499
1500 dprintk("%s:\n", __func__);
1501
1502 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1503 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1504 msleep(350);
1505}
1506#endif
1507static int stv0367ter_standby(struct dvb_frontend *fe, u8 standby_on)
1508{
1509 struct stv0367_state *state = fe->demodulator_priv;
1510
1511 dprintk("%s:\n", __func__);
1512
1513 if (standby_on) {
1514 stv0367_writebits(state, F367TER_STDBY, 1);
1515 stv0367_writebits(state, F367TER_STDBY_FEC, 1);
1516 stv0367_writebits(state, F367TER_STDBY_CORE, 1);
1517 } else {
1518 stv0367_writebits(state, F367TER_STDBY, 0);
1519 stv0367_writebits(state, F367TER_STDBY_FEC, 0);
1520 stv0367_writebits(state, F367TER_STDBY_CORE, 0);
1521 }
1522
1523 return 0;
1524}
1525
1526static int stv0367ter_sleep(struct dvb_frontend *fe)
1527{
1528 return stv0367ter_standby(fe, 1);
1529}
1530
1531int stv0367ter_init(struct dvb_frontend *fe)
1532{
1533 struct stv0367_state *state = fe->demodulator_priv;
1534 struct stv0367ter_state *ter_state = state->ter_state;
1535 int i;
1536
1537 dprintk("%s:\n", __func__);
1538
1539 ter_state->pBER = 0;
1540
1541 for (i = 0; i < STV0367TER_NBREGS; i++)
1542 stv0367_writereg(state, def0367ter[i].addr,
1543 def0367ter[i].value);
1544
1545 switch (state->config->xtal) {
1546 /*set internal freq to 53.125MHz */
1547 case 25000000:
1548 stv0367_writereg(state, R367TER_PLLMDIV, 0xa);
1549 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1550 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1551 break;
1552 default:
1553 case 27000000:
1554 dprintk("FE_STV0367TER_SetCLKgen for 27Mhz\n");
1555 stv0367_writereg(state, R367TER_PLLMDIV, 0x1);
1556 stv0367_writereg(state, R367TER_PLLNDIV, 0x8);
1557 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1558 break;
1559 case 30000000:
1560 stv0367_writereg(state, R367TER_PLLMDIV, 0xc);
1561 stv0367_writereg(state, R367TER_PLLNDIV, 0x55);
1562 stv0367_writereg(state, R367TER_PLLSETUP, 0x18);
1563 break;
1564 }
1565
1566 stv0367_writereg(state, R367TER_I2CRPT, 0xa0);
1567 stv0367_writereg(state, R367TER_ANACTRL, 0x00);
1568
1569 /*Set TS1 and TS2 to serial or parallel mode */
1570 stv0367ter_set_ts_mode(state, state->config->ts_mode);
1571 stv0367ter_set_clk_pol(state, state->config->clk_pol);
1572
1573 state->chip_id = stv0367_readreg(state, R367TER_ID);
1574 ter_state->first_lock = 0;
1575 ter_state->unlock_counter = 2;
1576
1577 return 0;
1578}
1579
1580static int stv0367ter_algo(struct dvb_frontend *fe,
1581 struct dvb_frontend_parameters *param)
1582{
1583 struct stv0367_state *state = fe->demodulator_priv;
1584 struct stv0367ter_state *ter_state = state->ter_state;
1585 int offset = 0, tempo = 0;
1586 u8 u_var;
1587 u8 /*constell,*/ counter, tps_rcvd[2];
1588 s8 step;
1589 s32 timing_offset = 0;
1590 u32 trl_nomrate = 0, InternalFreq = 0, temp = 0;
1591
1592 dprintk("%s:\n", __func__);
1593
1594 ter_state->frequency = param->frequency;
1595 ter_state->force = FE_TER_FORCENONE
1596 + stv0367_readbits(state, F367TER_FORCE) * 2;
1597 ter_state->if_iq_mode = state->config->if_iq_mode;
1598 switch (state->config->if_iq_mode) {
1599 case FE_TER_NORMAL_IF_TUNER: /* Normal IF mode */
1600 dprintk("ALGO: FE_TER_NORMAL_IF_TUNER selected\n");
1601 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1602 stv0367_writebits(state, F367TER_LONGPATH_IF, 0);
1603 stv0367_writebits(state, F367TER_DEMUX_SWAP, 0);
1604 break;
1605 case FE_TER_LONGPATH_IF_TUNER: /* Long IF mode */
1606 dprintk("ALGO: FE_TER_LONGPATH_IF_TUNER selected\n");
1607 stv0367_writebits(state, F367TER_TUNER_BB, 0);
1608 stv0367_writebits(state, F367TER_LONGPATH_IF, 1);
1609 stv0367_writebits(state, F367TER_DEMUX_SWAP, 1);
1610 break;
1611 case FE_TER_IQ_TUNER: /* IQ mode */
1612 dprintk("ALGO: FE_TER_IQ_TUNER selected\n");
1613 stv0367_writebits(state, F367TER_TUNER_BB, 1);
1614 stv0367_writebits(state, F367TER_PPM_INVSEL, 0);
1615 break;
1616 default:
1617 printk(KERN_ERR "ALGO: wrong TUNER type selected\n");
1618 return -EINVAL;
1619 }
1620
1621 usleep_range(5000, 7000);
1622
1623 switch (param->inversion) {
1624 case INVERSION_AUTO:
1625 default:
1626 dprintk("%s: inversion AUTO\n", __func__);
1627 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1628 stv0367_writebits(state, F367TER_IQ_INVERT,
1629 ter_state->sense);
1630 else
1631 stv0367_writebits(state, F367TER_INV_SPECTR,
1632 ter_state->sense);
1633
1634 break;
1635 case INVERSION_ON:
1636 case INVERSION_OFF:
1637 if (ter_state->if_iq_mode == FE_TER_IQ_TUNER)
1638 stv0367_writebits(state, F367TER_IQ_INVERT,
1639 param->inversion);
1640 else
1641 stv0367_writebits(state, F367TER_INV_SPECTR,
1642 param->inversion);
1643
1644 break;
1645 }
1646
1647 if ((ter_state->if_iq_mode != FE_TER_NORMAL_IF_TUNER) &&
1648 (ter_state->pBW != ter_state->bw)) {
1649 stv0367ter_agc_iir_lock_detect_set(state);
1650
1651 /*set fine agc target to 180 for LPIF or IQ mode*/
1652 /* set Q_AGCTarget */
1653 stv0367_writebits(state, F367TER_SEL_IQNTAR, 1);
1654 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1655 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1656
1657 /* set Q_AGCTarget */
1658 stv0367_writebits(state, F367TER_SEL_IQNTAR, 0);
1659 stv0367_writebits(state, F367TER_AUT_AGC_TARGET_MSB, 0xB);
1660 /*stv0367_writebits(state,AUT_AGC_TARGET_LSB,0x04); */
1661
1662 if (!stv0367_iir_filt_init(state, ter_state->bw,
1663 state->config->xtal))
1664 return -EINVAL;
1665 /*set IIR filter once for 6,7 or 8MHz BW*/
1666 ter_state->pBW = ter_state->bw;
1667
1668 stv0367ter_agc_iir_rst(state);
1669 }
1670
1671 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1672 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x01);
1673 else
1674 stv0367_writebits(state, F367TER_BDI_LPSEL, 0x00);
1675
1676 InternalFreq = stv0367ter_get_mclk(state, state->config->xtal) / 1000;
1677 temp = (int)
1678 ((((ter_state->bw * 64 * (1 << 15) * 100)
1679 / (InternalFreq)) * 10) / 7);
1680
1681 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB, temp % 2);
1682 temp = temp / 2;
1683 stv0367_writebits(state, F367TER_TRL_NOMRATE_HI, temp / 256);
1684 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO, temp % 256);
1685
1686 temp = stv0367_readbits(state, F367TER_TRL_NOMRATE_HI) * 512 +
1687 stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2 +
1688 stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB);
1689 temp = (int)(((1 << 17) * ter_state->bw * 1000) / (7 * (InternalFreq)));
1690 stv0367_writebits(state, F367TER_GAIN_SRC_HI, temp / 256);
1691 stv0367_writebits(state, F367TER_GAIN_SRC_LO, temp % 256);
1692 temp = stv0367_readbits(state, F367TER_GAIN_SRC_HI) * 256 +
1693 stv0367_readbits(state, F367TER_GAIN_SRC_LO);
1694
1695 temp = (int)
1696 ((InternalFreq - state->config->if_khz) * (1 << 16)
1697 / (InternalFreq));
1698
1699 dprintk("DEROT temp=0x%x\n", temp);
1700 stv0367_writebits(state, F367TER_INC_DEROT_HI, temp / 256);
1701 stv0367_writebits(state, F367TER_INC_DEROT_LO, temp % 256);
1702
1703 ter_state->echo_pos = 0;
1704 ter_state->ucblocks = 0; /* liplianin */
1705 ter_state->pBER = 0; /* liplianin */
1706 stv0367_writebits(state, F367TER_LONG_ECHO, ter_state->echo_pos);
1707
1708 if (stv0367ter_lock_algo(state) != FE_TER_LOCKOK)
1709 return 0;
1710
1711 ter_state->state = FE_TER_LOCKOK;
1712 /* update results */
1713 tps_rcvd[0] = stv0367_readreg(state, R367TER_TPS_RCVD2);
1714 tps_rcvd[1] = stv0367_readreg(state, R367TER_TPS_RCVD3);
1715
1716 ter_state->mode = stv0367_readbits(state, F367TER_SYR_MODE);
1717 ter_state->guard = stv0367_readbits(state, F367TER_SYR_GUARD);
1718
1719 ter_state->first_lock = 1; /* we know sense now :) */
1720
1721 ter_state->agc_val =
1722 (stv0367_readbits(state, F367TER_AGC1_VAL_LO) << 16) +
1723 (stv0367_readbits(state, F367TER_AGC1_VAL_HI) << 24) +
1724 stv0367_readbits(state, F367TER_AGC2_VAL_LO) +
1725 (stv0367_readbits(state, F367TER_AGC2_VAL_HI) << 8);
1726
1727 /* Carrier offset calculation */
1728 stv0367_writebits(state, F367TER_FREEZE, 1);
1729 offset = (stv0367_readbits(state, F367TER_CRL_FOFFSET_VHI) << 16) ;
1730 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_HI) << 8);
1731 offset += (stv0367_readbits(state, F367TER_CRL_FOFFSET_LO));
1732 stv0367_writebits(state, F367TER_FREEZE, 0);
1733 if (offset > 8388607)
1734 offset -= 16777216;
1735
1736 offset = offset * 2 / 16384;
1737
1738 if (ter_state->mode == FE_TER_MODE_2K)
1739 offset = (offset * 4464) / 1000;/*** 1 FFT BIN=4.464khz***/
1740 else if (ter_state->mode == FE_TER_MODE_4K)
1741 offset = (offset * 223) / 100;/*** 1 FFT BIN=2.23khz***/
1742 else if (ter_state->mode == FE_TER_MODE_8K)
1743 offset = (offset * 111) / 100;/*** 1 FFT BIN=1.1khz***/
1744
1745 if (stv0367_readbits(state, F367TER_PPM_INVSEL) == 1) {
1746 if ((stv0367_readbits(state, F367TER_INV_SPECTR) ==
1747 (stv0367_readbits(state,
1748 F367TER_STATUS_INV_SPECRUM) == 1)))
1749 offset = offset * -1;
1750 }
1751
1752 if (ter_state->bw == 6)
1753 offset = (offset * 6) / 8;
1754 else if (ter_state->bw == 7)
1755 offset = (offset * 7) / 8;
1756
1757 ter_state->frequency += offset;
1758
1759 tempo = 10; /* exit even if timing_offset stays null */
1760 while ((timing_offset == 0) && (tempo > 0)) {
1761 usleep_range(10000, 20000); /*was 20ms */
1762 /* fine tuning of timing offset if required */
1763 timing_offset = stv0367_readbits(state, F367TER_TRL_TOFFSET_LO)
1764 + 256 * stv0367_readbits(state,
1765 F367TER_TRL_TOFFSET_HI);
1766 if (timing_offset >= 32768)
1767 timing_offset -= 65536;
1768 trl_nomrate = (512 * stv0367_readbits(state,
1769 F367TER_TRL_NOMRATE_HI)
1770 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LO) * 2
1771 + stv0367_readbits(state, F367TER_TRL_NOMRATE_LSB));
1772
1773 timing_offset = ((signed)(1000000 / trl_nomrate) *
1774 timing_offset) / 2048;
1775 tempo--;
1776 }
1777
1778 if (timing_offset <= 0) {
1779 timing_offset = (timing_offset - 11) / 22;
1780 step = -1;
1781 } else {
1782 timing_offset = (timing_offset + 11) / 22;
1783 step = 1;
1784 }
1785
1786 for (counter = 0; counter < abs(timing_offset); counter++) {
1787 trl_nomrate += step;
1788 stv0367_writebits(state, F367TER_TRL_NOMRATE_LSB,
1789 trl_nomrate % 2);
1790 stv0367_writebits(state, F367TER_TRL_NOMRATE_LO,
1791 trl_nomrate / 2);
1792 usleep_range(1000, 2000);
1793 }
1794
1795 usleep_range(5000, 6000);
1796 /* unlocks could happen in case of trl centring big step,
1797 then a core off/on restarts demod */
1798 u_var = stv0367_readbits(state, F367TER_LK);
1799
1800 if (!u_var) {
1801 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
1802 msleep(20);
1803 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
1804 }
1805
1806 return 0;
1807}
1808
1809static int stv0367ter_set_frontend(struct dvb_frontend *fe,
1810 struct dvb_frontend_parameters *param)
1811{
1812 struct dvb_ofdm_parameters *op = &param->u.ofdm;
1813 struct stv0367_state *state = fe->demodulator_priv;
1814 struct stv0367ter_state *ter_state = state->ter_state;
1815
1816 /*u8 trials[2]; */
1817 s8 num_trials, index;
1818 u8 SenseTrials[] = { INVERSION_ON, INVERSION_OFF };
1819
1820 stv0367ter_init(fe);
1821
1822 if (fe->ops.tuner_ops.set_params) {
1823 if (fe->ops.i2c_gate_ctrl)
1824 fe->ops.i2c_gate_ctrl(fe, 1);
1825 fe->ops.tuner_ops.set_params(fe, param);
1826 if (fe->ops.i2c_gate_ctrl)
1827 fe->ops.i2c_gate_ctrl(fe, 0);
1828 }
1829
1830 switch (op->transmission_mode) {
1831 default:
1832 case TRANSMISSION_MODE_AUTO:
1833 case TRANSMISSION_MODE_2K:
1834 ter_state->mode = FE_TER_MODE_2K;
1835 break;
1836/* case TRANSMISSION_MODE_4K:
1837 pLook.mode = FE_TER_MODE_4K;
1838 break;*/
1839 case TRANSMISSION_MODE_8K:
1840 ter_state->mode = FE_TER_MODE_8K;
1841 break;
1842 }
1843
1844 switch (op->guard_interval) {
1845 default:
1846 case GUARD_INTERVAL_1_32:
1847 case GUARD_INTERVAL_1_16:
1848 case GUARD_INTERVAL_1_8:
1849 case GUARD_INTERVAL_1_4:
1850 ter_state->guard = op->guard_interval;
1851 break;
1852 case GUARD_INTERVAL_AUTO:
1853 ter_state->guard = GUARD_INTERVAL_1_32;
1854 break;
1855 }
1856
1857 switch (op->bandwidth) {
1858 case BANDWIDTH_6_MHZ:
1859 ter_state->bw = FE_TER_CHAN_BW_6M;
1860 break;
1861 case BANDWIDTH_7_MHZ:
1862 ter_state->bw = FE_TER_CHAN_BW_7M;
1863 break;
1864 case BANDWIDTH_8_MHZ:
1865 default:
1866 ter_state->bw = FE_TER_CHAN_BW_8M;
1867 }
1868
1869 ter_state->hierarchy = FE_TER_HIER_NONE;
1870
1871 switch (param->inversion) {
1872 case INVERSION_OFF:
1873 case INVERSION_ON:
1874 num_trials = 1;
1875 break;
1876 default:
1877 num_trials = 2;
1878 if (ter_state->first_lock)
1879 num_trials = 1;
1880 break;
1881 }
1882
1883 ter_state->state = FE_TER_NOLOCK;
1884 index = 0;
1885
1886 while (((index) < num_trials) && (ter_state->state != FE_TER_LOCKOK)) {
1887 if (!ter_state->first_lock) {
1888 if (param->inversion == INVERSION_AUTO)
1889 ter_state->sense = SenseTrials[index];
1890
1891 }
1892 stv0367ter_algo(fe,/* &pLook, result,*/ param);
1893
1894 if ((ter_state->state == FE_TER_LOCKOK) &&
1895 (param->inversion == INVERSION_AUTO) &&
1896 (index == 1)) {
1897 /* invert spectrum sense */
1898 SenseTrials[index] = SenseTrials[0];
1899 SenseTrials[(index + 1) % 2] = (SenseTrials[1] + 1) % 2;
1900 }
1901
1902 index++;
1903 }
1904
1905 return 0;
1906}
1907
1908static int stv0367ter_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
1909{
1910 struct stv0367_state *state = fe->demodulator_priv;
1911 struct stv0367ter_state *ter_state = state->ter_state;
1912 u32 errs = 0;
1913
1914 /*wait for counting completion*/
1915 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0) {
1916 errs =
1917 ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
1918 * (1 << 16))
1919 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
1920 * (1 << 8))
1921 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
1922 ter_state->ucblocks = errs;
1923 }
1924
1925 (*ucblocks) = ter_state->ucblocks;
1926
1927 return 0;
1928}
1929
1930static int stv0367ter_get_frontend(struct dvb_frontend *fe,
1931 struct dvb_frontend_parameters *param)
1932{
1933 struct stv0367_state *state = fe->demodulator_priv;
1934 struct stv0367ter_state *ter_state = state->ter_state;
1935 struct dvb_ofdm_parameters *op = &param->u.ofdm;
1936 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1937
1938 int error = 0;
1939 enum stv0367_ter_mode mode;
1940 int constell = 0,/* snr = 0,*/ Data = 0;
1941
1942 param->frequency = stv0367_get_tuner_freq(fe);
1943 if ((int)param->frequency < 0)
1944 param->frequency = c->frequency;
1945
1946 constell = stv0367_readbits(state, F367TER_TPS_CONST);
1947 if (constell == 0)
1948 op->constellation = QPSK;
1949 else if (constell == 1)
1950 op->constellation = QAM_16;
1951 else
1952 op->constellation = QAM_64;
1953
1954 param->inversion = stv0367_readbits(state, F367TER_INV_SPECTR);
1955
1956 /* Get the Hierarchical mode */
1957 Data = stv0367_readbits(state, F367TER_TPS_HIERMODE);
1958
1959 switch (Data) {
1960 case 0:
1961 op->hierarchy_information = HIERARCHY_NONE;
1962 break;
1963 case 1:
1964 op->hierarchy_information = HIERARCHY_1;
1965 break;
1966 case 2:
1967 op->hierarchy_information = HIERARCHY_2;
1968 break;
1969 case 3:
1970 op->hierarchy_information = HIERARCHY_4;
1971 break;
1972 default:
1973 op->hierarchy_information = HIERARCHY_AUTO;
1974 break; /* error */
1975 }
1976
1977 /* Get the FEC Rate */
1978 if (ter_state->hierarchy == FE_TER_HIER_LOW_PRIO)
1979 Data = stv0367_readbits(state, F367TER_TPS_LPCODE);
1980 else
1981 Data = stv0367_readbits(state, F367TER_TPS_HPCODE);
1982
1983 switch (Data) {
1984 case 0:
1985 op->code_rate_HP = FEC_1_2;
1986 break;
1987 case 1:
1988 op->code_rate_HP = FEC_2_3;
1989 break;
1990 case 2:
1991 op->code_rate_HP = FEC_3_4;
1992 break;
1993 case 3:
1994 op->code_rate_HP = FEC_5_6;
1995 break;
1996 case 4:
1997 op->code_rate_HP = FEC_7_8;
1998 break;
1999 default:
2000 op->code_rate_HP = FEC_AUTO;
2001 break; /* error */
2002 }
2003
2004 mode = stv0367_readbits(state, F367TER_SYR_MODE);
2005
2006 switch (mode) {
2007 case FE_TER_MODE_2K:
2008 op->transmission_mode = TRANSMISSION_MODE_2K;
2009 break;
2010/* case FE_TER_MODE_4K:
2011 op->transmission_mode = TRANSMISSION_MODE_4K;
2012 break;*/
2013 case FE_TER_MODE_8K:
2014 op->transmission_mode = TRANSMISSION_MODE_8K;
2015 break;
2016 default:
2017 op->transmission_mode = TRANSMISSION_MODE_AUTO;
2018 }
2019
2020 op->guard_interval = stv0367_readbits(state, F367TER_SYR_GUARD);
2021
2022 return error;
2023}
2024
2025static int stv0367ter_read_snr(struct dvb_frontend *fe, u16 *snr)
2026{
2027 struct stv0367_state *state = fe->demodulator_priv;
2028 u32 snru32 = 0;
2029 int cpt = 0;
2030 u8 cut = stv0367_readbits(state, F367TER_IDENTIFICATIONREG);
2031
2032 while (cpt < 10) {
2033 usleep_range(2000, 3000);
2034 if (cut == 0x50) /*cut 1.0 cut 1.1*/
2035 snru32 += stv0367_readbits(state, F367TER_CHCSNR) / 4;
2036 else /*cu2.0*/
2037 snru32 += 125 * stv0367_readbits(state, F367TER_CHCSNR);
2038
2039 cpt++;
2040 }
2041
2042 snru32 /= 10;/*average on 10 values*/
2043
2044 *snr = snru32 / 1000;
2045
2046 return 0;
2047}
2048
2049#if 0
2050static int stv0367ter_status(struct dvb_frontend *fe)
2051{
2052
2053 struct stv0367_state *state = fe->demodulator_priv;
2054 struct stv0367ter_state *ter_state = state->ter_state;
2055 int locked = FALSE;
2056
2057 locked = (stv0367_readbits(state, F367TER_LK));
2058 if (!locked)
2059 ter_state->unlock_counter += 1;
2060 else
2061 ter_state->unlock_counter = 0;
2062
2063 if (ter_state->unlock_counter > 2) {
2064 if (!stv0367_readbits(state, F367TER_TPS_LOCK) ||
2065 (!stv0367_readbits(state, F367TER_LK))) {
2066 stv0367_writebits(state, F367TER_CORE_ACTIVE, 0);
2067 usleep_range(2000, 3000);
2068 stv0367_writebits(state, F367TER_CORE_ACTIVE, 1);
2069 msleep(350);
2070 locked = (stv0367_readbits(state, F367TER_TPS_LOCK)) &&
2071 (stv0367_readbits(state, F367TER_LK));
2072 }
2073
2074 }
2075
2076 return locked;
2077}
2078#endif
2079static int stv0367ter_read_status(struct dvb_frontend *fe, fe_status_t *status)
2080{
2081 struct stv0367_state *state = fe->demodulator_priv;
2082
2083 dprintk("%s:\n", __func__);
2084
2085 *status = 0;
2086
2087 if (stv0367_readbits(state, F367TER_LK)) {
2088 *status |= FE_HAS_LOCK;
2089 dprintk("%s: stv0367 has locked\n", __func__);
2090 }
2091
2092 return 0;
2093}
2094
2095static int stv0367ter_read_ber(struct dvb_frontend *fe, u32 *ber)
2096{
2097 struct stv0367_state *state = fe->demodulator_priv;
2098 struct stv0367ter_state *ter_state = state->ter_state;
2099 u32 Errors = 0, tber = 0, temporary = 0;
2100 int abc = 0, def = 0;
2101
2102
2103 /*wait for counting completion*/
2104 if (stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 0)
2105 Errors = ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT)
2106 * (1 << 16))
2107 + ((u32)stv0367_readbits(state, F367TER_SFEC_ERR_CNT_HI)
2108 * (1 << 8))
2109 + ((u32)stv0367_readbits(state,
2110 F367TER_SFEC_ERR_CNT_LO));
2111 /*measurement not completed, load previous value*/
2112 else {
2113 tber = ter_state->pBER;
2114 return 0;
2115 }
2116
2117 abc = stv0367_readbits(state, F367TER_SFEC_ERR_SOURCE);
2118 def = stv0367_readbits(state, F367TER_SFEC_NUM_EVENT);
2119
2120 if (Errors == 0) {
2121 tber = 0;
2122 } else if (abc == 0x7) {
2123 if (Errors <= 4) {
2124 temporary = (Errors * 1000000000) / (8 * (1 << 14));
2125 temporary = temporary;
2126 } else if (Errors <= 42) {
2127 temporary = (Errors * 100000000) / (8 * (1 << 14));
2128 temporary = temporary * 10;
2129 } else if (Errors <= 429) {
2130 temporary = (Errors * 10000000) / (8 * (1 << 14));
2131 temporary = temporary * 100;
2132 } else if (Errors <= 4294) {
2133 temporary = (Errors * 1000000) / (8 * (1 << 14));
2134 temporary = temporary * 1000;
2135 } else if (Errors <= 42949) {
2136 temporary = (Errors * 100000) / (8 * (1 << 14));
2137 temporary = temporary * 10000;
2138 } else if (Errors <= 429496) {
2139 temporary = (Errors * 10000) / (8 * (1 << 14));
2140 temporary = temporary * 100000;
2141 } else { /*if (Errors<4294967) 2^22 max error*/
2142 temporary = (Errors * 1000) / (8 * (1 << 14));
2143 temporary = temporary * 100000; /* still to *10 */
2144 }
2145
2146 /* Byte error*/
2147 if (def == 2)
2148 /*tber=Errors/(8*(1 <<14));*/
2149 tber = temporary;
2150 else if (def == 3)
2151 /*tber=Errors/(8*(1 <<16));*/
2152 tber = temporary / 4;
2153 else if (def == 4)
2154 /*tber=Errors/(8*(1 <<18));*/
2155 tber = temporary / 16;
2156 else if (def == 5)
2157 /*tber=Errors/(8*(1 <<20));*/
2158 tber = temporary / 64;
2159 else if (def == 6)
2160 /*tber=Errors/(8*(1 <<22));*/
2161 tber = temporary / 256;
2162 else
2163 /* should not pass here*/
2164 tber = 0;
2165
2166 if ((Errors < 4294967) && (Errors > 429496))
2167 tber *= 10;
2168
2169 }
2170
2171 /* save actual value */
2172 ter_state->pBER = tber;
2173
2174 (*ber) = tber;
2175
2176 return 0;
2177}
2178#if 0
2179static u32 stv0367ter_get_per(struct stv0367_state *state)
2180{
2181 struct stv0367ter_state *ter_state = state->ter_state;
2182 u32 Errors = 0, Per = 0, temporary = 0;
2183 int abc = 0, def = 0, cpt = 0;
2184
2185 while (((stv0367_readbits(state, F367TER_SFERRC_OLDVALUE) == 1) &&
2186 (cpt < 400)) || ((Errors == 0) && (cpt < 400))) {
2187 usleep_range(1000, 2000);
2188 Errors = ((u32)stv0367_readbits(state, F367TER_ERR_CNT1)
2189 * (1 << 16))
2190 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_HI)
2191 * (1 << 8))
2192 + ((u32)stv0367_readbits(state, F367TER_ERR_CNT1_LO));
2193 cpt++;
2194 }
2195 abc = stv0367_readbits(state, F367TER_ERR_SRC1);
2196 def = stv0367_readbits(state, F367TER_NUM_EVT1);
2197
2198 if (Errors == 0)
2199 Per = 0;
2200 else if (abc == 0x9) {
2201 if (Errors <= 4) {
2202 temporary = (Errors * 1000000000) / (8 * (1 << 8));
2203 temporary = temporary;
2204 } else if (Errors <= 42) {
2205 temporary = (Errors * 100000000) / (8 * (1 << 8));
2206 temporary = temporary * 10;
2207 } else if (Errors <= 429) {
2208 temporary = (Errors * 10000000) / (8 * (1 << 8));
2209 temporary = temporary * 100;
2210 } else if (Errors <= 4294) {
2211 temporary = (Errors * 1000000) / (8 * (1 << 8));
2212 temporary = temporary * 1000;
2213 } else if (Errors <= 42949) {
2214 temporary = (Errors * 100000) / (8 * (1 << 8));
2215 temporary = temporary * 10000;
2216 } else { /*if(Errors<=429496) 2^16 errors max*/
2217 temporary = (Errors * 10000) / (8 * (1 << 8));
2218 temporary = temporary * 100000;
2219 }
2220
2221 /* pkt error*/
2222 if (def == 2)
2223 /*Per=Errors/(1 << 8);*/
2224 Per = temporary;
2225 else if (def == 3)
2226 /*Per=Errors/(1 << 10);*/
2227 Per = temporary / 4;
2228 else if (def == 4)
2229 /*Per=Errors/(1 << 12);*/
2230 Per = temporary / 16;
2231 else if (def == 5)
2232 /*Per=Errors/(1 << 14);*/
2233 Per = temporary / 64;
2234 else if (def == 6)
2235 /*Per=Errors/(1 << 16);*/
2236 Per = temporary / 256;
2237 else
2238 Per = 0;
2239
2240 }
2241 /* save actual value */
2242 ter_state->pPER = Per;
2243
2244 return Per;
2245}
2246#endif
2247static int stv0367_get_tune_settings(struct dvb_frontend *fe,
2248 struct dvb_frontend_tune_settings
2249 *fe_tune_settings)
2250{
2251 fe_tune_settings->min_delay_ms = 1000;
2252 fe_tune_settings->step_size = 0;
2253 fe_tune_settings->max_drift = 0;
2254
2255 return 0;
2256}
2257
2258static void stv0367_release(struct dvb_frontend *fe)
2259{
2260 struct stv0367_state *state = fe->demodulator_priv;
2261
2262 kfree(state->ter_state);
2263 kfree(state->cab_state);
2264 kfree(state);
2265}
2266
2267static struct dvb_frontend_ops stv0367ter_ops = {
2268 .info = {
2269 .name = "ST STV0367 DVB-T",
2270 .type = FE_OFDM,
2271 .frequency_min = 47000000,
2272 .frequency_max = 862000000,
2273 .frequency_stepsize = 15625,
2274 .frequency_tolerance = 0,
2275 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
2276 FE_CAN_FEC_3_4 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
2277 FE_CAN_FEC_AUTO |
2278 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
2279 FE_CAN_QAM_128 | FE_CAN_QAM_256 | FE_CAN_QAM_AUTO |
2280 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER |
2281 FE_CAN_INVERSION_AUTO |
2282 FE_CAN_MUTE_TS
2283 },
2284 .release = stv0367_release,
2285 .init = stv0367ter_init,
2286 .sleep = stv0367ter_sleep,
2287 .i2c_gate_ctrl = stv0367ter_gate_ctrl,
2288 .set_frontend = stv0367ter_set_frontend,
2289 .get_frontend = stv0367ter_get_frontend,
2290 .get_tune_settings = stv0367_get_tune_settings,
2291 .read_status = stv0367ter_read_status,
2292 .read_ber = stv0367ter_read_ber,/* too slow */
2293/* .read_signal_strength = stv0367_read_signal_strength,*/
2294 .read_snr = stv0367ter_read_snr,
2295 .read_ucblocks = stv0367ter_read_ucblocks,
2296};
2297
2298struct dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
2299 struct i2c_adapter *i2c)
2300{
2301 struct stv0367_state *state = NULL;
2302 struct stv0367ter_state *ter_state = NULL;
2303
2304 /* allocate memory for the internal state */
2305 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
2306 if (state == NULL)
2307 goto error;
2308 ter_state = kzalloc(sizeof(struct stv0367ter_state), GFP_KERNEL);
2309 if (ter_state == NULL)
2310 goto error;
2311
2312 /* setup the state */
2313 state->i2c = i2c;
2314 state->config = config;
2315 state->ter_state = ter_state;
2316 state->fe.ops = stv0367ter_ops;
2317 state->fe.demodulator_priv = state;
2318 state->chip_id = stv0367_readreg(state, 0xf000);
2319
2320 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
2321
2322 /* check if the demod is there */
2323 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
2324 goto error;
2325
2326 return &state->fe;
2327
2328error:
2329 kfree(ter_state);
2330 kfree(state);
2331 return NULL;
2332}
2333EXPORT_SYMBOL(stv0367ter_attach);
2334
2335static int stv0367cab_gate_ctrl(struct dvb_frontend *fe, int enable)
2336{
2337 struct stv0367_state *state = fe->demodulator_priv;
2338
2339 dprintk("%s:\n", __func__);
2340
2341 stv0367_writebits(state, F367CAB_I2CT_ON, (enable > 0) ? 1 : 0);
2342
2343 return 0;
2344}
2345
2346static u32 stv0367cab_get_mclk(struct dvb_frontend *fe, u32 ExtClk_Hz)
2347{
2348 struct stv0367_state *state = fe->demodulator_priv;
2349 u32 mclk_Hz = 0;/* master clock frequency (Hz) */
2350 u32 M, N, P;
2351
2352
2353 if (stv0367_readbits(state, F367CAB_BYPASS_PLLXN) == 0) {
2354 N = (u32)stv0367_readbits(state, F367CAB_PLL_NDIV);
2355 if (N == 0)
2356 N = N + 1;
2357
2358 M = (u32)stv0367_readbits(state, F367CAB_PLL_MDIV);
2359 if (M == 0)
2360 M = M + 1;
2361
2362 P = (u32)stv0367_readbits(state, F367CAB_PLL_PDIV);
2363
2364 if (P > 5)
2365 P = 5;
2366
2367 mclk_Hz = ((ExtClk_Hz / 2) * N) / (M * (1 << P));
2368 dprintk("stv0367cab_get_mclk BYPASS_PLLXN mclk_Hz=%d\n",
2369 mclk_Hz);
2370 } else
2371 mclk_Hz = ExtClk_Hz;
2372
2373 dprintk("stv0367cab_get_mclk final mclk_Hz=%d\n", mclk_Hz);
2374
2375 return mclk_Hz;
2376}
2377
2378static u32 stv0367cab_get_adc_freq(struct dvb_frontend *fe, u32 ExtClk_Hz)
2379{
2380 u32 ADCClk_Hz = ExtClk_Hz;
2381
2382 ADCClk_Hz = stv0367cab_get_mclk(fe, ExtClk_Hz);
2383
2384 return ADCClk_Hz;
2385}
2386
2387enum stv0367cab_mod stv0367cab_SetQamSize(struct stv0367_state *state,
2388 u32 SymbolRate,
2389 enum stv0367cab_mod QAMSize)
2390{
2391 /* Set QAM size */
2392 stv0367_writebits(state, F367CAB_QAM_MODE, QAMSize);
2393
2394 /* Set Registers settings specific to the QAM size */
2395 switch (QAMSize) {
2396 case FE_CAB_MOD_QAM4:
2397 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2398 break;
2399 case FE_CAB_MOD_QAM16:
2400 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x64);
2401 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2402 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2403 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2404 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2405 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2406 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2407 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x8a);
2408 break;
2409 case FE_CAB_MOD_QAM32:
2410 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2411 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x6e);
2412 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2413 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2414 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xb7);
2415 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x9d);
2416 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2417 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2418 break;
2419 case FE_CAB_MOD_QAM64:
2420 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x82);
2421 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2422 if (SymbolRate > 45000000) {
2423 stv0367_writereg(state, R367CAB_FSM_STATE, 0xb0);
2424 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2425 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa5);
2426 } else if (SymbolRate > 25000000) {
2427 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2428 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2429 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2430 } else {
2431 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2432 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2433 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2434 }
2435 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x95);
2436 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2437 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0x99);
2438 break;
2439 case FE_CAB_MOD_QAM128:
2440 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2441 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x76);
2442 stv0367_writereg(state, R367CAB_FSM_STATE, 0x90);
2443 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xb1);
2444 if (SymbolRate > 45000000)
2445 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2446 else if (SymbolRate > 25000000)
2447 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa6);
2448 else
2449 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0x97);
2450
2451 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x8e);
2452 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x7f);
2453 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2454 break;
2455 case FE_CAB_MOD_QAM256:
2456 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x94);
2457 stv0367_writereg(state, R367CAB_AGC_PWR_REF_L, 0x5a);
2458 stv0367_writereg(state, R367CAB_FSM_STATE, 0xa0);
2459 if (SymbolRate > 45000000)
2460 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2461 else if (SymbolRate > 25000000)
2462 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xc1);
2463 else
2464 stv0367_writereg(state, R367CAB_EQU_CTR_LPF_GAIN, 0xd1);
2465
2466 stv0367_writereg(state, R367CAB_EQU_CRL_LPF_GAIN, 0xa7);
2467 stv0367_writereg(state, R367CAB_EQU_CRL_LD_SEN, 0x85);
2468 stv0367_writereg(state, R367CAB_EQU_CRL_LIMITER, 0x40);
2469 stv0367_writereg(state, R367CAB_EQU_PNT_GAIN, 0xa7);
2470 break;
2471 case FE_CAB_MOD_QAM512:
2472 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2473 break;
2474 case FE_CAB_MOD_QAM1024:
2475 stv0367_writereg(state, R367CAB_IQDEM_ADJ_AGC_REF, 0x00);
2476 break;
2477 default:
2478 break;
2479 }
2480
2481 return QAMSize;
2482}
2483
2484static u32 stv0367cab_set_derot_freq(struct stv0367_state *state,
2485 u32 adc_hz, s32 derot_hz)
2486{
2487 u32 sampled_if = 0;
2488 u32 adc_khz;
2489
2490 adc_khz = adc_hz / 1000;
2491
2492 dprintk("%s: adc_hz=%d derot_hz=%d\n", __func__, adc_hz, derot_hz);
2493
2494 if (adc_khz != 0) {
2495 if (derot_hz < 1000000)
2496 derot_hz = adc_hz / 4; /* ZIF operation */
2497 if (derot_hz > adc_hz)
2498 derot_hz = derot_hz - adc_hz;
2499 sampled_if = (u32)derot_hz / 1000;
2500 sampled_if *= 32768;
2501 sampled_if /= adc_khz;
2502 sampled_if *= 256;
2503 }
2504
2505 if (sampled_if > 8388607)
2506 sampled_if = 8388607;
2507
2508 dprintk("%s: sampled_if=0x%x\n", __func__, sampled_if);
2509
2510 stv0367_writereg(state, R367CAB_MIX_NCO_LL, sampled_if);
2511 stv0367_writereg(state, R367CAB_MIX_NCO_HL, (sampled_if >> 8));
2512 stv0367_writebits(state, F367CAB_MIX_NCO_INC_HH, (sampled_if >> 16));
2513
2514 return derot_hz;
2515}
2516
2517static u32 stv0367cab_get_derot_freq(struct stv0367_state *state, u32 adc_hz)
2518{
2519 u32 sampled_if;
2520
2521 sampled_if = stv0367_readbits(state, F367CAB_MIX_NCO_INC_LL) +
2522 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HL) << 8) +
2523 (stv0367_readbits(state, F367CAB_MIX_NCO_INC_HH) << 16);
2524
2525 sampled_if /= 256;
2526 sampled_if *= (adc_hz / 1000);
2527 sampled_if += 1;
2528 sampled_if /= 32768;
2529
2530 return sampled_if;
2531}
2532
2533static u32 stv0367cab_set_srate(struct stv0367_state *state, u32 adc_hz,
2534 u32 mclk_hz, u32 SymbolRate,
2535 enum stv0367cab_mod QAMSize)
2536{
2537 u32 QamSizeCorr = 0;
2538 u32 u32_tmp = 0, u32_tmp1 = 0;
2539 u32 adp_khz;
2540
2541 dprintk("%s:\n", __func__);
2542
2543 /* Set Correction factor of SRC gain */
2544 switch (QAMSize) {
2545 case FE_CAB_MOD_QAM4:
2546 QamSizeCorr = 1110;
2547 break;
2548 case FE_CAB_MOD_QAM16:
2549 QamSizeCorr = 1032;
2550 break;
2551 case FE_CAB_MOD_QAM32:
2552 QamSizeCorr = 954;
2553 break;
2554 case FE_CAB_MOD_QAM64:
2555 QamSizeCorr = 983;
2556 break;
2557 case FE_CAB_MOD_QAM128:
2558 QamSizeCorr = 957;
2559 break;
2560 case FE_CAB_MOD_QAM256:
2561 QamSizeCorr = 948;
2562 break;
2563 case FE_CAB_MOD_QAM512:
2564 QamSizeCorr = 0;
2565 break;
2566 case FE_CAB_MOD_QAM1024:
2567 QamSizeCorr = 944;
2568 break;
2569 default:
2570 break;
2571 }
2572
2573 /* Transfer ratio calculation */
2574 if (adc_hz != 0) {
2575 u32_tmp = 256 * SymbolRate;
2576 u32_tmp = u32_tmp / adc_hz;
2577 }
2578 stv0367_writereg(state, R367CAB_EQU_CRL_TFR, (u8)u32_tmp);
2579
2580 /* Symbol rate and SRC gain calculation */
2581 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2582 if (adp_khz != 0) {
2583 u32_tmp = SymbolRate;
2584 u32_tmp1 = SymbolRate;
2585
2586 if (u32_tmp < 2097152) { /* 2097152 = 2^21 */
2587 /* Symbol rate calculation */
2588 u32_tmp *= 2048; /* 2048 = 2^11 */
2589 u32_tmp = u32_tmp / adp_khz;
2590 u32_tmp = u32_tmp * 16384; /* 16384 = 2^14 */
2591 u32_tmp /= 125 ; /* 125 = 1000/2^3 */
2592 u32_tmp = u32_tmp * 8; /* 8 = 2^3 */
2593
2594 /* SRC Gain Calculation */
2595 u32_tmp1 *= 2048; /* *2*2^10 */
2596 u32_tmp1 /= 439; /* *2/878 */
2597 u32_tmp1 *= 256; /* *2^8 */
2598 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2599 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2600 u32_tmp1 = u32_tmp1 / 10000000;
2601
2602 } else if (u32_tmp < 4194304) { /* 4194304 = 2**22 */
2603 /* Symbol rate calculation */
2604 u32_tmp *= 1024 ; /* 1024 = 2**10 */
2605 u32_tmp = u32_tmp / adp_khz;
2606 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2607 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2608 u32_tmp = u32_tmp * 16; /* 16 = 2**4 */
2609
2610 /* SRC Gain Calculation */
2611 u32_tmp1 *= 1024; /* *2*2^9 */
2612 u32_tmp1 /= 439; /* *2/878 */
2613 u32_tmp1 *= 256; /* *2^8 */
2614 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz)*/
2615 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2616 u32_tmp1 = u32_tmp1 / 5000000;
2617 } else if (u32_tmp < 8388607) { /* 8388607 = 2**23 */
2618 /* Symbol rate calculation */
2619 u32_tmp *= 512 ; /* 512 = 2**9 */
2620 u32_tmp = u32_tmp / adp_khz;
2621 u32_tmp = u32_tmp * 16384; /* 16384 = 2**14 */
2622 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2623 u32_tmp = u32_tmp * 32; /* 32 = 2**5 */
2624
2625 /* SRC Gain Calculation */
2626 u32_tmp1 *= 512; /* *2*2^8 */
2627 u32_tmp1 /= 439; /* *2/878 */
2628 u32_tmp1 *= 256; /* *2^8 */
2629 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2630 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2631 u32_tmp1 = u32_tmp1 / 2500000;
2632 } else {
2633 /* Symbol rate calculation */
2634 u32_tmp *= 256 ; /* 256 = 2**8 */
2635 u32_tmp = u32_tmp / adp_khz;
2636 u32_tmp = u32_tmp * 16384; /* 16384 = 2**13 */
2637 u32_tmp /= 125 ; /* 125 = 1000/2**3 */
2638 u32_tmp = u32_tmp * 64; /* 64 = 2**6 */
2639
2640 /* SRC Gain Calculation */
2641 u32_tmp1 *= 256; /* 2*2^7 */
2642 u32_tmp1 /= 439; /* *2/878 */
2643 u32_tmp1 *= 256; /* *2^8 */
2644 u32_tmp1 = u32_tmp1 / adp_khz; /* /(AdpClk in kHz) */
2645 u32_tmp1 *= QamSizeCorr * 9; /* *1000*corr factor */
2646 u32_tmp1 = u32_tmp1 / 1250000;
2647 }
2648 }
2649#if 0
2650 /* Filters' coefficients are calculated and written
2651 into registers only if the filters are enabled */
2652 if (stv0367_readbits(state, F367CAB_ADJ_EN)) {
2653 stv0367cab_SetIirAdjacentcoefficient(state, mclk_hz,
2654 SymbolRate);
2655 /* AllPass filter must be enabled
2656 when the adjacents filter is used */
2657 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 1);
2658 stv0367cab_SetAllPasscoefficient(state, mclk_hz, SymbolRate);
2659 } else
2660 /* AllPass filter must be disabled
2661 when the adjacents filter is not used */
2662#endif
2663 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2664
2665 stv0367_writereg(state, R367CAB_SRC_NCO_LL, u32_tmp);
2666 stv0367_writereg(state, R367CAB_SRC_NCO_LH, (u32_tmp >> 8));
2667 stv0367_writereg(state, R367CAB_SRC_NCO_HL, (u32_tmp >> 16));
2668 stv0367_writereg(state, R367CAB_SRC_NCO_HH, (u32_tmp >> 24));
2669
2670 stv0367_writereg(state, R367CAB_IQDEM_GAIN_SRC_L, u32_tmp1 & 0x00ff);
2671 stv0367_writebits(state, F367CAB_GAIN_SRC_HI, (u32_tmp1 >> 8) & 0x00ff);
2672
2673 return SymbolRate ;
2674}
2675
2676static u32 stv0367cab_GetSymbolRate(struct stv0367_state *state, u32 mclk_hz)
2677{
2678 u32 regsym;
2679 u32 adp_khz;
2680
2681 regsym = stv0367_readreg(state, R367CAB_SRC_NCO_LL) +
2682 (stv0367_readreg(state, R367CAB_SRC_NCO_LH) << 8) +
2683 (stv0367_readreg(state, R367CAB_SRC_NCO_HL) << 16) +
2684 (stv0367_readreg(state, R367CAB_SRC_NCO_HH) << 24);
2685
2686 adp_khz = (mclk_hz >> 1) / 1000;/* TRL works at half the system clock */
2687
2688 if (regsym < 134217728) { /* 134217728L = 2**27*/
2689 regsym = regsym * 32; /* 32 = 2**5 */
2690 regsym = regsym / 32768; /* 32768L = 2**15 */
2691 regsym = adp_khz * regsym; /* AdpClk in kHz */
2692 regsym = regsym / 128; /* 128 = 2**7 */
2693 regsym *= 125 ; /* 125 = 1000/2**3 */
2694 regsym /= 2048 ; /* 2048 = 2**11 */
2695 } else if (regsym < 268435456) { /* 268435456L = 2**28 */
2696 regsym = regsym * 16; /* 16 = 2**4 */
2697 regsym = regsym / 32768; /* 32768L = 2**15 */
2698 regsym = adp_khz * regsym; /* AdpClk in kHz */
2699 regsym = regsym / 128; /* 128 = 2**7 */
2700 regsym *= 125 ; /* 125 = 1000/2**3*/
2701 regsym /= 1024 ; /* 256 = 2**10*/
2702 } else if (regsym < 536870912) { /* 536870912L = 2**29*/
2703 regsym = regsym * 8; /* 8 = 2**3 */
2704 regsym = regsym / 32768; /* 32768L = 2**15 */
2705 regsym = adp_khz * regsym; /* AdpClk in kHz */
2706 regsym = regsym / 128; /* 128 = 2**7 */
2707 regsym *= 125 ; /* 125 = 1000/2**3 */
2708 regsym /= 512 ; /* 128 = 2**9 */
2709 } else {
2710 regsym = regsym * 4; /* 4 = 2**2 */
2711 regsym = regsym / 32768; /* 32768L = 2**15 */
2712 regsym = adp_khz * regsym; /* AdpClk in kHz */
2713 regsym = regsym / 128; /* 128 = 2**7 */
2714 regsym *= 125 ; /* 125 = 1000/2**3 */
2715 regsym /= 256 ; /* 64 = 2**8 */
2716 }
2717
2718 return regsym;
2719}
2720
2721static int stv0367cab_read_status(struct dvb_frontend *fe, fe_status_t *status)
2722{
2723 struct stv0367_state *state = fe->demodulator_priv;
2724
2725 dprintk("%s:\n", __func__);
2726
2727 *status = 0;
2728
2729 if (stv0367_readbits(state, F367CAB_QAMFEC_LOCK)) {
2730 *status |= FE_HAS_LOCK;
2731 dprintk("%s: stv0367 has locked\n", __func__);
2732 }
2733
2734 return 0;
2735}
2736
2737static int stv0367cab_standby(struct dvb_frontend *fe, u8 standby_on)
2738{
2739 struct stv0367_state *state = fe->demodulator_priv;
2740
2741 dprintk("%s:\n", __func__);
2742
2743 if (standby_on) {
2744 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x03);
2745 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x01);
2746 stv0367_writebits(state, F367CAB_STDBY, 1);
2747 stv0367_writebits(state, F367CAB_STDBY_CORE, 1);
2748 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 0);
2749 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 0);
2750 stv0367_writebits(state, F367CAB_POFFQ, 1);
2751 stv0367_writebits(state, F367CAB_POFFI, 1);
2752 } else {
2753 stv0367_writebits(state, F367CAB_STDBY_PLLXN, 0x00);
2754 stv0367_writebits(state, F367CAB_BYPASS_PLLXN, 0x00);
2755 stv0367_writebits(state, F367CAB_STDBY, 0);
2756 stv0367_writebits(state, F367CAB_STDBY_CORE, 0);
2757 stv0367_writebits(state, F367CAB_EN_BUFFER_I, 1);
2758 stv0367_writebits(state, F367CAB_EN_BUFFER_Q, 1);
2759 stv0367_writebits(state, F367CAB_POFFQ, 0);
2760 stv0367_writebits(state, F367CAB_POFFI, 0);
2761 }
2762
2763 return 0;
2764}
2765
2766static int stv0367cab_sleep(struct dvb_frontend *fe)
2767{
2768 return stv0367cab_standby(fe, 1);
2769}
2770
2771int stv0367cab_init(struct dvb_frontend *fe)
2772{
2773 struct stv0367_state *state = fe->demodulator_priv;
2774 struct stv0367cab_state *cab_state = state->cab_state;
2775 int i;
2776
2777 dprintk("%s:\n", __func__);
2778
2779 for (i = 0; i < STV0367CAB_NBREGS; i++)
2780 stv0367_writereg(state, def0367cab[i].addr,
2781 def0367cab[i].value);
2782
2783 switch (state->config->ts_mode) {
2784 case STV0367_DVBCI_CLOCK:
2785 dprintk("Setting TSMode = STV0367_DVBCI_CLOCK\n");
2786 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x03);
2787 break;
2788 case STV0367_SERIAL_PUNCT_CLOCK:
2789 case STV0367_SERIAL_CONT_CLOCK:
2790 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x01);
2791 break;
2792 case STV0367_PARALLEL_PUNCT_CLOCK:
2793 case STV0367_OUTPUTMODE_DEFAULT:
2794 stv0367_writebits(state, F367CAB_OUTFORMAT, 0x00);
2795 break;
2796 }
2797
2798 switch (state->config->clk_pol) {
2799 case STV0367_RISINGEDGE_CLOCK:
2800 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x00);
2801 break;
2802 case STV0367_FALLINGEDGE_CLOCK:
2803 case STV0367_CLOCKPOLARITY_DEFAULT:
2804 stv0367_writebits(state, F367CAB_CLK_POLARITY, 0x01);
2805 break;
2806 }
2807
2808 stv0367_writebits(state, F367CAB_SYNC_STRIP, 0x00);
2809
2810 stv0367_writebits(state, F367CAB_CT_NBST, 0x01);
2811
2812 stv0367_writebits(state, F367CAB_TS_SWAP, 0x01);
2813
2814 stv0367_writebits(state, F367CAB_FIFO_BYPASS, 0x00);
2815
2816 stv0367_writereg(state, R367CAB_ANACTRL, 0x00);/*PLL enabled and used */
2817
2818 cab_state->mclk = stv0367cab_get_mclk(fe, state->config->xtal);
2819 cab_state->adc_clk = stv0367cab_get_adc_freq(fe, state->config->xtal);
2820
2821 return 0;
2822}
2823static
2824enum stv0367_cab_signal_type stv0367cab_algo(struct stv0367_state *state,
2825 struct dvb_frontend_parameters *param)
2826{
2827 struct dvb_qam_parameters *op = &param->u.qam;
2828 struct stv0367cab_state *cab_state = state->cab_state;
2829 enum stv0367_cab_signal_type signalType = FE_CAB_NOAGC;
2830 u32 QAMFEC_Lock, QAM_Lock, u32_tmp,
2831 LockTime, TRLTimeOut, AGCTimeOut, CRLSymbols,
2832 CRLTimeOut, EQLTimeOut, DemodTimeOut, FECTimeOut;
2833 u8 TrackAGCAccum;
2834 s32 tmp;
2835
2836 dprintk("%s:\n", __func__);
2837
2838 /* Timeouts calculation */
2839 /* A max lock time of 25 ms is allowed for delayed AGC */
2840 AGCTimeOut = 25;
2841 /* 100000 symbols needed by the TRL as a maximum value */
2842 TRLTimeOut = 100000000 / op->symbol_rate;
2843 /* CRLSymbols is the needed number of symbols to achieve a lock
2844 within [-4%, +4%] of the symbol rate.
2845 CRL timeout is calculated
2846 for a lock within [-search_range, +search_range].
2847 EQL timeout can be changed depending on
2848 the micro-reflections we want to handle.
2849 A characterization must be performed
2850 with these echoes to get new timeout values.
2851 */
2852 switch (op->modulation) {
2853 case QAM_16:
2854 CRLSymbols = 150000;
2855 EQLTimeOut = 100;
2856 break;
2857 case QAM_32:
2858 CRLSymbols = 250000;
2859 EQLTimeOut = 100;
2860 break;
2861 case QAM_64:
2862 CRLSymbols = 200000;
2863 EQLTimeOut = 100;
2864 break;
2865 case QAM_128:
2866 CRLSymbols = 250000;
2867 EQLTimeOut = 100;
2868 break;
2869 case QAM_256:
2870 CRLSymbols = 250000;
2871 EQLTimeOut = 100;
2872 break;
2873 default:
2874 CRLSymbols = 200000;
2875 EQLTimeOut = 100;
2876 break;
2877 }
2878#if 0
2879 if (pIntParams->search_range < 0) {
2880 CRLTimeOut = (25 * CRLSymbols *
2881 (-pIntParams->search_range / 1000)) /
2882 (pIntParams->symbol_rate / 1000);
2883 } else
2884#endif
2885 CRLTimeOut = (25 * CRLSymbols * (cab_state->search_range / 1000)) /
2886 (op->symbol_rate / 1000);
2887
2888 CRLTimeOut = (1000 * CRLTimeOut) / op->symbol_rate;
2889 /* Timeouts below 50ms are coerced */
2890 if (CRLTimeOut < 50)
2891 CRLTimeOut = 50;
2892 /* A maximum of 100 TS packets is needed to get FEC lock even in case
2893 the spectrum inversion needs to be changed.
2894 This is equal to 20 ms in case of the lowest symbol rate of 0.87Msps
2895 */
2896 FECTimeOut = 20;
2897 DemodTimeOut = AGCTimeOut + TRLTimeOut + CRLTimeOut + EQLTimeOut;
2898
2899 dprintk("%s: DemodTimeOut=%d\n", __func__, DemodTimeOut);
2900
2901 /* Reset the TRL to ensure nothing starts until the
2902 AGC is stable which ensures a better lock time
2903 */
2904 stv0367_writereg(state, R367CAB_CTRL_1, 0x04);
2905 /* Set AGC accumulation time to minimum and lock threshold to maximum
2906 in order to speed up the AGC lock */
2907 TrackAGCAccum = stv0367_readbits(state, F367CAB_AGC_ACCUMRSTSEL);
2908 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, 0x0);
2909 /* Modulus Mapper is disabled */
2910 stv0367_writebits(state, F367CAB_MODULUSMAP_EN, 0);
2911 /* Disable the sweep function */
2912 stv0367_writebits(state, F367CAB_SWEEP_EN, 0);
2913 /* The sweep function is never used, Sweep rate must be set to 0 */
2914 /* Set the derotator frequency in Hz */
2915 stv0367cab_set_derot_freq(state, cab_state->adc_clk,
2916 (1000 * (s32)state->config->if_khz + cab_state->derot_offset));
2917 /* Disable the Allpass Filter when the symbol rate is out of range */
2918 if ((op->symbol_rate > 10800000) | (op->symbol_rate < 1800000)) {
2919 stv0367_writebits(state, F367CAB_ADJ_EN, 0);
2920 stv0367_writebits(state, F367CAB_ALLPASSFILT_EN, 0);
2921 }
2922#if 0
2923 /* Check if the tuner is locked */
2924 tuner_lock = stv0367cab_tuner_get_status(fe);
2925 if (tuner_lock == 0)
2926 return FE_367CAB_NOTUNER;
2927#endif
2928 /* Relase the TRL to start demodulator acquisition */
2929 /* Wait for QAM lock */
2930 LockTime = 0;
2931 stv0367_writereg(state, R367CAB_CTRL_1, 0x00);
2932 do {
2933 QAM_Lock = stv0367_readbits(state, F367CAB_FSM_STATUS);
2934 if ((LockTime >= (DemodTimeOut - EQLTimeOut)) &&
2935 (QAM_Lock == 0x04))
2936 /*
2937 * We don't wait longer, the frequency/phase offset
2938 * must be too big
2939 */
2940 LockTime = DemodTimeOut;
2941 else if ((LockTime >= (AGCTimeOut + TRLTimeOut)) &&
2942 (QAM_Lock == 0x02))
2943 /*
2944 * We don't wait longer, either there is no signal or
2945 * it is not the right symbol rate or it is an analog
2946 * carrier
2947 */
2948 {
2949 LockTime = DemodTimeOut;
2950 u32_tmp = stv0367_readbits(state,
2951 F367CAB_AGC_PWR_WORD_LO) +
2952 (stv0367_readbits(state,
2953 F367CAB_AGC_PWR_WORD_ME) << 8) +
2954 (stv0367_readbits(state,
2955 F367CAB_AGC_PWR_WORD_HI) << 16);
2956 if (u32_tmp >= 131072)
2957 u32_tmp = 262144 - u32_tmp;
2958 u32_tmp = u32_tmp / (1 << (11 - stv0367_readbits(state,
2959 F367CAB_AGC_IF_BWSEL)));
2960
2961 if (u32_tmp < stv0367_readbits(state,
2962 F367CAB_AGC_PWRREF_LO) +
2963 256 * stv0367_readbits(state,
2964 F367CAB_AGC_PWRREF_HI) - 10)
2965 QAM_Lock = 0x0f;
2966 } else {
2967 usleep_range(10000, 20000);
2968 LockTime += 10;
2969 }
2970 dprintk("QAM_Lock=0x%x LockTime=%d\n", QAM_Lock, LockTime);
2971 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2972
2973 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2974
2975 } while (((QAM_Lock != 0x0c) && (QAM_Lock != 0x0b)) &&
2976 (LockTime < DemodTimeOut));
2977
2978 dprintk("QAM_Lock=0x%x\n", QAM_Lock);
2979
2980 tmp = stv0367_readreg(state, R367CAB_IT_STATUS1);
2981 dprintk("R367CAB_IT_STATUS1=0x%x\n", tmp);
2982 tmp = stv0367_readreg(state, R367CAB_IT_STATUS2);
2983 dprintk("R367CAB_IT_STATUS2=0x%x\n", tmp);
2984
2985 tmp = stv0367cab_get_derot_freq(state, cab_state->adc_clk);
2986 dprintk("stv0367cab_get_derot_freq=0x%x\n", tmp);
2987
2988 if ((QAM_Lock == 0x0c) || (QAM_Lock == 0x0b)) {
2989 /* Wait for FEC lock */
2990 LockTime = 0;
2991 do {
2992 usleep_range(5000, 7000);
2993 LockTime += 5;
2994 QAMFEC_Lock = stv0367_readbits(state,
2995 F367CAB_QAMFEC_LOCK);
2996 } while (!QAMFEC_Lock && (LockTime < FECTimeOut));
2997 } else
2998 QAMFEC_Lock = 0;
2999
3000 if (QAMFEC_Lock) {
3001 signalType = FE_CAB_DATAOK;
3002 cab_state->modulation = op->modulation;
3003 cab_state->spect_inv = stv0367_readbits(state,
3004 F367CAB_QUAD_INV);
3005#if 0
3006/* not clear for me */
3007 if (state->config->if_khz != 0) {
3008 if (state->config->if_khz > cab_state->adc_clk / 1000) {
3009 cab_state->freq_khz =
3010 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3011 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3012 - cab_state->adc_clk / 1000 + state->config->if_khz;
3013 } else {
3014 cab_state->freq_khz =
3015 FE_Cab_TunerGetFrequency(pIntParams->hTuner)
3016 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3017 + state->config->if_khz;
3018 }
3019 } else {
3020 cab_state->freq_khz =
3021 FE_Cab_TunerGetFrequency(pIntParams->hTuner) +
3022 stv0367cab_get_derot_freq(state,
3023 cab_state->adc_clk) -
3024 cab_state->adc_clk / 4000;
3025 }
3026#endif
3027 cab_state->symbol_rate = stv0367cab_GetSymbolRate(state,
3028 cab_state->mclk);
3029 cab_state->locked = 1;
3030
3031 /* stv0367_setbits(state, F367CAB_AGC_ACCUMRSTSEL,7);*/
3032 } else {
3033 switch (QAM_Lock) {
3034 case 1:
3035 signalType = FE_CAB_NOAGC;
3036 break;
3037 case 2:
3038 signalType = FE_CAB_NOTIMING;
3039 break;
3040 case 3:
3041 signalType = FE_CAB_TIMINGOK;
3042 break;
3043 case 4:
3044 signalType = FE_CAB_NOCARRIER;
3045 break;
3046 case 5:
3047 signalType = FE_CAB_CARRIEROK;
3048 break;
3049 case 7:
3050 signalType = FE_CAB_NOBLIND;
3051 break;
3052 case 8:
3053 signalType = FE_CAB_BLINDOK;
3054 break;
3055 case 10:
3056 signalType = FE_CAB_NODEMOD;
3057 break;
3058 case 11:
3059 signalType = FE_CAB_DEMODOK;
3060 break;
3061 case 12:
3062 signalType = FE_CAB_DEMODOK;
3063 break;
3064 case 13:
3065 signalType = FE_CAB_NODEMOD;
3066 break;
3067 case 14:
3068 signalType = FE_CAB_NOBLIND;
3069 break;
3070 case 15:
3071 signalType = FE_CAB_NOSIGNAL;
3072 break;
3073 default:
3074 break;
3075 }
3076
3077 }
3078
3079 /* Set the AGC control values to tracking values */
3080 stv0367_writebits(state, F367CAB_AGC_ACCUMRSTSEL, TrackAGCAccum);
3081 return signalType;
3082}
3083
3084static int stv0367cab_set_frontend(struct dvb_frontend *fe,
3085 struct dvb_frontend_parameters *param)
3086{
3087 struct stv0367_state *state = fe->demodulator_priv;
3088 struct stv0367cab_state *cab_state = state->cab_state;
3089 struct dvb_qam_parameters *op = &param->u.qam;
3090 enum stv0367cab_mod QAMSize = 0;
3091
3092 dprintk("%s: freq = %d, srate = %d\n", __func__,
3093 param->frequency, op->symbol_rate);
3094
3095 cab_state->derot_offset = 0;
3096
3097 switch (op->modulation) {
3098 case QAM_16:
3099 QAMSize = FE_CAB_MOD_QAM16;
3100 break;
3101 case QAM_32:
3102 QAMSize = FE_CAB_MOD_QAM32;
3103 break;
3104 case QAM_64:
3105 QAMSize = FE_CAB_MOD_QAM64;
3106 break;
3107 case QAM_128:
3108 QAMSize = FE_CAB_MOD_QAM128;
3109 break;
3110 case QAM_256:
3111 QAMSize = FE_CAB_MOD_QAM256;
3112 break;
3113 default:
3114 break;
3115 }
3116
3117 stv0367cab_init(fe);
3118
3119 /* Tuner Frequency Setting */
3120 if (fe->ops.tuner_ops.set_params) {
3121 if (fe->ops.i2c_gate_ctrl)
3122 fe->ops.i2c_gate_ctrl(fe, 1);
3123 fe->ops.tuner_ops.set_params(fe, param);
3124 if (fe->ops.i2c_gate_ctrl)
3125 fe->ops.i2c_gate_ctrl(fe, 0);
3126 }
3127
3128 stv0367cab_SetQamSize(
3129 state,
3130 op->symbol_rate,
3131 QAMSize);
3132
3133 stv0367cab_set_srate(state,
3134 cab_state->adc_clk,
3135 cab_state->mclk,
3136 op->symbol_rate,
3137 QAMSize);
3138 /* Search algorithm launch, [-1.1*RangeOffset, +1.1*RangeOffset] scan */
3139 cab_state->state = stv0367cab_algo(state, param);
3140 return 0;
3141}
3142
3143static int stv0367cab_get_frontend(struct dvb_frontend *fe,
3144 struct dvb_frontend_parameters *param)
3145{
3146 struct stv0367_state *state = fe->demodulator_priv;
3147 struct stv0367cab_state *cab_state = state->cab_state;
3148 struct dvb_qam_parameters *op = &param->u.qam;
3149
3150 enum stv0367cab_mod QAMSize;
3151
3152 dprintk("%s:\n", __func__);
3153
3154 op->symbol_rate = stv0367cab_GetSymbolRate(state, cab_state->mclk);
3155
3156 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3157 switch (QAMSize) {
3158 case FE_CAB_MOD_QAM16:
3159 op->modulation = QAM_16;
3160 break;
3161 case FE_CAB_MOD_QAM32:
3162 op->modulation = QAM_32;
3163 break;
3164 case FE_CAB_MOD_QAM64:
3165 op->modulation = QAM_64;
3166 break;
3167 case FE_CAB_MOD_QAM128:
3168 op->modulation = QAM_128;
3169 break;
3170 case QAM_256:
3171 op->modulation = QAM_256;
3172 break;
3173 default:
3174 break;
3175 }
3176
3177 param->frequency = stv0367_get_tuner_freq(fe);
3178
3179 dprintk("%s: tuner frequency = %d\n", __func__, param->frequency);
3180
3181 if (state->config->if_khz == 0) {
3182 param->frequency +=
3183 (stv0367cab_get_derot_freq(state, cab_state->adc_clk) -
3184 cab_state->adc_clk / 4000);
3185 return 0;
3186 }
3187
3188 if (state->config->if_khz > cab_state->adc_clk / 1000)
3189 param->frequency += (state->config->if_khz
3190 - stv0367cab_get_derot_freq(state, cab_state->adc_clk)
3191 - cab_state->adc_clk / 1000);
3192 else
3193 param->frequency += (state->config->if_khz
3194 - stv0367cab_get_derot_freq(state, cab_state->adc_clk));
3195
3196 return 0;
3197}
3198
3199#if 0
3200void stv0367cab_GetErrorCount(state, enum stv0367cab_mod QAMSize,
3201 u32 symbol_rate, FE_367qam_Monitor *Monitor_results)
3202{
3203 stv0367cab_OptimiseNByteAndGetBER(state, QAMSize, symbol_rate, Monitor_results);
3204 stv0367cab_GetPacketsCount(state, Monitor_results);
3205
3206 return;
3207}
3208
3209static int stv0367cab_read_ber(struct dvb_frontend *fe, u32 *ber)
3210{
3211 struct stv0367_state *state = fe->demodulator_priv;
3212
3213 return 0;
3214}
3215#endif
3216static s32 stv0367cab_get_rf_lvl(struct stv0367_state *state)
3217{
3218 s32 rfLevel = 0;
3219 s32 RfAgcPwm = 0, IfAgcPwm = 0;
3220 u8 i;
3221
3222 stv0367_writebits(state, F367CAB_STDBY_ADCGP, 0x0);
3223
3224 RfAgcPwm =
3225 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_LO) & 0x03) +
3226 (stv0367_readbits(state, F367CAB_RF_AGC1_LEVEL_HI) << 2);
3227 RfAgcPwm = 100 * RfAgcPwm / 1023;
3228
3229 IfAgcPwm =
3230 stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_LO) +
3231 (stv0367_readbits(state, F367CAB_AGC_IF_PWMCMD_HI) << 8);
3232 if (IfAgcPwm >= 2048)
3233 IfAgcPwm -= 2048;
3234 else
3235 IfAgcPwm += 2048;
3236
3237 IfAgcPwm = 100 * IfAgcPwm / 4095;
3238
3239 /* For DTT75467 on NIM */
3240 if (RfAgcPwm < 90 && IfAgcPwm < 28) {
3241 for (i = 0; i < RF_LOOKUP_TABLE_SIZE; i++) {
3242 if (RfAgcPwm <= stv0367cab_RF_LookUp1[0][i]) {
3243 rfLevel = (-1) * stv0367cab_RF_LookUp1[1][i];
3244 break;
3245 }
3246 }
3247 if (i == RF_LOOKUP_TABLE_SIZE)
3248 rfLevel = -56;
3249 } else { /*if IF AGC>10*/
3250 for (i = 0; i < RF_LOOKUP_TABLE2_SIZE; i++) {
3251 if (IfAgcPwm <= stv0367cab_RF_LookUp2[0][i]) {
3252 rfLevel = (-1) * stv0367cab_RF_LookUp2[1][i];
3253 break;
3254 }
3255 }
3256 if (i == RF_LOOKUP_TABLE2_SIZE)
3257 rfLevel = -72;
3258 }
3259 return rfLevel;
3260}
3261
3262static int stv0367cab_read_strength(struct dvb_frontend *fe, u16 *strength)
3263{
3264 struct stv0367_state *state = fe->demodulator_priv;
3265
3266 s32 signal = stv0367cab_get_rf_lvl(state);
3267
3268 dprintk("%s: signal=%d dBm\n", __func__, signal);
3269
3270 if (signal <= -72)
3271 *strength = 65535;
3272 else
3273 *strength = (22 + signal) * (-1311);
3274
3275 dprintk("%s: strength=%d\n", __func__, (*strength));
3276
3277 return 0;
3278}
3279
3280static int stv0367cab_read_snr(struct dvb_frontend *fe, u16 *snr)
3281{
3282 struct stv0367_state *state = fe->demodulator_priv;
3283 u32 noisepercentage;
3284 enum stv0367cab_mod QAMSize;
3285 u32 regval = 0, temp = 0;
3286 int power, i;
3287
3288 QAMSize = stv0367_readbits(state, F367CAB_QAM_MODE);
3289 switch (QAMSize) {
3290 case FE_CAB_MOD_QAM4:
3291 power = 21904;
3292 break;
3293 case FE_CAB_MOD_QAM16:
3294 power = 20480;
3295 break;
3296 case FE_CAB_MOD_QAM32:
3297 power = 23040;
3298 break;
3299 case FE_CAB_MOD_QAM64:
3300 power = 21504;
3301 break;
3302 case FE_CAB_MOD_QAM128:
3303 power = 23616;
3304 break;
3305 case FE_CAB_MOD_QAM256:
3306 power = 21760;
3307 break;
3308 case FE_CAB_MOD_QAM512:
3309 power = 1;
3310 break;
3311 case FE_CAB_MOD_QAM1024:
3312 power = 21280;
3313 break;
3314 default:
3315 power = 1;
3316 break;
3317 }
3318
3319 for (i = 0; i < 10; i++) {
3320 regval += (stv0367_readbits(state, F367CAB_SNR_LO)
3321 + 256 * stv0367_readbits(state, F367CAB_SNR_HI));
3322 }
3323
3324 regval /= 10; /*for average over 10 times in for loop above*/
3325 if (regval != 0) {
3326 temp = power
3327 * (1 << (3 + stv0367_readbits(state, F367CAB_SNR_PER)));
3328 temp /= regval;
3329 }
3330
3331 /* table values, not needed to calculate logarithms */
3332 if (temp >= 5012)
3333 noisepercentage = 100;
3334 else if (temp >= 3981)
3335 noisepercentage = 93;
3336 else if (temp >= 3162)
3337 noisepercentage = 86;
3338 else if (temp >= 2512)
3339 noisepercentage = 79;
3340 else if (temp >= 1995)
3341 noisepercentage = 72;
3342 else if (temp >= 1585)
3343 noisepercentage = 65;
3344 else if (temp >= 1259)
3345 noisepercentage = 58;
3346 else if (temp >= 1000)
3347 noisepercentage = 50;
3348 else if (temp >= 794)
3349 noisepercentage = 43;
3350 else if (temp >= 501)
3351 noisepercentage = 36;
3352 else if (temp >= 316)
3353 noisepercentage = 29;
3354 else if (temp >= 200)
3355 noisepercentage = 22;
3356 else if (temp >= 158)
3357 noisepercentage = 14;
3358 else if (temp >= 126)
3359 noisepercentage = 7;
3360 else
3361 noisepercentage = 0;
3362
3363 dprintk("%s: noisepercentage=%d\n", __func__, noisepercentage);
3364
3365 *snr = (noisepercentage * 65535) / 100;
3366
3367 return 0;
3368}
3369
3370static int stv0367cab_read_ucblcks(struct dvb_frontend *fe, u32 *ucblocks)
3371{
3372 struct stv0367_state *state = fe->demodulator_priv;
3373 int corrected, tscount;
3374
3375 *ucblocks = (stv0367_readreg(state, R367CAB_RS_COUNTER_5) << 8)
3376 | stv0367_readreg(state, R367CAB_RS_COUNTER_4);
3377 corrected = (stv0367_readreg(state, R367CAB_RS_COUNTER_3) << 8)
3378 | stv0367_readreg(state, R367CAB_RS_COUNTER_2);
3379 tscount = (stv0367_readreg(state, R367CAB_RS_COUNTER_2) << 8)
3380 | stv0367_readreg(state, R367CAB_RS_COUNTER_1);
3381
3382 dprintk("%s: uncorrected blocks=%d corrected blocks=%d tscount=%d\n",
3383 __func__, *ucblocks, corrected, tscount);
3384
3385 return 0;
3386};
3387
3388static struct dvb_frontend_ops stv0367cab_ops = {
3389 .info = {
3390 .name = "ST STV0367 DVB-C",
3391 .type = FE_QAM,
3392 .frequency_min = 47000000,
3393 .frequency_max = 862000000,
3394 .frequency_stepsize = 62500,
3395 .symbol_rate_min = 870000,
3396 .symbol_rate_max = 11700000,
3397 .caps = 0x400 |/* FE_CAN_QAM_4 */
3398 FE_CAN_QAM_16 | FE_CAN_QAM_32 |
3399 FE_CAN_QAM_64 | FE_CAN_QAM_128 |
3400 FE_CAN_QAM_256 | FE_CAN_FEC_AUTO
3401 },
3402 .release = stv0367_release,
3403 .init = stv0367cab_init,
3404 .sleep = stv0367cab_sleep,
3405 .i2c_gate_ctrl = stv0367cab_gate_ctrl,
3406 .set_frontend = stv0367cab_set_frontend,
3407 .get_frontend = stv0367cab_get_frontend,
3408 .read_status = stv0367cab_read_status,
3409/* .read_ber = stv0367cab_read_ber, */
3410 .read_signal_strength = stv0367cab_read_strength,
3411 .read_snr = stv0367cab_read_snr,
3412 .read_ucblocks = stv0367cab_read_ucblcks,
3413 .get_tune_settings = stv0367_get_tune_settings,
3414};
3415
3416struct dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
3417 struct i2c_adapter *i2c)
3418{
3419 struct stv0367_state *state = NULL;
3420 struct stv0367cab_state *cab_state = NULL;
3421
3422 /* allocate memory for the internal state */
3423 state = kzalloc(sizeof(struct stv0367_state), GFP_KERNEL);
3424 if (state == NULL)
3425 goto error;
3426 cab_state = kzalloc(sizeof(struct stv0367cab_state), GFP_KERNEL);
3427 if (cab_state == NULL)
3428 goto error;
3429
3430 /* setup the state */
3431 state->i2c = i2c;
3432 state->config = config;
3433 cab_state->search_range = 280000;
3434 state->cab_state = cab_state;
3435 state->fe.ops = stv0367cab_ops;
3436 state->fe.demodulator_priv = state;
3437 state->chip_id = stv0367_readreg(state, 0xf000);
3438
3439 dprintk("%s: chip_id = 0x%x\n", __func__, state->chip_id);
3440
3441 /* check if the demod is there */
3442 if ((state->chip_id != 0x50) && (state->chip_id != 0x60))
3443 goto error;
3444
3445 return &state->fe;
3446
3447error:
3448 kfree(cab_state);
3449 kfree(state);
3450 return NULL;
3451}
3452EXPORT_SYMBOL(stv0367cab_attach);
3453
3454MODULE_PARM_DESC(debug, "Set debug");
3455MODULE_PARM_DESC(i2c_debug, "Set i2c debug");
3456
3457MODULE_AUTHOR("Igor M. Liplianin");
3458MODULE_DESCRIPTION("ST STV0367 DVB-C/T demodulator driver");
3459MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/stv0367.h b/drivers/media/dvb/frontends/stv0367.h
new file mode 100644
index 000000000000..93cc4a57eea0
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367.h
@@ -0,0 +1,66 @@
1/*
2 * stv0367.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0367_H
27#define STV0367_H
28
29#include <linux/dvb/frontend.h>
30#include "dvb_frontend.h"
31
32struct stv0367_config {
33 u8 demod_address;
34 u32 xtal;
35 u32 if_khz;/*4500*/
36 int if_iq_mode;
37 int ts_mode;
38 int clk_pol;
39};
40
41#if defined(CONFIG_DVB_STV0367) || (defined(CONFIG_DVB_STV0367_MODULE) \
42 && defined(MODULE))
43extern struct
44dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
45 struct i2c_adapter *i2c);
46extern struct
47dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
48 struct i2c_adapter *i2c);
49#else
50static inline struct
51dvb_frontend *stv0367ter_attach(const struct stv0367_config *config,
52 struct i2c_adapter *i2c)
53{
54 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
55 return NULL;
56}
57static inline struct
58dvb_frontend *stv0367cab_attach(const struct stv0367_config *config,
59 struct i2c_adapter *i2c)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
62 return NULL;
63}
64#endif
65
66#endif
diff --git a/drivers/media/dvb/frontends/stv0367_priv.h b/drivers/media/dvb/frontends/stv0367_priv.h
new file mode 100644
index 000000000000..995db0689ddd
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367_priv.h
@@ -0,0 +1,212 @@
1/*
2 * stv0367_priv.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25/* Common driver error constants */
26
27#ifndef STV0367_PRIV_H
28#define STV0367_PRIV_H
29
30#ifndef TRUE
31 #define TRUE (1 == 1)
32#endif
33#ifndef FALSE
34 #define FALSE (!TRUE)
35#endif
36
37#ifndef NULL
38#define NULL 0
39#endif
40
41/* MACRO definitions */
42#define ABS(X) ((X) < 0 ? (-1 * (X)) : (X))
43#define MAX(X, Y) ((X) >= (Y) ? (X) : (Y))
44#define MIN(X, Y) ((X) <= (Y) ? (X) : (Y))
45#define INRANGE(X, Y, Z) \
46 ((((X) <= (Y)) && ((Y) <= (Z))) || \
47 (((Z) <= (Y)) && ((Y) <= (X))) ? 1 : 0)
48
49#ifndef MAKEWORD
50#define MAKEWORD(X, Y) (((X) << 8) + (Y))
51#endif
52
53#define LSB(X) (((X) & 0xff))
54#define MSB(Y) (((Y) >> 8) & 0xff)
55#define MMSB(Y)(((Y) >> 16) & 0xff)
56
57enum stv0367_ter_signal_type {
58 FE_TER_NOAGC = 0,
59 FE_TER_AGCOK = 5,
60 FE_TER_NOTPS = 6,
61 FE_TER_TPSOK = 7,
62 FE_TER_NOSYMBOL = 8,
63 FE_TER_BAD_CPQ = 9,
64 FE_TER_PRFOUNDOK = 10,
65 FE_TER_NOPRFOUND = 11,
66 FE_TER_LOCKOK = 12,
67 FE_TER_NOLOCK = 13,
68 FE_TER_SYMBOLOK = 15,
69 FE_TER_CPAMPOK = 16,
70 FE_TER_NOCPAMP = 17,
71 FE_TER_SWNOK = 18
72};
73
74enum stv0367_ts_mode {
75 STV0367_OUTPUTMODE_DEFAULT,
76 STV0367_SERIAL_PUNCT_CLOCK,
77 STV0367_SERIAL_CONT_CLOCK,
78 STV0367_PARALLEL_PUNCT_CLOCK,
79 STV0367_DVBCI_CLOCK
80};
81
82enum stv0367_clk_pol {
83 STV0367_CLOCKPOLARITY_DEFAULT,
84 STV0367_RISINGEDGE_CLOCK,
85 STV0367_FALLINGEDGE_CLOCK
86};
87
88enum stv0367_ter_bw {
89 FE_TER_CHAN_BW_6M = 6,
90 FE_TER_CHAN_BW_7M = 7,
91 FE_TER_CHAN_BW_8M = 8
92};
93
94#if 0
95enum FE_TER_Rate_TPS {
96 FE_TER_TPS_1_2 = 0,
97 FE_TER_TPS_2_3 = 1,
98 FE_TER_TPS_3_4 = 2,
99 FE_TER_TPS_5_6 = 3,
100 FE_TER_TPS_7_8 = 4
101};
102#endif
103
104enum stv0367_ter_mode {
105 FE_TER_MODE_2K,
106 FE_TER_MODE_8K,
107 FE_TER_MODE_4K
108};
109#if 0
110enum FE_TER_Hierarchy_Alpha {
111 FE_TER_HIER_ALPHA_NONE, /* Regular modulation */
112 FE_TER_HIER_ALPHA_1, /* Hierarchical modulation a = 1*/
113 FE_TER_HIER_ALPHA_2, /* Hierarchical modulation a = 2*/
114 FE_TER_HIER_ALPHA_4 /* Hierarchical modulation a = 4*/
115};
116#endif
117enum stv0367_ter_hierarchy {
118 FE_TER_HIER_NONE, /*Hierarchy None*/
119 FE_TER_HIER_LOW_PRIO, /*Hierarchy : Low Priority*/
120 FE_TER_HIER_HIGH_PRIO, /*Hierarchy : High Priority*/
121 FE_TER_HIER_PRIO_ANY /*Hierarchy :Any*/
122};
123
124#if 0
125enum fe_stv0367_ter_spec {
126 FE_TER_INVERSION_NONE = 0,
127 FE_TER_INVERSION = 1,
128 FE_TER_INVERSION_AUTO = 2,
129 FE_TER_INVERSION_UNK = 4
130};
131#endif
132
133enum stv0367_ter_if_iq_mode {
134 FE_TER_NORMAL_IF_TUNER = 0,
135 FE_TER_LONGPATH_IF_TUNER = 1,
136 FE_TER_IQ_TUNER = 2
137
138};
139
140#if 0
141enum FE_TER_FECRate {
142 FE_TER_FEC_NONE = 0x00, /* no FEC rate specified */
143 FE_TER_FEC_ALL = 0xFF, /* Logical OR of all FECs */
144 FE_TER_FEC_1_2 = 1,
145 FE_TER_FEC_2_3 = (1 << 1),
146 FE_TER_FEC_3_4 = (1 << 2),
147 FE_TER_FEC_4_5 = (1 << 3),
148 FE_TER_FEC_5_6 = (1 << 4),
149 FE_TER_FEC_6_7 = (1 << 5),
150 FE_TER_FEC_7_8 = (1 << 6),
151 FE_TER_FEC_8_9 = (1 << 7)
152};
153
154enum FE_TER_Rate {
155 FE_TER_FE_1_2 = 0,
156 FE_TER_FE_2_3 = 1,
157 FE_TER_FE_3_4 = 2,
158 FE_TER_FE_5_6 = 3,
159 FE_TER_FE_6_7 = 4,
160 FE_TER_FE_7_8 = 5
161};
162#endif
163
164enum stv0367_ter_force {
165 FE_TER_FORCENONE = 0,
166 FE_TER_FORCE_M_G = 1
167};
168
169enum stv0367cab_mod {
170 FE_CAB_MOD_QAM4,
171 FE_CAB_MOD_QAM16,
172 FE_CAB_MOD_QAM32,
173 FE_CAB_MOD_QAM64,
174 FE_CAB_MOD_QAM128,
175 FE_CAB_MOD_QAM256,
176 FE_CAB_MOD_QAM512,
177 FE_CAB_MOD_QAM1024
178};
179#if 0
180enum {
181 FE_CAB_FEC_A = 1, /* J83 Annex A */
182 FE_CAB_FEC_B = (1 << 1),/* J83 Annex B */
183 FE_CAB_FEC_C = (1 << 2) /* J83 Annex C */
184} FE_CAB_FECType_t;
185#endif
186struct stv0367_cab_signal_info {
187 int locked;
188 u32 frequency; /* kHz */
189 u32 symbol_rate; /* Mbds */
190 enum stv0367cab_mod modulation;
191 fe_spectral_inversion_t spect_inv;
192 s32 Power_dBmx10; /* Power of the RF signal (dBm x 10) */
193 u32 CN_dBx10; /* Carrier to noise ratio (dB x 10) */
194 u32 BER; /* Bit error rate (x 10000000) */
195};
196
197enum stv0367_cab_signal_type {
198 FE_CAB_NOTUNER,
199 FE_CAB_NOAGC,
200 FE_CAB_NOSIGNAL,
201 FE_CAB_NOTIMING,
202 FE_CAB_TIMINGOK,
203 FE_CAB_NOCARRIER,
204 FE_CAB_CARRIEROK,
205 FE_CAB_NOBLIND,
206 FE_CAB_BLINDOK,
207 FE_CAB_NODEMOD,
208 FE_CAB_DEMODOK,
209 FE_CAB_DATAOK
210};
211
212#endif
diff --git a/drivers/media/dvb/frontends/stv0367_regs.h b/drivers/media/dvb/frontends/stv0367_regs.h
new file mode 100644
index 000000000000..a96fbdc7e25e
--- /dev/null
+++ b/drivers/media/dvb/frontends/stv0367_regs.h
@@ -0,0 +1,3614 @@
1/*
2 * stv0367_regs.h
3 *
4 * Driver for ST STV0367 DVB-T & DVB-C demodulator IC.
5 *
6 * Copyright (C) ST Microelectronics.
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef STV0367_REGS_H
27#define STV0367_REGS_H
28
29/* ID */
30#define R367TER_ID 0xf000
31#define F367TER_IDENTIFICATIONREG 0xf00000ff
32
33/* I2CRPT */
34#define R367TER_I2CRPT 0xf001
35#define F367TER_I2CT_ON 0xf0010080
36#define F367TER_ENARPT_LEVEL 0xf0010070
37#define F367TER_SCLT_DELAY 0xf0010008
38#define F367TER_SCLT_NOD 0xf0010004
39#define F367TER_STOP_ENABLE 0xf0010002
40#define F367TER_SDAT_NOD 0xf0010001
41
42/* TOPCTRL */
43#define R367TER_TOPCTRL 0xf002
44#define F367TER_STDBY 0xf0020080
45#define F367TER_STDBY_FEC 0xf0020040
46#define F367TER_STDBY_CORE 0xf0020020
47#define F367TER_QAM_COFDM 0xf0020010
48#define F367TER_TS_DIS 0xf0020008
49#define F367TER_DIR_CLK_216 0xf0020004
50#define F367TER_TUNER_BB 0xf0020002
51#define F367TER_DVBT_H 0xf0020001
52
53/* IOCFG0 */
54#define R367TER_IOCFG0 0xf003
55#define F367TER_OP0_SD 0xf0030080
56#define F367TER_OP0_VAL 0xf0030040
57#define F367TER_OP0_OD 0xf0030020
58#define F367TER_OP0_INV 0xf0030010
59#define F367TER_OP0_DACVALUE_HI 0xf003000f
60
61/* DAc0R */
62#define R367TER_DAC0R 0xf004
63#define F367TER_OP0_DACVALUE_LO 0xf00400ff
64
65/* IOCFG1 */
66#define R367TER_IOCFG1 0xf005
67#define F367TER_IP0 0xf0050040
68#define F367TER_OP1_OD 0xf0050020
69#define F367TER_OP1_INV 0xf0050010
70#define F367TER_OP1_DACVALUE_HI 0xf005000f
71
72/* DAC1R */
73#define R367TER_DAC1R 0xf006
74#define F367TER_OP1_DACVALUE_LO 0xf00600ff
75
76/* IOCFG2 */
77#define R367TER_IOCFG2 0xf007
78#define F367TER_OP2_LOCK_CONF 0xf00700e0
79#define F367TER_OP2_OD 0xf0070010
80#define F367TER_OP2_VAL 0xf0070008
81#define F367TER_OP1_LOCK_CONF 0xf0070007
82
83/* SDFR */
84#define R367TER_SDFR 0xf008
85#define F367TER_OP0_FREQ 0xf00800f0
86#define F367TER_OP1_FREQ 0xf008000f
87
88/* STATUS */
89#define R367TER_STATUS 0xf009
90#define F367TER_TPS_LOCK 0xf0090080
91#define F367TER_SYR_LOCK 0xf0090040
92#define F367TER_AGC_LOCK 0xf0090020
93#define F367TER_PRF 0xf0090010
94#define F367TER_LK 0xf0090008
95#define F367TER_PR 0xf0090007
96
97/* AUX_CLK */
98#define R367TER_AUX_CLK 0xf00a
99#define F367TER_AUXFEC_CTL 0xf00a00c0
100#define F367TER_DIS_CKX4 0xf00a0020
101#define F367TER_CKSEL 0xf00a0018
102#define F367TER_CKDIV_PROG 0xf00a0006
103#define F367TER_AUXCLK_ENA 0xf00a0001
104
105/* FREESYS1 */
106#define R367TER_FREESYS1 0xf00b
107#define F367TER_FREE_SYS1 0xf00b00ff
108
109/* FREESYS2 */
110#define R367TER_FREESYS2 0xf00c
111#define F367TER_FREE_SYS2 0xf00c00ff
112
113/* FREESYS3 */
114#define R367TER_FREESYS3 0xf00d
115#define F367TER_FREE_SYS3 0xf00d00ff
116
117/* GPIO_CFG */
118#define R367TER_GPIO_CFG 0xf00e
119#define F367TER_GPIO7_NOD 0xf00e0080
120#define F367TER_GPIO7_CFG 0xf00e0040
121#define F367TER_GPIO6_NOD 0xf00e0020
122#define F367TER_GPIO6_CFG 0xf00e0010
123#define F367TER_GPIO5_NOD 0xf00e0008
124#define F367TER_GPIO5_CFG 0xf00e0004
125#define F367TER_GPIO4_NOD 0xf00e0002
126#define F367TER_GPIO4_CFG 0xf00e0001
127
128/* GPIO_CMD */
129#define R367TER_GPIO_CMD 0xf00f
130#define F367TER_GPIO7_VAL 0xf00f0008
131#define F367TER_GPIO6_VAL 0xf00f0004
132#define F367TER_GPIO5_VAL 0xf00f0002
133#define F367TER_GPIO4_VAL 0xf00f0001
134
135/* AGC2MAX */
136#define R367TER_AGC2MAX 0xf010
137#define F367TER_AGC2_MAX 0xf01000ff
138
139/* AGC2MIN */
140#define R367TER_AGC2MIN 0xf011
141#define F367TER_AGC2_MIN 0xf01100ff
142
143/* AGC1MAX */
144#define R367TER_AGC1MAX 0xf012
145#define F367TER_AGC1_MAX 0xf01200ff
146
147/* AGC1MIN */
148#define R367TER_AGC1MIN 0xf013
149#define F367TER_AGC1_MIN 0xf01300ff
150
151/* AGCR */
152#define R367TER_AGCR 0xf014
153#define F367TER_RATIO_A 0xf01400e0
154#define F367TER_RATIO_B 0xf0140018
155#define F367TER_RATIO_C 0xf0140007
156
157/* AGC2TH */
158#define R367TER_AGC2TH 0xf015
159#define F367TER_AGC2_THRES 0xf01500ff
160
161/* AGC12c */
162#define R367TER_AGC12C 0xf016
163#define F367TER_AGC1_IV 0xf0160080
164#define F367TER_AGC1_OD 0xf0160040
165#define F367TER_AGC1_LOAD 0xf0160020
166#define F367TER_AGC2_IV 0xf0160010
167#define F367TER_AGC2_OD 0xf0160008
168#define F367TER_AGC2_LOAD 0xf0160004
169#define F367TER_AGC12_MODE 0xf0160003
170
171/* AGCCTRL1 */
172#define R367TER_AGCCTRL1 0xf017
173#define F367TER_DAGC_ON 0xf0170080
174#define F367TER_INVERT_AGC12 0xf0170040
175#define F367TER_AGC1_MODE 0xf0170008
176#define F367TER_AGC2_MODE 0xf0170007
177
178/* AGCCTRL2 */
179#define R367TER_AGCCTRL2 0xf018
180#define F367TER_FRZ2_CTRL 0xf0180060
181#define F367TER_FRZ1_CTRL 0xf0180018
182#define F367TER_TIME_CST 0xf0180007
183
184/* AGC1VAL1 */
185#define R367TER_AGC1VAL1 0xf019
186#define F367TER_AGC1_VAL_LO 0xf01900ff
187
188/* AGC1VAL2 */
189#define R367TER_AGC1VAL2 0xf01a
190#define F367TER_AGC1_VAL_HI 0xf01a000f
191
192/* AGC2VAL1 */
193#define R367TER_AGC2VAL1 0xf01b
194#define F367TER_AGC2_VAL_LO 0xf01b00ff
195
196/* AGC2VAL2 */
197#define R367TER_AGC2VAL2 0xf01c
198#define F367TER_AGC2_VAL_HI 0xf01c000f
199
200/* AGC2PGA */
201#define R367TER_AGC2PGA 0xf01d
202#define F367TER_AGC2_PGA 0xf01d00ff
203
204/* OVF_RATE1 */
205#define R367TER_OVF_RATE1 0xf01e
206#define F367TER_OVF_RATE_HI 0xf01e000f
207
208/* OVF_RATE2 */
209#define R367TER_OVF_RATE2 0xf01f
210#define F367TER_OVF_RATE_LO 0xf01f00ff
211
212/* GAIN_SRC1 */
213#define R367TER_GAIN_SRC1 0xf020
214#define F367TER_INV_SPECTR 0xf0200080
215#define F367TER_IQ_INVERT 0xf0200040
216#define F367TER_INR_BYPASS 0xf0200020
217#define F367TER_STATUS_INV_SPECRUM 0xf0200010
218#define F367TER_GAIN_SRC_HI 0xf020000f
219
220/* GAIN_SRC2 */
221#define R367TER_GAIN_SRC2 0xf021
222#define F367TER_GAIN_SRC_LO 0xf02100ff
223
224/* INC_DEROT1 */
225#define R367TER_INC_DEROT1 0xf022
226#define F367TER_INC_DEROT_HI 0xf02200ff
227
228/* INC_DEROT2 */
229#define R367TER_INC_DEROT2 0xf023
230#define F367TER_INC_DEROT_LO 0xf02300ff
231
232/* PPM_CPAMP_DIR */
233#define R367TER_PPM_CPAMP_DIR 0xf024
234#define F367TER_PPM_CPAMP_DIRECT 0xf02400ff
235
236/* PPM_CPAMP_INV */
237#define R367TER_PPM_CPAMP_INV 0xf025
238#define F367TER_PPM_CPAMP_INVER 0xf02500ff
239
240/* FREESTFE_1 */
241#define R367TER_FREESTFE_1 0xf026
242#define F367TER_SYMBOL_NUMBER_INC 0xf02600c0
243#define F367TER_SEL_LSB 0xf0260004
244#define F367TER_AVERAGE_ON 0xf0260002
245#define F367TER_DC_ADJ 0xf0260001
246
247/* FREESTFE_2 */
248#define R367TER_FREESTFE_2 0xf027
249#define F367TER_SEL_SRCOUT 0xf02700c0
250#define F367TER_SEL_SYRTHR 0xf027001f
251
252/* DCOFFSET */
253#define R367TER_DCOFFSET 0xf028
254#define F367TER_SELECT_I_Q 0xf0280080
255#define F367TER_DC_OFFSET 0xf028007f
256
257/* EN_PROCESS */
258#define R367TER_EN_PROCESS 0xf029
259#define F367TER_FREE 0xf02900f0
260#define F367TER_ENAB_MANUAL 0xf0290001
261
262/* SDI_SMOOTHER */
263#define R367TER_SDI_SMOOTHER 0xf02a
264#define F367TER_DIS_SMOOTH 0xf02a0080
265#define F367TER_SDI_INC_SMOOTHER 0xf02a007f
266
267/* FE_LOOP_OPEN */
268#define R367TER_FE_LOOP_OPEN 0xf02b
269#define F367TER_TRL_LOOP_OP 0xf02b0002
270#define F367TER_CRL_LOOP_OP 0xf02b0001
271
272/* FREQOFF1 */
273#define R367TER_FREQOFF1 0xf02c
274#define F367TER_FREQ_OFFSET_LOOP_OPEN_VHI 0xf02c00ff
275
276/* FREQOFF2 */
277#define R367TER_FREQOFF2 0xf02d
278#define F367TER_FREQ_OFFSET_LOOP_OPEN_HI 0xf02d00ff
279
280/* FREQOFF3 */
281#define R367TER_FREQOFF3 0xf02e
282#define F367TER_FREQ_OFFSET_LOOP_OPEN_LO 0xf02e00ff
283
284/* TIMOFF1 */
285#define R367TER_TIMOFF1 0xf02f
286#define F367TER_TIM_OFFSET_LOOP_OPEN_HI 0xf02f00ff
287
288/* TIMOFF2 */
289#define R367TER_TIMOFF2 0xf030
290#define F367TER_TIM_OFFSET_LOOP_OPEN_LO 0xf03000ff
291
292/* EPQ */
293#define R367TER_EPQ 0xf031
294#define F367TER_EPQ1 0xf03100ff
295
296/* EPQAUTO */
297#define R367TER_EPQAUTO 0xf032
298#define F367TER_EPQ2 0xf03200ff
299
300/* SYR_UPDATE */
301#define R367TER_SYR_UPDATE 0xf033
302#define F367TER_SYR_PROTV 0xf0330080
303#define F367TER_SYR_PROTV_GAIN 0xf0330060
304#define F367TER_SYR_FILTER 0xf0330010
305#define F367TER_SYR_TRACK_THRES 0xf033000c
306
307/* CHPFREE */
308#define R367TER_CHPFREE 0xf034
309#define F367TER_CHP_FREE 0xf03400ff
310
311/* PPM_STATE_MAC */
312#define R367TER_PPM_STATE_MAC 0xf035
313#define F367TER_PPM_STATE_MACHINE_DECODER 0xf035003f
314
315/* INR_THRESHOLD */
316#define R367TER_INR_THRESHOLD 0xf036
317#define F367TER_INR_THRESH 0xf03600ff
318
319/* EPQ_TPS_ID_CELL */
320#define R367TER_EPQ_TPS_ID_CELL 0xf037
321#define F367TER_ENABLE_LGTH_TO_CF 0xf0370080
322#define F367TER_DIS_TPS_RSVD 0xf0370040
323#define F367TER_DIS_BCH 0xf0370020
324#define F367TER_DIS_ID_CEL 0xf0370010
325#define F367TER_TPS_ADJUST_SYM 0xf037000f
326
327/* EPQ_CFG */
328#define R367TER_EPQ_CFG 0xf038
329#define F367TER_EPQ_RANGE 0xf0380002
330#define F367TER_EPQ_SOFT 0xf0380001
331
332/* EPQ_STATUS */
333#define R367TER_EPQ_STATUS 0xf039
334#define F367TER_SLOPE_INC 0xf03900fc
335#define F367TER_TPS_FIELD 0xf0390003
336
337/* AUTORELOCK */
338#define R367TER_AUTORELOCK 0xf03a
339#define F367TER_BYPASS_BER_TEMPO 0xf03a0080
340#define F367TER_BER_TEMPO 0xf03a0070
341#define F367TER_BYPASS_COFDM_TEMPO 0xf03a0008
342#define F367TER_COFDM_TEMPO 0xf03a0007
343
344/* BER_THR_VMSB */
345#define R367TER_BER_THR_VMSB 0xf03b
346#define F367TER_BER_THRESHOLD_HI 0xf03b00ff
347
348/* BER_THR_MSB */
349#define R367TER_BER_THR_MSB 0xf03c
350#define F367TER_BER_THRESHOLD_MID 0xf03c00ff
351
352/* BER_THR_LSB */
353#define R367TER_BER_THR_LSB 0xf03d
354#define F367TER_BER_THRESHOLD_LO 0xf03d00ff
355
356/* CCD */
357#define R367TER_CCD 0xf03e
358#define F367TER_CCD_DETECTED 0xf03e0080
359#define F367TER_CCD_RESET 0xf03e0040
360#define F367TER_CCD_THRESHOLD 0xf03e000f
361
362/* SPECTR_CFG */
363#define R367TER_SPECTR_CFG 0xf03f
364#define F367TER_SPECT_CFG 0xf03f0003
365
366/* CONSTMU_MSB */
367#define R367TER_CONSTMU_MSB 0xf040
368#define F367TER_CONSTMU_FREEZE 0xf0400080
369#define F367TER_CONSTNU_FORCE_EN 0xf0400040
370#define F367TER_CONST_MU_MSB 0xf040003f
371
372/* CONSTMU_LSB */
373#define R367TER_CONSTMU_LSB 0xf041
374#define F367TER_CONST_MU_LSB 0xf04100ff
375
376/* CONSTMU_MAX_MSB */
377#define R367TER_CONSTMU_MAX_MSB 0xf042
378#define F367TER_CONST_MU_MAX_MSB 0xf042003f
379
380/* CONSTMU_MAX_LSB */
381#define R367TER_CONSTMU_MAX_LSB 0xf043
382#define F367TER_CONST_MU_MAX_LSB 0xf04300ff
383
384/* ALPHANOISE */
385#define R367TER_ALPHANOISE 0xf044
386#define F367TER_USE_ALLFILTER 0xf0440080
387#define F367TER_INTER_ON 0xf0440040
388#define F367TER_ALPHA_NOISE 0xf044001f
389
390/* MAXGP_MSB */
391#define R367TER_MAXGP_MSB 0xf045
392#define F367TER_MUFILTER_LENGTH 0xf04500f0
393#define F367TER_MAX_GP_MSB 0xf045000f
394
395/* MAXGP_LSB */
396#define R367TER_MAXGP_LSB 0xf046
397#define F367TER_MAX_GP_LSB 0xf04600ff
398
399/* ALPHAMSB */
400#define R367TER_ALPHAMSB 0xf047
401#define F367TER_CHC_DATARATE 0xf04700c0
402#define F367TER_ALPHA_MSB 0xf047003f
403
404/* ALPHALSB */
405#define R367TER_ALPHALSB 0xf048
406#define F367TER_ALPHA_LSB 0xf04800ff
407
408/* PILOT_ACCU */
409#define R367TER_PILOT_ACCU 0xf049
410#define F367TER_USE_SCAT4ADDAPT 0xf0490080
411#define F367TER_PILOT_ACC 0xf049001f
412
413/* PILOTMU_ACCU */
414#define R367TER_PILOTMU_ACCU 0xf04a
415#define F367TER_DISCARD_BAD_SP 0xf04a0080
416#define F367TER_DISCARD_BAD_CP 0xf04a0040
417#define F367TER_PILOT_MU_ACCU 0xf04a001f
418
419/* FILT_CHANNEL_EST */
420#define R367TER_FILT_CHANNEL_EST 0xf04b
421#define F367TER_USE_FILT_PILOT 0xf04b0080
422#define F367TER_FILT_CHANNEL 0xf04b007f
423
424/* ALPHA_NOPISE_FREQ */
425#define R367TER_ALPHA_NOPISE_FREQ 0xf04c
426#define F367TER_NOISE_FREQ_FILT 0xf04c0040
427#define F367TER_ALPHA_NOISE_FREQ 0xf04c003f
428
429/* RATIO_PILOT */
430#define R367TER_RATIO_PILOT 0xf04d
431#define F367TER_RATIO_MEAN_SP 0xf04d00f0
432#define F367TER_RATIO_MEAN_CP 0xf04d000f
433
434/* CHC_CTL */
435#define R367TER_CHC_CTL 0xf04e
436#define F367TER_TRACK_EN 0xf04e0080
437#define F367TER_NOISE_NORM_EN 0xf04e0040
438#define F367TER_FORCE_CHC_RESET 0xf04e0020
439#define F367TER_SHORT_TIME 0xf04e0010
440#define F367TER_FORCE_STATE_EN 0xf04e0008
441#define F367TER_FORCE_STATE 0xf04e0007
442
443/* EPQ_ADJUST */
444#define R367TER_EPQ_ADJUST 0xf04f
445#define F367TER_ADJUST_SCAT_IND 0xf04f00c0
446#define F367TER_ONE_SYMBOL 0xf04f0010
447#define F367TER_EPQ_DECAY 0xf04f000e
448#define F367TER_HOLD_SLOPE 0xf04f0001
449
450/* EPQ_THRES */
451#define R367TER_EPQ_THRES 0xf050
452#define F367TER_EPQ_THR 0xf05000ff
453
454/* OMEGA_CTL */
455#define R367TER_OMEGA_CTL 0xf051
456#define F367TER_OMEGA_RST 0xf0510080
457#define F367TER_FREEZE_OMEGA 0xf0510040
458#define F367TER_OMEGA_SEL 0xf051003f
459
460/* GP_CTL */
461#define R367TER_GP_CTL 0xf052
462#define F367TER_CHC_STATE 0xf05200e0
463#define F367TER_FREEZE_GP 0xf0520010
464#define F367TER_GP_SEL 0xf052000f
465
466/* MUMSB */
467#define R367TER_MUMSB 0xf053
468#define F367TER_MU_MSB 0xf053007f
469
470/* MULSB */
471#define R367TER_MULSB 0xf054
472#define F367TER_MU_LSB 0xf05400ff
473
474/* GPMSB */
475#define R367TER_GPMSB 0xf055
476#define F367TER_CSI_THRESHOLD 0xf05500e0
477#define F367TER_GP_MSB 0xf055000f
478
479/* GPLSB */
480#define R367TER_GPLSB 0xf056
481#define F367TER_GP_LSB 0xf05600ff
482
483/* OMEGAMSB */
484#define R367TER_OMEGAMSB 0xf057
485#define F367TER_OMEGA_MSB 0xf057007f
486
487/* OMEGALSB */
488#define R367TER_OMEGALSB 0xf058
489#define F367TER_OMEGA_LSB 0xf05800ff
490
491/* SCAT_NB */
492#define R367TER_SCAT_NB 0xf059
493#define F367TER_CHC_TEST 0xf05900f8
494#define F367TER_SCAT_NUMB 0xf0590003
495
496/* CHC_DUMMY */
497#define R367TER_CHC_DUMMY 0xf05a
498#define F367TER_CHC_DUM 0xf05a00ff
499
500/* INC_CTL */
501#define R367TER_INC_CTL 0xf05b
502#define F367TER_INC_BYPASS 0xf05b0080
503#define F367TER_INC_NDEPTH 0xf05b000c
504#define F367TER_INC_MADEPTH 0xf05b0003
505
506/* INCTHRES_COR1 */
507#define R367TER_INCTHRES_COR1 0xf05c
508#define F367TER_INC_THRES_COR1 0xf05c00ff
509
510/* INCTHRES_COR2 */
511#define R367TER_INCTHRES_COR2 0xf05d
512#define F367TER_INC_THRES_COR2 0xf05d00ff
513
514/* INCTHRES_DET1 */
515#define R367TER_INCTHRES_DET1 0xf05e
516#define F367TER_INC_THRES_DET1 0xf05e003f
517
518/* INCTHRES_DET2 */
519#define R367TER_INCTHRES_DET2 0xf05f
520#define F367TER_INC_THRES_DET2 0xf05f003f
521
522/* IIR_CELLNB */
523#define R367TER_IIR_CELLNB 0xf060
524#define F367TER_NRST_IIR 0xf0600080
525#define F367TER_IIR_CELL_NB 0xf0600007
526
527/* IIRCX_COEFF1_MSB */
528#define R367TER_IIRCX_COEFF1_MSB 0xf061
529#define F367TER_IIR_CX_COEFF1_MSB 0xf06100ff
530
531/* IIRCX_COEFF1_LSB */
532#define R367TER_IIRCX_COEFF1_LSB 0xf062
533#define F367TER_IIR_CX_COEFF1_LSB 0xf06200ff
534
535/* IIRCX_COEFF2_MSB */
536#define R367TER_IIRCX_COEFF2_MSB 0xf063
537#define F367TER_IIR_CX_COEFF2_MSB 0xf06300ff
538
539/* IIRCX_COEFF2_LSB */
540#define R367TER_IIRCX_COEFF2_LSB 0xf064
541#define F367TER_IIR_CX_COEFF2_LSB 0xf06400ff
542
543/* IIRCX_COEFF3_MSB */
544#define R367TER_IIRCX_COEFF3_MSB 0xf065
545#define F367TER_IIR_CX_COEFF3_MSB 0xf06500ff
546
547/* IIRCX_COEFF3_LSB */
548#define R367TER_IIRCX_COEFF3_LSB 0xf066
549#define F367TER_IIR_CX_COEFF3_LSB 0xf06600ff
550
551/* IIRCX_COEFF4_MSB */
552#define R367TER_IIRCX_COEFF4_MSB 0xf067
553#define F367TER_IIR_CX_COEFF4_MSB 0xf06700ff
554
555/* IIRCX_COEFF4_LSB */
556#define R367TER_IIRCX_COEFF4_LSB 0xf068
557#define F367TER_IIR_CX_COEFF4_LSB 0xf06800ff
558
559/* IIRCX_COEFF5_MSB */
560#define R367TER_IIRCX_COEFF5_MSB 0xf069
561#define F367TER_IIR_CX_COEFF5_MSB 0xf06900ff
562
563/* IIRCX_COEFF5_LSB */
564#define R367TER_IIRCX_COEFF5_LSB 0xf06a
565#define F367TER_IIR_CX_COEFF5_LSB 0xf06a00ff
566
567/* FEPATH_CFG */
568#define R367TER_FEPATH_CFG 0xf06b
569#define F367TER_DEMUX_SWAP 0xf06b0004
570#define F367TER_DIGAGC_SWAP 0xf06b0002
571#define F367TER_LONGPATH_IF 0xf06b0001
572
573/* PMC1_FUNC */
574#define R367TER_PMC1_FUNC 0xf06c
575#define F367TER_SOFT_RSTN 0xf06c0080
576#define F367TER_PMC1_AVERAGE_TIME 0xf06c0078
577#define F367TER_PMC1_WAIT_TIME 0xf06c0006
578#define F367TER_PMC1_2N_SEL 0xf06c0001
579
580/* PMC1_FOR */
581#define R367TER_PMC1_FOR 0xf06d
582#define F367TER_PMC1_FORCE 0xf06d0080
583#define F367TER_PMC1_FORCE_VALUE 0xf06d007c
584
585/* PMC2_FUNC */
586#define R367TER_PMC2_FUNC 0xf06e
587#define F367TER_PMC2_SOFT_STN 0xf06e0080
588#define F367TER_PMC2_ACCU_TIME 0xf06e0070
589#define F367TER_PMC2_CMDP_MN 0xf06e0008
590#define F367TER_PMC2_SWAP 0xf06e0004
591
592/* STATUS_ERR_DA */
593#define R367TER_STATUS_ERR_DA 0xf06f
594#define F367TER_COM_USEGAINTRK 0xf06f0080
595#define F367TER_COM_AGCLOCK 0xf06f0040
596#define F367TER_AUT_AGCLOCK 0xf06f0020
597#define F367TER_MIN_ERR_X_LSB 0xf06f000f
598
599/* DIG_AGC_R */
600#define R367TER_DIG_AGC_R 0xf070
601#define F367TER_COM_SOFT_RSTN 0xf0700080
602#define F367TER_COM_AGC_ON 0xf0700040
603#define F367TER_COM_EARLY 0xf0700020
604#define F367TER_AUT_SOFT_RESETN 0xf0700010
605#define F367TER_AUT_AGC_ON 0xf0700008
606#define F367TER_AUT_EARLY 0xf0700004
607#define F367TER_AUT_ROT_EN 0xf0700002
608#define F367TER_LOCK_SOFT_RESETN 0xf0700001
609
610/* COMAGC_TARMSB */
611#define R367TER_COMAGC_TARMSB 0xf071
612#define F367TER_COM_AGC_TARGET_MSB 0xf07100ff
613
614/* COM_AGC_TAR_ENMODE */
615#define R367TER_COM_AGC_TAR_ENMODE 0xf072
616#define F367TER_COM_AGC_TARGET_LSB 0xf07200f0
617#define F367TER_COM_ENMODE 0xf072000f
618
619/* COM_AGC_CFG */
620#define R367TER_COM_AGC_CFG 0xf073
621#define F367TER_COM_N 0xf07300f8
622#define F367TER_COM_STABMODE 0xf0730006
623#define F367TER_ERR_SEL 0xf0730001
624
625/* COM_AGC_GAIN1 */
626#define R367TER_COM_AGC_GAIN1 0xf074
627#define F367TER_COM_GAIN1aCK 0xf07400f0
628#define F367TER_COM_GAIN1TRK 0xf074000f
629
630/* AUT_AGC_TARGETMSB */
631#define R367TER_AUT_AGC_TARGETMSB 0xf075
632#define F367TER_AUT_AGC_TARGET_MSB 0xf07500ff
633
634/* LOCK_DET_MSB */
635#define R367TER_LOCK_DET_MSB 0xf076
636#define F367TER_LOCK_DETECT_MSB 0xf07600ff
637
638/* AGCTAR_LOCK_LSBS */
639#define R367TER_AGCTAR_LOCK_LSBS 0xf077
640#define F367TER_AUT_AGC_TARGET_LSB 0xf07700f0
641#define F367TER_LOCK_DETECT_LSB 0xf077000f
642
643/* AUT_GAIN_EN */
644#define R367TER_AUT_GAIN_EN 0xf078
645#define F367TER_AUT_ENMODE 0xf07800f0
646#define F367TER_AUT_GAIN2 0xf078000f
647
648/* AUT_CFG */
649#define R367TER_AUT_CFG 0xf079
650#define F367TER_AUT_N 0xf07900f8
651#define F367TER_INT_CHOICE 0xf0790006
652#define F367TER_INT_LOAD 0xf0790001
653
654/* LOCKN */
655#define R367TER_LOCKN 0xf07a
656#define F367TER_LOCK_N 0xf07a00f8
657#define F367TER_SEL_IQNTAR 0xf07a0004
658#define F367TER_LOCK_DETECT_CHOICE 0xf07a0003
659
660/* INT_X_3 */
661#define R367TER_INT_X_3 0xf07b
662#define F367TER_INT_X3 0xf07b00ff
663
664/* INT_X_2 */
665#define R367TER_INT_X_2 0xf07c
666#define F367TER_INT_X2 0xf07c00ff
667
668/* INT_X_1 */
669#define R367TER_INT_X_1 0xf07d
670#define F367TER_INT_X1 0xf07d00ff
671
672/* INT_X_0 */
673#define R367TER_INT_X_0 0xf07e
674#define F367TER_INT_X0 0xf07e00ff
675
676/* MIN_ERRX_MSB */
677#define R367TER_MIN_ERRX_MSB 0xf07f
678#define F367TER_MIN_ERR_X_MSB 0xf07f00ff
679
680/* COR_CTL */
681#define R367TER_COR_CTL 0xf080
682#define F367TER_CORE_ACTIVE 0xf0800020
683#define F367TER_HOLD 0xf0800010
684#define F367TER_CORE_STATE_CTL 0xf080000f
685
686/* COR_STAT */
687#define R367TER_COR_STAT 0xf081
688#define F367TER_SCATT_LOCKED 0xf0810080
689#define F367TER_TPS_LOCKED 0xf0810040
690#define F367TER_SYR_LOCKED_COR 0xf0810020
691#define F367TER_AGC_LOCKED_STAT 0xf0810010
692#define F367TER_CORE_STATE_STAT 0xf081000f
693
694/* COR_INTEN */
695#define R367TER_COR_INTEN 0xf082
696#define F367TER_INTEN 0xf0820080
697#define F367TER_INTEN_SYR 0xf0820020
698#define F367TER_INTEN_FFT 0xf0820010
699#define F367TER_INTEN_AGC 0xf0820008
700#define F367TER_INTEN_TPS1 0xf0820004
701#define F367TER_INTEN_TPS2 0xf0820002
702#define F367TER_INTEN_TPS3 0xf0820001
703
704/* COR_INTSTAT */
705#define R367TER_COR_INTSTAT 0xf083
706#define F367TER_INTSTAT_SYR 0xf0830020
707#define F367TER_INTSTAT_FFT 0xf0830010
708#define F367TER_INTSAT_AGC 0xf0830008
709#define F367TER_INTSTAT_TPS1 0xf0830004
710#define F367TER_INTSTAT_TPS2 0xf0830002
711#define F367TER_INTSTAT_TPS3 0xf0830001
712
713/* COR_MODEGUARD */
714#define R367TER_COR_MODEGUARD 0xf084
715#define F367TER_FORCE 0xf0840010
716#define F367TER_MODE 0xf084000c
717#define F367TER_GUARD 0xf0840003
718
719/* AGC_CTL */
720#define R367TER_AGC_CTL 0xf085
721#define F367TER_AGC_TIMING_FACTOR 0xf08500e0
722#define F367TER_AGC_LAST 0xf0850010
723#define F367TER_AGC_GAIN 0xf085000c
724#define F367TER_AGC_NEG 0xf0850002
725#define F367TER_AGC_SET 0xf0850001
726
727/* AGC_MANUAL1 */
728#define R367TER_AGC_MANUAL1 0xf086
729#define F367TER_AGC_VAL_LO 0xf08600ff
730
731/* AGC_MANUAL2 */
732#define R367TER_AGC_MANUAL2 0xf087
733#define F367TER_AGC_VAL_HI 0xf087000f
734
735/* AGC_TARG */
736#define R367TER_AGC_TARG 0xf088
737#define F367TER_AGC_TARGET 0xf08800ff
738
739/* AGC_GAIN1 */
740#define R367TER_AGC_GAIN1 0xf089
741#define F367TER_AGC_GAIN_LO 0xf08900ff
742
743/* AGC_GAIN2 */
744#define R367TER_AGC_GAIN2 0xf08a
745#define F367TER_AGC_LOCKED_GAIN2 0xf08a0010
746#define F367TER_AGC_GAIN_HI 0xf08a000f
747
748/* RESERVED_1 */
749#define R367TER_RESERVED_1 0xf08b
750#define F367TER_RESERVED1 0xf08b00ff
751
752/* RESERVED_2 */
753#define R367TER_RESERVED_2 0xf08c
754#define F367TER_RESERVED2 0xf08c00ff
755
756/* RESERVED_3 */
757#define R367TER_RESERVED_3 0xf08d
758#define F367TER_RESERVED3 0xf08d00ff
759
760/* CAS_CTL */
761#define R367TER_CAS_CTL 0xf08e
762#define F367TER_CCS_ENABLE 0xf08e0080
763#define F367TER_ACS_DISABLE 0xf08e0040
764#define F367TER_DAGC_DIS 0xf08e0020
765#define F367TER_DAGC_GAIN 0xf08e0018
766#define F367TER_CCSMU 0xf08e0007
767
768/* CAS_FREQ */
769#define R367TER_CAS_FREQ 0xf08f
770#define F367TER_CCS_FREQ 0xf08f00ff
771
772/* CAS_DAGCGAIN */
773#define R367TER_CAS_DAGCGAIN 0xf090
774#define F367TER_CAS_DAGC_GAIN 0xf09000ff
775
776/* SYR_CTL */
777#define R367TER_SYR_CTL 0xf091
778#define F367TER_SICTH_ENABLE 0xf0910080
779#define F367TER_LONG_ECHO 0xf0910078
780#define F367TER_AUTO_LE_EN 0xf0910004
781#define F367TER_SYR_BYPASS 0xf0910002
782#define F367TER_SYR_TR_DIS 0xf0910001
783
784/* SYR_STAT */
785#define R367TER_SYR_STAT 0xf092
786#define F367TER_SYR_LOCKED_STAT 0xf0920010
787#define F367TER_SYR_MODE 0xf092000c
788#define F367TER_SYR_GUARD 0xf0920003
789
790/* SYR_NCO1 */
791#define R367TER_SYR_NCO1 0xf093
792#define F367TER_SYR_NCO_LO 0xf09300ff
793
794/* SYR_NCO2 */
795#define R367TER_SYR_NCO2 0xf094
796#define F367TER_SYR_NCO_HI 0xf094003f
797
798/* SYR_OFFSET1 */
799#define R367TER_SYR_OFFSET1 0xf095
800#define F367TER_SYR_OFFSET_LO 0xf09500ff
801
802/* SYR_OFFSET2 */
803#define R367TER_SYR_OFFSET2 0xf096
804#define F367TER_SYR_OFFSET_HI 0xf096003f
805
806/* FFT_CTL */
807#define R367TER_FFT_CTL 0xf097
808#define F367TER_SHIFT_FFT_TRIG 0xf0970018
809#define F367TER_FFT_TRIGGER 0xf0970004
810#define F367TER_FFT_MANUAL 0xf0970002
811#define F367TER_IFFT_MODE 0xf0970001
812
813/* SCR_CTL */
814#define R367TER_SCR_CTL 0xf098
815#define F367TER_SYRADJDECAY 0xf0980070
816#define F367TER_SCR_CPEDIS 0xf0980002
817#define F367TER_SCR_DIS 0xf0980001
818
819/* PPM_CTL1 */
820#define R367TER_PPM_CTL1 0xf099
821#define F367TER_PPM_MAXFREQ 0xf0990030
822#define F367TER_PPM_MAXTIM 0xf0990008
823#define F367TER_PPM_INVSEL 0xf0990004
824#define F367TER_PPM_SCATDIS 0xf0990002
825#define F367TER_PPM_BYP 0xf0990001
826
827/* TRL_CTL */
828#define R367TER_TRL_CTL 0xf09a
829#define F367TER_TRL_NOMRATE_LSB 0xf09a0080
830#define F367TER_TRL_GAIN_FACTOR 0xf09a0078
831#define F367TER_TRL_LOOPGAIN 0xf09a0007
832
833/* TRL_NOMRATE1 */
834#define R367TER_TRL_NOMRATE1 0xf09b
835#define F367TER_TRL_NOMRATE_LO 0xf09b00ff
836
837/* TRL_NOMRATE2 */
838#define R367TER_TRL_NOMRATE2 0xf09c
839#define F367TER_TRL_NOMRATE_HI 0xf09c00ff
840
841/* TRL_TIME1 */
842#define R367TER_TRL_TIME1 0xf09d
843#define F367TER_TRL_TOFFSET_LO 0xf09d00ff
844
845/* TRL_TIME2 */
846#define R367TER_TRL_TIME2 0xf09e
847#define F367TER_TRL_TOFFSET_HI 0xf09e00ff
848
849/* CRL_CTL */
850#define R367TER_CRL_CTL 0xf09f
851#define F367TER_CRL_DIS 0xf09f0080
852#define F367TER_CRL_GAIN_FACTOR 0xf09f0078
853#define F367TER_CRL_LOOPGAIN 0xf09f0007
854
855/* CRL_FREQ1 */
856#define R367TER_CRL_FREQ1 0xf0a0
857#define F367TER_CRL_FOFFSET_LO 0xf0a000ff
858
859/* CRL_FREQ2 */
860#define R367TER_CRL_FREQ2 0xf0a1
861#define F367TER_CRL_FOFFSET_HI 0xf0a100ff
862
863/* CRL_FREQ3 */
864#define R367TER_CRL_FREQ3 0xf0a2
865#define F367TER_CRL_FOFFSET_VHI 0xf0a200ff
866
867/* TPS_SFRAME_CTL */
868#define R367TER_TPS_SFRAME_CTL 0xf0a3
869#define F367TER_TPS_SFRAME_SYNC 0xf0a30001
870
871/* CHC_SNR */
872#define R367TER_CHC_SNR 0xf0a4
873#define F367TER_CHCSNR 0xf0a400ff
874
875/* BDI_CTL */
876#define R367TER_BDI_CTL 0xf0a5
877#define F367TER_BDI_LPSEL 0xf0a50002
878#define F367TER_BDI_SERIAL 0xf0a50001
879
880/* DMP_CTL */
881#define R367TER_DMP_CTL 0xf0a6
882#define F367TER_DMP_SCALING_FACTOR 0xf0a6001e
883#define F367TER_DMP_SDDIS 0xf0a60001
884
885/* TPS_RCVD1 */
886#define R367TER_TPS_RCVD1 0xf0a7
887#define F367TER_TPS_CHANGE 0xf0a70040
888#define F367TER_BCH_OK 0xf0a70020
889#define F367TER_TPS_SYNC 0xf0a70010
890#define F367TER_TPS_FRAME 0xf0a70003
891
892/* TPS_RCVD2 */
893#define R367TER_TPS_RCVD2 0xf0a8
894#define F367TER_TPS_HIERMODE 0xf0a80070
895#define F367TER_TPS_CONST 0xf0a80003
896
897/* TPS_RCVD3 */
898#define R367TER_TPS_RCVD3 0xf0a9
899#define F367TER_TPS_LPCODE 0xf0a90070
900#define F367TER_TPS_HPCODE 0xf0a90007
901
902/* TPS_RCVD4 */
903#define R367TER_TPS_RCVD4 0xf0aa
904#define F367TER_TPS_GUARD 0xf0aa0030
905#define F367TER_TPS_MODE 0xf0aa0003
906
907/* TPS_ID_CELL1 */
908#define R367TER_TPS_ID_CELL1 0xf0ab
909#define F367TER_TPS_ID_CELL_LO 0xf0ab00ff
910
911/* TPS_ID_CELL2 */
912#define R367TER_TPS_ID_CELL2 0xf0ac
913#define F367TER_TPS_ID_CELL_HI 0xf0ac00ff
914
915/* TPS_RCVD5_SET1 */
916#define R367TER_TPS_RCVD5_SET1 0xf0ad
917#define F367TER_TPS_NA 0xf0ad00fC
918#define F367TER_TPS_SETFRAME 0xf0ad0003
919
920/* TPS_SET2 */
921#define R367TER_TPS_SET2 0xf0ae
922#define F367TER_TPS_SETHIERMODE 0xf0ae0070
923#define F367TER_TPS_SETCONST 0xf0ae0003
924
925/* TPS_SET3 */
926#define R367TER_TPS_SET3 0xf0af
927#define F367TER_TPS_SETLPCODE 0xf0af0070
928#define F367TER_TPS_SETHPCODE 0xf0af0007
929
930/* TPS_CTL */
931#define R367TER_TPS_CTL 0xf0b0
932#define F367TER_TPS_IMM 0xf0b00004
933#define F367TER_TPS_BCHDIS 0xf0b00002
934#define F367TER_TPS_UPDDIS 0xf0b00001
935
936/* CTL_FFTOSNUM */
937#define R367TER_CTL_FFTOSNUM 0xf0b1
938#define F367TER_SYMBOL_NUMBER 0xf0b1007f
939
940/* TESTSELECT */
941#define R367TER_TESTSELECT 0xf0b2
942#define F367TER_TEST_SELECT 0xf0b2001f
943
944/* MSC_REV */
945#define R367TER_MSC_REV 0xf0b3
946#define F367TER_REV_NUMBER 0xf0b300ff
947
948/* PIR_CTL */
949#define R367TER_PIR_CTL 0xf0b4
950#define F367TER_FREEZE 0xf0b40001
951
952/* SNR_CARRIER1 */
953#define R367TER_SNR_CARRIER1 0xf0b5
954#define F367TER_SNR_CARRIER_LO 0xf0b500ff
955
956/* SNR_CARRIER2 */
957#define R367TER_SNR_CARRIER2 0xf0b6
958#define F367TER_MEAN 0xf0b600c0
959#define F367TER_SNR_CARRIER_HI 0xf0b6001f
960
961/* PPM_CPAMP */
962#define R367TER_PPM_CPAMP 0xf0b7
963#define F367TER_PPM_CPC 0xf0b700ff
964
965/* TSM_AP0 */
966#define R367TER_TSM_AP0 0xf0b8
967#define F367TER_ADDRESS_BYTE_0 0xf0b800ff
968
969/* TSM_AP1 */
970#define R367TER_TSM_AP1 0xf0b9
971#define F367TER_ADDRESS_BYTE_1 0xf0b900ff
972
973/* TSM_AP2 */
974#define R367TER_TSM_AP2 0xf0bA
975#define F367TER_DATA_BYTE_0 0xf0ba00ff
976
977/* TSM_AP3 */
978#define R367TER_TSM_AP3 0xf0bB
979#define F367TER_DATA_BYTE_1 0xf0bb00ff
980
981/* TSM_AP4 */
982#define R367TER_TSM_AP4 0xf0bC
983#define F367TER_DATA_BYTE_2 0xf0bc00ff
984
985/* TSM_AP5 */
986#define R367TER_TSM_AP5 0xf0bD
987#define F367TER_DATA_BYTE_3 0xf0bd00ff
988
989/* TSM_AP6 */
990#define R367TER_TSM_AP6 0xf0bE
991#define F367TER_TSM_AP_6 0xf0be00ff
992
993/* TSM_AP7 */
994#define R367TER_TSM_AP7 0xf0bF
995#define F367TER_MEM_SELECT_BYTE 0xf0bf00ff
996
997/* TSTRES */
998#define R367TER_TSTRES 0xf0c0
999#define F367TER_FRES_DISPLAY 0xf0c00080
1000#define F367TER_FRES_FIFO_AD 0xf0c00020
1001#define F367TER_FRESRS 0xf0c00010
1002#define F367TER_FRESACS 0xf0c00008
1003#define F367TER_FRESFEC 0xf0c00004
1004#define F367TER_FRES_PRIF 0xf0c00002
1005#define F367TER_FRESCORE 0xf0c00001
1006
1007/* ANACTRL */
1008#define R367TER_ANACTRL 0xf0c1
1009#define F367TER_BYPASS_XTAL 0xf0c10040
1010#define F367TER_BYPASS_PLLXN 0xf0c1000c
1011#define F367TER_DIS_PAD_OSC 0xf0c10002
1012#define F367TER_STDBY_PLLXN 0xf0c10001
1013
1014/* TSTBUS */
1015#define R367TER_TSTBUS 0xf0c2
1016#define F367TER_TS_BYTE_CLK_INV 0xf0c20080
1017#define F367TER_CFG_IP 0xf0c20070
1018#define F367TER_CFG_TST 0xf0c2000f
1019
1020/* TSTRATE */
1021#define R367TER_TSTRATE 0xf0c6
1022#define F367TER_FORCEPHA 0xf0c60080
1023#define F367TER_FNEWPHA 0xf0c60010
1024#define F367TER_FROT90 0xf0c60008
1025#define F367TER_FR 0xf0c60007
1026
1027/* CONSTMODE */
1028#define R367TER_CONSTMODE 0xf0cb
1029#define F367TER_TST_PRIF 0xf0cb00e0
1030#define F367TER_CAR_TYPE 0xf0cb0018
1031#define F367TER_CONST_MODE 0xf0cb0003
1032
1033/* CONSTCARR1 */
1034#define R367TER_CONSTCARR1 0xf0cc
1035#define F367TER_CONST_CARR_LO 0xf0cc00ff
1036
1037/* CONSTCARR2 */
1038#define R367TER_CONSTCARR2 0xf0cd
1039#define F367TER_CONST_CARR_HI 0xf0cd001f
1040
1041/* ICONSTEL */
1042#define R367TER_ICONSTEL 0xf0ce
1043#define F367TER_PICONSTEL 0xf0ce00ff
1044
1045/* QCONSTEL */
1046#define R367TER_QCONSTEL 0xf0cf
1047#define F367TER_PQCONSTEL 0xf0cf00ff
1048
1049/* TSTBISTRES0 */
1050#define R367TER_TSTBISTRES0 0xf0d0
1051#define F367TER_BEND_PPM 0xf0d00080
1052#define F367TER_BBAD_PPM 0xf0d00040
1053#define F367TER_BEND_FFTW 0xf0d00020
1054#define F367TER_BBAD_FFTW 0xf0d00010
1055#define F367TER_BEND_FFT_BUF 0xf0d00008
1056#define F367TER_BBAD_FFT_BUF 0xf0d00004
1057#define F367TER_BEND_SYR 0xf0d00002
1058#define F367TER_BBAD_SYR 0xf0d00001
1059
1060/* TSTBISTRES1 */
1061#define R367TER_TSTBISTRES1 0xf0d1
1062#define F367TER_BEND_CHC_CP 0xf0d10080
1063#define F367TER_BBAD_CHC_CP 0xf0d10040
1064#define F367TER_BEND_CHCI 0xf0d10020
1065#define F367TER_BBAD_CHCI 0xf0d10010
1066#define F367TER_BEND_BDI 0xf0d10008
1067#define F367TER_BBAD_BDI 0xf0d10004
1068#define F367TER_BEND_SDI 0xf0d10002
1069#define F367TER_BBAD_SDI 0xf0d10001
1070
1071/* TSTBISTRES2 */
1072#define R367TER_TSTBISTRES2 0xf0d2
1073#define F367TER_BEND_CHC_INC 0xf0d20080
1074#define F367TER_BBAD_CHC_INC 0xf0d20040
1075#define F367TER_BEND_CHC_SPP 0xf0d20020
1076#define F367TER_BBAD_CHC_SPP 0xf0d20010
1077#define F367TER_BEND_CHC_CPP 0xf0d20008
1078#define F367TER_BBAD_CHC_CPP 0xf0d20004
1079#define F367TER_BEND_CHC_SP 0xf0d20002
1080#define F367TER_BBAD_CHC_SP 0xf0d20001
1081
1082/* TSTBISTRES3 */
1083#define R367TER_TSTBISTRES3 0xf0d3
1084#define F367TER_BEND_QAM 0xf0d30080
1085#define F367TER_BBAD_QAM 0xf0d30040
1086#define F367TER_BEND_SFEC_VIT 0xf0d30020
1087#define F367TER_BBAD_SFEC_VIT 0xf0d30010
1088#define F367TER_BEND_SFEC_DLINE 0xf0d30008
1089#define F367TER_BBAD_SFEC_DLINE 0xf0d30004
1090#define F367TER_BEND_SFEC_HW 0xf0d30002
1091#define F367TER_BBAD_SFEC_HW 0xf0d30001
1092
1093/* RF_AGC1 */
1094#define R367TER_RF_AGC1 0xf0d4
1095#define F367TER_RF_AGC1_LEVEL_HI 0xf0d400ff
1096
1097/* RF_AGC2 */
1098#define R367TER_RF_AGC2 0xf0d5
1099#define F367TER_REF_ADGP 0xf0d50080
1100#define F367TER_STDBY_ADCGP 0xf0d50020
1101#define F367TER_CHANNEL_SEL 0xf0d5001c
1102#define F367TER_RF_AGC1_LEVEL_LO 0xf0d50003
1103
1104/* ANADIGCTRL */
1105#define R367TER_ANADIGCTRL 0xf0d7
1106#define F367TER_SEL_CLKDEM 0xf0d70020
1107#define F367TER_EN_BUFFER_Q 0xf0d70010
1108#define F367TER_EN_BUFFER_I 0xf0d70008
1109#define F367TER_ADC_RIS_EGDE 0xf0d70004
1110#define F367TER_SGN_ADC 0xf0d70002
1111#define F367TER_SEL_AD12_SYNC 0xf0d70001
1112
1113/* PLLMDIV */
1114#define R367TER_PLLMDIV 0xf0d8
1115#define F367TER_PLL_MDIV 0xf0d800ff
1116
1117/* PLLNDIV */
1118#define R367TER_PLLNDIV 0xf0d9
1119#define F367TER_PLL_NDIV 0xf0d900ff
1120
1121/* PLLSETUP */
1122#define R367TER_PLLSETUP 0xf0dA
1123#define F367TER_PLL_PDIV 0xf0da0070
1124#define F367TER_PLL_KDIV 0xf0da000f
1125
1126/* DUAL_AD12 */
1127#define R367TER_DUAL_AD12 0xf0dB
1128#define F367TER_FS20M 0xf0db0020
1129#define F367TER_FS50M 0xf0db0010
1130#define F367TER_INMODe0 0xf0db0008
1131#define F367TER_POFFQ 0xf0db0004
1132#define F367TER_POFFI 0xf0db0002
1133#define F367TER_INMODE1 0xf0db0001
1134
1135/* TSTBIST */
1136#define R367TER_TSTBIST 0xf0dC
1137#define F367TER_TST_BYP_CLK 0xf0dc0080
1138#define F367TER_TST_GCLKENA_STD 0xf0dc0040
1139#define F367TER_TST_GCLKENA 0xf0dc0020
1140#define F367TER_TST_MEMBIST 0xf0dc001f
1141
1142/* PAD_COMP_CTRL */
1143#define R367TER_PAD_COMP_CTRL 0xf0dD
1144#define F367TER_COMPTQ 0xf0dd0010
1145#define F367TER_COMPEN 0xf0dd0008
1146#define F367TER_FREEZE2 0xf0dd0004
1147#define F367TER_SLEEP_INHBT 0xf0dd0002
1148#define F367TER_CHIP_SLEEP 0xf0dd0001
1149
1150/* PAD_COMP_WR */
1151#define R367TER_PAD_COMP_WR 0xf0de
1152#define F367TER_WR_ASRC 0xf0de007f
1153
1154/* PAD_COMP_RD */
1155#define R367TER_PAD_COMP_RD 0xf0df
1156#define F367TER_COMPOK 0xf0df0080
1157#define F367TER_RD_ASRC 0xf0df007f
1158
1159/* SYR_TARGET_FFTADJT_MSB */
1160#define R367TER_SYR_TARGET_FFTADJT_MSB 0xf100
1161#define F367TER_SYR_START 0xf1000080
1162#define F367TER_SYR_TARGET_FFTADJ_HI 0xf100000f
1163
1164/* SYR_TARGET_FFTADJT_LSB */
1165#define R367TER_SYR_TARGET_FFTADJT_LSB 0xf101
1166#define F367TER_SYR_TARGET_FFTADJ_LO 0xf10100ff
1167
1168/* SYR_TARGET_CHCADJT_MSB */
1169#define R367TER_SYR_TARGET_CHCADJT_MSB 0xf102
1170#define F367TER_SYR_TARGET_CHCADJ_HI 0xf102000f
1171
1172/* SYR_TARGET_CHCADJT_LSB */
1173#define R367TER_SYR_TARGET_CHCADJT_LSB 0xf103
1174#define F367TER_SYR_TARGET_CHCADJ_LO 0xf10300ff
1175
1176/* SYR_FLAG */
1177#define R367TER_SYR_FLAG 0xf104
1178#define F367TER_TRIG_FLG1 0xf1040080
1179#define F367TER_TRIG_FLG0 0xf1040040
1180#define F367TER_FFT_FLG1 0xf1040008
1181#define F367TER_FFT_FLG0 0xf1040004
1182#define F367TER_CHC_FLG1 0xf1040002
1183#define F367TER_CHC_FLG0 0xf1040001
1184
1185/* CRL_TARGET1 */
1186#define R367TER_CRL_TARGET1 0xf105
1187#define F367TER_CRL_START 0xf1050080
1188#define F367TER_CRL_TARGET_VHI 0xf105000f
1189
1190/* CRL_TARGET2 */
1191#define R367TER_CRL_TARGET2 0xf106
1192#define F367TER_CRL_TARGET_HI 0xf10600ff
1193
1194/* CRL_TARGET3 */
1195#define R367TER_CRL_TARGET3 0xf107
1196#define F367TER_CRL_TARGET_LO 0xf10700ff
1197
1198/* CRL_TARGET4 */
1199#define R367TER_CRL_TARGET4 0xf108
1200#define F367TER_CRL_TARGET_VLO 0xf10800ff
1201
1202/* CRL_FLAG */
1203#define R367TER_CRL_FLAG 0xf109
1204#define F367TER_CRL_FLAG1 0xf1090002
1205#define F367TER_CRL_FLAG0 0xf1090001
1206
1207/* TRL_TARGET1 */
1208#define R367TER_TRL_TARGET1 0xf10a
1209#define F367TER_TRL_TARGET_HI 0xf10a00ff
1210
1211/* TRL_TARGET2 */
1212#define R367TER_TRL_TARGET2 0xf10b
1213#define F367TER_TRL_TARGET_LO 0xf10b00ff
1214
1215/* TRL_CHC */
1216#define R367TER_TRL_CHC 0xf10c
1217#define F367TER_TRL_START 0xf10c0080
1218#define F367TER_CHC_START 0xf10c0040
1219#define F367TER_TRL_FLAG1 0xf10c0002
1220#define F367TER_TRL_FLAG0 0xf10c0001
1221
1222/* CHC_SNR_TARG */
1223#define R367TER_CHC_SNR_TARG 0xf10d
1224#define F367TER_CHC_SNR_TARGET 0xf10d00ff
1225
1226/* TOP_TRACK */
1227#define R367TER_TOP_TRACK 0xf10e
1228#define F367TER_TOP_START 0xf10e0080
1229#define F367TER_FIRST_FLAG 0xf10e0070
1230#define F367TER_TOP_FLAG1 0xf10e0008
1231#define F367TER_TOP_FLAG0 0xf10e0004
1232#define F367TER_CHC_FLAG1 0xf10e0002
1233#define F367TER_CHC_FLAG0 0xf10e0001
1234
1235/* TRACKER_FREE1 */
1236#define R367TER_TRACKER_FREE1 0xf10f
1237#define F367TER_TRACKER_FREE_1 0xf10f00ff
1238
1239/* ERROR_CRL1 */
1240#define R367TER_ERROR_CRL1 0xf110
1241#define F367TER_ERROR_CRL_VHI 0xf11000ff
1242
1243/* ERROR_CRL2 */
1244#define R367TER_ERROR_CRL2 0xf111
1245#define F367TER_ERROR_CRL_HI 0xf11100ff
1246
1247/* ERROR_CRL3 */
1248#define R367TER_ERROR_CRL3 0xf112
1249#define F367TER_ERROR_CRL_LOI 0xf11200ff
1250
1251/* ERROR_CRL4 */
1252#define R367TER_ERROR_CRL4 0xf113
1253#define F367TER_ERROR_CRL_VLO 0xf11300ff
1254
1255/* DEC_NCO1 */
1256#define R367TER_DEC_NCO1 0xf114
1257#define F367TER_DEC_NCO_VHI 0xf11400ff
1258
1259/* DEC_NCO2 */
1260#define R367TER_DEC_NCO2 0xf115
1261#define F367TER_DEC_NCO_HI 0xf11500ff
1262
1263/* DEC_NCO3 */
1264#define R367TER_DEC_NCO3 0xf116
1265#define F367TER_DEC_NCO_LO 0xf11600ff
1266
1267/* SNR */
1268#define R367TER_SNR 0xf117
1269#define F367TER_SNRATIO 0xf11700ff
1270
1271/* SYR_FFTADJ1 */
1272#define R367TER_SYR_FFTADJ1 0xf118
1273#define F367TER_SYR_FFTADJ_HI 0xf11800ff
1274
1275/* SYR_FFTADJ2 */
1276#define R367TER_SYR_FFTADJ2 0xf119
1277#define F367TER_SYR_FFTADJ_LO 0xf11900ff
1278
1279/* SYR_CHCADJ1 */
1280#define R367TER_SYR_CHCADJ1 0xf11a
1281#define F367TER_SYR_CHCADJ_HI 0xf11a00ff
1282
1283/* SYR_CHCADJ2 */
1284#define R367TER_SYR_CHCADJ2 0xf11b
1285#define F367TER_SYR_CHCADJ_LO 0xf11b00ff
1286
1287/* SYR_OFF */
1288#define R367TER_SYR_OFF 0xf11c
1289#define F367TER_SYR_OFFSET 0xf11c00ff
1290
1291/* PPM_OFFSET1 */
1292#define R367TER_PPM_OFFSET1 0xf11d
1293#define F367TER_PPM_OFFSET_HI 0xf11d00ff
1294
1295/* PPM_OFFSET2 */
1296#define R367TER_PPM_OFFSET2 0xf11e
1297#define F367TER_PPM_OFFSET_LO 0xf11e00ff
1298
1299/* TRACKER_FREE2 */
1300#define R367TER_TRACKER_FREE2 0xf11f
1301#define F367TER_TRACKER_FREE_2 0xf11f00ff
1302
1303/* DEBG_LT10 */
1304#define R367TER_DEBG_LT10 0xf120
1305#define F367TER_DEBUG_LT10 0xf12000ff
1306
1307/* DEBG_LT11 */
1308#define R367TER_DEBG_LT11 0xf121
1309#define F367TER_DEBUG_LT11 0xf12100ff
1310
1311/* DEBG_LT12 */
1312#define R367TER_DEBG_LT12 0xf122
1313#define F367TER_DEBUG_LT12 0xf12200ff
1314
1315/* DEBG_LT13 */
1316#define R367TER_DEBG_LT13 0xf123
1317#define F367TER_DEBUG_LT13 0xf12300ff
1318
1319/* DEBG_LT14 */
1320#define R367TER_DEBG_LT14 0xf124
1321#define F367TER_DEBUG_LT14 0xf12400ff
1322
1323/* DEBG_LT15 */
1324#define R367TER_DEBG_LT15 0xf125
1325#define F367TER_DEBUG_LT15 0xf12500ff
1326
1327/* DEBG_LT16 */
1328#define R367TER_DEBG_LT16 0xf126
1329#define F367TER_DEBUG_LT16 0xf12600ff
1330
1331/* DEBG_LT17 */
1332#define R367TER_DEBG_LT17 0xf127
1333#define F367TER_DEBUG_LT17 0xf12700ff
1334
1335/* DEBG_LT18 */
1336#define R367TER_DEBG_LT18 0xf128
1337#define F367TER_DEBUG_LT18 0xf12800ff
1338
1339/* DEBG_LT19 */
1340#define R367TER_DEBG_LT19 0xf129
1341#define F367TER_DEBUG_LT19 0xf12900ff
1342
1343/* DEBG_LT1a */
1344#define R367TER_DEBG_LT1A 0xf12a
1345#define F367TER_DEBUG_LT1A 0xf12a00ff
1346
1347/* DEBG_LT1b */
1348#define R367TER_DEBG_LT1B 0xf12b
1349#define F367TER_DEBUG_LT1B 0xf12b00ff
1350
1351/* DEBG_LT1c */
1352#define R367TER_DEBG_LT1C 0xf12c
1353#define F367TER_DEBUG_LT1C 0xf12c00ff
1354
1355/* DEBG_LT1D */
1356#define R367TER_DEBG_LT1D 0xf12d
1357#define F367TER_DEBUG_LT1D 0xf12d00ff
1358
1359/* DEBG_LT1E */
1360#define R367TER_DEBG_LT1E 0xf12e
1361#define F367TER_DEBUG_LT1E 0xf12e00ff
1362
1363/* DEBG_LT1F */
1364#define R367TER_DEBG_LT1F 0xf12f
1365#define F367TER_DEBUG_LT1F 0xf12f00ff
1366
1367/* RCCFGH */
1368#define R367TER_RCCFGH 0xf200
1369#define F367TER_TSRCFIFO_DVBCI 0xf2000080
1370#define F367TER_TSRCFIFO_SERIAL 0xf2000040
1371#define F367TER_TSRCFIFO_DISABLE 0xf2000020
1372#define F367TER_TSFIFO_2TORC 0xf2000010
1373#define F367TER_TSRCFIFO_HSGNLOUT 0xf2000008
1374#define F367TER_TSRCFIFO_ERRMODE 0xf2000006
1375#define F367TER_RCCFGH_0 0xf2000001
1376
1377/* RCCFGM */
1378#define R367TER_RCCFGM 0xf201
1379#define F367TER_TSRCFIFO_MANSPEED 0xf20100c0
1380#define F367TER_TSRCFIFO_PERMDATA 0xf2010020
1381#define F367TER_TSRCFIFO_NONEWSGNL 0xf2010010
1382#define F367TER_RCBYTE_OVERSAMPLING 0xf201000e
1383#define F367TER_TSRCFIFO_INVDATA 0xf2010001
1384
1385/* RCCFGL */
1386#define R367TER_RCCFGL 0xf202
1387#define F367TER_TSRCFIFO_BCLKDEL1cK 0xf20200c0
1388#define F367TER_RCCFGL_5 0xf2020020
1389#define F367TER_TSRCFIFO_DUTY50 0xf2020010
1390#define F367TER_TSRCFIFO_NSGNL2dATA 0xf2020008
1391#define F367TER_TSRCFIFO_DISSERMUX 0xf2020004
1392#define F367TER_RCCFGL_1 0xf2020002
1393#define F367TER_TSRCFIFO_STOPCKDIS 0xf2020001
1394
1395/* RCINSDELH */
1396#define R367TER_RCINSDELH 0xf203
1397#define F367TER_TSRCDEL_SYNCBYTE 0xf2030080
1398#define F367TER_TSRCDEL_XXHEADER 0xf2030040
1399#define F367TER_TSRCDEL_BBHEADER 0xf2030020
1400#define F367TER_TSRCDEL_DATAFIELD 0xf2030010
1401#define F367TER_TSRCINSDEL_ISCR 0xf2030008
1402#define F367TER_TSRCINSDEL_NPD 0xf2030004
1403#define F367TER_TSRCINSDEL_RSPARITY 0xf2030002
1404#define F367TER_TSRCINSDEL_CRC8 0xf2030001
1405
1406/* RCINSDELM */
1407#define R367TER_RCINSDELM 0xf204
1408#define F367TER_TSRCINS_BBPADDING 0xf2040080
1409#define F367TER_TSRCINS_BCHFEC 0xf2040040
1410#define F367TER_TSRCINS_LDPCFEC 0xf2040020
1411#define F367TER_TSRCINS_EMODCOD 0xf2040010
1412#define F367TER_TSRCINS_TOKEN 0xf2040008
1413#define F367TER_TSRCINS_XXXERR 0xf2040004
1414#define F367TER_TSRCINS_MATYPE 0xf2040002
1415#define F367TER_TSRCINS_UPL 0xf2040001
1416
1417/* RCINSDELL */
1418#define R367TER_RCINSDELL 0xf205
1419#define F367TER_TSRCINS_DFL 0xf2050080
1420#define F367TER_TSRCINS_SYNCD 0xf2050040
1421#define F367TER_TSRCINS_BLOCLEN 0xf2050020
1422#define F367TER_TSRCINS_SIGPCOUNT 0xf2050010
1423#define F367TER_TSRCINS_FIFO 0xf2050008
1424#define F367TER_TSRCINS_REALPACK 0xf2050004
1425#define F367TER_TSRCINS_TSCONFIG 0xf2050002
1426#define F367TER_TSRCINS_LATENCY 0xf2050001
1427
1428/* RCSTATUS */
1429#define R367TER_RCSTATUS 0xf206
1430#define F367TER_TSRCFIFO_LINEOK 0xf2060080
1431#define F367TER_TSRCFIFO_ERROR 0xf2060040
1432#define F367TER_TSRCFIFO_DATA7 0xf2060020
1433#define F367TER_RCSTATUS_4 0xf2060010
1434#define F367TER_TSRCFIFO_DEMODSEL 0xf2060008
1435#define F367TER_TSRC1FIFOSPEED_STORE 0xf2060004
1436#define F367TER_RCSTATUS_1 0xf2060002
1437#define F367TER_TSRCSERIAL_IMPOSSIBLE 0xf2060001
1438
1439/* RCSPEED */
1440#define R367TER_RCSPEED 0xf207
1441#define F367TER_TSRCFIFO_OUTSPEED 0xf20700ff
1442
1443/* RCDEBUGM */
1444#define R367TER_RCDEBUGM 0xf208
1445#define F367TER_SD_UNSYNC 0xf2080080
1446#define F367TER_ULFLOCK_DETECTM 0xf2080040
1447#define F367TER_SUL_SELECTOS 0xf2080020
1448#define F367TER_DILUL_NOSCRBLE 0xf2080010
1449#define F367TER_NUL_SCRB 0xf2080008
1450#define F367TER_UL_SCRB 0xf2080004
1451#define F367TER_SCRAULBAD 0xf2080002
1452#define F367TER_SCRAUL_UNSYNC 0xf2080001
1453
1454/* RCDEBUGL */
1455#define R367TER_RCDEBUGL 0xf209
1456#define F367TER_RS_ERR 0xf2090080
1457#define F367TER_LLFLOCK_DETECTM 0xf2090040
1458#define F367TER_NOT_SUL_SELECTOS 0xf2090020
1459#define F367TER_DILLL_NOSCRBLE 0xf2090010
1460#define F367TER_NLL_SCRB 0xf2090008
1461#define F367TER_LL_SCRB 0xf2090004
1462#define F367TER_SCRALLBAD 0xf2090002
1463#define F367TER_SCRALL_UNSYNC 0xf2090001
1464
1465/* RCOBSCFG */
1466#define R367TER_RCOBSCFG 0xf20a
1467#define F367TER_TSRCFIFO_OBSCFG 0xf20a00ff
1468
1469/* RCOBSM */
1470#define R367TER_RCOBSM 0xf20b
1471#define F367TER_TSRCFIFO_OBSDATA_HI 0xf20b00ff
1472
1473/* RCOBSL */
1474#define R367TER_RCOBSL 0xf20c
1475#define F367TER_TSRCFIFO_OBSDATA_LO 0xf20c00ff
1476
1477/* RCFECSPY */
1478#define R367TER_RCFECSPY 0xf210
1479#define F367TER_SPYRC_ENABLE 0xf2100080
1480#define F367TER_RCNO_SYNCBYTE 0xf2100040
1481#define F367TER_RCSERIAL_MODE 0xf2100020
1482#define F367TER_RCUNUSUAL_PACKET 0xf2100010
1483#define F367TER_BERRCMETER_DATAMODE 0xf210000c
1484#define F367TER_BERRCMETER_LMODE 0xf2100002
1485#define F367TER_BERRCMETER_RESET 0xf2100001
1486
1487/* RCFSPYCFG */
1488#define R367TER_RCFSPYCFG 0xf211
1489#define F367TER_FECSPYRC_INPUT 0xf21100c0
1490#define F367TER_RCRST_ON_ERROR 0xf2110020
1491#define F367TER_RCONE_SHOT 0xf2110010
1492#define F367TER_RCI2C_MODE 0xf211000c
1493#define F367TER_SPYRC_HSTERESIS 0xf2110003
1494
1495/* RCFSPYDATA */
1496#define R367TER_RCFSPYDATA 0xf212
1497#define F367TER_SPYRC_STUFFING 0xf2120080
1498#define F367TER_RCNOERR_PKTJITTER 0xf2120040
1499#define F367TER_SPYRC_CNULLPKT 0xf2120020
1500#define F367TER_SPYRC_OUTDATA_MODE 0xf212001f
1501
1502/* RCFSPYOUT */
1503#define R367TER_RCFSPYOUT 0xf213
1504#define F367TER_FSPYRC_DIRECT 0xf2130080
1505#define F367TER_RCFSPYOUT_6 0xf2130040
1506#define F367TER_SPYRC_OUTDATA_BUS 0xf2130038
1507#define F367TER_RCSTUFF_MODE 0xf2130007
1508
1509/* RCFSTATUS */
1510#define R367TER_RCFSTATUS 0xf214
1511#define F367TER_SPYRC_ENDSIM 0xf2140080
1512#define F367TER_RCVALID_SIM 0xf2140040
1513#define F367TER_RCFOUND_SIGNAL 0xf2140020
1514#define F367TER_RCDSS_SYNCBYTE 0xf2140010
1515#define F367TER_RCRESULT_STATE 0xf214000f
1516
1517/* RCFGOODPACK */
1518#define R367TER_RCFGOODPACK 0xf215
1519#define F367TER_RCGOOD_PACKET 0xf21500ff
1520
1521/* RCFPACKCNT */
1522#define R367TER_RCFPACKCNT 0xf216
1523#define F367TER_RCPACKET_COUNTER 0xf21600ff
1524
1525/* RCFSPYMISC */
1526#define R367TER_RCFSPYMISC 0xf217
1527#define F367TER_RCLABEL_COUNTER 0xf21700ff
1528
1529/* RCFBERCPT4 */
1530#define R367TER_RCFBERCPT4 0xf218
1531#define F367TER_FBERRCMETER_CPT_MMMMSB 0xf21800ff
1532
1533/* RCFBERCPT3 */
1534#define R367TER_RCFBERCPT3 0xf219
1535#define F367TER_FBERRCMETER_CPT_MMMSB 0xf21900ff
1536
1537/* RCFBERCPT2 */
1538#define R367TER_RCFBERCPT2 0xf21a
1539#define F367TER_FBERRCMETER_CPT_MMSB 0xf21a00ff
1540
1541/* RCFBERCPT1 */
1542#define R367TER_RCFBERCPT1 0xf21b
1543#define F367TER_FBERRCMETER_CPT_MSB 0xf21b00ff
1544
1545/* RCFBERCPT0 */
1546#define R367TER_RCFBERCPT0 0xf21c
1547#define F367TER_FBERRCMETER_CPT_LSB 0xf21c00ff
1548
1549/* RCFBERERR2 */
1550#define R367TER_RCFBERERR2 0xf21d
1551#define F367TER_FBERRCMETER_ERR_HI 0xf21d00ff
1552
1553/* RCFBERERR1 */
1554#define R367TER_RCFBERERR1 0xf21e
1555#define F367TER_FBERRCMETER_ERR 0xf21e00ff
1556
1557/* RCFBERERR0 */
1558#define R367TER_RCFBERERR0 0xf21f
1559#define F367TER_FBERRCMETER_ERR_LO 0xf21f00ff
1560
1561/* RCFSTATESM */
1562#define R367TER_RCFSTATESM 0xf220
1563#define F367TER_RCRSTATE_F 0xf2200080
1564#define F367TER_RCRSTATE_E 0xf2200040
1565#define F367TER_RCRSTATE_D 0xf2200020
1566#define F367TER_RCRSTATE_C 0xf2200010
1567#define F367TER_RCRSTATE_B 0xf2200008
1568#define F367TER_RCRSTATE_A 0xf2200004
1569#define F367TER_RCRSTATE_9 0xf2200002
1570#define F367TER_RCRSTATE_8 0xf2200001
1571
1572/* RCFSTATESL */
1573#define R367TER_RCFSTATESL 0xf221
1574#define F367TER_RCRSTATE_7 0xf2210080
1575#define F367TER_RCRSTATE_6 0xf2210040
1576#define F367TER_RCRSTATE_5 0xf2210020
1577#define F367TER_RCRSTATE_4 0xf2210010
1578#define F367TER_RCRSTATE_3 0xf2210008
1579#define F367TER_RCRSTATE_2 0xf2210004
1580#define F367TER_RCRSTATE_1 0xf2210002
1581#define F367TER_RCRSTATE_0 0xf2210001
1582
1583/* RCFSPYBER */
1584#define R367TER_RCFSPYBER 0xf222
1585#define F367TER_RCFSPYBER_7 0xf2220080
1586#define F367TER_SPYRCOBS_XORREAD 0xf2220040
1587#define F367TER_FSPYRCBER_OBSMODE 0xf2220020
1588#define F367TER_FSPYRCBER_SYNCBYT 0xf2220010
1589#define F367TER_FSPYRCBER_UNSYNC 0xf2220008
1590#define F367TER_FSPYRCBER_CTIME 0xf2220007
1591
1592/* RCFSPYDISTM */
1593#define R367TER_RCFSPYDISTM 0xf223
1594#define F367TER_RCPKTTIME_DISTANCE_HI 0xf22300ff
1595
1596/* RCFSPYDISTL */
1597#define R367TER_RCFSPYDISTL 0xf224
1598#define F367TER_RCPKTTIME_DISTANCE_LO 0xf22400ff
1599
1600/* RCFSPYOBS7 */
1601#define R367TER_RCFSPYOBS7 0xf228
1602#define F367TER_RCSPYOBS_SPYFAIL 0xf2280080
1603#define F367TER_RCSPYOBS_SPYFAIL1 0xf2280040
1604#define F367TER_RCSPYOBS_ERROR 0xf2280020
1605#define F367TER_RCSPYOBS_STROUT 0xf2280010
1606#define F367TER_RCSPYOBS_RESULTSTATE1 0xf228000f
1607
1608/* RCFSPYOBS6 */
1609#define R367TER_RCFSPYOBS6 0xf229
1610#define F367TER_RCSPYOBS_RESULTSTATe0 0xf22900f0
1611#define F367TER_RCSPYOBS_RESULTSTATEM1 0xf229000f
1612
1613/* RCFSPYOBS5 */
1614#define R367TER_RCFSPYOBS5 0xf22a
1615#define F367TER_RCSPYOBS_BYTEOFPACKET1 0xf22a00ff
1616
1617/* RCFSPYOBS4 */
1618#define R367TER_RCFSPYOBS4 0xf22b
1619#define F367TER_RCSPYOBS_BYTEVALUE1 0xf22b00ff
1620
1621/* RCFSPYOBS3 */
1622#define R367TER_RCFSPYOBS3 0xf22c
1623#define F367TER_RCSPYOBS_DATA1 0xf22c00ff
1624
1625/* RCFSPYOBS2 */
1626#define R367TER_RCFSPYOBS2 0xf22d
1627#define F367TER_RCSPYOBS_DATa0 0xf22d00ff
1628
1629/* RCFSPYOBS1 */
1630#define R367TER_RCFSPYOBS1 0xf22e
1631#define F367TER_RCSPYOBS_DATAM1 0xf22e00ff
1632
1633/* RCFSPYOBS0 */
1634#define R367TER_RCFSPYOBS0 0xf22f
1635#define F367TER_RCSPYOBS_DATAM2 0xf22f00ff
1636
1637/* TSGENERAL */
1638#define R367TER_TSGENERAL 0xf230
1639#define F367TER_TSGENERAL_7 0xf2300080
1640#define F367TER_TSGENERAL_6 0xf2300040
1641#define F367TER_TSFIFO_BCLK1aLL 0xf2300020
1642#define F367TER_TSGENERAL_4 0xf2300010
1643#define F367TER_MUXSTREAM_OUTMODE 0xf2300008
1644#define F367TER_TSFIFO_PERMPARAL 0xf2300006
1645#define F367TER_RST_REEDSOLO 0xf2300001
1646
1647/* RC1SPEED */
1648#define R367TER_RC1SPEED 0xf231
1649#define F367TER_TSRCFIFO1_OUTSPEED 0xf23100ff
1650
1651/* TSGSTATUS */
1652#define R367TER_TSGSTATUS 0xf232
1653#define F367TER_TSGSTATUS_7 0xf2320080
1654#define F367TER_TSGSTATUS_6 0xf2320040
1655#define F367TER_RSMEM_FULL 0xf2320020
1656#define F367TER_RS_MULTCALC 0xf2320010
1657#define F367TER_RSIN_OVERTIME 0xf2320008
1658#define F367TER_TSFIFO3_DEMODSEL 0xf2320004
1659#define F367TER_TSFIFO2_DEMODSEL 0xf2320002
1660#define F367TER_TSFIFO1_DEMODSEL 0xf2320001
1661
1662
1663/* FECM */
1664#define R367TER_FECM 0xf233
1665#define F367TER_DSS_DVB 0xf2330080
1666#define F367TER_DEMOD_BYPASS 0xf2330040
1667#define F367TER_CMP_SLOWMODE 0xf2330020
1668#define F367TER_DSS_SRCH 0xf2330010
1669#define F367TER_FECM_3 0xf2330008
1670#define F367TER_DIFF_MODEVIT 0xf2330004
1671#define F367TER_SYNCVIT 0xf2330002
1672#define F367TER_I2CSYM 0xf2330001
1673
1674/* VTH12 */
1675#define R367TER_VTH12 0xf234
1676#define F367TER_VTH_12 0xf23400ff
1677
1678/* VTH23 */
1679#define R367TER_VTH23 0xf235
1680#define F367TER_VTH_23 0xf23500ff
1681
1682/* VTH34 */
1683#define R367TER_VTH34 0xf236
1684#define F367TER_VTH_34 0xf23600ff
1685
1686/* VTH56 */
1687#define R367TER_VTH56 0xf237
1688#define F367TER_VTH_56 0xf23700ff
1689
1690/* VTH67 */
1691#define R367TER_VTH67 0xf238
1692#define F367TER_VTH_67 0xf23800ff
1693
1694/* VTH78 */
1695#define R367TER_VTH78 0xf239
1696#define F367TER_VTH_78 0xf23900ff
1697
1698/* VITCURPUN */
1699#define R367TER_VITCURPUN 0xf23a
1700#define F367TER_VIT_MAPPING 0xf23a00e0
1701#define F367TER_VIT_CURPUN 0xf23a001f
1702
1703/* VERROR */
1704#define R367TER_VERROR 0xf23b
1705#define F367TER_REGERR_VIT 0xf23b00ff
1706
1707/* PRVIT */
1708#define R367TER_PRVIT 0xf23c
1709#define F367TER_PRVIT_7 0xf23c0080
1710#define F367TER_DIS_VTHLOCK 0xf23c0040
1711#define F367TER_E7_8VIT 0xf23c0020
1712#define F367TER_E6_7VIT 0xf23c0010
1713#define F367TER_E5_6VIT 0xf23c0008
1714#define F367TER_E3_4VIT 0xf23c0004
1715#define F367TER_E2_3VIT 0xf23c0002
1716#define F367TER_E1_2VIT 0xf23c0001
1717
1718/* VAVSRVIT */
1719#define R367TER_VAVSRVIT 0xf23d
1720#define F367TER_AMVIT 0xf23d0080
1721#define F367TER_FROZENVIT 0xf23d0040
1722#define F367TER_SNVIT 0xf23d0030
1723#define F367TER_TOVVIT 0xf23d000c
1724#define F367TER_HYPVIT 0xf23d0003
1725
1726/* VSTATUSVIT */
1727#define R367TER_VSTATUSVIT 0xf23e
1728#define F367TER_VITERBI_ON 0xf23e0080
1729#define F367TER_END_LOOPVIT 0xf23e0040
1730#define F367TER_VITERBI_DEPRF 0xf23e0020
1731#define F367TER_PRFVIT 0xf23e0010
1732#define F367TER_LOCKEDVIT 0xf23e0008
1733#define F367TER_VITERBI_DELOCK 0xf23e0004
1734#define F367TER_VIT_DEMODSEL 0xf23e0002
1735#define F367TER_VITERBI_COMPOUT 0xf23e0001
1736
1737/* VTHINUSE */
1738#define R367TER_VTHINUSE 0xf23f
1739#define F367TER_VIT_INUSE 0xf23f00ff
1740
1741/* KDIV12 */
1742#define R367TER_KDIV12 0xf240
1743#define F367TER_KDIV12_MANUAL 0xf2400080
1744#define F367TER_K_DIVIDER_12 0xf240007f
1745
1746/* KDIV23 */
1747#define R367TER_KDIV23 0xf241
1748#define F367TER_KDIV23_MANUAL 0xf2410080
1749#define F367TER_K_DIVIDER_23 0xf241007f
1750
1751/* KDIV34 */
1752#define R367TER_KDIV34 0xf242
1753#define F367TER_KDIV34_MANUAL 0xf2420080
1754#define F367TER_K_DIVIDER_34 0xf242007f
1755
1756/* KDIV56 */
1757#define R367TER_KDIV56 0xf243
1758#define F367TER_KDIV56_MANUAL 0xf2430080
1759#define F367TER_K_DIVIDER_56 0xf243007f
1760
1761/* KDIV67 */
1762#define R367TER_KDIV67 0xf244
1763#define F367TER_KDIV67_MANUAL 0xf2440080
1764#define F367TER_K_DIVIDER_67 0xf244007f
1765
1766/* KDIV78 */
1767#define R367TER_KDIV78 0xf245
1768#define F367TER_KDIV78_MANUAL 0xf2450080
1769#define F367TER_K_DIVIDER_78 0xf245007f
1770
1771/* SIGPOWER */
1772#define R367TER_SIGPOWER 0xf246
1773#define F367TER_SIGPOWER_MANUAL 0xf2460080
1774#define F367TER_SIG_POWER 0xf246007f
1775
1776/* DEMAPVIT */
1777#define R367TER_DEMAPVIT 0xf247
1778#define F367TER_DEMAPVIT_7 0xf2470080
1779#define F367TER_K_DIVIDER_VIT 0xf247007f
1780
1781/* VITSCALE */
1782#define R367TER_VITSCALE 0xf248
1783#define F367TER_NVTH_NOSRANGE 0xf2480080
1784#define F367TER_VERROR_MAXMODE 0xf2480040
1785#define F367TER_KDIV_MODE 0xf2480030
1786#define F367TER_NSLOWSN_LOCKED 0xf2480008
1787#define F367TER_DELOCK_PRFLOSS 0xf2480004
1788#define F367TER_DIS_RSFLOCK 0xf2480002
1789#define F367TER_VITSCALE_0 0xf2480001
1790
1791/* FFEC1PRG */
1792#define R367TER_FFEC1PRG 0xf249
1793#define F367TER_FDSS_DVB 0xf2490080
1794#define F367TER_FDSS_SRCH 0xf2490040
1795#define F367TER_FFECPROG_5 0xf2490020
1796#define F367TER_FFECPROG_4 0xf2490010
1797#define F367TER_FFECPROG_3 0xf2490008
1798#define F367TER_FFECPROG_2 0xf2490004
1799#define F367TER_FTS1_DISABLE 0xf2490002
1800#define F367TER_FTS2_DISABLE 0xf2490001
1801
1802/* FVITCURPUN */
1803#define R367TER_FVITCURPUN 0xf24a
1804#define F367TER_FVIT_MAPPING 0xf24a00e0
1805#define F367TER_FVIT_CURPUN 0xf24a001f
1806
1807/* FVERROR */
1808#define R367TER_FVERROR 0xf24b
1809#define F367TER_FREGERR_VIT 0xf24b00ff
1810
1811/* FVSTATUSVIT */
1812#define R367TER_FVSTATUSVIT 0xf24c
1813#define F367TER_FVITERBI_ON 0xf24c0080
1814#define F367TER_F1END_LOOPVIT 0xf24c0040
1815#define F367TER_FVITERBI_DEPRF 0xf24c0020
1816#define F367TER_FPRFVIT 0xf24c0010
1817#define F367TER_FLOCKEDVIT 0xf24c0008
1818#define F367TER_FVITERBI_DELOCK 0xf24c0004
1819#define F367TER_FVIT_DEMODSEL 0xf24c0002
1820#define F367TER_FVITERBI_COMPOUT 0xf24c0001
1821
1822/* DEBUG_LT1 */
1823#define R367TER_DEBUG_LT1 0xf24d
1824#define F367TER_DBG_LT1 0xf24d00ff
1825
1826/* DEBUG_LT2 */
1827#define R367TER_DEBUG_LT2 0xf24e
1828#define F367TER_DBG_LT2 0xf24e00ff
1829
1830/* DEBUG_LT3 */
1831#define R367TER_DEBUG_LT3 0xf24f
1832#define F367TER_DBG_LT3 0xf24f00ff
1833
1834/* TSTSFMET */
1835#define R367TER_TSTSFMET 0xf250
1836#define F367TER_TSTSFEC_METRIQUES 0xf25000ff
1837
1838/* SELOUT */
1839#define R367TER_SELOUT 0xf252
1840#define F367TER_EN_SYNC 0xf2520080
1841#define F367TER_EN_TBUSDEMAP 0xf2520040
1842#define F367TER_SELOUT_5 0xf2520020
1843#define F367TER_SELOUT_4 0xf2520010
1844#define F367TER_TSTSYNCHRO_MODE 0xf2520002
1845
1846/* TSYNC */
1847#define R367TER_TSYNC 0xf253
1848#define F367TER_CURPUN_INCMODE 0xf2530080
1849#define F367TER_CERR_TSTMODE 0xf2530040
1850#define F367TER_SHIFTSOF_MODE 0xf2530030
1851#define F367TER_SLOWPHA_MODE 0xf2530008
1852#define F367TER_PXX_BYPALL 0xf2530004
1853#define F367TER_FROTA45_FIRST 0xf2530002
1854#define F367TER_TST_BCHERROR 0xf2530001
1855
1856/* TSTERR */
1857#define R367TER_TSTERR 0xf254
1858#define F367TER_TST_LONGPKT 0xf2540080
1859#define F367TER_TST_ISSYION 0xf2540040
1860#define F367TER_TST_NPDON 0xf2540020
1861#define F367TER_TSTERR_4 0xf2540010
1862#define F367TER_TRACEBACK_MODE 0xf2540008
1863#define F367TER_TST_RSPARITY 0xf2540004
1864#define F367TER_METRIQUE_MODE 0xf2540003
1865
1866/* TSFSYNC */
1867#define R367TER_TSFSYNC 0xf255
1868#define F367TER_EN_SFECSYNC 0xf2550080
1869#define F367TER_EN_SFECDEMAP 0xf2550040
1870#define F367TER_SFCERR_TSTMODE 0xf2550020
1871#define F367TER_SFECPXX_BYPALL 0xf2550010
1872#define F367TER_SFECTSTSYNCHRO_MODE 0xf255000f
1873
1874/* TSTSFERR */
1875#define R367TER_TSTSFERR 0xf256
1876#define F367TER_TSTSTERR_7 0xf2560080
1877#define F367TER_TSTSTERR_6 0xf2560040
1878#define F367TER_TSTSTERR_5 0xf2560020
1879#define F367TER_TSTSTERR_4 0xf2560010
1880#define F367TER_SFECTRACEBACK_MODE 0xf2560008
1881#define F367TER_SFEC_NCONVPROG 0xf2560004
1882#define F367TER_SFECMETRIQUE_MODE 0xf2560003
1883
1884/* TSTTSSF1 */
1885#define R367TER_TSTTSSF1 0xf258
1886#define F367TER_TSTERSSF 0xf2580080
1887#define F367TER_TSTTSSFEN 0xf2580040
1888#define F367TER_SFEC_OUTMODE 0xf2580030
1889#define F367TER_XLSF_NOFTHRESHOLD 0xf2580008
1890#define F367TER_TSTTSSF_STACKSEL 0xf2580007
1891
1892/* TSTTSSF2 */
1893#define R367TER_TSTTSSF2 0xf259
1894#define F367TER_DILSF_DBBHEADER 0xf2590080
1895#define F367TER_TSTTSSF_DISBUG 0xf2590040
1896#define F367TER_TSTTSSF_NOBADSTART 0xf2590020
1897#define F367TER_TSTTSSF_SELECT 0xf259001f
1898
1899/* TSTTSSF3 */
1900#define R367TER_TSTTSSF3 0xf25a
1901#define F367TER_TSTTSSF3_7 0xf25a0080
1902#define F367TER_TSTTSSF3_6 0xf25a0040
1903#define F367TER_TSTTSSF3_5 0xf25a0020
1904#define F367TER_TSTTSSF3_4 0xf25a0010
1905#define F367TER_TSTTSSF3_3 0xf25a0008
1906#define F367TER_TSTTSSF3_2 0xf25a0004
1907#define F367TER_TSTTSSF3_1 0xf25a0002
1908#define F367TER_DISSF_CLKENABLE 0xf25a0001
1909
1910/* TSTTS1 */
1911#define R367TER_TSTTS1 0xf25c
1912#define F367TER_TSTERS 0xf25c0080
1913#define F367TER_TSFIFO_DSSSYNCB 0xf25c0040
1914#define F367TER_TSTTS_FSPYBEFRS 0xf25c0020
1915#define F367TER_NFORCE_SYNCBYTE 0xf25c0010
1916#define F367TER_XL_NOFTHRESHOLD 0xf25c0008
1917#define F367TER_TSTTS_FRFORCEPKT 0xf25c0004
1918#define F367TER_DESCR_NOTAUTO 0xf25c0002
1919#define F367TER_TSTTSEN 0xf25c0001
1920
1921/* TSTTS2 */
1922#define R367TER_TSTTS2 0xf25d
1923#define F367TER_DIL_DBBHEADER 0xf25d0080
1924#define F367TER_TSTTS_NOBADXXX 0xf25d0040
1925#define F367TER_TSFIFO_DELSPEEDUP 0xf25d0020
1926#define F367TER_TSTTS_SELECT 0xf25d001f
1927
1928/* TSTTS3 */
1929#define R367TER_TSTTS3 0xf25e
1930#define F367TER_TSTTS_NOPKTGAIN 0xf25e0080
1931#define F367TER_TSTTS_NOPKTENE 0xf25e0040
1932#define F367TER_TSTTS_ISOLATION 0xf25e0020
1933#define F367TER_TSTTS_DISBUG 0xf25e0010
1934#define F367TER_TSTTS_NOBADSTART 0xf25e0008
1935#define F367TER_TSTTS_STACKSEL 0xf25e0007
1936
1937/* TSTTS4 */
1938#define R367TER_TSTTS4 0xf25f
1939#define F367TER_TSTTS4_7 0xf25f0080
1940#define F367TER_TSTTS4_6 0xf25f0040
1941#define F367TER_TSTTS4_5 0xf25f0020
1942#define F367TER_TSTTS_DISDSTATE 0xf25f0010
1943#define F367TER_TSTTS_FASTNOSYNC 0xf25f0008
1944#define F367TER_EXT_FECSPYIN 0xf25f0004
1945#define F367TER_TSTTS_NODPZERO 0xf25f0002
1946#define F367TER_TSTTS_NODIV3 0xf25f0001
1947
1948/* TSTTSRC */
1949#define R367TER_TSTTSRC 0xf26c
1950#define F367TER_TSTTSRC_7 0xf26c0080
1951#define F367TER_TSRCFIFO_DSSSYNCB 0xf26c0040
1952#define F367TER_TSRCFIFO_DPUNACTIVE 0xf26c0020
1953#define F367TER_TSRCFIFO_DELSPEEDUP 0xf26c0010
1954#define F367TER_TSTTSRC_NODIV3 0xf26c0008
1955#define F367TER_TSTTSRC_FRFORCEPKT 0xf26c0004
1956#define F367TER_SAT25_SDDORIGINE 0xf26c0002
1957#define F367TER_TSTTSRC_INACTIVE 0xf26c0001
1958
1959/* TSTTSRS */
1960#define R367TER_TSTTSRS 0xf26d
1961#define F367TER_TSTTSRS_7 0xf26d0080
1962#define F367TER_TSTTSRS_6 0xf26d0040
1963#define F367TER_TSTTSRS_5 0xf26d0020
1964#define F367TER_TSTTSRS_4 0xf26d0010
1965#define F367TER_TSTTSRS_3 0xf26d0008
1966#define F367TER_TSTTSRS_2 0xf26d0004
1967#define F367TER_TSTRS_DISRS2 0xf26d0002
1968#define F367TER_TSTRS_DISRS1 0xf26d0001
1969
1970/* TSSTATEM */
1971#define R367TER_TSSTATEM 0xf270
1972#define F367TER_TSDIL_ON 0xf2700080
1973#define F367TER_TSSKIPRS_ON 0xf2700040
1974#define F367TER_TSRS_ON 0xf2700020
1975#define F367TER_TSDESCRAMB_ON 0xf2700010
1976#define F367TER_TSFRAME_MODE 0xf2700008
1977#define F367TER_TS_DISABLE 0xf2700004
1978#define F367TER_TSACM_MODE 0xf2700002
1979#define F367TER_TSOUT_NOSYNC 0xf2700001
1980
1981/* TSSTATEL */
1982#define R367TER_TSSTATEL 0xf271
1983#define F367TER_TSNOSYNCBYTE 0xf2710080
1984#define F367TER_TSPARITY_ON 0xf2710040
1985#define F367TER_TSSYNCOUTRS_ON 0xf2710020
1986#define F367TER_TSDVBS2_MODE 0xf2710010
1987#define F367TER_TSISSYI_ON 0xf2710008
1988#define F367TER_TSNPD_ON 0xf2710004
1989#define F367TER_TSCRC8_ON 0xf2710002
1990#define F367TER_TSDSS_PACKET 0xf2710001
1991
1992/* TSCFGH */
1993#define R367TER_TSCFGH 0xf272
1994#define F367TER_TSFIFO_DVBCI 0xf2720080
1995#define F367TER_TSFIFO_SERIAL 0xf2720040
1996#define F367TER_TSFIFO_TEIUPDATE 0xf2720020
1997#define F367TER_TSFIFO_DUTY50 0xf2720010
1998#define F367TER_TSFIFO_HSGNLOUT 0xf2720008
1999#define F367TER_TSFIFO_ERRMODE 0xf2720006
2000#define F367TER_RST_HWARE 0xf2720001
2001
2002/* TSCFGM */
2003#define R367TER_TSCFGM 0xf273
2004#define F367TER_TSFIFO_MANSPEED 0xf27300c0
2005#define F367TER_TSFIFO_PERMDATA 0xf2730020
2006#define F367TER_TSFIFO_NONEWSGNL 0xf2730010
2007#define F367TER_TSFIFO_BITSPEED 0xf2730008
2008#define F367TER_NPD_SPECDVBS2 0xf2730004
2009#define F367TER_TSFIFO_STOPCKDIS 0xf2730002
2010#define F367TER_TSFIFO_INVDATA 0xf2730001
2011
2012/* TSCFGL */
2013#define R367TER_TSCFGL 0xf274
2014#define F367TER_TSFIFO_BCLKDEL1cK 0xf27400c0
2015#define F367TER_BCHERROR_MODE 0xf2740030
2016#define F367TER_TSFIFO_NSGNL2dATA 0xf2740008
2017#define F367TER_TSFIFO_EMBINDVB 0xf2740004
2018#define F367TER_TSFIFO_DPUNACT 0xf2740002
2019#define F367TER_TSFIFO_NPDOFF 0xf2740001
2020
2021/* TSSYNC */
2022#define R367TER_TSSYNC 0xf275
2023#define F367TER_TSFIFO_PERMUTE 0xf2750080
2024#define F367TER_TSFIFO_FISCR3B 0xf2750060
2025#define F367TER_TSFIFO_SYNCMODE 0xf2750018
2026#define F367TER_TSFIFO_SYNCSEL 0xf2750007
2027
2028/* TSINSDELH */
2029#define R367TER_TSINSDELH 0xf276
2030#define F367TER_TSDEL_SYNCBYTE 0xf2760080
2031#define F367TER_TSDEL_XXHEADER 0xf2760040
2032#define F367TER_TSDEL_BBHEADER 0xf2760020
2033#define F367TER_TSDEL_DATAFIELD 0xf2760010
2034#define F367TER_TSINSDEL_ISCR 0xf2760008
2035#define F367TER_TSINSDEL_NPD 0xf2760004
2036#define F367TER_TSINSDEL_RSPARITY 0xf2760002
2037#define F367TER_TSINSDEL_CRC8 0xf2760001
2038
2039/* TSINSDELM */
2040#define R367TER_TSINSDELM 0xf277
2041#define F367TER_TSINS_BBPADDING 0xf2770080
2042#define F367TER_TSINS_BCHFEC 0xf2770040
2043#define F367TER_TSINS_LDPCFEC 0xf2770020
2044#define F367TER_TSINS_EMODCOD 0xf2770010
2045#define F367TER_TSINS_TOKEN 0xf2770008
2046#define F367TER_TSINS_XXXERR 0xf2770004
2047#define F367TER_TSINS_MATYPE 0xf2770002
2048#define F367TER_TSINS_UPL 0xf2770001
2049
2050/* TSINSDELL */
2051#define R367TER_TSINSDELL 0xf278
2052#define F367TER_TSINS_DFL 0xf2780080
2053#define F367TER_TSINS_SYNCD 0xf2780040
2054#define F367TER_TSINS_BLOCLEN 0xf2780020
2055#define F367TER_TSINS_SIGPCOUNT 0xf2780010
2056#define F367TER_TSINS_FIFO 0xf2780008
2057#define F367TER_TSINS_REALPACK 0xf2780004
2058#define F367TER_TSINS_TSCONFIG 0xf2780002
2059#define F367TER_TSINS_LATENCY 0xf2780001
2060
2061/* TSDIVN */
2062#define R367TER_TSDIVN 0xf279
2063#define F367TER_TSFIFO_LOWSPEED 0xf2790080
2064#define F367TER_BYTE_OVERSAMPLING 0xf2790070
2065#define F367TER_TSMANUAL_PACKETNBR 0xf279000f
2066
2067/* TSDIVPM */
2068#define R367TER_TSDIVPM 0xf27a
2069#define F367TER_TSMANUAL_P_HI 0xf27a00ff
2070
2071/* TSDIVPL */
2072#define R367TER_TSDIVPL 0xf27b
2073#define F367TER_TSMANUAL_P_LO 0xf27b00ff
2074
2075/* TSDIVQM */
2076#define R367TER_TSDIVQM 0xf27c
2077#define F367TER_TSMANUAL_Q_HI 0xf27c00ff
2078
2079/* TSDIVQL */
2080#define R367TER_TSDIVQL 0xf27d
2081#define F367TER_TSMANUAL_Q_LO 0xf27d00ff
2082
2083/* TSDILSTKM */
2084#define R367TER_TSDILSTKM 0xf27e
2085#define F367TER_TSFIFO_DILSTK_HI 0xf27e00ff
2086
2087/* TSDILSTKL */
2088#define R367TER_TSDILSTKL 0xf27f
2089#define F367TER_TSFIFO_DILSTK_LO 0xf27f00ff
2090
2091/* TSSPEED */
2092#define R367TER_TSSPEED 0xf280
2093#define F367TER_TSFIFO_OUTSPEED 0xf28000ff
2094
2095/* TSSTATUS */
2096#define R367TER_TSSTATUS 0xf281
2097#define F367TER_TSFIFO_LINEOK 0xf2810080
2098#define F367TER_TSFIFO_ERROR 0xf2810040
2099#define F367TER_TSFIFO_DATA7 0xf2810020
2100#define F367TER_TSFIFO_NOSYNC 0xf2810010
2101#define F367TER_ISCR_INITIALIZED 0xf2810008
2102#define F367TER_ISCR_UPDATED 0xf2810004
2103#define F367TER_SOFFIFO_UNREGUL 0xf2810002
2104#define F367TER_DIL_READY 0xf2810001
2105
2106/* TSSTATUS2 */
2107#define R367TER_TSSTATUS2 0xf282
2108#define F367TER_TSFIFO_DEMODSEL 0xf2820080
2109#define F367TER_TSFIFOSPEED_STORE 0xf2820040
2110#define F367TER_DILXX_RESET 0xf2820020
2111#define F367TER_TSSERIAL_IMPOSSIBLE 0xf2820010
2112#define F367TER_TSFIFO_UNDERSPEED 0xf2820008
2113#define F367TER_BITSPEED_EVENT 0xf2820004
2114#define F367TER_UL_SCRAMBDETECT 0xf2820002
2115#define F367TER_ULDTV67_FALSELOCK 0xf2820001
2116
2117/* TSBITRATEM */
2118#define R367TER_TSBITRATEM 0xf283
2119#define F367TER_TSFIFO_BITRATE_HI 0xf28300ff
2120
2121/* TSBITRATEL */
2122#define R367TER_TSBITRATEL 0xf284
2123#define F367TER_TSFIFO_BITRATE_LO 0xf28400ff
2124
2125/* TSPACKLENM */
2126#define R367TER_TSPACKLENM 0xf285
2127#define F367TER_TSFIFO_PACKCPT 0xf28500e0
2128#define F367TER_DIL_RPLEN_HI 0xf285001f
2129
2130/* TSPACKLENL */
2131#define R367TER_TSPACKLENL 0xf286
2132#define F367TER_DIL_RPLEN_LO 0xf28600ff
2133
2134/* TSBLOCLENM */
2135#define R367TER_TSBLOCLENM 0xf287
2136#define F367TER_TSFIFO_PFLEN_HI 0xf28700ff
2137
2138/* TSBLOCLENL */
2139#define R367TER_TSBLOCLENL 0xf288
2140#define F367TER_TSFIFO_PFLEN_LO 0xf28800ff
2141
2142/* TSDLYH */
2143#define R367TER_TSDLYH 0xf289
2144#define F367TER_SOFFIFO_TSTIMEVALID 0xf2890080
2145#define F367TER_SOFFIFO_SPEEDUP 0xf2890040
2146#define F367TER_SOFFIFO_STOP 0xf2890020
2147#define F367TER_SOFFIFO_REGULATED 0xf2890010
2148#define F367TER_SOFFIFO_REALSBOFF_HI 0xf289000f
2149
2150/* TSDLYM */
2151#define R367TER_TSDLYM 0xf28a
2152#define F367TER_SOFFIFO_REALSBOFF_MED 0xf28a00ff
2153
2154/* TSDLYL */
2155#define R367TER_TSDLYL 0xf28b
2156#define F367TER_SOFFIFO_REALSBOFF_LO 0xf28b00ff
2157
2158/* TSNPDAV */
2159#define R367TER_TSNPDAV 0xf28c
2160#define F367TER_TSNPD_AVERAGE 0xf28c00ff
2161
2162/* TSBUFSTATH */
2163#define R367TER_TSBUFSTATH 0xf28d
2164#define F367TER_TSISCR_3BYTES 0xf28d0080
2165#define F367TER_TSISCR_NEWDATA 0xf28d0040
2166#define F367TER_TSISCR_BUFSTAT_HI 0xf28d003f
2167
2168/* TSBUFSTATM */
2169#define R367TER_TSBUFSTATM 0xf28e
2170#define F367TER_TSISCR_BUFSTAT_MED 0xf28e00ff
2171
2172/* TSBUFSTATL */
2173#define R367TER_TSBUFSTATL 0xf28f
2174#define F367TER_TSISCR_BUFSTAT_LO 0xf28f00ff
2175
2176/* TSDEBUGM */
2177#define R367TER_TSDEBUGM 0xf290
2178#define F367TER_TSFIFO_ILLPACKET 0xf2900080
2179#define F367TER_DIL_NOSYNC 0xf2900040
2180#define F367TER_DIL_ISCR 0xf2900020
2181#define F367TER_DILOUT_BSYNCB 0xf2900010
2182#define F367TER_TSFIFO_EMPTYPKT 0xf2900008
2183#define F367TER_TSFIFO_EMPTYRD 0xf2900004
2184#define F367TER_SOFFIFO_STOPM 0xf2900002
2185#define F367TER_SOFFIFO_SPEEDUPM 0xf2900001
2186
2187/* TSDEBUGL */
2188#define R367TER_TSDEBUGL 0xf291
2189#define F367TER_TSFIFO_PACKLENFAIL 0xf2910080
2190#define F367TER_TSFIFO_SYNCBFAIL 0xf2910040
2191#define F367TER_TSFIFO_VITLIBRE 0xf2910020
2192#define F367TER_TSFIFO_BOOSTSPEEDM 0xf2910010
2193#define F367TER_TSFIFO_UNDERSPEEDM 0xf2910008
2194#define F367TER_TSFIFO_ERROR_EVNT 0xf2910004
2195#define F367TER_TSFIFO_FULL 0xf2910002
2196#define F367TER_TSFIFO_OVERFLOWM 0xf2910001
2197
2198/* TSDLYSETH */
2199#define R367TER_TSDLYSETH 0xf292
2200#define F367TER_SOFFIFO_OFFSET 0xf29200e0
2201#define F367TER_SOFFIFO_SYMBOFFSET_HI 0xf292001f
2202
2203/* TSDLYSETM */
2204#define R367TER_TSDLYSETM 0xf293
2205#define F367TER_SOFFIFO_SYMBOFFSET_MED 0xf29300ff
2206
2207/* TSDLYSETL */
2208#define R367TER_TSDLYSETL 0xf294
2209#define F367TER_SOFFIFO_SYMBOFFSET_LO 0xf29400ff
2210
2211/* TSOBSCFG */
2212#define R367TER_TSOBSCFG 0xf295
2213#define F367TER_TSFIFO_OBSCFG 0xf29500ff
2214
2215/* TSOBSM */
2216#define R367TER_TSOBSM 0xf296
2217#define F367TER_TSFIFO_OBSDATA_HI 0xf29600ff
2218
2219/* TSOBSL */
2220#define R367TER_TSOBSL 0xf297
2221#define F367TER_TSFIFO_OBSDATA_LO 0xf29700ff
2222
2223/* ERRCTRL1 */
2224#define R367TER_ERRCTRL1 0xf298
2225#define F367TER_ERR_SRC1 0xf29800f0
2226#define F367TER_ERRCTRL1_3 0xf2980008
2227#define F367TER_NUM_EVT1 0xf2980007
2228
2229/* ERRCNT1H */
2230#define R367TER_ERRCNT1H 0xf299
2231#define F367TER_ERRCNT1_OLDVALUE 0xf2990080
2232#define F367TER_ERR_CNT1 0xf299007f
2233
2234/* ERRCNT1M */
2235#define R367TER_ERRCNT1M 0xf29a
2236#define F367TER_ERR_CNT1_HI 0xf29a00ff
2237
2238/* ERRCNT1L */
2239#define R367TER_ERRCNT1L 0xf29b
2240#define F367TER_ERR_CNT1_LO 0xf29b00ff
2241
2242/* ERRCTRL2 */
2243#define R367TER_ERRCTRL2 0xf29c
2244#define F367TER_ERR_SRC2 0xf29c00f0
2245#define F367TER_ERRCTRL2_3 0xf29c0008
2246#define F367TER_NUM_EVT2 0xf29c0007
2247
2248/* ERRCNT2H */
2249#define R367TER_ERRCNT2H 0xf29d
2250#define F367TER_ERRCNT2_OLDVALUE 0xf29d0080
2251#define F367TER_ERR_CNT2_HI 0xf29d007f
2252
2253/* ERRCNT2M */
2254#define R367TER_ERRCNT2M 0xf29e
2255#define F367TER_ERR_CNT2_MED 0xf29e00ff
2256
2257/* ERRCNT2L */
2258#define R367TER_ERRCNT2L 0xf29f
2259#define F367TER_ERR_CNT2_LO 0xf29f00ff
2260
2261/* FECSPY */
2262#define R367TER_FECSPY 0xf2a0
2263#define F367TER_SPY_ENABLE 0xf2a00080
2264#define F367TER_NO_SYNCBYTE 0xf2a00040
2265#define F367TER_SERIAL_MODE 0xf2a00020
2266#define F367TER_UNUSUAL_PACKET 0xf2a00010
2267#define F367TER_BERMETER_DATAMODE 0xf2a0000c
2268#define F367TER_BERMETER_LMODE 0xf2a00002
2269#define F367TER_BERMETER_RESET 0xf2a00001
2270
2271/* FSPYCFG */
2272#define R367TER_FSPYCFG 0xf2a1
2273#define F367TER_FECSPY_INPUT 0xf2a100c0
2274#define F367TER_RST_ON_ERROR 0xf2a10020
2275#define F367TER_ONE_SHOT 0xf2a10010
2276#define F367TER_I2C_MOD 0xf2a1000c
2277#define F367TER_SPY_HYSTERESIS 0xf2a10003
2278
2279/* FSPYDATA */
2280#define R367TER_FSPYDATA 0xf2a2
2281#define F367TER_SPY_STUFFING 0xf2a20080
2282#define F367TER_NOERROR_PKTJITTER 0xf2a20040
2283#define F367TER_SPY_CNULLPKT 0xf2a20020
2284#define F367TER_SPY_OUTDATA_MODE 0xf2a2001f
2285
2286/* FSPYOUT */
2287#define R367TER_FSPYOUT 0xf2a3
2288#define F367TER_FSPY_DIRECT 0xf2a30080
2289#define F367TER_FSPYOUT_6 0xf2a30040
2290#define F367TER_SPY_OUTDATA_BUS 0xf2a30038
2291#define F367TER_STUFF_MODE 0xf2a30007
2292
2293/* FSTATUS */
2294#define R367TER_FSTATUS 0xf2a4
2295#define F367TER_SPY_ENDSIM 0xf2a40080
2296#define F367TER_VALID_SIM 0xf2a40040
2297#define F367TER_FOUND_SIGNAL 0xf2a40020
2298#define F367TER_DSS_SYNCBYTE 0xf2a40010
2299#define F367TER_RESULT_STATE 0xf2a4000f
2300
2301/* FGOODPACK */
2302#define R367TER_FGOODPACK 0xf2a5
2303#define F367TER_FGOOD_PACKET 0xf2a500ff
2304
2305/* FPACKCNT */
2306#define R367TER_FPACKCNT 0xf2a6
2307#define F367TER_FPACKET_COUNTER 0xf2a600ff
2308
2309/* FSPYMISC */
2310#define R367TER_FSPYMISC 0xf2a7
2311#define F367TER_FLABEL_COUNTER 0xf2a700ff
2312
2313/* FBERCPT4 */
2314#define R367TER_FBERCPT4 0xf2a8
2315#define F367TER_FBERMETER_CPT5 0xf2a800ff
2316
2317/* FBERCPT3 */
2318#define R367TER_FBERCPT3 0xf2a9
2319#define F367TER_FBERMETER_CPT4 0xf2a900ff
2320
2321/* FBERCPT2 */
2322#define R367TER_FBERCPT2 0xf2aa
2323#define F367TER_FBERMETER_CPT3 0xf2aa00ff
2324
2325/* FBERCPT1 */
2326#define R367TER_FBERCPT1 0xf2ab
2327#define F367TER_FBERMETER_CPT2 0xf2ab00ff
2328
2329/* FBERCPT0 */
2330#define R367TER_FBERCPT0 0xf2ac
2331#define F367TER_FBERMETER_CPT1 0xf2ac00ff
2332
2333/* FBERERR2 */
2334#define R367TER_FBERERR2 0xf2ad
2335#define F367TER_FBERMETER_ERR_HI 0xf2ad00ff
2336
2337/* FBERERR1 */
2338#define R367TER_FBERERR1 0xf2ae
2339#define F367TER_FBERMETER_ERR_MED 0xf2ae00ff
2340
2341/* FBERERR0 */
2342#define R367TER_FBERERR0 0xf2af
2343#define F367TER_FBERMETER_ERR_LO 0xf2af00ff
2344
2345/* FSTATESM */
2346#define R367TER_FSTATESM 0xf2b0
2347#define F367TER_RSTATE_F 0xf2b00080
2348#define F367TER_RSTATE_E 0xf2b00040
2349#define F367TER_RSTATE_D 0xf2b00020
2350#define F367TER_RSTATE_C 0xf2b00010
2351#define F367TER_RSTATE_B 0xf2b00008
2352#define F367TER_RSTATE_A 0xf2b00004
2353#define F367TER_RSTATE_9 0xf2b00002
2354#define F367TER_RSTATE_8 0xf2b00001
2355
2356/* FSTATESL */
2357#define R367TER_FSTATESL 0xf2b1
2358#define F367TER_RSTATE_7 0xf2b10080
2359#define F367TER_RSTATE_6 0xf2b10040
2360#define F367TER_RSTATE_5 0xf2b10020
2361#define F367TER_RSTATE_4 0xf2b10010
2362#define F367TER_RSTATE_3 0xf2b10008
2363#define F367TER_RSTATE_2 0xf2b10004
2364#define F367TER_RSTATE_1 0xf2b10002
2365#define F367TER_RSTATE_0 0xf2b10001
2366
2367/* FSPYBER */
2368#define R367TER_FSPYBER 0xf2b2
2369#define F367TER_FSPYBER_7 0xf2b20080
2370#define F367TER_FSPYOBS_XORREAD 0xf2b20040
2371#define F367TER_FSPYBER_OBSMODE 0xf2b20020
2372#define F367TER_FSPYBER_SYNCBYTE 0xf2b20010
2373#define F367TER_FSPYBER_UNSYNC 0xf2b20008
2374#define F367TER_FSPYBER_CTIME 0xf2b20007
2375
2376/* FSPYDISTM */
2377#define R367TER_FSPYDISTM 0xf2b3
2378#define F367TER_PKTTIME_DISTANCE_HI 0xf2b300ff
2379
2380/* FSPYDISTL */
2381#define R367TER_FSPYDISTL 0xf2b4
2382#define F367TER_PKTTIME_DISTANCE_LO 0xf2b400ff
2383
2384/* FSPYOBS7 */
2385#define R367TER_FSPYOBS7 0xf2b8
2386#define F367TER_FSPYOBS_SPYFAIL 0xf2b80080
2387#define F367TER_FSPYOBS_SPYFAIL1 0xf2b80040
2388#define F367TER_FSPYOBS_ERROR 0xf2b80020
2389#define F367TER_FSPYOBS_STROUT 0xf2b80010
2390#define F367TER_FSPYOBS_RESULTSTATE1 0xf2b8000f
2391
2392/* FSPYOBS6 */
2393#define R367TER_FSPYOBS6 0xf2b9
2394#define F367TER_FSPYOBS_RESULTSTATe0 0xf2b900f0
2395#define F367TER_FSPYOBS_RESULTSTATEM1 0xf2b9000f
2396
2397/* FSPYOBS5 */
2398#define R367TER_FSPYOBS5 0xf2ba
2399#define F367TER_FSPYOBS_BYTEOFPACKET1 0xf2ba00ff
2400
2401/* FSPYOBS4 */
2402#define R367TER_FSPYOBS4 0xf2bb
2403#define F367TER_FSPYOBS_BYTEVALUE1 0xf2bb00ff
2404
2405/* FSPYOBS3 */
2406#define R367TER_FSPYOBS3 0xf2bc
2407#define F367TER_FSPYOBS_DATA1 0xf2bc00ff
2408
2409/* FSPYOBS2 */
2410#define R367TER_FSPYOBS2 0xf2bd
2411#define F367TER_FSPYOBS_DATa0 0xf2bd00ff
2412
2413/* FSPYOBS1 */
2414#define R367TER_FSPYOBS1 0xf2be
2415#define F367TER_FSPYOBS_DATAM1 0xf2be00ff
2416
2417/* FSPYOBS0 */
2418#define R367TER_FSPYOBS0 0xf2bf
2419#define F367TER_FSPYOBS_DATAM2 0xf2bf00ff
2420
2421/* SFDEMAP */
2422#define R367TER_SFDEMAP 0xf2c0
2423#define F367TER_SFDEMAP_7 0xf2c00080
2424#define F367TER_SFEC_K_DIVIDER_VIT 0xf2c0007f
2425
2426/* SFERROR */
2427#define R367TER_SFERROR 0xf2c1
2428#define F367TER_SFEC_REGERR_VIT 0xf2c100ff
2429
2430/* SFAVSR */
2431#define R367TER_SFAVSR 0xf2c2
2432#define F367TER_SFEC_SUMERRORS 0xf2c20080
2433#define F367TER_SERROR_MAXMODE 0xf2c20040
2434#define F367TER_SN_SFEC 0xf2c20030
2435#define F367TER_KDIV_MODE_SFEC 0xf2c2000c
2436#define F367TER_SFAVSR_1 0xf2c20002
2437#define F367TER_SFAVSR_0 0xf2c20001
2438
2439/* SFECSTATUS */
2440#define R367TER_SFECSTATUS 0xf2c3
2441#define F367TER_SFEC_ON 0xf2c30080
2442#define F367TER_SFSTATUS_6 0xf2c30040
2443#define F367TER_SFSTATUS_5 0xf2c30020
2444#define F367TER_SFSTATUS_4 0xf2c30010
2445#define F367TER_LOCKEDSFEC 0xf2c30008
2446#define F367TER_SFEC_DELOCK 0xf2c30004
2447#define F367TER_SFEC_DEMODSEL1 0xf2c30002
2448#define F367TER_SFEC_OVFON 0xf2c30001
2449
2450/* SFKDIV12 */
2451#define R367TER_SFKDIV12 0xf2c4
2452#define F367TER_SFECKDIV12_MAN 0xf2c40080
2453#define F367TER_SFEC_K_DIVIDER_12 0xf2c4007f
2454
2455/* SFKDIV23 */
2456#define R367TER_SFKDIV23 0xf2c5
2457#define F367TER_SFECKDIV23_MAN 0xf2c50080
2458#define F367TER_SFEC_K_DIVIDER_23 0xf2c5007f
2459
2460/* SFKDIV34 */
2461#define R367TER_SFKDIV34 0xf2c6
2462#define F367TER_SFECKDIV34_MAN 0xf2c60080
2463#define F367TER_SFEC_K_DIVIDER_34 0xf2c6007f
2464
2465/* SFKDIV56 */
2466#define R367TER_SFKDIV56 0xf2c7
2467#define F367TER_SFECKDIV56_MAN 0xf2c70080
2468#define F367TER_SFEC_K_DIVIDER_56 0xf2c7007f
2469
2470/* SFKDIV67 */
2471#define R367TER_SFKDIV67 0xf2c8
2472#define F367TER_SFECKDIV67_MAN 0xf2c80080
2473#define F367TER_SFEC_K_DIVIDER_67 0xf2c8007f
2474
2475/* SFKDIV78 */
2476#define R367TER_SFKDIV78 0xf2c9
2477#define F367TER_SFECKDIV78_MAN 0xf2c90080
2478#define F367TER_SFEC_K_DIVIDER_78 0xf2c9007f
2479
2480/* SFDILSTKM */
2481#define R367TER_SFDILSTKM 0xf2ca
2482#define F367TER_SFEC_PACKCPT 0xf2ca00e0
2483#define F367TER_SFEC_DILSTK_HI 0xf2ca001f
2484
2485/* SFDILSTKL */
2486#define R367TER_SFDILSTKL 0xf2cb
2487#define F367TER_SFEC_DILSTK_LO 0xf2cb00ff
2488
2489/* SFSTATUS */
2490#define R367TER_SFSTATUS 0xf2cc
2491#define F367TER_SFEC_LINEOK 0xf2cc0080
2492#define F367TER_SFEC_ERROR 0xf2cc0040
2493#define F367TER_SFEC_DATA7 0xf2cc0020
2494#define F367TER_SFEC_OVERFLOW 0xf2cc0010
2495#define F367TER_SFEC_DEMODSEL2 0xf2cc0008
2496#define F367TER_SFEC_NOSYNC 0xf2cc0004
2497#define F367TER_SFEC_UNREGULA 0xf2cc0002
2498#define F367TER_SFEC_READY 0xf2cc0001
2499
2500/* SFDLYH */
2501#define R367TER_SFDLYH 0xf2cd
2502#define F367TER_SFEC_TSTIMEVALID 0xf2cd0080
2503#define F367TER_SFEC_SPEEDUP 0xf2cd0040
2504#define F367TER_SFEC_STOP 0xf2cd0020
2505#define F367TER_SFEC_REGULATED 0xf2cd0010
2506#define F367TER_SFEC_REALSYMBOFFSET 0xf2cd000f
2507
2508/* SFDLYM */
2509#define R367TER_SFDLYM 0xf2ce
2510#define F367TER_SFEC_REALSYMBOFFSET_HI 0xf2ce00ff
2511
2512/* SFDLYL */
2513#define R367TER_SFDLYL 0xf2cf
2514#define F367TER_SFEC_REALSYMBOFFSET_LO 0xf2cf00ff
2515
2516/* SFDLYSETH */
2517#define R367TER_SFDLYSETH 0xf2d0
2518#define F367TER_SFEC_OFFSET 0xf2d000e0
2519#define F367TER_SFECDLYSETH_4 0xf2d00010
2520#define F367TER_RST_SFEC 0xf2d00008
2521#define F367TER_SFECDLYSETH_2 0xf2d00004
2522#define F367TER_SFEC_DISABLE 0xf2d00002
2523#define F367TER_SFEC_UNREGUL 0xf2d00001
2524
2525/* SFDLYSETM */
2526#define R367TER_SFDLYSETM 0xf2d1
2527#define F367TER_SFECDLYSETM_7 0xf2d10080
2528#define F367TER_SFEC_SYMBOFFSET_HI 0xf2d1007f
2529
2530/* SFDLYSETL */
2531#define R367TER_SFDLYSETL 0xf2d2
2532#define F367TER_SFEC_SYMBOFFSET_LO 0xf2d200ff
2533
2534/* SFOBSCFG */
2535#define R367TER_SFOBSCFG 0xf2d3
2536#define F367TER_SFEC_OBSCFG 0xf2d300ff
2537
2538/* SFOBSM */
2539#define R367TER_SFOBSM 0xf2d4
2540#define F367TER_SFEC_OBSDATA_HI 0xf2d400ff
2541
2542/* SFOBSL */
2543#define R367TER_SFOBSL 0xf2d5
2544#define F367TER_SFEC_OBSDATA_LO 0xf2d500ff
2545
2546/* SFECINFO */
2547#define R367TER_SFECINFO 0xf2d6
2548#define F367TER_SFECINFO_7 0xf2d60080
2549#define F367TER_SFEC_SYNCDLSB 0xf2d60070
2550#define F367TER_SFCE_S1cPHASE 0xf2d6000f
2551
2552/* SFERRCTRL */
2553#define R367TER_SFERRCTRL 0xf2d8
2554#define F367TER_SFEC_ERR_SOURCE 0xf2d800f0
2555#define F367TER_SFERRCTRL_3 0xf2d80008
2556#define F367TER_SFEC_NUM_EVENT 0xf2d80007
2557
2558/* SFERRCNTH */
2559#define R367TER_SFERRCNTH 0xf2d9
2560#define F367TER_SFERRC_OLDVALUE 0xf2d90080
2561#define F367TER_SFEC_ERR_CNT 0xf2d9007f
2562
2563/* SFERRCNTM */
2564#define R367TER_SFERRCNTM 0xf2da
2565#define F367TER_SFEC_ERR_CNT_HI 0xf2da00ff
2566
2567/* SFERRCNTL */
2568#define R367TER_SFERRCNTL 0xf2db
2569#define F367TER_SFEC_ERR_CNT_LO 0xf2db00ff
2570
2571/* SYMBRATEM */
2572#define R367TER_SYMBRATEM 0xf2e0
2573#define F367TER_DEFGEN_SYMBRATE_HI 0xf2e000ff
2574
2575/* SYMBRATEL */
2576#define R367TER_SYMBRATEL 0xf2e1
2577#define F367TER_DEFGEN_SYMBRATE_LO 0xf2e100ff
2578
2579/* SYMBSTATUS */
2580#define R367TER_SYMBSTATUS 0xf2e2
2581#define F367TER_SYMBDLINE2_OFF 0xf2e20080
2582#define F367TER_SDDL_REINIT1 0xf2e20040
2583#define F367TER_SDD_REINIT1 0xf2e20020
2584#define F367TER_TOKENID_ERROR 0xf2e20010
2585#define F367TER_SYMBRATE_OVERFLOW 0xf2e20008
2586#define F367TER_SYMBRATE_UNDERFLOW 0xf2e20004
2587#define F367TER_TOKENID_RSTEVENT 0xf2e20002
2588#define F367TER_TOKENID_RESET1 0xf2e20001
2589
2590/* SYMBCFG */
2591#define R367TER_SYMBCFG 0xf2e3
2592#define F367TER_SYMBCFG_7 0xf2e30080
2593#define F367TER_SYMBCFG_6 0xf2e30040
2594#define F367TER_SYMBCFG_5 0xf2e30020
2595#define F367TER_SYMBCFG_4 0xf2e30010
2596#define F367TER_SYMRATE_FSPEED 0xf2e3000c
2597#define F367TER_SYMRATE_SSPEED 0xf2e30003
2598
2599/* SYMBFIFOM */
2600#define R367TER_SYMBFIFOM 0xf2e4
2601#define F367TER_SYMBFIFOM_7 0xf2e40080
2602#define F367TER_SYMBFIFOM_6 0xf2e40040
2603#define F367TER_DEFGEN_SYMFIFO_HI 0xf2e4003f
2604
2605/* SYMBFIFOL */
2606#define R367TER_SYMBFIFOL 0xf2e5
2607#define F367TER_DEFGEN_SYMFIFO_LO 0xf2e500ff
2608
2609/* SYMBOFFSM */
2610#define R367TER_SYMBOFFSM 0xf2e6
2611#define F367TER_TOKENID_RESET2 0xf2e60080
2612#define F367TER_SDDL_REINIT2 0xf2e60040
2613#define F367TER_SDD_REINIT2 0xf2e60020
2614#define F367TER_SYMBOFFSM_4 0xf2e60010
2615#define F367TER_SYMBOFFSM_3 0xf2e60008
2616#define F367TER_DEFGEN_SYMBOFFSET_HI 0xf2e60007
2617
2618/* SYMBOFFSL */
2619#define R367TER_SYMBOFFSL 0xf2e7
2620#define F367TER_DEFGEN_SYMBOFFSET_LO 0xf2e700ff
2621
2622/* DEBUG_LT4 */
2623#define R367TER_DEBUG_LT4 0xf400
2624#define F367TER_F_DEBUG_LT4 0xf40000ff
2625
2626/* DEBUG_LT5 */
2627#define R367TER_DEBUG_LT5 0xf401
2628#define F367TER_F_DEBUG_LT5 0xf40100ff
2629
2630/* DEBUG_LT6 */
2631#define R367TER_DEBUG_LT6 0xf402
2632#define F367TER_F_DEBUG_LT6 0xf40200ff
2633
2634/* DEBUG_LT7 */
2635#define R367TER_DEBUG_LT7 0xf403
2636#define F367TER_F_DEBUG_LT7 0xf40300ff
2637
2638/* DEBUG_LT8 */
2639#define R367TER_DEBUG_LT8 0xf404
2640#define F367TER_F_DEBUG_LT8 0xf40400ff
2641
2642/* DEBUG_LT9 */
2643#define R367TER_DEBUG_LT9 0xf405
2644#define F367TER_F_DEBUG_LT9 0xf40500ff
2645
2646#define STV0367TER_NBREGS 445
2647
2648/* ID */
2649#define R367CAB_ID 0xf000
2650#define F367CAB_IDENTIFICATIONREGISTER 0xf00000ff
2651
2652/* I2CRPT */
2653#define R367CAB_I2CRPT 0xf001
2654#define F367CAB_I2CT_ON 0xf0010080
2655#define F367CAB_ENARPT_LEVEL 0xf0010070
2656#define F367CAB_SCLT_DELAY 0xf0010008
2657#define F367CAB_SCLT_NOD 0xf0010004
2658#define F367CAB_STOP_ENABLE 0xf0010002
2659#define F367CAB_SDAT_NOD 0xf0010001
2660
2661/* TOPCTRL */
2662#define R367CAB_TOPCTRL 0xf002
2663#define F367CAB_STDBY 0xf0020080
2664#define F367CAB_STDBY_CORE 0xf0020020
2665#define F367CAB_QAM_COFDM 0xf0020010
2666#define F367CAB_TS_DIS 0xf0020008
2667#define F367CAB_DIR_CLK_216 0xf0020004
2668
2669/* IOCFG0 */
2670#define R367CAB_IOCFG0 0xf003
2671#define F367CAB_OP0_SD 0xf0030080
2672#define F367CAB_OP0_VAL 0xf0030040
2673#define F367CAB_OP0_OD 0xf0030020
2674#define F367CAB_OP0_INV 0xf0030010
2675#define F367CAB_OP0_DACVALUE_HI 0xf003000f
2676
2677/* DAc0R */
2678#define R367CAB_DAC0R 0xf004
2679#define F367CAB_OP0_DACVALUE_LO 0xf00400ff
2680
2681/* IOCFG1 */
2682#define R367CAB_IOCFG1 0xf005
2683#define F367CAB_IP0 0xf0050040
2684#define F367CAB_OP1_OD 0xf0050020
2685#define F367CAB_OP1_INV 0xf0050010
2686#define F367CAB_OP1_DACVALUE_HI 0xf005000f
2687
2688/* DAC1R */
2689#define R367CAB_DAC1R 0xf006
2690#define F367CAB_OP1_DACVALUE_LO 0xf00600ff
2691
2692/* IOCFG2 */
2693#define R367CAB_IOCFG2 0xf007
2694#define F367CAB_OP2_LOCK_CONF 0xf00700e0
2695#define F367CAB_OP2_OD 0xf0070010
2696#define F367CAB_OP2_VAL 0xf0070008
2697#define F367CAB_OP1_LOCK_CONF 0xf0070007
2698
2699/* SDFR */
2700#define R367CAB_SDFR 0xf008
2701#define F367CAB_OP0_FREQ 0xf00800f0
2702#define F367CAB_OP1_FREQ 0xf008000f
2703
2704/* AUX_CLK */
2705#define R367CAB_AUX_CLK 0xf00a
2706#define F367CAB_AUXFEC_CTL 0xf00a00c0
2707#define F367CAB_DIS_CKX4 0xf00a0020
2708#define F367CAB_CKSEL 0xf00a0018
2709#define F367CAB_CKDIV_PROG 0xf00a0006
2710#define F367CAB_AUXCLK_ENA 0xf00a0001
2711
2712/* FREESYS1 */
2713#define R367CAB_FREESYS1 0xf00b
2714#define F367CAB_FREESYS_1 0xf00b00ff
2715
2716/* FREESYS2 */
2717#define R367CAB_FREESYS2 0xf00c
2718#define F367CAB_FREESYS_2 0xf00c00ff
2719
2720/* FREESYS3 */
2721#define R367CAB_FREESYS3 0xf00d
2722#define F367CAB_FREESYS_3 0xf00d00ff
2723
2724/* GPIO_CFG */
2725#define R367CAB_GPIO_CFG 0xf00e
2726#define F367CAB_GPIO7_OD 0xf00e0080
2727#define F367CAB_GPIO7_CFG 0xf00e0040
2728#define F367CAB_GPIO6_OD 0xf00e0020
2729#define F367CAB_GPIO6_CFG 0xf00e0010
2730#define F367CAB_GPIO5_OD 0xf00e0008
2731#define F367CAB_GPIO5_CFG 0xf00e0004
2732#define F367CAB_GPIO4_OD 0xf00e0002
2733#define F367CAB_GPIO4_CFG 0xf00e0001
2734
2735/* GPIO_CMD */
2736#define R367CAB_GPIO_CMD 0xf00f
2737#define F367CAB_GPIO7_VAL 0xf00f0008
2738#define F367CAB_GPIO6_VAL 0xf00f0004
2739#define F367CAB_GPIO5_VAL 0xf00f0002
2740#define F367CAB_GPIO4_VAL 0xf00f0001
2741
2742/* TSTRES */
2743#define R367CAB_TSTRES 0xf0c0
2744#define F367CAB_FRES_DISPLAY 0xf0c00080
2745#define F367CAB_FRES_FIFO_AD 0xf0c00020
2746#define F367CAB_FRESRS 0xf0c00010
2747#define F367CAB_FRESACS 0xf0c00008
2748#define F367CAB_FRESFEC 0xf0c00004
2749#define F367CAB_FRES_PRIF 0xf0c00002
2750#define F367CAB_FRESCORE 0xf0c00001
2751
2752/* ANACTRL */
2753#define R367CAB_ANACTRL 0xf0c1
2754#define F367CAB_BYPASS_XTAL 0xf0c10040
2755#define F367CAB_BYPASS_PLLXN 0xf0c1000c
2756#define F367CAB_DIS_PAD_OSC 0xf0c10002
2757#define F367CAB_STDBY_PLLXN 0xf0c10001
2758
2759/* TSTBUS */
2760#define R367CAB_TSTBUS 0xf0c2
2761#define F367CAB_TS_BYTE_CLK_INV 0xf0c20080
2762#define F367CAB_CFG_IP 0xf0c20070
2763#define F367CAB_CFG_TST 0xf0c2000f
2764
2765/* RF_AGC1 */
2766#define R367CAB_RF_AGC1 0xf0d4
2767#define F367CAB_RF_AGC1_LEVEL_HI 0xf0d400ff
2768
2769/* RF_AGC2 */
2770#define R367CAB_RF_AGC2 0xf0d5
2771#define F367CAB_REF_ADGP 0xf0d50080
2772#define F367CAB_STDBY_ADCGP 0xf0d50020
2773#define F367CAB_RF_AGC1_LEVEL_LO 0xf0d50003
2774
2775/* ANADIGCTRL */
2776#define R367CAB_ANADIGCTRL 0xf0d7
2777#define F367CAB_SEL_CLKDEM 0xf0d70020
2778#define F367CAB_EN_BUFFER_Q 0xf0d70010
2779#define F367CAB_EN_BUFFER_I 0xf0d70008
2780#define F367CAB_ADC_RIS_EGDE 0xf0d70004
2781#define F367CAB_SGN_ADC 0xf0d70002
2782#define F367CAB_SEL_AD12_SYNC 0xf0d70001
2783
2784/* PLLMDIV */
2785#define R367CAB_PLLMDIV 0xf0d8
2786#define F367CAB_PLL_MDIV 0xf0d800ff
2787
2788/* PLLNDIV */
2789#define R367CAB_PLLNDIV 0xf0d9
2790#define F367CAB_PLL_NDIV 0xf0d900ff
2791
2792/* PLLSETUP */
2793#define R367CAB_PLLSETUP 0xf0da
2794#define F367CAB_PLL_PDIV 0xf0da0070
2795#define F367CAB_PLL_KDIV 0xf0da000f
2796
2797/* DUAL_AD12 */
2798#define R367CAB_DUAL_AD12 0xf0db
2799#define F367CAB_FS20M 0xf0db0020
2800#define F367CAB_FS50M 0xf0db0010
2801#define F367CAB_INMODe0 0xf0db0008
2802#define F367CAB_POFFQ 0xf0db0004
2803#define F367CAB_POFFI 0xf0db0002
2804#define F367CAB_INMODE1 0xf0db0001
2805
2806/* TSTBIST */
2807#define R367CAB_TSTBIST 0xf0dc
2808#define F367CAB_TST_BYP_CLK 0xf0dc0080
2809#define F367CAB_TST_GCLKENA_STD 0xf0dc0040
2810#define F367CAB_TST_GCLKENA 0xf0dc0020
2811#define F367CAB_TST_MEMBIST 0xf0dc001f
2812
2813/* CTRL_1 */
2814#define R367CAB_CTRL_1 0xf402
2815#define F367CAB_SOFT_RST 0xf4020080
2816#define F367CAB_EQU_RST 0xf4020008
2817#define F367CAB_CRL_RST 0xf4020004
2818#define F367CAB_TRL_RST 0xf4020002
2819#define F367CAB_AGC_RST 0xf4020001
2820
2821/* CTRL_2 */
2822#define R367CAB_CTRL_2 0xf403
2823#define F367CAB_DEINT_RST 0xf4030008
2824#define F367CAB_RS_RST 0xf4030004
2825
2826/* IT_STATUS1 */
2827#define R367CAB_IT_STATUS1 0xf408
2828#define F367CAB_SWEEP_OUT 0xf4080080
2829#define F367CAB_FSM_CRL 0xf4080040
2830#define F367CAB_CRL_LOCK 0xf4080020
2831#define F367CAB_MFSM 0xf4080010
2832#define F367CAB_TRL_LOCK 0xf4080008
2833#define F367CAB_TRL_AGC_LIMIT 0xf4080004
2834#define F367CAB_ADJ_AGC_LOCK 0xf4080002
2835#define F367CAB_AGC_QAM_LOCK 0xf4080001
2836
2837/* IT_STATUS2 */
2838#define R367CAB_IT_STATUS2 0xf409
2839#define F367CAB_TSMF_CNT 0xf4090080
2840#define F367CAB_TSMF_EOF 0xf4090040
2841#define F367CAB_TSMF_RDY 0xf4090020
2842#define F367CAB_FEC_NOCORR 0xf4090010
2843#define F367CAB_SYNCSTATE 0xf4090008
2844#define F367CAB_DEINT_LOCK 0xf4090004
2845#define F367CAB_FADDING_FRZ 0xf4090002
2846#define F367CAB_TAPMON_ALARM 0xf4090001
2847
2848/* IT_EN1 */
2849#define R367CAB_IT_EN1 0xf40a
2850#define F367CAB_SWEEP_OUTE 0xf40a0080
2851#define F367CAB_FSM_CRLE 0xf40a0040
2852#define F367CAB_CRL_LOCKE 0xf40a0020
2853#define F367CAB_MFSME 0xf40a0010
2854#define F367CAB_TRL_LOCKE 0xf40a0008
2855#define F367CAB_TRL_AGC_LIMITE 0xf40a0004
2856#define F367CAB_ADJ_AGC_LOCKE 0xf40a0002
2857#define F367CAB_AGC_LOCKE 0xf40a0001
2858
2859/* IT_EN2 */
2860#define R367CAB_IT_EN2 0xf40b
2861#define F367CAB_TSMF_CNTE 0xf40b0080
2862#define F367CAB_TSMF_EOFE 0xf40b0040
2863#define F367CAB_TSMF_RDYE 0xf40b0020
2864#define F367CAB_FEC_NOCORRE 0xf40b0010
2865#define F367CAB_SYNCSTATEE 0xf40b0008
2866#define F367CAB_DEINT_LOCKE 0xf40b0004
2867#define F367CAB_FADDING_FRZE 0xf40b0002
2868#define F367CAB_TAPMON_ALARME 0xf40b0001
2869
2870/* CTRL_STATUS */
2871#define R367CAB_CTRL_STATUS 0xf40c
2872#define F367CAB_QAMFEC_LOCK 0xf40c0004
2873#define F367CAB_TSMF_LOCK 0xf40c0002
2874#define F367CAB_TSMF_ERROR 0xf40c0001
2875
2876/* TEST_CTL */
2877#define R367CAB_TEST_CTL 0xf40f
2878#define F367CAB_TST_BLK_SEL 0xf40f0060
2879#define F367CAB_TST_BUS_SEL 0xf40f001f
2880
2881/* AGC_CTL */
2882#define R367CAB_AGC_CTL 0xf410
2883#define F367CAB_AGC_LCK_TH 0xf41000f0
2884#define F367CAB_AGC_ACCUMRSTSEL 0xf4100007
2885
2886/* AGC_IF_CFG */
2887#define R367CAB_AGC_IF_CFG 0xf411
2888#define F367CAB_AGC_IF_BWSEL 0xf41100f0
2889#define F367CAB_AGC_IF_FREEZE 0xf4110002
2890
2891/* AGC_RF_CFG */
2892#define R367CAB_AGC_RF_CFG 0xf412
2893#define F367CAB_AGC_RF_BWSEL 0xf4120070
2894#define F367CAB_AGC_RF_FREEZE 0xf4120002
2895
2896/* AGC_PWM_CFG */
2897#define R367CAB_AGC_PWM_CFG 0xf413
2898#define F367CAB_AGC_RF_PWM_TST 0xf4130080
2899#define F367CAB_AGC_RF_PWM_INV 0xf4130040
2900#define F367CAB_AGC_IF_PWM_TST 0xf4130008
2901#define F367CAB_AGC_IF_PWM_INV 0xf4130004
2902#define F367CAB_AGC_PWM_CLKDIV 0xf4130003
2903
2904/* AGC_PWR_REF_L */
2905#define R367CAB_AGC_PWR_REF_L 0xf414
2906#define F367CAB_AGC_PWRREF_LO 0xf41400ff
2907
2908/* AGC_PWR_REF_H */
2909#define R367CAB_AGC_PWR_REF_H 0xf415
2910#define F367CAB_AGC_PWRREF_HI 0xf4150003
2911
2912/* AGC_RF_TH_L */
2913#define R367CAB_AGC_RF_TH_L 0xf416
2914#define F367CAB_AGC_RF_TH_LO 0xf41600ff
2915
2916/* AGC_RF_TH_H */
2917#define R367CAB_AGC_RF_TH_H 0xf417
2918#define F367CAB_AGC_RF_TH_HI 0xf417000f
2919
2920/* AGC_IF_LTH_L */
2921#define R367CAB_AGC_IF_LTH_L 0xf418
2922#define F367CAB_AGC_IF_THLO_LO 0xf41800ff
2923
2924/* AGC_IF_LTH_H */
2925#define R367CAB_AGC_IF_LTH_H 0xf419
2926#define F367CAB_AGC_IF_THLO_HI 0xf419000f
2927
2928/* AGC_IF_HTH_L */
2929#define R367CAB_AGC_IF_HTH_L 0xf41a
2930#define F367CAB_AGC_IF_THHI_LO 0xf41a00ff
2931
2932/* AGC_IF_HTH_H */
2933#define R367CAB_AGC_IF_HTH_H 0xf41b
2934#define F367CAB_AGC_IF_THHI_HI 0xf41b000f
2935
2936/* AGC_PWR_RD_L */
2937#define R367CAB_AGC_PWR_RD_L 0xf41c
2938#define F367CAB_AGC_PWR_WORD_LO 0xf41c00ff
2939
2940/* AGC_PWR_RD_M */
2941#define R367CAB_AGC_PWR_RD_M 0xf41d
2942#define F367CAB_AGC_PWR_WORD_ME 0xf41d00ff
2943
2944/* AGC_PWR_RD_H */
2945#define R367CAB_AGC_PWR_RD_H 0xf41e
2946#define F367CAB_AGC_PWR_WORD_HI 0xf41e0003
2947
2948/* AGC_PWM_IFCMD_L */
2949#define R367CAB_AGC_PWM_IFCMD_L 0xf420
2950#define F367CAB_AGC_IF_PWMCMD_LO 0xf42000ff
2951
2952/* AGC_PWM_IFCMD_H */
2953#define R367CAB_AGC_PWM_IFCMD_H 0xf421
2954#define F367CAB_AGC_IF_PWMCMD_HI 0xf421000f
2955
2956/* AGC_PWM_RFCMD_L */
2957#define R367CAB_AGC_PWM_RFCMD_L 0xf422
2958#define F367CAB_AGC_RF_PWMCMD_LO 0xf42200ff
2959
2960/* AGC_PWM_RFCMD_H */
2961#define R367CAB_AGC_PWM_RFCMD_H 0xf423
2962#define F367CAB_AGC_RF_PWMCMD_HI 0xf423000f
2963
2964/* IQDEM_CFG */
2965#define R367CAB_IQDEM_CFG 0xf424
2966#define F367CAB_IQDEM_CLK_SEL 0xf4240004
2967#define F367CAB_IQDEM_INVIQ 0xf4240002
2968#define F367CAB_IQDEM_A2dTYPE 0xf4240001
2969
2970/* MIX_NCO_LL */
2971#define R367CAB_MIX_NCO_LL 0xf425
2972#define F367CAB_MIX_NCO_INC_LL 0xf42500ff
2973
2974/* MIX_NCO_HL */
2975#define R367CAB_MIX_NCO_HL 0xf426
2976#define F367CAB_MIX_NCO_INC_HL 0xf42600ff
2977
2978/* MIX_NCO_HH */
2979#define R367CAB_MIX_NCO_HH 0xf427
2980#define F367CAB_MIX_NCO_INVCNST 0xf4270080
2981#define F367CAB_MIX_NCO_INC_HH 0xf427007f
2982
2983/* SRC_NCO_LL */
2984#define R367CAB_SRC_NCO_LL 0xf428
2985#define F367CAB_SRC_NCO_INC_LL 0xf42800ff
2986
2987/* SRC_NCO_LH */
2988#define R367CAB_SRC_NCO_LH 0xf429
2989#define F367CAB_SRC_NCO_INC_LH 0xf42900ff
2990
2991/* SRC_NCO_HL */
2992#define R367CAB_SRC_NCO_HL 0xf42a
2993#define F367CAB_SRC_NCO_INC_HL 0xf42a00ff
2994
2995/* SRC_NCO_HH */
2996#define R367CAB_SRC_NCO_HH 0xf42b
2997#define F367CAB_SRC_NCO_INC_HH 0xf42b007f
2998
2999/* IQDEM_GAIN_SRC_L */
3000#define R367CAB_IQDEM_GAIN_SRC_L 0xf42c
3001#define F367CAB_GAIN_SRC_LO 0xf42c00ff
3002
3003/* IQDEM_GAIN_SRC_H */
3004#define R367CAB_IQDEM_GAIN_SRC_H 0xf42d
3005#define F367CAB_GAIN_SRC_HI 0xf42d0003
3006
3007/* IQDEM_DCRM_CFG_LL */
3008#define R367CAB_IQDEM_DCRM_CFG_LL 0xf430
3009#define F367CAB_DCRM0_DCIN_L 0xf43000ff
3010
3011/* IQDEM_DCRM_CFG_LH */
3012#define R367CAB_IQDEM_DCRM_CFG_LH 0xf431
3013#define F367CAB_DCRM1_I_DCIN_L 0xf43100fc
3014#define F367CAB_DCRM0_DCIN_H 0xf4310003
3015
3016/* IQDEM_DCRM_CFG_HL */
3017#define R367CAB_IQDEM_DCRM_CFG_HL 0xf432
3018#define F367CAB_DCRM1_Q_DCIN_L 0xf43200f0
3019#define F367CAB_DCRM1_I_DCIN_H 0xf432000f
3020
3021/* IQDEM_DCRM_CFG_HH */
3022#define R367CAB_IQDEM_DCRM_CFG_HH 0xf433
3023#define F367CAB_DCRM1_FRZ 0xf4330080
3024#define F367CAB_DCRM0_FRZ 0xf4330040
3025#define F367CAB_DCRM1_Q_DCIN_H 0xf433003f
3026
3027/* IQDEM_ADJ_COEFf0 */
3028#define R367CAB_IQDEM_ADJ_COEFF0 0xf434
3029#define F367CAB_ADJIIR_COEFF10_L 0xf43400ff
3030
3031/* IQDEM_ADJ_COEFF1 */
3032#define R367CAB_IQDEM_ADJ_COEFF1 0xf435
3033#define F367CAB_ADJIIR_COEFF11_L 0xf43500fc
3034#define F367CAB_ADJIIR_COEFF10_H 0xf4350003
3035
3036/* IQDEM_ADJ_COEFF2 */
3037#define R367CAB_IQDEM_ADJ_COEFF2 0xf436
3038#define F367CAB_ADJIIR_COEFF12_L 0xf43600f0
3039#define F367CAB_ADJIIR_COEFF11_H 0xf436000f
3040
3041/* IQDEM_ADJ_COEFF3 */
3042#define R367CAB_IQDEM_ADJ_COEFF3 0xf437
3043#define F367CAB_ADJIIR_COEFF20_L 0xf43700c0
3044#define F367CAB_ADJIIR_COEFF12_H 0xf437003f
3045
3046/* IQDEM_ADJ_COEFF4 */
3047#define R367CAB_IQDEM_ADJ_COEFF4 0xf438
3048#define F367CAB_ADJIIR_COEFF20_H 0xf43800ff
3049
3050/* IQDEM_ADJ_COEFF5 */
3051#define R367CAB_IQDEM_ADJ_COEFF5 0xf439
3052#define F367CAB_ADJIIR_COEFF21_L 0xf43900ff
3053
3054/* IQDEM_ADJ_COEFF6 */
3055#define R367CAB_IQDEM_ADJ_COEFF6 0xf43a
3056#define F367CAB_ADJIIR_COEFF22_L 0xf43a00fc
3057#define F367CAB_ADJIIR_COEFF21_H 0xf43a0003
3058
3059/* IQDEM_ADJ_COEFF7 */
3060#define R367CAB_IQDEM_ADJ_COEFF7 0xf43b
3061#define F367CAB_ADJIIR_COEFF22_H 0xf43b000f
3062
3063/* IQDEM_ADJ_EN */
3064#define R367CAB_IQDEM_ADJ_EN 0xf43c
3065#define F367CAB_ALLPASSFILT_EN 0xf43c0008
3066#define F367CAB_ADJ_AGC_EN 0xf43c0004
3067#define F367CAB_ADJ_COEFF_FRZ 0xf43c0002
3068#define F367CAB_ADJ_EN 0xf43c0001
3069
3070/* IQDEM_ADJ_AGC_REF */
3071#define R367CAB_IQDEM_ADJ_AGC_REF 0xf43d
3072#define F367CAB_ADJ_AGC_REF 0xf43d00ff
3073
3074/* ALLPASSFILT1 */
3075#define R367CAB_ALLPASSFILT1 0xf440
3076#define F367CAB_ALLPASSFILT_COEFF1_LO 0xf44000ff
3077
3078/* ALLPASSFILT2 */
3079#define R367CAB_ALLPASSFILT2 0xf441
3080#define F367CAB_ALLPASSFILT_COEFF1_ME 0xf44100ff
3081
3082/* ALLPASSFILT3 */
3083#define R367CAB_ALLPASSFILT3 0xf442
3084#define F367CAB_ALLPASSFILT_COEFF2_LO 0xf44200c0
3085#define F367CAB_ALLPASSFILT_COEFF1_HI 0xf442003f
3086
3087/* ALLPASSFILT4 */
3088#define R367CAB_ALLPASSFILT4 0xf443
3089#define F367CAB_ALLPASSFILT_COEFF2_MEL 0xf44300ff
3090
3091/* ALLPASSFILT5 */
3092#define R367CAB_ALLPASSFILT5 0xf444
3093#define F367CAB_ALLPASSFILT_COEFF2_MEH 0xf44400ff
3094
3095/* ALLPASSFILT6 */
3096#define R367CAB_ALLPASSFILT6 0xf445
3097#define F367CAB_ALLPASSFILT_COEFF3_LO 0xf44500f0
3098#define F367CAB_ALLPASSFILT_COEFF2_HI 0xf445000f
3099
3100/* ALLPASSFILT7 */
3101#define R367CAB_ALLPASSFILT7 0xf446
3102#define F367CAB_ALLPASSFILT_COEFF3_MEL 0xf44600ff
3103
3104/* ALLPASSFILT8 */
3105#define R367CAB_ALLPASSFILT8 0xf447
3106#define F367CAB_ALLPASSFILT_COEFF3_MEH 0xf44700ff
3107
3108/* ALLPASSFILT9 */
3109#define R367CAB_ALLPASSFILT9 0xf448
3110#define F367CAB_ALLPASSFILT_COEFF4_LO 0xf44800fc
3111#define F367CAB_ALLPASSFILT_COEFF3_HI 0xf4480003
3112
3113/* ALLPASSFILT10 */
3114#define R367CAB_ALLPASSFILT10 0xf449
3115#define F367CAB_ALLPASSFILT_COEFF4_ME 0xf44900ff
3116
3117/* ALLPASSFILT11 */
3118#define R367CAB_ALLPASSFILT11 0xf44a
3119#define F367CAB_ALLPASSFILT_COEFF4_HI 0xf44a00ff
3120
3121/* TRL_AGC_CFG */
3122#define R367CAB_TRL_AGC_CFG 0xf450
3123#define F367CAB_TRL_AGC_FREEZE 0xf4500080
3124#define F367CAB_TRL_AGC_REF 0xf450007f
3125
3126/* TRL_LPF_CFG */
3127#define R367CAB_TRL_LPF_CFG 0xf454
3128#define F367CAB_NYQPOINT_INV 0xf4540040
3129#define F367CAB_TRL_SHIFT 0xf4540030
3130#define F367CAB_NYQ_COEFF_SEL 0xf454000c
3131#define F367CAB_TRL_LPF_FREEZE 0xf4540002
3132#define F367CAB_TRL_LPF_CRT 0xf4540001
3133
3134/* TRL_LPF_ACQ_GAIN */
3135#define R367CAB_TRL_LPF_ACQ_GAIN 0xf455
3136#define F367CAB_TRL_GDIR_ACQ 0xf4550070
3137#define F367CAB_TRL_GINT_ACQ 0xf4550007
3138
3139/* TRL_LPF_TRK_GAIN */
3140#define R367CAB_TRL_LPF_TRK_GAIN 0xf456
3141#define F367CAB_TRL_GDIR_TRK 0xf4560070
3142#define F367CAB_TRL_GINT_TRK 0xf4560007
3143
3144/* TRL_LPF_OUT_GAIN */
3145#define R367CAB_TRL_LPF_OUT_GAIN 0xf457
3146#define F367CAB_TRL_GAIN_OUT 0xf4570007
3147
3148/* TRL_LOCKDET_LTH */
3149#define R367CAB_TRL_LOCKDET_LTH 0xf458
3150#define F367CAB_TRL_LCK_THLO 0xf4580007
3151
3152/* TRL_LOCKDET_HTH */
3153#define R367CAB_TRL_LOCKDET_HTH 0xf459
3154#define F367CAB_TRL_LCK_THHI 0xf45900ff
3155
3156/* TRL_LOCKDET_TRGVAL */
3157#define R367CAB_TRL_LOCKDET_TRGVAL 0xf45a
3158#define F367CAB_TRL_LCK_TRG 0xf45a00ff
3159
3160/* IQ_QAM */
3161#define R367CAB_IQ_QAM 0xf45c
3162#define F367CAB_IQ_INPUT 0xf45c0008
3163#define F367CAB_DETECT_MODE 0xf45c0007
3164
3165/* FSM_STATE */
3166#define R367CAB_FSM_STATE 0xf460
3167#define F367CAB_CRL_DFE 0xf4600080
3168#define F367CAB_DFE_START 0xf4600040
3169#define F367CAB_CTRLG_START 0xf4600030
3170#define F367CAB_FSM_FORCESTATE 0xf460000f
3171
3172/* FSM_CTL */
3173#define R367CAB_FSM_CTL 0xf461
3174#define F367CAB_FEC2_EN 0xf4610040
3175#define F367CAB_SIT_EN 0xf4610020
3176#define F367CAB_TRL_AHEAD 0xf4610010
3177#define F367CAB_TRL2_EN 0xf4610008
3178#define F367CAB_FSM_EQA1_EN 0xf4610004
3179#define F367CAB_FSM_BKP_DIS 0xf4610002
3180#define F367CAB_FSM_FORCE_EN 0xf4610001
3181
3182/* FSM_STS */
3183#define R367CAB_FSM_STS 0xf462
3184#define F367CAB_FSM_STATUS 0xf462000f
3185
3186/* FSM_SNR0_HTH */
3187#define R367CAB_FSM_SNR0_HTH 0xf463
3188#define F367CAB_SNR0_HTH 0xf46300ff
3189
3190/* FSM_SNR1_HTH */
3191#define R367CAB_FSM_SNR1_HTH 0xf464
3192#define F367CAB_SNR1_HTH 0xf46400ff
3193
3194/* FSM_SNR2_HTH */
3195#define R367CAB_FSM_SNR2_HTH 0xf465
3196#define F367CAB_SNR2_HTH 0xf46500ff
3197
3198/* FSM_SNR0_LTH */
3199#define R367CAB_FSM_SNR0_LTH 0xf466
3200#define F367CAB_SNR0_LTH 0xf46600ff
3201
3202/* FSM_SNR1_LTH */
3203#define R367CAB_FSM_SNR1_LTH 0xf467
3204#define F367CAB_SNR1_LTH 0xf46700ff
3205
3206/* FSM_EQA1_HTH */
3207#define R367CAB_FSM_EQA1_HTH 0xf468
3208#define F367CAB_SNR3_HTH_LO 0xf46800f0
3209#define F367CAB_EQA1_HTH 0xf468000f
3210
3211/* FSM_TEMPO */
3212#define R367CAB_FSM_TEMPO 0xf469
3213#define F367CAB_SIT 0xf46900c0
3214#define F367CAB_WST 0xf4690038
3215#define F367CAB_ELT 0xf4690006
3216#define F367CAB_SNR3_HTH_HI 0xf4690001
3217
3218/* FSM_CONFIG */
3219#define R367CAB_FSM_CONFIG 0xf46a
3220#define F367CAB_FEC2_DFEOFF 0xf46a0004
3221#define F367CAB_PRIT_STATE 0xf46a0002
3222#define F367CAB_MODMAP_STATE 0xf46a0001
3223
3224/* EQU_I_TESTTAP_L */
3225#define R367CAB_EQU_I_TESTTAP_L 0xf474
3226#define F367CAB_I_TEST_TAP_L 0xf47400ff
3227
3228/* EQU_I_TESTTAP_M */
3229#define R367CAB_EQU_I_TESTTAP_M 0xf475
3230#define F367CAB_I_TEST_TAP_M 0xf47500ff
3231
3232/* EQU_I_TESTTAP_H */
3233#define R367CAB_EQU_I_TESTTAP_H 0xf476
3234#define F367CAB_I_TEST_TAP_H 0xf476001f
3235
3236/* EQU_TESTAP_CFG */
3237#define R367CAB_EQU_TESTAP_CFG 0xf477
3238#define F367CAB_TEST_FFE_DFE_SEL 0xf4770040
3239#define F367CAB_TEST_TAP_SELECT 0xf477003f
3240
3241/* EQU_Q_TESTTAP_L */
3242#define R367CAB_EQU_Q_TESTTAP_L 0xf478
3243#define F367CAB_Q_TEST_TAP_L 0xf47800ff
3244
3245/* EQU_Q_TESTTAP_M */
3246#define R367CAB_EQU_Q_TESTTAP_M 0xf479
3247#define F367CAB_Q_TEST_TAP_M 0xf47900ff
3248
3249/* EQU_Q_TESTTAP_H */
3250#define R367CAB_EQU_Q_TESTTAP_H 0xf47a
3251#define F367CAB_Q_TEST_TAP_H 0xf47a001f
3252
3253/* EQU_TAP_CTRL */
3254#define R367CAB_EQU_TAP_CTRL 0xf47b
3255#define F367CAB_MTAP_FRZ 0xf47b0010
3256#define F367CAB_PRE_FREEZE 0xf47b0008
3257#define F367CAB_DFE_TAPMON_EN 0xf47b0004
3258#define F367CAB_FFE_TAPMON_EN 0xf47b0002
3259#define F367CAB_MTAP_ONLY 0xf47b0001
3260
3261/* EQU_CTR_CRL_CONTROL_L */
3262#define R367CAB_EQU_CTR_CRL_CONTROL_L 0xf47c
3263#define F367CAB_EQU_CTR_CRL_CONTROL_LO 0xf47c00ff
3264
3265/* EQU_CTR_CRL_CONTROL_H */
3266#define R367CAB_EQU_CTR_CRL_CONTROL_H 0xf47d
3267#define F367CAB_EQU_CTR_CRL_CONTROL_HI 0xf47d00ff
3268
3269/* EQU_CTR_HIPOW_L */
3270#define R367CAB_EQU_CTR_HIPOW_L 0xf47e
3271#define F367CAB_CTR_HIPOW_L 0xf47e00ff
3272
3273/* EQU_CTR_HIPOW_H */
3274#define R367CAB_EQU_CTR_HIPOW_H 0xf47f
3275#define F367CAB_CTR_HIPOW_H 0xf47f00ff
3276
3277/* EQU_I_EQU_LO */
3278#define R367CAB_EQU_I_EQU_LO 0xf480
3279#define F367CAB_EQU_I_EQU_L 0xf48000ff
3280
3281/* EQU_I_EQU_HI */
3282#define R367CAB_EQU_I_EQU_HI 0xf481
3283#define F367CAB_EQU_I_EQU_H 0xf4810003
3284
3285/* EQU_Q_EQU_LO */
3286#define R367CAB_EQU_Q_EQU_LO 0xf482
3287#define F367CAB_EQU_Q_EQU_L 0xf48200ff
3288
3289/* EQU_Q_EQU_HI */
3290#define R367CAB_EQU_Q_EQU_HI 0xf483
3291#define F367CAB_EQU_Q_EQU_H 0xf4830003
3292
3293/* EQU_MAPPER */
3294#define R367CAB_EQU_MAPPER 0xf484
3295#define F367CAB_QUAD_AUTO 0xf4840080
3296#define F367CAB_QUAD_INV 0xf4840040
3297#define F367CAB_QAM_MODE 0xf4840007
3298
3299/* EQU_SWEEP_RATE */
3300#define R367CAB_EQU_SWEEP_RATE 0xf485
3301#define F367CAB_SNR_PER 0xf48500c0
3302#define F367CAB_SWEEP_RATE 0xf485003f
3303
3304/* EQU_SNR_LO */
3305#define R367CAB_EQU_SNR_LO 0xf486
3306#define F367CAB_SNR_LO 0xf48600ff
3307
3308/* EQU_SNR_HI */
3309#define R367CAB_EQU_SNR_HI 0xf487
3310#define F367CAB_SNR_HI 0xf48700ff
3311
3312/* EQU_GAMMA_LO */
3313#define R367CAB_EQU_GAMMA_LO 0xf488
3314#define F367CAB_GAMMA_LO 0xf48800ff
3315
3316/* EQU_GAMMA_HI */
3317#define R367CAB_EQU_GAMMA_HI 0xf489
3318#define F367CAB_GAMMA_ME 0xf48900ff
3319
3320/* EQU_ERR_GAIN */
3321#define R367CAB_EQU_ERR_GAIN 0xf48a
3322#define F367CAB_EQA1MU 0xf48a0070
3323#define F367CAB_CRL2MU 0xf48a000e
3324#define F367CAB_GAMMA_HI 0xf48a0001
3325
3326/* EQU_RADIUS */
3327#define R367CAB_EQU_RADIUS 0xf48b
3328#define F367CAB_RADIUS 0xf48b00ff
3329
3330/* EQU_FFE_MAINTAP */
3331#define R367CAB_EQU_FFE_MAINTAP 0xf48c
3332#define F367CAB_FFE_MAINTAP_INIT 0xf48c00ff
3333
3334/* EQU_FFE_LEAKAGE */
3335#define R367CAB_EQU_FFE_LEAKAGE 0xf48e
3336#define F367CAB_LEAK_PER 0xf48e00f0
3337#define F367CAB_EQU_OUTSEL 0xf48e0002
3338#define F367CAB_PNT2dFE 0xf48e0001
3339
3340/* EQU_FFE_MAINTAP_POS */
3341#define R367CAB_EQU_FFE_MAINTAP_POS 0xf48f
3342#define F367CAB_FFE_LEAK_EN 0xf48f0080
3343#define F367CAB_DFE_LEAK_EN 0xf48f0040
3344#define F367CAB_FFE_MAINTAP_POS 0xf48f003f
3345
3346/* EQU_GAIN_WIDE */
3347#define R367CAB_EQU_GAIN_WIDE 0xf490
3348#define F367CAB_DFE_GAIN_WIDE 0xf49000f0
3349#define F367CAB_FFE_GAIN_WIDE 0xf490000f
3350
3351/* EQU_GAIN_NARROW */
3352#define R367CAB_EQU_GAIN_NARROW 0xf491
3353#define F367CAB_DFE_GAIN_NARROW 0xf49100f0
3354#define F367CAB_FFE_GAIN_NARROW 0xf491000f
3355
3356/* EQU_CTR_LPF_GAIN */
3357#define R367CAB_EQU_CTR_LPF_GAIN 0xf492
3358#define F367CAB_CTR_GTO 0xf4920080
3359#define F367CAB_CTR_GDIR 0xf4920070
3360#define F367CAB_SWEEP_EN 0xf4920008
3361#define F367CAB_CTR_GINT 0xf4920007
3362
3363/* EQU_CRL_LPF_GAIN */
3364#define R367CAB_EQU_CRL_LPF_GAIN 0xf493
3365#define F367CAB_CRL_GTO 0xf4930080
3366#define F367CAB_CRL_GDIR 0xf4930070
3367#define F367CAB_SWEEP_DIR 0xf4930008
3368#define F367CAB_CRL_GINT 0xf4930007
3369
3370/* EQU_GLOBAL_GAIN */
3371#define R367CAB_EQU_GLOBAL_GAIN 0xf494
3372#define F367CAB_CRL_GAIN 0xf49400f8
3373#define F367CAB_CTR_INC_GAIN 0xf4940004
3374#define F367CAB_CTR_FRAC 0xf4940003
3375
3376/* EQU_CRL_LD_SEN */
3377#define R367CAB_EQU_CRL_LD_SEN 0xf495
3378#define F367CAB_CTR_BADPOINT_EN 0xf4950080
3379#define F367CAB_CTR_GAIN 0xf4950070
3380#define F367CAB_LIMANEN 0xf4950008
3381#define F367CAB_CRL_LD_SEN 0xf4950007
3382
3383/* EQU_CRL_LD_VAL */
3384#define R367CAB_EQU_CRL_LD_VAL 0xf496
3385#define F367CAB_CRL_BISTH_LIMIT 0xf4960080
3386#define F367CAB_CARE_EN 0xf4960040
3387#define F367CAB_CRL_LD_PER 0xf4960030
3388#define F367CAB_CRL_LD_WST 0xf496000c
3389#define F367CAB_CRL_LD_TFS 0xf4960003
3390
3391/* EQU_CRL_TFR */
3392#define R367CAB_EQU_CRL_TFR 0xf497
3393#define F367CAB_CRL_LD_TFR 0xf49700ff
3394
3395/* EQU_CRL_BISTH_LO */
3396#define R367CAB_EQU_CRL_BISTH_LO 0xf498
3397#define F367CAB_CRL_BISTH_LO 0xf49800ff
3398
3399/* EQU_CRL_BISTH_HI */
3400#define R367CAB_EQU_CRL_BISTH_HI 0xf499
3401#define F367CAB_CRL_BISTH_HI 0xf49900ff
3402
3403/* EQU_SWEEP_RANGE_LO */
3404#define R367CAB_EQU_SWEEP_RANGE_LO 0xf49a
3405#define F367CAB_SWEEP_RANGE_LO 0xf49a00ff
3406
3407/* EQU_SWEEP_RANGE_HI */
3408#define R367CAB_EQU_SWEEP_RANGE_HI 0xf49b
3409#define F367CAB_SWEEP_RANGE_HI 0xf49b00ff
3410
3411/* EQU_CRL_LIMITER */
3412#define R367CAB_EQU_CRL_LIMITER 0xf49c
3413#define F367CAB_BISECTOR_EN 0xf49c0080
3414#define F367CAB_PHEST128_EN 0xf49c0040
3415#define F367CAB_CRL_LIM 0xf49c003f
3416
3417/* EQU_MODULUS_MAP */
3418#define R367CAB_EQU_MODULUS_MAP 0xf49d
3419#define F367CAB_PNT_DEPTH 0xf49d00e0
3420#define F367CAB_MODULUS_CMP 0xf49d001f
3421
3422/* EQU_PNT_GAIN */
3423#define R367CAB_EQU_PNT_GAIN 0xf49e
3424#define F367CAB_PNT_EN 0xf49e0080
3425#define F367CAB_MODULUSMAP_EN 0xf49e0040
3426#define F367CAB_PNT_GAIN 0xf49e003f
3427
3428/* FEC_AC_CTR_0 */
3429#define R367CAB_FEC_AC_CTR_0 0xf4a8
3430#define F367CAB_BE_BYPASS 0xf4a80020
3431#define F367CAB_REFRESH47 0xf4a80010
3432#define F367CAB_CT_NBST 0xf4a80008
3433#define F367CAB_TEI_ENA 0xf4a80004
3434#define F367CAB_DS_ENA 0xf4a80002
3435#define F367CAB_TSMF_EN 0xf4a80001
3436
3437/* FEC_AC_CTR_1 */
3438#define R367CAB_FEC_AC_CTR_1 0xf4a9
3439#define F367CAB_DEINT_DEPTH 0xf4a900ff
3440
3441/* FEC_AC_CTR_2 */
3442#define R367CAB_FEC_AC_CTR_2 0xf4aa
3443#define F367CAB_DEINT_M 0xf4aa00f8
3444#define F367CAB_DIS_UNLOCK 0xf4aa0004
3445#define F367CAB_DESCR_MODE 0xf4aa0003
3446
3447/* FEC_AC_CTR_3 */
3448#define R367CAB_FEC_AC_CTR_3 0xf4ab
3449#define F367CAB_DI_UNLOCK 0xf4ab0080
3450#define F367CAB_DI_FREEZE 0xf4ab0040
3451#define F367CAB_MISMATCH 0xf4ab0030
3452#define F367CAB_ACQ_MODE 0xf4ab000c
3453#define F367CAB_TRK_MODE 0xf4ab0003
3454
3455/* FEC_STATUS */
3456#define R367CAB_FEC_STATUS 0xf4ac
3457#define F367CAB_DEINT_SMCNTR 0xf4ac00e0
3458#define F367CAB_DEINT_SYNCSTATE 0xf4ac0018
3459#define F367CAB_DEINT_SYNLOST 0xf4ac0004
3460#define F367CAB_DESCR_SYNCSTATE 0xf4ac0002
3461
3462/* RS_COUNTER_0 */
3463#define R367CAB_RS_COUNTER_0 0xf4ae
3464#define F367CAB_BK_CT_L 0xf4ae00ff
3465
3466/* RS_COUNTER_1 */
3467#define R367CAB_RS_COUNTER_1 0xf4af
3468#define F367CAB_BK_CT_H 0xf4af00ff
3469
3470/* RS_COUNTER_2 */
3471#define R367CAB_RS_COUNTER_2 0xf4b0
3472#define F367CAB_CORR_CT_L 0xf4b000ff
3473
3474/* RS_COUNTER_3 */
3475#define R367CAB_RS_COUNTER_3 0xf4b1
3476#define F367CAB_CORR_CT_H 0xf4b100ff
3477
3478/* RS_COUNTER_4 */
3479#define R367CAB_RS_COUNTER_4 0xf4b2
3480#define F367CAB_UNCORR_CT_L 0xf4b200ff
3481
3482/* RS_COUNTER_5 */
3483#define R367CAB_RS_COUNTER_5 0xf4b3
3484#define F367CAB_UNCORR_CT_H 0xf4b300ff
3485
3486/* BERT_0 */
3487#define R367CAB_BERT_0 0xf4b4
3488#define F367CAB_RS_NOCORR 0xf4b40004
3489#define F367CAB_CT_HOLD 0xf4b40002
3490#define F367CAB_CT_CLEAR 0xf4b40001
3491
3492/* BERT_1 */
3493#define R367CAB_BERT_1 0xf4b5
3494#define F367CAB_BERT_ON 0xf4b50020
3495#define F367CAB_BERT_ERR_SRC 0xf4b50010
3496#define F367CAB_BERT_ERR_MODE 0xf4b50008
3497#define F367CAB_BERT_NBYTE 0xf4b50007
3498
3499/* BERT_2 */
3500#define R367CAB_BERT_2 0xf4b6
3501#define F367CAB_BERT_ERRCOUNT_L 0xf4b600ff
3502
3503/* BERT_3 */
3504#define R367CAB_BERT_3 0xf4b7
3505#define F367CAB_BERT_ERRCOUNT_H 0xf4b700ff
3506
3507/* OUTFORMAT_0 */
3508#define R367CAB_OUTFORMAT_0 0xf4b8
3509#define F367CAB_CLK_POLARITY 0xf4b80080
3510#define F367CAB_FEC_TYPE 0xf4b80040
3511#define F367CAB_SYNC_STRIP 0xf4b80008
3512#define F367CAB_TS_SWAP 0xf4b80004
3513#define F367CAB_OUTFORMAT 0xf4b80003
3514
3515/* OUTFORMAT_1 */
3516#define R367CAB_OUTFORMAT_1 0xf4b9
3517#define F367CAB_CI_DIVRANGE 0xf4b900ff
3518
3519/* SMOOTHER_2 */
3520#define R367CAB_SMOOTHER_2 0xf4be
3521#define F367CAB_FIFO_BYPASS 0xf4be0020
3522
3523/* TSMF_CTRL_0 */
3524#define R367CAB_TSMF_CTRL_0 0xf4c0
3525#define F367CAB_TS_NUMBER 0xf4c0001e
3526#define F367CAB_SEL_MODE 0xf4c00001
3527
3528/* TSMF_CTRL_1 */
3529#define R367CAB_TSMF_CTRL_1 0xf4c1
3530#define F367CAB_CHECK_ERROR_BIT 0xf4c10080
3531#define F367CAB_CHCK_F_SYNC 0xf4c10040
3532#define F367CAB_H_MODE 0xf4c10008
3533#define F367CAB_D_V_MODE 0xf4c10004
3534#define F367CAB_MODE 0xf4c10003
3535
3536/* TSMF_CTRL_3 */
3537#define R367CAB_TSMF_CTRL_3 0xf4c3
3538#define F367CAB_SYNC_IN_COUNT 0xf4c300f0
3539#define F367CAB_SYNC_OUT_COUNT 0xf4c3000f
3540
3541/* TS_ON_ID_0 */
3542#define R367CAB_TS_ON_ID_0 0xf4c4
3543#define F367CAB_TS_ID_L 0xf4c400ff
3544
3545/* TS_ON_ID_1 */
3546#define R367CAB_TS_ON_ID_1 0xf4c5
3547#define F367CAB_TS_ID_H 0xf4c500ff
3548
3549/* TS_ON_ID_2 */
3550#define R367CAB_TS_ON_ID_2 0xf4c6
3551#define F367CAB_ON_ID_L 0xf4c600ff
3552
3553/* TS_ON_ID_3 */
3554#define R367CAB_TS_ON_ID_3 0xf4c7
3555#define F367CAB_ON_ID_H 0xf4c700ff
3556
3557/* RE_STATUS_0 */
3558#define R367CAB_RE_STATUS_0 0xf4c8
3559#define F367CAB_RECEIVE_STATUS_L 0xf4c800ff
3560
3561/* RE_STATUS_1 */
3562#define R367CAB_RE_STATUS_1 0xf4c9
3563#define F367CAB_RECEIVE_STATUS_LH 0xf4c900ff
3564
3565/* RE_STATUS_2 */
3566#define R367CAB_RE_STATUS_2 0xf4ca
3567#define F367CAB_RECEIVE_STATUS_HL 0xf4ca00ff
3568
3569/* RE_STATUS_3 */
3570#define R367CAB_RE_STATUS_3 0xf4cb
3571#define F367CAB_RECEIVE_STATUS_HH 0xf4cb003f
3572
3573/* TS_STATUS_0 */
3574#define R367CAB_TS_STATUS_0 0xf4cc
3575#define F367CAB_TS_STATUS_L 0xf4cc00ff
3576
3577/* TS_STATUS_1 */
3578#define R367CAB_TS_STATUS_1 0xf4cd
3579#define F367CAB_TS_STATUS_H 0xf4cd007f
3580
3581/* TS_STATUS_2 */
3582#define R367CAB_TS_STATUS_2 0xf4ce
3583#define F367CAB_ERROR 0xf4ce0080
3584#define F367CAB_EMERGENCY 0xf4ce0040
3585#define F367CAB_CRE_TS 0xf4ce0030
3586#define F367CAB_VER 0xf4ce000e
3587#define F367CAB_M_LOCK 0xf4ce0001
3588
3589/* TS_STATUS_3 */
3590#define R367CAB_TS_STATUS_3 0xf4cf
3591#define F367CAB_UPDATE_READY 0xf4cf0080
3592#define F367CAB_END_FRAME_HEADER 0xf4cf0040
3593#define F367CAB_CONTCNT 0xf4cf0020
3594#define F367CAB_TS_IDENTIFIER_SEL 0xf4cf000f
3595
3596/* T_O_ID_0 */
3597#define R367CAB_T_O_ID_0 0xf4d0
3598#define F367CAB_ON_ID_I_L 0xf4d000ff
3599
3600/* T_O_ID_1 */
3601#define R367CAB_T_O_ID_1 0xf4d1
3602#define F367CAB_ON_ID_I_H 0xf4d100ff
3603
3604/* T_O_ID_2 */
3605#define R367CAB_T_O_ID_2 0xf4d2
3606#define F367CAB_TS_ID_I_L 0xf4d200ff
3607
3608/* T_O_ID_3 */
3609#define R367CAB_T_O_ID_3 0xf4d3
3610#define F367CAB_TS_ID_I_H 0xf4d300ff
3611
3612#define STV0367CAB_NBREGS 187
3613
3614#endif
diff --git a/drivers/media/dvb/frontends/stv0900.h b/drivers/media/dvb/frontends/stv0900.h
index e3e35d1ce838..91c7ee8b2313 100644
--- a/drivers/media/dvb/frontends/stv0900.h
+++ b/drivers/media/dvb/frontends/stv0900.h
@@ -53,6 +53,8 @@ struct stv0900_config {
53 u8 tun2_type; 53 u8 tun2_type;
54 /* Set device param to start dma */ 54 /* Set device param to start dma */
55 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured); 55 int (*set_ts_params)(struct dvb_frontend *fe, int is_punctured);
56 /* Hook for Lock LED */
57 void (*set_lock_led)(struct dvb_frontend *fe, int offon);
56}; 58};
57 59
58#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \ 60#if defined(CONFIG_DVB_STV0900) || (defined(CONFIG_DVB_STV0900_MODULE) \
diff --git a/drivers/media/dvb/frontends/stv0900_core.c b/drivers/media/dvb/frontends/stv0900_core.c
index 4f5e7d3a0e61..0ca316d6fffa 100644
--- a/drivers/media/dvb/frontends/stv0900_core.c
+++ b/drivers/media/dvb/frontends/stv0900_core.c
@@ -1604,6 +1604,9 @@ static enum dvbfe_search stv0900_search(struct dvb_frontend *fe,
1604 p_search.standard = STV0900_AUTO_SEARCH; 1604 p_search.standard = STV0900_AUTO_SEARCH;
1605 p_search.iq_inversion = STV0900_IQ_AUTO; 1605 p_search.iq_inversion = STV0900_IQ_AUTO;
1606 p_search.search_algo = STV0900_BLIND_SEARCH; 1606 p_search.search_algo = STV0900_BLIND_SEARCH;
1607 /* Speeds up DVB-S searching */
1608 if (c->delivery_system == SYS_DVBS)
1609 p_search.standard = STV0900_SEARCH_DVBS1;
1607 1610
1608 intp->srch_standard[demod] = p_search.standard; 1611 intp->srch_standard[demod] = p_search.standard;
1609 intp->symbol_rate[demod] = p_search.symbol_rate; 1612 intp->symbol_rate[demod] = p_search.symbol_rate;
@@ -1660,8 +1663,14 @@ static int stv0900_read_status(struct dvb_frontend *fe, enum fe_status *status)
1660 | FE_HAS_VITERBI 1663 | FE_HAS_VITERBI
1661 | FE_HAS_SYNC 1664 | FE_HAS_SYNC
1662 | FE_HAS_LOCK; 1665 | FE_HAS_LOCK;
1663 } else 1666 if (state->config->set_lock_led)
1667 state->config->set_lock_led(fe, 1);
1668 } else {
1669 *status = 0;
1670 if (state->config->set_lock_led)
1671 state->config->set_lock_led(fe, 0);
1664 dprintk("DEMOD LOCK FAIL\n"); 1672 dprintk("DEMOD LOCK FAIL\n");
1673 }
1665 1674
1666 return 0; 1675 return 0;
1667} 1676}
@@ -1831,6 +1840,9 @@ static void stv0900_release(struct dvb_frontend *fe)
1831 1840
1832 dprintk("%s\n", __func__); 1841 dprintk("%s\n", __func__);
1833 1842
1843 if (state->config->set_lock_led)
1844 state->config->set_lock_led(fe, 0);
1845
1834 if ((--(state->internal->dmds_used)) <= 0) { 1846 if ((--(state->internal->dmds_used)) <= 0) {
1835 1847
1836 dprintk("%s: Actually removing\n", __func__); 1848 dprintk("%s: Actually removing\n", __func__);
@@ -1842,6 +1854,18 @@ static void stv0900_release(struct dvb_frontend *fe)
1842 kfree(state); 1854 kfree(state);
1843} 1855}
1844 1856
1857static int stv0900_sleep(struct dvb_frontend *fe)
1858{
1859 struct stv0900_state *state = fe->demodulator_priv;
1860
1861 dprintk("%s\n", __func__);
1862
1863 if (state->config->set_lock_led)
1864 state->config->set_lock_led(fe, 0);
1865
1866 return 0;
1867}
1868
1845static int stv0900_get_frontend(struct dvb_frontend *fe, 1869static int stv0900_get_frontend(struct dvb_frontend *fe,
1846 struct dvb_frontend_parameters *p) 1870 struct dvb_frontend_parameters *p)
1847{ 1871{
@@ -1876,6 +1900,7 @@ static struct dvb_frontend_ops stv0900_ops = {
1876 .release = stv0900_release, 1900 .release = stv0900_release,
1877 .init = stv0900_init, 1901 .init = stv0900_init,
1878 .get_frontend = stv0900_get_frontend, 1902 .get_frontend = stv0900_get_frontend,
1903 .sleep = stv0900_sleep,
1879 .get_frontend_algo = stv0900_frontend_algo, 1904 .get_frontend_algo = stv0900_frontend_algo,
1880 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl, 1905 .i2c_gate_ctrl = stv0900_i2c_gate_ctrl,
1881 .diseqc_send_master_cmd = stv0900_send_master_cmd, 1906 .diseqc_send_master_cmd = stv0900_send_master_cmd,
diff --git a/drivers/media/dvb/frontends/stv090x.c b/drivers/media/dvb/frontends/stv090x.c
index 4e0fc2c8a41c..41d0f0a6655d 100644
--- a/drivers/media/dvb/frontends/stv090x.c
+++ b/drivers/media/dvb/frontends/stv090x.c
@@ -767,8 +767,12 @@ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
767 * In case of any error, the lock is unlocked and exit within the 767 * In case of any error, the lock is unlocked and exit within the
768 * relevant operations themselves. 768 * relevant operations themselves.
769 */ 769 */
770 if (enable) 770 if (enable) {
771 mutex_lock(&state->internal->tuner_lock); 771 if (state->config->tuner_i2c_lock)
772 state->config->tuner_i2c_lock(&state->frontend, 1);
773 else
774 mutex_lock(&state->internal->tuner_lock);
775 }
772 776
773 reg = STV090x_READ_DEMOD(state, I2CRPT); 777 reg = STV090x_READ_DEMOD(state, I2CRPT);
774 if (enable) { 778 if (enable) {
@@ -784,13 +788,20 @@ static int stv090x_i2c_gate_ctrl(struct stv090x_state *state, int enable)
784 goto err; 788 goto err;
785 } 789 }
786 790
787 if (!enable) 791 if (!enable) {
788 mutex_unlock(&state->internal->tuner_lock); 792 if (state->config->tuner_i2c_lock)
793 state->config->tuner_i2c_lock(&state->frontend, 0);
794 else
795 mutex_unlock(&state->internal->tuner_lock);
796 }
789 797
790 return 0; 798 return 0;
791err: 799err:
792 dprintk(FE_ERROR, 1, "I/O error"); 800 dprintk(FE_ERROR, 1, "I/O error");
793 mutex_unlock(&state->internal->tuner_lock); 801 if (state->config->tuner_i2c_lock)
802 state->config->tuner_i2c_lock(&state->frontend, 0);
803 else
804 mutex_unlock(&state->internal->tuner_lock);
794 return -1; 805 return -1;
795} 806}
796 807
@@ -2883,10 +2894,12 @@ static int stv090x_optimize_track(struct stv090x_state *state)
2883 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1); 2894 STV090x_SETFIELD_Px(reg, DVBS2_ENABLE_FIELD, 1);
2884 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0) 2895 if (STV090x_WRITE_DEMOD(state, DMDCFGMD, reg) < 0)
2885 goto err; 2896 goto err;
2886 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0) 2897 if (state->internal->dev_ver >= 0x30) {
2887 goto err; 2898 if (STV090x_WRITE_DEMOD(state, ACLC, 0) < 0)
2888 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0) 2899 goto err;
2889 goto err; 2900 if (STV090x_WRITE_DEMOD(state, BCLC, 0) < 0)
2901 goto err;
2902 }
2890 if (state->frame_len == STV090x_LONG_FRAME) { 2903 if (state->frame_len == STV090x_LONG_FRAME) {
2891 reg = STV090x_READ_DEMOD(state, DMDMODCOD); 2904 reg = STV090x_READ_DEMOD(state, DMDMODCOD);
2892 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD); 2905 modcod = STV090x_GETFIELD_Px(reg, DEMOD_MODCOD_FIELD);
@@ -3846,6 +3859,7 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3846{ 3859{
3847 struct stv090x_state *state = fe->demodulator_priv; 3860 struct stv090x_state *state = fe->demodulator_priv;
3848 u32 reg; 3861 u32 reg;
3862 u8 full_standby = 0;
3849 3863
3850 if (stv090x_i2c_gate_ctrl(state, 1) < 0) 3864 if (stv090x_i2c_gate_ctrl(state, 1) < 0)
3851 goto err; 3865 goto err;
@@ -3858,24 +3872,119 @@ static int stv090x_sleep(struct dvb_frontend *fe)
3858 if (stv090x_i2c_gate_ctrl(state, 0) < 0) 3872 if (stv090x_i2c_gate_ctrl(state, 0) < 0)
3859 goto err; 3873 goto err;
3860 3874
3861 dprintk(FE_DEBUG, 1, "Set %s to sleep", 3875 dprintk(FE_DEBUG, 1, "Set %s(%d) to sleep",
3862 state->device == STV0900 ? "STV0900" : "STV0903"); 3876 state->device == STV0900 ? "STV0900" : "STV0903",
3877 state->demod);
3863 3878
3864 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 3879 mutex_lock(&state->internal->demod_lock);
3865 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3866 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3867 goto err;
3868 3880
3869 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 3881 switch (state->demod) {
3870 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0); 3882 case STV090x_DEMODULATOR_0:
3871 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 3883 /* power off ADC 1 */
3872 goto err; 3884 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3885 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 0);
3886 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
3887 goto err;
3888 /* power off DiSEqC 1 */
3889 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
3890 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 0);
3891 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
3892 goto err;
3893
3894 /* check whether path 2 is already sleeping, that is when
3895 ADC2 is off */
3896 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3897 if (STV090x_GETFIELD(reg, ADC2_PON_FIELD) == 0)
3898 full_standby = 1;
3899
3900 /* stop clocks */
3901 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3902 /* packet delineator 1 clock */
3903 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 1);
3904 /* ADC 1 clock */
3905 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 1);
3906 /* FEC clock is shared between the two paths, only stop it
3907 when full standby is possible */
3908 if (full_standby)
3909 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3910 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3911 goto err;
3912 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3913 /* sampling 1 clock */
3914 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 1);
3915 /* viterbi 1 clock */
3916 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 1);
3917 /* TS clock is shared between the two paths, only stop it
3918 when full standby is possible */
3919 if (full_standby)
3920 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3921 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3922 goto err;
3923 break;
3924
3925 case STV090x_DEMODULATOR_1:
3926 /* power off ADC 2 */
3927 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
3928 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 0);
3929 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
3930 goto err;
3931 /* power off DiSEqC 2 */
3932 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
3933 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 0);
3934 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
3935 goto err;
3936
3937 /* check whether path 1 is already sleeping, that is when
3938 ADC1 is off */
3939 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
3940 if (STV090x_GETFIELD(reg, ADC1_PON_FIELD) == 0)
3941 full_standby = 1;
3942
3943 /* stop clocks */
3944 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
3945 /* packet delineator 2 clock */
3946 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 1);
3947 /* ADC 2 clock */
3948 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 1);
3949 /* FEC clock is shared between the two paths, only stop it
3950 when full standby is possible */
3951 if (full_standby)
3952 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 1);
3953 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
3954 goto err;
3955 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
3956 /* sampling 2 clock */
3957 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 1);
3958 /* viterbi 2 clock */
3959 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 1);
3960 /* TS clock is shared between the two paths, only stop it
3961 when full standby is possible */
3962 if (full_standby)
3963 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 1);
3964 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
3965 goto err;
3966 break;
3873 3967
3968 default:
3969 dprintk(FE_ERROR, 1, "Wrong demodulator!");
3970 break;
3971 }
3972
3973 if (full_standby) {
3974 /* general power off */
3975 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3976 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x01);
3977 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3978 goto err;
3979 }
3980
3981 mutex_unlock(&state->internal->demod_lock);
3874 return 0; 3982 return 0;
3875 3983
3876err_gateoff: 3984err_gateoff:
3877 stv090x_i2c_gate_ctrl(state, 0); 3985 stv090x_i2c_gate_ctrl(state, 0);
3878err: 3986err:
3987 mutex_unlock(&state->internal->demod_lock);
3879 dprintk(FE_ERROR, 1, "I/O error"); 3988 dprintk(FE_ERROR, 1, "I/O error");
3880 return -1; 3989 return -1;
3881} 3990}
@@ -3885,21 +3994,94 @@ static int stv090x_wakeup(struct dvb_frontend *fe)
3885 struct stv090x_state *state = fe->demodulator_priv; 3994 struct stv090x_state *state = fe->demodulator_priv;
3886 u32 reg; 3995 u32 reg;
3887 3996
3888 dprintk(FE_DEBUG, 1, "Wake %s from standby", 3997 dprintk(FE_DEBUG, 1, "Wake %s(%d) from standby",
3889 state->device == STV0900 ? "STV0900" : "STV0903"); 3998 state->device == STV0900 ? "STV0900" : "STV0903",
3999 state->demod);
4000
4001 mutex_lock(&state->internal->demod_lock);
3890 4002
4003 /* general power on */
3891 reg = stv090x_read_reg(state, STV090x_SYNTCTRL); 4004 reg = stv090x_read_reg(state, STV090x_SYNTCTRL);
3892 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00); 4005 STV090x_SETFIELD(reg, STANDBY_FIELD, 0x00);
3893 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0) 4006 if (stv090x_write_reg(state, STV090x_SYNTCTRL, reg) < 0)
3894 goto err; 4007 goto err;
3895 4008
3896 reg = stv090x_read_reg(state, STV090x_TSTTNR1); 4009 switch (state->demod) {
3897 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1); 4010 case STV090x_DEMODULATOR_0:
3898 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0) 4011 /* power on ADC 1 */
3899 goto err; 4012 reg = stv090x_read_reg(state, STV090x_TSTTNR1);
4013 STV090x_SETFIELD(reg, ADC1_PON_FIELD, 1);
4014 if (stv090x_write_reg(state, STV090x_TSTTNR1, reg) < 0)
4015 goto err;
4016 /* power on DiSEqC 1 */
4017 reg = stv090x_read_reg(state, STV090x_TSTTNR2);
4018 STV090x_SETFIELD(reg, DISEQC1_PON_FIELD, 1);
4019 if (stv090x_write_reg(state, STV090x_TSTTNR2, reg) < 0)
4020 goto err;
4021
4022 /* activate clocks */
4023 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4024 /* packet delineator 1 clock */
4025 STV090x_SETFIELD(reg, STOP_CLKPKDT1_FIELD, 0);
4026 /* ADC 1 clock */
4027 STV090x_SETFIELD(reg, STOP_CLKADCI1_FIELD, 0);
4028 /* FEC clock */
4029 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4030 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4031 goto err;
4032 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4033 /* sampling 1 clock */
4034 STV090x_SETFIELD(reg, STOP_CLKSAMP1_FIELD, 0);
4035 /* viterbi 1 clock */
4036 STV090x_SETFIELD(reg, STOP_CLKVIT1_FIELD, 0);
4037 /* TS clock */
4038 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4039 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4040 goto err;
4041 break;
3900 4042
4043 case STV090x_DEMODULATOR_1:
4044 /* power on ADC 2 */
4045 reg = stv090x_read_reg(state, STV090x_TSTTNR3);
4046 STV090x_SETFIELD(reg, ADC2_PON_FIELD, 1);
4047 if (stv090x_write_reg(state, STV090x_TSTTNR3, reg) < 0)
4048 goto err;
4049 /* power on DiSEqC 2 */
4050 reg = stv090x_read_reg(state, STV090x_TSTTNR4);
4051 STV090x_SETFIELD(reg, DISEQC2_PON_FIELD, 1);
4052 if (stv090x_write_reg(state, STV090x_TSTTNR4, reg) < 0)
4053 goto err;
4054
4055 /* activate clocks */
4056 reg = stv090x_read_reg(state, STV090x_STOPCLK1);
4057 /* packet delineator 2 clock */
4058 STV090x_SETFIELD(reg, STOP_CLKPKDT2_FIELD, 0);
4059 /* ADC 2 clock */
4060 STV090x_SETFIELD(reg, STOP_CLKADCI2_FIELD, 0);
4061 /* FEC clock */
4062 STV090x_SETFIELD(reg, STOP_CLKFEC_FIELD, 0);
4063 if (stv090x_write_reg(state, STV090x_STOPCLK1, reg) < 0)
4064 goto err;
4065 reg = stv090x_read_reg(state, STV090x_STOPCLK2);
4066 /* sampling 2 clock */
4067 STV090x_SETFIELD(reg, STOP_CLKSAMP2_FIELD, 0);
4068 /* viterbi 2 clock */
4069 STV090x_SETFIELD(reg, STOP_CLKVIT2_FIELD, 0);
4070 /* TS clock */
4071 STV090x_SETFIELD(reg, STOP_CLKTS_FIELD, 0);
4072 if (stv090x_write_reg(state, STV090x_STOPCLK2, reg) < 0)
4073 goto err;
4074 break;
4075
4076 default:
4077 dprintk(FE_ERROR, 1, "Wrong demodulator!");
4078 break;
4079 }
4080
4081 mutex_unlock(&state->internal->demod_lock);
3901 return 0; 4082 return 0;
3902err: 4083err:
4084 mutex_unlock(&state->internal->demod_lock);
3903 dprintk(FE_ERROR, 1, "I/O error"); 4085 dprintk(FE_ERROR, 1, "I/O error");
3904 return -1; 4086 return -1;
3905} 4087}
@@ -4169,6 +4351,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4169 switch (state->config->ts1_mode) { 4351 switch (state->config->ts1_mode) {
4170 case STV090x_TSMODE_PARALLEL_PUNCTURED: 4352 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4171 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4353 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4354 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4172 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4355 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4173 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4356 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4174 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4357 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4177,6 +4360,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4177 4360
4178 case STV090x_TSMODE_DVBCI: 4361 case STV090x_TSMODE_DVBCI:
4179 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4362 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4363 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4180 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4364 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4181 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4365 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4182 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4366 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4185,6 +4369,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4185 4369
4186 case STV090x_TSMODE_SERIAL_PUNCTURED: 4370 case STV090x_TSMODE_SERIAL_PUNCTURED:
4187 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4371 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4372 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4188 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4373 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4189 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4374 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4190 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4375 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4193,6 +4378,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4193 4378
4194 case STV090x_TSMODE_SERIAL_CONTINUOUS: 4379 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4195 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH); 4380 reg = stv090x_read_reg(state, STV090x_P1_TSCFGH);
4381 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts1_tei);
4196 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4382 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4197 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4383 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4198 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0) 4384 if (stv090x_write_reg(state, STV090x_P1_TSCFGH, reg) < 0)
@@ -4206,6 +4392,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4206 switch (state->config->ts2_mode) { 4392 switch (state->config->ts2_mode) {
4207 case STV090x_TSMODE_PARALLEL_PUNCTURED: 4393 case STV090x_TSMODE_PARALLEL_PUNCTURED:
4208 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4394 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4395 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4209 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4396 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4210 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4397 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4211 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4398 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4214,6 +4401,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4214 4401
4215 case STV090x_TSMODE_DVBCI: 4402 case STV090x_TSMODE_DVBCI:
4216 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4403 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4404 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4217 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00); 4405 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x00);
4218 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4406 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4219 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4407 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4222,6 +4410,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4222 4410
4223 case STV090x_TSMODE_SERIAL_PUNCTURED: 4411 case STV090x_TSMODE_SERIAL_PUNCTURED:
4224 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4412 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4413 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4225 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4414 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4226 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00); 4415 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x00);
4227 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4416 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4230,6 +4419,7 @@ static int stv090x_set_tspath(struct stv090x_state *state)
4230 4419
4231 case STV090x_TSMODE_SERIAL_CONTINUOUS: 4420 case STV090x_TSMODE_SERIAL_CONTINUOUS:
4232 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH); 4421 reg = stv090x_read_reg(state, STV090x_P2_TSCFGH);
4422 STV090x_SETFIELD_Px(reg, TSFIFO_TEIUPDATE_FIELD, state->config->ts2_tei);
4233 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01); 4423 STV090x_SETFIELD_Px(reg, TSFIFO_SERIAL_FIELD, 0x01);
4234 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01); 4424 STV090x_SETFIELD_Px(reg, TSFIFO_DVBCI_FIELD, 0x01);
4235 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0) 4425 if (stv090x_write_reg(state, STV090x_P2_TSCFGH, reg) < 0)
@@ -4506,16 +4696,26 @@ static int stv090x_setup(struct dvb_frontend *fe)
4506 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0) 4696 if (stv090x_write_reg(state, STV090x_TSTRES0, 0x00) < 0)
4507 goto err; 4697 goto err;
4508 4698
4509 /* workaround for stuck DiSEqC output */
4510 if (config->diseqc_envelope_mode)
4511 stv090x_send_diseqc_burst(fe, SEC_MINI_A);
4512
4513 return 0; 4699 return 0;
4514err: 4700err:
4515 dprintk(FE_ERROR, 1, "I/O error"); 4701 dprintk(FE_ERROR, 1, "I/O error");
4516 return -1; 4702 return -1;
4517} 4703}
4518 4704
4705int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio, u8 dir, u8 value,
4706 u8 xor_value)
4707{
4708 struct stv090x_state *state = fe->demodulator_priv;
4709 u8 reg = 0;
4710
4711 STV090x_SETFIELD(reg, GPIOx_OPD_FIELD, dir);
4712 STV090x_SETFIELD(reg, GPIOx_CONFIG_FIELD, value);
4713 STV090x_SETFIELD(reg, GPIOx_XOR_FIELD, xor_value);
4714
4715 return stv090x_write_reg(state, STV090x_GPIOxCFG(gpio), reg);
4716}
4717EXPORT_SYMBOL(stv090x_set_gpio);
4718
4519static struct dvb_frontend_ops stv090x_ops = { 4719static struct dvb_frontend_ops stv090x_ops = {
4520 4720
4521 .info = { 4721 .info = {
@@ -4580,39 +4780,35 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4580 state->internal = temp_int->internal; 4780 state->internal = temp_int->internal;
4581 state->internal->num_used++; 4781 state->internal->num_used++;
4582 dprintk(FE_INFO, 1, "Found Internal Structure!"); 4782 dprintk(FE_INFO, 1, "Found Internal Structure!");
4583 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4584 state->device == STV0900 ? "STV0900" : "STV0903",
4585 demod,
4586 state->internal->dev_ver);
4587 return &state->frontend;
4588 } else { 4783 } else {
4589 state->internal = kmalloc(sizeof(struct stv090x_internal), 4784 state->internal = kmalloc(sizeof(struct stv090x_internal),
4590 GFP_KERNEL); 4785 GFP_KERNEL);
4786 if (!state->internal)
4787 goto error;
4591 temp_int = append_internal(state->internal); 4788 temp_int = append_internal(state->internal);
4789 if (!temp_int) {
4790 kfree(state->internal);
4791 goto error;
4792 }
4592 state->internal->num_used = 1; 4793 state->internal->num_used = 1;
4593 state->internal->mclk = 0; 4794 state->internal->mclk = 0;
4594 state->internal->dev_ver = 0; 4795 state->internal->dev_ver = 0;
4595 state->internal->i2c_adap = state->i2c; 4796 state->internal->i2c_adap = state->i2c;
4596 state->internal->i2c_addr = state->config->address; 4797 state->internal->i2c_addr = state->config->address;
4597 dprintk(FE_INFO, 1, "Create New Internal Structure!"); 4798 dprintk(FE_INFO, 1, "Create New Internal Structure!");
4598 }
4599 4799
4600 mutex_init(&state->internal->demod_lock); 4800 mutex_init(&state->internal->demod_lock);
4601 mutex_init(&state->internal->tuner_lock); 4801 mutex_init(&state->internal->tuner_lock);
4602 4802
4603 if (stv090x_sleep(&state->frontend) < 0) { 4803 if (stv090x_setup(&state->frontend) < 0) {
4604 dprintk(FE_ERROR, 1, "Error putting device to sleep"); 4804 dprintk(FE_ERROR, 1, "Error setting up device");
4605 goto error; 4805 goto err_remove;
4806 }
4606 } 4807 }
4607 4808
4608 if (stv090x_setup(&state->frontend) < 0) { 4809 /* workaround for stuck DiSEqC output */
4609 dprintk(FE_ERROR, 1, "Error setting up device"); 4810 if (config->diseqc_envelope_mode)
4610 goto error; 4811 stv090x_send_diseqc_burst(&state->frontend, SEC_MINI_A);
4611 }
4612 if (stv090x_wakeup(&state->frontend) < 0) {
4613 dprintk(FE_ERROR, 1, "Error waking device");
4614 goto error;
4615 }
4616 4812
4617 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x", 4813 dprintk(FE_ERROR, 1, "Attaching %s demodulator(%d) Cut=0x%02x",
4618 state->device == STV0900 ? "STV0900" : "STV0903", 4814 state->device == STV0900 ? "STV0900" : "STV0903",
@@ -4621,6 +4817,9 @@ struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
4621 4817
4622 return &state->frontend; 4818 return &state->frontend;
4623 4819
4820err_remove:
4821 remove_dev(state->internal);
4822 kfree(state->internal);
4624error: 4823error:
4625 kfree(state); 4824 kfree(state);
4626 return NULL; 4825 return NULL;
diff --git a/drivers/media/dvb/frontends/stv090x.h b/drivers/media/dvb/frontends/stv090x.h
index dd1b93ae4e9d..29cdc2b71314 100644
--- a/drivers/media/dvb/frontends/stv090x.h
+++ b/drivers/media/dvb/frontends/stv090x.h
@@ -78,6 +78,9 @@ struct stv090x_config {
78 u32 ts1_clk; 78 u32 ts1_clk;
79 u32 ts2_clk; 79 u32 ts2_clk;
80 80
81 u8 ts1_tei : 1;
82 u8 ts2_tei : 1;
83
81 enum stv090x_i2crpt repeater_level; 84 enum stv090x_i2crpt repeater_level;
82 85
83 u8 tuner_bbgain; /* default: 10db */ 86 u8 tuner_bbgain; /* default: 10db */
@@ -97,6 +100,7 @@ struct stv090x_config {
97 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain); 100 int (*tuner_get_bbgain) (struct dvb_frontend *fe, u32 *gain);
98 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk); 101 int (*tuner_set_refclk) (struct dvb_frontend *fe, u32 refclk);
99 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status); 102 int (*tuner_get_status) (struct dvb_frontend *fe, u32 *status);
103 void (*tuner_i2c_lock) (struct dvb_frontend *fe, int lock);
100}; 104};
101 105
102#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE)) 106#if defined(CONFIG_DVB_STV090x) || (defined(CONFIG_DVB_STV090x_MODULE) && defined(MODULE))
@@ -104,6 +108,11 @@ struct stv090x_config {
104extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, 108extern struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
105 struct i2c_adapter *i2c, 109 struct i2c_adapter *i2c,
106 enum stv090x_demodulator demod); 110 enum stv090x_demodulator demod);
111
112/* dir = 0 -> output, dir = 1 -> input/open-drain */
113extern int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
114 u8 dir, u8 value, u8 xor_value);
115
107#else 116#else
108 117
109static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config, 118static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *config,
@@ -113,6 +122,13 @@ static inline struct dvb_frontend *stv090x_attach(const struct stv090x_config *c
113 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__); 122 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
114 return NULL; 123 return NULL;
115} 124}
125
126static inline int stv090x_set_gpio(struct dvb_frontend *fe, u8 gpio,
127 u8 opd, u8 value, u8 xor_value)
128{
129 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
130 return -ENODEV;
131}
116#endif /* CONFIG_DVB_STV090x */ 132#endif /* CONFIG_DVB_STV090x */
117 133
118#endif /* __STV090x_H */ 134#endif /* __STV090x_H */
diff --git a/drivers/media/dvb/frontends/stv090x_reg.h b/drivers/media/dvb/frontends/stv090x_reg.h
index 2502855dd784..93741ee14297 100644
--- a/drivers/media/dvb/frontends/stv090x_reg.h
+++ b/drivers/media/dvb/frontends/stv090x_reg.h
@@ -1327,10 +1327,10 @@
1327#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8 1327#define STV090x_WIDTH_Px_NOSPLHT_UNNORMED_FIELD 8
1328 1328
1329#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1) 1329#define STV090x_Px_NOSPLHy(__x, __y) (0xf48f - (__x - 1) * 0x200 - __y * 0x1)
1330#define STv090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0) 1330#define STV090x_P1_NOSPLH0 STV090x_Px_NOSPLHy(1, 0)
1331#define STv090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1) 1331#define STV090x_P1_NOSPLH1 STV090x_Px_NOSPLHy(1, 1)
1332#define STv090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0) 1332#define STV090x_P2_NOSPLH0 STV090x_Px_NOSPLHy(2, 0)
1333#define STv090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1) 1333#define STV090x_P2_NOSPLH1 STV090x_Px_NOSPLHy(2, 1)
1334#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0 1334#define STV090x_OFFST_Px_NOSPLH_UNNORMED_FIELD 0
1335#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8 1335#define STV090x_WIDTH_Px_NOSPLH_UNNORMED_FIELD 8
1336 1336
@@ -1406,7 +1406,7 @@
1406 1406
1407#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200) 1407#define STV090x_Px_BCLC2S28(__x) (0xf49d - (__x - 1) * 0x200)
1408#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1) 1408#define STV090x_P1_BCLC2S28 STV090x_Px_BCLC2S28(1)
1409#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(1) 1409#define STV090x_P2_BCLC2S28 STV090x_Px_BCLC2S28(2)
1410#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4 1410#define STV090x_OFFST_Px_CAR2S2_8_BETA_M_FIELD 4
1411#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2 1411#define STV090x_WIDTH_Px_CAR2S2_8_BETA_M_FIELD 2
1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0 1412#define STV090x_OFFST_Px_CAR2S2_8_BETA_E_FIELD 0
@@ -1414,7 +1414,7 @@
1414 1414
1415#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200) 1415#define STV090x_Px_BCLC2S216A(__x) (0xf49e - (__x - 1) * 0x200)
1416#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1) 1416#define STV090x_P1_BCLC2S216A STV090x_Px_BCLC2S216A(1)
1417#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(1) 1417#define STV090x_P2_BCLC2S216A STV090x_Px_BCLC2S216A(2)
1418#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4 1418#define STV090x_OFFST_Px_CAR2S2_16A_BETA_M_FIELD 4
1419#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2 1419#define STV090x_WIDTH_Px_CAR2S2_16A_BETA_M_FIELD 2
1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0 1420#define STV090x_OFFST_Px_CAR2S2_16A_BETA_E_FIELD 0
@@ -1422,7 +1422,7 @@
1422 1422
1423#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200) 1423#define STV090x_Px_BCLC2S232A(__x) (0xf49f - (__x - 1) * 0x200)
1424#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1) 1424#define STV090x_P1_BCLC2S232A STV090x_Px_BCLC2S232A(1)
1425#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(1) 1425#define STV090x_P2_BCLC2S232A STV090x_Px_BCLC2S232A(2)
1426#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4 1426#define STV090x_OFFST_Px_CAR2S2_32A_BETA_M_FIELD 4
1427#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2 1427#define STV090x_WIDTH_Px_CAR2S2_32A_BETA_M_FIELD 2
1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0 1428#define STV090x_OFFST_Px_CAR2S2_32A_BETA_E_FIELD 0
@@ -1602,7 +1602,7 @@
1602 1602
1603#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200) 1603#define STV090x_Px_CCIACC(__x) (0xf4c4 - (__x - 1) * 0x200)
1604#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1) 1604#define STV090x_P1_CCIACC STV090x_Px_CCIACC(1)
1605#define STV090x_P2_CCIACC STV090x_Px_CCIACC(1) 1605#define STV090x_P2_CCIACC STV090x_Px_CCIACC(2)
1606#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0 1606#define STV090x_OFFST_Px_CCI_VALUE_FIELD 0
1607#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8 1607#define STV090x_WIDTH_Px_CCI_VALUE_FIELD 8
1608 1608
diff --git a/drivers/media/dvb/frontends/zl10036.c b/drivers/media/dvb/frontends/zl10036.c
index 4627f491656b..81aa984c551f 100644
--- a/drivers/media/dvb/frontends/zl10036.c
+++ b/drivers/media/dvb/frontends/zl10036.c
@@ -463,16 +463,16 @@ struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
463 const struct zl10036_config *config, 463 const struct zl10036_config *config,
464 struct i2c_adapter *i2c) 464 struct i2c_adapter *i2c)
465{ 465{
466 struct zl10036_state *state = NULL; 466 struct zl10036_state *state;
467 int ret; 467 int ret;
468 468
469 if (NULL == config) { 469 if (!config) {
470 printk(KERN_ERR "%s: no config specified", __func__); 470 printk(KERN_ERR "%s: no config specified", __func__);
471 goto error; 471 return NULL;
472 } 472 }
473 473
474 state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL); 474 state = kzalloc(sizeof(struct zl10036_state), GFP_KERNEL);
475 if (NULL == state) 475 if (!state)
476 return NULL; 476 return NULL;
477 477
478 state->config = config; 478 state->config = config;
@@ -507,7 +507,7 @@ struct dvb_frontend *zl10036_attach(struct dvb_frontend *fe,
507 return fe; 507 return fe;
508 508
509error: 509error:
510 zl10036_release(fe); 510 kfree(state);
511 return NULL; 511 return NULL;
512} 512}
513EXPORT_SYMBOL(zl10036_attach); 513EXPORT_SYMBOL(zl10036_attach);
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
index 0608aabb14ee..2bc96874d044 100644
--- a/drivers/media/dvb/ngene/Makefile
+++ b/drivers/media/dvb/ngene/Makefile
@@ -9,3 +9,6 @@ obj-$(CONFIG_DVB_NGENE) += ngene.o
9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/ 9EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/ 10EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
11EXTRA_CFLAGS += -Idrivers/media/common/tuners/ 11EXTRA_CFLAGS += -Idrivers/media/common/tuners/
12
13# For the staging CI driver cxd2099
14EXTRA_CFLAGS += -Idrivers/staging/cxd2099/
diff --git a/drivers/media/dvb/ngene/ngene-cards.c b/drivers/media/dvb/ngene/ngene-cards.c
index 4692a41ad95b..fcf4be901ec8 100644
--- a/drivers/media/dvb/ngene/ngene-cards.c
+++ b/drivers/media/dvb/ngene/ngene-cards.c
@@ -48,20 +48,27 @@
48 48
49static int tuner_attach_stv6110(struct ngene_channel *chan) 49static int tuner_attach_stv6110(struct ngene_channel *chan)
50{ 50{
51 struct i2c_adapter *i2c;
51 struct stv090x_config *feconf = (struct stv090x_config *) 52 struct stv090x_config *feconf = (struct stv090x_config *)
52 chan->dev->card_info->fe_config[chan->number]; 53 chan->dev->card_info->fe_config[chan->number];
53 struct stv6110x_config *tunerconf = (struct stv6110x_config *) 54 struct stv6110x_config *tunerconf = (struct stv6110x_config *)
54 chan->dev->card_info->tuner_config[chan->number]; 55 chan->dev->card_info->tuner_config[chan->number];
55 struct stv6110x_devctl *ctl; 56 struct stv6110x_devctl *ctl;
56 57
57 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, 58 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
58 &chan->i2c_adapter); 59 if (chan->number < 2)
60 i2c = &chan->dev->channel[0].i2c_adapter;
61 else
62 i2c = &chan->dev->channel[1].i2c_adapter;
63
64 ctl = dvb_attach(stv6110x_attach, chan->fe, tunerconf, i2c);
59 if (ctl == NULL) { 65 if (ctl == NULL) {
60 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n"); 66 printk(KERN_ERR DEVICE_NAME ": No STV6110X found!\n");
61 return -ENODEV; 67 return -ENODEV;
62 } 68 }
63 69
64 feconf->tuner_init = ctl->tuner_init; 70 feconf->tuner_init = ctl->tuner_init;
71 feconf->tuner_sleep = ctl->tuner_sleep;
65 feconf->tuner_set_mode = ctl->tuner_set_mode; 72 feconf->tuner_set_mode = ctl->tuner_set_mode;
66 feconf->tuner_set_frequency = ctl->tuner_set_frequency; 73 feconf->tuner_set_frequency = ctl->tuner_set_frequency;
67 feconf->tuner_get_frequency = ctl->tuner_get_frequency; 74 feconf->tuner_get_frequency = ctl->tuner_get_frequency;
@@ -78,29 +85,106 @@ static int tuner_attach_stv6110(struct ngene_channel *chan)
78 85
79static int demod_attach_stv0900(struct ngene_channel *chan) 86static int demod_attach_stv0900(struct ngene_channel *chan)
80{ 87{
88 struct i2c_adapter *i2c;
81 struct stv090x_config *feconf = (struct stv090x_config *) 89 struct stv090x_config *feconf = (struct stv090x_config *)
82 chan->dev->card_info->fe_config[chan->number]; 90 chan->dev->card_info->fe_config[chan->number];
83 91
84 chan->fe = dvb_attach(stv090x_attach, 92 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
85 feconf, 93 /* Note: Both adapters share the same i2c bus, but the demod */
86 &chan->i2c_adapter, 94 /* driver requires that each demod has its own i2c adapter */
87 chan->number == 0 ? STV090x_DEMODULATOR_0 : 95 if (chan->number < 2)
88 STV090x_DEMODULATOR_1); 96 i2c = &chan->dev->channel[0].i2c_adapter;
97 else
98 i2c = &chan->dev->channel[1].i2c_adapter;
99
100 chan->fe = dvb_attach(stv090x_attach, feconf, i2c,
101 (chan->number & 1) == 0 ? STV090x_DEMODULATOR_0
102 : STV090x_DEMODULATOR_1);
89 if (chan->fe == NULL) { 103 if (chan->fe == NULL) {
90 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n"); 104 printk(KERN_ERR DEVICE_NAME ": No STV0900 found!\n");
91 return -ENODEV; 105 return -ENODEV;
92 } 106 }
93 107
94 if (!dvb_attach(lnbh24_attach, chan->fe, &chan->i2c_adapter, 0, 108 /* store channel info */
109 if (feconf->tuner_i2c_lock)
110 chan->fe->analog_demod_priv = chan;
111
112 if (!dvb_attach(lnbh24_attach, chan->fe, i2c, 0,
95 0, chan->dev->card_info->lnb[chan->number])) { 113 0, chan->dev->card_info->lnb[chan->number])) {
96 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n"); 114 printk(KERN_ERR DEVICE_NAME ": No LNBH24 found!\n");
97 dvb_frontend_detach(chan->fe); 115 dvb_frontend_detach(chan->fe);
116 chan->fe = NULL;
117 return -ENODEV;
118 }
119
120 return 0;
121}
122
123static void cineS2_tuner_i2c_lock(struct dvb_frontend *fe, int lock)
124{
125 struct ngene_channel *chan = fe->analog_demod_priv;
126
127 if (lock)
128 down(&chan->dev->pll_mutex);
129 else
130 up(&chan->dev->pll_mutex);
131}
132
133static int cineS2_probe(struct ngene_channel *chan)
134{
135 struct i2c_adapter *i2c;
136 struct stv090x_config *fe_conf;
137 u8 buf[3];
138 struct i2c_msg i2c_msg = { .flags = 0, .buf = buf };
139 int rc;
140
141 /* tuner 1+2: i2c adapter #0, tuner 3+4: i2c adapter #1 */
142 if (chan->number < 2)
143 i2c = &chan->dev->channel[0].i2c_adapter;
144 else
145 i2c = &chan->dev->channel[1].i2c_adapter;
146
147 fe_conf = chan->dev->card_info->fe_config[chan->number];
148 i2c_msg.addr = fe_conf->address;
149
150 /* probe demod */
151 i2c_msg.len = 2;
152 buf[0] = 0xf1;
153 buf[1] = 0x00;
154 rc = i2c_transfer(i2c, &i2c_msg, 1);
155 if (rc != 1)
156 return -ENODEV;
157
158 /* demod found, attach it */
159 rc = demod_attach_stv0900(chan);
160 if (rc < 0 || chan->number < 2)
161 return rc;
162
163 /* demod #2: reprogram outputs DPN1 & DPN2 */
164 i2c_msg.len = 3;
165 buf[0] = 0xf1;
166 switch (chan->number) {
167 case 2:
168 buf[1] = 0x5c;
169 buf[2] = 0xc2;
170 break;
171 case 3:
172 buf[1] = 0x61;
173 buf[2] = 0xcc;
174 break;
175 default:
98 return -ENODEV; 176 return -ENODEV;
99 } 177 }
178 rc = i2c_transfer(i2c, &i2c_msg, 1);
179 if (rc != 1) {
180 printk(KERN_ERR DEVICE_NAME ": could not setup DPNx\n");
181 return -EIO;
182 }
100 183
101 return 0; 184 return 0;
102} 185}
103 186
187
104static struct lgdt330x_config aver_m780 = { 188static struct lgdt330x_config aver_m780 = {
105 .demod_address = 0xb2 >> 1, 189 .demod_address = 0xb2 >> 1,
106 .demod_chip = LGDT3303, 190 .demod_chip = LGDT3303,
@@ -151,6 +235,29 @@ static struct stv090x_config fe_cineS2 = {
151 .adc2_range = STV090x_ADC_1Vpp, 235 .adc2_range = STV090x_ADC_1Vpp,
152 236
153 .diseqc_envelope_mode = true, 237 .diseqc_envelope_mode = true,
238
239 .tuner_i2c_lock = cineS2_tuner_i2c_lock,
240};
241
242static struct stv090x_config fe_cineS2_2 = {
243 .device = STV0900,
244 .demod_mode = STV090x_DUAL,
245 .clk_mode = STV090x_CLK_EXT,
246
247 .xtal = 27000000,
248 .address = 0x69,
249
250 .ts1_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
251 .ts2_mode = STV090x_TSMODE_SERIAL_PUNCTURED,
252
253 .repeater_level = STV090x_RPTLEVEL_16,
254
255 .adc1_range = STV090x_ADC_1Vpp,
256 .adc2_range = STV090x_ADC_1Vpp,
257
258 .diseqc_envelope_mode = true,
259
260 .tuner_i2c_lock = cineS2_tuner_i2c_lock,
154}; 261};
155 262
156static struct stv6110x_config tuner_cineS2_0 = { 263static struct stv6110x_config tuner_cineS2_0 = {
@@ -175,7 +282,8 @@ static struct ngene_info ngene_info_cineS2 = {
175 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 282 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
176 .lnb = {0x0b, 0x08}, 283 .lnb = {0x0b, 0x08},
177 .tsf = {3, 3}, 284 .tsf = {3, 3},
178 .fw_version = 15, 285 .fw_version = 18,
286 .msi_supported = true,
179}; 287};
180 288
181static struct ngene_info ngene_info_satixS2 = { 289static struct ngene_info ngene_info_satixS2 = {
@@ -188,46 +296,54 @@ static struct ngene_info ngene_info_satixS2 = {
188 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 296 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1},
189 .lnb = {0x0b, 0x08}, 297 .lnb = {0x0b, 0x08},
190 .tsf = {3, 3}, 298 .tsf = {3, 3},
191 .fw_version = 15, 299 .fw_version = 18,
300 .msi_supported = true,
192}; 301};
193 302
194static struct ngene_info ngene_info_satixS2v2 = { 303static struct ngene_info ngene_info_satixS2v2 = {
195 .type = NGENE_SIDEWINDER, 304 .type = NGENE_SIDEWINDER,
196 .name = "Mystique SaTiX-S2 Dual (v2)", 305 .name = "Mystique SaTiX-S2 Dual (v2)",
197 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 306 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
198 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 307 NGENE_IO_TSOUT},
199 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 308 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
200 .fe_config = {&fe_cineS2, &fe_cineS2}, 309 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
201 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 310 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
202 .lnb = {0x0a, 0x08}, 311 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
312 .lnb = {0x0a, 0x08, 0x0b, 0x09},
203 .tsf = {3, 3}, 313 .tsf = {3, 3},
204 .fw_version = 15, 314 .fw_version = 18,
315 .msi_supported = true,
205}; 316};
206 317
207static struct ngene_info ngene_info_cineS2v5 = { 318static struct ngene_info ngene_info_cineS2v5 = {
208 .type = NGENE_SIDEWINDER, 319 .type = NGENE_SIDEWINDER,
209 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)", 320 .name = "Linux4Media cineS2 DVB-S2 Twin Tuner (v5)",
210 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 321 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
211 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 322 NGENE_IO_TSOUT},
212 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 323 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900, cineS2_probe, cineS2_probe},
213 .fe_config = {&fe_cineS2, &fe_cineS2}, 324 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
214 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 325 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
215 .lnb = {0x0a, 0x08}, 326 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
327 .lnb = {0x0a, 0x08, 0x0b, 0x09},
216 .tsf = {3, 3}, 328 .tsf = {3, 3},
217 .fw_version = 15, 329 .fw_version = 18,
330 .msi_supported = true,
218}; 331};
219 332
333
220static struct ngene_info ngene_info_duoFlexS2 = { 334static struct ngene_info ngene_info_duoFlexS2 = {
221 .type = NGENE_SIDEWINDER, 335 .type = NGENE_SIDEWINDER,
222 .name = "Digital Devices DuoFlex S2 miniPCIe", 336 .name = "Digital Devices DuoFlex S2 miniPCIe",
223 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN}, 337 .io_type = {NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN, NGENE_IO_TSIN,
224 .demod_attach = {demod_attach_stv0900, demod_attach_stv0900}, 338 NGENE_IO_TSOUT},
225 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110}, 339 .demod_attach = {cineS2_probe, cineS2_probe, cineS2_probe, cineS2_probe},
226 .fe_config = {&fe_cineS2, &fe_cineS2}, 340 .tuner_attach = {tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110, tuner_attach_stv6110},
227 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1}, 341 .fe_config = {&fe_cineS2, &fe_cineS2, &fe_cineS2_2, &fe_cineS2_2},
228 .lnb = {0x0a, 0x08}, 342 .tuner_config = {&tuner_cineS2_0, &tuner_cineS2_1, &tuner_cineS2_0, &tuner_cineS2_1},
343 .lnb = {0x0a, 0x08, 0x0b, 0x09},
229 .tsf = {3, 3}, 344 .tsf = {3, 3},
230 .fw_version = 15, 345 .fw_version = 18,
346 .msi_supported = true,
231}; 347};
232 348
233static struct ngene_info ngene_info_m780 = { 349static struct ngene_info ngene_info_m780 = {
@@ -321,6 +437,7 @@ static struct pci_driver ngene_pci_driver = {
321 .probe = ngene_probe, 437 .probe = ngene_probe,
322 .remove = __devexit_p(ngene_remove), 438 .remove = __devexit_p(ngene_remove),
323 .err_handler = &ngene_errors, 439 .err_handler = &ngene_errors,
440 .shutdown = ngene_shutdown,
324}; 441};
325 442
326static __init int module_init_ngene(void) 443static __init int module_init_ngene(void)
diff --git a/drivers/media/dvb/ngene/ngene-core.c b/drivers/media/dvb/ngene/ngene-core.c
index dc073bdc623a..175a0f6c2a4c 100644
--- a/drivers/media/dvb/ngene/ngene-core.c
+++ b/drivers/media/dvb/ngene/ngene-core.c
@@ -45,6 +45,9 @@ static int one_adapter = 1;
45module_param(one_adapter, int, 0444); 45module_param(one_adapter, int, 0444);
46MODULE_PARM_DESC(one_adapter, "Use only one adapter."); 46MODULE_PARM_DESC(one_adapter, "Use only one adapter.");
47 47
48static int shutdown_workaround;
49module_param(shutdown_workaround, int, 0644);
50MODULE_PARM_DESC(shutdown_workaround, "Activate workaround for shutdown problem with some chipsets.");
48 51
49static int debug; 52static int debug;
50module_param(debug, int, 0444); 53module_param(debug, int, 0444);
@@ -143,7 +146,7 @@ static void demux_tasklet(unsigned long data)
143 } 146 }
144 } else { 147 } else {
145 if (chan->HWState == HWSTATE_RUN) { 148 if (chan->HWState == HWSTATE_RUN) {
146 u32 Flags = 0; 149 u32 Flags = chan->DataFormatFlags;
147 IBufferExchange *exch1 = chan->pBufferExchange; 150 IBufferExchange *exch1 = chan->pBufferExchange;
148 IBufferExchange *exch2 = chan->pBufferExchange2; 151 IBufferExchange *exch2 = chan->pBufferExchange2;
149 if (Cur->ngeneBuffer.SR.Flags & 0x01) 152 if (Cur->ngeneBuffer.SR.Flags & 0x01)
@@ -474,9 +477,9 @@ static u8 SPDIFConfiguration[10] = {
474 477
475/* Set NGENE I2S Config to transport stream compatible mode */ 478/* Set NGENE I2S Config to transport stream compatible mode */
476 479
477static u8 TS_I2SConfiguration[4] = { 0x3E, 0x1A, 0x00, 0x00 }; /*3e 18 00 00 ?*/ 480static u8 TS_I2SConfiguration[4] = { 0x3E, 0x18, 0x00, 0x00 };
478 481
479static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x20, 0x00, 0x00 }; 482static u8 TS_I2SOutConfiguration[4] = { 0x80, 0x04, 0x00, 0x00 };
480 483
481static u8 ITUDecoderSetup[4][16] = { 484static u8 ITUDecoderSetup[4][16] = {
482 {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */ 485 {0x1c, 0x13, 0x01, 0x68, 0x3d, 0x90, 0x14, 0x20, /* SDTV */
@@ -749,13 +752,11 @@ void set_transfer(struct ngene_channel *chan, int state)
749 if (chan->mode & NGENE_IO_TSOUT) { 752 if (chan->mode & NGENE_IO_TSOUT) {
750 chan->pBufferExchange = tsout_exchange; 753 chan->pBufferExchange = tsout_exchange;
751 /* 0x66666666 = 50MHz *2^33 /250MHz */ 754 /* 0x66666666 = 50MHz *2^33 /250MHz */
752 chan->AudioDTOValue = 0x66666666; 755 chan->AudioDTOValue = 0x80000000;
753 /* set_dto(chan, 38810700+1000); */ 756 chan->AudioDTOUpdated = 1;
754 /* set_dto(chan, 19392658); */
755 } 757 }
756 if (chan->mode & NGENE_IO_TSIN) 758 if (chan->mode & NGENE_IO_TSIN)
757 chan->pBufferExchange = tsin_exchange; 759 chan->pBufferExchange = tsin_exchange;
758 /* ngwritel(0, 0x9310); */
759 spin_unlock_irq(&chan->state_lock); 760 spin_unlock_irq(&chan->state_lock);
760 } else 761 } else
761 ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n", 762 ;/* printk(KERN_INFO DEVICE_NAME ": lock=%08x\n",
@@ -1168,6 +1169,7 @@ static void ngene_release_buffers(struct ngene *dev)
1168 iounmap(dev->iomem); 1169 iounmap(dev->iomem);
1169 free_common_buffers(dev); 1170 free_common_buffers(dev);
1170 vfree(dev->tsout_buf); 1171 vfree(dev->tsout_buf);
1172 vfree(dev->tsin_buf);
1171 vfree(dev->ain_buf); 1173 vfree(dev->ain_buf);
1172 vfree(dev->vin_buf); 1174 vfree(dev->vin_buf);
1173 vfree(dev); 1175 vfree(dev);
@@ -1184,6 +1186,13 @@ static int ngene_get_buffers(struct ngene *dev)
1184 dvb_ringbuffer_init(&dev->tsout_rbuf, 1186 dvb_ringbuffer_init(&dev->tsout_rbuf,
1185 dev->tsout_buf, TSOUT_BUF_SIZE); 1187 dev->tsout_buf, TSOUT_BUF_SIZE);
1186 } 1188 }
1189 if (dev->card_info->io_type[2]&NGENE_IO_TSIN) {
1190 dev->tsin_buf = vmalloc(TSIN_BUF_SIZE);
1191 if (!dev->tsin_buf)
1192 return -ENOMEM;
1193 dvb_ringbuffer_init(&dev->tsin_rbuf,
1194 dev->tsin_buf, TSIN_BUF_SIZE);
1195 }
1187 if (dev->card_info->io_type[2] & NGENE_IO_AIN) { 1196 if (dev->card_info->io_type[2] & NGENE_IO_AIN) {
1188 dev->ain_buf = vmalloc(AIN_BUF_SIZE); 1197 dev->ain_buf = vmalloc(AIN_BUF_SIZE);
1189 if (!dev->ain_buf) 1198 if (!dev->ain_buf)
@@ -1257,6 +1266,10 @@ static int ngene_load_firm(struct ngene *dev)
1257 fw_name = "ngene_17.fw"; 1266 fw_name = "ngene_17.fw";
1258 dev->cmd_timeout_workaround = true; 1267 dev->cmd_timeout_workaround = true;
1259 break; 1268 break;
1269 case 18:
1270 size = 0;
1271 fw_name = "ngene_18.fw";
1272 break;
1260 } 1273 }
1261 1274
1262 if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { 1275 if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) {
@@ -1266,6 +1279,8 @@ static int ngene_load_firm(struct ngene *dev)
1266 ": Copy %s to your hotplug directory!\n", fw_name); 1279 ": Copy %s to your hotplug directory!\n", fw_name);
1267 return -1; 1280 return -1;
1268 } 1281 }
1282 if (size == 0)
1283 size = fw->size;
1269 if (size != fw->size) { 1284 if (size != fw->size) {
1270 printk(KERN_ERR DEVICE_NAME 1285 printk(KERN_ERR DEVICE_NAME
1271 ": Firmware %s has invalid size!", fw_name); 1286 ": Firmware %s has invalid size!", fw_name);
@@ -1301,6 +1316,35 @@ static void ngene_stop(struct ngene *dev)
1301#endif 1316#endif
1302} 1317}
1303 1318
1319static int ngene_buffer_config(struct ngene *dev)
1320{
1321 int stat;
1322
1323 if (dev->card_info->fw_version >= 17) {
1324 u8 tsin12_config[6] = { 0x60, 0x60, 0x00, 0x00, 0x00, 0x00 };
1325 u8 tsin1234_config[6] = { 0x30, 0x30, 0x00, 0x30, 0x30, 0x00 };
1326 u8 tsio1235_config[6] = { 0x30, 0x30, 0x00, 0x28, 0x00, 0x38 };
1327 u8 *bconf = tsin12_config;
1328
1329 if (dev->card_info->io_type[2]&NGENE_IO_TSIN &&
1330 dev->card_info->io_type[3]&NGENE_IO_TSIN) {
1331 bconf = tsin1234_config;
1332 if (dev->card_info->io_type[4]&NGENE_IO_TSOUT &&
1333 dev->ci.en)
1334 bconf = tsio1235_config;
1335 }
1336 stat = ngene_command_config_free_buf(dev, bconf);
1337 } else {
1338 int bconf = BUFFER_CONFIG_4422;
1339
1340 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1341 bconf = BUFFER_CONFIG_3333;
1342 stat = ngene_command_config_buf(dev, bconf);
1343 }
1344 return stat;
1345}
1346
1347
1304static int ngene_start(struct ngene *dev) 1348static int ngene_start(struct ngene *dev)
1305{ 1349{
1306 int stat; 1350 int stat;
@@ -1365,23 +1409,6 @@ static int ngene_start(struct ngene *dev)
1365 if (stat < 0) 1409 if (stat < 0)
1366 goto fail; 1410 goto fail;
1367 1411
1368 if (dev->card_info->fw_version == 17) {
1369 u8 tsin4_config[6] = {
1370 3072 / 64, 3072 / 64, 0, 3072 / 64, 3072 / 64, 0};
1371 u8 default_config[6] = {
1372 4096 / 64, 4096 / 64, 0, 2048 / 64, 2048 / 64, 0};
1373 u8 *bconf = default_config;
1374
1375 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1376 bconf = tsin4_config;
1377 dprintk(KERN_DEBUG DEVICE_NAME ": FW 17 buffer config\n");
1378 stat = ngene_command_config_free_buf(dev, bconf);
1379 } else {
1380 int bconf = BUFFER_CONFIG_4422;
1381 if (dev->card_info->io_type[3] == NGENE_IO_TSIN)
1382 bconf = BUFFER_CONFIG_3333;
1383 stat = ngene_command_config_buf(dev, bconf);
1384 }
1385 if (!stat) 1412 if (!stat)
1386 return stat; 1413 return stat;
1387 1414
@@ -1397,9 +1424,6 @@ fail2:
1397 return stat; 1424 return stat;
1398} 1425}
1399 1426
1400
1401
1402
1403/****************************************************************************/ 1427/****************************************************************************/
1404/****************************************************************************/ 1428/****************************************************************************/
1405/****************************************************************************/ 1429/****************************************************************************/
@@ -1408,20 +1432,25 @@ static void release_channel(struct ngene_channel *chan)
1408{ 1432{
1409 struct dvb_demux *dvbdemux = &chan->demux; 1433 struct dvb_demux *dvbdemux = &chan->demux;
1410 struct ngene *dev = chan->dev; 1434 struct ngene *dev = chan->dev;
1411 struct ngene_info *ni = dev->card_info;
1412 int io = ni->io_type[chan->number];
1413 1435
1414 if (chan->dev->cmd_timeout_workaround && chan->running) 1436 if (chan->running)
1415 set_transfer(chan, 0); 1437 set_transfer(chan, 0);
1416 1438
1417 tasklet_kill(&chan->demux_tasklet); 1439 tasklet_kill(&chan->demux_tasklet);
1418 1440
1419 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { 1441 if (chan->ci_dev) {
1420 if (chan->fe) { 1442 dvb_unregister_device(chan->ci_dev);
1421 dvb_unregister_frontend(chan->fe); 1443 chan->ci_dev = NULL;
1422 dvb_frontend_detach(chan->fe); 1444 }
1423 chan->fe = NULL; 1445
1424 } 1446 if (chan->fe) {
1447 dvb_unregister_frontend(chan->fe);
1448 dvb_frontend_detach(chan->fe);
1449 chan->fe = NULL;
1450 }
1451
1452 if (chan->has_demux) {
1453 dvb_net_release(&chan->dvbnet);
1425 dvbdemux->dmx.close(&dvbdemux->dmx); 1454 dvbdemux->dmx.close(&dvbdemux->dmx);
1426 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx, 1455 dvbdemux->dmx.remove_frontend(&dvbdemux->dmx,
1427 &chan->hw_frontend); 1456 &chan->hw_frontend);
@@ -1429,9 +1458,12 @@ static void release_channel(struct ngene_channel *chan)
1429 &chan->mem_frontend); 1458 &chan->mem_frontend);
1430 dvb_dmxdev_release(&chan->dmxdev); 1459 dvb_dmxdev_release(&chan->dmxdev);
1431 dvb_dmx_release(&chan->demux); 1460 dvb_dmx_release(&chan->demux);
1461 chan->has_demux = false;
1462 }
1432 1463
1433 if (chan->number == 0 || !one_adapter) 1464 if (chan->has_adapter) {
1434 dvb_unregister_adapter(&dev->adapter[chan->number]); 1465 dvb_unregister_adapter(&dev->adapter[chan->number]);
1466 chan->has_adapter = false;
1435 } 1467 }
1436} 1468}
1437 1469
@@ -1449,9 +1481,27 @@ static int init_channel(struct ngene_channel *chan)
1449 chan->type = io; 1481 chan->type = io;
1450 chan->mode = chan->type; /* for now only one mode */ 1482 chan->mode = chan->type; /* for now only one mode */
1451 1483
1484 if (io & NGENE_IO_TSIN) {
1485 chan->fe = NULL;
1486 if (ni->demod_attach[nr]) {
1487 ret = ni->demod_attach[nr](chan);
1488 if (ret < 0)
1489 goto err;
1490 }
1491 if (chan->fe && ni->tuner_attach[nr]) {
1492 ret = ni->tuner_attach[nr](chan);
1493 if (ret < 0)
1494 goto err;
1495 }
1496 }
1497
1498 if (!dev->ci.en && (io & NGENE_IO_TSOUT))
1499 return 0;
1500
1452 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) { 1501 if (io & (NGENE_IO_TSIN | NGENE_IO_TSOUT)) {
1453 if (nr >= STREAM_AUDIOIN1) 1502 if (nr >= STREAM_AUDIOIN1)
1454 chan->DataFormatFlags = DF_SWAP32; 1503 chan->DataFormatFlags = DF_SWAP32;
1504
1455 if (nr == 0 || !one_adapter || dev->first_adapter == NULL) { 1505 if (nr == 0 || !one_adapter || dev->first_adapter == NULL) {
1456 adapter = &dev->adapter[nr]; 1506 adapter = &dev->adapter[nr];
1457 ret = dvb_register_adapter(adapter, "nGene", 1507 ret = dvb_register_adapter(adapter, "nGene",
@@ -1459,40 +1509,50 @@ static int init_channel(struct ngene_channel *chan)
1459 &chan->dev->pci_dev->dev, 1509 &chan->dev->pci_dev->dev,
1460 adapter_nr); 1510 adapter_nr);
1461 if (ret < 0) 1511 if (ret < 0)
1462 return ret; 1512 goto err;
1463 if (dev->first_adapter == NULL) 1513 if (dev->first_adapter == NULL)
1464 dev->first_adapter = adapter; 1514 dev->first_adapter = adapter;
1465 } else { 1515 chan->has_adapter = true;
1516 } else
1466 adapter = dev->first_adapter; 1517 adapter = dev->first_adapter;
1467 } 1518 }
1468 1519
1520 if (dev->ci.en && (io & NGENE_IO_TSOUT)) {
1521 dvb_ca_en50221_init(adapter, dev->ci.en, 0, 1);
1522 set_transfer(chan, 1);
1523 set_transfer(&chan->dev->channel[2], 1);
1524 dvb_register_device(adapter, &chan->ci_dev,
1525 &ngene_dvbdev_ci, (void *) chan,
1526 DVB_DEVICE_SEC);
1527 if (!chan->ci_dev)
1528 goto err;
1529 }
1530
1531 if (chan->fe) {
1532 if (dvb_register_frontend(adapter, chan->fe) < 0)
1533 goto err;
1534 chan->has_demux = true;
1535 }
1536
1537 if (chan->has_demux) {
1469 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux", 1538 ret = my_dvb_dmx_ts_card_init(dvbdemux, "SW demux",
1470 ngene_start_feed, 1539 ngene_start_feed,
1471 ngene_stop_feed, chan); 1540 ngene_stop_feed, chan);
1472 ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux, 1541 ret = my_dvb_dmxdev_ts_card_init(&chan->dmxdev, &chan->demux,
1473 &chan->hw_frontend, 1542 &chan->hw_frontend,
1474 &chan->mem_frontend, adapter); 1543 &chan->mem_frontend, adapter);
1544 ret = dvb_net_init(adapter, &chan->dvbnet, &chan->demux.dmx);
1475 } 1545 }
1476 1546
1477 if (io & NGENE_IO_TSIN) { 1547 return ret;
1548
1549err:
1550 if (chan->fe) {
1551 dvb_frontend_detach(chan->fe);
1478 chan->fe = NULL; 1552 chan->fe = NULL;
1479 if (ni->demod_attach[nr])
1480 ni->demod_attach[nr](chan);
1481 if (chan->fe) {
1482 if (dvb_register_frontend(adapter, chan->fe) < 0) {
1483 if (chan->fe->ops.release)
1484 chan->fe->ops.release(chan->fe);
1485 chan->fe = NULL;
1486 }
1487 }
1488 if (chan->fe && ni->tuner_attach[nr])
1489 if (ni->tuner_attach[nr] (chan) < 0) {
1490 printk(KERN_ERR DEVICE_NAME
1491 ": Tuner attach failed on channel %d!\n",
1492 nr);
1493 }
1494 } 1553 }
1495 return ret; 1554 release_channel(chan);
1555 return 0;
1496} 1556}
1497 1557
1498static int init_channels(struct ngene *dev) 1558static int init_channels(struct ngene *dev)
@@ -1510,6 +1570,57 @@ static int init_channels(struct ngene *dev)
1510 return 0; 1570 return 0;
1511} 1571}
1512 1572
1573static void cxd_attach(struct ngene *dev)
1574{
1575 struct ngene_ci *ci = &dev->ci;
1576
1577 ci->en = cxd2099_attach(0x40, dev, &dev->channel[0].i2c_adapter);
1578 ci->dev = dev;
1579 return;
1580}
1581
1582static void cxd_detach(struct ngene *dev)
1583{
1584 struct ngene_ci *ci = &dev->ci;
1585
1586 dvb_ca_en50221_release(ci->en);
1587 kfree(ci->en);
1588 ci->en = 0;
1589}
1590
1591/***********************************/
1592/* workaround for shutdown failure */
1593/***********************************/
1594
1595static void ngene_unlink(struct ngene *dev)
1596{
1597 struct ngene_command com;
1598
1599 com.cmd.hdr.Opcode = CMD_MEM_WRITE;
1600 com.cmd.hdr.Length = 3;
1601 com.cmd.MemoryWrite.address = 0x910c;
1602 com.cmd.MemoryWrite.data = 0xff;
1603 com.in_len = 3;
1604 com.out_len = 1;
1605
1606 down(&dev->cmd_mutex);
1607 ngwritel(0, NGENE_INT_ENABLE);
1608 ngene_command_mutex(dev, &com);
1609 up(&dev->cmd_mutex);
1610}
1611
1612void ngene_shutdown(struct pci_dev *pdev)
1613{
1614 struct ngene *dev = (struct ngene *)pci_get_drvdata(pdev);
1615
1616 if (!dev || !shutdown_workaround)
1617 return;
1618
1619 printk(KERN_INFO DEVICE_NAME ": shutdown workaround...\n");
1620 ngene_unlink(dev);
1621 pci_disable_device(pdev);
1622}
1623
1513/****************************************************************************/ 1624/****************************************************************************/
1514/* device probe/remove calls ************************************************/ 1625/* device probe/remove calls ************************************************/
1515/****************************************************************************/ 1626/****************************************************************************/
@@ -1522,6 +1633,8 @@ void __devexit ngene_remove(struct pci_dev *pdev)
1522 tasklet_kill(&dev->event_tasklet); 1633 tasklet_kill(&dev->event_tasklet);
1523 for (i = MAX_STREAM - 1; i >= 0; i--) 1634 for (i = MAX_STREAM - 1; i >= 0; i--)
1524 release_channel(&dev->channel[i]); 1635 release_channel(&dev->channel[i]);
1636 if (dev->ci.en)
1637 cxd_detach(dev);
1525 ngene_stop(dev); 1638 ngene_stop(dev);
1526 ngene_release_buffers(dev); 1639 ngene_release_buffers(dev);
1527 pci_set_drvdata(pdev, NULL); 1640 pci_set_drvdata(pdev, NULL);
@@ -1557,6 +1670,13 @@ int __devinit ngene_probe(struct pci_dev *pci_dev,
1557 if (stat < 0) 1670 if (stat < 0)
1558 goto fail1; 1671 goto fail1;
1559 1672
1673 cxd_attach(dev);
1674
1675 stat = ngene_buffer_config(dev);
1676 if (stat < 0)
1677 goto fail1;
1678
1679
1560 dev->i2c_current_bus = -1; 1680 dev->i2c_current_bus = -1;
1561 1681
1562 /* Register DVB adapters and devices for both channels */ 1682 /* Register DVB adapters and devices for both channels */
diff --git a/drivers/media/dvb/ngene/ngene-dvb.c b/drivers/media/dvb/ngene/ngene-dvb.c
index 3832e5983c19..0b4943233166 100644
--- a/drivers/media/dvb/ngene/ngene-dvb.c
+++ b/drivers/media/dvb/ngene/ngene-dvb.c
@@ -47,6 +47,64 @@
47/* COMMAND API interface ****************************************************/ 47/* COMMAND API interface ****************************************************/
48/****************************************************************************/ 48/****************************************************************************/
49 49
50static ssize_t ts_write(struct file *file, const char *buf,
51 size_t count, loff_t *ppos)
52{
53 struct dvb_device *dvbdev = file->private_data;
54 struct ngene_channel *chan = dvbdev->priv;
55 struct ngene *dev = chan->dev;
56
57 if (wait_event_interruptible(dev->tsout_rbuf.queue,
58 dvb_ringbuffer_free
59 (&dev->tsout_rbuf) >= count) < 0)
60 return 0;
61
62 dvb_ringbuffer_write(&dev->tsout_rbuf, buf, count);
63
64 return count;
65}
66
67static ssize_t ts_read(struct file *file, char *buf,
68 size_t count, loff_t *ppos)
69{
70 struct dvb_device *dvbdev = file->private_data;
71 struct ngene_channel *chan = dvbdev->priv;
72 struct ngene *dev = chan->dev;
73 int left, avail;
74
75 left = count;
76 while (left) {
77 if (wait_event_interruptible(
78 dev->tsin_rbuf.queue,
79 dvb_ringbuffer_avail(&dev->tsin_rbuf) > 0) < 0)
80 return -EAGAIN;
81 avail = dvb_ringbuffer_avail(&dev->tsin_rbuf);
82 if (avail > left)
83 avail = left;
84 dvb_ringbuffer_read_user(&dev->tsin_rbuf, buf, avail);
85 left -= avail;
86 buf += avail;
87 }
88 return count;
89}
90
91static const struct file_operations ci_fops = {
92 .owner = THIS_MODULE,
93 .read = ts_read,
94 .write = ts_write,
95 .open = dvb_generic_open,
96 .release = dvb_generic_release,
97};
98
99struct dvb_device ngene_dvbdev_ci = {
100 .priv = 0,
101 .readers = -1,
102 .writers = -1,
103 .users = -1,
104 .fops = &ci_fops,
105};
106
107
50/****************************************************************************/ 108/****************************************************************************/
51/* DVB functions and API interface ******************************************/ 109/* DVB functions and API interface ******************************************/
52/****************************************************************************/ 110/****************************************************************************/
@@ -63,10 +121,21 @@ static void swap_buffer(u32 *p, u32 len)
63void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags) 121void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags)
64{ 122{
65 struct ngene_channel *chan = priv; 123 struct ngene_channel *chan = priv;
124 struct ngene *dev = chan->dev;
66 125
67 126
68 if (chan->users > 0) 127 if (flags & DF_SWAP32)
128 swap_buffer(buf, len);
129 if (dev->ci.en && chan->number == 2) {
130 if (dvb_ringbuffer_free(&dev->tsin_rbuf) > len) {
131 dvb_ringbuffer_write(&dev->tsin_rbuf, buf, len);
132 wake_up_interruptible(&dev->tsin_rbuf.queue);
133 }
134 return 0;
135 }
136 if (chan->users > 0) {
69 dvb_dmx_swfilter(&chan->demux, buf, len); 137 dvb_dmx_swfilter(&chan->demux, buf, len);
138 }
70 return NULL; 139 return NULL;
71} 140}
72 141
diff --git a/drivers/media/dvb/ngene/ngene.h b/drivers/media/dvb/ngene/ngene.h
index 8fb4200f83f8..40fce9e3ae66 100644
--- a/drivers/media/dvb/ngene/ngene.h
+++ b/drivers/media/dvb/ngene/ngene.h
@@ -36,8 +36,11 @@
36#include "dmxdev.h" 36#include "dmxdev.h"
37#include "dvbdev.h" 37#include "dvbdev.h"
38#include "dvb_demux.h" 38#include "dvb_demux.h"
39#include "dvb_ca_en50221.h"
39#include "dvb_frontend.h" 40#include "dvb_frontend.h"
40#include "dvb_ringbuffer.h" 41#include "dvb_ringbuffer.h"
42#include "dvb_net.h"
43#include "cxd2099.h"
41 44
42#define DEVICE_NAME "ngene" 45#define DEVICE_NAME "ngene"
43 46
@@ -636,14 +639,18 @@ struct ngene_channel {
636 int number; 639 int number;
637 int type; 640 int type;
638 int mode; 641 int mode;
642 bool has_adapter;
643 bool has_demux;
639 644
640 struct dvb_frontend *fe; 645 struct dvb_frontend *fe;
641 struct dmxdev dmxdev; 646 struct dmxdev dmxdev;
642 struct dvb_demux demux; 647 struct dvb_demux demux;
648 struct dvb_net dvbnet;
643 struct dmx_frontend hw_frontend; 649 struct dmx_frontend hw_frontend;
644 struct dmx_frontend mem_frontend; 650 struct dmx_frontend mem_frontend;
645 int users; 651 int users;
646 struct video_device *v4l_dev; 652 struct video_device *v4l_dev;
653 struct dvb_device *ci_dev;
647 struct tasklet_struct demux_tasklet; 654 struct tasklet_struct demux_tasklet;
648 655
649 struct SBufferHeader *nextBuffer; 656 struct SBufferHeader *nextBuffer;
@@ -710,6 +717,15 @@ struct ngene_channel {
710 int running; 717 int running;
711}; 718};
712 719
720
721struct ngene_ci {
722 struct device device;
723 struct i2c_adapter i2c_adapter;
724
725 struct ngene *dev;
726 struct dvb_ca_en50221 *en;
727};
728
713struct ngene; 729struct ngene;
714 730
715typedef void (rx_cb_t)(struct ngene *, u32, u8); 731typedef void (rx_cb_t)(struct ngene *, u32, u8);
@@ -774,6 +790,10 @@ struct ngene {
774#define TSOUT_BUF_SIZE (512*188*8) 790#define TSOUT_BUF_SIZE (512*188*8)
775 struct dvb_ringbuffer tsout_rbuf; 791 struct dvb_ringbuffer tsout_rbuf;
776 792
793 u8 *tsin_buf;
794#define TSIN_BUF_SIZE (512*188*8)
795 struct dvb_ringbuffer tsin_rbuf;
796
777 u8 *ain_buf; 797 u8 *ain_buf;
778#define AIN_BUF_SIZE (128*1024) 798#define AIN_BUF_SIZE (128*1024)
779 struct dvb_ringbuffer ain_rbuf; 799 struct dvb_ringbuffer ain_rbuf;
@@ -785,6 +805,8 @@ struct ngene {
785 805
786 unsigned long exp_val; 806 unsigned long exp_val;
787 int prev_cmd; 807 int prev_cmd;
808
809 struct ngene_ci ci;
788}; 810};
789 811
790struct ngene_info { 812struct ngene_info {
@@ -863,6 +885,7 @@ struct ngene_buffer {
863int __devinit ngene_probe(struct pci_dev *pci_dev, 885int __devinit ngene_probe(struct pci_dev *pci_dev,
864 const struct pci_device_id *id); 886 const struct pci_device_id *id);
865void __devexit ngene_remove(struct pci_dev *pdev); 887void __devexit ngene_remove(struct pci_dev *pdev);
888void ngene_shutdown(struct pci_dev *pdev);
866int ngene_command(struct ngene *dev, struct ngene_command *com); 889int ngene_command(struct ngene *dev, struct ngene_command *com);
867int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level); 890int ngene_command_gpio_set(struct ngene *dev, u8 select, u8 level);
868void set_transfer(struct ngene_channel *chan, int state); 891void set_transfer(struct ngene_channel *chan, int state);
@@ -872,6 +895,7 @@ void FillTSBuffer(void *Buffer, int Length, u32 Flags);
872int ngene_i2c_init(struct ngene *dev, int dev_nr); 895int ngene_i2c_init(struct ngene *dev, int dev_nr);
873 896
874/* Provided by ngene-dvb.c */ 897/* Provided by ngene-dvb.c */
898extern struct dvb_device ngene_dvbdev_ci;
875void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); 899void *tsout_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
876void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags); 900void *tsin_exchange(void *priv, void *buf, u32 len, u32 clock, u32 flags);
877int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed); 901int ngene_start_feed(struct dvb_demux_feed *dvbdmxfeed);
diff --git a/drivers/media/dvb/siano/sms-cards.c b/drivers/media/dvb/siano/sms-cards.c
index 25b43e587fa6..af121db88ea0 100644
--- a/drivers/media/dvb/siano/sms-cards.c
+++ b/drivers/media/dvb/siano/sms-cards.c
@@ -64,7 +64,7 @@ static struct sms_board sms_boards[] = {
64 .type = SMS_NOVA_B0, 64 .type = SMS_NOVA_B0,
65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw", 65 .fw[DEVICE_MODE_ISDBT_BDA] = "sms1xxx-hcw-55xxx-isdbt-02.fw",
66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw", 66 .fw[DEVICE_MODE_DVBT_BDA] = "sms1xxx-hcw-55xxx-dvbt-02.fw",
67 .rc_codes = RC_MAP_RC5_HAUPPAUGE_NEW, 67 .rc_codes = RC_MAP_HAUPPAUGE,
68 .board_cfg.leds_power = 26, 68 .board_cfg.leds_power = 26,
69 .board_cfg.led0 = 27, 69 .board_cfg.led0 = 27,
70 .board_cfg.led1 = 28, 70 .board_cfg.led1 = 28,
diff --git a/drivers/media/dvb/ttpci/budget-ci.c b/drivers/media/dvb/ttpci/budget-ci.c
index b82756db5bd1..1d79ada864d6 100644
--- a/drivers/media/dvb/ttpci/budget-ci.c
+++ b/drivers/media/dvb/ttpci/budget-ci.c
@@ -26,7 +26,7 @@
26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html 26 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
27 * 27 *
28 * 28 *
29 * the project's page is at http://www.linuxtv.org/ 29 * the project's page is at http://www.linuxtv.org/
30 */ 30 */
31 31
32#include <linux/module.h> 32#include <linux/module.h>
@@ -102,6 +102,7 @@ struct budget_ci_ir {
102 int rc5_device; 102 int rc5_device;
103 u32 ir_key; 103 u32 ir_key;
104 bool have_command; 104 bool have_command;
105 bool full_rc5; /* Outputs a full RC5 code */
105}; 106};
106 107
107struct budget_ci { 108struct budget_ci {
@@ -154,11 +155,18 @@ static void msp430_ir_interrupt(unsigned long data)
154 return; 155 return;
155 budget_ci->ir.have_command = false; 156 budget_ci->ir.have_command = false;
156 157
157 /* FIXME: We should generate complete scancodes with device info */
158 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY && 158 if (budget_ci->ir.rc5_device != IR_DEVICE_ANY &&
159 budget_ci->ir.rc5_device != (command & 0x1f)) 159 budget_ci->ir.rc5_device != (command & 0x1f))
160 return; 160 return;
161 161
162 if (budget_ci->ir.full_rc5) {
163 rc_keydown(dev,
164 budget_ci->ir.rc5_device <<8 | budget_ci->ir.ir_key,
165 (command & 0x20) ? 1 : 0);
166 return;
167 }
168
169 /* FIXME: We should generate complete scancodes for all devices */
162 rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0); 170 rc_keydown(dev, budget_ci->ir.ir_key, (command & 0x20) ? 1 : 0);
163} 171}
164 172
@@ -206,7 +214,8 @@ static int msp430_ir_init(struct budget_ci *budget_ci)
206 case 0x1011: 214 case 0x1011:
207 case 0x1012: 215 case 0x1012:
208 /* The hauppauge keymap is a superset of these remotes */ 216 /* The hauppauge keymap is a superset of these remotes */
209 dev->map_name = RC_MAP_HAUPPAUGE_NEW; 217 dev->map_name = RC_MAP_HAUPPAUGE;
218 budget_ci->ir.full_rc5 = true;
210 219
211 if (rc5_device < 0) 220 if (rc5_device < 0)
212 budget_ci->ir.rc5_device = 0x1f; 221 budget_ci->ir.rc5_device = 0x1f;
diff --git a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
index 40625b26ac10..cbe2f0de1442 100644
--- a/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
+++ b/drivers/media/dvb/ttusb-budget/dvb-ttusb-budget.c
@@ -334,6 +334,7 @@ static int ttusb_boot_dsp(struct ttusb *ttusb)
334 err = ttusb_cmd(ttusb, b, 4, 0); 334 err = ttusb_cmd(ttusb, b, 4, 0);
335 335
336 done: 336 done:
337 release_firmware(fw);
337 if (err) { 338 if (err) {
338 dprintk("%s: usb_bulk_msg() failed, return value %i!\n", 339 dprintk("%s: usb_bulk_msg() failed, return value %i!\n",
339 __func__, err); 340 __func__, err);
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
new file mode 100644
index 000000000000..16b70b4412f7
--- /dev/null
+++ b/drivers/media/media-device.c
@@ -0,0 +1,382 @@
1/*
2 * Media device
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/types.h>
24#include <linux/ioctl.h>
25#include <linux/media.h>
26
27#include <media/media-device.h>
28#include <media/media-devnode.h>
29#include <media/media-entity.h>
30
31/* -----------------------------------------------------------------------------
32 * Userspace API
33 */
34
35static int media_device_open(struct file *filp)
36{
37 return 0;
38}
39
40static int media_device_close(struct file *filp)
41{
42 return 0;
43}
44
45static int media_device_get_info(struct media_device *dev,
46 struct media_device_info __user *__info)
47{
48 struct media_device_info info;
49
50 memset(&info, 0, sizeof(info));
51
52 strlcpy(info.driver, dev->dev->driver->name, sizeof(info.driver));
53 strlcpy(info.model, dev->model, sizeof(info.model));
54 strlcpy(info.serial, dev->serial, sizeof(info.serial));
55 strlcpy(info.bus_info, dev->bus_info, sizeof(info.bus_info));
56
57 info.media_version = MEDIA_API_VERSION;
58 info.hw_revision = dev->hw_revision;
59 info.driver_version = dev->driver_version;
60
61 return copy_to_user(__info, &info, sizeof(*__info));
62}
63
64static struct media_entity *find_entity(struct media_device *mdev, u32 id)
65{
66 struct media_entity *entity;
67 int next = id & MEDIA_ENT_ID_FLAG_NEXT;
68
69 id &= ~MEDIA_ENT_ID_FLAG_NEXT;
70
71 spin_lock(&mdev->lock);
72
73 media_device_for_each_entity(entity, mdev) {
74 if ((entity->id == id && !next) ||
75 (entity->id > id && next)) {
76 spin_unlock(&mdev->lock);
77 return entity;
78 }
79 }
80
81 spin_unlock(&mdev->lock);
82
83 return NULL;
84}
85
86static long media_device_enum_entities(struct media_device *mdev,
87 struct media_entity_desc __user *uent)
88{
89 struct media_entity *ent;
90 struct media_entity_desc u_ent;
91
92 if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id)))
93 return -EFAULT;
94
95 ent = find_entity(mdev, u_ent.id);
96
97 if (ent == NULL)
98 return -EINVAL;
99
100 u_ent.id = ent->id;
101 u_ent.name[0] = '\0';
102 if (ent->name)
103 strlcpy(u_ent.name, ent->name, sizeof(u_ent.name));
104 u_ent.type = ent->type;
105 u_ent.revision = ent->revision;
106 u_ent.flags = ent->flags;
107 u_ent.group_id = ent->group_id;
108 u_ent.pads = ent->num_pads;
109 u_ent.links = ent->num_links - ent->num_backlinks;
110 u_ent.v4l.major = ent->v4l.major;
111 u_ent.v4l.minor = ent->v4l.minor;
112 if (copy_to_user(uent, &u_ent, sizeof(u_ent)))
113 return -EFAULT;
114 return 0;
115}
116
117static void media_device_kpad_to_upad(const struct media_pad *kpad,
118 struct media_pad_desc *upad)
119{
120 upad->entity = kpad->entity->id;
121 upad->index = kpad->index;
122 upad->flags = kpad->flags;
123}
124
125static long media_device_enum_links(struct media_device *mdev,
126 struct media_links_enum __user *ulinks)
127{
128 struct media_entity *entity;
129 struct media_links_enum links;
130
131 if (copy_from_user(&links, ulinks, sizeof(links)))
132 return -EFAULT;
133
134 entity = find_entity(mdev, links.entity);
135 if (entity == NULL)
136 return -EINVAL;
137
138 if (links.pads) {
139 unsigned int p;
140
141 for (p = 0; p < entity->num_pads; p++) {
142 struct media_pad_desc pad;
143 media_device_kpad_to_upad(&entity->pads[p], &pad);
144 if (copy_to_user(&links.pads[p], &pad, sizeof(pad)))
145 return -EFAULT;
146 }
147 }
148
149 if (links.links) {
150 struct media_link_desc __user *ulink;
151 unsigned int l;
152
153 for (l = 0, ulink = links.links; l < entity->num_links; l++) {
154 struct media_link_desc link;
155
156 /* Ignore backlinks. */
157 if (entity->links[l].source->entity != entity)
158 continue;
159
160 media_device_kpad_to_upad(entity->links[l].source,
161 &link.source);
162 media_device_kpad_to_upad(entity->links[l].sink,
163 &link.sink);
164 link.flags = entity->links[l].flags;
165 if (copy_to_user(ulink, &link, sizeof(*ulink)))
166 return -EFAULT;
167 ulink++;
168 }
169 }
170 if (copy_to_user(ulinks, &links, sizeof(*ulinks)))
171 return -EFAULT;
172 return 0;
173}
174
175static long media_device_setup_link(struct media_device *mdev,
176 struct media_link_desc __user *_ulink)
177{
178 struct media_link *link = NULL;
179 struct media_link_desc ulink;
180 struct media_entity *source;
181 struct media_entity *sink;
182 int ret;
183
184 if (copy_from_user(&ulink, _ulink, sizeof(ulink)))
185 return -EFAULT;
186
187 /* Find the source and sink entities and link.
188 */
189 source = find_entity(mdev, ulink.source.entity);
190 sink = find_entity(mdev, ulink.sink.entity);
191
192 if (source == NULL || sink == NULL)
193 return -EINVAL;
194
195 if (ulink.source.index >= source->num_pads ||
196 ulink.sink.index >= sink->num_pads)
197 return -EINVAL;
198
199 link = media_entity_find_link(&source->pads[ulink.source.index],
200 &sink->pads[ulink.sink.index]);
201 if (link == NULL)
202 return -EINVAL;
203
204 /* Setup the link on both entities. */
205 ret = __media_entity_setup_link(link, ulink.flags);
206
207 if (copy_to_user(_ulink, &ulink, sizeof(ulink)))
208 return -EFAULT;
209
210 return ret;
211}
212
213static long media_device_ioctl(struct file *filp, unsigned int cmd,
214 unsigned long arg)
215{
216 struct media_devnode *devnode = media_devnode_data(filp);
217 struct media_device *dev = to_media_device(devnode);
218 long ret;
219
220 switch (cmd) {
221 case MEDIA_IOC_DEVICE_INFO:
222 ret = media_device_get_info(dev,
223 (struct media_device_info __user *)arg);
224 break;
225
226 case MEDIA_IOC_ENUM_ENTITIES:
227 ret = media_device_enum_entities(dev,
228 (struct media_entity_desc __user *)arg);
229 break;
230
231 case MEDIA_IOC_ENUM_LINKS:
232 mutex_lock(&dev->graph_mutex);
233 ret = media_device_enum_links(dev,
234 (struct media_links_enum __user *)arg);
235 mutex_unlock(&dev->graph_mutex);
236 break;
237
238 case MEDIA_IOC_SETUP_LINK:
239 mutex_lock(&dev->graph_mutex);
240 ret = media_device_setup_link(dev,
241 (struct media_link_desc __user *)arg);
242 mutex_unlock(&dev->graph_mutex);
243 break;
244
245 default:
246 ret = -ENOIOCTLCMD;
247 }
248
249 return ret;
250}
251
252static const struct media_file_operations media_device_fops = {
253 .owner = THIS_MODULE,
254 .open = media_device_open,
255 .ioctl = media_device_ioctl,
256 .release = media_device_close,
257};
258
259/* -----------------------------------------------------------------------------
260 * sysfs
261 */
262
263static ssize_t show_model(struct device *cd,
264 struct device_attribute *attr, char *buf)
265{
266 struct media_device *mdev = to_media_device(to_media_devnode(cd));
267
268 return sprintf(buf, "%.*s\n", (int)sizeof(mdev->model), mdev->model);
269}
270
271static DEVICE_ATTR(model, S_IRUGO, show_model, NULL);
272
273/* -----------------------------------------------------------------------------
274 * Registration/unregistration
275 */
276
277static void media_device_release(struct media_devnode *mdev)
278{
279}
280
281/**
282 * media_device_register - register a media device
283 * @mdev: The media device
284 *
285 * The caller is responsible for initializing the media device before
286 * registration. The following fields must be set:
287 *
288 * - dev must point to the parent device
289 * - model must be filled with the device model name
290 */
291int __must_check media_device_register(struct media_device *mdev)
292{
293 int ret;
294
295 if (WARN_ON(mdev->dev == NULL || mdev->model[0] == 0))
296 return -EINVAL;
297
298 mdev->entity_id = 1;
299 INIT_LIST_HEAD(&mdev->entities);
300 spin_lock_init(&mdev->lock);
301 mutex_init(&mdev->graph_mutex);
302
303 /* Register the device node. */
304 mdev->devnode.fops = &media_device_fops;
305 mdev->devnode.parent = mdev->dev;
306 mdev->devnode.release = media_device_release;
307 ret = media_devnode_register(&mdev->devnode);
308 if (ret < 0)
309 return ret;
310
311 ret = device_create_file(&mdev->devnode.dev, &dev_attr_model);
312 if (ret < 0) {
313 media_devnode_unregister(&mdev->devnode);
314 return ret;
315 }
316
317 return 0;
318}
319EXPORT_SYMBOL_GPL(media_device_register);
320
321/**
322 * media_device_unregister - unregister a media device
323 * @mdev: The media device
324 *
325 */
326void media_device_unregister(struct media_device *mdev)
327{
328 struct media_entity *entity;
329 struct media_entity *next;
330
331 list_for_each_entry_safe(entity, next, &mdev->entities, list)
332 media_device_unregister_entity(entity);
333
334 device_remove_file(&mdev->devnode.dev, &dev_attr_model);
335 media_devnode_unregister(&mdev->devnode);
336}
337EXPORT_SYMBOL_GPL(media_device_unregister);
338
339/**
340 * media_device_register_entity - Register an entity with a media device
341 * @mdev: The media device
342 * @entity: The entity
343 */
344int __must_check media_device_register_entity(struct media_device *mdev,
345 struct media_entity *entity)
346{
347 /* Warn if we apparently re-register an entity */
348 WARN_ON(entity->parent != NULL);
349 entity->parent = mdev;
350
351 spin_lock(&mdev->lock);
352 if (entity->id == 0)
353 entity->id = mdev->entity_id++;
354 else
355 mdev->entity_id = max(entity->id + 1, mdev->entity_id);
356 list_add_tail(&entity->list, &mdev->entities);
357 spin_unlock(&mdev->lock);
358
359 return 0;
360}
361EXPORT_SYMBOL_GPL(media_device_register_entity);
362
363/**
364 * media_device_unregister_entity - Unregister an entity
365 * @entity: The entity
366 *
367 * If the entity has never been registered this function will return
368 * immediately.
369 */
370void media_device_unregister_entity(struct media_entity *entity)
371{
372 struct media_device *mdev = entity->parent;
373
374 if (mdev == NULL)
375 return;
376
377 spin_lock(&mdev->lock);
378 list_del(&entity->list);
379 spin_unlock(&mdev->lock);
380 entity->parent = NULL;
381}
382EXPORT_SYMBOL_GPL(media_device_unregister_entity);
diff --git a/drivers/media/media-devnode.c b/drivers/media/media-devnode.c
new file mode 100644
index 000000000000..af5263c6625a
--- /dev/null
+++ b/drivers/media/media-devnode.c
@@ -0,0 +1,320 @@
1/*
2 * Media device node
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Based on drivers/media/video/v4l2_dev.c code authored by
7 * Mauro Carvalho Chehab <mchehab@infradead.org> (version 2)
8 * Alan Cox, <alan@lxorguk.ukuu.org.uk> (version 1)
9 *
10 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 *
26 * --
27 *
28 * Generic media device node infrastructure to register and unregister
29 * character devices using a dynamic major number and proper reference
30 * counting.
31 */
32
33#include <linux/errno.h>
34#include <linux/init.h>
35#include <linux/module.h>
36#include <linux/kernel.h>
37#include <linux/kmod.h>
38#include <linux/slab.h>
39#include <linux/mm.h>
40#include <linux/string.h>
41#include <linux/types.h>
42#include <linux/uaccess.h>
43#include <asm/system.h>
44
45#include <media/media-devnode.h>
46
47#define MEDIA_NUM_DEVICES 256
48#define MEDIA_NAME "media"
49
50static dev_t media_dev_t;
51
52/*
53 * Active devices
54 */
55static DEFINE_MUTEX(media_devnode_lock);
56static DECLARE_BITMAP(media_devnode_nums, MEDIA_NUM_DEVICES);
57
58/* Called when the last user of the media device exits. */
59static void media_devnode_release(struct device *cd)
60{
61 struct media_devnode *mdev = to_media_devnode(cd);
62
63 mutex_lock(&media_devnode_lock);
64
65 /* Delete the cdev on this minor as well */
66 cdev_del(&mdev->cdev);
67
68 /* Mark device node number as free */
69 clear_bit(mdev->minor, media_devnode_nums);
70
71 mutex_unlock(&media_devnode_lock);
72
73 /* Release media_devnode and perform other cleanups as needed. */
74 if (mdev->release)
75 mdev->release(mdev);
76}
77
78static struct bus_type media_bus_type = {
79 .name = MEDIA_NAME,
80};
81
82static ssize_t media_read(struct file *filp, char __user *buf,
83 size_t sz, loff_t *off)
84{
85 struct media_devnode *mdev = media_devnode_data(filp);
86
87 if (!mdev->fops->read)
88 return -EINVAL;
89 if (!media_devnode_is_registered(mdev))
90 return -EIO;
91 return mdev->fops->read(filp, buf, sz, off);
92}
93
94static ssize_t media_write(struct file *filp, const char __user *buf,
95 size_t sz, loff_t *off)
96{
97 struct media_devnode *mdev = media_devnode_data(filp);
98
99 if (!mdev->fops->write)
100 return -EINVAL;
101 if (!media_devnode_is_registered(mdev))
102 return -EIO;
103 return mdev->fops->write(filp, buf, sz, off);
104}
105
106static unsigned int media_poll(struct file *filp,
107 struct poll_table_struct *poll)
108{
109 struct media_devnode *mdev = media_devnode_data(filp);
110
111 if (!media_devnode_is_registered(mdev))
112 return POLLERR | POLLHUP;
113 if (!mdev->fops->poll)
114 return DEFAULT_POLLMASK;
115 return mdev->fops->poll(filp, poll);
116}
117
118static long media_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
119{
120 struct media_devnode *mdev = media_devnode_data(filp);
121
122 if (!mdev->fops->ioctl)
123 return -ENOTTY;
124
125 if (!media_devnode_is_registered(mdev))
126 return -EIO;
127
128 return mdev->fops->ioctl(filp, cmd, arg);
129}
130
131/* Override for the open function */
132static int media_open(struct inode *inode, struct file *filp)
133{
134 struct media_devnode *mdev;
135 int ret;
136
137 /* Check if the media device is available. This needs to be done with
138 * the media_devnode_lock held to prevent an open/unregister race:
139 * without the lock, the device could be unregistered and freed between
140 * the media_devnode_is_registered() and get_device() calls, leading to
141 * a crash.
142 */
143 mutex_lock(&media_devnode_lock);
144 mdev = container_of(inode->i_cdev, struct media_devnode, cdev);
145 /* return ENXIO if the media device has been removed
146 already or if it is not registered anymore. */
147 if (!media_devnode_is_registered(mdev)) {
148 mutex_unlock(&media_devnode_lock);
149 return -ENXIO;
150 }
151 /* and increase the device refcount */
152 get_device(&mdev->dev);
153 mutex_unlock(&media_devnode_lock);
154
155 filp->private_data = mdev;
156
157 if (mdev->fops->open) {
158 ret = mdev->fops->open(filp);
159 if (ret) {
160 put_device(&mdev->dev);
161 return ret;
162 }
163 }
164
165 return 0;
166}
167
168/* Override for the release function */
169static int media_release(struct inode *inode, struct file *filp)
170{
171 struct media_devnode *mdev = media_devnode_data(filp);
172 int ret = 0;
173
174 if (mdev->fops->release)
175 mdev->fops->release(filp);
176
177 /* decrease the refcount unconditionally since the release()
178 return value is ignored. */
179 put_device(&mdev->dev);
180 filp->private_data = NULL;
181 return ret;
182}
183
184static const struct file_operations media_devnode_fops = {
185 .owner = THIS_MODULE,
186 .read = media_read,
187 .write = media_write,
188 .open = media_open,
189 .unlocked_ioctl = media_ioctl,
190 .release = media_release,
191 .poll = media_poll,
192 .llseek = no_llseek,
193};
194
195/**
196 * media_devnode_register - register a media device node
197 * @mdev: media device node structure we want to register
198 *
199 * The registration code assigns minor numbers and registers the new device node
200 * with the kernel. An error is returned if no free minor number can be found,
201 * or if the registration of the device node fails.
202 *
203 * Zero is returned on success.
204 *
205 * Note that if the media_devnode_register call fails, the release() callback of
206 * the media_devnode structure is *not* called, so the caller is responsible for
207 * freeing any data.
208 */
209int __must_check media_devnode_register(struct media_devnode *mdev)
210{
211 int minor;
212 int ret;
213
214 /* Part 1: Find a free minor number */
215 mutex_lock(&media_devnode_lock);
216 minor = find_next_zero_bit(media_devnode_nums, 0, MEDIA_NUM_DEVICES);
217 if (minor == MEDIA_NUM_DEVICES) {
218 mutex_unlock(&media_devnode_lock);
219 printk(KERN_ERR "could not get a free minor\n");
220 return -ENFILE;
221 }
222
223 set_bit(mdev->minor, media_devnode_nums);
224 mutex_unlock(&media_devnode_lock);
225
226 mdev->minor = minor;
227
228 /* Part 2: Initialize and register the character device */
229 cdev_init(&mdev->cdev, &media_devnode_fops);
230 mdev->cdev.owner = mdev->fops->owner;
231
232 ret = cdev_add(&mdev->cdev, MKDEV(MAJOR(media_dev_t), mdev->minor), 1);
233 if (ret < 0) {
234 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
235 goto error;
236 }
237
238 /* Part 3: Register the media device */
239 mdev->dev.bus = &media_bus_type;
240 mdev->dev.devt = MKDEV(MAJOR(media_dev_t), mdev->minor);
241 mdev->dev.release = media_devnode_release;
242 if (mdev->parent)
243 mdev->dev.parent = mdev->parent;
244 dev_set_name(&mdev->dev, "media%d", mdev->minor);
245 ret = device_register(&mdev->dev);
246 if (ret < 0) {
247 printk(KERN_ERR "%s: device_register failed\n", __func__);
248 goto error;
249 }
250
251 /* Part 4: Activate this minor. The char device can now be used. */
252 set_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
253
254 return 0;
255
256error:
257 cdev_del(&mdev->cdev);
258 clear_bit(mdev->minor, media_devnode_nums);
259 return ret;
260}
261
262/**
263 * media_devnode_unregister - unregister a media device node
264 * @mdev: the device node to unregister
265 *
266 * This unregisters the passed device. Future open calls will be met with
267 * errors.
268 *
269 * This function can safely be called if the device node has never been
270 * registered or has already been unregistered.
271 */
272void media_devnode_unregister(struct media_devnode *mdev)
273{
274 /* Check if mdev was ever registered at all */
275 if (!media_devnode_is_registered(mdev))
276 return;
277
278 mutex_lock(&media_devnode_lock);
279 clear_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
280 mutex_unlock(&media_devnode_lock);
281 device_unregister(&mdev->dev);
282}
283
284/*
285 * Initialise media for linux
286 */
287static int __init media_devnode_init(void)
288{
289 int ret;
290
291 printk(KERN_INFO "Linux media interface: v0.10\n");
292 ret = alloc_chrdev_region(&media_dev_t, 0, MEDIA_NUM_DEVICES,
293 MEDIA_NAME);
294 if (ret < 0) {
295 printk(KERN_WARNING "media: unable to allocate major\n");
296 return ret;
297 }
298
299 ret = bus_register(&media_bus_type);
300 if (ret < 0) {
301 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
302 printk(KERN_WARNING "media: bus_register failed\n");
303 return -EIO;
304 }
305
306 return 0;
307}
308
309static void __exit media_devnode_exit(void)
310{
311 bus_unregister(&media_bus_type);
312 unregister_chrdev_region(media_dev_t, MEDIA_NUM_DEVICES);
313}
314
315module_init(media_devnode_init)
316module_exit(media_devnode_exit)
317
318MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>");
319MODULE_DESCRIPTION("Device node registration for media drivers");
320MODULE_LICENSE("GPL");
diff --git a/drivers/media/media-entity.c b/drivers/media/media-entity.c
new file mode 100644
index 000000000000..23640ed44d85
--- /dev/null
+++ b/drivers/media/media-entity.c
@@ -0,0 +1,536 @@
1/*
2 * Media entity
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <media/media-entity.h>
26#include <media/media-device.h>
27
28/**
29 * media_entity_init - Initialize a media entity
30 *
31 * @num_pads: Total number of sink and source pads.
32 * @extra_links: Initial estimate of the number of extra links.
33 * @pads: Array of 'num_pads' pads.
34 *
35 * The total number of pads is an intrinsic property of entities known by the
36 * entity driver, while the total number of links depends on hardware design
37 * and is an extrinsic property unknown to the entity driver. However, in most
38 * use cases the entity driver can guess the number of links which can safely
39 * be assumed to be equal to or larger than the number of pads.
40 *
41 * For those reasons the links array can be preallocated based on the entity
42 * driver guess and will be reallocated later if extra links need to be
43 * created.
44 *
45 * This function allocates a links array with enough space to hold at least
46 * 'num_pads' + 'extra_links' elements. The media_entity::max_links field will
47 * be set to the number of allocated elements.
48 *
49 * The pads array is managed by the entity driver and passed to
50 * media_entity_init() where its pointer will be stored in the entity structure.
51 */
52int
53media_entity_init(struct media_entity *entity, u16 num_pads,
54 struct media_pad *pads, u16 extra_links)
55{
56 struct media_link *links;
57 unsigned int max_links = num_pads + extra_links;
58 unsigned int i;
59
60 links = kzalloc(max_links * sizeof(links[0]), GFP_KERNEL);
61 if (links == NULL)
62 return -ENOMEM;
63
64 entity->group_id = 0;
65 entity->max_links = max_links;
66 entity->num_links = 0;
67 entity->num_backlinks = 0;
68 entity->num_pads = num_pads;
69 entity->pads = pads;
70 entity->links = links;
71
72 for (i = 0; i < num_pads; i++) {
73 pads[i].entity = entity;
74 pads[i].index = i;
75 }
76
77 return 0;
78}
79EXPORT_SYMBOL_GPL(media_entity_init);
80
81void
82media_entity_cleanup(struct media_entity *entity)
83{
84 kfree(entity->links);
85}
86EXPORT_SYMBOL_GPL(media_entity_cleanup);
87
88/* -----------------------------------------------------------------------------
89 * Graph traversal
90 */
91
92static struct media_entity *
93media_entity_other(struct media_entity *entity, struct media_link *link)
94{
95 if (link->source->entity == entity)
96 return link->sink->entity;
97 else
98 return link->source->entity;
99}
100
101/* push an entity to traversal stack */
102static void stack_push(struct media_entity_graph *graph,
103 struct media_entity *entity)
104{
105 if (graph->top == MEDIA_ENTITY_ENUM_MAX_DEPTH - 1) {
106 WARN_ON(1);
107 return;
108 }
109 graph->top++;
110 graph->stack[graph->top].link = 0;
111 graph->stack[graph->top].entity = entity;
112}
113
114static struct media_entity *stack_pop(struct media_entity_graph *graph)
115{
116 struct media_entity *entity;
117
118 entity = graph->stack[graph->top].entity;
119 graph->top--;
120
121 return entity;
122}
123
124#define stack_peek(en) ((en)->stack[(en)->top - 1].entity)
125#define link_top(en) ((en)->stack[(en)->top].link)
126#define stack_top(en) ((en)->stack[(en)->top].entity)
127
128/**
129 * media_entity_graph_walk_start - Start walking the media graph at a given entity
130 * @graph: Media graph structure that will be used to walk the graph
131 * @entity: Starting entity
132 *
133 * This function initializes the graph traversal structure to walk the entities
134 * graph starting at the given entity. The traversal structure must not be
135 * modified by the caller during graph traversal. When done the structure can
136 * safely be freed.
137 */
138void media_entity_graph_walk_start(struct media_entity_graph *graph,
139 struct media_entity *entity)
140{
141 graph->top = 0;
142 graph->stack[graph->top].entity = NULL;
143 stack_push(graph, entity);
144}
145EXPORT_SYMBOL_GPL(media_entity_graph_walk_start);
146
147/**
148 * media_entity_graph_walk_next - Get the next entity in the graph
149 * @graph: Media graph structure
150 *
151 * Perform a depth-first traversal of the given media entities graph.
152 *
153 * The graph structure must have been previously initialized with a call to
154 * media_entity_graph_walk_start().
155 *
156 * Return the next entity in the graph or NULL if the whole graph have been
157 * traversed.
158 */
159struct media_entity *
160media_entity_graph_walk_next(struct media_entity_graph *graph)
161{
162 if (stack_top(graph) == NULL)
163 return NULL;
164
165 /*
166 * Depth first search. Push entity to stack and continue from
167 * top of the stack until no more entities on the level can be
168 * found.
169 */
170 while (link_top(graph) < stack_top(graph)->num_links) {
171 struct media_entity *entity = stack_top(graph);
172 struct media_link *link = &entity->links[link_top(graph)];
173 struct media_entity *next;
174
175 /* The link is not enabled so we do not follow. */
176 if (!(link->flags & MEDIA_LNK_FL_ENABLED)) {
177 link_top(graph)++;
178 continue;
179 }
180
181 /* Get the entity in the other end of the link . */
182 next = media_entity_other(entity, link);
183
184 /* Was it the entity we came here from? */
185 if (next == stack_peek(graph)) {
186 link_top(graph)++;
187 continue;
188 }
189
190 /* Push the new entity to stack and start over. */
191 link_top(graph)++;
192 stack_push(graph, next);
193 }
194
195 return stack_pop(graph);
196}
197EXPORT_SYMBOL_GPL(media_entity_graph_walk_next);
198
199/* -----------------------------------------------------------------------------
200 * Pipeline management
201 */
202
203/**
204 * media_entity_pipeline_start - Mark a pipeline as streaming
205 * @entity: Starting entity
206 * @pipe: Media pipeline to be assigned to all entities in the pipeline.
207 *
208 * Mark all entities connected to a given entity through enabled links, either
209 * directly or indirectly, as streaming. The given pipeline object is assigned to
210 * every entity in the pipeline and stored in the media_entity pipe field.
211 *
212 * Calls to this function can be nested, in which case the same number of
213 * media_entity_pipeline_stop() calls will be required to stop streaming. The
214 * pipeline pointer must be identical for all nested calls to
215 * media_entity_pipeline_start().
216 */
217void media_entity_pipeline_start(struct media_entity *entity,
218 struct media_pipeline *pipe)
219{
220 struct media_device *mdev = entity->parent;
221 struct media_entity_graph graph;
222
223 mutex_lock(&mdev->graph_mutex);
224
225 media_entity_graph_walk_start(&graph, entity);
226
227 while ((entity = media_entity_graph_walk_next(&graph))) {
228 entity->stream_count++;
229 WARN_ON(entity->pipe && entity->pipe != pipe);
230 entity->pipe = pipe;
231 }
232
233 mutex_unlock(&mdev->graph_mutex);
234}
235EXPORT_SYMBOL_GPL(media_entity_pipeline_start);
236
237/**
238 * media_entity_pipeline_stop - Mark a pipeline as not streaming
239 * @entity: Starting entity
240 *
241 * Mark all entities connected to a given entity through enabled links, either
242 * directly or indirectly, as not streaming. The media_entity pipe field is
243 * reset to NULL.
244 *
245 * If multiple calls to media_entity_pipeline_start() have been made, the same
246 * number of calls to this function are required to mark the pipeline as not
247 * streaming.
248 */
249void media_entity_pipeline_stop(struct media_entity *entity)
250{
251 struct media_device *mdev = entity->parent;
252 struct media_entity_graph graph;
253
254 mutex_lock(&mdev->graph_mutex);
255
256 media_entity_graph_walk_start(&graph, entity);
257
258 while ((entity = media_entity_graph_walk_next(&graph))) {
259 entity->stream_count--;
260 if (entity->stream_count == 0)
261 entity->pipe = NULL;
262 }
263
264 mutex_unlock(&mdev->graph_mutex);
265}
266EXPORT_SYMBOL_GPL(media_entity_pipeline_stop);
267
268/* -----------------------------------------------------------------------------
269 * Module use count
270 */
271
272/*
273 * media_entity_get - Get a reference to the parent module
274 * @entity: The entity
275 *
276 * Get a reference to the parent media device module.
277 *
278 * The function will return immediately if @entity is NULL.
279 *
280 * Return a pointer to the entity on success or NULL on failure.
281 */
282struct media_entity *media_entity_get(struct media_entity *entity)
283{
284 if (entity == NULL)
285 return NULL;
286
287 if (entity->parent->dev &&
288 !try_module_get(entity->parent->dev->driver->owner))
289 return NULL;
290
291 return entity;
292}
293EXPORT_SYMBOL_GPL(media_entity_get);
294
295/*
296 * media_entity_put - Release the reference to the parent module
297 * @entity: The entity
298 *
299 * Release the reference count acquired by media_entity_get().
300 *
301 * The function will return immediately if @entity is NULL.
302 */
303void media_entity_put(struct media_entity *entity)
304{
305 if (entity == NULL)
306 return;
307
308 if (entity->parent->dev)
309 module_put(entity->parent->dev->driver->owner);
310}
311EXPORT_SYMBOL_GPL(media_entity_put);
312
313/* -----------------------------------------------------------------------------
314 * Links management
315 */
316
317static struct media_link *media_entity_add_link(struct media_entity *entity)
318{
319 if (entity->num_links >= entity->max_links) {
320 struct media_link *links = entity->links;
321 unsigned int max_links = entity->max_links + 2;
322 unsigned int i;
323
324 links = krealloc(links, max_links * sizeof(*links), GFP_KERNEL);
325 if (links == NULL)
326 return NULL;
327
328 for (i = 0; i < entity->num_links; i++)
329 links[i].reverse->reverse = &links[i];
330
331 entity->max_links = max_links;
332 entity->links = links;
333 }
334
335 return &entity->links[entity->num_links++];
336}
337
338int
339media_entity_create_link(struct media_entity *source, u16 source_pad,
340 struct media_entity *sink, u16 sink_pad, u32 flags)
341{
342 struct media_link *link;
343 struct media_link *backlink;
344
345 BUG_ON(source == NULL || sink == NULL);
346 BUG_ON(source_pad >= source->num_pads);
347 BUG_ON(sink_pad >= sink->num_pads);
348
349 link = media_entity_add_link(source);
350 if (link == NULL)
351 return -ENOMEM;
352
353 link->source = &source->pads[source_pad];
354 link->sink = &sink->pads[sink_pad];
355 link->flags = flags;
356
357 /* Create the backlink. Backlinks are used to help graph traversal and
358 * are not reported to userspace.
359 */
360 backlink = media_entity_add_link(sink);
361 if (backlink == NULL) {
362 source->num_links--;
363 return -ENOMEM;
364 }
365
366 backlink->source = &source->pads[source_pad];
367 backlink->sink = &sink->pads[sink_pad];
368 backlink->flags = flags;
369
370 link->reverse = backlink;
371 backlink->reverse = link;
372
373 sink->num_backlinks++;
374
375 return 0;
376}
377EXPORT_SYMBOL_GPL(media_entity_create_link);
378
379static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
380{
381 const u32 mask = MEDIA_LNK_FL_ENABLED;
382 int ret;
383
384 /* Notify both entities. */
385 ret = media_entity_call(link->source->entity, link_setup,
386 link->source, link->sink, flags);
387 if (ret < 0 && ret != -ENOIOCTLCMD)
388 return ret;
389
390 ret = media_entity_call(link->sink->entity, link_setup,
391 link->sink, link->source, flags);
392 if (ret < 0 && ret != -ENOIOCTLCMD) {
393 media_entity_call(link->source->entity, link_setup,
394 link->source, link->sink, link->flags);
395 return ret;
396 }
397
398 link->flags = (link->flags & ~mask) | (flags & mask);
399 link->reverse->flags = link->flags;
400
401 return 0;
402}
403
404/**
405 * __media_entity_setup_link - Configure a media link
406 * @link: The link being configured
407 * @flags: Link configuration flags
408 *
409 * The bulk of link setup is handled by the two entities connected through the
410 * link. This function notifies both entities of the link configuration change.
411 *
412 * If the link is immutable or if the current and new configuration are
413 * identical, return immediately.
414 *
415 * The user is expected to hold link->source->parent->mutex. If not,
416 * media_entity_setup_link() should be used instead.
417 */
418int __media_entity_setup_link(struct media_link *link, u32 flags)
419{
420 struct media_device *mdev;
421 struct media_entity *source, *sink;
422 int ret = -EBUSY;
423
424 if (link == NULL)
425 return -EINVAL;
426
427 if (link->flags & MEDIA_LNK_FL_IMMUTABLE)
428 return link->flags == flags ? 0 : -EINVAL;
429
430 if (link->flags == flags)
431 return 0;
432
433 source = link->source->entity;
434 sink = link->sink->entity;
435
436 if (!(link->flags & MEDIA_LNK_FL_DYNAMIC) &&
437 (source->stream_count || sink->stream_count))
438 return -EBUSY;
439
440 mdev = source->parent;
441
442 if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify) {
443 ret = mdev->link_notify(link->source, link->sink,
444 MEDIA_LNK_FL_ENABLED);
445 if (ret < 0)
446 return ret;
447 }
448
449 ret = __media_entity_setup_link_notify(link, flags);
450 if (ret < 0)
451 goto err;
452
453 if (!(flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
454 mdev->link_notify(link->source, link->sink, 0);
455
456 return 0;
457
458err:
459 if ((flags & MEDIA_LNK_FL_ENABLED) && mdev->link_notify)
460 mdev->link_notify(link->source, link->sink, 0);
461
462 return ret;
463}
464
465int media_entity_setup_link(struct media_link *link, u32 flags)
466{
467 int ret;
468
469 mutex_lock(&link->source->entity->parent->graph_mutex);
470 ret = __media_entity_setup_link(link, flags);
471 mutex_unlock(&link->source->entity->parent->graph_mutex);
472
473 return ret;
474}
475EXPORT_SYMBOL_GPL(media_entity_setup_link);
476
477/**
478 * media_entity_find_link - Find a link between two pads
479 * @source: Source pad
480 * @sink: Sink pad
481 *
482 * Return a pointer to the link between the two entities. If no such link
483 * exists, return NULL.
484 */
485struct media_link *
486media_entity_find_link(struct media_pad *source, struct media_pad *sink)
487{
488 struct media_link *link;
489 unsigned int i;
490
491 for (i = 0; i < source->entity->num_links; ++i) {
492 link = &source->entity->links[i];
493
494 if (link->source->entity == source->entity &&
495 link->source->index == source->index &&
496 link->sink->entity == sink->entity &&
497 link->sink->index == sink->index)
498 return link;
499 }
500
501 return NULL;
502}
503EXPORT_SYMBOL_GPL(media_entity_find_link);
504
505/**
506 * media_entity_remote_source - Find the source pad at the remote end of a link
507 * @pad: Sink pad at the local end of the link
508 *
509 * Search for a remote source pad connected to the given sink pad by iterating
510 * over all links originating or terminating at that pad until an enabled link
511 * is found.
512 *
513 * Return a pointer to the pad at the remote end of the first found enabled
514 * link, or NULL if no enabled link has been found.
515 */
516struct media_pad *media_entity_remote_source(struct media_pad *pad)
517{
518 unsigned int i;
519
520 for (i = 0; i < pad->entity->num_links; i++) {
521 struct media_link *link = &pad->entity->links[i];
522
523 if (!(link->flags & MEDIA_LNK_FL_ENABLED))
524 continue;
525
526 if (link->source == pad)
527 return link->sink;
528
529 if (link->sink == pad)
530 return link->source;
531 }
532
533 return NULL;
534
535}
536EXPORT_SYMBOL_GPL(media_entity_remote_source);
diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig
index ecdffa6aac66..299994c3aa74 100644
--- a/drivers/media/radio/Kconfig
+++ b/drivers/media/radio/Kconfig
@@ -441,6 +441,7 @@ config RADIO_TIMBERDALE
441config RADIO_WL1273 441config RADIO_WL1273
442 tristate "Texas Instruments WL1273 I2C FM Radio" 442 tristate "Texas Instruments WL1273 I2C FM Radio"
443 depends on I2C && VIDEO_V4L2 443 depends on I2C && VIDEO_V4L2
444 select MFD_CORE
444 select MFD_WL1273_CORE 445 select MFD_WL1273_CORE
445 select FW_LOADER 446 select FW_LOADER
446 ---help--- 447 ---help---
@@ -454,4 +455,7 @@ config RADIO_WL1273
454 To compile this driver as a module, choose M here: the 455 To compile this driver as a module, choose M here: the
455 module will be called radio-wl1273. 456 module will be called radio-wl1273.
456 457
458# TI's ST based wl128x FM radio
459source "drivers/media/radio/wl128x/Kconfig"
460
457endif # RADIO_ADAPTERS 461endif # RADIO_ADAPTERS
diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile
index 717656d2f749..2faa33371986 100644
--- a/drivers/media/radio/Makefile
+++ b/drivers/media/radio/Makefile
@@ -26,5 +26,6 @@ obj-$(CONFIG_RADIO_SAA7706H) += saa7706h.o
26obj-$(CONFIG_RADIO_TEF6862) += tef6862.o 26obj-$(CONFIG_RADIO_TEF6862) += tef6862.o
27obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o 27obj-$(CONFIG_RADIO_TIMBERDALE) += radio-timb.o
28obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o 28obj-$(CONFIG_RADIO_WL1273) += radio-wl1273.o
29obj-$(CONFIG_RADIO_WL128X) += wl128x/
29 30
30EXTRA_CFLAGS += -Isound 31EXTRA_CFLAGS += -Isound
diff --git a/drivers/media/radio/dsbr100.c b/drivers/media/radio/dsbr100.c
index ed9cd7ad0604..3d8cc425fa6b 100644
--- a/drivers/media/radio/dsbr100.c
+++ b/drivers/media/radio/dsbr100.c
@@ -129,7 +129,7 @@ devices, that would be 76 and 91. */
129#define STARTED 0 129#define STARTED 0
130#define STOPPED 1 130#define STOPPED 1
131 131
132#define videodev_to_radio(d) container_of(d, struct dsbr100_device, videodev) 132#define v4l2_dev_to_radio(d) container_of(d, struct dsbr100_device, v4l2_dev)
133 133
134static int usb_dsbr100_probe(struct usb_interface *intf, 134static int usb_dsbr100_probe(struct usb_interface *intf,
135 const struct usb_device_id *id); 135 const struct usb_device_id *id);
@@ -148,10 +148,9 @@ struct dsbr100_device {
148 struct v4l2_device v4l2_dev; 148 struct v4l2_device v4l2_dev;
149 149
150 u8 *transfer_buffer; 150 u8 *transfer_buffer;
151 struct mutex lock; /* buffer locking */ 151 struct mutex v4l2_lock;
152 int curfreq; 152 int curfreq;
153 int stereo; 153 int stereo;
154 int removed;
155 int status; 154 int status;
156}; 155};
157 156
@@ -182,8 +181,6 @@ static int dsbr100_start(struct dsbr100_device *radio)
182 int retval; 181 int retval;
183 int request; 182 int request;
184 183
185 mutex_lock(&radio->lock);
186
187 retval = usb_control_msg(radio->usbdev, 184 retval = usb_control_msg(radio->usbdev,
188 usb_rcvctrlpipe(radio->usbdev, 0), 185 usb_rcvctrlpipe(radio->usbdev, 0),
189 USB_REQ_GET_STATUS, 186 USB_REQ_GET_STATUS,
@@ -207,11 +204,9 @@ static int dsbr100_start(struct dsbr100_device *radio)
207 } 204 }
208 205
209 radio->status = STARTED; 206 radio->status = STARTED;
210 mutex_unlock(&radio->lock);
211 return (radio->transfer_buffer)[0]; 207 return (radio->transfer_buffer)[0];
212 208
213usb_control_msg_failed: 209usb_control_msg_failed:
214 mutex_unlock(&radio->lock);
215 dev_err(&radio->usbdev->dev, 210 dev_err(&radio->usbdev->dev,
216 "%s - usb_control_msg returned %i, request %i\n", 211 "%s - usb_control_msg returned %i, request %i\n",
217 __func__, retval, request); 212 __func__, retval, request);
@@ -225,8 +220,6 @@ static int dsbr100_stop(struct dsbr100_device *radio)
225 int retval; 220 int retval;
226 int request; 221 int request;
227 222
228 mutex_lock(&radio->lock);
229
230 retval = usb_control_msg(radio->usbdev, 223 retval = usb_control_msg(radio->usbdev,
231 usb_rcvctrlpipe(radio->usbdev, 0), 224 usb_rcvctrlpipe(radio->usbdev, 0),
232 USB_REQ_GET_STATUS, 225 USB_REQ_GET_STATUS,
@@ -250,11 +243,9 @@ static int dsbr100_stop(struct dsbr100_device *radio)
250 } 243 }
251 244
252 radio->status = STOPPED; 245 radio->status = STOPPED;
253 mutex_unlock(&radio->lock);
254 return (radio->transfer_buffer)[0]; 246 return (radio->transfer_buffer)[0];
255 247
256usb_control_msg_failed: 248usb_control_msg_failed:
257 mutex_unlock(&radio->lock);
258 dev_err(&radio->usbdev->dev, 249 dev_err(&radio->usbdev->dev,
259 "%s - usb_control_msg returned %i, request %i\n", 250 "%s - usb_control_msg returned %i, request %i\n",
260 __func__, retval, request); 251 __func__, retval, request);
@@ -269,8 +260,6 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
269 int request; 260 int request;
270 int freq = (radio->curfreq / 16 * 80) / 1000 + 856; 261 int freq = (radio->curfreq / 16 * 80) / 1000 + 856;
271 262
272 mutex_lock(&radio->lock);
273
274 retval = usb_control_msg(radio->usbdev, 263 retval = usb_control_msg(radio->usbdev,
275 usb_rcvctrlpipe(radio->usbdev, 0), 264 usb_rcvctrlpipe(radio->usbdev, 0),
276 DSB100_TUNE, 265 DSB100_TUNE,
@@ -306,12 +295,10 @@ static int dsbr100_setfreq(struct dsbr100_device *radio)
306 } 295 }
307 296
308 radio->stereo = !((radio->transfer_buffer)[0] & 0x01); 297 radio->stereo = !((radio->transfer_buffer)[0] & 0x01);
309 mutex_unlock(&radio->lock);
310 return (radio->transfer_buffer)[0]; 298 return (radio->transfer_buffer)[0];
311 299
312usb_control_msg_failed: 300usb_control_msg_failed:
313 radio->stereo = -1; 301 radio->stereo = -1;
314 mutex_unlock(&radio->lock);
315 dev_err(&radio->usbdev->dev, 302 dev_err(&radio->usbdev->dev,
316 "%s - usb_control_msg returned %i, request %i\n", 303 "%s - usb_control_msg returned %i, request %i\n",
317 __func__, retval, request); 304 __func__, retval, request);
@@ -324,8 +311,6 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
324{ 311{
325 int retval; 312 int retval;
326 313
327 mutex_lock(&radio->lock);
328
329 retval = usb_control_msg(radio->usbdev, 314 retval = usb_control_msg(radio->usbdev,
330 usb_rcvctrlpipe(radio->usbdev, 0), 315 usb_rcvctrlpipe(radio->usbdev, 0),
331 USB_REQ_GET_STATUS, 316 USB_REQ_GET_STATUS,
@@ -340,33 +325,8 @@ static void dsbr100_getstat(struct dsbr100_device *radio)
340 } else { 325 } else {
341 radio->stereo = !(radio->transfer_buffer[0] & 0x01); 326 radio->stereo = !(radio->transfer_buffer[0] & 0x01);
342 } 327 }
343
344 mutex_unlock(&radio->lock);
345} 328}
346 329
347/* USB subsystem interface begins here */
348
349/*
350 * Handle unplugging of the device.
351 * We call video_unregister_device in any case.
352 * The last function called in this procedure is
353 * usb_dsbr100_video_device_release
354 */
355static void usb_dsbr100_disconnect(struct usb_interface *intf)
356{
357 struct dsbr100_device *radio = usb_get_intfdata(intf);
358
359 usb_set_intfdata (intf, NULL);
360
361 mutex_lock(&radio->lock);
362 radio->removed = 1;
363 mutex_unlock(&radio->lock);
364
365 video_unregister_device(&radio->videodev);
366 v4l2_device_disconnect(&radio->v4l2_dev);
367}
368
369
370static int vidioc_querycap(struct file *file, void *priv, 330static int vidioc_querycap(struct file *file, void *priv,
371 struct v4l2_capability *v) 331 struct v4l2_capability *v)
372{ 332{
@@ -385,10 +345,6 @@ static int vidioc_g_tuner(struct file *file, void *priv,
385{ 345{
386 struct dsbr100_device *radio = video_drvdata(file); 346 struct dsbr100_device *radio = video_drvdata(file);
387 347
388 /* safety check */
389 if (radio->removed)
390 return -EIO;
391
392 if (v->index > 0) 348 if (v->index > 0)
393 return -EINVAL; 349 return -EINVAL;
394 350
@@ -410,16 +366,7 @@ static int vidioc_g_tuner(struct file *file, void *priv,
410static int vidioc_s_tuner(struct file *file, void *priv, 366static int vidioc_s_tuner(struct file *file, void *priv,
411 struct v4l2_tuner *v) 367 struct v4l2_tuner *v)
412{ 368{
413 struct dsbr100_device *radio = video_drvdata(file); 369 return v->index ? -EINVAL : 0;
414
415 /* safety check */
416 if (radio->removed)
417 return -EIO;
418
419 if (v->index > 0)
420 return -EINVAL;
421
422 return 0;
423} 370}
424 371
425static int vidioc_s_frequency(struct file *file, void *priv, 372static int vidioc_s_frequency(struct file *file, void *priv,
@@ -428,13 +375,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
428 struct dsbr100_device *radio = video_drvdata(file); 375 struct dsbr100_device *radio = video_drvdata(file);
429 int retval; 376 int retval;
430 377
431 /* safety check */
432 if (radio->removed)
433 return -EIO;
434
435 mutex_lock(&radio->lock);
436 radio->curfreq = f->frequency; 378 radio->curfreq = f->frequency;
437 mutex_unlock(&radio->lock);
438 379
439 retval = dsbr100_setfreq(radio); 380 retval = dsbr100_setfreq(radio);
440 if (retval < 0) 381 if (retval < 0)
@@ -447,10 +388,6 @@ static int vidioc_g_frequency(struct file *file, void *priv,
447{ 388{
448 struct dsbr100_device *radio = video_drvdata(file); 389 struct dsbr100_device *radio = video_drvdata(file);
449 390
450 /* safety check */
451 if (radio->removed)
452 return -EIO;
453
454 f->type = V4L2_TUNER_RADIO; 391 f->type = V4L2_TUNER_RADIO;
455 f->frequency = radio->curfreq; 392 f->frequency = radio->curfreq;
456 return 0; 393 return 0;
@@ -472,10 +409,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
472{ 409{
473 struct dsbr100_device *radio = video_drvdata(file); 410 struct dsbr100_device *radio = video_drvdata(file);
474 411
475 /* safety check */
476 if (radio->removed)
477 return -EIO;
478
479 switch (ctrl->id) { 412 switch (ctrl->id) {
480 case V4L2_CID_AUDIO_MUTE: 413 case V4L2_CID_AUDIO_MUTE:
481 ctrl->value = radio->status; 414 ctrl->value = radio->status;
@@ -490,10 +423,6 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
490 struct dsbr100_device *radio = video_drvdata(file); 423 struct dsbr100_device *radio = video_drvdata(file);
491 int retval; 424 int retval;
492 425
493 /* safety check */
494 if (radio->removed)
495 return -EIO;
496
497 switch (ctrl->id) { 426 switch (ctrl->id) {
498 case V4L2_CID_AUDIO_MUTE: 427 case V4L2_CID_AUDIO_MUTE:
499 if (ctrl->value) { 428 if (ctrl->value) {
@@ -535,25 +464,44 @@ static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
535 464
536static int vidioc_s_input(struct file *filp, void *priv, unsigned int i) 465static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
537{ 466{
538 if (i != 0) 467 return i ? -EINVAL : 0;
539 return -EINVAL;
540 return 0;
541} 468}
542 469
543static int vidioc_s_audio(struct file *file, void *priv, 470static int vidioc_s_audio(struct file *file, void *priv,
544 struct v4l2_audio *a) 471 struct v4l2_audio *a)
545{ 472{
546 if (a->index != 0) 473 return a->index ? -EINVAL : 0;
547 return -EINVAL; 474}
548 return 0; 475
476/* USB subsystem interface begins here */
477
478/*
479 * Handle unplugging of the device.
480 * We call video_unregister_device in any case.
481 * The last function called in this procedure is
482 * usb_dsbr100_video_device_release
483 */
484static void usb_dsbr100_disconnect(struct usb_interface *intf)
485{
486 struct dsbr100_device *radio = usb_get_intfdata(intf);
487
488 v4l2_device_get(&radio->v4l2_dev);
489 mutex_lock(&radio->v4l2_lock);
490 usb_set_intfdata(intf, NULL);
491 video_unregister_device(&radio->videodev);
492 v4l2_device_disconnect(&radio->v4l2_dev);
493 mutex_unlock(&radio->v4l2_lock);
494 v4l2_device_put(&radio->v4l2_dev);
549} 495}
550 496
497
551/* Suspend device - stop device. */ 498/* Suspend device - stop device. */
552static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message) 499static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
553{ 500{
554 struct dsbr100_device *radio = usb_get_intfdata(intf); 501 struct dsbr100_device *radio = usb_get_intfdata(intf);
555 int retval; 502 int retval;
556 503
504 mutex_lock(&radio->v4l2_lock);
557 if (radio->status == STARTED) { 505 if (radio->status == STARTED) {
558 retval = dsbr100_stop(radio); 506 retval = dsbr100_stop(radio);
559 if (retval < 0) 507 if (retval < 0)
@@ -564,11 +512,9 @@ static int usb_dsbr100_suspend(struct usb_interface *intf, pm_message_t message)
564 * we set status equal to STARTED. 512 * we set status equal to STARTED.
565 * On resume we will check status and run radio if needed. 513 * On resume we will check status and run radio if needed.
566 */ 514 */
567
568 mutex_lock(&radio->lock);
569 radio->status = STARTED; 515 radio->status = STARTED;
570 mutex_unlock(&radio->lock);
571 } 516 }
517 mutex_unlock(&radio->v4l2_lock);
572 518
573 dev_info(&intf->dev, "going into suspend..\n"); 519 dev_info(&intf->dev, "going into suspend..\n");
574 520
@@ -581,11 +527,13 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
581 struct dsbr100_device *radio = usb_get_intfdata(intf); 527 struct dsbr100_device *radio = usb_get_intfdata(intf);
582 int retval; 528 int retval;
583 529
530 mutex_lock(&radio->v4l2_lock);
584 if (radio->status == STARTED) { 531 if (radio->status == STARTED) {
585 retval = dsbr100_start(radio); 532 retval = dsbr100_start(radio);
586 if (retval < 0) 533 if (retval < 0)
587 dev_warn(&intf->dev, "dsbr100_start failed\n"); 534 dev_warn(&intf->dev, "dsbr100_start failed\n");
588 } 535 }
536 mutex_unlock(&radio->v4l2_lock);
589 537
590 dev_info(&intf->dev, "coming out of suspend..\n"); 538 dev_info(&intf->dev, "coming out of suspend..\n");
591 539
@@ -593,9 +541,9 @@ static int usb_dsbr100_resume(struct usb_interface *intf)
593} 541}
594 542
595/* free data structures */ 543/* free data structures */
596static void usb_dsbr100_video_device_release(struct video_device *videodev) 544static void usb_dsbr100_release(struct v4l2_device *v4l2_dev)
597{ 545{
598 struct dsbr100_device *radio = videodev_to_radio(videodev); 546 struct dsbr100_device *radio = v4l2_dev_to_radio(v4l2_dev);
599 547
600 v4l2_device_unregister(&radio->v4l2_dev); 548 v4l2_device_unregister(&radio->v4l2_dev);
601 kfree(radio->transfer_buffer); 549 kfree(radio->transfer_buffer);
@@ -605,7 +553,7 @@ static void usb_dsbr100_video_device_release(struct video_device *videodev)
605/* File system interface */ 553/* File system interface */
606static const struct v4l2_file_operations usb_dsbr100_fops = { 554static const struct v4l2_file_operations usb_dsbr100_fops = {
607 .owner = THIS_MODULE, 555 .owner = THIS_MODULE,
608 .ioctl = video_ioctl2, 556 .unlocked_ioctl = video_ioctl2,
609}; 557};
610 558
611static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = { 559static const struct v4l2_ioctl_ops usb_dsbr100_ioctl_ops = {
@@ -644,6 +592,7 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
644 } 592 }
645 593
646 v4l2_dev = &radio->v4l2_dev; 594 v4l2_dev = &radio->v4l2_dev;
595 v4l2_dev->release = usb_dsbr100_release;
647 596
648 retval = v4l2_device_register(&intf->dev, v4l2_dev); 597 retval = v4l2_device_register(&intf->dev, v4l2_dev);
649 if (retval < 0) { 598 if (retval < 0) {
@@ -653,15 +602,14 @@ static int usb_dsbr100_probe(struct usb_interface *intf,
653 return retval; 602 return retval;
654 } 603 }
655 604
605 mutex_init(&radio->v4l2_lock);
656 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name)); 606 strlcpy(radio->videodev.name, v4l2_dev->name, sizeof(radio->videodev.name));
657 radio->videodev.v4l2_dev = v4l2_dev; 607 radio->videodev.v4l2_dev = v4l2_dev;
658 radio->videodev.fops = &usb_dsbr100_fops; 608 radio->videodev.fops = &usb_dsbr100_fops;
659 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops; 609 radio->videodev.ioctl_ops = &usb_dsbr100_ioctl_ops;
660 radio->videodev.release = usb_dsbr100_video_device_release; 610 radio->videodev.release = video_device_release_empty;
661 611 radio->videodev.lock = &radio->v4l2_lock;
662 mutex_init(&radio->lock);
663 612
664 radio->removed = 0;
665 radio->usbdev = interface_to_usbdev(intf); 613 radio->usbdev = interface_to_usbdev(intf);
666 radio->curfreq = FREQ_MIN * FREQ_MUL; 614 radio->curfreq = FREQ_MIN * FREQ_MUL;
667 radio->status = STOPPED; 615 radio->status = STOPPED;
diff --git a/drivers/media/radio/radio-si4713.c b/drivers/media/radio/radio-si4713.c
index 726d367ad8d0..444b4cf7e65c 100644
--- a/drivers/media/radio/radio-si4713.c
+++ b/drivers/media/radio/radio-si4713.c
@@ -224,7 +224,8 @@ static int radio_si4713_s_frequency(struct file *file, void *p,
224 s_frequency, vf); 224 s_frequency, vf);
225} 225}
226 226
227static long radio_si4713_default(struct file *file, void *p, int cmd, void *arg) 227static long radio_si4713_default(struct file *file, void *p,
228 bool valid_prio, int cmd, void *arg)
228{ 229{
229 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core, 230 return v4l2_device_call_until_err(get_v4l2_dev(file), 0, core,
230 ioctl, cmd, arg); 231 ioctl, cmd, arg);
diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio-wl1273.c
index 4698eb00b59f..e2550dc2944f 100644
--- a/drivers/media/radio/radio-wl1273.c
+++ b/drivers/media/radio/radio-wl1273.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Driver for the Texas Instruments WL1273 FM radio. 2 * Driver for the Texas Instruments WL1273 FM radio.
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2011 Nokia Corporation
5 * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com> 5 * Author: Matti J. Aaltonen <matti.j.aaltonen@nokia.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or 7 * This program is free software; you can redistribute it and/or
@@ -67,7 +67,6 @@ struct wl1273_device {
67 67
68 /* RDS */ 68 /* RDS */
69 unsigned int rds_on; 69 unsigned int rds_on;
70 struct delayed_work work;
71 70
72 wait_queue_head_t read_queue; 71 wait_queue_head_t read_queue;
73 struct mutex lock; /* for serializing fm radio operations */ 72 struct mutex lock; /* for serializing fm radio operations */
@@ -104,58 +103,6 @@ static unsigned int rds_buf = 100;
104module_param(rds_buf, uint, 0); 103module_param(rds_buf, uint, 0);
105MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100"); 104MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default = 100");
106 105
107static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
108{
109 struct i2c_client *client = core->client;
110 u8 b[2];
111 int r;
112
113 r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
114 if (r != 2) {
115 dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
116 return -EREMOTEIO;
117 }
118
119 *value = (u16)b[0] << 8 | b[1];
120
121 return 0;
122}
123
124static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
125{
126 struct i2c_client *client = core->client;
127 u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
128 int r;
129
130 r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
131 if (r) {
132 dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
133 return r;
134 }
135
136 return 0;
137}
138
139static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
140{
141 struct i2c_client *client = core->client;
142 struct i2c_msg msg;
143 int r;
144
145 msg.addr = client->addr;
146 msg.flags = 0;
147 msg.buf = data;
148 msg.len = len;
149
150 r = i2c_transfer(client->adapter, &msg, 1);
151 if (r != 1) {
152 dev_err(&client->dev, "%s: write error.\n", __func__);
153 return -EREMOTEIO;
154 }
155
156 return 0;
157}
158
159static int wl1273_fm_write_fw(struct wl1273_core *core, 106static int wl1273_fm_write_fw(struct wl1273_core *core,
160 __u8 *fw, int len) 107 __u8 *fw, int len)
161{ 108{
@@ -188,94 +135,6 @@ static int wl1273_fm_write_fw(struct wl1273_core *core,
188 return r; 135 return r;
189} 136}
190 137
191/**
192 * wl1273_fm_set_audio() - Set audio mode.
193 * @core: A pointer to the device struct.
194 * @new_mode: The new audio mode.
195 *
196 * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
197 */
198static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
199{
200 int r = 0;
201
202 if (core->mode == WL1273_MODE_OFF ||
203 core->mode == WL1273_MODE_SUSPENDED)
204 return -EPERM;
205
206 if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
207 r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
208 WL1273_PCM_DEF_MODE);
209 if (r)
210 goto out;
211
212 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
213 core->i2s_mode);
214 if (r)
215 goto out;
216
217 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
218 WL1273_AUDIO_ENABLE_I2S);
219 if (r)
220 goto out;
221
222 } else if (core->mode == WL1273_MODE_RX &&
223 new_mode == WL1273_AUDIO_ANALOG) {
224 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
225 WL1273_AUDIO_ENABLE_ANALOG);
226 if (r)
227 goto out;
228
229 } else if (core->mode == WL1273_MODE_TX &&
230 new_mode == WL1273_AUDIO_DIGITAL) {
231 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
232 core->i2s_mode);
233 if (r)
234 goto out;
235
236 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
237 WL1273_AUDIO_IO_SET_I2S);
238 if (r)
239 goto out;
240
241 } else if (core->mode == WL1273_MODE_TX &&
242 new_mode == WL1273_AUDIO_ANALOG) {
243 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
244 WL1273_AUDIO_IO_SET_ANALOG);
245 if (r)
246 goto out;
247 }
248
249 core->audio_mode = new_mode;
250out:
251 return r;
252}
253
254/**
255 * wl1273_fm_set_volume() - Set volume.
256 * @core: A pointer to the device struct.
257 * @volume: The new volume value.
258 */
259static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
260{
261 u16 val;
262 int r;
263
264 if (volume > WL1273_MAX_VOLUME)
265 return -EINVAL;
266
267 if (core->volume == volume)
268 return 0;
269
270 val = volume;
271 r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val);
272 if (r)
273 return r;
274
275 core->volume = volume;
276 return 0;
277}
278
279#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status) 138#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status)
280#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3) 139#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3)
281#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4) 140#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4)
@@ -306,7 +165,7 @@ static int wl1273_fm_rds(struct wl1273_device *radio)
306 if (core->mode != WL1273_MODE_RX) 165 if (core->mode != WL1273_MODE_RX)
307 return 0; 166 return 0;
308 167
309 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 168 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
310 if (r) 169 if (r)
311 return r; 170 return r;
312 171
@@ -374,7 +233,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
374 u16 flags; 233 u16 flags;
375 int r; 234 int r;
376 235
377 r = wl1273_fm_read_reg(core, WL1273_FLAG_GET, &flags); 236 r = core->read(core, WL1273_FLAG_GET, &flags);
378 if (r) 237 if (r)
379 goto out; 238 goto out;
380 239
@@ -398,7 +257,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
398 if (flags & WL1273_LEV_EVENT) { 257 if (flags & WL1273_LEV_EVENT) {
399 u16 level; 258 u16 level;
400 259
401 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &level); 260 r = core->read(core, WL1273_RSSI_LVL_GET, &level);
402 if (r) 261 if (r)
403 goto out; 262 goto out;
404 263
@@ -439,8 +298,8 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
439 dev_dbg(radio->dev, "IRQ: FR:\n"); 298 dev_dbg(radio->dev, "IRQ: FR:\n");
440 299
441 if (core->mode == WL1273_MODE_RX) { 300 if (core->mode == WL1273_MODE_RX) {
442 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 301 r = core->write(core, WL1273_TUNER_MODE_SET,
443 TUNER_MODE_STOP_SEARCH); 302 TUNER_MODE_STOP_SEARCH);
444 if (r) { 303 if (r) {
445 dev_err(radio->dev, 304 dev_err(radio->dev,
446 "%s: TUNER_MODE_SET fails: %d\n", 305 "%s: TUNER_MODE_SET fails: %d\n",
@@ -448,7 +307,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
448 goto out; 307 goto out;
449 } 308 }
450 309
451 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &freq); 310 r = core->read(core, WL1273_FREQ_SET, &freq);
452 if (r) 311 if (r)
453 goto out; 312 goto out;
454 313
@@ -467,7 +326,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
467 dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency); 326 dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency);
468 327
469 } else { 328 } else {
470 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &freq); 329 r = core->read(core, WL1273_CHANL_SET, &freq);
471 if (r) 330 if (r)
472 goto out; 331 goto out;
473 332
@@ -477,8 +336,7 @@ static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id)
477 } 336 }
478 337
479out: 338out:
480 wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 339 core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
481 radio->irq_flags);
482 complete(&radio->busy); 340 complete(&radio->busy);
483 341
484 return IRQ_HANDLED; 342 return IRQ_HANDLED;
@@ -512,7 +370,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
512 dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq); 370 dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq);
513 371
514 /* Set the current tx channel */ 372 /* Set the current tx channel */
515 r = wl1273_fm_write_cmd(core, WL1273_CHANL_SET, freq / 10); 373 r = core->write(core, WL1273_CHANL_SET, freq / 10);
516 if (r) 374 if (r)
517 return r; 375 return r;
518 376
@@ -526,7 +384,7 @@ static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int freq)
526 dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r); 384 dev_dbg(radio->dev, "WL1273_CHANL_SET: %d\n", r);
527 385
528 /* Enable the output power */ 386 /* Enable the output power */
529 r = wl1273_fm_write_cmd(core, WL1273_POWER_ENB_SET, 1); 387 r = core->write(core, WL1273_POWER_ENB_SET, 1);
530 if (r) 388 if (r)
531 return r; 389 return r;
532 390
@@ -566,20 +424,20 @@ static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int freq)
566 424
567 dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq); 425 dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq);
568 426
569 wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 427 core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
570 428
571 if (radio->band == WL1273_BAND_JAPAN) 429 if (radio->band == WL1273_BAND_JAPAN)
572 f = (freq - WL1273_BAND_JAPAN_LOW) / 50; 430 f = (freq - WL1273_BAND_JAPAN_LOW) / 50;
573 else 431 else
574 f = (freq - WL1273_BAND_OTHER_LOW) / 50; 432 f = (freq - WL1273_BAND_OTHER_LOW) / 50;
575 433
576 r = wl1273_fm_write_cmd(core, WL1273_FREQ_SET, f); 434 r = core->write(core, WL1273_FREQ_SET, f);
577 if (r) { 435 if (r) {
578 dev_err(radio->dev, "FREQ_SET fails\n"); 436 dev_err(radio->dev, "FREQ_SET fails\n");
579 goto err; 437 goto err;
580 } 438 }
581 439
582 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET); 440 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET);
583 if (r) { 441 if (r) {
584 dev_err(radio->dev, "TUNER_MODE_SET fails\n"); 442 dev_err(radio->dev, "TUNER_MODE_SET fails\n");
585 goto err; 443 goto err;
@@ -609,7 +467,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
609 int r; 467 int r;
610 468
611 if (core->mode == WL1273_MODE_RX) { 469 if (core->mode == WL1273_MODE_RX) {
612 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &f); 470 r = core->read(core, WL1273_FREQ_SET, &f);
613 if (r) 471 if (r)
614 return r; 472 return r;
615 473
@@ -619,7 +477,7 @@ static int wl1273_fm_get_freq(struct wl1273_device *radio)
619 else 477 else
620 freq = WL1273_BAND_OTHER_LOW + 50 * f; 478 freq = WL1273_BAND_OTHER_LOW + 50 * f;
621 } else { 479 } else {
622 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &f); 480 r = core->read(core, WL1273_CHANL_SET, &f);
623 if (r) 481 if (r)
624 return r; 482 return r;
625 483
@@ -670,7 +528,7 @@ static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio)
670 } 528 }
671 529
672 /* ignore possible error here */ 530 /* ignore possible error here */
673 wl1273_fm_write_cmd(core, WL1273_RESET, 0); 531 core->write(core, WL1273_RESET, 0);
674 532
675 dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r); 533 dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r);
676out: 534out:
@@ -683,14 +541,14 @@ static int wl1273_fm_stop(struct wl1273_device *radio)
683 struct wl1273_core *core = radio->core; 541 struct wl1273_core *core = radio->core;
684 542
685 if (core->mode == WL1273_MODE_RX) { 543 if (core->mode == WL1273_MODE_RX) {
686 int r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 544 int r = core->write(core, WL1273_POWER_SET,
687 WL1273_POWER_SET_OFF); 545 WL1273_POWER_SET_OFF);
688 if (r) 546 if (r)
689 dev_err(radio->dev, "%s: POWER_SET fails: %d\n", 547 dev_err(radio->dev, "%s: POWER_SET fails: %d\n",
690 __func__, r); 548 __func__, r);
691 } else if (core->mode == WL1273_MODE_TX) { 549 } else if (core->mode == WL1273_MODE_TX) {
692 int r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 550 int r = core->write(core, WL1273_PUPD_SET,
693 WL1273_PUPD_SET_OFF); 551 WL1273_PUPD_SET_OFF);
694 if (r) 552 if (r)
695 dev_err(radio->dev, 553 dev_err(radio->dev,
696 "%s: PUPD_SET fails: %d\n", __func__, r); 554 "%s: PUPD_SET fails: %d\n", __func__, r);
@@ -725,11 +583,11 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
725 val |= WL1273_POWER_SET_RDS; 583 val |= WL1273_POWER_SET_RDS;
726 584
727 /* If this fails try again */ 585 /* If this fails try again */
728 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 586 r = core->write(core, WL1273_POWER_SET, val);
729 if (r) { 587 if (r) {
730 msleep(100); 588 msleep(100);
731 589
732 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 590 r = core->write(core, WL1273_POWER_SET, val);
733 if (r) { 591 if (r) {
734 dev_err(dev, "%s: POWER_SET fails\n", __func__); 592 dev_err(dev, "%s: POWER_SET fails\n", __func__);
735 goto fail; 593 goto fail;
@@ -742,11 +600,10 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
742 600
743 } else if (new_mode == WL1273_MODE_TX) { 601 } else if (new_mode == WL1273_MODE_TX) {
744 /* If this fails try again once */ 602 /* If this fails try again once */
745 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 603 r = core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON);
746 WL1273_PUPD_SET_ON);
747 if (r) { 604 if (r) {
748 msleep(100); 605 msleep(100);
749 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 606 r = core->write(core, WL1273_PUPD_SET,
750 WL1273_PUPD_SET_ON); 607 WL1273_PUPD_SET_ON);
751 if (r) { 608 if (r) {
752 dev_err(dev, "%s: PUPD_SET fails\n", __func__); 609 dev_err(dev, "%s: PUPD_SET fails\n", __func__);
@@ -755,9 +612,9 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
755 } 612 }
756 613
757 if (radio->rds_on) 614 if (radio->rds_on)
758 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1); 615 r = core->write(core, WL1273_RDS_DATA_ENB, 1);
759 else 616 else
760 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0); 617 r = core->write(core, WL1273_RDS_DATA_ENB, 0);
761 } else { 618 } else {
762 dev_warn(dev, "%s: Illegal mode.\n", __func__); 619 dev_warn(dev, "%s: Illegal mode.\n", __func__);
763 } 620 }
@@ -777,14 +634,14 @@ static int wl1273_fm_start(struct wl1273_device *radio, int new_mode)
777 if (radio->rds_on) 634 if (radio->rds_on)
778 val |= WL1273_POWER_SET_RDS; 635 val |= WL1273_POWER_SET_RDS;
779 636
780 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, val); 637 r = core->write(core, WL1273_POWER_SET, val);
781 if (r) { 638 if (r) {
782 dev_err(dev, "%s: POWER_SET fails\n", __func__); 639 dev_err(dev, "%s: POWER_SET fails\n", __func__);
783 goto fail; 640 goto fail;
784 } 641 }
785 } else if (new_mode == WL1273_MODE_TX) { 642 } else if (new_mode == WL1273_MODE_TX) {
786 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 643 r = core->write(core, WL1273_PUPD_SET,
787 WL1273_PUPD_SET_ON); 644 WL1273_PUPD_SET_ON);
788 if (r) { 645 if (r) {
789 dev_err(dev, "%s: PUPD_SET fails\n", __func__); 646 dev_err(dev, "%s: PUPD_SET fails\n", __func__);
790 goto fail; 647 goto fail;
@@ -808,10 +665,10 @@ static int wl1273_fm_suspend(struct wl1273_device *radio)
808 665
809 /* Cannot go from OFF to SUSPENDED */ 666 /* Cannot go from OFF to SUSPENDED */
810 if (core->mode == WL1273_MODE_RX) 667 if (core->mode == WL1273_MODE_RX)
811 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 668 r = core->write(core, WL1273_POWER_SET,
812 WL1273_POWER_SET_RETENTION); 669 WL1273_POWER_SET_RETENTION);
813 else if (core->mode == WL1273_MODE_TX) 670 else if (core->mode == WL1273_MODE_TX)
814 r = wl1273_fm_write_cmd(core, WL1273_PUPD_SET, 671 r = core->write(core, WL1273_PUPD_SET,
815 WL1273_PUPD_SET_RETENTION); 672 WL1273_PUPD_SET_RETENTION);
816 else 673 else
817 r = -EINVAL; 674 r = -EINVAL;
@@ -852,8 +709,7 @@ static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode)
852 } 709 }
853 710
854 core->mode = mode; 711 core->mode = mode;
855 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 712 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
856 radio->irq_flags);
857 if (r) { 713 if (r) {
858 dev_err(dev, "INT_MASK_SET fails.\n"); 714 dev_err(dev, "INT_MASK_SET fails.\n");
859 goto out; 715 goto out;
@@ -951,22 +807,21 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
951 INIT_COMPLETION(radio->busy); 807 INIT_COMPLETION(radio->busy);
952 dev_dbg(radio->dev, "%s: BUSY\n", __func__); 808 dev_dbg(radio->dev, "%s: BUSY\n", __func__);
953 809
954 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 810 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
955 if (r) 811 if (r)
956 goto out; 812 goto out;
957 813
958 dev_dbg(radio->dev, "%s\n", __func__); 814 dev_dbg(radio->dev, "%s\n", __func__);
959 815
960 r = wl1273_fm_write_cmd(core, WL1273_SEARCH_LVL_SET, level); 816 r = core->write(core, WL1273_SEARCH_LVL_SET, level);
961 if (r) 817 if (r)
962 goto out; 818 goto out;
963 819
964 r = wl1273_fm_write_cmd(core, WL1273_SEARCH_DIR_SET, dir); 820 r = core->write(core, WL1273_SEARCH_DIR_SET, dir);
965 if (r) 821 if (r)
966 goto out; 822 goto out;
967 823
968 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 824 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
969 TUNER_MODE_AUTO_SEEK);
970 if (r) 825 if (r)
971 goto out; 826 goto out;
972 827
@@ -994,8 +849,7 @@ static int wl1273_fm_set_seek(struct wl1273_device *radio,
994 INIT_COMPLETION(radio->busy); 849 INIT_COMPLETION(radio->busy);
995 dev_dbg(radio->dev, "%s: BUSY\n", __func__); 850 dev_dbg(radio->dev, "%s: BUSY\n", __func__);
996 851
997 r = wl1273_fm_write_cmd(core, WL1273_TUNER_MODE_SET, 852 r = core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK);
998 TUNER_MODE_AUTO_SEEK);
999 if (r) 853 if (r)
1000 goto out; 854 goto out;
1001 855
@@ -1020,7 +874,7 @@ static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio)
1020 core->mode == WL1273_MODE_SUSPENDED) 874 core->mode == WL1273_MODE_SUSPENDED)
1021 return -EPERM; 875 return -EPERM;
1022 876
1023 r = wl1273_fm_read_reg(core, WL1273_READ_FMANT_TUNE_VALUE, &val); 877 r = core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val);
1024 if (r) { 878 if (r) {
1025 dev_err(dev, "%s: read error: %d\n", __func__, r); 879 dev_err(dev, "%s: read error: %d\n", __func__, r);
1026 goto out; 880 goto out;
@@ -1066,7 +920,7 @@ static int wl1273_fm_set_preemphasis(struct wl1273_device *radio,
1066 goto out; 920 goto out;
1067 } 921 }
1068 922
1069 r = wl1273_fm_write_cmd(core, WL1273_PREMPH_SET, em); 923 r = core->write(core, WL1273_PREMPH_SET, em);
1070 if (r) 924 if (r)
1071 goto out; 925 goto out;
1072 926
@@ -1086,7 +940,7 @@ static int wl1273_fm_rds_on(struct wl1273_device *radio)
1086 if (radio->rds_on) 940 if (radio->rds_on)
1087 return 0; 941 return 0;
1088 942
1089 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, 943 r = core->write(core, WL1273_POWER_SET,
1090 WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS); 944 WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS);
1091 if (r) 945 if (r)
1092 goto out; 946 goto out;
@@ -1108,19 +962,16 @@ static int wl1273_fm_rds_off(struct wl1273_device *radio)
1108 962
1109 radio->irq_flags &= ~WL1273_RDS_EVENT; 963 radio->irq_flags &= ~WL1273_RDS_EVENT;
1110 964
1111 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, radio->irq_flags); 965 r = core->write(core, WL1273_INT_MASK_SET, radio->irq_flags);
1112 if (r) 966 if (r)
1113 goto out; 967 goto out;
1114 968
1115 /* stop rds reception */
1116 cancel_delayed_work(&radio->work);
1117
1118 /* Service pending read */ 969 /* Service pending read */
1119 wake_up_interruptible(&radio->read_queue); 970 wake_up_interruptible(&radio->read_queue);
1120 971
1121 dev_dbg(radio->dev, "%s\n", __func__); 972 dev_dbg(radio->dev, "%s\n", __func__);
1122 973
1123 r = wl1273_fm_write_cmd(core, WL1273_POWER_SET, WL1273_POWER_SET_FM); 974 r = core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM);
1124 if (r) 975 if (r)
1125 goto out; 976 goto out;
1126 977
@@ -1143,14 +994,14 @@ static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new_mode)
1143 return -EPERM; 994 return -EPERM;
1144 995
1145 if (new_mode == WL1273_RDS_RESET) { 996 if (new_mode == WL1273_RDS_RESET) {
1146 r = wl1273_fm_write_cmd(core, WL1273_RDS_CNTRL_SET, 1); 997 r = core->write(core, WL1273_RDS_CNTRL_SET, 1);
1147 return r; 998 return r;
1148 } 999 }
1149 1000
1150 if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) { 1001 if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_OFF) {
1151 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 0); 1002 r = core->write(core, WL1273_RDS_DATA_ENB, 0);
1152 } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) { 1003 } else if (core->mode == WL1273_MODE_TX && new_mode == WL1273_RDS_ON) {
1153 r = wl1273_fm_write_cmd(core, WL1273_RDS_DATA_ENB, 1); 1004 r = core->write(core, WL1273_RDS_DATA_ENB, 1);
1154 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) { 1005 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_OFF) {
1155 r = wl1273_fm_rds_off(radio); 1006 r = wl1273_fm_rds_off(radio);
1156 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) { 1007 } else if (core->mode == WL1273_MODE_RX && new_mode == WL1273_RDS_ON) {
@@ -1171,12 +1022,13 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1171 size_t count, loff_t *ppos) 1022 size_t count, loff_t *ppos)
1172{ 1023{
1173 struct wl1273_device *radio = video_get_drvdata(video_devdata(file)); 1024 struct wl1273_device *radio = video_get_drvdata(video_devdata(file));
1025 struct wl1273_core *core = radio->core;
1174 u16 val; 1026 u16 val;
1175 int r; 1027 int r;
1176 1028
1177 dev_dbg(radio->dev, "%s\n", __func__); 1029 dev_dbg(radio->dev, "%s\n", __func__);
1178 1030
1179 if (radio->core->mode != WL1273_MODE_TX) 1031 if (core->mode != WL1273_MODE_TX)
1180 return count; 1032 return count;
1181 1033
1182 if (radio->rds_users == 0) { 1034 if (radio->rds_users == 0) {
@@ -1184,7 +1036,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1184 return 0; 1036 return 0;
1185 } 1037 }
1186 1038
1187 if (mutex_lock_interruptible(&radio->core->lock)) 1039 if (mutex_lock_interruptible(&core->lock))
1188 return -EINTR; 1040 return -EINTR;
1189 /* 1041 /*
1190 * Multiple processes can open the device, but only 1042 * Multiple processes can open the device, but only
@@ -1202,7 +1054,7 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1202 else 1054 else
1203 val = count; 1055 val = count;
1204 1056
1205 wl1273_fm_write_cmd(radio->core, WL1273_RDS_CONFIG_DATA_SET, val); 1057 core->write(core, WL1273_RDS_CONFIG_DATA_SET, val);
1206 1058
1207 if (copy_from_user(radio->write_buf + 1, buf, val)) { 1059 if (copy_from_user(radio->write_buf + 1, buf, val)) {
1208 r = -EFAULT; 1060 r = -EFAULT;
@@ -1213,11 +1065,11 @@ static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *buf,
1213 dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf); 1065 dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf);
1214 1066
1215 radio->write_buf[0] = WL1273_RDS_DATA_SET; 1067 radio->write_buf[0] = WL1273_RDS_DATA_SET;
1216 wl1273_fm_write_data(radio->core, radio->write_buf, val + 1); 1068 core->write_data(core, radio->write_buf, val + 1);
1217 1069
1218 r = val; 1070 r = val;
1219out: 1071out:
1220 mutex_unlock(&radio->core->lock); 1072 mutex_unlock(&core->lock);
1221 1073
1222 return r; 1074 return r;
1223} 1075}
@@ -1263,8 +1115,8 @@ static int wl1273_fm_fops_open(struct file *file)
1263 1115
1264 radio->irq_flags |= WL1273_RDS_EVENT; 1116 radio->irq_flags |= WL1273_RDS_EVENT;
1265 1117
1266 r = wl1273_fm_write_cmd(core, WL1273_INT_MASK_SET, 1118 r = core->write(core, WL1273_INT_MASK_SET,
1267 radio->irq_flags); 1119 radio->irq_flags);
1268 if (r) { 1120 if (r) {
1269 mutex_unlock(&core->lock); 1121 mutex_unlock(&core->lock);
1270 goto out; 1122 goto out;
@@ -1295,9 +1147,9 @@ static int wl1273_fm_fops_release(struct file *file)
1295 radio->irq_flags &= ~WL1273_RDS_EVENT; 1147 radio->irq_flags &= ~WL1273_RDS_EVENT;
1296 1148
1297 if (core->mode == WL1273_MODE_RX) { 1149 if (core->mode == WL1273_MODE_RX) {
1298 r = wl1273_fm_write_cmd(core, 1150 r = core->write(core,
1299 WL1273_INT_MASK_SET, 1151 WL1273_INT_MASK_SET,
1300 radio->irq_flags); 1152 radio->irq_flags);
1301 if (r) { 1153 if (r) {
1302 mutex_unlock(&core->lock); 1154 mutex_unlock(&core->lock);
1303 goto out; 1155 goto out;
@@ -1324,7 +1176,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
1324 1176
1325 dev_dbg(radio->dev, "%s\n", __func__); 1177 dev_dbg(radio->dev, "%s\n", __func__);
1326 1178
1327 if (radio->core->mode != WL1273_MODE_RX) 1179 if (core->mode != WL1273_MODE_RX)
1328 return 0; 1180 return 0;
1329 1181
1330 if (radio->rds_users == 0) { 1182 if (radio->rds_users == 0) {
@@ -1345,7 +1197,7 @@ static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf,
1345 } 1197 }
1346 radio->owner = file; 1198 radio->owner = file;
1347 1199
1348 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1200 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
1349 if (r) { 1201 if (r) {
1350 dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__); 1202 dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__);
1351 goto out; 1203 goto out;
@@ -1466,23 +1318,24 @@ static int wl1273_fm_vidioc_s_input(struct file *file, void *priv,
1466 */ 1318 */
1467static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power) 1319static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power)
1468{ 1320{
1321 struct wl1273_core *core = radio->core;
1469 int r; 1322 int r;
1470 1323
1471 if (radio->core->mode == WL1273_MODE_OFF || 1324 if (core->mode == WL1273_MODE_OFF ||
1472 radio->core->mode == WL1273_MODE_SUSPENDED) 1325 core->mode == WL1273_MODE_SUSPENDED)
1473 return -EPERM; 1326 return -EPERM;
1474 1327
1475 mutex_lock(&radio->core->lock); 1328 mutex_lock(&core->lock);
1476 1329
1477 /* Convert the dBuV value to chip presentation */ 1330 /* Convert the dBuV value to chip presentation */
1478 r = wl1273_fm_write_cmd(radio->core, WL1273_POWER_LEV_SET, 122 - power); 1331 r = core->write(core, WL1273_POWER_LEV_SET, 122 - power);
1479 if (r) 1332 if (r)
1480 goto out; 1333 goto out;
1481 1334
1482 radio->tx_power = power; 1335 radio->tx_power = power;
1483 1336
1484out: 1337out:
1485 mutex_unlock(&radio->core->lock); 1338 mutex_unlock(&core->lock);
1486 return r; 1339 return r;
1487} 1340}
1488 1341
@@ -1493,23 +1346,24 @@ out:
1493static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio, 1346static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio,
1494 unsigned int spacing) 1347 unsigned int spacing)
1495{ 1348{
1349 struct wl1273_core *core = radio->core;
1496 int r; 1350 int r;
1497 1351
1498 if (spacing == 0) { 1352 if (spacing == 0) {
1499 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1353 r = core->write(core, WL1273_SCAN_SPACING_SET,
1500 WL1273_SPACING_100kHz); 1354 WL1273_SPACING_100kHz);
1501 radio->spacing = 100; 1355 radio->spacing = 100;
1502 } else if (spacing - 50000 < 25000) { 1356 } else if (spacing - 50000 < 25000) {
1503 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1357 r = core->write(core, WL1273_SCAN_SPACING_SET,
1504 WL1273_SPACING_50kHz); 1358 WL1273_SPACING_50kHz);
1505 radio->spacing = 50; 1359 radio->spacing = 50;
1506 } else if (spacing - 100000 < 50000) { 1360 } else if (spacing - 100000 < 50000) {
1507 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1361 r = core->write(core, WL1273_SCAN_SPACING_SET,
1508 WL1273_SPACING_100kHz); 1362 WL1273_SPACING_100kHz);
1509 radio->spacing = 100; 1363 radio->spacing = 100;
1510 } else { 1364 } else {
1511 r = wl1273_fm_write_cmd(radio->core, WL1273_SCAN_SPACING_SET, 1365 r = core->write(core, WL1273_SCAN_SPACING_SET,
1512 WL1273_SPACING_200kHz); 1366 WL1273_SPACING_200kHz);
1513 radio->spacing = 200; 1367 radio->spacing = 200;
1514 } 1368 }
1515 1369
@@ -1567,17 +1421,17 @@ static int wl1273_fm_vidioc_s_ctrl(struct v4l2_ctrl *ctrl)
1567 return -EINTR; 1421 return -EINTR;
1568 1422
1569 if (core->mode == WL1273_MODE_RX && ctrl->val) 1423 if (core->mode == WL1273_MODE_RX && ctrl->val)
1570 r = wl1273_fm_write_cmd(core, 1424 r = core->write(core,
1571 WL1273_MUTE_STATUS_SET, 1425 WL1273_MUTE_STATUS_SET,
1572 WL1273_MUTE_HARD_LEFT | 1426 WL1273_MUTE_HARD_LEFT |
1573 WL1273_MUTE_HARD_RIGHT); 1427 WL1273_MUTE_HARD_RIGHT);
1574 else if (core->mode == WL1273_MODE_RX) 1428 else if (core->mode == WL1273_MODE_RX)
1575 r = wl1273_fm_write_cmd(core, 1429 r = core->write(core,
1576 WL1273_MUTE_STATUS_SET, 0x0); 1430 WL1273_MUTE_STATUS_SET, 0x0);
1577 else if (core->mode == WL1273_MODE_TX && ctrl->val) 1431 else if (core->mode == WL1273_MODE_TX && ctrl->val)
1578 r = wl1273_fm_write_cmd(core, WL1273_MUTE, 1); 1432 r = core->write(core, WL1273_MUTE, 1);
1579 else if (core->mode == WL1273_MODE_TX) 1433 else if (core->mode == WL1273_MODE_TX)
1580 r = wl1273_fm_write_cmd(core, WL1273_MUTE, 0); 1434 r = core->write(core, WL1273_MUTE, 0);
1581 1435
1582 mutex_unlock(&core->lock); 1436 mutex_unlock(&core->lock);
1583 break; 1437 break;
@@ -1672,7 +1526,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1672 if (mutex_lock_interruptible(&core->lock)) 1526 if (mutex_lock_interruptible(&core->lock))
1673 return -EINTR; 1527 return -EINTR;
1674 1528
1675 r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val); 1529 r = core->read(core, WL1273_STEREO_GET, &val);
1676 if (r) 1530 if (r)
1677 goto out; 1531 goto out;
1678 1532
@@ -1681,7 +1535,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1681 else 1535 else
1682 tuner->rxsubchans = V4L2_TUNER_SUB_MONO; 1536 tuner->rxsubchans = V4L2_TUNER_SUB_MONO;
1683 1537
1684 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val); 1538 r = core->read(core, WL1273_RSSI_LVL_GET, &val);
1685 if (r) 1539 if (r)
1686 goto out; 1540 goto out;
1687 1541
@@ -1690,7 +1544,7 @@ static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv,
1690 1544
1691 tuner->afc = 0; 1545 tuner->afc = 0;
1692 1546
1693 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1547 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
1694 if (r) 1548 if (r)
1695 goto out; 1549 goto out;
1696 1550
@@ -1736,8 +1590,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
1736 dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r); 1590 dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r);
1737 1591
1738 if (tuner->audmode == V4L2_TUNER_MODE_MONO) { 1592 if (tuner->audmode == V4L2_TUNER_MODE_MONO) {
1739 r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, 1593 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO);
1740 WL1273_RX_MONO);
1741 if (r < 0) { 1594 if (r < 0) {
1742 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", 1595 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
1743 __func__, r); 1596 __func__, r);
@@ -1745,8 +1598,7 @@ static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv,
1745 } 1598 }
1746 radio->stereo = false; 1599 radio->stereo = false;
1747 } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) { 1600 } else if (tuner->audmode == V4L2_TUNER_MODE_STEREO) {
1748 r = wl1273_fm_write_cmd(core, WL1273_MOST_MODE_SET, 1601 r = core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO);
1749 WL1273_RX_STEREO);
1750 if (r < 0) { 1602 if (r < 0) {
1751 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", 1603 dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n",
1752 __func__, r); 1604 __func__, r);
@@ -1885,10 +1737,10 @@ static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv,
1885 r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF); 1737 r = wl1273_fm_set_rds(radio, WL1273_RDS_OFF);
1886 1738
1887 if (modulator->txsubchans & V4L2_TUNER_SUB_MONO) 1739 if (modulator->txsubchans & V4L2_TUNER_SUB_MONO)
1888 r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, WL1273_TX_MONO); 1740 r = core->write(core, WL1273_MONO_SET, WL1273_TX_MONO);
1889 else 1741 else
1890 r = wl1273_fm_write_cmd(core, WL1273_MONO_SET, 1742 r = core->write(core, WL1273_MONO_SET,
1891 WL1273_RX_STEREO); 1743 WL1273_RX_STEREO);
1892 if (r < 0) 1744 if (r < 0)
1893 dev_warn(radio->dev, WL1273_FM_DRIVER_NAME 1745 dev_warn(radio->dev, WL1273_FM_DRIVER_NAME
1894 "MONO_SET fails: %d\n", r); 1746 "MONO_SET fails: %d\n", r);
@@ -1923,7 +1775,7 @@ static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv,
1923 if (mutex_lock_interruptible(&core->lock)) 1775 if (mutex_lock_interruptible(&core->lock))
1924 return -EINTR; 1776 return -EINTR;
1925 1777
1926 r = wl1273_fm_read_reg(core, WL1273_MONO_SET, &val); 1778 r = core->read(core, WL1273_MONO_SET, &val);
1927 if (r) 1779 if (r)
1928 goto out; 1780 goto out;
1929 1781
@@ -1960,38 +1812,38 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
1960 return 0; 1812 return 0;
1961 } 1813 }
1962 1814
1963 r = wl1273_fm_read_reg(core, WL1273_ASIC_ID_GET, &val); 1815 r = core->read(core, WL1273_ASIC_ID_GET, &val);
1964 if (r) 1816 if (r)
1965 dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__); 1817 dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__);
1966 else 1818 else
1967 dev_info(dev, "ASIC_ID: 0x%04x\n", val); 1819 dev_info(dev, "ASIC_ID: 0x%04x\n", val);
1968 1820
1969 r = wl1273_fm_read_reg(core, WL1273_ASIC_VER_GET, &val); 1821 r = core->read(core, WL1273_ASIC_VER_GET, &val);
1970 if (r) 1822 if (r)
1971 dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__); 1823 dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__);
1972 else 1824 else
1973 dev_info(dev, "ASIC Version: 0x%04x\n", val); 1825 dev_info(dev, "ASIC Version: 0x%04x\n", val);
1974 1826
1975 r = wl1273_fm_read_reg(core, WL1273_FIRM_VER_GET, &val); 1827 r = core->read(core, WL1273_FIRM_VER_GET, &val);
1976 if (r) 1828 if (r)
1977 dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__); 1829 dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__);
1978 else 1830 else
1979 dev_info(dev, "FW version: %d(0x%04x)\n", val, val); 1831 dev_info(dev, "FW version: %d(0x%04x)\n", val, val);
1980 1832
1981 r = wl1273_fm_read_reg(core, WL1273_BAND_SET, &val); 1833 r = core->read(core, WL1273_BAND_SET, &val);
1982 if (r) 1834 if (r)
1983 dev_err(dev, "%s: Get BAND fails.\n", __func__); 1835 dev_err(dev, "%s: Get BAND fails.\n", __func__);
1984 else 1836 else
1985 dev_info(dev, "BAND: %d\n", val); 1837 dev_info(dev, "BAND: %d\n", val);
1986 1838
1987 if (core->mode == WL1273_MODE_TX) { 1839 if (core->mode == WL1273_MODE_TX) {
1988 r = wl1273_fm_read_reg(core, WL1273_PUPD_SET, &val); 1840 r = core->read(core, WL1273_PUPD_SET, &val);
1989 if (r) 1841 if (r)
1990 dev_err(dev, "%s: Get PUPD fails.\n", __func__); 1842 dev_err(dev, "%s: Get PUPD fails.\n", __func__);
1991 else 1843 else
1992 dev_info(dev, "PUPD: 0x%04x\n", val); 1844 dev_info(dev, "PUPD: 0x%04x\n", val);
1993 1845
1994 r = wl1273_fm_read_reg(core, WL1273_CHANL_SET, &val); 1846 r = core->read(core, WL1273_CHANL_SET, &val);
1995 if (r) 1847 if (r)
1996 dev_err(dev, "%s: Get CHANL fails.\n", __func__); 1848 dev_err(dev, "%s: Get CHANL fails.\n", __func__);
1997 else 1849 else
@@ -1999,13 +1851,13 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
1999 } else if (core->mode == WL1273_MODE_RX) { 1851 } else if (core->mode == WL1273_MODE_RX) {
2000 int bf = radio->rangelow; 1852 int bf = radio->rangelow;
2001 1853
2002 r = wl1273_fm_read_reg(core, WL1273_FREQ_SET, &val); 1854 r = core->read(core, WL1273_FREQ_SET, &val);
2003 if (r) 1855 if (r)
2004 dev_err(dev, "%s: Get FREQ fails.\n", __func__); 1856 dev_err(dev, "%s: Get FREQ fails.\n", __func__);
2005 else 1857 else
2006 dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50); 1858 dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50);
2007 1859
2008 r = wl1273_fm_read_reg(core, WL1273_MOST_MODE_SET, &val); 1860 r = core->read(core, WL1273_MOST_MODE_SET, &val);
2009 if (r) 1861 if (r)
2010 dev_err(dev, "%s: Get MOST_MODE fails.\n", 1862 dev_err(dev, "%s: Get MOST_MODE fails.\n",
2011 __func__); 1863 __func__);
@@ -2016,7 +1868,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2016 else 1868 else
2017 dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val); 1869 dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val);
2018 1870
2019 r = wl1273_fm_read_reg(core, WL1273_MOST_BLEND_SET, &val); 1871 r = core->read(core, WL1273_MOST_BLEND_SET, &val);
2020 if (r) 1872 if (r)
2021 dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__); 1873 dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__);
2022 else if (val == 0) 1874 else if (val == 0)
@@ -2027,7 +1879,7 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2027 else 1879 else
2028 dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val); 1880 dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val);
2029 1881
2030 r = wl1273_fm_read_reg(core, WL1273_STEREO_GET, &val); 1882 r = core->read(core, WL1273_STEREO_GET, &val);
2031 if (r) 1883 if (r)
2032 dev_err(dev, "%s: Get STEREO fails.\n", __func__); 1884 dev_err(dev, "%s: Get STEREO fails.\n", __func__);
2033 else if (val == 0) 1885 else if (val == 0)
@@ -2037,25 +1889,25 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2037 else 1889 else
2038 dev_info(dev, "STEREO: Unexpected value: %d\n", val); 1890 dev_info(dev, "STEREO: Unexpected value: %d\n", val);
2039 1891
2040 r = wl1273_fm_read_reg(core, WL1273_RSSI_LVL_GET, &val); 1892 r = core->read(core, WL1273_RSSI_LVL_GET, &val);
2041 if (r) 1893 if (r)
2042 dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__); 1894 dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__);
2043 else 1895 else
2044 dev_info(dev, "RX signal strength: %d\n", (s16) val); 1896 dev_info(dev, "RX signal strength: %d\n", (s16) val);
2045 1897
2046 r = wl1273_fm_read_reg(core, WL1273_POWER_SET, &val); 1898 r = core->read(core, WL1273_POWER_SET, &val);
2047 if (r) 1899 if (r)
2048 dev_err(dev, "%s: Get POWER fails.\n", __func__); 1900 dev_err(dev, "%s: Get POWER fails.\n", __func__);
2049 else 1901 else
2050 dev_info(dev, "POWER: 0x%04x\n", val); 1902 dev_info(dev, "POWER: 0x%04x\n", val);
2051 1903
2052 r = wl1273_fm_read_reg(core, WL1273_INT_MASK_SET, &val); 1904 r = core->read(core, WL1273_INT_MASK_SET, &val);
2053 if (r) 1905 if (r)
2054 dev_err(dev, "%s: Get INT_MASK fails.\n", __func__); 1906 dev_err(dev, "%s: Get INT_MASK fails.\n", __func__);
2055 else 1907 else
2056 dev_info(dev, "INT_MASK: 0x%04x\n", val); 1908 dev_info(dev, "INT_MASK: 0x%04x\n", val);
2057 1909
2058 r = wl1273_fm_read_reg(core, WL1273_RDS_SYNC_GET, &val); 1910 r = core->read(core, WL1273_RDS_SYNC_GET, &val);
2059 if (r) 1911 if (r)
2060 dev_err(dev, "%s: Get RDS_SYNC fails.\n", 1912 dev_err(dev, "%s: Get RDS_SYNC fails.\n",
2061 __func__); 1913 __func__);
@@ -2067,14 +1919,14 @@ static int wl1273_fm_vidioc_log_status(struct file *file, void *priv)
2067 else 1919 else
2068 dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val); 1920 dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val);
2069 1921
2070 r = wl1273_fm_read_reg(core, WL1273_I2S_MODE_CONFIG_SET, &val); 1922 r = core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val);
2071 if (r) 1923 if (r)
2072 dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n", 1924 dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n",
2073 __func__); 1925 __func__);
2074 else 1926 else
2075 dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val); 1927 dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val);
2076 1928
2077 r = wl1273_fm_read_reg(core, WL1273_VOLUME_SET, &val); 1929 r = core->read(core, WL1273_VOLUME_SET, &val);
2078 if (r) 1930 if (r)
2079 dev_err(dev, "%s: Get VOLUME fails.\n", __func__); 1931 dev_err(dev, "%s: Get VOLUME fails.\n", __func__);
2080 else 1932 else
@@ -2184,10 +2036,6 @@ static int __devinit wl1273_fm_radio_probe(struct platform_device *pdev)
2184 radio->stereo = true; 2036 radio->stereo = true;
2185 radio->bus_type = "I2C"; 2037 radio->bus_type = "I2C";
2186 2038
2187 radio->core->write = wl1273_fm_write_cmd;
2188 radio->core->set_audio = wl1273_fm_set_audio;
2189 radio->core->set_volume = wl1273_fm_set_volume;
2190
2191 if (radio->core->pdata->request_resources) { 2039 if (radio->core->pdata->request_resources) {
2192 r = radio->core->pdata->request_resources(radio->core->client); 2040 r = radio->core->pdata->request_resources(radio->core->client);
2193 if (r) { 2041 if (r) {
@@ -2319,7 +2167,6 @@ module_init(wl1273_fm_module_init);
2319 2167
2320static void __exit wl1273_fm_module_exit(void) 2168static void __exit wl1273_fm_module_exit(void)
2321{ 2169{
2322 flush_scheduled_work();
2323 platform_driver_unregister(&wl1273_fm_radio_driver); 2170 platform_driver_unregister(&wl1273_fm_radio_driver);
2324 pr_info(DRIVER_DESC ", Exiting.\n"); 2171 pr_info(DRIVER_DESC ", Exiting.\n");
2325} 2172}
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
index 60c176fe328e..38ae6cd65790 100644
--- a/drivers/media/radio/si470x/radio-si470x-common.c
+++ b/drivers/media/radio/si470x/radio-si470x-common.c
@@ -460,7 +460,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
460 count /= 3; 460 count /= 3;
461 461
462 /* copy RDS block out of internal buffer and to user buffer */ 462 /* copy RDS block out of internal buffer and to user buffer */
463 mutex_lock(&radio->lock);
464 while (block_count < count) { 463 while (block_count < count) {
465 if (radio->rd_index == radio->wr_index) 464 if (radio->rd_index == radio->wr_index)
466 break; 465 break;
diff --git a/drivers/media/radio/wl128x/Kconfig b/drivers/media/radio/wl128x/Kconfig
new file mode 100644
index 000000000000..749f67b192e7
--- /dev/null
+++ b/drivers/media/radio/wl128x/Kconfig
@@ -0,0 +1,17 @@
1#
2# TI's wl128x FM driver based on TI's ST driver.
3#
4menu "Texas Instruments WL128x FM driver (ST based)"
5config RADIO_WL128X
6 tristate "Texas Instruments WL128x FM Radio"
7 depends on VIDEO_V4L2 && RFKILL
8 select TI_ST
9 help
10 Choose Y here if you have this FM radio chip.
11
12 In order to control your radio card, you will need to use programs
13 that are compatible with the Video For Linux 2 API. Information on
14 this API and pointers to "v4l2" programs may be found at
15 <file:Documentation/video4linux/API.html>.
16
17endmenu
diff --git a/drivers/media/radio/wl128x/Makefile b/drivers/media/radio/wl128x/Makefile
new file mode 100644
index 000000000000..32a0ead09845
--- /dev/null
+++ b/drivers/media/radio/wl128x/Makefile
@@ -0,0 +1,6 @@
1#
2# Makefile for TI's shared transport driver based wl128x
3# FM radio.
4#
5obj-$(CONFIG_RADIO_WL128X) += fm_drv.o
6fm_drv-objs := fmdrv_common.o fmdrv_rx.o fmdrv_tx.o fmdrv_v4l2.o
diff --git a/drivers/media/radio/wl128x/fmdrv.h b/drivers/media/radio/wl128x/fmdrv.h
new file mode 100644
index 000000000000..5db6fd14cf3c
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv.h
@@ -0,0 +1,244 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * Common header for all FM driver sub-modules.
5 *
6 * Copyright (C) 2011 Texas Instruments
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 version 2 as
10 * published by the Free Software Foundation.
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#ifndef _FM_DRV_H
24#define _FM_DRV_H
25
26#include <linux/skbuff.h>
27#include <linux/interrupt.h>
28#include <sound/core.h>
29#include <sound/initval.h>
30#include <linux/timer.h>
31#include <linux/version.h>
32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-common.h>
34#include <media/v4l2-ctrls.h>
35
36#define FM_DRV_VERSION "0.10"
37/* Should match with FM_DRV_VERSION */
38#define FM_DRV_RADIO_VERSION KERNEL_VERSION(0, 0, 1)
39#define FM_DRV_NAME "ti_fmdrv"
40#define FM_DRV_CARD_SHORT_NAME "TI FM Radio"
41#define FM_DRV_CARD_LONG_NAME "Texas Instruments FM Radio"
42
43/* Flag info */
44#define FM_INTTASK_RUNNING 0
45#define FM_INTTASK_SCHEDULE_PENDING 1
46#define FM_FW_DW_INPROGRESS 2
47#define FM_CORE_READY 3
48#define FM_CORE_TRANSPORT_READY 4
49#define FM_AF_SWITCH_INPROGRESS 5
50#define FM_CORE_TX_XMITING 6
51
52#define FM_TUNE_COMPLETE 0x1
53#define FM_BAND_LIMIT 0x2
54
55#define FM_DRV_TX_TIMEOUT (5*HZ) /* 5 seconds */
56#define FM_DRV_RX_SEEK_TIMEOUT (20*HZ) /* 20 seconds */
57
58#define NO_OF_ENTRIES_IN_ARRAY(array) (sizeof(array) / sizeof(array[0]))
59
60#define fmerr(format, ...) \
61 printk(KERN_ERR "fmdrv: " format, ## __VA_ARGS__)
62#define fmwarn(format, ...) \
63 printk(KERN_WARNING "fmdrv: " format, ##__VA_ARGS__)
64#ifdef DEBUG
65#define fmdbg(format, ...) \
66 printk(KERN_DEBUG "fmdrv: " format, ## __VA_ARGS__)
67#else /* DEBUG */
68#define fmdbg(format, ...)
69#endif
70enum {
71 FM_MODE_OFF,
72 FM_MODE_TX,
73 FM_MODE_RX,
74 FM_MODE_ENTRY_MAX
75};
76
77#define FM_RX_RDS_INFO_FIELD_MAX 8 /* 4 Group * 2 Bytes */
78
79/* RX RDS data format */
80struct fm_rdsdata_format {
81 union {
82 struct {
83 u8 buff[FM_RX_RDS_INFO_FIELD_MAX];
84 } groupdatabuff;
85 struct {
86 u16 pidata;
87 u8 blk_b[2];
88 u8 blk_c[2];
89 u8 blk_d[2];
90 } groupgeneral;
91 struct {
92 u16 pidata;
93 u8 blk_b[2];
94 u8 af[2];
95 u8 ps[2];
96 } group0A;
97 struct {
98 u16 pi[2];
99 u8 blk_b[2];
100 u8 ps[2];
101 } group0B;
102 } data;
103};
104
105/* FM region (Europe/US, Japan) info */
106struct region_info {
107 u32 chanl_space;
108 u32 bot_freq;
109 u32 top_freq;
110 u8 fm_band;
111};
112struct fmdev;
113typedef void (*int_handler_prototype) (struct fmdev *);
114
115/* FM Interrupt processing related info */
116struct fm_irq {
117 u8 stage;
118 u16 flag; /* FM interrupt flag */
119 u16 mask; /* FM interrupt mask */
120 /* Interrupt process timeout handler */
121 struct timer_list timer;
122 u8 retry;
123 int_handler_prototype *handlers;
124};
125
126/* RDS info */
127struct fm_rds {
128 u8 flag; /* RX RDS on/off status */
129 u8 last_blk_idx; /* Last received RDS block */
130
131 /* RDS buffer */
132 wait_queue_head_t read_queue;
133 u32 buf_size; /* Size is always multiple of 3 */
134 u32 wr_idx;
135 u32 rd_idx;
136 u8 *buff;
137};
138
139#define FM_RDS_MAX_AF_LIST 25
140
141/*
142 * Current RX channel Alternate Frequency cache.
143 * This info is used to switch to other freq (AF)
144 * when current channel signal strengh is below RSSI threshold.
145 */
146struct tuned_station_info {
147 u16 picode;
148 u32 af_cache[FM_RDS_MAX_AF_LIST];
149 u8 afcache_size;
150 u8 af_list_max;
151};
152
153/* FM RX mode info */
154struct fm_rx {
155 struct region_info region; /* Current selected band */
156 u32 freq; /* Current RX frquency */
157 u8 mute_mode; /* Current mute mode */
158 u8 deemphasis_mode; /* Current deemphasis mode */
159 /* RF dependent soft mute mode */
160 u8 rf_depend_mute;
161 u16 volume; /* Current volume level */
162 u16 rssi_threshold; /* Current RSSI threshold level */
163 /* Holds the index of the current AF jump */
164 u8 afjump_idx;
165 /* Will hold the frequency before the jump */
166 u32 freq_before_jump;
167 u8 rds_mode; /* RDS operation mode (RDS/RDBS) */
168 u8 af_mode; /* Alternate frequency on/off */
169 struct tuned_station_info stat_info;
170 struct fm_rds rds;
171};
172
173#define FMTX_RDS_TXT_STR_SIZE 25
174/*
175 * FM TX RDS data
176 *
177 * @ text_type: is the text following PS or RT
178 * @ text: radio text string which could either be PS or RT
179 * @ af_freq: alternate frequency for Tx
180 * TODO: to be declared in application
181 */
182struct tx_rds {
183 u8 text_type;
184 u8 text[FMTX_RDS_TXT_STR_SIZE];
185 u8 flag;
186 u32 af_freq;
187};
188/*
189 * FM TX global data
190 *
191 * @ pwr_lvl: Power Level of the Transmission from mixer control
192 * @ xmit_state: Transmission state = Updated locally upon Start/Stop
193 * @ audio_io: i2S/Analog
194 * @ tx_frq: Transmission frequency
195 */
196struct fmtx_data {
197 u8 pwr_lvl;
198 u8 xmit_state;
199 u8 audio_io;
200 u8 region;
201 u16 aud_mode;
202 u32 preemph;
203 u32 tx_frq;
204 struct tx_rds rds;
205};
206
207/* FM driver operation structure */
208struct fmdev {
209 struct video_device *radio_dev; /* V4L2 video device pointer */
210 struct snd_card *card; /* Card which holds FM mixer controls */
211 u16 asci_id;
212 spinlock_t rds_buff_lock; /* To protect access to RDS buffer */
213 spinlock_t resp_skb_lock; /* To protect access to received SKB */
214
215 long flag; /* FM driver state machine info */
216 u8 streg_cbdata; /* status of ST registration */
217
218 struct sk_buff_head rx_q; /* RX queue */
219 struct tasklet_struct rx_task; /* RX Tasklet */
220
221 struct sk_buff_head tx_q; /* TX queue */
222 struct tasklet_struct tx_task; /* TX Tasklet */
223 unsigned long last_tx_jiffies; /* Timestamp of last pkt sent */
224 atomic_t tx_cnt; /* Number of packets can send at a time */
225
226 struct sk_buff *resp_skb; /* Response from the chip */
227 /* Main task completion handler */
228 struct completion maintask_comp;
229 /* Opcode of last command sent to the chip */
230 u8 pre_op;
231 /* Handler used for wakeup when response packet is received */
232 struct completion *resp_comp;
233 struct fm_irq irq_info;
234 u8 curr_fmmode; /* Current FM chip mode (TX, RX, OFF) */
235 struct fm_rx rx; /* FM receiver info */
236 struct fmtx_data tx_data;
237
238 /* V4L2 ctrl framwork handler*/
239 struct v4l2_ctrl_handler ctrl_handler;
240
241 /* For core assisted locking */
242 struct mutex mutex;
243};
244#endif
diff --git a/drivers/media/radio/wl128x/fmdrv_common.c b/drivers/media/radio/wl128x/fmdrv_common.c
new file mode 100644
index 000000000000..64454d39c0ca
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_common.c
@@ -0,0 +1,1677 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * This sub-module of FM driver is common for FM RX and TX
5 * functionality. This module is responsible for:
6 * 1) Forming group of Channel-8 commands to perform particular
7 * functionality (eg., frequency set require more than
8 * one Channel-8 command to be sent to the chip).
9 * 2) Sending each Channel-8 command to the chip and reading
10 * response back over Shared Transport.
11 * 3) Managing TX and RX Queues and Tasklets.
12 * 4) Handling FM Interrupt packet and taking appropriate action.
13 * 5) Loading FM firmware to the chip (common, FM TX, and FM RX
14 * firmware files based on mode selection)
15 *
16 * Copyright (C) 2011 Texas Instruments
17 * Author: Raja Mani <raja_mani@ti.com>
18 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License version 2 as
22 * published by the Free Software Foundation.
23 *
24 * This program is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 * GNU General Public License for more details.
28 *
29 * You should have received a copy of the GNU General Public License
30 * along with this program; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32 *
33 */
34
35#include <linux/module.h>
36#include <linux/firmware.h>
37#include <linux/delay.h>
38#include "fmdrv.h"
39#include "fmdrv_v4l2.h"
40#include "fmdrv_common.h"
41#include <linux/ti_wilink_st.h>
42#include "fmdrv_rx.h"
43#include "fmdrv_tx.h"
44
45/* Region info */
46static struct region_info region_configs[] = {
47 /* Europe/US */
48 {
49 .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL,
50 .bot_freq = 87500, /* 87.5 MHz */
51 .top_freq = 108000, /* 108 MHz */
52 .fm_band = 0,
53 },
54 /* Japan */
55 {
56 .chanl_space = FM_CHANNEL_SPACING_200KHZ * FM_FREQ_MUL,
57 .bot_freq = 76000, /* 76 MHz */
58 .top_freq = 90000, /* 90 MHz */
59 .fm_band = 1,
60 },
61};
62
63/* Band selection */
64static u8 default_radio_region; /* Europe/US */
65module_param(default_radio_region, byte, 0);
66MODULE_PARM_DESC(default_radio_region, "Region: 0=Europe/US, 1=Japan");
67
68/* RDS buffer blocks */
69static u32 default_rds_buf = 300;
70module_param(default_rds_buf, uint, 0444);
71MODULE_PARM_DESC(rds_buf, "RDS buffer entries");
72
73/* Radio Nr */
74static u32 radio_nr = -1;
75module_param(radio_nr, int, 0444);
76MODULE_PARM_DESC(radio_nr, "Radio Nr");
77
78/* FM irq handlers forward declaration */
79static void fm_irq_send_flag_getcmd(struct fmdev *);
80static void fm_irq_handle_flag_getcmd_resp(struct fmdev *);
81static void fm_irq_handle_hw_malfunction(struct fmdev *);
82static void fm_irq_handle_rds_start(struct fmdev *);
83static void fm_irq_send_rdsdata_getcmd(struct fmdev *);
84static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *);
85static void fm_irq_handle_rds_finish(struct fmdev *);
86static void fm_irq_handle_tune_op_ended(struct fmdev *);
87static void fm_irq_handle_power_enb(struct fmdev *);
88static void fm_irq_handle_low_rssi_start(struct fmdev *);
89static void fm_irq_afjump_set_pi(struct fmdev *);
90static void fm_irq_handle_set_pi_resp(struct fmdev *);
91static void fm_irq_afjump_set_pimask(struct fmdev *);
92static void fm_irq_handle_set_pimask_resp(struct fmdev *);
93static void fm_irq_afjump_setfreq(struct fmdev *);
94static void fm_irq_handle_setfreq_resp(struct fmdev *);
95static void fm_irq_afjump_enableint(struct fmdev *);
96static void fm_irq_afjump_enableint_resp(struct fmdev *);
97static void fm_irq_start_afjump(struct fmdev *);
98static void fm_irq_handle_start_afjump_resp(struct fmdev *);
99static void fm_irq_afjump_rd_freq(struct fmdev *);
100static void fm_irq_afjump_rd_freq_resp(struct fmdev *);
101static void fm_irq_handle_low_rssi_finish(struct fmdev *);
102static void fm_irq_send_intmsk_cmd(struct fmdev *);
103static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *);
104
105/*
106 * When FM common module receives interrupt packet, following handlers
107 * will be executed one after another to service the interrupt(s)
108 */
109enum fmc_irq_handler_index {
110 FM_SEND_FLAG_GETCMD_IDX,
111 FM_HANDLE_FLAG_GETCMD_RESP_IDX,
112
113 /* HW malfunction irq handler */
114 FM_HW_MAL_FUNC_IDX,
115
116 /* RDS threshold reached irq handler */
117 FM_RDS_START_IDX,
118 FM_RDS_SEND_RDS_GETCMD_IDX,
119 FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX,
120 FM_RDS_FINISH_IDX,
121
122 /* Tune operation ended irq handler */
123 FM_HW_TUNE_OP_ENDED_IDX,
124
125 /* TX power enable irq handler */
126 FM_HW_POWER_ENB_IDX,
127
128 /* Low RSSI irq handler */
129 FM_LOW_RSSI_START_IDX,
130 FM_AF_JUMP_SETPI_IDX,
131 FM_AF_JUMP_HANDLE_SETPI_RESP_IDX,
132 FM_AF_JUMP_SETPI_MASK_IDX,
133 FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX,
134 FM_AF_JUMP_SET_AF_FREQ_IDX,
135 FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX,
136 FM_AF_JUMP_ENABLE_INT_IDX,
137 FM_AF_JUMP_ENABLE_INT_RESP_IDX,
138 FM_AF_JUMP_START_AFJUMP_IDX,
139 FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX,
140 FM_AF_JUMP_RD_FREQ_IDX,
141 FM_AF_JUMP_RD_FREQ_RESP_IDX,
142 FM_LOW_RSSI_FINISH_IDX,
143
144 /* Interrupt process post action */
145 FM_SEND_INTMSK_CMD_IDX,
146 FM_HANDLE_INTMSK_CMD_RESP_IDX,
147};
148
149/* FM interrupt handler table */
150static int_handler_prototype int_handler_table[] = {
151 fm_irq_send_flag_getcmd,
152 fm_irq_handle_flag_getcmd_resp,
153 fm_irq_handle_hw_malfunction,
154 fm_irq_handle_rds_start, /* RDS threshold reached irq handler */
155 fm_irq_send_rdsdata_getcmd,
156 fm_irq_handle_rdsdata_getcmd_resp,
157 fm_irq_handle_rds_finish,
158 fm_irq_handle_tune_op_ended,
159 fm_irq_handle_power_enb, /* TX power enable irq handler */
160 fm_irq_handle_low_rssi_start,
161 fm_irq_afjump_set_pi,
162 fm_irq_handle_set_pi_resp,
163 fm_irq_afjump_set_pimask,
164 fm_irq_handle_set_pimask_resp,
165 fm_irq_afjump_setfreq,
166 fm_irq_handle_setfreq_resp,
167 fm_irq_afjump_enableint,
168 fm_irq_afjump_enableint_resp,
169 fm_irq_start_afjump,
170 fm_irq_handle_start_afjump_resp,
171 fm_irq_afjump_rd_freq,
172 fm_irq_afjump_rd_freq_resp,
173 fm_irq_handle_low_rssi_finish,
174 fm_irq_send_intmsk_cmd, /* Interrupt process post action */
175 fm_irq_handle_intmsk_cmd_resp
176};
177
178long (*g_st_write) (struct sk_buff *skb);
179static struct completion wait_for_fmdrv_reg_comp;
180
181static inline void fm_irq_call(struct fmdev *fmdev)
182{
183 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev);
184}
185
186/* Continue next function in interrupt handler table */
187static inline void fm_irq_call_stage(struct fmdev *fmdev, u8 stage)
188{
189 fmdev->irq_info.stage = stage;
190 fm_irq_call(fmdev);
191}
192
193static inline void fm_irq_timeout_stage(struct fmdev *fmdev, u8 stage)
194{
195 fmdev->irq_info.stage = stage;
196 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT);
197}
198
199#ifdef FM_DUMP_TXRX_PKT
200 /* To dump outgoing FM Channel-8 packets */
201inline void dump_tx_skb_data(struct sk_buff *skb)
202{
203 int len, len_org;
204 u8 index;
205 struct fm_cmd_msg_hdr *cmd_hdr;
206
207 cmd_hdr = (struct fm_cmd_msg_hdr *)skb->data;
208 printk(KERN_INFO "<<%shdr:%02x len:%02x opcode:%02x type:%s dlen:%02x",
209 fm_cb(skb)->completion ? " " : "*", cmd_hdr->hdr,
210 cmd_hdr->len, cmd_hdr->op,
211 cmd_hdr->rd_wr ? "RD" : "WR", cmd_hdr->dlen);
212
213 len_org = skb->len - FM_CMD_MSG_HDR_SIZE;
214 if (len_org > 0) {
215 printk("\n data(%d): ", cmd_hdr->dlen);
216 len = min(len_org, 14);
217 for (index = 0; index < len; index++)
218 printk("%x ",
219 skb->data[FM_CMD_MSG_HDR_SIZE + index]);
220 printk("%s", (len_org > 14) ? ".." : "");
221 }
222 printk("\n");
223}
224
225 /* To dump incoming FM Channel-8 packets */
226inline void dump_rx_skb_data(struct sk_buff *skb)
227{
228 int len, len_org;
229 u8 index;
230 struct fm_event_msg_hdr *evt_hdr;
231
232 evt_hdr = (struct fm_event_msg_hdr *)skb->data;
233 printk(KERN_INFO ">> hdr:%02x len:%02x sts:%02x numhci:%02x "
234 "opcode:%02x type:%s dlen:%02x", evt_hdr->hdr, evt_hdr->len,
235 evt_hdr->status, evt_hdr->num_fm_hci_cmds, evt_hdr->op,
236 (evt_hdr->rd_wr) ? "RD" : "WR", evt_hdr->dlen);
237
238 len_org = skb->len - FM_EVT_MSG_HDR_SIZE;
239 if (len_org > 0) {
240 printk("\n data(%d): ", evt_hdr->dlen);
241 len = min(len_org, 14);
242 for (index = 0; index < len; index++)
243 printk("%x ",
244 skb->data[FM_EVT_MSG_HDR_SIZE + index]);
245 printk("%s", (len_org > 14) ? ".." : "");
246 }
247 printk("\n");
248}
249#endif
250
251void fmc_update_region_info(struct fmdev *fmdev, u8 region_to_set)
252{
253 fmdev->rx.region = region_configs[region_to_set];
254}
255
256/*
257 * FM common sub-module will schedule this tasklet whenever it receives
258 * FM packet from ST driver.
259 */
260static void recv_tasklet(unsigned long arg)
261{
262 struct fmdev *fmdev;
263 struct fm_irq *irq_info;
264 struct fm_event_msg_hdr *evt_hdr;
265 struct sk_buff *skb;
266 u8 num_fm_hci_cmds;
267 unsigned long flags;
268
269 fmdev = (struct fmdev *)arg;
270 irq_info = &fmdev->irq_info;
271 /* Process all packets in the RX queue */
272 while ((skb = skb_dequeue(&fmdev->rx_q))) {
273 if (skb->len < sizeof(struct fm_event_msg_hdr)) {
274 fmerr("skb(%p) has only %d bytes, "
275 "at least need %zu bytes to decode\n", skb,
276 skb->len, sizeof(struct fm_event_msg_hdr));
277 kfree_skb(skb);
278 continue;
279 }
280
281 evt_hdr = (void *)skb->data;
282 num_fm_hci_cmds = evt_hdr->num_fm_hci_cmds;
283
284 /* FM interrupt packet? */
285 if (evt_hdr->op == FM_INTERRUPT) {
286 /* FM interrupt handler started already? */
287 if (!test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) {
288 set_bit(FM_INTTASK_RUNNING, &fmdev->flag);
289 if (irq_info->stage != 0) {
290 fmerr("Inval stage resetting to zero\n");
291 irq_info->stage = 0;
292 }
293
294 /*
295 * Execute first function in interrupt handler
296 * table.
297 */
298 irq_info->handlers[irq_info->stage](fmdev);
299 } else {
300 set_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag);
301 }
302 kfree_skb(skb);
303 }
304 /* Anyone waiting for this with completion handler? */
305 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp != NULL) {
306
307 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
308 fmdev->resp_skb = skb;
309 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
310 complete(fmdev->resp_comp);
311
312 fmdev->resp_comp = NULL;
313 atomic_set(&fmdev->tx_cnt, 1);
314 }
315 /* Is this for interrupt handler? */
316 else if (evt_hdr->op == fmdev->pre_op && fmdev->resp_comp == NULL) {
317 if (fmdev->resp_skb != NULL)
318 fmerr("Response SKB ptr not NULL\n");
319
320 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
321 fmdev->resp_skb = skb;
322 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
323
324 /* Execute interrupt handler where state index points */
325 irq_info->handlers[irq_info->stage](fmdev);
326
327 kfree_skb(skb);
328 atomic_set(&fmdev->tx_cnt, 1);
329 } else {
330 fmerr("Nobody claimed SKB(%p),purging\n", skb);
331 }
332
333 /*
334 * Check flow control field. If Num_FM_HCI_Commands field is
335 * not zero, schedule FM TX tasklet.
336 */
337 if (num_fm_hci_cmds && atomic_read(&fmdev->tx_cnt))
338 if (!skb_queue_empty(&fmdev->tx_q))
339 tasklet_schedule(&fmdev->tx_task);
340 }
341}
342
343/* FM send tasklet: is scheduled when FM packet has to be sent to chip */
344static void send_tasklet(unsigned long arg)
345{
346 struct fmdev *fmdev;
347 struct sk_buff *skb;
348 int len;
349
350 fmdev = (struct fmdev *)arg;
351
352 if (!atomic_read(&fmdev->tx_cnt))
353 return;
354
355 /* Check, is there any timeout happenned to last transmitted packet */
356 if ((jiffies - fmdev->last_tx_jiffies) > FM_DRV_TX_TIMEOUT) {
357 fmerr("TX timeout occurred\n");
358 atomic_set(&fmdev->tx_cnt, 1);
359 }
360
361 /* Send queued FM TX packets */
362 skb = skb_dequeue(&fmdev->tx_q);
363 if (!skb)
364 return;
365
366 atomic_dec(&fmdev->tx_cnt);
367 fmdev->pre_op = fm_cb(skb)->fm_op;
368
369 if (fmdev->resp_comp != NULL)
370 fmerr("Response completion handler is not NULL\n");
371
372 fmdev->resp_comp = fm_cb(skb)->completion;
373
374 /* Write FM packet to ST driver */
375 len = g_st_write(skb);
376 if (len < 0) {
377 kfree_skb(skb);
378 fmdev->resp_comp = NULL;
379 fmerr("TX tasklet failed to send skb(%p)\n", skb);
380 atomic_set(&fmdev->tx_cnt, 1);
381 } else {
382 fmdev->last_tx_jiffies = jiffies;
383 }
384}
385
386/*
387 * Queues FM Channel-8 packet to FM TX queue and schedules FM TX tasklet for
388 * transmission
389 */
390static u32 fm_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
391 int payload_len, struct completion *wait_completion)
392{
393 struct sk_buff *skb;
394 struct fm_cmd_msg_hdr *hdr;
395 int size;
396
397 if (fm_op >= FM_INTERRUPT) {
398 fmerr("Invalid fm opcode - %d\n", fm_op);
399 return -EINVAL;
400 }
401 if (test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) && payload == NULL) {
402 fmerr("Payload data is NULL during fw download\n");
403 return -EINVAL;
404 }
405 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag))
406 size =
407 FM_CMD_MSG_HDR_SIZE + ((payload == NULL) ? 0 : payload_len);
408 else
409 size = payload_len;
410
411 skb = alloc_skb(size, GFP_ATOMIC);
412 if (!skb) {
413 fmerr("No memory to create new SKB\n");
414 return -ENOMEM;
415 }
416 /*
417 * Don't fill FM header info for the commands which come from
418 * FM firmware file.
419 */
420 if (!test_bit(FM_FW_DW_INPROGRESS, &fmdev->flag) ||
421 test_bit(FM_INTTASK_RUNNING, &fmdev->flag)) {
422 /* Fill command header info */
423 hdr = (struct fm_cmd_msg_hdr *)skb_put(skb, FM_CMD_MSG_HDR_SIZE);
424 hdr->hdr = FM_PKT_LOGICAL_CHAN_NUMBER; /* 0x08 */
425
426 /* 3 (fm_opcode,rd_wr,dlen) + payload len) */
427 hdr->len = ((payload == NULL) ? 0 : payload_len) + 3;
428
429 /* FM opcode */
430 hdr->op = fm_op;
431
432 /* read/write type */
433 hdr->rd_wr = type;
434 hdr->dlen = payload_len;
435 fm_cb(skb)->fm_op = fm_op;
436
437 /*
438 * If firmware download has finished and the command is
439 * not a read command then payload is != NULL - a write
440 * command with u16 payload - convert to be16
441 */
442 if (payload != NULL)
443 *(u16 *)payload = cpu_to_be16(*(u16 *)payload);
444
445 } else if (payload != NULL) {
446 fm_cb(skb)->fm_op = *((u8 *)payload + 2);
447 }
448 if (payload != NULL)
449 memcpy(skb_put(skb, payload_len), payload, payload_len);
450
451 fm_cb(skb)->completion = wait_completion;
452 skb_queue_tail(&fmdev->tx_q, skb);
453 tasklet_schedule(&fmdev->tx_task);
454
455 return 0;
456}
457
458/* Sends FM Channel-8 command to the chip and waits for the response */
459u32 fmc_send_cmd(struct fmdev *fmdev, u8 fm_op, u16 type, void *payload,
460 unsigned int payload_len, void *response, int *response_len)
461{
462 struct sk_buff *skb;
463 struct fm_event_msg_hdr *evt_hdr;
464 unsigned long flags;
465 u32 ret;
466
467 init_completion(&fmdev->maintask_comp);
468 ret = fm_send_cmd(fmdev, fm_op, type, payload, payload_len,
469 &fmdev->maintask_comp);
470 if (ret)
471 return ret;
472
473 ret = wait_for_completion_timeout(&fmdev->maintask_comp, FM_DRV_TX_TIMEOUT);
474 if (!ret) {
475 fmerr("Timeout(%d sec),didn't get reg"
476 "completion signal from RX tasklet\n",
477 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
478 return -ETIMEDOUT;
479 }
480 if (!fmdev->resp_skb) {
481 fmerr("Reponse SKB is missing\n");
482 return -EFAULT;
483 }
484 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
485 skb = fmdev->resp_skb;
486 fmdev->resp_skb = NULL;
487 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
488
489 evt_hdr = (void *)skb->data;
490 if (evt_hdr->status != 0) {
491 fmerr("Received event pkt status(%d) is not zero\n",
492 evt_hdr->status);
493 kfree_skb(skb);
494 return -EIO;
495 }
496 /* Send response data to caller */
497 if (response != NULL && response_len != NULL && evt_hdr->dlen) {
498 /* Skip header info and copy only response data */
499 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
500 memcpy(response, skb->data, evt_hdr->dlen);
501 *response_len = evt_hdr->dlen;
502 } else if (response_len != NULL && evt_hdr->dlen == 0) {
503 *response_len = 0;
504 }
505 kfree_skb(skb);
506
507 return 0;
508}
509
510/* --- Helper functions used in FM interrupt handlers ---*/
511static inline u32 check_cmdresp_status(struct fmdev *fmdev,
512 struct sk_buff **skb)
513{
514 struct fm_event_msg_hdr *fm_evt_hdr;
515 unsigned long flags;
516
517 del_timer(&fmdev->irq_info.timer);
518
519 spin_lock_irqsave(&fmdev->resp_skb_lock, flags);
520 *skb = fmdev->resp_skb;
521 fmdev->resp_skb = NULL;
522 spin_unlock_irqrestore(&fmdev->resp_skb_lock, flags);
523
524 fm_evt_hdr = (void *)(*skb)->data;
525 if (fm_evt_hdr->status != 0) {
526 fmerr("irq: opcode %x response status is not zero "
527 "Initiating irq recovery process\n",
528 fm_evt_hdr->op);
529
530 mod_timer(&fmdev->irq_info.timer, jiffies + FM_DRV_TX_TIMEOUT);
531 return -1;
532 }
533
534 return 0;
535}
536
537static inline void fm_irq_common_cmd_resp_helper(struct fmdev *fmdev, u8 stage)
538{
539 struct sk_buff *skb;
540
541 if (!check_cmdresp_status(fmdev, &skb))
542 fm_irq_call_stage(fmdev, stage);
543}
544
545/*
546 * Interrupt process timeout handler.
547 * One of the irq handler did not get proper response from the chip. So take
548 * recovery action here. FM interrupts are disabled in the beginning of
549 * interrupt process. Therefore reset stage index to re-enable default
550 * interrupts. So that next interrupt will be processed as usual.
551 */
552static void int_timeout_handler(unsigned long data)
553{
554 struct fmdev *fmdev;
555 struct fm_irq *fmirq;
556
557 fmdbg("irq: timeout,trying to re-enable fm interrupts\n");
558 fmdev = (struct fmdev *)data;
559 fmirq = &fmdev->irq_info;
560 fmirq->retry++;
561
562 if (fmirq->retry > FM_IRQ_TIMEOUT_RETRY_MAX) {
563 /* Stop recovery action (interrupt reenable process) and
564 * reset stage index & retry count values */
565 fmirq->stage = 0;
566 fmirq->retry = 0;
567 fmerr("Recovery action failed during"
568 "irq processing, max retry reached\n");
569 return;
570 }
571 fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX);
572}
573
574/* --------- FM interrupt handlers ------------*/
575static void fm_irq_send_flag_getcmd(struct fmdev *fmdev)
576{
577 u16 flag;
578
579 /* Send FLAG_GET command , to know the source of interrupt */
580 if (!fm_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, sizeof(flag), NULL))
581 fm_irq_timeout_stage(fmdev, FM_HANDLE_FLAG_GETCMD_RESP_IDX);
582}
583
584static void fm_irq_handle_flag_getcmd_resp(struct fmdev *fmdev)
585{
586 struct sk_buff *skb;
587 struct fm_event_msg_hdr *fm_evt_hdr;
588
589 if (check_cmdresp_status(fmdev, &skb))
590 return;
591
592 fm_evt_hdr = (void *)skb->data;
593
594 /* Skip header info and copy only response data */
595 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
596 memcpy(&fmdev->irq_info.flag, skb->data, fm_evt_hdr->dlen);
597
598 fmdev->irq_info.flag = be16_to_cpu(fmdev->irq_info.flag);
599 fmdbg("irq: flag register(0x%x)\n", fmdev->irq_info.flag);
600
601 /* Continue next function in interrupt handler table */
602 fm_irq_call_stage(fmdev, FM_HW_MAL_FUNC_IDX);
603}
604
605static void fm_irq_handle_hw_malfunction(struct fmdev *fmdev)
606{
607 if (fmdev->irq_info.flag & FM_MAL_EVENT & fmdev->irq_info.mask)
608 fmerr("irq: HW MAL int received - do nothing\n");
609
610 /* Continue next function in interrupt handler table */
611 fm_irq_call_stage(fmdev, FM_RDS_START_IDX);
612}
613
614static void fm_irq_handle_rds_start(struct fmdev *fmdev)
615{
616 if (fmdev->irq_info.flag & FM_RDS_EVENT & fmdev->irq_info.mask) {
617 fmdbg("irq: rds threshold reached\n");
618 fmdev->irq_info.stage = FM_RDS_SEND_RDS_GETCMD_IDX;
619 } else {
620 /* Continue next function in interrupt handler table */
621 fmdev->irq_info.stage = FM_HW_TUNE_OP_ENDED_IDX;
622 }
623
624 fm_irq_call(fmdev);
625}
626
627static void fm_irq_send_rdsdata_getcmd(struct fmdev *fmdev)
628{
629 /* Send the command to read RDS data from the chip */
630 if (!fm_send_cmd(fmdev, RDS_DATA_GET, REG_RD, NULL,
631 (FM_RX_RDS_FIFO_THRESHOLD * 3), NULL))
632 fm_irq_timeout_stage(fmdev, FM_RDS_HANDLE_RDS_GETCMD_RESP_IDX);
633}
634
635/* Keeps track of current RX channel AF (Alternate Frequency) */
636static void fm_rx_update_af_cache(struct fmdev *fmdev, u8 af)
637{
638 struct tuned_station_info *stat_info = &fmdev->rx.stat_info;
639 u8 reg_idx = fmdev->rx.region.fm_band;
640 u8 index;
641 u32 freq;
642
643 /* First AF indicates the number of AF follows. Reset the list */
644 if ((af >= FM_RDS_1_AF_FOLLOWS) && (af <= FM_RDS_25_AF_FOLLOWS)) {
645 fmdev->rx.stat_info.af_list_max = (af - FM_RDS_1_AF_FOLLOWS + 1);
646 fmdev->rx.stat_info.afcache_size = 0;
647 fmdbg("No of expected AF : %d\n", fmdev->rx.stat_info.af_list_max);
648 return;
649 }
650
651 if (af < FM_RDS_MIN_AF)
652 return;
653 if (reg_idx == FM_BAND_EUROPE_US && af > FM_RDS_MAX_AF)
654 return;
655 if (reg_idx == FM_BAND_JAPAN && af > FM_RDS_MAX_AF_JAPAN)
656 return;
657
658 freq = fmdev->rx.region.bot_freq + (af * 100);
659 if (freq == fmdev->rx.freq) {
660 fmdbg("Current freq(%d) is matching with received AF(%d)\n",
661 fmdev->rx.freq, freq);
662 return;
663 }
664 /* Do check in AF cache */
665 for (index = 0; index < stat_info->afcache_size; index++) {
666 if (stat_info->af_cache[index] == freq)
667 break;
668 }
669 /* Reached the limit of the list - ignore the next AF */
670 if (index == stat_info->af_list_max) {
671 fmdbg("AF cache is full\n");
672 return;
673 }
674 /*
675 * If we reached the end of the list then this AF is not
676 * in the list - add it.
677 */
678 if (index == stat_info->afcache_size) {
679 fmdbg("Storing AF %d to cache index %d\n", freq, index);
680 stat_info->af_cache[index] = freq;
681 stat_info->afcache_size++;
682 }
683}
684
685/*
686 * Converts RDS buffer data from big endian format
687 * to little endian format.
688 */
689static void fm_rdsparse_swapbytes(struct fmdev *fmdev,
690 struct fm_rdsdata_format *rds_format)
691{
692 u8 byte1;
693 u8 index = 0;
694 u8 *rds_buff;
695
696 /*
697 * Since in Orca the 2 RDS Data bytes are in little endian and
698 * in Dolphin they are in big endian, the parsing of the RDS data
699 * is chip dependent
700 */
701 if (fmdev->asci_id != 0x6350) {
702 rds_buff = &rds_format->data.groupdatabuff.buff[0];
703 while (index + 1 < FM_RX_RDS_INFO_FIELD_MAX) {
704 byte1 = rds_buff[index];
705 rds_buff[index] = rds_buff[index + 1];
706 rds_buff[index + 1] = byte1;
707 index += 2;
708 }
709 }
710}
711
712static void fm_irq_handle_rdsdata_getcmd_resp(struct fmdev *fmdev)
713{
714 struct sk_buff *skb;
715 struct fm_rdsdata_format rds_fmt;
716 struct fm_rds *rds = &fmdev->rx.rds;
717 unsigned long group_idx, flags;
718 u8 *rds_data, meta_data, tmpbuf[3];
719 u8 type, blk_idx;
720 u16 cur_picode;
721 u32 rds_len;
722
723 if (check_cmdresp_status(fmdev, &skb))
724 return;
725
726 /* Skip header info */
727 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
728 rds_data = skb->data;
729 rds_len = skb->len;
730
731 /* Parse the RDS data */
732 while (rds_len >= FM_RDS_BLK_SIZE) {
733 meta_data = rds_data[2];
734 /* Get the type: 0=A, 1=B, 2=C, 3=C', 4=D, 5=E */
735 type = (meta_data & 0x07);
736
737 /* Transform the blk type into index sequence (0, 1, 2, 3, 4) */
738 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1));
739 fmdbg("Block index:%d(%s)\n", blk_idx,
740 (meta_data & FM_RDS_STATUS_ERR_MASK) ? "Bad" : "Ok");
741
742 if ((meta_data & FM_RDS_STATUS_ERR_MASK) != 0)
743 break;
744
745 if (blk_idx < FM_RDS_BLK_IDX_A || blk_idx > FM_RDS_BLK_IDX_D) {
746 fmdbg("Block sequence mismatch\n");
747 rds->last_blk_idx = -1;
748 break;
749 }
750
751 /* Skip checkword (control) byte and copy only data byte */
752 memcpy(&rds_fmt.data.groupdatabuff.
753 buff[blk_idx * (FM_RDS_BLK_SIZE - 1)],
754 rds_data, (FM_RDS_BLK_SIZE - 1));
755
756 rds->last_blk_idx = blk_idx;
757
758 /* If completed a whole group then handle it */
759 if (blk_idx == FM_RDS_BLK_IDX_D) {
760 fmdbg("Good block received\n");
761 fm_rdsparse_swapbytes(fmdev, &rds_fmt);
762
763 /*
764 * Extract PI code and store in local cache.
765 * We need this during AF switch processing.
766 */
767 cur_picode = be16_to_cpu(rds_fmt.data.groupgeneral.pidata);
768 if (fmdev->rx.stat_info.picode != cur_picode)
769 fmdev->rx.stat_info.picode = cur_picode;
770
771 fmdbg("picode:%d\n", cur_picode);
772
773 group_idx = (rds_fmt.data.groupgeneral.blk_b[0] >> 3);
774 fmdbg("(fmdrv):Group:%ld%s\n", group_idx/2,
775 (group_idx % 2) ? "B" : "A");
776
777 group_idx = 1 << (rds_fmt.data.groupgeneral.blk_b[0] >> 3);
778 if (group_idx == FM_RDS_GROUP_TYPE_MASK_0A) {
779 fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[0]);
780 fm_rx_update_af_cache(fmdev, rds_fmt.data.group0A.af[1]);
781 }
782 }
783 rds_len -= FM_RDS_BLK_SIZE;
784 rds_data += FM_RDS_BLK_SIZE;
785 }
786
787 /* Copy raw rds data to internal rds buffer */
788 rds_data = skb->data;
789 rds_len = skb->len;
790
791 spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
792 while (rds_len > 0) {
793 /*
794 * Fill RDS buffer as per V4L2 specification.
795 * Store control byte
796 */
797 type = (rds_data[2] & 0x07);
798 blk_idx = (type <= FM_RDS_BLOCK_C ? type : (type - 1));
799 tmpbuf[2] = blk_idx; /* Offset name */
800 tmpbuf[2] |= blk_idx << 3; /* Received offset */
801
802 /* Store data byte */
803 tmpbuf[0] = rds_data[0];
804 tmpbuf[1] = rds_data[1];
805
806 memcpy(&rds->buff[rds->wr_idx], &tmpbuf, FM_RDS_BLK_SIZE);
807 rds->wr_idx = (rds->wr_idx + FM_RDS_BLK_SIZE) % rds->buf_size;
808
809 /* Check for overflow & start over */
810 if (rds->wr_idx == rds->rd_idx) {
811 fmdbg("RDS buffer overflow\n");
812 rds->wr_idx = 0;
813 rds->rd_idx = 0;
814 break;
815 }
816 rds_len -= FM_RDS_BLK_SIZE;
817 rds_data += FM_RDS_BLK_SIZE;
818 }
819 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
820
821 /* Wakeup read queue */
822 if (rds->wr_idx != rds->rd_idx)
823 wake_up_interruptible(&rds->read_queue);
824
825 fm_irq_call_stage(fmdev, FM_RDS_FINISH_IDX);
826}
827
828static void fm_irq_handle_rds_finish(struct fmdev *fmdev)
829{
830 fm_irq_call_stage(fmdev, FM_HW_TUNE_OP_ENDED_IDX);
831}
832
833static void fm_irq_handle_tune_op_ended(struct fmdev *fmdev)
834{
835 if (fmdev->irq_info.flag & (FM_FR_EVENT | FM_BL_EVENT) & fmdev->
836 irq_info.mask) {
837 fmdbg("irq: tune ended/bandlimit reached\n");
838 if (test_and_clear_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag)) {
839 fmdev->irq_info.stage = FM_AF_JUMP_RD_FREQ_IDX;
840 } else {
841 complete(&fmdev->maintask_comp);
842 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX;
843 }
844 } else
845 fmdev->irq_info.stage = FM_HW_POWER_ENB_IDX;
846
847 fm_irq_call(fmdev);
848}
849
850static void fm_irq_handle_power_enb(struct fmdev *fmdev)
851{
852 if (fmdev->irq_info.flag & FM_POW_ENB_EVENT) {
853 fmdbg("irq: Power Enabled/Disabled\n");
854 complete(&fmdev->maintask_comp);
855 }
856
857 fm_irq_call_stage(fmdev, FM_LOW_RSSI_START_IDX);
858}
859
860static void fm_irq_handle_low_rssi_start(struct fmdev *fmdev)
861{
862 if ((fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON) &&
863 (fmdev->irq_info.flag & FM_LEV_EVENT & fmdev->irq_info.mask) &&
864 (fmdev->rx.freq != FM_UNDEFINED_FREQ) &&
865 (fmdev->rx.stat_info.afcache_size != 0)) {
866 fmdbg("irq: rssi level has fallen below threshold level\n");
867
868 /* Disable further low RSSI interrupts */
869 fmdev->irq_info.mask &= ~FM_LEV_EVENT;
870
871 fmdev->rx.afjump_idx = 0;
872 fmdev->rx.freq_before_jump = fmdev->rx.freq;
873 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX;
874 } else {
875 /* Continue next function in interrupt handler table */
876 fmdev->irq_info.stage = FM_SEND_INTMSK_CMD_IDX;
877 }
878
879 fm_irq_call(fmdev);
880}
881
882static void fm_irq_afjump_set_pi(struct fmdev *fmdev)
883{
884 u16 payload;
885
886 /* Set PI code - must be updated if the AF list is not empty */
887 payload = fmdev->rx.stat_info.picode;
888 if (!fm_send_cmd(fmdev, RDS_PI_SET, REG_WR, &payload, sizeof(payload), NULL))
889 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_RESP_IDX);
890}
891
892static void fm_irq_handle_set_pi_resp(struct fmdev *fmdev)
893{
894 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SETPI_MASK_IDX);
895}
896
897/*
898 * Set PI mask.
899 * 0xFFFF = Enable PI code matching
900 * 0x0000 = Disable PI code matching
901 */
902static void fm_irq_afjump_set_pimask(struct fmdev *fmdev)
903{
904 u16 payload;
905
906 payload = 0x0000;
907 if (!fm_send_cmd(fmdev, RDS_PI_MASK_SET, REG_WR, &payload, sizeof(payload), NULL))
908 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SETPI_MASK_RESP_IDX);
909}
910
911static void fm_irq_handle_set_pimask_resp(struct fmdev *fmdev)
912{
913 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_SET_AF_FREQ_IDX);
914}
915
916static void fm_irq_afjump_setfreq(struct fmdev *fmdev)
917{
918 u16 frq_index;
919 u16 payload;
920
921 fmdbg("Swtich to %d KHz\n", fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx]);
922 frq_index = (fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx] -
923 fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
924
925 payload = frq_index;
926 if (!fm_send_cmd(fmdev, AF_FREQ_SET, REG_WR, &payload, sizeof(payload), NULL))
927 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_SET_AFFREQ_RESP_IDX);
928}
929
930static void fm_irq_handle_setfreq_resp(struct fmdev *fmdev)
931{
932 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_ENABLE_INT_IDX);
933}
934
935static void fm_irq_afjump_enableint(struct fmdev *fmdev)
936{
937 u16 payload;
938
939 /* Enable FR (tuning operation ended) interrupt */
940 payload = FM_FR_EVENT;
941 if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload, sizeof(payload), NULL))
942 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_ENABLE_INT_RESP_IDX);
943}
944
945static void fm_irq_afjump_enableint_resp(struct fmdev *fmdev)
946{
947 fm_irq_common_cmd_resp_helper(fmdev, FM_AF_JUMP_START_AFJUMP_IDX);
948}
949
950static void fm_irq_start_afjump(struct fmdev *fmdev)
951{
952 u16 payload;
953
954 payload = FM_TUNER_AF_JUMP_MODE;
955 if (!fm_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
956 sizeof(payload), NULL))
957 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_HANDLE_START_AFJUMP_RESP_IDX);
958}
959
960static void fm_irq_handle_start_afjump_resp(struct fmdev *fmdev)
961{
962 struct sk_buff *skb;
963
964 if (check_cmdresp_status(fmdev, &skb))
965 return;
966
967 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX;
968 set_bit(FM_AF_SWITCH_INPROGRESS, &fmdev->flag);
969 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag);
970}
971
972static void fm_irq_afjump_rd_freq(struct fmdev *fmdev)
973{
974 u16 payload;
975
976 if (!fm_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, sizeof(payload), NULL))
977 fm_irq_timeout_stage(fmdev, FM_AF_JUMP_RD_FREQ_RESP_IDX);
978}
979
980static void fm_irq_afjump_rd_freq_resp(struct fmdev *fmdev)
981{
982 struct sk_buff *skb;
983 u16 read_freq;
984 u32 curr_freq, jumped_freq;
985
986 if (check_cmdresp_status(fmdev, &skb))
987 return;
988
989 /* Skip header info and copy only response data */
990 skb_pull(skb, sizeof(struct fm_event_msg_hdr));
991 memcpy(&read_freq, skb->data, sizeof(read_freq));
992 read_freq = be16_to_cpu(read_freq);
993 curr_freq = fmdev->rx.region.bot_freq + ((u32)read_freq * FM_FREQ_MUL);
994
995 jumped_freq = fmdev->rx.stat_info.af_cache[fmdev->rx.afjump_idx];
996
997 /* If the frequency was changed the jump succeeded */
998 if ((curr_freq != fmdev->rx.freq_before_jump) && (curr_freq == jumped_freq)) {
999 fmdbg("Successfully switched to alternate freq %d\n", curr_freq);
1000 fmdev->rx.freq = curr_freq;
1001 fm_rx_reset_rds_cache(fmdev);
1002
1003 /* AF feature is on, enable low level RSSI interrupt */
1004 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
1005 fmdev->irq_info.mask |= FM_LEV_EVENT;
1006
1007 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX;
1008 } else { /* jump to the next freq in the AF list */
1009 fmdev->rx.afjump_idx++;
1010
1011 /* If we reached the end of the list - stop searching */
1012 if (fmdev->rx.afjump_idx >= fmdev->rx.stat_info.afcache_size) {
1013 fmdbg("AF switch processing failed\n");
1014 fmdev->irq_info.stage = FM_LOW_RSSI_FINISH_IDX;
1015 } else { /* AF List is not over - try next one */
1016
1017 fmdbg("Trying next freq in AF cache\n");
1018 fmdev->irq_info.stage = FM_AF_JUMP_SETPI_IDX;
1019 }
1020 }
1021 fm_irq_call(fmdev);
1022}
1023
1024static void fm_irq_handle_low_rssi_finish(struct fmdev *fmdev)
1025{
1026 fm_irq_call_stage(fmdev, FM_SEND_INTMSK_CMD_IDX);
1027}
1028
1029static void fm_irq_send_intmsk_cmd(struct fmdev *fmdev)
1030{
1031 u16 payload;
1032
1033 /* Re-enable FM interrupts */
1034 payload = fmdev->irq_info.mask;
1035
1036 if (!fm_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
1037 sizeof(payload), NULL))
1038 fm_irq_timeout_stage(fmdev, FM_HANDLE_INTMSK_CMD_RESP_IDX);
1039}
1040
1041static void fm_irq_handle_intmsk_cmd_resp(struct fmdev *fmdev)
1042{
1043 struct sk_buff *skb;
1044
1045 if (check_cmdresp_status(fmdev, &skb))
1046 return;
1047 /*
1048 * This is last function in interrupt table to be executed.
1049 * So, reset stage index to 0.
1050 */
1051 fmdev->irq_info.stage = FM_SEND_FLAG_GETCMD_IDX;
1052
1053 /* Start processing any pending interrupt */
1054 if (test_and_clear_bit(FM_INTTASK_SCHEDULE_PENDING, &fmdev->flag))
1055 fmdev->irq_info.handlers[fmdev->irq_info.stage](fmdev);
1056 else
1057 clear_bit(FM_INTTASK_RUNNING, &fmdev->flag);
1058}
1059
1060/* Returns availability of RDS data in internel buffer */
1061u32 fmc_is_rds_data_available(struct fmdev *fmdev, struct file *file,
1062 struct poll_table_struct *pts)
1063{
1064 poll_wait(file, &fmdev->rx.rds.read_queue, pts);
1065 if (fmdev->rx.rds.rd_idx != fmdev->rx.rds.wr_idx)
1066 return 0;
1067
1068 return -EAGAIN;
1069}
1070
1071/* Copies RDS data from internal buffer to user buffer */
1072u32 fmc_transfer_rds_from_internal_buff(struct fmdev *fmdev, struct file *file,
1073 u8 __user *buf, size_t count)
1074{
1075 u32 block_count;
1076 unsigned long flags;
1077 int ret;
1078
1079 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx) {
1080 if (file->f_flags & O_NONBLOCK)
1081 return -EWOULDBLOCK;
1082
1083 ret = wait_event_interruptible(fmdev->rx.rds.read_queue,
1084 (fmdev->rx.rds.wr_idx != fmdev->rx.rds.rd_idx));
1085 if (ret)
1086 return -EINTR;
1087 }
1088
1089 /* Calculate block count from byte count */
1090 count /= 3;
1091 block_count = 0;
1092 ret = 0;
1093
1094 spin_lock_irqsave(&fmdev->rds_buff_lock, flags);
1095
1096 while (block_count < count) {
1097 if (fmdev->rx.rds.wr_idx == fmdev->rx.rds.rd_idx)
1098 break;
1099
1100 if (copy_to_user(buf, &fmdev->rx.rds.buff[fmdev->rx.rds.rd_idx],
1101 FM_RDS_BLK_SIZE))
1102 break;
1103
1104 fmdev->rx.rds.rd_idx += FM_RDS_BLK_SIZE;
1105 if (fmdev->rx.rds.rd_idx >= fmdev->rx.rds.buf_size)
1106 fmdev->rx.rds.rd_idx = 0;
1107
1108 block_count++;
1109 buf += FM_RDS_BLK_SIZE;
1110 ret += FM_RDS_BLK_SIZE;
1111 }
1112 spin_unlock_irqrestore(&fmdev->rds_buff_lock, flags);
1113 return ret;
1114}
1115
1116u32 fmc_set_freq(struct fmdev *fmdev, u32 freq_to_set)
1117{
1118 switch (fmdev->curr_fmmode) {
1119 case FM_MODE_RX:
1120 return fm_rx_set_freq(fmdev, freq_to_set);
1121
1122 case FM_MODE_TX:
1123 return fm_tx_set_freq(fmdev, freq_to_set);
1124
1125 default:
1126 return -EINVAL;
1127 }
1128}
1129
1130u32 fmc_get_freq(struct fmdev *fmdev, u32 *cur_tuned_frq)
1131{
1132 if (fmdev->rx.freq == FM_UNDEFINED_FREQ) {
1133 fmerr("RX frequency is not set\n");
1134 return -EPERM;
1135 }
1136 if (cur_tuned_frq == NULL) {
1137 fmerr("Invalid memory\n");
1138 return -ENOMEM;
1139 }
1140
1141 switch (fmdev->curr_fmmode) {
1142 case FM_MODE_RX:
1143 *cur_tuned_frq = fmdev->rx.freq;
1144 return 0;
1145
1146 case FM_MODE_TX:
1147 *cur_tuned_frq = 0; /* TODO : Change this later */
1148 return 0;
1149
1150 default:
1151 return -EINVAL;
1152 }
1153
1154}
1155
1156u32 fmc_set_region(struct fmdev *fmdev, u8 region_to_set)
1157{
1158 switch (fmdev->curr_fmmode) {
1159 case FM_MODE_RX:
1160 return fm_rx_set_region(fmdev, region_to_set);
1161
1162 case FM_MODE_TX:
1163 return fm_tx_set_region(fmdev, region_to_set);
1164
1165 default:
1166 return -EINVAL;
1167 }
1168}
1169
1170u32 fmc_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
1171{
1172 switch (fmdev->curr_fmmode) {
1173 case FM_MODE_RX:
1174 return fm_rx_set_mute_mode(fmdev, mute_mode_toset);
1175
1176 case FM_MODE_TX:
1177 return fm_tx_set_mute_mode(fmdev, mute_mode_toset);
1178
1179 default:
1180 return -EINVAL;
1181 }
1182}
1183
1184u32 fmc_set_stereo_mono(struct fmdev *fmdev, u16 mode)
1185{
1186 switch (fmdev->curr_fmmode) {
1187 case FM_MODE_RX:
1188 return fm_rx_set_stereo_mono(fmdev, mode);
1189
1190 case FM_MODE_TX:
1191 return fm_tx_set_stereo_mono(fmdev, mode);
1192
1193 default:
1194 return -EINVAL;
1195 }
1196}
1197
1198u32 fmc_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
1199{
1200 switch (fmdev->curr_fmmode) {
1201 case FM_MODE_RX:
1202 return fm_rx_set_rds_mode(fmdev, rds_en_dis);
1203
1204 case FM_MODE_TX:
1205 return fm_tx_set_rds_mode(fmdev, rds_en_dis);
1206
1207 default:
1208 return -EINVAL;
1209 }
1210}
1211
1212/* Sends power off command to the chip */
1213static u32 fm_power_down(struct fmdev *fmdev)
1214{
1215 u16 payload;
1216 u32 ret;
1217
1218 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1219 fmerr("FM core is not ready\n");
1220 return -EPERM;
1221 }
1222 if (fmdev->curr_fmmode == FM_MODE_OFF) {
1223 fmdbg("FM chip is already in OFF state\n");
1224 return 0;
1225 }
1226
1227 payload = 0x0;
1228 ret = fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload,
1229 sizeof(payload), NULL, NULL);
1230 if (ret < 0)
1231 return ret;
1232
1233 return fmc_release(fmdev);
1234}
1235
1236/* Reads init command from FM firmware file and loads to the chip */
1237static u32 fm_download_firmware(struct fmdev *fmdev, const u8 *fw_name)
1238{
1239 const struct firmware *fw_entry;
1240 struct bts_header *fw_header;
1241 struct bts_action *action;
1242 struct bts_action_delay *delay;
1243 u8 *fw_data;
1244 int ret, fw_len, cmd_cnt;
1245
1246 cmd_cnt = 0;
1247 set_bit(FM_FW_DW_INPROGRESS, &fmdev->flag);
1248
1249 ret = request_firmware(&fw_entry, fw_name,
1250 &fmdev->radio_dev->dev);
1251 if (ret < 0) {
1252 fmerr("Unable to read firmware(%s) content\n", fw_name);
1253 return ret;
1254 }
1255 fmdbg("Firmware(%s) length : %d bytes\n", fw_name, fw_entry->size);
1256
1257 fw_data = (void *)fw_entry->data;
1258 fw_len = fw_entry->size;
1259
1260 fw_header = (struct bts_header *)fw_data;
1261 if (fw_header->magic != FM_FW_FILE_HEADER_MAGIC) {
1262 fmerr("%s not a legal TI firmware file\n", fw_name);
1263 ret = -EINVAL;
1264 goto rel_fw;
1265 }
1266 fmdbg("FW(%s) magic number : 0x%x\n", fw_name, fw_header->magic);
1267
1268 /* Skip file header info , we already verified it */
1269 fw_data += sizeof(struct bts_header);
1270 fw_len -= sizeof(struct bts_header);
1271
1272 while (fw_data && fw_len > 0) {
1273 action = (struct bts_action *)fw_data;
1274
1275 switch (action->type) {
1276 case ACTION_SEND_COMMAND: /* Send */
1277 if (fmc_send_cmd(fmdev, 0, 0, action->data,
1278 action->size, NULL, NULL))
1279 goto rel_fw;
1280
1281 cmd_cnt++;
1282 break;
1283
1284 case ACTION_DELAY: /* Delay */
1285 delay = (struct bts_action_delay *)action->data;
1286 mdelay(delay->msec);
1287 break;
1288 }
1289
1290 fw_data += (sizeof(struct bts_action) + (action->size));
1291 fw_len -= (sizeof(struct bts_action) + (action->size));
1292 }
1293 fmdbg("Firmware commands(%d) loaded to chip\n", cmd_cnt);
1294rel_fw:
1295 release_firmware(fw_entry);
1296 clear_bit(FM_FW_DW_INPROGRESS, &fmdev->flag);
1297
1298 return ret;
1299}
1300
1301/* Loads default RX configuration to the chip */
1302static u32 load_default_rx_configuration(struct fmdev *fmdev)
1303{
1304 int ret;
1305
1306 ret = fm_rx_set_volume(fmdev, FM_DEFAULT_RX_VOLUME);
1307 if (ret < 0)
1308 return ret;
1309
1310 return fm_rx_set_rssi_threshold(fmdev, FM_DEFAULT_RSSI_THRESHOLD);
1311}
1312
1313/* Does FM power on sequence */
1314static u32 fm_power_up(struct fmdev *fmdev, u8 mode)
1315{
1316 u16 payload, asic_id, asic_ver;
1317 int resp_len, ret;
1318 u8 fw_name[50];
1319
1320 if (mode >= FM_MODE_ENTRY_MAX) {
1321 fmerr("Invalid firmware download option\n");
1322 return -EINVAL;
1323 }
1324
1325 /*
1326 * Initialize FM common module. FM GPIO toggling is
1327 * taken care in Shared Transport driver.
1328 */
1329 ret = fmc_prepare(fmdev);
1330 if (ret < 0) {
1331 fmerr("Unable to prepare FM Common\n");
1332 return ret;
1333 }
1334
1335 payload = FM_ENABLE;
1336 if (fmc_send_cmd(fmdev, FM_POWER_MODE, REG_WR, &payload,
1337 sizeof(payload), NULL, NULL))
1338 goto rel;
1339
1340 /* Allow the chip to settle down in Channel-8 mode */
1341 msleep(20);
1342
1343 if (fmc_send_cmd(fmdev, ASIC_ID_GET, REG_RD, NULL,
1344 sizeof(asic_id), &asic_id, &resp_len))
1345 goto rel;
1346
1347 if (fmc_send_cmd(fmdev, ASIC_VER_GET, REG_RD, NULL,
1348 sizeof(asic_ver), &asic_ver, &resp_len))
1349 goto rel;
1350
1351 fmdbg("ASIC ID: 0x%x , ASIC Version: %d\n",
1352 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1353
1354 sprintf(fw_name, "%s_%x.%d.bts", FM_FMC_FW_FILE_START,
1355 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1356
1357 ret = fm_download_firmware(fmdev, fw_name);
1358 if (ret < 0) {
1359 fmdbg("Failed to download firmware file %s\n", fw_name);
1360 goto rel;
1361 }
1362 sprintf(fw_name, "%s_%x.%d.bts", (mode == FM_MODE_RX) ?
1363 FM_RX_FW_FILE_START : FM_TX_FW_FILE_START,
1364 be16_to_cpu(asic_id), be16_to_cpu(asic_ver));
1365
1366 ret = fm_download_firmware(fmdev, fw_name);
1367 if (ret < 0) {
1368 fmdbg("Failed to download firmware file %s\n", fw_name);
1369 goto rel;
1370 } else
1371 return ret;
1372rel:
1373 return fmc_release(fmdev);
1374}
1375
1376/* Set FM Modes(TX, RX, OFF) */
1377u32 fmc_set_mode(struct fmdev *fmdev, u8 fm_mode)
1378{
1379 int ret = 0;
1380
1381 if (fm_mode >= FM_MODE_ENTRY_MAX) {
1382 fmerr("Invalid FM mode\n");
1383 return -EINVAL;
1384 }
1385 if (fmdev->curr_fmmode == fm_mode) {
1386 fmdbg("Already fm is in mode(%d)\n", fm_mode);
1387 return ret;
1388 }
1389
1390 switch (fm_mode) {
1391 case FM_MODE_OFF: /* OFF Mode */
1392 ret = fm_power_down(fmdev);
1393 if (ret < 0) {
1394 fmerr("Failed to set OFF mode\n");
1395 return ret;
1396 }
1397 break;
1398
1399 case FM_MODE_TX: /* TX Mode */
1400 case FM_MODE_RX: /* RX Mode */
1401 /* Power down before switching to TX or RX mode */
1402 if (fmdev->curr_fmmode != FM_MODE_OFF) {
1403 ret = fm_power_down(fmdev);
1404 if (ret < 0) {
1405 fmerr("Failed to set OFF mode\n");
1406 return ret;
1407 }
1408 msleep(30);
1409 }
1410 ret = fm_power_up(fmdev, fm_mode);
1411 if (ret < 0) {
1412 fmerr("Failed to load firmware\n");
1413 return ret;
1414 }
1415 }
1416 fmdev->curr_fmmode = fm_mode;
1417
1418 /* Set default configuration */
1419 if (fmdev->curr_fmmode == FM_MODE_RX) {
1420 fmdbg("Loading default rx configuration..\n");
1421 ret = load_default_rx_configuration(fmdev);
1422 if (ret < 0)
1423 fmerr("Failed to load default values\n");
1424 }
1425
1426 return ret;
1427}
1428
1429/* Returns current FM mode (TX, RX, OFF) */
1430u32 fmc_get_mode(struct fmdev *fmdev, u8 *fmmode)
1431{
1432 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1433 fmerr("FM core is not ready\n");
1434 return -EPERM;
1435 }
1436 if (fmmode == NULL) {
1437 fmerr("Invalid memory\n");
1438 return -ENOMEM;
1439 }
1440
1441 *fmmode = fmdev->curr_fmmode;
1442 return 0;
1443}
1444
1445/* Called by ST layer when FM packet is available */
1446static long fm_st_receive(void *arg, struct sk_buff *skb)
1447{
1448 struct fmdev *fmdev;
1449
1450 fmdev = (struct fmdev *)arg;
1451
1452 if (skb == NULL) {
1453 fmerr("Invalid SKB received from ST\n");
1454 return -EFAULT;
1455 }
1456
1457 if (skb->cb[0] != FM_PKT_LOGICAL_CHAN_NUMBER) {
1458 fmerr("Received SKB (%p) is not FM Channel 8 pkt\n", skb);
1459 return -EINVAL;
1460 }
1461
1462 memcpy(skb_push(skb, 1), &skb->cb[0], 1);
1463 skb_queue_tail(&fmdev->rx_q, skb);
1464 tasklet_schedule(&fmdev->rx_task);
1465
1466 return 0;
1467}
1468
1469/*
1470 * Called by ST layer to indicate protocol registration completion
1471 * status.
1472 */
1473static void fm_st_reg_comp_cb(void *arg, char data)
1474{
1475 struct fmdev *fmdev;
1476
1477 fmdev = (struct fmdev *)arg;
1478 fmdev->streg_cbdata = data;
1479 complete(&wait_for_fmdrv_reg_comp);
1480}
1481
1482/*
1483 * This function will be called from FM V4L2 open function.
1484 * Register with ST driver and initialize driver data.
1485 */
1486u32 fmc_prepare(struct fmdev *fmdev)
1487{
1488 static struct st_proto_s fm_st_proto;
1489 u32 ret;
1490
1491 if (test_bit(FM_CORE_READY, &fmdev->flag)) {
1492 fmdbg("FM Core is already up\n");
1493 return 0;
1494 }
1495
1496 memset(&fm_st_proto, 0, sizeof(fm_st_proto));
1497 fm_st_proto.type = ST_FM;
1498 fm_st_proto.recv = fm_st_receive;
1499 fm_st_proto.match_packet = NULL;
1500 fm_st_proto.reg_complete_cb = fm_st_reg_comp_cb;
1501 fm_st_proto.write = NULL; /* TI ST driver will fill write pointer */
1502 fm_st_proto.priv_data = fmdev;
1503
1504 ret = st_register(&fm_st_proto);
1505 if (ret == -EINPROGRESS) {
1506 init_completion(&wait_for_fmdrv_reg_comp);
1507 fmdev->streg_cbdata = -EINPROGRESS;
1508 fmdbg("%s waiting for ST reg completion signal\n", __func__);
1509
1510 ret = wait_for_completion_timeout(&wait_for_fmdrv_reg_comp,
1511 FM_ST_REG_TIMEOUT);
1512
1513 if (!ret) {
1514 fmerr("Timeout(%d sec), didn't get reg "
1515 "completion signal from ST\n",
1516 jiffies_to_msecs(FM_ST_REG_TIMEOUT) / 1000);
1517 return -ETIMEDOUT;
1518 }
1519 if (fmdev->streg_cbdata != 0) {
1520 fmerr("ST reg comp CB called with error "
1521 "status %d\n", fmdev->streg_cbdata);
1522 return -EAGAIN;
1523 }
1524
1525 ret = 0;
1526 } else if (ret == -1) {
1527 fmerr("st_register failed %d\n", ret);
1528 return -EAGAIN;
1529 }
1530
1531 if (fm_st_proto.write != NULL) {
1532 g_st_write = fm_st_proto.write;
1533 } else {
1534 fmerr("Failed to get ST write func pointer\n");
1535 ret = st_unregister(ST_FM);
1536 if (ret < 0)
1537 fmerr("st_unregister failed %d\n", ret);
1538 return -EAGAIN;
1539 }
1540
1541 spin_lock_init(&fmdev->rds_buff_lock);
1542 spin_lock_init(&fmdev->resp_skb_lock);
1543
1544 /* Initialize TX queue and TX tasklet */
1545 skb_queue_head_init(&fmdev->tx_q);
1546 tasklet_init(&fmdev->tx_task, send_tasklet, (unsigned long)fmdev);
1547
1548 /* Initialize RX Queue and RX tasklet */
1549 skb_queue_head_init(&fmdev->rx_q);
1550 tasklet_init(&fmdev->rx_task, recv_tasklet, (unsigned long)fmdev);
1551
1552 fmdev->irq_info.stage = 0;
1553 atomic_set(&fmdev->tx_cnt, 1);
1554 fmdev->resp_comp = NULL;
1555
1556 init_timer(&fmdev->irq_info.timer);
1557 fmdev->irq_info.timer.function = &int_timeout_handler;
1558 fmdev->irq_info.timer.data = (unsigned long)fmdev;
1559 /*TODO: add FM_STIC_EVENT later */
1560 fmdev->irq_info.mask = FM_MAL_EVENT;
1561
1562 /* Region info */
1563 memcpy(&fmdev->rx.region, &region_configs[default_radio_region],
1564 sizeof(struct region_info));
1565
1566 fmdev->rx.mute_mode = FM_MUTE_OFF;
1567 fmdev->rx.rf_depend_mute = FM_RX_RF_DEPENDENT_MUTE_OFF;
1568 fmdev->rx.rds.flag = FM_RDS_DISABLE;
1569 fmdev->rx.freq = FM_UNDEFINED_FREQ;
1570 fmdev->rx.rds_mode = FM_RDS_SYSTEM_RDS;
1571 fmdev->rx.af_mode = FM_RX_RDS_AF_SWITCH_MODE_OFF;
1572 fmdev->irq_info.retry = 0;
1573
1574 fm_rx_reset_rds_cache(fmdev);
1575 init_waitqueue_head(&fmdev->rx.rds.read_queue);
1576
1577 fm_rx_reset_station_info(fmdev);
1578 set_bit(FM_CORE_READY, &fmdev->flag);
1579
1580 return ret;
1581}
1582
1583/*
1584 * This function will be called from FM V4L2 release function.
1585 * Unregister from ST driver.
1586 */
1587u32 fmc_release(struct fmdev *fmdev)
1588{
1589 u32 ret;
1590
1591 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
1592 fmdbg("FM Core is already down\n");
1593 return 0;
1594 }
1595 /* Sevice pending read */
1596 wake_up_interruptible(&fmdev->rx.rds.read_queue);
1597
1598 tasklet_kill(&fmdev->tx_task);
1599 tasklet_kill(&fmdev->rx_task);
1600
1601 skb_queue_purge(&fmdev->tx_q);
1602 skb_queue_purge(&fmdev->rx_q);
1603
1604 fmdev->resp_comp = NULL;
1605 fmdev->rx.freq = 0;
1606
1607 ret = st_unregister(ST_FM);
1608 if (ret < 0)
1609 fmerr("Failed to de-register FM from ST %d\n", ret);
1610 else
1611 fmdbg("Successfully unregistered from ST\n");
1612
1613 clear_bit(FM_CORE_READY, &fmdev->flag);
1614 return ret;
1615}
1616
1617/*
1618 * Module init function. Ask FM V4L module to register video device.
1619 * Allocate memory for FM driver context and RX RDS buffer.
1620 */
1621static int __init fm_drv_init(void)
1622{
1623 struct fmdev *fmdev = NULL;
1624 u32 ret = -ENOMEM;
1625
1626 fmdbg("FM driver version %s\n", FM_DRV_VERSION);
1627
1628 fmdev = kzalloc(sizeof(struct fmdev), GFP_KERNEL);
1629 if (NULL == fmdev) {
1630 fmerr("Can't allocate operation structure memory\n");
1631 return ret;
1632 }
1633 fmdev->rx.rds.buf_size = default_rds_buf * FM_RDS_BLK_SIZE;
1634 fmdev->rx.rds.buff = kzalloc(fmdev->rx.rds.buf_size, GFP_KERNEL);
1635 if (NULL == fmdev->rx.rds.buff) {
1636 fmerr("Can't allocate rds ring buffer\n");
1637 goto rel_dev;
1638 }
1639
1640 ret = fm_v4l2_init_video_device(fmdev, radio_nr);
1641 if (ret < 0)
1642 goto rel_rdsbuf;
1643
1644 fmdev->irq_info.handlers = int_handler_table;
1645 fmdev->curr_fmmode = FM_MODE_OFF;
1646 fmdev->tx_data.pwr_lvl = FM_PWR_LVL_DEF;
1647 fmdev->tx_data.preemph = FM_TX_PREEMPH_50US;
1648 return ret;
1649
1650rel_rdsbuf:
1651 kfree(fmdev->rx.rds.buff);
1652rel_dev:
1653 kfree(fmdev);
1654
1655 return ret;
1656}
1657
1658/* Module exit function. Ask FM V4L module to unregister video device */
1659static void __exit fm_drv_exit(void)
1660{
1661 struct fmdev *fmdev = NULL;
1662
1663 fmdev = fm_v4l2_deinit_video_device();
1664 if (fmdev != NULL) {
1665 kfree(fmdev->rx.rds.buff);
1666 kfree(fmdev);
1667 }
1668}
1669
1670module_init(fm_drv_init);
1671module_exit(fm_drv_exit);
1672
1673/* ------------- Module Info ------------- */
1674MODULE_AUTHOR("Manjunatha Halli <manjunatha_halli@ti.com>");
1675MODULE_DESCRIPTION("FM Driver for TI's Connectivity chip. " FM_DRV_VERSION);
1676MODULE_VERSION(FM_DRV_VERSION);
1677MODULE_LICENSE("GPL");
diff --git a/drivers/media/radio/wl128x/fmdrv_common.h b/drivers/media/radio/wl128x/fmdrv_common.h
new file mode 100644
index 000000000000..427c4164cece
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_common.h
@@ -0,0 +1,402 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM Common module header file
4 *
5 * Copyright (C) 2011 Texas Instruments
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 version 2 as
9 * published by the Free Software Foundation.
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_COMMON_H
23#define _FMDRV_COMMON_H
24
25#define FM_ST_REG_TIMEOUT msecs_to_jiffies(6000) /* 6 sec */
26#define FM_PKT_LOGICAL_CHAN_NUMBER 0x08 /* Logical channel 8 */
27
28#define REG_RD 0x1
29#define REG_WR 0x0
30
31struct fm_reg_table {
32 u8 opcode;
33 u8 type;
34 u8 *name;
35};
36
37#define STEREO_GET 0
38#define RSSI_LVL_GET 1
39#define IF_COUNT_GET 2
40#define FLAG_GET 3
41#define RDS_SYNC_GET 4
42#define RDS_DATA_GET 5
43#define FREQ_SET 10
44#define AF_FREQ_SET 11
45#define MOST_MODE_SET 12
46#define MOST_BLEND_SET 13
47#define DEMPH_MODE_SET 14
48#define SEARCH_LVL_SET 15
49#define BAND_SET 16
50#define MUTE_STATUS_SET 17
51#define RDS_PAUSE_LVL_SET 18
52#define RDS_PAUSE_DUR_SET 19
53#define RDS_MEM_SET 20
54#define RDS_BLK_B_SET 21
55#define RDS_MSK_B_SET 22
56#define RDS_PI_MASK_SET 23
57#define RDS_PI_SET 24
58#define RDS_SYSTEM_SET 25
59#define INT_MASK_SET 26
60#define SEARCH_DIR_SET 27
61#define VOLUME_SET 28
62#define AUDIO_ENABLE_SET 29
63#define PCM_MODE_SET 30
64#define I2S_MODE_CONFIG_SET 31
65#define POWER_SET 32
66#define INTX_CONFIG_SET 33
67#define PULL_EN_SET 34
68#define HILO_SET 35
69#define SWITCH2FREF 36
70#define FREQ_DRIFT_REPORT 37
71
72#define PCE_GET 40
73#define FIRM_VER_GET 41
74#define ASIC_VER_GET 42
75#define ASIC_ID_GET 43
76#define MAN_ID_GET 44
77#define TUNER_MODE_SET 45
78#define STOP_SEARCH 46
79#define RDS_CNTRL_SET 47
80
81#define WRITE_HARDWARE_REG 100
82#define CODE_DOWNLOAD 101
83#define RESET 102
84
85#define FM_POWER_MODE 254
86#define FM_INTERRUPT 255
87
88/* Transmitter API */
89
90#define CHANL_SET 55
91#define CHANL_BW_SET 56
92#define REF_SET 57
93#define POWER_ENB_SET 90
94#define POWER_ATT_SET 58
95#define POWER_LEV_SET 59
96#define AUDIO_DEV_SET 60
97#define PILOT_DEV_SET 61
98#define RDS_DEV_SET 62
99#define TX_BAND_SET 65
100#define PUPD_SET 91
101#define AUDIO_IO_SET 63
102#define PREMPH_SET 64
103#define MONO_SET 66
104#define MUTE 92
105#define MPX_LMT_ENABLE 67
106#define PI_SET 93
107#define ECC_SET 69
108#define PTY 70
109#define AF 71
110#define DISPLAY_MODE 74
111#define RDS_REP_SET 77
112#define RDS_CONFIG_DATA_SET 98
113#define RDS_DATA_SET 99
114#define RDS_DATA_ENB 94
115#define TA_SET 78
116#define TP_SET 79
117#define DI_SET 80
118#define MS_SET 81
119#define PS_SCROLL_SPEED 82
120#define TX_AUDIO_LEVEL_TEST 96
121#define TX_AUDIO_LEVEL_TEST_THRESHOLD 73
122#define TX_AUDIO_INPUT_LEVEL_RANGE_SET 54
123#define RX_ANTENNA_SELECT 87
124#define I2C_DEV_ADDR_SET 86
125#define REF_ERR_CALIB_PARAM_SET 88
126#define REF_ERR_CALIB_PERIODICITY_SET 89
127#define SOC_INT_TRIGGER 52
128#define SOC_AUDIO_PATH_SET 83
129#define SOC_PCMI_OVERRIDE 84
130#define SOC_I2S_OVERRIDE 85
131#define RSSI_BLOCK_SCAN_FREQ_SET 95
132#define RSSI_BLOCK_SCAN_START 97
133#define RSSI_BLOCK_SCAN_DATA_GET 5
134#define READ_FMANT_TUNE_VALUE 104
135
136/* SKB helpers */
137struct fm_skb_cb {
138 __u8 fm_op;
139 struct completion *completion;
140};
141
142#define fm_cb(skb) ((struct fm_skb_cb *)(skb->cb))
143
144/* FM Channel-8 command message format */
145struct fm_cmd_msg_hdr {
146 __u8 hdr; /* Logical Channel-8 */
147 __u8 len; /* Number of bytes follows */
148 __u8 op; /* FM Opcode */
149 __u8 rd_wr; /* Read/Write command */
150 __u8 dlen; /* Length of payload */
151} __attribute__ ((packed));
152
153#define FM_CMD_MSG_HDR_SIZE 5 /* sizeof(struct fm_cmd_msg_hdr) */
154
155/* FM Channel-8 event messgage format */
156struct fm_event_msg_hdr {
157 __u8 header; /* Logical Channel-8 */
158 __u8 len; /* Number of bytes follows */
159 __u8 status; /* Event status */
160 __u8 num_fm_hci_cmds; /* Number of pkts the host allowed to send */
161 __u8 op; /* FM Opcode */
162 __u8 rd_wr; /* Read/Write command */
163 __u8 dlen; /* Length of payload */
164} __attribute__ ((packed));
165
166#define FM_EVT_MSG_HDR_SIZE 7 /* sizeof(struct fm_event_msg_hdr) */
167
168/* TI's magic number in firmware file */
169#define FM_FW_FILE_HEADER_MAGIC 0x42535442
170
171#define FM_ENABLE 1
172#define FM_DISABLE 0
173
174/* FLAG_GET register bits */
175#define FM_FR_EVENT (1 << 0)
176#define FM_BL_EVENT (1 << 1)
177#define FM_RDS_EVENT (1 << 2)
178#define FM_BBLK_EVENT (1 << 3)
179#define FM_LSYNC_EVENT (1 << 4)
180#define FM_LEV_EVENT (1 << 5)
181#define FM_IFFR_EVENT (1 << 6)
182#define FM_PI_EVENT (1 << 7)
183#define FM_PD_EVENT (1 << 8)
184#define FM_STIC_EVENT (1 << 9)
185#define FM_MAL_EVENT (1 << 10)
186#define FM_POW_ENB_EVENT (1 << 11)
187
188/*
189 * Firmware files of FM. ASIC ID and ASIC version will be appened to this,
190 * later.
191 */
192#define FM_FMC_FW_FILE_START ("fmc_ch8")
193#define FM_RX_FW_FILE_START ("fm_rx_ch8")
194#define FM_TX_FW_FILE_START ("fm_tx_ch8")
195
196#define FM_UNDEFINED_FREQ 0xFFFFFFFF
197
198/* Band types */
199#define FM_BAND_EUROPE_US 0
200#define FM_BAND_JAPAN 1
201
202/* Seek directions */
203#define FM_SEARCH_DIRECTION_DOWN 0
204#define FM_SEARCH_DIRECTION_UP 1
205
206/* Tunner modes */
207#define FM_TUNER_STOP_SEARCH_MODE 0
208#define FM_TUNER_PRESET_MODE 1
209#define FM_TUNER_AUTONOMOUS_SEARCH_MODE 2
210#define FM_TUNER_AF_JUMP_MODE 3
211
212/* Min and Max volume */
213#define FM_RX_VOLUME_MIN 0
214#define FM_RX_VOLUME_MAX 70
215
216/* Volume gain step */
217#define FM_RX_VOLUME_GAIN_STEP 0x370
218
219/* Mute modes */
220#define FM_MUTE_ON 0
221#define FM_MUTE_OFF 1
222#define FM_MUTE_ATTENUATE 2
223
224#define FM_RX_UNMUTE_MODE 0x00
225#define FM_RX_RF_DEP_MODE 0x01
226#define FM_RX_AC_MUTE_MODE 0x02
227#define FM_RX_HARD_MUTE_LEFT_MODE 0x04
228#define FM_RX_HARD_MUTE_RIGHT_MODE 0x08
229#define FM_RX_SOFT_MUTE_FORCE_MODE 0x10
230
231/* RF dependent mute mode */
232#define FM_RX_RF_DEPENDENT_MUTE_ON 1
233#define FM_RX_RF_DEPENDENT_MUTE_OFF 0
234
235/* RSSI threshold min and max */
236#define FM_RX_RSSI_THRESHOLD_MIN -128
237#define FM_RX_RSSI_THRESHOLD_MAX 127
238
239/* Stereo/Mono mode */
240#define FM_STEREO_MODE 0
241#define FM_MONO_MODE 1
242#define FM_STEREO_SOFT_BLEND 1
243
244/* FM RX De-emphasis filter modes */
245#define FM_RX_EMPHASIS_FILTER_50_USEC 0
246#define FM_RX_EMPHASIS_FILTER_75_USEC 1
247
248/* FM RDS modes */
249#define FM_RDS_DISABLE 0
250#define FM_RDS_ENABLE 1
251
252#define FM_NO_PI_CODE 0
253
254/* FM and RX RDS block enable/disable */
255#define FM_RX_PWR_SET_FM_ON_RDS_OFF 0x1
256#define FM_RX_PWR_SET_FM_AND_RDS_BLK_ON 0x3
257#define FM_RX_PWR_SET_FM_AND_RDS_BLK_OFF 0x0
258
259/* RX RDS */
260#define FM_RX_RDS_FLUSH_FIFO 0x1
261#define FM_RX_RDS_FIFO_THRESHOLD 64 /* tuples */
262#define FM_RDS_BLK_SIZE 3 /* 3 bytes */
263
264/* RDS block types */
265#define FM_RDS_BLOCK_A 0
266#define FM_RDS_BLOCK_B 1
267#define FM_RDS_BLOCK_C 2
268#define FM_RDS_BLOCK_Ctag 3
269#define FM_RDS_BLOCK_D 4
270#define FM_RDS_BLOCK_E 5
271
272#define FM_RDS_BLK_IDX_A 0
273#define FM_RDS_BLK_IDX_B 1
274#define FM_RDS_BLK_IDX_C 2
275#define FM_RDS_BLK_IDX_D 3
276#define FM_RDS_BLK_IDX_UNKNOWN 0xF0
277
278#define FM_RDS_STATUS_ERR_MASK 0x18
279
280/*
281 * Represents an RDS group type & version.
282 * There are 15 groups, each group has 2 versions: A and B.
283 */
284#define FM_RDS_GROUP_TYPE_MASK_0A ((unsigned long)1<<0)
285#define FM_RDS_GROUP_TYPE_MASK_0B ((unsigned long)1<<1)
286#define FM_RDS_GROUP_TYPE_MASK_1A ((unsigned long)1<<2)
287#define FM_RDS_GROUP_TYPE_MASK_1B ((unsigned long)1<<3)
288#define FM_RDS_GROUP_TYPE_MASK_2A ((unsigned long)1<<4)
289#define FM_RDS_GROUP_TYPE_MASK_2B ((unsigned long)1<<5)
290#define FM_RDS_GROUP_TYPE_MASK_3A ((unsigned long)1<<6)
291#define FM_RDS_GROUP_TYPE_MASK_3B ((unsigned long)1<<7)
292#define FM_RDS_GROUP_TYPE_MASK_4A ((unsigned long)1<<8)
293#define FM_RDS_GROUP_TYPE_MASK_4B ((unsigned long)1<<9)
294#define FM_RDS_GROUP_TYPE_MASK_5A ((unsigned long)1<<10)
295#define FM_RDS_GROUP_TYPE_MASK_5B ((unsigned long)1<<11)
296#define FM_RDS_GROUP_TYPE_MASK_6A ((unsigned long)1<<12)
297#define FM_RDS_GROUP_TYPE_MASK_6B ((unsigned long)1<<13)
298#define FM_RDS_GROUP_TYPE_MASK_7A ((unsigned long)1<<14)
299#define FM_RDS_GROUP_TYPE_MASK_7B ((unsigned long)1<<15)
300#define FM_RDS_GROUP_TYPE_MASK_8A ((unsigned long)1<<16)
301#define FM_RDS_GROUP_TYPE_MASK_8B ((unsigned long)1<<17)
302#define FM_RDS_GROUP_TYPE_MASK_9A ((unsigned long)1<<18)
303#define FM_RDS_GROUP_TYPE_MASK_9B ((unsigned long)1<<19)
304#define FM_RDS_GROUP_TYPE_MASK_10A ((unsigned long)1<<20)
305#define FM_RDS_GROUP_TYPE_MASK_10B ((unsigned long)1<<21)
306#define FM_RDS_GROUP_TYPE_MASK_11A ((unsigned long)1<<22)
307#define FM_RDS_GROUP_TYPE_MASK_11B ((unsigned long)1<<23)
308#define FM_RDS_GROUP_TYPE_MASK_12A ((unsigned long)1<<24)
309#define FM_RDS_GROUP_TYPE_MASK_12B ((unsigned long)1<<25)
310#define FM_RDS_GROUP_TYPE_MASK_13A ((unsigned long)1<<26)
311#define FM_RDS_GROUP_TYPE_MASK_13B ((unsigned long)1<<27)
312#define FM_RDS_GROUP_TYPE_MASK_14A ((unsigned long)1<<28)
313#define FM_RDS_GROUP_TYPE_MASK_14B ((unsigned long)1<<29)
314#define FM_RDS_GROUP_TYPE_MASK_15A ((unsigned long)1<<30)
315#define FM_RDS_GROUP_TYPE_MASK_15B ((unsigned long)1<<31)
316
317/* RX Alternate Frequency info */
318#define FM_RDS_MIN_AF 1
319#define FM_RDS_MAX_AF 204
320#define FM_RDS_MAX_AF_JAPAN 140
321#define FM_RDS_1_AF_FOLLOWS 225
322#define FM_RDS_25_AF_FOLLOWS 249
323
324/* RDS system type (RDS/RBDS) */
325#define FM_RDS_SYSTEM_RDS 0
326#define FM_RDS_SYSTEM_RBDS 1
327
328/* AF on/off */
329#define FM_RX_RDS_AF_SWITCH_MODE_ON 1
330#define FM_RX_RDS_AF_SWITCH_MODE_OFF 0
331
332/* Retry count when interrupt process goes wrong */
333#define FM_IRQ_TIMEOUT_RETRY_MAX 5 /* 5 times */
334
335/* Audio IO set values */
336#define FM_RX_AUDIO_ENABLE_I2S 0x01
337#define FM_RX_AUDIO_ENABLE_ANALOG 0x02
338#define FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG 0x03
339#define FM_RX_AUDIO_ENABLE_DISABLE 0x00
340
341/* HI/LO set values */
342#define FM_RX_IFFREQ_TO_HI_SIDE 0x0
343#define FM_RX_IFFREQ_TO_LO_SIDE 0x1
344#define FM_RX_IFFREQ_HILO_AUTOMATIC 0x2
345
346/*
347 * Default RX mode configuration. Chip will be configured
348 * with this default values after loading RX firmware.
349 */
350#define FM_DEFAULT_RX_VOLUME 10
351#define FM_DEFAULT_RSSI_THRESHOLD 3
352
353/* Range for TX power level in units for dB/uV */
354#define FM_PWR_LVL_LOW 91
355#define FM_PWR_LVL_HIGH 122
356
357/* Chip specific default TX power level value */
358#define FM_PWR_LVL_DEF 4
359
360/* FM TX Pre-emphasis filter values */
361#define FM_TX_PREEMPH_OFF 1
362#define FM_TX_PREEMPH_50US 0
363#define FM_TX_PREEMPH_75US 2
364
365/* FM TX antenna impedence values */
366#define FM_TX_ANT_IMP_50 0
367#define FM_TX_ANT_IMP_200 1
368#define FM_TX_ANT_IMP_500 2
369
370/* Functions exported by FM common sub-module */
371u32 fmc_prepare(struct fmdev *);
372u32 fmc_release(struct fmdev *);
373
374void fmc_update_region_info(struct fmdev *, u8);
375u32 fmc_send_cmd(struct fmdev *, u8, u16,
376 void *, unsigned int, void *, int *);
377u32 fmc_is_rds_data_available(struct fmdev *, struct file *,
378 struct poll_table_struct *);
379u32 fmc_transfer_rds_from_internal_buff(struct fmdev *, struct file *,
380 u8 __user *, size_t);
381
382u32 fmc_set_freq(struct fmdev *, u32);
383u32 fmc_set_mode(struct fmdev *, u8);
384u32 fmc_set_region(struct fmdev *, u8);
385u32 fmc_set_mute_mode(struct fmdev *, u8);
386u32 fmc_set_stereo_mono(struct fmdev *, u16);
387u32 fmc_set_rds_mode(struct fmdev *, u8);
388
389u32 fmc_get_freq(struct fmdev *, u32 *);
390u32 fmc_get_region(struct fmdev *, u8 *);
391u32 fmc_get_mode(struct fmdev *, u8 *);
392
393/*
394 * channel spacing
395 */
396#define FM_CHANNEL_SPACING_50KHZ 1
397#define FM_CHANNEL_SPACING_100KHZ 2
398#define FM_CHANNEL_SPACING_200KHZ 4
399#define FM_FREQ_MUL 50
400
401#endif
402
diff --git a/drivers/media/radio/wl128x/fmdrv_rx.c b/drivers/media/radio/wl128x/fmdrv_rx.c
new file mode 100644
index 000000000000..ec529b55b040
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_rx.c
@@ -0,0 +1,847 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM RX functionality.
4 *
5 * Copyright (C) 2011 Texas Instruments
6 * Author: Raja Mani <raja_mani@ti.com>
7 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 */
23
24#include "fmdrv.h"
25#include "fmdrv_common.h"
26#include "fmdrv_rx.h"
27
28void fm_rx_reset_rds_cache(struct fmdev *fmdev)
29{
30 fmdev->rx.rds.flag = FM_RDS_DISABLE;
31 fmdev->rx.rds.last_blk_idx = 0;
32 fmdev->rx.rds.wr_idx = 0;
33 fmdev->rx.rds.rd_idx = 0;
34
35 if (fmdev->rx.af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
36 fmdev->irq_info.mask |= FM_LEV_EVENT;
37}
38
39void fm_rx_reset_station_info(struct fmdev *fmdev)
40{
41 fmdev->rx.stat_info.picode = FM_NO_PI_CODE;
42 fmdev->rx.stat_info.afcache_size = 0;
43 fmdev->rx.stat_info.af_list_max = 0;
44}
45
46u32 fm_rx_set_freq(struct fmdev *fmdev, u32 freq)
47{
48 unsigned long timeleft;
49 u16 payload, curr_frq, intr_flag;
50 u32 curr_frq_in_khz;
51 u32 ret, resp_len;
52
53 if (freq < fmdev->rx.region.bot_freq || freq > fmdev->rx.region.top_freq) {
54 fmerr("Invalid frequency %d\n", freq);
55 return -EINVAL;
56 }
57
58 /* Set audio enable */
59 payload = FM_RX_AUDIO_ENABLE_I2S_AND_ANALOG;
60
61 ret = fmc_send_cmd(fmdev, AUDIO_ENABLE_SET, REG_WR, &payload,
62 sizeof(payload), NULL, NULL);
63 if (ret < 0)
64 return ret;
65
66 /* Set hilo to automatic selection */
67 payload = FM_RX_IFFREQ_HILO_AUTOMATIC;
68 ret = fmc_send_cmd(fmdev, HILO_SET, REG_WR, &payload,
69 sizeof(payload), NULL, NULL);
70 if (ret < 0)
71 return ret;
72
73 /* Calculate frequency index and set*/
74 payload = (freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
75
76 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload,
77 sizeof(payload), NULL, NULL);
78 if (ret < 0)
79 return ret;
80
81 /* Read flags - just to clear any pending interrupts if we had */
82 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL);
83 if (ret < 0)
84 return ret;
85
86 /* Enable FR, BL interrupts */
87 intr_flag = fmdev->irq_info.mask;
88 fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT);
89 payload = fmdev->irq_info.mask;
90 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
91 sizeof(payload), NULL, NULL);
92 if (ret < 0)
93 return ret;
94
95 /* Start tune */
96 payload = FM_TUNER_PRESET_MODE;
97 ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
98 sizeof(payload), NULL, NULL);
99 if (ret < 0)
100 goto exit;
101
102 /* Wait for tune ended interrupt */
103 init_completion(&fmdev->maintask_comp);
104 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
105 FM_DRV_TX_TIMEOUT);
106 if (!timeleft) {
107 fmerr("Timeout(%d sec),didn't get tune ended int\n",
108 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
109 ret = -ETIMEDOUT;
110 goto exit;
111 }
112
113 /* Read freq back to confirm */
114 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2, &curr_frq, &resp_len);
115 if (ret < 0)
116 goto exit;
117
118 curr_frq = be16_to_cpu(curr_frq);
119 curr_frq_in_khz = (fmdev->rx.region.bot_freq + ((u32)curr_frq * FM_FREQ_MUL));
120
121 if (curr_frq_in_khz != freq) {
122 pr_info("Frequency is set to (%d) but "
123 "requested freq is (%d)\n", curr_frq_in_khz, freq);
124 }
125
126 /* Update local cache */
127 fmdev->rx.freq = curr_frq_in_khz;
128exit:
129 /* Re-enable default FM interrupts */
130 fmdev->irq_info.mask = intr_flag;
131 payload = fmdev->irq_info.mask;
132 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
133 sizeof(payload), NULL, NULL);
134 if (ret < 0)
135 return ret;
136
137 /* Reset RDS cache and current station pointers */
138 fm_rx_reset_rds_cache(fmdev);
139 fm_rx_reset_station_info(fmdev);
140
141 return ret;
142}
143
144static u32 fm_rx_set_channel_spacing(struct fmdev *fmdev, u32 spacing)
145{
146 u16 payload;
147 u32 ret;
148
149 if (spacing > 0 && spacing <= 50000)
150 spacing = FM_CHANNEL_SPACING_50KHZ;
151 else if (spacing > 50000 && spacing <= 100000)
152 spacing = FM_CHANNEL_SPACING_100KHZ;
153 else
154 spacing = FM_CHANNEL_SPACING_200KHZ;
155
156 /* set channel spacing */
157 payload = spacing;
158 ret = fmc_send_cmd(fmdev, CHANL_BW_SET, REG_WR, &payload,
159 sizeof(payload), NULL, NULL);
160 if (ret < 0)
161 return ret;
162
163 fmdev->rx.region.chanl_space = spacing * FM_FREQ_MUL;
164
165 return ret;
166}
167
168u32 fm_rx_seek(struct fmdev *fmdev, u32 seek_upward,
169 u32 wrap_around, u32 spacing)
170{
171 u32 resp_len;
172 u16 curr_frq, next_frq, last_frq;
173 u16 payload, int_reason, intr_flag;
174 u16 offset, space_idx;
175 unsigned long timeleft;
176 u32 ret;
177
178 /* Set channel spacing */
179 ret = fm_rx_set_channel_spacing(fmdev, spacing);
180 if (ret < 0) {
181 fmerr("Failed to set channel spacing\n");
182 return ret;
183 }
184
185 /* Read the current frequency from chip */
186 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL,
187 sizeof(curr_frq), &curr_frq, &resp_len);
188 if (ret < 0)
189 return ret;
190
191 curr_frq = be16_to_cpu(curr_frq);
192 last_frq = (fmdev->rx.region.top_freq - fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
193
194 /* Check the offset in order to be aligned to the channel spacing*/
195 space_idx = fmdev->rx.region.chanl_space / FM_FREQ_MUL;
196 offset = curr_frq % space_idx;
197
198 next_frq = seek_upward ? curr_frq + space_idx /* Seek Up */ :
199 curr_frq - space_idx /* Seek Down */ ;
200
201 /*
202 * Add or subtract offset in order to stay aligned to the channel
203 * spacing.
204 */
205 if ((short)next_frq < 0)
206 next_frq = last_frq - offset;
207 else if (next_frq > last_frq)
208 next_frq = 0 + offset;
209
210again:
211 /* Set calculated next frequency to perform seek */
212 payload = next_frq;
213 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_WR, &payload,
214 sizeof(payload), NULL, NULL);
215 if (ret < 0)
216 return ret;
217
218 /* Set search direction (0:Seek Down, 1:Seek Up) */
219 payload = (seek_upward ? FM_SEARCH_DIRECTION_UP : FM_SEARCH_DIRECTION_DOWN);
220 ret = fmc_send_cmd(fmdev, SEARCH_DIR_SET, REG_WR, &payload,
221 sizeof(payload), NULL, NULL);
222 if (ret < 0)
223 return ret;
224
225 /* Read flags - just to clear any pending interrupts if we had */
226 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2, NULL, NULL);
227 if (ret < 0)
228 return ret;
229
230 /* Enable FR, BL interrupts */
231 intr_flag = fmdev->irq_info.mask;
232 fmdev->irq_info.mask = (FM_FR_EVENT | FM_BL_EVENT);
233 payload = fmdev->irq_info.mask;
234 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
235 sizeof(payload), NULL, NULL);
236 if (ret < 0)
237 return ret;
238
239 /* Start seek */
240 payload = FM_TUNER_AUTONOMOUS_SEARCH_MODE;
241 ret = fmc_send_cmd(fmdev, TUNER_MODE_SET, REG_WR, &payload,
242 sizeof(payload), NULL, NULL);
243 if (ret < 0)
244 return ret;
245
246 /* Wait for tune ended/band limit reached interrupt */
247 init_completion(&fmdev->maintask_comp);
248 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
249 FM_DRV_RX_SEEK_TIMEOUT);
250 if (!timeleft) {
251 fmerr("Timeout(%d sec),didn't get tune ended int\n",
252 jiffies_to_msecs(FM_DRV_RX_SEEK_TIMEOUT) / 1000);
253 return -ETIMEDOUT;
254 }
255
256 int_reason = fmdev->irq_info.flag & (FM_TUNE_COMPLETE | FM_BAND_LIMIT);
257
258 /* Re-enable default FM interrupts */
259 fmdev->irq_info.mask = intr_flag;
260 payload = fmdev->irq_info.mask;
261 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
262 sizeof(payload), NULL, NULL);
263 if (ret < 0)
264 return ret;
265
266 if (int_reason & FM_BL_EVENT) {
267 if (wrap_around == 0) {
268 fmdev->rx.freq = seek_upward ?
269 fmdev->rx.region.top_freq :
270 fmdev->rx.region.bot_freq;
271 } else {
272 fmdev->rx.freq = seek_upward ?
273 fmdev->rx.region.bot_freq :
274 fmdev->rx.region.top_freq;
275 /* Calculate frequency index to write */
276 next_frq = (fmdev->rx.freq -
277 fmdev->rx.region.bot_freq) / FM_FREQ_MUL;
278 goto again;
279 }
280 } else {
281 /* Read freq to know where operation tune operation stopped */
282 ret = fmc_send_cmd(fmdev, FREQ_SET, REG_RD, NULL, 2,
283 &curr_frq, &resp_len);
284 if (ret < 0)
285 return ret;
286
287 curr_frq = be16_to_cpu(curr_frq);
288 fmdev->rx.freq = (fmdev->rx.region.bot_freq +
289 ((u32)curr_frq * FM_FREQ_MUL));
290
291 }
292 /* Reset RDS cache and current station pointers */
293 fm_rx_reset_rds_cache(fmdev);
294 fm_rx_reset_station_info(fmdev);
295
296 return ret;
297}
298
299u32 fm_rx_set_volume(struct fmdev *fmdev, u16 vol_to_set)
300{
301 u16 payload;
302 u32 ret;
303
304 if (fmdev->curr_fmmode != FM_MODE_RX)
305 return -EPERM;
306
307 if (vol_to_set < FM_RX_VOLUME_MIN || vol_to_set > FM_RX_VOLUME_MAX) {
308 fmerr("Volume is not within(%d-%d) range\n",
309 FM_RX_VOLUME_MIN, FM_RX_VOLUME_MAX);
310 return -EINVAL;
311 }
312 vol_to_set *= FM_RX_VOLUME_GAIN_STEP;
313
314 payload = vol_to_set;
315 ret = fmc_send_cmd(fmdev, VOLUME_SET, REG_WR, &payload,
316 sizeof(payload), NULL, NULL);
317 if (ret < 0)
318 return ret;
319
320 fmdev->rx.volume = vol_to_set;
321 return ret;
322}
323
324/* Get volume */
325u32 fm_rx_get_volume(struct fmdev *fmdev, u16 *curr_vol)
326{
327 if (fmdev->curr_fmmode != FM_MODE_RX)
328 return -EPERM;
329
330 if (curr_vol == NULL) {
331 fmerr("Invalid memory\n");
332 return -ENOMEM;
333 }
334
335 *curr_vol = fmdev->rx.volume / FM_RX_VOLUME_GAIN_STEP;
336
337 return 0;
338}
339
340/* To get current band's bottom and top frequency */
341u32 fm_rx_get_band_freq_range(struct fmdev *fmdev, u32 *bot_freq, u32 *top_freq)
342{
343 if (bot_freq != NULL)
344 *bot_freq = fmdev->rx.region.bot_freq;
345
346 if (top_freq != NULL)
347 *top_freq = fmdev->rx.region.top_freq;
348
349 return 0;
350}
351
352/* Returns current band index (0-Europe/US; 1-Japan) */
353void fm_rx_get_region(struct fmdev *fmdev, u8 *region)
354{
355 *region = fmdev->rx.region.fm_band;
356}
357
358/* Sets band (0-Europe/US; 1-Japan) */
359u32 fm_rx_set_region(struct fmdev *fmdev, u8 region_to_set)
360{
361 u16 payload;
362 u32 new_frq = 0;
363 u32 ret;
364
365 if (region_to_set != FM_BAND_EUROPE_US &&
366 region_to_set != FM_BAND_JAPAN) {
367 fmerr("Invalid band\n");
368 return -EINVAL;
369 }
370
371 if (fmdev->rx.region.fm_band == region_to_set) {
372 fmerr("Requested band is already configured\n");
373 return 0;
374 }
375
376 /* Send cmd to set the band */
377 payload = (u16)region_to_set;
378 ret = fmc_send_cmd(fmdev, BAND_SET, REG_WR, &payload,
379 sizeof(payload), NULL, NULL);
380 if (ret < 0)
381 return ret;
382
383 fmc_update_region_info(fmdev, region_to_set);
384
385 /* Check whether current RX frequency is within band boundary */
386 if (fmdev->rx.freq < fmdev->rx.region.bot_freq)
387 new_frq = fmdev->rx.region.bot_freq;
388 else if (fmdev->rx.freq > fmdev->rx.region.top_freq)
389 new_frq = fmdev->rx.region.top_freq;
390
391 if (new_frq) {
392 fmdbg("Current freq is not within band limit boundary,"
393 "switching to %d KHz\n", new_frq);
394 /* Current RX frequency is not in range. So, update it */
395 ret = fm_rx_set_freq(fmdev, new_frq);
396 }
397
398 return ret;
399}
400
401/* Reads current mute mode (Mute Off/On/Attenuate)*/
402u32 fm_rx_get_mute_mode(struct fmdev *fmdev, u8 *curr_mute_mode)
403{
404 if (fmdev->curr_fmmode != FM_MODE_RX)
405 return -EPERM;
406
407 if (curr_mute_mode == NULL) {
408 fmerr("Invalid memory\n");
409 return -ENOMEM;
410 }
411
412 *curr_mute_mode = fmdev->rx.mute_mode;
413
414 return 0;
415}
416
417static u32 fm_config_rx_mute_reg(struct fmdev *fmdev)
418{
419 u16 payload, muteval;
420 u32 ret;
421
422 muteval = 0;
423 switch (fmdev->rx.mute_mode) {
424 case FM_MUTE_ON:
425 muteval = FM_RX_AC_MUTE_MODE;
426 break;
427
428 case FM_MUTE_OFF:
429 muteval = FM_RX_UNMUTE_MODE;
430 break;
431
432 case FM_MUTE_ATTENUATE:
433 muteval = FM_RX_SOFT_MUTE_FORCE_MODE;
434 break;
435 }
436 if (fmdev->rx.rf_depend_mute == FM_RX_RF_DEPENDENT_MUTE_ON)
437 muteval |= FM_RX_RF_DEP_MODE;
438 else
439 muteval &= ~FM_RX_RF_DEP_MODE;
440
441 payload = muteval;
442 ret = fmc_send_cmd(fmdev, MUTE_STATUS_SET, REG_WR, &payload,
443 sizeof(payload), NULL, NULL);
444 if (ret < 0)
445 return ret;
446
447 return 0;
448}
449
450/* Configures mute mode (Mute Off/On/Attenuate) */
451u32 fm_rx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
452{
453 u8 org_state;
454 u32 ret;
455
456 if (fmdev->rx.mute_mode == mute_mode_toset)
457 return 0;
458
459 org_state = fmdev->rx.mute_mode;
460 fmdev->rx.mute_mode = mute_mode_toset;
461
462 ret = fm_config_rx_mute_reg(fmdev);
463 if (ret < 0) {
464 fmdev->rx.mute_mode = org_state;
465 return ret;
466 }
467
468 return 0;
469}
470
471/* Gets RF dependent soft mute mode enable/disable status */
472u32 fm_rx_get_rfdepend_softmute(struct fmdev *fmdev, u8 *curr_mute_mode)
473{
474 if (fmdev->curr_fmmode != FM_MODE_RX)
475 return -EPERM;
476
477 if (curr_mute_mode == NULL) {
478 fmerr("Invalid memory\n");
479 return -ENOMEM;
480 }
481
482 *curr_mute_mode = fmdev->rx.rf_depend_mute;
483
484 return 0;
485}
486
487/* Sets RF dependent soft mute mode */
488u32 fm_rx_set_rfdepend_softmute(struct fmdev *fmdev, u8 rfdepend_mute)
489{
490 u8 org_state;
491 u32 ret;
492
493 if (fmdev->curr_fmmode != FM_MODE_RX)
494 return -EPERM;
495
496 if (rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_ON &&
497 rfdepend_mute != FM_RX_RF_DEPENDENT_MUTE_OFF) {
498 fmerr("Invalid RF dependent soft mute\n");
499 return -EINVAL;
500 }
501 if (fmdev->rx.rf_depend_mute == rfdepend_mute)
502 return 0;
503
504 org_state = fmdev->rx.rf_depend_mute;
505 fmdev->rx.rf_depend_mute = rfdepend_mute;
506
507 ret = fm_config_rx_mute_reg(fmdev);
508 if (ret < 0) {
509 fmdev->rx.rf_depend_mute = org_state;
510 return ret;
511 }
512
513 return 0;
514}
515
516/* Returns the signal strength level of current channel */
517u32 fm_rx_get_rssi_level(struct fmdev *fmdev, u16 *rssilvl)
518{
519 u16 curr_rssi_lel;
520 u32 resp_len;
521 u32 ret;
522
523 if (rssilvl == NULL) {
524 fmerr("Invalid memory\n");
525 return -ENOMEM;
526 }
527 /* Read current RSSI level */
528 ret = fmc_send_cmd(fmdev, RSSI_LVL_GET, REG_RD, NULL, 2,
529 &curr_rssi_lel, &resp_len);
530 if (ret < 0)
531 return ret;
532
533 *rssilvl = be16_to_cpu(curr_rssi_lel);
534
535 return 0;
536}
537
538/*
539 * Sets the signal strength level that once reached
540 * will stop the auto search process
541 */
542u32 fm_rx_set_rssi_threshold(struct fmdev *fmdev, short rssi_lvl_toset)
543{
544 u16 payload;
545 u32 ret;
546
547 if (rssi_lvl_toset < FM_RX_RSSI_THRESHOLD_MIN ||
548 rssi_lvl_toset > FM_RX_RSSI_THRESHOLD_MAX) {
549 fmerr("Invalid RSSI threshold level\n");
550 return -EINVAL;
551 }
552 payload = (u16)rssi_lvl_toset;
553 ret = fmc_send_cmd(fmdev, SEARCH_LVL_SET, REG_WR, &payload,
554 sizeof(payload), NULL, NULL);
555 if (ret < 0)
556 return ret;
557
558 fmdev->rx.rssi_threshold = rssi_lvl_toset;
559
560 return 0;
561}
562
563/* Returns current RX RSSI threshold value */
564u32 fm_rx_get_rssi_threshold(struct fmdev *fmdev, short *curr_rssi_lvl)
565{
566 if (fmdev->curr_fmmode != FM_MODE_RX)
567 return -EPERM;
568
569 if (curr_rssi_lvl == NULL) {
570 fmerr("Invalid memory\n");
571 return -ENOMEM;
572 }
573
574 *curr_rssi_lvl = fmdev->rx.rssi_threshold;
575
576 return 0;
577}
578
579/* Sets RX stereo/mono modes */
580u32 fm_rx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
581{
582 u16 payload;
583 u32 ret;
584
585 if (mode != FM_STEREO_MODE && mode != FM_MONO_MODE) {
586 fmerr("Invalid mode\n");
587 return -EINVAL;
588 }
589
590 /* Set stereo/mono mode */
591 payload = (u16)mode;
592 ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_WR, &payload,
593 sizeof(payload), NULL, NULL);
594 if (ret < 0)
595 return ret;
596
597 /* Set stereo blending mode */
598 payload = FM_STEREO_SOFT_BLEND;
599 ret = fmc_send_cmd(fmdev, MOST_BLEND_SET, REG_WR, &payload,
600 sizeof(payload), NULL, NULL);
601 if (ret < 0)
602 return ret;
603
604 return 0;
605}
606
607/* Gets current RX stereo/mono mode */
608u32 fm_rx_get_stereo_mono(struct fmdev *fmdev, u16 *mode)
609{
610 u16 curr_mode;
611 u32 ret, resp_len;
612
613 if (mode == NULL) {
614 fmerr("Invalid memory\n");
615 return -ENOMEM;
616 }
617
618 ret = fmc_send_cmd(fmdev, MOST_MODE_SET, REG_RD, NULL, 2,
619 &curr_mode, &resp_len);
620 if (ret < 0)
621 return ret;
622
623 *mode = be16_to_cpu(curr_mode);
624
625 return 0;
626}
627
628/* Choose RX de-emphasis filter mode (50us/75us) */
629u32 fm_rx_set_deemphasis_mode(struct fmdev *fmdev, u16 mode)
630{
631 u16 payload;
632 u32 ret;
633
634 if (fmdev->curr_fmmode != FM_MODE_RX)
635 return -EPERM;
636
637 if (mode != FM_RX_EMPHASIS_FILTER_50_USEC &&
638 mode != FM_RX_EMPHASIS_FILTER_75_USEC) {
639 fmerr("Invalid rx de-emphasis mode (%d)\n", mode);
640 return -EINVAL;
641 }
642
643 payload = mode;
644 ret = fmc_send_cmd(fmdev, DEMPH_MODE_SET, REG_WR, &payload,
645 sizeof(payload), NULL, NULL);
646 if (ret < 0)
647 return ret;
648
649 fmdev->rx.deemphasis_mode = mode;
650
651 return 0;
652}
653
654/* Gets current RX de-emphasis filter mode */
655u32 fm_rx_get_deemph_mode(struct fmdev *fmdev, u16 *curr_deemphasis_mode)
656{
657 if (fmdev->curr_fmmode != FM_MODE_RX)
658 return -EPERM;
659
660 if (curr_deemphasis_mode == NULL) {
661 fmerr("Invalid memory\n");
662 return -ENOMEM;
663 }
664
665 *curr_deemphasis_mode = fmdev->rx.deemphasis_mode;
666
667 return 0;
668}
669
670/* Enable/Disable RX RDS */
671u32 fm_rx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
672{
673 u16 payload;
674 u32 ret;
675
676 if (rds_en_dis != FM_RDS_ENABLE && rds_en_dis != FM_RDS_DISABLE) {
677 fmerr("Invalid rds option\n");
678 return -EINVAL;
679 }
680
681 if (rds_en_dis == FM_RDS_ENABLE
682 && fmdev->rx.rds.flag == FM_RDS_DISABLE) {
683 /* Turn on RX RDS and RDS circuit */
684 payload = FM_RX_PWR_SET_FM_AND_RDS_BLK_ON;
685 ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload,
686 sizeof(payload), NULL, NULL);
687 if (ret < 0)
688 return ret;
689
690 /* Clear and reset RDS FIFO */
691 payload = FM_RX_RDS_FLUSH_FIFO;
692 ret = fmc_send_cmd(fmdev, RDS_CNTRL_SET, REG_WR, &payload,
693 sizeof(payload), NULL, NULL);
694 if (ret < 0)
695 return ret;
696
697 /* Read flags - just to clear any pending interrupts. */
698 ret = fmc_send_cmd(fmdev, FLAG_GET, REG_RD, NULL, 2,
699 NULL, NULL);
700 if (ret < 0)
701 return ret;
702
703 /* Set RDS FIFO threshold value */
704 payload = FM_RX_RDS_FIFO_THRESHOLD;
705 ret = fmc_send_cmd(fmdev, RDS_MEM_SET, REG_WR, &payload,
706 sizeof(payload), NULL, NULL);
707 if (ret < 0)
708 return ret;
709
710 /* Enable RDS interrupt */
711 fmdev->irq_info.mask |= FM_RDS_EVENT;
712 payload = fmdev->irq_info.mask;
713 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
714 sizeof(payload), NULL, NULL);
715 if (ret < 0) {
716 fmdev->irq_info.mask &= ~FM_RDS_EVENT;
717 return ret;
718 }
719
720 /* Update our local flag */
721 fmdev->rx.rds.flag = FM_RDS_ENABLE;
722 } else if (rds_en_dis == FM_RDS_DISABLE
723 && fmdev->rx.rds.flag == FM_RDS_ENABLE) {
724 /* Turn off RX RDS */
725 payload = FM_RX_PWR_SET_FM_ON_RDS_OFF;
726 ret = fmc_send_cmd(fmdev, POWER_SET, REG_WR, &payload,
727 sizeof(payload), NULL, NULL);
728 if (ret < 0)
729 return ret;
730
731 /* Reset RDS pointers */
732 fmdev->rx.rds.last_blk_idx = 0;
733 fmdev->rx.rds.wr_idx = 0;
734 fmdev->rx.rds.rd_idx = 0;
735 fm_rx_reset_station_info(fmdev);
736
737 /* Update RDS local cache */
738 fmdev->irq_info.mask &= ~(FM_RDS_EVENT);
739 fmdev->rx.rds.flag = FM_RDS_DISABLE;
740 }
741
742 return 0;
743}
744
745/* Returns current RX RDS enable/disable status */
746u32 fm_rx_get_rds_mode(struct fmdev *fmdev, u8 *curr_rds_en_dis)
747{
748 if (fmdev->curr_fmmode != FM_MODE_RX)
749 return -EPERM;
750
751 if (curr_rds_en_dis == NULL) {
752 fmerr("Invalid memory\n");
753 return -ENOMEM;
754 }
755
756 *curr_rds_en_dis = fmdev->rx.rds.flag;
757
758 return 0;
759}
760
761/* Sets RDS operation mode (RDS/RDBS) */
762u32 fm_rx_set_rds_system(struct fmdev *fmdev, u8 rds_mode)
763{
764 u16 payload;
765 u32 ret;
766
767 if (fmdev->curr_fmmode != FM_MODE_RX)
768 return -EPERM;
769
770 if (rds_mode != FM_RDS_SYSTEM_RDS && rds_mode != FM_RDS_SYSTEM_RBDS) {
771 fmerr("Invalid rds mode\n");
772 return -EINVAL;
773 }
774 /* Set RDS operation mode */
775 payload = (u16)rds_mode;
776 ret = fmc_send_cmd(fmdev, RDS_SYSTEM_SET, REG_WR, &payload,
777 sizeof(payload), NULL, NULL);
778 if (ret < 0)
779 return ret;
780
781 fmdev->rx.rds_mode = rds_mode;
782
783 return 0;
784}
785
786/* Returns current RDS operation mode */
787u32 fm_rx_get_rds_system(struct fmdev *fmdev, u8 *rds_mode)
788{
789 if (fmdev->curr_fmmode != FM_MODE_RX)
790 return -EPERM;
791
792 if (rds_mode == NULL) {
793 fmerr("Invalid memory\n");
794 return -ENOMEM;
795 }
796
797 *rds_mode = fmdev->rx.rds_mode;
798
799 return 0;
800}
801
802/* Configures Alternate Frequency switch mode */
803u32 fm_rx_set_af_switch(struct fmdev *fmdev, u8 af_mode)
804{
805 u16 payload;
806 u32 ret;
807
808 if (fmdev->curr_fmmode != FM_MODE_RX)
809 return -EPERM;
810
811 if (af_mode != FM_RX_RDS_AF_SWITCH_MODE_ON &&
812 af_mode != FM_RX_RDS_AF_SWITCH_MODE_OFF) {
813 fmerr("Invalid af mode\n");
814 return -EINVAL;
815 }
816 /* Enable/disable low RSSI interrupt based on af_mode */
817 if (af_mode == FM_RX_RDS_AF_SWITCH_MODE_ON)
818 fmdev->irq_info.mask |= FM_LEV_EVENT;
819 else
820 fmdev->irq_info.mask &= ~FM_LEV_EVENT;
821
822 payload = fmdev->irq_info.mask;
823 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
824 sizeof(payload), NULL, NULL);
825 if (ret < 0)
826 return ret;
827
828 fmdev->rx.af_mode = af_mode;
829
830 return 0;
831}
832
833/* Returns Alternate Frequency switch status */
834u32 fm_rx_get_af_switch(struct fmdev *fmdev, u8 *af_mode)
835{
836 if (fmdev->curr_fmmode != FM_MODE_RX)
837 return -EPERM;
838
839 if (af_mode == NULL) {
840 fmerr("Invalid memory\n");
841 return -ENOMEM;
842 }
843
844 *af_mode = fmdev->rx.af_mode;
845
846 return 0;
847}
diff --git a/drivers/media/radio/wl128x/fmdrv_rx.h b/drivers/media/radio/wl128x/fmdrv_rx.h
new file mode 100644
index 000000000000..329e62f6be76
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_rx.h
@@ -0,0 +1,59 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM RX module header.
4 *
5 * Copyright (C) 2011 Texas Instruments
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 version 2 as
9 * published by the Free Software Foundation.
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_RX_H
23#define _FMDRV_RX_H
24
25u32 fm_rx_set_freq(struct fmdev *, u32);
26u32 fm_rx_set_mute_mode(struct fmdev *, u8);
27u32 fm_rx_set_stereo_mono(struct fmdev *, u16);
28u32 fm_rx_set_rds_mode(struct fmdev *, u8);
29u32 fm_rx_set_rds_system(struct fmdev *, u8);
30u32 fm_rx_set_volume(struct fmdev *, u16);
31u32 fm_rx_set_rssi_threshold(struct fmdev *, short);
32u32 fm_rx_set_region(struct fmdev *, u8);
33u32 fm_rx_set_rfdepend_softmute(struct fmdev *, u8);
34u32 fm_rx_set_deemphasis_mode(struct fmdev *, u16);
35u32 fm_rx_set_af_switch(struct fmdev *, u8);
36
37void fm_rx_reset_rds_cache(struct fmdev *);
38void fm_rx_reset_station_info(struct fmdev *);
39
40u32 fm_rx_seek(struct fmdev *, u32, u32, u32);
41
42u32 fm_rx_get_rds_mode(struct fmdev *, u8 *);
43u32 fm_rx_get_rds_system(struct fmdev *, u8 *);
44u32 fm_rx_get_mute_mode(struct fmdev *, u8 *);
45u32 fm_rx_get_volume(struct fmdev *, u16 *);
46u32 fm_rx_get_band_freq_range(struct fmdev *,
47 u32 *, u32 *);
48u32 fm_rx_get_stereo_mono(struct fmdev *, u16 *);
49u32 fm_rx_get_rssi_level(struct fmdev *, u16 *);
50u32 fm_rx_get_rssi_threshold(struct fmdev *, short *);
51u32 fm_rx_get_rfdepend_softmute(struct fmdev *, u8 *);
52u32 fm_rx_get_deemph_mode(struct fmdev *, u16 *);
53u32 fm_rx_get_af_switch(struct fmdev *, u8 *);
54void fm_rx_get_region(struct fmdev *, u8 *);
55
56u32 fm_rx_set_chanl_spacing(struct fmdev *, u8);
57u32 fm_rx_get_chanl_spacing(struct fmdev *, u8 *);
58#endif
59
diff --git a/drivers/media/radio/wl128x/fmdrv_tx.c b/drivers/media/radio/wl128x/fmdrv_tx.c
new file mode 100644
index 000000000000..be54068b56a8
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_tx.c
@@ -0,0 +1,425 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This sub-module of FM driver implements FM TX functionality.
4 *
5 * Copyright (C) 2011 Texas Instruments
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 version 2 as
9 * published by the Free Software Foundation.
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#include <linux/delay.h>
23#include "fmdrv.h"
24#include "fmdrv_common.h"
25#include "fmdrv_tx.h"
26
27u32 fm_tx_set_stereo_mono(struct fmdev *fmdev, u16 mode)
28{
29 u16 payload;
30 u32 ret;
31
32 if (fmdev->tx_data.aud_mode == mode)
33 return 0;
34
35 fmdbg("stereo mode: %d\n", mode);
36
37 /* Set Stereo/Mono mode */
38 payload = (1 - mode);
39 ret = fmc_send_cmd(fmdev, MONO_SET, REG_WR, &payload,
40 sizeof(payload), NULL, NULL);
41 if (ret < 0)
42 return ret;
43
44 fmdev->tx_data.aud_mode = mode;
45
46 return ret;
47}
48
49static u32 set_rds_text(struct fmdev *fmdev, u8 *rds_text)
50{
51 u16 payload;
52 u32 ret;
53
54 ret = fmc_send_cmd(fmdev, RDS_DATA_SET, REG_WR, rds_text,
55 strlen(rds_text), NULL, NULL);
56 if (ret < 0)
57 return ret;
58
59 /* Scroll mode */
60 payload = (u16)0x1;
61 ret = fmc_send_cmd(fmdev, DISPLAY_MODE, REG_WR, &payload,
62 sizeof(payload), NULL, NULL);
63 if (ret < 0)
64 return ret;
65
66 return 0;
67}
68
69static u32 set_rds_data_mode(struct fmdev *fmdev, u8 mode)
70{
71 u16 payload;
72 u32 ret;
73
74 /* Setting unique PI TODO: how unique? */
75 payload = (u16)0xcafe;
76 ret = fmc_send_cmd(fmdev, PI_SET, REG_WR, &payload,
77 sizeof(payload), NULL, NULL);
78 if (ret < 0)
79 return ret;
80
81 /* Set decoder id */
82 payload = (u16)0xa;
83 ret = fmc_send_cmd(fmdev, DI_SET, REG_WR, &payload,
84 sizeof(payload), NULL, NULL);
85 if (ret < 0)
86 return ret;
87
88 /* TODO: RDS_MODE_GET? */
89 return 0;
90}
91
92static u32 set_rds_len(struct fmdev *fmdev, u8 type, u16 len)
93{
94 u16 payload;
95 u32 ret;
96
97 len |= type << 8;
98 payload = len;
99 ret = fmc_send_cmd(fmdev, RDS_CONFIG_DATA_SET, REG_WR, &payload,
100 sizeof(payload), NULL, NULL);
101 if (ret < 0)
102 return ret;
103
104 /* TODO: LENGTH_GET? */
105 return 0;
106}
107
108u32 fm_tx_set_rds_mode(struct fmdev *fmdev, u8 rds_en_dis)
109{
110 u16 payload;
111 u32 ret;
112 u8 rds_text[] = "Zoom2\n";
113
114 fmdbg("rds_en_dis:%d(E:%d, D:%d)\n", rds_en_dis,
115 FM_RDS_ENABLE, FM_RDS_DISABLE);
116
117 if (rds_en_dis == FM_RDS_ENABLE) {
118 /* Set RDS length */
119 set_rds_len(fmdev, 0, strlen(rds_text));
120
121 /* Set RDS text */
122 set_rds_text(fmdev, rds_text);
123
124 /* Set RDS mode */
125 set_rds_data_mode(fmdev, 0x0);
126 }
127
128 /* Send command to enable RDS */
129 if (rds_en_dis == FM_RDS_ENABLE)
130 payload = 0x01;
131 else
132 payload = 0x00;
133
134 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
135 sizeof(payload), NULL, NULL);
136 if (ret < 0)
137 return ret;
138
139 if (rds_en_dis == FM_RDS_ENABLE) {
140 /* Set RDS length */
141 set_rds_len(fmdev, 0, strlen(rds_text));
142
143 /* Set RDS text */
144 set_rds_text(fmdev, rds_text);
145 }
146 fmdev->tx_data.rds.flag = rds_en_dis;
147
148 return 0;
149}
150
151u32 fm_tx_set_radio_text(struct fmdev *fmdev, u8 *rds_text, u8 rds_type)
152{
153 u16 payload;
154 u32 ret;
155
156 if (fmdev->curr_fmmode != FM_MODE_TX)
157 return -EPERM;
158
159 fm_tx_set_rds_mode(fmdev, 0);
160
161 /* Set RDS length */
162 set_rds_len(fmdev, rds_type, strlen(rds_text));
163
164 /* Set RDS text */
165 set_rds_text(fmdev, rds_text);
166
167 /* Set RDS mode */
168 set_rds_data_mode(fmdev, 0x0);
169
170 payload = 1;
171 ret = fmc_send_cmd(fmdev, RDS_DATA_ENB, REG_WR, &payload,
172 sizeof(payload), NULL, NULL);
173 if (ret < 0)
174 return ret;
175
176 return 0;
177}
178
179u32 fm_tx_set_af(struct fmdev *fmdev, u32 af)
180{
181 u16 payload;
182 u32 ret;
183
184 if (fmdev->curr_fmmode != FM_MODE_TX)
185 return -EPERM;
186
187 fmdbg("AF: %d\n", af);
188
189 af = (af - 87500) / 100;
190 payload = (u16)af;
191 ret = fmc_send_cmd(fmdev, TA_SET, REG_WR, &payload,
192 sizeof(payload), NULL, NULL);
193 if (ret < 0)
194 return ret;
195
196 return 0;
197}
198
199u32 fm_tx_set_region(struct fmdev *fmdev, u8 region)
200{
201 u16 payload;
202 u32 ret;
203
204 if (region != FM_BAND_EUROPE_US && region != FM_BAND_JAPAN) {
205 fmerr("Invalid band\n");
206 return -EINVAL;
207 }
208
209 /* Send command to set the band */
210 payload = (u16)region;
211 ret = fmc_send_cmd(fmdev, TX_BAND_SET, REG_WR, &payload,
212 sizeof(payload), NULL, NULL);
213 if (ret < 0)
214 return ret;
215
216 return 0;
217}
218
219u32 fm_tx_set_mute_mode(struct fmdev *fmdev, u8 mute_mode_toset)
220{
221 u16 payload;
222 u32 ret;
223
224 fmdbg("tx: mute mode %d\n", mute_mode_toset);
225
226 payload = mute_mode_toset;
227 ret = fmc_send_cmd(fmdev, MUTE, REG_WR, &payload,
228 sizeof(payload), NULL, NULL);
229 if (ret < 0)
230 return ret;
231
232 return 0;
233}
234
235/* Set TX Audio I/O */
236static u32 set_audio_io(struct fmdev *fmdev)
237{
238 struct fmtx_data *tx = &fmdev->tx_data;
239 u16 payload;
240 u32 ret;
241
242 /* Set Audio I/O Enable */
243 payload = tx->audio_io;
244 ret = fmc_send_cmd(fmdev, AUDIO_IO_SET, REG_WR, &payload,
245 sizeof(payload), NULL, NULL);
246 if (ret < 0)
247 return ret;
248
249 /* TODO: is audio set? */
250 return 0;
251}
252
253/* Start TX Transmission */
254static u32 enable_xmit(struct fmdev *fmdev, u8 new_xmit_state)
255{
256 struct fmtx_data *tx = &fmdev->tx_data;
257 unsigned long timeleft;
258 u16 payload;
259 u32 ret;
260
261 /* Enable POWER_ENB interrupts */
262 payload = FM_POW_ENB_EVENT;
263 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
264 sizeof(payload), NULL, NULL);
265 if (ret < 0)
266 return ret;
267
268 /* Set Power Enable */
269 payload = new_xmit_state;
270 ret = fmc_send_cmd(fmdev, POWER_ENB_SET, REG_WR, &payload,
271 sizeof(payload), NULL, NULL);
272 if (ret < 0)
273 return ret;
274
275 /* Wait for Power Enabled */
276 init_completion(&fmdev->maintask_comp);
277 timeleft = wait_for_completion_timeout(&fmdev->maintask_comp,
278 FM_DRV_TX_TIMEOUT);
279 if (!timeleft) {
280 fmerr("Timeout(%d sec),didn't get tune ended interrupt\n",
281 jiffies_to_msecs(FM_DRV_TX_TIMEOUT) / 1000);
282 return -ETIMEDOUT;
283 }
284
285 set_bit(FM_CORE_TX_XMITING, &fmdev->flag);
286 tx->xmit_state = new_xmit_state;
287
288 return 0;
289}
290
291/* Set TX power level */
292u32 fm_tx_set_pwr_lvl(struct fmdev *fmdev, u8 new_pwr_lvl)
293{
294 u16 payload;
295 struct fmtx_data *tx = &fmdev->tx_data;
296 u32 ret;
297
298 if (fmdev->curr_fmmode != FM_MODE_TX)
299 return -EPERM;
300 fmdbg("tx: pwr_level_to_set %ld\n", (long int)new_pwr_lvl);
301
302 /* If the core isn't ready update global variable */
303 if (!test_bit(FM_CORE_READY, &fmdev->flag)) {
304 tx->pwr_lvl = new_pwr_lvl;
305 return 0;
306 }
307
308 /* Set power level: Application will specify power level value in
309 * units of dB/uV, whereas range and step are specific to FM chip.
310 * For TI's WL chips, convert application specified power level value
311 * to chip specific value by subtracting 122 from it. Refer to TI FM
312 * data sheet for details.
313 * */
314
315 payload = (FM_PWR_LVL_HIGH - new_pwr_lvl);
316 ret = fmc_send_cmd(fmdev, POWER_LEV_SET, REG_WR, &payload,
317 sizeof(payload), NULL, NULL);
318 if (ret < 0)
319 return ret;
320
321 /* TODO: is the power level set? */
322 tx->pwr_lvl = new_pwr_lvl;
323
324 return 0;
325}
326
327/*
328 * Sets FM TX pre-emphasis filter value (OFF, 50us, or 75us)
329 * Convert V4L2 specified filter values to chip specific filter values.
330 */
331u32 fm_tx_set_preemph_filter(struct fmdev *fmdev, u32 preemphasis)
332{
333 struct fmtx_data *tx = &fmdev->tx_data;
334 u16 payload;
335 u32 ret;
336
337 if (fmdev->curr_fmmode != FM_MODE_TX)
338 return -EPERM;
339
340 switch (preemphasis) {
341 case V4L2_PREEMPHASIS_DISABLED:
342 payload = FM_TX_PREEMPH_OFF;
343 break;
344 case V4L2_PREEMPHASIS_50_uS:
345 payload = FM_TX_PREEMPH_50US;
346 break;
347 case V4L2_PREEMPHASIS_75_uS:
348 payload = FM_TX_PREEMPH_75US;
349 break;
350 }
351
352 ret = fmc_send_cmd(fmdev, PREMPH_SET, REG_WR, &payload,
353 sizeof(payload), NULL, NULL);
354 if (ret < 0)
355 return ret;
356
357 tx->preemph = payload;
358
359 return ret;
360}
361
362/* Get the TX tuning capacitor value.*/
363u32 fm_tx_get_tune_cap_val(struct fmdev *fmdev)
364{
365 u16 curr_val;
366 u32 ret, resp_len;
367
368 if (fmdev->curr_fmmode != FM_MODE_TX)
369 return -EPERM;
370
371 ret = fmc_send_cmd(fmdev, READ_FMANT_TUNE_VALUE, REG_RD,
372 NULL, sizeof(curr_val), &curr_val, &resp_len);
373 if (ret < 0)
374 return ret;
375
376 curr_val = be16_to_cpu(curr_val);
377
378 return curr_val;
379}
380
381/* Set TX Frequency */
382u32 fm_tx_set_freq(struct fmdev *fmdev, u32 freq_to_set)
383{
384 struct fmtx_data *tx = &fmdev->tx_data;
385 u16 payload, chanl_index;
386 u32 ret;
387
388 if (test_bit(FM_CORE_TX_XMITING, &fmdev->flag)) {
389 enable_xmit(fmdev, 0);
390 clear_bit(FM_CORE_TX_XMITING, &fmdev->flag);
391 }
392
393 /* Enable FR, BL interrupts */
394 payload = (FM_FR_EVENT | FM_BL_EVENT);
395 ret = fmc_send_cmd(fmdev, INT_MASK_SET, REG_WR, &payload,
396 sizeof(payload), NULL, NULL);
397 if (ret < 0)
398 return ret;
399
400 tx->tx_frq = (unsigned long)freq_to_set;
401 fmdbg("tx: freq_to_set %ld\n", (long int)tx->tx_frq);
402
403 chanl_index = freq_to_set / 10;
404
405 /* Set current tuner channel */
406 payload = chanl_index;
407 ret = fmc_send_cmd(fmdev, CHANL_SET, REG_WR, &payload,
408 sizeof(payload), NULL, NULL);
409 if (ret < 0)
410 return ret;
411
412 fm_tx_set_pwr_lvl(fmdev, tx->pwr_lvl);
413 fm_tx_set_preemph_filter(fmdev, tx->preemph);
414
415 tx->audio_io = 0x01; /* I2S */
416 set_audio_io(fmdev);
417
418 enable_xmit(fmdev, 0x01); /* Enable transmission */
419
420 tx->aud_mode = FM_STEREO_MODE;
421 tx->rds.flag = FM_RDS_DISABLE;
422
423 return 0;
424}
425
diff --git a/drivers/media/radio/wl128x/fmdrv_tx.h b/drivers/media/radio/wl128x/fmdrv_tx.h
new file mode 100644
index 000000000000..e393a2bdd49e
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_tx.h
@@ -0,0 +1,37 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * FM TX module header.
4 *
5 * Copyright (C) 2011 Texas Instruments
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 version 2 as
9 * published by the Free Software Foundation.
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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 */
21
22#ifndef _FMDRV_TX_H
23#define _FMDRV_TX_H
24
25u32 fm_tx_set_freq(struct fmdev *, u32);
26u32 fm_tx_set_pwr_lvl(struct fmdev *, u8);
27u32 fm_tx_set_region(struct fmdev *, u8);
28u32 fm_tx_set_mute_mode(struct fmdev *, u8);
29u32 fm_tx_set_stereo_mono(struct fmdev *, u16);
30u32 fm_tx_set_rds_mode(struct fmdev *, u8);
31u32 fm_tx_set_radio_text(struct fmdev *, u8 *, u8);
32u32 fm_tx_set_af(struct fmdev *, u32);
33u32 fm_tx_set_preemph_filter(struct fmdev *, u32);
34u32 fm_tx_get_tune_cap_val(struct fmdev *);
35
36#endif
37
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.c b/drivers/media/radio/wl128x/fmdrv_v4l2.c
new file mode 100644
index 000000000000..d50e5ac75ab6
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.c
@@ -0,0 +1,580 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 * This file provides interfaces to V4L2 subsystem.
4 *
5 * This module registers with V4L2 subsystem as Radio
6 * data system interface (/dev/radio). During the registration,
7 * it will expose two set of function pointers.
8 *
9 * 1) File operation related API (open, close, read, write, poll...etc).
10 * 2) Set of V4L2 IOCTL complaint API.
11 *
12 * Copyright (C) 2011 Texas Instruments
13 * Author: Raja Mani <raja_mani@ti.com>
14 * Author: Manjunatha Halli <manjunatha_halli@ti.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 *
29 */
30
31#include "fmdrv.h"
32#include "fmdrv_v4l2.h"
33#include "fmdrv_common.h"
34#include "fmdrv_rx.h"
35#include "fmdrv_tx.h"
36
37static struct video_device *gradio_dev;
38static u8 radio_disconnected;
39
40/* -- V4L2 RADIO (/dev/radioX) device file operation interfaces --- */
41
42/* Read RX RDS data */
43static ssize_t fm_v4l2_fops_read(struct file *file, char __user * buf,
44 size_t count, loff_t *ppos)
45{
46 u8 rds_mode;
47 int ret;
48 struct fmdev *fmdev;
49
50 fmdev = video_drvdata(file);
51
52 if (!radio_disconnected) {
53 fmerr("FM device is already disconnected\n");
54 return -EIO;
55 }
56
57 /* Turn on RDS mode , if it is disabled */
58 ret = fm_rx_get_rds_mode(fmdev, &rds_mode);
59 if (ret < 0) {
60 fmerr("Unable to read current rds mode\n");
61 return ret;
62 }
63
64 if (rds_mode == FM_RDS_DISABLE) {
65 ret = fmc_set_rds_mode(fmdev, FM_RDS_ENABLE);
66 if (ret < 0) {
67 fmerr("Failed to enable rds mode\n");
68 return ret;
69 }
70 }
71
72 /* Copy RDS data from internal buffer to user buffer */
73 return fmc_transfer_rds_from_internal_buff(fmdev, file, buf, count);
74}
75
76/* Write TX RDS data */
77static ssize_t fm_v4l2_fops_write(struct file *file, const char __user * buf,
78 size_t count, loff_t *ppos)
79{
80 struct tx_rds rds;
81 int ret;
82 struct fmdev *fmdev;
83
84 ret = copy_from_user(&rds, buf, sizeof(rds));
85 fmdbg("(%d)type: %d, text %s, af %d\n",
86 ret, rds.text_type, rds.text, rds.af_freq);
87
88 fmdev = video_drvdata(file);
89 fm_tx_set_radio_text(fmdev, rds.text, rds.text_type);
90 fm_tx_set_af(fmdev, rds.af_freq);
91
92 return 0;
93}
94
95static u32 fm_v4l2_fops_poll(struct file *file, struct poll_table_struct *pts)
96{
97 int ret;
98 struct fmdev *fmdev;
99
100 fmdev = video_drvdata(file);
101 ret = fmc_is_rds_data_available(fmdev, file, pts);
102 if (ret < 0)
103 return POLLIN | POLLRDNORM;
104
105 return 0;
106}
107
108/*
109 * Handle open request for "/dev/radioX" device.
110 * Start with FM RX mode as default.
111 */
112static int fm_v4l2_fops_open(struct file *file)
113{
114 int ret;
115 struct fmdev *fmdev = NULL;
116
117 /* Don't allow multiple open */
118 if (radio_disconnected) {
119 fmerr("FM device is already opened\n");
120 return -EBUSY;
121 }
122
123 fmdev = video_drvdata(file);
124
125 ret = fmc_prepare(fmdev);
126 if (ret < 0) {
127 fmerr("Unable to prepare FM CORE\n");
128 return ret;
129 }
130
131 fmdbg("Load FM RX firmware..\n");
132
133 ret = fmc_set_mode(fmdev, FM_MODE_RX);
134 if (ret < 0) {
135 fmerr("Unable to load FM RX firmware\n");
136 return ret;
137 }
138 radio_disconnected = 1;
139
140 return ret;
141}
142
143static int fm_v4l2_fops_release(struct file *file)
144{
145 int ret;
146 struct fmdev *fmdev;
147
148 fmdev = video_drvdata(file);
149 if (!radio_disconnected) {
150 fmdbg("FM device is already closed\n");
151 return 0;
152 }
153
154 ret = fmc_set_mode(fmdev, FM_MODE_OFF);
155 if (ret < 0) {
156 fmerr("Unable to turn off the chip\n");
157 return ret;
158 }
159
160 ret = fmc_release(fmdev);
161 if (ret < 0) {
162 fmerr("FM CORE release failed\n");
163 return ret;
164 }
165 radio_disconnected = 0;
166
167 return ret;
168}
169
170/* V4L2 RADIO (/dev/radioX) device IOCTL interfaces */
171static int fm_v4l2_vidioc_querycap(struct file *file, void *priv,
172 struct v4l2_capability *capability)
173{
174 strlcpy(capability->driver, FM_DRV_NAME, sizeof(capability->driver));
175 strlcpy(capability->card, FM_DRV_CARD_SHORT_NAME,
176 sizeof(capability->card));
177 sprintf(capability->bus_info, "UART");
178 capability->version = FM_DRV_RADIO_VERSION;
179 capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER |
180 V4L2_CAP_RADIO | V4L2_CAP_MODULATOR |
181 V4L2_CAP_AUDIO | V4L2_CAP_READWRITE |
182 V4L2_CAP_RDS_CAPTURE;
183
184 return 0;
185}
186
187static int fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
188{
189 struct fmdev *fmdev = container_of(ctrl->handler,
190 struct fmdev, ctrl_handler);
191
192 switch (ctrl->id) {
193 case V4L2_CID_TUNE_ANTENNA_CAPACITOR:
194 ctrl->val = fm_tx_get_tune_cap_val(fmdev);
195 break;
196 default:
197 fmwarn("%s: Unknown IOCTL: %d\n", __func__, ctrl->id);
198 break;
199 }
200
201 return 0;
202}
203
204static int fm_v4l2_s_ctrl(struct v4l2_ctrl *ctrl)
205{
206 struct fmdev *fmdev = container_of(ctrl->handler,
207 struct fmdev, ctrl_handler);
208
209 switch (ctrl->id) {
210 case V4L2_CID_AUDIO_VOLUME: /* set volume */
211 return fm_rx_set_volume(fmdev, (u16)ctrl->val);
212
213 case V4L2_CID_AUDIO_MUTE: /* set mute */
214 return fmc_set_mute_mode(fmdev, (u8)ctrl->val);
215
216 case V4L2_CID_TUNE_POWER_LEVEL:
217 /* set TX power level - ext control */
218 return fm_tx_set_pwr_lvl(fmdev, (u8)ctrl->val);
219
220 case V4L2_CID_TUNE_PREEMPHASIS:
221 return fm_tx_set_preemph_filter(fmdev, (u8) ctrl->val);
222
223 default:
224 return -EINVAL;
225 }
226}
227
228static int fm_v4l2_vidioc_g_audio(struct file *file, void *priv,
229 struct v4l2_audio *audio)
230{
231 memset(audio, 0, sizeof(*audio));
232 strcpy(audio->name, "Radio");
233 audio->capability = V4L2_AUDCAP_STEREO;
234
235 return 0;
236}
237
238static int fm_v4l2_vidioc_s_audio(struct file *file, void *priv,
239 struct v4l2_audio *audio)
240{
241 if (audio->index != 0)
242 return -EINVAL;
243
244 return 0;
245}
246
247/* Get tuner attributes. If current mode is NOT RX, return error */
248static int fm_v4l2_vidioc_g_tuner(struct file *file, void *priv,
249 struct v4l2_tuner *tuner)
250{
251 struct fmdev *fmdev = video_drvdata(file);
252 u32 bottom_freq;
253 u32 top_freq;
254 u16 stereo_mono_mode;
255 u16 rssilvl;
256 int ret;
257
258 if (tuner->index != 0)
259 return -EINVAL;
260
261 if (fmdev->curr_fmmode != FM_MODE_RX)
262 return -EPERM;
263
264 ret = fm_rx_get_band_freq_range(fmdev, &bottom_freq, &top_freq);
265 if (ret != 0)
266 return ret;
267
268 ret = fm_rx_get_stereo_mono(fmdev, &stereo_mono_mode);
269 if (ret != 0)
270 return ret;
271
272 ret = fm_rx_get_rssi_level(fmdev, &rssilvl);
273 if (ret != 0)
274 return ret;
275
276 strcpy(tuner->name, "FM");
277 tuner->type = V4L2_TUNER_RADIO;
278 /* Store rangelow and rangehigh freq in unit of 62.5 Hz */
279 tuner->rangelow = bottom_freq * 16;
280 tuner->rangehigh = top_freq * 16;
281 tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO |
282 ((fmdev->rx.rds.flag == FM_RDS_ENABLE) ? V4L2_TUNER_SUB_RDS : 0);
283 tuner->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
284 V4L2_TUNER_CAP_LOW;
285 tuner->audmode = (stereo_mono_mode ?
286 V4L2_TUNER_MODE_MONO : V4L2_TUNER_MODE_STEREO);
287
288 /*
289 * Actual rssi value lies in between -128 to +127.
290 * Convert this range from 0 to 255 by adding +128
291 */
292 rssilvl += 128;
293
294 /*
295 * Return signal strength value should be within 0 to 65535.
296 * Find out correct signal radio by multiplying (65535/255) = 257
297 */
298 tuner->signal = rssilvl * 257;
299 tuner->afc = 0;
300
301 return ret;
302}
303
304/*
305 * Set tuner attributes. If current mode is NOT RX, set to RX.
306 * Currently, we set only audio mode (mono/stereo) and RDS state (on/off).
307 * Should we set other tuner attributes, too?
308 */
309static int fm_v4l2_vidioc_s_tuner(struct file *file, void *priv,
310 struct v4l2_tuner *tuner)
311{
312 struct fmdev *fmdev = video_drvdata(file);
313 u16 aud_mode;
314 u8 rds_mode;
315 int ret;
316
317 if (tuner->index != 0)
318 return -EINVAL;
319
320 aud_mode = (tuner->audmode == V4L2_TUNER_MODE_STEREO) ?
321 FM_STEREO_MODE : FM_MONO_MODE;
322 rds_mode = (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) ?
323 FM_RDS_ENABLE : FM_RDS_DISABLE;
324
325 if (fmdev->curr_fmmode != FM_MODE_RX) {
326 ret = fmc_set_mode(fmdev, FM_MODE_RX);
327 if (ret < 0) {
328 fmerr("Failed to set RX mode\n");
329 return ret;
330 }
331 }
332
333 ret = fmc_set_stereo_mono(fmdev, aud_mode);
334 if (ret < 0) {
335 fmerr("Failed to set RX stereo/mono mode\n");
336 return ret;
337 }
338
339 ret = fmc_set_rds_mode(fmdev, rds_mode);
340 if (ret < 0)
341 fmerr("Failed to set RX RDS mode\n");
342
343 return ret;
344}
345
346/* Get tuner or modulator radio frequency */
347static int fm_v4l2_vidioc_g_freq(struct file *file, void *priv,
348 struct v4l2_frequency *freq)
349{
350 struct fmdev *fmdev = video_drvdata(file);
351 int ret;
352
353 ret = fmc_get_freq(fmdev, &freq->frequency);
354 if (ret < 0) {
355 fmerr("Failed to get frequency\n");
356 return ret;
357 }
358
359 /* Frequency unit of 62.5 Hz*/
360 freq->frequency = (u32) freq->frequency * 16;
361
362 return 0;
363}
364
365/* Set tuner or modulator radio frequency */
366static int fm_v4l2_vidioc_s_freq(struct file *file, void *priv,
367 struct v4l2_frequency *freq)
368{
369 struct fmdev *fmdev = video_drvdata(file);
370
371 /*
372 * As V4L2_TUNER_CAP_LOW is set 1 user sends the frequency
373 * in units of 62.5 Hz.
374 */
375 freq->frequency = (u32)(freq->frequency / 16);
376
377 return fmc_set_freq(fmdev, freq->frequency);
378}
379
380/* Set hardware frequency seek. If current mode is NOT RX, set it RX. */
381static int fm_v4l2_vidioc_s_hw_freq_seek(struct file *file, void *priv,
382 struct v4l2_hw_freq_seek *seek)
383{
384 struct fmdev *fmdev = video_drvdata(file);
385 int ret;
386
387 if (fmdev->curr_fmmode != FM_MODE_RX) {
388 ret = fmc_set_mode(fmdev, FM_MODE_RX);
389 if (ret != 0) {
390 fmerr("Failed to set RX mode\n");
391 return ret;
392 }
393 }
394
395 ret = fm_rx_seek(fmdev, seek->seek_upward, seek->wrap_around,
396 seek->spacing);
397 if (ret < 0)
398 fmerr("RX seek failed - %d\n", ret);
399
400 return ret;
401}
402/* Get modulator attributes. If mode is not TX, return no attributes. */
403static int fm_v4l2_vidioc_g_modulator(struct file *file, void *priv,
404 struct v4l2_modulator *mod)
405{
406 struct fmdev *fmdev = video_drvdata(file);;
407
408 if (mod->index != 0)
409 return -EINVAL;
410
411 if (fmdev->curr_fmmode != FM_MODE_TX)
412 return -EPERM;
413
414 mod->txsubchans = ((fmdev->tx_data.aud_mode == FM_STEREO_MODE) ?
415 V4L2_TUNER_SUB_STEREO : V4L2_TUNER_SUB_MONO) |
416 ((fmdev->tx_data.rds.flag == FM_RDS_ENABLE) ?
417 V4L2_TUNER_SUB_RDS : 0);
418
419 mod->capability = V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS |
420 V4L2_TUNER_CAP_LOW;
421
422 return 0;
423}
424
425/* Set modulator attributes. If mode is not TX, set to TX. */
426static int fm_v4l2_vidioc_s_modulator(struct file *file, void *priv,
427 struct v4l2_modulator *mod)
428{
429 struct fmdev *fmdev = video_drvdata(file);
430 u8 rds_mode;
431 u16 aud_mode;
432 int ret;
433
434 if (mod->index != 0)
435 return -EINVAL;
436
437 if (fmdev->curr_fmmode != FM_MODE_TX) {
438 ret = fmc_set_mode(fmdev, FM_MODE_TX);
439 if (ret != 0) {
440 fmerr("Failed to set TX mode\n");
441 return ret;
442 }
443 }
444
445 aud_mode = (mod->txsubchans & V4L2_TUNER_SUB_STEREO) ?
446 FM_STEREO_MODE : FM_MONO_MODE;
447 rds_mode = (mod->txsubchans & V4L2_TUNER_SUB_RDS) ?
448 FM_RDS_ENABLE : FM_RDS_DISABLE;
449 ret = fm_tx_set_stereo_mono(fmdev, aud_mode);
450 if (ret < 0) {
451 fmerr("Failed to set mono/stereo mode for TX\n");
452 return ret;
453 }
454 ret = fm_tx_set_rds_mode(fmdev, rds_mode);
455 if (ret < 0)
456 fmerr("Failed to set rds mode for TX\n");
457
458 return ret;
459}
460
461static const struct v4l2_file_operations fm_drv_fops = {
462 .owner = THIS_MODULE,
463 .read = fm_v4l2_fops_read,
464 .write = fm_v4l2_fops_write,
465 .poll = fm_v4l2_fops_poll,
466 .unlocked_ioctl = video_ioctl2,
467 .open = fm_v4l2_fops_open,
468 .release = fm_v4l2_fops_release,
469};
470
471static const struct v4l2_ctrl_ops fm_ctrl_ops = {
472 .s_ctrl = fm_v4l2_s_ctrl,
473 .g_volatile_ctrl = fm_g_volatile_ctrl,
474};
475static const struct v4l2_ioctl_ops fm_drv_ioctl_ops = {
476 .vidioc_querycap = fm_v4l2_vidioc_querycap,
477 .vidioc_g_audio = fm_v4l2_vidioc_g_audio,
478 .vidioc_s_audio = fm_v4l2_vidioc_s_audio,
479 .vidioc_g_tuner = fm_v4l2_vidioc_g_tuner,
480 .vidioc_s_tuner = fm_v4l2_vidioc_s_tuner,
481 .vidioc_g_frequency = fm_v4l2_vidioc_g_freq,
482 .vidioc_s_frequency = fm_v4l2_vidioc_s_freq,
483 .vidioc_s_hw_freq_seek = fm_v4l2_vidioc_s_hw_freq_seek,
484 .vidioc_g_modulator = fm_v4l2_vidioc_g_modulator,
485 .vidioc_s_modulator = fm_v4l2_vidioc_s_modulator
486};
487
488/* V4L2 RADIO device parent structure */
489static struct video_device fm_viddev_template = {
490 .fops = &fm_drv_fops,
491 .ioctl_ops = &fm_drv_ioctl_ops,
492 .name = FM_DRV_NAME,
493 .release = video_device_release,
494};
495
496int fm_v4l2_init_video_device(struct fmdev *fmdev, int radio_nr)
497{
498 struct v4l2_ctrl *ctrl;
499 int ret;
500
501 /* Init mutex for core locking */
502 mutex_init(&fmdev->mutex);
503
504 /* Allocate new video device */
505 gradio_dev = video_device_alloc();
506 if (NULL == gradio_dev) {
507 fmerr("Can't allocate video device\n");
508 return -ENOMEM;
509 }
510
511 /* Setup FM driver's V4L2 properties */
512 memcpy(gradio_dev, &fm_viddev_template, sizeof(fm_viddev_template));
513
514 video_set_drvdata(gradio_dev, fmdev);
515
516 gradio_dev->lock = &fmdev->mutex;
517
518 /* Register with V4L2 subsystem as RADIO device */
519 if (video_register_device(gradio_dev, VFL_TYPE_RADIO, radio_nr)) {
520 video_device_release(gradio_dev);
521 fmerr("Could not register video device\n");
522 return -ENOMEM;
523 }
524
525 fmdev->radio_dev = gradio_dev;
526
527 /* Register to v4l2 ctrl handler framework */
528 fmdev->radio_dev->ctrl_handler = &fmdev->ctrl_handler;
529
530 ret = v4l2_ctrl_handler_init(&fmdev->ctrl_handler, 5);
531 if (ret < 0) {
532 fmerr("(fmdev): Can't init ctrl handler\n");
533 v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
534 return -EBUSY;
535 }
536
537 /*
538 * Following controls are handled by V4L2 control framework.
539 * Added in ascending ID order.
540 */
541 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
542 V4L2_CID_AUDIO_VOLUME, FM_RX_VOLUME_MIN,
543 FM_RX_VOLUME_MAX, 1, FM_RX_VOLUME_MAX);
544
545 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
546 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1);
547
548 v4l2_ctrl_new_std_menu(&fmdev->ctrl_handler, &fm_ctrl_ops,
549 V4L2_CID_TUNE_PREEMPHASIS, V4L2_PREEMPHASIS_75_uS,
550 0, V4L2_PREEMPHASIS_75_uS);
551
552 v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
553 V4L2_CID_TUNE_POWER_LEVEL, FM_PWR_LVL_LOW,
554 FM_PWR_LVL_HIGH, 1, FM_PWR_LVL_HIGH);
555
556 ctrl = v4l2_ctrl_new_std(&fmdev->ctrl_handler, &fm_ctrl_ops,
557 V4L2_CID_TUNE_ANTENNA_CAPACITOR, 0,
558 255, 1, 255);
559
560 if (ctrl)
561 ctrl->is_volatile = 1;
562
563 return 0;
564}
565
566void *fm_v4l2_deinit_video_device(void)
567{
568 struct fmdev *fmdev;
569
570
571 fmdev = video_get_drvdata(gradio_dev);
572
573 /* Unregister to v4l2 ctrl handler framework*/
574 v4l2_ctrl_handler_free(&fmdev->ctrl_handler);
575
576 /* Unregister RADIO device from V4L2 subsystem */
577 video_unregister_device(gradio_dev);
578
579 return fmdev;
580}
diff --git a/drivers/media/radio/wl128x/fmdrv_v4l2.h b/drivers/media/radio/wl128x/fmdrv_v4l2.h
new file mode 100644
index 000000000000..0ba79d745e2f
--- /dev/null
+++ b/drivers/media/radio/wl128x/fmdrv_v4l2.h
@@ -0,0 +1,33 @@
1/*
2 * FM Driver for Connectivity chip of Texas Instruments.
3 *
4 * FM V4L2 module header.
5 *
6 * Copyright (C) 2011 Texas Instruments
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 version 2 as
10 * published by the Free Software Foundation.
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#ifndef _FMDRV_V4L2_H
24#define _FMDRV_V4L2_H
25
26#include <media/v4l2-ioctl.h>
27#include <media/v4l2-common.h>
28#include <media/v4l2-ctrls.h>
29
30int fm_v4l2_init_video_device(struct fmdev *, int);
31void *fm_v4l2_deinit_video_device(void);
32
33#endif
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig
index 3785162f928e..7f03142a329f 100644
--- a/drivers/media/rc/Kconfig
+++ b/drivers/media/rc/Kconfig
@@ -135,6 +135,19 @@ config IR_MCEUSB
135 To compile this driver as a module, choose M here: the 135 To compile this driver as a module, choose M here: the
136 module will be called mceusb. 136 module will be called mceusb.
137 137
138config IR_ITE_CIR
139 tristate "ITE Tech Inc. IT8712/IT8512 Consumer Infrared Transceiver"
140 depends on PNP
141 depends on RC_CORE
142 ---help---
143 Say Y here to enable support for integrated infrared receivers
144 /transceivers made by ITE Tech Inc. These are found in
145 several ASUS devices, like the ASUS Digimatrix or the ASUS
146 EEEBox 1501U.
147
148 To compile this driver as a module, choose M here: the
149 module will be called ite-cir.
150
138config IR_NUVOTON 151config IR_NUVOTON
139 tristate "Nuvoton w836x7hg Consumer Infrared Transceiver" 152 tristate "Nuvoton w836x7hg Consumer Infrared Transceiver"
140 depends on PNP 153 depends on PNP
@@ -161,20 +174,20 @@ config IR_STREAMZAP
161 module will be called streamzap. 174 module will be called streamzap.
162 175
163config IR_WINBOND_CIR 176config IR_WINBOND_CIR
164 tristate "Winbond IR remote control" 177 tristate "Winbond IR remote control"
165 depends on X86 && PNP 178 depends on X86 && PNP
166 depends on RC_CORE 179 depends on RC_CORE
167 select NEW_LEDS 180 select NEW_LEDS
168 select LEDS_CLASS 181 select LEDS_CLASS
169 select LEDS_TRIGGERS 182 select LEDS_TRIGGERS
170 select BITREVERSE 183 select BITREVERSE
171 ---help--- 184 ---help---
172 Say Y here if you want to use the IR remote functionality found 185 Say Y here if you want to use the IR remote functionality found
173 in some Winbond SuperI/O chips. Currently only the WPCD376I 186 in some Winbond SuperI/O chips. Currently only the WPCD376I
174 chip is supported (included in some Intel Media series 187 chip is supported (included in some Intel Media series
175 motherboards). 188 motherboards).
176 189
177 To compile this driver as a module, choose M here: the module will 190 To compile this driver as a module, choose M here: the module will
178 be called winbond_cir. 191 be called winbond_cir.
179 192
180config RC_LOOPBACK 193config RC_LOOPBACK
diff --git a/drivers/media/rc/Makefile b/drivers/media/rc/Makefile
index 67b4f7fe2577..c6cfe70d862f 100644
--- a/drivers/media/rc/Makefile
+++ b/drivers/media/rc/Makefile
@@ -14,6 +14,7 @@ obj-$(CONFIG_IR_LIRC_CODEC) += ir-lirc-codec.o
14 14
15# stand-alone IR receivers/transmitters 15# stand-alone IR receivers/transmitters
16obj-$(CONFIG_IR_IMON) += imon.o 16obj-$(CONFIG_IR_IMON) += imon.o
17obj-$(CONFIG_IR_ITE_CIR) += ite-cir.o
17obj-$(CONFIG_IR_MCEUSB) += mceusb.o 18obj-$(CONFIG_IR_MCEUSB) += mceusb.o
18obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o 19obj-$(CONFIG_IR_NUVOTON) += nuvoton-cir.o
19obj-$(CONFIG_IR_ENE) += ene_ir.o 20obj-$(CONFIG_IR_ENE) += ene_ir.o
diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c
index e7dc6b46fdfa..f714e1a22c92 100644
--- a/drivers/media/rc/imon.c
+++ b/drivers/media/rc/imon.c
@@ -277,12 +277,21 @@ static const struct {
277 u64 hw_code; 277 u64 hw_code;
278 u32 keycode; 278 u32 keycode;
279} imon_panel_key_table[] = { 279} imon_panel_key_table[] = {
280 { 0x000000000f00ffeell, KEY_PROG1 }, /* Go */ 280 { 0x000000000f00ffeell, KEY_MEDIA }, /* Go */
281 { 0x000000001200ffeell, KEY_UP },
282 { 0x000000001300ffeell, KEY_DOWN },
283 { 0x000000001400ffeell, KEY_LEFT },
284 { 0x000000001500ffeell, KEY_RIGHT },
285 { 0x000000001600ffeell, KEY_ENTER },
286 { 0x000000001700ffeell, KEY_ESC },
281 { 0x000000001f00ffeell, KEY_AUDIO }, 287 { 0x000000001f00ffeell, KEY_AUDIO },
282 { 0x000000002000ffeell, KEY_VIDEO }, 288 { 0x000000002000ffeell, KEY_VIDEO },
283 { 0x000000002100ffeell, KEY_CAMERA }, 289 { 0x000000002100ffeell, KEY_CAMERA },
284 { 0x000000002700ffeell, KEY_DVD }, 290 { 0x000000002700ffeell, KEY_DVD },
285 { 0x000000002300ffeell, KEY_TV }, 291 { 0x000000002300ffeell, KEY_TV },
292 { 0x000000002b00ffeell, KEY_EXIT },
293 { 0x000000002c00ffeell, KEY_SELECT },
294 { 0x000000002d00ffeell, KEY_MENU },
286 { 0x000000000500ffeell, KEY_PREVIOUS }, 295 { 0x000000000500ffeell, KEY_PREVIOUS },
287 { 0x000000000700ffeell, KEY_REWIND }, 296 { 0x000000000700ffeell, KEY_REWIND },
288 { 0x000000000400ffeell, KEY_STOP }, 297 { 0x000000000400ffeell, KEY_STOP },
diff --git a/drivers/media/rc/ir-nec-decoder.c b/drivers/media/rc/ir-nec-decoder.c
index 7b58b4a1729b..63ee722dbd02 100644
--- a/drivers/media/rc/ir-nec-decoder.c
+++ b/drivers/media/rc/ir-nec-decoder.c
@@ -49,6 +49,7 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
49 struct nec_dec *data = &dev->raw->nec; 49 struct nec_dec *data = &dev->raw->nec;
50 u32 scancode; 50 u32 scancode;
51 u8 address, not_address, command, not_command; 51 u8 address, not_address, command, not_command;
52 bool send_32bits = false;
52 53
53 if (!(dev->raw->enabled_protocols & RC_TYPE_NEC)) 54 if (!(dev->raw->enabled_protocols & RC_TYPE_NEC))
54 return 0; 55 return 0;
@@ -164,10 +165,15 @@ static int ir_nec_decode(struct rc_dev *dev, struct ir_raw_event ev)
164 if ((command ^ not_command) != 0xff) { 165 if ((command ^ not_command) != 0xff) {
165 IR_dprintk(1, "NEC checksum error: received 0x%08x\n", 166 IR_dprintk(1, "NEC checksum error: received 0x%08x\n",
166 data->bits); 167 data->bits);
167 break; 168 send_32bits = true;
168 } 169 }
169 170
170 if ((address ^ not_address) != 0xff) { 171 if (send_32bits) {
172 /* NEC transport, but modified protocol, used by at
173 * least Apple and TiVo remotes */
174 scancode = data->bits;
175 IR_dprintk(1, "NEC (modified) scancode 0x%08x\n", scancode);
176 } else if ((address ^ not_address) != 0xff) {
171 /* Extended NEC */ 177 /* Extended NEC */
172 scancode = address << 16 | 178 scancode = address << 16 |
173 not_address << 8 | 179 not_address << 8 |
diff --git a/drivers/media/rc/ite-cir.c b/drivers/media/rc/ite-cir.c
new file mode 100644
index 000000000000..9be6a830f1d2
--- /dev/null
+++ b/drivers/media/rc/ite-cir.c
@@ -0,0 +1,1736 @@
1/*
2 * Driver for ITE Tech Inc. IT8712F/IT8512 CIR
3 *
4 * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@gmail.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; 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 GNU
14 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA.
20 *
21 * Inspired by the original lirc_it87 and lirc_ite8709 drivers, on top of the
22 * skeleton provided by the nuvoton-cir driver.
23 *
24 * The lirc_it87 driver was originally written by Hans-Gunter Lutke Uphues
25 * <hg_lu@web.de> in 2001, with enhancements by Christoph Bartelmus
26 * <lirc@bartelmus.de>, Andrew Calkin <r_tay@hotmail.com> and James Edwards
27 * <jimbo-lirc@edwardsclan.net>.
28 *
29 * The lirc_ite8709 driver was written by Grégory Lardière
30 * <spmf2004-lirc@yahoo.fr> in 2008.
31 */
32
33#include <linux/kernel.h>
34#include <linux/module.h>
35#include <linux/pnp.h>
36#include <linux/io.h>
37#include <linux/interrupt.h>
38#include <linux/sched.h>
39#include <linux/slab.h>
40#include <linux/input.h>
41#include <linux/bitops.h>
42#include <media/rc-core.h>
43#include <linux/pci_ids.h>
44
45#include "ite-cir.h"
46
47/* module parameters */
48
49/* debug level */
50static int debug;
51module_param(debug, int, S_IRUGO | S_IWUSR);
52MODULE_PARM_DESC(debug, "Enable debugging output");
53
54/* low limit for RX carrier freq, Hz, 0 for no RX demodulation */
55static int rx_low_carrier_freq;
56module_param(rx_low_carrier_freq, int, S_IRUGO | S_IWUSR);
57MODULE_PARM_DESC(rx_low_carrier_freq, "Override low RX carrier frequency, Hz, "
58 "0 for no RX demodulation");
59
60/* high limit for RX carrier freq, Hz, 0 for no RX demodulation */
61static int rx_high_carrier_freq;
62module_param(rx_high_carrier_freq, int, S_IRUGO | S_IWUSR);
63MODULE_PARM_DESC(rx_high_carrier_freq, "Override high RX carrier frequency, "
64 "Hz, 0 for no RX demodulation");
65
66/* override tx carrier frequency */
67static int tx_carrier_freq;
68module_param(tx_carrier_freq, int, S_IRUGO | S_IWUSR);
69MODULE_PARM_DESC(tx_carrier_freq, "Override TX carrier frequency, Hz");
70
71/* override tx duty cycle */
72static int tx_duty_cycle;
73module_param(tx_duty_cycle, int, S_IRUGO | S_IWUSR);
74MODULE_PARM_DESC(tx_duty_cycle, "Override TX duty cycle, 1-100");
75
76/* override default sample period */
77static long sample_period;
78module_param(sample_period, long, S_IRUGO | S_IWUSR);
79MODULE_PARM_DESC(sample_period, "Override carrier sample period, us");
80
81/* override detected model id */
82static int model_number = -1;
83module_param(model_number, int, S_IRUGO | S_IWUSR);
84MODULE_PARM_DESC(model_number, "Use this model number, don't autodetect");
85
86
87/* HW-independent code functions */
88
89/* check whether carrier frequency is high frequency */
90static inline bool ite_is_high_carrier_freq(unsigned int freq)
91{
92 return freq >= ITE_HCF_MIN_CARRIER_FREQ;
93}
94
95/* get the bits required to program the carrier frequency in CFQ bits,
96 * unshifted */
97static u8 ite_get_carrier_freq_bits(unsigned int freq)
98{
99 if (ite_is_high_carrier_freq(freq)) {
100 if (freq < 425000)
101 return ITE_CFQ_400;
102
103 else if (freq < 465000)
104 return ITE_CFQ_450;
105
106 else if (freq < 490000)
107 return ITE_CFQ_480;
108
109 else
110 return ITE_CFQ_500;
111 } else {
112 /* trim to limits */
113 if (freq < ITE_LCF_MIN_CARRIER_FREQ)
114 freq = ITE_LCF_MIN_CARRIER_FREQ;
115 if (freq > ITE_LCF_MAX_CARRIER_FREQ)
116 freq = ITE_LCF_MAX_CARRIER_FREQ;
117
118 /* convert to kHz and subtract the base freq */
119 freq =
120 DIV_ROUND_CLOSEST(freq - ITE_LCF_MIN_CARRIER_FREQ,
121 1000);
122
123 return (u8) freq;
124 }
125}
126
127/* get the bits required to program the pulse with in TXMPW */
128static u8 ite_get_pulse_width_bits(unsigned int freq, int duty_cycle)
129{
130 unsigned long period_ns, on_ns;
131
132 /* sanitize freq into range */
133 if (freq < ITE_LCF_MIN_CARRIER_FREQ)
134 freq = ITE_LCF_MIN_CARRIER_FREQ;
135 if (freq > ITE_HCF_MAX_CARRIER_FREQ)
136 freq = ITE_HCF_MAX_CARRIER_FREQ;
137
138 period_ns = 1000000000UL / freq;
139 on_ns = period_ns * duty_cycle / 100;
140
141 if (ite_is_high_carrier_freq(freq)) {
142 if (on_ns < 750)
143 return ITE_TXMPW_A;
144
145 else if (on_ns < 850)
146 return ITE_TXMPW_B;
147
148 else if (on_ns < 950)
149 return ITE_TXMPW_C;
150
151 else if (on_ns < 1080)
152 return ITE_TXMPW_D;
153
154 else
155 return ITE_TXMPW_E;
156 } else {
157 if (on_ns < 6500)
158 return ITE_TXMPW_A;
159
160 else if (on_ns < 7850)
161 return ITE_TXMPW_B;
162
163 else if (on_ns < 9650)
164 return ITE_TXMPW_C;
165
166 else if (on_ns < 11950)
167 return ITE_TXMPW_D;
168
169 else
170 return ITE_TXMPW_E;
171 }
172}
173
174/* decode raw bytes as received by the hardware, and push them to the ir-core
175 * layer */
176static void ite_decode_bytes(struct ite_dev *dev, const u8 * data, int
177 length)
178{
179 u32 sample_period;
180 unsigned long *ldata;
181 unsigned int next_one, next_zero, size;
182 DEFINE_IR_RAW_EVENT(ev);
183
184 if (length == 0)
185 return;
186
187 sample_period = dev->params.sample_period;
188 ldata = (unsigned long *)data;
189 size = length << 3;
190 next_one = generic_find_next_le_bit(ldata, size, 0);
191 if (next_one > 0) {
192 ev.pulse = true;
193 ev.duration =
194 ITE_BITS_TO_NS(next_one, sample_period);
195 ir_raw_event_store_with_filter(dev->rdev, &ev);
196 }
197
198 while (next_one < size) {
199 next_zero = generic_find_next_zero_le_bit(ldata, size, next_one + 1);
200 ev.pulse = false;
201 ev.duration = ITE_BITS_TO_NS(next_zero - next_one, sample_period);
202 ir_raw_event_store_with_filter(dev->rdev, &ev);
203
204 if (next_zero < size) {
205 next_one =
206 generic_find_next_le_bit(ldata,
207 size,
208 next_zero + 1);
209 ev.pulse = true;
210 ev.duration =
211 ITE_BITS_TO_NS(next_one - next_zero,
212 sample_period);
213 ir_raw_event_store_with_filter
214 (dev->rdev, &ev);
215 } else
216 next_one = size;
217 }
218
219 ir_raw_event_handle(dev->rdev);
220
221 ite_dbg_verbose("decoded %d bytes.", length);
222}
223
224/* set all the rx/tx carrier parameters; this must be called with the device
225 * spinlock held */
226static void ite_set_carrier_params(struct ite_dev *dev)
227{
228 unsigned int freq, low_freq, high_freq;
229 int allowance;
230 bool use_demodulator;
231 bool for_tx = dev->transmitting;
232
233 ite_dbg("%s called", __func__);
234
235 if (for_tx) {
236 /* we don't need no stinking calculations */
237 freq = dev->params.tx_carrier_freq;
238 allowance = ITE_RXDCR_DEFAULT;
239 use_demodulator = false;
240 } else {
241 low_freq = dev->params.rx_low_carrier_freq;
242 high_freq = dev->params.rx_high_carrier_freq;
243
244 if (low_freq == 0) {
245 /* don't demodulate */
246 freq =
247 ITE_DEFAULT_CARRIER_FREQ;
248 allowance = ITE_RXDCR_DEFAULT;
249 use_demodulator = false;
250 } else {
251 /* calculate the middle freq */
252 freq = (low_freq + high_freq) / 2;
253
254 /* calculate the allowance */
255 allowance =
256 DIV_ROUND_CLOSEST(10000 * (high_freq - low_freq),
257 ITE_RXDCR_PER_10000_STEP
258 * (high_freq + low_freq));
259
260 if (allowance < 1)
261 allowance = 1;
262
263 if (allowance > ITE_RXDCR_MAX)
264 allowance = ITE_RXDCR_MAX;
265 }
266 }
267
268 /* set the carrier parameters in a device-dependent way */
269 dev->params.set_carrier_params(dev, ite_is_high_carrier_freq(freq),
270 use_demodulator, ite_get_carrier_freq_bits(freq), allowance,
271 ite_get_pulse_width_bits(freq, dev->params.tx_duty_cycle));
272}
273
274/* interrupt service routine for incoming and outgoing CIR data */
275static irqreturn_t ite_cir_isr(int irq, void *data)
276{
277 struct ite_dev *dev = data;
278 unsigned long flags;
279 irqreturn_t ret = IRQ_RETVAL(IRQ_NONE);
280 u8 rx_buf[ITE_RX_FIFO_LEN];
281 int rx_bytes;
282 int iflags;
283
284 ite_dbg_verbose("%s firing", __func__);
285
286 /* grab the spinlock */
287 spin_lock_irqsave(&dev->lock, flags);
288
289 /* read the interrupt flags */
290 iflags = dev->params.get_irq_causes(dev);
291
292 /* check for the receive interrupt */
293 if (iflags & (ITE_IRQ_RX_FIFO | ITE_IRQ_RX_FIFO_OVERRUN)) {
294 /* read the FIFO bytes */
295 rx_bytes =
296 dev->params.get_rx_bytes(dev, rx_buf,
297 ITE_RX_FIFO_LEN);
298
299 if (rx_bytes > 0) {
300 /* drop the spinlock, since the ir-core layer
301 * may call us back again through
302 * ite_s_idle() */
303 spin_unlock_irqrestore(&dev->
304 lock,
305 flags);
306
307 /* decode the data we've just received */
308 ite_decode_bytes(dev, rx_buf,
309 rx_bytes);
310
311 /* reacquire the spinlock */
312 spin_lock_irqsave(&dev->lock,
313 flags);
314
315 /* mark the interrupt as serviced */
316 ret = IRQ_RETVAL(IRQ_HANDLED);
317 }
318 } else if (iflags & ITE_IRQ_TX_FIFO) {
319 /* FIFO space available interrupt */
320 ite_dbg_verbose("got interrupt for TX FIFO");
321
322 /* wake any sleeping transmitter */
323 wake_up_interruptible(&dev->tx_queue);
324
325 /* mark the interrupt as serviced */
326 ret = IRQ_RETVAL(IRQ_HANDLED);
327 }
328
329 /* drop the spinlock */
330 spin_unlock_irqrestore(&dev->lock, flags);
331
332 ite_dbg_verbose("%s done returning %d", __func__, (int)ret);
333
334 return ret;
335}
336
337/* set the rx carrier freq range, guess it's in Hz... */
338static int ite_set_rx_carrier_range(struct rc_dev *rcdev, u32 carrier_low, u32
339 carrier_high)
340{
341 unsigned long flags;
342 struct ite_dev *dev = rcdev->priv;
343
344 spin_lock_irqsave(&dev->lock, flags);
345 dev->params.rx_low_carrier_freq = carrier_low;
346 dev->params.rx_high_carrier_freq = carrier_high;
347 ite_set_carrier_params(dev);
348 spin_unlock_irqrestore(&dev->lock, flags);
349
350 return 0;
351}
352
353/* set the tx carrier freq, guess it's in Hz... */
354static int ite_set_tx_carrier(struct rc_dev *rcdev, u32 carrier)
355{
356 unsigned long flags;
357 struct ite_dev *dev = rcdev->priv;
358
359 spin_lock_irqsave(&dev->lock, flags);
360 dev->params.tx_carrier_freq = carrier;
361 ite_set_carrier_params(dev);
362 spin_unlock_irqrestore(&dev->lock, flags);
363
364 return 0;
365}
366
367/* set the tx duty cycle by controlling the pulse width */
368static int ite_set_tx_duty_cycle(struct rc_dev *rcdev, u32 duty_cycle)
369{
370 unsigned long flags;
371 struct ite_dev *dev = rcdev->priv;
372
373 spin_lock_irqsave(&dev->lock, flags);
374 dev->params.tx_duty_cycle = duty_cycle;
375 ite_set_carrier_params(dev);
376 spin_unlock_irqrestore(&dev->lock, flags);
377
378 return 0;
379}
380
381/* transmit out IR pulses; what you get here is a batch of alternating
382 * pulse/space/pulse/space lengths that we should write out completely through
383 * the FIFO, blocking on a full FIFO */
384static int ite_tx_ir(struct rc_dev *rcdev, int *txbuf, u32 n)
385{
386 unsigned long flags;
387 struct ite_dev *dev = rcdev->priv;
388 bool is_pulse = false;
389 int remaining_us, fifo_avail, fifo_remaining, last_idx = 0;
390 int max_rle_us, next_rle_us;
391 int ret = n;
392 u8 last_sent[ITE_TX_FIFO_LEN];
393 u8 val;
394
395 ite_dbg("%s called", __func__);
396
397 /* clear the array just in case */
398 memset(last_sent, 0, ARRAY_SIZE(last_sent));
399
400 /* n comes in bytes; convert to ints */
401 n /= sizeof(int);
402
403 spin_lock_irqsave(&dev->lock, flags);
404
405 /* let everybody know we're now transmitting */
406 dev->transmitting = true;
407
408 /* and set the carrier values for transmission */
409 ite_set_carrier_params(dev);
410
411 /* calculate how much time we can send in one byte */
412 max_rle_us =
413 (ITE_BAUDRATE_DIVISOR * dev->params.sample_period *
414 ITE_TX_MAX_RLE) / 1000;
415
416 /* disable the receiver */
417 dev->params.disable_rx(dev);
418
419 /* this is where we'll begin filling in the FIFO, until it's full.
420 * then we'll just activate the interrupt, wait for it to wake us up
421 * again, disable it, continue filling the FIFO... until everything
422 * has been pushed out */
423 fifo_avail =
424 ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);
425
426 while (n > 0 && dev->in_use) {
427 /* transmit the next sample */
428 is_pulse = !is_pulse;
429 remaining_us = *(txbuf++);
430 n--;
431
432 ite_dbg("%s: %ld",
433 ((is_pulse) ? "pulse" : "space"),
434 (long int)
435 remaining_us);
436
437 /* repeat while the pulse is non-zero length */
438 while (remaining_us > 0 && dev->in_use) {
439 if (remaining_us > max_rle_us)
440 next_rle_us = max_rle_us;
441
442 else
443 next_rle_us = remaining_us;
444
445 remaining_us -= next_rle_us;
446
447 /* check what's the length we have to pump out */
448 val = (ITE_TX_MAX_RLE * next_rle_us) / max_rle_us;
449
450 /* put it into the sent buffer */
451 last_sent[last_idx++] = val;
452 last_idx &= (ITE_TX_FIFO_LEN);
453
454 /* encode it for 7 bits */
455 val = (val - 1) & ITE_TX_RLE_MASK;
456
457 /* take into account pulse/space prefix */
458 if (is_pulse)
459 val |= ITE_TX_PULSE;
460
461 else
462 val |= ITE_TX_SPACE;
463
464 /*
465 * if we get to 0 available, read again, just in case
466 * some other slot got freed
467 */
468 if (fifo_avail <= 0)
469 fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev);
470
471 /* if it's still full */
472 if (fifo_avail <= 0) {
473 /* enable the tx interrupt */
474 dev->params.
475 enable_tx_interrupt(dev);
476
477 /* drop the spinlock */
478 spin_unlock_irqrestore(&dev->lock, flags);
479
480 /* wait for the FIFO to empty enough */
481 wait_event_interruptible(dev->tx_queue, (fifo_avail = ITE_TX_FIFO_LEN - dev->params.get_tx_used_slots(dev)) >= 8);
482
483 /* get the spinlock again */
484 spin_lock_irqsave(&dev->lock, flags);
485
486 /* disable the tx interrupt again. */
487 dev->params.
488 disable_tx_interrupt(dev);
489 }
490
491 /* now send the byte through the FIFO */
492 dev->params.put_tx_byte(dev, val);
493 fifo_avail--;
494 }
495 }
496
497 /* wait and don't return until the whole FIFO has been sent out;
498 * otherwise we could configure the RX carrier params instead of the
499 * TX ones while the transmission is still being performed! */
500 fifo_remaining = dev->params.get_tx_used_slots(dev);
501 remaining_us = 0;
502 while (fifo_remaining > 0) {
503 fifo_remaining--;
504 last_idx--;
505 last_idx &= (ITE_TX_FIFO_LEN - 1);
506 remaining_us += last_sent[last_idx];
507 }
508 remaining_us = (remaining_us * max_rle_us) / (ITE_TX_MAX_RLE);
509
510 /* drop the spinlock while we sleep */
511 spin_unlock_irqrestore(&dev->lock, flags);
512
513 /* sleep remaining_us microseconds */
514 mdelay(DIV_ROUND_UP(remaining_us, 1000));
515
516 /* reacquire the spinlock */
517 spin_lock_irqsave(&dev->lock, flags);
518
519 /* now we're not transmitting anymore */
520 dev->transmitting = false;
521
522 /* and set the carrier values for reception */
523 ite_set_carrier_params(dev);
524
525 /* reenable the receiver */
526 if (dev->in_use)
527 dev->params.enable_rx(dev);
528
529 /* notify transmission end */
530 wake_up_interruptible(&dev->tx_ended);
531
532 spin_unlock_irqrestore(&dev->lock, flags);
533
534 return ret;
535}
536
537/* idle the receiver if needed */
538static void ite_s_idle(struct rc_dev *rcdev, bool enable)
539{
540 unsigned long flags;
541 struct ite_dev *dev = rcdev->priv;
542
543 ite_dbg("%s called", __func__);
544
545 if (enable) {
546 spin_lock_irqsave(&dev->lock, flags);
547 dev->params.idle_rx(dev);
548 spin_unlock_irqrestore(&dev->lock, flags);
549 }
550}
551
552
553/* IT8712F HW-specific functions */
554
555/* retrieve a bitmask of the current causes for a pending interrupt; this may
556 * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
557 * */
558static int it87_get_irq_causes(struct ite_dev *dev)
559{
560 u8 iflags;
561 int ret = 0;
562
563 ite_dbg("%s called", __func__);
564
565 /* read the interrupt flags */
566 iflags = inb(dev->cir_addr + IT87_IIR) & IT87_II;
567
568 switch (iflags) {
569 case IT87_II_RXDS:
570 ret = ITE_IRQ_RX_FIFO;
571 break;
572 case IT87_II_RXFO:
573 ret = ITE_IRQ_RX_FIFO_OVERRUN;
574 break;
575 case IT87_II_TXLDL:
576 ret = ITE_IRQ_TX_FIFO;
577 break;
578 }
579
580 return ret;
581}
582
583/* set the carrier parameters; to be called with the spinlock held */
584static void it87_set_carrier_params(struct ite_dev *dev, bool high_freq,
585 bool use_demodulator,
586 u8 carrier_freq_bits, u8 allowance_bits,
587 u8 pulse_width_bits)
588{
589 u8 val;
590
591 ite_dbg("%s called", __func__);
592
593 /* program the RCR register */
594 val = inb(dev->cir_addr + IT87_RCR)
595 & ~(IT87_HCFS | IT87_RXEND | IT87_RXDCR);
596
597 if (high_freq)
598 val |= IT87_HCFS;
599
600 if (use_demodulator)
601 val |= IT87_RXEND;
602
603 val |= allowance_bits;
604
605 outb(val, dev->cir_addr + IT87_RCR);
606
607 /* program the TCR2 register */
608 outb((carrier_freq_bits << IT87_CFQ_SHIFT) | pulse_width_bits,
609 dev->cir_addr + IT87_TCR2);
610}
611
612/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
613 * held */
614static int it87_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
615{
616 int fifo, read = 0;
617
618 ite_dbg("%s called", __func__);
619
620 /* read how many bytes are still in the FIFO */
621 fifo = inb(dev->cir_addr + IT87_RSR) & IT87_RXFBC;
622
623 while (fifo > 0 && buf_size > 0) {
624 *(buf++) = inb(dev->cir_addr + IT87_DR);
625 fifo--;
626 read++;
627 buf_size--;
628 }
629
630 return read;
631}
632
633/* return how many bytes are still in the FIFO; this will be called
634 * with the device spinlock NOT HELD while waiting for the TX FIFO to get
635 * empty; let's expect this won't be a problem */
636static int it87_get_tx_used_slots(struct ite_dev *dev)
637{
638 ite_dbg("%s called", __func__);
639
640 return inb(dev->cir_addr + IT87_TSR) & IT87_TXFBC;
641}
642
643/* put a byte to the TX fifo; this should be called with the spinlock held */
644static void it87_put_tx_byte(struct ite_dev *dev, u8 value)
645{
646 outb(value, dev->cir_addr + IT87_DR);
647}
648
649/* idle the receiver so that we won't receive samples until another
650 pulse is detected; this must be called with the device spinlock held */
651static void it87_idle_rx(struct ite_dev *dev)
652{
653 ite_dbg("%s called", __func__);
654
655 /* disable streaming by clearing RXACT writing it as 1 */
656 outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXACT,
657 dev->cir_addr + IT87_RCR);
658
659 /* clear the FIFO */
660 outb(inb(dev->cir_addr + IT87_TCR1) | IT87_FIFOCLR,
661 dev->cir_addr + IT87_TCR1);
662}
663
664/* disable the receiver; this must be called with the device spinlock held */
665static void it87_disable_rx(struct ite_dev *dev)
666{
667 ite_dbg("%s called", __func__);
668
669 /* disable the receiver interrupts */
670 outb(inb(dev->cir_addr + IT87_IER) & ~(IT87_RDAIE | IT87_RFOIE),
671 dev->cir_addr + IT87_IER);
672
673 /* disable the receiver */
674 outb(inb(dev->cir_addr + IT87_RCR) & ~IT87_RXEN,
675 dev->cir_addr + IT87_RCR);
676
677 /* clear the FIFO and RXACT (actually RXACT should have been cleared
678 * in the previous outb() call) */
679 it87_idle_rx(dev);
680}
681
682/* enable the receiver; this must be called with the device spinlock held */
683static void it87_enable_rx(struct ite_dev *dev)
684{
685 ite_dbg("%s called", __func__);
686
687 /* enable the receiver by setting RXEN */
688 outb(inb(dev->cir_addr + IT87_RCR) | IT87_RXEN,
689 dev->cir_addr + IT87_RCR);
690
691 /* just prepare it to idle for the next reception */
692 it87_idle_rx(dev);
693
694 /* enable the receiver interrupts and master enable flag */
695 outb(inb(dev->cir_addr + IT87_IER) | IT87_RDAIE | IT87_RFOIE | IT87_IEC,
696 dev->cir_addr + IT87_IER);
697}
698
699/* disable the transmitter interrupt; this must be called with the device
700 * spinlock held */
701static void it87_disable_tx_interrupt(struct ite_dev *dev)
702{
703 ite_dbg("%s called", __func__);
704
705 /* disable the transmitter interrupts */
706 outb(inb(dev->cir_addr + IT87_IER) & ~IT87_TLDLIE,
707 dev->cir_addr + IT87_IER);
708}
709
710/* enable the transmitter interrupt; this must be called with the device
711 * spinlock held */
712static void it87_enable_tx_interrupt(struct ite_dev *dev)
713{
714 ite_dbg("%s called", __func__);
715
716 /* enable the transmitter interrupts and master enable flag */
717 outb(inb(dev->cir_addr + IT87_IER) | IT87_TLDLIE | IT87_IEC,
718 dev->cir_addr + IT87_IER);
719}
720
721/* disable the device; this must be called with the device spinlock held */
722static void it87_disable(struct ite_dev *dev)
723{
724 ite_dbg("%s called", __func__);
725
726 /* clear out all interrupt enable flags */
727 outb(inb(dev->cir_addr + IT87_IER) &
728 ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE),
729 dev->cir_addr + IT87_IER);
730
731 /* disable the receiver */
732 it87_disable_rx(dev);
733
734 /* erase the FIFO */
735 outb(IT87_FIFOCLR | inb(dev->cir_addr + IT87_TCR1),
736 dev->cir_addr + IT87_TCR1);
737}
738
739/* initialize the hardware */
740static void it87_init_hardware(struct ite_dev *dev)
741{
742 ite_dbg("%s called", __func__);
743
744 /* enable just the baud rate divisor register,
745 disabling all the interrupts at the same time */
746 outb((inb(dev->cir_addr + IT87_IER) &
747 ~(IT87_IEC | IT87_RFOIE | IT87_RDAIE | IT87_TLDLIE)) | IT87_BR,
748 dev->cir_addr + IT87_IER);
749
750 /* write out the baud rate divisor */
751 outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT87_BDLR);
752 outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff, dev->cir_addr + IT87_BDHR);
753
754 /* disable the baud rate divisor register again */
755 outb(inb(dev->cir_addr + IT87_IER) & ~IT87_BR,
756 dev->cir_addr + IT87_IER);
757
758 /* program the RCR register defaults */
759 outb(ITE_RXDCR_DEFAULT, dev->cir_addr + IT87_RCR);
760
761 /* program the TCR1 register */
762 outb(IT87_TXMPM_DEFAULT | IT87_TXENDF | IT87_TXRLE
763 | IT87_FIFOTL_DEFAULT | IT87_FIFOCLR,
764 dev->cir_addr + IT87_TCR1);
765
766 /* program the carrier parameters */
767 ite_set_carrier_params(dev);
768}
769
770/* IT8512F on ITE8708 HW-specific functions */
771
772/* retrieve a bitmask of the current causes for a pending interrupt; this may
773 * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
774 * */
775static int it8708_get_irq_causes(struct ite_dev *dev)
776{
777 u8 iflags;
778 int ret = 0;
779
780 ite_dbg("%s called", __func__);
781
782 /* read the interrupt flags */
783 iflags = inb(dev->cir_addr + IT8708_C0IIR);
784
785 if (iflags & IT85_TLDLI)
786 ret |= ITE_IRQ_TX_FIFO;
787 if (iflags & IT85_RDAI)
788 ret |= ITE_IRQ_RX_FIFO;
789 if (iflags & IT85_RFOI)
790 ret |= ITE_IRQ_RX_FIFO_OVERRUN;
791
792 return ret;
793}
794
795/* set the carrier parameters; to be called with the spinlock held */
796static void it8708_set_carrier_params(struct ite_dev *dev, bool high_freq,
797 bool use_demodulator,
798 u8 carrier_freq_bits, u8 allowance_bits,
799 u8 pulse_width_bits)
800{
801 u8 val;
802
803 ite_dbg("%s called", __func__);
804
805 /* program the C0CFR register, with HRAE=1 */
806 outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
807 dev->cir_addr + IT8708_BANKSEL);
808
809 val = (inb(dev->cir_addr + IT8708_C0CFR)
810 & ~(IT85_HCFS | IT85_CFQ)) | carrier_freq_bits;
811
812 if (high_freq)
813 val |= IT85_HCFS;
814
815 outb(val, dev->cir_addr + IT8708_C0CFR);
816
817 outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
818 dev->cir_addr + IT8708_BANKSEL);
819
820 /* program the C0RCR register */
821 val = inb(dev->cir_addr + IT8708_C0RCR)
822 & ~(IT85_RXEND | IT85_RXDCR);
823
824 if (use_demodulator)
825 val |= IT85_RXEND;
826
827 val |= allowance_bits;
828
829 outb(val, dev->cir_addr + IT8708_C0RCR);
830
831 /* program the C0TCR register */
832 val = inb(dev->cir_addr + IT8708_C0TCR) & ~IT85_TXMPW;
833 val |= pulse_width_bits;
834 outb(val, dev->cir_addr + IT8708_C0TCR);
835}
836
837/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
838 * held */
839static int it8708_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
840{
841 int fifo, read = 0;
842
843 ite_dbg("%s called", __func__);
844
845 /* read how many bytes are still in the FIFO */
846 fifo = inb(dev->cir_addr + IT8708_C0RFSR) & IT85_RXFBC;
847
848 while (fifo > 0 && buf_size > 0) {
849 *(buf++) = inb(dev->cir_addr + IT8708_C0DR);
850 fifo--;
851 read++;
852 buf_size--;
853 }
854
855 return read;
856}
857
858/* return how many bytes are still in the FIFO; this will be called
859 * with the device spinlock NOT HELD while waiting for the TX FIFO to get
860 * empty; let's expect this won't be a problem */
861static int it8708_get_tx_used_slots(struct ite_dev *dev)
862{
863 ite_dbg("%s called", __func__);
864
865 return inb(dev->cir_addr + IT8708_C0TFSR) & IT85_TXFBC;
866}
867
868/* put a byte to the TX fifo; this should be called with the spinlock held */
869static void it8708_put_tx_byte(struct ite_dev *dev, u8 value)
870{
871 outb(value, dev->cir_addr + IT8708_C0DR);
872}
873
874/* idle the receiver so that we won't receive samples until another
875 pulse is detected; this must be called with the device spinlock held */
876static void it8708_idle_rx(struct ite_dev *dev)
877{
878 ite_dbg("%s called", __func__);
879
880 /* disable streaming by clearing RXACT writing it as 1 */
881 outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXACT,
882 dev->cir_addr + IT8708_C0RCR);
883
884 /* clear the FIFO */
885 outb(inb(dev->cir_addr + IT8708_C0MSTCR) | IT85_FIFOCLR,
886 dev->cir_addr + IT8708_C0MSTCR);
887}
888
889/* disable the receiver; this must be called with the device spinlock held */
890static void it8708_disable_rx(struct ite_dev *dev)
891{
892 ite_dbg("%s called", __func__);
893
894 /* disable the receiver interrupts */
895 outb(inb(dev->cir_addr + IT8708_C0IER) &
896 ~(IT85_RDAIE | IT85_RFOIE),
897 dev->cir_addr + IT8708_C0IER);
898
899 /* disable the receiver */
900 outb(inb(dev->cir_addr + IT8708_C0RCR) & ~IT85_RXEN,
901 dev->cir_addr + IT8708_C0RCR);
902
903 /* clear the FIFO and RXACT (actually RXACT should have been cleared
904 * in the previous outb() call) */
905 it8708_idle_rx(dev);
906}
907
908/* enable the receiver; this must be called with the device spinlock held */
909static void it8708_enable_rx(struct ite_dev *dev)
910{
911 ite_dbg("%s called", __func__);
912
913 /* enable the receiver by setting RXEN */
914 outb(inb(dev->cir_addr + IT8708_C0RCR) | IT85_RXEN,
915 dev->cir_addr + IT8708_C0RCR);
916
917 /* just prepare it to idle for the next reception */
918 it8708_idle_rx(dev);
919
920 /* enable the receiver interrupts and master enable flag */
921 outb(inb(dev->cir_addr + IT8708_C0IER)
922 |IT85_RDAIE | IT85_RFOIE | IT85_IEC,
923 dev->cir_addr + IT8708_C0IER);
924}
925
926/* disable the transmitter interrupt; this must be called with the device
927 * spinlock held */
928static void it8708_disable_tx_interrupt(struct ite_dev *dev)
929{
930 ite_dbg("%s called", __func__);
931
932 /* disable the transmitter interrupts */
933 outb(inb(dev->cir_addr + IT8708_C0IER) & ~IT85_TLDLIE,
934 dev->cir_addr + IT8708_C0IER);
935}
936
937/* enable the transmitter interrupt; this must be called with the device
938 * spinlock held */
939static void it8708_enable_tx_interrupt(struct ite_dev *dev)
940{
941 ite_dbg("%s called", __func__);
942
943 /* enable the transmitter interrupts and master enable flag */
944 outb(inb(dev->cir_addr + IT8708_C0IER)
945 |IT85_TLDLIE | IT85_IEC,
946 dev->cir_addr + IT8708_C0IER);
947}
948
949/* disable the device; this must be called with the device spinlock held */
950static void it8708_disable(struct ite_dev *dev)
951{
952 ite_dbg("%s called", __func__);
953
954 /* clear out all interrupt enable flags */
955 outb(inb(dev->cir_addr + IT8708_C0IER) &
956 ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
957 dev->cir_addr + IT8708_C0IER);
958
959 /* disable the receiver */
960 it8708_disable_rx(dev);
961
962 /* erase the FIFO */
963 outb(IT85_FIFOCLR | inb(dev->cir_addr + IT8708_C0MSTCR),
964 dev->cir_addr + IT8708_C0MSTCR);
965}
966
967/* initialize the hardware */
968static void it8708_init_hardware(struct ite_dev *dev)
969{
970 ite_dbg("%s called", __func__);
971
972 /* disable all the interrupts */
973 outb(inb(dev->cir_addr + IT8708_C0IER) &
974 ~(IT85_IEC | IT85_RFOIE | IT85_RDAIE | IT85_TLDLIE),
975 dev->cir_addr + IT8708_C0IER);
976
977 /* program the baud rate divisor */
978 outb(inb(dev->cir_addr + IT8708_BANKSEL) | IT8708_HRAE,
979 dev->cir_addr + IT8708_BANKSEL);
980
981 outb(ITE_BAUDRATE_DIVISOR & 0xff, dev->cir_addr + IT8708_C0BDLR);
982 outb((ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
983 dev->cir_addr + IT8708_C0BDHR);
984
985 outb(inb(dev->cir_addr + IT8708_BANKSEL) & ~IT8708_HRAE,
986 dev->cir_addr + IT8708_BANKSEL);
987
988 /* program the C0MSTCR register defaults */
989 outb((inb(dev->cir_addr + IT8708_C0MSTCR) &
990 ~(IT85_ILSEL | IT85_ILE | IT85_FIFOTL |
991 IT85_FIFOCLR | IT85_RESET)) |
992 IT85_FIFOTL_DEFAULT,
993 dev->cir_addr + IT8708_C0MSTCR);
994
995 /* program the C0RCR register defaults */
996 outb((inb(dev->cir_addr + IT8708_C0RCR) &
997 ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND |
998 IT85_RXACT | IT85_RXDCR)) |
999 ITE_RXDCR_DEFAULT,
1000 dev->cir_addr + IT8708_C0RCR);
1001
1002 /* program the C0TCR register defaults */
1003 outb((inb(dev->cir_addr + IT8708_C0TCR) &
1004 ~(IT85_TXMPM | IT85_TXMPW))
1005 |IT85_TXRLE | IT85_TXENDF |
1006 IT85_TXMPM_DEFAULT | IT85_TXMPW_DEFAULT,
1007 dev->cir_addr + IT8708_C0TCR);
1008
1009 /* program the carrier parameters */
1010 ite_set_carrier_params(dev);
1011}
1012
1013/* IT8512F on ITE8709 HW-specific functions */
1014
1015/* read a byte from the SRAM module */
1016static inline u8 it8709_rm(struct ite_dev *dev, int index)
1017{
1018 outb(index, dev->cir_addr + IT8709_RAM_IDX);
1019 return inb(dev->cir_addr + IT8709_RAM_VAL);
1020}
1021
1022/* write a byte to the SRAM module */
1023static inline void it8709_wm(struct ite_dev *dev, u8 val, int index)
1024{
1025 outb(index, dev->cir_addr + IT8709_RAM_IDX);
1026 outb(val, dev->cir_addr + IT8709_RAM_VAL);
1027}
1028
1029static void it8709_wait(struct ite_dev *dev)
1030{
1031 int i = 0;
1032 /*
1033 * loop until device tells it's ready to continue
1034 * iterations count is usually ~750 but can sometimes achieve 13000
1035 */
1036 for (i = 0; i < 15000; i++) {
1037 udelay(2);
1038 if (it8709_rm(dev, IT8709_MODE) == IT8709_IDLE)
1039 break;
1040 }
1041}
1042
1043/* read the value of a CIR register */
1044static u8 it8709_rr(struct ite_dev *dev, int index)
1045{
1046 /* just wait in case the previous access was a write */
1047 it8709_wait(dev);
1048 it8709_wm(dev, index, IT8709_REG_IDX);
1049 it8709_wm(dev, IT8709_READ, IT8709_MODE);
1050
1051 /* wait for the read data to be available */
1052 it8709_wait(dev);
1053
1054 /* return the read value */
1055 return it8709_rm(dev, IT8709_REG_VAL);
1056}
1057
1058/* write the value of a CIR register */
1059static void it8709_wr(struct ite_dev *dev, u8 val, int index)
1060{
1061 /* we wait before writing, and not afterwards, since this allows us to
1062 * pipeline the host CPU with the microcontroller */
1063 it8709_wait(dev);
1064 it8709_wm(dev, val, IT8709_REG_VAL);
1065 it8709_wm(dev, index, IT8709_REG_IDX);
1066 it8709_wm(dev, IT8709_WRITE, IT8709_MODE);
1067}
1068
1069/* retrieve a bitmask of the current causes for a pending interrupt; this may
1070 * be composed of ITE_IRQ_TX_FIFO, ITE_IRQ_RX_FIFO and ITE_IRQ_RX_FIFO_OVERRUN
1071 * */
1072static int it8709_get_irq_causes(struct ite_dev *dev)
1073{
1074 u8 iflags;
1075 int ret = 0;
1076
1077 ite_dbg("%s called", __func__);
1078
1079 /* read the interrupt flags */
1080 iflags = it8709_rm(dev, IT8709_IIR);
1081
1082 if (iflags & IT85_TLDLI)
1083 ret |= ITE_IRQ_TX_FIFO;
1084 if (iflags & IT85_RDAI)
1085 ret |= ITE_IRQ_RX_FIFO;
1086 if (iflags & IT85_RFOI)
1087 ret |= ITE_IRQ_RX_FIFO_OVERRUN;
1088
1089 return ret;
1090}
1091
1092/* set the carrier parameters; to be called with the spinlock held */
1093static void it8709_set_carrier_params(struct ite_dev *dev, bool high_freq,
1094 bool use_demodulator,
1095 u8 carrier_freq_bits, u8 allowance_bits,
1096 u8 pulse_width_bits)
1097{
1098 u8 val;
1099
1100 ite_dbg("%s called", __func__);
1101
1102 val = (it8709_rr(dev, IT85_C0CFR)
1103 &~(IT85_HCFS | IT85_CFQ)) |
1104 carrier_freq_bits;
1105
1106 if (high_freq)
1107 val |= IT85_HCFS;
1108
1109 it8709_wr(dev, val, IT85_C0CFR);
1110
1111 /* program the C0RCR register */
1112 val = it8709_rr(dev, IT85_C0RCR)
1113 & ~(IT85_RXEND | IT85_RXDCR);
1114
1115 if (use_demodulator)
1116 val |= IT85_RXEND;
1117
1118 val |= allowance_bits;
1119
1120 it8709_wr(dev, val, IT85_C0RCR);
1121
1122 /* program the C0TCR register */
1123 val = it8709_rr(dev, IT85_C0TCR) & ~IT85_TXMPW;
1124 val |= pulse_width_bits;
1125 it8709_wr(dev, val, IT85_C0TCR);
1126}
1127
1128/* read up to buf_size bytes from the RX FIFO; to be called with the spinlock
1129 * held */
1130static int it8709_get_rx_bytes(struct ite_dev *dev, u8 * buf, int buf_size)
1131{
1132 int fifo, read = 0;
1133
1134 ite_dbg("%s called", __func__);
1135
1136 /* read how many bytes are still in the FIFO */
1137 fifo = it8709_rm(dev, IT8709_RFSR) & IT85_RXFBC;
1138
1139 while (fifo > 0 && buf_size > 0) {
1140 *(buf++) = it8709_rm(dev, IT8709_FIFO + read);
1141 fifo--;
1142 read++;
1143 buf_size--;
1144 }
1145
1146 /* 'clear' the FIFO by setting the writing index to 0; this is
1147 * completely bound to be racy, but we can't help it, since it's a
1148 * limitation of the protocol */
1149 it8709_wm(dev, 0, IT8709_RFSR);
1150
1151 return read;
1152}
1153
1154/* return how many bytes are still in the FIFO; this will be called
1155 * with the device spinlock NOT HELD while waiting for the TX FIFO to get
1156 * empty; let's expect this won't be a problem */
1157static int it8709_get_tx_used_slots(struct ite_dev *dev)
1158{
1159 ite_dbg("%s called", __func__);
1160
1161 return it8709_rr(dev, IT85_C0TFSR) & IT85_TXFBC;
1162}
1163
1164/* put a byte to the TX fifo; this should be called with the spinlock held */
1165static void it8709_put_tx_byte(struct ite_dev *dev, u8 value)
1166{
1167 it8709_wr(dev, value, IT85_C0DR);
1168}
1169
1170/* idle the receiver so that we won't receive samples until another
1171 pulse is detected; this must be called with the device spinlock held */
1172static void it8709_idle_rx(struct ite_dev *dev)
1173{
1174 ite_dbg("%s called", __func__);
1175
1176 /* disable streaming by clearing RXACT writing it as 1 */
1177 it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXACT,
1178 IT85_C0RCR);
1179
1180 /* clear the FIFO */
1181 it8709_wr(dev, it8709_rr(dev, IT85_C0MSTCR) | IT85_FIFOCLR,
1182 IT85_C0MSTCR);
1183}
1184
1185/* disable the receiver; this must be called with the device spinlock held */
1186static void it8709_disable_rx(struct ite_dev *dev)
1187{
1188 ite_dbg("%s called", __func__);
1189
1190 /* disable the receiver interrupts */
1191 it8709_wr(dev, it8709_rr(dev, IT85_C0IER) &
1192 ~(IT85_RDAIE | IT85_RFOIE),
1193 IT85_C0IER);
1194
1195 /* disable the receiver */
1196 it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) & ~IT85_RXEN,
1197 IT85_C0RCR);
1198
1199 /* clear the FIFO and RXACT (actually RXACT should have been cleared
1200 * in the previous it8709_wr(dev, ) call) */
1201 it8709_idle_rx(dev);
1202}
1203
1204/* enable the receiver; this must be called with the device spinlock held */
1205static void it8709_enable_rx(struct ite_dev *dev)
1206{
1207 ite_dbg("%s called", __func__);
1208
1209 /* enable the receiver by setting RXEN */
1210 it8709_wr(dev, it8709_rr(dev, IT85_C0RCR) | IT85_RXEN,
1211 IT85_C0RCR);
1212
1213 /* just prepare it to idle for the next reception */
1214 it8709_idle_rx(dev);
1215
1216 /* enable the receiver interrupts and master enable flag */
1217 it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
1218 |IT85_RDAIE | IT85_RFOIE | IT85_IEC,
1219 IT85_C0IER);
1220}
1221
1222/* disable the transmitter interrupt; this must be called with the device
1223 * spinlock held */
1224static void it8709_disable_tx_interrupt(struct ite_dev *dev)
1225{
1226 ite_dbg("%s called", __func__);
1227
1228 /* disable the transmitter interrupts */
1229 it8709_wr(dev, it8709_rr(dev, IT85_C0IER) & ~IT85_TLDLIE,
1230 IT85_C0IER);
1231}
1232
1233/* enable the transmitter interrupt; this must be called with the device
1234 * spinlock held */
1235static void it8709_enable_tx_interrupt(struct ite_dev *dev)
1236{
1237 ite_dbg("%s called", __func__);
1238
1239 /* enable the transmitter interrupts and master enable flag */
1240 it8709_wr(dev, it8709_rr(dev, IT85_C0IER)
1241 |IT85_TLDLIE | IT85_IEC,
1242 IT85_C0IER);
1243}
1244
1245/* disable the device; this must be called with the device spinlock held */
1246static void it8709_disable(struct ite_dev *dev)
1247{
1248 ite_dbg("%s called", __func__);
1249
1250 /* clear out all interrupt enable flags */
1251 it8709_wr(dev,
1252 it8709_rr(dev,
1253 IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
1254 IT85_RDAIE |
1255 IT85_TLDLIE), IT85_C0IER);
1256
1257 /* disable the receiver */
1258 it8709_disable_rx(dev);
1259
1260 /* erase the FIFO */
1261 it8709_wr(dev, IT85_FIFOCLR | it8709_rr(dev, IT85_C0MSTCR),
1262 IT85_C0MSTCR);
1263}
1264
1265/* initialize the hardware */
1266static void it8709_init_hardware(struct ite_dev *dev)
1267{
1268 ite_dbg("%s called", __func__);
1269
1270 /* disable all the interrupts */
1271 it8709_wr(dev,
1272 it8709_rr(dev,
1273 IT85_C0IER) & ~(IT85_IEC | IT85_RFOIE |
1274 IT85_RDAIE |
1275 IT85_TLDLIE), IT85_C0IER);
1276
1277 /* program the baud rate divisor */
1278 it8709_wr(dev, ITE_BAUDRATE_DIVISOR & 0xff, IT85_C0BDLR);
1279 it8709_wr(dev, (ITE_BAUDRATE_DIVISOR >> 8) & 0xff,
1280 IT85_C0BDHR);
1281
1282 /* program the C0MSTCR register defaults */
1283 it8709_wr(dev, (it8709_rr(dev, IT85_C0MSTCR) & ~(IT85_ILSEL |
1284 IT85_ILE
1285 | IT85_FIFOTL
1286 |
1287 IT85_FIFOCLR
1288 |
1289 IT85_RESET))
1290 | IT85_FIFOTL_DEFAULT, IT85_C0MSTCR);
1291
1292 /* program the C0RCR register defaults */
1293 it8709_wr(dev,
1294 (it8709_rr(dev, IT85_C0RCR) &
1295 ~(IT85_RXEN | IT85_RDWOS | IT85_RXEND
1296 | IT85_RXACT | IT85_RXDCR)) |
1297 ITE_RXDCR_DEFAULT, IT85_C0RCR);
1298
1299 /* program the C0TCR register defaults */
1300 it8709_wr(dev, (it8709_rr(dev, IT85_C0TCR)
1301 &~(IT85_TXMPM | IT85_TXMPW))
1302 |IT85_TXRLE | IT85_TXENDF |
1303 IT85_TXMPM_DEFAULT |
1304 IT85_TXMPW_DEFAULT, IT85_C0TCR);
1305
1306 /* program the carrier parameters */
1307 ite_set_carrier_params(dev);
1308}
1309
1310
1311/* generic hardware setup/teardown code */
1312
1313/* activate the device for use */
1314static int ite_open(struct rc_dev *rcdev)
1315{
1316 struct ite_dev *dev = rcdev->priv;
1317 unsigned long flags;
1318
1319 ite_dbg("%s called", __func__);
1320
1321 spin_lock_irqsave(&dev->lock, flags);
1322 dev->in_use = true;
1323
1324 /* enable the receiver */
1325 dev->params.enable_rx(dev);
1326
1327 spin_unlock_irqrestore(&dev->lock, flags);
1328
1329 return 0;
1330}
1331
1332/* deactivate the device for use */
1333static void ite_close(struct rc_dev *rcdev)
1334{
1335 struct ite_dev *dev = rcdev->priv;
1336 unsigned long flags;
1337
1338 ite_dbg("%s called", __func__);
1339
1340 spin_lock_irqsave(&dev->lock, flags);
1341 dev->in_use = false;
1342
1343 /* wait for any transmission to end */
1344 spin_unlock_irqrestore(&dev->lock, flags);
1345 wait_event_interruptible(dev->tx_ended, !dev->transmitting);
1346 spin_lock_irqsave(&dev->lock, flags);
1347
1348 dev->params.disable(dev);
1349
1350 spin_unlock_irqrestore(&dev->lock, flags);
1351}
1352
1353/* supported models and their parameters */
1354static const struct ite_dev_params ite_dev_descs[] = {
1355 { /* 0: ITE8704 */
1356 .model = "ITE8704 CIR transceiver",
1357 .io_region_size = IT87_IOREG_LENGTH,
1358 .hw_tx_capable = true,
1359 .sample_period = (u32) (1000000000ULL / 115200),
1360 .tx_carrier_freq = 38000,
1361 .tx_duty_cycle = 33,
1362 .rx_low_carrier_freq = 0,
1363 .rx_high_carrier_freq = 0,
1364
1365 /* operations */
1366 .get_irq_causes = it87_get_irq_causes,
1367 .enable_rx = it87_enable_rx,
1368 .idle_rx = it87_idle_rx,
1369 .disable_rx = it87_idle_rx,
1370 .get_rx_bytes = it87_get_rx_bytes,
1371 .enable_tx_interrupt = it87_enable_tx_interrupt,
1372 .disable_tx_interrupt = it87_disable_tx_interrupt,
1373 .get_tx_used_slots = it87_get_tx_used_slots,
1374 .put_tx_byte = it87_put_tx_byte,
1375 .disable = it87_disable,
1376 .init_hardware = it87_init_hardware,
1377 .set_carrier_params = it87_set_carrier_params,
1378 },
1379 { /* 1: ITE8713 */
1380 .model = "ITE8713 CIR transceiver",
1381 .io_region_size = IT87_IOREG_LENGTH,
1382 .hw_tx_capable = true,
1383 .sample_period = (u32) (1000000000ULL / 115200),
1384 .tx_carrier_freq = 38000,
1385 .tx_duty_cycle = 33,
1386 .rx_low_carrier_freq = 0,
1387 .rx_high_carrier_freq = 0,
1388
1389 /* operations */
1390 .get_irq_causes = it87_get_irq_causes,
1391 .enable_rx = it87_enable_rx,
1392 .idle_rx = it87_idle_rx,
1393 .disable_rx = it87_idle_rx,
1394 .get_rx_bytes = it87_get_rx_bytes,
1395 .enable_tx_interrupt = it87_enable_tx_interrupt,
1396 .disable_tx_interrupt = it87_disable_tx_interrupt,
1397 .get_tx_used_slots = it87_get_tx_used_slots,
1398 .put_tx_byte = it87_put_tx_byte,
1399 .disable = it87_disable,
1400 .init_hardware = it87_init_hardware,
1401 .set_carrier_params = it87_set_carrier_params,
1402 },
1403 { /* 2: ITE8708 */
1404 .model = "ITE8708 CIR transceiver",
1405 .io_region_size = IT8708_IOREG_LENGTH,
1406 .hw_tx_capable = true,
1407 .sample_period = (u32) (1000000000ULL / 115200),
1408 .tx_carrier_freq = 38000,
1409 .tx_duty_cycle = 33,
1410 .rx_low_carrier_freq = 0,
1411 .rx_high_carrier_freq = 0,
1412
1413 /* operations */
1414 .get_irq_causes = it8708_get_irq_causes,
1415 .enable_rx = it8708_enable_rx,
1416 .idle_rx = it8708_idle_rx,
1417 .disable_rx = it8708_idle_rx,
1418 .get_rx_bytes = it8708_get_rx_bytes,
1419 .enable_tx_interrupt = it8708_enable_tx_interrupt,
1420 .disable_tx_interrupt =
1421 it8708_disable_tx_interrupt,
1422 .get_tx_used_slots = it8708_get_tx_used_slots,
1423 .put_tx_byte = it8708_put_tx_byte,
1424 .disable = it8708_disable,
1425 .init_hardware = it8708_init_hardware,
1426 .set_carrier_params = it8708_set_carrier_params,
1427 },
1428 { /* 3: ITE8709 */
1429 .model = "ITE8709 CIR transceiver",
1430 .io_region_size = IT8709_IOREG_LENGTH,
1431 .hw_tx_capable = true,
1432 .sample_period = (u32) (1000000000ULL / 115200),
1433 .tx_carrier_freq = 38000,
1434 .tx_duty_cycle = 33,
1435 .rx_low_carrier_freq = 0,
1436 .rx_high_carrier_freq = 0,
1437
1438 /* operations */
1439 .get_irq_causes = it8709_get_irq_causes,
1440 .enable_rx = it8709_enable_rx,
1441 .idle_rx = it8709_idle_rx,
1442 .disable_rx = it8709_idle_rx,
1443 .get_rx_bytes = it8709_get_rx_bytes,
1444 .enable_tx_interrupt = it8709_enable_tx_interrupt,
1445 .disable_tx_interrupt =
1446 it8709_disable_tx_interrupt,
1447 .get_tx_used_slots = it8709_get_tx_used_slots,
1448 .put_tx_byte = it8709_put_tx_byte,
1449 .disable = it8709_disable,
1450 .init_hardware = it8709_init_hardware,
1451 .set_carrier_params = it8709_set_carrier_params,
1452 },
1453};
1454
1455static const struct pnp_device_id ite_ids[] = {
1456 {"ITE8704", 0}, /* Default model */
1457 {"ITE8713", 1}, /* CIR found in EEEBox 1501U */
1458 {"ITE8708", 2}, /* Bridged IT8512 */
1459 {"ITE8709", 3}, /* SRAM-Bridged IT8512 */
1460 {"", 0},
1461};
1462
1463/* allocate memory, probe hardware, and initialize everything */
1464static int ite_probe(struct pnp_dev *pdev, const struct pnp_device_id
1465 *dev_id)
1466{
1467 const struct ite_dev_params *dev_desc = NULL;
1468 struct ite_dev *itdev = NULL;
1469 struct rc_dev *rdev = NULL;
1470 int ret = -ENOMEM;
1471 int model_no;
1472
1473 ite_dbg("%s called", __func__);
1474
1475 itdev = kzalloc(sizeof(struct ite_dev), GFP_KERNEL);
1476 if (!itdev)
1477 return ret;
1478
1479 /* input device for IR remote (and tx) */
1480 rdev = rc_allocate_device();
1481 if (!rdev)
1482 goto failure;
1483
1484 ret = -ENODEV;
1485
1486 /* get the model number */
1487 model_no = (int)dev_id->driver_data;
1488 ite_pr(KERN_NOTICE, "Auto-detected model: %s\n",
1489 ite_dev_descs[model_no].model);
1490
1491 if (model_number >= 0 && model_number < ARRAY_SIZE(ite_dev_descs)) {
1492 model_no = model_number;
1493 ite_pr(KERN_NOTICE, "The model has been fixed by a module "
1494 "parameter.");
1495 }
1496
1497 ite_pr(KERN_NOTICE, "Using model: %s\n", ite_dev_descs[model_no].model);
1498
1499 /* get the description for the device */
1500 dev_desc = &ite_dev_descs[model_no];
1501
1502 /* validate pnp resources */
1503 if (!pnp_port_valid(pdev, 0) ||
1504 pnp_port_len(pdev, 0) != dev_desc->io_region_size) {
1505 dev_err(&pdev->dev, "IR PNP Port not valid!\n");
1506 goto failure;
1507 }
1508
1509 if (!pnp_irq_valid(pdev, 0)) {
1510 dev_err(&pdev->dev, "PNP IRQ not valid!\n");
1511 goto failure;
1512 }
1513
1514 /* store resource values */
1515 itdev->cir_addr = pnp_port_start(pdev, 0);
1516 itdev->cir_irq = pnp_irq(pdev, 0);
1517
1518 /* initialize spinlocks */
1519 spin_lock_init(&itdev->lock);
1520
1521 /* initialize raw event */
1522 init_ir_raw_event(&itdev->rawir);
1523
1524 ret = -EBUSY;
1525 /* now claim resources */
1526 if (!request_region(itdev->cir_addr,
1527 dev_desc->io_region_size, ITE_DRIVER_NAME))
1528 goto failure;
1529
1530 if (request_irq(itdev->cir_irq, ite_cir_isr, IRQF_SHARED,
1531 ITE_DRIVER_NAME, (void *)itdev))
1532 goto failure;
1533
1534 /* set driver data into the pnp device */
1535 pnp_set_drvdata(pdev, itdev);
1536 itdev->pdev = pdev;
1537
1538 /* initialize waitqueues for transmission */
1539 init_waitqueue_head(&itdev->tx_queue);
1540 init_waitqueue_head(&itdev->tx_ended);
1541
1542 /* copy model-specific parameters */
1543 itdev->params = *dev_desc;
1544
1545 /* apply any overrides */
1546 if (sample_period > 0)
1547 itdev->params.sample_period = sample_period;
1548
1549 if (tx_carrier_freq > 0)
1550 itdev->params.tx_carrier_freq = tx_carrier_freq;
1551
1552 if (tx_duty_cycle > 0 && tx_duty_cycle <= 100)
1553 itdev->params.tx_duty_cycle = tx_duty_cycle;
1554
1555 if (rx_low_carrier_freq > 0)
1556 itdev->params.rx_low_carrier_freq = rx_low_carrier_freq;
1557
1558 if (rx_high_carrier_freq > 0)
1559 itdev->params.rx_high_carrier_freq = rx_high_carrier_freq;
1560
1561 /* print out parameters */
1562 ite_pr(KERN_NOTICE, "TX-capable: %d\n", (int)
1563 itdev->params.hw_tx_capable);
1564 ite_pr(KERN_NOTICE, "Sample period (ns): %ld\n", (long)
1565 itdev->params.sample_period);
1566 ite_pr(KERN_NOTICE, "TX carrier frequency (Hz): %d\n", (int)
1567 itdev->params.tx_carrier_freq);
1568 ite_pr(KERN_NOTICE, "TX duty cycle (%%): %d\n", (int)
1569 itdev->params.tx_duty_cycle);
1570 ite_pr(KERN_NOTICE, "RX low carrier frequency (Hz): %d\n", (int)
1571 itdev->params.rx_low_carrier_freq);
1572 ite_pr(KERN_NOTICE, "RX high carrier frequency (Hz): %d\n", (int)
1573 itdev->params.rx_high_carrier_freq);
1574
1575 /* set up hardware initial state */
1576 itdev->params.init_hardware(itdev);
1577
1578 /* set up ir-core props */
1579 rdev->priv = itdev;
1580 rdev->driver_type = RC_DRIVER_IR_RAW;
1581 rdev->allowed_protos = RC_TYPE_ALL;
1582 rdev->open = ite_open;
1583 rdev->close = ite_close;
1584 rdev->s_idle = ite_s_idle;
1585 rdev->s_rx_carrier_range = ite_set_rx_carrier_range;
1586 rdev->min_timeout = ITE_MIN_IDLE_TIMEOUT;
1587 rdev->max_timeout = ITE_MAX_IDLE_TIMEOUT;
1588 rdev->timeout = ITE_IDLE_TIMEOUT;
1589 rdev->rx_resolution = ITE_BAUDRATE_DIVISOR *
1590 itdev->params.sample_period;
1591 rdev->tx_resolution = ITE_BAUDRATE_DIVISOR *
1592 itdev->params.sample_period;
1593
1594 /* set up transmitter related values if needed */
1595 if (itdev->params.hw_tx_capable) {
1596 rdev->tx_ir = ite_tx_ir;
1597 rdev->s_tx_carrier = ite_set_tx_carrier;
1598 rdev->s_tx_duty_cycle = ite_set_tx_duty_cycle;
1599 }
1600
1601 rdev->input_name = dev_desc->model;
1602 rdev->input_id.bustype = BUS_HOST;
1603 rdev->input_id.vendor = PCI_VENDOR_ID_ITE;
1604 rdev->input_id.product = 0;
1605 rdev->input_id.version = 0;
1606 rdev->driver_name = ITE_DRIVER_NAME;
1607 rdev->map_name = RC_MAP_RC6_MCE;
1608
1609 ret = rc_register_device(rdev);
1610 if (ret)
1611 goto failure;
1612
1613 itdev->rdev = rdev;
1614 ite_pr(KERN_NOTICE, "driver has been successfully loaded\n");
1615
1616 return 0;
1617
1618failure:
1619 if (itdev->cir_irq)
1620 free_irq(itdev->cir_irq, itdev);
1621
1622 if (itdev->cir_addr)
1623 release_region(itdev->cir_addr, itdev->params.io_region_size);
1624
1625 rc_free_device(rdev);
1626 kfree(itdev);
1627
1628 return ret;
1629}
1630
1631static void __devexit ite_remove(struct pnp_dev *pdev)
1632{
1633 struct ite_dev *dev = pnp_get_drvdata(pdev);
1634 unsigned long flags;
1635
1636 ite_dbg("%s called", __func__);
1637
1638 spin_lock_irqsave(&dev->lock, flags);
1639
1640 /* disable hardware */
1641 dev->params.disable(dev);
1642
1643 spin_unlock_irqrestore(&dev->lock, flags);
1644
1645 /* free resources */
1646 free_irq(dev->cir_irq, dev);
1647 release_region(dev->cir_addr, dev->params.io_region_size);
1648
1649 rc_unregister_device(dev->rdev);
1650
1651 kfree(dev);
1652}
1653
1654static int ite_suspend(struct pnp_dev *pdev, pm_message_t state)
1655{
1656 struct ite_dev *dev = pnp_get_drvdata(pdev);
1657 unsigned long flags;
1658
1659 ite_dbg("%s called", __func__);
1660
1661 spin_lock_irqsave(&dev->lock, flags);
1662
1663 /* disable all interrupts */
1664 dev->params.disable(dev);
1665
1666 spin_unlock_irqrestore(&dev->lock, flags);
1667
1668 return 0;
1669}
1670
1671static int ite_resume(struct pnp_dev *pdev)
1672{
1673 int ret = 0;
1674 struct ite_dev *dev = pnp_get_drvdata(pdev);
1675 unsigned long flags;
1676
1677 ite_dbg("%s called", __func__);
1678
1679 spin_lock_irqsave(&dev->lock, flags);
1680
1681 if (dev->transmitting) {
1682 /* wake up the transmitter */
1683 wake_up_interruptible(&dev->tx_queue);
1684 } else {
1685 /* enable the receiver */
1686 dev->params.enable_rx(dev);
1687 }
1688
1689 spin_unlock_irqrestore(&dev->lock, flags);
1690
1691 return ret;
1692}
1693
1694static void ite_shutdown(struct pnp_dev *pdev)
1695{
1696 struct ite_dev *dev = pnp_get_drvdata(pdev);
1697 unsigned long flags;
1698
1699 ite_dbg("%s called", __func__);
1700
1701 spin_lock_irqsave(&dev->lock, flags);
1702
1703 /* disable all interrupts */
1704 dev->params.disable(dev);
1705
1706 spin_unlock_irqrestore(&dev->lock, flags);
1707}
1708
1709static struct pnp_driver ite_driver = {
1710 .name = ITE_DRIVER_NAME,
1711 .id_table = ite_ids,
1712 .probe = ite_probe,
1713 .remove = __devexit_p(ite_remove),
1714 .suspend = ite_suspend,
1715 .resume = ite_resume,
1716 .shutdown = ite_shutdown,
1717};
1718
1719int ite_init(void)
1720{
1721 return pnp_register_driver(&ite_driver);
1722}
1723
1724void ite_exit(void)
1725{
1726 pnp_unregister_driver(&ite_driver);
1727}
1728
1729MODULE_DEVICE_TABLE(pnp, ite_ids);
1730MODULE_DESCRIPTION("ITE Tech Inc. IT8712F/ITE8512F CIR driver");
1731
1732MODULE_AUTHOR("Juan J. Garcia de Soria <skandalfo@gmail.com>");
1733MODULE_LICENSE("GPL");
1734
1735module_init(ite_init);
1736module_exit(ite_exit);
diff --git a/drivers/media/rc/ite-cir.h b/drivers/media/rc/ite-cir.h
new file mode 100644
index 000000000000..16a19f5fd718
--- /dev/null
+++ b/drivers/media/rc/ite-cir.h
@@ -0,0 +1,481 @@
1/*
2 * Driver for ITE Tech Inc. IT8712F/IT8512F CIR
3 *
4 * Copyright (C) 2010 Juan Jesús García de Soria <skandalfo@gmail.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; 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 GNU
14 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA.
20 */
21
22/* platform driver name to register */
23#define ITE_DRIVER_NAME "ite-cir"
24
25/* logging macros */
26#define ite_pr(level, text, ...) \
27 printk(level KBUILD_MODNAME ": " text, ## __VA_ARGS__)
28#define ite_dbg(text, ...) do { \
29 if (debug) \
30 printk(KERN_DEBUG \
31 KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
32} while (0)
33
34#define ite_dbg_verbose(text, ...) do {\
35 if (debug > 1) \
36 printk(KERN_DEBUG \
37 KBUILD_MODNAME ": " text "\n" , ## __VA_ARGS__); \
38} while (0)
39
40/* FIFO sizes */
41#define ITE_TX_FIFO_LEN 32
42#define ITE_RX_FIFO_LEN 32
43
44/* interrupt types */
45#define ITE_IRQ_TX_FIFO 1
46#define ITE_IRQ_RX_FIFO 2
47#define ITE_IRQ_RX_FIFO_OVERRUN 4
48
49/* forward declaration */
50struct ite_dev;
51
52/* struct for storing the parameters of different recognized devices */
53struct ite_dev_params {
54 /* model of the device */
55 const char *model;
56
57 /* size of the I/O region */
58 int io_region_size;
59
60 /* true if the hardware supports transmission */
61 bool hw_tx_capable;
62
63 /* base sampling period, in ns */
64 u32 sample_period;
65
66 /* rx low carrier frequency, in Hz, 0 means no demodulation */
67 unsigned int rx_low_carrier_freq;
68
69 /* tx high carrier frequency, in Hz, 0 means no demodulation */
70 unsigned int rx_high_carrier_freq;
71
72 /* tx carrier frequency, in Hz */
73 unsigned int tx_carrier_freq;
74
75 /* duty cycle, 0-100 */
76 int tx_duty_cycle;
77
78 /* hw-specific operation function pointers; most of these must be
79 * called while holding the spin lock, except for the TX FIFO length
80 * one */
81 /* get pending interrupt causes */
82 int (*get_irq_causes) (struct ite_dev *dev);
83
84 /* enable rx */
85 void (*enable_rx) (struct ite_dev *dev);
86
87 /* make rx enter the idle state; keep listening for a pulse, but stop
88 * streaming space bytes */
89 void (*idle_rx) (struct ite_dev *dev);
90
91 /* disable rx completely */
92 void (*disable_rx) (struct ite_dev *dev);
93
94 /* read bytes from RX FIFO; return read count */
95 int (*get_rx_bytes) (struct ite_dev *dev, u8 *buf, int buf_size);
96
97 /* enable tx FIFO space available interrupt */
98 void (*enable_tx_interrupt) (struct ite_dev *dev);
99
100 /* disable tx FIFO space available interrupt */
101 void (*disable_tx_interrupt) (struct ite_dev *dev);
102
103 /* get number of full TX FIFO slots */
104 int (*get_tx_used_slots) (struct ite_dev *dev);
105
106 /* put a byte to the TX FIFO */
107 void (*put_tx_byte) (struct ite_dev *dev, u8 value);
108
109 /* disable hardware completely */
110 void (*disable) (struct ite_dev *dev);
111
112 /* initialize the hardware */
113 void (*init_hardware) (struct ite_dev *dev);
114
115 /* set the carrier parameters */
116 void (*set_carrier_params) (struct ite_dev *dev, bool high_freq,
117 bool use_demodulator, u8 carrier_freq_bits,
118 u8 allowance_bits, u8 pulse_width_bits);
119};
120
121/* ITE CIR device structure */
122struct ite_dev {
123 struct pnp_dev *pdev;
124 struct rc_dev *rdev;
125 struct ir_raw_event rawir;
126
127 /* sync data */
128 spinlock_t lock;
129 bool in_use, transmitting;
130
131 /* transmit support */
132 int tx_fifo_allowance;
133 wait_queue_head_t tx_queue, tx_ended;
134
135 /* hardware I/O settings */
136 unsigned long cir_addr;
137 int cir_irq;
138
139 /* overridable copy of model parameters */
140 struct ite_dev_params params;
141};
142
143/* common values for all kinds of hardware */
144
145/* baud rate divisor default */
146#define ITE_BAUDRATE_DIVISOR 1
147
148/* low-speed carrier frequency limits (Hz) */
149#define ITE_LCF_MIN_CARRIER_FREQ 27000
150#define ITE_LCF_MAX_CARRIER_FREQ 58000
151
152/* high-speed carrier frequency limits (Hz) */
153#define ITE_HCF_MIN_CARRIER_FREQ 400000
154#define ITE_HCF_MAX_CARRIER_FREQ 500000
155
156/* default carrier freq for when demodulator is off (Hz) */
157#define ITE_DEFAULT_CARRIER_FREQ 38000
158
159/* default idling timeout in ns (0.2 seconds) */
160#define ITE_IDLE_TIMEOUT 200000000UL
161
162/* limit timeout values */
163#define ITE_MIN_IDLE_TIMEOUT 100000000UL
164#define ITE_MAX_IDLE_TIMEOUT 1000000000UL
165
166/* convert bits to us */
167#define ITE_BITS_TO_NS(bits, sample_period) \
168((u32) ((bits) * ITE_BAUDRATE_DIVISOR * sample_period))
169
170/*
171 * n in RDCR produces a tolerance of +/- n * 6.25% around the center
172 * carrier frequency...
173 *
174 * From two limit frequencies, L (low) and H (high), we can get both the
175 * center frequency F = (L + H) / 2 and the variation from the center
176 * frequency A = (H - L) / (H + L). We can use this in order to honor the
177 * s_rx_carrier_range() call in ir-core. We'll suppose that any request
178 * setting L=0 means we must shut down the demodulator.
179 */
180#define ITE_RXDCR_PER_10000_STEP 625
181
182/* high speed carrier freq values */
183#define ITE_CFQ_400 0x03
184#define ITE_CFQ_450 0x08
185#define ITE_CFQ_480 0x0b
186#define ITE_CFQ_500 0x0d
187
188/* values for pulse widths */
189#define ITE_TXMPW_A 0x02
190#define ITE_TXMPW_B 0x03
191#define ITE_TXMPW_C 0x04
192#define ITE_TXMPW_D 0x05
193#define ITE_TXMPW_E 0x06
194
195/* values for demodulator carrier range allowance */
196#define ITE_RXDCR_DEFAULT 0x01 /* default carrier range */
197#define ITE_RXDCR_MAX 0x07 /* default carrier range */
198
199/* DR TX bits */
200#define ITE_TX_PULSE 0x00
201#define ITE_TX_SPACE 0x80
202#define ITE_TX_MAX_RLE 0x80
203#define ITE_TX_RLE_MASK 0x7f
204
205/*
206 * IT8712F
207 *
208 * hardware data obtained from:
209 *
210 * IT8712F
211 * Environment Control – Low Pin Count Input / Output
212 * (EC - LPC I/O)
213 * Preliminary Specification V0. 81
214 */
215
216/* register offsets */
217#define IT87_DR 0x00 /* data register */
218#define IT87_IER 0x01 /* interrupt enable register */
219#define IT87_RCR 0x02 /* receiver control register */
220#define IT87_TCR1 0x03 /* transmitter control register 1 */
221#define IT87_TCR2 0x04 /* transmitter control register 2 */
222#define IT87_TSR 0x05 /* transmitter status register */
223#define IT87_RSR 0x06 /* receiver status register */
224#define IT87_BDLR 0x05 /* baud rate divisor low byte register */
225#define IT87_BDHR 0x06 /* baud rate divisor high byte register */
226#define IT87_IIR 0x07 /* interrupt identification register */
227
228#define IT87_IOREG_LENGTH 0x08 /* length of register file */
229
230/* IER bits */
231#define IT87_TLDLIE 0x01 /* transmitter low data interrupt enable */
232#define IT87_RDAIE 0x02 /* receiver data available interrupt enable */
233#define IT87_RFOIE 0x04 /* receiver FIFO overrun interrupt enable */
234#define IT87_IEC 0x08 /* interrupt enable control */
235#define IT87_BR 0x10 /* baud rate register enable */
236#define IT87_RESET 0x20 /* reset */
237
238/* RCR bits */
239#define IT87_RXDCR 0x07 /* receiver demodulation carrier range mask */
240#define IT87_RXACT 0x08 /* receiver active */
241#define IT87_RXEND 0x10 /* receiver demodulation enable */
242#define IT87_RXEN 0x20 /* receiver enable */
243#define IT87_HCFS 0x40 /* high-speed carrier frequency select */
244#define IT87_RDWOS 0x80 /* receiver data without sync */
245
246/* TCR1 bits */
247#define IT87_TXMPM 0x03 /* transmitter modulation pulse mode mask */
248#define IT87_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
249#define IT87_TXENDF 0x04 /* transmitter deferral */
250#define IT87_TXRLE 0x08 /* transmitter run length enable */
251#define IT87_FIFOTL 0x30 /* FIFO level threshold mask */
252#define IT87_FIFOTL_DEFAULT 0x20 /* FIFO level threshold default
253 * 0x00 -> 1, 0x10 -> 7, 0x20 -> 17,
254 * 0x30 -> 25 */
255#define IT87_ILE 0x40 /* internal loopback enable */
256#define IT87_FIFOCLR 0x80 /* FIFO clear bit */
257
258/* TCR2 bits */
259#define IT87_TXMPW 0x07 /* transmitter modulation pulse width mask */
260#define IT87_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
261#define IT87_CFQ 0xf8 /* carrier frequency mask */
262#define IT87_CFQ_SHIFT 3 /* carrier frequency bit shift */
263
264/* TSR bits */
265#define IT87_TXFBC 0x3f /* transmitter FIFO byte count mask */
266
267/* RSR bits */
268#define IT87_RXFBC 0x3f /* receiver FIFO byte count mask */
269#define IT87_RXFTO 0x80 /* receiver FIFO time-out */
270
271/* IIR bits */
272#define IT87_IP 0x01 /* interrupt pending */
273#define IT87_II 0x06 /* interrupt identification mask */
274#define IT87_II_NOINT 0x00 /* no interrupt */
275#define IT87_II_TXLDL 0x02 /* transmitter low data level */
276#define IT87_II_RXDS 0x04 /* receiver data stored */
277#define IT87_II_RXFO 0x06 /* receiver FIFO overrun */
278
279/*
280 * IT8512E/F
281 *
282 * Hardware data obtained from:
283 *
284 * IT8512E/F
285 * Embedded Controller
286 * Preliminary Specification V0.4.1
287 *
288 * Note that the CIR registers are not directly available to the host, because
289 * they only are accessible to the integrated microcontroller. Thus, in order
290 * use it, some kind of bridging is required. As the bridging may depend on
291 * the controller firmware in use, we are going to use the PNP ID in order to
292 * determine the strategy and ports available. See after these generic
293 * IT8512E/F register definitions for register definitions for those
294 * strategies.
295 */
296
297/* register offsets */
298#define IT85_C0DR 0x00 /* data register */
299#define IT85_C0MSTCR 0x01 /* master control register */
300#define IT85_C0IER 0x02 /* interrupt enable register */
301#define IT85_C0IIR 0x03 /* interrupt identification register */
302#define IT85_C0CFR 0x04 /* carrier frequency register */
303#define IT85_C0RCR 0x05 /* receiver control register */
304#define IT85_C0TCR 0x06 /* transmitter control register */
305#define IT85_C0SCK 0x07 /* slow clock control register */
306#define IT85_C0BDLR 0x08 /* baud rate divisor low byte register */
307#define IT85_C0BDHR 0x09 /* baud rate divisor high byte register */
308#define IT85_C0TFSR 0x0a /* transmitter FIFO status register */
309#define IT85_C0RFSR 0x0b /* receiver FIFO status register */
310#define IT85_C0WCL 0x0d /* wakeup code length register */
311#define IT85_C0WCR 0x0e /* wakeup code read/write register */
312#define IT85_C0WPS 0x0f /* wakeup power control/status register */
313
314#define IT85_IOREG_LENGTH 0x10 /* length of register file */
315
316/* C0MSTCR bits */
317#define IT85_RESET 0x01 /* reset */
318#define IT85_FIFOCLR 0x02 /* FIFO clear bit */
319#define IT85_FIFOTL 0x0c /* FIFO level threshold mask */
320#define IT85_FIFOTL_DEFAULT 0x08 /* FIFO level threshold default
321 * 0x00 -> 1, 0x04 -> 7, 0x08 -> 17,
322 * 0x0c -> 25 */
323#define IT85_ILE 0x10 /* internal loopback enable */
324#define IT85_ILSEL 0x20 /* internal loopback select */
325
326/* C0IER bits */
327#define IT85_TLDLIE 0x01 /* TX low data level interrupt enable */
328#define IT85_RDAIE 0x02 /* RX data available interrupt enable */
329#define IT85_RFOIE 0x04 /* RX FIFO overrun interrupt enable */
330#define IT85_IEC 0x80 /* interrupt enable function control */
331
332/* C0IIR bits */
333#define IT85_TLDLI 0x01 /* transmitter low data level interrupt */
334#define IT85_RDAI 0x02 /* receiver data available interrupt */
335#define IT85_RFOI 0x04 /* receiver FIFO overrun interrupt */
336#define IT85_NIP 0x80 /* no interrupt pending */
337
338/* C0CFR bits */
339#define IT85_CFQ 0x1f /* carrier frequency mask */
340#define IT85_HCFS 0x20 /* high speed carrier frequency select */
341
342/* C0RCR bits */
343#define IT85_RXDCR 0x07 /* receiver demodulation carrier range mask */
344#define IT85_RXACT 0x08 /* receiver active */
345#define IT85_RXEND 0x10 /* receiver demodulation enable */
346#define IT85_RDWOS 0x20 /* receiver data without sync */
347#define IT85_RXEN 0x80 /* receiver enable */
348
349/* C0TCR bits */
350#define IT85_TXMPW 0x07 /* transmitter modulation pulse width mask */
351#define IT85_TXMPW_DEFAULT 0x04 /* default modulation pulse width */
352#define IT85_TXMPM 0x18 /* transmitter modulation pulse mode mask */
353#define IT85_TXMPM_DEFAULT 0x00 /* modulation pulse mode default */
354#define IT85_TXENDF 0x20 /* transmitter deferral */
355#define IT85_TXRLE 0x40 /* transmitter run length enable */
356
357/* C0SCK bits */
358#define IT85_SCKS 0x01 /* slow clock select */
359#define IT85_TXDCKG 0x02 /* TXD clock gating */
360#define IT85_DLL1P8E 0x04 /* DLL 1.8432M enable */
361#define IT85_DLLTE 0x08 /* DLL test enable */
362#define IT85_BRCM 0x70 /* baud rate count mode */
363#define IT85_DLLOCK 0x80 /* DLL lock */
364
365/* C0TFSR bits */
366#define IT85_TXFBC 0x3f /* transmitter FIFO count mask */
367
368/* C0RFSR bits */
369#define IT85_RXFBC 0x3f /* receiver FIFO count mask */
370#define IT85_RXFTO 0x80 /* receiver FIFO time-out */
371
372/* C0WCL bits */
373#define IT85_WCL 0x3f /* wakeup code length mask */
374
375/* C0WPS bits */
376#define IT85_CIRPOSIE 0x01 /* power on/off status interrupt enable */
377#define IT85_CIRPOIS 0x02 /* power on/off interrupt status */
378#define IT85_CIRPOII 0x04 /* power on/off interrupt identification */
379#define IT85_RCRST 0x10 /* wakeup code reading counter reset bit */
380#define IT85_WCRST 0x20 /* wakeup code writing counter reset bit */
381
382/*
383 * ITE8708
384 *
385 * Hardware data obtained from hacked driver for IT8512 in this forum post:
386 *
387 * http://ubuntuforums.org/showthread.php?t=1028640
388 *
389 * Although there's no official documentation for that driver, analysis would
390 * suggest that it maps the 16 registers of IT8512 onto two 8-register banks,
391 * selectable by a single bank-select bit that's mapped onto both banks. The
392 * IT8512 registers are mapped in a different order, so that the first bank
393 * maps the ones that are used more often, and two registers that share a
394 * reserved high-order bit are placed at the same offset in both banks in
395 * order to reuse the reserved bit as the bank select bit.
396 */
397
398/* register offsets */
399
400/* mapped onto both banks */
401#define IT8708_BANKSEL 0x07 /* bank select register */
402#define IT8708_HRAE 0x80 /* high registers access enable */
403
404/* mapped onto the low bank */
405#define IT8708_C0DR 0x00 /* data register */
406#define IT8708_C0MSTCR 0x01 /* master control register */
407#define IT8708_C0IER 0x02 /* interrupt enable register */
408#define IT8708_C0IIR 0x03 /* interrupt identification register */
409#define IT8708_C0RFSR 0x04 /* receiver FIFO status register */
410#define IT8708_C0RCR 0x05 /* receiver control register */
411#define IT8708_C0TFSR 0x06 /* transmitter FIFO status register */
412#define IT8708_C0TCR 0x07 /* transmitter control register */
413
414/* mapped onto the high bank */
415#define IT8708_C0BDLR 0x01 /* baud rate divisor low byte register */
416#define IT8708_C0BDHR 0x02 /* baud rate divisor high byte register */
417#define IT8708_C0CFR 0x04 /* carrier frequency register */
418
419/* registers whose bank mapping we don't know, since they weren't being used
420 * in the hacked driver... most probably they belong to the high bank too,
421 * since they fit in the holes the other registers leave */
422#define IT8708_C0SCK 0x03 /* slow clock control register */
423#define IT8708_C0WCL 0x05 /* wakeup code length register */
424#define IT8708_C0WCR 0x06 /* wakeup code read/write register */
425#define IT8708_C0WPS 0x07 /* wakeup power control/status register */
426
427#define IT8708_IOREG_LENGTH 0x08 /* length of register file */
428
429/* two more registers that are defined in the hacked driver, but can't be
430 * found in the data sheets; no idea what they are or how they are accessed,
431 * since the hacked driver doesn't seem to use them */
432#define IT8708_CSCRR 0x00
433#define IT8708_CGPINTR 0x01
434
435/* CSCRR bits */
436#define IT8708_CSCRR_SCRB 0x3f
437#define IT8708_CSCRR_PM 0x80
438
439/* CGPINTR bits */
440#define IT8708_CGPINT 0x01
441
442/*
443 * ITE8709
444 *
445 * Hardware interfacing data obtained from the original lirc_ite8709 driver.
446 * Verbatim from its sources:
447 *
448 * The ITE8709 device seems to be the combination of IT8512 superIO chip and
449 * a specific firmware running on the IT8512's embedded micro-controller.
450 * In addition of the embedded micro-controller, the IT8512 chip contains a
451 * CIR module and several other modules. A few modules are directly accessible
452 * by the host CPU, but most of them are only accessible by the
453 * micro-controller. The CIR module is only accessible by the
454 * micro-controller.
455 *
456 * The battery-backed SRAM module is accessible by the host CPU and the
457 * micro-controller. So one of the MC's firmware role is to act as a bridge
458 * between the host CPU and the CIR module. The firmware implements a kind of
459 * communication protocol using the SRAM module as a shared memory. The IT8512
460 * specification is publicly available on ITE's web site, but the
461 * communication protocol is not, so it was reverse-engineered.
462 */
463
464/* register offsets */
465#define IT8709_RAM_IDX 0x00 /* index into the SRAM module bytes */
466#define IT8709_RAM_VAL 0x01 /* read/write data to the indexed byte */
467
468#define IT8709_IOREG_LENGTH 0x02 /* length of register file */
469
470/* register offsets inside the SRAM module */
471#define IT8709_MODE 0x1a /* request/ack byte */
472#define IT8709_REG_IDX 0x1b /* index of the CIR register to access */
473#define IT8709_REG_VAL 0x1c /* value read/to be written */
474#define IT8709_IIR 0x1e /* interrupt identification register */
475#define IT8709_RFSR 0x1f /* receiver FIFO status register */
476#define IT8709_FIFO 0x20 /* start of in RAM RX FIFO copy */
477
478/* MODE values */
479#define IT8709_IDLE 0x00
480#define IT8709_WRITE 0x01
481#define IT8709_READ 0x02
diff --git a/drivers/media/rc/keymaps/Makefile b/drivers/media/rc/keymaps/Makefile
index 0659e9f50144..85cac7ddbcec 100644
--- a/drivers/media/rc/keymaps/Makefile
+++ b/drivers/media/rc/keymaps/Makefile
@@ -37,7 +37,6 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
37 rc-gadmei-rm008z.o \ 37 rc-gadmei-rm008z.o \
38 rc-genius-tvgo-a11mce.o \ 38 rc-genius-tvgo-a11mce.o \
39 rc-gotview7135.o \ 39 rc-gotview7135.o \
40 rc-hauppauge-new.o \
41 rc-imon-mce.o \ 40 rc-imon-mce.o \
42 rc-imon-pad.o \ 41 rc-imon-pad.o \
43 rc-iodata-bctv7e.o \ 42 rc-iodata-bctv7e.o \
@@ -68,14 +67,15 @@ obj-$(CONFIG_RC_MAP) += rc-adstech-dvb-t-pci.o \
68 rc-proteus-2309.o \ 67 rc-proteus-2309.o \
69 rc-purpletv.o \ 68 rc-purpletv.o \
70 rc-pv951.o \ 69 rc-pv951.o \
71 rc-rc5-hauppauge-new.o \ 70 rc-hauppauge.o \
72 rc-rc5-tv.o \
73 rc-rc6-mce.o \ 71 rc-rc6-mce.o \
74 rc-real-audio-220-32-keys.o \ 72 rc-real-audio-220-32-keys.o \
75 rc-streamzap.o \ 73 rc-streamzap.o \
76 rc-tbs-nec.o \ 74 rc-tbs-nec.o \
75 rc-technisat-usb2.o \
77 rc-terratec-cinergy-xs.o \ 76 rc-terratec-cinergy-xs.o \
78 rc-terratec-slim.o \ 77 rc-terratec-slim.o \
78 rc-terratec-slim-2.o \
79 rc-tevii-nec.o \ 79 rc-tevii-nec.o \
80 rc-total-media-in-hand.o \ 80 rc-total-media-in-hand.o \
81 rc-trekstor.o \ 81 rc-trekstor.o \
diff --git a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
index 136d3952dedc..9a8752fdcca1 100644
--- a/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
+++ b/drivers/media/rc/keymaps/rc-adstech-dvb-t-pci.c
@@ -50,9 +50,9 @@ static struct rc_map_table adstech_dvb_t_pci[] = {
50 { 0x13, KEY_TUNER }, /* Live */ 50 { 0x13, KEY_TUNER }, /* Live */
51 { 0x0a, KEY_A }, 51 { 0x0a, KEY_A },
52 { 0x12, KEY_B }, 52 { 0x12, KEY_B },
53 { 0x03, KEY_PROG1 }, /* 1 */ 53 { 0x03, KEY_RED }, /* 1 */
54 { 0x01, KEY_PROG2 }, /* 2 */ 54 { 0x01, KEY_GREEN }, /* 2 */
55 { 0x00, KEY_PROG3 }, /* 3 */ 55 { 0x00, KEY_YELLOW }, /* 3 */
56 { 0x06, KEY_DVD }, 56 { 0x06, KEY_DVD },
57 { 0x48, KEY_AUX }, /* Photo */ 57 { 0x48, KEY_AUX }, /* Photo */
58 { 0x40, KEY_VIDEO }, 58 { 0x40, KEY_VIDEO },
diff --git a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
index 3ddb41bc075e..c25809d4c813 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-dvbt.c
@@ -26,12 +26,12 @@ static struct rc_map_table avermedia_dvbt[] = {
26 { 0x16, KEY_8 }, /* '8' / 'down arrow' */ 26 { 0x16, KEY_8 }, /* '8' / 'down arrow' */
27 { 0x36, KEY_9 }, /* '9' */ 27 { 0x36, KEY_9 }, /* '9' */
28 28
29 { 0x20, KEY_LIST }, /* 'source' */ 29 { 0x20, KEY_VIDEO }, /* 'source' */
30 { 0x10, KEY_TEXT }, /* 'teletext' */ 30 { 0x10, KEY_TEXT }, /* 'teletext' */
31 { 0x00, KEY_POWER }, /* 'power' */ 31 { 0x00, KEY_POWER }, /* 'power' */
32 { 0x04, KEY_AUDIO }, /* 'audio' */ 32 { 0x04, KEY_AUDIO }, /* 'audio' */
33 { 0x06, KEY_ZOOM }, /* 'full screen' */ 33 { 0x06, KEY_ZOOM }, /* 'full screen' */
34 { 0x18, KEY_VIDEO }, /* 'display' */ 34 { 0x18, KEY_SWITCHVIDEOMODE }, /* 'display' */
35 { 0x38, KEY_SEARCH }, /* 'loop' */ 35 { 0x38, KEY_SEARCH }, /* 'loop' */
36 { 0x08, KEY_INFO }, /* 'preview' */ 36 { 0x08, KEY_INFO }, /* 'preview' */
37 { 0x2a, KEY_REWIND }, /* 'backward <<' */ 37 { 0x2a, KEY_REWIND }, /* 'backward <<' */
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m135a.c b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
index 357fea58a46e..3d2cbe4e5e46 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m135a.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m135a.c
@@ -108,7 +108,7 @@ static struct rc_map_table avermedia_m135a[] = {
108 { 0x0414, KEY_TEXT }, 108 { 0x0414, KEY_TEXT },
109 { 0x0415, KEY_EPG }, 109 { 0x0415, KEY_EPG },
110 { 0x041a, KEY_TV2 }, /* PIP */ 110 { 0x041a, KEY_TV2 }, /* PIP */
111 { 0x041b, KEY_MHP }, /* Snapshot */ 111 { 0x041b, KEY_CAMERA }, /* Snapshot */
112 112
113 { 0x0417, KEY_RECORD }, 113 { 0x0417, KEY_RECORD },
114 { 0x0416, KEY_PLAYPAUSE }, 114 { 0x0416, KEY_PLAYPAUSE },
diff --git a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
index e694e6eac37e..8cd7f28808bd 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-m733a-rm-k6.c
@@ -56,7 +56,7 @@ static struct rc_map_table avermedia_m733a_rm_k6[] = {
56 { 0x0414, KEY_TEXT }, 56 { 0x0414, KEY_TEXT },
57 { 0x0415, KEY_EPG }, 57 { 0x0415, KEY_EPG },
58 { 0x041a, KEY_TV2 }, /* PIP */ 58 { 0x041a, KEY_TV2 }, /* PIP */
59 { 0x041b, KEY_MHP }, /* Snapshot */ 59 { 0x041b, KEY_CAMERA }, /* Snapshot */
60 60
61 { 0x0417, KEY_RECORD }, 61 { 0x0417, KEY_RECORD },
62 { 0x0416, KEY_PLAYPAUSE }, 62 { 0x0416, KEY_PLAYPAUSE },
diff --git a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
index f4ca1fff455d..9d68af217d8b 100644
--- a/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
+++ b/drivers/media/rc/keymaps/rc-avermedia-rm-ks.c
@@ -31,7 +31,7 @@ static struct rc_map_table avermedia_rm_ks[] = {
31 { 0x0505, KEY_VOLUMEDOWN }, 31 { 0x0505, KEY_VOLUMEDOWN },
32 { 0x0506, KEY_MUTE }, 32 { 0x0506, KEY_MUTE },
33 { 0x0507, KEY_RIGHT }, 33 { 0x0507, KEY_RIGHT },
34 { 0x0508, KEY_PROG1 }, 34 { 0x0508, KEY_RED },
35 { 0x0509, KEY_1 }, 35 { 0x0509, KEY_1 },
36 { 0x050a, KEY_2 }, 36 { 0x050a, KEY_2 },
37 { 0x050b, KEY_3 }, 37 { 0x050b, KEY_3 },
diff --git a/drivers/media/rc/keymaps/rc-behold-columbus.c b/drivers/media/rc/keymaps/rc-behold-columbus.c
index 4b787fa94f08..8bf058f67f0c 100644
--- a/drivers/media/rc/keymaps/rc-behold-columbus.c
+++ b/drivers/media/rc/keymaps/rc-behold-columbus.c
@@ -28,7 +28,7 @@ static struct rc_map_table behold_columbus[] = {
28 * */ 28 * */
29 29
30 { 0x13, KEY_MUTE }, 30 { 0x13, KEY_MUTE },
31 { 0x11, KEY_PROPS }, 31 { 0x11, KEY_VIDEO },
32 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */ 32 { 0x1C, KEY_TUNER }, /* KEY_TV/KEY_RADIO */
33 { 0x12, KEY_POWER }, 33 { 0x12, KEY_POWER },
34 34
diff --git a/drivers/media/rc/keymaps/rc-behold.c b/drivers/media/rc/keymaps/rc-behold.c
index 0ee1f149364c..c909a234c776 100644
--- a/drivers/media/rc/keymaps/rc-behold.c
+++ b/drivers/media/rc/keymaps/rc-behold.c
@@ -97,7 +97,7 @@ static struct rc_map_table behold[] = {
97 { 0x6b861a, KEY_STOP }, 97 { 0x6b861a, KEY_STOP },
98 { 0x6b860e, KEY_TEXT }, 98 { 0x6b860e, KEY_TEXT },
99 { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */ 99 { 0x6b861f, KEY_RED }, /*XXX KEY_AUDIO */
100 { 0x6b861e, KEY_YELLOW }, /*XXX KEY_SOURCE */ 100 { 0x6b861e, KEY_VIDEO },
101 101
102 /* 0x1d 0x13 0x19 * 102 /* 0x1d 0x13 0x19 *
103 * SLEEP PREVIEW DVB * 103 * SLEEP PREVIEW DVB *
diff --git a/drivers/media/rc/keymaps/rc-budget-ci-old.c b/drivers/media/rc/keymaps/rc-budget-ci-old.c
index 97fc3862f608..2f66e4310d20 100644
--- a/drivers/media/rc/keymaps/rc-budget-ci-old.c
+++ b/drivers/media/rc/keymaps/rc-budget-ci-old.c
@@ -12,7 +12,8 @@
12 12
13#include <media/rc-map.h> 13#include <media/rc-map.h>
14 14
15/* From reading the following remotes: 15/*
16 * From reading the following remotes:
16 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837 17 * Zenith Universal 7 / TV Mode 807 / VCR Mode 837
17 * Hauppauge (from NOVA-CI-s box product) 18 * Hauppauge (from NOVA-CI-s box product)
18 * This is a "middle of the road" approach, differences are noted 19 * This is a "middle of the road" approach, differences are noted
diff --git a/drivers/media/rc/keymaps/rc-cinergy.c b/drivers/media/rc/keymaps/rc-cinergy.c
index 99520ff65b61..cf3a6bfb190c 100644
--- a/drivers/media/rc/keymaps/rc-cinergy.c
+++ b/drivers/media/rc/keymaps/rc-cinergy.c
@@ -25,7 +25,7 @@ static struct rc_map_table cinergy[] = {
25 { 0x09, KEY_9 }, 25 { 0x09, KEY_9 },
26 26
27 { 0x0a, KEY_POWER }, 27 { 0x0a, KEY_POWER },
28 { 0x0b, KEY_PROG1 }, /* app */ 28 { 0x0b, KEY_MEDIA }, /* app */
29 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */ 29 { 0x0c, KEY_ZOOM }, /* zoom/fullscreen */
30 { 0x0d, KEY_CHANNELUP }, /* channel */ 30 { 0x0d, KEY_CHANNELUP }, /* channel */
31 { 0x0e, KEY_CHANNELDOWN }, /* channel- */ 31 { 0x0e, KEY_CHANNELDOWN }, /* channel- */
diff --git a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
index 43912bd02a9e..82c0200029af 100644
--- a/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
+++ b/drivers/media/rc/keymaps/rc-dntv-live-dvb-t.c
@@ -32,7 +32,7 @@ static struct rc_map_table dntv_live_dvb_t[] = {
32 { 0x0c, KEY_SEARCH }, /* scan */ 32 { 0x0c, KEY_SEARCH }, /* scan */
33 { 0x0d, KEY_STOP }, 33 { 0x0d, KEY_STOP },
34 { 0x0e, KEY_PAUSE }, 34 { 0x0e, KEY_PAUSE },
35 { 0x0f, KEY_LIST }, /* source */ 35 { 0x0f, KEY_VIDEO }, /* source */
36 36
37 { 0x10, KEY_MUTE }, 37 { 0x10, KEY_MUTE },
38 { 0x11, KEY_REWIND }, /* backward << */ 38 { 0x11, KEY_REWIND }, /* backward << */
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv.c b/drivers/media/rc/keymaps/rc-encore-enltv.c
index afa4e92284ef..e56ac6e9670a 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv.c
@@ -24,7 +24,7 @@ static struct rc_map_table encore_enltv[] = {
24 { 0x1e, KEY_TV }, 24 { 0x1e, KEY_TV },
25 { 0x00, KEY_VIDEO }, 25 { 0x00, KEY_VIDEO },
26 { 0x01, KEY_AUDIO }, /* music */ 26 { 0x01, KEY_AUDIO }, /* music */
27 { 0x02, KEY_MHP }, /* picture */ 27 { 0x02, KEY_CAMERA }, /* picture */
28 28
29 { 0x1f, KEY_1 }, 29 { 0x1f, KEY_1 },
30 { 0x03, KEY_2 }, 30 { 0x03, KEY_2 },
@@ -77,7 +77,7 @@ static struct rc_map_table encore_enltv[] = {
77 { 0x50, KEY_SLEEP }, /* shutdown */ 77 { 0x50, KEY_SLEEP }, /* shutdown */
78 { 0x51, KEY_MODE }, /* stereo > main */ 78 { 0x51, KEY_MODE }, /* stereo > main */
79 { 0x52, KEY_SELECT }, /* stereo > sap */ 79 { 0x52, KEY_SELECT }, /* stereo > sap */
80 { 0x53, KEY_PROG1 }, /* teletext */ 80 { 0x53, KEY_TEXT }, /* teletext */
81 81
82 82
83 { 0x59, KEY_RED }, /* AP1 */ 83 { 0x59, KEY_RED }, /* AP1 */
diff --git a/drivers/media/rc/keymaps/rc-encore-enltv2.c b/drivers/media/rc/keymaps/rc-encore-enltv2.c
index 7d5b00ed4ff2..b6264f1bc4c1 100644
--- a/drivers/media/rc/keymaps/rc-encore-enltv2.c
+++ b/drivers/media/rc/keymaps/rc-encore-enltv2.c
@@ -32,7 +32,7 @@ static struct rc_map_table encore_enltv2[] = {
32 { 0x64, KEY_LAST }, /* +100 */ 32 { 0x64, KEY_LAST }, /* +100 */
33 { 0x4e, KEY_AGAIN }, /* Recall */ 33 { 0x4e, KEY_AGAIN }, /* Recall */
34 34
35 { 0x6c, KEY_SWITCHVIDEOMODE }, /* Video Source */ 35 { 0x6c, KEY_VIDEO }, /* Video Source */
36 { 0x5e, KEY_MENU }, 36 { 0x5e, KEY_MENU },
37 { 0x56, KEY_SCREEN }, 37 { 0x56, KEY_SCREEN },
38 { 0x7a, KEY_SETUP }, 38 { 0x7a, KEY_SETUP },
diff --git a/drivers/media/rc/keymaps/rc-flydvb.c b/drivers/media/rc/keymaps/rc-flydvb.c
index aea2f4acf7d8..a8b0f66edaa9 100644
--- a/drivers/media/rc/keymaps/rc-flydvb.c
+++ b/drivers/media/rc/keymaps/rc-flydvb.c
@@ -37,8 +37,8 @@ static struct rc_map_table flydvb[] = {
37 { 0x13, KEY_CHANNELDOWN }, /* CH- */ 37 { 0x13, KEY_CHANNELDOWN }, /* CH- */
38 { 0x1d, KEY_ENTER }, /* Enter */ 38 { 0x1d, KEY_ENTER }, /* Enter */
39 39
40 { 0x1a, KEY_MODE }, /* PIP */ 40 { 0x1a, KEY_TV2 }, /* PIP */
41 { 0x18, KEY_TUNER }, /* Source */ 41 { 0x18, KEY_VIDEO }, /* Source */
42 42
43 { 0x1e, KEY_RECORD }, /* Record/Pause */ 43 { 0x1e, KEY_RECORD }, /* Record/Pause */
44 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */ 44 { 0x15, KEY_ANGLE }, /* Swap (no label on key) */
diff --git a/drivers/media/rc/keymaps/rc-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge-new.c
deleted file mode 100644
index bd11da46e56a..000000000000
--- a/drivers/media/rc/keymaps/rc-hauppauge-new.c
+++ /dev/null
@@ -1,100 +0,0 @@
1/* hauppauge-new.h - Keytable for hauppauge_new Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.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
13#include <media/rc-map.h>
14
15/* Hauppauge: the newer, gray remotes (seems there are multiple
16 * slightly different versions), shipped with cx88+ivtv cards.
17 * almost rc5 coding, but some non-standard keys */
18
19static struct rc_map_table hauppauge_new[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0a, KEY_TEXT }, /* keypad asterisk as well */
33 { 0x0b, KEY_RED }, /* red button */
34 { 0x0c, KEY_RADIO },
35 { 0x0d, KEY_MENU },
36 { 0x0e, KEY_SUBTITLE }, /* also the # key */
37 { 0x0f, KEY_MUTE },
38 { 0x10, KEY_VOLUMEUP },
39 { 0x11, KEY_VOLUMEDOWN },
40 { 0x12, KEY_PREVIOUS }, /* previous channel */
41 { 0x14, KEY_UP },
42 { 0x15, KEY_DOWN },
43 { 0x16, KEY_LEFT },
44 { 0x17, KEY_RIGHT },
45 { 0x18, KEY_VIDEO }, /* Videos */
46 { 0x19, KEY_AUDIO }, /* Music */
47 /* 0x1a: Pictures - presume this means
48 "Multimedia Home Platform" -
49 no "PICTURES" key in input.h
50 */
51 { 0x1a, KEY_MHP },
52
53 { 0x1b, KEY_EPG }, /* Guide */
54 { 0x1c, KEY_TV },
55 { 0x1e, KEY_NEXTSONG }, /* skip >| */
56 { 0x1f, KEY_EXIT }, /* back/exit */
57 { 0x20, KEY_CHANNELUP }, /* channel / program + */
58 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
59 { 0x22, KEY_CHANNEL }, /* source (old black remote) */
60 { 0x24, KEY_PREVIOUSSONG }, /* replay |< */
61 { 0x25, KEY_ENTER }, /* OK */
62 { 0x26, KEY_SLEEP }, /* minimize (old black remote) */
63 { 0x29, KEY_BLUE }, /* blue key */
64 { 0x2e, KEY_GREEN }, /* green button */
65 { 0x30, KEY_PAUSE }, /* pause */
66 { 0x32, KEY_REWIND }, /* backward << */
67 { 0x34, KEY_FASTFORWARD }, /* forward >> */
68 { 0x35, KEY_PLAY },
69 { 0x36, KEY_STOP },
70 { 0x37, KEY_RECORD }, /* recording */
71 { 0x38, KEY_YELLOW }, /* yellow key */
72 { 0x3b, KEY_SELECT }, /* top right button */
73 { 0x3c, KEY_ZOOM }, /* full */
74 { 0x3d, KEY_POWER }, /* system power (green button) */
75};
76
77static struct rc_map_list hauppauge_new_map = {
78 .map = {
79 .scan = hauppauge_new,
80 .size = ARRAY_SIZE(hauppauge_new),
81 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
82 .name = RC_MAP_HAUPPAUGE_NEW,
83 }
84};
85
86static int __init init_rc_map_hauppauge_new(void)
87{
88 return rc_map_register(&hauppauge_new_map);
89}
90
91static void __exit exit_rc_map_hauppauge_new(void)
92{
93 rc_map_unregister(&hauppauge_new_map);
94}
95
96module_init(init_rc_map_hauppauge_new)
97module_exit(exit_rc_map_hauppauge_new)
98
99MODULE_LICENSE("GPL");
100MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c b/drivers/media/rc/keymaps/rc-hauppauge.c
index dfc9b15f43a9..cd3db7779772 100644
--- a/drivers/media/rc/keymaps/rc-rc5-hauppauge-new.c
+++ b/drivers/media/rc/keymaps/rc-hauppauge.c
@@ -1,8 +1,14 @@
1/* rc5-hauppauge-new.h - Keytable for rc5_hauppauge_new Remote Controller 1/* rc-hauppauge.c - Keytable for Hauppauge Remote Controllers
2 * 2 *
3 * keymap imported from ir-keymaps.c 3 * keymap imported from ir-keymaps.c
4 * 4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.com> 5 * This map currently contains the code for four different RCs:
6 * - New Hauppauge Gray;
7 * - Old Hauppauge Gray (with a golden screen for media keys);
8 * - Hauppauge Black;
9 * - DSR-0112 remote bundled with Haupauge MiniStick.
10 *
11 * Copyright (c) 2010-2011 by Mauro Carvalho Chehab <mchehab@redhat.com>
6 * 12 *
7 * This program is free software; you can redistribute it and/or modify 13 * 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 14 * it under the terms of the GNU General Public License as published by
@@ -20,63 +26,124 @@
20 */ 26 */
21 27
22static struct rc_map_table rc5_hauppauge_new[] = { 28static struct rc_map_table rc5_hauppauge_new[] = {
23 /* Keys 0 to 9 */ 29 /*
24 { 0x1e00, KEY_0 }, 30 * Remote Controller Hauppauge Gray found on modern devices
31 * Keycodes start with address = 0x1e
32 */
33
34 { 0x1e3b, KEY_SELECT }, /* GO / house symbol */
35 { 0x1e3d, KEY_POWER2 }, /* system power (green button) */
36
37 { 0x1e1c, KEY_TV },
38 { 0x1e18, KEY_VIDEO }, /* Videos */
39 { 0x1e19, KEY_AUDIO }, /* Music */
40 { 0x1e1a, KEY_CAMERA }, /* Pictures */
41
42 { 0x1e1b, KEY_EPG }, /* Guide */
43 { 0x1e0c, KEY_RADIO },
44
45 { 0x1e14, KEY_UP },
46 { 0x1e15, KEY_DOWN },
47 { 0x1e16, KEY_LEFT },
48 { 0x1e17, KEY_RIGHT },
49 { 0x1e25, KEY_OK }, /* OK */
50
51 { 0x1e1f, KEY_EXIT }, /* back/exit */
52 { 0x1e0d, KEY_MENU },
53
54 { 0x1e10, KEY_VOLUMEUP },
55 { 0x1e11, KEY_VOLUMEDOWN },
56
57 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
58 { 0x1e0f, KEY_MUTE },
59
60 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
61 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
62
63 { 0x1e37, KEY_RECORD }, /* recording */
64 { 0x1e36, KEY_STOP },
65
66 { 0x1e32, KEY_REWIND }, /* backward << */
67 { 0x1e35, KEY_PLAY },
68 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
69
70 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
71 { 0x1e30, KEY_PAUSE }, /* pause */
72 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
73
25 { 0x1e01, KEY_1 }, 74 { 0x1e01, KEY_1 },
26 { 0x1e02, KEY_2 }, 75 { 0x1e02, KEY_2 },
27 { 0x1e03, KEY_3 }, 76 { 0x1e03, KEY_3 },
77
28 { 0x1e04, KEY_4 }, 78 { 0x1e04, KEY_4 },
29 { 0x1e05, KEY_5 }, 79 { 0x1e05, KEY_5 },
30 { 0x1e06, KEY_6 }, 80 { 0x1e06, KEY_6 },
81
31 { 0x1e07, KEY_7 }, 82 { 0x1e07, KEY_7 },
32 { 0x1e08, KEY_8 }, 83 { 0x1e08, KEY_8 },
33 { 0x1e09, KEY_9 }, 84 { 0x1e09, KEY_9 },
34 85
35 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */ 86 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
36 { 0x1e0b, KEY_RED }, /* red button */ 87 { 0x1e00, KEY_0 },
37 { 0x1e0c, KEY_RADIO }, 88 { 0x1e0e, KEY_SUBTITLE }, /* also the Pound key (#) */
38 { 0x1e0d, KEY_MENU },
39 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
40 { 0x1e0f, KEY_MUTE },
41 { 0x1e10, KEY_VOLUMEUP },
42 { 0x1e11, KEY_VOLUMEDOWN },
43 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
44 { 0x1e14, KEY_UP },
45 { 0x1e15, KEY_DOWN },
46 { 0x1e16, KEY_LEFT },
47 { 0x1e17, KEY_RIGHT },
48 { 0x1e18, KEY_VIDEO }, /* Videos */
49 { 0x1e19, KEY_AUDIO }, /* Music */
50 /* 0x1e1a: Pictures - presume this means
51 "Multimedia Home Platform" -
52 no "PICTURES" key in input.h
53 */
54 { 0x1e1a, KEY_MHP },
55 89
56 { 0x1e1b, KEY_EPG }, /* Guide */ 90 { 0x1e0b, KEY_RED }, /* red button */
57 { 0x1e1c, KEY_TV },
58 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
59 { 0x1e1f, KEY_EXIT }, /* back/exit */
60 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
61 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
62 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
63 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
64 { 0x1e25, KEY_ENTER }, /* OK */
65 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
66 { 0x1e29, KEY_BLUE }, /* blue key */
67 { 0x1e2e, KEY_GREEN }, /* green button */ 91 { 0x1e2e, KEY_GREEN }, /* green button */
68 { 0x1e30, KEY_PAUSE }, /* pause */
69 { 0x1e32, KEY_REWIND }, /* backward << */
70 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
71 { 0x1e35, KEY_PLAY },
72 { 0x1e36, KEY_STOP },
73 { 0x1e37, KEY_RECORD }, /* recording */
74 { 0x1e38, KEY_YELLOW }, /* yellow key */ 92 { 0x1e38, KEY_YELLOW }, /* yellow key */
75 { 0x1e3b, KEY_SELECT }, /* top right button */ 93 { 0x1e29, KEY_BLUE }, /* blue key */
76 { 0x1e3c, KEY_ZOOM }, /* full */ 94
77 { 0x1e3d, KEY_POWER }, /* system power (green button) */ 95 /*
96 * Old Remote Controller Hauppauge Gray with a golden screen
97 * Keycodes start with address = 0x1f
98 */
99 { 0x1f3d, KEY_POWER2 }, /* system power (green button) */
100 { 0x1f3b, KEY_SELECT }, /* GO */
101
102 /* Keys 0 to 9 */
103 { 0x1f00, KEY_0 },
104 { 0x1f01, KEY_1 },
105 { 0x1f02, KEY_2 },
106 { 0x1f03, KEY_3 },
107 { 0x1f04, KEY_4 },
108 { 0x1f05, KEY_5 },
109 { 0x1f06, KEY_6 },
110 { 0x1f07, KEY_7 },
111 { 0x1f08, KEY_8 },
112 { 0x1f09, KEY_9 },
113
114 { 0x1f1f, KEY_EXIT }, /* back/exit */
115 { 0x1f0d, KEY_MENU },
116
117 { 0x1f10, KEY_VOLUMEUP },
118 { 0x1f11, KEY_VOLUMEDOWN },
119 { 0x1f20, KEY_CHANNELUP }, /* channel / program + */
120 { 0x1f21, KEY_CHANNELDOWN }, /* channel / program - */
121 { 0x1f25, KEY_ENTER }, /* OK */
122
123 { 0x1f0b, KEY_RED }, /* red button */
124 { 0x1f2e, KEY_GREEN }, /* green button */
125 { 0x1f38, KEY_YELLOW }, /* yellow key */
126 { 0x1f29, KEY_BLUE }, /* blue key */
127
128 { 0x1f0f, KEY_MUTE },
129 { 0x1f0c, KEY_RADIO }, /* There's no indicator on this key */
130 { 0x1f3c, KEY_ZOOM }, /* full */
131
132 { 0x1f32, KEY_REWIND }, /* backward << */
133 { 0x1f35, KEY_PLAY },
134 { 0x1f34, KEY_FASTFORWARD }, /* forward >> */
78 135
79 /* Keycodes for DSR-0112 remote bundled with Haupauge MiniStick */ 136 { 0x1f37, KEY_RECORD }, /* recording */
137 { 0x1f36, KEY_STOP },
138 { 0x1f30, KEY_PAUSE }, /* pause */
139
140 { 0x1f24, KEY_PREVIOUSSONG }, /* replay |< */
141 { 0x1f1e, KEY_NEXTSONG }, /* skip >| */
142
143 /*
144 * Keycodes for DSR-0112 remote bundled with Haupauge MiniStick
145 * Keycodes start with address = 0x1d
146 */
80 { 0x1d00, KEY_0 }, 147 { 0x1d00, KEY_0 },
81 { 0x1d01, KEY_1 }, 148 { 0x1d01, KEY_1 },
82 { 0x1d02, KEY_2 }, 149 { 0x1d02, KEY_2 },
@@ -113,6 +180,39 @@ static struct rc_map_table rc5_hauppauge_new[] = {
113 { 0x1d3b, KEY_GOTO }, 180 { 0x1d3b, KEY_GOTO },
114 { 0x1d3d, KEY_POWER }, 181 { 0x1d3d, KEY_POWER },
115 { 0x1d3f, KEY_HOME }, 182 { 0x1d3f, KEY_HOME },
183
184 /*
185 * Keycodes for the old Black Remote Controller
186 * This one also uses RC-5 protocol
187 * Keycodes start with address = 0x00
188 */
189 { 0x001f, KEY_TV },
190 { 0x0020, KEY_CHANNELUP },
191 { 0x000c, KEY_RADIO },
192
193 { 0x0011, KEY_VOLUMEDOWN },
194 { 0x002e, KEY_ZOOM }, /* full screen */
195 { 0x0010, KEY_VOLUMEUP },
196
197 { 0x000d, KEY_MUTE },
198 { 0x0021, KEY_CHANNELDOWN },
199 { 0x0022, KEY_VIDEO }, /* source */
200
201 { 0x0001, KEY_1 },
202 { 0x0002, KEY_2 },
203 { 0x0003, KEY_3 },
204
205 { 0x0004, KEY_4 },
206 { 0x0005, KEY_5 },
207 { 0x0006, KEY_6 },
208
209 { 0x0007, KEY_7 },
210 { 0x0008, KEY_8 },
211 { 0x0009, KEY_9 },
212
213 { 0x001e, KEY_RED }, /* Reserved */
214 { 0x0000, KEY_0 },
215 { 0x0026, KEY_SLEEP }, /* Minimize */
116}; 216};
117 217
118static struct rc_map_list rc5_hauppauge_new_map = { 218static struct rc_map_list rc5_hauppauge_new_map = {
@@ -120,7 +220,7 @@ static struct rc_map_list rc5_hauppauge_new_map = {
120 .scan = rc5_hauppauge_new, 220 .scan = rc5_hauppauge_new,
121 .size = ARRAY_SIZE(rc5_hauppauge_new), 221 .size = ARRAY_SIZE(rc5_hauppauge_new),
122 .rc_type = RC_TYPE_RC5, 222 .rc_type = RC_TYPE_RC5,
123 .name = RC_MAP_RC5_HAUPPAUGE_NEW, 223 .name = RC_MAP_HAUPPAUGE,
124 } 224 }
125}; 225};
126 226
diff --git a/drivers/media/rc/keymaps/rc-imon-mce.c b/drivers/media/rc/keymaps/rc-imon-mce.c
index cb67184e015c..937a81989f00 100644
--- a/drivers/media/rc/keymaps/rc-imon-mce.c
+++ b/drivers/media/rc/keymaps/rc-imon-mce.c
@@ -111,7 +111,7 @@ static struct rc_map_table imon_mce[] = {
111 { 0x800ff44d, KEY_TITLE }, 111 { 0x800ff44d, KEY_TITLE },
112 112
113 { 0x800ff40c, KEY_POWER }, 113 { 0x800ff40c, KEY_POWER },
114 { 0x800ff40d, KEY_PROG1 }, /* Windows MCE button */ 114 { 0x800ff40d, KEY_LEFTMETA }, /* Windows MCE button */
115 115
116}; 116};
117 117
diff --git a/drivers/media/rc/keymaps/rc-imon-pad.c b/drivers/media/rc/keymaps/rc-imon-pad.c
index eef46b73ca7b..63d42bd24c9e 100644
--- a/drivers/media/rc/keymaps/rc-imon-pad.c
+++ b/drivers/media/rc/keymaps/rc-imon-pad.c
@@ -125,7 +125,7 @@ static struct rc_map_table imon_pad[] = {
125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/ 125 { 0x2b8195b7, KEY_CONTEXT_MENU }, /* Left Menu*/
126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */ 126 { 0x02000065, KEY_COMPOSE }, /* RightMenu */
127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */ 127 { 0x28b715b7, KEY_COMPOSE }, /* RightMenu */
128 { 0x2ab195b7, KEY_PROG1 }, /* Go or MultiMon */ 128 { 0x2ab195b7, KEY_LEFTMETA }, /* Go or MultiMon */
129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */ 129 { 0x29b715b7, KEY_DASHBOARD }, /* AppLauncher */
130}; 130};
131 131
diff --git a/drivers/media/rc/keymaps/rc-kworld-315u.c b/drivers/media/rc/keymaps/rc-kworld-315u.c
index 3ce6ef79fc34..7f33edb47244 100644
--- a/drivers/media/rc/keymaps/rc-kworld-315u.c
+++ b/drivers/media/rc/keymaps/rc-kworld-315u.c
@@ -17,7 +17,7 @@
17 17
18static struct rc_map_table kworld_315u[] = { 18static struct rc_map_table kworld_315u[] = {
19 { 0x6143, KEY_POWER }, 19 { 0x6143, KEY_POWER },
20 { 0x6101, KEY_TUNER }, /* source */ 20 { 0x6101, KEY_VIDEO }, /* source */
21 { 0x610b, KEY_ZOOM }, 21 { 0x610b, KEY_ZOOM },
22 { 0x6103, KEY_POWER2 }, /* shutdown */ 22 { 0x6103, KEY_POWER2 }, /* shutdown */
23 23
diff --git a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
index e45f0b8759d0..08d183120e41 100644
--- a/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
+++ b/drivers/media/rc/keymaps/rc-kworld-plus-tv-analog.c
@@ -17,7 +17,7 @@
17 */ 17 */
18 18
19static struct rc_map_table kworld_plus_tv_analog[] = { 19static struct rc_map_table kworld_plus_tv_analog[] = {
20 { 0x0c, KEY_PROG1 }, /* Kworld key */ 20 { 0x0c, KEY_LEFTMETA }, /* Kworld key */
21 { 0x16, KEY_CLOSECD }, /* -> ) */ 21 { 0x16, KEY_CLOSECD }, /* -> ) */
22 { 0x1d, KEY_POWER2 }, 22 { 0x1d, KEY_POWER2 },
23 23
diff --git a/drivers/media/rc/keymaps/rc-lme2510.c b/drivers/media/rc/keymaps/rc-lme2510.c
index 875cd81477c7..3c1913926c1a 100644
--- a/drivers/media/rc/keymaps/rc-lme2510.c
+++ b/drivers/media/rc/keymaps/rc-lme2510.c
@@ -13,33 +13,75 @@
13 13
14 14
15static struct rc_map_table lme2510_rc[] = { 15static struct rc_map_table lme2510_rc[] = {
16 { 0xba45, KEY_0 }, 16 /* Type 1 - 26 buttons */
17 { 0xa05f, KEY_1 }, 17 { 0xef12ba45, KEY_0 },
18 { 0xaf50, KEY_2 }, 18 { 0xef12a05f, KEY_1 },
19 { 0xa25d, KEY_3 }, 19 { 0xef12af50, KEY_2 },
20 { 0xbe41, KEY_4 }, 20 { 0xef12a25d, KEY_3 },
21 { 0xf50a, KEY_5 }, 21 { 0xef12be41, KEY_4 },
22 { 0xbd42, KEY_6 }, 22 { 0xef12f50a, KEY_5 },
23 { 0xb847, KEY_7 }, 23 { 0xef12bd42, KEY_6 },
24 { 0xb649, KEY_8 }, 24 { 0xef12b847, KEY_7 },
25 { 0xfa05, KEY_9 }, 25 { 0xef12b649, KEY_8 },
26 { 0xbc43, KEY_POWER }, 26 { 0xef12fa05, KEY_9 },
27 { 0xb946, KEY_SUBTITLE }, 27 { 0xef12bc43, KEY_POWER },
28 { 0xf906, KEY_PAUSE }, 28 { 0xef12b946, KEY_SUBTITLE },
29 { 0xfc03, KEY_MEDIA_REPEAT}, 29 { 0xef12f906, KEY_PAUSE },
30 { 0xfd02, KEY_PAUSE }, 30 { 0xef12fc03, KEY_MEDIA_REPEAT},
31 { 0xa15e, KEY_VOLUMEUP }, 31 { 0xef12fd02, KEY_PAUSE },
32 { 0xa35c, KEY_VOLUMEDOWN }, 32 { 0xef12a15e, KEY_VOLUMEUP },
33 { 0xf609, KEY_CHANNELUP }, 33 { 0xef12a35c, KEY_VOLUMEDOWN },
34 { 0xe51a, KEY_CHANNELDOWN }, 34 { 0xef12f609, KEY_CHANNELUP },
35 { 0xe11e, KEY_PLAY }, 35 { 0xef12e51a, KEY_CHANNELDOWN },
36 { 0xe41b, KEY_ZOOM }, 36 { 0xef12e11e, KEY_PLAY },
37 { 0xa659, KEY_MUTE }, 37 { 0xef12e41b, KEY_ZOOM },
38 { 0xa55a, KEY_TV }, 38 { 0xef12a659, KEY_MUTE },
39 { 0xe718, KEY_RECORD }, 39 { 0xef12a55a, KEY_TV },
40 { 0xf807, KEY_EPG }, 40 { 0xef12e718, KEY_RECORD },
41 { 0xfe01, KEY_STOP }, 41 { 0xef12f807, KEY_EPG },
42 42 { 0xef12fe01, KEY_STOP },
43 /* Type 2 - 20 buttons */
44 { 0xff40ea15, KEY_0 },
45 { 0xff40f708, KEY_1 },
46 { 0xff40f609, KEY_2 },
47 { 0xff40f50a, KEY_3 },
48 { 0xff40f30c, KEY_4 },
49 { 0xff40f20d, KEY_5 },
50 { 0xff40f10e, KEY_6 },
51 { 0xff40ef10, KEY_7 },
52 { 0xff40ee11, KEY_8 },
53 { 0xff40ed12, KEY_9 },
54 { 0xff40ff00, KEY_POWER },
55 { 0xff40fb04, KEY_MEDIA_REPEAT}, /* Recall */
56 { 0xff40e51a, KEY_PAUSE }, /* Timeshift */
57 { 0xff40fd02, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
58 { 0xff40f906, KEY_VOLUMEDOWN }, /* Volumne defined as right hand*/
59 { 0xff40fe01, KEY_CHANNELUP },
60 { 0xff40fa05, KEY_CHANNELDOWN },
61 { 0xff40eb14, KEY_ZOOM },
62 { 0xff40e718, KEY_RECORD },
63 { 0xff40e916, KEY_STOP },
64 /* Type 3 - 20 buttons */
65 { 0xff00e31c, KEY_0 },
66 { 0xff00f807, KEY_1 },
67 { 0xff00ea15, KEY_2 },
68 { 0xff00f609, KEY_3 },
69 { 0xff00e916, KEY_4 },
70 { 0xff00e619, KEY_5 },
71 { 0xff00f20d, KEY_6 },
72 { 0xff00f30c, KEY_7 },
73 { 0xff00e718, KEY_8 },
74 { 0xff00a15e, KEY_9 },
75 { 0xff00ba45, KEY_POWER },
76 { 0xff00bb44, KEY_MEDIA_REPEAT}, /* Recall */
77 { 0xff00b54a, KEY_PAUSE }, /* Timeshift */
78 { 0xff00b847, KEY_VOLUMEUP }, /* 2 x -/+ Keys not marked */
79 { 0xff00bc43, KEY_VOLUMEDOWN }, /* Volumne defined as right hand*/
80 { 0xff00b946, KEY_CHANNELUP },
81 { 0xff00bf40, KEY_CHANNELDOWN },
82 { 0xff00f708, KEY_ZOOM },
83 { 0xff00bd42, KEY_RECORD },
84 { 0xff00a55a, KEY_STOP },
43}; 85};
44 86
45static struct rc_map_list lme2510_map = { 87static struct rc_map_list lme2510_map = {
diff --git a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
index fa8fd0ab94c7..8e9969d1239b 100644
--- a/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
+++ b/drivers/media/rc/keymaps/rc-msi-tvanywhere-plus.c
@@ -62,7 +62,7 @@ static struct rc_map_table msi_tvanywhere_plus[] = {
62 { 0x13, KEY_AGAIN }, /* Recall */ 62 { 0x13, KEY_AGAIN }, /* Recall */
63 63
64 { 0x1e, KEY_POWER }, /* Power */ 64 { 0x1e, KEY_POWER }, /* Power */
65 { 0x07, KEY_TUNER }, /* Source */ 65 { 0x07, KEY_VIDEO }, /* Source */
66 { 0x1c, KEY_SEARCH }, /* Scan */ 66 { 0x1c, KEY_SEARCH }, /* Scan */
67 { 0x18, KEY_MUTE }, /* Mute */ 67 { 0x18, KEY_MUTE }, /* Mute */
68 68
diff --git a/drivers/media/rc/keymaps/rc-nebula.c b/drivers/media/rc/keymaps/rc-nebula.c
index 3e6f077eb700..ddae20e9cd96 100644
--- a/drivers/media/rc/keymaps/rc-nebula.c
+++ b/drivers/media/rc/keymaps/rc-nebula.c
@@ -27,7 +27,7 @@ static struct rc_map_table nebula[] = {
27 { 0x0b, KEY_AUX }, 27 { 0x0b, KEY_AUX },
28 { 0x0c, KEY_DVD }, 28 { 0x0c, KEY_DVD },
29 { 0x0d, KEY_POWER }, 29 { 0x0d, KEY_POWER },
30 { 0x0e, KEY_MHP }, /* labelled 'Picture' */ 30 { 0x0e, KEY_CAMERA }, /* labelled 'Picture' */
31 { 0x0f, KEY_AUDIO }, 31 { 0x0f, KEY_AUDIO },
32 { 0x10, KEY_INFO }, 32 { 0x10, KEY_INFO },
33 { 0x11, KEY_F13 }, /* 16:9 */ 33 { 0x11, KEY_F13 }, /* 16:9 */
diff --git a/drivers/media/rc/keymaps/rc-norwood.c b/drivers/media/rc/keymaps/rc-norwood.c
index 629ee9d84537..f1c1281fbc17 100644
--- a/drivers/media/rc/keymaps/rc-norwood.c
+++ b/drivers/media/rc/keymaps/rc-norwood.c
@@ -29,7 +29,7 @@ static struct rc_map_table norwood[] = {
29 { 0x28, KEY_8 }, 29 { 0x28, KEY_8 },
30 { 0x29, KEY_9 }, 30 { 0x29, KEY_9 },
31 31
32 { 0x78, KEY_TUNER }, /* Video Source */ 32 { 0x78, KEY_VIDEO }, /* Video Source */
33 { 0x2c, KEY_EXIT }, /* Open/Close software */ 33 { 0x2c, KEY_EXIT }, /* Open/Close software */
34 { 0x2a, KEY_SELECT }, /* 2 Digit Select */ 34 { 0x2a, KEY_SELECT }, /* 2 Digit Select */
35 { 0x69, KEY_AGAIN }, /* Recall */ 35 { 0x69, KEY_AGAIN }, /* Recall */
diff --git a/drivers/media/rc/keymaps/rc-pctv-sedna.c b/drivers/media/rc/keymaps/rc-pctv-sedna.c
index fa5ae5981eb8..7cdef6e6cc0f 100644
--- a/drivers/media/rc/keymaps/rc-pctv-sedna.c
+++ b/drivers/media/rc/keymaps/rc-pctv-sedna.c
@@ -36,7 +36,7 @@ static struct rc_map_table pctv_sedna[] = {
36 { 0x0e, KEY_STOP }, 36 { 0x0e, KEY_STOP },
37 { 0x0f, KEY_PREVIOUSSONG }, 37 { 0x0f, KEY_PREVIOUSSONG },
38 { 0x10, KEY_ZOOM }, 38 { 0x10, KEY_ZOOM },
39 { 0x11, KEY_TUNER }, /* Source */ 39 { 0x11, KEY_VIDEO }, /* Source */
40 { 0x12, KEY_POWER }, 40 { 0x12, KEY_POWER },
41 { 0x13, KEY_MUTE }, 41 { 0x13, KEY_MUTE },
42 { 0x15, KEY_CHANNELDOWN }, 42 { 0x15, KEY_CHANNELDOWN },
diff --git a/drivers/media/rc/keymaps/rc-pixelview-mk12.c b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
index 8d9f664e0a2d..125fc3949c15 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-mk12.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-mk12.c
@@ -34,7 +34,7 @@ static struct rc_map_table pixelview_mk12[] = {
34 { 0x866b13, KEY_AGAIN }, /* loop */ 34 { 0x866b13, KEY_AGAIN }, /* loop */
35 { 0x866b10, KEY_DIGITS }, /* +100 */ 35 { 0x866b10, KEY_DIGITS }, /* +100 */
36 36
37 { 0x866b00, KEY_MEDIA }, /* source */ 37 { 0x866b00, KEY_VIDEO }, /* source */
38 { 0x866b18, KEY_MUTE }, /* mute */ 38 { 0x866b18, KEY_MUTE }, /* mute */
39 { 0x866b19, KEY_CAMERA }, /* snapshot */ 39 { 0x866b19, KEY_CAMERA }, /* snapshot */
40 { 0x866b1a, KEY_SEARCH }, /* scan */ 40 { 0x866b1a, KEY_SEARCH }, /* scan */
diff --git a/drivers/media/rc/keymaps/rc-pixelview-new.c b/drivers/media/rc/keymaps/rc-pixelview-new.c
index 777a70076be2..bd78d6ac1e16 100644
--- a/drivers/media/rc/keymaps/rc-pixelview-new.c
+++ b/drivers/media/rc/keymaps/rc-pixelview-new.c
@@ -33,7 +33,7 @@ static struct rc_map_table pixelview_new[] = {
33 { 0x3e, KEY_0 }, 33 { 0x3e, KEY_0 },
34 34
35 { 0x1c, KEY_AGAIN }, /* LOOP */ 35 { 0x1c, KEY_AGAIN }, /* LOOP */
36 { 0x3f, KEY_MEDIA }, /* Source */ 36 { 0x3f, KEY_VIDEO }, /* Source */
37 { 0x1f, KEY_LAST }, /* +100 */ 37 { 0x1f, KEY_LAST }, /* +100 */
38 { 0x1b, KEY_MUTE }, 38 { 0x1b, KEY_MUTE },
39 39
diff --git a/drivers/media/rc/keymaps/rc-pixelview.c b/drivers/media/rc/keymaps/rc-pixelview.c
index 0ec5988916b9..06187e7db446 100644
--- a/drivers/media/rc/keymaps/rc-pixelview.c
+++ b/drivers/media/rc/keymaps/rc-pixelview.c
@@ -15,7 +15,7 @@
15static struct rc_map_table pixelview[] = { 15static struct rc_map_table pixelview[] = {
16 16
17 { 0x1e, KEY_POWER }, /* power */ 17 { 0x1e, KEY_POWER }, /* power */
18 { 0x07, KEY_MEDIA }, /* source */ 18 { 0x07, KEY_VIDEO }, /* source */
19 { 0x1c, KEY_SEARCH }, /* scan */ 19 { 0x1c, KEY_SEARCH }, /* scan */
20 20
21 21
diff --git a/drivers/media/rc/keymaps/rc-pv951.c b/drivers/media/rc/keymaps/rc-pv951.c
index 83a418de12c6..5e8beee94de4 100644
--- a/drivers/media/rc/keymaps/rc-pv951.c
+++ b/drivers/media/rc/keymaps/rc-pv951.c
@@ -46,10 +46,10 @@ static struct rc_map_table pv951[] = {
46 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */ 46 { 0x0c, KEY_SEARCH }, /* AUTOSCAN */
47 47
48 /* Not sure what to do with these ones! */ 48 /* Not sure what to do with these ones! */
49 { 0x0f, KEY_SELECT }, /* SOURCE */ 49 { 0x0f, KEY_VIDEO }, /* SOURCE */
50 { 0x0a, KEY_KPPLUS }, /* +100 */ 50 { 0x0a, KEY_KPPLUS }, /* +100 */
51 { 0x14, KEY_EQUAL }, /* SYNC */ 51 { 0x14, KEY_EQUAL }, /* SYNC */
52 { 0x1c, KEY_MEDIA }, /* PC/TV */ 52 { 0x1c, KEY_TV }, /* PC/TV */
53}; 53};
54 54
55static struct rc_map_list pv951_map = { 55static struct rc_map_list pv951_map = {
diff --git a/drivers/media/rc/keymaps/rc-rc5-tv.c b/drivers/media/rc/keymaps/rc-rc5-tv.c
deleted file mode 100644
index 4fcef9f1f721..000000000000
--- a/drivers/media/rc/keymaps/rc-rc5-tv.c
+++ /dev/null
@@ -1,81 +0,0 @@
1/* rc5-tv.h - Keytable for rc5_tv Remote Controller
2 *
3 * keymap imported from ir-keymaps.c
4 *
5 * Copyright (c) 2010 by Mauro Carvalho Chehab <mchehab@redhat.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
13#include <media/rc-map.h>
14
15/* generic RC5 keytable */
16/* see http://users.pandora.be/nenya/electronics/rc5/codes00.htm */
17/* used by old (black) Hauppauge remotes */
18
19static struct rc_map_table rc5_tv[] = {
20 /* Keys 0 to 9 */
21 { 0x00, KEY_0 },
22 { 0x01, KEY_1 },
23 { 0x02, KEY_2 },
24 { 0x03, KEY_3 },
25 { 0x04, KEY_4 },
26 { 0x05, KEY_5 },
27 { 0x06, KEY_6 },
28 { 0x07, KEY_7 },
29 { 0x08, KEY_8 },
30 { 0x09, KEY_9 },
31
32 { 0x0b, KEY_CHANNEL }, /* channel / program (japan: 11) */
33 { 0x0c, KEY_POWER }, /* standby */
34 { 0x0d, KEY_MUTE }, /* mute / demute */
35 { 0x0f, KEY_TV }, /* display */
36 { 0x10, KEY_VOLUMEUP },
37 { 0x11, KEY_VOLUMEDOWN },
38 { 0x12, KEY_BRIGHTNESSUP },
39 { 0x13, KEY_BRIGHTNESSDOWN },
40 { 0x1e, KEY_SEARCH }, /* search + */
41 { 0x20, KEY_CHANNELUP }, /* channel / program + */
42 { 0x21, KEY_CHANNELDOWN }, /* channel / program - */
43 { 0x22, KEY_CHANNEL }, /* alt / channel */
44 { 0x23, KEY_LANGUAGE }, /* 1st / 2nd language */
45 { 0x26, KEY_SLEEP }, /* sleeptimer */
46 { 0x2e, KEY_MENU }, /* 2nd controls (USA: menu) */
47 { 0x30, KEY_PAUSE },
48 { 0x32, KEY_REWIND },
49 { 0x33, KEY_GOTO },
50 { 0x35, KEY_PLAY },
51 { 0x36, KEY_STOP },
52 { 0x37, KEY_RECORD }, /* recording */
53 { 0x3c, KEY_TEXT }, /* teletext submode (Japan: 12) */
54 { 0x3d, KEY_SUSPEND }, /* system standby */
55
56};
57
58static struct rc_map_list rc5_tv_map = {
59 .map = {
60 .scan = rc5_tv,
61 .size = ARRAY_SIZE(rc5_tv),
62 .rc_type = RC_TYPE_UNKNOWN, /* Legacy IR type */
63 .name = RC_MAP_RC5_TV,
64 }
65};
66
67static int __init init_rc_map_rc5_tv(void)
68{
69 return rc_map_register(&rc5_tv_map);
70}
71
72static void __exit exit_rc_map_rc5_tv(void)
73{
74 rc_map_unregister(&rc5_tv_map);
75}
76
77module_init(init_rc_map_rc5_tv)
78module_exit(exit_rc_map_rc5_tv)
79
80MODULE_LICENSE("GPL");
81MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
diff --git a/drivers/media/rc/keymaps/rc-rc6-mce.c b/drivers/media/rc/keymaps/rc-rc6-mce.c
index 2f5dc0622b94..8dd519ecc58e 100644
--- a/drivers/media/rc/keymaps/rc-rc6-mce.c
+++ b/drivers/media/rc/keymaps/rc-rc6-mce.c
@@ -30,7 +30,7 @@ static struct rc_map_table rc6_mce[] = {
30 { 0x800f040a, KEY_DELETE }, 30 { 0x800f040a, KEY_DELETE },
31 { 0x800f040b, KEY_ENTER }, 31 { 0x800f040b, KEY_ENTER },
32 { 0x800f040c, KEY_POWER }, /* PC Power */ 32 { 0x800f040c, KEY_POWER }, /* PC Power */
33 { 0x800f040d, KEY_PROG1 }, /* Windows MCE button */ 33 { 0x800f040d, KEY_LEFTMETA }, /* Windows MCE button */
34 { 0x800f040e, KEY_MUTE }, 34 { 0x800f040e, KEY_MUTE },
35 { 0x800f040f, KEY_INFO }, 35 { 0x800f040f, KEY_INFO },
36 36
diff --git a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
index 2d14598592d8..6813d1102118 100644
--- a/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
+++ b/drivers/media/rc/keymaps/rc-real-audio-220-32-keys.c
@@ -35,7 +35,7 @@ static struct rc_map_table real_audio_220_32_keys[] = {
35 { 0x15, KEY_CHANNELDOWN}, 35 { 0x15, KEY_CHANNELDOWN},
36 { 0x16, KEY_ENTER}, 36 { 0x16, KEY_ENTER},
37 37
38 { 0x11, KEY_LIST}, /* Source */ 38 { 0x11, KEY_VIDEO}, /* Source */
39 { 0x0d, KEY_AUDIO}, /* stereo */ 39 { 0x0d, KEY_AUDIO}, /* stereo */
40 40
41 { 0x0f, KEY_PREVIOUS}, /* Prev */ 41 { 0x0f, KEY_PREVIOUS}, /* Prev */
diff --git a/drivers/media/rc/keymaps/rc-technisat-usb2.c b/drivers/media/rc/keymaps/rc-technisat-usb2.c
new file mode 100644
index 000000000000..4afe5774f192
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-technisat-usb2.c
@@ -0,0 +1,93 @@
1/* rc-technisat-usb2.c - Keytable for SkyStar HD USB
2 *
3 * Copyright (C) 2010 Patrick Boettcher,
4 * Kernel Labs Inc. PO Box 745, St James, NY 11780
5 *
6 * Development was sponsored by Technisat Digital UK Limited, whose
7 * registered office is Witan Gate House 500 - 600 Witan Gate West,
8 * Milton Keynes, MK9 1SH
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; either version 2 of the
13 * License, or (at your option) any later version.
14 *
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 * THIS PROGRAM IS PROVIDED "AS IS" AND BOTH THE COPYRIGHT HOLDER AND
21 * TECHNISAT DIGITAL UK LTD DISCLAIM ALL WARRANTIES WITH REGARD TO
22 * THIS PROGRAM INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY OR
23 * FITNESS FOR A PARTICULAR PURPOSE. NEITHER THE COPYRIGHT HOLDER
24 * NOR TECHNISAT DIGITAL UK LIMITED SHALL BE LIABLE FOR ANY SPECIAL,
25 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
26 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
27 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
28 * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS PROGRAM. See the
29 * GNU General Public License for more details.
30 */
31
32#include <media/rc-map.h>
33
34static struct rc_map_table technisat_usb2[] = {
35 {0x0a0c, KEY_POWER},
36 {0x0a01, KEY_1},
37 {0x0a02, KEY_2},
38 {0x0a03, KEY_3},
39 {0x0a0d, KEY_MUTE},
40 {0x0a04, KEY_4},
41 {0x0a05, KEY_5},
42 {0x0a06, KEY_6},
43 {0x0a38, KEY_VIDEO}, /* EXT */
44 {0x0a07, KEY_7},
45 {0x0a08, KEY_8},
46 {0x0a09, KEY_9},
47 {0x0a00, KEY_0},
48 {0x0a4f, KEY_INFO},
49 {0x0a20, KEY_CHANNELUP},
50 {0x0a52, KEY_MENU},
51 {0x0a11, KEY_VOLUMEUP},
52 {0x0a57, KEY_OK},
53 {0x0a10, KEY_VOLUMEDOWN},
54 {0x0a2f, KEY_EPG},
55 {0x0a21, KEY_CHANNELDOWN},
56 {0x0a22, KEY_REFRESH},
57 {0x0a3c, KEY_TEXT},
58 {0x0a76, KEY_ENTER}, /* HOOK */
59 {0x0a0f, KEY_HELP},
60 {0x0a6b, KEY_RED},
61 {0x0a6c, KEY_GREEN},
62 {0x0a6d, KEY_YELLOW},
63 {0x0a6e, KEY_BLUE},
64 {0x0a29, KEY_STOP},
65 {0x0a23, KEY_LANGUAGE},
66 {0x0a53, KEY_TV},
67 {0x0a0a, KEY_PROGRAM},
68};
69
70static struct rc_map_list technisat_usb2_map = {
71 .map = {
72 .scan = technisat_usb2,
73 .size = ARRAY_SIZE(technisat_usb2),
74 .rc_type = RC_TYPE_RC5,
75 .name = RC_MAP_TECHNISAT_USB2,
76 }
77};
78
79static int __init init_rc_map(void)
80{
81 return rc_map_register(&technisat_usb2_map);
82}
83
84static void __exit exit_rc_map(void)
85{
86 rc_map_unregister(&technisat_usb2_map);
87}
88
89module_init(init_rc_map)
90module_exit(exit_rc_map)
91
92MODULE_AUTHOR("Patrick Boettcher <pboettcher@kernellabs.com>");
93MODULE_LICENSE("GPL");
diff --git a/drivers/media/rc/keymaps/rc-terratec-slim-2.c b/drivers/media/rc/keymaps/rc-terratec-slim-2.c
new file mode 100644
index 000000000000..44093918cf03
--- /dev/null
+++ b/drivers/media/rc/keymaps/rc-terratec-slim-2.c
@@ -0,0 +1,72 @@
1/*
2 * TerraTec remote controller keytable
3 *
4 * Copyright (C) 2011 Martin Groszhauser <mgroszhauser@gmail.com>
5 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
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 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22#include <media/rc-map.h>
23
24/*
25 * TerraTec slim remote, 6 rows, 3 columns.
26 * Keytable from Martin Groszhauser <mgroszhauser@gmail.com>
27 */
28static struct rc_map_table terratec_slim_2[] = {
29 { 0x8001, KEY_MUTE }, /* MUTE */
30 { 0x8002, KEY_VOLUMEDOWN },
31 { 0x8003, KEY_CHANNELDOWN },
32 { 0x8004, KEY_1 },
33 { 0x8005, KEY_2 },
34 { 0x8006, KEY_3 },
35 { 0x8007, KEY_4 },
36 { 0x8008, KEY_5 },
37 { 0x8009, KEY_6 },
38 { 0x800a, KEY_7 },
39 { 0x800c, KEY_ZOOM }, /* [fullscreen] */
40 { 0x800d, KEY_0 },
41 { 0x800e, KEY_AGAIN }, /* [two arrows forming a circle] */
42 { 0x8012, KEY_POWER2 }, /* [red power button] */
43 { 0x801a, KEY_VOLUMEUP },
44 { 0x801b, KEY_8 },
45 { 0x801e, KEY_CHANNELUP },
46 { 0x801f, KEY_9 },
47};
48
49static struct rc_map_list terratec_slim_2_map = {
50 .map = {
51 .scan = terratec_slim_2,
52 .size = ARRAY_SIZE(terratec_slim_2),
53 .rc_type = RC_TYPE_NEC,
54 .name = RC_MAP_TERRATEC_SLIM_2,
55 }
56};
57
58static int __init init_rc_map_terratec_slim_2(void)
59{
60 return rc_map_register(&terratec_slim_2_map);
61}
62
63static void __exit exit_rc_map_terratec_slim_2(void)
64{
65 rc_map_unregister(&terratec_slim_2_map);
66}
67
68module_init(init_rc_map_terratec_slim_2)
69module_exit(exit_rc_map_terratec_slim_2)
70
71MODULE_LICENSE("GPL");
72MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
diff --git a/drivers/media/rc/keymaps/rc-winfast.c b/drivers/media/rc/keymaps/rc-winfast.c
index 2747db43b70c..0062ca291959 100644
--- a/drivers/media/rc/keymaps/rc-winfast.c
+++ b/drivers/media/rc/keymaps/rc-winfast.c
@@ -27,15 +27,15 @@ static struct rc_map_table winfast[] = {
27 { 0x0e, KEY_8 }, 27 { 0x0e, KEY_8 },
28 { 0x0f, KEY_9 }, 28 { 0x0f, KEY_9 },
29 29
30 { 0x00, KEY_POWER }, 30 { 0x00, KEY_POWER2 },
31 { 0x1b, KEY_AUDIO }, /* Audio Source */ 31 { 0x1b, KEY_AUDIO }, /* Audio Source */
32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */ 32 { 0x02, KEY_TUNER }, /* TV/FM, not on Y0400052 */
33 { 0x1e, KEY_VIDEO }, /* Video Source */ 33 { 0x1e, KEY_VIDEO }, /* Video Source */
34 { 0x16, KEY_INFO }, /* Display information */ 34 { 0x16, KEY_INFO }, /* Display information */
35 { 0x04, KEY_VOLUMEUP }, 35 { 0x04, KEY_LEFT },
36 { 0x08, KEY_VOLUMEDOWN }, 36 { 0x08, KEY_RIGHT },
37 { 0x0c, KEY_CHANNELUP }, 37 { 0x0c, KEY_UP },
38 { 0x10, KEY_CHANNELDOWN }, 38 { 0x10, KEY_DOWN },
39 { 0x03, KEY_ZOOM }, /* fullscreen */ 39 { 0x03, KEY_ZOOM }, /* fullscreen */
40 { 0x1f, KEY_TEXT }, /* closed caption/teletext */ 40 { 0x1f, KEY_TEXT }, /* closed caption/teletext */
41 { 0x20, KEY_SLEEP }, 41 { 0x20, KEY_SLEEP },
@@ -47,7 +47,7 @@ static struct rc_map_table winfast[] = {
47 { 0x2e, KEY_BLUE }, 47 { 0x2e, KEY_BLUE },
48 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */ 48 { 0x18, KEY_KPPLUS }, /* fine tune + , not on Y040052 */
49 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */ 49 { 0x19, KEY_KPMINUS }, /* fine tune - , not on Y040052 */
50 { 0x2a, KEY_MEDIA }, /* PIP (Picture in picture */ 50 { 0x2a, KEY_TV2 }, /* PIP (Picture in picture */
51 { 0x21, KEY_DOT }, 51 { 0x21, KEY_DOT },
52 { 0x13, KEY_ENTER }, 52 { 0x13, KEY_ENTER },
53 { 0x11, KEY_LAST }, /* Recall (last channel */ 53 { 0x11, KEY_LAST }, /* Recall (last channel */
@@ -57,7 +57,7 @@ static struct rc_map_table winfast[] = {
57 { 0x25, KEY_TIME }, /* Time Shifting */ 57 { 0x25, KEY_TIME }, /* Time Shifting */
58 { 0x26, KEY_STOP }, 58 { 0x26, KEY_STOP },
59 { 0x27, KEY_RECORD }, 59 { 0x27, KEY_RECORD },
60 { 0x28, KEY_SAVE }, /* Screenshot */ 60 { 0x28, KEY_CAMERA }, /* Screenshot */
61 { 0x2f, KEY_MENU }, 61 { 0x2f, KEY_MENU },
62 { 0x30, KEY_CANCEL }, 62 { 0x30, KEY_CANCEL },
63 { 0x31, KEY_CHANNEL }, /* Channel Surf */ 63 { 0x31, KEY_CHANNEL }, /* Channel Surf */
@@ -70,10 +70,10 @@ static struct rc_map_table winfast[] = {
70 { 0x38, KEY_DVD }, 70 { 0x38, KEY_DVD },
71 71
72 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */ 72 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
73 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ 73 { 0x3e, KEY_VOLUMEUP }, /* MCE +VOL, on Y04G0033 */
74 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ 74 { 0x3a, KEY_VOLUMEDOWN }, /* MCE -VOL, on Y04G0033 */
75 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ 75 { 0x3b, KEY_CHANNELUP }, /* MCE +CH, on Y04G0033 */
76 { 0x3f, KEY_F24 } /* MCE -CH, on Y04G0033 */ 76 { 0x3f, KEY_CHANNELDOWN } /* MCE -CH, on Y04G0033 */
77}; 77};
78 78
79static struct rc_map_list winfast_map = { 79static struct rc_map_list winfast_map = {
diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c
index e4f8eac7f717..044fb7a382d6 100644
--- a/drivers/media/rc/mceusb.c
+++ b/drivers/media/rc/mceusb.c
@@ -186,7 +186,7 @@ static const struct mceusb_model mceusb_model[] = {
186 * remotes, but we should have something handy, 186 * remotes, but we should have something handy,
187 * to allow testing it 187 * to allow testing it
188 */ 188 */
189 .rc_map = RC_MAP_RC5_HAUPPAUGE_NEW, 189 .rc_map = RC_MAP_HAUPPAUGE,
190 .name = "Conexant Hybrid TV (cx231xx) MCE IR", 190 .name = "Conexant Hybrid TV (cx231xx) MCE IR",
191 }, 191 },
192 [CX_HYBRID_TV] = { 192 [CX_HYBRID_TV] = {
@@ -261,7 +261,7 @@ static struct usb_device_id mceusb_dev_table[] = {
261 .driver_info = MCE_GEN2_TX_INV }, 261 .driver_info = MCE_GEN2_TX_INV },
262 /* Topseed eHome Infrared Transceiver */ 262 /* Topseed eHome Infrared Transceiver */
263 { USB_DEVICE(VENDOR_TOPSEED, 0x0011), 263 { USB_DEVICE(VENDOR_TOPSEED, 0x0011),
264 .driver_info = MCE_GEN2_TX_INV }, 264 .driver_info = MCE_GEN3 },
265 /* Ricavision internal Infrared Transceiver */ 265 /* Ricavision internal Infrared Transceiver */
266 { USB_DEVICE(VENDOR_RICAVISION, 0x0010) }, 266 { USB_DEVICE(VENDOR_RICAVISION, 0x0010) },
267 /* Itron ione Libra Q-11 */ 267 /* Itron ione Libra Q-11 */
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index aa021600e9df..4498b944dec8 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -42,8 +42,30 @@ config VIDEO_TUNER
42 42
43config V4L2_MEM2MEM_DEV 43config V4L2_MEM2MEM_DEV
44 tristate 44 tristate
45 depends on VIDEOBUF_GEN 45 depends on VIDEOBUF2_CORE
46 46
47config VIDEOBUF2_CORE
48 tristate
49
50config VIDEOBUF2_MEMOPS
51 tristate
52
53config VIDEOBUF2_DMA_CONTIG
54 select VIDEOBUF2_CORE
55 select VIDEOBUF2_MEMOPS
56 tristate
57
58config VIDEOBUF2_VMALLOC
59 select VIDEOBUF2_CORE
60 select VIDEOBUF2_MEMOPS
61 tristate
62
63
64config VIDEOBUF2_DMA_SG
65 #depends on HAS_DMA
66 select VIDEOBUF2_CORE
67 select VIDEOBUF2_MEMOPS
68 tristate
47# 69#
48# Multimedia Video device configuration 70# Multimedia Video device configuration
49# 71#
@@ -527,7 +549,7 @@ config VIDEO_VIVI
527 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64 549 depends on VIDEO_DEV && VIDEO_V4L2 && !SPARC32 && !SPARC64
528 depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE 550 depends on FRAMEBUFFER_CONSOLE || STI_CONSOLE
529 select FONT_8x16 551 select FONT_8x16
530 select VIDEOBUF_VMALLOC 552 select VIDEOBUF2_VMALLOC
531 default n 553 default n
532 ---help--- 554 ---help---
533 Enables a virtual video driver. This device shows a color bar 555 Enables a virtual video driver. This device shows a color bar
@@ -718,10 +740,30 @@ config VIDEO_VIA_CAMERA
718 Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems 740 Chrome9 chipsets. Currently only tested on OLPC xo-1.5 systems
719 with ov7670 sensors. 741 with ov7670 sensors.
720 742
743config VIDEO_NOON010PC30
744 tristate "NOON010PC30 CIF camera sensor support"
745 depends on I2C && VIDEO_V4L2
746 ---help---
747 This driver supports NOON010PC30 CIF camera from Siliconfile
748
749config VIDEO_OMAP3
750 tristate "OMAP 3 Camera support (EXPERIMENTAL)"
751 select OMAP_IOMMU
752 depends on VIDEO_V4L2 && I2C && VIDEO_V4L2_SUBDEV_API && ARCH_OMAP3 && EXPERIMENTAL
753 ---help---
754 Driver for an OMAP 3 camera controller.
755
756config VIDEO_OMAP3_DEBUG
757 bool "OMAP 3 Camera debug messages"
758 depends on VIDEO_OMAP3
759 ---help---
760 Enable debug messages on OMAP 3 camera controller driver.
761
721config SOC_CAMERA 762config SOC_CAMERA
722 tristate "SoC camera support" 763 tristate "SoC camera support"
723 depends on VIDEO_V4L2 && HAS_DMA && I2C 764 depends on VIDEO_V4L2 && HAS_DMA && I2C
724 select VIDEOBUF_GEN 765 select VIDEOBUF_GEN
766 select VIDEOBUF2_CORE
725 help 767 help
726 SoC Camera is a common API to several cameras, not connecting 768 SoC Camera is a common API to several cameras, not connecting
727 over a bus like PCI or USB. For example some i2c camera connected 769 over a bus like PCI or USB. For example some i2c camera connected
@@ -809,6 +851,12 @@ config SOC_CAMERA_OV9640
809 help 851 help
810 This is a ov9640 camera driver 852 This is a ov9640 camera driver
811 853
854config SOC_CAMERA_OV9740
855 tristate "ov9740 camera support"
856 depends on SOC_CAMERA && I2C
857 help
858 This is a ov9740 camera driver
859
812config MX1_VIDEO 860config MX1_VIDEO
813 bool 861 bool
814 862
@@ -848,7 +896,7 @@ config VIDEO_SH_MOBILE_CSI2
848config VIDEO_SH_MOBILE_CEU 896config VIDEO_SH_MOBILE_CEU
849 tristate "SuperH Mobile CEU Interface driver" 897 tristate "SuperH Mobile CEU Interface driver"
850 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK 898 depends on VIDEO_DEV && SOC_CAMERA && HAS_DMA && HAVE_CLK
851 select VIDEOBUF_DMA_CONTIG 899 select VIDEOBUF2_DMA_CONTIG
852 ---help--- 900 ---help---
853 This is a v4l2 driver for the SuperH Mobile CEU Interface 901 This is a v4l2 driver for the SuperH Mobile CEU Interface
854 902
@@ -967,7 +1015,7 @@ if V4L_MEM2MEM_DRIVERS
967config VIDEO_MEM2MEM_TESTDEV 1015config VIDEO_MEM2MEM_TESTDEV
968 tristate "Virtual test device for mem2mem framework" 1016 tristate "Virtual test device for mem2mem framework"
969 depends on VIDEO_DEV && VIDEO_V4L2 1017 depends on VIDEO_DEV && VIDEO_V4L2
970 select VIDEOBUF_VMALLOC 1018 select VIDEOBUF2_VMALLOC
971 select V4L2_MEM2MEM_DEV 1019 select V4L2_MEM2MEM_DEV
972 default n 1020 default n
973 ---help--- 1021 ---help---
@@ -977,7 +1025,7 @@ config VIDEO_MEM2MEM_TESTDEV
977config VIDEO_SAMSUNG_S5P_FIMC 1025config VIDEO_SAMSUNG_S5P_FIMC
978 tristate "Samsung S5P FIMC (video postprocessor) driver" 1026 tristate "Samsung S5P FIMC (video postprocessor) driver"
979 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P 1027 depends on VIDEO_DEV && VIDEO_V4L2 && PLAT_S5P
980 select VIDEOBUF_DMA_CONTIG 1028 select VIDEOBUF2_DMA_CONTIG
981 select V4L2_MEM2MEM_DEV 1029 select V4L2_MEM2MEM_DEV
982 help 1030 help
983 This is a v4l2 driver for the S5P camera interface 1031 This is a v4l2 driver for the S5P camera interface
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index a509d317e258..ace5d8b57221 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -11,7 +11,7 @@ stkwebcam-objs := stk-webcam.o stk-sensor.o
11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o 11omap2cam-objs := omap24xxcam.o omap24xxcam-dma.o
12 12
13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \ 13videodev-objs := v4l2-dev.o v4l2-ioctl.o v4l2-device.o v4l2-fh.o \
14 v4l2-event.o v4l2-ctrls.o 14 v4l2-event.o v4l2-ctrls.o v4l2-subdev.o
15 15
16# V4L2 core modules 16# V4L2 core modules
17 17
@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_TCM825X) += tcm825x.o
67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o 67obj-$(CONFIG_VIDEO_TVEEPROM) += tveeprom.o
68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o 68obj-$(CONFIG_VIDEO_MT9V011) += mt9v011.o
69obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 69obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
70obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
70 71
71obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o 72obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
72obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o 73obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o
@@ -78,6 +79,7 @@ obj-$(CONFIG_SOC_CAMERA_OV2640) += ov2640.o
78obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o 79obj-$(CONFIG_SOC_CAMERA_OV6650) += ov6650.o
79obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o 80obj-$(CONFIG_SOC_CAMERA_OV772X) += ov772x.o
80obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o 81obj-$(CONFIG_SOC_CAMERA_OV9640) += ov9640.o
82obj-$(CONFIG_SOC_CAMERA_OV9740) += ov9740.o
81obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o 83obj-$(CONFIG_SOC_CAMERA_RJ54N1) += rj54n1cb0c.o
82obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o 84obj-$(CONFIG_SOC_CAMERA_TW9910) += tw9910.o
83 85
@@ -111,6 +113,12 @@ obj-$(CONFIG_VIDEOBUF_VMALLOC) += videobuf-vmalloc.o
111obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o 113obj-$(CONFIG_VIDEOBUF_DVB) += videobuf-dvb.o
112obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o 114obj-$(CONFIG_VIDEO_BTCX) += btcx-risc.o
113 115
116obj-$(CONFIG_VIDEOBUF2_CORE) += videobuf2-core.o
117obj-$(CONFIG_VIDEOBUF2_MEMOPS) += videobuf2-memops.o
118obj-$(CONFIG_VIDEOBUF2_VMALLOC) += videobuf2-vmalloc.o
119obj-$(CONFIG_VIDEOBUF2_DMA_CONTIG) += videobuf2-dma-contig.o
120obj-$(CONFIG_VIDEOBUF2_DMA_SG) += videobuf2-dma-sg.o
121
114obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o 122obj-$(CONFIG_V4L2_MEM2MEM_DEV) += v4l2-mem2mem.o
115 123
116obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o 124obj-$(CONFIG_VIDEO_M32R_AR_M64278) += arv.o
@@ -121,6 +129,8 @@ obj-$(CONFIG_VIDEO_CAFE_CCIC) += cafe_ccic.o
121 129
122obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o 130obj-$(CONFIG_VIDEO_VIA_CAMERA) += via-camera.o
123 131
132obj-$(CONFIG_VIDEO_OMAP3) += omap3isp/
133
124obj-$(CONFIG_USB_ZR364XX) += zr364xx.o 134obj-$(CONFIG_USB_ZR364XX) += zr364xx.o
125obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o 135obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o
126 136
diff --git a/drivers/media/video/adv7343.c b/drivers/media/video/adv7343.c
index 41b2930d0ce4..021fab23070d 100644
--- a/drivers/media/video/adv7343.c
+++ b/drivers/media/video/adv7343.c
@@ -29,6 +29,7 @@
29#include <media/adv7343.h> 29#include <media/adv7343.h>
30#include <media/v4l2-device.h> 30#include <media/v4l2-device.h>
31#include <media/v4l2-chip-ident.h> 31#include <media/v4l2-chip-ident.h>
32#include <media/v4l2-ctrls.h>
32 33
33#include "adv7343_regs.h" 34#include "adv7343_regs.h"
34 35
@@ -41,15 +42,13 @@ MODULE_PARM_DESC(debug, "Debug level 0-1");
41 42
42struct adv7343_state { 43struct adv7343_state {
43 struct v4l2_subdev sd; 44 struct v4l2_subdev sd;
45 struct v4l2_ctrl_handler hdl;
44 u8 reg00; 46 u8 reg00;
45 u8 reg01; 47 u8 reg01;
46 u8 reg02; 48 u8 reg02;
47 u8 reg35; 49 u8 reg35;
48 u8 reg80; 50 u8 reg80;
49 u8 reg82; 51 u8 reg82;
50 int bright;
51 int hue;
52 int gain;
53 u32 output; 52 u32 output;
54 v4l2_std_id std; 53 v4l2_std_id std;
55}; 54};
@@ -59,6 +58,11 @@ static inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
59 return container_of(sd, struct adv7343_state, sd); 58 return container_of(sd, struct adv7343_state, sd);
60} 59}
61 60
61static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
62{
63 return &container_of(ctrl->handler, struct adv7343_state, hdl)->sd;
64}
65
62static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value) 66static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
63{ 67{
64 struct i2c_client *client = v4l2_get_subdevdata(sd); 68 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -268,111 +272,22 @@ static int adv7343_log_status(struct v4l2_subdev *sd)
268 return 0; 272 return 0;
269} 273}
270 274
271static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 275static int adv7343_s_ctrl(struct v4l2_ctrl *ctrl)
272{
273 switch (qc->id) {
274 case V4L2_CID_BRIGHTNESS:
275 return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN,
276 ADV7343_BRIGHTNESS_MAX, 1,
277 ADV7343_BRIGHTNESS_DEF);
278 case V4L2_CID_HUE:
279 return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN,
280 ADV7343_HUE_MAX, 1 ,
281 ADV7343_HUE_DEF);
282 case V4L2_CID_GAIN:
283 return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN,
284 ADV7343_GAIN_MAX, 1,
285 ADV7343_GAIN_DEF);
286 default:
287 break;
288 }
289
290 return 0;
291}
292
293static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
294{
295 struct adv7343_state *state = to_state(sd);
296 int err = 0;
297
298 switch (ctrl->id) {
299 case V4L2_CID_BRIGHTNESS:
300 if (ctrl->value < ADV7343_BRIGHTNESS_MIN ||
301 ctrl->value > ADV7343_BRIGHTNESS_MAX) {
302 v4l2_dbg(1, debug, sd,
303 "invalid brightness settings %d\n",
304 ctrl->value);
305 return -ERANGE;
306 }
307
308 state->bright = ctrl->value;
309 err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
310 state->bright);
311 break;
312
313 case V4L2_CID_HUE:
314 if (ctrl->value < ADV7343_HUE_MIN ||
315 ctrl->value > ADV7343_HUE_MAX) {
316 v4l2_dbg(1, debug, sd, "invalid hue settings %d\n",
317 ctrl->value);
318 return -ERANGE;
319 }
320
321 state->hue = ctrl->value;
322 err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue);
323 break;
324
325 case V4L2_CID_GAIN:
326 if (ctrl->value < ADV7343_GAIN_MIN ||
327 ctrl->value > ADV7343_GAIN_MAX) {
328 v4l2_dbg(1, debug, sd, "invalid gain settings %d\n",
329 ctrl->value);
330 return -ERANGE;
331 }
332
333 if ((ctrl->value > POSITIVE_GAIN_MAX) &&
334 (ctrl->value < NEGATIVE_GAIN_MIN)) {
335 v4l2_dbg(1, debug, sd,
336 "gain settings not within the specified range\n");
337 return -ERANGE;
338 }
339
340 state->gain = ctrl->value;
341 err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain);
342 break;
343
344 default:
345 return -EINVAL;
346 }
347
348 if (err < 0)
349 v4l2_err(sd, "Failed to set the encoder controls\n");
350
351 return err;
352}
353
354static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
355{ 276{
356 struct adv7343_state *state = to_state(sd); 277 struct v4l2_subdev *sd = to_sd(ctrl);
357 278
358 switch (ctrl->id) { 279 switch (ctrl->id) {
359 case V4L2_CID_BRIGHTNESS: 280 case V4L2_CID_BRIGHTNESS:
360 ctrl->value = state->bright; 281 return adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
361 break; 282 ctrl->val);
362 283
363 case V4L2_CID_HUE: 284 case V4L2_CID_HUE:
364 ctrl->value = state->hue; 285 return adv7343_write(sd, ADV7343_SD_HUE_REG, ctrl->val);
365 break;
366 286
367 case V4L2_CID_GAIN: 287 case V4L2_CID_GAIN:
368 ctrl->value = state->gain; 288 return adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, ctrl->val);
369 break;
370
371 default:
372 return -EINVAL;
373 } 289 }
374 290 return -EINVAL;
375 return 0;
376} 291}
377 292
378static int adv7343_g_chip_ident(struct v4l2_subdev *sd, 293static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
@@ -383,12 +298,20 @@ static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
383 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0); 298 return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
384} 299}
385 300
301static const struct v4l2_ctrl_ops adv7343_ctrl_ops = {
302 .s_ctrl = adv7343_s_ctrl,
303};
304
386static const struct v4l2_subdev_core_ops adv7343_core_ops = { 305static const struct v4l2_subdev_core_ops adv7343_core_ops = {
387 .log_status = adv7343_log_status, 306 .log_status = adv7343_log_status,
388 .g_chip_ident = adv7343_g_chip_ident, 307 .g_chip_ident = adv7343_g_chip_ident,
389 .g_ctrl = adv7343_g_ctrl, 308 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
390 .s_ctrl = adv7343_s_ctrl, 309 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
391 .queryctrl = adv7343_queryctrl, 310 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
311 .g_ctrl = v4l2_subdev_g_ctrl,
312 .s_ctrl = v4l2_subdev_s_ctrl,
313 .queryctrl = v4l2_subdev_queryctrl,
314 .querymenu = v4l2_subdev_querymenu,
392}; 315};
393 316
394static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std) 317static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
@@ -468,6 +391,7 @@ static int adv7343_probe(struct i2c_client *client,
468 const struct i2c_device_id *id) 391 const struct i2c_device_id *id)
469{ 392{
470 struct adv7343_state *state; 393 struct adv7343_state *state;
394 int err;
471 395
472 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 396 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
473 return -ENODEV; 397 return -ENODEV;
@@ -490,15 +414,46 @@ static int adv7343_probe(struct i2c_client *client,
490 state->std = V4L2_STD_NTSC; 414 state->std = V4L2_STD_NTSC;
491 415
492 v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops); 416 v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
493 return adv7343_initialize(&state->sd); 417
418 v4l2_ctrl_handler_init(&state->hdl, 2);
419 v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
420 V4L2_CID_BRIGHTNESS, ADV7343_BRIGHTNESS_MIN,
421 ADV7343_BRIGHTNESS_MAX, 1,
422 ADV7343_BRIGHTNESS_DEF);
423 v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
424 V4L2_CID_HUE, ADV7343_HUE_MIN,
425 ADV7343_HUE_MAX, 1,
426 ADV7343_HUE_DEF);
427 v4l2_ctrl_new_std(&state->hdl, &adv7343_ctrl_ops,
428 V4L2_CID_GAIN, ADV7343_GAIN_MIN,
429 ADV7343_GAIN_MAX, 1,
430 ADV7343_GAIN_DEF);
431 state->sd.ctrl_handler = &state->hdl;
432 if (state->hdl.error) {
433 int err = state->hdl.error;
434
435 v4l2_ctrl_handler_free(&state->hdl);
436 kfree(state);
437 return err;
438 }
439 v4l2_ctrl_handler_setup(&state->hdl);
440
441 err = adv7343_initialize(&state->sd);
442 if (err) {
443 v4l2_ctrl_handler_free(&state->hdl);
444 kfree(state);
445 }
446 return err;
494} 447}
495 448
496static int adv7343_remove(struct i2c_client *client) 449static int adv7343_remove(struct i2c_client *client)
497{ 450{
498 struct v4l2_subdev *sd = i2c_get_clientdata(client); 451 struct v4l2_subdev *sd = i2c_get_clientdata(client);
452 struct adv7343_state *state = to_state(sd);
499 453
500 v4l2_device_unregister_subdev(sd); 454 v4l2_device_unregister_subdev(sd);
501 kfree(to_state(sd)); 455 v4l2_ctrl_handler_free(&state->hdl);
456 kfree(state);
502 457
503 return 0; 458 return 0;
504} 459}
diff --git a/drivers/media/video/adv7343_regs.h b/drivers/media/video/adv7343_regs.h
index 3431045b33da..446606764346 100644
--- a/drivers/media/video/adv7343_regs.h
+++ b/drivers/media/video/adv7343_regs.h
@@ -102,10 +102,6 @@ struct adv7343_std_info {
102 102
103/* Bit masks for DAC output levels */ 103/* Bit masks for DAC output levels */
104#define DAC_OUTPUT_LEVEL_MASK (0xFF) 104#define DAC_OUTPUT_LEVEL_MASK (0xFF)
105#define POSITIVE_GAIN_MAX (0x40)
106#define POSITIVE_GAIN_MIN (0x00)
107#define NEGATIVE_GAIN_MAX (0xFF)
108#define NEGATIVE_GAIN_MIN (0xC0)
109 105
110/* Bit masks for soft reset register */ 106/* Bit masks for soft reset register */
111#define SOFT_RESET (0x02) 107#define SOFT_RESET (0x02)
@@ -178,8 +174,8 @@ struct adv7343_std_info {
178#define ADV7343_HUE_MAX (255) 174#define ADV7343_HUE_MAX (255)
179#define ADV7343_HUE_MIN (0) 175#define ADV7343_HUE_MIN (0)
180#define ADV7343_HUE_DEF (127) 176#define ADV7343_HUE_DEF (127)
181#define ADV7343_GAIN_MAX (255) 177#define ADV7343_GAIN_MAX (64)
182#define ADV7343_GAIN_MIN (0) 178#define ADV7343_GAIN_MIN (-64)
183#define ADV7343_GAIN_DEF (0) 179#define ADV7343_GAIN_DEF (0)
184 180
185#endif 181#endif
diff --git a/drivers/media/video/au0828/au0828-cards.c b/drivers/media/video/au0828/au0828-cards.c
index 01be89fa5c78..39fc923fc46b 100644
--- a/drivers/media/video/au0828/au0828-cards.c
+++ b/drivers/media/video/au0828/au0828-cards.c
@@ -185,8 +185,7 @@ void au0828_card_setup(struct au0828_dev *dev)
185 static u8 eeprom[256]; 185 static u8 eeprom[256];
186 struct tuner_setup tun_setup; 186 struct tuner_setup tun_setup;
187 struct v4l2_subdev *sd; 187 struct v4l2_subdev *sd;
188 unsigned int mode_mask = T_ANALOG_TV | 188 unsigned int mode_mask = T_ANALOG_TV;
189 T_DIGITAL_TV;
190 189
191 dprintk(1, "%s()\n", __func__); 190 dprintk(1, "%s()\n", __func__);
192 191
diff --git a/drivers/media/video/au0828/au0828-dvb.c b/drivers/media/video/au0828/au0828-dvb.c
index f1edf1d4afe8..518216743c9c 100644
--- a/drivers/media/video/au0828/au0828-dvb.c
+++ b/drivers/media/video/au0828/au0828-dvb.c
@@ -96,7 +96,6 @@ static struct tda18271_config hauppauge_woodbury_tunerconfig = {
96/*-------------------------------------------------------------------*/ 96/*-------------------------------------------------------------------*/
97static void urb_completion(struct urb *purb) 97static void urb_completion(struct urb *purb)
98{ 98{
99 u8 *ptr;
100 struct au0828_dev *dev = purb->context; 99 struct au0828_dev *dev = purb->context;
101 int ptype = usb_pipetype(purb->pipe); 100 int ptype = usb_pipetype(purb->pipe);
102 101
@@ -114,8 +113,6 @@ static void urb_completion(struct urb *purb)
114 return; 113 return;
115 } 114 }
116 115
117 ptr = (u8 *)purb->transfer_buffer;
118
119 /* Feed the transport payload into the kernel demux */ 116 /* Feed the transport payload into the kernel demux */
120 dvb_dmx_swfilter_packets(&dev->dvb.demux, 117 dvb_dmx_swfilter_packets(&dev->dvb.demux,
121 purb->transfer_buffer, purb->actual_length / 188); 118 purb->transfer_buffer, purb->actual_length / 188);
diff --git a/drivers/media/video/au0828/au0828-video.c b/drivers/media/video/au0828/au0828-video.c
index 9c475c600fc9..6ad83a15d073 100644
--- a/drivers/media/video/au0828/au0828-video.c
+++ b/drivers/media/video/au0828/au0828-video.c
@@ -1177,10 +1177,6 @@ static int au0828_set_format(struct au0828_dev *dev, unsigned int cmd,
1177 int ret; 1177 int ret;
1178 int width = format->fmt.pix.width; 1178 int width = format->fmt.pix.width;
1179 int height = format->fmt.pix.height; 1179 int height = format->fmt.pix.height;
1180 unsigned int maxwidth, maxheight;
1181
1182 maxwidth = 720;
1183 maxheight = 480;
1184 1180
1185 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 1181 if (format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1186 return -EINVAL; 1182 return -EINVAL;
diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c
index c38300fc0b1d..f87204461cb4 100644
--- a/drivers/media/video/bt819.c
+++ b/drivers/media/video/bt819.c
@@ -37,6 +37,7 @@
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <media/v4l2-device.h> 38#include <media/v4l2-device.h>
39#include <media/v4l2-chip-ident.h> 39#include <media/v4l2-chip-ident.h>
40#include <media/v4l2-ctrls.h>
40#include <media/bt819.h> 41#include <media/bt819.h>
41 42
42MODULE_DESCRIPTION("Brooktree-819 video decoder driver"); 43MODULE_DESCRIPTION("Brooktree-819 video decoder driver");
@@ -52,16 +53,13 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
52 53
53struct bt819 { 54struct bt819 {
54 struct v4l2_subdev sd; 55 struct v4l2_subdev sd;
56 struct v4l2_ctrl_handler hdl;
55 unsigned char reg[32]; 57 unsigned char reg[32];
56 58
57 v4l2_std_id norm; 59 v4l2_std_id norm;
58 int ident; 60 int ident;
59 int input; 61 int input;
60 int enable; 62 int enable;
61 int bright;
62 int contrast;
63 int hue;
64 int sat;
65}; 63};
66 64
67static inline struct bt819 *to_bt819(struct v4l2_subdev *sd) 65static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
@@ -69,6 +67,11 @@ static inline struct bt819 *to_bt819(struct v4l2_subdev *sd)
69 return container_of(sd, struct bt819, sd); 67 return container_of(sd, struct bt819, sd);
70} 68}
71 69
70static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
71{
72 return &container_of(ctrl->handler, struct bt819, hdl)->sd;
73}
74
72struct timing { 75struct timing {
73 int hactive; 76 int hactive;
74 int hdelay; 77 int hdelay;
@@ -333,71 +336,35 @@ static int bt819_s_stream(struct v4l2_subdev *sd, int enable)
333 return 0; 336 return 0;
334} 337}
335 338
336static int bt819_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 339static int bt819_s_ctrl(struct v4l2_ctrl *ctrl)
337{
338 switch (qc->id) {
339 case V4L2_CID_BRIGHTNESS:
340 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
341 break;
342
343 case V4L2_CID_CONTRAST:
344 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
345 break;
346
347 case V4L2_CID_SATURATION:
348 v4l2_ctrl_query_fill(qc, 0, 511, 1, 256);
349 break;
350
351 case V4L2_CID_HUE:
352 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
353 break;
354
355 default:
356 return -EINVAL;
357 }
358 return 0;
359}
360
361static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
362{ 340{
341 struct v4l2_subdev *sd = to_sd(ctrl);
363 struct bt819 *decoder = to_bt819(sd); 342 struct bt819 *decoder = to_bt819(sd);
364 int temp; 343 int temp;
365 344
366 switch (ctrl->id) { 345 switch (ctrl->id) {
367 case V4L2_CID_BRIGHTNESS: 346 case V4L2_CID_BRIGHTNESS:
368 if (decoder->bright == ctrl->value) 347 bt819_write(decoder, 0x0a, ctrl->val);
369 break;
370 decoder->bright = ctrl->value;
371 bt819_write(decoder, 0x0a, decoder->bright);
372 break; 348 break;
373 349
374 case V4L2_CID_CONTRAST: 350 case V4L2_CID_CONTRAST:
375 if (decoder->contrast == ctrl->value) 351 bt819_write(decoder, 0x0c, ctrl->val & 0xff);
376 break; 352 bt819_setbit(decoder, 0x0b, 2, ((ctrl->val >> 8) & 0x01));
377 decoder->contrast = ctrl->value;
378 bt819_write(decoder, 0x0c, decoder->contrast & 0xff);
379 bt819_setbit(decoder, 0x0b, 2, ((decoder->contrast >> 8) & 0x01));
380 break; 353 break;
381 354
382 case V4L2_CID_SATURATION: 355 case V4L2_CID_SATURATION:
383 if (decoder->sat == ctrl->value) 356 bt819_write(decoder, 0x0d, (ctrl->val >> 7) & 0xff);
384 break; 357 bt819_setbit(decoder, 0x0b, 1, ((ctrl->val >> 15) & 0x01));
385 decoder->sat = ctrl->value;
386 bt819_write(decoder, 0x0d, (decoder->sat >> 7) & 0xff);
387 bt819_setbit(decoder, 0x0b, 1, ((decoder->sat >> 15) & 0x01));
388 358
389 /* Ratio between U gain and V gain must stay the same as 359 /* Ratio between U gain and V gain must stay the same as
390 the ratio between the default U and V gain values. */ 360 the ratio between the default U and V gain values. */
391 temp = (decoder->sat * 180) / 254; 361 temp = (ctrl->val * 180) / 254;
392 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff); 362 bt819_write(decoder, 0x0e, (temp >> 7) & 0xff);
393 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01); 363 bt819_setbit(decoder, 0x0b, 0, (temp >> 15) & 0x01);
394 break; 364 break;
395 365
396 case V4L2_CID_HUE: 366 case V4L2_CID_HUE:
397 if (decoder->hue == ctrl->value) 367 bt819_write(decoder, 0x0f, ctrl->val);
398 break;
399 decoder->hue = ctrl->value;
400 bt819_write(decoder, 0x0f, decoder->hue);
401 break; 368 break;
402 369
403 default: 370 default:
@@ -406,29 +373,6 @@ static int bt819_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
406 return 0; 373 return 0;
407} 374}
408 375
409static int bt819_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
410{
411 struct bt819 *decoder = to_bt819(sd);
412
413 switch (ctrl->id) {
414 case V4L2_CID_BRIGHTNESS:
415 ctrl->value = decoder->bright;
416 break;
417 case V4L2_CID_CONTRAST:
418 ctrl->value = decoder->contrast;
419 break;
420 case V4L2_CID_SATURATION:
421 ctrl->value = decoder->sat;
422 break;
423 case V4L2_CID_HUE:
424 ctrl->value = decoder->hue;
425 break;
426 default:
427 return -EINVAL;
428 }
429 return 0;
430}
431
432static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) 376static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
433{ 377{
434 struct bt819 *decoder = to_bt819(sd); 378 struct bt819 *decoder = to_bt819(sd);
@@ -439,11 +383,19 @@ static int bt819_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident
439 383
440/* ----------------------------------------------------------------------- */ 384/* ----------------------------------------------------------------------- */
441 385
386static const struct v4l2_ctrl_ops bt819_ctrl_ops = {
387 .s_ctrl = bt819_s_ctrl,
388};
389
442static const struct v4l2_subdev_core_ops bt819_core_ops = { 390static const struct v4l2_subdev_core_ops bt819_core_ops = {
443 .g_chip_ident = bt819_g_chip_ident, 391 .g_chip_ident = bt819_g_chip_ident,
444 .g_ctrl = bt819_g_ctrl, 392 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
445 .s_ctrl = bt819_s_ctrl, 393 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
446 .queryctrl = bt819_queryctrl, 394 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
395 .g_ctrl = v4l2_subdev_g_ctrl,
396 .s_ctrl = v4l2_subdev_s_ctrl,
397 .queryctrl = v4l2_subdev_queryctrl,
398 .querymenu = v4l2_subdev_querymenu,
447 .s_std = bt819_s_std, 399 .s_std = bt819_s_std,
448}; 400};
449 401
@@ -505,23 +457,40 @@ static int bt819_probe(struct i2c_client *client,
505 decoder->norm = V4L2_STD_NTSC; 457 decoder->norm = V4L2_STD_NTSC;
506 decoder->input = 0; 458 decoder->input = 0;
507 decoder->enable = 1; 459 decoder->enable = 1;
508 decoder->bright = 0;
509 decoder->contrast = 0xd8; /* 100% of original signal */
510 decoder->hue = 0;
511 decoder->sat = 0xfe; /* 100% of original signal */
512 460
513 i = bt819_init(sd); 461 i = bt819_init(sd);
514 if (i < 0) 462 if (i < 0)
515 v4l2_dbg(1, debug, sd, "init status %d\n", i); 463 v4l2_dbg(1, debug, sd, "init status %d\n", i);
464
465 v4l2_ctrl_handler_init(&decoder->hdl, 4);
466 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
467 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
468 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
469 V4L2_CID_CONTRAST, 0, 511, 1, 0xd8);
470 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
471 V4L2_CID_SATURATION, 0, 511, 1, 0xfe);
472 v4l2_ctrl_new_std(&decoder->hdl, &bt819_ctrl_ops,
473 V4L2_CID_HUE, -128, 127, 1, 0);
474 sd->ctrl_handler = &decoder->hdl;
475 if (decoder->hdl.error) {
476 int err = decoder->hdl.error;
477
478 v4l2_ctrl_handler_free(&decoder->hdl);
479 kfree(decoder);
480 return err;
481 }
482 v4l2_ctrl_handler_setup(&decoder->hdl);
516 return 0; 483 return 0;
517} 484}
518 485
519static int bt819_remove(struct i2c_client *client) 486static int bt819_remove(struct i2c_client *client)
520{ 487{
521 struct v4l2_subdev *sd = i2c_get_clientdata(client); 488 struct v4l2_subdev *sd = i2c_get_clientdata(client);
489 struct bt819 *decoder = to_bt819(sd);
522 490
523 v4l2_device_unregister_subdev(sd); 491 v4l2_device_unregister_subdev(sd);
524 kfree(to_bt819(sd)); 492 v4l2_ctrl_handler_free(&decoder->hdl);
493 kfree(decoder);
525 return 0; 494 return 0;
526} 495}
527 496
diff --git a/drivers/media/video/bt8xx/bttv-cards.c b/drivers/media/video/bt8xx/bttv-cards.c
index 7f58756d72c8..242f0d512238 100644
--- a/drivers/media/video/bt8xx/bttv-cards.c
+++ b/drivers/media/video/bt8xx/bttv-cards.c
@@ -3616,7 +3616,7 @@ void __devinit bttv_init_tuner(struct bttv *btv)
3616 &btv->c.i2c_adap, "tuner", 3616 &btv->c.i2c_adap, "tuner",
3617 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD)); 3617 0, v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
3618 3618
3619 tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV; 3619 tun_setup.mode_mask = T_ANALOG_TV;
3620 tun_setup.type = btv->tuner_type; 3620 tun_setup.type = btv->tuner_type;
3621 tun_setup.addr = addr; 3621 tun_setup.addr = addr;
3622 3622
diff --git a/drivers/media/video/bt8xx/bttv-input.c b/drivers/media/video/bt8xx/bttv-input.c
index e8b64bca9db2..677d70c0e1ce 100644
--- a/drivers/media/video/bt8xx/bttv-input.c
+++ b/drivers/media/video/bt8xx/bttv-input.c
@@ -193,12 +193,10 @@ static void bttv_rc5_timer_end(unsigned long data)
193{ 193{
194 struct bttv_ir *ir = (struct bttv_ir *)data; 194 struct bttv_ir *ir = (struct bttv_ir *)data;
195 struct timeval tv; 195 struct timeval tv;
196 unsigned long current_jiffies;
197 u32 gap; 196 u32 gap;
198 u32 rc5 = 0; 197 u32 rc5 = 0;
199 198
200 /* get time */ 199 /* get time */
201 current_jiffies = jiffies;
202 do_gettimeofday(&tv); 200 do_gettimeofday(&tv);
203 201
204 /* avoid overflow with gap >1s */ 202 /* avoid overflow with gap >1s */
diff --git a/drivers/media/video/cpia2/cpia2_core.c b/drivers/media/video/cpia2/cpia2_core.c
index aaffca8e13fd..ee91e295c90a 100644
--- a/drivers/media/video/cpia2/cpia2_core.c
+++ b/drivers/media/video/cpia2/cpia2_core.c
@@ -519,22 +519,16 @@ int cpia2_do_command(struct camera_data *cam,
519 * cpia2_send_command 519 * cpia2_send_command
520 * 520 *
521 *****************************************************************************/ 521 *****************************************************************************/
522
523#define DIR(cmd) ((cmd->direction == TRANSFER_WRITE) ? "Write" : "Read")
524#define BINDEX(cmd) (cmd->req_mode & 0x03)
525
522int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd) 526int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
523{ 527{
524 u8 count; 528 u8 count;
525 u8 start; 529 u8 start;
526 u8 block_index;
527 u8 *buffer; 530 u8 *buffer;
528 int retval; 531 int retval;
529 const char* dir;
530
531 if (cmd->direction == TRANSFER_WRITE) {
532 dir = "Write";
533 } else {
534 dir = "Read";
535 }
536
537 block_index = cmd->req_mode & 0x03;
538 532
539 switch (cmd->req_mode & 0x0c) { 533 switch (cmd->req_mode & 0x0c) {
540 case CAMERAACCESS_TYPE_RANDOM: 534 case CAMERAACCESS_TYPE_RANDOM:
@@ -542,32 +536,32 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
542 start = 0; 536 start = 0;
543 buffer = (u8 *) & cmd->buffer; 537 buffer = (u8 *) & cmd->buffer;
544 if (debugs_on & DEBUG_REG) 538 if (debugs_on & DEBUG_REG)
545 DBG("%s Random: Register block %s\n", dir, 539 DBG("%s Random: Register block %s\n", DIR(cmd),
546 block_name[block_index]); 540 block_name[BINDEX(cmd)]);
547 break; 541 break;
548 case CAMERAACCESS_TYPE_BLOCK: 542 case CAMERAACCESS_TYPE_BLOCK:
549 count = cmd->reg_count; 543 count = cmd->reg_count;
550 start = cmd->start; 544 start = cmd->start;
551 buffer = cmd->buffer.block_data; 545 buffer = cmd->buffer.block_data;
552 if (debugs_on & DEBUG_REG) 546 if (debugs_on & DEBUG_REG)
553 DBG("%s Block: Register block %s\n", dir, 547 DBG("%s Block: Register block %s\n", DIR(cmd),
554 block_name[block_index]); 548 block_name[BINDEX(cmd)]);
555 break; 549 break;
556 case CAMERAACCESS_TYPE_MASK: 550 case CAMERAACCESS_TYPE_MASK:
557 count = cmd->reg_count * sizeof(struct cpia2_reg_mask); 551 count = cmd->reg_count * sizeof(struct cpia2_reg_mask);
558 start = 0; 552 start = 0;
559 buffer = (u8 *) & cmd->buffer; 553 buffer = (u8 *) & cmd->buffer;
560 if (debugs_on & DEBUG_REG) 554 if (debugs_on & DEBUG_REG)
561 DBG("%s Mask: Register block %s\n", dir, 555 DBG("%s Mask: Register block %s\n", DIR(cmd),
562 block_name[block_index]); 556 block_name[BINDEX(cmd)]);
563 break; 557 break;
564 case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */ 558 case CAMERAACCESS_TYPE_REPEAT: /* For patch blocks only */
565 count = cmd->reg_count; 559 count = cmd->reg_count;
566 start = cmd->start; 560 start = cmd->start;
567 buffer = cmd->buffer.block_data; 561 buffer = cmd->buffer.block_data;
568 if (debugs_on & DEBUG_REG) 562 if (debugs_on & DEBUG_REG)
569 DBG("%s Repeat: Register block %s\n", dir, 563 DBG("%s Repeat: Register block %s\n", DIR(cmd),
570 block_name[block_index]); 564 block_name[BINDEX(cmd)]);
571 break; 565 break;
572 default: 566 default:
573 LOG("%s: invalid request mode\n",__func__); 567 LOG("%s: invalid request mode\n",__func__);
@@ -584,10 +578,10 @@ int cpia2_send_command(struct camera_data *cam, struct cpia2_command *cmd)
584 for (i = 0; i < cmd->reg_count; i++) { 578 for (i = 0; i < cmd->reg_count; i++) {
585 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK) 579 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_BLOCK)
586 KINFO("%s Block: [0x%02X] = 0x%02X\n", 580 KINFO("%s Block: [0x%02X] = 0x%02X\n",
587 dir, start + i, buffer[i]); 581 DIR(cmd), start + i, buffer[i]);
588 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM) 582 if((cmd->req_mode & 0x0c) == CAMERAACCESS_TYPE_RANDOM)
589 KINFO("%s Random: [0x%02X] = 0x%02X\n", 583 KINFO("%s Random: [0x%02X] = 0x%02X\n",
590 dir, cmd->buffer.registers[i].index, 584 DIR(cmd), cmd->buffer.registers[i].index,
591 cmd->buffer.registers[i].value); 585 cmd->buffer.registers[i].value);
592 } 586 }
593 } 587 }
diff --git a/drivers/media/video/cpia2/cpia2_v4l.c b/drivers/media/video/cpia2/cpia2_v4l.c
index 9bad39842936..5111bbcefad5 100644
--- a/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/drivers/media/video/cpia2/cpia2_v4l.c
@@ -395,10 +395,15 @@ static int sync(struct camera_data *cam, int frame_nr)
395 * 395 *
396 *****************************************************************************/ 396 *****************************************************************************/
397 397
398static int ioctl_set_gpio(void *arg, struct camera_data *cam) 398static long cpia2_default(struct file *file, void *fh, bool valid_prio,
399 int cmd, void *arg)
399{ 400{
401 struct camera_data *cam = video_drvdata(file);
400 __u32 gpio_val; 402 __u32 gpio_val;
401 403
404 if (cmd != CPIA2_CID_GPIO)
405 return -EINVAL;
406
402 gpio_val = *(__u32*) arg; 407 gpio_val = *(__u32*) arg;
403 408
404 if (gpio_val &~ 0xFFU) 409 if (gpio_val &~ 0xFFU)
@@ -415,11 +420,10 @@ static int ioctl_set_gpio(void *arg, struct camera_data *cam)
415 * 420 *
416 *****************************************************************************/ 421 *****************************************************************************/
417 422
418static int ioctl_querycap(void *arg, struct camera_data *cam) 423static int cpia2_querycap(struct file *file, void *fh, struct v4l2_capability *vc)
419{ 424{
420 struct v4l2_capability *vc = arg; 425 struct camera_data *cam = video_drvdata(file);
421 426
422 memset(vc, 0, sizeof(*vc));
423 strcpy(vc->driver, "cpia2"); 427 strcpy(vc->driver, "cpia2");
424 428
425 if (cam->params.pnp_id.product == 0x151) 429 if (cam->params.pnp_id.product == 0x151)
@@ -479,22 +483,26 @@ static int ioctl_querycap(void *arg, struct camera_data *cam)
479 * 483 *
480 *****************************************************************************/ 484 *****************************************************************************/
481 485
482static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam) 486static int cpia2_enum_input(struct file *file, void *fh, struct v4l2_input *i)
483{ 487{
484 struct v4l2_input *i = arg; 488 if (i->index)
485 489 return -EINVAL;
486 if(ioclt_nr != VIDIOC_G_INPUT) {
487 if (i->index != 0)
488 return -EINVAL;
489 }
490
491 memset(i, 0, sizeof(*i));
492 strcpy(i->name, "Camera"); 490 strcpy(i->name, "Camera");
493 i->type = V4L2_INPUT_TYPE_CAMERA; 491 i->type = V4L2_INPUT_TYPE_CAMERA;
492 return 0;
493}
494 494
495static int cpia2_g_input(struct file *file, void *fh, unsigned int *i)
496{
497 *i = 0;
495 return 0; 498 return 0;
496} 499}
497 500
501static int cpia2_s_input(struct file *file, void *fh, unsigned int i)
502{
503 return i ? -EINVAL : 0;
504}
505
498/****************************************************************************** 506/******************************************************************************
499 * 507 *
500 * ioctl_enum_fmt 508 * ioctl_enum_fmt
@@ -503,9 +511,9 @@ static int ioctl_input(unsigned int ioclt_nr,void *arg,struct camera_data *cam)
503 * 511 *
504 *****************************************************************************/ 512 *****************************************************************************/
505 513
506static int ioctl_enum_fmt(void *arg,struct camera_data *cam) 514static int cpia2_enum_fmt_vid_cap(struct file *file, void *fh,
515 struct v4l2_fmtdesc *f)
507{ 516{
508 struct v4l2_fmtdesc *f = arg;
509 int index = f->index; 517 int index = f->index;
510 518
511 if (index < 0 || index > 1) 519 if (index < 0 || index > 1)
@@ -539,12 +547,10 @@ static int ioctl_enum_fmt(void *arg,struct camera_data *cam)
539 * 547 *
540 *****************************************************************************/ 548 *****************************************************************************/
541 549
542static int ioctl_try_fmt(void *arg,struct camera_data *cam) 550static int cpia2_try_fmt_vid_cap(struct file *file, void *fh,
551 struct v4l2_format *f)
543{ 552{
544 struct v4l2_format *f = arg; 553 struct camera_data *cam = video_drvdata(file);
545
546 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
547 return -EINVAL;
548 554
549 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG && 555 if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG &&
550 f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG) 556 f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
@@ -603,12 +609,17 @@ static int ioctl_try_fmt(void *arg,struct camera_data *cam)
603 * 609 *
604 *****************************************************************************/ 610 *****************************************************************************/
605 611
606static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh) 612static int cpia2_s_fmt_vid_cap(struct file *file, void *_fh,
613 struct v4l2_format *f)
607{ 614{
608 struct v4l2_format *f = arg; 615 struct camera_data *cam = video_drvdata(file);
616 struct cpia2_fh *fh = _fh;
609 int err, frame; 617 int err, frame;
610 618
611 err = ioctl_try_fmt(arg, cam); 619 err = v4l2_prio_check(&cam->prio, fh->prio);
620 if (err)
621 return err;
622 err = cpia2_try_fmt_vid_cap(file, _fh, f);
612 if(err != 0) 623 if(err != 0)
613 return err; 624 return err;
614 625
@@ -658,12 +669,10 @@ static int ioctl_set_fmt(void *arg,struct camera_data *cam, struct cpia2_fh *fh)
658 * 669 *
659 *****************************************************************************/ 670 *****************************************************************************/
660 671
661static int ioctl_get_fmt(void *arg,struct camera_data *cam) 672static int cpia2_g_fmt_vid_cap(struct file *file, void *fh,
673 struct v4l2_format *f)
662{ 674{
663 struct v4l2_format *f = arg; 675 struct camera_data *cam = video_drvdata(file);
664
665 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
666 return -EINVAL;
667 676
668 f->fmt.pix.width = cam->width; 677 f->fmt.pix.width = cam->width;
669 f->fmt.pix.height = cam->height; 678 f->fmt.pix.height = cam->height;
@@ -686,9 +695,9 @@ static int ioctl_get_fmt(void *arg,struct camera_data *cam)
686 * 695 *
687 *****************************************************************************/ 696 *****************************************************************************/
688 697
689static int ioctl_cropcap(void *arg,struct camera_data *cam) 698static int cpia2_cropcap(struct file *file, void *fh, struct v4l2_cropcap *c)
690{ 699{
691 struct v4l2_cropcap *c = arg; 700 struct camera_data *cam = video_drvdata(file);
692 701
693 if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 702 if (c->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
694 return -EINVAL; 703 return -EINVAL;
@@ -715,9 +724,9 @@ static int ioctl_cropcap(void *arg,struct camera_data *cam)
715 * 724 *
716 *****************************************************************************/ 725 *****************************************************************************/
717 726
718static int ioctl_queryctrl(void *arg,struct camera_data *cam) 727static int cpia2_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
719{ 728{
720 struct v4l2_queryctrl *c = arg; 729 struct camera_data *cam = video_drvdata(file);
721 int i; 730 int i;
722 731
723 for(i=0; i<NUM_CONTROLS; ++i) { 732 for(i=0; i<NUM_CONTROLS; ++i) {
@@ -783,12 +792,9 @@ static int ioctl_queryctrl(void *arg,struct camera_data *cam)
783 * 792 *
784 *****************************************************************************/ 793 *****************************************************************************/
785 794
786static int ioctl_querymenu(void *arg,struct camera_data *cam) 795static int cpia2_querymenu(struct file *file, void *fh, struct v4l2_querymenu *m)
787{ 796{
788 struct v4l2_querymenu *m = arg; 797 struct camera_data *cam = video_drvdata(file);
789
790 memset(m->name, 0, sizeof(m->name));
791 m->reserved = 0;
792 798
793 switch(m->id) { 799 switch(m->id) {
794 case CPIA2_CID_FLICKER_MODE: 800 case CPIA2_CID_FLICKER_MODE:
@@ -837,9 +843,9 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
837 * 843 *
838 *****************************************************************************/ 844 *****************************************************************************/
839 845
840static int ioctl_g_ctrl(void *arg,struct camera_data *cam) 846static int cpia2_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
841{ 847{
842 struct v4l2_control *c = arg; 848 struct camera_data *cam = video_drvdata(file);
843 849
844 switch(c->id) { 850 switch(c->id) {
845 case V4L2_CID_BRIGHTNESS: 851 case V4L2_CID_BRIGHTNESS:
@@ -955,9 +961,9 @@ static int ioctl_g_ctrl(void *arg,struct camera_data *cam)
955 * 961 *
956 *****************************************************************************/ 962 *****************************************************************************/
957 963
958static int ioctl_s_ctrl(void *arg,struct camera_data *cam) 964static int cpia2_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
959{ 965{
960 struct v4l2_control *c = arg; 966 struct camera_data *cam = video_drvdata(file);
961 int i; 967 int i;
962 int retval = 0; 968 int retval = 0;
963 969
@@ -1031,9 +1037,9 @@ static int ioctl_s_ctrl(void *arg,struct camera_data *cam)
1031 * 1037 *
1032 *****************************************************************************/ 1038 *****************************************************************************/
1033 1039
1034static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam) 1040static int cpia2_g_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
1035{ 1041{
1036 struct v4l2_jpegcompression *parms = arg; 1042 struct camera_data *cam = video_drvdata(file);
1037 1043
1038 memset(parms, 0, sizeof(*parms)); 1044 memset(parms, 0, sizeof(*parms));
1039 1045
@@ -1072,9 +1078,9 @@ static int ioctl_g_jpegcomp(void *arg,struct camera_data *cam)
1072 * 1078 *
1073 *****************************************************************************/ 1079 *****************************************************************************/
1074 1080
1075static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam) 1081static int cpia2_s_jpegcomp(struct file *file, void *fh, struct v4l2_jpegcompression *parms)
1076{ 1082{
1077 struct v4l2_jpegcompression *parms = arg; 1083 struct camera_data *cam = video_drvdata(file);
1078 1084
1079 DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n", 1085 DBG("S_JPEGCOMP APP_len:%d COM_len:%d\n",
1080 parms->APP_len, parms->COM_len); 1086 parms->APP_len, parms->COM_len);
@@ -1121,9 +1127,9 @@ static int ioctl_s_jpegcomp(void *arg,struct camera_data *cam)
1121 * 1127 *
1122 *****************************************************************************/ 1128 *****************************************************************************/
1123 1129
1124static int ioctl_reqbufs(void *arg,struct camera_data *cam) 1130static int cpia2_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *req)
1125{ 1131{
1126 struct v4l2_requestbuffers *req = arg; 1132 struct camera_data *cam = video_drvdata(file);
1127 1133
1128 if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1134 if(req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1129 req->memory != V4L2_MEMORY_MMAP) 1135 req->memory != V4L2_MEMORY_MMAP)
@@ -1144,9 +1150,9 @@ static int ioctl_reqbufs(void *arg,struct camera_data *cam)
1144 * 1150 *
1145 *****************************************************************************/ 1151 *****************************************************************************/
1146 1152
1147static int ioctl_querybuf(void *arg,struct camera_data *cam) 1153static int cpia2_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1148{ 1154{
1149 struct v4l2_buffer *buf = arg; 1155 struct camera_data *cam = video_drvdata(file);
1150 1156
1151 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1157 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1152 buf->index > cam->num_frames) 1158 buf->index > cam->num_frames)
@@ -1192,9 +1198,9 @@ static int ioctl_querybuf(void *arg,struct camera_data *cam)
1192 * 1198 *
1193 *****************************************************************************/ 1199 *****************************************************************************/
1194 1200
1195static int ioctl_qbuf(void *arg,struct camera_data *cam) 1201static int cpia2_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1196{ 1202{
1197 struct v4l2_buffer *buf = arg; 1203 struct camera_data *cam = video_drvdata(file);
1198 1204
1199 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1205 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
1200 buf->memory != V4L2_MEMORY_MMAP || 1206 buf->memory != V4L2_MEMORY_MMAP ||
@@ -1248,9 +1254,9 @@ static int find_earliest_filled_buffer(struct camera_data *cam)
1248 * 1254 *
1249 *****************************************************************************/ 1255 *****************************************************************************/
1250 1256
1251static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file) 1257static int cpia2_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
1252{ 1258{
1253 struct v4l2_buffer *buf = arg; 1259 struct camera_data *cam = video_drvdata(file);
1254 int frame; 1260 int frame;
1255 1261
1256 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE || 1262 if(buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE ||
@@ -1296,210 +1302,56 @@ static int ioctl_dqbuf(void *arg,struct camera_data *cam, struct file *file)
1296 return 0; 1302 return 0;
1297} 1303}
1298 1304
1299/****************************************************************************** 1305static int cpia2_g_priority(struct file *file, void *_fh, enum v4l2_priority *p)
1300 *
1301 * cpia2_ioctl
1302 *
1303 *****************************************************************************/
1304static long cpia2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1305{ 1306{
1306 struct camera_data *cam = video_drvdata(file); 1307 struct cpia2_fh *fh = _fh;
1307 long retval = 0;
1308
1309 if (!cam)
1310 return -ENOTTY;
1311
1312 if (!cam->present)
1313 return -ENODEV;
1314
1315 /* Priority check */
1316 switch (cmd) {
1317 case VIDIOC_S_FMT:
1318 {
1319 struct cpia2_fh *fh = file->private_data;
1320 retval = v4l2_prio_check(&cam->prio, fh->prio);
1321 if (retval)
1322 return retval;
1323 break;
1324 }
1325 default:
1326 break;
1327 }
1328
1329 switch (cmd) {
1330 /* CPIA2 extension to Video4Linux API */
1331 case CPIA2_IOC_SET_GPIO:
1332 retval = ioctl_set_gpio(arg, cam);
1333 break;
1334 case VIDIOC_QUERYCAP:
1335 retval = ioctl_querycap(arg,cam);
1336 break;
1337
1338 case VIDIOC_ENUMINPUT:
1339 case VIDIOC_G_INPUT:
1340 case VIDIOC_S_INPUT:
1341 retval = ioctl_input(cmd, arg, cam);
1342 break;
1343
1344 case VIDIOC_ENUM_FMT:
1345 retval = ioctl_enum_fmt(arg,cam);
1346 break;
1347 case VIDIOC_TRY_FMT:
1348 retval = ioctl_try_fmt(arg,cam);
1349 break;
1350 case VIDIOC_G_FMT:
1351 retval = ioctl_get_fmt(arg,cam);
1352 break;
1353 case VIDIOC_S_FMT:
1354 retval = ioctl_set_fmt(arg,cam,file->private_data);
1355 break;
1356 1308
1357 case VIDIOC_CROPCAP: 1309 *p = fh->prio;
1358 retval = ioctl_cropcap(arg,cam); 1310 return 0;
1359 break; 1311}
1360 case VIDIOC_G_CROP:
1361 case VIDIOC_S_CROP:
1362 // TODO: I think cropping can be implemented - SJB
1363 retval = -EINVAL;
1364 break;
1365
1366 case VIDIOC_QUERYCTRL:
1367 retval = ioctl_queryctrl(arg,cam);
1368 break;
1369 case VIDIOC_QUERYMENU:
1370 retval = ioctl_querymenu(arg,cam);
1371 break;
1372 case VIDIOC_G_CTRL:
1373 retval = ioctl_g_ctrl(arg,cam);
1374 break;
1375 case VIDIOC_S_CTRL:
1376 retval = ioctl_s_ctrl(arg,cam);
1377 break;
1378
1379 case VIDIOC_G_JPEGCOMP:
1380 retval = ioctl_g_jpegcomp(arg,cam);
1381 break;
1382 case VIDIOC_S_JPEGCOMP:
1383 retval = ioctl_s_jpegcomp(arg,cam);
1384 break;
1385
1386 case VIDIOC_G_PRIORITY:
1387 {
1388 struct cpia2_fh *fh = file->private_data;
1389 *(enum v4l2_priority*)arg = fh->prio;
1390 break;
1391 }
1392 case VIDIOC_S_PRIORITY:
1393 {
1394 struct cpia2_fh *fh = file->private_data;
1395 enum v4l2_priority prio;
1396 prio = *(enum v4l2_priority*)arg;
1397 if(cam->streaming &&
1398 prio != fh->prio &&
1399 fh->prio == V4L2_PRIORITY_RECORD) {
1400 /* Can't drop record priority while streaming */
1401 retval = -EBUSY;
1402 } else if(prio == V4L2_PRIORITY_RECORD &&
1403 prio != fh->prio &&
1404 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD) {
1405 /* Only one program can record at a time */
1406 retval = -EBUSY;
1407 } else {
1408 retval = v4l2_prio_change(&cam->prio, &fh->prio, prio);
1409 }
1410 break;
1411 }
1412
1413 case VIDIOC_REQBUFS:
1414 retval = ioctl_reqbufs(arg,cam);
1415 break;
1416 case VIDIOC_QUERYBUF:
1417 retval = ioctl_querybuf(arg,cam);
1418 break;
1419 case VIDIOC_QBUF:
1420 retval = ioctl_qbuf(arg,cam);
1421 break;
1422 case VIDIOC_DQBUF:
1423 retval = ioctl_dqbuf(arg,cam,file);
1424 break;
1425 case VIDIOC_STREAMON:
1426 {
1427 int type;
1428 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1429 type = *(int*)arg;
1430 if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1431 retval = -EINVAL;
1432
1433 if(!cam->streaming) {
1434 retval = cpia2_usb_stream_start(cam,
1435 cam->params.camera_state.stream_mode);
1436 } else {
1437 retval = -EINVAL;
1438 }
1439
1440 break;
1441 }
1442 case VIDIOC_STREAMOFF:
1443 {
1444 int type;
1445 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1446 type = *(int*)arg;
1447 if(!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1448 retval = -EINVAL;
1449
1450 if(cam->streaming) {
1451 retval = cpia2_usb_stream_stop(cam);
1452 } else {
1453 retval = -EINVAL;
1454 }
1455
1456 break;
1457 }
1458
1459 case VIDIOC_ENUMOUTPUT:
1460 case VIDIOC_G_OUTPUT:
1461 case VIDIOC_S_OUTPUT:
1462 case VIDIOC_G_MODULATOR:
1463 case VIDIOC_S_MODULATOR:
1464
1465 case VIDIOC_ENUMAUDIO:
1466 case VIDIOC_G_AUDIO:
1467 case VIDIOC_S_AUDIO:
1468 1312
1469 case VIDIOC_ENUMAUDOUT: 1313static int cpia2_s_priority(struct file *file, void *_fh, enum v4l2_priority prio)
1470 case VIDIOC_G_AUDOUT: 1314{
1471 case VIDIOC_S_AUDOUT: 1315 struct camera_data *cam = video_drvdata(file);
1316 struct cpia2_fh *fh = fh;
1472 1317
1473 case VIDIOC_ENUMSTD: 1318 if (cam->streaming && prio != fh->prio &&
1474 case VIDIOC_QUERYSTD: 1319 fh->prio == V4L2_PRIORITY_RECORD)
1475 case VIDIOC_G_STD: 1320 /* Can't drop record priority while streaming */
1476 case VIDIOC_S_STD: 1321 return -EBUSY;
1477 1322
1478 case VIDIOC_G_TUNER: 1323 if (prio == V4L2_PRIORITY_RECORD && prio != fh->prio &&
1479 case VIDIOC_S_TUNER: 1324 v4l2_prio_max(&cam->prio) == V4L2_PRIORITY_RECORD)
1480 case VIDIOC_G_FREQUENCY: 1325 /* Only one program can record at a time */
1481 case VIDIOC_S_FREQUENCY: 1326 return -EBUSY;
1327 return v4l2_prio_change(&cam->prio, &fh->prio, prio);
1328}
1482 1329
1483 case VIDIOC_OVERLAY: 1330static int cpia2_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
1484 case VIDIOC_G_FBUF: 1331{
1485 case VIDIOC_S_FBUF: 1332 struct camera_data *cam = video_drvdata(file);
1486 1333
1487 case VIDIOC_G_PARM: 1334 DBG("VIDIOC_STREAMON, streaming=%d\n", cam->streaming);
1488 case VIDIOC_S_PARM: 1335 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1489 retval = -EINVAL; 1336 return -EINVAL;
1490 break;
1491 default:
1492 retval = -ENOIOCTLCMD;
1493 break;
1494 }
1495 1337
1496 return retval; 1338 if (!cam->streaming)
1339 return cpia2_usb_stream_start(cam,
1340 cam->params.camera_state.stream_mode);
1341 return -EINVAL;
1497} 1342}
1498 1343
1499static long cpia2_ioctl(struct file *file, 1344static int cpia2_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
1500 unsigned int cmd, unsigned long arg)
1501{ 1345{
1502 return video_usercopy(file, cmd, arg, cpia2_do_ioctl); 1346 struct camera_data *cam = video_drvdata(file);
1347
1348 DBG("VIDIOC_STREAMOFF, streaming=%d\n", cam->streaming);
1349 if (!cam->mmapped || type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
1350 return -EINVAL;
1351
1352 if (cam->streaming)
1353 return cpia2_usb_stream_stop(cam);
1354 return -EINVAL;
1503} 1355}
1504 1356
1505/****************************************************************************** 1357/******************************************************************************
@@ -1550,6 +1402,33 @@ static void reset_camera_struct_v4l(struct camera_data *cam)
1550 v4l2_prio_init(&cam->prio); 1402 v4l2_prio_init(&cam->prio);
1551} 1403}
1552 1404
1405static const struct v4l2_ioctl_ops cpia2_ioctl_ops = {
1406 .vidioc_querycap = cpia2_querycap,
1407 .vidioc_enum_input = cpia2_enum_input,
1408 .vidioc_g_input = cpia2_g_input,
1409 .vidioc_s_input = cpia2_s_input,
1410 .vidioc_enum_fmt_vid_cap = cpia2_enum_fmt_vid_cap,
1411 .vidioc_g_fmt_vid_cap = cpia2_g_fmt_vid_cap,
1412 .vidioc_s_fmt_vid_cap = cpia2_s_fmt_vid_cap,
1413 .vidioc_try_fmt_vid_cap = cpia2_try_fmt_vid_cap,
1414 .vidioc_queryctrl = cpia2_queryctrl,
1415 .vidioc_querymenu = cpia2_querymenu,
1416 .vidioc_g_ctrl = cpia2_g_ctrl,
1417 .vidioc_s_ctrl = cpia2_s_ctrl,
1418 .vidioc_g_jpegcomp = cpia2_g_jpegcomp,
1419 .vidioc_s_jpegcomp = cpia2_s_jpegcomp,
1420 .vidioc_cropcap = cpia2_cropcap,
1421 .vidioc_reqbufs = cpia2_reqbufs,
1422 .vidioc_querybuf = cpia2_querybuf,
1423 .vidioc_qbuf = cpia2_qbuf,
1424 .vidioc_dqbuf = cpia2_dqbuf,
1425 .vidioc_streamon = cpia2_streamon,
1426 .vidioc_streamoff = cpia2_streamoff,
1427 .vidioc_g_priority = cpia2_g_priority,
1428 .vidioc_s_priority = cpia2_s_priority,
1429 .vidioc_default = cpia2_default,
1430};
1431
1553/*** 1432/***
1554 * The v4l video device structure initialized for this device 1433 * The v4l video device structure initialized for this device
1555 ***/ 1434 ***/
@@ -1559,7 +1438,7 @@ static const struct v4l2_file_operations cpia2_fops = {
1559 .release = cpia2_close, 1438 .release = cpia2_close,
1560 .read = cpia2_v4l_read, 1439 .read = cpia2_v4l_read,
1561 .poll = cpia2_v4l_poll, 1440 .poll = cpia2_v4l_poll,
1562 .unlocked_ioctl = cpia2_ioctl, 1441 .unlocked_ioctl = video_ioctl2,
1563 .mmap = cpia2_mmap, 1442 .mmap = cpia2_mmap,
1564}; 1443};
1565 1444
@@ -1567,6 +1446,7 @@ static struct video_device cpia2_template = {
1567 /* I could not find any place for the old .initialize initializer?? */ 1446 /* I could not find any place for the old .initialize initializer?? */
1568 .name = "CPiA2 Camera", 1447 .name = "CPiA2 Camera",
1569 .fops = &cpia2_fops, 1448 .fops = &cpia2_fops,
1449 .ioctl_ops = &cpia2_ioctl_ops,
1570 .release = video_device_release, 1450 .release = video_device_release,
1571}; 1451};
1572 1452
diff --git a/drivers/media/video/cs5345.c b/drivers/media/video/cs5345.c
index 9358fe77e562..5909f2557ab4 100644
--- a/drivers/media/video/cs5345.c
+++ b/drivers/media/video/cs5345.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <media/v4l2-device.h> 26#include <media/v4l2-device.h>
27#include <media/v4l2-chip-ident.h> 27#include <media/v4l2-chip-ident.h>
28#include <media/v4l2-ctrls.h>
28 29
29MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC"); 30MODULE_DESCRIPTION("i2c device driver for cs5345 Audio ADC");
30MODULE_AUTHOR("Hans Verkuil"); 31MODULE_AUTHOR("Hans Verkuil");
@@ -36,6 +37,20 @@ module_param(debug, bool, 0644);
36 37
37MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On"); 38MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
38 39
40struct cs5345_state {
41 struct v4l2_subdev sd;
42 struct v4l2_ctrl_handler hdl;
43};
44
45static inline struct cs5345_state *to_state(struct v4l2_subdev *sd)
46{
47 return container_of(sd, struct cs5345_state, sd);
48}
49
50static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
51{
52 return &container_of(ctrl->handler, struct cs5345_state, hdl)->sd;
53}
39 54
40/* ----------------------------------------------------------------------- */ 55/* ----------------------------------------------------------------------- */
41 56
@@ -65,33 +80,20 @@ static int cs5345_s_routing(struct v4l2_subdev *sd,
65 return 0; 80 return 0;
66} 81}
67 82
68static int cs5345_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 83static int cs5345_s_ctrl(struct v4l2_ctrl *ctrl)
69{ 84{
70 if (ctrl->id == V4L2_CID_AUDIO_MUTE) { 85 struct v4l2_subdev *sd = to_sd(ctrl);
71 ctrl->value = (cs5345_read(sd, 0x04) & 0x08) != 0;
72 return 0;
73 }
74 if (ctrl->id != V4L2_CID_AUDIO_VOLUME)
75 return -EINVAL;
76 ctrl->value = cs5345_read(sd, 0x07) & 0x3f;
77 if (ctrl->value >= 32)
78 ctrl->value = ctrl->value - 64;
79 return 0;
80}
81 86
82static int cs5345_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 87 switch (ctrl->id) {
83{ 88 case V4L2_CID_AUDIO_MUTE:
84 if (ctrl->id == V4L2_CID_AUDIO_MUTE) { 89 cs5345_write(sd, 0x04, ctrl->val ? 0x80 : 0);
85 cs5345_write(sd, 0x04, ctrl->value ? 0x80 : 0); 90 return 0;
91 case V4L2_CID_AUDIO_VOLUME:
92 cs5345_write(sd, 0x07, ((u8)ctrl->val) & 0x3f);
93 cs5345_write(sd, 0x08, ((u8)ctrl->val) & 0x3f);
86 return 0; 94 return 0;
87 } 95 }
88 if (ctrl->id != V4L2_CID_AUDIO_VOLUME) 96 return -EINVAL;
89 return -EINVAL;
90 if (ctrl->value > 24 || ctrl->value < -24)
91 return -EINVAL;
92 cs5345_write(sd, 0x07, ((u8)ctrl->value) & 0x3f);
93 cs5345_write(sd, 0x08, ((u8)ctrl->value) & 0x3f);
94 return 0;
95} 97}
96 98
97#ifdef CONFIG_VIDEO_ADV_DEBUG 99#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -144,11 +146,20 @@ static int cs5345_log_status(struct v4l2_subdev *sd)
144 146
145/* ----------------------------------------------------------------------- */ 147/* ----------------------------------------------------------------------- */
146 148
149static const struct v4l2_ctrl_ops cs5345_ctrl_ops = {
150 .s_ctrl = cs5345_s_ctrl,
151};
152
147static const struct v4l2_subdev_core_ops cs5345_core_ops = { 153static const struct v4l2_subdev_core_ops cs5345_core_ops = {
148 .log_status = cs5345_log_status, 154 .log_status = cs5345_log_status,
149 .g_chip_ident = cs5345_g_chip_ident, 155 .g_chip_ident = cs5345_g_chip_ident,
150 .g_ctrl = cs5345_g_ctrl, 156 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
151 .s_ctrl = cs5345_s_ctrl, 157 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
158 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
159 .g_ctrl = v4l2_subdev_g_ctrl,
160 .s_ctrl = v4l2_subdev_s_ctrl,
161 .queryctrl = v4l2_subdev_queryctrl,
162 .querymenu = v4l2_subdev_querymenu,
152#ifdef CONFIG_VIDEO_ADV_DEBUG 163#ifdef CONFIG_VIDEO_ADV_DEBUG
153 .g_register = cs5345_g_register, 164 .g_register = cs5345_g_register,
154 .s_register = cs5345_s_register, 165 .s_register = cs5345_s_register,
@@ -169,6 +180,7 @@ static const struct v4l2_subdev_ops cs5345_ops = {
169static int cs5345_probe(struct i2c_client *client, 180static int cs5345_probe(struct i2c_client *client,
170 const struct i2c_device_id *id) 181 const struct i2c_device_id *id)
171{ 182{
183 struct cs5345_state *state;
172 struct v4l2_subdev *sd; 184 struct v4l2_subdev *sd;
173 185
174 /* Check if the adapter supports the needed features */ 186 /* Check if the adapter supports the needed features */
@@ -178,11 +190,28 @@ static int cs5345_probe(struct i2c_client *client,
178 v4l_info(client, "chip found @ 0x%x (%s)\n", 190 v4l_info(client, "chip found @ 0x%x (%s)\n",
179 client->addr << 1, client->adapter->name); 191 client->addr << 1, client->adapter->name);
180 192
181 sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL); 193 state = kzalloc(sizeof(struct cs5345_state), GFP_KERNEL);
182 if (sd == NULL) 194 if (state == NULL)
183 return -ENOMEM; 195 return -ENOMEM;
196 sd = &state->sd;
184 v4l2_i2c_subdev_init(sd, client, &cs5345_ops); 197 v4l2_i2c_subdev_init(sd, client, &cs5345_ops);
185 198
199 v4l2_ctrl_handler_init(&state->hdl, 2);
200 v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
201 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
202 v4l2_ctrl_new_std(&state->hdl, &cs5345_ctrl_ops,
203 V4L2_CID_AUDIO_VOLUME, -24, 24, 1, 0);
204 sd->ctrl_handler = &state->hdl;
205 if (state->hdl.error) {
206 int err = state->hdl.error;
207
208 v4l2_ctrl_handler_free(&state->hdl);
209 kfree(state);
210 return err;
211 }
212 /* set volume/mute */
213 v4l2_ctrl_handler_setup(&state->hdl);
214
186 cs5345_write(sd, 0x02, 0x00); 215 cs5345_write(sd, 0x02, 0x00);
187 cs5345_write(sd, 0x04, 0x01); 216 cs5345_write(sd, 0x04, 0x01);
188 cs5345_write(sd, 0x09, 0x01); 217 cs5345_write(sd, 0x09, 0x01);
@@ -194,9 +223,11 @@ static int cs5345_probe(struct i2c_client *client,
194static int cs5345_remove(struct i2c_client *client) 223static int cs5345_remove(struct i2c_client *client)
195{ 224{
196 struct v4l2_subdev *sd = i2c_get_clientdata(client); 225 struct v4l2_subdev *sd = i2c_get_clientdata(client);
226 struct cs5345_state *state = to_state(sd);
197 227
198 v4l2_device_unregister_subdev(sd); 228 v4l2_device_unregister_subdev(sd);
199 kfree(sd); 229 v4l2_ctrl_handler_free(&state->hdl);
230 kfree(state);
200 return 0; 231 return 0;
201} 232}
202 233
diff --git a/drivers/media/video/cx18/cx18-av-audio.c b/drivers/media/video/cx18/cx18-av-audio.c
index 43d09a24b262..4a24ffb17a7d 100644
--- a/drivers/media/video/cx18/cx18-av-audio.c
+++ b/drivers/media/video/cx18/cx18-av-audio.c
@@ -342,17 +342,6 @@ void cx18_av_audio_set_path(struct cx18 *cx)
342 } 342 }
343} 343}
344 344
345static int get_volume(struct cx18 *cx)
346{
347 /* Volume runs +18dB to -96dB in 1/2dB steps
348 * change to fit the msp3400 -114dB to +12dB range */
349
350 /* check PATH1_VOLUME */
351 int vol = 228 - cx18_av_read(cx, 0x8d4);
352 vol = (vol / 2) + 23;
353 return vol << 9;
354}
355
356static void set_volume(struct cx18 *cx, int volume) 345static void set_volume(struct cx18 *cx, int volume)
357{ 346{
358 /* First convert the volume to msp3400 values (0-127) */ 347 /* First convert the volume to msp3400 values (0-127) */
@@ -369,52 +358,18 @@ static void set_volume(struct cx18 *cx, int volume)
369 cx18_av_write(cx, 0x8d4, 228 - (vol * 2)); 358 cx18_av_write(cx, 0x8d4, 228 - (vol * 2));
370} 359}
371 360
372static int get_bass(struct cx18 *cx)
373{
374 /* bass is 49 steps +12dB to -12dB */
375
376 /* check PATH1_EQ_BASS_VOL */
377 int bass = cx18_av_read(cx, 0x8d9) & 0x3f;
378 bass = (((48 - bass) * 0xffff) + 47) / 48;
379 return bass;
380}
381
382static void set_bass(struct cx18 *cx, int bass) 361static void set_bass(struct cx18 *cx, int bass)
383{ 362{
384 /* PATH1_EQ_BASS_VOL */ 363 /* PATH1_EQ_BASS_VOL */
385 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff)); 364 cx18_av_and_or(cx, 0x8d9, ~0x3f, 48 - (bass * 48 / 0xffff));
386} 365}
387 366
388static int get_treble(struct cx18 *cx)
389{
390 /* treble is 49 steps +12dB to -12dB */
391
392 /* check PATH1_EQ_TREBLE_VOL */
393 int treble = cx18_av_read(cx, 0x8db) & 0x3f;
394 treble = (((48 - treble) * 0xffff) + 47) / 48;
395 return treble;
396}
397
398static void set_treble(struct cx18 *cx, int treble) 367static void set_treble(struct cx18 *cx, int treble)
399{ 368{
400 /* PATH1_EQ_TREBLE_VOL */ 369 /* PATH1_EQ_TREBLE_VOL */
401 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff)); 370 cx18_av_and_or(cx, 0x8db, ~0x3f, 48 - (treble * 48 / 0xffff));
402} 371}
403 372
404static int get_balance(struct cx18 *cx)
405{
406 /* balance is 7 bit, 0 to -96dB */
407
408 /* check PATH1_BAL_LEVEL */
409 int balance = cx18_av_read(cx, 0x8d5) & 0x7f;
410 /* check PATH1_BAL_LEFT */
411 if ((cx18_av_read(cx, 0x8d5) & 0x80) == 0)
412 balance = 0x80 - balance;
413 else
414 balance = 0x80 + balance;
415 return balance << 8;
416}
417
418static void set_balance(struct cx18 *cx, int balance) 373static void set_balance(struct cx18 *cx, int balance)
419{ 374{
420 int bal = balance >> 8; 375 int bal = balance >> 8;
@@ -431,12 +386,6 @@ static void set_balance(struct cx18 *cx, int balance)
431 } 386 }
432} 387}
433 388
434static int get_mute(struct cx18 *cx)
435{
436 /* check SRC1_MUTE_EN */
437 return cx18_av_read(cx, 0x8d3) & 0x2 ? 1 : 0;
438}
439
440static void set_mute(struct cx18 *cx, int mute) 389static void set_mute(struct cx18 *cx, int mute)
441{ 390{
442 struct cx18_av_state *state = &cx->av_state; 391 struct cx18_av_state *state = &cx->av_state;
@@ -490,50 +439,33 @@ int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
490 return retval; 439 return retval;
491} 440}
492 441
493int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl) 442static int cx18_av_audio_s_ctrl(struct v4l2_ctrl *ctrl)
494{ 443{
495 switch (ctrl->id) { 444 struct v4l2_subdev *sd = to_sd(ctrl);
496 case V4L2_CID_AUDIO_VOLUME: 445 struct cx18 *cx = v4l2_get_subdevdata(sd);
497 ctrl->value = get_volume(cx);
498 break;
499 case V4L2_CID_AUDIO_BASS:
500 ctrl->value = get_bass(cx);
501 break;
502 case V4L2_CID_AUDIO_TREBLE:
503 ctrl->value = get_treble(cx);
504 break;
505 case V4L2_CID_AUDIO_BALANCE:
506 ctrl->value = get_balance(cx);
507 break;
508 case V4L2_CID_AUDIO_MUTE:
509 ctrl->value = get_mute(cx);
510 break;
511 default:
512 return -EINVAL;
513 }
514 return 0;
515}
516 446
517int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
518{
519 switch (ctrl->id) { 447 switch (ctrl->id) {
520 case V4L2_CID_AUDIO_VOLUME: 448 case V4L2_CID_AUDIO_VOLUME:
521 set_volume(cx, ctrl->value); 449 set_volume(cx, ctrl->val);
522 break; 450 break;
523 case V4L2_CID_AUDIO_BASS: 451 case V4L2_CID_AUDIO_BASS:
524 set_bass(cx, ctrl->value); 452 set_bass(cx, ctrl->val);
525 break; 453 break;
526 case V4L2_CID_AUDIO_TREBLE: 454 case V4L2_CID_AUDIO_TREBLE:
527 set_treble(cx, ctrl->value); 455 set_treble(cx, ctrl->val);
528 break; 456 break;
529 case V4L2_CID_AUDIO_BALANCE: 457 case V4L2_CID_AUDIO_BALANCE:
530 set_balance(cx, ctrl->value); 458 set_balance(cx, ctrl->val);
531 break; 459 break;
532 case V4L2_CID_AUDIO_MUTE: 460 case V4L2_CID_AUDIO_MUTE:
533 set_mute(cx, ctrl->value); 461 set_mute(cx, ctrl->val);
534 break; 462 break;
535 default: 463 default:
536 return -EINVAL; 464 return -EINVAL;
537 } 465 }
538 return 0; 466 return 0;
539} 467}
468
469const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops = {
470 .s_ctrl = cx18_av_audio_s_ctrl,
471};
diff --git a/drivers/media/video/cx18/cx18-av-core.c b/drivers/media/video/cx18/cx18-av-core.c
index a41951cab276..f164b7f610a5 100644
--- a/drivers/media/video/cx18/cx18-av-core.c
+++ b/drivers/media/video/cx18/cx18-av-core.c
@@ -129,6 +129,7 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
129{ 129{
130 struct cx18_av_state *state = to_cx18_av_state(sd); 130 struct cx18_av_state *state = to_cx18_av_state(sd);
131 struct cx18 *cx = v4l2_get_subdevdata(sd); 131 struct cx18 *cx = v4l2_get_subdevdata(sd);
132 int default_volume;
132 u32 v; 133 u32 v;
133 134
134 cx18_av_loadfw(cx); 135 cx18_av_loadfw(cx);
@@ -247,8 +248,23 @@ static void cx18_av_initialize(struct v4l2_subdev *sd)
247/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */ 248/* CxDevWrReg(CXADEC_SRC_COMB_CFG, 0x6628021F); */
248/* } */ 249/* } */
249 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F); 250 cx18_av_write4(cx, CXADEC_SRC_COMB_CFG, 0x6628021F);
250 state->default_volume = 228 - cx18_av_read(cx, 0x8d4); 251 default_volume = cx18_av_read(cx, 0x8d4);
251 state->default_volume = ((state->default_volume / 2) + 23) << 9; 252 /*
253 * Enforce the legacy volume scale mapping limits to avoid
254 * -ERANGE errors when initializing the volume control
255 */
256 if (default_volume > 228) {
257 /* Bottom out at -96 dB, v4l2 vol range 0x2e00-0x2fff */
258 default_volume = 228;
259 cx18_av_write(cx, 0x8d4, 228);
260 } else if (default_volume < 20) {
261 /* Top out at + 8 dB, v4l2 vol range 0xfe00-0xffff */
262 default_volume = 20;
263 cx18_av_write(cx, 0x8d4, 20);
264 }
265 default_volume = (((228 - default_volume) >> 1) + 23) << 9;
266 state->volume->cur.val = state->volume->default_value = default_volume;
267 v4l2_ctrl_handler_setup(&state->hdl);
252} 268}
253 269
254static int cx18_av_reset(struct v4l2_subdev *sd, u32 val) 270static int cx18_av_reset(struct v4l2_subdev *sd, u32 val)
@@ -901,126 +917,35 @@ static int cx18_av_s_radio(struct v4l2_subdev *sd)
901 return 0; 917 return 0;
902} 918}
903 919
904static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 920static int cx18_av_s_ctrl(struct v4l2_ctrl *ctrl)
905{ 921{
922 struct v4l2_subdev *sd = to_sd(ctrl);
906 struct cx18 *cx = v4l2_get_subdevdata(sd); 923 struct cx18 *cx = v4l2_get_subdevdata(sd);
907 924
908 switch (ctrl->id) { 925 switch (ctrl->id) {
909 case V4L2_CID_BRIGHTNESS: 926 case V4L2_CID_BRIGHTNESS:
910 if (ctrl->value < 0 || ctrl->value > 255) { 927 cx18_av_write(cx, 0x414, ctrl->val - 128);
911 CX18_ERR_DEV(sd, "invalid brightness setting %d\n",
912 ctrl->value);
913 return -ERANGE;
914 }
915
916 cx18_av_write(cx, 0x414, ctrl->value - 128);
917 break; 928 break;
918 929
919 case V4L2_CID_CONTRAST: 930 case V4L2_CID_CONTRAST:
920 if (ctrl->value < 0 || ctrl->value > 127) { 931 cx18_av_write(cx, 0x415, ctrl->val << 1);
921 CX18_ERR_DEV(sd, "invalid contrast setting %d\n",
922 ctrl->value);
923 return -ERANGE;
924 }
925
926 cx18_av_write(cx, 0x415, ctrl->value << 1);
927 break; 932 break;
928 933
929 case V4L2_CID_SATURATION: 934 case V4L2_CID_SATURATION:
930 if (ctrl->value < 0 || ctrl->value > 127) { 935 cx18_av_write(cx, 0x420, ctrl->val << 1);
931 CX18_ERR_DEV(sd, "invalid saturation setting %d\n", 936 cx18_av_write(cx, 0x421, ctrl->val << 1);
932 ctrl->value);
933 return -ERANGE;
934 }
935
936 cx18_av_write(cx, 0x420, ctrl->value << 1);
937 cx18_av_write(cx, 0x421, ctrl->value << 1);
938 break; 937 break;
939 938
940 case V4L2_CID_HUE: 939 case V4L2_CID_HUE:
941 if (ctrl->value < -128 || ctrl->value > 127) { 940 cx18_av_write(cx, 0x422, ctrl->val);
942 CX18_ERR_DEV(sd, "invalid hue setting %d\n",
943 ctrl->value);
944 return -ERANGE;
945 }
946
947 cx18_av_write(cx, 0x422, ctrl->value);
948 break; 941 break;
949 942
950 case V4L2_CID_AUDIO_VOLUME:
951 case V4L2_CID_AUDIO_BASS:
952 case V4L2_CID_AUDIO_TREBLE:
953 case V4L2_CID_AUDIO_BALANCE:
954 case V4L2_CID_AUDIO_MUTE:
955 return cx18_av_audio_s_ctrl(cx, ctrl);
956
957 default:
958 return -EINVAL;
959 }
960 return 0;
961}
962
963static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
964{
965 struct cx18 *cx = v4l2_get_subdevdata(sd);
966
967 switch (ctrl->id) {
968 case V4L2_CID_BRIGHTNESS:
969 ctrl->value = (s8)cx18_av_read(cx, 0x414) + 128;
970 break;
971 case V4L2_CID_CONTRAST:
972 ctrl->value = cx18_av_read(cx, 0x415) >> 1;
973 break;
974 case V4L2_CID_SATURATION:
975 ctrl->value = cx18_av_read(cx, 0x420) >> 1;
976 break;
977 case V4L2_CID_HUE:
978 ctrl->value = (s8)cx18_av_read(cx, 0x422);
979 break;
980 case V4L2_CID_AUDIO_VOLUME:
981 case V4L2_CID_AUDIO_BASS:
982 case V4L2_CID_AUDIO_TREBLE:
983 case V4L2_CID_AUDIO_BALANCE:
984 case V4L2_CID_AUDIO_MUTE:
985 return cx18_av_audio_g_ctrl(cx, ctrl);
986 default: 943 default:
987 return -EINVAL; 944 return -EINVAL;
988 } 945 }
989 return 0; 946 return 0;
990} 947}
991 948
992static int cx18_av_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
993{
994 struct cx18_av_state *state = to_cx18_av_state(sd);
995
996 switch (qc->id) {
997 case V4L2_CID_BRIGHTNESS:
998 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
999 case V4L2_CID_CONTRAST:
1000 case V4L2_CID_SATURATION:
1001 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
1002 case V4L2_CID_HUE:
1003 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
1004 default:
1005 break;
1006 }
1007
1008 switch (qc->id) {
1009 case V4L2_CID_AUDIO_VOLUME:
1010 return v4l2_ctrl_query_fill(qc, 0, 65535,
1011 65535 / 100, state->default_volume);
1012 case V4L2_CID_AUDIO_MUTE:
1013 return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
1014 case V4L2_CID_AUDIO_BALANCE:
1015 case V4L2_CID_AUDIO_BASS:
1016 case V4L2_CID_AUDIO_TREBLE:
1017 return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 32768);
1018 default:
1019 return -EINVAL;
1020 }
1021 return -EINVAL;
1022}
1023
1024static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt) 949static int cx18_av_s_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *fmt)
1025{ 950{
1026 struct cx18_av_state *state = to_cx18_av_state(sd); 951 struct cx18_av_state *state = to_cx18_av_state(sd);
@@ -1356,14 +1281,22 @@ static int cx18_av_s_register(struct v4l2_subdev *sd,
1356} 1281}
1357#endif 1282#endif
1358 1283
1284static const struct v4l2_ctrl_ops cx18_av_ctrl_ops = {
1285 .s_ctrl = cx18_av_s_ctrl,
1286};
1287
1359static const struct v4l2_subdev_core_ops cx18_av_general_ops = { 1288static const struct v4l2_subdev_core_ops cx18_av_general_ops = {
1360 .g_chip_ident = cx18_av_g_chip_ident, 1289 .g_chip_ident = cx18_av_g_chip_ident,
1361 .log_status = cx18_av_log_status, 1290 .log_status = cx18_av_log_status,
1362 .load_fw = cx18_av_load_fw, 1291 .load_fw = cx18_av_load_fw,
1363 .reset = cx18_av_reset, 1292 .reset = cx18_av_reset,
1364 .queryctrl = cx18_av_queryctrl, 1293 .g_ctrl = v4l2_subdev_g_ctrl,
1365 .g_ctrl = cx18_av_g_ctrl, 1294 .s_ctrl = v4l2_subdev_s_ctrl,
1366 .s_ctrl = cx18_av_s_ctrl, 1295 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
1296 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1297 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1298 .queryctrl = v4l2_subdev_queryctrl,
1299 .querymenu = v4l2_subdev_querymenu,
1367 .s_std = cx18_av_s_std, 1300 .s_std = cx18_av_s_std,
1368#ifdef CONFIG_VIDEO_ADV_DEBUG 1301#ifdef CONFIG_VIDEO_ADV_DEBUG
1369 .g_register = cx18_av_g_register, 1302 .g_register = cx18_av_g_register,
@@ -1427,8 +1360,42 @@ int cx18_av_probe(struct cx18 *cx)
1427 snprintf(sd->name, sizeof(sd->name), 1360 snprintf(sd->name, sizeof(sd->name),
1428 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4)); 1361 "%s %03x", cx->v4l2_dev.name, (state->rev >> 4));
1429 sd->grp_id = CX18_HW_418_AV; 1362 sd->grp_id = CX18_HW_418_AV;
1363 v4l2_ctrl_handler_init(&state->hdl, 9);
1364 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1365 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1366 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1367 V4L2_CID_CONTRAST, 0, 127, 1, 64);
1368 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1369 V4L2_CID_SATURATION, 0, 127, 1, 64);
1370 v4l2_ctrl_new_std(&state->hdl, &cx18_av_ctrl_ops,
1371 V4L2_CID_HUE, -128, 127, 1, 0);
1372
1373 state->volume = v4l2_ctrl_new_std(&state->hdl,
1374 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_VOLUME,
1375 0, 65535, 65535 / 100, 0);
1376 v4l2_ctrl_new_std(&state->hdl,
1377 &cx18_av_audio_ctrl_ops, V4L2_CID_AUDIO_MUTE,
1378 0, 1, 1, 0);
1379 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1380 V4L2_CID_AUDIO_BALANCE,
1381 0, 65535, 65535 / 100, 32768);
1382 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1383 V4L2_CID_AUDIO_BASS,
1384 0, 65535, 65535 / 100, 32768);
1385 v4l2_ctrl_new_std(&state->hdl, &cx18_av_audio_ctrl_ops,
1386 V4L2_CID_AUDIO_TREBLE,
1387 0, 65535, 65535 / 100, 32768);
1388 sd->ctrl_handler = &state->hdl;
1389 if (state->hdl.error) {
1390 int err = state->hdl.error;
1391
1392 v4l2_ctrl_handler_free(&state->hdl);
1393 return err;
1394 }
1430 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd); 1395 err = v4l2_device_register_subdev(&cx->v4l2_dev, sd);
1431 if (!err) 1396 if (err)
1397 v4l2_ctrl_handler_free(&state->hdl);
1398 else
1432 cx18_av_init(cx); 1399 cx18_av_init(cx);
1433 return err; 1400 return err;
1434} 1401}
diff --git a/drivers/media/video/cx18/cx18-av-core.h b/drivers/media/video/cx18/cx18-av-core.h
index 1956991795e3..188c9c3d2db1 100644
--- a/drivers/media/video/cx18/cx18-av-core.h
+++ b/drivers/media/video/cx18/cx18-av-core.h
@@ -26,6 +26,7 @@
26#define _CX18_AV_CORE_H_ 26#define _CX18_AV_CORE_H_
27 27
28#include <media/v4l2-device.h> 28#include <media/v4l2-device.h>
29#include <media/v4l2-ctrls.h>
29 30
30struct cx18; 31struct cx18;
31 32
@@ -95,13 +96,14 @@ enum cx18_av_audio_input {
95 96
96struct cx18_av_state { 97struct cx18_av_state {
97 struct v4l2_subdev sd; 98 struct v4l2_subdev sd;
99 struct v4l2_ctrl_handler hdl;
100 struct v4l2_ctrl *volume;
98 int radio; 101 int radio;
99 v4l2_std_id std; 102 v4l2_std_id std;
100 enum cx18_av_video_input vid_input; 103 enum cx18_av_video_input vid_input;
101 enum cx18_av_audio_input aud_input; 104 enum cx18_av_audio_input aud_input;
102 u32 audclk_freq; 105 u32 audclk_freq;
103 int audmode; 106 int audmode;
104 int default_volume;
105 u32 id; 107 u32 id;
106 u32 rev; 108 u32 rev;
107 int is_initialized; 109 int is_initialized;
@@ -347,6 +349,11 @@ static inline struct cx18_av_state *to_cx18_av_state(struct v4l2_subdev *sd)
347 return container_of(sd, struct cx18_av_state, sd); 349 return container_of(sd, struct cx18_av_state, sd);
348} 350}
349 351
352static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
353{
354 return &container_of(ctrl->handler, struct cx18_av_state, hdl)->sd;
355}
356
350/* ----------------------------------------------------------------------- */ 357/* ----------------------------------------------------------------------- */
351/* cx18_av-core.c */ 358/* cx18_av-core.c */
352int cx18_av_write(struct cx18 *cx, u16 addr, u8 value); 359int cx18_av_write(struct cx18 *cx, u16 addr, u8 value);
@@ -369,10 +376,9 @@ int cx18_av_loadfw(struct cx18 *cx);
369 376
370/* ----------------------------------------------------------------------- */ 377/* ----------------------------------------------------------------------- */
371/* cx18_av-audio.c */ 378/* cx18_av-audio.c */
372int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
373int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
374int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq); 379int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
375void cx18_av_audio_set_path(struct cx18 *cx); 380void cx18_av_audio_set_path(struct cx18 *cx);
381extern const struct v4l2_ctrl_ops cx18_av_audio_ctrl_ops;
376 382
377/* ----------------------------------------------------------------------- */ 383/* ----------------------------------------------------------------------- */
378/* cx18_av-vbi.c */ 384/* cx18_av-vbi.c */
diff --git a/drivers/media/video/cx18/cx18-controls.c b/drivers/media/video/cx18/cx18-controls.c
index 97d7b7e100a3..282a3d29fdaa 100644
--- a/drivers/media/video/cx18/cx18-controls.c
+++ b/drivers/media/video/cx18/cx18-controls.c
@@ -30,152 +30,11 @@
30#include "cx18-mailbox.h" 30#include "cx18-mailbox.h"
31#include "cx18-controls.h" 31#include "cx18-controls.h"
32 32
33/* Must be sorted from low to high control ID! */ 33static int cx18_s_stream_vbi_fmt(struct cx2341x_handler *cxhdl, u32 fmt)
34static const u32 user_ctrls[] = {
35 V4L2_CID_USER_CLASS,
36 V4L2_CID_BRIGHTNESS,
37 V4L2_CID_CONTRAST,
38 V4L2_CID_SATURATION,
39 V4L2_CID_HUE,
40 V4L2_CID_AUDIO_VOLUME,
41 V4L2_CID_AUDIO_BALANCE,
42 V4L2_CID_AUDIO_BASS,
43 V4L2_CID_AUDIO_TREBLE,
44 V4L2_CID_AUDIO_MUTE,
45 V4L2_CID_AUDIO_LOUDNESS,
46 0
47};
48
49static const u32 *ctrl_classes[] = {
50 user_ctrls,
51 cx2341x_mpeg_ctrls,
52 NULL
53};
54
55int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
56{
57 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
58 const char *name;
59
60 qctrl->id = v4l2_ctrl_next(ctrl_classes, qctrl->id);
61 if (qctrl->id == 0)
62 return -EINVAL;
63
64 switch (qctrl->id) {
65 /* Standard V4L2 controls */
66 case V4L2_CID_USER_CLASS:
67 return v4l2_ctrl_query_fill(qctrl, 0, 0, 0, 0);
68 case V4L2_CID_BRIGHTNESS:
69 case V4L2_CID_HUE:
70 case V4L2_CID_SATURATION:
71 case V4L2_CID_CONTRAST:
72 if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
73 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
74 return 0;
75
76 case V4L2_CID_AUDIO_VOLUME:
77 case V4L2_CID_AUDIO_MUTE:
78 case V4L2_CID_AUDIO_BALANCE:
79 case V4L2_CID_AUDIO_BASS:
80 case V4L2_CID_AUDIO_TREBLE:
81 case V4L2_CID_AUDIO_LOUDNESS:
82 if (v4l2_subdev_call(cx->sd_av, core, queryctrl, qctrl))
83 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
84 return 0;
85
86 default:
87 if (cx2341x_ctrl_query(&cx->params, qctrl))
88 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
89 return 0;
90 }
91 strncpy(qctrl->name, name, sizeof(qctrl->name) - 1);
92 qctrl->name[sizeof(qctrl->name) - 1] = 0;
93 return 0;
94}
95
96int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
97{ 34{
98 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 35 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
99 struct v4l2_queryctrl qctrl; 36 int type = cxhdl->stream_type->val;
100
101 qctrl.id = qmenu->id;
102 cx18_queryctrl(file, fh, &qctrl);
103 return v4l2_ctrl_query_menu(qmenu, &qctrl,
104 cx2341x_ctrl_get_menu(&cx->params, qmenu->id));
105}
106
107static int cx18_try_ctrl(struct file *file, void *fh,
108 struct v4l2_ext_control *vctrl)
109{
110 struct v4l2_queryctrl qctrl;
111 const char * const *menu_items = NULL;
112 int err;
113
114 qctrl.id = vctrl->id;
115 err = cx18_queryctrl(file, fh, &qctrl);
116 if (err)
117 return err;
118 if (qctrl.type == V4L2_CTRL_TYPE_MENU)
119 menu_items = v4l2_ctrl_get_menu(qctrl.id);
120 return v4l2_ctrl_check(vctrl, &qctrl, menu_items);
121}
122
123static int cx18_s_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
124{
125 switch (vctrl->id) {
126 /* Standard V4L2 controls */
127 case V4L2_CID_BRIGHTNESS:
128 case V4L2_CID_HUE:
129 case V4L2_CID_SATURATION:
130 case V4L2_CID_CONTRAST:
131 return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
132
133 case V4L2_CID_AUDIO_VOLUME:
134 case V4L2_CID_AUDIO_MUTE:
135 case V4L2_CID_AUDIO_BALANCE:
136 case V4L2_CID_AUDIO_BASS:
137 case V4L2_CID_AUDIO_TREBLE:
138 case V4L2_CID_AUDIO_LOUDNESS:
139 return v4l2_subdev_call(cx->sd_av, core, s_ctrl, vctrl);
140
141 default:
142 CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
143 return -EINVAL;
144 }
145 return 0;
146}
147
148static int cx18_g_ctrl(struct cx18 *cx, struct v4l2_control *vctrl)
149{
150 switch (vctrl->id) {
151 /* Standard V4L2 controls */
152 case V4L2_CID_BRIGHTNESS:
153 case V4L2_CID_HUE:
154 case V4L2_CID_SATURATION:
155 case V4L2_CID_CONTRAST:
156 return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
157
158 case V4L2_CID_AUDIO_VOLUME:
159 case V4L2_CID_AUDIO_MUTE:
160 case V4L2_CID_AUDIO_BALANCE:
161 case V4L2_CID_AUDIO_BASS:
162 case V4L2_CID_AUDIO_TREBLE:
163 case V4L2_CID_AUDIO_LOUDNESS:
164 return v4l2_subdev_call(cx->sd_av, core, g_ctrl, vctrl);
165 37
166 default:
167 CX18_DEBUG_IOCTL("invalid control 0x%x\n", vctrl->id);
168 return -EINVAL;
169 }
170 return 0;
171}
172
173static int cx18_setup_vbi_fmt(struct cx18 *cx,
174 enum v4l2_mpeg_stream_vbi_fmt fmt,
175 enum v4l2_mpeg_stream_type type)
176{
177 if (!(cx->v4l2_cap & V4L2_CAP_SLICED_VBI_CAPTURE))
178 return -EINVAL;
179 if (atomic_read(&cx->ana_capturing) > 0) 38 if (atomic_read(&cx->ana_capturing) > 0)
180 return -EBUSY; 39 return -EBUSY;
181 40
@@ -230,121 +89,43 @@ static int cx18_setup_vbi_fmt(struct cx18 *cx,
230 return 0; 89 return 0;
231} 90}
232 91
233int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) 92static int cx18_s_video_encoding(struct cx2341x_handler *cxhdl, u32 val)
234{ 93{
235 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 94 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
236 struct v4l2_control ctrl; 95 int is_mpeg1 = val == V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
237 96 struct v4l2_mbus_framefmt fmt;
238 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { 97
239 int i; 98 /* fix videodecoder resolution */
240 int err = 0; 99 fmt.width = cxhdl->width / (is_mpeg1 ? 2 : 1);
241 100 fmt.height = cxhdl->height;
242 for (i = 0; i < c->count; i++) { 101 fmt.code = V4L2_MBUS_FMT_FIXED;
243 ctrl.id = c->controls[i].id; 102 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
244 ctrl.value = c->controls[i].value; 103 return 0;
245 err = cx18_g_ctrl(cx, &ctrl);
246 c->controls[i].value = ctrl.value;
247 if (err) {
248 c->error_idx = i;
249 break;
250 }
251 }
252 return err;
253 }
254 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
255 return cx2341x_ext_ctrls(&cx->params, 0, c, VIDIOC_G_EXT_CTRLS);
256 return -EINVAL;
257} 104}
258 105
259int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) 106static int cx18_s_audio_sampling_freq(struct cx2341x_handler *cxhdl, u32 idx)
260{ 107{
261 struct cx18_open_id *id = fh; 108 static const u32 freqs[3] = { 44100, 48000, 32000 };
262 struct cx18 *cx = id->cx; 109 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
263 int ret;
264 struct v4l2_control ctrl;
265
266 ret = v4l2_prio_check(&cx->prio, id->prio);
267 if (ret)
268 return ret;
269
270 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
271 int i;
272 int err = 0;
273
274 for (i = 0; i < c->count; i++) {
275 ctrl.id = c->controls[i].id;
276 ctrl.value = c->controls[i].value;
277 err = cx18_s_ctrl(cx, &ctrl);
278 c->controls[i].value = ctrl.value;
279 if (err) {
280 c->error_idx = i;
281 break;
282 }
283 }
284 return err;
285 }
286 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
287 static u32 freqs[3] = { 44100, 48000, 32000 };
288 struct cx18_api_func_private priv;
289 struct cx2341x_mpeg_params p = cx->params;
290 int err = cx2341x_ext_ctrls(&p, atomic_read(&cx->ana_capturing),
291 c, VIDIOC_S_EXT_CTRLS);
292 unsigned int idx;
293
294 if (err)
295 return err;
296 110
297 if (p.video_encoding != cx->params.video_encoding) { 111 /* The audio clock of the digitizer must match the codec sample
298 int is_mpeg1 = p.video_encoding == 112 rate otherwise you get some very strange effects. */
299 V4L2_MPEG_VIDEO_ENCODING_MPEG_1; 113 if (idx < ARRAY_SIZE(freqs))
300 struct v4l2_mbus_framefmt fmt; 114 cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
301 115 return 0;
302 /* fix videodecoder resolution */
303 fmt.width = cx->params.width / (is_mpeg1 ? 2 : 1);
304 fmt.height = cx->params.height;
305 fmt.code = V4L2_MBUS_FMT_FIXED;
306 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &fmt);
307 }
308 priv.cx = cx;
309 priv.s = &cx->streams[id->type];
310 err = cx2341x_update(&priv, cx18_api_func, &cx->params, &p);
311 if (!err &&
312 (cx->params.stream_vbi_fmt != p.stream_vbi_fmt ||
313 cx->params.stream_type != p.stream_type))
314 err = cx18_setup_vbi_fmt(cx, p.stream_vbi_fmt,
315 p.stream_type);
316 cx->params = p;
317 cx->dualwatch_stereo_mode = p.audio_properties & 0x0300;
318 idx = p.audio_properties & 0x03;
319 /* The audio clock of the digitizer must match the codec sample
320 rate otherwise you get some very strange effects. */
321 if (idx < ARRAY_SIZE(freqs))
322 cx18_call_all(cx, audio, s_clock_freq, freqs[idx]);
323 return err;
324 }
325 return -EINVAL;
326} 116}
327 117
328int cx18_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c) 118static int cx18_s_audio_mode(struct cx2341x_handler *cxhdl, u32 val)
329{ 119{
330 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 120 struct cx18 *cx = container_of(cxhdl, struct cx18, cxhdl);
331 121
332 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { 122 cx->dualwatch_stereo_mode = val;
333 int i; 123 return 0;
334 int err = 0;
335
336 for (i = 0; i < c->count; i++) {
337 err = cx18_try_ctrl(file, fh, &c->controls[i]);
338 if (err) {
339 c->error_idx = i;
340 break;
341 }
342 }
343 return err;
344 }
345 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
346 return cx2341x_ext_ctrls(&cx->params,
347 atomic_read(&cx->ana_capturing),
348 c, VIDIOC_TRY_EXT_CTRLS);
349 return -EINVAL;
350} 124}
125
126struct cx2341x_handler_ops cx18_cxhdl_ops = {
127 .s_audio_mode = cx18_s_audio_mode,
128 .s_audio_sampling_freq = cx18_s_audio_sampling_freq,
129 .s_video_encoding = cx18_s_video_encoding,
130 .s_stream_vbi_fmt = cx18_s_stream_vbi_fmt,
131};
diff --git a/drivers/media/video/cx18/cx18-controls.h b/drivers/media/video/cx18/cx18-controls.h
index e46323700b81..cb5dfc7b2054 100644
--- a/drivers/media/video/cx18/cx18-controls.h
+++ b/drivers/media/video/cx18/cx18-controls.h
@@ -21,9 +21,4 @@
21 * 02111-1307 USA 21 * 02111-1307 USA
22 */ 22 */
23 23
24int cx18_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a); 24extern struct cx2341x_handler_ops cx18_cxhdl_ops;
25int cx18_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
26int cx18_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
27int cx18_try_ext_ctrls(struct file *file, void *fh,
28 struct v4l2_ext_controls *a);
29int cx18_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index b1c3cbd92743..321c1b79794c 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -36,6 +36,7 @@
36#include "cx18-scb.h" 36#include "cx18-scb.h"
37#include "cx18-mailbox.h" 37#include "cx18-mailbox.h"
38#include "cx18-ioctl.h" 38#include "cx18-ioctl.h"
39#include "cx18-controls.h"
39#include "tuner-xc2028.h" 40#include "tuner-xc2028.h"
40 41
41#include <media/tveeprom.h> 42#include <media/tveeprom.h>
@@ -729,15 +730,22 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
729 cx->open_id = 1; 730 cx->open_id = 1;
730 731
731 /* Initial settings */ 732 /* Initial settings */
732 cx2341x_fill_defaults(&cx->params); 733 cx->cxhdl.port = CX2341X_PORT_MEMORY;
733 cx->temporal_strength = cx->params.video_temporal_filter; 734 cx->cxhdl.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI;
734 cx->spatial_strength = cx->params.video_spatial_filter; 735 cx->cxhdl.ops = &cx18_cxhdl_ops;
735 cx->filter_mode = cx->params.video_spatial_filter_mode | 736 cx->cxhdl.func = cx18_api_func;
736 (cx->params.video_temporal_filter_mode << 1) | 737 cx->cxhdl.priv = &cx->streams[CX18_ENC_STREAM_TYPE_MPG];
737 (cx->params.video_median_filter_type << 2); 738 ret = cx2341x_handler_init(&cx->cxhdl, 50);
738 cx->params.port = CX2341X_PORT_MEMORY; 739 if (ret)
739 cx->params.capabilities = 740 return ret;
740 CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_SLICED_VBI; 741 cx->v4l2_dev.ctrl_handler = &cx->cxhdl.hdl;
742
743 cx->temporal_strength = cx->cxhdl.video_temporal_filter->cur.val;
744 cx->spatial_strength = cx->cxhdl.video_spatial_filter->cur.val;
745 cx->filter_mode = cx->cxhdl.video_spatial_filter_mode->cur.val |
746 (cx->cxhdl.video_temporal_filter_mode->cur.val << 1) |
747 (cx->cxhdl.video_median_filter_type->cur.val << 2);
748
741 init_waitqueue_head(&cx->cap_w); 749 init_waitqueue_head(&cx->cap_w);
742 init_waitqueue_head(&cx->mb_apu_waitq); 750 init_waitqueue_head(&cx->mb_apu_waitq);
743 init_waitqueue_head(&cx->mb_cpu_waitq); 751 init_waitqueue_head(&cx->mb_cpu_waitq);
@@ -1049,7 +1057,7 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1049 else 1057 else
1050 cx->is_50hz = 1; 1058 cx->is_50hz = 1;
1051 1059
1052 cx->params.video_gop_size = cx->is_60hz ? 15 : 12; 1060 cx2341x_handler_set_50hz(&cx->cxhdl, !cx->is_60hz);
1053 1061
1054 if (cx->options.radio > 0) 1062 if (cx->options.radio > 0)
1055 cx->v4l2_cap |= V4L2_CAP_RADIO; 1063 cx->v4l2_cap |= V4L2_CAP_RADIO;
@@ -1095,7 +1103,6 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1095 1103
1096 /* Load cx18 submodules (cx18-alsa) */ 1104 /* Load cx18 submodules (cx18-alsa) */
1097 request_modules(cx); 1105 request_modules(cx);
1098
1099 return 0; 1106 return 0;
1100 1107
1101free_streams: 1108free_streams:
@@ -1278,6 +1285,8 @@ static void cx18_remove(struct pci_dev *pci_dev)
1278 for (i = 0; i < CX18_VBI_FRAMES; i++) 1285 for (i = 0; i < CX18_VBI_FRAMES; i++)
1279 kfree(cx->vbi.sliced_mpeg_data[i]); 1286 kfree(cx->vbi.sliced_mpeg_data[i]);
1280 1287
1288 v4l2_ctrl_handler_free(&cx->av_state.hdl);
1289
1281 CX18_INFO("Removed %s\n", cx->card_name); 1290 CX18_INFO("Removed %s\n", cx->card_name);
1282 1291
1283 v4l2_device_unregister(v4l2_dev); 1292 v4l2_device_unregister(v4l2_dev);
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h
index f736679d2517..b86a740c68df 100644
--- a/drivers/media/video/cx18/cx18-driver.h
+++ b/drivers/media/video/cx18/cx18-driver.h
@@ -50,6 +50,7 @@
50#include <media/v4l2-common.h> 50#include <media/v4l2-common.h>
51#include <media/v4l2-ioctl.h> 51#include <media/v4l2-ioctl.h>
52#include <media/v4l2-device.h> 52#include <media/v4l2-device.h>
53#include <media/v4l2-fh.h>
53#include <media/tuner.h> 54#include <media/tuner.h>
54#include <media/ir-kbd-i2c.h> 55#include <media/ir-kbd-i2c.h>
55#include "cx18-mailbox.h" 56#include "cx18-mailbox.h"
@@ -405,12 +406,22 @@ struct cx18_stream {
405}; 406};
406 407
407struct cx18_open_id { 408struct cx18_open_id {
409 struct v4l2_fh fh;
408 u32 open_id; 410 u32 open_id;
409 int type; 411 int type;
410 enum v4l2_priority prio;
411 struct cx18 *cx; 412 struct cx18 *cx;
412}; 413};
413 414
415static inline struct cx18_open_id *fh2id(struct v4l2_fh *fh)
416{
417 return container_of(fh, struct cx18_open_id, fh);
418}
419
420static inline struct cx18_open_id *file2id(struct file *file)
421{
422 return fh2id(file->private_data);
423}
424
414/* forward declaration of struct defined in cx18-cards.h */ 425/* forward declaration of struct defined in cx18-cards.h */
415struct cx18_card; 426struct cx18_card;
416 427
@@ -565,7 +576,7 @@ struct cx18 {
565 struct cx18_av_state av_state; 576 struct cx18_av_state av_state;
566 577
567 /* codec settings */ 578 /* codec settings */
568 struct cx2341x_mpeg_params params; 579 struct cx2341x_handler cxhdl;
569 u32 filter_mode; 580 u32 filter_mode;
570 u32 temporal_strength; 581 u32 temporal_strength;
571 u32 spatial_strength; 582 u32 spatial_strength;
@@ -593,7 +604,6 @@ struct cx18 {
593 uninitialized value in the stream->id. */ 604 uninitialized value in the stream->id. */
594 605
595 u32 base_addr; 606 u32 base_addr;
596 struct v4l2_prio_state prio;
597 607
598 u8 card_rev; 608 u8 card_rev;
599 void __iomem *enc_mem, *reg_mem; 609 void __iomem *enc_mem, *reg_mem;
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c
index 9f23b90732f2..e9802d99439b 100644
--- a/drivers/media/video/cx18/cx18-fileops.c
+++ b/drivers/media/video/cx18/cx18-fileops.c
@@ -160,13 +160,10 @@ EXPORT_SYMBOL(cx18_release_stream);
160static void cx18_dualwatch(struct cx18 *cx) 160static void cx18_dualwatch(struct cx18 *cx)
161{ 161{
162 struct v4l2_tuner vt; 162 struct v4l2_tuner vt;
163 u32 new_bitmap;
164 u32 new_stereo_mode; 163 u32 new_stereo_mode;
165 const u32 stereo_mask = 0x0300;
166 const u32 dual = 0x0200; 164 const u32 dual = 0x0200;
167 u32 h;
168 165
169 new_stereo_mode = cx->params.audio_properties & stereo_mask; 166 new_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
170 memset(&vt, 0, sizeof(vt)); 167 memset(&vt, 0, sizeof(vt));
171 cx18_call_all(cx, tuner, g_tuner, &vt); 168 cx18_call_all(cx, tuner, g_tuner, &vt);
172 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 && 169 if (vt.audmode == V4L2_TUNER_MODE_LANG1_LANG2 &&
@@ -176,25 +173,10 @@ static void cx18_dualwatch(struct cx18 *cx)
176 if (new_stereo_mode == cx->dualwatch_stereo_mode) 173 if (new_stereo_mode == cx->dualwatch_stereo_mode)
177 return; 174 return;
178 175
179 new_bitmap = new_stereo_mode 176 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x.\n",
180 | (cx->params.audio_properties & ~stereo_mask); 177 cx->dualwatch_stereo_mode, new_stereo_mode);
181 178 if (v4l2_ctrl_s_ctrl(cx->cxhdl.audio_mode, new_stereo_mode))
182 CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. " 179 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
183 "new audio_bitmask=0x%ux\n",
184 cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap);
185
186 h = cx18_find_handle(cx);
187 if (h == CX18_INVALID_TASK_HANDLE) {
188 CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n");
189 return;
190 }
191
192 if (cx18_vapi(cx,
193 CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) {
194 cx->dualwatch_stereo_mode = new_stereo_mode;
195 return;
196 }
197 CX18_DEBUG_INFO("dualwatch: changing stereo flag failed\n");
198} 180}
199 181
200 182
@@ -603,7 +585,7 @@ start_failed:
603ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count, 585ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
604 loff_t *pos) 586 loff_t *pos)
605{ 587{
606 struct cx18_open_id *id = filp->private_data; 588 struct cx18_open_id *id = file2id(filp);
607 struct cx18 *cx = id->cx; 589 struct cx18 *cx = id->cx;
608 struct cx18_stream *s = &cx->streams[id->type]; 590 struct cx18_stream *s = &cx->streams[id->type];
609 int rc; 591 int rc;
@@ -620,7 +602,7 @@ ssize_t cx18_v4l2_read(struct file *filp, char __user *buf, size_t count,
620 602
621unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait) 603unsigned int cx18_v4l2_enc_poll(struct file *filp, poll_table *wait)
622{ 604{
623 struct cx18_open_id *id = filp->private_data; 605 struct cx18_open_id *id = file2id(filp);
624 struct cx18 *cx = id->cx; 606 struct cx18 *cx = id->cx;
625 struct cx18_stream *s = &cx->streams[id->type]; 607 struct cx18_stream *s = &cx->streams[id->type];
626 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags); 608 int eof = test_bit(CX18_F_S_STREAMOFF, &s->s_flags);
@@ -694,13 +676,15 @@ void cx18_stop_capture(struct cx18_open_id *id, int gop_end)
694 676
695int cx18_v4l2_close(struct file *filp) 677int cx18_v4l2_close(struct file *filp)
696{ 678{
697 struct cx18_open_id *id = filp->private_data; 679 struct v4l2_fh *fh = filp->private_data;
680 struct cx18_open_id *id = fh2id(fh);
698 struct cx18 *cx = id->cx; 681 struct cx18 *cx = id->cx;
699 struct cx18_stream *s = &cx->streams[id->type]; 682 struct cx18_stream *s = &cx->streams[id->type];
700 683
701 CX18_DEBUG_IOCTL("close() of %s\n", s->name); 684 CX18_DEBUG_IOCTL("close() of %s\n", s->name);
702 685
703 v4l2_prio_close(&cx->prio, id->prio); 686 v4l2_fh_del(fh);
687 v4l2_fh_exit(fh);
704 688
705 /* Easy case first: this stream was never claimed by us */ 689 /* Easy case first: this stream was never claimed by us */
706 if (s->id != id->open_id) { 690 if (s->id != id->open_id) {
@@ -724,8 +708,8 @@ int cx18_v4l2_close(struct file *filp)
724 if (atomic_read(&cx->ana_capturing) > 0) { 708 if (atomic_read(&cx->ana_capturing) > 0) {
725 /* Undo video mute */ 709 /* Undo video mute */
726 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 710 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
727 cx->params.video_mute | 711 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute) |
728 (cx->params.video_mute_yuv << 8)); 712 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8)));
729 } 713 }
730 /* Done! Unmute and continue. */ 714 /* Done! Unmute and continue. */
731 cx18_unmute(cx); 715 cx18_unmute(cx);
@@ -746,22 +730,24 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
746 CX18_DEBUG_FILE("open %s\n", s->name); 730 CX18_DEBUG_FILE("open %s\n", s->name);
747 731
748 /* Allocate memory */ 732 /* Allocate memory */
749 item = kmalloc(sizeof(struct cx18_open_id), GFP_KERNEL); 733 item = kzalloc(sizeof(struct cx18_open_id), GFP_KERNEL);
750 if (NULL == item) { 734 if (NULL == item) {
751 CX18_DEBUG_WARN("nomem on v4l2 open\n"); 735 CX18_DEBUG_WARN("nomem on v4l2 open\n");
752 return -ENOMEM; 736 return -ENOMEM;
753 } 737 }
738 v4l2_fh_init(&item->fh, s->video_dev);
739
754 item->cx = cx; 740 item->cx = cx;
755 item->type = s->type; 741 item->type = s->type;
756 v4l2_prio_open(&cx->prio, &item->prio);
757 742
758 item->open_id = cx->open_id++; 743 item->open_id = cx->open_id++;
759 filp->private_data = item; 744 filp->private_data = &item->fh;
760 745
761 if (item->type == CX18_ENC_STREAM_TYPE_RAD) { 746 if (item->type == CX18_ENC_STREAM_TYPE_RAD) {
762 /* Try to claim this stream */ 747 /* Try to claim this stream */
763 if (cx18_claim_stream(item, item->type)) { 748 if (cx18_claim_stream(item, item->type)) {
764 /* No, it's already in use */ 749 /* No, it's already in use */
750 v4l2_fh_exit(&item->fh);
765 kfree(item); 751 kfree(item);
766 return -EBUSY; 752 return -EBUSY;
767 } 753 }
@@ -771,6 +757,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
771 /* switching to radio while capture is 757 /* switching to radio while capture is
772 in progress is not polite */ 758 in progress is not polite */
773 cx18_release_stream(s); 759 cx18_release_stream(s);
760 v4l2_fh_exit(&item->fh);
774 kfree(item); 761 kfree(item);
775 return -EBUSY; 762 return -EBUSY;
776 } 763 }
@@ -787,6 +774,7 @@ static int cx18_serialized_open(struct cx18_stream *s, struct file *filp)
787 /* Done! Unmute and continue. */ 774 /* Done! Unmute and continue. */
788 cx18_unmute(cx); 775 cx18_unmute(cx);
789 } 776 }
777 v4l2_fh_add(&item->fh);
790 return 0; 778 return 0;
791} 779}
792 780
diff --git a/drivers/media/video/cx18/cx18-i2c.c b/drivers/media/video/cx18/cx18-i2c.c
index c330fb917b50..040aaa87579d 100644
--- a/drivers/media/video/cx18/cx18-i2c.c
+++ b/drivers/media/video/cx18/cx18-i2c.c
@@ -96,7 +96,7 @@ static int cx18_i2c_new_ir(struct cx18 *cx, struct i2c_adapter *adap, u32 hw,
96 /* Our default information for ir-kbd-i2c.c to use */ 96 /* Our default information for ir-kbd-i2c.c to use */
97 switch (hw) { 97 switch (hw) {
98 case CX18_HW_Z8F0811_IR_RX_HAUP: 98 case CX18_HW_Z8F0811_IR_RX_HAUP:
99 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 99 init_data->ir_codes = RC_MAP_HAUPPAUGE;
100 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 100 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
101 init_data->type = RC_TYPE_RC5; 101 init_data->type = RC_TYPE_RC5;
102 init_data->name = cx->card_name; 102 init_data->name = cx->card_name;
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index 7150195740dc..86c30b9963e5 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -148,12 +148,12 @@ u16 cx18_get_service_set(struct v4l2_sliced_vbi_format *fmt)
148static int cx18_g_fmt_vid_cap(struct file *file, void *fh, 148static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
149 struct v4l2_format *fmt) 149 struct v4l2_format *fmt)
150{ 150{
151 struct cx18_open_id *id = fh; 151 struct cx18_open_id *id = fh2id(fh);
152 struct cx18 *cx = id->cx; 152 struct cx18 *cx = id->cx;
153 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 153 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
154 154
155 pixfmt->width = cx->params.width; 155 pixfmt->width = cx->cxhdl.width;
156 pixfmt->height = cx->params.height; 156 pixfmt->height = cx->cxhdl.height;
157 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M; 157 pixfmt->colorspace = V4L2_COLORSPACE_SMPTE170M;
158 pixfmt->field = V4L2_FIELD_INTERLACED; 158 pixfmt->field = V4L2_FIELD_INTERLACED;
159 pixfmt->priv = 0; 159 pixfmt->priv = 0;
@@ -173,7 +173,7 @@ static int cx18_g_fmt_vid_cap(struct file *file, void *fh,
173static int cx18_g_fmt_vbi_cap(struct file *file, void *fh, 173static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
174 struct v4l2_format *fmt) 174 struct v4l2_format *fmt)
175{ 175{
176 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 176 struct cx18 *cx = fh2id(fh)->cx;
177 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; 177 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
178 178
179 vbifmt->sampling_rate = 27000000; 179 vbifmt->sampling_rate = 27000000;
@@ -192,7 +192,7 @@ static int cx18_g_fmt_vbi_cap(struct file *file, void *fh,
192static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh, 192static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
193 struct v4l2_format *fmt) 193 struct v4l2_format *fmt)
194{ 194{
195 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 195 struct cx18 *cx = fh2id(fh)->cx;
196 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 196 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
197 197
198 /* sane, V4L2 spec compliant, defaults */ 198 /* sane, V4L2 spec compliant, defaults */
@@ -221,7 +221,7 @@ static int cx18_g_fmt_sliced_vbi_cap(struct file *file, void *fh,
221static int cx18_try_fmt_vid_cap(struct file *file, void *fh, 221static int cx18_try_fmt_vid_cap(struct file *file, void *fh,
222 struct v4l2_format *fmt) 222 struct v4l2_format *fmt)
223{ 223{
224 struct cx18_open_id *id = fh; 224 struct cx18_open_id *id = fh2id(fh);
225 struct cx18 *cx = id->cx; 225 struct cx18 *cx = id->cx;
226 int w = fmt->fmt.pix.width; 226 int w = fmt->fmt.pix.width;
227 int h = fmt->fmt.pix.height; 227 int h = fmt->fmt.pix.height;
@@ -252,7 +252,7 @@ static int cx18_try_fmt_vbi_cap(struct file *file, void *fh,
252static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh, 252static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
253 struct v4l2_format *fmt) 253 struct v4l2_format *fmt)
254{ 254{
255 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 255 struct cx18 *cx = fh2id(fh)->cx;
256 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 256 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
257 257
258 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; 258 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
@@ -271,30 +271,26 @@ static int cx18_try_fmt_sliced_vbi_cap(struct file *file, void *fh,
271static int cx18_s_fmt_vid_cap(struct file *file, void *fh, 271static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
272 struct v4l2_format *fmt) 272 struct v4l2_format *fmt)
273{ 273{
274 struct cx18_open_id *id = fh; 274 struct cx18_open_id *id = fh2id(fh);
275 struct cx18 *cx = id->cx; 275 struct cx18 *cx = id->cx;
276 struct v4l2_mbus_framefmt mbus_fmt; 276 struct v4l2_mbus_framefmt mbus_fmt;
277 int ret; 277 int ret;
278 int w, h; 278 int w, h;
279 279
280 ret = v4l2_prio_check(&cx->prio, id->prio);
281 if (ret)
282 return ret;
283
284 ret = cx18_try_fmt_vid_cap(file, fh, fmt); 280 ret = cx18_try_fmt_vid_cap(file, fh, fmt);
285 if (ret) 281 if (ret)
286 return ret; 282 return ret;
287 w = fmt->fmt.pix.width; 283 w = fmt->fmt.pix.width;
288 h = fmt->fmt.pix.height; 284 h = fmt->fmt.pix.height;
289 285
290 if (cx->params.width == w && cx->params.height == h) 286 if (cx->cxhdl.width == w && cx->cxhdl.height == h)
291 return 0; 287 return 0;
292 288
293 if (atomic_read(&cx->ana_capturing) > 0) 289 if (atomic_read(&cx->ana_capturing) > 0)
294 return -EBUSY; 290 return -EBUSY;
295 291
296 mbus_fmt.width = cx->params.width = w; 292 mbus_fmt.width = cx->cxhdl.width = w;
297 mbus_fmt.height = cx->params.height = h; 293 mbus_fmt.height = cx->cxhdl.height = h;
298 mbus_fmt.code = V4L2_MBUS_FMT_FIXED; 294 mbus_fmt.code = V4L2_MBUS_FMT_FIXED;
299 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt); 295 v4l2_subdev_call(cx->sd_av, video, s_mbus_fmt, &mbus_fmt);
300 return cx18_g_fmt_vid_cap(file, fh, fmt); 296 return cx18_g_fmt_vid_cap(file, fh, fmt);
@@ -303,14 +299,10 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh,
303static int cx18_s_fmt_vbi_cap(struct file *file, void *fh, 299static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
304 struct v4l2_format *fmt) 300 struct v4l2_format *fmt)
305{ 301{
306 struct cx18_open_id *id = fh; 302 struct cx18_open_id *id = fh2id(fh);
307 struct cx18 *cx = id->cx; 303 struct cx18 *cx = id->cx;
308 int ret; 304 int ret;
309 305
310 ret = v4l2_prio_check(&cx->prio, id->prio);
311 if (ret)
312 return ret;
313
314 /* 306 /*
315 * Changing the Encoder's Raw VBI parameters won't have any effect 307 * Changing the Encoder's Raw VBI parameters won't have any effect
316 * if any analog capture is ongoing 308 * if any analog capture is ongoing
@@ -337,15 +329,11 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
337static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh, 329static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
338 struct v4l2_format *fmt) 330 struct v4l2_format *fmt)
339{ 331{
340 struct cx18_open_id *id = fh; 332 struct cx18_open_id *id = fh2id(fh);
341 struct cx18 *cx = id->cx; 333 struct cx18 *cx = id->cx;
342 int ret; 334 int ret;
343 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 335 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
344 336
345 ret = v4l2_prio_check(&cx->prio, id->prio);
346 if (ret)
347 return ret;
348
349 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); 337 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
350 338
351 /* 339 /*
@@ -372,7 +360,7 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
372static int cx18_g_chip_ident(struct file *file, void *fh, 360static int cx18_g_chip_ident(struct file *file, void *fh,
373 struct v4l2_dbg_chip_ident *chip) 361 struct v4l2_dbg_chip_ident *chip)
374{ 362{
375 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 363 struct cx18 *cx = fh2id(fh)->cx;
376 int err = 0; 364 int err = 0;
377 365
378 chip->ident = V4L2_IDENT_NONE; 366 chip->ident = V4L2_IDENT_NONE;
@@ -442,7 +430,7 @@ static int cx18_cxc(struct cx18 *cx, unsigned int cmd, void *arg)
442static int cx18_g_register(struct file *file, void *fh, 430static int cx18_g_register(struct file *file, void *fh,
443 struct v4l2_dbg_register *reg) 431 struct v4l2_dbg_register *reg)
444{ 432{
445 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 433 struct cx18 *cx = fh2id(fh)->cx;
446 434
447 if (v4l2_chip_match_host(&reg->match)) 435 if (v4l2_chip_match_host(&reg->match))
448 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg); 436 return cx18_cxc(cx, VIDIOC_DBG_G_REGISTER, reg);
@@ -454,7 +442,7 @@ static int cx18_g_register(struct file *file, void *fh,
454static int cx18_s_register(struct file *file, void *fh, 442static int cx18_s_register(struct file *file, void *fh,
455 struct v4l2_dbg_register *reg) 443 struct v4l2_dbg_register *reg)
456{ 444{
457 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 445 struct cx18 *cx = fh2id(fh)->cx;
458 446
459 if (v4l2_chip_match_host(&reg->match)) 447 if (v4l2_chip_match_host(&reg->match))
460 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg); 448 return cx18_cxc(cx, VIDIOC_DBG_S_REGISTER, reg);
@@ -464,26 +452,10 @@ static int cx18_s_register(struct file *file, void *fh,
464} 452}
465#endif 453#endif
466 454
467static int cx18_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
468{
469 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx;
470
471 *p = v4l2_prio_max(&cx->prio);
472 return 0;
473}
474
475static int cx18_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
476{
477 struct cx18_open_id *id = fh;
478 struct cx18 *cx = id->cx;
479
480 return v4l2_prio_change(&cx->prio, &id->prio, prio);
481}
482
483static int cx18_querycap(struct file *file, void *fh, 455static int cx18_querycap(struct file *file, void *fh,
484 struct v4l2_capability *vcap) 456 struct v4l2_capability *vcap)
485{ 457{
486 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 458 struct cx18 *cx = fh2id(fh)->cx;
487 459
488 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver)); 460 strlcpy(vcap->driver, CX18_DRIVER_NAME, sizeof(vcap->driver));
489 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card)); 461 strlcpy(vcap->card, cx->card_name, sizeof(vcap->card));
@@ -496,14 +468,14 @@ static int cx18_querycap(struct file *file, void *fh,
496 468
497static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) 469static int cx18_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
498{ 470{
499 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 471 struct cx18 *cx = fh2id(fh)->cx;
500 472
501 return cx18_get_audio_input(cx, vin->index, vin); 473 return cx18_get_audio_input(cx, vin->index, vin);
502} 474}
503 475
504static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) 476static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
505{ 477{
506 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 478 struct cx18 *cx = fh2id(fh)->cx;
507 479
508 vin->index = cx->audio_input; 480 vin->index = cx->audio_input;
509 return cx18_get_audio_input(cx, vin->index, vin); 481 return cx18_get_audio_input(cx, vin->index, vin);
@@ -511,7 +483,7 @@ static int cx18_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
511 483
512static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) 484static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
513{ 485{
514 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 486 struct cx18 *cx = fh2id(fh)->cx;
515 487
516 if (vout->index >= cx->nof_audio_inputs) 488 if (vout->index >= cx->nof_audio_inputs)
517 return -EINVAL; 489 return -EINVAL;
@@ -522,7 +494,7 @@ static int cx18_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
522 494
523static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 495static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
524{ 496{
525 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 497 struct cx18 *cx = fh2id(fh)->cx;
526 498
527 /* set it to defaults from our table */ 499 /* set it to defaults from our table */
528 return cx18_get_input(cx, vin->index, vin); 500 return cx18_get_input(cx, vin->index, vin);
@@ -531,7 +503,7 @@ static int cx18_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
531static int cx18_cropcap(struct file *file, void *fh, 503static int cx18_cropcap(struct file *file, void *fh,
532 struct v4l2_cropcap *cropcap) 504 struct v4l2_cropcap *cropcap)
533{ 505{
534 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 506 struct cx18 *cx = fh2id(fh)->cx;
535 507
536 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 508 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
537 return -EINVAL; 509 return -EINVAL;
@@ -546,13 +518,8 @@ static int cx18_cropcap(struct file *file, void *fh,
546 518
547static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) 519static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
548{ 520{
549 struct cx18_open_id *id = fh; 521 struct cx18_open_id *id = fh2id(fh);
550 struct cx18 *cx = id->cx; 522 struct cx18 *cx = id->cx;
551 int ret;
552
553 ret = v4l2_prio_check(&cx->prio, id->prio);
554 if (ret)
555 return ret;
556 523
557 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 524 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
558 return -EINVAL; 525 return -EINVAL;
@@ -562,7 +529,7 @@ static int cx18_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
562 529
563static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) 530static int cx18_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
564{ 531{
565 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 532 struct cx18 *cx = fh2id(fh)->cx;
566 533
567 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 534 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
568 return -EINVAL; 535 return -EINVAL;
@@ -590,7 +557,7 @@ static int cx18_enum_fmt_vid_cap(struct file *file, void *fh,
590 557
591static int cx18_g_input(struct file *file, void *fh, unsigned int *i) 558static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
592{ 559{
593 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 560 struct cx18 *cx = fh2id(fh)->cx;
594 561
595 *i = cx->active_input; 562 *i = cx->active_input;
596 return 0; 563 return 0;
@@ -598,13 +565,8 @@ static int cx18_g_input(struct file *file, void *fh, unsigned int *i)
598 565
599int cx18_s_input(struct file *file, void *fh, unsigned int inp) 566int cx18_s_input(struct file *file, void *fh, unsigned int inp)
600{ 567{
601 struct cx18_open_id *id = fh; 568 struct cx18_open_id *id = fh2id(fh);
602 struct cx18 *cx = id->cx; 569 struct cx18 *cx = id->cx;
603 int ret;
604
605 ret = v4l2_prio_check(&cx->prio, id->prio);
606 if (ret)
607 return ret;
608 570
609 if (inp >= cx->nof_inputs) 571 if (inp >= cx->nof_inputs)
610 return -EINVAL; 572 return -EINVAL;
@@ -633,7 +595,7 @@ int cx18_s_input(struct file *file, void *fh, unsigned int inp)
633static int cx18_g_frequency(struct file *file, void *fh, 595static int cx18_g_frequency(struct file *file, void *fh,
634 struct v4l2_frequency *vf) 596 struct v4l2_frequency *vf)
635{ 597{
636 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 598 struct cx18 *cx = fh2id(fh)->cx;
637 599
638 if (vf->tuner != 0) 600 if (vf->tuner != 0)
639 return -EINVAL; 601 return -EINVAL;
@@ -644,13 +606,8 @@ static int cx18_g_frequency(struct file *file, void *fh,
644 606
645int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 607int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
646{ 608{
647 struct cx18_open_id *id = fh; 609 struct cx18_open_id *id = fh2id(fh);
648 struct cx18 *cx = id->cx; 610 struct cx18 *cx = id->cx;
649 int ret;
650
651 ret = v4l2_prio_check(&cx->prio, id->prio);
652 if (ret)
653 return ret;
654 611
655 if (vf->tuner != 0) 612 if (vf->tuner != 0)
656 return -EINVAL; 613 return -EINVAL;
@@ -664,7 +621,7 @@ int cx18_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
664 621
665static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std) 622static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
666{ 623{
667 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 624 struct cx18 *cx = fh2id(fh)->cx;
668 625
669 *std = cx->std; 626 *std = cx->std;
670 return 0; 627 return 0;
@@ -672,13 +629,8 @@ static int cx18_g_std(struct file *file, void *fh, v4l2_std_id *std)
672 629
673int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std) 630int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
674{ 631{
675 struct cx18_open_id *id = fh; 632 struct cx18_open_id *id = fh2id(fh);
676 struct cx18 *cx = id->cx; 633 struct cx18 *cx = id->cx;
677 int ret;
678
679 ret = v4l2_prio_check(&cx->prio, id->prio);
680 if (ret)
681 return ret;
682 634
683 if ((*std & V4L2_STD_ALL) == 0) 635 if ((*std & V4L2_STD_ALL) == 0)
684 return -EINVAL; 636 return -EINVAL;
@@ -696,9 +648,10 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
696 648
697 cx->std = *std; 649 cx->std = *std;
698 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0; 650 cx->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
699 cx->params.is_50hz = cx->is_50hz = !cx->is_60hz; 651 cx->is_50hz = !cx->is_60hz;
700 cx->params.width = 720; 652 cx2341x_handler_set_50hz(&cx->cxhdl, cx->is_50hz);
701 cx->params.height = cx->is_50hz ? 576 : 480; 653 cx->cxhdl.width = 720;
654 cx->cxhdl.height = cx->is_50hz ? 576 : 480;
702 cx->vbi.count = cx->is_50hz ? 18 : 12; 655 cx->vbi.count = cx->is_50hz ? 18 : 12;
703 cx->vbi.start[0] = cx->is_50hz ? 6 : 10; 656 cx->vbi.start[0] = cx->is_50hz ? 6 : 10;
704 cx->vbi.start[1] = cx->is_50hz ? 318 : 273; 657 cx->vbi.start[1] = cx->is_50hz ? 318 : 273;
@@ -712,13 +665,8 @@ int cx18_s_std(struct file *file, void *fh, v4l2_std_id *std)
712 665
713static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 666static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
714{ 667{
715 struct cx18_open_id *id = fh; 668 struct cx18_open_id *id = fh2id(fh);
716 struct cx18 *cx = id->cx; 669 struct cx18 *cx = id->cx;
717 int ret;
718
719 ret = v4l2_prio_check(&cx->prio, id->prio);
720 if (ret)
721 return ret;
722 670
723 if (vt->index != 0) 671 if (vt->index != 0)
724 return -EINVAL; 672 return -EINVAL;
@@ -729,7 +677,7 @@ static int cx18_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
729 677
730static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 678static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
731{ 679{
732 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 680 struct cx18 *cx = fh2id(fh)->cx;
733 681
734 if (vt->index != 0) 682 if (vt->index != 0)
735 return -EINVAL; 683 return -EINVAL;
@@ -750,7 +698,7 @@ static int cx18_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
750static int cx18_g_sliced_vbi_cap(struct file *file, void *fh, 698static int cx18_g_sliced_vbi_cap(struct file *file, void *fh,
751 struct v4l2_sliced_vbi_cap *cap) 699 struct v4l2_sliced_vbi_cap *cap)
752{ 700{
753 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 701 struct cx18 *cx = fh2id(fh)->cx;
754 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 702 int set = cx->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
755 int f, l; 703 int f, l;
756 704
@@ -871,7 +819,7 @@ static int cx18_process_idx_data(struct cx18_stream *s, struct cx18_mdl *mdl,
871static int cx18_g_enc_index(struct file *file, void *fh, 819static int cx18_g_enc_index(struct file *file, void *fh,
872 struct v4l2_enc_idx *idx) 820 struct v4l2_enc_idx *idx)
873{ 821{
874 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 822 struct cx18 *cx = fh2id(fh)->cx;
875 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX]; 823 struct cx18_stream *s = &cx->streams[CX18_ENC_STREAM_TYPE_IDX];
876 s32 tmp; 824 s32 tmp;
877 struct cx18_mdl *mdl; 825 struct cx18_mdl *mdl;
@@ -918,7 +866,7 @@ static int cx18_g_enc_index(struct file *file, void *fh,
918static int cx18_encoder_cmd(struct file *file, void *fh, 866static int cx18_encoder_cmd(struct file *file, void *fh,
919 struct v4l2_encoder_cmd *enc) 867 struct v4l2_encoder_cmd *enc)
920{ 868{
921 struct cx18_open_id *id = fh; 869 struct cx18_open_id *id = fh2id(fh);
922 struct cx18 *cx = id->cx; 870 struct cx18 *cx = id->cx;
923 u32 h; 871 u32 h;
924 872
@@ -979,7 +927,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
979static int cx18_try_encoder_cmd(struct file *file, void *fh, 927static int cx18_try_encoder_cmd(struct file *file, void *fh,
980 struct v4l2_encoder_cmd *enc) 928 struct v4l2_encoder_cmd *enc)
981{ 929{
982 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 930 struct cx18 *cx = fh2id(fh)->cx;
983 931
984 switch (enc->cmd) { 932 switch (enc->cmd) {
985 case V4L2_ENC_CMD_START: 933 case V4L2_ENC_CMD_START:
@@ -1011,7 +959,7 @@ static int cx18_try_encoder_cmd(struct file *file, void *fh,
1011 959
1012static int cx18_log_status(struct file *file, void *fh) 960static int cx18_log_status(struct file *file, void *fh)
1013{ 961{
1014 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 962 struct cx18 *cx = fh2id(fh)->cx;
1015 struct v4l2_input vidin; 963 struct v4l2_input vidin;
1016 struct v4l2_audio audin; 964 struct v4l2_audio audin;
1017 int i; 965 int i;
@@ -1035,7 +983,7 @@ static int cx18_log_status(struct file *file, void *fh)
1035 mutex_unlock(&cx->gpio_lock); 983 mutex_unlock(&cx->gpio_lock);
1036 CX18_INFO("Tuner: %s\n", 984 CX18_INFO("Tuner: %s\n",
1037 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV"); 985 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags) ? "Radio" : "TV");
1038 cx2341x_log_status(&cx->params, cx->v4l2_dev.name); 986 v4l2_ctrl_handler_log_status(&cx->cxhdl.hdl, cx->v4l2_dev.name);
1039 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags); 987 CX18_INFO("Status flags: 0x%08lx\n", cx->i_flags);
1040 for (i = 0; i < CX18_MAX_STREAMS; i++) { 988 for (i = 0; i < CX18_MAX_STREAMS; i++) {
1041 struct cx18_stream *s = &cx->streams[i]; 989 struct cx18_stream *s = &cx->streams[i];
@@ -1056,9 +1004,10 @@ static int cx18_log_status(struct file *file, void *fh)
1056 return 0; 1004 return 0;
1057} 1005}
1058 1006
1059static long cx18_default(struct file *file, void *fh, int cmd, void *arg) 1007static long cx18_default(struct file *file, void *fh, bool valid_prio,
1008 int cmd, void *arg)
1060{ 1009{
1061 struct cx18 *cx = ((struct cx18_open_id *)fh)->cx; 1010 struct cx18 *cx = fh2id(fh)->cx;
1062 1011
1063 switch (cmd) { 1012 switch (cmd) {
1064 case VIDIOC_INT_RESET: { 1013 case VIDIOC_INT_RESET: {
@@ -1080,14 +1029,12 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1080 unsigned long arg) 1029 unsigned long arg)
1081{ 1030{
1082 struct video_device *vfd = video_devdata(filp); 1031 struct video_device *vfd = video_devdata(filp);
1083 struct cx18_open_id *id = filp->private_data; 1032 struct cx18_open_id *id = file2id(filp);
1084 struct cx18 *cx = id->cx; 1033 struct cx18 *cx = id->cx;
1085 long res; 1034 long res;
1086 1035
1087 mutex_lock(&cx->serialize_lock); 1036 mutex_lock(&cx->serialize_lock);
1088 1037
1089 /* FIXME - consolidate v4l2_prio_check()'s here */
1090
1091 if (cx18_debug & CX18_DBGFLG_IOCTL) 1038 if (cx18_debug & CX18_DBGFLG_IOCTL)
1092 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; 1039 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1093 res = video_ioctl2(filp, cmd, arg); 1040 res = video_ioctl2(filp, cmd, arg);
@@ -1098,8 +1045,6 @@ long cx18_v4l2_ioctl(struct file *filp, unsigned int cmd,
1098 1045
1099static const struct v4l2_ioctl_ops cx18_ioctl_ops = { 1046static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1100 .vidioc_querycap = cx18_querycap, 1047 .vidioc_querycap = cx18_querycap,
1101 .vidioc_g_priority = cx18_g_priority,
1102 .vidioc_s_priority = cx18_s_priority,
1103 .vidioc_s_audio = cx18_s_audio, 1048 .vidioc_s_audio = cx18_s_audio,
1104 .vidioc_g_audio = cx18_g_audio, 1049 .vidioc_g_audio = cx18_g_audio,
1105 .vidioc_enumaudio = cx18_enumaudio, 1050 .vidioc_enumaudio = cx18_enumaudio,
@@ -1136,11 +1081,6 @@ static const struct v4l2_ioctl_ops cx18_ioctl_ops = {
1136 .vidioc_s_register = cx18_s_register, 1081 .vidioc_s_register = cx18_s_register,
1137#endif 1082#endif
1138 .vidioc_default = cx18_default, 1083 .vidioc_default = cx18_default,
1139 .vidioc_queryctrl = cx18_queryctrl,
1140 .vidioc_querymenu = cx18_querymenu,
1141 .vidioc_g_ext_ctrls = cx18_g_ext_ctrls,
1142 .vidioc_s_ext_ctrls = cx18_s_ext_ctrls,
1143 .vidioc_try_ext_ctrls = cx18_try_ext_ctrls,
1144}; 1084};
1145 1085
1146void cx18_set_funcs(struct video_device *vdev) 1086void cx18_set_funcs(struct video_device *vdev)
diff --git a/drivers/media/video/cx18/cx18-mailbox.c b/drivers/media/video/cx18/cx18-mailbox.c
index c545f3beef78..9605d54bd083 100644
--- a/drivers/media/video/cx18/cx18-mailbox.c
+++ b/drivers/media/video/cx18/cx18-mailbox.c
@@ -716,9 +716,8 @@ static int cx18_set_filter_param(struct cx18_stream *s)
716int cx18_api_func(void *priv, u32 cmd, int in, int out, 716int cx18_api_func(void *priv, u32 cmd, int in, int out,
717 u32 data[CX2341X_MBOX_MAX_DATA]) 717 u32 data[CX2341X_MBOX_MAX_DATA])
718{ 718{
719 struct cx18_api_func_private *api_priv = priv; 719 struct cx18_stream *s = priv;
720 struct cx18 *cx = api_priv->cx; 720 struct cx18 *cx = s->cx;
721 struct cx18_stream *s = api_priv->s;
722 721
723 switch (cmd) { 722 switch (cmd) {
724 case CX2341X_ENC_SET_OUTPUT_PORT: 723 case CX2341X_ENC_SET_OUTPUT_PORT:
diff --git a/drivers/media/video/cx18/cx18-mailbox.h b/drivers/media/video/cx18/cx18-mailbox.h
index 077952fcbcca..05fe6bdbe062 100644
--- a/drivers/media/video/cx18/cx18-mailbox.h
+++ b/drivers/media/video/cx18/cx18-mailbox.h
@@ -81,11 +81,6 @@ struct cx18_mailbox {
81 81
82struct cx18_stream; 82struct cx18_stream;
83 83
84struct cx18_api_func_private {
85 struct cx18 *cx;
86 struct cx18_stream *s;
87};
88
89int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]); 84int cx18_api(struct cx18 *cx, u32 cmd, int args, u32 data[]);
90int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd, 85int cx18_vapi_result(struct cx18 *cx, u32 data[MAX_MB_ARGUMENTS], u32 cmd,
91 int args, ...); 86 int args, ...);
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index 94f5d7967c5c..c6e2ca3b1149 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -207,6 +207,7 @@ static int cx18_prep_dev(struct cx18 *cx, int type)
207 s->video_dev->fops = &cx18_v4l2_enc_fops; 207 s->video_dev->fops = &cx18_v4l2_enc_fops;
208 s->video_dev->release = video_device_release; 208 s->video_dev->release = video_device_release;
209 s->video_dev->tvnorms = V4L2_STD_ALL; 209 s->video_dev->tvnorms = V4L2_STD_ALL;
210 set_bit(V4L2_FL_USE_FH_PRIO, &s->video_dev->flags);
210 cx18_set_funcs(s->video_dev); 211 cx18_set_funcs(s->video_dev);
211 return 0; 212 return 0;
212} 213}
@@ -572,7 +573,7 @@ static void cx18_stream_configure_mdls(struct cx18_stream *s)
572 * Set the MDL size to the exact size needed for one frame. 573 * Set the MDL size to the exact size needed for one frame.
573 * Use enough buffers per MDL to cover the MDL size 574 * Use enough buffers per MDL to cover the MDL size
574 */ 575 */
575 s->mdl_size = 720 * s->cx->params.height * 3 / 2; 576 s->mdl_size = 720 * s->cx->cxhdl.height * 3 / 2;
576 s->bufs_per_mdl = s->mdl_size / s->buf_size; 577 s->bufs_per_mdl = s->mdl_size / s->buf_size;
577 if (s->mdl_size % s->buf_size) 578 if (s->mdl_size % s->buf_size)
578 s->bufs_per_mdl++; 579 s->bufs_per_mdl++;
@@ -607,7 +608,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
607 u32 data[MAX_MB_ARGUMENTS]; 608 u32 data[MAX_MB_ARGUMENTS];
608 struct cx18 *cx = s->cx; 609 struct cx18 *cx = s->cx;
609 int captype = 0; 610 int captype = 0;
610 struct cx18_api_func_private priv;
611 struct cx18_stream *s_idx; 611 struct cx18_stream *s_idx;
612 612
613 if (!cx18_stream_enabled(s)) 613 if (!cx18_stream_enabled(s))
@@ -620,7 +620,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
620 captype = CAPTURE_CHANNEL_TYPE_MPEG; 620 captype = CAPTURE_CHANNEL_TYPE_MPEG;
621 cx->mpg_data_received = cx->vbi_data_inserted = 0; 621 cx->mpg_data_received = cx->vbi_data_inserted = 0;
622 cx->dualwatch_jiffies = jiffies; 622 cx->dualwatch_jiffies = jiffies;
623 cx->dualwatch_stereo_mode = cx->params.audio_properties & 0x300; 623 cx->dualwatch_stereo_mode = v4l2_ctrl_g_ctrl(cx->cxhdl.audio_mode);
624 cx->search_pack_header = 0; 624 cx->search_pack_header = 0;
625 break; 625 break;
626 626
@@ -710,21 +710,21 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
710 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0); 710 s->handle, cx18_stream_enabled(s_idx) ? 7 : 0);
711 711
712 /* Call out to the common CX2341x API setup for user controls */ 712 /* Call out to the common CX2341x API setup for user controls */
713 priv.cx = cx; 713 cx->cxhdl.priv = s;
714 priv.s = s; 714 cx2341x_handler_setup(&cx->cxhdl);
715 cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
716 715
717 /* 716 /*
718 * When starting a capture and we're set for radio, 717 * When starting a capture and we're set for radio,
719 * ensure the video is muted, despite the user control. 718 * ensure the video is muted, despite the user control.
720 */ 719 */
721 if (!cx->params.video_mute && 720 if (!cx->cxhdl.video_mute &&
722 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags)) 721 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
723 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle, 722 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
724 (cx->params.video_mute_yuv << 8) | 1); 723 (v4l2_ctrl_g_ctrl(cx->cxhdl.video_mute_yuv) << 8) | 1);
725 } 724 }
726 725
727 if (atomic_read(&cx->tot_capturing) == 0) { 726 if (atomic_read(&cx->tot_capturing) == 0) {
727 cx2341x_handler_set_busy(&cx->cxhdl, 1);
728 clear_bit(CX18_F_I_EOS, &cx->i_flags); 728 clear_bit(CX18_F_I_EOS, &cx->i_flags);
729 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK); 729 cx18_write_reg(cx, 7, CX18_DSP0_INTERRUPT_MASK);
730 } 730 }
@@ -826,6 +826,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
826 if (atomic_read(&cx->tot_capturing) > 0) 826 if (atomic_read(&cx->tot_capturing) > 0)
827 return 0; 827 return 0;
828 828
829 cx2341x_handler_set_busy(&cx->cxhdl, 0);
829 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK); 830 cx18_write_reg(cx, 5, CX18_DSP0_INTERRUPT_MASK);
830 wake_up(&s->waitq); 831 wake_up(&s->waitq);
831 832
diff --git a/drivers/media/video/cx18/cx23418.h b/drivers/media/video/cx18/cx23418.h
index 7e40035028d2..935f557acbd0 100644
--- a/drivers/media/video/cx18/cx23418.h
+++ b/drivers/media/video/cx18/cx23418.h
@@ -477,7 +477,7 @@
477/* The are no buffers ready. Try again soon! */ 477/* The are no buffers ready. Try again soon! */
478#define CXERR_NODATA_AGAIN 0x00001E 478#define CXERR_NODATA_AGAIN 0x00001E
479 479
480/* The stream is stopping. Function not alllowed now! */ 480/* The stream is stopping. Function not allowed now! */
481#define CXERR_STOPPING_STATUS 0x00001F 481#define CXERR_STOPPING_STATUS 0x00001F
482 482
483/* Trying to access hardware when the power is turned OFF */ 483/* Trying to access hardware when the power is turned OFF */
diff --git a/drivers/media/video/cx231xx/cx231xx-417.c b/drivers/media/video/cx231xx/cx231xx-417.c
index fc9526a5b746..f8f0e59cd583 100644
--- a/drivers/media/video/cx231xx/cx231xx-417.c
+++ b/drivers/media/video/cx231xx/cx231xx-417.c
@@ -942,13 +942,13 @@ static int cx231xx_load_firmware(struct cx231xx *dev)
942 942
943 p_current_fw = vmalloc(1884180 * 4); 943 p_current_fw = vmalloc(1884180 * 4);
944 p_fw = p_current_fw; 944 p_fw = p_current_fw;
945 if (p_current_fw == 0) { 945 if (p_current_fw == NULL) {
946 dprintk(2, "FAIL!!!\n"); 946 dprintk(2, "FAIL!!!\n");
947 return -1; 947 return -1;
948 } 948 }
949 949
950 p_buffer = vmalloc(4096); 950 p_buffer = vmalloc(4096);
951 if (p_buffer == 0) { 951 if (p_buffer == NULL) {
952 dprintk(2, "FAIL!!!\n"); 952 dprintk(2, "FAIL!!!\n");
953 return -1; 953 return -1;
954 } 954 }
diff --git a/drivers/media/video/cx231xx/cx231xx-avcore.c b/drivers/media/video/cx231xx/cx231xx-avcore.c
index c53e97295a0d..62843d39817c 100644
--- a/drivers/media/video/cx231xx/cx231xx-avcore.c
+++ b/drivers/media/video/cx231xx/cx231xx-avcore.c
@@ -759,11 +759,8 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
759 case CX231XX_VMUX_TELEVISION: 759 case CX231XX_VMUX_TELEVISION:
760 case CX231XX_VMUX_CABLE: 760 case CX231XX_VMUX_CABLE:
761 default: 761 default:
762 switch (dev->model) { 762 /* TODO: Test if this is also needed for xc2028/xc3028 */
763 case CX231XX_BOARD_CNXT_CARRAERA: 763 if (dev->board.tuner_type == TUNER_XC5000) {
764 case CX231XX_BOARD_CNXT_RDE_250:
765 case CX231XX_BOARD_CNXT_SHELBY:
766 case CX231XX_BOARD_CNXT_RDU_250:
767 /* Disable the use of DIF */ 764 /* Disable the use of DIF */
768 765
769 status = vid_blk_read_word(dev, AFE_CTRL, &value); 766 status = vid_blk_read_word(dev, AFE_CTRL, &value);
@@ -820,8 +817,7 @@ int cx231xx_set_decoder_video_input(struct cx231xx *dev,
820 MODE_CTRL, FLD_INPUT_MODE, 817 MODE_CTRL, FLD_INPUT_MODE,
821 cx231xx_set_field(FLD_INPUT_MODE, 818 cx231xx_set_field(FLD_INPUT_MODE,
822 INPUT_MODE_CVBS_0)); 819 INPUT_MODE_CVBS_0));
823 break; 820 } else {
824 default:
825 /* Enable the DIF for the tuner */ 821 /* Enable the DIF for the tuner */
826 822
827 /* Reinitialize the DIF */ 823 /* Reinitialize the DIF */
@@ -1275,6 +1271,8 @@ int cx231xx_enable_i2c_port_3(struct cx231xx *dev, bool is_port_3)
1275 int status = 0; 1271 int status = 0;
1276 bool current_is_port_3; 1272 bool current_is_port_3;
1277 1273
1274 if (dev->board.dont_use_port_3)
1275 is_port_3 = false;
1278 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER, 1276 status = cx231xx_read_ctrl_reg(dev, VRT_GET_REGISTER,
1279 PWR_CTL_EN, value, 4); 1277 PWR_CTL_EN, value, 4);
1280 if (status < 0) 1278 if (status < 0)
@@ -2550,7 +2548,7 @@ int cx231xx_initialize_stream_xfer(struct cx231xx *dev, u32 media_type)
2550 case 4: /* ts1 */ 2548 case 4: /* ts1 */
2551 cx231xx_info("%s: set ts1 registers", __func__); 2549 cx231xx_info("%s: set ts1 registers", __func__);
2552 2550
2553 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { 2551 if (dev->board.has_417) {
2554 cx231xx_info(" MPEG\n"); 2552 cx231xx_info(" MPEG\n");
2555 value &= 0xFFFFFFFC; 2553 value &= 0xFFFFFFFC;
2556 value |= 0x3; 2554 value |= 0x3;
diff --git a/drivers/media/video/cx231xx/cx231xx-cards.c b/drivers/media/video/cx231xx/cx231xx-cards.c
index 588f3e8f028b..f49230d170e6 100644
--- a/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -261,6 +261,9 @@ struct cx231xx_board cx231xx_boards[] = {
261 .agc_analog_digital_select_gpio = 0x1c, 261 .agc_analog_digital_select_gpio = 0x1c,
262 .gpio_pin_status_mask = 0x4001000, 262 .gpio_pin_status_mask = 0x4001000,
263 .norm = V4L2_STD_PAL, 263 .norm = V4L2_STD_PAL,
264 .no_alt_vanc = 1,
265 .external_av = 1,
266 .has_417 = 1,
264 267
265 .input = {{ 268 .input = {{
266 .type = CX231XX_VMUX_COMPOSITE1, 269 .type = CX231XX_VMUX_COMPOSITE1,
@@ -357,19 +360,19 @@ struct cx231xx_board cx231xx_boards[] = {
357 .type = CX231XX_VMUX_TELEVISION, 360 .type = CX231XX_VMUX_TELEVISION,
358 .vmux = CX231XX_VIN_3_1, 361 .vmux = CX231XX_VIN_3_1,
359 .amux = CX231XX_AMUX_VIDEO, 362 .amux = CX231XX_AMUX_VIDEO,
360 .gpio = 0, 363 .gpio = NULL,
361 }, { 364 }, {
362 .type = CX231XX_VMUX_COMPOSITE1, 365 .type = CX231XX_VMUX_COMPOSITE1,
363 .vmux = CX231XX_VIN_2_1, 366 .vmux = CX231XX_VIN_2_1,
364 .amux = CX231XX_AMUX_LINE_IN, 367 .amux = CX231XX_AMUX_LINE_IN,
365 .gpio = 0, 368 .gpio = NULL,
366 }, { 369 }, {
367 .type = CX231XX_VMUX_SVIDEO, 370 .type = CX231XX_VMUX_SVIDEO,
368 .vmux = CX231XX_VIN_1_1 | 371 .vmux = CX231XX_VIN_1_1 |
369 (CX231XX_VIN_1_2 << 8) | 372 (CX231XX_VIN_1_2 << 8) |
370 CX25840_SVIDEO_ON, 373 CX25840_SVIDEO_ON,
371 .amux = CX231XX_AMUX_LINE_IN, 374 .amux = CX231XX_AMUX_LINE_IN,
372 .gpio = 0, 375 .gpio = NULL,
373 } }, 376 } },
374 }, 377 },
375 [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = { 378 [CX231XX_BOARD_HAUPPAUGE_USBLIVE2] = {
@@ -382,18 +385,20 @@ struct cx231xx_board cx231xx_boards[] = {
382 .agc_analog_digital_select_gpio = 0x0c, 385 .agc_analog_digital_select_gpio = 0x0c,
383 .gpio_pin_status_mask = 0x4001000, 386 .gpio_pin_status_mask = 0x4001000,
384 .norm = V4L2_STD_NTSC, 387 .norm = V4L2_STD_NTSC,
388 .no_alt_vanc = 1,
389 .external_av = 1,
385 .input = {{ 390 .input = {{
386 .type = CX231XX_VMUX_COMPOSITE1, 391 .type = CX231XX_VMUX_COMPOSITE1,
387 .vmux = CX231XX_VIN_2_1, 392 .vmux = CX231XX_VIN_2_1,
388 .amux = CX231XX_AMUX_LINE_IN, 393 .amux = CX231XX_AMUX_LINE_IN,
389 .gpio = 0, 394 .gpio = NULL,
390 }, { 395 }, {
391 .type = CX231XX_VMUX_SVIDEO, 396 .type = CX231XX_VMUX_SVIDEO,
392 .vmux = CX231XX_VIN_1_1 | 397 .vmux = CX231XX_VIN_1_1 |
393 (CX231XX_VIN_1_2 << 8) | 398 (CX231XX_VIN_1_2 << 8) |
394 CX25840_SVIDEO_ON, 399 CX25840_SVIDEO_ON,
395 .amux = CX231XX_AMUX_LINE_IN, 400 .amux = CX231XX_AMUX_LINE_IN,
396 .gpio = 0, 401 .gpio = NULL,
397 } }, 402 } },
398 }, 403 },
399 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = { 404 [CX231XX_BOARD_PV_PLAYTV_USB_HYBRID] = {
@@ -420,21 +425,50 @@ struct cx231xx_board cx231xx_boards[] = {
420 .type = CX231XX_VMUX_TELEVISION, 425 .type = CX231XX_VMUX_TELEVISION,
421 .vmux = CX231XX_VIN_3_1, 426 .vmux = CX231XX_VIN_3_1,
422 .amux = CX231XX_AMUX_VIDEO, 427 .amux = CX231XX_AMUX_VIDEO,
423 .gpio = 0, 428 .gpio = NULL,
424 }, { 429 }, {
425 .type = CX231XX_VMUX_COMPOSITE1, 430 .type = CX231XX_VMUX_COMPOSITE1,
426 .vmux = CX231XX_VIN_2_1, 431 .vmux = CX231XX_VIN_2_1,
427 .amux = CX231XX_AMUX_LINE_IN, 432 .amux = CX231XX_AMUX_LINE_IN,
428 .gpio = 0, 433 .gpio = NULL,
429 }, { 434 }, {
430 .type = CX231XX_VMUX_SVIDEO, 435 .type = CX231XX_VMUX_SVIDEO,
431 .vmux = CX231XX_VIN_1_1 | 436 .vmux = CX231XX_VIN_1_1 |
432 (CX231XX_VIN_1_2 << 8) | 437 (CX231XX_VIN_1_2 << 8) |
433 CX25840_SVIDEO_ON, 438 CX25840_SVIDEO_ON,
434 .amux = CX231XX_AMUX_LINE_IN, 439 .amux = CX231XX_AMUX_LINE_IN,
435 .gpio = 0, 440 .gpio = NULL,
436 } }, 441 } },
437 }, 442 },
443 [CX231XX_BOARD_PV_XCAPTURE_USB] = {
444 .name = "Pixelview Xcapture USB",
445 .tuner_type = TUNER_ABSENT,
446 .decoder = CX231XX_AVDECODER,
447 .output_mode = OUT_MODE_VIP11,
448 .demod_xfer_mode = 0,
449 .ctl_pin_status_mask = 0xFFFFFFC4,
450 .agc_analog_digital_select_gpio = 0x0c,
451 .gpio_pin_status_mask = 0x4001000,
452 .norm = V4L2_STD_NTSC,
453 .no_alt_vanc = 1,
454 .external_av = 1,
455 .dont_use_port_3 = 1,
456
457 .input = {{
458 .type = CX231XX_VMUX_COMPOSITE1,
459 .vmux = CX231XX_VIN_2_1,
460 .amux = CX231XX_AMUX_LINE_IN,
461 .gpio = NULL,
462 }, {
463 .type = CX231XX_VMUX_SVIDEO,
464 .vmux = CX231XX_VIN_1_1 |
465 (CX231XX_VIN_1_2 << 8) |
466 CX25840_SVIDEO_ON,
467 .amux = CX231XX_AMUX_LINE_IN,
468 .gpio = NULL,
469 }
470 },
471 },
438}; 472};
439const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards); 473const unsigned int cx231xx_bcount = ARRAY_SIZE(cx231xx_boards);
440 474
@@ -464,6 +498,8 @@ struct usb_device_id cx231xx_id_table[] = {
464 .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2}, 498 .driver_info = CX231XX_BOARD_HAUPPAUGE_USBLIVE2},
465 {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001), 499 {USB_DEVICE_VER(USB_VID_PIXELVIEW, USB_PID_PIXELVIEW_SBTVD, 0x4000, 0x4001),
466 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID}, 500 .driver_info = CX231XX_BOARD_PV_PLAYTV_USB_HYBRID},
501 {USB_DEVICE(USB_VID_PIXELVIEW, 0x5014),
502 .driver_info = CX231XX_BOARD_PV_XCAPTURE_USB},
467 {}, 503 {},
468}; 504};
469 505
@@ -772,7 +808,7 @@ static int cx231xx_init_dev(struct cx231xx **devhandle, struct usb_device *udev,
772 /* Reset other chips required if they are tied up with GPIO pins */ 808 /* Reset other chips required if they are tied up with GPIO pins */
773 cx231xx_add_into_devlist(dev); 809 cx231xx_add_into_devlist(dev);
774 810
775 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) { 811 if (dev->board.has_417) {
776 printk(KERN_INFO "attach 417 %d\n", dev->model); 812 printk(KERN_INFO "attach 417 %d\n", dev->model);
777 if (cx231xx_417_register(dev) < 0) { 813 if (cx231xx_417_register(dev) < 0) {
778 printk(KERN_ERR 814 printk(KERN_ERR
@@ -844,110 +880,110 @@ static int cx231xx_usb_probe(struct usb_interface *interface,
844 udev = usb_get_dev(interface_to_usbdev(interface)); 880 udev = usb_get_dev(interface_to_usbdev(interface));
845 ifnum = interface->altsetting[0].desc.bInterfaceNumber; 881 ifnum = interface->altsetting[0].desc.bInterfaceNumber;
846 882
847 if (ifnum == 1) { 883 /*
848 /* 884 * Interface number 0 - IR interface (handled by mceusb driver)
849 * Interface number 0 - IR interface 885 * Interface number 1 - AV interface (handled by this driver)
850 */ 886 */
851 /* Check to see next free device and mark as used */ 887 if (ifnum != 1)
852 nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS); 888 return -ENODEV;
853 cx231xx_devused |= 1 << nr;
854
855 if (nr >= CX231XX_MAXBOARDS) {
856 cx231xx_err(DRIVER_NAME
857 ": Supports only %i cx231xx boards.\n", CX231XX_MAXBOARDS);
858 cx231xx_devused &= ~(1 << nr);
859 return -ENOMEM;
860 }
861
862 /* allocate memory for our device state and initialize it */
863 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
864 if (dev == NULL) {
865 cx231xx_err(DRIVER_NAME ": out of memory!\n");
866 cx231xx_devused &= ~(1 << nr);
867 return -ENOMEM;
868 }
869
870 snprintf(dev->name, 29, "cx231xx #%d", nr);
871 dev->devno = nr;
872 dev->model = id->driver_info;
873 dev->video_mode.alt = -1;
874 dev->interface_count++;
875
876 /* reset gpio dir and value */
877 dev->gpio_dir = 0;
878 dev->gpio_val = 0;
879 dev->xc_fw_load_done = 0;
880 dev->has_alsa_audio = 1;
881 dev->power_mode = -1;
882 atomic_set(&dev->devlist_count, 0);
883
884 /* 0 - vbi ; 1 -sliced cc mode */
885 dev->vbi_or_sliced_cc_mode = 0;
886
887 /* get maximum no.of IAD interfaces */
888 assoc_desc = udev->actconfig->intf_assoc[0];
889 dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
890
891 /* init CIR module TBD */
892 889
893 /* store the current interface */ 890 /* Check to see next free device and mark as used */
894 lif = interface; 891 nr = find_first_zero_bit(&cx231xx_devused, CX231XX_MAXBOARDS);
892 cx231xx_devused |= 1 << nr;
895 893
896 /*mode_tv: digital=1 or analog=0*/ 894 if (nr >= CX231XX_MAXBOARDS) {
897 dev->mode_tv = 0; 895 cx231xx_err(DRIVER_NAME
896 ": Supports only %i cx231xx boards.\n", CX231XX_MAXBOARDS);
897 cx231xx_devused &= ~(1 << nr);
898 return -ENOMEM;
899 }
898 900
899 dev->USE_ISO = transfer_mode; 901 /* allocate memory for our device state and initialize it */
902 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
903 if (dev == NULL) {
904 cx231xx_err(DRIVER_NAME ": out of memory!\n");
905 cx231xx_devused &= ~(1 << nr);
906 return -ENOMEM;
907 }
900 908
901 switch (udev->speed) { 909 snprintf(dev->name, 29, "cx231xx #%d", nr);
902 case USB_SPEED_LOW: 910 dev->devno = nr;
903 speed = "1.5"; 911 dev->model = id->driver_info;
904 break; 912 dev->video_mode.alt = -1;
905 case USB_SPEED_UNKNOWN: 913
906 case USB_SPEED_FULL: 914 dev->interface_count++;
907 speed = "12"; 915 /* reset gpio dir and value */
908 break; 916 dev->gpio_dir = 0;
909 case USB_SPEED_HIGH: 917 dev->gpio_val = 0;
910 speed = "480"; 918 dev->xc_fw_load_done = 0;
911 break; 919 dev->has_alsa_audio = 1;
912 default: 920 dev->power_mode = -1;
913 speed = "unknown"; 921 atomic_set(&dev->devlist_count, 0);
914 } 922
923 /* 0 - vbi ; 1 -sliced cc mode */
924 dev->vbi_or_sliced_cc_mode = 0;
925
926 /* get maximum no.of IAD interfaces */
927 assoc_desc = udev->actconfig->intf_assoc[0];
928 dev->max_iad_interface_count = assoc_desc->bInterfaceCount;
929
930 /* init CIR module TBD */
931
932 /* store the current interface */
933 lif = interface;
934
935 /*mode_tv: digital=1 or analog=0*/
936 dev->mode_tv = 0;
937
938 dev->USE_ISO = transfer_mode;
939
940 switch (udev->speed) {
941 case USB_SPEED_LOW:
942 speed = "1.5";
943 break;
944 case USB_SPEED_UNKNOWN:
945 case USB_SPEED_FULL:
946 speed = "12";
947 break;
948 case USB_SPEED_HIGH:
949 speed = "480";
950 break;
951 default:
952 speed = "unknown";
953 }
915 954
916 if (udev->manufacturer) 955 if (udev->manufacturer)
917 strlcpy(descr, udev->manufacturer, sizeof(descr)); 956 strlcpy(descr, udev->manufacturer, sizeof(descr));
918 957
919 if (udev->product) { 958 if (udev->product) {
920 if (*descr)
921 strlcat(descr, " ", sizeof(descr));
922 strlcat(descr, udev->product, sizeof(descr));
923 }
924 if (*descr) 959 if (*descr)
925 strlcat(descr, " ", sizeof(descr)); 960 strlcat(descr, " ", sizeof(descr));
926 961 strlcat(descr, udev->product, sizeof(descr));
927 cx231xx_info("New device %s@ %s Mbps " 962 }
928 "(%04x:%04x) with %d interfaces\n", 963 if (*descr)
929 descr, 964 strlcat(descr, " ", sizeof(descr));
930 speed, 965
931 le16_to_cpu(udev->descriptor.idVendor), 966 cx231xx_info("New device %s@ %s Mbps "
932 le16_to_cpu(udev->descriptor.idProduct), 967 "(%04x:%04x) with %d interfaces\n",
933 dev->max_iad_interface_count); 968 descr,
934 969 speed,
935 /* store the interface 0 back */ 970 le16_to_cpu(udev->descriptor.idVendor),
936 lif = udev->actconfig->interface[0]; 971 le16_to_cpu(udev->descriptor.idProduct),
937 972 dev->max_iad_interface_count);
938 /* increment interface count */ 973
939 dev->interface_count++; 974 /* store the interface 0 back */
940 975 lif = udev->actconfig->interface[0];
941 /* get device number */ 976
942 nr = dev->devno; 977 /* increment interface count */
943 978 dev->interface_count++;
944 assoc_desc = udev->actconfig->intf_assoc[0]; 979
945 if (assoc_desc->bFirstInterface != ifnum) { 980 /* get device number */
946 cx231xx_err(DRIVER_NAME ": Not found " 981 nr = dev->devno;
947 "matching IAD interface\n"); 982
948 return -ENODEV; 983 assoc_desc = udev->actconfig->intf_assoc[0];
949 } 984 if (assoc_desc->bFirstInterface != ifnum) {
950 } else { 985 cx231xx_err(DRIVER_NAME ": Not found "
986 "matching IAD interface\n");
951 return -ENODEV; 987 return -ENODEV;
952 } 988 }
953 989
diff --git a/drivers/media/video/cx231xx/cx231xx-core.c b/drivers/media/video/cx231xx/cx231xx-core.c
index 7d62d58617f5..abe500feb7dd 100644
--- a/drivers/media/video/cx231xx/cx231xx-core.c
+++ b/drivers/media/video/cx231xx/cx231xx-core.c
@@ -571,6 +571,8 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
571 alt]; 571 alt];
572 break; 572 break;
573 case INDEX_VANC: 573 case INDEX_VANC:
574 if (dev->board.no_alt_vanc)
575 return 0;
574 usb_interface_index = 576 usb_interface_index =
575 dev->current_pcb_config.hs_config_info[0].interface_info. 577 dev->current_pcb_config.hs_config_info[0].interface_info.
576 vanc_index + 1; 578 vanc_index + 1;
@@ -600,8 +602,7 @@ int cx231xx_set_alt_setting(struct cx231xx *dev, u8 index, u8 alt)
600 usb_interface_index, alt); 602 usb_interface_index, alt);
601 /*To workaround error number=-71 on EP0 for videograbber, 603 /*To workaround error number=-71 on EP0 for videograbber,
602 need add following codes.*/ 604 need add following codes.*/
603 if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && 605 if (dev->board.no_alt_vanc)
604 dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
605 return -1; 606 return -1;
606 } 607 }
607 608
@@ -1301,8 +1302,7 @@ int cx231xx_dev_init(struct cx231xx *dev)
1301 /* init hardware */ 1302 /* init hardware */
1302 /* Note : with out calling set power mode function, 1303 /* Note : with out calling set power mode function,
1303 afe can not be set up correctly */ 1304 afe can not be set up correctly */
1304 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || 1305 if (dev->board.external_av) {
1305 dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2) {
1306 errCode = cx231xx_set_power_mode(dev, 1306 errCode = cx231xx_set_power_mode(dev,
1307 POLARIS_AVMODE_ENXTERNAL_AV); 1307 POLARIS_AVMODE_ENXTERNAL_AV);
1308 if (errCode < 0) { 1308 if (errCode < 0) {
@@ -1322,11 +1322,9 @@ int cx231xx_dev_init(struct cx231xx *dev)
1322 } 1322 }
1323 } 1323 }
1324 1324
1325 /* reset the Tuner */ 1325 /* reset the Tuner, if it is a Xceive tuner */
1326 if ((dev->model == CX231XX_BOARD_CNXT_CARRAERA) || 1326 if ((dev->board.tuner_type == TUNER_XC5000) ||
1327 (dev->model == CX231XX_BOARD_CNXT_RDE_250) || 1327 (dev->board.tuner_type == TUNER_XC2028))
1328 (dev->model == CX231XX_BOARD_CNXT_SHELBY) ||
1329 (dev->model == CX231XX_BOARD_CNXT_RDU_250))
1330 cx231xx_gpio_set(dev, dev->board.tuner_gpio); 1328 cx231xx_gpio_set(dev, dev->board.tuner_gpio);
1331 1329
1332 /* initialize Colibri block */ 1330 /* initialize Colibri block */
diff --git a/drivers/media/video/cx231xx/cx231xx-i2c.c b/drivers/media/video/cx231xx/cx231xx-i2c.c
index 835670623dfb..925f3a04e53c 100644
--- a/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -54,6 +54,21 @@ do { \
54 } \ 54 } \
55} while (0) 55} while (0)
56 56
57static inline bool is_tuner(struct cx231xx *dev, struct cx231xx_i2c *bus,
58 const struct i2c_msg *msg, int tuner_type)
59{
60 if (bus->nr != dev->board.tuner_i2c_master)
61 return false;
62
63 if (msg->addr != dev->board.tuner_addr)
64 return false;
65
66 if (dev->tuner_type != tuner_type)
67 return false;
68
69 return true;
70}
71
57/* 72/*
58 * cx231xx_i2c_send_bytes() 73 * cx231xx_i2c_send_bytes()
59 */ 74 */
@@ -71,9 +86,7 @@ int cx231xx_i2c_send_bytes(struct i2c_adapter *i2c_adap,
71 u16 saddr = 0; 86 u16 saddr = 0;
72 u8 need_gpio = 0; 87 u8 need_gpio = 0;
73 88
74 if ((bus->nr == 1) && (msg->addr == 0x61) 89 if (is_tuner(dev, bus, msg, TUNER_XC5000)) {
75 && (dev->tuner_type == TUNER_XC5000)) {
76
77 size = msg->len; 90 size = msg->len;
78 91
79 if (size == 2) { /* register write sub addr */ 92 if (size == 2) { /* register write sub addr */
@@ -180,9 +193,7 @@ static int cx231xx_i2c_recv_bytes(struct i2c_adapter *i2c_adap,
180 u16 saddr = 0; 193 u16 saddr = 0;
181 u8 need_gpio = 0; 194 u8 need_gpio = 0;
182 195
183 if ((bus->nr == 1) && (msg->addr == 0x61) 196 if (is_tuner(dev, bus, msg, TUNER_XC5000)) {
184 && dev->tuner_type == TUNER_XC5000) {
185
186 if (msg->len == 2) 197 if (msg->len == 2)
187 saddr = msg->buf[0] << 8 | msg->buf[1]; 198 saddr = msg->buf[0] << 8 | msg->buf[1];
188 else if (msg->len == 1) 199 else if (msg->len == 1)
@@ -274,9 +285,7 @@ static int cx231xx_i2c_recv_bytes_with_saddr(struct i2c_adapter *i2c_adap,
274 else if (msg1->len == 1) 285 else if (msg1->len == 1)
275 saddr = msg1->buf[0]; 286 saddr = msg1->buf[0];
276 287
277 if ((bus->nr == 1) && (msg2->addr == 0x61) 288 if (is_tuner(dev, bus, msg2, TUNER_XC5000)) {
278 && dev->tuner_type == TUNER_XC5000) {
279
280 if ((msg2->len < 16)) { 289 if ((msg2->len < 16)) {
281 290
282 dprintk1(1, 291 dprintk1(1,
@@ -454,8 +463,8 @@ static char *i2c_devs[128] = {
454 [0x32 >> 1] = "GeminiIII", 463 [0x32 >> 1] = "GeminiIII",
455 [0x02 >> 1] = "Aquarius", 464 [0x02 >> 1] = "Aquarius",
456 [0xa0 >> 1] = "eeprom", 465 [0xa0 >> 1] = "eeprom",
457 [0xc0 >> 1] = "tuner/XC3028", 466 [0xc0 >> 1] = "tuner",
458 [0xc2 >> 1] = "tuner/XC5000", 467 [0xc2 >> 1] = "tuner",
459}; 468};
460 469
461/* 470/*
diff --git a/drivers/media/video/cx231xx/cx231xx-video.c b/drivers/media/video/cx231xx/cx231xx-video.c
index 7e3e8c4f19b7..ffd5af914c44 100644
--- a/drivers/media/video/cx231xx/cx231xx-video.c
+++ b/drivers/media/video/cx231xx/cx231xx-video.c
@@ -2190,8 +2190,7 @@ static int cx231xx_v4l2_open(struct file *filp)
2190 dev->height = norm_maxh(dev); 2190 dev->height = norm_maxh(dev);
2191 2191
2192 /* Power up in Analog TV mode */ 2192 /* Power up in Analog TV mode */
2193 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER || 2193 if (dev->board.external_av)
2194 dev->model == CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
2195 cx231xx_set_power_mode(dev, 2194 cx231xx_set_power_mode(dev,
2196 POLARIS_AVMODE_ENXTERNAL_AV); 2195 POLARIS_AVMODE_ENXTERNAL_AV);
2197 else 2196 else
@@ -2231,9 +2230,7 @@ static int cx231xx_v4l2_open(struct file *filp)
2231 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 2230 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
2232 /* Set the required alternate setting VBI interface works in 2231 /* Set the required alternate setting VBI interface works in
2233 Bulk mode only */ 2232 Bulk mode only */
2234 if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && 2233 cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
2235 dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2)
2236 cx231xx_set_alt_setting(dev, INDEX_VANC, 0);
2237 2234
2238 videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops, 2235 videobuf_queue_vmalloc_init(&fh->vb_vidq, &cx231xx_vbi_qops,
2239 NULL, &dev->vbi_mode.slock, 2236 NULL, &dev->vbi_mode.slock,
@@ -2275,7 +2272,7 @@ void cx231xx_release_analog_resources(struct cx231xx *dev)
2275 cx231xx_info("V4L2 device %s deregistered\n", 2272 cx231xx_info("V4L2 device %s deregistered\n",
2276 video_device_node_name(dev->vdev)); 2273 video_device_node_name(dev->vdev));
2277 2274
2278 if (dev->model == CX231XX_BOARD_CNXT_VIDEO_GRABBER) 2275 if (dev->board.has_417)
2279 cx231xx_417_unregister(dev); 2276 cx231xx_417_unregister(dev);
2280 2277
2281 if (video_is_registered(dev->vdev)) 2278 if (video_is_registered(dev->vdev))
@@ -2302,10 +2299,13 @@ static int cx231xx_v4l2_close(struct file *filp)
2302 if (res_check(fh)) 2299 if (res_check(fh))
2303 res_free(fh); 2300 res_free(fh);
2304 2301
2305 /*To workaround error number=-71 on EP0 for VideoGrabber, 2302 /*
2306 need exclude following.*/ 2303 * To workaround error number=-71 on EP0 for VideoGrabber,
2307 if (dev->model != CX231XX_BOARD_CNXT_VIDEO_GRABBER && 2304 * need exclude following.
2308 dev->model != CX231XX_BOARD_HAUPPAUGE_USBLIVE2) 2305 * FIXME: It is probably safe to remove most of these, as we're
2306 * now avoiding the alternate setting for INDEX_VANC
2307 */
2308 if (!dev->board.no_alt_vanc)
2309 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 2309 if (fh->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
2310 videobuf_stop(&fh->vb_vidq); 2310 videobuf_stop(&fh->vb_vidq);
2311 videobuf_mmap_free(&fh->vb_vidq); 2311 videobuf_mmap_free(&fh->vb_vidq);
diff --git a/drivers/media/video/cx231xx/cx231xx.h b/drivers/media/video/cx231xx/cx231xx.h
index 72bbea2bcd56..bd4a9cf29577 100644
--- a/drivers/media/video/cx231xx/cx231xx.h
+++ b/drivers/media/video/cx231xx/cx231xx.h
@@ -64,6 +64,7 @@
64#define CX231XX_BOARD_HAUPPAUGE_EXETER 8 64#define CX231XX_BOARD_HAUPPAUGE_EXETER 8
65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9 65#define CX231XX_BOARD_HAUPPAUGE_USBLIVE2 9
66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10 66#define CX231XX_BOARD_PV_PLAYTV_USB_HYBRID 10
67#define CX231XX_BOARD_PV_XCAPTURE_USB 11
67 68
68/* Limits minimum and default number of buffers */ 69/* Limits minimum and default number of buffers */
69#define CX231XX_MIN_BUF 4 70#define CX231XX_MIN_BUF 4
@@ -353,7 +354,11 @@ struct cx231xx_board {
353 354
354 unsigned int max_range_640_480:1; 355 unsigned int max_range_640_480:1;
355 unsigned int has_dvb:1; 356 unsigned int has_dvb:1;
357 unsigned int has_417:1;
356 unsigned int valid:1; 358 unsigned int valid:1;
359 unsigned int no_alt_vanc:1;
360 unsigned int external_av:1;
361 unsigned int dont_use_port_3:1;
357 362
358 unsigned char xclk, i2c_speed; 363 unsigned char xclk, i2c_speed;
359 364
@@ -464,7 +469,7 @@ struct cx231xx_fh {
464#define I2C_STOP 0x0 469#define I2C_STOP 0x0
465/* 1-- do not transmit STOP at end of transaction */ 470/* 1-- do not transmit STOP at end of transaction */
466#define I2C_NOSTOP 0x1 471#define I2C_NOSTOP 0x1
467/* 1--alllow slave to insert clock wait states */ 472/* 1--allow slave to insert clock wait states */
468#define I2C_SYNC 0x1 473#define I2C_SYNC 0x1
469 474
470struct cx231xx_i2c { 475struct cx231xx_i2c {
diff --git a/drivers/media/video/cx23885/Kconfig b/drivers/media/video/cx23885/Kconfig
index 6b4a516addfe..3b6e7f28568e 100644
--- a/drivers/media/video/cx23885/Kconfig
+++ b/drivers/media/video/cx23885/Kconfig
@@ -1,6 +1,7 @@
1config VIDEO_CX23885 1config VIDEO_CX23885
2 tristate "Conexant cx23885 (2388x successor) support" 2 tristate "Conexant cx23885 (2388x successor) support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT 3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C && INPUT && SND
4 select SND_PCM
4 select I2C_ALGOBIT 5 select I2C_ALGOBIT
5 select VIDEO_BTCX 6 select VIDEO_BTCX
6 select VIDEO_TUNER 7 select VIDEO_TUNER
@@ -33,3 +34,12 @@ config VIDEO_CX23885
33 To compile this driver as a module, choose M here: the 34 To compile this driver as a module, choose M here: the
34 module will be called cx23885 35 module will be called cx23885
35 36
37config MEDIA_ALTERA_CI
38 tristate "Altera FPGA based CI module"
39 depends on VIDEO_CX23885 && DVB_CORE
40 select STAPL_ALTERA
41 ---help---
42 An Altera FPGA CI module for NetUP Dual DVB-T/C RF CI card.
43
44 To compile this driver as a module, choose M here: the
45 module will be called altera-ci
diff --git a/drivers/media/video/cx23885/Makefile b/drivers/media/video/cx23885/Makefile
index e2ee95f660d8..23293c7b6ac7 100644
--- a/drivers/media/video/cx23885/Makefile
+++ b/drivers/media/video/cx23885/Makefile
@@ -5,6 +5,7 @@ cx23885-objs := cx23885-cards.o cx23885-video.o cx23885-vbi.o \
5 cx23885-f300.o 5 cx23885-f300.o
6 6
7obj-$(CONFIG_VIDEO_CX23885) += cx23885.o 7obj-$(CONFIG_VIDEO_CX23885) += cx23885.o
8obj-$(CONFIG_MEDIA_ALTERA_CI) += altera-ci.o
8 9
9EXTRA_CFLAGS += -Idrivers/media/video 10EXTRA_CFLAGS += -Idrivers/media/video
10EXTRA_CFLAGS += -Idrivers/media/common/tuners 11EXTRA_CFLAGS += -Idrivers/media/common/tuners
diff --git a/drivers/media/video/cx23885/altera-ci.c b/drivers/media/video/cx23885/altera-ci.c
new file mode 100644
index 000000000000..678539b2acfa
--- /dev/null
+++ b/drivers/media/video/cx23885/altera-ci.c
@@ -0,0 +1,838 @@
1/*
2 * altera-ci.c
3 *
4 * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
5 *
6 * Copyright (C) 2010,2011 NetUP Inc.
7 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 *
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, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25/*
26 * currently cx23885 GPIO's used.
27 * GPIO-0 ~INT in
28 * GPIO-1 TMS out
29 * GPIO-2 ~reset chips out
30 * GPIO-3 to GPIO-10 data/addr for CA in/out
31 * GPIO-11 ~CS out
32 * GPIO-12 AD_RG out
33 * GPIO-13 ~WR out
34 * GPIO-14 ~RD out
35 * GPIO-15 ~RDY in
36 * GPIO-16 TCK out
37 * GPIO-17 TDO in
38 * GPIO-18 TDI out
39 */
40/*
41 * Bit definitions for MC417_RWD and MC417_OEN registers
42 * bits 31-16
43 * +-----------+
44 * | Reserved |
45 * +-----------+
46 * bit 15 bit 14 bit 13 bit 12 bit 11 bit 10 bit 9 bit 8
47 * +-------+-------+-------+-------+-------+-------+-------+-------+
48 * | TDI | TDO | TCK | RDY# | #RD | #WR | AD_RG | #CS |
49 * +-------+-------+-------+-------+-------+-------+-------+-------+
50 * bit 7 bit 6 bit 5 bit 4 bit 3 bit 2 bit 1 bit 0
51 * +-------+-------+-------+-------+-------+-------+-------+-------+
52 * | DATA7| DATA6| DATA5| DATA4| DATA3| DATA2| DATA1| DATA0|
53 * +-------+-------+-------+-------+-------+-------+-------+-------+
54 */
55#include <linux/version.h>
56#include <media/videobuf-dma-sg.h>
57#include <media/videobuf-dvb.h>
58#include "altera-ci.h"
59#include "dvb_ca_en50221.h"
60
61/* FPGA regs */
62#define NETUP_CI_INT_CTRL 0x00
63#define NETUP_CI_BUSCTRL2 0x01
64#define NETUP_CI_ADDR0 0x04
65#define NETUP_CI_ADDR1 0x05
66#define NETUP_CI_DATA 0x06
67#define NETUP_CI_BUSCTRL 0x07
68#define NETUP_CI_PID_ADDR0 0x08
69#define NETUP_CI_PID_ADDR1 0x09
70#define NETUP_CI_PID_DATA 0x0a
71#define NETUP_CI_TSA_DIV 0x0c
72#define NETUP_CI_TSB_DIV 0x0d
73#define NETUP_CI_REVISION 0x0f
74
75/* const for ci op */
76#define NETUP_CI_FLG_CTL 1
77#define NETUP_CI_FLG_RD 1
78#define NETUP_CI_FLG_AD 1
79
80static unsigned int ci_dbg;
81module_param(ci_dbg, int, 0644);
82MODULE_PARM_DESC(ci_dbg, "Enable CI debugging");
83
84static unsigned int pid_dbg;
85module_param(pid_dbg, int, 0644);
86MODULE_PARM_DESC(pid_dbg, "Enable PID filtering debugging");
87
88MODULE_DESCRIPTION("altera FPGA CI module");
89MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
90MODULE_LICENSE("GPL");
91
92#define ci_dbg_print(args...) \
93 do { \
94 if (ci_dbg) \
95 printk(KERN_DEBUG args); \
96 } while (0)
97
98#define pid_dbg_print(args...) \
99 do { \
100 if (pid_dbg) \
101 printk(KERN_DEBUG args); \
102 } while (0)
103
104struct altera_ci_state;
105struct netup_hw_pid_filter;
106
107struct fpga_internal {
108 void *dev;
109 struct mutex fpga_mutex;/* two CI's on the same fpga */
110 struct netup_hw_pid_filter *pid_filt[2];
111 struct altera_ci_state *state[2];
112 struct work_struct work;
113 int (*fpga_rw) (void *dev, int flag, int data, int rw);
114 int cis_used;
115 int filts_used;
116 int strt_wrk;
117};
118
119/* stores all private variables for communication with CI */
120struct altera_ci_state {
121 struct fpga_internal *internal;
122 struct dvb_ca_en50221 ca;
123 int status;
124 int nr;
125};
126
127/* stores all private variables for hardware pid filtering */
128struct netup_hw_pid_filter {
129 struct fpga_internal *internal;
130 struct dvb_demux *demux;
131 /* save old functions */
132 int (*start_feed)(struct dvb_demux_feed *feed);
133 int (*stop_feed)(struct dvb_demux_feed *feed);
134
135 int status;
136 int nr;
137};
138
139/* internal params node */
140struct fpga_inode {
141 /* pointer for internal params, one for each pair of CI's */
142 struct fpga_internal *internal;
143 struct fpga_inode *next_inode;
144};
145
146/* first internal params */
147static struct fpga_inode *fpga_first_inode;
148
149/* find chip by dev */
150static struct fpga_inode *find_inode(void *dev)
151{
152 struct fpga_inode *temp_chip = fpga_first_inode;
153
154 if (temp_chip == NULL)
155 return temp_chip;
156
157 /*
158 Search for the last fpga CI chip or
159 find it by dev */
160 while ((temp_chip != NULL) &&
161 (temp_chip->internal->dev != dev))
162 temp_chip = temp_chip->next_inode;
163
164 return temp_chip;
165}
166/* check demux */
167static struct fpga_internal *check_filter(struct fpga_internal *temp_int,
168 void *demux_dev, int filt_nr)
169{
170 if (temp_int == NULL)
171 return NULL;
172
173 if ((temp_int->pid_filt[filt_nr]) == NULL)
174 return NULL;
175
176 if (temp_int->pid_filt[filt_nr]->demux == demux_dev)
177 return temp_int;
178
179 return NULL;
180}
181
182/* find chip by demux */
183static struct fpga_inode *find_dinode(void *demux_dev)
184{
185 struct fpga_inode *temp_chip = fpga_first_inode;
186 struct fpga_internal *temp_int;
187
188 /*
189 * Search of the last fpga CI chip or
190 * find it by demux
191 */
192 while (temp_chip != NULL) {
193 if (temp_chip->internal != NULL) {
194 temp_int = temp_chip->internal;
195 if (check_filter(temp_int, demux_dev, 0))
196 break;
197 if (check_filter(temp_int, demux_dev, 1))
198 break;
199 }
200
201 temp_chip = temp_chip->next_inode;
202 }
203
204 return temp_chip;
205}
206
207/* deallocating chip */
208static void remove_inode(struct fpga_internal *internal)
209{
210 struct fpga_inode *prev_node = fpga_first_inode;
211 struct fpga_inode *del_node = find_inode(internal->dev);
212
213 if (del_node != NULL) {
214 if (del_node == fpga_first_inode) {
215 fpga_first_inode = del_node->next_inode;
216 } else {
217 while (prev_node->next_inode != del_node)
218 prev_node = prev_node->next_inode;
219
220 if (del_node->next_inode == NULL)
221 prev_node->next_inode = NULL;
222 else
223 prev_node->next_inode =
224 prev_node->next_inode->next_inode;
225 }
226
227 kfree(del_node);
228 }
229}
230
231/* allocating new chip */
232static struct fpga_inode *append_internal(struct fpga_internal *internal)
233{
234 struct fpga_inode *new_node = fpga_first_inode;
235
236 if (new_node == NULL) {
237 new_node = kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
238 fpga_first_inode = new_node;
239 } else {
240 while (new_node->next_inode != NULL)
241 new_node = new_node->next_inode;
242
243 new_node->next_inode =
244 kmalloc(sizeof(struct fpga_inode), GFP_KERNEL);
245 if (new_node->next_inode != NULL)
246 new_node = new_node->next_inode;
247 else
248 new_node = NULL;
249 }
250
251 if (new_node != NULL) {
252 new_node->internal = internal;
253 new_node->next_inode = NULL;
254 }
255
256 return new_node;
257}
258
259static int netup_fpga_op_rw(struct fpga_internal *inter, int addr,
260 u8 val, u8 read)
261{
262 inter->fpga_rw(inter->dev, NETUP_CI_FLG_AD, addr, 0);
263 return inter->fpga_rw(inter->dev, 0, val, read);
264}
265
266/* flag - mem/io, read - read/write */
267int altera_ci_op_cam(struct dvb_ca_en50221 *en50221, int slot,
268 u8 flag, u8 read, int addr, u8 val)
269{
270
271 struct altera_ci_state *state = en50221->data;
272 struct fpga_internal *inter = state->internal;
273
274 u8 store;
275 int mem = 0;
276
277 if (0 != slot)
278 return -EINVAL;
279
280 mutex_lock(&inter->fpga_mutex);
281
282 netup_fpga_op_rw(inter, NETUP_CI_ADDR0, ((addr << 1) & 0xfe), 0);
283 netup_fpga_op_rw(inter, NETUP_CI_ADDR1, ((addr >> 7) & 0x7f), 0);
284 store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
285
286 store &= 0x0f;
287 store |= ((state->nr << 7) | (flag << 6));
288
289 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, store, 0);
290 mem = netup_fpga_op_rw(inter, NETUP_CI_DATA, val, read);
291
292 mutex_unlock(&inter->fpga_mutex);
293
294 ci_dbg_print("%s: %s: addr=[0x%02x], %s=%x\n", __func__,
295 (read) ? "read" : "write", addr,
296 (flag == NETUP_CI_FLG_CTL) ? "ctl" : "mem",
297 (read) ? mem : val);
298
299 return mem;
300}
301
302int altera_ci_read_attribute_mem(struct dvb_ca_en50221 *en50221,
303 int slot, int addr)
304{
305 return altera_ci_op_cam(en50221, slot, 0, NETUP_CI_FLG_RD, addr, 0);
306}
307
308int altera_ci_write_attribute_mem(struct dvb_ca_en50221 *en50221,
309 int slot, int addr, u8 data)
310{
311 return altera_ci_op_cam(en50221, slot, 0, 0, addr, data);
312}
313
314int altera_ci_read_cam_ctl(struct dvb_ca_en50221 *en50221, int slot, u8 addr)
315{
316 return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL,
317 NETUP_CI_FLG_RD, addr, 0);
318}
319
320int altera_ci_write_cam_ctl(struct dvb_ca_en50221 *en50221, int slot,
321 u8 addr, u8 data)
322{
323 return altera_ci_op_cam(en50221, slot, NETUP_CI_FLG_CTL, 0, addr, data);
324}
325
326int altera_ci_slot_reset(struct dvb_ca_en50221 *en50221, int slot)
327{
328 struct altera_ci_state *state = en50221->data;
329 struct fpga_internal *inter = state->internal;
330 /* reasonable timeout for CI reset is 10 seconds */
331 unsigned long t_out = jiffies + msecs_to_jiffies(9999);
332 int ret;
333
334 ci_dbg_print("%s\n", __func__);
335
336 if (0 != slot)
337 return -EINVAL;
338
339 mutex_lock(&inter->fpga_mutex);
340
341 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
342 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
343 (ret & 0xcf) | (1 << (5 - state->nr)), 0);
344
345 mutex_unlock(&inter->fpga_mutex);
346
347 for (;;) {
348 mdelay(50);
349
350 mutex_lock(&inter->fpga_mutex);
351
352 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
353 0, NETUP_CI_FLG_RD);
354 mutex_unlock(&inter->fpga_mutex);
355
356 if ((ret & (1 << (5 - state->nr))) == 0)
357 break;
358 if (time_after(jiffies, t_out))
359 break;
360 }
361
362
363 ci_dbg_print("%s: %d msecs\n", __func__,
364 jiffies_to_msecs(jiffies + msecs_to_jiffies(9999) - t_out));
365
366 return 0;
367}
368
369int altera_ci_slot_shutdown(struct dvb_ca_en50221 *en50221, int slot)
370{
371 /* not implemented */
372 return 0;
373}
374
375int altera_ci_slot_ts_ctl(struct dvb_ca_en50221 *en50221, int slot)
376{
377 struct altera_ci_state *state = en50221->data;
378 struct fpga_internal *inter = state->internal;
379 int ret;
380
381 ci_dbg_print("%s\n", __func__);
382
383 if (0 != slot)
384 return -EINVAL;
385
386 mutex_lock(&inter->fpga_mutex);
387
388 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
389 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL,
390 (ret & 0x0f) | (1 << (3 - state->nr)), 0);
391
392 mutex_unlock(&inter->fpga_mutex);
393
394 return 0;
395}
396
397/* work handler */
398static void netup_read_ci_status(struct work_struct *work)
399{
400 struct fpga_internal *inter =
401 container_of(work, struct fpga_internal, work);
402 int ret;
403
404 ci_dbg_print("%s\n", __func__);
405
406 mutex_lock(&inter->fpga_mutex);
407 /* ack' irq */
408 ret = netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0, NETUP_CI_FLG_RD);
409 ret = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL, 0, NETUP_CI_FLG_RD);
410
411 mutex_unlock(&inter->fpga_mutex);
412
413 if (inter->state[1] != NULL) {
414 inter->state[1]->status =
415 ((ret & 1) == 0 ?
416 DVB_CA_EN50221_POLL_CAM_PRESENT |
417 DVB_CA_EN50221_POLL_CAM_READY : 0);
418 ci_dbg_print("%s: setting CI[1] status = 0x%x\n",
419 __func__, inter->state[1]->status);
420 };
421
422 if (inter->state[0] != NULL) {
423 inter->state[0]->status =
424 ((ret & 2) == 0 ?
425 DVB_CA_EN50221_POLL_CAM_PRESENT |
426 DVB_CA_EN50221_POLL_CAM_READY : 0);
427 ci_dbg_print("%s: setting CI[0] status = 0x%x\n",
428 __func__, inter->state[0]->status);
429 };
430}
431
432/* CI irq handler */
433int altera_ci_irq(void *dev)
434{
435 struct fpga_inode *temp_int = NULL;
436 struct fpga_internal *inter = NULL;
437
438 ci_dbg_print("%s\n", __func__);
439
440 if (dev != NULL) {
441 temp_int = find_inode(dev);
442 if (temp_int != NULL) {
443 inter = temp_int->internal;
444 schedule_work(&inter->work);
445 }
446 }
447
448 return 1;
449}
450EXPORT_SYMBOL(altera_ci_irq);
451
452int altera_poll_ci_slot_status(struct dvb_ca_en50221 *en50221, int slot,
453 int open)
454{
455 struct altera_ci_state *state = en50221->data;
456
457 if (0 != slot)
458 return -EINVAL;
459
460 return state->status;
461}
462
463void altera_hw_filt_release(void *main_dev, int filt_nr)
464{
465 struct fpga_inode *temp_int = find_inode(main_dev);
466 struct netup_hw_pid_filter *pid_filt = NULL;
467
468 ci_dbg_print("%s\n", __func__);
469
470 if (temp_int != NULL) {
471 pid_filt = temp_int->internal->pid_filt[filt_nr - 1];
472 /* stored old feed controls */
473 pid_filt->demux->start_feed = pid_filt->start_feed;
474 pid_filt->demux->stop_feed = pid_filt->stop_feed;
475
476 if (((--(temp_int->internal->filts_used)) <= 0) &&
477 ((temp_int->internal->cis_used) <= 0)) {
478
479 ci_dbg_print("%s: Actually removing\n", __func__);
480
481 remove_inode(temp_int->internal);
482 kfree(pid_filt->internal);
483 }
484
485 kfree(pid_filt);
486
487 }
488
489}
490EXPORT_SYMBOL(altera_hw_filt_release);
491
492void altera_ci_release(void *dev, int ci_nr)
493{
494 struct fpga_inode *temp_int = find_inode(dev);
495 struct altera_ci_state *state = NULL;
496
497 ci_dbg_print("%s\n", __func__);
498
499 if (temp_int != NULL) {
500 state = temp_int->internal->state[ci_nr - 1];
501 altera_hw_filt_release(dev, ci_nr);
502
503
504 if (((temp_int->internal->filts_used) <= 0) &&
505 ((--(temp_int->internal->cis_used)) <= 0)) {
506
507 ci_dbg_print("%s: Actually removing\n", __func__);
508
509 remove_inode(temp_int->internal);
510 kfree(state->internal);
511 }
512
513 if (state != NULL) {
514 if (state->ca.data != NULL)
515 dvb_ca_en50221_release(&state->ca);
516
517 kfree(state);
518 }
519 }
520
521}
522EXPORT_SYMBOL(altera_ci_release);
523
524static void altera_pid_control(struct netup_hw_pid_filter *pid_filt,
525 u16 pid, int onoff)
526{
527 struct fpga_internal *inter = pid_filt->internal;
528 u8 store = 0;
529
530 /* pid 0-0x1f always enabled, don't touch them */
531 if ((pid == 0x2000) || (pid < 0x20))
532 return;
533
534 mutex_lock(&inter->fpga_mutex);
535
536 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, (pid >> 3) & 0xff, 0);
537 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
538 ((pid >> 11) & 0x03) | (pid_filt->nr << 2), 0);
539
540 store = netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, 0, NETUP_CI_FLG_RD);
541
542 if (onoff)/* 0 - on, 1 - off */
543 store |= (1 << (pid & 7));
544 else
545 store &= ~(1 << (pid & 7));
546
547 netup_fpga_op_rw(inter, NETUP_CI_PID_DATA, store, 0);
548
549 mutex_unlock(&inter->fpga_mutex);
550
551 pid_dbg_print("%s: (%d) set pid: %5d 0x%04x '%s'\n", __func__,
552 pid_filt->nr, pid, pid, onoff ? "off" : "on");
553}
554
555static void altera_toggle_fullts_streaming(struct netup_hw_pid_filter *pid_filt,
556 int filt_nr, int onoff)
557{
558 struct fpga_internal *inter = pid_filt->internal;
559 u8 store = 0;
560 int i;
561
562 pid_dbg_print("%s: pid_filt->nr[%d] now %s\n", __func__, pid_filt->nr,
563 onoff ? "off" : "on");
564
565 if (onoff)/* 0 - on, 1 - off */
566 store = 0xff;/* ignore pid */
567 else
568 store = 0;/* enable pid */
569
570 mutex_lock(&inter->fpga_mutex);
571
572 for (i = 0; i < 1024; i++) {
573 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR0, i & 0xff, 0);
574
575 netup_fpga_op_rw(inter, NETUP_CI_PID_ADDR1,
576 ((i >> 8) & 0x03) | (pid_filt->nr << 2), 0);
577 /* pid 0-0x1f always enabled */
578 netup_fpga_op_rw(inter, NETUP_CI_PID_DATA,
579 (i > 3 ? store : 0), 0);
580 }
581
582 mutex_unlock(&inter->fpga_mutex);
583}
584
585int altera_pid_feed_control(void *demux_dev, int filt_nr,
586 struct dvb_demux_feed *feed, int onoff)
587{
588 struct fpga_inode *temp_int = find_dinode(demux_dev);
589 struct fpga_internal *inter = temp_int->internal;
590 struct netup_hw_pid_filter *pid_filt = inter->pid_filt[filt_nr - 1];
591
592 altera_pid_control(pid_filt, feed->pid, onoff ? 0 : 1);
593 /* call old feed proc's */
594 if (onoff)
595 pid_filt->start_feed(feed);
596 else
597 pid_filt->stop_feed(feed);
598
599 if (feed->pid == 0x2000)
600 altera_toggle_fullts_streaming(pid_filt, filt_nr,
601 onoff ? 0 : 1);
602
603 return 0;
604}
605EXPORT_SYMBOL(altera_pid_feed_control);
606
607int altera_ci_start_feed(struct dvb_demux_feed *feed, int num)
608{
609 altera_pid_feed_control(feed->demux, num, feed, 1);
610
611 return 0;
612}
613
614int altera_ci_stop_feed(struct dvb_demux_feed *feed, int num)
615{
616 altera_pid_feed_control(feed->demux, num, feed, 0);
617
618 return 0;
619}
620
621int altera_ci_start_feed_1(struct dvb_demux_feed *feed)
622{
623 return altera_ci_start_feed(feed, 1);
624}
625
626int altera_ci_stop_feed_1(struct dvb_demux_feed *feed)
627{
628 return altera_ci_stop_feed(feed, 1);
629}
630
631int altera_ci_start_feed_2(struct dvb_demux_feed *feed)
632{
633 return altera_ci_start_feed(feed, 2);
634}
635
636int altera_ci_stop_feed_2(struct dvb_demux_feed *feed)
637{
638 return altera_ci_stop_feed(feed, 2);
639}
640
641int altera_hw_filt_init(struct altera_ci_config *config, int hw_filt_nr)
642{
643 struct netup_hw_pid_filter *pid_filt = NULL;
644 struct fpga_inode *temp_int = find_inode(config->dev);
645 struct fpga_internal *inter = NULL;
646 int ret = 0;
647
648 pid_filt = kzalloc(sizeof(struct netup_hw_pid_filter), GFP_KERNEL);
649
650 ci_dbg_print("%s\n", __func__);
651
652 if (!pid_filt) {
653 ret = -ENOMEM;
654 goto err;
655 }
656
657 if (temp_int != NULL) {
658 inter = temp_int->internal;
659 (inter->filts_used)++;
660 ci_dbg_print("%s: Find Internal Structure!\n", __func__);
661 } else {
662 inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
663 if (!inter) {
664 ret = -ENOMEM;
665 goto err;
666 }
667
668 temp_int = append_internal(inter);
669 inter->filts_used = 1;
670 inter->dev = config->dev;
671 inter->fpga_rw = config->fpga_rw;
672 mutex_init(&inter->fpga_mutex);
673 inter->strt_wrk = 1;
674 ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
675 }
676
677 ci_dbg_print("%s: setting hw pid filter = %p for ci = %d\n", __func__,
678 pid_filt, hw_filt_nr - 1);
679 inter->pid_filt[hw_filt_nr - 1] = pid_filt;
680 pid_filt->demux = config->demux;
681 pid_filt->internal = inter;
682 pid_filt->nr = hw_filt_nr - 1;
683 /* store old feed controls */
684 pid_filt->start_feed = config->demux->start_feed;
685 pid_filt->stop_feed = config->demux->stop_feed;
686 /* replace with new feed controls */
687 if (hw_filt_nr == 1) {
688 pid_filt->demux->start_feed = altera_ci_start_feed_1;
689 pid_filt->demux->stop_feed = altera_ci_stop_feed_1;
690 } else if (hw_filt_nr == 2) {
691 pid_filt->demux->start_feed = altera_ci_start_feed_2;
692 pid_filt->demux->stop_feed = altera_ci_stop_feed_2;
693 }
694
695 altera_toggle_fullts_streaming(pid_filt, 0, 1);
696
697 return 0;
698err:
699 ci_dbg_print("%s: Can't init hardware filter: Error %d\n",
700 __func__, ret);
701
702 kfree(pid_filt);
703
704 return ret;
705}
706EXPORT_SYMBOL(altera_hw_filt_init);
707
708int altera_ci_init(struct altera_ci_config *config, int ci_nr)
709{
710 struct altera_ci_state *state;
711 struct fpga_inode *temp_int = find_inode(config->dev);
712 struct fpga_internal *inter = NULL;
713 int ret = 0;
714 u8 store = 0;
715
716 state = kzalloc(sizeof(struct altera_ci_state), GFP_KERNEL);
717
718 ci_dbg_print("%s\n", __func__);
719
720 if (!state) {
721 ret = -ENOMEM;
722 goto err;
723 }
724
725 if (temp_int != NULL) {
726 inter = temp_int->internal;
727 (inter->cis_used)++;
728 ci_dbg_print("%s: Find Internal Structure!\n", __func__);
729 } else {
730 inter = kzalloc(sizeof(struct fpga_internal), GFP_KERNEL);
731 if (!inter) {
732 ret = -ENOMEM;
733 goto err;
734 }
735
736 temp_int = append_internal(inter);
737 inter->cis_used = 1;
738 inter->dev = config->dev;
739 inter->fpga_rw = config->fpga_rw;
740 mutex_init(&inter->fpga_mutex);
741 inter->strt_wrk = 1;
742 ci_dbg_print("%s: Create New Internal Structure!\n", __func__);
743 }
744
745 ci_dbg_print("%s: setting state = %p for ci = %d\n", __func__,
746 state, ci_nr - 1);
747 inter->state[ci_nr - 1] = state;
748 state->internal = inter;
749 state->nr = ci_nr - 1;
750
751 state->ca.owner = THIS_MODULE;
752 state->ca.read_attribute_mem = altera_ci_read_attribute_mem;
753 state->ca.write_attribute_mem = altera_ci_write_attribute_mem;
754 state->ca.read_cam_control = altera_ci_read_cam_ctl;
755 state->ca.write_cam_control = altera_ci_write_cam_ctl;
756 state->ca.slot_reset = altera_ci_slot_reset;
757 state->ca.slot_shutdown = altera_ci_slot_shutdown;
758 state->ca.slot_ts_enable = altera_ci_slot_ts_ctl;
759 state->ca.poll_slot_status = altera_poll_ci_slot_status;
760 state->ca.data = state;
761
762 ret = dvb_ca_en50221_init(config->adapter,
763 &state->ca,
764 /* flags */ 0,
765 /* n_slots */ 1);
766 if (0 != ret)
767 goto err;
768
769 altera_hw_filt_init(config, ci_nr);
770
771 if (inter->strt_wrk) {
772 INIT_WORK(&inter->work, netup_read_ci_status);
773 inter->strt_wrk = 0;
774 }
775
776 ci_dbg_print("%s: CI initialized!\n", __func__);
777
778 mutex_lock(&inter->fpga_mutex);
779
780 /* Enable div */
781 netup_fpga_op_rw(inter, NETUP_CI_TSA_DIV, 0x0, 0);
782 netup_fpga_op_rw(inter, NETUP_CI_TSB_DIV, 0x0, 0);
783
784 /* enable TS out */
785 store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
786 store |= (3 << 4);
787 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
788
789 ret = netup_fpga_op_rw(inter, NETUP_CI_REVISION, 0, NETUP_CI_FLG_RD);
790 /* enable irq */
791 netup_fpga_op_rw(inter, NETUP_CI_INT_CTRL, 0x44, 0);
792
793 mutex_unlock(&inter->fpga_mutex);
794
795 ci_dbg_print("%s: NetUP CI Revision = 0x%x\n", __func__, ret);
796
797 schedule_work(&inter->work);
798
799 return 0;
800err:
801 ci_dbg_print("%s: Cannot initialize CI: Error %d.\n", __func__, ret);
802
803 kfree(state);
804
805 return ret;
806}
807EXPORT_SYMBOL(altera_ci_init);
808
809int altera_ci_tuner_reset(void *dev, int ci_nr)
810{
811 struct fpga_inode *temp_int = find_inode(dev);
812 struct fpga_internal *inter = NULL;
813 u8 store;
814
815 ci_dbg_print("%s\n", __func__);
816
817 if (temp_int == NULL)
818 return -1;
819
820 if (temp_int->internal == NULL)
821 return -1;
822
823 inter = temp_int->internal;
824
825 mutex_lock(&inter->fpga_mutex);
826
827 store = netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, 0, NETUP_CI_FLG_RD);
828 store &= ~(4 << (2 - ci_nr));
829 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
830 msleep(100);
831 store |= (4 << (2 - ci_nr));
832 netup_fpga_op_rw(inter, NETUP_CI_BUSCTRL2, store, 0);
833
834 mutex_unlock(&inter->fpga_mutex);
835
836 return 0;
837}
838EXPORT_SYMBOL(altera_ci_tuner_reset);
diff --git a/drivers/media/video/cx23885/altera-ci.h b/drivers/media/video/cx23885/altera-ci.h
new file mode 100644
index 000000000000..70e4fd69ad9e
--- /dev/null
+++ b/drivers/media/video/cx23885/altera-ci.h
@@ -0,0 +1,100 @@
1/*
2 * altera-ci.c
3 *
4 * CI driver in conjunction with NetUp Dual DVB-T/C RF CI card
5 *
6 * Copyright (C) 2010 NetUP Inc.
7 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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 *
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, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24#ifndef __ALTERA_CI_H
25#define __ALTERA_CI_H
26
27#define ALT_DATA 0x000000ff
28#define ALT_TDI 0x00008000
29#define ALT_TDO 0x00004000
30#define ALT_TCK 0x00002000
31#define ALT_RDY 0x00001000
32#define ALT_RD 0x00000800
33#define ALT_WR 0x00000400
34#define ALT_AD_RG 0x00000200
35#define ALT_CS 0x00000100
36
37struct altera_ci_config {
38 void *dev;/* main dev, for example cx23885_dev */
39 void *adapter;/* for CI to connect to */
40 struct dvb_demux *demux;/* for hardware PID filter to connect to */
41 int (*fpga_rw) (void *dev, int ad_rg, int val, int rw);
42};
43
44#if defined(CONFIG_MEDIA_ALTERA_CI) || (defined(CONFIG_MEDIA_ALTERA_CI_MODULE) \
45 && defined(MODULE))
46
47extern int altera_ci_init(struct altera_ci_config *config, int ci_nr);
48extern void altera_ci_release(void *dev, int ci_nr);
49extern int altera_ci_irq(void *dev);
50extern int altera_ci_tuner_reset(void *dev, int ci_nr);
51
52#else
53
54static inline int altera_ci_init(struct altera_ci_config *config, int ci_nr)
55{
56 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
57 return 0;
58}
59
60static inline void altera_ci_release(void *dev, int ci_nr)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
63}
64
65static inline int altera_ci_irq(void *dev)
66{
67 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
68 return 0;
69}
70
71static inline int altera_ci_tuner_reset(void *dev, int ci_nr)
72{
73 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
74 return 0;
75}
76
77#endif
78#if 0
79static inline int altera_hw_filt_init(struct altera_ci_config *config,
80 int hw_filt_nr)
81{
82 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
83 return 0;
84}
85
86static inline void altera_hw_filt_release(void *dev, int filt_nr)
87{
88 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
89}
90
91static inline int altera_pid_feed_control(void *dev, int filt_nr,
92 struct dvb_demux_feed *dvbdmxfeed, int onoff)
93{
94 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
95 return 0;
96}
97
98#endif /* CONFIG_MEDIA_ALTERA_CI */
99
100#endif /* __ALTERA_CI_H */
diff --git a/drivers/media/video/cx23885/cx23885-cards.c b/drivers/media/video/cx23885/cx23885-cards.c
index b298b730943c..ea88722cb4ab 100644
--- a/drivers/media/video/cx23885/cx23885-cards.c
+++ b/drivers/media/video/cx23885/cx23885-cards.c
@@ -24,10 +24,14 @@
24#include <linux/pci.h> 24#include <linux/pci.h>
25#include <linux/delay.h> 25#include <linux/delay.h>
26#include <media/cx25840.h> 26#include <media/cx25840.h>
27#include <linux/firmware.h>
28#include <staging/altera.h>
27 29
28#include "cx23885.h" 30#include "cx23885.h"
29#include "tuner-xc2028.h" 31#include "tuner-xc2028.h"
30#include "netup-init.h" 32#include "netup-init.h"
33#include "altera-ci.h"
34#include "xc5000.h"
31#include "cx23888-ir.h" 35#include "cx23888-ir.h"
32 36
33static unsigned int enable_885_ir; 37static unsigned int enable_885_ir;
@@ -90,6 +94,7 @@ struct cx23885_board cx23885_boards[] = {
90 .portc = CX23885_MPEG_DVB, 94 .portc = CX23885_MPEG_DVB,
91 .tuner_type = TUNER_PHILIPS_TDA8290, 95 .tuner_type = TUNER_PHILIPS_TDA8290,
92 .tuner_addr = 0x42, /* 0x84 >> 1 */ 96 .tuner_addr = 0x42, /* 0x84 >> 1 */
97 .tuner_bus = 1,
93 .input = {{ 98 .input = {{
94 .type = CX23885_VMUX_TELEVISION, 99 .type = CX23885_VMUX_TELEVISION,
95 .vmux = CX25840_VIN7_CH3 | 100 .vmux = CX25840_VIN7_CH3 |
@@ -187,7 +192,7 @@ struct cx23885_board cx23885_boards[] = {
187 .portb = CX23885_MPEG_DVB, 192 .portb = CX23885_MPEG_DVB,
188 }, 193 },
189 [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = { 194 [CX23885_BOARD_NETUP_DUAL_DVBS2_CI] = {
190 .cimax = 1, 195 .ci_type = 1,
191 .name = "NetUP Dual DVB-S2 CI", 196 .name = "NetUP Dual DVB-S2 CI",
192 .portb = CX23885_MPEG_DVB, 197 .portb = CX23885_MPEG_DVB,
193 .portc = CX23885_MPEG_DVB, 198 .portc = CX23885_MPEG_DVB,
@@ -212,6 +217,7 @@ struct cx23885_board cx23885_boards[] = {
212 .name = "Mygica X8506 DMB-TH", 217 .name = "Mygica X8506 DMB-TH",
213 .tuner_type = TUNER_XC5000, 218 .tuner_type = TUNER_XC5000,
214 .tuner_addr = 0x61, 219 .tuner_addr = 0x61,
220 .tuner_bus = 1,
215 .porta = CX23885_ANALOG_VIDEO, 221 .porta = CX23885_ANALOG_VIDEO,
216 .portb = CX23885_MPEG_DVB, 222 .portb = CX23885_MPEG_DVB,
217 .input = { 223 .input = {
@@ -241,6 +247,7 @@ struct cx23885_board cx23885_boards[] = {
241 .name = "Magic-Pro ProHDTV Extreme 2", 247 .name = "Magic-Pro ProHDTV Extreme 2",
242 .tuner_type = TUNER_XC5000, 248 .tuner_type = TUNER_XC5000,
243 .tuner_addr = 0x61, 249 .tuner_addr = 0x61,
250 .tuner_bus = 1,
244 .porta = CX23885_ANALOG_VIDEO, 251 .porta = CX23885_ANALOG_VIDEO,
245 .portb = CX23885_MPEG_DVB, 252 .portb = CX23885_MPEG_DVB,
246 .input = { 253 .input = {
@@ -289,6 +296,7 @@ struct cx23885_board cx23885_boards[] = {
289 .porta = CX23885_ANALOG_VIDEO, 296 .porta = CX23885_ANALOG_VIDEO,
290 .tuner_type = TUNER_XC2028, 297 .tuner_type = TUNER_XC2028,
291 .tuner_addr = 0x61, 298 .tuner_addr = 0x61,
299 .tuner_bus = 1,
292 .input = {{ 300 .input = {{
293 .type = CX23885_VMUX_TELEVISION, 301 .type = CX23885_VMUX_TELEVISION,
294 .vmux = CX25840_VIN2_CH1 | 302 .vmux = CX25840_VIN2_CH1 |
@@ -313,6 +321,7 @@ struct cx23885_board cx23885_boards[] = {
313 .name = "GoTView X5 3D Hybrid", 321 .name = "GoTView X5 3D Hybrid",
314 .tuner_type = TUNER_XC5000, 322 .tuner_type = TUNER_XC5000,
315 .tuner_addr = 0x64, 323 .tuner_addr = 0x64,
324 .tuner_bus = 1,
316 .porta = CX23885_ANALOG_VIDEO, 325 .porta = CX23885_ANALOG_VIDEO,
317 .portb = CX23885_MPEG_DVB, 326 .portb = CX23885_MPEG_DVB,
318 .input = {{ 327 .input = {{
@@ -329,6 +338,21 @@ struct cx23885_board cx23885_boards[] = {
329 CX25840_SVIDEO_CHROMA4, 338 CX25840_SVIDEO_CHROMA4,
330 } }, 339 } },
331 }, 340 },
341 [CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF] = {
342 .ci_type = 2,
343 .name = "NetUP Dual DVB-T/C-CI RF",
344 .porta = CX23885_ANALOG_VIDEO,
345 .portb = CX23885_MPEG_DVB,
346 .portc = CX23885_MPEG_DVB,
347 .num_fds_portb = 2,
348 .num_fds_portc = 2,
349 .tuner_type = TUNER_XC5000,
350 .tuner_addr = 0x64,
351 .input = { {
352 .type = CX23885_VMUX_TELEVISION,
353 .vmux = CX25840_COMPOSITE1,
354 } },
355 },
332}; 356};
333const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards); 357const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
334 358
@@ -520,6 +544,10 @@ struct cx23885_subid cx23885_subids[] = {
520 .subvendor = 0x5654, 544 .subvendor = 0x5654,
521 .subdevice = 0x2390, 545 .subdevice = 0x2390,
522 .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID, 546 .card = CX23885_BOARD_GOTVIEW_X5_3D_HYBRID,
547 }, {
548 .subvendor = 0x1b55,
549 .subdevice = 0xe2e4,
550 .card = CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF,
523 }, 551 },
524}; 552};
525const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids); 553const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -740,6 +768,9 @@ int cx23885_tuner_callback(void *priv, int component, int command, int arg)
740 /* Tuner Reset Command */ 768 /* Tuner Reset Command */
741 bitmask = 0x02; 769 bitmask = 0x02;
742 break; 770 break;
771 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
772 altera_ci_tuner_reset(dev, port->nr);
773 break;
743 } 774 }
744 775
745 if (bitmask) { 776 if (bitmask) {
@@ -998,6 +1029,33 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
998 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID: 1029 case CX23885_BOARD_GOTVIEW_X5_3D_HYBRID:
999 cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */ 1030 cx_set(GP0_IO, 0x00010001); /* Bring the part out of reset */
1000 break; 1031 break;
1032 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1033 /* GPIO-0 ~INT in
1034 GPIO-1 TMS out
1035 GPIO-2 ~reset chips out
1036 GPIO-3 to GPIO-10 data/addr for CA in/out
1037 GPIO-11 ~CS out
1038 GPIO-12 ADDR out
1039 GPIO-13 ~WR out
1040 GPIO-14 ~RD out
1041 GPIO-15 ~RDY in
1042 GPIO-16 TCK out
1043 GPIO-17 TDO in
1044 GPIO-18 TDI out
1045 */
1046 cx_set(GP0_IO, 0x00060000); /* GPIO-1,2 as out */
1047 /* GPIO-0 as INT, reset & TMS low */
1048 cx_clear(GP0_IO, 0x00010006);
1049 mdelay(100);/* reset delay */
1050 cx_set(GP0_IO, 0x00000004); /* reset high */
1051 cx_write(MC417_CTL, 0x00000037);/* enable GPIO-3..18 pins */
1052 /* GPIO-17 is TDO in, GPIO-15 is ~RDY in, rest is out */
1053 cx_write(MC417_OEN, 0x00005000);
1054 /* ~RD, ~WR high; ADDR low; ~CS high */
1055 cx_write(MC417_RWD, 0x00000d00);
1056 /* enable irq */
1057 cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
1058 break;
1001 } 1059 }
1002} 1060}
1003 1061
@@ -1113,6 +1171,31 @@ void cx23885_ir_fini(struct cx23885_dev *dev)
1113 } 1171 }
1114} 1172}
1115 1173
1174int netup_jtag_io(void *device, int tms, int tdi, int read_tdo)
1175{
1176 int data;
1177 int tdo = 0;
1178 struct cx23885_dev *dev = (struct cx23885_dev *)device;
1179 /*TMS*/
1180 data = ((cx_read(GP0_IO)) & (~0x00000002));
1181 data |= (tms ? 0x00020002 : 0x00020000);
1182 cx_write(GP0_IO, data);
1183
1184 /*TDI*/
1185 data = ((cx_read(MC417_RWD)) & (~0x0000a000));
1186 data |= (tdi ? 0x00008000 : 0);
1187 cx_write(MC417_RWD, data);
1188 if (read_tdo)
1189 tdo = (data & 0x00004000) ? 1 : 0; /*TDO*/
1190
1191 cx_write(MC417_RWD, data | 0x00002000);
1192 udelay(1);
1193 /*TCK*/
1194 cx_write(MC417_RWD, data);
1195
1196 return tdo;
1197}
1198
1116void cx23885_ir_pci_int_enable(struct cx23885_dev *dev) 1199void cx23885_ir_pci_int_enable(struct cx23885_dev *dev)
1117{ 1200{
1118 switch (dev->board) { 1201 switch (dev->board) {
@@ -1212,6 +1295,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1212 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1295 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
1213 break; 1296 break;
1214 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1297 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1298 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1215 ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */ 1299 ts1->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
1216 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */ 1300 ts1->ts_clk_en_val = 0x1; /* Enable TS_CLK */
1217 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; 1301 ts1->src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO;
@@ -1271,6 +1355,7 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1271 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H: 1355 case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
1272 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F: 1356 case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
1273 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1357 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1358 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1274 case CX23885_BOARD_COMPRO_VIDEOMATE_E800: 1359 case CX23885_BOARD_COMPRO_VIDEOMATE_E800:
1275 case CX23885_BOARD_HAUPPAUGE_HVR1850: 1360 case CX23885_BOARD_HAUPPAUGE_HVR1850:
1276 case CX23885_BOARD_MYGICA_X8506: 1361 case CX23885_BOARD_MYGICA_X8506:
@@ -1293,6 +1378,29 @@ void cx23885_card_setup(struct cx23885_dev *dev)
1293 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1378 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1294 netup_initialize(dev); 1379 netup_initialize(dev);
1295 break; 1380 break;
1381 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1382 int ret;
1383 const struct firmware *fw;
1384 const char *filename = "dvb-netup-altera-01.fw";
1385 char *action = "configure";
1386 struct altera_config netup_config = {
1387 .dev = dev,
1388 .action = action,
1389 .jtag_io = netup_jtag_io,
1390 };
1391
1392 netup_initialize(dev);
1393
1394 ret = request_firmware(&fw, filename, &dev->pci->dev);
1395 if (ret != 0)
1396 printk(KERN_ERR "did not find the firmware file. (%s) "
1397 "Please see linux/Documentation/dvb/ for more details "
1398 "on firmware-problems.", filename);
1399 else
1400 altera_init(&netup_config, fw);
1401
1402 break;
1403 }
1296 } 1404 }
1297} 1405}
1298 1406
diff --git a/drivers/media/video/cx23885/cx23885-core.c b/drivers/media/video/cx23885/cx23885-core.c
index 359882419b7f..9933810b4e33 100644
--- a/drivers/media/video/cx23885/cx23885-core.c
+++ b/drivers/media/video/cx23885/cx23885-core.c
@@ -29,9 +29,11 @@
29#include <linux/interrupt.h> 29#include <linux/interrupt.h>
30#include <linux/delay.h> 30#include <linux/delay.h>
31#include <asm/div64.h> 31#include <asm/div64.h>
32#include <linux/firmware.h>
32 33
33#include "cx23885.h" 34#include "cx23885.h"
34#include "cimax2.h" 35#include "cimax2.h"
36#include "altera-ci.h"
35#include "cx23888-ir.h" 37#include "cx23888-ir.h"
36#include "cx23885-ir.h" 38#include "cx23885-ir.h"
37#include "cx23885-av.h" 39#include "cx23885-av.h"
@@ -902,8 +904,6 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
902 dev->pci_bus = dev->pci->bus->number; 904 dev->pci_bus = dev->pci->bus->number;
903 dev->pci_slot = PCI_SLOT(dev->pci->devfn); 905 dev->pci_slot = PCI_SLOT(dev->pci->devfn);
904 cx23885_irq_add(dev, 0x001f00); 906 cx23885_irq_add(dev, 0x001f00);
905 if (cx23885_boards[dev->board].cimax > 0)
906 cx23885_irq_add(dev, 0x01800000); /* for CiMaxes */
907 907
908 /* External Master 1 Bus */ 908 /* External Master 1 Bus */
909 dev->i2c_bus[0].nr = 0; 909 dev->i2c_bus[0].nr = 0;
@@ -970,11 +970,12 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
970 /* Assume some sensible defaults */ 970 /* Assume some sensible defaults */
971 dev->tuner_type = cx23885_boards[dev->board].tuner_type; 971 dev->tuner_type = cx23885_boards[dev->board].tuner_type;
972 dev->tuner_addr = cx23885_boards[dev->board].tuner_addr; 972 dev->tuner_addr = cx23885_boards[dev->board].tuner_addr;
973 dev->tuner_bus = cx23885_boards[dev->board].tuner_bus;
973 dev->radio_type = cx23885_boards[dev->board].radio_type; 974 dev->radio_type = cx23885_boards[dev->board].radio_type;
974 dev->radio_addr = cx23885_boards[dev->board].radio_addr; 975 dev->radio_addr = cx23885_boards[dev->board].radio_addr;
975 976
976 dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x\n", 977 dprintk(1, "%s() tuner_type = 0x%x tuner_addr = 0x%x tuner_bus = %d\n",
977 __func__, dev->tuner_type, dev->tuner_addr); 978 __func__, dev->tuner_type, dev->tuner_addr, dev->tuner_bus);
978 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n", 979 dprintk(1, "%s() radio_type = 0x%x radio_addr = 0x%x\n",
979 __func__, dev->radio_type, dev->radio_addr); 980 __func__, dev->radio_type, dev->radio_addr);
980 981
@@ -1004,6 +1005,9 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1004 } 1005 }
1005 1006
1006 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) { 1007 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) {
1008 if (cx23885_boards[dev->board].num_fds_portb)
1009 dev->ts1.num_frontends =
1010 cx23885_boards[dev->board].num_fds_portb;
1007 if (cx23885_dvb_register(&dev->ts1) < 0) { 1011 if (cx23885_dvb_register(&dev->ts1) < 0) {
1008 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n", 1012 printk(KERN_ERR "%s() Failed to register dvb adapters on VID_B\n",
1009 __func__); 1013 __func__);
@@ -1018,6 +1022,9 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1018 } 1022 }
1019 1023
1020 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) { 1024 if (cx23885_boards[dev->board].portc == CX23885_MPEG_DVB) {
1025 if (cx23885_boards[dev->board].num_fds_portc)
1026 dev->ts2.num_frontends =
1027 cx23885_boards[dev->board].num_fds_portc;
1021 if (cx23885_dvb_register(&dev->ts2) < 0) { 1028 if (cx23885_dvb_register(&dev->ts2) < 0) {
1022 printk(KERN_ERR 1029 printk(KERN_ERR
1023 "%s() Failed to register dvb on VID_C\n", 1030 "%s() Failed to register dvb on VID_C\n",
@@ -1034,6 +1041,10 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
1034 1041
1035 cx23885_dev_checkrevision(dev); 1042 cx23885_dev_checkrevision(dev);
1036 1043
1044 /* disable MSI for NetUP cards, otherwise CI is not working */
1045 if (cx23885_boards[dev->board].ci_type > 0)
1046 cx_clear(RDR_RDRCTL1, 1 << 8);
1047
1037 return 0; 1048 return 0;
1038} 1049}
1039 1050
@@ -1822,14 +1833,13 @@ static irqreturn_t cx23885_irq(int irq, void *dev_id)
1822 PCI_MSK_IR); 1833 PCI_MSK_IR);
1823 } 1834 }
1824 1835
1825 if (cx23885_boards[dev->board].cimax > 0 && 1836 if (cx23885_boards[dev->board].ci_type == 1 &&
1826 ((pci_status & PCI_MSK_GPIO0) || 1837 (pci_status & (PCI_MSK_GPIO1 | PCI_MSK_GPIO0)))
1827 (pci_status & PCI_MSK_GPIO1))) { 1838 handled += netup_ci_slot_status(dev, pci_status);
1828
1829 if (cx23885_boards[dev->board].cimax > 0)
1830 handled += netup_ci_slot_status(dev, pci_status);
1831 1839
1832 } 1840 if (cx23885_boards[dev->board].ci_type == 2 &&
1841 (pci_status & PCI_MSK_GPIO0))
1842 handled += altera_ci_irq(dev);
1833 1843
1834 if (ts1_status) { 1844 if (ts1_status) {
1835 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB) 1845 if (cx23885_boards[dev->board].portb == CX23885_MPEG_DVB)
@@ -2064,7 +2074,10 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
2064 2074
2065 switch (dev->board) { 2075 switch (dev->board) {
2066 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 2076 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
2067 cx23885_irq_add_enable(dev, 0x01800000); /* for NetUP */ 2077 cx23885_irq_add_enable(dev, PCI_MSK_GPIO1 | PCI_MSK_GPIO0);
2078 break;
2079 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
2080 cx23885_irq_add_enable(dev, PCI_MSK_GPIO0);
2068 break; 2081 break;
2069 } 2082 }
2070 2083
diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c
index 5958cb882e93..3c315f94cc85 100644
--- a/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/drivers/media/video/cx23885/cx23885-dvb.c
@@ -58,6 +58,8 @@
58#include "atbm8830.h" 58#include "atbm8830.h"
59#include "ds3000.h" 59#include "ds3000.h"
60#include "cx23885-f300.h" 60#include "cx23885-f300.h"
61#include "altera-ci.h"
62#include "stv0367.h"
61 63
62static unsigned int debug; 64static unsigned int debug;
63 65
@@ -108,6 +110,22 @@ static void dvb_buf_release(struct videobuf_queue *q,
108 cx23885_free_buffer(q, (struct cx23885_buffer *)vb); 110 cx23885_free_buffer(q, (struct cx23885_buffer *)vb);
109} 111}
110 112
113static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open)
114{
115 struct videobuf_dvb_frontends *f;
116 struct videobuf_dvb_frontend *fe;
117
118 f = &port->frontends;
119
120 if (f->gate <= 1) /* undefined or fe0 */
121 fe = videobuf_dvb_get_frontend(f, 1);
122 else
123 fe = videobuf_dvb_get_frontend(f, f->gate);
124
125 if (fe && fe->dvb.frontend && fe->dvb.frontend->ops.i2c_gate_ctrl)
126 fe->dvb.frontend->ops.i2c_gate_ctrl(fe->dvb.frontend, open);
127}
128
111static struct videobuf_queue_ops dvb_qops = { 129static struct videobuf_queue_ops dvb_qops = {
112 .buf_setup = dvb_buf_setup, 130 .buf_setup = dvb_buf_setup,
113 .buf_prepare = dvb_buf_prepare, 131 .buf_prepare = dvb_buf_prepare,
@@ -570,12 +588,84 @@ static struct max2165_config mygic_x8558pro_max2165_cfg2 = {
570 .i2c_address = 0x60, 588 .i2c_address = 0x60,
571 .osc_clk = 20 589 .osc_clk = 20
572}; 590};
591static struct stv0367_config netup_stv0367_config[] = {
592 {
593 .demod_address = 0x1c,
594 .xtal = 27000000,
595 .if_khz = 4500,
596 .if_iq_mode = 0,
597 .ts_mode = 1,
598 .clk_pol = 0,
599 }, {
600 .demod_address = 0x1d,
601 .xtal = 27000000,
602 .if_khz = 4500,
603 .if_iq_mode = 0,
604 .ts_mode = 1,
605 .clk_pol = 0,
606 },
607};
608
609static struct xc5000_config netup_xc5000_config[] = {
610 {
611 .i2c_address = 0x61,
612 .if_khz = 4500,
613 }, {
614 .i2c_address = 0x64,
615 .if_khz = 4500,
616 },
617};
618
619int netup_altera_fpga_rw(void *device, int flag, int data, int read)
620{
621 struct cx23885_dev *dev = (struct cx23885_dev *)device;
622 unsigned long timeout = jiffies + msecs_to_jiffies(1);
623 uint32_t mem = 0;
624
625 mem = cx_read(MC417_RWD);
626 if (read)
627 cx_set(MC417_OEN, ALT_DATA);
628 else {
629 cx_clear(MC417_OEN, ALT_DATA);/* D0-D7 out */
630 mem &= ~ALT_DATA;
631 mem |= (data & ALT_DATA);
632 }
633
634 if (flag)
635 mem |= ALT_AD_RG;
636 else
637 mem &= ~ALT_AD_RG;
638
639 mem &= ~ALT_CS;
640 if (read)
641 mem = (mem & ~ALT_RD) | ALT_WR;
642 else
643 mem = (mem & ~ALT_WR) | ALT_RD;
644
645 cx_write(MC417_RWD, mem); /* start RW cycle */
646
647 for (;;) {
648 mem = cx_read(MC417_RWD);
649 if ((mem & ALT_RDY) == 0)
650 break;
651 if (time_after(jiffies, timeout))
652 break;
653 udelay(1);
654 }
655
656 cx_set(MC417_RWD, ALT_RD | ALT_WR | ALT_CS);
657 if (read)
658 return mem & ALT_DATA;
659
660 return 0;
661};
573 662
574static int dvb_register(struct cx23885_tsport *port) 663static int dvb_register(struct cx23885_tsport *port)
575{ 664{
576 struct cx23885_dev *dev = port->dev; 665 struct cx23885_dev *dev = port->dev;
577 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL; 666 struct cx23885_i2c *i2c_bus = NULL, *i2c_bus2 = NULL;
578 struct videobuf_dvb_frontend *fe0; 667 struct videobuf_dvb_frontend *fe0, *fe1 = NULL;
668 int mfe_shared = 0; /* bus not shared by default */
579 int ret; 669 int ret;
580 670
581 /* Get the first frontend */ 671 /* Get the first frontend */
@@ -586,6 +676,12 @@ static int dvb_register(struct cx23885_tsport *port)
586 /* init struct videobuf_dvb */ 676 /* init struct videobuf_dvb */
587 fe0->dvb.name = dev->name; 677 fe0->dvb.name = dev->name;
588 678
679 /* multi-frontend gate control is undefined or defaults to fe0 */
680 port->frontends.gate = 0;
681
682 /* Sets the gate control callback to be used by i2c command calls */
683 port->gate_ctrl = cx23885_dvb_gate_ctrl;
684
589 /* init frontend */ 685 /* init frontend */
590 switch (dev->board) { 686 switch (dev->board) {
591 case CX23885_BOARD_HAUPPAUGE_HVR1250: 687 case CX23885_BOARD_HAUPPAUGE_HVR1250:
@@ -966,20 +1062,64 @@ static int dvb_register(struct cx23885_tsport *port)
966 break; 1062 break;
967 } 1063 }
968 break; 1064 break;
969 1065 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1066 i2c_bus = &dev->i2c_bus[0];
1067 mfe_shared = 1;/* MFE */
1068 port->frontends.gate = 0;/* not clear for me yet */
1069 /* ports B, C */
1070 /* MFE frontend 1 DVB-T */
1071 fe0->dvb.frontend = dvb_attach(stv0367ter_attach,
1072 &netup_stv0367_config[port->nr - 1],
1073 &i2c_bus->i2c_adap);
1074 if (fe0->dvb.frontend != NULL) {
1075 if (NULL == dvb_attach(xc5000_attach,
1076 fe0->dvb.frontend,
1077 &i2c_bus->i2c_adap,
1078 &netup_xc5000_config[port->nr - 1]))
1079 goto frontend_detach;
1080 /* load xc5000 firmware */
1081 fe0->dvb.frontend->ops.tuner_ops.init(fe0->dvb.frontend);
1082 }
1083 /* MFE frontend 2 */
1084 fe1 = videobuf_dvb_get_frontend(&port->frontends, 2);
1085 if (fe1 == NULL)
1086 goto frontend_detach;
1087 /* DVB-C init */
1088 fe1->dvb.frontend = dvb_attach(stv0367cab_attach,
1089 &netup_stv0367_config[port->nr - 1],
1090 &i2c_bus->i2c_adap);
1091 if (fe1->dvb.frontend != NULL) {
1092 fe1->dvb.frontend->id = 1;
1093 if (NULL == dvb_attach(xc5000_attach,
1094 fe1->dvb.frontend,
1095 &i2c_bus->i2c_adap,
1096 &netup_xc5000_config[port->nr - 1]))
1097 goto frontend_detach;
1098 }
1099 break;
970 default: 1100 default:
971 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card " 1101 printk(KERN_INFO "%s: The frontend of your DVB/ATSC card "
972 " isn't supported yet\n", 1102 " isn't supported yet\n",
973 dev->name); 1103 dev->name);
974 break; 1104 break;
975 } 1105 }
976 if (NULL == fe0->dvb.frontend) { 1106
1107 if ((NULL == fe0->dvb.frontend) || (fe1 && NULL == fe1->dvb.frontend)) {
977 printk(KERN_ERR "%s: frontend initialization failed\n", 1108 printk(KERN_ERR "%s: frontend initialization failed\n",
978 dev->name); 1109 dev->name);
979 return -1; 1110 goto frontend_detach;
980 } 1111 }
1112
981 /* define general-purpose callback pointer */ 1113 /* define general-purpose callback pointer */
982 fe0->dvb.frontend->callback = cx23885_tuner_callback; 1114 fe0->dvb.frontend->callback = cx23885_tuner_callback;
1115 if (fe1)
1116 fe1->dvb.frontend->callback = cx23885_tuner_callback;
1117#if 0
1118 /* Ensure all frontends negotiate bus access */
1119 fe0->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
1120 if (fe1)
1121 fe1->dvb.frontend->ops.ts_bus_ctrl = cx23885_dvb_bus_ctrl;
1122#endif
983 1123
984 /* Put the analog decoder in standby to keep it quiet */ 1124 /* Put the analog decoder in standby to keep it quiet */
985 call_all(dev, core, s_power, 0); 1125 call_all(dev, core, s_power, 0);
@@ -989,10 +1129,10 @@ static int dvb_register(struct cx23885_tsport *port)
989 1129
990 /* register everything */ 1130 /* register everything */
991 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port, 1131 ret = videobuf_dvb_register_bus(&port->frontends, THIS_MODULE, port,
992 &dev->pci->dev, adapter_nr, 0, 1132 &dev->pci->dev, adapter_nr, mfe_shared,
993 cx23885_dvb_fe_ioctl_override); 1133 cx23885_dvb_fe_ioctl_override);
994 if (ret) 1134 if (ret)
995 return ret; 1135 goto frontend_detach;
996 1136
997 /* init CI & MAC */ 1137 /* init CI & MAC */
998 switch (dev->board) { 1138 switch (dev->board) {
@@ -1008,6 +1148,17 @@ static int dvb_register(struct cx23885_tsport *port)
1008 netup_ci_init(port); 1148 netup_ci_init(port);
1009 break; 1149 break;
1010 } 1150 }
1151 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF: {
1152 struct altera_ci_config netup_ci_cfg = {
1153 .dev = dev,/* magic number to identify*/
1154 .adapter = &port->frontends.adapter,/* for CI */
1155 .demux = &fe0->dvb.demux,/* for hw pid filter */
1156 .fpga_rw = netup_altera_fpga_rw,
1157 };
1158
1159 altera_ci_init(&netup_ci_cfg, port->nr);
1160 break;
1161 }
1011 case CX23885_BOARD_TEVII_S470: { 1162 case CX23885_BOARD_TEVII_S470: {
1012 u8 eeprom[256]; /* 24C02 i2c eeprom */ 1163 u8 eeprom[256]; /* 24C02 i2c eeprom */
1013 1164
@@ -1024,6 +1175,11 @@ static int dvb_register(struct cx23885_tsport *port)
1024 } 1175 }
1025 1176
1026 return ret; 1177 return ret;
1178
1179frontend_detach:
1180 port->gate_ctrl = NULL;
1181 videobuf_dvb_dealloc_frontends(&port->frontends);
1182 return -EINVAL;
1027} 1183}
1028 1184
1029int cx23885_dvb_register(struct cx23885_tsport *port) 1185int cx23885_dvb_register(struct cx23885_tsport *port)
@@ -1100,8 +1256,13 @@ int cx23885_dvb_unregister(struct cx23885_tsport *port)
1100 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI: 1256 case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
1101 netup_ci_exit(port); 1257 netup_ci_exit(port);
1102 break; 1258 break;
1259 case CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF:
1260 altera_ci_release(port->dev, port->nr);
1261 break;
1103 } 1262 }
1104 1263
1264 port->gate_ctrl = NULL;
1265
1105 return 0; 1266 return 0;
1106} 1267}
1107 1268
diff --git a/drivers/media/video/cx23885/cx23885-input.c b/drivers/media/video/cx23885/cx23885-input.c
index 199b9964bbe5..e97cafd83984 100644
--- a/drivers/media/video/cx23885/cx23885-input.c
+++ b/drivers/media/video/cx23885/cx23885-input.c
@@ -264,7 +264,7 @@ int cx23885_input_init(struct cx23885_dev *dev)
264 driver_type = RC_DRIVER_IR_RAW; 264 driver_type = RC_DRIVER_IR_RAW;
265 allowed_protos = RC_TYPE_ALL; 265 allowed_protos = RC_TYPE_ALL;
266 /* The grey Hauppauge RC-5 remote */ 266 /* The grey Hauppauge RC-5 remote */
267 rc_map = RC_MAP_RC5_HAUPPAUGE_NEW; 267 rc_map = RC_MAP_HAUPPAUGE;
268 break; 268 break;
269 case CX23885_BOARD_TEVII_S470: 269 case CX23885_BOARD_TEVII_S470:
270 /* Integrated CX23885 IR controller */ 270 /* Integrated CX23885 IR controller */
diff --git a/drivers/media/video/cx23885/cx23885-reg.h b/drivers/media/video/cx23885/cx23885-reg.h
index a28772db11f0..c87ac682ebbe 100644
--- a/drivers/media/video/cx23885/cx23885-reg.h
+++ b/drivers/media/video/cx23885/cx23885-reg.h
@@ -292,6 +292,7 @@ Channel manager Data Structure entry = 20 DWORD
292#define RDR_CFG0 0x00050000 292#define RDR_CFG0 0x00050000
293#define RDR_CFG1 0x00050004 293#define RDR_CFG1 0x00050004
294#define RDR_CFG2 0x00050008 294#define RDR_CFG2 0x00050008
295#define RDR_RDRCTL1 0x0005030c
295#define RDR_TLCTL0 0x00050318 296#define RDR_TLCTL0 0x00050318
296 297
297/* APB DMAC Current Buffer Pointer */ 298/* APB DMAC Current Buffer Pointer */
diff --git a/drivers/media/video/cx23885/cx23885-video.c b/drivers/media/video/cx23885/cx23885-video.c
index 644fcb808c0b..ee57f6bedbe3 100644
--- a/drivers/media/video/cx23885/cx23885-video.c
+++ b/drivers/media/video/cx23885/cx23885-video.c
@@ -1468,16 +1468,17 @@ int cx23885_video_register(struct cx23885_dev *dev)
1468 1468
1469 cx23885_irq_add_enable(dev, 0x01); 1469 cx23885_irq_add_enable(dev, 0x01);
1470 1470
1471 if (TUNER_ABSENT != dev->tuner_type) { 1471 if ((TUNER_ABSENT != dev->tuner_type) &&
1472 ((dev->tuner_bus == 0) || (dev->tuner_bus == 1))) {
1472 struct v4l2_subdev *sd = NULL; 1473 struct v4l2_subdev *sd = NULL;
1473 1474
1474 if (dev->tuner_addr) 1475 if (dev->tuner_addr)
1475 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1476 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1476 &dev->i2c_bus[1].i2c_adap, 1477 &dev->i2c_bus[dev->tuner_bus].i2c_adap,
1477 "tuner", dev->tuner_addr, NULL); 1478 "tuner", dev->tuner_addr, NULL);
1478 else 1479 else
1479 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev, 1480 sd = v4l2_i2c_new_subdev(&dev->v4l2_dev,
1480 &dev->i2c_bus[1].i2c_adap, 1481 &dev->i2c_bus[dev->tuner_bus].i2c_adap,
1481 "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV)); 1482 "tuner", 0, v4l2_i2c_tuner_addrs(ADDRS_TV));
1482 if (sd) { 1483 if (sd) {
1483 struct tuner_setup tun_setup; 1484 struct tuner_setup tun_setup;
diff --git a/drivers/media/video/cx23885/cx23885.h b/drivers/media/video/cx23885/cx23885.h
index 62e41ab65810..8db2797bc7c3 100644
--- a/drivers/media/video/cx23885/cx23885.h
+++ b/drivers/media/video/cx23885/cx23885.h
@@ -85,6 +85,7 @@
85#define CX23885_BOARD_MYGICA_X8558PRO 27 85#define CX23885_BOARD_MYGICA_X8558PRO 27
86#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28 86#define CX23885_BOARD_LEADTEK_WINFAST_PXTV1200 28
87#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29 87#define CX23885_BOARD_GOTVIEW_X5_3D_HYBRID 29
88#define CX23885_BOARD_NETUP_DUAL_DVB_T_C_CI_RF 30
88 89
89#define GPIO_0 0x00000001 90#define GPIO_0 0x00000001
90#define GPIO_1 0x00000002 91#define GPIO_1 0x00000002
@@ -204,10 +205,12 @@ typedef enum {
204struct cx23885_board { 205struct cx23885_board {
205 char *name; 206 char *name;
206 port_t porta, portb, portc; 207 port_t porta, portb, portc;
208 int num_fds_portb, num_fds_portc;
207 unsigned int tuner_type; 209 unsigned int tuner_type;
208 unsigned int radio_type; 210 unsigned int radio_type;
209 unsigned char tuner_addr; 211 unsigned char tuner_addr;
210 unsigned char radio_addr; 212 unsigned char radio_addr;
213 unsigned int tuner_bus;
211 214
212 /* Vendors can and do run the PCIe bridge at different 215 /* Vendors can and do run the PCIe bridge at different
213 * clock rates, driven physically by crystals on the PCBs. 216 * clock rates, driven physically by crystals on the PCBs.
@@ -220,7 +223,7 @@ struct cx23885_board {
220 */ 223 */
221 u32 clk_freq; 224 u32 clk_freq;
222 struct cx23885_input input[MAX_CX23885_INPUT]; 225 struct cx23885_input input[MAX_CX23885_INPUT];
223 int cimax; /* for NetUP */ 226 int ci_type; /* for NetUP */
224}; 227};
225 228
226struct cx23885_subid { 229struct cx23885_subid {
@@ -303,6 +306,7 @@ struct cx23885_tsport {
303 306
304 /* Allow a single tsport to have multiple frontends */ 307 /* Allow a single tsport to have multiple frontends */
305 u32 num_frontends; 308 u32 num_frontends;
309 void (*gate_ctrl)(struct cx23885_tsport *port, int open);
306 void *port_priv; 310 void *port_priv;
307}; 311};
308 312
@@ -362,6 +366,7 @@ struct cx23885_dev {
362 v4l2_std_id tvnorm; 366 v4l2_std_id tvnorm;
363 unsigned int tuner_type; 367 unsigned int tuner_type;
364 unsigned char tuner_addr; 368 unsigned char tuner_addr;
369 unsigned int tuner_bus;
365 unsigned int radio_type; 370 unsigned int radio_type;
366 unsigned char radio_addr; 371 unsigned char radio_addr;
367 unsigned int has_radio; 372 unsigned int has_radio;
diff --git a/drivers/media/video/cx88/cx88-alsa.c b/drivers/media/video/cx88/cx88-alsa.c
index 54b7fcd469a8..423c1af8a782 100644
--- a/drivers/media/video/cx88/cx88-alsa.c
+++ b/drivers/media/video/cx88/cx88-alsa.c
@@ -40,6 +40,7 @@
40#include <sound/control.h> 40#include <sound/control.h>
41#include <sound/initval.h> 41#include <sound/initval.h>
42#include <sound/tlv.h> 42#include <sound/tlv.h>
43#include <media/wm8775.h>
43 44
44#include "cx88.h" 45#include "cx88.h"
45#include "cx88-reg.h" 46#include "cx88-reg.h"
@@ -577,6 +578,35 @@ static int snd_cx88_volume_get(struct snd_kcontrol *kcontrol,
577 return 0; 578 return 0;
578} 579}
579 580
581static void snd_cx88_wm8775_volume_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *value)
583{
584 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
585 struct cx88_core *core = chip->core;
586 struct v4l2_control client_ctl;
587 int left = value->value.integer.value[0];
588 int right = value->value.integer.value[1];
589 int v, b;
590
591 memset(&client_ctl, 0, sizeof(client_ctl));
592
593 /* Pass volume & balance onto any WM8775 */
594 if (left >= right) {
595 v = left << 10;
596 b = left ? (0x8000 * right) / left : 0x8000;
597 } else {
598 v = right << 10;
599 b = right ? 0xffff - (0x8000 * left) / right : 0x8000;
600 }
601 client_ctl.value = v;
602 client_ctl.id = V4L2_CID_AUDIO_VOLUME;
603 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
604
605 client_ctl.value = b;
606 client_ctl.id = V4L2_CID_AUDIO_BALANCE;
607 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
608}
609
580/* OK - TODO: test it */ 610/* OK - TODO: test it */
581static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol, 611static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_value *value) 612 struct snd_ctl_elem_value *value)
@@ -587,25 +617,28 @@ static int snd_cx88_volume_put(struct snd_kcontrol *kcontrol,
587 int changed = 0; 617 int changed = 0;
588 u32 old; 618 u32 old;
589 619
620 if (core->board.audio_chip == V4L2_IDENT_WM8775)
621 snd_cx88_wm8775_volume_put(kcontrol, value);
622
590 left = value->value.integer.value[0] & 0x3f; 623 left = value->value.integer.value[0] & 0x3f;
591 right = value->value.integer.value[1] & 0x3f; 624 right = value->value.integer.value[1] & 0x3f;
592 b = right - left; 625 b = right - left;
593 if (b < 0) { 626 if (b < 0) {
594 v = 0x3f - left; 627 v = 0x3f - left;
595 b = (-b) | 0x40; 628 b = (-b) | 0x40;
596 } else { 629 } else {
597 v = 0x3f - right; 630 v = 0x3f - right;
598 } 631 }
599 /* Do we really know this will always be called with IRQs on? */ 632 /* Do we really know this will always be called with IRQs on? */
600 spin_lock_irq(&chip->reg_lock); 633 spin_lock_irq(&chip->reg_lock);
601 old = cx_read(AUD_VOL_CTL); 634 old = cx_read(AUD_VOL_CTL);
602 if (v != (old & 0x3f)) { 635 if (v != (old & 0x3f)) {
603 cx_write(AUD_VOL_CTL, (old & ~0x3f) | v); 636 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, (old & ~0x3f) | v);
604 changed = 1; 637 changed = 1;
605 } 638 }
606 if (cx_read(AUD_BAL_CTL) != b) { 639 if ((cx_read(AUD_BAL_CTL) & 0x7f) != b) {
607 cx_write(AUD_BAL_CTL, b); 640 cx_write(AUD_BAL_CTL, b);
608 changed = 1; 641 changed = 1;
609 } 642 }
610 spin_unlock_irq(&chip->reg_lock); 643 spin_unlock_irq(&chip->reg_lock);
611 644
@@ -618,7 +651,7 @@ static const struct snd_kcontrol_new snd_cx88_volume = {
618 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
619 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | 652 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
620 SNDRV_CTL_ELEM_ACCESS_TLV_READ, 653 SNDRV_CTL_ELEM_ACCESS_TLV_READ,
621 .name = "Playback Volume", 654 .name = "Analog-TV Volume",
622 .info = snd_cx88_volume_info, 655 .info = snd_cx88_volume_info,
623 .get = snd_cx88_volume_get, 656 .get = snd_cx88_volume_get,
624 .put = snd_cx88_volume_put, 657 .put = snd_cx88_volume_put,
@@ -649,7 +682,17 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
649 vol = cx_read(AUD_VOL_CTL); 682 vol = cx_read(AUD_VOL_CTL);
650 if (value->value.integer.value[0] != !(vol & bit)) { 683 if (value->value.integer.value[0] != !(vol & bit)) {
651 vol ^= bit; 684 vol ^= bit;
652 cx_write(AUD_VOL_CTL, vol); 685 cx_swrite(SHADOW_AUD_VOL_CTL, AUD_VOL_CTL, vol);
686 /* Pass mute onto any WM8775 */
687 if ((core->board.audio_chip == V4L2_IDENT_WM8775) &&
688 ((1<<6) == bit)) {
689 struct v4l2_control client_ctl;
690
691 memset(&client_ctl, 0, sizeof(client_ctl));
692 client_ctl.value = 0 != (vol & bit);
693 client_ctl.id = V4L2_CID_AUDIO_MUTE;
694 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
695 }
653 ret = 1; 696 ret = 1;
654 } 697 }
655 spin_unlock_irq(&chip->reg_lock); 698 spin_unlock_irq(&chip->reg_lock);
@@ -658,7 +701,7 @@ static int snd_cx88_switch_put(struct snd_kcontrol *kcontrol,
658 701
659static const struct snd_kcontrol_new snd_cx88_dac_switch = { 702static const struct snd_kcontrol_new snd_cx88_dac_switch = {
660 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 703 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
661 .name = "Playback Switch", 704 .name = "Audio-Out Switch",
662 .info = snd_ctl_boolean_mono_info, 705 .info = snd_ctl_boolean_mono_info,
663 .get = snd_cx88_switch_get, 706 .get = snd_cx88_switch_get,
664 .put = snd_cx88_switch_put, 707 .put = snd_cx88_switch_put,
@@ -667,13 +710,51 @@ static const struct snd_kcontrol_new snd_cx88_dac_switch = {
667 710
668static const struct snd_kcontrol_new snd_cx88_source_switch = { 711static const struct snd_kcontrol_new snd_cx88_source_switch = {
669 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 712 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
670 .name = "Capture Switch", 713 .name = "Analog-TV Switch",
671 .info = snd_ctl_boolean_mono_info, 714 .info = snd_ctl_boolean_mono_info,
672 .get = snd_cx88_switch_get, 715 .get = snd_cx88_switch_get,
673 .put = snd_cx88_switch_put, 716 .put = snd_cx88_switch_put,
674 .private_value = (1<<6), 717 .private_value = (1<<6),
675}; 718};
676 719
720static int snd_cx88_alc_get(struct snd_kcontrol *kcontrol,
721 struct snd_ctl_elem_value *value)
722{
723 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
724 struct cx88_core *core = chip->core;
725 struct v4l2_control client_ctl;
726
727 memset(&client_ctl, 0, sizeof(client_ctl));
728 client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
729 call_hw(core, WM8775_GID, core, g_ctrl, &client_ctl);
730 value->value.integer.value[0] = client_ctl.value ? 1 : 0;
731
732 return 0;
733}
734
735static int snd_cx88_alc_put(struct snd_kcontrol *kcontrol,
736 struct snd_ctl_elem_value *value)
737{
738 snd_cx88_card_t *chip = snd_kcontrol_chip(kcontrol);
739 struct cx88_core *core = chip->core;
740 struct v4l2_control client_ctl;
741
742 memset(&client_ctl, 0, sizeof(client_ctl));
743 client_ctl.value = 0 != value->value.integer.value[0];
744 client_ctl.id = V4L2_CID_AUDIO_LOUDNESS;
745 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
746
747 return 0;
748}
749
750static struct snd_kcontrol_new snd_cx88_alc_switch = {
751 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
752 .name = "Line-In ALC Switch",
753 .info = snd_ctl_boolean_mono_info,
754 .get = snd_cx88_alc_get,
755 .put = snd_cx88_alc_put,
756};
757
677/**************************************************************************** 758/****************************************************************************
678 Basic Flow for Sound Devices 759 Basic Flow for Sound Devices
679 ****************************************************************************/ 760 ****************************************************************************/
@@ -724,7 +805,8 @@ static void snd_cx88_dev_free(struct snd_card * card)
724static int devno; 805static int devno;
725static int __devinit snd_cx88_create(struct snd_card *card, 806static int __devinit snd_cx88_create(struct snd_card *card,
726 struct pci_dev *pci, 807 struct pci_dev *pci,
727 snd_cx88_card_t **rchip) 808 snd_cx88_card_t **rchip,
809 struct cx88_core **core_ptr)
728{ 810{
729 snd_cx88_card_t *chip; 811 snd_cx88_card_t *chip;
730 struct cx88_core *core; 812 struct cx88_core *core;
@@ -750,7 +832,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
750 if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) { 832 if (!pci_dma_supported(pci,DMA_BIT_MASK(32))) {
751 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name); 833 dprintk(0, "%s/1: Oops: no 32bit PCI DMA ???\n",core->name);
752 err = -EIO; 834 err = -EIO;
753 cx88_core_put(core,pci); 835 cx88_core_put(core, pci);
754 return err; 836 return err;
755 } 837 }
756 838
@@ -786,6 +868,7 @@ static int __devinit snd_cx88_create(struct snd_card *card,
786 snd_card_set_dev(card, &pci->dev); 868 snd_card_set_dev(card, &pci->dev);
787 869
788 *rchip = chip; 870 *rchip = chip;
871 *core_ptr = core;
789 872
790 return 0; 873 return 0;
791} 874}
@@ -795,6 +878,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
795{ 878{
796 struct snd_card *card; 879 struct snd_card *card;
797 snd_cx88_card_t *chip; 880 snd_cx88_card_t *chip;
881 struct cx88_core *core = NULL;
798 int err; 882 int err;
799 883
800 if (devno >= SNDRV_CARDS) 884 if (devno >= SNDRV_CARDS)
@@ -812,7 +896,7 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
812 896
813 card->private_free = snd_cx88_dev_free; 897 card->private_free = snd_cx88_dev_free;
814 898
815 err = snd_cx88_create(card, pci, &chip); 899 err = snd_cx88_create(card, pci, &chip, &core);
816 if (err < 0) 900 if (err < 0)
817 goto error; 901 goto error;
818 902
@@ -830,6 +914,10 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci,
830 if (err < 0) 914 if (err < 0)
831 goto error; 915 goto error;
832 916
917 /* If there's a wm8775 then add a Line-In ALC switch */
918 if (core->board.audio_chip == V4L2_IDENT_WM8775)
919 snd_ctl_add(card, snd_ctl_new1(&snd_cx88_alc_switch, chip));
920
833 strcpy (card->driver, "CX88x"); 921 strcpy (card->driver, "CX88x");
834 sprintf(card->shortname, "Conexant CX%x", pci->device); 922 sprintf(card->shortname, "Conexant CX%x", pci->device);
835 sprintf(card->longname, "%s at %#llx", 923 sprintf(card->longname, "%s at %#llx",
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c
index 4e6ee5584cb3..27222c92b603 100644
--- a/drivers/media/video/cx88/cx88-cards.c
+++ b/drivers/media/video/cx88/cx88-cards.c
@@ -970,7 +970,8 @@ static const struct cx88_board cx88_boards[] = {
970 .radio_type = UNSET, 970 .radio_type = UNSET,
971 .tuner_addr = ADDR_UNSET, 971 .tuner_addr = ADDR_UNSET,
972 .radio_addr = ADDR_UNSET, 972 .radio_addr = ADDR_UNSET,
973 .audio_chip = V4L2_IDENT_WM8775, 973 .audio_chip = V4L2_IDENT_WM8775,
974 .i2sinputcntl = 2,
974 .input = {{ 975 .input = {{
975 .type = CX88_VMUX_DVB, 976 .type = CX88_VMUX_DVB,
976 .vmux = 0, 977 .vmux = 0,
@@ -1952,6 +1953,18 @@ static const struct cx88_board cx88_boards[] = {
1952 } }, 1953 } },
1953 .mpeg = CX88_MPEG_DVB, 1954 .mpeg = CX88_MPEG_DVB,
1954 }, 1955 },
1956 [CX88_BOARD_TEVII_S464] = {
1957 .name = "TeVii S464 DVB-S/S2",
1958 .tuner_type = UNSET,
1959 .radio_type = UNSET,
1960 .tuner_addr = ADDR_UNSET,
1961 .radio_addr = ADDR_UNSET,
1962 .input = {{
1963 .type = CX88_VMUX_DVB,
1964 .vmux = 0,
1965 } },
1966 .mpeg = CX88_MPEG_DVB,
1967 },
1955 [CX88_BOARD_OMICOM_SS4_PCI] = { 1968 [CX88_BOARD_OMICOM_SS4_PCI] = {
1956 .name = "Omicom SS4 DVB-S/S2 PCI", 1969 .name = "Omicom SS4 DVB-S/S2 PCI",
1957 .tuner_type = UNSET, 1970 .tuner_type = UNSET,
@@ -2528,6 +2541,10 @@ static const struct cx88_subid cx88_subids[] = {
2528 .subdevice = 0x9022, 2541 .subdevice = 0x9022,
2529 .card = CX88_BOARD_TEVII_S460, 2542 .card = CX88_BOARD_TEVII_S460,
2530 }, { 2543 }, {
2544 .subvendor = 0xd464,
2545 .subdevice = 0x9022,
2546 .card = CX88_BOARD_TEVII_S464,
2547 }, {
2531 .subvendor = 0xA044, 2548 .subvendor = 0xA044,
2532 .subdevice = 0x2011, 2549 .subdevice = 0x2011,
2533 .card = CX88_BOARD_OMICOM_SS4_PCI, 2550 .card = CX88_BOARD_OMICOM_SS4_PCI,
@@ -3165,9 +3182,7 @@ static void cx88_card_setup(struct cx88_core *core)
3165{ 3182{
3166 static u8 eeprom[256]; 3183 static u8 eeprom[256];
3167 struct tuner_setup tun_setup; 3184 struct tuner_setup tun_setup;
3168 unsigned int mode_mask = T_RADIO | 3185 unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
3169 T_ANALOG_TV |
3170 T_DIGITAL_TV;
3171 3186
3172 memset(&tun_setup, 0, sizeof(tun_setup)); 3187 memset(&tun_setup, 0, sizeof(tun_setup));
3173 3188
@@ -3287,6 +3302,7 @@ static void cx88_card_setup(struct cx88_core *core)
3287 } 3302 }
3288 case CX88_BOARD_TEVII_S420: 3303 case CX88_BOARD_TEVII_S420:
3289 case CX88_BOARD_TEVII_S460: 3304 case CX88_BOARD_TEVII_S460:
3305 case CX88_BOARD_TEVII_S464:
3290 case CX88_BOARD_OMICOM_SS4_PCI: 3306 case CX88_BOARD_OMICOM_SS4_PCI:
3291 case CX88_BOARD_TBS_8910: 3307 case CX88_BOARD_TBS_8910:
3292 case CX88_BOARD_TBS_8920: 3308 case CX88_BOARD_TBS_8920:
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c
index 90717ee944ec..7b8c9d3b6efc 100644
--- a/drivers/media/video/cx88/cx88-dvb.c
+++ b/drivers/media/video/cx88/cx88-dvb.c
@@ -57,6 +57,7 @@
57#include "stb6100.h" 57#include "stb6100.h"
58#include "stb6100_proc.h" 58#include "stb6100_proc.h"
59#include "mb86a16.h" 59#include "mb86a16.h"
60#include "ds3000.h"
60 61
61MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); 62MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
62MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); 63MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
@@ -648,6 +649,20 @@ static const struct cx24116_config tevii_s460_config = {
648 .reset_device = cx24116_reset_device, 649 .reset_device = cx24116_reset_device,
649}; 650};
650 651
652static int ds3000_set_ts_param(struct dvb_frontend *fe,
653 int is_punctured)
654{
655 struct cx8802_dev *dev = fe->dvb->priv;
656 dev->ts_gen_cntrl = 4;
657
658 return 0;
659}
660
661static struct ds3000_config tevii_ds3000_config = {
662 .demod_address = 0x68,
663 .set_ts_params = ds3000_set_ts_param,
664};
665
651static const struct stv0900_config prof_7301_stv0900_config = { 666static const struct stv0900_config prof_7301_stv0900_config = {
652 .demod_address = 0x6a, 667 .demod_address = 0x6a,
653/* demod_mode = 0,*/ 668/* demod_mode = 0,*/
@@ -1381,6 +1396,14 @@ static int dvb_register(struct cx8802_dev *dev)
1381 if (fe0->dvb.frontend != NULL) 1396 if (fe0->dvb.frontend != NULL)
1382 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage; 1397 fe0->dvb.frontend->ops.set_voltage = tevii_dvbs_set_voltage;
1383 break; 1398 break;
1399 case CX88_BOARD_TEVII_S464:
1400 fe0->dvb.frontend = dvb_attach(ds3000_attach,
1401 &tevii_ds3000_config,
1402 &core->i2c_adap);
1403 if (fe0->dvb.frontend != NULL)
1404 fe0->dvb.frontend->ops.set_voltage =
1405 tevii_dvbs_set_voltage;
1406 break;
1384 case CX88_BOARD_OMICOM_SS4_PCI: 1407 case CX88_BOARD_OMICOM_SS4_PCI:
1385 case CX88_BOARD_TBS_8920: 1408 case CX88_BOARD_TBS_8920:
1386 case CX88_BOARD_PROF_7300: 1409 case CX88_BOARD_PROF_7300:
diff --git a/drivers/media/video/cx88/cx88-input.c b/drivers/media/video/cx88/cx88-input.c
index 06f7d1d00944..c820e2f53527 100644
--- a/drivers/media/video/cx88/cx88-input.c
+++ b/drivers/media/video/cx88/cx88-input.c
@@ -283,7 +283,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
283 case CX88_BOARD_PCHDTV_HD3000: 283 case CX88_BOARD_PCHDTV_HD3000:
284 case CX88_BOARD_PCHDTV_HD5500: 284 case CX88_BOARD_PCHDTV_HD5500:
285 case CX88_BOARD_HAUPPAUGE_IRONLY: 285 case CX88_BOARD_HAUPPAUGE_IRONLY:
286 ir_codes = RC_MAP_HAUPPAUGE_NEW; 286 ir_codes = RC_MAP_HAUPPAUGE;
287 ir->sampling = 1; 287 ir->sampling = 1;
288 break; 288 break;
289 case CX88_BOARD_WINFAST_DTV2000H: 289 case CX88_BOARD_WINFAST_DTV2000H:
@@ -373,6 +373,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
373 ir_codes = RC_MAP_TBS_NEC; 373 ir_codes = RC_MAP_TBS_NEC;
374 ir->sampling = 0xff00; /* address */ 374 ir->sampling = 0xff00; /* address */
375 break; 375 break;
376 case CX88_BOARD_TEVII_S464:
376 case CX88_BOARD_TEVII_S460: 377 case CX88_BOARD_TEVII_S460:
377 case CX88_BOARD_TEVII_S420: 378 case CX88_BOARD_TEVII_S420:
378 ir_codes = RC_MAP_TEVII_NEC; 379 ir_codes = RC_MAP_TEVII_NEC;
@@ -603,7 +604,7 @@ void cx88_i2c_init_ir(struct cx88_core *core)
603 if (*addrp == 0x71) { 604 if (*addrp == 0x71) {
604 /* Hauppauge XVR */ 605 /* Hauppauge XVR */
605 core->init_data.name = "cx88 Hauppauge XVR remote"; 606 core->init_data.name = "cx88 Hauppauge XVR remote";
606 core->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; 607 core->init_data.ir_codes = RC_MAP_HAUPPAUGE;
607 core->init_data.type = RC_TYPE_RC5; 608 core->init_data.type = RC_TYPE_RC5;
608 core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 609 core->init_data.internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
609 610
diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c
index 08220de3d74d..770ec05b5e9b 100644
--- a/drivers/media/video/cx88/cx88-tvaudio.c
+++ b/drivers/media/video/cx88/cx88-tvaudio.c
@@ -786,8 +786,12 @@ void cx88_set_tvaudio(struct cx88_core *core)
786 break; 786 break;
787 case WW_I2SADC: 787 case WW_I2SADC:
788 set_audio_start(core, 0x01); 788 set_audio_start(core, 0x01);
789 /* Slave/Philips/Autobaud */ 789 /*
790 cx_write(AUD_I2SINPUTCNTL, 0); 790 * Slave/Philips/Autobaud
791 * NB on Nova-S bit1 NPhilipsSony appears to be inverted:
792 * 0= Sony, 1=Philips
793 */
794 cx_write(AUD_I2SINPUTCNTL, core->board.i2sinputcntl);
791 /* Switch to "I2S ADC mode" */ 795 /* Switch to "I2S ADC mode" */
792 cx_write(AUD_I2SCNTL, 0x1); 796 cx_write(AUD_I2SCNTL, 0x1);
793 set_audio_finish(core, EN_I2SIN_ENABLE); 797 set_audio_finish(core, EN_I2SIN_ENABLE);
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c
index 508dabbed986..287a41ee1c4f 100644
--- a/drivers/media/video/cx88/cx88-video.c
+++ b/drivers/media/video/cx88/cx88-video.c
@@ -40,6 +40,7 @@
40#include "cx88.h" 40#include "cx88.h"
41#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
42#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
43#include <media/wm8775.h>
43 44
44MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards"); 45MODULE_DESCRIPTION("v4l2 driver module for cx2388x based TV cards");
45MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 46MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
@@ -989,6 +990,32 @@ int cx88_set_control(struct cx88_core *core, struct v4l2_control *ctl)
989 ctl->value = c->v.minimum; 990 ctl->value = c->v.minimum;
990 if (ctl->value > c->v.maximum) 991 if (ctl->value > c->v.maximum)
991 ctl->value = c->v.maximum; 992 ctl->value = c->v.maximum;
993
994 /* Pass changes onto any WM8775 */
995 if (core->board.audio_chip == V4L2_IDENT_WM8775) {
996 struct v4l2_control client_ctl;
997 memset(&client_ctl, 0, sizeof(client_ctl));
998 client_ctl.id = ctl->id;
999
1000 switch (ctl->id) {
1001 case V4L2_CID_AUDIO_MUTE:
1002 client_ctl.value = ctl->value;
1003 break;
1004 case V4L2_CID_AUDIO_VOLUME:
1005 client_ctl.value = (ctl->value) ?
1006 (0x90 + ctl->value) << 8 : 0;
1007 break;
1008 case V4L2_CID_AUDIO_BALANCE:
1009 client_ctl.value = ctl->value << 9;
1010 break;
1011 default:
1012 client_ctl.id = 0;
1013 break;
1014 }
1015 if (client_ctl.id)
1016 call_hw(core, WM8775_GID, core, s_ctrl, &client_ctl);
1017 }
1018
992 mask=c->mask; 1019 mask=c->mask;
993 switch (ctl->id) { 1020 switch (ctl->id) {
994 case V4L2_CID_AUDIO_BALANCE: 1021 case V4L2_CID_AUDIO_BALANCE:
@@ -1526,7 +1553,9 @@ static int radio_queryctrl (struct file *file, void *priv,
1526 if (c->id < V4L2_CID_BASE || 1553 if (c->id < V4L2_CID_BASE ||
1527 c->id >= V4L2_CID_LASTP1) 1554 c->id >= V4L2_CID_LASTP1)
1528 return -EINVAL; 1555 return -EINVAL;
1529 if (c->id == V4L2_CID_AUDIO_MUTE) { 1556 if (c->id == V4L2_CID_AUDIO_MUTE ||
1557 c->id == V4L2_CID_AUDIO_VOLUME ||
1558 c->id == V4L2_CID_AUDIO_BALANCE) {
1530 for (i = 0; i < CX8800_CTLS; i++) { 1559 for (i = 0; i < CX8800_CTLS; i++) {
1531 if (cx8800_ctls[i].v.id == c->id) 1560 if (cx8800_ctls[i].v.id == c->id)
1532 break; 1561 break;
@@ -1672,7 +1701,7 @@ static const struct v4l2_file_operations video_fops =
1672 .read = video_read, 1701 .read = video_read,
1673 .poll = video_poll, 1702 .poll = video_poll,
1674 .mmap = video_mmap, 1703 .mmap = video_mmap,
1675 .ioctl = video_ioctl2, 1704 .unlocked_ioctl = video_ioctl2,
1676}; 1705};
1677 1706
1678static const struct v4l2_ioctl_ops video_ioctl_ops = { 1707static const struct v4l2_ioctl_ops video_ioctl_ops = {
@@ -1722,7 +1751,7 @@ static const struct v4l2_file_operations radio_fops =
1722 .owner = THIS_MODULE, 1751 .owner = THIS_MODULE,
1723 .open = video_open, 1752 .open = video_open,
1724 .release = video_release, 1753 .release = video_release,
1725 .ioctl = video_ioctl2, 1754 .unlocked_ioctl = video_ioctl2,
1726}; 1755};
1727 1756
1728static const struct v4l2_ioctl_ops radio_ioctl_ops = { 1757static const struct v4l2_ioctl_ops radio_ioctl_ops = {
@@ -1856,9 +1885,24 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1856 1885
1857 /* load and configure helper modules */ 1886 /* load and configure helper modules */
1858 1887
1859 if (core->board.audio_chip == V4L2_IDENT_WM8775) 1888 if (core->board.audio_chip == V4L2_IDENT_WM8775) {
1860 v4l2_i2c_new_subdev(&core->v4l2_dev, &core->i2c_adap, 1889 struct i2c_board_info wm8775_info = {
1861 "wm8775", 0x36 >> 1, NULL); 1890 .type = "wm8775",
1891 .addr = 0x36 >> 1,
1892 .platform_data = &core->wm8775_data,
1893 };
1894 struct v4l2_subdev *sd;
1895
1896 if (core->boardnr == CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1)
1897 core->wm8775_data.is_nova_s = true;
1898 else
1899 core->wm8775_data.is_nova_s = false;
1900
1901 sd = v4l2_i2c_new_subdev_board(&core->v4l2_dev, &core->i2c_adap,
1902 &wm8775_info, NULL);
1903 if (sd != NULL)
1904 sd->grp_id = WM8775_GID;
1905 }
1862 1906
1863 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) { 1907 if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
1864 /* This probes for a tda9874 as is used on some 1908 /* This probes for a tda9874 as is used on some
@@ -1882,6 +1926,15 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1882 request_module("ir-kbd-i2c"); 1926 request_module("ir-kbd-i2c");
1883 } 1927 }
1884 1928
1929 /* Sets device info at pci_dev */
1930 pci_set_drvdata(pci_dev, dev);
1931
1932 /* initial device configuration */
1933 mutex_lock(&core->lock);
1934 cx88_set_tvnorm(core, core->tvnorm);
1935 init_controls(core);
1936 cx88_video_mux(core, 0);
1937
1885 /* register v4l devices */ 1938 /* register v4l devices */
1886 dev->video_dev = cx88_vdev_init(core,dev->pci, 1939 dev->video_dev = cx88_vdev_init(core,dev->pci,
1887 &cx8800_video_template,"video"); 1940 &cx8800_video_template,"video");
@@ -1923,16 +1976,6 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1923 core->name, video_device_node_name(dev->radio_dev)); 1976 core->name, video_device_node_name(dev->radio_dev));
1924 } 1977 }
1925 1978
1926 /* everything worked */
1927 pci_set_drvdata(pci_dev,dev);
1928
1929 /* initial device configuration */
1930 mutex_lock(&core->lock);
1931 cx88_set_tvnorm(core,core->tvnorm);
1932 init_controls(core);
1933 cx88_video_mux(core,0);
1934 mutex_unlock(&core->lock);
1935
1936 /* start tvaudio thread */ 1979 /* start tvaudio thread */
1937 if (core->board.tuner_type != TUNER_ABSENT) { 1980 if (core->board.tuner_type != TUNER_ABSENT) {
1938 core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio"); 1981 core->kthread = kthread_run(cx88_audio_thread, core, "cx88 tvaudio");
@@ -1942,11 +1985,14 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
1942 core->name, err); 1985 core->name, err);
1943 } 1986 }
1944 } 1987 }
1988 mutex_unlock(&core->lock);
1989
1945 return 0; 1990 return 0;
1946 1991
1947fail_unreg: 1992fail_unreg:
1948 cx8800_unregister_video(dev); 1993 cx8800_unregister_video(dev);
1949 free_irq(pci_dev->irq, dev); 1994 free_irq(pci_dev->irq, dev);
1995 mutex_unlock(&core->lock);
1950fail_core: 1996fail_core:
1951 cx88_core_put(core,dev->pci); 1997 cx88_core_put(core,dev->pci);
1952fail_free: 1998fail_free:
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h
index c9981e77416a..9b3742a7746c 100644
--- a/drivers/media/video/cx88/cx88.h
+++ b/drivers/media/video/cx88/cx88.h
@@ -33,6 +33,7 @@
33#include <media/cx2341x.h> 33#include <media/cx2341x.h>
34#include <media/videobuf-dvb.h> 34#include <media/videobuf-dvb.h>
35#include <media/ir-kbd-i2c.h> 35#include <media/ir-kbd-i2c.h>
36#include <media/wm8775.h>
36 37
37#include "btcx-risc.h" 38#include "btcx-risc.h"
38#include "cx88-reg.h" 39#include "cx88-reg.h"
@@ -240,6 +241,7 @@ extern const struct sram_channel const cx88_sram_channels[];
240#define CX88_BOARD_PROF_7301 83 241#define CX88_BOARD_PROF_7301 83
241#define CX88_BOARD_SAMSUNG_SMT_7020 84 242#define CX88_BOARD_SAMSUNG_SMT_7020 84
242#define CX88_BOARD_TWINHAN_VP1027_DVBS 85 243#define CX88_BOARD_TWINHAN_VP1027_DVBS 85
244#define CX88_BOARD_TEVII_S464 86
243 245
244enum cx88_itype { 246enum cx88_itype {
245 CX88_VMUX_COMPOSITE1 = 1, 247 CX88_VMUX_COMPOSITE1 = 1,
@@ -273,6 +275,9 @@ struct cx88_board {
273 enum cx88_board_type mpeg; 275 enum cx88_board_type mpeg;
274 unsigned int audio_chip; 276 unsigned int audio_chip;
275 int num_frontends; 277 int num_frontends;
278
279 /* Used for I2S devices */
280 int i2sinputcntl;
276}; 281};
277 282
278struct cx88_subid { 283struct cx88_subid {
@@ -379,6 +384,7 @@ struct cx88_core {
379 384
380 /* I2C remote data */ 385 /* I2C remote data */
381 struct IR_i2c_init_data init_data; 386 struct IR_i2c_init_data init_data;
387 struct wm8775_platform_data wm8775_data;
382 388
383 struct mutex lock; 389 struct mutex lock;
384 /* various v4l controls */ 390 /* various v4l controls */
@@ -398,17 +404,21 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
398 return container_of(v4l2_dev, struct cx88_core, v4l2_dev); 404 return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
399} 405}
400 406
401#define call_all(core, o, f, args...) \ 407#define WM8775_GID (1 << 0)
408
409#define call_hw(core, grpid, o, f, args...) \
402 do { \ 410 do { \
403 if (!core->i2c_rc) { \ 411 if (!core->i2c_rc) { \
404 if (core->gate_ctrl) \ 412 if (core->gate_ctrl) \
405 core->gate_ctrl(core, 1); \ 413 core->gate_ctrl(core, 1); \
406 v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \ 414 v4l2_device_call_all(&core->v4l2_dev, grpid, o, f, ##args); \
407 if (core->gate_ctrl) \ 415 if (core->gate_ctrl) \
408 core->gate_ctrl(core, 0); \ 416 core->gate_ctrl(core, 0); \
409 } \ 417 } \
410 } while (0) 418 } while (0)
411 419
420#define call_all(core, o, f, args...) call_hw(core, 0, o, f, ##args)
421
412struct cx8800_dev; 422struct cx8800_dev;
413struct cx8802_dev; 423struct cx8802_dev;
414 424
diff --git a/drivers/media/video/davinci/vpfe_capture.c b/drivers/media/video/davinci/vpfe_capture.c
index 353eadaa823e..71e961e53a56 100644
--- a/drivers/media/video/davinci/vpfe_capture.c
+++ b/drivers/media/video/davinci/vpfe_capture.c
@@ -1719,7 +1719,7 @@ unlock_out:
1719 1719
1720 1720
1721static long vpfe_param_handler(struct file *file, void *priv, 1721static long vpfe_param_handler(struct file *file, void *priv,
1722 int cmd, void *param) 1722 bool valid_prio, int cmd, void *param)
1723{ 1723{
1724 struct vpfe_device *vpfe_dev = video_drvdata(file); 1724 struct vpfe_device *vpfe_dev = video_drvdata(file);
1725 int ret = 0; 1725 int ret = 0;
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 87f77a34eeab..69fcea82d01c 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -834,7 +834,7 @@ struct em28xx_board em28xx_boards[] = {
834 .mts_firmware = 1, 834 .mts_firmware = 1,
835 .has_dvb = 1, 835 .has_dvb = 1,
836 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 836 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
837 .ir_codes = RC_MAP_HAUPPAUGE_NEW, 837 .ir_codes = RC_MAP_HAUPPAUGE,
838 .decoder = EM28XX_TVP5150, 838 .decoder = EM28XX_TVP5150,
839 .input = { { 839 .input = { {
840 .type = EM28XX_VMUX_TELEVISION, 840 .type = EM28XX_VMUX_TELEVISION,
@@ -859,7 +859,7 @@ struct em28xx_board em28xx_boards[] = {
859 .tuner_type = TUNER_XC2028, 859 .tuner_type = TUNER_XC2028,
860 .tuner_gpio = default_tuner_gpio, 860 .tuner_gpio = default_tuner_gpio,
861 .mts_firmware = 1, 861 .mts_firmware = 1,
862 .ir_codes = RC_MAP_HAUPPAUGE_NEW, 862 .ir_codes = RC_MAP_HAUPPAUGE,
863 .decoder = EM28XX_TVP5150, 863 .decoder = EM28XX_TVP5150,
864 .input = { { 864 .input = { {
865 .type = EM28XX_VMUX_TELEVISION, 865 .type = EM28XX_VMUX_TELEVISION,
@@ -885,7 +885,7 @@ struct em28xx_board em28xx_boards[] = {
885 .mts_firmware = 1, 885 .mts_firmware = 1,
886 .has_dvb = 1, 886 .has_dvb = 1,
887 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 887 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
888 .ir_codes = RC_MAP_HAUPPAUGE_NEW, 888 .ir_codes = RC_MAP_HAUPPAUGE,
889 .decoder = EM28XX_TVP5150, 889 .decoder = EM28XX_TVP5150,
890 .input = { { 890 .input = { {
891 .type = EM28XX_VMUX_TELEVISION, 891 .type = EM28XX_VMUX_TELEVISION,
@@ -911,7 +911,7 @@ struct em28xx_board em28xx_boards[] = {
911 .mts_firmware = 1, 911 .mts_firmware = 1,
912 .has_dvb = 1, 912 .has_dvb = 1,
913 .dvb_gpio = hauppauge_wintv_hvr_900_digital, 913 .dvb_gpio = hauppauge_wintv_hvr_900_digital,
914 .ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW, 914 .ir_codes = RC_MAP_HAUPPAUGE,
915 .decoder = EM28XX_TVP5150, 915 .decoder = EM28XX_TVP5150,
916 .input = { { 916 .input = { {
917 .type = EM28XX_VMUX_TELEVISION, 917 .type = EM28XX_VMUX_TELEVISION,
@@ -2430,7 +2430,7 @@ void em28xx_register_i2c_ir(struct em28xx *dev)
2430 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)"; 2430 dev->init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
2431 break; 2431 break;
2432 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2: 2432 case EM2820_BOARD_HAUPPAUGE_WINTV_USB_2:
2433 dev->init_data.ir_codes = RC_MAP_RC5_HAUPPAUGE_NEW; 2433 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
2434 dev->init_data.get_key = em28xx_get_key_em_haup; 2434 dev->init_data.get_key = em28xx_get_key_em_haup;
2435 dev->init_data.name = "i2c IR (EM2840 Hauppauge)"; 2435 dev->init_data.name = "i2c IR (EM2840 Hauppauge)";
2436 break; 2436 break;
diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c
index f34d524ccb09..a83131bd00b2 100644
--- a/drivers/media/video/em28xx/em28xx-video.c
+++ b/drivers/media/video/em28xx/em28xx-video.c
@@ -1387,6 +1387,27 @@ static int vidioc_queryctrl(struct file *file, void *priv,
1387 return -EINVAL; 1387 return -EINVAL;
1388} 1388}
1389 1389
1390/*
1391 * FIXME: This is an indirect way to check if a control exists at a
1392 * subdev. Instead of that hack, maybe the better would be to change all
1393 * subdevs to return -ENOIOCTLCMD, if an ioctl is not supported.
1394 */
1395static int check_subdev_ctrl(struct em28xx *dev, int id)
1396{
1397 struct v4l2_queryctrl qc;
1398
1399 memset(&qc, 0, sizeof(qc));
1400 qc.id = id;
1401
1402 /* enumerate V4L2 device controls */
1403 v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, &qc);
1404
1405 if (qc.type)
1406 return 0;
1407 else
1408 return -EINVAL;
1409}
1410
1390static int vidioc_g_ctrl(struct file *file, void *priv, 1411static int vidioc_g_ctrl(struct file *file, void *priv,
1391 struct v4l2_control *ctrl) 1412 struct v4l2_control *ctrl)
1392{ 1413{
@@ -1399,7 +1420,6 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1399 return rc; 1420 return rc;
1400 rc = 0; 1421 rc = 0;
1401 1422
1402
1403 /* Set an AC97 control */ 1423 /* Set an AC97 control */
1404 if (dev->audio_mode.ac97 != EM28XX_NO_AC97) 1424 if (dev->audio_mode.ac97 != EM28XX_NO_AC97)
1405 rc = ac97_get_ctrl(dev, ctrl); 1425 rc = ac97_get_ctrl(dev, ctrl);
@@ -1408,6 +1428,9 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1408 1428
1409 /* It were not an AC97 control. Sends it to the v4l2 dev interface */ 1429 /* It were not an AC97 control. Sends it to the v4l2 dev interface */
1410 if (rc == 1) { 1430 if (rc == 1) {
1431 if (check_subdev_ctrl(dev, ctrl->id))
1432 return -EINVAL;
1433
1411 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl); 1434 v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
1412 rc = 0; 1435 rc = 0;
1413 } 1436 }
@@ -1434,8 +1457,10 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1434 1457
1435 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */ 1458 /* It isn't an AC97 control. Sends it to the v4l2 dev interface */
1436 if (rc == 1) { 1459 if (rc == 1) {
1437 rc = v4l2_device_call_until_err(&dev->v4l2_dev, 0, core, s_ctrl, ctrl); 1460 rc = check_subdev_ctrl(dev, ctrl->id);
1438 1461 if (!rc)
1462 v4l2_device_call_all(&dev->v4l2_dev, 0,
1463 core, s_ctrl, ctrl);
1439 /* 1464 /*
1440 * In the case of non-AC97 volume controls, we still need 1465 * In the case of non-AC97 volume controls, we still need
1441 * to do some setups at em28xx, in order to mute/unmute 1466 * to do some setups at em28xx, in order to mute/unmute
@@ -1452,7 +1477,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1452 rc = em28xx_audio_analog_set(dev); 1477 rc = em28xx_audio_analog_set(dev);
1453 } 1478 }
1454 } 1479 }
1455 return rc; 1480 return (rc < 0) ? rc : 0;
1456} 1481}
1457 1482
1458static int vidioc_g_tuner(struct file *file, void *priv, 1483static int vidioc_g_tuner(struct file *file, void *priv,
diff --git a/drivers/media/video/gspca/Kconfig b/drivers/media/video/gspca/Kconfig
index dda56ff834f4..eb04e8b59989 100644
--- a/drivers/media/video/gspca/Kconfig
+++ b/drivers/media/video/gspca/Kconfig
@@ -104,6 +104,15 @@ config USB_GSPCA_MR97310A
104 To compile this driver as a module, choose M here: the 104 To compile this driver as a module, choose M here: the
105 module will be called gspca_mr97310a. 105 module will be called gspca_mr97310a.
106 106
107config USB_GSPCA_NW80X
108 tristate "Divio based (NW80x) USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA
110 help
111 Say Y here if you want support for cameras based on the NW80x chips.
112
113 To compile this driver as a module, choose M here: the
114 module will be called gspca_nw80x.
115
107config USB_GSPCA_OV519 116config USB_GSPCA_OV519
108 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver" 117 tristate "OV51x / OVFX2 / W996xCF USB Camera Driver"
109 depends on VIDEO_V4L2 && USB_GSPCA 118 depends on VIDEO_V4L2 && USB_GSPCA
@@ -346,6 +355,16 @@ config USB_GSPCA_VC032X
346 To compile this driver as a module, choose M here: the 355 To compile this driver as a module, choose M here: the
347 module will be called gspca_vc032x. 356 module will be called gspca_vc032x.
348 357
358config USB_GSPCA_VICAM
359 tristate "ViCam USB Camera Driver"
360 depends on VIDEO_V4L2 && USB_GSPCA
361 help
362 Say Y here if you want support for the 3com homeconnect camera
363 (vicam).
364
365 To compile this driver as a module, choose M here: the
366 module will be called gspca_vicam.
367
349config USB_GSPCA_XIRLINK_CIT 368config USB_GSPCA_XIRLINK_CIT
350 tristate "Xirlink C-It USB Camera Driver" 369 tristate "Xirlink C-It USB Camera Driver"
351 depends on VIDEO_V4L2 && USB_GSPCA 370 depends on VIDEO_V4L2 && USB_GSPCA
diff --git a/drivers/media/video/gspca/Makefile b/drivers/media/video/gspca/Makefile
index 24e695b8b077..855fbc8c9c47 100644
--- a/drivers/media/video/gspca/Makefile
+++ b/drivers/media/video/gspca/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_USB_GSPCA_JEILINJ) += gspca_jeilinj.o
8obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o 8obj-$(CONFIG_USB_GSPCA_KONICA) += gspca_konica.o
9obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o 9obj-$(CONFIG_USB_GSPCA_MARS) += gspca_mars.o
10obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o 10obj-$(CONFIG_USB_GSPCA_MR97310A) += gspca_mr97310a.o
11obj-$(CONFIG_USB_GSPCA_NW80X) += gspca_nw80x.o
11obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o 12obj-$(CONFIG_USB_GSPCA_OV519) += gspca_ov519.o
12obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o 13obj-$(CONFIG_USB_GSPCA_OV534) += gspca_ov534.o
13obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o 14obj-$(CONFIG_USB_GSPCA_OV534_9) += gspca_ov534_9.o
@@ -34,6 +35,7 @@ obj-$(CONFIG_USB_GSPCA_STV0680) += gspca_stv0680.o
34obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o 35obj-$(CONFIG_USB_GSPCA_T613) += gspca_t613.o
35obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o 36obj-$(CONFIG_USB_GSPCA_TV8532) += gspca_tv8532.o
36obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o 37obj-$(CONFIG_USB_GSPCA_VC032X) += gspca_vc032x.o
38obj-$(CONFIG_USB_GSPCA_VICAM) += gspca_vicam.o
37obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o 39obj-$(CONFIG_USB_GSPCA_XIRLINK_CIT) += gspca_xirlink_cit.o
38obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o 40obj-$(CONFIG_USB_GSPCA_ZC3XX) += gspca_zc3xx.o
39 41
@@ -47,6 +49,7 @@ gspca_jeilinj-objs := jeilinj.o
47gspca_konica-objs := konica.o 49gspca_konica-objs := konica.o
48gspca_mars-objs := mars.o 50gspca_mars-objs := mars.o
49gspca_mr97310a-objs := mr97310a.o 51gspca_mr97310a-objs := mr97310a.o
52gspca_nw80x-objs := nw80x.o
50gspca_ov519-objs := ov519.o 53gspca_ov519-objs := ov519.o
51gspca_ov534-objs := ov534.o 54gspca_ov534-objs := ov534.o
52gspca_ov534_9-objs := ov534_9.o 55gspca_ov534_9-objs := ov534_9.o
@@ -73,6 +76,7 @@ gspca_sunplus-objs := sunplus.o
73gspca_t613-objs := t613.o 76gspca_t613-objs := t613.o
74gspca_tv8532-objs := tv8532.o 77gspca_tv8532-objs := tv8532.o
75gspca_vc032x-objs := vc032x.o 78gspca_vc032x-objs := vc032x.o
79gspca_vicam-objs := vicam.o
76gspca_xirlink_cit-objs := xirlink_cit.o 80gspca_xirlink_cit-objs := xirlink_cit.o
77gspca_zc3xx-objs := zc3xx.o 81gspca_zc3xx-objs := zc3xx.o
78 82
diff --git a/drivers/media/video/gspca/autogain_functions.h b/drivers/media/video/gspca/autogain_functions.h
new file mode 100644
index 000000000000..46777eee678b
--- /dev/null
+++ b/drivers/media/video/gspca/autogain_functions.h
@@ -0,0 +1,179 @@
1/*
2 * Functions for auto gain.
3 *
4 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.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 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21/* auto gain and exposure algorithm based on the knee algorithm described here:
22 http://ytse.tricolour.net/docs/LowLightOptimization.html
23
24 Returns 0 if no changes were made, 1 if the gain and or exposure settings
25 where changed. */
26static inline int auto_gain_n_exposure(
27 struct gspca_dev *gspca_dev,
28 int avg_lum,
29 int desired_avg_lum,
30 int deadzone,
31 int gain_knee,
32 int exposure_knee)
33{
34 struct sd *sd = (struct sd *) gspca_dev;
35 int i, steps, gain, orig_gain, exposure, orig_exposure;
36 int retval = 0;
37
38 orig_gain = gain = sd->ctrls[GAIN].val;
39 orig_exposure = exposure = sd->ctrls[EXPOSURE].val;
40
41 /* If we are of a multiple of deadzone, do multiple steps to reach the
42 desired lumination fast (with the risc of a slight overshoot) */
43 steps = abs(desired_avg_lum - avg_lum) / deadzone;
44
45 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
46 avg_lum, desired_avg_lum, steps);
47
48 for (i = 0; i < steps; i++) {
49 if (avg_lum > desired_avg_lum) {
50 if (gain > gain_knee)
51 gain--;
52 else if (exposure > exposure_knee)
53 exposure--;
54 else if (gain > sd->ctrls[GAIN].def)
55 gain--;
56 else if (exposure > sd->ctrls[EXPOSURE].min)
57 exposure--;
58 else if (gain > sd->ctrls[GAIN].min)
59 gain--;
60 else
61 break;
62 } else {
63 if (gain < sd->ctrls[GAIN].def)
64 gain++;
65 else if (exposure < exposure_knee)
66 exposure++;
67 else if (gain < gain_knee)
68 gain++;
69 else if (exposure < sd->ctrls[EXPOSURE].max)
70 exposure++;
71 else if (gain < sd->ctrls[GAIN].max)
72 gain++;
73 else
74 break;
75 }
76 }
77
78 if (gain != orig_gain) {
79 sd->ctrls[GAIN].val = gain;
80 setgain(gspca_dev);
81 retval = 1;
82 }
83 if (exposure != orig_exposure) {
84 sd->ctrls[EXPOSURE].val = exposure;
85 setexposure(gspca_dev);
86 retval = 1;
87 }
88
89 if (retval)
90 PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
91 gain, exposure);
92 return retval;
93}
94
95/* Autogain + exposure algorithm for cameras with a coarse exposure control
96 (usually this means we can only control the clockdiv to change exposure)
97 As changing the clockdiv so that the fps drops from 30 to 15 fps for
98 example, will lead to a huge exposure change (it effectively doubles),
99 this algorithm normally tries to only adjust the gain (between 40 and
100 80 %) and if that does not help, only then changes exposure. This leads
101 to a much more stable image then using the knee algorithm which at
102 certain points of the knee graph will only try to adjust exposure,
103 which leads to oscilating as one exposure step is huge.
104
105 Note this assumes that the sd struct for the cam in question has
106 exp_too_high_cnt and exp_too_high_cnt int members for use by this function.
107
108 Returns 0 if no changes were made, 1 if the gain and or exposure settings
109 where changed. */
110static inline int coarse_grained_expo_autogain(
111 struct gspca_dev *gspca_dev,
112 int avg_lum,
113 int desired_avg_lum,
114 int deadzone)
115{
116 struct sd *sd = (struct sd *) gspca_dev;
117 int steps, gain, orig_gain, exposure, orig_exposure;
118 int gain_low, gain_high;
119 int retval = 0;
120
121 orig_gain = gain = sd->ctrls[GAIN].val;
122 orig_exposure = exposure = sd->ctrls[EXPOSURE].val;
123
124 gain_low = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 2;
125 gain_low += sd->ctrls[GAIN].min;
126 gain_high = (sd->ctrls[GAIN].max - sd->ctrls[GAIN].min) / 5 * 4;
127 gain_high += sd->ctrls[GAIN].min;
128
129 /* If we are of a multiple of deadzone, do multiple steps to reach the
130 desired lumination fast (with the risc of a slight overshoot) */
131 steps = (desired_avg_lum - avg_lum) / deadzone;
132
133 PDEBUG(D_FRAM, "autogain: lum: %d, desired: %d, steps: %d",
134 avg_lum, desired_avg_lum, steps);
135
136 if ((gain + steps) > gain_high &&
137 exposure < sd->ctrls[EXPOSURE].max) {
138 gain = gain_high;
139 sd->exp_too_low_cnt++;
140 sd->exp_too_high_cnt = 0;
141 } else if ((gain + steps) < gain_low &&
142 exposure > sd->ctrls[EXPOSURE].min) {
143 gain = gain_low;
144 sd->exp_too_high_cnt++;
145 sd->exp_too_low_cnt = 0;
146 } else {
147 gain += steps;
148 if (gain > sd->ctrls[GAIN].max)
149 gain = sd->ctrls[GAIN].max;
150 else if (gain < sd->ctrls[GAIN].min)
151 gain = sd->ctrls[GAIN].min;
152 sd->exp_too_high_cnt = 0;
153 sd->exp_too_low_cnt = 0;
154 }
155
156 if (sd->exp_too_high_cnt > 3) {
157 exposure--;
158 sd->exp_too_high_cnt = 0;
159 } else if (sd->exp_too_low_cnt > 3) {
160 exposure++;
161 sd->exp_too_low_cnt = 0;
162 }
163
164 if (gain != orig_gain) {
165 sd->ctrls[GAIN].val = gain;
166 setgain(gspca_dev);
167 retval = 1;
168 }
169 if (exposure != orig_exposure) {
170 sd->ctrls[EXPOSURE].val = exposure;
171 setexposure(gspca_dev);
172 retval = 1;
173 }
174
175 if (retval)
176 PDEBUG(D_FRAM, "autogain: changed gain: %d, expo: %d",
177 gain, exposure);
178 return retval;
179}
diff --git a/drivers/media/video/gspca/cpia1.c b/drivers/media/video/gspca/cpia1.c
index 4bf2cab98d64..9ddbac680663 100644
--- a/drivers/media/video/gspca/cpia1.c
+++ b/drivers/media/video/gspca/cpia1.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * cpia CPiA (1) gspca driver 2 * cpia CPiA (1) gspca driver
3 * 3 *
4 * Copyright (C) 2010 Hans de Goede <hdegoede@redhat.com> 4 * Copyright (C) 2010-2011 Hans de Goede <hdegoede@redhat.com>
5 * 5 *
6 * This module is adapted from the in kernel v4l1 cpia driver which is : 6 * This module is adapted from the in kernel v4l1 cpia driver which is :
7 * 7 *
@@ -28,6 +28,7 @@
28 28
29#define MODULE_NAME "cpia1" 29#define MODULE_NAME "cpia1"
30 30
31#include <linux/input.h>
31#include "gspca.h" 32#include "gspca.h"
32 33
33MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 34MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
@@ -653,10 +654,15 @@ static int do_command(struct gspca_dev *gspca_dev, u16 command,
653 break; 654 break;
654 655
655 case CPIA_COMMAND_ReadMCPorts: 656 case CPIA_COMMAND_ReadMCPorts:
656 if (!sd->params.qx3.qx3_detected)
657 break;
658 /* test button press */ 657 /* test button press */
659 sd->params.qx3.button = ((gspca_dev->usb_buf[1] & 0x02) == 0); 658 a = ((gspca_dev->usb_buf[1] & 0x02) == 0);
659 if (a != sd->params.qx3.button) {
660#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
661 input_report_key(gspca_dev->input_dev, KEY_CAMERA, a);
662 input_sync(gspca_dev->input_dev);
663#endif
664 sd->params.qx3.button = a;
665 }
660 if (sd->params.qx3.button) { 666 if (sd->params.qx3.button) {
661 /* button pressed - unlock the latch */ 667 /* button pressed - unlock the latch */
662 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort, 668 do_command(gspca_dev, CPIA_COMMAND_WriteMCPort,
@@ -1400,7 +1406,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
1400 if ((sd->exposure_status == EXPOSURE_VERY_DARK || 1406 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1401 sd->exposure_status == EXPOSURE_DARK) && 1407 sd->exposure_status == EXPOSURE_DARK) &&
1402 sd->exposure_count >= DARK_TIME * framerate && 1408 sd->exposure_count >= DARK_TIME * framerate &&
1403 sd->params.sensorFps.divisor < 3) { 1409 sd->params.sensorFps.divisor < 2) {
1404 1410
1405 /* dark for too long */ 1411 /* dark for too long */
1406 ++sd->params.sensorFps.divisor; 1412 ++sd->params.sensorFps.divisor;
@@ -1456,7 +1462,7 @@ static void monitor_exposure(struct gspca_dev *gspca_dev)
1456 if ((sd->exposure_status == EXPOSURE_VERY_DARK || 1462 if ((sd->exposure_status == EXPOSURE_VERY_DARK ||
1457 sd->exposure_status == EXPOSURE_DARK) && 1463 sd->exposure_status == EXPOSURE_DARK) &&
1458 sd->exposure_count >= DARK_TIME * framerate && 1464 sd->exposure_count >= DARK_TIME * framerate &&
1459 sd->params.sensorFps.divisor < 3) { 1465 sd->params.sensorFps.divisor < 2) {
1460 1466
1461 /* dark for too long */ 1467 /* dark for too long */
1462 ++sd->params.sensorFps.divisor; 1468 ++sd->params.sensorFps.divisor;
@@ -1738,6 +1744,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
1738 1744
1739static void sd_stopN(struct gspca_dev *gspca_dev) 1745static void sd_stopN(struct gspca_dev *gspca_dev)
1740{ 1746{
1747 struct sd *sd = (struct sd *) gspca_dev;
1748
1741 command_pause(gspca_dev); 1749 command_pause(gspca_dev);
1742 1750
1743 /* save camera state for later open (developers guide ch 3.5.3) */ 1751 /* save camera state for later open (developers guide ch 3.5.3) */
@@ -1748,6 +1756,17 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
1748 1756
1749 /* Update the camera status */ 1757 /* Update the camera status */
1750 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0); 1758 do_command(gspca_dev, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);
1759
1760#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1761 /* If the last button state is pressed, release it now! */
1762 if (sd->params.qx3.button) {
1763 /* The camera latch will hold the pressed state until we reset
1764 the latch, so we do not reset sd->params.qx3.button now, to
1765 avoid a false keypress being reported the next sd_start */
1766 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1767 input_sync(gspca_dev->input_dev);
1768 }
1769#endif
1751} 1770}
1752 1771
1753/* this function is called at probe and resume time */ 1772/* this function is called at probe and resume time */
@@ -1852,8 +1871,7 @@ static void sd_dq_callback(struct gspca_dev *gspca_dev)
1852 1871
1853 /* Update our knowledge of the camera state */ 1872 /* Update our knowledge of the camera state */
1854 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0); 1873 do_command(gspca_dev, CPIA_COMMAND_GetExposure, 0, 0, 0, 0);
1855 if (sd->params.qx3.qx3_detected) 1874 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1856 do_command(gspca_dev, CPIA_COMMAND_ReadMCPorts, 0, 0, 0, 0);
1857} 1875}
1858 1876
1859static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val) 1877static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
@@ -2085,6 +2103,9 @@ static const struct sd_desc sd_desc = {
2085 .dq_callback = sd_dq_callback, 2103 .dq_callback = sd_dq_callback,
2086 .pkt_scan = sd_pkt_scan, 2104 .pkt_scan = sd_pkt_scan,
2087 .querymenu = sd_querymenu, 2105 .querymenu = sd_querymenu,
2106#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2107 .other_input = 1,
2108#endif
2088}; 2109};
2089 2110
2090/* -- module initialisation -- */ 2111/* -- module initialisation -- */
diff --git a/drivers/media/video/gspca/gspca.c b/drivers/media/video/gspca/gspca.c
index f21f2a258ae0..9c6a643caf01 100644
--- a/drivers/media/video/gspca/gspca.c
+++ b/drivers/media/video/gspca/gspca.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Main USB camera driver 2 * Main USB camera driver
3 * 3 *
4 * Copyright (C) 2008-2010 Jean-François Moine <http://moinejf.free.fr> 4 * Copyright (C) 2008-2011 Jean-François Moine <http://moinejf.free.fr>
5 * 5 *
6 * Camera button input handling by Márton Németh 6 * Camera button input handling by Márton Németh
7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu> 7 * Copyright (C) 2009-2010 Márton Németh <nm127@freemail.hu>
@@ -414,7 +414,6 @@ resubmit:
414 * - 0 or many INTER_PACKETs 414 * - 0 or many INTER_PACKETs
415 * - one LAST_PACKET 415 * - one LAST_PACKET
416 * DISCARD_PACKET invalidates the whole frame. 416 * DISCARD_PACKET invalidates the whole frame.
417 * On LAST_PACKET, a new frame is returned.
418 */ 417 */
419void gspca_frame_add(struct gspca_dev *gspca_dev, 418void gspca_frame_add(struct gspca_dev *gspca_dev,
420 enum gspca_packet_type packet_type, 419 enum gspca_packet_type packet_type,
@@ -631,7 +630,8 @@ static struct usb_host_endpoint *alt_xfer(struct usb_host_interface *alt,
631 ep = &alt->endpoint[i]; 630 ep = &alt->endpoint[i];
632 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; 631 attr = ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
633 if (attr == xfer 632 if (attr == xfer
634 && ep->desc.wMaxPacketSize != 0) 633 && ep->desc.wMaxPacketSize != 0
634 && usb_endpoint_dir_in(&ep->desc))
635 return ep; 635 return ep;
636 } 636 }
637 return NULL; 637 return NULL;
@@ -1525,10 +1525,12 @@ static int vidioc_reqbufs(struct file *file, void *priv,
1525 gspca_dev->usb_err = 0; 1525 gspca_dev->usb_err = 0;
1526 gspca_stream_off(gspca_dev); 1526 gspca_stream_off(gspca_dev);
1527 mutex_unlock(&gspca_dev->usb_lock); 1527 mutex_unlock(&gspca_dev->usb_lock);
1528
1529 /* Don't restart the stream when switching from read
1530 * to mmap mode */
1531 if (gspca_dev->memory == GSPCA_MEMORY_READ)
1532 streaming = 0;
1528 } 1533 }
1529 /* Don't restart the stream when switching from read to mmap mode */
1530 if (gspca_dev->memory == GSPCA_MEMORY_READ)
1531 streaming = 0;
1532 1534
1533 /* free the previous allocated buffers, if any */ 1535 /* free the previous allocated buffers, if any */
1534 if (gspca_dev->nframes != 0) 1536 if (gspca_dev->nframes != 0)
@@ -2152,7 +2154,7 @@ static const struct v4l2_ioctl_ops dev_ioctl_ops = {
2152 .vidioc_g_chip_ident = vidioc_g_chip_ident, 2154 .vidioc_g_chip_ident = vidioc_g_chip_ident,
2153}; 2155};
2154 2156
2155static struct video_device gspca_template = { 2157static const struct video_device gspca_template = {
2156 .name = "gspca main driver", 2158 .name = "gspca main driver",
2157 .fops = &dev_fops, 2159 .fops = &dev_fops,
2158 .ioctl_ops = &dev_ioctl_ops, 2160 .ioctl_ops = &dev_ioctl_ops,
diff --git a/drivers/media/video/gspca/jeilinj.c b/drivers/media/video/gspca/jeilinj.c
index 06b777f5379e..36dae38b1e38 100644
--- a/drivers/media/video/gspca/jeilinj.c
+++ b/drivers/media/video/gspca/jeilinj.c
@@ -183,7 +183,6 @@ static void jlj_dostream(struct work_struct *work)
183 struct sd *dev = container_of(work, struct sd, work_struct); 183 struct sd *dev = container_of(work, struct sd, work_struct);
184 struct gspca_dev *gspca_dev = &dev->gspca_dev; 184 struct gspca_dev *gspca_dev = &dev->gspca_dev;
185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */ 185 int blocks_left; /* 0x200-sized blocks remaining in current frame. */
186 int size_in_blocks;
187 int act_len; 186 int act_len;
188 int packet_type; 187 int packet_type;
189 int ret; 188 int ret;
@@ -209,7 +208,6 @@ static void jlj_dostream(struct work_struct *work)
209 act_len, JEILINJ_MAX_TRANSFER); 208 act_len, JEILINJ_MAX_TRANSFER);
210 if (ret < 0 || act_len < FRAME_HEADER_LEN) 209 if (ret < 0 || act_len < FRAME_HEADER_LEN)
211 goto quit_stream; 210 goto quit_stream;
212 size_in_blocks = buffer[0x0a];
213 blocks_left = buffer[0x0a] - 1; 211 blocks_left = buffer[0x0a] - 1;
214 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left); 212 PDEBUG(D_STREAM, "blocks_left = 0x%x", blocks_left);
215 213
diff --git a/drivers/media/video/gspca/nw80x.c b/drivers/media/video/gspca/nw80x.c
new file mode 100644
index 000000000000..8e754fd4dc5e
--- /dev/null
+++ b/drivers/media/video/gspca/nw80x.c
@@ -0,0 +1,2145 @@
1/*
2 * DivIO nw80x subdriver
3 *
4 * Copyright (C) 2011 Jean-François Moine (http://moinejf.free.fr)
5 * Copyright (C) 2003 Sylvain Munaut <tnt@246tNt.com>
6 * Kjell Claesson <keyson@users.sourceforge.net>
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 * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#define MODULE_NAME "nw80x"
24
25#include "gspca.h"
26
27MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
28MODULE_DESCRIPTION("NW80x USB Camera Driver");
29MODULE_LICENSE("GPL");
30
31static int webcam;
32
33/* controls */
34enum e_ctrl {
35 GAIN,
36 EXPOSURE,
37 AUTOGAIN,
38 NCTRLS /* number of controls */
39};
40
41#define AUTOGAIN_DEF 1
42
43/* specific webcam descriptor */
44struct sd {
45 struct gspca_dev gspca_dev; /* !! must be the first item */
46
47 struct gspca_ctrl ctrls[NCTRLS];
48
49 u32 ae_res;
50 s8 ag_cnt;
51#define AG_CNT_START 13
52 u8 exp_too_low_cnt;
53 u8 exp_too_high_cnt;
54
55 u8 bridge;
56 u8 webcam;
57};
58
59enum bridges {
60 BRIDGE_NW800, /* and et31x110 */
61 BRIDGE_NW801,
62 BRIDGE_NW802,
63};
64enum webcams {
65 Generic800,
66 SpaceCam, /* Trust 120 SpaceCam */
67 SpaceCam2, /* other Trust 120 SpaceCam */
68 Cvideopro, /* Conceptronic Video Pro */
69 Dlink350c,
70 DS3303u,
71 Kr651us,
72 Kritter,
73 Mustek300,
74 Proscope,
75 Twinkle,
76 DvcV6,
77 P35u,
78 Generic802,
79 NWEBCAMS /* number of webcams */
80};
81
82static const u8 webcam_chip[NWEBCAMS] = {
83 [Generic800] = BRIDGE_NW800, /* 06a5:0000
84 * Typhoon Webcam 100 USB */
85
86 [SpaceCam] = BRIDGE_NW800, /* 06a5:d800
87 * Trust SpaceCam120 or SpaceCam100 PORTABLE */
88
89 [SpaceCam2] = BRIDGE_NW800, /* 06a5:d800 - pas106
90 * other Trust SpaceCam120 or SpaceCam100 PORTABLE */
91
92 [Cvideopro] = BRIDGE_NW802, /* 06a5:d001
93 * Conceptronic Video Pro 'CVIDEOPRO USB Webcam CCD' */
94
95 [Dlink350c] = BRIDGE_NW802, /* 06a5:d001
96 * D-Link NetQam Pro 250plus */
97
98 [DS3303u] = BRIDGE_NW801, /* 06a5:d001
99 * Plustek Opticam 500U or ProLink DS3303u */
100
101 [Kr651us] = BRIDGE_NW802, /* 06a5:d001
102 * Panasonic GP-KR651US */
103
104 [Kritter] = BRIDGE_NW802, /* 06a5:d001
105 * iRez Kritter cam */
106
107 [Mustek300] = BRIDGE_NW802, /* 055f:d001
108 * Mustek Wcam 300 mini */
109
110 [Proscope] = BRIDGE_NW802, /* 06a5:d001
111 * Scalar USB Microscope (ProScope) */
112
113 [Twinkle] = BRIDGE_NW800, /* 06a5:d800 - hv7121b? (seems pas106)
114 * Divio Chicony TwinkleCam
115 * DSB-C110 */
116
117 [DvcV6] = BRIDGE_NW802, /* 0502:d001
118 * DVC V6 */
119
120 [P35u] = BRIDGE_NW801, /* 052b:d001, 06a5:d001 and 06be:d001
121 * EZCam Pro p35u */
122
123 [Generic802] = BRIDGE_NW802,
124};
125/*
126 * other webcams:
127 * - nw801 046d:d001
128 * Logitech QuickCam Pro (dark focus ring)
129 * - nw801 0728:d001
130 * AVerMedia Camguard
131 * - nw??? 06a5:d001
132 * D-Link NetQam Pro 250plus
133 * - nw800 065a:d800
134 * Showcam NGS webcam
135 * - nw??? ????:????
136 * Sceptre svc300
137 */
138
139/*
140 * registers
141 * nw800/et31x110 nw801 nw802
142 * 0000..009e 0000..00a1 0000..009e
143 * 0200..0211 id id
144 * 0300..0302 id id
145 * 0400..0406 (inex) 0400..0406
146 * 0500..0505 0500..0506 (inex)
147 * 0600..061a 0600..0601 0600..0601
148 * 0800..0814 id id
149 * 1000..109c 1000..10a1 1000..109a
150 */
151
152/* resolutions
153 * nw800: 320x240, 352x288
154 * nw801/802: 320x240, 640x480
155 */
156static const struct v4l2_pix_format cif_mode[] = {
157 {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
158 .bytesperline = 320,
159 .sizeimage = 320 * 240 * 4 / 8,
160 .colorspace = V4L2_COLORSPACE_JPEG},
161 {352, 288, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
162 .bytesperline = 352,
163 .sizeimage = 352 * 288 * 4 / 8,
164 .colorspace = V4L2_COLORSPACE_JPEG}
165};
166static const struct v4l2_pix_format vga_mode[] = {
167 {320, 240, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
168 .bytesperline = 320,
169 .sizeimage = 320 * 240 * 4 / 8,
170 .colorspace = V4L2_COLORSPACE_JPEG},
171 {640, 480, V4L2_PIX_FMT_JPGL, V4L2_FIELD_NONE,
172 .bytesperline = 640,
173 .sizeimage = 640 * 480 * 3 / 8,
174 .colorspace = V4L2_COLORSPACE_JPEG},
175};
176
177/*
178 * The sequences below contain:
179 * - 1st and 2nd bytes: either
180 * - register number (BE)
181 * - I2C0 + i2c address
182 * - 3rd byte: data length (=0 for end of sequence)
183 * - n bytes: data
184 */
185#define I2C0 0xff
186
187static const u8 nw800_init[] = {
188 0x04, 0x05, 0x01, 0x61,
189 0x04, 0x04, 0x01, 0x01,
190 0x04, 0x06, 0x01, 0x04,
191 0x04, 0x04, 0x03, 0x00, 0x00, 0x00,
192 0x05, 0x05, 0x01, 0x00,
193 0, 0, 0
194};
195static const u8 nw800_start[] = {
196 0x04, 0x06, 0x01, 0xc0,
197 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
198 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
199 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
200 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
201 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
202 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
203 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
204 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
205 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
206 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
207 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
208 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
209 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
210 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
211 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
212 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
213 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
214 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
215 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
216 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
217 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
218 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
219 0x40, 0x20,
220 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
221 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0,
222 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20,
223 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
224 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
225 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
226 0x00, 0x00, 0x00,
227 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
228 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
229 0x00, 0x00, 0x00, 0x00, 0x00,
230 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
231 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
232 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
234 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
235 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
236 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
237 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
238 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
239 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
240 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
241 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
242 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
243 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
244 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
245 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
246 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
247 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
248 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
249 0x01, 0x60, 0x01, 0x00, 0x00,
250
251 0x04, 0x04, 0x01, 0xff,
252 0x04, 0x06, 0x01, 0xc4,
253
254 0x04, 0x06, 0x01, 0xc0,
255 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
256 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
257 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
258 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
259 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
260 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
261 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
262 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
263 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
264 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
265 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
266 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
267 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
268 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
269 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
270 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
271 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
272 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
273 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
274 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
275 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
276 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
277 0x40, 0x20,
278 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
279 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0xc0,
280 0x05, 0x00, 0x06, 0xe8, 0x00, 0x00, 0x00, 0x20, 0x20,
281 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
284 0x00, 0x00, 0x00,
285 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
286 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
287 0x00, 0x00, 0x00, 0x00, 0x00,
288 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
289 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
290 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
292 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
293 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
294 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
295 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
296 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
297 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
298 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
299 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
300 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
301 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
302 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
303 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
304 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
305 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
306 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
307 0x01, 0x60, 0x01, 0x00, 0x00,
308
309 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
310 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
311 0x40,
312 0x00, 0x80, 0x01, 0xa0,
313 0x10, 0x1a, 0x01, 0x00,
314 0x00, 0x91, 0x02, 0x6c, 0x01,
315 0x00, 0x03, 0x02, 0xc8, 0x01,
316 0x10, 0x1a, 0x01, 0x00,
317 0x10, 0x00, 0x01, 0x83,
318 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
319 0x20, 0x01, 0x60, 0x01,
320 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
321 0x10, 0x1b, 0x02, 0x69, 0x00,
322 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
323 0x05, 0x02, 0x01, 0x02,
324 0x06, 0x00, 0x02, 0x04, 0xd9,
325 0x05, 0x05, 0x01, 0x20,
326 0x05, 0x05, 0x01, 0x21,
327 0x10, 0x0e, 0x01, 0x08,
328 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83,
329 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0,
330 0xea,
331 0x10, 0x03, 0x01, 0x00,
332 0x10, 0x0f, 0x02, 0x13, 0x13,
333 0x10, 0x03, 0x01, 0x14,
334 0x10, 0x41, 0x11, 0x00, 0x08, 0x21, 0x3d, 0x52, 0x63, 0x75, 0x83,
335 0x91, 0x9e, 0xaa, 0xb6, 0xc1, 0xcc, 0xd6, 0xe0,
336 0xea,
337 0x10, 0x0b, 0x01, 0x14,
338 0x10, 0x0d, 0x01, 0x20,
339 0x10, 0x0c, 0x01, 0x34,
340 0x04, 0x06, 0x01, 0xc3,
341 0x04, 0x04, 0x01, 0x00,
342 0x05, 0x02, 0x01, 0x02,
343 0x06, 0x00, 0x02, 0x00, 0x48,
344 0x05, 0x05, 0x01, 0x20,
345 0x05, 0x05, 0x01, 0x21,
346 0, 0, 0
347};
348
349/* 06a5:d001 - nw801 - Panasonic
350 * P35u */
351static const u8 nw801_start_1[] = {
352 0x05, 0x06, 0x01, 0x04,
353 0x00, 0x00, 0x40, 0x0e, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e,
354 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
355 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
356 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
357 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
358 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
359 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
360 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
361 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
362 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
363 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
364 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
365 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
366 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
367 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
368 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
369 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00,
370 0x00, 0x00, 0x00, 0x00, 0x69, 0xa8, 0x1f, 0x00,
371 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00,
372 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00,
373 0x36, 0x00,
374 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
375 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
376 0x40, 0x20,
377 0x03, 0x00, 0x03, 0x00, 0x00, 0x00,
378 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
379 0x06, 0x00, 0x02, 0x09, 0x99,
380 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
382 0x00, 0x00, 0x00, 0x00, 0x00,
383 0x10, 0x00, 0x40, 0x22, 0x02, 0x80, 0x00, 0x1e, 0x00, 0x00, 0x00,
384 0x00, 0x00, 0x00, 0x0a, 0x15, 0x08, 0x08, 0x0a,
385 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386 0x00, 0x01, 0x35, 0xfd, 0x07, 0x3d, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x14, 0x02,
388 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
389 0x40, 0x00, 0x00, 0x00, 0x40, 0x20, 0x10, 0x06,
390 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7,
391 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80,
392 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99, 0xa4,
393 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc, 0xcf,
394 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64,
395 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2,
396 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
397 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
398 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
399 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
400 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x82, 0x02,
402 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01,
403 0xf0, 0x00,
404 0, 0, 0,
405};
406static const u8 nw801_start_qvga[] = {
407 0x02, 0x00, 0x10, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
408 0x00, 0x78, 0x18, 0x0b, 0x06, 0xa2, 0x86, 0x78,
409 0x02, 0x0f, 0x01, 0x6b,
410 0x10, 0x1a, 0x01, 0x15,
411 0x00, 0x00, 0x01, 0x1e,
412 0x10, 0x00, 0x01, 0x2f,
413 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
414 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00,
415 /* AE window */
416 0, 0, 0,
417};
418static const u8 nw801_start_vga[] = {
419 0x02, 0x00, 0x10, 0x78, 0xa0, 0x97, 0x78, 0xa0, 0x00, 0x00, 0x00,
420 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xf0,
421 0x02, 0x0f, 0x01, 0xd5,
422 0x10, 0x1a, 0x01, 0x15,
423 0x00, 0x00, 0x01, 0x0e,
424 0x10, 0x00, 0x01, 0x22,
425 0x10, 0x8c, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
426 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01,
427 0, 0, 0,
428};
429static const u8 nw801_start_2[] = {
430 0x10, 0x04, 0x01, 0x1a,
431 0x10, 0x19, 0x01, 0x09, /* clock */
432 0x10, 0x24, 0x06, 0xc0, 0x00, 0x3f, 0x02, 0x00, 0x01,
433 /* .. gain .. */
434 0x00, 0x03, 0x02, 0x92, 0x03,
435 0x00, 0x1d, 0x04, 0xf2, 0x00, 0x24, 0x07,
436 0x00, 0x7b, 0x01, 0xcf,
437 0x10, 0x94, 0x01, 0x07,
438 0x05, 0x05, 0x01, 0x01,
439 0x05, 0x04, 0x01, 0x01,
440 0x10, 0x0e, 0x01, 0x08,
441 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8,
442 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0,
443 0xf0,
444 0x10, 0x03, 0x01, 0x00,
445 0x10, 0x0f, 0x02, 0x0c, 0x0c,
446 0x10, 0x03, 0x01, 0x08,
447 0x10, 0x48, 0x11, 0x00, 0x37, 0x55, 0x6b, 0x7d, 0x8d, 0x9b, 0xa8,
448 0xb4, 0xbf, 0xca, 0xd4, 0xdd, 0xe6, 0xef, 0xf0,
449 0xf0,
450 0x10, 0x0b, 0x01, 0x0b,
451 0x10, 0x0d, 0x01, 0x0b,
452 0x10, 0x0c, 0x01, 0x1f,
453 0x05, 0x06, 0x01, 0x03,
454 0, 0, 0
455};
456
457/* nw802 (sharp IR3Y38M?) */
458static const u8 nw802_start[] = {
459 0x04, 0x06, 0x01, 0x04,
460 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x4d,
461 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
462 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
463 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
464 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
465 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
466 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
467 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
468 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
469 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
470 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
471 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
472 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
473 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
474 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
475 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
476 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
477 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
478 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
479 0x00, 0x10, 0x06, 0x08, 0x00, 0x18, 0x00,
480 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
481 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
482 0x40, 0x20,
483 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
484 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
485 0x06, 0x00, 0x02, 0x09, 0x99,
486 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
487 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
488 0x00, 0x00, 0x00, 0x00, 0x00,
489 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x1d, 0x00, 0x00, 0x00,
490 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
491 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
492 0x00, 0x49, 0x13, 0xff, 0x01, 0xc0, 0x00, 0x14,
493 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
494 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
495 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
496 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
497 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
498 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
499 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
500 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
501 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
502 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
503 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
504 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
505 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
506 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x05, 0x82,
507 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
508 0x01, 0xf0, 0x00,
509 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
510 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
511 0x40,
512 0x10, 0x1a, 0x01, 0x00,
513 0x10, 0x00, 0x01, 0xad,
514 0x00, 0x00, 0x01, 0x08,
515 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
516 0x10, 0x1b, 0x02, 0x00, 0x00,
517 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00,
518 0x10, 0x1d, 0x08, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0, 0x00, 0xa0,
519 0x10, 0x0e, 0x01, 0x27,
520 0x10, 0x41, 0x11, 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b,
521 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2,
522 0xd8,
523 0x10, 0x03, 0x01, 0x00,
524 0x10, 0x0f, 0x02, 0x14, 0x14,
525 0x10, 0x03, 0x01, 0x0c,
526 0x10, 0x41, 0x11, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64, 0x74,
527 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2, 0xf1,
528 0xff,
529/* 0x00, 0x0e, 0x35, 0x4f, 0x62, 0x71, 0x7f, 0x8b,
530 * 0x96, 0xa0, 0xa9, 0xb2, 0xbb, 0xc3, 0xca, 0xd2,
531 * 0xd8, */
532 0x10, 0x0b, 0x01, 0x10,
533 0x10, 0x0d, 0x01, 0x11,
534 0x10, 0x0c, 0x01, 0x1c,
535 0x04, 0x06, 0x01, 0x03,
536 0x04, 0x04, 0x01, 0x00,
537 0, 0, 0
538};
539/* et31x110 - Trust 120 SpaceCam */
540static const u8 spacecam_init[] = {
541 0x04, 0x05, 0x01, 0x01,
542 0x04, 0x04, 0x01, 0x01,
543 0x04, 0x06, 0x01, 0x04,
544 0x04, 0x04, 0x03, 0x00, 0x00, 0x00,
545 0x05, 0x05, 0x01, 0x00,
546 0, 0, 0
547};
548static const u8 spacecam_start[] = {
549 0x04, 0x06, 0x01, 0x44,
550 0x00, 0x00, 0x40, 0x10, 0x43, 0x00, 0xb4, 0x01, 0x10, 0x00, 0x4f,
551 0xef, 0x0e, 0x00, 0x74, 0x01, 0x01, 0x00, 0x19,
552 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
553 0x00, 0x01, 0x00, 0x19, 0x00, 0x3e, 0x00, 0x24,
554 0x03, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
555 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
556 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
557 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
558 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
559 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
560 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
561 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
562 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
563 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
564 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
565 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
566 0x00, 0x80, 0x1f, 0xa0, 0x48, 0xc3, 0x02, 0x88, 0x0c, 0x68, 0x00,
567 0x00, 0x00, 0x00, 0x00, 0xa8, 0x06, 0x00, 0x08,
568 0x00, 0x32, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
569 0x00, 0x4b, 0x00, 0x7c, 0x00, 0x80, 0x00,
570 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
571 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
572 0x40, 0x20,
573 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
574 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00,
575 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
576 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
577 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
578 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
579 0x00, 0x00, 0x00,
580 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
582 0x00, 0x00, 0x00, 0x00, 0x00,
583 0x10, 0x00, 0x40, 0x83, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00,
584 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
585 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
586 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
587 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
588 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
589 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
590 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
591 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
592 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
593 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
594 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
595 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
596 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
597 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
598 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
599 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
600 0x00, 0x00, 0x00, 0x00, 0x00, 0x2d, 0x00, 0x62,
601 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
602 0x01, 0x60, 0x01, 0x00, 0x00,
603 0x04, 0x06, 0x01, 0xc0,
604 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
605 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
606 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
607 0x40,
608 0x00, 0x80, 0x01, 0xa0,
609 0x10, 0x1a, 0x01, 0x00,
610 0x00, 0x91, 0x02, 0x32, 0x01,
611 0x00, 0x03, 0x02, 0x08, 0x02,
612 0x10, 0x00, 0x01, 0x83,
613 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
614 0x20, 0x01, 0x60, 0x01,
615 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
616 0x10, 0x0e, 0x01, 0x08,
617 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9,
618 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
619 0xf9,
620 0x10, 0x03, 0x01, 0x00,
621 0x10, 0x0f, 0x02, 0x13, 0x13,
622 0x10, 0x03, 0x01, 0x06,
623 0x10, 0x41, 0x11, 0x00, 0x64, 0x99, 0xc0, 0xe2, 0xf9, 0xf9, 0xf9,
624 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
625 0xf9,
626 0x10, 0x0b, 0x01, 0x08,
627 0x10, 0x0d, 0x01, 0x10,
628 0x10, 0x0c, 0x01, 0x1f,
629 0x04, 0x06, 0x01, 0xc3,
630 0x04, 0x05, 0x01, 0x40,
631 0x04, 0x04, 0x01, 0x40,
632 0, 0, 0
633};
634/* et31x110 - pas106 - other Trust SpaceCam120 */
635static const u8 spacecam2_start[] = {
636 0x04, 0x06, 0x01, 0x44,
637 0x04, 0x06, 0x01, 0x00,
638 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f,
639 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19,
640 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
641 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc,
642 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
643 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
644 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
645 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
646 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
647 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
648 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
649 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
650 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
651 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
652 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
653 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
654 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00,
655 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03,
656 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
657 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
658 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
659 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
660 0x40, 0x20,
661 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
662 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00,
663 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
664 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
665 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
666 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
667 0x00, 0x00, 0x00,
668 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
669 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
670 0x00, 0x00, 0x00, 0x00, 0x00,
671 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x13, 0x00, 0x00, 0x00,
672 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
673 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
674 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
675 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
676 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
677 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
678 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
679 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
680 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
681 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
682 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
683 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
684 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
685 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
686 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
687 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
688 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62,
689 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
690 0x01, 0x60, 0x01, 0x00, 0x00,
691 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
692 0x04, 0x04, 0x01, 0x40,
693 0x04, 0x04, 0x01, 0x00,
694 I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x05,
695 0x00, 0x00, 0x05, 0x05,
696 I2C0, 0x40, 0x02, 0x11, 0x06,
697 I2C0, 0x40, 0x02, 0x14, 0x00,
698 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
699 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
700 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
701 0x40,
702 I2C0, 0x40, 0x02, 0x02, 0x0c, /* pixel clock */
703 I2C0, 0x40, 0x02, 0x0f, 0x00,
704 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
705 0x10, 0x00, 0x01, 0x01,
706 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
707 0x20, 0x01, 0x60, 0x01,
708 I2C0, 0x40, 0x02, 0x05, 0x0f, /* exposure */
709 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
710 I2C0, 0x40, 0x07, 0x09, 0x0b, 0x0f, 0x05, 0x05, 0x0f, 0x00,
711 /* gains */
712 I2C0, 0x40, 0x03, 0x12, 0x04, 0x01,
713 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
714 0x10, 0x0e, 0x01, 0x08,
715 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
716 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
717 0xf9,
718 0x10, 0x03, 0x01, 0x00,
719 0x10, 0x0f, 0x02, 0x13, 0x13,
720 0x10, 0x03, 0x01, 0x06,
721 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
722 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
723 0xf9,
724 0x10, 0x0b, 0x01, 0x11,
725 0x10, 0x0d, 0x01, 0x10,
726 0x10, 0x0c, 0x01, 0x14,
727 0x04, 0x06, 0x01, 0x03,
728 0x04, 0x05, 0x01, 0x61,
729 0x04, 0x04, 0x01, 0x00,
730 0, 0, 0
731};
732
733/* nw802 - Conceptronic Video Pro */
734static const u8 cvideopro_start[] = {
735 0x04, 0x06, 0x01, 0x04,
736 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c,
737 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
738 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
739 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
740 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
741 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
742 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
743 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
744 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
745 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
746 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
747 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
748 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
749 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
750 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
751 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
752 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
753 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
754 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
755 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
756 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
757 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
758 0x40, 0x20,
759 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
760 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
761 0x06, 0x00, 0x02, 0x09, 0x99,
762 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
763 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
764 0x00, 0x00, 0x00, 0x00, 0x00,
765 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
766 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
767 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
769 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
770 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
771 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
772 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
773 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
774 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
775 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
776 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
777 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
778 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
779 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
780 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
781 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
782 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
783 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
784 0x01, 0xf0, 0x00,
785 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00,
786 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
787 0x40,
788 0x10, 0x1a, 0x01, 0x03,
789 0x10, 0x00, 0x01, 0xac,
790 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
791 0x10, 0x1b, 0x02, 0x3b, 0x01,
792 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
793 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
794 0x10, 0x1d, 0x02, 0x40, 0x06,
795 0x10, 0x0e, 0x01, 0x08,
796 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0,
797 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc,
798 0xdc,
799 0x10, 0x03, 0x01, 0x00,
800 0x10, 0x0f, 0x02, 0x12, 0x12,
801 0x10, 0x03, 0x01, 0x0c,
802 0x10, 0x41, 0x11, 0x00, 0x0f, 0x46, 0x62, 0x76, 0x86, 0x94, 0xa0,
803 0xab, 0xb6, 0xbf, 0xc8, 0xcf, 0xd7, 0xdc, 0xdc,
804 0xdc,
805 0x10, 0x0b, 0x01, 0x09,
806 0x10, 0x0d, 0x01, 0x10,
807 0x10, 0x0c, 0x01, 0x2f,
808 0x04, 0x06, 0x01, 0x03,
809 0x04, 0x04, 0x01, 0x00,
810 0, 0, 0
811};
812
813/* nw802 - D-link dru-350c cam */
814static const u8 dlink_start[] = {
815 0x04, 0x06, 0x01, 0x04,
816 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d,
817 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
818 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
819 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
820 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
821 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
822 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
823 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
824 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
825 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
826 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
827 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
828 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
829 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
830 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
831 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
832 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
833 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
834 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
835 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00,
836 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
837 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
838 0x40, 0x20,
839 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
840 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
841 0x06, 0x00, 0x02, 0x09, 0x99,
842 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
844 0x00, 0x00, 0x00, 0x00, 0x00,
845 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
846 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
847 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
848 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14,
849 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
850 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
851 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
852 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
853 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
854 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
855 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
856 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
857 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
858 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
859 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
860 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
861 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
862 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x01, 0x82,
863 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
864 0x01, 0xf0, 0x00,
865 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
866 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
867 0x40,
868 0x10, 0x1a, 0x01, 0x00,
869 0x10, 0x00, 0x01, 0xad,
870 0x00, 0x00, 0x01, 0x08,
871 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
872 0x10, 0x1b, 0x02, 0x00, 0x00,
873 0x10, 0x11, 0x08, 0x51, 0x00, 0xf0, 0x00, 0x3d, 0x00, 0xb4, 0x00,
874 0x10, 0x1d, 0x08, 0x40, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
875 0x10, 0x0e, 0x01, 0x20,
876 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f,
877 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf,
878 0xea,
879 0x10, 0x03, 0x01, 0x00,
880 0x10, 0x0f, 0x02, 0x11, 0x11,
881 0x10, 0x03, 0x01, 0x10,
882 0x10, 0x41, 0x11, 0x00, 0x07, 0x1e, 0x38, 0x4d, 0x60, 0x70, 0x7f,
883 0x8e, 0x9b, 0xa8, 0xb4, 0xbf, 0xca, 0xd5, 0xdf,
884 0xea,
885 0x10, 0x0b, 0x01, 0x19,
886 0x10, 0x0d, 0x01, 0x10,
887 0x10, 0x0c, 0x01, 0x1e,
888 0x04, 0x06, 0x01, 0x03,
889 0x04, 0x04, 0x01, 0x00,
890 0, 0, 0
891};
892
893/* 06a5:d001 - nw801 - Sony
894 * Plustek Opticam 500U or ProLink DS3303u (Hitachi HD49322BF) */
895/*fixme: 320x240 only*/
896static const u8 ds3303_start[] = {
897 0x05, 0x06, 0x01, 0x04,
898 0x00, 0x00, 0x40, 0x16, 0x00, 0x00, 0xf9, 0x02, 0x11, 0x00, 0x0e,
899 0x01, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
900 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
901 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
902 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
903 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
904 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
905 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
906 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
907 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
908 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
909 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
910 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
911 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
912 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
913 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
914 0x00, 0x80, 0x22, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x08, 0x00,
915 0x00, 0x00, 0x00, 0x00, 0xa9, 0xa8, 0x1f, 0x00,
916 0x0d, 0x02, 0x07, 0x00, 0x01, 0x00, 0x19, 0x00,
917 0xf2, 0x00, 0x18, 0x06, 0x10, 0x06, 0x10, 0x00,
918 0x36, 0x00,
919 0x02, 0x00, 0x12, 0x03, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
920 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0x50,
921 0x40, 0x20,
922 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
923 0x05, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
924 0x06, 0x00, 0x02, 0x09, 0x99,
925 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
926 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
927 0x00, 0x00, 0x00, 0x00, 0x00,
928 0x10, 0x00, 0x40, 0x2f, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
929 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a,
930 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4,
931 0x00, 0x01, 0x15, 0xfd, 0x07, 0x3d, 0x00, 0x00,
932 0x00, 0x00, 0x00, 0x00, 0x8c, 0x04, 0x01, 0x20,
933 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00, 0x00,
934 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x03,
935 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06, 0xf7,
936 0x10, 0x40, 0x40, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80, 0x80,
937 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f, 0x88,
938 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4, 0xcb,
939 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54, 0x64,
940 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2, 0xe2,
941 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
942 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
943 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
944 0x10, 0x80, 0x22, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
945 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f, 0x01,
946 0x00, 0x00, 0xef, 0x00, 0x02, 0x0a, 0x82, 0x02,
947 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40, 0x01,
948 0xf0, 0x00,
949
950 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
951 0x00, 0x78, 0x3f, 0x3f, 0x00, 0xf2, 0x8f, 0x81,
952 0x40,
953 0x10, 0x1a, 0x01, 0x15,
954 0x10, 0x00, 0x01, 0x2f,
955 0x10, 0x8c, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
956 0x10, 0x1b, 0x02, 0x00, 0x00,
957 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
958 0x10, 0x26, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
959 0x10, 0x24, 0x02, 0x40, 0x06,
960 0x10, 0x0e, 0x01, 0x08,
961 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6,
962 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
963 0xf9,
964 0x10, 0x03, 0x01, 0x00,
965 0x10, 0x0f, 0x02, 0x16, 0x16,
966 0x10, 0x03, 0x01, 0x0c,
967 0x10, 0x48, 0x11, 0x00, 0x15, 0x40, 0x67, 0x84, 0x9d, 0xb2, 0xc6,
968 0xd6, 0xe7, 0xf6, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
969 0xf9,
970 0x10, 0x0b, 0x01, 0x26,
971 0x10, 0x0d, 0x01, 0x10,
972 0x10, 0x0c, 0x01, 0x1c,
973 0x05, 0x06, 0x01, 0x03,
974 0x05, 0x04, 0x01, 0x00,
975 0, 0, 0
976};
977
978/* 06a5:d001 - nw802 - Panasonic
979 * GP-KR651US (Philips TDA8786) */
980static const u8 kr651_start_1[] = {
981 0x04, 0x06, 0x01, 0x04,
982 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x48,
983 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
984 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
985 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
986 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
987 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
988 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
989 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
990 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
991 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
992 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
993 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
994 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
995 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
996 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
997 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
998 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
999 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1000 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
1001 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
1002 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1003 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1004 0x40, 0x20,
1005 0x03, 0x00, 0x03, 0x02, 0x00, 0x00,
1006 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
1007 0x06, 0x00, 0x02, 0x09, 0x99,
1008 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1009 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1010 0x00, 0x00, 0x00, 0x00, 0x00,
1011 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1012 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1013 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1014 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
1015 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1016 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1017 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1018 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1019 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1020 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1021 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1022 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1023 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1024 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1025 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1026 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1027 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1028 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
1029 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1030 0x01, 0xf0, 0x00,
1031 0, 0, 0
1032};
1033static const u8 kr651_start_qvga[] = {
1034 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
1035 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
1036 0x40,
1037 0x10, 0x1a, 0x01, 0x03,
1038 0x10, 0x00, 0x01, 0xac,
1039 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1040 0x10, 0x1b, 0x02, 0x00, 0x00,
1041 0x10, 0x11, 0x08, 0x29, 0x00, 0x18, 0x01, 0x1f, 0x00, 0xd2, 0x00,
1042 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
1043 0x10, 0x1d, 0x02, 0x28, 0x01,
1044 0, 0, 0
1045};
1046static const u8 kr651_start_vga[] = {
1047 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00,
1048 0x00, 0xf0, 0x30, 0x03, 0x01, 0x82, 0x82, 0x98,
1049 0x80,
1050 0x10, 0x1a, 0x01, 0x03,
1051 0x10, 0x00, 0x01, 0xa0,
1052 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
1053 0x10, 0x1b, 0x02, 0x00, 0x00,
1054 0x10, 0x11, 0x08, 0x51, 0x00, 0x30, 0x02, 0x3d, 0x00, 0xa4, 0x01,
1055 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
1056 0x10, 0x1d, 0x02, 0x68, 0x00,
1057};
1058static const u8 kr651_start_2[] = {
1059 0x10, 0x0e, 0x01, 0x08,
1060 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8,
1061 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
1062 0xdc,
1063 0x10, 0x03, 0x01, 0x00,
1064 0x10, 0x0f, 0x02, 0x0c, 0x0c,
1065 0x10, 0x03, 0x01, 0x0c,
1066 0x10, 0x41, 0x11, 0x00, 0x11, 0x3c, 0x5c, 0x74, 0x88, 0x99, 0xa8,
1067 0xb7, 0xc4, 0xd0, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
1068 0xdc,
1069 0x10, 0x0b, 0x01, 0x10,
1070 0x10, 0x0d, 0x01, 0x10,
1071 0x10, 0x0c, 0x01, 0x2d,
1072 0x04, 0x06, 0x01, 0x03,
1073 0x04, 0x04, 0x01, 0x00,
1074 0, 0, 0
1075};
1076
1077/* nw802 - iRez Kritter cam */
1078static const u8 kritter_start[] = {
1079 0x04, 0x06, 0x01, 0x06,
1080 0x00, 0x00, 0x40, 0x44, 0x96, 0x98, 0x94, 0x03, 0x18, 0x00, 0x48,
1081 0x0f, 0x1e, 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19,
1082 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1083 0x00, 0x0b, 0x00, 0x1b, 0x00, 0x0a, 0x01, 0x28,
1084 0x07, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
1085 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1086 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
1087 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1088 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
1089 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1090 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
1091 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1092 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
1093 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
1095 0x00, 0x5d, 0x00, 0x0e, 0x00, 0x7e, 0x00, 0x30,
1096 0x00, 0x80, 0x1f, 0x18, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
1097 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1098 0x00, 0x0b, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
1099 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
1100 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1101 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1102 0x40, 0x20,
1103 0x03, 0x00, 0x03, 0x02, 0x00, 0x00,
1104 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
1105 0x06, 0x00, 0x02, 0x09, 0x99,
1106 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1108 0x00, 0x00, 0x00, 0x00, 0x00,
1109 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1110 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1111 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1112 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
1113 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1114 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1115 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1116 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1117 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1118 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1119 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1120 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1121 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1122 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1123 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1124 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1125 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1126 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x82,
1127 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1128 0x01, 0xf0, 0x00,
1129 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8c, 0x3c, 0x50, 0x00, 0x00, 0x00,
1130 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
1131 0x40,
1132 0x10, 0x1a, 0x01, 0x03,
1133 0x10, 0x00, 0x01, 0xaf,
1134 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1135 0x10, 0x1b, 0x02, 0x3b, 0x01,
1136 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
1137 0x10, 0x1d, 0x06, 0xe0, 0x00, 0x0c, 0x00, 0x52, 0x00,
1138 0x10, 0x1d, 0x02, 0x00, 0x00,
1139 0x10, 0x0e, 0x01, 0x08,
1140 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86,
1141 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4,
1142 0xcb,
1143 0x10, 0x03, 0x01, 0x00,
1144 0x10, 0x0f, 0x02, 0x0d, 0x0d,
1145 0x10, 0x03, 0x01, 0x02,
1146 0x10, 0x41, 0x11, 0x00, 0x0d, 0x36, 0x4e, 0x60, 0x6f, 0x7b, 0x86,
1147 0x90, 0x98, 0xa1, 0xa9, 0xb1, 0xb7, 0xbe, 0xc4,
1148 0xcb,
1149 0x10, 0x0b, 0x01, 0x17,
1150 0x10, 0x0d, 0x01, 0x10,
1151 0x10, 0x0c, 0x01, 0x1e,
1152 0x04, 0x06, 0x01, 0x03,
1153 0x04, 0x04, 0x01, 0x00,
1154 0, 0, 0
1155};
1156
1157/* nw802 - Mustek Wcam 300 mini */
1158static const u8 mustek_start[] = {
1159 0x04, 0x06, 0x01, 0x04,
1160 0x00, 0x00, 0x40, 0x10, 0x00, 0x00, 0x92, 0x03, 0x10, 0x00, 0x4d,
1161 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
1162 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1163 0x00, 0x01, 0x00, 0x19, 0x00, 0xce, 0x00, 0xf4,
1164 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
1165 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
1166 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
1167 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
1168 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1169 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1170 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1171 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1172 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
1173 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1174 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
1175 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
1176 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x3f, 0x0f, 0x88, 0x20, 0x68, 0x00,
1177 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1178 0x00, 0x0c, 0x02, 0x01, 0x00, 0x16, 0x00, 0x94,
1179 0x00, 0x10, 0x06, 0xfc, 0x05, 0x0c, 0x06,
1180 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1181 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1182 0x40, 0x20,
1183 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1184 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
1185 0x06, 0x00, 0x02, 0x09, 0x99,
1186 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1187 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1188 0x00, 0x00, 0x00, 0x00, 0x00,
1189 0x10, 0x00, 0x40, 0xa1, 0x02, 0x80, 0x00, 0x13, 0x00, 0x00, 0x00,
1190 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1191 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1192 0x00, 0x49, 0x13, 0x00, 0x00, 0xc0, 0x00, 0x14,
1193 0x02, 0x00, 0x01, 0x00, 0x00, 0x20, 0x00, 0x00,
1194 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1195 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1196 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1197 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1198 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1199 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1200 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1201 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1202 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1203 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1204 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1205 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1206 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x01, 0x82,
1207 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1208 0x01, 0xf0, 0x00,
1209 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
1210 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
1211 0x40,
1212 0x10, 0x1a, 0x01, 0x00,
1213 0x10, 0x00, 0x01, 0xad,
1214 0x00, 0x00, 0x01, 0x08,
1215 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1216 0x10, 0x1b, 0x02, 0x00, 0x00,
1217 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1218 0x10, 0x1d, 0x08, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20,
1219 0x10, 0x0e, 0x01, 0x0f,
1220 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e,
1221 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9,
1222 0xff,
1223 0x10, 0x0f, 0x02, 0x11, 0x11,
1224 0x10, 0x03, 0x01, 0x0c,
1225 0x10, 0x41, 0x11, 0x00, 0x0f, 0x29, 0x4a, 0x64, 0x7a, 0x8c, 0x9e,
1226 0xad, 0xba, 0xc7, 0xd3, 0xde, 0xe8, 0xf1, 0xf9,
1227 0xff,
1228 0x10, 0x0b, 0x01, 0x1c,
1229 0x10, 0x0d, 0x01, 0x1a,
1230 0x10, 0x0c, 0x01, 0x34,
1231 0x04, 0x05, 0x01, 0x61,
1232 0x04, 0x04, 0x01, 0x40,
1233 0x04, 0x06, 0x01, 0x03,
1234 0, 0, 0
1235};
1236
1237/* nw802 - Scope USB Microscope M2 (ProScope) (Hitachi HD49322BF) */
1238static const u8 proscope_init[] = {
1239 0x04, 0x05, 0x01, 0x21,
1240 0x04, 0x04, 0x01, 0x01,
1241 0, 0, 0
1242};
1243static const u8 proscope_start_1[] = {
1244 0x04, 0x06, 0x01, 0x04,
1245 0x00, 0x00, 0x40, 0x10, 0x01, 0x00, 0xf9, 0x02, 0x10, 0x00, 0x04,
1246 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
1247 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1248 0x00, 0x08, 0x00, 0x17, 0x00, 0xce, 0x00, 0xf4,
1249 0x05, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
1250 0x00, 0xce, 0x00, 0xf8, 0x03, 0x3e, 0x00, 0x86,
1251 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
1252 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
1253 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0xb6,
1254 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1255 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1256 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1257 0x00, 0xf6, 0x03, 0x34, 0x04, 0xf6, 0x03, 0x34,
1258 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1259 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xe8,
1260 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
1261 0x00, 0x80, 0x1f, 0xb4, 0x6f, 0x1f, 0x0f, 0x08, 0x20, 0xa8, 0x00,
1262 0x00, 0x00, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1263 0x00, 0x0c, 0x02, 0x01, 0x00, 0x19, 0x00, 0x94,
1264 0x00, 0x10, 0x06, 0x10, 0x00, 0x36, 0x00,
1265 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1266 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1267 0x40, 0x20,
1268 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1269 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x21, 0x00,
1270 0x06, 0x00, 0x02, 0x09, 0x99,
1271 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1272 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1273 0x00, 0x00, 0x00, 0x00, 0x00,
1274 0x10, 0x00, 0x40, 0xad, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1275 0x00, 0x00, 0x00, 0x10, 0x1f, 0x10, 0x08, 0x0a,
1276 0x0a, 0x51, 0x00, 0xf1, 0x00, 0x3c, 0x00, 0xb4,
1277 0x00, 0x49, 0x13, 0x00, 0x00, 0x8c, 0x04, 0x01,
1278 0x20, 0x02, 0x00, 0x03, 0x00, 0x20, 0x00, 0x00,
1279 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1280 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1281 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1282 0x10, 0x40, 0x40, 0x80, 0x00, 0x2d, 0x46, 0x58, 0x67, 0x74, 0x7f,
1283 0x88, 0x94, 0x9d, 0xa6, 0xae, 0xb5, 0xbd, 0xc4,
1284 0xcb, 0xd1, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1285 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1286 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1287 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1288 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1289 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1290 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x3f,
1291 0x01, 0x00, 0x00, 0xef, 0x00, 0x09, 0x05, 0x82,
1292 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1293 0x01, 0xf0, 0x00,
1294 0, 0, 0
1295};
1296static const u8 proscope_start_qvga[] = {
1297 0x02, 0x00, 0x11, 0x3c, 0x50, 0x9e, 0x3c, 0x50, 0x00, 0x00, 0x00,
1298 0x00, 0x78, 0x3f, 0x10, 0x02, 0xf2, 0x8f, 0x78,
1299 0x40,
1300 0x10, 0x1a, 0x01, 0x06,
1301 0x00, 0x03, 0x02, 0xf9, 0x02,
1302 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1303 0x10, 0x1b, 0x02, 0x00, 0x00,
1304 0x10, 0x11, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1305 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
1306 0x10, 0x0e, 0x01, 0x10,
1307 0, 0, 0
1308};
1309static const u8 proscope_start_vga[] = {
1310 0x00, 0x03, 0x02, 0xf9, 0x02,
1311 0x10, 0x85, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
1312 0x02, 0x00, 0x11, 0x78, 0xa0, 0x8c, 0x78, 0xa0, 0x00, 0x00, 0x00,
1313 0x00, 0xf0, 0x16, 0x00, 0x00, 0x82, 0x84, 0x00,
1314 0x80,
1315 0x10, 0x1a, 0x01, 0x06,
1316 0x10, 0x00, 0x01, 0xa1,
1317 0x10, 0x1b, 0x02, 0x00, 0x00,
1318 0x10, 0x1d, 0x08, 0xc0, 0x0d, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
1319 0x10, 0x11, 0x08, 0x00, 0x00, 0x7f, 0x02, 0x00, 0x00, 0xdf, 0x01,
1320 0x10, 0x0e, 0x01, 0x10,
1321 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae,
1322 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2,
1323 0xf9,
1324 0x10, 0x03, 0x01, 0x00,
1325 0, 0, 0
1326};
1327static const u8 proscope_start_2[] = {
1328 0x10, 0x0f, 0x02, 0x0c, 0x0c,
1329 0x10, 0x03, 0x01, 0x0c,
1330 0x10, 0x41, 0x11, 0x00, 0x10, 0x51, 0x6e, 0x83, 0x93, 0xa1, 0xae,
1331 0xb9, 0xc3, 0xcc, 0xd4, 0xdd, 0xe4, 0xeb, 0xf2,
1332 0xf9,
1333 0x10, 0x0b, 0x01, 0x0b,
1334 0x10, 0x0d, 0x01, 0x10,
1335 0x10, 0x0c, 0x01, 0x1b,
1336 0x04, 0x06, 0x01, 0x03,
1337 0x04, 0x05, 0x01, 0x21,
1338 0x04, 0x04, 0x01, 0x00,
1339 0, 0, 0
1340};
1341
1342/* nw800 - hv7121b? (seems pas106) - Divio Chicony TwinkleCam */
1343static const u8 twinkle_start[] = {
1344 0x04, 0x06, 0x01, 0x44,
1345 0x04, 0x06, 0x01, 0x00,
1346 0x00, 0x00, 0x40, 0x14, 0x83, 0x00, 0xba, 0x01, 0x10, 0x00, 0x4f,
1347 0xef, 0x00, 0x00, 0x60, 0x00, 0x01, 0x00, 0x19,
1348 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1349 0x00, 0x01, 0x00, 0x19, 0x00, 0x06, 0x00, 0xfc,
1350 0x01, 0x3e, 0x00, 0x86, 0x00, 0x3e, 0x00, 0x86,
1351 0x00, 0x3e, 0x00, 0x86, 0x00, 0x01, 0x00, 0x01,
1352 0x00, 0x56, 0x00, 0x9e, 0x00, 0x56, 0x00, 0x9e,
1353 0x00, 0x56, 0x00, 0x9e, 0x00, 0x01, 0x00, 0x01,
1354 0x00, 0x40, 0x40, 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1355 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1356 0x00, 0x6e, 0x00, 0xb6, 0x00, 0x6e, 0x00, 0x78,
1357 0x04, 0x6e, 0x00, 0xb6, 0x00, 0x01, 0x00, 0x01,
1358 0x00, 0xca, 0x03, 0x46, 0x04, 0xca, 0x03, 0x46,
1359 0x04, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1360 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0xf0,
1361 0x00, 0x3e, 0x00, 0xaa, 0x00, 0x88, 0x00, 0x2e,
1362 0x00, 0x80, 0x1f, 0xb8, 0x48, 0x0f, 0x04, 0x88, 0x14, 0x68, 0x00,
1363 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x03,
1364 0x00, 0x24, 0x01, 0x01, 0x00, 0x16, 0x00, 0x04,
1365 0x00, 0x4b, 0x00, 0x76, 0x00, 0x86, 0x00,
1366 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1367 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1368 0x40, 0x20,
1369 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1370 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0x61, 0x00,
1371 0x05, 0x00, 0x06, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00,
1372 0x06, 0x00, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1375 0x00, 0x00, 0x00,
1376 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1377 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1378 0x00, 0x00, 0x00, 0x00, 0x00,
1379 0x10, 0x00, 0x40, 0x80, 0x02, 0x20, 0x00, 0x11, 0x00, 0x00, 0x00,
1380 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x08,
1381 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1382 0x00, 0x49, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00,
1383 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1384 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1385 0x03, 0x00, 0x00, 0x10, 0x00, 0x20, 0x10, 0x06,
1386 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x00, 0x80,
1387 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1388 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1389 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1390 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1391 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1392 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1393 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1394 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1395 0x10, 0x80, 0x1d, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1396 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x62,
1397 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01, 0x20,
1398 0x01, 0x60, 0x01, 0x00, 0x00,
1399
1400 0x10, 0x85, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
1401 0x04, 0x04, 0x01, 0x10,
1402 0x04, 0x04, 0x01, 0x00,
1403 0x04, 0x05, 0x01, 0x61,
1404 0x04, 0x04, 0x01, 0x01,
1405 I2C0, 0x40, 0x0c, 0x02, 0x0c, 0x12, 0x07, 0x00, 0x00, 0x00, 0x00,
1406 0x00, 0x00, 0x00, 0x0a,
1407 I2C0, 0x40, 0x02, 0x11, 0x06,
1408 I2C0, 0x40, 0x02, 0x14, 0x00,
1409 I2C0, 0x40, 0x02, 0x13, 0x01, /* i2c end */
1410 I2C0, 0x40, 0x02, 0x07, 0x01,
1411 0x02, 0x00, 0x11, 0x48, 0x58, 0x9e, 0x48, 0x58, 0x00, 0x00, 0x00,
1412 0x00, 0x84, 0x36, 0x05, 0x01, 0xf2, 0x86, 0x65,
1413 0x40,
1414 I2C0, 0x40, 0x02, 0x02, 0x0c,
1415 I2C0, 0x40, 0x02, 0x13, 0x01,
1416 0x10, 0x00, 0x01, 0x01,
1417 0x10, 0x8f, 0x0c, 0x62, 0x01, 0x24, 0x01, 0x62, 0x01, 0x24, 0x01,
1418 0x20, 0x01, 0x60, 0x01,
1419 I2C0, 0x40, 0x02, 0x05, 0x0f,
1420 I2C0, 0x40, 0x02, 0x13, 0x01,
1421 I2C0, 0x40, 0x08, 0x08, 0x04, 0x0b, 0x01, 0x01, 0x02, 0x00, 0x17,
1422 I2C0, 0x40, 0x03, 0x12, 0x00, 0x01,
1423 0x10, 0x11, 0x08, 0x00, 0x00, 0x5f, 0x01, 0x00, 0x00, 0x1f, 0x01,
1424 I2C0, 0x40, 0x02, 0x12, 0x00,
1425 I2C0, 0x40, 0x02, 0x0e, 0x00,
1426 I2C0, 0x40, 0x02, 0x11, 0x06,
1427 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
1428 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
1429 0xf9,
1430 0x10, 0x03, 0x01, 0x00,
1431 0x10, 0x0f, 0x02, 0x0c, 0x0c,
1432 0x10, 0x03, 0x01, 0x06,
1433 0x10, 0x41, 0x11, 0x00, 0x17, 0x3f, 0x69, 0x7b, 0x8c, 0x9a, 0xa7,
1434 0xb3, 0xbf, 0xc9, 0xd3, 0xdd, 0xe6, 0xef, 0xf7,
1435 0xf9,
1436 0x10, 0x0b, 0x01, 0x19,
1437 0x10, 0x0d, 0x01, 0x10,
1438 0x10, 0x0c, 0x01, 0x0d,
1439 0x04, 0x06, 0x01, 0x03,
1440 0x04, 0x05, 0x01, 0x61,
1441 0x04, 0x04, 0x01, 0x41,
1442 0, 0, 0
1443};
1444
1445/* nw802 dvc-v6 */
1446static const u8 dvcv6_start[] = {
1447 0x04, 0x06, 0x01, 0x06,
1448 0x00, 0x00, 0x40, 0x54, 0x96, 0x98, 0xf9, 0x02, 0x18, 0x00, 0x4c,
1449 0x0f, 0x1f, 0x00, 0x0d, 0x02, 0x01, 0x00, 0x19,
1450 0x00, 0x01, 0x00, 0x19, 0x00, 0x01, 0x00, 0x19,
1451 0x00, 0x0b, 0x00, 0x1b, 0x00, 0xc8, 0x00, 0xf4,
1452 0x05, 0xb4, 0x00, 0xcc, 0x00, 0x01, 0x00, 0x01,
1453 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1454 0x00, 0xa2, 0x00, 0xc6, 0x00, 0x60, 0x00, 0xc6,
1455 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1456 0x00, 0x40, 0x40, 0x00, 0xae, 0x00, 0xd2, 0x00, 0xae, 0x00, 0xd2,
1457 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1458 0x00, 0xa8, 0x00, 0xc0, 0x00, 0x66, 0x00, 0xc0,
1459 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01,
1460 0x00, 0x0a, 0x00, 0x54, 0x00, 0x0a, 0x00, 0x54,
1461 0x00, 0x10, 0x00, 0x36, 0x00, 0xd2, 0x00, 0xee,
1462 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6,
1463 0x00, 0x5d, 0x00, 0xc7, 0x00, 0x7e, 0x00, 0x30,
1464 0x00, 0x80, 0x1f, 0x98, 0x43, 0x3f, 0x0d, 0x88, 0x20, 0x80, 0x3f,
1465 0x47, 0xaf, 0x00, 0x00, 0xa8, 0x08, 0x00, 0x11,
1466 0x00, 0x0c, 0x02, 0x0c, 0x00, 0x1c, 0x00, 0x94,
1467 0x00, 0x10, 0x06, 0x24, 0x00, 0x4a, 0x00,
1468 0x02, 0x00, 0x12, 0x78, 0xa0, 0x9e, 0x78, 0xa0, 0x00, 0x00, 0x00,
1469 0x00, 0xf0, 0x18, 0x0b, 0x06, 0x62, 0x82, 0xa0,
1470 0x40, 0x20,
1471 0x03, 0x00, 0x03, 0x03, 0x00, 0x00,
1472 0x04, 0x00, 0x07, 0x01, 0x10, 0x00, 0x00, 0x00, 0xff, 0x00,
1473 0x06, 0x00, 0x02, 0x09, 0x99,
1474 0x08, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1475 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1476 0x00, 0x00, 0x00, 0x00, 0x00,
1477 0x10, 0x00, 0x40, 0xa0, 0x02, 0x80, 0x00, 0x12, 0x00, 0x00, 0x00,
1478 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x08, 0x0a,
1479 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1480 0x00, 0x49, 0x13, 0x00, 0x00, 0xe0, 0x00, 0x0c,
1481 0x00, 0x52, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00,
1482 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08,
1483 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x06,
1484 0xf7, 0xee, 0x1c, 0x1c, 0xe9, 0xfc, 0x10, 0x80,
1485 0x10, 0x40, 0x40, 0x80, 0x00, 0x05, 0x35, 0x5e, 0x78, 0x8b, 0x99,
1486 0xa4, 0xae, 0xb5, 0xbc, 0xc1, 0xc6, 0xc9, 0xcc,
1487 0xcf, 0xd0, 0x00, 0x11, 0x22, 0x32, 0x43, 0x54,
1488 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3, 0xd2,
1489 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32, 0x43,
1490 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3, 0xc3,
1491 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x11, 0x22, 0x32,
1492 0x43, 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb3,
1493 0x10, 0x80, 0x1b, 0xc3, 0xd2, 0xe2, 0xf1, 0xff, 0x00, 0x00, 0x00,
1494 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x05, 0x82,
1495 0x02, 0xe4, 0x01, 0x40, 0x01, 0xf0, 0x00, 0x40,
1496 0x01, 0xf0, 0x00,
1497 0x00, 0x03, 0x02, 0x94, 0x03,
1498 0x00, 0x1d, 0x04, 0x0a, 0x01, 0x28, 0x07,
1499 0x00, 0x7b, 0x02, 0xe0, 0x00,
1500 0x10, 0x8d, 0x01, 0x00,
1501 0x00, 0x09, 0x04, 0x1e, 0x00, 0x0c, 0x02,
1502 0x00, 0x91, 0x02, 0x0b, 0x02,
1503 0x10, 0x00, 0x01, 0xaf,
1504 0x02, 0x00, 0x11, 0x3c, 0x50, 0x8f, 0x3c, 0x50, 0x00, 0x00, 0x00,
1505 0x00, 0x78, 0x3f, 0x3f, 0x06, 0xf2, 0x8f, 0xf0,
1506 0x40,
1507 0x10, 0x1a, 0x01, 0x02,
1508 0x10, 0x00, 0x01, 0xaf,
1509 0x10, 0x85, 0x08, 0x00, 0x00, 0x3f, 0x01, 0x00, 0x00, 0xef, 0x00,
1510 0x10, 0x1b, 0x02, 0x07, 0x01,
1511 0x10, 0x11, 0x08, 0x61, 0x00, 0xe0, 0x00, 0x49, 0x00, 0xa8, 0x00,
1512 0x10, 0x1f, 0x06, 0x01, 0x20, 0x02, 0xe8, 0x03, 0x00,
1513 0x10, 0x1d, 0x02, 0x40, 0x06,
1514 0x10, 0x0e, 0x01, 0x08,
1515 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa,
1516 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc,
1517 0xdc,
1518 0x10, 0x03, 0x01, 0x00,
1519 0x10, 0x0f, 0x02, 0x12, 0x12,
1520 0x10, 0x03, 0x01, 0x11,
1521 0x10, 0x41, 0x11, 0x00, 0x0f, 0x54, 0x6f, 0x82, 0x91, 0x9f, 0xaa,
1522 0xb4, 0xbd, 0xc5, 0xcd, 0xd5, 0xdb, 0xdc, 0xdc,
1523 0xdc,
1524 0x10, 0x0b, 0x01, 0x16,
1525 0x10, 0x0d, 0x01, 0x10,
1526 0x10, 0x0c, 0x01, 0x1a,
1527 0x04, 0x06, 0x01, 0x03,
1528 0x04, 0x04, 0x01, 0x00,
1529};
1530
1531static const u8 *webcam_start[] = {
1532 [Generic800] = nw800_start,
1533 [SpaceCam] = spacecam_start,
1534 [SpaceCam2] = spacecam2_start,
1535 [Cvideopro] = cvideopro_start,
1536 [Dlink350c] = dlink_start,
1537 [DS3303u] = ds3303_start,
1538 [Kr651us] = kr651_start_1,
1539 [Kritter] = kritter_start,
1540 [Mustek300] = mustek_start,
1541 [Proscope] = proscope_start_1,
1542 [Twinkle] = twinkle_start,
1543 [DvcV6] = dvcv6_start,
1544 [P35u] = nw801_start_1,
1545 [Generic802] = nw802_start,
1546};
1547
1548/* -- write a register -- */
1549static void reg_w(struct gspca_dev *gspca_dev,
1550 u16 index,
1551 const u8 *data,
1552 int len)
1553{
1554 struct usb_device *dev = gspca_dev->dev;
1555 int ret;
1556
1557 if (gspca_dev->usb_err < 0)
1558 return;
1559 if (len == 1)
1560 PDEBUG(D_USBO, "SET 00 0000 %04x %02x", index, *data);
1561 else
1562 PDEBUG(D_USBO, "SET 00 0000 %04x %02x %02x ...",
1563 index, *data, data[1]);
1564 memcpy(gspca_dev->usb_buf, data, len);
1565 ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
1566 0x00,
1567 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1568 0x00, /* value */
1569 index,
1570 gspca_dev->usb_buf,
1571 len,
1572 500);
1573 if (ret < 0) {
1574 err("reg_w err %d", ret);
1575 gspca_dev->usb_err = ret;
1576 }
1577}
1578
1579/* -- read registers in usb_buf -- */
1580static void reg_r(struct gspca_dev *gspca_dev,
1581 u16 index,
1582 int len)
1583{
1584 struct usb_device *dev = gspca_dev->dev;
1585 int ret;
1586
1587 if (gspca_dev->usb_err < 0)
1588 return;
1589 ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
1590 0x00,
1591 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
1592 0x00, index,
1593 gspca_dev->usb_buf, len, 500);
1594 if (ret < 0) {
1595 err("reg_r err %d", ret);
1596 gspca_dev->usb_err = ret;
1597 return;
1598 }
1599 if (len == 1)
1600 PDEBUG(D_USBI, "GET 00 0000 %04x %02x",
1601 index, gspca_dev->usb_buf[0]);
1602 else
1603 PDEBUG(D_USBI, "GET 00 0000 %04x %02x %02x ..",
1604 index, gspca_dev->usb_buf[0],
1605 gspca_dev->usb_buf[1]);
1606}
1607
1608static void i2c_w(struct gspca_dev *gspca_dev,
1609 u8 i2c_addr,
1610 const u8 *data,
1611 int len)
1612{
1613 u8 val[2];
1614 int i;
1615
1616 reg_w(gspca_dev, 0x0600, data + 1, len - 1);
1617 reg_w(gspca_dev, 0x0600, data, len);
1618 val[0] = len;
1619 val[1] = i2c_addr;
1620 reg_w(gspca_dev, 0x0502, val, 2);
1621 val[0] = 0x01;
1622 reg_w(gspca_dev, 0x0501, val, 1);
1623 for (i = 5; --i >= 0; ) {
1624 msleep(4);
1625 reg_r(gspca_dev, 0x0505, 1);
1626 if (gspca_dev->usb_err < 0)
1627 return;
1628 if (gspca_dev->usb_buf[0] == 0)
1629 return;
1630 }
1631 gspca_dev->usb_err = -ETIME;
1632}
1633
1634static void reg_w_buf(struct gspca_dev *gspca_dev,
1635 const u8 *cmd)
1636{
1637 u16 reg;
1638 int len;
1639
1640 for (;;) {
1641 reg = *cmd++ << 8;
1642 reg += *cmd++;
1643 len = *cmd++;
1644 if (len == 0)
1645 break;
1646 if (cmd[-3] != I2C0)
1647 reg_w(gspca_dev, reg, cmd, len);
1648 else
1649 i2c_w(gspca_dev, reg, cmd, len);
1650 cmd += len;
1651 }
1652}
1653
1654static int swap_bits(int v)
1655{
1656 int r, i;
1657
1658 r = 0;
1659 for (i = 0; i < 8; i++) {
1660 r <<= 1;
1661 if (v & 1)
1662 r++;
1663 v >>= 1;
1664 }
1665 return r;
1666}
1667
1668static void setgain(struct gspca_dev *gspca_dev)
1669{
1670 struct sd *sd = (struct sd *) gspca_dev;
1671 u8 val, v[2];
1672
1673 val = sd->ctrls[GAIN].val;
1674 switch (sd->webcam) {
1675 case P35u:
1676 /* Note the control goes from 0-255 not 0-127, but anything
1677 above 127 just means amplifying noise */
1678 val >>= 1; /* 0 - 255 -> 0 - 127 */
1679 reg_w(gspca_dev, 0x1026, &val, 1);
1680 break;
1681 case Kr651us:
1682 /* 0 - 253 */
1683 val = swap_bits(val);
1684 v[0] = val << 3;
1685 v[1] = val >> 5;
1686 reg_w(gspca_dev, 0x101d, v, 2); /* SIF reg0/1 (AGC) */
1687 break;
1688 }
1689}
1690
1691static void setexposure(struct gspca_dev *gspca_dev)
1692{
1693 struct sd *sd = (struct sd *) gspca_dev;
1694 s16 val;
1695 u8 v[2];
1696
1697 val = sd->ctrls[EXPOSURE].val;
1698 switch (sd->webcam) {
1699 case P35u:
1700 v[0] = ((9 - val) << 3) | 0x01;
1701 reg_w(gspca_dev, 0x1019, v, 1);
1702 break;
1703 case Cvideopro:
1704 case DvcV6:
1705 case Kritter:
1706 case Kr651us:
1707 v[0] = val;
1708 v[1] = val >> 8;
1709 reg_w(gspca_dev, 0x101b, v, 2);
1710 break;
1711 }
1712}
1713
1714static void setautogain(struct gspca_dev *gspca_dev)
1715{
1716 struct sd *sd = (struct sd *) gspca_dev;
1717 int w, h;
1718
1719 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
1720 return;
1721 if (!sd->ctrls[AUTOGAIN].val) {
1722 sd->ag_cnt = -1;
1723 return;
1724 }
1725 sd->ag_cnt = AG_CNT_START;
1726
1727 reg_r(gspca_dev, 0x1004, 1);
1728 if (gspca_dev->usb_buf[0] & 0x04) { /* if AE_FULL_FRM */
1729 sd->ae_res = gspca_dev->width * gspca_dev->height;
1730 } else { /* get the AE window size */
1731 reg_r(gspca_dev, 0x1011, 8);
1732 w = (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0]
1733 - (gspca_dev->usb_buf[3] << 8) - gspca_dev->usb_buf[2];
1734 h = (gspca_dev->usb_buf[5] << 8) + gspca_dev->usb_buf[4]
1735 - (gspca_dev->usb_buf[7] << 8) - gspca_dev->usb_buf[6];
1736 sd->ae_res = h * w;
1737 if (sd->ae_res == 0)
1738 sd->ae_res = gspca_dev->width * gspca_dev->height;
1739 }
1740}
1741
1742static int nw802_test_reg(struct gspca_dev *gspca_dev,
1743 u16 index,
1744 u8 value)
1745{
1746 /* write the value */
1747 reg_w(gspca_dev, index, &value, 1);
1748
1749 /* read it */
1750 reg_r(gspca_dev, index, 1);
1751
1752 return gspca_dev->usb_buf[0] == value;
1753}
1754
1755/* this function is called at probe time */
1756static int sd_config(struct gspca_dev *gspca_dev,
1757 const struct usb_device_id *id)
1758{
1759 struct sd *sd = (struct sd *) gspca_dev;
1760
1761 if ((unsigned) webcam >= NWEBCAMS)
1762 webcam = 0;
1763 sd->webcam = webcam;
1764 gspca_dev->cam.reverse_alts = 1;
1765 gspca_dev->cam.ctrls = sd->ctrls;
1766 sd->ag_cnt = -1;
1767
1768 /*
1769 * Autodetect sequence inspired from some log.
1770 * We try to detect what registers exist or not.
1771 * If 0x0500 does not exist => NW802
1772 * If it does, test 0x109b. If it doesn't exist,
1773 * then it's a NW801. Else, a NW800
1774 * If a et31x110 (nw800 and 06a5:d800)
1775 * get the sensor ID
1776 */
1777 if (!nw802_test_reg(gspca_dev, 0x0500, 0x55)) {
1778 sd->bridge = BRIDGE_NW802;
1779 if (sd->webcam == Generic800)
1780 sd->webcam = Generic802;
1781 } else if (!nw802_test_reg(gspca_dev, 0x109b, 0xaa)) {
1782 sd->bridge = BRIDGE_NW801;
1783 if (sd->webcam == Generic800)
1784 sd->webcam = P35u;
1785 } else if (id->idVendor == 0x06a5 && id->idProduct == 0xd800) {
1786 reg_r(gspca_dev, 0x0403, 1); /* GPIO */
1787 PDEBUG(D_PROBE, "et31x110 sensor type %02x",
1788 gspca_dev->usb_buf[0]);
1789 switch (gspca_dev->usb_buf[0] >> 1) {
1790 case 0x00: /* ?? */
1791 if (sd->webcam == Generic800)
1792 sd->webcam = SpaceCam;
1793 break;
1794 case 0x01: /* Hynix? */
1795 if (sd->webcam == Generic800)
1796 sd->webcam = Twinkle;
1797 break;
1798 case 0x0a: /* Pixart */
1799 if (sd->webcam == Generic800)
1800 sd->webcam = SpaceCam2;
1801 break;
1802 }
1803 }
1804 if (webcam_chip[sd->webcam] != sd->bridge) {
1805 err("Bad webcam type %d for NW80%d", sd->webcam, sd->bridge);
1806 gspca_dev->usb_err = -ENODEV;
1807 return gspca_dev->usb_err;
1808 }
1809 PDEBUG(D_PROBE, "Bridge nw80%d - type: %d", sd->bridge, sd->webcam);
1810
1811 if (sd->bridge == BRIDGE_NW800) {
1812 switch (sd->webcam) {
1813 case DS3303u:
1814 gspca_dev->cam.cam_mode = cif_mode; /* qvga */
1815 break;
1816 default:
1817 gspca_dev->cam.cam_mode = &cif_mode[1]; /* cif */
1818 break;
1819 }
1820 gspca_dev->cam.nmodes = 1;
1821 } else {
1822 gspca_dev->cam.cam_mode = vga_mode;
1823 switch (sd->webcam) {
1824 case Kr651us:
1825 case Proscope:
1826 case P35u:
1827 gspca_dev->cam.nmodes = ARRAY_SIZE(vga_mode);
1828 break;
1829 default:
1830 gspca_dev->cam.nmodes = 1; /* qvga only */
1831 break;
1832 }
1833 }
1834 switch (sd->webcam) {
1835 case P35u:
1836/* sd->ctrls[EXPOSURE].max = 9;
1837 * sd->ctrls[EXPOSURE].def = 9; */
1838 /* coarse expo auto gain function gain minimum, to avoid
1839 * a large settings jump the first auto adjustment */
1840 sd->ctrls[GAIN].def = 255 / 5 * 2;
1841 break;
1842 case Cvideopro:
1843 case DvcV6:
1844 case Kritter:
1845 gspca_dev->ctrl_dis = (1 << GAIN) | (1 << AUTOGAIN);
1846 /* fall thru */
1847 case Kr651us:
1848 sd->ctrls[EXPOSURE].max = 315;
1849 sd->ctrls[EXPOSURE].def = 150;
1850 break;
1851 default:
1852 gspca_dev->ctrl_dis = (1 << GAIN) | (1 << EXPOSURE)
1853 | (1 << AUTOGAIN);
1854 break;
1855 }
1856
1857#if AUTOGAIN_DEF
1858 if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1859 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1860#endif
1861 return gspca_dev->usb_err;
1862}
1863
1864/* this function is called at probe and resume time */
1865static int sd_init(struct gspca_dev *gspca_dev)
1866{
1867 struct sd *sd = (struct sd *) gspca_dev;
1868
1869 switch (sd->bridge) {
1870 case BRIDGE_NW800:
1871 switch (sd->webcam) {
1872 case SpaceCam:
1873 reg_w_buf(gspca_dev, spacecam_init);
1874 break;
1875 default:
1876 reg_w_buf(gspca_dev, nw800_init);
1877 break;
1878 }
1879 break;
1880 default:
1881 switch (sd->webcam) {
1882 case Mustek300:
1883 case P35u:
1884 case Proscope:
1885 reg_w_buf(gspca_dev, proscope_init);
1886 break;
1887 }
1888 break;
1889 }
1890 return gspca_dev->usb_err;
1891}
1892
1893/* -- start the camera -- */
1894static int sd_start(struct gspca_dev *gspca_dev)
1895{
1896 struct sd *sd = (struct sd *) gspca_dev;
1897 const u8 *cmd;
1898
1899 cmd = webcam_start[sd->webcam];
1900 reg_w_buf(gspca_dev, cmd);
1901 switch (sd->webcam) {
1902 case P35u:
1903 if (gspca_dev->width == 320)
1904 reg_w_buf(gspca_dev, nw801_start_qvga);
1905 else
1906 reg_w_buf(gspca_dev, nw801_start_vga);
1907 reg_w_buf(gspca_dev, nw801_start_2);
1908 break;
1909 case Kr651us:
1910 if (gspca_dev->width == 320)
1911 reg_w_buf(gspca_dev, kr651_start_qvga);
1912 else
1913 reg_w_buf(gspca_dev, kr651_start_vga);
1914 reg_w_buf(gspca_dev, kr651_start_2);
1915 break;
1916 case Proscope:
1917 if (gspca_dev->width == 320)
1918 reg_w_buf(gspca_dev, proscope_start_qvga);
1919 else
1920 reg_w_buf(gspca_dev, proscope_start_vga);
1921 reg_w_buf(gspca_dev, proscope_start_2);
1922 break;
1923 }
1924
1925 setgain(gspca_dev);
1926 setexposure(gspca_dev);
1927 setautogain(gspca_dev);
1928 sd->exp_too_high_cnt = 0;
1929 sd->exp_too_low_cnt = 0;
1930 return gspca_dev->usb_err;
1931}
1932
1933static void sd_stopN(struct gspca_dev *gspca_dev)
1934{
1935 struct sd *sd = (struct sd *) gspca_dev;
1936 u8 value;
1937
1938 /* 'go' off */
1939 if (sd->bridge != BRIDGE_NW801) {
1940 value = 0x02;
1941 reg_w(gspca_dev, 0x0406, &value, 1);
1942 }
1943
1944 /* LED off */
1945 switch (sd->webcam) {
1946 case Cvideopro:
1947 case Kr651us:
1948 case DvcV6:
1949 case Kritter:
1950 value = 0xff;
1951 break;
1952 case Dlink350c:
1953 value = 0x21;
1954 break;
1955 case SpaceCam:
1956 case SpaceCam2:
1957 case Proscope:
1958 case Twinkle:
1959 value = 0x01;
1960 break;
1961 default:
1962 return;
1963 }
1964 reg_w(gspca_dev, 0x0404, &value, 1);
1965}
1966
1967static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1968 u8 *data, /* isoc packet */
1969 int len) /* iso packet length */
1970{
1971 /*
1972 * frame header = '00 00 hh ww ss xx ff ff'
1973 * with:
1974 * - 'hh': height / 4
1975 * - 'ww': width / 4
1976 * - 'ss': frame sequence number c0..dd
1977 */
1978 if (data[0] == 0x00 && data[1] == 0x00
1979 && data[6] == 0xff && data[7] == 0xff) {
1980 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1981 gspca_frame_add(gspca_dev, FIRST_PACKET, data + 8, len - 8);
1982 } else {
1983 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1984 }
1985}
1986
1987static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1988{
1989 struct sd *sd = (struct sd *) gspca_dev;
1990
1991 sd->ctrls[AUTOGAIN].val = val;
1992 if (val)
1993 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1994 else
1995 gspca_dev->ctrl_inac = 0;
1996 if (gspca_dev->streaming)
1997 setautogain(gspca_dev);
1998 return gspca_dev->usb_err;
1999}
2000
2001#include "autogain_functions.h"
2002
2003static void do_autogain(struct gspca_dev *gspca_dev)
2004{
2005 struct sd *sd = (struct sd *) gspca_dev;
2006 int luma;
2007
2008 if (sd->ag_cnt < 0)
2009 return;
2010 if (--sd->ag_cnt >= 0)
2011 return;
2012 sd->ag_cnt = AG_CNT_START;
2013
2014 /* get the average luma */
2015 reg_r(gspca_dev, sd->bridge == BRIDGE_NW801 ? 0x080d : 0x080c, 4);
2016 luma = (gspca_dev->usb_buf[3] << 24) + (gspca_dev->usb_buf[2] << 16)
2017 + (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
2018 luma /= sd->ae_res;
2019
2020 switch (sd->webcam) {
2021 case P35u:
2022 coarse_grained_expo_autogain(gspca_dev, luma, 100, 5);
2023 break;
2024 default:
2025 auto_gain_n_exposure(gspca_dev, luma, 100, 5, 230, 0);
2026 break;
2027 }
2028}
2029
2030/* V4L2 controls supported by the driver */
2031static const struct ctrl sd_ctrls[NCTRLS] = {
2032[GAIN] = {
2033 {
2034 .id = V4L2_CID_GAIN,
2035 .type = V4L2_CTRL_TYPE_INTEGER,
2036 .name = "Gain",
2037 .minimum = 0,
2038 .maximum = 253,
2039 .step = 1,
2040 .default_value = 128
2041 },
2042 .set_control = setgain
2043 },
2044[EXPOSURE] = {
2045 {
2046 .id = V4L2_CID_EXPOSURE,
2047 .type = V4L2_CTRL_TYPE_INTEGER,
2048 .name = "Exposure",
2049 .minimum = 0,
2050 .maximum = 9,
2051 .step = 1,
2052 .default_value = 9
2053 },
2054 .set_control = setexposure
2055 },
2056[AUTOGAIN] = {
2057 {
2058 .id = V4L2_CID_AUTOGAIN,
2059 .type = V4L2_CTRL_TYPE_BOOLEAN,
2060 .name = "Auto Gain",
2061 .minimum = 0,
2062 .maximum = 1,
2063 .step = 1,
2064 .default_value = AUTOGAIN_DEF,
2065 .flags = V4L2_CTRL_FLAG_UPDATE
2066 },
2067 .set = sd_setautogain
2068 },
2069};
2070
2071/* sub-driver description */
2072static const struct sd_desc sd_desc = {
2073 .name = MODULE_NAME,
2074 .ctrls = sd_ctrls,
2075 .nctrls = ARRAY_SIZE(sd_ctrls),
2076 .config = sd_config,
2077 .init = sd_init,
2078 .start = sd_start,
2079 .stopN = sd_stopN,
2080 .pkt_scan = sd_pkt_scan,
2081 .dq_callback = do_autogain,
2082};
2083
2084/* -- module initialisation -- */
2085static const struct usb_device_id device_table[] = {
2086 {USB_DEVICE(0x046d, 0xd001)},
2087 {USB_DEVICE(0x0502, 0xd001)},
2088 {USB_DEVICE(0x052b, 0xd001)},
2089 {USB_DEVICE(0x055f, 0xd001)},
2090 {USB_DEVICE(0x06a5, 0x0000)},
2091 {USB_DEVICE(0x06a5, 0xd001)},
2092 {USB_DEVICE(0x06a5, 0xd800)},
2093 {USB_DEVICE(0x06be, 0xd001)},
2094 {USB_DEVICE(0x0728, 0xd001)},
2095 {}
2096};
2097MODULE_DEVICE_TABLE(usb, device_table);
2098
2099/* -- device connect -- */
2100static int sd_probe(struct usb_interface *intf,
2101 const struct usb_device_id *id)
2102{
2103 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2104 THIS_MODULE);
2105}
2106
2107static struct usb_driver sd_driver = {
2108 .name = MODULE_NAME,
2109 .id_table = device_table,
2110 .probe = sd_probe,
2111 .disconnect = gspca_disconnect,
2112#ifdef CONFIG_PM
2113 .suspend = gspca_suspend,
2114 .resume = gspca_resume,
2115#endif
2116};
2117
2118/* -- module insert / remove -- */
2119static int __init sd_mod_init(void)
2120{
2121 return usb_register(&sd_driver);
2122}
2123static void __exit sd_mod_exit(void)
2124{
2125 usb_deregister(&sd_driver);
2126}
2127
2128module_init(sd_mod_init);
2129module_exit(sd_mod_exit);
2130
2131module_param(webcam, int, 0644);
2132MODULE_PARM_DESC(webcam,
2133 "Webcam type\n"
2134 "0: generic\n"
2135 "1: Trust 120 SpaceCam\n"
2136 "2: other Trust 120 SpaceCam\n"
2137 "3: Conceptronic Video Pro\n"
2138 "4: D-link dru-350c\n"
2139 "5: Plustek Opticam 500U\n"
2140 "6: Panasonic GP-KR651US\n"
2141 "7: iRez Kritter\n"
2142 "8: Mustek Wcam 300 mini\n"
2143 "9: Scalar USB Microscope M2 (Proscope)\n"
2144 "10: Divio Chicony TwinkleCam\n"
2145 "11: DVC-V6\n");
diff --git a/drivers/media/video/gspca/ov519.c b/drivers/media/video/gspca/ov519.c
index 8ab2c452c25e..fd1b6082c96d 100644
--- a/drivers/media/video/gspca/ov519.c
+++ b/drivers/media/video/gspca/ov519.c
@@ -1,7 +1,7 @@
1/** 1/**
2 * OV519 driver 2 * OV519 driver
3 * 3 *
4 * Copyright (C) 2008 Jean-Francois Moine (http://moinejf.free.fr) 4 * Copyright (C) 2008-2011 Jean-François Moine <moinejf@free.fr>
5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com> 5 * Copyright (C) 2009 Hans de Goede <hdegoede@redhat.com>
6 * 6 *
7 * This module is adapted from the ov51x-jpeg package, which itself 7 * This module is adapted from the ov51x-jpeg package, which itself
@@ -61,10 +61,12 @@ static int i2c_detect_tries = 10;
61enum e_ctrl { 61enum e_ctrl {
62 BRIGHTNESS, 62 BRIGHTNESS,
63 CONTRAST, 63 CONTRAST,
64 EXPOSURE,
64 COLORS, 65 COLORS,
65 HFLIP, 66 HFLIP,
66 VFLIP, 67 VFLIP,
67 AUTOBRIGHT, 68 AUTOBRIGHT,
69 AUTOGAIN,
68 FREQ, 70 FREQ,
69 NCTRL /* number of controls */ 71 NCTRL /* number of controls */
70}; 72};
@@ -118,6 +120,7 @@ struct sd {
118}; 120};
119enum sensors { 121enum sensors {
120 SEN_OV2610, 122 SEN_OV2610,
123 SEN_OV2610AE,
121 SEN_OV3610, 124 SEN_OV3610,
122 SEN_OV6620, 125 SEN_OV6620,
123 SEN_OV6630, 126 SEN_OV6630,
@@ -141,9 +144,11 @@ enum sensors {
141/* V4L2 controls supported by the driver */ 144/* V4L2 controls supported by the driver */
142static void setbrightness(struct gspca_dev *gspca_dev); 145static void setbrightness(struct gspca_dev *gspca_dev);
143static void setcontrast(struct gspca_dev *gspca_dev); 146static void setcontrast(struct gspca_dev *gspca_dev);
147static void setexposure(struct gspca_dev *gspca_dev);
144static void setcolors(struct gspca_dev *gspca_dev); 148static void setcolors(struct gspca_dev *gspca_dev);
145static void sethvflip(struct gspca_dev *gspca_dev); 149static void sethvflip(struct gspca_dev *gspca_dev);
146static void setautobright(struct gspca_dev *gspca_dev); 150static void setautobright(struct gspca_dev *gspca_dev);
151static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
147static void setfreq(struct gspca_dev *gspca_dev); 152static void setfreq(struct gspca_dev *gspca_dev);
148static void setfreq_i(struct sd *sd); 153static void setfreq_i(struct sd *sd);
149 154
@@ -172,6 +177,18 @@ static const struct ctrl sd_ctrls[] = {
172 }, 177 },
173 .set_control = setcontrast, 178 .set_control = setcontrast,
174 }, 179 },
180[EXPOSURE] = {
181 {
182 .id = V4L2_CID_EXPOSURE,
183 .type = V4L2_CTRL_TYPE_INTEGER,
184 .name = "Exposure",
185 .minimum = 0,
186 .maximum = 255,
187 .step = 1,
188 .default_value = 127,
189 },
190 .set_control = setexposure,
191 },
175[COLORS] = { 192[COLORS] = {
176 { 193 {
177 .id = V4L2_CID_SATURATION, 194 .id = V4L2_CID_SATURATION,
@@ -221,6 +238,19 @@ static const struct ctrl sd_ctrls[] = {
221 }, 238 },
222 .set_control = setautobright, 239 .set_control = setautobright,
223 }, 240 },
241[AUTOGAIN] = {
242 {
243 .id = V4L2_CID_AUTOGAIN,
244 .type = V4L2_CTRL_TYPE_BOOLEAN,
245 .name = "Auto Gain",
246 .minimum = 0,
247 .maximum = 1,
248 .step = 1,
249 .default_value = 1,
250 .flags = V4L2_CTRL_FLAG_UPDATE
251 },
252 .set = sd_setautogain,
253 },
224[FREQ] = { 254[FREQ] = {
225 { 255 {
226 .id = V4L2_CID_POWER_LINE_FREQUENCY, 256 .id = V4L2_CID_POWER_LINE_FREQUENCY,
@@ -237,48 +267,78 @@ static const struct ctrl sd_ctrls[] = {
237 267
238/* table of the disabled controls */ 268/* table of the disabled controls */
239static const unsigned ctrl_dis[] = { 269static const unsigned ctrl_dis[] = {
240[SEN_OV2610] = (1 << NCTRL) - 1, /* no control */ 270[SEN_OV2610] = ((1 << NCTRL) - 1) /* no control */
271 ^ ((1 << EXPOSURE) /* but exposure */
272 | (1 << AUTOGAIN)), /* and autogain */
273
274[SEN_OV2610AE] = ((1 << NCTRL) - 1) /* no control */
275 ^ ((1 << EXPOSURE) /* but exposure */
276 | (1 << AUTOGAIN)), /* and autogain */
241 277
242[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */ 278[SEN_OV3610] = (1 << NCTRL) - 1, /* no control */
243 279
244[SEN_OV6620] = (1 << HFLIP) | 280[SEN_OV6620] = (1 << HFLIP) |
245 (1 << VFLIP), 281 (1 << VFLIP) |
282 (1 << EXPOSURE) |
283 (1 << AUTOGAIN),
246 284
247[SEN_OV6630] = (1 << HFLIP) | 285[SEN_OV6630] = (1 << HFLIP) |
248 (1 << VFLIP), 286 (1 << VFLIP) |
287 (1 << EXPOSURE) |
288 (1 << AUTOGAIN),
249 289
250[SEN_OV66308AF] = (1 << HFLIP) | 290[SEN_OV66308AF] = (1 << HFLIP) |
251 (1 << VFLIP), 291 (1 << VFLIP) |
292 (1 << EXPOSURE) |
293 (1 << AUTOGAIN),
252 294
253[SEN_OV7610] = (1 << HFLIP) | 295[SEN_OV7610] = (1 << HFLIP) |
254 (1 << VFLIP), 296 (1 << VFLIP) |
297 (1 << EXPOSURE) |
298 (1 << AUTOGAIN),
255 299
256[SEN_OV7620] = (1 << HFLIP) | 300[SEN_OV7620] = (1 << HFLIP) |
257 (1 << VFLIP), 301 (1 << VFLIP) |
302 (1 << EXPOSURE) |
303 (1 << AUTOGAIN),
258 304
259[SEN_OV7620AE] = (1 << HFLIP) | 305[SEN_OV7620AE] = (1 << HFLIP) |
260 (1 << VFLIP), 306 (1 << VFLIP) |
307 (1 << EXPOSURE) |
308 (1 << AUTOGAIN),
261 309
262[SEN_OV7640] = (1 << HFLIP) | 310[SEN_OV7640] = (1 << HFLIP) |
263 (1 << VFLIP) | 311 (1 << VFLIP) |
264 (1 << AUTOBRIGHT) | 312 (1 << AUTOBRIGHT) |
265 (1 << CONTRAST), 313 (1 << CONTRAST) |
314 (1 << EXPOSURE) |
315 (1 << AUTOGAIN),
266 316
267[SEN_OV7648] = (1 << HFLIP) | 317[SEN_OV7648] = (1 << HFLIP) |
268 (1 << VFLIP) | 318 (1 << VFLIP) |
269 (1 << AUTOBRIGHT) | 319 (1 << AUTOBRIGHT) |
270 (1 << CONTRAST), 320 (1 << CONTRAST) |
321 (1 << EXPOSURE) |
322 (1 << AUTOGAIN),
271 323
272[SEN_OV7660] = (1 << AUTOBRIGHT), 324[SEN_OV7660] = (1 << AUTOBRIGHT) |
325 (1 << EXPOSURE) |
326 (1 << AUTOGAIN),
273 327
274[SEN_OV7670] = (1 << COLORS) | 328[SEN_OV7670] = (1 << COLORS) |
275 (1 << AUTOBRIGHT), 329 (1 << AUTOBRIGHT) |
330 (1 << EXPOSURE) |
331 (1 << AUTOGAIN),
276 332
277[SEN_OV76BE] = (1 << HFLIP) | 333[SEN_OV76BE] = (1 << HFLIP) |
278 (1 << VFLIP), 334 (1 << VFLIP) |
335 (1 << EXPOSURE) |
336 (1 << AUTOGAIN),
279 337
280[SEN_OV8610] = (1 << HFLIP) | 338[SEN_OV8610] = (1 << HFLIP) |
281 (1 << VFLIP) | 339 (1 << VFLIP) |
340 (1 << EXPOSURE) |
341 (1 << AUTOGAIN) |
282 (1 << FREQ), 342 (1 << FREQ),
283}; 343};
284 344
@@ -428,6 +488,11 @@ static const struct v4l2_pix_format ovfx2_cif_mode[] = {
428 .priv = 0}, 488 .priv = 0},
429}; 489};
430static const struct v4l2_pix_format ovfx2_ov2610_mode[] = { 490static const struct v4l2_pix_format ovfx2_ov2610_mode[] = {
491 {800, 600, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
492 .bytesperline = 800,
493 .sizeimage = 800 * 600,
494 .colorspace = V4L2_COLORSPACE_SRGB,
495 .priv = 1},
431 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 496 {1600, 1200, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
432 .bytesperline = 1600, 497 .bytesperline = 1600,
433 .sizeimage = 1600 * 1200, 498 .sizeimage = 1600 * 1200,
@@ -544,6 +609,7 @@ static const struct v4l2_pix_format ovfx2_ov3610_mode[] = {
544 * buffers, there are some pretty strict real time constraints for 609 * buffers, there are some pretty strict real time constraints for
545 * isochronous transfer for larger frame sizes). 610 * isochronous transfer for larger frame sizes).
546 */ 611 */
612/*jfm: this value works well for 1600x1200, but not 800x600 - see isoc_init */
547#define OVFX2_BULK_SIZE (13 * 4096) 613#define OVFX2_BULK_SIZE (13 * 4096)
548 614
549/* I2C registers */ 615/* I2C registers */
@@ -656,6 +722,24 @@ static const struct ov_i2c_regvals norm_2610[] = {
656 { 0x12, 0x80 }, /* reset */ 722 { 0x12, 0x80 }, /* reset */
657}; 723};
658 724
725static const struct ov_i2c_regvals norm_2610ae[] = {
726 {0x12, 0x80}, /* reset */
727 {0x13, 0xcd},
728 {0x09, 0x01},
729 {0x0d, 0x00},
730 {0x11, 0x80},
731 {0x12, 0x20}, /* 1600x1200 */
732 {0x33, 0x0c},
733 {0x35, 0x90},
734 {0x36, 0x37},
735/* ms-win traces */
736 {0x11, 0x83}, /* clock / 3 ? */
737 {0x2d, 0x00}, /* 60 Hz filter */
738 {0x24, 0xb0}, /* normal colors */
739 {0x25, 0x90},
740 {0x10, 0x43},
741};
742
659static const struct ov_i2c_regvals norm_3620b[] = { 743static const struct ov_i2c_regvals norm_3620b[] = {
660 /* 744 /*
661 * From the datasheet: "Note that after writing to register COMH 745 * From the datasheet: "Note that after writing to register COMH
@@ -2621,6 +2705,9 @@ static void ov_hires_configure(struct sd *sd)
2621 if (high == 0x96 && low == 0x40) { 2705 if (high == 0x96 && low == 0x40) {
2622 PDEBUG(D_PROBE, "Sensor is an OV2610"); 2706 PDEBUG(D_PROBE, "Sensor is an OV2610");
2623 sd->sensor = SEN_OV2610; 2707 sd->sensor = SEN_OV2610;
2708 } else if (high == 0x96 && low == 0x41) {
2709 PDEBUG(D_PROBE, "Sensor is an OV2610AE");
2710 sd->sensor = SEN_OV2610AE;
2624 } else if (high == 0x36 && (low & 0x0f) == 0x00) { 2711 } else if (high == 0x36 && (low & 0x0f) == 0x00) {
2625 PDEBUG(D_PROBE, "Sensor is an OV3610"); 2712 PDEBUG(D_PROBE, "Sensor is an OV3610");
2626 sd->sensor = SEN_OV3610; 2713 sd->sensor = SEN_OV3610;
@@ -3171,6 +3258,13 @@ static void ov519_set_fr(struct sd *sd)
3171 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock); 3258 ov518_i2c_w(sd, OV7670_R11_CLKRC, clock);
3172} 3259}
3173 3260
3261static void setautogain(struct gspca_dev *gspca_dev)
3262{
3263 struct sd *sd = (struct sd *) gspca_dev;
3264
3265 i2c_w_mask(sd, 0x13, sd->ctrls[AUTOGAIN].val ? 0x05 : 0x00, 0x05);
3266}
3267
3174/* this function is called at probe time */ 3268/* this function is called at probe time */
3175static int sd_config(struct gspca_dev *gspca_dev, 3269static int sd_config(struct gspca_dev *gspca_dev,
3176 const struct usb_device_id *id) 3270 const struct usb_device_id *id)
@@ -3295,15 +3389,22 @@ static int sd_init(struct gspca_dev *gspca_dev)
3295 } 3389 }
3296 break; 3390 break;
3297 case BRIDGE_OVFX2: 3391 case BRIDGE_OVFX2:
3298 if (sd->sensor == SEN_OV2610) { 3392 switch (sd->sensor) {
3393 case SEN_OV2610:
3394 case SEN_OV2610AE:
3299 cam->cam_mode = ovfx2_ov2610_mode; 3395 cam->cam_mode = ovfx2_ov2610_mode;
3300 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode); 3396 cam->nmodes = ARRAY_SIZE(ovfx2_ov2610_mode);
3301 } else if (sd->sensor == SEN_OV3610) { 3397 break;
3398 case SEN_OV3610:
3302 cam->cam_mode = ovfx2_ov3610_mode; 3399 cam->cam_mode = ovfx2_ov3610_mode;
3303 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode); 3400 cam->nmodes = ARRAY_SIZE(ovfx2_ov3610_mode);
3304 } else if (sd->sif) { 3401 break;
3305 cam->cam_mode = ov519_sif_mode; 3402 default:
3306 cam->nmodes = ARRAY_SIZE(ov519_sif_mode); 3403 if (sd->sif) {
3404 cam->cam_mode = ov519_sif_mode;
3405 cam->nmodes = ARRAY_SIZE(ov519_sif_mode);
3406 }
3407 break;
3307 } 3408 }
3308 break; 3409 break;
3309 case BRIDGE_W9968CF: 3410 case BRIDGE_W9968CF:
@@ -3325,6 +3426,12 @@ static int sd_init(struct gspca_dev *gspca_dev)
3325 /* Enable autogain, autoexpo, awb, bandfilter */ 3426 /* Enable autogain, autoexpo, awb, bandfilter */
3326 i2c_w_mask(sd, 0x13, 0x27, 0x27); 3427 i2c_w_mask(sd, 0x13, 0x27, 0x27);
3327 break; 3428 break;
3429 case SEN_OV2610AE:
3430 write_i2c_regvals(sd, norm_2610ae, ARRAY_SIZE(norm_2610ae));
3431
3432 /* enable autoexpo */
3433 i2c_w_mask(sd, 0x13, 0x05, 0x05);
3434 break;
3328 case SEN_OV3610: 3435 case SEN_OV3610:
3329 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b)); 3436 write_i2c_regvals(sd, norm_3620b, ARRAY_SIZE(norm_3620b));
3330 3437
@@ -3397,6 +3504,22 @@ error:
3397 return -EINVAL; 3504 return -EINVAL;
3398} 3505}
3399 3506
3507/* function called at start time before URB creation */
3508static int sd_isoc_init(struct gspca_dev *gspca_dev)
3509{
3510 struct sd *sd = (struct sd *) gspca_dev;
3511
3512 switch (sd->bridge) {
3513 case BRIDGE_OVFX2:
3514 if (gspca_dev->width == 1600)
3515 gspca_dev->cam.bulk_size = OVFX2_BULK_SIZE;
3516 else
3517 gspca_dev->cam.bulk_size = 7 * 4096;
3518 break;
3519 }
3520 return 0;
3521}
3522
3400/* Set up the OV511/OV511+ with the given image parameters. 3523/* Set up the OV511/OV511+ with the given image parameters.
3401 * 3524 *
3402 * Do not put any sensor-specific code in here (including I2C I/O functions) 3525 * Do not put any sensor-specific code in here (including I2C I/O functions)
@@ -3827,6 +3950,25 @@ static void mode_init_ov_sensor_regs(struct sd *sd)
3827 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0); 3950 i2c_w_mask(sd, 0x67, qvga ? 0xf0 : 0x90, 0xf0);
3828 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20); 3951 i2c_w_mask(sd, 0x74, qvga ? 0x20 : 0x00, 0x20);
3829 return; 3952 return;
3953 case SEN_OV2610AE: {
3954 u8 v;
3955
3956 /* frame rates:
3957 * 10fps / 5 fps for 1600x1200
3958 * 40fps / 20fps for 800x600
3959 */
3960 v = 80;
3961 if (qvga) {
3962 if (sd->frame_rate < 25)
3963 v = 0x81;
3964 } else {
3965 if (sd->frame_rate < 10)
3966 v = 0x81;
3967 }
3968 i2c_w(sd, 0x11, v);
3969 i2c_w(sd, 0x12, qvga ? 0x60 : 0x20);
3970 return;
3971 }
3830 case SEN_OV3610: 3972 case SEN_OV3610:
3831 if (qvga) { 3973 if (qvga) {
3832 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4); 3974 xstart = (1040 - gspca_dev->width) / 2 + (0x1f << 4);
@@ -3975,6 +4117,7 @@ static void set_ov_sensor_window(struct sd *sd)
3975 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */ 4117 /* mode setup is fully handled in mode_init_ov_sensor_regs for these */
3976 switch (sd->sensor) { 4118 switch (sd->sensor) {
3977 case SEN_OV2610: 4119 case SEN_OV2610:
4120 case SEN_OV2610AE:
3978 case SEN_OV3610: 4121 case SEN_OV3610:
3979 case SEN_OV7670: 4122 case SEN_OV7670:
3980 mode_init_ov_sensor_regs(sd); 4123 mode_init_ov_sensor_regs(sd);
@@ -4110,12 +4253,16 @@ static int sd_start(struct gspca_dev *gspca_dev)
4110 setcontrast(gspca_dev); 4253 setcontrast(gspca_dev);
4111 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS))) 4254 if (!(sd->gspca_dev.ctrl_dis & (1 << BRIGHTNESS)))
4112 setbrightness(gspca_dev); 4255 setbrightness(gspca_dev);
4256 if (!(sd->gspca_dev.ctrl_dis & (1 << EXPOSURE)))
4257 setexposure(gspca_dev);
4113 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS))) 4258 if (!(sd->gspca_dev.ctrl_dis & (1 << COLORS)))
4114 setcolors(gspca_dev); 4259 setcolors(gspca_dev);
4115 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP)))) 4260 if (!(sd->gspca_dev.ctrl_dis & ((1 << HFLIP) | (1 << VFLIP))))
4116 sethvflip(gspca_dev); 4261 sethvflip(gspca_dev);
4117 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT))) 4262 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOBRIGHT)))
4118 setautobright(gspca_dev); 4263 setautobright(gspca_dev);
4264 if (!(sd->gspca_dev.ctrl_dis & (1 << AUTOGAIN)))
4265 setautogain(gspca_dev);
4119 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ))) 4266 if (!(sd->gspca_dev.ctrl_dis & (1 << FREQ)))
4120 setfreq_i(sd); 4267 setfreq_i(sd);
4121 4268
@@ -4529,6 +4676,14 @@ static void setcontrast(struct gspca_dev *gspca_dev)
4529 } 4676 }
4530} 4677}
4531 4678
4679static void setexposure(struct gspca_dev *gspca_dev)
4680{
4681 struct sd *sd = (struct sd *) gspca_dev;
4682
4683 if (!sd->ctrls[AUTOGAIN].val)
4684 i2c_w(sd, 0x10, sd->ctrls[EXPOSURE].val);
4685}
4686
4532static void setcolors(struct gspca_dev *gspca_dev) 4687static void setcolors(struct gspca_dev *gspca_dev)
4533{ 4688{
4534 struct sd *sd = (struct sd *) gspca_dev; 4689 struct sd *sd = (struct sd *) gspca_dev;
@@ -4587,6 +4742,22 @@ static void setautobright(struct gspca_dev *gspca_dev)
4587 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10); 4742 i2c_w_mask(sd, 0x2d, sd->ctrls[AUTOBRIGHT].val ? 0x10 : 0x00, 0x10);
4588} 4743}
4589 4744
4745static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
4746{
4747 struct sd *sd = (struct sd *) gspca_dev;
4748
4749 sd->ctrls[AUTOGAIN].val = val;
4750 if (val) {
4751 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
4752 } else {
4753 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
4754 sd->ctrls[EXPOSURE].val = i2c_r(sd, 0x10);
4755 }
4756 if (gspca_dev->streaming)
4757 setautogain(gspca_dev);
4758 return gspca_dev->usb_err;
4759}
4760
4590static void setfreq_i(struct sd *sd) 4761static void setfreq_i(struct sd *sd)
4591{ 4762{
4592 if (sd->sensor == SEN_OV7660 4763 if (sd->sensor == SEN_OV7660
@@ -4731,6 +4902,7 @@ static const struct sd_desc sd_desc = {
4731 .nctrls = ARRAY_SIZE(sd_ctrls), 4902 .nctrls = ARRAY_SIZE(sd_ctrls),
4732 .config = sd_config, 4903 .config = sd_config,
4733 .init = sd_init, 4904 .init = sd_init,
4905 .isoc_init = sd_isoc_init,
4734 .start = sd_start, 4906 .start = sd_start,
4735 .stopN = sd_stopN, 4907 .stopN = sd_stopN,
4736 .stop0 = sd_stop0, 4908 .stop0 = sd_stop0,
diff --git a/drivers/media/video/gspca/ov534.c b/drivers/media/video/gspca/ov534.c
index 04da22802736..0c6369b7fe18 100644
--- a/drivers/media/video/gspca/ov534.c
+++ b/drivers/media/video/gspca/ov534.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * ov534-ov772x gspca driver 2 * ov534-ov7xxx gspca driver
3 * 3 *
4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2008 Antonio Ospite <ospite@studenti.unina.it>
5 * Copyright (C) 2008 Jim Paris <jim@jtan.com> 5 * Copyright (C) 2008 Jim Paris <jim@jtan.com>
@@ -49,54 +49,59 @@ MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
49MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver"); 49MODULE_DESCRIPTION("GSPCA/OV534 USB Camera Driver");
50MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
51 51
52/* controls */
53enum e_ctrl {
54 BRIGHTNESS,
55 CONTRAST,
56 GAIN,
57 EXPOSURE,
58 AGC,
59 AWB,
60 AEC,
61 SHARPNESS,
62 HFLIP,
63 VFLIP,
64 COLORS,
65 LIGHTFREQ,
66 NCTRLS /* number of controls */
67};
68
52/* specific webcam descriptor */ 69/* specific webcam descriptor */
53struct sd { 70struct sd {
54 struct gspca_dev gspca_dev; /* !! must be the first item */ 71 struct gspca_dev gspca_dev; /* !! must be the first item */
72
73 struct gspca_ctrl ctrls[NCTRLS];
74
55 __u32 last_pts; 75 __u32 last_pts;
56 u16 last_fid; 76 u16 last_fid;
57 u8 frame_rate; 77 u8 frame_rate;
58 78
59 u8 brightness; 79 u8 sensor;
60 u8 contrast; 80};
61 u8 gain; 81enum sensors {
62 u8 exposure; 82 SENSOR_OV767x,
63 u8 agc; 83 SENSOR_OV772x,
64 u8 awb; 84 NSENSORS
65 u8 aec;
66 s8 sharpness;
67 u8 hflip;
68 u8 vflip;
69 u8 freqfltr;
70}; 85};
71 86
72/* V4L2 controls supported by the driver */ 87/* V4L2 controls supported by the driver */
73static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 88static void setbrightness(struct gspca_dev *gspca_dev);
74static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val); 89static void setcontrast(struct gspca_dev *gspca_dev);
75static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val); 90static void setgain(struct gspca_dev *gspca_dev);
76static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val); 91static void setexposure(struct gspca_dev *gspca_dev);
77static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val); 92static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getagc(struct gspca_dev *gspca_dev, __s32 *val); 93static void setawb(struct gspca_dev *gspca_dev);
79static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val); 94static void setaec(struct gspca_dev *gspca_dev);
80static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val); 95static void setsharpness(struct gspca_dev *gspca_dev);
81static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val); 96static void sethvflip(struct gspca_dev *gspca_dev);
82static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val); 97static void setcolors(struct gspca_dev *gspca_dev);
83static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); 98static void setlightfreq(struct gspca_dev *gspca_dev);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); 99
85static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val); 100static int sd_start(struct gspca_dev *gspca_dev);
86static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val); 101static void sd_stopN(struct gspca_dev *gspca_dev);
87static int sd_setaec(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getaec(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setfreqfltr(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getfreqfltr(struct gspca_dev *gspca_dev, __s32 *val);
95static int sd_querymenu(struct gspca_dev *gspca_dev,
96 struct v4l2_querymenu *menu);
97 102
98static const struct ctrl sd_ctrls[] = { 103static const struct ctrl sd_ctrls[] = {
99 { /* 0 */ 104[BRIGHTNESS] = {
100 { 105 {
101 .id = V4L2_CID_BRIGHTNESS, 106 .id = V4L2_CID_BRIGHTNESS,
102 .type = V4L2_CTRL_TYPE_INTEGER, 107 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -104,13 +109,11 @@ static const struct ctrl sd_ctrls[] = {
104 .minimum = 0, 109 .minimum = 0,
105 .maximum = 255, 110 .maximum = 255,
106 .step = 1, 111 .step = 1,
107#define BRIGHTNESS_DEF 0 112 .default_value = 0,
108 .default_value = BRIGHTNESS_DEF,
109 }, 113 },
110 .set = sd_setbrightness, 114 .set_control = setbrightness
111 .get = sd_getbrightness,
112 }, 115 },
113 { /* 1 */ 116[CONTRAST] = {
114 { 117 {
115 .id = V4L2_CID_CONTRAST, 118 .id = V4L2_CID_CONTRAST,
116 .type = V4L2_CTRL_TYPE_INTEGER, 119 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -118,13 +121,11 @@ static const struct ctrl sd_ctrls[] = {
118 .minimum = 0, 121 .minimum = 0,
119 .maximum = 255, 122 .maximum = 255,
120 .step = 1, 123 .step = 1,
121#define CONTRAST_DEF 32 124 .default_value = 32,
122 .default_value = CONTRAST_DEF,
123 }, 125 },
124 .set = sd_setcontrast, 126 .set_control = setcontrast
125 .get = sd_getcontrast,
126 }, 127 },
127 { /* 2 */ 128[GAIN] = {
128 { 129 {
129 .id = V4L2_CID_GAIN, 130 .id = V4L2_CID_GAIN,
130 .type = V4L2_CTRL_TYPE_INTEGER, 131 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -132,13 +133,11 @@ static const struct ctrl sd_ctrls[] = {
132 .minimum = 0, 133 .minimum = 0,
133 .maximum = 63, 134 .maximum = 63,
134 .step = 1, 135 .step = 1,
135#define GAIN_DEF 20 136 .default_value = 20,
136 .default_value = GAIN_DEF,
137 }, 137 },
138 .set = sd_setgain, 138 .set_control = setgain
139 .get = sd_getgain,
140 }, 139 },
141 { /* 3 */ 140[EXPOSURE] = {
142 { 141 {
143 .id = V4L2_CID_EXPOSURE, 142 .id = V4L2_CID_EXPOSURE,
144 .type = V4L2_CTRL_TYPE_INTEGER, 143 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -146,13 +145,11 @@ static const struct ctrl sd_ctrls[] = {
146 .minimum = 0, 145 .minimum = 0,
147 .maximum = 255, 146 .maximum = 255,
148 .step = 1, 147 .step = 1,
149#define EXPO_DEF 120 148 .default_value = 120,
150 .default_value = EXPO_DEF,
151 }, 149 },
152 .set = sd_setexposure, 150 .set_control = setexposure
153 .get = sd_getexposure,
154 }, 151 },
155 { /* 4 */ 152[AGC] = {
156 { 153 {
157 .id = V4L2_CID_AUTOGAIN, 154 .id = V4L2_CID_AUTOGAIN,
158 .type = V4L2_CTRL_TYPE_BOOLEAN, 155 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -160,14 +157,11 @@ static const struct ctrl sd_ctrls[] = {
160 .minimum = 0, 157 .minimum = 0,
161 .maximum = 1, 158 .maximum = 1,
162 .step = 1, 159 .step = 1,
163#define AGC_DEF 1 160 .default_value = 1,
164 .default_value = AGC_DEF,
165 }, 161 },
166 .set = sd_setagc, 162 .set = sd_setagc
167 .get = sd_getagc,
168 }, 163 },
169#define AWB_IDX 5 164[AWB] = {
170 { /* 5 */
171 { 165 {
172 .id = V4L2_CID_AUTO_WHITE_BALANCE, 166 .id = V4L2_CID_AUTO_WHITE_BALANCE,
173 .type = V4L2_CTRL_TYPE_BOOLEAN, 167 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -175,13 +169,11 @@ static const struct ctrl sd_ctrls[] = {
175 .minimum = 0, 169 .minimum = 0,
176 .maximum = 1, 170 .maximum = 1,
177 .step = 1, 171 .step = 1,
178#define AWB_DEF 1 172 .default_value = 1,
179 .default_value = AWB_DEF,
180 }, 173 },
181 .set = sd_setawb, 174 .set_control = setawb
182 .get = sd_getawb,
183 }, 175 },
184 { /* 6 */ 176[AEC] = {
185 { 177 {
186 .id = V4L2_CID_EXPOSURE_AUTO, 178 .id = V4L2_CID_EXPOSURE_AUTO,
187 .type = V4L2_CTRL_TYPE_BOOLEAN, 179 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -189,13 +181,11 @@ static const struct ctrl sd_ctrls[] = {
189 .minimum = 0, 181 .minimum = 0,
190 .maximum = 1, 182 .maximum = 1,
191 .step = 1, 183 .step = 1,
192#define AEC_DEF 1 184 .default_value = 1,
193 .default_value = AEC_DEF,
194 }, 185 },
195 .set = sd_setaec, 186 .set_control = setaec
196 .get = sd_getaec,
197 }, 187 },
198 { /* 7 */ 188[SHARPNESS] = {
199 { 189 {
200 .id = V4L2_CID_SHARPNESS, 190 .id = V4L2_CID_SHARPNESS,
201 .type = V4L2_CTRL_TYPE_INTEGER, 191 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -203,13 +193,11 @@ static const struct ctrl sd_ctrls[] = {
203 .minimum = 0, 193 .minimum = 0,
204 .maximum = 63, 194 .maximum = 63,
205 .step = 1, 195 .step = 1,
206#define SHARPNESS_DEF 0 196 .default_value = 0,
207 .default_value = SHARPNESS_DEF,
208 }, 197 },
209 .set = sd_setsharpness, 198 .set_control = setsharpness
210 .get = sd_getsharpness,
211 }, 199 },
212 { /* 8 */ 200[HFLIP] = {
213 { 201 {
214 .id = V4L2_CID_HFLIP, 202 .id = V4L2_CID_HFLIP,
215 .type = V4L2_CTRL_TYPE_BOOLEAN, 203 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -217,13 +205,11 @@ static const struct ctrl sd_ctrls[] = {
217 .minimum = 0, 205 .minimum = 0,
218 .maximum = 1, 206 .maximum = 1,
219 .step = 1, 207 .step = 1,
220#define HFLIP_DEF 0 208 .default_value = 0,
221 .default_value = HFLIP_DEF,
222 }, 209 },
223 .set = sd_sethflip, 210 .set_control = sethvflip
224 .get = sd_gethflip,
225 }, 211 },
226 { /* 9 */ 212[VFLIP] = {
227 { 213 {
228 .id = V4L2_CID_VFLIP, 214 .id = V4L2_CID_VFLIP,
229 .type = V4L2_CTRL_TYPE_BOOLEAN, 215 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -231,13 +217,23 @@ static const struct ctrl sd_ctrls[] = {
231 .minimum = 0, 217 .minimum = 0,
232 .maximum = 1, 218 .maximum = 1,
233 .step = 1, 219 .step = 1,
234#define VFLIP_DEF 0 220 .default_value = 0,
235 .default_value = VFLIP_DEF,
236 }, 221 },
237 .set = sd_setvflip, 222 .set_control = sethvflip
238 .get = sd_getvflip,
239 }, 223 },
240 { /* 10 */ 224[COLORS] = {
225 {
226 .id = V4L2_CID_SATURATION,
227 .type = V4L2_CTRL_TYPE_INTEGER,
228 .name = "Saturation",
229 .minimum = 0,
230 .maximum = 6,
231 .step = 1,
232 .default_value = 3,
233 },
234 .set_control = setcolors
235 },
236[LIGHTFREQ] = {
241 { 237 {
242 .id = V4L2_CID_POWER_LINE_FREQUENCY, 238 .id = V4L2_CID_POWER_LINE_FREQUENCY,
243 .type = V4L2_CTRL_TYPE_MENU, 239 .type = V4L2_CTRL_TYPE_MENU,
@@ -245,11 +241,9 @@ static const struct ctrl sd_ctrls[] = {
245 .minimum = 0, 241 .minimum = 0,
246 .maximum = 1, 242 .maximum = 1,
247 .step = 1, 243 .step = 1,
248#define FREQFLTR_DEF 0 244 .default_value = 0,
249 .default_value = FREQFLTR_DEF,
250 }, 245 },
251 .set = sd_setfreqfltr, 246 .set_control = setlightfreq
252 .get = sd_getfreqfltr,
253 }, 247 },
254}; 248};
255 249
@@ -265,6 +259,16 @@ static const struct v4l2_pix_format ov772x_mode[] = {
265 .colorspace = V4L2_COLORSPACE_SRGB, 259 .colorspace = V4L2_COLORSPACE_SRGB,
266 .priv = 0}, 260 .priv = 0},
267}; 261};
262static const struct v4l2_pix_format ov767x_mode[] = {
263 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
264 .bytesperline = 320,
265 .sizeimage = 320 * 240 * 3 / 8 + 590,
266 .colorspace = V4L2_COLORSPACE_JPEG},
267 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
268 .bytesperline = 640,
269 .sizeimage = 640 * 480 * 3 / 8 + 590,
270 .colorspace = V4L2_COLORSPACE_JPEG},
271};
268 272
269static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30}; 273static const u8 qvga_rates[] = {125, 100, 75, 60, 50, 40, 30};
270static const u8 vga_rates[] = {60, 50, 40, 30, 15}; 274static const u8 vga_rates[] = {60, 50, 40, 30, 15};
@@ -280,7 +284,288 @@ static const struct framerates ov772x_framerates[] = {
280 }, 284 },
281}; 285};
282 286
283static const u8 bridge_init[][2] = { 287struct reg_array {
288 const u8 (*val)[2];
289 int len;
290};
291
292static const u8 bridge_init_767x[][2] = {
293/* comments from the ms-win file apollo7670.set */
294/* str1 */
295 {0xf1, 0x42},
296 {0x88, 0xf8},
297 {0x89, 0xff},
298 {0x76, 0x03},
299 {0x92, 0x03},
300 {0x95, 0x10},
301 {0xe2, 0x00},
302 {0xe7, 0x3e},
303 {0x8d, 0x1c},
304 {0x8e, 0x00},
305 {0x8f, 0x00},
306 {0x1f, 0x00},
307 {0xc3, 0xf9},
308 {0x89, 0xff},
309 {0x88, 0xf8},
310 {0x76, 0x03},
311 {0x92, 0x01},
312 {0x93, 0x18},
313 {0x1c, 0x00},
314 {0x1d, 0x48},
315 {0x1d, 0x00},
316 {0x1d, 0xff},
317 {0x1d, 0x02},
318 {0x1d, 0x58},
319 {0x1d, 0x00},
320 {0x1c, 0x0a},
321 {0x1d, 0x0a},
322 {0x1d, 0x0e},
323 {0xc0, 0x50}, /* HSize 640 */
324 {0xc1, 0x3c}, /* VSize 480 */
325 {0x34, 0x05}, /* enable Audio Suspend mode */
326 {0xc2, 0x0c}, /* Input YUV */
327 {0xc3, 0xf9}, /* enable PRE */
328 {0x34, 0x05}, /* enable Audio Suspend mode */
329 {0xe7, 0x2e}, /* this solves failure of "SuspendResumeTest" */
330 {0x31, 0xf9}, /* enable 1.8V Suspend */
331 {0x35, 0x02}, /* turn on JPEG */
332 {0xd9, 0x10},
333 {0x25, 0x42}, /* GPIO[8]:Input */
334 {0x94, 0x11}, /* If the default setting is loaded when
335 * system boots up, this flag is closed here */
336};
337static const u8 sensor_init_767x[][2] = {
338 {0x12, 0x80},
339 {0x11, 0x03},
340 {0x3a, 0x04},
341 {0x12, 0x00},
342 {0x17, 0x13},
343 {0x18, 0x01},
344 {0x32, 0xb6},
345 {0x19, 0x02},
346 {0x1a, 0x7a},
347 {0x03, 0x0a},
348 {0x0c, 0x00},
349 {0x3e, 0x00},
350 {0x70, 0x3a},
351 {0x71, 0x35},
352 {0x72, 0x11},
353 {0x73, 0xf0},
354 {0xa2, 0x02},
355 {0x7a, 0x2a}, /* set Gamma=1.6 below */
356 {0x7b, 0x12},
357 {0x7c, 0x1d},
358 {0x7d, 0x2d},
359 {0x7e, 0x45},
360 {0x7f, 0x50},
361 {0x80, 0x59},
362 {0x81, 0x62},
363 {0x82, 0x6b},
364 {0x83, 0x73},
365 {0x84, 0x7b},
366 {0x85, 0x8a},
367 {0x86, 0x98},
368 {0x87, 0xb2},
369 {0x88, 0xca},
370 {0x89, 0xe0},
371 {0x13, 0xe0},
372 {0x00, 0x00},
373 {0x10, 0x00},
374 {0x0d, 0x40},
375 {0x14, 0x38}, /* gain max 16x */
376 {0xa5, 0x05},
377 {0xab, 0x07},
378 {0x24, 0x95},
379 {0x25, 0x33},
380 {0x26, 0xe3},
381 {0x9f, 0x78},
382 {0xa0, 0x68},
383 {0xa1, 0x03},
384 {0xa6, 0xd8},
385 {0xa7, 0xd8},
386 {0xa8, 0xf0},
387 {0xa9, 0x90},
388 {0xaa, 0x94},
389 {0x13, 0xe5},
390 {0x0e, 0x61},
391 {0x0f, 0x4b},
392 {0x16, 0x02},
393 {0x21, 0x02},
394 {0x22, 0x91},
395 {0x29, 0x07},
396 {0x33, 0x0b},
397 {0x35, 0x0b},
398 {0x37, 0x1d},
399 {0x38, 0x71},
400 {0x39, 0x2a},
401 {0x3c, 0x78},
402 {0x4d, 0x40},
403 {0x4e, 0x20},
404 {0x69, 0x00},
405 {0x6b, 0x4a},
406 {0x74, 0x10},
407 {0x8d, 0x4f},
408 {0x8e, 0x00},
409 {0x8f, 0x00},
410 {0x90, 0x00},
411 {0x91, 0x00},
412 {0x96, 0x00},
413 {0x9a, 0x80},
414 {0xb0, 0x84},
415 {0xb1, 0x0c},
416 {0xb2, 0x0e},
417 {0xb3, 0x82},
418 {0xb8, 0x0a},
419 {0x43, 0x0a},
420 {0x44, 0xf0},
421 {0x45, 0x34},
422 {0x46, 0x58},
423 {0x47, 0x28},
424 {0x48, 0x3a},
425 {0x59, 0x88},
426 {0x5a, 0x88},
427 {0x5b, 0x44},
428 {0x5c, 0x67},
429 {0x5d, 0x49},
430 {0x5e, 0x0e},
431 {0x6c, 0x0a},
432 {0x6d, 0x55},
433 {0x6e, 0x11},
434 {0x6f, 0x9f},
435 {0x6a, 0x40},
436 {0x01, 0x40},
437 {0x02, 0x40},
438 {0x13, 0xe7},
439 {0x4f, 0x80},
440 {0x50, 0x80},
441 {0x51, 0x00},
442 {0x52, 0x22},
443 {0x53, 0x5e},
444 {0x54, 0x80},
445 {0x58, 0x9e},
446 {0x41, 0x08},
447 {0x3f, 0x00},
448 {0x75, 0x04},
449 {0x76, 0xe1},
450 {0x4c, 0x00},
451 {0x77, 0x01},
452 {0x3d, 0xc2},
453 {0x4b, 0x09},
454 {0xc9, 0x60},
455 {0x41, 0x38}, /* jfm: auto sharpness + auto de-noise */
456 {0x56, 0x40},
457 {0x34, 0x11},
458 {0x3b, 0xc2},
459 {0xa4, 0x8a}, /* Night mode trigger point */
460 {0x96, 0x00},
461 {0x97, 0x30},
462 {0x98, 0x20},
463 {0x99, 0x20},
464 {0x9a, 0x84},
465 {0x9b, 0x29},
466 {0x9c, 0x03},
467 {0x9d, 0x4c},
468 {0x9e, 0x3f},
469 {0x78, 0x04},
470 {0x79, 0x01},
471 {0xc8, 0xf0},
472 {0x79, 0x0f},
473 {0xc8, 0x00},
474 {0x79, 0x10},
475 {0xc8, 0x7e},
476 {0x79, 0x0a},
477 {0xc8, 0x80},
478 {0x79, 0x0b},
479 {0xc8, 0x01},
480 {0x79, 0x0c},
481 {0xc8, 0x0f},
482 {0x79, 0x0d},
483 {0xc8, 0x20},
484 {0x79, 0x09},
485 {0xc8, 0x80},
486 {0x79, 0x02},
487 {0xc8, 0xc0},
488 {0x79, 0x03},
489 {0xc8, 0x20},
490 {0x79, 0x26},
491};
492static const u8 bridge_start_vga_767x[][2] = {
493/* str59 JPG */
494 {0x94, 0xaa},
495 {0xf1, 0x42},
496 {0xe5, 0x04},
497 {0xc0, 0x50},
498 {0xc1, 0x3c},
499 {0xc2, 0x0c},
500 {0x35, 0x02}, /* turn on JPEG */
501 {0xd9, 0x10},
502 {0xda, 0x00}, /* for higher clock rate(30fps) */
503 {0x34, 0x05}, /* enable Audio Suspend mode */
504 {0xc3, 0xf9}, /* enable PRE */
505 {0x8c, 0x00}, /* CIF VSize LSB[2:0] */
506 {0x8d, 0x1c}, /* output YUV */
507/* {0x34, 0x05}, * enable Audio Suspend mode (?) */
508 {0x50, 0x00}, /* H/V divider=0 */
509 {0x51, 0xa0}, /* input H=640/4 */
510 {0x52, 0x3c}, /* input V=480/4 */
511 {0x53, 0x00}, /* offset X=0 */
512 {0x54, 0x00}, /* offset Y=0 */
513 {0x55, 0x00}, /* H/V size[8]=0 */
514 {0x57, 0x00}, /* H-size[9]=0 */
515 {0x5c, 0x00}, /* output size[9:8]=0 */
516 {0x5a, 0xa0}, /* output H=640/4 */
517 {0x5b, 0x78}, /* output V=480/4 */
518 {0x1c, 0x0a},
519 {0x1d, 0x0a},
520 {0x94, 0x11},
521};
522static const u8 sensor_start_vga_767x[][2] = {
523 {0x11, 0x01},
524 {0x1e, 0x04},
525 {0x19, 0x02},
526 {0x1a, 0x7a},
527};
528static const u8 bridge_start_qvga_767x[][2] = {
529/* str86 JPG */
530 {0x94, 0xaa},
531 {0xf1, 0x42},
532 {0xe5, 0x04},
533 {0xc0, 0x80},
534 {0xc1, 0x60},
535 {0xc2, 0x0c},
536 {0x35, 0x02}, /* turn on JPEG */
537 {0xd9, 0x10},
538 {0xc0, 0x50}, /* CIF HSize 640 */
539 {0xc1, 0x3c}, /* CIF VSize 480 */
540 {0x8c, 0x00}, /* CIF VSize LSB[2:0] */
541 {0x8d, 0x1c}, /* output YUV */
542 {0x34, 0x05}, /* enable Audio Suspend mode */
543 {0xc2, 0x4c}, /* output YUV and Enable DCW */
544 {0xc3, 0xf9}, /* enable PRE */
545 {0x1c, 0x00}, /* indirect addressing */
546 {0x1d, 0x48}, /* output YUV422 */
547 {0x50, 0x89}, /* H/V divider=/2; plus DCW AVG */
548 {0x51, 0xa0}, /* DCW input H=640/4 */
549 {0x52, 0x78}, /* DCW input V=480/4 */
550 {0x53, 0x00}, /* offset X=0 */
551 {0x54, 0x00}, /* offset Y=0 */
552 {0x55, 0x00}, /* H/V size[8]=0 */
553 {0x57, 0x00}, /* H-size[9]=0 */
554 {0x5c, 0x00}, /* DCW output size[9:8]=0 */
555 {0x5a, 0x50}, /* DCW output H=320/4 */
556 {0x5b, 0x3c}, /* DCW output V=240/4 */
557 {0x1c, 0x0a},
558 {0x1d, 0x0a},
559 {0x94, 0x11},
560};
561static const u8 sensor_start_qvga_767x[][2] = {
562 {0x11, 0x01},
563 {0x1e, 0x04},
564 {0x19, 0x02},
565 {0x1a, 0x7a},
566};
567
568static const u8 bridge_init_772x[][2] = {
284 { 0xc2, 0x0c }, 569 { 0xc2, 0x0c },
285 { 0x88, 0xf8 }, 570 { 0x88, 0xf8 },
286 { 0xc3, 0x69 }, 571 { 0xc3, 0x69 },
@@ -338,7 +623,7 @@ static const u8 bridge_init[][2] = {
338 { 0xc1, 0x3c }, 623 { 0xc1, 0x3c },
339 { 0xc2, 0x0c }, 624 { 0xc2, 0x0c },
340}; 625};
341static const u8 sensor_init[][2] = { 626static const u8 sensor_init_772x[][2] = {
342 { 0x12, 0x80 }, 627 { 0x12, 0x80 },
343 { 0x11, 0x01 }, 628 { 0x11, 0x01 },
344/*fixme: better have a delay?*/ 629/*fixme: better have a delay?*/
@@ -431,7 +716,7 @@ static const u8 sensor_init[][2] = {
431 { 0x8e, 0x00 }, /* De-noise threshold */ 716 { 0x8e, 0x00 }, /* De-noise threshold */
432 { 0x0c, 0xd0 } 717 { 0x0c, 0xd0 }
433}; 718};
434static const u8 bridge_start_vga[][2] = { 719static const u8 bridge_start_vga_772x[][2] = {
435 {0x1c, 0x00}, 720 {0x1c, 0x00},
436 {0x1d, 0x40}, 721 {0x1d, 0x40},
437 {0x1d, 0x02}, 722 {0x1d, 0x02},
@@ -442,7 +727,7 @@ static const u8 bridge_start_vga[][2] = {
442 {0xc0, 0x50}, 727 {0xc0, 0x50},
443 {0xc1, 0x3c}, 728 {0xc1, 0x3c},
444}; 729};
445static const u8 sensor_start_vga[][2] = { 730static const u8 sensor_start_vga_772x[][2] = {
446 {0x12, 0x00}, 731 {0x12, 0x00},
447 {0x17, 0x26}, 732 {0x17, 0x26},
448 {0x18, 0xa0}, 733 {0x18, 0xa0},
@@ -452,7 +737,7 @@ static const u8 sensor_start_vga[][2] = {
452 {0x2c, 0xf0}, 737 {0x2c, 0xf0},
453 {0x65, 0x20}, 738 {0x65, 0x20},
454}; 739};
455static const u8 bridge_start_qvga[][2] = { 740static const u8 bridge_start_qvga_772x[][2] = {
456 {0x1c, 0x00}, 741 {0x1c, 0x00},
457 {0x1d, 0x40}, 742 {0x1d, 0x40},
458 {0x1d, 0x02}, 743 {0x1d, 0x02},
@@ -463,7 +748,7 @@ static const u8 bridge_start_qvga[][2] = {
463 {0xc0, 0x28}, 748 {0xc0, 0x28},
464 {0xc1, 0x1e}, 749 {0xc1, 0x1e},
465}; 750};
466static const u8 sensor_start_qvga[][2] = { 751static const u8 sensor_start_qvga_772x[][2] = {
467 {0x12, 0x40}, 752 {0x12, 0x40},
468 {0x17, 0x3f}, 753 {0x17, 0x3f},
469 {0x18, 0x50}, 754 {0x18, 0x50},
@@ -646,6 +931,8 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
646 {30, 0x04, 0x41, 0x04}, 931 {30, 0x04, 0x41, 0x04},
647 }; 932 };
648 933
934 if (sd->sensor != SENSOR_OV772x)
935 return;
649 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) { 936 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv == 0) {
650 r = rate_0; 937 r = rate_0;
651 i = ARRAY_SIZE(rate_0); 938 i = ARRAY_SIZE(rate_0);
@@ -669,15 +956,28 @@ static void set_frame_rate(struct gspca_dev *gspca_dev)
669static void setbrightness(struct gspca_dev *gspca_dev) 956static void setbrightness(struct gspca_dev *gspca_dev)
670{ 957{
671 struct sd *sd = (struct sd *) gspca_dev; 958 struct sd *sd = (struct sd *) gspca_dev;
959 int val;
672 960
673 sccb_reg_write(gspca_dev, 0x9b, sd->brightness); 961 val = sd->ctrls[BRIGHTNESS].val;
962 if (sd->sensor == SENSOR_OV767x) {
963 if (val < 0)
964 val = 0x80 - val;
965 sccb_reg_write(gspca_dev, 0x55, val); /* bright */
966 } else {
967 sccb_reg_write(gspca_dev, 0x9b, val);
968 }
674} 969}
675 970
676static void setcontrast(struct gspca_dev *gspca_dev) 971static void setcontrast(struct gspca_dev *gspca_dev)
677{ 972{
678 struct sd *sd = (struct sd *) gspca_dev; 973 struct sd *sd = (struct sd *) gspca_dev;
974 u8 val;
679 975
680 sccb_reg_write(gspca_dev, 0x9c, sd->contrast); 976 val = sd->ctrls[CONTRAST].val;
977 if (sd->sensor == SENSOR_OV767x)
978 sccb_reg_write(gspca_dev, 0x56, val); /* contras */
979 else
980 sccb_reg_write(gspca_dev, 0x9c, val);
681} 981}
682 982
683static void setgain(struct gspca_dev *gspca_dev) 983static void setgain(struct gspca_dev *gspca_dev)
@@ -685,10 +985,10 @@ static void setgain(struct gspca_dev *gspca_dev)
685 struct sd *sd = (struct sd *) gspca_dev; 985 struct sd *sd = (struct sd *) gspca_dev;
686 u8 val; 986 u8 val;
687 987
688 if (sd->agc) 988 if (sd->ctrls[AGC].val)
689 return; 989 return;
690 990
691 val = sd->gain; 991 val = sd->ctrls[GAIN].val;
692 switch (val & 0x30) { 992 switch (val & 0x30) {
693 case 0x00: 993 case 0x00:
694 val &= 0x0f; 994 val &= 0x0f;
@@ -715,25 +1015,32 @@ static void setexposure(struct gspca_dev *gspca_dev)
715 struct sd *sd = (struct sd *) gspca_dev; 1015 struct sd *sd = (struct sd *) gspca_dev;
716 u8 val; 1016 u8 val;
717 1017
718 if (sd->aec) 1018 if (sd->ctrls[AEC].val)
719 return; 1019 return;
720 1020
721 /* 'val' is one byte and represents half of the exposure value we are 1021 val = sd->ctrls[EXPOSURE].val;
722 * going to set into registers, a two bytes value: 1022 if (sd->sensor == SENSOR_OV767x) {
723 * 1023
724 * MSB: ((u16) val << 1) >> 8 == val >> 7 1024 /* set only aec[9:2] */
725 * LSB: ((u16) val << 1) & 0xff == val << 1 1025 sccb_reg_write(gspca_dev, 0x10, val); /* aech */
726 */ 1026 } else {
727 val = sd->exposure; 1027
728 sccb_reg_write(gspca_dev, 0x08, val >> 7); 1028 /* 'val' is one byte and represents half of the exposure value
729 sccb_reg_write(gspca_dev, 0x10, val << 1); 1029 * we are going to set into registers, a two bytes value:
1030 *
1031 * MSB: ((u16) val << 1) >> 8 == val >> 7
1032 * LSB: ((u16) val << 1) & 0xff == val << 1
1033 */
1034 sccb_reg_write(gspca_dev, 0x08, val >> 7);
1035 sccb_reg_write(gspca_dev, 0x10, val << 1);
1036 }
730} 1037}
731 1038
732static void setagc(struct gspca_dev *gspca_dev) 1039static void setagc(struct gspca_dev *gspca_dev)
733{ 1040{
734 struct sd *sd = (struct sd *) gspca_dev; 1041 struct sd *sd = (struct sd *) gspca_dev;
735 1042
736 if (sd->agc) { 1043 if (sd->ctrls[AGC].val) {
737 sccb_reg_write(gspca_dev, 0x13, 1044 sccb_reg_write(gspca_dev, 0x13,
738 sccb_reg_read(gspca_dev, 0x13) | 0x04); 1045 sccb_reg_read(gspca_dev, 0x13) | 0x04);
739 sccb_reg_write(gspca_dev, 0x64, 1046 sccb_reg_write(gspca_dev, 0x64,
@@ -752,15 +1059,17 @@ static void setawb(struct gspca_dev *gspca_dev)
752{ 1059{
753 struct sd *sd = (struct sd *) gspca_dev; 1060 struct sd *sd = (struct sd *) gspca_dev;
754 1061
755 if (sd->awb) { 1062 if (sd->ctrls[AWB].val) {
756 sccb_reg_write(gspca_dev, 0x13, 1063 sccb_reg_write(gspca_dev, 0x13,
757 sccb_reg_read(gspca_dev, 0x13) | 0x02); 1064 sccb_reg_read(gspca_dev, 0x13) | 0x02);
758 sccb_reg_write(gspca_dev, 0x63, 1065 if (sd->sensor == SENSOR_OV772x)
1066 sccb_reg_write(gspca_dev, 0x63,
759 sccb_reg_read(gspca_dev, 0x63) | 0xc0); 1067 sccb_reg_read(gspca_dev, 0x63) | 0xc0);
760 } else { 1068 } else {
761 sccb_reg_write(gspca_dev, 0x13, 1069 sccb_reg_write(gspca_dev, 0x13,
762 sccb_reg_read(gspca_dev, 0x13) & ~0x02); 1070 sccb_reg_read(gspca_dev, 0x13) & ~0x02);
763 sccb_reg_write(gspca_dev, 0x63, 1071 if (sd->sensor == SENSOR_OV772x)
1072 sccb_reg_write(gspca_dev, 0x63,
764 sccb_reg_read(gspca_dev, 0x63) & ~0xc0); 1073 sccb_reg_read(gspca_dev, 0x63) & ~0xc0);
765 } 1074 }
766} 1075}
@@ -768,14 +1077,22 @@ static void setawb(struct gspca_dev *gspca_dev)
768static void setaec(struct gspca_dev *gspca_dev) 1077static void setaec(struct gspca_dev *gspca_dev)
769{ 1078{
770 struct sd *sd = (struct sd *) gspca_dev; 1079 struct sd *sd = (struct sd *) gspca_dev;
1080 u8 data;
771 1081
772 if (sd->aec) 1082 data = sd->sensor == SENSOR_OV767x ?
1083 0x05 : /* agc + aec */
1084 0x01; /* agc */
1085 if (sd->ctrls[AEC].val)
773 sccb_reg_write(gspca_dev, 0x13, 1086 sccb_reg_write(gspca_dev, 0x13,
774 sccb_reg_read(gspca_dev, 0x13) | 0x01); 1087 sccb_reg_read(gspca_dev, 0x13) | data);
775 else { 1088 else {
776 sccb_reg_write(gspca_dev, 0x13, 1089 sccb_reg_write(gspca_dev, 0x13,
777 sccb_reg_read(gspca_dev, 0x13) & ~0x01); 1090 sccb_reg_read(gspca_dev, 0x13) & ~data);
778 setexposure(gspca_dev); 1091 if (sd->sensor == SENSOR_OV767x)
1092 sd->ctrls[EXPOSURE].val =
1093 sccb_reg_read(gspca_dev, 10); /* aech */
1094 else
1095 setexposure(gspca_dev);
779 } 1096 }
780} 1097}
781 1098
@@ -784,43 +1101,67 @@ static void setsharpness(struct gspca_dev *gspca_dev)
784 struct sd *sd = (struct sd *) gspca_dev; 1101 struct sd *sd = (struct sd *) gspca_dev;
785 u8 val; 1102 u8 val;
786 1103
787 val = sd->sharpness; 1104 val = sd->ctrls[SHARPNESS].val;
788 sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */ 1105 sccb_reg_write(gspca_dev, 0x91, val); /* Auto de-noise threshold */
789 sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */ 1106 sccb_reg_write(gspca_dev, 0x8e, val); /* De-noise threshold */
790} 1107}
791 1108
792static void sethflip(struct gspca_dev *gspca_dev) 1109static void sethvflip(struct gspca_dev *gspca_dev)
793{ 1110{
794 struct sd *sd = (struct sd *) gspca_dev; 1111 struct sd *sd = (struct sd *) gspca_dev;
1112 u8 val;
795 1113
796 if (sd->hflip == 0) 1114 if (sd->sensor == SENSOR_OV767x) {
797 sccb_reg_write(gspca_dev, 0x0c, 1115 val = sccb_reg_read(gspca_dev, 0x1e); /* mvfp */
798 sccb_reg_read(gspca_dev, 0x0c) | 0x40); 1116 val &= ~0x30;
799 else 1117 if (sd->ctrls[HFLIP].val)
800 sccb_reg_write(gspca_dev, 0x0c, 1118 val |= 0x20;
801 sccb_reg_read(gspca_dev, 0x0c) & ~0x40); 1119 if (sd->ctrls[VFLIP].val)
1120 val |= 0x10;
1121 sccb_reg_write(gspca_dev, 0x1e, val);
1122 } else {
1123 val = sccb_reg_read(gspca_dev, 0x0c);
1124 val &= ~0xc0;
1125 if (sd->ctrls[HFLIP].val == 0)
1126 val |= 0x40;
1127 if (sd->ctrls[VFLIP].val == 0)
1128 val |= 0x80;
1129 sccb_reg_write(gspca_dev, 0x0c, val);
1130 }
802} 1131}
803 1132
804static void setvflip(struct gspca_dev *gspca_dev) 1133static void setcolors(struct gspca_dev *gspca_dev)
805{ 1134{
806 struct sd *sd = (struct sd *) gspca_dev; 1135 struct sd *sd = (struct sd *) gspca_dev;
1136 u8 val;
1137 int i;
1138 static u8 color_tb[][6] = {
1139 {0x42, 0x42, 0x00, 0x11, 0x30, 0x41},
1140 {0x52, 0x52, 0x00, 0x16, 0x3c, 0x52},
1141 {0x66, 0x66, 0x00, 0x1b, 0x4b, 0x66},
1142 {0x80, 0x80, 0x00, 0x22, 0x5e, 0x80},
1143 {0x9a, 0x9a, 0x00, 0x29, 0x71, 0x9a},
1144 {0xb8, 0xb8, 0x00, 0x31, 0x87, 0xb8},
1145 {0xdd, 0xdd, 0x00, 0x3b, 0xa2, 0xdd},
1146 };
807 1147
808 if (sd->vflip == 0) 1148 val = sd->ctrls[COLORS].val;
809 sccb_reg_write(gspca_dev, 0x0c, 1149 for (i = 0; i < ARRAY_SIZE(color_tb[0]); i++)
810 sccb_reg_read(gspca_dev, 0x0c) | 0x80); 1150 sccb_reg_write(gspca_dev, 0x4f + i, color_tb[val][i]);
811 else
812 sccb_reg_write(gspca_dev, 0x0c,
813 sccb_reg_read(gspca_dev, 0x0c) & ~0x80);
814} 1151}
815 1152
816static void setfreqfltr(struct gspca_dev *gspca_dev) 1153static void setlightfreq(struct gspca_dev *gspca_dev)
817{ 1154{
818 struct sd *sd = (struct sd *) gspca_dev; 1155 struct sd *sd = (struct sd *) gspca_dev;
1156 u8 val;
819 1157
820 if (sd->freqfltr == 0) 1158 val = sd->ctrls[LIGHTFREQ].val ? 0x9e : 0x00;
821 sccb_reg_write(gspca_dev, 0x2b, 0x00); 1159 if (sd->sensor == SENSOR_OV767x) {
822 else 1160 sccb_reg_write(gspca_dev, 0x2a, 0x00);
823 sccb_reg_write(gspca_dev, 0x2b, 0x9e); 1161 if (val)
1162 val = 0x9d; /* insert dummy to 25fps for 50Hz */
1163 }
1164 sccb_reg_write(gspca_dev, 0x2b, val);
824} 1165}
825 1166
826 1167
@@ -833,39 +1174,33 @@ static int sd_config(struct gspca_dev *gspca_dev,
833 1174
834 cam = &gspca_dev->cam; 1175 cam = &gspca_dev->cam;
835 1176
1177 cam->ctrls = sd->ctrls;
1178
1179 /* the auto white balance control works only when auto gain is set */
1180 if (sd_ctrls[AGC].qctrl.default_value == 0)
1181 gspca_dev->ctrl_inac |= (1 << AWB);
1182
836 cam->cam_mode = ov772x_mode; 1183 cam->cam_mode = ov772x_mode;
837 cam->nmodes = ARRAY_SIZE(ov772x_mode); 1184 cam->nmodes = ARRAY_SIZE(ov772x_mode);
838 cam->mode_framerates = ov772x_framerates;
839
840 cam->bulk = 1;
841 cam->bulk_size = 16384;
842 cam->bulk_nurbs = 2;
843 1185
844 sd->frame_rate = 30; 1186 sd->frame_rate = 30;
845 1187
846 sd->brightness = BRIGHTNESS_DEF;
847 sd->contrast = CONTRAST_DEF;
848 sd->gain = GAIN_DEF;
849 sd->exposure = EXPO_DEF;
850#if AGC_DEF != 0
851 sd->agc = AGC_DEF;
852#else
853 gspca_dev->ctrl_inac |= (1 << AWB_IDX);
854#endif
855 sd->awb = AWB_DEF;
856 sd->aec = AEC_DEF;
857 sd->sharpness = SHARPNESS_DEF;
858 sd->hflip = HFLIP_DEF;
859 sd->vflip = VFLIP_DEF;
860 sd->freqfltr = FREQFLTR_DEF;
861
862 return 0; 1188 return 0;
863} 1189}
864 1190
865/* this function is called at probe and resume time */ 1191/* this function is called at probe and resume time */
866static int sd_init(struct gspca_dev *gspca_dev) 1192static int sd_init(struct gspca_dev *gspca_dev)
867{ 1193{
1194 struct sd *sd = (struct sd *) gspca_dev;
868 u16 sensor_id; 1195 u16 sensor_id;
1196 static const struct reg_array bridge_init[NSENSORS] = {
1197 [SENSOR_OV767x] = {bridge_init_767x, ARRAY_SIZE(bridge_init_767x)},
1198 [SENSOR_OV772x] = {bridge_init_772x, ARRAY_SIZE(bridge_init_772x)},
1199 };
1200 static const struct reg_array sensor_init[NSENSORS] = {
1201 [SENSOR_OV767x] = {sensor_init_767x, ARRAY_SIZE(sensor_init_767x)},
1202 [SENSOR_OV772x] = {sensor_init_772x, ARRAY_SIZE(sensor_init_772x)},
1203 };
869 1204
870 /* reset bridge */ 1205 /* reset bridge */
871 ov534_reg_write(gspca_dev, 0xe7, 0x3a); 1206 ov534_reg_write(gspca_dev, 0xe7, 0x3a);
@@ -886,48 +1221,100 @@ static int sd_init(struct gspca_dev *gspca_dev)
886 sensor_id |= sccb_reg_read(gspca_dev, 0x0b); 1221 sensor_id |= sccb_reg_read(gspca_dev, 0x0b);
887 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id); 1222 PDEBUG(D_PROBE, "Sensor ID: %04x", sensor_id);
888 1223
1224 if ((sensor_id & 0xfff0) == 0x7670) {
1225 sd->sensor = SENSOR_OV767x;
1226 gspca_dev->ctrl_dis = (1 << GAIN) |
1227 (1 << AGC) |
1228 (1 << SHARPNESS); /* auto */
1229 sd->ctrls[BRIGHTNESS].min = -127;
1230 sd->ctrls[BRIGHTNESS].max = 127;
1231 sd->ctrls[BRIGHTNESS].def = 0;
1232 sd->ctrls[CONTRAST].max = 0x80;
1233 sd->ctrls[CONTRAST].def = 0x40;
1234 sd->ctrls[EXPOSURE].min = 0x08;
1235 sd->ctrls[EXPOSURE].max = 0x60;
1236 sd->ctrls[EXPOSURE].def = 0x13;
1237 sd->ctrls[SHARPNESS].max = 9;
1238 sd->ctrls[SHARPNESS].def = 4;
1239 sd->ctrls[HFLIP].def = 1;
1240 gspca_dev->cam.cam_mode = ov767x_mode;
1241 gspca_dev->cam.nmodes = ARRAY_SIZE(ov767x_mode);
1242 } else {
1243 sd->sensor = SENSOR_OV772x;
1244 gspca_dev->ctrl_dis = (1 << COLORS);
1245 gspca_dev->cam.bulk = 1;
1246 gspca_dev->cam.bulk_size = 16384;
1247 gspca_dev->cam.bulk_nurbs = 2;
1248 gspca_dev->cam.mode_framerates = ov772x_framerates;
1249 }
1250
889 /* initialize */ 1251 /* initialize */
890 reg_w_array(gspca_dev, bridge_init, 1252 reg_w_array(gspca_dev, bridge_init[sd->sensor].val,
891 ARRAY_SIZE(bridge_init)); 1253 bridge_init[sd->sensor].len);
892 ov534_set_led(gspca_dev, 1); 1254 ov534_set_led(gspca_dev, 1);
893 sccb_w_array(gspca_dev, sensor_init, 1255 sccb_w_array(gspca_dev, sensor_init[sd->sensor].val,
894 ARRAY_SIZE(sensor_init)); 1256 sensor_init[sd->sensor].len);
895 ov534_reg_write(gspca_dev, 0xe0, 0x09); 1257 if (sd->sensor == SENSOR_OV767x)
896 ov534_set_led(gspca_dev, 0); 1258 sd_start(gspca_dev);
897 set_frame_rate(gspca_dev); 1259 sd_stopN(gspca_dev);
1260/* set_frame_rate(gspca_dev); */
898 1261
899 return gspca_dev->usb_err; 1262 return gspca_dev->usb_err;
900} 1263}
901 1264
902static int sd_start(struct gspca_dev *gspca_dev) 1265static int sd_start(struct gspca_dev *gspca_dev)
903{ 1266{
1267 struct sd *sd = (struct sd *) gspca_dev;
904 int mode; 1268 int mode;
1269 static const struct reg_array bridge_start[NSENSORS][2] = {
1270 [SENSOR_OV767x] = {{bridge_start_qvga_767x,
1271 ARRAY_SIZE(bridge_start_qvga_767x)},
1272 {bridge_start_vga_767x,
1273 ARRAY_SIZE(bridge_start_vga_767x)}},
1274 [SENSOR_OV772x] = {{bridge_start_qvga_772x,
1275 ARRAY_SIZE(bridge_start_qvga_772x)},
1276 {bridge_start_vga_772x,
1277 ARRAY_SIZE(bridge_start_vga_772x)}},
1278 };
1279 static const struct reg_array sensor_start[NSENSORS][2] = {
1280 [SENSOR_OV767x] = {{sensor_start_qvga_767x,
1281 ARRAY_SIZE(sensor_start_qvga_767x)},
1282 {sensor_start_vga_767x,
1283 ARRAY_SIZE(sensor_start_vga_767x)}},
1284 [SENSOR_OV772x] = {{sensor_start_qvga_772x,
1285 ARRAY_SIZE(sensor_start_qvga_772x)},
1286 {sensor_start_vga_772x,
1287 ARRAY_SIZE(sensor_start_vga_772x)}},
1288 };
1289
1290 /* (from ms-win trace) */
1291 if (sd->sensor == SENSOR_OV767x)
1292 sccb_reg_write(gspca_dev, 0x1e, 0x04);
1293 /* black sun enable ? */
1294
1295 mode = gspca_dev->curr_mode; /* 0: 320x240, 1: 640x480 */
1296 reg_w_array(gspca_dev, bridge_start[sd->sensor][mode].val,
1297 bridge_start[sd->sensor][mode].len);
1298 sccb_w_array(gspca_dev, sensor_start[sd->sensor][mode].val,
1299 sensor_start[sd->sensor][mode].len);
905 1300
906 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
907 if (mode != 0) { /* 320x240 */
908 reg_w_array(gspca_dev, bridge_start_qvga,
909 ARRAY_SIZE(bridge_start_qvga));
910 sccb_w_array(gspca_dev, sensor_start_qvga,
911 ARRAY_SIZE(sensor_start_qvga));
912 } else { /* 640x480 */
913 reg_w_array(gspca_dev, bridge_start_vga,
914 ARRAY_SIZE(bridge_start_vga));
915 sccb_w_array(gspca_dev, sensor_start_vga,
916 ARRAY_SIZE(sensor_start_vga));
917 }
918 set_frame_rate(gspca_dev); 1301 set_frame_rate(gspca_dev);
919 1302
920 setagc(gspca_dev); 1303 if (!(gspca_dev->ctrl_dis & (1 << AGC)))
1304 setagc(gspca_dev);
921 setawb(gspca_dev); 1305 setawb(gspca_dev);
922 setaec(gspca_dev); 1306 setaec(gspca_dev);
923 setgain(gspca_dev); 1307 if (!(gspca_dev->ctrl_dis & (1 << GAIN)))
1308 setgain(gspca_dev);
924 setexposure(gspca_dev); 1309 setexposure(gspca_dev);
925 setbrightness(gspca_dev); 1310 setbrightness(gspca_dev);
926 setcontrast(gspca_dev); 1311 setcontrast(gspca_dev);
927 setsharpness(gspca_dev); 1312 if (!(gspca_dev->ctrl_dis & (1 << SHARPNESS)))
928 setvflip(gspca_dev); 1313 setsharpness(gspca_dev);
929 sethflip(gspca_dev); 1314 sethvflip(gspca_dev);
930 setfreqfltr(gspca_dev); 1315 if (!(gspca_dev->ctrl_dis & (1 << COLORS)))
1316 setcolors(gspca_dev);
1317 setlightfreq(gspca_dev);
931 1318
932 ov534_set_led(gspca_dev, 1); 1319 ov534_set_led(gspca_dev, 1);
933 ov534_reg_write(gspca_dev, 0xe0, 0x00); 1320 ov534_reg_write(gspca_dev, 0xe0, 0x00);
@@ -957,9 +1344,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
957 __u32 this_pts; 1344 __u32 this_pts;
958 u16 this_fid; 1345 u16 this_fid;
959 int remaining_len = len; 1346 int remaining_len = len;
1347 int payload_len;
960 1348
1349 payload_len = gspca_dev->cam.bulk ? 2048 : 2040;
961 do { 1350 do {
962 len = min(remaining_len, 2048); 1351 len = min(remaining_len, payload_len);
963 1352
964 /* Payloads are prefixed with a UVC-style header. We 1353 /* Payloads are prefixed with a UVC-style header. We
965 consider a frame to start when the FID toggles, or the PTS 1354 consider a frame to start when the FID toggles, or the PTS
@@ -999,8 +1388,9 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
999 /* If this packet is marked as EOF, end the frame */ 1388 /* If this packet is marked as EOF, end the frame */
1000 } else if (data[1] & UVC_STREAM_EOF) { 1389 } else if (data[1] & UVC_STREAM_EOF) {
1001 sd->last_pts = 0; 1390 sd->last_pts = 0;
1002 if (gspca_dev->image_len + len - 12 != 1391 if (gspca_dev->pixfmt == V4L2_PIX_FMT_YUYV
1003 gspca_dev->width * gspca_dev->height * 2) { 1392 && gspca_dev->image_len + len - 12 !=
1393 gspca_dev->width * gspca_dev->height * 2) {
1004 PDEBUG(D_PACK, "wrong sized frame"); 1394 PDEBUG(D_PACK, "wrong sized frame");
1005 goto discard; 1395 goto discard;
1006 } 1396 }
@@ -1026,212 +1416,27 @@ scan_next:
1026 } while (remaining_len > 0); 1416 } while (remaining_len > 0);
1027} 1417}
1028 1418
1029/* controls */
1030static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1031{
1032 struct sd *sd = (struct sd *) gspca_dev;
1033
1034 sd->gain = val;
1035 if (gspca_dev->streaming)
1036 setgain(gspca_dev);
1037 return 0;
1038}
1039
1040static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1041{
1042 struct sd *sd = (struct sd *) gspca_dev;
1043
1044 *val = sd->gain;
1045 return 0;
1046}
1047
1048static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1049{
1050 struct sd *sd = (struct sd *) gspca_dev;
1051
1052 sd->exposure = val;
1053 if (gspca_dev->streaming)
1054 setexposure(gspca_dev);
1055 return 0;
1056}
1057
1058static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1059{
1060 struct sd *sd = (struct sd *) gspca_dev;
1061
1062 *val = sd->exposure;
1063 return 0;
1064}
1065
1066static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1067{
1068 struct sd *sd = (struct sd *) gspca_dev;
1069
1070 sd->brightness = val;
1071 if (gspca_dev->streaming)
1072 setbrightness(gspca_dev);
1073 return 0;
1074}
1075
1076static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1077{
1078 struct sd *sd = (struct sd *) gspca_dev;
1079
1080 *val = sd->brightness;
1081 return 0;
1082}
1083
1084static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1085{
1086 struct sd *sd = (struct sd *) gspca_dev;
1087
1088 sd->contrast = val;
1089 if (gspca_dev->streaming)
1090 setcontrast(gspca_dev);
1091 return 0;
1092}
1093
1094static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1095{
1096 struct sd *sd = (struct sd *) gspca_dev;
1097
1098 *val = sd->contrast;
1099 return 0;
1100}
1101
1102static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val) 1419static int sd_setagc(struct gspca_dev *gspca_dev, __s32 val)
1103{ 1420{
1104 struct sd *sd = (struct sd *) gspca_dev; 1421 struct sd *sd = (struct sd *) gspca_dev;
1105 1422
1106 sd->agc = val; 1423 sd->ctrls[AGC].val = val;
1107
1108 if (gspca_dev->streaming) {
1109 1424
1110 /* the auto white balance control works only 1425 /* the auto white balance control works only
1111 * when auto gain is set */ 1426 * when auto gain is set */
1112 if (val) 1427 if (val) {
1113 gspca_dev->ctrl_inac &= ~(1 << AWB_IDX); 1428 gspca_dev->ctrl_inac &= ~(1 << AWB);
1114 else 1429 } else {
1115 gspca_dev->ctrl_inac |= (1 << AWB_IDX); 1430 gspca_dev->ctrl_inac |= (1 << AWB);
1116 setagc(gspca_dev); 1431 if (sd->ctrls[AWB].val) {
1432 sd->ctrls[AWB].val = 0;
1433 if (gspca_dev->streaming)
1434 setawb(gspca_dev);
1435 }
1117 } 1436 }
1118 return 0;
1119}
1120
1121static int sd_getagc(struct gspca_dev *gspca_dev, __s32 *val)
1122{
1123 struct sd *sd = (struct sd *) gspca_dev;
1124
1125 *val = sd->agc;
1126 return 0;
1127}
1128
1129static int sd_setawb(struct gspca_dev *gspca_dev, __s32 val)
1130{
1131 struct sd *sd = (struct sd *) gspca_dev;
1132
1133 sd->awb = val;
1134 if (gspca_dev->streaming)
1135 setawb(gspca_dev);
1136 return 0;
1137}
1138
1139static int sd_getawb(struct gspca_dev *gspca_dev, __s32 *val)
1140{
1141 struct sd *sd = (struct sd *) gspca_dev;
1142
1143 *val = sd->awb;
1144 return 0;
1145}
1146
1147static int sd_setaec(struct gspca_dev *gspca_dev, __s32 val)
1148{
1149 struct sd *sd = (struct sd *) gspca_dev;
1150
1151 sd->aec = val;
1152 if (gspca_dev->streaming)
1153 setaec(gspca_dev);
1154 return 0;
1155}
1156
1157static int sd_getaec(struct gspca_dev *gspca_dev, __s32 *val)
1158{
1159 struct sd *sd = (struct sd *) gspca_dev;
1160
1161 *val = sd->aec;
1162 return 0;
1163}
1164
1165static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
1166{
1167 struct sd *sd = (struct sd *) gspca_dev;
1168
1169 sd->sharpness = val;
1170 if (gspca_dev->streaming)
1171 setsharpness(gspca_dev);
1172 return 0;
1173}
1174
1175static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
1176{
1177 struct sd *sd = (struct sd *) gspca_dev;
1178
1179 *val = sd->sharpness;
1180 return 0;
1181}
1182
1183static int sd_sethflip(struct gspca_dev *gspca_dev, __s32 val)
1184{
1185 struct sd *sd = (struct sd *) gspca_dev;
1186
1187 sd->hflip = val;
1188 if (gspca_dev->streaming)
1189 sethflip(gspca_dev);
1190 return 0;
1191}
1192
1193static int sd_gethflip(struct gspca_dev *gspca_dev, __s32 *val)
1194{
1195 struct sd *sd = (struct sd *) gspca_dev;
1196
1197 *val = sd->hflip;
1198 return 0;
1199}
1200
1201static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1202{
1203 struct sd *sd = (struct sd *) gspca_dev;
1204
1205 sd->vflip = val;
1206 if (gspca_dev->streaming)
1207 setvflip(gspca_dev);
1208 return 0;
1209}
1210
1211static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1212{
1213 struct sd *sd = (struct sd *) gspca_dev;
1214
1215 *val = sd->vflip;
1216 return 0;
1217}
1218
1219static int sd_setfreqfltr(struct gspca_dev *gspca_dev, __s32 val)
1220{
1221 struct sd *sd = (struct sd *) gspca_dev;
1222
1223 sd->freqfltr = val;
1224 if (gspca_dev->streaming) 1437 if (gspca_dev->streaming)
1225 setfreqfltr(gspca_dev); 1438 setagc(gspca_dev);
1226 return 0; 1439 return gspca_dev->usb_err;
1227}
1228
1229static int sd_getfreqfltr(struct gspca_dev *gspca_dev, __s32 *val)
1230{
1231 struct sd *sd = (struct sd *) gspca_dev;
1232
1233 *val = sd->freqfltr;
1234 return 0;
1235} 1440}
1236 1441
1237static int sd_querymenu(struct gspca_dev *gspca_dev, 1442static int sd_querymenu(struct gspca_dev *gspca_dev,
@@ -1302,6 +1507,7 @@ static const struct sd_desc sd_desc = {
1302/* -- module initialisation -- */ 1507/* -- module initialisation -- */
1303static const struct usb_device_id device_table[] = { 1508static const struct usb_device_id device_table[] = {
1304 {USB_DEVICE(0x1415, 0x2000)}, 1509 {USB_DEVICE(0x1415, 0x2000)},
1510 {USB_DEVICE(0x06f8, 0x3002)},
1305 {} 1511 {}
1306}; 1512};
1307 1513
diff --git a/drivers/media/video/gspca/sn9c20x.c b/drivers/media/video/gspca/sn9c20x.c
index fcf29897b713..c431900cd292 100644
--- a/drivers/media/video/gspca/sn9c20x.c
+++ b/drivers/media/video/gspca/sn9c20x.c
@@ -152,6 +152,13 @@ static const struct dmi_system_id flip_dmi_table[] = {
152 } 152 }
153 }, 153 },
154 { 154 {
155 .ident = "MSI MS-1633X",
156 .matches = {
157 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
158 DMI_MATCH(DMI_BOARD_NAME, "MS-1633X")
159 }
160 },
161 {
155 .ident = "MSI MS-1635X", 162 .ident = "MSI MS-1635X",
156 .matches = { 163 .matches = {
157 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"), 164 DMI_MATCH(DMI_BOARD_VENDOR, "MSI"),
@@ -369,7 +376,7 @@ static const struct v4l2_pix_format vga_mode[] = {
369 .priv = SCALE_160x120}, 376 .priv = SCALE_160x120},
370 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 377 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
371 .bytesperline = 320, 378 .bytesperline = 320,
372 .sizeimage = 320 * 240 * 3 / 8 + 590, 379 .sizeimage = 320 * 240 * 4 / 8 + 590,
373 .colorspace = V4L2_COLORSPACE_JPEG, 380 .colorspace = V4L2_COLORSPACE_JPEG,
374 .priv = SCALE_320x240 | MODE_JPEG}, 381 .priv = SCALE_320x240 | MODE_JPEG},
375 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 382 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -384,7 +391,7 @@ static const struct v4l2_pix_format vga_mode[] = {
384 .priv = SCALE_320x240}, 391 .priv = SCALE_320x240},
385 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 392 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
386 .bytesperline = 640, 393 .bytesperline = 640,
387 .sizeimage = 640 * 480 * 3 / 8 + 590, 394 .sizeimage = 640 * 480 * 4 / 8 + 590,
388 .colorspace = V4L2_COLORSPACE_JPEG, 395 .colorspace = V4L2_COLORSPACE_JPEG,
389 .priv = SCALE_640x480 | MODE_JPEG}, 396 .priv = SCALE_640x480 | MODE_JPEG},
390 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 397 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -417,7 +424,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
417 .priv = SCALE_160x120}, 424 .priv = SCALE_160x120},
418 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 425 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
419 .bytesperline = 320, 426 .bytesperline = 320,
420 .sizeimage = 320 * 240 * 3 / 8 + 590, 427 .sizeimage = 320 * 240 * 4 / 8 + 590,
421 .colorspace = V4L2_COLORSPACE_JPEG, 428 .colorspace = V4L2_COLORSPACE_JPEG,
422 .priv = SCALE_320x240 | MODE_JPEG}, 429 .priv = SCALE_320x240 | MODE_JPEG},
423 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 430 {320, 240, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -432,7 +439,7 @@ static const struct v4l2_pix_format sxga_mode[] = {
432 .priv = SCALE_320x240}, 439 .priv = SCALE_320x240},
433 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE, 440 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
434 .bytesperline = 640, 441 .bytesperline = 640,
435 .sizeimage = 640 * 480 * 3 / 8 + 590, 442 .sizeimage = 640 * 480 * 4 / 8 + 590,
436 .colorspace = V4L2_COLORSPACE_JPEG, 443 .colorspace = V4L2_COLORSPACE_JPEG,
437 .priv = SCALE_640x480 | MODE_JPEG}, 444 .priv = SCALE_640x480 | MODE_JPEG},
438 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE, 445 {640, 480, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
@@ -884,6 +891,9 @@ static struct i2c_reg_u8 ov7660_init[] = {
884 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3}, 891 {0x0e, 0x80}, {0x0d, 0x08}, {0x0f, 0xc3},
885 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40}, 892 {0x04, 0xc3}, {0x10, 0x40}, {0x11, 0x40},
886 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a}, 893 {0x12, 0x05}, {0x13, 0xba}, {0x14, 0x2a},
894 /* HDG Set hstart and hstop, datasheet default 0x11, 0x61, using
895 0x10, 0x61 and sd->hstart, vstart = 3, fixes ugly colored borders */
896 {0x17, 0x10}, {0x18, 0x61},
887 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43}, 897 {0x37, 0x0f}, {0x38, 0x02}, {0x39, 0x43},
888 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6}, 898 {0x3a, 0x00}, {0x69, 0x90}, {0x2d, 0xf6},
889 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50}, 899 {0x2e, 0x0b}, {0x01, 0x78}, {0x02, 0x50},
@@ -1332,10 +1342,8 @@ static int ov7660_init_sensor(struct gspca_dev *gspca_dev)
1332 return -ENODEV; 1342 return -ENODEV;
1333 } 1343 }
1334 } 1344 }
1335 /* disable hflip and vflip */ 1345 sd->hstart = 3;
1336 gspca_dev->ctrl_dis = (1 << HFLIP_IDX) | (1 << VFLIP_IDX); 1346 sd->vstart = 3;
1337 sd->hstart = 1;
1338 sd->vstart = 1;
1339 return 0; 1347 return 0;
1340} 1348}
1341 1349
@@ -1608,6 +1616,18 @@ static int set_hvflip(struct gspca_dev *gspca_dev)
1608 } 1616 }
1609 1617
1610 switch (sd->sensor) { 1618 switch (sd->sensor) {
1619 case SENSOR_OV7660:
1620 value = 0x01;
1621 if (hflip)
1622 value |= 0x20;
1623 if (vflip) {
1624 value |= 0x10;
1625 sd->vstart = 2;
1626 } else
1627 sd->vstart = 3;
1628 reg_w1(gspca_dev, 0x1182, sd->vstart);
1629 i2c_w1(gspca_dev, 0x1e, value);
1630 break;
1611 case SENSOR_OV9650: 1631 case SENSOR_OV9650:
1612 i2c_r1(gspca_dev, 0x1e, &value); 1632 i2c_r1(gspca_dev, 0x1e, &value);
1613 value &= ~0x30; 1633 value &= ~0x30;
@@ -2482,7 +2502,7 @@ static const struct usb_device_id device_table[] = {
2482 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)}, 2502 {USB_DEVICE(0x0c45, 0x6253), SN9C20X(OV9650, 0x30, 0)},
2483 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)}, 2503 {USB_DEVICE(0x0c45, 0x6260), SN9C20X(OV7670, 0x21, 0)},
2484 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)}, 2504 {USB_DEVICE(0x0c45, 0x6270), SN9C20X(MT9VPRB, 0x00, 0)},
2485 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, 0)}, 2505 {USB_DEVICE(0x0c45, 0x627b), SN9C20X(OV7660, 0x21, FLIP_DETECT)},
2486 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)}, 2506 {USB_DEVICE(0x0c45, 0x627c), SN9C20X(HV7131R, 0x11, 0)},
2487 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)}, 2507 {USB_DEVICE(0x0c45, 0x627f), SN9C20X(OV9650, 0x30, 0)},
2488 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)}, 2508 {USB_DEVICE(0x0c45, 0x6280), SN9C20X(MT9M001, 0x5d, 0)},
@@ -2494,7 +2514,7 @@ static const struct usb_device_id device_table[] = {
2494 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)}, 2514 {USB_DEVICE(0x0c45, 0x62a0), SN9C20X(OV7670, 0x21, 0)},
2495 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)}, 2515 {USB_DEVICE(0x0c45, 0x62b0), SN9C20X(MT9VPRB, 0x00, 0)},
2496 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)}, 2516 {USB_DEVICE(0x0c45, 0x62b3), SN9C20X(OV9655, 0x30, 0)},
2497 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, 0)}, 2517 {USB_DEVICE(0x0c45, 0x62bb), SN9C20X(OV7660, 0x21, LED_REVERSE)},
2498 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)}, 2518 {USB_DEVICE(0x0c45, 0x62bc), SN9C20X(HV7131R, 0x11, 0)},
2499 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)}, 2519 {USB_DEVICE(0x045e, 0x00f4), SN9C20X(OV9650, 0x30, 0)},
2500 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)}, 2520 {USB_DEVICE(0x145f, 0x013d), SN9C20X(OV7660, 0x21, 0)},
diff --git a/drivers/media/video/gspca/sonixb.c b/drivers/media/video/gspca/sonixb.c
index c6cd68d66b53..5a08738fba30 100644
--- a/drivers/media/video/gspca/sonixb.c
+++ b/drivers/media/video/gspca/sonixb.c
@@ -1,9 +1,9 @@
1/* 1/*
2 * sonix sn9c102 (bayer) library 2 * sonix sn9c102 (bayer) library
3 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
4 * Add Pas106 Stefano Mozzi (C) 2004
5 * 3 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2011 Jean-François Moine <http://moinejf.free.fr>
5 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
6 * Add Pas106 Stefano Mozzi (C) 2004
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License as published by
@@ -52,13 +52,26 @@ all:
52#include <linux/input.h> 52#include <linux/input.h>
53#include "gspca.h" 53#include "gspca.h"
54 54
55MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>"); 55MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver"); 56MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
57MODULE_LICENSE("GPL"); 57MODULE_LICENSE("GPL");
58 58
59/* controls */
60enum e_ctrl {
61 BRIGHTNESS,
62 GAIN,
63 EXPOSURE,
64 AUTOGAIN,
65 FREQ,
66 NCTRLS /* number of controls */
67};
68
59/* specific webcam descriptor */ 69/* specific webcam descriptor */
60struct sd { 70struct sd {
61 struct gspca_dev gspca_dev; /* !! must be the first item */ 71 struct gspca_dev gspca_dev; /* !! must be the first item */
72
73 struct gspca_ctrl ctrls[NCTRLS];
74
62 atomic_t avg_lum; 75 atomic_t avg_lum;
63 int prev_avg_lum; 76 int prev_avg_lum;
64 int exp_too_low_cnt; 77 int exp_too_low_cnt;
@@ -66,13 +79,8 @@ struct sd {
66 int header_read; 79 int header_read;
67 u8 header[12]; /* Header without sof marker */ 80 u8 header[12]; /* Header without sof marker */
68 81
69 unsigned short exposure;
70 unsigned char gain;
71 unsigned char brightness;
72 unsigned char autogain;
73 unsigned char autogain_ignore_frames; 82 unsigned char autogain_ignore_frames;
74 unsigned char frames_to_drop; 83 unsigned char frames_to_drop;
75 unsigned char freq; /* light freq filter setting */
76 84
77 __u8 bridge; /* Type of bridge */ 85 __u8 bridge; /* Type of bridge */
78#define BRIDGE_101 0 86#define BRIDGE_101 0
@@ -113,10 +121,9 @@ struct sensor_data {
113#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */ 121#define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
114 122
115/* ctrl_dis helper macros */ 123/* ctrl_dis helper macros */
116#define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \ 124#define NO_EXPO ((1 << EXPOSURE) | (1 << AUTOGAIN))
117 (1 << AUTOGAIN_IDX)) 125#define NO_FREQ (1 << FREQ)
118#define NO_FREQ (1 << FREQ_IDX) 126#define NO_BRIGHTNESS (1 << BRIGHTNESS)
119#define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
120 127
121#define COMP 0xc7 /* 0x87 //0x07 */ 128#define COMP 0xc7 /* 0x87 //0x07 */
122#define COMP1 0xc9 /* 0x89 //0x09 */ 129#define COMP1 0xc9 /* 0x89 //0x09 */
@@ -141,20 +148,14 @@ struct sensor_data {
141#define AUTOGAIN_IGNORE_FRAMES 1 148#define AUTOGAIN_IGNORE_FRAMES 1
142 149
143/* V4L2 controls supported by the driver */ 150/* V4L2 controls supported by the driver */
144static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val); 151static void setbrightness(struct gspca_dev *gspca_dev);
145static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val); 152static void setgain(struct gspca_dev *gspca_dev);
146static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val); 153static void setexposure(struct gspca_dev *gspca_dev);
147static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
148static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
149static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
150static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); 154static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
151static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); 155static void setfreq(struct gspca_dev *gspca_dev);
152static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
153static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
154 156
155static const struct ctrl sd_ctrls[] = { 157static const struct ctrl sd_ctrls[NCTRLS] = {
156#define BRIGHTNESS_IDX 0 158[BRIGHTNESS] = {
157 {
158 { 159 {
159 .id = V4L2_CID_BRIGHTNESS, 160 .id = V4L2_CID_BRIGHTNESS,
160 .type = V4L2_CTRL_TYPE_INTEGER, 161 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -162,14 +163,11 @@ static const struct ctrl sd_ctrls[] = {
162 .minimum = 0, 163 .minimum = 0,
163 .maximum = 255, 164 .maximum = 255,
164 .step = 1, 165 .step = 1,
165#define BRIGHTNESS_DEF 127 166 .default_value = 127,
166 .default_value = BRIGHTNESS_DEF,
167 }, 167 },
168 .set = sd_setbrightness, 168 .set_control = setbrightness
169 .get = sd_getbrightness,
170 }, 169 },
171#define GAIN_IDX 1 170[GAIN] = {
172 {
173 { 171 {
174 .id = V4L2_CID_GAIN, 172 .id = V4L2_CID_GAIN,
175 .type = V4L2_CTRL_TYPE_INTEGER, 173 .type = V4L2_CTRL_TYPE_INTEGER,
@@ -177,48 +175,31 @@ static const struct ctrl sd_ctrls[] = {
177 .minimum = 0, 175 .minimum = 0,
178 .maximum = 255, 176 .maximum = 255,
179 .step = 1, 177 .step = 1,
180#define GAIN_DEF 127
181#define GAIN_KNEE 230 178#define GAIN_KNEE 230
182 .default_value = GAIN_DEF, 179 .default_value = 127,
183 }, 180 },
184 .set = sd_setgain, 181 .set_control = setgain
185 .get = sd_getgain,
186 }, 182 },
187#define EXPOSURE_IDX 2 183[EXPOSURE] = {
188 {
189 { 184 {
190 .id = V4L2_CID_EXPOSURE, 185 .id = V4L2_CID_EXPOSURE,
191 .type = V4L2_CTRL_TYPE_INTEGER, 186 .type = V4L2_CTRL_TYPE_INTEGER,
192 .name = "Exposure", 187 .name = "Exposure",
193#define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
194#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
195 .minimum = 0, 188 .minimum = 0,
196 .maximum = 1023, 189 .maximum = 1023,
197 .step = 1, 190 .step = 1,
198 .default_value = EXPOSURE_DEF, 191 .default_value = 66,
192 /* 33 ms / 30 fps (except on PASXXX) */
193#define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
199 .flags = 0, 194 .flags = 0,
200 }, 195 },
201 .set = sd_setexposure, 196 .set_control = setexposure
202 .get = sd_getexposure,
203 }, 197 },
204#define COARSE_EXPOSURE_IDX 3 198/* for coarse exposure */
205 { 199#define COARSE_EXPOSURE_MIN 2
206 { 200#define COARSE_EXPOSURE_MAX 15
207 .id = V4L2_CID_EXPOSURE,
208 .type = V4L2_CTRL_TYPE_INTEGER,
209 .name = "Exposure",
210#define COARSE_EXPOSURE_DEF 2 /* 30 fps */ 201#define COARSE_EXPOSURE_DEF 2 /* 30 fps */
211 .minimum = 2, 202[AUTOGAIN] = {
212 .maximum = 15,
213 .step = 1,
214 .default_value = COARSE_EXPOSURE_DEF,
215 .flags = 0,
216 },
217 .set = sd_setexposure,
218 .get = sd_getexposure,
219 },
220#define AUTOGAIN_IDX 4
221 {
222 { 203 {
223 .id = V4L2_CID_AUTOGAIN, 204 .id = V4L2_CID_AUTOGAIN,
224 .type = V4L2_CTRL_TYPE_BOOLEAN, 205 .type = V4L2_CTRL_TYPE_BOOLEAN,
@@ -228,13 +209,11 @@ static const struct ctrl sd_ctrls[] = {
228 .step = 1, 209 .step = 1,
229#define AUTOGAIN_DEF 1 210#define AUTOGAIN_DEF 1
230 .default_value = AUTOGAIN_DEF, 211 .default_value = AUTOGAIN_DEF,
231 .flags = 0, 212 .flags = V4L2_CTRL_FLAG_UPDATE
232 }, 213 },
233 .set = sd_setautogain, 214 .set = sd_setautogain,
234 .get = sd_getautogain,
235 }, 215 },
236#define FREQ_IDX 5 216[FREQ] = {
237 {
238 { 217 {
239 .id = V4L2_CID_POWER_LINE_FREQUENCY, 218 .id = V4L2_CID_POWER_LINE_FREQUENCY,
240 .type = V4L2_CTRL_TYPE_MENU, 219 .type = V4L2_CTRL_TYPE_MENU,
@@ -245,8 +224,7 @@ static const struct ctrl sd_ctrls[] = {
245#define FREQ_DEF 0 224#define FREQ_DEF 0
246 .default_value = FREQ_DEF, 225 .default_value = FREQ_DEF,
247 }, 226 },
248 .set = sd_setfreq, 227 .set_control = setfreq
249 .get = sd_getfreq,
250 }, 228 },
251}; 229};
252 230
@@ -553,7 +531,7 @@ static const __u8 tas5130_sensor_init[][8] = {
553 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10}, 531 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
554}; 532};
555 533
556static struct sensor_data sensor_data[] = { 534static const struct sensor_data sensor_data[] = {
557SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0), 535SENS(initHv7131d, hv7131d_sensor_init, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
558SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0), 536SENS(initHv7131r, hv7131r_sensor_init, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
559SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60), 537SENS(initOv6650, ov6650_sensor_init, F_GAIN|F_SIF, 0, 0x60),
@@ -646,7 +624,7 @@ static void setbrightness(struct gspca_dev *gspca_dev)
646 624
647 /* change reg 0x06 */ 625 /* change reg 0x06 */
648 i2cOV[1] = sensor_data[sd->sensor].sensor_addr; 626 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
649 i2cOV[3] = sd->brightness; 627 i2cOV[3] = sd->ctrls[BRIGHTNESS].val;
650 if (i2c_w(gspca_dev, i2cOV) < 0) 628 if (i2c_w(gspca_dev, i2cOV) < 0)
651 goto err; 629 goto err;
652 break; 630 break;
@@ -664,13 +642,13 @@ static void setbrightness(struct gspca_dev *gspca_dev)
664 i2cpdoit[2] = 0x13; 642 i2cpdoit[2] = 0x13;
665 } 643 }
666 644
667 if (sd->brightness < 127) { 645 if (sd->ctrls[BRIGHTNESS].val < 127) {
668 /* change reg 0x0b, signreg */ 646 /* change reg 0x0b, signreg */
669 i2cpbright[3] = 0x01; 647 i2cpbright[3] = 0x01;
670 /* set reg 0x0c, offset */ 648 /* set reg 0x0c, offset */
671 i2cpbright[4] = 127 - sd->brightness; 649 i2cpbright[4] = 127 - sd->ctrls[BRIGHTNESS].val;
672 } else 650 } else
673 i2cpbright[4] = sd->brightness - 127; 651 i2cpbright[4] = sd->ctrls[BRIGHTNESS].val - 127;
674 652
675 if (i2c_w(gspca_dev, i2cpbright) < 0) 653 if (i2c_w(gspca_dev, i2cpbright) < 0)
676 goto err; 654 goto err;
@@ -687,16 +665,16 @@ err:
687static void setsensorgain(struct gspca_dev *gspca_dev) 665static void setsensorgain(struct gspca_dev *gspca_dev)
688{ 666{
689 struct sd *sd = (struct sd *) gspca_dev; 667 struct sd *sd = (struct sd *) gspca_dev;
690 unsigned char gain = sd->gain; 668 u8 gain = sd->ctrls[GAIN].val;
691 669
692 switch (sd->sensor) { 670 switch (sd->sensor) {
693 case SENSOR_HV7131D: { 671 case SENSOR_HV7131D: {
694 __u8 i2c[] = 672 __u8 i2c[] =
695 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17}; 673 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
696 674
697 i2c[3] = 0x3f - (sd->gain / 4); 675 i2c[3] = 0x3f - (gain / 4);
698 i2c[4] = 0x3f - (sd->gain / 4); 676 i2c[4] = 0x3f - (gain / 4);
699 i2c[5] = 0x3f - (sd->gain / 4); 677 i2c[5] = 0x3f - (gain / 4);
700 678
701 if (i2c_w(gspca_dev, i2c) < 0) 679 if (i2c_w(gspca_dev, i2c) < 0)
702 goto err; 680 goto err;
@@ -759,11 +737,11 @@ static void setsensorgain(struct gspca_dev *gspca_dev)
759 i2cpdoit[2] = 0x13; 737 i2cpdoit[2] = 0x13;
760 } 738 }
761 739
762 i2cpgain[3] = sd->gain >> 3; 740 i2cpgain[3] = gain >> 3;
763 i2cpcolorgain[3] = sd->gain >> 4; 741 i2cpcolorgain[3] = gain >> 4;
764 i2cpcolorgain[4] = sd->gain >> 4; 742 i2cpcolorgain[4] = gain >> 4;
765 i2cpcolorgain[5] = sd->gain >> 4; 743 i2cpcolorgain[5] = gain >> 4;
766 i2cpcolorgain[6] = sd->gain >> 4; 744 i2cpcolorgain[6] = gain >> 4;
767 745
768 if (i2c_w(gspca_dev, i2cpgain) < 0) 746 if (i2c_w(gspca_dev, i2cpgain) < 0)
769 goto err; 747 goto err;
@@ -792,13 +770,13 @@ static void setgain(struct gspca_dev *gspca_dev)
792 } 770 }
793 771
794 if (sd->bridge == BRIDGE_103) { 772 if (sd->bridge == BRIDGE_103) {
795 gain = sd->gain >> 1; 773 gain = sd->ctrls[GAIN].val >> 1;
796 buf[0] = gain; /* Red */ 774 buf[0] = gain; /* Red */
797 buf[1] = gain; /* Green */ 775 buf[1] = gain; /* Green */
798 buf[2] = gain; /* Blue */ 776 buf[2] = gain; /* Blue */
799 reg_w(gspca_dev, 0x05, buf, 3); 777 reg_w(gspca_dev, 0x05, buf, 3);
800 } else { 778 } else {
801 gain = sd->gain >> 4; 779 gain = sd->ctrls[GAIN].val >> 4;
802 buf[0] = gain << 4 | gain; /* Red and blue */ 780 buf[0] = gain << 4 | gain; /* Red and blue */
803 buf[1] = gain; /* Green */ 781 buf[1] = gain; /* Green */
804 reg_w(gspca_dev, 0x10, buf, 2); 782 reg_w(gspca_dev, 0x10, buf, 2);
@@ -820,7 +798,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
820 where the framerate starts dropping 798 where the framerate starts dropping
821 2) At 6138 the framerate has already dropped to 2 fps, 799 2) At 6138 the framerate has already dropped to 2 fps,
822 going any lower makes little sense */ 800 going any lower makes little sense */
823 __u16 reg = sd->exposure * 6; 801 u16 reg = sd->ctrls[EXPOSURE].val * 6;
802
824 i2c[3] = reg >> 8; 803 i2c[3] = reg >> 8;
825 i2c[4] = reg & 0xff; 804 i2c[4] = reg & 0xff;
826 if (i2c_w(gspca_dev, i2c) != 0) 805 if (i2c_w(gspca_dev, i2c) != 0)
@@ -832,7 +811,8 @@ static void setexposure(struct gspca_dev *gspca_dev)
832 /* register 19's high nibble contains the sn9c10x clock divider 811 /* register 19's high nibble contains the sn9c10x clock divider
833 The high nibble configures the no fps according to the 812 The high nibble configures the no fps according to the
834 formula: 60 / high_nibble. With a maximum of 30 fps */ 813 formula: 60 / high_nibble. With a maximum of 30 fps */
835 __u8 reg = sd->exposure; 814 u8 reg = sd->ctrls[EXPOSURE].val;
815
836 reg = (reg << 4) | 0x0b; 816 reg = (reg << 4) | 0x0b;
837 reg_w(gspca_dev, 0x19, &reg, 1); 817 reg_w(gspca_dev, 0x19, &reg, 1);
838 break; 818 break;
@@ -868,7 +848,7 @@ static void setexposure(struct gspca_dev *gspca_dev)
868 } else 848 } else
869 reg10_max = 0x41; 849 reg10_max = 0x41;
870 850
871 reg11 = (15 * sd->exposure + 999) / 1000; 851 reg11 = (15 * sd->ctrls[EXPOSURE].val + 999) / 1000;
872 if (reg11 < 1) 852 if (reg11 < 1)
873 reg11 = 1; 853 reg11 = 1;
874 else if (reg11 > 16) 854 else if (reg11 > 16)
@@ -881,14 +861,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
881 reg11 = 4; 861 reg11 = 4;
882 862
883 /* frame exposure time in ms = 1000 * reg11 / 30 -> 863 /* frame exposure time in ms = 1000 * reg11 / 30 ->
884 reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */ 864 reg10 = (sd->ctrls[EXPOSURE].val / 2) * reg10_max
885 reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11); 865 / (1000 * reg11 / 30) */
866 reg10 = (sd->ctrls[EXPOSURE].val * 15 * reg10_max)
867 / (1000 * reg11);
886 868
887 /* Don't allow this to get below 10 when using autogain, the 869 /* Don't allow this to get below 10 when using autogain, the
888 steps become very large (relatively) when below 10 causing 870 steps become very large (relatively) when below 10 causing
889 the image to oscilate from much too dark, to much too bright 871 the image to oscilate from much too dark, to much too bright
890 and back again. */ 872 and back again. */
891 if (sd->autogain && reg10 < 10) 873 if (sd->ctrls[AUTOGAIN].val && reg10 < 10)
892 reg10 = 10; 874 reg10 = 10;
893 else if (reg10 > reg10_max) 875 else if (reg10 > reg10_max)
894 reg10 = reg10_max; 876 reg10 = reg10_max;
@@ -927,15 +909,16 @@ static void setexposure(struct gspca_dev *gspca_dev)
927 frame exposure times (like we are doing with the ov chips), 909 frame exposure times (like we are doing with the ov chips),
928 as that sometimes leads to jumps in the exposure control, 910 as that sometimes leads to jumps in the exposure control,
929 which are bad for auto exposure. */ 911 which are bad for auto exposure. */
930 if (sd->exposure < 200) { 912 if (sd->ctrls[EXPOSURE].val < 200) {
931 i2cpexpo[3] = 255 - (sd->exposure * 255) / 200; 913 i2cpexpo[3] = 255 - (sd->ctrls[EXPOSURE].val * 255)
914 / 200;
932 framerate_ctrl = 500; 915 framerate_ctrl = 500;
933 } else { 916 } else {
934 /* The PAS202's exposure control goes from 0 - 4095, 917 /* The PAS202's exposure control goes from 0 - 4095,
935 but anything below 500 causes vsync issues, so scale 918 but anything below 500 causes vsync issues, so scale
936 our 200-1023 to 500-4095 */ 919 our 200-1023 to 500-4095 */
937 framerate_ctrl = (sd->exposure - 200) * 1000 / 229 + 920 framerate_ctrl = (sd->ctrls[EXPOSURE].val - 200)
938 500; 921 * 1000 / 229 + 500;
939 } 922 }
940 923
941 i2cpframerate[3] = framerate_ctrl >> 6; 924 i2cpframerate[3] = framerate_ctrl >> 6;
@@ -959,15 +942,15 @@ static void setexposure(struct gspca_dev *gspca_dev)
959 942
960 /* For values below 150 use partial frame exposure, above 943 /* For values below 150 use partial frame exposure, above
961 that use framerate ctrl */ 944 that use framerate ctrl */
962 if (sd->exposure < 150) { 945 if (sd->ctrls[EXPOSURE].val < 150) {
963 i2cpexpo[3] = 150 - sd->exposure; 946 i2cpexpo[3] = 150 - sd->ctrls[EXPOSURE].val;
964 framerate_ctrl = 300; 947 framerate_ctrl = 300;
965 } else { 948 } else {
966 /* The PAS106's exposure control goes from 0 - 4095, 949 /* The PAS106's exposure control goes from 0 - 4095,
967 but anything below 300 causes vsync issues, so scale 950 but anything below 300 causes vsync issues, so scale
968 our 150-1023 to 300-4095 */ 951 our 150-1023 to 300-4095 */
969 framerate_ctrl = (sd->exposure - 150) * 1000 / 230 + 952 framerate_ctrl = (sd->ctrls[EXPOSURE].val - 150)
970 300; 953 * 1000 / 230 + 300;
971 } 954 }
972 955
973 i2cpframerate[3] = framerate_ctrl >> 4; 956 i2cpframerate[3] = framerate_ctrl >> 4;
@@ -998,7 +981,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
998 0x2b register, see ov6630 datasheet. 981 0x2b register, see ov6630 datasheet.
999 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */ 982 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
1000 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}; 983 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
1001 switch (sd->freq) { 984 switch (sd->ctrls[FREQ].val) {
1002 default: 985 default:
1003/* case 0: * no filter*/ 986/* case 0: * no filter*/
1004/* case 2: * 60 hz */ 987/* case 2: * 60 hz */
@@ -1017,7 +1000,7 @@ static void setfreq(struct gspca_dev *gspca_dev)
1017 } 1000 }
1018} 1001}
1019 1002
1020#include "coarse_expo_autogain.h" 1003#include "autogain_functions.h"
1021 1004
1022static void do_autogain(struct gspca_dev *gspca_dev) 1005static void do_autogain(struct gspca_dev *gspca_dev)
1023{ 1006{
@@ -1025,7 +1008,8 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1025 struct sd *sd = (struct sd *) gspca_dev; 1008 struct sd *sd = (struct sd *) gspca_dev;
1026 int avg_lum = atomic_read(&sd->avg_lum); 1009 int avg_lum = atomic_read(&sd->avg_lum);
1027 1010
1028 if (avg_lum == -1 || !sd->autogain) 1011 if ((gspca_dev->ctrl_dis & (1 << AUTOGAIN)) ||
1012 avg_lum == -1 || !sd->ctrls[AUTOGAIN].val)
1029 return; 1013 return;
1030 1014
1031 if (sd->autogain_ignore_frames > 0) { 1015 if (sd->autogain_ignore_frames > 0) {
@@ -1045,17 +1029,20 @@ static void do_autogain(struct gspca_dev *gspca_dev)
1045 } 1029 }
1046 1030
1047 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) 1031 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
1048 result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum, 1032 result = coarse_grained_expo_autogain(gspca_dev, avg_lum,
1049 sd->brightness * desired_avg_lum / 127, 1033 sd->ctrls[BRIGHTNESS].val
1034 * desired_avg_lum / 127,
1050 deadzone); 1035 deadzone);
1051 else 1036 else
1052 result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum, 1037 result = auto_gain_n_exposure(gspca_dev, avg_lum,
1053 sd->brightness * desired_avg_lum / 127, 1038 sd->ctrls[BRIGHTNESS].val
1039 * desired_avg_lum / 127,
1054 deadzone, GAIN_KNEE, EXPOSURE_KNEE); 1040 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1055 1041
1056 if (result) { 1042 if (result) {
1057 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d", 1043 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1058 (int)sd->gain, (int)sd->exposure); 1044 (int) sd->ctrls[GAIN].val,
1045 (int) sd->ctrls[EXPOSURE].val);
1059 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1046 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1060 } 1047 }
1061} 1048}
@@ -1074,9 +1061,15 @@ static int sd_config(struct gspca_dev *gspca_dev,
1074 /* copy the webcam info from the device id */ 1061 /* copy the webcam info from the device id */
1075 sd->sensor = id->driver_info >> 8; 1062 sd->sensor = id->driver_info >> 8;
1076 sd->bridge = id->driver_info & 0xff; 1063 sd->bridge = id->driver_info & 0xff;
1064
1077 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis; 1065 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1066#if AUTOGAIN_DEF
1067 if (!(gspca_dev->ctrl_dis & (1 << AUTOGAIN)))
1068 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1069#endif
1078 1070
1079 cam = &gspca_dev->cam; 1071 cam = &gspca_dev->cam;
1072 cam->ctrls = sd->ctrls;
1080 if (!(sensor_data[sd->sensor].flags & F_SIF)) { 1073 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1081 cam->cam_mode = vga_mode; 1074 cam->cam_mode = vga_mode;
1082 cam->nmodes = ARRAY_SIZE(vga_mode); 1075 cam->nmodes = ARRAY_SIZE(vga_mode);
@@ -1086,20 +1079,11 @@ static int sd_config(struct gspca_dev *gspca_dev,
1086 } 1079 }
1087 cam->npkt = 36; /* 36 packets per ISOC message */ 1080 cam->npkt = 36; /* 36 packets per ISOC message */
1088 1081
1089 sd->brightness = BRIGHTNESS_DEF;
1090 sd->gain = GAIN_DEF;
1091 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) { 1082 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1092 sd->exposure = COARSE_EXPOSURE_DEF; 1083 sd->ctrls[EXPOSURE].min = COARSE_EXPOSURE_MIN;
1093 gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX); 1084 sd->ctrls[EXPOSURE].max = COARSE_EXPOSURE_MAX;
1094 } else { 1085 sd->ctrls[EXPOSURE].def = COARSE_EXPOSURE_DEF;
1095 sd->exposure = EXPOSURE_DEF;
1096 gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1097 } 1086 }
1098 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1099 sd->autogain = 0; /* Disable do_autogain callback */
1100 else
1101 sd->autogain = AUTOGAIN_DEF;
1102 sd->freq = FREQ_DEF;
1103 1087
1104 return 0; 1088 return 0;
1105} 1089}
@@ -1398,65 +1382,11 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1398 } 1382 }
1399} 1383}
1400 1384
1401static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1402{
1403 struct sd *sd = (struct sd *) gspca_dev;
1404
1405 sd->brightness = val;
1406 if (gspca_dev->streaming)
1407 setbrightness(gspca_dev);
1408 return 0;
1409}
1410
1411static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1412{
1413 struct sd *sd = (struct sd *) gspca_dev;
1414
1415 *val = sd->brightness;
1416 return 0;
1417}
1418
1419static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1420{
1421 struct sd *sd = (struct sd *) gspca_dev;
1422
1423 sd->gain = val;
1424 if (gspca_dev->streaming)
1425 setgain(gspca_dev);
1426 return 0;
1427}
1428
1429static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1430{
1431 struct sd *sd = (struct sd *) gspca_dev;
1432
1433 *val = sd->gain;
1434 return 0;
1435}
1436
1437static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1438{
1439 struct sd *sd = (struct sd *) gspca_dev;
1440
1441 sd->exposure = val;
1442 if (gspca_dev->streaming)
1443 setexposure(gspca_dev);
1444 return 0;
1445}
1446
1447static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1448{
1449 struct sd *sd = (struct sd *) gspca_dev;
1450
1451 *val = sd->exposure;
1452 return 0;
1453}
1454
1455static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val) 1385static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1456{ 1386{
1457 struct sd *sd = (struct sd *) gspca_dev; 1387 struct sd *sd = (struct sd *) gspca_dev;
1458 1388
1459 sd->autogain = val; 1389 sd->ctrls[AUTOGAIN].val = val;
1460 sd->exp_too_high_cnt = 0; 1390 sd->exp_too_high_cnt = 0;
1461 sd->exp_too_low_cnt = 0; 1391 sd->exp_too_low_cnt = 0;
1462 1392
@@ -1464,9 +1394,10 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1464 we are on a valid point of the autogain gain / 1394 we are on a valid point of the autogain gain /
1465 exposure knee graph, and give this change time to 1395 exposure knee graph, and give this change time to
1466 take effect before doing autogain. */ 1396 take effect before doing autogain. */
1467 if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) { 1397 if (sd->ctrls[AUTOGAIN].val
1468 sd->exposure = EXPOSURE_DEF; 1398 && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1469 sd->gain = GAIN_DEF; 1399 sd->ctrls[EXPOSURE].val = sd->ctrls[EXPOSURE].def;
1400 sd->ctrls[GAIN].val = sd->ctrls[GAIN].def;
1470 if (gspca_dev->streaming) { 1401 if (gspca_dev->streaming) {
1471 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES; 1402 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1472 setexposure(gspca_dev); 1403 setexposure(gspca_dev);
@@ -1474,32 +1405,11 @@ static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1474 } 1405 }
1475 } 1406 }
1476 1407
1477 return 0; 1408 if (sd->ctrls[AUTOGAIN].val)
1478} 1409 gspca_dev->ctrl_inac = (1 << GAIN) | (1 << EXPOSURE);
1479 1410 else
1480static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) 1411 gspca_dev->ctrl_inac = 0;
1481{
1482 struct sd *sd = (struct sd *) gspca_dev;
1483
1484 *val = sd->autogain;
1485 return 0;
1486}
1487
1488static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1489{
1490 struct sd *sd = (struct sd *) gspca_dev;
1491
1492 sd->freq = val;
1493 if (gspca_dev->streaming)
1494 setfreq(gspca_dev);
1495 return 0;
1496}
1497
1498static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1499{
1500 struct sd *sd = (struct sd *) gspca_dev;
1501 1412
1502 *val = sd->freq;
1503 return 0; 1413 return 0;
1504} 1414}
1505 1415
diff --git a/drivers/media/video/gspca/sonixj.c b/drivers/media/video/gspca/sonixj.c
index d6f39ce1b7e1..6415aff5cbd1 100644
--- a/drivers/media/video/gspca/sonixj.c
+++ b/drivers/media/video/gspca/sonixj.c
@@ -29,8 +29,6 @@ MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
29MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver"); 29MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
30MODULE_LICENSE("GPL"); 30MODULE_LICENSE("GPL");
31 31
32static int starcam;
33
34/* controls */ 32/* controls */
35enum e_ctrl { 33enum e_ctrl {
36 BRIGHTNESS, 34 BRIGHTNESS,
@@ -57,11 +55,18 @@ struct sd {
57 atomic_t avg_lum; 55 atomic_t avg_lum;
58 u32 exposure; 56 u32 exposure;
59 57
58 struct work_struct work;
59 struct workqueue_struct *work_thread;
60
61 u32 pktsz; /* (used by pkt_scan) */
62 u16 npkt;
63 u8 nchg;
64 s8 short_mark;
65
60 u8 quality; /* image quality */ 66 u8 quality; /* image quality */
61#define QUALITY_MIN 60 67#define QUALITY_MIN 25
62#define QUALITY_MAX 95 68#define QUALITY_MAX 90
63#define QUALITY_DEF 80 69#define QUALITY_DEF 70
64 u8 jpegqual; /* webcam quality */
65 70
66 u8 reg01; 71 u8 reg01;
67 u8 reg17; 72 u8 reg17;
@@ -99,6 +104,8 @@ enum sensors {
99 SENSOR_SP80708, 104 SENSOR_SP80708,
100}; 105};
101 106
107static void qual_upd(struct work_struct *work);
108
102/* device flags */ 109/* device flags */
103#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */ 110#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
104#define F_ILLUM 0x02 /* presence of illuminator */ 111#define F_ILLUM 0x02 /* presence of illuminator */
@@ -401,7 +408,7 @@ static const u8 sn_hv7131[0x1c] = {
401 408
402static const u8 sn_mi0360[0x1c] = { 409static const u8 sn_mi0360[0x1c] = {
403/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */ 410/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
404 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20, 411 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
405/* reg8 reg9 rega regb regc regd rege regf */ 412/* reg8 reg9 rega regb regc regd rege regf */
406 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 413 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
407/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */ 414/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
@@ -847,18 +854,8 @@ static const u8 mt9v111_sensor_init[][8] = {
847 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */ 854 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
848 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */ 855 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
849 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */ 856 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
850 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
851 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
852 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
853 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
854 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */ 857 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
855 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
856 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
857 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
858 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
859 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
860 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */ 858 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
861 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
862 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */ 859 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
863 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */ 860 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
864 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */ 861 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
@@ -872,15 +869,10 @@ static const u8 mt9v111_sensor_init[][8] = {
872 {} 869 {}
873}; 870};
874static const u8 mt9v111_sensor_param1[][8] = { 871static const u8 mt9v111_sensor_param1[][8] = {
875 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 872 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
876 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, 873 {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
877 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10}, 874 {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
878 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */ 875 {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
879 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
880 /*******/
881 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
882 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
883 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
884 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */ 876 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
885 {} 877 {}
886}; 878};
@@ -1784,7 +1776,12 @@ static int sd_config(struct gspca_dev *gspca_dev,
1784 1776
1785 sd->ag_cnt = -1; 1777 sd->ag_cnt = -1;
1786 sd->quality = QUALITY_DEF; 1778 sd->quality = QUALITY_DEF;
1787 sd->jpegqual = 80; 1779
1780 /* if USB 1.1, let some bandwidth for the audio device */
1781 if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
1782 gspca_dev->nbalt--;
1783
1784 INIT_WORK(&sd->work, qual_upd);
1788 1785
1789 return 0; 1786 return 0;
1790} 1787}
@@ -1794,7 +1791,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1794{ 1791{
1795 struct sd *sd = (struct sd *) gspca_dev; 1792 struct sd *sd = (struct sd *) gspca_dev;
1796 const u8 *sn9c1xx; 1793 const u8 *sn9c1xx;
1797 u8 regGpio[] = { 0x29, 0x74 }; /* with audio */ 1794 u8 regGpio[] = { 0x29, 0x70 }; /* no audio */
1798 u8 regF1; 1795 u8 regF1;
1799 1796
1800 /* setup a selector by bridge */ 1797 /* setup a selector by bridge */
@@ -1806,6 +1803,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
1806 if (gspca_dev->usb_err < 0) 1803 if (gspca_dev->usb_err < 0)
1807 return gspca_dev->usb_err; 1804 return gspca_dev->usb_err;
1808 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1); 1805 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1806 if (gspca_dev->audio)
1807 regGpio[1] |= 0x04; /* with audio */
1809 switch (sd->bridge) { 1808 switch (sd->bridge) {
1810 case BRIDGE_SN9C102P: 1809 case BRIDGE_SN9C102P:
1811 case BRIDGE_SN9C105: 1810 case BRIDGE_SN9C105:
@@ -1838,14 +1837,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
1838 case BRIDGE_SN9C102P: 1837 case BRIDGE_SN9C102P:
1839 reg_w1(gspca_dev, 0x02, regGpio[1]); 1838 reg_w1(gspca_dev, 0x02, regGpio[1]);
1840 break; 1839 break;
1841 case BRIDGE_SN9C105: 1840 default:
1842 reg_w(gspca_dev, 0x01, regGpio, 2);
1843 break;
1844 case BRIDGE_SN9C110:
1845 reg_w1(gspca_dev, 0x02, 0x62);
1846 break;
1847 case BRIDGE_SN9C120:
1848 regGpio[1] = 0x70; /* no audio */
1849 reg_w(gspca_dev, 0x01, regGpio, 2); 1841 reg_w(gspca_dev, 0x01, regGpio, 2);
1850 break; 1842 break;
1851 } 1843 }
@@ -1944,10 +1936,10 @@ static u32 setexposure(struct gspca_dev *gspca_dev,
1944 u8 expo_c1[] = 1936 u8 expo_c1[] =
1945 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 }; 1937 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1946 1938
1947 if (expo > 0x0280) 1939 if (expo > 0x0390)
1948 expo = 0x0280; 1940 expo = 0x0390;
1949 else if (expo < 0x0040) 1941 else if (expo < 0x0060)
1950 expo = 0x0040; 1942 expo = 0x0060;
1951 expo_c1[3] = expo >> 8; 1943 expo_c1[3] = expo >> 8;
1952 expo_c1[4] = expo; 1944 expo_c1[4] = expo;
1953 i2c_w8(gspca_dev, expo_c1); 1945 i2c_w8(gspca_dev, expo_c1);
@@ -2004,10 +1996,13 @@ static void setbrightness(struct gspca_dev *gspca_dev)
2004 sd->exposure = setexposure(gspca_dev, expo); 1996 sd->exposure = setexposure(gspca_dev, expo);
2005 break; 1997 break;
2006 case SENSOR_GC0307: 1998 case SENSOR_GC0307:
2007 case SENSOR_MT9V111:
2008 expo = brightness; 1999 expo = brightness;
2009 sd->exposure = setexposure(gspca_dev, expo); 2000 sd->exposure = setexposure(gspca_dev, expo);
2010 return; /* don't set the Y offset */ 2001 return; /* don't set the Y offset */
2002 case SENSOR_MT9V111:
2003 expo = brightness << 2;
2004 sd->exposure = setexposure(gspca_dev, expo);
2005 return; /* don't set the Y offset */
2011 case SENSOR_OM6802: 2006 case SENSOR_OM6802:
2012 expo = brightness << 2; 2007 expo = brightness << 2;
2013 sd->exposure = setexposure(gspca_dev, expo); 2008 sd->exposure = setexposure(gspca_dev, expo);
@@ -2199,14 +2194,11 @@ static void setillum(struct gspca_dev *gspca_dev)
2199 sd->ctrls[ILLUM].val ? 0x64 : 0x60); 2194 sd->ctrls[ILLUM].val ? 0x64 : 0x60);
2200 break; 2195 break;
2201 case SENSOR_MT9V111: 2196 case SENSOR_MT9V111:
2202 if (starcam) 2197 reg_w1(gspca_dev, 0x02,
2203 reg_w1(gspca_dev, 0x02, 2198 sd->ctrls[ILLUM].val ? 0x77 : 0x74);
2204 sd->ctrls[ILLUM].val ? 2199/* should have been: */
2205 0x55 : 0x54); /* 370i */ 2200/* 0x55 : 0x54); * 370i */
2206 else 2201/* 0x66 : 0x64); * Clip */
2207 reg_w1(gspca_dev, 0x02,
2208 sd->ctrls[ILLUM].val ?
2209 0x66 : 0x64); /* Clip */
2210 break; 2202 break;
2211 } 2203 }
2212} 2204}
@@ -2271,18 +2263,12 @@ static void setfreq(struct gspca_dev *gspca_dev)
2271static void setjpegqual(struct gspca_dev *gspca_dev) 2263static void setjpegqual(struct gspca_dev *gspca_dev)
2272{ 2264{
2273 struct sd *sd = (struct sd *) gspca_dev; 2265 struct sd *sd = (struct sd *) gspca_dev;
2274 int i, sc;
2275 2266
2276 if (sd->jpegqual < 50) 2267 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2277 sc = 5000 / sd->jpegqual;
2278 else
2279 sc = 200 - sd->jpegqual * 2;
2280#if USB_BUF_SZ < 64 2268#if USB_BUF_SZ < 64
2281#error "No room enough in usb_buf for quantization table" 2269#error "No room enough in usb_buf for quantization table"
2282#endif 2270#endif
2283 for (i = 0; i < 64; i++) 2271 memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2284 gspca_dev->usb_buf[i] =
2285 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
2286 usb_control_msg(gspca_dev->dev, 2272 usb_control_msg(gspca_dev->dev,
2287 usb_sndctrlpipe(gspca_dev->dev, 0), 2273 usb_sndctrlpipe(gspca_dev->dev, 0),
2288 0x08, 2274 0x08,
@@ -2290,9 +2276,7 @@ static void setjpegqual(struct gspca_dev *gspca_dev)
2290 0x0100, 0, 2276 0x0100, 0,
2291 gspca_dev->usb_buf, 64, 2277 gspca_dev->usb_buf, 64,
2292 500); 2278 500);
2293 for (i = 0; i < 64; i++) 2279 memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2294 gspca_dev->usb_buf[i] =
2295 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
2296 usb_control_msg(gspca_dev->dev, 2280 usb_control_msg(gspca_dev->dev,
2297 usb_sndctrlpipe(gspca_dev->dev, 0), 2281 usb_sndctrlpipe(gspca_dev->dev, 0),
2298 0x08, 2282 0x08,
@@ -2305,6 +2289,19 @@ static void setjpegqual(struct gspca_dev *gspca_dev)
2305 reg_w1(gspca_dev, 0x18, sd->reg18); 2289 reg_w1(gspca_dev, 0x18, sd->reg18);
2306} 2290}
2307 2291
2292/* JPEG quality update */
2293/* This function is executed from a work queue. */
2294static void qual_upd(struct work_struct *work)
2295{
2296 struct sd *sd = container_of(work, struct sd, work);
2297 struct gspca_dev *gspca_dev = &sd->gspca_dev;
2298
2299 mutex_lock(&gspca_dev->usb_lock);
2300 PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
2301 setjpegqual(gspca_dev);
2302 mutex_unlock(&gspca_dev->usb_lock);
2303}
2304
2308/* -- start the camera -- */ 2305/* -- start the camera -- */
2309static int sd_start(struct gspca_dev *gspca_dev) 2306static int sd_start(struct gspca_dev *gspca_dev)
2310{ 2307{
@@ -2338,7 +2335,6 @@ static int sd_start(struct gspca_dev *gspca_dev)
2338 /* create the JPEG header */ 2335 /* create the JPEG header */
2339 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width, 2336 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2340 0x21); /* JPEG 422 */ 2337 0x21); /* JPEG 422 */
2341 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2342 2338
2343 /* initialize the bridge */ 2339 /* initialize the bridge */
2344 sn9c1xx = sn_tb[sd->sensor]; 2340 sn9c1xx = sn_tb[sd->sensor];
@@ -2619,6 +2615,11 @@ static int sd_start(struct gspca_dev *gspca_dev)
2619 setcolors(gspca_dev); 2615 setcolors(gspca_dev);
2620 setautogain(gspca_dev); 2616 setautogain(gspca_dev);
2621 setfreq(gspca_dev); 2617 setfreq(gspca_dev);
2618
2619 sd->pktsz = sd->npkt = 0;
2620 sd->nchg = sd->short_mark = 0;
2621 sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
2622
2622 return gspca_dev->usb_err; 2623 return gspca_dev->usb_err;
2623} 2624}
2624 2625
@@ -2695,6 +2696,20 @@ static void sd_stopN(struct gspca_dev *gspca_dev)
2695 /* reg_w1(gspca_dev, 0xf1, 0x01); */ 2696 /* reg_w1(gspca_dev, 0xf1, 0x01); */
2696} 2697}
2697 2698
2699/* called on streamoff with alt==0 and on disconnect */
2700/* the usb_lock is held at entry - restore on exit */
2701static void sd_stop0(struct gspca_dev *gspca_dev)
2702{
2703 struct sd *sd = (struct sd *) gspca_dev;
2704
2705 if (sd->work_thread != NULL) {
2706 mutex_unlock(&gspca_dev->usb_lock);
2707 destroy_workqueue(sd->work_thread);
2708 mutex_lock(&gspca_dev->usb_lock);
2709 sd->work_thread = NULL;
2710 }
2711}
2712
2698static void do_autogain(struct gspca_dev *gspca_dev) 2713static void do_autogain(struct gspca_dev *gspca_dev)
2699{ 2714{
2700 struct sd *sd = (struct sd *) gspca_dev; 2715 struct sd *sd = (struct sd *) gspca_dev;
@@ -2732,6 +2747,7 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2732 (unsigned int) (expotimes << 8)); 2747 (unsigned int) (expotimes << 8));
2733 break; 2748 break;
2734 case SENSOR_OM6802: 2749 case SENSOR_OM6802:
2750 case SENSOR_MT9V111:
2735 expotimes = sd->exposure; 2751 expotimes = sd->exposure;
2736 expotimes += (luma_mean - delta) >> 2; 2752 expotimes += (luma_mean - delta) >> 2;
2737 if (expotimes < 0) 2753 if (expotimes < 0)
@@ -2744,7 +2760,6 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2744/* case SENSOR_MO4000: */ 2760/* case SENSOR_MO4000: */
2745/* case SENSOR_MI0360: */ 2761/* case SENSOR_MI0360: */
2746/* case SENSOR_MI0360B: */ 2762/* case SENSOR_MI0360B: */
2747/* case SENSOR_MT9V111: */
2748 expotimes = sd->exposure; 2763 expotimes = sd->exposure;
2749 expotimes += (luma_mean - delta) >> 6; 2764 expotimes += (luma_mean - delta) >> 6;
2750 if (expotimes < 0) 2765 if (expotimes < 0)
@@ -2757,6 +2772,29 @@ static void do_autogain(struct gspca_dev *gspca_dev)
2757 } 2772 }
2758} 2773}
2759 2774
2775/* set the average luminosity from an isoc marker */
2776static void set_lum(struct sd *sd,
2777 u8 *data)
2778{
2779 int avg_lum;
2780
2781 /* w0 w1 w2
2782 * w3 w4 w5
2783 * w6 w7 w8
2784 */
2785 avg_lum = (data[27] << 8) + data[28] /* w3 */
2786
2787 + (data[31] << 8) + data[32] /* w5 */
2788
2789 + (data[23] << 8) + data[24] /* w1 */
2790
2791 + (data[35] << 8) + data[36] /* w7 */
2792
2793 + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */
2794 avg_lum >>= 10;
2795 atomic_set(&sd->avg_lum, avg_lum);
2796}
2797
2760/* scan the URB packets */ 2798/* scan the URB packets */
2761/* This function is run at interrupt level. */ 2799/* This function is run at interrupt level. */
2762static void sd_pkt_scan(struct gspca_dev *gspca_dev, 2800static void sd_pkt_scan(struct gspca_dev *gspca_dev,
@@ -2764,70 +2802,141 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2764 int len) /* iso packet length */ 2802 int len) /* iso packet length */
2765{ 2803{
2766 struct sd *sd = (struct sd *) gspca_dev; 2804 struct sd *sd = (struct sd *) gspca_dev;
2767 int sof, avg_lum; 2805 int i, new_qual;
2768 2806
2769 /* the image ends on a 64 bytes block starting with 2807 /*
2770 * ff d9 ff ff 00 c4 c4 96 2808 * A frame ends on the marker
2771 * and followed by various information including luminosity */ 2809 * ff ff 00 c4 c4 96 ..
2772 /* this block may be splitted between two packets */ 2810 * which is 62 bytes long and is followed by various information
2773 /* a new image always starts in a new packet */ 2811 * including statuses and luminosity.
2774 switch (gspca_dev->last_packet_type) { 2812 *
2775 case DISCARD_PACKET: /* restart image building */ 2813 * A marker may be splitted on two packets.
2776 sof = len - 64; 2814 *
2777 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) 2815 * The 6th byte of a marker contains the bits:
2778 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2816 * 0x08: USB full
2779 return; 2817 * 0xc0: frame sequence
2780 case LAST_PACKET: /* put the JPEG 422 header */ 2818 * When the bit 'USB full' is set, the frame must be discarded;
2819 * this is also the case when the 2 bytes before the marker are
2820 * not the JPEG end of frame ('ff d9').
2821 */
2822
2823/*fixme: assumption about the following code:
2824 * - there can be only one marker in a packet
2825 */
2826
2827 /* skip the remaining bytes of a short marker */
2828 i = sd->short_mark;
2829 if (i != 0) {
2830 sd->short_mark = 0;
2831 if (i < 0 /* if 'ff' at end of previous packet */
2832 && data[0] == 0xff
2833 && data[1] == 0x00)
2834 goto marker_found;
2835 if (data[0] == 0xff && data[1] == 0xff) {
2836 i = 0;
2837 goto marker_found;
2838 }
2839 len -= i;
2840 if (len <= 0)
2841 return;
2842 data += i;
2843 }
2844
2845 /* count the packets and their size */
2846 sd->npkt++;
2847 sd->pktsz += len;
2848
2849 /* search backwards if there is a marker in the packet */
2850 for (i = len - 1; --i >= 0; ) {
2851 if (data[i] != 0xff) {
2852 i--;
2853 continue;
2854 }
2855 if (data[i + 1] == 0xff) {
2856
2857 /* (there may be 'ff ff' inside a marker) */
2858 if (i + 2 >= len || data[i + 2] == 0x00)
2859 goto marker_found;
2860 }
2861 }
2862
2863 /* no marker found */
2864 /* add the JPEG header if first fragment */
2865 if (data[len - 1] == 0xff)
2866 sd->short_mark = -1;
2867 if (gspca_dev->last_packet_type == LAST_PACKET)
2781 gspca_frame_add(gspca_dev, FIRST_PACKET, 2868 gspca_frame_add(gspca_dev, FIRST_PACKET,
2782 sd->jpeg_hdr, JPEG_HDR_SZ); 2869 sd->jpeg_hdr, JPEG_HDR_SZ);
2783 break;
2784 }
2785 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 2870 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2871 return;
2872
2873 /* marker found */
2874 /* if some error, discard the frame and decrease the quality */
2875marker_found:
2876 new_qual = 0;
2877 if (i > 2) {
2878 if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2879 gspca_dev->last_packet_type = DISCARD_PACKET;
2880 new_qual = -3;
2881 }
2882 } else if (i + 6 < len) {
2883 if (data[i + 6] & 0x08) {
2884 gspca_dev->last_packet_type = DISCARD_PACKET;
2885 new_qual = -5;
2886 }
2887 }
2786 2888
2787 data = gspca_dev->image; 2889 gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2788 if (data == NULL)
2789 return;
2790 sof = gspca_dev->image_len - 64;
2791 if (data[sof] != 0xff
2792 || data[sof + 1] != 0xd9)
2793 return;
2794 2890
2795 /* end of image found - remove the trailing data */ 2891 /* compute the filling rate and a new JPEG quality */
2796 gspca_dev->image_len = sof + 2; 2892 if (new_qual == 0) {
2797 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0); 2893 int r;
2798 if (sd->ag_cnt < 0)
2799 return;
2800/* w1 w2 w3 */
2801/* w4 w5 w6 */
2802/* w7 w8 */
2803/* w4 */
2804 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2805/* w6 */
2806 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2807/* w2 */
2808 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2809/* w8 */
2810 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2811/* w5 */
2812 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2813 avg_lum >>= 4;
2814 atomic_set(&sd->avg_lum, avg_lum);
2815}
2816 2894
2817static int sd_set_jcomp(struct gspca_dev *gspca_dev, 2895 r = (sd->pktsz * 100) /
2818 struct v4l2_jpegcompression *jcomp) 2896 (sd->npkt *
2819{ 2897 gspca_dev->urb[0]->iso_frame_desc[0].length);
2820 struct sd *sd = (struct sd *) gspca_dev; 2898 if (r >= 85)
2899 new_qual = -3;
2900 else if (r < 75)
2901 new_qual = 2;
2902 }
2903 if (new_qual != 0) {
2904 sd->nchg += new_qual;
2905 if (sd->nchg < -6 || sd->nchg >= 12) {
2906 sd->nchg = 0;
2907 new_qual += sd->quality;
2908 if (new_qual < QUALITY_MIN)
2909 new_qual = QUALITY_MIN;
2910 else if (new_qual > QUALITY_MAX)
2911 new_qual = QUALITY_MAX;
2912 if (new_qual != sd->quality) {
2913 sd->quality = new_qual;
2914 queue_work(sd->work_thread, &sd->work);
2915 }
2916 }
2917 } else {
2918 sd->nchg = 0;
2919 }
2920 sd->pktsz = sd->npkt = 0;
2821 2921
2822 if (jcomp->quality < QUALITY_MIN) 2922 /* if the marker is smaller than 62 bytes,
2823 sd->quality = QUALITY_MIN; 2923 * memorize the number of bytes to skip in the next packet */
2824 else if (jcomp->quality > QUALITY_MAX) 2924 if (i + 62 > len) { /* no more usable data */
2825 sd->quality = QUALITY_MAX; 2925 sd->short_mark = i + 62 - len;
2826 else 2926 return;
2827 sd->quality = jcomp->quality; 2927 }
2828 if (gspca_dev->streaming) 2928 if (sd->ag_cnt >= 0)
2829 jpeg_set_qual(sd->jpeg_hdr, sd->quality); 2929 set_lum(sd, data + i);
2830 return 0; 2930
2931 /* if more data, start a new frame */
2932 i += 62;
2933 if (i < len) {
2934 data += i;
2935 len -= i;
2936 gspca_frame_add(gspca_dev, FIRST_PACKET,
2937 sd->jpeg_hdr, JPEG_HDR_SZ);
2938 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2939 }
2831} 2940}
2832 2941
2833static int sd_get_jcomp(struct gspca_dev *gspca_dev, 2942static int sd_get_jcomp(struct gspca_dev *gspca_dev,
@@ -2891,10 +3000,10 @@ static const struct sd_desc sd_desc = {
2891 .init = sd_init, 3000 .init = sd_init,
2892 .start = sd_start, 3001 .start = sd_start,
2893 .stopN = sd_stopN, 3002 .stopN = sd_stopN,
3003 .stop0 = sd_stop0,
2894 .pkt_scan = sd_pkt_scan, 3004 .pkt_scan = sd_pkt_scan,
2895 .dq_callback = do_autogain, 3005 .dq_callback = do_autogain,
2896 .get_jcomp = sd_get_jcomp, 3006 .get_jcomp = sd_get_jcomp,
2897 .set_jcomp = sd_set_jcomp,
2898 .querymenu = sd_querymenu, 3007 .querymenu = sd_querymenu,
2899#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) 3008#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
2900 .int_pkt_scan = sd_int_pkt_scan, 3009 .int_pkt_scan = sd_int_pkt_scan,
@@ -3004,7 +3113,3 @@ static void __exit sd_mod_exit(void)
3004 3113
3005module_init(sd_mod_init); 3114module_init(sd_mod_init);
3006module_exit(sd_mod_exit); 3115module_exit(sd_mod_exit);
3007
3008module_param(starcam, int, 0644);
3009MODULE_PARM_DESC(starcam,
3010 "StarCam model. 0: Clip, 1: 370i");
diff --git a/drivers/media/video/gspca/stv06xx/stv06xx.c b/drivers/media/video/gspca/stv06xx/stv06xx.c
index 7e0661429293..abf1658fa33e 100644
--- a/drivers/media/video/gspca/stv06xx/stv06xx.c
+++ b/drivers/media/video/gspca/stv06xx/stv06xx.c
@@ -525,11 +525,9 @@ static int stv06xx_config(struct gspca_dev *gspca_dev,
525 const struct usb_device_id *id) 525 const struct usb_device_id *id)
526{ 526{
527 struct sd *sd = (struct sd *) gspca_dev; 527 struct sd *sd = (struct sd *) gspca_dev;
528 struct cam *cam;
529 528
530 PDEBUG(D_PROBE, "Configuring camera"); 529 PDEBUG(D_PROBE, "Configuring camera");
531 530
532 cam = &gspca_dev->cam;
533 sd->desc = sd_desc; 531 sd->desc = sd_desc;
534 sd->bridge = id->driver_info; 532 sd->bridge = id->driver_info;
535 gspca_dev->sd_desc = &sd->desc; 533 gspca_dev->sd_desc = &sd->desc;
diff --git a/drivers/media/video/gspca/vicam.c b/drivers/media/video/gspca/vicam.c
new file mode 100644
index 000000000000..84dfbab923b5
--- /dev/null
+++ b/drivers/media/video/gspca/vicam.c
@@ -0,0 +1,381 @@
1/*
2 * gspca ViCam subdriver
3 *
4 * Copyright (C) 2011 Hans de Goede <hdegoede@redhat.com>
5 *
6 * Based on the usbvideo vicam driver, which is:
7 *
8 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
9 * Christopher L Cheney (ccheney@cheney.cx),
10 * Pavel Machek (pavel@ucw.cz),
11 * John Tyner (jtyner@cs.ucr.edu),
12 * Monroe Williams (monroe@pobox.com)
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 */
28
29#define MODULE_NAME "vicam"
30#define HEADER_SIZE 64
31
32#include <linux/workqueue.h>
33#include <linux/slab.h>
34#include <linux/firmware.h>
35#include <linux/ihex.h>
36#include "gspca.h"
37
38MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
39MODULE_DESCRIPTION("GSPCA ViCam USB Camera Driver");
40MODULE_LICENSE("GPL");
41
42enum e_ctrl {
43 GAIN,
44 EXPOSURE,
45 NCTRL /* number of controls */
46};
47
48struct sd {
49 struct gspca_dev gspca_dev; /* !! must be the first item */
50 struct work_struct work_struct;
51 struct workqueue_struct *work_thread;
52 struct gspca_ctrl ctrls[NCTRL];
53};
54
55/* The vicam sensor has a resolution of 512 x 244, with I believe square
56 pixels, but this is forced to a 4:3 ratio by optics. So it has
57 non square pixels :( */
58static struct v4l2_pix_format vicam_mode[] = {
59 { 256, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
60 .bytesperline = 256,
61 .sizeimage = 256 * 122,
62 .colorspace = V4L2_COLORSPACE_SRGB,},
63 /* 2 modes with somewhat more square pixels */
64 { 256, 200, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
65 .bytesperline = 256,
66 .sizeimage = 256 * 200,
67 .colorspace = V4L2_COLORSPACE_SRGB,},
68 { 256, 240, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
69 .bytesperline = 256,
70 .sizeimage = 256 * 240,
71 .colorspace = V4L2_COLORSPACE_SRGB,},
72#if 0 /* This mode has extremely non square pixels, testing use only */
73 { 512, 122, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
74 .bytesperline = 512,
75 .sizeimage = 512 * 122,
76 .colorspace = V4L2_COLORSPACE_SRGB,},
77#endif
78 { 512, 244, V4L2_PIX_FMT_SGRBG8, V4L2_FIELD_NONE,
79 .bytesperline = 512,
80 .sizeimage = 512 * 244,
81 .colorspace = V4L2_COLORSPACE_SRGB,},
82};
83
84static const struct ctrl sd_ctrls[] = {
85[GAIN] = {
86 {
87 .id = V4L2_CID_GAIN,
88 .type = V4L2_CTRL_TYPE_INTEGER,
89 .name = "Gain",
90 .minimum = 0,
91 .maximum = 255,
92 .step = 1,
93 .default_value = 200,
94 },
95 },
96[EXPOSURE] = {
97 {
98 .id = V4L2_CID_EXPOSURE,
99 .type = V4L2_CTRL_TYPE_INTEGER,
100 .name = "Exposure",
101 .minimum = 0,
102 .maximum = 2047,
103 .step = 1,
104 .default_value = 256,
105 },
106 },
107};
108
109static int vicam_control_msg(struct gspca_dev *gspca_dev, u8 request,
110 u16 value, u16 index, u8 *data, u16 len)
111{
112 int ret;
113
114 ret = usb_control_msg(gspca_dev->dev,
115 usb_sndctrlpipe(gspca_dev->dev, 0),
116 request,
117 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
118 value, index, data, len, 1000);
119 if (ret < 0)
120 err("control msg req %02X error %d", request, ret);
121
122 return ret;
123}
124
125static int vicam_set_camera_power(struct gspca_dev *gspca_dev, int state)
126{
127 int ret;
128
129 ret = vicam_control_msg(gspca_dev, 0x50, state, 0, NULL, 0);
130 if (ret < 0)
131 return ret;
132
133 if (state)
134 ret = vicam_control_msg(gspca_dev, 0x55, 1, 0, NULL, 0);
135
136 return ret;
137}
138
139/*
140 * request and read a block of data - see warning on vicam_command.
141 */
142static int vicam_read_frame(struct gspca_dev *gspca_dev, u8 *data, int size)
143{
144 struct sd *sd = (struct sd *)gspca_dev;
145 int ret, unscaled_height, act_len = 0;
146 u8 *req_data = gspca_dev->usb_buf;
147
148 memset(req_data, 0, 16);
149 req_data[0] = sd->ctrls[GAIN].val;
150 if (gspca_dev->width == 256)
151 req_data[1] |= 0x01; /* low nibble x-scale */
152 if (gspca_dev->height <= 122) {
153 req_data[1] |= 0x10; /* high nibble y-scale */
154 unscaled_height = gspca_dev->height * 2;
155 } else
156 unscaled_height = gspca_dev->height;
157 req_data[2] = 0x90; /* unknown, does not seem to do anything */
158 if (unscaled_height <= 200)
159 req_data[3] = 0x06; /* vend? */
160 else if (unscaled_height <= 242) /* Yes 242 not 240 */
161 req_data[3] = 0x07; /* vend? */
162 else /* Up to 244 lines with req_data[3] == 0x08 */
163 req_data[3] = 0x08; /* vend? */
164
165 if (sd->ctrls[EXPOSURE].val < 256) {
166 /* Frame rate maxed out, use partial frame expo time */
167 req_data[4] = 255 - sd->ctrls[EXPOSURE].val;
168 req_data[5] = 0x00;
169 req_data[6] = 0x00;
170 req_data[7] = 0x01;
171 } else {
172 /* Modify frame rate */
173 req_data[4] = 0x00;
174 req_data[5] = 0x00;
175 req_data[6] = sd->ctrls[EXPOSURE].val & 0xFF;
176 req_data[7] = sd->ctrls[EXPOSURE].val >> 8;
177 }
178 req_data[8] = ((244 - unscaled_height) / 2) & ~0x01; /* vstart */
179 /* bytes 9-15 do not seem to affect exposure or image quality */
180
181 mutex_lock(&gspca_dev->usb_lock);
182 ret = vicam_control_msg(gspca_dev, 0x51, 0x80, 0, req_data, 16);
183 mutex_unlock(&gspca_dev->usb_lock);
184 if (ret < 0)
185 return ret;
186
187 ret = usb_bulk_msg(gspca_dev->dev,
188 usb_rcvbulkpipe(gspca_dev->dev, 0x81),
189 data, size, &act_len, 10000);
190 /* successful, it returns 0, otherwise negative */
191 if (ret < 0 || act_len != size) {
192 err("bulk read fail (%d) len %d/%d",
193 ret, act_len, size);
194 return -EIO;
195 }
196 return 0;
197}
198
199/* This function is called as a workqueue function and runs whenever the camera
200 * is streaming data. Because it is a workqueue function it is allowed to sleep
201 * so we can use synchronous USB calls. To avoid possible collisions with other
202 * threads attempting to use the camera's USB interface we take the gspca
203 * usb_lock when performing USB operations. In practice the only thing we need
204 * to protect against is the usb_set_interface call that gspca makes during
205 * stream_off as the camera doesn't provide any controls that the user could try
206 * to change.
207 */
208static void vicam_dostream(struct work_struct *work)
209{
210 struct sd *sd = container_of(work, struct sd, work_struct);
211 struct gspca_dev *gspca_dev = &sd->gspca_dev;
212 int ret, frame_sz;
213 u8 *buffer;
214
215 frame_sz = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].sizeimage +
216 HEADER_SIZE;
217 buffer = kmalloc(frame_sz, GFP_KERNEL | GFP_DMA);
218 if (!buffer) {
219 err("Couldn't allocate USB buffer");
220 goto exit;
221 }
222
223 while (gspca_dev->present && gspca_dev->streaming) {
224 ret = vicam_read_frame(gspca_dev, buffer, frame_sz);
225 if (ret < 0)
226 break;
227
228 /* Note the frame header contents seem to be completely
229 constant, they do not change with either image, or
230 settings. So we simply discard it. The frames have
231 a very similar 64 byte footer, which we don't even
232 bother reading from the cam */
233 gspca_frame_add(gspca_dev, FIRST_PACKET,
234 buffer + HEADER_SIZE,
235 frame_sz - HEADER_SIZE);
236 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
237 }
238exit:
239 kfree(buffer);
240}
241
242/* This function is called at probe time just before sd_init */
243static int sd_config(struct gspca_dev *gspca_dev,
244 const struct usb_device_id *id)
245{
246 struct cam *cam = &gspca_dev->cam;
247 struct sd *sd = (struct sd *)gspca_dev;
248
249 /* We don't use the buffer gspca allocates so make it small. */
250 cam->bulk = 1;
251 cam->bulk_size = 64;
252 cam->cam_mode = vicam_mode;
253 cam->nmodes = ARRAY_SIZE(vicam_mode);
254 cam->ctrls = sd->ctrls;
255
256 INIT_WORK(&sd->work_struct, vicam_dostream);
257
258 return 0;
259}
260
261/* this function is called at probe and resume time */
262static int sd_init(struct gspca_dev *gspca_dev)
263{
264 int ret;
265 const struct ihex_binrec *rec;
266 const struct firmware *uninitialized_var(fw);
267 u8 *firmware_buf;
268
269 ret = request_ihex_firmware(&fw, "vicam/firmware.fw",
270 &gspca_dev->dev->dev);
271 if (ret) {
272 err("Failed to load \"vicam/firmware.fw\": %d\n", ret);
273 return ret;
274 }
275
276 firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
277 if (!firmware_buf) {
278 ret = -ENOMEM;
279 goto exit;
280 }
281 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
282 memcpy(firmware_buf, rec->data, be16_to_cpu(rec->len));
283 ret = vicam_control_msg(gspca_dev, 0xff, 0, 0, firmware_buf,
284 be16_to_cpu(rec->len));
285 if (ret < 0)
286 break;
287 }
288
289 kfree(firmware_buf);
290exit:
291 release_firmware(fw);
292 return ret;
293}
294
295/* Set up for getting frames. */
296static int sd_start(struct gspca_dev *gspca_dev)
297{
298 struct sd *sd = (struct sd *)gspca_dev;
299 int ret;
300
301 ret = vicam_set_camera_power(gspca_dev, 1);
302 if (ret < 0)
303 return ret;
304
305 /* Start the workqueue function to do the streaming */
306 sd->work_thread = create_singlethread_workqueue(MODULE_NAME);
307 queue_work(sd->work_thread, &sd->work_struct);
308
309 return 0;
310}
311
312/* called on streamoff with alt==0 and on disconnect */
313/* the usb_lock is held at entry - restore on exit */
314static void sd_stop0(struct gspca_dev *gspca_dev)
315{
316 struct sd *dev = (struct sd *)gspca_dev;
317
318 /* wait for the work queue to terminate */
319 mutex_unlock(&gspca_dev->usb_lock);
320 /* This waits for vicam_dostream to finish */
321 destroy_workqueue(dev->work_thread);
322 dev->work_thread = NULL;
323 mutex_lock(&gspca_dev->usb_lock);
324
325 vicam_set_camera_power(gspca_dev, 0);
326}
327
328/* Table of supported USB devices */
329static const struct usb_device_id device_table[] = {
330 {USB_DEVICE(0x04c1, 0x009d)},
331 {USB_DEVICE(0x0602, 0x1001)},
332 {}
333};
334
335MODULE_DEVICE_TABLE(usb, device_table);
336
337/* sub-driver description */
338static const struct sd_desc sd_desc = {
339 .name = MODULE_NAME,
340 .ctrls = sd_ctrls,
341 .nctrls = ARRAY_SIZE(sd_ctrls),
342 .config = sd_config,
343 .init = sd_init,
344 .start = sd_start,
345 .stop0 = sd_stop0,
346};
347
348/* -- device connect -- */
349static int sd_probe(struct usb_interface *intf,
350 const struct usb_device_id *id)
351{
352 return gspca_dev_probe(intf, id,
353 &sd_desc,
354 sizeof(struct sd),
355 THIS_MODULE);
356}
357
358static struct usb_driver sd_driver = {
359 .name = MODULE_NAME,
360 .id_table = device_table,
361 .probe = sd_probe,
362 .disconnect = gspca_disconnect,
363#ifdef CONFIG_PM
364 .suspend = gspca_suspend,
365 .resume = gspca_resume,
366#endif
367};
368
369/* -- module insert / remove -- */
370static int __init sd_mod_init(void)
371{
372 return usb_register(&sd_driver);
373}
374
375static void __exit sd_mod_exit(void)
376{
377 usb_deregister(&sd_driver);
378}
379
380module_init(sd_mod_init);
381module_exit(sd_mod_exit);
diff --git a/drivers/media/video/gspca/zc3xx-reg.h b/drivers/media/video/gspca/zc3xx-reg.h
index bfb559c3b713..a1bd94e8ce52 100644
--- a/drivers/media/video/gspca/zc3xx-reg.h
+++ b/drivers/media/video/gspca/zc3xx-reg.h
@@ -160,8 +160,6 @@
160#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6 160#define ZC3XX_R1A6_YMEANAFTERAE 0x01a6
161#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7 161#define ZC3XX_R1A7_CALCGLOBALMEAN 0x01a7
162 162
163#define ZC3XX_R1A2_BLUEMEANAFTERAGC 0x01a2
164
165/* Matrixes */ 163/* Matrixes */
166 164
167/* Color matrix is like : 165/* Color matrix is like :
diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c
index 47236a58bf33..fa164e861cde 100644
--- a/drivers/media/video/gspca/zc3xx.c
+++ b/drivers/media/video/gspca/zc3xx.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Z-Star/Vimicro zc301/zc302p/vc30x library 2 * Z-Star/Vimicro zc301/zc302p/vc30x library
3 * 3 *
4 * Copyright (C) 2009-2010 Jean-Francois Moine <http://moinejf.free.fr> 4 * Copyright (C) 2009-2011 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr 5 * Copyright (C) 2004 2005 2006 Michel Xhaard mxhaard@magic.fr
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -39,6 +39,7 @@ static int force_sensor = -1;
39enum e_ctrl { 39enum e_ctrl {
40 BRIGHTNESS, 40 BRIGHTNESS,
41 CONTRAST, 41 CONTRAST,
42 EXPOSURE,
42 GAMMA, 43 GAMMA,
43 AUTOGAIN, 44 AUTOGAIN,
44 LIGHTFREQ, 45 LIGHTFREQ,
@@ -46,6 +47,8 @@ enum e_ctrl {
46 NCTRLS /* number of controls */ 47 NCTRLS /* number of controls */
47}; 48};
48 49
50#define AUTOGAIN_DEF 1
51
49/* specific webcam descriptor */ 52/* specific webcam descriptor */
50struct sd { 53struct sd {
51 struct gspca_dev gspca_dev; /* !! must be the first item */ 54 struct gspca_dev gspca_dev; /* !! must be the first item */
@@ -73,7 +76,7 @@ enum sensors {
73 SENSOR_CS2102K, 76 SENSOR_CS2102K,
74 SENSOR_GC0303, 77 SENSOR_GC0303,
75 SENSOR_GC0305, 78 SENSOR_GC0305,
76 SENSOR_HDCS2020b, 79 SENSOR_HDCS2020,
77 SENSOR_HV7131B, 80 SENSOR_HV7131B,
78 SENSOR_HV7131R, 81 SENSOR_HV7131R,
79 SENSOR_ICM105A, 82 SENSOR_ICM105A,
@@ -92,7 +95,8 @@ enum sensors {
92 95
93/* V4L2 controls supported by the driver */ 96/* V4L2 controls supported by the driver */
94static void setcontrast(struct gspca_dev *gspca_dev); 97static void setcontrast(struct gspca_dev *gspca_dev);
95static void setautogain(struct gspca_dev *gspca_dev); 98static void setexposure(struct gspca_dev *gspca_dev);
99static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
96static void setlightfreq(struct gspca_dev *gspca_dev); 100static void setlightfreq(struct gspca_dev *gspca_dev);
97static void setsharpness(struct gspca_dev *gspca_dev); 101static void setsharpness(struct gspca_dev *gspca_dev);
98 102
@@ -121,6 +125,18 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
121 }, 125 },
122 .set_control = setcontrast 126 .set_control = setcontrast
123 }, 127 },
128[EXPOSURE] = {
129 {
130 .id = V4L2_CID_EXPOSURE,
131 .type = V4L2_CTRL_TYPE_INTEGER,
132 .name = "Exposure",
133 .minimum = 0x30d,
134 .maximum = 0x493e,
135 .step = 1,
136 .default_value = 0x927
137 },
138 .set_control = setexposure
139 },
124[GAMMA] = { 140[GAMMA] = {
125 { 141 {
126 .id = V4L2_CID_GAMMA, 142 .id = V4L2_CID_GAMMA,
@@ -141,9 +157,10 @@ static const struct ctrl sd_ctrls[NCTRLS] = {
141 .minimum = 0, 157 .minimum = 0,
142 .maximum = 1, 158 .maximum = 1,
143 .step = 1, 159 .step = 1,
144 .default_value = 1, 160 .default_value = AUTOGAIN_DEF,
161 .flags = V4L2_CTRL_FLAG_UPDATE
145 }, 162 },
146 .set_control = setautogain 163 .set = sd_setautogain
147 }, 164 },
148[LIGHTFREQ] = { 165[LIGHTFREQ] = {
149 { 166 {
@@ -1498,7 +1515,7 @@ static const struct usb_action gc0305_NoFliker[] = {
1498 {} 1515 {}
1499}; 1516};
1500 1517
1501static const struct usb_action hdcs2020b_InitialScale[] = { 1518static const struct usb_action hdcs2020_InitialScale[] = {
1502 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1519 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1503 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT}, 1520 {0xa0, 0x11, ZC3XX_R002_CLOCKSELECT},
1504 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */ 1521 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, /* qtable 0x05 */
@@ -1630,7 +1647,7 @@ static const struct usb_action hdcs2020b_InitialScale[] = {
1630 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 1647 {0xa0, 0x40, ZC3XX_R118_BGAIN},
1631 {} 1648 {}
1632}; 1649};
1633static const struct usb_action hdcs2020b_Initial[] = { 1650static const struct usb_action hdcs2020_Initial[] = {
1634 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL}, 1651 {0xa0, 0x01, ZC3XX_R000_SYSTEMCONTROL},
1635 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT}, 1652 {0xa0, 0x00, ZC3XX_R002_CLOCKSELECT},
1636 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING}, 1653 {0xa0, 0x03, ZC3XX_R008_CLOCKSETTING},
@@ -1758,7 +1775,7 @@ static const struct usb_action hdcs2020b_Initial[] = {
1758 {0xa0, 0x40, ZC3XX_R118_BGAIN}, 1775 {0xa0, 0x40, ZC3XX_R118_BGAIN},
1759 {} 1776 {}
1760}; 1777};
1761static const struct usb_action hdcs2020b_50HZ[] = { 1778static const struct usb_action hdcs2020_50HZ[] = {
1762 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 1779 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
1763 {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */ 1780 {0xaa, 0x13, 0x0018}, /* 00,13,18,aa */
1764 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ 1781 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
@@ -1779,7 +1796,7 @@ static const struct usb_action hdcs2020b_50HZ[] = {
1779 {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */ 1796 {0xa0, 0x2f, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2f,cc */
1780 {} 1797 {}
1781}; 1798};
1782static const struct usb_action hdcs2020b_60HZ[] = { 1799static const struct usb_action hdcs2020_60HZ[] = {
1783 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 1800 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
1784 {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */ 1801 {0xaa, 0x13, 0x0031}, /* 00,13,31,aa */
1785 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ 1802 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
@@ -1800,7 +1817,7 @@ static const struct usb_action hdcs2020b_60HZ[] = {
1800 {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */ 1817 {0xa0, 0x2c, ZC3XX_R01F_HSYNC_2}, /* 00,1f,2c,cc */
1801 {} 1818 {}
1802}; 1819};
1803static const struct usb_action hdcs2020b_NoFliker[] = { 1820static const struct usb_action hdcs2020_NoFliker[] = {
1804 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */ 1821 {0xa0, 0x00, ZC3XX_R019_AUTOADJUSTFPS}, /* 00,19,00,cc */
1805 {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */ 1822 {0xaa, 0x13, 0x0010}, /* 00,13,10,aa */
1806 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */ 1823 {0xaa, 0x14, 0x0001}, /* 00,14,01,aa */
@@ -2126,7 +2143,6 @@ static const struct usb_action hv7131r_Initial[] = {
2126 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW}, 2143 {0xa0, 0x80, ZC3XX_R004_FRAMEWIDTHLOW},
2127 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH}, 2144 {0xa0, 0x01, ZC3XX_R005_FRAMEHEIGHTHIGH},
2128 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW}, 2145 {0xa0, 0xe0, ZC3XX_R006_FRAMEHEIGHTLOW},
2129
2130 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW}, 2146 {0xa0, 0x00, ZC3XX_R098_WINYSTARTLOW},
2131 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW}, 2147 {0xa0, 0x00, ZC3XX_R09A_WINXSTARTLOW},
2132 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH}, 2148 {0xa0, 0x01, ZC3XX_R09B_WINHEIGHTHIGH},
@@ -2878,7 +2894,7 @@ static const struct usb_action mc501cb_Initial[] = {
2878 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ 2894 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
2879 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ 2895 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
2880 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ 2896 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
2881 {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ 2897 {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */
2882 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ 2898 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
2883 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ 2899 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
2884 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ 2900 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
@@ -2998,7 +3014,7 @@ static const struct usb_action mc501cb_InitialScale[] = { /* 320x240 */
2998 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */ 3014 {0xaa, 0x11, 0x0001}, /* 00,11,01,aa */
2999 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */ 3015 {0xaa, 0x30, 0x0000}, /* 00,30,00,aa */
3000 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */ 3016 {0xaa, 0x60, 0x0000}, /* 00,60,00,aa */
3001 {0xaa, 0xa0, ZC3XX_R01A_LASTFRAMESTATE}, /* 00,a0,1a,aa */ 3017 {0xaa, 0xa0, 0x001a}, /* 00,a0,1a,aa */
3002 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */ 3018 {0xaa, 0xa1, 0x0000}, /* 00,a1,00,aa */
3003 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */ 3019 {0xaa, 0xa2, 0x003f}, /* 00,a2,3f,aa */
3004 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */ 3020 {0xaa, 0xa3, 0x0028}, /* 00,a3,28,aa */
@@ -3310,7 +3326,7 @@ static const struct usb_action ov7620_50HZ[] = {
3310 {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */ 3326 {0xaa, 0x10, 0x0082}, /* 00,10,82,aa */
3311 {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */ 3327 {0xaa, 0x76, 0x0003}, /* 00,76,03,aa */
3312/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc 3328/* {0xa0, 0x40, ZC3XX_R002_CLOCKSELECT}, * 00,02,40,cc
3313 if mode0 (640x480) */ 3329 * if mode0 (640x480) */
3314 {} 3330 {}
3315}; 3331};
3316static const struct usb_action ov7620_60HZ[] = { 3332static const struct usb_action ov7620_60HZ[] = {
@@ -5828,7 +5844,7 @@ static void setmatrix(struct gspca_dev *gspca_dev)
5828 [SENSOR_CS2102K] = NULL, 5844 [SENSOR_CS2102K] = NULL,
5829 [SENSOR_GC0303] = gc0303_matrix, 5845 [SENSOR_GC0303] = gc0303_matrix,
5830 [SENSOR_GC0305] = gc0305_matrix, 5846 [SENSOR_GC0305] = gc0305_matrix,
5831 [SENSOR_HDCS2020b] = NULL, 5847 [SENSOR_HDCS2020] = NULL,
5832 [SENSOR_HV7131B] = NULL, 5848 [SENSOR_HV7131B] = NULL,
5833 [SENSOR_HV7131R] = po2030_matrix, 5849 [SENSOR_HV7131R] = po2030_matrix,
5834 [SENSOR_ICM105A] = po2030_matrix, 5850 [SENSOR_ICM105A] = po2030_matrix,
@@ -5927,6 +5943,26 @@ static void setcontrast(struct gspca_dev *gspca_dev)
5927 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */ 5943 reg_w(gspca_dev, gr[i], 0x0130 + i); /* gradient */
5928} 5944}
5929 5945
5946static void getexposure(struct gspca_dev *gspca_dev)
5947{
5948 struct sd *sd = (struct sd *) gspca_dev;
5949
5950 sd->ctrls[EXPOSURE].val = (i2c_read(gspca_dev, 0x25) << 9)
5951 | (i2c_read(gspca_dev, 0x26) << 1)
5952 | (i2c_read(gspca_dev, 0x27) >> 7);
5953}
5954
5955static void setexposure(struct gspca_dev *gspca_dev)
5956{
5957 struct sd *sd = (struct sd *) gspca_dev;
5958 int val;
5959
5960 val = sd->ctrls[EXPOSURE].val;
5961 i2c_write(gspca_dev, 0x25, val >> 9, 0x00);
5962 i2c_write(gspca_dev, 0x26, val >> 1, 0x00);
5963 i2c_write(gspca_dev, 0x27, val << 7, 0x00);
5964}
5965
5930static void setquality(struct gspca_dev *gspca_dev) 5966static void setquality(struct gspca_dev *gspca_dev)
5931{ 5967{
5932 struct sd *sd = (struct sd *) gspca_dev; 5968 struct sd *sd = (struct sd *) gspca_dev;
@@ -5990,10 +6026,10 @@ static void setlightfreq(struct gspca_dev *gspca_dev)
5990 {gc0305_NoFliker, gc0305_NoFliker, 6026 {gc0305_NoFliker, gc0305_NoFliker,
5991 gc0305_50HZ, gc0305_50HZ, 6027 gc0305_50HZ, gc0305_50HZ,
5992 gc0305_60HZ, gc0305_60HZ}, 6028 gc0305_60HZ, gc0305_60HZ},
5993 [SENSOR_HDCS2020b] = 6029 [SENSOR_HDCS2020] =
5994 {hdcs2020b_NoFliker, hdcs2020b_NoFliker, 6030 {hdcs2020_NoFliker, hdcs2020_NoFliker,
5995 hdcs2020b_50HZ, hdcs2020b_50HZ, 6031 hdcs2020_50HZ, hdcs2020_50HZ,
5996 hdcs2020b_60HZ, hdcs2020b_60HZ}, 6032 hdcs2020_60HZ, hdcs2020_60HZ},
5997 [SENSOR_HV7131B] = 6033 [SENSOR_HV7131B] =
5998 {hv7131b_NoFliker, hv7131b_NoFlikerScale, 6034 {hv7131b_NoFliker, hv7131b_NoFlikerScale,
5999 hv7131b_50HZ, hv7131b_50HZScale, 6035 hv7131b_50HZ, hv7131b_50HZScale,
@@ -6091,7 +6127,7 @@ static void setautogain(struct gspca_dev *gspca_dev)
6091 6127
6092static void send_unknown(struct gspca_dev *gspca_dev, int sensor) 6128static void send_unknown(struct gspca_dev *gspca_dev, int sensor)
6093{ 6129{
6094 reg_w(gspca_dev, 0x01, 0x0000); /* led off */ 6130 reg_w(gspca_dev, 0x01, 0x0000); /* bridge reset */
6095 switch (sensor) { 6131 switch (sensor) {
6096 case SENSOR_PAS106: 6132 case SENSOR_PAS106:
6097 reg_w(gspca_dev, 0x03, 0x003a); 6133 reg_w(gspca_dev, 0x03, 0x003a);
@@ -6310,6 +6346,7 @@ static int vga_3wr_probe(struct gspca_dev *gspca_dev)
6310 return 0x0a; /* PB0330 */ 6346 return 0x0a; /* PB0330 */
6311 } 6347 }
6312 6348
6349 /* probe gc0303 / gc0305 */
6313 reg_w(gspca_dev, 0x01, 0x0000); 6350 reg_w(gspca_dev, 0x01, 0x0000);
6314 reg_w(gspca_dev, 0x01, 0x0001); 6351 reg_w(gspca_dev, 0x01, 0x0001);
6315 reg_w(gspca_dev, 0x98, 0x008b); 6352 reg_w(gspca_dev, 0x98, 0x008b);
@@ -6414,6 +6451,10 @@ static int sd_config(struct gspca_dev *gspca_dev,
6414 gspca_dev->cam.ctrls = sd->ctrls; 6451 gspca_dev->cam.ctrls = sd->ctrls;
6415 sd->quality = QUALITY_DEF; 6452 sd->quality = QUALITY_DEF;
6416 6453
6454 /* if USB 1.1, let some bandwidth for the audio device */
6455 if (gspca_dev->audio && gspca_dev->dev->speed < USB_SPEED_HIGH)
6456 gspca_dev->nbalt--;
6457
6417 return 0; 6458 return 0;
6418} 6459}
6419 6460
@@ -6429,7 +6470,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
6429 [SENSOR_CS2102K] = 5, 6470 [SENSOR_CS2102K] = 5,
6430 [SENSOR_GC0303] = 3, 6471 [SENSOR_GC0303] = 3,
6431 [SENSOR_GC0305] = 4, 6472 [SENSOR_GC0305] = 4,
6432 [SENSOR_HDCS2020b] = 4, 6473 [SENSOR_HDCS2020] = 4,
6433 [SENSOR_HV7131B] = 4, 6474 [SENSOR_HV7131B] = 4,
6434 [SENSOR_HV7131R] = 4, 6475 [SENSOR_HV7131R] = 4,
6435 [SENSOR_ICM105A] = 4, 6476 [SENSOR_ICM105A] = 4,
@@ -6450,7 +6491,7 @@ static int sd_init(struct gspca_dev *gspca_dev)
6450 [SENSOR_CS2102K] = 1, 6491 [SENSOR_CS2102K] = 1,
6451 [SENSOR_GC0303] = 1, 6492 [SENSOR_GC0303] = 1,
6452 [SENSOR_GC0305] = 1, 6493 [SENSOR_GC0305] = 1,
6453 [SENSOR_HDCS2020b] = 1, 6494 [SENSOR_HDCS2020] = 1,
6454 [SENSOR_HV7131B] = 1, 6495 [SENSOR_HV7131B] = 1,
6455 [SENSOR_HV7131R] = 1, 6496 [SENSOR_HV7131R] = 1,
6456 [SENSOR_ICM105A] = 1, 6497 [SENSOR_ICM105A] = 1,
@@ -6513,8 +6554,8 @@ static int sd_init(struct gspca_dev *gspca_dev)
6513 sd->sensor = SENSOR_CS2102; 6554 sd->sensor = SENSOR_CS2102;
6514 break; 6555 break;
6515 case 0x08: 6556 case 0x08:
6516 PDEBUG(D_PROBE, "Find Sensor HDCS2020(b)"); 6557 PDEBUG(D_PROBE, "Find Sensor HDCS2020");
6517 sd->sensor = SENSOR_HDCS2020b; 6558 sd->sensor = SENSOR_HDCS2020;
6518 break; 6559 break;
6519 case 0x0a: 6560 case 0x0a:
6520 PDEBUG(D_PROBE, 6561 PDEBUG(D_PROBE,
@@ -6619,10 +6660,19 @@ static int sd_init(struct gspca_dev *gspca_dev)
6619 sd->ctrls[GAMMA].def = gamma[sd->sensor]; 6660 sd->ctrls[GAMMA].def = gamma[sd->sensor];
6620 6661
6621 switch (sd->sensor) { 6662 switch (sd->sensor) {
6663 case SENSOR_HV7131R:
6664 break;
6622 case SENSOR_OV7630C: 6665 case SENSOR_OV7630C:
6623 gspca_dev->ctrl_dis = (1 << LIGHTFREQ); 6666 gspca_dev->ctrl_dis = (1 << LIGHTFREQ) | (1 << EXPOSURE);
6667 break;
6668 default:
6669 gspca_dev->ctrl_dis = (1 << EXPOSURE);
6624 break; 6670 break;
6625 } 6671 }
6672#if AUTOGAIN_DEF
6673 if (sd->ctrls[AUTOGAIN].val)
6674 gspca_dev->ctrl_inac = (1 << EXPOSURE);
6675#endif
6626 6676
6627 /* switch off the led */ 6677 /* switch off the led */
6628 reg_w(gspca_dev, 0x01, 0x0000); 6678 reg_w(gspca_dev, 0x01, 0x0000);
@@ -6644,8 +6694,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
6644 {gc0303_Initial, gc0303_InitialScale}, 6694 {gc0303_Initial, gc0303_InitialScale},
6645 [SENSOR_GC0305] = 6695 [SENSOR_GC0305] =
6646 {gc0305_Initial, gc0305_InitialScale}, 6696 {gc0305_Initial, gc0305_InitialScale},
6647 [SENSOR_HDCS2020b] = 6697 [SENSOR_HDCS2020] =
6648 {hdcs2020b_Initial, hdcs2020b_InitialScale}, 6698 {hdcs2020_Initial, hdcs2020_InitialScale},
6649 [SENSOR_HV7131B] = 6699 [SENSOR_HV7131B] =
6650 {hv7131b_Initial, hv7131b_InitialScale}, 6700 {hv7131b_Initial, hv7131b_InitialScale},
6651 [SENSOR_HV7131R] = 6701 [SENSOR_HV7131R] =
@@ -6739,7 +6789,7 @@ static int sd_start(struct gspca_dev *gspca_dev)
6739 /* set the gamma tables when not set */ 6789 /* set the gamma tables when not set */
6740 switch (sd->sensor) { 6790 switch (sd->sensor) {
6741 case SENSOR_CS2102K: /* gamma set in xxx_Initial */ 6791 case SENSOR_CS2102K: /* gamma set in xxx_Initial */
6742 case SENSOR_HDCS2020b: 6792 case SENSOR_HDCS2020:
6743 case SENSOR_OV7630C: 6793 case SENSOR_OV7630C:
6744 break; 6794 break;
6745 default: 6795 default:
@@ -6768,9 +6818,8 @@ static int sd_start(struct gspca_dev *gspca_dev)
6768 reg_w(gspca_dev, 0x40, 0x0117); 6818 reg_w(gspca_dev, 0x40, 0x0117);
6769 break; 6819 break;
6770 case SENSOR_HV7131R: 6820 case SENSOR_HV7131R:
6771 i2c_write(gspca_dev, 0x25, 0x04, 0x00); /* exposure */ 6821 if (!sd->ctrls[AUTOGAIN].val)
6772 i2c_write(gspca_dev, 0x26, 0x93, 0x00); 6822 setexposure(gspca_dev);
6773 i2c_write(gspca_dev, 0x27, 0xe0, 0x00);
6774 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN); 6823 reg_w(gspca_dev, 0x00, ZC3XX_R1A7_CALCGLOBALMEAN);
6775 break; 6824 break;
6776 case SENSOR_GC0305: 6825 case SENSOR_GC0305:
@@ -6848,6 +6897,23 @@ static void sd_pkt_scan(struct gspca_dev *gspca_dev,
6848 gspca_frame_add(gspca_dev, INTER_PACKET, data, len); 6897 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
6849} 6898}
6850 6899
6900static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
6901{
6902 struct sd *sd = (struct sd *) gspca_dev;
6903
6904 sd->ctrls[AUTOGAIN].val = val;
6905 if (val) {
6906 gspca_dev->ctrl_inac |= (1 << EXPOSURE);
6907 } else {
6908 gspca_dev->ctrl_inac &= ~(1 << EXPOSURE);
6909 if (gspca_dev->streaming)
6910 getexposure(gspca_dev);
6911 }
6912 if (gspca_dev->streaming)
6913 setautogain(gspca_dev);
6914 return gspca_dev->usb_err;
6915}
6916
6851static int sd_querymenu(struct gspca_dev *gspca_dev, 6917static int sd_querymenu(struct gspca_dev *gspca_dev,
6852 struct v4l2_querymenu *menu) 6918 struct v4l2_querymenu *menu)
6853{ 6919{
diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c
index e53fa55d56a1..2a1ac287591d 100644
--- a/drivers/media/video/hdpvr/hdpvr-i2c.c
+++ b/drivers/media/video/hdpvr/hdpvr-i2c.c
@@ -52,25 +52,36 @@ struct i2c_client *hdpvr_register_ir_rx_i2c(struct hdpvr_device *dev)
52 }; 52 };
53 53
54 /* Our default information for ir-kbd-i2c.c to use */ 54 /* Our default information for ir-kbd-i2c.c to use */
55 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 55 init_data->ir_codes = RC_MAP_HAUPPAUGE;
56 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 56 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
57 init_data->type = RC_TYPE_RC5; 57 init_data->type = RC_TYPE_RC5;
58 init_data->name = "HD-PVR"; 58 init_data->name = "HD-PVR";
59 init_data->polling_interval = 405; /* ms, duplicated from Windows */
59 hdpvr_ir_rx_i2c_board_info.platform_data = init_data; 60 hdpvr_ir_rx_i2c_board_info.platform_data = init_data;
60 61
61 return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info); 62 return i2c_new_device(&dev->i2c_adapter, &hdpvr_ir_rx_i2c_board_info);
62} 63}
63 64
64static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus, 65static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus,
65 unsigned char addr, char *data, int len) 66 unsigned char addr, char *wdata, int wlen,
67 char *data, int len)
66{ 68{
67 int ret; 69 int ret;
68 70
69 if (len > sizeof(dev->i2c_buf)) 71 if ((len > sizeof(dev->i2c_buf)) || (wlen > sizeof(dev->i2c_buf)))
70 return -EINVAL; 72 return -EINVAL;
71 73
72 ret = usb_control_msg(dev->udev, 74 if (wlen) {
73 usb_rcvctrlpipe(dev->udev, 0), 75 memcpy(&dev->i2c_buf, wdata, wlen);
76 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
77 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
78 (bus << 8) | addr, 0, &dev->i2c_buf,
79 wlen, 1000);
80 if (ret < 0)
81 return ret;
82 }
83
84 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
74 REQTYPE_I2C_READ, CTRL_READ_REQUEST, 85 REQTYPE_I2C_READ, CTRL_READ_REQUEST,
75 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); 86 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
76 87
@@ -92,16 +103,14 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus,
92 return -EINVAL; 103 return -EINVAL;
93 104
94 memcpy(&dev->i2c_buf, data, len); 105 memcpy(&dev->i2c_buf, data, len);
95 ret = usb_control_msg(dev->udev, 106 ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
96 usb_sndctrlpipe(dev->udev, 0),
97 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, 107 REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST,
98 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); 108 (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000);
99 109
100 if (ret < 0) 110 if (ret < 0)
101 return ret; 111 return ret;
102 112
103 ret = usb_control_msg(dev->udev, 113 ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
104 usb_rcvctrlpipe(dev->udev, 0),
105 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, 114 REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST,
106 0, 0, &dev->i2c_buf, 2, 1000); 115 0, 0, &dev->i2c_buf, 2, 1000);
107 116
@@ -117,24 +126,49 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs,
117 int num) 126 int num)
118{ 127{
119 struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter); 128 struct hdpvr_device *dev = i2c_get_adapdata(i2c_adapter);
120 int retval = 0, i, addr; 129 int retval = 0, addr;
121 130
122 if (num <= 0) 131 if (num <= 0)
123 return 0; 132 return 0;
124 133
125 mutex_lock(&dev->i2c_mutex); 134 mutex_lock(&dev->i2c_mutex);
126 135
127 for (i = 0; i < num && !retval; i++) { 136 addr = msgs[0].addr << 1;
128 addr = msgs[i].addr << 1;
129 137
130 if (msgs[i].flags & I2C_M_RD) 138 if (num == 1) {
131 retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf, 139 if (msgs[0].flags & I2C_M_RD)
132 msgs[i].len); 140 retval = hdpvr_i2c_read(dev, 1, addr, NULL, 0,
141 msgs[0].buf, msgs[0].len);
133 else 142 else
134 retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf, 143 retval = hdpvr_i2c_write(dev, 1, addr, msgs[0].buf,
135 msgs[i].len); 144 msgs[0].len);
145 } else if (num == 2) {
146 if (msgs[0].addr != msgs[1].addr) {
147 v4l2_warn(&dev->v4l2_dev, "refusing 2-phase i2c xfer "
148 "with conflicting target addresses\n");
149 retval = -EINVAL;
150 goto out;
151 }
152
153 if ((msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD)) {
154 v4l2_warn(&dev->v4l2_dev, "refusing complex xfer with "
155 "r0=%d, r1=%d\n", msgs[0].flags & I2C_M_RD,
156 msgs[1].flags & I2C_M_RD);
157 retval = -EINVAL;
158 goto out;
159 }
160
161 /*
162 * Write followed by atomic read is the only complex xfer that
163 * we actually support here.
164 */
165 retval = hdpvr_i2c_read(dev, 1, addr, msgs[0].buf, msgs[0].len,
166 msgs[1].buf, msgs[1].len);
167 } else {
168 v4l2_warn(&dev->v4l2_dev, "refusing %d-phase i2c xfer\n", num);
136 } 169 }
137 170
171out:
138 mutex_unlock(&dev->i2c_mutex); 172 mutex_unlock(&dev->i2c_mutex);
139 173
140 return retval ? retval : num; 174 return retval ? retval : num;
@@ -158,11 +192,11 @@ static struct i2c_adapter hdpvr_i2c_adapter_template = {
158 192
159static int hdpvr_activate_ir(struct hdpvr_device *dev) 193static int hdpvr_activate_ir(struct hdpvr_device *dev)
160{ 194{
161 char buffer[8]; 195 char buffer[2];
162 196
163 mutex_lock(&dev->i2c_mutex); 197 mutex_lock(&dev->i2c_mutex);
164 198
165 hdpvr_i2c_read(dev, 0, 0x54, buffer, 1); 199 hdpvr_i2c_read(dev, 0, 0x54, NULL, 0, buffer, 1);
166 200
167 buffer[0] = 0; 201 buffer[0] = 0;
168 buffer[1] = 0x8; 202 buffer[1] = 0x8;
diff --git a/drivers/media/video/ir-kbd-i2c.c b/drivers/media/video/ir-kbd-i2c.c
index a221ad68b330..3ab875d036e1 100644
--- a/drivers/media/video/ir-kbd-i2c.c
+++ b/drivers/media/video/ir-kbd-i2c.c
@@ -55,10 +55,6 @@
55static int debug; 55static int debug;
56module_param(debug, int, 0644); /* debug level (0,1,2) */ 56module_param(debug, int, 0644); /* debug level (0,1,2) */
57 57
58static int hauppauge;
59module_param(hauppauge, int, 0644); /* Choose Hauppauge remote */
60MODULE_PARM_DESC(hauppauge, "Specify Hauppauge remote: 0=black, 1=grey (defaults to 0)");
61
62 58
63#define MODULE_NAME "ir-kbd-i2c" 59#define MODULE_NAME "ir-kbd-i2c"
64#define dprintk(level, fmt, arg...) if (debug >= level) \ 60#define dprintk(level, fmt, arg...) if (debug >= level) \
@@ -105,10 +101,6 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
105 /* invalid key press */ 101 /* invalid key press */
106 return 0; 102 return 0;
107 103
108 if (dev!=0x1e && dev!=0x1f)
109 /* not a hauppauge remote */
110 return 0;
111
112 if (!range) 104 if (!range)
113 code += 64; 105 code += 64;
114 106
@@ -116,7 +108,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
116 start, range, toggle, dev, code); 108 start, range, toggle, dev, code);
117 109
118 /* return key */ 110 /* return key */
119 *ir_key = code; 111 *ir_key = (dev << 8) | code;
120 *ir_raw = ircode; 112 *ir_raw = ircode;
121 return 1; 113 return 1;
122} 114}
@@ -312,11 +304,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
312 name = "Hauppauge"; 304 name = "Hauppauge";
313 ir->get_key = get_key_haup; 305 ir->get_key = get_key_haup;
314 rc_type = RC_TYPE_RC5; 306 rc_type = RC_TYPE_RC5;
315 if (hauppauge == 1) { 307 ir_codes = RC_MAP_HAUPPAUGE;
316 ir_codes = RC_MAP_HAUPPAUGE_NEW;
317 } else {
318 ir_codes = RC_MAP_RC5_TV;
319 }
320 break; 308 break;
321 case 0x30: 309 case 0x30:
322 name = "KNC One"; 310 name = "KNC One";
@@ -340,7 +328,7 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
340 name = "Hauppauge/Zilog Z8"; 328 name = "Hauppauge/Zilog Z8";
341 ir->get_key = get_key_haup_xvr; 329 ir->get_key = get_key_haup_xvr;
342 rc_type = RC_TYPE_RC5; 330 rc_type = RC_TYPE_RC5;
343 ir_codes = hauppauge ? RC_MAP_HAUPPAUGE_NEW : RC_MAP_RC5_TV; 331 ir_codes = RC_MAP_HAUPPAUGE;
344 break; 332 break;
345 } 333 }
346 334
diff --git a/drivers/media/video/ivtv/ivtv-driver.h b/drivers/media/video/ivtv/ivtv-driver.h
index 04bacdbd10bb..84bdf0f42a8e 100644
--- a/drivers/media/video/ivtv/ivtv-driver.h
+++ b/drivers/media/video/ivtv/ivtv-driver.h
@@ -383,7 +383,6 @@ struct ivtv_open_id {
383 u32 open_id; /* unique ID for this file descriptor */ 383 u32 open_id; /* unique ID for this file descriptor */
384 int type; /* stream type */ 384 int type; /* stream type */
385 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */ 385 int yuv_frames; /* 1: started OUT_UDMA_YUV output mode */
386 enum v4l2_priority prio; /* priority */
387 struct ivtv *itv; 386 struct ivtv *itv;
388}; 387};
389 388
@@ -710,7 +709,6 @@ struct ivtv {
710 709
711 /* Miscellaneous */ 710 /* Miscellaneous */
712 u32 open_id; /* incremented each time an open occurs, is >= 1 */ 711 u32 open_id; /* incremented each time an open occurs, is >= 1 */
713 struct v4l2_prio_state prio; /* priority state */
714 int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */ 712 int search_pack_header; /* 1 if ivtv_copy_buf_to_user() is scanning for a pack header (0xba) */
715 int speed; /* current playback speed setting */ 713 int speed; /* current playback speed setting */
716 u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */ 714 u8 speed_mute_audio; /* 1 if audio should be muted when fast forward */
diff --git a/drivers/media/video/ivtv/ivtv-fileops.c b/drivers/media/video/ivtv/ivtv-fileops.c
index c57a58523ca8..a7f54b010a5c 100644
--- a/drivers/media/video/ivtv/ivtv-fileops.c
+++ b/drivers/media/video/ivtv/ivtv-fileops.c
@@ -856,7 +856,6 @@ int ivtv_v4l2_close(struct file *filp)
856 856
857 IVTV_DEBUG_FILE("close %s\n", s->name); 857 IVTV_DEBUG_FILE("close %s\n", s->name);
858 858
859 v4l2_prio_close(&itv->prio, id->prio);
860 v4l2_fh_del(fh); 859 v4l2_fh_del(fh);
861 v4l2_fh_exit(fh); 860 v4l2_fh_exit(fh);
862 861
@@ -973,7 +972,6 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
973 } 972 }
974 item->itv = itv; 973 item->itv = itv;
975 item->type = s->type; 974 item->type = s->type;
976 v4l2_prio_open(&itv->prio, &item->prio);
977 975
978 item->open_id = itv->open_id++; 976 item->open_id = itv->open_id++;
979 filp->private_data = &item->fh; 977 filp->private_data = &item->fh;
@@ -982,6 +980,7 @@ static int ivtv_serialized_open(struct ivtv_stream *s, struct file *filp)
982 /* Try to claim this stream */ 980 /* Try to claim this stream */
983 if (ivtv_claim_stream(item, item->type)) { 981 if (ivtv_claim_stream(item, item->type)) {
984 /* No, it's already in use */ 982 /* No, it's already in use */
983 v4l2_fh_exit(&item->fh);
985 kfree(item); 984 kfree(item);
986 return -EBUSY; 985 return -EBUSY;
987 } 986 }
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 9fb86a081c0f..d47f41a0ef66 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -205,15 +205,14 @@ static int ivtv_i2c_new_ir(struct ivtv *itv, u32 hw, const char *type, u8 addr)
205 break; 205 break;
206 case IVTV_HW_I2C_IR_RX_HAUP_EXT: 206 case IVTV_HW_I2C_IR_RX_HAUP_EXT:
207 case IVTV_HW_I2C_IR_RX_HAUP_INT: 207 case IVTV_HW_I2C_IR_RX_HAUP_INT:
208 /* Default to old black remote */ 208 init_data->ir_codes = RC_MAP_HAUPPAUGE;
209 init_data->ir_codes = RC_MAP_RC5_TV;
210 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; 209 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
211 init_data->type = RC_TYPE_RC5; 210 init_data->type = RC_TYPE_RC5;
212 init_data->name = itv->card_name; 211 init_data->name = itv->card_name;
213 break; 212 break;
214 case IVTV_HW_Z8F0811_IR_RX_HAUP: 213 case IVTV_HW_Z8F0811_IR_RX_HAUP:
215 /* Default to grey remote */ 214 /* Default to grey remote */
216 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 215 init_data->ir_codes = RC_MAP_HAUPPAUGE;
217 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 216 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
218 init_data->type = RC_TYPE_RC5; 217 init_data->type = RC_TYPE_RC5;
219 init_data->name = itv->card_name; 218 init_data->name = itv->card_name;
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index b686da5e4326..1689783cd19a 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -313,7 +313,7 @@ static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
313 313
314static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt) 314static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
315{ 315{
316 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 316 struct ivtv *itv = fh2id(fh)->itv;
317 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 317 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
318 318
319 vbifmt->reserved[0] = 0; 319 vbifmt->reserved[0] = 0;
@@ -334,7 +334,7 @@ static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
334 334
335static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 335static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
336{ 336{
337 struct ivtv_open_id *id = fh; 337 struct ivtv_open_id *id = fh2id(fh);
338 struct ivtv *itv = id->itv; 338 struct ivtv *itv = id->itv;
339 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 339 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
340 340
@@ -358,7 +358,7 @@ static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
358 358
359static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 359static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
360{ 360{
361 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 361 struct ivtv *itv = fh2id(fh)->itv;
362 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi; 362 struct v4l2_vbi_format *vbifmt = &fmt->fmt.vbi;
363 363
364 vbifmt->sampling_rate = 27000000; 364 vbifmt->sampling_rate = 27000000;
@@ -377,7 +377,7 @@ static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
377static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 377static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
378{ 378{
379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
380 struct ivtv_open_id *id = fh; 380 struct ivtv_open_id *id = fh2id(fh);
381 struct ivtv *itv = id->itv; 381 struct ivtv *itv = id->itv;
382 382
383 vbifmt->reserved[0] = 0; 383 vbifmt->reserved[0] = 0;
@@ -398,7 +398,7 @@ static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
398 398
399static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 399static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
400{ 400{
401 struct ivtv_open_id *id = fh; 401 struct ivtv_open_id *id = fh2id(fh);
402 struct ivtv *itv = id->itv; 402 struct ivtv *itv = id->itv;
403 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix; 403 struct v4l2_pix_format *pixfmt = &fmt->fmt.pix;
404 404
@@ -439,7 +439,7 @@ static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
439 439
440static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 440static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
441{ 441{
442 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 442 struct ivtv *itv = fh2id(fh)->itv;
443 struct v4l2_window *winfmt = &fmt->fmt.win; 443 struct v4l2_window *winfmt = &fmt->fmt.win;
444 444
445 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 445 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
@@ -463,7 +463,7 @@ static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_
463 463
464static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 464static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
465{ 465{
466 struct ivtv_open_id *id = fh; 466 struct ivtv_open_id *id = fh2id(fh);
467 struct ivtv *itv = id->itv; 467 struct ivtv *itv = id->itv;
468 int w = fmt->fmt.pix.width; 468 int w = fmt->fmt.pix.width;
469 int h = fmt->fmt.pix.height; 469 int h = fmt->fmt.pix.height;
@@ -492,7 +492,7 @@ static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format
492static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 492static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
493{ 493{
494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
495 struct ivtv_open_id *id = fh; 495 struct ivtv_open_id *id = fh2id(fh);
496 struct ivtv *itv = id->itv; 496 struct ivtv *itv = id->itv;
497 497
498 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) 498 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
@@ -512,7 +512,7 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_
512 512
513static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 513static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
514{ 514{
515 struct ivtv_open_id *id = fh; 515 struct ivtv_open_id *id = fh2id(fh);
516 s32 w = fmt->fmt.pix.width; 516 s32 w = fmt->fmt.pix.width;
517 s32 h = fmt->fmt.pix.height; 517 s32 h = fmt->fmt.pix.height;
518 int field = fmt->fmt.pix.field; 518 int field = fmt->fmt.pix.field;
@@ -546,7 +546,7 @@ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format
546 546
547static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 547static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
548{ 548{
549 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 549 struct ivtv *itv = fh2id(fh)->itv;
550 u32 chromakey = fmt->fmt.win.chromakey; 550 u32 chromakey = fmt->fmt.win.chromakey;
551 u8 global_alpha = fmt->fmt.win.global_alpha; 551 u8 global_alpha = fmt->fmt.win.global_alpha;
552 552
@@ -565,7 +565,7 @@ static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_fo
565 565
566static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt) 566static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
567{ 567{
568 struct ivtv_open_id *id = fh; 568 struct ivtv_open_id *id = fh2id(fh);
569 struct ivtv *itv = id->itv; 569 struct ivtv *itv = id->itv;
570 struct v4l2_mbus_framefmt mbus_fmt; 570 struct v4l2_mbus_framefmt mbus_fmt;
571 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); 571 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
@@ -594,7 +594,7 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f
594 594
595static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 595static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
596{ 596{
597 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 597 struct ivtv *itv = fh2id(fh)->itv;
598 598
599 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0) 599 if (!ivtv_raw_vbi(itv) && atomic_read(&itv->capturing) > 0)
600 return -EBUSY; 600 return -EBUSY;
@@ -607,7 +607,7 @@ static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *f
607static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt) 607static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
608{ 608{
609 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 609 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
610 struct ivtv_open_id *id = fh; 610 struct ivtv_open_id *id = fh2id(fh);
611 struct ivtv *itv = id->itv; 611 struct ivtv *itv = id->itv;
612 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt); 612 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
613 613
@@ -625,7 +625,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo
625 625
626static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) 626static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
627{ 627{
628 struct ivtv_open_id *id = fh; 628 struct ivtv_open_id *id = fh2id(fh);
629 struct ivtv *itv = id->itv; 629 struct ivtv *itv = id->itv;
630 struct yuv_playback_info *yi = &itv->yuv_info; 630 struct yuv_playback_info *yi = &itv->yuv_info;
631 int ret = ivtv_try_fmt_vid_out(file, fh, fmt); 631 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
@@ -670,7 +670,7 @@ static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *f
670 670
671static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt) 671static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
672{ 672{
673 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 673 struct ivtv *itv = fh2id(fh)->itv;
674 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt); 674 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
675 675
676 if (ret == 0) { 676 if (ret == 0) {
@@ -683,7 +683,7 @@ static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_f
683 683
684static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip) 684static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_dbg_chip_ident *chip)
685{ 685{
686 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 686 struct ivtv *itv = fh2id(fh)->itv;
687 687
688 chip->ident = V4L2_IDENT_NONE; 688 chip->ident = V4L2_IDENT_NONE;
689 chip->revision = 0; 689 chip->revision = 0;
@@ -727,7 +727,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
727 727
728static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) 728static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
729{ 729{
730 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 730 struct ivtv *itv = fh2id(fh)->itv;
731 731
732 if (v4l2_chip_match_host(&reg->match)) 732 if (v4l2_chip_match_host(&reg->match))
733 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg); 733 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
@@ -739,7 +739,7 @@ static int ivtv_g_register(struct file *file, void *fh, struct v4l2_dbg_register
739 739
740static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg) 740static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register *reg)
741{ 741{
742 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 742 struct ivtv *itv = fh2id(fh)->itv;
743 743
744 if (v4l2_chip_match_host(&reg->match)) 744 if (v4l2_chip_match_host(&reg->match))
745 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg); 745 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
@@ -750,26 +750,9 @@ static int ivtv_s_register(struct file *file, void *fh, struct v4l2_dbg_register
750} 750}
751#endif 751#endif
752 752
753static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
754{
755 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
756
757 *p = v4l2_prio_max(&itv->prio);
758
759 return 0;
760}
761
762static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
763{
764 struct ivtv_open_id *id = fh;
765 struct ivtv *itv = id->itv;
766
767 return v4l2_prio_change(&itv->prio, &id->prio, prio);
768}
769
770static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap) 753static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
771{ 754{
772 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 755 struct ivtv *itv = fh2id(fh)->itv;
773 756
774 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); 757 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
775 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); 758 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
@@ -781,14 +764,14 @@ static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vc
781 764
782static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin) 765static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
783{ 766{
784 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 767 struct ivtv *itv = fh2id(fh)->itv;
785 768
786 return ivtv_get_audio_input(itv, vin->index, vin); 769 return ivtv_get_audio_input(itv, vin->index, vin);
787} 770}
788 771
789static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin) 772static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
790{ 773{
791 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 774 struct ivtv *itv = fh2id(fh)->itv;
792 775
793 vin->index = itv->audio_input; 776 vin->index = itv->audio_input;
794 return ivtv_get_audio_input(itv, vin->index, vin); 777 return ivtv_get_audio_input(itv, vin->index, vin);
@@ -796,7 +779,7 @@ static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
796 779
797static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout) 780static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
798{ 781{
799 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 782 struct ivtv *itv = fh2id(fh)->itv;
800 783
801 if (vout->index >= itv->nof_audio_inputs) 784 if (vout->index >= itv->nof_audio_inputs)
802 return -EINVAL; 785 return -EINVAL;
@@ -809,7 +792,7 @@ static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
809 792
810static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin) 793static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
811{ 794{
812 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 795 struct ivtv *itv = fh2id(fh)->itv;
813 796
814 /* set it to defaults from our table */ 797 /* set it to defaults from our table */
815 return ivtv_get_audio_output(itv, vin->index, vin); 798 return ivtv_get_audio_output(itv, vin->index, vin);
@@ -817,7 +800,7 @@ static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vi
817 800
818static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin) 801static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
819{ 802{
820 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 803 struct ivtv *itv = fh2id(fh)->itv;
821 804
822 vin->index = 0; 805 vin->index = 0;
823 return ivtv_get_audio_output(itv, vin->index, vin); 806 return ivtv_get_audio_output(itv, vin->index, vin);
@@ -825,14 +808,14 @@ static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
825 808
826static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout) 809static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
827{ 810{
828 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 811 struct ivtv *itv = fh2id(fh)->itv;
829 812
830 return ivtv_get_audio_output(itv, vout->index, vout); 813 return ivtv_get_audio_output(itv, vout->index, vout);
831} 814}
832 815
833static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin) 816static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
834{ 817{
835 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 818 struct ivtv *itv = fh2id(fh)->itv;
836 819
837 /* set it to defaults from our table */ 820 /* set it to defaults from our table */
838 return ivtv_get_input(itv, vin->index, vin); 821 return ivtv_get_input(itv, vin->index, vin);
@@ -840,14 +823,14 @@ static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
840 823
841static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout) 824static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
842{ 825{
843 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 826 struct ivtv *itv = fh2id(fh)->itv;
844 827
845 return ivtv_get_output(itv, vout->index, vout); 828 return ivtv_get_output(itv, vout->index, vout);
846} 829}
847 830
848static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap) 831static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
849{ 832{
850 struct ivtv_open_id *id = fh; 833 struct ivtv_open_id *id = fh2id(fh);
851 struct ivtv *itv = id->itv; 834 struct ivtv *itv = id->itv;
852 struct yuv_playback_info *yi = &itv->yuv_info; 835 struct yuv_playback_info *yi = &itv->yuv_info;
853 int streamtype; 836 int streamtype;
@@ -884,7 +867,7 @@ static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropca
884 867
885static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) 868static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
886{ 869{
887 struct ivtv_open_id *id = fh; 870 struct ivtv_open_id *id = fh2id(fh);
888 struct ivtv *itv = id->itv; 871 struct ivtv *itv = id->itv;
889 struct yuv_playback_info *yi = &itv->yuv_info; 872 struct yuv_playback_info *yi = &itv->yuv_info;
890 int streamtype; 873 int streamtype;
@@ -910,7 +893,7 @@ static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
910 893
911static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop) 894static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
912{ 895{
913 struct ivtv_open_id *id = fh; 896 struct ivtv_open_id *id = fh2id(fh);
914 struct ivtv *itv = id->itv; 897 struct ivtv *itv = id->itv;
915 struct yuv_playback_info *yi = &itv->yuv_info; 898 struct yuv_playback_info *yi = &itv->yuv_info;
916 int streamtype; 899 int streamtype;
@@ -952,7 +935,7 @@ static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdes
952 935
953static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt) 936static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
954{ 937{
955 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 938 struct ivtv *itv = fh2id(fh)->itv;
956 939
957 static struct v4l2_fmtdesc formats[] = { 940 static struct v4l2_fmtdesc formats[] = {
958 { 0, 0, 0, 941 { 0, 0, 0,
@@ -980,7 +963,7 @@ static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdes
980 963
981static int ivtv_g_input(struct file *file, void *fh, unsigned int *i) 964static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
982{ 965{
983 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 966 struct ivtv *itv = fh2id(fh)->itv;
984 967
985 *i = itv->active_input; 968 *i = itv->active_input;
986 969
@@ -989,7 +972,7 @@ static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
989 972
990int ivtv_s_input(struct file *file, void *fh, unsigned int inp) 973int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
991{ 974{
992 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 975 struct ivtv *itv = fh2id(fh)->itv;
993 976
994 if (inp < 0 || inp >= itv->nof_inputs) 977 if (inp < 0 || inp >= itv->nof_inputs)
995 return -EINVAL; 978 return -EINVAL;
@@ -1023,7 +1006,7 @@ int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
1023 1006
1024static int ivtv_g_output(struct file *file, void *fh, unsigned int *i) 1007static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1025{ 1008{
1026 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1009 struct ivtv *itv = fh2id(fh)->itv;
1027 1010
1028 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1011 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1029 return -EINVAL; 1012 return -EINVAL;
@@ -1035,7 +1018,7 @@ static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
1035 1018
1036static int ivtv_s_output(struct file *file, void *fh, unsigned int outp) 1019static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1037{ 1020{
1038 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1021 struct ivtv *itv = fh2id(fh)->itv;
1039 1022
1040 if (outp >= itv->card->nof_outputs) 1023 if (outp >= itv->card->nof_outputs)
1041 return -EINVAL; 1024 return -EINVAL;
@@ -1057,7 +1040,7 @@ static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
1057 1040
1058static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 1041static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1059{ 1042{
1060 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1043 struct ivtv *itv = fh2id(fh)->itv;
1061 1044
1062 if (vf->tuner != 0) 1045 if (vf->tuner != 0)
1063 return -EINVAL; 1046 return -EINVAL;
@@ -1068,7 +1051,7 @@ static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *
1068 1051
1069int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf) 1052int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1070{ 1053{
1071 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1054 struct ivtv *itv = fh2id(fh)->itv;
1072 1055
1073 if (vf->tuner != 0) 1056 if (vf->tuner != 0)
1074 return -EINVAL; 1057 return -EINVAL;
@@ -1082,7 +1065,7 @@ int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1082 1065
1083static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std) 1066static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1084{ 1067{
1085 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1068 struct ivtv *itv = fh2id(fh)->itv;
1086 1069
1087 *std = itv->std; 1070 *std = itv->std;
1088 return 0; 1071 return 0;
@@ -1091,7 +1074,7 @@ static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1091int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std) 1074int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1092{ 1075{
1093 DEFINE_WAIT(wait); 1076 DEFINE_WAIT(wait);
1094 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1077 struct ivtv *itv = fh2id(fh)->itv;
1095 struct yuv_playback_info *yi = &itv->yuv_info; 1078 struct yuv_playback_info *yi = &itv->yuv_info;
1096 int f; 1079 int f;
1097 1080
@@ -1170,7 +1153,7 @@ int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1170 1153
1171static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 1154static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1172{ 1155{
1173 struct ivtv_open_id *id = fh; 1156 struct ivtv_open_id *id = fh2id(fh);
1174 struct ivtv *itv = id->itv; 1157 struct ivtv *itv = id->itv;
1175 1158
1176 if (vt->index != 0) 1159 if (vt->index != 0)
@@ -1183,7 +1166,7 @@ static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1183 1166
1184static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt) 1167static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1185{ 1168{
1186 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1169 struct ivtv *itv = fh2id(fh)->itv;
1187 1170
1188 if (vt->index != 0) 1171 if (vt->index != 0)
1189 return -EINVAL; 1172 return -EINVAL;
@@ -1203,7 +1186,7 @@ static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1203 1186
1204static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap) 1187static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1205{ 1188{
1206 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1189 struct ivtv *itv = fh2id(fh)->itv;
1207 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 1190 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1208 int f, l; 1191 int f, l;
1209 1192
@@ -1233,7 +1216,7 @@ static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced
1233 1216
1234static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx) 1217static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1235{ 1218{
1236 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1219 struct ivtv *itv = fh2id(fh)->itv;
1237 struct v4l2_enc_idx_entry *e = idx->entry; 1220 struct v4l2_enc_idx_entry *e = idx->entry;
1238 int entries; 1221 int entries;
1239 int i; 1222 int i;
@@ -1256,7 +1239,7 @@ static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *id
1256 1239
1257static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) 1240static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1258{ 1241{
1259 struct ivtv_open_id *id = fh; 1242 struct ivtv_open_id *id = fh2id(fh);
1260 struct ivtv *itv = id->itv; 1243 struct ivtv *itv = id->itv;
1261 1244
1262 1245
@@ -1308,7 +1291,7 @@ static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd
1308 1291
1309static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc) 1292static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1310{ 1293{
1311 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1294 struct ivtv *itv = fh2id(fh)->itv;
1312 1295
1313 switch (enc->cmd) { 1296 switch (enc->cmd) {
1314 case V4L2_ENC_CMD_START: 1297 case V4L2_ENC_CMD_START:
@@ -1338,7 +1321,7 @@ static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder
1338 1321
1339static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 1322static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1340{ 1323{
1341 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1324 struct ivtv *itv = fh2id(fh)->itv;
1342 u32 data[CX2341X_MBOX_MAX_DATA]; 1325 u32 data[CX2341X_MBOX_MAX_DATA];
1343 struct yuv_playback_info *yi = &itv->yuv_info; 1326 struct yuv_playback_info *yi = &itv->yuv_info;
1344 1327
@@ -1425,7 +1408,7 @@ static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1425 1408
1426static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb) 1409static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1427{ 1410{
1428 struct ivtv_open_id *id = fh; 1411 struct ivtv_open_id *id = fh2id(fh);
1429 struct ivtv *itv = id->itv; 1412 struct ivtv *itv = id->itv;
1430 struct yuv_playback_info *yi = &itv->yuv_info; 1413 struct yuv_playback_info *yi = &itv->yuv_info;
1431 1414
@@ -1445,7 +1428,7 @@ static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1445 1428
1446static int ivtv_overlay(struct file *file, void *fh, unsigned int on) 1429static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1447{ 1430{
1448 struct ivtv_open_id *id = fh; 1431 struct ivtv_open_id *id = fh2id(fh);
1449 struct ivtv *itv = id->itv; 1432 struct ivtv *itv = id->itv;
1450 1433
1451 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1434 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
@@ -1470,7 +1453,7 @@ static int ivtv_subscribe_event(struct v4l2_fh *fh, struct v4l2_event_subscripti
1470 1453
1471static int ivtv_log_status(struct file *file, void *fh) 1454static int ivtv_log_status(struct file *file, void *fh)
1472{ 1455{
1473 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1456 struct ivtv *itv = fh2id(fh)->itv;
1474 u32 data[CX2341X_MBOX_MAX_DATA]; 1457 u32 data[CX2341X_MBOX_MAX_DATA];
1475 1458
1476 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT; 1459 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
@@ -1795,9 +1778,25 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1795 return 0; 1778 return 0;
1796} 1779}
1797 1780
1798static long ivtv_default(struct file *file, void *fh, int cmd, void *arg) 1781static long ivtv_default(struct file *file, void *fh, bool valid_prio,
1782 int cmd, void *arg)
1799{ 1783{
1800 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv; 1784 struct ivtv *itv = fh2id(fh)->itv;
1785
1786 if (!valid_prio) {
1787 switch (cmd) {
1788 case VIDEO_PLAY:
1789 case VIDEO_STOP:
1790 case VIDEO_FREEZE:
1791 case VIDEO_CONTINUE:
1792 case VIDEO_COMMAND:
1793 case VIDEO_SELECT_SOURCE:
1794 case AUDIO_SET_MUTE:
1795 case AUDIO_CHANNEL_SELECT:
1796 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1797 return -EBUSY;
1798 }
1799 }
1801 1800
1802 switch (cmd) { 1801 switch (cmd) {
1803 case VIDIOC_INT_RESET: { 1802 case VIDIOC_INT_RESET: {
@@ -1836,30 +1835,8 @@ static long ivtv_serialized_ioctl(struct ivtv *itv, struct file *filp,
1836 unsigned int cmd, unsigned long arg) 1835 unsigned int cmd, unsigned long arg)
1837{ 1836{
1838 struct video_device *vfd = video_devdata(filp); 1837 struct video_device *vfd = video_devdata(filp);
1839 struct ivtv_open_id *id = fh2id(filp->private_data);
1840 long ret; 1838 long ret;
1841 1839
1842 /* check priority */
1843 switch (cmd) {
1844 case VIDIOC_S_CTRL:
1845 case VIDIOC_S_STD:
1846 case VIDIOC_S_INPUT:
1847 case VIDIOC_S_OUTPUT:
1848 case VIDIOC_S_TUNER:
1849 case VIDIOC_S_FREQUENCY:
1850 case VIDIOC_S_FMT:
1851 case VIDIOC_S_CROP:
1852 case VIDIOC_S_AUDIO:
1853 case VIDIOC_S_AUDOUT:
1854 case VIDIOC_S_EXT_CTRLS:
1855 case VIDIOC_S_FBUF:
1856 case VIDIOC_S_PRIORITY:
1857 case VIDIOC_OVERLAY:
1858 ret = v4l2_prio_check(&itv->prio, id->prio);
1859 if (ret)
1860 return ret;
1861 }
1862
1863 if (ivtv_debug & IVTV_DBGFLG_IOCTL) 1840 if (ivtv_debug & IVTV_DBGFLG_IOCTL)
1864 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG; 1841 vfd->debug = V4L2_DEBUG_IOCTL | V4L2_DEBUG_IOCTL_ARG;
1865 ret = video_ioctl2(filp, cmd, arg); 1842 ret = video_ioctl2(filp, cmd, arg);
@@ -1884,8 +1861,6 @@ long ivtv_v4l2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1884 1861
1885static const struct v4l2_ioctl_ops ivtv_ioctl_ops = { 1862static const struct v4l2_ioctl_ops ivtv_ioctl_ops = {
1886 .vidioc_querycap = ivtv_querycap, 1863 .vidioc_querycap = ivtv_querycap,
1887 .vidioc_g_priority = ivtv_g_priority,
1888 .vidioc_s_priority = ivtv_s_priority,
1889 .vidioc_s_audio = ivtv_s_audio, 1864 .vidioc_s_audio = ivtv_s_audio,
1890 .vidioc_g_audio = ivtv_g_audio, 1865 .vidioc_g_audio = ivtv_g_audio,
1891 .vidioc_enumaudio = ivtv_enumaudio, 1866 .vidioc_enumaudio = ivtv_enumaudio,
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index 512607e0cda3..942683336555 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -214,6 +214,7 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
214 s->vdev->fops = ivtv_stream_info[type].fops; 214 s->vdev->fops = ivtv_stream_info[type].fops;
215 s->vdev->release = video_device_release; 215 s->vdev->release = video_device_release;
216 s->vdev->tvnorms = V4L2_STD_ALL; 216 s->vdev->tvnorms = V4L2_STD_ALL;
217 set_bit(V4L2_FL_USE_FH_PRIO, &s->vdev->flags);
217 ivtv_set_funcs(s->vdev); 218 ivtv_set_funcs(s->vdev);
218 return 0; 219 return 0;
219} 220}
diff --git a/drivers/media/video/ivtv/ivtv-udma.c b/drivers/media/video/ivtv/ivtv-udma.c
index 1daf1dd65bf7..69cc8166b20b 100644
--- a/drivers/media/video/ivtv/ivtv-udma.c
+++ b/drivers/media/video/ivtv/ivtv-udma.c
@@ -132,7 +132,12 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
132 if (user_dma.page_count != err) { 132 if (user_dma.page_count != err) {
133 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n", 133 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
134 err, user_dma.page_count); 134 err, user_dma.page_count);
135 return -EINVAL; 135 if (err >= 0) {
136 for (i = 0; i < err; i++)
137 put_page(dma->map[i]);
138 return -EINVAL;
139 }
140 return err;
136 } 141 }
137 142
138 dma->page_count = user_dma.page_count; 143 dma->page_count = user_dma.page_count;
diff --git a/drivers/media/video/ivtv/ivtv-vbi.c b/drivers/media/video/ivtv/ivtv-vbi.c
index 2dfa957b0fd5..b6eb51ce7735 100644
--- a/drivers/media/video/ivtv/ivtv-vbi.c
+++ b/drivers/media/video/ivtv/ivtv-vbi.c
@@ -174,7 +174,7 @@ ivtv_write_vbi_from_user(struct ivtv *itv,
174 ret = -EFAULT; 174 ret = -EFAULT;
175 break; 175 break;
176 } 176 }
177 ivtv_write_vbi_line(itv, sliced + i, &cc, &found_cc); 177 ivtv_write_vbi_line(itv, &d, &cc, &found_cc);
178 } 178 }
179 179
180 if (found_cc) 180 if (found_cc)
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index c0875378acc2..dcbab6ad4c26 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -77,23 +77,51 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
77 /* Get user pages for DMA Xfer */ 77 /* Get user pages for DMA Xfer */
78 down_read(&current->mm->mmap_sem); 78 down_read(&current->mm->mmap_sem);
79 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL); 79 y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
80 uv_pages = get_user_pages(current, current->mm, uv_dma.uaddr, uv_dma.page_count, 0, 1, &dma->map[y_pages], NULL); 80 uv_pages = 0; /* silence gcc. value is set and consumed only if: */
81 if (y_pages == y_dma.page_count) {
82 uv_pages = get_user_pages(current, current->mm,
83 uv_dma.uaddr, uv_dma.page_count, 0, 1,
84 &dma->map[y_pages], NULL);
85 }
81 up_read(&current->mm->mmap_sem); 86 up_read(&current->mm->mmap_sem);
82 87
83 dma->page_count = y_dma.page_count + uv_dma.page_count; 88 if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
84 89 int rc = -EFAULT;
85 if (y_pages + uv_pages != dma->page_count) { 90
86 IVTV_DEBUG_WARN 91 if (y_pages == y_dma.page_count) {
87 ("failed to map user pages, returned %d instead of %d\n", 92 IVTV_DEBUG_WARN
88 y_pages + uv_pages, dma->page_count); 93 ("failed to map uv user pages, returned %d "
89 94 "expecting %d\n", uv_pages, uv_dma.page_count);
90 for (i = 0; i < dma->page_count; i++) { 95
91 put_page(dma->map[i]); 96 if (uv_pages >= 0) {
97 for (i = 0; i < uv_pages; i++)
98 put_page(dma->map[y_pages + i]);
99 rc = -EFAULT;
100 } else {
101 rc = uv_pages;
102 }
103 } else {
104 IVTV_DEBUG_WARN
105 ("failed to map y user pages, returned %d "
106 "expecting %d\n", y_pages, y_dma.page_count);
92 } 107 }
93 dma->page_count = 0; 108 if (y_pages >= 0) {
94 return -EINVAL; 109 for (i = 0; i < y_pages; i++)
110 put_page(dma->map[i]);
111 /*
112 * Inherit the -EFAULT from rc's
113 * initialization, but allow it to be
114 * overriden by uv_pages above if it was an
115 * actual errno.
116 */
117 } else {
118 rc = y_pages;
119 }
120 return rc;
95 } 121 }
96 122
123 dma->page_count = y_pages + uv_pages;
124
97 /* Fill & map SG List */ 125 /* Fill & map SG List */
98 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) { 126 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
99 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n"); 127 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index e7e717800ee2..b03d74e09a3c 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -8,7 +8,7 @@
8 * operation (via the mem2mem framework). 8 * operation (via the mem2mem framework).
9 * 9 *
10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 10 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
11 * Pawel Osciak, <p.osciak@samsung.com> 11 * Pawel Osciak, <pawel@osciak.com>
12 * Marek Szyprowski, <m.szyprowski@samsung.com> 12 * Marek Szyprowski, <m.szyprowski@samsung.com>
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
@@ -28,12 +28,12 @@
28#include <media/v4l2-mem2mem.h> 28#include <media/v4l2-mem2mem.h>
29#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-ioctl.h> 30#include <media/v4l2-ioctl.h>
31#include <media/videobuf-vmalloc.h> 31#include <media/videobuf2-vmalloc.h>
32 32
33#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev" 33#define MEM2MEM_TEST_MODULE_NAME "mem2mem-testdev"
34 34
35MODULE_DESCRIPTION("Virtual device for mem2mem framework testing"); 35MODULE_DESCRIPTION("Virtual device for mem2mem framework testing");
36MODULE_AUTHOR("Pawel Osciak, <p.osciak@samsung.com>"); 36MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
37MODULE_LICENSE("GPL"); 37MODULE_LICENSE("GPL");
38 38
39 39
@@ -201,11 +201,6 @@ struct m2mtest_ctx {
201 struct v4l2_m2m_ctx *m2m_ctx; 201 struct v4l2_m2m_ctx *m2m_ctx;
202}; 202};
203 203
204struct m2mtest_buffer {
205 /* vb must be first! */
206 struct videobuf_buffer vb;
207};
208
209static struct v4l2_queryctrl *get_ctrl(int id) 204static struct v4l2_queryctrl *get_ctrl(int id)
210{ 205{
211 int i; 206 int i;
@@ -219,37 +214,41 @@ static struct v4l2_queryctrl *get_ctrl(int id)
219} 214}
220 215
221static int device_process(struct m2mtest_ctx *ctx, 216static int device_process(struct m2mtest_ctx *ctx,
222 struct m2mtest_buffer *in_buf, 217 struct vb2_buffer *in_vb,
223 struct m2mtest_buffer *out_buf) 218 struct vb2_buffer *out_vb)
224{ 219{
225 struct m2mtest_dev *dev = ctx->dev; 220 struct m2mtest_dev *dev = ctx->dev;
221 struct m2mtest_q_data *q_data;
226 u8 *p_in, *p_out; 222 u8 *p_in, *p_out;
227 int x, y, t, w; 223 int x, y, t, w;
228 int tile_w, bytes_left; 224 int tile_w, bytes_left;
229 struct videobuf_queue *src_q; 225 int width, height, bytesperline;
230 struct videobuf_queue *dst_q;
231 226
232 src_q = v4l2_m2m_get_src_vq(ctx->m2m_ctx); 227 q_data = get_q_data(V4L2_BUF_TYPE_VIDEO_OUTPUT);
233 dst_q = v4l2_m2m_get_dst_vq(ctx->m2m_ctx); 228
234 p_in = videobuf_queue_to_vaddr(src_q, &in_buf->vb); 229 width = q_data->width;
235 p_out = videobuf_queue_to_vaddr(dst_q, &out_buf->vb); 230 height = q_data->height;
231 bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
232
233 p_in = vb2_plane_vaddr(in_vb, 0);
234 p_out = vb2_plane_vaddr(out_vb, 0);
236 if (!p_in || !p_out) { 235 if (!p_in || !p_out) {
237 v4l2_err(&dev->v4l2_dev, 236 v4l2_err(&dev->v4l2_dev,
238 "Acquiring kernel pointers to buffers failed\n"); 237 "Acquiring kernel pointers to buffers failed\n");
239 return -EFAULT; 238 return -EFAULT;
240 } 239 }
241 240
242 if (in_buf->vb.size > out_buf->vb.size) { 241 if (vb2_plane_size(in_vb, 0) > vb2_plane_size(out_vb, 0)) {
243 v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n"); 242 v4l2_err(&dev->v4l2_dev, "Output buffer is too small\n");
244 return -EINVAL; 243 return -EINVAL;
245 } 244 }
246 245
247 tile_w = (in_buf->vb.width * (q_data[V4L2_M2M_DST].fmt->depth >> 3)) 246 tile_w = (width * (q_data[V4L2_M2M_DST].fmt->depth >> 3))
248 / MEM2MEM_NUM_TILES; 247 / MEM2MEM_NUM_TILES;
249 bytes_left = in_buf->vb.bytesperline - tile_w * MEM2MEM_NUM_TILES; 248 bytes_left = bytesperline - tile_w * MEM2MEM_NUM_TILES;
250 w = 0; 249 w = 0;
251 250
252 for (y = 0; y < in_buf->vb.height; ++y) { 251 for (y = 0; y < height; ++y) {
253 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) { 252 for (t = 0; t < MEM2MEM_NUM_TILES; ++t) {
254 if (w & 0x1) { 253 if (w & 0x1) {
255 for (x = 0; x < tile_w; ++x) 254 for (x = 0; x < tile_w; ++x)
@@ -301,6 +300,21 @@ static void job_abort(void *priv)
301 ctx->aborting = 1; 300 ctx->aborting = 1;
302} 301}
303 302
303static void m2mtest_lock(void *priv)
304{
305 struct m2mtest_ctx *ctx = priv;
306 struct m2mtest_dev *dev = ctx->dev;
307 mutex_lock(&dev->dev_mutex);
308}
309
310static void m2mtest_unlock(void *priv)
311{
312 struct m2mtest_ctx *ctx = priv;
313 struct m2mtest_dev *dev = ctx->dev;
314 mutex_unlock(&dev->dev_mutex);
315}
316
317
304/* device_run() - prepares and starts the device 318/* device_run() - prepares and starts the device
305 * 319 *
306 * This simulates all the immediate preparations required before starting 320 * This simulates all the immediate preparations required before starting
@@ -311,7 +325,7 @@ static void device_run(void *priv)
311{ 325{
312 struct m2mtest_ctx *ctx = priv; 326 struct m2mtest_ctx *ctx = priv;
313 struct m2mtest_dev *dev = ctx->dev; 327 struct m2mtest_dev *dev = ctx->dev;
314 struct m2mtest_buffer *src_buf, *dst_buf; 328 struct vb2_buffer *src_buf, *dst_buf;
315 329
316 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 330 src_buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
317 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 331 dst_buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
@@ -322,12 +336,11 @@ static void device_run(void *priv)
322 schedule_irq(dev, ctx->transtime); 336 schedule_irq(dev, ctx->transtime);
323} 337}
324 338
325
326static void device_isr(unsigned long priv) 339static void device_isr(unsigned long priv)
327{ 340{
328 struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv; 341 struct m2mtest_dev *m2mtest_dev = (struct m2mtest_dev *)priv;
329 struct m2mtest_ctx *curr_ctx; 342 struct m2mtest_ctx *curr_ctx;
330 struct m2mtest_buffer *src_buf, *dst_buf; 343 struct vb2_buffer *src_vb, *dst_vb;
331 unsigned long flags; 344 unsigned long flags;
332 345
333 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev); 346 curr_ctx = v4l2_m2m_get_curr_priv(m2mtest_dev->m2m_dev);
@@ -338,31 +351,26 @@ static void device_isr(unsigned long priv)
338 return; 351 return;
339 } 352 }
340 353
341 src_buf = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx); 354 src_vb = v4l2_m2m_src_buf_remove(curr_ctx->m2m_ctx);
342 dst_buf = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx); 355 dst_vb = v4l2_m2m_dst_buf_remove(curr_ctx->m2m_ctx);
356
343 curr_ctx->num_processed++; 357 curr_ctx->num_processed++;
344 358
359 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
360 v4l2_m2m_buf_done(src_vb, VB2_BUF_STATE_DONE);
361 v4l2_m2m_buf_done(dst_vb, VB2_BUF_STATE_DONE);
362 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
363
345 if (curr_ctx->num_processed == curr_ctx->translen 364 if (curr_ctx->num_processed == curr_ctx->translen
346 || curr_ctx->aborting) { 365 || curr_ctx->aborting) {
347 dprintk(curr_ctx->dev, "Finishing transaction\n"); 366 dprintk(curr_ctx->dev, "Finishing transaction\n");
348 curr_ctx->num_processed = 0; 367 curr_ctx->num_processed = 0;
349 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
350 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
351 wake_up(&src_buf->vb.done);
352 wake_up(&dst_buf->vb.done);
353 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
354 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx); 368 v4l2_m2m_job_finish(m2mtest_dev->m2m_dev, curr_ctx->m2m_ctx);
355 } else { 369 } else {
356 spin_lock_irqsave(&m2mtest_dev->irqlock, flags);
357 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE;
358 wake_up(&src_buf->vb.done);
359 wake_up(&dst_buf->vb.done);
360 spin_unlock_irqrestore(&m2mtest_dev->irqlock, flags);
361 device_run(curr_ctx); 370 device_run(curr_ctx);
362 } 371 }
363} 372}
364 373
365
366/* 374/*
367 * video ioctls 375 * video ioctls
368 */ 376 */
@@ -423,7 +431,7 @@ static int vidioc_enum_fmt_vid_out(struct file *file, void *priv,
423 431
424static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) 432static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
425{ 433{
426 struct videobuf_queue *vq; 434 struct vb2_queue *vq;
427 struct m2mtest_q_data *q_data; 435 struct m2mtest_q_data *q_data;
428 436
429 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 437 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
@@ -434,7 +442,7 @@ static int vidioc_g_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
434 442
435 f->fmt.pix.width = q_data->width; 443 f->fmt.pix.width = q_data->width;
436 f->fmt.pix.height = q_data->height; 444 f->fmt.pix.height = q_data->height;
437 f->fmt.pix.field = vq->field; 445 f->fmt.pix.field = V4L2_FIELD_NONE;
438 f->fmt.pix.pixelformat = q_data->fmt->fourcc; 446 f->fmt.pix.pixelformat = q_data->fmt->fourcc;
439 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3; 447 f->fmt.pix.bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
440 f->fmt.pix.sizeimage = q_data->sizeimage; 448 f->fmt.pix.sizeimage = q_data->sizeimage;
@@ -523,7 +531,7 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *priv,
523static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f) 531static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
524{ 532{
525 struct m2mtest_q_data *q_data; 533 struct m2mtest_q_data *q_data;
526 struct videobuf_queue *vq; 534 struct vb2_queue *vq;
527 535
528 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 536 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
529 if (!vq) 537 if (!vq)
@@ -533,7 +541,7 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
533 if (!q_data) 541 if (!q_data)
534 return -EINVAL; 542 return -EINVAL;
535 543
536 if (videobuf_queue_is_busy(vq)) { 544 if (vb2_is_busy(vq)) {
537 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__); 545 v4l2_err(&ctx->dev->v4l2_dev, "%s queue busy\n", __func__);
538 return -EBUSY; 546 return -EBUSY;
539 } 547 }
@@ -543,7 +551,6 @@ static int vidioc_s_fmt(struct m2mtest_ctx *ctx, struct v4l2_format *f)
543 q_data->height = f->fmt.pix.height; 551 q_data->height = f->fmt.pix.height;
544 q_data->sizeimage = q_data->width * q_data->height 552 q_data->sizeimage = q_data->width * q_data->height
545 * q_data->fmt->depth >> 3; 553 * q_data->fmt->depth >> 3;
546 vq->field = f->fmt.pix.field;
547 554
548 dprintk(ctx->dev, 555 dprintk(ctx->dev,
549 "Setting format for type %d, wxh: %dx%d, fmt: %d\n", 556 "Setting format for type %d, wxh: %dx%d, fmt: %d\n",
@@ -733,120 +740,94 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
733 * Queue operations 740 * Queue operations
734 */ 741 */
735 742
736static void m2mtest_buf_release(struct videobuf_queue *vq, 743static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
737 struct videobuf_buffer *vb) 744 unsigned int *nplanes, unsigned long sizes[],
738{ 745 void *alloc_ctxs[])
739 struct m2mtest_ctx *ctx = vq->priv_data;
740
741 dprintk(ctx->dev, "type: %d, index: %d, state: %d\n",
742 vq->type, vb->i, vb->state);
743
744 videobuf_vmalloc_free(vb);
745 vb->state = VIDEOBUF_NEEDS_INIT;
746}
747
748static int m2mtest_buf_setup(struct videobuf_queue *vq, unsigned int *count,
749 unsigned int *size)
750{ 746{
751 struct m2mtest_ctx *ctx = vq->priv_data; 747 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
752 struct m2mtest_q_data *q_data; 748 struct m2mtest_q_data *q_data;
749 unsigned int size, count = *nbuffers;
753 750
754 q_data = get_q_data(vq->type); 751 q_data = get_q_data(vq->type);
755 752
756 *size = q_data->width * q_data->height * q_data->fmt->depth >> 3; 753 size = q_data->width * q_data->height * q_data->fmt->depth >> 3;
757 dprintk(ctx->dev, "size:%d, w/h %d/%d, depth: %d\n",
758 *size, q_data->width, q_data->height, q_data->fmt->depth);
759 754
760 if (0 == *count) 755 while (size * count > MEM2MEM_VID_MEM_LIMIT)
761 *count = MEM2MEM_DEF_NUM_BUFS; 756 (count)--;
762 757
763 while (*size * *count > MEM2MEM_VID_MEM_LIMIT) 758 *nplanes = 1;
764 (*count)--; 759 *nbuffers = count;
760 sizes[0] = size;
765 761
766 v4l2_info(&ctx->dev->v4l2_dev, 762 /*
767 "%d buffers of size %d set up.\n", *count, *size); 763 * videobuf2-vmalloc allocator is context-less so no need to set
764 * alloc_ctxs array.
765 */
766
767 dprintk(ctx->dev, "get %d buffer(s) of size %d each.\n", count, size);
768 768
769 return 0; 769 return 0;
770} 770}
771 771
772static int m2mtest_buf_prepare(struct videobuf_queue *vq, 772static int m2mtest_buf_prepare(struct vb2_buffer *vb)
773 struct videobuf_buffer *vb,
774 enum v4l2_field field)
775{ 773{
776 struct m2mtest_ctx *ctx = vq->priv_data; 774 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
777 struct m2mtest_q_data *q_data; 775 struct m2mtest_q_data *q_data;
778 int ret;
779 776
780 dprintk(ctx->dev, "type: %d, index: %d, state: %d\n", 777 dprintk(ctx->dev, "type: %d\n", vb->vb2_queue->type);
781 vq->type, vb->i, vb->state);
782 778
783 q_data = get_q_data(vq->type); 779 q_data = get_q_data(vb->vb2_queue->type);
784 780
785 if (vb->baddr) { 781 if (vb2_plane_size(vb, 0) < q_data->sizeimage) {
786 /* User-provided buffer */ 782 dprintk(ctx->dev, "%s data will not fit into plane (%lu < %lu)\n",
787 if (vb->bsize < q_data->sizeimage) { 783 __func__, vb2_plane_size(vb, 0), (long)q_data->sizeimage);
788 /* Buffer too small to fit a frame */
789 v4l2_err(&ctx->dev->v4l2_dev,
790 "User-provided buffer too small\n");
791 return -EINVAL;
792 }
793 } else if (vb->state != VIDEOBUF_NEEDS_INIT
794 && vb->bsize < q_data->sizeimage) {
795 /* We provide the buffer, but it's already been initialized
796 * and is too small */
797 return -EINVAL; 784 return -EINVAL;
798 } 785 }
799 786
800 vb->width = q_data->width; 787 vb2_set_plane_payload(vb, 0, q_data->sizeimage);
801 vb->height = q_data->height;
802 vb->bytesperline = (q_data->width * q_data->fmt->depth) >> 3;
803 vb->size = q_data->sizeimage;
804 vb->field = field;
805
806 if (VIDEOBUF_NEEDS_INIT == vb->state) {
807 ret = videobuf_iolock(vq, vb, NULL);
808 if (ret) {
809 v4l2_err(&ctx->dev->v4l2_dev,
810 "Iolock failed\n");
811 goto fail;
812 }
813 }
814
815 vb->state = VIDEOBUF_PREPARED;
816 788
817 return 0; 789 return 0;
818fail:
819 m2mtest_buf_release(vq, vb);
820 return ret;
821} 790}
822 791
823static void m2mtest_buf_queue(struct videobuf_queue *vq, 792static void m2mtest_buf_queue(struct vb2_buffer *vb)
824 struct videobuf_buffer *vb)
825{ 793{
826 struct m2mtest_ctx *ctx = vq->priv_data; 794 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
827 795 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
828 v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb);
829} 796}
830 797
831static struct videobuf_queue_ops m2mtest_qops = { 798static struct vb2_ops m2mtest_qops = {
832 .buf_setup = m2mtest_buf_setup, 799 .queue_setup = m2mtest_queue_setup,
833 .buf_prepare = m2mtest_buf_prepare, 800 .buf_prepare = m2mtest_buf_prepare,
834 .buf_queue = m2mtest_buf_queue, 801 .buf_queue = m2mtest_buf_queue,
835 .buf_release = m2mtest_buf_release,
836}; 802};
837 803
838static void queue_init(void *priv, struct videobuf_queue *vq, 804static int queue_init(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq)
839 enum v4l2_buf_type type)
840{ 805{
841 struct m2mtest_ctx *ctx = priv; 806 struct m2mtest_ctx *ctx = priv;
842 struct m2mtest_dev *dev = ctx->dev; 807 int ret;
843 808
844 videobuf_queue_vmalloc_init(vq, &m2mtest_qops, dev->v4l2_dev.dev, 809 memset(src_vq, 0, sizeof(*src_vq));
845 &dev->irqlock, type, V4L2_FIELD_NONE, 810 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
846 sizeof(struct m2mtest_buffer), priv, 811 src_vq->io_modes = VB2_MMAP;
847 &dev->dev_mutex); 812 src_vq->drv_priv = ctx;
848} 813 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
814 src_vq->ops = &m2mtest_qops;
815 src_vq->mem_ops = &vb2_vmalloc_memops;
849 816
817 ret = vb2_queue_init(src_vq);
818 if (ret)
819 return ret;
820
821 memset(dst_vq, 0, sizeof(*dst_vq));
822 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
823 dst_vq->io_modes = VB2_MMAP;
824 dst_vq->drv_priv = ctx;
825 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
826 dst_vq->ops = &m2mtest_qops;
827 dst_vq->mem_ops = &vb2_vmalloc_memops;
828
829 return vb2_queue_init(dst_vq);
830}
850 831
851/* 832/*
852 * File operations 833 * File operations
@@ -866,7 +847,8 @@ static int m2mtest_open(struct file *file)
866 ctx->transtime = MEM2MEM_DEF_TRANSTIME; 847 ctx->transtime = MEM2MEM_DEF_TRANSTIME;
867 ctx->num_processed = 0; 848 ctx->num_processed = 0;
868 849
869 ctx->m2m_ctx = v4l2_m2m_ctx_init(ctx, dev->m2m_dev, queue_init); 850 ctx->m2m_ctx = v4l2_m2m_ctx_init(dev->m2m_dev, ctx, &queue_init);
851
870 if (IS_ERR(ctx->m2m_ctx)) { 852 if (IS_ERR(ctx->m2m_ctx)) {
871 int ret = PTR_ERR(ctx->m2m_ctx); 853 int ret = PTR_ERR(ctx->m2m_ctx);
872 854
@@ -932,6 +914,8 @@ static struct v4l2_m2m_ops m2m_ops = {
932 .device_run = device_run, 914 .device_run = device_run,
933 .job_ready = job_ready, 915 .job_ready = job_ready,
934 .job_abort = job_abort, 916 .job_abort = job_abort,
917 .lock = m2mtest_lock,
918 .unlock = m2mtest_unlock,
935}; 919};
936 920
937static int m2mtest_probe(struct platform_device *pdev) 921static int m2mtest_probe(struct platform_device *pdev)
@@ -990,6 +974,7 @@ static int m2mtest_probe(struct platform_device *pdev)
990 974
991 return 0; 975 return 0;
992 976
977 v4l2_m2m_release(dev->m2m_dev);
993err_m2m: 978err_m2m:
994 video_unregister_device(dev->vfd); 979 video_unregister_device(dev->vfd);
995rel_vdev: 980rel_vdev:
diff --git a/drivers/media/video/meye.c b/drivers/media/video/meye.c
index 48d2c2419c13..b09a3c80a15e 100644
--- a/drivers/media/video/meye.c
+++ b/drivers/media/video/meye.c
@@ -1547,7 +1547,8 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
1547 return 0; 1547 return 0;
1548} 1548}
1549 1549
1550static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) 1550static long vidioc_default(struct file *file, void *fh, bool valid_prio,
1551 int cmd, void *arg)
1551{ 1552{
1552 switch (cmd) { 1553 switch (cmd) {
1553 case MEYEIOC_G_PARAMS: 1554 case MEYEIOC_G_PARAMS:
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index f7fc88d240e6..e2bbd8c35c98 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -79,7 +79,7 @@ static const struct mt9m001_datafmt mt9m001_colour_fmts[] = {
79static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = { 79static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
80 /* Order important - see above */ 80 /* Order important - see above */
81 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, 81 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
82 {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, 82 {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
83}; 83};
84 84
85struct mt9m001 { 85struct mt9m001 {
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 6a784c87e5ff..e313d8390092 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -95,7 +95,7 @@ static const struct mt9v022_datafmt mt9v022_colour_fmts[] = {
95static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = { 95static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
96 /* Order important - see above */ 96 /* Order important - see above */
97 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG}, 97 {V4L2_MBUS_FMT_Y10_1X10, V4L2_COLORSPACE_JPEG},
98 {V4L2_MBUS_FMT_GREY8_1X8, V4L2_COLORSPACE_JPEG}, 98 {V4L2_MBUS_FMT_Y8_1X8, V4L2_COLORSPACE_JPEG},
99}; 99};
100 100
101struct mt9v022 { 101struct mt9v022 {
@@ -392,7 +392,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
392 * icd->try_fmt(), datawidth is from our supported format list 392 * icd->try_fmt(), datawidth is from our supported format list
393 */ 393 */
394 switch (mf->code) { 394 switch (mf->code) {
395 case V4L2_MBUS_FMT_GREY8_1X8: 395 case V4L2_MBUS_FMT_Y8_1X8:
396 case V4L2_MBUS_FMT_Y10_1X10: 396 case V4L2_MBUS_FMT_Y10_1X10:
397 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM) 397 if (mt9v022->model != V4L2_IDENT_MT9V022IX7ATM)
398 return -EINVAL; 398 return -EINVAL;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index b9cb4a436959..502e2a40964c 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -21,7 +21,7 @@
21 21
22#include <media/v4l2-common.h> 22#include <media/v4l2-common.h>
23#include <media/v4l2-dev.h> 23#include <media/v4l2-dev.h>
24#include <media/videobuf-dma-contig.h> 24#include <media/videobuf2-dma-contig.h>
25#include <media/soc_camera.h> 25#include <media/soc_camera.h>
26#include <media/soc_mediabus.h> 26#include <media/soc_mediabus.h>
27 27
@@ -62,10 +62,16 @@
62 62
63#define MAX_VIDEO_MEM 16 63#define MAX_VIDEO_MEM 16
64 64
65enum csi_buffer_state {
66 CSI_BUF_NEEDS_INIT,
67 CSI_BUF_PREPARED,
68};
69
65struct mx3_camera_buffer { 70struct mx3_camera_buffer {
66 /* common v4l buffer stuff -- must be first */ 71 /* common v4l buffer stuff -- must be first */
67 struct videobuf_buffer vb; 72 struct vb2_buffer vb;
68 enum v4l2_mbus_pixelcode code; 73 enum csi_buffer_state state;
74 struct list_head queue;
69 75
70 /* One descriptot per scatterlist (per frame) */ 76 /* One descriptot per scatterlist (per frame) */
71 struct dma_async_tx_descriptor *txd; 77 struct dma_async_tx_descriptor *txd;
@@ -108,6 +114,9 @@ struct mx3_camera_dev {
108 struct list_head capture; 114 struct list_head capture;
109 spinlock_t lock; /* Protects video buffer lists */ 115 spinlock_t lock; /* Protects video buffer lists */
110 struct mx3_camera_buffer *active; 116 struct mx3_camera_buffer *active;
117 struct vb2_alloc_ctx *alloc_ctx;
118 enum v4l2_field field;
119 int sequence;
111 120
112 /* IDMAC / dmaengine interface */ 121 /* IDMAC / dmaengine interface */
113 struct idmac_channel *idmac_channel[1]; /* We need one channel */ 122 struct idmac_channel *idmac_channel[1]; /* We need one channel */
@@ -130,6 +139,11 @@ static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg)
130 __raw_writel(value, mx3->base + reg); 139 __raw_writel(value, mx3->base + reg);
131} 140}
132 141
142static struct mx3_camera_buffer *to_mx3_vb(struct vb2_buffer *vb)
143{
144 return container_of(vb, struct mx3_camera_buffer, vb);
145}
146
133/* Called from the IPU IDMAC ISR */ 147/* Called from the IPU IDMAC ISR */
134static void mx3_cam_dma_done(void *arg) 148static void mx3_cam_dma_done(void *arg)
135{ 149{
@@ -137,20 +151,20 @@ static void mx3_cam_dma_done(void *arg)
137 struct dma_chan *chan = desc->txd.chan; 151 struct dma_chan *chan = desc->txd.chan;
138 struct idmac_channel *ichannel = to_idmac_chan(chan); 152 struct idmac_channel *ichannel = to_idmac_chan(chan);
139 struct mx3_camera_dev *mx3_cam = ichannel->client; 153 struct mx3_camera_dev *mx3_cam = ichannel->client;
140 struct videobuf_buffer *vb;
141 154
142 dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n", 155 dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n",
143 desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0); 156 desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0);
144 157
145 spin_lock(&mx3_cam->lock); 158 spin_lock(&mx3_cam->lock);
146 if (mx3_cam->active) { 159 if (mx3_cam->active) {
147 vb = &mx3_cam->active->vb; 160 struct vb2_buffer *vb = &mx3_cam->active->vb;
148 161 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
149 list_del_init(&vb->queue); 162
150 vb->state = VIDEOBUF_DONE; 163 list_del_init(&buf->queue);
151 do_gettimeofday(&vb->ts); 164 do_gettimeofday(&vb->v4l2_buf.timestamp);
152 vb->field_count++; 165 vb->v4l2_buf.field = mx3_cam->field;
153 wake_up(&vb->done); 166 vb->v4l2_buf.sequence = mx3_cam->sequence++;
167 vb2_buffer_done(vb, VB2_BUF_STATE_DONE);
154 } 168 }
155 169
156 if (list_empty(&mx3_cam->capture)) { 170 if (list_empty(&mx3_cam->capture)) {
@@ -165,50 +179,22 @@ static void mx3_cam_dma_done(void *arg)
165 } 179 }
166 180
167 mx3_cam->active = list_entry(mx3_cam->capture.next, 181 mx3_cam->active = list_entry(mx3_cam->capture.next,
168 struct mx3_camera_buffer, vb.queue); 182 struct mx3_camera_buffer, queue);
169 mx3_cam->active->vb.state = VIDEOBUF_ACTIVE;
170 spin_unlock(&mx3_cam->lock); 183 spin_unlock(&mx3_cam->lock);
171} 184}
172 185
173static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf)
174{
175 struct soc_camera_device *icd = vq->priv_data;
176 struct videobuf_buffer *vb = &buf->vb;
177 struct dma_async_tx_descriptor *txd = buf->txd;
178 struct idmac_channel *ichan;
179
180 BUG_ON(in_interrupt());
181
182 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
183 vb, vb->baddr, vb->bsize);
184
185 /*
186 * This waits until this buffer is out of danger, i.e., until it is no
187 * longer in STATE_QUEUED or STATE_ACTIVE
188 */
189 videobuf_waiton(vq, vb, 0, 0);
190 if (txd) {
191 ichan = to_idmac_chan(txd->chan);
192 async_tx_ack(txd);
193 }
194 videobuf_dma_contig_free(vq, vb);
195 buf->txd = NULL;
196
197 vb->state = VIDEOBUF_NEEDS_INIT;
198}
199
200/* 186/*
201 * Videobuf operations 187 * Videobuf operations
202 */ 188 */
203 189
204/* 190/*
205 * Calculate the __buffer__ (not data) size and number of buffers. 191 * Calculate the __buffer__ (not data) size and number of buffers.
206 * Called with .vb_lock held
207 */ 192 */
208static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, 193static int mx3_videobuf_setup(struct vb2_queue *vq,
209 unsigned int *size) 194 unsigned int *count, unsigned int *num_planes,
195 unsigned long sizes[], void *alloc_ctxs[])
210{ 196{
211 struct soc_camera_device *icd = vq->priv_data; 197 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
212 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 198 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
213 struct mx3_camera_dev *mx3_cam = ici->priv; 199 struct mx3_camera_dev *mx3_cam = ici->priv;
214 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 200 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
@@ -220,162 +206,133 @@ static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
220 if (!mx3_cam->idmac_channel[0]) 206 if (!mx3_cam->idmac_channel[0])
221 return -EINVAL; 207 return -EINVAL;
222 208
223 *size = bytes_per_line * icd->user_height; 209 *num_planes = 1;
210
211 mx3_cam->sequence = 0;
212 sizes[0] = bytes_per_line * icd->user_height;
213 alloc_ctxs[0] = mx3_cam->alloc_ctx;
224 214
225 if (!*count) 215 if (!*count)
226 *count = 32; 216 *count = 32;
227 217
228 if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) 218 if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024)
229 *count = MAX_VIDEO_MEM * 1024 * 1024 / *size; 219 *count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0];
230 220
231 return 0; 221 return 0;
232} 222}
233 223
234/* Called with .vb_lock held */ 224static int mx3_videobuf_prepare(struct vb2_buffer *vb)
235static int mx3_videobuf_prepare(struct videobuf_queue *vq,
236 struct videobuf_buffer *vb, enum v4l2_field field)
237{ 225{
238 struct soc_camera_device *icd = vq->priv_data; 226 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
239 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 227 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
240 struct mx3_camera_dev *mx3_cam = ici->priv; 228 struct mx3_camera_dev *mx3_cam = ici->priv;
241 struct mx3_camera_buffer *buf = 229 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
242 container_of(vb, struct mx3_camera_buffer, vb); 230 struct scatterlist *sg;
231 struct mx3_camera_buffer *buf;
243 size_t new_size; 232 size_t new_size;
244 int ret;
245 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 233 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
246 icd->current_fmt->host_fmt); 234 icd->current_fmt->host_fmt);
247 235
248 if (bytes_per_line < 0) 236 if (bytes_per_line < 0)
249 return bytes_per_line; 237 return bytes_per_line;
250 238
251 new_size = bytes_per_line * icd->user_height; 239 buf = to_mx3_vb(vb);
240 sg = &buf->sg;
252 241
253 /* 242 new_size = bytes_per_line * icd->user_height;
254 * I think, in buf_prepare you only have to protect global data,
255 * the actual buffer is yours
256 */
257
258 if (buf->code != icd->current_fmt->code ||
259 vb->width != icd->user_width ||
260 vb->height != icd->user_height ||
261 vb->field != field) {
262 buf->code = icd->current_fmt->code;
263 vb->width = icd->user_width;
264 vb->height = icd->user_height;
265 vb->field = field;
266 if (vb->state != VIDEOBUF_NEEDS_INIT)
267 free_buffer(vq, buf);
268 }
269 243
270 if (vb->baddr && vb->bsize < new_size) { 244 if (vb2_plane_size(vb, 0) < new_size) {
271 /* User provided buffer, but it is too small */ 245 dev_err(icd->dev.parent, "Buffer too small (%lu < %zu)\n",
272 ret = -ENOMEM; 246 vb2_plane_size(vb, 0), new_size);
273 goto out; 247 return -ENOBUFS;
274 } 248 }
275 249
276 if (vb->state == VIDEOBUF_NEEDS_INIT) { 250 if (buf->state == CSI_BUF_NEEDS_INIT) {
277 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 251 sg_dma_address(sg) = vb2_dma_contig_plane_paddr(vb, 0);
278 struct scatterlist *sg = &buf->sg; 252 sg_dma_len(sg) = new_size;
279
280 /*
281 * The total size of video-buffers that will be allocated / mapped.
282 * *size that we calculated in videobuf_setup gets assigned to
283 * vb->bsize, and now we use the same calculation to get vb->size.
284 */
285 vb->size = new_size;
286
287 /* This actually (allocates and) maps buffers */
288 ret = videobuf_iolock(vq, vb, NULL);
289 if (ret)
290 goto fail;
291
292 /*
293 * We will have to configure the IDMAC channel. It has two slots
294 * for DMA buffers, we shall enter the first two buffers there,
295 * and then submit new buffers in DMA-ready interrupts
296 */
297 sg_init_table(sg, 1);
298 sg_dma_address(sg) = videobuf_to_dma_contig(vb);
299 sg_dma_len(sg) = vb->size;
300 253
301 buf->txd = ichan->dma_chan.device->device_prep_slave_sg( 254 buf->txd = ichan->dma_chan.device->device_prep_slave_sg(
302 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE, 255 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
303 DMA_PREP_INTERRUPT); 256 DMA_PREP_INTERRUPT);
304 if (!buf->txd) { 257 if (!buf->txd)
305 ret = -EIO; 258 return -EIO;
306 goto fail;
307 }
308 259
309 buf->txd->callback_param = buf->txd; 260 buf->txd->callback_param = buf->txd;
310 buf->txd->callback = mx3_cam_dma_done; 261 buf->txd->callback = mx3_cam_dma_done;
311 262
312 vb->state = VIDEOBUF_PREPARED; 263 buf->state = CSI_BUF_PREPARED;
313 } 264 }
314 265
315 return 0; 266 vb2_set_plane_payload(vb, 0, new_size);
316 267
317fail: 268 return 0;
318 free_buffer(vq, buf);
319out:
320 return ret;
321} 269}
322 270
323static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc) 271static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc)
324{ 272{
325 /* Add more formats as need arises and test possibilities appear... */ 273 /* Add more formats as need arises and test possibilities appear... */
326 switch (fourcc) { 274 switch (fourcc) {
327 case V4L2_PIX_FMT_RGB565:
328 return IPU_PIX_FMT_RGB565;
329 case V4L2_PIX_FMT_RGB24: 275 case V4L2_PIX_FMT_RGB24:
330 return IPU_PIX_FMT_RGB24; 276 return IPU_PIX_FMT_RGB24;
331 case V4L2_PIX_FMT_RGB332: 277 case V4L2_PIX_FMT_UYVY:
332 return IPU_PIX_FMT_RGB332; 278 case V4L2_PIX_FMT_RGB565:
333 case V4L2_PIX_FMT_YUV422P:
334 return IPU_PIX_FMT_YVU422P;
335 default: 279 default:
336 return IPU_PIX_FMT_GENERIC; 280 return IPU_PIX_FMT_GENERIC;
337 } 281 }
338} 282}
339 283
340/* 284static void mx3_videobuf_queue(struct vb2_buffer *vb)
341 * Called with .vb_lock mutex held and
342 * under spinlock_irqsave(&mx3_cam->lock, ...)
343 */
344static void mx3_videobuf_queue(struct videobuf_queue *vq,
345 struct videobuf_buffer *vb)
346{ 285{
347 struct soc_camera_device *icd = vq->priv_data; 286 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
348 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 287 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
349 struct mx3_camera_dev *mx3_cam = ici->priv; 288 struct mx3_camera_dev *mx3_cam = ici->priv;
350 struct mx3_camera_buffer *buf = 289 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
351 container_of(vb, struct mx3_camera_buffer, vb);
352 struct dma_async_tx_descriptor *txd = buf->txd; 290 struct dma_async_tx_descriptor *txd = buf->txd;
353 struct idmac_channel *ichan = to_idmac_chan(txd->chan); 291 struct idmac_channel *ichan = to_idmac_chan(txd->chan);
354 struct idmac_video_param *video = &ichan->params.video; 292 struct idmac_video_param *video = &ichan->params.video;
355 dma_cookie_t cookie; 293 dma_cookie_t cookie;
356 u32 fourcc = icd->current_fmt->host_fmt->fourcc; 294 u32 fourcc = icd->current_fmt->host_fmt->fourcc;
357 295 unsigned long flags;
358 BUG_ON(!irqs_disabled());
359 296
360 /* This is the configuration of one sg-element */ 297 /* This is the configuration of one sg-element */
361 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); 298 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc);
362 video->out_width = icd->user_width; 299
363 video->out_height = icd->user_height; 300 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
364 video->out_stride = icd->user_width; 301 /*
302 * If the IPU DMA channel is configured to transport
303 * generic 8-bit data, we have to set up correctly the
304 * geometry parameters upon the current pixel format.
305 * So, since the DMA horizontal parameters are expressed
306 * in bytes not pixels, convert these in the right unit.
307 */
308 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
309 icd->current_fmt->host_fmt);
310 BUG_ON(bytes_per_line <= 0);
311
312 video->out_width = bytes_per_line;
313 video->out_height = icd->user_height;
314 video->out_stride = bytes_per_line;
315 } else {
316 /*
317 * For IPU known formats the pixel unit will be managed
318 * successfully by the IPU code
319 */
320 video->out_width = icd->user_width;
321 video->out_height = icd->user_height;
322 video->out_stride = icd->user_width;
323 }
365 324
366#ifdef DEBUG 325#ifdef DEBUG
367 /* helps to see what DMA actually has written */ 326 /* helps to see what DMA actually has written */
368 memset((void *)vb->baddr, 0xaa, vb->bsize); 327 if (vb2_plane_vaddr(vb, 0))
328 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
369#endif 329#endif
370 330
371 list_add_tail(&vb->queue, &mx3_cam->capture); 331 spin_lock_irqsave(&mx3_cam->lock, flags);
332 list_add_tail(&buf->queue, &mx3_cam->capture);
372 333
373 if (!mx3_cam->active) { 334 if (!mx3_cam->active)
374 mx3_cam->active = buf; 335 mx3_cam->active = buf;
375 vb->state = VIDEOBUF_ACTIVE;
376 } else {
377 vb->state = VIDEOBUF_QUEUED;
378 }
379 336
380 spin_unlock_irq(&mx3_cam->lock); 337 spin_unlock_irq(&mx3_cam->lock);
381 338
@@ -383,67 +340,87 @@ static void mx3_videobuf_queue(struct videobuf_queue *vq,
383 dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n", 340 dev_dbg(icd->dev.parent, "Submitted cookie %d DMA 0x%08x\n",
384 cookie, sg_dma_address(&buf->sg)); 341 cookie, sg_dma_address(&buf->sg));
385 342
386 spin_lock_irq(&mx3_cam->lock);
387
388 if (cookie >= 0) 343 if (cookie >= 0)
389 return; 344 return;
390 345
391 /* Submit error */ 346 spin_lock_irq(&mx3_cam->lock);
392 vb->state = VIDEOBUF_PREPARED;
393 347
394 list_del_init(&vb->queue); 348 /* Submit error */
349 list_del_init(&buf->queue);
395 350
396 if (mx3_cam->active == buf) 351 if (mx3_cam->active == buf)
397 mx3_cam->active = NULL; 352 mx3_cam->active = NULL;
353
354 spin_unlock_irqrestore(&mx3_cam->lock, flags);
355 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
398} 356}
399 357
400/* Called with .vb_lock held */ 358static void mx3_videobuf_release(struct vb2_buffer *vb)
401static void mx3_videobuf_release(struct videobuf_queue *vq,
402 struct videobuf_buffer *vb)
403{ 359{
404 struct soc_camera_device *icd = vq->priv_data; 360 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
405 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 361 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
406 struct mx3_camera_dev *mx3_cam = ici->priv; 362 struct mx3_camera_dev *mx3_cam = ici->priv;
407 struct mx3_camera_buffer *buf = 363 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
408 container_of(vb, struct mx3_camera_buffer, vb); 364 struct dma_async_tx_descriptor *txd = buf->txd;
409 unsigned long flags; 365 unsigned long flags;
410 366
411 dev_dbg(icd->dev.parent, 367 dev_dbg(icd->dev.parent,
412 "Release%s DMA 0x%08x (state %d), queue %sempty\n", 368 "Release%s DMA 0x%08x, queue %sempty\n",
413 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg), 369 mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg),
414 vb->state, list_empty(&vb->queue) ? "" : "not "); 370 list_empty(&buf->queue) ? "" : "not ");
371
415 spin_lock_irqsave(&mx3_cam->lock, flags); 372 spin_lock_irqsave(&mx3_cam->lock, flags);
416 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) &&
417 !list_empty(&vb->queue)) {
418 vb->state = VIDEOBUF_ERROR;
419 373
420 list_del_init(&vb->queue); 374 if (mx3_cam->active == buf)
421 if (mx3_cam->active == buf) 375 mx3_cam->active = NULL;
422 mx3_cam->active = NULL; 376
377 /* Doesn't hurt also if the list is empty */
378 list_del_init(&buf->queue);
379 buf->state = CSI_BUF_NEEDS_INIT;
380
381 if (txd) {
382 buf->txd = NULL;
383 if (mx3_cam->idmac_channel[0])
384 async_tx_ack(txd);
423 } 385 }
386
424 spin_unlock_irqrestore(&mx3_cam->lock, flags); 387 spin_unlock_irqrestore(&mx3_cam->lock, flags);
425 free_buffer(vq, buf);
426} 388}
427 389
428static struct videobuf_queue_ops mx3_videobuf_ops = { 390static int mx3_videobuf_init(struct vb2_buffer *vb)
429 .buf_setup = mx3_videobuf_setup, 391{
430 .buf_prepare = mx3_videobuf_prepare, 392 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
431 .buf_queue = mx3_videobuf_queue, 393 /* This is for locking debugging only */
432 .buf_release = mx3_videobuf_release, 394 INIT_LIST_HEAD(&buf->queue);
395 sg_init_table(&buf->sg, 1);
396
397 buf->state = CSI_BUF_NEEDS_INIT;
398 buf->txd = NULL;
399
400 return 0;
401}
402
403static struct vb2_ops mx3_videobuf_ops = {
404 .queue_setup = mx3_videobuf_setup,
405 .buf_prepare = mx3_videobuf_prepare,
406 .buf_queue = mx3_videobuf_queue,
407 .buf_cleanup = mx3_videobuf_release,
408 .buf_init = mx3_videobuf_init,
409 .wait_prepare = soc_camera_unlock,
410 .wait_finish = soc_camera_lock,
433}; 411};
434 412
435static void mx3_camera_init_videobuf(struct videobuf_queue *q, 413static int mx3_camera_init_videobuf(struct vb2_queue *q,
436 struct soc_camera_device *icd) 414 struct soc_camera_device *icd)
437{ 415{
438 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 416 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
439 struct mx3_camera_dev *mx3_cam = ici->priv; 417 q->io_modes = VB2_MMAP | VB2_USERPTR;
440 418 q->drv_priv = icd;
441 videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, icd->dev.parent, 419 q->ops = &mx3_videobuf_ops;
442 &mx3_cam->lock, 420 q->mem_ops = &vb2_dma_contig_memops;
443 V4L2_BUF_TYPE_VIDEO_CAPTURE, 421 q->buf_struct_size = sizeof(struct mx3_camera_buffer);
444 V4L2_FIELD_NONE, 422
445 sizeof(struct mx3_camera_buffer), icd, 423 return vb2_queue_init(q);
446 &icd->video_lock);
447} 424}
448 425
449/* First part of ipu_csi_init_interface() */ 426/* First part of ipu_csi_init_interface() */
@@ -538,18 +515,6 @@ static void mx3_camera_remove_device(struct soc_camera_device *icd)
538 icd->devnum); 515 icd->devnum);
539} 516}
540 517
541static bool channel_change_requested(struct soc_camera_device *icd,
542 struct v4l2_rect *rect)
543{
544 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
545 struct mx3_camera_dev *mx3_cam = ici->priv;
546 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
547
548 /* Do buffers have to be re-allocated or channel re-configured? */
549 return ichan && rect->width * rect->height >
550 icd->user_width * icd->user_height;
551}
552
553static int test_platform_param(struct mx3_camera_dev *mx3_cam, 518static int test_platform_param(struct mx3_camera_dev *mx3_cam,
554 unsigned char buswidth, unsigned long *flags) 519 unsigned char buswidth, unsigned long *flags)
555{ 520{
@@ -734,18 +699,36 @@ static int mx3_camera_get_formats(struct soc_camera_device *icd, unsigned int id
734 if (xlate) { 699 if (xlate) {
735 xlate->host_fmt = fmt; 700 xlate->host_fmt = fmt;
736 xlate->code = code; 701 xlate->code = code;
702 dev_dbg(dev, "Providing format %c%c%c%c in pass-through mode\n",
703 (fmt->fourcc >> (0*8)) & 0xFF,
704 (fmt->fourcc >> (1*8)) & 0xFF,
705 (fmt->fourcc >> (2*8)) & 0xFF,
706 (fmt->fourcc >> (3*8)) & 0xFF);
737 xlate++; 707 xlate++;
738 dev_dbg(dev, "Providing format %x in pass-through mode\n",
739 xlate->host_fmt->fourcc);
740 } 708 }
741 709
742 return formats; 710 return formats;
743} 711}
744 712
745static void configure_geometry(struct mx3_camera_dev *mx3_cam, 713static void configure_geometry(struct mx3_camera_dev *mx3_cam,
746 unsigned int width, unsigned int height) 714 unsigned int width, unsigned int height,
715 enum v4l2_mbus_pixelcode code)
747{ 716{
748 u32 ctrl, width_field, height_field; 717 u32 ctrl, width_field, height_field;
718 const struct soc_mbus_pixelfmt *fmt;
719
720 fmt = soc_mbus_get_fmtdesc(code);
721 BUG_ON(!fmt);
722
723 if (fourcc_to_ipu_pix(fmt->fourcc) == IPU_PIX_FMT_GENERIC) {
724 /*
725 * As the CSI will be configured to output BAYER, here
726 * the width parameter count the number of samples to
727 * capture to complete the whole image width.
728 */
729 width *= soc_mbus_samples_per_pixel(fmt);
730 BUG_ON(width < 0);
731 }
749 732
750 /* Setup frame size - this cannot be changed on-the-fly... */ 733 /* Setup frame size - this cannot be changed on-the-fly... */
751 width_field = width - 1; 734 width_field = width - 1;
@@ -772,18 +755,6 @@ static int acquire_dma_channel(struct mx3_camera_dev *mx3_cam)
772 struct dma_chan_request rq = {.mx3_cam = mx3_cam, 755 struct dma_chan_request rq = {.mx3_cam = mx3_cam,
773 .id = IDMAC_IC_7}; 756 .id = IDMAC_IC_7};
774 757
775 if (*ichan) {
776 struct videobuf_buffer *vb, *_vb;
777 dma_release_channel(&(*ichan)->dma_chan);
778 *ichan = NULL;
779 mx3_cam->active = NULL;
780 list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) {
781 list_del_init(&vb->queue);
782 vb->state = VIDEOBUF_ERROR;
783 wake_up(&vb->done);
784 }
785 }
786
787 dma_cap_zero(mask); 758 dma_cap_zero(mask);
788 dma_cap_set(DMA_SLAVE, mask); 759 dma_cap_set(DMA_SLAVE, mask);
789 dma_cap_set(DMA_PRIVATE, mask); 760 dma_cap_set(DMA_PRIVATE, mask);
@@ -843,19 +814,8 @@ static int mx3_camera_set_crop(struct soc_camera_device *icd,
843 return ret; 814 return ret;
844 } 815 }
845 816
846 if (mf.width != icd->user_width || mf.height != icd->user_height) { 817 if (mf.width != icd->user_width || mf.height != icd->user_height)
847 /* 818 configure_geometry(mx3_cam, mf.width, mf.height, mf.code);
848 * We now know pixel formats and can decide upon DMA-channel(s)
849 * So far only direct camera-to-memory is supported
850 */
851 if (channel_change_requested(icd, rect)) {
852 ret = acquire_dma_channel(mx3_cam);
853 if (ret < 0)
854 return ret;
855 }
856
857 configure_geometry(mx3_cam, mf.width, mf.height);
858 }
859 819
860 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n", 820 dev_dbg(icd->dev.parent, "Sensor cropped %dx%d\n",
861 mf.width, mf.height); 821 mf.width, mf.height);
@@ -887,17 +847,13 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
887 stride_align(&pix->width); 847 stride_align(&pix->width);
888 dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height); 848 dev_dbg(icd->dev.parent, "Set format %dx%d\n", pix->width, pix->height);
889 849
890 ret = acquire_dma_channel(mx3_cam);
891 if (ret < 0)
892 return ret;
893
894 /* 850 /*
895 * Might have to perform a complete interface initialisation like in 851 * Might have to perform a complete interface initialisation like in
896 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider 852 * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider
897 * mxc_v4l2_s_fmt() 853 * mxc_v4l2_s_fmt()
898 */ 854 */
899 855
900 configure_geometry(mx3_cam, pix->width, pix->height); 856 configure_geometry(mx3_cam, pix->width, pix->height, xlate->code);
901 857
902 mf.width = pix->width; 858 mf.width = pix->width;
903 mf.height = pix->height; 859 mf.height = pix->height;
@@ -912,12 +868,25 @@ static int mx3_camera_set_fmt(struct soc_camera_device *icd,
912 if (mf.code != xlate->code) 868 if (mf.code != xlate->code)
913 return -EINVAL; 869 return -EINVAL;
914 870
871 if (!mx3_cam->idmac_channel[0]) {
872 ret = acquire_dma_channel(mx3_cam);
873 if (ret < 0)
874 return ret;
875 }
876
915 pix->width = mf.width; 877 pix->width = mf.width;
916 pix->height = mf.height; 878 pix->height = mf.height;
917 pix->field = mf.field; 879 pix->field = mf.field;
880 mx3_cam->field = mf.field;
918 pix->colorspace = mf.colorspace; 881 pix->colorspace = mf.colorspace;
919 icd->current_fmt = xlate; 882 icd->current_fmt = xlate;
920 883
884 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
885 xlate->host_fmt);
886 if (pix->bytesperline < 0)
887 return pix->bytesperline;
888 pix->sizeimage = pix->height * pix->bytesperline;
889
921 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height); 890 dev_dbg(icd->dev.parent, "Sensor set %dx%d\n", pix->width, pix->height);
922 891
923 return ret; 892 return ret;
@@ -991,7 +960,7 @@ static unsigned int mx3_camera_poll(struct file *file, poll_table *pt)
991{ 960{
992 struct soc_camera_device *icd = file->private_data; 961 struct soc_camera_device *icd = file->private_data;
993 962
994 return videobuf_poll_stream(file, &icd->vb_vidq, pt); 963 return vb2_poll(&icd->vb2_vidq, file, pt);
995} 964}
996 965
997static int mx3_camera_querycap(struct soc_camera_host *ici, 966static int mx3_camera_querycap(struct soc_camera_host *ici,
@@ -1165,7 +1134,7 @@ static struct soc_camera_host_ops mx3_soc_camera_host_ops = {
1165 .set_fmt = mx3_camera_set_fmt, 1134 .set_fmt = mx3_camera_set_fmt,
1166 .try_fmt = mx3_camera_try_fmt, 1135 .try_fmt = mx3_camera_try_fmt,
1167 .get_formats = mx3_camera_get_formats, 1136 .get_formats = mx3_camera_get_formats,
1168 .init_videobuf = mx3_camera_init_videobuf, 1137 .init_videobuf2 = mx3_camera_init_videobuf,
1169 .reqbufs = mx3_camera_reqbufs, 1138 .reqbufs = mx3_camera_reqbufs,
1170 .poll = mx3_camera_poll, 1139 .poll = mx3_camera_poll,
1171 .querycap = mx3_camera_querycap, 1140 .querycap = mx3_camera_querycap,
@@ -1241,6 +1210,12 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1241 soc_host->v4l2_dev.dev = &pdev->dev; 1210 soc_host->v4l2_dev.dev = &pdev->dev;
1242 soc_host->nr = pdev->id; 1211 soc_host->nr = pdev->id;
1243 1212
1213 mx3_cam->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1214 if (IS_ERR(mx3_cam->alloc_ctx)) {
1215 err = PTR_ERR(mx3_cam->alloc_ctx);
1216 goto eallocctx;
1217 }
1218
1244 err = soc_camera_host_register(soc_host); 1219 err = soc_camera_host_register(soc_host);
1245 if (err) 1220 if (err)
1246 goto ecamhostreg; 1221 goto ecamhostreg;
@@ -1251,6 +1226,8 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1251 return 0; 1226 return 0;
1252 1227
1253ecamhostreg: 1228ecamhostreg:
1229 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1230eallocctx:
1254 iounmap(base); 1231 iounmap(base);
1255eioremap: 1232eioremap:
1256 clk_put(mx3_cam->clk); 1233 clk_put(mx3_cam->clk);
@@ -1280,6 +1257,8 @@ static int __devexit mx3_camera_remove(struct platform_device *pdev)
1280 if (WARN_ON(mx3_cam->idmac_channel[0])) 1257 if (WARN_ON(mx3_cam->idmac_channel[0]))
1281 dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan); 1258 dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan);
1282 1259
1260 vb2_dma_contig_cleanup_ctx(mx3_cam->alloc_ctx);
1261
1283 vfree(mx3_cam); 1262 vfree(mx3_cam);
1284 1263
1285 dmaengine_put(); 1264 dmaengine_put();
diff --git a/drivers/media/video/mxb.c b/drivers/media/video/mxb.c
index e8846a09b026..0b3850023505 100644
--- a/drivers/media/video/mxb.c
+++ b/drivers/media/video/mxb.c
@@ -643,7 +643,8 @@ static int vidioc_s_register(struct file *file, void *fh, struct v4l2_dbg_regist
643} 643}
644#endif 644#endif
645 645
646static long vidioc_default(struct file *file, void *fh, int cmd, void *arg) 646static long vidioc_default(struct file *file, void *fh, bool valid_prio,
647 int cmd, void *arg)
647{ 648{
648 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev; 649 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
649 struct mxb *mxb = (struct mxb *)dev->ext_priv; 650 struct mxb *mxb = (struct mxb *)dev->ext_priv;
diff --git a/drivers/media/video/noon010pc30.c b/drivers/media/video/noon010pc30.c
new file mode 100644
index 000000000000..35f722a88f76
--- /dev/null
+++ b/drivers/media/video/noon010pc30.c
@@ -0,0 +1,792 @@
1/*
2 * Driver for SiliconFile NOON010PC30 CIF (1/11") Image Sensor with ISP
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 * Contact: Sylwester Nawrocki, <s.nawrocki@samsung.com>
6 *
7 * Initial register configuration based on a driver authored by
8 * HeungJun Kim <riverful.kim@samsung.com>.
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 * (at your option) any later vergsion.
14 */
15
16#include <linux/delay.h>
17#include <linux/gpio.h>
18#include <linux/i2c.h>
19#include <linux/slab.h>
20#include <linux/regulator/consumer.h>
21#include <media/noon010pc30.h>
22#include <media/v4l2-chip-ident.h>
23#include <linux/videodev2.h>
24#include <media/v4l2-ctrls.h>
25#include <media/v4l2-device.h>
26#include <media/v4l2-mediabus.h>
27#include <media/v4l2-subdev.h>
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "Enable module debug trace. Set to 1 to enable.");
32
33#define MODULE_NAME "NOON010PC30"
34
35/*
36 * Register offsets within a page
37 * b15..b8 - page id, b7..b0 - register address
38 */
39#define POWER_CTRL_REG 0x0001
40#define PAGEMODE_REG 0x03
41#define DEVICE_ID_REG 0x0004
42#define NOON010PC30_ID 0x86
43#define VDO_CTL_REG(n) (0x0010 + (n))
44#define SYNC_CTL_REG 0x0012
45/* Window size and position */
46#define WIN_ROWH_REG 0x0013
47#define WIN_ROWL_REG 0x0014
48#define WIN_COLH_REG 0x0015
49#define WIN_COLL_REG 0x0016
50#define WIN_HEIGHTH_REG 0x0017
51#define WIN_HEIGHTL_REG 0x0018
52#define WIN_WIDTHH_REG 0x0019
53#define WIN_WIDTHL_REG 0x001A
54#define HBLANKH_REG 0x001B
55#define HBLANKL_REG 0x001C
56#define VSYNCH_REG 0x001D
57#define VSYNCL_REG 0x001E
58/* VSYNC control */
59#define VS_CTL_REG(n) (0x00A1 + (n))
60/* page 1 */
61#define ISP_CTL_REG(n) (0x0110 + (n))
62#define YOFS_REG 0x0119
63#define DARK_YOFS_REG 0x011A
64#define SAT_CTL_REG 0x0120
65#define BSAT_REG 0x0121
66#define RSAT_REG 0x0122
67/* Color correction */
68#define CMC_CTL_REG 0x0130
69#define CMC_OFSGH_REG 0x0133
70#define CMC_OFSGL_REG 0x0135
71#define CMC_SIGN_REG 0x0136
72#define CMC_GOFS_REG 0x0137
73#define CMC_COEF_REG(n) (0x0138 + (n))
74#define CMC_OFS_REG(n) (0x0141 + (n))
75/* Gamma correction */
76#define GMA_CTL_REG 0x0160
77#define GMA_COEF_REG(n) (0x0161 + (n))
78/* Lens Shading */
79#define LENS_CTRL_REG 0x01D0
80#define LENS_XCEN_REG 0x01D1
81#define LENS_YCEN_REG 0x01D2
82#define LENS_RC_REG 0x01D3
83#define LENS_GC_REG 0x01D4
84#define LENS_BC_REG 0x01D5
85#define L_AGON_REG 0x01D6
86#define L_AGOFF_REG 0x01D7
87/* Page 3 - Auto Exposure */
88#define AE_CTL_REG(n) (0x0310 + (n))
89#define AE_CTL9_REG 0x032C
90#define AE_CTL10_REG 0x032D
91#define AE_YLVL_REG 0x031C
92#define AE_YTH_REG(n) (0x031D + (n))
93#define AE_WGT_REG 0x0326
94#define EXP_TIMEH_REG 0x0333
95#define EXP_TIMEM_REG 0x0334
96#define EXP_TIMEL_REG 0x0335
97#define EXP_MMINH_REG 0x0336
98#define EXP_MMINL_REG 0x0337
99#define EXP_MMAXH_REG 0x0338
100#define EXP_MMAXM_REG 0x0339
101#define EXP_MMAXL_REG 0x033A
102/* Page 4 - Auto White Balance */
103#define AWB_CTL_REG(n) (0x0410 + (n))
104#define AWB_ENABE 0x80
105#define AWB_WGHT_REG 0x0419
106#define BGAIN_PAR_REG(n) (0x044F + (n))
107/* Manual white balance, when AWB_CTL2[0]=1 */
108#define MWB_RGAIN_REG 0x0466
109#define MWB_BGAIN_REG 0x0467
110
111/* The token to mark an array end */
112#define REG_TERM 0xFFFF
113
114struct noon010_format {
115 enum v4l2_mbus_pixelcode code;
116 enum v4l2_colorspace colorspace;
117 u16 ispctl1_reg;
118};
119
120struct noon010_frmsize {
121 u16 width;
122 u16 height;
123 int vid_ctl1;
124};
125
126static const char * const noon010_supply_name[] = {
127 "vdd_core", "vddio", "vdda"
128};
129
130#define NOON010_NUM_SUPPLIES ARRAY_SIZE(noon010_supply_name)
131
132struct noon010_info {
133 struct v4l2_subdev sd;
134 struct v4l2_ctrl_handler hdl;
135 const struct noon010pc30_platform_data *pdata;
136 const struct noon010_format *curr_fmt;
137 const struct noon010_frmsize *curr_win;
138 unsigned int hflip:1;
139 unsigned int vflip:1;
140 unsigned int power:1;
141 u8 i2c_reg_page;
142 struct regulator_bulk_data supply[NOON010_NUM_SUPPLIES];
143 u32 gpio_nreset;
144 u32 gpio_nstby;
145};
146
147struct i2c_regval {
148 u16 addr;
149 u16 val;
150};
151
152/* Supported resolutions. */
153static const struct noon010_frmsize noon010_sizes[] = {
154 {
155 .width = 352,
156 .height = 288,
157 .vid_ctl1 = 0,
158 }, {
159 .width = 176,
160 .height = 144,
161 .vid_ctl1 = 0x10,
162 }, {
163 .width = 88,
164 .height = 72,
165 .vid_ctl1 = 0x20,
166 },
167};
168
169/* Supported pixel formats. */
170static const struct noon010_format noon010_formats[] = {
171 {
172 .code = V4L2_MBUS_FMT_YUYV8_2X8,
173 .colorspace = V4L2_COLORSPACE_JPEG,
174 .ispctl1_reg = 0x03,
175 }, {
176 .code = V4L2_MBUS_FMT_YVYU8_2X8,
177 .colorspace = V4L2_COLORSPACE_JPEG,
178 .ispctl1_reg = 0x02,
179 }, {
180 .code = V4L2_MBUS_FMT_VYUY8_2X8,
181 .colorspace = V4L2_COLORSPACE_JPEG,
182 .ispctl1_reg = 0,
183 }, {
184 .code = V4L2_MBUS_FMT_UYVY8_2X8,
185 .colorspace = V4L2_COLORSPACE_JPEG,
186 .ispctl1_reg = 0x01,
187 }, {
188 .code = V4L2_MBUS_FMT_RGB565_2X8_BE,
189 .colorspace = V4L2_COLORSPACE_JPEG,
190 .ispctl1_reg = 0x40,
191 },
192};
193
194static const struct i2c_regval noon010_base_regs[] = {
195 { WIN_COLL_REG, 0x06 }, { HBLANKL_REG, 0x7C },
196 /* Color corection and saturation */
197 { ISP_CTL_REG(0), 0x30 }, { ISP_CTL_REG(2), 0x30 },
198 { YOFS_REG, 0x80 }, { DARK_YOFS_REG, 0x04 },
199 { SAT_CTL_REG, 0x1F }, { BSAT_REG, 0x90 },
200 { CMC_CTL_REG, 0x0F }, { CMC_OFSGH_REG, 0x3C },
201 { CMC_OFSGL_REG, 0x2C }, { CMC_SIGN_REG, 0x3F },
202 { CMC_COEF_REG(0), 0x79 }, { CMC_OFS_REG(0), 0x00 },
203 { CMC_COEF_REG(1), 0x39 }, { CMC_OFS_REG(1), 0x00 },
204 { CMC_COEF_REG(2), 0x00 }, { CMC_OFS_REG(2), 0x00 },
205 { CMC_COEF_REG(3), 0x11 }, { CMC_OFS_REG(3), 0x8B },
206 { CMC_COEF_REG(4), 0x65 }, { CMC_OFS_REG(4), 0x07 },
207 { CMC_COEF_REG(5), 0x14 }, { CMC_OFS_REG(5), 0x04 },
208 { CMC_COEF_REG(6), 0x01 }, { CMC_OFS_REG(6), 0x9C },
209 { CMC_COEF_REG(7), 0x33 }, { CMC_OFS_REG(7), 0x89 },
210 { CMC_COEF_REG(8), 0x74 }, { CMC_OFS_REG(8), 0x25 },
211 /* Automatic white balance */
212 { AWB_CTL_REG(0), 0x78 }, { AWB_CTL_REG(1), 0x2E },
213 { AWB_CTL_REG(2), 0x20 }, { AWB_CTL_REG(3), 0x85 },
214 /* Auto exposure */
215 { AE_CTL_REG(0), 0xDC }, { AE_CTL_REG(1), 0x81 },
216 { AE_CTL_REG(2), 0x30 }, { AE_CTL_REG(3), 0xA5 },
217 { AE_CTL_REG(4), 0x40 }, { AE_CTL_REG(5), 0x51 },
218 { AE_CTL_REG(6), 0x33 }, { AE_CTL_REG(7), 0x7E },
219 { AE_CTL9_REG, 0x00 }, { AE_CTL10_REG, 0x02 },
220 { AE_YLVL_REG, 0x44 }, { AE_YTH_REG(0), 0x34 },
221 { AE_YTH_REG(1), 0x30 }, { AE_WGT_REG, 0xD5 },
222 /* Lens shading compensation */
223 { LENS_CTRL_REG, 0x01 }, { LENS_XCEN_REG, 0x80 },
224 { LENS_YCEN_REG, 0x70 }, { LENS_RC_REG, 0x53 },
225 { LENS_GC_REG, 0x40 }, { LENS_BC_REG, 0x3E },
226 { REG_TERM, 0 },
227};
228
229static inline struct noon010_info *to_noon010(struct v4l2_subdev *sd)
230{
231 return container_of(sd, struct noon010_info, sd);
232}
233
234static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
235{
236 return &container_of(ctrl->handler, struct noon010_info, hdl)->sd;
237}
238
239static inline int set_i2c_page(struct noon010_info *info,
240 struct i2c_client *client, unsigned int reg)
241{
242 u32 page = reg >> 8 & 0xFF;
243 int ret = 0;
244
245 if (info->i2c_reg_page != page && (reg & 0xFF) != 0x03) {
246 ret = i2c_smbus_write_byte_data(client, PAGEMODE_REG, page);
247 if (!ret)
248 info->i2c_reg_page = page;
249 }
250 return ret;
251}
252
253static int cam_i2c_read(struct v4l2_subdev *sd, u32 reg_addr)
254{
255 struct i2c_client *client = v4l2_get_subdevdata(sd);
256 struct noon010_info *info = to_noon010(sd);
257 int ret = set_i2c_page(info, client, reg_addr);
258
259 if (ret)
260 return ret;
261 return i2c_smbus_read_byte_data(client, reg_addr & 0xFF);
262}
263
264static int cam_i2c_write(struct v4l2_subdev *sd, u32 reg_addr, u32 val)
265{
266 struct i2c_client *client = v4l2_get_subdevdata(sd);
267 struct noon010_info *info = to_noon010(sd);
268 int ret = set_i2c_page(info, client, reg_addr);
269
270 if (ret)
271 return ret;
272 return i2c_smbus_write_byte_data(client, reg_addr & 0xFF, val);
273}
274
275static inline int noon010_bulk_write_reg(struct v4l2_subdev *sd,
276 const struct i2c_regval *msg)
277{
278 while (msg->addr != REG_TERM) {
279 int ret = cam_i2c_write(sd, msg->addr, msg->val);
280
281 if (ret)
282 return ret;
283 msg++;
284 }
285 return 0;
286}
287
288/* Device reset and sleep mode control */
289static int noon010_power_ctrl(struct v4l2_subdev *sd, bool reset, bool sleep)
290{
291 struct noon010_info *info = to_noon010(sd);
292 u8 reg = sleep ? 0xF1 : 0xF0;
293 int ret = 0;
294
295 if (reset)
296 ret = cam_i2c_write(sd, POWER_CTRL_REG, reg | 0x02);
297 if (!ret) {
298 ret = cam_i2c_write(sd, POWER_CTRL_REG, reg);
299 if (reset && !ret)
300 info->i2c_reg_page = -1;
301 }
302 return ret;
303}
304
305/* Automatic white balance control */
306static int noon010_enable_autowhitebalance(struct v4l2_subdev *sd, int on)
307{
308 int ret;
309
310 ret = cam_i2c_write(sd, AWB_CTL_REG(1), on ? 0x2E : 0x2F);
311 if (!ret)
312 ret = cam_i2c_write(sd, AWB_CTL_REG(0), on ? 0xFB : 0x7B);
313 return ret;
314}
315
316static int noon010_set_flip(struct v4l2_subdev *sd, int hflip, int vflip)
317{
318 struct noon010_info *info = to_noon010(sd);
319 int reg, ret;
320
321 reg = cam_i2c_read(sd, VDO_CTL_REG(1));
322 if (reg < 0)
323 return reg;
324
325 reg &= 0x7C;
326 if (hflip)
327 reg |= 0x01;
328 if (vflip)
329 reg |= 0x02;
330
331 ret = cam_i2c_write(sd, VDO_CTL_REG(1), reg | 0x80);
332 if (!ret) {
333 info->hflip = hflip;
334 info->vflip = vflip;
335 }
336 return ret;
337}
338
339/* Configure resolution and color format */
340static int noon010_set_params(struct v4l2_subdev *sd)
341{
342 struct noon010_info *info = to_noon010(sd);
343 int ret;
344
345 if (!info->curr_win)
346 return -EINVAL;
347
348 ret = cam_i2c_write(sd, VDO_CTL_REG(0), info->curr_win->vid_ctl1);
349
350 if (!ret && info->curr_fmt)
351 ret = cam_i2c_write(sd, ISP_CTL_REG(0),
352 info->curr_fmt->ispctl1_reg);
353 return ret;
354}
355
356/* Find nearest matching image pixel size. */
357static int noon010_try_frame_size(struct v4l2_mbus_framefmt *mf)
358{
359 unsigned int min_err = ~0;
360 int i = ARRAY_SIZE(noon010_sizes);
361 const struct noon010_frmsize *fsize = &noon010_sizes[0],
362 *match = NULL;
363
364 while (i--) {
365 int err = abs(fsize->width - mf->width)
366 + abs(fsize->height - mf->height);
367
368 if (err < min_err) {
369 min_err = err;
370 match = fsize;
371 }
372 fsize++;
373 }
374 if (match) {
375 mf->width = match->width;
376 mf->height = match->height;
377 return 0;
378 }
379 return -EINVAL;
380}
381
382static int power_enable(struct noon010_info *info)
383{
384 int ret;
385
386 if (info->power) {
387 v4l2_info(&info->sd, "%s: sensor is already on\n", __func__);
388 return 0;
389 }
390
391 if (gpio_is_valid(info->gpio_nstby))
392 gpio_set_value(info->gpio_nstby, 0);
393
394 if (gpio_is_valid(info->gpio_nreset))
395 gpio_set_value(info->gpio_nreset, 0);
396
397 ret = regulator_bulk_enable(NOON010_NUM_SUPPLIES, info->supply);
398 if (ret)
399 return ret;
400
401 if (gpio_is_valid(info->gpio_nreset)) {
402 msleep(50);
403 gpio_set_value(info->gpio_nreset, 1);
404 }
405 if (gpio_is_valid(info->gpio_nstby)) {
406 udelay(1000);
407 gpio_set_value(info->gpio_nstby, 1);
408 }
409 if (gpio_is_valid(info->gpio_nreset)) {
410 udelay(1000);
411 gpio_set_value(info->gpio_nreset, 0);
412 msleep(100);
413 gpio_set_value(info->gpio_nreset, 1);
414 msleep(20);
415 }
416 info->power = 1;
417
418 v4l2_dbg(1, debug, &info->sd, "%s: sensor is on\n", __func__);
419 return 0;
420}
421
422static int power_disable(struct noon010_info *info)
423{
424 int ret;
425
426 if (!info->power) {
427 v4l2_info(&info->sd, "%s: sensor is already off\n", __func__);
428 return 0;
429 }
430
431 ret = regulator_bulk_disable(NOON010_NUM_SUPPLIES, info->supply);
432 if (ret)
433 return ret;
434
435 if (gpio_is_valid(info->gpio_nstby))
436 gpio_set_value(info->gpio_nstby, 0);
437
438 if (gpio_is_valid(info->gpio_nreset))
439 gpio_set_value(info->gpio_nreset, 0);
440
441 info->power = 0;
442
443 v4l2_dbg(1, debug, &info->sd, "%s: sensor is off\n", __func__);
444
445 return 0;
446}
447
448static int noon010_s_ctrl(struct v4l2_ctrl *ctrl)
449{
450 struct v4l2_subdev *sd = to_sd(ctrl);
451
452 v4l2_dbg(1, debug, sd, "%s: ctrl_id: %d, value: %d\n",
453 __func__, ctrl->id, ctrl->val);
454
455 switch (ctrl->id) {
456 case V4L2_CID_AUTO_WHITE_BALANCE:
457 return noon010_enable_autowhitebalance(sd, ctrl->val);
458 case V4L2_CID_BLUE_BALANCE:
459 return cam_i2c_write(sd, MWB_BGAIN_REG, ctrl->val);
460 case V4L2_CID_RED_BALANCE:
461 return cam_i2c_write(sd, MWB_RGAIN_REG, ctrl->val);
462 default:
463 return -EINVAL;
464 }
465}
466
467static int noon010_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
468 enum v4l2_mbus_pixelcode *code)
469{
470 if (!code || index >= ARRAY_SIZE(noon010_formats))
471 return -EINVAL;
472
473 *code = noon010_formats[index].code;
474 return 0;
475}
476
477static int noon010_g_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
478{
479 struct noon010_info *info = to_noon010(sd);
480 int ret;
481
482 if (!mf)
483 return -EINVAL;
484
485 if (!info->curr_win || !info->curr_fmt) {
486 ret = noon010_set_params(sd);
487 if (ret)
488 return ret;
489 }
490
491 mf->width = info->curr_win->width;
492 mf->height = info->curr_win->height;
493 mf->code = info->curr_fmt->code;
494 mf->colorspace = info->curr_fmt->colorspace;
495 mf->field = V4L2_FIELD_NONE;
496
497 return 0;
498}
499
500/* Return nearest media bus frame format. */
501static const struct noon010_format *try_fmt(struct v4l2_subdev *sd,
502 struct v4l2_mbus_framefmt *mf)
503{
504 int i = ARRAY_SIZE(noon010_formats);
505
506 noon010_try_frame_size(mf);
507
508 while (i--)
509 if (mf->code == noon010_formats[i].code)
510 break;
511
512 mf->code = noon010_formats[i].code;
513
514 return &noon010_formats[i];
515}
516
517static int noon010_try_fmt(struct v4l2_subdev *sd,
518 struct v4l2_mbus_framefmt *mf)
519{
520 if (!sd || !mf)
521 return -EINVAL;
522
523 try_fmt(sd, mf);
524 return 0;
525}
526
527static int noon010_s_fmt(struct v4l2_subdev *sd,
528 struct v4l2_mbus_framefmt *mf)
529{
530 struct noon010_info *info = to_noon010(sd);
531
532 if (!sd || !mf)
533 return -EINVAL;
534
535 info->curr_fmt = try_fmt(sd, mf);
536
537 return noon010_set_params(sd);
538}
539
540static int noon010_base_config(struct v4l2_subdev *sd)
541{
542 struct noon010_info *info = to_noon010(sd);
543 int ret;
544
545 ret = noon010_bulk_write_reg(sd, noon010_base_regs);
546 if (!ret) {
547 info->curr_fmt = &noon010_formats[0];
548 info->curr_win = &noon010_sizes[0];
549 ret = noon010_set_params(sd);
550 }
551 if (!ret)
552 ret = noon010_set_flip(sd, 1, 0);
553 if (!ret)
554 ret = noon010_power_ctrl(sd, false, false);
555
556 /* sync the handler and the registers state */
557 v4l2_ctrl_handler_setup(&to_noon010(sd)->hdl);
558 return ret;
559}
560
561static int noon010_s_power(struct v4l2_subdev *sd, int on)
562{
563 struct noon010_info *info = to_noon010(sd);
564 const struct noon010pc30_platform_data *pdata = info->pdata;
565 int ret = 0;
566
567 if (WARN(pdata == NULL, "No platform data!\n"))
568 return -ENOMEM;
569
570 if (on) {
571 ret = power_enable(info);
572 if (ret)
573 return ret;
574 ret = noon010_base_config(sd);
575 } else {
576 noon010_power_ctrl(sd, false, true);
577 ret = power_disable(info);
578 info->curr_win = NULL;
579 info->curr_fmt = NULL;
580 }
581
582 return ret;
583}
584
585static int noon010_g_chip_ident(struct v4l2_subdev *sd,
586 struct v4l2_dbg_chip_ident *chip)
587{
588 struct i2c_client *client = v4l2_get_subdevdata(sd);
589
590 return v4l2_chip_ident_i2c_client(client, chip,
591 V4L2_IDENT_NOON010PC30, 0);
592}
593
594static int noon010_log_status(struct v4l2_subdev *sd)
595{
596 struct noon010_info *info = to_noon010(sd);
597
598 v4l2_ctrl_handler_log_status(&info->hdl, sd->name);
599 return 0;
600}
601
602static const struct v4l2_ctrl_ops noon010_ctrl_ops = {
603 .s_ctrl = noon010_s_ctrl,
604};
605
606static const struct v4l2_subdev_core_ops noon010_core_ops = {
607 .g_chip_ident = noon010_g_chip_ident,
608 .s_power = noon010_s_power,
609 .g_ctrl = v4l2_subdev_g_ctrl,
610 .s_ctrl = v4l2_subdev_s_ctrl,
611 .queryctrl = v4l2_subdev_queryctrl,
612 .querymenu = v4l2_subdev_querymenu,
613 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
614 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
615 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
616 .log_status = noon010_log_status,
617};
618
619static const struct v4l2_subdev_video_ops noon010_video_ops = {
620 .g_mbus_fmt = noon010_g_fmt,
621 .s_mbus_fmt = noon010_s_fmt,
622 .try_mbus_fmt = noon010_try_fmt,
623 .enum_mbus_fmt = noon010_enum_fmt,
624};
625
626static const struct v4l2_subdev_ops noon010_ops = {
627 .core = &noon010_core_ops,
628 .video = &noon010_video_ops,
629};
630
631/* Return 0 if NOON010PC30L sensor type was detected or -ENODEV otherwise. */
632static int noon010_detect(struct i2c_client *client, struct noon010_info *info)
633{
634 int ret;
635
636 ret = power_enable(info);
637 if (ret)
638 return ret;
639
640 ret = i2c_smbus_read_byte_data(client, DEVICE_ID_REG);
641 if (ret < 0)
642 dev_err(&client->dev, "I2C read failed: 0x%X\n", ret);
643
644 power_disable(info);
645
646 return ret == NOON010PC30_ID ? 0 : -ENODEV;
647}
648
649static int noon010_probe(struct i2c_client *client,
650 const struct i2c_device_id *id)
651{
652 struct noon010_info *info;
653 struct v4l2_subdev *sd;
654 const struct noon010pc30_platform_data *pdata
655 = client->dev.platform_data;
656 int ret;
657 int i;
658
659 if (!pdata) {
660 dev_err(&client->dev, "No platform data!\n");
661 return -EIO;
662 }
663
664 info = kzalloc(sizeof(*info), GFP_KERNEL);
665 if (!info)
666 return -ENOMEM;
667
668 sd = &info->sd;
669 strlcpy(sd->name, MODULE_NAME, sizeof(sd->name));
670 v4l2_i2c_subdev_init(sd, client, &noon010_ops);
671
672 v4l2_ctrl_handler_init(&info->hdl, 3);
673
674 v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
675 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
676 v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
677 V4L2_CID_RED_BALANCE, 0, 127, 1, 64);
678 v4l2_ctrl_new_std(&info->hdl, &noon010_ctrl_ops,
679 V4L2_CID_BLUE_BALANCE, 0, 127, 1, 64);
680
681 sd->ctrl_handler = &info->hdl;
682
683 ret = info->hdl.error;
684 if (ret)
685 goto np_err;
686
687 info->pdata = client->dev.platform_data;
688 info->i2c_reg_page = -1;
689 info->gpio_nreset = -EINVAL;
690 info->gpio_nstby = -EINVAL;
691
692 if (gpio_is_valid(pdata->gpio_nreset)) {
693 ret = gpio_request(pdata->gpio_nreset, "NOON010PC30 NRST");
694 if (ret) {
695 dev_err(&client->dev, "GPIO request error: %d\n", ret);
696 goto np_err;
697 }
698 info->gpio_nreset = pdata->gpio_nreset;
699 gpio_direction_output(info->gpio_nreset, 0);
700 gpio_export(info->gpio_nreset, 0);
701 }
702
703 if (gpio_is_valid(pdata->gpio_nstby)) {
704 ret = gpio_request(pdata->gpio_nstby, "NOON010PC30 NSTBY");
705 if (ret) {
706 dev_err(&client->dev, "GPIO request error: %d\n", ret);
707 goto np_gpio_err;
708 }
709 info->gpio_nstby = pdata->gpio_nstby;
710 gpio_direction_output(info->gpio_nstby, 0);
711 gpio_export(info->gpio_nstby, 0);
712 }
713
714 for (i = 0; i < NOON010_NUM_SUPPLIES; i++)
715 info->supply[i].supply = noon010_supply_name[i];
716
717 ret = regulator_bulk_get(&client->dev, NOON010_NUM_SUPPLIES,
718 info->supply);
719 if (ret)
720 goto np_reg_err;
721
722 ret = noon010_detect(client, info);
723 if (!ret)
724 return 0;
725
726 /* the sensor detection failed */
727 regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
728np_reg_err:
729 if (gpio_is_valid(info->gpio_nstby))
730 gpio_free(info->gpio_nstby);
731np_gpio_err:
732 if (gpio_is_valid(info->gpio_nreset))
733 gpio_free(info->gpio_nreset);
734np_err:
735 v4l2_ctrl_handler_free(&info->hdl);
736 v4l2_device_unregister_subdev(sd);
737 kfree(info);
738 return ret;
739}
740
741static int noon010_remove(struct i2c_client *client)
742{
743 struct v4l2_subdev *sd = i2c_get_clientdata(client);
744 struct noon010_info *info = to_noon010(sd);
745
746 v4l2_device_unregister_subdev(sd);
747 v4l2_ctrl_handler_free(&info->hdl);
748
749 regulator_bulk_free(NOON010_NUM_SUPPLIES, info->supply);
750
751 if (gpio_is_valid(info->gpio_nreset))
752 gpio_free(info->gpio_nreset);
753
754 if (gpio_is_valid(info->gpio_nstby))
755 gpio_free(info->gpio_nstby);
756
757 kfree(info);
758 return 0;
759}
760
761static const struct i2c_device_id noon010_id[] = {
762 { MODULE_NAME, 0 },
763 { },
764};
765MODULE_DEVICE_TABLE(i2c, noon010_id);
766
767
768static struct i2c_driver noon010_i2c_driver = {
769 .driver = {
770 .name = MODULE_NAME
771 },
772 .probe = noon010_probe,
773 .remove = noon010_remove,
774 .id_table = noon010_id,
775};
776
777static int __init noon010_init(void)
778{
779 return i2c_add_driver(&noon010_i2c_driver);
780}
781
782static void __exit noon010_exit(void)
783{
784 i2c_del_driver(&noon010_i2c_driver);
785}
786
787module_init(noon010_init);
788module_exit(noon010_exit);
789
790MODULE_DESCRIPTION("Siliconfile NOON010PC30 camera driver");
791MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
792MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index 0a2fb2bfdbfb..eab31cbd68eb 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -811,8 +811,8 @@ static irqreturn_t cam_isr(int irq, void *data)
811 spin_lock_irqsave(&pcdev->lock, flags); 811 spin_lock_irqsave(&pcdev->lock, flags);
812 812
813 if (WARN_ON(!buf)) { 813 if (WARN_ON(!buf)) {
814 dev_warn(dev, "%s: unhandled camera interrupt, status == " 814 dev_warn(dev, "%s: unhandled camera interrupt, status == %#x\n",
815 "%#x\n", __func__, it_status); 815 __func__, it_status);
816 suspend_capture(pcdev); 816 suspend_capture(pcdev);
817 disable_capture(pcdev); 817 disable_capture(pcdev);
818 goto out; 818 goto out;
@@ -1088,15 +1088,15 @@ static int omap1_cam_get_formats(struct soc_camera_device *icd,
1088 xlate->host_fmt = &omap1_cam_formats[code]; 1088 xlate->host_fmt = &omap1_cam_formats[code];
1089 xlate->code = code; 1089 xlate->code = code;
1090 xlate++; 1090 xlate++;
1091 dev_dbg(dev, "%s: providing format %s " 1091 dev_dbg(dev,
1092 "as byte swapped code #%d\n", __func__, 1092 "%s: providing format %s as byte swapped code #%d\n",
1093 omap1_cam_formats[code].name, code); 1093 __func__, omap1_cam_formats[code].name, code);
1094 } 1094 }
1095 default: 1095 default:
1096 if (xlate) 1096 if (xlate)
1097 dev_dbg(dev, "%s: providing format %s " 1097 dev_dbg(dev,
1098 "in pass-through mode\n", __func__, 1098 "%s: providing format %s in pass-through mode\n",
1099 fmt->name); 1099 __func__, fmt->name);
1100 } 1100 }
1101 formats++; 1101 formats++;
1102 if (xlate) { 1102 if (xlate) {
@@ -1139,29 +1139,29 @@ static int dma_align(int *width, int *height,
1139 return 1; 1139 return 1;
1140} 1140}
1141 1141
1142#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \ 1142#define subdev_call_with_sense(pcdev, dev, icd, sd, function, args...) \
1143({ \ 1143({ \
1144 struct soc_camera_sense sense = { \ 1144 struct soc_camera_sense sense = { \
1145 .master_clock = pcdev->camexclk, \ 1145 .master_clock = pcdev->camexclk, \
1146 .pixel_clock_max = 0, \ 1146 .pixel_clock_max = 0, \
1147 }; \ 1147 }; \
1148 int __ret; \ 1148 int __ret; \
1149 \ 1149 \
1150 if (pcdev->pdata) \ 1150 if (pcdev->pdata) \
1151 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \ 1151 sense.pixel_clock_max = pcdev->pdata->lclk_khz_max * 1000; \
1152 icd->sense = &sense; \ 1152 icd->sense = &sense; \
1153 __ret = v4l2_subdev_call(sd, video, function, ##args); \ 1153 __ret = v4l2_subdev_call(sd, video, function, ##args); \
1154 icd->sense = NULL; \ 1154 icd->sense = NULL; \
1155 \ 1155 \
1156 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \ 1156 if (sense.flags & SOCAM_SENSE_PCLK_CHANGED) { \
1157 if (sense.pixel_clock > sense.pixel_clock_max) { \ 1157 if (sense.pixel_clock > sense.pixel_clock_max) { \
1158 dev_err(dev, "%s: pixel clock %lu " \ 1158 dev_err(dev, \
1159 "set by the camera too high!\n", \ 1159 "%s: pixel clock %lu set by the camera too high!\n", \
1160 __func__, sense.pixel_clock); \ 1160 __func__, sense.pixel_clock); \
1161 __ret = -EINVAL; \ 1161 __ret = -EINVAL; \
1162 } \ 1162 } \
1163 } \ 1163 } \
1164 __ret; \ 1164 __ret; \
1165}) 1165})
1166 1166
1167static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev, 1167static int set_mbus_format(struct omap1_cam_dev *pcdev, struct device *dev,
@@ -1664,10 +1664,10 @@ static int __exit omap1_cam_remove(struct platform_device *pdev)
1664 res = pcdev->res; 1664 res = pcdev->res;
1665 release_mem_region(res->start, resource_size(res)); 1665 release_mem_region(res->start, resource_size(res));
1666 1666
1667 kfree(pcdev);
1668
1669 clk_put(pcdev->clk); 1667 clk_put(pcdev->clk);
1670 1668
1669 kfree(pcdev);
1670
1671 dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n"); 1671 dev_info(&pdev->dev, "OMAP1 Camera Interface driver unloaded\n");
1672 1672
1673 return 0; 1673 return 0;
diff --git a/drivers/media/video/omap24xxcam.c b/drivers/media/video/omap24xxcam.c
index 017552762902..f6626e87dbc5 100644
--- a/drivers/media/video/omap24xxcam.c
+++ b/drivers/media/video/omap24xxcam.c
@@ -36,6 +36,7 @@
36#include <linux/clk.h> 36#include <linux/clk.h>
37#include <linux/io.h> 37#include <linux/io.h>
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/sched.h>
39 40
40#include <media/v4l2-common.h> 41#include <media/v4l2-common.h>
41#include <media/v4l2-ioctl.h> 42#include <media/v4l2-ioctl.h>
diff --git a/drivers/media/video/omap3isp/Makefile b/drivers/media/video/omap3isp/Makefile
new file mode 100644
index 000000000000..b1b344774ae7
--- /dev/null
+++ b/drivers/media/video/omap3isp/Makefile
@@ -0,0 +1,13 @@
1# Makefile for OMAP3 ISP driver
2
3ifdef CONFIG_VIDEO_OMAP3_DEBUG
4EXTRA_CFLAGS += -DDEBUG
5endif
6
7omap3-isp-objs += \
8 isp.o ispqueue.o ispvideo.o \
9 ispcsiphy.o ispccp2.o ispcsi2.o \
10 ispccdc.o isppreview.o ispresizer.o \
11 ispstat.o isph3a_aewb.o isph3a_af.o isphist.o
12
13obj-$(CONFIG_VIDEO_OMAP3) += omap3-isp.o
diff --git a/drivers/media/video/omap3isp/cfa_coef_table.h b/drivers/media/video/omap3isp/cfa_coef_table.h
new file mode 100644
index 000000000000..c60df0ed075a
--- /dev/null
+++ b/drivers/media/video/omap3isp/cfa_coef_table.h
@@ -0,0 +1,61 @@
1/*
2 * cfa_coef_table.h
3 *
4 * TI OMAP3 ISP - CFA coefficients table
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * version 2 as published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * 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, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
27248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
28247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
29244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
30248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
31247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
32244, 0, 247, 0, 12, 27, 36, 247, 250, 0, 27, 0, 4, 250, 12, 244,
33248, 0, 0, 0, 0, 40, 0, 0, 244, 12, 250, 4, 0, 27, 0, 250,
34247, 36, 27, 12, 0, 247, 0, 244, 0, 0, 40, 0, 0, 0, 0, 248,
35 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
36 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
37 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
38 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
39 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
40 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
41 0, 247, 0, 244, 247, 36, 27, 12, 0, 27, 0, 250, 244, 12, 250, 4,
42 0, 0, 0, 248, 0, 0, 40, 0, 4, 250, 12, 244, 250, 0, 27, 0,
43 12, 27, 36, 247, 244, 0, 247, 0, 0, 40, 0, 0, 248, 0, 0, 0,
44 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
45 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
46 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
47 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
48 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
49 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
50 4, 250, 12, 244, 250, 0, 27, 0, 12, 27, 36, 247, 244, 0, 247, 0,
51 0, 0, 0, 248, 0, 0, 40, 0, 0, 247, 0, 244, 247, 36, 27, 12,
52 0, 27, 0, 250, 244, 12, 250, 4, 0, 40, 0, 0, 248, 0, 0, 0,
53244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
54248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
55250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
56244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
57248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
58250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248,
59244, 12, 250, 4, 0, 27, 0, 250, 247, 36, 27, 12, 0, 247, 0, 244,
60248, 0, 0, 0, 0, 40, 0, 0, 244, 0, 247, 0, 12, 27, 36, 247,
61250, 0, 27, 0, 4, 250, 12, 244, 0, 0, 40, 0, 0, 0, 0, 248
diff --git a/drivers/media/video/omap3isp/gamma_table.h b/drivers/media/video/omap3isp/gamma_table.h
new file mode 100644
index 000000000000..78deebf7d965
--- /dev/null
+++ b/drivers/media/video/omap3isp/gamma_table.h
@@ -0,0 +1,90 @@
1/*
2 * gamma_table.h
3 *
4 * TI OMAP3 ISP - Default gamma table for all components
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27 0, 0, 1, 2, 3, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18, 20,
28 22, 23, 25, 26, 28, 29, 31, 32, 34, 35, 36, 37, 39, 40, 41, 42,
29 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 52, 53, 54, 55, 56, 57,
30 58, 59, 60, 61, 62, 63, 63, 64, 65, 66, 66, 67, 68, 69, 69, 70,
31 71, 72, 72, 73, 74, 75, 75, 76, 77, 78, 78, 79, 80, 81, 81, 82,
32 83, 84, 84, 85, 86, 87, 88, 88, 89, 90, 91, 91, 92, 93, 94, 94,
33 95, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 103, 104, 104,
34105, 106, 107, 108, 108, 109, 110, 111, 111, 112, 113, 114, 114, 115, 116, 117,
35117, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125,
36126, 126, 127, 127, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132, 133, 133,
37134, 134, 135, 135, 136, 136, 137, 137, 138, 138, 139, 139, 140, 140, 141, 141,
38142, 142, 143, 143, 144, 144, 145, 145, 146, 146, 147, 147, 148, 148, 149, 149,
39150, 150, 151, 151, 152, 152, 153, 153, 153, 153, 154, 154, 154, 154, 155, 155,
40156, 156, 157, 157, 158, 158, 158, 159, 159, 159, 160, 160, 160, 161, 161, 162,
41162, 163, 163, 164, 164, 164, 164, 165, 165, 165, 165, 166, 166, 167, 167, 168,
42168, 169, 169, 170, 170, 170, 170, 171, 171, 171, 171, 172, 172, 173, 173, 174,
43174, 175, 175, 176, 176, 176, 176, 177, 177, 177, 177, 178, 178, 178, 178, 179,
44179, 179, 179, 180, 180, 180, 180, 181, 181, 181, 181, 182, 182, 182, 182, 183,
45183, 183, 183, 184, 184, 184, 184, 185, 185, 185, 185, 186, 186, 186, 186, 187,
46187, 187, 187, 188, 188, 188, 188, 189, 189, 189, 189, 190, 190, 190, 190, 191,
47191, 191, 191, 192, 192, 192, 192, 193, 193, 193, 193, 194, 194, 194, 194, 195,
48195, 195, 195, 196, 196, 196, 196, 197, 197, 197, 197, 198, 198, 198, 198, 199,
49199, 199, 199, 200, 200, 200, 200, 201, 201, 201, 201, 202, 202, 202, 203, 203,
50203, 203, 204, 204, 204, 204, 205, 205, 205, 205, 206, 206, 206, 206, 207, 207,
51207, 207, 208, 208, 208, 208, 209, 209, 209, 209, 210, 210, 210, 210, 210, 210,
52210, 210, 210, 210, 210, 210, 211, 211, 211, 211, 211, 211, 211, 211, 211, 211,
53211, 212, 212, 212, 212, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213, 213,
54213, 214, 214, 214, 214, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
55216, 216, 216, 216, 217, 217, 217, 217, 218, 218, 218, 218, 219, 219, 219, 219,
56219, 219, 219, 219, 219, 219, 219, 219, 220, 220, 220, 220, 221, 221, 221, 221,
57221, 221, 221, 221, 221, 221, 221, 222, 222, 222, 222, 223, 223, 223, 223, 223,
58223, 223, 223, 223, 223, 223, 223, 224, 224, 224, 224, 225, 225, 225, 225, 225,
59225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 226, 226,
60226, 226, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 227, 228, 228,
61228, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 229, 230, 230, 230,
62230, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 231, 232, 232, 232,
63232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232, 232,
64233, 233, 233, 233, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 234, 235,
65235, 235, 235, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236, 236,
66236, 236, 236, 236, 236, 236, 237, 237, 237, 237, 238, 238, 238, 238, 238, 238,
67238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238, 238,
68238, 238, 238, 238, 238, 239, 239, 239, 239, 240, 240, 240, 240, 240, 240, 240,
69240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240, 240,
70240, 240, 240, 240, 241, 241, 241, 241, 242, 242, 242, 242, 242, 242, 242, 242,
71242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242, 242,
72242, 242, 243, 243, 243, 243, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
73244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244, 244,
74244, 245, 245, 245, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
75246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246,
76246, 246, 246, 246, 246, 246, 246, 247, 247, 247, 247, 248, 248, 248, 248, 248,
77248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248, 248,
78248, 248, 248, 248, 248, 248, 249, 249, 249, 249, 250, 250, 250, 250, 250, 250,
79250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
80250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250, 250,
81250, 250, 250, 250, 251, 251, 251, 251, 252, 252, 252, 252, 252, 252, 252, 252,
82252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
83252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
84252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252, 252,
85252, 252, 252, 252, 252, 252, 252, 252, 253, 253, 253, 253, 253, 253, 253, 253,
86253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
87253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
88253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253, 253,
89253, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
90255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
new file mode 100644
index 000000000000..1a9963bd6d40
--- /dev/null
+++ b/drivers/media/video/omap3isp/isp.c
@@ -0,0 +1,2220 @@
1/*
2 * isp.c
3 *
4 * TI OMAP3 ISP - Core
5 *
6 * Copyright (C) 2006-2010 Nokia Corporation
7 * Copyright (C) 2007-2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * Contributors:
13 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
14 * Sakari Ailus <sakari.ailus@iki.fi>
15 * David Cohen <dacohen@gmail.com>
16 * Stanimir Varbanov <svarbanov@mm-sol.com>
17 * Vimarsh Zutshi <vimarsh.zutshi@gmail.com>
18 * Tuukka Toivonen <tuukkat76@gmail.com>
19 * Sergio Aguirre <saaguirre@ti.com>
20 * Antti Koskipaa <akoskipa@gmail.com>
21 * Ivan T. Ivanov <iivanov@mm-sol.com>
22 * RaniSuneela <r-m@ti.com>
23 * Atanas Filipov <afilipov@mm-sol.com>
24 * Gjorgji Rosikopulos <grosikopulos@mm-sol.com>
25 * Hiroshi DOYU <hiroshi.doyu@nokia.com>
26 * Nayden Kanchev <nkanchev@mm-sol.com>
27 * Phil Carmody <ext-phil.2.carmody@nokia.com>
28 * Artem Bityutskiy <artem.bityutskiy@nokia.com>
29 * Dominic Curran <dcurran@ti.com>
30 * Ilkka Myllyperkio <ilkka.myllyperkio@sofica.fi>
31 * Pallavi Kulkarni <p-kulkarni@ti.com>
32 * Vaibhav Hiremath <hvaibhav@ti.com>
33 * Mohit Jalori <mjalori@ti.com>
34 * Sameer Venkatraman <sameerv@ti.com>
35 * Senthilvadivu Guruswamy <svadivu@ti.com>
36 * Thara Gopinath <thara@ti.com>
37 * Toni Leinonen <toni.leinonen@nokia.com>
38 * Troy Laramy <t-laramy@ti.com>
39 *
40 * This program is free software; you can redistribute it and/or modify
41 * it under the terms of the GNU General Public License version 2 as
42 * published by the Free Software Foundation.
43 *
44 * This program is distributed in the hope that it will be useful, but
45 * WITHOUT ANY WARRANTY; without even the implied warranty of
46 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
47 * General Public License for more details.
48 *
49 * You should have received a copy of the GNU General Public License
50 * along with this program; if not, write to the Free Software
51 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
52 * 02110-1301 USA
53 */
54
55#include <asm/cacheflush.h>
56
57#include <linux/clk.h>
58#include <linux/delay.h>
59#include <linux/device.h>
60#include <linux/dma-mapping.h>
61#include <linux/i2c.h>
62#include <linux/interrupt.h>
63#include <linux/module.h>
64#include <linux/platform_device.h>
65#include <linux/regulator/consumer.h>
66#include <linux/slab.h>
67#include <linux/sched.h>
68#include <linux/vmalloc.h>
69
70#include <media/v4l2-common.h>
71#include <media/v4l2-device.h>
72
73#include "isp.h"
74#include "ispreg.h"
75#include "ispccdc.h"
76#include "isppreview.h"
77#include "ispresizer.h"
78#include "ispcsi2.h"
79#include "ispccp2.h"
80#include "isph3a.h"
81#include "isphist.h"
82
83static unsigned int autoidle;
84module_param(autoidle, int, 0444);
85MODULE_PARM_DESC(autoidle, "Enable OMAP3ISP AUTOIDLE support");
86
87static void isp_save_ctx(struct isp_device *isp);
88
89static void isp_restore_ctx(struct isp_device *isp);
90
91static const struct isp_res_mapping isp_res_maps[] = {
92 {
93 .isp_rev = ISP_REVISION_2_0,
94 .map = 1 << OMAP3_ISP_IOMEM_MAIN |
95 1 << OMAP3_ISP_IOMEM_CCP2 |
96 1 << OMAP3_ISP_IOMEM_CCDC |
97 1 << OMAP3_ISP_IOMEM_HIST |
98 1 << OMAP3_ISP_IOMEM_H3A |
99 1 << OMAP3_ISP_IOMEM_PREV |
100 1 << OMAP3_ISP_IOMEM_RESZ |
101 1 << OMAP3_ISP_IOMEM_SBL |
102 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
103 1 << OMAP3_ISP_IOMEM_CSIPHY2,
104 },
105 {
106 .isp_rev = ISP_REVISION_15_0,
107 .map = 1 << OMAP3_ISP_IOMEM_MAIN |
108 1 << OMAP3_ISP_IOMEM_CCP2 |
109 1 << OMAP3_ISP_IOMEM_CCDC |
110 1 << OMAP3_ISP_IOMEM_HIST |
111 1 << OMAP3_ISP_IOMEM_H3A |
112 1 << OMAP3_ISP_IOMEM_PREV |
113 1 << OMAP3_ISP_IOMEM_RESZ |
114 1 << OMAP3_ISP_IOMEM_SBL |
115 1 << OMAP3_ISP_IOMEM_CSI2A_REGS1 |
116 1 << OMAP3_ISP_IOMEM_CSIPHY2 |
117 1 << OMAP3_ISP_IOMEM_CSI2A_REGS2 |
118 1 << OMAP3_ISP_IOMEM_CSI2C_REGS1 |
119 1 << OMAP3_ISP_IOMEM_CSIPHY1 |
120 1 << OMAP3_ISP_IOMEM_CSI2C_REGS2,
121 },
122};
123
124/* Structure for saving/restoring ISP module registers */
125static struct isp_reg isp_reg_list[] = {
126 {OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG, 0},
127 {OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, 0},
128 {OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, 0},
129 {0, ISP_TOK_TERM, 0}
130};
131
132/*
133 * omap3isp_flush - Post pending L3 bus writes by doing a register readback
134 * @isp: OMAP3 ISP device
135 *
136 * In order to force posting of pending writes, we need to write and
137 * readback the same register, in this case the revision register.
138 *
139 * See this link for reference:
140 * http://www.mail-archive.com/linux-omap@vger.kernel.org/msg08149.html
141 */
142void omap3isp_flush(struct isp_device *isp)
143{
144 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
145 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
146}
147
148/*
149 * isp_enable_interrupts - Enable ISP interrupts.
150 * @isp: OMAP3 ISP device
151 */
152static void isp_enable_interrupts(struct isp_device *isp)
153{
154 static const u32 irq = IRQ0ENABLE_CSIA_IRQ
155 | IRQ0ENABLE_CSIB_IRQ
156 | IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ
157 | IRQ0ENABLE_CCDC_LSC_DONE_IRQ
158 | IRQ0ENABLE_CCDC_VD0_IRQ
159 | IRQ0ENABLE_CCDC_VD1_IRQ
160 | IRQ0ENABLE_HS_VS_IRQ
161 | IRQ0ENABLE_HIST_DONE_IRQ
162 | IRQ0ENABLE_H3A_AWB_DONE_IRQ
163 | IRQ0ENABLE_H3A_AF_DONE_IRQ
164 | IRQ0ENABLE_PRV_DONE_IRQ
165 | IRQ0ENABLE_RSZ_DONE_IRQ;
166
167 isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
168 isp_reg_writel(isp, irq, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
169}
170
171/*
172 * isp_disable_interrupts - Disable ISP interrupts.
173 * @isp: OMAP3 ISP device
174 */
175static void isp_disable_interrupts(struct isp_device *isp)
176{
177 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0ENABLE);
178}
179
180/**
181 * isp_set_xclk - Configures the specified cam_xclk to the desired frequency.
182 * @isp: OMAP3 ISP device
183 * @xclk: Desired frequency of the clock in Hz. 0 = stable low, 1 is stable high
184 * @xclksel: XCLK to configure (0 = A, 1 = B).
185 *
186 * Configures the specified MCLK divisor in the ISP timing control register
187 * (TCTRL_CTRL) to generate the desired xclk clock value.
188 *
189 * Divisor = cam_mclk_hz / xclk
190 *
191 * Returns the final frequency that is actually being generated
192 **/
193static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
194{
195 u32 divisor;
196 u32 currentxclk;
197 unsigned long mclk_hz;
198
199 if (!omap3isp_get(isp))
200 return 0;
201
202 mclk_hz = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
203
204 if (xclk >= mclk_hz) {
205 divisor = ISPTCTRL_CTRL_DIV_BYPASS;
206 currentxclk = mclk_hz;
207 } else if (xclk >= 2) {
208 divisor = mclk_hz / xclk;
209 if (divisor >= ISPTCTRL_CTRL_DIV_BYPASS)
210 divisor = ISPTCTRL_CTRL_DIV_BYPASS - 1;
211 currentxclk = mclk_hz / divisor;
212 } else {
213 divisor = xclk;
214 currentxclk = 0;
215 }
216
217 switch (xclksel) {
218 case 0:
219 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
220 ISPTCTRL_CTRL_DIVA_MASK,
221 divisor << ISPTCTRL_CTRL_DIVA_SHIFT);
222 dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n",
223 currentxclk);
224 break;
225 case 1:
226 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
227 ISPTCTRL_CTRL_DIVB_MASK,
228 divisor << ISPTCTRL_CTRL_DIVB_SHIFT);
229 dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n",
230 currentxclk);
231 break;
232 default:
233 omap3isp_put(isp);
234 dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested "
235 "xclk. Must be 0 (A) or 1 (B).\n");
236 return -EINVAL;
237 }
238
239 /* Do we go from stable whatever to clock? */
240 if (divisor >= 2 && isp->xclk_divisor[xclksel] < 2)
241 omap3isp_get(isp);
242 /* Stopping the clock. */
243 else if (divisor < 2 && isp->xclk_divisor[xclksel] >= 2)
244 omap3isp_put(isp);
245
246 isp->xclk_divisor[xclksel] = divisor;
247
248 omap3isp_put(isp);
249
250 return currentxclk;
251}
252
253/*
254 * isp_power_settings - Sysconfig settings, for Power Management.
255 * @isp: OMAP3 ISP device
256 * @idle: Consider idle state.
257 *
258 * Sets the power settings for the ISP, and SBL bus.
259 */
260static void isp_power_settings(struct isp_device *isp, int idle)
261{
262 isp_reg_writel(isp,
263 ((idle ? ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY :
264 ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY) <<
265 ISP_SYSCONFIG_MIDLEMODE_SHIFT) |
266 ((isp->revision == ISP_REVISION_15_0) ?
267 ISP_SYSCONFIG_AUTOIDLE : 0),
268 OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
269
270 if (isp->autoidle)
271 isp_reg_writel(isp, ISPCTRL_SBL_AUTOIDLE, OMAP3_ISP_IOMEM_MAIN,
272 ISP_CTRL);
273}
274
275/*
276 * Configure the bridge and lane shifter. Valid inputs are
277 *
278 * CCDC_INPUT_PARALLEL: Parallel interface
279 * CCDC_INPUT_CSI2A: CSI2a receiver
280 * CCDC_INPUT_CCP2B: CCP2b receiver
281 * CCDC_INPUT_CSI2C: CSI2c receiver
282 *
283 * The bridge and lane shifter are configured according to the selected input
284 * and the ISP platform data.
285 */
286void omap3isp_configure_bridge(struct isp_device *isp,
287 enum ccdc_input_entity input,
288 const struct isp_parallel_platform_data *pdata)
289{
290 u32 ispctrl_val;
291
292 ispctrl_val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
293 ispctrl_val &= ~ISPCTRL_SHIFT_MASK;
294 ispctrl_val &= ~ISPCTRL_PAR_CLK_POL_INV;
295 ispctrl_val &= ~ISPCTRL_PAR_SER_CLK_SEL_MASK;
296 ispctrl_val &= ~ISPCTRL_PAR_BRIDGE_MASK;
297
298 switch (input) {
299 case CCDC_INPUT_PARALLEL:
300 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
301 ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT;
302 ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
303 ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
304 break;
305
306 case CCDC_INPUT_CSI2A:
307 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIA;
308 break;
309
310 case CCDC_INPUT_CCP2B:
311 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIB;
312 break;
313
314 case CCDC_INPUT_CSI2C:
315 ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_CSIC;
316 break;
317
318 default:
319 return;
320 }
321
322 ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
323 ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
324
325 isp_reg_writel(isp, ispctrl_val, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL);
326}
327
328/**
329 * isp_set_pixel_clock - Configures the ISP pixel clock
330 * @isp: OMAP3 ISP device
331 * @pixelclk: Average pixel clock in Hz
332 *
333 * Set the average pixel clock required by the sensor. The ISP will use the
334 * lowest possible memory bandwidth settings compatible with the clock.
335 **/
336static void isp_set_pixel_clock(struct isp_device *isp, unsigned int pixelclk)
337{
338 isp->isp_ccdc.vpcfg.pixelclk = pixelclk;
339}
340
341void omap3isp_hist_dma_done(struct isp_device *isp)
342{
343 if (omap3isp_ccdc_busy(&isp->isp_ccdc) ||
344 omap3isp_stat_pcr_busy(&isp->isp_hist)) {
345 /* Histogram cannot be enabled in this frame anymore */
346 atomic_set(&isp->isp_hist.buf_err, 1);
347 dev_dbg(isp->dev, "hist: Out of synchronization with "
348 "CCDC. Ignoring next buffer.\n");
349 }
350}
351
352static inline void isp_isr_dbg(struct isp_device *isp, u32 irqstatus)
353{
354 static const char *name[] = {
355 "CSIA_IRQ",
356 "res1",
357 "res2",
358 "CSIB_LCM_IRQ",
359 "CSIB_IRQ",
360 "res5",
361 "res6",
362 "res7",
363 "CCDC_VD0_IRQ",
364 "CCDC_VD1_IRQ",
365 "CCDC_VD2_IRQ",
366 "CCDC_ERR_IRQ",
367 "H3A_AF_DONE_IRQ",
368 "H3A_AWB_DONE_IRQ",
369 "res14",
370 "res15",
371 "HIST_DONE_IRQ",
372 "CCDC_LSC_DONE",
373 "CCDC_LSC_PREFETCH_COMPLETED",
374 "CCDC_LSC_PREFETCH_ERROR",
375 "PRV_DONE_IRQ",
376 "CBUFF_IRQ",
377 "res22",
378 "res23",
379 "RSZ_DONE_IRQ",
380 "OVF_IRQ",
381 "res26",
382 "res27",
383 "MMU_ERR_IRQ",
384 "OCP_ERR_IRQ",
385 "SEC_ERR_IRQ",
386 "HS_VS_IRQ",
387 };
388 int i;
389
390 dev_dbg(isp->dev, "");
391
392 for (i = 0; i < ARRAY_SIZE(name); i++) {
393 if ((1 << i) & irqstatus)
394 printk(KERN_CONT "%s ", name[i]);
395 }
396 printk(KERN_CONT "\n");
397}
398
399static void isp_isr_sbl(struct isp_device *isp)
400{
401 struct device *dev = isp->dev;
402 u32 sbl_pcr;
403
404 /*
405 * Handle shared buffer logic overflows for video buffers.
406 * ISPSBL_PCR_CCDCPRV_2_RSZ_OVF can be safely ignored.
407 */
408 sbl_pcr = isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
409 isp_reg_writel(isp, sbl_pcr, OMAP3_ISP_IOMEM_SBL, ISPSBL_PCR);
410 sbl_pcr &= ~ISPSBL_PCR_CCDCPRV_2_RSZ_OVF;
411
412 if (sbl_pcr)
413 dev_dbg(dev, "SBL overflow (PCR = 0x%08x)\n", sbl_pcr);
414
415 if (sbl_pcr & (ISPSBL_PCR_CCDC_WBL_OVF | ISPSBL_PCR_CSIA_WBL_OVF
416 | ISPSBL_PCR_CSIB_WBL_OVF)) {
417 isp->isp_ccdc.error = 1;
418 if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
419 isp->isp_prev.error = 1;
420 if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
421 isp->isp_res.error = 1;
422 }
423
424 if (sbl_pcr & ISPSBL_PCR_PRV_WBL_OVF) {
425 isp->isp_prev.error = 1;
426 if (isp->isp_res.input == RESIZER_INPUT_VP &&
427 !(isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER))
428 isp->isp_res.error = 1;
429 }
430
431 if (sbl_pcr & (ISPSBL_PCR_RSZ1_WBL_OVF
432 | ISPSBL_PCR_RSZ2_WBL_OVF
433 | ISPSBL_PCR_RSZ3_WBL_OVF
434 | ISPSBL_PCR_RSZ4_WBL_OVF))
435 isp->isp_res.error = 1;
436
437 if (sbl_pcr & ISPSBL_PCR_H3A_AF_WBL_OVF)
438 omap3isp_stat_sbl_overflow(&isp->isp_af);
439
440 if (sbl_pcr & ISPSBL_PCR_H3A_AEAWB_WBL_OVF)
441 omap3isp_stat_sbl_overflow(&isp->isp_aewb);
442}
443
444/*
445 * isp_isr - Interrupt Service Routine for Camera ISP module.
446 * @irq: Not used currently.
447 * @_isp: Pointer to the OMAP3 ISP device
448 *
449 * Handles the corresponding callback if plugged in.
450 *
451 * Returns IRQ_HANDLED when IRQ was correctly handled, or IRQ_NONE when the
452 * IRQ wasn't handled.
453 */
454static irqreturn_t isp_isr(int irq, void *_isp)
455{
456 static const u32 ccdc_events = IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ |
457 IRQ0STATUS_CCDC_LSC_DONE_IRQ |
458 IRQ0STATUS_CCDC_VD0_IRQ |
459 IRQ0STATUS_CCDC_VD1_IRQ |
460 IRQ0STATUS_HS_VS_IRQ;
461 struct isp_device *isp = _isp;
462 u32 irqstatus;
463 int ret;
464
465 irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
466 isp_reg_writel(isp, irqstatus, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
467
468 isp_isr_sbl(isp);
469
470 if (irqstatus & IRQ0STATUS_CSIA_IRQ) {
471 ret = omap3isp_csi2_isr(&isp->isp_csi2a);
472 if (ret)
473 isp->isp_ccdc.error = 1;
474 }
475
476 if (irqstatus & IRQ0STATUS_CSIB_IRQ) {
477 ret = omap3isp_ccp2_isr(&isp->isp_ccp2);
478 if (ret)
479 isp->isp_ccdc.error = 1;
480 }
481
482 if (irqstatus & IRQ0STATUS_CCDC_VD0_IRQ) {
483 if (isp->isp_ccdc.output & CCDC_OUTPUT_PREVIEW)
484 omap3isp_preview_isr_frame_sync(&isp->isp_prev);
485 if (isp->isp_ccdc.output & CCDC_OUTPUT_RESIZER)
486 omap3isp_resizer_isr_frame_sync(&isp->isp_res);
487 omap3isp_stat_isr_frame_sync(&isp->isp_aewb);
488 omap3isp_stat_isr_frame_sync(&isp->isp_af);
489 omap3isp_stat_isr_frame_sync(&isp->isp_hist);
490 }
491
492 if (irqstatus & ccdc_events)
493 omap3isp_ccdc_isr(&isp->isp_ccdc, irqstatus & ccdc_events);
494
495 if (irqstatus & IRQ0STATUS_PRV_DONE_IRQ) {
496 if (isp->isp_prev.output & PREVIEW_OUTPUT_RESIZER)
497 omap3isp_resizer_isr_frame_sync(&isp->isp_res);
498 omap3isp_preview_isr(&isp->isp_prev);
499 }
500
501 if (irqstatus & IRQ0STATUS_RSZ_DONE_IRQ)
502 omap3isp_resizer_isr(&isp->isp_res);
503
504 if (irqstatus & IRQ0STATUS_H3A_AWB_DONE_IRQ)
505 omap3isp_stat_isr(&isp->isp_aewb);
506
507 if (irqstatus & IRQ0STATUS_H3A_AF_DONE_IRQ)
508 omap3isp_stat_isr(&isp->isp_af);
509
510 if (irqstatus & IRQ0STATUS_HIST_DONE_IRQ)
511 omap3isp_stat_isr(&isp->isp_hist);
512
513 omap3isp_flush(isp);
514
515#if defined(DEBUG) && defined(ISP_ISR_DEBUG)
516 isp_isr_dbg(isp, irqstatus);
517#endif
518
519 return IRQ_HANDLED;
520}
521
522/* -----------------------------------------------------------------------------
523 * Pipeline power management
524 *
525 * Entities must be powered up when part of a pipeline that contains at least
526 * one open video device node.
527 *
528 * To achieve this use the entity use_count field to track the number of users.
529 * For entities corresponding to video device nodes the use_count field stores
530 * the users count of the node. For entities corresponding to subdevs the
531 * use_count field stores the total number of users of all video device nodes
532 * in the pipeline.
533 *
534 * The omap3isp_pipeline_pm_use() function must be called in the open() and
535 * close() handlers of video device nodes. It increments or decrements the use
536 * count of all subdev entities in the pipeline.
537 *
538 * To react to link management on powered pipelines, the link setup notification
539 * callback updates the use count of all entities in the source and sink sides
540 * of the link.
541 */
542
543/*
544 * isp_pipeline_pm_use_count - Count the number of users of a pipeline
545 * @entity: The entity
546 *
547 * Return the total number of users of all video device nodes in the pipeline.
548 */
549static int isp_pipeline_pm_use_count(struct media_entity *entity)
550{
551 struct media_entity_graph graph;
552 int use = 0;
553
554 media_entity_graph_walk_start(&graph, entity);
555
556 while ((entity = media_entity_graph_walk_next(&graph))) {
557 if (media_entity_type(entity) == MEDIA_ENT_T_DEVNODE)
558 use += entity->use_count;
559 }
560
561 return use;
562}
563
564/*
565 * isp_pipeline_pm_power_one - Apply power change to an entity
566 * @entity: The entity
567 * @change: Use count change
568 *
569 * Change the entity use count by @change. If the entity is a subdev update its
570 * power state by calling the core::s_power operation when the use count goes
571 * from 0 to != 0 or from != 0 to 0.
572 *
573 * Return 0 on success or a negative error code on failure.
574 */
575static int isp_pipeline_pm_power_one(struct media_entity *entity, int change)
576{
577 struct v4l2_subdev *subdev;
578 int ret;
579
580 subdev = media_entity_type(entity) == MEDIA_ENT_T_V4L2_SUBDEV
581 ? media_entity_to_v4l2_subdev(entity) : NULL;
582
583 if (entity->use_count == 0 && change > 0 && subdev != NULL) {
584 ret = v4l2_subdev_call(subdev, core, s_power, 1);
585 if (ret < 0 && ret != -ENOIOCTLCMD)
586 return ret;
587 }
588
589 entity->use_count += change;
590 WARN_ON(entity->use_count < 0);
591
592 if (entity->use_count == 0 && change < 0 && subdev != NULL)
593 v4l2_subdev_call(subdev, core, s_power, 0);
594
595 return 0;
596}
597
598/*
599 * isp_pipeline_pm_power - Apply power change to all entities in a pipeline
600 * @entity: The entity
601 * @change: Use count change
602 *
603 * Walk the pipeline to update the use count and the power state of all non-node
604 * entities.
605 *
606 * Return 0 on success or a negative error code on failure.
607 */
608static int isp_pipeline_pm_power(struct media_entity *entity, int change)
609{
610 struct media_entity_graph graph;
611 struct media_entity *first = entity;
612 int ret = 0;
613
614 if (!change)
615 return 0;
616
617 media_entity_graph_walk_start(&graph, entity);
618
619 while (!ret && (entity = media_entity_graph_walk_next(&graph)))
620 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
621 ret = isp_pipeline_pm_power_one(entity, change);
622
623 if (!ret)
624 return 0;
625
626 media_entity_graph_walk_start(&graph, first);
627
628 while ((first = media_entity_graph_walk_next(&graph))
629 && first != entity)
630 if (media_entity_type(first) != MEDIA_ENT_T_DEVNODE)
631 isp_pipeline_pm_power_one(first, -change);
632
633 return ret;
634}
635
636/*
637 * omap3isp_pipeline_pm_use - Update the use count of an entity
638 * @entity: The entity
639 * @use: Use (1) or stop using (0) the entity
640 *
641 * Update the use count of all entities in the pipeline and power entities on or
642 * off accordingly.
643 *
644 * Return 0 on success or a negative error code on failure. Powering entities
645 * off is assumed to never fail. No failure can occur when the use parameter is
646 * set to 0.
647 */
648int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
649{
650 int change = use ? 1 : -1;
651 int ret;
652
653 mutex_lock(&entity->parent->graph_mutex);
654
655 /* Apply use count to node. */
656 entity->use_count += change;
657 WARN_ON(entity->use_count < 0);
658
659 /* Apply power change to connected non-nodes. */
660 ret = isp_pipeline_pm_power(entity, change);
661
662 mutex_unlock(&entity->parent->graph_mutex);
663
664 return ret;
665}
666
667/*
668 * isp_pipeline_link_notify - Link management notification callback
669 * @source: Pad at the start of the link
670 * @sink: Pad at the end of the link
671 * @flags: New link flags that will be applied
672 *
673 * React to link management on powered pipelines by updating the use count of
674 * all entities in the source and sink sides of the link. Entities are powered
675 * on or off accordingly.
676 *
677 * Return 0 on success or a negative error code on failure. Powering entities
678 * off is assumed to never fail. This function will not fail for disconnection
679 * events.
680 */
681static int isp_pipeline_link_notify(struct media_pad *source,
682 struct media_pad *sink, u32 flags)
683{
684 int source_use = isp_pipeline_pm_use_count(source->entity);
685 int sink_use = isp_pipeline_pm_use_count(sink->entity);
686 int ret;
687
688 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
689 /* Powering off entities is assumed to never fail. */
690 isp_pipeline_pm_power(source->entity, -sink_use);
691 isp_pipeline_pm_power(sink->entity, -source_use);
692 return 0;
693 }
694
695 ret = isp_pipeline_pm_power(source->entity, sink_use);
696 if (ret < 0)
697 return ret;
698
699 ret = isp_pipeline_pm_power(sink->entity, source_use);
700 if (ret < 0)
701 isp_pipeline_pm_power(source->entity, -sink_use);
702
703 return ret;
704}
705
706/* -----------------------------------------------------------------------------
707 * Pipeline stream management
708 */
709
710/*
711 * isp_pipeline_enable - Enable streaming on a pipeline
712 * @pipe: ISP pipeline
713 * @mode: Stream mode (single shot or continuous)
714 *
715 * Walk the entities chain starting at the pipeline output video node and start
716 * all modules in the chain in the given mode.
717 *
718 * Return 0 if successfull, or the return value of the failed video::s_stream
719 * operation otherwise.
720 */
721static int isp_pipeline_enable(struct isp_pipeline *pipe,
722 enum isp_pipeline_stream_state mode)
723{
724 struct isp_device *isp = pipe->output->isp;
725 struct media_entity *entity;
726 struct media_pad *pad;
727 struct v4l2_subdev *subdev;
728 unsigned long flags;
729 int ret = 0;
730
731 spin_lock_irqsave(&pipe->lock, flags);
732 pipe->state &= ~(ISP_PIPELINE_IDLE_INPUT | ISP_PIPELINE_IDLE_OUTPUT);
733 spin_unlock_irqrestore(&pipe->lock, flags);
734
735 pipe->do_propagation = false;
736
737 entity = &pipe->output->video.entity;
738 while (1) {
739 pad = &entity->pads[0];
740 if (!(pad->flags & MEDIA_PAD_FL_SINK))
741 break;
742
743 pad = media_entity_remote_source(pad);
744 if (pad == NULL ||
745 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
746 break;
747
748 entity = pad->entity;
749 subdev = media_entity_to_v4l2_subdev(entity);
750
751 ret = v4l2_subdev_call(subdev, video, s_stream, mode);
752 if (ret < 0 && ret != -ENOIOCTLCMD)
753 break;
754
755 if (subdev == &isp->isp_ccdc.subdev) {
756 v4l2_subdev_call(&isp->isp_aewb.subdev, video,
757 s_stream, mode);
758 v4l2_subdev_call(&isp->isp_af.subdev, video,
759 s_stream, mode);
760 v4l2_subdev_call(&isp->isp_hist.subdev, video,
761 s_stream, mode);
762 pipe->do_propagation = true;
763 }
764 }
765
766 /* Frame number propagation. In continuous streaming mode the number
767 * is incremented in the frame start ISR. In mem-to-mem mode
768 * singleshot is used and frame start IRQs are not available.
769 * Thus we have to increment the number here.
770 */
771 if (pipe->do_propagation && mode == ISP_PIPELINE_STREAM_SINGLESHOT)
772 atomic_inc(&pipe->frame_number);
773
774 return ret;
775}
776
777static int isp_pipeline_wait_resizer(struct isp_device *isp)
778{
779 return omap3isp_resizer_busy(&isp->isp_res);
780}
781
782static int isp_pipeline_wait_preview(struct isp_device *isp)
783{
784 return omap3isp_preview_busy(&isp->isp_prev);
785}
786
787static int isp_pipeline_wait_ccdc(struct isp_device *isp)
788{
789 return omap3isp_stat_busy(&isp->isp_af)
790 || omap3isp_stat_busy(&isp->isp_aewb)
791 || omap3isp_stat_busy(&isp->isp_hist)
792 || omap3isp_ccdc_busy(&isp->isp_ccdc);
793}
794
795#define ISP_STOP_TIMEOUT msecs_to_jiffies(1000)
796
797static int isp_pipeline_wait(struct isp_device *isp,
798 int(*busy)(struct isp_device *isp))
799{
800 unsigned long timeout = jiffies + ISP_STOP_TIMEOUT;
801
802 while (!time_after(jiffies, timeout)) {
803 if (!busy(isp))
804 return 0;
805 }
806
807 return 1;
808}
809
810/*
811 * isp_pipeline_disable - Disable streaming on a pipeline
812 * @pipe: ISP pipeline
813 *
814 * Walk the entities chain starting at the pipeline output video node and stop
815 * all modules in the chain. Wait synchronously for the modules to be stopped if
816 * necessary.
817 *
818 * Return 0 if all modules have been properly stopped, or -ETIMEDOUT if a module
819 * can't be stopped (in which case a software reset of the ISP is probably
820 * necessary).
821 */
822static int isp_pipeline_disable(struct isp_pipeline *pipe)
823{
824 struct isp_device *isp = pipe->output->isp;
825 struct media_entity *entity;
826 struct media_pad *pad;
827 struct v4l2_subdev *subdev;
828 int failure = 0;
829 int ret;
830
831 /*
832 * We need to stop all the modules after CCDC first or they'll
833 * never stop since they may not get a full frame from CCDC.
834 */
835 entity = &pipe->output->video.entity;
836 while (1) {
837 pad = &entity->pads[0];
838 if (!(pad->flags & MEDIA_PAD_FL_SINK))
839 break;
840
841 pad = media_entity_remote_source(pad);
842 if (pad == NULL ||
843 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
844 break;
845
846 entity = pad->entity;
847 subdev = media_entity_to_v4l2_subdev(entity);
848
849 if (subdev == &isp->isp_ccdc.subdev) {
850 v4l2_subdev_call(&isp->isp_aewb.subdev,
851 video, s_stream, 0);
852 v4l2_subdev_call(&isp->isp_af.subdev,
853 video, s_stream, 0);
854 v4l2_subdev_call(&isp->isp_hist.subdev,
855 video, s_stream, 0);
856 }
857
858 v4l2_subdev_call(subdev, video, s_stream, 0);
859
860 if (subdev == &isp->isp_res.subdev)
861 ret = isp_pipeline_wait(isp, isp_pipeline_wait_resizer);
862 else if (subdev == &isp->isp_prev.subdev)
863 ret = isp_pipeline_wait(isp, isp_pipeline_wait_preview);
864 else if (subdev == &isp->isp_ccdc.subdev)
865 ret = isp_pipeline_wait(isp, isp_pipeline_wait_ccdc);
866 else
867 ret = 0;
868
869 if (ret) {
870 dev_info(isp->dev, "Unable to stop %s\n", subdev->name);
871 failure = -ETIMEDOUT;
872 }
873 }
874
875 return failure;
876}
877
878/*
879 * omap3isp_pipeline_set_stream - Enable/disable streaming on a pipeline
880 * @pipe: ISP pipeline
881 * @state: Stream state (stopped, single shot or continuous)
882 *
883 * Set the pipeline to the given stream state. Pipelines can be started in
884 * single-shot or continuous mode.
885 *
886 * Return 0 if successfull, or the return value of the failed video::s_stream
887 * operation otherwise.
888 */
889int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
890 enum isp_pipeline_stream_state state)
891{
892 int ret;
893
894 if (state == ISP_PIPELINE_STREAM_STOPPED)
895 ret = isp_pipeline_disable(pipe);
896 else
897 ret = isp_pipeline_enable(pipe, state);
898 pipe->stream_state = state;
899
900 return ret;
901}
902
903/*
904 * isp_pipeline_resume - Resume streaming on a pipeline
905 * @pipe: ISP pipeline
906 *
907 * Resume video output and input and re-enable pipeline.
908 */
909static void isp_pipeline_resume(struct isp_pipeline *pipe)
910{
911 int singleshot = pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT;
912
913 omap3isp_video_resume(pipe->output, !singleshot);
914 if (singleshot)
915 omap3isp_video_resume(pipe->input, 0);
916 isp_pipeline_enable(pipe, pipe->stream_state);
917}
918
919/*
920 * isp_pipeline_suspend - Suspend streaming on a pipeline
921 * @pipe: ISP pipeline
922 *
923 * Suspend pipeline.
924 */
925static void isp_pipeline_suspend(struct isp_pipeline *pipe)
926{
927 isp_pipeline_disable(pipe);
928}
929
930/*
931 * isp_pipeline_is_last - Verify if entity has an enabled link to the output
932 * video node
933 * @me: ISP module's media entity
934 *
935 * Returns 1 if the entity has an enabled link to the output video node or 0
936 * otherwise. It's true only while pipeline can have no more than one output
937 * node.
938 */
939static int isp_pipeline_is_last(struct media_entity *me)
940{
941 struct isp_pipeline *pipe;
942 struct media_pad *pad;
943
944 if (!me->pipe)
945 return 0;
946 pipe = to_isp_pipeline(me);
947 if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED)
948 return 0;
949 pad = media_entity_remote_source(&pipe->output->pad);
950 return pad->entity == me;
951}
952
953/*
954 * isp_suspend_module_pipeline - Suspend pipeline to which belongs the module
955 * @me: ISP module's media entity
956 *
957 * Suspend the whole pipeline if module's entity has an enabled link to the
958 * output video node. It works only while pipeline can have no more than one
959 * output node.
960 */
961static void isp_suspend_module_pipeline(struct media_entity *me)
962{
963 if (isp_pipeline_is_last(me))
964 isp_pipeline_suspend(to_isp_pipeline(me));
965}
966
967/*
968 * isp_resume_module_pipeline - Resume pipeline to which belongs the module
969 * @me: ISP module's media entity
970 *
971 * Resume the whole pipeline if module's entity has an enabled link to the
972 * output video node. It works only while pipeline can have no more than one
973 * output node.
974 */
975static void isp_resume_module_pipeline(struct media_entity *me)
976{
977 if (isp_pipeline_is_last(me))
978 isp_pipeline_resume(to_isp_pipeline(me));
979}
980
981/*
982 * isp_suspend_modules - Suspend ISP submodules.
983 * @isp: OMAP3 ISP device
984 *
985 * Returns 0 if suspend left in idle state all the submodules properly,
986 * or returns 1 if a general Reset is required to suspend the submodules.
987 */
988static int isp_suspend_modules(struct isp_device *isp)
989{
990 unsigned long timeout;
991
992 omap3isp_stat_suspend(&isp->isp_aewb);
993 omap3isp_stat_suspend(&isp->isp_af);
994 omap3isp_stat_suspend(&isp->isp_hist);
995 isp_suspend_module_pipeline(&isp->isp_res.subdev.entity);
996 isp_suspend_module_pipeline(&isp->isp_prev.subdev.entity);
997 isp_suspend_module_pipeline(&isp->isp_ccdc.subdev.entity);
998 isp_suspend_module_pipeline(&isp->isp_csi2a.subdev.entity);
999 isp_suspend_module_pipeline(&isp->isp_ccp2.subdev.entity);
1000
1001 timeout = jiffies + ISP_STOP_TIMEOUT;
1002 while (omap3isp_stat_busy(&isp->isp_af)
1003 || omap3isp_stat_busy(&isp->isp_aewb)
1004 || omap3isp_stat_busy(&isp->isp_hist)
1005 || omap3isp_preview_busy(&isp->isp_prev)
1006 || omap3isp_resizer_busy(&isp->isp_res)
1007 || omap3isp_ccdc_busy(&isp->isp_ccdc)) {
1008 if (time_after(jiffies, timeout)) {
1009 dev_info(isp->dev, "can't stop modules.\n");
1010 return 1;
1011 }
1012 msleep(1);
1013 }
1014
1015 return 0;
1016}
1017
1018/*
1019 * isp_resume_modules - Resume ISP submodules.
1020 * @isp: OMAP3 ISP device
1021 */
1022static void isp_resume_modules(struct isp_device *isp)
1023{
1024 omap3isp_stat_resume(&isp->isp_aewb);
1025 omap3isp_stat_resume(&isp->isp_af);
1026 omap3isp_stat_resume(&isp->isp_hist);
1027 isp_resume_module_pipeline(&isp->isp_res.subdev.entity);
1028 isp_resume_module_pipeline(&isp->isp_prev.subdev.entity);
1029 isp_resume_module_pipeline(&isp->isp_ccdc.subdev.entity);
1030 isp_resume_module_pipeline(&isp->isp_csi2a.subdev.entity);
1031 isp_resume_module_pipeline(&isp->isp_ccp2.subdev.entity);
1032}
1033
1034/*
1035 * isp_reset - Reset ISP with a timeout wait for idle.
1036 * @isp: OMAP3 ISP device
1037 */
1038static int isp_reset(struct isp_device *isp)
1039{
1040 unsigned long timeout = 0;
1041
1042 isp_reg_writel(isp,
1043 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG)
1044 | ISP_SYSCONFIG_SOFTRESET,
1045 OMAP3_ISP_IOMEM_MAIN, ISP_SYSCONFIG);
1046 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN,
1047 ISP_SYSSTATUS) & 0x1)) {
1048 if (timeout++ > 10000) {
1049 dev_alert(isp->dev, "cannot reset ISP\n");
1050 return -ETIMEDOUT;
1051 }
1052 udelay(1);
1053 }
1054
1055 return 0;
1056}
1057
1058/*
1059 * isp_save_context - Saves the values of the ISP module registers.
1060 * @isp: OMAP3 ISP device
1061 * @reg_list: Structure containing pairs of register address and value to
1062 * modify on OMAP.
1063 */
1064static void
1065isp_save_context(struct isp_device *isp, struct isp_reg *reg_list)
1066{
1067 struct isp_reg *next = reg_list;
1068
1069 for (; next->reg != ISP_TOK_TERM; next++)
1070 next->val = isp_reg_readl(isp, next->mmio_range, next->reg);
1071}
1072
1073/*
1074 * isp_restore_context - Restores the values of the ISP module registers.
1075 * @isp: OMAP3 ISP device
1076 * @reg_list: Structure containing pairs of register address and value to
1077 * modify on OMAP.
1078 */
1079static void
1080isp_restore_context(struct isp_device *isp, struct isp_reg *reg_list)
1081{
1082 struct isp_reg *next = reg_list;
1083
1084 for (; next->reg != ISP_TOK_TERM; next++)
1085 isp_reg_writel(isp, next->val, next->mmio_range, next->reg);
1086}
1087
1088/*
1089 * isp_save_ctx - Saves ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
1090 * @isp: OMAP3 ISP device
1091 *
1092 * Routine for saving the context of each module in the ISP.
1093 * CCDC, HIST, H3A, PREV, RESZ and MMU.
1094 */
1095static void isp_save_ctx(struct isp_device *isp)
1096{
1097 isp_save_context(isp, isp_reg_list);
1098 if (isp->iommu)
1099 iommu_save_ctx(isp->iommu);
1100}
1101
1102/*
1103 * isp_restore_ctx - Restores ISP, CCDC, HIST, H3A, PREV, RESZ & MMU context.
1104 * @isp: OMAP3 ISP device
1105 *
1106 * Routine for restoring the context of each module in the ISP.
1107 * CCDC, HIST, H3A, PREV, RESZ and MMU.
1108 */
1109static void isp_restore_ctx(struct isp_device *isp)
1110{
1111 isp_restore_context(isp, isp_reg_list);
1112 if (isp->iommu)
1113 iommu_restore_ctx(isp->iommu);
1114 omap3isp_ccdc_restore_context(isp);
1115 omap3isp_preview_restore_context(isp);
1116}
1117
1118/* -----------------------------------------------------------------------------
1119 * SBL resources management
1120 */
1121#define OMAP3_ISP_SBL_READ (OMAP3_ISP_SBL_CSI1_READ | \
1122 OMAP3_ISP_SBL_CCDC_LSC_READ | \
1123 OMAP3_ISP_SBL_PREVIEW_READ | \
1124 OMAP3_ISP_SBL_RESIZER_READ)
1125#define OMAP3_ISP_SBL_WRITE (OMAP3_ISP_SBL_CSI1_WRITE | \
1126 OMAP3_ISP_SBL_CSI2A_WRITE | \
1127 OMAP3_ISP_SBL_CSI2C_WRITE | \
1128 OMAP3_ISP_SBL_CCDC_WRITE | \
1129 OMAP3_ISP_SBL_PREVIEW_WRITE)
1130
1131void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res)
1132{
1133 u32 sbl = 0;
1134
1135 isp->sbl_resources |= res;
1136
1137 if (isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ)
1138 sbl |= ISPCTRL_SBL_SHARED_RPORTA;
1139
1140 if (isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ)
1141 sbl |= ISPCTRL_SBL_SHARED_RPORTB;
1142
1143 if (isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE)
1144 sbl |= ISPCTRL_SBL_SHARED_WPORTC;
1145
1146 if (isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE)
1147 sbl |= ISPCTRL_SBL_WR0_RAM_EN;
1148
1149 if (isp->sbl_resources & OMAP3_ISP_SBL_WRITE)
1150 sbl |= ISPCTRL_SBL_WR1_RAM_EN;
1151
1152 if (isp->sbl_resources & OMAP3_ISP_SBL_READ)
1153 sbl |= ISPCTRL_SBL_RD_RAM_EN;
1154
1155 isp_reg_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
1156}
1157
1158void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res)
1159{
1160 u32 sbl = 0;
1161
1162 isp->sbl_resources &= ~res;
1163
1164 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI1_READ))
1165 sbl |= ISPCTRL_SBL_SHARED_RPORTA;
1166
1167 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CCDC_LSC_READ))
1168 sbl |= ISPCTRL_SBL_SHARED_RPORTB;
1169
1170 if (!(isp->sbl_resources & OMAP3_ISP_SBL_CSI2C_WRITE))
1171 sbl |= ISPCTRL_SBL_SHARED_WPORTC;
1172
1173 if (!(isp->sbl_resources & OMAP3_ISP_SBL_RESIZER_WRITE))
1174 sbl |= ISPCTRL_SBL_WR0_RAM_EN;
1175
1176 if (!(isp->sbl_resources & OMAP3_ISP_SBL_WRITE))
1177 sbl |= ISPCTRL_SBL_WR1_RAM_EN;
1178
1179 if (!(isp->sbl_resources & OMAP3_ISP_SBL_READ))
1180 sbl |= ISPCTRL_SBL_RD_RAM_EN;
1181
1182 isp_reg_clr(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL, sbl);
1183}
1184
1185/*
1186 * isp_module_sync_idle - Helper to sync module with its idle state
1187 * @me: ISP submodule's media entity
1188 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
1189 * @stopping: flag which tells module wants to stop
1190 *
1191 * This function checks if ISP submodule needs to wait for next interrupt. If
1192 * yes, makes the caller to sleep while waiting for such event.
1193 */
1194int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
1195 atomic_t *stopping)
1196{
1197 struct isp_pipeline *pipe = to_isp_pipeline(me);
1198
1199 if (pipe->stream_state == ISP_PIPELINE_STREAM_STOPPED ||
1200 (pipe->stream_state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1201 !isp_pipeline_ready(pipe)))
1202 return 0;
1203
1204 /*
1205 * atomic_set() doesn't include memory barrier on ARM platform for SMP
1206 * scenario. We'll call it here to avoid race conditions.
1207 */
1208 atomic_set(stopping, 1);
1209 smp_mb();
1210
1211 /*
1212 * If module is the last one, it's writing to memory. In this case,
1213 * it's necessary to check if the module is already paused due to
1214 * DMA queue underrun or if it has to wait for next interrupt to be
1215 * idle.
1216 * If it isn't the last one, the function won't sleep but *stopping
1217 * will still be set to warn next submodule caller's interrupt the
1218 * module wants to be idle.
1219 */
1220 if (isp_pipeline_is_last(me)) {
1221 struct isp_video *video = pipe->output;
1222 unsigned long flags;
1223 spin_lock_irqsave(&video->queue->irqlock, flags);
1224 if (video->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
1225 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1226 atomic_set(stopping, 0);
1227 smp_mb();
1228 return 0;
1229 }
1230 spin_unlock_irqrestore(&video->queue->irqlock, flags);
1231 if (!wait_event_timeout(*wait, !atomic_read(stopping),
1232 msecs_to_jiffies(1000))) {
1233 atomic_set(stopping, 0);
1234 smp_mb();
1235 return -ETIMEDOUT;
1236 }
1237 }
1238
1239 return 0;
1240}
1241
1242/*
1243 * omap3isp_module_sync_is_stopped - Helper to verify if module was stopping
1244 * @wait: ISP submodule's wait queue for streamoff/interrupt synchronization
1245 * @stopping: flag which tells module wants to stop
1246 *
1247 * This function checks if ISP submodule was stopping. In case of yes, it
1248 * notices the caller by setting stopping to 0 and waking up the wait queue.
1249 * Returns 1 if it was stopping or 0 otherwise.
1250 */
1251int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
1252 atomic_t *stopping)
1253{
1254 if (atomic_cmpxchg(stopping, 1, 0)) {
1255 wake_up(wait);
1256 return 1;
1257 }
1258
1259 return 0;
1260}
1261
1262/* --------------------------------------------------------------------------
1263 * Clock management
1264 */
1265
1266#define ISPCTRL_CLKS_MASK (ISPCTRL_H3A_CLK_EN | \
1267 ISPCTRL_HIST_CLK_EN | \
1268 ISPCTRL_RSZ_CLK_EN | \
1269 (ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN) | \
1270 (ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN))
1271
1272static void __isp_subclk_update(struct isp_device *isp)
1273{
1274 u32 clk = 0;
1275
1276 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_H3A)
1277 clk |= ISPCTRL_H3A_CLK_EN;
1278
1279 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_HIST)
1280 clk |= ISPCTRL_HIST_CLK_EN;
1281
1282 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_RESIZER)
1283 clk |= ISPCTRL_RSZ_CLK_EN;
1284
1285 /* NOTE: For CCDC & Preview submodules, we need to affect internal
1286 * RAM aswell.
1287 */
1288 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_CCDC)
1289 clk |= ISPCTRL_CCDC_CLK_EN | ISPCTRL_CCDC_RAM_EN;
1290
1291 if (isp->subclk_resources & OMAP3_ISP_SUBCLK_PREVIEW)
1292 clk |= ISPCTRL_PREV_CLK_EN | ISPCTRL_PREV_RAM_EN;
1293
1294 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
1295 ISPCTRL_CLKS_MASK, clk);
1296}
1297
1298void omap3isp_subclk_enable(struct isp_device *isp,
1299 enum isp_subclk_resource res)
1300{
1301 isp->subclk_resources |= res;
1302
1303 __isp_subclk_update(isp);
1304}
1305
1306void omap3isp_subclk_disable(struct isp_device *isp,
1307 enum isp_subclk_resource res)
1308{
1309 isp->subclk_resources &= ~res;
1310
1311 __isp_subclk_update(isp);
1312}
1313
1314/*
1315 * isp_enable_clocks - Enable ISP clocks
1316 * @isp: OMAP3 ISP device
1317 *
1318 * Return 0 if successful, or clk_enable return value if any of tthem fails.
1319 */
1320static int isp_enable_clocks(struct isp_device *isp)
1321{
1322 int r;
1323 unsigned long rate;
1324 int divisor;
1325
1326 /*
1327 * cam_mclk clock chain:
1328 * dpll4 -> dpll4_m5 -> dpll4_m5x2 -> cam_mclk
1329 *
1330 * In OMAP3630 dpll4_m5x2 != 2 x dpll4_m5 but both are
1331 * set to the same value. Hence the rate set for dpll4_m5
1332 * has to be twice of what is set on OMAP3430 to get
1333 * the required value for cam_mclk
1334 */
1335 if (cpu_is_omap3630())
1336 divisor = 1;
1337 else
1338 divisor = 2;
1339
1340 r = clk_enable(isp->clock[ISP_CLK_CAM_ICK]);
1341 if (r) {
1342 dev_err(isp->dev, "clk_enable cam_ick failed\n");
1343 goto out_clk_enable_ick;
1344 }
1345 r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK],
1346 CM_CAM_MCLK_HZ/divisor);
1347 if (r) {
1348 dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n");
1349 goto out_clk_enable_mclk;
1350 }
1351 r = clk_enable(isp->clock[ISP_CLK_CAM_MCLK]);
1352 if (r) {
1353 dev_err(isp->dev, "clk_enable cam_mclk failed\n");
1354 goto out_clk_enable_mclk;
1355 }
1356 rate = clk_get_rate(isp->clock[ISP_CLK_CAM_MCLK]);
1357 if (rate != CM_CAM_MCLK_HZ)
1358 dev_warn(isp->dev, "unexpected cam_mclk rate:\n"
1359 " expected : %d\n"
1360 " actual : %ld\n", CM_CAM_MCLK_HZ, rate);
1361 r = clk_enable(isp->clock[ISP_CLK_CSI2_FCK]);
1362 if (r) {
1363 dev_err(isp->dev, "clk_enable csi2_fck failed\n");
1364 goto out_clk_enable_csi2_fclk;
1365 }
1366 return 0;
1367
1368out_clk_enable_csi2_fclk:
1369 clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
1370out_clk_enable_mclk:
1371 clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
1372out_clk_enable_ick:
1373 return r;
1374}
1375
1376/*
1377 * isp_disable_clocks - Disable ISP clocks
1378 * @isp: OMAP3 ISP device
1379 */
1380static void isp_disable_clocks(struct isp_device *isp)
1381{
1382 clk_disable(isp->clock[ISP_CLK_CAM_ICK]);
1383 clk_disable(isp->clock[ISP_CLK_CAM_MCLK]);
1384 clk_disable(isp->clock[ISP_CLK_CSI2_FCK]);
1385}
1386
1387static const char *isp_clocks[] = {
1388 "cam_ick",
1389 "cam_mclk",
1390 "dpll4_m5_ck",
1391 "csi2_96m_fck",
1392 "l3_ick",
1393};
1394
1395static void isp_put_clocks(struct isp_device *isp)
1396{
1397 unsigned int i;
1398
1399 for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
1400 if (isp->clock[i]) {
1401 clk_put(isp->clock[i]);
1402 isp->clock[i] = NULL;
1403 }
1404 }
1405}
1406
1407static int isp_get_clocks(struct isp_device *isp)
1408{
1409 struct clk *clk;
1410 unsigned int i;
1411
1412 for (i = 0; i < ARRAY_SIZE(isp_clocks); ++i) {
1413 clk = clk_get(isp->dev, isp_clocks[i]);
1414 if (IS_ERR(clk)) {
1415 dev_err(isp->dev, "clk_get %s failed\n", isp_clocks[i]);
1416 isp_put_clocks(isp);
1417 return PTR_ERR(clk);
1418 }
1419
1420 isp->clock[i] = clk;
1421 }
1422
1423 return 0;
1424}
1425
1426/*
1427 * omap3isp_get - Acquire the ISP resource.
1428 *
1429 * Initializes the clocks for the first acquire.
1430 *
1431 * Increment the reference count on the ISP. If the first reference is taken,
1432 * enable clocks and power-up all submodules.
1433 *
1434 * Return a pointer to the ISP device structure, or NULL if an error occured.
1435 */
1436struct isp_device *omap3isp_get(struct isp_device *isp)
1437{
1438 struct isp_device *__isp = isp;
1439
1440 if (isp == NULL)
1441 return NULL;
1442
1443 mutex_lock(&isp->isp_mutex);
1444 if (isp->ref_count > 0)
1445 goto out;
1446
1447 if (isp_enable_clocks(isp) < 0) {
1448 __isp = NULL;
1449 goto out;
1450 }
1451
1452 /* We don't want to restore context before saving it! */
1453 if (isp->has_context)
1454 isp_restore_ctx(isp);
1455 else
1456 isp->has_context = 1;
1457
1458 isp_enable_interrupts(isp);
1459
1460out:
1461 if (__isp != NULL)
1462 isp->ref_count++;
1463 mutex_unlock(&isp->isp_mutex);
1464
1465 return __isp;
1466}
1467
1468/*
1469 * omap3isp_put - Release the ISP
1470 *
1471 * Decrement the reference count on the ISP. If the last reference is released,
1472 * power-down all submodules, disable clocks and free temporary buffers.
1473 */
1474void omap3isp_put(struct isp_device *isp)
1475{
1476 if (isp == NULL)
1477 return;
1478
1479 mutex_lock(&isp->isp_mutex);
1480 BUG_ON(isp->ref_count == 0);
1481 if (--isp->ref_count == 0) {
1482 isp_disable_interrupts(isp);
1483 isp_save_ctx(isp);
1484 isp_disable_clocks(isp);
1485 }
1486 mutex_unlock(&isp->isp_mutex);
1487}
1488
1489/* --------------------------------------------------------------------------
1490 * Platform device driver
1491 */
1492
1493/*
1494 * omap3isp_print_status - Prints the values of the ISP Control Module registers
1495 * @isp: OMAP3 ISP device
1496 */
1497#define ISP_PRINT_REGISTER(isp, name)\
1498 dev_dbg(isp->dev, "###ISP " #name "=0x%08x\n", \
1499 isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_##name))
1500#define SBL_PRINT_REGISTER(isp, name)\
1501 dev_dbg(isp->dev, "###SBL " #name "=0x%08x\n", \
1502 isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_##name))
1503
1504void omap3isp_print_status(struct isp_device *isp)
1505{
1506 dev_dbg(isp->dev, "-------------ISP Register dump--------------\n");
1507
1508 ISP_PRINT_REGISTER(isp, SYSCONFIG);
1509 ISP_PRINT_REGISTER(isp, SYSSTATUS);
1510 ISP_PRINT_REGISTER(isp, IRQ0ENABLE);
1511 ISP_PRINT_REGISTER(isp, IRQ0STATUS);
1512 ISP_PRINT_REGISTER(isp, TCTRL_GRESET_LENGTH);
1513 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_REPLAY);
1514 ISP_PRINT_REGISTER(isp, CTRL);
1515 ISP_PRINT_REGISTER(isp, TCTRL_CTRL);
1516 ISP_PRINT_REGISTER(isp, TCTRL_FRAME);
1517 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_DELAY);
1518 ISP_PRINT_REGISTER(isp, TCTRL_STRB_DELAY);
1519 ISP_PRINT_REGISTER(isp, TCTRL_SHUT_DELAY);
1520 ISP_PRINT_REGISTER(isp, TCTRL_PSTRB_LENGTH);
1521 ISP_PRINT_REGISTER(isp, TCTRL_STRB_LENGTH);
1522 ISP_PRINT_REGISTER(isp, TCTRL_SHUT_LENGTH);
1523
1524 SBL_PRINT_REGISTER(isp, PCR);
1525 SBL_PRINT_REGISTER(isp, SDR_REQ_EXP);
1526
1527 dev_dbg(isp->dev, "--------------------------------------------\n");
1528}
1529
1530#ifdef CONFIG_PM
1531
1532/*
1533 * Power management support.
1534 *
1535 * As the ISP can't properly handle an input video stream interruption on a non
1536 * frame boundary, the ISP pipelines need to be stopped before sensors get
1537 * suspended. However, as suspending the sensors can require a running clock,
1538 * which can be provided by the ISP, the ISP can't be completely suspended
1539 * before the sensor.
1540 *
1541 * To solve this problem power management support is split into prepare/complete
1542 * and suspend/resume operations. The pipelines are stopped in prepare() and the
1543 * ISP clocks get disabled in suspend(). Similarly, the clocks are reenabled in
1544 * resume(), and the the pipelines are restarted in complete().
1545 *
1546 * TODO: PM dependencies between the ISP and sensors are not modeled explicitly
1547 * yet.
1548 */
1549static int isp_pm_prepare(struct device *dev)
1550{
1551 struct isp_device *isp = dev_get_drvdata(dev);
1552 int reset;
1553
1554 WARN_ON(mutex_is_locked(&isp->isp_mutex));
1555
1556 if (isp->ref_count == 0)
1557 return 0;
1558
1559 reset = isp_suspend_modules(isp);
1560 isp_disable_interrupts(isp);
1561 isp_save_ctx(isp);
1562 if (reset)
1563 isp_reset(isp);
1564
1565 return 0;
1566}
1567
1568static int isp_pm_suspend(struct device *dev)
1569{
1570 struct isp_device *isp = dev_get_drvdata(dev);
1571
1572 WARN_ON(mutex_is_locked(&isp->isp_mutex));
1573
1574 if (isp->ref_count)
1575 isp_disable_clocks(isp);
1576
1577 return 0;
1578}
1579
1580static int isp_pm_resume(struct device *dev)
1581{
1582 struct isp_device *isp = dev_get_drvdata(dev);
1583
1584 if (isp->ref_count == 0)
1585 return 0;
1586
1587 return isp_enable_clocks(isp);
1588}
1589
1590static void isp_pm_complete(struct device *dev)
1591{
1592 struct isp_device *isp = dev_get_drvdata(dev);
1593
1594 if (isp->ref_count == 0)
1595 return;
1596
1597 isp_restore_ctx(isp);
1598 isp_enable_interrupts(isp);
1599 isp_resume_modules(isp);
1600}
1601
1602#else
1603
1604#define isp_pm_prepare NULL
1605#define isp_pm_suspend NULL
1606#define isp_pm_resume NULL
1607#define isp_pm_complete NULL
1608
1609#endif /* CONFIG_PM */
1610
1611static void isp_unregister_entities(struct isp_device *isp)
1612{
1613 omap3isp_csi2_unregister_entities(&isp->isp_csi2a);
1614 omap3isp_ccp2_unregister_entities(&isp->isp_ccp2);
1615 omap3isp_ccdc_unregister_entities(&isp->isp_ccdc);
1616 omap3isp_preview_unregister_entities(&isp->isp_prev);
1617 omap3isp_resizer_unregister_entities(&isp->isp_res);
1618 omap3isp_stat_unregister_entities(&isp->isp_aewb);
1619 omap3isp_stat_unregister_entities(&isp->isp_af);
1620 omap3isp_stat_unregister_entities(&isp->isp_hist);
1621
1622 v4l2_device_unregister(&isp->v4l2_dev);
1623 media_device_unregister(&isp->media_dev);
1624}
1625
1626/*
1627 * isp_register_subdev_group - Register a group of subdevices
1628 * @isp: OMAP3 ISP device
1629 * @board_info: I2C subdevs board information array
1630 *
1631 * Register all I2C subdevices in the board_info array. The array must be
1632 * terminated by a NULL entry, and the first entry must be the sensor.
1633 *
1634 * Return a pointer to the sensor media entity if it has been successfully
1635 * registered, or NULL otherwise.
1636 */
1637static struct v4l2_subdev *
1638isp_register_subdev_group(struct isp_device *isp,
1639 struct isp_subdev_i2c_board_info *board_info)
1640{
1641 struct v4l2_subdev *sensor = NULL;
1642 unsigned int first;
1643
1644 if (board_info->board_info == NULL)
1645 return NULL;
1646
1647 for (first = 1; board_info->board_info; ++board_info, first = 0) {
1648 struct v4l2_subdev *subdev;
1649 struct i2c_adapter *adapter;
1650
1651 adapter = i2c_get_adapter(board_info->i2c_adapter_id);
1652 if (adapter == NULL) {
1653 printk(KERN_ERR "%s: Unable to get I2C adapter %d for "
1654 "device %s\n", __func__,
1655 board_info->i2c_adapter_id,
1656 board_info->board_info->type);
1657 continue;
1658 }
1659
1660 subdev = v4l2_i2c_new_subdev_board(&isp->v4l2_dev, adapter,
1661 board_info->board_info, NULL);
1662 if (subdev == NULL) {
1663 printk(KERN_ERR "%s: Unable to register subdev %s\n",
1664 __func__, board_info->board_info->type);
1665 continue;
1666 }
1667
1668 if (first)
1669 sensor = subdev;
1670 }
1671
1672 return sensor;
1673}
1674
1675static int isp_register_entities(struct isp_device *isp)
1676{
1677 struct isp_platform_data *pdata = isp->pdata;
1678 struct isp_v4l2_subdevs_group *subdevs;
1679 int ret;
1680
1681 isp->media_dev.dev = isp->dev;
1682 strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
1683 sizeof(isp->media_dev.model));
1684 isp->media_dev.link_notify = isp_pipeline_link_notify;
1685 ret = media_device_register(&isp->media_dev);
1686 if (ret < 0) {
1687 printk(KERN_ERR "%s: Media device registration failed (%d)\n",
1688 __func__, ret);
1689 return ret;
1690 }
1691
1692 isp->v4l2_dev.mdev = &isp->media_dev;
1693 ret = v4l2_device_register(isp->dev, &isp->v4l2_dev);
1694 if (ret < 0) {
1695 printk(KERN_ERR "%s: V4L2 device registration failed (%d)\n",
1696 __func__, ret);
1697 goto done;
1698 }
1699
1700 /* Register internal entities */
1701 ret = omap3isp_ccp2_register_entities(&isp->isp_ccp2, &isp->v4l2_dev);
1702 if (ret < 0)
1703 goto done;
1704
1705 ret = omap3isp_csi2_register_entities(&isp->isp_csi2a, &isp->v4l2_dev);
1706 if (ret < 0)
1707 goto done;
1708
1709 ret = omap3isp_ccdc_register_entities(&isp->isp_ccdc, &isp->v4l2_dev);
1710 if (ret < 0)
1711 goto done;
1712
1713 ret = omap3isp_preview_register_entities(&isp->isp_prev,
1714 &isp->v4l2_dev);
1715 if (ret < 0)
1716 goto done;
1717
1718 ret = omap3isp_resizer_register_entities(&isp->isp_res, &isp->v4l2_dev);
1719 if (ret < 0)
1720 goto done;
1721
1722 ret = omap3isp_stat_register_entities(&isp->isp_aewb, &isp->v4l2_dev);
1723 if (ret < 0)
1724 goto done;
1725
1726 ret = omap3isp_stat_register_entities(&isp->isp_af, &isp->v4l2_dev);
1727 if (ret < 0)
1728 goto done;
1729
1730 ret = omap3isp_stat_register_entities(&isp->isp_hist, &isp->v4l2_dev);
1731 if (ret < 0)
1732 goto done;
1733
1734 /* Register external entities */
1735 for (subdevs = pdata->subdevs; subdevs->subdevs; ++subdevs) {
1736 struct v4l2_subdev *sensor;
1737 struct media_entity *input;
1738 unsigned int flags;
1739 unsigned int pad;
1740
1741 sensor = isp_register_subdev_group(isp, subdevs->subdevs);
1742 if (sensor == NULL)
1743 continue;
1744
1745 sensor->host_priv = subdevs;
1746
1747 /* Connect the sensor to the correct interface module. Parallel
1748 * sensors are connected directly to the CCDC, while serial
1749 * sensors are connected to the CSI2a, CCP2b or CSI2c receiver
1750 * through CSIPHY1 or CSIPHY2.
1751 */
1752 switch (subdevs->interface) {
1753 case ISP_INTERFACE_PARALLEL:
1754 input = &isp->isp_ccdc.subdev.entity;
1755 pad = CCDC_PAD_SINK;
1756 flags = 0;
1757 break;
1758
1759 case ISP_INTERFACE_CSI2A_PHY2:
1760 input = &isp->isp_csi2a.subdev.entity;
1761 pad = CSI2_PAD_SINK;
1762 flags = MEDIA_LNK_FL_IMMUTABLE
1763 | MEDIA_LNK_FL_ENABLED;
1764 break;
1765
1766 case ISP_INTERFACE_CCP2B_PHY1:
1767 case ISP_INTERFACE_CCP2B_PHY2:
1768 input = &isp->isp_ccp2.subdev.entity;
1769 pad = CCP2_PAD_SINK;
1770 flags = 0;
1771 break;
1772
1773 case ISP_INTERFACE_CSI2C_PHY1:
1774 input = &isp->isp_csi2c.subdev.entity;
1775 pad = CSI2_PAD_SINK;
1776 flags = MEDIA_LNK_FL_IMMUTABLE
1777 | MEDIA_LNK_FL_ENABLED;
1778 break;
1779
1780 default:
1781 printk(KERN_ERR "%s: invalid interface type %u\n",
1782 __func__, subdevs->interface);
1783 ret = -EINVAL;
1784 goto done;
1785 }
1786
1787 ret = media_entity_create_link(&sensor->entity, 0, input, pad,
1788 flags);
1789 if (ret < 0)
1790 goto done;
1791 }
1792
1793 ret = v4l2_device_register_subdev_nodes(&isp->v4l2_dev);
1794
1795done:
1796 if (ret < 0)
1797 isp_unregister_entities(isp);
1798
1799 return ret;
1800}
1801
1802static void isp_cleanup_modules(struct isp_device *isp)
1803{
1804 omap3isp_h3a_aewb_cleanup(isp);
1805 omap3isp_h3a_af_cleanup(isp);
1806 omap3isp_hist_cleanup(isp);
1807 omap3isp_resizer_cleanup(isp);
1808 omap3isp_preview_cleanup(isp);
1809 omap3isp_ccdc_cleanup(isp);
1810 omap3isp_ccp2_cleanup(isp);
1811 omap3isp_csi2_cleanup(isp);
1812}
1813
1814static int isp_initialize_modules(struct isp_device *isp)
1815{
1816 int ret;
1817
1818 ret = omap3isp_csiphy_init(isp);
1819 if (ret < 0) {
1820 dev_err(isp->dev, "CSI PHY initialization failed\n");
1821 goto error_csiphy;
1822 }
1823
1824 ret = omap3isp_csi2_init(isp);
1825 if (ret < 0) {
1826 dev_err(isp->dev, "CSI2 initialization failed\n");
1827 goto error_csi2;
1828 }
1829
1830 ret = omap3isp_ccp2_init(isp);
1831 if (ret < 0) {
1832 dev_err(isp->dev, "CCP2 initialization failed\n");
1833 goto error_ccp2;
1834 }
1835
1836 ret = omap3isp_ccdc_init(isp);
1837 if (ret < 0) {
1838 dev_err(isp->dev, "CCDC initialization failed\n");
1839 goto error_ccdc;
1840 }
1841
1842 ret = omap3isp_preview_init(isp);
1843 if (ret < 0) {
1844 dev_err(isp->dev, "Preview initialization failed\n");
1845 goto error_preview;
1846 }
1847
1848 ret = omap3isp_resizer_init(isp);
1849 if (ret < 0) {
1850 dev_err(isp->dev, "Resizer initialization failed\n");
1851 goto error_resizer;
1852 }
1853
1854 ret = omap3isp_hist_init(isp);
1855 if (ret < 0) {
1856 dev_err(isp->dev, "Histogram initialization failed\n");
1857 goto error_hist;
1858 }
1859
1860 ret = omap3isp_h3a_aewb_init(isp);
1861 if (ret < 0) {
1862 dev_err(isp->dev, "H3A AEWB initialization failed\n");
1863 goto error_h3a_aewb;
1864 }
1865
1866 ret = omap3isp_h3a_af_init(isp);
1867 if (ret < 0) {
1868 dev_err(isp->dev, "H3A AF initialization failed\n");
1869 goto error_h3a_af;
1870 }
1871
1872 /* Connect the submodules. */
1873 ret = media_entity_create_link(
1874 &isp->isp_csi2a.subdev.entity, CSI2_PAD_SOURCE,
1875 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
1876 if (ret < 0)
1877 goto error_link;
1878
1879 ret = media_entity_create_link(
1880 &isp->isp_ccp2.subdev.entity, CCP2_PAD_SOURCE,
1881 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SINK, 0);
1882 if (ret < 0)
1883 goto error_link;
1884
1885 ret = media_entity_create_link(
1886 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1887 &isp->isp_prev.subdev.entity, PREV_PAD_SINK, 0);
1888 if (ret < 0)
1889 goto error_link;
1890
1891 ret = media_entity_create_link(
1892 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_OF,
1893 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1894 if (ret < 0)
1895 goto error_link;
1896
1897 ret = media_entity_create_link(
1898 &isp->isp_prev.subdev.entity, PREV_PAD_SOURCE,
1899 &isp->isp_res.subdev.entity, RESZ_PAD_SINK, 0);
1900 if (ret < 0)
1901 goto error_link;
1902
1903 ret = media_entity_create_link(
1904 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1905 &isp->isp_aewb.subdev.entity, 0,
1906 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1907 if (ret < 0)
1908 goto error_link;
1909
1910 ret = media_entity_create_link(
1911 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1912 &isp->isp_af.subdev.entity, 0,
1913 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1914 if (ret < 0)
1915 goto error_link;
1916
1917 ret = media_entity_create_link(
1918 &isp->isp_ccdc.subdev.entity, CCDC_PAD_SOURCE_VP,
1919 &isp->isp_hist.subdev.entity, 0,
1920 MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE);
1921 if (ret < 0)
1922 goto error_link;
1923
1924 return 0;
1925
1926error_link:
1927 omap3isp_h3a_af_cleanup(isp);
1928error_h3a_af:
1929 omap3isp_h3a_aewb_cleanup(isp);
1930error_h3a_aewb:
1931 omap3isp_hist_cleanup(isp);
1932error_hist:
1933 omap3isp_resizer_cleanup(isp);
1934error_resizer:
1935 omap3isp_preview_cleanup(isp);
1936error_preview:
1937 omap3isp_ccdc_cleanup(isp);
1938error_ccdc:
1939 omap3isp_ccp2_cleanup(isp);
1940error_ccp2:
1941 omap3isp_csi2_cleanup(isp);
1942error_csi2:
1943error_csiphy:
1944 return ret;
1945}
1946
1947/*
1948 * isp_remove - Remove ISP platform device
1949 * @pdev: Pointer to ISP platform device
1950 *
1951 * Always returns 0.
1952 */
1953static int isp_remove(struct platform_device *pdev)
1954{
1955 struct isp_device *isp = platform_get_drvdata(pdev);
1956 int i;
1957
1958 isp_unregister_entities(isp);
1959 isp_cleanup_modules(isp);
1960
1961 omap3isp_get(isp);
1962 iommu_put(isp->iommu);
1963 omap3isp_put(isp);
1964
1965 free_irq(isp->irq_num, isp);
1966 isp_put_clocks(isp);
1967
1968 for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
1969 if (isp->mmio_base[i]) {
1970 iounmap(isp->mmio_base[i]);
1971 isp->mmio_base[i] = NULL;
1972 }
1973
1974 if (isp->mmio_base_phys[i]) {
1975 release_mem_region(isp->mmio_base_phys[i],
1976 isp->mmio_size[i]);
1977 isp->mmio_base_phys[i] = 0;
1978 }
1979 }
1980
1981 regulator_put(isp->isp_csiphy1.vdd);
1982 regulator_put(isp->isp_csiphy2.vdd);
1983 kfree(isp);
1984
1985 return 0;
1986}
1987
1988static int isp_map_mem_resource(struct platform_device *pdev,
1989 struct isp_device *isp,
1990 enum isp_mem_resources res)
1991{
1992 struct resource *mem;
1993
1994 /* request the mem region for the camera registers */
1995
1996 mem = platform_get_resource(pdev, IORESOURCE_MEM, res);
1997 if (!mem) {
1998 dev_err(isp->dev, "no mem resource?\n");
1999 return -ENODEV;
2000 }
2001
2002 if (!request_mem_region(mem->start, resource_size(mem), pdev->name)) {
2003 dev_err(isp->dev,
2004 "cannot reserve camera register I/O region\n");
2005 return -ENODEV;
2006 }
2007 isp->mmio_base_phys[res] = mem->start;
2008 isp->mmio_size[res] = resource_size(mem);
2009
2010 /* map the region */
2011 isp->mmio_base[res] = ioremap_nocache(isp->mmio_base_phys[res],
2012 isp->mmio_size[res]);
2013 if (!isp->mmio_base[res]) {
2014 dev_err(isp->dev, "cannot map camera register I/O region\n");
2015 return -ENODEV;
2016 }
2017
2018 return 0;
2019}
2020
2021/*
2022 * isp_probe - Probe ISP platform device
2023 * @pdev: Pointer to ISP platform device
2024 *
2025 * Returns 0 if successful,
2026 * -ENOMEM if no memory available,
2027 * -ENODEV if no platform device resources found
2028 * or no space for remapping registers,
2029 * -EINVAL if couldn't install ISR,
2030 * or clk_get return error value.
2031 */
2032static int isp_probe(struct platform_device *pdev)
2033{
2034 struct isp_platform_data *pdata = pdev->dev.platform_data;
2035 struct isp_device *isp;
2036 int ret;
2037 int i, m;
2038
2039 if (pdata == NULL)
2040 return -EINVAL;
2041
2042 isp = kzalloc(sizeof(*isp), GFP_KERNEL);
2043 if (!isp) {
2044 dev_err(&pdev->dev, "could not allocate memory\n");
2045 return -ENOMEM;
2046 }
2047
2048 isp->autoidle = autoidle;
2049 isp->platform_cb.set_xclk = isp_set_xclk;
2050 isp->platform_cb.set_pixel_clock = isp_set_pixel_clock;
2051
2052 mutex_init(&isp->isp_mutex);
2053 spin_lock_init(&isp->stat_lock);
2054
2055 isp->dev = &pdev->dev;
2056 isp->pdata = pdata;
2057 isp->ref_count = 0;
2058
2059 isp->raw_dmamask = DMA_BIT_MASK(32);
2060 isp->dev->dma_mask = &isp->raw_dmamask;
2061 isp->dev->coherent_dma_mask = DMA_BIT_MASK(32);
2062
2063 platform_set_drvdata(pdev, isp);
2064
2065 /* Regulators */
2066 isp->isp_csiphy1.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY1");
2067 isp->isp_csiphy2.vdd = regulator_get(&pdev->dev, "VDD_CSIPHY2");
2068
2069 /* Clocks */
2070 ret = isp_map_mem_resource(pdev, isp, OMAP3_ISP_IOMEM_MAIN);
2071 if (ret < 0)
2072 goto error;
2073
2074 ret = isp_get_clocks(isp);
2075 if (ret < 0)
2076 goto error;
2077
2078 if (omap3isp_get(isp) == NULL)
2079 goto error;
2080
2081 ret = isp_reset(isp);
2082 if (ret < 0)
2083 goto error_isp;
2084
2085 /* Memory resources */
2086 isp->revision = isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_REVISION);
2087 dev_info(isp->dev, "Revision %d.%d found\n",
2088 (isp->revision & 0xf0) >> 4, isp->revision & 0x0f);
2089
2090 for (m = 0; m < ARRAY_SIZE(isp_res_maps); m++)
2091 if (isp->revision == isp_res_maps[m].isp_rev)
2092 break;
2093
2094 if (m == ARRAY_SIZE(isp_res_maps)) {
2095 dev_err(isp->dev, "No resource map found for ISP rev %d.%d\n",
2096 (isp->revision & 0xf0) >> 4, isp->revision & 0xf);
2097 ret = -ENODEV;
2098 goto error_isp;
2099 }
2100
2101 for (i = 1; i < OMAP3_ISP_IOMEM_LAST; i++) {
2102 if (isp_res_maps[m].map & 1 << i) {
2103 ret = isp_map_mem_resource(pdev, isp, i);
2104 if (ret)
2105 goto error_isp;
2106 }
2107 }
2108
2109 /* IOMMU */
2110 isp->iommu = iommu_get("isp");
2111 if (IS_ERR_OR_NULL(isp->iommu)) {
2112 isp->iommu = NULL;
2113 ret = -ENODEV;
2114 goto error_isp;
2115 }
2116
2117 /* Interrupt */
2118 isp->irq_num = platform_get_irq(pdev, 0);
2119 if (isp->irq_num <= 0) {
2120 dev_err(isp->dev, "No IRQ resource\n");
2121 ret = -ENODEV;
2122 goto error_isp;
2123 }
2124
2125 if (request_irq(isp->irq_num, isp_isr, IRQF_SHARED, "OMAP3 ISP", isp)) {
2126 dev_err(isp->dev, "Unable to request IRQ\n");
2127 ret = -EINVAL;
2128 goto error_isp;
2129 }
2130
2131 /* Entities */
2132 ret = isp_initialize_modules(isp);
2133 if (ret < 0)
2134 goto error_irq;
2135
2136 ret = isp_register_entities(isp);
2137 if (ret < 0)
2138 goto error_modules;
2139
2140 isp_power_settings(isp, 1);
2141 omap3isp_put(isp);
2142
2143 return 0;
2144
2145error_modules:
2146 isp_cleanup_modules(isp);
2147error_irq:
2148 free_irq(isp->irq_num, isp);
2149error_isp:
2150 iommu_put(isp->iommu);
2151 omap3isp_put(isp);
2152error:
2153 isp_put_clocks(isp);
2154
2155 for (i = 0; i < OMAP3_ISP_IOMEM_LAST; i++) {
2156 if (isp->mmio_base[i]) {
2157 iounmap(isp->mmio_base[i]);
2158 isp->mmio_base[i] = NULL;
2159 }
2160
2161 if (isp->mmio_base_phys[i]) {
2162 release_mem_region(isp->mmio_base_phys[i],
2163 isp->mmio_size[i]);
2164 isp->mmio_base_phys[i] = 0;
2165 }
2166 }
2167 regulator_put(isp->isp_csiphy2.vdd);
2168 regulator_put(isp->isp_csiphy1.vdd);
2169 platform_set_drvdata(pdev, NULL);
2170 kfree(isp);
2171
2172 return ret;
2173}
2174
2175static const struct dev_pm_ops omap3isp_pm_ops = {
2176 .prepare = isp_pm_prepare,
2177 .suspend = isp_pm_suspend,
2178 .resume = isp_pm_resume,
2179 .complete = isp_pm_complete,
2180};
2181
2182static struct platform_device_id omap3isp_id_table[] = {
2183 { "omap3isp", 0 },
2184 { },
2185};
2186MODULE_DEVICE_TABLE(platform, omap3isp_id_table);
2187
2188static struct platform_driver omap3isp_driver = {
2189 .probe = isp_probe,
2190 .remove = isp_remove,
2191 .id_table = omap3isp_id_table,
2192 .driver = {
2193 .owner = THIS_MODULE,
2194 .name = "omap3isp",
2195 .pm = &omap3isp_pm_ops,
2196 },
2197};
2198
2199/*
2200 * isp_init - ISP module initialization.
2201 */
2202static int __init isp_init(void)
2203{
2204 return platform_driver_register(&omap3isp_driver);
2205}
2206
2207/*
2208 * isp_cleanup - ISP module cleanup.
2209 */
2210static void __exit isp_cleanup(void)
2211{
2212 platform_driver_unregister(&omap3isp_driver);
2213}
2214
2215module_init(isp_init);
2216module_exit(isp_cleanup);
2217
2218MODULE_AUTHOR("Nokia Corporation");
2219MODULE_DESCRIPTION("TI OMAP3 ISP driver");
2220MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/omap3isp/isp.h b/drivers/media/video/omap3isp/isp.h
new file mode 100644
index 000000000000..cf5214e95a92
--- /dev/null
+++ b/drivers/media/video/omap3isp/isp.h
@@ -0,0 +1,431 @@
1/*
2 * isp.h
3 *
4 * TI OMAP3 ISP - Core
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CORE_H
28#define OMAP3_ISP_CORE_H
29
30#include <media/v4l2-device.h>
31#include <linux/device.h>
32#include <linux/io.h>
33#include <linux/platform_device.h>
34#include <linux/wait.h>
35#include <plat/iommu.h>
36#include <plat/iovmm.h>
37
38#include "ispstat.h"
39#include "ispccdc.h"
40#include "ispreg.h"
41#include "ispresizer.h"
42#include "isppreview.h"
43#include "ispcsiphy.h"
44#include "ispcsi2.h"
45#include "ispccp2.h"
46
47#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
48
49#define ISP_TOK_TERM 0xFFFFFFFF /*
50 * terminating token for ISP
51 * modules reg list
52 */
53#define to_isp_device(ptr_module) \
54 container_of(ptr_module, struct isp_device, isp_##ptr_module)
55#define to_device(ptr_module) \
56 (to_isp_device(ptr_module)->dev)
57
58enum isp_mem_resources {
59 OMAP3_ISP_IOMEM_MAIN,
60 OMAP3_ISP_IOMEM_CCP2,
61 OMAP3_ISP_IOMEM_CCDC,
62 OMAP3_ISP_IOMEM_HIST,
63 OMAP3_ISP_IOMEM_H3A,
64 OMAP3_ISP_IOMEM_PREV,
65 OMAP3_ISP_IOMEM_RESZ,
66 OMAP3_ISP_IOMEM_SBL,
67 OMAP3_ISP_IOMEM_CSI2A_REGS1,
68 OMAP3_ISP_IOMEM_CSIPHY2,
69 OMAP3_ISP_IOMEM_CSI2A_REGS2,
70 OMAP3_ISP_IOMEM_CSI2C_REGS1,
71 OMAP3_ISP_IOMEM_CSIPHY1,
72 OMAP3_ISP_IOMEM_CSI2C_REGS2,
73 OMAP3_ISP_IOMEM_LAST
74};
75
76enum isp_sbl_resource {
77 OMAP3_ISP_SBL_CSI1_READ = 0x1,
78 OMAP3_ISP_SBL_CSI1_WRITE = 0x2,
79 OMAP3_ISP_SBL_CSI2A_WRITE = 0x4,
80 OMAP3_ISP_SBL_CSI2C_WRITE = 0x8,
81 OMAP3_ISP_SBL_CCDC_LSC_READ = 0x10,
82 OMAP3_ISP_SBL_CCDC_WRITE = 0x20,
83 OMAP3_ISP_SBL_PREVIEW_READ = 0x40,
84 OMAP3_ISP_SBL_PREVIEW_WRITE = 0x80,
85 OMAP3_ISP_SBL_RESIZER_READ = 0x100,
86 OMAP3_ISP_SBL_RESIZER_WRITE = 0x200,
87};
88
89enum isp_subclk_resource {
90 OMAP3_ISP_SUBCLK_CCDC = (1 << 0),
91 OMAP3_ISP_SUBCLK_H3A = (1 << 1),
92 OMAP3_ISP_SUBCLK_HIST = (1 << 2),
93 OMAP3_ISP_SUBCLK_PREVIEW = (1 << 3),
94 OMAP3_ISP_SUBCLK_RESIZER = (1 << 4),
95};
96
97enum isp_interface_type {
98 ISP_INTERFACE_PARALLEL,
99 ISP_INTERFACE_CSI2A_PHY2,
100 ISP_INTERFACE_CCP2B_PHY1,
101 ISP_INTERFACE_CCP2B_PHY2,
102 ISP_INTERFACE_CSI2C_PHY1,
103};
104
105/* ISP: OMAP 34xx ES 1.0 */
106#define ISP_REVISION_1_0 0x10
107/* ISP2: OMAP 34xx ES 2.0, 2.1 and 3.0 */
108#define ISP_REVISION_2_0 0x20
109/* ISP2P: OMAP 36xx */
110#define ISP_REVISION_15_0 0xF0
111
112/*
113 * struct isp_res_mapping - Map ISP io resources to ISP revision.
114 * @isp_rev: ISP_REVISION_x_x
115 * @map: bitmap for enum isp_mem_resources
116 */
117struct isp_res_mapping {
118 u32 isp_rev;
119 u32 map;
120};
121
122/*
123 * struct isp_reg - Structure for ISP register values.
124 * @reg: 32-bit Register address.
125 * @val: 32-bit Register value.
126 */
127struct isp_reg {
128 enum isp_mem_resources mmio_range;
129 u32 reg;
130 u32 val;
131};
132
133/**
134 * struct isp_parallel_platform_data - Parallel interface platform data
135 * @width: Parallel bus width in bits (8, 10, 11 or 12)
136 * @data_lane_shift: Data lane shifter
137 * 0 - CAMEXT[13:0] -> CAM[13:0]
138 * 1 - CAMEXT[13:2] -> CAM[11:0]
139 * 2 - CAMEXT[13:4] -> CAM[9:0]
140 * 3 - CAMEXT[13:6] -> CAM[7:0]
141 * @clk_pol: Pixel clock polarity
142 * 0 - Non Inverted, 1 - Inverted
143 * @bridge: CCDC Bridge input control
144 * ISPCTRL_PAR_BRIDGE_DISABLE - Disable
145 * ISPCTRL_PAR_BRIDGE_LENDIAN - Little endian
146 * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian
147 */
148struct isp_parallel_platform_data {
149 unsigned int width;
150 unsigned int data_lane_shift:2;
151 unsigned int clk_pol:1;
152 unsigned int bridge:4;
153};
154
155/**
156 * struct isp_ccp2_platform_data - CCP2 interface platform data
157 * @strobe_clk_pol: Strobe/clock polarity
158 * 0 - Non Inverted, 1 - Inverted
159 * @crc: Enable the cyclic redundancy check
160 * @ccp2_mode: Enable CCP2 compatibility mode
161 * 0 - MIPI-CSI1 mode, 1 - CCP2 mode
162 * @phy_layer: Physical layer selection
163 * ISPCCP2_CTRL_PHY_SEL_CLOCK - Data/clock physical layer
164 * ISPCCP2_CTRL_PHY_SEL_STROBE - Data/strobe physical layer
165 * @vpclk_div: Video port output clock control
166 */
167struct isp_ccp2_platform_data {
168 unsigned int strobe_clk_pol:1;
169 unsigned int crc:1;
170 unsigned int ccp2_mode:1;
171 unsigned int phy_layer:1;
172 unsigned int vpclk_div:2;
173};
174
175/**
176 * struct isp_csi2_platform_data - CSI2 interface platform data
177 * @crc: Enable the cyclic redundancy check
178 * @vpclk_div: Video port output clock control
179 */
180struct isp_csi2_platform_data {
181 unsigned crc:1;
182 unsigned vpclk_div:2;
183};
184
185struct isp_subdev_i2c_board_info {
186 struct i2c_board_info *board_info;
187 int i2c_adapter_id;
188};
189
190struct isp_v4l2_subdevs_group {
191 struct isp_subdev_i2c_board_info *subdevs;
192 enum isp_interface_type interface;
193 union {
194 struct isp_parallel_platform_data parallel;
195 struct isp_ccp2_platform_data ccp2;
196 struct isp_csi2_platform_data csi2;
197 } bus; /* gcc < 4.6.0 chokes on anonymous union initializers */
198};
199
200struct isp_platform_data {
201 struct isp_v4l2_subdevs_group *subdevs;
202 void (*set_constraints)(struct isp_device *isp, bool enable);
203};
204
205struct isp_platform_callback {
206 u32 (*set_xclk)(struct isp_device *isp, u32 xclk, u8 xclksel);
207 int (*csiphy_config)(struct isp_csiphy *phy,
208 struct isp_csiphy_dphy_cfg *dphy,
209 struct isp_csiphy_lanes_cfg *lanes);
210 void (*set_pixel_clock)(struct isp_device *isp, unsigned int pixelclk);
211};
212
213/*
214 * struct isp_device - ISP device structure.
215 * @dev: Device pointer specific to the OMAP3 ISP.
216 * @revision: Stores current ISP module revision.
217 * @irq_num: Currently used IRQ number.
218 * @mmio_base: Array with kernel base addresses for ioremapped ISP register
219 * regions.
220 * @mmio_base_phys: Array with physical L4 bus addresses for ISP register
221 * regions.
222 * @mmio_size: Array with ISP register regions size in bytes.
223 * @raw_dmamask: Raw DMA mask
224 * @stat_lock: Spinlock for handling statistics
225 * @isp_mutex: Mutex for serializing requests to ISP.
226 * @has_context: Context has been saved at least once and can be restored.
227 * @ref_count: Reference count for handling multiple ISP requests.
228 * @cam_ick: Pointer to camera interface clock structure.
229 * @cam_mclk: Pointer to camera functional clock structure.
230 * @dpll4_m5_ck: Pointer to DPLL4 M5 clock structure.
231 * @csi2_fck: Pointer to camera CSI2 complexIO clock structure.
232 * @l3_ick: Pointer to OMAP3 L3 bus interface clock.
233 * @irq: Currently attached ISP ISR callbacks information structure.
234 * @isp_af: Pointer to current settings for ISP AutoFocus SCM.
235 * @isp_hist: Pointer to current settings for ISP Histogram SCM.
236 * @isp_h3a: Pointer to current settings for ISP Auto Exposure and
237 * White Balance SCM.
238 * @isp_res: Pointer to current settings for ISP Resizer.
239 * @isp_prev: Pointer to current settings for ISP Preview.
240 * @isp_ccdc: Pointer to current settings for ISP CCDC.
241 * @iommu: Pointer to requested IOMMU instance for ISP.
242 * @platform_cb: ISP driver callback function pointers for platform code
243 *
244 * This structure is used to store the OMAP ISP Information.
245 */
246struct isp_device {
247 struct v4l2_device v4l2_dev;
248 struct media_device media_dev;
249 struct device *dev;
250 u32 revision;
251
252 /* platform HW resources */
253 struct isp_platform_data *pdata;
254 unsigned int irq_num;
255
256 void __iomem *mmio_base[OMAP3_ISP_IOMEM_LAST];
257 unsigned long mmio_base_phys[OMAP3_ISP_IOMEM_LAST];
258 resource_size_t mmio_size[OMAP3_ISP_IOMEM_LAST];
259
260 u64 raw_dmamask;
261
262 /* ISP Obj */
263 spinlock_t stat_lock; /* common lock for statistic drivers */
264 struct mutex isp_mutex; /* For handling ref_count field */
265 int has_context;
266 int ref_count;
267 unsigned int autoidle;
268 u32 xclk_divisor[2]; /* Two clocks, a and b. */
269#define ISP_CLK_CAM_ICK 0
270#define ISP_CLK_CAM_MCLK 1
271#define ISP_CLK_DPLL4_M5_CK 2
272#define ISP_CLK_CSI2_FCK 3
273#define ISP_CLK_L3_ICK 4
274 struct clk *clock[5];
275
276 /* ISP modules */
277 struct ispstat isp_af;
278 struct ispstat isp_aewb;
279 struct ispstat isp_hist;
280 struct isp_res_device isp_res;
281 struct isp_prev_device isp_prev;
282 struct isp_ccdc_device isp_ccdc;
283 struct isp_csi2_device isp_csi2a;
284 struct isp_csi2_device isp_csi2c;
285 struct isp_ccp2_device isp_ccp2;
286 struct isp_csiphy isp_csiphy1;
287 struct isp_csiphy isp_csiphy2;
288
289 unsigned int sbl_resources;
290 unsigned int subclk_resources;
291
292 struct iommu *iommu;
293
294 struct isp_platform_callback platform_cb;
295};
296
297#define v4l2_dev_to_isp_device(dev) \
298 container_of(dev, struct isp_device, v4l2_dev)
299
300void omap3isp_hist_dma_done(struct isp_device *isp);
301
302void omap3isp_flush(struct isp_device *isp);
303
304int omap3isp_module_sync_idle(struct media_entity *me, wait_queue_head_t *wait,
305 atomic_t *stopping);
306
307int omap3isp_module_sync_is_stopping(wait_queue_head_t *wait,
308 atomic_t *stopping);
309
310int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
311 enum isp_pipeline_stream_state state);
312void omap3isp_configure_bridge(struct isp_device *isp,
313 enum ccdc_input_entity input,
314 const struct isp_parallel_platform_data *pdata);
315
316#define ISP_XCLK_NONE -1
317#define ISP_XCLK_A 0
318#define ISP_XCLK_B 1
319
320struct isp_device *omap3isp_get(struct isp_device *isp);
321void omap3isp_put(struct isp_device *isp);
322
323void omap3isp_print_status(struct isp_device *isp);
324
325void omap3isp_sbl_enable(struct isp_device *isp, enum isp_sbl_resource res);
326void omap3isp_sbl_disable(struct isp_device *isp, enum isp_sbl_resource res);
327
328void omap3isp_subclk_enable(struct isp_device *isp,
329 enum isp_subclk_resource res);
330void omap3isp_subclk_disable(struct isp_device *isp,
331 enum isp_subclk_resource res);
332
333int omap3isp_pipeline_pm_use(struct media_entity *entity, int use);
334
335int omap3isp_register_entities(struct platform_device *pdev,
336 struct v4l2_device *v4l2_dev);
337void omap3isp_unregister_entities(struct platform_device *pdev);
338
339/*
340 * isp_reg_readl - Read value of an OMAP3 ISP register
341 * @dev: Device pointer specific to the OMAP3 ISP.
342 * @isp_mmio_range: Range to which the register offset refers to.
343 * @reg_offset: Register offset to read from.
344 *
345 * Returns an unsigned 32 bit value with the required register contents.
346 */
347static inline
348u32 isp_reg_readl(struct isp_device *isp, enum isp_mem_resources isp_mmio_range,
349 u32 reg_offset)
350{
351 return __raw_readl(isp->mmio_base[isp_mmio_range] + reg_offset);
352}
353
354/*
355 * isp_reg_writel - Write value to an OMAP3 ISP register
356 * @dev: Device pointer specific to the OMAP3 ISP.
357 * @reg_value: 32 bit value to write to the register.
358 * @isp_mmio_range: Range to which the register offset refers to.
359 * @reg_offset: Register offset to write into.
360 */
361static inline
362void isp_reg_writel(struct isp_device *isp, u32 reg_value,
363 enum isp_mem_resources isp_mmio_range, u32 reg_offset)
364{
365 __raw_writel(reg_value, isp->mmio_base[isp_mmio_range] + reg_offset);
366}
367
368/*
369 * isp_reg_and - Clear individual bits in an OMAP3 ISP register
370 * @dev: Device pointer specific to the OMAP3 ISP.
371 * @mmio_range: Range to which the register offset refers to.
372 * @reg: Register offset to work on.
373 * @clr_bits: 32 bit value which would be cleared in the register.
374 */
375static inline
376void isp_reg_clr(struct isp_device *isp, enum isp_mem_resources mmio_range,
377 u32 reg, u32 clr_bits)
378{
379 u32 v = isp_reg_readl(isp, mmio_range, reg);
380
381 isp_reg_writel(isp, v & ~clr_bits, mmio_range, reg);
382}
383
384/*
385 * isp_reg_set - Set individual bits in an OMAP3 ISP register
386 * @dev: Device pointer specific to the OMAP3 ISP.
387 * @mmio_range: Range to which the register offset refers to.
388 * @reg: Register offset to work on.
389 * @set_bits: 32 bit value which would be set in the register.
390 */
391static inline
392void isp_reg_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
393 u32 reg, u32 set_bits)
394{
395 u32 v = isp_reg_readl(isp, mmio_range, reg);
396
397 isp_reg_writel(isp, v | set_bits, mmio_range, reg);
398}
399
400/*
401 * isp_reg_clr_set - Clear and set invidial bits in an OMAP3 ISP register
402 * @dev: Device pointer specific to the OMAP3 ISP.
403 * @mmio_range: Range to which the register offset refers to.
404 * @reg: Register offset to work on.
405 * @clr_bits: 32 bit value which would be cleared in the register.
406 * @set_bits: 32 bit value which would be set in the register.
407 *
408 * The clear operation is done first, and then the set operation.
409 */
410static inline
411void isp_reg_clr_set(struct isp_device *isp, enum isp_mem_resources mmio_range,
412 u32 reg, u32 clr_bits, u32 set_bits)
413{
414 u32 v = isp_reg_readl(isp, mmio_range, reg);
415
416 isp_reg_writel(isp, (v & ~clr_bits) | set_bits, mmio_range, reg);
417}
418
419static inline enum v4l2_buf_type
420isp_pad_buffer_type(const struct v4l2_subdev *subdev, int pad)
421{
422 if (pad >= subdev->entity.num_pads)
423 return 0;
424
425 if (subdev->entity.pads[pad].flags & MEDIA_PAD_FL_SINK)
426 return V4L2_BUF_TYPE_VIDEO_OUTPUT;
427 else
428 return V4L2_BUF_TYPE_VIDEO_CAPTURE;
429}
430
431#endif /* OMAP3_ISP_CORE_H */
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
new file mode 100644
index 000000000000..5ff9d14ce710
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -0,0 +1,2268 @@
1/*
2 * ispccdc.c
3 *
4 * TI OMAP3 ISP - CCDC module
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/module.h>
28#include <linux/uaccess.h>
29#include <linux/delay.h>
30#include <linux/device.h>
31#include <linux/dma-mapping.h>
32#include <linux/mm.h>
33#include <linux/sched.h>
34#include <media/v4l2-event.h>
35
36#include "isp.h"
37#include "ispreg.h"
38#include "ispccdc.h"
39
40static struct v4l2_mbus_framefmt *
41__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
42 unsigned int pad, enum v4l2_subdev_format_whence which);
43
44static const unsigned int ccdc_fmts[] = {
45 V4L2_MBUS_FMT_Y8_1X8,
46 V4L2_MBUS_FMT_SGRBG10_1X10,
47 V4L2_MBUS_FMT_SRGGB10_1X10,
48 V4L2_MBUS_FMT_SBGGR10_1X10,
49 V4L2_MBUS_FMT_SGBRG10_1X10,
50 V4L2_MBUS_FMT_SGRBG12_1X12,
51 V4L2_MBUS_FMT_SRGGB12_1X12,
52 V4L2_MBUS_FMT_SBGGR12_1X12,
53 V4L2_MBUS_FMT_SGBRG12_1X12,
54};
55
56/*
57 * ccdc_print_status - Print current CCDC Module register values.
58 * @ccdc: Pointer to ISP CCDC device.
59 *
60 * Also prints other debug information stored in the CCDC module.
61 */
62#define CCDC_PRINT_REGISTER(isp, name)\
63 dev_dbg(isp->dev, "###CCDC " #name "=0x%08x\n", \
64 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_##name))
65
66static void ccdc_print_status(struct isp_ccdc_device *ccdc)
67{
68 struct isp_device *isp = to_isp_device(ccdc);
69
70 dev_dbg(isp->dev, "-------------CCDC Register dump-------------\n");
71
72 CCDC_PRINT_REGISTER(isp, PCR);
73 CCDC_PRINT_REGISTER(isp, SYN_MODE);
74 CCDC_PRINT_REGISTER(isp, HD_VD_WID);
75 CCDC_PRINT_REGISTER(isp, PIX_LINES);
76 CCDC_PRINT_REGISTER(isp, HORZ_INFO);
77 CCDC_PRINT_REGISTER(isp, VERT_START);
78 CCDC_PRINT_REGISTER(isp, VERT_LINES);
79 CCDC_PRINT_REGISTER(isp, CULLING);
80 CCDC_PRINT_REGISTER(isp, HSIZE_OFF);
81 CCDC_PRINT_REGISTER(isp, SDOFST);
82 CCDC_PRINT_REGISTER(isp, SDR_ADDR);
83 CCDC_PRINT_REGISTER(isp, CLAMP);
84 CCDC_PRINT_REGISTER(isp, DCSUB);
85 CCDC_PRINT_REGISTER(isp, COLPTN);
86 CCDC_PRINT_REGISTER(isp, BLKCMP);
87 CCDC_PRINT_REGISTER(isp, FPC);
88 CCDC_PRINT_REGISTER(isp, FPC_ADDR);
89 CCDC_PRINT_REGISTER(isp, VDINT);
90 CCDC_PRINT_REGISTER(isp, ALAW);
91 CCDC_PRINT_REGISTER(isp, REC656IF);
92 CCDC_PRINT_REGISTER(isp, CFG);
93 CCDC_PRINT_REGISTER(isp, FMTCFG);
94 CCDC_PRINT_REGISTER(isp, FMT_HORZ);
95 CCDC_PRINT_REGISTER(isp, FMT_VERT);
96 CCDC_PRINT_REGISTER(isp, PRGEVEN0);
97 CCDC_PRINT_REGISTER(isp, PRGEVEN1);
98 CCDC_PRINT_REGISTER(isp, PRGODD0);
99 CCDC_PRINT_REGISTER(isp, PRGODD1);
100 CCDC_PRINT_REGISTER(isp, VP_OUT);
101 CCDC_PRINT_REGISTER(isp, LSC_CONFIG);
102 CCDC_PRINT_REGISTER(isp, LSC_INITIAL);
103 CCDC_PRINT_REGISTER(isp, LSC_TABLE_BASE);
104 CCDC_PRINT_REGISTER(isp, LSC_TABLE_OFFSET);
105
106 dev_dbg(isp->dev, "--------------------------------------------\n");
107}
108
109/*
110 * omap3isp_ccdc_busy - Get busy state of the CCDC.
111 * @ccdc: Pointer to ISP CCDC device.
112 */
113int omap3isp_ccdc_busy(struct isp_ccdc_device *ccdc)
114{
115 struct isp_device *isp = to_isp_device(ccdc);
116
117 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR) &
118 ISPCCDC_PCR_BUSY;
119}
120
121/* -----------------------------------------------------------------------------
122 * Lens Shading Compensation
123 */
124
125/*
126 * ccdc_lsc_validate_config - Check that LSC configuration is valid.
127 * @ccdc: Pointer to ISP CCDC device.
128 * @lsc_cfg: the LSC configuration to check.
129 *
130 * Returns 0 if the LSC configuration is valid, or -EINVAL if invalid.
131 */
132static int ccdc_lsc_validate_config(struct isp_ccdc_device *ccdc,
133 struct omap3isp_ccdc_lsc_config *lsc_cfg)
134{
135 struct isp_device *isp = to_isp_device(ccdc);
136 struct v4l2_mbus_framefmt *format;
137 unsigned int paxel_width, paxel_height;
138 unsigned int paxel_shift_x, paxel_shift_y;
139 unsigned int min_width, min_height, min_size;
140 unsigned int input_width, input_height;
141
142 paxel_shift_x = lsc_cfg->gain_mode_m;
143 paxel_shift_y = lsc_cfg->gain_mode_n;
144
145 if ((paxel_shift_x < 2) || (paxel_shift_x > 6) ||
146 (paxel_shift_y < 2) || (paxel_shift_y > 6)) {
147 dev_dbg(isp->dev, "CCDC: LSC: Invalid paxel size\n");
148 return -EINVAL;
149 }
150
151 if (lsc_cfg->offset & 3) {
152 dev_dbg(isp->dev, "CCDC: LSC: Offset must be a multiple of "
153 "4\n");
154 return -EINVAL;
155 }
156
157 if ((lsc_cfg->initial_x & 1) || (lsc_cfg->initial_y & 1)) {
158 dev_dbg(isp->dev, "CCDC: LSC: initial_x and y must be even\n");
159 return -EINVAL;
160 }
161
162 format = __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
163 V4L2_SUBDEV_FORMAT_ACTIVE);
164 input_width = format->width;
165 input_height = format->height;
166
167 /* Calculate minimum bytesize for validation */
168 paxel_width = 1 << paxel_shift_x;
169 min_width = ((input_width + lsc_cfg->initial_x + paxel_width - 1)
170 >> paxel_shift_x) + 1;
171
172 paxel_height = 1 << paxel_shift_y;
173 min_height = ((input_height + lsc_cfg->initial_y + paxel_height - 1)
174 >> paxel_shift_y) + 1;
175
176 min_size = 4 * min_width * min_height;
177 if (min_size > lsc_cfg->size) {
178 dev_dbg(isp->dev, "CCDC: LSC: too small table\n");
179 return -EINVAL;
180 }
181 if (lsc_cfg->offset < (min_width * 4)) {
182 dev_dbg(isp->dev, "CCDC: LSC: Offset is too small\n");
183 return -EINVAL;
184 }
185 if ((lsc_cfg->size / lsc_cfg->offset) < min_height) {
186 dev_dbg(isp->dev, "CCDC: LSC: Wrong size/offset combination\n");
187 return -EINVAL;
188 }
189 return 0;
190}
191
192/*
193 * ccdc_lsc_program_table - Program Lens Shading Compensation table address.
194 * @ccdc: Pointer to ISP CCDC device.
195 */
196static void ccdc_lsc_program_table(struct isp_ccdc_device *ccdc, u32 addr)
197{
198 isp_reg_writel(to_isp_device(ccdc), addr,
199 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_TABLE_BASE);
200}
201
202/*
203 * ccdc_lsc_setup_regs - Configures the lens shading compensation module
204 * @ccdc: Pointer to ISP CCDC device.
205 */
206static void ccdc_lsc_setup_regs(struct isp_ccdc_device *ccdc,
207 struct omap3isp_ccdc_lsc_config *cfg)
208{
209 struct isp_device *isp = to_isp_device(ccdc);
210 int reg;
211
212 isp_reg_writel(isp, cfg->offset, OMAP3_ISP_IOMEM_CCDC,
213 ISPCCDC_LSC_TABLE_OFFSET);
214
215 reg = 0;
216 reg |= cfg->gain_mode_n << ISPCCDC_LSC_GAIN_MODE_N_SHIFT;
217 reg |= cfg->gain_mode_m << ISPCCDC_LSC_GAIN_MODE_M_SHIFT;
218 reg |= cfg->gain_format << ISPCCDC_LSC_GAIN_FORMAT_SHIFT;
219 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG);
220
221 reg = 0;
222 reg &= ~ISPCCDC_LSC_INITIAL_X_MASK;
223 reg |= cfg->initial_x << ISPCCDC_LSC_INITIAL_X_SHIFT;
224 reg &= ~ISPCCDC_LSC_INITIAL_Y_MASK;
225 reg |= cfg->initial_y << ISPCCDC_LSC_INITIAL_Y_SHIFT;
226 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_CCDC,
227 ISPCCDC_LSC_INITIAL);
228}
229
230static int ccdc_lsc_wait_prefetch(struct isp_ccdc_device *ccdc)
231{
232 struct isp_device *isp = to_isp_device(ccdc);
233 unsigned int wait;
234
235 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
236 OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
237
238 /* timeout 1 ms */
239 for (wait = 0; wait < 1000; wait++) {
240 if (isp_reg_readl(isp, OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS) &
241 IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ) {
242 isp_reg_writel(isp, IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ,
243 OMAP3_ISP_IOMEM_MAIN, ISP_IRQ0STATUS);
244 return 0;
245 }
246
247 rmb();
248 udelay(1);
249 }
250
251 return -ETIMEDOUT;
252}
253
254/*
255 * __ccdc_lsc_enable - Enables/Disables the Lens Shading Compensation module.
256 * @ccdc: Pointer to ISP CCDC device.
257 * @enable: 0 Disables LSC, 1 Enables LSC.
258 */
259static int __ccdc_lsc_enable(struct isp_ccdc_device *ccdc, int enable)
260{
261 struct isp_device *isp = to_isp_device(ccdc);
262 const struct v4l2_mbus_framefmt *format =
263 __ccdc_get_format(ccdc, NULL, CCDC_PAD_SINK,
264 V4L2_SUBDEV_FORMAT_ACTIVE);
265
266 if ((format->code != V4L2_MBUS_FMT_SGRBG10_1X10) &&
267 (format->code != V4L2_MBUS_FMT_SRGGB10_1X10) &&
268 (format->code != V4L2_MBUS_FMT_SBGGR10_1X10) &&
269 (format->code != V4L2_MBUS_FMT_SGBRG10_1X10))
270 return -EINVAL;
271
272 if (enable)
273 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_LSC_READ);
274
275 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
276 ISPCCDC_LSC_ENABLE, enable ? ISPCCDC_LSC_ENABLE : 0);
277
278 if (enable) {
279 if (ccdc_lsc_wait_prefetch(ccdc) < 0) {
280 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC,
281 ISPCCDC_LSC_CONFIG, ISPCCDC_LSC_ENABLE);
282 ccdc->lsc.state = LSC_STATE_STOPPED;
283 dev_warn(to_device(ccdc), "LSC prefecth timeout\n");
284 return -ETIMEDOUT;
285 }
286 ccdc->lsc.state = LSC_STATE_RUNNING;
287 } else {
288 ccdc->lsc.state = LSC_STATE_STOPPING;
289 }
290
291 return 0;
292}
293
294static int ccdc_lsc_busy(struct isp_ccdc_device *ccdc)
295{
296 struct isp_device *isp = to_isp_device(ccdc);
297
298 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG) &
299 ISPCCDC_LSC_BUSY;
300}
301
302/* __ccdc_lsc_configure - Apply a new configuration to the LSC engine
303 * @ccdc: Pointer to ISP CCDC device
304 * @req: New configuration request
305 *
306 * context: in_interrupt()
307 */
308static int __ccdc_lsc_configure(struct isp_ccdc_device *ccdc,
309 struct ispccdc_lsc_config_req *req)
310{
311 if (!req->enable)
312 return -EINVAL;
313
314 if (ccdc_lsc_validate_config(ccdc, &req->config) < 0) {
315 dev_dbg(to_device(ccdc), "Discard LSC configuration\n");
316 return -EINVAL;
317 }
318
319 if (ccdc_lsc_busy(ccdc))
320 return -EBUSY;
321
322 ccdc_lsc_setup_regs(ccdc, &req->config);
323 ccdc_lsc_program_table(ccdc, req->table);
324 return 0;
325}
326
327/*
328 * ccdc_lsc_error_handler - Handle LSC prefetch error scenario.
329 * @ccdc: Pointer to ISP CCDC device.
330 *
331 * Disables LSC, and defers enablement to shadow registers update time.
332 */
333static void ccdc_lsc_error_handler(struct isp_ccdc_device *ccdc)
334{
335 struct isp_device *isp = to_isp_device(ccdc);
336 /*
337 * From OMAP3 TRM: When this event is pending, the module
338 * goes into transparent mode (output =input). Normal
339 * operation can be resumed at the start of the next frame
340 * after:
341 * 1) Clearing this event
342 * 2) Disabling the LSC module
343 * 3) Enabling it
344 */
345 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_LSC_CONFIG,
346 ISPCCDC_LSC_ENABLE);
347 ccdc->lsc.state = LSC_STATE_STOPPED;
348}
349
350static void ccdc_lsc_free_request(struct isp_ccdc_device *ccdc,
351 struct ispccdc_lsc_config_req *req)
352{
353 struct isp_device *isp = to_isp_device(ccdc);
354
355 if (req == NULL)
356 return;
357
358 if (req->iovm)
359 dma_unmap_sg(isp->dev, req->iovm->sgt->sgl,
360 req->iovm->sgt->nents, DMA_TO_DEVICE);
361 if (req->table)
362 iommu_vfree(isp->iommu, req->table);
363 kfree(req);
364}
365
366static void ccdc_lsc_free_queue(struct isp_ccdc_device *ccdc,
367 struct list_head *queue)
368{
369 struct ispccdc_lsc_config_req *req, *n;
370 unsigned long flags;
371
372 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
373 list_for_each_entry_safe(req, n, queue, list) {
374 list_del(&req->list);
375 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
376 ccdc_lsc_free_request(ccdc, req);
377 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
378 }
379 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
380}
381
382static void ccdc_lsc_free_table_work(struct work_struct *work)
383{
384 struct isp_ccdc_device *ccdc;
385 struct ispccdc_lsc *lsc;
386
387 lsc = container_of(work, struct ispccdc_lsc, table_work);
388 ccdc = container_of(lsc, struct isp_ccdc_device, lsc);
389
390 ccdc_lsc_free_queue(ccdc, &lsc->free_queue);
391}
392
393/*
394 * ccdc_lsc_config - Configure the LSC module from a userspace request
395 *
396 * Store the request LSC configuration in the LSC engine request pointer. The
397 * configuration will be applied to the hardware when the CCDC will be enabled,
398 * or at the next LSC interrupt if the CCDC is already running.
399 */
400static int ccdc_lsc_config(struct isp_ccdc_device *ccdc,
401 struct omap3isp_ccdc_update_config *config)
402{
403 struct isp_device *isp = to_isp_device(ccdc);
404 struct ispccdc_lsc_config_req *req;
405 unsigned long flags;
406 void *table;
407 u16 update;
408 int ret;
409
410 update = config->update &
411 (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC);
412 if (!update)
413 return 0;
414
415 if (update != (OMAP3ISP_CCDC_CONFIG_LSC | OMAP3ISP_CCDC_TBL_LSC)) {
416 dev_dbg(to_device(ccdc), "%s: Both LSC configuration and table "
417 "need to be supplied\n", __func__);
418 return -EINVAL;
419 }
420
421 req = kzalloc(sizeof(*req), GFP_KERNEL);
422 if (req == NULL)
423 return -ENOMEM;
424
425 if (config->flag & OMAP3ISP_CCDC_CONFIG_LSC) {
426 if (copy_from_user(&req->config, config->lsc_cfg,
427 sizeof(req->config))) {
428 ret = -EFAULT;
429 goto done;
430 }
431
432 req->enable = 1;
433
434 req->table = iommu_vmalloc(isp->iommu, 0, req->config.size,
435 IOMMU_FLAG);
436 if (IS_ERR_VALUE(req->table)) {
437 req->table = 0;
438 ret = -ENOMEM;
439 goto done;
440 }
441
442 req->iovm = find_iovm_area(isp->iommu, req->table);
443 if (req->iovm == NULL) {
444 ret = -ENOMEM;
445 goto done;
446 }
447
448 if (!dma_map_sg(isp->dev, req->iovm->sgt->sgl,
449 req->iovm->sgt->nents, DMA_TO_DEVICE)) {
450 ret = -ENOMEM;
451 req->iovm = NULL;
452 goto done;
453 }
454
455 dma_sync_sg_for_cpu(isp->dev, req->iovm->sgt->sgl,
456 req->iovm->sgt->nents, DMA_TO_DEVICE);
457
458 table = da_to_va(isp->iommu, req->table);
459 if (copy_from_user(table, config->lsc, req->config.size)) {
460 ret = -EFAULT;
461 goto done;
462 }
463
464 dma_sync_sg_for_device(isp->dev, req->iovm->sgt->sgl,
465 req->iovm->sgt->nents, DMA_TO_DEVICE);
466 }
467
468 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
469 if (ccdc->lsc.request) {
470 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
471 schedule_work(&ccdc->lsc.table_work);
472 }
473 ccdc->lsc.request = req;
474 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
475
476 ret = 0;
477
478done:
479 if (ret < 0)
480 ccdc_lsc_free_request(ccdc, req);
481
482 return ret;
483}
484
485static inline int ccdc_lsc_is_configured(struct isp_ccdc_device *ccdc)
486{
487 unsigned long flags;
488
489 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
490 if (ccdc->lsc.active) {
491 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
492 return 1;
493 }
494 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
495 return 0;
496}
497
498static int ccdc_lsc_enable(struct isp_ccdc_device *ccdc)
499{
500 struct ispccdc_lsc *lsc = &ccdc->lsc;
501
502 if (lsc->state != LSC_STATE_STOPPED)
503 return -EINVAL;
504
505 if (lsc->active) {
506 list_add_tail(&lsc->active->list, &lsc->free_queue);
507 lsc->active = NULL;
508 }
509
510 if (__ccdc_lsc_configure(ccdc, lsc->request) < 0) {
511 omap3isp_sbl_disable(to_isp_device(ccdc),
512 OMAP3_ISP_SBL_CCDC_LSC_READ);
513 list_add_tail(&lsc->request->list, &lsc->free_queue);
514 lsc->request = NULL;
515 goto done;
516 }
517
518 lsc->active = lsc->request;
519 lsc->request = NULL;
520 __ccdc_lsc_enable(ccdc, 1);
521
522done:
523 if (!list_empty(&lsc->free_queue))
524 schedule_work(&lsc->table_work);
525
526 return 0;
527}
528
529/* -----------------------------------------------------------------------------
530 * Parameters configuration
531 */
532
533/*
534 * ccdc_configure_clamp - Configure optical-black or digital clamping
535 * @ccdc: Pointer to ISP CCDC device.
536 *
537 * The CCDC performs either optical-black or digital clamp. Configure and enable
538 * the selected clamp method.
539 */
540static void ccdc_configure_clamp(struct isp_ccdc_device *ccdc)
541{
542 struct isp_device *isp = to_isp_device(ccdc);
543 u32 clamp;
544
545 if (ccdc->obclamp) {
546 clamp = ccdc->clamp.obgain << ISPCCDC_CLAMP_OBGAIN_SHIFT;
547 clamp |= ccdc->clamp.oblen << ISPCCDC_CLAMP_OBSLEN_SHIFT;
548 clamp |= ccdc->clamp.oblines << ISPCCDC_CLAMP_OBSLN_SHIFT;
549 clamp |= ccdc->clamp.obstpixel << ISPCCDC_CLAMP_OBST_SHIFT;
550 isp_reg_writel(isp, clamp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP);
551 } else {
552 isp_reg_writel(isp, ccdc->clamp.dcsubval,
553 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_DCSUB);
554 }
555
556 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CLAMP,
557 ISPCCDC_CLAMP_CLAMPEN,
558 ccdc->obclamp ? ISPCCDC_CLAMP_CLAMPEN : 0);
559}
560
561/*
562 * ccdc_configure_fpc - Configure Faulty Pixel Correction
563 * @ccdc: Pointer to ISP CCDC device.
564 */
565static void ccdc_configure_fpc(struct isp_ccdc_device *ccdc)
566{
567 struct isp_device *isp = to_isp_device(ccdc);
568
569 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC, ISPCCDC_FPC_FPCEN);
570
571 if (!ccdc->fpc_en)
572 return;
573
574 isp_reg_writel(isp, ccdc->fpc.fpcaddr, OMAP3_ISP_IOMEM_CCDC,
575 ISPCCDC_FPC_ADDR);
576 /* The FPNUM field must be set before enabling FPC. */
577 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT),
578 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
579 isp_reg_writel(isp, (ccdc->fpc.fpnum << ISPCCDC_FPC_FPNUM_SHIFT) |
580 ISPCCDC_FPC_FPCEN, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FPC);
581}
582
583/*
584 * ccdc_configure_black_comp - Configure Black Level Compensation.
585 * @ccdc: Pointer to ISP CCDC device.
586 */
587static void ccdc_configure_black_comp(struct isp_ccdc_device *ccdc)
588{
589 struct isp_device *isp = to_isp_device(ccdc);
590 u32 blcomp;
591
592 blcomp = ccdc->blcomp.b_mg << ISPCCDC_BLKCMP_B_MG_SHIFT;
593 blcomp |= ccdc->blcomp.gb_g << ISPCCDC_BLKCMP_GB_G_SHIFT;
594 blcomp |= ccdc->blcomp.gr_cy << ISPCCDC_BLKCMP_GR_CY_SHIFT;
595 blcomp |= ccdc->blcomp.r_ye << ISPCCDC_BLKCMP_R_YE_SHIFT;
596
597 isp_reg_writel(isp, blcomp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_BLKCMP);
598}
599
600/*
601 * ccdc_configure_lpf - Configure Low-Pass Filter (LPF).
602 * @ccdc: Pointer to ISP CCDC device.
603 */
604static void ccdc_configure_lpf(struct isp_ccdc_device *ccdc)
605{
606 struct isp_device *isp = to_isp_device(ccdc);
607
608 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE,
609 ISPCCDC_SYN_MODE_LPF,
610 ccdc->lpf ? ISPCCDC_SYN_MODE_LPF : 0);
611}
612
613/*
614 * ccdc_configure_alaw - Configure A-law compression.
615 * @ccdc: Pointer to ISP CCDC device.
616 */
617static void ccdc_configure_alaw(struct isp_ccdc_device *ccdc)
618{
619 struct isp_device *isp = to_isp_device(ccdc);
620 u32 alaw = 0;
621
622 switch (ccdc->syncif.datsz) {
623 case 8:
624 return;
625
626 case 10:
627 alaw = ISPCCDC_ALAW_GWDI_9_0;
628 break;
629 case 11:
630 alaw = ISPCCDC_ALAW_GWDI_10_1;
631 break;
632 case 12:
633 alaw = ISPCCDC_ALAW_GWDI_11_2;
634 break;
635 case 13:
636 alaw = ISPCCDC_ALAW_GWDI_12_3;
637 break;
638 }
639
640 if (ccdc->alaw)
641 alaw |= ISPCCDC_ALAW_CCDTBL;
642
643 isp_reg_writel(isp, alaw, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_ALAW);
644}
645
646/*
647 * ccdc_config_imgattr - Configure sensor image specific attributes.
648 * @ccdc: Pointer to ISP CCDC device.
649 * @colptn: Color pattern of the sensor.
650 */
651static void ccdc_config_imgattr(struct isp_ccdc_device *ccdc, u32 colptn)
652{
653 struct isp_device *isp = to_isp_device(ccdc);
654
655 isp_reg_writel(isp, colptn, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_COLPTN);
656}
657
658/*
659 * ccdc_config - Set CCDC configuration from userspace
660 * @ccdc: Pointer to ISP CCDC device.
661 * @userspace_add: Structure containing CCDC configuration sent from userspace.
662 *
663 * Returns 0 if successful, -EINVAL if the pointer to the configuration
664 * structure is null, or the copy_from_user function fails to copy user space
665 * memory to kernel space memory.
666 */
667static int ccdc_config(struct isp_ccdc_device *ccdc,
668 struct omap3isp_ccdc_update_config *ccdc_struct)
669{
670 struct isp_device *isp = to_isp_device(ccdc);
671 unsigned long flags;
672
673 spin_lock_irqsave(&ccdc->lock, flags);
674 ccdc->shadow_update = 1;
675 spin_unlock_irqrestore(&ccdc->lock, flags);
676
677 if (OMAP3ISP_CCDC_ALAW & ccdc_struct->update) {
678 ccdc->alaw = !!(OMAP3ISP_CCDC_ALAW & ccdc_struct->flag);
679 ccdc->update |= OMAP3ISP_CCDC_ALAW;
680 }
681
682 if (OMAP3ISP_CCDC_LPF & ccdc_struct->update) {
683 ccdc->lpf = !!(OMAP3ISP_CCDC_LPF & ccdc_struct->flag);
684 ccdc->update |= OMAP3ISP_CCDC_LPF;
685 }
686
687 if (OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->update) {
688 if (copy_from_user(&ccdc->clamp, ccdc_struct->bclamp,
689 sizeof(ccdc->clamp))) {
690 ccdc->shadow_update = 0;
691 return -EFAULT;
692 }
693
694 ccdc->obclamp = !!(OMAP3ISP_CCDC_BLCLAMP & ccdc_struct->flag);
695 ccdc->update |= OMAP3ISP_CCDC_BLCLAMP;
696 }
697
698 if (OMAP3ISP_CCDC_BCOMP & ccdc_struct->update) {
699 if (copy_from_user(&ccdc->blcomp, ccdc_struct->blcomp,
700 sizeof(ccdc->blcomp))) {
701 ccdc->shadow_update = 0;
702 return -EFAULT;
703 }
704
705 ccdc->update |= OMAP3ISP_CCDC_BCOMP;
706 }
707
708 ccdc->shadow_update = 0;
709
710 if (OMAP3ISP_CCDC_FPC & ccdc_struct->update) {
711 u32 table_old = 0;
712 u32 table_new;
713 u32 size;
714
715 if (ccdc->state != ISP_PIPELINE_STREAM_STOPPED)
716 return -EBUSY;
717
718 ccdc->fpc_en = !!(OMAP3ISP_CCDC_FPC & ccdc_struct->flag);
719
720 if (ccdc->fpc_en) {
721 if (copy_from_user(&ccdc->fpc, ccdc_struct->fpc,
722 sizeof(ccdc->fpc)))
723 return -EFAULT;
724
725 /*
726 * table_new must be 64-bytes aligned, but it's
727 * already done by iommu_vmalloc().
728 */
729 size = ccdc->fpc.fpnum * 4;
730 table_new = iommu_vmalloc(isp->iommu, 0, size,
731 IOMMU_FLAG);
732 if (IS_ERR_VALUE(table_new))
733 return -ENOMEM;
734
735 if (copy_from_user(da_to_va(isp->iommu, table_new),
736 (__force void __user *)
737 ccdc->fpc.fpcaddr, size)) {
738 iommu_vfree(isp->iommu, table_new);
739 return -EFAULT;
740 }
741
742 table_old = ccdc->fpc.fpcaddr;
743 ccdc->fpc.fpcaddr = table_new;
744 }
745
746 ccdc_configure_fpc(ccdc);
747 if (table_old != 0)
748 iommu_vfree(isp->iommu, table_old);
749 }
750
751 return ccdc_lsc_config(ccdc, ccdc_struct);
752}
753
754static void ccdc_apply_controls(struct isp_ccdc_device *ccdc)
755{
756 if (ccdc->update & OMAP3ISP_CCDC_ALAW) {
757 ccdc_configure_alaw(ccdc);
758 ccdc->update &= ~OMAP3ISP_CCDC_ALAW;
759 }
760
761 if (ccdc->update & OMAP3ISP_CCDC_LPF) {
762 ccdc_configure_lpf(ccdc);
763 ccdc->update &= ~OMAP3ISP_CCDC_LPF;
764 }
765
766 if (ccdc->update & OMAP3ISP_CCDC_BLCLAMP) {
767 ccdc_configure_clamp(ccdc);
768 ccdc->update &= ~OMAP3ISP_CCDC_BLCLAMP;
769 }
770
771 if (ccdc->update & OMAP3ISP_CCDC_BCOMP) {
772 ccdc_configure_black_comp(ccdc);
773 ccdc->update &= ~OMAP3ISP_CCDC_BCOMP;
774 }
775}
776
777/*
778 * omap3isp_ccdc_restore_context - Restore values of the CCDC module registers
779 * @dev: Pointer to ISP device
780 */
781void omap3isp_ccdc_restore_context(struct isp_device *isp)
782{
783 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
784
785 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG, ISPCCDC_CFG_VDLC);
786
787 ccdc->update = OMAP3ISP_CCDC_ALAW | OMAP3ISP_CCDC_LPF
788 | OMAP3ISP_CCDC_BLCLAMP | OMAP3ISP_CCDC_BCOMP;
789 ccdc_apply_controls(ccdc);
790 ccdc_configure_fpc(ccdc);
791}
792
793/* -----------------------------------------------------------------------------
794 * Format- and pipeline-related configuration helpers
795 */
796
797/*
798 * ccdc_config_vp - Configure the Video Port.
799 * @ccdc: Pointer to ISP CCDC device.
800 */
801static void ccdc_config_vp(struct isp_ccdc_device *ccdc)
802{
803 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
804 struct isp_device *isp = to_isp_device(ccdc);
805 unsigned long l3_ick = pipe->l3_ick;
806 unsigned int max_div = isp->revision == ISP_REVISION_15_0 ? 64 : 8;
807 unsigned int div = 0;
808 u32 fmtcfg_vp;
809
810 fmtcfg_vp = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG)
811 & ~(ISPCCDC_FMTCFG_VPIN_MASK | ISPCCDC_FMTCFG_VPIF_FRQ_MASK);
812
813 switch (ccdc->syncif.datsz) {
814 case 8:
815 case 10:
816 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_9_0;
817 break;
818 case 11:
819 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_10_1;
820 break;
821 case 12:
822 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_11_2;
823 break;
824 case 13:
825 fmtcfg_vp |= ISPCCDC_FMTCFG_VPIN_12_3;
826 break;
827 };
828
829 if (pipe->input)
830 div = DIV_ROUND_UP(l3_ick, pipe->max_rate);
831 else if (ccdc->vpcfg.pixelclk)
832 div = l3_ick / ccdc->vpcfg.pixelclk;
833
834 div = clamp(div, 2U, max_div);
835 fmtcfg_vp |= (div - 2) << ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT;
836
837 isp_reg_writel(isp, fmtcfg_vp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG);
838}
839
840/*
841 * ccdc_enable_vp - Enable Video Port.
842 * @ccdc: Pointer to ISP CCDC device.
843 * @enable: 0 Disables VP, 1 Enables VP
844 *
845 * This is needed for outputting image to Preview, H3A and HIST ISP submodules.
846 */
847static void ccdc_enable_vp(struct isp_ccdc_device *ccdc, u8 enable)
848{
849 struct isp_device *isp = to_isp_device(ccdc);
850
851 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMTCFG,
852 ISPCCDC_FMTCFG_VPEN, enable ? ISPCCDC_FMTCFG_VPEN : 0);
853}
854
855/*
856 * ccdc_config_outlineoffset - Configure memory saving output line offset
857 * @ccdc: Pointer to ISP CCDC device.
858 * @offset: Address offset to start a new line. Must be twice the
859 * Output width and aligned on 32 byte boundary
860 * @oddeven: Specifies the odd/even line pattern to be chosen to store the
861 * output.
862 * @numlines: Set the value 0-3 for +1-4lines, 4-7 for -1-4lines.
863 *
864 * - Configures the output line offset when stored in memory
865 * - Sets the odd/even line pattern to store the output
866 * (EVENEVEN (1), ODDEVEN (2), EVENODD (3), ODDODD (4))
867 * - Configures the number of even and odd line fields in case of rearranging
868 * the lines.
869 */
870static void ccdc_config_outlineoffset(struct isp_ccdc_device *ccdc,
871 u32 offset, u8 oddeven, u8 numlines)
872{
873 struct isp_device *isp = to_isp_device(ccdc);
874
875 isp_reg_writel(isp, offset & 0xffff,
876 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HSIZE_OFF);
877
878 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
879 ISPCCDC_SDOFST_FINV);
880
881 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
882 ISPCCDC_SDOFST_FOFST_4L);
883
884 switch (oddeven) {
885 case EVENEVEN:
886 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
887 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST0_SHIFT);
888 break;
889 case ODDEVEN:
890 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
891 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST1_SHIFT);
892 break;
893 case EVENODD:
894 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
895 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST2_SHIFT);
896 break;
897 case ODDODD:
898 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDOFST,
899 (numlines & 0x7) << ISPCCDC_SDOFST_LOFST3_SHIFT);
900 break;
901 default:
902 break;
903 }
904}
905
906/*
907 * ccdc_set_outaddr - Set memory address to save output image
908 * @ccdc: Pointer to ISP CCDC device.
909 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
910 *
911 * Sets the memory address where the output will be saved.
912 */
913static void ccdc_set_outaddr(struct isp_ccdc_device *ccdc, u32 addr)
914{
915 struct isp_device *isp = to_isp_device(ccdc);
916
917 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SDR_ADDR);
918}
919
920/*
921 * omap3isp_ccdc_max_rate - Calculate maximum input data rate based on the input
922 * @ccdc: Pointer to ISP CCDC device.
923 * @max_rate: Maximum calculated data rate.
924 *
925 * Returns in *max_rate less value between calculated and passed
926 */
927void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
928 unsigned int *max_rate)
929{
930 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
931 unsigned int rate;
932
933 if (pipe == NULL)
934 return;
935
936 /*
937 * TRM says that for parallel sensors the maximum data rate
938 * should be 90% form L3/2 clock, otherwise just L3/2.
939 */
940 if (ccdc->input == CCDC_INPUT_PARALLEL)
941 rate = pipe->l3_ick / 2 * 9 / 10;
942 else
943 rate = pipe->l3_ick / 2;
944
945 *max_rate = min(*max_rate, rate);
946}
947
948/*
949 * ccdc_config_sync_if - Set CCDC sync interface configuration
950 * @ccdc: Pointer to ISP CCDC device.
951 * @syncif: Structure containing the sync parameters like field state, CCDC in
952 * master/slave mode, raw/yuv data, polarity of data, field, hs, vs
953 * signals.
954 */
955static void ccdc_config_sync_if(struct isp_ccdc_device *ccdc,
956 struct ispccdc_syncif *syncif)
957{
958 struct isp_device *isp = to_isp_device(ccdc);
959 u32 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC,
960 ISPCCDC_SYN_MODE);
961
962 syn_mode |= ISPCCDC_SYN_MODE_VDHDEN;
963
964 if (syncif->fldstat)
965 syn_mode |= ISPCCDC_SYN_MODE_FLDSTAT;
966 else
967 syn_mode &= ~ISPCCDC_SYN_MODE_FLDSTAT;
968
969 syn_mode &= ~ISPCCDC_SYN_MODE_DATSIZ_MASK;
970 switch (syncif->datsz) {
971 case 8:
972 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_8;
973 break;
974 case 10:
975 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_10;
976 break;
977 case 11:
978 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_11;
979 break;
980 case 12:
981 syn_mode |= ISPCCDC_SYN_MODE_DATSIZ_12;
982 break;
983 };
984
985 if (syncif->fldmode)
986 syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
987 else
988 syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;
989
990 if (syncif->datapol)
991 syn_mode |= ISPCCDC_SYN_MODE_DATAPOL;
992 else
993 syn_mode &= ~ISPCCDC_SYN_MODE_DATAPOL;
994
995 if (syncif->fldpol)
996 syn_mode |= ISPCCDC_SYN_MODE_FLDPOL;
997 else
998 syn_mode &= ~ISPCCDC_SYN_MODE_FLDPOL;
999
1000 if (syncif->hdpol)
1001 syn_mode |= ISPCCDC_SYN_MODE_HDPOL;
1002 else
1003 syn_mode &= ~ISPCCDC_SYN_MODE_HDPOL;
1004
1005 if (syncif->vdpol)
1006 syn_mode |= ISPCCDC_SYN_MODE_VDPOL;
1007 else
1008 syn_mode &= ~ISPCCDC_SYN_MODE_VDPOL;
1009
1010 if (syncif->ccdc_mastermode) {
1011 syn_mode |= ISPCCDC_SYN_MODE_FLDOUT | ISPCCDC_SYN_MODE_VDHDOUT;
1012 isp_reg_writel(isp,
1013 syncif->hs_width << ISPCCDC_HD_VD_WID_HDW_SHIFT
1014 | syncif->vs_width << ISPCCDC_HD_VD_WID_VDW_SHIFT,
1015 OMAP3_ISP_IOMEM_CCDC,
1016 ISPCCDC_HD_VD_WID);
1017
1018 isp_reg_writel(isp,
1019 syncif->ppln << ISPCCDC_PIX_LINES_PPLN_SHIFT
1020 | syncif->hlprf << ISPCCDC_PIX_LINES_HLPRF_SHIFT,
1021 OMAP3_ISP_IOMEM_CCDC,
1022 ISPCCDC_PIX_LINES);
1023 } else
1024 syn_mode &= ~(ISPCCDC_SYN_MODE_FLDOUT |
1025 ISPCCDC_SYN_MODE_VDHDOUT);
1026
1027 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1028
1029 if (!syncif->bt_r656_en)
1030 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_REC656IF,
1031 ISPCCDC_REC656IF_R656ON);
1032}
1033
1034/* CCDC formats descriptions */
1035static const u32 ccdc_sgrbg_pattern =
1036 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1037 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1038 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1039 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1040 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1041 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1042 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1043 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1044 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1045 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1046 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1047 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1048 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1049 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1050 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1051 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1052
1053static const u32 ccdc_srggb_pattern =
1054 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1055 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1056 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1057 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1058 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1059 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1060 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1061 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1062 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1063 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1064 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1065 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1066 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1067 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1068 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1069 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1070
1071static const u32 ccdc_sbggr_pattern =
1072 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1073 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1074 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1075 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1076 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1077 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1078 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1079 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1080 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1081 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1082 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1083 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1084 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1085 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1086 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1087 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1088
1089static const u32 ccdc_sgbrg_pattern =
1090 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC0_SHIFT |
1091 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC1_SHIFT |
1092 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP0PLC2_SHIFT |
1093 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP0PLC3_SHIFT |
1094 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC0_SHIFT |
1095 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC1_SHIFT |
1096 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP1PLC2_SHIFT |
1097 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP1PLC3_SHIFT |
1098 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC0_SHIFT |
1099 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC1_SHIFT |
1100 ISPCCDC_COLPTN_Gb_G << ISPCCDC_COLPTN_CP2PLC2_SHIFT |
1101 ISPCCDC_COLPTN_B_Mg << ISPCCDC_COLPTN_CP2PLC3_SHIFT |
1102 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC0_SHIFT |
1103 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC1_SHIFT |
1104 ISPCCDC_COLPTN_R_Ye << ISPCCDC_COLPTN_CP3PLC2_SHIFT |
1105 ISPCCDC_COLPTN_Gr_Cy << ISPCCDC_COLPTN_CP3PLC3_SHIFT;
1106
1107static void ccdc_configure(struct isp_ccdc_device *ccdc)
1108{
1109 struct isp_device *isp = to_isp_device(ccdc);
1110 struct isp_parallel_platform_data *pdata = NULL;
1111 struct v4l2_subdev *sensor;
1112 struct v4l2_mbus_framefmt *format;
1113 struct media_pad *pad;
1114 unsigned long flags;
1115 u32 syn_mode;
1116 u32 ccdc_pattern;
1117
1118 if (ccdc->input == CCDC_INPUT_PARALLEL) {
1119 pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
1120 sensor = media_entity_to_v4l2_subdev(pad->entity);
1121 pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
1122 ->bus.parallel;
1123 }
1124
1125 omap3isp_configure_bridge(isp, ccdc->input, pdata);
1126
1127 ccdc->syncif.datsz = pdata ? pdata->width : 10;
1128 ccdc_config_sync_if(ccdc, &ccdc->syncif);
1129
1130 /* CCDC_PAD_SINK */
1131 format = &ccdc->formats[CCDC_PAD_SINK];
1132
1133 syn_mode = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1134
1135 /* Use the raw, unprocessed data when writing to memory. The H3A and
1136 * histogram modules are still fed with lens shading corrected data.
1137 */
1138 syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
1139
1140 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1141 syn_mode |= ISPCCDC_SYN_MODE_WEN;
1142 else
1143 syn_mode &= ~ISPCCDC_SYN_MODE_WEN;
1144
1145 if (ccdc->output & CCDC_OUTPUT_RESIZER)
1146 syn_mode |= ISPCCDC_SYN_MODE_SDR2RSZ;
1147 else
1148 syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
1149
1150 /* Use PACK8 mode for 1byte per pixel formats. */
1151 if (omap3isp_video_format_info(format->code)->bpp <= 8)
1152 syn_mode |= ISPCCDC_SYN_MODE_PACK8;
1153 else
1154 syn_mode &= ~ISPCCDC_SYN_MODE_PACK8;
1155
1156 isp_reg_writel(isp, syn_mode, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_SYN_MODE);
1157
1158 /* Mosaic filter */
1159 switch (format->code) {
1160 case V4L2_MBUS_FMT_SRGGB10_1X10:
1161 case V4L2_MBUS_FMT_SRGGB12_1X12:
1162 ccdc_pattern = ccdc_srggb_pattern;
1163 break;
1164 case V4L2_MBUS_FMT_SBGGR10_1X10:
1165 case V4L2_MBUS_FMT_SBGGR12_1X12:
1166 ccdc_pattern = ccdc_sbggr_pattern;
1167 break;
1168 case V4L2_MBUS_FMT_SGBRG10_1X10:
1169 case V4L2_MBUS_FMT_SGBRG12_1X12:
1170 ccdc_pattern = ccdc_sgbrg_pattern;
1171 break;
1172 default:
1173 /* Use GRBG */
1174 ccdc_pattern = ccdc_sgrbg_pattern;
1175 break;
1176 }
1177 ccdc_config_imgattr(ccdc, ccdc_pattern);
1178
1179 /* Generate VD0 on the last line of the image and VD1 on the
1180 * 2/3 height line.
1181 */
1182 isp_reg_writel(isp, ((format->height - 2) << ISPCCDC_VDINT_0_SHIFT) |
1183 ((format->height * 2 / 3) << ISPCCDC_VDINT_1_SHIFT),
1184 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VDINT);
1185
1186 /* CCDC_PAD_SOURCE_OF */
1187 format = &ccdc->formats[CCDC_PAD_SOURCE_OF];
1188
1189 isp_reg_writel(isp, (0 << ISPCCDC_HORZ_INFO_SPH_SHIFT) |
1190 ((format->width - 1) << ISPCCDC_HORZ_INFO_NPH_SHIFT),
1191 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_HORZ_INFO);
1192 isp_reg_writel(isp, 0 << ISPCCDC_VERT_START_SLV0_SHIFT,
1193 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_START);
1194 isp_reg_writel(isp, (format->height - 1)
1195 << ISPCCDC_VERT_LINES_NLV_SHIFT,
1196 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VERT_LINES);
1197
1198 ccdc_config_outlineoffset(ccdc, ccdc->video_out.bpl_value, 0, 0);
1199
1200 /* CCDC_PAD_SOURCE_VP */
1201 format = &ccdc->formats[CCDC_PAD_SOURCE_VP];
1202
1203 isp_reg_writel(isp, (0 << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) |
1204 (format->width << ISPCCDC_FMT_HORZ_FMTLNH_SHIFT),
1205 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_HORZ);
1206 isp_reg_writel(isp, (0 << ISPCCDC_FMT_VERT_FMTSLV_SHIFT) |
1207 ((format->height + 1) << ISPCCDC_FMT_VERT_FMTLNV_SHIFT),
1208 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_FMT_VERT);
1209
1210 isp_reg_writel(isp, (format->width << ISPCCDC_VP_OUT_HORZ_NUM_SHIFT) |
1211 (format->height << ISPCCDC_VP_OUT_VERT_NUM_SHIFT),
1212 OMAP3_ISP_IOMEM_CCDC, ISPCCDC_VP_OUT);
1213
1214 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1215 if (ccdc->lsc.request == NULL)
1216 goto unlock;
1217
1218 WARN_ON(ccdc->lsc.active);
1219
1220 /* Get last good LSC configuration. If it is not supported for
1221 * the current active resolution discard it.
1222 */
1223 if (ccdc->lsc.active == NULL &&
1224 __ccdc_lsc_configure(ccdc, ccdc->lsc.request) == 0) {
1225 ccdc->lsc.active = ccdc->lsc.request;
1226 } else {
1227 list_add_tail(&ccdc->lsc.request->list, &ccdc->lsc.free_queue);
1228 schedule_work(&ccdc->lsc.table_work);
1229 }
1230
1231 ccdc->lsc.request = NULL;
1232
1233unlock:
1234 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1235
1236 ccdc_apply_controls(ccdc);
1237}
1238
1239static void __ccdc_enable(struct isp_ccdc_device *ccdc, int enable)
1240{
1241 struct isp_device *isp = to_isp_device(ccdc);
1242
1243 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_PCR,
1244 ISPCCDC_PCR_EN, enable ? ISPCCDC_PCR_EN : 0);
1245}
1246
1247static int ccdc_disable(struct isp_ccdc_device *ccdc)
1248{
1249 unsigned long flags;
1250 int ret = 0;
1251
1252 spin_lock_irqsave(&ccdc->lock, flags);
1253 if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1254 ccdc->stopping = CCDC_STOP_REQUEST;
1255 spin_unlock_irqrestore(&ccdc->lock, flags);
1256
1257 ret = wait_event_timeout(ccdc->wait,
1258 ccdc->stopping == CCDC_STOP_FINISHED,
1259 msecs_to_jiffies(2000));
1260 if (ret == 0) {
1261 ret = -ETIMEDOUT;
1262 dev_warn(to_device(ccdc), "CCDC stop timeout!\n");
1263 }
1264
1265 omap3isp_sbl_disable(to_isp_device(ccdc), OMAP3_ISP_SBL_CCDC_LSC_READ);
1266
1267 mutex_lock(&ccdc->ioctl_lock);
1268 ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
1269 ccdc->lsc.request = ccdc->lsc.active;
1270 ccdc->lsc.active = NULL;
1271 cancel_work_sync(&ccdc->lsc.table_work);
1272 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
1273 mutex_unlock(&ccdc->ioctl_lock);
1274
1275 ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
1276
1277 return ret > 0 ? 0 : ret;
1278}
1279
1280static void ccdc_enable(struct isp_ccdc_device *ccdc)
1281{
1282 if (ccdc_lsc_is_configured(ccdc))
1283 __ccdc_lsc_enable(ccdc, 1);
1284 __ccdc_enable(ccdc, 1);
1285}
1286
1287/* -----------------------------------------------------------------------------
1288 * Interrupt handling
1289 */
1290
1291/*
1292 * ccdc_sbl_busy - Poll idle state of CCDC and related SBL memory write bits
1293 * @ccdc: Pointer to ISP CCDC device.
1294 *
1295 * Returns zero if the CCDC is idle and the image has been written to
1296 * memory, too.
1297 */
1298static int ccdc_sbl_busy(struct isp_ccdc_device *ccdc)
1299{
1300 struct isp_device *isp = to_isp_device(ccdc);
1301
1302 return omap3isp_ccdc_busy(ccdc)
1303 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_0) &
1304 ISPSBL_CCDC_WR_0_DATA_READY)
1305 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_1) &
1306 ISPSBL_CCDC_WR_0_DATA_READY)
1307 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_2) &
1308 ISPSBL_CCDC_WR_0_DATA_READY)
1309 | (isp_reg_readl(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_CCDC_WR_3) &
1310 ISPSBL_CCDC_WR_0_DATA_READY);
1311}
1312
1313/*
1314 * ccdc_sbl_wait_idle - Wait until the CCDC and related SBL are idle
1315 * @ccdc: Pointer to ISP CCDC device.
1316 * @max_wait: Max retry count in us for wait for idle/busy transition.
1317 */
1318static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
1319 unsigned int max_wait)
1320{
1321 unsigned int wait = 0;
1322
1323 if (max_wait == 0)
1324 max_wait = 10000; /* 10 ms */
1325
1326 for (wait = 0; wait <= max_wait; wait++) {
1327 if (!ccdc_sbl_busy(ccdc))
1328 return 0;
1329
1330 rmb();
1331 udelay(1);
1332 }
1333
1334 return -EBUSY;
1335}
1336
1337/* __ccdc_handle_stopping - Handle CCDC and/or LSC stopping sequence
1338 * @ccdc: Pointer to ISP CCDC device.
1339 * @event: Pointing which event trigger handler
1340 *
1341 * Return 1 when the event and stopping request combination is satisfyied,
1342 * zero otherwise.
1343 */
1344static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
1345{
1346 int rval = 0;
1347
1348 switch ((ccdc->stopping & 3) | event) {
1349 case CCDC_STOP_REQUEST | CCDC_EVENT_VD1:
1350 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1351 __ccdc_lsc_enable(ccdc, 0);
1352 __ccdc_enable(ccdc, 0);
1353 ccdc->stopping = CCDC_STOP_EXECUTED;
1354 return 1;
1355
1356 case CCDC_STOP_EXECUTED | CCDC_EVENT_VD0:
1357 ccdc->stopping |= CCDC_STOP_CCDC_FINISHED;
1358 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1359 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1360 rval = 1;
1361 break;
1362
1363 case CCDC_STOP_EXECUTED | CCDC_EVENT_LSC_DONE:
1364 ccdc->stopping |= CCDC_STOP_LSC_FINISHED;
1365 rval = 1;
1366 break;
1367
1368 case CCDC_STOP_EXECUTED | CCDC_EVENT_VD1:
1369 return 1;
1370 }
1371
1372 if (ccdc->stopping == CCDC_STOP_FINISHED) {
1373 wake_up(&ccdc->wait);
1374 rval = 1;
1375 }
1376
1377 return rval;
1378}
1379
1380static void ccdc_hs_vs_isr(struct isp_ccdc_device *ccdc)
1381{
1382 struct video_device *vdev = &ccdc->subdev.devnode;
1383 struct v4l2_event event;
1384
1385 memset(&event, 0, sizeof(event));
1386 event.type = V4L2_EVENT_OMAP3ISP_HS_VS;
1387
1388 v4l2_event_queue(vdev, &event);
1389}
1390
1391/*
1392 * ccdc_lsc_isr - Handle LSC events
1393 * @ccdc: Pointer to ISP CCDC device.
1394 * @events: LSC events
1395 */
1396static void ccdc_lsc_isr(struct isp_ccdc_device *ccdc, u32 events)
1397{
1398 unsigned long flags;
1399
1400 if (events & IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ) {
1401 ccdc_lsc_error_handler(ccdc);
1402 ccdc->error = 1;
1403 dev_dbg(to_device(ccdc), "lsc prefetch error\n");
1404 }
1405
1406 if (!(events & IRQ0STATUS_CCDC_LSC_DONE_IRQ))
1407 return;
1408
1409 /* LSC_DONE interrupt occur, there are two cases
1410 * 1. stopping for reconfiguration
1411 * 2. stopping because of STREAM OFF command
1412 */
1413 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1414
1415 if (ccdc->lsc.state == LSC_STATE_STOPPING)
1416 ccdc->lsc.state = LSC_STATE_STOPPED;
1417
1418 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_LSC_DONE))
1419 goto done;
1420
1421 if (ccdc->lsc.state != LSC_STATE_RECONFIG)
1422 goto done;
1423
1424 /* LSC is in STOPPING state, change to the new state */
1425 ccdc->lsc.state = LSC_STATE_STOPPED;
1426
1427 /* This is an exception. Start of frame and LSC_DONE interrupt
1428 * have been received on the same time. Skip this event and wait
1429 * for better times.
1430 */
1431 if (events & IRQ0STATUS_HS_VS_IRQ)
1432 goto done;
1433
1434 /* The LSC engine is stopped at this point. Enable it if there's a
1435 * pending request.
1436 */
1437 if (ccdc->lsc.request == NULL)
1438 goto done;
1439
1440 ccdc_lsc_enable(ccdc);
1441
1442done:
1443 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1444}
1445
1446static int ccdc_isr_buffer(struct isp_ccdc_device *ccdc)
1447{
1448 struct isp_pipeline *pipe = to_isp_pipeline(&ccdc->subdev.entity);
1449 struct isp_device *isp = to_isp_device(ccdc);
1450 struct isp_buffer *buffer;
1451 int restart = 0;
1452
1453 /* The CCDC generates VD0 interrupts even when disabled (the datasheet
1454 * doesn't explicitly state if that's supposed to happen or not, so it
1455 * can be considered as a hardware bug or as a feature, but we have to
1456 * deal with it anyway). Disabling the CCDC when no buffer is available
1457 * would thus not be enough, we need to handle the situation explicitly.
1458 */
1459 if (list_empty(&ccdc->video_out.dmaqueue))
1460 goto done;
1461
1462 /* We're in continuous mode, and memory writes were disabled due to a
1463 * buffer underrun. Reenable them now that we have a buffer. The buffer
1464 * address has been set in ccdc_video_queue.
1465 */
1466 if (ccdc->state == ISP_PIPELINE_STREAM_CONTINUOUS && ccdc->underrun) {
1467 restart = 1;
1468 ccdc->underrun = 0;
1469 goto done;
1470 }
1471
1472 if (ccdc_sbl_wait_idle(ccdc, 1000)) {
1473 dev_info(isp->dev, "CCDC won't become idle!\n");
1474 goto done;
1475 }
1476
1477 buffer = omap3isp_video_buffer_next(&ccdc->video_out, ccdc->error);
1478 if (buffer != NULL) {
1479 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1480 restart = 1;
1481 }
1482
1483 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1484
1485 if (ccdc->state == ISP_PIPELINE_STREAM_SINGLESHOT &&
1486 isp_pipeline_ready(pipe))
1487 omap3isp_pipeline_set_stream(pipe,
1488 ISP_PIPELINE_STREAM_SINGLESHOT);
1489
1490done:
1491 ccdc->error = 0;
1492 return restart;
1493}
1494
1495/*
1496 * ccdc_vd0_isr - Handle VD0 event
1497 * @ccdc: Pointer to ISP CCDC device.
1498 *
1499 * Executes LSC deferred enablement before next frame starts.
1500 */
1501static void ccdc_vd0_isr(struct isp_ccdc_device *ccdc)
1502{
1503 unsigned long flags;
1504 int restart = 0;
1505
1506 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1507 restart = ccdc_isr_buffer(ccdc);
1508
1509 spin_lock_irqsave(&ccdc->lock, flags);
1510 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD0)) {
1511 spin_unlock_irqrestore(&ccdc->lock, flags);
1512 return;
1513 }
1514
1515 if (!ccdc->shadow_update)
1516 ccdc_apply_controls(ccdc);
1517 spin_unlock_irqrestore(&ccdc->lock, flags);
1518
1519 if (restart)
1520 ccdc_enable(ccdc);
1521}
1522
1523/*
1524 * ccdc_vd1_isr - Handle VD1 event
1525 * @ccdc: Pointer to ISP CCDC device.
1526 */
1527static void ccdc_vd1_isr(struct isp_ccdc_device *ccdc)
1528{
1529 unsigned long flags;
1530
1531 spin_lock_irqsave(&ccdc->lsc.req_lock, flags);
1532
1533 /*
1534 * Depending on the CCDC pipeline state, CCDC stopping should be
1535 * handled differently. In SINGLESHOT we emulate an internal CCDC
1536 * stopping because the CCDC hw works only in continuous mode.
1537 * When CONTINUOUS pipeline state is used and the CCDC writes it's
1538 * data to memory the CCDC and LSC are stopped immediately but
1539 * without change the CCDC stopping state machine. The CCDC
1540 * stopping state machine should be used only when user request
1541 * for stopping is received (SINGLESHOT is an exeption).
1542 */
1543 switch (ccdc->state) {
1544 case ISP_PIPELINE_STREAM_SINGLESHOT:
1545 ccdc->stopping = CCDC_STOP_REQUEST;
1546 break;
1547
1548 case ISP_PIPELINE_STREAM_CONTINUOUS:
1549 if (ccdc->output & CCDC_OUTPUT_MEMORY) {
1550 if (ccdc->lsc.state != LSC_STATE_STOPPED)
1551 __ccdc_lsc_enable(ccdc, 0);
1552 __ccdc_enable(ccdc, 0);
1553 }
1554 break;
1555
1556 case ISP_PIPELINE_STREAM_STOPPED:
1557 break;
1558 }
1559
1560 if (__ccdc_handle_stopping(ccdc, CCDC_EVENT_VD1))
1561 goto done;
1562
1563 if (ccdc->lsc.request == NULL)
1564 goto done;
1565
1566 /*
1567 * LSC need to be reconfigured. Stop it here and on next LSC_DONE IRQ
1568 * do the appropriate changes in registers
1569 */
1570 if (ccdc->lsc.state == LSC_STATE_RUNNING) {
1571 __ccdc_lsc_enable(ccdc, 0);
1572 ccdc->lsc.state = LSC_STATE_RECONFIG;
1573 goto done;
1574 }
1575
1576 /* LSC has been in STOPPED state, enable it */
1577 if (ccdc->lsc.state == LSC_STATE_STOPPED)
1578 ccdc_lsc_enable(ccdc);
1579
1580done:
1581 spin_unlock_irqrestore(&ccdc->lsc.req_lock, flags);
1582}
1583
1584/*
1585 * omap3isp_ccdc_isr - Configure CCDC during interframe time.
1586 * @ccdc: Pointer to ISP CCDC device.
1587 * @events: CCDC events
1588 */
1589int omap3isp_ccdc_isr(struct isp_ccdc_device *ccdc, u32 events)
1590{
1591 if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED)
1592 return 0;
1593
1594 if (events & IRQ0STATUS_CCDC_VD1_IRQ)
1595 ccdc_vd1_isr(ccdc);
1596
1597 ccdc_lsc_isr(ccdc, events);
1598
1599 if (events & IRQ0STATUS_CCDC_VD0_IRQ)
1600 ccdc_vd0_isr(ccdc);
1601
1602 if (events & IRQ0STATUS_HS_VS_IRQ)
1603 ccdc_hs_vs_isr(ccdc);
1604
1605 return 0;
1606}
1607
1608/* -----------------------------------------------------------------------------
1609 * ISP video operations
1610 */
1611
1612static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
1613{
1614 struct isp_ccdc_device *ccdc = &video->isp->isp_ccdc;
1615
1616 if (!(ccdc->output & CCDC_OUTPUT_MEMORY))
1617 return -ENODEV;
1618
1619 ccdc_set_outaddr(ccdc, buffer->isp_addr);
1620
1621 /* We now have a buffer queued on the output, restart the pipeline in
1622 * on the next CCDC interrupt if running in continuous mode (or when
1623 * starting the stream).
1624 */
1625 ccdc->underrun = 1;
1626
1627 return 0;
1628}
1629
1630static const struct isp_video_operations ccdc_video_ops = {
1631 .queue = ccdc_video_queue,
1632};
1633
1634/* -----------------------------------------------------------------------------
1635 * V4L2 subdev operations
1636 */
1637
1638/*
1639 * ccdc_ioctl - CCDC module private ioctl's
1640 * @sd: ISP CCDC V4L2 subdevice
1641 * @cmd: ioctl command
1642 * @arg: ioctl argument
1643 *
1644 * Return 0 on success or a negative error code otherwise.
1645 */
1646static long ccdc_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1647{
1648 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1649 int ret;
1650
1651 switch (cmd) {
1652 case VIDIOC_OMAP3ISP_CCDC_CFG:
1653 mutex_lock(&ccdc->ioctl_lock);
1654 ret = ccdc_config(ccdc, arg);
1655 mutex_unlock(&ccdc->ioctl_lock);
1656 break;
1657
1658 default:
1659 return -ENOIOCTLCMD;
1660 }
1661
1662 return ret;
1663}
1664
1665static int ccdc_subscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1666 struct v4l2_event_subscription *sub)
1667{
1668 if (sub->type != V4L2_EVENT_OMAP3ISP_HS_VS)
1669 return -EINVAL;
1670
1671 return v4l2_event_subscribe(fh, sub);
1672}
1673
1674static int ccdc_unsubscribe_event(struct v4l2_subdev *sd, struct v4l2_fh *fh,
1675 struct v4l2_event_subscription *sub)
1676{
1677 return v4l2_event_unsubscribe(fh, sub);
1678}
1679
1680/*
1681 * ccdc_set_stream - Enable/Disable streaming on the CCDC module
1682 * @sd: ISP CCDC V4L2 subdevice
1683 * @enable: Enable/disable stream
1684 *
1685 * When writing to memory, the CCDC hardware can't be enabled without a memory
1686 * buffer to write to. As the s_stream operation is called in response to a
1687 * STREAMON call without any buffer queued yet, just update the enabled field
1688 * and return immediately. The CCDC will be enabled in ccdc_isr_buffer().
1689 *
1690 * When not writing to memory enable the CCDC immediately.
1691 */
1692static int ccdc_set_stream(struct v4l2_subdev *sd, int enable)
1693{
1694 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1695 struct isp_device *isp = to_isp_device(ccdc);
1696 int ret = 0;
1697
1698 if (ccdc->state == ISP_PIPELINE_STREAM_STOPPED) {
1699 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1700 return 0;
1701
1702 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_CCDC);
1703 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCDC, ISPCCDC_CFG,
1704 ISPCCDC_CFG_VDLC);
1705
1706 ccdc_configure(ccdc);
1707
1708 /* TODO: Don't configure the video port if all of its output
1709 * links are inactive.
1710 */
1711 ccdc_config_vp(ccdc);
1712 ccdc_enable_vp(ccdc, 1);
1713 ccdc->error = 0;
1714 ccdc_print_status(ccdc);
1715 }
1716
1717 switch (enable) {
1718 case ISP_PIPELINE_STREAM_CONTINUOUS:
1719 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1720 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1721
1722 if (ccdc->underrun || !(ccdc->output & CCDC_OUTPUT_MEMORY))
1723 ccdc_enable(ccdc);
1724
1725 ccdc->underrun = 0;
1726 break;
1727
1728 case ISP_PIPELINE_STREAM_SINGLESHOT:
1729 if (ccdc->output & CCDC_OUTPUT_MEMORY &&
1730 ccdc->state != ISP_PIPELINE_STREAM_SINGLESHOT)
1731 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1732
1733 ccdc_enable(ccdc);
1734 break;
1735
1736 case ISP_PIPELINE_STREAM_STOPPED:
1737 ret = ccdc_disable(ccdc);
1738 if (ccdc->output & CCDC_OUTPUT_MEMORY)
1739 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CCDC_WRITE);
1740 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_CCDC);
1741 ccdc->underrun = 0;
1742 break;
1743 }
1744
1745 ccdc->state = enable;
1746 return ret;
1747}
1748
1749static struct v4l2_mbus_framefmt *
1750__ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1751 unsigned int pad, enum v4l2_subdev_format_whence which)
1752{
1753 if (which == V4L2_SUBDEV_FORMAT_TRY)
1754 return v4l2_subdev_get_try_format(fh, pad);
1755 else
1756 return &ccdc->formats[pad];
1757}
1758
1759/*
1760 * ccdc_try_format - Try video format on a pad
1761 * @ccdc: ISP CCDC device
1762 * @fh : V4L2 subdev file handle
1763 * @pad: Pad number
1764 * @fmt: Format
1765 */
1766static void
1767ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1768 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
1769 enum v4l2_subdev_format_whence which)
1770{
1771 struct v4l2_mbus_framefmt *format;
1772 const struct isp_format_info *info;
1773 unsigned int width = fmt->width;
1774 unsigned int height = fmt->height;
1775 unsigned int i;
1776
1777 switch (pad) {
1778 case CCDC_PAD_SINK:
1779 /* TODO: If the CCDC output formatter pad is connected directly
1780 * to the resizer, only YUV formats can be used.
1781 */
1782 for (i = 0; i < ARRAY_SIZE(ccdc_fmts); i++) {
1783 if (fmt->code == ccdc_fmts[i])
1784 break;
1785 }
1786
1787 /* If not found, use SGRBG10 as default */
1788 if (i >= ARRAY_SIZE(ccdc_fmts))
1789 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1790
1791 /* Clamp the input size. */
1792 fmt->width = clamp_t(u32, width, 32, 4096);
1793 fmt->height = clamp_t(u32, height, 32, 4096);
1794 break;
1795
1796 case CCDC_PAD_SOURCE_OF:
1797 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1798 memcpy(fmt, format, sizeof(*fmt));
1799
1800 /* The data formatter truncates the number of horizontal output
1801 * pixels to a multiple of 16. To avoid clipping data, allow
1802 * callers to request an output size bigger than the input size
1803 * up to the nearest multiple of 16.
1804 */
1805 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15);
1806 fmt->width &= ~15;
1807 fmt->height = clamp_t(u32, height, 32, fmt->height);
1808 break;
1809
1810 case CCDC_PAD_SOURCE_VP:
1811 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK, which);
1812 memcpy(fmt, format, sizeof(*fmt));
1813
1814 /* The video port interface truncates the data to 10 bits. */
1815 info = omap3isp_video_format_info(fmt->code);
1816 fmt->code = info->truncated;
1817
1818 /* The number of lines that can be clocked out from the video
1819 * port output must be at least one line less than the number
1820 * of input lines.
1821 */
1822 fmt->width = clamp_t(u32, width, 32, fmt->width);
1823 fmt->height = clamp_t(u32, height, 32, fmt->height - 1);
1824 break;
1825 }
1826
1827 /* Data is written to memory unpacked, each 10-bit or 12-bit pixel is
1828 * stored on 2 bytes.
1829 */
1830 fmt->colorspace = V4L2_COLORSPACE_SRGB;
1831 fmt->field = V4L2_FIELD_NONE;
1832}
1833
1834/*
1835 * ccdc_enum_mbus_code - Handle pixel format enumeration
1836 * @sd : pointer to v4l2 subdev structure
1837 * @fh : V4L2 subdev file handle
1838 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1839 * return -EINVAL or zero on success
1840 */
1841static int ccdc_enum_mbus_code(struct v4l2_subdev *sd,
1842 struct v4l2_subdev_fh *fh,
1843 struct v4l2_subdev_mbus_code_enum *code)
1844{
1845 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1846 struct v4l2_mbus_framefmt *format;
1847
1848 switch (code->pad) {
1849 case CCDC_PAD_SINK:
1850 if (code->index >= ARRAY_SIZE(ccdc_fmts))
1851 return -EINVAL;
1852
1853 code->code = ccdc_fmts[code->index];
1854 break;
1855
1856 case CCDC_PAD_SOURCE_OF:
1857 case CCDC_PAD_SOURCE_VP:
1858 /* No format conversion inside CCDC */
1859 if (code->index != 0)
1860 return -EINVAL;
1861
1862 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SINK,
1863 V4L2_SUBDEV_FORMAT_TRY);
1864
1865 code->code = format->code;
1866 break;
1867
1868 default:
1869 return -EINVAL;
1870 }
1871
1872 return 0;
1873}
1874
1875static int ccdc_enum_frame_size(struct v4l2_subdev *sd,
1876 struct v4l2_subdev_fh *fh,
1877 struct v4l2_subdev_frame_size_enum *fse)
1878{
1879 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1880 struct v4l2_mbus_framefmt format;
1881
1882 if (fse->index != 0)
1883 return -EINVAL;
1884
1885 format.code = fse->code;
1886 format.width = 1;
1887 format.height = 1;
1888 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1889 fse->min_width = format.width;
1890 fse->min_height = format.height;
1891
1892 if (format.code != fse->code)
1893 return -EINVAL;
1894
1895 format.code = fse->code;
1896 format.width = -1;
1897 format.height = -1;
1898 ccdc_try_format(ccdc, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1899 fse->max_width = format.width;
1900 fse->max_height = format.height;
1901
1902 return 0;
1903}
1904
1905/*
1906 * ccdc_get_format - Retrieve the video format on a pad
1907 * @sd : ISP CCDC V4L2 subdevice
1908 * @fh : V4L2 subdev file handle
1909 * @fmt: Format
1910 *
1911 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
1912 * to the format type.
1913 */
1914static int ccdc_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1915 struct v4l2_subdev_format *fmt)
1916{
1917 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1918 struct v4l2_mbus_framefmt *format;
1919
1920 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1921 if (format == NULL)
1922 return -EINVAL;
1923
1924 fmt->format = *format;
1925 return 0;
1926}
1927
1928/*
1929 * ccdc_set_format - Set the video format on a pad
1930 * @sd : ISP CCDC V4L2 subdevice
1931 * @fh : V4L2 subdev file handle
1932 * @fmt: Format
1933 *
1934 * Return 0 on success or -EINVAL if the pad is invalid or doesn't correspond
1935 * to the format type.
1936 */
1937static int ccdc_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1938 struct v4l2_subdev_format *fmt)
1939{
1940 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
1941 struct v4l2_mbus_framefmt *format;
1942
1943 format = __ccdc_get_format(ccdc, fh, fmt->pad, fmt->which);
1944 if (format == NULL)
1945 return -EINVAL;
1946
1947 ccdc_try_format(ccdc, fh, fmt->pad, &fmt->format, fmt->which);
1948 *format = fmt->format;
1949
1950 /* Propagate the format from sink to source */
1951 if (fmt->pad == CCDC_PAD_SINK) {
1952 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_OF,
1953 fmt->which);
1954 *format = fmt->format;
1955 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_OF, format,
1956 fmt->which);
1957
1958 format = __ccdc_get_format(ccdc, fh, CCDC_PAD_SOURCE_VP,
1959 fmt->which);
1960 *format = fmt->format;
1961 ccdc_try_format(ccdc, fh, CCDC_PAD_SOURCE_VP, format,
1962 fmt->which);
1963 }
1964
1965 return 0;
1966}
1967
1968/*
1969 * ccdc_init_formats - Initialize formats on all pads
1970 * @sd: ISP CCDC V4L2 subdevice
1971 * @fh: V4L2 subdev file handle
1972 *
1973 * Initialize all pad formats with default values. If fh is not NULL, try
1974 * formats are initialized on the file handle. Otherwise active formats are
1975 * initialized on the device.
1976 */
1977static int ccdc_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1978{
1979 struct v4l2_subdev_format format;
1980
1981 memset(&format, 0, sizeof(format));
1982 format.pad = CCDC_PAD_SINK;
1983 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1984 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1985 format.format.width = 4096;
1986 format.format.height = 4096;
1987 ccdc_set_format(sd, fh, &format);
1988
1989 return 0;
1990}
1991
1992/* V4L2 subdev core operations */
1993static const struct v4l2_subdev_core_ops ccdc_v4l2_core_ops = {
1994 .ioctl = ccdc_ioctl,
1995 .subscribe_event = ccdc_subscribe_event,
1996 .unsubscribe_event = ccdc_unsubscribe_event,
1997};
1998
1999/* V4L2 subdev video operations */
2000static const struct v4l2_subdev_video_ops ccdc_v4l2_video_ops = {
2001 .s_stream = ccdc_set_stream,
2002};
2003
2004/* V4L2 subdev pad operations */
2005static const struct v4l2_subdev_pad_ops ccdc_v4l2_pad_ops = {
2006 .enum_mbus_code = ccdc_enum_mbus_code,
2007 .enum_frame_size = ccdc_enum_frame_size,
2008 .get_fmt = ccdc_get_format,
2009 .set_fmt = ccdc_set_format,
2010};
2011
2012/* V4L2 subdev operations */
2013static const struct v4l2_subdev_ops ccdc_v4l2_ops = {
2014 .core = &ccdc_v4l2_core_ops,
2015 .video = &ccdc_v4l2_video_ops,
2016 .pad = &ccdc_v4l2_pad_ops,
2017};
2018
2019/* V4L2 subdev internal operations */
2020static const struct v4l2_subdev_internal_ops ccdc_v4l2_internal_ops = {
2021 .open = ccdc_init_formats,
2022};
2023
2024/* -----------------------------------------------------------------------------
2025 * Media entity operations
2026 */
2027
2028/*
2029 * ccdc_link_setup - Setup CCDC connections
2030 * @entity: CCDC media entity
2031 * @local: Pad at the local end of the link
2032 * @remote: Pad at the remote end of the link
2033 * @flags: Link flags
2034 *
2035 * return -EINVAL or zero on success
2036 */
2037static int ccdc_link_setup(struct media_entity *entity,
2038 const struct media_pad *local,
2039 const struct media_pad *remote, u32 flags)
2040{
2041 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
2042 struct isp_ccdc_device *ccdc = v4l2_get_subdevdata(sd);
2043 struct isp_device *isp = to_isp_device(ccdc);
2044
2045 switch (local->index | media_entity_type(remote->entity)) {
2046 case CCDC_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
2047 /* Read from the sensor (parallel interface), CCP2, CSI2a or
2048 * CSI2c.
2049 */
2050 if (!(flags & MEDIA_LNK_FL_ENABLED)) {
2051 ccdc->input = CCDC_INPUT_NONE;
2052 break;
2053 }
2054
2055 if (ccdc->input != CCDC_INPUT_NONE)
2056 return -EBUSY;
2057
2058 if (remote->entity == &isp->isp_ccp2.subdev.entity)
2059 ccdc->input = CCDC_INPUT_CCP2B;
2060 else if (remote->entity == &isp->isp_csi2a.subdev.entity)
2061 ccdc->input = CCDC_INPUT_CSI2A;
2062 else if (remote->entity == &isp->isp_csi2c.subdev.entity)
2063 ccdc->input = CCDC_INPUT_CSI2C;
2064 else
2065 ccdc->input = CCDC_INPUT_PARALLEL;
2066
2067 break;
2068
2069 /*
2070 * The ISP core doesn't support pipelines with multiple video outputs.
2071 * Revisit this when it will be implemented, and return -EBUSY for now.
2072 */
2073
2074 case CCDC_PAD_SOURCE_VP | MEDIA_ENT_T_V4L2_SUBDEV:
2075 /* Write to preview engine, histogram and H3A. When none of
2076 * those links are active, the video port can be disabled.
2077 */
2078 if (flags & MEDIA_LNK_FL_ENABLED) {
2079 if (ccdc->output & ~CCDC_OUTPUT_PREVIEW)
2080 return -EBUSY;
2081 ccdc->output |= CCDC_OUTPUT_PREVIEW;
2082 } else {
2083 ccdc->output &= ~CCDC_OUTPUT_PREVIEW;
2084 }
2085 break;
2086
2087 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_DEVNODE:
2088 /* Write to memory */
2089 if (flags & MEDIA_LNK_FL_ENABLED) {
2090 if (ccdc->output & ~CCDC_OUTPUT_MEMORY)
2091 return -EBUSY;
2092 ccdc->output |= CCDC_OUTPUT_MEMORY;
2093 } else {
2094 ccdc->output &= ~CCDC_OUTPUT_MEMORY;
2095 }
2096 break;
2097
2098 case CCDC_PAD_SOURCE_OF | MEDIA_ENT_T_V4L2_SUBDEV:
2099 /* Write to resizer */
2100 if (flags & MEDIA_LNK_FL_ENABLED) {
2101 if (ccdc->output & ~CCDC_OUTPUT_RESIZER)
2102 return -EBUSY;
2103 ccdc->output |= CCDC_OUTPUT_RESIZER;
2104 } else {
2105 ccdc->output &= ~CCDC_OUTPUT_RESIZER;
2106 }
2107 break;
2108
2109 default:
2110 return -EINVAL;
2111 }
2112
2113 return 0;
2114}
2115
2116/* media operations */
2117static const struct media_entity_operations ccdc_media_ops = {
2118 .link_setup = ccdc_link_setup,
2119};
2120
2121/*
2122 * ccdc_init_entities - Initialize V4L2 subdev and media entity
2123 * @ccdc: ISP CCDC module
2124 *
2125 * Return 0 on success and a negative error code on failure.
2126 */
2127static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2128{
2129 struct v4l2_subdev *sd = &ccdc->subdev;
2130 struct media_pad *pads = ccdc->pads;
2131 struct media_entity *me = &sd->entity;
2132 int ret;
2133
2134 ccdc->input = CCDC_INPUT_NONE;
2135
2136 v4l2_subdev_init(sd, &ccdc_v4l2_ops);
2137 sd->internal_ops = &ccdc_v4l2_internal_ops;
2138 strlcpy(sd->name, "OMAP3 ISP CCDC", sizeof(sd->name));
2139 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
2140 v4l2_set_subdevdata(sd, ccdc);
2141 sd->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
2142 sd->nevents = OMAP3ISP_CCDC_NEVENTS;
2143
2144 pads[CCDC_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2145 pads[CCDC_PAD_SOURCE_VP].flags = MEDIA_PAD_FL_SOURCE;
2146 pads[CCDC_PAD_SOURCE_OF].flags = MEDIA_PAD_FL_SOURCE;
2147
2148 me->ops = &ccdc_media_ops;
2149 ret = media_entity_init(me, CCDC_PADS_NUM, pads, 0);
2150 if (ret < 0)
2151 return ret;
2152
2153 ccdc_init_formats(sd, NULL);
2154
2155 ccdc->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2156 ccdc->video_out.ops = &ccdc_video_ops;
2157 ccdc->video_out.isp = to_isp_device(ccdc);
2158 ccdc->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
2159 ccdc->video_out.bpl_alignment = 32;
2160
2161 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2162 if (ret < 0)
2163 return ret;
2164
2165 /* Connect the CCDC subdev to the video node. */
2166 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2167 &ccdc->video_out.video.entity, 0, 0);
2168 if (ret < 0)
2169 return ret;
2170
2171 return 0;
2172}
2173
2174void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2175{
2176 media_entity_cleanup(&ccdc->subdev.entity);
2177
2178 v4l2_device_unregister_subdev(&ccdc->subdev);
2179 omap3isp_video_unregister(&ccdc->video_out);
2180}
2181
2182int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2183 struct v4l2_device *vdev)
2184{
2185 int ret;
2186
2187 /* Register the subdev and video node. */
2188 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2189 if (ret < 0)
2190 goto error;
2191
2192 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2193 if (ret < 0)
2194 goto error;
2195
2196 return 0;
2197
2198error:
2199 omap3isp_ccdc_unregister_entities(ccdc);
2200 return ret;
2201}
2202
2203/* -----------------------------------------------------------------------------
2204 * ISP CCDC initialisation and cleanup
2205 */
2206
2207/*
2208 * omap3isp_ccdc_init - CCDC module initialization.
2209 * @dev: Device pointer specific to the OMAP3 ISP.
2210 *
2211 * TODO: Get the initialisation values from platform data.
2212 *
2213 * Return 0 on success or a negative error code otherwise.
2214 */
2215int omap3isp_ccdc_init(struct isp_device *isp)
2216{
2217 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2218
2219 spin_lock_init(&ccdc->lock);
2220 init_waitqueue_head(&ccdc->wait);
2221 mutex_init(&ccdc->ioctl_lock);
2222
2223 ccdc->stopping = CCDC_STOP_NOT_REQUESTED;
2224
2225 INIT_WORK(&ccdc->lsc.table_work, ccdc_lsc_free_table_work);
2226 ccdc->lsc.state = LSC_STATE_STOPPED;
2227 INIT_LIST_HEAD(&ccdc->lsc.free_queue);
2228 spin_lock_init(&ccdc->lsc.req_lock);
2229
2230 ccdc->syncif.ccdc_mastermode = 0;
2231 ccdc->syncif.datapol = 0;
2232 ccdc->syncif.datsz = 0;
2233 ccdc->syncif.fldmode = 0;
2234 ccdc->syncif.fldout = 0;
2235 ccdc->syncif.fldpol = 0;
2236 ccdc->syncif.fldstat = 0;
2237 ccdc->syncif.hdpol = 0;
2238 ccdc->syncif.vdpol = 0;
2239
2240 ccdc->clamp.oblen = 0;
2241 ccdc->clamp.dcsubval = 0;
2242
2243 ccdc->vpcfg.pixelclk = 0;
2244
2245 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2246 ccdc_apply_controls(ccdc);
2247
2248 return ccdc_init_entities(ccdc);
2249}
2250
2251/*
2252 * omap3isp_ccdc_cleanup - CCDC module cleanup.
2253 * @dev: Device pointer specific to the OMAP3 ISP.
2254 */
2255void omap3isp_ccdc_cleanup(struct isp_device *isp)
2256{
2257 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2258
2259 /* Free LSC requests. As the CCDC is stopped there's no active request,
2260 * so only the pending request and the free queue need to be handled.
2261 */
2262 ccdc_lsc_free_request(ccdc, ccdc->lsc.request);
2263 cancel_work_sync(&ccdc->lsc.table_work);
2264 ccdc_lsc_free_queue(ccdc, &ccdc->lsc.free_queue);
2265
2266 if (ccdc->fpc.fpcaddr != 0)
2267 iommu_vfree(isp->iommu, ccdc->fpc.fpcaddr);
2268}
diff --git a/drivers/media/video/omap3isp/ispccdc.h b/drivers/media/video/omap3isp/ispccdc.h
new file mode 100644
index 000000000000..d403af5d31d2
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccdc.h
@@ -0,0 +1,219 @@
1/*
2 * ispccdc.h
3 *
4 * TI OMAP3 ISP - CCDC module
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CCDC_H
28#define OMAP3_ISP_CCDC_H
29
30#include <linux/omap3isp.h>
31#include <linux/workqueue.h>
32
33#include "ispvideo.h"
34
35enum ccdc_input_entity {
36 CCDC_INPUT_NONE,
37 CCDC_INPUT_PARALLEL,
38 CCDC_INPUT_CSI2A,
39 CCDC_INPUT_CCP2B,
40 CCDC_INPUT_CSI2C
41};
42
43#define CCDC_OUTPUT_MEMORY (1 << 0)
44#define CCDC_OUTPUT_PREVIEW (1 << 1)
45#define CCDC_OUTPUT_RESIZER (1 << 2)
46
47#define OMAP3ISP_CCDC_NEVENTS 16
48
49/*
50 * struct ispccdc_syncif - Structure for Sync Interface between sensor and CCDC
51 * @ccdc_mastermode: Master mode. 1 - Master, 0 - Slave.
52 * @fldstat: Field state. 0 - Odd Field, 1 - Even Field.
53 * @datsz: Data size.
54 * @fldmode: 0 - Progressive, 1 - Interlaced.
55 * @datapol: 0 - Positive, 1 - Negative.
56 * @fldpol: 0 - Positive, 1 - Negative.
57 * @hdpol: 0 - Positive, 1 - Negative.
58 * @vdpol: 0 - Positive, 1 - Negative.
59 * @fldout: 0 - Input, 1 - Output.
60 * @hs_width: Width of the Horizontal Sync pulse, used for HS/VS Output.
61 * @vs_width: Width of the Vertical Sync pulse, used for HS/VS Output.
62 * @ppln: Number of pixels per line, used for HS/VS Output.
63 * @hlprf: Number of half lines per frame, used for HS/VS Output.
64 * @bt_r656_en: 1 - Enable ITU-R BT656 mode, 0 - Sync mode.
65 */
66struct ispccdc_syncif {
67 u8 ccdc_mastermode;
68 u8 fldstat;
69 u8 datsz;
70 u8 fldmode;
71 u8 datapol;
72 u8 fldpol;
73 u8 hdpol;
74 u8 vdpol;
75 u8 fldout;
76 u8 hs_width;
77 u8 vs_width;
78 u8 ppln;
79 u8 hlprf;
80 u8 bt_r656_en;
81};
82
83/*
84 * struct ispccdc_vp - Structure for Video Port parameters
85 * @pixelclk: Input pixel clock in Hz
86 */
87struct ispccdc_vp {
88 unsigned int pixelclk;
89};
90
91enum ispccdc_lsc_state {
92 LSC_STATE_STOPPED = 0,
93 LSC_STATE_STOPPING = 1,
94 LSC_STATE_RUNNING = 2,
95 LSC_STATE_RECONFIG = 3,
96};
97
98struct ispccdc_lsc_config_req {
99 struct list_head list;
100 struct omap3isp_ccdc_lsc_config config;
101 unsigned char enable;
102 u32 table;
103 struct iovm_struct *iovm;
104};
105
106/*
107 * ispccdc_lsc - CCDC LSC parameters
108 * @update_config: Set when user changes config
109 * @request_enable: Whether LSC is requested to be enabled
110 * @config: LSC config set by user
111 * @update_table: Set when user provides a new LSC table to table_new
112 * @table_new: LSC table set by user, ISP address
113 * @table_inuse: LSC table currently in use, ISP address
114 */
115struct ispccdc_lsc {
116 enum ispccdc_lsc_state state;
117 struct work_struct table_work;
118
119 /* LSC queue of configurations */
120 spinlock_t req_lock;
121 struct ispccdc_lsc_config_req *request; /* requested configuration */
122 struct ispccdc_lsc_config_req *active; /* active configuration */
123 struct list_head free_queue; /* configurations for freeing */
124};
125
126#define CCDC_STOP_NOT_REQUESTED 0x00
127#define CCDC_STOP_REQUEST 0x01
128#define CCDC_STOP_EXECUTED (0x02 | CCDC_STOP_REQUEST)
129#define CCDC_STOP_CCDC_FINISHED 0x04
130#define CCDC_STOP_LSC_FINISHED 0x08
131#define CCDC_STOP_FINISHED \
132 (CCDC_STOP_EXECUTED | CCDC_STOP_CCDC_FINISHED | CCDC_STOP_LSC_FINISHED)
133
134#define CCDC_EVENT_VD1 0x10
135#define CCDC_EVENT_VD0 0x20
136#define CCDC_EVENT_LSC_DONE 0x40
137
138/* Sink and source CCDC pads */
139#define CCDC_PAD_SINK 0
140#define CCDC_PAD_SOURCE_OF 1
141#define CCDC_PAD_SOURCE_VP 2
142#define CCDC_PADS_NUM 3
143
144/*
145 * struct isp_ccdc_device - Structure for the CCDC module to store its own
146 * information
147 * @subdev: V4L2 subdevice
148 * @pads: Sink and source media entity pads
149 * @formats: Active video formats
150 * @input: Active input
151 * @output: Active outputs
152 * @video_out: Output video node
153 * @error: A hardware error occured during capture
154 * @alaw: A-law compression enabled (1) or disabled (0)
155 * @lpf: Low pass filter enabled (1) or disabled (0)
156 * @obclamp: Optical-black clamp enabled (1) or disabled (0)
157 * @fpc_en: Faulty pixels correction enabled (1) or disabled (0)
158 * @blcomp: Black level compensation configuration
159 * @clamp: Optical-black or digital clamp configuration
160 * @fpc: Faulty pixels correction configuration
161 * @lsc: Lens shading compensation configuration
162 * @update: Bitmask of controls to update during the next interrupt
163 * @shadow_update: Controls update in progress by userspace
164 * @syncif: Interface synchronization configuration
165 * @vpcfg: Video port configuration
166 * @underrun: A buffer underrun occured and a new buffer has been queued
167 * @state: Streaming state
168 * @lock: Serializes shadow_update with interrupt handler
169 * @wait: Wait queue used to stop the module
170 * @stopping: Stopping state
171 * @ioctl_lock: Serializes ioctl calls and LSC requests freeing
172 */
173struct isp_ccdc_device {
174 struct v4l2_subdev subdev;
175 struct media_pad pads[CCDC_PADS_NUM];
176 struct v4l2_mbus_framefmt formats[CCDC_PADS_NUM];
177
178 enum ccdc_input_entity input;
179 unsigned int output;
180 struct isp_video video_out;
181 unsigned int error;
182
183 unsigned int alaw:1,
184 lpf:1,
185 obclamp:1,
186 fpc_en:1;
187 struct omap3isp_ccdc_blcomp blcomp;
188 struct omap3isp_ccdc_bclamp clamp;
189 struct omap3isp_ccdc_fpc fpc;
190 struct ispccdc_lsc lsc;
191 unsigned int update;
192 unsigned int shadow_update;
193
194 struct ispccdc_syncif syncif;
195 struct ispccdc_vp vpcfg;
196
197 unsigned int underrun:1;
198 enum isp_pipeline_stream_state state;
199 spinlock_t lock;
200 wait_queue_head_t wait;
201 unsigned int stopping;
202 struct mutex ioctl_lock;
203};
204
205struct isp_device;
206
207int omap3isp_ccdc_init(struct isp_device *isp);
208void omap3isp_ccdc_cleanup(struct isp_device *isp);
209int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
210 struct v4l2_device *vdev);
211void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc);
212
213int omap3isp_ccdc_busy(struct isp_ccdc_device *isp_ccdc);
214int omap3isp_ccdc_isr(struct isp_ccdc_device *isp_ccdc, u32 events);
215void omap3isp_ccdc_restore_context(struct isp_device *isp);
216void omap3isp_ccdc_max_rate(struct isp_ccdc_device *ccdc,
217 unsigned int *max_rate);
218
219#endif /* OMAP3_ISP_CCDC_H */
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
new file mode 100644
index 000000000000..0efef2e78d93
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -0,0 +1,1173 @@
1/*
2 * ispccp2.c
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/delay.h>
28#include <linux/device.h>
29#include <linux/mm.h>
30#include <linux/module.h>
31#include <linux/mutex.h>
32#include <linux/uaccess.h>
33
34#include "isp.h"
35#include "ispreg.h"
36#include "ispccp2.h"
37
38/* Number of LCX channels */
39#define CCP2_LCx_CHANS_NUM 3
40/* Max/Min size for CCP2 video port */
41#define ISPCCP2_DAT_START_MIN 0
42#define ISPCCP2_DAT_START_MAX 4095
43#define ISPCCP2_DAT_SIZE_MIN 0
44#define ISPCCP2_DAT_SIZE_MAX 4095
45#define ISPCCP2_VPCLK_FRACDIV 65536
46#define ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP 0x12
47#define ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP 0x16
48/* Max/Min size for CCP2 memory channel */
49#define ISPCCP2_LCM_HSIZE_COUNT_MIN 16
50#define ISPCCP2_LCM_HSIZE_COUNT_MAX 8191
51#define ISPCCP2_LCM_HSIZE_SKIP_MIN 0
52#define ISPCCP2_LCM_HSIZE_SKIP_MAX 8191
53#define ISPCCP2_LCM_VSIZE_MIN 1
54#define ISPCCP2_LCM_VSIZE_MAX 8191
55#define ISPCCP2_LCM_HWORDS_MIN 1
56#define ISPCCP2_LCM_HWORDS_MAX 4095
57#define ISPCCP2_LCM_CTRL_BURST_SIZE_32X 5
58#define ISPCCP2_LCM_CTRL_READ_THROTTLE_FULL 0
59#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 2
60#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 2
61#define ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 3
62#define ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 3
63#define ISPCCP2_LCM_CTRL_DST_PORT_VP 0
64#define ISPCCP2_LCM_CTRL_DST_PORT_MEM 1
65
66/* Set only the required bits */
67#define BIT_SET(var, shift, mask, val) \
68 do { \
69 var = ((var) & ~((mask) << (shift))) \
70 | ((val) << (shift)); \
71 } while (0)
72
73/*
74 * ccp2_print_status - Print current CCP2 module register values.
75 */
76#define CCP2_PRINT_REGISTER(isp, name)\
77 dev_dbg(isp->dev, "###CCP2 " #name "=0x%08x\n", \
78 isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_##name))
79
80static void ccp2_print_status(struct isp_ccp2_device *ccp2)
81{
82 struct isp_device *isp = to_isp_device(ccp2);
83
84 dev_dbg(isp->dev, "-------------CCP2 Register dump-------------\n");
85
86 CCP2_PRINT_REGISTER(isp, SYSCONFIG);
87 CCP2_PRINT_REGISTER(isp, SYSSTATUS);
88 CCP2_PRINT_REGISTER(isp, LC01_IRQENABLE);
89 CCP2_PRINT_REGISTER(isp, LC01_IRQSTATUS);
90 CCP2_PRINT_REGISTER(isp, LC23_IRQENABLE);
91 CCP2_PRINT_REGISTER(isp, LC23_IRQSTATUS);
92 CCP2_PRINT_REGISTER(isp, LCM_IRQENABLE);
93 CCP2_PRINT_REGISTER(isp, LCM_IRQSTATUS);
94 CCP2_PRINT_REGISTER(isp, CTRL);
95 CCP2_PRINT_REGISTER(isp, LCx_CTRL(0));
96 CCP2_PRINT_REGISTER(isp, LCx_CODE(0));
97 CCP2_PRINT_REGISTER(isp, LCx_STAT_START(0));
98 CCP2_PRINT_REGISTER(isp, LCx_STAT_SIZE(0));
99 CCP2_PRINT_REGISTER(isp, LCx_SOF_ADDR(0));
100 CCP2_PRINT_REGISTER(isp, LCx_EOF_ADDR(0));
101 CCP2_PRINT_REGISTER(isp, LCx_DAT_START(0));
102 CCP2_PRINT_REGISTER(isp, LCx_DAT_SIZE(0));
103 CCP2_PRINT_REGISTER(isp, LCx_DAT_PING_ADDR(0));
104 CCP2_PRINT_REGISTER(isp, LCx_DAT_PONG_ADDR(0));
105 CCP2_PRINT_REGISTER(isp, LCx_DAT_OFST(0));
106 CCP2_PRINT_REGISTER(isp, LCM_CTRL);
107 CCP2_PRINT_REGISTER(isp, LCM_VSIZE);
108 CCP2_PRINT_REGISTER(isp, LCM_HSIZE);
109 CCP2_PRINT_REGISTER(isp, LCM_PREFETCH);
110 CCP2_PRINT_REGISTER(isp, LCM_SRC_ADDR);
111 CCP2_PRINT_REGISTER(isp, LCM_SRC_OFST);
112 CCP2_PRINT_REGISTER(isp, LCM_DST_ADDR);
113 CCP2_PRINT_REGISTER(isp, LCM_DST_OFST);
114
115 dev_dbg(isp->dev, "--------------------------------------------\n");
116}
117
118/*
119 * ccp2_reset - Reset the CCP2
120 * @ccp2: pointer to ISP CCP2 device
121 */
122static void ccp2_reset(struct isp_ccp2_device *ccp2)
123{
124 struct isp_device *isp = to_isp_device(ccp2);
125 int i = 0;
126
127 /* Reset the CSI1/CCP2B and wait for reset to complete */
128 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG,
129 ISPCCP2_SYSCONFIG_SOFT_RESET);
130 while (!(isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSSTATUS) &
131 ISPCCP2_SYSSTATUS_RESET_DONE)) {
132 udelay(10);
133 if (i++ > 10) { /* try read 10 times */
134 dev_warn(isp->dev,
135 "omap3_isp: timeout waiting for ccp2 reset\n");
136 break;
137 }
138 }
139}
140
141/*
142 * ccp2_pwr_cfg - Configure the power mode settings
143 * @ccp2: pointer to ISP CCP2 device
144 */
145static void ccp2_pwr_cfg(struct isp_ccp2_device *ccp2)
146{
147 struct isp_device *isp = to_isp_device(ccp2);
148
149 isp_reg_writel(isp, ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART |
150 ((isp->revision == ISP_REVISION_15_0 && isp->autoidle) ?
151 ISPCCP2_SYSCONFIG_AUTO_IDLE : 0),
152 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_SYSCONFIG);
153}
154
155/*
156 * ccp2_if_enable - Enable CCP2 interface.
157 * @ccp2: pointer to ISP CCP2 device
158 * @enable: enable/disable flag
159 */
160static void ccp2_if_enable(struct isp_ccp2_device *ccp2, u8 enable)
161{
162 struct isp_device *isp = to_isp_device(ccp2);
163 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
164 int i;
165
166 /* Enable/Disable all the LCx channels */
167 for (i = 0; i < CCP2_LCx_CHANS_NUM; i++)
168 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(i),
169 ISPCCP2_LCx_CTRL_CHAN_EN,
170 enable ? ISPCCP2_LCx_CTRL_CHAN_EN : 0);
171
172 /* Enable/Disable ccp2 interface in ccp2 mode */
173 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
174 ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN,
175 enable ? (ISPCCP2_CTRL_MODE | ISPCCP2_CTRL_IF_EN) : 0);
176
177 /* For frame count propagation */
178 if (pipe->do_propagation) {
179 /* We may want the Frame Start IRQ from LC0 */
180 if (enable)
181 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2,
182 ISPCCP2_LC01_IRQENABLE,
183 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
184 else
185 isp_reg_clr(isp, OMAP3_ISP_IOMEM_CCP2,
186 ISPCCP2_LC01_IRQENABLE,
187 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ);
188 }
189}
190
191/*
192 * ccp2_mem_enable - Enable CCP2 memory interface.
193 * @ccp2: pointer to ISP CCP2 device
194 * @enable: enable/disable flag
195 */
196static void ccp2_mem_enable(struct isp_ccp2_device *ccp2, u8 enable)
197{
198 struct isp_device *isp = to_isp_device(ccp2);
199
200 if (enable)
201 ccp2_if_enable(ccp2, 0);
202
203 /* Enable/Disable ccp2 interface in ccp2 mode */
204 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
205 ISPCCP2_CTRL_MODE, enable ? ISPCCP2_CTRL_MODE : 0);
206
207 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL,
208 ISPCCP2_LCM_CTRL_CHAN_EN,
209 enable ? ISPCCP2_LCM_CTRL_CHAN_EN : 0);
210}
211
212/*
213 * ccp2_phyif_config - Initialize CCP2 phy interface config
214 * @ccp2: Pointer to ISP CCP2 device
215 * @config: CCP2 platform data
216 *
217 * Configure the CCP2 physical interface module from platform data.
218 *
219 * Returns -EIO if strobe is chosen in CSI1 mode, or 0 on success.
220 */
221static int ccp2_phyif_config(struct isp_ccp2_device *ccp2,
222 const struct isp_ccp2_platform_data *pdata)
223{
224 struct isp_device *isp = to_isp_device(ccp2);
225 u32 val;
226
227 /* CCP2B mode */
228 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL) |
229 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE;
230 /* Data/strobe physical layer */
231 BIT_SET(val, ISPCCP2_CTRL_PHY_SEL_SHIFT, ISPCCP2_CTRL_PHY_SEL_MASK,
232 pdata->phy_layer);
233 BIT_SET(val, ISPCCP2_CTRL_INV_SHIFT, ISPCCP2_CTRL_INV_MASK,
234 pdata->strobe_clk_pol);
235 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
236
237 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
238 if (!(val & ISPCCP2_CTRL_MODE)) {
239 if (pdata->ccp2_mode)
240 dev_warn(isp->dev, "OMAP3 CCP2 bus not available\n");
241 if (pdata->phy_layer == ISPCCP2_CTRL_PHY_SEL_STROBE)
242 /* Strobe mode requires CCP2 */
243 return -EIO;
244 }
245
246 return 0;
247}
248
249/*
250 * ccp2_vp_config - Initialize CCP2 video port interface.
251 * @ccp2: Pointer to ISP CCP2 device
252 * @vpclk_div: Video port divisor
253 *
254 * Configure the CCP2 video port with the given clock divisor. The valid divisor
255 * values depend on the ISP revision:
256 *
257 * - revision 1.0 and 2.0 1 to 4
258 * - revision 15.0 1 to 65536
259 *
260 * The exact divisor value used might differ from the requested value, as ISP
261 * revision 15.0 represent the divisor by 65536 divided by an integer.
262 */
263static void ccp2_vp_config(struct isp_ccp2_device *ccp2,
264 unsigned int vpclk_div)
265{
266 struct isp_device *isp = to_isp_device(ccp2);
267 u32 val;
268
269 /* ISPCCP2_CTRL Video port */
270 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
271 val |= ISPCCP2_CTRL_VP_ONLY_EN; /* Disable the memory write port */
272
273 if (isp->revision == ISP_REVISION_15_0) {
274 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 65536);
275 vpclk_div = min(ISPCCP2_VPCLK_FRACDIV / vpclk_div, 65535U);
276 BIT_SET(val, ISPCCP2_CTRL_VPCLK_DIV_SHIFT,
277 ISPCCP2_CTRL_VPCLK_DIV_MASK, vpclk_div);
278 } else {
279 vpclk_div = clamp_t(unsigned int, vpclk_div, 1, 4);
280 BIT_SET(val, ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT,
281 ISPCCP2_CTRL_VP_OUT_CTRL_MASK, vpclk_div - 1);
282 }
283
284 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL);
285}
286
287/*
288 * ccp2_lcx_config - Initialize CCP2 logical channel interface.
289 * @ccp2: Pointer to ISP CCP2 device
290 * @config: Pointer to ISP LCx config structure.
291 *
292 * This will analyze the parameters passed by the interface config
293 * and configure CSI1/CCP2 logical channel
294 *
295 */
296static void ccp2_lcx_config(struct isp_ccp2_device *ccp2,
297 struct isp_interface_lcx_config *config)
298{
299 struct isp_device *isp = to_isp_device(ccp2);
300 u32 val, format;
301
302 switch (config->format) {
303 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
304 format = ISPCCP2_LCx_CTRL_FORMAT_RAW8_DPCM10_VP;
305 break;
306 case V4L2_MBUS_FMT_SGRBG10_1X10:
307 default:
308 format = ISPCCP2_LCx_CTRL_FORMAT_RAW10_VP; /* RAW10+VP */
309 break;
310 }
311 /* ISPCCP2_LCx_CTRL logical channel #0 */
312 val = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0))
313 | (ISPCCP2_LCx_CTRL_REGION_EN); /* Region */
314
315 if (isp->revision == ISP_REVISION_15_0) {
316 /* CRC */
317 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0,
318 ISPCCP2_LCx_CTRL_CRC_MASK,
319 config->crc);
320 /* Format = RAW10+VP or RAW8+DPCM10+VP*/
321 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0,
322 ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0, format);
323 } else {
324 BIT_SET(val, ISPCCP2_LCx_CTRL_CRC_SHIFT,
325 ISPCCP2_LCx_CTRL_CRC_MASK,
326 config->crc);
327
328 BIT_SET(val, ISPCCP2_LCx_CTRL_FORMAT_SHIFT,
329 ISPCCP2_LCx_CTRL_FORMAT_MASK, format);
330 }
331 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_CTRL(0));
332
333 /* ISPCCP2_DAT_START for logical channel #0 */
334 isp_reg_writel(isp, config->data_start << ISPCCP2_LCx_DAT_SHIFT,
335 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_START(0));
336
337 /* ISPCCP2_DAT_SIZE for logical channel #0 */
338 isp_reg_writel(isp, config->data_size << ISPCCP2_LCx_DAT_SHIFT,
339 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCx_DAT_SIZE(0));
340
341 /* Enable error IRQs for logical channel #0 */
342 val = ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
343 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
344 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
345 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
346 ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ |
347 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
348 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
349
350 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQSTATUS);
351 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LC01_IRQENABLE, val);
352}
353
354/*
355 * ccp2_if_configure - Configure ccp2 with data from sensor
356 * @ccp2: Pointer to ISP CCP2 device
357 *
358 * Return 0 on success or a negative error code
359 */
360static int ccp2_if_configure(struct isp_ccp2_device *ccp2)
361{
362 const struct isp_v4l2_subdevs_group *pdata;
363 struct v4l2_mbus_framefmt *format;
364 struct media_pad *pad;
365 struct v4l2_subdev *sensor;
366 u32 lines = 0;
367 int ret;
368
369 ccp2_pwr_cfg(ccp2);
370
371 pad = media_entity_remote_source(&ccp2->pads[CCP2_PAD_SINK]);
372 sensor = media_entity_to_v4l2_subdev(pad->entity);
373 pdata = sensor->host_priv;
374
375 ret = ccp2_phyif_config(ccp2, &pdata->bus.ccp2);
376 if (ret < 0)
377 return ret;
378
379 ccp2_vp_config(ccp2, pdata->bus.ccp2.vpclk_div + 1);
380
381 v4l2_subdev_call(sensor, sensor, g_skip_top_lines, &lines);
382
383 format = &ccp2->formats[CCP2_PAD_SINK];
384
385 ccp2->if_cfg.data_start = lines;
386 ccp2->if_cfg.crc = pdata->bus.ccp2.crc;
387 ccp2->if_cfg.format = format->code;
388 ccp2->if_cfg.data_size = format->height;
389
390 ccp2_lcx_config(ccp2, &ccp2->if_cfg);
391
392 return 0;
393}
394
395static int ccp2_adjust_bandwidth(struct isp_ccp2_device *ccp2)
396{
397 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
398 struct isp_device *isp = to_isp_device(ccp2);
399 const struct v4l2_mbus_framefmt *ofmt = &ccp2->formats[CCP2_PAD_SOURCE];
400 unsigned long l3_ick = pipe->l3_ick;
401 struct v4l2_fract *timeperframe;
402 unsigned int vpclk_div = 2;
403 unsigned int value;
404 u64 bound;
405 u64 area;
406
407 /* Compute the minimum clock divisor, based on the pipeline maximum
408 * data rate. This is an absolute lower bound if we don't want SBL
409 * overflows, so round the value up.
410 */
411 vpclk_div = max_t(unsigned int, DIV_ROUND_UP(l3_ick, pipe->max_rate),
412 vpclk_div);
413
414 /* Compute the maximum clock divisor, based on the requested frame rate.
415 * This is a soft lower bound to achieve a frame rate equal or higher
416 * than the requested value, so round the value down.
417 */
418 timeperframe = &pipe->max_timeperframe;
419
420 if (timeperframe->numerator) {
421 area = ofmt->width * ofmt->height;
422 bound = div_u64(area * timeperframe->denominator,
423 timeperframe->numerator);
424 value = min_t(u64, bound, l3_ick);
425 vpclk_div = max_t(unsigned int, l3_ick / value, vpclk_div);
426 }
427
428 dev_dbg(isp->dev, "%s: minimum clock divisor = %u\n", __func__,
429 vpclk_div);
430
431 return vpclk_div;
432}
433
434/*
435 * ccp2_mem_configure - Initialize CCP2 memory input/output interface
436 * @ccp2: Pointer to ISP CCP2 device
437 * @config: Pointer to ISP mem interface config structure
438 *
439 * This will analyze the parameters passed by the interface config
440 * structure, and configure the respective registers for proper
441 * CSI1/CCP2 memory input.
442 */
443static void ccp2_mem_configure(struct isp_ccp2_device *ccp2,
444 struct isp_interface_mem_config *config)
445{
446 struct isp_device *isp = to_isp_device(ccp2);
447 u32 sink_pixcode = ccp2->formats[CCP2_PAD_SINK].code;
448 u32 source_pixcode = ccp2->formats[CCP2_PAD_SOURCE].code;
449 unsigned int dpcm_decompress = 0;
450 u32 val, hwords;
451
452 if (sink_pixcode != source_pixcode &&
453 sink_pixcode == V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
454 dpcm_decompress = 1;
455
456 ccp2_pwr_cfg(ccp2);
457
458 /* Hsize, Skip */
459 isp_reg_writel(isp, ISPCCP2_LCM_HSIZE_SKIP_MIN |
460 (config->hsize_count << ISPCCP2_LCM_HSIZE_SHIFT),
461 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_HSIZE);
462
463 /* Vsize, no. of lines */
464 isp_reg_writel(isp, config->vsize_count << ISPCCP2_LCM_VSIZE_SHIFT,
465 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_VSIZE);
466
467 if (ccp2->video_in.bpl_padding == 0)
468 config->src_ofst = 0;
469 else
470 config->src_ofst = ccp2->video_in.bpl_value;
471
472 isp_reg_writel(isp, config->src_ofst, OMAP3_ISP_IOMEM_CCP2,
473 ISPCCP2_LCM_SRC_OFST);
474
475 /* Source and Destination formats */
476 val = ISPCCP2_LCM_CTRL_DST_FORMAT_RAW10 <<
477 ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT;
478
479 if (dpcm_decompress) {
480 /* source format is RAW8 */
481 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW8 <<
482 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
483
484 /* RAW8 + DPCM10 - simple predictor */
485 val |= ISPCCP2_LCM_CTRL_SRC_DPCM_PRED;
486
487 /* enable source DPCM decompression */
488 val |= ISPCCP2_LCM_CTRL_SRC_DECOMPR_DPCM10 <<
489 ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT;
490 } else {
491 /* source format is RAW10 */
492 val |= ISPCCP2_LCM_CTRL_SRC_FORMAT_RAW10 <<
493 ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT;
494 }
495
496 /* Burst size to 32x64 */
497 val |= ISPCCP2_LCM_CTRL_BURST_SIZE_32X <<
498 ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT;
499
500 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_CTRL);
501
502 /* Prefetch setup */
503 if (dpcm_decompress)
504 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
505 config->hsize_count) >> 3;
506 else
507 hwords = (ISPCCP2_LCM_HSIZE_SKIP_MIN +
508 config->hsize_count) >> 2;
509
510 isp_reg_writel(isp, hwords << ISPCCP2_LCM_PREFETCH_SHIFT,
511 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_PREFETCH);
512
513 /* Video port */
514 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_CTRL,
515 ISPCCP2_CTRL_IO_OUT_SEL | ISPCCP2_CTRL_MODE);
516 ccp2_vp_config(ccp2, ccp2_adjust_bandwidth(ccp2));
517
518 /* Clear LCM interrupts */
519 isp_reg_writel(isp, ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ |
520 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ,
521 OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQSTATUS);
522
523 /* Enable LCM interupts */
524 isp_reg_set(isp, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_IRQENABLE,
525 ISPCCP2_LCM_IRQSTATUS_EOF_IRQ |
526 ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ);
527}
528
529/*
530 * ccp2_set_inaddr - Sets memory address of input frame.
531 * @ccp2: Pointer to ISP CCP2 device
532 * @addr: 32bit memory address aligned on 32byte boundary.
533 *
534 * Configures the memory address from which the input frame is to be read.
535 */
536static void ccp2_set_inaddr(struct isp_ccp2_device *ccp2, u32 addr)
537{
538 struct isp_device *isp = to_isp_device(ccp2);
539
540 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_CCP2, ISPCCP2_LCM_SRC_ADDR);
541}
542
543/* -----------------------------------------------------------------------------
544 * Interrupt handling
545 */
546
547static void ccp2_isr_buffer(struct isp_ccp2_device *ccp2)
548{
549 struct isp_pipeline *pipe = to_isp_pipeline(&ccp2->subdev.entity);
550 struct isp_buffer *buffer;
551
552 buffer = omap3isp_video_buffer_next(&ccp2->video_in, ccp2->error);
553 if (buffer != NULL)
554 ccp2_set_inaddr(ccp2, buffer->isp_addr);
555
556 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
557
558 if (ccp2->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
559 if (isp_pipeline_ready(pipe))
560 omap3isp_pipeline_set_stream(pipe,
561 ISP_PIPELINE_STREAM_SINGLESHOT);
562 }
563
564 ccp2->error = 0;
565}
566
567/*
568 * omap3isp_ccp2_isr - Handle ISP CCP2 interrupts
569 * @ccp2: Pointer to ISP CCP2 device
570 *
571 * This will handle the CCP2 interrupts
572 *
573 * Returns -EIO in case of error, or 0 on success.
574 */
575int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2)
576{
577 struct isp_device *isp = to_isp_device(ccp2);
578 int ret = 0;
579 static const u32 ISPCCP2_LC01_ERROR =
580 ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ |
581 ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ |
582 ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ |
583 ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ |
584 ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ |
585 ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ;
586 u32 lcx_irqstatus, lcm_irqstatus;
587
588 /* First clear the interrupts */
589 lcx_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
590 ISPCCP2_LC01_IRQSTATUS);
591 isp_reg_writel(isp, lcx_irqstatus, OMAP3_ISP_IOMEM_CCP2,
592 ISPCCP2_LC01_IRQSTATUS);
593
594 lcm_irqstatus = isp_reg_readl(isp, OMAP3_ISP_IOMEM_CCP2,
595 ISPCCP2_LCM_IRQSTATUS);
596 isp_reg_writel(isp, lcm_irqstatus, OMAP3_ISP_IOMEM_CCP2,
597 ISPCCP2_LCM_IRQSTATUS);
598 /* Errors */
599 if (lcx_irqstatus & ISPCCP2_LC01_ERROR) {
600 ccp2->error = 1;
601 dev_dbg(isp->dev, "CCP2 err:%x\n", lcx_irqstatus);
602 return -EIO;
603 }
604
605 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ) {
606 ccp2->error = 1;
607 dev_dbg(isp->dev, "CCP2 OCP err:%x\n", lcm_irqstatus);
608 ret = -EIO;
609 }
610
611 if (omap3isp_module_sync_is_stopping(&ccp2->wait, &ccp2->stopping))
612 return 0;
613
614 /* Frame number propagation */
615 if (lcx_irqstatus & ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ) {
616 struct isp_pipeline *pipe =
617 to_isp_pipeline(&ccp2->subdev.entity);
618 if (pipe->do_propagation)
619 atomic_inc(&pipe->frame_number);
620 }
621
622 /* Handle queued buffers on frame end interrupts */
623 if (lcm_irqstatus & ISPCCP2_LCM_IRQSTATUS_EOF_IRQ)
624 ccp2_isr_buffer(ccp2);
625
626 return ret;
627}
628
629/* -----------------------------------------------------------------------------
630 * V4L2 subdev operations
631 */
632
633static const unsigned int ccp2_fmts[] = {
634 V4L2_MBUS_FMT_SGRBG10_1X10,
635 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
636};
637
638/*
639 * __ccp2_get_format - helper function for getting ccp2 format
640 * @ccp2 : Pointer to ISP CCP2 device
641 * @fh : V4L2 subdev file handle
642 * @pad : pad number
643 * @which : wanted subdev format
644 * return format structure or NULL on error
645 */
646static struct v4l2_mbus_framefmt *
647__ccp2_get_format(struct isp_ccp2_device *ccp2, struct v4l2_subdev_fh *fh,
648 unsigned int pad, enum v4l2_subdev_format_whence which)
649{
650 if (which == V4L2_SUBDEV_FORMAT_TRY)
651 return v4l2_subdev_get_try_format(fh, pad);
652 else
653 return &ccp2->formats[pad];
654}
655
656/*
657 * ccp2_try_format - Handle try format by pad subdev method
658 * @ccp2 : Pointer to ISP CCP2 device
659 * @fh : V4L2 subdev file handle
660 * @pad : pad num
661 * @fmt : pointer to v4l2 mbus format structure
662 * @which : wanted subdev format
663 */
664static void ccp2_try_format(struct isp_ccp2_device *ccp2,
665 struct v4l2_subdev_fh *fh, unsigned int pad,
666 struct v4l2_mbus_framefmt *fmt,
667 enum v4l2_subdev_format_whence which)
668{
669 struct v4l2_mbus_framefmt *format;
670
671 switch (pad) {
672 case CCP2_PAD_SINK:
673 if (fmt->code != V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8)
674 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
675
676 if (ccp2->input == CCP2_INPUT_SENSOR) {
677 fmt->width = clamp_t(u32, fmt->width,
678 ISPCCP2_DAT_START_MIN,
679 ISPCCP2_DAT_START_MAX);
680 fmt->height = clamp_t(u32, fmt->height,
681 ISPCCP2_DAT_SIZE_MIN,
682 ISPCCP2_DAT_SIZE_MAX);
683 } else if (ccp2->input == CCP2_INPUT_MEMORY) {
684 fmt->width = clamp_t(u32, fmt->width,
685 ISPCCP2_LCM_HSIZE_COUNT_MIN,
686 ISPCCP2_LCM_HSIZE_COUNT_MAX);
687 fmt->height = clamp_t(u32, fmt->height,
688 ISPCCP2_LCM_VSIZE_MIN,
689 ISPCCP2_LCM_VSIZE_MAX);
690 }
691 break;
692
693 case CCP2_PAD_SOURCE:
694 /* Source format - copy sink format and change pixel code
695 * to SGRBG10_1X10 as we don't support CCP2 write to memory.
696 * When CCP2 write to memory feature will be added this
697 * should be changed properly.
698 */
699 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK, which);
700 memcpy(fmt, format, sizeof(*fmt));
701 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
702 break;
703 }
704
705 fmt->field = V4L2_FIELD_NONE;
706 fmt->colorspace = V4L2_COLORSPACE_SRGB;
707}
708
709/*
710 * ccp2_enum_mbus_code - Handle pixel format enumeration
711 * @sd : pointer to v4l2 subdev structure
712 * @fh : V4L2 subdev file handle
713 * @code : pointer to v4l2_subdev_mbus_code_enum structure
714 * return -EINVAL or zero on success
715 */
716static int ccp2_enum_mbus_code(struct v4l2_subdev *sd,
717 struct v4l2_subdev_fh *fh,
718 struct v4l2_subdev_mbus_code_enum *code)
719{
720 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
721 struct v4l2_mbus_framefmt *format;
722
723 if (code->pad == CCP2_PAD_SINK) {
724 if (code->index >= ARRAY_SIZE(ccp2_fmts))
725 return -EINVAL;
726
727 code->code = ccp2_fmts[code->index];
728 } else {
729 if (code->index != 0)
730 return -EINVAL;
731
732 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SINK,
733 V4L2_SUBDEV_FORMAT_TRY);
734 code->code = format->code;
735 }
736
737 return 0;
738}
739
740static int ccp2_enum_frame_size(struct v4l2_subdev *sd,
741 struct v4l2_subdev_fh *fh,
742 struct v4l2_subdev_frame_size_enum *fse)
743{
744 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
745 struct v4l2_mbus_framefmt format;
746
747 if (fse->index != 0)
748 return -EINVAL;
749
750 format.code = fse->code;
751 format.width = 1;
752 format.height = 1;
753 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
754 fse->min_width = format.width;
755 fse->min_height = format.height;
756
757 if (format.code != fse->code)
758 return -EINVAL;
759
760 format.code = fse->code;
761 format.width = -1;
762 format.height = -1;
763 ccp2_try_format(ccp2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
764 fse->max_width = format.width;
765 fse->max_height = format.height;
766
767 return 0;
768}
769
770/*
771 * ccp2_get_format - Handle get format by pads subdev method
772 * @sd : pointer to v4l2 subdev structure
773 * @fh : V4L2 subdev file handle
774 * @fmt : pointer to v4l2 subdev format structure
775 * return -EINVAL or zero on sucess
776 */
777static int ccp2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
778 struct v4l2_subdev_format *fmt)
779{
780 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
781 struct v4l2_mbus_framefmt *format;
782
783 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
784 if (format == NULL)
785 return -EINVAL;
786
787 fmt->format = *format;
788 return 0;
789}
790
791/*
792 * ccp2_set_format - Handle set format by pads subdev method
793 * @sd : pointer to v4l2 subdev structure
794 * @fh : V4L2 subdev file handle
795 * @fmt : pointer to v4l2 subdev format structure
796 * returns zero
797 */
798static int ccp2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
799 struct v4l2_subdev_format *fmt)
800{
801 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
802 struct v4l2_mbus_framefmt *format;
803
804 format = __ccp2_get_format(ccp2, fh, fmt->pad, fmt->which);
805 if (format == NULL)
806 return -EINVAL;
807
808 ccp2_try_format(ccp2, fh, fmt->pad, &fmt->format, fmt->which);
809 *format = fmt->format;
810
811 /* Propagate the format from sink to source */
812 if (fmt->pad == CCP2_PAD_SINK) {
813 format = __ccp2_get_format(ccp2, fh, CCP2_PAD_SOURCE,
814 fmt->which);
815 *format = fmt->format;
816 ccp2_try_format(ccp2, fh, CCP2_PAD_SOURCE, format, fmt->which);
817 }
818
819 return 0;
820}
821
822/*
823 * ccp2_init_formats - Initialize formats on all pads
824 * @sd: ISP CCP2 V4L2 subdevice
825 * @fh: V4L2 subdev file handle
826 *
827 * Initialize all pad formats with default values. If fh is not NULL, try
828 * formats are initialized on the file handle. Otherwise active formats are
829 * initialized on the device.
830 */
831static int ccp2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
832{
833 struct v4l2_subdev_format format;
834
835 memset(&format, 0, sizeof(format));
836 format.pad = CCP2_PAD_SINK;
837 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
838 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
839 format.format.width = 4096;
840 format.format.height = 4096;
841 ccp2_set_format(sd, fh, &format);
842
843 return 0;
844}
845
846/*
847 * ccp2_s_stream - Enable/Disable streaming on ccp2 subdev
848 * @sd : pointer to v4l2 subdev structure
849 * @enable: 1 == Enable, 0 == Disable
850 * return zero
851 */
852static int ccp2_s_stream(struct v4l2_subdev *sd, int enable)
853{
854 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
855 struct isp_device *isp = to_isp_device(ccp2);
856 struct device *dev = to_device(ccp2);
857 int ret;
858
859 if (ccp2->state == ISP_PIPELINE_STREAM_STOPPED) {
860 if (enable == ISP_PIPELINE_STREAM_STOPPED)
861 return 0;
862 atomic_set(&ccp2->stopping, 0);
863 ccp2->error = 0;
864 }
865
866 switch (enable) {
867 case ISP_PIPELINE_STREAM_CONTINUOUS:
868 if (ccp2->phy) {
869 ret = omap3isp_csiphy_acquire(ccp2->phy);
870 if (ret < 0)
871 return ret;
872 }
873
874 ccp2_if_configure(ccp2);
875 ccp2_print_status(ccp2);
876
877 /* Enable CSI1/CCP2 interface */
878 ccp2_if_enable(ccp2, 1);
879 break;
880
881 case ISP_PIPELINE_STREAM_SINGLESHOT:
882 if (ccp2->state != ISP_PIPELINE_STREAM_SINGLESHOT) {
883 struct v4l2_mbus_framefmt *format;
884
885 format = &ccp2->formats[CCP2_PAD_SINK];
886
887 ccp2->mem_cfg.hsize_count = format->width;
888 ccp2->mem_cfg.vsize_count = format->height;
889 ccp2->mem_cfg.src_ofst = 0;
890
891 ccp2_mem_configure(ccp2, &ccp2->mem_cfg);
892 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI1_READ);
893 ccp2_print_status(ccp2);
894 }
895 ccp2_mem_enable(ccp2, 1);
896 break;
897
898 case ISP_PIPELINE_STREAM_STOPPED:
899 if (omap3isp_module_sync_idle(&sd->entity, &ccp2->wait,
900 &ccp2->stopping))
901 dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
902 if (ccp2->input == CCP2_INPUT_MEMORY) {
903 ccp2_mem_enable(ccp2, 0);
904 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI1_READ);
905 } else if (ccp2->input == CCP2_INPUT_SENSOR) {
906 /* Disable CSI1/CCP2 interface */
907 ccp2_if_enable(ccp2, 0);
908 if (ccp2->phy)
909 omap3isp_csiphy_release(ccp2->phy);
910 }
911 break;
912 }
913
914 ccp2->state = enable;
915 return 0;
916}
917
918/* subdev video operations */
919static const struct v4l2_subdev_video_ops ccp2_sd_video_ops = {
920 .s_stream = ccp2_s_stream,
921};
922
923/* subdev pad operations */
924static const struct v4l2_subdev_pad_ops ccp2_sd_pad_ops = {
925 .enum_mbus_code = ccp2_enum_mbus_code,
926 .enum_frame_size = ccp2_enum_frame_size,
927 .get_fmt = ccp2_get_format,
928 .set_fmt = ccp2_set_format,
929};
930
931/* subdev operations */
932static const struct v4l2_subdev_ops ccp2_sd_ops = {
933 .video = &ccp2_sd_video_ops,
934 .pad = &ccp2_sd_pad_ops,
935};
936
937/* subdev internal operations */
938static const struct v4l2_subdev_internal_ops ccp2_sd_internal_ops = {
939 .open = ccp2_init_formats,
940};
941
942/* --------------------------------------------------------------------------
943 * ISP ccp2 video device node
944 */
945
946/*
947 * ccp2_video_queue - Queue video buffer.
948 * @video : Pointer to isp video structure
949 * @buffer: Pointer to isp_buffer structure
950 * return -EIO or zero on success
951 */
952static int ccp2_video_queue(struct isp_video *video, struct isp_buffer *buffer)
953{
954 struct isp_ccp2_device *ccp2 = &video->isp->isp_ccp2;
955
956 ccp2_set_inaddr(ccp2, buffer->isp_addr);
957 return 0;
958}
959
960static const struct isp_video_operations ccp2_video_ops = {
961 .queue = ccp2_video_queue,
962};
963
964/* -----------------------------------------------------------------------------
965 * Media entity operations
966 */
967
968/*
969 * ccp2_link_setup - Setup ccp2 connections.
970 * @entity : Pointer to media entity structure
971 * @local : Pointer to local pad array
972 * @remote : Pointer to remote pad array
973 * @flags : Link flags
974 * return -EINVAL on error or zero on success
975 */
976static int ccp2_link_setup(struct media_entity *entity,
977 const struct media_pad *local,
978 const struct media_pad *remote, u32 flags)
979{
980 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
981 struct isp_ccp2_device *ccp2 = v4l2_get_subdevdata(sd);
982
983 switch (local->index | media_entity_type(remote->entity)) {
984 case CCP2_PAD_SINK | MEDIA_ENT_T_DEVNODE:
985 /* read from memory */
986 if (flags & MEDIA_LNK_FL_ENABLED) {
987 if (ccp2->input == CCP2_INPUT_SENSOR)
988 return -EBUSY;
989 ccp2->input = CCP2_INPUT_MEMORY;
990 } else {
991 if (ccp2->input == CCP2_INPUT_MEMORY)
992 ccp2->input = CCP2_INPUT_NONE;
993 }
994 break;
995
996 case CCP2_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
997 /* read from sensor/phy */
998 if (flags & MEDIA_LNK_FL_ENABLED) {
999 if (ccp2->input == CCP2_INPUT_MEMORY)
1000 return -EBUSY;
1001 ccp2->input = CCP2_INPUT_SENSOR;
1002 } else {
1003 if (ccp2->input == CCP2_INPUT_SENSOR)
1004 ccp2->input = CCP2_INPUT_NONE;
1005 } break;
1006
1007 case CCP2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1008 /* write to video port/ccdc */
1009 if (flags & MEDIA_LNK_FL_ENABLED)
1010 ccp2->output = CCP2_OUTPUT_CCDC;
1011 else
1012 ccp2->output = CCP2_OUTPUT_NONE;
1013 break;
1014
1015 default:
1016 return -EINVAL;
1017 }
1018
1019 return 0;
1020}
1021
1022/* media operations */
1023static const struct media_entity_operations ccp2_media_ops = {
1024 .link_setup = ccp2_link_setup,
1025};
1026
1027/*
1028 * ccp2_init_entities - Initialize ccp2 subdev and media entity.
1029 * @ccp2: Pointer to ISP CCP2 device
1030 * return negative error code or zero on success
1031 */
1032static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1033{
1034 struct v4l2_subdev *sd = &ccp2->subdev;
1035 struct media_pad *pads = ccp2->pads;
1036 struct media_entity *me = &sd->entity;
1037 int ret;
1038
1039 ccp2->input = CCP2_INPUT_NONE;
1040 ccp2->output = CCP2_OUTPUT_NONE;
1041
1042 v4l2_subdev_init(sd, &ccp2_sd_ops);
1043 sd->internal_ops = &ccp2_sd_internal_ops;
1044 strlcpy(sd->name, "OMAP3 ISP CCP2", sizeof(sd->name));
1045 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1046 v4l2_set_subdevdata(sd, ccp2);
1047 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1048
1049 pads[CCP2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1050 pads[CCP2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1051
1052 me->ops = &ccp2_media_ops;
1053 ret = media_entity_init(me, CCP2_PADS_NUM, pads, 0);
1054 if (ret < 0)
1055 return ret;
1056
1057 ccp2_init_formats(sd, NULL);
1058
1059 /*
1060 * The CCP2 has weird line alignment requirements, possibly caused by
1061 * DPCM8 decompression. Line length for data read from memory must be a
1062 * multiple of 128 bits (16 bytes) in continuous mode (when no padding
1063 * is present at end of lines). Additionally, if padding is used, the
1064 * padded line length must be a multiple of 32 bytes. To simplify the
1065 * implementation we use a fixed 32 bytes alignment regardless of the
1066 * input format and width. If strict 128 bits alignment support is
1067 * required ispvideo will need to be made aware of this special dual
1068 * alignement requirements.
1069 */
1070 ccp2->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1071 ccp2->video_in.bpl_alignment = 32;
1072 ccp2->video_in.bpl_max = 0xffffffe0;
1073 ccp2->video_in.isp = to_isp_device(ccp2);
1074 ccp2->video_in.ops = &ccp2_video_ops;
1075 ccp2->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1076
1077 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1078 if (ret < 0)
1079 return ret;
1080
1081 /* Connect the video node to the ccp2 subdev. */
1082 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1083 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1084 if (ret < 0)
1085 return ret;
1086
1087 return 0;
1088}
1089
1090/*
1091 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
1092 * @ccp2: Pointer to ISP CCP2 device
1093 */
1094void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1095{
1096 media_entity_cleanup(&ccp2->subdev.entity);
1097
1098 v4l2_device_unregister_subdev(&ccp2->subdev);
1099 omap3isp_video_unregister(&ccp2->video_in);
1100}
1101
1102/*
1103 * omap3isp_ccp2_register_entities - Register the subdev media entity
1104 * @ccp2: Pointer to ISP CCP2 device
1105 * @vdev: Pointer to v4l device
1106 * return negative error code or zero on success
1107 */
1108
1109int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1110 struct v4l2_device *vdev)
1111{
1112 int ret;
1113
1114 /* Register the subdev and video nodes. */
1115 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1116 if (ret < 0)
1117 goto error;
1118
1119 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1120 if (ret < 0)
1121 goto error;
1122
1123 return 0;
1124
1125error:
1126 omap3isp_ccp2_unregister_entities(ccp2);
1127 return ret;
1128}
1129
1130/* -----------------------------------------------------------------------------
1131 * ISP ccp2 initialisation and cleanup
1132 */
1133
1134/*
1135 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1136 * @isp : Pointer to ISP device
1137 */
1138void omap3isp_ccp2_cleanup(struct isp_device *isp)
1139{
1140}
1141
1142/*
1143 * omap3isp_ccp2_init - CCP2 initialization.
1144 * @isp : Pointer to ISP device
1145 * return negative error code or zero on success
1146 */
1147int omap3isp_ccp2_init(struct isp_device *isp)
1148{
1149 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1150 int ret;
1151
1152 init_waitqueue_head(&ccp2->wait);
1153
1154 /* On the OMAP36xx, the CCP2 uses the CSI PHY1 or PHY2, shared with
1155 * the CSI2c or CSI2a receivers. The PHY then needs to be explicitly
1156 * configured.
1157 *
1158 * TODO: Don't hardcode the usage of PHY1 (shared with CSI2c).
1159 */
1160 if (isp->revision == ISP_REVISION_15_0)
1161 ccp2->phy = &isp->isp_csiphy1;
1162
1163 ret = ccp2_init_entities(ccp2);
1164 if (ret < 0)
1165 goto out;
1166
1167 ccp2_reset(ccp2);
1168out:
1169 if (ret)
1170 omap3isp_ccp2_cleanup(isp);
1171
1172 return ret;
1173}
diff --git a/drivers/media/video/omap3isp/ispccp2.h b/drivers/media/video/omap3isp/ispccp2.h
new file mode 100644
index 000000000000..5505a86a9a74
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispccp2.h
@@ -0,0 +1,98 @@
1/*
2 * ispccp2.h
3 *
4 * TI OMAP3 ISP - CCP2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CCP2_H
28#define OMAP3_ISP_CCP2_H
29
30#include <linux/videodev2.h>
31
32struct isp_device;
33struct isp_csiphy;
34
35/* Sink and source ccp2 pads */
36#define CCP2_PAD_SINK 0
37#define CCP2_PAD_SOURCE 1
38#define CCP2_PADS_NUM 2
39
40/* CCP2 input media entity */
41enum ccp2_input_entity {
42 CCP2_INPUT_NONE,
43 CCP2_INPUT_SENSOR,
44 CCP2_INPUT_MEMORY,
45};
46
47/* CCP2 output media entity */
48enum ccp2_output_entity {
49 CCP2_OUTPUT_NONE,
50 CCP2_OUTPUT_CCDC,
51 CCP2_OUTPUT_MEMORY,
52};
53
54
55/* Logical channel configuration */
56struct isp_interface_lcx_config {
57 int crc;
58 u32 data_start;
59 u32 data_size;
60 u32 format;
61};
62
63/* Memory channel configuration */
64struct isp_interface_mem_config {
65 u32 dst_port;
66 u32 vsize_count;
67 u32 hsize_count;
68 u32 src_ofst;
69 u32 dst_ofst;
70};
71
72/* CCP2 device */
73struct isp_ccp2_device {
74 struct v4l2_subdev subdev;
75 struct v4l2_mbus_framefmt formats[CCP2_PADS_NUM];
76 struct media_pad pads[CCP2_PADS_NUM];
77
78 enum ccp2_input_entity input;
79 enum ccp2_output_entity output;
80 struct isp_interface_lcx_config if_cfg;
81 struct isp_interface_mem_config mem_cfg;
82 struct isp_video video_in;
83 struct isp_csiphy *phy;
84 unsigned int error;
85 enum isp_pipeline_stream_state state;
86 wait_queue_head_t wait;
87 atomic_t stopping;
88};
89
90/* Function declarations */
91int omap3isp_ccp2_init(struct isp_device *isp);
92void omap3isp_ccp2_cleanup(struct isp_device *isp);
93int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
94 struct v4l2_device *vdev);
95void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2);
96int omap3isp_ccp2_isr(struct isp_ccp2_device *ccp2);
97
98#endif /* OMAP3_ISP_CCP2_H */
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
new file mode 100644
index 000000000000..fb503f3db3be
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -0,0 +1,1317 @@
1/*
2 * ispcsi2.c
3 *
4 * TI OMAP3 ISP - CSI2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26#include <linux/delay.h>
27#include <media/v4l2-common.h>
28#include <linux/v4l2-mediabus.h>
29#include <linux/mm.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispcsi2.h"
34
35/*
36 * csi2_if_enable - Enable CSI2 Receiver interface.
37 * @enable: enable flag
38 *
39 */
40static void csi2_if_enable(struct isp_device *isp,
41 struct isp_csi2_device *csi2, u8 enable)
42{
43 struct isp_csi2_ctrl_cfg *currctrl = &csi2->ctrl;
44
45 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_CTRL, ISPCSI2_CTRL_IF_EN,
46 enable ? ISPCSI2_CTRL_IF_EN : 0);
47
48 currctrl->if_enable = enable;
49}
50
51/*
52 * csi2_recv_config - CSI2 receiver module configuration.
53 * @currctrl: isp_csi2_ctrl_cfg structure
54 *
55 */
56static void csi2_recv_config(struct isp_device *isp,
57 struct isp_csi2_device *csi2,
58 struct isp_csi2_ctrl_cfg *currctrl)
59{
60 u32 reg;
61
62 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTRL);
63
64 if (currctrl->frame_mode)
65 reg |= ISPCSI2_CTRL_FRAME;
66 else
67 reg &= ~ISPCSI2_CTRL_FRAME;
68
69 if (currctrl->vp_clk_enable)
70 reg |= ISPCSI2_CTRL_VP_CLK_EN;
71 else
72 reg &= ~ISPCSI2_CTRL_VP_CLK_EN;
73
74 if (currctrl->vp_only_enable)
75 reg |= ISPCSI2_CTRL_VP_ONLY_EN;
76 else
77 reg &= ~ISPCSI2_CTRL_VP_ONLY_EN;
78
79 reg &= ~ISPCSI2_CTRL_VP_OUT_CTRL_MASK;
80 reg |= currctrl->vp_out_ctrl << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT;
81
82 if (currctrl->ecc_enable)
83 reg |= ISPCSI2_CTRL_ECC_EN;
84 else
85 reg &= ~ISPCSI2_CTRL_ECC_EN;
86
87 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTRL);
88}
89
90static const unsigned int csi2_input_fmts[] = {
91 V4L2_MBUS_FMT_SGRBG10_1X10,
92 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
93 V4L2_MBUS_FMT_SRGGB10_1X10,
94 V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8,
95 V4L2_MBUS_FMT_SBGGR10_1X10,
96 V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8,
97 V4L2_MBUS_FMT_SGBRG10_1X10,
98 V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8,
99};
100
101/* To set the format on the CSI2 requires a mapping function that takes
102 * the following inputs:
103 * - 2 different formats (at this time)
104 * - 2 destinations (mem, vp+mem) (vp only handled separately)
105 * - 2 decompression options (on, off)
106 * - 2 isp revisions (certain format must be handled differently on OMAP3630)
107 * Output should be CSI2 frame format code
108 * Array indices as follows: [format][dest][decompr][is_3630]
109 * Not all combinations are valid. 0 means invalid.
110 */
111static const u16 __csi2_fmt_map[2][2][2][2] = {
112 /* RAW10 formats */
113 {
114 /* Output to memory */
115 {
116 /* No DPCM decompression */
117 { CSI2_PIX_FMT_RAW10_EXP16, CSI2_PIX_FMT_RAW10_EXP16 },
118 /* DPCM decompression */
119 { 0, 0 },
120 },
121 /* Output to both */
122 {
123 /* No DPCM decompression */
124 { CSI2_PIX_FMT_RAW10_EXP16_VP,
125 CSI2_PIX_FMT_RAW10_EXP16_VP },
126 /* DPCM decompression */
127 { 0, 0 },
128 },
129 },
130 /* RAW10 DPCM8 formats */
131 {
132 /* Output to memory */
133 {
134 /* No DPCM decompression */
135 { CSI2_PIX_FMT_RAW8, CSI2_USERDEF_8BIT_DATA1 },
136 /* DPCM decompression */
137 { CSI2_PIX_FMT_RAW8_DPCM10_EXP16,
138 CSI2_USERDEF_8BIT_DATA1_DPCM10 },
139 },
140 /* Output to both */
141 {
142 /* No DPCM decompression */
143 { CSI2_PIX_FMT_RAW8_VP,
144 CSI2_PIX_FMT_RAW8_VP },
145 /* DPCM decompression */
146 { CSI2_PIX_FMT_RAW8_DPCM10_VP,
147 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP },
148 },
149 },
150};
151
152/*
153 * csi2_ctx_map_format - Map CSI2 sink media bus format to CSI2 format ID
154 * @csi2: ISP CSI2 device
155 *
156 * Returns CSI2 physical format id
157 */
158static u16 csi2_ctx_map_format(struct isp_csi2_device *csi2)
159{
160 const struct v4l2_mbus_framefmt *fmt = &csi2->formats[CSI2_PAD_SINK];
161 int fmtidx, destidx, is_3630;
162
163 switch (fmt->code) {
164 case V4L2_MBUS_FMT_SGRBG10_1X10:
165 case V4L2_MBUS_FMT_SRGGB10_1X10:
166 case V4L2_MBUS_FMT_SBGGR10_1X10:
167 case V4L2_MBUS_FMT_SGBRG10_1X10:
168 fmtidx = 0;
169 break;
170 case V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8:
171 case V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8:
172 case V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8:
173 case V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8:
174 fmtidx = 1;
175 break;
176 default:
177 WARN(1, KERN_ERR "CSI2: pixel format %08x unsupported!\n",
178 fmt->code);
179 return 0;
180 }
181
182 if (!(csi2->output & CSI2_OUTPUT_CCDC) &&
183 !(csi2->output & CSI2_OUTPUT_MEMORY)) {
184 /* Neither output enabled is a valid combination */
185 return CSI2_PIX_FMT_OTHERS;
186 }
187
188 /* If we need to skip frames at the beginning of the stream disable the
189 * video port to avoid sending the skipped frames to the CCDC.
190 */
191 destidx = csi2->frame_skip ? 0 : !!(csi2->output & CSI2_OUTPUT_CCDC);
192 is_3630 = csi2->isp->revision == ISP_REVISION_15_0;
193
194 return __csi2_fmt_map[fmtidx][destidx][csi2->dpcm_decompress][is_3630];
195}
196
197/*
198 * csi2_set_outaddr - Set memory address to save output image
199 * @csi2: Pointer to ISP CSI2a device.
200 * @addr: ISP MMU Mapped 32-bit memory address aligned on 32 byte boundary.
201 *
202 * Sets the memory address where the output will be saved.
203 *
204 * Returns 0 if successful, or -EINVAL if the address is not in the 32 byte
205 * boundary.
206 */
207static void csi2_set_outaddr(struct isp_csi2_device *csi2, u32 addr)
208{
209 struct isp_device *isp = csi2->isp;
210 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[0];
211
212 ctx->ping_addr = addr;
213 ctx->pong_addr = addr;
214 isp_reg_writel(isp, ctx->ping_addr,
215 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
216 isp_reg_writel(isp, ctx->pong_addr,
217 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
218}
219
220/*
221 * is_usr_def_mapping - Checks whether USER_DEF_MAPPING should
222 * be enabled by CSI2.
223 * @format_id: mapped format id
224 *
225 */
226static inline int is_usr_def_mapping(u32 format_id)
227{
228 return (format_id & 0x40) ? 1 : 0;
229}
230
231/*
232 * csi2_ctx_enable - Enable specified CSI2 context
233 * @ctxnum: Context number, valid between 0 and 7 values.
234 * @enable: enable
235 *
236 */
237static void csi2_ctx_enable(struct isp_device *isp,
238 struct isp_csi2_device *csi2, u8 ctxnum, u8 enable)
239{
240 struct isp_csi2_ctx_cfg *ctx = &csi2->contexts[ctxnum];
241 unsigned int skip = 0;
242 u32 reg;
243
244 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
245
246 if (enable) {
247 if (csi2->frame_skip)
248 skip = csi2->frame_skip;
249 else if (csi2->output & CSI2_OUTPUT_MEMORY)
250 skip = 1;
251
252 reg &= ~ISPCSI2_CTX_CTRL1_COUNT_MASK;
253 reg |= ISPCSI2_CTX_CTRL1_COUNT_UNLOCK
254 | (skip << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
255 | ISPCSI2_CTX_CTRL1_CTX_EN;
256 } else {
257 reg &= ~ISPCSI2_CTX_CTRL1_CTX_EN;
258 }
259
260 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctxnum));
261 ctx->enabled = enable;
262}
263
264/*
265 * csi2_ctx_config - CSI2 context configuration.
266 * @ctx: context configuration
267 *
268 */
269static void csi2_ctx_config(struct isp_device *isp,
270 struct isp_csi2_device *csi2,
271 struct isp_csi2_ctx_cfg *ctx)
272{
273 u32 reg;
274
275 /* Set up CSI2_CTx_CTRL1 */
276 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
277
278 if (ctx->eof_enabled)
279 reg |= ISPCSI2_CTX_CTRL1_EOF_EN;
280 else
281 reg &= ~ISPCSI2_CTX_CTRL1_EOF_EN;
282
283 if (ctx->eol_enabled)
284 reg |= ISPCSI2_CTX_CTRL1_EOL_EN;
285 else
286 reg &= ~ISPCSI2_CTX_CTRL1_EOL_EN;
287
288 if (ctx->checksum_enabled)
289 reg |= ISPCSI2_CTX_CTRL1_CS_EN;
290 else
291 reg &= ~ISPCSI2_CTX_CTRL1_CS_EN;
292
293 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL1(ctx->ctxnum));
294
295 /* Set up CSI2_CTx_CTRL2 */
296 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
297
298 reg &= ~(ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK);
299 reg |= ctx->virtual_id << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT;
300
301 reg &= ~(ISPCSI2_CTX_CTRL2_FORMAT_MASK);
302 reg |= ctx->format_id << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT;
303
304 if (ctx->dpcm_decompress) {
305 if (ctx->dpcm_predictor)
306 reg |= ISPCSI2_CTX_CTRL2_DPCM_PRED;
307 else
308 reg &= ~ISPCSI2_CTX_CTRL2_DPCM_PRED;
309 }
310
311 if (is_usr_def_mapping(ctx->format_id)) {
312 reg &= ~ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK;
313 reg |= 2 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT;
314 }
315
316 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL2(ctx->ctxnum));
317
318 /* Set up CSI2_CTx_CTRL3 */
319 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
320 reg &= ~(ISPCSI2_CTX_CTRL3_ALPHA_MASK);
321 reg |= (ctx->alpha << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT);
322
323 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_CTX_CTRL3(ctx->ctxnum));
324
325 /* Set up CSI2_CTx_DAT_OFST */
326 reg = isp_reg_readl(isp, csi2->regs1,
327 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
328 reg &= ~ISPCSI2_CTX_DAT_OFST_OFST_MASK;
329 reg |= ctx->data_offset << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT;
330 isp_reg_writel(isp, reg, csi2->regs1,
331 ISPCSI2_CTX_DAT_OFST(ctx->ctxnum));
332
333 isp_reg_writel(isp, ctx->ping_addr,
334 csi2->regs1, ISPCSI2_CTX_DAT_PING_ADDR(ctx->ctxnum));
335
336 isp_reg_writel(isp, ctx->pong_addr,
337 csi2->regs1, ISPCSI2_CTX_DAT_PONG_ADDR(ctx->ctxnum));
338}
339
340/*
341 * csi2_timing_config - CSI2 timing configuration.
342 * @timing: csi2_timing_cfg structure
343 */
344static void csi2_timing_config(struct isp_device *isp,
345 struct isp_csi2_device *csi2,
346 struct isp_csi2_timing_cfg *timing)
347{
348 u32 reg;
349
350 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_TIMING);
351
352 if (timing->force_rx_mode)
353 reg |= ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
354 else
355 reg &= ~ISPCSI2_TIMING_FORCE_RX_MODE_IO(timing->ionum);
356
357 if (timing->stop_state_16x)
358 reg |= ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
359 else
360 reg &= ~ISPCSI2_TIMING_STOP_STATE_X16_IO(timing->ionum);
361
362 if (timing->stop_state_4x)
363 reg |= ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
364 else
365 reg &= ~ISPCSI2_TIMING_STOP_STATE_X4_IO(timing->ionum);
366
367 reg &= ~ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(timing->ionum);
368 reg |= timing->stop_state_counter <<
369 ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(timing->ionum);
370
371 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_TIMING);
372}
373
374/*
375 * csi2_irq_ctx_set - Enables CSI2 Context IRQs.
376 * @enable: Enable/disable CSI2 Context interrupts
377 */
378static void csi2_irq_ctx_set(struct isp_device *isp,
379 struct isp_csi2_device *csi2, int enable)
380{
381 u32 reg = ISPCSI2_CTX_IRQSTATUS_FE_IRQ;
382 int i;
383
384 if (csi2->use_fs_irq)
385 reg |= ISPCSI2_CTX_IRQSTATUS_FS_IRQ;
386
387 for (i = 0; i < 8; i++) {
388 isp_reg_writel(isp, reg, csi2->regs1,
389 ISPCSI2_CTX_IRQSTATUS(i));
390 if (enable)
391 isp_reg_set(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
392 reg);
393 else
394 isp_reg_clr(isp, csi2->regs1, ISPCSI2_CTX_IRQENABLE(i),
395 reg);
396 }
397}
398
399/*
400 * csi2_irq_complexio1_set - Enables CSI2 ComplexIO IRQs.
401 * @enable: Enable/disable CSI2 ComplexIO #1 interrupts
402 */
403static void csi2_irq_complexio1_set(struct isp_device *isp,
404 struct isp_csi2_device *csi2, int enable)
405{
406 u32 reg;
407 reg = ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT |
408 ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER |
409 ISPCSI2_PHY_IRQENABLE_STATEULPM5 |
410 ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 |
411 ISPCSI2_PHY_IRQENABLE_ERRESC5 |
412 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 |
413 ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 |
414 ISPCSI2_PHY_IRQENABLE_STATEULPM4 |
415 ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 |
416 ISPCSI2_PHY_IRQENABLE_ERRESC4 |
417 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 |
418 ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 |
419 ISPCSI2_PHY_IRQENABLE_STATEULPM3 |
420 ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 |
421 ISPCSI2_PHY_IRQENABLE_ERRESC3 |
422 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 |
423 ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 |
424 ISPCSI2_PHY_IRQENABLE_STATEULPM2 |
425 ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 |
426 ISPCSI2_PHY_IRQENABLE_ERRESC2 |
427 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 |
428 ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 |
429 ISPCSI2_PHY_IRQENABLE_STATEULPM1 |
430 ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 |
431 ISPCSI2_PHY_IRQENABLE_ERRESC1 |
432 ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 |
433 ISPCSI2_PHY_IRQENABLE_ERRSOTHS1;
434 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
435 if (enable)
436 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
437 else
438 reg = 0;
439 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_PHY_IRQENABLE);
440}
441
442/*
443 * csi2_irq_status_set - Enables CSI2 Status IRQs.
444 * @enable: Enable/disable CSI2 Status interrupts
445 */
446static void csi2_irq_status_set(struct isp_device *isp,
447 struct isp_csi2_device *csi2, int enable)
448{
449 u32 reg;
450 reg = ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
451 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
452 ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ |
453 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
454 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
455 ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ |
456 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ |
457 ISPCSI2_IRQSTATUS_CONTEXT(0);
458 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQSTATUS);
459 if (enable)
460 reg |= isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQENABLE);
461 else
462 reg = 0;
463
464 isp_reg_writel(isp, reg, csi2->regs1, ISPCSI2_IRQENABLE);
465}
466
467/*
468 * omap3isp_csi2_reset - Resets the CSI2 module.
469 *
470 * Must be called with the phy lock held.
471 *
472 * Returns 0 if successful, or -EBUSY if power command didn't respond.
473 */
474int omap3isp_csi2_reset(struct isp_csi2_device *csi2)
475{
476 struct isp_device *isp = csi2->isp;
477 u8 soft_reset_retries = 0;
478 u32 reg;
479 int i;
480
481 if (!csi2->available)
482 return -ENODEV;
483
484 if (csi2->phy->phy_in_use)
485 return -EBUSY;
486
487 isp_reg_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
488 ISPCSI2_SYSCONFIG_SOFT_RESET);
489
490 do {
491 reg = isp_reg_readl(isp, csi2->regs1, ISPCSI2_SYSSTATUS) &
492 ISPCSI2_SYSSTATUS_RESET_DONE;
493 if (reg == ISPCSI2_SYSSTATUS_RESET_DONE)
494 break;
495 soft_reset_retries++;
496 if (soft_reset_retries < 5)
497 udelay(100);
498 } while (soft_reset_retries < 5);
499
500 if (soft_reset_retries == 5) {
501 printk(KERN_ERR "CSI2: Soft reset try count exceeded!\n");
502 return -EBUSY;
503 }
504
505 if (isp->revision == ISP_REVISION_15_0)
506 isp_reg_set(isp, csi2->regs1, ISPCSI2_PHY_CFG,
507 ISPCSI2_PHY_CFG_RESET_CTRL);
508
509 i = 100;
510 do {
511 reg = isp_reg_readl(isp, csi2->phy->phy_regs, ISPCSIPHY_REG1)
512 & ISPCSIPHY_REG1_RESET_DONE_CTRLCLK;
513 if (reg == ISPCSIPHY_REG1_RESET_DONE_CTRLCLK)
514 break;
515 udelay(100);
516 } while (--i > 0);
517
518 if (i == 0) {
519 printk(KERN_ERR
520 "CSI2: Reset for CSI2_96M_FCLK domain Failed!\n");
521 return -EBUSY;
522 }
523
524 if (isp->autoidle)
525 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
526 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
527 ISPCSI2_SYSCONFIG_AUTO_IDLE,
528 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART |
529 ((isp->revision == ISP_REVISION_15_0) ?
530 ISPCSI2_SYSCONFIG_AUTO_IDLE : 0));
531 else
532 isp_reg_clr_set(isp, csi2->regs1, ISPCSI2_SYSCONFIG,
533 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK |
534 ISPCSI2_SYSCONFIG_AUTO_IDLE,
535 ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO);
536
537 return 0;
538}
539
540static int csi2_configure(struct isp_csi2_device *csi2)
541{
542 const struct isp_v4l2_subdevs_group *pdata;
543 struct isp_device *isp = csi2->isp;
544 struct isp_csi2_timing_cfg *timing = &csi2->timing[0];
545 struct v4l2_subdev *sensor;
546 struct media_pad *pad;
547
548 /*
549 * CSI2 fields that can be updated while the context has
550 * been enabled or the interface has been enabled are not
551 * updated dynamically currently. So we do not allow to
552 * reconfigure if either has been enabled
553 */
554 if (csi2->contexts[0].enabled || csi2->ctrl.if_enable)
555 return -EBUSY;
556
557 pad = media_entity_remote_source(&csi2->pads[CSI2_PAD_SINK]);
558 sensor = media_entity_to_v4l2_subdev(pad->entity);
559 pdata = sensor->host_priv;
560
561 csi2->frame_skip = 0;
562 v4l2_subdev_call(sensor, sensor, g_skip_frames, &csi2->frame_skip);
563
564 csi2->ctrl.vp_out_ctrl = pdata->bus.csi2.vpclk_div;
565 csi2->ctrl.frame_mode = ISP_CSI2_FRAME_IMMEDIATE;
566 csi2->ctrl.ecc_enable = pdata->bus.csi2.crc;
567
568 timing->ionum = 1;
569 timing->force_rx_mode = 1;
570 timing->stop_state_16x = 1;
571 timing->stop_state_4x = 1;
572 timing->stop_state_counter = 0x1FF;
573
574 /*
575 * The CSI2 receiver can't do any format conversion except DPCM
576 * decompression, so every set_format call configures both pads
577 * and enables DPCM decompression as a special case:
578 */
579 if (csi2->formats[CSI2_PAD_SINK].code !=
580 csi2->formats[CSI2_PAD_SOURCE].code)
581 csi2->dpcm_decompress = true;
582 else
583 csi2->dpcm_decompress = false;
584
585 csi2->contexts[0].format_id = csi2_ctx_map_format(csi2);
586
587 if (csi2->video_out.bpl_padding == 0)
588 csi2->contexts[0].data_offset = 0;
589 else
590 csi2->contexts[0].data_offset = csi2->video_out.bpl_value;
591
592 /*
593 * Enable end of frame and end of line signals generation for
594 * context 0. These signals are generated from CSI2 receiver to
595 * qualify the last pixel of a frame and the last pixel of a line.
596 * Without enabling the signals CSI2 receiver writes data to memory
597 * beyond buffer size and/or data line offset is not handled correctly.
598 */
599 csi2->contexts[0].eof_enabled = 1;
600 csi2->contexts[0].eol_enabled = 1;
601
602 csi2_irq_complexio1_set(isp, csi2, 1);
603 csi2_irq_ctx_set(isp, csi2, 1);
604 csi2_irq_status_set(isp, csi2, 1);
605
606 /* Set configuration (timings, format and links) */
607 csi2_timing_config(isp, csi2, timing);
608 csi2_recv_config(isp, csi2, &csi2->ctrl);
609 csi2_ctx_config(isp, csi2, &csi2->contexts[0]);
610
611 return 0;
612}
613
614/*
615 * csi2_print_status - Prints CSI2 debug information.
616 */
617#define CSI2_PRINT_REGISTER(isp, regs, name)\
618 dev_dbg(isp->dev, "###CSI2 " #name "=0x%08x\n", \
619 isp_reg_readl(isp, regs, ISPCSI2_##name))
620
621static void csi2_print_status(struct isp_csi2_device *csi2)
622{
623 struct isp_device *isp = csi2->isp;
624
625 if (!csi2->available)
626 return;
627
628 dev_dbg(isp->dev, "-------------CSI2 Register dump-------------\n");
629
630 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSCONFIG);
631 CSI2_PRINT_REGISTER(isp, csi2->regs1, SYSSTATUS);
632 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQENABLE);
633 CSI2_PRINT_REGISTER(isp, csi2->regs1, IRQSTATUS);
634 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTRL);
635 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_H);
636 CSI2_PRINT_REGISTER(isp, csi2->regs1, GNQ);
637 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_CFG);
638 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQSTATUS);
639 CSI2_PRINT_REGISTER(isp, csi2->regs1, SHORT_PACKET);
640 CSI2_PRINT_REGISTER(isp, csi2->regs1, PHY_IRQENABLE);
641 CSI2_PRINT_REGISTER(isp, csi2->regs1, DBG_P);
642 CSI2_PRINT_REGISTER(isp, csi2->regs1, TIMING);
643 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL1(0));
644 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL2(0));
645 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_OFST(0));
646 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PING_ADDR(0));
647 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_DAT_PONG_ADDR(0));
648 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQENABLE(0));
649 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_IRQSTATUS(0));
650 CSI2_PRINT_REGISTER(isp, csi2->regs1, CTX_CTRL3(0));
651
652 dev_dbg(isp->dev, "--------------------------------------------\n");
653}
654
655/* -----------------------------------------------------------------------------
656 * Interrupt handling
657 */
658
659/*
660 * csi2_isr_buffer - Does buffer handling at end-of-frame
661 * when writing to memory.
662 */
663static void csi2_isr_buffer(struct isp_csi2_device *csi2)
664{
665 struct isp_device *isp = csi2->isp;
666 struct isp_buffer *buffer;
667
668 csi2_ctx_enable(isp, csi2, 0, 0);
669
670 buffer = omap3isp_video_buffer_next(&csi2->video_out, 0);
671
672 /*
673 * Let video queue operation restart engine if there is an underrun
674 * condition.
675 */
676 if (buffer == NULL)
677 return;
678
679 csi2_set_outaddr(csi2, buffer->isp_addr);
680 csi2_ctx_enable(isp, csi2, 0, 1);
681}
682
683static void csi2_isr_ctx(struct isp_csi2_device *csi2,
684 struct isp_csi2_ctx_cfg *ctx)
685{
686 struct isp_device *isp = csi2->isp;
687 unsigned int n = ctx->ctxnum;
688 u32 status;
689
690 status = isp_reg_readl(isp, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
691 isp_reg_writel(isp, status, csi2->regs1, ISPCSI2_CTX_IRQSTATUS(n));
692
693 /* Propagate frame number */
694 if (status & ISPCSI2_CTX_IRQSTATUS_FS_IRQ) {
695 struct isp_pipeline *pipe =
696 to_isp_pipeline(&csi2->subdev.entity);
697 if (pipe->do_propagation)
698 atomic_inc(&pipe->frame_number);
699 }
700
701 if (!(status & ISPCSI2_CTX_IRQSTATUS_FE_IRQ))
702 return;
703
704 /* Skip interrupts until we reach the frame skip count. The CSI2 will be
705 * automatically disabled, as the frame skip count has been programmed
706 * in the CSI2_CTx_CTRL1::COUNT field, so reenable it.
707 *
708 * It would have been nice to rely on the FRAME_NUMBER interrupt instead
709 * but it turned out that the interrupt is only generated when the CSI2
710 * writes to memory (the CSI2_CTx_CTRL1::COUNT field is decreased
711 * correctly and reaches 0 when data is forwarded to the video port only
712 * but no interrupt arrives). Maybe a CSI2 hardware bug.
713 */
714 if (csi2->frame_skip) {
715 csi2->frame_skip--;
716 if (csi2->frame_skip == 0) {
717 ctx->format_id = csi2_ctx_map_format(csi2);
718 csi2_ctx_config(isp, csi2, ctx);
719 csi2_ctx_enable(isp, csi2, n, 1);
720 }
721 return;
722 }
723
724 if (csi2->output & CSI2_OUTPUT_MEMORY)
725 csi2_isr_buffer(csi2);
726}
727
728/*
729 * omap3isp_csi2_isr - CSI2 interrupt handling.
730 *
731 * Return -EIO on Transmission error
732 */
733int omap3isp_csi2_isr(struct isp_csi2_device *csi2)
734{
735 u32 csi2_irqstatus, cpxio1_irqstatus;
736 struct isp_device *isp = csi2->isp;
737 int retval = 0;
738
739 if (!csi2->available)
740 return -ENODEV;
741
742 csi2_irqstatus = isp_reg_readl(isp, csi2->regs1, ISPCSI2_IRQSTATUS);
743 isp_reg_writel(isp, csi2_irqstatus, csi2->regs1, ISPCSI2_IRQSTATUS);
744
745 /* Failure Cases */
746 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ) {
747 cpxio1_irqstatus = isp_reg_readl(isp, csi2->regs1,
748 ISPCSI2_PHY_IRQSTATUS);
749 isp_reg_writel(isp, cpxio1_irqstatus,
750 csi2->regs1, ISPCSI2_PHY_IRQSTATUS);
751 dev_dbg(isp->dev, "CSI2: ComplexIO Error IRQ "
752 "%x\n", cpxio1_irqstatus);
753 retval = -EIO;
754 }
755
756 if (csi2_irqstatus & (ISPCSI2_IRQSTATUS_OCP_ERR_IRQ |
757 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ |
758 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ |
759 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ |
760 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ)) {
761 dev_dbg(isp->dev, "CSI2 Err:"
762 " OCP:%d,"
763 " Short_pack:%d,"
764 " ECC:%d,"
765 " CPXIO2:%d,"
766 " FIFO_OVF:%d,"
767 "\n",
768 (csi2_irqstatus &
769 ISPCSI2_IRQSTATUS_OCP_ERR_IRQ) ? 1 : 0,
770 (csi2_irqstatus &
771 ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ) ? 1 : 0,
772 (csi2_irqstatus &
773 ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ) ? 1 : 0,
774 (csi2_irqstatus &
775 ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ) ? 1 : 0,
776 (csi2_irqstatus &
777 ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ) ? 1 : 0);
778 retval = -EIO;
779 }
780
781 if (omap3isp_module_sync_is_stopping(&csi2->wait, &csi2->stopping))
782 return 0;
783
784 /* Successful cases */
785 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_CONTEXT(0))
786 csi2_isr_ctx(csi2, &csi2->contexts[0]);
787
788 if (csi2_irqstatus & ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ)
789 dev_dbg(isp->dev, "CSI2: ECC correction done\n");
790
791 return retval;
792}
793
794/* -----------------------------------------------------------------------------
795 * ISP video operations
796 */
797
798/*
799 * csi2_queue - Queues the first buffer when using memory output
800 * @video: The video node
801 * @buffer: buffer to queue
802 */
803static int csi2_queue(struct isp_video *video, struct isp_buffer *buffer)
804{
805 struct isp_device *isp = video->isp;
806 struct isp_csi2_device *csi2 = &isp->isp_csi2a;
807
808 csi2_set_outaddr(csi2, buffer->isp_addr);
809
810 /*
811 * If streaming was enabled before there was a buffer queued
812 * or underrun happened in the ISR, the hardware was not enabled
813 * and DMA queue flag ISP_VIDEO_DMAQUEUE_UNDERRUN is still set.
814 * Enable it now.
815 */
816 if (csi2->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_UNDERRUN) {
817 /* Enable / disable context 0 and IRQs */
818 csi2_if_enable(isp, csi2, 1);
819 csi2_ctx_enable(isp, csi2, 0, 1);
820 isp_video_dmaqueue_flags_clr(&csi2->video_out);
821 }
822
823 return 0;
824}
825
826static const struct isp_video_operations csi2_ispvideo_ops = {
827 .queue = csi2_queue,
828};
829
830/* -----------------------------------------------------------------------------
831 * V4L2 subdev operations
832 */
833
834static struct v4l2_mbus_framefmt *
835__csi2_get_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
836 unsigned int pad, enum v4l2_subdev_format_whence which)
837{
838 if (which == V4L2_SUBDEV_FORMAT_TRY)
839 return v4l2_subdev_get_try_format(fh, pad);
840 else
841 return &csi2->formats[pad];
842}
843
844static void
845csi2_try_format(struct isp_csi2_device *csi2, struct v4l2_subdev_fh *fh,
846 unsigned int pad, struct v4l2_mbus_framefmt *fmt,
847 enum v4l2_subdev_format_whence which)
848{
849 enum v4l2_mbus_pixelcode pixelcode;
850 struct v4l2_mbus_framefmt *format;
851 const struct isp_format_info *info;
852 unsigned int i;
853
854 switch (pad) {
855 case CSI2_PAD_SINK:
856 /* Clamp the width and height to valid range (1-8191). */
857 for (i = 0; i < ARRAY_SIZE(csi2_input_fmts); i++) {
858 if (fmt->code == csi2_input_fmts[i])
859 break;
860 }
861
862 /* If not found, use SGRBG10 as default */
863 if (i >= ARRAY_SIZE(csi2_input_fmts))
864 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
865
866 fmt->width = clamp_t(u32, fmt->width, 1, 8191);
867 fmt->height = clamp_t(u32, fmt->height, 1, 8191);
868 break;
869
870 case CSI2_PAD_SOURCE:
871 /* Source format same as sink format, except for DPCM
872 * compression.
873 */
874 pixelcode = fmt->code;
875 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK, which);
876 memcpy(fmt, format, sizeof(*fmt));
877
878 /*
879 * Only Allow DPCM decompression, and check that the
880 * pattern is preserved
881 */
882 info = omap3isp_video_format_info(fmt->code);
883 if (info->uncompressed == pixelcode)
884 fmt->code = pixelcode;
885 break;
886 }
887
888 /* RGB, non-interlaced */
889 fmt->colorspace = V4L2_COLORSPACE_SRGB;
890 fmt->field = V4L2_FIELD_NONE;
891}
892
893/*
894 * csi2_enum_mbus_code - Handle pixel format enumeration
895 * @sd : pointer to v4l2 subdev structure
896 * @fh : V4L2 subdev file handle
897 * @code : pointer to v4l2_subdev_mbus_code_enum structure
898 * return -EINVAL or zero on success
899 */
900static int csi2_enum_mbus_code(struct v4l2_subdev *sd,
901 struct v4l2_subdev_fh *fh,
902 struct v4l2_subdev_mbus_code_enum *code)
903{
904 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
905 struct v4l2_mbus_framefmt *format;
906 const struct isp_format_info *info;
907
908 if (code->pad == CSI2_PAD_SINK) {
909 if (code->index >= ARRAY_SIZE(csi2_input_fmts))
910 return -EINVAL;
911
912 code->code = csi2_input_fmts[code->index];
913 } else {
914 format = __csi2_get_format(csi2, fh, CSI2_PAD_SINK,
915 V4L2_SUBDEV_FORMAT_TRY);
916 switch (code->index) {
917 case 0:
918 /* Passthrough sink pad code */
919 code->code = format->code;
920 break;
921 case 1:
922 /* Uncompressed code */
923 info = omap3isp_video_format_info(format->code);
924 if (info->uncompressed == format->code)
925 return -EINVAL;
926
927 code->code = info->uncompressed;
928 break;
929 default:
930 return -EINVAL;
931 }
932 }
933
934 return 0;
935}
936
937static int csi2_enum_frame_size(struct v4l2_subdev *sd,
938 struct v4l2_subdev_fh *fh,
939 struct v4l2_subdev_frame_size_enum *fse)
940{
941 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
942 struct v4l2_mbus_framefmt format;
943
944 if (fse->index != 0)
945 return -EINVAL;
946
947 format.code = fse->code;
948 format.width = 1;
949 format.height = 1;
950 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
951 fse->min_width = format.width;
952 fse->min_height = format.height;
953
954 if (format.code != fse->code)
955 return -EINVAL;
956
957 format.code = fse->code;
958 format.width = -1;
959 format.height = -1;
960 csi2_try_format(csi2, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
961 fse->max_width = format.width;
962 fse->max_height = format.height;
963
964 return 0;
965}
966
967/*
968 * csi2_get_format - Handle get format by pads subdev method
969 * @sd : pointer to v4l2 subdev structure
970 * @fh : V4L2 subdev file handle
971 * @fmt: pointer to v4l2 subdev format structure
972 * return -EINVAL or zero on sucess
973 */
974static int csi2_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
975 struct v4l2_subdev_format *fmt)
976{
977 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
978 struct v4l2_mbus_framefmt *format;
979
980 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
981 if (format == NULL)
982 return -EINVAL;
983
984 fmt->format = *format;
985 return 0;
986}
987
988/*
989 * csi2_set_format - Handle set format by pads subdev method
990 * @sd : pointer to v4l2 subdev structure
991 * @fh : V4L2 subdev file handle
992 * @fmt: pointer to v4l2 subdev format structure
993 * return -EINVAL or zero on success
994 */
995static int csi2_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
996 struct v4l2_subdev_format *fmt)
997{
998 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
999 struct v4l2_mbus_framefmt *format;
1000
1001 format = __csi2_get_format(csi2, fh, fmt->pad, fmt->which);
1002 if (format == NULL)
1003 return -EINVAL;
1004
1005 csi2_try_format(csi2, fh, fmt->pad, &fmt->format, fmt->which);
1006 *format = fmt->format;
1007
1008 /* Propagate the format from sink to source */
1009 if (fmt->pad == CSI2_PAD_SINK) {
1010 format = __csi2_get_format(csi2, fh, CSI2_PAD_SOURCE,
1011 fmt->which);
1012 *format = fmt->format;
1013 csi2_try_format(csi2, fh, CSI2_PAD_SOURCE, format, fmt->which);
1014 }
1015
1016 return 0;
1017}
1018
1019/*
1020 * csi2_init_formats - Initialize formats on all pads
1021 * @sd: ISP CSI2 V4L2 subdevice
1022 * @fh: V4L2 subdev file handle
1023 *
1024 * Initialize all pad formats with default values. If fh is not NULL, try
1025 * formats are initialized on the file handle. Otherwise active formats are
1026 * initialized on the device.
1027 */
1028static int csi2_init_formats(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1029{
1030 struct v4l2_subdev_format format;
1031
1032 memset(&format, 0, sizeof(format));
1033 format.pad = CSI2_PAD_SINK;
1034 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1035 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1036 format.format.width = 4096;
1037 format.format.height = 4096;
1038 csi2_set_format(sd, fh, &format);
1039
1040 return 0;
1041}
1042
1043/*
1044 * csi2_set_stream - Enable/Disable streaming on the CSI2 module
1045 * @sd: ISP CSI2 V4L2 subdevice
1046 * @enable: ISP pipeline stream state
1047 *
1048 * Return 0 on success or a negative error code otherwise.
1049 */
1050static int csi2_set_stream(struct v4l2_subdev *sd, int enable)
1051{
1052 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1053 struct isp_device *isp = csi2->isp;
1054 struct isp_pipeline *pipe = to_isp_pipeline(&csi2->subdev.entity);
1055 struct isp_video *video_out = &csi2->video_out;
1056
1057 switch (enable) {
1058 case ISP_PIPELINE_STREAM_CONTINUOUS:
1059 if (omap3isp_csiphy_acquire(csi2->phy) < 0)
1060 return -ENODEV;
1061 csi2->use_fs_irq = pipe->do_propagation;
1062 if (csi2->output & CSI2_OUTPUT_MEMORY)
1063 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1064 csi2_configure(csi2);
1065 csi2_print_status(csi2);
1066
1067 /*
1068 * When outputting to memory with no buffer available, let the
1069 * buffer queue handler start the hardware. A DMA queue flag
1070 * ISP_VIDEO_DMAQUEUE_QUEUED will be set as soon as there is
1071 * a buffer available.
1072 */
1073 if (csi2->output & CSI2_OUTPUT_MEMORY &&
1074 !(video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED))
1075 break;
1076 /* Enable context 0 and IRQs */
1077 atomic_set(&csi2->stopping, 0);
1078 csi2_ctx_enable(isp, csi2, 0, 1);
1079 csi2_if_enable(isp, csi2, 1);
1080 isp_video_dmaqueue_flags_clr(video_out);
1081 break;
1082
1083 case ISP_PIPELINE_STREAM_STOPPED:
1084 if (csi2->state == ISP_PIPELINE_STREAM_STOPPED)
1085 return 0;
1086 if (omap3isp_module_sync_idle(&sd->entity, &csi2->wait,
1087 &csi2->stopping))
1088 dev_dbg(isp->dev, "%s: module stop timeout.\n",
1089 sd->name);
1090 csi2_ctx_enable(isp, csi2, 0, 0);
1091 csi2_if_enable(isp, csi2, 0);
1092 csi2_irq_ctx_set(isp, csi2, 0);
1093 omap3isp_csiphy_release(csi2->phy);
1094 isp_video_dmaqueue_flags_clr(video_out);
1095 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_CSI2A_WRITE);
1096 break;
1097 }
1098
1099 csi2->state = enable;
1100 return 0;
1101}
1102
1103/* subdev video operations */
1104static const struct v4l2_subdev_video_ops csi2_video_ops = {
1105 .s_stream = csi2_set_stream,
1106};
1107
1108/* subdev pad operations */
1109static const struct v4l2_subdev_pad_ops csi2_pad_ops = {
1110 .enum_mbus_code = csi2_enum_mbus_code,
1111 .enum_frame_size = csi2_enum_frame_size,
1112 .get_fmt = csi2_get_format,
1113 .set_fmt = csi2_set_format,
1114};
1115
1116/* subdev operations */
1117static const struct v4l2_subdev_ops csi2_ops = {
1118 .video = &csi2_video_ops,
1119 .pad = &csi2_pad_ops,
1120};
1121
1122/* subdev internal operations */
1123static const struct v4l2_subdev_internal_ops csi2_internal_ops = {
1124 .open = csi2_init_formats,
1125};
1126
1127/* -----------------------------------------------------------------------------
1128 * Media entity operations
1129 */
1130
1131/*
1132 * csi2_link_setup - Setup CSI2 connections.
1133 * @entity : Pointer to media entity structure
1134 * @local : Pointer to local pad array
1135 * @remote : Pointer to remote pad array
1136 * @flags : Link flags
1137 * return -EINVAL or zero on success
1138 */
1139static int csi2_link_setup(struct media_entity *entity,
1140 const struct media_pad *local,
1141 const struct media_pad *remote, u32 flags)
1142{
1143 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1144 struct isp_csi2_device *csi2 = v4l2_get_subdevdata(sd);
1145 struct isp_csi2_ctrl_cfg *ctrl = &csi2->ctrl;
1146
1147 /*
1148 * The ISP core doesn't support pipelines with multiple video outputs.
1149 * Revisit this when it will be implemented, and return -EBUSY for now.
1150 */
1151
1152 switch (local->index | media_entity_type(remote->entity)) {
1153 case CSI2_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1154 if (flags & MEDIA_LNK_FL_ENABLED) {
1155 if (csi2->output & ~CSI2_OUTPUT_MEMORY)
1156 return -EBUSY;
1157 csi2->output |= CSI2_OUTPUT_MEMORY;
1158 } else {
1159 csi2->output &= ~CSI2_OUTPUT_MEMORY;
1160 }
1161 break;
1162
1163 case CSI2_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1164 if (flags & MEDIA_LNK_FL_ENABLED) {
1165 if (csi2->output & ~CSI2_OUTPUT_CCDC)
1166 return -EBUSY;
1167 csi2->output |= CSI2_OUTPUT_CCDC;
1168 } else {
1169 csi2->output &= ~CSI2_OUTPUT_CCDC;
1170 }
1171 break;
1172
1173 default:
1174 /* Link from camera to CSI2 is fixed... */
1175 return -EINVAL;
1176 }
1177
1178 ctrl->vp_only_enable =
1179 (csi2->output & CSI2_OUTPUT_MEMORY) ? false : true;
1180 ctrl->vp_clk_enable = !!(csi2->output & CSI2_OUTPUT_CCDC);
1181
1182 return 0;
1183}
1184
1185/* media operations */
1186static const struct media_entity_operations csi2_media_ops = {
1187 .link_setup = csi2_link_setup,
1188};
1189
1190/*
1191 * csi2_init_entities - Initialize subdev and media entity.
1192 * @csi2: Pointer to csi2 structure.
1193 * return -ENOMEM or zero on success
1194 */
1195static int csi2_init_entities(struct isp_csi2_device *csi2)
1196{
1197 struct v4l2_subdev *sd = &csi2->subdev;
1198 struct media_pad *pads = csi2->pads;
1199 struct media_entity *me = &sd->entity;
1200 int ret;
1201
1202 v4l2_subdev_init(sd, &csi2_ops);
1203 sd->internal_ops = &csi2_internal_ops;
1204 strlcpy(sd->name, "OMAP3 ISP CSI2a", sizeof(sd->name));
1205
1206 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1207 v4l2_set_subdevdata(sd, csi2);
1208 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1209
1210 pads[CSI2_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1211 pads[CSI2_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1212
1213 me->ops = &csi2_media_ops;
1214 ret = media_entity_init(me, CSI2_PADS_NUM, pads, 0);
1215 if (ret < 0)
1216 return ret;
1217
1218 csi2_init_formats(sd, NULL);
1219
1220 /* Video device node */
1221 csi2->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1222 csi2->video_out.ops = &csi2_ispvideo_ops;
1223 csi2->video_out.bpl_alignment = 32;
1224 csi2->video_out.bpl_zero_padding = 1;
1225 csi2->video_out.bpl_max = 0x1ffe0;
1226 csi2->video_out.isp = csi2->isp;
1227 csi2->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 3;
1228
1229 ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
1230 if (ret < 0)
1231 return ret;
1232
1233 /* Connect the CSI2 subdev to the video node. */
1234 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1235 &csi2->video_out.video.entity, 0, 0);
1236 if (ret < 0)
1237 return ret;
1238
1239 return 0;
1240}
1241
1242void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
1243{
1244 media_entity_cleanup(&csi2->subdev.entity);
1245
1246 v4l2_device_unregister_subdev(&csi2->subdev);
1247 omap3isp_video_unregister(&csi2->video_out);
1248}
1249
1250int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
1251 struct v4l2_device *vdev)
1252{
1253 int ret;
1254
1255 /* Register the subdev and video nodes. */
1256 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1257 if (ret < 0)
1258 goto error;
1259
1260 ret = omap3isp_video_register(&csi2->video_out, vdev);
1261 if (ret < 0)
1262 goto error;
1263
1264 return 0;
1265
1266error:
1267 omap3isp_csi2_unregister_entities(csi2);
1268 return ret;
1269}
1270
1271/* -----------------------------------------------------------------------------
1272 * ISP CSI2 initialisation and cleanup
1273 */
1274
1275/*
1276 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1277 */
1278void omap3isp_csi2_cleanup(struct isp_device *isp)
1279{
1280}
1281
1282/*
1283 * omap3isp_csi2_init - Routine for module driver init
1284 */
1285int omap3isp_csi2_init(struct isp_device *isp)
1286{
1287 struct isp_csi2_device *csi2a = &isp->isp_csi2a;
1288 struct isp_csi2_device *csi2c = &isp->isp_csi2c;
1289 int ret;
1290
1291 csi2a->isp = isp;
1292 csi2a->available = 1;
1293 csi2a->regs1 = OMAP3_ISP_IOMEM_CSI2A_REGS1;
1294 csi2a->regs2 = OMAP3_ISP_IOMEM_CSI2A_REGS2;
1295 csi2a->phy = &isp->isp_csiphy2;
1296 csi2a->state = ISP_PIPELINE_STREAM_STOPPED;
1297 init_waitqueue_head(&csi2a->wait);
1298
1299 ret = csi2_init_entities(csi2a);
1300 if (ret < 0)
1301 goto fail;
1302
1303 if (isp->revision == ISP_REVISION_15_0) {
1304 csi2c->isp = isp;
1305 csi2c->available = 1;
1306 csi2c->regs1 = OMAP3_ISP_IOMEM_CSI2C_REGS1;
1307 csi2c->regs2 = OMAP3_ISP_IOMEM_CSI2C_REGS2;
1308 csi2c->phy = &isp->isp_csiphy1;
1309 csi2c->state = ISP_PIPELINE_STREAM_STOPPED;
1310 init_waitqueue_head(&csi2c->wait);
1311 }
1312
1313 return 0;
1314fail:
1315 omap3isp_csi2_cleanup(isp);
1316 return ret;
1317}
diff --git a/drivers/media/video/omap3isp/ispcsi2.h b/drivers/media/video/omap3isp/ispcsi2.h
new file mode 100644
index 000000000000..456fb7fb8a0f
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsi2.h
@@ -0,0 +1,166 @@
1/*
2 * ispcsi2.h
3 *
4 * TI OMAP3 ISP - CSI2 module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CSI2_H
28#define OMAP3_ISP_CSI2_H
29
30#include <linux/types.h>
31#include <linux/videodev2.h>
32
33struct isp_csiphy;
34
35/* This is not an exhaustive list */
36enum isp_csi2_pix_formats {
37 CSI2_PIX_FMT_OTHERS = 0,
38 CSI2_PIX_FMT_YUV422_8BIT = 0x1e,
39 CSI2_PIX_FMT_YUV422_8BIT_VP = 0x9e,
40 CSI2_PIX_FMT_RAW10_EXP16 = 0xab,
41 CSI2_PIX_FMT_RAW10_EXP16_VP = 0x12f,
42 CSI2_PIX_FMT_RAW8 = 0x2a,
43 CSI2_PIX_FMT_RAW8_DPCM10_EXP16 = 0x2aa,
44 CSI2_PIX_FMT_RAW8_DPCM10_VP = 0x32a,
45 CSI2_PIX_FMT_RAW8_VP = 0x12a,
46 CSI2_USERDEF_8BIT_DATA1_DPCM10_VP = 0x340,
47 CSI2_USERDEF_8BIT_DATA1_DPCM10 = 0x2c0,
48 CSI2_USERDEF_8BIT_DATA1 = 0x40,
49};
50
51enum isp_csi2_irqevents {
52 OCP_ERR_IRQ = 0x4000,
53 SHORT_PACKET_IRQ = 0x2000,
54 ECC_CORRECTION_IRQ = 0x1000,
55 ECC_NO_CORRECTION_IRQ = 0x800,
56 COMPLEXIO2_ERR_IRQ = 0x400,
57 COMPLEXIO1_ERR_IRQ = 0x200,
58 FIFO_OVF_IRQ = 0x100,
59 CONTEXT7 = 0x80,
60 CONTEXT6 = 0x40,
61 CONTEXT5 = 0x20,
62 CONTEXT4 = 0x10,
63 CONTEXT3 = 0x8,
64 CONTEXT2 = 0x4,
65 CONTEXT1 = 0x2,
66 CONTEXT0 = 0x1,
67};
68
69enum isp_csi2_ctx_irqevents {
70 CTX_ECC_CORRECTION = 0x100,
71 CTX_LINE_NUMBER = 0x80,
72 CTX_FRAME_NUMBER = 0x40,
73 CTX_CS = 0x20,
74 CTX_LE = 0x8,
75 CTX_LS = 0x4,
76 CTX_FE = 0x2,
77 CTX_FS = 0x1,
78};
79
80enum isp_csi2_frame_mode {
81 ISP_CSI2_FRAME_IMMEDIATE,
82 ISP_CSI2_FRAME_AFTERFEC,
83};
84
85#define ISP_CSI2_MAX_CTX_NUM 7
86
87struct isp_csi2_ctx_cfg {
88 u8 ctxnum; /* context number 0 - 7 */
89 u8 dpcm_decompress;
90
91 /* Fields in CSI2_CTx_CTRL2 - locked by CSI2_CTx_CTRL1.CTX_EN */
92 u8 virtual_id;
93 u16 format_id; /* as in CSI2_CTx_CTRL2[9:0] */
94 u8 dpcm_predictor; /* 1: simple, 0: advanced */
95
96 /* Fields in CSI2_CTx_CTRL1/3 - Shadowed */
97 u16 alpha;
98 u16 data_offset;
99 u32 ping_addr;
100 u32 pong_addr;
101 u8 eof_enabled;
102 u8 eol_enabled;
103 u8 checksum_enabled;
104 u8 enabled;
105};
106
107struct isp_csi2_timing_cfg {
108 u8 ionum; /* IO1 or IO2 as in CSI2_TIMING */
109 unsigned force_rx_mode:1;
110 unsigned stop_state_16x:1;
111 unsigned stop_state_4x:1;
112 u16 stop_state_counter;
113};
114
115struct isp_csi2_ctrl_cfg {
116 bool vp_clk_enable;
117 bool vp_only_enable;
118 u8 vp_out_ctrl;
119 enum isp_csi2_frame_mode frame_mode;
120 bool ecc_enable;
121 bool if_enable;
122};
123
124#define CSI2_PAD_SINK 0
125#define CSI2_PAD_SOURCE 1
126#define CSI2_PADS_NUM 2
127
128#define CSI2_OUTPUT_CCDC (1 << 0)
129#define CSI2_OUTPUT_MEMORY (1 << 1)
130
131struct isp_csi2_device {
132 struct v4l2_subdev subdev;
133 struct media_pad pads[CSI2_PADS_NUM];
134 struct v4l2_mbus_framefmt formats[CSI2_PADS_NUM];
135
136 struct isp_video video_out;
137 struct isp_device *isp;
138
139 u8 available; /* Is the IP present on the silicon? */
140
141 /* mem resources - enums as defined in enum isp_mem_resources */
142 u8 regs1;
143 u8 regs2;
144
145 u32 output; /* output to CCDC, memory or both? */
146 bool dpcm_decompress;
147 unsigned int frame_skip;
148 bool use_fs_irq;
149
150 struct isp_csiphy *phy;
151 struct isp_csi2_ctx_cfg contexts[ISP_CSI2_MAX_CTX_NUM + 1];
152 struct isp_csi2_timing_cfg timing[2];
153 struct isp_csi2_ctrl_cfg ctrl;
154 enum isp_pipeline_stream_state state;
155 wait_queue_head_t wait;
156 atomic_t stopping;
157};
158
159int omap3isp_csi2_isr(struct isp_csi2_device *csi2);
160int omap3isp_csi2_reset(struct isp_csi2_device *csi2);
161int omap3isp_csi2_init(struct isp_device *isp);
162void omap3isp_csi2_cleanup(struct isp_device *isp);
163void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2);
164int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
165 struct v4l2_device *vdev);
166#endif /* OMAP3_ISP_CSI2_H */
diff --git a/drivers/media/video/omap3isp/ispcsiphy.c b/drivers/media/video/omap3isp/ispcsiphy.c
new file mode 100644
index 000000000000..5be37ce7d0c2
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsiphy.c
@@ -0,0 +1,247 @@
1/*
2 * ispcsiphy.c
3 *
4 * TI OMAP3 ISP - CSI PHY module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/delay.h>
28#include <linux/device.h>
29#include <linux/regulator/consumer.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispcsiphy.h"
34
35/*
36 * csiphy_lanes_config - Configuration of CSIPHY lanes.
37 *
38 * Updates HW configuration.
39 * Called with phy->mutex taken.
40 */
41static void csiphy_lanes_config(struct isp_csiphy *phy)
42{
43 unsigned int i;
44 u32 reg;
45
46 reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG);
47
48 for (i = 0; i < phy->num_data_lanes; i++) {
49 reg &= ~(ISPCSI2_PHY_CFG_DATA_POL_MASK(i + 1) |
50 ISPCSI2_PHY_CFG_DATA_POSITION_MASK(i + 1));
51 reg |= (phy->lanes.data[i].pol <<
52 ISPCSI2_PHY_CFG_DATA_POL_SHIFT(i + 1));
53 reg |= (phy->lanes.data[i].pos <<
54 ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(i + 1));
55 }
56
57 reg &= ~(ISPCSI2_PHY_CFG_CLOCK_POL_MASK |
58 ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK);
59 reg |= phy->lanes.clk.pol << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT;
60 reg |= phy->lanes.clk.pos << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT;
61
62 isp_reg_writel(phy->isp, reg, phy->cfg_regs, ISPCSI2_PHY_CFG);
63}
64
65/*
66 * csiphy_power_autoswitch_enable
67 * @enable: Sets or clears the autoswitch function enable flag.
68 */
69static void csiphy_power_autoswitch_enable(struct isp_csiphy *phy, bool enable)
70{
71 isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
72 ISPCSI2_PHY_CFG_PWR_AUTO,
73 enable ? ISPCSI2_PHY_CFG_PWR_AUTO : 0);
74}
75
76/*
77 * csiphy_set_power
78 * @power: Power state to be set.
79 *
80 * Returns 0 if successful, or -EBUSY if the retry count is exceeded.
81 */
82static int csiphy_set_power(struct isp_csiphy *phy, u32 power)
83{
84 u32 reg;
85 u8 retry_count;
86
87 isp_reg_clr_set(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG,
88 ISPCSI2_PHY_CFG_PWR_CMD_MASK, power);
89
90 retry_count = 0;
91 do {
92 udelay(50);
93 reg = isp_reg_readl(phy->isp, phy->cfg_regs, ISPCSI2_PHY_CFG) &
94 ISPCSI2_PHY_CFG_PWR_STATUS_MASK;
95
96 if (reg != power >> 2)
97 retry_count++;
98
99 } while ((reg != power >> 2) && (retry_count < 100));
100
101 if (retry_count == 100) {
102 printk(KERN_ERR "CSI2 CIO set power failed!\n");
103 return -EBUSY;
104 }
105
106 return 0;
107}
108
109/*
110 * csiphy_dphy_config - Configure CSI2 D-PHY parameters.
111 *
112 * Called with phy->mutex taken.
113 */
114static void csiphy_dphy_config(struct isp_csiphy *phy)
115{
116 u32 reg;
117
118 /* Set up ISPCSIPHY_REG0 */
119 reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG0);
120
121 reg &= ~(ISPCSIPHY_REG0_THS_TERM_MASK |
122 ISPCSIPHY_REG0_THS_SETTLE_MASK);
123 reg |= phy->dphy.ths_term << ISPCSIPHY_REG0_THS_TERM_SHIFT;
124 reg |= phy->dphy.ths_settle << ISPCSIPHY_REG0_THS_SETTLE_SHIFT;
125
126 isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG0);
127
128 /* Set up ISPCSIPHY_REG1 */
129 reg = isp_reg_readl(phy->isp, phy->phy_regs, ISPCSIPHY_REG1);
130
131 reg &= ~(ISPCSIPHY_REG1_TCLK_TERM_MASK |
132 ISPCSIPHY_REG1_TCLK_MISS_MASK |
133 ISPCSIPHY_REG1_TCLK_SETTLE_MASK);
134 reg |= phy->dphy.tclk_term << ISPCSIPHY_REG1_TCLK_TERM_SHIFT;
135 reg |= phy->dphy.tclk_miss << ISPCSIPHY_REG1_TCLK_MISS_SHIFT;
136 reg |= phy->dphy.tclk_settle << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT;
137
138 isp_reg_writel(phy->isp, reg, phy->phy_regs, ISPCSIPHY_REG1);
139}
140
141static int csiphy_config(struct isp_csiphy *phy,
142 struct isp_csiphy_dphy_cfg *dphy,
143 struct isp_csiphy_lanes_cfg *lanes)
144{
145 unsigned int used_lanes = 0;
146 unsigned int i;
147
148 /* Clock and data lanes verification */
149 for (i = 0; i < phy->num_data_lanes; i++) {
150 if (lanes->data[i].pol > 1 || lanes->data[i].pos > 3)
151 return -EINVAL;
152
153 if (used_lanes & (1 << lanes->data[i].pos))
154 return -EINVAL;
155
156 used_lanes |= 1 << lanes->data[i].pos;
157 }
158
159 if (lanes->clk.pol > 1 || lanes->clk.pos > 3)
160 return -EINVAL;
161
162 if (lanes->clk.pos == 0 || used_lanes & (1 << lanes->clk.pos))
163 return -EINVAL;
164
165 mutex_lock(&phy->mutex);
166 phy->dphy = *dphy;
167 phy->lanes = *lanes;
168 mutex_unlock(&phy->mutex);
169
170 return 0;
171}
172
173int omap3isp_csiphy_acquire(struct isp_csiphy *phy)
174{
175 int rval;
176
177 if (phy->vdd == NULL) {
178 dev_err(phy->isp->dev, "Power regulator for CSI PHY not "
179 "available\n");
180 return -ENODEV;
181 }
182
183 mutex_lock(&phy->mutex);
184
185 rval = regulator_enable(phy->vdd);
186 if (rval < 0)
187 goto done;
188
189 omap3isp_csi2_reset(phy->csi2);
190
191 csiphy_dphy_config(phy);
192 csiphy_lanes_config(phy);
193
194 rval = csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_ON);
195 if (rval) {
196 regulator_disable(phy->vdd);
197 goto done;
198 }
199
200 csiphy_power_autoswitch_enable(phy, true);
201 phy->phy_in_use = 1;
202
203done:
204 mutex_unlock(&phy->mutex);
205 return rval;
206}
207
208void omap3isp_csiphy_release(struct isp_csiphy *phy)
209{
210 mutex_lock(&phy->mutex);
211 if (phy->phy_in_use) {
212 csiphy_power_autoswitch_enable(phy, false);
213 csiphy_set_power(phy, ISPCSI2_PHY_CFG_PWR_CMD_OFF);
214 regulator_disable(phy->vdd);
215 phy->phy_in_use = 0;
216 }
217 mutex_unlock(&phy->mutex);
218}
219
220/*
221 * omap3isp_csiphy_init - Initialize the CSI PHY frontends
222 */
223int omap3isp_csiphy_init(struct isp_device *isp)
224{
225 struct isp_csiphy *phy1 = &isp->isp_csiphy1;
226 struct isp_csiphy *phy2 = &isp->isp_csiphy2;
227
228 isp->platform_cb.csiphy_config = csiphy_config;
229
230 phy2->isp = isp;
231 phy2->csi2 = &isp->isp_csi2a;
232 phy2->num_data_lanes = ISP_CSIPHY2_NUM_DATA_LANES;
233 phy2->cfg_regs = OMAP3_ISP_IOMEM_CSI2A_REGS1;
234 phy2->phy_regs = OMAP3_ISP_IOMEM_CSIPHY2;
235 mutex_init(&phy2->mutex);
236
237 if (isp->revision == ISP_REVISION_15_0) {
238 phy1->isp = isp;
239 phy1->csi2 = &isp->isp_csi2c;
240 phy1->num_data_lanes = ISP_CSIPHY1_NUM_DATA_LANES;
241 phy1->cfg_regs = OMAP3_ISP_IOMEM_CSI2C_REGS1;
242 phy1->phy_regs = OMAP3_ISP_IOMEM_CSIPHY1;
243 mutex_init(&phy1->mutex);
244 }
245
246 return 0;
247}
diff --git a/drivers/media/video/omap3isp/ispcsiphy.h b/drivers/media/video/omap3isp/ispcsiphy.h
new file mode 100644
index 000000000000..9596dc6830a6
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispcsiphy.h
@@ -0,0 +1,74 @@
1/*
2 * ispcsiphy.h
3 *
4 * TI OMAP3 ISP - CSI PHY module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_CSI_PHY_H
28#define OMAP3_ISP_CSI_PHY_H
29
30struct isp_csi2_device;
31struct regulator;
32
33struct csiphy_lane {
34 u8 pos;
35 u8 pol;
36};
37
38#define ISP_CSIPHY2_NUM_DATA_LANES 2
39#define ISP_CSIPHY1_NUM_DATA_LANES 1
40
41struct isp_csiphy_lanes_cfg {
42 struct csiphy_lane data[ISP_CSIPHY2_NUM_DATA_LANES];
43 struct csiphy_lane clk;
44};
45
46struct isp_csiphy_dphy_cfg {
47 u8 ths_term;
48 u8 ths_settle;
49 u8 tclk_term;
50 unsigned tclk_miss:1;
51 u8 tclk_settle;
52};
53
54struct isp_csiphy {
55 struct isp_device *isp;
56 struct mutex mutex; /* serialize csiphy configuration */
57 u8 phy_in_use;
58 struct isp_csi2_device *csi2;
59 struct regulator *vdd;
60
61 /* mem resources - enums as defined in enum isp_mem_resources */
62 unsigned int cfg_regs;
63 unsigned int phy_regs;
64
65 u8 num_data_lanes; /* number of CSI2 Data Lanes supported */
66 struct isp_csiphy_lanes_cfg lanes;
67 struct isp_csiphy_dphy_cfg dphy;
68};
69
70int omap3isp_csiphy_acquire(struct isp_csiphy *phy);
71void omap3isp_csiphy_release(struct isp_csiphy *phy);
72int omap3isp_csiphy_init(struct isp_device *isp);
73
74#endif /* OMAP3_ISP_CSI_PHY_H */
diff --git a/drivers/media/video/omap3isp/isph3a.h b/drivers/media/video/omap3isp/isph3a.h
new file mode 100644
index 000000000000..fb09fd4ca755
--- /dev/null
+++ b/drivers/media/video/omap3isp/isph3a.h
@@ -0,0 +1,117 @@
1/*
2 * isph3a.h
3 *
4 * TI OMAP3 ISP - H3A AF module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_H3A_H
29#define OMAP3_ISP_H3A_H
30
31#include <linux/omap3isp.h>
32
33/*
34 * ----------
35 * -H3A AEWB-
36 * ----------
37 */
38
39#define AEWB_PACKET_SIZE 16
40#define AEWB_SATURATION_LIMIT 0x3ff
41
42/* Flags for changed registers */
43#define PCR_CHNG (1 << 0)
44#define AEWWIN1_CHNG (1 << 1)
45#define AEWINSTART_CHNG (1 << 2)
46#define AEWINBLK_CHNG (1 << 3)
47#define AEWSUBWIN_CHNG (1 << 4)
48#define PRV_WBDGAIN_CHNG (1 << 5)
49#define PRV_WBGAIN_CHNG (1 << 6)
50
51/* ISPH3A REGISTERS bits */
52#define ISPH3A_PCR_AF_EN (1 << 0)
53#define ISPH3A_PCR_AF_ALAW_EN (1 << 1)
54#define ISPH3A_PCR_AF_MED_EN (1 << 2)
55#define ISPH3A_PCR_AF_BUSY (1 << 15)
56#define ISPH3A_PCR_AEW_EN (1 << 16)
57#define ISPH3A_PCR_AEW_ALAW_EN (1 << 17)
58#define ISPH3A_PCR_AEW_BUSY (1 << 18)
59#define ISPH3A_PCR_AEW_MASK (ISPH3A_PCR_AEW_ALAW_EN | \
60 ISPH3A_PCR_AEW_AVE2LMT_MASK)
61
62/*
63 * --------
64 * -H3A AF-
65 * --------
66 */
67
68/* Peripheral Revision */
69#define AFPID 0x0
70
71#define AFCOEF_OFFSET 0x00000004 /* COEF base address */
72
73/* PCR fields */
74#define AF_BUSYAF (1 << 15)
75#define AF_FVMODE (1 << 14)
76#define AF_RGBPOS (0x7 << 11)
77#define AF_MED_TH (0xFF << 3)
78#define AF_MED_EN (1 << 2)
79#define AF_ALAW_EN (1 << 1)
80#define AF_EN (1 << 0)
81#define AF_PCR_MASK (AF_FVMODE | AF_RGBPOS | AF_MED_TH | \
82 AF_MED_EN | AF_ALAW_EN)
83
84/* AFPAX1 fields */
85#define AF_PAXW (0x7F << 16)
86#define AF_PAXH 0x7F
87
88/* AFPAX2 fields */
89#define AF_AFINCV (0xF << 13)
90#define AF_PAXVC (0x7F << 6)
91#define AF_PAXHC 0x3F
92
93/* AFPAXSTART fields */
94#define AF_PAXSH (0xFFF<<16)
95#define AF_PAXSV 0xFFF
96
97/* COEFFICIENT MASK */
98#define AF_COEF_MASK0 0xFFF
99#define AF_COEF_MASK1 (0xFFF<<16)
100
101/* BIT SHIFTS */
102#define AF_RGBPOS_SHIFT 11
103#define AF_MED_TH_SHIFT 3
104#define AF_PAXW_SHIFT 16
105#define AF_LINE_INCR_SHIFT 13
106#define AF_VT_COUNT_SHIFT 6
107#define AF_HZ_START_SHIFT 16
108#define AF_COEF_SHIFT 16
109
110/* Init and cleanup functions */
111int omap3isp_h3a_aewb_init(struct isp_device *isp);
112int omap3isp_h3a_af_init(struct isp_device *isp);
113
114void omap3isp_h3a_aewb_cleanup(struct isp_device *isp);
115void omap3isp_h3a_af_cleanup(struct isp_device *isp);
116
117#endif /* OMAP3_ISP_H3A_H */
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/video/omap3isp/isph3a_aewb.c
new file mode 100644
index 000000000000..8068cefd8d89
--- /dev/null
+++ b/drivers/media/video/omap3isp/isph3a_aewb.c
@@ -0,0 +1,374 @@
1/*
2 * isph3a.c
3 *
4 * TI OMAP3 ISP - H3A module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/slab.h>
29#include <linux/uaccess.h>
30
31#include "isp.h"
32#include "isph3a.h"
33#include "ispstat.h"
34
35/*
36 * h3a_aewb_update_regs - Helper function to update h3a registers.
37 */
38static void h3a_aewb_setup_regs(struct ispstat *aewb, void *priv)
39{
40 struct omap3isp_h3a_aewb_config *conf = priv;
41 u32 pcr;
42 u32 win1;
43 u32 start;
44 u32 blk;
45 u32 subwin;
46
47 if (aewb->state == ISPSTAT_DISABLED)
48 return;
49
50 isp_reg_writel(aewb->isp, aewb->active_buf->iommu_addr,
51 OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWBUFST);
52
53 if (!aewb->update)
54 return;
55
56 /* Converting config metadata into reg values */
57 pcr = conf->saturation_limit << ISPH3A_PCR_AEW_AVE2LMT_SHIFT;
58 pcr |= !!conf->alaw_enable << ISPH3A_PCR_AEW_ALAW_EN_SHIFT;
59
60 win1 = ((conf->win_height >> 1) - 1) << ISPH3A_AEWWIN1_WINH_SHIFT;
61 win1 |= ((conf->win_width >> 1) - 1) << ISPH3A_AEWWIN1_WINW_SHIFT;
62 win1 |= (conf->ver_win_count - 1) << ISPH3A_AEWWIN1_WINVC_SHIFT;
63 win1 |= (conf->hor_win_count - 1) << ISPH3A_AEWWIN1_WINHC_SHIFT;
64
65 start = conf->hor_win_start << ISPH3A_AEWINSTART_WINSH_SHIFT;
66 start |= conf->ver_win_start << ISPH3A_AEWINSTART_WINSV_SHIFT;
67
68 blk = conf->blk_ver_win_start << ISPH3A_AEWINBLK_WINSV_SHIFT;
69 blk |= ((conf->blk_win_height >> 1) - 1) << ISPH3A_AEWINBLK_WINH_SHIFT;
70
71 subwin = ((conf->subsample_ver_inc >> 1) - 1) <<
72 ISPH3A_AEWSUBWIN_AEWINCV_SHIFT;
73 subwin |= ((conf->subsample_hor_inc >> 1) - 1) <<
74 ISPH3A_AEWSUBWIN_AEWINCH_SHIFT;
75
76 isp_reg_writel(aewb->isp, win1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWWIN1);
77 isp_reg_writel(aewb->isp, start, OMAP3_ISP_IOMEM_H3A,
78 ISPH3A_AEWINSTART);
79 isp_reg_writel(aewb->isp, blk, OMAP3_ISP_IOMEM_H3A, ISPH3A_AEWINBLK);
80 isp_reg_writel(aewb->isp, subwin, OMAP3_ISP_IOMEM_H3A,
81 ISPH3A_AEWSUBWIN);
82 isp_reg_clr_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
83 ISPH3A_PCR_AEW_MASK, pcr);
84
85 aewb->update = 0;
86 aewb->config_counter += aewb->inc_config;
87 aewb->inc_config = 0;
88 aewb->buf_size = conf->buf_size;
89}
90
91static void h3a_aewb_enable(struct ispstat *aewb, int enable)
92{
93 if (enable) {
94 isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
95 ISPH3A_PCR_AEW_EN);
96 /* This bit is already set if AF is enabled */
97 if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
98 isp_reg_set(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
99 ISPCTRL_H3A_CLK_EN);
100 } else {
101 isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
102 ISPH3A_PCR_AEW_EN);
103 /* This bit can't be cleared if AF is enabled */
104 if (aewb->isp->isp_af.state != ISPSTAT_ENABLED)
105 isp_reg_clr(aewb->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
106 ISPCTRL_H3A_CLK_EN);
107 }
108}
109
110static int h3a_aewb_busy(struct ispstat *aewb)
111{
112 return isp_reg_readl(aewb->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
113 & ISPH3A_PCR_BUSYAEAWB;
114}
115
116static u32 h3a_aewb_get_buf_size(struct omap3isp_h3a_aewb_config *conf)
117{
118 /* Number of configured windows + extra row for black data */
119 u32 win_count = (conf->ver_win_count + 1) * conf->hor_win_count;
120
121 /*
122 * Unsaturated block counts for each 8 windows.
123 * 1 extra for the last (win_count % 8) windows if win_count is not
124 * divisible by 8.
125 */
126 win_count += (win_count + 7) / 8;
127
128 return win_count * AEWB_PACKET_SIZE;
129}
130
131static int h3a_aewb_validate_params(struct ispstat *aewb, void *new_conf)
132{
133 struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
134 u32 buf_size;
135
136 if (unlikely(user_cfg->saturation_limit >
137 OMAP3ISP_AEWB_MAX_SATURATION_LIM))
138 return -EINVAL;
139
140 if (unlikely(user_cfg->win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
141 user_cfg->win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
142 user_cfg->win_height & 0x01))
143 return -EINVAL;
144
145 if (unlikely(user_cfg->win_width < OMAP3ISP_AEWB_MIN_WIN_W ||
146 user_cfg->win_width > OMAP3ISP_AEWB_MAX_WIN_W ||
147 user_cfg->win_width & 0x01))
148 return -EINVAL;
149
150 if (unlikely(user_cfg->ver_win_count < OMAP3ISP_AEWB_MIN_WINVC ||
151 user_cfg->ver_win_count > OMAP3ISP_AEWB_MAX_WINVC))
152 return -EINVAL;
153
154 if (unlikely(user_cfg->hor_win_count < OMAP3ISP_AEWB_MIN_WINHC ||
155 user_cfg->hor_win_count > OMAP3ISP_AEWB_MAX_WINHC))
156 return -EINVAL;
157
158 if (unlikely(user_cfg->ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
159 return -EINVAL;
160
161 if (unlikely(user_cfg->hor_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
162 return -EINVAL;
163
164 if (unlikely(user_cfg->blk_ver_win_start > OMAP3ISP_AEWB_MAX_WINSTART))
165 return -EINVAL;
166
167 if (unlikely(user_cfg->blk_win_height < OMAP3ISP_AEWB_MIN_WIN_H ||
168 user_cfg->blk_win_height > OMAP3ISP_AEWB_MAX_WIN_H ||
169 user_cfg->blk_win_height & 0x01))
170 return -EINVAL;
171
172 if (unlikely(user_cfg->subsample_ver_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
173 user_cfg->subsample_ver_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
174 user_cfg->subsample_ver_inc & 0x01))
175 return -EINVAL;
176
177 if (unlikely(user_cfg->subsample_hor_inc < OMAP3ISP_AEWB_MIN_SUB_INC ||
178 user_cfg->subsample_hor_inc > OMAP3ISP_AEWB_MAX_SUB_INC ||
179 user_cfg->subsample_hor_inc & 0x01))
180 return -EINVAL;
181
182 buf_size = h3a_aewb_get_buf_size(user_cfg);
183 if (buf_size > user_cfg->buf_size)
184 user_cfg->buf_size = buf_size;
185 else if (user_cfg->buf_size > OMAP3ISP_AEWB_MAX_BUF_SIZE)
186 user_cfg->buf_size = OMAP3ISP_AEWB_MAX_BUF_SIZE;
187
188 return 0;
189}
190
191/*
192 * h3a_aewb_set_params - Helper function to check & store user given params.
193 * @new_conf: Pointer to AE and AWB parameters struct.
194 *
195 * As most of them are busy-lock registers, need to wait until AEW_BUSY = 0 to
196 * program them during ISR.
197 */
198static void h3a_aewb_set_params(struct ispstat *aewb, void *new_conf)
199{
200 struct omap3isp_h3a_aewb_config *user_cfg = new_conf;
201 struct omap3isp_h3a_aewb_config *cur_cfg = aewb->priv;
202 int update = 0;
203
204 if (cur_cfg->saturation_limit != user_cfg->saturation_limit) {
205 cur_cfg->saturation_limit = user_cfg->saturation_limit;
206 update = 1;
207 }
208 if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
209 cur_cfg->alaw_enable = user_cfg->alaw_enable;
210 update = 1;
211 }
212 if (cur_cfg->win_height != user_cfg->win_height) {
213 cur_cfg->win_height = user_cfg->win_height;
214 update = 1;
215 }
216 if (cur_cfg->win_width != user_cfg->win_width) {
217 cur_cfg->win_width = user_cfg->win_width;
218 update = 1;
219 }
220 if (cur_cfg->ver_win_count != user_cfg->ver_win_count) {
221 cur_cfg->ver_win_count = user_cfg->ver_win_count;
222 update = 1;
223 }
224 if (cur_cfg->hor_win_count != user_cfg->hor_win_count) {
225 cur_cfg->hor_win_count = user_cfg->hor_win_count;
226 update = 1;
227 }
228 if (cur_cfg->ver_win_start != user_cfg->ver_win_start) {
229 cur_cfg->ver_win_start = user_cfg->ver_win_start;
230 update = 1;
231 }
232 if (cur_cfg->hor_win_start != user_cfg->hor_win_start) {
233 cur_cfg->hor_win_start = user_cfg->hor_win_start;
234 update = 1;
235 }
236 if (cur_cfg->blk_ver_win_start != user_cfg->blk_ver_win_start) {
237 cur_cfg->blk_ver_win_start = user_cfg->blk_ver_win_start;
238 update = 1;
239 }
240 if (cur_cfg->blk_win_height != user_cfg->blk_win_height) {
241 cur_cfg->blk_win_height = user_cfg->blk_win_height;
242 update = 1;
243 }
244 if (cur_cfg->subsample_ver_inc != user_cfg->subsample_ver_inc) {
245 cur_cfg->subsample_ver_inc = user_cfg->subsample_ver_inc;
246 update = 1;
247 }
248 if (cur_cfg->subsample_hor_inc != user_cfg->subsample_hor_inc) {
249 cur_cfg->subsample_hor_inc = user_cfg->subsample_hor_inc;
250 update = 1;
251 }
252
253 if (update || !aewb->configured) {
254 aewb->inc_config++;
255 aewb->update = 1;
256 cur_cfg->buf_size = h3a_aewb_get_buf_size(cur_cfg);
257 }
258}
259
260static long h3a_aewb_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
261{
262 struct ispstat *stat = v4l2_get_subdevdata(sd);
263
264 switch (cmd) {
265 case VIDIOC_OMAP3ISP_AEWB_CFG:
266 return omap3isp_stat_config(stat, arg);
267 case VIDIOC_OMAP3ISP_STAT_REQ:
268 return omap3isp_stat_request_statistics(stat, arg);
269 case VIDIOC_OMAP3ISP_STAT_EN: {
270 unsigned long *en = arg;
271 return omap3isp_stat_enable(stat, !!*en);
272 }
273 }
274
275 return -ENOIOCTLCMD;
276}
277
278static const struct ispstat_ops h3a_aewb_ops = {
279 .validate_params = h3a_aewb_validate_params,
280 .set_params = h3a_aewb_set_params,
281 .setup_regs = h3a_aewb_setup_regs,
282 .enable = h3a_aewb_enable,
283 .busy = h3a_aewb_busy,
284};
285
286static const struct v4l2_subdev_core_ops h3a_aewb_subdev_core_ops = {
287 .ioctl = h3a_aewb_ioctl,
288 .subscribe_event = omap3isp_stat_subscribe_event,
289 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
290};
291
292static const struct v4l2_subdev_video_ops h3a_aewb_subdev_video_ops = {
293 .s_stream = omap3isp_stat_s_stream,
294};
295
296static const struct v4l2_subdev_ops h3a_aewb_subdev_ops = {
297 .core = &h3a_aewb_subdev_core_ops,
298 .video = &h3a_aewb_subdev_video_ops,
299};
300
301/*
302 * omap3isp_h3a_aewb_init - Module Initialisation.
303 */
304int omap3isp_h3a_aewb_init(struct isp_device *isp)
305{
306 struct ispstat *aewb = &isp->isp_aewb;
307 struct omap3isp_h3a_aewb_config *aewb_cfg;
308 struct omap3isp_h3a_aewb_config *aewb_recover_cfg;
309 int ret;
310
311 aewb_cfg = kzalloc(sizeof(*aewb_cfg), GFP_KERNEL);
312 if (!aewb_cfg)
313 return -ENOMEM;
314
315 memset(aewb, 0, sizeof(*aewb));
316 aewb->ops = &h3a_aewb_ops;
317 aewb->priv = aewb_cfg;
318 aewb->dma_ch = -1;
319 aewb->event_type = V4L2_EVENT_OMAP3ISP_AEWB;
320 aewb->isp = isp;
321
322 /* Set recover state configuration */
323 aewb_recover_cfg = kzalloc(sizeof(*aewb_recover_cfg), GFP_KERNEL);
324 if (!aewb_recover_cfg) {
325 dev_err(aewb->isp->dev, "AEWB: cannot allocate memory for "
326 "recover configuration.\n");
327 ret = -ENOMEM;
328 goto err_recover_alloc;
329 }
330
331 aewb_recover_cfg->saturation_limit = OMAP3ISP_AEWB_MAX_SATURATION_LIM;
332 aewb_recover_cfg->win_height = OMAP3ISP_AEWB_MIN_WIN_H;
333 aewb_recover_cfg->win_width = OMAP3ISP_AEWB_MIN_WIN_W;
334 aewb_recover_cfg->ver_win_count = OMAP3ISP_AEWB_MIN_WINVC;
335 aewb_recover_cfg->hor_win_count = OMAP3ISP_AEWB_MIN_WINHC;
336 aewb_recover_cfg->blk_ver_win_start = aewb_recover_cfg->ver_win_start +
337 aewb_recover_cfg->win_height * aewb_recover_cfg->ver_win_count;
338 aewb_recover_cfg->blk_win_height = OMAP3ISP_AEWB_MIN_WIN_H;
339 aewb_recover_cfg->subsample_ver_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
340 aewb_recover_cfg->subsample_hor_inc = OMAP3ISP_AEWB_MIN_SUB_INC;
341
342 if (h3a_aewb_validate_params(aewb, aewb_recover_cfg)) {
343 dev_err(aewb->isp->dev, "AEWB: recover configuration is "
344 "invalid.\n");
345 ret = -EINVAL;
346 goto err_conf;
347 }
348
349 aewb_recover_cfg->buf_size = h3a_aewb_get_buf_size(aewb_recover_cfg);
350 aewb->recover_priv = aewb_recover_cfg;
351
352 ret = omap3isp_stat_init(aewb, "AEWB", &h3a_aewb_subdev_ops);
353 if (ret)
354 goto err_conf;
355
356 return 0;
357
358err_conf:
359 kfree(aewb_recover_cfg);
360err_recover_alloc:
361 kfree(aewb_cfg);
362
363 return ret;
364}
365
366/*
367 * omap3isp_h3a_aewb_cleanup - Module exit.
368 */
369void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
370{
371 kfree(isp->isp_aewb.priv);
372 kfree(isp->isp_aewb.recover_priv);
373 omap3isp_stat_free(&isp->isp_aewb);
374}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/video/omap3isp/isph3a_af.c
new file mode 100644
index 000000000000..ba54d0acdecf
--- /dev/null
+++ b/drivers/media/video/omap3isp/isph3a_af.c
@@ -0,0 +1,429 @@
1/*
2 * isph3a_af.c
3 *
4 * TI OMAP3 ISP - H3A AF module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28/* Linux specific include files */
29#include <linux/device.h>
30#include <linux/slab.h>
31
32#include "isp.h"
33#include "isph3a.h"
34#include "ispstat.h"
35
36#define IS_OUT_OF_BOUNDS(value, min, max) \
37 (((value) < (min)) || ((value) > (max)))
38
39static void h3a_af_setup_regs(struct ispstat *af, void *priv)
40{
41 struct omap3isp_h3a_af_config *conf = priv;
42 u32 pcr;
43 u32 pax1;
44 u32 pax2;
45 u32 paxstart;
46 u32 coef;
47 u32 base_coef_set0;
48 u32 base_coef_set1;
49 int index;
50
51 if (af->state == ISPSTAT_DISABLED)
52 return;
53
54 isp_reg_writel(af->isp, af->active_buf->iommu_addr, OMAP3_ISP_IOMEM_H3A,
55 ISPH3A_AFBUFST);
56
57 if (!af->update)
58 return;
59
60 /* Configure Hardware Registers */
61 pax1 = ((conf->paxel.width >> 1) - 1) << AF_PAXW_SHIFT;
62 /* Set height in AFPAX1 */
63 pax1 |= (conf->paxel.height >> 1) - 1;
64 isp_reg_writel(af->isp, pax1, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX1);
65
66 /* Configure AFPAX2 Register */
67 /* Set Line Increment in AFPAX2 Register */
68 pax2 = ((conf->paxel.line_inc >> 1) - 1) << AF_LINE_INCR_SHIFT;
69 /* Set Vertical Count */
70 pax2 |= (conf->paxel.v_cnt - 1) << AF_VT_COUNT_SHIFT;
71 /* Set Horizontal Count */
72 pax2 |= (conf->paxel.h_cnt - 1);
73 isp_reg_writel(af->isp, pax2, OMAP3_ISP_IOMEM_H3A, ISPH3A_AFPAX2);
74
75 /* Configure PAXSTART Register */
76 /*Configure Horizontal Start */
77 paxstart = conf->paxel.h_start << AF_HZ_START_SHIFT;
78 /* Configure Vertical Start */
79 paxstart |= conf->paxel.v_start;
80 isp_reg_writel(af->isp, paxstart, OMAP3_ISP_IOMEM_H3A,
81 ISPH3A_AFPAXSTART);
82
83 /*SetIIRSH Register */
84 isp_reg_writel(af->isp, conf->iir.h_start,
85 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFIIRSH);
86
87 base_coef_set0 = ISPH3A_AFCOEF010;
88 base_coef_set1 = ISPH3A_AFCOEF110;
89 for (index = 0; index <= 8; index += 2) {
90 /*Set IIR Filter0 Coefficients */
91 coef = 0;
92 coef |= conf->iir.coeff_set0[index];
93 coef |= conf->iir.coeff_set0[index + 1] <<
94 AF_COEF_SHIFT;
95 isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
96 base_coef_set0);
97 base_coef_set0 += AFCOEF_OFFSET;
98
99 /*Set IIR Filter1 Coefficients */
100 coef = 0;
101 coef |= conf->iir.coeff_set1[index];
102 coef |= conf->iir.coeff_set1[index + 1] <<
103 AF_COEF_SHIFT;
104 isp_reg_writel(af->isp, coef, OMAP3_ISP_IOMEM_H3A,
105 base_coef_set1);
106 base_coef_set1 += AFCOEF_OFFSET;
107 }
108 /* set AFCOEF0010 Register */
109 isp_reg_writel(af->isp, conf->iir.coeff_set0[10],
110 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF0010);
111 /* set AFCOEF1010 Register */
112 isp_reg_writel(af->isp, conf->iir.coeff_set1[10],
113 OMAP3_ISP_IOMEM_H3A, ISPH3A_AFCOEF1010);
114
115 /* PCR Register */
116 /* Set RGB Position */
117 pcr = conf->rgb_pos << AF_RGBPOS_SHIFT;
118 /* Set Accumulator Mode */
119 if (conf->fvmode == OMAP3ISP_AF_MODE_PEAK)
120 pcr |= AF_FVMODE;
121 /* Set A-law */
122 if (conf->alaw_enable)
123 pcr |= AF_ALAW_EN;
124 /* HMF Configurations */
125 if (conf->hmf.enable) {
126 /* Enable HMF */
127 pcr |= AF_MED_EN;
128 /* Set Median Threshold */
129 pcr |= conf->hmf.threshold << AF_MED_TH_SHIFT;
130 }
131 /* Set PCR Register */
132 isp_reg_clr_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
133 AF_PCR_MASK, pcr);
134
135 af->update = 0;
136 af->config_counter += af->inc_config;
137 af->inc_config = 0;
138 af->buf_size = conf->buf_size;
139}
140
141static void h3a_af_enable(struct ispstat *af, int enable)
142{
143 if (enable) {
144 isp_reg_set(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
145 ISPH3A_PCR_AF_EN);
146 /* This bit is already set if AEWB is enabled */
147 if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
148 isp_reg_set(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
149 ISPCTRL_H3A_CLK_EN);
150 } else {
151 isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR,
152 ISPH3A_PCR_AF_EN);
153 /* This bit can't be cleared if AEWB is enabled */
154 if (af->isp->isp_aewb.state != ISPSTAT_ENABLED)
155 isp_reg_clr(af->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
156 ISPCTRL_H3A_CLK_EN);
157 }
158}
159
160static int h3a_af_busy(struct ispstat *af)
161{
162 return isp_reg_readl(af->isp, OMAP3_ISP_IOMEM_H3A, ISPH3A_PCR)
163 & ISPH3A_PCR_BUSYAF;
164}
165
166static u32 h3a_af_get_buf_size(struct omap3isp_h3a_af_config *conf)
167{
168 return conf->paxel.h_cnt * conf->paxel.v_cnt * OMAP3ISP_AF_PAXEL_SIZE;
169}
170
171/* Function to check paxel parameters */
172static int h3a_af_validate_params(struct ispstat *af, void *new_conf)
173{
174 struct omap3isp_h3a_af_config *user_cfg = new_conf;
175 struct omap3isp_h3a_af_paxel *paxel_cfg = &user_cfg->paxel;
176 struct omap3isp_h3a_af_iir *iir_cfg = &user_cfg->iir;
177 int index;
178 u32 buf_size;
179
180 /* Check horizontal Count */
181 if (IS_OUT_OF_BOUNDS(paxel_cfg->h_cnt,
182 OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN,
183 OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX))
184 return -EINVAL;
185
186 /* Check Vertical Count */
187 if (IS_OUT_OF_BOUNDS(paxel_cfg->v_cnt,
188 OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN,
189 OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX))
190 return -EINVAL;
191
192 if (IS_OUT_OF_BOUNDS(paxel_cfg->height, OMAP3ISP_AF_PAXEL_HEIGHT_MIN,
193 OMAP3ISP_AF_PAXEL_HEIGHT_MAX) ||
194 paxel_cfg->height % 2)
195 return -EINVAL;
196
197 /* Check width */
198 if (IS_OUT_OF_BOUNDS(paxel_cfg->width, OMAP3ISP_AF_PAXEL_WIDTH_MIN,
199 OMAP3ISP_AF_PAXEL_WIDTH_MAX) ||
200 paxel_cfg->width % 2)
201 return -EINVAL;
202
203 /* Check Line Increment */
204 if (IS_OUT_OF_BOUNDS(paxel_cfg->line_inc,
205 OMAP3ISP_AF_PAXEL_INCREMENT_MIN,
206 OMAP3ISP_AF_PAXEL_INCREMENT_MAX) ||
207 paxel_cfg->line_inc % 2)
208 return -EINVAL;
209
210 /* Check Horizontal Start */
211 if ((paxel_cfg->h_start < iir_cfg->h_start) ||
212 IS_OUT_OF_BOUNDS(paxel_cfg->h_start,
213 OMAP3ISP_AF_PAXEL_HZSTART_MIN,
214 OMAP3ISP_AF_PAXEL_HZSTART_MAX))
215 return -EINVAL;
216
217 /* Check IIR */
218 for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
219 if ((iir_cfg->coeff_set0[index]) > OMAP3ISP_AF_COEF_MAX)
220 return -EINVAL;
221
222 if ((iir_cfg->coeff_set1[index]) > OMAP3ISP_AF_COEF_MAX)
223 return -EINVAL;
224 }
225
226 if (IS_OUT_OF_BOUNDS(iir_cfg->h_start, OMAP3ISP_AF_IIRSH_MIN,
227 OMAP3ISP_AF_IIRSH_MAX))
228 return -EINVAL;
229
230 /* Hack: If paxel size is 12, the 10th AF window may be corrupted */
231 if ((paxel_cfg->h_cnt * paxel_cfg->v_cnt > 9) &&
232 (paxel_cfg->width * paxel_cfg->height == 12))
233 return -EINVAL;
234
235 buf_size = h3a_af_get_buf_size(user_cfg);
236 if (buf_size > user_cfg->buf_size)
237 /* User buf_size request wasn't enough */
238 user_cfg->buf_size = buf_size;
239 else if (user_cfg->buf_size > OMAP3ISP_AF_MAX_BUF_SIZE)
240 user_cfg->buf_size = OMAP3ISP_AF_MAX_BUF_SIZE;
241
242 return 0;
243}
244
245/* Update local parameters */
246static void h3a_af_set_params(struct ispstat *af, void *new_conf)
247{
248 struct omap3isp_h3a_af_config *user_cfg = new_conf;
249 struct omap3isp_h3a_af_config *cur_cfg = af->priv;
250 int update = 0;
251 int index;
252
253 /* alaw */
254 if (cur_cfg->alaw_enable != user_cfg->alaw_enable) {
255 update = 1;
256 goto out;
257 }
258
259 /* hmf */
260 if (cur_cfg->hmf.enable != user_cfg->hmf.enable) {
261 update = 1;
262 goto out;
263 }
264 if (cur_cfg->hmf.threshold != user_cfg->hmf.threshold) {
265 update = 1;
266 goto out;
267 }
268
269 /* rgbpos */
270 if (cur_cfg->rgb_pos != user_cfg->rgb_pos) {
271 update = 1;
272 goto out;
273 }
274
275 /* iir */
276 if (cur_cfg->iir.h_start != user_cfg->iir.h_start) {
277 update = 1;
278 goto out;
279 }
280 for (index = 0; index < OMAP3ISP_AF_NUM_COEF; index++) {
281 if (cur_cfg->iir.coeff_set0[index] !=
282 user_cfg->iir.coeff_set0[index]) {
283 update = 1;
284 goto out;
285 }
286 if (cur_cfg->iir.coeff_set1[index] !=
287 user_cfg->iir.coeff_set1[index]) {
288 update = 1;
289 goto out;
290 }
291 }
292
293 /* paxel */
294 if ((cur_cfg->paxel.width != user_cfg->paxel.width) ||
295 (cur_cfg->paxel.height != user_cfg->paxel.height) ||
296 (cur_cfg->paxel.h_start != user_cfg->paxel.h_start) ||
297 (cur_cfg->paxel.v_start != user_cfg->paxel.v_start) ||
298 (cur_cfg->paxel.h_cnt != user_cfg->paxel.h_cnt) ||
299 (cur_cfg->paxel.v_cnt != user_cfg->paxel.v_cnt) ||
300 (cur_cfg->paxel.line_inc != user_cfg->paxel.line_inc)) {
301 update = 1;
302 goto out;
303 }
304
305 /* af_mode */
306 if (cur_cfg->fvmode != user_cfg->fvmode)
307 update = 1;
308
309out:
310 if (update || !af->configured) {
311 memcpy(cur_cfg, user_cfg, sizeof(*cur_cfg));
312 af->inc_config++;
313 af->update = 1;
314 /*
315 * User might be asked for a bigger buffer than necessary for
316 * this configuration. In order to return the right amount of
317 * data during buffer request, let's calculate the size here
318 * instead of stick with user_cfg->buf_size.
319 */
320 cur_cfg->buf_size = h3a_af_get_buf_size(cur_cfg);
321 }
322}
323
324static long h3a_af_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
325{
326 struct ispstat *stat = v4l2_get_subdevdata(sd);
327
328 switch (cmd) {
329 case VIDIOC_OMAP3ISP_AF_CFG:
330 return omap3isp_stat_config(stat, arg);
331 case VIDIOC_OMAP3ISP_STAT_REQ:
332 return omap3isp_stat_request_statistics(stat, arg);
333 case VIDIOC_OMAP3ISP_STAT_EN: {
334 int *en = arg;
335 return omap3isp_stat_enable(stat, !!*en);
336 }
337 }
338
339 return -ENOIOCTLCMD;
340
341}
342
343static const struct ispstat_ops h3a_af_ops = {
344 .validate_params = h3a_af_validate_params,
345 .set_params = h3a_af_set_params,
346 .setup_regs = h3a_af_setup_regs,
347 .enable = h3a_af_enable,
348 .busy = h3a_af_busy,
349};
350
351static const struct v4l2_subdev_core_ops h3a_af_subdev_core_ops = {
352 .ioctl = h3a_af_ioctl,
353 .subscribe_event = omap3isp_stat_subscribe_event,
354 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
355};
356
357static const struct v4l2_subdev_video_ops h3a_af_subdev_video_ops = {
358 .s_stream = omap3isp_stat_s_stream,
359};
360
361static const struct v4l2_subdev_ops h3a_af_subdev_ops = {
362 .core = &h3a_af_subdev_core_ops,
363 .video = &h3a_af_subdev_video_ops,
364};
365
366/* Function to register the AF character device driver. */
367int omap3isp_h3a_af_init(struct isp_device *isp)
368{
369 struct ispstat *af = &isp->isp_af;
370 struct omap3isp_h3a_af_config *af_cfg;
371 struct omap3isp_h3a_af_config *af_recover_cfg;
372 int ret;
373
374 af_cfg = kzalloc(sizeof(*af_cfg), GFP_KERNEL);
375 if (af_cfg == NULL)
376 return -ENOMEM;
377
378 memset(af, 0, sizeof(*af));
379 af->ops = &h3a_af_ops;
380 af->priv = af_cfg;
381 af->dma_ch = -1;
382 af->event_type = V4L2_EVENT_OMAP3ISP_AF;
383 af->isp = isp;
384
385 /* Set recover state configuration */
386 af_recover_cfg = kzalloc(sizeof(*af_recover_cfg), GFP_KERNEL);
387 if (!af_recover_cfg) {
388 dev_err(af->isp->dev, "AF: cannot allocate memory for recover "
389 "configuration.\n");
390 ret = -ENOMEM;
391 goto err_recover_alloc;
392 }
393
394 af_recover_cfg->paxel.h_start = OMAP3ISP_AF_PAXEL_HZSTART_MIN;
395 af_recover_cfg->paxel.width = OMAP3ISP_AF_PAXEL_WIDTH_MIN;
396 af_recover_cfg->paxel.height = OMAP3ISP_AF_PAXEL_HEIGHT_MIN;
397 af_recover_cfg->paxel.h_cnt = OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN;
398 af_recover_cfg->paxel.v_cnt = OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN;
399 af_recover_cfg->paxel.line_inc = OMAP3ISP_AF_PAXEL_INCREMENT_MIN;
400 if (h3a_af_validate_params(af, af_recover_cfg)) {
401 dev_err(af->isp->dev, "AF: recover configuration is "
402 "invalid.\n");
403 ret = -EINVAL;
404 goto err_conf;
405 }
406
407 af_recover_cfg->buf_size = h3a_af_get_buf_size(af_recover_cfg);
408 af->recover_priv = af_recover_cfg;
409
410 ret = omap3isp_stat_init(af, "AF", &h3a_af_subdev_ops);
411 if (ret)
412 goto err_conf;
413
414 return 0;
415
416err_conf:
417 kfree(af_recover_cfg);
418err_recover_alloc:
419 kfree(af_cfg);
420
421 return ret;
422}
423
424void omap3isp_h3a_af_cleanup(struct isp_device *isp)
425{
426 kfree(isp->isp_af.priv);
427 kfree(isp->isp_af.recover_priv);
428 omap3isp_stat_free(&isp->isp_af);
429}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/video/omap3isp/isphist.c
new file mode 100644
index 000000000000..1743856b30d1
--- /dev/null
+++ b/drivers/media/video/omap3isp/isphist.c
@@ -0,0 +1,520 @@
1/*
2 * isphist.c
3 *
4 * TI OMAP3 ISP - Histogram module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/uaccess.h>
31#include <linux/device.h>
32
33#include "isp.h"
34#include "ispreg.h"
35#include "isphist.h"
36
37#define HIST_CONFIG_DMA 1
38
39#define HIST_USING_DMA(hist) ((hist)->dma_ch >= 0)
40
41/*
42 * hist_reset_mem - clear Histogram memory before start stats engine.
43 */
44static void hist_reset_mem(struct ispstat *hist)
45{
46 struct isp_device *isp = hist->isp;
47 struct omap3isp_hist_config *conf = hist->priv;
48 unsigned int i;
49
50 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
51
52 /*
53 * By setting it, the histogram internal buffer is being cleared at the
54 * same time it's being read. This bit must be cleared afterwards.
55 */
56 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
57
58 /*
59 * We'll clear 4 words at each iteration for optimization. It avoids
60 * 3/4 of the jumps. We also know HIST_MEM_SIZE is divisible by 4.
61 */
62 for (i = OMAP3ISP_HIST_MEM_SIZE / 4; i > 0; i--) {
63 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
64 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
65 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
66 isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
67 }
68 isp_reg_clr(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
69
70 hist->wait_acc_frames = conf->num_acc_frames;
71}
72
73static void hist_dma_config(struct ispstat *hist)
74{
75 hist->dma_config.data_type = OMAP_DMA_DATA_TYPE_S32;
76 hist->dma_config.sync_mode = OMAP_DMA_SYNC_ELEMENT;
77 hist->dma_config.frame_count = 1;
78 hist->dma_config.src_amode = OMAP_DMA_AMODE_CONSTANT;
79 hist->dma_config.src_start = OMAP3ISP_HIST_REG_BASE + ISPHIST_DATA;
80 hist->dma_config.dst_amode = OMAP_DMA_AMODE_POST_INC;
81 hist->dma_config.src_or_dst_synch = OMAP_DMA_SRC_SYNC;
82}
83
84/*
85 * hist_setup_regs - Helper function to update Histogram registers.
86 */
87static void hist_setup_regs(struct ispstat *hist, void *priv)
88{
89 struct isp_device *isp = hist->isp;
90 struct omap3isp_hist_config *conf = priv;
91 int c;
92 u32 cnt;
93 u32 wb_gain;
94 u32 reg_hor[OMAP3ISP_HIST_MAX_REGIONS];
95 u32 reg_ver[OMAP3ISP_HIST_MAX_REGIONS];
96
97 if (!hist->update || hist->state == ISPSTAT_DISABLED ||
98 hist->state == ISPSTAT_DISABLING)
99 return;
100
101 cnt = conf->cfa << ISPHIST_CNT_CFA_SHIFT;
102
103 wb_gain = conf->wg[0] << ISPHIST_WB_GAIN_WG00_SHIFT;
104 wb_gain |= conf->wg[1] << ISPHIST_WB_GAIN_WG01_SHIFT;
105 wb_gain |= conf->wg[2] << ISPHIST_WB_GAIN_WG02_SHIFT;
106 if (conf->cfa == OMAP3ISP_HIST_CFA_BAYER)
107 wb_gain |= conf->wg[3] << ISPHIST_WB_GAIN_WG03_SHIFT;
108
109 /* Regions size and position */
110 for (c = 0; c < OMAP3ISP_HIST_MAX_REGIONS; c++) {
111 if (c < conf->num_regions) {
112 reg_hor[c] = conf->region[c].h_start <<
113 ISPHIST_REG_START_SHIFT;
114 reg_hor[c] = conf->region[c].h_end <<
115 ISPHIST_REG_END_SHIFT;
116 reg_ver[c] = conf->region[c].v_start <<
117 ISPHIST_REG_START_SHIFT;
118 reg_ver[c] = conf->region[c].v_end <<
119 ISPHIST_REG_END_SHIFT;
120 } else {
121 reg_hor[c] = 0;
122 reg_ver[c] = 0;
123 }
124 }
125
126 cnt |= conf->hist_bins << ISPHIST_CNT_BINS_SHIFT;
127 switch (conf->hist_bins) {
128 case OMAP3ISP_HIST_BINS_256:
129 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 8) <<
130 ISPHIST_CNT_SHIFT_SHIFT;
131 break;
132 case OMAP3ISP_HIST_BINS_128:
133 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 7) <<
134 ISPHIST_CNT_SHIFT_SHIFT;
135 break;
136 case OMAP3ISP_HIST_BINS_64:
137 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 6) <<
138 ISPHIST_CNT_SHIFT_SHIFT;
139 break;
140 default: /* OMAP3ISP_HIST_BINS_32 */
141 cnt |= (ISPHIST_IN_BIT_WIDTH_CCDC - 5) <<
142 ISPHIST_CNT_SHIFT_SHIFT;
143 break;
144 }
145
146 hist_reset_mem(hist);
147
148 isp_reg_writel(isp, cnt, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT);
149 isp_reg_writel(isp, wb_gain, OMAP3_ISP_IOMEM_HIST, ISPHIST_WB_GAIN);
150 isp_reg_writel(isp, reg_hor[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_HORZ);
151 isp_reg_writel(isp, reg_ver[0], OMAP3_ISP_IOMEM_HIST, ISPHIST_R0_VERT);
152 isp_reg_writel(isp, reg_hor[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_HORZ);
153 isp_reg_writel(isp, reg_ver[1], OMAP3_ISP_IOMEM_HIST, ISPHIST_R1_VERT);
154 isp_reg_writel(isp, reg_hor[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_HORZ);
155 isp_reg_writel(isp, reg_ver[2], OMAP3_ISP_IOMEM_HIST, ISPHIST_R2_VERT);
156 isp_reg_writel(isp, reg_hor[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_HORZ);
157 isp_reg_writel(isp, reg_ver[3], OMAP3_ISP_IOMEM_HIST, ISPHIST_R3_VERT);
158
159 hist->update = 0;
160 hist->config_counter += hist->inc_config;
161 hist->inc_config = 0;
162 hist->buf_size = conf->buf_size;
163}
164
165static void hist_enable(struct ispstat *hist, int enable)
166{
167 if (enable) {
168 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
169 ISPHIST_PCR_ENABLE);
170 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
171 ISPCTRL_HIST_CLK_EN);
172 } else {
173 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR,
174 ISPHIST_PCR_ENABLE);
175 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_MAIN, ISP_CTRL,
176 ISPCTRL_HIST_CLK_EN);
177 }
178}
179
180static int hist_busy(struct ispstat *hist)
181{
182 return isp_reg_readl(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_PCR)
183 & ISPHIST_PCR_BUSY;
184}
185
186static void hist_dma_cb(int lch, u16 ch_status, void *data)
187{
188 struct ispstat *hist = data;
189
190 if (ch_status & ~OMAP_DMA_BLOCK_IRQ) {
191 dev_dbg(hist->isp->dev, "hist: DMA error. status = 0x%04x\n",
192 ch_status);
193 omap_stop_dma(lch);
194 hist_reset_mem(hist);
195 atomic_set(&hist->buf_err, 1);
196 }
197 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
198 ISPHIST_CNT_CLEAR);
199
200 omap3isp_stat_dma_isr(hist);
201 if (hist->state != ISPSTAT_DISABLED)
202 omap3isp_hist_dma_done(hist->isp);
203}
204
205static int hist_buf_dma(struct ispstat *hist)
206{
207 dma_addr_t dma_addr = hist->active_buf->dma_addr;
208
209 if (unlikely(!dma_addr)) {
210 dev_dbg(hist->isp->dev, "hist: invalid DMA buffer address\n");
211 hist_reset_mem(hist);
212 return STAT_NO_BUF;
213 }
214
215 isp_reg_writel(hist->isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
216 isp_reg_set(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
217 ISPHIST_CNT_CLEAR);
218 omap3isp_flush(hist->isp);
219 hist->dma_config.dst_start = dma_addr;
220 hist->dma_config.elem_count = hist->buf_size / sizeof(u32);
221 omap_set_dma_params(hist->dma_ch, &hist->dma_config);
222
223 omap_start_dma(hist->dma_ch);
224
225 return STAT_BUF_WAITING_DMA;
226}
227
228static int hist_buf_pio(struct ispstat *hist)
229{
230 struct isp_device *isp = hist->isp;
231 u32 *buf = hist->active_buf->virt_addr;
232 unsigned int i;
233
234 if (!buf) {
235 dev_dbg(isp->dev, "hist: invalid PIO buffer address\n");
236 hist_reset_mem(hist);
237 return STAT_NO_BUF;
238 }
239
240 isp_reg_writel(isp, 0, OMAP3_ISP_IOMEM_HIST, ISPHIST_ADDR);
241
242 /*
243 * By setting it, the histogram internal buffer is being cleared at the
244 * same time it's being read. This bit must be cleared just after all
245 * data is acquired.
246 */
247 isp_reg_set(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT, ISPHIST_CNT_CLEAR);
248
249 /*
250 * We'll read 4 times a 4-bytes-word at each iteration for
251 * optimization. It avoids 3/4 of the jumps. We also know buf_size is
252 * divisible by 16.
253 */
254 for (i = hist->buf_size / 16; i > 0; i--) {
255 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
256 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
257 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
258 *buf++ = isp_reg_readl(isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_DATA);
259 }
260 isp_reg_clr(hist->isp, OMAP3_ISP_IOMEM_HIST, ISPHIST_CNT,
261 ISPHIST_CNT_CLEAR);
262
263 return STAT_BUF_DONE;
264}
265
266/*
267 * hist_buf_process - Callback from ISP driver for HIST interrupt.
268 */
269static int hist_buf_process(struct ispstat *hist)
270{
271 struct omap3isp_hist_config *user_cfg = hist->priv;
272 int ret;
273
274 if (atomic_read(&hist->buf_err) || hist->state != ISPSTAT_ENABLED) {
275 hist_reset_mem(hist);
276 return STAT_NO_BUF;
277 }
278
279 if (--(hist->wait_acc_frames))
280 return STAT_NO_BUF;
281
282 if (HIST_USING_DMA(hist))
283 ret = hist_buf_dma(hist);
284 else
285 ret = hist_buf_pio(hist);
286
287 hist->wait_acc_frames = user_cfg->num_acc_frames;
288
289 return ret;
290}
291
292static u32 hist_get_buf_size(struct omap3isp_hist_config *conf)
293{
294 return OMAP3ISP_HIST_MEM_SIZE_BINS(conf->hist_bins) * conf->num_regions;
295}
296
297/*
298 * hist_validate_params - Helper function to check user given params.
299 * @user_cfg: Pointer to user configuration structure.
300 *
301 * Returns 0 on success configuration.
302 */
303static int hist_validate_params(struct ispstat *hist, void *new_conf)
304{
305 struct omap3isp_hist_config *user_cfg = new_conf;
306 int c;
307 u32 buf_size;
308
309 if (user_cfg->cfa > OMAP3ISP_HIST_CFA_FOVEONX3)
310 return -EINVAL;
311
312 /* Regions size and position */
313
314 if ((user_cfg->num_regions < OMAP3ISP_HIST_MIN_REGIONS) ||
315 (user_cfg->num_regions > OMAP3ISP_HIST_MAX_REGIONS))
316 return -EINVAL;
317
318 /* Regions */
319 for (c = 0; c < user_cfg->num_regions; c++) {
320 if (user_cfg->region[c].h_start & ~ISPHIST_REG_START_END_MASK)
321 return -EINVAL;
322 if (user_cfg->region[c].h_end & ~ISPHIST_REG_START_END_MASK)
323 return -EINVAL;
324 if (user_cfg->region[c].v_start & ~ISPHIST_REG_START_END_MASK)
325 return -EINVAL;
326 if (user_cfg->region[c].v_end & ~ISPHIST_REG_START_END_MASK)
327 return -EINVAL;
328 if (user_cfg->region[c].h_start > user_cfg->region[c].h_end)
329 return -EINVAL;
330 if (user_cfg->region[c].v_start > user_cfg->region[c].v_end)
331 return -EINVAL;
332 }
333
334 switch (user_cfg->num_regions) {
335 case 1:
336 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_256)
337 return -EINVAL;
338 break;
339 case 2:
340 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_128)
341 return -EINVAL;
342 break;
343 default: /* 3 or 4 */
344 if (user_cfg->hist_bins > OMAP3ISP_HIST_BINS_64)
345 return -EINVAL;
346 break;
347 }
348
349 buf_size = hist_get_buf_size(user_cfg);
350 if (buf_size > user_cfg->buf_size)
351 /* User's buf_size request wasn't enoght */
352 user_cfg->buf_size = buf_size;
353 else if (user_cfg->buf_size > OMAP3ISP_HIST_MAX_BUF_SIZE)
354 user_cfg->buf_size = OMAP3ISP_HIST_MAX_BUF_SIZE;
355
356 return 0;
357}
358
359static int hist_comp_params(struct ispstat *hist,
360 struct omap3isp_hist_config *user_cfg)
361{
362 struct omap3isp_hist_config *cur_cfg = hist->priv;
363 int c;
364
365 if (cur_cfg->cfa != user_cfg->cfa)
366 return 1;
367
368 if (cur_cfg->num_acc_frames != user_cfg->num_acc_frames)
369 return 1;
370
371 if (cur_cfg->hist_bins != user_cfg->hist_bins)
372 return 1;
373
374 for (c = 0; c < OMAP3ISP_HIST_MAX_WG; c++) {
375 if (c == 3 && user_cfg->cfa == OMAP3ISP_HIST_CFA_FOVEONX3)
376 break;
377 else if (cur_cfg->wg[c] != user_cfg->wg[c])
378 return 1;
379 }
380
381 if (cur_cfg->num_regions != user_cfg->num_regions)
382 return 1;
383
384 /* Regions */
385 for (c = 0; c < user_cfg->num_regions; c++) {
386 if (cur_cfg->region[c].h_start != user_cfg->region[c].h_start)
387 return 1;
388 if (cur_cfg->region[c].h_end != user_cfg->region[c].h_end)
389 return 1;
390 if (cur_cfg->region[c].v_start != user_cfg->region[c].v_start)
391 return 1;
392 if (cur_cfg->region[c].v_end != user_cfg->region[c].v_end)
393 return 1;
394 }
395
396 return 0;
397}
398
399/*
400 * hist_update_params - Helper function to check and store user given params.
401 * @new_conf: Pointer to user configuration structure.
402 */
403static void hist_set_params(struct ispstat *hist, void *new_conf)
404{
405 struct omap3isp_hist_config *user_cfg = new_conf;
406 struct omap3isp_hist_config *cur_cfg = hist->priv;
407
408 if (!hist->configured || hist_comp_params(hist, user_cfg)) {
409 memcpy(cur_cfg, user_cfg, sizeof(*user_cfg));
410 if (user_cfg->num_acc_frames == 0)
411 user_cfg->num_acc_frames = 1;
412 hist->inc_config++;
413 hist->update = 1;
414 /*
415 * User might be asked for a bigger buffer than necessary for
416 * this configuration. In order to return the right amount of
417 * data during buffer request, let's calculate the size here
418 * instead of stick with user_cfg->buf_size.
419 */
420 cur_cfg->buf_size = hist_get_buf_size(cur_cfg);
421
422 }
423}
424
425static long hist_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
426{
427 struct ispstat *stat = v4l2_get_subdevdata(sd);
428
429 switch (cmd) {
430 case VIDIOC_OMAP3ISP_HIST_CFG:
431 return omap3isp_stat_config(stat, arg);
432 case VIDIOC_OMAP3ISP_STAT_REQ:
433 return omap3isp_stat_request_statistics(stat, arg);
434 case VIDIOC_OMAP3ISP_STAT_EN: {
435 int *en = arg;
436 return omap3isp_stat_enable(stat, !!*en);
437 }
438 }
439
440 return -ENOIOCTLCMD;
441
442}
443
444static const struct ispstat_ops hist_ops = {
445 .validate_params = hist_validate_params,
446 .set_params = hist_set_params,
447 .setup_regs = hist_setup_regs,
448 .enable = hist_enable,
449 .busy = hist_busy,
450 .buf_process = hist_buf_process,
451};
452
453static const struct v4l2_subdev_core_ops hist_subdev_core_ops = {
454 .ioctl = hist_ioctl,
455 .subscribe_event = omap3isp_stat_subscribe_event,
456 .unsubscribe_event = omap3isp_stat_unsubscribe_event,
457};
458
459static const struct v4l2_subdev_video_ops hist_subdev_video_ops = {
460 .s_stream = omap3isp_stat_s_stream,
461};
462
463static const struct v4l2_subdev_ops hist_subdev_ops = {
464 .core = &hist_subdev_core_ops,
465 .video = &hist_subdev_video_ops,
466};
467
468/*
469 * omap3isp_hist_init - Module Initialization.
470 */
471int omap3isp_hist_init(struct isp_device *isp)
472{
473 struct ispstat *hist = &isp->isp_hist;
474 struct omap3isp_hist_config *hist_cfg;
475 int ret = -1;
476
477 hist_cfg = kzalloc(sizeof(*hist_cfg), GFP_KERNEL);
478 if (hist_cfg == NULL)
479 return -ENOMEM;
480
481 memset(hist, 0, sizeof(*hist));
482 if (HIST_CONFIG_DMA)
483 ret = omap_request_dma(OMAP24XX_DMA_NO_DEVICE, "DMA_ISP_HIST",
484 hist_dma_cb, hist, &hist->dma_ch);
485 if (ret) {
486 if (HIST_CONFIG_DMA)
487 dev_warn(isp->dev, "hist: DMA request channel failed. "
488 "Using PIO only.\n");
489 hist->dma_ch = -1;
490 } else {
491 dev_dbg(isp->dev, "hist: DMA channel = %d\n", hist->dma_ch);
492 hist_dma_config(hist);
493 omap_enable_dma_irq(hist->dma_ch, OMAP_DMA_BLOCK_IRQ);
494 }
495
496 hist->ops = &hist_ops;
497 hist->priv = hist_cfg;
498 hist->event_type = V4L2_EVENT_OMAP3ISP_HIST;
499 hist->isp = isp;
500
501 ret = omap3isp_stat_init(hist, "histogram", &hist_subdev_ops);
502 if (ret) {
503 kfree(hist_cfg);
504 if (HIST_USING_DMA(hist))
505 omap_free_dma(hist->dma_ch);
506 }
507
508 return ret;
509}
510
511/*
512 * omap3isp_hist_cleanup - Module cleanup.
513 */
514void omap3isp_hist_cleanup(struct isp_device *isp)
515{
516 if (HIST_USING_DMA(&isp->isp_hist))
517 omap_free_dma(isp->isp_hist.dma_ch);
518 kfree(isp->isp_hist.priv);
519 omap3isp_stat_free(&isp->isp_hist);
520}
diff --git a/drivers/media/video/omap3isp/isphist.h b/drivers/media/video/omap3isp/isphist.h
new file mode 100644
index 000000000000..0b2a38ec94c4
--- /dev/null
+++ b/drivers/media/video/omap3isp/isphist.h
@@ -0,0 +1,40 @@
1/*
2 * isphist.h
3 *
4 * TI OMAP3 ISP - Histogram module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_HIST_H
29#define OMAP3_ISP_HIST_H
30
31#include <linux/omap3isp.h>
32
33#define ISPHIST_IN_BIT_WIDTH_CCDC 10
34
35struct isp_device;
36
37int omap3isp_hist_init(struct isp_device *isp);
38void omap3isp_hist_cleanup(struct isp_device *isp);
39
40#endif /* OMAP3_ISP_HIST */
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
new file mode 100644
index 000000000000..baf9374201dc
--- /dev/null
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -0,0 +1,2113 @@
1/*
2 * isppreview.c
3 *
4 * TI OMAP3 ISP driver - Preview module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30#include <linux/mutex.h>
31#include <linux/uaccess.h>
32
33#include "isp.h"
34#include "ispreg.h"
35#include "isppreview.h"
36
37/* Default values in Office Flourescent Light for RGBtoRGB Blending */
38static struct omap3isp_prev_rgbtorgb flr_rgb2rgb = {
39 { /* RGB-RGB Matrix */
40 {0x01E2, 0x0F30, 0x0FEE},
41 {0x0F9B, 0x01AC, 0x0FB9},
42 {0x0FE0, 0x0EC0, 0x0260}
43 }, /* RGB Offset */
44 {0x0000, 0x0000, 0x0000}
45};
46
47/* Default values in Office Flourescent Light for RGB to YUV Conversion*/
48static struct omap3isp_prev_csc flr_prev_csc = {
49 { /* CSC Coef Matrix */
50 {66, 129, 25},
51 {-38, -75, 112},
52 {112, -94 , -18}
53 }, /* CSC Offset */
54 {0x0, 0x0, 0x0}
55};
56
57/* Default values in Office Flourescent Light for CFA Gradient*/
58#define FLR_CFA_GRADTHRS_HORZ 0x28
59#define FLR_CFA_GRADTHRS_VERT 0x28
60
61/* Default values in Office Flourescent Light for Chroma Suppression*/
62#define FLR_CSUP_GAIN 0x0D
63#define FLR_CSUP_THRES 0xEB
64
65/* Default values in Office Flourescent Light for Noise Filter*/
66#define FLR_NF_STRGTH 0x03
67
68/* Default values for White Balance */
69#define FLR_WBAL_DGAIN 0x100
70#define FLR_WBAL_COEF 0x20
71
72/* Default values in Office Flourescent Light for Black Adjustment*/
73#define FLR_BLKADJ_BLUE 0x0
74#define FLR_BLKADJ_GREEN 0x0
75#define FLR_BLKADJ_RED 0x0
76
77#define DEF_DETECT_CORRECT_VAL 0xe
78
79#define PREV_MIN_WIDTH 64
80#define PREV_MIN_HEIGHT 8
81#define PREV_MAX_HEIGHT 16384
82
83/*
84 * Coeficient Tables for the submodules in Preview.
85 * Array is initialised with the values from.the tables text file.
86 */
87
88/*
89 * CFA Filter Coefficient Table
90 *
91 */
92static u32 cfa_coef_table[] = {
93#include "cfa_coef_table.h"
94};
95
96/*
97 * Default Gamma Correction Table - All components
98 */
99static u32 gamma_table[] = {
100#include "gamma_table.h"
101};
102
103/*
104 * Noise Filter Threshold table
105 */
106static u32 noise_filter_table[] = {
107#include "noise_filter_table.h"
108};
109
110/*
111 * Luminance Enhancement Table
112 */
113static u32 luma_enhance_table[] = {
114#include "luma_enhance_table.h"
115};
116
117/*
118 * preview_enable_invalaw - Enable/Disable Inverse A-Law module in Preview.
119 * @enable: 1 - Reverse the A-Law done in CCDC.
120 */
121static void
122preview_enable_invalaw(struct isp_prev_device *prev, u8 enable)
123{
124 struct isp_device *isp = to_isp_device(prev);
125
126 if (enable)
127 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
128 ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
129 else
130 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
131 ISPPRV_PCR_WIDTH | ISPPRV_PCR_INVALAW);
132}
133
134/*
135 * preview_enable_drkframe_capture - Enable/Disable of the darkframe capture.
136 * @prev -
137 * @enable: 1 - Enable, 0 - Disable
138 *
139 * NOTE: PRV_WSDR_ADDR and PRV_WADD_OFFSET must be set also
140 * The proccess is applied for each captured frame.
141 */
142static void
143preview_enable_drkframe_capture(struct isp_prev_device *prev, u8 enable)
144{
145 struct isp_device *isp = to_isp_device(prev);
146
147 if (enable)
148 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
149 ISPPRV_PCR_DRKFCAP);
150 else
151 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
152 ISPPRV_PCR_DRKFCAP);
153}
154
155/*
156 * preview_enable_drkframe - Enable/Disable of the darkframe subtract.
157 * @enable: 1 - Acquires memory bandwidth since the pixels in each frame is
158 * subtracted with the pixels in the current frame.
159 *
160 * The proccess is applied for each captured frame.
161 */
162static void
163preview_enable_drkframe(struct isp_prev_device *prev, u8 enable)
164{
165 struct isp_device *isp = to_isp_device(prev);
166
167 if (enable)
168 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
169 ISPPRV_PCR_DRKFEN);
170 else
171 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
172 ISPPRV_PCR_DRKFEN);
173}
174
175/*
176 * preview_config_drkf_shadcomp - Configures shift value in shading comp.
177 * @scomp_shtval: 3bit value of shift used in shading compensation.
178 */
179static void
180preview_config_drkf_shadcomp(struct isp_prev_device *prev,
181 const void *scomp_shtval)
182{
183 struct isp_device *isp = to_isp_device(prev);
184 const u32 *shtval = scomp_shtval;
185
186 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
187 ISPPRV_PCR_SCOMP_SFT_MASK,
188 *shtval << ISPPRV_PCR_SCOMP_SFT_SHIFT);
189}
190
191/*
192 * preview_enable_hmed - Enables/Disables of the Horizontal Median Filter.
193 * @enable: 1 - Enables Horizontal Median Filter.
194 */
195static void
196preview_enable_hmed(struct isp_prev_device *prev, u8 enable)
197{
198 struct isp_device *isp = to_isp_device(prev);
199
200 if (enable)
201 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
202 ISPPRV_PCR_HMEDEN);
203 else
204 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
205 ISPPRV_PCR_HMEDEN);
206}
207
208/*
209 * preview_config_hmed - Configures the Horizontal Median Filter.
210 * @prev_hmed: Structure containing the odd and even distance between the
211 * pixels in the image along with the filter threshold.
212 */
213static void
214preview_config_hmed(struct isp_prev_device *prev, const void *prev_hmed)
215{
216 struct isp_device *isp = to_isp_device(prev);
217 const struct omap3isp_prev_hmed *hmed = prev_hmed;
218
219 isp_reg_writel(isp, (hmed->odddist == 1 ? 0 : ISPPRV_HMED_ODDDIST) |
220 (hmed->evendist == 1 ? 0 : ISPPRV_HMED_EVENDIST) |
221 (hmed->thres << ISPPRV_HMED_THRESHOLD_SHIFT),
222 OMAP3_ISP_IOMEM_PREV, ISPPRV_HMED);
223}
224
225/*
226 * preview_config_noisefilter - Configures the Noise Filter.
227 * @prev_nf: Structure containing the noisefilter table, strength to be used
228 * for the noise filter and the defect correction enable flag.
229 */
230static void
231preview_config_noisefilter(struct isp_prev_device *prev, const void *prev_nf)
232{
233 struct isp_device *isp = to_isp_device(prev);
234 const struct omap3isp_prev_nf *nf = prev_nf;
235 unsigned int i;
236
237 isp_reg_writel(isp, nf->spread, OMAP3_ISP_IOMEM_PREV, ISPPRV_NF);
238 isp_reg_writel(isp, ISPPRV_NF_TABLE_ADDR,
239 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
240 for (i = 0; i < OMAP3ISP_PREV_NF_TBL_SIZE; i++) {
241 isp_reg_writel(isp, nf->table[i],
242 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
243 }
244}
245
246/*
247 * preview_config_dcor - Configures the defect correction
248 * @prev_dcor: Structure containing the defect correct thresholds
249 */
250static void
251preview_config_dcor(struct isp_prev_device *prev, const void *prev_dcor)
252{
253 struct isp_device *isp = to_isp_device(prev);
254 const struct omap3isp_prev_dcor *dcor = prev_dcor;
255
256 isp_reg_writel(isp, dcor->detect_correct[0],
257 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR0);
258 isp_reg_writel(isp, dcor->detect_correct[1],
259 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR1);
260 isp_reg_writel(isp, dcor->detect_correct[2],
261 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR2);
262 isp_reg_writel(isp, dcor->detect_correct[3],
263 OMAP3_ISP_IOMEM_PREV, ISPPRV_CDC_THR3);
264 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
265 ISPPRV_PCR_DCCOUP,
266 dcor->couplet_mode_en ? ISPPRV_PCR_DCCOUP : 0);
267}
268
269/*
270 * preview_config_cfa - Configures the CFA Interpolation parameters.
271 * @prev_cfa: Structure containing the CFA interpolation table, CFA format
272 * in the image, vertical and horizontal gradient threshold.
273 */
274static void
275preview_config_cfa(struct isp_prev_device *prev, const void *prev_cfa)
276{
277 struct isp_device *isp = to_isp_device(prev);
278 const struct omap3isp_prev_cfa *cfa = prev_cfa;
279 unsigned int i;
280
281 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
282 ISPPRV_PCR_CFAFMT_MASK,
283 cfa->format << ISPPRV_PCR_CFAFMT_SHIFT);
284
285 isp_reg_writel(isp,
286 (cfa->gradthrs_vert << ISPPRV_CFA_GRADTH_VER_SHIFT) |
287 (cfa->gradthrs_horz << ISPPRV_CFA_GRADTH_HOR_SHIFT),
288 OMAP3_ISP_IOMEM_PREV, ISPPRV_CFA);
289
290 isp_reg_writel(isp, ISPPRV_CFA_TABLE_ADDR,
291 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
292
293 for (i = 0; i < OMAP3ISP_PREV_CFA_TBL_SIZE; i++) {
294 isp_reg_writel(isp, cfa->table[i],
295 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
296 }
297}
298
299/*
300 * preview_config_gammacorrn - Configures the Gamma Correction table values
301 * @gtable: Structure containing the table for red, blue, green gamma table.
302 */
303static void
304preview_config_gammacorrn(struct isp_prev_device *prev, const void *gtable)
305{
306 struct isp_device *isp = to_isp_device(prev);
307 const struct omap3isp_prev_gtables *gt = gtable;
308 unsigned int i;
309
310 isp_reg_writel(isp, ISPPRV_REDGAMMA_TABLE_ADDR,
311 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
312 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
313 isp_reg_writel(isp, gt->red[i], OMAP3_ISP_IOMEM_PREV,
314 ISPPRV_SET_TBL_DATA);
315
316 isp_reg_writel(isp, ISPPRV_GREENGAMMA_TABLE_ADDR,
317 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
318 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
319 isp_reg_writel(isp, gt->green[i], OMAP3_ISP_IOMEM_PREV,
320 ISPPRV_SET_TBL_DATA);
321
322 isp_reg_writel(isp, ISPPRV_BLUEGAMMA_TABLE_ADDR,
323 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
324 for (i = 0; i < OMAP3ISP_PREV_GAMMA_TBL_SIZE; i++)
325 isp_reg_writel(isp, gt->blue[i], OMAP3_ISP_IOMEM_PREV,
326 ISPPRV_SET_TBL_DATA);
327}
328
329/*
330 * preview_config_luma_enhancement - Sets the Luminance Enhancement table.
331 * @ytable: Structure containing the table for Luminance Enhancement table.
332 */
333static void
334preview_config_luma_enhancement(struct isp_prev_device *prev,
335 const void *ytable)
336{
337 struct isp_device *isp = to_isp_device(prev);
338 const struct omap3isp_prev_luma *yt = ytable;
339 unsigned int i;
340
341 isp_reg_writel(isp, ISPPRV_YENH_TABLE_ADDR,
342 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_ADDR);
343 for (i = 0; i < OMAP3ISP_PREV_YENH_TBL_SIZE; i++) {
344 isp_reg_writel(isp, yt->table[i],
345 OMAP3_ISP_IOMEM_PREV, ISPPRV_SET_TBL_DATA);
346 }
347}
348
349/*
350 * preview_config_chroma_suppression - Configures the Chroma Suppression.
351 * @csup: Structure containing the threshold value for suppression
352 * and the hypass filter enable flag.
353 */
354static void
355preview_config_chroma_suppression(struct isp_prev_device *prev,
356 const void *csup)
357{
358 struct isp_device *isp = to_isp_device(prev);
359 const struct omap3isp_prev_csup *cs = csup;
360
361 isp_reg_writel(isp,
362 cs->gain | (cs->thres << ISPPRV_CSUP_THRES_SHIFT) |
363 (cs->hypf_en << ISPPRV_CSUP_HPYF_SHIFT),
364 OMAP3_ISP_IOMEM_PREV, ISPPRV_CSUP);
365}
366
367/*
368 * preview_enable_noisefilter - Enables/Disables the Noise Filter.
369 * @enable: 1 - Enables the Noise Filter.
370 */
371static void
372preview_enable_noisefilter(struct isp_prev_device *prev, u8 enable)
373{
374 struct isp_device *isp = to_isp_device(prev);
375
376 if (enable)
377 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
378 ISPPRV_PCR_NFEN);
379 else
380 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
381 ISPPRV_PCR_NFEN);
382}
383
384/*
385 * preview_enable_dcor - Enables/Disables the defect correction.
386 * @enable: 1 - Enables the defect correction.
387 */
388static void
389preview_enable_dcor(struct isp_prev_device *prev, u8 enable)
390{
391 struct isp_device *isp = to_isp_device(prev);
392
393 if (enable)
394 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
395 ISPPRV_PCR_DCOREN);
396 else
397 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
398 ISPPRV_PCR_DCOREN);
399}
400
401/*
402 * preview_enable_cfa - Enable/Disable the CFA Interpolation.
403 * @enable: 1 - Enables the CFA.
404 */
405static void
406preview_enable_cfa(struct isp_prev_device *prev, u8 enable)
407{
408 struct isp_device *isp = to_isp_device(prev);
409
410 if (enable)
411 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
412 ISPPRV_PCR_CFAEN);
413 else
414 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
415 ISPPRV_PCR_CFAEN);
416}
417
418/*
419 * preview_enable_gammabypass - Enables/Disables the GammaByPass
420 * @enable: 1 - Bypasses Gamma - 10bit input is cropped to 8MSB.
421 * 0 - Goes through Gamma Correction. input and output is 10bit.
422 */
423static void
424preview_enable_gammabypass(struct isp_prev_device *prev, u8 enable)
425{
426 struct isp_device *isp = to_isp_device(prev);
427
428 if (enable)
429 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
430 ISPPRV_PCR_GAMMA_BYPASS);
431 else
432 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
433 ISPPRV_PCR_GAMMA_BYPASS);
434}
435
436/*
437 * preview_enable_luma_enhancement - Enables/Disables Luminance Enhancement
438 * @enable: 1 - Enable the Luminance Enhancement.
439 */
440static void
441preview_enable_luma_enhancement(struct isp_prev_device *prev, u8 enable)
442{
443 struct isp_device *isp = to_isp_device(prev);
444
445 if (enable)
446 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
447 ISPPRV_PCR_YNENHEN);
448 else
449 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
450 ISPPRV_PCR_YNENHEN);
451}
452
453/*
454 * preview_enable_chroma_suppression - Enables/Disables Chrominance Suppr.
455 * @enable: 1 - Enable the Chrominance Suppression.
456 */
457static void
458preview_enable_chroma_suppression(struct isp_prev_device *prev, u8 enable)
459{
460 struct isp_device *isp = to_isp_device(prev);
461
462 if (enable)
463 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
464 ISPPRV_PCR_SUPEN);
465 else
466 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
467 ISPPRV_PCR_SUPEN);
468}
469
470/*
471 * preview_config_whitebalance - Configures the White Balance parameters.
472 * @prev_wbal: Structure containing the digital gain and white balance
473 * coefficient.
474 *
475 * Coefficient matrix always with default values.
476 */
477static void
478preview_config_whitebalance(struct isp_prev_device *prev, const void *prev_wbal)
479{
480 struct isp_device *isp = to_isp_device(prev);
481 const struct omap3isp_prev_wbal *wbal = prev_wbal;
482 u32 val;
483
484 isp_reg_writel(isp, wbal->dgain, OMAP3_ISP_IOMEM_PREV, ISPPRV_WB_DGAIN);
485
486 val = wbal->coef0 << ISPPRV_WBGAIN_COEF0_SHIFT;
487 val |= wbal->coef1 << ISPPRV_WBGAIN_COEF1_SHIFT;
488 val |= wbal->coef2 << ISPPRV_WBGAIN_COEF2_SHIFT;
489 val |= wbal->coef3 << ISPPRV_WBGAIN_COEF3_SHIFT;
490 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_WBGAIN);
491
492 isp_reg_writel(isp,
493 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_0_SHIFT |
494 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_1_SHIFT |
495 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N0_2_SHIFT |
496 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N0_3_SHIFT |
497 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_0_SHIFT |
498 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_1_SHIFT |
499 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N1_2_SHIFT |
500 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N1_3_SHIFT |
501 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_0_SHIFT |
502 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_1_SHIFT |
503 ISPPRV_WBSEL_COEF0 << ISPPRV_WBSEL_N2_2_SHIFT |
504 ISPPRV_WBSEL_COEF1 << ISPPRV_WBSEL_N2_3_SHIFT |
505 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_0_SHIFT |
506 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_1_SHIFT |
507 ISPPRV_WBSEL_COEF2 << ISPPRV_WBSEL_N3_2_SHIFT |
508 ISPPRV_WBSEL_COEF3 << ISPPRV_WBSEL_N3_3_SHIFT,
509 OMAP3_ISP_IOMEM_PREV, ISPPRV_WBSEL);
510}
511
512/*
513 * preview_config_blkadj - Configures the Black Adjustment parameters.
514 * @prev_blkadj: Structure containing the black adjustment towards red, green,
515 * blue.
516 */
517static void
518preview_config_blkadj(struct isp_prev_device *prev, const void *prev_blkadj)
519{
520 struct isp_device *isp = to_isp_device(prev);
521 const struct omap3isp_prev_blkadj *blkadj = prev_blkadj;
522
523 isp_reg_writel(isp, (blkadj->blue << ISPPRV_BLKADJOFF_B_SHIFT) |
524 (blkadj->green << ISPPRV_BLKADJOFF_G_SHIFT) |
525 (blkadj->red << ISPPRV_BLKADJOFF_R_SHIFT),
526 OMAP3_ISP_IOMEM_PREV, ISPPRV_BLKADJOFF);
527}
528
529/*
530 * preview_config_rgb_blending - Configures the RGB-RGB Blending matrix.
531 * @rgb2rgb: Structure containing the rgb to rgb blending matrix and the rgb
532 * offset.
533 */
534static void
535preview_config_rgb_blending(struct isp_prev_device *prev, const void *rgb2rgb)
536{
537 struct isp_device *isp = to_isp_device(prev);
538 const struct omap3isp_prev_rgbtorgb *rgbrgb = rgb2rgb;
539 u32 val;
540
541 val = (rgbrgb->matrix[0][0] & 0xfff) << ISPPRV_RGB_MAT1_MTX_RR_SHIFT;
542 val |= (rgbrgb->matrix[0][1] & 0xfff) << ISPPRV_RGB_MAT1_MTX_GR_SHIFT;
543 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT1);
544
545 val = (rgbrgb->matrix[0][2] & 0xfff) << ISPPRV_RGB_MAT2_MTX_BR_SHIFT;
546 val |= (rgbrgb->matrix[1][0] & 0xfff) << ISPPRV_RGB_MAT2_MTX_RG_SHIFT;
547 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT2);
548
549 val = (rgbrgb->matrix[1][1] & 0xfff) << ISPPRV_RGB_MAT3_MTX_GG_SHIFT;
550 val |= (rgbrgb->matrix[1][2] & 0xfff) << ISPPRV_RGB_MAT3_MTX_BG_SHIFT;
551 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT3);
552
553 val = (rgbrgb->matrix[2][0] & 0xfff) << ISPPRV_RGB_MAT4_MTX_RB_SHIFT;
554 val |= (rgbrgb->matrix[2][1] & 0xfff) << ISPPRV_RGB_MAT4_MTX_GB_SHIFT;
555 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT4);
556
557 val = (rgbrgb->matrix[2][2] & 0xfff) << ISPPRV_RGB_MAT5_MTX_BB_SHIFT;
558 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_MAT5);
559
560 val = (rgbrgb->offset[0] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT;
561 val |= (rgbrgb->offset[1] & 0x3ff) << ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT;
562 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF1);
563
564 val = (rgbrgb->offset[2] & 0x3ff) << ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT;
565 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_RGB_OFF2);
566}
567
568/*
569 * Configures the RGB-YCbYCr conversion matrix
570 * @prev_csc: Structure containing the RGB to YCbYCr matrix and the
571 * YCbCr offset.
572 */
573static void
574preview_config_rgb_to_ycbcr(struct isp_prev_device *prev, const void *prev_csc)
575{
576 struct isp_device *isp = to_isp_device(prev);
577 const struct omap3isp_prev_csc *csc = prev_csc;
578 u32 val;
579
580 val = (csc->matrix[0][0] & 0x3ff) << ISPPRV_CSC0_RY_SHIFT;
581 val |= (csc->matrix[0][1] & 0x3ff) << ISPPRV_CSC0_GY_SHIFT;
582 val |= (csc->matrix[0][2] & 0x3ff) << ISPPRV_CSC0_BY_SHIFT;
583 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC0);
584
585 val = (csc->matrix[1][0] & 0x3ff) << ISPPRV_CSC1_RCB_SHIFT;
586 val |= (csc->matrix[1][1] & 0x3ff) << ISPPRV_CSC1_GCB_SHIFT;
587 val |= (csc->matrix[1][2] & 0x3ff) << ISPPRV_CSC1_BCB_SHIFT;
588 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC1);
589
590 val = (csc->matrix[2][0] & 0x3ff) << ISPPRV_CSC2_RCR_SHIFT;
591 val |= (csc->matrix[2][1] & 0x3ff) << ISPPRV_CSC2_GCR_SHIFT;
592 val |= (csc->matrix[2][2] & 0x3ff) << ISPPRV_CSC2_BCR_SHIFT;
593 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC2);
594
595 val = (csc->offset[0] & 0xff) << ISPPRV_CSC_OFFSET_Y_SHIFT;
596 val |= (csc->offset[1] & 0xff) << ISPPRV_CSC_OFFSET_CB_SHIFT;
597 val |= (csc->offset[2] & 0xff) << ISPPRV_CSC_OFFSET_CR_SHIFT;
598 isp_reg_writel(isp, val, OMAP3_ISP_IOMEM_PREV, ISPPRV_CSC_OFFSET);
599}
600
601/*
602 * preview_update_contrast - Updates the contrast.
603 * @contrast: Pointer to hold the current programmed contrast value.
604 *
605 * Value should be programmed before enabling the module.
606 */
607static void
608preview_update_contrast(struct isp_prev_device *prev, u8 contrast)
609{
610 struct prev_params *params = &prev->params;
611
612 if (params->contrast != (contrast * ISPPRV_CONTRAST_UNITS)) {
613 params->contrast = contrast * ISPPRV_CONTRAST_UNITS;
614 prev->update |= PREV_CONTRAST;
615 }
616}
617
618/*
619 * preview_config_contrast - Configures the Contrast.
620 * @params: Contrast value (u8 pointer, U8Q0 format).
621 *
622 * Value should be programmed before enabling the module.
623 */
624static void
625preview_config_contrast(struct isp_prev_device *prev, const void *params)
626{
627 struct isp_device *isp = to_isp_device(prev);
628
629 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
630 0xff << ISPPRV_CNT_BRT_CNT_SHIFT,
631 *(u8 *)params << ISPPRV_CNT_BRT_CNT_SHIFT);
632}
633
634/*
635 * preview_update_brightness - Updates the brightness in preview module.
636 * @brightness: Pointer to hold the current programmed brightness value.
637 *
638 */
639static void
640preview_update_brightness(struct isp_prev_device *prev, u8 brightness)
641{
642 struct prev_params *params = &prev->params;
643
644 if (params->brightness != (brightness * ISPPRV_BRIGHT_UNITS)) {
645 params->brightness = brightness * ISPPRV_BRIGHT_UNITS;
646 prev->update |= PREV_BRIGHTNESS;
647 }
648}
649
650/*
651 * preview_config_brightness - Configures the brightness.
652 * @params: Brightness value (u8 pointer, U8Q0 format).
653 */
654static void
655preview_config_brightness(struct isp_prev_device *prev, const void *params)
656{
657 struct isp_device *isp = to_isp_device(prev);
658
659 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_CNT_BRT,
660 0xff << ISPPRV_CNT_BRT_BRT_SHIFT,
661 *(u8 *)params << ISPPRV_CNT_BRT_BRT_SHIFT);
662}
663
664/*
665 * preview_config_yc_range - Configures the max and min Y and C values.
666 * @yclimit: Structure containing the range of Y and C values.
667 */
668static void
669preview_config_yc_range(struct isp_prev_device *prev, const void *yclimit)
670{
671 struct isp_device *isp = to_isp_device(prev);
672 const struct omap3isp_prev_yclimit *yc = yclimit;
673
674 isp_reg_writel(isp,
675 yc->maxC << ISPPRV_SETUP_YC_MAXC_SHIFT |
676 yc->maxY << ISPPRV_SETUP_YC_MAXY_SHIFT |
677 yc->minC << ISPPRV_SETUP_YC_MINC_SHIFT |
678 yc->minY << ISPPRV_SETUP_YC_MINY_SHIFT,
679 OMAP3_ISP_IOMEM_PREV, ISPPRV_SETUP_YC);
680}
681
682/* preview parameters update structure */
683struct preview_update {
684 int cfg_bit;
685 int feature_bit;
686 void (*config)(struct isp_prev_device *, const void *);
687 void (*enable)(struct isp_prev_device *, u8);
688};
689
690static struct preview_update update_attrs[] = {
691 {OMAP3ISP_PREV_LUMAENH, PREV_LUMA_ENHANCE,
692 preview_config_luma_enhancement,
693 preview_enable_luma_enhancement},
694 {OMAP3ISP_PREV_INVALAW, PREV_INVERSE_ALAW,
695 NULL,
696 preview_enable_invalaw},
697 {OMAP3ISP_PREV_HRZ_MED, PREV_HORZ_MEDIAN_FILTER,
698 preview_config_hmed,
699 preview_enable_hmed},
700 {OMAP3ISP_PREV_CFA, PREV_CFA,
701 preview_config_cfa,
702 preview_enable_cfa},
703 {OMAP3ISP_PREV_CHROMA_SUPP, PREV_CHROMA_SUPPRESS,
704 preview_config_chroma_suppression,
705 preview_enable_chroma_suppression},
706 {OMAP3ISP_PREV_WB, PREV_WB,
707 preview_config_whitebalance,
708 NULL},
709 {OMAP3ISP_PREV_BLKADJ, PREV_BLKADJ,
710 preview_config_blkadj,
711 NULL},
712 {OMAP3ISP_PREV_RGB2RGB, PREV_RGB2RGB,
713 preview_config_rgb_blending,
714 NULL},
715 {OMAP3ISP_PREV_COLOR_CONV, PREV_COLOR_CONV,
716 preview_config_rgb_to_ycbcr,
717 NULL},
718 {OMAP3ISP_PREV_YC_LIMIT, PREV_YCLIMITS,
719 preview_config_yc_range,
720 NULL},
721 {OMAP3ISP_PREV_DEFECT_COR, PREV_DEFECT_COR,
722 preview_config_dcor,
723 preview_enable_dcor},
724 {OMAP3ISP_PREV_GAMMABYPASS, PREV_GAMMA_BYPASS,
725 NULL,
726 preview_enable_gammabypass},
727 {OMAP3ISP_PREV_DRK_FRM_CAPTURE, PREV_DARK_FRAME_CAPTURE,
728 NULL,
729 preview_enable_drkframe_capture},
730 {OMAP3ISP_PREV_DRK_FRM_SUBTRACT, PREV_DARK_FRAME_SUBTRACT,
731 NULL,
732 preview_enable_drkframe},
733 {OMAP3ISP_PREV_LENS_SHADING, PREV_LENS_SHADING,
734 preview_config_drkf_shadcomp,
735 preview_enable_drkframe},
736 {OMAP3ISP_PREV_NF, PREV_NOISE_FILTER,
737 preview_config_noisefilter,
738 preview_enable_noisefilter},
739 {OMAP3ISP_PREV_GAMMA, PREV_GAMMA,
740 preview_config_gammacorrn,
741 NULL},
742 {-1, PREV_CONTRAST,
743 preview_config_contrast,
744 NULL},
745 {-1, PREV_BRIGHTNESS,
746 preview_config_brightness,
747 NULL},
748};
749
750/*
751 * __preview_get_ptrs - helper function which return pointers to members
752 * of params and config structures.
753 * @params - pointer to preview_params structure.
754 * @param - return pointer to appropriate structure field.
755 * @configs - pointer to update config structure.
756 * @config - return pointer to appropriate structure field.
757 * @bit - for which feature to return pointers.
758 * Return size of coresponding prev_params member
759 */
760static u32
761__preview_get_ptrs(struct prev_params *params, void **param,
762 struct omap3isp_prev_update_config *configs,
763 void __user **config, u32 bit)
764{
765#define CHKARG(cfgs, cfg, field) \
766 if (cfgs && cfg) { \
767 *(cfg) = (cfgs)->field; \
768 }
769
770 switch (bit) {
771 case PREV_HORZ_MEDIAN_FILTER:
772 *param = &params->hmed;
773 CHKARG(configs, config, hmed)
774 return sizeof(params->hmed);
775 case PREV_NOISE_FILTER:
776 *param = &params->nf;
777 CHKARG(configs, config, nf)
778 return sizeof(params->nf);
779 break;
780 case PREV_CFA:
781 *param = &params->cfa;
782 CHKARG(configs, config, cfa)
783 return sizeof(params->cfa);
784 case PREV_LUMA_ENHANCE:
785 *param = &params->luma;
786 CHKARG(configs, config, luma)
787 return sizeof(params->luma);
788 case PREV_CHROMA_SUPPRESS:
789 *param = &params->csup;
790 CHKARG(configs, config, csup)
791 return sizeof(params->csup);
792 case PREV_DEFECT_COR:
793 *param = &params->dcor;
794 CHKARG(configs, config, dcor)
795 return sizeof(params->dcor);
796 case PREV_BLKADJ:
797 *param = &params->blk_adj;
798 CHKARG(configs, config, blkadj)
799 return sizeof(params->blk_adj);
800 case PREV_YCLIMITS:
801 *param = &params->yclimit;
802 CHKARG(configs, config, yclimit)
803 return sizeof(params->yclimit);
804 case PREV_RGB2RGB:
805 *param = &params->rgb2rgb;
806 CHKARG(configs, config, rgb2rgb)
807 return sizeof(params->rgb2rgb);
808 case PREV_COLOR_CONV:
809 *param = &params->rgb2ycbcr;
810 CHKARG(configs, config, csc)
811 return sizeof(params->rgb2ycbcr);
812 case PREV_WB:
813 *param = &params->wbal;
814 CHKARG(configs, config, wbal)
815 return sizeof(params->wbal);
816 case PREV_GAMMA:
817 *param = &params->gamma;
818 CHKARG(configs, config, gamma)
819 return sizeof(params->gamma);
820 case PREV_CONTRAST:
821 *param = &params->contrast;
822 return 0;
823 case PREV_BRIGHTNESS:
824 *param = &params->brightness;
825 return 0;
826 default:
827 *param = NULL;
828 *config = NULL;
829 break;
830 }
831 return 0;
832}
833
834/*
835 * preview_config - Copy and update local structure with userspace preview
836 * configuration.
837 * @prev: ISP preview engine
838 * @cfg: Configuration
839 *
840 * Return zero if success or -EFAULT if the configuration can't be copied from
841 * userspace.
842 */
843static int preview_config(struct isp_prev_device *prev,
844 struct omap3isp_prev_update_config *cfg)
845{
846 struct prev_params *params;
847 struct preview_update *attr;
848 int i, bit, rval = 0;
849
850 params = &prev->params;
851
852 if (prev->state != ISP_PIPELINE_STREAM_STOPPED) {
853 unsigned long flags;
854
855 spin_lock_irqsave(&prev->lock, flags);
856 prev->shadow_update = 1;
857 spin_unlock_irqrestore(&prev->lock, flags);
858 }
859
860 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
861 attr = &update_attrs[i];
862 bit = 0;
863
864 if (!(cfg->update & attr->cfg_bit))
865 continue;
866
867 bit = cfg->flag & attr->cfg_bit;
868 if (bit) {
869 void *to = NULL, __user *from = NULL;
870 unsigned long sz = 0;
871
872 sz = __preview_get_ptrs(params, &to, cfg, &from,
873 bit);
874 if (to && from && sz) {
875 if (copy_from_user(to, from, sz)) {
876 rval = -EFAULT;
877 break;
878 }
879 }
880 params->features |= attr->feature_bit;
881 } else {
882 params->features &= ~attr->feature_bit;
883 }
884
885 prev->update |= attr->feature_bit;
886 }
887
888 prev->shadow_update = 0;
889 return rval;
890}
891
892/*
893 * preview_setup_hw - Setup preview registers and/or internal memory
894 * @prev: pointer to preview private structure
895 * Note: can be called from interrupt context
896 * Return none
897 */
898static void preview_setup_hw(struct isp_prev_device *prev)
899{
900 struct prev_params *params = &prev->params;
901 struct preview_update *attr;
902 int i, bit;
903 void *param_ptr;
904
905 for (i = 0; i < ARRAY_SIZE(update_attrs); i++) {
906 attr = &update_attrs[i];
907
908 if (!(prev->update & attr->feature_bit))
909 continue;
910 bit = params->features & attr->feature_bit;
911 if (bit) {
912 if (attr->config) {
913 __preview_get_ptrs(params, &param_ptr, NULL,
914 NULL, bit);
915 attr->config(prev, param_ptr);
916 }
917 if (attr->enable)
918 attr->enable(prev, 1);
919 } else
920 if (attr->enable)
921 attr->enable(prev, 0);
922
923 prev->update &= ~attr->feature_bit;
924 }
925}
926
927/*
928 * preview_config_ycpos - Configure byte layout of YUV image.
929 * @mode: Indicates the required byte layout.
930 */
931static void
932preview_config_ycpos(struct isp_prev_device *prev,
933 enum v4l2_mbus_pixelcode pixelcode)
934{
935 struct isp_device *isp = to_isp_device(prev);
936 enum preview_ycpos_mode mode;
937
938 switch (pixelcode) {
939 case V4L2_MBUS_FMT_YUYV8_1X16:
940 mode = YCPOS_CrYCbY;
941 break;
942 case V4L2_MBUS_FMT_UYVY8_1X16:
943 mode = YCPOS_YCrYCb;
944 break;
945 default:
946 return;
947 }
948
949 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
950 ISPPRV_PCR_YCPOS_CrYCbY,
951 mode << ISPPRV_PCR_YCPOS_SHIFT);
952}
953
954/*
955 * preview_config_averager - Enable / disable / configure averager
956 * @average: Average value to be configured.
957 */
958static void preview_config_averager(struct isp_prev_device *prev, u8 average)
959{
960 struct isp_device *isp = to_isp_device(prev);
961 int reg = 0;
962
963 if (prev->params.cfa.format == OMAP3ISP_CFAFMT_BAYER)
964 reg = ISPPRV_AVE_EVENDIST_2 << ISPPRV_AVE_EVENDIST_SHIFT |
965 ISPPRV_AVE_ODDDIST_2 << ISPPRV_AVE_ODDDIST_SHIFT |
966 average;
967 else if (prev->params.cfa.format == OMAP3ISP_CFAFMT_RGBFOVEON)
968 reg = ISPPRV_AVE_EVENDIST_3 << ISPPRV_AVE_EVENDIST_SHIFT |
969 ISPPRV_AVE_ODDDIST_3 << ISPPRV_AVE_ODDDIST_SHIFT |
970 average;
971 isp_reg_writel(isp, reg, OMAP3_ISP_IOMEM_PREV, ISPPRV_AVE);
972}
973
974/*
975 * preview_config_input_size - Configure the input frame size
976 *
977 * The preview engine crops several rows and columns internally depending on
978 * which processing blocks are enabled. The driver assumes all those blocks are
979 * enabled when reporting source pad formats to userspace. If this assumption is
980 * not true, rows and columns must be manually cropped at the preview engine
981 * input to avoid overflows at the end of lines and frames.
982 */
983static void preview_config_input_size(struct isp_prev_device *prev)
984{
985 struct isp_device *isp = to_isp_device(prev);
986 struct prev_params *params = &prev->params;
987 struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK];
988 unsigned int sph = 0;
989 unsigned int eph = format->width - 1;
990 unsigned int slv = 0;
991 unsigned int elv = format->height - 1;
992
993 if (prev->input == PREVIEW_INPUT_CCDC) {
994 sph += 2;
995 eph -= 2;
996 }
997
998 /*
999 * Median filter 4 pixels
1000 * Noise filter 4 pixels, 4 lines
1001 * or faulty pixels correction
1002 * CFA filter 4 pixels, 4 lines in Bayer mode
1003 * 2 lines in other modes
1004 * Color suppression 2 pixels
1005 * or luma enhancement
1006 * -------------------------------------------------------------
1007 * Maximum total 14 pixels, 8 lines
1008 */
1009
1010 if (!(params->features & PREV_CFA)) {
1011 sph += 2;
1012 eph -= 2;
1013 slv += 2;
1014 elv -= 2;
1015 }
1016 if (!(params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER))) {
1017 sph += 2;
1018 eph -= 2;
1019 slv += 2;
1020 elv -= 2;
1021 }
1022 if (!(params->features & PREV_HORZ_MEDIAN_FILTER)) {
1023 sph += 2;
1024 eph -= 2;
1025 }
1026 if (!(params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)))
1027 sph += 2;
1028
1029 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
1030 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
1031 isp_reg_writel(isp, (slv << ISPPRV_VERT_INFO_SLV_SHIFT) | elv,
1032 OMAP3_ISP_IOMEM_PREV, ISPPRV_VERT_INFO);
1033}
1034
1035/*
1036 * preview_config_inlineoffset - Configures the Read address line offset.
1037 * @prev: Preview module
1038 * @offset: Line offset
1039 *
1040 * According to the TRM, the line offset must be aligned on a 32 bytes boundary.
1041 * However, a hardware bug requires the memory start address to be aligned on a
1042 * 64 bytes boundary, so the offset probably should be aligned on 64 bytes as
1043 * well.
1044 */
1045static void
1046preview_config_inlineoffset(struct isp_prev_device *prev, u32 offset)
1047{
1048 struct isp_device *isp = to_isp_device(prev);
1049
1050 isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
1051 ISPPRV_RADR_OFFSET);
1052}
1053
1054/*
1055 * preview_set_inaddr - Sets memory address of input frame.
1056 * @addr: 32bit memory address aligned on 32byte boundary.
1057 *
1058 * Configures the memory address from which the input frame is to be read.
1059 */
1060static void preview_set_inaddr(struct isp_prev_device *prev, u32 addr)
1061{
1062 struct isp_device *isp = to_isp_device(prev);
1063
1064 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_RSDR_ADDR);
1065}
1066
1067/*
1068 * preview_config_outlineoffset - Configures the Write address line offset.
1069 * @offset: Line Offset for the preview output.
1070 *
1071 * The offset must be a multiple of 32 bytes.
1072 */
1073static void preview_config_outlineoffset(struct isp_prev_device *prev,
1074 u32 offset)
1075{
1076 struct isp_device *isp = to_isp_device(prev);
1077
1078 isp_reg_writel(isp, offset & 0xffff, OMAP3_ISP_IOMEM_PREV,
1079 ISPPRV_WADD_OFFSET);
1080}
1081
1082/*
1083 * preview_set_outaddr - Sets the memory address to store output frame
1084 * @addr: 32bit memory address aligned on 32byte boundary.
1085 *
1086 * Configures the memory address to which the output frame is written.
1087 */
1088static void preview_set_outaddr(struct isp_prev_device *prev, u32 addr)
1089{
1090 struct isp_device *isp = to_isp_device(prev);
1091
1092 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_PREV, ISPPRV_WSDR_ADDR);
1093}
1094
1095static void preview_adjust_bandwidth(struct isp_prev_device *prev)
1096{
1097 struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
1098 struct isp_device *isp = to_isp_device(prev);
1099 const struct v4l2_mbus_framefmt *ifmt = &prev->formats[PREV_PAD_SINK];
1100 unsigned long l3_ick = pipe->l3_ick;
1101 struct v4l2_fract *timeperframe;
1102 unsigned int cycles_per_frame;
1103 unsigned int requests_per_frame;
1104 unsigned int cycles_per_request;
1105 unsigned int minimum;
1106 unsigned int maximum;
1107 unsigned int value;
1108
1109 if (prev->input != PREVIEW_INPUT_MEMORY) {
1110 isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
1111 ISPSBL_SDR_REQ_PRV_EXP_MASK);
1112 return;
1113 }
1114
1115 /* Compute the minimum number of cycles per request, based on the
1116 * pipeline maximum data rate. This is an absolute lower bound if we
1117 * don't want SBL overflows, so round the value up.
1118 */
1119 cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
1120 pipe->max_rate);
1121 minimum = DIV_ROUND_UP(cycles_per_request, 32);
1122
1123 /* Compute the maximum number of cycles per request, based on the
1124 * requested frame rate. This is a soft upper bound to achieve a frame
1125 * rate equal or higher than the requested value, so round the value
1126 * down.
1127 */
1128 timeperframe = &pipe->max_timeperframe;
1129
1130 requests_per_frame = DIV_ROUND_UP(ifmt->width * 2, 256) * ifmt->height;
1131 cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
1132 timeperframe->denominator);
1133 cycles_per_request = cycles_per_frame / requests_per_frame;
1134
1135 maximum = cycles_per_request / 32;
1136
1137 value = max(minimum, maximum);
1138
1139 dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
1140 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
1141 ISPSBL_SDR_REQ_PRV_EXP_MASK,
1142 value << ISPSBL_SDR_REQ_PRV_EXP_SHIFT);
1143}
1144
1145/*
1146 * omap3isp_preview_busy - Gets busy state of preview module.
1147 */
1148int omap3isp_preview_busy(struct isp_prev_device *prev)
1149{
1150 struct isp_device *isp = to_isp_device(prev);
1151
1152 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR)
1153 & ISPPRV_PCR_BUSY;
1154}
1155
1156/*
1157 * omap3isp_preview_restore_context - Restores the values of preview registers
1158 */
1159void omap3isp_preview_restore_context(struct isp_device *isp)
1160{
1161 isp->isp_prev.update = PREV_FEATURES_END - 1;
1162 preview_setup_hw(&isp->isp_prev);
1163}
1164
1165/*
1166 * preview_print_status - Dump preview module registers to the kernel log
1167 */
1168#define PREV_PRINT_REGISTER(isp, name)\
1169 dev_dbg(isp->dev, "###PRV " #name "=0x%08x\n", \
1170 isp_reg_readl(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_##name))
1171
1172static void preview_print_status(struct isp_prev_device *prev)
1173{
1174 struct isp_device *isp = to_isp_device(prev);
1175
1176 dev_dbg(isp->dev, "-------------Preview Register dump----------\n");
1177
1178 PREV_PRINT_REGISTER(isp, PCR);
1179 PREV_PRINT_REGISTER(isp, HORZ_INFO);
1180 PREV_PRINT_REGISTER(isp, VERT_INFO);
1181 PREV_PRINT_REGISTER(isp, RSDR_ADDR);
1182 PREV_PRINT_REGISTER(isp, RADR_OFFSET);
1183 PREV_PRINT_REGISTER(isp, DSDR_ADDR);
1184 PREV_PRINT_REGISTER(isp, DRKF_OFFSET);
1185 PREV_PRINT_REGISTER(isp, WSDR_ADDR);
1186 PREV_PRINT_REGISTER(isp, WADD_OFFSET);
1187 PREV_PRINT_REGISTER(isp, AVE);
1188 PREV_PRINT_REGISTER(isp, HMED);
1189 PREV_PRINT_REGISTER(isp, NF);
1190 PREV_PRINT_REGISTER(isp, WB_DGAIN);
1191 PREV_PRINT_REGISTER(isp, WBGAIN);
1192 PREV_PRINT_REGISTER(isp, WBSEL);
1193 PREV_PRINT_REGISTER(isp, CFA);
1194 PREV_PRINT_REGISTER(isp, BLKADJOFF);
1195 PREV_PRINT_REGISTER(isp, RGB_MAT1);
1196 PREV_PRINT_REGISTER(isp, RGB_MAT2);
1197 PREV_PRINT_REGISTER(isp, RGB_MAT3);
1198 PREV_PRINT_REGISTER(isp, RGB_MAT4);
1199 PREV_PRINT_REGISTER(isp, RGB_MAT5);
1200 PREV_PRINT_REGISTER(isp, RGB_OFF1);
1201 PREV_PRINT_REGISTER(isp, RGB_OFF2);
1202 PREV_PRINT_REGISTER(isp, CSC0);
1203 PREV_PRINT_REGISTER(isp, CSC1);
1204 PREV_PRINT_REGISTER(isp, CSC2);
1205 PREV_PRINT_REGISTER(isp, CSC_OFFSET);
1206 PREV_PRINT_REGISTER(isp, CNT_BRT);
1207 PREV_PRINT_REGISTER(isp, CSUP);
1208 PREV_PRINT_REGISTER(isp, SETUP_YC);
1209 PREV_PRINT_REGISTER(isp, SET_TBL_ADDR);
1210 PREV_PRINT_REGISTER(isp, CDC_THR0);
1211 PREV_PRINT_REGISTER(isp, CDC_THR1);
1212 PREV_PRINT_REGISTER(isp, CDC_THR2);
1213 PREV_PRINT_REGISTER(isp, CDC_THR3);
1214
1215 dev_dbg(isp->dev, "--------------------------------------------\n");
1216}
1217
1218/*
1219 * preview_init_params - init image processing parameters.
1220 * @prev: pointer to previewer private structure
1221 * return none
1222 */
1223static void preview_init_params(struct isp_prev_device *prev)
1224{
1225 struct prev_params *params = &prev->params;
1226 int i = 0;
1227
1228 /* Init values */
1229 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
1230 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
1231 params->average = NO_AVE;
1232 params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
1233 memcpy(params->cfa.table, cfa_coef_table,
1234 sizeof(params->cfa.table));
1235 params->cfa.gradthrs_horz = FLR_CFA_GRADTHRS_HORZ;
1236 params->cfa.gradthrs_vert = FLR_CFA_GRADTHRS_VERT;
1237 params->csup.gain = FLR_CSUP_GAIN;
1238 params->csup.thres = FLR_CSUP_THRES;
1239 params->csup.hypf_en = 0;
1240 memcpy(params->luma.table, luma_enhance_table,
1241 sizeof(params->luma.table));
1242 params->nf.spread = FLR_NF_STRGTH;
1243 memcpy(params->nf.table, noise_filter_table, sizeof(params->nf.table));
1244 params->dcor.couplet_mode_en = 1;
1245 for (i = 0; i < OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS; i++)
1246 params->dcor.detect_correct[i] = DEF_DETECT_CORRECT_VAL;
1247 memcpy(params->gamma.blue, gamma_table, sizeof(params->gamma.blue));
1248 memcpy(params->gamma.green, gamma_table, sizeof(params->gamma.green));
1249 memcpy(params->gamma.red, gamma_table, sizeof(params->gamma.red));
1250 params->wbal.dgain = FLR_WBAL_DGAIN;
1251 params->wbal.coef0 = FLR_WBAL_COEF;
1252 params->wbal.coef1 = FLR_WBAL_COEF;
1253 params->wbal.coef2 = FLR_WBAL_COEF;
1254 params->wbal.coef3 = FLR_WBAL_COEF;
1255 params->blk_adj.red = FLR_BLKADJ_RED;
1256 params->blk_adj.green = FLR_BLKADJ_GREEN;
1257 params->blk_adj.blue = FLR_BLKADJ_BLUE;
1258 params->rgb2rgb = flr_rgb2rgb;
1259 params->rgb2ycbcr = flr_prev_csc;
1260 params->yclimit.minC = ISPPRV_YC_MIN;
1261 params->yclimit.maxC = ISPPRV_YC_MAX;
1262 params->yclimit.minY = ISPPRV_YC_MIN;
1263 params->yclimit.maxY = ISPPRV_YC_MAX;
1264
1265 params->features = PREV_CFA | PREV_DEFECT_COR | PREV_NOISE_FILTER
1266 | PREV_GAMMA | PREV_BLKADJ | PREV_YCLIMITS
1267 | PREV_RGB2RGB | PREV_COLOR_CONV | PREV_WB
1268 | PREV_BRIGHTNESS | PREV_CONTRAST;
1269
1270 prev->update = PREV_FEATURES_END - 1;
1271}
1272
1273/*
1274 * preview_max_out_width - Handle previewer hardware ouput limitations
1275 * @isp_revision : ISP revision
1276 * returns maximum width output for current isp revision
1277 */
1278static unsigned int preview_max_out_width(struct isp_prev_device *prev)
1279{
1280 struct isp_device *isp = to_isp_device(prev);
1281
1282 switch (isp->revision) {
1283 case ISP_REVISION_1_0:
1284 return ISPPRV_MAXOUTPUT_WIDTH;
1285
1286 case ISP_REVISION_2_0:
1287 default:
1288 return ISPPRV_MAXOUTPUT_WIDTH_ES2;
1289
1290 case ISP_REVISION_15_0:
1291 return ISPPRV_MAXOUTPUT_WIDTH_3630;
1292 }
1293}
1294
1295static void preview_configure(struct isp_prev_device *prev)
1296{
1297 struct isp_device *isp = to_isp_device(prev);
1298 struct v4l2_mbus_framefmt *format;
1299 unsigned int max_out_width;
1300 unsigned int format_avg;
1301
1302 preview_setup_hw(prev);
1303
1304 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1305 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1306 ISPPRV_PCR_SDRPORT);
1307 else
1308 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1309 ISPPRV_PCR_SDRPORT);
1310
1311 if (prev->output & PREVIEW_OUTPUT_RESIZER)
1312 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1313 ISPPRV_PCR_RSZPORT);
1314 else
1315 isp_reg_clr(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1316 ISPPRV_PCR_RSZPORT);
1317
1318 /* PREV_PAD_SINK */
1319 format = &prev->formats[PREV_PAD_SINK];
1320
1321 preview_adjust_bandwidth(prev);
1322
1323 preview_config_input_size(prev);
1324
1325 if (prev->input == PREVIEW_INPUT_CCDC)
1326 preview_config_inlineoffset(prev, 0);
1327 else
1328 preview_config_inlineoffset(prev,
1329 ALIGN(format->width, 0x20) * 2);
1330
1331 /* PREV_PAD_SOURCE */
1332 format = &prev->formats[PREV_PAD_SOURCE];
1333
1334 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1335 preview_config_outlineoffset(prev,
1336 ALIGN(format->width, 0x10) * 2);
1337
1338 max_out_width = preview_max_out_width(prev);
1339
1340 format_avg = fls(DIV_ROUND_UP(format->width, max_out_width) - 1);
1341 preview_config_averager(prev, format_avg);
1342 preview_config_ycpos(prev, format->code);
1343}
1344
1345/* -----------------------------------------------------------------------------
1346 * Interrupt handling
1347 */
1348
1349static void preview_enable_oneshot(struct isp_prev_device *prev)
1350{
1351 struct isp_device *isp = to_isp_device(prev);
1352
1353 /* The PCR.SOURCE bit is automatically reset to 0 when the PCR.ENABLE
1354 * bit is set. As the preview engine is used in single-shot mode, we
1355 * need to set PCR.SOURCE before enabling the preview engine.
1356 */
1357 if (prev->input == PREVIEW_INPUT_MEMORY)
1358 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1359 ISPPRV_PCR_SOURCE);
1360
1361 isp_reg_set(isp, OMAP3_ISP_IOMEM_PREV, ISPPRV_PCR,
1362 ISPPRV_PCR_EN | ISPPRV_PCR_ONESHOT);
1363}
1364
1365void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev)
1366{
1367 /*
1368 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
1369 * condition, the module was paused and now we have a buffer queued
1370 * on the output again. Restart the pipeline if running in continuous
1371 * mode.
1372 */
1373 if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
1374 prev->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1375 preview_enable_oneshot(prev);
1376 isp_video_dmaqueue_flags_clr(&prev->video_out);
1377 }
1378}
1379
1380static void preview_isr_buffer(struct isp_prev_device *prev)
1381{
1382 struct isp_pipeline *pipe = to_isp_pipeline(&prev->subdev.entity);
1383 struct isp_buffer *buffer;
1384 int restart = 0;
1385
1386 if (prev->input == PREVIEW_INPUT_MEMORY) {
1387 buffer = omap3isp_video_buffer_next(&prev->video_in,
1388 prev->error);
1389 if (buffer != NULL)
1390 preview_set_inaddr(prev, buffer->isp_addr);
1391 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
1392 }
1393
1394 if (prev->output & PREVIEW_OUTPUT_MEMORY) {
1395 buffer = omap3isp_video_buffer_next(&prev->video_out,
1396 prev->error);
1397 if (buffer != NULL) {
1398 preview_set_outaddr(prev, buffer->isp_addr);
1399 restart = 1;
1400 }
1401 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1402 }
1403
1404 switch (prev->state) {
1405 case ISP_PIPELINE_STREAM_SINGLESHOT:
1406 if (isp_pipeline_ready(pipe))
1407 omap3isp_pipeline_set_stream(pipe,
1408 ISP_PIPELINE_STREAM_SINGLESHOT);
1409 break;
1410
1411 case ISP_PIPELINE_STREAM_CONTINUOUS:
1412 /* If an underrun occurs, the video queue operation handler will
1413 * restart the preview engine. Otherwise restart it immediately.
1414 */
1415 if (restart)
1416 preview_enable_oneshot(prev);
1417 break;
1418
1419 case ISP_PIPELINE_STREAM_STOPPED:
1420 default:
1421 return;
1422 }
1423
1424 prev->error = 0;
1425}
1426
1427/*
1428 * omap3isp_preview_isr - ISP preview engine interrupt handler
1429 *
1430 * Manage the preview engine video buffers and configure shadowed registers.
1431 */
1432void omap3isp_preview_isr(struct isp_prev_device *prev)
1433{
1434 unsigned long flags;
1435
1436 if (omap3isp_module_sync_is_stopping(&prev->wait, &prev->stopping))
1437 return;
1438
1439 spin_lock_irqsave(&prev->lock, flags);
1440 if (prev->shadow_update)
1441 goto done;
1442
1443 preview_setup_hw(prev);
1444 preview_config_input_size(prev);
1445
1446done:
1447 spin_unlock_irqrestore(&prev->lock, flags);
1448
1449 if (prev->input == PREVIEW_INPUT_MEMORY ||
1450 prev->output & PREVIEW_OUTPUT_MEMORY)
1451 preview_isr_buffer(prev);
1452 else if (prev->state == ISP_PIPELINE_STREAM_CONTINUOUS)
1453 preview_enable_oneshot(prev);
1454}
1455
1456/* -----------------------------------------------------------------------------
1457 * ISP video operations
1458 */
1459
1460static int preview_video_queue(struct isp_video *video,
1461 struct isp_buffer *buffer)
1462{
1463 struct isp_prev_device *prev = &video->isp->isp_prev;
1464
1465 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1466 preview_set_inaddr(prev, buffer->isp_addr);
1467
1468 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1469 preview_set_outaddr(prev, buffer->isp_addr);
1470
1471 return 0;
1472}
1473
1474static const struct isp_video_operations preview_video_ops = {
1475 .queue = preview_video_queue,
1476};
1477
1478/* -----------------------------------------------------------------------------
1479 * V4L2 subdev operations
1480 */
1481
1482/*
1483 * preview_s_ctrl - Handle set control subdev method
1484 * @ctrl: pointer to v4l2 control structure
1485 */
1486static int preview_s_ctrl(struct v4l2_ctrl *ctrl)
1487{
1488 struct isp_prev_device *prev =
1489 container_of(ctrl->handler, struct isp_prev_device, ctrls);
1490
1491 switch (ctrl->id) {
1492 case V4L2_CID_BRIGHTNESS:
1493 preview_update_brightness(prev, ctrl->val);
1494 break;
1495 case V4L2_CID_CONTRAST:
1496 preview_update_contrast(prev, ctrl->val);
1497 break;
1498 }
1499
1500 return 0;
1501}
1502
1503static const struct v4l2_ctrl_ops preview_ctrl_ops = {
1504 .s_ctrl = preview_s_ctrl,
1505};
1506
1507/*
1508 * preview_ioctl - Handle preview module private ioctl's
1509 * @prev: pointer to preview context structure
1510 * @cmd: configuration command
1511 * @arg: configuration argument
1512 * return -EINVAL or zero on success
1513 */
1514static long preview_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
1515{
1516 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1517
1518 switch (cmd) {
1519 case VIDIOC_OMAP3ISP_PRV_CFG:
1520 return preview_config(prev, arg);
1521
1522 default:
1523 return -ENOIOCTLCMD;
1524 }
1525}
1526
1527/*
1528 * preview_set_stream - Enable/Disable streaming on preview subdev
1529 * @sd : pointer to v4l2 subdev structure
1530 * @enable: 1 == Enable, 0 == Disable
1531 * return -EINVAL or zero on sucess
1532 */
1533static int preview_set_stream(struct v4l2_subdev *sd, int enable)
1534{
1535 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1536 struct isp_video *video_out = &prev->video_out;
1537 struct isp_device *isp = to_isp_device(prev);
1538 struct device *dev = to_device(prev);
1539 unsigned long flags;
1540
1541 if (prev->state == ISP_PIPELINE_STREAM_STOPPED) {
1542 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1543 return 0;
1544
1545 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1546 preview_configure(prev);
1547 atomic_set(&prev->stopping, 0);
1548 prev->error = 0;
1549 preview_print_status(prev);
1550 }
1551
1552 switch (enable) {
1553 case ISP_PIPELINE_STREAM_CONTINUOUS:
1554 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1555 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1556
1557 if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED ||
1558 !(prev->output & PREVIEW_OUTPUT_MEMORY))
1559 preview_enable_oneshot(prev);
1560
1561 isp_video_dmaqueue_flags_clr(video_out);
1562 break;
1563
1564 case ISP_PIPELINE_STREAM_SINGLESHOT:
1565 if (prev->input == PREVIEW_INPUT_MEMORY)
1566 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1567 if (prev->output & PREVIEW_OUTPUT_MEMORY)
1568 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1569
1570 preview_enable_oneshot(prev);
1571 break;
1572
1573 case ISP_PIPELINE_STREAM_STOPPED:
1574 if (omap3isp_module_sync_idle(&sd->entity, &prev->wait,
1575 &prev->stopping))
1576 dev_dbg(dev, "%s: stop timeout.\n", sd->name);
1577 spin_lock_irqsave(&prev->lock, flags);
1578 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_READ);
1579 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_PREVIEW_WRITE);
1580 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_PREVIEW);
1581 spin_unlock_irqrestore(&prev->lock, flags);
1582 isp_video_dmaqueue_flags_clr(video_out);
1583 break;
1584 }
1585
1586 prev->state = enable;
1587 return 0;
1588}
1589
1590static struct v4l2_mbus_framefmt *
1591__preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1592 unsigned int pad, enum v4l2_subdev_format_whence which)
1593{
1594 if (which == V4L2_SUBDEV_FORMAT_TRY)
1595 return v4l2_subdev_get_try_format(fh, pad);
1596 else
1597 return &prev->formats[pad];
1598}
1599
1600/* previewer format descriptions */
1601static const unsigned int preview_input_fmts[] = {
1602 V4L2_MBUS_FMT_SGRBG10_1X10,
1603 V4L2_MBUS_FMT_SRGGB10_1X10,
1604 V4L2_MBUS_FMT_SBGGR10_1X10,
1605 V4L2_MBUS_FMT_SGBRG10_1X10,
1606};
1607
1608static const unsigned int preview_output_fmts[] = {
1609 V4L2_MBUS_FMT_UYVY8_1X16,
1610 V4L2_MBUS_FMT_YUYV8_1X16,
1611};
1612
1613/*
1614 * preview_try_format - Handle try format by pad subdev method
1615 * @prev: ISP preview device
1616 * @fh : V4L2 subdev file handle
1617 * @pad: pad num
1618 * @fmt: pointer to v4l2 format structure
1619 */
1620static void preview_try_format(struct isp_prev_device *prev,
1621 struct v4l2_subdev_fh *fh, unsigned int pad,
1622 struct v4l2_mbus_framefmt *fmt,
1623 enum v4l2_subdev_format_whence which)
1624{
1625 struct v4l2_mbus_framefmt *format;
1626 unsigned int max_out_width;
1627 enum v4l2_mbus_pixelcode pixelcode;
1628 unsigned int i;
1629
1630 max_out_width = preview_max_out_width(prev);
1631
1632 switch (pad) {
1633 case PREV_PAD_SINK:
1634 /* When reading data from the CCDC, the input size has already
1635 * been mangled by the CCDC output pad so it can be accepted
1636 * as-is.
1637 *
1638 * When reading data from memory, clamp the requested width and
1639 * height. The TRM doesn't specify a minimum input height, make
1640 * sure we got enough lines to enable the noise filter and color
1641 * filter array interpolation.
1642 */
1643 if (prev->input == PREVIEW_INPUT_MEMORY) {
1644 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_WIDTH,
1645 max_out_width * 8);
1646 fmt->height = clamp_t(u32, fmt->height, PREV_MIN_HEIGHT,
1647 PREV_MAX_HEIGHT);
1648 }
1649
1650 fmt->colorspace = V4L2_COLORSPACE_SRGB;
1651
1652 for (i = 0; i < ARRAY_SIZE(preview_input_fmts); i++) {
1653 if (fmt->code == preview_input_fmts[i])
1654 break;
1655 }
1656
1657 /* If not found, use SGRBG10 as default */
1658 if (i >= ARRAY_SIZE(preview_input_fmts))
1659 fmt->code = V4L2_MBUS_FMT_SGRBG10_1X10;
1660 break;
1661
1662 case PREV_PAD_SOURCE:
1663 pixelcode = fmt->code;
1664 format = __preview_get_format(prev, fh, PREV_PAD_SINK, which);
1665 memcpy(fmt, format, sizeof(*fmt));
1666
1667 /* The preview module output size is configurable through the
1668 * input interface (horizontal and vertical cropping) and the
1669 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). In
1670 * spite of this, hardcode the output size to the biggest
1671 * possible value for simplicity reasons.
1672 */
1673 switch (pixelcode) {
1674 case V4L2_MBUS_FMT_YUYV8_1X16:
1675 case V4L2_MBUS_FMT_UYVY8_1X16:
1676 fmt->code = pixelcode;
1677 break;
1678
1679 default:
1680 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1681 break;
1682 }
1683
1684 /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped
1685 * from the left and right sides when the input source is the
1686 * CCDC. This seems not to be needed in practice, investigation
1687 * is required.
1688 */
1689 if (prev->input == PREVIEW_INPUT_CCDC)
1690 fmt->width -= 4;
1691
1692 /* The preview module can output a maximum of 3312 pixels
1693 * horizontally due to fixed memory-line sizes. Compute the
1694 * horizontal averaging factor accordingly. Note that the limit
1695 * applies to the noise filter and CFA interpolation blocks, so
1696 * it doesn't take cropping by further blocks into account.
1697 *
1698 * ES 1.0 hardware revision is limited to 1280 pixels
1699 * horizontally.
1700 */
1701 fmt->width >>= fls(DIV_ROUND_UP(fmt->width, max_out_width) - 1);
1702
1703 /* Assume that all blocks are enabled and crop pixels and lines
1704 * accordingly. See preview_config_input_size() for more
1705 * information.
1706 */
1707 fmt->width -= 14;
1708 fmt->height -= 8;
1709
1710 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1711 break;
1712 }
1713
1714 fmt->field = V4L2_FIELD_NONE;
1715}
1716
1717/*
1718 * preview_enum_mbus_code - Handle pixel format enumeration
1719 * @sd : pointer to v4l2 subdev structure
1720 * @fh : V4L2 subdev file handle
1721 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1722 * return -EINVAL or zero on success
1723 */
1724static int preview_enum_mbus_code(struct v4l2_subdev *sd,
1725 struct v4l2_subdev_fh *fh,
1726 struct v4l2_subdev_mbus_code_enum *code)
1727{
1728 switch (code->pad) {
1729 case PREV_PAD_SINK:
1730 if (code->index >= ARRAY_SIZE(preview_input_fmts))
1731 return -EINVAL;
1732
1733 code->code = preview_input_fmts[code->index];
1734 break;
1735 case PREV_PAD_SOURCE:
1736 if (code->index >= ARRAY_SIZE(preview_output_fmts))
1737 return -EINVAL;
1738
1739 code->code = preview_output_fmts[code->index];
1740 break;
1741 default:
1742 return -EINVAL;
1743 }
1744
1745 return 0;
1746}
1747
1748static int preview_enum_frame_size(struct v4l2_subdev *sd,
1749 struct v4l2_subdev_fh *fh,
1750 struct v4l2_subdev_frame_size_enum *fse)
1751{
1752 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1753 struct v4l2_mbus_framefmt format;
1754
1755 if (fse->index != 0)
1756 return -EINVAL;
1757
1758 format.code = fse->code;
1759 format.width = 1;
1760 format.height = 1;
1761 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1762 fse->min_width = format.width;
1763 fse->min_height = format.height;
1764
1765 if (format.code != fse->code)
1766 return -EINVAL;
1767
1768 format.code = fse->code;
1769 format.width = -1;
1770 format.height = -1;
1771 preview_try_format(prev, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1772 fse->max_width = format.width;
1773 fse->max_height = format.height;
1774
1775 return 0;
1776}
1777
1778/*
1779 * preview_get_format - Handle get format by pads subdev method
1780 * @sd : pointer to v4l2 subdev structure
1781 * @fh : V4L2 subdev file handle
1782 * @fmt: pointer to v4l2 subdev format structure
1783 * return -EINVAL or zero on sucess
1784 */
1785static int preview_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1786 struct v4l2_subdev_format *fmt)
1787{
1788 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1789 struct v4l2_mbus_framefmt *format;
1790
1791 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
1792 if (format == NULL)
1793 return -EINVAL;
1794
1795 fmt->format = *format;
1796 return 0;
1797}
1798
1799/*
1800 * preview_set_format - Handle set format by pads subdev method
1801 * @sd : pointer to v4l2 subdev structure
1802 * @fh : V4L2 subdev file handle
1803 * @fmt: pointer to v4l2 subdev format structure
1804 * return -EINVAL or zero on success
1805 */
1806static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1807 struct v4l2_subdev_format *fmt)
1808{
1809 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1810 struct v4l2_mbus_framefmt *format;
1811
1812 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
1813 if (format == NULL)
1814 return -EINVAL;
1815
1816 preview_try_format(prev, fh, fmt->pad, &fmt->format, fmt->which);
1817 *format = fmt->format;
1818
1819 /* Propagate the format from sink to source */
1820 if (fmt->pad == PREV_PAD_SINK) {
1821 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
1822 fmt->which);
1823 *format = fmt->format;
1824 preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
1825 fmt->which);
1826 }
1827
1828 return 0;
1829}
1830
1831/*
1832 * preview_init_formats - Initialize formats on all pads
1833 * @sd: ISP preview V4L2 subdevice
1834 * @fh: V4L2 subdev file handle
1835 *
1836 * Initialize all pad formats with default values. If fh is not NULL, try
1837 * formats are initialized on the file handle. Otherwise active formats are
1838 * initialized on the device.
1839 */
1840static int preview_init_formats(struct v4l2_subdev *sd,
1841 struct v4l2_subdev_fh *fh)
1842{
1843 struct v4l2_subdev_format format;
1844
1845 memset(&format, 0, sizeof(format));
1846 format.pad = PREV_PAD_SINK;
1847 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1848 format.format.code = V4L2_MBUS_FMT_SGRBG10_1X10;
1849 format.format.width = 4096;
1850 format.format.height = 4096;
1851 preview_set_format(sd, fh, &format);
1852
1853 return 0;
1854}
1855
1856/* subdev core operations */
1857static const struct v4l2_subdev_core_ops preview_v4l2_core_ops = {
1858 .ioctl = preview_ioctl,
1859};
1860
1861/* subdev video operations */
1862static const struct v4l2_subdev_video_ops preview_v4l2_video_ops = {
1863 .s_stream = preview_set_stream,
1864};
1865
1866/* subdev pad operations */
1867static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
1868 .enum_mbus_code = preview_enum_mbus_code,
1869 .enum_frame_size = preview_enum_frame_size,
1870 .get_fmt = preview_get_format,
1871 .set_fmt = preview_set_format,
1872};
1873
1874/* subdev operations */
1875static const struct v4l2_subdev_ops preview_v4l2_ops = {
1876 .core = &preview_v4l2_core_ops,
1877 .video = &preview_v4l2_video_ops,
1878 .pad = &preview_v4l2_pad_ops,
1879};
1880
1881/* subdev internal operations */
1882static const struct v4l2_subdev_internal_ops preview_v4l2_internal_ops = {
1883 .open = preview_init_formats,
1884};
1885
1886/* -----------------------------------------------------------------------------
1887 * Media entity operations
1888 */
1889
1890/*
1891 * preview_link_setup - Setup previewer connections.
1892 * @entity : Pointer to media entity structure
1893 * @local : Pointer to local pad array
1894 * @remote : Pointer to remote pad array
1895 * @flags : Link flags
1896 * return -EINVAL or zero on success
1897 */
1898static int preview_link_setup(struct media_entity *entity,
1899 const struct media_pad *local,
1900 const struct media_pad *remote, u32 flags)
1901{
1902 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1903 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1904
1905 switch (local->index | media_entity_type(remote->entity)) {
1906 case PREV_PAD_SINK | MEDIA_ENT_T_DEVNODE:
1907 /* read from memory */
1908 if (flags & MEDIA_LNK_FL_ENABLED) {
1909 if (prev->input == PREVIEW_INPUT_CCDC)
1910 return -EBUSY;
1911 prev->input = PREVIEW_INPUT_MEMORY;
1912 } else {
1913 if (prev->input == PREVIEW_INPUT_MEMORY)
1914 prev->input = PREVIEW_INPUT_NONE;
1915 }
1916 break;
1917
1918 case PREV_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
1919 /* read from ccdc */
1920 if (flags & MEDIA_LNK_FL_ENABLED) {
1921 if (prev->input == PREVIEW_INPUT_MEMORY)
1922 return -EBUSY;
1923 prev->input = PREVIEW_INPUT_CCDC;
1924 } else {
1925 if (prev->input == PREVIEW_INPUT_CCDC)
1926 prev->input = PREVIEW_INPUT_NONE;
1927 }
1928 break;
1929
1930 /*
1931 * The ISP core doesn't support pipelines with multiple video outputs.
1932 * Revisit this when it will be implemented, and return -EBUSY for now.
1933 */
1934
1935 case PREV_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1936 /* write to memory */
1937 if (flags & MEDIA_LNK_FL_ENABLED) {
1938 if (prev->output & ~PREVIEW_OUTPUT_MEMORY)
1939 return -EBUSY;
1940 prev->output |= PREVIEW_OUTPUT_MEMORY;
1941 } else {
1942 prev->output &= ~PREVIEW_OUTPUT_MEMORY;
1943 }
1944 break;
1945
1946 case PREV_PAD_SOURCE | MEDIA_ENT_T_V4L2_SUBDEV:
1947 /* write to resizer */
1948 if (flags & MEDIA_LNK_FL_ENABLED) {
1949 if (prev->output & ~PREVIEW_OUTPUT_RESIZER)
1950 return -EBUSY;
1951 prev->output |= PREVIEW_OUTPUT_RESIZER;
1952 } else {
1953 prev->output &= ~PREVIEW_OUTPUT_RESIZER;
1954 }
1955 break;
1956
1957 default:
1958 return -EINVAL;
1959 }
1960
1961 return 0;
1962}
1963
1964/* media operations */
1965static const struct media_entity_operations preview_media_ops = {
1966 .link_setup = preview_link_setup,
1967};
1968
1969/*
1970 * review_init_entities - Initialize subdev and media entity.
1971 * @prev : Pointer to preview structure
1972 * return -ENOMEM or zero on success
1973 */
1974static int preview_init_entities(struct isp_prev_device *prev)
1975{
1976 struct v4l2_subdev *sd = &prev->subdev;
1977 struct media_pad *pads = prev->pads;
1978 struct media_entity *me = &sd->entity;
1979 int ret;
1980
1981 prev->input = PREVIEW_INPUT_NONE;
1982
1983 v4l2_subdev_init(sd, &preview_v4l2_ops);
1984 sd->internal_ops = &preview_v4l2_internal_ops;
1985 strlcpy(sd->name, "OMAP3 ISP preview", sizeof(sd->name));
1986 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1987 v4l2_set_subdevdata(sd, prev);
1988 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1989
1990 v4l2_ctrl_handler_init(&prev->ctrls, 2);
1991 v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_BRIGHTNESS,
1992 ISPPRV_BRIGHT_LOW, ISPPRV_BRIGHT_HIGH,
1993 ISPPRV_BRIGHT_STEP, ISPPRV_BRIGHT_DEF);
1994 v4l2_ctrl_new_std(&prev->ctrls, &preview_ctrl_ops, V4L2_CID_CONTRAST,
1995 ISPPRV_CONTRAST_LOW, ISPPRV_CONTRAST_HIGH,
1996 ISPPRV_CONTRAST_STEP, ISPPRV_CONTRAST_DEF);
1997 v4l2_ctrl_handler_setup(&prev->ctrls);
1998 sd->ctrl_handler = &prev->ctrls;
1999
2000 pads[PREV_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
2001 pads[PREV_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
2002
2003 me->ops = &preview_media_ops;
2004 ret = media_entity_init(me, PREV_PADS_NUM, pads, 0);
2005 if (ret < 0)
2006 return ret;
2007
2008 preview_init_formats(sd, NULL);
2009
2010 /* According to the OMAP34xx TRM, video buffers need to be aligned on a
2011 * 32 bytes boundary. However, an undocumented hardware bug requires a
2012 * 64 bytes boundary at the preview engine input.
2013 */
2014 prev->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
2015 prev->video_in.ops = &preview_video_ops;
2016 prev->video_in.isp = to_isp_device(prev);
2017 prev->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
2018 prev->video_in.bpl_alignment = 64;
2019 prev->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
2020 prev->video_out.ops = &preview_video_ops;
2021 prev->video_out.isp = to_isp_device(prev);
2022 prev->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
2023 prev->video_out.bpl_alignment = 32;
2024
2025 ret = omap3isp_video_init(&prev->video_in, "preview");
2026 if (ret < 0)
2027 return ret;
2028
2029 ret = omap3isp_video_init(&prev->video_out, "preview");
2030 if (ret < 0)
2031 return ret;
2032
2033 /* Connect the video nodes to the previewer subdev. */
2034 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2035 &prev->subdev.entity, PREV_PAD_SINK, 0);
2036 if (ret < 0)
2037 return ret;
2038
2039 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2040 &prev->video_out.video.entity, 0, 0);
2041 if (ret < 0)
2042 return ret;
2043
2044 return 0;
2045}
2046
2047void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
2048{
2049 media_entity_cleanup(&prev->subdev.entity);
2050
2051 v4l2_device_unregister_subdev(&prev->subdev);
2052 v4l2_ctrl_handler_free(&prev->ctrls);
2053 omap3isp_video_unregister(&prev->video_in);
2054 omap3isp_video_unregister(&prev->video_out);
2055}
2056
2057int omap3isp_preview_register_entities(struct isp_prev_device *prev,
2058 struct v4l2_device *vdev)
2059{
2060 int ret;
2061
2062 /* Register the subdev and video nodes. */
2063 ret = v4l2_device_register_subdev(vdev, &prev->subdev);
2064 if (ret < 0)
2065 goto error;
2066
2067 ret = omap3isp_video_register(&prev->video_in, vdev);
2068 if (ret < 0)
2069 goto error;
2070
2071 ret = omap3isp_video_register(&prev->video_out, vdev);
2072 if (ret < 0)
2073 goto error;
2074
2075 return 0;
2076
2077error:
2078 omap3isp_preview_unregister_entities(prev);
2079 return ret;
2080}
2081
2082/* -----------------------------------------------------------------------------
2083 * ISP previewer initialisation and cleanup
2084 */
2085
2086void omap3isp_preview_cleanup(struct isp_device *isp)
2087{
2088}
2089
2090/*
2091 * isp_preview_init - Previewer initialization.
2092 * @dev : Pointer to ISP device
2093 * return -ENOMEM or zero on success
2094 */
2095int omap3isp_preview_init(struct isp_device *isp)
2096{
2097 struct isp_prev_device *prev = &isp->isp_prev;
2098 int ret;
2099
2100 spin_lock_init(&prev->lock);
2101 init_waitqueue_head(&prev->wait);
2102 preview_init_params(prev);
2103
2104 ret = preview_init_entities(prev);
2105 if (ret < 0)
2106 goto out;
2107
2108out:
2109 if (ret)
2110 omap3isp_preview_cleanup(isp);
2111
2112 return ret;
2113}
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
new file mode 100644
index 000000000000..f2d63ca4bd6f
--- /dev/null
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -0,0 +1,214 @@
1/*
2 * isppreview.h
3 *
4 * TI OMAP3 ISP - Preview module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_PREVIEW_H
28#define OMAP3_ISP_PREVIEW_H
29
30#include <linux/omap3isp.h>
31#include <linux/types.h>
32#include <media/v4l2-ctrls.h>
33
34#include "ispvideo.h"
35
36#define ISPPRV_BRIGHT_STEP 0x1
37#define ISPPRV_BRIGHT_DEF 0x0
38#define ISPPRV_BRIGHT_LOW 0x0
39#define ISPPRV_BRIGHT_HIGH 0xFF
40#define ISPPRV_BRIGHT_UNITS 0x1
41
42#define ISPPRV_CONTRAST_STEP 0x1
43#define ISPPRV_CONTRAST_DEF 0x10
44#define ISPPRV_CONTRAST_LOW 0x0
45#define ISPPRV_CONTRAST_HIGH 0xFF
46#define ISPPRV_CONTRAST_UNITS 0x1
47
48#define NO_AVE 0x0
49#define AVE_2_PIX 0x1
50#define AVE_4_PIX 0x2
51#define AVE_8_PIX 0x3
52
53/* Features list */
54#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH
55#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW
56#define PREV_HORZ_MEDIAN_FILTER OMAP3ISP_PREV_HRZ_MED
57#define PREV_CFA OMAP3ISP_PREV_CFA
58#define PREV_CHROMA_SUPPRESS OMAP3ISP_PREV_CHROMA_SUPP
59#define PREV_WB OMAP3ISP_PREV_WB
60#define PREV_BLKADJ OMAP3ISP_PREV_BLKADJ
61#define PREV_RGB2RGB OMAP3ISP_PREV_RGB2RGB
62#define PREV_COLOR_CONV OMAP3ISP_PREV_COLOR_CONV
63#define PREV_YCLIMITS OMAP3ISP_PREV_YC_LIMIT
64#define PREV_DEFECT_COR OMAP3ISP_PREV_DEFECT_COR
65#define PREV_GAMMA_BYPASS OMAP3ISP_PREV_GAMMABYPASS
66#define PREV_DARK_FRAME_CAPTURE OMAP3ISP_PREV_DRK_FRM_CAPTURE
67#define PREV_DARK_FRAME_SUBTRACT OMAP3ISP_PREV_DRK_FRM_SUBTRACT
68#define PREV_LENS_SHADING OMAP3ISP_PREV_LENS_SHADING
69#define PREV_NOISE_FILTER OMAP3ISP_PREV_NF
70#define PREV_GAMMA OMAP3ISP_PREV_GAMMA
71
72#define PREV_CONTRAST (1 << 17)
73#define PREV_BRIGHTNESS (1 << 18)
74#define PREV_AVERAGER (1 << 19)
75#define PREV_FEATURES_END (1 << 20)
76
77enum preview_input_entity {
78 PREVIEW_INPUT_NONE,
79 PREVIEW_INPUT_CCDC,
80 PREVIEW_INPUT_MEMORY,
81};
82
83#define PREVIEW_OUTPUT_RESIZER (1 << 1)
84#define PREVIEW_OUTPUT_MEMORY (1 << 2)
85
86/* Configure byte layout of YUV image */
87enum preview_ycpos_mode {
88 YCPOS_YCrYCb = 0,
89 YCPOS_YCbYCr = 1,
90 YCPOS_CbYCrY = 2,
91 YCPOS_CrYCbY = 3
92};
93
94/*
95 * struct prev_params - Structure for all configuration
96 * @features: Set of features enabled.
97 * @cfa: CFA coefficients.
98 * @csup: Chroma suppression coefficients.
99 * @luma: Luma enhancement coefficients.
100 * @nf: Noise filter coefficients.
101 * @dcor: Noise filter coefficients.
102 * @gamma: Gamma coefficients.
103 * @wbal: White Balance parameters.
104 * @blk_adj: Black adjustment parameters.
105 * @rgb2rgb: RGB blending parameters.
106 * @rgb2ycbcr: RGB to ycbcr parameters.
107 * @hmed: Horizontal median filter.
108 * @yclimit: YC limits parameters.
109 * @average: Downsampling rate for averager.
110 * @contrast: Contrast.
111 * @brightness: Brightness.
112 */
113struct prev_params {
114 u32 features;
115 struct omap3isp_prev_cfa cfa;
116 struct omap3isp_prev_csup csup;
117 struct omap3isp_prev_luma luma;
118 struct omap3isp_prev_nf nf;
119 struct omap3isp_prev_dcor dcor;
120 struct omap3isp_prev_gtables gamma;
121 struct omap3isp_prev_wbal wbal;
122 struct omap3isp_prev_blkadj blk_adj;
123 struct omap3isp_prev_rgbtorgb rgb2rgb;
124 struct omap3isp_prev_csc rgb2ycbcr;
125 struct omap3isp_prev_hmed hmed;
126 struct omap3isp_prev_yclimit yclimit;
127 u8 average;
128 u8 contrast;
129 u8 brightness;
130};
131
132/*
133 * struct isptables_update - Structure for Table Configuration.
134 * @update: Specifies which tables should be updated.
135 * @flag: Specifies which tables should be enabled.
136 * @nf: Pointer to structure for Noise Filter
137 * @lsc: Pointer to LSC gain table. (currently not used)
138 * @gamma: Pointer to gamma correction tables.
139 * @cfa: Pointer to color filter array configuration.
140 * @wbal: Pointer to colour and digital gain configuration.
141 */
142struct isptables_update {
143 u32 update;
144 u32 flag;
145 struct omap3isp_prev_nf *nf;
146 u32 *lsc;
147 struct omap3isp_prev_gtables *gamma;
148 struct omap3isp_prev_cfa *cfa;
149 struct omap3isp_prev_wbal *wbal;
150};
151
152/* Sink and source previewer pads */
153#define PREV_PAD_SINK 0
154#define PREV_PAD_SOURCE 1
155#define PREV_PADS_NUM 2
156
157/*
158 * struct isp_prev_device - Structure for storing ISP Preview module information
159 * @subdev: V4L2 subdevice
160 * @pads: Media entity pads
161 * @formats: Active formats at the subdev pad
162 * @input: Module currently connected to the input pad
163 * @output: Bitmask of the active output
164 * @video_in: Input video entity
165 * @video_out: Output video entity
166 * @error: A hardware error occured during capture
167 * @params: Module configuration data
168 * @shadow_update: If set, update the hardware configured in the next interrupt
169 * @underrun: Whether the preview entity has queued buffers on the output
170 * @state: Current preview pipeline state
171 * @lock: Shadow update lock
172 * @update: Bitmask of the parameters to be updated
173 *
174 * This structure is used to store the OMAP ISP Preview module Information.
175 */
176struct isp_prev_device {
177 struct v4l2_subdev subdev;
178 struct media_pad pads[PREV_PADS_NUM];
179 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
180
181 struct v4l2_ctrl_handler ctrls;
182
183 enum preview_input_entity input;
184 unsigned int output;
185 struct isp_video video_in;
186 struct isp_video video_out;
187 unsigned int error;
188
189 struct prev_params params;
190 unsigned int shadow_update:1;
191 enum isp_pipeline_stream_state state;
192 wait_queue_head_t wait;
193 atomic_t stopping;
194 spinlock_t lock;
195 u32 update;
196};
197
198struct isp_device;
199
200int omap3isp_preview_init(struct isp_device *isp);
201void omap3isp_preview_cleanup(struct isp_device *isp);
202
203int omap3isp_preview_register_entities(struct isp_prev_device *prv,
204 struct v4l2_device *vdev);
205void omap3isp_preview_unregister_entities(struct isp_prev_device *prv);
206
207void omap3isp_preview_isr_frame_sync(struct isp_prev_device *prev);
208void omap3isp_preview_isr(struct isp_prev_device *prev);
209
210int omap3isp_preview_busy(struct isp_prev_device *isp_prev);
211
212void omap3isp_preview_restore_context(struct isp_device *isp);
213
214#endif /* OMAP3_ISP_PREVIEW_H */
diff --git a/drivers/media/video/omap3isp/ispqueue.c b/drivers/media/video/omap3isp/ispqueue.c
new file mode 100644
index 000000000000..8fddc5806b0d
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispqueue.c
@@ -0,0 +1,1153 @@
1/*
2 * ispqueue.c
3 *
4 * TI OMAP3 ISP - Video buffers queue handling
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * 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, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/dma-mapping.h>
28#include <linux/mm.h>
29#include <linux/pagemap.h>
30#include <linux/poll.h>
31#include <linux/scatterlist.h>
32#include <linux/sched.h>
33#include <linux/slab.h>
34#include <linux/vmalloc.h>
35
36#include "ispqueue.h"
37
38/* -----------------------------------------------------------------------------
39 * Video buffers management
40 */
41
42/*
43 * isp_video_buffer_cache_sync - Keep the buffers coherent between CPU and ISP
44 *
45 * The typical operation required here is Cache Invalidation across
46 * the (user space) buffer address range. And this _must_ be done
47 * at QBUF stage (and *only* at QBUF).
48 *
49 * We try to use optimal cache invalidation function:
50 * - dmac_map_area:
51 * - used when the number of pages are _low_.
52 * - it becomes quite slow as the number of pages increase.
53 * - for 648x492 viewfinder (150 pages) it takes 1.3 ms.
54 * - for 5 Mpix buffer (2491 pages) it takes between 25-50 ms.
55 *
56 * - flush_cache_all:
57 * - used when the number of pages are _high_.
58 * - time taken in the range of 500-900 us.
59 * - has a higher penalty but, as whole dcache + icache is invalidated
60 */
61/*
62 * FIXME: dmac_inv_range crashes randomly on the user space buffer
63 * address. Fall back to flush_cache_all for now.
64 */
65#define ISP_CACHE_FLUSH_PAGES_MAX 0
66
67static void isp_video_buffer_cache_sync(struct isp_video_buffer *buf)
68{
69 if (buf->skip_cache)
70 return;
71
72 if (buf->vbuf.m.userptr == 0 || buf->npages == 0 ||
73 buf->npages > ISP_CACHE_FLUSH_PAGES_MAX)
74 flush_cache_all();
75 else {
76 dmac_map_area((void *)buf->vbuf.m.userptr, buf->vbuf.length,
77 DMA_FROM_DEVICE);
78 outer_inv_range(buf->vbuf.m.userptr,
79 buf->vbuf.m.userptr + buf->vbuf.length);
80 }
81}
82
83/*
84 * isp_video_buffer_lock_vma - Prevent VMAs from being unmapped
85 *
86 * Lock the VMAs underlying the given buffer into memory. This avoids the
87 * userspace buffer mapping from being swapped out, making VIPT cache handling
88 * easier.
89 *
90 * Note that the pages will not be freed as the buffers have been locked to
91 * memory using by a call to get_user_pages(), but the userspace mapping could
92 * still disappear if the VMAs are not locked. This is caused by the memory
93 * management code trying to be as lock-less as possible, which results in the
94 * userspace mapping manager not finding out that the pages are locked under
95 * some conditions.
96 */
97static int isp_video_buffer_lock_vma(struct isp_video_buffer *buf, int lock)
98{
99 struct vm_area_struct *vma;
100 unsigned long start;
101 unsigned long end;
102 int ret = 0;
103
104 if (buf->vbuf.memory == V4L2_MEMORY_MMAP)
105 return 0;
106
107 /* We can be called from workqueue context if the current task dies to
108 * unlock the VMAs. In that case there's no current memory management
109 * context so unlocking can't be performed, but the VMAs have been or
110 * are getting destroyed anyway so it doesn't really matter.
111 */
112 if (!current || !current->mm)
113 return lock ? -EINVAL : 0;
114
115 start = buf->vbuf.m.userptr;
116 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
117
118 down_write(&current->mm->mmap_sem);
119 spin_lock(&current->mm->page_table_lock);
120
121 do {
122 vma = find_vma(current->mm, start);
123 if (vma == NULL) {
124 ret = -EFAULT;
125 goto out;
126 }
127
128 if (lock)
129 vma->vm_flags |= VM_LOCKED;
130 else
131 vma->vm_flags &= ~VM_LOCKED;
132
133 start = vma->vm_end + 1;
134 } while (vma->vm_end < end);
135
136 if (lock)
137 buf->vm_flags |= VM_LOCKED;
138 else
139 buf->vm_flags &= ~VM_LOCKED;
140
141out:
142 spin_unlock(&current->mm->page_table_lock);
143 up_write(&current->mm->mmap_sem);
144 return ret;
145}
146
147/*
148 * isp_video_buffer_sglist_kernel - Build a scatter list for a vmalloc'ed buffer
149 *
150 * Iterate over the vmalloc'ed area and create a scatter list entry for every
151 * page.
152 */
153static int isp_video_buffer_sglist_kernel(struct isp_video_buffer *buf)
154{
155 struct scatterlist *sglist;
156 unsigned int npages;
157 unsigned int i;
158 void *addr;
159
160 addr = buf->vaddr;
161 npages = PAGE_ALIGN(buf->vbuf.length) >> PAGE_SHIFT;
162
163 sglist = vmalloc(npages * sizeof(*sglist));
164 if (sglist == NULL)
165 return -ENOMEM;
166
167 sg_init_table(sglist, npages);
168
169 for (i = 0; i < npages; ++i, addr += PAGE_SIZE) {
170 struct page *page = vmalloc_to_page(addr);
171
172 if (page == NULL || PageHighMem(page)) {
173 vfree(sglist);
174 return -EINVAL;
175 }
176
177 sg_set_page(&sglist[i], page, PAGE_SIZE, 0);
178 }
179
180 buf->sglen = npages;
181 buf->sglist = sglist;
182
183 return 0;
184}
185
186/*
187 * isp_video_buffer_sglist_user - Build a scatter list for a userspace buffer
188 *
189 * Walk the buffer pages list and create a 1:1 mapping to a scatter list.
190 */
191static int isp_video_buffer_sglist_user(struct isp_video_buffer *buf)
192{
193 struct scatterlist *sglist;
194 unsigned int offset = buf->offset;
195 unsigned int i;
196
197 sglist = vmalloc(buf->npages * sizeof(*sglist));
198 if (sglist == NULL)
199 return -ENOMEM;
200
201 sg_init_table(sglist, buf->npages);
202
203 for (i = 0; i < buf->npages; ++i) {
204 if (PageHighMem(buf->pages[i])) {
205 vfree(sglist);
206 return -EINVAL;
207 }
208
209 sg_set_page(&sglist[i], buf->pages[i], PAGE_SIZE - offset,
210 offset);
211 offset = 0;
212 }
213
214 buf->sglen = buf->npages;
215 buf->sglist = sglist;
216
217 return 0;
218}
219
220/*
221 * isp_video_buffer_sglist_pfnmap - Build a scatter list for a VM_PFNMAP buffer
222 *
223 * Create a scatter list of physically contiguous pages starting at the buffer
224 * memory physical address.
225 */
226static int isp_video_buffer_sglist_pfnmap(struct isp_video_buffer *buf)
227{
228 struct scatterlist *sglist;
229 unsigned int offset = buf->offset;
230 unsigned long pfn = buf->paddr >> PAGE_SHIFT;
231 unsigned int i;
232
233 sglist = vmalloc(buf->npages * sizeof(*sglist));
234 if (sglist == NULL)
235 return -ENOMEM;
236
237 sg_init_table(sglist, buf->npages);
238
239 for (i = 0; i < buf->npages; ++i, ++pfn) {
240 sg_set_page(&sglist[i], pfn_to_page(pfn), PAGE_SIZE - offset,
241 offset);
242 /* PFNMAP buffers will not get DMA-mapped, set the DMA address
243 * manually.
244 */
245 sg_dma_address(&sglist[i]) = (pfn << PAGE_SHIFT) + offset;
246 offset = 0;
247 }
248
249 buf->sglen = buf->npages;
250 buf->sglist = sglist;
251
252 return 0;
253}
254
255/*
256 * isp_video_buffer_cleanup - Release pages for a userspace VMA.
257 *
258 * Release pages locked by a call isp_video_buffer_prepare_user and free the
259 * pages table.
260 */
261static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
262{
263 enum dma_data_direction direction;
264 unsigned int i;
265
266 if (buf->queue->ops->buffer_cleanup)
267 buf->queue->ops->buffer_cleanup(buf);
268
269 if (!(buf->vm_flags & VM_PFNMAP)) {
270 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
271 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
272 dma_unmap_sg(buf->queue->dev, buf->sglist, buf->sglen,
273 direction);
274 }
275
276 vfree(buf->sglist);
277 buf->sglist = NULL;
278 buf->sglen = 0;
279
280 if (buf->pages != NULL) {
281 isp_video_buffer_lock_vma(buf, 0);
282
283 for (i = 0; i < buf->npages; ++i)
284 page_cache_release(buf->pages[i]);
285
286 vfree(buf->pages);
287 buf->pages = NULL;
288 }
289
290 buf->npages = 0;
291 buf->skip_cache = false;
292}
293
294/*
295 * isp_video_buffer_prepare_user - Pin userspace VMA pages to memory.
296 *
297 * This function creates a list of pages for a userspace VMA. The number of
298 * pages is first computed based on the buffer size, and pages are then
299 * retrieved by a call to get_user_pages.
300 *
301 * Pages are pinned to memory by get_user_pages, making them available for DMA
302 * transfers. However, due to memory management optimization, it seems the
303 * get_user_pages doesn't guarantee that the pinned pages will not be written
304 * to swap and removed from the userspace mapping(s). When this happens, a page
305 * fault can be generated when accessing those unmapped pages.
306 *
307 * If the fault is triggered by a page table walk caused by VIPT cache
308 * management operations, the page fault handler might oops if the MM semaphore
309 * is held, as it can't handle kernel page faults in that case. To fix that, a
310 * fixup entry needs to be added to the cache management code, or the userspace
311 * VMA must be locked to avoid removing pages from the userspace mapping in the
312 * first place.
313 *
314 * If the number of pages retrieved is smaller than the number required by the
315 * buffer size, the function returns -EFAULT.
316 */
317static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
318{
319 unsigned long data;
320 unsigned int first;
321 unsigned int last;
322 int ret;
323
324 data = buf->vbuf.m.userptr;
325 first = (data & PAGE_MASK) >> PAGE_SHIFT;
326 last = ((data + buf->vbuf.length - 1) & PAGE_MASK) >> PAGE_SHIFT;
327
328 buf->offset = data & ~PAGE_MASK;
329 buf->npages = last - first + 1;
330 buf->pages = vmalloc(buf->npages * sizeof(buf->pages[0]));
331 if (buf->pages == NULL)
332 return -ENOMEM;
333
334 down_read(&current->mm->mmap_sem);
335 ret = get_user_pages(current, current->mm, data & PAGE_MASK,
336 buf->npages,
337 buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE, 0,
338 buf->pages, NULL);
339 up_read(&current->mm->mmap_sem);
340
341 if (ret != buf->npages) {
342 buf->npages = ret;
343 isp_video_buffer_cleanup(buf);
344 return -EFAULT;
345 }
346
347 ret = isp_video_buffer_lock_vma(buf, 1);
348 if (ret < 0)
349 isp_video_buffer_cleanup(buf);
350
351 return ret;
352}
353
354/*
355 * isp_video_buffer_prepare_pfnmap - Validate a VM_PFNMAP userspace buffer
356 *
357 * Userspace VM_PFNMAP buffers are supported only if they are contiguous in
358 * memory and if they span a single VMA.
359 *
360 * Return 0 if the buffer is valid, or -EFAULT otherwise.
361 */
362static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf)
363{
364 struct vm_area_struct *vma;
365 unsigned long prev_pfn;
366 unsigned long this_pfn;
367 unsigned long start;
368 unsigned long end;
369 dma_addr_t pa;
370 int ret = -EFAULT;
371
372 start = buf->vbuf.m.userptr;
373 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
374
375 buf->offset = start & ~PAGE_MASK;
376 buf->npages = (end >> PAGE_SHIFT) - (start >> PAGE_SHIFT) + 1;
377 buf->pages = NULL;
378
379 down_read(&current->mm->mmap_sem);
380 vma = find_vma(current->mm, start);
381 if (vma == NULL || vma->vm_end < end)
382 goto done;
383
384 for (prev_pfn = 0; start <= end; start += PAGE_SIZE) {
385 ret = follow_pfn(vma, start, &this_pfn);
386 if (ret)
387 goto done;
388
389 if (prev_pfn == 0)
390 pa = this_pfn << PAGE_SHIFT;
391 else if (this_pfn != prev_pfn + 1) {
392 ret = -EFAULT;
393 goto done;
394 }
395
396 prev_pfn = this_pfn;
397 }
398
399 buf->paddr = pa + buf->offset;
400 ret = 0;
401
402done:
403 up_read(&current->mm->mmap_sem);
404 return ret;
405}
406
407/*
408 * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address
409 *
410 * This function locates the VMAs for the buffer's userspace address and checks
411 * that their flags match. The onlflag that we need to care for at the moment is
412 * VM_PFNMAP.
413 *
414 * The buffer vm_flags field is set to the first VMA flags.
415 *
416 * Return -EFAULT if no VMA can be found for part of the buffer, or if the VMAs
417 * have incompatible flags.
418 */
419static int isp_video_buffer_prepare_vm_flags(struct isp_video_buffer *buf)
420{
421 struct vm_area_struct *vma;
422 pgprot_t vm_page_prot;
423 unsigned long start;
424 unsigned long end;
425 int ret = -EFAULT;
426
427 start = buf->vbuf.m.userptr;
428 end = buf->vbuf.m.userptr + buf->vbuf.length - 1;
429
430 down_read(&current->mm->mmap_sem);
431
432 do {
433 vma = find_vma(current->mm, start);
434 if (vma == NULL)
435 goto done;
436
437 if (start == buf->vbuf.m.userptr) {
438 buf->vm_flags = vma->vm_flags;
439 vm_page_prot = vma->vm_page_prot;
440 }
441
442 if ((buf->vm_flags ^ vma->vm_flags) & VM_PFNMAP)
443 goto done;
444
445 if (vm_page_prot != vma->vm_page_prot)
446 goto done;
447
448 start = vma->vm_end + 1;
449 } while (vma->vm_end < end);
450
451 /* Skip cache management to enhance performances for non-cached or
452 * write-combining buffers.
453 */
454 if (vm_page_prot == pgprot_noncached(vm_page_prot) ||
455 vm_page_prot == pgprot_writecombine(vm_page_prot))
456 buf->skip_cache = true;
457
458 ret = 0;
459
460done:
461 up_read(&current->mm->mmap_sem);
462 return ret;
463}
464
465/*
466 * isp_video_buffer_prepare - Make a buffer ready for operation
467 *
468 * Preparing a buffer involves:
469 *
470 * - validating VMAs (userspace buffers only)
471 * - locking pages and VMAs into memory (userspace buffers only)
472 * - building page and scatter-gather lists
473 * - mapping buffers for DMA operation
474 * - performing driver-specific preparation
475 *
476 * The function must be called in userspace context with a valid mm context
477 * (this excludes cleanup paths such as sys_close when the userspace process
478 * segfaults).
479 */
480static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
481{
482 enum dma_data_direction direction;
483 int ret;
484
485 switch (buf->vbuf.memory) {
486 case V4L2_MEMORY_MMAP:
487 ret = isp_video_buffer_sglist_kernel(buf);
488 break;
489
490 case V4L2_MEMORY_USERPTR:
491 ret = isp_video_buffer_prepare_vm_flags(buf);
492 if (ret < 0)
493 return ret;
494
495 if (buf->vm_flags & VM_PFNMAP) {
496 ret = isp_video_buffer_prepare_pfnmap(buf);
497 if (ret < 0)
498 return ret;
499
500 ret = isp_video_buffer_sglist_pfnmap(buf);
501 } else {
502 ret = isp_video_buffer_prepare_user(buf);
503 if (ret < 0)
504 return ret;
505
506 ret = isp_video_buffer_sglist_user(buf);
507 }
508 break;
509
510 default:
511 return -EINVAL;
512 }
513
514 if (ret < 0)
515 goto done;
516
517 if (!(buf->vm_flags & VM_PFNMAP)) {
518 direction = buf->vbuf.type == V4L2_BUF_TYPE_VIDEO_CAPTURE
519 ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
520 ret = dma_map_sg(buf->queue->dev, buf->sglist, buf->sglen,
521 direction);
522 if (ret != buf->sglen) {
523 ret = -EFAULT;
524 goto done;
525 }
526 }
527
528 if (buf->queue->ops->buffer_prepare)
529 ret = buf->queue->ops->buffer_prepare(buf);
530
531done:
532 if (ret < 0) {
533 isp_video_buffer_cleanup(buf);
534 return ret;
535 }
536
537 return ret;
538}
539
540/*
541 * isp_video_queue_query - Query the status of a given buffer
542 *
543 * Locking: must be called with the queue lock held.
544 */
545static void isp_video_buffer_query(struct isp_video_buffer *buf,
546 struct v4l2_buffer *vbuf)
547{
548 memcpy(vbuf, &buf->vbuf, sizeof(*vbuf));
549
550 if (buf->vma_use_count)
551 vbuf->flags |= V4L2_BUF_FLAG_MAPPED;
552
553 switch (buf->state) {
554 case ISP_BUF_STATE_ERROR:
555 vbuf->flags |= V4L2_BUF_FLAG_ERROR;
556 case ISP_BUF_STATE_DONE:
557 vbuf->flags |= V4L2_BUF_FLAG_DONE;
558 case ISP_BUF_STATE_QUEUED:
559 case ISP_BUF_STATE_ACTIVE:
560 vbuf->flags |= V4L2_BUF_FLAG_QUEUED;
561 break;
562 case ISP_BUF_STATE_IDLE:
563 default:
564 break;
565 }
566}
567
568/*
569 * isp_video_buffer_wait - Wait for a buffer to be ready
570 *
571 * In non-blocking mode, return immediately with 0 if the buffer is ready or
572 * -EAGAIN if the buffer is in the QUEUED or ACTIVE state.
573 *
574 * In blocking mode, wait (interruptibly but with no timeout) on the buffer wait
575 * queue using the same condition.
576 */
577static int isp_video_buffer_wait(struct isp_video_buffer *buf, int nonblocking)
578{
579 if (nonblocking) {
580 return (buf->state != ISP_BUF_STATE_QUEUED &&
581 buf->state != ISP_BUF_STATE_ACTIVE)
582 ? 0 : -EAGAIN;
583 }
584
585 return wait_event_interruptible(buf->wait,
586 buf->state != ISP_BUF_STATE_QUEUED &&
587 buf->state != ISP_BUF_STATE_ACTIVE);
588}
589
590/* -----------------------------------------------------------------------------
591 * Queue management
592 */
593
594/*
595 * isp_video_queue_free - Free video buffers memory
596 *
597 * Buffers can only be freed if the queue isn't streaming and if no buffer is
598 * mapped to userspace. Return -EBUSY if those conditions aren't statisfied.
599 *
600 * This function must be called with the queue lock held.
601 */
602static int isp_video_queue_free(struct isp_video_queue *queue)
603{
604 unsigned int i;
605
606 if (queue->streaming)
607 return -EBUSY;
608
609 for (i = 0; i < queue->count; ++i) {
610 if (queue->buffers[i]->vma_use_count != 0)
611 return -EBUSY;
612 }
613
614 for (i = 0; i < queue->count; ++i) {
615 struct isp_video_buffer *buf = queue->buffers[i];
616
617 isp_video_buffer_cleanup(buf);
618
619 vfree(buf->vaddr);
620 buf->vaddr = NULL;
621
622 kfree(buf);
623 queue->buffers[i] = NULL;
624 }
625
626 INIT_LIST_HEAD(&queue->queue);
627 queue->count = 0;
628 return 0;
629}
630
631/*
632 * isp_video_queue_alloc - Allocate video buffers memory
633 *
634 * This function must be called with the queue lock held.
635 */
636static int isp_video_queue_alloc(struct isp_video_queue *queue,
637 unsigned int nbuffers,
638 unsigned int size, enum v4l2_memory memory)
639{
640 struct isp_video_buffer *buf;
641 unsigned int i;
642 void *mem;
643 int ret;
644
645 /* Start by freeing the buffers. */
646 ret = isp_video_queue_free(queue);
647 if (ret < 0)
648 return ret;
649
650 /* Bail out of no buffers should be allocated. */
651 if (nbuffers == 0)
652 return 0;
653
654 /* Initialize the allocated buffers. */
655 for (i = 0; i < nbuffers; ++i) {
656 buf = kzalloc(queue->bufsize, GFP_KERNEL);
657 if (buf == NULL)
658 break;
659
660 if (memory == V4L2_MEMORY_MMAP) {
661 /* Allocate video buffers memory for mmap mode. Align
662 * the size to the page size.
663 */
664 mem = vmalloc_32_user(PAGE_ALIGN(size));
665 if (mem == NULL) {
666 kfree(buf);
667 break;
668 }
669
670 buf->vbuf.m.offset = i * PAGE_ALIGN(size);
671 buf->vaddr = mem;
672 }
673
674 buf->vbuf.index = i;
675 buf->vbuf.length = size;
676 buf->vbuf.type = queue->type;
677 buf->vbuf.field = V4L2_FIELD_NONE;
678 buf->vbuf.memory = memory;
679
680 buf->queue = queue;
681 init_waitqueue_head(&buf->wait);
682
683 queue->buffers[i] = buf;
684 }
685
686 if (i == 0)
687 return -ENOMEM;
688
689 queue->count = i;
690 return nbuffers;
691}
692
693/**
694 * omap3isp_video_queue_cleanup - Clean up the video buffers queue
695 * @queue: Video buffers queue
696 *
697 * Free all allocated resources and clean up the video buffers queue. The queue
698 * must not be busy (no ongoing video stream) and buffers must have been
699 * unmapped.
700 *
701 * Return 0 on success or -EBUSY if the queue is busy or buffers haven't been
702 * unmapped.
703 */
704int omap3isp_video_queue_cleanup(struct isp_video_queue *queue)
705{
706 return isp_video_queue_free(queue);
707}
708
709/**
710 * omap3isp_video_queue_init - Initialize the video buffers queue
711 * @queue: Video buffers queue
712 * @type: V4L2 buffer type (capture or output)
713 * @ops: Driver-specific queue operations
714 * @dev: Device used for DMA operations
715 * @bufsize: Size of the driver-specific buffer structure
716 *
717 * Initialize the video buffers queue with the supplied parameters.
718 *
719 * The queue type must be one of V4L2_BUF_TYPE_VIDEO_CAPTURE or
720 * V4L2_BUF_TYPE_VIDEO_OUTPUT. Other buffer types are not supported yet.
721 *
722 * Buffer objects will be allocated using the given buffer size to allow room
723 * for driver-specific fields. Driver-specific buffer structures must start
724 * with a struct isp_video_buffer field. Drivers with no driver-specific buffer
725 * structure must pass the size of the isp_video_buffer structure in the bufsize
726 * parameter.
727 *
728 * Return 0 on success.
729 */
730int omap3isp_video_queue_init(struct isp_video_queue *queue,
731 enum v4l2_buf_type type,
732 const struct isp_video_queue_operations *ops,
733 struct device *dev, unsigned int bufsize)
734{
735 INIT_LIST_HEAD(&queue->queue);
736 mutex_init(&queue->lock);
737 spin_lock_init(&queue->irqlock);
738
739 queue->type = type;
740 queue->ops = ops;
741 queue->dev = dev;
742 queue->bufsize = bufsize;
743
744 return 0;
745}
746
747/* -----------------------------------------------------------------------------
748 * V4L2 operations
749 */
750
751/**
752 * omap3isp_video_queue_reqbufs - Allocate video buffers memory
753 *
754 * This function is intended to be used as a VIDIOC_REQBUFS ioctl handler. It
755 * allocated video buffer objects and, for MMAP buffers, buffer memory.
756 *
757 * If the number of buffers is 0, all buffers are freed and the function returns
758 * without performing any allocation.
759 *
760 * If the number of buffers is not 0, currently allocated buffers (if any) are
761 * freed and the requested number of buffers are allocated. Depending on
762 * driver-specific requirements and on memory availability, a number of buffer
763 * smaller or bigger than requested can be allocated. This isn't considered as
764 * an error.
765 *
766 * Return 0 on success or one of the following error codes:
767 *
768 * -EINVAL if the buffer type or index are invalid
769 * -EBUSY if the queue is busy (streaming or buffers mapped)
770 * -ENOMEM if the buffers can't be allocated due to an out-of-memory condition
771 */
772int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
773 struct v4l2_requestbuffers *rb)
774{
775 unsigned int nbuffers = rb->count;
776 unsigned int size;
777 int ret;
778
779 if (rb->type != queue->type)
780 return -EINVAL;
781
782 queue->ops->queue_prepare(queue, &nbuffers, &size);
783 if (size == 0)
784 return -EINVAL;
785
786 nbuffers = min_t(unsigned int, nbuffers, ISP_VIDEO_MAX_BUFFERS);
787
788 mutex_lock(&queue->lock);
789
790 ret = isp_video_queue_alloc(queue, nbuffers, size, rb->memory);
791 if (ret < 0)
792 goto done;
793
794 rb->count = ret;
795 ret = 0;
796
797done:
798 mutex_unlock(&queue->lock);
799 return ret;
800}
801
802/**
803 * omap3isp_video_queue_querybuf - Query the status of a buffer in a queue
804 *
805 * This function is intended to be used as a VIDIOC_QUERYBUF ioctl handler. It
806 * returns the status of a given video buffer.
807 *
808 * Return 0 on success or -EINVAL if the buffer type or index are invalid.
809 */
810int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
811 struct v4l2_buffer *vbuf)
812{
813 struct isp_video_buffer *buf;
814 int ret = 0;
815
816 if (vbuf->type != queue->type)
817 return -EINVAL;
818
819 mutex_lock(&queue->lock);
820
821 if (vbuf->index >= queue->count) {
822 ret = -EINVAL;
823 goto done;
824 }
825
826 buf = queue->buffers[vbuf->index];
827 isp_video_buffer_query(buf, vbuf);
828
829done:
830 mutex_unlock(&queue->lock);
831 return ret;
832}
833
834/**
835 * omap3isp_video_queue_qbuf - Queue a buffer
836 *
837 * This function is intended to be used as a VIDIOC_QBUF ioctl handler.
838 *
839 * The v4l2_buffer structure passed from userspace is first sanity tested. If
840 * sane, the buffer is then processed and added to the main queue and, if the
841 * queue is streaming, to the IRQ queue.
842 *
843 * Before being enqueued, USERPTR buffers are checked for address changes. If
844 * the buffer has a different userspace address, the old memory area is unlocked
845 * and the new memory area is locked.
846 */
847int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
848 struct v4l2_buffer *vbuf)
849{
850 struct isp_video_buffer *buf;
851 unsigned long flags;
852 int ret = -EINVAL;
853
854 if (vbuf->type != queue->type)
855 goto done;
856
857 mutex_lock(&queue->lock);
858
859 if (vbuf->index >= queue->count)
860 goto done;
861
862 buf = queue->buffers[vbuf->index];
863
864 if (vbuf->memory != buf->vbuf.memory)
865 goto done;
866
867 if (buf->state != ISP_BUF_STATE_IDLE)
868 goto done;
869
870 if (vbuf->memory == V4L2_MEMORY_USERPTR &&
871 vbuf->m.userptr != buf->vbuf.m.userptr) {
872 isp_video_buffer_cleanup(buf);
873 buf->vbuf.m.userptr = vbuf->m.userptr;
874 buf->prepared = 0;
875 }
876
877 if (!buf->prepared) {
878 ret = isp_video_buffer_prepare(buf);
879 if (ret < 0)
880 goto done;
881 buf->prepared = 1;
882 }
883
884 isp_video_buffer_cache_sync(buf);
885
886 buf->state = ISP_BUF_STATE_QUEUED;
887 list_add_tail(&buf->stream, &queue->queue);
888
889 if (queue->streaming) {
890 spin_lock_irqsave(&queue->irqlock, flags);
891 queue->ops->buffer_queue(buf);
892 spin_unlock_irqrestore(&queue->irqlock, flags);
893 }
894
895 ret = 0;
896
897done:
898 mutex_unlock(&queue->lock);
899 return ret;
900}
901
902/**
903 * omap3isp_video_queue_dqbuf - Dequeue a buffer
904 *
905 * This function is intended to be used as a VIDIOC_DQBUF ioctl handler.
906 *
907 * The v4l2_buffer structure passed from userspace is first sanity tested. If
908 * sane, the buffer is then processed and added to the main queue and, if the
909 * queue is streaming, to the IRQ queue.
910 *
911 * Before being enqueued, USERPTR buffers are checked for address changes. If
912 * the buffer has a different userspace address, the old memory area is unlocked
913 * and the new memory area is locked.
914 */
915int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
916 struct v4l2_buffer *vbuf, int nonblocking)
917{
918 struct isp_video_buffer *buf;
919 int ret;
920
921 if (vbuf->type != queue->type)
922 return -EINVAL;
923
924 mutex_lock(&queue->lock);
925
926 if (list_empty(&queue->queue)) {
927 ret = -EINVAL;
928 goto done;
929 }
930
931 buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
932 ret = isp_video_buffer_wait(buf, nonblocking);
933 if (ret < 0)
934 goto done;
935
936 list_del(&buf->stream);
937
938 isp_video_buffer_query(buf, vbuf);
939 buf->state = ISP_BUF_STATE_IDLE;
940 vbuf->flags &= ~V4L2_BUF_FLAG_QUEUED;
941
942done:
943 mutex_unlock(&queue->lock);
944 return ret;
945}
946
947/**
948 * omap3isp_video_queue_streamon - Start streaming
949 *
950 * This function is intended to be used as a VIDIOC_STREAMON ioctl handler. It
951 * starts streaming on the queue and calls the buffer_queue operation for all
952 * queued buffers.
953 *
954 * Return 0 on success.
955 */
956int omap3isp_video_queue_streamon(struct isp_video_queue *queue)
957{
958 struct isp_video_buffer *buf;
959 unsigned long flags;
960
961 mutex_lock(&queue->lock);
962
963 if (queue->streaming)
964 goto done;
965
966 queue->streaming = 1;
967
968 spin_lock_irqsave(&queue->irqlock, flags);
969 list_for_each_entry(buf, &queue->queue, stream)
970 queue->ops->buffer_queue(buf);
971 spin_unlock_irqrestore(&queue->irqlock, flags);
972
973done:
974 mutex_unlock(&queue->lock);
975 return 0;
976}
977
978/**
979 * omap3isp_video_queue_streamoff - Stop streaming
980 *
981 * This function is intended to be used as a VIDIOC_STREAMOFF ioctl handler. It
982 * stops streaming on the queue and wakes up all the buffers.
983 *
984 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
985 * delayed works before calling this function to make sure no buffer will be
986 * touched by the driver and/or hardware.
987 */
988void omap3isp_video_queue_streamoff(struct isp_video_queue *queue)
989{
990 struct isp_video_buffer *buf;
991 unsigned long flags;
992 unsigned int i;
993
994 mutex_lock(&queue->lock);
995
996 if (!queue->streaming)
997 goto done;
998
999 queue->streaming = 0;
1000
1001 spin_lock_irqsave(&queue->irqlock, flags);
1002 for (i = 0; i < queue->count; ++i) {
1003 buf = queue->buffers[i];
1004
1005 if (buf->state == ISP_BUF_STATE_ACTIVE)
1006 wake_up(&buf->wait);
1007
1008 buf->state = ISP_BUF_STATE_IDLE;
1009 }
1010 spin_unlock_irqrestore(&queue->irqlock, flags);
1011
1012 INIT_LIST_HEAD(&queue->queue);
1013
1014done:
1015 mutex_unlock(&queue->lock);
1016}
1017
1018/**
1019 * omap3isp_video_queue_discard_done - Discard all buffers marked as DONE
1020 *
1021 * This function is intended to be used with suspend/resume operations. It
1022 * discards all 'done' buffers as they would be too old to be requested after
1023 * resume.
1024 *
1025 * Drivers must stop the hardware and synchronize with interrupt handlers and/or
1026 * delayed works before calling this function to make sure no buffer will be
1027 * touched by the driver and/or hardware.
1028 */
1029void omap3isp_video_queue_discard_done(struct isp_video_queue *queue)
1030{
1031 struct isp_video_buffer *buf;
1032 unsigned int i;
1033
1034 mutex_lock(&queue->lock);
1035
1036 if (!queue->streaming)
1037 goto done;
1038
1039 for (i = 0; i < queue->count; ++i) {
1040 buf = queue->buffers[i];
1041
1042 if (buf->state == ISP_BUF_STATE_DONE)
1043 buf->state = ISP_BUF_STATE_ERROR;
1044 }
1045
1046done:
1047 mutex_unlock(&queue->lock);
1048}
1049
1050static void isp_video_queue_vm_open(struct vm_area_struct *vma)
1051{
1052 struct isp_video_buffer *buf = vma->vm_private_data;
1053
1054 buf->vma_use_count++;
1055}
1056
1057static void isp_video_queue_vm_close(struct vm_area_struct *vma)
1058{
1059 struct isp_video_buffer *buf = vma->vm_private_data;
1060
1061 buf->vma_use_count--;
1062}
1063
1064static const struct vm_operations_struct isp_video_queue_vm_ops = {
1065 .open = isp_video_queue_vm_open,
1066 .close = isp_video_queue_vm_close,
1067};
1068
1069/**
1070 * omap3isp_video_queue_mmap - Map buffers to userspace
1071 *
1072 * This function is intended to be used as an mmap() file operation handler. It
1073 * maps a buffer to userspace based on the VMA offset.
1074 *
1075 * Only buffers of memory type MMAP are supported.
1076 */
1077int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
1078 struct vm_area_struct *vma)
1079{
1080 struct isp_video_buffer *uninitialized_var(buf);
1081 unsigned long size;
1082 unsigned int i;
1083 int ret = 0;
1084
1085 mutex_lock(&queue->lock);
1086
1087 for (i = 0; i < queue->count; ++i) {
1088 buf = queue->buffers[i];
1089 if ((buf->vbuf.m.offset >> PAGE_SHIFT) == vma->vm_pgoff)
1090 break;
1091 }
1092
1093 if (i == queue->count) {
1094 ret = -EINVAL;
1095 goto done;
1096 }
1097
1098 size = vma->vm_end - vma->vm_start;
1099
1100 if (buf->vbuf.memory != V4L2_MEMORY_MMAP ||
1101 size != PAGE_ALIGN(buf->vbuf.length)) {
1102 ret = -EINVAL;
1103 goto done;
1104 }
1105
1106 ret = remap_vmalloc_range(vma, buf->vaddr, 0);
1107 if (ret < 0)
1108 goto done;
1109
1110 vma->vm_ops = &isp_video_queue_vm_ops;
1111 vma->vm_private_data = buf;
1112 isp_video_queue_vm_open(vma);
1113
1114done:
1115 mutex_unlock(&queue->lock);
1116 return ret;
1117}
1118
1119/**
1120 * omap3isp_video_queue_poll - Poll video queue state
1121 *
1122 * This function is intended to be used as a poll() file operation handler. It
1123 * polls the state of the video buffer at the front of the queue and returns an
1124 * events mask.
1125 *
1126 * If no buffer is present at the front of the queue, POLLERR is returned.
1127 */
1128unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
1129 struct file *file, poll_table *wait)
1130{
1131 struct isp_video_buffer *buf;
1132 unsigned int mask = 0;
1133
1134 mutex_lock(&queue->lock);
1135 if (list_empty(&queue->queue)) {
1136 mask |= POLLERR;
1137 goto done;
1138 }
1139 buf = list_first_entry(&queue->queue, struct isp_video_buffer, stream);
1140
1141 poll_wait(file, &buf->wait, wait);
1142 if (buf->state == ISP_BUF_STATE_DONE ||
1143 buf->state == ISP_BUF_STATE_ERROR) {
1144 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1145 mask |= POLLIN | POLLRDNORM;
1146 else
1147 mask |= POLLOUT | POLLWRNORM;
1148 }
1149
1150done:
1151 mutex_unlock(&queue->lock);
1152 return mask;
1153}
diff --git a/drivers/media/video/omap3isp/ispqueue.h b/drivers/media/video/omap3isp/ispqueue.h
new file mode 100644
index 000000000000..251de3e1679d
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispqueue.h
@@ -0,0 +1,187 @@
1/*
2 * ispqueue.h
3 *
4 * TI OMAP3 ISP - Video buffers queue handling
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * 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, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef OMAP3_ISP_QUEUE_H
27#define OMAP3_ISP_QUEUE_H
28
29#include <linux/kernel.h>
30#include <linux/list.h>
31#include <linux/mutex.h>
32#include <linux/videodev2.h>
33#include <linux/wait.h>
34
35struct isp_video_queue;
36struct page;
37struct scatterlist;
38
39#define ISP_VIDEO_MAX_BUFFERS 16
40
41/**
42 * enum isp_video_buffer_state - ISP video buffer state
43 * @ISP_BUF_STATE_IDLE: The buffer is under userspace control (dequeued
44 * or not queued yet).
45 * @ISP_BUF_STATE_QUEUED: The buffer has been queued but isn't used by the
46 * device yet.
47 * @ISP_BUF_STATE_ACTIVE: The buffer is in use for an active video transfer.
48 * @ISP_BUF_STATE_ERROR: The device is done with the buffer and an error
49 * occured. For capture device the buffer likely contains corrupted data or
50 * no data at all.
51 * @ISP_BUF_STATE_DONE: The device is done with the buffer and no error occured.
52 * For capture devices the buffer contains valid data.
53 */
54enum isp_video_buffer_state {
55 ISP_BUF_STATE_IDLE,
56 ISP_BUF_STATE_QUEUED,
57 ISP_BUF_STATE_ACTIVE,
58 ISP_BUF_STATE_ERROR,
59 ISP_BUF_STATE_DONE,
60};
61
62/**
63 * struct isp_video_buffer - ISP video buffer
64 * @vma_use_count: Number of times the buffer is mmap'ed to userspace
65 * @stream: List head for insertion into main queue
66 * @queue: ISP buffers queue this buffer belongs to
67 * @prepared: Whether the buffer has been prepared
68 * @skip_cache: Whether to skip cache management operations for this buffer
69 * @vaddr: Memory virtual address (for kernel buffers)
70 * @vm_flags: Buffer VMA flags (for userspace buffers)
71 * @offset: Offset inside the first page (for userspace buffers)
72 * @npages: Number of pages (for userspace buffers)
73 * @pages: Pages table (for userspace non-VM_PFNMAP buffers)
74 * @paddr: Memory physical address (for userspace VM_PFNMAP buffers)
75 * @sglen: Number of elements in the scatter list (for non-VM_PFNMAP buffers)
76 * @sglist: Scatter list (for non-VM_PFNMAP buffers)
77 * @vbuf: V4L2 buffer
78 * @irqlist: List head for insertion into IRQ queue
79 * @state: Current buffer state
80 * @wait: Wait queue to signal buffer completion
81 */
82struct isp_video_buffer {
83 unsigned long vma_use_count;
84 struct list_head stream;
85 struct isp_video_queue *queue;
86 unsigned int prepared:1;
87 bool skip_cache;
88
89 /* For kernel buffers. */
90 void *vaddr;
91
92 /* For userspace buffers. */
93 unsigned long vm_flags;
94 unsigned long offset;
95 unsigned int npages;
96 struct page **pages;
97 dma_addr_t paddr;
98
99 /* For all buffers except VM_PFNMAP. */
100 unsigned int sglen;
101 struct scatterlist *sglist;
102
103 /* Touched by the interrupt handler. */
104 struct v4l2_buffer vbuf;
105 struct list_head irqlist;
106 enum isp_video_buffer_state state;
107 wait_queue_head_t wait;
108};
109
110#define to_isp_video_buffer(vb) container_of(vb, struct isp_video_buffer, vb)
111
112/**
113 * struct isp_video_queue_operations - Driver-specific operations
114 * @queue_prepare: Called before allocating buffers. Drivers should clamp the
115 * number of buffers according to their requirements, and must return the
116 * buffer size in bytes.
117 * @buffer_prepare: Called the first time a buffer is queued, or after changing
118 * the userspace memory address for a USERPTR buffer, with the queue lock
119 * held. Drivers should perform device-specific buffer preparation (such as
120 * mapping the buffer memory in an IOMMU). This operation is optional.
121 * @buffer_queue: Called when a buffer is being added to the queue with the
122 * queue irqlock spinlock held.
123 * @buffer_cleanup: Called before freeing buffers, or before changing the
124 * userspace memory address for a USERPTR buffer, with the queue lock held.
125 * Drivers must perform cleanup operations required to undo the
126 * buffer_prepare call. This operation is optional.
127 */
128struct isp_video_queue_operations {
129 void (*queue_prepare)(struct isp_video_queue *queue,
130 unsigned int *nbuffers, unsigned int *size);
131 int (*buffer_prepare)(struct isp_video_buffer *buf);
132 void (*buffer_queue)(struct isp_video_buffer *buf);
133 void (*buffer_cleanup)(struct isp_video_buffer *buf);
134};
135
136/**
137 * struct isp_video_queue - ISP video buffers queue
138 * @type: Type of video buffers handled by this queue
139 * @ops: Queue operations
140 * @dev: Device used for DMA operations
141 * @bufsize: Size of a driver-specific buffer object
142 * @count: Number of currently allocated buffers
143 * @buffers: ISP video buffers
144 * @lock: Mutex to protect access to the buffers, main queue and state
145 * @irqlock: Spinlock to protect access to the IRQ queue
146 * @streaming: Queue state, indicates whether the queue is streaming
147 * @queue: List of all queued buffers
148 */
149struct isp_video_queue {
150 enum v4l2_buf_type type;
151 const struct isp_video_queue_operations *ops;
152 struct device *dev;
153 unsigned int bufsize;
154
155 unsigned int count;
156 struct isp_video_buffer *buffers[ISP_VIDEO_MAX_BUFFERS];
157 struct mutex lock;
158 spinlock_t irqlock;
159
160 unsigned int streaming:1;
161
162 struct list_head queue;
163};
164
165int omap3isp_video_queue_cleanup(struct isp_video_queue *queue);
166int omap3isp_video_queue_init(struct isp_video_queue *queue,
167 enum v4l2_buf_type type,
168 const struct isp_video_queue_operations *ops,
169 struct device *dev, unsigned int bufsize);
170
171int omap3isp_video_queue_reqbufs(struct isp_video_queue *queue,
172 struct v4l2_requestbuffers *rb);
173int omap3isp_video_queue_querybuf(struct isp_video_queue *queue,
174 struct v4l2_buffer *vbuf);
175int omap3isp_video_queue_qbuf(struct isp_video_queue *queue,
176 struct v4l2_buffer *vbuf);
177int omap3isp_video_queue_dqbuf(struct isp_video_queue *queue,
178 struct v4l2_buffer *vbuf, int nonblocking);
179int omap3isp_video_queue_streamon(struct isp_video_queue *queue);
180void omap3isp_video_queue_streamoff(struct isp_video_queue *queue);
181void omap3isp_video_queue_discard_done(struct isp_video_queue *queue);
182int omap3isp_video_queue_mmap(struct isp_video_queue *queue,
183 struct vm_area_struct *vma);
184unsigned int omap3isp_video_queue_poll(struct isp_video_queue *queue,
185 struct file *file, poll_table *wait);
186
187#endif /* OMAP3_ISP_QUEUE_H */
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/video/omap3isp/ispreg.h
new file mode 100644
index 000000000000..69f6af6f6b9c
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispreg.h
@@ -0,0 +1,1589 @@
1/*
2 * ispreg.h
3 *
4 * TI OMAP3 ISP - Registers definitions
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_REG_H
28#define OMAP3_ISP_REG_H
29
30#include <plat/omap34xx.h>
31
32
33#define CM_CAM_MCLK_HZ 172800000 /* Hz */
34
35/* ISP Submodules offset */
36
37#define OMAP3ISP_REG_BASE OMAP3430_ISP_BASE
38#define OMAP3ISP_REG(offset) (OMAP3ISP_REG_BASE + (offset))
39
40#define OMAP3ISP_CCP2_REG_OFFSET 0x0400
41#define OMAP3ISP_CCP2_REG_BASE (OMAP3ISP_REG_BASE + \
42 OMAP3ISP_CCP2_REG_OFFSET)
43#define OMAP3ISP_CCP2_REG(offset) (OMAP3ISP_CCP2_REG_BASE + (offset))
44
45#define OMAP3ISP_CCDC_REG_OFFSET 0x0600
46#define OMAP3ISP_CCDC_REG_BASE (OMAP3ISP_REG_BASE + \
47 OMAP3ISP_CCDC_REG_OFFSET)
48#define OMAP3ISP_CCDC_REG(offset) (OMAP3ISP_CCDC_REG_BASE + (offset))
49
50#define OMAP3ISP_HIST_REG_OFFSET 0x0A00
51#define OMAP3ISP_HIST_REG_BASE (OMAP3ISP_REG_BASE + \
52 OMAP3ISP_HIST_REG_OFFSET)
53#define OMAP3ISP_HIST_REG(offset) (OMAP3ISP_HIST_REG_BASE + (offset))
54
55#define OMAP3ISP_H3A_REG_OFFSET 0x0C00
56#define OMAP3ISP_H3A_REG_BASE (OMAP3ISP_REG_BASE + \
57 OMAP3ISP_H3A_REG_OFFSET)
58#define OMAP3ISP_H3A_REG(offset) (OMAP3ISP_H3A_REG_BASE + (offset))
59
60#define OMAP3ISP_PREV_REG_OFFSET 0x0E00
61#define OMAP3ISP_PREV_REG_BASE (OMAP3ISP_REG_BASE + \
62 OMAP3ISP_PREV_REG_OFFSET)
63#define OMAP3ISP_PREV_REG(offset) (OMAP3ISP_PREV_REG_BASE + (offset))
64
65#define OMAP3ISP_RESZ_REG_OFFSET 0x1000
66#define OMAP3ISP_RESZ_REG_BASE (OMAP3ISP_REG_BASE + \
67 OMAP3ISP_RESZ_REG_OFFSET)
68#define OMAP3ISP_RESZ_REG(offset) (OMAP3ISP_RESZ_REG_BASE + (offset))
69
70#define OMAP3ISP_SBL_REG_OFFSET 0x1200
71#define OMAP3ISP_SBL_REG_BASE (OMAP3ISP_REG_BASE + \
72 OMAP3ISP_SBL_REG_OFFSET)
73#define OMAP3ISP_SBL_REG(offset) (OMAP3ISP_SBL_REG_BASE + (offset))
74
75#define OMAP3ISP_CSI2A_REGS1_REG_OFFSET 0x1800
76#define OMAP3ISP_CSI2A_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
77 OMAP3ISP_CSI2A_REGS1_REG_OFFSET)
78#define OMAP3ISP_CSI2A_REGS1_REG(offset) \
79 (OMAP3ISP_CSI2A_REGS1_REG_BASE + (offset))
80
81#define OMAP3ISP_CSIPHY2_REG_OFFSET 0x1970
82#define OMAP3ISP_CSIPHY2_REG_BASE (OMAP3ISP_REG_BASE + \
83 OMAP3ISP_CSIPHY2_REG_OFFSET)
84#define OMAP3ISP_CSIPHY2_REG(offset) (OMAP3ISP_CSIPHY2_REG_BASE + (offset))
85
86#define OMAP3ISP_CSI2A_REGS2_REG_OFFSET 0x19C0
87#define OMAP3ISP_CSI2A_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
88 OMAP3ISP_CSI2A_REGS2_REG_OFFSET)
89#define OMAP3ISP_CSI2A_REGS2_REG(offset) \
90 (OMAP3ISP_CSI2A_REGS2_REG_BASE + (offset))
91
92#define OMAP3ISP_CSI2C_REGS1_REG_OFFSET 0x1C00
93#define OMAP3ISP_CSI2C_REGS1_REG_BASE (OMAP3ISP_REG_BASE + \
94 OMAP3ISP_CSI2C_REGS1_REG_OFFSET)
95#define OMAP3ISP_CSI2C_REGS1_REG(offset) \
96 (OMAP3ISP_CSI2C_REGS1_REG_BASE + (offset))
97
98#define OMAP3ISP_CSIPHY1_REG_OFFSET 0x1D70
99#define OMAP3ISP_CSIPHY1_REG_BASE (OMAP3ISP_REG_BASE + \
100 OMAP3ISP_CSIPHY1_REG_OFFSET)
101#define OMAP3ISP_CSIPHY1_REG(offset) (OMAP3ISP_CSIPHY1_REG_BASE + (offset))
102
103#define OMAP3ISP_CSI2C_REGS2_REG_OFFSET 0x1DC0
104#define OMAP3ISP_CSI2C_REGS2_REG_BASE (OMAP3ISP_REG_BASE + \
105 OMAP3ISP_CSI2C_REGS2_REG_OFFSET)
106#define OMAP3ISP_CSI2C_REGS2_REG(offset) \
107 (OMAP3ISP_CSI2C_REGS2_REG_BASE + (offset))
108
109/* ISP module register offset */
110
111#define ISP_REVISION (0x000)
112#define ISP_SYSCONFIG (0x004)
113#define ISP_SYSSTATUS (0x008)
114#define ISP_IRQ0ENABLE (0x00C)
115#define ISP_IRQ0STATUS (0x010)
116#define ISP_IRQ1ENABLE (0x014)
117#define ISP_IRQ1STATUS (0x018)
118#define ISP_TCTRL_GRESET_LENGTH (0x030)
119#define ISP_TCTRL_PSTRB_REPLAY (0x034)
120#define ISP_CTRL (0x040)
121#define ISP_SECURE (0x044)
122#define ISP_TCTRL_CTRL (0x050)
123#define ISP_TCTRL_FRAME (0x054)
124#define ISP_TCTRL_PSTRB_DELAY (0x058)
125#define ISP_TCTRL_STRB_DELAY (0x05C)
126#define ISP_TCTRL_SHUT_DELAY (0x060)
127#define ISP_TCTRL_PSTRB_LENGTH (0x064)
128#define ISP_TCTRL_STRB_LENGTH (0x068)
129#define ISP_TCTRL_SHUT_LENGTH (0x06C)
130#define ISP_PING_PONG_ADDR (0x070)
131#define ISP_PING_PONG_MEM_RANGE (0x074)
132#define ISP_PING_PONG_BUF_SIZE (0x078)
133
134/* CCP2 receiver registers */
135
136#define ISPCCP2_REVISION (0x000)
137#define ISPCCP2_SYSCONFIG (0x004)
138#define ISPCCP2_SYSCONFIG_SOFT_RESET (1 << 1)
139#define ISPCCP2_SYSCONFIG_AUTO_IDLE 0x1
140#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
141#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_FORCE \
142 (0x0 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
143#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_NO \
144 (0x1 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
145#define ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SMART \
146 (0x2 << ISPCCP2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
147#define ISPCCP2_SYSSTATUS (0x008)
148#define ISPCCP2_SYSSTATUS_RESET_DONE (1 << 0)
149#define ISPCCP2_LC01_IRQENABLE (0x00C)
150#define ISPCCP2_LC01_IRQSTATUS (0x010)
151#define ISPCCP2_LC01_IRQSTATUS_LC0_FS_IRQ (1 << 11)
152#define ISPCCP2_LC01_IRQSTATUS_LC0_LE_IRQ (1 << 10)
153#define ISPCCP2_LC01_IRQSTATUS_LC0_LS_IRQ (1 << 9)
154#define ISPCCP2_LC01_IRQSTATUS_LC0_FE_IRQ (1 << 8)
155#define ISPCCP2_LC01_IRQSTATUS_LC0_COUNT_IRQ (1 << 7)
156#define ISPCCP2_LC01_IRQSTATUS_LC0_FIFO_OVF_IRQ (1 << 5)
157#define ISPCCP2_LC01_IRQSTATUS_LC0_CRC_IRQ (1 << 4)
158#define ISPCCP2_LC01_IRQSTATUS_LC0_FSP_IRQ (1 << 3)
159#define ISPCCP2_LC01_IRQSTATUS_LC0_FW_IRQ (1 << 2)
160#define ISPCCP2_LC01_IRQSTATUS_LC0_FSC_IRQ (1 << 1)
161#define ISPCCP2_LC01_IRQSTATUS_LC0_SSC_IRQ (1 << 0)
162
163#define ISPCCP2_LC23_IRQENABLE (0x014)
164#define ISPCCP2_LC23_IRQSTATUS (0x018)
165#define ISPCCP2_LCM_IRQENABLE (0x02C)
166#define ISPCCP2_LCM_IRQSTATUS_EOF_IRQ (1 << 0)
167#define ISPCCP2_LCM_IRQSTATUS_OCPERROR_IRQ (1 << 1)
168#define ISPCCP2_LCM_IRQSTATUS (0x030)
169#define ISPCCP2_CTRL (0x040)
170#define ISPCCP2_CTRL_IF_EN (1 << 0)
171#define ISPCCP2_CTRL_PHY_SEL (1 << 1)
172#define ISPCCP2_CTRL_PHY_SEL_CLOCK (0 << 1)
173#define ISPCCP2_CTRL_PHY_SEL_STROBE (1 << 1)
174#define ISPCCP2_CTRL_PHY_SEL_MASK 0x1
175#define ISPCCP2_CTRL_PHY_SEL_SHIFT 1
176#define ISPCCP2_CTRL_IO_OUT_SEL (1 << 2)
177#define ISPCCP2_CTRL_MODE (1 << 4)
178#define ISPCCP2_CTRL_VP_CLK_FORCE_ON (1 << 9)
179#define ISPCCP2_CTRL_INV (1 << 10)
180#define ISPCCP2_CTRL_INV_MASK 0x1
181#define ISPCCP2_CTRL_INV_SHIFT 10
182#define ISPCCP2_CTRL_VP_ONLY_EN (1 << 11)
183#define ISPCCP2_CTRL_VP_CLK_POL (1 << 12)
184#define ISPCCP2_CTRL_VPCLK_DIV_SHIFT 15
185#define ISPCCP2_CTRL_VPCLK_DIV_MASK 0x1ffff /* [31:15] */
186#define ISPCCP2_CTRL_VP_OUT_CTRL_SHIFT 8 /* 3430 bits */
187#define ISPCCP2_CTRL_VP_OUT_CTRL_MASK 0x3 /* 3430 bits */
188#define ISPCCP2_DBG (0x044)
189#define ISPCCP2_GNQ (0x048)
190#define ISPCCP2_LCx_CTRL(x) ((0x050)+0x30*(x))
191#define ISPCCP2_LCx_CTRL_CHAN_EN (1 << 0)
192#define ISPCCP2_LCx_CTRL_CRC_EN (1 << 19)
193#define ISPCCP2_LCx_CTRL_CRC_MASK 0x1
194#define ISPCCP2_LCx_CTRL_CRC_SHIFT 2
195#define ISPCCP2_LCx_CTRL_CRC_SHIFT_15_0 19
196#define ISPCCP2_LCx_CTRL_REGION_EN (1 << 1)
197#define ISPCCP2_LCx_CTRL_REGION_MASK 0x1
198#define ISPCCP2_LCx_CTRL_REGION_SHIFT 1
199#define ISPCCP2_LCx_CTRL_FORMAT_MASK_15_0 0x3f
200#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT_15_0 0x2
201#define ISPCCP2_LCx_CTRL_FORMAT_MASK 0x1f
202#define ISPCCP2_LCx_CTRL_FORMAT_SHIFT 0x3
203#define ISPCCP2_LCx_CODE(x) ((0x054)+0x30*(x))
204#define ISPCCP2_LCx_STAT_START(x) ((0x058)+0x30*(x))
205#define ISPCCP2_LCx_STAT_SIZE(x) ((0x05C)+0x30*(x))
206#define ISPCCP2_LCx_SOF_ADDR(x) ((0x060)+0x30*(x))
207#define ISPCCP2_LCx_EOF_ADDR(x) ((0x064)+0x30*(x))
208#define ISPCCP2_LCx_DAT_START(x) ((0x068)+0x30*(x))
209#define ISPCCP2_LCx_DAT_SIZE(x) ((0x06C)+0x30*(x))
210#define ISPCCP2_LCx_DAT_MASK 0xFFF
211#define ISPCCP2_LCx_DAT_SHIFT 16
212#define ISPCCP2_LCx_DAT_PING_ADDR(x) ((0x070)+0x30*(x))
213#define ISPCCP2_LCx_DAT_PONG_ADDR(x) ((0x074)+0x30*(x))
214#define ISPCCP2_LCx_DAT_OFST(x) ((0x078)+0x30*(x))
215#define ISPCCP2_LCM_CTRL (0x1D0)
216#define ISPCCP2_LCM_CTRL_CHAN_EN (1 << 0)
217#define ISPCCP2_LCM_CTRL_DST_PORT (1 << 2)
218#define ISPCCP2_LCM_CTRL_DST_PORT_SHIFT 2
219#define ISPCCP2_LCM_CTRL_READ_THROTTLE_SHIFT 3
220#define ISPCCP2_LCM_CTRL_READ_THROTTLE_MASK 0x11
221#define ISPCCP2_LCM_CTRL_BURST_SIZE_SHIFT 5
222#define ISPCCP2_LCM_CTRL_BURST_SIZE_MASK 0x7
223#define ISPCCP2_LCM_CTRL_SRC_FORMAT_SHIFT 16
224#define ISPCCP2_LCM_CTRL_SRC_FORMAT_MASK 0x7
225#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_SHIFT 20
226#define ISPCCP2_LCM_CTRL_SRC_DECOMPR_MASK 0x3
227#define ISPCCP2_LCM_CTRL_SRC_DPCM_PRED (1 << 22)
228#define ISPCCP2_LCM_CTRL_SRC_PACK (1 << 23)
229#define ISPCCP2_LCM_CTRL_DST_FORMAT_SHIFT 24
230#define ISPCCP2_LCM_CTRL_DST_FORMAT_MASK 0x7
231#define ISPCCP2_LCM_VSIZE (0x1D4)
232#define ISPCCP2_LCM_VSIZE_SHIFT 16
233#define ISPCCP2_LCM_HSIZE (0x1D8)
234#define ISPCCP2_LCM_HSIZE_SHIFT 16
235#define ISPCCP2_LCM_PREFETCH (0x1DC)
236#define ISPCCP2_LCM_PREFETCH_SHIFT 3
237#define ISPCCP2_LCM_SRC_ADDR (0x1E0)
238#define ISPCCP2_LCM_SRC_OFST (0x1E4)
239#define ISPCCP2_LCM_DST_ADDR (0x1E8)
240#define ISPCCP2_LCM_DST_OFST (0x1EC)
241
242/* CCDC module register offset */
243
244#define ISPCCDC_PID (0x000)
245#define ISPCCDC_PCR (0x004)
246#define ISPCCDC_SYN_MODE (0x008)
247#define ISPCCDC_HD_VD_WID (0x00C)
248#define ISPCCDC_PIX_LINES (0x010)
249#define ISPCCDC_HORZ_INFO (0x014)
250#define ISPCCDC_VERT_START (0x018)
251#define ISPCCDC_VERT_LINES (0x01C)
252#define ISPCCDC_CULLING (0x020)
253#define ISPCCDC_HSIZE_OFF (0x024)
254#define ISPCCDC_SDOFST (0x028)
255#define ISPCCDC_SDR_ADDR (0x02C)
256#define ISPCCDC_CLAMP (0x030)
257#define ISPCCDC_DCSUB (0x034)
258#define ISPCCDC_COLPTN (0x038)
259#define ISPCCDC_BLKCMP (0x03C)
260#define ISPCCDC_FPC (0x040)
261#define ISPCCDC_FPC_ADDR (0x044)
262#define ISPCCDC_VDINT (0x048)
263#define ISPCCDC_ALAW (0x04C)
264#define ISPCCDC_REC656IF (0x050)
265#define ISPCCDC_CFG (0x054)
266#define ISPCCDC_FMTCFG (0x058)
267#define ISPCCDC_FMT_HORZ (0x05C)
268#define ISPCCDC_FMT_VERT (0x060)
269#define ISPCCDC_FMT_ADDR0 (0x064)
270#define ISPCCDC_FMT_ADDR1 (0x068)
271#define ISPCCDC_FMT_ADDR2 (0x06C)
272#define ISPCCDC_FMT_ADDR3 (0x070)
273#define ISPCCDC_FMT_ADDR4 (0x074)
274#define ISPCCDC_FMT_ADDR5 (0x078)
275#define ISPCCDC_FMT_ADDR6 (0x07C)
276#define ISPCCDC_FMT_ADDR7 (0x080)
277#define ISPCCDC_PRGEVEN0 (0x084)
278#define ISPCCDC_PRGEVEN1 (0x088)
279#define ISPCCDC_PRGODD0 (0x08C)
280#define ISPCCDC_PRGODD1 (0x090)
281#define ISPCCDC_VP_OUT (0x094)
282
283#define ISPCCDC_LSC_CONFIG (0x098)
284#define ISPCCDC_LSC_INITIAL (0x09C)
285#define ISPCCDC_LSC_TABLE_BASE (0x0A0)
286#define ISPCCDC_LSC_TABLE_OFFSET (0x0A4)
287
288/* SBL */
289#define ISPSBL_PCR 0x4
290#define ISPSBL_PCR_H3A_AEAWB_WBL_OVF (1 << 16)
291#define ISPSBL_PCR_H3A_AF_WBL_OVF (1 << 17)
292#define ISPSBL_PCR_RSZ4_WBL_OVF (1 << 18)
293#define ISPSBL_PCR_RSZ3_WBL_OVF (1 << 19)
294#define ISPSBL_PCR_RSZ2_WBL_OVF (1 << 20)
295#define ISPSBL_PCR_RSZ1_WBL_OVF (1 << 21)
296#define ISPSBL_PCR_PRV_WBL_OVF (1 << 22)
297#define ISPSBL_PCR_CCDC_WBL_OVF (1 << 23)
298#define ISPSBL_PCR_CCDCPRV_2_RSZ_OVF (1 << 24)
299#define ISPSBL_PCR_CSIA_WBL_OVF (1 << 25)
300#define ISPSBL_PCR_CSIB_WBL_OVF (1 << 26)
301#define ISPSBL_CCDC_WR_0 (0x028)
302#define ISPSBL_CCDC_WR_0_DATA_READY (1 << 21)
303#define ISPSBL_CCDC_WR_1 (0x02C)
304#define ISPSBL_CCDC_WR_2 (0x030)
305#define ISPSBL_CCDC_WR_3 (0x034)
306
307#define ISPSBL_SDR_REQ_EXP 0xF8
308#define ISPSBL_SDR_REQ_HIST_EXP_SHIFT 0
309#define ISPSBL_SDR_REQ_HIST_EXP_MASK (0x3FF)
310#define ISPSBL_SDR_REQ_RSZ_EXP_SHIFT 10
311#define ISPSBL_SDR_REQ_RSZ_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT)
312#define ISPSBL_SDR_REQ_PRV_EXP_SHIFT 20
313#define ISPSBL_SDR_REQ_PRV_EXP_MASK (0x3FF << ISPSBL_SDR_REQ_PRV_EXP_SHIFT)
314
315/* Histogram registers */
316#define ISPHIST_PID (0x000)
317#define ISPHIST_PCR (0x004)
318#define ISPHIST_CNT (0x008)
319#define ISPHIST_WB_GAIN (0x00C)
320#define ISPHIST_R0_HORZ (0x010)
321#define ISPHIST_R0_VERT (0x014)
322#define ISPHIST_R1_HORZ (0x018)
323#define ISPHIST_R1_VERT (0x01C)
324#define ISPHIST_R2_HORZ (0x020)
325#define ISPHIST_R2_VERT (0x024)
326#define ISPHIST_R3_HORZ (0x028)
327#define ISPHIST_R3_VERT (0x02C)
328#define ISPHIST_ADDR (0x030)
329#define ISPHIST_DATA (0x034)
330#define ISPHIST_RADD (0x038)
331#define ISPHIST_RADD_OFF (0x03C)
332#define ISPHIST_H_V_INFO (0x040)
333
334/* H3A module registers */
335#define ISPH3A_PID (0x000)
336#define ISPH3A_PCR (0x004)
337#define ISPH3A_AEWWIN1 (0x04C)
338#define ISPH3A_AEWINSTART (0x050)
339#define ISPH3A_AEWINBLK (0x054)
340#define ISPH3A_AEWSUBWIN (0x058)
341#define ISPH3A_AEWBUFST (0x05C)
342#define ISPH3A_AFPAX1 (0x008)
343#define ISPH3A_AFPAX2 (0x00C)
344#define ISPH3A_AFPAXSTART (0x010)
345#define ISPH3A_AFIIRSH (0x014)
346#define ISPH3A_AFBUFST (0x018)
347#define ISPH3A_AFCOEF010 (0x01C)
348#define ISPH3A_AFCOEF032 (0x020)
349#define ISPH3A_AFCOEF054 (0x024)
350#define ISPH3A_AFCOEF076 (0x028)
351#define ISPH3A_AFCOEF098 (0x02C)
352#define ISPH3A_AFCOEF0010 (0x030)
353#define ISPH3A_AFCOEF110 (0x034)
354#define ISPH3A_AFCOEF132 (0x038)
355#define ISPH3A_AFCOEF154 (0x03C)
356#define ISPH3A_AFCOEF176 (0x040)
357#define ISPH3A_AFCOEF198 (0x044)
358#define ISPH3A_AFCOEF1010 (0x048)
359
360#define ISPPRV_PCR (0x004)
361#define ISPPRV_HORZ_INFO (0x008)
362#define ISPPRV_VERT_INFO (0x00C)
363#define ISPPRV_RSDR_ADDR (0x010)
364#define ISPPRV_RADR_OFFSET (0x014)
365#define ISPPRV_DSDR_ADDR (0x018)
366#define ISPPRV_DRKF_OFFSET (0x01C)
367#define ISPPRV_WSDR_ADDR (0x020)
368#define ISPPRV_WADD_OFFSET (0x024)
369#define ISPPRV_AVE (0x028)
370#define ISPPRV_HMED (0x02C)
371#define ISPPRV_NF (0x030)
372#define ISPPRV_WB_DGAIN (0x034)
373#define ISPPRV_WBGAIN (0x038)
374#define ISPPRV_WBSEL (0x03C)
375#define ISPPRV_CFA (0x040)
376#define ISPPRV_BLKADJOFF (0x044)
377#define ISPPRV_RGB_MAT1 (0x048)
378#define ISPPRV_RGB_MAT2 (0x04C)
379#define ISPPRV_RGB_MAT3 (0x050)
380#define ISPPRV_RGB_MAT4 (0x054)
381#define ISPPRV_RGB_MAT5 (0x058)
382#define ISPPRV_RGB_OFF1 (0x05C)
383#define ISPPRV_RGB_OFF2 (0x060)
384#define ISPPRV_CSC0 (0x064)
385#define ISPPRV_CSC1 (0x068)
386#define ISPPRV_CSC2 (0x06C)
387#define ISPPRV_CSC_OFFSET (0x070)
388#define ISPPRV_CNT_BRT (0x074)
389#define ISPPRV_CSUP (0x078)
390#define ISPPRV_SETUP_YC (0x07C)
391#define ISPPRV_SET_TBL_ADDR (0x080)
392#define ISPPRV_SET_TBL_DATA (0x084)
393#define ISPPRV_CDC_THR0 (0x090)
394#define ISPPRV_CDC_THR1 (ISPPRV_CDC_THR0 + (0x4))
395#define ISPPRV_CDC_THR2 (ISPPRV_CDC_THR0 + (0x4) * 2)
396#define ISPPRV_CDC_THR3 (ISPPRV_CDC_THR0 + (0x4) * 3)
397
398#define ISPPRV_REDGAMMA_TABLE_ADDR 0x0000
399#define ISPPRV_GREENGAMMA_TABLE_ADDR 0x0400
400#define ISPPRV_BLUEGAMMA_TABLE_ADDR 0x0800
401#define ISPPRV_NF_TABLE_ADDR 0x0C00
402#define ISPPRV_YENH_TABLE_ADDR 0x1000
403#define ISPPRV_CFA_TABLE_ADDR 0x1400
404
405#define ISPPRV_MAXOUTPUT_WIDTH 1280
406#define ISPPRV_MAXOUTPUT_WIDTH_ES2 3300
407#define ISPPRV_MAXOUTPUT_WIDTH_3630 4096
408#define ISPRSZ_MIN_OUTPUT 64
409#define ISPRSZ_MAX_OUTPUT 3312
410
411/* Resizer module register offset */
412#define ISPRSZ_PID (0x000)
413#define ISPRSZ_PCR (0x004)
414#define ISPRSZ_CNT (0x008)
415#define ISPRSZ_OUT_SIZE (0x00C)
416#define ISPRSZ_IN_START (0x010)
417#define ISPRSZ_IN_SIZE (0x014)
418#define ISPRSZ_SDR_INADD (0x018)
419#define ISPRSZ_SDR_INOFF (0x01C)
420#define ISPRSZ_SDR_OUTADD (0x020)
421#define ISPRSZ_SDR_OUTOFF (0x024)
422#define ISPRSZ_HFILT10 (0x028)
423#define ISPRSZ_HFILT32 (0x02C)
424#define ISPRSZ_HFILT54 (0x030)
425#define ISPRSZ_HFILT76 (0x034)
426#define ISPRSZ_HFILT98 (0x038)
427#define ISPRSZ_HFILT1110 (0x03C)
428#define ISPRSZ_HFILT1312 (0x040)
429#define ISPRSZ_HFILT1514 (0x044)
430#define ISPRSZ_HFILT1716 (0x048)
431#define ISPRSZ_HFILT1918 (0x04C)
432#define ISPRSZ_HFILT2120 (0x050)
433#define ISPRSZ_HFILT2322 (0x054)
434#define ISPRSZ_HFILT2524 (0x058)
435#define ISPRSZ_HFILT2726 (0x05C)
436#define ISPRSZ_HFILT2928 (0x060)
437#define ISPRSZ_HFILT3130 (0x064)
438#define ISPRSZ_VFILT10 (0x068)
439#define ISPRSZ_VFILT32 (0x06C)
440#define ISPRSZ_VFILT54 (0x070)
441#define ISPRSZ_VFILT76 (0x074)
442#define ISPRSZ_VFILT98 (0x078)
443#define ISPRSZ_VFILT1110 (0x07C)
444#define ISPRSZ_VFILT1312 (0x080)
445#define ISPRSZ_VFILT1514 (0x084)
446#define ISPRSZ_VFILT1716 (0x088)
447#define ISPRSZ_VFILT1918 (0x08C)
448#define ISPRSZ_VFILT2120 (0x090)
449#define ISPRSZ_VFILT2322 (0x094)
450#define ISPRSZ_VFILT2524 (0x098)
451#define ISPRSZ_VFILT2726 (0x09C)
452#define ISPRSZ_VFILT2928 (0x0A0)
453#define ISPRSZ_VFILT3130 (0x0A4)
454#define ISPRSZ_YENH (0x0A8)
455
456#define ISP_INT_CLR 0xFF113F11
457#define ISPPRV_PCR_EN 1
458#define ISPPRV_PCR_BUSY (1 << 1)
459#define ISPPRV_PCR_SOURCE (1 << 2)
460#define ISPPRV_PCR_ONESHOT (1 << 3)
461#define ISPPRV_PCR_WIDTH (1 << 4)
462#define ISPPRV_PCR_INVALAW (1 << 5)
463#define ISPPRV_PCR_DRKFEN (1 << 6)
464#define ISPPRV_PCR_DRKFCAP (1 << 7)
465#define ISPPRV_PCR_HMEDEN (1 << 8)
466#define ISPPRV_PCR_NFEN (1 << 9)
467#define ISPPRV_PCR_CFAEN (1 << 10)
468#define ISPPRV_PCR_CFAFMT_SHIFT 11
469#define ISPPRV_PCR_CFAFMT_MASK 0x7800
470#define ISPPRV_PCR_CFAFMT_BAYER (0 << 11)
471#define ISPPRV_PCR_CFAFMT_SONYVGA (1 << 11)
472#define ISPPRV_PCR_CFAFMT_RGBFOVEON (2 << 11)
473#define ISPPRV_PCR_CFAFMT_DNSPL (3 << 11)
474#define ISPPRV_PCR_CFAFMT_HONEYCOMB (4 << 11)
475#define ISPPRV_PCR_CFAFMT_RRGGBBFOVEON (5 << 11)
476#define ISPPRV_PCR_YNENHEN (1 << 15)
477#define ISPPRV_PCR_SUPEN (1 << 16)
478#define ISPPRV_PCR_YCPOS_SHIFT 17
479#define ISPPRV_PCR_YCPOS_YCrYCb (0 << 17)
480#define ISPPRV_PCR_YCPOS_YCbYCr (1 << 17)
481#define ISPPRV_PCR_YCPOS_CbYCrY (2 << 17)
482#define ISPPRV_PCR_YCPOS_CrYCbY (3 << 17)
483#define ISPPRV_PCR_RSZPORT (1 << 19)
484#define ISPPRV_PCR_SDRPORT (1 << 20)
485#define ISPPRV_PCR_SCOMP_EN (1 << 21)
486#define ISPPRV_PCR_SCOMP_SFT_SHIFT (22)
487#define ISPPRV_PCR_SCOMP_SFT_MASK (7 << 22)
488#define ISPPRV_PCR_GAMMA_BYPASS (1 << 26)
489#define ISPPRV_PCR_DCOREN (1 << 27)
490#define ISPPRV_PCR_DCCOUP (1 << 28)
491#define ISPPRV_PCR_DRK_FAIL (1 << 31)
492
493#define ISPPRV_HORZ_INFO_EPH_SHIFT 0
494#define ISPPRV_HORZ_INFO_EPH_MASK 0x3fff
495#define ISPPRV_HORZ_INFO_SPH_SHIFT 16
496#define ISPPRV_HORZ_INFO_SPH_MASK 0x3fff0
497
498#define ISPPRV_VERT_INFO_ELV_SHIFT 0
499#define ISPPRV_VERT_INFO_ELV_MASK 0x3fff
500#define ISPPRV_VERT_INFO_SLV_SHIFT 16
501#define ISPPRV_VERT_INFO_SLV_MASK 0x3fff0
502
503#define ISPPRV_AVE_EVENDIST_SHIFT 2
504#define ISPPRV_AVE_EVENDIST_1 0x0
505#define ISPPRV_AVE_EVENDIST_2 0x1
506#define ISPPRV_AVE_EVENDIST_3 0x2
507#define ISPPRV_AVE_EVENDIST_4 0x3
508#define ISPPRV_AVE_ODDDIST_SHIFT 4
509#define ISPPRV_AVE_ODDDIST_1 0x0
510#define ISPPRV_AVE_ODDDIST_2 0x1
511#define ISPPRV_AVE_ODDDIST_3 0x2
512#define ISPPRV_AVE_ODDDIST_4 0x3
513
514#define ISPPRV_HMED_THRESHOLD_SHIFT 0
515#define ISPPRV_HMED_EVENDIST (1 << 8)
516#define ISPPRV_HMED_ODDDIST (1 << 9)
517
518#define ISPPRV_WBGAIN_COEF0_SHIFT 0
519#define ISPPRV_WBGAIN_COEF1_SHIFT 8
520#define ISPPRV_WBGAIN_COEF2_SHIFT 16
521#define ISPPRV_WBGAIN_COEF3_SHIFT 24
522
523#define ISPPRV_WBSEL_COEF0 0x0
524#define ISPPRV_WBSEL_COEF1 0x1
525#define ISPPRV_WBSEL_COEF2 0x2
526#define ISPPRV_WBSEL_COEF3 0x3
527
528#define ISPPRV_WBSEL_N0_0_SHIFT 0
529#define ISPPRV_WBSEL_N0_1_SHIFT 2
530#define ISPPRV_WBSEL_N0_2_SHIFT 4
531#define ISPPRV_WBSEL_N0_3_SHIFT 6
532#define ISPPRV_WBSEL_N1_0_SHIFT 8
533#define ISPPRV_WBSEL_N1_1_SHIFT 10
534#define ISPPRV_WBSEL_N1_2_SHIFT 12
535#define ISPPRV_WBSEL_N1_3_SHIFT 14
536#define ISPPRV_WBSEL_N2_0_SHIFT 16
537#define ISPPRV_WBSEL_N2_1_SHIFT 18
538#define ISPPRV_WBSEL_N2_2_SHIFT 20
539#define ISPPRV_WBSEL_N2_3_SHIFT 22
540#define ISPPRV_WBSEL_N3_0_SHIFT 24
541#define ISPPRV_WBSEL_N3_1_SHIFT 26
542#define ISPPRV_WBSEL_N3_2_SHIFT 28
543#define ISPPRV_WBSEL_N3_3_SHIFT 30
544
545#define ISPPRV_CFA_GRADTH_HOR_SHIFT 0
546#define ISPPRV_CFA_GRADTH_VER_SHIFT 8
547
548#define ISPPRV_BLKADJOFF_B_SHIFT 0
549#define ISPPRV_BLKADJOFF_G_SHIFT 8
550#define ISPPRV_BLKADJOFF_R_SHIFT 16
551
552#define ISPPRV_RGB_MAT1_MTX_RR_SHIFT 0
553#define ISPPRV_RGB_MAT1_MTX_GR_SHIFT 16
554
555#define ISPPRV_RGB_MAT2_MTX_BR_SHIFT 0
556#define ISPPRV_RGB_MAT2_MTX_RG_SHIFT 16
557
558#define ISPPRV_RGB_MAT3_MTX_GG_SHIFT 0
559#define ISPPRV_RGB_MAT3_MTX_BG_SHIFT 16
560
561#define ISPPRV_RGB_MAT4_MTX_RB_SHIFT 0
562#define ISPPRV_RGB_MAT4_MTX_GB_SHIFT 16
563
564#define ISPPRV_RGB_MAT5_MTX_BB_SHIFT 0
565
566#define ISPPRV_RGB_OFF1_MTX_OFFG_SHIFT 0
567#define ISPPRV_RGB_OFF1_MTX_OFFR_SHIFT 16
568
569#define ISPPRV_RGB_OFF2_MTX_OFFB_SHIFT 0
570
571#define ISPPRV_CSC0_RY_SHIFT 0
572#define ISPPRV_CSC0_GY_SHIFT 10
573#define ISPPRV_CSC0_BY_SHIFT 20
574
575#define ISPPRV_CSC1_RCB_SHIFT 0
576#define ISPPRV_CSC1_GCB_SHIFT 10
577#define ISPPRV_CSC1_BCB_SHIFT 20
578
579#define ISPPRV_CSC2_RCR_SHIFT 0
580#define ISPPRV_CSC2_GCR_SHIFT 10
581#define ISPPRV_CSC2_BCR_SHIFT 20
582
583#define ISPPRV_CSC_OFFSET_CR_SHIFT 0
584#define ISPPRV_CSC_OFFSET_CB_SHIFT 8
585#define ISPPRV_CSC_OFFSET_Y_SHIFT 16
586
587#define ISPPRV_CNT_BRT_BRT_SHIFT 0
588#define ISPPRV_CNT_BRT_CNT_SHIFT 8
589
590#define ISPPRV_CONTRAST_MAX 0x10
591#define ISPPRV_CONTRAST_MIN 0xFF
592#define ISPPRV_BRIGHT_MIN 0x00
593#define ISPPRV_BRIGHT_MAX 0xFF
594
595#define ISPPRV_CSUP_CSUPG_SHIFT 0
596#define ISPPRV_CSUP_THRES_SHIFT 8
597#define ISPPRV_CSUP_HPYF_SHIFT 16
598
599#define ISPPRV_SETUP_YC_MINC_SHIFT 0
600#define ISPPRV_SETUP_YC_MAXC_SHIFT 8
601#define ISPPRV_SETUP_YC_MINY_SHIFT 16
602#define ISPPRV_SETUP_YC_MAXY_SHIFT 24
603#define ISPPRV_YC_MAX 0xFF
604#define ISPPRV_YC_MIN 0x0
605
606/* Define bit fields within selected registers */
607#define ISP_REVISION_SHIFT 0
608
609#define ISP_SYSCONFIG_AUTOIDLE (1 << 0)
610#define ISP_SYSCONFIG_SOFTRESET (1 << 1)
611#define ISP_SYSCONFIG_MIDLEMODE_SHIFT 12
612#define ISP_SYSCONFIG_MIDLEMODE_FORCESTANDBY 0x0
613#define ISP_SYSCONFIG_MIDLEMODE_NOSTANBY 0x1
614#define ISP_SYSCONFIG_MIDLEMODE_SMARTSTANDBY 0x2
615
616#define ISP_SYSSTATUS_RESETDONE 0
617
618#define IRQ0ENABLE_CSIA_IRQ (1 << 0)
619#define IRQ0ENABLE_CSIC_IRQ (1 << 1)
620#define IRQ0ENABLE_CCP2_LCM_IRQ (1 << 3)
621#define IRQ0ENABLE_CCP2_LC0_IRQ (1 << 4)
622#define IRQ0ENABLE_CCP2_LC1_IRQ (1 << 5)
623#define IRQ0ENABLE_CCP2_LC2_IRQ (1 << 6)
624#define IRQ0ENABLE_CCP2_LC3_IRQ (1 << 7)
625#define IRQ0ENABLE_CSIB_IRQ (IRQ0ENABLE_CCP2_LCM_IRQ | \
626 IRQ0ENABLE_CCP2_LC0_IRQ | \
627 IRQ0ENABLE_CCP2_LC1_IRQ | \
628 IRQ0ENABLE_CCP2_LC2_IRQ | \
629 IRQ0ENABLE_CCP2_LC3_IRQ)
630
631#define IRQ0ENABLE_CCDC_VD0_IRQ (1 << 8)
632#define IRQ0ENABLE_CCDC_VD1_IRQ (1 << 9)
633#define IRQ0ENABLE_CCDC_VD2_IRQ (1 << 10)
634#define IRQ0ENABLE_CCDC_ERR_IRQ (1 << 11)
635#define IRQ0ENABLE_H3A_AF_DONE_IRQ (1 << 12)
636#define IRQ0ENABLE_H3A_AWB_DONE_IRQ (1 << 13)
637#define IRQ0ENABLE_HIST_DONE_IRQ (1 << 16)
638#define IRQ0ENABLE_CCDC_LSC_DONE_IRQ (1 << 17)
639#define IRQ0ENABLE_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
640#define IRQ0ENABLE_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
641#define IRQ0ENABLE_PRV_DONE_IRQ (1 << 20)
642#define IRQ0ENABLE_RSZ_DONE_IRQ (1 << 24)
643#define IRQ0ENABLE_OVF_IRQ (1 << 25)
644#define IRQ0ENABLE_PING_IRQ (1 << 26)
645#define IRQ0ENABLE_PONG_IRQ (1 << 27)
646#define IRQ0ENABLE_MMU_ERR_IRQ (1 << 28)
647#define IRQ0ENABLE_OCP_ERR_IRQ (1 << 29)
648#define IRQ0ENABLE_SEC_ERR_IRQ (1 << 30)
649#define IRQ0ENABLE_HS_VS_IRQ (1 << 31)
650
651#define IRQ0STATUS_CSIA_IRQ (1 << 0)
652#define IRQ0STATUS_CSI2C_IRQ (1 << 1)
653#define IRQ0STATUS_CCP2_LCM_IRQ (1 << 3)
654#define IRQ0STATUS_CCP2_LC0_IRQ (1 << 4)
655#define IRQ0STATUS_CSIB_IRQ (IRQ0STATUS_CCP2_LCM_IRQ | \
656 IRQ0STATUS_CCP2_LC0_IRQ)
657
658#define IRQ0STATUS_CSIB_LC1_IRQ (1 << 5)
659#define IRQ0STATUS_CSIB_LC2_IRQ (1 << 6)
660#define IRQ0STATUS_CSIB_LC3_IRQ (1 << 7)
661#define IRQ0STATUS_CCDC_VD0_IRQ (1 << 8)
662#define IRQ0STATUS_CCDC_VD1_IRQ (1 << 9)
663#define IRQ0STATUS_CCDC_VD2_IRQ (1 << 10)
664#define IRQ0STATUS_CCDC_ERR_IRQ (1 << 11)
665#define IRQ0STATUS_H3A_AF_DONE_IRQ (1 << 12)
666#define IRQ0STATUS_H3A_AWB_DONE_IRQ (1 << 13)
667#define IRQ0STATUS_HIST_DONE_IRQ (1 << 16)
668#define IRQ0STATUS_CCDC_LSC_DONE_IRQ (1 << 17)
669#define IRQ0STATUS_CCDC_LSC_PREF_COMP_IRQ (1 << 18)
670#define IRQ0STATUS_CCDC_LSC_PREF_ERR_IRQ (1 << 19)
671#define IRQ0STATUS_PRV_DONE_IRQ (1 << 20)
672#define IRQ0STATUS_RSZ_DONE_IRQ (1 << 24)
673#define IRQ0STATUS_OVF_IRQ (1 << 25)
674#define IRQ0STATUS_PING_IRQ (1 << 26)
675#define IRQ0STATUS_PONG_IRQ (1 << 27)
676#define IRQ0STATUS_MMU_ERR_IRQ (1 << 28)
677#define IRQ0STATUS_OCP_ERR_IRQ (1 << 29)
678#define IRQ0STATUS_SEC_ERR_IRQ (1 << 30)
679#define IRQ0STATUS_HS_VS_IRQ (1 << 31)
680
681#define TCTRL_GRESET_LEN 0
682
683#define TCTRL_PSTRB_REPLAY_DELAY 0
684#define TCTRL_PSTRB_REPLAY_COUNTER_SHIFT 25
685
686#define ISPCTRL_PAR_SER_CLK_SEL_PARALLEL 0x0
687#define ISPCTRL_PAR_SER_CLK_SEL_CSIA 0x1
688#define ISPCTRL_PAR_SER_CLK_SEL_CSIB 0x2
689#define ISPCTRL_PAR_SER_CLK_SEL_CSIC 0x3
690#define ISPCTRL_PAR_SER_CLK_SEL_MASK 0x3
691
692#define ISPCTRL_PAR_BRIDGE_SHIFT 2
693#define ISPCTRL_PAR_BRIDGE_DISABLE (0x0 << 2)
694#define ISPCTRL_PAR_BRIDGE_LENDIAN (0x2 << 2)
695#define ISPCTRL_PAR_BRIDGE_BENDIAN (0x3 << 2)
696#define ISPCTRL_PAR_BRIDGE_MASK (0x3 << 2)
697
698#define ISPCTRL_PAR_CLK_POL_SHIFT 4
699#define ISPCTRL_PAR_CLK_POL_INV (1 << 4)
700#define ISPCTRL_PING_PONG_EN (1 << 5)
701#define ISPCTRL_SHIFT_SHIFT 6
702#define ISPCTRL_SHIFT_0 (0x0 << 6)
703#define ISPCTRL_SHIFT_2 (0x1 << 6)
704#define ISPCTRL_SHIFT_4 (0x2 << 6)
705#define ISPCTRL_SHIFT_MASK (0x3 << 6)
706
707#define ISPCTRL_CCDC_CLK_EN (1 << 8)
708#define ISPCTRL_SCMP_CLK_EN (1 << 9)
709#define ISPCTRL_H3A_CLK_EN (1 << 10)
710#define ISPCTRL_HIST_CLK_EN (1 << 11)
711#define ISPCTRL_PREV_CLK_EN (1 << 12)
712#define ISPCTRL_RSZ_CLK_EN (1 << 13)
713#define ISPCTRL_SYNC_DETECT_SHIFT 14
714#define ISPCTRL_SYNC_DETECT_HSFALL (0x0 << ISPCTRL_SYNC_DETECT_SHIFT)
715#define ISPCTRL_SYNC_DETECT_HSRISE (0x1 << ISPCTRL_SYNC_DETECT_SHIFT)
716#define ISPCTRL_SYNC_DETECT_VSFALL (0x2 << ISPCTRL_SYNC_DETECT_SHIFT)
717#define ISPCTRL_SYNC_DETECT_VSRISE (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
718#define ISPCTRL_SYNC_DETECT_MASK (0x3 << ISPCTRL_SYNC_DETECT_SHIFT)
719
720#define ISPCTRL_CCDC_RAM_EN (1 << 16)
721#define ISPCTRL_PREV_RAM_EN (1 << 17)
722#define ISPCTRL_SBL_RD_RAM_EN (1 << 18)
723#define ISPCTRL_SBL_WR1_RAM_EN (1 << 19)
724#define ISPCTRL_SBL_WR0_RAM_EN (1 << 20)
725#define ISPCTRL_SBL_AUTOIDLE (1 << 21)
726#define ISPCTRL_SBL_SHARED_WPORTC (1 << 26)
727#define ISPCTRL_SBL_SHARED_RPORTA (1 << 27)
728#define ISPCTRL_SBL_SHARED_RPORTB (1 << 28)
729#define ISPCTRL_JPEG_FLUSH (1 << 30)
730#define ISPCTRL_CCDC_FLUSH (1 << 31)
731
732#define ISPSECURE_SECUREMODE 0
733
734#define ISPTCTRL_CTRL_DIV_LOW 0x0
735#define ISPTCTRL_CTRL_DIV_HIGH 0x1
736#define ISPTCTRL_CTRL_DIV_BYPASS 0x1F
737
738#define ISPTCTRL_CTRL_DIVA_SHIFT 0
739#define ISPTCTRL_CTRL_DIVA_MASK (0x1F << ISPTCTRL_CTRL_DIVA_SHIFT)
740
741#define ISPTCTRL_CTRL_DIVB_SHIFT 5
742#define ISPTCTRL_CTRL_DIVB_MASK (0x1F << ISPTCTRL_CTRL_DIVB_SHIFT)
743
744#define ISPTCTRL_CTRL_DIVC_SHIFT 10
745#define ISPTCTRL_CTRL_DIVC_NOCLOCK (0x0 << 10)
746
747#define ISPTCTRL_CTRL_SHUTEN (1 << 21)
748#define ISPTCTRL_CTRL_PSTRBEN (1 << 22)
749#define ISPTCTRL_CTRL_STRBEN (1 << 23)
750#define ISPTCTRL_CTRL_SHUTPOL (1 << 24)
751#define ISPTCTRL_CTRL_STRBPSTRBPOL (1 << 26)
752
753#define ISPTCTRL_CTRL_INSEL_SHIFT 27
754#define ISPTCTRL_CTRL_INSEL_PARALLEL (0x0 << 27)
755#define ISPTCTRL_CTRL_INSEL_CSIA (0x1 << 27)
756#define ISPTCTRL_CTRL_INSEL_CSIB (0x2 << 27)
757
758#define ISPTCTRL_CTRL_GRESETEn (1 << 29)
759#define ISPTCTRL_CTRL_GRESETPOL (1 << 30)
760#define ISPTCTRL_CTRL_GRESETDIR (1 << 31)
761
762#define ISPTCTRL_FRAME_SHUT_SHIFT 0
763#define ISPTCTRL_FRAME_PSTRB_SHIFT 6
764#define ISPTCTRL_FRAME_STRB_SHIFT 12
765
766#define ISPCCDC_PID_PREV_SHIFT 0
767#define ISPCCDC_PID_CID_SHIFT 8
768#define ISPCCDC_PID_TID_SHIFT 16
769
770#define ISPCCDC_PCR_EN 1
771#define ISPCCDC_PCR_BUSY (1 << 1)
772
773#define ISPCCDC_SYN_MODE_VDHDOUT 0x1
774#define ISPCCDC_SYN_MODE_FLDOUT (1 << 1)
775#define ISPCCDC_SYN_MODE_VDPOL (1 << 2)
776#define ISPCCDC_SYN_MODE_HDPOL (1 << 3)
777#define ISPCCDC_SYN_MODE_FLDPOL (1 << 4)
778#define ISPCCDC_SYN_MODE_EXWEN (1 << 5)
779#define ISPCCDC_SYN_MODE_DATAPOL (1 << 6)
780#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7)
781#define ISPCCDC_SYN_MODE_DATSIZ_MASK (0x7 << 8)
782#define ISPCCDC_SYN_MODE_DATSIZ_8_16 (0x0 << 8)
783#define ISPCCDC_SYN_MODE_DATSIZ_12 (0x4 << 8)
784#define ISPCCDC_SYN_MODE_DATSIZ_11 (0x5 << 8)
785#define ISPCCDC_SYN_MODE_DATSIZ_10 (0x6 << 8)
786#define ISPCCDC_SYN_MODE_DATSIZ_8 (0x7 << 8)
787#define ISPCCDC_SYN_MODE_PACK8 (1 << 11)
788#define ISPCCDC_SYN_MODE_INPMOD_MASK (3 << 12)
789#define ISPCCDC_SYN_MODE_INPMOD_RAW (0 << 12)
790#define ISPCCDC_SYN_MODE_INPMOD_YCBCR16 (1 << 12)
791#define ISPCCDC_SYN_MODE_INPMOD_YCBCR8 (2 << 12)
792#define ISPCCDC_SYN_MODE_LPF (1 << 14)
793#define ISPCCDC_SYN_MODE_FLDSTAT (1 << 15)
794#define ISPCCDC_SYN_MODE_VDHDEN (1 << 16)
795#define ISPCCDC_SYN_MODE_WEN (1 << 17)
796#define ISPCCDC_SYN_MODE_VP2SDR (1 << 18)
797#define ISPCCDC_SYN_MODE_SDR2RSZ (1 << 19)
798
799#define ISPCCDC_HD_VD_WID_VDW_SHIFT 0
800#define ISPCCDC_HD_VD_WID_HDW_SHIFT 16
801
802#define ISPCCDC_PIX_LINES_HLPRF_SHIFT 0
803#define ISPCCDC_PIX_LINES_PPLN_SHIFT 16
804
805#define ISPCCDC_HORZ_INFO_NPH_SHIFT 0
806#define ISPCCDC_HORZ_INFO_NPH_MASK 0x00007fff
807#define ISPCCDC_HORZ_INFO_SPH_SHIFT 16
808#define ISPCCDC_HORZ_INFO_SPH_MASK 0x7fff0000
809
810#define ISPCCDC_VERT_START_SLV1_SHIFT 0
811#define ISPCCDC_VERT_START_SLV0_SHIFT 16
812#define ISPCCDC_VERT_START_SLV0_MASK 0x7fff0000
813
814#define ISPCCDC_VERT_LINES_NLV_SHIFT 0
815#define ISPCCDC_VERT_LINES_NLV_MASK 0x00007fff
816
817#define ISPCCDC_CULLING_CULV_SHIFT 0
818#define ISPCCDC_CULLING_CULHODD_SHIFT 16
819#define ISPCCDC_CULLING_CULHEVN_SHIFT 24
820
821#define ISPCCDC_HSIZE_OFF_SHIFT 0
822
823#define ISPCCDC_SDOFST_FINV (1 << 14)
824#define ISPCCDC_SDOFST_FOFST_1L 0
825#define ISPCCDC_SDOFST_FOFST_4L (3 << 12)
826#define ISPCCDC_SDOFST_LOFST3_SHIFT 0
827#define ISPCCDC_SDOFST_LOFST2_SHIFT 3
828#define ISPCCDC_SDOFST_LOFST1_SHIFT 6
829#define ISPCCDC_SDOFST_LOFST0_SHIFT 9
830#define EVENEVEN 1
831#define ODDEVEN 2
832#define EVENODD 3
833#define ODDODD 4
834
835#define ISPCCDC_CLAMP_OBGAIN_SHIFT 0
836#define ISPCCDC_CLAMP_OBST_SHIFT 10
837#define ISPCCDC_CLAMP_OBSLN_SHIFT 25
838#define ISPCCDC_CLAMP_OBSLEN_SHIFT 28
839#define ISPCCDC_CLAMP_CLAMPEN (1 << 31)
840
841#define ISPCCDC_COLPTN_R_Ye 0x0
842#define ISPCCDC_COLPTN_Gr_Cy 0x1
843#define ISPCCDC_COLPTN_Gb_G 0x2
844#define ISPCCDC_COLPTN_B_Mg 0x3
845#define ISPCCDC_COLPTN_CP0PLC0_SHIFT 0
846#define ISPCCDC_COLPTN_CP0PLC1_SHIFT 2
847#define ISPCCDC_COLPTN_CP0PLC2_SHIFT 4
848#define ISPCCDC_COLPTN_CP0PLC3_SHIFT 6
849#define ISPCCDC_COLPTN_CP1PLC0_SHIFT 8
850#define ISPCCDC_COLPTN_CP1PLC1_SHIFT 10
851#define ISPCCDC_COLPTN_CP1PLC2_SHIFT 12
852#define ISPCCDC_COLPTN_CP1PLC3_SHIFT 14
853#define ISPCCDC_COLPTN_CP2PLC0_SHIFT 16
854#define ISPCCDC_COLPTN_CP2PLC1_SHIFT 18
855#define ISPCCDC_COLPTN_CP2PLC2_SHIFT 20
856#define ISPCCDC_COLPTN_CP2PLC3_SHIFT 22
857#define ISPCCDC_COLPTN_CP3PLC0_SHIFT 24
858#define ISPCCDC_COLPTN_CP3PLC1_SHIFT 26
859#define ISPCCDC_COLPTN_CP3PLC2_SHIFT 28
860#define ISPCCDC_COLPTN_CP3PLC3_SHIFT 30
861
862#define ISPCCDC_BLKCMP_B_MG_SHIFT 0
863#define ISPCCDC_BLKCMP_GB_G_SHIFT 8
864#define ISPCCDC_BLKCMP_GR_CY_SHIFT 16
865#define ISPCCDC_BLKCMP_R_YE_SHIFT 24
866
867#define ISPCCDC_FPC_FPNUM_SHIFT 0
868#define ISPCCDC_FPC_FPCEN (1 << 15)
869#define ISPCCDC_FPC_FPERR (1 << 16)
870
871#define ISPCCDC_VDINT_1_SHIFT 0
872#define ISPCCDC_VDINT_1_MASK 0x00007fff
873#define ISPCCDC_VDINT_0_SHIFT 16
874#define ISPCCDC_VDINT_0_MASK 0x7fff0000
875
876#define ISPCCDC_ALAW_GWDI_12_3 (0x3 << 0)
877#define ISPCCDC_ALAW_GWDI_11_2 (0x4 << 0)
878#define ISPCCDC_ALAW_GWDI_10_1 (0x5 << 0)
879#define ISPCCDC_ALAW_GWDI_9_0 (0x6 << 0)
880#define ISPCCDC_ALAW_CCDTBL (1 << 3)
881
882#define ISPCCDC_REC656IF_R656ON 1
883#define ISPCCDC_REC656IF_ECCFVH (1 << 1)
884
885#define ISPCCDC_CFG_BW656 (1 << 5)
886#define ISPCCDC_CFG_FIDMD_SHIFT 6
887#define ISPCCDC_CFG_WENLOG (1 << 8)
888#define ISPCCDC_CFG_WENLOG_AND (0 << 8)
889#define ISPCCDC_CFG_WENLOG_OR (1 << 8)
890#define ISPCCDC_CFG_Y8POS (1 << 11)
891#define ISPCCDC_CFG_BSWD (1 << 12)
892#define ISPCCDC_CFG_MSBINVI (1 << 13)
893#define ISPCCDC_CFG_VDLC (1 << 15)
894
895#define ISPCCDC_FMTCFG_FMTEN 0x1
896#define ISPCCDC_FMTCFG_LNALT (1 << 1)
897#define ISPCCDC_FMTCFG_LNUM_SHIFT 2
898#define ISPCCDC_FMTCFG_PLEN_ODD_SHIFT 4
899#define ISPCCDC_FMTCFG_PLEN_EVEN_SHIFT 8
900#define ISPCCDC_FMTCFG_VPIN_MASK 0x00007000
901#define ISPCCDC_FMTCFG_VPIN_12_3 (0x3 << 12)
902#define ISPCCDC_FMTCFG_VPIN_11_2 (0x4 << 12)
903#define ISPCCDC_FMTCFG_VPIN_10_1 (0x5 << 12)
904#define ISPCCDC_FMTCFG_VPIN_9_0 (0x6 << 12)
905#define ISPCCDC_FMTCFG_VPEN (1 << 15)
906
907#define ISPCCDC_FMTCFG_VPIF_FRQ_MASK 0x003f0000
908#define ISPCCDC_FMTCFG_VPIF_FRQ_SHIFT 16
909#define ISPCCDC_FMTCFG_VPIF_FRQ_BY2 (0x0 << 16)
910#define ISPCCDC_FMTCFG_VPIF_FRQ_BY3 (0x1 << 16)
911#define ISPCCDC_FMTCFG_VPIF_FRQ_BY4 (0x2 << 16)
912#define ISPCCDC_FMTCFG_VPIF_FRQ_BY5 (0x3 << 16)
913#define ISPCCDC_FMTCFG_VPIF_FRQ_BY6 (0x4 << 16)
914
915#define ISPCCDC_FMT_HORZ_FMTLNH_SHIFT 0
916#define ISPCCDC_FMT_HORZ_FMTSPH_SHIFT 16
917
918#define ISPCCDC_FMT_VERT_FMTLNV_SHIFT 0
919#define ISPCCDC_FMT_VERT_FMTSLV_SHIFT 16
920
921#define ISPCCDC_FMT_HORZ_FMTSPH_MASK 0x1fff0000
922#define ISPCCDC_FMT_HORZ_FMTLNH_MASK 0x00001fff
923
924#define ISPCCDC_FMT_VERT_FMTSLV_MASK 0x1fff0000
925#define ISPCCDC_FMT_VERT_FMTLNV_MASK 0x00001fff
926
927#define ISPCCDC_VP_OUT_HORZ_ST_SHIFT 0
928#define ISPCCDC_VP_OUT_HORZ_NUM_SHIFT 4
929#define ISPCCDC_VP_OUT_VERT_NUM_SHIFT 17
930
931#define ISPRSZ_PID_PREV_SHIFT 0
932#define ISPRSZ_PID_CID_SHIFT 8
933#define ISPRSZ_PID_TID_SHIFT 16
934
935#define ISPRSZ_PCR_ENABLE (1 << 0)
936#define ISPRSZ_PCR_BUSY (1 << 1)
937#define ISPRSZ_PCR_ONESHOT (1 << 2)
938
939#define ISPRSZ_CNT_HRSZ_SHIFT 0
940#define ISPRSZ_CNT_HRSZ_MASK \
941 (0x3FF << ISPRSZ_CNT_HRSZ_SHIFT)
942#define ISPRSZ_CNT_VRSZ_SHIFT 10
943#define ISPRSZ_CNT_VRSZ_MASK \
944 (0x3FF << ISPRSZ_CNT_VRSZ_SHIFT)
945#define ISPRSZ_CNT_HSTPH_SHIFT 20
946#define ISPRSZ_CNT_HSTPH_MASK (0x7 << ISPRSZ_CNT_HSTPH_SHIFT)
947#define ISPRSZ_CNT_VSTPH_SHIFT 23
948#define ISPRSZ_CNT_VSTPH_MASK (0x7 << ISPRSZ_CNT_VSTPH_SHIFT)
949#define ISPRSZ_CNT_YCPOS (1 << 26)
950#define ISPRSZ_CNT_INPTYP (1 << 27)
951#define ISPRSZ_CNT_INPSRC (1 << 28)
952#define ISPRSZ_CNT_CBILIN (1 << 29)
953
954#define ISPRSZ_OUT_SIZE_HORZ_SHIFT 0
955#define ISPRSZ_OUT_SIZE_HORZ_MASK \
956 (0xFFF << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
957#define ISPRSZ_OUT_SIZE_VERT_SHIFT 16
958#define ISPRSZ_OUT_SIZE_VERT_MASK \
959 (0xFFF << ISPRSZ_OUT_SIZE_VERT_SHIFT)
960
961#define ISPRSZ_IN_START_HORZ_ST_SHIFT 0
962#define ISPRSZ_IN_START_HORZ_ST_MASK \
963 (0x1FFF << ISPRSZ_IN_START_HORZ_ST_SHIFT)
964#define ISPRSZ_IN_START_VERT_ST_SHIFT 16
965#define ISPRSZ_IN_START_VERT_ST_MASK \
966 (0x1FFF << ISPRSZ_IN_START_VERT_ST_SHIFT)
967
968#define ISPRSZ_IN_SIZE_HORZ_SHIFT 0
969#define ISPRSZ_IN_SIZE_HORZ_MASK \
970 (0x1FFF << ISPRSZ_IN_SIZE_HORZ_SHIFT)
971#define ISPRSZ_IN_SIZE_VERT_SHIFT 16
972#define ISPRSZ_IN_SIZE_VERT_MASK \
973 (0x1FFF << ISPRSZ_IN_SIZE_VERT_SHIFT)
974
975#define ISPRSZ_SDR_INADD_ADDR_SHIFT 0
976#define ISPRSZ_SDR_INADD_ADDR_MASK 0xFFFFFFFF
977
978#define ISPRSZ_SDR_INOFF_OFFSET_SHIFT 0
979#define ISPRSZ_SDR_INOFF_OFFSET_MASK \
980 (0xFFFF << ISPRSZ_SDR_INOFF_OFFSET_SHIFT)
981
982#define ISPRSZ_SDR_OUTADD_ADDR_SHIFT 0
983#define ISPRSZ_SDR_OUTADD_ADDR_MASK 0xFFFFFFFF
984
985
986#define ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT 0
987#define ISPRSZ_SDR_OUTOFF_OFFSET_MASK \
988 (0xFFFF << ISPRSZ_SDR_OUTOFF_OFFSET_SHIFT)
989
990#define ISPRSZ_HFILT_COEF0_SHIFT 0
991#define ISPRSZ_HFILT_COEF0_MASK \
992 (0x3FF << ISPRSZ_HFILT_COEF0_SHIFT)
993#define ISPRSZ_HFILT_COEF1_SHIFT 16
994#define ISPRSZ_HFILT_COEF1_MASK \
995 (0x3FF << ISPRSZ_HFILT_COEF1_SHIFT)
996
997#define ISPRSZ_HFILT32_COEF2_SHIFT 0
998#define ISPRSZ_HFILT32_COEF2_MASK 0x3FF
999#define ISPRSZ_HFILT32_COEF3_SHIFT 16
1000#define ISPRSZ_HFILT32_COEF3_MASK 0x3FF0000
1001
1002#define ISPRSZ_HFILT54_COEF4_SHIFT 0
1003#define ISPRSZ_HFILT54_COEF4_MASK 0x3FF
1004#define ISPRSZ_HFILT54_COEF5_SHIFT 16
1005#define ISPRSZ_HFILT54_COEF5_MASK 0x3FF0000
1006
1007#define ISPRSZ_HFILT76_COEFF6_SHIFT 0
1008#define ISPRSZ_HFILT76_COEFF6_MASK 0x3FF
1009#define ISPRSZ_HFILT76_COEFF7_SHIFT 16
1010#define ISPRSZ_HFILT76_COEFF7_MASK 0x3FF0000
1011
1012#define ISPRSZ_HFILT98_COEFF8_SHIFT 0
1013#define ISPRSZ_HFILT98_COEFF8_MASK 0x3FF
1014#define ISPRSZ_HFILT98_COEFF9_SHIFT 16
1015#define ISPRSZ_HFILT98_COEFF9_MASK 0x3FF0000
1016
1017#define ISPRSZ_HFILT1110_COEF10_SHIFT 0
1018#define ISPRSZ_HFILT1110_COEF10_MASK 0x3FF
1019#define ISPRSZ_HFILT1110_COEF11_SHIFT 16
1020#define ISPRSZ_HFILT1110_COEF11_MASK 0x3FF0000
1021
1022#define ISPRSZ_HFILT1312_COEFF12_SHIFT 0
1023#define ISPRSZ_HFILT1312_COEFF12_MASK 0x3FF
1024#define ISPRSZ_HFILT1312_COEFF13_SHIFT 16
1025#define ISPRSZ_HFILT1312_COEFF13_MASK 0x3FF0000
1026
1027#define ISPRSZ_HFILT1514_COEFF14_SHIFT 0
1028#define ISPRSZ_HFILT1514_COEFF14_MASK 0x3FF
1029#define ISPRSZ_HFILT1514_COEFF15_SHIFT 16
1030#define ISPRSZ_HFILT1514_COEFF15_MASK 0x3FF0000
1031
1032#define ISPRSZ_HFILT1716_COEF16_SHIFT 0
1033#define ISPRSZ_HFILT1716_COEF16_MASK 0x3FF
1034#define ISPRSZ_HFILT1716_COEF17_SHIFT 16
1035#define ISPRSZ_HFILT1716_COEF17_MASK 0x3FF0000
1036
1037#define ISPRSZ_HFILT1918_COEF18_SHIFT 0
1038#define ISPRSZ_HFILT1918_COEF18_MASK 0x3FF
1039#define ISPRSZ_HFILT1918_COEF19_SHIFT 16
1040#define ISPRSZ_HFILT1918_COEF19_MASK 0x3FF0000
1041
1042#define ISPRSZ_HFILT2120_COEF20_SHIFT 0
1043#define ISPRSZ_HFILT2120_COEF20_MASK 0x3FF
1044#define ISPRSZ_HFILT2120_COEF21_SHIFT 16
1045#define ISPRSZ_HFILT2120_COEF21_MASK 0x3FF0000
1046
1047#define ISPRSZ_HFILT2322_COEF22_SHIFT 0
1048#define ISPRSZ_HFILT2322_COEF22_MASK 0x3FF
1049#define ISPRSZ_HFILT2322_COEF23_SHIFT 16
1050#define ISPRSZ_HFILT2322_COEF23_MASK 0x3FF0000
1051
1052#define ISPRSZ_HFILT2524_COEF24_SHIFT 0
1053#define ISPRSZ_HFILT2524_COEF24_MASK 0x3FF
1054#define ISPRSZ_HFILT2524_COEF25_SHIFT 16
1055#define ISPRSZ_HFILT2524_COEF25_MASK 0x3FF0000
1056
1057#define ISPRSZ_HFILT2726_COEF26_SHIFT 0
1058#define ISPRSZ_HFILT2726_COEF26_MASK 0x3FF
1059#define ISPRSZ_HFILT2726_COEF27_SHIFT 16
1060#define ISPRSZ_HFILT2726_COEF27_MASK 0x3FF0000
1061
1062#define ISPRSZ_HFILT2928_COEF28_SHIFT 0
1063#define ISPRSZ_HFILT2928_COEF28_MASK 0x3FF
1064#define ISPRSZ_HFILT2928_COEF29_SHIFT 16
1065#define ISPRSZ_HFILT2928_COEF29_MASK 0x3FF0000
1066
1067#define ISPRSZ_HFILT3130_COEF30_SHIFT 0
1068#define ISPRSZ_HFILT3130_COEF30_MASK 0x3FF
1069#define ISPRSZ_HFILT3130_COEF31_SHIFT 16
1070#define ISPRSZ_HFILT3130_COEF31_MASK 0x3FF0000
1071
1072#define ISPRSZ_VFILT_COEF0_SHIFT 0
1073#define ISPRSZ_VFILT_COEF0_MASK \
1074 (0x3FF << ISPRSZ_VFILT_COEF0_SHIFT)
1075#define ISPRSZ_VFILT_COEF1_SHIFT 16
1076#define ISPRSZ_VFILT_COEF1_MASK \
1077 (0x3FF << ISPRSZ_VFILT_COEF1_SHIFT)
1078
1079#define ISPRSZ_VFILT10_COEF0_SHIFT 0
1080#define ISPRSZ_VFILT10_COEF0_MASK 0x3FF
1081#define ISPRSZ_VFILT10_COEF1_SHIFT 16
1082#define ISPRSZ_VFILT10_COEF1_MASK 0x3FF0000
1083
1084#define ISPRSZ_VFILT32_COEF2_SHIFT 0
1085#define ISPRSZ_VFILT32_COEF2_MASK 0x3FF
1086#define ISPRSZ_VFILT32_COEF3_SHIFT 16
1087#define ISPRSZ_VFILT32_COEF3_MASK 0x3FF0000
1088
1089#define ISPRSZ_VFILT54_COEF4_SHIFT 0
1090#define ISPRSZ_VFILT54_COEF4_MASK 0x3FF
1091#define ISPRSZ_VFILT54_COEF5_SHIFT 16
1092#define ISPRSZ_VFILT54_COEF5_MASK 0x3FF0000
1093
1094#define ISPRSZ_VFILT76_COEFF6_SHIFT 0
1095#define ISPRSZ_VFILT76_COEFF6_MASK 0x3FF
1096#define ISPRSZ_VFILT76_COEFF7_SHIFT 16
1097#define ISPRSZ_VFILT76_COEFF7_MASK 0x3FF0000
1098
1099#define ISPRSZ_VFILT98_COEFF8_SHIFT 0
1100#define ISPRSZ_VFILT98_COEFF8_MASK 0x3FF
1101#define ISPRSZ_VFILT98_COEFF9_SHIFT 16
1102#define ISPRSZ_VFILT98_COEFF9_MASK 0x3FF0000
1103
1104#define ISPRSZ_VFILT1110_COEF10_SHIFT 0
1105#define ISPRSZ_VFILT1110_COEF10_MASK 0x3FF
1106#define ISPRSZ_VFILT1110_COEF11_SHIFT 16
1107#define ISPRSZ_VFILT1110_COEF11_MASK 0x3FF0000
1108
1109#define ISPRSZ_VFILT1312_COEFF12_SHIFT 0
1110#define ISPRSZ_VFILT1312_COEFF12_MASK 0x3FF
1111#define ISPRSZ_VFILT1312_COEFF13_SHIFT 16
1112#define ISPRSZ_VFILT1312_COEFF13_MASK 0x3FF0000
1113
1114#define ISPRSZ_VFILT1514_COEFF14_SHIFT 0
1115#define ISPRSZ_VFILT1514_COEFF14_MASK 0x3FF
1116#define ISPRSZ_VFILT1514_COEFF15_SHIFT 16
1117#define ISPRSZ_VFILT1514_COEFF15_MASK 0x3FF0000
1118
1119#define ISPRSZ_VFILT1716_COEF16_SHIFT 0
1120#define ISPRSZ_VFILT1716_COEF16_MASK 0x3FF
1121#define ISPRSZ_VFILT1716_COEF17_SHIFT 16
1122#define ISPRSZ_VFILT1716_COEF17_MASK 0x3FF0000
1123
1124#define ISPRSZ_VFILT1918_COEF18_SHIFT 0
1125#define ISPRSZ_VFILT1918_COEF18_MASK 0x3FF
1126#define ISPRSZ_VFILT1918_COEF19_SHIFT 16
1127#define ISPRSZ_VFILT1918_COEF19_MASK 0x3FF0000
1128
1129#define ISPRSZ_VFILT2120_COEF20_SHIFT 0
1130#define ISPRSZ_VFILT2120_COEF20_MASK 0x3FF
1131#define ISPRSZ_VFILT2120_COEF21_SHIFT 16
1132#define ISPRSZ_VFILT2120_COEF21_MASK 0x3FF0000
1133
1134#define ISPRSZ_VFILT2322_COEF22_SHIFT 0
1135#define ISPRSZ_VFILT2322_COEF22_MASK 0x3FF
1136#define ISPRSZ_VFILT2322_COEF23_SHIFT 16
1137#define ISPRSZ_VFILT2322_COEF23_MASK 0x3FF0000
1138
1139#define ISPRSZ_VFILT2524_COEF24_SHIFT 0
1140#define ISPRSZ_VFILT2524_COEF24_MASK 0x3FF
1141#define ISPRSZ_VFILT2524_COEF25_SHIFT 16
1142#define ISPRSZ_VFILT2524_COEF25_MASK 0x3FF0000
1143
1144#define ISPRSZ_VFILT2726_COEF26_SHIFT 0
1145#define ISPRSZ_VFILT2726_COEF26_MASK 0x3FF
1146#define ISPRSZ_VFILT2726_COEF27_SHIFT 16
1147#define ISPRSZ_VFILT2726_COEF27_MASK 0x3FF0000
1148
1149#define ISPRSZ_VFILT2928_COEF28_SHIFT 0
1150#define ISPRSZ_VFILT2928_COEF28_MASK 0x3FF
1151#define ISPRSZ_VFILT2928_COEF29_SHIFT 16
1152#define ISPRSZ_VFILT2928_COEF29_MASK 0x3FF0000
1153
1154#define ISPRSZ_VFILT3130_COEF30_SHIFT 0
1155#define ISPRSZ_VFILT3130_COEF30_MASK 0x3FF
1156#define ISPRSZ_VFILT3130_COEF31_SHIFT 16
1157#define ISPRSZ_VFILT3130_COEF31_MASK 0x3FF0000
1158
1159#define ISPRSZ_YENH_CORE_SHIFT 0
1160#define ISPRSZ_YENH_CORE_MASK \
1161 (0xFF << ISPRSZ_YENH_CORE_SHIFT)
1162#define ISPRSZ_YENH_SLOP_SHIFT 8
1163#define ISPRSZ_YENH_SLOP_MASK \
1164 (0xF << ISPRSZ_YENH_SLOP_SHIFT)
1165#define ISPRSZ_YENH_GAIN_SHIFT 12
1166#define ISPRSZ_YENH_GAIN_MASK \
1167 (0xF << ISPRSZ_YENH_GAIN_SHIFT)
1168#define ISPRSZ_YENH_ALGO_SHIFT 16
1169#define ISPRSZ_YENH_ALGO_MASK \
1170 (0x3 << ISPRSZ_YENH_ALGO_SHIFT)
1171
1172#define ISPH3A_PCR_AEW_ALAW_EN_SHIFT 1
1173#define ISPH3A_PCR_AF_MED_TH_SHIFT 3
1174#define ISPH3A_PCR_AF_RGBPOS_SHIFT 11
1175#define ISPH3A_PCR_AEW_AVE2LMT_SHIFT 22
1176#define ISPH3A_PCR_AEW_AVE2LMT_MASK 0xFFC00000
1177#define ISPH3A_PCR_BUSYAF (1 << 15)
1178#define ISPH3A_PCR_BUSYAEAWB (1 << 18)
1179
1180#define ISPH3A_AEWWIN1_WINHC_SHIFT 0
1181#define ISPH3A_AEWWIN1_WINHC_MASK 0x3F
1182#define ISPH3A_AEWWIN1_WINVC_SHIFT 6
1183#define ISPH3A_AEWWIN1_WINVC_MASK 0x1FC0
1184#define ISPH3A_AEWWIN1_WINW_SHIFT 13
1185#define ISPH3A_AEWWIN1_WINW_MASK 0xFE000
1186#define ISPH3A_AEWWIN1_WINH_SHIFT 24
1187#define ISPH3A_AEWWIN1_WINH_MASK 0x7F000000
1188
1189#define ISPH3A_AEWINSTART_WINSH_SHIFT 0
1190#define ISPH3A_AEWINSTART_WINSH_MASK 0x0FFF
1191#define ISPH3A_AEWINSTART_WINSV_SHIFT 16
1192#define ISPH3A_AEWINSTART_WINSV_MASK 0x0FFF0000
1193
1194#define ISPH3A_AEWINBLK_WINH_SHIFT 0
1195#define ISPH3A_AEWINBLK_WINH_MASK 0x7F
1196#define ISPH3A_AEWINBLK_WINSV_SHIFT 16
1197#define ISPH3A_AEWINBLK_WINSV_MASK 0x0FFF0000
1198
1199#define ISPH3A_AEWSUBWIN_AEWINCH_SHIFT 0
1200#define ISPH3A_AEWSUBWIN_AEWINCH_MASK 0x0F
1201#define ISPH3A_AEWSUBWIN_AEWINCV_SHIFT 8
1202#define ISPH3A_AEWSUBWIN_AEWINCV_MASK 0x0F00
1203
1204#define ISPHIST_PCR_ENABLE_SHIFT 0
1205#define ISPHIST_PCR_ENABLE_MASK 0x01
1206#define ISPHIST_PCR_ENABLE (1 << ISPHIST_PCR_ENABLE_SHIFT)
1207#define ISPHIST_PCR_BUSY 0x02
1208
1209#define ISPHIST_CNT_DATASIZE_SHIFT 8
1210#define ISPHIST_CNT_DATASIZE_MASK 0x0100
1211#define ISPHIST_CNT_CLEAR_SHIFT 7
1212#define ISPHIST_CNT_CLEAR_MASK 0x080
1213#define ISPHIST_CNT_CLEAR (1 << ISPHIST_CNT_CLEAR_SHIFT)
1214#define ISPHIST_CNT_CFA_SHIFT 6
1215#define ISPHIST_CNT_CFA_MASK 0x040
1216#define ISPHIST_CNT_BINS_SHIFT 4
1217#define ISPHIST_CNT_BINS_MASK 0x030
1218#define ISPHIST_CNT_SOURCE_SHIFT 3
1219#define ISPHIST_CNT_SOURCE_MASK 0x08
1220#define ISPHIST_CNT_SHIFT_SHIFT 0
1221#define ISPHIST_CNT_SHIFT_MASK 0x07
1222
1223#define ISPHIST_WB_GAIN_WG00_SHIFT 24
1224#define ISPHIST_WB_GAIN_WG00_MASK 0xFF000000
1225#define ISPHIST_WB_GAIN_WG01_SHIFT 16
1226#define ISPHIST_WB_GAIN_WG01_MASK 0xFF0000
1227#define ISPHIST_WB_GAIN_WG02_SHIFT 8
1228#define ISPHIST_WB_GAIN_WG02_MASK 0xFF00
1229#define ISPHIST_WB_GAIN_WG03_SHIFT 0
1230#define ISPHIST_WB_GAIN_WG03_MASK 0xFF
1231
1232#define ISPHIST_REG_START_END_MASK 0x3FFF
1233#define ISPHIST_REG_START_SHIFT 16
1234#define ISPHIST_REG_END_SHIFT 0
1235#define ISPHIST_REG_START_MASK (ISPHIST_REG_START_END_MASK << \
1236 ISPHIST_REG_START_SHIFT)
1237#define ISPHIST_REG_END_MASK (ISPHIST_REG_START_END_MASK << \
1238 ISPHIST_REG_END_SHIFT)
1239
1240#define ISPHIST_REG_MASK (ISPHIST_REG_START_MASK | \
1241 ISPHIST_REG_END_MASK)
1242
1243#define ISPHIST_ADDR_SHIFT 0
1244#define ISPHIST_ADDR_MASK 0x3FF
1245
1246#define ISPHIST_DATA_SHIFT 0
1247#define ISPHIST_DATA_MASK 0xFFFFF
1248
1249#define ISPHIST_RADD_SHIFT 0
1250#define ISPHIST_RADD_MASK 0xFFFFFFFF
1251
1252#define ISPHIST_RADD_OFF_SHIFT 0
1253#define ISPHIST_RADD_OFF_MASK 0xFFFF
1254
1255#define ISPHIST_HV_INFO_HSIZE_SHIFT 16
1256#define ISPHIST_HV_INFO_HSIZE_MASK 0x3FFF0000
1257#define ISPHIST_HV_INFO_VSIZE_SHIFT 0
1258#define ISPHIST_HV_INFO_VSIZE_MASK 0x3FFF
1259
1260#define ISPHIST_HV_INFO_MASK 0x3FFF3FFF
1261
1262#define ISPCCDC_LSC_ENABLE 1
1263#define ISPCCDC_LSC_BUSY (1 << 7)
1264#define ISPCCDC_LSC_GAIN_MODE_N_MASK 0x700
1265#define ISPCCDC_LSC_GAIN_MODE_N_SHIFT 8
1266#define ISPCCDC_LSC_GAIN_MODE_M_MASK 0x3800
1267#define ISPCCDC_LSC_GAIN_MODE_M_SHIFT 12
1268#define ISPCCDC_LSC_GAIN_FORMAT_MASK 0xE
1269#define ISPCCDC_LSC_GAIN_FORMAT_SHIFT 1
1270#define ISPCCDC_LSC_AFTER_REFORMATTER_MASK (1<<6)
1271
1272#define ISPCCDC_LSC_INITIAL_X_MASK 0x3F
1273#define ISPCCDC_LSC_INITIAL_X_SHIFT 0
1274#define ISPCCDC_LSC_INITIAL_Y_MASK 0x3F0000
1275#define ISPCCDC_LSC_INITIAL_Y_SHIFT 16
1276
1277/* -----------------------------------------------------------------------------
1278 * CSI2 receiver registers (ES2.0)
1279 */
1280
1281#define ISPCSI2_REVISION (0x000)
1282#define ISPCSI2_SYSCONFIG (0x010)
1283#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT 12
1284#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_MASK \
1285 (0x3 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1286#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_FORCE \
1287 (0x0 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1288#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_NO \
1289 (0x1 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1290#define ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SMART \
1291 (0x2 << ISPCSI2_SYSCONFIG_MSTANDBY_MODE_SHIFT)
1292#define ISPCSI2_SYSCONFIG_SOFT_RESET (1 << 1)
1293#define ISPCSI2_SYSCONFIG_AUTO_IDLE (1 << 0)
1294
1295#define ISPCSI2_SYSSTATUS (0x014)
1296#define ISPCSI2_SYSSTATUS_RESET_DONE (1 << 0)
1297
1298#define ISPCSI2_IRQSTATUS (0x018)
1299#define ISPCSI2_IRQSTATUS_OCP_ERR_IRQ (1 << 14)
1300#define ISPCSI2_IRQSTATUS_SHORT_PACKET_IRQ (1 << 13)
1301#define ISPCSI2_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 12)
1302#define ISPCSI2_IRQSTATUS_ECC_NO_CORRECTION_IRQ (1 << 11)
1303#define ISPCSI2_IRQSTATUS_COMPLEXIO2_ERR_IRQ (1 << 10)
1304#define ISPCSI2_IRQSTATUS_COMPLEXIO1_ERR_IRQ (1 << 9)
1305#define ISPCSI2_IRQSTATUS_FIFO_OVF_IRQ (1 << 8)
1306#define ISPCSI2_IRQSTATUS_CONTEXT(n) (1 << (n))
1307
1308#define ISPCSI2_IRQENABLE (0x01c)
1309#define ISPCSI2_CTRL (0x040)
1310#define ISPCSI2_CTRL_VP_CLK_EN (1 << 15)
1311#define ISPCSI2_CTRL_VP_ONLY_EN (1 << 11)
1312#define ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT 8
1313#define ISPCSI2_CTRL_VP_OUT_CTRL_MASK \
1314 (3 << ISPCSI2_CTRL_VP_OUT_CTRL_SHIFT)
1315#define ISPCSI2_CTRL_DBG_EN (1 << 7)
1316#define ISPCSI2_CTRL_BURST_SIZE_SHIFT 5
1317#define ISPCSI2_CTRL_BURST_SIZE_MASK \
1318 (3 << ISPCSI2_CTRL_BURST_SIZE_SHIFT)
1319#define ISPCSI2_CTRL_FRAME (1 << 3)
1320#define ISPCSI2_CTRL_ECC_EN (1 << 2)
1321#define ISPCSI2_CTRL_SECURE (1 << 1)
1322#define ISPCSI2_CTRL_IF_EN (1 << 0)
1323
1324#define ISPCSI2_DBG_H (0x044)
1325#define ISPCSI2_GNQ (0x048)
1326#define ISPCSI2_PHY_CFG (0x050)
1327#define ISPCSI2_PHY_CFG_RESET_CTRL (1 << 30)
1328#define ISPCSI2_PHY_CFG_RESET_DONE (1 << 29)
1329#define ISPCSI2_PHY_CFG_PWR_CMD_SHIFT 27
1330#define ISPCSI2_PHY_CFG_PWR_CMD_MASK \
1331 (0x3 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1332#define ISPCSI2_PHY_CFG_PWR_CMD_OFF \
1333 (0x0 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1334#define ISPCSI2_PHY_CFG_PWR_CMD_ON \
1335 (0x1 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1336#define ISPCSI2_PHY_CFG_PWR_CMD_ULPW \
1337 (0x2 << ISPCSI2_PHY_CFG_PWR_CMD_SHIFT)
1338#define ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT 25
1339#define ISPCSI2_PHY_CFG_PWR_STATUS_MASK \
1340 (0x3 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1341#define ISPCSI2_PHY_CFG_PWR_STATUS_OFF \
1342 (0x0 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1343#define ISPCSI2_PHY_CFG_PWR_STATUS_ON \
1344 (0x1 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1345#define ISPCSI2_PHY_CFG_PWR_STATUS_ULPW \
1346 (0x2 << ISPCSI2_PHY_CFG_PWR_STATUS_SHIFT)
1347#define ISPCSI2_PHY_CFG_PWR_AUTO (1 << 24)
1348
1349#define ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n) (3 + ((n) * 4))
1350#define ISPCSI2_PHY_CFG_DATA_POL_MASK(n) \
1351 (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1352#define ISPCSI2_PHY_CFG_DATA_POL_PN(n) \
1353 (0x0 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1354#define ISPCSI2_PHY_CFG_DATA_POL_NP(n) \
1355 (0x1 << ISPCSI2_PHY_CFG_DATA_POL_SHIFT(n))
1356
1357#define ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n) ((n) * 4)
1358#define ISPCSI2_PHY_CFG_DATA_POSITION_MASK(n) \
1359 (0x7 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1360#define ISPCSI2_PHY_CFG_DATA_POSITION_NC(n) \
1361 (0x0 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1362#define ISPCSI2_PHY_CFG_DATA_POSITION_1(n) \
1363 (0x1 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1364#define ISPCSI2_PHY_CFG_DATA_POSITION_2(n) \
1365 (0x2 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1366#define ISPCSI2_PHY_CFG_DATA_POSITION_3(n) \
1367 (0x3 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1368#define ISPCSI2_PHY_CFG_DATA_POSITION_4(n) \
1369 (0x4 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1370#define ISPCSI2_PHY_CFG_DATA_POSITION_5(n) \
1371 (0x5 << ISPCSI2_PHY_CFG_DATA_POSITION_SHIFT(n))
1372
1373#define ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT 3
1374#define ISPCSI2_PHY_CFG_CLOCK_POL_MASK \
1375 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1376#define ISPCSI2_PHY_CFG_CLOCK_POL_PN \
1377 (0x0 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1378#define ISPCSI2_PHY_CFG_CLOCK_POL_NP \
1379 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POL_SHIFT)
1380
1381#define ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT 0
1382#define ISPCSI2_PHY_CFG_CLOCK_POSITION_MASK \
1383 (0x7 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1384#define ISPCSI2_PHY_CFG_CLOCK_POSITION_1 \
1385 (0x1 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1386#define ISPCSI2_PHY_CFG_CLOCK_POSITION_2 \
1387 (0x2 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1388#define ISPCSI2_PHY_CFG_CLOCK_POSITION_3 \
1389 (0x3 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1390#define ISPCSI2_PHY_CFG_CLOCK_POSITION_4 \
1391 (0x4 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1392#define ISPCSI2_PHY_CFG_CLOCK_POSITION_5 \
1393 (0x5 << ISPCSI2_PHY_CFG_CLOCK_POSITION_SHIFT)
1394
1395#define ISPCSI2_PHY_IRQSTATUS (0x054)
1396#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMEXIT (1 << 26)
1397#define ISPCSI2_PHY_IRQSTATUS_STATEALLULPMENTER (1 << 25)
1398#define ISPCSI2_PHY_IRQSTATUS_STATEULPM5 (1 << 24)
1399#define ISPCSI2_PHY_IRQSTATUS_STATEULPM4 (1 << 23)
1400#define ISPCSI2_PHY_IRQSTATUS_STATEULPM3 (1 << 22)
1401#define ISPCSI2_PHY_IRQSTATUS_STATEULPM2 (1 << 21)
1402#define ISPCSI2_PHY_IRQSTATUS_STATEULPM1 (1 << 20)
1403#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL5 (1 << 19)
1404#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL4 (1 << 18)
1405#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL3 (1 << 17)
1406#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL2 (1 << 16)
1407#define ISPCSI2_PHY_IRQSTATUS_ERRCONTROL1 (1 << 15)
1408#define ISPCSI2_PHY_IRQSTATUS_ERRESC5 (1 << 14)
1409#define ISPCSI2_PHY_IRQSTATUS_ERRESC4 (1 << 13)
1410#define ISPCSI2_PHY_IRQSTATUS_ERRESC3 (1 << 12)
1411#define ISPCSI2_PHY_IRQSTATUS_ERRESC2 (1 << 11)
1412#define ISPCSI2_PHY_IRQSTATUS_ERRESC1 (1 << 10)
1413#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS5 (1 << 9)
1414#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS4 (1 << 8)
1415#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS3 (1 << 7)
1416#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS2 (1 << 6)
1417#define ISPCSI2_PHY_IRQSTATUS_ERRSOTSYNCHS1 (1 << 5)
1418#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS5 (1 << 4)
1419#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS4 (1 << 3)
1420#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS3 (1 << 2)
1421#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS2 (1 << 1)
1422#define ISPCSI2_PHY_IRQSTATUS_ERRSOTHS1 1
1423
1424#define ISPCSI2_SHORT_PACKET (0x05c)
1425#define ISPCSI2_PHY_IRQENABLE (0x060)
1426#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMEXIT (1 << 26)
1427#define ISPCSI2_PHY_IRQENABLE_STATEALLULPMENTER (1 << 25)
1428#define ISPCSI2_PHY_IRQENABLE_STATEULPM5 (1 << 24)
1429#define ISPCSI2_PHY_IRQENABLE_STATEULPM4 (1 << 23)
1430#define ISPCSI2_PHY_IRQENABLE_STATEULPM3 (1 << 22)
1431#define ISPCSI2_PHY_IRQENABLE_STATEULPM2 (1 << 21)
1432#define ISPCSI2_PHY_IRQENABLE_STATEULPM1 (1 << 20)
1433#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL5 (1 << 19)
1434#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL4 (1 << 18)
1435#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL3 (1 << 17)
1436#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL2 (1 << 16)
1437#define ISPCSI2_PHY_IRQENABLE_ERRCONTROL1 (1 << 15)
1438#define ISPCSI2_PHY_IRQENABLE_ERRESC5 (1 << 14)
1439#define ISPCSI2_PHY_IRQENABLE_ERRESC4 (1 << 13)
1440#define ISPCSI2_PHY_IRQENABLE_ERRESC3 (1 << 12)
1441#define ISPCSI2_PHY_IRQENABLE_ERRESC2 (1 << 11)
1442#define ISPCSI2_PHY_IRQENABLE_ERRESC1 (1 << 10)
1443#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS5 (1 << 9)
1444#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS4 (1 << 8)
1445#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS3 (1 << 7)
1446#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS2 (1 << 6)
1447#define ISPCSI2_PHY_IRQENABLE_ERRSOTSYNCHS1 (1 << 5)
1448#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS5 (1 << 4)
1449#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS4 (1 << 3)
1450#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS3 (1 << 2)
1451#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS2 (1 << 1)
1452#define ISPCSI2_PHY_IRQENABLE_ERRSOTHS1 (1 << 0)
1453
1454#define ISPCSI2_DBG_P (0x068)
1455#define ISPCSI2_TIMING (0x06c)
1456#define ISPCSI2_TIMING_FORCE_RX_MODE_IO(n) (1 << ((16 * ((n) - 1)) + 15))
1457#define ISPCSI2_TIMING_STOP_STATE_X16_IO(n) (1 << ((16 * ((n) - 1)) + 14))
1458#define ISPCSI2_TIMING_STOP_STATE_X4_IO(n) (1 << ((16 * ((n) - 1)) + 13))
1459#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n) (16 * ((n) - 1))
1460#define ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_MASK(n) \
1461 (0x1fff << ISPCSI2_TIMING_STOP_STATE_COUNTER_IO_SHIFT(n))
1462
1463#define ISPCSI2_CTX_CTRL1(n) ((0x070) + 0x20 * (n))
1464#define ISPCSI2_CTX_CTRL1_COUNT_SHIFT 8
1465#define ISPCSI2_CTX_CTRL1_COUNT_MASK \
1466 (0xff << ISPCSI2_CTX_CTRL1_COUNT_SHIFT)
1467#define ISPCSI2_CTX_CTRL1_EOF_EN (1 << 7)
1468#define ISPCSI2_CTX_CTRL1_EOL_EN (1 << 6)
1469#define ISPCSI2_CTX_CTRL1_CS_EN (1 << 5)
1470#define ISPCSI2_CTX_CTRL1_COUNT_UNLOCK (1 << 4)
1471#define ISPCSI2_CTX_CTRL1_PING_PONG (1 << 3)
1472#define ISPCSI2_CTX_CTRL1_CTX_EN (1 << 0)
1473
1474#define ISPCSI2_CTX_CTRL2(n) ((0x074) + 0x20 * (n))
1475#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT 13
1476#define ISPCSI2_CTX_CTRL2_USER_DEF_MAP_MASK \
1477 (0x3 << ISPCSI2_CTX_CTRL2_USER_DEF_MAP_SHIFT)
1478#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT 11
1479#define ISPCSI2_CTX_CTRL2_VIRTUAL_ID_MASK \
1480 (0x3 << ISPCSI2_CTX_CTRL2_VIRTUAL_ID_SHIFT)
1481#define ISPCSI2_CTX_CTRL2_DPCM_PRED (1 << 10)
1482#define ISPCSI2_CTX_CTRL2_FORMAT_SHIFT 0
1483#define ISPCSI2_CTX_CTRL2_FORMAT_MASK \
1484 (0x3ff << ISPCSI2_CTX_CTRL2_FORMAT_SHIFT)
1485#define ISPCSI2_CTX_CTRL2_FRAME_SHIFT 16
1486#define ISPCSI2_CTX_CTRL2_FRAME_MASK \
1487 (0xffff << ISPCSI2_CTX_CTRL2_FRAME_SHIFT)
1488
1489#define ISPCSI2_CTX_DAT_OFST(n) ((0x078) + 0x20 * (n))
1490#define ISPCSI2_CTX_DAT_OFST_OFST_SHIFT 0
1491#define ISPCSI2_CTX_DAT_OFST_OFST_MASK \
1492 (0x1ffe0 << ISPCSI2_CTX_DAT_OFST_OFST_SHIFT)
1493
1494#define ISPCSI2_CTX_DAT_PING_ADDR(n) ((0x07c) + 0x20 * (n))
1495#define ISPCSI2_CTX_DAT_PONG_ADDR(n) ((0x080) + 0x20 * (n))
1496#define ISPCSI2_CTX_IRQENABLE(n) ((0x084) + 0x20 * (n))
1497#define ISPCSI2_CTX_IRQENABLE_ECC_CORRECTION_IRQ (1 << 8)
1498#define ISPCSI2_CTX_IRQENABLE_LINE_NUMBER_IRQ (1 << 7)
1499#define ISPCSI2_CTX_IRQENABLE_FRAME_NUMBER_IRQ (1 << 6)
1500#define ISPCSI2_CTX_IRQENABLE_CS_IRQ (1 << 5)
1501#define ISPCSI2_CTX_IRQENABLE_LE_IRQ (1 << 3)
1502#define ISPCSI2_CTX_IRQENABLE_LS_IRQ (1 << 2)
1503#define ISPCSI2_CTX_IRQENABLE_FE_IRQ (1 << 1)
1504#define ISPCSI2_CTX_IRQENABLE_FS_IRQ (1 << 0)
1505
1506#define ISPCSI2_CTX_IRQSTATUS(n) ((0x088) + 0x20 * (n))
1507#define ISPCSI2_CTX_IRQSTATUS_ECC_CORRECTION_IRQ (1 << 8)
1508#define ISPCSI2_CTX_IRQSTATUS_LINE_NUMBER_IRQ (1 << 7)
1509#define ISPCSI2_CTX_IRQSTATUS_FRAME_NUMBER_IRQ (1 << 6)
1510#define ISPCSI2_CTX_IRQSTATUS_CS_IRQ (1 << 5)
1511#define ISPCSI2_CTX_IRQSTATUS_LE_IRQ (1 << 3)
1512#define ISPCSI2_CTX_IRQSTATUS_LS_IRQ (1 << 2)
1513#define ISPCSI2_CTX_IRQSTATUS_FE_IRQ (1 << 1)
1514#define ISPCSI2_CTX_IRQSTATUS_FS_IRQ (1 << 0)
1515
1516#define ISPCSI2_CTX_CTRL3(n) ((0x08c) + 0x20 * (n))
1517#define ISPCSI2_CTX_CTRL3_ALPHA_SHIFT 5
1518#define ISPCSI2_CTX_CTRL3_ALPHA_MASK \
1519 (0x3fff << ISPCSI2_CTX_CTRL3_ALPHA_SHIFT)
1520
1521/* This instance is for OMAP3630 only */
1522#define ISPCSI2_CTX_TRANSCODEH(n) (0x000 + 0x8 * (n))
1523#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT 16
1524#define ISPCSI2_CTX_TRANSCODEH_HCOUNT_MASK \
1525 (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
1526#define ISPCSI2_CTX_TRANSCODEH_HSKIP_SHIFT 0
1527#define ISPCSI2_CTX_TRANSCODEH_HSKIP_MASK \
1528 (0x1fff << ISPCSI2_CTX_TRANSCODEH_HCOUNT_SHIFT)
1529#define ISPCSI2_CTX_TRANSCODEV(n) (0x004 + 0x8 * (n))
1530#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT 16
1531#define ISPCSI2_CTX_TRANSCODEV_VCOUNT_MASK \
1532 (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
1533#define ISPCSI2_CTX_TRANSCODEV_VSKIP_SHIFT 0
1534#define ISPCSI2_CTX_TRANSCODEV_VSKIP_MASK \
1535 (0x1fff << ISPCSI2_CTX_TRANSCODEV_VCOUNT_SHIFT)
1536
1537/* -----------------------------------------------------------------------------
1538 * CSI PHY registers
1539 */
1540
1541#define ISPCSIPHY_REG0 (0x000)
1542#define ISPCSIPHY_REG0_THS_TERM_SHIFT 8
1543#define ISPCSIPHY_REG0_THS_TERM_MASK \
1544 (0xff << ISPCSIPHY_REG0_THS_TERM_SHIFT)
1545#define ISPCSIPHY_REG0_THS_SETTLE_SHIFT 0
1546#define ISPCSIPHY_REG0_THS_SETTLE_MASK \
1547 (0xff << ISPCSIPHY_REG0_THS_SETTLE_SHIFT)
1548
1549#define ISPCSIPHY_REG1 (0x004)
1550#define ISPCSIPHY_REG1_RESET_DONE_CTRLCLK (1 << 29)
1551/* This field is for OMAP3630 only */
1552#define ISPCSIPHY_REG1_CLOCK_MISS_DETECTOR_STATUS (1 << 25)
1553#define ISPCSIPHY_REG1_TCLK_TERM_SHIFT 18
1554#define ISPCSIPHY_REG1_TCLK_TERM_MASK \
1555 (0x7f << ISPCSIPHY_REG1_TCLK_TERM_SHIFT)
1556#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_SHIFT 10
1557#define ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN_MASK \
1558 (0xff << ISPCSIPHY_REG1_DPHY_HS_SYNC_PATTERN)
1559/* This field is for OMAP3430 only */
1560#define ISPCSIPHY_REG1_TCLK_MISS_SHIFT 8
1561#define ISPCSIPHY_REG1_TCLK_MISS_MASK \
1562 (0x3 << ISPCSIPHY_REG1_TCLK_MISS_SHIFT)
1563/* This field is for OMAP3630 only */
1564#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT 8
1565#define ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_MASK \
1566 (0x3 << ISPCSIPHY_REG1_CTRLCLK_DIV_FACTOR_SHIFT)
1567#define ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT 0
1568#define ISPCSIPHY_REG1_TCLK_SETTLE_MASK \
1569 (0xff << ISPCSIPHY_REG1_TCLK_SETTLE_SHIFT)
1570
1571/* This register is for OMAP3630 only */
1572#define ISPCSIPHY_REG2 (0x008)
1573#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT 30
1574#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_MASK \
1575 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC0_SHIFT)
1576#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT 28
1577#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_MASK \
1578 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC1_SHIFT)
1579#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT 26
1580#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_MASK \
1581 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC2_SHIFT)
1582#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT 24
1583#define ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_MASK \
1584 (0x3 << ISPCSIPHY_REG2_TRIGGER_CMD_RXTRIGESC3_SHIFT)
1585#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT 0
1586#define ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_MASK \
1587 (0x7fffff << ISPCSIPHY_REG2_CCP2_SYNC_PATTERN_SHIFT)
1588
1589#endif /* OMAP3_ISP_REG_H */
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
new file mode 100644
index 000000000000..75d39b115d42
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -0,0 +1,1693 @@
1/*
2 * ispresizer.c
3 *
4 * TI OMAP3 ISP - Resizer module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#include <linux/device.h>
28#include <linux/mm.h>
29#include <linux/module.h>
30
31#include "isp.h"
32#include "ispreg.h"
33#include "ispresizer.h"
34
35/*
36 * Resizer Constants
37 */
38#define MIN_RESIZE_VALUE 64
39#define MID_RESIZE_VALUE 512
40#define MAX_RESIZE_VALUE 1024
41
42#define MIN_IN_WIDTH 32
43#define MIN_IN_HEIGHT 32
44#define MAX_IN_WIDTH_MEMORY_MODE 4095
45#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES1 1280
46#define MAX_IN_WIDTH_ONTHEFLY_MODE_ES2 4095
47#define MAX_IN_HEIGHT 4095
48
49#define MIN_OUT_WIDTH 16
50#define MIN_OUT_HEIGHT 2
51#define MAX_OUT_HEIGHT 4095
52
53/*
54 * Resizer Use Constraints
55 * "TRM ES3.1, table 12-46"
56 */
57#define MAX_4TAP_OUT_WIDTH_ES1 1280
58#define MAX_7TAP_OUT_WIDTH_ES1 640
59#define MAX_4TAP_OUT_WIDTH_ES2 3312
60#define MAX_7TAP_OUT_WIDTH_ES2 1650
61#define MAX_4TAP_OUT_WIDTH_3630 4096
62#define MAX_7TAP_OUT_WIDTH_3630 2048
63
64/*
65 * Constants for ratio calculation
66 */
67#define RESIZE_DIVISOR 256
68#define DEFAULT_PHASE 1
69
70/*
71 * Default (and only) configuration of filter coefficients.
72 * 7-tap mode is for scale factors 0.25x to 0.5x.
73 * 4-tap mode is for scale factors 0.5x to 4.0x.
74 * There shouldn't be any reason to recalculate these, EVER.
75 */
76static const struct isprsz_coef filter_coefs = {
77 /* For 8-phase 4-tap horizontal filter: */
78 {
79 0x0000, 0x0100, 0x0000, 0x0000,
80 0x03FA, 0x00F6, 0x0010, 0x0000,
81 0x03F9, 0x00DB, 0x002C, 0x0000,
82 0x03FB, 0x00B3, 0x0053, 0x03FF,
83 0x03FD, 0x0082, 0x0084, 0x03FD,
84 0x03FF, 0x0053, 0x00B3, 0x03FB,
85 0x0000, 0x002C, 0x00DB, 0x03F9,
86 0x0000, 0x0010, 0x00F6, 0x03FA
87 },
88 /* For 8-phase 4-tap vertical filter: */
89 {
90 0x0000, 0x0100, 0x0000, 0x0000,
91 0x03FA, 0x00F6, 0x0010, 0x0000,
92 0x03F9, 0x00DB, 0x002C, 0x0000,
93 0x03FB, 0x00B3, 0x0053, 0x03FF,
94 0x03FD, 0x0082, 0x0084, 0x03FD,
95 0x03FF, 0x0053, 0x00B3, 0x03FB,
96 0x0000, 0x002C, 0x00DB, 0x03F9,
97 0x0000, 0x0010, 0x00F6, 0x03FA
98 },
99 /* For 4-phase 7-tap horizontal filter: */
100 #define DUMMY 0
101 {
102 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
103 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
104 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
105 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
106 },
107 /* For 4-phase 7-tap vertical filter: */
108 {
109 0x0004, 0x0023, 0x005A, 0x0058, 0x0023, 0x0004, 0x0000, DUMMY,
110 0x0002, 0x0018, 0x004d, 0x0060, 0x0031, 0x0008, 0x0000, DUMMY,
111 0x0001, 0x000f, 0x003f, 0x0062, 0x003f, 0x000f, 0x0001, DUMMY,
112 0x0000, 0x0008, 0x0031, 0x0060, 0x004d, 0x0018, 0x0002, DUMMY
113 }
114 /*
115 * The dummy padding is required in 7-tap mode because of how the
116 * registers are arranged physically.
117 */
118 #undef DUMMY
119};
120
121/*
122 * __resizer_get_format - helper function for getting resizer format
123 * @res : pointer to resizer private structure
124 * @pad : pad number
125 * @fh : V4L2 subdev file handle
126 * @which : wanted subdev format
127 * return zero
128 */
129static struct v4l2_mbus_framefmt *
130__resizer_get_format(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
131 unsigned int pad, enum v4l2_subdev_format_whence which)
132{
133 if (which == V4L2_SUBDEV_FORMAT_TRY)
134 return v4l2_subdev_get_try_format(fh, pad);
135 else
136 return &res->formats[pad];
137}
138
139/*
140 * __resizer_get_crop - helper function for getting resizer crop rectangle
141 * @res : pointer to resizer private structure
142 * @fh : V4L2 subdev file handle
143 * @which : wanted subdev crop rectangle
144 */
145static struct v4l2_rect *
146__resizer_get_crop(struct isp_res_device *res, struct v4l2_subdev_fh *fh,
147 enum v4l2_subdev_format_whence which)
148{
149 if (which == V4L2_SUBDEV_FORMAT_TRY)
150 return v4l2_subdev_get_try_crop(fh, RESZ_PAD_SINK);
151 else
152 return &res->crop.request;
153}
154
155/*
156 * resizer_set_filters - Set resizer filters
157 * @res: Device context.
158 * @h_coeff: horizontal coefficient
159 * @v_coeff: vertical coefficient
160 * Return none
161 */
162static void resizer_set_filters(struct isp_res_device *res, const u16 *h_coeff,
163 const u16 *v_coeff)
164{
165 struct isp_device *isp = to_isp_device(res);
166 u32 startaddr_h, startaddr_v, tmp_h, tmp_v;
167 int i;
168
169 startaddr_h = ISPRSZ_HFILT10;
170 startaddr_v = ISPRSZ_VFILT10;
171
172 for (i = 0; i < COEFF_CNT; i += 2) {
173 tmp_h = h_coeff[i] |
174 (h_coeff[i + 1] << ISPRSZ_HFILT_COEF1_SHIFT);
175 tmp_v = v_coeff[i] |
176 (v_coeff[i + 1] << ISPRSZ_VFILT_COEF1_SHIFT);
177 isp_reg_writel(isp, tmp_h, OMAP3_ISP_IOMEM_RESZ, startaddr_h);
178 isp_reg_writel(isp, tmp_v, OMAP3_ISP_IOMEM_RESZ, startaddr_v);
179 startaddr_h += 4;
180 startaddr_v += 4;
181 }
182}
183
184/*
185 * resizer_set_bilinear - Chrominance horizontal algorithm select
186 * @res: Device context.
187 * @type: Filtering interpolation type.
188 *
189 * Filtering that is same as luminance processing is
190 * intended only for downsampling, and bilinear interpolation
191 * is intended only for upsampling.
192 */
193static void resizer_set_bilinear(struct isp_res_device *res,
194 enum resizer_chroma_algo type)
195{
196 struct isp_device *isp = to_isp_device(res);
197
198 if (type == RSZ_BILINEAR)
199 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
200 ISPRSZ_CNT_CBILIN);
201 else
202 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
203 ISPRSZ_CNT_CBILIN);
204}
205
206/*
207 * resizer_set_ycpos - Luminance and chrominance order
208 * @res: Device context.
209 * @order: order type.
210 */
211static void resizer_set_ycpos(struct isp_res_device *res,
212 enum v4l2_mbus_pixelcode pixelcode)
213{
214 struct isp_device *isp = to_isp_device(res);
215
216 switch (pixelcode) {
217 case V4L2_MBUS_FMT_YUYV8_1X16:
218 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
219 ISPRSZ_CNT_YCPOS);
220 break;
221 case V4L2_MBUS_FMT_UYVY8_1X16:
222 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
223 ISPRSZ_CNT_YCPOS);
224 break;
225 default:
226 return;
227 }
228}
229
230/*
231 * resizer_set_phase - Setup horizontal and vertical starting phase
232 * @res: Device context.
233 * @h_phase: horizontal phase parameters.
234 * @v_phase: vertical phase parameters.
235 *
236 * Horizontal and vertical phase range is 0 to 7
237 */
238static void resizer_set_phase(struct isp_res_device *res, u32 h_phase,
239 u32 v_phase)
240{
241 struct isp_device *isp = to_isp_device(res);
242 u32 rgval = 0;
243
244 rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
245 ~(ISPRSZ_CNT_HSTPH_MASK | ISPRSZ_CNT_VSTPH_MASK);
246 rgval |= (h_phase << ISPRSZ_CNT_HSTPH_SHIFT) & ISPRSZ_CNT_HSTPH_MASK;
247 rgval |= (v_phase << ISPRSZ_CNT_VSTPH_SHIFT) & ISPRSZ_CNT_VSTPH_MASK;
248
249 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
250}
251
252/*
253 * resizer_set_luma - Setup luminance enhancer parameters
254 * @res: Device context.
255 * @luma: Structure for luminance enhancer parameters.
256 *
257 * Algorithm select:
258 * 0x0: Disable
259 * 0x1: [-1 2 -1]/2 high-pass filter
260 * 0x2: [-1 -2 6 -2 -1]/4 high-pass filter
261 *
262 * Maximum gain:
263 * The data is coded in U4Q4 representation.
264 *
265 * Slope:
266 * The data is coded in U4Q4 representation.
267 *
268 * Coring offset:
269 * The data is coded in U8Q0 representation.
270 *
271 * The new luminance value is computed as:
272 * Y += HPF(Y) x max(GAIN, (HPF(Y) - CORE) x SLOP + 8) >> 4.
273 */
274static void resizer_set_luma(struct isp_res_device *res,
275 struct resizer_luma_yenh *luma)
276{
277 struct isp_device *isp = to_isp_device(res);
278 u32 rgval = 0;
279
280 rgval = (luma->algo << ISPRSZ_YENH_ALGO_SHIFT)
281 & ISPRSZ_YENH_ALGO_MASK;
282 rgval |= (luma->gain << ISPRSZ_YENH_GAIN_SHIFT)
283 & ISPRSZ_YENH_GAIN_MASK;
284 rgval |= (luma->slope << ISPRSZ_YENH_SLOP_SHIFT)
285 & ISPRSZ_YENH_SLOP_MASK;
286 rgval |= (luma->core << ISPRSZ_YENH_CORE_SHIFT)
287 & ISPRSZ_YENH_CORE_MASK;
288
289 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_YENH);
290}
291
292/*
293 * resizer_set_source - Input source select
294 * @res: Device context.
295 * @source: Input source type
296 *
297 * If this field is set to RESIZER_INPUT_VP, the resizer input is fed from
298 * Preview/CCDC engine, otherwise from memory.
299 */
300static void resizer_set_source(struct isp_res_device *res,
301 enum resizer_input_entity source)
302{
303 struct isp_device *isp = to_isp_device(res);
304
305 if (source == RESIZER_INPUT_MEMORY)
306 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
307 ISPRSZ_CNT_INPSRC);
308 else
309 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
310 ISPRSZ_CNT_INPSRC);
311}
312
313/*
314 * resizer_set_ratio - Setup horizontal and vertical resizing value
315 * @res: Device context.
316 * @ratio: Structure for ratio parameters.
317 *
318 * Resizing range from 64 to 1024
319 */
320static void resizer_set_ratio(struct isp_res_device *res,
321 const struct resizer_ratio *ratio)
322{
323 struct isp_device *isp = to_isp_device(res);
324 const u16 *h_filter, *v_filter;
325 u32 rgval = 0;
326
327 rgval = isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT) &
328 ~(ISPRSZ_CNT_HRSZ_MASK | ISPRSZ_CNT_VRSZ_MASK);
329 rgval |= ((ratio->horz - 1) << ISPRSZ_CNT_HRSZ_SHIFT)
330 & ISPRSZ_CNT_HRSZ_MASK;
331 rgval |= ((ratio->vert - 1) << ISPRSZ_CNT_VRSZ_SHIFT)
332 & ISPRSZ_CNT_VRSZ_MASK;
333 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT);
334
335 /* prepare horizontal filter coefficients */
336 if (ratio->horz > MID_RESIZE_VALUE)
337 h_filter = &filter_coefs.h_filter_coef_7tap[0];
338 else
339 h_filter = &filter_coefs.h_filter_coef_4tap[0];
340
341 /* prepare vertical filter coefficients */
342 if (ratio->vert > MID_RESIZE_VALUE)
343 v_filter = &filter_coefs.v_filter_coef_7tap[0];
344 else
345 v_filter = &filter_coefs.v_filter_coef_4tap[0];
346
347 resizer_set_filters(res, h_filter, v_filter);
348}
349
350/*
351 * resizer_set_dst_size - Setup the output height and width
352 * @res: Device context.
353 * @width: Output width.
354 * @height: Output height.
355 *
356 * Width :
357 * The value must be EVEN.
358 *
359 * Height:
360 * The number of bytes written to SDRAM must be
361 * a multiple of 16-bytes if the vertical resizing factor
362 * is greater than 1x (upsizing)
363 */
364static void resizer_set_output_size(struct isp_res_device *res,
365 u32 width, u32 height)
366{
367 struct isp_device *isp = to_isp_device(res);
368 u32 rgval = 0;
369
370 dev_dbg(isp->dev, "Output size[w/h]: %dx%d\n", width, height);
371 rgval = (width << ISPRSZ_OUT_SIZE_HORZ_SHIFT)
372 & ISPRSZ_OUT_SIZE_HORZ_MASK;
373 rgval |= (height << ISPRSZ_OUT_SIZE_VERT_SHIFT)
374 & ISPRSZ_OUT_SIZE_VERT_MASK;
375 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_OUT_SIZE);
376}
377
378/*
379 * resizer_set_output_offset - Setup memory offset for the output lines.
380 * @res: Device context.
381 * @offset: Memory offset.
382 *
383 * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
384 * boundary; the 5 LSBs are read-only. For optimal use of SDRAM bandwidth,
385 * the SDRAM line offset must be set on a 256-byte boundary
386 */
387static void resizer_set_output_offset(struct isp_res_device *res, u32 offset)
388{
389 struct isp_device *isp = to_isp_device(res);
390
391 isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTOFF);
392}
393
394/*
395 * resizer_set_start - Setup vertical and horizontal start position
396 * @res: Device context.
397 * @left: Horizontal start position.
398 * @top: Vertical start position.
399 *
400 * Vertical start line:
401 * This field makes sense only when the resizer obtains its input
402 * from the preview engine/CCDC
403 *
404 * Horizontal start pixel:
405 * Pixels are coded on 16 bits for YUV and 8 bits for color separate data.
406 * When the resizer gets its input from SDRAM, this field must be set
407 * to <= 15 for YUV 16-bit data and <= 31 for 8-bit color separate data
408 */
409static void resizer_set_start(struct isp_res_device *res, u32 left, u32 top)
410{
411 struct isp_device *isp = to_isp_device(res);
412 u32 rgval = 0;
413
414 rgval = (left << ISPRSZ_IN_START_HORZ_ST_SHIFT)
415 & ISPRSZ_IN_START_HORZ_ST_MASK;
416 rgval |= (top << ISPRSZ_IN_START_VERT_ST_SHIFT)
417 & ISPRSZ_IN_START_VERT_ST_MASK;
418
419 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_START);
420}
421
422/*
423 * resizer_set_input_size - Setup the input size
424 * @res: Device context.
425 * @width: The range is 0 to 4095 pixels
426 * @height: The range is 0 to 4095 lines
427 */
428static void resizer_set_input_size(struct isp_res_device *res,
429 u32 width, u32 height)
430{
431 struct isp_device *isp = to_isp_device(res);
432 u32 rgval = 0;
433
434 dev_dbg(isp->dev, "Input size[w/h]: %dx%d\n", width, height);
435
436 rgval = (width << ISPRSZ_IN_SIZE_HORZ_SHIFT)
437 & ISPRSZ_IN_SIZE_HORZ_MASK;
438 rgval |= (height << ISPRSZ_IN_SIZE_VERT_SHIFT)
439 & ISPRSZ_IN_SIZE_VERT_MASK;
440
441 isp_reg_writel(isp, rgval, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_IN_SIZE);
442}
443
444/*
445 * resizer_set_src_offs - Setup the memory offset for the input lines
446 * @res: Device context.
447 * @offset: Memory offset.
448 *
449 * The 5 LSBs are forced to be zeros by the hardware to align on a 32-byte
450 * boundary; the 5 LSBs are read-only. This field must be programmed to be
451 * 0x0 if the resizer input is from preview engine/CCDC.
452 */
453static void resizer_set_input_offset(struct isp_res_device *res, u32 offset)
454{
455 struct isp_device *isp = to_isp_device(res);
456
457 isp_reg_writel(isp, offset, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INOFF);
458}
459
460/*
461 * resizer_set_intype - Input type select
462 * @res: Device context.
463 * @type: Pixel format type.
464 */
465static void resizer_set_intype(struct isp_res_device *res,
466 enum resizer_colors_type type)
467{
468 struct isp_device *isp = to_isp_device(res);
469
470 if (type == RSZ_COLOR8)
471 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
472 ISPRSZ_CNT_INPTYP);
473 else
474 isp_reg_clr(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_CNT,
475 ISPRSZ_CNT_INPTYP);
476}
477
478/*
479 * __resizer_set_inaddr - Helper function for set input address
480 * @res : pointer to resizer private data structure
481 * @addr: input address
482 * return none
483 */
484static void __resizer_set_inaddr(struct isp_res_device *res, u32 addr)
485{
486 struct isp_device *isp = to_isp_device(res);
487
488 isp_reg_writel(isp, addr, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_INADD);
489}
490
491/*
492 * The data rate at the horizontal resizer output must not exceed half the
493 * functional clock or 100 MP/s, whichever is lower. According to the TRM
494 * there's no similar requirement for the vertical resizer output. However
495 * experience showed that vertical upscaling by 4 leads to SBL overflows (with
496 * data rates at the resizer output exceeding 300 MP/s). Limiting the resizer
497 * output data rate to the functional clock or 200 MP/s, whichever is lower,
498 * seems to get rid of SBL overflows.
499 *
500 * The maximum data rate at the output of the horizontal resizer can thus be
501 * computed with
502 *
503 * max intermediate rate <= L3 clock * input height / output height
504 * max intermediate rate <= L3 clock / 2
505 *
506 * The maximum data rate at the resizer input is then
507 *
508 * max input rate <= max intermediate rate * input width / output width
509 *
510 * where the input width and height are the resizer input crop rectangle size.
511 * The TRM doesn't clearly explain if that's a maximum instant data rate or a
512 * maximum average data rate.
513 */
514void omap3isp_resizer_max_rate(struct isp_res_device *res,
515 unsigned int *max_rate)
516{
517 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
518 const struct v4l2_mbus_framefmt *ofmt = &res->formats[RESZ_PAD_SOURCE];
519 unsigned long limit = min(pipe->l3_ick, 200000000UL);
520 unsigned long clock;
521
522 clock = div_u64((u64)limit * res->crop.active.height, ofmt->height);
523 clock = min(clock, limit / 2);
524 *max_rate = div_u64((u64)clock * res->crop.active.width, ofmt->width);
525}
526
527/*
528 * When the resizer processes images from memory, the driver must slow down read
529 * requests on the input to at least comply with the internal data rate
530 * requirements. If the application real-time requirements can cope with slower
531 * processing, the resizer can be slowed down even more to put less pressure on
532 * the overall system.
533 *
534 * When the resizer processes images on the fly (either from the CCDC or the
535 * preview module), the same data rate requirements apply but they can't be
536 * enforced at the resizer level. The image input module (sensor, CCP2 or
537 * preview module) must not provide image data faster than the resizer can
538 * process.
539 *
540 * For live image pipelines, the data rate is set by the frame format, size and
541 * rate. The sensor output frame rate must not exceed the maximum resizer data
542 * rate.
543 *
544 * The resizer slows down read requests by inserting wait cycles in the SBL
545 * requests. The maximum number of 256-byte requests per second can be computed
546 * as (the data rate is multiplied by 2 to convert from pixels per second to
547 * bytes per second)
548 *
549 * request per second = data rate * 2 / 256
550 * cycles per request = cycles per second / requests per second
551 *
552 * The number of cycles per second is controlled by the L3 clock, leading to
553 *
554 * cycles per request = L3 frequency / 2 * 256 / data rate
555 */
556static void resizer_adjust_bandwidth(struct isp_res_device *res)
557{
558 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
559 struct isp_device *isp = to_isp_device(res);
560 unsigned long l3_ick = pipe->l3_ick;
561 struct v4l2_fract *timeperframe;
562 unsigned int cycles_per_frame;
563 unsigned int requests_per_frame;
564 unsigned int cycles_per_request;
565 unsigned int granularity;
566 unsigned int minimum;
567 unsigned int maximum;
568 unsigned int value;
569
570 if (res->input != RESIZER_INPUT_MEMORY) {
571 isp_reg_clr(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
572 ISPSBL_SDR_REQ_RSZ_EXP_MASK);
573 return;
574 }
575
576 switch (isp->revision) {
577 case ISP_REVISION_1_0:
578 case ISP_REVISION_2_0:
579 default:
580 granularity = 1024;
581 break;
582
583 case ISP_REVISION_15_0:
584 granularity = 32;
585 break;
586 }
587
588 /* Compute the minimum number of cycles per request, based on the
589 * pipeline maximum data rate. This is an absolute lower bound if we
590 * don't want SBL overflows, so round the value up.
591 */
592 cycles_per_request = div_u64((u64)l3_ick / 2 * 256 + pipe->max_rate - 1,
593 pipe->max_rate);
594 minimum = DIV_ROUND_UP(cycles_per_request, granularity);
595
596 /* Compute the maximum number of cycles per request, based on the
597 * requested frame rate. This is a soft upper bound to achieve a frame
598 * rate equal or higher than the requested value, so round the value
599 * down.
600 */
601 timeperframe = &pipe->max_timeperframe;
602
603 requests_per_frame = DIV_ROUND_UP(res->crop.active.width * 2, 256)
604 * res->crop.active.height;
605 cycles_per_frame = div_u64((u64)l3_ick * timeperframe->numerator,
606 timeperframe->denominator);
607 cycles_per_request = cycles_per_frame / requests_per_frame;
608
609 maximum = cycles_per_request / granularity;
610
611 value = max(minimum, maximum);
612
613 dev_dbg(isp->dev, "%s: cycles per request = %u\n", __func__, value);
614 isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_SBL, ISPSBL_SDR_REQ_EXP,
615 ISPSBL_SDR_REQ_RSZ_EXP_MASK,
616 value << ISPSBL_SDR_REQ_RSZ_EXP_SHIFT);
617}
618
619/*
620 * omap3isp_resizer_busy - Checks if ISP resizer is busy.
621 *
622 * Returns busy field from ISPRSZ_PCR register.
623 */
624int omap3isp_resizer_busy(struct isp_res_device *res)
625{
626 struct isp_device *isp = to_isp_device(res);
627
628 return isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR) &
629 ISPRSZ_PCR_BUSY;
630}
631
632/*
633 * resizer_set_inaddr - Sets the memory address of the input frame.
634 * @addr: 32bit memory address aligned on 32byte boundary.
635 */
636static void resizer_set_inaddr(struct isp_res_device *res, u32 addr)
637{
638 res->addr_base = addr;
639
640 /* This will handle crop settings in stream off state */
641 if (res->crop_offset)
642 addr += res->crop_offset & ~0x1f;
643
644 __resizer_set_inaddr(res, addr);
645}
646
647/*
648 * Configures the memory address to which the output frame is written.
649 * @addr: 32bit memory address aligned on 32byte boundary.
650 * Note: For SBL efficiency reasons the address should be on a 256-byte
651 * boundary.
652 */
653static void resizer_set_outaddr(struct isp_res_device *res, u32 addr)
654{
655 struct isp_device *isp = to_isp_device(res);
656
657 /*
658 * Set output address. This needs to be in its own function
659 * because it changes often.
660 */
661 isp_reg_writel(isp, addr << ISPRSZ_SDR_OUTADD_ADDR_SHIFT,
662 OMAP3_ISP_IOMEM_RESZ, ISPRSZ_SDR_OUTADD);
663}
664
665/*
666 * resizer_print_status - Prints the values of the resizer module registers.
667 */
668#define RSZ_PRINT_REGISTER(isp, name)\
669 dev_dbg(isp->dev, "###RSZ " #name "=0x%08x\n", \
670 isp_reg_readl(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_##name))
671
672static void resizer_print_status(struct isp_res_device *res)
673{
674 struct isp_device *isp = to_isp_device(res);
675
676 dev_dbg(isp->dev, "-------------Resizer Register dump----------\n");
677
678 RSZ_PRINT_REGISTER(isp, PCR);
679 RSZ_PRINT_REGISTER(isp, CNT);
680 RSZ_PRINT_REGISTER(isp, OUT_SIZE);
681 RSZ_PRINT_REGISTER(isp, IN_START);
682 RSZ_PRINT_REGISTER(isp, IN_SIZE);
683 RSZ_PRINT_REGISTER(isp, SDR_INADD);
684 RSZ_PRINT_REGISTER(isp, SDR_INOFF);
685 RSZ_PRINT_REGISTER(isp, SDR_OUTADD);
686 RSZ_PRINT_REGISTER(isp, SDR_OUTOFF);
687 RSZ_PRINT_REGISTER(isp, YENH);
688
689 dev_dbg(isp->dev, "--------------------------------------------\n");
690}
691
692/*
693 * resizer_calc_ratios - Helper function for calculate resizer ratios
694 * @res: pointer to resizer private data structure
695 * @input: input frame size
696 * @output: output frame size
697 * @ratio : return calculated ratios
698 * return none
699 *
700 * The resizer uses a polyphase sample rate converter. The upsampling filter
701 * has a fixed number of phases that depend on the resizing ratio. As the ratio
702 * computation depends on the number of phases, we need to compute a first
703 * approximation and then refine it.
704 *
705 * The input/output/ratio relationship is given by the OMAP34xx TRM:
706 *
707 * - 8-phase, 4-tap mode (RSZ = 64 ~ 512)
708 * iw = (32 * sph + (ow - 1) * hrsz + 16) >> 8 + 7
709 * ih = (32 * spv + (oh - 1) * vrsz + 16) >> 8 + 4
710 * - 4-phase, 7-tap mode (RSZ = 513 ~ 1024)
711 * iw = (64 * sph + (ow - 1) * hrsz + 32) >> 8 + 7
712 * ih = (64 * spv + (oh - 1) * vrsz + 32) >> 8 + 7
713 *
714 * iw and ih are the input width and height after cropping. Those equations need
715 * to be satisfied exactly for the resizer to work correctly.
716 *
717 * Reverting the equations, we can compute the resizing ratios with
718 *
719 * - 8-phase, 4-tap mode
720 * hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1)
721 * vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1)
722 * - 4-phase, 7-tap mode
723 * hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1)
724 * vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1)
725 *
726 * The ratios are integer values, and must be rounded down to ensure that the
727 * cropped input size is not bigger than the uncropped input size. As the ratio
728 * in 7-tap mode is always smaller than the ratio in 4-tap mode, we can use the
729 * 7-tap mode equations to compute a ratio approximation.
730 *
731 * We first clamp the output size according to the hardware capabilitie to avoid
732 * auto-cropping the input more than required to satisfy the TRM equations. The
733 * minimum output size is achieved with a scaling factor of 1024. It is thus
734 * computed using the 7-tap equations.
735 *
736 * min ow = ((iw - 7) * 256 - 32 - 64 * sph) / 1024 + 1
737 * min oh = ((ih - 7) * 256 - 32 - 64 * spv) / 1024 + 1
738 *
739 * Similarly, the maximum output size is achieved with a scaling factor of 64
740 * and computed using the 4-tap equations.
741 *
742 * max ow = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / 64 + 1
743 * max oh = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1
744 *
745 * The additional +255 term compensates for the round down operation performed
746 * by the TRM equations when shifting the value right by 8 bits.
747 *
748 * We then compute and clamp the ratios (x1/4 ~ x4). Clamping the output size to
749 * the maximum value guarantees that the ratio value will never be smaller than
750 * the minimum, but it could still slightly exceed the maximum. Clamping the
751 * ratio will thus result in a resizing factor slightly larger than the
752 * requested value.
753 *
754 * To accomodate that, and make sure the TRM equations are satisfied exactly, we
755 * compute the input crop rectangle as the last step.
756 *
757 * As if the situation wasn't complex enough, the maximum output width depends
758 * on the vertical resizing ratio. Fortunately, the output height doesn't
759 * depend on the horizontal resizing ratio. We can then start by computing the
760 * output height and the vertical ratio, and then move to computing the output
761 * width and the horizontal ratio.
762 */
763static void resizer_calc_ratios(struct isp_res_device *res,
764 struct v4l2_rect *input,
765 struct v4l2_mbus_framefmt *output,
766 struct resizer_ratio *ratio)
767{
768 struct isp_device *isp = to_isp_device(res);
769 const unsigned int spv = DEFAULT_PHASE;
770 const unsigned int sph = DEFAULT_PHASE;
771 unsigned int upscaled_width;
772 unsigned int upscaled_height;
773 unsigned int min_width;
774 unsigned int min_height;
775 unsigned int max_width;
776 unsigned int max_height;
777 unsigned int width_alignment;
778
779 /*
780 * Clamp the output height based on the hardware capabilities and
781 * compute the vertical resizing ratio.
782 */
783 min_height = ((input->height - 7) * 256 - 32 - 64 * spv) / 1024 + 1;
784 min_height = max_t(unsigned int, min_height, MIN_OUT_HEIGHT);
785 max_height = ((input->height - 4) * 256 + 255 - 16 - 32 * spv) / 64 + 1;
786 max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
787 output->height = clamp(output->height, min_height, max_height);
788
789 ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv)
790 / (output->height - 1);
791 ratio->vert = clamp_t(unsigned int, ratio->vert,
792 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
793
794 if (ratio->vert <= MID_RESIZE_VALUE) {
795 upscaled_height = (output->height - 1) * ratio->vert
796 + 32 * spv + 16;
797 input->height = (upscaled_height >> 8) + 4;
798 } else {
799 upscaled_height = (output->height - 1) * ratio->vert
800 + 64 * spv + 32;
801 input->height = (upscaled_height >> 8) + 7;
802 }
803
804 /*
805 * Compute the minimum and maximum output widths based on the hardware
806 * capabilities. The maximum depends on the vertical resizing ratio.
807 */
808 min_width = ((input->width - 7) * 256 - 32 - 64 * sph) / 1024 + 1;
809 min_width = max_t(unsigned int, min_width, MIN_OUT_WIDTH);
810
811 if (ratio->vert <= MID_RESIZE_VALUE) {
812 switch (isp->revision) {
813 case ISP_REVISION_1_0:
814 max_width = MAX_4TAP_OUT_WIDTH_ES1;
815 break;
816
817 case ISP_REVISION_2_0:
818 default:
819 max_width = MAX_4TAP_OUT_WIDTH_ES2;
820 break;
821
822 case ISP_REVISION_15_0:
823 max_width = MAX_4TAP_OUT_WIDTH_3630;
824 break;
825 }
826 } else {
827 switch (isp->revision) {
828 case ISP_REVISION_1_0:
829 max_width = MAX_7TAP_OUT_WIDTH_ES1;
830 break;
831
832 case ISP_REVISION_2_0:
833 default:
834 max_width = MAX_7TAP_OUT_WIDTH_ES2;
835 break;
836
837 case ISP_REVISION_15_0:
838 max_width = MAX_7TAP_OUT_WIDTH_3630;
839 break;
840 }
841 }
842 max_width = min(((input->width - 7) * 256 + 255 - 16 - 32 * sph) / 64
843 + 1, max_width);
844
845 /*
846 * The output width must be even, and must be a multiple of 16 bytes
847 * when upscaling vertically. Clamp the output width to the valid range.
848 * Take the alignment into account (the maximum width in 7-tap mode on
849 * ES2 isn't a multiple of 8) and align the result up to make sure it
850 * won't be smaller than the minimum.
851 */
852 width_alignment = ratio->vert < 256 ? 8 : 2;
853 output->width = clamp(output->width, min_width,
854 max_width & ~(width_alignment - 1));
855 output->width = ALIGN(output->width, width_alignment);
856
857 ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph)
858 / (output->width - 1);
859 ratio->horz = clamp_t(unsigned int, ratio->horz,
860 MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
861
862 if (ratio->horz <= MID_RESIZE_VALUE) {
863 upscaled_width = (output->width - 1) * ratio->horz
864 + 32 * sph + 16;
865 input->width = (upscaled_width >> 8) + 7;
866 } else {
867 upscaled_width = (output->width - 1) * ratio->horz
868 + 64 * sph + 32;
869 input->width = (upscaled_width >> 8) + 7;
870 }
871}
872
873/*
874 * resizer_set_crop_params - Setup hardware with cropping parameters
875 * @res : resizer private structure
876 * @crop_rect : current crop rectangle
877 * @ratio : resizer ratios
878 * return none
879 */
880static void resizer_set_crop_params(struct isp_res_device *res,
881 const struct v4l2_mbus_framefmt *input,
882 const struct v4l2_mbus_framefmt *output)
883{
884 resizer_set_ratio(res, &res->ratio);
885
886 /* Set chrominance horizontal algorithm */
887 if (res->ratio.horz >= RESIZE_DIVISOR)
888 resizer_set_bilinear(res, RSZ_THE_SAME);
889 else
890 resizer_set_bilinear(res, RSZ_BILINEAR);
891
892 resizer_adjust_bandwidth(res);
893
894 if (res->input == RESIZER_INPUT_MEMORY) {
895 /* Calculate additional offset for crop */
896 res->crop_offset = (res->crop.active.top * input->width +
897 res->crop.active.left) * 2;
898 /*
899 * Write lowest 4 bits of horizontal pixel offset (in pixels),
900 * vertical start must be 0.
901 */
902 resizer_set_start(res, (res->crop_offset / 2) & 0xf, 0);
903
904 /*
905 * Set start (read) address for cropping, in bytes.
906 * Lowest 5 bits must be zero.
907 */
908 __resizer_set_inaddr(res,
909 res->addr_base + (res->crop_offset & ~0x1f));
910 } else {
911 /*
912 * Set vertical start line and horizontal starting pixel.
913 * If the input is from CCDC/PREV, horizontal start field is
914 * in bytes (twice number of pixels).
915 */
916 resizer_set_start(res, res->crop.active.left * 2,
917 res->crop.active.top);
918 /* Input address and offset must be 0 for preview/ccdc input */
919 __resizer_set_inaddr(res, 0);
920 resizer_set_input_offset(res, 0);
921 }
922
923 /* Set the input size */
924 resizer_set_input_size(res, res->crop.active.width,
925 res->crop.active.height);
926}
927
928static void resizer_configure(struct isp_res_device *res)
929{
930 struct v4l2_mbus_framefmt *informat, *outformat;
931 struct resizer_luma_yenh luma = {0, 0, 0, 0};
932
933 resizer_set_source(res, res->input);
934
935 informat = &res->formats[RESZ_PAD_SINK];
936 outformat = &res->formats[RESZ_PAD_SOURCE];
937
938 /* RESZ_PAD_SINK */
939 if (res->input == RESIZER_INPUT_VP)
940 resizer_set_input_offset(res, 0);
941 else
942 resizer_set_input_offset(res, ALIGN(informat->width, 0x10) * 2);
943
944 /* YUV422 interleaved, default phase, no luma enhancement */
945 resizer_set_intype(res, RSZ_YUV422);
946 resizer_set_ycpos(res, informat->code);
947 resizer_set_phase(res, DEFAULT_PHASE, DEFAULT_PHASE);
948 resizer_set_luma(res, &luma);
949
950 /* RESZ_PAD_SOURCE */
951 resizer_set_output_offset(res, ALIGN(outformat->width * 2, 32));
952 resizer_set_output_size(res, outformat->width, outformat->height);
953
954 resizer_set_crop_params(res, informat, outformat);
955}
956
957/* -----------------------------------------------------------------------------
958 * Interrupt handling
959 */
960
961static void resizer_enable_oneshot(struct isp_res_device *res)
962{
963 struct isp_device *isp = to_isp_device(res);
964
965 isp_reg_set(isp, OMAP3_ISP_IOMEM_RESZ, ISPRSZ_PCR,
966 ISPRSZ_PCR_ENABLE | ISPRSZ_PCR_ONESHOT);
967}
968
969void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res)
970{
971 /*
972 * If ISP_VIDEO_DMAQUEUE_QUEUED is set, DMA queue had an underrun
973 * condition, the module was paused and now we have a buffer queued
974 * on the output again. Restart the pipeline if running in continuous
975 * mode.
976 */
977 if (res->state == ISP_PIPELINE_STREAM_CONTINUOUS &&
978 res->video_out.dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
979 resizer_enable_oneshot(res);
980 isp_video_dmaqueue_flags_clr(&res->video_out);
981 }
982}
983
984static void resizer_isr_buffer(struct isp_res_device *res)
985{
986 struct isp_pipeline *pipe = to_isp_pipeline(&res->subdev.entity);
987 struct isp_buffer *buffer;
988 int restart = 0;
989
990 if (res->state == ISP_PIPELINE_STREAM_STOPPED)
991 return;
992
993 /* Complete the output buffer and, if reading from memory, the input
994 * buffer.
995 */
996 buffer = omap3isp_video_buffer_next(&res->video_out, res->error);
997 if (buffer != NULL) {
998 resizer_set_outaddr(res, buffer->isp_addr);
999 restart = 1;
1000 }
1001
1002 pipe->state |= ISP_PIPELINE_IDLE_OUTPUT;
1003
1004 if (res->input == RESIZER_INPUT_MEMORY) {
1005 buffer = omap3isp_video_buffer_next(&res->video_in, 0);
1006 if (buffer != NULL)
1007 resizer_set_inaddr(res, buffer->isp_addr);
1008 pipe->state |= ISP_PIPELINE_IDLE_INPUT;
1009 }
1010
1011 if (res->state == ISP_PIPELINE_STREAM_SINGLESHOT) {
1012 if (isp_pipeline_ready(pipe))
1013 omap3isp_pipeline_set_stream(pipe,
1014 ISP_PIPELINE_STREAM_SINGLESHOT);
1015 } else {
1016 /* If an underrun occurs, the video queue operation handler will
1017 * restart the resizer. Otherwise restart it immediately.
1018 */
1019 if (restart)
1020 resizer_enable_oneshot(res);
1021 }
1022
1023 res->error = 0;
1024}
1025
1026/*
1027 * omap3isp_resizer_isr - ISP resizer interrupt handler
1028 *
1029 * Manage the resizer video buffers and configure shadowed and busy-locked
1030 * registers.
1031 */
1032void omap3isp_resizer_isr(struct isp_res_device *res)
1033{
1034 struct v4l2_mbus_framefmt *informat, *outformat;
1035
1036 if (omap3isp_module_sync_is_stopping(&res->wait, &res->stopping))
1037 return;
1038
1039 if (res->applycrop) {
1040 outformat = __resizer_get_format(res, NULL, RESZ_PAD_SOURCE,
1041 V4L2_SUBDEV_FORMAT_ACTIVE);
1042 informat = __resizer_get_format(res, NULL, RESZ_PAD_SINK,
1043 V4L2_SUBDEV_FORMAT_ACTIVE);
1044 resizer_set_crop_params(res, informat, outformat);
1045 res->applycrop = 0;
1046 }
1047
1048 resizer_isr_buffer(res);
1049}
1050
1051/* -----------------------------------------------------------------------------
1052 * ISP video operations
1053 */
1054
1055static int resizer_video_queue(struct isp_video *video,
1056 struct isp_buffer *buffer)
1057{
1058 struct isp_res_device *res = &video->isp->isp_res;
1059
1060 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
1061 resizer_set_inaddr(res, buffer->isp_addr);
1062
1063 /*
1064 * We now have a buffer queued on the output. Despite what the
1065 * TRM says, the resizer can't be restarted immediately.
1066 * Enabling it in one shot mode in the middle of a frame (or at
1067 * least asynchronously to the frame) results in the output
1068 * being shifted randomly left/right and up/down, as if the
1069 * hardware didn't synchronize itself to the beginning of the
1070 * frame correctly.
1071 *
1072 * Restart the resizer on the next sync interrupt if running in
1073 * continuous mode or when starting the stream.
1074 */
1075 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1076 resizer_set_outaddr(res, buffer->isp_addr);
1077
1078 return 0;
1079}
1080
1081static const struct isp_video_operations resizer_video_ops = {
1082 .queue = resizer_video_queue,
1083};
1084
1085/* -----------------------------------------------------------------------------
1086 * V4L2 subdev operations
1087 */
1088
1089/*
1090 * resizer_set_stream - Enable/Disable streaming on resizer subdev
1091 * @sd: ISP resizer V4L2 subdev
1092 * @enable: 1 == Enable, 0 == Disable
1093 *
1094 * The resizer hardware can't be enabled without a memory buffer to write to.
1095 * As the s_stream operation is called in response to a STREAMON call without
1096 * any buffer queued yet, just update the state field and return immediately.
1097 * The resizer will be enabled in resizer_video_queue().
1098 */
1099static int resizer_set_stream(struct v4l2_subdev *sd, int enable)
1100{
1101 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1102 struct isp_video *video_out = &res->video_out;
1103 struct isp_device *isp = to_isp_device(res);
1104 struct device *dev = to_device(res);
1105
1106 if (res->state == ISP_PIPELINE_STREAM_STOPPED) {
1107 if (enable == ISP_PIPELINE_STREAM_STOPPED)
1108 return 0;
1109
1110 omap3isp_subclk_enable(isp, OMAP3_ISP_SUBCLK_RESIZER);
1111 resizer_configure(res);
1112 res->error = 0;
1113 resizer_print_status(res);
1114 }
1115
1116 switch (enable) {
1117 case ISP_PIPELINE_STREAM_CONTINUOUS:
1118 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
1119 if (video_out->dmaqueue_flags & ISP_VIDEO_DMAQUEUE_QUEUED) {
1120 resizer_enable_oneshot(res);
1121 isp_video_dmaqueue_flags_clr(video_out);
1122 }
1123 break;
1124
1125 case ISP_PIPELINE_STREAM_SINGLESHOT:
1126 if (res->input == RESIZER_INPUT_MEMORY)
1127 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_READ);
1128 omap3isp_sbl_enable(isp, OMAP3_ISP_SBL_RESIZER_WRITE);
1129
1130 resizer_enable_oneshot(res);
1131 break;
1132
1133 case ISP_PIPELINE_STREAM_STOPPED:
1134 if (omap3isp_module_sync_idle(&sd->entity, &res->wait,
1135 &res->stopping))
1136 dev_dbg(dev, "%s: module stop timeout.\n", sd->name);
1137 omap3isp_sbl_disable(isp, OMAP3_ISP_SBL_RESIZER_READ |
1138 OMAP3_ISP_SBL_RESIZER_WRITE);
1139 omap3isp_subclk_disable(isp, OMAP3_ISP_SUBCLK_RESIZER);
1140 isp_video_dmaqueue_flags_clr(video_out);
1141 break;
1142 }
1143
1144 res->state = enable;
1145 return 0;
1146}
1147
1148/*
1149 * resizer_g_crop - handle get crop subdev operation
1150 * @sd : pointer to v4l2 subdev structure
1151 * @pad : subdev pad
1152 * @crop : pointer to crop structure
1153 * @which : active or try format
1154 * return zero
1155 */
1156static int resizer_g_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1157 struct v4l2_subdev_crop *crop)
1158{
1159 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1160 struct v4l2_mbus_framefmt *format;
1161 struct resizer_ratio ratio;
1162
1163 /* Only sink pad has crop capability */
1164 if (crop->pad != RESZ_PAD_SINK)
1165 return -EINVAL;
1166
1167 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE, crop->which);
1168 crop->rect = *__resizer_get_crop(res, fh, crop->which);
1169 resizer_calc_ratios(res, &crop->rect, format, &ratio);
1170
1171 return 0;
1172}
1173
1174/*
1175 * resizer_try_crop - mangles crop parameters.
1176 */
1177static void resizer_try_crop(const struct v4l2_mbus_framefmt *sink,
1178 const struct v4l2_mbus_framefmt *source,
1179 struct v4l2_rect *crop)
1180{
1181 const unsigned int spv = DEFAULT_PHASE;
1182 const unsigned int sph = DEFAULT_PHASE;
1183
1184 /* Crop rectangle is constrained to the output size so that zoom ratio
1185 * cannot exceed +/-4.0.
1186 */
1187 unsigned int min_width =
1188 ((32 * sph + (source->width - 1) * 64 + 16) >> 8) + 7;
1189 unsigned int min_height =
1190 ((32 * spv + (source->height - 1) * 64 + 16) >> 8) + 4;
1191 unsigned int max_width =
1192 ((64 * sph + (source->width - 1) * 1024 + 32) >> 8) + 7;
1193 unsigned int max_height =
1194 ((64 * spv + (source->height - 1) * 1024 + 32) >> 8) + 7;
1195
1196 crop->width = clamp_t(u32, crop->width, min_width, max_width);
1197 crop->height = clamp_t(u32, crop->height, min_height, max_height);
1198
1199 /* Crop can not go beyond of the input rectangle */
1200 crop->left = clamp_t(u32, crop->left, 0, sink->width - MIN_IN_WIDTH);
1201 crop->width = clamp_t(u32, crop->width, MIN_IN_WIDTH,
1202 sink->width - crop->left);
1203 crop->top = clamp_t(u32, crop->top, 0, sink->height - MIN_IN_HEIGHT);
1204 crop->height = clamp_t(u32, crop->height, MIN_IN_HEIGHT,
1205 sink->height - crop->top);
1206}
1207
1208/*
1209 * resizer_s_crop - handle set crop subdev operation
1210 * @sd : pointer to v4l2 subdev structure
1211 * @pad : subdev pad
1212 * @crop : pointer to crop structure
1213 * @which : active or try format
1214 * return -EINVAL or zero when succeed
1215 */
1216static int resizer_s_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1217 struct v4l2_subdev_crop *crop)
1218{
1219 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1220 struct isp_device *isp = to_isp_device(res);
1221 struct v4l2_mbus_framefmt *format_sink, *format_source;
1222 struct resizer_ratio ratio;
1223
1224 /* Only sink pad has crop capability */
1225 if (crop->pad != RESZ_PAD_SINK)
1226 return -EINVAL;
1227
1228 format_sink = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1229 crop->which);
1230 format_source = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1231 crop->which);
1232
1233 dev_dbg(isp->dev, "%s: L=%d,T=%d,W=%d,H=%d,which=%d\n", __func__,
1234 crop->rect.left, crop->rect.top, crop->rect.width,
1235 crop->rect.height, crop->which);
1236
1237 dev_dbg(isp->dev, "%s: input=%dx%d, output=%dx%d\n", __func__,
1238 format_sink->width, format_sink->height,
1239 format_source->width, format_source->height);
1240
1241 resizer_try_crop(format_sink, format_source, &crop->rect);
1242 *__resizer_get_crop(res, fh, crop->which) = crop->rect;
1243 resizer_calc_ratios(res, &crop->rect, format_source, &ratio);
1244
1245 if (crop->which == V4L2_SUBDEV_FORMAT_TRY)
1246 return 0;
1247
1248 res->ratio = ratio;
1249 res->crop.active = crop->rect;
1250
1251 /*
1252 * s_crop can be called while streaming is on. In this case
1253 * the crop values will be set in the next IRQ.
1254 */
1255 if (res->state != ISP_PIPELINE_STREAM_STOPPED)
1256 res->applycrop = 1;
1257
1258 return 0;
1259}
1260
1261/* resizer pixel formats */
1262static const unsigned int resizer_formats[] = {
1263 V4L2_MBUS_FMT_UYVY8_1X16,
1264 V4L2_MBUS_FMT_YUYV8_1X16,
1265};
1266
1267static unsigned int resizer_max_in_width(struct isp_res_device *res)
1268{
1269 struct isp_device *isp = to_isp_device(res);
1270
1271 if (res->input == RESIZER_INPUT_MEMORY) {
1272 return MAX_IN_WIDTH_MEMORY_MODE;
1273 } else {
1274 if (isp->revision == ISP_REVISION_1_0)
1275 return MAX_IN_WIDTH_ONTHEFLY_MODE_ES1;
1276 else
1277 return MAX_IN_WIDTH_ONTHEFLY_MODE_ES2;
1278 }
1279}
1280
1281/*
1282 * resizer_try_format - Handle try format by pad subdev method
1283 * @res : ISP resizer device
1284 * @fh : V4L2 subdev file handle
1285 * @pad : pad num
1286 * @fmt : pointer to v4l2 format structure
1287 * @which : wanted subdev format
1288 */
1289static void resizer_try_format(struct isp_res_device *res,
1290 struct v4l2_subdev_fh *fh, unsigned int pad,
1291 struct v4l2_mbus_framefmt *fmt,
1292 enum v4l2_subdev_format_whence which)
1293{
1294 struct v4l2_mbus_framefmt *format;
1295 struct resizer_ratio ratio;
1296 struct v4l2_rect crop;
1297
1298 switch (pad) {
1299 case RESZ_PAD_SINK:
1300 if (fmt->code != V4L2_MBUS_FMT_YUYV8_1X16 &&
1301 fmt->code != V4L2_MBUS_FMT_UYVY8_1X16)
1302 fmt->code = V4L2_MBUS_FMT_YUYV8_1X16;
1303
1304 fmt->width = clamp_t(u32, fmt->width, MIN_IN_WIDTH,
1305 resizer_max_in_width(res));
1306 fmt->height = clamp_t(u32, fmt->height, MIN_IN_HEIGHT,
1307 MAX_IN_HEIGHT);
1308 break;
1309
1310 case RESZ_PAD_SOURCE:
1311 format = __resizer_get_format(res, fh, RESZ_PAD_SINK, which);
1312 fmt->code = format->code;
1313
1314 crop = *__resizer_get_crop(res, fh, which);
1315 resizer_calc_ratios(res, &crop, fmt, &ratio);
1316 break;
1317 }
1318
1319 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1320 fmt->field = V4L2_FIELD_NONE;
1321}
1322
1323/*
1324 * resizer_enum_mbus_code - Handle pixel format enumeration
1325 * @sd : pointer to v4l2 subdev structure
1326 * @fh : V4L2 subdev file handle
1327 * @code : pointer to v4l2_subdev_mbus_code_enum structure
1328 * return -EINVAL or zero on success
1329 */
1330static int resizer_enum_mbus_code(struct v4l2_subdev *sd,
1331 struct v4l2_subdev_fh *fh,
1332 struct v4l2_subdev_mbus_code_enum *code)
1333{
1334 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1335 struct v4l2_mbus_framefmt *format;
1336
1337 if (code->pad == RESZ_PAD_SINK) {
1338 if (code->index >= ARRAY_SIZE(resizer_formats))
1339 return -EINVAL;
1340
1341 code->code = resizer_formats[code->index];
1342 } else {
1343 if (code->index != 0)
1344 return -EINVAL;
1345
1346 format = __resizer_get_format(res, fh, RESZ_PAD_SINK,
1347 V4L2_SUBDEV_FORMAT_TRY);
1348 code->code = format->code;
1349 }
1350
1351 return 0;
1352}
1353
1354static int resizer_enum_frame_size(struct v4l2_subdev *sd,
1355 struct v4l2_subdev_fh *fh,
1356 struct v4l2_subdev_frame_size_enum *fse)
1357{
1358 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1359 struct v4l2_mbus_framefmt format;
1360
1361 if (fse->index != 0)
1362 return -EINVAL;
1363
1364 format.code = fse->code;
1365 format.width = 1;
1366 format.height = 1;
1367 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1368 fse->min_width = format.width;
1369 fse->min_height = format.height;
1370
1371 if (format.code != fse->code)
1372 return -EINVAL;
1373
1374 format.code = fse->code;
1375 format.width = -1;
1376 format.height = -1;
1377 resizer_try_format(res, fh, fse->pad, &format, V4L2_SUBDEV_FORMAT_TRY);
1378 fse->max_width = format.width;
1379 fse->max_height = format.height;
1380
1381 return 0;
1382}
1383
1384/*
1385 * resizer_get_format - Handle get format by pads subdev method
1386 * @sd : pointer to v4l2 subdev structure
1387 * @fh : V4L2 subdev file handle
1388 * @fmt : pointer to v4l2 subdev format structure
1389 * return -EINVAL or zero on sucess
1390 */
1391static int resizer_get_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1392 struct v4l2_subdev_format *fmt)
1393{
1394 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1395 struct v4l2_mbus_framefmt *format;
1396
1397 format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
1398 if (format == NULL)
1399 return -EINVAL;
1400
1401 fmt->format = *format;
1402 return 0;
1403}
1404
1405/*
1406 * resizer_set_format - Handle set format by pads subdev method
1407 * @sd : pointer to v4l2 subdev structure
1408 * @fh : V4L2 subdev file handle
1409 * @fmt : pointer to v4l2 subdev format structure
1410 * return -EINVAL or zero on success
1411 */
1412static int resizer_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1413 struct v4l2_subdev_format *fmt)
1414{
1415 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1416 struct v4l2_mbus_framefmt *format;
1417 struct v4l2_rect *crop;
1418
1419 format = __resizer_get_format(res, fh, fmt->pad, fmt->which);
1420 if (format == NULL)
1421 return -EINVAL;
1422
1423 resizer_try_format(res, fh, fmt->pad, &fmt->format, fmt->which);
1424 *format = fmt->format;
1425
1426 if (fmt->pad == RESZ_PAD_SINK) {
1427 /* reset crop rectangle */
1428 crop = __resizer_get_crop(res, fh, fmt->which);
1429 crop->left = 0;
1430 crop->top = 0;
1431 crop->width = fmt->format.width;
1432 crop->height = fmt->format.height;
1433
1434 /* Propagate the format from sink to source */
1435 format = __resizer_get_format(res, fh, RESZ_PAD_SOURCE,
1436 fmt->which);
1437 *format = fmt->format;
1438 resizer_try_format(res, fh, RESZ_PAD_SOURCE, format,
1439 fmt->which);
1440 }
1441
1442 if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1443 /* Compute and store the active crop rectangle and resizer
1444 * ratios. format already points to the source pad active
1445 * format.
1446 */
1447 res->crop.active = res->crop.request;
1448 resizer_calc_ratios(res, &res->crop.active, format,
1449 &res->ratio);
1450 }
1451
1452 return 0;
1453}
1454
1455/*
1456 * resizer_init_formats - Initialize formats on all pads
1457 * @sd: ISP resizer V4L2 subdevice
1458 * @fh: V4L2 subdev file handle
1459 *
1460 * Initialize all pad formats with default values. If fh is not NULL, try
1461 * formats are initialized on the file handle. Otherwise active formats are
1462 * initialized on the device.
1463 */
1464static int resizer_init_formats(struct v4l2_subdev *sd,
1465 struct v4l2_subdev_fh *fh)
1466{
1467 struct v4l2_subdev_format format;
1468
1469 memset(&format, 0, sizeof(format));
1470 format.pad = RESZ_PAD_SINK;
1471 format.which = fh ? V4L2_SUBDEV_FORMAT_TRY : V4L2_SUBDEV_FORMAT_ACTIVE;
1472 format.format.code = V4L2_MBUS_FMT_YUYV8_1X16;
1473 format.format.width = 4096;
1474 format.format.height = 4096;
1475 resizer_set_format(sd, fh, &format);
1476
1477 return 0;
1478}
1479
1480/* subdev video operations */
1481static const struct v4l2_subdev_video_ops resizer_v4l2_video_ops = {
1482 .s_stream = resizer_set_stream,
1483};
1484
1485/* subdev pad operations */
1486static const struct v4l2_subdev_pad_ops resizer_v4l2_pad_ops = {
1487 .enum_mbus_code = resizer_enum_mbus_code,
1488 .enum_frame_size = resizer_enum_frame_size,
1489 .get_fmt = resizer_get_format,
1490 .set_fmt = resizer_set_format,
1491 .get_crop = resizer_g_crop,
1492 .set_crop = resizer_s_crop,
1493};
1494
1495/* subdev operations */
1496static const struct v4l2_subdev_ops resizer_v4l2_ops = {
1497 .video = &resizer_v4l2_video_ops,
1498 .pad = &resizer_v4l2_pad_ops,
1499};
1500
1501/* subdev internal operations */
1502static const struct v4l2_subdev_internal_ops resizer_v4l2_internal_ops = {
1503 .open = resizer_init_formats,
1504};
1505
1506/* -----------------------------------------------------------------------------
1507 * Media entity operations
1508 */
1509
1510/*
1511 * resizer_link_setup - Setup resizer connections.
1512 * @entity : Pointer to media entity structure
1513 * @local : Pointer to local pad array
1514 * @remote : Pointer to remote pad array
1515 * @flags : Link flags
1516 * return -EINVAL or zero on success
1517 */
1518static int resizer_link_setup(struct media_entity *entity,
1519 const struct media_pad *local,
1520 const struct media_pad *remote, u32 flags)
1521{
1522 struct v4l2_subdev *sd = media_entity_to_v4l2_subdev(entity);
1523 struct isp_res_device *res = v4l2_get_subdevdata(sd);
1524
1525 switch (local->index | media_entity_type(remote->entity)) {
1526 case RESZ_PAD_SINK | MEDIA_ENT_T_DEVNODE:
1527 /* read from memory */
1528 if (flags & MEDIA_LNK_FL_ENABLED) {
1529 if (res->input == RESIZER_INPUT_VP)
1530 return -EBUSY;
1531 res->input = RESIZER_INPUT_MEMORY;
1532 } else {
1533 if (res->input == RESIZER_INPUT_MEMORY)
1534 res->input = RESIZER_INPUT_NONE;
1535 }
1536 break;
1537
1538 case RESZ_PAD_SINK | MEDIA_ENT_T_V4L2_SUBDEV:
1539 /* read from ccdc or previewer */
1540 if (flags & MEDIA_LNK_FL_ENABLED) {
1541 if (res->input == RESIZER_INPUT_MEMORY)
1542 return -EBUSY;
1543 res->input = RESIZER_INPUT_VP;
1544 } else {
1545 if (res->input == RESIZER_INPUT_VP)
1546 res->input = RESIZER_INPUT_NONE;
1547 }
1548 break;
1549
1550 case RESZ_PAD_SOURCE | MEDIA_ENT_T_DEVNODE:
1551 /* resizer always write to memory */
1552 break;
1553
1554 default:
1555 return -EINVAL;
1556 }
1557
1558 return 0;
1559}
1560
1561/* media operations */
1562static const struct media_entity_operations resizer_media_ops = {
1563 .link_setup = resizer_link_setup,
1564};
1565
1566/*
1567 * resizer_init_entities - Initialize resizer subdev and media entity.
1568 * @res : Pointer to resizer device structure
1569 * return -ENOMEM or zero on success
1570 */
1571static int resizer_init_entities(struct isp_res_device *res)
1572{
1573 struct v4l2_subdev *sd = &res->subdev;
1574 struct media_pad *pads = res->pads;
1575 struct media_entity *me = &sd->entity;
1576 int ret;
1577
1578 res->input = RESIZER_INPUT_NONE;
1579
1580 v4l2_subdev_init(sd, &resizer_v4l2_ops);
1581 sd->internal_ops = &resizer_v4l2_internal_ops;
1582 strlcpy(sd->name, "OMAP3 ISP resizer", sizeof(sd->name));
1583 sd->grp_id = 1 << 16; /* group ID for isp subdevs */
1584 v4l2_set_subdevdata(sd, res);
1585 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1586
1587 pads[RESZ_PAD_SINK].flags = MEDIA_PAD_FL_SINK;
1588 pads[RESZ_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
1589
1590 me->ops = &resizer_media_ops;
1591 ret = media_entity_init(me, RESZ_PADS_NUM, pads, 0);
1592 if (ret < 0)
1593 return ret;
1594
1595 resizer_init_formats(sd, NULL);
1596
1597 res->video_in.type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
1598 res->video_in.ops = &resizer_video_ops;
1599 res->video_in.isp = to_isp_device(res);
1600 res->video_in.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
1601 res->video_in.bpl_alignment = 32;
1602 res->video_out.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1603 res->video_out.ops = &resizer_video_ops;
1604 res->video_out.isp = to_isp_device(res);
1605 res->video_out.capture_mem = PAGE_ALIGN(4096 * 4096) * 2 * 3;
1606 res->video_out.bpl_alignment = 32;
1607
1608 ret = omap3isp_video_init(&res->video_in, "resizer");
1609 if (ret < 0)
1610 return ret;
1611
1612 ret = omap3isp_video_init(&res->video_out, "resizer");
1613 if (ret < 0)
1614 return ret;
1615
1616 /* Connect the video nodes to the resizer subdev. */
1617 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1618 &res->subdev.entity, RESZ_PAD_SINK, 0);
1619 if (ret < 0)
1620 return ret;
1621
1622 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1623 &res->video_out.video.entity, 0, 0);
1624 if (ret < 0)
1625 return ret;
1626
1627 return 0;
1628}
1629
1630void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
1631{
1632 media_entity_cleanup(&res->subdev.entity);
1633
1634 v4l2_device_unregister_subdev(&res->subdev);
1635 omap3isp_video_unregister(&res->video_in);
1636 omap3isp_video_unregister(&res->video_out);
1637}
1638
1639int omap3isp_resizer_register_entities(struct isp_res_device *res,
1640 struct v4l2_device *vdev)
1641{
1642 int ret;
1643
1644 /* Register the subdev and video nodes. */
1645 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1646 if (ret < 0)
1647 goto error;
1648
1649 ret = omap3isp_video_register(&res->video_in, vdev);
1650 if (ret < 0)
1651 goto error;
1652
1653 ret = omap3isp_video_register(&res->video_out, vdev);
1654 if (ret < 0)
1655 goto error;
1656
1657 return 0;
1658
1659error:
1660 omap3isp_resizer_unregister_entities(res);
1661 return ret;
1662}
1663
1664/* -----------------------------------------------------------------------------
1665 * ISP resizer initialization and cleanup
1666 */
1667
1668void omap3isp_resizer_cleanup(struct isp_device *isp)
1669{
1670}
1671
1672/*
1673 * isp_resizer_init - Resizer initialization.
1674 * @isp : Pointer to ISP device
1675 * return -ENOMEM or zero on success
1676 */
1677int omap3isp_resizer_init(struct isp_device *isp)
1678{
1679 struct isp_res_device *res = &isp->isp_res;
1680 int ret;
1681
1682 init_waitqueue_head(&res->wait);
1683 atomic_set(&res->stopping, 0);
1684 ret = resizer_init_entities(res);
1685 if (ret < 0)
1686 goto out;
1687
1688out:
1689 if (ret)
1690 omap3isp_resizer_cleanup(isp);
1691
1692 return ret;
1693}
diff --git a/drivers/media/video/omap3isp/ispresizer.h b/drivers/media/video/omap3isp/ispresizer.h
new file mode 100644
index 000000000000..76abc2e42126
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispresizer.h
@@ -0,0 +1,147 @@
1/*
2 * ispresizer.h
3 *
4 * TI OMAP3 ISP - Resizer module
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_RESIZER_H
28#define OMAP3_ISP_RESIZER_H
29
30#include <linux/types.h>
31
32/*
33 * Constants for filter coefficents count
34 */
35#define COEFF_CNT 32
36
37/*
38 * struct isprsz_coef - Structure for resizer filter coeffcients.
39 * @h_filter_coef_4tap: Horizontal filter coefficients for 8-phase/4-tap
40 * mode (.5x-4x)
41 * @v_filter_coef_4tap: Vertical filter coefficients for 8-phase/4-tap
42 * mode (.5x-4x)
43 * @h_filter_coef_7tap: Horizontal filter coefficients for 4-phase/7-tap
44 * mode (.25x-.5x)
45 * @v_filter_coef_7tap: Vertical filter coefficients for 4-phase/7-tap
46 * mode (.25x-.5x)
47 */
48struct isprsz_coef {
49 u16 h_filter_coef_4tap[32];
50 u16 v_filter_coef_4tap[32];
51 /* Every 8th value is a dummy value in the following arrays: */
52 u16 h_filter_coef_7tap[32];
53 u16 v_filter_coef_7tap[32];
54};
55
56/* Chrominance horizontal algorithm */
57enum resizer_chroma_algo {
58 RSZ_THE_SAME = 0, /* Chrominance the same as Luminance */
59 RSZ_BILINEAR = 1, /* Chrominance uses bilinear interpolation */
60};
61
62/* Resizer input type select */
63enum resizer_colors_type {
64 RSZ_YUV422 = 0, /* YUV422 color is interleaved */
65 RSZ_COLOR8 = 1, /* Color separate data on 8 bits */
66};
67
68/*
69 * Structure for horizontal and vertical resizing value
70 */
71struct resizer_ratio {
72 u32 horz;
73 u32 vert;
74};
75
76/*
77 * Structure for luminance enhancer parameters.
78 */
79struct resizer_luma_yenh {
80 u8 algo; /* algorithm select. */
81 u8 gain; /* maximum gain. */
82 u8 slope; /* slope. */
83 u8 core; /* core offset. */
84};
85
86enum resizer_input_entity {
87 RESIZER_INPUT_NONE,
88 RESIZER_INPUT_VP, /* input video port - prev or ccdc */
89 RESIZER_INPUT_MEMORY,
90};
91
92/* Sink and source resizer pads */
93#define RESZ_PAD_SINK 0
94#define RESZ_PAD_SOURCE 1
95#define RESZ_PADS_NUM 2
96
97/*
98 * struct isp_res_device - OMAP3 ISP resizer module
99 * @crop.request: Crop rectangle requested by the user
100 * @crop.active: Active crop rectangle (based on hardware requirements)
101 */
102struct isp_res_device {
103 struct v4l2_subdev subdev;
104 struct media_pad pads[RESZ_PADS_NUM];
105 struct v4l2_mbus_framefmt formats[RESZ_PADS_NUM];
106
107 enum resizer_input_entity input;
108 struct isp_video video_in;
109 struct isp_video video_out;
110 unsigned int error;
111
112 u32 addr_base; /* stored source buffer address in memory mode */
113 u32 crop_offset; /* additional offset for crop in memory mode */
114 struct resizer_ratio ratio;
115 int pm_state;
116 unsigned int applycrop:1;
117 enum isp_pipeline_stream_state state;
118 wait_queue_head_t wait;
119 atomic_t stopping;
120
121 struct {
122 struct v4l2_rect request;
123 struct v4l2_rect active;
124 } crop;
125};
126
127struct isp_device;
128
129int omap3isp_resizer_init(struct isp_device *isp);
130void omap3isp_resizer_cleanup(struct isp_device *isp);
131
132int omap3isp_resizer_register_entities(struct isp_res_device *res,
133 struct v4l2_device *vdev);
134void omap3isp_resizer_unregister_entities(struct isp_res_device *res);
135void omap3isp_resizer_isr_frame_sync(struct isp_res_device *res);
136void omap3isp_resizer_isr(struct isp_res_device *isp_res);
137
138void omap3isp_resizer_max_rate(struct isp_res_device *res,
139 unsigned int *max_rate);
140
141void omap3isp_resizer_suspend(struct isp_res_device *isp_res);
142
143void omap3isp_resizer_resume(struct isp_res_device *isp_res);
144
145int omap3isp_resizer_busy(struct isp_res_device *isp_res);
146
147#endif /* OMAP3_ISP_RESIZER_H */
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
new file mode 100644
index 000000000000..b44cb685236a
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -0,0 +1,1092 @@
1/*
2 * ispstat.c
3 *
4 * TI OMAP3 ISP - Statistics core
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#include <linux/dma-mapping.h>
29#include <linux/slab.h>
30#include <linux/uaccess.h>
31
32#include "isp.h"
33
34#define IS_COHERENT_BUF(stat) ((stat)->dma_ch >= 0)
35
36/*
37 * MAGIC_SIZE must always be the greatest common divisor of
38 * AEWB_PACKET_SIZE and AF_PAXEL_SIZE.
39 */
40#define MAGIC_SIZE 16
41#define MAGIC_NUM 0x55
42
43/* HACK: AF module seems to be writing one more paxel data than it should. */
44#define AF_EXTRA_DATA OMAP3ISP_AF_PAXEL_SIZE
45
46/*
47 * HACK: H3A modules go to an invalid state after have a SBL overflow. It makes
48 * the next buffer to start to be written in the same point where the overflow
49 * occurred instead of the configured address. The only known way to make it to
50 * go back to a valid state is having a valid buffer processing. Of course it
51 * requires at least a doubled buffer size to avoid an access to invalid memory
52 * region. But it does not fix everything. It may happen more than one
53 * consecutive SBL overflows. In that case, it might be unpredictable how many
54 * buffers the allocated memory should fit. For that case, a recover
55 * configuration was created. It produces the minimum buffer size for each H3A
56 * module and decrease the change for more SBL overflows. This recover state
57 * will be enabled every time a SBL overflow occur. As the output buffer size
58 * isn't big, it's possible to have an extra size able to fit many recover
59 * buffers making it extreamily unlikely to have an access to invalid memory
60 * region.
61 */
62#define NUM_H3A_RECOVER_BUFS 10
63
64/*
65 * HACK: Because of HW issues the generic layer sometimes need to have
66 * different behaviour for different statistic modules.
67 */
68#define IS_H3A_AF(stat) ((stat) == &(stat)->isp->isp_af)
69#define IS_H3A_AEWB(stat) ((stat) == &(stat)->isp->isp_aewb)
70#define IS_H3A(stat) (IS_H3A_AF(stat) || IS_H3A_AEWB(stat))
71
72static void __isp_stat_buf_sync_magic(struct ispstat *stat,
73 struct ispstat_buffer *buf,
74 u32 buf_size, enum dma_data_direction dir,
75 void (*dma_sync)(struct device *,
76 dma_addr_t, unsigned long, size_t,
77 enum dma_data_direction))
78{
79 struct device *dev = stat->isp->dev;
80 struct page *pg;
81 dma_addr_t dma_addr;
82 u32 offset;
83
84 /* Initial magic words */
85 pg = vmalloc_to_page(buf->virt_addr);
86 dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
87 dma_sync(dev, dma_addr, 0, MAGIC_SIZE, dir);
88
89 /* Final magic words */
90 pg = vmalloc_to_page(buf->virt_addr + buf_size);
91 dma_addr = pfn_to_dma(dev, page_to_pfn(pg));
92 offset = ((u32)buf->virt_addr + buf_size) & ~PAGE_MASK;
93 dma_sync(dev, dma_addr, offset, MAGIC_SIZE, dir);
94}
95
96static void isp_stat_buf_sync_magic_for_device(struct ispstat *stat,
97 struct ispstat_buffer *buf,
98 u32 buf_size,
99 enum dma_data_direction dir)
100{
101 if (IS_COHERENT_BUF(stat))
102 return;
103
104 __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
105 dma_sync_single_range_for_device);
106}
107
108static void isp_stat_buf_sync_magic_for_cpu(struct ispstat *stat,
109 struct ispstat_buffer *buf,
110 u32 buf_size,
111 enum dma_data_direction dir)
112{
113 if (IS_COHERENT_BUF(stat))
114 return;
115
116 __isp_stat_buf_sync_magic(stat, buf, buf_size, dir,
117 dma_sync_single_range_for_cpu);
118}
119
120static int isp_stat_buf_check_magic(struct ispstat *stat,
121 struct ispstat_buffer *buf)
122{
123 const u32 buf_size = IS_H3A_AF(stat) ?
124 buf->buf_size + AF_EXTRA_DATA : buf->buf_size;
125 u8 *w;
126 u8 *end;
127 int ret = -EINVAL;
128
129 isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
130
131 /* Checking initial magic numbers. They shouldn't be here anymore. */
132 for (w = buf->virt_addr, end = w + MAGIC_SIZE; w < end; w++)
133 if (likely(*w != MAGIC_NUM))
134 ret = 0;
135
136 if (ret) {
137 dev_dbg(stat->isp->dev, "%s: beginning magic check does not "
138 "match.\n", stat->subdev.name);
139 return ret;
140 }
141
142 /* Checking magic numbers at the end. They must be still here. */
143 for (w = buf->virt_addr + buf_size, end = w + MAGIC_SIZE;
144 w < end; w++) {
145 if (unlikely(*w != MAGIC_NUM)) {
146 dev_dbg(stat->isp->dev, "%s: endding magic check does "
147 "not match.\n", stat->subdev.name);
148 return -EINVAL;
149 }
150 }
151
152 isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
153 DMA_FROM_DEVICE);
154
155 return 0;
156}
157
158static void isp_stat_buf_insert_magic(struct ispstat *stat,
159 struct ispstat_buffer *buf)
160{
161 const u32 buf_size = IS_H3A_AF(stat) ?
162 stat->buf_size + AF_EXTRA_DATA : stat->buf_size;
163
164 isp_stat_buf_sync_magic_for_cpu(stat, buf, buf_size, DMA_FROM_DEVICE);
165
166 /*
167 * Inserting MAGIC_NUM at the beginning and end of the buffer.
168 * buf->buf_size is set only after the buffer is queued. For now the
169 * right buf_size for the current configuration is pointed by
170 * stat->buf_size.
171 */
172 memset(buf->virt_addr, MAGIC_NUM, MAGIC_SIZE);
173 memset(buf->virt_addr + buf_size, MAGIC_NUM, MAGIC_SIZE);
174
175 isp_stat_buf_sync_magic_for_device(stat, buf, buf_size,
176 DMA_BIDIRECTIONAL);
177}
178
179static void isp_stat_buf_sync_for_device(struct ispstat *stat,
180 struct ispstat_buffer *buf)
181{
182 if (IS_COHERENT_BUF(stat))
183 return;
184
185 dma_sync_sg_for_device(stat->isp->dev, buf->iovm->sgt->sgl,
186 buf->iovm->sgt->nents, DMA_FROM_DEVICE);
187}
188
189static void isp_stat_buf_sync_for_cpu(struct ispstat *stat,
190 struct ispstat_buffer *buf)
191{
192 if (IS_COHERENT_BUF(stat))
193 return;
194
195 dma_sync_sg_for_cpu(stat->isp->dev, buf->iovm->sgt->sgl,
196 buf->iovm->sgt->nents, DMA_FROM_DEVICE);
197}
198
199static void isp_stat_buf_clear(struct ispstat *stat)
200{
201 int i;
202
203 for (i = 0; i < STAT_MAX_BUFS; i++)
204 stat->buf[i].empty = 1;
205}
206
207static struct ispstat_buffer *
208__isp_stat_buf_find(struct ispstat *stat, int look_empty)
209{
210 struct ispstat_buffer *found = NULL;
211 int i;
212
213 for (i = 0; i < STAT_MAX_BUFS; i++) {
214 struct ispstat_buffer *curr = &stat->buf[i];
215
216 /*
217 * Don't select the buffer which is being copied to
218 * userspace or used by the module.
219 */
220 if (curr == stat->locked_buf || curr == stat->active_buf)
221 continue;
222
223 /* Don't select uninitialised buffers if it's not required */
224 if (!look_empty && curr->empty)
225 continue;
226
227 /* Pick uninitialised buffer over anything else if look_empty */
228 if (curr->empty) {
229 found = curr;
230 break;
231 }
232
233 /* Choose the oldest buffer */
234 if (!found ||
235 (s32)curr->frame_number - (s32)found->frame_number < 0)
236 found = curr;
237 }
238
239 return found;
240}
241
242static inline struct ispstat_buffer *
243isp_stat_buf_find_oldest(struct ispstat *stat)
244{
245 return __isp_stat_buf_find(stat, 0);
246}
247
248static inline struct ispstat_buffer *
249isp_stat_buf_find_oldest_or_empty(struct ispstat *stat)
250{
251 return __isp_stat_buf_find(stat, 1);
252}
253
254static int isp_stat_buf_queue(struct ispstat *stat)
255{
256 if (!stat->active_buf)
257 return STAT_NO_BUF;
258
259 do_gettimeofday(&stat->active_buf->ts);
260
261 stat->active_buf->buf_size = stat->buf_size;
262 if (isp_stat_buf_check_magic(stat, stat->active_buf)) {
263 dev_dbg(stat->isp->dev, "%s: data wasn't properly written.\n",
264 stat->subdev.name);
265 return STAT_NO_BUF;
266 }
267 stat->active_buf->config_counter = stat->config_counter;
268 stat->active_buf->frame_number = stat->frame_number;
269 stat->active_buf->empty = 0;
270 stat->active_buf = NULL;
271
272 return STAT_BUF_DONE;
273}
274
275/* Get next free buffer to write the statistics to and mark it active. */
276static void isp_stat_buf_next(struct ispstat *stat)
277{
278 if (unlikely(stat->active_buf))
279 /* Overwriting unused active buffer */
280 dev_dbg(stat->isp->dev, "%s: new buffer requested without "
281 "queuing active one.\n",
282 stat->subdev.name);
283 else
284 stat->active_buf = isp_stat_buf_find_oldest_or_empty(stat);
285}
286
287static void isp_stat_buf_release(struct ispstat *stat)
288{
289 unsigned long flags;
290
291 isp_stat_buf_sync_for_device(stat, stat->locked_buf);
292 spin_lock_irqsave(&stat->isp->stat_lock, flags);
293 stat->locked_buf = NULL;
294 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
295}
296
297/* Get buffer to userspace. */
298static struct ispstat_buffer *isp_stat_buf_get(struct ispstat *stat,
299 struct omap3isp_stat_data *data)
300{
301 int rval = 0;
302 unsigned long flags;
303 struct ispstat_buffer *buf;
304
305 spin_lock_irqsave(&stat->isp->stat_lock, flags);
306
307 while (1) {
308 buf = isp_stat_buf_find_oldest(stat);
309 if (!buf) {
310 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
311 dev_dbg(stat->isp->dev, "%s: cannot find a buffer.\n",
312 stat->subdev.name);
313 return ERR_PTR(-EBUSY);
314 }
315 if (isp_stat_buf_check_magic(stat, buf)) {
316 dev_dbg(stat->isp->dev, "%s: current buffer has "
317 "corrupted data\n.", stat->subdev.name);
318 /* Mark empty because it doesn't have valid data. */
319 buf->empty = 1;
320 } else {
321 /* Buffer isn't corrupted. */
322 break;
323 }
324 }
325
326 stat->locked_buf = buf;
327
328 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
329
330 if (buf->buf_size > data->buf_size) {
331 dev_warn(stat->isp->dev, "%s: userspace's buffer size is "
332 "not enough.\n", stat->subdev.name);
333 isp_stat_buf_release(stat);
334 return ERR_PTR(-EINVAL);
335 }
336
337 isp_stat_buf_sync_for_cpu(stat, buf);
338
339 rval = copy_to_user(data->buf,
340 buf->virt_addr,
341 buf->buf_size);
342
343 if (rval) {
344 dev_info(stat->isp->dev,
345 "%s: failed copying %d bytes of stat data\n",
346 stat->subdev.name, rval);
347 buf = ERR_PTR(-EFAULT);
348 isp_stat_buf_release(stat);
349 }
350
351 return buf;
352}
353
354static void isp_stat_bufs_free(struct ispstat *stat)
355{
356 struct isp_device *isp = stat->isp;
357 int i;
358
359 for (i = 0; i < STAT_MAX_BUFS; i++) {
360 struct ispstat_buffer *buf = &stat->buf[i];
361
362 if (!IS_COHERENT_BUF(stat)) {
363 if (IS_ERR_OR_NULL((void *)buf->iommu_addr))
364 continue;
365 if (buf->iovm)
366 dma_unmap_sg(isp->dev, buf->iovm->sgt->sgl,
367 buf->iovm->sgt->nents,
368 DMA_FROM_DEVICE);
369 iommu_vfree(isp->iommu, buf->iommu_addr);
370 } else {
371 if (!buf->virt_addr)
372 continue;
373 dma_free_coherent(stat->isp->dev, stat->buf_alloc_size,
374 buf->virt_addr, buf->dma_addr);
375 }
376 buf->iommu_addr = 0;
377 buf->iovm = NULL;
378 buf->dma_addr = 0;
379 buf->virt_addr = NULL;
380 buf->empty = 1;
381 }
382
383 dev_dbg(stat->isp->dev, "%s: all buffers were freed.\n",
384 stat->subdev.name);
385
386 stat->buf_alloc_size = 0;
387 stat->active_buf = NULL;
388}
389
390static int isp_stat_bufs_alloc_iommu(struct ispstat *stat, unsigned int size)
391{
392 struct isp_device *isp = stat->isp;
393 int i;
394
395 stat->buf_alloc_size = size;
396
397 for (i = 0; i < STAT_MAX_BUFS; i++) {
398 struct ispstat_buffer *buf = &stat->buf[i];
399 struct iovm_struct *iovm;
400
401 WARN_ON(buf->dma_addr);
402 buf->iommu_addr = iommu_vmalloc(isp->iommu, 0, size,
403 IOMMU_FLAG);
404 if (IS_ERR((void *)buf->iommu_addr)) {
405 dev_err(stat->isp->dev,
406 "%s: Can't acquire memory for "
407 "buffer %d\n", stat->subdev.name, i);
408 isp_stat_bufs_free(stat);
409 return -ENOMEM;
410 }
411
412 iovm = find_iovm_area(isp->iommu, buf->iommu_addr);
413 if (!iovm ||
414 !dma_map_sg(isp->dev, iovm->sgt->sgl, iovm->sgt->nents,
415 DMA_FROM_DEVICE)) {
416 isp_stat_bufs_free(stat);
417 return -ENOMEM;
418 }
419 buf->iovm = iovm;
420
421 buf->virt_addr = da_to_va(stat->isp->iommu,
422 (u32)buf->iommu_addr);
423 buf->empty = 1;
424 dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
425 "iommu_addr=0x%08lx virt_addr=0x%08lx",
426 stat->subdev.name, i, buf->iommu_addr,
427 (unsigned long)buf->virt_addr);
428 }
429
430 return 0;
431}
432
433static int isp_stat_bufs_alloc_dma(struct ispstat *stat, unsigned int size)
434{
435 int i;
436
437 stat->buf_alloc_size = size;
438
439 for (i = 0; i < STAT_MAX_BUFS; i++) {
440 struct ispstat_buffer *buf = &stat->buf[i];
441
442 WARN_ON(buf->iommu_addr);
443 buf->virt_addr = dma_alloc_coherent(stat->isp->dev, size,
444 &buf->dma_addr, GFP_KERNEL | GFP_DMA);
445
446 if (!buf->virt_addr || !buf->dma_addr) {
447 dev_info(stat->isp->dev,
448 "%s: Can't acquire memory for "
449 "DMA buffer %d\n", stat->subdev.name, i);
450 isp_stat_bufs_free(stat);
451 return -ENOMEM;
452 }
453 buf->empty = 1;
454
455 dev_dbg(stat->isp->dev, "%s: buffer[%d] allocated."
456 "dma_addr=0x%08lx virt_addr=0x%08lx\n",
457 stat->subdev.name, i, (unsigned long)buf->dma_addr,
458 (unsigned long)buf->virt_addr);
459 }
460
461 return 0;
462}
463
464static int isp_stat_bufs_alloc(struct ispstat *stat, u32 size)
465{
466 unsigned long flags;
467
468 spin_lock_irqsave(&stat->isp->stat_lock, flags);
469
470 BUG_ON(stat->locked_buf != NULL);
471
472 /* Are the old buffers big enough? */
473 if (stat->buf_alloc_size >= size) {
474 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
475 return 0;
476 }
477
478 if (stat->state != ISPSTAT_DISABLED || stat->buf_processing) {
479 dev_info(stat->isp->dev,
480 "%s: trying to allocate memory when busy\n",
481 stat->subdev.name);
482 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
483 return -EBUSY;
484 }
485
486 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
487
488 isp_stat_bufs_free(stat);
489
490 if (IS_COHERENT_BUF(stat))
491 return isp_stat_bufs_alloc_dma(stat, size);
492 else
493 return isp_stat_bufs_alloc_iommu(stat, size);
494}
495
496static void isp_stat_queue_event(struct ispstat *stat, int err)
497{
498 struct video_device *vdev = &stat->subdev.devnode;
499 struct v4l2_event event;
500 struct omap3isp_stat_event_status *status = (void *)event.u.data;
501
502 memset(&event, 0, sizeof(event));
503 if (!err) {
504 status->frame_number = stat->frame_number;
505 status->config_counter = stat->config_counter;
506 } else {
507 status->buf_err = 1;
508 }
509 event.type = stat->event_type;
510 v4l2_event_queue(vdev, &event);
511}
512
513
514/*
515 * omap3isp_stat_request_statistics - Request statistics.
516 * @data: Pointer to return statistics data.
517 *
518 * Returns 0 if successful.
519 */
520int omap3isp_stat_request_statistics(struct ispstat *stat,
521 struct omap3isp_stat_data *data)
522{
523 struct ispstat_buffer *buf;
524
525 if (stat->state != ISPSTAT_ENABLED) {
526 dev_dbg(stat->isp->dev, "%s: engine not enabled.\n",
527 stat->subdev.name);
528 return -EINVAL;
529 }
530
531 mutex_lock(&stat->ioctl_lock);
532 buf = isp_stat_buf_get(stat, data);
533 if (IS_ERR(buf)) {
534 mutex_unlock(&stat->ioctl_lock);
535 return PTR_ERR(buf);
536 }
537
538 data->ts = buf->ts;
539 data->config_counter = buf->config_counter;
540 data->frame_number = buf->frame_number;
541 data->buf_size = buf->buf_size;
542
543 buf->empty = 1;
544 isp_stat_buf_release(stat);
545 mutex_unlock(&stat->ioctl_lock);
546
547 return 0;
548}
549
550/*
551 * omap3isp_stat_config - Receives new statistic engine configuration.
552 * @new_conf: Pointer to config structure.
553 *
554 * Returns 0 if successful, -EINVAL if new_conf pointer is NULL, -ENOMEM if
555 * was unable to allocate memory for the buffer, or other errors if parameters
556 * are invalid.
557 */
558int omap3isp_stat_config(struct ispstat *stat, void *new_conf)
559{
560 int ret;
561 unsigned long irqflags;
562 struct ispstat_generic_config *user_cfg = new_conf;
563 u32 buf_size = user_cfg->buf_size;
564
565 if (!new_conf) {
566 dev_dbg(stat->isp->dev, "%s: configuration is NULL\n",
567 stat->subdev.name);
568 return -EINVAL;
569 }
570
571 mutex_lock(&stat->ioctl_lock);
572
573 dev_dbg(stat->isp->dev, "%s: configuring module with buffer "
574 "size=0x%08lx\n", stat->subdev.name, (unsigned long)buf_size);
575
576 ret = stat->ops->validate_params(stat, new_conf);
577 if (ret) {
578 mutex_unlock(&stat->ioctl_lock);
579 dev_dbg(stat->isp->dev, "%s: configuration values are "
580 "invalid.\n", stat->subdev.name);
581 return ret;
582 }
583
584 if (buf_size != user_cfg->buf_size)
585 dev_dbg(stat->isp->dev, "%s: driver has corrected buffer size "
586 "request to 0x%08lx\n", stat->subdev.name,
587 (unsigned long)user_cfg->buf_size);
588
589 /*
590 * Hack: H3A modules may need a doubled buffer size to avoid access
591 * to a invalid memory address after a SBL overflow.
592 * The buffer size is always PAGE_ALIGNED.
593 * Hack 2: MAGIC_SIZE is added to buf_size so a magic word can be
594 * inserted at the end to data integrity check purpose.
595 * Hack 3: AF module writes one paxel data more than it should, so
596 * the buffer allocation must consider it to avoid invalid memory
597 * access.
598 * Hack 4: H3A need to allocate extra space for the recover state.
599 */
600 if (IS_H3A(stat)) {
601 buf_size = user_cfg->buf_size * 2 + MAGIC_SIZE;
602 if (IS_H3A_AF(stat))
603 /*
604 * Adding one extra paxel data size for each recover
605 * buffer + 2 regular ones.
606 */
607 buf_size += AF_EXTRA_DATA * (NUM_H3A_RECOVER_BUFS + 2);
608 if (stat->recover_priv) {
609 struct ispstat_generic_config *recover_cfg =
610 stat->recover_priv;
611 buf_size += recover_cfg->buf_size *
612 NUM_H3A_RECOVER_BUFS;
613 }
614 buf_size = PAGE_ALIGN(buf_size);
615 } else { /* Histogram */
616 buf_size = PAGE_ALIGN(user_cfg->buf_size + MAGIC_SIZE);
617 }
618
619 ret = isp_stat_bufs_alloc(stat, buf_size);
620 if (ret) {
621 mutex_unlock(&stat->ioctl_lock);
622 return ret;
623 }
624
625 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
626 stat->ops->set_params(stat, new_conf);
627 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
628
629 /*
630 * Returning the right future config_counter for this setup, so
631 * userspace can *know* when it has been applied.
632 */
633 user_cfg->config_counter = stat->config_counter + stat->inc_config;
634
635 /* Module has a valid configuration. */
636 stat->configured = 1;
637 dev_dbg(stat->isp->dev, "%s: module has been successfully "
638 "configured.\n", stat->subdev.name);
639
640 mutex_unlock(&stat->ioctl_lock);
641
642 return 0;
643}
644
645/*
646 * isp_stat_buf_process - Process statistic buffers.
647 * @buf_state: points out if buffer is ready to be processed. It's necessary
648 * because histogram needs to copy the data from internal memory
649 * before be able to process the buffer.
650 */
651static int isp_stat_buf_process(struct ispstat *stat, int buf_state)
652{
653 int ret = STAT_NO_BUF;
654
655 if (!atomic_add_unless(&stat->buf_err, -1, 0) &&
656 buf_state == STAT_BUF_DONE && stat->state == ISPSTAT_ENABLED) {
657 ret = isp_stat_buf_queue(stat);
658 isp_stat_buf_next(stat);
659 }
660
661 return ret;
662}
663
664int omap3isp_stat_pcr_busy(struct ispstat *stat)
665{
666 return stat->ops->busy(stat);
667}
668
669int omap3isp_stat_busy(struct ispstat *stat)
670{
671 return omap3isp_stat_pcr_busy(stat) | stat->buf_processing |
672 (stat->state != ISPSTAT_DISABLED);
673}
674
675/*
676 * isp_stat_pcr_enable - Disables/Enables statistic engines.
677 * @pcr_enable: 0/1 - Disables/Enables the engine.
678 *
679 * Must be called from ISP driver when the module is idle and synchronized
680 * with CCDC.
681 */
682static void isp_stat_pcr_enable(struct ispstat *stat, u8 pcr_enable)
683{
684 if ((stat->state != ISPSTAT_ENABLING &&
685 stat->state != ISPSTAT_ENABLED) && pcr_enable)
686 /* Userspace has disabled the module. Aborting. */
687 return;
688
689 stat->ops->enable(stat, pcr_enable);
690 if (stat->state == ISPSTAT_DISABLING && !pcr_enable)
691 stat->state = ISPSTAT_DISABLED;
692 else if (stat->state == ISPSTAT_ENABLING && pcr_enable)
693 stat->state = ISPSTAT_ENABLED;
694}
695
696void omap3isp_stat_suspend(struct ispstat *stat)
697{
698 unsigned long flags;
699
700 spin_lock_irqsave(&stat->isp->stat_lock, flags);
701
702 if (stat->state != ISPSTAT_DISABLED)
703 stat->ops->enable(stat, 0);
704 if (stat->state == ISPSTAT_ENABLED)
705 stat->state = ISPSTAT_SUSPENDED;
706
707 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
708}
709
710void omap3isp_stat_resume(struct ispstat *stat)
711{
712 /* Module will be re-enabled with its pipeline */
713 if (stat->state == ISPSTAT_SUSPENDED)
714 stat->state = ISPSTAT_ENABLING;
715}
716
717static void isp_stat_try_enable(struct ispstat *stat)
718{
719 unsigned long irqflags;
720
721 if (stat->priv == NULL)
722 /* driver wasn't initialised */
723 return;
724
725 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
726 if (stat->state == ISPSTAT_ENABLING && !stat->buf_processing &&
727 stat->buf_alloc_size) {
728 /*
729 * Userspace's requested to enable the engine but it wasn't yet.
730 * Let's do that now.
731 */
732 stat->update = 1;
733 isp_stat_buf_next(stat);
734 stat->ops->setup_regs(stat, stat->priv);
735 isp_stat_buf_insert_magic(stat, stat->active_buf);
736
737 /*
738 * H3A module has some hw issues which forces the driver to
739 * ignore next buffers even if it was disabled in the meantime.
740 * On the other hand, Histogram shouldn't ignore buffers anymore
741 * if it's being enabled.
742 */
743 if (!IS_H3A(stat))
744 atomic_set(&stat->buf_err, 0);
745
746 isp_stat_pcr_enable(stat, 1);
747 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
748 dev_dbg(stat->isp->dev, "%s: module is enabled.\n",
749 stat->subdev.name);
750 } else {
751 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
752 }
753}
754
755void omap3isp_stat_isr_frame_sync(struct ispstat *stat)
756{
757 isp_stat_try_enable(stat);
758}
759
760void omap3isp_stat_sbl_overflow(struct ispstat *stat)
761{
762 unsigned long irqflags;
763
764 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
765 /*
766 * Due to a H3A hw issue which prevents the next buffer to start from
767 * the correct memory address, 2 buffers must be ignored.
768 */
769 atomic_set(&stat->buf_err, 2);
770
771 /*
772 * If more than one SBL overflow happen in a row, H3A module may access
773 * invalid memory region.
774 * stat->sbl_ovl_recover is set to tell to the driver to temporarily use
775 * a soft configuration which helps to avoid consecutive overflows.
776 */
777 if (stat->recover_priv)
778 stat->sbl_ovl_recover = 1;
779 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
780}
781
782/*
783 * omap3isp_stat_enable - Disable/Enable statistic engine as soon as possible
784 * @enable: 0/1 - Disables/Enables the engine.
785 *
786 * Client should configure all the module registers before this.
787 * This function can be called from a userspace request.
788 */
789int omap3isp_stat_enable(struct ispstat *stat, u8 enable)
790{
791 unsigned long irqflags;
792
793 dev_dbg(stat->isp->dev, "%s: user wants to %s module.\n",
794 stat->subdev.name, enable ? "enable" : "disable");
795
796 /* Prevent enabling while configuring */
797 mutex_lock(&stat->ioctl_lock);
798
799 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
800
801 if (!stat->configured && enable) {
802 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
803 mutex_unlock(&stat->ioctl_lock);
804 dev_dbg(stat->isp->dev, "%s: cannot enable module as it's "
805 "never been successfully configured so far.\n",
806 stat->subdev.name);
807 return -EINVAL;
808 }
809
810 if (enable) {
811 if (stat->state == ISPSTAT_DISABLING)
812 /* Previous disabling request wasn't done yet */
813 stat->state = ISPSTAT_ENABLED;
814 else if (stat->state == ISPSTAT_DISABLED)
815 /* Module is now being enabled */
816 stat->state = ISPSTAT_ENABLING;
817 } else {
818 if (stat->state == ISPSTAT_ENABLING) {
819 /* Previous enabling request wasn't done yet */
820 stat->state = ISPSTAT_DISABLED;
821 } else if (stat->state == ISPSTAT_ENABLED) {
822 /* Module is now being disabled */
823 stat->state = ISPSTAT_DISABLING;
824 isp_stat_buf_clear(stat);
825 }
826 }
827
828 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
829 mutex_unlock(&stat->ioctl_lock);
830
831 return 0;
832}
833
834int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable)
835{
836 struct ispstat *stat = v4l2_get_subdevdata(subdev);
837
838 if (enable) {
839 /*
840 * Only set enable PCR bit if the module was previously
841 * enabled through ioct.
842 */
843 isp_stat_try_enable(stat);
844 } else {
845 unsigned long flags;
846 /* Disable PCR bit and config enable field */
847 omap3isp_stat_enable(stat, 0);
848 spin_lock_irqsave(&stat->isp->stat_lock, flags);
849 stat->ops->enable(stat, 0);
850 spin_unlock_irqrestore(&stat->isp->stat_lock, flags);
851
852 /*
853 * If module isn't busy, a new interrupt may come or not to
854 * set the state to DISABLED. As Histogram needs to read its
855 * internal memory to clear it, let interrupt handler
856 * responsible of changing state to DISABLED. If the last
857 * interrupt is coming, it's still safe as the handler will
858 * ignore the second time when state is already set to DISABLED.
859 * It's necessary to synchronize Histogram with streamoff, once
860 * the module may be considered idle before last SDMA transfer
861 * starts if we return here.
862 */
863 if (!omap3isp_stat_pcr_busy(stat))
864 omap3isp_stat_isr(stat);
865
866 dev_dbg(stat->isp->dev, "%s: module is being disabled\n",
867 stat->subdev.name);
868 }
869
870 return 0;
871}
872
873/*
874 * __stat_isr - Interrupt handler for statistic drivers
875 */
876static void __stat_isr(struct ispstat *stat, int from_dma)
877{
878 int ret = STAT_BUF_DONE;
879 int buf_processing;
880 unsigned long irqflags;
881 struct isp_pipeline *pipe;
882
883 /*
884 * stat->buf_processing must be set before disable module. It's
885 * necessary to not inform too early the buffers aren't busy in case
886 * of SDMA is going to be used.
887 */
888 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
889 if (stat->state == ISPSTAT_DISABLED) {
890 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
891 return;
892 }
893 buf_processing = stat->buf_processing;
894 stat->buf_processing = 1;
895 stat->ops->enable(stat, 0);
896
897 if (buf_processing && !from_dma) {
898 if (stat->state == ISPSTAT_ENABLED) {
899 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
900 dev_err(stat->isp->dev,
901 "%s: interrupt occurred when module was still "
902 "processing a buffer.\n", stat->subdev.name);
903 ret = STAT_NO_BUF;
904 goto out;
905 } else {
906 /*
907 * Interrupt handler was called from streamoff when
908 * the module wasn't busy anymore to ensure it is being
909 * disabled after process last buffer. If such buffer
910 * processing has already started, no need to do
911 * anything else.
912 */
913 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
914 return;
915 }
916 }
917 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
918
919 /* If it's busy we can't process this buffer anymore */
920 if (!omap3isp_stat_pcr_busy(stat)) {
921 if (!from_dma && stat->ops->buf_process)
922 /* Module still need to copy data to buffer. */
923 ret = stat->ops->buf_process(stat);
924 if (ret == STAT_BUF_WAITING_DMA)
925 /* Buffer is not ready yet */
926 return;
927
928 spin_lock_irqsave(&stat->isp->stat_lock, irqflags);
929
930 /*
931 * Histogram needs to read its internal memory to clear it
932 * before be disabled. For that reason, common statistic layer
933 * can return only after call stat's buf_process() operator.
934 */
935 if (stat->state == ISPSTAT_DISABLING) {
936 stat->state = ISPSTAT_DISABLED;
937 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
938 stat->buf_processing = 0;
939 return;
940 }
941 pipe = to_isp_pipeline(&stat->subdev.entity);
942 stat->frame_number = atomic_read(&pipe->frame_number);
943
944 /*
945 * Before this point, 'ret' stores the buffer's status if it's
946 * ready to be processed. Afterwards, it holds the status if
947 * it was processed successfully.
948 */
949 ret = isp_stat_buf_process(stat, ret);
950
951 if (likely(!stat->sbl_ovl_recover)) {
952 stat->ops->setup_regs(stat, stat->priv);
953 } else {
954 /*
955 * Using recover config to increase the chance to have
956 * a good buffer processing and make the H3A module to
957 * go back to a valid state.
958 */
959 stat->update = 1;
960 stat->ops->setup_regs(stat, stat->recover_priv);
961 stat->sbl_ovl_recover = 0;
962
963 /*
964 * Set 'update' in case of the module needs to use
965 * regular configuration after next buffer.
966 */
967 stat->update = 1;
968 }
969
970 isp_stat_buf_insert_magic(stat, stat->active_buf);
971
972 /*
973 * Hack: H3A modules may access invalid memory address or send
974 * corrupted data to userspace if more than 1 SBL overflow
975 * happens in a row without re-writing its buffer's start memory
976 * address in the meantime. Such situation is avoided if the
977 * module is not immediately re-enabled when the ISR misses the
978 * timing to process the buffer and to setup the registers.
979 * Because of that, pcr_enable(1) was moved to inside this 'if'
980 * block. But the next interruption will still happen as during
981 * pcr_enable(0) the module was busy.
982 */
983 isp_stat_pcr_enable(stat, 1);
984 spin_unlock_irqrestore(&stat->isp->stat_lock, irqflags);
985 } else {
986 /*
987 * If a SBL overflow occurs and the H3A driver misses the timing
988 * to process the buffer, stat->buf_err is set and won't be
989 * cleared now. So the next buffer will be correctly ignored.
990 * It's necessary due to a hw issue which makes the next H3A
991 * buffer to start from the memory address where the previous
992 * one stopped, instead of start where it was configured to.
993 * Do not "stat->buf_err = 0" here.
994 */
995
996 if (stat->ops->buf_process)
997 /*
998 * Driver may need to erase current data prior to
999 * process a new buffer. If it misses the timing, the
1000 * next buffer might be wrong. So should be ignored.
1001 * It happens only for Histogram.
1002 */
1003 atomic_set(&stat->buf_err, 1);
1004
1005 ret = STAT_NO_BUF;
1006 dev_dbg(stat->isp->dev, "%s: cannot process buffer, "
1007 "device is busy.\n", stat->subdev.name);
1008 }
1009
1010out:
1011 stat->buf_processing = 0;
1012 isp_stat_queue_event(stat, ret != STAT_BUF_DONE);
1013}
1014
1015void omap3isp_stat_isr(struct ispstat *stat)
1016{
1017 __stat_isr(stat, 0);
1018}
1019
1020void omap3isp_stat_dma_isr(struct ispstat *stat)
1021{
1022 __stat_isr(stat, 1);
1023}
1024
1025static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1026 const struct v4l2_subdev_ops *sd_ops)
1027{
1028 struct v4l2_subdev *subdev = &stat->subdev;
1029 struct media_entity *me = &subdev->entity;
1030
1031 v4l2_subdev_init(subdev, sd_ops);
1032 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1033 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1034 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1035 subdev->nevents = STAT_NEVENTS;
1036 v4l2_set_subdevdata(subdev, stat);
1037
1038 stat->pad.flags = MEDIA_PAD_FL_SINK;
1039 me->ops = NULL;
1040
1041 return media_entity_init(me, 1, &stat->pad, 0);
1042}
1043
1044int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
1045 struct v4l2_fh *fh,
1046 struct v4l2_event_subscription *sub)
1047{
1048 struct ispstat *stat = v4l2_get_subdevdata(subdev);
1049
1050 if (sub->type != stat->event_type)
1051 return -EINVAL;
1052
1053 return v4l2_event_subscribe(fh, sub);
1054}
1055
1056int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
1057 struct v4l2_fh *fh,
1058 struct v4l2_event_subscription *sub)
1059{
1060 return v4l2_event_unsubscribe(fh, sub);
1061}
1062
1063void omap3isp_stat_unregister_entities(struct ispstat *stat)
1064{
1065 media_entity_cleanup(&stat->subdev.entity);
1066 v4l2_device_unregister_subdev(&stat->subdev);
1067}
1068
1069int omap3isp_stat_register_entities(struct ispstat *stat,
1070 struct v4l2_device *vdev)
1071{
1072 return v4l2_device_register_subdev(vdev, &stat->subdev);
1073}
1074
1075int omap3isp_stat_init(struct ispstat *stat, const char *name,
1076 const struct v4l2_subdev_ops *sd_ops)
1077{
1078 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
1079 if (!stat->buf)
1080 return -ENOMEM;
1081 isp_stat_buf_clear(stat);
1082 mutex_init(&stat->ioctl_lock);
1083 atomic_set(&stat->buf_err, 0);
1084
1085 return isp_stat_init_entities(stat, name, sd_ops);
1086}
1087
1088void omap3isp_stat_free(struct ispstat *stat)
1089{
1090 isp_stat_bufs_free(stat);
1091 kfree(stat->buf);
1092}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h
new file mode 100644
index 000000000000..820950c9ef46
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispstat.h
@@ -0,0 +1,169 @@
1/*
2 * ispstat.h
3 *
4 * TI OMAP3 ISP - Statistics core
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc
8 *
9 * Contacts: David Cohen <dacohen@gmail.com>
10 * Laurent Pinchart <laurent.pinchart@ideasonboard.com>
11 * Sakari Ailus <sakari.ailus@iki.fi>
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2 as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
25 * 02110-1301 USA
26 */
27
28#ifndef OMAP3_ISP_STAT_H
29#define OMAP3_ISP_STAT_H
30
31#include <linux/types.h>
32#include <linux/omap3isp.h>
33#include <plat/dma.h>
34#include <media/v4l2-event.h>
35
36#include "isp.h"
37#include "ispvideo.h"
38
39#define STAT_MAX_BUFS 5
40#define STAT_NEVENTS 8
41
42#define STAT_BUF_DONE 0 /* Buffer is ready */
43#define STAT_NO_BUF 1 /* An error has occurred */
44#define STAT_BUF_WAITING_DMA 2 /* Histogram only: DMA is running */
45
46struct ispstat;
47
48struct ispstat_buffer {
49 unsigned long iommu_addr;
50 struct iovm_struct *iovm;
51 void *virt_addr;
52 dma_addr_t dma_addr;
53 struct timeval ts;
54 u32 buf_size;
55 u32 frame_number;
56 u16 config_counter;
57 u8 empty;
58};
59
60struct ispstat_ops {
61 /*
62 * Validate new params configuration.
63 * new_conf->buf_size value must be changed to the exact buffer size
64 * necessary for the new configuration if it's smaller.
65 */
66 int (*validate_params)(struct ispstat *stat, void *new_conf);
67
68 /*
69 * Save new params configuration.
70 * stat->priv->buf_size value must be set to the exact buffer size for
71 * the new configuration.
72 * stat->update is set to 1 if new configuration is different than
73 * current one.
74 */
75 void (*set_params)(struct ispstat *stat, void *new_conf);
76
77 /* Apply stored configuration. */
78 void (*setup_regs)(struct ispstat *stat, void *priv);
79
80 /* Enable/Disable module. */
81 void (*enable)(struct ispstat *stat, int enable);
82
83 /* Verify is module is busy. */
84 int (*busy)(struct ispstat *stat);
85
86 /* Used for specific operations during generic buf process task. */
87 int (*buf_process)(struct ispstat *stat);
88};
89
90enum ispstat_state_t {
91 ISPSTAT_DISABLED = 0,
92 ISPSTAT_DISABLING,
93 ISPSTAT_ENABLED,
94 ISPSTAT_ENABLING,
95 ISPSTAT_SUSPENDED,
96};
97
98struct ispstat {
99 struct v4l2_subdev subdev;
100 struct media_pad pad; /* sink pad */
101
102 /* Control */
103 unsigned configured:1;
104 unsigned update:1;
105 unsigned buf_processing:1;
106 unsigned sbl_ovl_recover:1;
107 u8 inc_config;
108 atomic_t buf_err;
109 enum ispstat_state_t state; /* enabling/disabling state */
110 struct omap_dma_channel_params dma_config;
111 struct isp_device *isp;
112 void *priv; /* pointer to priv config struct */
113 void *recover_priv; /* pointer to recover priv configuration */
114 struct mutex ioctl_lock; /* serialize private ioctl */
115
116 const struct ispstat_ops *ops;
117
118 /* Buffer */
119 u8 wait_acc_frames;
120 u16 config_counter;
121 u32 frame_number;
122 u32 buf_size;
123 u32 buf_alloc_size;
124 int dma_ch;
125 unsigned long event_type;
126 struct ispstat_buffer *buf;
127 struct ispstat_buffer *active_buf;
128 struct ispstat_buffer *locked_buf;
129};
130
131struct ispstat_generic_config {
132 /*
133 * Fields must be in the same order as in:
134 * - isph3a_aewb_config
135 * - isph3a_af_config
136 * - isphist_config
137 */
138 u32 buf_size;
139 u16 config_counter;
140};
141
142int omap3isp_stat_config(struct ispstat *stat, void *new_conf);
143int omap3isp_stat_request_statistics(struct ispstat *stat,
144 struct omap3isp_stat_data *data);
145int omap3isp_stat_init(struct ispstat *stat, const char *name,
146 const struct v4l2_subdev_ops *sd_ops);
147void omap3isp_stat_free(struct ispstat *stat);
148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
149 struct v4l2_fh *fh,
150 struct v4l2_event_subscription *sub);
151int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
152 struct v4l2_fh *fh,
153 struct v4l2_event_subscription *sub);
154int omap3isp_stat_s_stream(struct v4l2_subdev *subdev, int enable);
155
156int omap3isp_stat_busy(struct ispstat *stat);
157int omap3isp_stat_pcr_busy(struct ispstat *stat);
158void omap3isp_stat_suspend(struct ispstat *stat);
159void omap3isp_stat_resume(struct ispstat *stat);
160int omap3isp_stat_enable(struct ispstat *stat, u8 enable);
161void omap3isp_stat_sbl_overflow(struct ispstat *stat);
162void omap3isp_stat_isr(struct ispstat *stat);
163void omap3isp_stat_isr_frame_sync(struct ispstat *stat);
164void omap3isp_stat_dma_isr(struct ispstat *stat);
165int omap3isp_stat_register_entities(struct ispstat *stat,
166 struct v4l2_device *vdev);
167void omap3isp_stat_unregister_entities(struct ispstat *stat);
168
169#endif /* OMAP3_ISP_STAT_H */
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
new file mode 100644
index 000000000000..a0bb5db9cb8a
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -0,0 +1,1255 @@
1/*
2 * ispvideo.c
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * 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, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#include <asm/cacheflush.h>
27#include <linux/clk.h>
28#include <linux/mm.h>
29#include <linux/pagemap.h>
30#include <linux/scatterlist.h>
31#include <linux/sched.h>
32#include <linux/slab.h>
33#include <linux/vmalloc.h>
34#include <media/v4l2-dev.h>
35#include <media/v4l2-ioctl.h>
36#include <plat/iommu.h>
37#include <plat/iovmm.h>
38#include <plat/omap-pm.h>
39
40#include "ispvideo.h"
41#include "isp.h"
42
43
44/* -----------------------------------------------------------------------------
45 * Helper functions
46 */
47
48static struct isp_format_info formats[] = {
49 { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
50 V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, },
51 { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
52 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
53 { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
54 V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, },
55 { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
56 V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, },
57 { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
58 V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, },
59 { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
60 V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, },
61 { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
62 V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, },
63 { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
64 V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, },
65 { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
66 V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, },
67 { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
68 V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, },
69 { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
70 V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, },
71 { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
72 V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, },
73};
74
75const struct isp_format_info *
76omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
77{
78 unsigned int i;
79
80 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
81 if (formats[i].code == code)
82 return &formats[i];
83 }
84
85 return NULL;
86}
87
88/*
89 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
90 * @video: ISP video instance
91 * @mbus: v4l2_mbus_framefmt format (input)
92 * @pix: v4l2_pix_format format (output)
93 *
94 * Fill the output pix structure with information from the input mbus format.
95 * The bytesperline and sizeimage fields are computed from the requested bytes
96 * per line value in the pix format and information from the video instance.
97 *
98 * Return the number of padding bytes at end of line.
99 */
100static unsigned int isp_video_mbus_to_pix(const struct isp_video *video,
101 const struct v4l2_mbus_framefmt *mbus,
102 struct v4l2_pix_format *pix)
103{
104 unsigned int bpl = pix->bytesperline;
105 unsigned int min_bpl;
106 unsigned int i;
107
108 memset(pix, 0, sizeof(*pix));
109 pix->width = mbus->width;
110 pix->height = mbus->height;
111
112 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
113 if (formats[i].code == mbus->code)
114 break;
115 }
116
117 if (WARN_ON(i == ARRAY_SIZE(formats)))
118 return 0;
119
120 min_bpl = pix->width * ALIGN(formats[i].bpp, 8) / 8;
121
122 /* Clamp the requested bytes per line value. If the maximum bytes per
123 * line value is zero, the module doesn't support user configurable line
124 * sizes. Override the requested value with the minimum in that case.
125 */
126 if (video->bpl_max)
127 bpl = clamp(bpl, min_bpl, video->bpl_max);
128 else
129 bpl = min_bpl;
130
131 if (!video->bpl_zero_padding || bpl != min_bpl)
132 bpl = ALIGN(bpl, video->bpl_alignment);
133
134 pix->pixelformat = formats[i].pixelformat;
135 pix->bytesperline = bpl;
136 pix->sizeimage = pix->bytesperline * pix->height;
137 pix->colorspace = mbus->colorspace;
138 pix->field = mbus->field;
139
140 return bpl - min_bpl;
141}
142
143static void isp_video_pix_to_mbus(const struct v4l2_pix_format *pix,
144 struct v4l2_mbus_framefmt *mbus)
145{
146 unsigned int i;
147
148 memset(mbus, 0, sizeof(*mbus));
149 mbus->width = pix->width;
150 mbus->height = pix->height;
151
152 for (i = 0; i < ARRAY_SIZE(formats); ++i) {
153 if (formats[i].pixelformat == pix->pixelformat)
154 break;
155 }
156
157 if (WARN_ON(i == ARRAY_SIZE(formats)))
158 return;
159
160 mbus->code = formats[i].code;
161 mbus->colorspace = pix->colorspace;
162 mbus->field = pix->field;
163}
164
165static struct v4l2_subdev *
166isp_video_remote_subdev(struct isp_video *video, u32 *pad)
167{
168 struct media_pad *remote;
169
170 remote = media_entity_remote_source(&video->pad);
171
172 if (remote == NULL ||
173 media_entity_type(remote->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
174 return NULL;
175
176 if (pad)
177 *pad = remote->index;
178
179 return media_entity_to_v4l2_subdev(remote->entity);
180}
181
182/* Return a pointer to the ISP video instance at the far end of the pipeline. */
183static struct isp_video *
184isp_video_far_end(struct isp_video *video)
185{
186 struct media_entity_graph graph;
187 struct media_entity *entity = &video->video.entity;
188 struct media_device *mdev = entity->parent;
189 struct isp_video *far_end = NULL;
190
191 mutex_lock(&mdev->graph_mutex);
192 media_entity_graph_walk_start(&graph, entity);
193
194 while ((entity = media_entity_graph_walk_next(&graph))) {
195 if (entity == &video->video.entity)
196 continue;
197
198 if (media_entity_type(entity) != MEDIA_ENT_T_DEVNODE)
199 continue;
200
201 far_end = to_isp_video(media_entity_to_video_device(entity));
202 if (far_end->type != video->type)
203 break;
204
205 far_end = NULL;
206 }
207
208 mutex_unlock(&mdev->graph_mutex);
209 return far_end;
210}
211
212/*
213 * Validate a pipeline by checking both ends of all links for format
214 * discrepancies.
215 *
216 * Compute the minimum time per frame value as the maximum of time per frame
217 * limits reported by every block in the pipeline.
218 *
219 * Return 0 if all formats match, or -EPIPE if at least one link is found with
220 * different formats on its two ends.
221 */
222static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
223{
224 struct isp_device *isp = pipe->output->isp;
225 struct v4l2_subdev_format fmt_source;
226 struct v4l2_subdev_format fmt_sink;
227 struct media_pad *pad;
228 struct v4l2_subdev *subdev;
229 int ret;
230
231 pipe->max_rate = pipe->l3_ick;
232
233 subdev = isp_video_remote_subdev(pipe->output, NULL);
234 if (subdev == NULL)
235 return -EPIPE;
236
237 while (1) {
238 /* Retrieve the sink format */
239 pad = &subdev->entity.pads[0];
240 if (!(pad->flags & MEDIA_PAD_FL_SINK))
241 break;
242
243 fmt_sink.pad = pad->index;
244 fmt_sink.which = V4L2_SUBDEV_FORMAT_ACTIVE;
245 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_sink);
246 if (ret < 0 && ret != -ENOIOCTLCMD)
247 return -EPIPE;
248
249 /* Update the maximum frame rate */
250 if (subdev == &isp->isp_res.subdev)
251 omap3isp_resizer_max_rate(&isp->isp_res,
252 &pipe->max_rate);
253
254 /* Check ccdc maximum data rate when data comes from sensor
255 * TODO: Include ccdc rate in pipe->max_rate and compare the
256 * total pipe rate with the input data rate from sensor.
257 */
258 if (subdev == &isp->isp_ccdc.subdev && pipe->input == NULL) {
259 unsigned int rate = UINT_MAX;
260
261 omap3isp_ccdc_max_rate(&isp->isp_ccdc, &rate);
262 if (isp->isp_ccdc.vpcfg.pixelclk > rate)
263 return -ENOSPC;
264 }
265
266 /* Retrieve the source format */
267 pad = media_entity_remote_source(pad);
268 if (pad == NULL ||
269 media_entity_type(pad->entity) != MEDIA_ENT_T_V4L2_SUBDEV)
270 break;
271
272 subdev = media_entity_to_v4l2_subdev(pad->entity);
273
274 fmt_source.pad = pad->index;
275 fmt_source.which = V4L2_SUBDEV_FORMAT_ACTIVE;
276 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt_source);
277 if (ret < 0 && ret != -ENOIOCTLCMD)
278 return -EPIPE;
279
280 /* Check if the two ends match */
281 if (fmt_source.format.code != fmt_sink.format.code ||
282 fmt_source.format.width != fmt_sink.format.width ||
283 fmt_source.format.height != fmt_sink.format.height)
284 return -EPIPE;
285 }
286
287 return 0;
288}
289
290static int
291__isp_video_get_format(struct isp_video *video, struct v4l2_format *format)
292{
293 struct v4l2_subdev_format fmt;
294 struct v4l2_subdev *subdev;
295 u32 pad;
296 int ret;
297
298 subdev = isp_video_remote_subdev(video, &pad);
299 if (subdev == NULL)
300 return -EINVAL;
301
302 mutex_lock(&video->mutex);
303
304 fmt.pad = pad;
305 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
306 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
307 if (ret == -ENOIOCTLCMD)
308 ret = -EINVAL;
309
310 mutex_unlock(&video->mutex);
311
312 if (ret)
313 return ret;
314
315 format->type = video->type;
316 return isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
317}
318
319static int
320isp_video_check_format(struct isp_video *video, struct isp_video_fh *vfh)
321{
322 struct v4l2_format format;
323 int ret;
324
325 memcpy(&format, &vfh->format, sizeof(format));
326 ret = __isp_video_get_format(video, &format);
327 if (ret < 0)
328 return ret;
329
330 if (vfh->format.fmt.pix.pixelformat != format.fmt.pix.pixelformat ||
331 vfh->format.fmt.pix.height != format.fmt.pix.height ||
332 vfh->format.fmt.pix.width != format.fmt.pix.width ||
333 vfh->format.fmt.pix.bytesperline != format.fmt.pix.bytesperline ||
334 vfh->format.fmt.pix.sizeimage != format.fmt.pix.sizeimage)
335 return -EINVAL;
336
337 return ret;
338}
339
340/* -----------------------------------------------------------------------------
341 * IOMMU management
342 */
343
344#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
345
346/*
347 * ispmmu_vmap - Wrapper for Virtual memory mapping of a scatter gather list
348 * @dev: Device pointer specific to the OMAP3 ISP.
349 * @sglist: Pointer to source Scatter gather list to allocate.
350 * @sglen: Number of elements of the scatter-gatter list.
351 *
352 * Returns a resulting mapped device address by the ISP MMU, or -ENOMEM if
353 * we ran out of memory.
354 */
355static dma_addr_t
356ispmmu_vmap(struct isp_device *isp, const struct scatterlist *sglist, int sglen)
357{
358 struct sg_table *sgt;
359 u32 da;
360
361 sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
362 if (sgt == NULL)
363 return -ENOMEM;
364
365 sgt->sgl = (struct scatterlist *)sglist;
366 sgt->nents = sglen;
367 sgt->orig_nents = sglen;
368
369 da = iommu_vmap(isp->iommu, 0, sgt, IOMMU_FLAG);
370 if (IS_ERR_VALUE(da))
371 kfree(sgt);
372
373 return da;
374}
375
376/*
377 * ispmmu_vunmap - Unmap a device address from the ISP MMU
378 * @dev: Device pointer specific to the OMAP3 ISP.
379 * @da: Device address generated from a ispmmu_vmap call.
380 */
381static void ispmmu_vunmap(struct isp_device *isp, dma_addr_t da)
382{
383 struct sg_table *sgt;
384
385 sgt = iommu_vunmap(isp->iommu, (u32)da);
386 kfree(sgt);
387}
388
389/* -----------------------------------------------------------------------------
390 * Video queue operations
391 */
392
393static void isp_video_queue_prepare(struct isp_video_queue *queue,
394 unsigned int *nbuffers, unsigned int *size)
395{
396 struct isp_video_fh *vfh =
397 container_of(queue, struct isp_video_fh, queue);
398 struct isp_video *video = vfh->video;
399
400 *size = vfh->format.fmt.pix.sizeimage;
401 if (*size == 0)
402 return;
403
404 *nbuffers = min(*nbuffers, video->capture_mem / PAGE_ALIGN(*size));
405}
406
407static void isp_video_buffer_cleanup(struct isp_video_buffer *buf)
408{
409 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
410 struct isp_buffer *buffer = to_isp_buffer(buf);
411 struct isp_video *video = vfh->video;
412
413 if (buffer->isp_addr) {
414 ispmmu_vunmap(video->isp, buffer->isp_addr);
415 buffer->isp_addr = 0;
416 }
417}
418
419static int isp_video_buffer_prepare(struct isp_video_buffer *buf)
420{
421 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
422 struct isp_buffer *buffer = to_isp_buffer(buf);
423 struct isp_video *video = vfh->video;
424 unsigned long addr;
425
426 addr = ispmmu_vmap(video->isp, buf->sglist, buf->sglen);
427 if (IS_ERR_VALUE(addr))
428 return -EIO;
429
430 if (!IS_ALIGNED(addr, 32)) {
431 dev_dbg(video->isp->dev, "Buffer address must be "
432 "aligned to 32 bytes boundary.\n");
433 ispmmu_vunmap(video->isp, buffer->isp_addr);
434 return -EINVAL;
435 }
436
437 buf->vbuf.bytesused = vfh->format.fmt.pix.sizeimage;
438 buffer->isp_addr = addr;
439 return 0;
440}
441
442/*
443 * isp_video_buffer_queue - Add buffer to streaming queue
444 * @buf: Video buffer
445 *
446 * In memory-to-memory mode, start streaming on the pipeline if buffers are
447 * queued on both the input and the output, if the pipeline isn't already busy.
448 * If the pipeline is busy, it will be restarted in the output module interrupt
449 * handler.
450 */
451static void isp_video_buffer_queue(struct isp_video_buffer *buf)
452{
453 struct isp_video_fh *vfh = isp_video_queue_to_isp_video_fh(buf->queue);
454 struct isp_buffer *buffer = to_isp_buffer(buf);
455 struct isp_video *video = vfh->video;
456 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
457 enum isp_pipeline_state state;
458 unsigned long flags;
459 unsigned int empty;
460 unsigned int start;
461
462 empty = list_empty(&video->dmaqueue);
463 list_add_tail(&buffer->buffer.irqlist, &video->dmaqueue);
464
465 if (empty) {
466 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
467 state = ISP_PIPELINE_QUEUE_OUTPUT;
468 else
469 state = ISP_PIPELINE_QUEUE_INPUT;
470
471 spin_lock_irqsave(&pipe->lock, flags);
472 pipe->state |= state;
473 video->ops->queue(video, buffer);
474 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
475
476 start = isp_pipeline_ready(pipe);
477 if (start)
478 pipe->state |= ISP_PIPELINE_STREAM;
479 spin_unlock_irqrestore(&pipe->lock, flags);
480
481 if (start)
482 omap3isp_pipeline_set_stream(pipe,
483 ISP_PIPELINE_STREAM_SINGLESHOT);
484 }
485}
486
487static const struct isp_video_queue_operations isp_video_queue_ops = {
488 .queue_prepare = &isp_video_queue_prepare,
489 .buffer_prepare = &isp_video_buffer_prepare,
490 .buffer_queue = &isp_video_buffer_queue,
491 .buffer_cleanup = &isp_video_buffer_cleanup,
492};
493
494/*
495 * omap3isp_video_buffer_next - Complete the current buffer and return the next
496 * @video: ISP video object
497 * @error: Whether an error occured during capture
498 *
499 * Remove the current video buffer from the DMA queue and fill its timestamp,
500 * field count and state fields before waking up its completion handler.
501 *
502 * The buffer state is set to VIDEOBUF_DONE if no error occured (@error is 0)
503 * or VIDEOBUF_ERROR otherwise (@error is non-zero).
504 *
505 * The DMA queue is expected to contain at least one buffer.
506 *
507 * Return a pointer to the next buffer in the DMA queue, or NULL if the queue is
508 * empty.
509 */
510struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video,
511 unsigned int error)
512{
513 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
514 struct isp_video_queue *queue = video->queue;
515 enum isp_pipeline_state state;
516 struct isp_video_buffer *buf;
517 unsigned long flags;
518 struct timespec ts;
519
520 spin_lock_irqsave(&queue->irqlock, flags);
521 if (WARN_ON(list_empty(&video->dmaqueue))) {
522 spin_unlock_irqrestore(&queue->irqlock, flags);
523 return NULL;
524 }
525
526 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
527 irqlist);
528 list_del(&buf->irqlist);
529 spin_unlock_irqrestore(&queue->irqlock, flags);
530
531 ktime_get_ts(&ts);
532 buf->vbuf.timestamp.tv_sec = ts.tv_sec;
533 buf->vbuf.timestamp.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
534
535 /* Do frame number propagation only if this is the output video node.
536 * Frame number either comes from the CSI receivers or it gets
537 * incremented here if H3A is not active.
538 * Note: There is no guarantee that the output buffer will finish
539 * first, so the input number might lag behind by 1 in some cases.
540 */
541 if (video == pipe->output && !pipe->do_propagation)
542 buf->vbuf.sequence = atomic_inc_return(&pipe->frame_number);
543 else
544 buf->vbuf.sequence = atomic_read(&pipe->frame_number);
545
546 buf->state = error ? ISP_BUF_STATE_ERROR : ISP_BUF_STATE_DONE;
547
548 wake_up(&buf->wait);
549
550 if (list_empty(&video->dmaqueue)) {
551 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
552 state = ISP_PIPELINE_QUEUE_OUTPUT
553 | ISP_PIPELINE_STREAM;
554 else
555 state = ISP_PIPELINE_QUEUE_INPUT
556 | ISP_PIPELINE_STREAM;
557
558 spin_lock_irqsave(&pipe->lock, flags);
559 pipe->state &= ~state;
560 if (video->pipe.stream_state == ISP_PIPELINE_STREAM_CONTINUOUS)
561 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
562 spin_unlock_irqrestore(&pipe->lock, flags);
563 return NULL;
564 }
565
566 if (queue->type == V4L2_BUF_TYPE_VIDEO_CAPTURE && pipe->input != NULL) {
567 spin_lock_irqsave(&pipe->lock, flags);
568 pipe->state &= ~ISP_PIPELINE_STREAM;
569 spin_unlock_irqrestore(&pipe->lock, flags);
570 }
571
572 buf = list_first_entry(&video->dmaqueue, struct isp_video_buffer,
573 irqlist);
574 buf->state = ISP_BUF_STATE_ACTIVE;
575 return to_isp_buffer(buf);
576}
577
578/*
579 * omap3isp_video_resume - Perform resume operation on the buffers
580 * @video: ISP video object
581 * @continuous: Pipeline is in single shot mode if 0 or continous mode otherwise
582 *
583 * This function is intended to be used on suspend/resume scenario. It
584 * requests video queue layer to discard buffers marked as DONE if it's in
585 * continuous mode and requests ISP modules to queue again the ACTIVE buffer
586 * if there's any.
587 */
588void omap3isp_video_resume(struct isp_video *video, int continuous)
589{
590 struct isp_buffer *buf = NULL;
591
592 if (continuous && video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
593 omap3isp_video_queue_discard_done(video->queue);
594
595 if (!list_empty(&video->dmaqueue)) {
596 buf = list_first_entry(&video->dmaqueue,
597 struct isp_buffer, buffer.irqlist);
598 video->ops->queue(video, buf);
599 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_QUEUED;
600 } else {
601 if (continuous)
602 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
603 }
604}
605
606/* -----------------------------------------------------------------------------
607 * V4L2 ioctls
608 */
609
610static int
611isp_video_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
612{
613 struct isp_video *video = video_drvdata(file);
614
615 strlcpy(cap->driver, ISP_VIDEO_DRIVER_NAME, sizeof(cap->driver));
616 strlcpy(cap->card, video->video.name, sizeof(cap->card));
617 strlcpy(cap->bus_info, "media", sizeof(cap->bus_info));
618 cap->version = ISP_VIDEO_DRIVER_VERSION;
619
620 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
621 cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING;
622 else
623 cap->capabilities = V4L2_CAP_VIDEO_OUTPUT | V4L2_CAP_STREAMING;
624
625 return 0;
626}
627
628static int
629isp_video_get_format(struct file *file, void *fh, struct v4l2_format *format)
630{
631 struct isp_video_fh *vfh = to_isp_video_fh(fh);
632 struct isp_video *video = video_drvdata(file);
633
634 if (format->type != video->type)
635 return -EINVAL;
636
637 mutex_lock(&video->mutex);
638 *format = vfh->format;
639 mutex_unlock(&video->mutex);
640
641 return 0;
642}
643
644static int
645isp_video_set_format(struct file *file, void *fh, struct v4l2_format *format)
646{
647 struct isp_video_fh *vfh = to_isp_video_fh(fh);
648 struct isp_video *video = video_drvdata(file);
649 struct v4l2_mbus_framefmt fmt;
650
651 if (format->type != video->type)
652 return -EINVAL;
653
654 mutex_lock(&video->mutex);
655
656 /* Fill the bytesperline and sizeimage fields by converting to media bus
657 * format and back to pixel format.
658 */
659 isp_video_pix_to_mbus(&format->fmt.pix, &fmt);
660 isp_video_mbus_to_pix(video, &fmt, &format->fmt.pix);
661
662 vfh->format = *format;
663
664 mutex_unlock(&video->mutex);
665 return 0;
666}
667
668static int
669isp_video_try_format(struct file *file, void *fh, struct v4l2_format *format)
670{
671 struct isp_video *video = video_drvdata(file);
672 struct v4l2_subdev_format fmt;
673 struct v4l2_subdev *subdev;
674 u32 pad;
675 int ret;
676
677 if (format->type != video->type)
678 return -EINVAL;
679
680 subdev = isp_video_remote_subdev(video, &pad);
681 if (subdev == NULL)
682 return -EINVAL;
683
684 isp_video_pix_to_mbus(&format->fmt.pix, &fmt.format);
685
686 fmt.pad = pad;
687 fmt.which = V4L2_SUBDEV_FORMAT_ACTIVE;
688 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &fmt);
689 if (ret)
690 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
691
692 isp_video_mbus_to_pix(video, &fmt.format, &format->fmt.pix);
693 return 0;
694}
695
696static int
697isp_video_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
698{
699 struct isp_video *video = video_drvdata(file);
700 struct v4l2_subdev *subdev;
701 int ret;
702
703 subdev = isp_video_remote_subdev(video, NULL);
704 if (subdev == NULL)
705 return -EINVAL;
706
707 mutex_lock(&video->mutex);
708 ret = v4l2_subdev_call(subdev, video, cropcap, cropcap);
709 mutex_unlock(&video->mutex);
710
711 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
712}
713
714static int
715isp_video_get_crop(struct file *file, void *fh, struct v4l2_crop *crop)
716{
717 struct isp_video *video = video_drvdata(file);
718 struct v4l2_subdev_format format;
719 struct v4l2_subdev *subdev;
720 u32 pad;
721 int ret;
722
723 subdev = isp_video_remote_subdev(video, &pad);
724 if (subdev == NULL)
725 return -EINVAL;
726
727 /* Try the get crop operation first and fallback to get format if not
728 * implemented.
729 */
730 ret = v4l2_subdev_call(subdev, video, g_crop, crop);
731 if (ret != -ENOIOCTLCMD)
732 return ret;
733
734 format.pad = pad;
735 format.which = V4L2_SUBDEV_FORMAT_ACTIVE;
736 ret = v4l2_subdev_call(subdev, pad, get_fmt, NULL, &format);
737 if (ret < 0)
738 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
739
740 crop->c.left = 0;
741 crop->c.top = 0;
742 crop->c.width = format.format.width;
743 crop->c.height = format.format.height;
744
745 return 0;
746}
747
748static int
749isp_video_set_crop(struct file *file, void *fh, struct v4l2_crop *crop)
750{
751 struct isp_video *video = video_drvdata(file);
752 struct v4l2_subdev *subdev;
753 int ret;
754
755 subdev = isp_video_remote_subdev(video, NULL);
756 if (subdev == NULL)
757 return -EINVAL;
758
759 mutex_lock(&video->mutex);
760 ret = v4l2_subdev_call(subdev, video, s_crop, crop);
761 mutex_unlock(&video->mutex);
762
763 return ret == -ENOIOCTLCMD ? -EINVAL : ret;
764}
765
766static int
767isp_video_get_param(struct file *file, void *fh, struct v4l2_streamparm *a)
768{
769 struct isp_video_fh *vfh = to_isp_video_fh(fh);
770 struct isp_video *video = video_drvdata(file);
771
772 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
773 video->type != a->type)
774 return -EINVAL;
775
776 memset(a, 0, sizeof(*a));
777 a->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
778 a->parm.output.capability = V4L2_CAP_TIMEPERFRAME;
779 a->parm.output.timeperframe = vfh->timeperframe;
780
781 return 0;
782}
783
784static int
785isp_video_set_param(struct file *file, void *fh, struct v4l2_streamparm *a)
786{
787 struct isp_video_fh *vfh = to_isp_video_fh(fh);
788 struct isp_video *video = video_drvdata(file);
789
790 if (video->type != V4L2_BUF_TYPE_VIDEO_OUTPUT ||
791 video->type != a->type)
792 return -EINVAL;
793
794 if (a->parm.output.timeperframe.denominator == 0)
795 a->parm.output.timeperframe.denominator = 1;
796
797 vfh->timeperframe = a->parm.output.timeperframe;
798
799 return 0;
800}
801
802static int
803isp_video_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
804{
805 struct isp_video_fh *vfh = to_isp_video_fh(fh);
806
807 return omap3isp_video_queue_reqbufs(&vfh->queue, rb);
808}
809
810static int
811isp_video_querybuf(struct file *file, void *fh, struct v4l2_buffer *b)
812{
813 struct isp_video_fh *vfh = to_isp_video_fh(fh);
814
815 return omap3isp_video_queue_querybuf(&vfh->queue, b);
816}
817
818static int
819isp_video_qbuf(struct file *file, void *fh, struct v4l2_buffer *b)
820{
821 struct isp_video_fh *vfh = to_isp_video_fh(fh);
822
823 return omap3isp_video_queue_qbuf(&vfh->queue, b);
824}
825
826static int
827isp_video_dqbuf(struct file *file, void *fh, struct v4l2_buffer *b)
828{
829 struct isp_video_fh *vfh = to_isp_video_fh(fh);
830
831 return omap3isp_video_queue_dqbuf(&vfh->queue, b,
832 file->f_flags & O_NONBLOCK);
833}
834
835/*
836 * Stream management
837 *
838 * Every ISP pipeline has a single input and a single output. The input can be
839 * either a sensor or a video node. The output is always a video node.
840 *
841 * As every pipeline has an output video node, the ISP video objects at the
842 * pipeline output stores the pipeline state. It tracks the streaming state of
843 * both the input and output, as well as the availability of buffers.
844 *
845 * In sensor-to-memory mode, frames are always available at the pipeline input.
846 * Starting the sensor usually requires I2C transfers and must be done in
847 * interruptible context. The pipeline is started and stopped synchronously
848 * to the stream on/off commands. All modules in the pipeline will get their
849 * subdev set stream handler called. The module at the end of the pipeline must
850 * delay starting the hardware until buffers are available at its output.
851 *
852 * In memory-to-memory mode, starting/stopping the stream requires
853 * synchronization between the input and output. ISP modules can't be stopped
854 * in the middle of a frame, and at least some of the modules seem to become
855 * busy as soon as they're started, even if they don't receive a frame start
856 * event. For that reason frames need to be processed in single-shot mode. The
857 * driver needs to wait until a frame is completely processed and written to
858 * memory before restarting the pipeline for the next frame. Pipelined
859 * processing might be possible but requires more testing.
860 *
861 * Stream start must be delayed until buffers are available at both the input
862 * and output. The pipeline must be started in the videobuf queue callback with
863 * the buffers queue spinlock held. The modules subdev set stream operation must
864 * not sleep.
865 */
866static int
867isp_video_streamon(struct file *file, void *fh, enum v4l2_buf_type type)
868{
869 struct isp_video_fh *vfh = to_isp_video_fh(fh);
870 struct isp_video *video = video_drvdata(file);
871 enum isp_pipeline_state state;
872 struct isp_pipeline *pipe;
873 struct isp_video *far_end;
874 unsigned long flags;
875 int ret;
876
877 if (type != video->type)
878 return -EINVAL;
879
880 mutex_lock(&video->stream_lock);
881
882 if (video->streaming) {
883 mutex_unlock(&video->stream_lock);
884 return -EBUSY;
885 }
886
887 /* Start streaming on the pipeline. No link touching an entity in the
888 * pipeline can be activated or deactivated once streaming is started.
889 */
890 pipe = video->video.entity.pipe
891 ? to_isp_pipeline(&video->video.entity) : &video->pipe;
892 media_entity_pipeline_start(&video->video.entity, &pipe->pipe);
893
894 /* Verify that the currently configured format matches the output of
895 * the connected subdev.
896 */
897 ret = isp_video_check_format(video, vfh);
898 if (ret < 0)
899 goto error;
900
901 video->bpl_padding = ret;
902 video->bpl_value = vfh->format.fmt.pix.bytesperline;
903
904 /* Find the ISP video node connected at the far end of the pipeline and
905 * update the pipeline.
906 */
907 far_end = isp_video_far_end(video);
908
909 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
910 state = ISP_PIPELINE_STREAM_OUTPUT | ISP_PIPELINE_IDLE_OUTPUT;
911 pipe->input = far_end;
912 pipe->output = video;
913 } else {
914 if (far_end == NULL) {
915 ret = -EPIPE;
916 goto error;
917 }
918
919 state = ISP_PIPELINE_STREAM_INPUT | ISP_PIPELINE_IDLE_INPUT;
920 pipe->input = video;
921 pipe->output = far_end;
922 }
923
924 if (video->isp->pdata->set_constraints)
925 video->isp->pdata->set_constraints(video->isp, true);
926 pipe->l3_ick = clk_get_rate(video->isp->clock[ISP_CLK_L3_ICK]);
927
928 /* Validate the pipeline and update its state. */
929 ret = isp_video_validate_pipeline(pipe);
930 if (ret < 0)
931 goto error;
932
933 spin_lock_irqsave(&pipe->lock, flags);
934 pipe->state &= ~ISP_PIPELINE_STREAM;
935 pipe->state |= state;
936 spin_unlock_irqrestore(&pipe->lock, flags);
937
938 /* Set the maximum time per frame as the value requested by userspace.
939 * This is a soft limit that can be overridden if the hardware doesn't
940 * support the request limit.
941 */
942 if (video->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
943 pipe->max_timeperframe = vfh->timeperframe;
944
945 video->queue = &vfh->queue;
946 INIT_LIST_HEAD(&video->dmaqueue);
947 atomic_set(&pipe->frame_number, -1);
948
949 ret = omap3isp_video_queue_streamon(&vfh->queue);
950 if (ret < 0)
951 goto error;
952
953 /* In sensor-to-memory mode, the stream can be started synchronously
954 * to the stream on command. In memory-to-memory mode, it will be
955 * started when buffers are queued on both the input and output.
956 */
957 if (pipe->input == NULL) {
958 ret = omap3isp_pipeline_set_stream(pipe,
959 ISP_PIPELINE_STREAM_CONTINUOUS);
960 if (ret < 0)
961 goto error;
962 spin_lock_irqsave(&video->queue->irqlock, flags);
963 if (list_empty(&video->dmaqueue))
964 video->dmaqueue_flags |= ISP_VIDEO_DMAQUEUE_UNDERRUN;
965 spin_unlock_irqrestore(&video->queue->irqlock, flags);
966 }
967
968error:
969 if (ret < 0) {
970 omap3isp_video_queue_streamoff(&vfh->queue);
971 if (video->isp->pdata->set_constraints)
972 video->isp->pdata->set_constraints(video->isp, false);
973 media_entity_pipeline_stop(&video->video.entity);
974 video->queue = NULL;
975 }
976
977 if (!ret)
978 video->streaming = 1;
979
980 mutex_unlock(&video->stream_lock);
981 return ret;
982}
983
984static int
985isp_video_streamoff(struct file *file, void *fh, enum v4l2_buf_type type)
986{
987 struct isp_video_fh *vfh = to_isp_video_fh(fh);
988 struct isp_video *video = video_drvdata(file);
989 struct isp_pipeline *pipe = to_isp_pipeline(&video->video.entity);
990 enum isp_pipeline_state state;
991 unsigned int streaming;
992 unsigned long flags;
993
994 if (type != video->type)
995 return -EINVAL;
996
997 mutex_lock(&video->stream_lock);
998
999 /* Make sure we're not streaming yet. */
1000 mutex_lock(&vfh->queue.lock);
1001 streaming = vfh->queue.streaming;
1002 mutex_unlock(&vfh->queue.lock);
1003
1004 if (!streaming)
1005 goto done;
1006
1007 /* Update the pipeline state. */
1008 if (video->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
1009 state = ISP_PIPELINE_STREAM_OUTPUT
1010 | ISP_PIPELINE_QUEUE_OUTPUT;
1011 else
1012 state = ISP_PIPELINE_STREAM_INPUT
1013 | ISP_PIPELINE_QUEUE_INPUT;
1014
1015 spin_lock_irqsave(&pipe->lock, flags);
1016 pipe->state &= ~state;
1017 spin_unlock_irqrestore(&pipe->lock, flags);
1018
1019 /* Stop the stream. */
1020 omap3isp_pipeline_set_stream(pipe, ISP_PIPELINE_STREAM_STOPPED);
1021 omap3isp_video_queue_streamoff(&vfh->queue);
1022 video->queue = NULL;
1023 video->streaming = 0;
1024
1025 if (video->isp->pdata->set_constraints)
1026 video->isp->pdata->set_constraints(video->isp, false);
1027 media_entity_pipeline_stop(&video->video.entity);
1028
1029done:
1030 mutex_unlock(&video->stream_lock);
1031 return 0;
1032}
1033
1034static int
1035isp_video_enum_input(struct file *file, void *fh, struct v4l2_input *input)
1036{
1037 if (input->index > 0)
1038 return -EINVAL;
1039
1040 strlcpy(input->name, "camera", sizeof(input->name));
1041 input->type = V4L2_INPUT_TYPE_CAMERA;
1042
1043 return 0;
1044}
1045
1046static int
1047isp_video_g_input(struct file *file, void *fh, unsigned int *input)
1048{
1049 *input = 0;
1050
1051 return 0;
1052}
1053
1054static int
1055isp_video_s_input(struct file *file, void *fh, unsigned int input)
1056{
1057 return input == 0 ? 0 : -EINVAL;
1058}
1059
1060static const struct v4l2_ioctl_ops isp_video_ioctl_ops = {
1061 .vidioc_querycap = isp_video_querycap,
1062 .vidioc_g_fmt_vid_cap = isp_video_get_format,
1063 .vidioc_s_fmt_vid_cap = isp_video_set_format,
1064 .vidioc_try_fmt_vid_cap = isp_video_try_format,
1065 .vidioc_g_fmt_vid_out = isp_video_get_format,
1066 .vidioc_s_fmt_vid_out = isp_video_set_format,
1067 .vidioc_try_fmt_vid_out = isp_video_try_format,
1068 .vidioc_cropcap = isp_video_cropcap,
1069 .vidioc_g_crop = isp_video_get_crop,
1070 .vidioc_s_crop = isp_video_set_crop,
1071 .vidioc_g_parm = isp_video_get_param,
1072 .vidioc_s_parm = isp_video_set_param,
1073 .vidioc_reqbufs = isp_video_reqbufs,
1074 .vidioc_querybuf = isp_video_querybuf,
1075 .vidioc_qbuf = isp_video_qbuf,
1076 .vidioc_dqbuf = isp_video_dqbuf,
1077 .vidioc_streamon = isp_video_streamon,
1078 .vidioc_streamoff = isp_video_streamoff,
1079 .vidioc_enum_input = isp_video_enum_input,
1080 .vidioc_g_input = isp_video_g_input,
1081 .vidioc_s_input = isp_video_s_input,
1082};
1083
1084/* -----------------------------------------------------------------------------
1085 * V4L2 file operations
1086 */
1087
1088static int isp_video_open(struct file *file)
1089{
1090 struct isp_video *video = video_drvdata(file);
1091 struct isp_video_fh *handle;
1092 int ret = 0;
1093
1094 handle = kzalloc(sizeof(*handle), GFP_KERNEL);
1095 if (handle == NULL)
1096 return -ENOMEM;
1097
1098 v4l2_fh_init(&handle->vfh, &video->video);
1099 v4l2_fh_add(&handle->vfh);
1100
1101 /* If this is the first user, initialise the pipeline. */
1102 if (omap3isp_get(video->isp) == NULL) {
1103 ret = -EBUSY;
1104 goto done;
1105 }
1106
1107 ret = omap3isp_pipeline_pm_use(&video->video.entity, 1);
1108 if (ret < 0) {
1109 omap3isp_put(video->isp);
1110 goto done;
1111 }
1112
1113 omap3isp_video_queue_init(&handle->queue, video->type,
1114 &isp_video_queue_ops, video->isp->dev,
1115 sizeof(struct isp_buffer));
1116
1117 memset(&handle->format, 0, sizeof(handle->format));
1118 handle->format.type = video->type;
1119 handle->timeperframe.denominator = 1;
1120
1121 handle->video = video;
1122 file->private_data = &handle->vfh;
1123
1124done:
1125 if (ret < 0) {
1126 v4l2_fh_del(&handle->vfh);
1127 kfree(handle);
1128 }
1129
1130 return ret;
1131}
1132
1133static int isp_video_release(struct file *file)
1134{
1135 struct isp_video *video = video_drvdata(file);
1136 struct v4l2_fh *vfh = file->private_data;
1137 struct isp_video_fh *handle = to_isp_video_fh(vfh);
1138
1139 /* Disable streaming and free the buffers queue resources. */
1140 isp_video_streamoff(file, vfh, video->type);
1141
1142 mutex_lock(&handle->queue.lock);
1143 omap3isp_video_queue_cleanup(&handle->queue);
1144 mutex_unlock(&handle->queue.lock);
1145
1146 omap3isp_pipeline_pm_use(&video->video.entity, 0);
1147
1148 /* Release the file handle. */
1149 v4l2_fh_del(vfh);
1150 kfree(handle);
1151 file->private_data = NULL;
1152
1153 omap3isp_put(video->isp);
1154
1155 return 0;
1156}
1157
1158static unsigned int isp_video_poll(struct file *file, poll_table *wait)
1159{
1160 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1161 struct isp_video_queue *queue = &vfh->queue;
1162
1163 return omap3isp_video_queue_poll(queue, file, wait);
1164}
1165
1166static int isp_video_mmap(struct file *file, struct vm_area_struct *vma)
1167{
1168 struct isp_video_fh *vfh = to_isp_video_fh(file->private_data);
1169
1170 return omap3isp_video_queue_mmap(&vfh->queue, vma);
1171}
1172
1173static struct v4l2_file_operations isp_video_fops = {
1174 .owner = THIS_MODULE,
1175 .unlocked_ioctl = video_ioctl2,
1176 .open = isp_video_open,
1177 .release = isp_video_release,
1178 .poll = isp_video_poll,
1179 .mmap = isp_video_mmap,
1180};
1181
1182/* -----------------------------------------------------------------------------
1183 * ISP video core
1184 */
1185
1186static const struct isp_video_operations isp_video_dummy_ops = {
1187};
1188
1189int omap3isp_video_init(struct isp_video *video, const char *name)
1190{
1191 const char *direction;
1192 int ret;
1193
1194 switch (video->type) {
1195 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
1196 direction = "output";
1197 video->pad.flags = MEDIA_PAD_FL_SINK;
1198 break;
1199 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
1200 direction = "input";
1201 video->pad.flags = MEDIA_PAD_FL_SOURCE;
1202 break;
1203
1204 default:
1205 return -EINVAL;
1206 }
1207
1208 ret = media_entity_init(&video->video.entity, 1, &video->pad, 0);
1209 if (ret < 0)
1210 return ret;
1211
1212 mutex_init(&video->mutex);
1213 atomic_set(&video->active, 0);
1214
1215 spin_lock_init(&video->pipe.lock);
1216 mutex_init(&video->stream_lock);
1217
1218 /* Initialize the video device. */
1219 if (video->ops == NULL)
1220 video->ops = &isp_video_dummy_ops;
1221
1222 video->video.fops = &isp_video_fops;
1223 snprintf(video->video.name, sizeof(video->video.name),
1224 "OMAP3 ISP %s %s", name, direction);
1225 video->video.vfl_type = VFL_TYPE_GRABBER;
1226 video->video.release = video_device_release_empty;
1227 video->video.ioctl_ops = &isp_video_ioctl_ops;
1228 video->pipe.stream_state = ISP_PIPELINE_STREAM_STOPPED;
1229
1230 video_set_drvdata(&video->video, video);
1231
1232 return 0;
1233}
1234
1235int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1236{
1237 int ret;
1238
1239 video->video.v4l2_dev = vdev;
1240
1241 ret = video_register_device(&video->video, VFL_TYPE_GRABBER, -1);
1242 if (ret < 0)
1243 printk(KERN_ERR "%s: could not register video device (%d)\n",
1244 __func__, ret);
1245
1246 return ret;
1247}
1248
1249void omap3isp_video_unregister(struct isp_video *video)
1250{
1251 if (video_is_registered(&video->video)) {
1252 media_entity_cleanup(&video->video.entity);
1253 video_unregister_device(&video->video);
1254 }
1255}
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
new file mode 100644
index 000000000000..524a1acd0906
--- /dev/null
+++ b/drivers/media/video/omap3isp/ispvideo.h
@@ -0,0 +1,202 @@
1/*
2 * ispvideo.h
3 *
4 * TI OMAP3 ISP - Generic video node
5 *
6 * Copyright (C) 2009-2010 Nokia Corporation
7 *
8 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
9 * Sakari Ailus <sakari.ailus@iki.fi>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 *
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * 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, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23 * 02110-1301 USA
24 */
25
26#ifndef OMAP3_ISP_VIDEO_H
27#define OMAP3_ISP_VIDEO_H
28
29#include <linux/v4l2-mediabus.h>
30#include <linux/version.h>
31#include <media/media-entity.h>
32#include <media/v4l2-dev.h>
33#include <media/v4l2-fh.h>
34
35#include "ispqueue.h"
36
37#define ISP_VIDEO_DRIVER_NAME "ispvideo"
38#define ISP_VIDEO_DRIVER_VERSION KERNEL_VERSION(0, 0, 1)
39
40struct isp_device;
41struct isp_video;
42struct v4l2_mbus_framefmt;
43struct v4l2_pix_format;
44
45/*
46 * struct isp_format_info - ISP media bus format information
47 * @code: V4L2 media bus format code
48 * @truncated: V4L2 media bus format code for the same format truncated to 10
49 * bits. Identical to @code if the format is 10 bits wide or less.
50 * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
51 * format. Identical to @code if the format is not DPCM compressed.
52 * @pixelformat: V4L2 pixel format FCC identifier
53 * @bpp: Bits per pixel
54 */
55struct isp_format_info {
56 enum v4l2_mbus_pixelcode code;
57 enum v4l2_mbus_pixelcode truncated;
58 enum v4l2_mbus_pixelcode uncompressed;
59 u32 pixelformat;
60 unsigned int bpp;
61};
62
63enum isp_pipeline_stream_state {
64 ISP_PIPELINE_STREAM_STOPPED = 0,
65 ISP_PIPELINE_STREAM_CONTINUOUS = 1,
66 ISP_PIPELINE_STREAM_SINGLESHOT = 2,
67};
68
69enum isp_pipeline_state {
70 /* The stream has been started on the input video node. */
71 ISP_PIPELINE_STREAM_INPUT = 1,
72 /* The stream has been started on the output video node. */
73 ISP_PIPELINE_STREAM_OUTPUT = 2,
74 /* At least one buffer is queued on the input video node. */
75 ISP_PIPELINE_QUEUE_INPUT = 4,
76 /* At least one buffer is queued on the output video node. */
77 ISP_PIPELINE_QUEUE_OUTPUT = 8,
78 /* The input entity is idle, ready to be started. */
79 ISP_PIPELINE_IDLE_INPUT = 16,
80 /* The output entity is idle, ready to be started. */
81 ISP_PIPELINE_IDLE_OUTPUT = 32,
82 /* The pipeline is currently streaming. */
83 ISP_PIPELINE_STREAM = 64,
84};
85
86struct isp_pipeline {
87 struct media_pipeline pipe;
88 spinlock_t lock; /* Pipeline state and queue flags */
89 unsigned int state;
90 enum isp_pipeline_stream_state stream_state;
91 struct isp_video *input;
92 struct isp_video *output;
93 unsigned long l3_ick;
94 unsigned int max_rate;
95 atomic_t frame_number;
96 bool do_propagation; /* of frame number */
97 struct v4l2_fract max_timeperframe;
98};
99
100#define to_isp_pipeline(__e) \
101 container_of((__e)->pipe, struct isp_pipeline, pipe)
102
103static inline int isp_pipeline_ready(struct isp_pipeline *pipe)
104{
105 return pipe->state == (ISP_PIPELINE_STREAM_INPUT |
106 ISP_PIPELINE_STREAM_OUTPUT |
107 ISP_PIPELINE_QUEUE_INPUT |
108 ISP_PIPELINE_QUEUE_OUTPUT |
109 ISP_PIPELINE_IDLE_INPUT |
110 ISP_PIPELINE_IDLE_OUTPUT);
111}
112
113/*
114 * struct isp_buffer - ISP buffer
115 * @buffer: ISP video buffer
116 * @isp_addr: MMU mapped address (a.k.a. device address) of the buffer.
117 */
118struct isp_buffer {
119 struct isp_video_buffer buffer;
120 dma_addr_t isp_addr;
121};
122
123#define to_isp_buffer(buf) container_of(buf, struct isp_buffer, buffer)
124
125enum isp_video_dmaqueue_flags {
126 /* Set if DMA queue becomes empty when ISP_PIPELINE_STREAM_CONTINUOUS */
127 ISP_VIDEO_DMAQUEUE_UNDERRUN = (1 << 0),
128 /* Set when queuing buffer to an empty DMA queue */
129 ISP_VIDEO_DMAQUEUE_QUEUED = (1 << 1),
130};
131
132#define isp_video_dmaqueue_flags_clr(video) \
133 ({ (video)->dmaqueue_flags = 0; })
134
135/*
136 * struct isp_video_operations - ISP video operations
137 * @queue: Resume streaming when a buffer is queued. Called on VIDIOC_QBUF
138 * if there was no buffer previously queued.
139 */
140struct isp_video_operations {
141 int(*queue)(struct isp_video *video, struct isp_buffer *buffer);
142};
143
144struct isp_video {
145 struct video_device video;
146 enum v4l2_buf_type type;
147 struct media_pad pad;
148
149 struct mutex mutex; /* format and crop settings */
150 atomic_t active;
151
152 struct isp_device *isp;
153
154 unsigned int capture_mem;
155 unsigned int bpl_alignment; /* alignment value */
156 unsigned int bpl_zero_padding; /* whether the alignment is optional */
157 unsigned int bpl_max; /* maximum bytes per line value */
158 unsigned int bpl_value; /* bytes per line value */
159 unsigned int bpl_padding; /* padding at end of line */
160
161 /* Entity video node streaming */
162 unsigned int streaming:1;
163
164 /* Pipeline state */
165 struct isp_pipeline pipe;
166 struct mutex stream_lock; /* pipeline and stream states */
167
168 /* Video buffers queue */
169 struct isp_video_queue *queue;
170 struct list_head dmaqueue;
171 enum isp_video_dmaqueue_flags dmaqueue_flags;
172
173 const struct isp_video_operations *ops;
174};
175
176#define to_isp_video(vdev) container_of(vdev, struct isp_video, video)
177
178struct isp_video_fh {
179 struct v4l2_fh vfh;
180 struct isp_video *video;
181 struct isp_video_queue queue;
182 struct v4l2_format format;
183 struct v4l2_fract timeperframe;
184};
185
186#define to_isp_video_fh(fh) container_of(fh, struct isp_video_fh, vfh)
187#define isp_video_queue_to_isp_video_fh(q) \
188 container_of(q, struct isp_video_fh, queue)
189
190int omap3isp_video_init(struct isp_video *video, const char *name);
191int omap3isp_video_register(struct isp_video *video,
192 struct v4l2_device *vdev);
193void omap3isp_video_unregister(struct isp_video *video);
194struct isp_buffer *omap3isp_video_buffer_next(struct isp_video *video,
195 unsigned int error);
196void omap3isp_video_resume(struct isp_video *video, int continuous);
197struct media_pad *omap3isp_video_remote_pad(struct isp_video *video);
198
199const struct isp_format_info *
200omap3isp_video_format_info(enum v4l2_mbus_pixelcode code);
201
202#endif /* OMAP3_ISP_VIDEO_H */
diff --git a/drivers/media/video/omap3isp/luma_enhance_table.h b/drivers/media/video/omap3isp/luma_enhance_table.h
new file mode 100644
index 000000000000..098b45e2280f
--- /dev/null
+++ b/drivers/media/video/omap3isp/luma_enhance_table.h
@@ -0,0 +1,42 @@
1/*
2 * luma_enhance_table.h
3 *
4 * TI OMAP3 ISP - Luminance enhancement table
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
271047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
281047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
291047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552, 1047552,
301047552, 1047552, 1047552, 1047552, 1048575, 1047551, 1046527, 1045503,
311044479, 1043455, 1042431, 1041407, 1040383, 1039359, 1038335, 1037311,
321036287, 1035263, 1034239, 1033215, 1032191, 1031167, 1030143, 1028096,
331028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096, 1028096,
341028096, 1028100, 1032196, 1036292, 1040388, 1044484, 0, 0,
35 0, 5, 5125, 10245, 15365, 20485, 25605, 30720,
36 30720, 30720, 30720, 30720, 30720, 30720, 30720, 30720,
37 30720, 30720, 31743, 30719, 29695, 28671, 27647, 26623,
38 25599, 24575, 23551, 22527, 21503, 20479, 19455, 18431,
39 17407, 16383, 15359, 14335, 13311, 12287, 11263, 10239,
40 9215, 8191, 7167, 6143, 5119, 4095, 3071, 1024,
41 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024,
42 1024, 1024, 1024, 1024, 1024, 1024, 1024, 1024
diff --git a/drivers/media/video/omap3isp/noise_filter_table.h b/drivers/media/video/omap3isp/noise_filter_table.h
new file mode 100644
index 000000000000..d50451a4a242
--- /dev/null
+++ b/drivers/media/video/omap3isp/noise_filter_table.h
@@ -0,0 +1,30 @@
1/*
2 * noise_filter_table.h
3 *
4 * TI OMAP3 ISP - Noise filter table
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
2716, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2816, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
2931, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
3031, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index cf93de988068..fe8e3ebd9ce4 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -207,7 +207,7 @@ static enum v4l2_mbus_pixelcode ov6650_codes[] = {
207 V4L2_MBUS_FMT_YVYU8_2X8, 207 V4L2_MBUS_FMT_YVYU8_2X8,
208 V4L2_MBUS_FMT_VYUY8_2X8, 208 V4L2_MBUS_FMT_VYUY8_2X8,
209 V4L2_MBUS_FMT_SBGGR8_1X8, 209 V4L2_MBUS_FMT_SBGGR8_1X8,
210 V4L2_MBUS_FMT_GREY8_1X8, 210 V4L2_MBUS_FMT_Y8_1X8,
211}; 211};
212 212
213static const struct v4l2_queryctrl ov6650_controls[] = { 213static const struct v4l2_queryctrl ov6650_controls[] = {
@@ -800,7 +800,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
800 800
801 /* select color matrix configuration for given color encoding */ 801 /* select color matrix configuration for given color encoding */
802 switch (code) { 802 switch (code) {
803 case V4L2_MBUS_FMT_GREY8_1X8: 803 case V4L2_MBUS_FMT_Y8_1X8:
804 dev_dbg(&client->dev, "pixel format GREY8_1X8\n"); 804 dev_dbg(&client->dev, "pixel format GREY8_1X8\n");
805 coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP; 805 coma_mask |= COMA_RGB | COMA_WORD_SWAP | COMA_BYTE_SWAP;
806 coma_set |= COMA_BW; 806 coma_set |= COMA_BW;
@@ -846,7 +846,7 @@ static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
846 } 846 }
847 priv->code = code; 847 priv->code = code;
848 848
849 if (code == V4L2_MBUS_FMT_GREY8_1X8 || 849 if (code == V4L2_MBUS_FMT_Y8_1X8 ||
850 code == V4L2_MBUS_FMT_SBGGR8_1X8) { 850 code == V4L2_MBUS_FMT_SBGGR8_1X8) {
851 coml_mask = COML_ONE_CHANNEL; 851 coml_mask = COML_ONE_CHANNEL;
852 coml_set = 0; 852 coml_set = 0;
@@ -936,8 +936,8 @@ static int ov6650_try_fmt(struct v4l2_subdev *sd,
936 936
937 switch (mf->code) { 937 switch (mf->code) {
938 case V4L2_MBUS_FMT_Y10_1X10: 938 case V4L2_MBUS_FMT_Y10_1X10:
939 mf->code = V4L2_MBUS_FMT_GREY8_1X8; 939 mf->code = V4L2_MBUS_FMT_Y8_1X8;
940 case V4L2_MBUS_FMT_GREY8_1X8: 940 case V4L2_MBUS_FMT_Y8_1X8:
941 case V4L2_MBUS_FMT_YVYU8_2X8: 941 case V4L2_MBUS_FMT_YVYU8_2X8:
942 case V4L2_MBUS_FMT_YUYV8_2X8: 942 case V4L2_MBUS_FMT_YUYV8_2X8:
943 case V4L2_MBUS_FMT_VYUY8_2X8: 943 case V4L2_MBUS_FMT_VYUY8_2X8:
diff --git a/drivers/media/video/ov9740.c b/drivers/media/video/ov9740.c
new file mode 100644
index 000000000000..4d4ee4faca69
--- /dev/null
+++ b/drivers/media/video/ov9740.c
@@ -0,0 +1,1009 @@
1/*
2 * OmniVision OV9740 Camera Driver
3 *
4 * Copyright (C) 2011 NVIDIA Corporation
5 *
6 * Based on ov9640 camera 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 version 2 as
10 * published by the Free Software Foundation.
11 */
12
13#include <linux/init.h>
14#include <linux/module.h>
15#include <linux/i2c.h>
16#include <linux/slab.h>
17#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h>
19
20#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
21
22/* General Status Registers */
23#define OV9740_MODEL_ID_HI 0x0000
24#define OV9740_MODEL_ID_LO 0x0001
25#define OV9740_REVISION_NUMBER 0x0002
26#define OV9740_MANUFACTURER_ID 0x0003
27#define OV9740_SMIA_VERSION 0x0004
28
29/* General Setup Registers */
30#define OV9740_MODE_SELECT 0x0100
31#define OV9740_IMAGE_ORT 0x0101
32#define OV9740_SOFTWARE_RESET 0x0103
33#define OV9740_GRP_PARAM_HOLD 0x0104
34#define OV9740_MSK_CORRUP_FM 0x0105
35
36/* Timing Setting */
37#define OV9740_FRM_LENGTH_LN_HI 0x0340 /* VTS */
38#define OV9740_FRM_LENGTH_LN_LO 0x0341 /* VTS */
39#define OV9740_LN_LENGTH_PCK_HI 0x0342 /* HTS */
40#define OV9740_LN_LENGTH_PCK_LO 0x0343 /* HTS */
41#define OV9740_X_ADDR_START_HI 0x0344
42#define OV9740_X_ADDR_START_LO 0x0345
43#define OV9740_Y_ADDR_START_HI 0x0346
44#define OV9740_Y_ADDR_START_LO 0x0347
45#define OV9740_X_ADDR_END_HI 0x0348
46#define OV9740_X_ADDR_END_LO 0x0349
47#define OV9740_Y_ADDR_END_HI 0x034A
48#define OV9740_Y_ADDR_END_LO 0x034B
49#define OV9740_X_OUTPUT_SIZE_HI 0x034C
50#define OV9740_X_OUTPUT_SIZE_LO 0x034D
51#define OV9740_Y_OUTPUT_SIZE_HI 0x034E
52#define OV9740_Y_OUTPUT_SIZE_LO 0x034F
53
54/* IO Control Registers */
55#define OV9740_IO_CREL00 0x3002
56#define OV9740_IO_CREL01 0x3004
57#define OV9740_IO_CREL02 0x3005
58#define OV9740_IO_OUTPUT_SEL01 0x3026
59#define OV9740_IO_OUTPUT_SEL02 0x3027
60
61/* AWB Registers */
62#define OV9740_AWB_MANUAL_CTRL 0x3406
63
64/* Analog Control Registers */
65#define OV9740_ANALOG_CTRL01 0x3601
66#define OV9740_ANALOG_CTRL02 0x3602
67#define OV9740_ANALOG_CTRL03 0x3603
68#define OV9740_ANALOG_CTRL04 0x3604
69#define OV9740_ANALOG_CTRL10 0x3610
70#define OV9740_ANALOG_CTRL12 0x3612
71#define OV9740_ANALOG_CTRL20 0x3620
72#define OV9740_ANALOG_CTRL21 0x3621
73#define OV9740_ANALOG_CTRL22 0x3622
74#define OV9740_ANALOG_CTRL30 0x3630
75#define OV9740_ANALOG_CTRL31 0x3631
76#define OV9740_ANALOG_CTRL32 0x3632
77#define OV9740_ANALOG_CTRL33 0x3633
78
79/* Sensor Control */
80#define OV9740_SENSOR_CTRL03 0x3703
81#define OV9740_SENSOR_CTRL04 0x3704
82#define OV9740_SENSOR_CTRL05 0x3705
83#define OV9740_SENSOR_CTRL07 0x3707
84
85/* Timing Control */
86#define OV9740_TIMING_CTRL17 0x3817
87#define OV9740_TIMING_CTRL19 0x3819
88#define OV9740_TIMING_CTRL33 0x3833
89#define OV9740_TIMING_CTRL35 0x3835
90
91/* Banding Filter */
92#define OV9740_AEC_MAXEXPO_60_H 0x3A02
93#define OV9740_AEC_MAXEXPO_60_L 0x3A03
94#define OV9740_AEC_B50_STEP_HI 0x3A08
95#define OV9740_AEC_B50_STEP_LO 0x3A09
96#define OV9740_AEC_B60_STEP_HI 0x3A0A
97#define OV9740_AEC_B60_STEP_LO 0x3A0B
98#define OV9740_AEC_CTRL0D 0x3A0D
99#define OV9740_AEC_CTRL0E 0x3A0E
100#define OV9740_AEC_MAXEXPO_50_H 0x3A14
101#define OV9740_AEC_MAXEXPO_50_L 0x3A15
102
103/* AEC/AGC Control */
104#define OV9740_AEC_ENABLE 0x3503
105#define OV9740_GAIN_CEILING_01 0x3A18
106#define OV9740_GAIN_CEILING_02 0x3A19
107#define OV9740_AEC_HI_THRESHOLD 0x3A11
108#define OV9740_AEC_3A1A 0x3A1A
109#define OV9740_AEC_CTRL1B_WPT2 0x3A1B
110#define OV9740_AEC_CTRL0F_WPT 0x3A0F
111#define OV9740_AEC_CTRL10_BPT 0x3A10
112#define OV9740_AEC_CTRL1E_BPT2 0x3A1E
113#define OV9740_AEC_LO_THRESHOLD 0x3A1F
114
115/* BLC Control */
116#define OV9740_BLC_AUTO_ENABLE 0x4002
117#define OV9740_BLC_MODE 0x4005
118
119/* VFIFO */
120#define OV9740_VFIFO_READ_START_HI 0x4608
121#define OV9740_VFIFO_READ_START_LO 0x4609
122
123/* DVP Control */
124#define OV9740_DVP_VSYNC_CTRL02 0x4702
125#define OV9740_DVP_VSYNC_MODE 0x4704
126#define OV9740_DVP_VSYNC_CTRL06 0x4706
127
128/* PLL Setting */
129#define OV9740_PLL_MODE_CTRL01 0x3104
130#define OV9740_PRE_PLL_CLK_DIV 0x0305
131#define OV9740_PLL_MULTIPLIER 0x0307
132#define OV9740_VT_SYS_CLK_DIV 0x0303
133#define OV9740_VT_PIX_CLK_DIV 0x0301
134#define OV9740_PLL_CTRL3010 0x3010
135#define OV9740_VFIFO_CTRL00 0x460E
136
137/* ISP Control */
138#define OV9740_ISP_CTRL00 0x5000
139#define OV9740_ISP_CTRL01 0x5001
140#define OV9740_ISP_CTRL03 0x5003
141#define OV9740_ISP_CTRL05 0x5005
142#define OV9740_ISP_CTRL12 0x5012
143#define OV9740_ISP_CTRL19 0x5019
144#define OV9740_ISP_CTRL1A 0x501A
145#define OV9740_ISP_CTRL1E 0x501E
146#define OV9740_ISP_CTRL1F 0x501F
147#define OV9740_ISP_CTRL20 0x5020
148#define OV9740_ISP_CTRL21 0x5021
149
150/* AWB */
151#define OV9740_AWB_CTRL00 0x5180
152#define OV9740_AWB_CTRL01 0x5181
153#define OV9740_AWB_CTRL02 0x5182
154#define OV9740_AWB_CTRL03 0x5183
155#define OV9740_AWB_ADV_CTRL01 0x5184
156#define OV9740_AWB_ADV_CTRL02 0x5185
157#define OV9740_AWB_ADV_CTRL03 0x5186
158#define OV9740_AWB_ADV_CTRL04 0x5187
159#define OV9740_AWB_ADV_CTRL05 0x5188
160#define OV9740_AWB_ADV_CTRL06 0x5189
161#define OV9740_AWB_ADV_CTRL07 0x518A
162#define OV9740_AWB_ADV_CTRL08 0x518B
163#define OV9740_AWB_ADV_CTRL09 0x518C
164#define OV9740_AWB_ADV_CTRL10 0x518D
165#define OV9740_AWB_ADV_CTRL11 0x518E
166#define OV9740_AWB_CTRL0F 0x518F
167#define OV9740_AWB_CTRL10 0x5190
168#define OV9740_AWB_CTRL11 0x5191
169#define OV9740_AWB_CTRL12 0x5192
170#define OV9740_AWB_CTRL13 0x5193
171#define OV9740_AWB_CTRL14 0x5194
172
173/* MIPI Control */
174#define OV9740_MIPI_CTRL00 0x4800
175#define OV9740_MIPI_3837 0x3837
176#define OV9740_MIPI_CTRL01 0x4801
177#define OV9740_MIPI_CTRL03 0x4803
178#define OV9740_MIPI_CTRL05 0x4805
179#define OV9740_VFIFO_RD_CTRL 0x4601
180#define OV9740_MIPI_CTRL_3012 0x3012
181#define OV9740_SC_CMMM_MIPI_CTR 0x3014
182
183/* supported resolutions */
184enum {
185 OV9740_VGA,
186 OV9740_720P,
187};
188
189struct ov9740_resolution {
190 unsigned int width;
191 unsigned int height;
192};
193
194static struct ov9740_resolution ov9740_resolutions[] = {
195 [OV9740_VGA] = {
196 .width = 640,
197 .height = 480,
198 },
199 [OV9740_720P] = {
200 .width = 1280,
201 .height = 720,
202 },
203};
204
205/* Misc. structures */
206struct ov9740_reg {
207 u16 reg;
208 u8 val;
209};
210
211struct ov9740_priv {
212 struct v4l2_subdev subdev;
213
214 int ident;
215 u16 model;
216 u8 revision;
217 u8 manid;
218 u8 smiaver;
219
220 bool flag_vflip;
221 bool flag_hflip;
222};
223
224static const struct ov9740_reg ov9740_defaults[] = {
225 /* Banding Filter */
226 { OV9740_AEC_B50_STEP_HI, 0x00 },
227 { OV9740_AEC_B50_STEP_LO, 0xe8 },
228 { OV9740_AEC_CTRL0E, 0x03 },
229 { OV9740_AEC_MAXEXPO_50_H, 0x15 },
230 { OV9740_AEC_MAXEXPO_50_L, 0xc6 },
231 { OV9740_AEC_B60_STEP_HI, 0x00 },
232 { OV9740_AEC_B60_STEP_LO, 0xc0 },
233 { OV9740_AEC_CTRL0D, 0x04 },
234 { OV9740_AEC_MAXEXPO_60_H, 0x18 },
235 { OV9740_AEC_MAXEXPO_60_L, 0x20 },
236
237 /* LC */
238 { 0x5842, 0x02 }, { 0x5843, 0x5e }, { 0x5844, 0x04 }, { 0x5845, 0x32 },
239 { 0x5846, 0x03 }, { 0x5847, 0x29 }, { 0x5848, 0x02 }, { 0x5849, 0xcc },
240
241 /* Un-documented OV9740 registers */
242 { 0x5800, 0x29 }, { 0x5801, 0x25 }, { 0x5802, 0x20 }, { 0x5803, 0x21 },
243 { 0x5804, 0x26 }, { 0x5805, 0x2e }, { 0x5806, 0x11 }, { 0x5807, 0x0c },
244 { 0x5808, 0x09 }, { 0x5809, 0x0a }, { 0x580A, 0x0e }, { 0x580B, 0x16 },
245 { 0x580C, 0x06 }, { 0x580D, 0x02 }, { 0x580E, 0x00 }, { 0x580F, 0x00 },
246 { 0x5810, 0x04 }, { 0x5811, 0x0a }, { 0x5812, 0x05 }, { 0x5813, 0x02 },
247 { 0x5814, 0x00 }, { 0x5815, 0x00 }, { 0x5816, 0x03 }, { 0x5817, 0x09 },
248 { 0x5818, 0x0f }, { 0x5819, 0x0a }, { 0x581A, 0x07 }, { 0x581B, 0x08 },
249 { 0x581C, 0x0b }, { 0x581D, 0x14 }, { 0x581E, 0x28 }, { 0x581F, 0x23 },
250 { 0x5820, 0x1d }, { 0x5821, 0x1e }, { 0x5822, 0x24 }, { 0x5823, 0x2a },
251 { 0x5824, 0x4f }, { 0x5825, 0x6f }, { 0x5826, 0x5f }, { 0x5827, 0x7f },
252 { 0x5828, 0x9f }, { 0x5829, 0x5f }, { 0x582A, 0x8f }, { 0x582B, 0x9e },
253 { 0x582C, 0x8f }, { 0x582D, 0x9f }, { 0x582E, 0x4f }, { 0x582F, 0x87 },
254 { 0x5830, 0x86 }, { 0x5831, 0x97 }, { 0x5832, 0xae }, { 0x5833, 0x3f },
255 { 0x5834, 0x8e }, { 0x5835, 0x7c }, { 0x5836, 0x7e }, { 0x5837, 0xaf },
256 { 0x5838, 0x8f }, { 0x5839, 0x8f }, { 0x583A, 0x9f }, { 0x583B, 0x7f },
257 { 0x583C, 0x5f },
258
259 /* Y Gamma */
260 { 0x5480, 0x07 }, { 0x5481, 0x18 }, { 0x5482, 0x2c }, { 0x5483, 0x4e },
261 { 0x5484, 0x5e }, { 0x5485, 0x6b }, { 0x5486, 0x77 }, { 0x5487, 0x82 },
262 { 0x5488, 0x8c }, { 0x5489, 0x95 }, { 0x548A, 0xa4 }, { 0x548B, 0xb1 },
263 { 0x548C, 0xc6 }, { 0x548D, 0xd8 }, { 0x548E, 0xe9 },
264
265 /* UV Gamma */
266 { 0x5490, 0x0f }, { 0x5491, 0xff }, { 0x5492, 0x0d }, { 0x5493, 0x05 },
267 { 0x5494, 0x07 }, { 0x5495, 0x1a }, { 0x5496, 0x04 }, { 0x5497, 0x01 },
268 { 0x5498, 0x03 }, { 0x5499, 0x53 }, { 0x549A, 0x02 }, { 0x549B, 0xeb },
269 { 0x549C, 0x02 }, { 0x549D, 0xa0 }, { 0x549E, 0x02 }, { 0x549F, 0x67 },
270 { 0x54A0, 0x02 }, { 0x54A1, 0x3b }, { 0x54A2, 0x02 }, { 0x54A3, 0x18 },
271 { 0x54A4, 0x01 }, { 0x54A5, 0xe7 }, { 0x54A6, 0x01 }, { 0x54A7, 0xc3 },
272 { 0x54A8, 0x01 }, { 0x54A9, 0x94 }, { 0x54AA, 0x01 }, { 0x54AB, 0x72 },
273 { 0x54AC, 0x01 }, { 0x54AD, 0x57 },
274
275 /* AWB */
276 { OV9740_AWB_CTRL00, 0xf0 },
277 { OV9740_AWB_CTRL01, 0x00 },
278 { OV9740_AWB_CTRL02, 0x41 },
279 { OV9740_AWB_CTRL03, 0x42 },
280 { OV9740_AWB_ADV_CTRL01, 0x8a },
281 { OV9740_AWB_ADV_CTRL02, 0x61 },
282 { OV9740_AWB_ADV_CTRL03, 0xce },
283 { OV9740_AWB_ADV_CTRL04, 0xa8 },
284 { OV9740_AWB_ADV_CTRL05, 0x17 },
285 { OV9740_AWB_ADV_CTRL06, 0x1f },
286 { OV9740_AWB_ADV_CTRL07, 0x27 },
287 { OV9740_AWB_ADV_CTRL08, 0x41 },
288 { OV9740_AWB_ADV_CTRL09, 0x34 },
289 { OV9740_AWB_ADV_CTRL10, 0xf0 },
290 { OV9740_AWB_ADV_CTRL11, 0x10 },
291 { OV9740_AWB_CTRL0F, 0xff },
292 { OV9740_AWB_CTRL10, 0x00 },
293 { OV9740_AWB_CTRL11, 0xff },
294 { OV9740_AWB_CTRL12, 0x00 },
295 { OV9740_AWB_CTRL13, 0xff },
296 { OV9740_AWB_CTRL14, 0x00 },
297
298 /* CIP */
299 { 0x530D, 0x12 },
300
301 /* CMX */
302 { 0x5380, 0x01 }, { 0x5381, 0x00 }, { 0x5382, 0x00 }, { 0x5383, 0x17 },
303 { 0x5384, 0x00 }, { 0x5385, 0x01 }, { 0x5386, 0x00 }, { 0x5387, 0x00 },
304 { 0x5388, 0x00 }, { 0x5389, 0xe0 }, { 0x538A, 0x00 }, { 0x538B, 0x20 },
305 { 0x538C, 0x00 }, { 0x538D, 0x00 }, { 0x538E, 0x00 }, { 0x538F, 0x16 },
306 { 0x5390, 0x00 }, { 0x5391, 0x9c }, { 0x5392, 0x00 }, { 0x5393, 0xa0 },
307 { 0x5394, 0x18 },
308
309 /* 50/60 Detection */
310 { 0x3C0A, 0x9c }, { 0x3C0B, 0x3f },
311
312 /* Output Select */
313 { OV9740_IO_OUTPUT_SEL01, 0x00 },
314 { OV9740_IO_OUTPUT_SEL02, 0x00 },
315 { OV9740_IO_CREL00, 0x00 },
316 { OV9740_IO_CREL01, 0x00 },
317 { OV9740_IO_CREL02, 0x00 },
318
319 /* AWB Control */
320 { OV9740_AWB_MANUAL_CTRL, 0x00 },
321
322 /* Analog Control */
323 { OV9740_ANALOG_CTRL03, 0xaa },
324 { OV9740_ANALOG_CTRL32, 0x2f },
325 { OV9740_ANALOG_CTRL20, 0x66 },
326 { OV9740_ANALOG_CTRL21, 0xc0 },
327 { OV9740_ANALOG_CTRL31, 0x52 },
328 { OV9740_ANALOG_CTRL33, 0x50 },
329 { OV9740_ANALOG_CTRL30, 0xca },
330 { OV9740_ANALOG_CTRL04, 0x0c },
331 { OV9740_ANALOG_CTRL01, 0x40 },
332 { OV9740_ANALOG_CTRL02, 0x16 },
333 { OV9740_ANALOG_CTRL10, 0xa1 },
334 { OV9740_ANALOG_CTRL12, 0x24 },
335 { OV9740_ANALOG_CTRL22, 0x9f },
336
337 /* Sensor Control */
338 { OV9740_SENSOR_CTRL03, 0x42 },
339 { OV9740_SENSOR_CTRL04, 0x10 },
340 { OV9740_SENSOR_CTRL05, 0x45 },
341 { OV9740_SENSOR_CTRL07, 0x14 },
342
343 /* Timing Control */
344 { OV9740_TIMING_CTRL33, 0x04 },
345 { OV9740_TIMING_CTRL35, 0x02 },
346 { OV9740_TIMING_CTRL19, 0x6e },
347 { OV9740_TIMING_CTRL17, 0x94 },
348
349 /* AEC/AGC Control */
350 { OV9740_AEC_ENABLE, 0x10 },
351 { OV9740_GAIN_CEILING_01, 0x00 },
352 { OV9740_GAIN_CEILING_02, 0x7f },
353 { OV9740_AEC_HI_THRESHOLD, 0xa0 },
354 { OV9740_AEC_3A1A, 0x05 },
355 { OV9740_AEC_CTRL1B_WPT2, 0x50 },
356 { OV9740_AEC_CTRL0F_WPT, 0x50 },
357 { OV9740_AEC_CTRL10_BPT, 0x4c },
358 { OV9740_AEC_CTRL1E_BPT2, 0x4c },
359 { OV9740_AEC_LO_THRESHOLD, 0x26 },
360
361 /* BLC Control */
362 { OV9740_BLC_AUTO_ENABLE, 0x45 },
363 { OV9740_BLC_MODE, 0x18 },
364
365 /* DVP Control */
366 { OV9740_DVP_VSYNC_CTRL02, 0x04 },
367 { OV9740_DVP_VSYNC_MODE, 0x00 },
368 { OV9740_DVP_VSYNC_CTRL06, 0x08 },
369
370 /* PLL Setting */
371 { OV9740_PLL_MODE_CTRL01, 0x20 },
372 { OV9740_PRE_PLL_CLK_DIV, 0x03 },
373 { OV9740_PLL_MULTIPLIER, 0x4c },
374 { OV9740_VT_SYS_CLK_DIV, 0x01 },
375 { OV9740_VT_PIX_CLK_DIV, 0x08 },
376 { OV9740_PLL_CTRL3010, 0x01 },
377 { OV9740_VFIFO_CTRL00, 0x82 },
378
379 /* Timing Setting */
380 /* VTS */
381 { OV9740_FRM_LENGTH_LN_HI, 0x03 },
382 { OV9740_FRM_LENGTH_LN_LO, 0x07 },
383 /* HTS */
384 { OV9740_LN_LENGTH_PCK_HI, 0x06 },
385 { OV9740_LN_LENGTH_PCK_LO, 0x62 },
386
387 /* MIPI Control */
388 { OV9740_MIPI_CTRL00, 0x44 },
389 { OV9740_MIPI_3837, 0x01 },
390 { OV9740_MIPI_CTRL01, 0x0f },
391 { OV9740_MIPI_CTRL03, 0x05 },
392 { OV9740_MIPI_CTRL05, 0x10 },
393 { OV9740_VFIFO_RD_CTRL, 0x16 },
394 { OV9740_MIPI_CTRL_3012, 0x70 },
395 { OV9740_SC_CMMM_MIPI_CTR, 0x01 },
396};
397
398static const struct ov9740_reg ov9740_regs_vga[] = {
399 { OV9740_X_ADDR_START_HI, 0x00 },
400 { OV9740_X_ADDR_START_LO, 0xa0 },
401 { OV9740_Y_ADDR_START_HI, 0x00 },
402 { OV9740_Y_ADDR_START_LO, 0x00 },
403 { OV9740_X_ADDR_END_HI, 0x04 },
404 { OV9740_X_ADDR_END_LO, 0x63 },
405 { OV9740_Y_ADDR_END_HI, 0x02 },
406 { OV9740_Y_ADDR_END_LO, 0xd3 },
407 { OV9740_X_OUTPUT_SIZE_HI, 0x02 },
408 { OV9740_X_OUTPUT_SIZE_LO, 0x80 },
409 { OV9740_Y_OUTPUT_SIZE_HI, 0x01 },
410 { OV9740_Y_OUTPUT_SIZE_LO, 0xe0 },
411 { OV9740_ISP_CTRL1E, 0x03 },
412 { OV9740_ISP_CTRL1F, 0xc0 },
413 { OV9740_ISP_CTRL20, 0x02 },
414 { OV9740_ISP_CTRL21, 0xd0 },
415 { OV9740_VFIFO_READ_START_HI, 0x01 },
416 { OV9740_VFIFO_READ_START_LO, 0x40 },
417 { OV9740_ISP_CTRL00, 0xff },
418 { OV9740_ISP_CTRL01, 0xff },
419 { OV9740_ISP_CTRL03, 0xff },
420};
421
422static const struct ov9740_reg ov9740_regs_720p[] = {
423 { OV9740_X_ADDR_START_HI, 0x00 },
424 { OV9740_X_ADDR_START_LO, 0x00 },
425 { OV9740_Y_ADDR_START_HI, 0x00 },
426 { OV9740_Y_ADDR_START_LO, 0x00 },
427 { OV9740_X_ADDR_END_HI, 0x05 },
428 { OV9740_X_ADDR_END_LO, 0x03 },
429 { OV9740_Y_ADDR_END_HI, 0x02 },
430 { OV9740_Y_ADDR_END_LO, 0xd3 },
431 { OV9740_X_OUTPUT_SIZE_HI, 0x05 },
432 { OV9740_X_OUTPUT_SIZE_LO, 0x00 },
433 { OV9740_Y_OUTPUT_SIZE_HI, 0x02 },
434 { OV9740_Y_OUTPUT_SIZE_LO, 0xd0 },
435 { OV9740_ISP_CTRL1E, 0x05 },
436 { OV9740_ISP_CTRL1F, 0x00 },
437 { OV9740_ISP_CTRL20, 0x02 },
438 { OV9740_ISP_CTRL21, 0xd0 },
439 { OV9740_VFIFO_READ_START_HI, 0x02 },
440 { OV9740_VFIFO_READ_START_LO, 0x30 },
441 { OV9740_ISP_CTRL00, 0xff },
442 { OV9740_ISP_CTRL01, 0xef },
443 { OV9740_ISP_CTRL03, 0xff },
444};
445
446static enum v4l2_mbus_pixelcode ov9740_codes[] = {
447 V4L2_MBUS_FMT_YUYV8_2X8,
448};
449
450static const struct v4l2_queryctrl ov9740_controls[] = {
451 {
452 .id = V4L2_CID_VFLIP,
453 .type = V4L2_CTRL_TYPE_BOOLEAN,
454 .name = "Flip Vertically",
455 .minimum = 0,
456 .maximum = 1,
457 .step = 1,
458 .default_value = 0,
459 },
460 {
461 .id = V4L2_CID_HFLIP,
462 .type = V4L2_CTRL_TYPE_BOOLEAN,
463 .name = "Flip Horizontally",
464 .minimum = 0,
465 .maximum = 1,
466 .step = 1,
467 .default_value = 0,
468 },
469};
470
471/* read a register */
472static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
473{
474 int ret;
475 struct i2c_msg msg[] = {
476 {
477 .addr = client->addr,
478 .flags = 0,
479 .len = 2,
480 .buf = (u8 *)&reg,
481 },
482 {
483 .addr = client->addr,
484 .flags = I2C_M_RD,
485 .len = 1,
486 .buf = val,
487 },
488 };
489
490 reg = swab16(reg);
491
492 ret = i2c_transfer(client->adapter, msg, 2);
493 if (ret < 0) {
494 dev_err(&client->dev, "Failed reading register 0x%04x!\n", reg);
495 return ret;
496 }
497
498 return 0;
499}
500
501/* write a register */
502static int ov9740_reg_write(struct i2c_client *client, u16 reg, u8 val)
503{
504 struct i2c_msg msg;
505 struct {
506 u16 reg;
507 u8 val;
508 } __packed buf;
509 int ret;
510
511 reg = swab16(reg);
512
513 buf.reg = reg;
514 buf.val = val;
515
516 msg.addr = client->addr;
517 msg.flags = 0;
518 msg.len = 3;
519 msg.buf = (u8 *)&buf;
520
521 ret = i2c_transfer(client->adapter, &msg, 1);
522 if (ret < 0) {
523 dev_err(&client->dev, "Failed writing register 0x%04x!\n", reg);
524 return ret;
525 }
526
527 return 0;
528}
529
530
531/* Read a register, alter its bits, write it back */
532static int ov9740_reg_rmw(struct i2c_client *client, u16 reg, u8 set, u8 unset)
533{
534 u8 val;
535 int ret;
536
537 ret = ov9740_reg_read(client, reg, &val);
538 if (ret < 0) {
539 dev_err(&client->dev,
540 "[Read]-Modify-Write of register %02x failed!\n", reg);
541 return ret;
542 }
543
544 val |= set;
545 val &= ~unset;
546
547 ret = ov9740_reg_write(client, reg, val);
548 if (ret < 0) {
549 dev_err(&client->dev,
550 "Read-Modify-[Write] of register %02x failed!\n", reg);
551 return ret;
552 }
553
554 return 0;
555}
556
557static int ov9740_reg_write_array(struct i2c_client *client,
558 const struct ov9740_reg *regarray,
559 int regarraylen)
560{
561 int i;
562 int ret;
563
564 for (i = 0; i < regarraylen; i++) {
565 ret = ov9740_reg_write(client,
566 regarray[i].reg, regarray[i].val);
567 if (ret < 0)
568 return ret;
569 }
570
571 return 0;
572}
573
574/* Start/Stop streaming from the device */
575static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
576{
577 struct i2c_client *client = v4l2_get_subdevdata(sd);
578 struct ov9740_priv *priv = to_ov9740(sd);
579 int ret;
580
581 /* Program orientation register. */
582 if (priv->flag_vflip)
583 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x2, 0);
584 else
585 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x2);
586 if (ret < 0)
587 return ret;
588
589 if (priv->flag_hflip)
590 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0x1, 0);
591 else
592 ret = ov9740_reg_rmw(client, OV9740_IMAGE_ORT, 0, 0x1);
593 if (ret < 0)
594 return ret;
595
596 if (enable) {
597 dev_dbg(&client->dev, "Enabling Streaming\n");
598 /* Start Streaming */
599 ret = ov9740_reg_write(client, OV9740_MODE_SELECT, 0x01);
600
601 } else {
602 dev_dbg(&client->dev, "Disabling Streaming\n");
603 /* Software Reset */
604 ret = ov9740_reg_write(client, OV9740_SOFTWARE_RESET, 0x01);
605 if (!ret)
606 /* Setting Streaming to Standby */
607 ret = ov9740_reg_write(client, OV9740_MODE_SELECT,
608 0x00);
609 }
610
611 return ret;
612}
613
614/* Alter bus settings on camera side */
615static int ov9740_set_bus_param(struct soc_camera_device *icd,
616 unsigned long flags)
617{
618 return 0;
619}
620
621/* Request bus settings on camera side */
622static unsigned long ov9740_query_bus_param(struct soc_camera_device *icd)
623{
624 struct soc_camera_link *icl = to_soc_camera_link(icd);
625
626 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
627 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
628 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
629
630 return soc_camera_apply_sensor_flags(icl, flags);
631}
632
633/* Get status of additional camera capabilities */
634static int ov9740_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
635{
636 struct ov9740_priv *priv = to_ov9740(sd);
637
638 switch (ctrl->id) {
639 case V4L2_CID_VFLIP:
640 ctrl->value = priv->flag_vflip;
641 break;
642 case V4L2_CID_HFLIP:
643 ctrl->value = priv->flag_hflip;
644 break;
645 default:
646 return -EINVAL;
647 }
648
649 return 0;
650}
651
652/* Set status of additional camera capabilities */
653static int ov9740_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
654{
655 struct ov9740_priv *priv = to_ov9740(sd);
656
657 switch (ctrl->id) {
658 case V4L2_CID_VFLIP:
659 priv->flag_vflip = ctrl->value;
660 break;
661 case V4L2_CID_HFLIP:
662 priv->flag_hflip = ctrl->value;
663 break;
664 default:
665 return -EINVAL;
666 }
667
668 return 0;
669}
670
671/* Get chip identification */
672static int ov9740_g_chip_ident(struct v4l2_subdev *sd,
673 struct v4l2_dbg_chip_ident *id)
674{
675 struct ov9740_priv *priv = to_ov9740(sd);
676
677 id->ident = priv->ident;
678 id->revision = priv->revision;
679
680 return 0;
681}
682
683#ifdef CONFIG_VIDEO_ADV_DEBUG
684static int ov9740_get_register(struct v4l2_subdev *sd,
685 struct v4l2_dbg_register *reg)
686{
687 struct i2c_client *client = v4l2_get_subdevdata(sd);
688 int ret;
689 u8 val;
690
691 if (reg->reg & ~0xffff)
692 return -EINVAL;
693
694 reg->size = 2;
695
696 ret = ov9740_reg_read(client, reg->reg, &val);
697 if (ret)
698 return ret;
699
700 reg->val = (__u64)val;
701
702 return ret;
703}
704
705static int ov9740_set_register(struct v4l2_subdev *sd,
706 struct v4l2_dbg_register *reg)
707{
708 struct i2c_client *client = v4l2_get_subdevdata(sd);
709
710 if (reg->reg & ~0xffff || reg->val & ~0xff)
711 return -EINVAL;
712
713 return ov9740_reg_write(client, reg->reg, reg->val);
714}
715#endif
716
717/* select nearest higher resolution for capture */
718static void ov9740_res_roundup(u32 *width, u32 *height)
719{
720 int i;
721
722 for (i = 0; i < ARRAY_SIZE(ov9740_resolutions); i++)
723 if ((ov9740_resolutions[i].width >= *width) &&
724 (ov9740_resolutions[i].height >= *height)) {
725 *width = ov9740_resolutions[i].width;
726 *height = ov9740_resolutions[i].height;
727 return;
728 }
729
730 *width = ov9740_resolutions[OV9740_720P].width;
731 *height = ov9740_resolutions[OV9740_720P].height;
732}
733
734/* Setup registers according to resolution and color encoding */
735static int ov9740_set_res(struct i2c_client *client, u32 width)
736{
737 int ret;
738
739 /* select register configuration for given resolution */
740 if (width == ov9740_resolutions[OV9740_VGA].width) {
741 dev_dbg(&client->dev, "Setting image size to 640x480\n");
742 ret = ov9740_reg_write_array(client, ov9740_regs_vga,
743 ARRAY_SIZE(ov9740_regs_vga));
744 } else if (width == ov9740_resolutions[OV9740_720P].width) {
745 dev_dbg(&client->dev, "Setting image size to 1280x720\n");
746 ret = ov9740_reg_write_array(client, ov9740_regs_720p,
747 ARRAY_SIZE(ov9740_regs_720p));
748 } else {
749 dev_err(&client->dev, "Failed to select resolution!\n");
750 return -EINVAL;
751 }
752
753 return ret;
754}
755
756/* set the format we will capture in */
757static int ov9740_s_fmt(struct v4l2_subdev *sd,
758 struct v4l2_mbus_framefmt *mf)
759{
760 struct i2c_client *client = v4l2_get_subdevdata(sd);
761 enum v4l2_colorspace cspace;
762 enum v4l2_mbus_pixelcode code = mf->code;
763 int ret;
764
765 ov9740_res_roundup(&mf->width, &mf->height);
766
767 switch (code) {
768 case V4L2_MBUS_FMT_YUYV8_2X8:
769 cspace = V4L2_COLORSPACE_SRGB;
770 break;
771 default:
772 return -EINVAL;
773 }
774
775 ret = ov9740_reg_write_array(client, ov9740_defaults,
776 ARRAY_SIZE(ov9740_defaults));
777 if (ret < 0)
778 return ret;
779
780 ret = ov9740_set_res(client, mf->width);
781 if (ret < 0)
782 return ret;
783
784 mf->code = code;
785 mf->colorspace = cspace;
786
787 return ret;
788}
789
790static int ov9740_try_fmt(struct v4l2_subdev *sd,
791 struct v4l2_mbus_framefmt *mf)
792{
793 ov9740_res_roundup(&mf->width, &mf->height);
794
795 mf->field = V4L2_FIELD_NONE;
796 mf->code = V4L2_MBUS_FMT_YUYV8_2X8;
797 mf->colorspace = V4L2_COLORSPACE_SRGB;
798
799 return 0;
800}
801
802static int ov9740_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
803 enum v4l2_mbus_pixelcode *code)
804{
805 if (index >= ARRAY_SIZE(ov9740_codes))
806 return -EINVAL;
807
808 *code = ov9740_codes[index];
809
810 return 0;
811}
812
813static int ov9740_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
814{
815 a->bounds.left = 0;
816 a->bounds.top = 0;
817 a->bounds.width = ov9740_resolutions[OV9740_720P].width;
818 a->bounds.height = ov9740_resolutions[OV9740_720P].height;
819 a->defrect = a->bounds;
820 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
821 a->pixelaspect.numerator = 1;
822 a->pixelaspect.denominator = 1;
823
824 return 0;
825}
826
827static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
828{
829 a->c.left = 0;
830 a->c.top = 0;
831 a->c.width = ov9740_resolutions[OV9740_720P].width;
832 a->c.height = ov9740_resolutions[OV9740_720P].height;
833 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
834
835 return 0;
836}
837
838static int ov9740_video_probe(struct soc_camera_device *icd,
839 struct i2c_client *client)
840{
841 struct v4l2_subdev *sd = i2c_get_clientdata(client);
842 struct ov9740_priv *priv = to_ov9740(sd);
843 u8 modelhi, modello;
844 int ret;
845
846 /*
847 * We must have a parent by now. And it cannot be a wrong one.
848 * So this entire test is completely redundant.
849 */
850 if (!icd->dev.parent ||
851 to_soc_camera_host(icd->dev.parent)->nr != icd->iface) {
852 dev_err(&client->dev, "Parent missing or invalid!\n");
853 ret = -ENODEV;
854 goto err;
855 }
856
857 /*
858 * check and show product ID and manufacturer ID
859 */
860 ret = ov9740_reg_read(client, OV9740_MODEL_ID_HI, &modelhi);
861 if (ret < 0)
862 goto err;
863
864 ret = ov9740_reg_read(client, OV9740_MODEL_ID_LO, &modello);
865 if (ret < 0)
866 goto err;
867
868 priv->model = (modelhi << 8) | modello;
869
870 ret = ov9740_reg_read(client, OV9740_REVISION_NUMBER, &priv->revision);
871 if (ret < 0)
872 goto err;
873
874 ret = ov9740_reg_read(client, OV9740_MANUFACTURER_ID, &priv->manid);
875 if (ret < 0)
876 goto err;
877
878 ret = ov9740_reg_read(client, OV9740_SMIA_VERSION, &priv->smiaver);
879 if (ret < 0)
880 goto err;
881
882 if (priv->model != 0x9740) {
883 ret = -ENODEV;
884 goto err;
885 }
886
887 priv->ident = V4L2_IDENT_OV9740;
888
889 dev_info(&client->dev, "ov9740 Model ID 0x%04x, Revision 0x%02x, "
890 "Manufacturer 0x%02x, SMIA Version 0x%02x\n",
891 priv->model, priv->revision, priv->manid, priv->smiaver);
892
893err:
894 return ret;
895}
896
897static struct soc_camera_ops ov9740_ops = {
898 .set_bus_param = ov9740_set_bus_param,
899 .query_bus_param = ov9740_query_bus_param,
900 .controls = ov9740_controls,
901 .num_controls = ARRAY_SIZE(ov9740_controls),
902};
903
904static struct v4l2_subdev_core_ops ov9740_core_ops = {
905 .g_ctrl = ov9740_g_ctrl,
906 .s_ctrl = ov9740_s_ctrl,
907 .g_chip_ident = ov9740_g_chip_ident,
908#ifdef CONFIG_VIDEO_ADV_DEBUG
909 .g_register = ov9740_get_register,
910 .s_register = ov9740_set_register,
911#endif
912
913};
914
915static struct v4l2_subdev_video_ops ov9740_video_ops = {
916 .s_stream = ov9740_s_stream,
917 .s_mbus_fmt = ov9740_s_fmt,
918 .try_mbus_fmt = ov9740_try_fmt,
919 .enum_mbus_fmt = ov9740_enum_fmt,
920 .cropcap = ov9740_cropcap,
921 .g_crop = ov9740_g_crop,
922};
923
924static struct v4l2_subdev_ops ov9740_subdev_ops = {
925 .core = &ov9740_core_ops,
926 .video = &ov9740_video_ops,
927};
928
929/*
930 * i2c_driver function
931 */
932static int ov9740_probe(struct i2c_client *client,
933 const struct i2c_device_id *did)
934{
935 struct ov9740_priv *priv;
936 struct soc_camera_device *icd = client->dev.platform_data;
937 struct soc_camera_link *icl;
938 int ret;
939
940 if (!icd) {
941 dev_err(&client->dev, "Missing soc-camera data!\n");
942 return -EINVAL;
943 }
944
945 icl = to_soc_camera_link(icd);
946 if (!icl) {
947 dev_err(&client->dev, "Missing platform_data for driver\n");
948 return -EINVAL;
949 }
950
951 priv = kzalloc(sizeof(struct ov9740_priv), GFP_KERNEL);
952 if (!priv) {
953 dev_err(&client->dev, "Failed to allocate private data!\n");
954 return -ENOMEM;
955 }
956
957 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
958
959 icd->ops = &ov9740_ops;
960
961 ret = ov9740_video_probe(icd, client);
962 if (ret < 0) {
963 icd->ops = NULL;
964 kfree(priv);
965 }
966
967 return ret;
968}
969
970static int ov9740_remove(struct i2c_client *client)
971{
972 struct ov9740_priv *priv = i2c_get_clientdata(client);
973
974 kfree(priv);
975
976 return 0;
977}
978
979static const struct i2c_device_id ov9740_id[] = {
980 { "ov9740", 0 },
981 { }
982};
983MODULE_DEVICE_TABLE(i2c, ov9740_id);
984
985static struct i2c_driver ov9740_i2c_driver = {
986 .driver = {
987 .name = "ov9740",
988 },
989 .probe = ov9740_probe,
990 .remove = ov9740_remove,
991 .id_table = ov9740_id,
992};
993
994static int __init ov9740_module_init(void)
995{
996 return i2c_add_driver(&ov9740_i2c_driver);
997}
998
999static void __exit ov9740_module_exit(void)
1000{
1001 i2c_del_driver(&ov9740_i2c_driver);
1002}
1003
1004module_init(ov9740_module_init);
1005module_exit(ov9740_module_exit);
1006
1007MODULE_DESCRIPTION("SoC Camera driver for OmniVision OV9740");
1008MODULE_AUTHOR("Andrew Chew <achew@nvidia.com>");
1009MODULE_LICENSE("GPL v2");
diff --git a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
index 2222da8d0ca6..c514d0b9ffdc 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-cx2584x-v4l.c
@@ -99,9 +99,27 @@ static const struct routing_scheme routing_defgv = {
99 .cnt = ARRAY_SIZE(routing_schemegv), 99 .cnt = ARRAY_SIZE(routing_schemegv),
100}; 100};
101 101
102/* Specific to grabster av400 device */
103static const struct routing_scheme_item routing_schemeav400[] = {
104 [PVR2_CVAL_INPUT_COMPOSITE] = {
105 .vid = CX25840_COMPOSITE1,
106 .aud = CX25840_AUDIO_SERIAL,
107 },
108 [PVR2_CVAL_INPUT_SVIDEO] = {
109 .vid = (CX25840_SVIDEO_LUMA2|CX25840_SVIDEO_CHROMA4),
110 .aud = CX25840_AUDIO_SERIAL,
111 },
112};
113
114static const struct routing_scheme routing_defav400 = {
115 .def = routing_schemeav400,
116 .cnt = ARRAY_SIZE(routing_schemeav400),
117};
118
102static const struct routing_scheme *routing_schemes[] = { 119static const struct routing_scheme *routing_schemes[] = {
103 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0, 120 [PVR2_ROUTING_SCHEME_HAUPPAUGE] = &routing_def0,
104 [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv, 121 [PVR2_ROUTING_SCHEME_GOTVIEW] = &routing_defgv,
122 [PVR2_ROUTING_SCHEME_AV400] = &routing_defav400,
105}; 123};
106 124
107void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd) 125void pvr2_cx25840_subdev_update(struct pvr2_hdw *hdw, struct v4l2_subdev *sd)
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 3092abfd66a2..e799331389b1 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -157,6 +157,28 @@ static const struct pvr2_device_desc pvr2_device_gotview_2d = {
157 157
158 158
159/*------------------------------------------------------------------------*/ 159/*------------------------------------------------------------------------*/
160/* Terratec Grabster AV400 */
161
162static const struct pvr2_device_client_desc pvr2_cli_av400[] = {
163 { .module_id = PVR2_CLIENT_ID_CX25840 },
164};
165
166static const struct pvr2_device_desc pvr2_device_av400 = {
167 .description = "Terratec Grabster AV400",
168 .shortname = "av400",
169 .flag_is_experimental = 1,
170 .client_table.lst = pvr2_cli_av400,
171 .client_table.cnt = ARRAY_SIZE(pvr2_cli_av400),
172 .flag_has_cx25840 = !0,
173 .flag_has_analogtuner = 0,
174 .flag_has_composite = !0,
175 .flag_has_svideo = !0,
176 .signal_routing_scheme = PVR2_ROUTING_SCHEME_AV400,
177};
178
179
180
181/*------------------------------------------------------------------------*/
160/* OnAir Creator */ 182/* OnAir Creator */
161 183
162#ifdef CONFIG_VIDEO_PVRUSB2_DVB 184#ifdef CONFIG_VIDEO_PVRUSB2_DVB
@@ -517,6 +539,8 @@ struct usb_device_id pvr2_device_table[] = {
517 .driver_info = (kernel_ulong_t)&pvr2_device_750xx}, 539 .driver_info = (kernel_ulong_t)&pvr2_device_750xx},
518 { USB_DEVICE(0x2040, 0x7501), 540 { USB_DEVICE(0x2040, 0x7501),
519 .driver_info = (kernel_ulong_t)&pvr2_device_751xx}, 541 .driver_info = (kernel_ulong_t)&pvr2_device_751xx},
542 { USB_DEVICE(0x0ccd, 0x0039),
543 .driver_info = (kernel_ulong_t)&pvr2_device_av400},
520 { } 544 { }
521}; 545};
522 546
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index 66ad516bdfd9..9d0dd08f57f8 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -499,31 +499,35 @@ static int ctrl_cropt_max_get(struct pvr2_ctrl *cptr, int *top)
499 return 0; 499 return 0;
500} 500}
501 501
502static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *val) 502static int ctrl_cropw_max_get(struct pvr2_ctrl *cptr, int *width)
503{ 503{
504 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; 504 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
505 int stat = pvr2_hdw_check_cropcap(cptr->hdw); 505 int stat, bleftend, cleft;
506
507 stat = pvr2_hdw_check_cropcap(cptr->hdw);
506 if (stat != 0) { 508 if (stat != 0) {
507 return stat; 509 return stat;
508 } 510 }
509 *val = 0; 511 bleftend = cap->bounds.left+cap->bounds.width;
510 if (cap->bounds.width > cptr->hdw->cropl_val) { 512 cleft = cptr->hdw->cropl_val;
511 *val = cap->bounds.width - cptr->hdw->cropl_val; 513
512 } 514 *width = cleft < bleftend ? bleftend-cleft : 0;
513 return 0; 515 return 0;
514} 516}
515 517
516static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *val) 518static int ctrl_croph_max_get(struct pvr2_ctrl *cptr, int *height)
517{ 519{
518 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info; 520 struct v4l2_cropcap *cap = &cptr->hdw->cropcap_info;
519 int stat = pvr2_hdw_check_cropcap(cptr->hdw); 521 int stat, btopend, ctop;
522
523 stat = pvr2_hdw_check_cropcap(cptr->hdw);
520 if (stat != 0) { 524 if (stat != 0) {
521 return stat; 525 return stat;
522 } 526 }
523 *val = 0; 527 btopend = cap->bounds.top+cap->bounds.height;
524 if (cap->bounds.height > cptr->hdw->cropt_val) { 528 ctop = cptr->hdw->cropt_val;
525 *val = cap->bounds.height - cptr->hdw->cropt_val; 529
526 } 530 *height = ctop < btopend ? btopend-ctop : 0;
527 return 0; 531 return 0;
528} 532}
529 533
@@ -1114,6 +1118,7 @@ static const struct pvr2_ctl_info control_defs[] = {
1114 .internal_id = PVR2_CID_CROPW, 1118 .internal_id = PVR2_CID_CROPW,
1115 .default_value = 720, 1119 .default_value = 720,
1116 DEFREF(cropw), 1120 DEFREF(cropw),
1121 DEFINT(0, 864),
1117 .get_max_value = ctrl_cropw_max_get, 1122 .get_max_value = ctrl_cropw_max_get,
1118 .get_def_value = ctrl_get_cropcapdw, 1123 .get_def_value = ctrl_get_cropcapdw,
1119 }, { 1124 }, {
@@ -1122,6 +1127,7 @@ static const struct pvr2_ctl_info control_defs[] = {
1122 .internal_id = PVR2_CID_CROPH, 1127 .internal_id = PVR2_CID_CROPH,
1123 .default_value = 480, 1128 .default_value = 480,
1124 DEFREF(croph), 1129 DEFREF(croph),
1130 DEFINT(0, 576),
1125 .get_max_value = ctrl_croph_max_get, 1131 .get_max_value = ctrl_croph_max_get,
1126 .get_def_value = ctrl_get_cropcapdh, 1132 .get_def_value = ctrl_get_cropcapdh,
1127 }, { 1133 }, {
@@ -2027,6 +2033,8 @@ static void pvr2_hdw_cx25840_vbi_hack(struct pvr2_hdw *hdw)
2027 hdw->decoder_client_id); 2033 hdw->decoder_client_id);
2028 memset(&fmt, 0, sizeof(fmt)); 2034 memset(&fmt, 0, sizeof(fmt));
2029 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE; 2035 fmt.type = V4L2_BUF_TYPE_SLICED_VBI_CAPTURE;
2036 fmt.fmt.sliced.service_lines[0][21] = V4L2_SLICED_CAPTION_525;
2037 fmt.fmt.sliced.service_lines[1][21] = V4L2_SLICED_CAPTION_525;
2030 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id, 2038 v4l2_device_call_all(&hdw->v4l2_dev, hdw->decoder_client_id,
2031 vbi, s_sliced_fmt, &fmt.fmt.sliced); 2039 vbi, s_sliced_fmt, &fmt.fmt.sliced);
2032} 2040}
@@ -2842,15 +2850,23 @@ static void pvr2_hdw_internal_set_std_avail(struct pvr2_hdw *hdw)
2842 PVR2_TRACE_ERROR_LEGS, 2850 PVR2_TRACE_ERROR_LEGS,
2843 "WARNING: Failed to identify any viable standards"); 2851 "WARNING: Failed to identify any viable standards");
2844 } 2852 }
2853
2854 /* Set up the dynamic control for this standard */
2845 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL); 2855 hdw->std_enum_names = kmalloc(sizeof(char *)*(std_cnt+1),GFP_KERNEL);
2846 hdw->std_enum_names[0] = "none"; 2856 if (hdw->std_enum_names) {
2847 for (idx = 0; idx < std_cnt; idx++) { 2857 hdw->std_enum_names[0] = "none";
2848 hdw->std_enum_names[idx+1] = 2858 for (idx = 0; idx < std_cnt; idx++)
2849 newstd[idx].name; 2859 hdw->std_enum_names[idx+1] = newstd[idx].name;
2850 } 2860 hdw->std_info_enum.def.type_enum.value_names =
2851 // Set up the dynamic control for this standard 2861 hdw->std_enum_names;
2852 hdw->std_info_enum.def.type_enum.value_names = hdw->std_enum_names; 2862 hdw->std_info_enum.def.type_enum.count = std_cnt+1;
2853 hdw->std_info_enum.def.type_enum.count = std_cnt+1; 2863 } else {
2864 pvr2_trace(
2865 PVR2_TRACE_ERROR_LEGS,
2866 "WARNING: Failed to alloc memory for names");
2867 hdw->std_info_enum.def.type_enum.value_names = NULL;
2868 hdw->std_info_enum.def.type_enum.count = 0;
2869 }
2854 hdw->std_defs = newstd; 2870 hdw->std_defs = newstd;
2855 hdw->std_enum_cnt = std_cnt+1; 2871 hdw->std_enum_cnt = std_cnt+1;
2856 hdw->std_enum_cur = 0; 2872 hdw->std_enum_cur = 0;
@@ -3165,6 +3181,19 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
3165 struct pvr2_ctrl *cptr; 3181 struct pvr2_ctrl *cptr;
3166 int disruptive_change; 3182 int disruptive_change;
3167 3183
3184 if (hdw->input_dirty && hdw->state_pathway_ok &&
3185 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
3186 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
3187 hdw->pathway_state)) {
3188 /* Change of mode being asked for... */
3189 hdw->state_pathway_ok = 0;
3190 trace_stbit("state_pathway_ok", hdw->state_pathway_ok);
3191 }
3192 if (!hdw->state_pathway_ok) {
3193 /* Can't commit anything until pathway is ok. */
3194 return 0;
3195 }
3196
3168 /* Handle some required side effects when the video standard is 3197 /* Handle some required side effects when the video standard is
3169 changed.... */ 3198 changed.... */
3170 if (hdw->std_dirty) { 3199 if (hdw->std_dirty) {
@@ -3199,18 +3228,6 @@ static int pvr2_hdw_commit_execute(struct pvr2_hdw *hdw)
3199 } 3228 }
3200 } 3229 }
3201 3230
3202 if (hdw->input_dirty && hdw->state_pathway_ok &&
3203 (((hdw->input_val == PVR2_CVAL_INPUT_DTV) ?
3204 PVR2_PATHWAY_DIGITAL : PVR2_PATHWAY_ANALOG) !=
3205 hdw->pathway_state)) {
3206 /* Change of mode being asked for... */
3207 hdw->state_pathway_ok = 0;
3208 trace_stbit("state_pathway_ok",hdw->state_pathway_ok);
3209 }
3210 if (!hdw->state_pathway_ok) {
3211 /* Can't commit anything until pathway is ok. */
3212 return 0;
3213 }
3214 /* The broadcast decoder can only scale down, so if 3231 /* The broadcast decoder can only scale down, so if
3215 * res_*_dirty && crop window < output format ==> enlarge crop. 3232 * res_*_dirty && crop window < output format ==> enlarge crop.
3216 * 3233 *
@@ -5159,8 +5176,7 @@ void pvr2_hdw_status_poll(struct pvr2_hdw *hdw)
5159 using v4l2-subdev - therefore we can't support that AT ALL right 5176 using v4l2-subdev - therefore we can't support that AT ALL right
5160 now. (Of course, no sub-drivers seem to implement it either. 5177 now. (Of course, no sub-drivers seem to implement it either.
5161 But now it's a a chicken and egg problem...) */ 5178 But now it's a a chicken and egg problem...) */
5162 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, 5179 v4l2_device_call_all(&hdw->v4l2_dev, 0, tuner, g_tuner, vtp);
5163 &hdw->tuner_signal_info);
5164 pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll" 5180 pvr2_trace(PVR2_TRACE_CHIPS, "subdev status poll"
5165 " type=%u strength=%u audio=0x%x cap=0x%x" 5181 " type=%u strength=%u audio=0x%x cap=0x%x"
5166 " low=%u hi=%u", 5182 " low=%u hi=%u",
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 451ecd485f97..e72d5103e778 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -578,7 +578,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
578 switch (hdw->ir_scheme_active) { 578 switch (hdw->ir_scheme_active) {
579 case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */ 579 case PVR2_IR_SCHEME_24XXX: /* FX2-controlled IR */
580 case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */ 580 case PVR2_IR_SCHEME_29XXX: /* Original 29xxx device */
581 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 581 init_data->ir_codes = RC_MAP_HAUPPAUGE;
582 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP; 582 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP;
583 init_data->type = RC_TYPE_RC5; 583 init_data->type = RC_TYPE_RC5;
584 init_data->name = hdw->hdw_desc->description; 584 init_data->name = hdw->hdw_desc->description;
@@ -593,7 +593,7 @@ static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
593 break; 593 break;
594 case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */ 594 case PVR2_IR_SCHEME_ZILOG: /* HVR-1950 style */
595 case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */ 595 case PVR2_IR_SCHEME_24XXX_MCE: /* 24xxx MCE device */
596 init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; 596 init_data->ir_codes = RC_MAP_HAUPPAUGE;
597 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; 597 init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR;
598 init_data->type = RC_TYPE_RC5; 598 init_data->type = RC_TYPE_RC5;
599 init_data->name = hdw->hdw_desc->description; 599 init_data->name = hdw->hdw_desc->description;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 281806b2df62..6ef1335b2858 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -324,36 +324,45 @@ static void pvr2_sysfs_add_control(struct pvr2_sysfs *sfp,int ctl_id)
324 } 324 }
325 sfp->item_last = cip; 325 sfp->item_last = cip;
326 326
327 sysfs_attr_init(&cip->attr_name.attr);
327 cip->attr_name.attr.name = "name"; 328 cip->attr_name.attr.name = "name";
328 cip->attr_name.attr.mode = S_IRUGO; 329 cip->attr_name.attr.mode = S_IRUGO;
329 cip->attr_name.show = show_name; 330 cip->attr_name.show = show_name;
330 331
332 sysfs_attr_init(&cip->attr_type.attr);
331 cip->attr_type.attr.name = "type"; 333 cip->attr_type.attr.name = "type";
332 cip->attr_type.attr.mode = S_IRUGO; 334 cip->attr_type.attr.mode = S_IRUGO;
333 cip->attr_type.show = show_type; 335 cip->attr_type.show = show_type;
334 336
337 sysfs_attr_init(&cip->attr_min.attr);
335 cip->attr_min.attr.name = "min_val"; 338 cip->attr_min.attr.name = "min_val";
336 cip->attr_min.attr.mode = S_IRUGO; 339 cip->attr_min.attr.mode = S_IRUGO;
337 cip->attr_min.show = show_min; 340 cip->attr_min.show = show_min;
338 341
342 sysfs_attr_init(&cip->attr_max.attr);
339 cip->attr_max.attr.name = "max_val"; 343 cip->attr_max.attr.name = "max_val";
340 cip->attr_max.attr.mode = S_IRUGO; 344 cip->attr_max.attr.mode = S_IRUGO;
341 cip->attr_max.show = show_max; 345 cip->attr_max.show = show_max;
342 346
347 sysfs_attr_init(&cip->attr_def.attr);
343 cip->attr_def.attr.name = "def_val"; 348 cip->attr_def.attr.name = "def_val";
344 cip->attr_def.attr.mode = S_IRUGO; 349 cip->attr_def.attr.mode = S_IRUGO;
345 cip->attr_def.show = show_def; 350 cip->attr_def.show = show_def;
346 351
352 sysfs_attr_init(&cip->attr_val.attr);
347 cip->attr_val.attr.name = "cur_val"; 353 cip->attr_val.attr.name = "cur_val";
348 cip->attr_val.attr.mode = S_IRUGO; 354 cip->attr_val.attr.mode = S_IRUGO;
349 355
356 sysfs_attr_init(&cip->attr_custom.attr);
350 cip->attr_custom.attr.name = "custom_val"; 357 cip->attr_custom.attr.name = "custom_val";
351 cip->attr_custom.attr.mode = S_IRUGO; 358 cip->attr_custom.attr.mode = S_IRUGO;
352 359
360 sysfs_attr_init(&cip->attr_enum.attr);
353 cip->attr_enum.attr.name = "enum_val"; 361 cip->attr_enum.attr.name = "enum_val";
354 cip->attr_enum.attr.mode = S_IRUGO; 362 cip->attr_enum.attr.mode = S_IRUGO;
355 cip->attr_enum.show = show_enum; 363 cip->attr_enum.show = show_enum;
356 364
365 sysfs_attr_init(&cip->attr_bits.attr);
357 cip->attr_bits.attr.name = "bit_val"; 366 cip->attr_bits.attr.name = "bit_val";
358 cip->attr_bits.attr.mode = S_IRUGO; 367 cip->attr_bits.attr.mode = S_IRUGO;
359 cip->attr_bits.show = show_bits; 368 cip->attr_bits.show = show_bits;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index 58617fc656c2..38761142a4d9 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -795,12 +795,10 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
795 case VIDIOC_S_CROP: 795 case VIDIOC_S_CROP:
796 { 796 {
797 struct v4l2_crop *crop = (struct v4l2_crop *)arg; 797 struct v4l2_crop *crop = (struct v4l2_crop *)arg;
798 struct v4l2_cropcap cap;
799 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 798 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
800 ret = -EINVAL; 799 ret = -EINVAL;
801 break; 800 break;
802 } 801 }
803 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
804 ret = pvr2_ctrl_set_value( 802 ret = pvr2_ctrl_set_value(
805 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL), 803 pvr2_hdw_get_ctrl_by_id(hdw, PVR2_CID_CROPL),
806 crop->c.left); 804 crop->c.left);
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index bd1519a4ecb4..780af5f81642 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -151,8 +151,6 @@ static int pwc_video_close(struct file *file);
151static ssize_t pwc_video_read(struct file *file, char __user *buf, 151static ssize_t pwc_video_read(struct file *file, char __user *buf,
152 size_t count, loff_t *ppos); 152 size_t count, loff_t *ppos);
153static unsigned int pwc_video_poll(struct file *file, poll_table *wait); 153static unsigned int pwc_video_poll(struct file *file, poll_table *wait);
154static long pwc_video_ioctl(struct file *file,
155 unsigned int ioctlnr, unsigned long arg);
156static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma); 154static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma);
157 155
158static const struct v4l2_file_operations pwc_fops = { 156static const struct v4l2_file_operations pwc_fops = {
@@ -162,7 +160,7 @@ static const struct v4l2_file_operations pwc_fops = {
162 .read = pwc_video_read, 160 .read = pwc_video_read,
163 .poll = pwc_video_poll, 161 .poll = pwc_video_poll,
164 .mmap = pwc_video_mmap, 162 .mmap = pwc_video_mmap,
165 .unlocked_ioctl = pwc_video_ioctl, 163 .unlocked_ioctl = video_ioctl2,
166}; 164};
167static struct video_device pwc_template = { 165static struct video_device pwc_template = {
168 .name = "Philips Webcam", /* Filled in later */ 166 .name = "Philips Webcam", /* Filled in later */
@@ -1098,7 +1096,6 @@ static int pwc_video_open(struct file *file)
1098 return -EBUSY; 1096 return -EBUSY;
1099 } 1097 }
1100 1098
1101 mutex_lock(&pdev->modlock);
1102 pwc_construct(pdev); /* set min/max sizes correct */ 1099 pwc_construct(pdev); /* set min/max sizes correct */
1103 if (!pdev->usb_init) { 1100 if (!pdev->usb_init) {
1104 PWC_DEBUG_OPEN("Doing first time initialization.\n"); 1101 PWC_DEBUG_OPEN("Doing first time initialization.\n");
@@ -1130,7 +1127,6 @@ static int pwc_video_open(struct file *file)
1130 if (i < 0) { 1127 if (i < 0) {
1131 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n"); 1128 PWC_DEBUG_OPEN("Failed to allocate buffers memory.\n");
1132 pwc_free_buffers(pdev); 1129 pwc_free_buffers(pdev);
1133 mutex_unlock(&pdev->modlock);
1134 return i; 1130 return i;
1135 } 1131 }
1136 1132
@@ -1171,7 +1167,6 @@ static int pwc_video_open(struct file *file)
1171 if (i) { 1167 if (i) {
1172 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n"); 1168 PWC_DEBUG_OPEN("Second attempt at set_video_mode failed.\n");
1173 pwc_free_buffers(pdev); 1169 pwc_free_buffers(pdev);
1174 mutex_unlock(&pdev->modlock);
1175 return i; 1170 return i;
1176 } 1171 }
1177 1172
@@ -1181,7 +1176,6 @@ static int pwc_video_open(struct file *file)
1181 1176
1182 pdev->vopen++; 1177 pdev->vopen++;
1183 file->private_data = vdev; 1178 file->private_data = vdev;
1184 mutex_unlock(&pdev->modlock);
1185 PWC_DEBUG_OPEN("<< video_open() returns 0.\n"); 1179 PWC_DEBUG_OPEN("<< video_open() returns 0.\n");
1186 return 0; 1180 return 0;
1187} 1181}
@@ -1210,7 +1204,6 @@ static int pwc_video_close(struct file *file)
1210 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); 1204 PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
1211 1205
1212 pdev = video_get_drvdata(vdev); 1206 pdev = video_get_drvdata(vdev);
1213 mutex_lock(&pdev->modlock);
1214 if (pdev->vopen == 0) 1207 if (pdev->vopen == 0)
1215 PWC_DEBUG_MODULE("video_close() called on closed device?\n"); 1208 PWC_DEBUG_MODULE("video_close() called on closed device?\n");
1216 1209
@@ -1248,7 +1241,6 @@ static int pwc_video_close(struct file *file)
1248 if (device_hint[hint].pdev == pdev) 1241 if (device_hint[hint].pdev == pdev)
1249 device_hint[hint].pdev = NULL; 1242 device_hint[hint].pdev = NULL;
1250 } 1243 }
1251 mutex_unlock(&pdev->modlock);
1252 1244
1253 return 0; 1245 return 0;
1254} 1246}
@@ -1283,7 +1275,6 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1283 if (pdev == NULL) 1275 if (pdev == NULL)
1284 return -EFAULT; 1276 return -EFAULT;
1285 1277
1286 mutex_lock(&pdev->modlock);
1287 if (pdev->error_status) { 1278 if (pdev->error_status) {
1288 rv = -pdev->error_status; /* Something happened, report what. */ 1279 rv = -pdev->error_status; /* Something happened, report what. */
1289 goto err_out; 1280 goto err_out;
@@ -1318,8 +1309,10 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1318 rv = -ERESTARTSYS; 1309 rv = -ERESTARTSYS;
1319 goto err_out; 1310 goto err_out;
1320 } 1311 }
1312 mutex_unlock(&pdev->modlock);
1321 schedule(); 1313 schedule();
1322 set_current_state(TASK_INTERRUPTIBLE); 1314 set_current_state(TASK_INTERRUPTIBLE);
1315 mutex_lock(&pdev->modlock);
1323 } 1316 }
1324 remove_wait_queue(&pdev->frameq, &wait); 1317 remove_wait_queue(&pdev->frameq, &wait);
1325 set_current_state(TASK_RUNNING); 1318 set_current_state(TASK_RUNNING);
@@ -1352,10 +1345,8 @@ static ssize_t pwc_video_read(struct file *file, char __user *buf,
1352 pdev->image_read_pos = 0; 1345 pdev->image_read_pos = 0;
1353 pwc_next_image(pdev); 1346 pwc_next_image(pdev);
1354 } 1347 }
1355 mutex_unlock(&pdev->modlock);
1356 return count; 1348 return count;
1357err_out: 1349err_out:
1358 mutex_unlock(&pdev->modlock);
1359 return rv; 1350 return rv;
1360} 1351}
1361 1352
@@ -1372,9 +1363,7 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1372 return -EFAULT; 1363 return -EFAULT;
1373 1364
1374 /* Start the stream (if not already started) */ 1365 /* Start the stream (if not already started) */
1375 mutex_lock(&pdev->modlock);
1376 ret = pwc_isoc_init(pdev); 1366 ret = pwc_isoc_init(pdev);
1377 mutex_unlock(&pdev->modlock);
1378 if (ret) 1367 if (ret)
1379 return ret; 1368 return ret;
1380 1369
@@ -1387,25 +1376,6 @@ static unsigned int pwc_video_poll(struct file *file, poll_table *wait)
1387 return 0; 1376 return 0;
1388} 1377}
1389 1378
1390static long pwc_video_ioctl(struct file *file,
1391 unsigned int cmd, unsigned long arg)
1392{
1393 struct video_device *vdev = file->private_data;
1394 struct pwc_device *pdev;
1395 long r = -ENODEV;
1396
1397 if (!vdev)
1398 goto out;
1399 pdev = video_get_drvdata(vdev);
1400
1401 mutex_lock(&pdev->modlock);
1402 if (!pdev->unplugged)
1403 r = video_usercopy(file, cmd, arg, pwc_video_do_ioctl);
1404 mutex_unlock(&pdev->modlock);
1405out:
1406 return r;
1407}
1408
1409static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma) 1379static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
1410{ 1380{
1411 struct video_device *vdev = file->private_data; 1381 struct video_device *vdev = file->private_data;
@@ -1754,6 +1724,8 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
1754 } 1724 }
1755 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template)); 1725 memcpy(pdev->vdev, &pwc_template, sizeof(pwc_template));
1756 pdev->vdev->parent = &intf->dev; 1726 pdev->vdev->parent = &intf->dev;
1727 pdev->vdev->lock = &pdev->modlock;
1728 pdev->vdev->ioctl_ops = &pwc_ioctl_ops;
1757 strcpy(pdev->vdev->name, name); 1729 strcpy(pdev->vdev->name, name);
1758 video_set_drvdata(pdev->vdev, pdev); 1730 video_set_drvdata(pdev->vdev, pdev);
1759 1731
diff --git a/drivers/media/video/pwc/pwc-v4l.c b/drivers/media/video/pwc/pwc-v4l.c
index 8ca4d22b4384..aa87e462a958 100644
--- a/drivers/media/video/pwc/pwc-v4l.c
+++ b/drivers/media/video/pwc/pwc-v4l.c
@@ -341,604 +341,555 @@ static int pwc_vidioc_set_fmt(struct pwc_device *pdev, struct v4l2_format *f)
341 341
342} 342}
343 343
344long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg) 344static int pwc_querycap(struct file *file, void *fh, struct v4l2_capability *cap)
345{ 345{
346 struct video_device *vdev = video_devdata(file); 346 struct video_device *vdev = video_devdata(file);
347 struct pwc_device *pdev; 347 struct pwc_device *pdev = video_drvdata(file);
348 DECLARE_WAITQUEUE(wait, current); 348
349 349 strcpy(cap->driver, PWC_NAME);
350 if (vdev == NULL) 350 strlcpy(cap->card, vdev->name, sizeof(cap->card));
351 return -EFAULT; 351 usb_make_path(pdev->udev, cap->bus_info, sizeof(cap->bus_info));
352 pdev = video_get_drvdata(vdev); 352 cap->version = PWC_VERSION_CODE;
353 if (pdev == NULL) 353 cap->capabilities =
354 return -EFAULT; 354 V4L2_CAP_VIDEO_CAPTURE |
355 V4L2_CAP_STREAMING |
356 V4L2_CAP_READWRITE;
357 return 0;
358}
355 359
356#ifdef CONFIG_USB_PWC_DEBUG 360static int pwc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
357 if (PWC_DEBUG_LEVEL_IOCTL & pwc_trace) { 361{
358 v4l_printk_ioctl(cmd); 362 if (i->index) /* Only one INPUT is supported */
359 printk("\n"); 363 return -EINVAL;
360 }
361#endif
362
363
364 switch (cmd) {
365 /* V4L2 Layer */
366 case VIDIOC_QUERYCAP:
367 {
368 struct v4l2_capability *cap = arg;
369
370 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCAP) This application "\
371 "try to use the v4l2 layer\n");
372 strcpy(cap->driver,PWC_NAME);
373 strlcpy(cap->card, vdev->name, sizeof(cap->card));
374 usb_make_path(pdev->udev,cap->bus_info,sizeof(cap->bus_info));
375 cap->version = PWC_VERSION_CODE;
376 cap->capabilities =
377 V4L2_CAP_VIDEO_CAPTURE |
378 V4L2_CAP_STREAMING |
379 V4L2_CAP_READWRITE;
380 return 0;
381 }
382 364
383 case VIDIOC_ENUMINPUT: 365 strcpy(i->name, "usb");
384 { 366 return 0;
385 struct v4l2_input *i = arg; 367}
386 368
387 if ( i->index ) /* Only one INPUT is supported */ 369static int pwc_g_input(struct file *file, void *fh, unsigned int *i)
388 return -EINVAL; 370{
371 *i = 0;
372 return 0;
373}
389 374
390 memset(i, 0, sizeof(struct v4l2_input)); 375static int pwc_s_input(struct file *file, void *fh, unsigned int i)
391 strcpy(i->name, "usb"); 376{
392 return 0; 377 return i ? -EINVAL : 0;
393 } 378}
394 379
395 case VIDIOC_G_INPUT: 380static int pwc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *c)
396 { 381{
397 int *i = arg; 382 int i;
398 *i = 0; /* Only one INPUT is supported */
399 return 0;
400 }
401 case VIDIOC_S_INPUT:
402 {
403 int *i = arg;
404 383
405 if ( *i ) { /* Only one INPUT is supported */ 384 for (i = 0; i < sizeof(pwc_controls) / sizeof(struct v4l2_queryctrl); i++) {
406 PWC_DEBUG_IOCTL("Only one input source is"\ 385 if (pwc_controls[i].id == c->id) {
407 " supported with this webcam.\n"); 386 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
408 return -EINVAL; 387 memcpy(c, &pwc_controls[i], sizeof(struct v4l2_queryctrl));
409 }
410 return 0; 388 return 0;
411 } 389 }
390 }
391 return -EINVAL;
392}
412 393
413 /* TODO: */ 394static int pwc_g_ctrl(struct file *file, void *fh, struct v4l2_control *c)
414 case VIDIOC_QUERYCTRL: 395{
415 { 396 struct pwc_device *pdev = video_drvdata(file);
416 struct v4l2_queryctrl *c = arg; 397 int ret;
417 int i;
418
419 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) query id=%d\n", c->id);
420 for (i=0; i<sizeof(pwc_controls)/sizeof(struct v4l2_queryctrl); i++) {
421 if (pwc_controls[i].id == c->id) {
422 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) found\n");
423 memcpy(c,&pwc_controls[i],sizeof(struct v4l2_queryctrl));
424 return 0;
425 }
426 }
427 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYCTRL) not found\n");
428 398
399 switch (c->id) {
400 case V4L2_CID_BRIGHTNESS:
401 c->value = pwc_get_brightness(pdev);
402 if (c->value < 0)
429 return -EINVAL; 403 return -EINVAL;
430 } 404 return 0;
431 case VIDIOC_G_CTRL: 405 case V4L2_CID_CONTRAST:
432 { 406 c->value = pwc_get_contrast(pdev);
433 struct v4l2_control *c = arg; 407 if (c->value < 0)
434 int ret;
435
436 switch (c->id)
437 {
438 case V4L2_CID_BRIGHTNESS:
439 c->value = pwc_get_brightness(pdev);
440 if (c->value<0)
441 return -EINVAL;
442 return 0;
443 case V4L2_CID_CONTRAST:
444 c->value = pwc_get_contrast(pdev);
445 if (c->value<0)
446 return -EINVAL;
447 return 0;
448 case V4L2_CID_SATURATION:
449 ret = pwc_get_saturation(pdev, &c->value);
450 if (ret<0)
451 return -EINVAL;
452 return 0;
453 case V4L2_CID_GAMMA:
454 c->value = pwc_get_gamma(pdev);
455 if (c->value<0)
456 return -EINVAL;
457 return 0;
458 case V4L2_CID_RED_BALANCE:
459 ret = pwc_get_red_gain(pdev, &c->value);
460 if (ret<0)
461 return -EINVAL;
462 c->value >>= 8;
463 return 0;
464 case V4L2_CID_BLUE_BALANCE:
465 ret = pwc_get_blue_gain(pdev, &c->value);
466 if (ret<0)
467 return -EINVAL;
468 c->value >>= 8;
469 return 0;
470 case V4L2_CID_AUTO_WHITE_BALANCE:
471 ret = pwc_get_awb(pdev);
472 if (ret<0)
473 return -EINVAL;
474 c->value = (ret == PWC_WB_MANUAL)?0:1;
475 return 0;
476 case V4L2_CID_GAIN:
477 ret = pwc_get_agc(pdev, &c->value);
478 if (ret<0)
479 return -EINVAL;
480 c->value >>= 8;
481 return 0;
482 case V4L2_CID_AUTOGAIN:
483 ret = pwc_get_agc(pdev, &c->value);
484 if (ret<0)
485 return -EINVAL;
486 c->value = (c->value < 0)?1:0;
487 return 0;
488 case V4L2_CID_EXPOSURE:
489 ret = pwc_get_shutter_speed(pdev, &c->value);
490 if (ret<0)
491 return -EINVAL;
492 return 0;
493 case V4L2_CID_PRIVATE_COLOUR_MODE:
494 ret = pwc_get_colour_mode(pdev, &c->value);
495 if (ret < 0)
496 return -EINVAL;
497 return 0;
498 case V4L2_CID_PRIVATE_AUTOCONTOUR:
499 ret = pwc_get_contour(pdev, &c->value);
500 if (ret < 0)
501 return -EINVAL;
502 c->value=(c->value == -1?1:0);
503 return 0;
504 case V4L2_CID_PRIVATE_CONTOUR:
505 ret = pwc_get_contour(pdev, &c->value);
506 if (ret < 0)
507 return -EINVAL;
508 c->value >>= 10;
509 return 0;
510 case V4L2_CID_PRIVATE_BACKLIGHT:
511 ret = pwc_get_backlight(pdev, &c->value);
512 if (ret < 0)
513 return -EINVAL;
514 return 0;
515 case V4L2_CID_PRIVATE_FLICKERLESS:
516 ret = pwc_get_flicker(pdev, &c->value);
517 if (ret < 0)
518 return -EINVAL;
519 c->value=(c->value?1:0);
520 return 0;
521 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
522 ret = pwc_get_dynamic_noise(pdev, &c->value);
523 if (ret < 0)
524 return -EINVAL;
525 return 0;
526
527 case V4L2_CID_PRIVATE_SAVE_USER:
528 case V4L2_CID_PRIVATE_RESTORE_USER:
529 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
530 return -EINVAL;
531 }
532 return -EINVAL; 408 return -EINVAL;
533 } 409 return 0;
534 case VIDIOC_S_CTRL: 410 case V4L2_CID_SATURATION:
535 { 411 ret = pwc_get_saturation(pdev, &c->value);
536 struct v4l2_control *c = arg; 412 if (ret < 0)
537 int ret;
538
539 switch (c->id)
540 {
541 case V4L2_CID_BRIGHTNESS:
542 c->value <<= 9;
543 ret = pwc_set_brightness(pdev, c->value);
544 if (ret<0)
545 return -EINVAL;
546 return 0;
547 case V4L2_CID_CONTRAST:
548 c->value <<= 10;
549 ret = pwc_set_contrast(pdev, c->value);
550 if (ret<0)
551 return -EINVAL;
552 return 0;
553 case V4L2_CID_SATURATION:
554 ret = pwc_set_saturation(pdev, c->value);
555 if (ret<0)
556 return -EINVAL;
557 return 0;
558 case V4L2_CID_GAMMA:
559 c->value <<= 11;
560 ret = pwc_set_gamma(pdev, c->value);
561 if (ret<0)
562 return -EINVAL;
563 return 0;
564 case V4L2_CID_RED_BALANCE:
565 c->value <<= 8;
566 ret = pwc_set_red_gain(pdev, c->value);
567 if (ret<0)
568 return -EINVAL;
569 return 0;
570 case V4L2_CID_BLUE_BALANCE:
571 c->value <<= 8;
572 ret = pwc_set_blue_gain(pdev, c->value);
573 if (ret<0)
574 return -EINVAL;
575 return 0;
576 case V4L2_CID_AUTO_WHITE_BALANCE:
577 c->value = (c->value == 0)?PWC_WB_MANUAL:PWC_WB_AUTO;
578 ret = pwc_set_awb(pdev, c->value);
579 if (ret<0)
580 return -EINVAL;
581 return 0;
582 case V4L2_CID_EXPOSURE:
583 c->value <<= 8;
584 ret = pwc_set_shutter_speed(pdev, c->value?0:1, c->value);
585 if (ret<0)
586 return -EINVAL;
587 return 0;
588 case V4L2_CID_AUTOGAIN:
589 /* autogain off means nothing without a gain */
590 if (c->value == 0)
591 return 0;
592 ret = pwc_set_agc(pdev, c->value, 0);
593 if (ret<0)
594 return -EINVAL;
595 return 0;
596 case V4L2_CID_GAIN:
597 c->value <<= 8;
598 ret = pwc_set_agc(pdev, 0, c->value);
599 if (ret<0)
600 return -EINVAL;
601 return 0;
602 case V4L2_CID_PRIVATE_SAVE_USER:
603 if (pwc_save_user(pdev))
604 return -EINVAL;
605 return 0;
606 case V4L2_CID_PRIVATE_RESTORE_USER:
607 if (pwc_restore_user(pdev))
608 return -EINVAL;
609 return 0;
610 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
611 if (pwc_restore_factory(pdev))
612 return -EINVAL;
613 return 0;
614 case V4L2_CID_PRIVATE_COLOUR_MODE:
615 ret = pwc_set_colour_mode(pdev, c->value);
616 if (ret < 0)
617 return -EINVAL;
618 return 0;
619 case V4L2_CID_PRIVATE_AUTOCONTOUR:
620 c->value=(c->value == 1)?-1:0;
621 ret = pwc_set_contour(pdev, c->value);
622 if (ret < 0)
623 return -EINVAL;
624 return 0;
625 case V4L2_CID_PRIVATE_CONTOUR:
626 c->value <<= 10;
627 ret = pwc_set_contour(pdev, c->value);
628 if (ret < 0)
629 return -EINVAL;
630 return 0;
631 case V4L2_CID_PRIVATE_BACKLIGHT:
632 ret = pwc_set_backlight(pdev, c->value);
633 if (ret < 0)
634 return -EINVAL;
635 return 0;
636 case V4L2_CID_PRIVATE_FLICKERLESS:
637 ret = pwc_set_flicker(pdev, c->value);
638 if (ret < 0)
639 return -EINVAL;
640 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
641 ret = pwc_set_dynamic_noise(pdev, c->value);
642 if (ret < 0)
643 return -EINVAL;
644 return 0;
645
646 }
647 return -EINVAL; 413 return -EINVAL;
648 } 414 return 0;
415 case V4L2_CID_GAMMA:
416 c->value = pwc_get_gamma(pdev);
417 if (c->value < 0)
418 return -EINVAL;
419 return 0;
420 case V4L2_CID_RED_BALANCE:
421 ret = pwc_get_red_gain(pdev, &c->value);
422 if (ret < 0)
423 return -EINVAL;
424 c->value >>= 8;
425 return 0;
426 case V4L2_CID_BLUE_BALANCE:
427 ret = pwc_get_blue_gain(pdev, &c->value);
428 if (ret < 0)
429 return -EINVAL;
430 c->value >>= 8;
431 return 0;
432 case V4L2_CID_AUTO_WHITE_BALANCE:
433 ret = pwc_get_awb(pdev);
434 if (ret < 0)
435 return -EINVAL;
436 c->value = (ret == PWC_WB_MANUAL) ? 0 : 1;
437 return 0;
438 case V4L2_CID_GAIN:
439 ret = pwc_get_agc(pdev, &c->value);
440 if (ret < 0)
441 return -EINVAL;
442 c->value >>= 8;
443 return 0;
444 case V4L2_CID_AUTOGAIN:
445 ret = pwc_get_agc(pdev, &c->value);
446 if (ret < 0)
447 return -EINVAL;
448 c->value = (c->value < 0) ? 1 : 0;
449 return 0;
450 case V4L2_CID_EXPOSURE:
451 ret = pwc_get_shutter_speed(pdev, &c->value);
452 if (ret < 0)
453 return -EINVAL;
454 return 0;
455 case V4L2_CID_PRIVATE_COLOUR_MODE:
456 ret = pwc_get_colour_mode(pdev, &c->value);
457 if (ret < 0)
458 return -EINVAL;
459 return 0;
460 case V4L2_CID_PRIVATE_AUTOCONTOUR:
461 ret = pwc_get_contour(pdev, &c->value);
462 if (ret < 0)
463 return -EINVAL;
464 c->value = (c->value == -1 ? 1 : 0);
465 return 0;
466 case V4L2_CID_PRIVATE_CONTOUR:
467 ret = pwc_get_contour(pdev, &c->value);
468 if (ret < 0)
469 return -EINVAL;
470 c->value >>= 10;
471 return 0;
472 case V4L2_CID_PRIVATE_BACKLIGHT:
473 ret = pwc_get_backlight(pdev, &c->value);
474 if (ret < 0)
475 return -EINVAL;
476 return 0;
477 case V4L2_CID_PRIVATE_FLICKERLESS:
478 ret = pwc_get_flicker(pdev, &c->value);
479 if (ret < 0)
480 return -EINVAL;
481 c->value = (c->value ? 1 : 0);
482 return 0;
483 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
484 ret = pwc_get_dynamic_noise(pdev, &c->value);
485 if (ret < 0)
486 return -EINVAL;
487 return 0;
649 488
650 case VIDIOC_ENUM_FMT: 489 case V4L2_CID_PRIVATE_SAVE_USER:
651 { 490 case V4L2_CID_PRIVATE_RESTORE_USER:
652 struct v4l2_fmtdesc *f = arg; 491 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
653 int index; 492 return -EINVAL;
654 493 }
655 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 494 return -EINVAL;
656 return -EINVAL; 495}
657
658 /* We only support two format: the raw format, and YUV */
659 index = f->index;
660 memset(f,0,sizeof(struct v4l2_fmtdesc));
661 f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
662 f->index = index;
663 switch(index)
664 {
665 case 0:
666 /* RAW format */
667 f->pixelformat = pdev->type<=646?V4L2_PIX_FMT_PWC1:V4L2_PIX_FMT_PWC2;
668 f->flags = V4L2_FMT_FLAG_COMPRESSED;
669 strlcpy(f->description,"Raw Philips Webcam",sizeof(f->description));
670 break;
671 case 1:
672 f->pixelformat = V4L2_PIX_FMT_YUV420;
673 strlcpy(f->description,"4:2:0, planar, Y-Cb-Cr",sizeof(f->description));
674 break;
675 default:
676 return -EINVAL;
677 }
678 return 0;
679 }
680 496
681 case VIDIOC_G_FMT: 497static int pwc_s_ctrl(struct file *file, void *fh, struct v4l2_control *c)
682 { 498{
683 struct v4l2_format *f = arg; 499 struct pwc_device *pdev = video_drvdata(file);
500 int ret;
501
502 switch (c->id) {
503 case V4L2_CID_BRIGHTNESS:
504 c->value <<= 9;
505 ret = pwc_set_brightness(pdev, c->value);
506 if (ret < 0)
507 return -EINVAL;
508 return 0;
509 case V4L2_CID_CONTRAST:
510 c->value <<= 10;
511 ret = pwc_set_contrast(pdev, c->value);
512 if (ret < 0)
513 return -EINVAL;
514 return 0;
515 case V4L2_CID_SATURATION:
516 ret = pwc_set_saturation(pdev, c->value);
517 if (ret < 0)
518 return -EINVAL;
519 return 0;
520 case V4L2_CID_GAMMA:
521 c->value <<= 11;
522 ret = pwc_set_gamma(pdev, c->value);
523 if (ret < 0)
524 return -EINVAL;
525 return 0;
526 case V4L2_CID_RED_BALANCE:
527 c->value <<= 8;
528 ret = pwc_set_red_gain(pdev, c->value);
529 if (ret < 0)
530 return -EINVAL;
531 return 0;
532 case V4L2_CID_BLUE_BALANCE:
533 c->value <<= 8;
534 ret = pwc_set_blue_gain(pdev, c->value);
535 if (ret < 0)
536 return -EINVAL;
537 return 0;
538 case V4L2_CID_AUTO_WHITE_BALANCE:
539 c->value = (c->value == 0) ? PWC_WB_MANUAL : PWC_WB_AUTO;
540 ret = pwc_set_awb(pdev, c->value);
541 if (ret < 0)
542 return -EINVAL;
543 return 0;
544 case V4L2_CID_EXPOSURE:
545 c->value <<= 8;
546 ret = pwc_set_shutter_speed(pdev, c->value ? 0 : 1, c->value);
547 if (ret < 0)
548 return -EINVAL;
549 return 0;
550 case V4L2_CID_AUTOGAIN:
551 /* autogain off means nothing without a gain */
552 if (c->value == 0)
553 return 0;
554 ret = pwc_set_agc(pdev, c->value, 0);
555 if (ret < 0)
556 return -EINVAL;
557 return 0;
558 case V4L2_CID_GAIN:
559 c->value <<= 8;
560 ret = pwc_set_agc(pdev, 0, c->value);
561 if (ret < 0)
562 return -EINVAL;
563 return 0;
564 case V4L2_CID_PRIVATE_SAVE_USER:
565 if (pwc_save_user(pdev))
566 return -EINVAL;
567 return 0;
568 case V4L2_CID_PRIVATE_RESTORE_USER:
569 if (pwc_restore_user(pdev))
570 return -EINVAL;
571 return 0;
572 case V4L2_CID_PRIVATE_RESTORE_FACTORY:
573 if (pwc_restore_factory(pdev))
574 return -EINVAL;
575 return 0;
576 case V4L2_CID_PRIVATE_COLOUR_MODE:
577 ret = pwc_set_colour_mode(pdev, c->value);
578 if (ret < 0)
579 return -EINVAL;
580 return 0;
581 case V4L2_CID_PRIVATE_AUTOCONTOUR:
582 c->value = (c->value == 1) ? -1 : 0;
583 ret = pwc_set_contour(pdev, c->value);
584 if (ret < 0)
585 return -EINVAL;
586 return 0;
587 case V4L2_CID_PRIVATE_CONTOUR:
588 c->value <<= 10;
589 ret = pwc_set_contour(pdev, c->value);
590 if (ret < 0)
591 return -EINVAL;
592 return 0;
593 case V4L2_CID_PRIVATE_BACKLIGHT:
594 ret = pwc_set_backlight(pdev, c->value);
595 if (ret < 0)
596 return -EINVAL;
597 return 0;
598 case V4L2_CID_PRIVATE_FLICKERLESS:
599 ret = pwc_set_flicker(pdev, c->value);
600 if (ret < 0)
601 return -EINVAL;
602 case V4L2_CID_PRIVATE_NOISE_REDUCTION:
603 ret = pwc_set_dynamic_noise(pdev, c->value);
604 if (ret < 0)
605 return -EINVAL;
606 return 0;
684 607
685 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",pdev->image.x,pdev->image.y); 608 }
686 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 609 return -EINVAL;
687 return -EINVAL; 610}
688 611
689 pwc_vidioc_fill_fmt(pdev, f); 612static int pwc_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *f)
613{
614 struct pwc_device *pdev = video_drvdata(file);
615
616 /* We only support two format: the raw format, and YUV */
617 switch (f->index) {
618 case 0:
619 /* RAW format */
620 f->pixelformat = pdev->type <= 646 ? V4L2_PIX_FMT_PWC1 : V4L2_PIX_FMT_PWC2;
621 f->flags = V4L2_FMT_FLAG_COMPRESSED;
622 strlcpy(f->description, "Raw Philips Webcam", sizeof(f->description));
623 break;
624 case 1:
625 f->pixelformat = V4L2_PIX_FMT_YUV420;
626 strlcpy(f->description, "4:2:0, planar, Y-Cb-Cr", sizeof(f->description));
627 break;
628 default:
629 return -EINVAL;
630 }
631 return 0;
632}
690 633
691 return 0; 634static int pwc_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
692 } 635{
636 struct pwc_device *pdev = video_drvdata(file);
693 637
694 case VIDIOC_TRY_FMT: 638 PWC_DEBUG_IOCTL("ioctl(VIDIOC_G_FMT) return size %dx%d\n",
695 return pwc_vidioc_try_fmt(pdev, arg); 639 pdev->image.x, pdev->image.y);
640 pwc_vidioc_fill_fmt(pdev, f);
641 return 0;
642}
696 643
697 case VIDIOC_S_FMT: 644static int pwc_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
698 return pwc_vidioc_set_fmt(pdev, arg); 645{
646 struct pwc_device *pdev = video_drvdata(file);
699 647
700 case VIDIOC_G_STD: 648 return pwc_vidioc_try_fmt(pdev, f);
701 { 649}
702 v4l2_std_id *std = arg;
703 *std = V4L2_STD_UNKNOWN;
704 return 0;
705 }
706 650
707 case VIDIOC_S_STD: 651static int pwc_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f)
708 { 652{
709 v4l2_std_id *std = arg; 653 struct pwc_device *pdev = video_drvdata(file);
710 if (*std != V4L2_STD_UNKNOWN)
711 return -EINVAL;
712 return 0;
713 }
714 654
715 case VIDIOC_ENUMSTD: 655 return pwc_vidioc_set_fmt(pdev, f);
716 { 656}
717 struct v4l2_standard *std = arg;
718 if (std->index != 0)
719 return -EINVAL;
720 std->id = V4L2_STD_UNKNOWN;
721 strlcpy(std->name, "webcam", sizeof(std->name));
722 return 0;
723 }
724 657
725 case VIDIOC_REQBUFS: 658static int pwc_reqbufs(struct file *file, void *fh, struct v4l2_requestbuffers *rb)
726 { 659{
727 struct v4l2_requestbuffers *rb = arg; 660 int nbuffers;
728 int nbuffers;
729 661
730 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n",rb->count); 662 PWC_DEBUG_IOCTL("ioctl(VIDIOC_REQBUFS) count=%d\n", rb->count);
731 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 663 if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
732 return -EINVAL; 664 return -EINVAL;
733 if (rb->memory != V4L2_MEMORY_MMAP) 665 if (rb->memory != V4L2_MEMORY_MMAP)
734 return -EINVAL; 666 return -EINVAL;
735 667
736 nbuffers = rb->count; 668 nbuffers = rb->count;
737 if (nbuffers < 2) 669 if (nbuffers < 2)
738 nbuffers = 2; 670 nbuffers = 2;
739 else if (nbuffers > pwc_mbufs) 671 else if (nbuffers > pwc_mbufs)
740 nbuffers = pwc_mbufs; 672 nbuffers = pwc_mbufs;
741 /* Force to use our # of buffers */ 673 /* Force to use our # of buffers */
742 rb->count = pwc_mbufs; 674 rb->count = pwc_mbufs;
743 return 0; 675 return 0;
744 } 676}
745 677
746 case VIDIOC_QUERYBUF: 678static int pwc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
747 { 679{
748 struct v4l2_buffer *buf = arg; 680 struct pwc_device *pdev = video_drvdata(file);
749 int index; 681 int index;
750 682
751 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n",buf->index); 683 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) index=%d\n", buf->index);
752 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 684 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
753 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n"); 685 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad type\n");
754 return -EINVAL; 686 return -EINVAL;
755 } 687 }
756 if (buf->memory != V4L2_MEMORY_MMAP) { 688 index = buf->index;
757 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad memory type\n"); 689 if (index < 0 || index >= pwc_mbufs) {
758 return -EINVAL; 690 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
759 } 691 return -EINVAL;
760 index = buf->index; 692 }
761 if (index < 0 || index >= pwc_mbufs) {
762 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QUERYBUF) Bad index %d\n", buf->index);
763 return -EINVAL;
764 }
765 693
766 memset(buf, 0, sizeof(struct v4l2_buffer)); 694 buf->m.offset = index * pdev->len_per_image;
767 buf->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 695 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
768 buf->index = index; 696 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
769 buf->m.offset = index * pdev->len_per_image; 697 else
770 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) 698 buf->bytesused = pdev->view.size;
771 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); 699 buf->field = V4L2_FIELD_NONE;
772 else 700 buf->memory = V4L2_MEMORY_MMAP;
773 buf->bytesused = pdev->view.size; 701 /*buf->flags = V4L2_BUF_FLAG_MAPPED;*/
774 buf->field = V4L2_FIELD_NONE; 702 buf->length = pdev->len_per_image;
775 buf->memory = V4L2_MEMORY_MMAP;
776 //buf->flags = V4L2_BUF_FLAG_MAPPED;
777 buf->length = pdev->len_per_image;
778
779 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n",buf->index);
780 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n",buf->m.offset);
781 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n",buf->bytesused);
782 703
783 return 0; 704 PWC_DEBUG_READ("VIDIOC_QUERYBUF: index=%d\n", buf->index);
784 } 705 PWC_DEBUG_READ("VIDIOC_QUERYBUF: m.offset=%d\n", buf->m.offset);
706 PWC_DEBUG_READ("VIDIOC_QUERYBUF: bytesused=%d\n", buf->bytesused);
785 707
786 case VIDIOC_QBUF: 708 return 0;
787 { 709}
788 struct v4l2_buffer *buf = arg;
789 710
790 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n",buf->index); 711static int pwc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
791 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 712{
792 return -EINVAL; 713 PWC_DEBUG_IOCTL("ioctl(VIDIOC_QBUF) index=%d\n", buf->index);
793 if (buf->memory != V4L2_MEMORY_MMAP) 714 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
794 return -EINVAL; 715 return -EINVAL;
795 if (buf->index >= pwc_mbufs) 716 if (buf->memory != V4L2_MEMORY_MMAP)
796 return -EINVAL; 717 return -EINVAL;
718 if (buf->index >= pwc_mbufs)
719 return -EINVAL;
797 720
798 buf->flags |= V4L2_BUF_FLAG_QUEUED; 721 buf->flags |= V4L2_BUF_FLAG_QUEUED;
799 buf->flags &= ~V4L2_BUF_FLAG_DONE; 722 buf->flags &= ~V4L2_BUF_FLAG_DONE;
800 723
801 return 0; 724 return 0;
802 } 725}
803 726
804 case VIDIOC_DQBUF: 727static int pwc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
805 { 728{
806 struct v4l2_buffer *buf = arg; 729 DECLARE_WAITQUEUE(wait, current);
807 int ret; 730 struct pwc_device *pdev = video_drvdata(file);
731 int ret;
808 732
809 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n"); 733 PWC_DEBUG_IOCTL("ioctl(VIDIOC_DQBUF)\n");
810 734
811 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 735 if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
812 return -EINVAL; 736 return -EINVAL;
813 737
814 /* Add ourselves to the frame wait-queue. 738 add_wait_queue(&pdev->frameq, &wait);
815 739 while (pdev->full_frames == NULL) {
816 FIXME: needs auditing for safety. 740 if (pdev->error_status) {
817 QUESTION: In what respect? I think that using the 741 remove_wait_queue(&pdev->frameq, &wait);
818 frameq is safe now. 742 set_current_state(TASK_RUNNING);
819 */ 743 return -pdev->error_status;
820 add_wait_queue(&pdev->frameq, &wait); 744 }
821 while (pdev->full_frames == NULL) {
822 if (pdev->error_status) {
823 remove_wait_queue(&pdev->frameq, &wait);
824 set_current_state(TASK_RUNNING);
825 return -pdev->error_status;
826 }
827 745
828 if (signal_pending(current)) { 746 if (signal_pending(current)) {
829 remove_wait_queue(&pdev->frameq, &wait);
830 set_current_state(TASK_RUNNING);
831 return -ERESTARTSYS;
832 }
833 schedule();
834 set_current_state(TASK_INTERRUPTIBLE);
835 }
836 remove_wait_queue(&pdev->frameq, &wait); 747 remove_wait_queue(&pdev->frameq, &wait);
837 set_current_state(TASK_RUNNING); 748 set_current_state(TASK_RUNNING);
749 return -ERESTARTSYS;
750 }
751 mutex_unlock(&pdev->modlock);
752 schedule();
753 set_current_state(TASK_INTERRUPTIBLE);
754 mutex_lock(&pdev->modlock);
755 }
756 remove_wait_queue(&pdev->frameq, &wait);
757 set_current_state(TASK_RUNNING);
838 758
839 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n"); 759 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: frame ready.\n");
840 /* Decompress data in pdev->images[pdev->fill_image] */ 760 /* Decompress data in pdev->images[pdev->fill_image] */
841 ret = pwc_handle_frame(pdev); 761 ret = pwc_handle_frame(pdev);
842 if (ret) 762 if (ret)
843 return -EFAULT; 763 return -EFAULT;
844 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n"); 764 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: after pwc_handle_frame\n");
845 765
846 buf->index = pdev->fill_image; 766 buf->index = pdev->fill_image;
847 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420) 767 if (pdev->pixfmt != V4L2_PIX_FMT_YUV420)
848 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame); 768 buf->bytesused = pdev->frame_size + sizeof(struct pwc_raw_frame);
849 else 769 else
850 buf->bytesused = pdev->view.size; 770 buf->bytesused = pdev->view.size;
851 buf->flags = V4L2_BUF_FLAG_MAPPED; 771 buf->flags = V4L2_BUF_FLAG_MAPPED;
852 buf->field = V4L2_FIELD_NONE; 772 buf->field = V4L2_FIELD_NONE;
853 do_gettimeofday(&buf->timestamp); 773 do_gettimeofday(&buf->timestamp);
854 buf->sequence = 0; 774 buf->sequence = 0;
855 buf->memory = V4L2_MEMORY_MMAP; 775 buf->memory = V4L2_MEMORY_MMAP;
856 buf->m.offset = pdev->fill_image * pdev->len_per_image; 776 buf->m.offset = pdev->fill_image * pdev->len_per_image;
857 buf->length = pdev->len_per_image; 777 buf->length = pdev->len_per_image;
858 pwc_next_image(pdev); 778 pwc_next_image(pdev);
859 779
860 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n",buf->index); 780 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->index=%d\n", buf->index);
861 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n",buf->length); 781 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: buf->length=%d\n", buf->length);
862 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n",buf->m.offset); 782 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: m.offset=%d\n", buf->m.offset);
863 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n",buf->bytesused); 783 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: bytesused=%d\n", buf->bytesused);
864 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n"); 784 PWC_DEBUG_IOCTL("VIDIOC_DQBUF: leaving\n");
865 return 0; 785 return 0;
866 786
867 } 787}
868 788
869 case VIDIOC_STREAMON: 789static int pwc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
870 { 790{
871 return pwc_isoc_init(pdev); 791 struct pwc_device *pdev = video_drvdata(file);
872 }
873 792
874 case VIDIOC_STREAMOFF: 793 return pwc_isoc_init(pdev);
875 { 794}
876 pwc_isoc_cleanup(pdev);
877 return 0;
878 }
879 795
880 case VIDIOC_ENUM_FRAMESIZES: 796static int pwc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
881 { 797{
882 struct v4l2_frmsizeenum *fsize = arg; 798 struct pwc_device *pdev = video_drvdata(file);
883 unsigned int i = 0, index = fsize->index;
884
885 if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
886 for (i = 0; i < PSZ_MAX; i++) {
887 if (pdev->image_mask & (1UL << i)) {
888 if (!index--) {
889 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
890 fsize->discrete.width = pwc_image_sizes[i].x;
891 fsize->discrete.height = pwc_image_sizes[i].y;
892 return 0;
893 }
894 }
895 }
896 } else if (fsize->index == 0 &&
897 ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
898 (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
899
900 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
901 fsize->discrete.width = pdev->abs_max.x;
902 fsize->discrete.height = pdev->abs_max.y;
903 return 0;
904 }
905 return -EINVAL;
906 }
907 799
908 case VIDIOC_ENUM_FRAMEINTERVALS: 800 pwc_isoc_cleanup(pdev);
909 { 801 return 0;
910 struct v4l2_frmivalenum *fival = arg; 802}
911 int size = -1; 803
912 unsigned int i; 804static int pwc_enum_framesizes(struct file *file, void *fh,
913 805 struct v4l2_frmsizeenum *fsize)
914 for (i = 0; i < PSZ_MAX; i++) { 806{
915 if (pwc_image_sizes[i].x == fival->width && 807 struct pwc_device *pdev = video_drvdata(file);
916 pwc_image_sizes[i].y == fival->height) { 808 unsigned int i = 0, index = fsize->index;
917 size = i; 809
918 break; 810 if (fsize->pixel_format == V4L2_PIX_FMT_YUV420) {
811 for (i = 0; i < PSZ_MAX; i++) {
812 if (pdev->image_mask & (1UL << i)) {
813 if (!index--) {
814 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
815 fsize->discrete.width = pwc_image_sizes[i].x;
816 fsize->discrete.height = pwc_image_sizes[i].y;
817 return 0;
919 } 818 }
920 } 819 }
820 }
821 } else if (fsize->index == 0 &&
822 ((fsize->pixel_format == V4L2_PIX_FMT_PWC1 && DEVICE_USE_CODEC1(pdev->type)) ||
823 (fsize->pixel_format == V4L2_PIX_FMT_PWC2 && DEVICE_USE_CODEC23(pdev->type)))) {
824
825 fsize->type = V4L2_FRMSIZE_TYPE_DISCRETE;
826 fsize->discrete.width = pdev->abs_max.x;
827 fsize->discrete.height = pdev->abs_max.y;
828 return 0;
829 }
830 return -EINVAL;
831}
921 832
922 /* TODO: Support raw format */ 833static int pwc_enum_frameintervals(struct file *file, void *fh,
923 if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420) { 834 struct v4l2_frmivalenum *fival)
924 return -EINVAL; 835{
925 } 836 struct pwc_device *pdev = video_drvdata(file);
837 int size = -1;
838 unsigned int i;
839
840 for (i = 0; i < PSZ_MAX; i++) {
841 if (pwc_image_sizes[i].x == fival->width &&
842 pwc_image_sizes[i].y == fival->height) {
843 size = i;
844 break;
845 }
846 }
926 847
927 i = pwc_get_fps(pdev, fival->index, size); 848 /* TODO: Support raw format */
928 if (!i) 849 if (size < 0 || fival->pixel_format != V4L2_PIX_FMT_YUV420)
929 return -EINVAL; 850 return -EINVAL;
930 851
931 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE; 852 i = pwc_get_fps(pdev, fival->index, size);
932 fival->discrete.numerator = 1; 853 if (!i)
933 fival->discrete.denominator = i; 854 return -EINVAL;
934 855
935 return 0; 856 fival->type = V4L2_FRMIVAL_TYPE_DISCRETE;
936 } 857 fival->discrete.numerator = 1;
858 fival->discrete.denominator = i;
937 859
938 default:
939 return pwc_ioctl(pdev, cmd, arg);
940 } /* ..switch */
941 return 0; 860 return 0;
942} 861}
943 862
863static long pwc_default(struct file *file, void *fh, bool valid_prio,
864 int cmd, void *arg)
865{
866 struct pwc_device *pdev = video_drvdata(file);
867
868 return pwc_ioctl(pdev, cmd, arg);
869}
870
871const struct v4l2_ioctl_ops pwc_ioctl_ops = {
872 .vidioc_querycap = pwc_querycap,
873 .vidioc_enum_input = pwc_enum_input,
874 .vidioc_g_input = pwc_g_input,
875 .vidioc_s_input = pwc_s_input,
876 .vidioc_enum_fmt_vid_cap = pwc_enum_fmt_vid_cap,
877 .vidioc_g_fmt_vid_cap = pwc_g_fmt_vid_cap,
878 .vidioc_s_fmt_vid_cap = pwc_s_fmt_vid_cap,
879 .vidioc_try_fmt_vid_cap = pwc_try_fmt_vid_cap,
880 .vidioc_queryctrl = pwc_queryctrl,
881 .vidioc_g_ctrl = pwc_g_ctrl,
882 .vidioc_s_ctrl = pwc_s_ctrl,
883 .vidioc_reqbufs = pwc_reqbufs,
884 .vidioc_querybuf = pwc_querybuf,
885 .vidioc_qbuf = pwc_qbuf,
886 .vidioc_dqbuf = pwc_dqbuf,
887 .vidioc_streamon = pwc_streamon,
888 .vidioc_streamoff = pwc_streamoff,
889 .vidioc_enum_framesizes = pwc_enum_framesizes,
890 .vidioc_enum_frameintervals = pwc_enum_frameintervals,
891 .vidioc_default = pwc_default,
892};
893
894
944/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */ 895/* vim: set cino= formatoptions=croql cindent shiftwidth=8 tabstop=8: */
diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h
index 16bbc6df9b07..e947766337d6 100644
--- a/drivers/media/video/pwc/pwc.h
+++ b/drivers/media/video/pwc/pwc.h
@@ -339,8 +339,7 @@ extern int pwc_camera_power(struct pwc_device *pdev, int power);
339/* Private ioctl()s; see pwc-ioctl.h */ 339/* Private ioctl()s; see pwc-ioctl.h */
340extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg); 340extern long pwc_ioctl(struct pwc_device *pdev, unsigned int cmd, void *arg);
341 341
342/** Functions in pwc-v4l.c */ 342extern const struct v4l2_ioctl_ops pwc_ioctl_ops;
343extern long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg);
344 343
345/** pwc-uncompress.c */ 344/** pwc-uncompress.c */
346/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */ 345/* Expand frame to image, possibly including decompression. Uses read_frame and fill_image */
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 2f500809f53d..95f8b4e11e46 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -27,13 +27,13 @@
27#include <media/v4l2-device.h> 27#include <media/v4l2-device.h>
28#include <media/v4l2-ioctl.h> 28#include <media/v4l2-ioctl.h>
29#include <media/v4l2-mem2mem.h> 29#include <media/v4l2-mem2mem.h>
30#include <media/videobuf-core.h> 30#include <media/videobuf2-core.h>
31#include <media/videobuf-dma-contig.h> 31#include <media/videobuf2-dma-contig.h>
32 32
33#include "fimc-core.h" 33#include "fimc-core.h"
34 34
35static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc, 35static struct v4l2_subdev *fimc_subdev_register(struct fimc_dev *fimc,
36 struct s3c_fimc_isp_info *isp_info) 36 struct s5p_fimc_isp_info *isp_info)
37{ 37{
38 struct i2c_adapter *i2c_adap; 38 struct i2c_adapter *i2c_adap;
39 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 39 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
@@ -86,19 +86,19 @@ static void fimc_subdev_unregister(struct fimc_dev *fimc)
86static int fimc_subdev_attach(struct fimc_dev *fimc, int index) 86static int fimc_subdev_attach(struct fimc_dev *fimc, int index)
87{ 87{
88 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 88 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
89 struct s3c_platform_fimc *pdata = fimc->pdata; 89 struct s5p_platform_fimc *pdata = fimc->pdata;
90 struct s3c_fimc_isp_info *isp_info; 90 struct s5p_fimc_isp_info *isp_info;
91 struct v4l2_subdev *sd; 91 struct v4l2_subdev *sd;
92 int i; 92 int i;
93 93
94 for (i = 0; i < FIMC_MAX_CAMIF_CLIENTS; ++i) { 94 for (i = 0; i < pdata->num_clients; ++i) {
95 isp_info = pdata->isp_info[i]; 95 isp_info = &pdata->isp_info[i];
96 96
97 if (!isp_info || (index >= 0 && i != index)) 97 if (index >= 0 && i != index)
98 continue; 98 continue;
99 99
100 sd = fimc_subdev_register(fimc, isp_info); 100 sd = fimc_subdev_register(fimc, isp_info);
101 if (sd) { 101 if (!IS_ERR_OR_NULL(sd)) {
102 vid_cap->sd = sd; 102 vid_cap->sd = sd;
103 vid_cap->input_index = i; 103 vid_cap->input_index = i;
104 104
@@ -113,60 +113,42 @@ static int fimc_subdev_attach(struct fimc_dev *fimc, int index)
113 return -ENODEV; 113 return -ENODEV;
114} 114}
115 115
116static int fimc_isp_subdev_init(struct fimc_dev *fimc, int index) 116static int fimc_isp_subdev_init(struct fimc_dev *fimc, unsigned int index)
117{ 117{
118 struct s3c_fimc_isp_info *isp_info; 118 struct s5p_fimc_isp_info *isp_info;
119 struct s5p_platform_fimc *pdata = fimc->pdata;
119 int ret; 120 int ret;
120 121
121 ret = fimc_subdev_attach(fimc, index); 122 if (index >= pdata->num_clients)
122 if (ret) 123 return -EINVAL;
123 return ret;
124 124
125 isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index]; 125 isp_info = &pdata->isp_info[index];
126 ret = fimc_hw_set_camera_polarity(fimc, isp_info);
127 if (!ret) {
128 ret = v4l2_subdev_call(fimc->vid_cap.sd, core,
129 s_power, 1);
130 if (!ret)
131 return ret;
132 }
133 126
134 fimc_subdev_unregister(fimc); 127 if (isp_info->clk_frequency)
135 err("ISP initialization failed: %d", ret); 128 clk_set_rate(fimc->clock[CLK_CAM], isp_info->clk_frequency);
136 return ret;
137}
138 129
139/* 130 ret = clk_enable(fimc->clock[CLK_CAM]);
140 * At least one buffer on the pending_buf_q queue is required. 131 if (ret)
141 * Locking: The caller holds fimc->slock spinlock. 132 return ret;
142 */
143int fimc_vid_cap_buf_queue(struct fimc_dev *fimc,
144 struct fimc_vid_buffer *fimc_vb)
145{
146 struct fimc_vid_cap *cap = &fimc->vid_cap;
147 struct fimc_ctx *ctx = cap->ctx;
148 int ret = 0;
149 133
150 BUG_ON(!fimc || !fimc_vb); 134 ret = fimc_subdev_attach(fimc, index);
135 if (ret)
136 return ret;
151 137
152 ret = fimc_prepare_addr(ctx, fimc_vb, &ctx->d_frame, 138 ret = fimc_hw_set_camera_polarity(fimc, isp_info);
153 &fimc_vb->paddr);
154 if (ret) 139 if (ret)
155 return ret; 140 return ret;
156 141
157 if (test_bit(ST_CAPT_STREAM, &fimc->state)) { 142 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 1);
158 fimc_pending_queue_add(cap, fimc_vb); 143 if (!ret)
159 } else { 144 return ret;
160 /* Setup the buffer directly for processing. */ 145
161 int buf_id = (cap->reqbufs_count == 1) ? -1 : cap->buf_index; 146 /* enabling power failed so unregister subdev */
162 fimc_hw_set_output_addr(fimc, &fimc_vb->paddr, buf_id); 147 fimc_subdev_unregister(fimc);
163 148
164 fimc_vb->index = cap->buf_index; 149 v4l2_err(&fimc->vid_cap.v4l2_dev, "ISP initialization failed: %d\n",
165 active_queue_add(cap, fimc_vb); 150 ret);
166 151
167 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
168 cap->buf_index = 0;
169 }
170 return ret; 152 return ret;
171} 153}
172 154
@@ -174,7 +156,7 @@ static int fimc_stop_capture(struct fimc_dev *fimc)
174{ 156{
175 unsigned long flags; 157 unsigned long flags;
176 struct fimc_vid_cap *cap; 158 struct fimc_vid_cap *cap;
177 int ret; 159 struct fimc_vid_buffer *buf;
178 160
179 cap = &fimc->vid_cap; 161 cap = &fimc->vid_cap;
180 162
@@ -187,24 +169,224 @@ static int fimc_stop_capture(struct fimc_dev *fimc)
187 spin_unlock_irqrestore(&fimc->slock, flags); 169 spin_unlock_irqrestore(&fimc->slock, flags);
188 170
189 wait_event_timeout(fimc->irq_queue, 171 wait_event_timeout(fimc->irq_queue,
190 test_bit(ST_CAPT_SHUT, &fimc->state), 172 !test_bit(ST_CAPT_SHUT, &fimc->state),
191 FIMC_SHUTDOWN_TIMEOUT); 173 FIMC_SHUTDOWN_TIMEOUT);
192 174
193 ret = v4l2_subdev_call(cap->sd, video, s_stream, 0); 175 v4l2_subdev_call(cap->sd, video, s_stream, 0);
194 if (ret)
195 v4l2_err(&fimc->vid_cap.v4l2_dev, "s_stream(0) failed\n");
196 176
197 spin_lock_irqsave(&fimc->slock, flags); 177 spin_lock_irqsave(&fimc->slock, flags);
198 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND | 178 fimc->state &= ~(1 << ST_CAPT_RUN | 1 << ST_CAPT_PEND |
199 1 << ST_CAPT_STREAM); 179 1 << ST_CAPT_SHUT | 1 << ST_CAPT_STREAM);
200 180
201 fimc->vid_cap.active_buf_cnt = 0; 181 fimc->vid_cap.active_buf_cnt = 0;
182
183 /* Release buffers that were enqueued in the driver by videobuf2. */
184 while (!list_empty(&cap->pending_buf_q)) {
185 buf = pending_queue_pop(cap);
186 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
187 }
188
189 while (!list_empty(&cap->active_buf_q)) {
190 buf = active_queue_pop(cap);
191 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
192 }
193
202 spin_unlock_irqrestore(&fimc->slock, flags); 194 spin_unlock_irqrestore(&fimc->slock, flags);
203 195
204 dbg("state: 0x%lx", fimc->state); 196 dbg("state: 0x%lx", fimc->state);
205 return 0; 197 return 0;
206} 198}
207 199
200static int start_streaming(struct vb2_queue *q)
201{
202 struct fimc_ctx *ctx = q->drv_priv;
203 struct fimc_dev *fimc = ctx->fimc_dev;
204 struct s5p_fimc_isp_info *isp_info;
205 int ret;
206
207 fimc_hw_reset(fimc);
208
209 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
210 if (ret && ret != -ENOIOCTLCMD)
211 return ret;
212
213 ret = fimc_prepare_config(ctx, ctx->state);
214 if (ret)
215 return ret;
216
217 isp_info = &fimc->pdata->isp_info[fimc->vid_cap.input_index];
218 fimc_hw_set_camera_type(fimc, isp_info);
219 fimc_hw_set_camera_source(fimc, isp_info);
220 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
221
222 if (ctx->state & FIMC_PARAMS) {
223 ret = fimc_set_scaler_info(ctx);
224 if (ret) {
225 err("Scaler setup error");
226 return ret;
227 }
228 fimc_hw_set_input_path(ctx);
229 fimc_hw_set_prescaler(ctx);
230 fimc_hw_set_mainscaler(ctx);
231 fimc_hw_set_target_format(ctx);
232 fimc_hw_set_rotation(ctx);
233 fimc_hw_set_effect(ctx);
234 }
235
236 fimc_hw_set_output_path(ctx);
237 fimc_hw_set_out_dma(ctx);
238
239 INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
240 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
241 fimc->vid_cap.active_buf_cnt = 0;
242 fimc->vid_cap.frame_count = 0;
243 fimc->vid_cap.buf_index = 0;
244
245 set_bit(ST_CAPT_PEND, &fimc->state);
246
247 return 0;
248}
249
250static int stop_streaming(struct vb2_queue *q)
251{
252 struct fimc_ctx *ctx = q->drv_priv;
253 struct fimc_dev *fimc = ctx->fimc_dev;
254
255 if (!fimc_capture_active(fimc))
256 return -EINVAL;
257
258 return fimc_stop_capture(fimc);
259}
260
261static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
262{
263 if (!fr || plane >= fr->fmt->memplanes)
264 return 0;
265
266 dbg("%s: w: %d. h: %d. depth[%d]: %d",
267 __func__, fr->width, fr->height, plane, fr->fmt->depth[plane]);
268
269 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
270
271}
272
273static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
274 unsigned int *num_planes, unsigned long sizes[],
275 void *allocators[])
276{
277 struct fimc_ctx *ctx = vq->drv_priv;
278 struct fimc_fmt *fmt = ctx->d_frame.fmt;
279 int i;
280
281 if (!fmt)
282 return -EINVAL;
283
284 *num_planes = fmt->memplanes;
285
286 dbg("%s, buffer count=%d, plane count=%d",
287 __func__, *num_buffers, *num_planes);
288
289 for (i = 0; i < fmt->memplanes; i++) {
290 sizes[i] = get_plane_size(&ctx->d_frame, i);
291 dbg("plane: %u, plane_size: %lu", i, sizes[i]);
292 allocators[i] = ctx->fimc_dev->alloc_ctx;
293 }
294
295 return 0;
296}
297
298static int buffer_init(struct vb2_buffer *vb)
299{
300 /* TODO: */
301 return 0;
302}
303
304static int buffer_prepare(struct vb2_buffer *vb)
305{
306 struct vb2_queue *vq = vb->vb2_queue;
307 struct fimc_ctx *ctx = vq->drv_priv;
308 struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev;
309 int i;
310
311 if (!ctx->d_frame.fmt || vq->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
312 return -EINVAL;
313
314 for (i = 0; i < ctx->d_frame.fmt->memplanes; i++) {
315 unsigned long size = get_plane_size(&ctx->d_frame, i);
316
317 if (vb2_plane_size(vb, i) < size) {
318 v4l2_err(v4l2_dev, "User buffer too small (%ld < %ld)\n",
319 vb2_plane_size(vb, i), size);
320 return -EINVAL;
321 }
322
323 vb2_set_plane_payload(vb, i, size);
324 }
325
326 return 0;
327}
328
329static void buffer_queue(struct vb2_buffer *vb)
330{
331 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
332 struct fimc_dev *fimc = ctx->fimc_dev;
333 struct fimc_vid_buffer *buf
334 = container_of(vb, struct fimc_vid_buffer, vb);
335 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
336 unsigned long flags;
337 int min_bufs;
338
339 spin_lock_irqsave(&fimc->slock, flags);
340 fimc_prepare_addr(ctx, &buf->vb, &ctx->d_frame, &buf->paddr);
341
342 if (!test_bit(ST_CAPT_STREAM, &fimc->state)
343 && vid_cap->active_buf_cnt < FIMC_MAX_OUT_BUFS) {
344 /* Setup the buffer directly for processing. */
345 int buf_id = (vid_cap->reqbufs_count == 1) ? -1 :
346 vid_cap->buf_index;
347
348 fimc_hw_set_output_addr(fimc, &buf->paddr, buf_id);
349 buf->index = vid_cap->buf_index;
350 active_queue_add(vid_cap, buf);
351
352 if (++vid_cap->buf_index >= FIMC_MAX_OUT_BUFS)
353 vid_cap->buf_index = 0;
354 } else {
355 fimc_pending_queue_add(vid_cap, buf);
356 }
357
358 min_bufs = vid_cap->reqbufs_count > 1 ? 2 : 1;
359
360 if (vid_cap->active_buf_cnt >= min_bufs &&
361 !test_and_set_bit(ST_CAPT_STREAM, &fimc->state))
362 fimc_activate_capture(ctx);
363
364 spin_unlock_irqrestore(&fimc->slock, flags);
365}
366
367static void fimc_lock(struct vb2_queue *vq)
368{
369 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
370 mutex_lock(&ctx->fimc_dev->lock);
371}
372
373static void fimc_unlock(struct vb2_queue *vq)
374{
375 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
376 mutex_unlock(&ctx->fimc_dev->lock);
377}
378
379static struct vb2_ops fimc_capture_qops = {
380 .queue_setup = queue_setup,
381 .buf_prepare = buffer_prepare,
382 .buf_queue = buffer_queue,
383 .buf_init = buffer_init,
384 .wait_prepare = fimc_unlock,
385 .wait_finish = fimc_lock,
386 .start_streaming = start_streaming,
387 .stop_streaming = stop_streaming,
388};
389
208static int fimc_capture_open(struct file *file) 390static int fimc_capture_open(struct file *file)
209{ 391{
210 struct fimc_dev *fimc = video_drvdata(file); 392 struct fimc_dev *fimc = video_drvdata(file);
@@ -216,44 +398,36 @@ static int fimc_capture_open(struct file *file)
216 if (fimc_m2m_active(fimc)) 398 if (fimc_m2m_active(fimc))
217 return -EBUSY; 399 return -EBUSY;
218 400
219 if (mutex_lock_interruptible(&fimc->lock))
220 return -ERESTARTSYS;
221
222 if (++fimc->vid_cap.refcnt == 1) { 401 if (++fimc->vid_cap.refcnt == 1) {
223 ret = fimc_isp_subdev_init(fimc, -1); 402 ret = fimc_isp_subdev_init(fimc, 0);
224 if (ret) { 403 if (ret) {
225 fimc->vid_cap.refcnt--; 404 fimc->vid_cap.refcnt--;
226 ret = -EIO; 405 return -EIO;
227 } 406 }
228 } 407 }
229 408
230 file->private_data = fimc->vid_cap.ctx; 409 file->private_data = fimc->vid_cap.ctx;
231 410
232 mutex_unlock(&fimc->lock); 411 return 0;
233 return ret;
234} 412}
235 413
236static int fimc_capture_close(struct file *file) 414static int fimc_capture_close(struct file *file)
237{ 415{
238 struct fimc_dev *fimc = video_drvdata(file); 416 struct fimc_dev *fimc = video_drvdata(file);
239 417
240 if (mutex_lock_interruptible(&fimc->lock))
241 return -ERESTARTSYS;
242
243 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state); 418 dbg("pid: %d, state: 0x%lx", task_pid_nr(current), fimc->state);
244 419
245 if (--fimc->vid_cap.refcnt == 0) { 420 if (--fimc->vid_cap.refcnt == 0) {
246 fimc_stop_capture(fimc); 421 fimc_stop_capture(fimc);
247 422 vb2_queue_release(&fimc->vid_cap.vbq);
248 videobuf_stop(&fimc->vid_cap.vbq);
249 videobuf_mmap_free(&fimc->vid_cap.vbq);
250 423
251 v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n"); 424 v4l2_err(&fimc->vid_cap.v4l2_dev, "releasing ISP\n");
425
252 v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 426 v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
427 clk_disable(fimc->clock[CLK_CAM]);
253 fimc_subdev_unregister(fimc); 428 fimc_subdev_unregister(fimc);
254 } 429 }
255 430
256 mutex_unlock(&fimc->lock);
257 return 0; 431 return 0;
258} 432}
259 433
@@ -262,32 +436,16 @@ static unsigned int fimc_capture_poll(struct file *file,
262{ 436{
263 struct fimc_ctx *ctx = file->private_data; 437 struct fimc_ctx *ctx = file->private_data;
264 struct fimc_dev *fimc = ctx->fimc_dev; 438 struct fimc_dev *fimc = ctx->fimc_dev;
265 struct fimc_vid_cap *cap = &fimc->vid_cap;
266 int ret;
267
268 if (mutex_lock_interruptible(&fimc->lock))
269 return POLLERR;
270 439
271 ret = videobuf_poll_stream(file, &cap->vbq, wait); 440 return vb2_poll(&fimc->vid_cap.vbq, file, wait);
272 mutex_unlock(&fimc->lock);
273
274 return ret;
275} 441}
276 442
277static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma) 443static int fimc_capture_mmap(struct file *file, struct vm_area_struct *vma)
278{ 444{
279 struct fimc_ctx *ctx = file->private_data; 445 struct fimc_ctx *ctx = file->private_data;
280 struct fimc_dev *fimc = ctx->fimc_dev; 446 struct fimc_dev *fimc = ctx->fimc_dev;
281 struct fimc_vid_cap *cap = &fimc->vid_cap;
282 int ret;
283
284 if (mutex_lock_interruptible(&fimc->lock))
285 return -ERESTARTSYS;
286 447
287 ret = videobuf_mmap_mapper(&cap->vbq, vma); 448 return vb2_mmap(&fimc->vid_cap.vbq, vma);
288 mutex_unlock(&fimc->lock);
289
290 return ret;
291} 449}
292 450
293/* video device file operations */ 451/* video device file operations */
@@ -310,7 +468,8 @@ static int fimc_vidioc_querycap_capture(struct file *file, void *priv,
310 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1); 468 strncpy(cap->card, fimc->pdev->name, sizeof(cap->card) - 1);
311 cap->bus_info[0] = 0; 469 cap->bus_info[0] = 0;
312 cap->version = KERNEL_VERSION(1, 0, 0); 470 cap->version = KERNEL_VERSION(1, 0, 0);
313 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE; 471 cap->capabilities = V4L2_CAP_STREAMING | V4L2_CAP_VIDEO_CAPTURE |
472 V4L2_CAP_VIDEO_CAPTURE_MPLANE;
314 473
315 return 0; 474 return 0;
316} 475}
@@ -351,57 +510,52 @@ static int sync_capture_fmt(struct fimc_ctx *ctx)
351 return 0; 510 return 0;
352} 511}
353 512
354static int fimc_cap_s_fmt(struct file *file, void *priv, 513static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
355 struct v4l2_format *f) 514 struct v4l2_format *f)
356{ 515{
357 struct fimc_ctx *ctx = priv; 516 struct fimc_ctx *ctx = priv;
358 struct fimc_dev *fimc = ctx->fimc_dev; 517 struct fimc_dev *fimc = ctx->fimc_dev;
359 struct fimc_frame *frame; 518 struct fimc_frame *frame;
360 struct v4l2_pix_format *pix; 519 struct v4l2_pix_format_mplane *pix;
361 int ret; 520 int ret;
521 int i;
362 522
363 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 523 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
364 return -EINVAL; 524 return -EINVAL;
365 525
366 ret = fimc_vidioc_try_fmt(file, priv, f); 526 ret = fimc_vidioc_try_fmt_mplane(file, priv, f);
367 if (ret) 527 if (ret)
368 return ret; 528 return ret;
369 529
370 if (mutex_lock_interruptible(&fimc->lock)) 530 if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc))
371 return -ERESTARTSYS; 531 return -EBUSY;
372
373 if (fimc_capture_active(fimc)) {
374 ret = -EBUSY;
375 goto sf_unlock;
376 }
377 532
378 frame = &ctx->d_frame; 533 frame = &ctx->d_frame;
379 534
380 pix = &f->fmt.pix; 535 pix = &f->fmt.pix_mp;
381 frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM); 536 frame->fmt = find_format(f, FMT_FLAGS_M2M | FMT_FLAGS_CAM);
382 if (!frame->fmt) { 537 if (!frame->fmt) {
383 err("fimc target format not found\n"); 538 err("fimc target format not found\n");
384 ret = -EINVAL; 539 return -EINVAL;
385 goto sf_unlock;
386 } 540 }
387 541
542 for (i = 0; i < frame->fmt->colplanes; i++)
543 frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
544
388 /* Output DMA frame pixel size and offsets. */ 545 /* Output DMA frame pixel size and offsets. */
389 frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; 546 frame->f_width = pix->plane_fmt[0].bytesperline * 8
547 / frame->fmt->depth[0];
390 frame->f_height = pix->height; 548 frame->f_height = pix->height;
391 frame->width = pix->width; 549 frame->width = pix->width;
392 frame->height = pix->height; 550 frame->height = pix->height;
393 frame->o_width = pix->width; 551 frame->o_width = pix->width;
394 frame->o_height = pix->height; 552 frame->o_height = pix->height;
395 frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3;
396 frame->offs_h = 0; 553 frame->offs_h = 0;
397 frame->offs_v = 0; 554 frame->offs_v = 0;
398 555
399 ret = sync_capture_fmt(ctx);
400
401 ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT); 556 ctx->state |= (FIMC_PARAMS | FIMC_DST_FMT);
402 557
403sf_unlock: 558 ret = sync_capture_fmt(ctx);
404 mutex_unlock(&fimc->lock);
405 return ret; 559 return ret;
406} 560}
407 561
@@ -409,15 +563,13 @@ static int fimc_cap_enum_input(struct file *file, void *priv,
409 struct v4l2_input *i) 563 struct v4l2_input *i)
410{ 564{
411 struct fimc_ctx *ctx = priv; 565 struct fimc_ctx *ctx = priv;
412 struct s3c_platform_fimc *pldata = ctx->fimc_dev->pdata; 566 struct s5p_platform_fimc *pldata = ctx->fimc_dev->pdata;
413 struct s3c_fimc_isp_info *isp_info; 567 struct s5p_fimc_isp_info *isp_info;
414 568
415 if (i->index >= FIMC_MAX_CAMIF_CLIENTS) 569 if (i->index >= pldata->num_clients)
416 return -EINVAL; 570 return -EINVAL;
417 571
418 isp_info = pldata->isp_info[i->index]; 572 isp_info = &pldata->isp_info[i->index];
419 if (isp_info == NULL)
420 return -EINVAL;
421 573
422 i->type = V4L2_INPUT_TYPE_CAMERA; 574 i->type = V4L2_INPUT_TYPE_CAMERA;
423 strncpy(i->name, isp_info->board_info->type, 32); 575 strncpy(i->name, isp_info->board_info->type, 32);
@@ -429,34 +581,27 @@ static int fimc_cap_s_input(struct file *file, void *priv,
429{ 581{
430 struct fimc_ctx *ctx = priv; 582 struct fimc_ctx *ctx = priv;
431 struct fimc_dev *fimc = ctx->fimc_dev; 583 struct fimc_dev *fimc = ctx->fimc_dev;
432 struct s3c_platform_fimc *pdata = fimc->pdata; 584 struct s5p_platform_fimc *pdata = fimc->pdata;
433 int ret;
434 585
435 if (fimc_capture_active(ctx->fimc_dev)) 586 if (fimc_capture_active(ctx->fimc_dev))
436 return -EBUSY; 587 return -EBUSY;
437 588
438 if (mutex_lock_interruptible(&fimc->lock)) 589 if (i >= pdata->num_clients)
439 return -ERESTARTSYS; 590 return -EINVAL;
440 591
441 if (i >= FIMC_MAX_CAMIF_CLIENTS || !pdata->isp_info[i]) {
442 ret = -EINVAL;
443 goto si_unlock;
444 }
445 592
446 if (fimc->vid_cap.sd) { 593 if (fimc->vid_cap.sd) {
447 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0); 594 int ret = v4l2_subdev_call(fimc->vid_cap.sd, core, s_power, 0);
448 if (ret) 595 if (ret)
449 err("s_power failed: %d", ret); 596 err("s_power failed: %d", ret);
597
598 clk_disable(fimc->clock[CLK_CAM]);
450 } 599 }
451 600
452 /* Release the attached sensor subdevice. */ 601 /* Release the attached sensor subdevice. */
453 fimc_subdev_unregister(fimc); 602 fimc_subdev_unregister(fimc);
454 603
455 ret = fimc_isp_subdev_init(fimc, i); 604 return fimc_isp_subdev_init(fimc, i);
456
457si_unlock:
458 mutex_unlock(&fimc->lock);
459 return ret;
460} 605}
461 606
462static int fimc_cap_g_input(struct file *file, void *priv, 607static int fimc_cap_g_input(struct file *file, void *priv,
@@ -470,66 +615,20 @@ static int fimc_cap_g_input(struct file *file, void *priv,
470} 615}
471 616
472static int fimc_cap_streamon(struct file *file, void *priv, 617static int fimc_cap_streamon(struct file *file, void *priv,
473 enum v4l2_buf_type type) 618 enum v4l2_buf_type type)
474{ 619{
475 struct s3c_fimc_isp_info *isp_info;
476 struct fimc_ctx *ctx = priv; 620 struct fimc_ctx *ctx = priv;
477 struct fimc_dev *fimc = ctx->fimc_dev; 621 struct fimc_dev *fimc = ctx->fimc_dev;
478 int ret = -EBUSY;
479
480 if (mutex_lock_interruptible(&fimc->lock))
481 return -ERESTARTSYS;
482 622
483 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd) 623 if (fimc_capture_active(fimc) || !fimc->vid_cap.sd)
484 goto s_unlock; 624 return -EBUSY;
485 625
486 if (!(ctx->state & FIMC_DST_FMT)) { 626 if (!(ctx->state & FIMC_DST_FMT)) {
487 v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n"); 627 v4l2_err(&fimc->vid_cap.v4l2_dev, "Format is not set\n");
488 ret = -EINVAL; 628 return -EINVAL;
489 goto s_unlock;
490 }
491
492 ret = v4l2_subdev_call(fimc->vid_cap.sd, video, s_stream, 1);
493 if (ret && ret != -ENOIOCTLCMD)
494 goto s_unlock;
495
496 ret = fimc_prepare_config(ctx, ctx->state);
497 if (ret)
498 goto s_unlock;
499
500 isp_info = fimc->pdata->isp_info[fimc->vid_cap.input_index];
501 fimc_hw_set_camera_type(fimc, isp_info);
502 fimc_hw_set_camera_source(fimc, isp_info);
503 fimc_hw_set_camera_offset(fimc, &ctx->s_frame);
504
505 if (ctx->state & FIMC_PARAMS) {
506 ret = fimc_set_scaler_info(ctx);
507 if (ret) {
508 err("Scaler setup error");
509 goto s_unlock;
510 }
511 fimc_hw_set_input_path(ctx);
512 fimc_hw_set_scaler(ctx);
513 fimc_hw_set_target_format(ctx);
514 fimc_hw_set_rotation(ctx);
515 fimc_hw_set_effect(ctx);
516 } 629 }
517 630
518 fimc_hw_set_output_path(ctx); 631 return vb2_streamon(&fimc->vid_cap.vbq, type);
519 fimc_hw_set_out_dma(ctx);
520
521 INIT_LIST_HEAD(&fimc->vid_cap.pending_buf_q);
522 INIT_LIST_HEAD(&fimc->vid_cap.active_buf_q);
523 fimc->vid_cap.active_buf_cnt = 0;
524 fimc->vid_cap.frame_count = 0;
525 fimc->vid_cap.buf_index = fimc_hw_get_frame_index(fimc);
526
527 set_bit(ST_CAPT_PEND, &fimc->state);
528 ret = videobuf_streamon(&fimc->vid_cap.vbq);
529
530s_unlock:
531 mutex_unlock(&fimc->lock);
532 return ret;
533} 632}
534 633
535static int fimc_cap_streamoff(struct file *file, void *priv, 634static int fimc_cap_streamoff(struct file *file, void *priv,
@@ -537,46 +636,22 @@ static int fimc_cap_streamoff(struct file *file, void *priv,
537{ 636{
538 struct fimc_ctx *ctx = priv; 637 struct fimc_ctx *ctx = priv;
539 struct fimc_dev *fimc = ctx->fimc_dev; 638 struct fimc_dev *fimc = ctx->fimc_dev;
540 struct fimc_vid_cap *cap = &fimc->vid_cap;
541 unsigned long flags;
542 int ret;
543
544 spin_lock_irqsave(&fimc->slock, flags);
545 if (!fimc_capture_running(fimc) && !fimc_capture_pending(fimc)) {
546 spin_unlock_irqrestore(&fimc->slock, flags);
547 dbg("state: 0x%lx", fimc->state);
548 return -EINVAL;
549 }
550 spin_unlock_irqrestore(&fimc->slock, flags);
551 639
552 if (mutex_lock_interruptible(&fimc->lock)) 640 return vb2_streamoff(&fimc->vid_cap.vbq, type);
553 return -ERESTARTSYS;
554
555 fimc_stop_capture(fimc);
556 ret = videobuf_streamoff(&cap->vbq);
557 mutex_unlock(&fimc->lock);
558 return ret;
559} 641}
560 642
561static int fimc_cap_reqbufs(struct file *file, void *priv, 643static int fimc_cap_reqbufs(struct file *file, void *priv,
562 struct v4l2_requestbuffers *reqbufs) 644 struct v4l2_requestbuffers *reqbufs)
563{ 645{
564 struct fimc_ctx *ctx = priv; 646 struct fimc_ctx *ctx = priv;
565 struct fimc_dev *fimc = ctx->fimc_dev; 647 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
566 struct fimc_vid_cap *cap = &fimc->vid_cap;
567 int ret; 648 int ret;
568 649
569 if (fimc_capture_active(ctx->fimc_dev))
570 return -EBUSY;
571 650
572 if (mutex_lock_interruptible(&fimc->lock)) 651 ret = vb2_reqbufs(&cap->vbq, reqbufs);
573 return -ERESTARTSYS;
574
575 ret = videobuf_reqbufs(&cap->vbq, reqbufs);
576 if (!ret) 652 if (!ret)
577 cap->reqbufs_count = reqbufs->count; 653 cap->reqbufs_count = reqbufs->count;
578 654
579 mutex_unlock(&fimc->lock);
580 return ret; 655 return ret;
581} 656}
582 657
@@ -586,43 +661,23 @@ static int fimc_cap_querybuf(struct file *file, void *priv,
586 struct fimc_ctx *ctx = priv; 661 struct fimc_ctx *ctx = priv;
587 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap; 662 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
588 663
589 if (fimc_capture_active(ctx->fimc_dev)) 664 return vb2_querybuf(&cap->vbq, buf);
590 return -EBUSY;
591
592 return videobuf_querybuf(&cap->vbq, buf);
593} 665}
594 666
595static int fimc_cap_qbuf(struct file *file, void *priv, 667static int fimc_cap_qbuf(struct file *file, void *priv,
596 struct v4l2_buffer *buf) 668 struct v4l2_buffer *buf)
597{ 669{
598 struct fimc_ctx *ctx = priv; 670 struct fimc_ctx *ctx = priv;
599 struct fimc_dev *fimc = ctx->fimc_dev; 671 struct fimc_vid_cap *cap = &ctx->fimc_dev->vid_cap;
600 struct fimc_vid_cap *cap = &fimc->vid_cap; 672 return vb2_qbuf(&cap->vbq, buf);
601 int ret;
602
603 if (mutex_lock_interruptible(&fimc->lock))
604 return -ERESTARTSYS;
605
606 ret = videobuf_qbuf(&cap->vbq, buf);
607
608 mutex_unlock(&fimc->lock);
609 return ret;
610} 673}
611 674
612static int fimc_cap_dqbuf(struct file *file, void *priv, 675static int fimc_cap_dqbuf(struct file *file, void *priv,
613 struct v4l2_buffer *buf) 676 struct v4l2_buffer *buf)
614{ 677{
615 struct fimc_ctx *ctx = priv; 678 struct fimc_ctx *ctx = priv;
616 int ret; 679 return vb2_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf,
617
618 if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
619 return -ERESTARTSYS;
620
621 ret = videobuf_dqbuf(&ctx->fimc_dev->vid_cap.vbq, buf,
622 file->f_flags & O_NONBLOCK); 680 file->f_flags & O_NONBLOCK);
623
624 mutex_unlock(&ctx->fimc_dev->lock);
625 return ret;
626} 681}
627 682
628static int fimc_cap_s_ctrl(struct file *file, void *priv, 683static int fimc_cap_s_ctrl(struct file *file, void *priv,
@@ -631,9 +686,6 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
631 struct fimc_ctx *ctx = priv; 686 struct fimc_ctx *ctx = priv;
632 int ret = -EINVAL; 687 int ret = -EINVAL;
633 688
634 if (mutex_lock_interruptible(&ctx->fimc_dev->lock))
635 return -ERESTARTSYS;
636
637 /* Allow any controls but 90/270 rotation while streaming */ 689 /* Allow any controls but 90/270 rotation while streaming */
638 if (!fimc_capture_active(ctx->fimc_dev) || 690 if (!fimc_capture_active(ctx->fimc_dev) ||
639 ctrl->id != V4L2_CID_ROTATE || 691 ctrl->id != V4L2_CID_ROTATE ||
@@ -648,8 +700,6 @@ static int fimc_cap_s_ctrl(struct file *file, void *priv,
648 if (ret == -EINVAL) 700 if (ret == -EINVAL)
649 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd, 701 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
650 core, s_ctrl, ctrl); 702 core, s_ctrl, ctrl);
651
652 mutex_unlock(&ctx->fimc_dev->lock);
653 return ret; 703 return ret;
654} 704}
655 705
@@ -658,22 +708,18 @@ static int fimc_cap_cropcap(struct file *file, void *fh,
658{ 708{
659 struct fimc_frame *f; 709 struct fimc_frame *f;
660 struct fimc_ctx *ctx = fh; 710 struct fimc_ctx *ctx = fh;
661 struct fimc_dev *fimc = ctx->fimc_dev;
662 711
663 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) 712 if (cr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
664 return -EINVAL; 713 return -EINVAL;
665 714
666 if (mutex_lock_interruptible(&fimc->lock))
667 return -ERESTARTSYS;
668
669 f = &ctx->s_frame; 715 f = &ctx->s_frame;
716
670 cr->bounds.left = 0; 717 cr->bounds.left = 0;
671 cr->bounds.top = 0; 718 cr->bounds.top = 0;
672 cr->bounds.width = f->o_width; 719 cr->bounds.width = f->o_width;
673 cr->bounds.height = f->o_height; 720 cr->bounds.height = f->o_height;
674 cr->defrect = cr->bounds; 721 cr->defrect = cr->bounds;
675 722
676 mutex_unlock(&fimc->lock);
677 return 0; 723 return 0;
678} 724}
679 725
@@ -681,19 +727,14 @@ static int fimc_cap_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
681{ 727{
682 struct fimc_frame *f; 728 struct fimc_frame *f;
683 struct fimc_ctx *ctx = file->private_data; 729 struct fimc_ctx *ctx = file->private_data;
684 struct fimc_dev *fimc = ctx->fimc_dev;
685
686
687 if (mutex_lock_interruptible(&fimc->lock))
688 return -ERESTARTSYS;
689 730
690 f = &ctx->s_frame; 731 f = &ctx->s_frame;
732
691 cr->c.left = f->offs_h; 733 cr->c.left = f->offs_h;
692 cr->c.top = f->offs_v; 734 cr->c.top = f->offs_v;
693 cr->c.width = f->width; 735 cr->c.width = f->width;
694 cr->c.height = f->height; 736 cr->c.height = f->height;
695 737
696 mutex_unlock(&fimc->lock);
697 return 0; 738 return 0;
698} 739}
699 740
@@ -712,41 +753,38 @@ static int fimc_cap_s_crop(struct file *file, void *fh,
712 if (ret) 753 if (ret)
713 return ret; 754 return ret;
714 755
715 if (mutex_lock_interruptible(&fimc->lock))
716 return -ERESTARTSYS;
717
718 if (!(ctx->state & FIMC_DST_FMT)) { 756 if (!(ctx->state & FIMC_DST_FMT)) {
719 v4l2_err(&fimc->vid_cap.v4l2_dev, 757 v4l2_err(&fimc->vid_cap.v4l2_dev,
720 "Capture color format not set\n"); 758 "Capture color format not set\n");
721 goto sc_unlock; 759 return -EINVAL; /* TODO: make sure this is the right value */
722 } 760 }
723 761
724 f = &ctx->s_frame; 762 f = &ctx->s_frame;
725 /* Check for the pixel scaling ratio when cropping input image. */ 763 /* Check for the pixel scaling ratio when cropping input image. */
726 ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); 764 ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height,
765 ctx->d_frame.width, ctx->d_frame.height,
766 ctx->rotation);
727 if (ret) { 767 if (ret) {
728 v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range"); 768 v4l2_err(&fimc->vid_cap.v4l2_dev, "Out of the scaler range\n");
729 } else { 769 return ret;
730 ret = 0;
731 f->offs_h = cr->c.left;
732 f->offs_v = cr->c.top;
733 f->width = cr->c.width;
734 f->height = cr->c.height;
735 } 770 }
736 771
737sc_unlock: 772 f->offs_h = cr->c.left;
738 mutex_unlock(&fimc->lock); 773 f->offs_v = cr->c.top;
739 return ret; 774 f->width = cr->c.width;
775 f->height = cr->c.height;
776
777 return 0;
740} 778}
741 779
742 780
743static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = { 781static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
744 .vidioc_querycap = fimc_vidioc_querycap_capture, 782 .vidioc_querycap = fimc_vidioc_querycap_capture,
745 783
746 .vidioc_enum_fmt_vid_cap = fimc_vidioc_enum_fmt, 784 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane,
747 .vidioc_try_fmt_vid_cap = fimc_vidioc_try_fmt, 785 .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane,
748 .vidioc_s_fmt_vid_cap = fimc_cap_s_fmt, 786 .vidioc_s_fmt_vid_cap_mplane = fimc_cap_s_fmt_mplane,
749 .vidioc_g_fmt_vid_cap = fimc_vidioc_g_fmt, 787 .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane,
750 788
751 .vidioc_reqbufs = fimc_cap_reqbufs, 789 .vidioc_reqbufs = fimc_cap_reqbufs,
752 .vidioc_querybuf = fimc_cap_querybuf, 790 .vidioc_querybuf = fimc_cap_querybuf,
@@ -770,6 +808,7 @@ static const struct v4l2_ioctl_ops fimc_capture_ioctl_ops = {
770 .vidioc_g_input = fimc_cap_g_input, 808 .vidioc_g_input = fimc_cap_g_input,
771}; 809};
772 810
811/* fimc->lock must be already initialized */
773int fimc_register_capture_device(struct fimc_dev *fimc) 812int fimc_register_capture_device(struct fimc_dev *fimc)
774{ 813{
775 struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev; 814 struct v4l2_device *v4l2_dev = &fimc->vid_cap.v4l2_dev;
@@ -777,6 +816,8 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
777 struct fimc_vid_cap *vid_cap; 816 struct fimc_vid_cap *vid_cap;
778 struct fimc_ctx *ctx; 817 struct fimc_ctx *ctx;
779 struct v4l2_format f; 818 struct v4l2_format f;
819 struct fimc_frame *fr;
820 struct vb2_queue *q;
780 int ret; 821 int ret;
781 822
782 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 823 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
@@ -788,8 +829,12 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
788 ctx->out_path = FIMC_DMA; 829 ctx->out_path = FIMC_DMA;
789 ctx->state = FIMC_CTX_CAP; 830 ctx->state = FIMC_CTX_CAP;
790 831
791 f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB24; 832 /* Default format of the output frames */
792 ctx->d_frame.fmt = find_format(&f, FMT_FLAGS_M2M); 833 f.fmt.pix.pixelformat = V4L2_PIX_FMT_RGB32;
834 fr = &ctx->d_frame;
835 fr->fmt = find_format(&f, FMT_FLAGS_M2M);
836 fr->width = fr->f_width = fr->o_width = 640;
837 fr->height = fr->f_height = fr->o_height = 480;
793 838
794 if (!v4l2_dev->name[0]) 839 if (!v4l2_dev->name[0])
795 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), 840 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name),
@@ -812,6 +857,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
812 vfd->ioctl_ops = &fimc_capture_ioctl_ops; 857 vfd->ioctl_ops = &fimc_capture_ioctl_ops;
813 vfd->minor = -1; 858 vfd->minor = -1;
814 vfd->release = video_device_release; 859 vfd->release = video_device_release;
860 vfd->lock = &fimc->lock;
815 video_set_drvdata(vfd, fimc); 861 video_set_drvdata(vfd, fimc);
816 862
817 vid_cap = &fimc->vid_cap; 863 vid_cap = &fimc->vid_cap;
@@ -819,7 +865,7 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
819 vid_cap->active_buf_cnt = 0; 865 vid_cap->active_buf_cnt = 0;
820 vid_cap->reqbufs_count = 0; 866 vid_cap->reqbufs_count = 0;
821 vid_cap->refcnt = 0; 867 vid_cap->refcnt = 0;
822 /* The default color format for image sensor. */ 868 /* Default color format for image sensor */
823 vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8; 869 vid_cap->fmt.code = V4L2_MBUS_FMT_YUYV8_2X8;
824 870
825 INIT_LIST_HEAD(&vid_cap->pending_buf_q); 871 INIT_LIST_HEAD(&vid_cap->pending_buf_q);
@@ -827,10 +873,16 @@ int fimc_register_capture_device(struct fimc_dev *fimc)
827 spin_lock_init(&ctx->slock); 873 spin_lock_init(&ctx->slock);
828 vid_cap->ctx = ctx; 874 vid_cap->ctx = ctx;
829 875
830 videobuf_queue_dma_contig_init(&vid_cap->vbq, &fimc_qops, 876 q = &fimc->vid_cap.vbq;
831 vid_cap->v4l2_dev.dev, &fimc->irqlock, 877 memset(q, 0, sizeof(*q));
832 V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_NONE, 878 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
833 sizeof(struct fimc_vid_buffer), (void *)ctx, NULL); 879 q->io_modes = VB2_MMAP | VB2_USERPTR;
880 q->drv_priv = fimc->vid_cap.ctx;
881 q->ops = &fimc_capture_qops;
882 q->mem_ops = &vb2_dma_contig_memops;
883 q->buf_struct_size = sizeof(struct fimc_vid_buffer);
884
885 vb2_queue_init(q);
834 886
835 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1); 887 ret = video_register_device(vfd, VFL_TYPE_GRABBER, -1);
836 if (ret) { 888 if (ret) {
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 817aa66627f6..6c919b38a3d8 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -25,114 +25,141 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/clk.h> 26#include <linux/clk.h>
27#include <media/v4l2-ioctl.h> 27#include <media/v4l2-ioctl.h>
28#include <media/videobuf-dma-contig.h> 28#include <media/videobuf2-core.h>
29#include <media/videobuf2-dma-contig.h>
29 30
30#include "fimc-core.h" 31#include "fimc-core.h"
31 32
32static char *fimc_clock_name[NUM_FIMC_CLOCKS] = { "sclk_fimc", "fimc" }; 33static char *fimc_clocks[MAX_FIMC_CLOCKS] = {
34 "sclk_fimc", "fimc", "sclk_cam"
35};
33 36
34static struct fimc_fmt fimc_formats[] = { 37static struct fimc_fmt fimc_formats[] = {
35 { 38 {
36 .name = "RGB565", 39 .name = "RGB565",
37 .fourcc = V4L2_PIX_FMT_RGB565X, 40 .fourcc = V4L2_PIX_FMT_RGB565X,
38 .depth = 16, 41 .depth = { 16 },
39 .color = S5P_FIMC_RGB565, 42 .color = S5P_FIMC_RGB565,
40 .buff_cnt = 1, 43 .memplanes = 1,
41 .planes_cnt = 1, 44 .colplanes = 1,
42 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE, 45 .mbus_code = V4L2_MBUS_FMT_RGB565_2X8_BE,
43 .flags = FMT_FLAGS_M2M, 46 .flags = FMT_FLAGS_M2M,
47 }, {
48 .name = "BGR666",
49 .fourcc = V4L2_PIX_FMT_BGR666,
50 .depth = { 32 },
51 .color = S5P_FIMC_RGB666,
52 .memplanes = 1,
53 .colplanes = 1,
54 .flags = FMT_FLAGS_M2M,
55 }, {
56 .name = "XRGB-8-8-8-8, 32 bpp",
57 .fourcc = V4L2_PIX_FMT_RGB32,
58 .depth = { 32 },
59 .color = S5P_FIMC_RGB888,
60 .memplanes = 1,
61 .colplanes = 1,
62 .flags = FMT_FLAGS_M2M,
63 }, {
64 .name = "YUV 4:2:2 packed, YCbYCr",
65 .fourcc = V4L2_PIX_FMT_YUYV,
66 .depth = { 16 },
67 .color = S5P_FIMC_YCBYCR422,
68 .memplanes = 1,
69 .colplanes = 1,
70 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8,
71 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
44 }, { 72 }, {
45 .name = "BGR666", 73 .name = "YUV 4:2:2 packed, CbYCrY",
46 .fourcc = V4L2_PIX_FMT_BGR666, 74 .fourcc = V4L2_PIX_FMT_UYVY,
47 .depth = 32, 75 .depth = { 16 },
48 .color = S5P_FIMC_RGB666, 76 .color = S5P_FIMC_CBYCRY422,
49 .buff_cnt = 1, 77 .memplanes = 1,
50 .planes_cnt = 1, 78 .colplanes = 1,
51 .flags = FMT_FLAGS_M2M, 79 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8,
80 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
52 }, { 81 }, {
53 .name = "XRGB-8-8-8-8, 32 bpp", 82 .name = "YUV 4:2:2 packed, CrYCbY",
54 .fourcc = V4L2_PIX_FMT_RGB32, 83 .fourcc = V4L2_PIX_FMT_VYUY,
55 .depth = 32, 84 .depth = { 16 },
56 .color = S5P_FIMC_RGB888, 85 .color = S5P_FIMC_CRYCBY422,
57 .buff_cnt = 1, 86 .memplanes = 1,
58 .planes_cnt = 1, 87 .colplanes = 1,
59 .flags = FMT_FLAGS_M2M, 88 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8,
89 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
60 }, { 90 }, {
61 .name = "YUV 4:2:2 packed, YCbYCr", 91 .name = "YUV 4:2:2 packed, YCrYCb",
62 .fourcc = V4L2_PIX_FMT_YUYV, 92 .fourcc = V4L2_PIX_FMT_YVYU,
63 .depth = 16, 93 .depth = { 16 },
64 .color = S5P_FIMC_YCBYCR422, 94 .color = S5P_FIMC_YCRYCB422,
65 .buff_cnt = 1, 95 .memplanes = 1,
66 .planes_cnt = 1, 96 .colplanes = 1,
67 .mbus_code = V4L2_MBUS_FMT_YUYV8_2X8, 97 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8,
68 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM, 98 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
69 }, { 99 }, {
70 .name = "YUV 4:2:2 packed, CbYCrY", 100 .name = "YUV 4:2:2 planar, Y/Cb/Cr",
71 .fourcc = V4L2_PIX_FMT_UYVY, 101 .fourcc = V4L2_PIX_FMT_YUV422P,
72 .depth = 16, 102 .depth = { 12 },
73 .color = S5P_FIMC_CBYCRY422, 103 .color = S5P_FIMC_YCBYCR422,
74 .buff_cnt = 1, 104 .memplanes = 1,
75 .planes_cnt = 1, 105 .colplanes = 3,
76 .mbus_code = V4L2_MBUS_FMT_UYVY8_2X8, 106 .flags = FMT_FLAGS_M2M,
77 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
78 }, { 107 }, {
79 .name = "YUV 4:2:2 packed, CrYCbY", 108 .name = "YUV 4:2:2 planar, Y/CbCr",
80 .fourcc = V4L2_PIX_FMT_VYUY, 109 .fourcc = V4L2_PIX_FMT_NV16,
81 .depth = 16, 110 .depth = { 16 },
82 .color = S5P_FIMC_CRYCBY422, 111 .color = S5P_FIMC_YCBYCR422,
83 .buff_cnt = 1, 112 .memplanes = 1,
84 .planes_cnt = 1, 113 .colplanes = 2,
85 .mbus_code = V4L2_MBUS_FMT_VYUY8_2X8, 114 .flags = FMT_FLAGS_M2M,
86 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
87 }, { 115 }, {
88 .name = "YUV 4:2:2 packed, YCrYCb", 116 .name = "YUV 4:2:2 planar, Y/CrCb",
89 .fourcc = V4L2_PIX_FMT_YVYU, 117 .fourcc = V4L2_PIX_FMT_NV61,
90 .depth = 16, 118 .depth = { 16 },
91 .color = S5P_FIMC_YCRYCB422, 119 .color = S5P_FIMC_YCRYCB422,
92 .buff_cnt = 1, 120 .memplanes = 1,
93 .planes_cnt = 1, 121 .colplanes = 2,
94 .mbus_code = V4L2_MBUS_FMT_YVYU8_2X8, 122 .flags = FMT_FLAGS_M2M,
95 .flags = FMT_FLAGS_M2M | FMT_FLAGS_CAM,
96 }, { 123 }, {
97 .name = "YUV 4:2:2 planar, Y/Cb/Cr", 124 .name = "YUV 4:2:0 planar, YCbCr",
98 .fourcc = V4L2_PIX_FMT_YUV422P, 125 .fourcc = V4L2_PIX_FMT_YUV420,
99 .depth = 12, 126 .depth = { 12 },
100 .color = S5P_FIMC_YCBCR422, 127 .color = S5P_FIMC_YCBCR420,
101 .buff_cnt = 1, 128 .memplanes = 1,
102 .planes_cnt = 3, 129 .colplanes = 3,
103 .flags = FMT_FLAGS_M2M, 130 .flags = FMT_FLAGS_M2M,
104 }, { 131 }, {
105 .name = "YUV 4:2:2 planar, Y/CbCr", 132 .name = "YUV 4:2:0 planar, Y/CbCr",
106 .fourcc = V4L2_PIX_FMT_NV16, 133 .fourcc = V4L2_PIX_FMT_NV12,
107 .depth = 16, 134 .depth = { 12 },
108 .color = S5P_FIMC_YCBCR422, 135 .color = S5P_FIMC_YCBCR420,
109 .buff_cnt = 1, 136 .memplanes = 1,
110 .planes_cnt = 2, 137 .colplanes = 2,
111 .flags = FMT_FLAGS_M2M, 138 .flags = FMT_FLAGS_M2M,
112 }, { 139 }, {
113 .name = "YUV 4:2:2 planar, Y/CrCb", 140 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr",
114 .fourcc = V4L2_PIX_FMT_NV61, 141 .fourcc = V4L2_PIX_FMT_NV12M,
115 .depth = 16, 142 .color = S5P_FIMC_YCBCR420,
116 .color = S5P_FIMC_RGB565, 143 .depth = { 8, 4 },
117 .buff_cnt = 1, 144 .memplanes = 2,
118 .planes_cnt = 2, 145 .colplanes = 2,
119 .flags = FMT_FLAGS_M2M, 146 .flags = FMT_FLAGS_M2M,
120 }, { 147 }, {
121 .name = "YUV 4:2:0 planar, YCbCr", 148 .name = "YUV 4:2:0 non-contiguous 3-planar, Y/Cb/Cr",
122 .fourcc = V4L2_PIX_FMT_YUV420, 149 .fourcc = V4L2_PIX_FMT_YUV420M,
123 .depth = 12, 150 .color = S5P_FIMC_YCBCR420,
124 .color = S5P_FIMC_YCBCR420, 151 .depth = { 8, 2, 2 },
125 .buff_cnt = 1, 152 .memplanes = 3,
126 .planes_cnt = 3, 153 .colplanes = 3,
127 .flags = FMT_FLAGS_M2M, 154 .flags = FMT_FLAGS_M2M,
128 }, { 155 }, {
129 .name = "YUV 4:2:0 planar, Y/CbCr", 156 .name = "YUV 4:2:0 non-contiguous 2-planar, Y/CbCr, tiled",
130 .fourcc = V4L2_PIX_FMT_NV12, 157 .fourcc = V4L2_PIX_FMT_NV12MT,
131 .depth = 12, 158 .color = S5P_FIMC_YCBCR420,
132 .color = S5P_FIMC_YCBCR420, 159 .depth = { 8, 4 },
133 .buff_cnt = 1, 160 .memplanes = 2,
134 .planes_cnt = 2, 161 .colplanes = 2,
135 .flags = FMT_FLAGS_M2M, 162 .flags = FMT_FLAGS_M2M,
136 }, 163 },
137}; 164};
138 165
@@ -173,24 +200,21 @@ static struct v4l2_queryctrl *get_ctrl(int id)
173 return NULL; 200 return NULL;
174} 201}
175 202
176int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f) 203int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot)
177{ 204{
178 if (r->width > f->width) { 205 int tx, ty;
179 if (f->width > (r->width * SCALER_MAX_HRATIO))
180 return -EINVAL;
181 } else {
182 if ((f->width * SCALER_MAX_HRATIO) < r->width)
183 return -EINVAL;
184 }
185 206
186 if (r->height > f->height) { 207 if (rot == 90 || rot == 270) {
187 if (f->height > (r->height * SCALER_MAX_VRATIO)) 208 ty = dw;
188 return -EINVAL; 209 tx = dh;
189 } else { 210 } else {
190 if ((f->height * SCALER_MAX_VRATIO) < r->height) 211 tx = dw;
191 return -EINVAL; 212 ty = dh;
192 } 213 }
193 214
215 if ((sw >= SCALER_MAX_HRATIO * tx) || (sh >= SCALER_MAX_VRATIO * ty))
216 return -EINVAL;
217
194 return 0; 218 return 0;
195} 219}
196 220
@@ -221,6 +245,7 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
221 struct fimc_scaler *sc = &ctx->scaler; 245 struct fimc_scaler *sc = &ctx->scaler;
222 struct fimc_frame *s_frame = &ctx->s_frame; 246 struct fimc_frame *s_frame = &ctx->s_frame;
223 struct fimc_frame *d_frame = &ctx->d_frame; 247 struct fimc_frame *d_frame = &ctx->d_frame;
248 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
224 int tx, ty, sx, sy; 249 int tx, ty, sx, sy;
225 int ret; 250 int ret;
226 251
@@ -259,8 +284,14 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
259 sc->pre_dst_width = sx / sc->pre_hratio; 284 sc->pre_dst_width = sx / sc->pre_hratio;
260 sc->pre_dst_height = sy / sc->pre_vratio; 285 sc->pre_dst_height = sy / sc->pre_vratio;
261 286
262 sc->main_hratio = (sx << 8) / (tx << sc->hfactor); 287 if (variant->has_mainscaler_ext) {
263 sc->main_vratio = (sy << 8) / (ty << sc->vfactor); 288 sc->main_hratio = (sx << 14) / (tx << sc->hfactor);
289 sc->main_vratio = (sy << 14) / (ty << sc->vfactor);
290 } else {
291 sc->main_hratio = (sx << 8) / (tx << sc->hfactor);
292 sc->main_vratio = (sy << 8) / (ty << sc->vfactor);
293
294 }
264 295
265 sc->scaleup_h = (tx >= sx) ? 1 : 0; 296 sc->scaleup_h = (tx >= sx) ? 1 : 0;
266 sc->scaleup_v = (ty >= sy) ? 1 : 0; 297 sc->scaleup_v = (ty >= sy) ? 1 : 0;
@@ -276,14 +307,65 @@ int fimc_set_scaler_info(struct fimc_ctx *ctx)
276 return 0; 307 return 0;
277} 308}
278 309
279static void fimc_capture_handler(struct fimc_dev *fimc) 310static void fimc_m2m_job_finish(struct fimc_ctx *ctx, int vb_state)
311{
312 struct vb2_buffer *src_vb, *dst_vb;
313 struct fimc_dev *fimc = ctx->fimc_dev;
314
315 if (!ctx || !ctx->m2m_ctx)
316 return;
317
318 src_vb = v4l2_m2m_src_buf_remove(ctx->m2m_ctx);
319 dst_vb = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx);
320
321 if (src_vb && dst_vb) {
322 v4l2_m2m_buf_done(src_vb, vb_state);
323 v4l2_m2m_buf_done(dst_vb, vb_state);
324 v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx);
325 }
326}
327
328/* Complete the transaction which has been scheduled for execution. */
329static void fimc_m2m_shutdown(struct fimc_ctx *ctx)
330{
331 struct fimc_dev *fimc = ctx->fimc_dev;
332 int ret;
333
334 if (!fimc_m2m_pending(fimc))
335 return;
336
337 fimc_ctx_state_lock_set(FIMC_CTX_SHUT, ctx);
338
339 ret = wait_event_timeout(fimc->irq_queue,
340 !fimc_ctx_state_is_set(FIMC_CTX_SHUT, ctx),
341 FIMC_SHUTDOWN_TIMEOUT);
342 /*
343 * In case of a timeout the buffers are not released in the interrupt
344 * handler so return them here with the error flag set, if there are
345 * any on the queue.
346 */
347 if (ret == 0)
348 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_ERROR);
349}
350
351static int stop_streaming(struct vb2_queue *q)
352{
353 struct fimc_ctx *ctx = q->drv_priv;
354
355 fimc_m2m_shutdown(ctx);
356
357 return 0;
358}
359
360static void fimc_capture_irq_handler(struct fimc_dev *fimc)
280{ 361{
281 struct fimc_vid_cap *cap = &fimc->vid_cap; 362 struct fimc_vid_cap *cap = &fimc->vid_cap;
282 struct fimc_vid_buffer *v_buf = NULL; 363 struct fimc_vid_buffer *v_buf;
283 364
284 if (!list_empty(&cap->active_buf_q)) { 365 if (!list_empty(&cap->active_buf_q) &&
366 test_bit(ST_CAPT_RUN, &fimc->state)) {
285 v_buf = active_queue_pop(cap); 367 v_buf = active_queue_pop(cap);
286 fimc_buf_finish(fimc, v_buf); 368 vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
287 } 369 }
288 370
289 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) { 371 if (test_and_clear_bit(ST_CAPT_SHUT, &fimc->state)) {
@@ -297,13 +379,6 @@ static void fimc_capture_handler(struct fimc_dev *fimc)
297 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index); 379 fimc_hw_set_output_addr(fimc, &v_buf->paddr, cap->buf_index);
298 v_buf->index = cap->buf_index; 380 v_buf->index = cap->buf_index;
299 381
300 dbg("hw ptr: %d, sw ptr: %d",
301 fimc_hw_get_frame_index(fimc), cap->buf_index);
302
303 spin_lock(&fimc->irqlock);
304 v_buf->vb.state = VIDEOBUF_ACTIVE;
305 spin_unlock(&fimc->irqlock);
306
307 /* Move the buffer to the capture active queue */ 382 /* Move the buffer to the capture active queue */
308 active_queue_add(cap, v_buf); 383 active_queue_add(cap, v_buf);
309 384
@@ -312,77 +387,79 @@ static void fimc_capture_handler(struct fimc_dev *fimc)
312 387
313 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS) 388 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
314 cap->buf_index = 0; 389 cap->buf_index = 0;
390 }
315 391
316 } else if (test_and_clear_bit(ST_CAPT_STREAM, &fimc->state) && 392 if (cap->active_buf_cnt == 0) {
317 cap->active_buf_cnt <= 1) { 393 clear_bit(ST_CAPT_RUN, &fimc->state);
318 fimc_deactivate_capture(fimc); 394
395 if (++cap->buf_index >= FIMC_MAX_OUT_BUFS)
396 cap->buf_index = 0;
397 } else {
398 set_bit(ST_CAPT_RUN, &fimc->state);
319 } 399 }
320 400
321 dbg("frame: %d, active_buf_cnt= %d", 401 dbg("frame: %d, active_buf_cnt: %d",
322 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt); 402 fimc_hw_get_frame_index(fimc), cap->active_buf_cnt);
323} 403}
324 404
325static irqreturn_t fimc_isr(int irq, void *priv) 405static irqreturn_t fimc_isr(int irq, void *priv)
326{ 406{
327 struct fimc_vid_buffer *src_buf, *dst_buf;
328 struct fimc_ctx *ctx;
329 struct fimc_dev *fimc = priv; 407 struct fimc_dev *fimc = priv;
408 struct fimc_vid_cap *cap = &fimc->vid_cap;
409 struct fimc_ctx *ctx;
330 410
331 BUG_ON(!fimc);
332 fimc_hw_clear_irq(fimc); 411 fimc_hw_clear_irq(fimc);
333 412
334 spin_lock(&fimc->slock);
335
336 if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) { 413 if (test_and_clear_bit(ST_M2M_PEND, &fimc->state)) {
337 ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev); 414 ctx = v4l2_m2m_get_curr_priv(fimc->m2m.m2m_dev);
338 if (!ctx || !ctx->m2m_ctx) 415 if (ctx != NULL) {
339 goto isr_unlock; 416 fimc_m2m_job_finish(ctx, VB2_BUF_STATE_DONE);
340 src_buf = v4l2_m2m_src_buf_remove(ctx->m2m_ctx); 417
341 dst_buf = v4l2_m2m_dst_buf_remove(ctx->m2m_ctx); 418 spin_lock(&ctx->slock);
342 if (src_buf && dst_buf) { 419 if (ctx->state & FIMC_CTX_SHUT) {
343 spin_lock(&fimc->irqlock); 420 ctx->state &= ~FIMC_CTX_SHUT;
344 src_buf->vb.state = dst_buf->vb.state = VIDEOBUF_DONE; 421 wake_up(&fimc->irq_queue);
345 wake_up(&src_buf->vb.done); 422 }
346 wake_up(&dst_buf->vb.done); 423 spin_unlock(&ctx->slock);
347 spin_unlock(&fimc->irqlock);
348 v4l2_m2m_job_finish(fimc->m2m.m2m_dev, ctx->m2m_ctx);
349 } 424 }
350 goto isr_unlock;
351 425
426 return IRQ_HANDLED;
352 } 427 }
353 428
354 if (test_bit(ST_CAPT_RUN, &fimc->state)) 429 spin_lock(&fimc->slock);
355 fimc_capture_handler(fimc);
356 430
357 if (test_and_clear_bit(ST_CAPT_PEND, &fimc->state)) { 431 if (test_bit(ST_CAPT_PEND, &fimc->state)) {
358 set_bit(ST_CAPT_RUN, &fimc->state); 432 fimc_capture_irq_handler(fimc);
359 wake_up(&fimc->irq_queue); 433
434 if (cap->active_buf_cnt == 1) {
435 fimc_deactivate_capture(fimc);
436 clear_bit(ST_CAPT_STREAM, &fimc->state);
437 }
360 } 438 }
361 439
362isr_unlock:
363 spin_unlock(&fimc->slock); 440 spin_unlock(&fimc->slock);
364 return IRQ_HANDLED; 441 return IRQ_HANDLED;
365} 442}
366 443
367/* The color format (planes_cnt, buff_cnt) must be already configured. */ 444/* The color format (colplanes, memplanes) must be already configured. */
368int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, 445int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
369 struct fimc_frame *frame, struct fimc_addr *paddr) 446 struct fimc_frame *frame, struct fimc_addr *paddr)
370{ 447{
371 int ret = 0; 448 int ret = 0;
372 u32 pix_size; 449 u32 pix_size;
373 450
374 if (buf == NULL || frame == NULL) 451 if (vb == NULL || frame == NULL)
375 return -EINVAL; 452 return -EINVAL;
376 453
377 pix_size = frame->width * frame->height; 454 pix_size = frame->width * frame->height;
378 455
379 dbg("buff_cnt= %d, planes_cnt= %d, frame->size= %d, pix_size= %d", 456 dbg("memplanes= %d, colplanes= %d, pix_size= %d",
380 frame->fmt->buff_cnt, frame->fmt->planes_cnt, 457 frame->fmt->memplanes, frame->fmt->colplanes, pix_size);
381 frame->size, pix_size); 458
459 paddr->y = vb2_dma_contig_plane_paddr(vb, 0);
382 460
383 if (frame->fmt->buff_cnt == 1) { 461 if (frame->fmt->memplanes == 1) {
384 paddr->y = videobuf_to_dma_contig(&buf->vb); 462 switch (frame->fmt->colplanes) {
385 switch (frame->fmt->planes_cnt) {
386 case 1: 463 case 1:
387 paddr->cb = 0; 464 paddr->cb = 0;
388 paddr->cr = 0; 465 paddr->cr = 0;
@@ -405,6 +482,12 @@ int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf,
405 default: 482 default:
406 return -EINVAL; 483 return -EINVAL;
407 } 484 }
485 } else {
486 if (frame->fmt->memplanes >= 2)
487 paddr->cb = vb2_dma_contig_plane_paddr(vb, 1);
488
489 if (frame->fmt->memplanes == 3)
490 paddr->cr = vb2_dma_contig_plane_paddr(vb, 2);
408 } 491 }
409 492
410 dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d", 493 dbg("PHYS_ADDR: y= 0x%X cb= 0x%X cr= 0x%X ret= %d",
@@ -423,34 +506,34 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
423 /* Set order for 1 plane input formats. */ 506 /* Set order for 1 plane input formats. */
424 switch (ctx->s_frame.fmt->color) { 507 switch (ctx->s_frame.fmt->color) {
425 case S5P_FIMC_YCRYCB422: 508 case S5P_FIMC_YCRYCB422:
426 ctx->in_order_1p = S5P_FIMC_IN_YCRYCB; 509 ctx->in_order_1p = S5P_MSCTRL_ORDER422_CBYCRY;
427 break; 510 break;
428 case S5P_FIMC_CBYCRY422: 511 case S5P_FIMC_CBYCRY422:
429 ctx->in_order_1p = S5P_FIMC_IN_CBYCRY; 512 ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCRYCB;
430 break; 513 break;
431 case S5P_FIMC_CRYCBY422: 514 case S5P_FIMC_CRYCBY422:
432 ctx->in_order_1p = S5P_FIMC_IN_CRYCBY; 515 ctx->in_order_1p = S5P_MSCTRL_ORDER422_YCBYCR;
433 break; 516 break;
434 case S5P_FIMC_YCBYCR422: 517 case S5P_FIMC_YCBYCR422:
435 default: 518 default:
436 ctx->in_order_1p = S5P_FIMC_IN_YCBYCR; 519 ctx->in_order_1p = S5P_MSCTRL_ORDER422_CRYCBY;
437 break; 520 break;
438 } 521 }
439 dbg("ctx->in_order_1p= %d", ctx->in_order_1p); 522 dbg("ctx->in_order_1p= %d", ctx->in_order_1p);
440 523
441 switch (ctx->d_frame.fmt->color) { 524 switch (ctx->d_frame.fmt->color) {
442 case S5P_FIMC_YCRYCB422: 525 case S5P_FIMC_YCRYCB422:
443 ctx->out_order_1p = S5P_FIMC_OUT_YCRYCB; 526 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CBYCRY;
444 break; 527 break;
445 case S5P_FIMC_CBYCRY422: 528 case S5P_FIMC_CBYCRY422:
446 ctx->out_order_1p = S5P_FIMC_OUT_CBYCRY; 529 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCRYCB;
447 break; 530 break;
448 case S5P_FIMC_CRYCBY422: 531 case S5P_FIMC_CRYCBY422:
449 ctx->out_order_1p = S5P_FIMC_OUT_CRYCBY; 532 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_YCBYCR;
450 break; 533 break;
451 case S5P_FIMC_YCBYCR422: 534 case S5P_FIMC_YCBYCR422:
452 default: 535 default:
453 ctx->out_order_1p = S5P_FIMC_OUT_YCBYCR; 536 ctx->out_order_1p = S5P_CIOCTRL_ORDER422_CRYCBY;
454 break; 537 break;
455 } 538 }
456 dbg("ctx->out_order_1p= %d", ctx->out_order_1p); 539 dbg("ctx->out_order_1p= %d", ctx->out_order_1p);
@@ -459,10 +542,14 @@ static void fimc_set_yuv_order(struct fimc_ctx *ctx)
459static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f) 542static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
460{ 543{
461 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 544 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
545 u32 i, depth = 0;
546
547 for (i = 0; i < f->fmt->colplanes; i++)
548 depth += f->fmt->depth[i];
462 549
463 f->dma_offset.y_h = f->offs_h; 550 f->dma_offset.y_h = f->offs_h;
464 if (!variant->pix_hoff) 551 if (!variant->pix_hoff)
465 f->dma_offset.y_h *= (f->fmt->depth >> 3); 552 f->dma_offset.y_h *= (depth >> 3);
466 553
467 f->dma_offset.y_v = f->offs_v; 554 f->dma_offset.y_v = f->offs_v;
468 555
@@ -473,7 +560,7 @@ static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
473 f->dma_offset.cr_v = f->offs_v; 560 f->dma_offset.cr_v = f->offs_v;
474 561
475 if (!variant->pix_hoff) { 562 if (!variant->pix_hoff) {
476 if (f->fmt->planes_cnt == 3) { 563 if (f->fmt->colplanes == 3) {
477 f->dma_offset.cb_h >>= 1; 564 f->dma_offset.cb_h >>= 1;
478 f->dma_offset.cr_h >>= 1; 565 f->dma_offset.cr_h >>= 1;
479 } 566 }
@@ -499,7 +586,7 @@ static void fimc_prepare_dma_offset(struct fimc_ctx *ctx, struct fimc_frame *f)
499int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags) 586int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
500{ 587{
501 struct fimc_frame *s_frame, *d_frame; 588 struct fimc_frame *s_frame, *d_frame;
502 struct fimc_vid_buffer *buf = NULL; 589 struct vb2_buffer *vb = NULL;
503 int ret = 0; 590 int ret = 0;
504 591
505 s_frame = &ctx->s_frame; 592 s_frame = &ctx->s_frame;
@@ -522,15 +609,15 @@ int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags)
522 ctx->scaler.enabled = 1; 609 ctx->scaler.enabled = 1;
523 610
524 if (flags & FIMC_SRC_ADDR) { 611 if (flags & FIMC_SRC_ADDR) {
525 buf = v4l2_m2m_next_src_buf(ctx->m2m_ctx); 612 vb = v4l2_m2m_next_src_buf(ctx->m2m_ctx);
526 ret = fimc_prepare_addr(ctx, buf, s_frame, &s_frame->paddr); 613 ret = fimc_prepare_addr(ctx, vb, s_frame, &s_frame->paddr);
527 if (ret) 614 if (ret)
528 return ret; 615 return ret;
529 } 616 }
530 617
531 if (flags & FIMC_DST_ADDR) { 618 if (flags & FIMC_DST_ADDR) {
532 buf = v4l2_m2m_next_dst_buf(ctx->m2m_ctx); 619 vb = v4l2_m2m_next_dst_buf(ctx->m2m_ctx);
533 ret = fimc_prepare_addr(ctx, buf, d_frame, &d_frame->paddr); 620 ret = fimc_prepare_addr(ctx, vb, d_frame, &d_frame->paddr);
534 } 621 }
535 622
536 return ret; 623 return ret;
@@ -553,26 +640,28 @@ static void fimc_dma_run(void *priv)
553 640
554 ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR); 641 ctx->state |= (FIMC_SRC_ADDR | FIMC_DST_ADDR);
555 ret = fimc_prepare_config(ctx, ctx->state); 642 ret = fimc_prepare_config(ctx, ctx->state);
556 if (ret) { 643 if (ret)
557 err("Wrong parameters");
558 goto dma_unlock; 644 goto dma_unlock;
559 } 645
560 /* Reconfigure hardware if the context has changed. */ 646 /* Reconfigure hardware if the context has changed. */
561 if (fimc->m2m.ctx != ctx) { 647 if (fimc->m2m.ctx != ctx) {
562 ctx->state |= FIMC_PARAMS; 648 ctx->state |= FIMC_PARAMS;
563 fimc->m2m.ctx = ctx; 649 fimc->m2m.ctx = ctx;
564 } 650 }
565 651
652 spin_lock(&fimc->slock);
566 fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr); 653 fimc_hw_set_input_addr(fimc, &ctx->s_frame.paddr);
567 654
568 if (ctx->state & FIMC_PARAMS) { 655 if (ctx->state & FIMC_PARAMS) {
569 fimc_hw_set_input_path(ctx); 656 fimc_hw_set_input_path(ctx);
570 fimc_hw_set_in_dma(ctx); 657 fimc_hw_set_in_dma(ctx);
571 if (fimc_set_scaler_info(ctx)) { 658 ret = fimc_set_scaler_info(ctx);
572 err("Scaler setup error"); 659 if (ret) {
660 spin_unlock(&fimc->slock);
573 goto dma_unlock; 661 goto dma_unlock;
574 } 662 }
575 fimc_hw_set_scaler(ctx); 663 fimc_hw_set_prescaler(ctx);
664 fimc_hw_set_mainscaler(ctx);
576 fimc_hw_set_target_format(ctx); 665 fimc_hw_set_target_format(ctx);
577 fimc_hw_set_rotation(ctx); 666 fimc_hw_set_rotation(ctx);
578 fimc_hw_set_effect(ctx); 667 fimc_hw_set_effect(ctx);
@@ -587,8 +676,10 @@ static void fimc_dma_run(void *priv)
587 676
588 fimc_activate_capture(ctx); 677 fimc_activate_capture(ctx);
589 678
590 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP); 679 ctx->state &= (FIMC_CTX_M2M | FIMC_CTX_CAP |
680 FIMC_SRC_FMT | FIMC_DST_FMT);
591 fimc_hw_activate_input_dma(fimc, true); 681 fimc_hw_activate_input_dma(fimc, true);
682 spin_unlock(&fimc->slock);
592 683
593dma_unlock: 684dma_unlock:
594 spin_unlock_irqrestore(&ctx->slock, flags); 685 spin_unlock_irqrestore(&ctx->slock, flags);
@@ -596,109 +687,84 @@ dma_unlock:
596 687
597static void fimc_job_abort(void *priv) 688static void fimc_job_abort(void *priv)
598{ 689{
599 /* Nothing done in job_abort. */ 690 fimc_m2m_shutdown(priv);
600} 691}
601 692
602static void fimc_buf_release(struct videobuf_queue *vq, 693static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers,
603 struct videobuf_buffer *vb) 694 unsigned int *num_planes, unsigned long sizes[],
695 void *allocators[])
604{ 696{
605 videobuf_dma_contig_free(vq, vb); 697 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
606 vb->state = VIDEOBUF_NEEDS_INIT; 698 struct fimc_frame *f;
607} 699 int i;
608 700
609static int fimc_buf_setup(struct videobuf_queue *vq, unsigned int *count, 701 f = ctx_get_frame(ctx, vq->type);
610 unsigned int *size) 702 if (IS_ERR(f))
611{ 703 return PTR_ERR(f);
612 struct fimc_ctx *ctx = vq->priv_data;
613 struct fimc_frame *frame;
614 704
615 frame = ctx_get_frame(ctx, vq->type); 705 /*
616 if (IS_ERR(frame)) 706 * Return number of non-contigous planes (plane buffers)
617 return PTR_ERR(frame); 707 * depending on the configured color format.
708 */
709 if (f->fmt)
710 *num_planes = f->fmt->memplanes;
711
712 for (i = 0; i < f->fmt->memplanes; i++) {
713 sizes[i] = (f->width * f->height * f->fmt->depth[i]) >> 3;
714 allocators[i] = ctx->fimc_dev->alloc_ctx;
715 }
716
717 if (*num_buffers == 0)
718 *num_buffers = 1;
618 719
619 *size = (frame->width * frame->height * frame->fmt->depth) >> 3;
620 if (0 == *count)
621 *count = 1;
622 return 0; 720 return 0;
623} 721}
624 722
625static int fimc_buf_prepare(struct videobuf_queue *vq, 723static int fimc_buf_prepare(struct vb2_buffer *vb)
626 struct videobuf_buffer *vb, enum v4l2_field field)
627{ 724{
628 struct fimc_ctx *ctx = vq->priv_data; 725 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
629 struct v4l2_device *v4l2_dev = &ctx->fimc_dev->m2m.v4l2_dev;
630 struct fimc_frame *frame; 726 struct fimc_frame *frame;
631 int ret; 727 int i;
632 728
633 frame = ctx_get_frame(ctx, vq->type); 729 frame = ctx_get_frame(ctx, vb->vb2_queue->type);
634 if (IS_ERR(frame)) 730 if (IS_ERR(frame))
635 return PTR_ERR(frame); 731 return PTR_ERR(frame);
636 732
637 if (vb->baddr) { 733 for (i = 0; i < frame->fmt->memplanes; i++)
638 if (vb->bsize < frame->size) { 734 vb2_set_plane_payload(vb, i, frame->payload[i]);
639 v4l2_err(v4l2_dev,
640 "User-provided buffer too small (%d < %d)\n",
641 vb->bsize, frame->size);
642 WARN_ON(1);
643 return -EINVAL;
644 }
645 } else if (vb->state != VIDEOBUF_NEEDS_INIT
646 && vb->bsize < frame->size) {
647 return -EINVAL;
648 }
649
650 vb->width = frame->width;
651 vb->height = frame->height;
652 vb->bytesperline = (frame->width * frame->fmt->depth) >> 3;
653 vb->size = frame->size;
654 vb->field = field;
655
656 if (VIDEOBUF_NEEDS_INIT == vb->state) {
657 ret = videobuf_iolock(vq, vb, NULL);
658 if (ret) {
659 v4l2_err(v4l2_dev, "Iolock failed\n");
660 fimc_buf_release(vq, vb);
661 return ret;
662 }
663 }
664 vb->state = VIDEOBUF_PREPARED;
665 735
666 return 0; 736 return 0;
667} 737}
668 738
669static void fimc_buf_queue(struct videobuf_queue *vq, 739static void fimc_buf_queue(struct vb2_buffer *vb)
670 struct videobuf_buffer *vb)
671{ 740{
672 struct fimc_ctx *ctx = vq->priv_data; 741 struct fimc_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue);
673 struct fimc_dev *fimc = ctx->fimc_dev;
674 struct fimc_vid_cap *cap = &fimc->vid_cap;
675 unsigned long flags;
676 742
677 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state); 743 dbg("ctx: %p, ctx->state: 0x%x", ctx, ctx->state);
678 744
679 if ((ctx->state & FIMC_CTX_M2M) && ctx->m2m_ctx) { 745 if (ctx->m2m_ctx)
680 v4l2_m2m_buf_queue(ctx->m2m_ctx, vq, vb); 746 v4l2_m2m_buf_queue(ctx->m2m_ctx, vb);
681 } else if (ctx->state & FIMC_CTX_CAP) { 747}
682 spin_lock_irqsave(&fimc->slock, flags);
683 fimc_vid_cap_buf_queue(fimc, (struct fimc_vid_buffer *)vb);
684 748
685 dbg("fimc->cap.active_buf_cnt: %d", 749static void fimc_lock(struct vb2_queue *vq)
686 fimc->vid_cap.active_buf_cnt); 750{
751 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
752 mutex_lock(&ctx->fimc_dev->lock);
753}
687 754
688 if (cap->active_buf_cnt >= cap->reqbufs_count || 755static void fimc_unlock(struct vb2_queue *vq)
689 cap->active_buf_cnt >= FIMC_MAX_OUT_BUFS) { 756{
690 if (!test_and_set_bit(ST_CAPT_STREAM, &fimc->state)) 757 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
691 fimc_activate_capture(ctx); 758 mutex_unlock(&ctx->fimc_dev->lock);
692 }
693 spin_unlock_irqrestore(&fimc->slock, flags);
694 }
695} 759}
696 760
697struct videobuf_queue_ops fimc_qops = { 761struct vb2_ops fimc_qops = {
698 .buf_setup = fimc_buf_setup, 762 .queue_setup = fimc_queue_setup,
699 .buf_prepare = fimc_buf_prepare, 763 .buf_prepare = fimc_buf_prepare,
700 .buf_queue = fimc_buf_queue, 764 .buf_queue = fimc_buf_queue,
701 .buf_release = fimc_buf_release, 765 .wait_prepare = fimc_unlock,
766 .wait_finish = fimc_lock,
767 .stop_streaming = stop_streaming,
702}; 768};
703 769
704static int fimc_m2m_querycap(struct file *file, void *priv, 770static int fimc_m2m_querycap(struct file *file, void *priv,
@@ -712,12 +778,13 @@ static int fimc_m2m_querycap(struct file *file, void *priv,
712 cap->bus_info[0] = 0; 778 cap->bus_info[0] = 0;
713 cap->version = KERNEL_VERSION(1, 0, 0); 779 cap->version = KERNEL_VERSION(1, 0, 0);
714 cap->capabilities = V4L2_CAP_STREAMING | 780 cap->capabilities = V4L2_CAP_STREAMING |
715 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT; 781 V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_VIDEO_OUTPUT |
782 V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE;
716 783
717 return 0; 784 return 0;
718} 785}
719 786
720int fimc_vidioc_enum_fmt(struct file *file, void *priv, 787int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
721 struct v4l2_fmtdesc *f) 788 struct v4l2_fmtdesc *f)
722{ 789{
723 struct fimc_fmt *fmt; 790 struct fimc_fmt *fmt;
@@ -732,25 +799,39 @@ int fimc_vidioc_enum_fmt(struct file *file, void *priv,
732 return 0; 799 return 0;
733} 800}
734 801
735int fimc_vidioc_g_fmt(struct file *file, void *priv, struct v4l2_format *f) 802int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv,
803 struct v4l2_format *f)
736{ 804{
737 struct fimc_ctx *ctx = priv; 805 struct fimc_ctx *ctx = priv;
738 struct fimc_dev *fimc = ctx->fimc_dev;
739 struct fimc_frame *frame; 806 struct fimc_frame *frame;
807 struct v4l2_pix_format_mplane *pixm;
808 int i;
740 809
741 frame = ctx_get_frame(ctx, f->type); 810 frame = ctx_get_frame(ctx, f->type);
742 if (IS_ERR(frame)) 811 if (IS_ERR(frame))
743 return PTR_ERR(frame); 812 return PTR_ERR(frame);
744 813
745 if (mutex_lock_interruptible(&fimc->lock)) 814 pixm = &f->fmt.pix_mp;
746 return -ERESTARTSYS; 815
816 pixm->width = frame->width;
817 pixm->height = frame->height;
818 pixm->field = V4L2_FIELD_NONE;
819 pixm->pixelformat = frame->fmt->fourcc;
820 pixm->colorspace = V4L2_COLORSPACE_JPEG;
821 pixm->num_planes = frame->fmt->memplanes;
822
823 for (i = 0; i < pixm->num_planes; ++i) {
824 int bpl = frame->o_width;
747 825
748 f->fmt.pix.width = frame->width; 826 if (frame->fmt->colplanes == 1) /* packed formats */
749 f->fmt.pix.height = frame->height; 827 bpl = (bpl * frame->fmt->depth[0]) / 8;
750 f->fmt.pix.field = V4L2_FIELD_NONE; 828
751 f->fmt.pix.pixelformat = frame->fmt->fourcc; 829 pixm->plane_fmt[i].bytesperline = bpl;
830
831 pixm->plane_fmt[i].sizeimage = (frame->o_width *
832 frame->o_height * frame->fmt->depth[i]) / 8;
833 }
752 834
753 mutex_unlock(&fimc->lock);
754 return 0; 835 return 0;
755} 836}
756 837
@@ -785,42 +866,40 @@ struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
785} 866}
786 867
787 868
788int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f) 869int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
870 struct v4l2_format *f)
789{ 871{
790 struct fimc_ctx *ctx = priv; 872 struct fimc_ctx *ctx = priv;
791 struct fimc_dev *fimc = ctx->fimc_dev; 873 struct fimc_dev *fimc = ctx->fimc_dev;
792 struct samsung_fimc_variant *variant = fimc->variant; 874 struct samsung_fimc_variant *variant = fimc->variant;
793 struct v4l2_pix_format *pix = &f->fmt.pix; 875 struct v4l2_pix_format_mplane *pix = &f->fmt.pix_mp;
794 struct fimc_fmt *fmt; 876 struct fimc_fmt *fmt;
795 u32 max_width, mod_x, mod_y, mask; 877 u32 max_width, mod_x, mod_y, mask;
796 int ret = -EINVAL, is_output = 0; 878 int i, is_output = 0;
879
797 880
798 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 881 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
799 if (ctx->state & FIMC_CTX_CAP) 882 if (fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx))
800 return -EINVAL; 883 return -EINVAL;
801 is_output = 1; 884 is_output = 1;
802 } else if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { 885 } else if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
803 return -EINVAL; 886 return -EINVAL;
804 } 887 }
805 888
806 dbg("w: %d, h: %d, bpl: %d", 889 dbg("w: %d, h: %d", pix->width, pix->height);
807 pix->width, pix->height, pix->bytesperline);
808
809 if (mutex_lock_interruptible(&fimc->lock))
810 return -ERESTARTSYS;
811 890
812 mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM; 891 mask = is_output ? FMT_FLAGS_M2M : FMT_FLAGS_M2M | FMT_FLAGS_CAM;
813 fmt = find_format(f, mask); 892 fmt = find_format(f, mask);
814 if (!fmt) { 893 if (!fmt) {
815 v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n", 894 v4l2_err(&fimc->m2m.v4l2_dev, "Fourcc format (0x%X) invalid.\n",
816 pix->pixelformat); 895 pix->pixelformat);
817 goto tf_out; 896 return -EINVAL;
818 } 897 }
819 898
820 if (pix->field == V4L2_FIELD_ANY) 899 if (pix->field == V4L2_FIELD_ANY)
821 pix->field = V4L2_FIELD_NONE; 900 pix->field = V4L2_FIELD_NONE;
822 else if (V4L2_FIELD_NONE != pix->field) 901 else if (V4L2_FIELD_NONE != pix->field)
823 goto tf_out; 902 return -EINVAL;
824 903
825 if (is_output) { 904 if (is_output) {
826 max_width = variant->pix_limit->scaler_dis_w; 905 max_width = variant->pix_limit->scaler_dis_w;
@@ -834,7 +913,7 @@ int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
834 mod_x = 6; /* 64 x 32 pixels tile */ 913 mod_x = 6; /* 64 x 32 pixels tile */
835 mod_y = 5; 914 mod_y = 5;
836 } else { 915 } else {
837 if (fimc->id == 1 && fimc->variant->pix_hoff) 916 if (fimc->id == 1 && variant->pix_hoff)
838 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1; 917 mod_y = fimc_fmt_is_rgb(fmt->color) ? 0 : 1;
839 else 918 else
840 mod_y = mod_x; 919 mod_y = mod_x;
@@ -845,74 +924,72 @@ int fimc_vidioc_try_fmt(struct file *file, void *priv, struct v4l2_format *f)
845 v4l_bound_align_image(&pix->width, 16, max_width, mod_x, 924 v4l_bound_align_image(&pix->width, 16, max_width, mod_x,
846 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0); 925 &pix->height, 8, variant->pix_limit->scaler_dis_w, mod_y, 0);
847 926
848 if (pix->bytesperline == 0 || 927 pix->num_planes = fmt->memplanes;
849 (pix->bytesperline * 8 / fmt->depth) > pix->width) 928 pix->colorspace = V4L2_COLORSPACE_JPEG;
850 pix->bytesperline = (pix->width * fmt->depth) >> 3;
851 929
852 if (pix->sizeimage == 0) 930 for (i = 0; i < pix->num_planes; ++i) {
853 pix->sizeimage = pix->height * pix->bytesperline; 931 int bpl = pix->plane_fmt[i].bytesperline;
854 932
855 dbg("w: %d, h: %d, bpl: %d, depth: %d", 933 dbg("[%d] bpl: %d, depth: %d, w: %d, h: %d",
856 pix->width, pix->height, pix->bytesperline, fmt->depth); 934 i, bpl, fmt->depth[i], pix->width, pix->height);
857 935
858 ret = 0; 936 if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width)
937 bpl = (pix->width * fmt->depth[0]) >> 3;
859 938
860tf_out: 939 if (!pix->plane_fmt[i].sizeimage)
861 mutex_unlock(&fimc->lock); 940 pix->plane_fmt[i].sizeimage = pix->height * bpl;
862 return ret; 941
942 pix->plane_fmt[i].bytesperline = bpl;
943
944 dbg("[%d]: bpl: %d, sizeimage: %d",
945 i, pix->plane_fmt[i].bytesperline,
946 pix->plane_fmt[i].sizeimage);
947 }
948
949 return 0;
863} 950}
864 951
865static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f) 952static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
953 struct v4l2_format *f)
866{ 954{
867 struct fimc_ctx *ctx = priv; 955 struct fimc_ctx *ctx = priv;
868 struct fimc_dev *fimc = ctx->fimc_dev; 956 struct fimc_dev *fimc = ctx->fimc_dev;
869 struct v4l2_device *v4l2_dev = &fimc->m2m.v4l2_dev; 957 struct vb2_queue *vq;
870 struct videobuf_queue *vq;
871 struct fimc_frame *frame; 958 struct fimc_frame *frame;
872 struct v4l2_pix_format *pix; 959 struct v4l2_pix_format_mplane *pix;
873 unsigned long flags; 960 int i, ret = 0;
874 int ret = 0;
875 961
876 ret = fimc_vidioc_try_fmt(file, priv, f); 962 ret = fimc_vidioc_try_fmt_mplane(file, priv, f);
877 if (ret) 963 if (ret)
878 return ret; 964 return ret;
879 965
880 if (mutex_lock_interruptible(&fimc->lock))
881 return -ERESTARTSYS;
882
883 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type); 966 vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
884 mutex_lock(&vq->vb_lock);
885 967
886 if (videobuf_queue_is_busy(vq)) { 968 if (vb2_is_streaming(vq)) {
887 v4l2_err(v4l2_dev, "%s: queue (%d) busy\n", __func__, f->type); 969 v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type);
888 ret = -EBUSY; 970 return -EBUSY;
889 goto sf_out;
890 } 971 }
891 972
892 spin_lock_irqsave(&ctx->slock, flags); 973 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
893 if (f->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
894 frame = &ctx->s_frame; 974 frame = &ctx->s_frame;
895 ctx->state |= FIMC_SRC_FMT; 975 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) {
896 } else if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
897 frame = &ctx->d_frame; 976 frame = &ctx->d_frame;
898 ctx->state |= FIMC_DST_FMT;
899 } else { 977 } else {
900 spin_unlock_irqrestore(&ctx->slock, flags); 978 v4l2_err(&fimc->m2m.v4l2_dev,
901 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
902 "Wrong buffer/video queue type (%d)\n", f->type); 979 "Wrong buffer/video queue type (%d)\n", f->type);
903 ret = -EINVAL; 980 return -EINVAL;
904 goto sf_out;
905 } 981 }
906 spin_unlock_irqrestore(&ctx->slock, flags);
907 982
908 pix = &f->fmt.pix; 983 pix = &f->fmt.pix_mp;
909 frame->fmt = find_format(f, FMT_FLAGS_M2M); 984 frame->fmt = find_format(f, FMT_FLAGS_M2M);
910 if (!frame->fmt) { 985 if (!frame->fmt)
911 ret = -EINVAL; 986 return -EINVAL;
912 goto sf_out;
913 }
914 987
915 frame->f_width = pix->bytesperline * 8 / frame->fmt->depth; 988 for (i = 0; i < frame->fmt->colplanes; i++)
989 frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
990
991 frame->f_width = pix->plane_fmt[0].bytesperline * 8 /
992 frame->fmt->depth[0];
916 frame->f_height = pix->height; 993 frame->f_height = pix->height;
917 frame->width = pix->width; 994 frame->width = pix->width;
918 frame->height = pix->height; 995 frame->height = pix->height;
@@ -920,19 +997,15 @@ static int fimc_m2m_s_fmt(struct file *file, void *priv, struct v4l2_format *f)
920 frame->o_height = pix->height; 997 frame->o_height = pix->height;
921 frame->offs_h = 0; 998 frame->offs_h = 0;
922 frame->offs_v = 0; 999 frame->offs_v = 0;
923 frame->size = (pix->width * pix->height * frame->fmt->depth) >> 3;
924 vq->field = pix->field;
925 1000
926 spin_lock_irqsave(&ctx->slock, flags); 1001 if (f->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
927 ctx->state |= FIMC_PARAMS; 1002 fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_DST_FMT, ctx);
928 spin_unlock_irqrestore(&ctx->slock, flags); 1003 else
1004 fimc_ctx_state_lock_set(FIMC_PARAMS | FIMC_SRC_FMT, ctx);
929 1005
930 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height); 1006 dbg("f_w: %d, f_h: %d", frame->f_width, frame->f_height);
931 1007
932sf_out: 1008 return 0;
933 mutex_unlock(&vq->vb_lock);
934 mutex_unlock(&fimc->lock);
935 return ret;
936} 1009}
937 1010
938static int fimc_m2m_reqbufs(struct file *file, void *priv, 1011static int fimc_m2m_reqbufs(struct file *file, void *priv,
@@ -968,6 +1041,15 @@ static int fimc_m2m_streamon(struct file *file, void *priv,
968 enum v4l2_buf_type type) 1041 enum v4l2_buf_type type)
969{ 1042{
970 struct fimc_ctx *ctx = priv; 1043 struct fimc_ctx *ctx = priv;
1044
1045 /* The source and target color format need to be set */
1046 if (V4L2_TYPE_IS_OUTPUT(type)) {
1047 if (!fimc_ctx_state_is_set(FIMC_SRC_FMT, ctx))
1048 return -EINVAL;
1049 } else if (!fimc_ctx_state_is_set(FIMC_DST_FMT, ctx)) {
1050 return -EINVAL;
1051 }
1052
971 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type); 1053 return v4l2_m2m_streamon(file, ctx->m2m_ctx, type);
972} 1054}
973 1055
@@ -991,12 +1073,9 @@ int fimc_vidioc_queryctrl(struct file *file, void *priv,
991 return 0; 1073 return 0;
992 } 1074 }
993 1075
994 if (ctx->state & FIMC_CTX_CAP) { 1076 if (fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx)) {
995 if (mutex_lock_interruptible(&ctx->fimc_dev->lock)) 1077 return v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
996 return -ERESTARTSYS;
997 ret = v4l2_subdev_call(ctx->fimc_dev->vid_cap.sd,
998 core, queryctrl, qc); 1078 core, queryctrl, qc);
999 mutex_unlock(&ctx->fimc_dev->lock);
1000 } 1079 }
1001 return ret; 1080 return ret;
1002} 1081}
@@ -1006,10 +1085,6 @@ int fimc_vidioc_g_ctrl(struct file *file, void *priv,
1006{ 1085{
1007 struct fimc_ctx *ctx = priv; 1086 struct fimc_ctx *ctx = priv;
1008 struct fimc_dev *fimc = ctx->fimc_dev; 1087 struct fimc_dev *fimc = ctx->fimc_dev;
1009 int ret = 0;
1010
1011 if (mutex_lock_interruptible(&fimc->lock))
1012 return -ERESTARTSYS;
1013 1088
1014 switch (ctrl->id) { 1089 switch (ctrl->id) {
1015 case V4L2_CID_HFLIP: 1090 case V4L2_CID_HFLIP:
@@ -1022,19 +1097,17 @@ int fimc_vidioc_g_ctrl(struct file *file, void *priv,
1022 ctrl->value = ctx->rotation; 1097 ctrl->value = ctx->rotation;
1023 break; 1098 break;
1024 default: 1099 default:
1025 if (ctx->state & FIMC_CTX_CAP) { 1100 if (fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx)) {
1026 ret = v4l2_subdev_call(fimc->vid_cap.sd, core, 1101 return v4l2_subdev_call(fimc->vid_cap.sd, core,
1027 g_ctrl, ctrl); 1102 g_ctrl, ctrl);
1028 } else { 1103 } else {
1029 v4l2_err(&fimc->m2m.v4l2_dev, 1104 v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n");
1030 "Invalid control\n"); 1105 return -EINVAL;
1031 ret = -EINVAL;
1032 } 1106 }
1033 } 1107 }
1034 dbg("ctrl->value= %d", ctrl->value); 1108 dbg("ctrl->value= %d", ctrl->value);
1035 1109
1036 mutex_unlock(&fimc->lock); 1110 return 0;
1037 return ret;
1038} 1111}
1039 1112
1040int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl) 1113int check_ctrl_val(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
@@ -1058,16 +1131,7 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1058{ 1131{
1059 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant; 1132 struct samsung_fimc_variant *variant = ctx->fimc_dev->variant;
1060 struct fimc_dev *fimc = ctx->fimc_dev; 1133 struct fimc_dev *fimc = ctx->fimc_dev;
1061 unsigned long flags; 1134 int ret = 0;
1062
1063 if (ctx->rotation != 0 &&
1064 (ctrl->id == V4L2_CID_HFLIP || ctrl->id == V4L2_CID_VFLIP)) {
1065 v4l2_err(&fimc->m2m.v4l2_dev,
1066 "Simultaneous flip and rotation is not supported\n");
1067 return -EINVAL;
1068 }
1069
1070 spin_lock_irqsave(&ctx->slock, flags);
1071 1135
1072 switch (ctrl->id) { 1136 switch (ctrl->id) {
1073 case V4L2_CID_HFLIP: 1137 case V4L2_CID_HFLIP:
@@ -1085,29 +1149,36 @@ int fimc_s_ctrl(struct fimc_ctx *ctx, struct v4l2_control *ctrl)
1085 break; 1149 break;
1086 1150
1087 case V4L2_CID_ROTATE: 1151 case V4L2_CID_ROTATE:
1152 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
1153 ret = fimc_check_scaler_ratio(ctx->s_frame.width,
1154 ctx->s_frame.height, ctx->d_frame.width,
1155 ctx->d_frame.height, ctrl->value);
1156 }
1157
1158 if (ret) {
1159 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range\n");
1160 return -EINVAL;
1161 }
1162
1088 /* Check for the output rotator availability */ 1163 /* Check for the output rotator availability */
1089 if ((ctrl->value == 90 || ctrl->value == 270) && 1164 if ((ctrl->value == 90 || ctrl->value == 270) &&
1090 (ctx->in_path == FIMC_DMA && !variant->has_out_rot)) { 1165 (ctx->in_path == FIMC_DMA && !variant->has_out_rot))
1091 spin_unlock_irqrestore(&ctx->slock, flags);
1092 return -EINVAL; 1166 return -EINVAL;
1093 } else { 1167 ctx->rotation = ctrl->value;
1094 ctx->rotation = ctrl->value;
1095 }
1096 break; 1168 break;
1097 1169
1098 default: 1170 default:
1099 spin_unlock_irqrestore(&ctx->slock, flags);
1100 v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n"); 1171 v4l2_err(&fimc->m2m.v4l2_dev, "Invalid control\n");
1101 return -EINVAL; 1172 return -EINVAL;
1102 } 1173 }
1103 ctx->state |= FIMC_PARAMS; 1174
1104 spin_unlock_irqrestore(&ctx->slock, flags); 1175 fimc_ctx_state_lock_set(FIMC_PARAMS, ctx);
1105 1176
1106 return 0; 1177 return 0;
1107} 1178}
1108 1179
1109static int fimc_m2m_s_ctrl(struct file *file, void *priv, 1180static int fimc_m2m_s_ctrl(struct file *file, void *priv,
1110 struct v4l2_control *ctrl) 1181 struct v4l2_control *ctrl)
1111{ 1182{
1112 struct fimc_ctx *ctx = priv; 1183 struct fimc_ctx *ctx = priv;
1113 int ret = 0; 1184 int ret = 0;
@@ -1125,22 +1196,17 @@ static int fimc_m2m_cropcap(struct file *file, void *fh,
1125{ 1196{
1126 struct fimc_frame *frame; 1197 struct fimc_frame *frame;
1127 struct fimc_ctx *ctx = fh; 1198 struct fimc_ctx *ctx = fh;
1128 struct fimc_dev *fimc = ctx->fimc_dev;
1129 1199
1130 frame = ctx_get_frame(ctx, cr->type); 1200 frame = ctx_get_frame(ctx, cr->type);
1131 if (IS_ERR(frame)) 1201 if (IS_ERR(frame))
1132 return PTR_ERR(frame); 1202 return PTR_ERR(frame);
1133 1203
1134 if (mutex_lock_interruptible(&fimc->lock))
1135 return -ERESTARTSYS;
1136
1137 cr->bounds.left = 0; 1204 cr->bounds.left = 0;
1138 cr->bounds.top = 0; 1205 cr->bounds.top = 0;
1139 cr->bounds.width = frame->f_width; 1206 cr->bounds.width = frame->f_width;
1140 cr->bounds.height = frame->f_height; 1207 cr->bounds.height = frame->f_height;
1141 cr->defrect = cr->bounds; 1208 cr->defrect = cr->bounds;
1142 1209
1143 mutex_unlock(&fimc->lock);
1144 return 0; 1210 return 0;
1145} 1211}
1146 1212
@@ -1148,21 +1214,16 @@ static int fimc_m2m_g_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1148{ 1214{
1149 struct fimc_frame *frame; 1215 struct fimc_frame *frame;
1150 struct fimc_ctx *ctx = file->private_data; 1216 struct fimc_ctx *ctx = file->private_data;
1151 struct fimc_dev *fimc = ctx->fimc_dev;
1152 1217
1153 frame = ctx_get_frame(ctx, cr->type); 1218 frame = ctx_get_frame(ctx, cr->type);
1154 if (IS_ERR(frame)) 1219 if (IS_ERR(frame))
1155 return PTR_ERR(frame); 1220 return PTR_ERR(frame);
1156 1221
1157 if (mutex_lock_interruptible(&fimc->lock))
1158 return -ERESTARTSYS;
1159
1160 cr->c.left = frame->offs_h; 1222 cr->c.left = frame->offs_h;
1161 cr->c.top = frame->offs_v; 1223 cr->c.top = frame->offs_v;
1162 cr->c.width = frame->width; 1224 cr->c.width = frame->width;
1163 cr->c.height = frame->height; 1225 cr->c.height = frame->height;
1164 1226
1165 mutex_unlock(&fimc->lock);
1166 return 0; 1227 return 0;
1167} 1228}
1168 1229
@@ -1170,7 +1231,9 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1170{ 1231{
1171 struct fimc_dev *fimc = ctx->fimc_dev; 1232 struct fimc_dev *fimc = ctx->fimc_dev;
1172 struct fimc_frame *f; 1233 struct fimc_frame *f;
1173 u32 min_size, halign; 1234 u32 min_size, halign, depth = 0;
1235 bool is_capture_ctx;
1236 int i;
1174 1237
1175 if (cr->c.top < 0 || cr->c.left < 0) { 1238 if (cr->c.top < 0 || cr->c.left < 0) {
1176 v4l2_err(&fimc->m2m.v4l2_dev, 1239 v4l2_err(&fimc->m2m.v4l2_dev,
@@ -1178,10 +1241,12 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1178 return -EINVAL; 1241 return -EINVAL;
1179 } 1242 }
1180 1243
1181 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) 1244 is_capture_ctx = fimc_ctx_state_is_set(FIMC_CTX_CAP, ctx);
1182 f = (ctx->state & FIMC_CTX_CAP) ? &ctx->s_frame : &ctx->d_frame; 1245
1183 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 1246 if (cr->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
1184 ctx->state & FIMC_CTX_M2M) 1247 f = is_capture_ctx ? &ctx->s_frame : &ctx->d_frame;
1248 else if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE &&
1249 !is_capture_ctx)
1185 f = &ctx->s_frame; 1250 f = &ctx->s_frame;
1186 else 1251 else
1187 return -EINVAL; 1252 return -EINVAL;
@@ -1189,21 +1254,24 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1189 min_size = (f == &ctx->s_frame) ? 1254 min_size = (f == &ctx->s_frame) ?
1190 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize; 1255 fimc->variant->min_inp_pixsize : fimc->variant->min_out_pixsize;
1191 1256
1192 if (ctx->state & FIMC_CTX_M2M) { 1257 /* Get pixel alignment constraints. */
1258 if (is_capture_ctx) {
1259 min_size = 16;
1260 halign = 4;
1261 } else {
1193 if (fimc->id == 1 && fimc->variant->pix_hoff) 1262 if (fimc->id == 1 && fimc->variant->pix_hoff)
1194 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1; 1263 halign = fimc_fmt_is_rgb(f->fmt->color) ? 0 : 1;
1195 else 1264 else
1196 halign = ffs(min_size) - 1; 1265 halign = ffs(min_size) - 1;
1197 /* there are more strict aligment requirements at camera interface */
1198 } else {
1199 min_size = 16;
1200 halign = 4;
1201 } 1266 }
1202 1267
1268 for (i = 0; i < f->fmt->colplanes; i++)
1269 depth += f->fmt->depth[i];
1270
1203 v4l_bound_align_image(&cr->c.width, min_size, f->o_width, 1271 v4l_bound_align_image(&cr->c.width, min_size, f->o_width,
1204 ffs(min_size) - 1, 1272 ffs(min_size) - 1,
1205 &cr->c.height, min_size, f->o_height, 1273 &cr->c.height, min_size, f->o_height,
1206 halign, 64/(ALIGN(f->fmt->depth, 8))); 1274 halign, 64/(ALIGN(depth, 8)));
1207 1275
1208 /* adjust left/top if cropping rectangle is out of bounds */ 1276 /* adjust left/top if cropping rectangle is out of bounds */
1209 if (cr->c.left + cr->c.width > f->o_width) 1277 if (cr->c.left + cr->c.width > f->o_width)
@@ -1212,8 +1280,7 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1212 cr->c.top = f->o_height - cr->c.height; 1280 cr->c.top = f->o_height - cr->c.height;
1213 1281
1214 cr->c.left = round_down(cr->c.left, min_size); 1282 cr->c.left = round_down(cr->c.left, min_size);
1215 cr->c.top = round_down(cr->c.top, 1283 cr->c.top = round_down(cr->c.top, is_capture_ctx ? 16 : 8);
1216 ctx->state & FIMC_CTX_M2M ? 8 : 16);
1217 1284
1218 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d", 1285 dbg("l:%d, t:%d, w:%d, h:%d, f_w: %d, f_h: %d",
1219 cr->c.left, cr->c.top, cr->c.width, cr->c.height, 1286 cr->c.left, cr->c.top, cr->c.width, cr->c.height,
@@ -1222,12 +1289,10 @@ int fimc_try_crop(struct fimc_ctx *ctx, struct v4l2_crop *cr)
1222 return 0; 1289 return 0;
1223} 1290}
1224 1291
1225
1226static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr) 1292static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1227{ 1293{
1228 struct fimc_ctx *ctx = file->private_data; 1294 struct fimc_ctx *ctx = file->private_data;
1229 struct fimc_dev *fimc = ctx->fimc_dev; 1295 struct fimc_dev *fimc = ctx->fimc_dev;
1230 unsigned long flags;
1231 struct fimc_frame *f; 1296 struct fimc_frame *f;
1232 int ret; 1297 int ret;
1233 1298
@@ -1235,52 +1300,52 @@ static int fimc_m2m_s_crop(struct file *file, void *fh, struct v4l2_crop *cr)
1235 if (ret) 1300 if (ret)
1236 return ret; 1301 return ret;
1237 1302
1238 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) ? 1303 f = (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) ?
1239 &ctx->s_frame : &ctx->d_frame; 1304 &ctx->s_frame : &ctx->d_frame;
1240 1305
1241 if (mutex_lock_interruptible(&fimc->lock)) 1306 /* Check to see if scaling ratio is within supported range */
1242 return -ERESTARTSYS; 1307 if (fimc_ctx_state_is_set(FIMC_DST_FMT | FIMC_SRC_FMT, ctx)) {
1243 1308 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE) {
1244 spin_lock_irqsave(&ctx->slock, flags); 1309 ret = fimc_check_scaler_ratio(cr->c.width, cr->c.height,
1245 if (~ctx->state & (FIMC_SRC_FMT | FIMC_DST_FMT)) { 1310 ctx->d_frame.width,
1246 /* Check to see if scaling ratio is within supported range */ 1311 ctx->d_frame.height,
1247 if (cr->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) 1312 ctx->rotation);
1248 ret = fimc_check_scaler_ratio(&cr->c, &ctx->d_frame); 1313 } else {
1249 else 1314 ret = fimc_check_scaler_ratio(ctx->s_frame.width,
1250 ret = fimc_check_scaler_ratio(&cr->c, &ctx->s_frame); 1315 ctx->s_frame.height,
1316 cr->c.width, cr->c.height,
1317 ctx->rotation);
1318 }
1251 if (ret) { 1319 if (ret) {
1252 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range"); 1320 v4l2_err(&fimc->m2m.v4l2_dev, "Out of scaler range\n");
1253 ret = -EINVAL; 1321 return -EINVAL;
1254 goto scr_unlock;
1255 } 1322 }
1256 } 1323 }
1257 ctx->state |= FIMC_PARAMS;
1258 1324
1259 f->offs_h = cr->c.left; 1325 f->offs_h = cr->c.left;
1260 f->offs_v = cr->c.top; 1326 f->offs_v = cr->c.top;
1261 f->width = cr->c.width; 1327 f->width = cr->c.width;
1262 f->height = cr->c.height; 1328 f->height = cr->c.height;
1263 1329
1264scr_unlock: 1330 fimc_ctx_state_lock_set(FIMC_PARAMS, ctx);
1265 spin_unlock_irqrestore(&ctx->slock, flags); 1331
1266 mutex_unlock(&fimc->lock);
1267 return 0; 1332 return 0;
1268} 1333}
1269 1334
1270static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = { 1335static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
1271 .vidioc_querycap = fimc_m2m_querycap, 1336 .vidioc_querycap = fimc_m2m_querycap,
1272 1337
1273 .vidioc_enum_fmt_vid_cap = fimc_vidioc_enum_fmt, 1338 .vidioc_enum_fmt_vid_cap_mplane = fimc_vidioc_enum_fmt_mplane,
1274 .vidioc_enum_fmt_vid_out = fimc_vidioc_enum_fmt, 1339 .vidioc_enum_fmt_vid_out_mplane = fimc_vidioc_enum_fmt_mplane,
1275 1340
1276 .vidioc_g_fmt_vid_cap = fimc_vidioc_g_fmt, 1341 .vidioc_g_fmt_vid_cap_mplane = fimc_vidioc_g_fmt_mplane,
1277 .vidioc_g_fmt_vid_out = fimc_vidioc_g_fmt, 1342 .vidioc_g_fmt_vid_out_mplane = fimc_vidioc_g_fmt_mplane,
1278 1343
1279 .vidioc_try_fmt_vid_cap = fimc_vidioc_try_fmt, 1344 .vidioc_try_fmt_vid_cap_mplane = fimc_vidioc_try_fmt_mplane,
1280 .vidioc_try_fmt_vid_out = fimc_vidioc_try_fmt, 1345 .vidioc_try_fmt_vid_out_mplane = fimc_vidioc_try_fmt_mplane,
1281 1346
1282 .vidioc_s_fmt_vid_cap = fimc_m2m_s_fmt, 1347 .vidioc_s_fmt_vid_cap_mplane = fimc_m2m_s_fmt_mplane,
1283 .vidioc_s_fmt_vid_out = fimc_m2m_s_fmt, 1348 .vidioc_s_fmt_vid_out_mplane = fimc_m2m_s_fmt_mplane,
1284 1349
1285 .vidioc_reqbufs = fimc_m2m_reqbufs, 1350 .vidioc_reqbufs = fimc_m2m_reqbufs,
1286 .vidioc_querybuf = fimc_m2m_querybuf, 1351 .vidioc_querybuf = fimc_m2m_querybuf,
@@ -1301,26 +1366,39 @@ static const struct v4l2_ioctl_ops fimc_m2m_ioctl_ops = {
1301 1366
1302}; 1367};
1303 1368
1304static void queue_init(void *priv, struct videobuf_queue *vq, 1369static int queue_init(void *priv, struct vb2_queue *src_vq,
1305 enum v4l2_buf_type type) 1370 struct vb2_queue *dst_vq)
1306{ 1371{
1307 struct fimc_ctx *ctx = priv; 1372 struct fimc_ctx *ctx = priv;
1308 struct fimc_dev *fimc = ctx->fimc_dev; 1373 int ret;
1374
1375 memset(src_vq, 0, sizeof(*src_vq));
1376 src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
1377 src_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1378 src_vq->drv_priv = ctx;
1379 src_vq->ops = &fimc_qops;
1380 src_vq->mem_ops = &vb2_dma_contig_memops;
1381 src_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1382
1383 ret = vb2_queue_init(src_vq);
1384 if (ret)
1385 return ret;
1309 1386
1310 videobuf_queue_dma_contig_init(vq, &fimc_qops, 1387 memset(dst_vq, 0, sizeof(*dst_vq));
1311 &fimc->pdev->dev, 1388 dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
1312 &fimc->irqlock, type, V4L2_FIELD_NONE, 1389 dst_vq->io_modes = VB2_MMAP | VB2_USERPTR;
1313 sizeof(struct fimc_vid_buffer), priv, NULL); 1390 dst_vq->drv_priv = ctx;
1391 dst_vq->ops = &fimc_qops;
1392 dst_vq->mem_ops = &vb2_dma_contig_memops;
1393 dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer);
1394
1395 return vb2_queue_init(dst_vq);
1314} 1396}
1315 1397
1316static int fimc_m2m_open(struct file *file) 1398static int fimc_m2m_open(struct file *file)
1317{ 1399{
1318 struct fimc_dev *fimc = video_drvdata(file); 1400 struct fimc_dev *fimc = video_drvdata(file);
1319 struct fimc_ctx *ctx = NULL; 1401 struct fimc_ctx *ctx = NULL;
1320 int err = 0;
1321
1322 if (mutex_lock_interruptible(&fimc->lock))
1323 return -ERESTARTSYS;
1324 1402
1325 dbg("pid: %d, state: 0x%lx, refcnt: %d", 1403 dbg("pid: %d, state: 0x%lx, refcnt: %d",
1326 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt); 1404 task_pid_nr(current), fimc->state, fimc->vid_cap.refcnt);
@@ -1329,19 +1407,15 @@ static int fimc_m2m_open(struct file *file)
1329 * Return if the corresponding video capture node 1407 * Return if the corresponding video capture node
1330 * is already opened. 1408 * is already opened.
1331 */ 1409 */
1332 if (fimc->vid_cap.refcnt > 0) { 1410 if (fimc->vid_cap.refcnt > 0)
1333 err = -EBUSY; 1411 return -EBUSY;
1334 goto err_unlock;
1335 }
1336 1412
1337 fimc->m2m.refcnt++; 1413 fimc->m2m.refcnt++;
1338 set_bit(ST_OUTDMA_RUN, &fimc->state); 1414 set_bit(ST_OUTDMA_RUN, &fimc->state);
1339 1415
1340 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 1416 ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
1341 if (!ctx) { 1417 if (!ctx)
1342 err = -ENOMEM; 1418 return -ENOMEM;
1343 goto err_unlock;
1344 }
1345 1419
1346 file->private_data = ctx; 1420 file->private_data = ctx;
1347 ctx->fimc_dev = fimc; 1421 ctx->fimc_dev = fimc;
@@ -1355,15 +1429,14 @@ static int fimc_m2m_open(struct file *file)
1355 ctx->out_path = FIMC_DMA; 1429 ctx->out_path = FIMC_DMA;
1356 spin_lock_init(&ctx->slock); 1430 spin_lock_init(&ctx->slock);
1357 1431
1358 ctx->m2m_ctx = v4l2_m2m_ctx_init(ctx, fimc->m2m.m2m_dev, queue_init); 1432 ctx->m2m_ctx = v4l2_m2m_ctx_init(fimc->m2m.m2m_dev, ctx, queue_init);
1359 if (IS_ERR(ctx->m2m_ctx)) { 1433 if (IS_ERR(ctx->m2m_ctx)) {
1360 err = PTR_ERR(ctx->m2m_ctx); 1434 int err = PTR_ERR(ctx->m2m_ctx);
1361 kfree(ctx); 1435 kfree(ctx);
1436 return err;
1362 } 1437 }
1363 1438
1364err_unlock: 1439 return 0;
1365 mutex_unlock(&fimc->lock);
1366 return err;
1367} 1440}
1368 1441
1369static int fimc_m2m_release(struct file *file) 1442static int fimc_m2m_release(struct file *file)
@@ -1371,8 +1444,6 @@ static int fimc_m2m_release(struct file *file)
1371 struct fimc_ctx *ctx = file->private_data; 1444 struct fimc_ctx *ctx = file->private_data;
1372 struct fimc_dev *fimc = ctx->fimc_dev; 1445 struct fimc_dev *fimc = ctx->fimc_dev;
1373 1446
1374 mutex_lock(&fimc->lock);
1375
1376 dbg("pid: %d, state: 0x%lx, refcnt= %d", 1447 dbg("pid: %d, state: 0x%lx, refcnt= %d",
1377 task_pid_nr(current), fimc->state, fimc->m2m.refcnt); 1448 task_pid_nr(current), fimc->state, fimc->m2m.refcnt);
1378 1449
@@ -1381,7 +1452,6 @@ static int fimc_m2m_release(struct file *file)
1381 if (--fimc->m2m.refcnt <= 0) 1452 if (--fimc->m2m.refcnt <= 0)
1382 clear_bit(ST_OUTDMA_RUN, &fimc->state); 1453 clear_bit(ST_OUTDMA_RUN, &fimc->state);
1383 1454
1384 mutex_unlock(&fimc->lock);
1385 return 0; 1455 return 0;
1386} 1456}
1387 1457
@@ -1415,7 +1485,6 @@ static struct v4l2_m2m_ops m2m_ops = {
1415 .job_abort = fimc_job_abort, 1485 .job_abort = fimc_job_abort,
1416}; 1486};
1417 1487
1418
1419static int fimc_register_m2m_device(struct fimc_dev *fimc) 1488static int fimc_register_m2m_device(struct fimc_dev *fimc)
1420{ 1489{
1421 struct video_device *vfd; 1490 struct video_device *vfd;
@@ -1448,6 +1517,7 @@ static int fimc_register_m2m_device(struct fimc_dev *fimc)
1448 vfd->ioctl_ops = &fimc_m2m_ioctl_ops; 1517 vfd->ioctl_ops = &fimc_m2m_ioctl_ops;
1449 vfd->minor = -1; 1518 vfd->minor = -1;
1450 vfd->release = video_device_release; 1519 vfd->release = video_device_release;
1520 vfd->lock = &fimc->lock;
1451 1521
1452 snprintf(vfd->name, sizeof(vfd->name), "%s:m2m", dev_name(&pdev->dev)); 1522 snprintf(vfd->name, sizeof(vfd->name), "%s:m2m", dev_name(&pdev->dev));
1453 1523
@@ -1496,7 +1566,7 @@ static void fimc_unregister_m2m_device(struct fimc_dev *fimc)
1496static void fimc_clk_release(struct fimc_dev *fimc) 1566static void fimc_clk_release(struct fimc_dev *fimc)
1497{ 1567{
1498 int i; 1568 int i;
1499 for (i = 0; i < NUM_FIMC_CLOCKS; i++) { 1569 for (i = 0; i < fimc->num_clocks; i++) {
1500 if (fimc->clock[i]) { 1570 if (fimc->clock[i]) {
1501 clk_disable(fimc->clock[i]); 1571 clk_disable(fimc->clock[i]);
1502 clk_put(fimc->clock[i]); 1572 clk_put(fimc->clock[i]);
@@ -1507,15 +1577,16 @@ static void fimc_clk_release(struct fimc_dev *fimc)
1507static int fimc_clk_get(struct fimc_dev *fimc) 1577static int fimc_clk_get(struct fimc_dev *fimc)
1508{ 1578{
1509 int i; 1579 int i;
1510 for (i = 0; i < NUM_FIMC_CLOCKS; i++) { 1580 for (i = 0; i < fimc->num_clocks; i++) {
1511 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clock_name[i]); 1581 fimc->clock[i] = clk_get(&fimc->pdev->dev, fimc_clocks[i]);
1512 if (IS_ERR(fimc->clock[i])) { 1582
1513 dev_err(&fimc->pdev->dev, 1583 if (!IS_ERR_OR_NULL(fimc->clock[i])) {
1514 "failed to get fimc clock: %s\n", 1584 clk_enable(fimc->clock[i]);
1515 fimc_clock_name[i]); 1585 continue;
1516 return -ENXIO;
1517 } 1586 }
1518 clk_enable(fimc->clock[i]); 1587 dev_err(&fimc->pdev->dev, "failed to get fimc clock: %s\n",
1588 fimc_clocks[i]);
1589 return -ENXIO;
1519 } 1590 }
1520 return 0; 1591 return 0;
1521} 1592}
@@ -1525,7 +1596,9 @@ static int fimc_probe(struct platform_device *pdev)
1525 struct fimc_dev *fimc; 1596 struct fimc_dev *fimc;
1526 struct resource *res; 1597 struct resource *res;
1527 struct samsung_fimc_driverdata *drv_data; 1598 struct samsung_fimc_driverdata *drv_data;
1599 struct s5p_platform_fimc *pdata;
1528 int ret = 0; 1600 int ret = 0;
1601 int cap_input_index = -1;
1529 1602
1530 dev_dbg(&pdev->dev, "%s():\n", __func__); 1603 dev_dbg(&pdev->dev, "%s():\n", __func__);
1531 1604
@@ -1545,10 +1618,10 @@ static int fimc_probe(struct platform_device *pdev)
1545 fimc->id = pdev->id; 1618 fimc->id = pdev->id;
1546 fimc->variant = drv_data->variant[fimc->id]; 1619 fimc->variant = drv_data->variant[fimc->id];
1547 fimc->pdev = pdev; 1620 fimc->pdev = pdev;
1548 fimc->pdata = pdev->dev.platform_data; 1621 pdata = pdev->dev.platform_data;
1622 fimc->pdata = pdata;
1549 fimc->state = ST_IDLE; 1623 fimc->state = ST_IDLE;
1550 1624
1551 spin_lock_init(&fimc->irqlock);
1552 init_waitqueue_head(&fimc->irq_queue); 1625 init_waitqueue_head(&fimc->irq_queue);
1553 spin_lock_init(&fimc->slock); 1626 spin_lock_init(&fimc->slock);
1554 1627
@@ -1576,10 +1649,18 @@ static int fimc_probe(struct platform_device *pdev)
1576 goto err_req_region; 1649 goto err_req_region;
1577 } 1650 }
1578 1651
1652 fimc->num_clocks = MAX_FIMC_CLOCKS - 1;
1653
1654 /* Check if a video capture node needs to be registered. */
1655 if (pdata && pdata->num_clients > 0) {
1656 cap_input_index = 0;
1657 fimc->num_clocks++;
1658 }
1659
1579 ret = fimc_clk_get(fimc); 1660 ret = fimc_clk_get(fimc);
1580 if (ret) 1661 if (ret)
1581 goto err_regs_unmap; 1662 goto err_regs_unmap;
1582 clk_set_rate(fimc->clock[0], drv_data->lclk_frequency); 1663 clk_set_rate(fimc->clock[CLK_BUS], drv_data->lclk_frequency);
1583 1664
1584 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 1665 res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
1585 if (!res) { 1666 if (!res) {
@@ -1597,24 +1678,24 @@ static int fimc_probe(struct platform_device *pdev)
1597 goto err_clk; 1678 goto err_clk;
1598 } 1679 }
1599 1680
1681 /* Initialize contiguous memory allocator */
1682 fimc->alloc_ctx = vb2_dma_contig_init_ctx(&fimc->pdev->dev);
1683 if (IS_ERR(fimc->alloc_ctx)) {
1684 ret = PTR_ERR(fimc->alloc_ctx);
1685 goto err_irq;
1686 }
1687
1600 ret = fimc_register_m2m_device(fimc); 1688 ret = fimc_register_m2m_device(fimc);
1601 if (ret) 1689 if (ret)
1602 goto err_irq; 1690 goto err_irq;
1603 1691
1604 /* At least one camera sensor is required to register capture node */ 1692 /* At least one camera sensor is required to register capture node */
1605 if (fimc->pdata) { 1693 if (cap_input_index >= 0) {
1606 int i; 1694 ret = fimc_register_capture_device(fimc);
1607 for (i = 0; i < FIMC_MAX_CAMIF_CLIENTS; ++i) 1695 if (ret)
1608 if (fimc->pdata->isp_info[i]) 1696 goto err_m2m;
1609 break; 1697 clk_disable(fimc->clock[CLK_CAM]);
1610
1611 if (i < FIMC_MAX_CAMIF_CLIENTS) {
1612 ret = fimc_register_capture_device(fimc);
1613 if (ret)
1614 goto err_m2m;
1615 }
1616 } 1698 }
1617
1618 /* 1699 /*
1619 * Exclude the additional output DMA address registers by masking 1700 * Exclude the additional output DMA address registers by masking
1620 * them out on HW revisions that provide extended capabilites. 1701 * them out on HW revisions that provide extended capabilites.
@@ -1656,6 +1737,9 @@ static int __devexit fimc_remove(struct platform_device *pdev)
1656 fimc_unregister_capture_device(fimc); 1737 fimc_unregister_capture_device(fimc);
1657 1738
1658 fimc_clk_release(fimc); 1739 fimc_clk_release(fimc);
1740
1741 vb2_dma_contig_cleanup_ctx(fimc->alloc_ctx);
1742
1659 iounmap(fimc->regs); 1743 iounmap(fimc->regs);
1660 release_resource(fimc->regs_res); 1744 release_resource(fimc->regs_res);
1661 kfree(fimc->regs_res); 1745 kfree(fimc->regs_res);
@@ -1726,6 +1810,7 @@ static struct samsung_fimc_variant fimc1_variant_s5pv210 = {
1726 .pix_hoff = 1, 1810 .pix_hoff = 1,
1727 .has_inp_rot = 1, 1811 .has_inp_rot = 1,
1728 .has_out_rot = 1, 1812 .has_out_rot = 1,
1813 .has_mainscaler_ext = 1,
1729 .min_inp_pixsize = 16, 1814 .min_inp_pixsize = 16,
1730 .min_out_pixsize = 16, 1815 .min_out_pixsize = 16,
1731 .hor_offs_align = 1, 1816 .hor_offs_align = 1,
@@ -1747,6 +1832,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
1747 .has_inp_rot = 1, 1832 .has_inp_rot = 1,
1748 .has_out_rot = 1, 1833 .has_out_rot = 1,
1749 .has_cistatus2 = 1, 1834 .has_cistatus2 = 1,
1835 .has_mainscaler_ext = 1,
1750 .min_inp_pixsize = 16, 1836 .min_inp_pixsize = 16,
1751 .min_out_pixsize = 16, 1837 .min_out_pixsize = 16,
1752 .hor_offs_align = 1, 1838 .hor_offs_align = 1,
@@ -1757,6 +1843,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
1757static struct samsung_fimc_variant fimc2_variant_s5pv310 = { 1843static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
1758 .pix_hoff = 1, 1844 .pix_hoff = 1,
1759 .has_cistatus2 = 1, 1845 .has_cistatus2 = 1,
1846 .has_mainscaler_ext = 1,
1760 .min_inp_pixsize = 16, 1847 .min_inp_pixsize = 16,
1761 .min_out_pixsize = 16, 1848 .min_out_pixsize = 16,
1762 .hor_offs_align = 1, 1849 .hor_offs_align = 1,
diff --git a/drivers/media/video/s5p-fimc/fimc-core.h b/drivers/media/video/s5p-fimc/fimc-core.h
index 4f047d35f8ad..3beb1e5320ce 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.h
+++ b/drivers/media/video/s5p-fimc/fimc-core.h
@@ -14,29 +14,27 @@
14/*#define DEBUG*/ 14/*#define DEBUG*/
15 15
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/spinlock.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/videodev2.h> 19#include <linux/videodev2.h>
19#include <media/videobuf-core.h> 20#include <linux/io.h>
21#include <media/videobuf2-core.h>
20#include <media/v4l2-device.h> 22#include <media/v4l2-device.h>
21#include <media/v4l2-mem2mem.h> 23#include <media/v4l2-mem2mem.h>
22#include <media/v4l2-mediabus.h> 24#include <media/v4l2-mediabus.h>
23#include <media/s3c_fimc.h> 25#include <media/s5p_fimc.h>
24 26
25#include "regs-fimc.h" 27#include "regs-fimc.h"
26 28
27#define err(fmt, args...) \ 29#define err(fmt, args...) \
28 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args) 30 printk(KERN_ERR "%s:%d: " fmt "\n", __func__, __LINE__, ##args)
29 31
30#ifdef DEBUG
31#define dbg(fmt, args...) \ 32#define dbg(fmt, args...) \
32 printk(KERN_DEBUG "%s:%d: " fmt "\n", __func__, __LINE__, ##args) 33 pr_debug("%s:%d: " fmt "\n", __func__, __LINE__, ##args)
33#else
34#define dbg(fmt, args...)
35#endif
36 34
37/* Time to wait for next frame VSYNC interrupt while stopping operation. */ 35/* Time to wait for next frame VSYNC interrupt while stopping operation. */
38#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000) 36#define FIMC_SHUTDOWN_TIMEOUT ((100*HZ)/1000)
39#define NUM_FIMC_CLOCKS 2 37#define MAX_FIMC_CLOCKS 3
40#define MODULE_NAME "s5p-fimc" 38#define MODULE_NAME "s5p-fimc"
41#define FIMC_MAX_DEVS 4 39#define FIMC_MAX_DEVS 4
42#define FIMC_MAX_OUT_BUFS 4 40#define FIMC_MAX_OUT_BUFS 4
@@ -44,7 +42,13 @@
44#define SCALER_MAX_VRATIO 64 42#define SCALER_MAX_VRATIO 64
45#define DMA_MIN_SIZE 8 43#define DMA_MIN_SIZE 8
46 44
47/* FIMC device state flags */ 45/* indices to the clocks array */
46enum {
47 CLK_BUS,
48 CLK_GATE,
49 CLK_CAM,
50};
51
48enum fimc_dev_flags { 52enum fimc_dev_flags {
49 /* for m2m node */ 53 /* for m2m node */
50 ST_IDLE, 54 ST_IDLE,
@@ -63,20 +67,6 @@ enum fimc_dev_flags {
63#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state) 67#define fimc_capture_running(dev) test_bit(ST_CAPT_RUN, &(dev)->state)
64#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state) 68#define fimc_capture_pending(dev) test_bit(ST_CAPT_PEND, &(dev)->state)
65 69
66#define fimc_capture_active(dev) \
67 (test_bit(ST_CAPT_RUN, &(dev)->state) || \
68 test_bit(ST_CAPT_PEND, &(dev)->state))
69
70#define fimc_capture_streaming(dev) \
71 test_bit(ST_CAPT_STREAM, &(dev)->state)
72
73#define fimc_buf_finish(dev, vid_buf) do { \
74 spin_lock(&(dev)->irqlock); \
75 (vid_buf)->vb.state = VIDEOBUF_DONE; \
76 spin_unlock(&(dev)->irqlock); \
77 wake_up(&(vid_buf)->vb.done); \
78} while (0)
79
80enum fimc_datapath { 70enum fimc_datapath {
81 FIMC_CAMERA, 71 FIMC_CAMERA,
82 FIMC_DMA, 72 FIMC_DMA,
@@ -90,7 +80,6 @@ enum fimc_color_fmt {
90 S5P_FIMC_RGB888, 80 S5P_FIMC_RGB888,
91 S5P_FIMC_RGB30_LOCAL, 81 S5P_FIMC_RGB30_LOCAL,
92 S5P_FIMC_YCBCR420 = 0x20, 82 S5P_FIMC_YCBCR420 = 0x20,
93 S5P_FIMC_YCBCR422,
94 S5P_FIMC_YCBYCR422, 83 S5P_FIMC_YCBYCR422,
95 S5P_FIMC_YCRYCB422, 84 S5P_FIMC_YCRYCB422,
96 S5P_FIMC_CBYCRY422, 85 S5P_FIMC_CBYCRY422,
@@ -100,18 +89,6 @@ enum fimc_color_fmt {
100 89
101#define fimc_fmt_is_rgb(x) ((x) & 0x10) 90#define fimc_fmt_is_rgb(x) ((x) & 0x10)
102 91
103/* Y/Cb/Cr components order at DMA output for 1 plane YCbCr 4:2:2 formats. */
104#define S5P_FIMC_OUT_CRYCBY S5P_CIOCTRL_ORDER422_CRYCBY
105#define S5P_FIMC_OUT_CBYCRY S5P_CIOCTRL_ORDER422_YCRYCB
106#define S5P_FIMC_OUT_YCRYCB S5P_CIOCTRL_ORDER422_CBYCRY
107#define S5P_FIMC_OUT_YCBYCR S5P_CIOCTRL_ORDER422_YCBYCR
108
109/* Input Y/Cb/Cr components order for 1 plane YCbCr 4:2:2 color formats. */
110#define S5P_FIMC_IN_CRYCBY S5P_MSCTRL_ORDER422_CRYCBY
111#define S5P_FIMC_IN_CBYCRY S5P_MSCTRL_ORDER422_YCRYCB
112#define S5P_FIMC_IN_YCRYCB S5P_MSCTRL_ORDER422_CBYCRY
113#define S5P_FIMC_IN_YCBYCR S5P_MSCTRL_ORDER422_YCBYCR
114
115/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */ 92/* Cb/Cr chrominance components order for 2 plane Y/CbCr 4:2:2 formats. */
116#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB 93#define S5P_FIMC_LSB_CRCB S5P_CIOCTRL_ORDER422_2P_LSB_CRCB
117 94
@@ -131,6 +108,7 @@ enum fimc_color_fmt {
131#define FIMC_DST_FMT (1 << 4) 108#define FIMC_DST_FMT (1 << 4)
132#define FIMC_CTX_M2M (1 << 5) 109#define FIMC_CTX_M2M (1 << 5)
133#define FIMC_CTX_CAP (1 << 6) 110#define FIMC_CTX_CAP (1 << 6)
111#define FIMC_CTX_SHUT (1 << 7)
134 112
135/* Image conversion flags */ 113/* Image conversion flags */
136#define FIMC_IN_DMA_ACCESS_TILED (1 << 0) 114#define FIMC_IN_DMA_ACCESS_TILED (1 << 0)
@@ -157,18 +135,18 @@ enum fimc_color_fmt {
157 * @name: format description 135 * @name: format description
158 * @fourcc: the fourcc code for this format, 0 if not applicable 136 * @fourcc: the fourcc code for this format, 0 if not applicable
159 * @color: the corresponding fimc_color_fmt 137 * @color: the corresponding fimc_color_fmt
160 * @depth: driver's private 'number of bits per pixel' 138 * @depth: per plane driver's private 'number of bits per pixel'
161 * @buff_cnt: number of physically non-contiguous data planes 139 * @memplanes: number of physically non-contiguous data planes
162 * @planes_cnt: number of physically contiguous data planes 140 * @colplanes: number of physically contiguous data planes
163 */ 141 */
164struct fimc_fmt { 142struct fimc_fmt {
165 enum v4l2_mbus_pixelcode mbus_code; 143 enum v4l2_mbus_pixelcode mbus_code;
166 char *name; 144 char *name;
167 u32 fourcc; 145 u32 fourcc;
168 u32 color; 146 u32 color;
169 u16 buff_cnt; 147 u16 memplanes;
170 u16 planes_cnt; 148 u16 colplanes;
171 u16 depth; 149 u8 depth[VIDEO_MAX_PLANES];
172 u16 flags; 150 u16 flags;
173#define FMT_FLAGS_CAM (1 << 0) 151#define FMT_FLAGS_CAM (1 << 0)
174#define FMT_FLAGS_M2M (1 << 1) 152#define FMT_FLAGS_M2M (1 << 1)
@@ -260,7 +238,8 @@ struct fimc_addr {
260 * @index: buffer index for the output DMA engine 238 * @index: buffer index for the output DMA engine
261 */ 239 */
262struct fimc_vid_buffer { 240struct fimc_vid_buffer {
263 struct videobuf_buffer vb; 241 struct vb2_buffer vb;
242 struct list_head list;
264 struct fimc_addr paddr; 243 struct fimc_addr paddr;
265 int index; 244 int index;
266}; 245};
@@ -277,7 +256,7 @@ struct fimc_vid_buffer {
277 * @height: image pixel weight 256 * @height: image pixel weight
278 * @paddr: image frame buffer physical addresses 257 * @paddr: image frame buffer physical addresses
279 * @buf_cnt: number of buffers depending on a color format 258 * @buf_cnt: number of buffers depending on a color format
280 * @size: image size in bytes 259 * @payload: image size in bytes (w x h x bpp)
281 * @color: color format 260 * @color: color format
282 * @dma_offset: DMA offset in bytes 261 * @dma_offset: DMA offset in bytes
283 */ 262 */
@@ -290,7 +269,7 @@ struct fimc_frame {
290 u32 offs_v; 269 u32 offs_v;
291 u32 width; 270 u32 width;
292 u32 height; 271 u32 height;
293 u32 size; 272 unsigned long payload[VIDEO_MAX_PLANES];
294 struct fimc_addr paddr; 273 struct fimc_addr paddr;
295 struct fimc_dma_offset dma_offset; 274 struct fimc_dma_offset dma_offset;
296 struct fimc_fmt *fmt; 275 struct fimc_fmt *fmt;
@@ -331,13 +310,14 @@ struct fimc_m2m_device {
331 */ 310 */
332struct fimc_vid_cap { 311struct fimc_vid_cap {
333 struct fimc_ctx *ctx; 312 struct fimc_ctx *ctx;
313 struct vb2_alloc_ctx *alloc_ctx;
334 struct video_device *vfd; 314 struct video_device *vfd;
335 struct v4l2_device v4l2_dev; 315 struct v4l2_device v4l2_dev;
336 struct v4l2_subdev *sd; 316 struct v4l2_subdev *sd;;
337 struct v4l2_mbus_framefmt fmt; 317 struct v4l2_mbus_framefmt fmt;
338 struct list_head pending_buf_q; 318 struct list_head pending_buf_q;
339 struct list_head active_buf_q; 319 struct list_head active_buf_q;
340 struct videobuf_queue vbq; 320 struct vb2_queue vbq;
341 int active_buf_cnt; 321 int active_buf_cnt;
342 int buf_index; 322 int buf_index;
343 unsigned int frame_count; 323 unsigned int frame_count;
@@ -372,6 +352,8 @@ struct fimc_pix_limit {
372 * @has_inp_rot: set if has input rotator 352 * @has_inp_rot: set if has input rotator
373 * @has_out_rot: set if has output rotator 353 * @has_out_rot: set if has output rotator
374 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision 354 * @has_cistatus2: 1 if CISTATUS2 register is present in this IP revision
355 * @has_mainscaler_ext: 1 if extended mainscaler ratios in CIEXTEN register
356 * are present in this IP revision
375 * @pix_limit: pixel size constraints for the scaler 357 * @pix_limit: pixel size constraints for the scaler
376 * @min_inp_pixsize: minimum input pixel size 358 * @min_inp_pixsize: minimum input pixel size
377 * @min_out_pixsize: minimum output pixel size 359 * @min_out_pixsize: minimum output pixel size
@@ -383,6 +365,7 @@ struct samsung_fimc_variant {
383 unsigned int has_inp_rot:1; 365 unsigned int has_inp_rot:1;
384 unsigned int has_out_rot:1; 366 unsigned int has_out_rot:1;
385 unsigned int has_cistatus2:1; 367 unsigned int has_cistatus2:1;
368 unsigned int has_mainscaler_ext:1;
386 struct fimc_pix_limit *pix_limit; 369 struct fimc_pix_limit *pix_limit;
387 u16 min_inp_pixsize; 370 u16 min_inp_pixsize;
388 u16 min_out_pixsize; 371 u16 min_out_pixsize;
@@ -412,12 +395,12 @@ struct fimc_ctx;
412 * @lock: the mutex protecting this data structure 395 * @lock: the mutex protecting this data structure
413 * @pdev: pointer to the FIMC platform device 396 * @pdev: pointer to the FIMC platform device
414 * @pdata: pointer to the device platform data 397 * @pdata: pointer to the device platform data
415 * @id: FIMC device index (0..2) 398 * @id: FIMC device index (0..FIMC_MAX_DEVS)
399 * @num_clocks: the number of clocks managed by this device instance
416 * @clock[]: the clocks required for FIMC operation 400 * @clock[]: the clocks required for FIMC operation
417 * @regs: the mapped hardware registers 401 * @regs: the mapped hardware registers
418 * @regs_res: the resource claimed for IO registers 402 * @regs_res: the resource claimed for IO registers
419 * @irq: interrupt number of the FIMC subdevice 403 * @irq: interrupt number of the FIMC subdevice
420 * @irqlock: spinlock protecting videobuffer queue
421 * @irq_queue: 404 * @irq_queue:
422 * @m2m: memory-to-memory V4L2 device information 405 * @m2m: memory-to-memory V4L2 device information
423 * @vid_cap: camera capture device information 406 * @vid_cap: camera capture device information
@@ -427,18 +410,19 @@ struct fimc_dev {
427 spinlock_t slock; 410 spinlock_t slock;
428 struct mutex lock; 411 struct mutex lock;
429 struct platform_device *pdev; 412 struct platform_device *pdev;
430 struct s3c_platform_fimc *pdata; 413 struct s5p_platform_fimc *pdata;
431 struct samsung_fimc_variant *variant; 414 struct samsung_fimc_variant *variant;
432 int id; 415 u16 id;
433 struct clk *clock[NUM_FIMC_CLOCKS]; 416 u16 num_clocks;
417 struct clk *clock[MAX_FIMC_CLOCKS];
434 void __iomem *regs; 418 void __iomem *regs;
435 struct resource *regs_res; 419 struct resource *regs_res;
436 int irq; 420 int irq;
437 spinlock_t irqlock;
438 wait_queue_head_t irq_queue; 421 wait_queue_head_t irq_queue;
439 struct fimc_m2m_device m2m; 422 struct fimc_m2m_device m2m;
440 struct fimc_vid_cap vid_cap; 423 struct fimc_vid_cap vid_cap;
441 unsigned long state; 424 unsigned long state;
425 struct vb2_alloc_ctx *alloc_ctx;
442}; 426};
443 427
444/** 428/**
@@ -482,11 +466,41 @@ struct fimc_ctx {
482 struct v4l2_m2m_ctx *m2m_ctx; 466 struct v4l2_m2m_ctx *m2m_ctx;
483}; 467};
484 468
485extern struct videobuf_queue_ops fimc_qops; 469static inline bool fimc_capture_active(struct fimc_dev *fimc)
470{
471 unsigned long flags;
472 bool ret;
473
474 spin_lock_irqsave(&fimc->slock, flags);
475 ret = !!(fimc->state & (1 << ST_CAPT_RUN) ||
476 fimc->state & (1 << ST_CAPT_PEND));
477 spin_unlock_irqrestore(&fimc->slock, flags);
478 return ret;
479}
480
481static inline void fimc_ctx_state_lock_set(u32 state, struct fimc_ctx *ctx)
482{
483 unsigned long flags;
484
485 spin_lock_irqsave(&ctx->slock, flags);
486 ctx->state |= state;
487 spin_unlock_irqrestore(&ctx->slock, flags);
488}
489
490static inline bool fimc_ctx_state_is_set(u32 mask, struct fimc_ctx *ctx)
491{
492 unsigned long flags;
493 bool ret;
494
495 spin_lock_irqsave(&ctx->slock, flags);
496 ret = (ctx->state & mask) == mask;
497 spin_unlock_irqrestore(&ctx->slock, flags);
498 return ret;
499}
486 500
487static inline int tiled_fmt(struct fimc_fmt *fmt) 501static inline int tiled_fmt(struct fimc_fmt *fmt)
488{ 502{
489 return 0; 503 return fmt->fourcc == V4L2_PIX_FMT_NV12MT;
490} 504}
491 505
492static inline void fimc_hw_clear_irq(struct fimc_dev *dev) 506static inline void fimc_hw_clear_irq(struct fimc_dev *dev)
@@ -542,12 +556,12 @@ static inline struct fimc_frame *ctx_get_frame(struct fimc_ctx *ctx,
542{ 556{
543 struct fimc_frame *frame; 557 struct fimc_frame *frame;
544 558
545 if (V4L2_BUF_TYPE_VIDEO_OUTPUT == type) { 559 if (V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == type) {
546 if (ctx->state & FIMC_CTX_M2M) 560 if (fimc_ctx_state_is_set(FIMC_CTX_M2M, ctx))
547 frame = &ctx->s_frame; 561 frame = &ctx->s_frame;
548 else 562 else
549 return ERR_PTR(-EINVAL); 563 return ERR_PTR(-EINVAL);
550 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE == type) { 564 } else if (V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == type) {
551 frame = &ctx->d_frame; 565 frame = &ctx->d_frame;
552 } else { 566 } else {
553 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev, 567 v4l2_err(&ctx->fimc_dev->m2m.v4l2_dev,
@@ -581,7 +595,8 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx);
581void fimc_hw_set_out_dma(struct fimc_ctx *ctx); 595void fimc_hw_set_out_dma(struct fimc_ctx *ctx);
582void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable); 596void fimc_hw_en_lastirq(struct fimc_dev *fimc, int enable);
583void fimc_hw_en_irq(struct fimc_dev *fimc, int enable); 597void fimc_hw_en_irq(struct fimc_dev *fimc, int enable);
584void fimc_hw_set_scaler(struct fimc_ctx *ctx); 598void fimc_hw_set_prescaler(struct fimc_ctx *ctx);
599void fimc_hw_set_mainscaler(struct fimc_ctx *ctx);
585void fimc_hw_en_capture(struct fimc_ctx *ctx); 600void fimc_hw_en_capture(struct fimc_ctx *ctx);
586void fimc_hw_set_effect(struct fimc_ctx *ctx); 601void fimc_hw_set_effect(struct fimc_ctx *ctx);
587void fimc_hw_set_in_dma(struct fimc_ctx *ctx); 602void fimc_hw_set_in_dma(struct fimc_ctx *ctx);
@@ -589,23 +604,23 @@ void fimc_hw_set_input_path(struct fimc_ctx *ctx);
589void fimc_hw_set_output_path(struct fimc_ctx *ctx); 604void fimc_hw_set_output_path(struct fimc_ctx *ctx);
590void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr); 605void fimc_hw_set_input_addr(struct fimc_dev *fimc, struct fimc_addr *paddr);
591void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr, 606void fimc_hw_set_output_addr(struct fimc_dev *fimc, struct fimc_addr *paddr,
592 int index); 607 int index);
593int fimc_hw_set_camera_source(struct fimc_dev *fimc, 608int fimc_hw_set_camera_source(struct fimc_dev *fimc,
594 struct s3c_fimc_isp_info *cam); 609 struct s5p_fimc_isp_info *cam);
595int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f); 610int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f);
596int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, 611int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
597 struct s3c_fimc_isp_info *cam); 612 struct s5p_fimc_isp_info *cam);
598int fimc_hw_set_camera_type(struct fimc_dev *fimc, 613int fimc_hw_set_camera_type(struct fimc_dev *fimc,
599 struct s3c_fimc_isp_info *cam); 614 struct s5p_fimc_isp_info *cam);
600 615
601/* -----------------------------------------------------*/ 616/* -----------------------------------------------------*/
602/* fimc-core.c */ 617/* fimc-core.c */
603int fimc_vidioc_enum_fmt(struct file *file, void *priv, 618int fimc_vidioc_enum_fmt_mplane(struct file *file, void *priv,
604 struct v4l2_fmtdesc *f); 619 struct v4l2_fmtdesc *f);
605int fimc_vidioc_g_fmt(struct file *file, void *priv, 620int fimc_vidioc_g_fmt_mplane(struct file *file, void *priv,
606 struct v4l2_format *f); 621 struct v4l2_format *f);
607int fimc_vidioc_try_fmt(struct file *file, void *priv, 622int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
608 struct v4l2_format *f); 623 struct v4l2_format *f);
609int fimc_vidioc_queryctrl(struct file *file, void *priv, 624int fimc_vidioc_queryctrl(struct file *file, void *priv,
610 struct v4l2_queryctrl *qc); 625 struct v4l2_queryctrl *qc);
611int fimc_vidioc_g_ctrl(struct file *file, void *priv, 626int fimc_vidioc_g_ctrl(struct file *file, void *priv,
@@ -619,10 +634,10 @@ struct fimc_fmt *find_format(struct v4l2_format *f, unsigned int mask);
619struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f, 634struct fimc_fmt *find_mbus_format(struct v4l2_mbus_framefmt *f,
620 unsigned int mask); 635 unsigned int mask);
621 636
622int fimc_check_scaler_ratio(struct v4l2_rect *r, struct fimc_frame *f); 637int fimc_check_scaler_ratio(int sw, int sh, int dw, int dh, int rot);
623int fimc_set_scaler_info(struct fimc_ctx *ctx); 638int fimc_set_scaler_info(struct fimc_ctx *ctx);
624int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags); 639int fimc_prepare_config(struct fimc_ctx *ctx, u32 flags);
625int fimc_prepare_addr(struct fimc_ctx *ctx, struct fimc_vid_buffer *buf, 640int fimc_prepare_addr(struct fimc_ctx *ctx, struct vb2_buffer *vb,
626 struct fimc_frame *frame, struct fimc_addr *paddr); 641 struct fimc_frame *frame, struct fimc_addr *paddr);
627 642
628/* -----------------------------------------------------*/ 643/* -----------------------------------------------------*/
@@ -649,28 +664,27 @@ static inline void fimc_deactivate_capture(struct fimc_dev *fimc)
649} 664}
650 665
651/* 666/*
652 * Add video buffer to the active buffers queue. 667 * Add buf to the capture active buffers queue.
653 * The caller holds irqlock spinlock. 668 * Locking: Need to be called with fimc_dev::slock held.
654 */ 669 */
655static inline void active_queue_add(struct fimc_vid_cap *vid_cap, 670static inline void active_queue_add(struct fimc_vid_cap *vid_cap,
656 struct fimc_vid_buffer *buf) 671 struct fimc_vid_buffer *buf)
657{ 672{
658 buf->vb.state = VIDEOBUF_ACTIVE; 673 list_add_tail(&buf->list, &vid_cap->active_buf_q);
659 list_add_tail(&buf->vb.queue, &vid_cap->active_buf_q);
660 vid_cap->active_buf_cnt++; 674 vid_cap->active_buf_cnt++;
661} 675}
662 676
663/* 677/*
664 * Pop a video buffer from the capture active buffers queue 678 * Pop a video buffer from the capture active buffers queue
665 * Locking: Need to be called with dev->slock held. 679 * Locking: Need to be called with fimc_dev::slock held.
666 */ 680 */
667static inline struct fimc_vid_buffer * 681static inline struct fimc_vid_buffer *
668active_queue_pop(struct fimc_vid_cap *vid_cap) 682active_queue_pop(struct fimc_vid_cap *vid_cap)
669{ 683{
670 struct fimc_vid_buffer *buf; 684 struct fimc_vid_buffer *buf;
671 buf = list_entry(vid_cap->active_buf_q.next, 685 buf = list_entry(vid_cap->active_buf_q.next,
672 struct fimc_vid_buffer, vb.queue); 686 struct fimc_vid_buffer, list);
673 list_del(&buf->vb.queue); 687 list_del(&buf->list);
674 vid_cap->active_buf_cnt--; 688 vid_cap->active_buf_cnt--;
675 return buf; 689 return buf;
676} 690}
@@ -679,8 +693,7 @@ active_queue_pop(struct fimc_vid_cap *vid_cap)
679static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap, 693static inline void fimc_pending_queue_add(struct fimc_vid_cap *vid_cap,
680 struct fimc_vid_buffer *buf) 694 struct fimc_vid_buffer *buf)
681{ 695{
682 buf->vb.state = VIDEOBUF_QUEUED; 696 list_add_tail(&buf->list, &vid_cap->pending_buf_q);
683 list_add_tail(&buf->vb.queue, &vid_cap->pending_buf_q);
684} 697}
685 698
686/* Add video buffer to the capture pending buffers queue */ 699/* Add video buffer to the capture pending buffers queue */
@@ -689,10 +702,9 @@ pending_queue_pop(struct fimc_vid_cap *vid_cap)
689{ 702{
690 struct fimc_vid_buffer *buf; 703 struct fimc_vid_buffer *buf;
691 buf = list_entry(vid_cap->pending_buf_q.next, 704 buf = list_entry(vid_cap->pending_buf_q.next,
692 struct fimc_vid_buffer, vb.queue); 705 struct fimc_vid_buffer, list);
693 list_del(&buf->vb.queue); 706 list_del(&buf->list);
694 return buf; 707 return buf;
695} 708}
696 709
697
698#endif /* FIMC_CORE_H_ */ 710#endif /* FIMC_CORE_H_ */
diff --git a/drivers/media/video/s5p-fimc/fimc-reg.c b/drivers/media/video/s5p-fimc/fimc-reg.c
index 511631a2e5c3..4d929a394521 100644
--- a/drivers/media/video/s5p-fimc/fimc-reg.c
+++ b/drivers/media/video/s5p-fimc/fimc-reg.c
@@ -13,7 +13,7 @@
13#include <linux/io.h> 13#include <linux/io.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <mach/map.h> 15#include <mach/map.h>
16#include <media/s3c_fimc.h> 16#include <media/s5p_fimc.h>
17 17
18#include "fimc-core.h" 18#include "fimc-core.h"
19 19
@@ -37,11 +37,11 @@ void fimc_hw_reset(struct fimc_dev *dev)
37 writel(cfg, dev->regs + S5P_CIGCTRL); 37 writel(cfg, dev->regs + S5P_CIGCTRL);
38} 38}
39 39
40static u32 fimc_hw_get_in_flip(u32 ctx_flip) 40static u32 fimc_hw_get_in_flip(struct fimc_ctx *ctx)
41{ 41{
42 u32 flip = S5P_MSCTRL_FLIP_NORMAL; 42 u32 flip = S5P_MSCTRL_FLIP_NORMAL;
43 43
44 switch (ctx_flip) { 44 switch (ctx->flip) {
45 case FLIP_X_AXIS: 45 case FLIP_X_AXIS:
46 flip = S5P_MSCTRL_FLIP_X_MIRROR; 46 flip = S5P_MSCTRL_FLIP_X_MIRROR;
47 break; 47 break;
@@ -51,16 +51,20 @@ static u32 fimc_hw_get_in_flip(u32 ctx_flip)
51 case FLIP_XY_AXIS: 51 case FLIP_XY_AXIS:
52 flip = S5P_MSCTRL_FLIP_180; 52 flip = S5P_MSCTRL_FLIP_180;
53 break; 53 break;
54 default:
55 break;
54 } 56 }
57 if (ctx->rotation <= 90)
58 return flip;
55 59
56 return flip; 60 return (flip ^ S5P_MSCTRL_FLIP_180) & S5P_MSCTRL_FLIP_180;
57} 61}
58 62
59static u32 fimc_hw_get_target_flip(u32 ctx_flip) 63static u32 fimc_hw_get_target_flip(struct fimc_ctx *ctx)
60{ 64{
61 u32 flip = S5P_CITRGFMT_FLIP_NORMAL; 65 u32 flip = S5P_CITRGFMT_FLIP_NORMAL;
62 66
63 switch (ctx_flip) { 67 switch (ctx->flip) {
64 case FLIP_X_AXIS: 68 case FLIP_X_AXIS:
65 flip = S5P_CITRGFMT_FLIP_X_MIRROR; 69 flip = S5P_CITRGFMT_FLIP_X_MIRROR;
66 break; 70 break;
@@ -70,11 +74,13 @@ static u32 fimc_hw_get_target_flip(u32 ctx_flip)
70 case FLIP_XY_AXIS: 74 case FLIP_XY_AXIS:
71 flip = S5P_CITRGFMT_FLIP_180; 75 flip = S5P_CITRGFMT_FLIP_180;
72 break; 76 break;
73 case FLIP_NONE: 77 default:
74 break; 78 break;
75
76 } 79 }
77 return flip; 80 if (ctx->rotation <= 90)
81 return flip;
82
83 return (flip ^ S5P_CITRGFMT_FLIP_180) & S5P_CITRGFMT_FLIP_180;
78} 84}
79 85
80void fimc_hw_set_rotation(struct fimc_ctx *ctx) 86void fimc_hw_set_rotation(struct fimc_ctx *ctx)
@@ -84,10 +90,7 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
84 90
85 cfg = readl(dev->regs + S5P_CITRGFMT); 91 cfg = readl(dev->regs + S5P_CITRGFMT);
86 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 | 92 cfg &= ~(S5P_CITRGFMT_INROT90 | S5P_CITRGFMT_OUTROT90 |
87 S5P_CITRGFMT_FLIP_180); 93 S5P_CITRGFMT_FLIP_180);
88
89 flip = readl(dev->regs + S5P_MSCTRL);
90 flip &= ~S5P_MSCTRL_FLIP_MASK;
91 94
92 /* 95 /*
93 * The input and output rotator cannot work simultaneously. 96 * The input and output rotator cannot work simultaneously.
@@ -95,26 +98,22 @@ void fimc_hw_set_rotation(struct fimc_ctx *ctx)
95 * in direct fifo output mode. 98 * in direct fifo output mode.
96 */ 99 */
97 if (ctx->rotation == 90 || ctx->rotation == 270) { 100 if (ctx->rotation == 90 || ctx->rotation == 270) {
98 if (ctx->out_path == FIMC_LCDFIFO) {
99 cfg |= S5P_CITRGFMT_INROT90;
100 if (ctx->rotation == 270)
101 flip |= S5P_MSCTRL_FLIP_180;
102 } else {
103 cfg |= S5P_CITRGFMT_OUTROT90;
104 if (ctx->rotation == 270)
105 cfg |= S5P_CITRGFMT_FLIP_180;
106 }
107 } else if (ctx->rotation == 180) {
108 if (ctx->out_path == FIMC_LCDFIFO) 101 if (ctx->out_path == FIMC_LCDFIFO)
109 flip |= S5P_MSCTRL_FLIP_180; 102 cfg |= S5P_CITRGFMT_INROT90;
110 else 103 else
111 cfg |= S5P_CITRGFMT_FLIP_180; 104 cfg |= S5P_CITRGFMT_OUTROT90;
112 } 105 }
113 if (ctx->rotation == 180 || ctx->rotation == 270)
114 writel(flip, dev->regs + S5P_MSCTRL);
115 106
116 cfg |= fimc_hw_get_target_flip(ctx->flip); 107 if (ctx->out_path == FIMC_DMA) {
117 writel(cfg, dev->regs + S5P_CITRGFMT); 108 cfg |= fimc_hw_get_target_flip(ctx);
109 writel(cfg, dev->regs + S5P_CITRGFMT);
110 } else {
111 /* LCD FIFO path */
112 flip = readl(dev->regs + S5P_MSCTRL);
113 flip &= ~S5P_MSCTRL_FLIP_MASK;
114 flip |= fimc_hw_get_in_flip(ctx);
115 writel(flip, dev->regs + S5P_MSCTRL);
116 }
118} 117}
119 118
120void fimc_hw_set_target_format(struct fimc_ctx *ctx) 119void fimc_hw_set_target_format(struct fimc_ctx *ctx)
@@ -131,19 +130,14 @@ void fimc_hw_set_target_format(struct fimc_ctx *ctx)
131 S5P_CITRGFMT_VSIZE_MASK); 130 S5P_CITRGFMT_VSIZE_MASK);
132 131
133 switch (frame->fmt->color) { 132 switch (frame->fmt->color) {
134 case S5P_FIMC_RGB565: 133 case S5P_FIMC_RGB565...S5P_FIMC_RGB888:
135 case S5P_FIMC_RGB666:
136 case S5P_FIMC_RGB888:
137 cfg |= S5P_CITRGFMT_RGB; 134 cfg |= S5P_CITRGFMT_RGB;
138 break; 135 break;
139 case S5P_FIMC_YCBCR420: 136 case S5P_FIMC_YCBCR420:
140 cfg |= S5P_CITRGFMT_YCBCR420; 137 cfg |= S5P_CITRGFMT_YCBCR420;
141 break; 138 break;
142 case S5P_FIMC_YCBYCR422: 139 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
143 case S5P_FIMC_YCRYCB422: 140 if (frame->fmt->colplanes == 1)
144 case S5P_FIMC_CBYCRY422:
145 case S5P_FIMC_CRYCBY422:
146 if (frame->fmt->planes_cnt == 1)
147 cfg |= S5P_CITRGFMT_YCBCR422_1P; 141 cfg |= S5P_CITRGFMT_YCBCR422_1P;
148 else 142 else
149 cfg |= S5P_CITRGFMT_YCBCR422; 143 cfg |= S5P_CITRGFMT_YCBCR422;
@@ -219,11 +213,11 @@ void fimc_hw_set_out_dma(struct fimc_ctx *ctx)
219 cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK | 213 cfg &= ~(S5P_CIOCTRL_ORDER2P_MASK | S5P_CIOCTRL_ORDER422_MASK |
220 S5P_CIOCTRL_YCBCR_PLANE_MASK); 214 S5P_CIOCTRL_YCBCR_PLANE_MASK);
221 215
222 if (frame->fmt->planes_cnt == 1) 216 if (frame->fmt->colplanes == 1)
223 cfg |= ctx->out_order_1p; 217 cfg |= ctx->out_order_1p;
224 else if (frame->fmt->planes_cnt == 2) 218 else if (frame->fmt->colplanes == 2)
225 cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE; 219 cfg |= ctx->out_order_2p | S5P_CIOCTRL_YCBCR_2PLANE;
226 else if (frame->fmt->planes_cnt == 3) 220 else if (frame->fmt->colplanes == 3)
227 cfg |= S5P_CIOCTRL_YCBCR_3PLANE; 221 cfg |= S5P_CIOCTRL_YCBCR_3PLANE;
228 222
229 writel(cfg, dev->regs + S5P_CIOCTRL); 223 writel(cfg, dev->regs + S5P_CIOCTRL);
@@ -249,7 +243,7 @@ void fimc_hw_en_lastirq(struct fimc_dev *dev, int enable)
249 writel(cfg, dev->regs + S5P_CIOCTRL); 243 writel(cfg, dev->regs + S5P_CIOCTRL);
250} 244}
251 245
252static void fimc_hw_set_prescaler(struct fimc_ctx *ctx) 246void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
253{ 247{
254 struct fimc_dev *dev = ctx->fimc_dev; 248 struct fimc_dev *dev = ctx->fimc_dev;
255 struct fimc_scaler *sc = &ctx->scaler; 249 struct fimc_scaler *sc = &ctx->scaler;
@@ -267,7 +261,7 @@ static void fimc_hw_set_prescaler(struct fimc_ctx *ctx)
267 writel(cfg, dev->regs + S5P_CISCPREDST); 261 writel(cfg, dev->regs + S5P_CISCPREDST);
268} 262}
269 263
270void fimc_hw_set_scaler(struct fimc_ctx *ctx) 264static void fimc_hw_set_scaler(struct fimc_ctx *ctx)
271{ 265{
272 struct fimc_dev *dev = ctx->fimc_dev; 266 struct fimc_dev *dev = ctx->fimc_dev;
273 struct fimc_scaler *sc = &ctx->scaler; 267 struct fimc_scaler *sc = &ctx->scaler;
@@ -275,8 +269,6 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx)
275 struct fimc_frame *dst_frame = &ctx->d_frame; 269 struct fimc_frame *dst_frame = &ctx->d_frame;
276 u32 cfg = 0; 270 u32 cfg = 0;
277 271
278 fimc_hw_set_prescaler(ctx);
279
280 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW)) 272 if (!(ctx->flags & FIMC_COLOR_RANGE_NARROW))
281 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE); 273 cfg |= (S5P_CISCCTRL_CSCR2Y_WIDE | S5P_CISCCTRL_CSCY2R_WIDE);
282 274
@@ -316,13 +308,42 @@ void fimc_hw_set_scaler(struct fimc_ctx *ctx)
316 cfg |= S5P_CISCCTRL_INTERLACE; 308 cfg |= S5P_CISCCTRL_INTERLACE;
317 } 309 }
318 310
311 writel(cfg, dev->regs + S5P_CISCCTRL);
312}
313
314void fimc_hw_set_mainscaler(struct fimc_ctx *ctx)
315{
316 struct fimc_dev *dev = ctx->fimc_dev;
317 struct samsung_fimc_variant *variant = dev->variant;
318 struct fimc_scaler *sc = &ctx->scaler;
319 u32 cfg;
320
319 dbg("main_hratio= 0x%X main_vratio= 0x%X", 321 dbg("main_hratio= 0x%X main_vratio= 0x%X",
320 sc->main_hratio, sc->main_vratio); 322 sc->main_hratio, sc->main_vratio);
321 323
322 cfg |= S5P_CISCCTRL_SC_HORRATIO(sc->main_hratio); 324 fimc_hw_set_scaler(ctx);
323 cfg |= S5P_CISCCTRL_SC_VERRATIO(sc->main_vratio);
324 325
325 writel(cfg, dev->regs + S5P_CISCCTRL); 326 cfg = readl(dev->regs + S5P_CISCCTRL);
327
328 if (variant->has_mainscaler_ext) {
329 cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK);
330 cfg |= S5P_CISCCTRL_MHRATIO_EXT(sc->main_hratio);
331 cfg |= S5P_CISCCTRL_MVRATIO_EXT(sc->main_vratio);
332 writel(cfg, dev->regs + S5P_CISCCTRL);
333
334 cfg = readl(dev->regs + S5P_CIEXTEN);
335
336 cfg &= ~(S5P_CIEXTEN_MVRATIO_EXT_MASK |
337 S5P_CIEXTEN_MHRATIO_EXT_MASK);
338 cfg |= S5P_CIEXTEN_MHRATIO_EXT(sc->main_hratio);
339 cfg |= S5P_CIEXTEN_MVRATIO_EXT(sc->main_vratio);
340 writel(cfg, dev->regs + S5P_CIEXTEN);
341 } else {
342 cfg &= ~(S5P_CISCCTRL_MHRATIO_MASK | S5P_CISCCTRL_MVRATIO_MASK);
343 cfg |= S5P_CISCCTRL_MHRATIO(sc->main_hratio);
344 cfg |= S5P_CISCCTRL_MVRATIO(sc->main_vratio);
345 writel(cfg, dev->regs + S5P_CISCCTRL);
346 }
326} 347}
327 348
328void fimc_hw_en_capture(struct fimc_ctx *ctx) 349void fimc_hw_en_capture(struct fimc_ctx *ctx)
@@ -410,41 +431,37 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
410 431
411 /* Set the input DMA to process single frame only. */ 432 /* Set the input DMA to process single frame only. */
412 cfg = readl(dev->regs + S5P_MSCTRL); 433 cfg = readl(dev->regs + S5P_MSCTRL);
413 cfg &= ~(S5P_MSCTRL_FLIP_MASK 434 cfg &= ~(S5P_MSCTRL_INFORMAT_MASK
414 | S5P_MSCTRL_INFORMAT_MASK
415 | S5P_MSCTRL_IN_BURST_COUNT_MASK 435 | S5P_MSCTRL_IN_BURST_COUNT_MASK
416 | S5P_MSCTRL_INPUT_MASK 436 | S5P_MSCTRL_INPUT_MASK
417 | S5P_MSCTRL_C_INT_IN_MASK 437 | S5P_MSCTRL_C_INT_IN_MASK
418 | S5P_MSCTRL_2P_IN_ORDER_MASK); 438 | S5P_MSCTRL_2P_IN_ORDER_MASK);
419 439
420 cfg |= (S5P_MSCTRL_FRAME_COUNT(1) | S5P_MSCTRL_INPUT_MEMORY); 440 cfg |= (S5P_MSCTRL_IN_BURST_COUNT(4)
441 | S5P_MSCTRL_INPUT_MEMORY
442 | S5P_MSCTRL_FIFO_CTRL_FULL);
421 443
422 switch (frame->fmt->color) { 444 switch (frame->fmt->color) {
423 case S5P_FIMC_RGB565: 445 case S5P_FIMC_RGB565...S5P_FIMC_RGB888:
424 case S5P_FIMC_RGB666:
425 case S5P_FIMC_RGB888:
426 cfg |= S5P_MSCTRL_INFORMAT_RGB; 446 cfg |= S5P_MSCTRL_INFORMAT_RGB;
427 break; 447 break;
428 case S5P_FIMC_YCBCR420: 448 case S5P_FIMC_YCBCR420:
429 cfg |= S5P_MSCTRL_INFORMAT_YCBCR420; 449 cfg |= S5P_MSCTRL_INFORMAT_YCBCR420;
430 450
431 if (frame->fmt->planes_cnt == 2) 451 if (frame->fmt->colplanes == 2)
432 cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE; 452 cfg |= ctx->in_order_2p | S5P_MSCTRL_C_INT_IN_2PLANE;
433 else 453 else
434 cfg |= S5P_MSCTRL_C_INT_IN_3PLANE; 454 cfg |= S5P_MSCTRL_C_INT_IN_3PLANE;
435 455
436 break; 456 break;
437 case S5P_FIMC_YCBYCR422: 457 case S5P_FIMC_YCBYCR422...S5P_FIMC_CRYCBY422:
438 case S5P_FIMC_YCRYCB422: 458 if (frame->fmt->colplanes == 1) {
439 case S5P_FIMC_CBYCRY422:
440 case S5P_FIMC_CRYCBY422:
441 if (frame->fmt->planes_cnt == 1) {
442 cfg |= ctx->in_order_1p 459 cfg |= ctx->in_order_1p
443 | S5P_MSCTRL_INFORMAT_YCBCR422_1P; 460 | S5P_MSCTRL_INFORMAT_YCBCR422_1P;
444 } else { 461 } else {
445 cfg |= S5P_MSCTRL_INFORMAT_YCBCR422; 462 cfg |= S5P_MSCTRL_INFORMAT_YCBCR422;
446 463
447 if (frame->fmt->planes_cnt == 2) 464 if (frame->fmt->colplanes == 2)
448 cfg |= ctx->in_order_2p 465 cfg |= ctx->in_order_2p
449 | S5P_MSCTRL_C_INT_IN_2PLANE; 466 | S5P_MSCTRL_C_INT_IN_2PLANE;
450 else 467 else
@@ -455,13 +472,6 @@ void fimc_hw_set_in_dma(struct fimc_ctx *ctx)
455 break; 472 break;
456 } 473 }
457 474
458 /*
459 * Input DMA flip mode (and rotation).
460 * Do not allow simultaneous rotation and flipping.
461 */
462 if (!ctx->rotation && ctx->out_path == FIMC_LCDFIFO)
463 cfg |= fimc_hw_get_in_flip(ctx->flip);
464
465 writel(cfg, dev->regs + S5P_MSCTRL); 475 writel(cfg, dev->regs + S5P_MSCTRL);
466 476
467 /* Input/output DMA linear/tiled mode. */ 477 /* Input/output DMA linear/tiled mode. */
@@ -532,7 +542,7 @@ void fimc_hw_set_output_addr(struct fimc_dev *dev,
532} 542}
533 543
534int fimc_hw_set_camera_polarity(struct fimc_dev *fimc, 544int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
535 struct s3c_fimc_isp_info *cam) 545 struct s5p_fimc_isp_info *cam)
536{ 546{
537 u32 cfg = readl(fimc->regs + S5P_CIGCTRL); 547 u32 cfg = readl(fimc->regs + S5P_CIGCTRL);
538 548
@@ -557,41 +567,46 @@ int fimc_hw_set_camera_polarity(struct fimc_dev *fimc,
557} 567}
558 568
559int fimc_hw_set_camera_source(struct fimc_dev *fimc, 569int fimc_hw_set_camera_source(struct fimc_dev *fimc,
560 struct s3c_fimc_isp_info *cam) 570 struct s5p_fimc_isp_info *cam)
561{ 571{
562 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame; 572 struct fimc_frame *f = &fimc->vid_cap.ctx->s_frame;
563 u32 cfg = 0; 573 u32 cfg = 0;
574 u32 bus_width;
575 int i;
576
577 static const struct {
578 u32 pixelcode;
579 u32 cisrcfmt;
580 u16 bus_width;
581 } pix_desc[] = {
582 { V4L2_MBUS_FMT_YUYV8_2X8, S5P_CISRCFMT_ORDER422_YCBYCR, 8 },
583 { V4L2_MBUS_FMT_YVYU8_2X8, S5P_CISRCFMT_ORDER422_YCRYCB, 8 },
584 { V4L2_MBUS_FMT_VYUY8_2X8, S5P_CISRCFMT_ORDER422_CRYCBY, 8 },
585 { V4L2_MBUS_FMT_UYVY8_2X8, S5P_CISRCFMT_ORDER422_CBYCRY, 8 },
586 /* TODO: Add pixel codes for 16-bit bus width */
587 };
564 588
565 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) { 589 if (cam->bus_type == FIMC_ITU_601 || cam->bus_type == FIMC_ITU_656) {
590 for (i = 0; i < ARRAY_SIZE(pix_desc); i++) {
591 if (fimc->vid_cap.fmt.code == pix_desc[i].pixelcode) {
592 cfg = pix_desc[i].cisrcfmt;
593 bus_width = pix_desc[i].bus_width;
594 break;
595 }
596 }
566 597
567 switch (fimc->vid_cap.fmt.code) { 598 if (i == ARRAY_SIZE(pix_desc)) {
568 case V4L2_MBUS_FMT_YUYV8_2X8: 599 v4l2_err(&fimc->vid_cap.v4l2_dev,
569 cfg = S5P_CISRCFMT_ORDER422_YCBYCR; 600 "Camera color format not supported: %d\n",
570 break; 601 fimc->vid_cap.fmt.code);
571 case V4L2_MBUS_FMT_YVYU8_2X8:
572 cfg = S5P_CISRCFMT_ORDER422_YCRYCB;
573 break;
574 case V4L2_MBUS_FMT_VYUY8_2X8:
575 cfg = S5P_CISRCFMT_ORDER422_CRYCBY;
576 break;
577 case V4L2_MBUS_FMT_UYVY8_2X8:
578 cfg = S5P_CISRCFMT_ORDER422_CBYCRY;
579 break;
580 default:
581 err("camera image format not supported: %d",
582 fimc->vid_cap.fmt.code);
583 return -EINVAL; 602 return -EINVAL;
584 } 603 }
585 604
586 if (cam->bus_type == FIMC_ITU_601) { 605 if (cam->bus_type == FIMC_ITU_601) {
587 if (cam->bus_width == 8) { 606 if (bus_width == 8)
588 cfg |= S5P_CISRCFMT_ITU601_8BIT; 607 cfg |= S5P_CISRCFMT_ITU601_8BIT;
589 } else if (cam->bus_width == 16) { 608 else if (bus_width == 16)
590 cfg |= S5P_CISRCFMT_ITU601_16BIT; 609 cfg |= S5P_CISRCFMT_ITU601_16BIT;
591 } else {
592 err("invalid bus width: %d", cam->bus_width);
593 return -EINVAL;
594 }
595 } /* else defaults to ITU-R BT.656 8-bit */ 610 } /* else defaults to ITU-R BT.656 8-bit */
596 } 611 }
597 612
@@ -624,7 +639,7 @@ int fimc_hw_set_camera_offset(struct fimc_dev *fimc, struct fimc_frame *f)
624} 639}
625 640
626int fimc_hw_set_camera_type(struct fimc_dev *fimc, 641int fimc_hw_set_camera_type(struct fimc_dev *fimc,
627 struct s3c_fimc_isp_info *cam) 642 struct s5p_fimc_isp_info *cam)
628{ 643{
629 u32 cfg, tmp; 644 u32 cfg, tmp;
630 struct fimc_vid_cap *vid_cap = &fimc->vid_cap; 645 struct fimc_vid_cap *vid_cap = &fimc->vid_cap;
@@ -650,10 +665,12 @@ int fimc_hw_set_camera_type(struct fimc_dev *fimc,
650 vid_cap->fmt.code); 665 vid_cap->fmt.code);
651 return -EINVAL; 666 return -EINVAL;
652 } 667 }
653 writel(tmp | (0x1 << 8), fimc->regs + S5P_CSIIMGFMT); 668 tmp |= (cam->csi_data_align == 32) << 8;
669
670 writel(tmp, fimc->regs + S5P_CSIIMGFMT);
654 671
655 } else if (cam->bus_type == FIMC_ITU_601 || 672 } else if (cam->bus_type == FIMC_ITU_601 ||
656 cam->bus_type == FIMC_ITU_656) { 673 cam->bus_type == FIMC_ITU_656) {
657 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */ 674 if (cam->mux_id == 0) /* ITU-A, ITU-B: 0, 1 */
658 cfg |= S5P_CIGCTRL_SELCAM_ITU_A; 675 cfg |= S5P_CIGCTRL_SELCAM_ITU_A;
659 } else if (cam->bus_type == FIMC_LCD_WB) { 676 } else if (cam->bus_type == FIMC_LCD_WB) {
diff --git a/drivers/media/video/s5p-fimc/regs-fimc.h b/drivers/media/video/s5p-fimc/regs-fimc.h
index 57e33f84fcfa..0fea3e635d76 100644
--- a/drivers/media/video/s5p-fimc/regs-fimc.h
+++ b/drivers/media/video/s5p-fimc/regs-fimc.h
@@ -98,8 +98,8 @@
98#define S5P_CIOCTRL 0x4c 98#define S5P_CIOCTRL 0x4c
99#define S5P_CIOCTRL_ORDER422_MASK (3 << 0) 99#define S5P_CIOCTRL_ORDER422_MASK (3 << 0)
100#define S5P_CIOCTRL_ORDER422_CRYCBY (0 << 0) 100#define S5P_CIOCTRL_ORDER422_CRYCBY (0 << 0)
101#define S5P_CIOCTRL_ORDER422_YCRYCB (1 << 0) 101#define S5P_CIOCTRL_ORDER422_CBYCRY (1 << 0)
102#define S5P_CIOCTRL_ORDER422_CBYCRY (2 << 0) 102#define S5P_CIOCTRL_ORDER422_YCRYCB (2 << 0)
103#define S5P_CIOCTRL_ORDER422_YCBYCR (3 << 0) 103#define S5P_CIOCTRL_ORDER422_YCBYCR (3 << 0)
104#define S5P_CIOCTRL_LASTIRQ_ENABLE (1 << 2) 104#define S5P_CIOCTRL_LASTIRQ_ENABLE (1 << 2)
105#define S5P_CIOCTRL_YCBCR_3PLANE (0 << 3) 105#define S5P_CIOCTRL_YCBCR_3PLANE (0 << 3)
@@ -139,8 +139,12 @@
139#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11) 139#define S5P_CISCCTRL_OUTRGB_FMT_MASK (3 << 11)
140#define S5P_CISCCTRL_RGB_EXT (1 << 10) 140#define S5P_CISCCTRL_RGB_EXT (1 << 10)
141#define S5P_CISCCTRL_ONE2ONE (1 << 9) 141#define S5P_CISCCTRL_ONE2ONE (1 << 9)
142#define S5P_CISCCTRL_SC_HORRATIO(x) ((x) << 16) 142#define S5P_CISCCTRL_MHRATIO(x) ((x) << 16)
143#define S5P_CISCCTRL_SC_VERRATIO(x) ((x) << 0) 143#define S5P_CISCCTRL_MVRATIO(x) ((x) << 0)
144#define S5P_CISCCTRL_MHRATIO_MASK (0x1ff << 16)
145#define S5P_CISCCTRL_MVRATIO_MASK (0x1ff << 0)
146#define S5P_CISCCTRL_MHRATIO_EXT(x) (((x) >> 6) << 16)
147#define S5P_CISCCTRL_MVRATIO_EXT(x) (((x) >> 6) << 0)
144 148
145/* Target area */ 149/* Target area */
146#define S5P_CITAREA 0x5c 150#define S5P_CITAREA 0x5c
@@ -210,7 +214,7 @@
210 214
211/* Input DMA control */ 215/* Input DMA control */
212#define S5P_MSCTRL 0xfc 216#define S5P_MSCTRL 0xfc
213#define S5P_MSCTRL_IN_BURST_COUNT_MASK (3 << 24) 217#define S5P_MSCTRL_IN_BURST_COUNT_MASK (0xF << 24)
214#define S5P_MSCTRL_2P_IN_ORDER_MASK (3 << 16) 218#define S5P_MSCTRL_2P_IN_ORDER_MASK (3 << 16)
215#define S5P_MSCTRL_2P_IN_ORDER_SHIFT 16 219#define S5P_MSCTRL_2P_IN_ORDER_SHIFT 16
216#define S5P_MSCTRL_C_INT_IN_3PLANE (0 << 15) 220#define S5P_MSCTRL_C_INT_IN_3PLANE (0 << 15)
@@ -222,11 +226,12 @@
222#define S5P_MSCTRL_FLIP_X_MIRROR (1 << 13) 226#define S5P_MSCTRL_FLIP_X_MIRROR (1 << 13)
223#define S5P_MSCTRL_FLIP_Y_MIRROR (2 << 13) 227#define S5P_MSCTRL_FLIP_Y_MIRROR (2 << 13)
224#define S5P_MSCTRL_FLIP_180 (3 << 13) 228#define S5P_MSCTRL_FLIP_180 (3 << 13)
229#define S5P_MSCTRL_FIFO_CTRL_FULL (1 << 12)
225#define S5P_MSCTRL_ORDER422_SHIFT 4 230#define S5P_MSCTRL_ORDER422_SHIFT 4
226#define S5P_MSCTRL_ORDER422_CRYCBY (0 << 4) 231#define S5P_MSCTRL_ORDER422_YCBYCR (0 << 4)
227#define S5P_MSCTRL_ORDER422_YCRYCB (1 << 4) 232#define S5P_MSCTRL_ORDER422_CBYCRY (1 << 4)
228#define S5P_MSCTRL_ORDER422_CBYCRY (2 << 4) 233#define S5P_MSCTRL_ORDER422_YCRYCB (2 << 4)
229#define S5P_MSCTRL_ORDER422_YCBYCR (3 << 4) 234#define S5P_MSCTRL_ORDER422_CRYCBY (3 << 4)
230#define S5P_MSCTRL_ORDER422_MASK (3 << 4) 235#define S5P_MSCTRL_ORDER422_MASK (3 << 4)
231#define S5P_MSCTRL_INPUT_EXTCAM (0 << 3) 236#define S5P_MSCTRL_INPUT_EXTCAM (0 << 3)
232#define S5P_MSCTRL_INPUT_MEMORY (1 << 3) 237#define S5P_MSCTRL_INPUT_MEMORY (1 << 3)
@@ -237,7 +242,7 @@
237#define S5P_MSCTRL_INFORMAT_RGB (3 << 1) 242#define S5P_MSCTRL_INFORMAT_RGB (3 << 1)
238#define S5P_MSCTRL_INFORMAT_MASK (3 << 1) 243#define S5P_MSCTRL_INFORMAT_MASK (3 << 1)
239#define S5P_MSCTRL_ENVID (1 << 0) 244#define S5P_MSCTRL_ENVID (1 << 0)
240#define S5P_MSCTRL_FRAME_COUNT(x) ((x) << 24) 245#define S5P_MSCTRL_IN_BURST_COUNT(x) ((x) << 24)
241 246
242/* Output DMA Y/Cb/Cr offset */ 247/* Output DMA Y/Cb/Cr offset */
243#define S5P_CIOYOFF 0x168 248#define S5P_CIOYOFF 0x168
@@ -263,6 +268,10 @@
263 268
264/* Real output DMA image size (extension register) */ 269/* Real output DMA image size (extension register) */
265#define S5P_CIEXTEN 0x188 270#define S5P_CIEXTEN 0x188
271#define S5P_CIEXTEN_MHRATIO_EXT(x) (((x) & 0x3f) << 10)
272#define S5P_CIEXTEN_MVRATIO_EXT(x) ((x) & 0x3f)
273#define S5P_CIEXTEN_MHRATIO_EXT_MASK (0x3f << 10)
274#define S5P_CIEXTEN_MVRATIO_EXT_MASK 0x3f
266 275
267#define S5P_CIDMAPARAM 0x18c 276#define S5P_CIDMAPARAM 0x18c
268#define S5P_CIDMAPARAM_R_LINEAR (0 << 29) 277#define S5P_CIDMAPARAM_R_LINEAR (0 << 29)
diff --git a/drivers/media/video/saa7110.c b/drivers/media/video/saa7110.c
index 7913f93979b8..99664205ef4e 100644
--- a/drivers/media/video/saa7110.c
+++ b/drivers/media/video/saa7110.c
@@ -36,6 +36,7 @@
36#include <linux/videodev2.h> 36#include <linux/videodev2.h>
37#include <media/v4l2-device.h> 37#include <media/v4l2-device.h>
38#include <media/v4l2-chip-ident.h> 38#include <media/v4l2-chip-ident.h>
39#include <media/v4l2-ctrls.h>
39 40
40MODULE_DESCRIPTION("Philips SAA7110 video decoder driver"); 41MODULE_DESCRIPTION("Philips SAA7110 video decoder driver");
41MODULE_AUTHOR("Pauline Middelink"); 42MODULE_AUTHOR("Pauline Middelink");
@@ -53,15 +54,12 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
53 54
54struct saa7110 { 55struct saa7110 {
55 struct v4l2_subdev sd; 56 struct v4l2_subdev sd;
57 struct v4l2_ctrl_handler hdl;
56 u8 reg[SAA7110_NR_REG]; 58 u8 reg[SAA7110_NR_REG];
57 59
58 v4l2_std_id norm; 60 v4l2_std_id norm;
59 int input; 61 int input;
60 int enable; 62 int enable;
61 int bright;
62 int contrast;
63 int hue;
64 int sat;
65 63
66 wait_queue_head_t wq; 64 wait_queue_head_t wq;
67}; 65};
@@ -71,6 +69,11 @@ static inline struct saa7110 *to_saa7110(struct v4l2_subdev *sd)
71 return container_of(sd, struct saa7110, sd); 69 return container_of(sd, struct saa7110, sd);
72} 70}
73 71
72static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
73{
74 return &container_of(ctrl->handler, struct saa7110, hdl)->sd;
75}
76
74/* ----------------------------------------------------------------------- */ 77/* ----------------------------------------------------------------------- */
75/* I2C support functions */ 78/* I2C support functions */
76/* ----------------------------------------------------------------------- */ 79/* ----------------------------------------------------------------------- */
@@ -326,73 +329,22 @@ static int saa7110_s_stream(struct v4l2_subdev *sd, int enable)
326 return 0; 329 return 0;
327} 330}
328 331
329static int saa7110_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 332static int saa7110_s_ctrl(struct v4l2_ctrl *ctrl)
330{
331 switch (qc->id) {
332 case V4L2_CID_BRIGHTNESS:
333 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
334 case V4L2_CID_CONTRAST:
335 case V4L2_CID_SATURATION:
336 return v4l2_ctrl_query_fill(qc, 0, 127, 1, 64);
337 case V4L2_CID_HUE:
338 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
339 default:
340 return -EINVAL;
341 }
342 return 0;
343}
344
345static int saa7110_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
346{
347 struct saa7110 *decoder = to_saa7110(sd);
348
349 switch (ctrl->id) {
350 case V4L2_CID_BRIGHTNESS:
351 ctrl->value = decoder->bright;
352 break;
353 case V4L2_CID_CONTRAST:
354 ctrl->value = decoder->contrast;
355 break;
356 case V4L2_CID_SATURATION:
357 ctrl->value = decoder->sat;
358 break;
359 case V4L2_CID_HUE:
360 ctrl->value = decoder->hue;
361 break;
362 default:
363 return -EINVAL;
364 }
365 return 0;
366}
367
368static int saa7110_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
369{ 333{
370 struct saa7110 *decoder = to_saa7110(sd); 334 struct v4l2_subdev *sd = to_sd(ctrl);
371 335
372 switch (ctrl->id) { 336 switch (ctrl->id) {
373 case V4L2_CID_BRIGHTNESS: 337 case V4L2_CID_BRIGHTNESS:
374 if (decoder->bright != ctrl->value) { 338 saa7110_write(sd, 0x19, ctrl->val);
375 decoder->bright = ctrl->value;
376 saa7110_write(sd, 0x19, decoder->bright);
377 }
378 break; 339 break;
379 case V4L2_CID_CONTRAST: 340 case V4L2_CID_CONTRAST:
380 if (decoder->contrast != ctrl->value) { 341 saa7110_write(sd, 0x13, ctrl->val);
381 decoder->contrast = ctrl->value;
382 saa7110_write(sd, 0x13, decoder->contrast);
383 }
384 break; 342 break;
385 case V4L2_CID_SATURATION: 343 case V4L2_CID_SATURATION:
386 if (decoder->sat != ctrl->value) { 344 saa7110_write(sd, 0x12, ctrl->val);
387 decoder->sat = ctrl->value;
388 saa7110_write(sd, 0x12, decoder->sat);
389 }
390 break; 345 break;
391 case V4L2_CID_HUE: 346 case V4L2_CID_HUE:
392 if (decoder->hue != ctrl->value) { 347 saa7110_write(sd, 0x07, ctrl->val);
393 decoder->hue = ctrl->value;
394 saa7110_write(sd, 0x07, decoder->hue);
395 }
396 break; 348 break;
397 default: 349 default:
398 return -EINVAL; 350 return -EINVAL;
@@ -409,11 +361,19 @@ static int saa7110_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
409 361
410/* ----------------------------------------------------------------------- */ 362/* ----------------------------------------------------------------------- */
411 363
364static const struct v4l2_ctrl_ops saa7110_ctrl_ops = {
365 .s_ctrl = saa7110_s_ctrl,
366};
367
412static const struct v4l2_subdev_core_ops saa7110_core_ops = { 368static const struct v4l2_subdev_core_ops saa7110_core_ops = {
413 .g_chip_ident = saa7110_g_chip_ident, 369 .g_chip_ident = saa7110_g_chip_ident,
414 .g_ctrl = saa7110_g_ctrl, 370 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
415 .s_ctrl = saa7110_s_ctrl, 371 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
416 .queryctrl = saa7110_queryctrl, 372 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
373 .g_ctrl = v4l2_subdev_g_ctrl,
374 .s_ctrl = v4l2_subdev_s_ctrl,
375 .queryctrl = v4l2_subdev_queryctrl,
376 .querymenu = v4l2_subdev_querymenu,
417 .s_std = saa7110_s_std, 377 .s_std = saa7110_s_std,
418}; 378};
419 379
@@ -454,10 +414,25 @@ static int saa7110_probe(struct i2c_client *client,
454 decoder->norm = V4L2_STD_PAL; 414 decoder->norm = V4L2_STD_PAL;
455 decoder->input = 0; 415 decoder->input = 0;
456 decoder->enable = 1; 416 decoder->enable = 1;
457 decoder->bright = 32768; 417 v4l2_ctrl_handler_init(&decoder->hdl, 2);
458 decoder->contrast = 32768; 418 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
459 decoder->hue = 32768; 419 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
460 decoder->sat = 32768; 420 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
421 V4L2_CID_CONTRAST, 0, 127, 1, 64);
422 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
423 V4L2_CID_SATURATION, 0, 127, 1, 64);
424 v4l2_ctrl_new_std(&decoder->hdl, &saa7110_ctrl_ops,
425 V4L2_CID_HUE, -128, 127, 1, 0);
426 sd->ctrl_handler = &decoder->hdl;
427 if (decoder->hdl.error) {
428 int err = decoder->hdl.error;
429
430 v4l2_ctrl_handler_free(&decoder->hdl);
431 kfree(decoder);
432 return err;
433 }
434 v4l2_ctrl_handler_setup(&decoder->hdl);
435
461 init_waitqueue_head(&decoder->wq); 436 init_waitqueue_head(&decoder->wq);
462 437
463 rv = saa7110_write_block(sd, initseq, sizeof(initseq)); 438 rv = saa7110_write_block(sd, initseq, sizeof(initseq));
@@ -490,9 +465,11 @@ static int saa7110_probe(struct i2c_client *client,
490static int saa7110_remove(struct i2c_client *client) 465static int saa7110_remove(struct i2c_client *client)
491{ 466{
492 struct v4l2_subdev *sd = i2c_get_clientdata(client); 467 struct v4l2_subdev *sd = i2c_get_clientdata(client);
468 struct saa7110 *decoder = to_saa7110(sd);
493 469
494 v4l2_device_unregister_subdev(sd); 470 v4l2_device_unregister_subdev(sd);
495 kfree(to_saa7110(sd)); 471 v4l2_ctrl_handler_free(&decoder->hdl);
472 kfree(decoder);
496 return 0; 473 return 0;
497} 474}
498 475
diff --git a/drivers/media/video/saa7134/Kconfig b/drivers/media/video/saa7134/Kconfig
index 380f1b28cfcc..39fc0187a747 100644
--- a/drivers/media/video/saa7134/Kconfig
+++ b/drivers/media/video/saa7134/Kconfig
@@ -28,6 +28,7 @@ config VIDEO_SAA7134_RC
28 bool "Philips SAA7134 Remote Controller support" 28 bool "Philips SAA7134 Remote Controller support"
29 depends on RC_CORE 29 depends on RC_CORE
30 depends on VIDEO_SAA7134 30 depends on VIDEO_SAA7134
31 depends on !(RC_CORE=m && VIDEO_SAA7134=y)
31 default y 32 default y
32 ---help--- 33 ---help---
33 Enables Remote Controller support on saa7134 driver. 34 Enables Remote Controller support on saa7134 driver.
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index deb8fcf4aa49..61c6007c8ea6 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -3620,6 +3620,38 @@ struct saa7134_board saa7134_boards[] = {
3620 .amux = 0, 3620 .amux = 0,
3621 }, 3621 },
3622 }, 3622 },
3623 [SAA7134_BOARD_ENCORE_ENLTV_FM3] = {
3624 .name = "Encore ENLTV-FM 3",
3625 .audio_clock = 0x02187de7,
3626 .tuner_type = TUNER_TENA_TNF_5337,
3627 .radio_type = TUNER_TEA5767,
3628 .tuner_addr = 0x61,
3629 .radio_addr = 0x60,
3630 .inputs = { {
3631 .name = name_tv,
3632 .vmux = 1,
3633 .amux = LINE2,
3634 .tv = 1,
3635 }, {
3636 .name = name_comp1,
3637 .vmux = 3,
3638 .amux = LINE1,
3639 }, {
3640 .name = name_svideo,
3641 .vmux = 8,
3642 .amux = LINE1,
3643 } },
3644 .radio = {
3645 .name = name_radio,
3646 .vmux = 1,
3647 .amux = LINE1,
3648 },
3649 .mute = {
3650 .name = name_mute,
3651 .amux = LINE1,
3652 .gpio = 0x43000,
3653 },
3654 },
3623 [SAA7134_BOARD_CINERGY_HT_PCI] = { 3655 [SAA7134_BOARD_CINERGY_HT_PCI] = {
3624 .name = "Terratec Cinergy HT PCI", 3656 .name = "Terratec Cinergy HT PCI",
3625 .audio_clock = 0x00187de7, 3657 .audio_clock = 0x00187de7,
@@ -6387,6 +6419,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6387 .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53, 6419 .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM53,
6388 }, { 6420 }, {
6389 .vendor = PCI_VENDOR_ID_PHILIPS, 6421 .vendor = PCI_VENDOR_ID_PHILIPS,
6422 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6423 .subvendor = 0x1a7f,
6424 .subdevice = 0x2108,
6425 .driver_data = SAA7134_BOARD_ENCORE_ENLTV_FM3,
6426 }, {
6427 .vendor = PCI_VENDOR_ID_PHILIPS,
6390 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, 6428 .device = PCI_DEVICE_ID_PHILIPS_SAA7133,
6391 .subvendor = 0x153b, 6429 .subvendor = 0x153b,
6392 .subdevice = 0x1175, 6430 .subdevice = 0x1175,
@@ -7102,6 +7140,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7102 case SAA7134_BOARD_ENCORE_ENLTV: 7140 case SAA7134_BOARD_ENCORE_ENLTV:
7103 case SAA7134_BOARD_ENCORE_ENLTV_FM: 7141 case SAA7134_BOARD_ENCORE_ENLTV_FM:
7104 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 7142 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
7143 case SAA7134_BOARD_ENCORE_ENLTV_FM3:
7105 case SAA7134_BOARD_10MOONSTVMASTER3: 7144 case SAA7134_BOARD_10MOONSTVMASTER3:
7106 case SAA7134_BOARD_BEHOLD_401: 7145 case SAA7134_BOARD_BEHOLD_401:
7107 case SAA7134_BOARD_BEHOLD_403: 7146 case SAA7134_BOARD_BEHOLD_403:
@@ -7294,9 +7333,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7294static void saa7134_tuner_setup(struct saa7134_dev *dev) 7333static void saa7134_tuner_setup(struct saa7134_dev *dev)
7295{ 7334{
7296 struct tuner_setup tun_setup; 7335 struct tuner_setup tun_setup;
7297 unsigned int mode_mask = T_RADIO | 7336 unsigned int mode_mask = T_RADIO | T_ANALOG_TV;
7298 T_ANALOG_TV |
7299 T_DIGITAL_TV;
7300 7337
7301 memset(&tun_setup, 0, sizeof(tun_setup)); 7338 memset(&tun_setup, 0, sizeof(tun_setup));
7302 tun_setup.tuner_callback = saa7134_tuner_callback; 7339 tun_setup.tuner_callback = saa7134_tuner_callback;
diff --git a/drivers/media/video/saa7134/saa7134-core.c b/drivers/media/video/saa7134/saa7134-core.c
index 6abeecff6da7..41f836fc93ec 100644
--- a/drivers/media/video/saa7134/saa7134-core.c
+++ b/drivers/media/video/saa7134/saa7134-core.c
@@ -752,19 +752,28 @@ static int saa7134_hwfini(struct saa7134_dev *dev)
752 return 0; 752 return 0;
753} 753}
754 754
755static void __devinit must_configure_manually(void) 755static void __devinit must_configure_manually(int has_eeprom)
756{ 756{
757 unsigned int i,p; 757 unsigned int i,p;
758 758
759 printk(KERN_WARNING 759 if (!has_eeprom)
760 "saa7134: <rant>\n" 760 printk(KERN_WARNING
761 "saa7134: Congratulations! Your TV card vendor saved a few\n" 761 "saa7134: <rant>\n"
762 "saa7134: cents for a eeprom, thus your pci board has no\n" 762 "saa7134: Congratulations! Your TV card vendor saved a few\n"
763 "saa7134: subsystem ID and I can't identify it automatically\n" 763 "saa7134: cents for a eeprom, thus your pci board has no\n"
764 "saa7134: </rant>\n" 764 "saa7134: subsystem ID and I can't identify it automatically\n"
765 "saa7134: I feel better now. Ok, here are the good news:\n" 765 "saa7134: </rant>\n"
766 "saa7134: You can use the card=<nr> insmod option to specify\n" 766 "saa7134: I feel better now. Ok, here are the good news:\n"
767 "saa7134: which board do you have. The list:\n"); 767 "saa7134: You can use the card=<nr> insmod option to specify\n"
768 "saa7134: which board do you have. The list:\n");
769 else
770 printk(KERN_WARNING
771 "saa7134: Board is currently unknown. You might try to use the card=<nr>\n"
772 "saa7134: insmod option to specify which board do you have, but this is\n"
773 "saa7134: somewhat risky, as might damage your card. It is better to ask\n"
774 "saa7134: for support at linux-media@vger.kernel.org.\n"
775 "saa7134: The supported cards are:\n");
776
768 for (i = 0; i < saa7134_bcount; i++) { 777 for (i = 0; i < saa7134_bcount; i++) {
769 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s", 778 printk(KERN_WARNING "saa7134: card=%d -> %-40.40s",
770 i,saa7134_boards[i].name); 779 i,saa7134_boards[i].name);
@@ -936,8 +945,10 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
936 if (card[dev->nr] >= 0 && 945 if (card[dev->nr] >= 0 &&
937 card[dev->nr] < saa7134_bcount) 946 card[dev->nr] < saa7134_bcount)
938 dev->board = card[dev->nr]; 947 dev->board = card[dev->nr];
939 if (SAA7134_BOARD_NOAUTO == dev->board) { 948 if (SAA7134_BOARD_UNKNOWN == dev->board)
940 must_configure_manually(); 949 must_configure_manually(0);
950 else if (SAA7134_BOARD_NOAUTO == dev->board) {
951 must_configure_manually(1);
941 dev->board = SAA7134_BOARD_UNKNOWN; 952 dev->board = SAA7134_BOARD_UNKNOWN;
942 } 953 }
943 dev->autodetected = card[dev->nr] != dev->board; 954 dev->autodetected = card[dev->nr] != dev->board;
diff --git a/drivers/media/video/saa7134/saa7134-empress.c b/drivers/media/video/saa7134/saa7134-empress.c
index 6b8459c7728e..18294db38a01 100644
--- a/drivers/media/video/saa7134/saa7134-empress.c
+++ b/drivers/media/video/saa7134/saa7134-empress.c
@@ -373,6 +373,10 @@ static int empress_queryctrl(struct file *file, void *priv,
373 static const u32 mpeg_ctrls[] = { 373 static const u32 mpeg_ctrls[] = {
374 V4L2_CID_MPEG_CLASS, 374 V4L2_CID_MPEG_CLASS,
375 V4L2_CID_MPEG_STREAM_TYPE, 375 V4L2_CID_MPEG_STREAM_TYPE,
376 V4L2_CID_MPEG_STREAM_PID_PMT,
377 V4L2_CID_MPEG_STREAM_PID_AUDIO,
378 V4L2_CID_MPEG_STREAM_PID_VIDEO,
379 V4L2_CID_MPEG_STREAM_PID_PCR,
376 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ, 380 V4L2_CID_MPEG_AUDIO_SAMPLING_FREQ,
377 V4L2_CID_MPEG_AUDIO_ENCODING, 381 V4L2_CID_MPEG_AUDIO_ENCODING,
378 V4L2_CID_MPEG_AUDIO_L2_BITRATE, 382 V4L2_CID_MPEG_AUDIO_L2_BITRATE,
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index dc646e65edb7..be1c2a2de27c 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -414,6 +414,41 @@ static int __saa7134_ir_start(void *priv)
414 if (ir->running) 414 if (ir->running)
415 return 0; 415 return 0;
416 416
417 /* Moved here from saa7134_input_init1() because the latter
418 * is not called on device resume */
419 switch (dev->board) {
420 case SAA7134_BOARD_MD2819:
421 case SAA7134_BOARD_KWORLD_VSTREAM_XPERT:
422 case SAA7134_BOARD_AVERMEDIA_305:
423 case SAA7134_BOARD_AVERMEDIA_307:
424 case SAA7134_BOARD_AVERMEDIA_STUDIO_305:
425 case SAA7134_BOARD_AVERMEDIA_STUDIO_505:
426 case SAA7134_BOARD_AVERMEDIA_STUDIO_307:
427 case SAA7134_BOARD_AVERMEDIA_STUDIO_507:
428 case SAA7134_BOARD_AVERMEDIA_STUDIO_507UA:
429 case SAA7134_BOARD_AVERMEDIA_GO_007_FM:
430 case SAA7134_BOARD_AVERMEDIA_M102:
431 case SAA7134_BOARD_AVERMEDIA_GO_007_FM_PLUS:
432 /* Without this we won't receive key up events */
433 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
434 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
435 break;
436 case SAA7134_BOARD_AVERMEDIA_777:
437 case SAA7134_BOARD_AVERMEDIA_A16AR:
438 /* Without this we won't receive key up events */
439 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
440 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
441 break;
442 case SAA7134_BOARD_AVERMEDIA_A16D:
443 /* Without this we won't receive key up events */
444 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
445 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
446 break;
447 case SAA7134_BOARD_GOTVIEW_7135:
448 saa_setb(SAA7134_GPIO_GPMODE1, 0x80);
449 break;
450 }
451
417 ir->running = true; 452 ir->running = true;
418 ir->active = false; 453 ir->active = false;
419 454
@@ -548,9 +583,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
548 mask_keycode = 0x0007C8; 583 mask_keycode = 0x0007C8;
549 mask_keydown = 0x000010; 584 mask_keydown = 0x000010;
550 polling = 50; // ms 585 polling = 50; // ms
551 /* Set GPIO pin2 to high to enable the IR controller */ 586 /* GPIO stuff moved to __saa7134_ir_start() */
552 saa_setb(SAA7134_GPIO_GPMODE0, 0x4);
553 saa_setb(SAA7134_GPIO_GPSTATUS0, 0x4);
554 break; 587 break;
555 case SAA7134_BOARD_AVERMEDIA_M135A: 588 case SAA7134_BOARD_AVERMEDIA_M135A:
556 ir_codes = RC_MAP_AVERMEDIA_M135A; 589 ir_codes = RC_MAP_AVERMEDIA_M135A;
@@ -572,18 +605,14 @@ int saa7134_input_init1(struct saa7134_dev *dev)
572 mask_keycode = 0x02F200; 605 mask_keycode = 0x02F200;
573 mask_keydown = 0x000400; 606 mask_keydown = 0x000400;
574 polling = 50; // ms 607 polling = 50; // ms
575 /* Without this we won't receive key up events */ 608 /* GPIO stuff moved to __saa7134_ir_start() */
576 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
577 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
578 break; 609 break;
579 case SAA7134_BOARD_AVERMEDIA_A16D: 610 case SAA7134_BOARD_AVERMEDIA_A16D:
580 ir_codes = RC_MAP_AVERMEDIA_A16D; 611 ir_codes = RC_MAP_AVERMEDIA_A16D;
581 mask_keycode = 0x02F200; 612 mask_keycode = 0x02F200;
582 mask_keydown = 0x000400; 613 mask_keydown = 0x000400;
583 polling = 50; /* ms */ 614 polling = 50; /* ms */
584 /* Without this we won't receive key up events */ 615 /* GPIO stuff moved to __saa7134_ir_start() */
585 saa_setb(SAA7134_GPIO_GPMODE1, 0x1);
586 saa_setb(SAA7134_GPIO_GPSTATUS1, 0x1);
587 break; 616 break;
588 case SAA7134_BOARD_KWORLD_TERMINATOR: 617 case SAA7134_BOARD_KWORLD_TERMINATOR:
589 ir_codes = RC_MAP_PIXELVIEW; 618 ir_codes = RC_MAP_PIXELVIEW;
@@ -635,7 +664,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
635 mask_keycode = 0x0003CC; 664 mask_keycode = 0x0003CC;
636 mask_keydown = 0x000010; 665 mask_keydown = 0x000010;
637 polling = 5; /* ms */ 666 polling = 5; /* ms */
638 saa_setb(SAA7134_GPIO_GPMODE1, 0x80); 667 /* GPIO stuff moved to __saa7134_ir_start() */
639 break; 668 break;
640 case SAA7134_BOARD_VIDEOMATE_TV_PVR: 669 case SAA7134_BOARD_VIDEOMATE_TV_PVR:
641 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS: 670 case SAA7134_BOARD_VIDEOMATE_GOLD_PLUS:
@@ -681,6 +710,7 @@ int saa7134_input_init1(struct saa7134_dev *dev)
681 polling = 50; // ms 710 polling = 50; // ms
682 break; 711 break;
683 case SAA7134_BOARD_ENCORE_ENLTV_FM53: 712 case SAA7134_BOARD_ENCORE_ENLTV_FM53:
713 case SAA7134_BOARD_ENCORE_ENLTV_FM3:
684 ir_codes = RC_MAP_ENCORE_ENLTV_FM53; 714 ir_codes = RC_MAP_ENCORE_ENLTV_FM53;
685 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */ 715 mask_keydown = 0x0040000; /* Enable GPIO18 line on both edges */
686 mask_keyup = 0x0040000; 716 mask_keyup = 0x0040000;
@@ -863,7 +893,7 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
863 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 893 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
864 dev->init_data.name = "HVR 1110"; 894 dev->init_data.name = "HVR 1110";
865 dev->init_data.get_key = get_key_hvr1110; 895 dev->init_data.get_key = get_key_hvr1110;
866 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE_NEW; 896 dev->init_data.ir_codes = RC_MAP_HAUPPAUGE;
867 info.addr = 0x71; 897 info.addr = 0x71;
868 break; 898 break;
869 case SAA7134_BOARD_BEHOLD_607FM_MK3: 899 case SAA7134_BOARD_BEHOLD_607FM_MK3:
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 5b0a347b0b8f..f96cd5d761f9 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -327,6 +327,7 @@ struct saa7134_card_ir {
327#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181 327#define SAA7134_BOARD_TECHNOTREND_BUDGET_T3000 181
328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182 328#define SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG 182
329#define SAA7134_BOARD_VIDEOMATE_M1F 183 329#define SAA7134_BOARD_VIDEOMATE_M1F 183
330#define SAA7134_BOARD_ENCORE_ENLTV_FM3 184
330 331
331#define SAA7134_MAXBOARDS 32 332#define SAA7134_MAXBOARDS 32
332#define SAA7134_INPUT_MAX 8 333#define SAA7134_INPUT_MAX 8
diff --git a/drivers/media/video/saa7164/saa7164-api.c b/drivers/media/video/saa7164/saa7164-api.c
index bd86d970f4c2..8a98ab68239e 100644
--- a/drivers/media/video/saa7164/saa7164-api.c
+++ b/drivers/media/video/saa7164/saa7164-api.c
@@ -743,7 +743,7 @@ int saa7164_api_configure_dif(struct saa7164_port *port, u32 std)
743int saa7164_api_initialize_dif(struct saa7164_port *port) 743int saa7164_api_initialize_dif(struct saa7164_port *port)
744{ 744{
745 struct saa7164_dev *dev = port->dev; 745 struct saa7164_dev *dev = port->dev;
746 struct saa7164_port *p = 0; 746 struct saa7164_port *p = NULL;
747 int ret = -EINVAL; 747 int ret = -EINVAL;
748 u32 std = 0; 748 u32 std = 0;
749 749
@@ -926,9 +926,9 @@ int saa7164_api_configure_port_mpeg2ps(struct saa7164_dev *dev,
926 926
927int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len) 927int saa7164_api_dump_subdevs(struct saa7164_dev *dev, u8 *buf, int len)
928{ 928{
929 struct saa7164_port *tsport = 0; 929 struct saa7164_port *tsport = NULL;
930 struct saa7164_port *encport = 0; 930 struct saa7164_port *encport = NULL;
931 struct saa7164_port *vbiport = 0; 931 struct saa7164_port *vbiport = NULL;
932 u32 idx, next_offset; 932 u32 idx, next_offset;
933 int i; 933 int i;
934 struct tmComResDescrHeader *hdr, *t; 934 struct tmComResDescrHeader *hdr, *t;
@@ -1340,7 +1340,7 @@ int saa7164_api_enum_subdevs(struct saa7164_dev *dev)
1340 1340
1341 /* Allocate enough storage for all of the descs */ 1341 /* Allocate enough storage for all of the descs */
1342 buf = kzalloc(buflen, GFP_KERNEL); 1342 buf = kzalloc(buflen, GFP_KERNEL);
1343 if (buf == NULL) 1343 if (!buf)
1344 return SAA_ERR_NO_RESOURCES; 1344 return SAA_ERR_NO_RESOURCES;
1345 1345
1346 /* Retrieve them */ 1346 /* Retrieve them */
diff --git a/drivers/media/video/saa7164/saa7164-buffer.c b/drivers/media/video/saa7164/saa7164-buffer.c
index ddd25211c9e8..66696fa8341d 100644
--- a/drivers/media/video/saa7164/saa7164-buffer.c
+++ b/drivers/media/video/saa7164/saa7164-buffer.c
@@ -93,7 +93,7 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
93 u32 len) 93 u32 len)
94{ 94{
95 struct tmHWStreamParameters *params = &port->hw_streamingparams; 95 struct tmHWStreamParameters *params = &port->hw_streamingparams;
96 struct saa7164_buffer *buf = 0; 96 struct saa7164_buffer *buf = NULL;
97 struct saa7164_dev *dev = port->dev; 97 struct saa7164_dev *dev = port->dev;
98 int i; 98 int i;
99 99
@@ -103,7 +103,7 @@ struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
103 } 103 }
104 104
105 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL); 105 buf = kzalloc(sizeof(struct saa7164_buffer), GFP_KERNEL);
106 if (buf == NULL) { 106 if (!buf) {
107 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__); 107 log_warn("%s() SAA_ERR_NO_RESOURCES\n", __func__);
108 goto ret; 108 goto ret;
109 } 109 }
@@ -157,7 +157,7 @@ fail2:
157fail1: 157fail1:
158 kfree(buf); 158 kfree(buf);
159 159
160 buf = 0; 160 buf = NULL;
161ret: 161ret:
162 return buf; 162 return buf;
163} 163}
@@ -289,14 +289,14 @@ struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
289 struct saa7164_user_buffer *buf; 289 struct saa7164_user_buffer *buf;
290 290
291 buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL); 291 buf = kzalloc(sizeof(struct saa7164_user_buffer), GFP_KERNEL);
292 if (buf == 0) 292 if (!buf)
293 return 0; 293 return NULL;
294 294
295 buf->data = kzalloc(len, GFP_KERNEL); 295 buf->data = kzalloc(len, GFP_KERNEL);
296 296
297 if (buf->data == 0) { 297 if (!buf->data) {
298 kfree(buf); 298 kfree(buf);
299 return 0; 299 return NULL;
300 } 300 }
301 301
302 buf->actual_size = len; 302 buf->actual_size = len;
@@ -315,7 +315,7 @@ void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
315 return; 315 return;
316 316
317 kfree(buf->data); 317 kfree(buf->data);
318 buf->data = 0; 318 buf->data = NULL;
319 319
320 kfree(buf); 320 kfree(buf);
321} 321}
diff --git a/drivers/media/video/saa7164/saa7164-bus.c b/drivers/media/video/saa7164/saa7164-bus.c
index b2b0d97101d0..466e1b02f91f 100644
--- a/drivers/media/video/saa7164/saa7164-bus.c
+++ b/drivers/media/video/saa7164/saa7164-bus.c
@@ -158,7 +158,7 @@ int saa7164_bus_set(struct saa7164_dev *dev, struct tmComResInfo* msg,
158 return SAA_ERR_BAD_PARAMETER; 158 return SAA_ERR_BAD_PARAMETER;
159 } 159 }
160 160
161 if ((msg->size > 0) && (buf == 0)) { 161 if ((msg->size > 0) && (buf == NULL)) {
162 printk(KERN_ERR "%s() Missing message buffer\n", __func__); 162 printk(KERN_ERR "%s() Missing message buffer\n", __func__);
163 return SAA_ERR_BAD_PARAMETER; 163 return SAA_ERR_BAD_PARAMETER;
164 } 164 }
@@ -315,7 +315,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
315 315
316 saa7164_bus_verify(dev); 316 saa7164_bus_verify(dev);
317 317
318 if (msg == 0) 318 if (msg == NULL)
319 return ret; 319 return ret;
320 320
321 if (msg->size > dev->bus.m_wMaxReqSize) { 321 if (msg->size > dev->bus.m_wMaxReqSize) {
@@ -324,7 +324,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
324 return ret; 324 return ret;
325 } 325 }
326 326
327 if ((peekonly == 0) && (msg->size > 0) && (buf == 0)) { 327 if ((peekonly == 0) && (msg->size > 0) && (buf == NULL)) {
328 printk(KERN_ERR 328 printk(KERN_ERR
329 "%s() Missing msg buf, size should be %d bytes\n", 329 "%s() Missing msg buf, size should be %d bytes\n",
330 __func__, msg->size); 330 __func__, msg->size);
@@ -392,7 +392,7 @@ int saa7164_bus_get(struct saa7164_dev *dev, struct tmComResInfo* msg,
392 392
393 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__); 393 printk(KERN_ERR "%s() Unexpected msg miss-match\n", __func__);
394 saa7164_bus_dumpmsg(dev, msg, buf); 394 saa7164_bus_dumpmsg(dev, msg, buf);
395 saa7164_bus_dumpmsg(dev, &msg_tmp, 0); 395 saa7164_bus_dumpmsg(dev, &msg_tmp, NULL);
396 ret = SAA_ERR_INVALID_COMMAND; 396 ret = SAA_ERR_INVALID_COMMAND;
397 goto out; 397 goto out;
398 } 398 }
diff --git a/drivers/media/video/saa7164/saa7164-cmd.c b/drivers/media/video/saa7164/saa7164-cmd.c
index a97ae17b36c2..6a4c217ed3a7 100644
--- a/drivers/media/video/saa7164/saa7164-cmd.c
+++ b/drivers/media/video/saa7164/saa7164-cmd.c
@@ -84,7 +84,7 @@ int saa7164_irq_dequeue(struct saa7164_dev *dev)
84{ 84{
85 int ret = SAA_OK, i = 0; 85 int ret = SAA_OK, i = 0;
86 u32 timeout; 86 u32 timeout;
87 wait_queue_head_t *q = 0; 87 wait_queue_head_t *q = NULL;
88 u8 tmp[512]; 88 u8 tmp[512];
89 dprintk(DBGLVL_CMD, "%s()\n", __func__); 89 dprintk(DBGLVL_CMD, "%s()\n", __func__);
90 90
@@ -137,7 +137,7 @@ int saa7164_cmd_dequeue(struct saa7164_dev *dev)
137 int loop = 1; 137 int loop = 1;
138 int ret; 138 int ret;
139 u32 timeout; 139 u32 timeout;
140 wait_queue_head_t *q = 0; 140 wait_queue_head_t *q = NULL;
141 u8 tmp[512]; 141 u8 tmp[512];
142 dprintk(DBGLVL_CMD, "%s()\n", __func__); 142 dprintk(DBGLVL_CMD, "%s()\n", __func__);
143 143
@@ -261,7 +261,7 @@ out:
261 */ 261 */
262int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno) 262int saa7164_cmd_wait(struct saa7164_dev *dev, u8 seqno)
263{ 263{
264 wait_queue_head_t *q = 0; 264 wait_queue_head_t *q = NULL;
265 int ret = SAA_BUS_TIMEOUT; 265 int ret = SAA_BUS_TIMEOUT;
266 unsigned long stamp; 266 unsigned long stamp;
267 int r; 267 int r;
@@ -357,7 +357,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
357 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id, 357 "sel = 0x%x)\n", __func__, saa7164_unitid_name(dev, id), id,
358 command, controlselector); 358 command, controlselector);
359 359
360 if ((size == 0) || (buf == 0)) { 360 if ((size == 0) || (buf == NULL)) {
361 printk(KERN_ERR "%s() Invalid param\n", __func__); 361 printk(KERN_ERR "%s() Invalid param\n", __func__);
362 return SAA_ERR_BAD_PARAMETER; 362 return SAA_ERR_BAD_PARAMETER;
363 } 363 }
@@ -538,7 +538,7 @@ int saa7164_cmd_send(struct saa7164_dev *dev, u8 id, enum tmComResCmd command,
538 538
539 /* Invalid */ 539 /* Invalid */
540 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__); 540 dprintk(DBGLVL_CMD, "%s() Invalid\n", __func__);
541 ret = saa7164_bus_get(dev, presponse_t, 0, 0); 541 ret = saa7164_bus_get(dev, presponse_t, NULL, 0);
542 if (ret != SAA_OK) { 542 if (ret != SAA_OK) {
543 printk(KERN_ERR "get failed\n"); 543 printk(KERN_ERR "get failed\n");
544 return ret; 544 return ret;
diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c
index 58af67f2278b..b813aec1e456 100644
--- a/drivers/media/video/saa7164/saa7164-core.c
+++ b/drivers/media/video/saa7164/saa7164-core.c
@@ -277,8 +277,8 @@ static void saa7164_histogram_print(struct saa7164_port *port,
277static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr) 277static void saa7164_work_enchandler_helper(struct saa7164_port *port, int bufnr)
278{ 278{
279 struct saa7164_dev *dev = port->dev; 279 struct saa7164_dev *dev = port->dev;
280 struct saa7164_buffer *buf = 0; 280 struct saa7164_buffer *buf = NULL;
281 struct saa7164_user_buffer *ubuf = 0; 281 struct saa7164_user_buffer *ubuf = NULL;
282 struct list_head *c, *n; 282 struct list_head *c, *n;
283 int i = 0; 283 int i = 0;
284 u8 __iomem *p; 284 u8 __iomem *p;
@@ -649,7 +649,7 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id)
649 u32 intid, intstat[INT_SIZE/4]; 649 u32 intid, intstat[INT_SIZE/4];
650 int i, handled = 0, bit; 650 int i, handled = 0, bit;
651 651
652 if (dev == 0) { 652 if (dev == NULL) {
653 printk(KERN_ERR "%s() No device specified\n", __func__); 653 printk(KERN_ERR "%s() No device specified\n", __func__);
654 handled = 0; 654 handled = 0;
655 goto out; 655 goto out;
@@ -945,7 +945,7 @@ static int get_resources(struct saa7164_dev *dev)
945 945
946static int saa7164_port_init(struct saa7164_dev *dev, int portnr) 946static int saa7164_port_init(struct saa7164_dev *dev, int portnr)
947{ 947{
948 struct saa7164_port *port = 0; 948 struct saa7164_port *port = NULL;
949 949
950 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS)) 950 if ((portnr < 0) || (portnr >= SAA7164_MAX_PORTS))
951 BUG(); 951 BUG();
diff --git a/drivers/media/video/saa7164/saa7164-dvb.c b/drivers/media/video/saa7164/saa7164-dvb.c
index b305a01b3bde..f65eab63ca87 100644
--- a/drivers/media/video/saa7164/saa7164-dvb.c
+++ b/drivers/media/video/saa7164/saa7164-dvb.c
@@ -309,8 +309,8 @@ static int dvb_register(struct saa7164_port *port)
309 309
310 port->hw_streamingparams.pitch = 188; 310 port->hw_streamingparams.pitch = 188;
311 port->hw_streamingparams.linethreshold = 0; 311 port->hw_streamingparams.linethreshold = 0;
312 port->hw_streamingparams.pagetablelistvirt = 0; 312 port->hw_streamingparams.pagetablelistvirt = NULL;
313 port->hw_streamingparams.pagetablelistphys = 0; 313 port->hw_streamingparams.pagetablelistphys = NULL;
314 port->hw_streamingparams.numpagetables = 2 + 314 port->hw_streamingparams.numpagetables = 2 +
315 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE); 315 ((SAA7164_TS_NUMBER_OF_LINES * 188) / PAGE_SIZE);
316 316
diff --git a/drivers/media/video/saa7164/saa7164-encoder.c b/drivers/media/video/saa7164/saa7164-encoder.c
index 1838408cd5cb..f9d594698832 100644
--- a/drivers/media/video/saa7164/saa7164-encoder.c
+++ b/drivers/media/video/saa7164/saa7164-encoder.c
@@ -152,8 +152,8 @@ static int saa7164_encoder_buffers_alloc(struct saa7164_port *port)
152 /* Init and establish defaults */ 152 /* Init and establish defaults */
153 params->bitspersample = 8; 153 params->bitspersample = 8;
154 params->linethreshold = 0; 154 params->linethreshold = 0;
155 params->pagetablelistvirt = 0; 155 params->pagetablelistvirt = NULL;
156 params->pagetablelistphys = 0; 156 params->pagetablelistphys = NULL;
157 params->numpagetableentries = port->hwcfg.buffercount; 157 params->numpagetableentries = port->hwcfg.buffercount;
158 158
159 /* Allocate the PCI resources, buffers (hard) */ 159 /* Allocate the PCI resources, buffers (hard) */
@@ -1108,7 +1108,7 @@ static int fops_release(struct file *file)
1108 1108
1109struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port) 1109struct saa7164_user_buffer *saa7164_enc_next_buf(struct saa7164_port *port)
1110{ 1110{
1111 struct saa7164_user_buffer *ubuf = 0; 1111 struct saa7164_user_buffer *ubuf = NULL;
1112 struct saa7164_dev *dev = port->dev; 1112 struct saa7164_dev *dev = port->dev;
1113 u32 crc; 1113 u32 crc;
1114 1114
@@ -1443,7 +1443,7 @@ int saa7164_encoder_register(struct saa7164_port *port)
1443 port->v4l_device = saa7164_encoder_alloc(port, 1443 port->v4l_device = saa7164_encoder_alloc(port,
1444 dev->pci, &saa7164_mpeg_template, "mpeg"); 1444 dev->pci, &saa7164_mpeg_template, "mpeg");
1445 1445
1446 if (port->v4l_device == NULL) { 1446 if (!port->v4l_device) {
1447 printk(KERN_INFO "%s: can't allocate mpeg device\n", 1447 printk(KERN_INFO "%s: can't allocate mpeg device\n",
1448 dev->name); 1448 dev->name);
1449 result = -ENOMEM; 1449 result = -ENOMEM;
diff --git a/drivers/media/video/saa7164/saa7164-fw.c b/drivers/media/video/saa7164/saa7164-fw.c
index ebed6f786a23..b369300cce06 100644
--- a/drivers/media/video/saa7164/saa7164-fw.c
+++ b/drivers/media/video/saa7164/saa7164-fw.c
@@ -88,7 +88,7 @@ int saa7164_downloadimage(struct saa7164_dev *dev, u8 *src, u32 srcsize,
88 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n", 88 "%s(image=%p, size=%d, flags=0x%x, dst=%p, dstsize=0x%x)\n",
89 __func__, src, srcsize, dlflags, dst, dstsize); 89 __func__, src, srcsize, dlflags, dst, dstsize);
90 90
91 if ((src == 0) || (dst == 0)) { 91 if ((src == NULL) || (dst == NULL)) {
92 ret = -EIO; 92 ret = -EIO;
93 goto out; 93 goto out;
94 } 94 }
diff --git a/drivers/media/video/saa7164/saa7164-vbi.c b/drivers/media/video/saa7164/saa7164-vbi.c
index 8abbe6d661e4..9e5b01c29cf5 100644
--- a/drivers/media/video/saa7164/saa7164-vbi.c
+++ b/drivers/media/video/saa7164/saa7164-vbi.c
@@ -123,8 +123,8 @@ static int saa7164_vbi_buffers_alloc(struct saa7164_port *port)
123 ((params->numberoflines * params->pitch) / PAGE_SIZE); 123 ((params->numberoflines * params->pitch) / PAGE_SIZE);
124 params->bitspersample = 8; 124 params->bitspersample = 8;
125 params->linethreshold = 0; 125 params->linethreshold = 0;
126 params->pagetablelistvirt = 0; 126 params->pagetablelistvirt = NULL;
127 params->pagetablelistphys = 0; 127 params->pagetablelistphys = NULL;
128 params->numpagetableentries = port->hwcfg.buffercount; 128 params->numpagetableentries = port->hwcfg.buffercount;
129 129
130 /* Allocate the PCI resources, buffers (hard) */ 130 /* Allocate the PCI resources, buffers (hard) */
@@ -1054,7 +1054,7 @@ static int fops_release(struct file *file)
1054 1054
1055struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port) 1055struct saa7164_user_buffer *saa7164_vbi_next_buf(struct saa7164_port *port)
1056{ 1056{
1057 struct saa7164_user_buffer *ubuf = 0; 1057 struct saa7164_user_buffer *ubuf = NULL;
1058 struct saa7164_dev *dev = port->dev; 1058 struct saa7164_dev *dev = port->dev;
1059 u32 crc; 1059 u32 crc;
1060 1060
@@ -1334,7 +1334,7 @@ int saa7164_vbi_register(struct saa7164_port *port)
1334 port->v4l_device = saa7164_vbi_alloc(port, 1334 port->v4l_device = saa7164_vbi_alloc(port,
1335 dev->pci, &saa7164_vbi_template, "vbi"); 1335 dev->pci, &saa7164_vbi_template, "vbi");
1336 1336
1337 if (port->v4l_device == NULL) { 1337 if (!port->v4l_device) {
1338 printk(KERN_INFO "%s: can't allocate vbi device\n", 1338 printk(KERN_INFO "%s: can't allocate vbi device\n",
1339 dev->name); 1339 dev->name);
1340 result = -ENOMEM; 1340 result = -ENOMEM;
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 954222bc3458..3fe54bf41142 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -38,7 +38,7 @@
38#include <media/v4l2-dev.h> 38#include <media/v4l2-dev.h>
39#include <media/soc_camera.h> 39#include <media/soc_camera.h>
40#include <media/sh_mobile_ceu.h> 40#include <media/sh_mobile_ceu.h>
41#include <media/videobuf-dma-contig.h> 41#include <media/videobuf2-dma-contig.h>
42#include <media/v4l2-mediabus.h> 42#include <media/v4l2-mediabus.h>
43#include <media/soc_mediabus.h> 43#include <media/soc_mediabus.h>
44 44
@@ -87,7 +87,8 @@
87 87
88/* per video frame buffer */ 88/* per video frame buffer */
89struct sh_mobile_ceu_buffer { 89struct sh_mobile_ceu_buffer {
90 struct videobuf_buffer vb; /* v4l buffer must be first */ 90 struct vb2_buffer vb; /* v4l buffer must be first */
91 struct list_head queue;
91 enum v4l2_mbus_pixelcode code; 92 enum v4l2_mbus_pixelcode code;
92}; 93};
93 94
@@ -99,16 +100,17 @@ struct sh_mobile_ceu_dev {
99 void __iomem *base; 100 void __iomem *base;
100 unsigned long video_limit; 101 unsigned long video_limit;
101 102
102 /* lock used to protect videobuf */ 103 spinlock_t lock; /* Protects video buffer lists */
103 spinlock_t lock;
104 struct list_head capture; 104 struct list_head capture;
105 struct videobuf_buffer *active; 105 struct vb2_buffer *active;
106 struct vb2_alloc_ctx *alloc_ctx;
106 107
107 struct sh_mobile_ceu_info *pdata; 108 struct sh_mobile_ceu_info *pdata;
108 109
109 u32 cflcr; 110 u32 cflcr;
110 111
111 enum v4l2_field field; 112 enum v4l2_field field;
113 int sequence;
112 114
113 unsigned int image_mode:1; 115 unsigned int image_mode:1;
114 unsigned int is_16bit:1; 116 unsigned int is_16bit:1;
@@ -133,6 +135,11 @@ struct sh_mobile_ceu_cam {
133 enum v4l2_mbus_pixelcode code; 135 enum v4l2_mbus_pixelcode code;
134}; 136};
135 137
138static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
139{
140 return container_of(vb, struct sh_mobile_ceu_buffer, vb);
141}
142
136static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev) 143static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
137{ 144{
138 unsigned long flags; 145 unsigned long flags;
@@ -205,11 +212,11 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
205/* 212/*
206 * Videobuf operations 213 * Videobuf operations
207 */ 214 */
208static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq, 215static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
209 unsigned int *count, 216 unsigned int *count, unsigned int *num_planes,
210 unsigned int *size) 217 unsigned long sizes[], void *alloc_ctxs[])
211{ 218{
212 struct soc_camera_device *icd = vq->priv_data; 219 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
213 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 220 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
214 struct sh_mobile_ceu_dev *pcdev = ici->priv; 221 struct sh_mobile_ceu_dev *pcdev = ici->priv;
215 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 222 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
@@ -218,39 +225,25 @@ static int sh_mobile_ceu_videobuf_setup(struct videobuf_queue *vq,
218 if (bytes_per_line < 0) 225 if (bytes_per_line < 0)
219 return bytes_per_line; 226 return bytes_per_line;
220 227
221 *size = bytes_per_line * icd->user_height; 228 *num_planes = 1;
229
230 pcdev->sequence = 0;
231 sizes[0] = bytes_per_line * icd->user_height;
232 alloc_ctxs[0] = pcdev->alloc_ctx;
222 233
223 if (0 == *count) 234 if (!*count)
224 *count = 2; 235 *count = 2;
225 236
226 if (pcdev->video_limit) { 237 if (pcdev->video_limit) {
227 if (PAGE_ALIGN(*size) * *count > pcdev->video_limit) 238 if (PAGE_ALIGN(sizes[0]) * *count > pcdev->video_limit)
228 *count = pcdev->video_limit / PAGE_ALIGN(*size); 239 *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]);
229 } 240 }
230 241
231 dev_dbg(icd->dev.parent, "count=%d, size=%d\n", *count, *size); 242 dev_dbg(icd->dev.parent, "count=%d, size=%lu\n", *count, sizes[0]);
232 243
233 return 0; 244 return 0;
234} 245}
235 246
236static void free_buffer(struct videobuf_queue *vq,
237 struct sh_mobile_ceu_buffer *buf)
238{
239 struct soc_camera_device *icd = vq->priv_data;
240 struct device *dev = icd->dev.parent;
241
242 dev_dbg(dev, "%s (vb=0x%p) 0x%08lx %zd\n", __func__,
243 &buf->vb, buf->vb.baddr, buf->vb.bsize);
244
245 if (in_interrupt())
246 BUG();
247
248 videobuf_waiton(vq, &buf->vb, 0, 0);
249 videobuf_dma_contig_free(vq, &buf->vb);
250 dev_dbg(dev, "%s freed\n", __func__);
251 buf->vb.state = VIDEOBUF_NEEDS_INIT;
252}
253
254#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */ 247#define CEU_CETCR_MAGIC 0x0317f313 /* acknowledge magical interrupt sources */
255#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */ 248#define CEU_CETCR_IGRW (1 << 4) /* prohibited register access interrupt bit */
256#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */ 249#define CEU_CEIER_CPEIE (1 << 0) /* one-frame capture end interrupt */
@@ -309,7 +302,8 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
309 bottom2 = CDBCR; 302 bottom2 = CDBCR;
310 } 303 }
311 304
312 phys_addr_top = videobuf_to_dma_contig(pcdev->active); 305 phys_addr_top = vb2_dma_contig_plane_paddr(pcdev->active, 0);
306
313 ceu_write(pcdev, top1, phys_addr_top); 307 ceu_write(pcdev, top1, phys_addr_top);
314 if (V4L2_FIELD_NONE != pcdev->field) { 308 if (V4L2_FIELD_NONE != pcdev->field) {
315 phys_addr_bottom = phys_addr_top + icd->user_width; 309 phys_addr_bottom = phys_addr_top + icd->user_width;
@@ -330,87 +324,67 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
330 } 324 }
331 } 325 }
332 326
333 pcdev->active->state = VIDEOBUF_ACTIVE;
334 ceu_write(pcdev, CAPSR, 0x1); /* start capture */ 327 ceu_write(pcdev, CAPSR, 0x1); /* start capture */
335 328
336 return ret; 329 return ret;
337} 330}
338 331
339static int sh_mobile_ceu_videobuf_prepare(struct videobuf_queue *vq, 332static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
340 struct videobuf_buffer *vb,
341 enum v4l2_field field)
342{ 333{
343 struct soc_camera_device *icd = vq->priv_data; 334 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
344 struct sh_mobile_ceu_buffer *buf; 335 struct sh_mobile_ceu_buffer *buf;
345 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 336 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
346 icd->current_fmt->host_fmt); 337 icd->current_fmt->host_fmt);
347 int ret; 338 unsigned long size;
348 339
349 if (bytes_per_line < 0) 340 if (bytes_per_line < 0)
350 return bytes_per_line; 341 return bytes_per_line;
351 342
352 buf = container_of(vb, struct sh_mobile_ceu_buffer, vb); 343 buf = to_ceu_vb(vb);
353 344
354 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 345 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
355 vb, vb->baddr, vb->bsize); 346 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
356 347
357 /* Added list head initialization on alloc */ 348 /* Added list head initialization on alloc */
358 WARN_ON(!list_empty(&vb->queue)); 349 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
359 350
360#ifdef DEBUG 351#ifdef DEBUG
361 /* 352 /*
362 * This can be useful if you want to see if we actually fill 353 * This can be useful if you want to see if we actually fill
363 * the buffer with something 354 * the buffer with something
364 */ 355 */
365 memset((void *)vb->baddr, 0xaa, vb->bsize); 356 if (vb2_plane_vaddr(vb, 0))
357 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
366#endif 358#endif
367 359
368 BUG_ON(NULL == icd->current_fmt); 360 BUG_ON(NULL == icd->current_fmt);
369 361
370 if (buf->code != icd->current_fmt->code || 362 size = icd->user_height * bytes_per_line;
371 vb->width != icd->user_width ||
372 vb->height != icd->user_height ||
373 vb->field != field) {
374 buf->code = icd->current_fmt->code;
375 vb->width = icd->user_width;
376 vb->height = icd->user_height;
377 vb->field = field;
378 vb->state = VIDEOBUF_NEEDS_INIT;
379 }
380 363
381 vb->size = vb->height * bytes_per_line; 364 if (vb2_plane_size(vb, 0) < size) {
382 if (0 != vb->baddr && vb->bsize < vb->size) { 365 dev_err(icd->dev.parent, "Buffer too small (%lu < %lu)\n",
383 ret = -EINVAL; 366 vb2_plane_size(vb, 0), size);
384 goto out; 367 return -ENOBUFS;
385 } 368 }
386 369
387 if (vb->state == VIDEOBUF_NEEDS_INIT) { 370 vb2_set_plane_payload(vb, 0, size);
388 ret = videobuf_iolock(vq, vb, NULL);
389 if (ret)
390 goto fail;
391 vb->state = VIDEOBUF_PREPARED;
392 }
393 371
394 return 0; 372 return 0;
395fail:
396 free_buffer(vq, buf);
397out:
398 return ret;
399} 373}
400 374
401/* Called under spinlock_irqsave(&pcdev->lock, ...) */ 375static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
402static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
403 struct videobuf_buffer *vb)
404{ 376{
405 struct soc_camera_device *icd = vq->priv_data; 377 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
406 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 378 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
407 struct sh_mobile_ceu_dev *pcdev = ici->priv; 379 struct sh_mobile_ceu_dev *pcdev = ici->priv;
380 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
381 unsigned long flags;
408 382
409 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%08lx %zd\n", __func__, 383 dev_dbg(icd->dev.parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
410 vb, vb->baddr, vb->bsize); 384 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
411 385
412 vb->state = VIDEOBUF_QUEUED; 386 spin_lock_irqsave(&pcdev->lock, flags);
413 list_add_tail(&vb->queue, &pcdev->capture); 387 list_add_tail(&buf->queue, &pcdev->capture);
414 388
415 if (!pcdev->active) { 389 if (!pcdev->active) {
416 /* 390 /*
@@ -421,13 +395,14 @@ static void sh_mobile_ceu_videobuf_queue(struct videobuf_queue *vq,
421 pcdev->active = vb; 395 pcdev->active = vb;
422 sh_mobile_ceu_capture(pcdev); 396 sh_mobile_ceu_capture(pcdev);
423 } 397 }
398 spin_unlock_irqrestore(&pcdev->lock, flags);
424} 399}
425 400
426static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq, 401static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
427 struct videobuf_buffer *vb)
428{ 402{
429 struct soc_camera_device *icd = vq->priv_data; 403 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
430 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 404 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
405 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
431 struct sh_mobile_ceu_dev *pcdev = ici->priv; 406 struct sh_mobile_ceu_dev *pcdev = ici->priv;
432 unsigned long flags; 407 unsigned long flags;
433 408
@@ -439,53 +414,60 @@ static void sh_mobile_ceu_videobuf_release(struct videobuf_queue *vq,
439 pcdev->active = NULL; 414 pcdev->active = NULL;
440 } 415 }
441 416
442 if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && 417 /* Doesn't hurt also if the list is empty */
443 !list_empty(&vb->queue)) { 418 list_del_init(&buf->queue);
444 vb->state = VIDEOBUF_ERROR;
445 list_del_init(&vb->queue);
446 }
447 419
448 spin_unlock_irqrestore(&pcdev->lock, flags); 420 spin_unlock_irqrestore(&pcdev->lock, flags);
421}
449 422
450 free_buffer(vq, container_of(vb, struct sh_mobile_ceu_buffer, vb)); 423static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
424{
425 /* This is for locking debugging only */
426 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
427 return 0;
451} 428}
452 429
453static struct videobuf_queue_ops sh_mobile_ceu_videobuf_ops = { 430static struct vb2_ops sh_mobile_ceu_videobuf_ops = {
454 .buf_setup = sh_mobile_ceu_videobuf_setup, 431 .queue_setup = sh_mobile_ceu_videobuf_setup,
455 .buf_prepare = sh_mobile_ceu_videobuf_prepare, 432 .buf_prepare = sh_mobile_ceu_videobuf_prepare,
456 .buf_queue = sh_mobile_ceu_videobuf_queue, 433 .buf_queue = sh_mobile_ceu_videobuf_queue,
457 .buf_release = sh_mobile_ceu_videobuf_release, 434 .buf_cleanup = sh_mobile_ceu_videobuf_release,
435 .buf_init = sh_mobile_ceu_videobuf_init,
436 .wait_prepare = soc_camera_unlock,
437 .wait_finish = soc_camera_lock,
458}; 438};
459 439
460static irqreturn_t sh_mobile_ceu_irq(int irq, void *data) 440static irqreturn_t sh_mobile_ceu_irq(int irq, void *data)
461{ 441{
462 struct sh_mobile_ceu_dev *pcdev = data; 442 struct sh_mobile_ceu_dev *pcdev = data;
463 struct videobuf_buffer *vb; 443 struct vb2_buffer *vb;
464 unsigned long flags; 444 int ret;
465 445
466 spin_lock_irqsave(&pcdev->lock, flags); 446 spin_lock(&pcdev->lock);
467 447
468 vb = pcdev->active; 448 vb = pcdev->active;
469 if (!vb) 449 if (!vb)
470 /* Stale interrupt from a released buffer */ 450 /* Stale interrupt from a released buffer */
471 goto out; 451 goto out;
472 452
473 list_del_init(&vb->queue); 453 list_del_init(&to_ceu_vb(vb)->queue);
474 454
475 if (!list_empty(&pcdev->capture)) 455 if (!list_empty(&pcdev->capture))
476 pcdev->active = list_entry(pcdev->capture.next, 456 pcdev->active = &list_entry(pcdev->capture.next,
477 struct videobuf_buffer, queue); 457 struct sh_mobile_ceu_buffer, queue)->vb;
478 else 458 else
479 pcdev->active = NULL; 459 pcdev->active = NULL;
480 460
481 vb->state = (sh_mobile_ceu_capture(pcdev) < 0) ? 461 ret = sh_mobile_ceu_capture(pcdev);
482 VIDEOBUF_ERROR : VIDEOBUF_DONE; 462 do_gettimeofday(&vb->v4l2_buf.timestamp);
483 do_gettimeofday(&vb->ts); 463 if (!ret) {
484 vb->field_count++; 464 vb->v4l2_buf.field = pcdev->field;
485 wake_up(&vb->done); 465 vb->v4l2_buf.sequence = pcdev->sequence++;
466 }
467 vb2_buffer_done(vb, ret < 0 ? VB2_BUF_STATE_ERROR : VB2_BUF_STATE_DONE);
486 468
487out: 469out:
488 spin_unlock_irqrestore(&pcdev->lock, flags); 470 spin_unlock(&pcdev->lock);
489 471
490 return IRQ_HANDLED; 472 return IRQ_HANDLED;
491} 473}
@@ -529,9 +511,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
529 /* make sure active buffer is canceled */ 511 /* make sure active buffer is canceled */
530 spin_lock_irqsave(&pcdev->lock, flags); 512 spin_lock_irqsave(&pcdev->lock, flags);
531 if (pcdev->active) { 513 if (pcdev->active) {
532 list_del(&pcdev->active->queue); 514 list_del_init(&to_ceu_vb(pcdev->active)->queue);
533 pcdev->active->state = VIDEOBUF_ERROR; 515 vb2_buffer_done(pcdev->active, VB2_BUF_STATE_ERROR);
534 wake_up_all(&pcdev->active->done);
535 pcdev->active = NULL; 516 pcdev->active = NULL;
536 } 517 }
537 spin_unlock_irqrestore(&pcdev->lock, flags); 518 spin_unlock_irqrestore(&pcdev->lock, flags);
@@ -686,6 +667,7 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
686 ceu_write(pcdev, CAPSR, capsr); 667 ceu_write(pcdev, CAPSR, capsr);
687} 668}
688 669
670/* Capture is not running, no interrupts, no locking needed */
689static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 671static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
690 __u32 pixfmt) 672 __u32 pixfmt)
691{ 673{
@@ -1364,7 +1346,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1364 struct device *dev = icd->dev.parent; 1346 struct device *dev = icd->dev.parent;
1365 struct v4l2_mbus_framefmt mf; 1347 struct v4l2_mbus_framefmt mf;
1366 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v, 1348 unsigned int scale_cam_h, scale_cam_v, scale_ceu_h, scale_ceu_v,
1367 out_width, out_height, scale_h, scale_v; 1349 out_width, out_height;
1368 int interm_width, interm_height; 1350 int interm_width, interm_height;
1369 u32 capsr, cflcr; 1351 u32 capsr, cflcr;
1370 int ret; 1352 int ret;
@@ -1422,10 +1404,6 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1422 scale_ceu_h = calc_scale(interm_width, &out_width); 1404 scale_ceu_h = calc_scale(interm_width, &out_width);
1423 scale_ceu_v = calc_scale(interm_height, &out_height); 1405 scale_ceu_v = calc_scale(interm_height, &out_height);
1424 1406
1425 /* Calculate camera scales */
1426 scale_h = calc_generic_scale(cam_rect->width, out_width);
1427 scale_v = calc_generic_scale(cam_rect->height, out_height);
1428
1429 dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v); 1407 dev_geo(dev, "5: CEU scales %u:%u\n", scale_ceu_h, scale_ceu_v);
1430 1408
1431 /* Apply CEU scales. */ 1409 /* Apply CEU scales. */
@@ -1437,8 +1415,8 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1437 1415
1438 icd->user_width = out_width; 1416 icd->user_width = out_width;
1439 icd->user_height = out_height; 1417 icd->user_height = out_height;
1440 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_h) & ~1; 1418 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
1441 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_v) & ~1; 1419 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
1442 1420
1443 /* 6. Use CEU cropping to crop to the new window. */ 1421 /* 6. Use CEU cropping to crop to the new window. */
1444 sh_mobile_ceu_set_rect(icd); 1422 sh_mobile_ceu_set_rect(icd);
@@ -1449,7 +1427,7 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1449 icd->user_width, icd->user_height, 1427 icd->user_width, icd->user_height,
1450 cam->ceu_left, cam->ceu_top); 1428 cam->ceu_left, cam->ceu_top);
1451 1429
1452 /* Restore capture */ 1430 /* Restore capture. The CE bit can be cleared by the hardware */
1453 if (pcdev->active) 1431 if (pcdev->active)
1454 capsr |= 1; 1432 capsr |= 1;
1455 capture_restore(pcdev, capsr); 1433 capture_restore(pcdev, capsr);
@@ -1726,43 +1704,11 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1726 return ret; 1704 return ret;
1727} 1705}
1728 1706
1729static int sh_mobile_ceu_reqbufs(struct soc_camera_device *icd,
1730 struct v4l2_requestbuffers *p)
1731{
1732 int i;
1733
1734 /*
1735 * This is for locking debugging only. I removed spinlocks and now I
1736 * check whether .prepare is ever called on a linked buffer, or whether
1737 * a dma IRQ can occur for an in-work or unlinked buffer. Until now
1738 * it hadn't triggered
1739 */
1740 for (i = 0; i < p->count; i++) {
1741 struct sh_mobile_ceu_buffer *buf;
1742
1743 buf = container_of(icd->vb_vidq.bufs[i],
1744 struct sh_mobile_ceu_buffer, vb);
1745 INIT_LIST_HEAD(&buf->vb.queue);
1746 }
1747
1748 return 0;
1749}
1750
1751static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt) 1707static unsigned int sh_mobile_ceu_poll(struct file *file, poll_table *pt)
1752{ 1708{
1753 struct soc_camera_device *icd = file->private_data; 1709 struct soc_camera_device *icd = file->private_data;
1754 struct sh_mobile_ceu_buffer *buf;
1755
1756 buf = list_entry(icd->vb_vidq.stream.next,
1757 struct sh_mobile_ceu_buffer, vb.stream);
1758
1759 poll_wait(file, &buf->vb.done, pt);
1760 1710
1761 if (buf->vb.state == VIDEOBUF_DONE || 1711 return vb2_poll(&icd->vb2_vidq, file, pt);
1762 buf->vb.state == VIDEOBUF_ERROR)
1763 return POLLIN|POLLRDNORM;
1764
1765 return 0;
1766} 1712}
1767 1713
1768static int sh_mobile_ceu_querycap(struct soc_camera_host *ici, 1714static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
@@ -1774,19 +1720,17 @@ static int sh_mobile_ceu_querycap(struct soc_camera_host *ici,
1774 return 0; 1720 return 0;
1775} 1721}
1776 1722
1777static void sh_mobile_ceu_init_videobuf(struct videobuf_queue *q, 1723static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
1778 struct soc_camera_device *icd) 1724 struct soc_camera_device *icd)
1779{ 1725{
1780 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); 1726 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1781 struct sh_mobile_ceu_dev *pcdev = ici->priv; 1727 q->io_modes = VB2_MMAP | VB2_USERPTR;
1782 1728 q->drv_priv = icd;
1783 videobuf_queue_dma_contig_init(q, 1729 q->ops = &sh_mobile_ceu_videobuf_ops;
1784 &sh_mobile_ceu_videobuf_ops, 1730 q->mem_ops = &vb2_dma_contig_memops;
1785 icd->dev.parent, &pcdev->lock, 1731 q->buf_struct_size = sizeof(struct sh_mobile_ceu_buffer);
1786 V4L2_BUF_TYPE_VIDEO_CAPTURE, 1732
1787 pcdev->field, 1733 return vb2_queue_init(q);
1788 sizeof(struct sh_mobile_ceu_buffer),
1789 icd, &icd->video_lock);
1790} 1734}
1791 1735
1792static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd, 1736static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
@@ -1850,11 +1794,10 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1850 .try_fmt = sh_mobile_ceu_try_fmt, 1794 .try_fmt = sh_mobile_ceu_try_fmt,
1851 .set_ctrl = sh_mobile_ceu_set_ctrl, 1795 .set_ctrl = sh_mobile_ceu_set_ctrl,
1852 .get_ctrl = sh_mobile_ceu_get_ctrl, 1796 .get_ctrl = sh_mobile_ceu_get_ctrl,
1853 .reqbufs = sh_mobile_ceu_reqbufs,
1854 .poll = sh_mobile_ceu_poll, 1797 .poll = sh_mobile_ceu_poll,
1855 .querycap = sh_mobile_ceu_querycap, 1798 .querycap = sh_mobile_ceu_querycap,
1856 .set_bus_param = sh_mobile_ceu_set_bus_param, 1799 .set_bus_param = sh_mobile_ceu_set_bus_param,
1857 .init_videobuf = sh_mobile_ceu_init_videobuf, 1800 .init_videobuf2 = sh_mobile_ceu_init_videobuf,
1858 .controls = sh_mobile_ceu_controls, 1801 .controls = sh_mobile_ceu_controls,
1859 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls), 1802 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls),
1860}; 1803};
@@ -2005,12 +1948,20 @@ static int __devinit sh_mobile_ceu_probe(struct platform_device *pdev)
2005 } 1948 }
2006 } 1949 }
2007 1950
1951 pcdev->alloc_ctx = vb2_dma_contig_init_ctx(&pdev->dev);
1952 if (IS_ERR(pcdev->alloc_ctx)) {
1953 err = PTR_ERR(pcdev->alloc_ctx);
1954 goto exit_module_put;
1955 }
1956
2008 err = soc_camera_host_register(&pcdev->ici); 1957 err = soc_camera_host_register(&pcdev->ici);
2009 if (err) 1958 if (err)
2010 goto exit_module_put; 1959 goto exit_free_ctx;
2011 1960
2012 return 0; 1961 return 0;
2013 1962
1963exit_free_ctx:
1964 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2014exit_module_put: 1965exit_module_put:
2015 if (csi2 && csi2->driver) 1966 if (csi2 && csi2->driver)
2016 module_put(csi2->driver->owner); 1967 module_put(csi2->driver->owner);
@@ -2041,6 +1992,7 @@ static int __devexit sh_mobile_ceu_remove(struct platform_device *pdev)
2041 if (platform_get_resource(pdev, IORESOURCE_MEM, 1)) 1992 if (platform_get_resource(pdev, IORESOURCE_MEM, 1))
2042 dma_release_declared_memory(&pdev->dev); 1993 dma_release_declared_memory(&pdev->dev);
2043 iounmap(pcdev->base); 1994 iounmap(pcdev->base);
1995 vb2_dma_contig_cleanup_ctx(pcdev->alloc_ctx);
2044 if (csi2 && csi2->driver) 1996 if (csi2 && csi2->driver)
2045 module_put(csi2->driver->owner); 1997 module_put(csi2->driver->owner);
2046 kfree(pcdev); 1998 kfree(pcdev);
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
index 84a646819318..dd1b81b1442b 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/video/sh_mobile_csi2.c
@@ -56,7 +56,7 @@ static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
56 switch (mf->code) { 56 switch (mf->code) {
57 case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */ 57 case V4L2_MBUS_FMT_UYVY8_2X8: /* YUV422 */
58 case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */ 58 case V4L2_MBUS_FMT_YUYV8_1_5X8: /* YUV420 */
59 case V4L2_MBUS_FMT_GREY8_1X8: /* RAW8 */ 59 case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */
60 case V4L2_MBUS_FMT_SBGGR8_1X8: 60 case V4L2_MBUS_FMT_SBGGR8_1X8:
61 case V4L2_MBUS_FMT_SGRBG8_1X8: 61 case V4L2_MBUS_FMT_SGRBG8_1X8:
62 break; 62 break;
@@ -67,7 +67,7 @@ static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
67 break; 67 break;
68 case SH_CSI2I: 68 case SH_CSI2I:
69 switch (mf->code) { 69 switch (mf->code) {
70 case V4L2_MBUS_FMT_GREY8_1X8: /* RAW8 */ 70 case V4L2_MBUS_FMT_Y8_1X8: /* RAW8 */
71 case V4L2_MBUS_FMT_SBGGR8_1X8: 71 case V4L2_MBUS_FMT_SBGGR8_1X8:
72 case V4L2_MBUS_FMT_SGRBG8_1X8: 72 case V4L2_MBUS_FMT_SGRBG8_1X8:
73 case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */ 73 case V4L2_MBUS_FMT_SBGGR10_1X10: /* RAW10 */
@@ -111,7 +111,7 @@ static int sh_csi2_s_fmt(struct v4l2_subdev *sd,
111 case V4L2_MBUS_FMT_RGB565_2X8_BE: 111 case V4L2_MBUS_FMT_RGB565_2X8_BE:
112 tmp |= 0x22; /* RGB565 */ 112 tmp |= 0x22; /* RGB565 */
113 break; 113 break;
114 case V4L2_MBUS_FMT_GREY8_1X8: 114 case V4L2_MBUS_FMT_Y8_1X8:
115 case V4L2_MBUS_FMT_SBGGR8_1X8: 115 case V4L2_MBUS_FMT_SBGGR8_1X8:
116 case V4L2_MBUS_FMT_SGRBG8_1X8: 116 case V4L2_MBUS_FMT_SGRBG8_1X8:
117 tmp |= 0x2a; /* RAW8 */ 117 tmp |= 0x2a; /* RAW8 */
diff --git a/drivers/media/video/sn9c102/sn9c102_core.c b/drivers/media/video/sn9c102/sn9c102_core.c
index 84984f64b234..ce56a1cdbf0a 100644
--- a/drivers/media/video/sn9c102/sn9c102_core.c
+++ b/drivers/media/video/sn9c102/sn9c102_core.c
@@ -1430,9 +1430,9 @@ static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR,
1430 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg); 1430 sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);
1431static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, 1431static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR,
1432 sn9c102_show_i2c_val, sn9c102_store_i2c_val); 1432 sn9c102_show_i2c_val, sn9c102_store_i2c_val);
1433static DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green); 1433static DEVICE_ATTR(green, S_IWUSR, NULL, sn9c102_store_green);
1434static DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue); 1434static DEVICE_ATTR(blue, S_IWUSR, NULL, sn9c102_store_blue);
1435static DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red); 1435static DEVICE_ATTR(red, S_IWUSR, NULL, sn9c102_store_red);
1436static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL); 1436static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);
1437 1437
1438 1438
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index a66811b43710..46284489e4eb 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -34,6 +34,7 @@
34#include <media/v4l2-ioctl.h> 34#include <media/v4l2-ioctl.h>
35#include <media/v4l2-dev.h> 35#include <media/v4l2-dev.h>
36#include <media/videobuf-core.h> 36#include <media/videobuf-core.h>
37#include <media/videobuf2-core.h>
37#include <media/soc_mediabus.h> 38#include <media/soc_mediabus.h>
38 39
39/* Default to VGA resolution */ 40/* Default to VGA resolution */
@@ -143,6 +144,10 @@ static int soc_camera_try_fmt_vid_cap(struct file *file, void *priv,
143 144
144 WARN_ON(priv != file->private_data); 145 WARN_ON(priv != file->private_data);
145 146
147 /* Only single-plane capture is supported so far */
148 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
149 return -EINVAL;
150
146 /* limit format to hardware capabilities */ 151 /* limit format to hardware capabilities */
147 return ici->ops->try_fmt(icd, f); 152 return ici->ops->try_fmt(icd, f);
148} 153}
@@ -191,6 +196,15 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
191 return v4l2_subdev_call(sd, core, s_std, *a); 196 return v4l2_subdev_call(sd, core, s_std, *a);
192} 197}
193 198
199static int soc_camera_enum_fsizes(struct file *file, void *fh,
200 struct v4l2_frmsizeenum *fsize)
201{
202 struct soc_camera_device *icd = file->private_data;
203 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
204
205 return ici->ops->enum_fsizes(icd, fsize);
206}
207
194static int soc_camera_reqbufs(struct file *file, void *priv, 208static int soc_camera_reqbufs(struct file *file, void *priv,
195 struct v4l2_requestbuffers *p) 209 struct v4l2_requestbuffers *p)
196{ 210{
@@ -203,11 +217,16 @@ static int soc_camera_reqbufs(struct file *file, void *priv,
203 if (icd->streamer && icd->streamer != file) 217 if (icd->streamer && icd->streamer != file)
204 return -EBUSY; 218 return -EBUSY;
205 219
206 ret = videobuf_reqbufs(&icd->vb_vidq, p); 220 if (ici->ops->init_videobuf) {
207 if (ret < 0) 221 ret = videobuf_reqbufs(&icd->vb_vidq, p);
208 return ret; 222 if (ret < 0)
223 return ret;
224
225 ret = ici->ops->reqbufs(icd, p);
226 } else {
227 ret = vb2_reqbufs(&icd->vb2_vidq, p);
228 }
209 229
210 ret = ici->ops->reqbufs(icd, p);
211 if (!ret && !icd->streamer) 230 if (!ret && !icd->streamer)
212 icd->streamer = file; 231 icd->streamer = file;
213 232
@@ -218,36 +237,48 @@ static int soc_camera_querybuf(struct file *file, void *priv,
218 struct v4l2_buffer *p) 237 struct v4l2_buffer *p)
219{ 238{
220 struct soc_camera_device *icd = file->private_data; 239 struct soc_camera_device *icd = file->private_data;
240 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
221 241
222 WARN_ON(priv != file->private_data); 242 WARN_ON(priv != file->private_data);
223 243
224 return videobuf_querybuf(&icd->vb_vidq, p); 244 if (ici->ops->init_videobuf)
245 return videobuf_querybuf(&icd->vb_vidq, p);
246 else
247 return vb2_querybuf(&icd->vb2_vidq, p);
225} 248}
226 249
227static int soc_camera_qbuf(struct file *file, void *priv, 250static int soc_camera_qbuf(struct file *file, void *priv,
228 struct v4l2_buffer *p) 251 struct v4l2_buffer *p)
229{ 252{
230 struct soc_camera_device *icd = file->private_data; 253 struct soc_camera_device *icd = file->private_data;
254 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
231 255
232 WARN_ON(priv != file->private_data); 256 WARN_ON(priv != file->private_data);
233 257
234 if (icd->streamer != file) 258 if (icd->streamer != file)
235 return -EBUSY; 259 return -EBUSY;
236 260
237 return videobuf_qbuf(&icd->vb_vidq, p); 261 if (ici->ops->init_videobuf)
262 return videobuf_qbuf(&icd->vb_vidq, p);
263 else
264 return vb2_qbuf(&icd->vb2_vidq, p);
238} 265}
239 266
240static int soc_camera_dqbuf(struct file *file, void *priv, 267static int soc_camera_dqbuf(struct file *file, void *priv,
241 struct v4l2_buffer *p) 268 struct v4l2_buffer *p)
242{ 269{
243 struct soc_camera_device *icd = file->private_data; 270 struct soc_camera_device *icd = file->private_data;
271 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
244 272
245 WARN_ON(priv != file->private_data); 273 WARN_ON(priv != file->private_data);
246 274
247 if (icd->streamer != file) 275 if (icd->streamer != file)
248 return -EBUSY; 276 return -EBUSY;
249 277
250 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK); 278 if (ici->ops->init_videobuf)
279 return videobuf_dqbuf(&icd->vb_vidq, p, file->f_flags & O_NONBLOCK);
280 else
281 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
251} 282}
252 283
253/* Always entered with .video_lock held */ 284/* Always entered with .video_lock held */
@@ -362,13 +393,12 @@ static int soc_camera_set_fmt(struct soc_camera_device *icd,
362 393
363 icd->user_width = pix->width; 394 icd->user_width = pix->width;
364 icd->user_height = pix->height; 395 icd->user_height = pix->height;
396 icd->bytesperline = pix->bytesperline;
397 icd->sizeimage = pix->sizeimage;
365 icd->colorspace = pix->colorspace; 398 icd->colorspace = pix->colorspace;
366 icd->vb_vidq.field = 399 icd->field = pix->field;
367 icd->field = pix->field; 400 if (ici->ops->init_videobuf)
368 401 icd->vb_vidq.field = pix->field;
369 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
370 dev_warn(&icd->dev, "Attention! Wrong buf-type %d\n",
371 f->type);
372 402
373 dev_dbg(&icd->dev, "set width: %d height: %d\n", 403 dev_dbg(&icd->dev, "set width: %d height: %d\n",
374 icd->user_width, icd->user_height); 404 icd->user_width, icd->user_height);
@@ -444,7 +474,13 @@ static int soc_camera_open(struct file *file)
444 if (ret < 0) 474 if (ret < 0)
445 goto esfmt; 475 goto esfmt;
446 476
447 ici->ops->init_videobuf(&icd->vb_vidq, icd); 477 if (ici->ops->init_videobuf) {
478 ici->ops->init_videobuf(&icd->vb_vidq, icd);
479 } else {
480 ret = ici->ops->init_videobuf2(&icd->vb2_vidq, icd);
481 if (ret < 0)
482 goto einitvb;
483 }
448 } 484 }
449 485
450 file->private_data = icd; 486 file->private_data = icd;
@@ -456,6 +492,7 @@ static int soc_camera_open(struct file *file)
456 * First four errors are entered with the .video_lock held 492 * First four errors are entered with the .video_lock held
457 * and use_count == 1 493 * and use_count == 1
458 */ 494 */
495einitvb:
459esfmt: 496esfmt:
460 pm_runtime_disable(&icd->vdev->dev); 497 pm_runtime_disable(&icd->vdev->dev);
461eresume: 498eresume:
@@ -482,6 +519,8 @@ static int soc_camera_close(struct file *file)
482 pm_runtime_disable(&icd->vdev->dev); 519 pm_runtime_disable(&icd->vdev->dev);
483 520
484 ici->ops->remove(icd); 521 ici->ops->remove(icd);
522 if (ici->ops->init_videobuf2)
523 vb2_queue_release(&icd->vb2_vidq);
485 524
486 soc_camera_power_set(icd, icl, 0); 525 soc_camera_power_set(icd, icl, 0);
487 } 526 }
@@ -510,6 +549,7 @@ static ssize_t soc_camera_read(struct file *file, char __user *buf,
510static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma) 549static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
511{ 550{
512 struct soc_camera_device *icd = file->private_data; 551 struct soc_camera_device *icd = file->private_data;
552 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
513 int err; 553 int err;
514 554
515 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 555 dev_dbg(&icd->dev, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
@@ -517,7 +557,10 @@ static int soc_camera_mmap(struct file *file, struct vm_area_struct *vma)
517 if (icd->streamer != file) 557 if (icd->streamer != file)
518 return -EBUSY; 558 return -EBUSY;
519 559
520 err = videobuf_mmap_mapper(&icd->vb_vidq, vma); 560 if (ici->ops->init_videobuf)
561 err = videobuf_mmap_mapper(&icd->vb_vidq, vma);
562 else
563 err = vb2_mmap(&icd->vb2_vidq, vma);
521 564
522 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n", 565 dev_dbg(&icd->dev, "vma start=0x%08lx, size=%ld, ret=%d\n",
523 (unsigned long)vma->vm_start, 566 (unsigned long)vma->vm_start,
@@ -535,7 +578,7 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
535 if (icd->streamer != file) 578 if (icd->streamer != file)
536 return -EBUSY; 579 return -EBUSY;
537 580
538 if (list_empty(&icd->vb_vidq.stream)) { 581 if (ici->ops->init_videobuf && list_empty(&icd->vb_vidq.stream)) {
539 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n"); 582 dev_err(&icd->dev, "Trying to poll with no queued buffers!\n");
540 return POLLERR; 583 return POLLERR;
541 } 584 }
@@ -543,6 +586,20 @@ static unsigned int soc_camera_poll(struct file *file, poll_table *pt)
543 return ici->ops->poll(file, pt); 586 return ici->ops->poll(file, pt);
544} 587}
545 588
589void soc_camera_lock(struct vb2_queue *vq)
590{
591 struct soc_camera_device *icd = vb2_get_drv_priv(vq);
592 mutex_lock(&icd->video_lock);
593}
594EXPORT_SYMBOL(soc_camera_lock);
595
596void soc_camera_unlock(struct vb2_queue *vq)
597{
598 struct soc_camera_device *icd = vb2_get_drv_priv(vq);
599 mutex_unlock(&icd->video_lock);
600}
601EXPORT_SYMBOL(soc_camera_unlock);
602
546static struct v4l2_file_operations soc_camera_fops = { 603static struct v4l2_file_operations soc_camera_fops = {
547 .owner = THIS_MODULE, 604 .owner = THIS_MODULE,
548 .open = soc_camera_open, 605 .open = soc_camera_open,
@@ -561,6 +618,11 @@ static int soc_camera_s_fmt_vid_cap(struct file *file, void *priv,
561 618
562 WARN_ON(priv != file->private_data); 619 WARN_ON(priv != file->private_data);
563 620
621 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) {
622 dev_warn(&icd->dev, "Wrong buf-type %d\n", f->type);
623 return -EINVAL;
624 }
625
564 if (icd->streamer && icd->streamer != file) 626 if (icd->streamer && icd->streamer != file)
565 return -EBUSY; 627 return -EBUSY;
566 628
@@ -604,16 +666,16 @@ static int soc_camera_g_fmt_vid_cap(struct file *file, void *priv,
604 666
605 WARN_ON(priv != file->private_data); 667 WARN_ON(priv != file->private_data);
606 668
669 if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
670 return -EINVAL;
671
607 pix->width = icd->user_width; 672 pix->width = icd->user_width;
608 pix->height = icd->user_height; 673 pix->height = icd->user_height;
609 pix->field = icd->vb_vidq.field; 674 pix->bytesperline = icd->bytesperline;
675 pix->sizeimage = icd->sizeimage;
676 pix->field = icd->field;
610 pix->pixelformat = icd->current_fmt->host_fmt->fourcc; 677 pix->pixelformat = icd->current_fmt->host_fmt->fourcc;
611 pix->bytesperline = soc_mbus_bytes_per_line(pix->width,
612 icd->current_fmt->host_fmt);
613 pix->colorspace = icd->colorspace; 678 pix->colorspace = icd->colorspace;
614 if (pix->bytesperline < 0)
615 return pix->bytesperline;
616 pix->sizeimage = pix->height * pix->bytesperline;
617 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n", 679 dev_dbg(&icd->dev, "current_fmt->fourcc: 0x%08x\n",
618 icd->current_fmt->host_fmt->fourcc); 680 icd->current_fmt->host_fmt->fourcc);
619 return 0; 681 return 0;
@@ -635,6 +697,7 @@ static int soc_camera_streamon(struct file *file, void *priv,
635 enum v4l2_buf_type i) 697 enum v4l2_buf_type i)
636{ 698{
637 struct soc_camera_device *icd = file->private_data; 699 struct soc_camera_device *icd = file->private_data;
700 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
638 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 701 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
639 int ret; 702 int ret;
640 703
@@ -646,10 +709,14 @@ static int soc_camera_streamon(struct file *file, void *priv,
646 if (icd->streamer != file) 709 if (icd->streamer != file)
647 return -EBUSY; 710 return -EBUSY;
648 711
649 v4l2_subdev_call(sd, video, s_stream, 1);
650
651 /* This calls buf_queue from host driver's videobuf_queue_ops */ 712 /* This calls buf_queue from host driver's videobuf_queue_ops */
652 ret = videobuf_streamon(&icd->vb_vidq); 713 if (ici->ops->init_videobuf)
714 ret = videobuf_streamon(&icd->vb_vidq);
715 else
716 ret = vb2_streamon(&icd->vb2_vidq, i);
717
718 if (!ret)
719 v4l2_subdev_call(sd, video, s_stream, 1);
653 720
654 return ret; 721 return ret;
655} 722}
@@ -659,6 +726,7 @@ static int soc_camera_streamoff(struct file *file, void *priv,
659{ 726{
660 struct soc_camera_device *icd = file->private_data; 727 struct soc_camera_device *icd = file->private_data;
661 struct v4l2_subdev *sd = soc_camera_to_subdev(icd); 728 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
729 struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
662 730
663 WARN_ON(priv != file->private_data); 731 WARN_ON(priv != file->private_data);
664 732
@@ -672,7 +740,10 @@ static int soc_camera_streamoff(struct file *file, void *priv,
672 * This calls buf_release from host driver's videobuf_queue_ops for all 740 * This calls buf_release from host driver's videobuf_queue_ops for all
673 * remaining buffers. When the last buffer is freed, stop capture 741 * remaining buffers. When the last buffer is freed, stop capture
674 */ 742 */
675 videobuf_streamoff(&icd->vb_vidq); 743 if (ici->ops->init_videobuf)
744 videobuf_streamoff(&icd->vb_vidq);
745 else
746 vb2_streamoff(&icd->vb2_vidq, i);
676 747
677 v4l2_subdev_call(sd, video, s_stream, 0); 748 v4l2_subdev_call(sd, video, s_stream, 0);
678 749
@@ -1175,6 +1246,31 @@ static int default_s_parm(struct soc_camera_device *icd,
1175 return v4l2_subdev_call(sd, video, s_parm, parm); 1246 return v4l2_subdev_call(sd, video, s_parm, parm);
1176} 1247}
1177 1248
1249static int default_enum_fsizes(struct soc_camera_device *icd,
1250 struct v4l2_frmsizeenum *fsize)
1251{
1252 int ret;
1253 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1254 const struct soc_camera_format_xlate *xlate;
1255 __u32 pixfmt = fsize->pixel_format;
1256 struct v4l2_frmsizeenum fsize_mbus = *fsize;
1257
1258 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1259 if (!xlate)
1260 return -EINVAL;
1261 /* map xlate-code to pixel_format, sensor only handle xlate-code*/
1262 fsize_mbus.pixel_format = xlate->code;
1263
1264 ret = v4l2_subdev_call(sd, video, enum_mbus_fsizes, &fsize_mbus);
1265 if (ret < 0)
1266 return ret;
1267
1268 *fsize = fsize_mbus;
1269 fsize->pixel_format = pixfmt;
1270
1271 return 0;
1272}
1273
1178static void soc_camera_device_init(struct device *dev, void *pdata) 1274static void soc_camera_device_init(struct device *dev, void *pdata)
1179{ 1275{
1180 dev->platform_data = pdata; 1276 dev->platform_data = pdata;
@@ -1192,8 +1288,9 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1192 !ici->ops->set_fmt || 1288 !ici->ops->set_fmt ||
1193 !ici->ops->set_bus_param || 1289 !ici->ops->set_bus_param ||
1194 !ici->ops->querycap || 1290 !ici->ops->querycap ||
1195 !ici->ops->init_videobuf || 1291 ((!ici->ops->init_videobuf ||
1196 !ici->ops->reqbufs || 1292 !ici->ops->reqbufs) &&
1293 !ici->ops->init_videobuf2) ||
1197 !ici->ops->add || 1294 !ici->ops->add ||
1198 !ici->ops->remove || 1295 !ici->ops->remove ||
1199 !ici->ops->poll || 1296 !ici->ops->poll ||
@@ -1210,6 +1307,8 @@ int soc_camera_host_register(struct soc_camera_host *ici)
1210 ici->ops->set_parm = default_s_parm; 1307 ici->ops->set_parm = default_s_parm;
1211 if (!ici->ops->get_parm) 1308 if (!ici->ops->get_parm)
1212 ici->ops->get_parm = default_g_parm; 1309 ici->ops->get_parm = default_g_parm;
1310 if (!ici->ops->enum_fsizes)
1311 ici->ops->enum_fsizes = default_enum_fsizes;
1213 1312
1214 mutex_lock(&list_lock); 1313 mutex_lock(&list_lock);
1215 list_for_each_entry(ix, &hosts, list) { 1314 list_for_each_entry(ix, &hosts, list) {
@@ -1317,6 +1416,7 @@ static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1317 .vidioc_g_input = soc_camera_g_input, 1416 .vidioc_g_input = soc_camera_g_input,
1318 .vidioc_s_input = soc_camera_s_input, 1417 .vidioc_s_input = soc_camera_s_input,
1319 .vidioc_s_std = soc_camera_s_std, 1418 .vidioc_s_std = soc_camera_s_std,
1419 .vidioc_enum_framesizes = soc_camera_enum_fsizes,
1320 .vidioc_reqbufs = soc_camera_reqbufs, 1420 .vidioc_reqbufs = soc_camera_reqbufs,
1321 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap, 1421 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
1322 .vidioc_querybuf = soc_camera_querybuf, 1422 .vidioc_querybuf = soc_camera_querybuf,
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index 91391214c682..ed77aa055b63 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -88,7 +88,7 @@ static const struct soc_mbus_pixelfmt mbus_fmt[] = {
88 .packing = SOC_MBUS_PACKING_EXTEND16, 88 .packing = SOC_MBUS_PACKING_EXTEND16,
89 .order = SOC_MBUS_ORDER_LE, 89 .order = SOC_MBUS_ORDER_LE,
90 }, 90 },
91 [MBUS_IDX(GREY8_1X8)] = { 91 [MBUS_IDX(Y8_1X8)] = {
92 .fourcc = V4L2_PIX_FMT_GREY, 92 .fourcc = V4L2_PIX_FMT_GREY,
93 .name = "Grey", 93 .name = "Grey",
94 .bits_per_sample = 8, 94 .bits_per_sample = 8,
@@ -132,6 +132,20 @@ static const struct soc_mbus_pixelfmt mbus_fmt[] = {
132 }, 132 },
133}; 133};
134 134
135int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf)
136{
137 switch (mf->packing) {
138 case SOC_MBUS_PACKING_NONE:
139 case SOC_MBUS_PACKING_EXTEND16:
140 return 1;
141 case SOC_MBUS_PACKING_2X8_PADHI:
142 case SOC_MBUS_PACKING_2X8_PADLO:
143 return 2;
144 }
145 return -EINVAL;
146}
147EXPORT_SYMBOL(soc_mbus_samples_per_pixel);
148
135s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) 149s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf)
136{ 150{
137 switch (mf->packing) { 151 switch (mf->packing) {
diff --git a/drivers/media/video/tlg2300/pd-video.c b/drivers/media/video/tlg2300/pd-video.c
index df33a1d188bb..a794ae62aebf 100644
--- a/drivers/media/video/tlg2300/pd-video.c
+++ b/drivers/media/video/tlg2300/pd-video.c
@@ -764,10 +764,8 @@ static int pd_vidioc_s_fmt(struct poseidon *pd, struct v4l2_pix_format *pix)
764 } 764 }
765 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL, 765 ret |= send_set_req(pd, VIDEO_ROSOLU_SEL,
766 vid_resol, &cmd_status); 766 vid_resol, &cmd_status);
767 if (ret || cmd_status) { 767 if (ret || cmd_status)
768 mutex_unlock(&pd->lock);
769 return -EBUSY; 768 return -EBUSY;
770 }
771 769
772 pix_def->pixelformat = pix->pixelformat; /* save it */ 770 pix_def->pixelformat = pix->pixelformat; /* save it */
773 pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576; 771 pix->height = (context->tvnormid & V4L2_STD_525_60) ? 480 : 576;
diff --git a/drivers/media/video/tlv320aic23b.c b/drivers/media/video/tlv320aic23b.c
index dfc4dd7c5097..286ec7e7062a 100644
--- a/drivers/media/video/tlv320aic23b.c
+++ b/drivers/media/video/tlv320aic23b.c
@@ -31,6 +31,7 @@
31#include <linux/i2c.h> 31#include <linux/i2c.h>
32#include <linux/videodev2.h> 32#include <linux/videodev2.h>
33#include <media/v4l2-device.h> 33#include <media/v4l2-device.h>
34#include <media/v4l2-ctrls.h>
34 35
35MODULE_DESCRIPTION("tlv320aic23b driver"); 36MODULE_DESCRIPTION("tlv320aic23b driver");
36MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil"); 37MODULE_AUTHOR("Scott Alfter, Ulf Eklund, Hans Verkuil");
@@ -41,7 +42,7 @@ MODULE_LICENSE("GPL");
41 42
42struct tlv320aic23b_state { 43struct tlv320aic23b_state {
43 struct v4l2_subdev sd; 44 struct v4l2_subdev sd;
44 u8 muted; 45 struct v4l2_ctrl_handler hdl;
45}; 46};
46 47
47static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd) 48static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
@@ -49,6 +50,11 @@ static inline struct tlv320aic23b_state *to_state(struct v4l2_subdev *sd)
49 return container_of(sd, struct tlv320aic23b_state, sd); 50 return container_of(sd, struct tlv320aic23b_state, sd);
50} 51}
51 52
53static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
54{
55 return &container_of(ctrl->handler, struct tlv320aic23b_state, hdl)->sd;
56}
57
52static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val) 58static int tlv320aic23b_write(struct v4l2_subdev *sd, int reg, u16 val)
53{ 59{
54 struct i2c_client *client = v4l2_get_subdevdata(sd); 60 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -85,44 +91,44 @@ static int tlv320aic23b_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
85 return 0; 91 return 0;
86} 92}
87 93
88static int tlv320aic23b_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 94static int tlv320aic23b_s_ctrl(struct v4l2_ctrl *ctrl)
89{
90 struct tlv320aic23b_state *state = to_state(sd);
91
92 if (ctrl->id != V4L2_CID_AUDIO_MUTE)
93 return -EINVAL;
94 ctrl->value = state->muted;
95 return 0;
96}
97
98static int tlv320aic23b_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
99{ 95{
100 struct tlv320aic23b_state *state = to_state(sd); 96 struct v4l2_subdev *sd = to_sd(ctrl);
101 97
102 if (ctrl->id != V4L2_CID_AUDIO_MUTE) 98 switch (ctrl->id) {
103 return -EINVAL; 99 case V4L2_CID_AUDIO_MUTE:
104 state->muted = ctrl->value; 100 tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */
105 tlv320aic23b_write(sd, 0, 0x180); /* mute both channels */ 101 /* set gain on both channels to +3.0 dB */
106 /* set gain on both channels to +3.0 dB */ 102 if (!ctrl->val)
107 if (!state->muted) 103 tlv320aic23b_write(sd, 0, 0x119);
108 tlv320aic23b_write(sd, 0, 0x119); 104 return 0;
109 return 0; 105 }
106 return -EINVAL;
110} 107}
111 108
112static int tlv320aic23b_log_status(struct v4l2_subdev *sd) 109static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
113{ 110{
114 struct tlv320aic23b_state *state = to_state(sd); 111 struct tlv320aic23b_state *state = to_state(sd);
115 112
116 v4l2_info(sd, "Input: %s\n", state->muted ? "muted" : "active"); 113 v4l2_ctrl_handler_log_status(&state->hdl, sd->name);
117 return 0; 114 return 0;
118} 115}
119 116
120/* ----------------------------------------------------------------------- */ 117/* ----------------------------------------------------------------------- */
121 118
119static const struct v4l2_ctrl_ops tlv320aic23b_ctrl_ops = {
120 .s_ctrl = tlv320aic23b_s_ctrl,
121};
122
122static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = { 123static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
123 .log_status = tlv320aic23b_log_status, 124 .log_status = tlv320aic23b_log_status,
124 .g_ctrl = tlv320aic23b_g_ctrl, 125 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
125 .s_ctrl = tlv320aic23b_s_ctrl, 126 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
127 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
128 .g_ctrl = v4l2_subdev_g_ctrl,
129 .s_ctrl = v4l2_subdev_s_ctrl,
130 .queryctrl = v4l2_subdev_queryctrl,
131 .querymenu = v4l2_subdev_querymenu,
126}; 132};
127 133
128static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = { 134static const struct v4l2_subdev_audio_ops tlv320aic23b_audio_ops = {
@@ -161,7 +167,6 @@ static int tlv320aic23b_probe(struct i2c_client *client,
161 return -ENOMEM; 167 return -ENOMEM;
162 sd = &state->sd; 168 sd = &state->sd;
163 v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops); 169 v4l2_i2c_subdev_init(sd, client, &tlv320aic23b_ops);
164 state->muted = 0;
165 170
166 /* Initialize tlv320aic23b */ 171 /* Initialize tlv320aic23b */
167 172
@@ -177,15 +182,30 @@ static int tlv320aic23b_probe(struct i2c_client *client,
177 tlv320aic23b_write(sd, 8, 0x000); 182 tlv320aic23b_write(sd, 8, 0x000);
178 /* activate digital interface */ 183 /* activate digital interface */
179 tlv320aic23b_write(sd, 9, 0x001); 184 tlv320aic23b_write(sd, 9, 0x001);
185
186 v4l2_ctrl_handler_init(&state->hdl, 1);
187 v4l2_ctrl_new_std(&state->hdl, &tlv320aic23b_ctrl_ops,
188 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
189 sd->ctrl_handler = &state->hdl;
190 if (state->hdl.error) {
191 int err = state->hdl.error;
192
193 v4l2_ctrl_handler_free(&state->hdl);
194 kfree(state);
195 return err;
196 }
197 v4l2_ctrl_handler_setup(&state->hdl);
180 return 0; 198 return 0;
181} 199}
182 200
183static int tlv320aic23b_remove(struct i2c_client *client) 201static int tlv320aic23b_remove(struct i2c_client *client)
184{ 202{
185 struct v4l2_subdev *sd = i2c_get_clientdata(client); 203 struct v4l2_subdev *sd = i2c_get_clientdata(client);
204 struct tlv320aic23b_state *state = to_state(sd);
186 205
187 v4l2_device_unregister_subdev(sd); 206 v4l2_device_unregister_subdev(sd);
188 kfree(to_state(sd)); 207 v4l2_ctrl_handler_free(&state->hdl);
208 kfree(state);
189 return 0; 209 return 0;
190} 210}
191 211
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 1cec1224913f..9363ed91a4cb 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -1,7 +1,17 @@
1/* 1/*
2 *
3 * i2c tv tuner chip device driver 2 * i2c tv tuner chip device driver
4 * core core, i.e. kernel interfaces, registering and so on 3 * core core, i.e. kernel interfaces, registering and so on
4 *
5 * Copyright(c) by Ralph Metzler, Gerd Knorr, Gunther Mayer
6 *
7 * Copyright(c) 2005-2011 by Mauro Carvalho Chehab
8 * - Added support for a separate Radio tuner
9 * - Major rework and cleanups at the code
10 *
11 * This driver supports many devices and the idea is to let the driver
12 * detect which device is present. So rather than listing all supported
13 * devices here, we pretend to support a single, fake device type that will
14 * handle both radio and analog TV tuning.
5 */ 15 */
6 16
7#include <linux/module.h> 17#include <linux/module.h>
@@ -32,9 +42,111 @@
32 42
33#define UNSET (-1U) 43#define UNSET (-1U)
34 44
35#define PREFIX t->i2c->driver->driver.name 45#define PREFIX (t->i2c->driver->driver.name)
46
47/*
48 * Driver modprobe parameters
49 */
50
51/* insmod options used at init time => read/only */
52static unsigned int addr;
53static unsigned int no_autodetect;
54static unsigned int show_i2c;
55
56module_param(addr, int, 0444);
57module_param(no_autodetect, int, 0444);
58module_param(show_i2c, int, 0444);
59
60/* insmod options used at runtime => read/write */
61static int tuner_debug;
62static unsigned int tv_range[2] = { 44, 958 };
63static unsigned int radio_range[2] = { 65, 108 };
64static char pal[] = "--";
65static char secam[] = "--";
66static char ntsc[] = "-";
67
68module_param_named(debug, tuner_debug, int, 0644);
69module_param_array(tv_range, int, NULL, 0644);
70module_param_array(radio_range, int, NULL, 0644);
71module_param_string(pal, pal, sizeof(pal), 0644);
72module_param_string(secam, secam, sizeof(secam), 0644);
73module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
74
75/*
76 * Static vars
77 */
78
79static LIST_HEAD(tuner_list);
80static const struct v4l2_subdev_ops tuner_ops;
81
82/*
83 * Debug macros
84 */
85
86#define tuner_warn(fmt, arg...) do { \
87 printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
88 i2c_adapter_id(t->i2c->adapter), \
89 t->i2c->addr, ##arg); \
90 } while (0)
91
92#define tuner_info(fmt, arg...) do { \
93 printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \
94 i2c_adapter_id(t->i2c->adapter), \
95 t->i2c->addr, ##arg); \
96 } while (0)
97
98#define tuner_err(fmt, arg...) do { \
99 printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \
100 i2c_adapter_id(t->i2c->adapter), \
101 t->i2c->addr, ##arg); \
102 } while (0)
36 103
37/** This macro allows us to probe dynamically, avoiding static links */ 104#define tuner_dbg(fmt, arg...) do { \
105 if (tuner_debug) \
106 printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \
107 i2c_adapter_id(t->i2c->adapter), \
108 t->i2c->addr, ##arg); \
109 } while (0)
110
111/*
112 * Internal struct used inside the driver
113 */
114
115struct tuner {
116 /* device */
117 struct dvb_frontend fe;
118 struct i2c_client *i2c;
119 struct v4l2_subdev sd;
120 struct list_head list;
121
122 /* keep track of the current settings */
123 v4l2_std_id std;
124 unsigned int tv_freq;
125 unsigned int radio_freq;
126 unsigned int audmode;
127
128 enum v4l2_tuner_type mode;
129 unsigned int mode_mask; /* Combination of allowable modes */
130
131 bool standby; /* Standby mode */
132
133 unsigned int type; /* chip type id */
134 unsigned int config;
135 const char *name;
136};
137
138/*
139 * Function prototypes
140 */
141
142static void set_tv_freq(struct i2c_client *c, unsigned int freq);
143static void set_radio_freq(struct i2c_client *c, unsigned int freq);
144
145/*
146 * tuner attach/detach logic
147 */
148
149/* This macro allows us to probe dynamically, avoiding static links */
38#ifdef CONFIG_MEDIA_ATTACH 150#ifdef CONFIG_MEDIA_ATTACH
39#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \ 151#define tuner_symbol_probe(FUNCTION, ARGS...) ({ \
40 int __r = -EINVAL; \ 152 int __r = -EINVAL; \
@@ -74,92 +186,15 @@ static void tuner_detach(struct dvb_frontend *fe)
74} 186}
75#endif 187#endif
76 188
77struct tuner {
78 /* device */
79 struct dvb_frontend fe;
80 struct i2c_client *i2c;
81 struct v4l2_subdev sd;
82 struct list_head list;
83 unsigned int using_v4l2:1;
84
85 /* keep track of the current settings */
86 v4l2_std_id std;
87 unsigned int tv_freq;
88 unsigned int radio_freq;
89 unsigned int audmode;
90
91 unsigned int mode;
92 unsigned int mode_mask; /* Combination of allowable modes */
93
94 unsigned int type; /* chip type id */
95 unsigned int config;
96 const char *name;
97};
98 189
99static inline struct tuner *to_tuner(struct v4l2_subdev *sd) 190static inline struct tuner *to_tuner(struct v4l2_subdev *sd)
100{ 191{
101 return container_of(sd, struct tuner, sd); 192 return container_of(sd, struct tuner, sd);
102} 193}
103 194
104 195/*
105/* insmod options used at init time => read/only */ 196 * struct analog_demod_ops callbacks
106static unsigned int addr; 197 */
107static unsigned int no_autodetect;
108static unsigned int show_i2c;
109
110/* insmod options used at runtime => read/write */
111static int tuner_debug;
112
113#define tuner_warn(fmt, arg...) do { \
114 printk(KERN_WARNING "%s %d-%04x: " fmt, PREFIX, \
115 i2c_adapter_id(t->i2c->adapter), \
116 t->i2c->addr, ##arg); \
117 } while (0)
118
119#define tuner_info(fmt, arg...) do { \
120 printk(KERN_INFO "%s %d-%04x: " fmt, PREFIX, \
121 i2c_adapter_id(t->i2c->adapter), \
122 t->i2c->addr, ##arg); \
123 } while (0)
124
125#define tuner_err(fmt, arg...) do { \
126 printk(KERN_ERR "%s %d-%04x: " fmt, PREFIX, \
127 i2c_adapter_id(t->i2c->adapter), \
128 t->i2c->addr, ##arg); \
129 } while (0)
130
131#define tuner_dbg(fmt, arg...) do { \
132 if (tuner_debug) \
133 printk(KERN_DEBUG "%s %d-%04x: " fmt, PREFIX, \
134 i2c_adapter_id(t->i2c->adapter), \
135 t->i2c->addr, ##arg); \
136 } while (0)
137
138/* ------------------------------------------------------------------------ */
139
140static unsigned int tv_range[2] = { 44, 958 };
141static unsigned int radio_range[2] = { 65, 108 };
142
143static char pal[] = "--";
144static char secam[] = "--";
145static char ntsc[] = "-";
146
147
148module_param(addr, int, 0444);
149module_param(no_autodetect, int, 0444);
150module_param(show_i2c, int, 0444);
151module_param_named(debug,tuner_debug, int, 0644);
152module_param_string(pal, pal, sizeof(pal), 0644);
153module_param_string(secam, secam, sizeof(secam), 0644);
154module_param_string(ntsc, ntsc, sizeof(ntsc), 0644);
155module_param_array(tv_range, int, NULL, 0644);
156module_param_array(radio_range, int, NULL, 0644);
157
158MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
159MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
160MODULE_LICENSE("GPL");
161
162/* ---------------------------------------------------------------------- */
163 198
164static void fe_set_params(struct dvb_frontend *fe, 199static void fe_set_params(struct dvb_frontend *fe,
165 struct analog_parameters *params) 200 struct analog_parameters *params)
@@ -215,102 +250,25 @@ static struct analog_demod_ops tuner_analog_ops = {
215 .tuner_status = tuner_status 250 .tuner_status = tuner_status
216}; 251};
217 252
218/* Set tuner frequency, freq in Units of 62.5kHz = 1/16MHz */ 253/*
219static void set_tv_freq(struct i2c_client *c, unsigned int freq) 254 * Functions to select between radio and TV and tuner probe/remove functions
220{ 255 */
221 struct tuner *t = to_tuner(i2c_get_clientdata(c));
222 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
223
224 struct analog_parameters params = {
225 .mode = t->mode,
226 .audmode = t->audmode,
227 .std = t->std
228 };
229
230 if (t->type == UNSET) {
231 tuner_warn ("tuner type not set\n");
232 return;
233 }
234 if (NULL == analog_ops->set_params) {
235 tuner_warn ("Tuner has no way to set tv freq\n");
236 return;
237 }
238 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
239 tuner_dbg ("TV freq (%d.%02d) out of range (%d-%d)\n",
240 freq / 16, freq % 16 * 100 / 16, tv_range[0],
241 tv_range[1]);
242 /* V4L2 spec: if the freq is not possible then the closest
243 possible value should be selected */
244 if (freq < tv_range[0] * 16)
245 freq = tv_range[0] * 16;
246 else
247 freq = tv_range[1] * 16;
248 }
249 params.frequency = freq;
250
251 analog_ops->set_params(&t->fe, &params);
252}
253
254static void set_radio_freq(struct i2c_client *c, unsigned int freq)
255{
256 struct tuner *t = to_tuner(i2c_get_clientdata(c));
257 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
258
259 struct analog_parameters params = {
260 .mode = t->mode,
261 .audmode = t->audmode,
262 .std = t->std
263 };
264
265 if (t->type == UNSET) {
266 tuner_warn ("tuner type not set\n");
267 return;
268 }
269 if (NULL == analog_ops->set_params) {
270 tuner_warn ("tuner has no way to set radio frequency\n");
271 return;
272 }
273 if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
274 tuner_dbg ("radio freq (%d.%02d) out of range (%d-%d)\n",
275 freq / 16000, freq % 16000 * 100 / 16000,
276 radio_range[0], radio_range[1]);
277 /* V4L2 spec: if the freq is not possible then the closest
278 possible value should be selected */
279 if (freq < radio_range[0] * 16000)
280 freq = radio_range[0] * 16000;
281 else
282 freq = radio_range[1] * 16000;
283 }
284 params.frequency = freq;
285
286 analog_ops->set_params(&t->fe, &params);
287}
288
289static void set_freq(struct i2c_client *c, unsigned long freq)
290{
291 struct tuner *t = to_tuner(i2c_get_clientdata(c));
292
293 switch (t->mode) {
294 case V4L2_TUNER_RADIO:
295 tuner_dbg("radio freq set to %lu.%02lu\n",
296 freq / 16000, freq % 16000 * 100 / 16000);
297 set_radio_freq(c, freq);
298 t->radio_freq = freq;
299 break;
300 case V4L2_TUNER_ANALOG_TV:
301 case V4L2_TUNER_DIGITAL_TV:
302 tuner_dbg("tv freq set to %lu.%02lu\n",
303 freq / 16, freq % 16 * 100 / 16);
304 set_tv_freq(c, freq);
305 t->tv_freq = freq;
306 break;
307 default:
308 tuner_dbg("freq set: unknown mode: 0x%04x!\n",t->mode);
309 }
310}
311
312static struct xc5000_config xc5000_cfg;
313 256
257/**
258 * set_type - Sets the tuner type for a given device
259 *
260 * @c: i2c_client descriptoy
261 * @type: type of the tuner (e. g. tuner number)
262 * @new_mode_mask: Indicates if tuner supports TV and/or Radio
263 * @new_config: an optional parameter ranging from 0-255 used by
264 a few tuners to adjust an internal parameter,
265 like LNA mode
266 * @tuner_callback: an optional function to be called when switching
267 * to analog mode
268 *
269 * This function applys the tuner config to tuner specified
270 * by tun_setup structure. It contains several per-tuner initialization "magic"
271 */
314static void set_type(struct i2c_client *c, unsigned int type, 272static void set_type(struct i2c_client *c, unsigned int type,
315 unsigned int new_mode_mask, unsigned int new_config, 273 unsigned int new_mode_mask, unsigned int new_config,
316 int (*tuner_callback) (void *dev, int component, int cmd, int arg)) 274 int (*tuner_callback) (void *dev, int component, int cmd, int arg))
@@ -322,7 +280,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
322 int tune_now = 1; 280 int tune_now = 1;
323 281
324 if (type == UNSET || type == TUNER_ABSENT) { 282 if (type == UNSET || type == TUNER_ABSENT) {
325 tuner_dbg ("tuner 0x%02x: Tuner type absent\n",c->addr); 283 tuner_dbg("tuner 0x%02x: Tuner type absent\n", c->addr);
326 return; 284 return;
327 } 285 }
328 286
@@ -334,12 +292,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
334 t->fe.callback = tuner_callback; 292 t->fe.callback = tuner_callback;
335 } 293 }
336 294
337 if (t->mode == T_UNINITIALIZED) {
338 tuner_dbg ("tuner 0x%02x: called during i2c_client register by adapter's attach_inform\n", c->addr);
339
340 return;
341 }
342
343 /* discard private data, in case set_type() was previously called */ 295 /* discard private data, in case set_type() was previously called */
344 tuner_detach(&t->fe); 296 tuner_detach(&t->fe);
345 t->fe.analog_demod_priv = NULL; 297 t->fe.analog_demod_priv = NULL;
@@ -414,9 +366,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
414 break; 366 break;
415 case TUNER_XC5000: 367 case TUNER_XC5000:
416 { 368 {
417 xc5000_cfg.i2c_address = t->i2c->addr; 369 struct xc5000_config xc5000_cfg = {
418 /* if_khz will be set when the digital dvb_attach() occurs */ 370 .i2c_address = t->i2c->addr,
419 xc5000_cfg.if_khz = 0; 371 /* if_khz will be set at dvb_attach() */
372 .if_khz = 0,
373 };
374
420 if (!dvb_attach(xc5000_attach, 375 if (!dvb_attach(xc5000_attach,
421 &t->fe, t->i2c->adapter, &xc5000_cfg)) 376 &t->fe, t->i2c->adapter, &xc5000_cfg))
422 goto attach_failed; 377 goto attach_failed;
@@ -459,8 +414,7 @@ static void set_type(struct i2c_client *c, unsigned int type,
459 414
460 tuner_dbg("type set to %s\n", t->name); 415 tuner_dbg("type set to %s\n", t->name);
461 416
462 if (t->mode_mask == T_UNINITIALIZED) 417 t->mode_mask = new_mode_mask;
463 t->mode_mask = new_mode_mask;
464 418
465 /* Some tuners require more initialization setup before use, 419 /* Some tuners require more initialization setup before use,
466 such as firmware download or device calibration. 420 such as firmware download or device calibration.
@@ -468,9 +422,12 @@ static void set_type(struct i2c_client *c, unsigned int type,
468 FIXME: better to move set_freq to the tuner code. This is needed 422 FIXME: better to move set_freq to the tuner code. This is needed
469 on analog tuners for PLL to properly work 423 on analog tuners for PLL to properly work
470 */ 424 */
471 if (tune_now) 425 if (tune_now) {
472 set_freq(c, (V4L2_TUNER_RADIO == t->mode) ? 426 if (V4L2_TUNER_RADIO == t->mode)
473 t->radio_freq : t->tv_freq); 427 set_radio_freq(c, t->radio_freq);
428 else
429 set_tv_freq(c, t->tv_freq);
430 }
474 431
475 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n", 432 tuner_dbg("%s %s I2C addr 0x%02x with type %d used for 0x%02x\n",
476 c->adapter->name, c->driver->driver.name, c->addr << 1, type, 433 c->adapter->name, c->driver->driver.name, c->addr << 1, type,
@@ -480,86 +437,426 @@ static void set_type(struct i2c_client *c, unsigned int type,
480attach_failed: 437attach_failed:
481 tuner_dbg("Tuner attach for type = %d failed.\n", t->type); 438 tuner_dbg("Tuner attach for type = %d failed.\n", t->type);
482 t->type = TUNER_ABSENT; 439 t->type = TUNER_ABSENT;
483 t->mode_mask = T_UNINITIALIZED;
484 440
485 return; 441 return;
486} 442}
487 443
488/* 444/**
489 * This function apply tuner config to tuner specified 445 * tuner_s_type_addr - Sets the tuner type for a device
490 * by tun_setup structure. I addr is unset, then admin status 446 *
491 * and tun addr status is more precise then current status, 447 * @sd: subdev descriptor
492 * it's applied. Otherwise status and type are applied only to 448 * @tun_setup: type to be associated to a given tuner i2c address
493 * tuner with exactly the same addr. 449 *
494*/ 450 * This function applys the tuner config to tuner specified
495 451 * by tun_setup structure.
496static void set_addr(struct i2c_client *c, struct tuner_setup *tun_setup) 452 * If tuner I2C address is UNSET, then it will only set the device
453 * if the tuner supports the mode specified in the call.
454 * If the address is specified, the change will be applied only if
455 * tuner I2C address matches.
456 * The call can change the tuner number and the tuner mode.
457 */
458static int tuner_s_type_addr(struct v4l2_subdev *sd,
459 struct tuner_setup *tun_setup)
497{ 460{
498 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 461 struct tuner *t = to_tuner(sd);
462 struct i2c_client *c = v4l2_get_subdevdata(sd);
499 463
500 if ( (t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) && 464 tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
501 (t->mode_mask & tun_setup->mode_mask))) || 465 tun_setup->type,
502 (tun_setup->addr == c->addr)) { 466 tun_setup->addr,
503 set_type(c, tun_setup->type, tun_setup->mode_mask, 467 tun_setup->mode_mask,
504 tun_setup->config, tun_setup->tuner_callback); 468 tun_setup->config);
469
470 if ((t->type == UNSET && ((tun_setup->addr == ADDR_UNSET) &&
471 (t->mode_mask & tun_setup->mode_mask))) ||
472 (tun_setup->addr == c->addr)) {
473 set_type(c, tun_setup->type, tun_setup->mode_mask,
474 tun_setup->config, tun_setup->tuner_callback);
505 } else 475 } else
506 tuner_dbg("set addr discarded for type %i, mask %x. " 476 tuner_dbg("set addr discarded for type %i, mask %x. "
507 "Asked to change tuner at addr 0x%02x, with mask %x\n", 477 "Asked to change tuner at addr 0x%02x, with mask %x\n",
508 t->type, t->mode_mask, 478 t->type, t->mode_mask,
509 tun_setup->addr, tun_setup->mode_mask); 479 tun_setup->addr, tun_setup->mode_mask);
480
481 return 0;
510} 482}
511 483
512static inline int check_mode(struct tuner *t, char *cmd) 484/**
485 * tuner_s_config - Sets tuner configuration
486 *
487 * @sd: subdev descriptor
488 * @cfg: tuner configuration
489 *
490 * Calls tuner set_config() private function to set some tuner-internal
491 * parameters
492 */
493static int tuner_s_config(struct v4l2_subdev *sd,
494 const struct v4l2_priv_tun_config *cfg)
513{ 495{
514 if ((1 << t->mode & t->mode_mask) == 0) { 496 struct tuner *t = to_tuner(sd);
515 return -EINVAL; 497 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
498
499 if (t->type != cfg->tuner)
500 return 0;
501
502 if (analog_ops->set_config) {
503 analog_ops->set_config(&t->fe, cfg->priv);
504 return 0;
516 } 505 }
517 506
518 switch (t->mode) { 507 tuner_dbg("Tuner frontend module has no way to set config\n");
519 case V4L2_TUNER_RADIO: 508 return 0;
520 tuner_dbg("Cmd %s accepted for radio\n", cmd); 509}
521 break; 510
522 case V4L2_TUNER_ANALOG_TV: 511/**
523 tuner_dbg("Cmd %s accepted for analog TV\n", cmd); 512 * tuner_lookup - Seek for tuner adapters
524 break; 513 *
525 case V4L2_TUNER_DIGITAL_TV: 514 * @adap: i2c_adapter struct
526 tuner_dbg("Cmd %s accepted for digital TV\n", cmd); 515 * @radio: pointer to be filled if the adapter is radio
527 break; 516 * @tv: pointer to be filled if the adapter is TV
517 *
518 * Search for existing radio and/or TV tuners on the given I2C adapter,
519 * discarding demod-only adapters (tda9887).
520 *
521 * Note that when this function is called from tuner_probe you can be
522 * certain no other devices will be added/deleted at the same time, I2C
523 * core protects against that.
524 */
525static void tuner_lookup(struct i2c_adapter *adap,
526 struct tuner **radio, struct tuner **tv)
527{
528 struct tuner *pos;
529
530 *radio = NULL;
531 *tv = NULL;
532
533 list_for_each_entry(pos, &tuner_list, list) {
534 int mode_mask;
535
536 if (pos->i2c->adapter != adap ||
537 strcmp(pos->i2c->driver->driver.name, "tuner"))
538 continue;
539
540 mode_mask = pos->mode_mask;
541 if (*radio == NULL && mode_mask == T_RADIO)
542 *radio = pos;
543 /* Note: currently TDA9887 is the only demod-only
544 device. If other devices appear then we need to
545 make this test more general. */
546 else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
547 (pos->mode_mask & T_ANALOG_TV))
548 *tv = pos;
549 }
550}
551
552/**
553 *tuner_probe - Probes the existing tuners on an I2C bus
554 *
555 * @client: i2c_client descriptor
556 * @id: not used
557 *
558 * This routine probes for tuners at the expected I2C addresses. On most
559 * cases, if a device answers to a given I2C address, it assumes that the
560 * device is a tuner. On a few cases, however, an additional logic is needed
561 * to double check if the device is really a tuner, or to identify the tuner
562 * type, like on tea5767/5761 devices.
563 *
564 * During client attach, set_type is called by adapter's attach_inform callback.
565 * set_type must then be completed by tuner_probe.
566 */
567static int tuner_probe(struct i2c_client *client,
568 const struct i2c_device_id *id)
569{
570 struct tuner *t;
571 struct tuner *radio;
572 struct tuner *tv;
573
574 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
575 if (NULL == t)
576 return -ENOMEM;
577 v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
578 t->i2c = client;
579 t->name = "(tuner unset)";
580 t->type = UNSET;
581 t->audmode = V4L2_TUNER_MODE_STEREO;
582 t->standby = 1;
583 t->radio_freq = 87.5 * 16000; /* Initial freq range */
584 t->tv_freq = 400 * 16; /* Sets freq to VHF High - needed for some PLL's to properly start */
585
586 if (show_i2c) {
587 unsigned char buffer[16];
588 int i, rc;
589
590 memset(buffer, 0, sizeof(buffer));
591 rc = i2c_master_recv(client, buffer, sizeof(buffer));
592 tuner_info("I2C RECV = ");
593 for (i = 0; i < rc; i++)
594 printk(KERN_CONT "%02x ", buffer[i]);
595 printk("\n");
596 }
597
598 /* autodetection code based on the i2c addr */
599 if (!no_autodetect) {
600 switch (client->addr) {
601 case 0x10:
602 if (tuner_symbol_probe(tea5761_autodetection,
603 t->i2c->adapter,
604 t->i2c->addr) >= 0) {
605 t->type = TUNER_TEA5761;
606 t->mode_mask = T_RADIO;
607 tuner_lookup(t->i2c->adapter, &radio, &tv);
608 if (tv)
609 tv->mode_mask &= ~T_RADIO;
610
611 goto register_client;
612 }
613 kfree(t);
614 return -ENODEV;
615 case 0x42:
616 case 0x43:
617 case 0x4a:
618 case 0x4b:
619 /* If chip is not tda8290, don't register.
620 since it can be tda9887*/
621 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
622 t->i2c->addr) >= 0) {
623 tuner_dbg("tda829x detected\n");
624 } else {
625 /* Default is being tda9887 */
626 t->type = TUNER_TDA9887;
627 t->mode_mask = T_RADIO | T_ANALOG_TV;
628 goto register_client;
629 }
630 break;
631 case 0x60:
632 if (tuner_symbol_probe(tea5767_autodetection,
633 t->i2c->adapter, t->i2c->addr)
634 >= 0) {
635 t->type = TUNER_TEA5767;
636 t->mode_mask = T_RADIO;
637 /* Sets freq to FM range */
638 tuner_lookup(t->i2c->adapter, &radio, &tv);
639 if (tv)
640 tv->mode_mask &= ~T_RADIO;
641
642 goto register_client;
643 }
644 break;
645 }
646 }
647
648 /* Initializes only the first TV tuner on this adapter. Why only the
649 first? Because there are some devices (notably the ones with TI
650 tuners) that have more than one i2c address for the *same* device.
651 Experience shows that, except for just one case, the first
652 address is the right one. The exception is a Russian tuner
653 (ACORP_Y878F). So, the desired behavior is just to enable the
654 first found TV tuner. */
655 tuner_lookup(t->i2c->adapter, &radio, &tv);
656 if (tv == NULL) {
657 t->mode_mask = T_ANALOG_TV;
658 if (radio == NULL)
659 t->mode_mask |= T_RADIO;
660 tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
661 }
662
663 /* Should be just before return */
664register_client:
665 /* Sets a default mode */
666 if (t->mode_mask & T_ANALOG_TV)
667 t->mode = V4L2_TUNER_ANALOG_TV;
668 else
669 t->mode = V4L2_TUNER_RADIO;
670 set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
671 list_add_tail(&t->list, &tuner_list);
672
673 tuner_info("Tuner %d found with type(s)%s%s.\n",
674 t->type,
675 t->mode_mask & T_RADIO ? " Radio" : "",
676 t->mode_mask & T_ANALOG_TV ? " TV" : "");
677 return 0;
678}
679
680/**
681 * tuner_remove - detaches a tuner
682 *
683 * @client: i2c_client descriptor
684 */
685
686static int tuner_remove(struct i2c_client *client)
687{
688 struct tuner *t = to_tuner(i2c_get_clientdata(client));
689
690 v4l2_device_unregister_subdev(&t->sd);
691 tuner_detach(&t->fe);
692 t->fe.analog_demod_priv = NULL;
693
694 list_del(&t->list);
695 kfree(t);
696 return 0;
697}
698
699/*
700 * Functions to switch between Radio and TV
701 *
702 * A few cards have a separate I2C tuner for radio. Those routines
703 * take care of switching between TV/Radio mode, filtering only the
704 * commands that apply to the Radio or TV tuner.
705 */
706
707/**
708 * check_mode - Verify if tuner supports the requested mode
709 * @t: a pointer to the module's internal struct_tuner
710 *
711 * This function checks if the tuner is capable of tuning analog TV,
712 * digital TV or radio, depending on what the caller wants. If the
713 * tuner can't support that mode, it returns -EINVAL. Otherwise, it
714 * returns 0.
715 * This function is needed for boards that have a separate tuner for
716 * radio (like devices with tea5767).
717 */
718static inline int check_mode(struct tuner *t, enum v4l2_tuner_type mode)
719{
720 if ((1 << mode & t->mode_mask) == 0)
721 return -EINVAL;
722
723 return 0;
724}
725
726/**
727 * set_mode_freq - Switch tuner to other mode.
728 * @client: struct i2c_client pointer
729 * @t: a pointer to the module's internal struct_tuner
730 * @mode: enum v4l2_type (radio or TV)
731 * @freq: frequency to set (0 means to use the previous one)
732 *
733 * If tuner doesn't support the needed mode (radio or TV), prints a
734 * debug message and returns -EINVAL, changing its state to standby.
735 * Otherwise, changes the state and sets frequency to the last value, if
736 * the tuner can sleep or if it supports both Radio and TV.
737 */
738static int set_mode_freq(struct i2c_client *client, struct tuner *t,
739 enum v4l2_tuner_type mode, unsigned int freq)
740{
741 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
742
743 if (mode != t->mode) {
744 if (check_mode(t, mode) == -EINVAL) {
745 tuner_dbg("Tuner doesn't support mode %d. "
746 "Putting tuner to sleep\n", mode);
747 t->standby = true;
748 if (analog_ops->standby)
749 analog_ops->standby(&t->fe);
750 return -EINVAL;
751 }
752 t->mode = mode;
753 tuner_dbg("Changing to mode %d\n", mode);
528 } 754 }
755 if (t->mode == V4L2_TUNER_RADIO) {
756 if (freq)
757 t->radio_freq = freq;
758 set_radio_freq(client, t->radio_freq);
759 } else {
760 if (freq)
761 t->tv_freq = freq;
762 set_tv_freq(client, t->tv_freq);
763 }
764
529 return 0; 765 return 0;
530} 766}
531 767
532/* get more precise norm info from insmod option */ 768/*
769 * Functions that are specific for TV mode
770 */
771
772/**
773 * set_tv_freq - Set tuner frequency, freq in Units of 62.5 kHz = 1/16MHz
774 *
775 * @c: i2c_client descriptor
776 * @freq: frequency
777 */
778static void set_tv_freq(struct i2c_client *c, unsigned int freq)
779{
780 struct tuner *t = to_tuner(i2c_get_clientdata(c));
781 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
782
783 struct analog_parameters params = {
784 .mode = t->mode,
785 .audmode = t->audmode,
786 .std = t->std
787 };
788
789 if (t->type == UNSET) {
790 tuner_warn("tuner type not set\n");
791 return;
792 }
793 if (NULL == analog_ops->set_params) {
794 tuner_warn("Tuner has no way to set tv freq\n");
795 return;
796 }
797 if (freq < tv_range[0] * 16 || freq > tv_range[1] * 16) {
798 tuner_dbg("TV freq (%d.%02d) out of range (%d-%d)\n",
799 freq / 16, freq % 16 * 100 / 16, tv_range[0],
800 tv_range[1]);
801 /* V4L2 spec: if the freq is not possible then the closest
802 possible value should be selected */
803 if (freq < tv_range[0] * 16)
804 freq = tv_range[0] * 16;
805 else
806 freq = tv_range[1] * 16;
807 }
808 params.frequency = freq;
809 tuner_dbg("tv freq set to %d.%02d\n",
810 freq / 16, freq % 16 * 100 / 16);
811 t->tv_freq = freq;
812 t->standby = false;
813
814 analog_ops->set_params(&t->fe, &params);
815}
816
817/**
818 * tuner_fixup_std - force a given video standard variant
819 *
820 * @t: tuner internal struct
821 *
822 * A few devices or drivers have problem to detect some standard variations.
823 * On other operational systems, the drivers generally have a per-country
824 * code, and some logic to apply per-country hacks. V4L2 API doesn't provide
825 * such hacks. Instead, it relies on a proper video standard selection from
826 * the userspace application. However, as some apps are buggy, not allowing
827 * to distinguish all video standard variations, a modprobe parameter can
828 * be used to force a video standard match.
829 */
533static int tuner_fixup_std(struct tuner *t) 830static int tuner_fixup_std(struct tuner *t)
534{ 831{
535 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) { 832 if ((t->std & V4L2_STD_PAL) == V4L2_STD_PAL) {
536 switch (pal[0]) { 833 switch (pal[0]) {
537 case '6': 834 case '6':
538 tuner_dbg ("insmod fixup: PAL => PAL-60\n"); 835 tuner_dbg("insmod fixup: PAL => PAL-60\n");
539 t->std = V4L2_STD_PAL_60; 836 t->std = V4L2_STD_PAL_60;
540 break; 837 break;
541 case 'b': 838 case 'b':
542 case 'B': 839 case 'B':
543 case 'g': 840 case 'g':
544 case 'G': 841 case 'G':
545 tuner_dbg ("insmod fixup: PAL => PAL-BG\n"); 842 tuner_dbg("insmod fixup: PAL => PAL-BG\n");
546 t->std = V4L2_STD_PAL_BG; 843 t->std = V4L2_STD_PAL_BG;
547 break; 844 break;
548 case 'i': 845 case 'i':
549 case 'I': 846 case 'I':
550 tuner_dbg ("insmod fixup: PAL => PAL-I\n"); 847 tuner_dbg("insmod fixup: PAL => PAL-I\n");
551 t->std = V4L2_STD_PAL_I; 848 t->std = V4L2_STD_PAL_I;
552 break; 849 break;
553 case 'd': 850 case 'd':
554 case 'D': 851 case 'D':
555 case 'k': 852 case 'k':
556 case 'K': 853 case 'K':
557 tuner_dbg ("insmod fixup: PAL => PAL-DK\n"); 854 tuner_dbg("insmod fixup: PAL => PAL-DK\n");
558 t->std = V4L2_STD_PAL_DK; 855 t->std = V4L2_STD_PAL_DK;
559 break; 856 break;
560 case 'M': 857 case 'M':
561 case 'm': 858 case 'm':
562 tuner_dbg ("insmod fixup: PAL => PAL-M\n"); 859 tuner_dbg("insmod fixup: PAL => PAL-M\n");
563 t->std = V4L2_STD_PAL_M; 860 t->std = V4L2_STD_PAL_M;
564 break; 861 break;
565 case 'N': 862 case 'N':
@@ -568,7 +865,7 @@ static int tuner_fixup_std(struct tuner *t)
568 tuner_dbg("insmod fixup: PAL => PAL-Nc\n"); 865 tuner_dbg("insmod fixup: PAL => PAL-Nc\n");
569 t->std = V4L2_STD_PAL_Nc; 866 t->std = V4L2_STD_PAL_Nc;
570 } else { 867 } else {
571 tuner_dbg ("insmod fixup: PAL => PAL-N\n"); 868 tuner_dbg("insmod fixup: PAL => PAL-N\n");
572 t->std = V4L2_STD_PAL_N; 869 t->std = V4L2_STD_PAL_N;
573 } 870 }
574 break; 871 break;
@@ -576,7 +873,7 @@ static int tuner_fixup_std(struct tuner *t)
576 /* default parameter, do nothing */ 873 /* default parameter, do nothing */
577 break; 874 break;
578 default: 875 default:
579 tuner_warn ("pal= argument not recognised\n"); 876 tuner_warn("pal= argument not recognised\n");
580 break; 877 break;
581 } 878 }
582 } 879 }
@@ -589,22 +886,24 @@ static int tuner_fixup_std(struct tuner *t)
589 case 'h': 886 case 'h':
590 case 'H': 887 case 'H':
591 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n"); 888 tuner_dbg("insmod fixup: SECAM => SECAM-BGH\n");
592 t->std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H; 889 t->std = V4L2_STD_SECAM_B |
890 V4L2_STD_SECAM_G |
891 V4L2_STD_SECAM_H;
593 break; 892 break;
594 case 'd': 893 case 'd':
595 case 'D': 894 case 'D':
596 case 'k': 895 case 'k':
597 case 'K': 896 case 'K':
598 tuner_dbg ("insmod fixup: SECAM => SECAM-DK\n"); 897 tuner_dbg("insmod fixup: SECAM => SECAM-DK\n");
599 t->std = V4L2_STD_SECAM_DK; 898 t->std = V4L2_STD_SECAM_DK;
600 break; 899 break;
601 case 'l': 900 case 'l':
602 case 'L': 901 case 'L':
603 if ((secam[1]=='C')||(secam[1]=='c')) { 902 if ((secam[1] == 'C') || (secam[1] == 'c')) {
604 tuner_dbg ("insmod fixup: SECAM => SECAM-L'\n"); 903 tuner_dbg("insmod fixup: SECAM => SECAM-L'\n");
605 t->std = V4L2_STD_SECAM_LC; 904 t->std = V4L2_STD_SECAM_LC;
606 } else { 905 } else {
607 tuner_dbg ("insmod fixup: SECAM => SECAM-L\n"); 906 tuner_dbg("insmod fixup: SECAM => SECAM-L\n");
608 t->std = V4L2_STD_SECAM_L; 907 t->std = V4L2_STD_SECAM_L;
609 } 908 }
610 break; 909 break;
@@ -612,7 +911,7 @@ static int tuner_fixup_std(struct tuner *t)
612 /* default parameter, do nothing */ 911 /* default parameter, do nothing */
613 break; 912 break;
614 default: 913 default:
615 tuner_warn ("secam= argument not recognised\n"); 914 tuner_warn("secam= argument not recognised\n");
616 break; 915 break;
617 } 916 }
618 } 917 }
@@ -645,6 +944,66 @@ static int tuner_fixup_std(struct tuner *t)
645 return 0; 944 return 0;
646} 945}
647 946
947/*
948 * Functions that are specific for Radio mode
949 */
950
951/**
952 * set_radio_freq - Set tuner frequency, freq in Units of 62.5 Hz = 1/16kHz
953 *
954 * @c: i2c_client descriptor
955 * @freq: frequency
956 */
957static void set_radio_freq(struct i2c_client *c, unsigned int freq)
958{
959 struct tuner *t = to_tuner(i2c_get_clientdata(c));
960 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
961
962 struct analog_parameters params = {
963 .mode = t->mode,
964 .audmode = t->audmode,
965 .std = t->std
966 };
967
968 if (t->type == UNSET) {
969 tuner_warn("tuner type not set\n");
970 return;
971 }
972 if (NULL == analog_ops->set_params) {
973 tuner_warn("tuner has no way to set radio frequency\n");
974 return;
975 }
976 if (freq < radio_range[0] * 16000 || freq > radio_range[1] * 16000) {
977 tuner_dbg("radio freq (%d.%02d) out of range (%d-%d)\n",
978 freq / 16000, freq % 16000 * 100 / 16000,
979 radio_range[0], radio_range[1]);
980 /* V4L2 spec: if the freq is not possible then the closest
981 possible value should be selected */
982 if (freq < radio_range[0] * 16000)
983 freq = radio_range[0] * 16000;
984 else
985 freq = radio_range[1] * 16000;
986 }
987 params.frequency = freq;
988 tuner_dbg("radio freq set to %d.%02d\n",
989 freq / 16000, freq % 16000 * 100 / 16000);
990 t->radio_freq = freq;
991 t->standby = false;
992
993 analog_ops->set_params(&t->fe, &params);
994}
995
996/*
997 * Debug function for reporting tuner status to userspace
998 */
999
1000/**
1001 * tuner_status - Dumps the current tuner status at dmesg
1002 * @fe: pointer to struct dvb_frontend
1003 *
1004 * This callback is used only for driver debug purposes, answering to
1005 * VIDIOC_LOG_STATUS. No changes should happen on this call.
1006 */
648static void tuner_status(struct dvb_frontend *fe) 1007static void tuner_status(struct dvb_frontend *fe)
649{ 1008{
650 struct tuner *t = fe->analog_demod_priv; 1009 struct tuner *t = fe->analog_demod_priv;
@@ -654,10 +1013,16 @@ static void tuner_status(struct dvb_frontend *fe)
654 const char *p; 1013 const char *p;
655 1014
656 switch (t->mode) { 1015 switch (t->mode) {
657 case V4L2_TUNER_RADIO: p = "radio"; break; 1016 case V4L2_TUNER_RADIO:
658 case V4L2_TUNER_ANALOG_TV: p = "analog TV"; break; 1017 p = "radio";
659 case V4L2_TUNER_DIGITAL_TV: p = "digital TV"; break; 1018 break;
660 default: p = "undefined"; break; 1019 case V4L2_TUNER_DIGITAL_TV:
1020 p = "digital TV";
1021 break;
1022 case V4L2_TUNER_ANALOG_TV:
1023 default:
1024 p = "analog TV";
1025 break;
661 } 1026 }
662 if (t->mode == V4L2_TUNER_RADIO) { 1027 if (t->mode == V4L2_TUNER_RADIO) {
663 freq = t->radio_freq / 16000; 1028 freq = t->radio_freq / 16000;
@@ -666,11 +1031,12 @@ static void tuner_status(struct dvb_frontend *fe)
666 freq = t->tv_freq / 16; 1031 freq = t->tv_freq / 16;
667 freq_fraction = (t->tv_freq % 16) * 100 / 16; 1032 freq_fraction = (t->tv_freq % 16) * 100 / 16;
668 } 1033 }
669 tuner_info("Tuner mode: %s\n", p); 1034 tuner_info("Tuner mode: %s%s\n", p,
1035 t->standby ? " on standby mode" : "");
670 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction); 1036 tuner_info("Frequency: %lu.%02lu MHz\n", freq, freq_fraction);
671 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std); 1037 tuner_info("Standard: 0x%08lx\n", (unsigned long)t->std);
672 if (t->mode != V4L2_TUNER_RADIO) 1038 if (t->mode != V4L2_TUNER_RADIO)
673 return; 1039 return;
674 if (fe_tuner_ops->get_status) { 1040 if (fe_tuner_ops->get_status) {
675 u32 tuner_status; 1041 u32 tuner_status;
676 1042
@@ -683,132 +1049,58 @@ static void tuner_status(struct dvb_frontend *fe)
683 if (analog_ops->has_signal) 1049 if (analog_ops->has_signal)
684 tuner_info("Signal strength: %d\n", 1050 tuner_info("Signal strength: %d\n",
685 analog_ops->has_signal(fe)); 1051 analog_ops->has_signal(fe));
686 if (analog_ops->is_stereo)
687 tuner_info("Stereo: %s\n",
688 analog_ops->is_stereo(fe) ? "yes" : "no");
689} 1052}
690 1053
691/* ---------------------------------------------------------------------- */
692
693/* 1054/*
694 * Switch tuner to other mode. If tuner support both tv and radio, 1055 * Function to splicitly change mode to radio. Probably not needed anymore
695 * set another frequency to some value (This is needed for some pal
696 * tuners to avoid locking). Otherwise, just put second tuner in
697 * standby mode.
698 */ 1056 */
699 1057
700static inline int set_mode(struct i2c_client *client, struct tuner *t, int mode, char *cmd)
701{
702 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
703
704 if (mode == t->mode)
705 return 0;
706
707 t->mode = mode;
708
709 if (check_mode(t, cmd) == -EINVAL) {
710 tuner_dbg("Tuner doesn't support this mode. "
711 "Putting tuner to sleep\n");
712 t->mode = T_STANDBY;
713 if (analog_ops->standby)
714 analog_ops->standby(&t->fe);
715 return -EINVAL;
716 }
717 return 0;
718}
719
720#define switch_v4l2() if (!t->using_v4l2) \
721 tuner_dbg("switching to v4l2\n"); \
722 t->using_v4l2 = 1;
723
724static inline int check_v4l2(struct tuner *t)
725{
726 /* bttv still uses both v4l1 and v4l2 calls to the tuner (v4l2 for
727 TV, v4l1 for radio), until that is fixed this code is disabled.
728 Otherwise the radio (v4l1) wouldn't tune after using the TV (v4l2)
729 first. */
730 return 0;
731}
732
733static int tuner_s_type_addr(struct v4l2_subdev *sd, struct tuner_setup *type)
734{
735 struct tuner *t = to_tuner(sd);
736 struct i2c_client *client = v4l2_get_subdevdata(sd);
737
738 tuner_dbg("Calling set_type_addr for type=%d, addr=0x%02x, mode=0x%02x, config=0x%02x\n",
739 type->type,
740 type->addr,
741 type->mode_mask,
742 type->config);
743
744 set_addr(client, type);
745 return 0;
746}
747
748static int tuner_s_radio(struct v4l2_subdev *sd) 1058static int tuner_s_radio(struct v4l2_subdev *sd)
749{ 1059{
750 struct tuner *t = to_tuner(sd); 1060 struct tuner *t = to_tuner(sd);
751 struct i2c_client *client = v4l2_get_subdevdata(sd); 1061 struct i2c_client *client = v4l2_get_subdevdata(sd);
752 1062
753 if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL) 1063 if (set_mode_freq(client, t, V4L2_TUNER_RADIO, 0) == -EINVAL)
754 return 0; 1064 return 0;
755 if (t->radio_freq)
756 set_freq(client, t->radio_freq);
757 return 0; 1065 return 0;
758} 1066}
759 1067
1068/*
1069 * Tuner callbacks to handle userspace ioctl's
1070 */
1071
1072/**
1073 * tuner_s_power - controls the power state of the tuner
1074 * @sd: pointer to struct v4l2_subdev
1075 * @on: a zero value puts the tuner to sleep
1076 */
760static int tuner_s_power(struct v4l2_subdev *sd, int on) 1077static int tuner_s_power(struct v4l2_subdev *sd, int on)
761{ 1078{
762 struct tuner *t = to_tuner(sd); 1079 struct tuner *t = to_tuner(sd);
763 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1080 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
764 1081
1082 /* FIXME: Why this function don't wake the tuner if on != 0 ? */
765 if (on) 1083 if (on)
766 return 0; 1084 return 0;
767 1085
768 tuner_dbg("Putting tuner to sleep\n"); 1086 tuner_dbg("Putting tuner to sleep\n");
769 1087 t->standby = true;
770 if (check_mode(t, "s_power") == -EINVAL)
771 return 0;
772 t->mode = T_STANDBY;
773 if (analog_ops->standby) 1088 if (analog_ops->standby)
774 analog_ops->standby(&t->fe); 1089 analog_ops->standby(&t->fe);
775 return 0; 1090 return 0;
776} 1091}
777 1092
778static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
779{
780 struct tuner *t = to_tuner(sd);
781 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
782
783 if (t->type != cfg->tuner)
784 return 0;
785
786 if (analog_ops->set_config) {
787 analog_ops->set_config(&t->fe, cfg->priv);
788 return 0;
789 }
790
791 tuner_dbg("Tuner frontend module has no way to set config\n");
792 return 0;
793}
794
795/* --- v4l ioctls --- */
796/* take care: bttv does userspace copying, we'll get a
797 kernel pointer here... */
798static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std) 1093static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
799{ 1094{
800 struct tuner *t = to_tuner(sd); 1095 struct tuner *t = to_tuner(sd);
801 struct i2c_client *client = v4l2_get_subdevdata(sd); 1096 struct i2c_client *client = v4l2_get_subdevdata(sd);
802 1097
803 if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL) 1098 if (set_mode_freq(client, t, V4L2_TUNER_ANALOG_TV, 0) == -EINVAL)
804 return 0; 1099 return 0;
805 1100
806 switch_v4l2();
807
808 t->std = std; 1101 t->std = std;
809 tuner_fixup_std(t); 1102 tuner_fixup_std(t);
810 if (t->tv_freq) 1103
811 set_freq(client, t->tv_freq);
812 return 0; 1104 return 0;
813} 1105}
814 1106
@@ -817,10 +1109,8 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
817 struct tuner *t = to_tuner(sd); 1109 struct tuner *t = to_tuner(sd);
818 struct i2c_client *client = v4l2_get_subdevdata(sd); 1110 struct i2c_client *client = v4l2_get_subdevdata(sd);
819 1111
820 if (set_mode(client, t, f->type, "s_frequency") == -EINVAL) 1112 if (set_mode_freq(client, t, f->type, f->frequency) == -EINVAL)
821 return 0; 1113 return 0;
822 switch_v4l2();
823 set_freq(client, f->frequency);
824 1114
825 return 0; 1115 return 0;
826} 1116}
@@ -830,21 +1120,20 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
830 struct tuner *t = to_tuner(sd); 1120 struct tuner *t = to_tuner(sd);
831 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 1121 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
832 1122
833 if (check_mode(t, "g_frequency") == -EINVAL) 1123 if (check_mode(t, f->type) == -EINVAL)
834 return 0; 1124 return 0;
835 switch_v4l2();
836 f->type = t->mode; 1125 f->type = t->mode;
837 if (fe_tuner_ops->get_frequency) { 1126 if (fe_tuner_ops->get_frequency && !t->standby) {
838 u32 abs_freq; 1127 u32 abs_freq;
839 1128
840 fe_tuner_ops->get_frequency(&t->fe, &abs_freq); 1129 fe_tuner_ops->get_frequency(&t->fe, &abs_freq);
841 f->frequency = (V4L2_TUNER_RADIO == t->mode) ? 1130 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
842 DIV_ROUND_CLOSEST(abs_freq * 2, 125) : 1131 DIV_ROUND_CLOSEST(abs_freq * 2, 125) :
843 DIV_ROUND_CLOSEST(abs_freq, 62500); 1132 DIV_ROUND_CLOSEST(abs_freq, 62500);
844 return 0; 1133 } else {
1134 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
1135 t->radio_freq : t->tv_freq;
845 } 1136 }
846 f->frequency = (V4L2_TUNER_RADIO == t->mode) ?
847 t->radio_freq : t->tv_freq;
848 return 0; 1137 return 0;
849} 1138}
850 1139
@@ -854,10 +1143,8 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
854 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops; 1143 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
855 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops; 1144 struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
856 1145
857 if (check_mode(t, "g_tuner") == -EINVAL) 1146 if (check_mode(t, vt->type) == -EINVAL)
858 return 0; 1147 return 0;
859 switch_v4l2();
860
861 vt->type = t->mode; 1148 vt->type = t->mode;
862 if (analog_ops->get_afc) 1149 if (analog_ops->get_afc)
863 vt->afc = analog_ops->get_afc(&t->fe); 1150 vt->afc = analog_ops->get_afc(&t->fe);
@@ -870,8 +1157,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
870 } 1157 }
871 1158
872 /* radio mode */ 1159 /* radio mode */
873 vt->rxsubchans = 1160 vt->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
874 V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
875 if (fe_tuner_ops->get_status) { 1161 if (fe_tuner_ops->get_status) {
876 u32 tuner_status; 1162 u32 tuner_status;
877 1163
@@ -880,21 +1166,14 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
880 (tuner_status & TUNER_STATUS_STEREO) ? 1166 (tuner_status & TUNER_STATUS_STEREO) ?
881 V4L2_TUNER_SUB_STEREO : 1167 V4L2_TUNER_SUB_STEREO :
882 V4L2_TUNER_SUB_MONO; 1168 V4L2_TUNER_SUB_MONO;
883 } else {
884 if (analog_ops->is_stereo) {
885 vt->rxsubchans =
886 analog_ops->is_stereo(&t->fe) ?
887 V4L2_TUNER_SUB_STEREO :
888 V4L2_TUNER_SUB_MONO;
889 }
890 } 1169 }
891 if (analog_ops->has_signal) 1170 if (analog_ops->has_signal)
892 vt->signal = analog_ops->has_signal(&t->fe); 1171 vt->signal = analog_ops->has_signal(&t->fe);
893 vt->capability |= 1172 vt->capability |= V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
894 V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO;
895 vt->audmode = t->audmode; 1173 vt->audmode = t->audmode;
896 vt->rangelow = radio_range[0] * 16000; 1174 vt->rangelow = radio_range[0] * 16000;
897 vt->rangehigh = radio_range[1] * 16000; 1175 vt->rangehigh = radio_range[1] * 16000;
1176
898 return 0; 1177 return 0;
899} 1178}
900 1179
@@ -903,16 +1182,12 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
903 struct tuner *t = to_tuner(sd); 1182 struct tuner *t = to_tuner(sd);
904 struct i2c_client *client = v4l2_get_subdevdata(sd); 1183 struct i2c_client *client = v4l2_get_subdevdata(sd);
905 1184
906 if (check_mode(t, "s_tuner") == -EINVAL) 1185 if (set_mode_freq(client, t, vt->type, 0) == -EINVAL)
907 return 0; 1186 return 0;
908 1187
909 switch_v4l2(); 1188 if (t->mode == V4L2_TUNER_RADIO)
1189 t->audmode = vt->audmode;
910 1190
911 /* do nothing unless we're a radio tuner */
912 if (t->mode != V4L2_TUNER_RADIO)
913 return 0;
914 t->audmode = vt->audmode;
915 set_radio_freq(client, t->radio_freq);
916 return 0; 1191 return 0;
917} 1192}
918 1193
@@ -929,9 +1204,13 @@ static int tuner_log_status(struct v4l2_subdev *sd)
929static int tuner_suspend(struct i2c_client *c, pm_message_t state) 1204static int tuner_suspend(struct i2c_client *c, pm_message_t state)
930{ 1205{
931 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1206 struct tuner *t = to_tuner(i2c_get_clientdata(c));
1207 struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
932 1208
933 tuner_dbg("suspend\n"); 1209 tuner_dbg("suspend\n");
934 /* FIXME: power down ??? */ 1210
1211 if (!t->standby && analog_ops->standby)
1212 analog_ops->standby(&t->fe);
1213
935 return 0; 1214 return 0;
936} 1215}
937 1216
@@ -940,13 +1219,10 @@ static int tuner_resume(struct i2c_client *c)
940 struct tuner *t = to_tuner(i2c_get_clientdata(c)); 1219 struct tuner *t = to_tuner(i2c_get_clientdata(c));
941 1220
942 tuner_dbg("resume\n"); 1221 tuner_dbg("resume\n");
943 if (V4L2_TUNER_RADIO == t->mode) { 1222
944 if (t->radio_freq) 1223 if (!t->standby)
945 set_freq(c, t->radio_freq); 1224 set_mode_freq(c, t, t->type, 0);
946 } else { 1225
947 if (t->tv_freq)
948 set_freq(c, t->tv_freq);
949 }
950 return 0; 1226 return 0;
951} 1227}
952 1228
@@ -964,7 +1240,9 @@ static int tuner_command(struct i2c_client *client, unsigned cmd, void *arg)
964 return -ENOIOCTLCMD; 1240 return -ENOIOCTLCMD;
965} 1241}
966 1242
967/* ----------------------------------------------------------------------- */ 1243/*
1244 * Callback structs
1245 */
968 1246
969static const struct v4l2_subdev_core_ops tuner_core_ops = { 1247static const struct v4l2_subdev_core_ops tuner_core_ops = {
970 .log_status = tuner_log_status, 1248 .log_status = tuner_log_status,
@@ -987,183 +1265,10 @@ static const struct v4l2_subdev_ops tuner_ops = {
987 .tuner = &tuner_tuner_ops, 1265 .tuner = &tuner_tuner_ops,
988}; 1266};
989 1267
990/* ---------------------------------------------------------------------- */ 1268/*
991 1269 * I2C structs and module init functions
992static LIST_HEAD(tuner_list);
993
994/* Search for existing radio and/or TV tuners on the given I2C adapter.
995 Note that when this function is called from tuner_probe you can be
996 certain no other devices will be added/deleted at the same time, I2C
997 core protects against that. */
998static void tuner_lookup(struct i2c_adapter *adap,
999 struct tuner **radio, struct tuner **tv)
1000{
1001 struct tuner *pos;
1002
1003 *radio = NULL;
1004 *tv = NULL;
1005
1006 list_for_each_entry(pos, &tuner_list, list) {
1007 int mode_mask;
1008
1009 if (pos->i2c->adapter != adap ||
1010 strcmp(pos->i2c->driver->driver.name, "tuner"))
1011 continue;
1012
1013 mode_mask = pos->mode_mask & ~T_STANDBY;
1014 if (*radio == NULL && mode_mask == T_RADIO)
1015 *radio = pos;
1016 /* Note: currently TDA9887 is the only demod-only
1017 device. If other devices appear then we need to
1018 make this test more general. */
1019 else if (*tv == NULL && pos->type != TUNER_TDA9887 &&
1020 (pos->mode_mask & (T_ANALOG_TV | T_DIGITAL_TV)))
1021 *tv = pos;
1022 }
1023}
1024
1025/* During client attach, set_type is called by adapter's attach_inform callback.
1026 set_type must then be completed by tuner_probe.
1027 */ 1270 */
1028static int tuner_probe(struct i2c_client *client,
1029 const struct i2c_device_id *id)
1030{
1031 struct tuner *t;
1032 struct tuner *radio;
1033 struct tuner *tv;
1034
1035 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
1036 if (NULL == t)
1037 return -ENOMEM;
1038 v4l2_i2c_subdev_init(&t->sd, client, &tuner_ops);
1039 t->i2c = client;
1040 t->name = "(tuner unset)";
1041 t->type = UNSET;
1042 t->audmode = V4L2_TUNER_MODE_STEREO;
1043 t->mode_mask = T_UNINITIALIZED;
1044
1045 if (show_i2c) {
1046 unsigned char buffer[16];
1047 int i, rc;
1048
1049 memset(buffer, 0, sizeof(buffer));
1050 rc = i2c_master_recv(client, buffer, sizeof(buffer));
1051 tuner_info("I2C RECV = ");
1052 for (i = 0; i < rc; i++)
1053 printk(KERN_CONT "%02x ", buffer[i]);
1054 printk("\n");
1055 }
1056 1271
1057 /* autodetection code based on the i2c addr */
1058 if (!no_autodetect) {
1059 switch (client->addr) {
1060 case 0x10:
1061 if (tuner_symbol_probe(tea5761_autodetection,
1062 t->i2c->adapter,
1063 t->i2c->addr) >= 0) {
1064 t->type = TUNER_TEA5761;
1065 t->mode_mask = T_RADIO;
1066 t->mode = T_STANDBY;
1067 /* Sets freq to FM range */
1068 t->radio_freq = 87.5 * 16000;
1069 tuner_lookup(t->i2c->adapter, &radio, &tv);
1070 if (tv)
1071 tv->mode_mask &= ~T_RADIO;
1072
1073 goto register_client;
1074 }
1075 kfree(t);
1076 return -ENODEV;
1077 case 0x42:
1078 case 0x43:
1079 case 0x4a:
1080 case 0x4b:
1081 /* If chip is not tda8290, don't register.
1082 since it can be tda9887*/
1083 if (tuner_symbol_probe(tda829x_probe, t->i2c->adapter,
1084 t->i2c->addr) >= 0) {
1085 tuner_dbg("tda829x detected\n");
1086 } else {
1087 /* Default is being tda9887 */
1088 t->type = TUNER_TDA9887;
1089 t->mode_mask = T_RADIO | T_ANALOG_TV |
1090 T_DIGITAL_TV;
1091 t->mode = T_STANDBY;
1092 goto register_client;
1093 }
1094 break;
1095 case 0x60:
1096 if (tuner_symbol_probe(tea5767_autodetection,
1097 t->i2c->adapter, t->i2c->addr)
1098 >= 0) {
1099 t->type = TUNER_TEA5767;
1100 t->mode_mask = T_RADIO;
1101 t->mode = T_STANDBY;
1102 /* Sets freq to FM range */
1103 t->radio_freq = 87.5 * 16000;
1104 tuner_lookup(t->i2c->adapter, &radio, &tv);
1105 if (tv)
1106 tv->mode_mask &= ~T_RADIO;
1107
1108 goto register_client;
1109 }
1110 break;
1111 }
1112 }
1113
1114 /* Initializes only the first TV tuner on this adapter. Why only the
1115 first? Because there are some devices (notably the ones with TI
1116 tuners) that have more than one i2c address for the *same* device.
1117 Experience shows that, except for just one case, the first
1118 address is the right one. The exception is a Russian tuner
1119 (ACORP_Y878F). So, the desired behavior is just to enable the
1120 first found TV tuner. */
1121 tuner_lookup(t->i2c->adapter, &radio, &tv);
1122 if (tv == NULL) {
1123 t->mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
1124 if (radio == NULL)
1125 t->mode_mask |= T_RADIO;
1126 tuner_dbg("Setting mode_mask to 0x%02x\n", t->mode_mask);
1127 t->tv_freq = 400 * 16; /* Sets freq to VHF High */
1128 t->radio_freq = 87.5 * 16000; /* Sets freq to FM range */
1129 }
1130
1131 /* Should be just before return */
1132register_client:
1133 tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
1134 client->adapter->name);
1135
1136 /* Sets a default mode */
1137 if (t->mode_mask & T_ANALOG_TV) {
1138 t->mode = V4L2_TUNER_ANALOG_TV;
1139 } else if (t->mode_mask & T_RADIO) {
1140 t->mode = V4L2_TUNER_RADIO;
1141 } else {
1142 t->mode = V4L2_TUNER_DIGITAL_TV;
1143 }
1144 set_type(client, t->type, t->mode_mask, t->config, t->fe.callback);
1145 list_add_tail(&t->list, &tuner_list);
1146 return 0;
1147}
1148
1149static int tuner_remove(struct i2c_client *client)
1150{
1151 struct tuner *t = to_tuner(i2c_get_clientdata(client));
1152
1153 v4l2_device_unregister_subdev(&t->sd);
1154 tuner_detach(&t->fe);
1155 t->fe.analog_demod_priv = NULL;
1156
1157 list_del(&t->list);
1158 kfree(t);
1159 return 0;
1160}
1161
1162/* ----------------------------------------------------------------------- */
1163
1164/* This driver supports many devices and the idea is to let the driver
1165 detect which device is present. So rather than listing all supported
1166 devices here, we pretend to support a single, fake device type. */
1167static const struct i2c_device_id tuner_id[] = { 1272static const struct i2c_device_id tuner_id[] = {
1168 { "tuner", }, /* autodetect */ 1273 { "tuner", }, /* autodetect */
1169 { } 1274 { }
@@ -1196,10 +1301,6 @@ static __exit void exit_tuner(void)
1196module_init(init_tuner); 1301module_init(init_tuner);
1197module_exit(exit_tuner); 1302module_exit(exit_tuner);
1198 1303
1199/* 1304MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
1200 * Overrides for Emacs so that we follow Linus's tabbing style. 1305MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
1201 * --------------------------------------------------------------------------- 1306MODULE_LICENSE("GPL");
1202 * Local variables:
1203 * c-basic-offset: 8
1204 * End:
1205 */
diff --git a/drivers/media/video/tvp514x.c b/drivers/media/video/tvp514x.c
index 45bcf0358a1d..9b3e828b0775 100644
--- a/drivers/media/video/tvp514x.c
+++ b/drivers/media/video/tvp514x.c
@@ -37,6 +37,7 @@
37#include <media/v4l2-common.h> 37#include <media/v4l2-common.h>
38#include <media/v4l2-mediabus.h> 38#include <media/v4l2-mediabus.h>
39#include <media/v4l2-chip-ident.h> 39#include <media/v4l2-chip-ident.h>
40#include <media/v4l2-ctrls.h>
40#include <media/tvp514x.h> 41#include <media/tvp514x.h>
41 42
42#include "tvp514x_regs.h" 43#include "tvp514x_regs.h"
@@ -97,6 +98,7 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable);
97 */ 98 */
98struct tvp514x_decoder { 99struct tvp514x_decoder {
99 struct v4l2_subdev sd; 100 struct v4l2_subdev sd;
101 struct v4l2_ctrl_handler hdl;
100 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)]; 102 struct tvp514x_reg tvp514x_regs[ARRAY_SIZE(tvp514x_reg_list_default)];
101 const struct tvp514x_platform_data *pdata; 103 const struct tvp514x_platform_data *pdata;
102 104
@@ -238,6 +240,11 @@ static inline struct tvp514x_decoder *to_decoder(struct v4l2_subdev *sd)
238 return container_of(sd, struct tvp514x_decoder, sd); 240 return container_of(sd, struct tvp514x_decoder, sd);
239} 241}
240 242
243static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
244{
245 return &container_of(ctrl->handler, struct tvp514x_decoder, hdl)->sd;
246}
247
241 248
242/** 249/**
243 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47. 250 * tvp514x_read_reg() - Read a value from a register in an TVP5146/47.
@@ -719,213 +726,54 @@ static int tvp514x_s_routing(struct v4l2_subdev *sd,
719} 726}
720 727
721/** 728/**
722 * tvp514x_queryctrl() - V4L2 decoder interface handler for queryctrl
723 * @sd: pointer to standard V4L2 sub-device structure
724 * @qctrl: standard V4L2 v4l2_queryctrl structure
725 *
726 * If the requested control is supported, returns the control information.
727 * Otherwise, returns -EINVAL if the control is not supported.
728 */
729static int
730tvp514x_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qctrl)
731{
732 int err = -EINVAL;
733
734 if (qctrl == NULL)
735 return err;
736
737 switch (qctrl->id) {
738 case V4L2_CID_BRIGHTNESS:
739 /* Brightness supported is (0-255), */
740 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
741 break;
742 case V4L2_CID_CONTRAST:
743 case V4L2_CID_SATURATION:
744 /**
745 * Saturation and Contrast supported is -
746 * Contrast: 0 - 255 (Default - 128)
747 * Saturation: 0 - 255 (Default - 128)
748 */
749 err = v4l2_ctrl_query_fill(qctrl, 0, 255, 1, 128);
750 break;
751 case V4L2_CID_HUE:
752 /* Hue Supported is -
753 * Hue - -180 - +180 (Default - 0, Step - +180)
754 */
755 err = v4l2_ctrl_query_fill(qctrl, -180, 180, 180, 0);
756 break;
757 case V4L2_CID_AUTOGAIN:
758 /**
759 * Auto Gain supported is -
760 * 0 - 1 (Default - 1)
761 */
762 err = v4l2_ctrl_query_fill(qctrl, 0, 1, 1, 1);
763 break;
764 default:
765 v4l2_err(sd, "invalid control id %d\n", qctrl->id);
766 return err;
767 }
768
769 v4l2_dbg(1, debug, sd, "Query Control:%s: Min - %d, Max - %d, Def - %d\n",
770 qctrl->name, qctrl->minimum, qctrl->maximum,
771 qctrl->default_value);
772
773 return err;
774}
775
776/**
777 * tvp514x_g_ctrl() - V4L2 decoder interface handler for g_ctrl
778 * @sd: pointer to standard V4L2 sub-device structure
779 * @ctrl: pointer to v4l2_control structure
780 *
781 * If the requested control is supported, returns the control's current
782 * value from the decoder. Otherwise, returns -EINVAL if the control is not
783 * supported.
784 */
785static int
786tvp514x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
787{
788 struct tvp514x_decoder *decoder = to_decoder(sd);
789
790 if (ctrl == NULL)
791 return -EINVAL;
792
793 switch (ctrl->id) {
794 case V4L2_CID_BRIGHTNESS:
795 ctrl->value = decoder->tvp514x_regs[REG_BRIGHTNESS].val;
796 break;
797 case V4L2_CID_CONTRAST:
798 ctrl->value = decoder->tvp514x_regs[REG_CONTRAST].val;
799 break;
800 case V4L2_CID_SATURATION:
801 ctrl->value = decoder->tvp514x_regs[REG_SATURATION].val;
802 break;
803 case V4L2_CID_HUE:
804 ctrl->value = decoder->tvp514x_regs[REG_HUE].val;
805 if (ctrl->value == 0x7F)
806 ctrl->value = 180;
807 else if (ctrl->value == 0x80)
808 ctrl->value = -180;
809 else
810 ctrl->value = 0;
811
812 break;
813 case V4L2_CID_AUTOGAIN:
814 ctrl->value = decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val;
815 if ((ctrl->value & 0x3) == 3)
816 ctrl->value = 1;
817 else
818 ctrl->value = 0;
819
820 break;
821 default:
822 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
823 return -EINVAL;
824 }
825
826 v4l2_dbg(1, debug, sd, "Get Control: ID - %d - %d\n",
827 ctrl->id, ctrl->value);
828 return 0;
829}
830
831/**
832 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl 729 * tvp514x_s_ctrl() - V4L2 decoder interface handler for s_ctrl
833 * @sd: pointer to standard V4L2 sub-device structure 730 * @ctrl: pointer to v4l2_ctrl structure
834 * @ctrl: pointer to v4l2_control structure
835 * 731 *
836 * If the requested control is supported, sets the control's current 732 * If the requested control is supported, sets the control's current
837 * value in HW. Otherwise, returns -EINVAL if the control is not supported. 733 * value in HW. Otherwise, returns -EINVAL if the control is not supported.
838 */ 734 */
839static int 735static int tvp514x_s_ctrl(struct v4l2_ctrl *ctrl)
840tvp514x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
841{ 736{
737 struct v4l2_subdev *sd = to_sd(ctrl);
842 struct tvp514x_decoder *decoder = to_decoder(sd); 738 struct tvp514x_decoder *decoder = to_decoder(sd);
843 int err = -EINVAL, value; 739 int err = -EINVAL, value;
844 740
845 if (ctrl == NULL) 741 value = ctrl->val;
846 return err;
847
848 value = ctrl->value;
849 742
850 switch (ctrl->id) { 743 switch (ctrl->id) {
851 case V4L2_CID_BRIGHTNESS: 744 case V4L2_CID_BRIGHTNESS:
852 if (ctrl->value < 0 || ctrl->value > 255) { 745 err = tvp514x_write_reg(sd, REG_BRIGHTNESS, value);
853 v4l2_err(sd, "invalid brightness setting %d\n", 746 if (!err)
854 ctrl->value); 747 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
855 return -ERANGE;
856 }
857 err = tvp514x_write_reg(sd, REG_BRIGHTNESS,
858 value);
859 if (err)
860 return err;
861
862 decoder->tvp514x_regs[REG_BRIGHTNESS].val = value;
863 break; 748 break;
864 case V4L2_CID_CONTRAST: 749 case V4L2_CID_CONTRAST:
865 if (ctrl->value < 0 || ctrl->value > 255) {
866 v4l2_err(sd, "invalid contrast setting %d\n",
867 ctrl->value);
868 return -ERANGE;
869 }
870 err = tvp514x_write_reg(sd, REG_CONTRAST, value); 750 err = tvp514x_write_reg(sd, REG_CONTRAST, value);
871 if (err) 751 if (!err)
872 return err; 752 decoder->tvp514x_regs[REG_CONTRAST].val = value;
873
874 decoder->tvp514x_regs[REG_CONTRAST].val = value;
875 break; 753 break;
876 case V4L2_CID_SATURATION: 754 case V4L2_CID_SATURATION:
877 if (ctrl->value < 0 || ctrl->value > 255) {
878 v4l2_err(sd, "invalid saturation setting %d\n",
879 ctrl->value);
880 return -ERANGE;
881 }
882 err = tvp514x_write_reg(sd, REG_SATURATION, value); 755 err = tvp514x_write_reg(sd, REG_SATURATION, value);
883 if (err) 756 if (!err)
884 return err; 757 decoder->tvp514x_regs[REG_SATURATION].val = value;
885
886 decoder->tvp514x_regs[REG_SATURATION].val = value;
887 break; 758 break;
888 case V4L2_CID_HUE: 759 case V4L2_CID_HUE:
889 if (value == 180) 760 if (value == 180)
890 value = 0x7F; 761 value = 0x7F;
891 else if (value == -180) 762 else if (value == -180)
892 value = 0x80; 763 value = 0x80;
893 else if (value == 0)
894 value = 0;
895 else {
896 v4l2_err(sd, "invalid hue setting %d\n", ctrl->value);
897 return -ERANGE;
898 }
899 err = tvp514x_write_reg(sd, REG_HUE, value); 764 err = tvp514x_write_reg(sd, REG_HUE, value);
900 if (err) 765 if (!err)
901 return err; 766 decoder->tvp514x_regs[REG_HUE].val = value;
902
903 decoder->tvp514x_regs[REG_HUE].val = value;
904 break; 767 break;
905 case V4L2_CID_AUTOGAIN: 768 case V4L2_CID_AUTOGAIN:
906 if (value == 1) 769 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value ? 0x0f : 0x0c);
907 value = 0x0F; 770 if (!err)
908 else if (value == 0) 771 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
909 value = 0x0C;
910 else {
911 v4l2_err(sd, "invalid auto gain setting %d\n",
912 ctrl->value);
913 return -ERANGE;
914 }
915 err = tvp514x_write_reg(sd, REG_AFE_GAIN_CTRL, value);
916 if (err)
917 return err;
918
919 decoder->tvp514x_regs[REG_AFE_GAIN_CTRL].val = value;
920 break; 772 break;
921 default:
922 v4l2_err(sd, "invalid control id %d\n", ctrl->id);
923 return err;
924 } 773 }
925 774
926 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n", 775 v4l2_dbg(1, debug, sd, "Set Control: ID - %d - %d\n",
927 ctrl->id, ctrl->value); 776 ctrl->id, ctrl->val);
928
929 return err; 777 return err;
930} 778}
931 779
@@ -1104,10 +952,18 @@ static int tvp514x_s_stream(struct v4l2_subdev *sd, int enable)
1104 return err; 952 return err;
1105} 953}
1106 954
1107static const struct v4l2_subdev_core_ops tvp514x_core_ops = { 955static const struct v4l2_ctrl_ops tvp514x_ctrl_ops = {
1108 .queryctrl = tvp514x_queryctrl,
1109 .g_ctrl = tvp514x_g_ctrl,
1110 .s_ctrl = tvp514x_s_ctrl, 956 .s_ctrl = tvp514x_s_ctrl,
957};
958
959static const struct v4l2_subdev_core_ops tvp514x_core_ops = {
960 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
961 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
962 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
963 .g_ctrl = v4l2_subdev_g_ctrl,
964 .s_ctrl = v4l2_subdev_s_ctrl,
965 .queryctrl = v4l2_subdev_queryctrl,
966 .querymenu = v4l2_subdev_querymenu,
1111 .s_std = tvp514x_s_std, 967 .s_std = tvp514x_s_std,
1112}; 968};
1113 969
@@ -1190,6 +1046,27 @@ tvp514x_probe(struct i2c_client *client, const struct i2c_device_id *id)
1190 sd = &decoder->sd; 1046 sd = &decoder->sd;
1191 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops); 1047 v4l2_i2c_subdev_init(sd, client, &tvp514x_ops);
1192 1048
1049 v4l2_ctrl_handler_init(&decoder->hdl, 5);
1050 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1051 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1052 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1053 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1054 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1055 V4L2_CID_SATURATION, 0, 255, 1, 128);
1056 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1057 V4L2_CID_HUE, -180, 180, 180, 0);
1058 v4l2_ctrl_new_std(&decoder->hdl, &tvp514x_ctrl_ops,
1059 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
1060 sd->ctrl_handler = &decoder->hdl;
1061 if (decoder->hdl.error) {
1062 int err = decoder->hdl.error;
1063
1064 v4l2_ctrl_handler_free(&decoder->hdl);
1065 kfree(decoder);
1066 return err;
1067 }
1068 v4l2_ctrl_handler_setup(&decoder->hdl);
1069
1193 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name); 1070 v4l2_info(sd, "%s decoder driver registered !!\n", sd->name);
1194 1071
1195 return 0; 1072 return 0;
@@ -1209,6 +1086,7 @@ static int tvp514x_remove(struct i2c_client *client)
1209 struct tvp514x_decoder *decoder = to_decoder(sd); 1086 struct tvp514x_decoder *decoder = to_decoder(sd);
1210 1087
1211 v4l2_device_unregister_subdev(sd); 1088 v4l2_device_unregister_subdev(sd);
1089 v4l2_ctrl_handler_free(&decoder->hdl);
1212 kfree(decoder); 1090 kfree(decoder);
1213 return 0; 1091 return 0;
1214} 1092}
diff --git a/drivers/media/video/tvp5150.c b/drivers/media/video/tvp5150.c
index 58927664d3ea..e927d25e0d35 100644
--- a/drivers/media/video/tvp5150.c
+++ b/drivers/media/video/tvp5150.c
@@ -12,6 +12,7 @@
12#include <media/v4l2-device.h> 12#include <media/v4l2-device.h>
13#include <media/tvp5150.h> 13#include <media/tvp5150.h>
14#include <media/v4l2-chip-ident.h> 14#include <media/v4l2-chip-ident.h>
15#include <media/v4l2-ctrls.h>
15 16
16#include "tvp5150_reg.h" 17#include "tvp5150_reg.h"
17 18
@@ -24,58 +25,14 @@ static int debug;
24module_param(debug, int, 0); 25module_param(debug, int, 0);
25MODULE_PARM_DESC(debug, "Debug level (0-2)"); 26MODULE_PARM_DESC(debug, "Debug level (0-2)");
26 27
27/* supported controls */
28static struct v4l2_queryctrl tvp5150_qctrl[] = {
29 {
30 .id = V4L2_CID_BRIGHTNESS,
31 .type = V4L2_CTRL_TYPE_INTEGER,
32 .name = "Brightness",
33 .minimum = 0,
34 .maximum = 255,
35 .step = 1,
36 .default_value = 128,
37 .flags = 0,
38 }, {
39 .id = V4L2_CID_CONTRAST,
40 .type = V4L2_CTRL_TYPE_INTEGER,
41 .name = "Contrast",
42 .minimum = 0,
43 .maximum = 255,
44 .step = 0x1,
45 .default_value = 128,
46 .flags = 0,
47 }, {
48 .id = V4L2_CID_SATURATION,
49 .type = V4L2_CTRL_TYPE_INTEGER,
50 .name = "Saturation",
51 .minimum = 0,
52 .maximum = 255,
53 .step = 0x1,
54 .default_value = 128,
55 .flags = 0,
56 }, {
57 .id = V4L2_CID_HUE,
58 .type = V4L2_CTRL_TYPE_INTEGER,
59 .name = "Hue",
60 .minimum = -128,
61 .maximum = 127,
62 .step = 0x1,
63 .default_value = 0,
64 .flags = 0,
65 }
66};
67
68struct tvp5150 { 28struct tvp5150 {
69 struct v4l2_subdev sd; 29 struct v4l2_subdev sd;
30 struct v4l2_ctrl_handler hdl;
70 31
71 v4l2_std_id norm; /* Current set standard */ 32 v4l2_std_id norm; /* Current set standard */
72 u32 input; 33 u32 input;
73 u32 output; 34 u32 output;
74 int enable; 35 int enable;
75 int bright;
76 int contrast;
77 int hue;
78 int sat;
79}; 36};
80 37
81static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd) 38static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
@@ -83,6 +40,11 @@ static inline struct tvp5150 *to_tvp5150(struct v4l2_subdev *sd)
83 return container_of(sd, struct tvp5150, sd); 40 return container_of(sd, struct tvp5150, sd);
84} 41}
85 42
43static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
44{
45 return &container_of(ctrl->handler, struct tvp5150, hdl)->sd;
46}
47
86static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr) 48static int tvp5150_read(struct v4l2_subdev *sd, unsigned char addr)
87{ 49{
88 struct i2c_client *c = v4l2_get_subdevdata(sd); 50 struct i2c_client *c = v4l2_get_subdevdata(sd);
@@ -775,27 +737,6 @@ static int tvp5150_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
775static int tvp5150_reset(struct v4l2_subdev *sd, u32 val) 737static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
776{ 738{
777 struct tvp5150 *decoder = to_tvp5150(sd); 739 struct tvp5150 *decoder = to_tvp5150(sd);
778 u8 msb_id, lsb_id, msb_rom, lsb_rom;
779
780 msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID);
781 lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID);
782 msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER);
783 lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
784
785 if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */
786 v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id);
787
788 /* ITU-T BT.656.4 timing */
789 tvp5150_write(sd, TVP5150_REV_SELECT, 0);
790 } else {
791 if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */
792 v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id);
793 } else {
794 v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
795 msb_id, lsb_id);
796 v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom);
797 }
798 }
799 740
800 /* Initializes TVP5150 to its default values */ 741 /* Initializes TVP5150 to its default values */
801 tvp5150_write_inittab(sd, tvp5150_init_default); 742 tvp5150_write_inittab(sd, tvp5150_init_default);
@@ -810,64 +751,28 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
810 tvp5150_write_inittab(sd, tvp5150_init_enable); 751 tvp5150_write_inittab(sd, tvp5150_init_enable);
811 752
812 /* Initialize image preferences */ 753 /* Initialize image preferences */
813 tvp5150_write(sd, TVP5150_BRIGHT_CTL, decoder->bright); 754 v4l2_ctrl_handler_setup(&decoder->hdl);
814 tvp5150_write(sd, TVP5150_CONTRAST_CTL, decoder->contrast);
815 tvp5150_write(sd, TVP5150_SATURATION_CTL, decoder->contrast);
816 tvp5150_write(sd, TVP5150_HUE_CTL, decoder->hue);
817 755
818 tvp5150_set_std(sd, decoder->norm); 756 tvp5150_set_std(sd, decoder->norm);
819 return 0; 757 return 0;
820}; 758};
821 759
822static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 760static int tvp5150_s_ctrl(struct v4l2_ctrl *ctrl)
823{
824 v4l2_dbg(1, debug, sd, "g_ctrl called\n");
825
826 switch (ctrl->id) {
827 case V4L2_CID_BRIGHTNESS:
828 ctrl->value = tvp5150_read(sd, TVP5150_BRIGHT_CTL);
829 return 0;
830 case V4L2_CID_CONTRAST:
831 ctrl->value = tvp5150_read(sd, TVP5150_CONTRAST_CTL);
832 return 0;
833 case V4L2_CID_SATURATION:
834 ctrl->value = tvp5150_read(sd, TVP5150_SATURATION_CTL);
835 return 0;
836 case V4L2_CID_HUE:
837 ctrl->value = tvp5150_read(sd, TVP5150_HUE_CTL);
838 return 0;
839 }
840 return -EINVAL;
841}
842
843static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
844{ 761{
845 u8 i, n; 762 struct v4l2_subdev *sd = to_sd(ctrl);
846 n = ARRAY_SIZE(tvp5150_qctrl);
847
848 for (i = 0; i < n; i++) {
849 if (ctrl->id != tvp5150_qctrl[i].id)
850 continue;
851 if (ctrl->value < tvp5150_qctrl[i].minimum ||
852 ctrl->value > tvp5150_qctrl[i].maximum)
853 return -ERANGE;
854 v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
855 ctrl->id, ctrl->value);
856 break;
857 }
858 763
859 switch (ctrl->id) { 764 switch (ctrl->id) {
860 case V4L2_CID_BRIGHTNESS: 765 case V4L2_CID_BRIGHTNESS:
861 tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->value); 766 tvp5150_write(sd, TVP5150_BRIGHT_CTL, ctrl->val);
862 return 0; 767 return 0;
863 case V4L2_CID_CONTRAST: 768 case V4L2_CID_CONTRAST:
864 tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->value); 769 tvp5150_write(sd, TVP5150_CONTRAST_CTL, ctrl->val);
865 return 0; 770 return 0;
866 case V4L2_CID_SATURATION: 771 case V4L2_CID_SATURATION:
867 tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->value); 772 tvp5150_write(sd, TVP5150_SATURATION_CTL, ctrl->val);
868 return 0; 773 return 0;
869 case V4L2_CID_HUE: 774 case V4L2_CID_HUE:
870 tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->value); 775 tvp5150_write(sd, TVP5150_HUE_CTL, ctrl->val);
871 return 0; 776 return 0;
872 } 777 }
873 return -EINVAL; 778 return -EINVAL;
@@ -995,29 +900,21 @@ static int tvp5150_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
995 return 0; 900 return 0;
996} 901}
997 902
998static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
999{
1000 int i;
1001
1002 v4l2_dbg(1, debug, sd, "queryctrl called\n");
1003
1004 for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
1005 if (qc->id && qc->id == tvp5150_qctrl[i].id) {
1006 memcpy(qc, &(tvp5150_qctrl[i]),
1007 sizeof(*qc));
1008 return 0;
1009 }
1010
1011 return -EINVAL;
1012}
1013
1014/* ----------------------------------------------------------------------- */ 903/* ----------------------------------------------------------------------- */
1015 904
905static const struct v4l2_ctrl_ops tvp5150_ctrl_ops = {
906 .s_ctrl = tvp5150_s_ctrl,
907};
908
1016static const struct v4l2_subdev_core_ops tvp5150_core_ops = { 909static const struct v4l2_subdev_core_ops tvp5150_core_ops = {
1017 .log_status = tvp5150_log_status, 910 .log_status = tvp5150_log_status,
1018 .g_ctrl = tvp5150_g_ctrl, 911 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
1019 .s_ctrl = tvp5150_s_ctrl, 912 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
1020 .queryctrl = tvp5150_queryctrl, 913 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
914 .g_ctrl = v4l2_subdev_g_ctrl,
915 .s_ctrl = v4l2_subdev_s_ctrl,
916 .queryctrl = v4l2_subdev_queryctrl,
917 .querymenu = v4l2_subdev_querymenu,
1021 .s_std = tvp5150_s_std, 918 .s_std = tvp5150_s_std,
1022 .reset = tvp5150_reset, 919 .reset = tvp5150_reset,
1023 .g_chip_ident = tvp5150_g_chip_ident, 920 .g_chip_ident = tvp5150_g_chip_ident,
@@ -1059,6 +956,7 @@ static int tvp5150_probe(struct i2c_client *c,
1059{ 956{
1060 struct tvp5150 *core; 957 struct tvp5150 *core;
1061 struct v4l2_subdev *sd; 958 struct v4l2_subdev *sd;
959 u8 msb_id, lsb_id, msb_rom, lsb_rom;
1062 960
1063 /* Check if the adapter supports the needed features */ 961 /* Check if the adapter supports the needed features */
1064 if (!i2c_check_functionality(c->adapter, 962 if (!i2c_check_functionality(c->adapter,
@@ -1074,13 +972,48 @@ static int tvp5150_probe(struct i2c_client *c,
1074 v4l_info(c, "chip found @ 0x%02x (%s)\n", 972 v4l_info(c, "chip found @ 0x%02x (%s)\n",
1075 c->addr << 1, c->adapter->name); 973 c->addr << 1, c->adapter->name);
1076 974
975 msb_id = tvp5150_read(sd, TVP5150_MSB_DEV_ID);
976 lsb_id = tvp5150_read(sd, TVP5150_LSB_DEV_ID);
977 msb_rom = tvp5150_read(sd, TVP5150_ROM_MAJOR_VER);
978 lsb_rom = tvp5150_read(sd, TVP5150_ROM_MINOR_VER);
979
980 if (msb_rom == 4 && lsb_rom == 0) { /* Is TVP5150AM1 */
981 v4l2_info(sd, "tvp%02x%02xam1 detected.\n", msb_id, lsb_id);
982
983 /* ITU-T BT.656.4 timing */
984 tvp5150_write(sd, TVP5150_REV_SELECT, 0);
985 } else {
986 if (msb_rom == 3 || lsb_rom == 0x21) { /* Is TVP5150A */
987 v4l2_info(sd, "tvp%02x%02xa detected.\n", msb_id, lsb_id);
988 } else {
989 v4l2_info(sd, "*** unknown tvp%02x%02x chip detected.\n",
990 msb_id, lsb_id);
991 v4l2_info(sd, "*** Rom ver is %d.%d\n", msb_rom, lsb_rom);
992 }
993 }
994
1077 core->norm = V4L2_STD_ALL; /* Default is autodetect */ 995 core->norm = V4L2_STD_ALL; /* Default is autodetect */
1078 core->input = TVP5150_COMPOSITE1; 996 core->input = TVP5150_COMPOSITE1;
1079 core->enable = 1; 997 core->enable = 1;
1080 core->bright = 128; 998
1081 core->contrast = 128; 999 v4l2_ctrl_handler_init(&core->hdl, 4);
1082 core->hue = 0; 1000 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1083 core->sat = 128; 1001 V4L2_CID_BRIGHTNESS, 0, 255, 1, 128);
1002 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1003 V4L2_CID_CONTRAST, 0, 255, 1, 128);
1004 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1005 V4L2_CID_SATURATION, 0, 255, 1, 128);
1006 v4l2_ctrl_new_std(&core->hdl, &tvp5150_ctrl_ops,
1007 V4L2_CID_HUE, -128, 127, 1, 0);
1008 sd->ctrl_handler = &core->hdl;
1009 if (core->hdl.error) {
1010 int err = core->hdl.error;
1011
1012 v4l2_ctrl_handler_free(&core->hdl);
1013 kfree(core);
1014 return err;
1015 }
1016 v4l2_ctrl_handler_setup(&core->hdl);
1084 1017
1085 if (debug > 1) 1018 if (debug > 1)
1086 tvp5150_log_status(sd); 1019 tvp5150_log_status(sd);
@@ -1090,12 +1023,14 @@ static int tvp5150_probe(struct i2c_client *c,
1090static int tvp5150_remove(struct i2c_client *c) 1023static int tvp5150_remove(struct i2c_client *c)
1091{ 1024{
1092 struct v4l2_subdev *sd = i2c_get_clientdata(c); 1025 struct v4l2_subdev *sd = i2c_get_clientdata(c);
1026 struct tvp5150 *decoder = to_tvp5150(sd);
1093 1027
1094 v4l2_dbg(1, debug, sd, 1028 v4l2_dbg(1, debug, sd,
1095 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n", 1029 "tvp5150.c: removing tvp5150 adapter on address 0x%x\n",
1096 c->addr << 1); 1030 c->addr << 1);
1097 1031
1098 v4l2_device_unregister_subdev(sd); 1032 v4l2_device_unregister_subdev(sd);
1033 v4l2_ctrl_handler_free(&decoder->hdl);
1099 kfree(to_tvp5150(sd)); 1034 kfree(to_tvp5150(sd));
1100 return 0; 1035 return 0;
1101} 1036}
diff --git a/drivers/media/video/tvp7002.c b/drivers/media/video/tvp7002.c
index c799e4eb6fcd..b799851bf3d0 100644
--- a/drivers/media/video/tvp7002.c
+++ b/drivers/media/video/tvp7002.c
@@ -32,6 +32,7 @@
32#include <media/v4l2-device.h> 32#include <media/v4l2-device.h>
33#include <media/v4l2-chip-ident.h> 33#include <media/v4l2-chip-ident.h>
34#include <media/v4l2-common.h> 34#include <media/v4l2-common.h>
35#include <media/v4l2-ctrls.h>
35#include "tvp7002_reg.h" 36#include "tvp7002_reg.h"
36 37
37MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver"); 38MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
@@ -421,13 +422,13 @@ static const struct tvp7002_preset_definition tvp7002_presets[] = {
421/* Device definition */ 422/* Device definition */
422struct tvp7002 { 423struct tvp7002 {
423 struct v4l2_subdev sd; 424 struct v4l2_subdev sd;
425 struct v4l2_ctrl_handler hdl;
424 const struct tvp7002_config *pdata; 426 const struct tvp7002_config *pdata;
425 427
426 int ver; 428 int ver;
427 int streaming; 429 int streaming;
428 430
429 const struct tvp7002_preset_definition *current_preset; 431 const struct tvp7002_preset_definition *current_preset;
430 u8 gain;
431}; 432};
432 433
433/* 434/*
@@ -441,6 +442,11 @@ static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
441 return container_of(sd, struct tvp7002, sd); 442 return container_of(sd, struct tvp7002, sd);
442} 443}
443 444
445static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
446{
447 return &container_of(ctrl->handler, struct tvp7002, hdl)->sd;
448}
449
444/* 450/*
445 * tvp7002_read - Read a value from a register in an TVP7002 451 * tvp7002_read - Read a value from a register in an TVP7002
446 * @sd: ptr to v4l2_subdev struct 452 * @sd: ptr to v4l2_subdev struct
@@ -606,78 +612,25 @@ static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
606} 612}
607 613
608/* 614/*
609 * tvp7002_g_ctrl() - Get a control
610 * @sd: ptr to v4l2_subdev struct
611 * @ctrl: ptr to v4l2_control struct
612 *
613 * Get a control for a TVP7002 decoder device.
614 * Returns zero when successful or -EINVAL if register access fails.
615 */
616static int tvp7002_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
617{
618 struct tvp7002 *device = to_tvp7002(sd);
619
620 switch (ctrl->id) {
621 case V4L2_CID_GAIN:
622 ctrl->value = device->gain;
623 return 0;
624 default:
625 return -EINVAL;
626 }
627}
628
629/*
630 * tvp7002_s_ctrl() - Set a control 615 * tvp7002_s_ctrl() - Set a control
631 * @sd: ptr to v4l2_subdev struct 616 * @ctrl: ptr to v4l2_ctrl struct
632 * @ctrl: ptr to v4l2_control struct
633 * 617 *
634 * Set a control in TVP7002 decoder device. 618 * Set a control in TVP7002 decoder device.
635 * Returns zero when successful or -EINVAL if register access fails. 619 * Returns zero when successful or -EINVAL if register access fails.
636 */ 620 */
637static int tvp7002_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 621static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
638{ 622{
639 struct tvp7002 *device = to_tvp7002(sd); 623 struct v4l2_subdev *sd = to_sd(ctrl);
640 int error = 0; 624 int error = 0;
641 625
642 switch (ctrl->id) { 626 switch (ctrl->id) {
643 case V4L2_CID_GAIN: 627 case V4L2_CID_GAIN:
644 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, 628 tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, ctrl->val, &error);
645 ctrl->value & 0xff, &error); 629 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, ctrl->val, &error);
646 tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, 630 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN, ctrl->val, &error);
647 ctrl->value & 0xff, &error); 631 return error;
648 tvp7002_write_err(sd, TVP7002_B_FINE_GAIN,
649 ctrl->value & 0xff, &error);
650
651 if (error < 0)
652 return error;
653
654 /* Set only after knowing there is no error */
655 device->gain = ctrl->value & 0xff;
656 return 0;
657 default:
658 return -EINVAL;
659 }
660}
661
662/*
663 * tvp7002_queryctrl() - Query a control
664 * @sd: ptr to v4l2_subdev struct
665 * @qc: ptr to v4l2_queryctrl struct
666 *
667 * Query a control of a TVP7002 decoder device.
668 * Returns zero when successful or -EINVAL if register read fails.
669 */
670static int tvp7002_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
671{
672 switch (qc->id) {
673 case V4L2_CID_GAIN:
674 /*
675 * Gain is supported [0-255, default=0, step=1]
676 */
677 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 0);
678 default:
679 return -EINVAL;
680 } 632 }
633 return -EINVAL;
681} 634}
682 635
683/* 636/*
@@ -924,7 +877,7 @@ static int tvp7002_log_status(struct v4l2_subdev *sd)
924 device->streaming ? "yes" : "no"); 877 device->streaming ? "yes" : "no");
925 878
926 /* Print the current value of the gain control */ 879 /* Print the current value of the gain control */
927 v4l2_info(sd, "Gain: %u\n", device->gain); 880 v4l2_ctrl_handler_log_status(&device->hdl, sd->name);
928 881
929 return 0; 882 return 0;
930} 883}
@@ -946,13 +899,21 @@ static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
946 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset); 899 return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
947} 900}
948 901
902static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
903 .s_ctrl = tvp7002_s_ctrl,
904};
905
949/* V4L2 core operation handlers */ 906/* V4L2 core operation handlers */
950static const struct v4l2_subdev_core_ops tvp7002_core_ops = { 907static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
951 .g_chip_ident = tvp7002_g_chip_ident, 908 .g_chip_ident = tvp7002_g_chip_ident,
952 .log_status = tvp7002_log_status, 909 .log_status = tvp7002_log_status,
953 .g_ctrl = tvp7002_g_ctrl, 910 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
954 .s_ctrl = tvp7002_s_ctrl, 911 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
955 .queryctrl = tvp7002_queryctrl, 912 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
913 .g_ctrl = v4l2_subdev_g_ctrl,
914 .s_ctrl = v4l2_subdev_s_ctrl,
915 .queryctrl = v4l2_subdev_queryctrl,
916 .querymenu = v4l2_subdev_querymenu,
956#ifdef CONFIG_VIDEO_ADV_DEBUG 917#ifdef CONFIG_VIDEO_ADV_DEBUG
957 .g_register = tvp7002_g_register, 918 .g_register = tvp7002_g_register,
958 .s_register = tvp7002_s_register, 919 .s_register = tvp7002_s_register,
@@ -977,12 +938,6 @@ static const struct v4l2_subdev_ops tvp7002_ops = {
977 .video = &tvp7002_video_ops, 938 .video = &tvp7002_video_ops,
978}; 939};
979 940
980static struct tvp7002 tvp7002_dev = {
981 .streaming = 0,
982 .current_preset = tvp7002_presets,
983 .gain = 0,
984};
985
986/* 941/*
987 * tvp7002_probe - Probe a TVP7002 device 942 * tvp7002_probe - Probe a TVP7002 device
988 * @c: ptr to i2c_client struct 943 * @c: ptr to i2c_client struct
@@ -1013,14 +968,14 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1013 return -ENODEV; 968 return -ENODEV;
1014 } 969 }
1015 970
1016 device = kmalloc(sizeof(struct tvp7002), GFP_KERNEL); 971 device = kzalloc(sizeof(struct tvp7002), GFP_KERNEL);
1017 972
1018 if (!device) 973 if (!device)
1019 return -ENOMEM; 974 return -ENOMEM;
1020 975
1021 *device = tvp7002_dev;
1022 sd = &device->sd; 976 sd = &device->sd;
1023 device->pdata = c->dev.platform_data; 977 device->pdata = c->dev.platform_data;
978 device->current_preset = tvp7002_presets;
1024 979
1025 /* Tell v4l2 the device is ready */ 980 /* Tell v4l2 the device is ready */
1026 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops); 981 v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
@@ -1060,6 +1015,19 @@ static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
1060 preset.preset = device->current_preset->preset; 1015 preset.preset = device->current_preset->preset;
1061 error = tvp7002_s_dv_preset(sd, &preset); 1016 error = tvp7002_s_dv_preset(sd, &preset);
1062 1017
1018 v4l2_ctrl_handler_init(&device->hdl, 1);
1019 v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
1020 V4L2_CID_GAIN, 0, 255, 1, 0);
1021 sd->ctrl_handler = &device->hdl;
1022 if (device->hdl.error) {
1023 int err = device->hdl.error;
1024
1025 v4l2_ctrl_handler_free(&device->hdl);
1026 kfree(device);
1027 return err;
1028 }
1029 v4l2_ctrl_handler_setup(&device->hdl);
1030
1063found_error: 1031found_error:
1064 if (error < 0) 1032 if (error < 0)
1065 kfree(device); 1033 kfree(device);
@@ -1083,6 +1051,7 @@ static int tvp7002_remove(struct i2c_client *c)
1083 "on address 0x%x\n", c->addr); 1051 "on address 0x%x\n", c->addr);
1084 1052
1085 v4l2_device_unregister_subdev(sd); 1053 v4l2_device_unregister_subdev(sd);
1054 v4l2_ctrl_handler_free(&device->hdl);
1086 kfree(device); 1055 kfree(device);
1087 return 0; 1056 return 0;
1088} 1057}
diff --git a/drivers/media/video/uvc/uvc_driver.c b/drivers/media/video/uvc/uvc_driver.c
index a1e9dfb52f69..6459b8cba223 100644
--- a/drivers/media/video/uvc/uvc_driver.c
+++ b/drivers/media/video/uvc/uvc_driver.c
@@ -1264,6 +1264,14 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
1264 1264
1265 break; 1265 break;
1266 1266
1267 case UVC_OTT_VENDOR_SPECIFIC:
1268 case UVC_OTT_DISPLAY:
1269 case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
1270 if (uvc_trace_param & UVC_TRACE_PROBE)
1271 printk(" OT %d", entity->id);
1272
1273 break;
1274
1267 case UVC_TT_STREAMING: 1275 case UVC_TT_STREAMING:
1268 if (UVC_ENTITY_IS_ITERM(entity)) { 1276 if (UVC_ENTITY_IS_ITERM(entity)) {
1269 if (uvc_trace_param & UVC_TRACE_PROBE) 1277 if (uvc_trace_param & UVC_TRACE_PROBE)
diff --git a/drivers/media/video/uvc/uvc_video.c b/drivers/media/video/uvc/uvc_video.c
index 5673d673504b..545c0294813d 100644
--- a/drivers/media/video/uvc/uvc_video.c
+++ b/drivers/media/video/uvc/uvc_video.c
@@ -89,15 +89,19 @@ int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
89static void uvc_fixup_video_ctrl(struct uvc_streaming *stream, 89static void uvc_fixup_video_ctrl(struct uvc_streaming *stream,
90 struct uvc_streaming_control *ctrl) 90 struct uvc_streaming_control *ctrl)
91{ 91{
92 struct uvc_format *format; 92 struct uvc_format *format = NULL;
93 struct uvc_frame *frame = NULL; 93 struct uvc_frame *frame = NULL;
94 unsigned int i; 94 unsigned int i;
95 95
96 if (ctrl->bFormatIndex <= 0 || 96 for (i = 0; i < stream->nformats; ++i) {
97 ctrl->bFormatIndex > stream->nformats) 97 if (stream->format[i].index == ctrl->bFormatIndex) {
98 return; 98 format = &stream->format[i];
99 break;
100 }
101 }
99 102
100 format = &stream->format[ctrl->bFormatIndex - 1]; 103 if (format == NULL)
104 return;
101 105
102 for (i = 0; i < format->nframes; ++i) { 106 for (i = 0; i < format->nframes; ++i) {
103 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) { 107 if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c
index 810eef43c216..06b9f9f82013 100644
--- a/drivers/media/video/v4l2-common.c
+++ b/drivers/media/video/v4l2-common.c
@@ -59,7 +59,6 @@
59#include <asm/pgtable.h> 59#include <asm/pgtable.h>
60#include <asm/io.h> 60#include <asm/io.h>
61#include <asm/div64.h> 61#include <asm/div64.h>
62#define __OLD_VIDIOC_ /* To allow fixing old calls*/
63#include <media/v4l2-common.h> 62#include <media/v4l2-common.h>
64#include <media/v4l2-device.h> 63#include <media/v4l2-device.h>
65#include <media/v4l2-ctrls.h> 64#include <media/v4l2-ctrls.h>
@@ -81,69 +80,6 @@ MODULE_LICENSE("GPL");
81 * Video Standard Operations (contributed by Michael Schimek) 80 * Video Standard Operations (contributed by Michael Schimek)
82 */ 81 */
83 82
84
85/* ----------------------------------------------------------------- */
86/* priority handling */
87
88#define V4L2_PRIO_VALID(val) (val == V4L2_PRIORITY_BACKGROUND || \
89 val == V4L2_PRIORITY_INTERACTIVE || \
90 val == V4L2_PRIORITY_RECORD)
91
92void v4l2_prio_init(struct v4l2_prio_state *global)
93{
94 memset(global, 0, sizeof(*global));
95}
96EXPORT_SYMBOL(v4l2_prio_init);
97
98int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
99 enum v4l2_priority new)
100{
101 if (!V4L2_PRIO_VALID(new))
102 return -EINVAL;
103 if (*local == new)
104 return 0;
105
106 atomic_inc(&global->prios[new]);
107 if (V4L2_PRIO_VALID(*local))
108 atomic_dec(&global->prios[*local]);
109 *local = new;
110 return 0;
111}
112EXPORT_SYMBOL(v4l2_prio_change);
113
114void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
115{
116 v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
117}
118EXPORT_SYMBOL(v4l2_prio_open);
119
120void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
121{
122 if (V4L2_PRIO_VALID(local))
123 atomic_dec(&global->prios[local]);
124}
125EXPORT_SYMBOL(v4l2_prio_close);
126
127enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
128{
129 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
130 return V4L2_PRIORITY_RECORD;
131 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
132 return V4L2_PRIORITY_INTERACTIVE;
133 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
134 return V4L2_PRIORITY_BACKGROUND;
135 return V4L2_PRIORITY_UNSET;
136}
137EXPORT_SYMBOL(v4l2_prio_max);
138
139int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
140{
141 return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
142}
143EXPORT_SYMBOL(v4l2_prio_check);
144
145/* ----------------------------------------------------------------- */
146
147/* Helper functions for control handling */ 83/* Helper functions for control handling */
148 84
149/* Check for correctness of the ctrl's value based on the data from 85/* Check for correctness of the ctrl's value based on the data from
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index dc82eb83c1d4..7c2694738b31 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/compat.h> 16#include <linux/compat.h>
17#define __OLD_VIDIOC_ /* To allow fixing old calls*/
18#include <linux/videodev2.h> 17#include <linux/videodev2.h>
19#include <linux/module.h> 18#include <linux/module.h>
20#include <media/v4l2-ioctl.h> 19#include <media/v4l2-ioctl.h>
@@ -97,6 +96,14 @@ static inline int get_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pi
97 return 0; 96 return 0;
98} 97}
99 98
99static inline int get_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
100 struct v4l2_pix_format_mplane __user *up)
101{
102 if (copy_from_user(kp, up, sizeof(struct v4l2_pix_format_mplane)))
103 return -EFAULT;
104 return 0;
105}
106
100static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up) 107static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pix_format __user *up)
101{ 108{
102 if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format))) 109 if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format)))
@@ -104,6 +111,14 @@ static inline int put_v4l2_pix_format(struct v4l2_pix_format *kp, struct v4l2_pi
104 return 0; 111 return 0;
105} 112}
106 113
114static inline int put_v4l2_pix_format_mplane(struct v4l2_pix_format_mplane *kp,
115 struct v4l2_pix_format_mplane __user *up)
116{
117 if (copy_to_user(up, kp, sizeof(struct v4l2_pix_format_mplane)))
118 return -EFAULT;
119 return 0;
120}
121
107static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up) 122static inline int get_v4l2_vbi_format(struct v4l2_vbi_format *kp, struct v4l2_vbi_format __user *up)
108{ 123{
109 if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format))) 124 if (copy_from_user(kp, up, sizeof(struct v4l2_vbi_format)))
@@ -136,6 +151,7 @@ struct v4l2_format32 {
136 enum v4l2_buf_type type; 151 enum v4l2_buf_type type;
137 union { 152 union {
138 struct v4l2_pix_format pix; 153 struct v4l2_pix_format pix;
154 struct v4l2_pix_format_mplane pix_mp;
139 struct v4l2_window32 win; 155 struct v4l2_window32 win;
140 struct v4l2_vbi_format vbi; 156 struct v4l2_vbi_format vbi;
141 struct v4l2_sliced_vbi_format sliced; 157 struct v4l2_sliced_vbi_format sliced;
@@ -152,6 +168,10 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
152 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 168 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
153 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 169 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
154 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); 170 return get_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
171 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
172 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
173 return get_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
174 &up->fmt.pix_mp);
155 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 175 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
156 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 176 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
157 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win); 177 return get_v4l2_window32(&kp->fmt.win, &up->fmt.win);
@@ -181,6 +201,10 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
181 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 201 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
182 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 202 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
183 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix); 203 return put_v4l2_pix_format(&kp->fmt.pix, &up->fmt.pix);
204 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
205 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
206 return put_v4l2_pix_format_mplane(&kp->fmt.pix_mp,
207 &up->fmt.pix_mp);
184 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 208 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
185 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 209 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
186 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win); 210 return put_v4l2_window32(&kp->fmt.win, &up->fmt.win);
@@ -232,6 +256,17 @@ static int put_v4l2_standard32(struct v4l2_standard *kp, struct v4l2_standard32
232 return 0; 256 return 0;
233} 257}
234 258
259struct v4l2_plane32 {
260 __u32 bytesused;
261 __u32 length;
262 union {
263 __u32 mem_offset;
264 compat_long_t userptr;
265 } m;
266 __u32 data_offset;
267 __u32 reserved[11];
268};
269
235struct v4l2_buffer32 { 270struct v4l2_buffer32 {
236 __u32 index; 271 __u32 index;
237 enum v4l2_buf_type type; 272 enum v4l2_buf_type type;
@@ -247,14 +282,64 @@ struct v4l2_buffer32 {
247 union { 282 union {
248 __u32 offset; 283 __u32 offset;
249 compat_long_t userptr; 284 compat_long_t userptr;
285 compat_caddr_t planes;
250 } m; 286 } m;
251 __u32 length; 287 __u32 length;
252 __u32 input; 288 __u32 input;
253 __u32 reserved; 289 __u32 reserved;
254}; 290};
255 291
292static int get_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
293 enum v4l2_memory memory)
294{
295 void __user *up_pln;
296 compat_long_t p;
297
298 if (copy_in_user(up, up32, 2 * sizeof(__u32)) ||
299 copy_in_user(&up->data_offset, &up32->data_offset,
300 sizeof(__u32)))
301 return -EFAULT;
302
303 if (memory == V4L2_MEMORY_USERPTR) {
304 if (get_user(p, &up32->m.userptr))
305 return -EFAULT;
306 up_pln = compat_ptr(p);
307 if (put_user((unsigned long)up_pln, &up->m.userptr))
308 return -EFAULT;
309 } else {
310 if (copy_in_user(&up->m.mem_offset, &up32->m.mem_offset,
311 sizeof(__u32)))
312 return -EFAULT;
313 }
314
315 return 0;
316}
317
318static int put_v4l2_plane32(struct v4l2_plane *up, struct v4l2_plane32 *up32,
319 enum v4l2_memory memory)
320{
321 if (copy_in_user(up32, up, 2 * sizeof(__u32)) ||
322 copy_in_user(&up32->data_offset, &up->data_offset,
323 sizeof(__u32)))
324 return -EFAULT;
325
326 /* For MMAP, driver might've set up the offset, so copy it back.
327 * USERPTR stays the same (was userspace-provided), so no copying. */
328 if (memory == V4L2_MEMORY_MMAP)
329 if (copy_in_user(&up32->m.mem_offset, &up->m.mem_offset,
330 sizeof(__u32)))
331 return -EFAULT;
332
333 return 0;
334}
335
256static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) 336static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
257{ 337{
338 struct v4l2_plane32 __user *uplane32;
339 struct v4l2_plane __user *uplane;
340 compat_caddr_t p;
341 int num_planes;
342 int ret;
258 343
259 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) || 344 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_buffer32)) ||
260 get_user(kp->index, &up->index) || 345 get_user(kp->index, &up->index) ||
@@ -263,33 +348,84 @@ static int get_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
263 get_user(kp->memory, &up->memory) || 348 get_user(kp->memory, &up->memory) ||
264 get_user(kp->input, &up->input)) 349 get_user(kp->input, &up->input))
265 return -EFAULT; 350 return -EFAULT;
266 switch (kp->memory) { 351
267 case V4L2_MEMORY_MMAP: 352 if (V4L2_TYPE_IS_OUTPUT(kp->type))
268 if (get_user(kp->length, &up->length) || 353 if (get_user(kp->bytesused, &up->bytesused) ||
269 get_user(kp->m.offset, &up->m.offset)) 354 get_user(kp->field, &up->field) ||
355 get_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
356 get_user(kp->timestamp.tv_usec,
357 &up->timestamp.tv_usec))
270 return -EFAULT; 358 return -EFAULT;
271 break;
272 case V4L2_MEMORY_USERPTR:
273 {
274 compat_long_t tmp;
275 359
276 if (get_user(kp->length, &up->length) || 360 if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
277 get_user(tmp, &up->m.userptr)) 361 if (get_user(kp->length, &up->length))
278 return -EFAULT; 362 return -EFAULT;
279 363
280 kp->m.userptr = (unsigned long)compat_ptr(tmp); 364 num_planes = kp->length;
365 if (num_planes == 0) {
366 kp->m.planes = NULL;
367 /* num_planes == 0 is legal, e.g. when userspace doesn't
368 * need planes array on DQBUF*/
369 return 0;
281 } 370 }
282 break; 371
283 case V4L2_MEMORY_OVERLAY: 372 if (get_user(p, &up->m.planes))
284 if (get_user(kp->m.offset, &up->m.offset))
285 return -EFAULT; 373 return -EFAULT;
286 break; 374
375 uplane32 = compat_ptr(p);
376 if (!access_ok(VERIFY_READ, uplane32,
377 num_planes * sizeof(struct v4l2_plane32)))
378 return -EFAULT;
379
380 /* We don't really care if userspace decides to kill itself
381 * by passing a very big num_planes value */
382 uplane = compat_alloc_user_space(num_planes *
383 sizeof(struct v4l2_plane));
384 kp->m.planes = uplane;
385
386 while (--num_planes >= 0) {
387 ret = get_v4l2_plane32(uplane, uplane32, kp->memory);
388 if (ret)
389 return ret;
390 ++uplane;
391 ++uplane32;
392 }
393 } else {
394 switch (kp->memory) {
395 case V4L2_MEMORY_MMAP:
396 if (get_user(kp->length, &up->length) ||
397 get_user(kp->m.offset, &up->m.offset))
398 return -EFAULT;
399 break;
400 case V4L2_MEMORY_USERPTR:
401 {
402 compat_long_t tmp;
403
404 if (get_user(kp->length, &up->length) ||
405 get_user(tmp, &up->m.userptr))
406 return -EFAULT;
407
408 kp->m.userptr = (unsigned long)compat_ptr(tmp);
409 }
410 break;
411 case V4L2_MEMORY_OVERLAY:
412 if (get_user(kp->m.offset, &up->m.offset))
413 return -EFAULT;
414 break;
415 }
287 } 416 }
417
288 return 0; 418 return 0;
289} 419}
290 420
291static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up) 421static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user *up)
292{ 422{
423 struct v4l2_plane32 __user *uplane32;
424 struct v4l2_plane __user *uplane;
425 compat_caddr_t p;
426 int num_planes;
427 int ret;
428
293 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) || 429 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_buffer32)) ||
294 put_user(kp->index, &up->index) || 430 put_user(kp->index, &up->index) ||
295 put_user(kp->type, &up->type) || 431 put_user(kp->type, &up->type) ||
@@ -297,22 +433,7 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
297 put_user(kp->memory, &up->memory) || 433 put_user(kp->memory, &up->memory) ||
298 put_user(kp->input, &up->input)) 434 put_user(kp->input, &up->input))
299 return -EFAULT; 435 return -EFAULT;
300 switch (kp->memory) { 436
301 case V4L2_MEMORY_MMAP:
302 if (put_user(kp->length, &up->length) ||
303 put_user(kp->m.offset, &up->m.offset))
304 return -EFAULT;
305 break;
306 case V4L2_MEMORY_USERPTR:
307 if (put_user(kp->length, &up->length) ||
308 put_user(kp->m.userptr, &up->m.userptr))
309 return -EFAULT;
310 break;
311 case V4L2_MEMORY_OVERLAY:
312 if (put_user(kp->m.offset, &up->m.offset))
313 return -EFAULT;
314 break;
315 }
316 if (put_user(kp->bytesused, &up->bytesused) || 437 if (put_user(kp->bytesused, &up->bytesused) ||
317 put_user(kp->field, &up->field) || 438 put_user(kp->field, &up->field) ||
318 put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) || 439 put_user(kp->timestamp.tv_sec, &up->timestamp.tv_sec) ||
@@ -321,6 +442,43 @@ static int put_v4l2_buffer32(struct v4l2_buffer *kp, struct v4l2_buffer32 __user
321 put_user(kp->sequence, &up->sequence) || 442 put_user(kp->sequence, &up->sequence) ||
322 put_user(kp->reserved, &up->reserved)) 443 put_user(kp->reserved, &up->reserved))
323 return -EFAULT; 444 return -EFAULT;
445
446 if (V4L2_TYPE_IS_MULTIPLANAR(kp->type)) {
447 num_planes = kp->length;
448 if (num_planes == 0)
449 return 0;
450
451 uplane = kp->m.planes;
452 if (get_user(p, &up->m.planes))
453 return -EFAULT;
454 uplane32 = compat_ptr(p);
455
456 while (--num_planes >= 0) {
457 ret = put_v4l2_plane32(uplane, uplane32, kp->memory);
458 if (ret)
459 return ret;
460 ++uplane;
461 ++uplane32;
462 }
463 } else {
464 switch (kp->memory) {
465 case V4L2_MEMORY_MMAP:
466 if (put_user(kp->length, &up->length) ||
467 put_user(kp->m.offset, &up->m.offset))
468 return -EFAULT;
469 break;
470 case V4L2_MEMORY_USERPTR:
471 if (put_user(kp->length, &up->length) ||
472 put_user(kp->m.userptr, &up->m.userptr))
473 return -EFAULT;
474 break;
475 case V4L2_MEMORY_OVERLAY:
476 if (put_user(kp->m.offset, &up->m.offset))
477 return -EFAULT;
478 break;
479 }
480 }
481
324 return 0; 482 return 0;
325} 483}
326 484
@@ -442,12 +600,13 @@ static int get_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
442 if (get_user(p, &up->controls)) 600 if (get_user(p, &up->controls))
443 return -EFAULT; 601 return -EFAULT;
444 ucontrols = compat_ptr(p); 602 ucontrols = compat_ptr(p);
445 if (!access_ok(VERIFY_READ, ucontrols, n * sizeof(struct v4l2_ext_control))) 603 if (!access_ok(VERIFY_READ, ucontrols,
604 n * sizeof(struct v4l2_ext_control32)))
446 return -EFAULT; 605 return -EFAULT;
447 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control)); 606 kcontrols = compat_alloc_user_space(n * sizeof(struct v4l2_ext_control));
448 kp->controls = kcontrols; 607 kp->controls = kcontrols;
449 while (--n >= 0) { 608 while (--n >= 0) {
450 if (copy_in_user(kcontrols, ucontrols, sizeof(*kcontrols))) 609 if (copy_in_user(kcontrols, ucontrols, sizeof(*ucontrols)))
451 return -EFAULT; 610 return -EFAULT;
452 if (ctrl_is_pointer(kcontrols->id)) { 611 if (ctrl_is_pointer(kcontrols->id)) {
453 void __user *s; 612 void __user *s;
@@ -483,7 +642,8 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
483 if (get_user(p, &up->controls)) 642 if (get_user(p, &up->controls))
484 return -EFAULT; 643 return -EFAULT;
485 ucontrols = compat_ptr(p); 644 ucontrols = compat_ptr(p);
486 if (!access_ok(VERIFY_WRITE, ucontrols, n * sizeof(struct v4l2_ext_control))) 645 if (!access_ok(VERIFY_WRITE, ucontrols,
646 n * sizeof(struct v4l2_ext_control32)))
487 return -EFAULT; 647 return -EFAULT;
488 648
489 while (--n >= 0) { 649 while (--n >= 0) {
@@ -517,9 +677,6 @@ static int put_v4l2_ext_controls32(struct v4l2_ext_controls *kp, struct v4l2_ext
517#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) 677#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
518 678
519#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32) 679#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
520#ifdef __OLD_VIDIOC_
521#define VIDIOC_OVERLAY32_OLD _IOWR('V', 14, s32)
522#endif
523#define VIDIOC_STREAMON32 _IOW ('V', 18, s32) 680#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
524#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32) 681#define VIDIOC_STREAMOFF32 _IOW ('V', 19, s32)
525#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32) 682#define VIDIOC_G_INPUT32 _IOR ('V', 38, s32)
@@ -559,9 +716,6 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
559 case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break; 716 case VIDIOC_S_EXT_CTRLS32: cmd = VIDIOC_S_EXT_CTRLS; break;
560 case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break; 717 case VIDIOC_TRY_EXT_CTRLS32: cmd = VIDIOC_TRY_EXT_CTRLS; break;
561 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break; 718 case VIDIOC_OVERLAY32: cmd = VIDIOC_OVERLAY; break;
562#ifdef __OLD_VIDIOC_
563 case VIDIOC_OVERLAY32_OLD: cmd = VIDIOC_OVERLAY; break;
564#endif
565 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break; 719 case VIDIOC_STREAMON32: cmd = VIDIOC_STREAMON; break;
566 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break; 720 case VIDIOC_STREAMOFF32: cmd = VIDIOC_STREAMOFF; break;
567 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break; 721 case VIDIOC_G_INPUT32: cmd = VIDIOC_G_INPUT; break;
@@ -695,14 +849,6 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
695 return ret; 849 return ret;
696 850
697 switch (cmd) { 851 switch (cmd) {
698#ifdef __OLD_VIDIOC_
699 case VIDIOC_OVERLAY32_OLD:
700 case VIDIOC_S_PARM_OLD:
701 case VIDIOC_S_CTRL_OLD:
702 case VIDIOC_G_AUDIO_OLD:
703 case VIDIOC_G_AUDOUT_OLD:
704 case VIDIOC_CROPCAP_OLD:
705#endif
706 case VIDIOC_QUERYCAP: 852 case VIDIOC_QUERYCAP:
707 case VIDIOC_RESERVED: 853 case VIDIOC_RESERVED:
708 case VIDIOC_ENUM_FMT: 854 case VIDIOC_ENUM_FMT:
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index ef66d2af0c57..2412f08527aa 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -1364,6 +1364,8 @@ EXPORT_SYMBOL(v4l2_queryctrl);
1364 1364
1365int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 1365int v4l2_subdev_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
1366{ 1366{
1367 if (qc->id & V4L2_CTRL_FLAG_NEXT_CTRL)
1368 return -EINVAL;
1367 return v4l2_queryctrl(sd->ctrl_handler, qc); 1369 return v4l2_queryctrl(sd->ctrl_handler, qc);
1368} 1370}
1369EXPORT_SYMBOL(v4l2_subdev_queryctrl); 1371EXPORT_SYMBOL(v4l2_subdev_queryctrl);
diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c
index 341764a3a990..498e6742579e 100644
--- a/drivers/media/video/v4l2-dev.c
+++ b/drivers/media/video/v4l2-dev.c
@@ -143,6 +143,7 @@ static inline void video_put(struct video_device *vdev)
143static void v4l2_device_release(struct device *cd) 143static void v4l2_device_release(struct device *cd)
144{ 144{
145 struct video_device *vdev = to_video_device(cd); 145 struct video_device *vdev = to_video_device(cd);
146 struct v4l2_device *v4l2_dev = vdev->v4l2_dev;
146 147
147 mutex_lock(&videodev_lock); 148 mutex_lock(&videodev_lock);
148 if (video_device[vdev->minor] != vdev) { 149 if (video_device[vdev->minor] != vdev) {
@@ -169,6 +170,10 @@ static void v4l2_device_release(struct device *cd)
169 /* Release video_device and perform other 170 /* Release video_device and perform other
170 cleanups as needed. */ 171 cleanups as needed. */
171 vdev->release(vdev); 172 vdev->release(vdev);
173
174 /* Decrease v4l2_device refcount */
175 if (v4l2_dev)
176 v4l2_device_put(v4l2_dev);
172} 177}
173 178
174static struct class video_class = { 179static struct class video_class = {
@@ -182,6 +187,70 @@ struct video_device *video_devdata(struct file *file)
182} 187}
183EXPORT_SYMBOL(video_devdata); 188EXPORT_SYMBOL(video_devdata);
184 189
190
191/* Priority handling */
192
193static inline bool prio_is_valid(enum v4l2_priority prio)
194{
195 return prio == V4L2_PRIORITY_BACKGROUND ||
196 prio == V4L2_PRIORITY_INTERACTIVE ||
197 prio == V4L2_PRIORITY_RECORD;
198}
199
200void v4l2_prio_init(struct v4l2_prio_state *global)
201{
202 memset(global, 0, sizeof(*global));
203}
204EXPORT_SYMBOL(v4l2_prio_init);
205
206int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
207 enum v4l2_priority new)
208{
209 if (!prio_is_valid(new))
210 return -EINVAL;
211 if (*local == new)
212 return 0;
213
214 atomic_inc(&global->prios[new]);
215 if (prio_is_valid(*local))
216 atomic_dec(&global->prios[*local]);
217 *local = new;
218 return 0;
219}
220EXPORT_SYMBOL(v4l2_prio_change);
221
222void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local)
223{
224 v4l2_prio_change(global, local, V4L2_PRIORITY_DEFAULT);
225}
226EXPORT_SYMBOL(v4l2_prio_open);
227
228void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local)
229{
230 if (prio_is_valid(local))
231 atomic_dec(&global->prios[local]);
232}
233EXPORT_SYMBOL(v4l2_prio_close);
234
235enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global)
236{
237 if (atomic_read(&global->prios[V4L2_PRIORITY_RECORD]) > 0)
238 return V4L2_PRIORITY_RECORD;
239 if (atomic_read(&global->prios[V4L2_PRIORITY_INTERACTIVE]) > 0)
240 return V4L2_PRIORITY_INTERACTIVE;
241 if (atomic_read(&global->prios[V4L2_PRIORITY_BACKGROUND]) > 0)
242 return V4L2_PRIORITY_BACKGROUND;
243 return V4L2_PRIORITY_UNSET;
244}
245EXPORT_SYMBOL(v4l2_prio_max);
246
247int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local)
248{
249 return (local < v4l2_prio_max(global)) ? -EBUSY : 0;
250}
251EXPORT_SYMBOL(v4l2_prio_check);
252
253
185static ssize_t v4l2_read(struct file *filp, char __user *buf, 254static ssize_t v4l2_read(struct file *filp, char __user *buf,
186 size_t sz, loff_t *off) 255 size_t sz, loff_t *off)
187{ 256{
@@ -303,6 +372,9 @@ static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
303static int v4l2_open(struct inode *inode, struct file *filp) 372static int v4l2_open(struct inode *inode, struct file *filp)
304{ 373{
305 struct video_device *vdev; 374 struct video_device *vdev;
375#if defined(CONFIG_MEDIA_CONTROLLER)
376 struct media_entity *entity = NULL;
377#endif
306 int ret = 0; 378 int ret = 0;
307 379
308 /* Check if the video device is available */ 380 /* Check if the video device is available */
@@ -316,6 +388,16 @@ static int v4l2_open(struct inode *inode, struct file *filp)
316 /* and increase the device refcount */ 388 /* and increase the device refcount */
317 video_get(vdev); 389 video_get(vdev);
318 mutex_unlock(&videodev_lock); 390 mutex_unlock(&videodev_lock);
391#if defined(CONFIG_MEDIA_CONTROLLER)
392 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
393 entity = media_entity_get(&vdev->entity);
394 if (!entity) {
395 ret = -EBUSY;
396 video_put(vdev);
397 return ret;
398 }
399 }
400#endif
319 if (vdev->fops->open) { 401 if (vdev->fops->open) {
320 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) { 402 if (vdev->lock && mutex_lock_interruptible(vdev->lock)) {
321 ret = -ERESTARTSYS; 403 ret = -ERESTARTSYS;
@@ -331,8 +413,13 @@ static int v4l2_open(struct inode *inode, struct file *filp)
331 413
332err: 414err:
333 /* decrease the refcount in case of an error */ 415 /* decrease the refcount in case of an error */
334 if (ret) 416 if (ret) {
417#if defined(CONFIG_MEDIA_CONTROLLER)
418 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
419 media_entity_put(entity);
420#endif
335 video_put(vdev); 421 video_put(vdev);
422 }
336 return ret; 423 return ret;
337} 424}
338 425
@@ -349,7 +436,10 @@ static int v4l2_release(struct inode *inode, struct file *filp)
349 if (vdev->lock) 436 if (vdev->lock)
350 mutex_unlock(vdev->lock); 437 mutex_unlock(vdev->lock);
351 } 438 }
352 439#if defined(CONFIG_MEDIA_CONTROLLER)
440 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
441 media_entity_put(&vdev->entity);
442#endif
353 /* decrease the refcount unconditionally since the release() 443 /* decrease the refcount unconditionally since the release()
354 return value is ignored. */ 444 return value is ignored. */
355 video_put(vdev); 445 video_put(vdev);
@@ -408,13 +498,14 @@ static int get_index(struct video_device *vdev)
408} 498}
409 499
410/** 500/**
411 * video_register_device - register video4linux devices 501 * __video_register_device - register video4linux devices
412 * @vdev: video device structure we want to register 502 * @vdev: video device structure we want to register
413 * @type: type of device to register 503 * @type: type of device to register
414 * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ... 504 * @nr: which device node number (0 == /dev/video0, 1 == /dev/video1, ...
415 * -1 == first free) 505 * -1 == first free)
416 * @warn_if_nr_in_use: warn if the desired device node number 506 * @warn_if_nr_in_use: warn if the desired device node number
417 * was already in use and another number was chosen instead. 507 * was already in use and another number was chosen instead.
508 * @owner: module that owns the video device node
418 * 509 *
419 * The registration code assigns minor numbers and device node numbers 510 * The registration code assigns minor numbers and device node numbers
420 * based on the requested type and registers the new device node with 511 * based on the requested type and registers the new device node with
@@ -435,9 +526,11 @@ static int get_index(struct video_device *vdev)
435 * %VFL_TYPE_VBI - Vertical blank data (undecoded) 526 * %VFL_TYPE_VBI - Vertical blank data (undecoded)
436 * 527 *
437 * %VFL_TYPE_RADIO - A radio card 528 * %VFL_TYPE_RADIO - A radio card
529 *
530 * %VFL_TYPE_SUBDEV - A subdevice
438 */ 531 */
439static int __video_register_device(struct video_device *vdev, int type, int nr, 532int __video_register_device(struct video_device *vdev, int type, int nr,
440 int warn_if_nr_in_use) 533 int warn_if_nr_in_use, struct module *owner)
441{ 534{
442 int i = 0; 535 int i = 0;
443 int ret; 536 int ret;
@@ -469,6 +562,9 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
469 case VFL_TYPE_RADIO: 562 case VFL_TYPE_RADIO:
470 name_base = "radio"; 563 name_base = "radio";
471 break; 564 break;
565 case VFL_TYPE_SUBDEV:
566 name_base = "v4l-subdev";
567 break;
472 default: 568 default:
473 printk(KERN_ERR "%s called with unknown type: %d\n", 569 printk(KERN_ERR "%s called with unknown type: %d\n",
474 __func__, type); 570 __func__, type);
@@ -482,6 +578,10 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
482 vdev->parent = vdev->v4l2_dev->dev; 578 vdev->parent = vdev->v4l2_dev->dev;
483 if (vdev->ctrl_handler == NULL) 579 if (vdev->ctrl_handler == NULL)
484 vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler; 580 vdev->ctrl_handler = vdev->v4l2_dev->ctrl_handler;
581 /* If the prio state pointer is NULL, then use the v4l2_device
582 prio state. */
583 if (vdev->prio == NULL)
584 vdev->prio = &vdev->v4l2_dev->prio;
485 } 585 }
486 586
487 /* Part 2: find a free minor, device node number and device index. */ 587 /* Part 2: find a free minor, device node number and device index. */
@@ -552,7 +652,7 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
552 goto cleanup; 652 goto cleanup;
553 } 653 }
554 vdev->cdev->ops = &v4l2_fops; 654 vdev->cdev->ops = &v4l2_fops;
555 vdev->cdev->owner = vdev->fops->owner; 655 vdev->cdev->owner = owner;
556 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1); 656 ret = cdev_add(vdev->cdev, MKDEV(VIDEO_MAJOR, vdev->minor), 1);
557 if (ret < 0) { 657 if (ret < 0) {
558 printk(KERN_ERR "%s: cdev_add failed\n", __func__); 658 printk(KERN_ERR "%s: cdev_add failed\n", __func__);
@@ -580,11 +680,31 @@ static int __video_register_device(struct video_device *vdev, int type, int nr,
580 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__, 680 printk(KERN_WARNING "%s: requested %s%d, got %s\n", __func__,
581 name_base, nr, video_device_node_name(vdev)); 681 name_base, nr, video_device_node_name(vdev));
582 682
583 /* Part 5: Activate this minor. The char device can now be used. */ 683 /* Increase v4l2_device refcount */
684 if (vdev->v4l2_dev)
685 v4l2_device_get(vdev->v4l2_dev);
686
687#if defined(CONFIG_MEDIA_CONTROLLER)
688 /* Part 5: Register the entity. */
689 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
690 vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
691 vdev->entity.name = vdev->name;
692 vdev->entity.v4l.major = VIDEO_MAJOR;
693 vdev->entity.v4l.minor = vdev->minor;
694 ret = media_device_register_entity(vdev->v4l2_dev->mdev,
695 &vdev->entity);
696 if (ret < 0)
697 printk(KERN_WARNING
698 "%s: media_device_register_entity failed\n",
699 __func__);
700 }
701#endif
702 /* Part 6: Activate this minor. The char device can now be used. */
584 set_bit(V4L2_FL_REGISTERED, &vdev->flags); 703 set_bit(V4L2_FL_REGISTERED, &vdev->flags);
585 mutex_lock(&videodev_lock); 704 mutex_lock(&videodev_lock);
586 video_device[vdev->minor] = vdev; 705 video_device[vdev->minor] = vdev;
587 mutex_unlock(&videodev_lock); 706 mutex_unlock(&videodev_lock);
707
588 return 0; 708 return 0;
589 709
590cleanup: 710cleanup:
@@ -597,18 +717,7 @@ cleanup:
597 vdev->minor = -1; 717 vdev->minor = -1;
598 return ret; 718 return ret;
599} 719}
600 720EXPORT_SYMBOL(__video_register_device);
601int video_register_device(struct video_device *vdev, int type, int nr)
602{
603 return __video_register_device(vdev, type, nr, 1);
604}
605EXPORT_SYMBOL(video_register_device);
606
607int video_register_device_no_warn(struct video_device *vdev, int type, int nr)
608{
609 return __video_register_device(vdev, type, nr, 0);
610}
611EXPORT_SYMBOL(video_register_device_no_warn);
612 721
613/** 722/**
614 * video_unregister_device - unregister a video4linux device 723 * video_unregister_device - unregister a video4linux device
@@ -623,6 +732,11 @@ void video_unregister_device(struct video_device *vdev)
623 if (!vdev || !video_is_registered(vdev)) 732 if (!vdev || !video_is_registered(vdev))
624 return; 733 return;
625 734
735#if defined(CONFIG_MEDIA_CONTROLLER)
736 if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
737 media_device_unregister_entity(&vdev->entity);
738#endif
739
626 mutex_lock(&videodev_lock); 740 mutex_lock(&videodev_lock);
627 /* This must be in a critical section to prevent a race with v4l2_open. 741 /* This must be in a critical section to prevent a race with v4l2_open.
628 * Once this bit has been cleared video_get may never be called again. 742 * Once this bit has been cleared video_get may never be called again.
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index ce64fe16bc60..5aeaf876ba9b 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -36,6 +36,8 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
36 INIT_LIST_HEAD(&v4l2_dev->subdevs); 36 INIT_LIST_HEAD(&v4l2_dev->subdevs);
37 spin_lock_init(&v4l2_dev->lock); 37 spin_lock_init(&v4l2_dev->lock);
38 mutex_init(&v4l2_dev->ioctl_lock); 38 mutex_init(&v4l2_dev->ioctl_lock);
39 v4l2_prio_init(&v4l2_dev->prio);
40 kref_init(&v4l2_dev->ref);
39 v4l2_dev->dev = dev; 41 v4l2_dev->dev = dev;
40 if (dev == NULL) { 42 if (dev == NULL) {
41 /* If dev == NULL, then name must be filled in by the caller */ 43 /* If dev == NULL, then name must be filled in by the caller */
@@ -47,13 +49,27 @@ int v4l2_device_register(struct device *dev, struct v4l2_device *v4l2_dev)
47 if (!v4l2_dev->name[0]) 49 if (!v4l2_dev->name[0])
48 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s", 50 snprintf(v4l2_dev->name, sizeof(v4l2_dev->name), "%s %s",
49 dev->driver->name, dev_name(dev)); 51 dev->driver->name, dev_name(dev));
50 if (dev_get_drvdata(dev)) 52 if (!dev_get_drvdata(dev))
51 v4l2_warn(v4l2_dev, "Non-NULL drvdata on register\n"); 53 dev_set_drvdata(dev, v4l2_dev);
52 dev_set_drvdata(dev, v4l2_dev);
53 return 0; 54 return 0;
54} 55}
55EXPORT_SYMBOL_GPL(v4l2_device_register); 56EXPORT_SYMBOL_GPL(v4l2_device_register);
56 57
58static void v4l2_device_release(struct kref *ref)
59{
60 struct v4l2_device *v4l2_dev =
61 container_of(ref, struct v4l2_device, ref);
62
63 if (v4l2_dev->release)
64 v4l2_dev->release(v4l2_dev);
65}
66
67int v4l2_device_put(struct v4l2_device *v4l2_dev)
68{
69 return kref_put(&v4l2_dev->ref, v4l2_device_release);
70}
71EXPORT_SYMBOL_GPL(v4l2_device_put);
72
57int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename, 73int v4l2_device_set_name(struct v4l2_device *v4l2_dev, const char *basename,
58 atomic_t *instance) 74 atomic_t *instance)
59{ 75{
@@ -72,10 +88,12 @@ EXPORT_SYMBOL_GPL(v4l2_device_set_name);
72 88
73void v4l2_device_disconnect(struct v4l2_device *v4l2_dev) 89void v4l2_device_disconnect(struct v4l2_device *v4l2_dev)
74{ 90{
75 if (v4l2_dev->dev) { 91 if (v4l2_dev->dev == NULL)
92 return;
93
94 if (dev_get_drvdata(v4l2_dev->dev) == v4l2_dev)
76 dev_set_drvdata(v4l2_dev->dev, NULL); 95 dev_set_drvdata(v4l2_dev->dev, NULL);
77 v4l2_dev->dev = NULL; 96 v4l2_dev->dev = NULL;
78 }
79} 97}
80EXPORT_SYMBOL_GPL(v4l2_device_disconnect); 98EXPORT_SYMBOL_GPL(v4l2_device_disconnect);
81 99
@@ -117,23 +135,30 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
117EXPORT_SYMBOL_GPL(v4l2_device_unregister); 135EXPORT_SYMBOL_GPL(v4l2_device_unregister);
118 136
119int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev, 137int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
120 struct v4l2_subdev *sd) 138 struct v4l2_subdev *sd)
121{ 139{
140#if defined(CONFIG_MEDIA_CONTROLLER)
141 struct media_entity *entity = &sd->entity;
142#endif
122 int err; 143 int err;
123 144
124 /* Check for valid input */ 145 /* Check for valid input */
125 if (v4l2_dev == NULL || sd == NULL || !sd->name[0]) 146 if (v4l2_dev == NULL || sd == NULL || !sd->name[0])
126 return -EINVAL; 147 return -EINVAL;
148
127 /* Warn if we apparently re-register a subdev */ 149 /* Warn if we apparently re-register a subdev */
128 WARN_ON(sd->v4l2_dev != NULL); 150 WARN_ON(sd->v4l2_dev != NULL);
151
129 if (!try_module_get(sd->owner)) 152 if (!try_module_get(sd->owner))
130 return -ENODEV; 153 return -ENODEV;
154
131 sd->v4l2_dev = v4l2_dev; 155 sd->v4l2_dev = v4l2_dev;
132 if (sd->internal_ops && sd->internal_ops->registered) { 156 if (sd->internal_ops && sd->internal_ops->registered) {
133 err = sd->internal_ops->registered(sd); 157 err = sd->internal_ops->registered(sd);
134 if (err) 158 if (err)
135 return err; 159 return err;
136 } 160 }
161
137 /* This just returns 0 if either of the two args is NULL */ 162 /* This just returns 0 if either of the two args is NULL */
138 err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler); 163 err = v4l2_ctrl_add_handler(v4l2_dev->ctrl_handler, sd->ctrl_handler);
139 if (err) { 164 if (err) {
@@ -141,24 +166,82 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
141 sd->internal_ops->unregistered(sd); 166 sd->internal_ops->unregistered(sd);
142 return err; 167 return err;
143 } 168 }
169
170#if defined(CONFIG_MEDIA_CONTROLLER)
171 /* Register the entity. */
172 if (v4l2_dev->mdev) {
173 err = media_device_register_entity(v4l2_dev->mdev, entity);
174 if (err < 0) {
175 if (sd->internal_ops && sd->internal_ops->unregistered)
176 sd->internal_ops->unregistered(sd);
177 module_put(sd->owner);
178 return err;
179 }
180 }
181#endif
182
144 spin_lock(&v4l2_dev->lock); 183 spin_lock(&v4l2_dev->lock);
145 list_add_tail(&sd->list, &v4l2_dev->subdevs); 184 list_add_tail(&sd->list, &v4l2_dev->subdevs);
146 spin_unlock(&v4l2_dev->lock); 185 spin_unlock(&v4l2_dev->lock);
186
147 return 0; 187 return 0;
148} 188}
149EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); 189EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
150 190
191int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
192{
193 struct video_device *vdev;
194 struct v4l2_subdev *sd;
195 int err;
196
197 /* Register a device node for every subdev marked with the
198 * V4L2_SUBDEV_FL_HAS_DEVNODE flag.
199 */
200 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
201 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
202 continue;
203
204 vdev = &sd->devnode;
205 strlcpy(vdev->name, sd->name, sizeof(vdev->name));
206 vdev->v4l2_dev = v4l2_dev;
207 vdev->fops = &v4l2_subdev_fops;
208 vdev->release = video_device_release_empty;
209 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
210 sd->owner);
211 if (err < 0)
212 return err;
213#if defined(CONFIG_MEDIA_CONTROLLER)
214 sd->entity.v4l.major = VIDEO_MAJOR;
215 sd->entity.v4l.minor = vdev->minor;
216#endif
217 }
218 return 0;
219}
220EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
221
151void v4l2_device_unregister_subdev(struct v4l2_subdev *sd) 222void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
152{ 223{
224 struct v4l2_device *v4l2_dev;
225
153 /* return if it isn't registered */ 226 /* return if it isn't registered */
154 if (sd == NULL || sd->v4l2_dev == NULL) 227 if (sd == NULL || sd->v4l2_dev == NULL)
155 return; 228 return;
156 spin_lock(&sd->v4l2_dev->lock); 229
230 v4l2_dev = sd->v4l2_dev;
231
232 spin_lock(&v4l2_dev->lock);
157 list_del(&sd->list); 233 list_del(&sd->list);
158 spin_unlock(&sd->v4l2_dev->lock); 234 spin_unlock(&v4l2_dev->lock);
235
159 if (sd->internal_ops && sd->internal_ops->unregistered) 236 if (sd->internal_ops && sd->internal_ops->unregistered)
160 sd->internal_ops->unregistered(sd); 237 sd->internal_ops->unregistered(sd);
161 sd->v4l2_dev = NULL; 238 sd->v4l2_dev = NULL;
239
240#if defined(CONFIG_MEDIA_CONTROLLER)
241 if (v4l2_dev->mdev)
242 media_device_unregister_entity(&sd->entity);
243#endif
244 video_unregister_device(&sd->devnode);
162 module_put(sd->owner); 245 module_put(sd->owner);
163} 246}
164EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); 247EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-fh.c b/drivers/media/video/v4l2-fh.c
index d78f184f40c5..717f71e6370e 100644
--- a/drivers/media/video/v4l2-fh.c
+++ b/drivers/media/video/v4l2-fh.c
@@ -23,6 +23,7 @@
23 */ 23 */
24 24
25#include <linux/bitops.h> 25#include <linux/bitops.h>
26#include <linux/slab.h>
26#include <media/v4l2-dev.h> 27#include <media/v4l2-dev.h>
27#include <media/v4l2-fh.h> 28#include <media/v4l2-fh.h>
28#include <media/v4l2-event.h> 29#include <media/v4l2-event.h>
@@ -33,6 +34,7 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
33 fh->vdev = vdev; 34 fh->vdev = vdev;
34 INIT_LIST_HEAD(&fh->list); 35 INIT_LIST_HEAD(&fh->list);
35 set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags); 36 set_bit(V4L2_FL_USES_V4L2_FH, &fh->vdev->flags);
37 fh->prio = V4L2_PRIORITY_UNSET;
36 38
37 /* 39 /*
38 * fh->events only needs to be initialized if the driver 40 * fh->events only needs to be initialized if the driver
@@ -51,12 +53,28 @@ void v4l2_fh_add(struct v4l2_fh *fh)
51{ 53{
52 unsigned long flags; 54 unsigned long flags;
53 55
56 if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
57 v4l2_prio_open(fh->vdev->prio, &fh->prio);
54 spin_lock_irqsave(&fh->vdev->fh_lock, flags); 58 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
55 list_add(&fh->list, &fh->vdev->fh_list); 59 list_add(&fh->list, &fh->vdev->fh_list);
56 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 60 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
57} 61}
58EXPORT_SYMBOL_GPL(v4l2_fh_add); 62EXPORT_SYMBOL_GPL(v4l2_fh_add);
59 63
64int v4l2_fh_open(struct file *filp)
65{
66 struct video_device *vdev = video_devdata(filp);
67 struct v4l2_fh *fh = kzalloc(sizeof(*fh), GFP_KERNEL);
68
69 filp->private_data = fh;
70 if (fh == NULL)
71 return -ENOMEM;
72 v4l2_fh_init(fh, vdev);
73 v4l2_fh_add(fh);
74 return 0;
75}
76EXPORT_SYMBOL_GPL(v4l2_fh_open);
77
60void v4l2_fh_del(struct v4l2_fh *fh) 78void v4l2_fh_del(struct v4l2_fh *fh)
61{ 79{
62 unsigned long flags; 80 unsigned long flags;
@@ -64,6 +82,8 @@ void v4l2_fh_del(struct v4l2_fh *fh)
64 spin_lock_irqsave(&fh->vdev->fh_lock, flags); 82 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
65 list_del_init(&fh->list); 83 list_del_init(&fh->list);
66 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags); 84 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
85 if (test_bit(V4L2_FL_USE_FH_PRIO, &fh->vdev->flags))
86 v4l2_prio_close(fh->vdev->prio, fh->prio);
67} 87}
68EXPORT_SYMBOL_GPL(v4l2_fh_del); 88EXPORT_SYMBOL_GPL(v4l2_fh_del);
69 89
@@ -77,3 +97,30 @@ void v4l2_fh_exit(struct v4l2_fh *fh)
77 v4l2_event_free(fh); 97 v4l2_event_free(fh);
78} 98}
79EXPORT_SYMBOL_GPL(v4l2_fh_exit); 99EXPORT_SYMBOL_GPL(v4l2_fh_exit);
100
101int v4l2_fh_release(struct file *filp)
102{
103 struct v4l2_fh *fh = filp->private_data;
104
105 if (fh) {
106 v4l2_fh_del(fh);
107 v4l2_fh_exit(fh);
108 kfree(fh);
109 }
110 return 0;
111}
112EXPORT_SYMBOL_GPL(v4l2_fh_release);
113
114int v4l2_fh_is_singular(struct v4l2_fh *fh)
115{
116 unsigned long flags;
117 int is_singular;
118
119 if (fh == NULL || fh->vdev == NULL)
120 return 0;
121 spin_lock_irqsave(&fh->vdev->fh_lock, flags);
122 is_singular = list_is_singular(&fh->list);
123 spin_unlock_irqrestore(&fh->vdev->fh_lock, flags);
124 return is_singular;
125}
126EXPORT_SYMBOL_GPL(v4l2_fh_is_singular);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index f51327ef6757..a01ed39e6c16 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -17,7 +17,6 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/kernel.h> 18#include <linux/kernel.h>
19 19
20#define __OLD_VIDIOC_ /* To allow fixing old calls */
21#include <linux/videodev2.h> 20#include <linux/videodev2.h>
22 21
23#include <media/v4l2-common.h> 22#include <media/v4l2-common.h>
@@ -25,6 +24,7 @@
25#include <media/v4l2-ctrls.h> 24#include <media/v4l2-ctrls.h>
26#include <media/v4l2-fh.h> 25#include <media/v4l2-fh.h>
27#include <media/v4l2-event.h> 26#include <media/v4l2-event.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-chip-ident.h> 28#include <media/v4l2-chip-ident.h>
29 29
30#define dbgarg(cmd, fmt, arg...) \ 30#define dbgarg(cmd, fmt, arg...) \
@@ -165,6 +165,8 @@ const char *v4l2_type_names[] = {
165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap", 165 [V4L2_BUF_TYPE_SLICED_VBI_CAPTURE] = "sliced-vbi-cap",
166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out", 166 [V4L2_BUF_TYPE_SLICED_VBI_OUTPUT] = "sliced-vbi-out",
167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay", 167 [V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY] = "vid-out-overlay",
168 [V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE] = "vid-cap-mplane",
169 [V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE] = "vid-out-mplane",
168}; 170};
169EXPORT_SYMBOL(v4l2_type_names); 171EXPORT_SYMBOL(v4l2_type_names);
170 172
@@ -293,153 +295,37 @@ void v4l_printk_ioctl(unsigned int cmd)
293} 295}
294EXPORT_SYMBOL(v4l_printk_ioctl); 296EXPORT_SYMBOL(v4l_printk_ioctl);
295 297
296/*
297 * helper function -- handles userspace copying for ioctl arguments
298 */
299
300#ifdef __OLD_VIDIOC_
301static unsigned int
302video_fix_command(unsigned int cmd)
303{
304 switch (cmd) {
305 case VIDIOC_OVERLAY_OLD:
306 cmd = VIDIOC_OVERLAY;
307 break;
308 case VIDIOC_S_PARM_OLD:
309 cmd = VIDIOC_S_PARM;
310 break;
311 case VIDIOC_S_CTRL_OLD:
312 cmd = VIDIOC_S_CTRL;
313 break;
314 case VIDIOC_G_AUDIO_OLD:
315 cmd = VIDIOC_G_AUDIO;
316 break;
317 case VIDIOC_G_AUDOUT_OLD:
318 cmd = VIDIOC_G_AUDOUT;
319 break;
320 case VIDIOC_CROPCAP_OLD:
321 cmd = VIDIOC_CROPCAP;
322 break;
323 }
324 return cmd;
325}
326#endif
327
328/*
329 * Obsolete usercopy function - Should be removed soon
330 */
331long
332video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
333 v4l2_kioctl func)
334{
335 char sbuf[128];
336 void *mbuf = NULL;
337 void *parg = NULL;
338 long err = -EINVAL;
339 int is_ext_ctrl;
340 size_t ctrls_size = 0;
341 void __user *user_ptr = NULL;
342
343#ifdef __OLD_VIDIOC_
344 cmd = video_fix_command(cmd);
345#endif
346 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
347 cmd == VIDIOC_TRY_EXT_CTRLS);
348
349 /* Copy arguments into temp kernel buffer */
350 switch (_IOC_DIR(cmd)) {
351 case _IOC_NONE:
352 parg = NULL;
353 break;
354 case _IOC_READ:
355 case _IOC_WRITE:
356 case (_IOC_WRITE | _IOC_READ):
357 if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
358 parg = sbuf;
359 } else {
360 /* too big to allocate from stack */
361 mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
362 if (NULL == mbuf)
363 return -ENOMEM;
364 parg = mbuf;
365 }
366
367 err = -EFAULT;
368 if (_IOC_DIR(cmd) & _IOC_WRITE)
369 if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))
370 goto out;
371 break;
372 }
373 if (is_ext_ctrl) {
374 struct v4l2_ext_controls *p = parg;
375
376 /* In case of an error, tell the caller that it wasn't
377 a specific control that caused it. */
378 p->error_idx = p->count;
379 user_ptr = (void __user *)p->controls;
380 if (p->count) {
381 ctrls_size = sizeof(struct v4l2_ext_control) * p->count;
382 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */
383 mbuf = kmalloc(ctrls_size, GFP_KERNEL);
384 err = -ENOMEM;
385 if (NULL == mbuf)
386 goto out_ext_ctrl;
387 err = -EFAULT;
388 if (copy_from_user(mbuf, user_ptr, ctrls_size))
389 goto out_ext_ctrl;
390 p->controls = mbuf;
391 }
392 }
393
394 /* call driver */
395 err = func(file, cmd, parg);
396 if (err == -ENOIOCTLCMD)
397 err = -EINVAL;
398 if (is_ext_ctrl) {
399 struct v4l2_ext_controls *p = parg;
400
401 p->controls = (void *)user_ptr;
402 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size))
403 err = -EFAULT;
404 goto out_ext_ctrl;
405 }
406 if (err < 0)
407 goto out;
408
409out_ext_ctrl:
410 /* Copy results into user buffer */
411 switch (_IOC_DIR(cmd)) {
412 case _IOC_READ:
413 case (_IOC_WRITE | _IOC_READ):
414 if (copy_to_user((void __user *)arg, parg, _IOC_SIZE(cmd)))
415 err = -EFAULT;
416 break;
417 }
418
419out:
420 kfree(mbuf);
421 return err;
422}
423EXPORT_SYMBOL(video_usercopy);
424
425static void dbgbuf(unsigned int cmd, struct video_device *vfd, 298static void dbgbuf(unsigned int cmd, struct video_device *vfd,
426 struct v4l2_buffer *p) 299 struct v4l2_buffer *p)
427{ 300{
428 struct v4l2_timecode *tc = &p->timecode; 301 struct v4l2_timecode *tc = &p->timecode;
302 struct v4l2_plane *plane;
303 int i;
429 304
430 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, " 305 dbgarg(cmd, "%02ld:%02d:%02d.%08ld index=%d, type=%s, "
431 "bytesused=%d, flags=0x%08d, " 306 "flags=0x%08d, field=%0d, sequence=%d, memory=%s\n",
432 "field=%0d, sequence=%d, memory=%s, offset/userptr=0x%08lx, length=%d\n",
433 p->timestamp.tv_sec / 3600, 307 p->timestamp.tv_sec / 3600,
434 (int)(p->timestamp.tv_sec / 60) % 60, 308 (int)(p->timestamp.tv_sec / 60) % 60,
435 (int)(p->timestamp.tv_sec % 60), 309 (int)(p->timestamp.tv_sec % 60),
436 (long)p->timestamp.tv_usec, 310 (long)p->timestamp.tv_usec,
437 p->index, 311 p->index,
438 prt_names(p->type, v4l2_type_names), 312 prt_names(p->type, v4l2_type_names),
439 p->bytesused, p->flags, 313 p->flags, p->field, p->sequence,
440 p->field, p->sequence, 314 prt_names(p->memory, v4l2_memory_names));
441 prt_names(p->memory, v4l2_memory_names), 315
442 p->m.userptr, p->length); 316 if (V4L2_TYPE_IS_MULTIPLANAR(p->type) && p->m.planes) {
317 for (i = 0; i < p->length; ++i) {
318 plane = &p->m.planes[i];
319 dbgarg2("plane %d: bytesused=%d, data_offset=0x%08x "
320 "offset/userptr=0x%08lx, length=%d\n",
321 i, plane->bytesused, plane->data_offset,
322 plane->m.userptr, plane->length);
323 }
324 } else {
325 dbgarg2("bytesused=%d, offset/userptr=0x%08lx, length=%d\n",
326 p->bytesused, p->m.userptr, p->length);
327 }
328
443 dbgarg2("timecode=%02d:%02d:%02d type=%d, " 329 dbgarg2("timecode=%02d:%02d:%02d type=%d, "
444 "flags=0x%08d, frames=%d, userbits=0x%08x\n", 330 "flags=0x%08d, frames=%d, userbits=0x%08x\n",
445 tc->hours, tc->minutes, tc->seconds, 331 tc->hours, tc->minutes, tc->seconds,
@@ -467,6 +353,27 @@ static inline void v4l_print_pix_fmt(struct video_device *vfd,
467 fmt->bytesperline, fmt->sizeimage, fmt->colorspace); 353 fmt->bytesperline, fmt->sizeimage, fmt->colorspace);
468}; 354};
469 355
356static inline void v4l_print_pix_fmt_mplane(struct video_device *vfd,
357 struct v4l2_pix_format_mplane *fmt)
358{
359 int i;
360
361 dbgarg2("width=%d, height=%d, format=%c%c%c%c, field=%s, "
362 "colorspace=%d, num_planes=%d\n",
363 fmt->width, fmt->height,
364 (fmt->pixelformat & 0xff),
365 (fmt->pixelformat >> 8) & 0xff,
366 (fmt->pixelformat >> 16) & 0xff,
367 (fmt->pixelformat >> 24) & 0xff,
368 prt_names(fmt->field, v4l2_field_names),
369 fmt->colorspace, fmt->num_planes);
370
371 for (i = 0; i < fmt->num_planes; ++i)
372 dbgarg2("plane %d: bytesperline=%d sizeimage=%d\n", i,
373 fmt->plane_fmt[i].bytesperline,
374 fmt->plane_fmt[i].sizeimage);
375}
376
470static inline void v4l_print_ext_ctrls(unsigned int cmd, 377static inline void v4l_print_ext_ctrls(unsigned int cmd,
471 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals) 378 struct video_device *vfd, struct v4l2_ext_controls *c, int show_vals)
472{ 379{
@@ -520,7 +427,12 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
520 427
521 switch (type) { 428 switch (type) {
522 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 429 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
523 if (ops->vidioc_g_fmt_vid_cap) 430 if (ops->vidioc_g_fmt_vid_cap ||
431 ops->vidioc_g_fmt_vid_cap_mplane)
432 return 0;
433 break;
434 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
435 if (ops->vidioc_g_fmt_vid_cap_mplane)
524 return 0; 436 return 0;
525 break; 437 break;
526 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 438 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
@@ -528,7 +440,12 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
528 return 0; 440 return 0;
529 break; 441 break;
530 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 442 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
531 if (ops->vidioc_g_fmt_vid_out) 443 if (ops->vidioc_g_fmt_vid_out ||
444 ops->vidioc_g_fmt_vid_out_mplane)
445 return 0;
446 break;
447 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
448 if (ops->vidioc_g_fmt_vid_out_mplane)
532 return 0; 449 return 0;
533 break; 450 break;
534 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 451 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
@@ -559,12 +476,72 @@ static int check_fmt(const struct v4l2_ioctl_ops *ops, enum v4l2_buf_type type)
559 return -EINVAL; 476 return -EINVAL;
560} 477}
561 478
479/**
480 * fmt_sp_to_mp() - Convert a single-plane format to its multi-planar 1-plane
481 * equivalent
482 */
483static int fmt_sp_to_mp(const struct v4l2_format *f_sp,
484 struct v4l2_format *f_mp)
485{
486 struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp;
487 const struct v4l2_pix_format *pix = &f_sp->fmt.pix;
488
489 if (f_sp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE)
490 f_mp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
491 else if (f_sp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT)
492 f_mp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
493 else
494 return -EINVAL;
495
496 pix_mp->width = pix->width;
497 pix_mp->height = pix->height;
498 pix_mp->pixelformat = pix->pixelformat;
499 pix_mp->field = pix->field;
500 pix_mp->colorspace = pix->colorspace;
501 pix_mp->num_planes = 1;
502 pix_mp->plane_fmt[0].sizeimage = pix->sizeimage;
503 pix_mp->plane_fmt[0].bytesperline = pix->bytesperline;
504
505 return 0;
506}
507
508/**
509 * fmt_mp_to_sp() - Convert a multi-planar 1-plane format to its single-planar
510 * equivalent
511 */
512static int fmt_mp_to_sp(const struct v4l2_format *f_mp,
513 struct v4l2_format *f_sp)
514{
515 const struct v4l2_pix_format_mplane *pix_mp = &f_mp->fmt.pix_mp;
516 struct v4l2_pix_format *pix = &f_sp->fmt.pix;
517
518 if (f_mp->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
519 f_sp->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
520 else if (f_mp->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
521 f_sp->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
522 else
523 return -EINVAL;
524
525 pix->width = pix_mp->width;
526 pix->height = pix_mp->height;
527 pix->pixelformat = pix_mp->pixelformat;
528 pix->field = pix_mp->field;
529 pix->colorspace = pix_mp->colorspace;
530 pix->sizeimage = pix_mp->plane_fmt[0].sizeimage;
531 pix->bytesperline = pix_mp->plane_fmt[0].bytesperline;
532
533 return 0;
534}
535
562static long __video_do_ioctl(struct file *file, 536static long __video_do_ioctl(struct file *file,
563 unsigned int cmd, void *arg) 537 unsigned int cmd, void *arg)
564{ 538{
565 struct video_device *vfd = video_devdata(file); 539 struct video_device *vfd = video_devdata(file);
566 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops; 540 const struct v4l2_ioctl_ops *ops = vfd->ioctl_ops;
567 void *fh = file->private_data; 541 void *fh = file->private_data;
542 struct v4l2_fh *vfh = NULL;
543 struct v4l2_format f_copy;
544 int use_fh_prio = 0;
568 long ret = -EINVAL; 545 long ret = -EINVAL;
569 546
570 if (ops == NULL) { 547 if (ops == NULL) {
@@ -579,6 +556,45 @@ static long __video_do_ioctl(struct file *file,
579 printk(KERN_CONT "\n"); 556 printk(KERN_CONT "\n");
580 } 557 }
581 558
559 if (test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags)) {
560 vfh = file->private_data;
561 use_fh_prio = test_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
562 }
563
564 if (use_fh_prio) {
565 switch (cmd) {
566 case VIDIOC_S_CTRL:
567 case VIDIOC_S_STD:
568 case VIDIOC_S_INPUT:
569 case VIDIOC_S_OUTPUT:
570 case VIDIOC_S_TUNER:
571 case VIDIOC_S_FREQUENCY:
572 case VIDIOC_S_FMT:
573 case VIDIOC_S_CROP:
574 case VIDIOC_S_AUDIO:
575 case VIDIOC_S_AUDOUT:
576 case VIDIOC_S_EXT_CTRLS:
577 case VIDIOC_S_FBUF:
578 case VIDIOC_S_PRIORITY:
579 case VIDIOC_S_DV_PRESET:
580 case VIDIOC_S_DV_TIMINGS:
581 case VIDIOC_S_JPEGCOMP:
582 case VIDIOC_S_MODULATOR:
583 case VIDIOC_S_PARM:
584 case VIDIOC_S_HW_FREQ_SEEK:
585 case VIDIOC_ENCODER_CMD:
586 case VIDIOC_OVERLAY:
587 case VIDIOC_REQBUFS:
588 case VIDIOC_STREAMON:
589 case VIDIOC_STREAMOFF:
590 ret = v4l2_prio_check(vfd->prio, vfh->prio);
591 if (ret)
592 goto exit_prio;
593 ret = -EINVAL;
594 break;
595 }
596 }
597
582 switch (cmd) { 598 switch (cmd) {
583 599
584 /* --- capabilities ------------------------------------------ */ 600 /* --- capabilities ------------------------------------------ */
@@ -605,9 +621,12 @@ static long __video_do_ioctl(struct file *file,
605 { 621 {
606 enum v4l2_priority *p = arg; 622 enum v4l2_priority *p = arg;
607 623
608 if (!ops->vidioc_g_priority) 624 if (ops->vidioc_g_priority) {
609 break; 625 ret = ops->vidioc_g_priority(file, fh, p);
610 ret = ops->vidioc_g_priority(file, fh, p); 626 } else if (use_fh_prio) {
627 *p = v4l2_prio_max(&vfd->v4l2_dev->prio);
628 ret = 0;
629 }
611 if (!ret) 630 if (!ret)
612 dbgarg(cmd, "priority is %d\n", *p); 631 dbgarg(cmd, "priority is %d\n", *p);
613 break; 632 break;
@@ -616,10 +635,13 @@ static long __video_do_ioctl(struct file *file,
616 { 635 {
617 enum v4l2_priority *p = arg; 636 enum v4l2_priority *p = arg;
618 637
619 if (!ops->vidioc_s_priority) 638 if (!ops->vidioc_s_priority && !use_fh_prio)
620 break; 639 break;
621 dbgarg(cmd, "setting priority to %d\n", *p); 640 dbgarg(cmd, "setting priority to %d\n", *p);
622 ret = ops->vidioc_s_priority(file, fh, *p); 641 if (ops->vidioc_s_priority)
642 ret = ops->vidioc_s_priority(file, fh, *p);
643 else
644 ret = v4l2_prio_change(&vfd->v4l2_dev->prio, &vfh->prio, *p);
623 break; 645 break;
624 } 646 }
625 647
@@ -633,6 +655,11 @@ static long __video_do_ioctl(struct file *file,
633 if (ops->vidioc_enum_fmt_vid_cap) 655 if (ops->vidioc_enum_fmt_vid_cap)
634 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f); 656 ret = ops->vidioc_enum_fmt_vid_cap(file, fh, f);
635 break; 657 break;
658 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
659 if (ops->vidioc_enum_fmt_vid_cap_mplane)
660 ret = ops->vidioc_enum_fmt_vid_cap_mplane(file,
661 fh, f);
662 break;
636 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 663 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
637 if (ops->vidioc_enum_fmt_vid_overlay) 664 if (ops->vidioc_enum_fmt_vid_overlay)
638 ret = ops->vidioc_enum_fmt_vid_overlay(file, 665 ret = ops->vidioc_enum_fmt_vid_overlay(file,
@@ -642,6 +669,11 @@ static long __video_do_ioctl(struct file *file,
642 if (ops->vidioc_enum_fmt_vid_out) 669 if (ops->vidioc_enum_fmt_vid_out)
643 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f); 670 ret = ops->vidioc_enum_fmt_vid_out(file, fh, f);
644 break; 671 break;
672 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
673 if (ops->vidioc_enum_fmt_vid_out_mplane)
674 ret = ops->vidioc_enum_fmt_vid_out_mplane(file,
675 fh, f);
676 break;
645 case V4L2_BUF_TYPE_PRIVATE: 677 case V4L2_BUF_TYPE_PRIVATE:
646 if (ops->vidioc_enum_fmt_type_private) 678 if (ops->vidioc_enum_fmt_type_private)
647 ret = ops->vidioc_enum_fmt_type_private(file, 679 ret = ops->vidioc_enum_fmt_type_private(file,
@@ -670,22 +702,90 @@ static long __video_do_ioctl(struct file *file,
670 702
671 switch (f->type) { 703 switch (f->type) {
672 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 704 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
673 if (ops->vidioc_g_fmt_vid_cap) 705 if (ops->vidioc_g_fmt_vid_cap) {
674 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f); 706 ret = ops->vidioc_g_fmt_vid_cap(file, fh, f);
707 } else if (ops->vidioc_g_fmt_vid_cap_mplane) {
708 if (fmt_sp_to_mp(f, &f_copy))
709 break;
710 ret = ops->vidioc_g_fmt_vid_cap_mplane(file, fh,
711 &f_copy);
712 if (ret)
713 break;
714
715 /* Driver is currently in multi-planar format,
716 * we can't return it in single-planar API*/
717 if (f_copy.fmt.pix_mp.num_planes > 1) {
718 ret = -EBUSY;
719 break;
720 }
721
722 ret = fmt_mp_to_sp(&f_copy, f);
723 }
675 if (!ret) 724 if (!ret)
676 v4l_print_pix_fmt(vfd, &f->fmt.pix); 725 v4l_print_pix_fmt(vfd, &f->fmt.pix);
677 break; 726 break;
727 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
728 if (ops->vidioc_g_fmt_vid_cap_mplane) {
729 ret = ops->vidioc_g_fmt_vid_cap_mplane(file,
730 fh, f);
731 } else if (ops->vidioc_g_fmt_vid_cap) {
732 if (fmt_mp_to_sp(f, &f_copy))
733 break;
734 ret = ops->vidioc_g_fmt_vid_cap(file,
735 fh, &f_copy);
736 if (ret)
737 break;
738
739 ret = fmt_sp_to_mp(&f_copy, f);
740 }
741 if (!ret)
742 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
743 break;
678 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 744 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
679 if (ops->vidioc_g_fmt_vid_overlay) 745 if (ops->vidioc_g_fmt_vid_overlay)
680 ret = ops->vidioc_g_fmt_vid_overlay(file, 746 ret = ops->vidioc_g_fmt_vid_overlay(file,
681 fh, f); 747 fh, f);
682 break; 748 break;
683 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 749 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
684 if (ops->vidioc_g_fmt_vid_out) 750 if (ops->vidioc_g_fmt_vid_out) {
685 ret = ops->vidioc_g_fmt_vid_out(file, fh, f); 751 ret = ops->vidioc_g_fmt_vid_out(file, fh, f);
752 } else if (ops->vidioc_g_fmt_vid_out_mplane) {
753 if (fmt_sp_to_mp(f, &f_copy))
754 break;
755 ret = ops->vidioc_g_fmt_vid_out_mplane(file, fh,
756 &f_copy);
757 if (ret)
758 break;
759
760 /* Driver is currently in multi-planar format,
761 * we can't return it in single-planar API*/
762 if (f_copy.fmt.pix_mp.num_planes > 1) {
763 ret = -EBUSY;
764 break;
765 }
766
767 ret = fmt_mp_to_sp(&f_copy, f);
768 }
686 if (!ret) 769 if (!ret)
687 v4l_print_pix_fmt(vfd, &f->fmt.pix); 770 v4l_print_pix_fmt(vfd, &f->fmt.pix);
688 break; 771 break;
772 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
773 if (ops->vidioc_g_fmt_vid_out_mplane) {
774 ret = ops->vidioc_g_fmt_vid_out_mplane(file,
775 fh, f);
776 } else if (ops->vidioc_g_fmt_vid_out) {
777 if (fmt_mp_to_sp(f, &f_copy))
778 break;
779 ret = ops->vidioc_g_fmt_vid_out(file,
780 fh, &f_copy);
781 if (ret)
782 break;
783
784 ret = fmt_sp_to_mp(&f_copy, f);
785 }
786 if (!ret)
787 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
788 break;
689 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 789 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
690 if (ops->vidioc_g_fmt_vid_out_overlay) 790 if (ops->vidioc_g_fmt_vid_out_overlay)
691 ret = ops->vidioc_g_fmt_vid_out_overlay(file, 791 ret = ops->vidioc_g_fmt_vid_out_overlay(file,
@@ -729,8 +829,44 @@ static long __video_do_ioctl(struct file *file,
729 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 829 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
730 CLEAR_AFTER_FIELD(f, fmt.pix); 830 CLEAR_AFTER_FIELD(f, fmt.pix);
731 v4l_print_pix_fmt(vfd, &f->fmt.pix); 831 v4l_print_pix_fmt(vfd, &f->fmt.pix);
732 if (ops->vidioc_s_fmt_vid_cap) 832 if (ops->vidioc_s_fmt_vid_cap) {
733 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f); 833 ret = ops->vidioc_s_fmt_vid_cap(file, fh, f);
834 } else if (ops->vidioc_s_fmt_vid_cap_mplane) {
835 if (fmt_sp_to_mp(f, &f_copy))
836 break;
837 ret = ops->vidioc_s_fmt_vid_cap_mplane(file, fh,
838 &f_copy);
839 if (ret)
840 break;
841
842 if (f_copy.fmt.pix_mp.num_planes > 1) {
843 /* Drivers shouldn't adjust from 1-plane
844 * to more than 1-plane formats */
845 ret = -EBUSY;
846 WARN_ON(1);
847 break;
848 }
849
850 ret = fmt_mp_to_sp(&f_copy, f);
851 }
852 break;
853 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
854 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
855 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
856 if (ops->vidioc_s_fmt_vid_cap_mplane) {
857 ret = ops->vidioc_s_fmt_vid_cap_mplane(file,
858 fh, f);
859 } else if (ops->vidioc_s_fmt_vid_cap &&
860 f->fmt.pix_mp.num_planes == 1) {
861 if (fmt_mp_to_sp(f, &f_copy))
862 break;
863 ret = ops->vidioc_s_fmt_vid_cap(file,
864 fh, &f_copy);
865 if (ret)
866 break;
867
868 ret = fmt_sp_to_mp(&f_copy, f);
869 }
734 break; 870 break;
735 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 871 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
736 CLEAR_AFTER_FIELD(f, fmt.win); 872 CLEAR_AFTER_FIELD(f, fmt.win);
@@ -741,8 +877,44 @@ static long __video_do_ioctl(struct file *file,
741 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 877 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
742 CLEAR_AFTER_FIELD(f, fmt.pix); 878 CLEAR_AFTER_FIELD(f, fmt.pix);
743 v4l_print_pix_fmt(vfd, &f->fmt.pix); 879 v4l_print_pix_fmt(vfd, &f->fmt.pix);
744 if (ops->vidioc_s_fmt_vid_out) 880 if (ops->vidioc_s_fmt_vid_out) {
745 ret = ops->vidioc_s_fmt_vid_out(file, fh, f); 881 ret = ops->vidioc_s_fmt_vid_out(file, fh, f);
882 } else if (ops->vidioc_s_fmt_vid_out_mplane) {
883 if (fmt_sp_to_mp(f, &f_copy))
884 break;
885 ret = ops->vidioc_s_fmt_vid_out_mplane(file, fh,
886 &f_copy);
887 if (ret)
888 break;
889
890 if (f_copy.fmt.pix_mp.num_planes > 1) {
891 /* Drivers shouldn't adjust from 1-plane
892 * to more than 1-plane formats */
893 ret = -EBUSY;
894 WARN_ON(1);
895 break;
896 }
897
898 ret = fmt_mp_to_sp(&f_copy, f);
899 }
900 break;
901 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
902 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
903 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
904 if (ops->vidioc_s_fmt_vid_out_mplane) {
905 ret = ops->vidioc_s_fmt_vid_out_mplane(file,
906 fh, f);
907 } else if (ops->vidioc_s_fmt_vid_out &&
908 f->fmt.pix_mp.num_planes == 1) {
909 if (fmt_mp_to_sp(f, &f_copy))
910 break;
911 ret = ops->vidioc_s_fmt_vid_out(file,
912 fh, &f_copy);
913 if (ret)
914 break;
915
916 ret = fmt_mp_to_sp(&f_copy, f);
917 }
746 break; 918 break;
747 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 919 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
748 CLEAR_AFTER_FIELD(f, fmt.win); 920 CLEAR_AFTER_FIELD(f, fmt.win);
@@ -791,11 +963,47 @@ static long __video_do_ioctl(struct file *file,
791 switch (f->type) { 963 switch (f->type) {
792 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 964 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
793 CLEAR_AFTER_FIELD(f, fmt.pix); 965 CLEAR_AFTER_FIELD(f, fmt.pix);
794 if (ops->vidioc_try_fmt_vid_cap) 966 if (ops->vidioc_try_fmt_vid_cap) {
795 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f); 967 ret = ops->vidioc_try_fmt_vid_cap(file, fh, f);
968 } else if (ops->vidioc_try_fmt_vid_cap_mplane) {
969 if (fmt_sp_to_mp(f, &f_copy))
970 break;
971 ret = ops->vidioc_try_fmt_vid_cap_mplane(file,
972 fh, &f_copy);
973 if (ret)
974 break;
975
976 if (f_copy.fmt.pix_mp.num_planes > 1) {
977 /* Drivers shouldn't adjust from 1-plane
978 * to more than 1-plane formats */
979 ret = -EBUSY;
980 WARN_ON(1);
981 break;
982 }
983 ret = fmt_mp_to_sp(&f_copy, f);
984 }
796 if (!ret) 985 if (!ret)
797 v4l_print_pix_fmt(vfd, &f->fmt.pix); 986 v4l_print_pix_fmt(vfd, &f->fmt.pix);
798 break; 987 break;
988 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
989 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
990 if (ops->vidioc_try_fmt_vid_cap_mplane) {
991 ret = ops->vidioc_try_fmt_vid_cap_mplane(file,
992 fh, f);
993 } else if (ops->vidioc_try_fmt_vid_cap &&
994 f->fmt.pix_mp.num_planes == 1) {
995 if (fmt_mp_to_sp(f, &f_copy))
996 break;
997 ret = ops->vidioc_try_fmt_vid_cap(file,
998 fh, &f_copy);
999 if (ret)
1000 break;
1001
1002 ret = fmt_sp_to_mp(&f_copy, f);
1003 }
1004 if (!ret)
1005 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
1006 break;
799 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 1007 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
800 CLEAR_AFTER_FIELD(f, fmt.win); 1008 CLEAR_AFTER_FIELD(f, fmt.win);
801 if (ops->vidioc_try_fmt_vid_overlay) 1009 if (ops->vidioc_try_fmt_vid_overlay)
@@ -804,11 +1012,47 @@ static long __video_do_ioctl(struct file *file,
804 break; 1012 break;
805 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 1013 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
806 CLEAR_AFTER_FIELD(f, fmt.pix); 1014 CLEAR_AFTER_FIELD(f, fmt.pix);
807 if (ops->vidioc_try_fmt_vid_out) 1015 if (ops->vidioc_try_fmt_vid_out) {
808 ret = ops->vidioc_try_fmt_vid_out(file, fh, f); 1016 ret = ops->vidioc_try_fmt_vid_out(file, fh, f);
1017 } else if (ops->vidioc_try_fmt_vid_out_mplane) {
1018 if (fmt_sp_to_mp(f, &f_copy))
1019 break;
1020 ret = ops->vidioc_try_fmt_vid_out_mplane(file,
1021 fh, &f_copy);
1022 if (ret)
1023 break;
1024
1025 if (f_copy.fmt.pix_mp.num_planes > 1) {
1026 /* Drivers shouldn't adjust from 1-plane
1027 * to more than 1-plane formats */
1028 ret = -EBUSY;
1029 WARN_ON(1);
1030 break;
1031 }
1032 ret = fmt_mp_to_sp(&f_copy, f);
1033 }
809 if (!ret) 1034 if (!ret)
810 v4l_print_pix_fmt(vfd, &f->fmt.pix); 1035 v4l_print_pix_fmt(vfd, &f->fmt.pix);
811 break; 1036 break;
1037 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
1038 CLEAR_AFTER_FIELD(f, fmt.pix_mp);
1039 if (ops->vidioc_try_fmt_vid_out_mplane) {
1040 ret = ops->vidioc_try_fmt_vid_out_mplane(file,
1041 fh, f);
1042 } else if (ops->vidioc_try_fmt_vid_out &&
1043 f->fmt.pix_mp.num_planes == 1) {
1044 if (fmt_mp_to_sp(f, &f_copy))
1045 break;
1046 ret = ops->vidioc_try_fmt_vid_out(file,
1047 fh, &f_copy);
1048 if (ret)
1049 break;
1050
1051 ret = fmt_sp_to_mp(&f_copy, f);
1052 }
1053 if (!ret)
1054 v4l_print_pix_fmt_mplane(vfd, &f->fmt.pix_mp);
1055 break;
812 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY: 1056 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
813 CLEAR_AFTER_FIELD(f, fmt.win); 1057 CLEAR_AFTER_FIELD(f, fmt.win);
814 if (ops->vidioc_try_fmt_vid_out_overlay) 1058 if (ops->vidioc_try_fmt_vid_out_overlay)
@@ -1942,13 +2186,18 @@ static long __video_do_ioctl(struct file *file,
1942 } 2186 }
1943 default: 2187 default:
1944 { 2188 {
2189 bool valid_prio = true;
2190
1945 if (!ops->vidioc_default) 2191 if (!ops->vidioc_default)
1946 break; 2192 break;
1947 ret = ops->vidioc_default(file, fh, cmd, arg); 2193 if (use_fh_prio)
2194 valid_prio = v4l2_prio_check(vfd->prio, vfh->prio) >= 0;
2195 ret = ops->vidioc_default(file, fh, valid_prio, cmd, arg);
1948 break; 2196 break;
1949 } 2197 }
1950 } /* switch */ 2198 } /* switch */
1951 2199
2200exit_prio:
1952 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) { 2201 if (vfd->debug & V4L2_DEBUG_IOCTL_ARG) {
1953 if (ret < 0) { 2202 if (ret < 0) {
1954 v4l_print_ioctl(vfd->name, cmd); 2203 v4l_print_ioctl(vfd->name, cmd);
@@ -1973,7 +2222,7 @@ static unsigned long cmd_input_size(unsigned int cmd)
1973 switch (cmd) { 2222 switch (cmd) {
1974 CMDINSIZE(ENUM_FMT, fmtdesc, type); 2223 CMDINSIZE(ENUM_FMT, fmtdesc, type);
1975 CMDINSIZE(G_FMT, format, type); 2224 CMDINSIZE(G_FMT, format, type);
1976 CMDINSIZE(QUERYBUF, buffer, type); 2225 CMDINSIZE(QUERYBUF, buffer, length);
1977 CMDINSIZE(G_PARM, streamparm, type); 2226 CMDINSIZE(G_PARM, streamparm, type);
1978 CMDINSIZE(ENUMSTD, standard, index); 2227 CMDINSIZE(ENUMSTD, standard, index);
1979 CMDINSIZE(ENUMINPUT, input, index); 2228 CMDINSIZE(ENUMINPUT, input, index);
@@ -1998,22 +2247,61 @@ static unsigned long cmd_input_size(unsigned int cmd)
1998 } 2247 }
1999} 2248}
2000 2249
2001long video_ioctl2(struct file *file, 2250static int check_array_args(unsigned int cmd, void *parg, size_t *array_size,
2002 unsigned int cmd, unsigned long arg) 2251 void * __user *user_ptr, void ***kernel_ptr)
2252{
2253 int ret = 0;
2254
2255 switch (cmd) {
2256 case VIDIOC_QUERYBUF:
2257 case VIDIOC_QBUF:
2258 case VIDIOC_DQBUF: {
2259 struct v4l2_buffer *buf = parg;
2260
2261 if (V4L2_TYPE_IS_MULTIPLANAR(buf->type) && buf->length > 0) {
2262 if (buf->length > VIDEO_MAX_PLANES) {
2263 ret = -EINVAL;
2264 break;
2265 }
2266 *user_ptr = (void __user *)buf->m.planes;
2267 *kernel_ptr = (void **)&buf->m.planes;
2268 *array_size = sizeof(struct v4l2_plane) * buf->length;
2269 ret = 1;
2270 }
2271 break;
2272 }
2273
2274 case VIDIOC_S_EXT_CTRLS:
2275 case VIDIOC_G_EXT_CTRLS:
2276 case VIDIOC_TRY_EXT_CTRLS: {
2277 struct v4l2_ext_controls *ctrls = parg;
2278
2279 if (ctrls->count != 0) {
2280 *user_ptr = (void __user *)ctrls->controls;
2281 *kernel_ptr = (void **)&ctrls->controls;
2282 *array_size = sizeof(struct v4l2_ext_control)
2283 * ctrls->count;
2284 ret = 1;
2285 }
2286 break;
2287 }
2288 }
2289
2290 return ret;
2291}
2292
2293long
2294video_usercopy(struct file *file, unsigned int cmd, unsigned long arg,
2295 v4l2_kioctl func)
2003{ 2296{
2004 char sbuf[128]; 2297 char sbuf[128];
2005 void *mbuf = NULL; 2298 void *mbuf = NULL;
2006 void *parg = (void *)arg; 2299 void *parg = (void *)arg;
2007 long err = -EINVAL; 2300 long err = -EINVAL;
2008 int is_ext_ctrl; 2301 bool has_array_args;
2009 size_t ctrls_size = 0; 2302 size_t array_size = 0;
2010 void __user *user_ptr = NULL; 2303 void __user *user_ptr = NULL;
2011 2304 void **kernel_ptr = NULL;
2012#ifdef __OLD_VIDIOC_
2013 cmd = video_fix_command(cmd);
2014#endif
2015 is_ext_ctrl = (cmd == VIDIOC_S_EXT_CTRLS || cmd == VIDIOC_G_EXT_CTRLS ||
2016 cmd == VIDIOC_TRY_EXT_CTRLS);
2017 2305
2018 /* Copy arguments into temp kernel buffer */ 2306 /* Copy arguments into temp kernel buffer */
2019 if (_IOC_DIR(cmd) != _IOC_NONE) { 2307 if (_IOC_DIR(cmd) != _IOC_NONE) {
@@ -2043,43 +2331,43 @@ long video_ioctl2(struct file *file,
2043 } 2331 }
2044 } 2332 }
2045 2333
2046 if (is_ext_ctrl) { 2334 err = check_array_args(cmd, parg, &array_size, &user_ptr, &kernel_ptr);
2047 struct v4l2_ext_controls *p = parg; 2335 if (err < 0)
2336 goto out;
2337 has_array_args = err;
2048 2338
2049 /* In case of an error, tell the caller that it wasn't 2339 if (has_array_args) {
2050 a specific control that caused it. */ 2340 /*
2051 p->error_idx = p->count; 2341 * When adding new types of array args, make sure that the
2052 user_ptr = (void __user *)p->controls; 2342 * parent argument to ioctl (which contains the pointer to the
2053 if (p->count) { 2343 * array) fits into sbuf (so that mbuf will still remain
2054 ctrls_size = sizeof(struct v4l2_ext_control) * p->count; 2344 * unused up to here).
2055 /* Note: v4l2_ext_controls fits in sbuf[] so mbuf is still NULL. */ 2345 */
2056 mbuf = kmalloc(ctrls_size, GFP_KERNEL); 2346 mbuf = kmalloc(array_size, GFP_KERNEL);
2057 err = -ENOMEM; 2347 err = -ENOMEM;
2058 if (NULL == mbuf) 2348 if (NULL == mbuf)
2059 goto out_ext_ctrl; 2349 goto out_array_args;
2060 err = -EFAULT; 2350 err = -EFAULT;
2061 if (copy_from_user(mbuf, user_ptr, ctrls_size)) 2351 if (copy_from_user(mbuf, user_ptr, array_size))
2062 goto out_ext_ctrl; 2352 goto out_array_args;
2063 p->controls = mbuf; 2353 *kernel_ptr = mbuf;
2064 }
2065 } 2354 }
2066 2355
2067 /* Handles IOCTL */ 2356 /* Handles IOCTL */
2068 err = __video_do_ioctl(file, cmd, parg); 2357 err = func(file, cmd, parg);
2069 if (err == -ENOIOCTLCMD) 2358 if (err == -ENOIOCTLCMD)
2070 err = -EINVAL; 2359 err = -EINVAL;
2071 if (is_ext_ctrl) {
2072 struct v4l2_ext_controls *p = parg;
2073 2360
2074 p->controls = (void *)user_ptr; 2361 if (has_array_args) {
2075 if (p->count && err == 0 && copy_to_user(user_ptr, mbuf, ctrls_size)) 2362 *kernel_ptr = user_ptr;
2363 if (copy_to_user(user_ptr, mbuf, array_size))
2076 err = -EFAULT; 2364 err = -EFAULT;
2077 goto out_ext_ctrl; 2365 goto out_array_args;
2078 } 2366 }
2079 if (err < 0) 2367 if (err < 0)
2080 goto out; 2368 goto out;
2081 2369
2082out_ext_ctrl: 2370out_array_args:
2083 /* Copy results into user buffer */ 2371 /* Copy results into user buffer */
2084 switch (_IOC_DIR(cmd)) { 2372 switch (_IOC_DIR(cmd)) {
2085 case _IOC_READ: 2373 case _IOC_READ:
@@ -2093,4 +2381,11 @@ out:
2093 kfree(mbuf); 2381 kfree(mbuf);
2094 return err; 2382 return err;
2095} 2383}
2384EXPORT_SYMBOL(video_usercopy);
2385
2386long video_ioctl2(struct file *file,
2387 unsigned int cmd, unsigned long arg)
2388{
2389 return video_usercopy(file, cmd, arg, __video_do_ioctl);
2390}
2096EXPORT_SYMBOL(video_ioctl2); 2391EXPORT_SYMBOL(video_ioctl2);
diff --git a/drivers/media/video/v4l2-mem2mem.c b/drivers/media/video/v4l2-mem2mem.c
index ac832a28e18e..3b15bf5892a8 100644
--- a/drivers/media/video/v4l2-mem2mem.c
+++ b/drivers/media/video/v4l2-mem2mem.c
@@ -5,7 +5,7 @@
5 * source and destination. 5 * source and destination.
6 * 6 *
7 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2009-2010 Samsung Electronics Co., Ltd.
8 * Pawel Osciak, <p.osciak@samsung.com> 8 * Pawel Osciak, <pawel@osciak.com>
9 * Marek Szyprowski, <m.szyprowski@samsung.com> 9 * Marek Szyprowski, <m.szyprowski@samsung.com>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
@@ -17,11 +17,11 @@
17#include <linux/sched.h> 17#include <linux/sched.h>
18#include <linux/slab.h> 18#include <linux/slab.h>
19 19
20#include <media/videobuf-core.h> 20#include <media/videobuf2-core.h>
21#include <media/v4l2-mem2mem.h> 21#include <media/v4l2-mem2mem.h>
22 22
23MODULE_DESCRIPTION("Mem to mem device framework for videobuf"); 23MODULE_DESCRIPTION("Mem to mem device framework for videobuf");
24MODULE_AUTHOR("Pawel Osciak, <p.osciak@samsung.com>"); 24MODULE_AUTHOR("Pawel Osciak, <pawel@osciak.com>");
25MODULE_LICENSE("GPL"); 25MODULE_LICENSE("GPL");
26 26
27static bool debug; 27static bool debug;
@@ -65,21 +65,16 @@ struct v4l2_m2m_dev {
65static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx, 65static struct v4l2_m2m_queue_ctx *get_queue_ctx(struct v4l2_m2m_ctx *m2m_ctx,
66 enum v4l2_buf_type type) 66 enum v4l2_buf_type type)
67{ 67{
68 switch (type) { 68 if (V4L2_TYPE_IS_OUTPUT(type))
69 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
70 return &m2m_ctx->cap_q_ctx;
71 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
72 return &m2m_ctx->out_q_ctx; 69 return &m2m_ctx->out_q_ctx;
73 default: 70 else
74 printk(KERN_ERR "Invalid buffer type\n"); 71 return &m2m_ctx->cap_q_ctx;
75 return NULL;
76 }
77} 72}
78 73
79/** 74/**
80 * v4l2_m2m_get_vq() - return videobuf_queue for the given type 75 * v4l2_m2m_get_vq() - return vb2_queue for the given type
81 */ 76 */
82struct videobuf_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, 77struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
83 enum v4l2_buf_type type) 78 enum v4l2_buf_type type)
84{ 79{
85 struct v4l2_m2m_queue_ctx *q_ctx; 80 struct v4l2_m2m_queue_ctx *q_ctx;
@@ -95,27 +90,20 @@ EXPORT_SYMBOL(v4l2_m2m_get_vq);
95/** 90/**
96 * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers 91 * v4l2_m2m_next_buf() - return next buffer from the list of ready buffers
97 */ 92 */
98void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) 93void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx)
99{ 94{
100 struct v4l2_m2m_queue_ctx *q_ctx; 95 struct v4l2_m2m_buffer *b = NULL;
101 struct videobuf_buffer *vb = NULL;
102 unsigned long flags; 96 unsigned long flags;
103 97
104 q_ctx = get_queue_ctx(m2m_ctx, type); 98 spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
105 if (!q_ctx)
106 return NULL;
107
108 spin_lock_irqsave(q_ctx->q.irqlock, flags);
109 99
110 if (list_empty(&q_ctx->rdy_queue)) 100 if (list_empty(&q_ctx->rdy_queue))
111 goto end; 101 goto end;
112 102
113 vb = list_entry(q_ctx->rdy_queue.next, struct videobuf_buffer, queue); 103 b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer, list);
114 vb->state = VIDEOBUF_ACTIVE;
115
116end: 104end:
117 spin_unlock_irqrestore(q_ctx->q.irqlock, flags); 105 spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
118 return vb; 106 return &b->vb;
119} 107}
120EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf); 108EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf);
121 109
@@ -123,26 +111,21 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_next_buf);
123 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and 111 * v4l2_m2m_buf_remove() - take off a buffer from the list of ready buffers and
124 * return it 112 * return it
125 */ 113 */
126void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type) 114void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx)
127{ 115{
128 struct v4l2_m2m_queue_ctx *q_ctx; 116 struct v4l2_m2m_buffer *b = NULL;
129 struct videobuf_buffer *vb = NULL;
130 unsigned long flags; 117 unsigned long flags;
131 118
132 q_ctx = get_queue_ctx(m2m_ctx, type); 119 spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
133 if (!q_ctx)
134 return NULL;
135
136 spin_lock_irqsave(q_ctx->q.irqlock, flags);
137 if (!list_empty(&q_ctx->rdy_queue)) { 120 if (!list_empty(&q_ctx->rdy_queue)) {
138 vb = list_entry(q_ctx->rdy_queue.next, struct videobuf_buffer, 121 b = list_entry(q_ctx->rdy_queue.next, struct v4l2_m2m_buffer,
139 queue); 122 list);
140 list_del(&vb->queue); 123 list_del(&b->list);
141 q_ctx->num_rdy--; 124 q_ctx->num_rdy--;
142 } 125 }
143 spin_unlock_irqrestore(q_ctx->q.irqlock, flags); 126 spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
144 127
145 return vb; 128 return &b->vb;
146} 129}
147EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove); 130EXPORT_SYMBOL_GPL(v4l2_m2m_buf_remove);
148 131
@@ -235,20 +218,20 @@ static void v4l2_m2m_try_schedule(struct v4l2_m2m_ctx *m2m_ctx)
235 return; 218 return;
236 } 219 }
237 220
238 spin_lock_irqsave(m2m_ctx->out_q_ctx.q.irqlock, flags); 221 spin_lock_irqsave(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
239 if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) { 222 if (list_empty(&m2m_ctx->out_q_ctx.rdy_queue)) {
240 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags); 223 spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
241 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); 224 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
242 dprintk("No input buffers available\n"); 225 dprintk("No input buffers available\n");
243 return; 226 return;
244 } 227 }
245 if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) { 228 if (list_empty(&m2m_ctx->cap_q_ctx.rdy_queue)) {
246 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags); 229 spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
247 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job); 230 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags_job);
248 dprintk("No output buffers available\n"); 231 dprintk("No output buffers available\n");
249 return; 232 return;
250 } 233 }
251 spin_unlock_irqrestore(m2m_ctx->out_q_ctx.q.irqlock, flags); 234 spin_unlock_irqrestore(&m2m_ctx->out_q_ctx.rdy_spinlock, flags);
252 235
253 if (m2m_dev->m2m_ops->job_ready 236 if (m2m_dev->m2m_ops->job_ready
254 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) { 237 && (!m2m_dev->m2m_ops->job_ready(m2m_ctx->priv))) {
@@ -291,6 +274,7 @@ void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
291 274
292 list_del(&m2m_dev->curr_ctx->queue); 275 list_del(&m2m_dev->curr_ctx->queue);
293 m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); 276 m2m_dev->curr_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
277 wake_up(&m2m_dev->curr_ctx->finished);
294 m2m_dev->curr_ctx = NULL; 278 m2m_dev->curr_ctx = NULL;
295 279
296 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); 280 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
@@ -309,10 +293,10 @@ EXPORT_SYMBOL(v4l2_m2m_job_finish);
309int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 293int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
310 struct v4l2_requestbuffers *reqbufs) 294 struct v4l2_requestbuffers *reqbufs)
311{ 295{
312 struct videobuf_queue *vq; 296 struct vb2_queue *vq;
313 297
314 vq = v4l2_m2m_get_vq(m2m_ctx, reqbufs->type); 298 vq = v4l2_m2m_get_vq(m2m_ctx, reqbufs->type);
315 return videobuf_reqbufs(vq, reqbufs); 299 return vb2_reqbufs(vq, reqbufs);
316} 300}
317EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs); 301EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
318 302
@@ -324,15 +308,22 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_reqbufs);
324int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 308int v4l2_m2m_querybuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
325 struct v4l2_buffer *buf) 309 struct v4l2_buffer *buf)
326{ 310{
327 struct videobuf_queue *vq; 311 struct vb2_queue *vq;
328 int ret; 312 int ret = 0;
313 unsigned int i;
329 314
330 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); 315 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
331 ret = videobuf_querybuf(vq, buf); 316 ret = vb2_querybuf(vq, buf);
332 317
333 if (buf->memory == V4L2_MEMORY_MMAP 318 /* Adjust MMAP memory offsets for the CAPTURE queue */
334 && vq->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 319 if (buf->memory == V4L2_MEMORY_MMAP && !V4L2_TYPE_IS_OUTPUT(vq->type)) {
335 buf->m.offset += DST_QUEUE_OFF_BASE; 320 if (V4L2_TYPE_IS_MULTIPLANAR(vq->type)) {
321 for (i = 0; i < buf->length; ++i)
322 buf->m.planes[i].m.mem_offset
323 += DST_QUEUE_OFF_BASE;
324 } else {
325 buf->m.offset += DST_QUEUE_OFF_BASE;
326 }
336 } 327 }
337 328
338 return ret; 329 return ret;
@@ -346,11 +337,11 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_querybuf);
346int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 337int v4l2_m2m_qbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
347 struct v4l2_buffer *buf) 338 struct v4l2_buffer *buf)
348{ 339{
349 struct videobuf_queue *vq; 340 struct vb2_queue *vq;
350 int ret; 341 int ret;
351 342
352 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); 343 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
353 ret = videobuf_qbuf(vq, buf); 344 ret = vb2_qbuf(vq, buf);
354 if (!ret) 345 if (!ret)
355 v4l2_m2m_try_schedule(m2m_ctx); 346 v4l2_m2m_try_schedule(m2m_ctx);
356 347
@@ -365,10 +356,10 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_qbuf);
365int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 356int v4l2_m2m_dqbuf(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
366 struct v4l2_buffer *buf) 357 struct v4l2_buffer *buf)
367{ 358{
368 struct videobuf_queue *vq; 359 struct vb2_queue *vq;
369 360
370 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type); 361 vq = v4l2_m2m_get_vq(m2m_ctx, buf->type);
371 return videobuf_dqbuf(vq, buf, file->f_flags & O_NONBLOCK); 362 return vb2_dqbuf(vq, buf, file->f_flags & O_NONBLOCK);
372} 363}
373EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf); 364EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
374 365
@@ -378,11 +369,11 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_dqbuf);
378int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 369int v4l2_m2m_streamon(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
379 enum v4l2_buf_type type) 370 enum v4l2_buf_type type)
380{ 371{
381 struct videobuf_queue *vq; 372 struct vb2_queue *vq;
382 int ret; 373 int ret;
383 374
384 vq = v4l2_m2m_get_vq(m2m_ctx, type); 375 vq = v4l2_m2m_get_vq(m2m_ctx, type);
385 ret = videobuf_streamon(vq); 376 ret = vb2_streamon(vq, type);
386 if (!ret) 377 if (!ret)
387 v4l2_m2m_try_schedule(m2m_ctx); 378 v4l2_m2m_try_schedule(m2m_ctx);
388 379
@@ -396,10 +387,10 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_streamon);
396int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 387int v4l2_m2m_streamoff(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
397 enum v4l2_buf_type type) 388 enum v4l2_buf_type type)
398{ 389{
399 struct videobuf_queue *vq; 390 struct vb2_queue *vq;
400 391
401 vq = v4l2_m2m_get_vq(m2m_ctx, type); 392 vq = v4l2_m2m_get_vq(m2m_ctx, type);
402 return videobuf_streamoff(vq); 393 return vb2_streamoff(vq, type);
403} 394}
404EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff); 395EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
405 396
@@ -414,44 +405,53 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_streamoff);
414unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 405unsigned int v4l2_m2m_poll(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
415 struct poll_table_struct *wait) 406 struct poll_table_struct *wait)
416{ 407{
417 struct videobuf_queue *src_q, *dst_q; 408 struct vb2_queue *src_q, *dst_q;
418 struct videobuf_buffer *src_vb = NULL, *dst_vb = NULL; 409 struct vb2_buffer *src_vb = NULL, *dst_vb = NULL;
419 unsigned int rc = 0; 410 unsigned int rc = 0;
411 unsigned long flags;
420 412
421 src_q = v4l2_m2m_get_src_vq(m2m_ctx); 413 src_q = v4l2_m2m_get_src_vq(m2m_ctx);
422 dst_q = v4l2_m2m_get_dst_vq(m2m_ctx); 414 dst_q = v4l2_m2m_get_dst_vq(m2m_ctx);
423 415
424 videobuf_queue_lock(src_q); 416 /*
425 videobuf_queue_lock(dst_q); 417 * There has to be at least one buffer queued on each queued_list, which
426 418 * means either in driver already or waiting for driver to claim it
427 if (src_q->streaming && !list_empty(&src_q->stream)) 419 * and start processing.
428 src_vb = list_first_entry(&src_q->stream, 420 */
429 struct videobuf_buffer, stream); 421 if ((!src_q->streaming || list_empty(&src_q->queued_list))
430 if (dst_q->streaming && !list_empty(&dst_q->stream)) 422 && (!dst_q->streaming || list_empty(&dst_q->queued_list))) {
431 dst_vb = list_first_entry(&dst_q->stream,
432 struct videobuf_buffer, stream);
433
434 if (!src_vb && !dst_vb) {
435 rc = POLLERR; 423 rc = POLLERR;
436 goto end; 424 goto end;
437 } 425 }
438 426
439 if (src_vb) { 427 if (m2m_ctx->m2m_dev->m2m_ops->unlock)
440 poll_wait(file, &src_vb->done, wait); 428 m2m_ctx->m2m_dev->m2m_ops->unlock(m2m_ctx->priv);
441 if (src_vb->state == VIDEOBUF_DONE 429
442 || src_vb->state == VIDEOBUF_ERROR) 430 poll_wait(file, &src_q->done_wq, wait);
443 rc |= POLLOUT | POLLWRNORM; 431 poll_wait(file, &dst_q->done_wq, wait);
444 } 432
445 if (dst_vb) { 433 if (m2m_ctx->m2m_dev->m2m_ops->lock)
446 poll_wait(file, &dst_vb->done, wait); 434 m2m_ctx->m2m_dev->m2m_ops->lock(m2m_ctx->priv);
447 if (dst_vb->state == VIDEOBUF_DONE 435
448 || dst_vb->state == VIDEOBUF_ERROR) 436 spin_lock_irqsave(&src_q->done_lock, flags);
449 rc |= POLLIN | POLLRDNORM; 437 if (!list_empty(&src_q->done_list))
450 } 438 src_vb = list_first_entry(&src_q->done_list, struct vb2_buffer,
439 done_entry);
440 if (src_vb && (src_vb->state == VB2_BUF_STATE_DONE
441 || src_vb->state == VB2_BUF_STATE_ERROR))
442 rc |= POLLOUT | POLLWRNORM;
443 spin_unlock_irqrestore(&src_q->done_lock, flags);
444
445 spin_lock_irqsave(&dst_q->done_lock, flags);
446 if (!list_empty(&dst_q->done_list))
447 dst_vb = list_first_entry(&dst_q->done_list, struct vb2_buffer,
448 done_entry);
449 if (dst_vb && (dst_vb->state == VB2_BUF_STATE_DONE
450 || dst_vb->state == VB2_BUF_STATE_ERROR))
451 rc |= POLLIN | POLLRDNORM;
452 spin_unlock_irqrestore(&dst_q->done_lock, flags);
451 453
452end: 454end:
453 videobuf_queue_unlock(dst_q);
454 videobuf_queue_unlock(src_q);
455 return rc; 455 return rc;
456} 456}
457EXPORT_SYMBOL_GPL(v4l2_m2m_poll); 457EXPORT_SYMBOL_GPL(v4l2_m2m_poll);
@@ -470,7 +470,7 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
470 struct vm_area_struct *vma) 470 struct vm_area_struct *vma)
471{ 471{
472 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; 472 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
473 struct videobuf_queue *vq; 473 struct vb2_queue *vq;
474 474
475 if (offset < DST_QUEUE_OFF_BASE) { 475 if (offset < DST_QUEUE_OFF_BASE) {
476 vq = v4l2_m2m_get_src_vq(m2m_ctx); 476 vq = v4l2_m2m_get_src_vq(m2m_ctx);
@@ -479,7 +479,7 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
479 vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT); 479 vma->vm_pgoff -= (DST_QUEUE_OFF_BASE >> PAGE_SHIFT);
480 } 480 }
481 481
482 return videobuf_mmap_mapper(vq, vma); 482 return vb2_mmap(vq, vma);
483} 483}
484EXPORT_SYMBOL(v4l2_m2m_mmap); 484EXPORT_SYMBOL(v4l2_m2m_mmap);
485 485
@@ -531,36 +531,41 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_release);
531 * 531 *
532 * Usually called from driver's open() function. 532 * Usually called from driver's open() function.
533 */ 533 */
534struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(void *priv, struct v4l2_m2m_dev *m2m_dev, 534struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
535 void (*vq_init)(void *priv, struct videobuf_queue *, 535 void *drv_priv,
536 enum v4l2_buf_type)) 536 int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq))
537{ 537{
538 struct v4l2_m2m_ctx *m2m_ctx; 538 struct v4l2_m2m_ctx *m2m_ctx;
539 struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx; 539 struct v4l2_m2m_queue_ctx *out_q_ctx, *cap_q_ctx;
540 540 int ret;
541 if (!vq_init)
542 return ERR_PTR(-EINVAL);
543 541
544 m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL); 542 m2m_ctx = kzalloc(sizeof *m2m_ctx, GFP_KERNEL);
545 if (!m2m_ctx) 543 if (!m2m_ctx)
546 return ERR_PTR(-ENOMEM); 544 return ERR_PTR(-ENOMEM);
547 545
548 m2m_ctx->priv = priv; 546 m2m_ctx->priv = drv_priv;
549 m2m_ctx->m2m_dev = m2m_dev; 547 m2m_ctx->m2m_dev = m2m_dev;
548 init_waitqueue_head(&m2m_ctx->finished);
550 549
551 out_q_ctx = get_queue_ctx(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 550 out_q_ctx = &m2m_ctx->out_q_ctx;
552 cap_q_ctx = get_queue_ctx(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 551 cap_q_ctx = &m2m_ctx->cap_q_ctx;
553 552
554 INIT_LIST_HEAD(&out_q_ctx->rdy_queue); 553 INIT_LIST_HEAD(&out_q_ctx->rdy_queue);
555 INIT_LIST_HEAD(&cap_q_ctx->rdy_queue); 554 INIT_LIST_HEAD(&cap_q_ctx->rdy_queue);
555 spin_lock_init(&out_q_ctx->rdy_spinlock);
556 spin_lock_init(&cap_q_ctx->rdy_spinlock);
556 557
557 INIT_LIST_HEAD(&m2m_ctx->queue); 558 INIT_LIST_HEAD(&m2m_ctx->queue);
558 559
559 vq_init(priv, &out_q_ctx->q, V4L2_BUF_TYPE_VIDEO_OUTPUT); 560 ret = queue_init(drv_priv, &out_q_ctx->q, &cap_q_ctx->q);
560 vq_init(priv, &cap_q_ctx->q, V4L2_BUF_TYPE_VIDEO_CAPTURE); 561
561 out_q_ctx->q.priv_data = cap_q_ctx->q.priv_data = priv; 562 if (ret)
563 goto err;
562 564
563 return m2m_ctx; 565 return m2m_ctx;
566err:
567 kfree(m2m_ctx);
568 return ERR_PTR(ret);
564} 569}
565EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init); 570EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
566 571
@@ -572,7 +577,6 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_init);
572void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx) 577void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
573{ 578{
574 struct v4l2_m2m_dev *m2m_dev; 579 struct v4l2_m2m_dev *m2m_dev;
575 struct videobuf_buffer *vb;
576 unsigned long flags; 580 unsigned long flags;
577 581
578 m2m_dev = m2m_ctx->m2m_dev; 582 m2m_dev = m2m_ctx->m2m_dev;
@@ -582,10 +586,7 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
582 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); 586 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
583 m2m_dev->m2m_ops->job_abort(m2m_ctx->priv); 587 m2m_dev->m2m_ops->job_abort(m2m_ctx->priv);
584 dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx); 588 dprintk("m2m_ctx %p running, will wait to complete", m2m_ctx);
585 vb = v4l2_m2m_next_dst_buf(m2m_ctx); 589 wait_event(m2m_ctx->finished, !(m2m_ctx->job_flags & TRANS_RUNNING));
586 BUG_ON(NULL == vb);
587 wait_event(vb->done, vb->state != VIDEOBUF_ACTIVE
588 && vb->state != VIDEOBUF_QUEUED);
589 } else if (m2m_ctx->job_flags & TRANS_QUEUED) { 590 } else if (m2m_ctx->job_flags & TRANS_QUEUED) {
590 list_del(&m2m_ctx->queue); 591 list_del(&m2m_ctx->queue);
591 m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING); 592 m2m_ctx->job_flags &= ~(TRANS_QUEUED | TRANS_RUNNING);
@@ -597,11 +598,8 @@ void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx)
597 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags); 598 spin_unlock_irqrestore(&m2m_dev->job_spinlock, flags);
598 } 599 }
599 600
600 videobuf_stop(&m2m_ctx->cap_q_ctx.q); 601 vb2_queue_release(&m2m_ctx->cap_q_ctx.q);
601 videobuf_stop(&m2m_ctx->out_q_ctx.q); 602 vb2_queue_release(&m2m_ctx->out_q_ctx.q);
602
603 videobuf_mmap_free(&m2m_ctx->cap_q_ctx.q);
604 videobuf_mmap_free(&m2m_ctx->out_q_ctx.q);
605 603
606 kfree(m2m_ctx); 604 kfree(m2m_ctx);
607} 605}
@@ -611,23 +609,21 @@ EXPORT_SYMBOL_GPL(v4l2_m2m_ctx_release);
611 * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list. 609 * v4l2_m2m_buf_queue() - add a buffer to the proper ready buffers list.
612 * 610 *
613 * Call from buf_queue(), videobuf_queue_ops callback. 611 * Call from buf_queue(), videobuf_queue_ops callback.
614 *
615 * Locking: Caller holds q->irqlock (taken by videobuf before calling buf_queue
616 * callback in the driver).
617 */ 612 */
618void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct videobuf_queue *vq, 613void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb)
619 struct videobuf_buffer *vb)
620{ 614{
615 struct v4l2_m2m_buffer *b = container_of(vb, struct v4l2_m2m_buffer, vb);
621 struct v4l2_m2m_queue_ctx *q_ctx; 616 struct v4l2_m2m_queue_ctx *q_ctx;
617 unsigned long flags;
622 618
623 q_ctx = get_queue_ctx(m2m_ctx, vq->type); 619 q_ctx = get_queue_ctx(m2m_ctx, vb->vb2_queue->type);
624 if (!q_ctx) 620 if (!q_ctx)
625 return; 621 return;
626 622
627 list_add_tail(&vb->queue, &q_ctx->rdy_queue); 623 spin_lock_irqsave(&q_ctx->rdy_spinlock, flags);
624 list_add_tail(&b->list, &q_ctx->rdy_queue);
628 q_ctx->num_rdy++; 625 q_ctx->num_rdy++;
629 626 spin_unlock_irqrestore(&q_ctx->rdy_spinlock, flags);
630 vb->state = VIDEOBUF_QUEUED;
631} 627}
632EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue); 628EXPORT_SYMBOL_GPL(v4l2_m2m_buf_queue);
633 629
diff --git a/drivers/media/video/v4l2-subdev.c b/drivers/media/video/v4l2-subdev.c
new file mode 100644
index 000000000000..0b8064490676
--- /dev/null
+++ b/drivers/media/video/v4l2-subdev.c
@@ -0,0 +1,332 @@
1/*
2 * V4L2 sub-device
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contact: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/ioctl.h>
24#include <linux/slab.h>
25#include <linux/types.h>
26#include <linux/videodev2.h>
27
28#include <media/v4l2-ctrls.h>
29#include <media/v4l2-device.h>
30#include <media/v4l2-ioctl.h>
31#include <media/v4l2-fh.h>
32#include <media/v4l2-event.h>
33
34static int subdev_fh_init(struct v4l2_subdev_fh *fh, struct v4l2_subdev *sd)
35{
36#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
37 /* Allocate try format and crop in the same memory block */
38 fh->try_fmt = kzalloc((sizeof(*fh->try_fmt) + sizeof(*fh->try_crop))
39 * sd->entity.num_pads, GFP_KERNEL);
40 if (fh->try_fmt == NULL)
41 return -ENOMEM;
42
43 fh->try_crop = (struct v4l2_rect *)
44 (fh->try_fmt + sd->entity.num_pads);
45#endif
46 return 0;
47}
48
49static void subdev_fh_free(struct v4l2_subdev_fh *fh)
50{
51#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
52 kfree(fh->try_fmt);
53 fh->try_fmt = NULL;
54 fh->try_crop = NULL;
55#endif
56}
57
58static int subdev_open(struct file *file)
59{
60 struct video_device *vdev = video_devdata(file);
61 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
62 struct v4l2_subdev_fh *subdev_fh;
63#if defined(CONFIG_MEDIA_CONTROLLER)
64 struct media_entity *entity = NULL;
65#endif
66 int ret;
67
68 subdev_fh = kzalloc(sizeof(*subdev_fh), GFP_KERNEL);
69 if (subdev_fh == NULL)
70 return -ENOMEM;
71
72 ret = subdev_fh_init(subdev_fh, sd);
73 if (ret) {
74 kfree(subdev_fh);
75 return ret;
76 }
77
78 ret = v4l2_fh_init(&subdev_fh->vfh, vdev);
79 if (ret)
80 goto err;
81
82 if (sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS) {
83 ret = v4l2_event_init(&subdev_fh->vfh);
84 if (ret)
85 goto err;
86
87 ret = v4l2_event_alloc(&subdev_fh->vfh, sd->nevents);
88 if (ret)
89 goto err;
90 }
91
92 v4l2_fh_add(&subdev_fh->vfh);
93 file->private_data = &subdev_fh->vfh;
94#if defined(CONFIG_MEDIA_CONTROLLER)
95 if (sd->v4l2_dev->mdev) {
96 entity = media_entity_get(&sd->entity);
97 if (!entity) {
98 ret = -EBUSY;
99 goto err;
100 }
101 }
102#endif
103
104 if (sd->internal_ops && sd->internal_ops->open) {
105 ret = sd->internal_ops->open(sd, subdev_fh);
106 if (ret < 0)
107 goto err;
108 }
109
110 return 0;
111
112err:
113#if defined(CONFIG_MEDIA_CONTROLLER)
114 if (entity)
115 media_entity_put(entity);
116#endif
117 v4l2_fh_del(&subdev_fh->vfh);
118 v4l2_fh_exit(&subdev_fh->vfh);
119 subdev_fh_free(subdev_fh);
120 kfree(subdev_fh);
121
122 return ret;
123}
124
125static int subdev_close(struct file *file)
126{
127 struct video_device *vdev = video_devdata(file);
128 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
129 struct v4l2_fh *vfh = file->private_data;
130 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
131
132 if (sd->internal_ops && sd->internal_ops->close)
133 sd->internal_ops->close(sd, subdev_fh);
134#if defined(CONFIG_MEDIA_CONTROLLER)
135 if (sd->v4l2_dev->mdev)
136 media_entity_put(&sd->entity);
137#endif
138 v4l2_fh_del(vfh);
139 v4l2_fh_exit(vfh);
140 subdev_fh_free(subdev_fh);
141 kfree(subdev_fh);
142 file->private_data = NULL;
143
144 return 0;
145}
146
147static long subdev_do_ioctl(struct file *file, unsigned int cmd, void *arg)
148{
149 struct video_device *vdev = video_devdata(file);
150 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
151 struct v4l2_fh *vfh = file->private_data;
152#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
153 struct v4l2_subdev_fh *subdev_fh = to_v4l2_subdev_fh(vfh);
154#endif
155
156 switch (cmd) {
157 case VIDIOC_QUERYCTRL:
158 return v4l2_subdev_queryctrl(sd, arg);
159
160 case VIDIOC_QUERYMENU:
161 return v4l2_subdev_querymenu(sd, arg);
162
163 case VIDIOC_G_CTRL:
164 return v4l2_subdev_g_ctrl(sd, arg);
165
166 case VIDIOC_S_CTRL:
167 return v4l2_subdev_s_ctrl(sd, arg);
168
169 case VIDIOC_G_EXT_CTRLS:
170 return v4l2_subdev_g_ext_ctrls(sd, arg);
171
172 case VIDIOC_S_EXT_CTRLS:
173 return v4l2_subdev_s_ext_ctrls(sd, arg);
174
175 case VIDIOC_TRY_EXT_CTRLS:
176 return v4l2_subdev_try_ext_ctrls(sd, arg);
177
178 case VIDIOC_DQEVENT:
179 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
180 return -ENOIOCTLCMD;
181
182 return v4l2_event_dequeue(vfh, arg, file->f_flags & O_NONBLOCK);
183
184 case VIDIOC_SUBSCRIBE_EVENT:
185 return v4l2_subdev_call(sd, core, subscribe_event, vfh, arg);
186
187 case VIDIOC_UNSUBSCRIBE_EVENT:
188 return v4l2_subdev_call(sd, core, unsubscribe_event, vfh, arg);
189#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
190 case VIDIOC_SUBDEV_G_FMT: {
191 struct v4l2_subdev_format *format = arg;
192
193 if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
194 format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
195 return -EINVAL;
196
197 if (format->pad >= sd->entity.num_pads)
198 return -EINVAL;
199
200 return v4l2_subdev_call(sd, pad, get_fmt, subdev_fh, format);
201 }
202
203 case VIDIOC_SUBDEV_S_FMT: {
204 struct v4l2_subdev_format *format = arg;
205
206 if (format->which != V4L2_SUBDEV_FORMAT_TRY &&
207 format->which != V4L2_SUBDEV_FORMAT_ACTIVE)
208 return -EINVAL;
209
210 if (format->pad >= sd->entity.num_pads)
211 return -EINVAL;
212
213 return v4l2_subdev_call(sd, pad, set_fmt, subdev_fh, format);
214 }
215
216 case VIDIOC_SUBDEV_G_CROP: {
217 struct v4l2_subdev_crop *crop = arg;
218
219 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
220 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
221 return -EINVAL;
222
223 if (crop->pad >= sd->entity.num_pads)
224 return -EINVAL;
225
226 return v4l2_subdev_call(sd, pad, get_crop, subdev_fh, crop);
227 }
228
229 case VIDIOC_SUBDEV_S_CROP: {
230 struct v4l2_subdev_crop *crop = arg;
231
232 if (crop->which != V4L2_SUBDEV_FORMAT_TRY &&
233 crop->which != V4L2_SUBDEV_FORMAT_ACTIVE)
234 return -EINVAL;
235
236 if (crop->pad >= sd->entity.num_pads)
237 return -EINVAL;
238
239 return v4l2_subdev_call(sd, pad, set_crop, subdev_fh, crop);
240 }
241
242 case VIDIOC_SUBDEV_ENUM_MBUS_CODE: {
243 struct v4l2_subdev_mbus_code_enum *code = arg;
244
245 if (code->pad >= sd->entity.num_pads)
246 return -EINVAL;
247
248 return v4l2_subdev_call(sd, pad, enum_mbus_code, subdev_fh,
249 code);
250 }
251
252 case VIDIOC_SUBDEV_ENUM_FRAME_SIZE: {
253 struct v4l2_subdev_frame_size_enum *fse = arg;
254
255 if (fse->pad >= sd->entity.num_pads)
256 return -EINVAL;
257
258 return v4l2_subdev_call(sd, pad, enum_frame_size, subdev_fh,
259 fse);
260 }
261
262 case VIDIOC_SUBDEV_G_FRAME_INTERVAL:
263 return v4l2_subdev_call(sd, video, g_frame_interval, arg);
264
265 case VIDIOC_SUBDEV_S_FRAME_INTERVAL:
266 return v4l2_subdev_call(sd, video, s_frame_interval, arg);
267
268 case VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL: {
269 struct v4l2_subdev_frame_interval_enum *fie = arg;
270
271 if (fie->pad >= sd->entity.num_pads)
272 return -EINVAL;
273
274 return v4l2_subdev_call(sd, pad, enum_frame_interval, subdev_fh,
275 fie);
276 }
277#endif
278 default:
279 return v4l2_subdev_call(sd, core, ioctl, cmd, arg);
280 }
281
282 return 0;
283}
284
285static long subdev_ioctl(struct file *file, unsigned int cmd,
286 unsigned long arg)
287{
288 return video_usercopy(file, cmd, arg, subdev_do_ioctl);
289}
290
291static unsigned int subdev_poll(struct file *file, poll_table *wait)
292{
293 struct video_device *vdev = video_devdata(file);
294 struct v4l2_subdev *sd = vdev_to_v4l2_subdev(vdev);
295 struct v4l2_fh *fh = file->private_data;
296
297 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_EVENTS))
298 return POLLERR;
299
300 poll_wait(file, &fh->events->wait, wait);
301
302 if (v4l2_event_pending(fh))
303 return POLLPRI;
304
305 return 0;
306}
307
308const struct v4l2_file_operations v4l2_subdev_fops = {
309 .owner = THIS_MODULE,
310 .open = subdev_open,
311 .unlocked_ioctl = subdev_ioctl,
312 .release = subdev_close,
313 .poll = subdev_poll,
314};
315
316void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops)
317{
318 INIT_LIST_HEAD(&sd->list);
319 BUG_ON(!ops);
320 sd->ops = ops;
321 sd->v4l2_dev = NULL;
322 sd->flags = 0;
323 sd->name[0] = '\0';
324 sd->grp_id = 0;
325 sd->dev_priv = NULL;
326 sd->host_priv = NULL;
327#if defined(CONFIG_MEDIA_CONTROLLER)
328 sd->entity.name = sd->name;
329 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV;
330#endif
331}
332EXPORT_SYMBOL(v4l2_subdev_init);
diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c
index 2f973cd56408..8c780c2d937b 100644
--- a/drivers/media/video/via-camera.c
+++ b/drivers/media/video/via-camera.c
@@ -25,6 +25,7 @@
25#include <linux/via-core.h> 25#include <linux/via-core.h>
26#include <linux/via-gpio.h> 26#include <linux/via-gpio.h>
27#include <linux/via_i2c.h> 27#include <linux/via_i2c.h>
28#include <asm/olpc.h>
28 29
29#include "via-camera.h" 30#include "via-camera.h"
30 31
@@ -38,14 +39,12 @@ MODULE_PARM_DESC(flip_image,
38 "If set, the sensor will be instructed to flip the image " 39 "If set, the sensor will be instructed to flip the image "
39 "vertically."); 40 "vertically.");
40 41
41#ifdef CONFIG_OLPC_XO_1_5
42static int override_serial; 42static int override_serial;
43module_param(override_serial, bool, 0444); 43module_param(override_serial, bool, 0444);
44MODULE_PARM_DESC(override_serial, 44MODULE_PARM_DESC(override_serial,
45 "The camera driver will normally refuse to load if " 45 "The camera driver will normally refuse to load if "
46 "the XO 1.5 serial port is enabled. Set this option " 46 "the XO 1.5 serial port is enabled. Set this option "
47 "to force the issue."); 47 "to force-enable the camera.");
48#endif
49 48
50/* 49/*
51 * Basic window sizes. 50 * Basic window sizes.
@@ -1246,6 +1245,62 @@ static const struct v4l2_ioctl_ops viacam_ioctl_ops = {
1246/* 1245/*
1247 * Power management. 1246 * Power management.
1248 */ 1247 */
1248#ifdef CONFIG_PM
1249
1250static int viacam_suspend(void *priv)
1251{
1252 struct via_camera *cam = priv;
1253 enum viacam_opstate state = cam->opstate;
1254
1255 if (cam->opstate != S_IDLE) {
1256 viacam_stop_engine(cam);
1257 cam->opstate = state; /* So resume restarts */
1258 }
1259
1260 return 0;
1261}
1262
1263static int viacam_resume(void *priv)
1264{
1265 struct via_camera *cam = priv;
1266 int ret = 0;
1267
1268 /*
1269 * Get back to a reasonable operating state.
1270 */
1271 via_write_reg_mask(VIASR, 0x78, 0, 0x80);
1272 via_write_reg_mask(VIASR, 0x1e, 0xc0, 0xc0);
1273 viacam_int_disable(cam);
1274 set_bit(CF_CONFIG_NEEDED, &cam->flags);
1275 /*
1276 * Make sure the sensor's power state is correct
1277 */
1278 if (cam->users > 0)
1279 via_sensor_power_up(cam);
1280 else
1281 via_sensor_power_down(cam);
1282 /*
1283 * If it was operating, try to restart it.
1284 */
1285 if (cam->opstate != S_IDLE) {
1286 mutex_lock(&cam->lock);
1287 ret = viacam_configure_sensor(cam);
1288 if (!ret)
1289 ret = viacam_config_controller(cam);
1290 mutex_unlock(&cam->lock);
1291 if (!ret)
1292 viacam_start_engine(cam);
1293 }
1294
1295 return ret;
1296}
1297
1298static struct viafb_pm_hooks viacam_pm_hooks = {
1299 .suspend = viacam_suspend,
1300 .resume = viacam_resume
1301};
1302
1303#endif /* CONFIG_PM */
1249 1304
1250/* 1305/*
1251 * Setup stuff. 1306 * Setup stuff.
@@ -1261,6 +1316,37 @@ static struct video_device viacam_v4l_template = {
1261 .release = video_device_release_empty, /* Check this */ 1316 .release = video_device_release_empty, /* Check this */
1262}; 1317};
1263 1318
1319/*
1320 * The OLPC folks put the serial port on the same pin as
1321 * the camera. They also get grumpy if we break the
1322 * serial port and keep them from using it. So we have
1323 * to check the serial enable bit and not step on it.
1324 */
1325#define VIACAM_SERIAL_DEVFN 0x88
1326#define VIACAM_SERIAL_CREG 0x46
1327#define VIACAM_SERIAL_BIT 0x40
1328
1329static __devinit bool viacam_serial_is_enabled(void)
1330{
1331 struct pci_bus *pbus = pci_find_bus(0, 0);
1332 u8 cbyte;
1333
1334 pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1335 VIACAM_SERIAL_CREG, &cbyte);
1336 if ((cbyte & VIACAM_SERIAL_BIT) == 0)
1337 return false; /* Not enabled */
1338 if (override_serial == 0) {
1339 printk(KERN_NOTICE "Via camera: serial port is enabled, " \
1340 "refusing to load.\n");
1341 printk(KERN_NOTICE "Specify override_serial=1 to force " \
1342 "module loading.\n");
1343 return true;
1344 }
1345 printk(KERN_NOTICE "Via camera: overriding serial port\n");
1346 pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1347 VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
1348 return false;
1349}
1264 1350
1265static __devinit int viacam_probe(struct platform_device *pdev) 1351static __devinit int viacam_probe(struct platform_device *pdev)
1266{ 1352{
@@ -1292,6 +1378,10 @@ static __devinit int viacam_probe(struct platform_device *pdev)
1292 printk(KERN_ERR "viacam: No I/O memory, so no pictures\n"); 1378 printk(KERN_ERR "viacam: No I/O memory, so no pictures\n");
1293 return -ENOMEM; 1379 return -ENOMEM;
1294 } 1380 }
1381
1382 if (machine_is_olpc() && viacam_serial_is_enabled())
1383 return -EBUSY;
1384
1295 /* 1385 /*
1296 * Basic structure initialization. 1386 * Basic structure initialization.
1297 */ 1387 */
@@ -1369,6 +1459,14 @@ static __devinit int viacam_probe(struct platform_device *pdev)
1369 goto out_irq; 1459 goto out_irq;
1370 video_set_drvdata(&cam->vdev, cam); 1460 video_set_drvdata(&cam->vdev, cam);
1371 1461
1462#ifdef CONFIG_PM
1463 /*
1464 * Hook into PM events
1465 */
1466 viacam_pm_hooks.private = cam;
1467 viafb_pm_register(&viacam_pm_hooks);
1468#endif
1469
1372 /* Power the sensor down until somebody opens the device */ 1470 /* Power the sensor down until somebody opens the device */
1373 via_sensor_power_down(cam); 1471 via_sensor_power_down(cam);
1374 return 0; 1472 return 0;
@@ -1395,7 +1493,6 @@ static __devexit int viacam_remove(struct platform_device *pdev)
1395 return 0; 1493 return 0;
1396} 1494}
1397 1495
1398
1399static struct platform_driver viacam_driver = { 1496static struct platform_driver viacam_driver = {
1400 .driver = { 1497 .driver = {
1401 .name = "viafb-camera", 1498 .name = "viafb-camera",
@@ -1404,50 +1501,8 @@ static struct platform_driver viacam_driver = {
1404 .remove = viacam_remove, 1501 .remove = viacam_remove,
1405}; 1502};
1406 1503
1407
1408#ifdef CONFIG_OLPC_XO_1_5
1409/*
1410 * The OLPC folks put the serial port on the same pin as
1411 * the camera. They also get grumpy if we break the
1412 * serial port and keep them from using it. So we have
1413 * to check the serial enable bit and not step on it.
1414 */
1415#define VIACAM_SERIAL_DEVFN 0x88
1416#define VIACAM_SERIAL_CREG 0x46
1417#define VIACAM_SERIAL_BIT 0x40
1418
1419static __devinit int viacam_check_serial_port(void)
1420{
1421 struct pci_bus *pbus = pci_find_bus(0, 0);
1422 u8 cbyte;
1423
1424 pci_bus_read_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1425 VIACAM_SERIAL_CREG, &cbyte);
1426 if ((cbyte & VIACAM_SERIAL_BIT) == 0)
1427 return 0; /* Not enabled */
1428 if (override_serial == 0) {
1429 printk(KERN_NOTICE "Via camera: serial port is enabled, " \
1430 "refusing to load.\n");
1431 printk(KERN_NOTICE "Specify override_serial=1 to force " \
1432 "module loading.\n");
1433 return -EBUSY;
1434 }
1435 printk(KERN_NOTICE "Via camera: overriding serial port\n");
1436 pci_bus_write_config_byte(pbus, VIACAM_SERIAL_DEVFN,
1437 VIACAM_SERIAL_CREG, cbyte & ~VIACAM_SERIAL_BIT);
1438 return 0;
1439}
1440#endif
1441
1442
1443
1444
1445static int viacam_init(void) 1504static int viacam_init(void)
1446{ 1505{
1447#ifdef CONFIG_OLPC_XO_1_5
1448 if (viacam_check_serial_port())
1449 return -EBUSY;
1450#endif
1451 return platform_driver_register(&viacam_driver); 1506 return platform_driver_register(&viacam_driver);
1452} 1507}
1453module_init(viacam_init); 1508module_init(viacam_init);
diff --git a/drivers/media/video/videobuf-dma-contig.c b/drivers/media/video/videobuf-dma-contig.c
index c9691115f2d2..c4742fc15529 100644
--- a/drivers/media/video/videobuf-dma-contig.c
+++ b/drivers/media/video/videobuf-dma-contig.c
@@ -300,7 +300,7 @@ static int __videobuf_mmap_mapper(struct videobuf_queue *q,
300 300
301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); 301 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
302 retval = remap_pfn_range(vma, vma->vm_start, 302 retval = remap_pfn_range(vma, vma->vm_start,
303 mem->dma_handle >> PAGE_SHIFT, 303 PFN_DOWN(virt_to_phys(mem->vaddr)),
304 size, vma->vm_page_prot); 304 size, vma->vm_page_prot);
305 if (retval) { 305 if (retval) {
306 dev_err(q->dev, "mmap: remap failed with error %d. ", retval); 306 dev_err(q->dev, "mmap: remap failed with error %d. ", retval);
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
new file mode 100644
index 000000000000..6698c77e0f64
--- /dev/null
+++ b/drivers/media/video/videobuf2-core.c
@@ -0,0 +1,1819 @@
1/*
2 * videobuf2-core.c - V4L2 driver helper framework
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 * Marek Szyprowski <m.szyprowski@samsung.com>
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.
12 */
13
14#include <linux/err.h>
15#include <linux/kernel.h>
16#include <linux/module.h>
17#include <linux/mm.h>
18#include <linux/poll.h>
19#include <linux/slab.h>
20#include <linux/sched.h>
21
22#include <media/videobuf2-core.h>
23
24static int debug;
25module_param(debug, int, 0644);
26
27#define dprintk(level, fmt, arg...) \
28 do { \
29 if (debug >= level) \
30 printk(KERN_DEBUG "vb2: " fmt, ## arg); \
31 } while (0)
32
33#define call_memop(q, plane, op, args...) \
34 (((q)->mem_ops->op) ? \
35 ((q)->mem_ops->op(args)) : 0)
36
37#define call_qop(q, op, args...) \
38 (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
39
40/**
41 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
42 */
43static int __vb2_buf_mem_alloc(struct vb2_buffer *vb,
44 unsigned long *plane_sizes)
45{
46 struct vb2_queue *q = vb->vb2_queue;
47 void *mem_priv;
48 int plane;
49
50 /* Allocate memory for all planes in this buffer */
51 for (plane = 0; plane < vb->num_planes; ++plane) {
52 mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane],
53 plane_sizes[plane]);
54 if (!mem_priv)
55 goto free;
56
57 /* Associate allocator private data with this plane */
58 vb->planes[plane].mem_priv = mem_priv;
59 vb->v4l2_planes[plane].length = plane_sizes[plane];
60 }
61
62 return 0;
63free:
64 /* Free already allocated memory if one of the allocations failed */
65 for (; plane > 0; --plane)
66 call_memop(q, plane, put, vb->planes[plane - 1].mem_priv);
67
68 return -ENOMEM;
69}
70
71/**
72 * __vb2_buf_mem_free() - free memory of the given buffer
73 */
74static void __vb2_buf_mem_free(struct vb2_buffer *vb)
75{
76 struct vb2_queue *q = vb->vb2_queue;
77 unsigned int plane;
78
79 for (plane = 0; plane < vb->num_planes; ++plane) {
80 call_memop(q, plane, put, vb->planes[plane].mem_priv);
81 vb->planes[plane].mem_priv = NULL;
82 dprintk(3, "Freed plane %d of buffer %d\n",
83 plane, vb->v4l2_buf.index);
84 }
85}
86
87/**
88 * __vb2_buf_userptr_put() - release userspace memory associated with
89 * a USERPTR buffer
90 */
91static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
92{
93 struct vb2_queue *q = vb->vb2_queue;
94 unsigned int plane;
95
96 for (plane = 0; plane < vb->num_planes; ++plane) {
97 void *mem_priv = vb->planes[plane].mem_priv;
98
99 if (mem_priv) {
100 call_memop(q, plane, put_userptr, mem_priv);
101 vb->planes[plane].mem_priv = NULL;
102 }
103 }
104}
105
106/**
107 * __setup_offsets() - setup unique offsets ("cookies") for every plane in
108 * every buffer on the queue
109 */
110static void __setup_offsets(struct vb2_queue *q)
111{
112 unsigned int buffer, plane;
113 struct vb2_buffer *vb;
114 unsigned long off = 0;
115
116 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
117 vb = q->bufs[buffer];
118 if (!vb)
119 continue;
120
121 for (plane = 0; plane < vb->num_planes; ++plane) {
122 vb->v4l2_planes[plane].m.mem_offset = off;
123
124 dprintk(3, "Buffer %d, plane %d offset 0x%08lx\n",
125 buffer, plane, off);
126
127 off += vb->v4l2_planes[plane].length;
128 off = PAGE_ALIGN(off);
129 }
130 }
131}
132
133/**
134 * __vb2_queue_alloc() - allocate videobuf buffer structures and (for MMAP type)
135 * video buffer memory for all buffers/planes on the queue and initializes the
136 * queue
137 *
138 * Returns the number of buffers successfully allocated.
139 */
140static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
141 unsigned int num_buffers, unsigned int num_planes,
142 unsigned long plane_sizes[])
143{
144 unsigned int buffer;
145 struct vb2_buffer *vb;
146 int ret;
147
148 for (buffer = 0; buffer < num_buffers; ++buffer) {
149 /* Allocate videobuf buffer structures */
150 vb = kzalloc(q->buf_struct_size, GFP_KERNEL);
151 if (!vb) {
152 dprintk(1, "Memory alloc for buffer struct failed\n");
153 break;
154 }
155
156 /* Length stores number of planes for multiplanar buffers */
157 if (V4L2_TYPE_IS_MULTIPLANAR(q->type))
158 vb->v4l2_buf.length = num_planes;
159
160 vb->state = VB2_BUF_STATE_DEQUEUED;
161 vb->vb2_queue = q;
162 vb->num_planes = num_planes;
163 vb->v4l2_buf.index = buffer;
164 vb->v4l2_buf.type = q->type;
165 vb->v4l2_buf.memory = memory;
166
167 /* Allocate video buffer memory for the MMAP type */
168 if (memory == V4L2_MEMORY_MMAP) {
169 ret = __vb2_buf_mem_alloc(vb, plane_sizes);
170 if (ret) {
171 dprintk(1, "Failed allocating memory for "
172 "buffer %d\n", buffer);
173 kfree(vb);
174 break;
175 }
176 /*
177 * Call the driver-provided buffer initialization
178 * callback, if given. An error in initialization
179 * results in queue setup failure.
180 */
181 ret = call_qop(q, buf_init, vb);
182 if (ret) {
183 dprintk(1, "Buffer %d %p initialization"
184 " failed\n", buffer, vb);
185 __vb2_buf_mem_free(vb);
186 kfree(vb);
187 break;
188 }
189 }
190
191 q->bufs[buffer] = vb;
192 }
193
194 q->num_buffers = buffer;
195
196 __setup_offsets(q);
197
198 dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
199 q->num_buffers, num_planes);
200
201 return buffer;
202}
203
204/**
205 * __vb2_free_mem() - release all video buffer memory for a given queue
206 */
207static void __vb2_free_mem(struct vb2_queue *q)
208{
209 unsigned int buffer;
210 struct vb2_buffer *vb;
211
212 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
213 vb = q->bufs[buffer];
214 if (!vb)
215 continue;
216
217 /* Free MMAP buffers or release USERPTR buffers */
218 if (q->memory == V4L2_MEMORY_MMAP)
219 __vb2_buf_mem_free(vb);
220 else
221 __vb2_buf_userptr_put(vb);
222 }
223}
224
225/**
226 * __vb2_queue_free() - free the queue - video memory and related information
227 * and return the queue to an uninitialized state. Might be called even if the
228 * queue has already been freed.
229 */
230static void __vb2_queue_free(struct vb2_queue *q)
231{
232 unsigned int buffer;
233
234 /* Call driver-provided cleanup function for each buffer, if provided */
235 if (q->ops->buf_cleanup) {
236 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
237 if (NULL == q->bufs[buffer])
238 continue;
239 q->ops->buf_cleanup(q->bufs[buffer]);
240 }
241 }
242
243 /* Release video buffer memory */
244 __vb2_free_mem(q);
245
246 /* Free videobuf buffers */
247 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
248 kfree(q->bufs[buffer]);
249 q->bufs[buffer] = NULL;
250 }
251
252 q->num_buffers = 0;
253 q->memory = 0;
254}
255
256/**
257 * __verify_planes_array() - verify that the planes array passed in struct
258 * v4l2_buffer from userspace can be safely used
259 */
260static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b)
261{
262 /* Is memory for copying plane information present? */
263 if (NULL == b->m.planes) {
264 dprintk(1, "Multi-planar buffer passed but "
265 "planes array not provided\n");
266 return -EINVAL;
267 }
268
269 if (b->length < vb->num_planes || b->length > VIDEO_MAX_PLANES) {
270 dprintk(1, "Incorrect planes array length, "
271 "expected %d, got %d\n", vb->num_planes, b->length);
272 return -EINVAL;
273 }
274
275 return 0;
276}
277
278/**
279 * __fill_v4l2_buffer() - fill in a struct v4l2_buffer with information to be
280 * returned to userspace
281 */
282static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
283{
284 struct vb2_queue *q = vb->vb2_queue;
285 int ret = 0;
286
287 /* Copy back data such as timestamp, input, etc. */
288 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
289 b->input = vb->v4l2_buf.input;
290 b->reserved = vb->v4l2_buf.reserved;
291
292 if (V4L2_TYPE_IS_MULTIPLANAR(q->type)) {
293 ret = __verify_planes_array(vb, b);
294 if (ret)
295 return ret;
296
297 /*
298 * Fill in plane-related data if userspace provided an array
299 * for it. The memory and size is verified above.
300 */
301 memcpy(b->m.planes, vb->v4l2_planes,
302 b->length * sizeof(struct v4l2_plane));
303 } else {
304 /*
305 * We use length and offset in v4l2_planes array even for
306 * single-planar buffers, but userspace does not.
307 */
308 b->length = vb->v4l2_planes[0].length;
309 b->bytesused = vb->v4l2_planes[0].bytesused;
310 if (q->memory == V4L2_MEMORY_MMAP)
311 b->m.offset = vb->v4l2_planes[0].m.mem_offset;
312 else if (q->memory == V4L2_MEMORY_USERPTR)
313 b->m.userptr = vb->v4l2_planes[0].m.userptr;
314 }
315
316 b->flags = 0;
317
318 switch (vb->state) {
319 case VB2_BUF_STATE_QUEUED:
320 case VB2_BUF_STATE_ACTIVE:
321 b->flags |= V4L2_BUF_FLAG_QUEUED;
322 break;
323 case VB2_BUF_STATE_ERROR:
324 b->flags |= V4L2_BUF_FLAG_ERROR;
325 /* fall through */
326 case VB2_BUF_STATE_DONE:
327 b->flags |= V4L2_BUF_FLAG_DONE;
328 break;
329 case VB2_BUF_STATE_DEQUEUED:
330 /* nothing */
331 break;
332 }
333
334 if (vb->num_planes_mapped == vb->num_planes)
335 b->flags |= V4L2_BUF_FLAG_MAPPED;
336
337 return ret;
338}
339
340/**
341 * vb2_querybuf() - query video buffer information
342 * @q: videobuf queue
343 * @b: buffer struct passed from userspace to vidioc_querybuf handler
344 * in driver
345 *
346 * Should be called from vidioc_querybuf ioctl handler in driver.
347 * This function will verify the passed v4l2_buffer structure and fill the
348 * relevant information for the userspace.
349 *
350 * The return values from this function are intended to be directly returned
351 * from vidioc_querybuf handler in driver.
352 */
353int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b)
354{
355 struct vb2_buffer *vb;
356
357 if (b->type != q->type) {
358 dprintk(1, "querybuf: wrong buffer type\n");
359 return -EINVAL;
360 }
361
362 if (b->index >= q->num_buffers) {
363 dprintk(1, "querybuf: buffer index out of range\n");
364 return -EINVAL;
365 }
366 vb = q->bufs[b->index];
367
368 return __fill_v4l2_buffer(vb, b);
369}
370EXPORT_SYMBOL(vb2_querybuf);
371
372/**
373 * __verify_userptr_ops() - verify that all memory operations required for
374 * USERPTR queue type have been provided
375 */
376static int __verify_userptr_ops(struct vb2_queue *q)
377{
378 if (!(q->io_modes & VB2_USERPTR) || !q->mem_ops->get_userptr ||
379 !q->mem_ops->put_userptr)
380 return -EINVAL;
381
382 return 0;
383}
384
385/**
386 * __verify_mmap_ops() - verify that all memory operations required for
387 * MMAP queue type have been provided
388 */
389static int __verify_mmap_ops(struct vb2_queue *q)
390{
391 if (!(q->io_modes & VB2_MMAP) || !q->mem_ops->alloc ||
392 !q->mem_ops->put || !q->mem_ops->mmap)
393 return -EINVAL;
394
395 return 0;
396}
397
398/**
399 * __buffers_in_use() - return true if any buffers on the queue are in use and
400 * the queue cannot be freed (by the means of REQBUFS(0)) call
401 */
402static bool __buffers_in_use(struct vb2_queue *q)
403{
404 unsigned int buffer, plane;
405 struct vb2_buffer *vb;
406
407 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
408 vb = q->bufs[buffer];
409 for (plane = 0; plane < vb->num_planes; ++plane) {
410 /*
411 * If num_users() has not been provided, call_memop
412 * will return 0, apparently nobody cares about this
413 * case anyway. If num_users() returns more than 1,
414 * we are not the only user of the plane's memory.
415 */
416 if (call_memop(q, plane, num_users,
417 vb->planes[plane].mem_priv) > 1)
418 return true;
419 }
420 }
421
422 return false;
423}
424
425/**
426 * vb2_reqbufs() - Initiate streaming
427 * @q: videobuf2 queue
428 * @req: struct passed from userspace to vidioc_reqbufs handler in driver
429 *
430 * Should be called from vidioc_reqbufs ioctl handler of a driver.
431 * This function:
432 * 1) verifies streaming parameters passed from the userspace,
433 * 2) sets up the queue,
434 * 3) negotiates number of buffers and planes per buffer with the driver
435 * to be used during streaming,
436 * 4) allocates internal buffer structures (struct vb2_buffer), according to
437 * the agreed parameters,
438 * 5) for MMAP memory type, allocates actual video memory, using the
439 * memory handling/allocation routines provided during queue initialization
440 *
441 * If req->count is 0, all the memory will be freed instead.
442 * If the queue has been allocated previously (by a previous vb2_reqbufs) call
443 * and the queue is not busy, memory will be reallocated.
444 *
445 * The return values from this function are intended to be directly returned
446 * from vidioc_reqbufs handler in driver.
447 */
448int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
449{
450 unsigned int num_buffers, num_planes;
451 unsigned long plane_sizes[VIDEO_MAX_PLANES];
452 int ret = 0;
453
454 if (q->fileio) {
455 dprintk(1, "reqbufs: file io in progress\n");
456 return -EBUSY;
457 }
458
459 if (req->memory != V4L2_MEMORY_MMAP
460 && req->memory != V4L2_MEMORY_USERPTR) {
461 dprintk(1, "reqbufs: unsupported memory type\n");
462 return -EINVAL;
463 }
464
465 if (req->type != q->type) {
466 dprintk(1, "reqbufs: requested type is incorrect\n");
467 return -EINVAL;
468 }
469
470 if (q->streaming) {
471 dprintk(1, "reqbufs: streaming active\n");
472 return -EBUSY;
473 }
474
475 /*
476 * Make sure all the required memory ops for given memory type
477 * are available.
478 */
479 if (req->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
480 dprintk(1, "reqbufs: MMAP for current setup unsupported\n");
481 return -EINVAL;
482 }
483
484 if (req->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
485 dprintk(1, "reqbufs: USERPTR for current setup unsupported\n");
486 return -EINVAL;
487 }
488
489 /*
490 * If the same number of buffers and memory access method is requested
491 * then return immediately.
492 */
493 if (q->memory == req->memory && req->count == q->num_buffers)
494 return 0;
495
496 if (req->count == 0 || q->num_buffers != 0 || q->memory != req->memory) {
497 /*
498 * We already have buffers allocated, so first check if they
499 * are not in use and can be freed.
500 */
501 if (q->memory == V4L2_MEMORY_MMAP && __buffers_in_use(q)) {
502 dprintk(1, "reqbufs: memory in use, cannot free\n");
503 return -EBUSY;
504 }
505
506 __vb2_queue_free(q);
507
508 /*
509 * In case of REQBUFS(0) return immediately without calling
510 * driver's queue_setup() callback and allocating resources.
511 */
512 if (req->count == 0)
513 return 0;
514 }
515
516 /*
517 * Make sure the requested values and current defaults are sane.
518 */
519 num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
520 memset(plane_sizes, 0, sizeof(plane_sizes));
521 memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
522
523 /*
524 * Ask the driver how many buffers and planes per buffer it requires.
525 * Driver also sets the size and allocator context for each plane.
526 */
527 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
528 plane_sizes, q->alloc_ctx);
529 if (ret)
530 return ret;
531
532 /* Finally, allocate buffers and video memory */
533 ret = __vb2_queue_alloc(q, req->memory, num_buffers, num_planes,
534 plane_sizes);
535 if (ret < 0) {
536 dprintk(1, "Memory allocation failed with error: %d\n", ret);
537 return ret;
538 }
539
540 /*
541 * Check if driver can handle the allocated number of buffers.
542 */
543 if (ret < num_buffers) {
544 unsigned int orig_num_buffers;
545
546 orig_num_buffers = num_buffers = ret;
547 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes,
548 plane_sizes, q->alloc_ctx);
549 if (ret)
550 goto free_mem;
551
552 if (orig_num_buffers < num_buffers) {
553 ret = -ENOMEM;
554 goto free_mem;
555 }
556
557 /*
558 * Ok, driver accepted smaller number of buffers.
559 */
560 ret = num_buffers;
561 }
562
563 q->memory = req->memory;
564
565 /*
566 * Return the number of successfully allocated buffers
567 * to the userspace.
568 */
569 req->count = ret;
570
571 return 0;
572
573free_mem:
574 __vb2_queue_free(q);
575 return ret;
576}
577EXPORT_SYMBOL_GPL(vb2_reqbufs);
578
579/**
580 * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
581 * @vb: vb2_buffer to which the plane in question belongs to
582 * @plane_no: plane number for which the address is to be returned
583 *
584 * This function returns a kernel virtual address of a given plane if
585 * such a mapping exist, NULL otherwise.
586 */
587void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no)
588{
589 struct vb2_queue *q = vb->vb2_queue;
590
591 if (plane_no > vb->num_planes)
592 return NULL;
593
594 return call_memop(q, plane_no, vaddr, vb->planes[plane_no].mem_priv);
595
596}
597EXPORT_SYMBOL_GPL(vb2_plane_vaddr);
598
599/**
600 * vb2_plane_cookie() - Return allocator specific cookie for the given plane
601 * @vb: vb2_buffer to which the plane in question belongs to
602 * @plane_no: plane number for which the cookie is to be returned
603 *
604 * This function returns an allocator specific cookie for a given plane if
605 * available, NULL otherwise. The allocator should provide some simple static
606 * inline function, which would convert this cookie to the allocator specific
607 * type that can be used directly by the driver to access the buffer. This can
608 * be for example physical address, pointer to scatter list or IOMMU mapping.
609 */
610void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no)
611{
612 struct vb2_queue *q = vb->vb2_queue;
613
614 if (plane_no > vb->num_planes)
615 return NULL;
616
617 return call_memop(q, plane_no, cookie, vb->planes[plane_no].mem_priv);
618}
619EXPORT_SYMBOL_GPL(vb2_plane_cookie);
620
621/**
622 * vb2_buffer_done() - inform videobuf that an operation on a buffer is finished
623 * @vb: vb2_buffer returned from the driver
624 * @state: either VB2_BUF_STATE_DONE if the operation finished successfully
625 * or VB2_BUF_STATE_ERROR if the operation finished with an error
626 *
627 * This function should be called by the driver after a hardware operation on
628 * a buffer is finished and the buffer may be returned to userspace. The driver
629 * cannot use this buffer anymore until it is queued back to it by videobuf
630 * by the means of buf_queue callback. Only buffers previously queued to the
631 * driver by buf_queue can be passed to this function.
632 */
633void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state)
634{
635 struct vb2_queue *q = vb->vb2_queue;
636 unsigned long flags;
637
638 if (vb->state != VB2_BUF_STATE_ACTIVE)
639 return;
640
641 if (state != VB2_BUF_STATE_DONE && state != VB2_BUF_STATE_ERROR)
642 return;
643
644 dprintk(4, "Done processing on buffer %d, state: %d\n",
645 vb->v4l2_buf.index, vb->state);
646
647 /* Add the buffer to the done buffers list */
648 spin_lock_irqsave(&q->done_lock, flags);
649 vb->state = state;
650 list_add_tail(&vb->done_entry, &q->done_list);
651 atomic_dec(&q->queued_count);
652 spin_unlock_irqrestore(&q->done_lock, flags);
653
654 /* Inform any processes that may be waiting for buffers */
655 wake_up(&q->done_wq);
656}
657EXPORT_SYMBOL_GPL(vb2_buffer_done);
658
659/**
660 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
661 * a v4l2_buffer by the userspace
662 */
663static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
664 struct v4l2_plane *v4l2_planes)
665{
666 unsigned int plane;
667 int ret;
668
669 if (V4L2_TYPE_IS_MULTIPLANAR(b->type)) {
670 /*
671 * Verify that the userspace gave us a valid array for
672 * plane information.
673 */
674 ret = __verify_planes_array(vb, b);
675 if (ret)
676 return ret;
677
678 /* Fill in driver-provided information for OUTPUT types */
679 if (V4L2_TYPE_IS_OUTPUT(b->type)) {
680 /*
681 * Will have to go up to b->length when API starts
682 * accepting variable number of planes.
683 */
684 for (plane = 0; plane < vb->num_planes; ++plane) {
685 v4l2_planes[plane].bytesused =
686 b->m.planes[plane].bytesused;
687 v4l2_planes[plane].data_offset =
688 b->m.planes[plane].data_offset;
689 }
690 }
691
692 if (b->memory == V4L2_MEMORY_USERPTR) {
693 for (plane = 0; plane < vb->num_planes; ++plane) {
694 v4l2_planes[plane].m.userptr =
695 b->m.planes[plane].m.userptr;
696 v4l2_planes[plane].length =
697 b->m.planes[plane].length;
698 }
699 }
700 } else {
701 /*
702 * Single-planar buffers do not use planes array,
703 * so fill in relevant v4l2_buffer struct fields instead.
704 * In videobuf we use our internal V4l2_planes struct for
705 * single-planar buffers as well, for simplicity.
706 */
707 if (V4L2_TYPE_IS_OUTPUT(b->type))
708 v4l2_planes[0].bytesused = b->bytesused;
709
710 if (b->memory == V4L2_MEMORY_USERPTR) {
711 v4l2_planes[0].m.userptr = b->m.userptr;
712 v4l2_planes[0].length = b->length;
713 }
714 }
715
716 vb->v4l2_buf.field = b->field;
717 vb->v4l2_buf.timestamp = b->timestamp;
718
719 return 0;
720}
721
722/**
723 * __qbuf_userptr() - handle qbuf of a USERPTR buffer
724 */
725static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b)
726{
727 struct v4l2_plane planes[VIDEO_MAX_PLANES];
728 struct vb2_queue *q = vb->vb2_queue;
729 void *mem_priv;
730 unsigned int plane;
731 int ret;
732 int write = !V4L2_TYPE_IS_OUTPUT(q->type);
733
734 /* Verify and copy relevant information provided by the userspace */
735 ret = __fill_vb2_buffer(vb, b, planes);
736 if (ret)
737 return ret;
738
739 for (plane = 0; plane < vb->num_planes; ++plane) {
740 /* Skip the plane if already verified */
741 if (vb->v4l2_planes[plane].m.userptr == planes[plane].m.userptr
742 && vb->v4l2_planes[plane].length == planes[plane].length)
743 continue;
744
745 dprintk(3, "qbuf: userspace address for plane %d changed, "
746 "reacquiring memory\n", plane);
747
748 /* Release previously acquired memory if present */
749 if (vb->planes[plane].mem_priv)
750 call_memop(q, plane, put_userptr,
751 vb->planes[plane].mem_priv);
752
753 vb->planes[plane].mem_priv = NULL;
754
755 /* Acquire each plane's memory */
756 if (q->mem_ops->get_userptr) {
757 mem_priv = q->mem_ops->get_userptr(q->alloc_ctx[plane],
758 planes[plane].m.userptr,
759 planes[plane].length,
760 write);
761 if (IS_ERR(mem_priv)) {
762 dprintk(1, "qbuf: failed acquiring userspace "
763 "memory for plane %d\n", plane);
764 ret = PTR_ERR(mem_priv);
765 goto err;
766 }
767 vb->planes[plane].mem_priv = mem_priv;
768 }
769 }
770
771 /*
772 * Call driver-specific initialization on the newly acquired buffer,
773 * if provided.
774 */
775 ret = call_qop(q, buf_init, vb);
776 if (ret) {
777 dprintk(1, "qbuf: buffer initialization failed\n");
778 goto err;
779 }
780
781 /*
782 * Now that everything is in order, copy relevant information
783 * provided by userspace.
784 */
785 for (plane = 0; plane < vb->num_planes; ++plane)
786 vb->v4l2_planes[plane] = planes[plane];
787
788 return 0;
789err:
790 /* In case of errors, release planes that were already acquired */
791 for (; plane > 0; --plane) {
792 call_memop(q, plane, put_userptr,
793 vb->planes[plane - 1].mem_priv);
794 vb->planes[plane - 1].mem_priv = NULL;
795 }
796
797 return ret;
798}
799
800/**
801 * __qbuf_mmap() - handle qbuf of an MMAP buffer
802 */
803static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b)
804{
805 return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
806}
807
808/**
809 * __enqueue_in_driver() - enqueue a vb2_buffer in driver for processing
810 */
811static void __enqueue_in_driver(struct vb2_buffer *vb)
812{
813 struct vb2_queue *q = vb->vb2_queue;
814
815 vb->state = VB2_BUF_STATE_ACTIVE;
816 atomic_inc(&q->queued_count);
817 q->ops->buf_queue(vb);
818}
819
820/**
821 * vb2_qbuf() - Queue a buffer from userspace
822 * @q: videobuf2 queue
823 * @b: buffer structure passed from userspace to vidioc_qbuf handler
824 * in driver
825 *
826 * Should be called from vidioc_qbuf ioctl handler of a driver.
827 * This function:
828 * 1) verifies the passed buffer,
829 * 2) calls buf_prepare callback in the driver (if provided), in which
830 * driver-specific buffer initialization can be performed,
831 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
832 * callback for processing.
833 *
834 * The return values from this function are intended to be directly returned
835 * from vidioc_qbuf handler in driver.
836 */
837int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
838{
839 struct vb2_buffer *vb;
840 int ret = 0;
841
842 if (q->fileio) {
843 dprintk(1, "qbuf: file io in progress\n");
844 return -EBUSY;
845 }
846
847 if (b->type != q->type) {
848 dprintk(1, "qbuf: invalid buffer type\n");
849 return -EINVAL;
850 }
851
852 if (b->index >= q->num_buffers) {
853 dprintk(1, "qbuf: buffer index out of range\n");
854 return -EINVAL;
855 }
856
857 vb = q->bufs[b->index];
858 if (NULL == vb) {
859 /* Should never happen */
860 dprintk(1, "qbuf: buffer is NULL\n");
861 return -EINVAL;
862 }
863
864 if (b->memory != q->memory) {
865 dprintk(1, "qbuf: invalid memory type\n");
866 return -EINVAL;
867 }
868
869 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
870 dprintk(1, "qbuf: buffer already in use\n");
871 return -EINVAL;
872 }
873
874 if (q->memory == V4L2_MEMORY_MMAP)
875 ret = __qbuf_mmap(vb, b);
876 else if (q->memory == V4L2_MEMORY_USERPTR)
877 ret = __qbuf_userptr(vb, b);
878 else {
879 WARN(1, "Invalid queue type\n");
880 return -EINVAL;
881 }
882
883 if (ret)
884 return ret;
885
886 ret = call_qop(q, buf_prepare, vb);
887 if (ret) {
888 dprintk(1, "qbuf: buffer preparation failed\n");
889 return ret;
890 }
891
892 /*
893 * Add to the queued buffers list, a buffer will stay on it until
894 * dequeued in dqbuf.
895 */
896 list_add_tail(&vb->queued_entry, &q->queued_list);
897 vb->state = VB2_BUF_STATE_QUEUED;
898
899 /*
900 * If already streaming, give the buffer to driver for processing.
901 * If not, the buffer will be given to driver on next streamon.
902 */
903 if (q->streaming)
904 __enqueue_in_driver(vb);
905
906 dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
907 return 0;
908}
909EXPORT_SYMBOL_GPL(vb2_qbuf);
910
911/**
912 * __vb2_wait_for_done_vb() - wait for a buffer to become available
913 * for dequeuing
914 *
915 * Will sleep if required for nonblocking == false.
916 */
917static int __vb2_wait_for_done_vb(struct vb2_queue *q, int nonblocking)
918{
919 /*
920 * All operations on vb_done_list are performed under done_lock
921 * spinlock protection. However, buffers may be removed from
922 * it and returned to userspace only while holding both driver's
923 * lock and the done_lock spinlock. Thus we can be sure that as
924 * long as we hold the driver's lock, the list will remain not
925 * empty if list_empty() check succeeds.
926 */
927
928 for (;;) {
929 int ret;
930
931 if (!q->streaming) {
932 dprintk(1, "Streaming off, will not wait for buffers\n");
933 return -EINVAL;
934 }
935
936 if (!list_empty(&q->done_list)) {
937 /*
938 * Found a buffer that we were waiting for.
939 */
940 break;
941 }
942
943 if (nonblocking) {
944 dprintk(1, "Nonblocking and no buffers to dequeue, "
945 "will not wait\n");
946 return -EAGAIN;
947 }
948
949 /*
950 * We are streaming and blocking, wait for another buffer to
951 * become ready or for streamoff. Driver's lock is released to
952 * allow streamoff or qbuf to be called while waiting.
953 */
954 call_qop(q, wait_prepare, q);
955
956 /*
957 * All locks have been released, it is safe to sleep now.
958 */
959 dprintk(3, "Will sleep waiting for buffers\n");
960 ret = wait_event_interruptible(q->done_wq,
961 !list_empty(&q->done_list) || !q->streaming);
962
963 /*
964 * We need to reevaluate both conditions again after reacquiring
965 * the locks or return an error if one occurred.
966 */
967 call_qop(q, wait_finish, q);
968 if (ret)
969 return ret;
970 }
971 return 0;
972}
973
974/**
975 * __vb2_get_done_vb() - get a buffer ready for dequeuing
976 *
977 * Will sleep if required for nonblocking == false.
978 */
979static int __vb2_get_done_vb(struct vb2_queue *q, struct vb2_buffer **vb,
980 int nonblocking)
981{
982 unsigned long flags;
983 int ret;
984
985 /*
986 * Wait for at least one buffer to become available on the done_list.
987 */
988 ret = __vb2_wait_for_done_vb(q, nonblocking);
989 if (ret)
990 return ret;
991
992 /*
993 * Driver's lock has been held since we last verified that done_list
994 * is not empty, so no need for another list_empty(done_list) check.
995 */
996 spin_lock_irqsave(&q->done_lock, flags);
997 *vb = list_first_entry(&q->done_list, struct vb2_buffer, done_entry);
998 list_del(&(*vb)->done_entry);
999 spin_unlock_irqrestore(&q->done_lock, flags);
1000
1001 return 0;
1002}
1003
1004/**
1005 * vb2_wait_for_all_buffers() - wait until all buffers are given back to vb2
1006 * @q: videobuf2 queue
1007 *
1008 * This function will wait until all buffers that have been given to the driver
1009 * by buf_queue() are given back to vb2 with vb2_buffer_done(). It doesn't call
1010 * wait_prepare, wait_finish pair. It is intended to be called with all locks
1011 * taken, for example from stop_streaming() callback.
1012 */
1013int vb2_wait_for_all_buffers(struct vb2_queue *q)
1014{
1015 if (!q->streaming) {
1016 dprintk(1, "Streaming off, will not wait for buffers\n");
1017 return -EINVAL;
1018 }
1019
1020 wait_event(q->done_wq, !atomic_read(&q->queued_count));
1021 return 0;
1022}
1023EXPORT_SYMBOL_GPL(vb2_wait_for_all_buffers);
1024
1025/**
1026 * vb2_dqbuf() - Dequeue a buffer to the userspace
1027 * @q: videobuf2 queue
1028 * @b: buffer structure passed from userspace to vidioc_dqbuf handler
1029 * in driver
1030 * @nonblocking: if true, this call will not sleep waiting for a buffer if no
1031 * buffers ready for dequeuing are present. Normally the driver
1032 * would be passing (file->f_flags & O_NONBLOCK) here
1033 *
1034 * Should be called from vidioc_dqbuf ioctl handler of a driver.
1035 * This function:
1036 * 1) verifies the passed buffer,
1037 * 2) calls buf_finish callback in the driver (if provided), in which
1038 * driver can perform any additional operations that may be required before
1039 * returning the buffer to userspace, such as cache sync,
1040 * 3) the buffer struct members are filled with relevant information for
1041 * the userspace.
1042 *
1043 * The return values from this function are intended to be directly returned
1044 * from vidioc_dqbuf handler in driver.
1045 */
1046int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking)
1047{
1048 struct vb2_buffer *vb = NULL;
1049 int ret;
1050
1051 if (q->fileio) {
1052 dprintk(1, "dqbuf: file io in progress\n");
1053 return -EBUSY;
1054 }
1055
1056 if (b->type != q->type) {
1057 dprintk(1, "dqbuf: invalid buffer type\n");
1058 return -EINVAL;
1059 }
1060
1061 ret = __vb2_get_done_vb(q, &vb, nonblocking);
1062 if (ret < 0) {
1063 dprintk(1, "dqbuf: error getting next done buffer\n");
1064 return ret;
1065 }
1066
1067 ret = call_qop(q, buf_finish, vb);
1068 if (ret) {
1069 dprintk(1, "dqbuf: buffer finish failed\n");
1070 return ret;
1071 }
1072
1073 switch (vb->state) {
1074 case VB2_BUF_STATE_DONE:
1075 dprintk(3, "dqbuf: Returning done buffer\n");
1076 break;
1077 case VB2_BUF_STATE_ERROR:
1078 dprintk(3, "dqbuf: Returning done buffer with errors\n");
1079 break;
1080 default:
1081 dprintk(1, "dqbuf: Invalid buffer state\n");
1082 return -EINVAL;
1083 }
1084
1085 /* Fill buffer information for the userspace */
1086 __fill_v4l2_buffer(vb, b);
1087 /* Remove from videobuf queue */
1088 list_del(&vb->queued_entry);
1089
1090 dprintk(1, "dqbuf of buffer %d, with state %d\n",
1091 vb->v4l2_buf.index, vb->state);
1092
1093 vb->state = VB2_BUF_STATE_DEQUEUED;
1094 return 0;
1095}
1096EXPORT_SYMBOL_GPL(vb2_dqbuf);
1097
1098/**
1099 * vb2_streamon - start streaming
1100 * @q: videobuf2 queue
1101 * @type: type argument passed from userspace to vidioc_streamon handler
1102 *
1103 * Should be called from vidioc_streamon handler of a driver.
1104 * This function:
1105 * 1) verifies current state
1106 * 2) starts streaming and passes any previously queued buffers to the driver
1107 *
1108 * The return values from this function are intended to be directly returned
1109 * from vidioc_streamon handler in the driver.
1110 */
1111int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type)
1112{
1113 struct vb2_buffer *vb;
1114 int ret;
1115
1116 if (q->fileio) {
1117 dprintk(1, "streamon: file io in progress\n");
1118 return -EBUSY;
1119 }
1120
1121 if (type != q->type) {
1122 dprintk(1, "streamon: invalid stream type\n");
1123 return -EINVAL;
1124 }
1125
1126 if (q->streaming) {
1127 dprintk(1, "streamon: already streaming\n");
1128 return -EBUSY;
1129 }
1130
1131 /*
1132 * Cannot start streaming on an OUTPUT device if no buffers have
1133 * been queued yet.
1134 */
1135 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1136 if (list_empty(&q->queued_list)) {
1137 dprintk(1, "streamon: no output buffers queued\n");
1138 return -EINVAL;
1139 }
1140 }
1141
1142 /*
1143 * Let driver notice that streaming state has been enabled.
1144 */
1145 ret = call_qop(q, start_streaming, q);
1146 if (ret) {
1147 dprintk(1, "streamon: driver refused to start streaming\n");
1148 return ret;
1149 }
1150
1151 q->streaming = 1;
1152
1153 /*
1154 * If any buffers were queued before streamon,
1155 * we can now pass them to driver for processing.
1156 */
1157 list_for_each_entry(vb, &q->queued_list, queued_entry)
1158 __enqueue_in_driver(vb);
1159
1160 dprintk(3, "Streamon successful\n");
1161 return 0;
1162}
1163EXPORT_SYMBOL_GPL(vb2_streamon);
1164
1165/**
1166 * __vb2_queue_cancel() - cancel and stop (pause) streaming
1167 *
1168 * Removes all queued buffers from driver's queue and all buffers queued by
1169 * userspace from videobuf's queue. Returns to state after reqbufs.
1170 */
1171static void __vb2_queue_cancel(struct vb2_queue *q)
1172{
1173 unsigned int i;
1174
1175 /*
1176 * Tell driver to stop all transactions and release all queued
1177 * buffers.
1178 */
1179 if (q->streaming)
1180 call_qop(q, stop_streaming, q);
1181 q->streaming = 0;
1182
1183 /*
1184 * Remove all buffers from videobuf's list...
1185 */
1186 INIT_LIST_HEAD(&q->queued_list);
1187 /*
1188 * ...and done list; userspace will not receive any buffers it
1189 * has not already dequeued before initiating cancel.
1190 */
1191 INIT_LIST_HEAD(&q->done_list);
1192 wake_up_all(&q->done_wq);
1193
1194 /*
1195 * Reinitialize all buffers for next use.
1196 */
1197 for (i = 0; i < q->num_buffers; ++i)
1198 q->bufs[i]->state = VB2_BUF_STATE_DEQUEUED;
1199}
1200
1201/**
1202 * vb2_streamoff - stop streaming
1203 * @q: videobuf2 queue
1204 * @type: type argument passed from userspace to vidioc_streamoff handler
1205 *
1206 * Should be called from vidioc_streamoff handler of a driver.
1207 * This function:
1208 * 1) verifies current state,
1209 * 2) stop streaming and dequeues any queued buffers, including those previously
1210 * passed to the driver (after waiting for the driver to finish).
1211 *
1212 * This call can be used for pausing playback.
1213 * The return values from this function are intended to be directly returned
1214 * from vidioc_streamoff handler in the driver
1215 */
1216int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type)
1217{
1218 if (q->fileio) {
1219 dprintk(1, "streamoff: file io in progress\n");
1220 return -EBUSY;
1221 }
1222
1223 if (type != q->type) {
1224 dprintk(1, "streamoff: invalid stream type\n");
1225 return -EINVAL;
1226 }
1227
1228 if (!q->streaming) {
1229 dprintk(1, "streamoff: not streaming\n");
1230 return -EINVAL;
1231 }
1232
1233 /*
1234 * Cancel will pause streaming and remove all buffers from the driver
1235 * and videobuf, effectively returning control over them to userspace.
1236 */
1237 __vb2_queue_cancel(q);
1238
1239 dprintk(3, "Streamoff successful\n");
1240 return 0;
1241}
1242EXPORT_SYMBOL_GPL(vb2_streamoff);
1243
1244/**
1245 * __find_plane_by_offset() - find plane associated with the given offset off
1246 */
1247static int __find_plane_by_offset(struct vb2_queue *q, unsigned long off,
1248 unsigned int *_buffer, unsigned int *_plane)
1249{
1250 struct vb2_buffer *vb;
1251 unsigned int buffer, plane;
1252
1253 /*
1254 * Go over all buffers and their planes, comparing the given offset
1255 * with an offset assigned to each plane. If a match is found,
1256 * return its buffer and plane numbers.
1257 */
1258 for (buffer = 0; buffer < q->num_buffers; ++buffer) {
1259 vb = q->bufs[buffer];
1260
1261 for (plane = 0; plane < vb->num_planes; ++plane) {
1262 if (vb->v4l2_planes[plane].m.mem_offset == off) {
1263 *_buffer = buffer;
1264 *_plane = plane;
1265 return 0;
1266 }
1267 }
1268 }
1269
1270 return -EINVAL;
1271}
1272
1273/**
1274 * vb2_mmap() - map video buffers into application address space
1275 * @q: videobuf2 queue
1276 * @vma: vma passed to the mmap file operation handler in the driver
1277 *
1278 * Should be called from mmap file operation handler of a driver.
1279 * This function maps one plane of one of the available video buffers to
1280 * userspace. To map whole video memory allocated on reqbufs, this function
1281 * has to be called once per each plane per each buffer previously allocated.
1282 *
1283 * When the userspace application calls mmap, it passes to it an offset returned
1284 * to it earlier by the means of vidioc_querybuf handler. That offset acts as
1285 * a "cookie", which is then used to identify the plane to be mapped.
1286 * This function finds a plane with a matching offset and a mapping is performed
1287 * by the means of a provided memory operation.
1288 *
1289 * The return values from this function are intended to be directly returned
1290 * from the mmap handler in driver.
1291 */
1292int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
1293{
1294 unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
1295 struct vb2_plane *vb_plane;
1296 struct vb2_buffer *vb;
1297 unsigned int buffer, plane;
1298 int ret;
1299
1300 if (q->memory != V4L2_MEMORY_MMAP) {
1301 dprintk(1, "Queue is not currently set up for mmap\n");
1302 return -EINVAL;
1303 }
1304
1305 /*
1306 * Check memory area access mode.
1307 */
1308 if (!(vma->vm_flags & VM_SHARED)) {
1309 dprintk(1, "Invalid vma flags, VM_SHARED needed\n");
1310 return -EINVAL;
1311 }
1312 if (V4L2_TYPE_IS_OUTPUT(q->type)) {
1313 if (!(vma->vm_flags & VM_WRITE)) {
1314 dprintk(1, "Invalid vma flags, VM_WRITE needed\n");
1315 return -EINVAL;
1316 }
1317 } else {
1318 if (!(vma->vm_flags & VM_READ)) {
1319 dprintk(1, "Invalid vma flags, VM_READ needed\n");
1320 return -EINVAL;
1321 }
1322 }
1323
1324 /*
1325 * Find the plane corresponding to the offset passed by userspace.
1326 */
1327 ret = __find_plane_by_offset(q, off, &buffer, &plane);
1328 if (ret)
1329 return ret;
1330
1331 vb = q->bufs[buffer];
1332 vb_plane = &vb->planes[plane];
1333
1334 ret = q->mem_ops->mmap(vb_plane->mem_priv, vma);
1335 if (ret)
1336 return ret;
1337
1338 vb_plane->mapped = 1;
1339 vb->num_planes_mapped++;
1340
1341 dprintk(3, "Buffer %d, plane %d successfully mapped\n", buffer, plane);
1342 return 0;
1343}
1344EXPORT_SYMBOL_GPL(vb2_mmap);
1345
1346static int __vb2_init_fileio(struct vb2_queue *q, int read);
1347static int __vb2_cleanup_fileio(struct vb2_queue *q);
1348
1349/**
1350 * vb2_poll() - implements poll userspace operation
1351 * @q: videobuf2 queue
1352 * @file: file argument passed to the poll file operation handler
1353 * @wait: wait argument passed to the poll file operation handler
1354 *
1355 * This function implements poll file operation handler for a driver.
1356 * For CAPTURE queues, if a buffer is ready to be dequeued, the userspace will
1357 * be informed that the file descriptor of a video device is available for
1358 * reading.
1359 * For OUTPUT queues, if a buffer is ready to be dequeued, the file descriptor
1360 * will be reported as available for writing.
1361 *
1362 * The return values from this function are intended to be directly returned
1363 * from poll handler in driver.
1364 */
1365unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait)
1366{
1367 unsigned long flags;
1368 unsigned int ret;
1369 struct vb2_buffer *vb = NULL;
1370
1371 /*
1372 * Start file I/O emulator only if streaming API has not been used yet.
1373 */
1374 if (q->num_buffers == 0 && q->fileio == NULL) {
1375 if (!V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_READ)) {
1376 ret = __vb2_init_fileio(q, 1);
1377 if (ret)
1378 return POLLERR;
1379 }
1380 if (V4L2_TYPE_IS_OUTPUT(q->type) && (q->io_modes & VB2_WRITE)) {
1381 ret = __vb2_init_fileio(q, 0);
1382 if (ret)
1383 return POLLERR;
1384 /*
1385 * Write to OUTPUT queue can be done immediately.
1386 */
1387 return POLLOUT | POLLWRNORM;
1388 }
1389 }
1390
1391 /*
1392 * There is nothing to wait for if no buffers have already been queued.
1393 */
1394 if (list_empty(&q->queued_list))
1395 return POLLERR;
1396
1397 poll_wait(file, &q->done_wq, wait);
1398
1399 /*
1400 * Take first buffer available for dequeuing.
1401 */
1402 spin_lock_irqsave(&q->done_lock, flags);
1403 if (!list_empty(&q->done_list))
1404 vb = list_first_entry(&q->done_list, struct vb2_buffer,
1405 done_entry);
1406 spin_unlock_irqrestore(&q->done_lock, flags);
1407
1408 if (vb && (vb->state == VB2_BUF_STATE_DONE
1409 || vb->state == VB2_BUF_STATE_ERROR)) {
1410 return (V4L2_TYPE_IS_OUTPUT(q->type)) ? POLLOUT | POLLWRNORM :
1411 POLLIN | POLLRDNORM;
1412 }
1413 return 0;
1414}
1415EXPORT_SYMBOL_GPL(vb2_poll);
1416
1417/**
1418 * vb2_queue_init() - initialize a videobuf2 queue
1419 * @q: videobuf2 queue; this structure should be allocated in driver
1420 *
1421 * The vb2_queue structure should be allocated by the driver. The driver is
1422 * responsible of clearing it's content and setting initial values for some
1423 * required entries before calling this function.
1424 * q->ops, q->mem_ops, q->type and q->io_modes are mandatory. Please refer
1425 * to the struct vb2_queue description in include/media/videobuf2-core.h
1426 * for more information.
1427 */
1428int vb2_queue_init(struct vb2_queue *q)
1429{
1430 BUG_ON(!q);
1431 BUG_ON(!q->ops);
1432 BUG_ON(!q->mem_ops);
1433 BUG_ON(!q->type);
1434 BUG_ON(!q->io_modes);
1435
1436 BUG_ON(!q->ops->queue_setup);
1437 BUG_ON(!q->ops->buf_queue);
1438
1439 INIT_LIST_HEAD(&q->queued_list);
1440 INIT_LIST_HEAD(&q->done_list);
1441 spin_lock_init(&q->done_lock);
1442 init_waitqueue_head(&q->done_wq);
1443
1444 if (q->buf_struct_size == 0)
1445 q->buf_struct_size = sizeof(struct vb2_buffer);
1446
1447 return 0;
1448}
1449EXPORT_SYMBOL_GPL(vb2_queue_init);
1450
1451/**
1452 * vb2_queue_release() - stop streaming, release the queue and free memory
1453 * @q: videobuf2 queue
1454 *
1455 * This function stops streaming and performs necessary clean ups, including
1456 * freeing video buffer memory. The driver is responsible for freeing
1457 * the vb2_queue structure itself.
1458 */
1459void vb2_queue_release(struct vb2_queue *q)
1460{
1461 __vb2_cleanup_fileio(q);
1462 __vb2_queue_cancel(q);
1463 __vb2_queue_free(q);
1464}
1465EXPORT_SYMBOL_GPL(vb2_queue_release);
1466
1467/**
1468 * struct vb2_fileio_buf - buffer context used by file io emulator
1469 *
1470 * vb2 provides a compatibility layer and emulator of file io (read and
1471 * write) calls on top of streaming API. This structure is used for
1472 * tracking context related to the buffers.
1473 */
1474struct vb2_fileio_buf {
1475 void *vaddr;
1476 unsigned int size;
1477 unsigned int pos;
1478 unsigned int queued:1;
1479};
1480
1481/**
1482 * struct vb2_fileio_data - queue context used by file io emulator
1483 *
1484 * vb2 provides a compatibility layer and emulator of file io (read and
1485 * write) calls on top of streaming API. For proper operation it required
1486 * this structure to save the driver state between each call of the read
1487 * or write function.
1488 */
1489struct vb2_fileio_data {
1490 struct v4l2_requestbuffers req;
1491 struct v4l2_buffer b;
1492 struct vb2_fileio_buf bufs[VIDEO_MAX_FRAME];
1493 unsigned int index;
1494 unsigned int q_count;
1495 unsigned int dq_count;
1496 unsigned int flags;
1497};
1498
1499/**
1500 * __vb2_init_fileio() - initialize file io emulator
1501 * @q: videobuf2 queue
1502 * @read: mode selector (1 means read, 0 means write)
1503 */
1504static int __vb2_init_fileio(struct vb2_queue *q, int read)
1505{
1506 struct vb2_fileio_data *fileio;
1507 int i, ret;
1508 unsigned int count = 0;
1509
1510 /*
1511 * Sanity check
1512 */
1513 if ((read && !(q->io_modes & VB2_READ)) ||
1514 (!read && !(q->io_modes & VB2_WRITE)))
1515 BUG();
1516
1517 /*
1518 * Check if device supports mapping buffers to kernel virtual space.
1519 */
1520 if (!q->mem_ops->vaddr)
1521 return -EBUSY;
1522
1523 /*
1524 * Check if streaming api has not been already activated.
1525 */
1526 if (q->streaming || q->num_buffers > 0)
1527 return -EBUSY;
1528
1529 /*
1530 * Start with count 1, driver can increase it in queue_setup()
1531 */
1532 count = 1;
1533
1534 dprintk(3, "setting up file io: mode %s, count %d, flags %08x\n",
1535 (read) ? "read" : "write", count, q->io_flags);
1536
1537 fileio = kzalloc(sizeof(struct vb2_fileio_data), GFP_KERNEL);
1538 if (fileio == NULL)
1539 return -ENOMEM;
1540
1541 fileio->flags = q->io_flags;
1542
1543 /*
1544 * Request buffers and use MMAP type to force driver
1545 * to allocate buffers by itself.
1546 */
1547 fileio->req.count = count;
1548 fileio->req.memory = V4L2_MEMORY_MMAP;
1549 fileio->req.type = q->type;
1550 ret = vb2_reqbufs(q, &fileio->req);
1551 if (ret)
1552 goto err_kfree;
1553
1554 /*
1555 * Check if plane_count is correct
1556 * (multiplane buffers are not supported).
1557 */
1558 if (q->bufs[0]->num_planes != 1) {
1559 fileio->req.count = 0;
1560 ret = -EBUSY;
1561 goto err_reqbufs;
1562 }
1563
1564 /*
1565 * Get kernel address of each buffer.
1566 */
1567 for (i = 0; i < q->num_buffers; i++) {
1568 fileio->bufs[i].vaddr = vb2_plane_vaddr(q->bufs[i], 0);
1569 if (fileio->bufs[i].vaddr == NULL)
1570 goto err_reqbufs;
1571 fileio->bufs[i].size = vb2_plane_size(q->bufs[i], 0);
1572 }
1573
1574 /*
1575 * Read mode requires pre queuing of all buffers.
1576 */
1577 if (read) {
1578 /*
1579 * Queue all buffers.
1580 */
1581 for (i = 0; i < q->num_buffers; i++) {
1582 struct v4l2_buffer *b = &fileio->b;
1583 memset(b, 0, sizeof(*b));
1584 b->type = q->type;
1585 b->memory = q->memory;
1586 b->index = i;
1587 ret = vb2_qbuf(q, b);
1588 if (ret)
1589 goto err_reqbufs;
1590 fileio->bufs[i].queued = 1;
1591 }
1592
1593 /*
1594 * Start streaming.
1595 */
1596 ret = vb2_streamon(q, q->type);
1597 if (ret)
1598 goto err_reqbufs;
1599 }
1600
1601 q->fileio = fileio;
1602
1603 return ret;
1604
1605err_reqbufs:
1606 vb2_reqbufs(q, &fileio->req);
1607
1608err_kfree:
1609 kfree(fileio);
1610 return ret;
1611}
1612
1613/**
1614 * __vb2_cleanup_fileio() - free resourced used by file io emulator
1615 * @q: videobuf2 queue
1616 */
1617static int __vb2_cleanup_fileio(struct vb2_queue *q)
1618{
1619 struct vb2_fileio_data *fileio = q->fileio;
1620
1621 if (fileio) {
1622 /*
1623 * Hack fileio context to enable direct calls to vb2 ioctl
1624 * interface.
1625 */
1626 q->fileio = NULL;
1627
1628 vb2_streamoff(q, q->type);
1629 fileio->req.count = 0;
1630 vb2_reqbufs(q, &fileio->req);
1631 kfree(fileio);
1632 dprintk(3, "file io emulator closed\n");
1633 }
1634 return 0;
1635}
1636
1637/**
1638 * __vb2_perform_fileio() - perform a single file io (read or write) operation
1639 * @q: videobuf2 queue
1640 * @data: pointed to target userspace buffer
1641 * @count: number of bytes to read or write
1642 * @ppos: file handle position tracking pointer
1643 * @nonblock: mode selector (1 means blocking calls, 0 means nonblocking)
1644 * @read: access mode selector (1 means read, 0 means write)
1645 */
1646static size_t __vb2_perform_fileio(struct vb2_queue *q, char __user *data, size_t count,
1647 loff_t *ppos, int nonblock, int read)
1648{
1649 struct vb2_fileio_data *fileio;
1650 struct vb2_fileio_buf *buf;
1651 int ret, index;
1652
1653 dprintk(3, "file io: mode %s, offset %ld, count %zd, %sblocking\n",
1654 read ? "read" : "write", (long)*ppos, count,
1655 nonblock ? "non" : "");
1656
1657 if (!data)
1658 return -EINVAL;
1659
1660 /*
1661 * Initialize emulator on first call.
1662 */
1663 if (!q->fileio) {
1664 ret = __vb2_init_fileio(q, read);
1665 dprintk(3, "file io: vb2_init_fileio result: %d\n", ret);
1666 if (ret)
1667 return ret;
1668 }
1669 fileio = q->fileio;
1670
1671 /*
1672 * Hack fileio context to enable direct calls to vb2 ioctl interface.
1673 * The pointer will be restored before returning from this function.
1674 */
1675 q->fileio = NULL;
1676
1677 index = fileio->index;
1678 buf = &fileio->bufs[index];
1679
1680 /*
1681 * Check if we need to dequeue the buffer.
1682 */
1683 if (buf->queued) {
1684 struct vb2_buffer *vb;
1685
1686 /*
1687 * Call vb2_dqbuf to get buffer back.
1688 */
1689 memset(&fileio->b, 0, sizeof(fileio->b));
1690 fileio->b.type = q->type;
1691 fileio->b.memory = q->memory;
1692 fileio->b.index = index;
1693 ret = vb2_dqbuf(q, &fileio->b, nonblock);
1694 dprintk(5, "file io: vb2_dqbuf result: %d\n", ret);
1695 if (ret)
1696 goto end;
1697 fileio->dq_count += 1;
1698
1699 /*
1700 * Get number of bytes filled by the driver
1701 */
1702 vb = q->bufs[index];
1703 buf->size = vb2_get_plane_payload(vb, 0);
1704 buf->queued = 0;
1705 }
1706
1707 /*
1708 * Limit count on last few bytes of the buffer.
1709 */
1710 if (buf->pos + count > buf->size) {
1711 count = buf->size - buf->pos;
1712 dprintk(5, "reducing read count: %zd\n", count);
1713 }
1714
1715 /*
1716 * Transfer data to userspace.
1717 */
1718 dprintk(3, "file io: copying %zd bytes - buffer %d, offset %u\n",
1719 count, index, buf->pos);
1720 if (read)
1721 ret = copy_to_user(data, buf->vaddr + buf->pos, count);
1722 else
1723 ret = copy_from_user(buf->vaddr + buf->pos, data, count);
1724 if (ret) {
1725 dprintk(3, "file io: error copying data\n");
1726 ret = -EFAULT;
1727 goto end;
1728 }
1729
1730 /*
1731 * Update counters.
1732 */
1733 buf->pos += count;
1734 *ppos += count;
1735
1736 /*
1737 * Queue next buffer if required.
1738 */
1739 if (buf->pos == buf->size ||
1740 (!read && (fileio->flags & VB2_FILEIO_WRITE_IMMEDIATELY))) {
1741 /*
1742 * Check if this is the last buffer to read.
1743 */
1744 if (read && (fileio->flags & VB2_FILEIO_READ_ONCE) &&
1745 fileio->dq_count == 1) {
1746 dprintk(3, "file io: read limit reached\n");
1747 /*
1748 * Restore fileio pointer and release the context.
1749 */
1750 q->fileio = fileio;
1751 return __vb2_cleanup_fileio(q);
1752 }
1753
1754 /*
1755 * Call vb2_qbuf and give buffer to the driver.
1756 */
1757 memset(&fileio->b, 0, sizeof(fileio->b));
1758 fileio->b.type = q->type;
1759 fileio->b.memory = q->memory;
1760 fileio->b.index = index;
1761 fileio->b.bytesused = buf->pos;
1762 ret = vb2_qbuf(q, &fileio->b);
1763 dprintk(5, "file io: vb2_dbuf result: %d\n", ret);
1764 if (ret)
1765 goto end;
1766
1767 /*
1768 * Buffer has been queued, update the status
1769 */
1770 buf->pos = 0;
1771 buf->queued = 1;
1772 buf->size = q->bufs[0]->v4l2_planes[0].length;
1773 fileio->q_count += 1;
1774
1775 /*
1776 * Switch to the next buffer
1777 */
1778 fileio->index = (index + 1) % q->num_buffers;
1779
1780 /*
1781 * Start streaming if required.
1782 */
1783 if (!read && !q->streaming) {
1784 ret = vb2_streamon(q, q->type);
1785 if (ret)
1786 goto end;
1787 }
1788 }
1789
1790 /*
1791 * Return proper number of bytes processed.
1792 */
1793 if (ret == 0)
1794 ret = count;
1795end:
1796 /*
1797 * Restore the fileio context and block vb2 ioctl interface.
1798 */
1799 q->fileio = fileio;
1800 return ret;
1801}
1802
1803size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
1804 loff_t *ppos, int nonblocking)
1805{
1806 return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 1);
1807}
1808EXPORT_SYMBOL_GPL(vb2_read);
1809
1810size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
1811 loff_t *ppos, int nonblocking)
1812{
1813 return __vb2_perform_fileio(q, data, count, ppos, nonblocking, 0);
1814}
1815EXPORT_SYMBOL_GPL(vb2_write);
1816
1817MODULE_DESCRIPTION("Driver helper framework for Video for Linux 2");
1818MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>, Marek Szyprowski");
1819MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-dma-contig.c b/drivers/media/video/videobuf2-dma-contig.c
new file mode 100644
index 000000000000..58205d596138
--- /dev/null
+++ b/drivers/media/video/videobuf2-dma-contig.c
@@ -0,0 +1,185 @@
1/*
2 * videobuf2-dma-contig.c - DMA contig memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
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.
11 */
12
13#include <linux/module.h>
14#include <linux/slab.h>
15#include <linux/dma-mapping.h>
16
17#include <media/videobuf2-core.h>
18#include <media/videobuf2-memops.h>
19
20struct vb2_dc_conf {
21 struct device *dev;
22};
23
24struct vb2_dc_buf {
25 struct vb2_dc_conf *conf;
26 void *vaddr;
27 dma_addr_t paddr;
28 unsigned long size;
29 struct vm_area_struct *vma;
30 atomic_t refcount;
31 struct vb2_vmarea_handler handler;
32};
33
34static void vb2_dma_contig_put(void *buf_priv);
35
36static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
37{
38 struct vb2_dc_conf *conf = alloc_ctx;
39 struct vb2_dc_buf *buf;
40
41 buf = kzalloc(sizeof *buf, GFP_KERNEL);
42 if (!buf)
43 return ERR_PTR(-ENOMEM);
44
45 buf->vaddr = dma_alloc_coherent(conf->dev, size, &buf->paddr,
46 GFP_KERNEL);
47 if (!buf->vaddr) {
48 dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
49 buf->size);
50 kfree(buf);
51 return ERR_PTR(-ENOMEM);
52 }
53
54 buf->conf = conf;
55 buf->size = size;
56
57 buf->handler.refcount = &buf->refcount;
58 buf->handler.put = vb2_dma_contig_put;
59 buf->handler.arg = buf;
60
61 atomic_inc(&buf->refcount);
62
63 return buf;
64}
65
66static void vb2_dma_contig_put(void *buf_priv)
67{
68 struct vb2_dc_buf *buf = buf_priv;
69
70 if (atomic_dec_and_test(&buf->refcount)) {
71 dma_free_coherent(buf->conf->dev, buf->size, buf->vaddr,
72 buf->paddr);
73 kfree(buf);
74 }
75}
76
77static void *vb2_dma_contig_cookie(void *buf_priv)
78{
79 struct vb2_dc_buf *buf = buf_priv;
80
81 return &buf->paddr;
82}
83
84static void *vb2_dma_contig_vaddr(void *buf_priv)
85{
86 struct vb2_dc_buf *buf = buf_priv;
87 if (!buf)
88 return 0;
89
90 return buf->vaddr;
91}
92
93static unsigned int vb2_dma_contig_num_users(void *buf_priv)
94{
95 struct vb2_dc_buf *buf = buf_priv;
96
97 return atomic_read(&buf->refcount);
98}
99
100static int vb2_dma_contig_mmap(void *buf_priv, struct vm_area_struct *vma)
101{
102 struct vb2_dc_buf *buf = buf_priv;
103
104 if (!buf) {
105 printk(KERN_ERR "No buffer to map\n");
106 return -EINVAL;
107 }
108
109 return vb2_mmap_pfn_range(vma, buf->paddr, buf->size,
110 &vb2_common_vm_ops, &buf->handler);
111}
112
113static void *vb2_dma_contig_get_userptr(void *alloc_ctx, unsigned long vaddr,
114 unsigned long size, int write)
115{
116 struct vb2_dc_buf *buf;
117 struct vm_area_struct *vma;
118 dma_addr_t paddr = 0;
119 int ret;
120
121 buf = kzalloc(sizeof *buf, GFP_KERNEL);
122 if (!buf)
123 return ERR_PTR(-ENOMEM);
124
125 ret = vb2_get_contig_userptr(vaddr, size, &vma, &paddr);
126 if (ret) {
127 printk(KERN_ERR "Failed acquiring VMA for vaddr 0x%08lx\n",
128 vaddr);
129 kfree(buf);
130 return ERR_PTR(ret);
131 }
132
133 buf->size = size;
134 buf->paddr = paddr;
135 buf->vma = vma;
136
137 return buf;
138}
139
140static void vb2_dma_contig_put_userptr(void *mem_priv)
141{
142 struct vb2_dc_buf *buf = mem_priv;
143
144 if (!buf)
145 return;
146
147 vb2_put_vma(buf->vma);
148 kfree(buf);
149}
150
151const struct vb2_mem_ops vb2_dma_contig_memops = {
152 .alloc = vb2_dma_contig_alloc,
153 .put = vb2_dma_contig_put,
154 .cookie = vb2_dma_contig_cookie,
155 .vaddr = vb2_dma_contig_vaddr,
156 .mmap = vb2_dma_contig_mmap,
157 .get_userptr = vb2_dma_contig_get_userptr,
158 .put_userptr = vb2_dma_contig_put_userptr,
159 .num_users = vb2_dma_contig_num_users,
160};
161EXPORT_SYMBOL_GPL(vb2_dma_contig_memops);
162
163void *vb2_dma_contig_init_ctx(struct device *dev)
164{
165 struct vb2_dc_conf *conf;
166
167 conf = kzalloc(sizeof *conf, GFP_KERNEL);
168 if (!conf)
169 return ERR_PTR(-ENOMEM);
170
171 conf->dev = dev;
172
173 return conf;
174}
175EXPORT_SYMBOL_GPL(vb2_dma_contig_init_ctx);
176
177void vb2_dma_contig_cleanup_ctx(void *alloc_ctx)
178{
179 kfree(alloc_ctx);
180}
181EXPORT_SYMBOL_GPL(vb2_dma_contig_cleanup_ctx);
182
183MODULE_DESCRIPTION("DMA-contig memory handling routines for videobuf2");
184MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
185MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-dma-sg.c b/drivers/media/video/videobuf2-dma-sg.c
new file mode 100644
index 000000000000..b2d9485aac75
--- /dev/null
+++ b/drivers/media/video/videobuf2-dma-sg.c
@@ -0,0 +1,294 @@
1/*
2 * videobuf2-dma-sg.c - dma scatter/gather memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
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.
11 */
12
13#include <linux/module.h>
14#include <linux/mm.h>
15#include <linux/scatterlist.h>
16#include <linux/sched.h>
17#include <linux/slab.h>
18#include <linux/vmalloc.h>
19
20#include <media/videobuf2-core.h>
21#include <media/videobuf2-memops.h>
22#include <media/videobuf2-dma-sg.h>
23
24struct vb2_dma_sg_buf {
25 void *vaddr;
26 struct page **pages;
27 int write;
28 int offset;
29 struct vb2_dma_sg_desc sg_desc;
30 atomic_t refcount;
31 struct vb2_vmarea_handler handler;
32};
33
34static void vb2_dma_sg_put(void *buf_priv);
35
36static void *vb2_dma_sg_alloc(void *alloc_ctx, unsigned long size)
37{
38 struct vb2_dma_sg_buf *buf;
39 int i;
40
41 buf = kzalloc(sizeof *buf, GFP_KERNEL);
42 if (!buf)
43 return NULL;
44
45 buf->vaddr = NULL;
46 buf->write = 0;
47 buf->offset = 0;
48 buf->sg_desc.size = size;
49 buf->sg_desc.num_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
50
51 buf->sg_desc.sglist = vmalloc(buf->sg_desc.num_pages *
52 sizeof(*buf->sg_desc.sglist));
53 if (!buf->sg_desc.sglist)
54 goto fail_sglist_alloc;
55 memset(buf->sg_desc.sglist, 0, buf->sg_desc.num_pages *
56 sizeof(*buf->sg_desc.sglist));
57 sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
58
59 buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
60 GFP_KERNEL);
61 if (!buf->pages)
62 goto fail_pages_array_alloc;
63
64 for (i = 0; i < buf->sg_desc.num_pages; ++i) {
65 buf->pages[i] = alloc_page(GFP_KERNEL | __GFP_ZERO);
66 if (NULL == buf->pages[i])
67 goto fail_pages_alloc;
68 sg_set_page(&buf->sg_desc.sglist[i],
69 buf->pages[i], PAGE_SIZE, 0);
70 }
71
72 buf->handler.refcount = &buf->refcount;
73 buf->handler.put = vb2_dma_sg_put;
74 buf->handler.arg = buf;
75
76 atomic_inc(&buf->refcount);
77
78 printk(KERN_DEBUG "%s: Allocated buffer of %d pages\n",
79 __func__, buf->sg_desc.num_pages);
80
81 if (!buf->vaddr)
82 buf->vaddr = vm_map_ram(buf->pages,
83 buf->sg_desc.num_pages,
84 -1,
85 PAGE_KERNEL);
86 return buf;
87
88fail_pages_alloc:
89 while (--i >= 0)
90 __free_page(buf->pages[i]);
91 kfree(buf->pages);
92
93fail_pages_array_alloc:
94 vfree(buf->sg_desc.sglist);
95
96fail_sglist_alloc:
97 kfree(buf);
98 return NULL;
99}
100
101static void vb2_dma_sg_put(void *buf_priv)
102{
103 struct vb2_dma_sg_buf *buf = buf_priv;
104 int i = buf->sg_desc.num_pages;
105
106 if (atomic_dec_and_test(&buf->refcount)) {
107 printk(KERN_DEBUG "%s: Freeing buffer of %d pages\n", __func__,
108 buf->sg_desc.num_pages);
109 if (buf->vaddr)
110 vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages);
111 vfree(buf->sg_desc.sglist);
112 while (--i >= 0)
113 __free_page(buf->pages[i]);
114 kfree(buf->pages);
115 kfree(buf);
116 }
117}
118
119static void *vb2_dma_sg_get_userptr(void *alloc_ctx, unsigned long vaddr,
120 unsigned long size, int write)
121{
122 struct vb2_dma_sg_buf *buf;
123 unsigned long first, last;
124 int num_pages_from_user, i;
125
126 buf = kzalloc(sizeof *buf, GFP_KERNEL);
127 if (!buf)
128 return NULL;
129
130 buf->vaddr = NULL;
131 buf->write = write;
132 buf->offset = vaddr & ~PAGE_MASK;
133 buf->sg_desc.size = size;
134
135 first = (vaddr & PAGE_MASK) >> PAGE_SHIFT;
136 last = ((vaddr + size - 1) & PAGE_MASK) >> PAGE_SHIFT;
137 buf->sg_desc.num_pages = last - first + 1;
138
139 buf->sg_desc.sglist = vmalloc(
140 buf->sg_desc.num_pages * sizeof(*buf->sg_desc.sglist));
141 if (!buf->sg_desc.sglist)
142 goto userptr_fail_sglist_alloc;
143
144 memset(buf->sg_desc.sglist, 0,
145 buf->sg_desc.num_pages * sizeof(*buf->sg_desc.sglist));
146 sg_init_table(buf->sg_desc.sglist, buf->sg_desc.num_pages);
147
148 buf->pages = kzalloc(buf->sg_desc.num_pages * sizeof(struct page *),
149 GFP_KERNEL);
150 if (!buf->pages)
151 goto userptr_fail_pages_array_alloc;
152
153 down_read(&current->mm->mmap_sem);
154 num_pages_from_user = get_user_pages(current, current->mm,
155 vaddr & PAGE_MASK,
156 buf->sg_desc.num_pages,
157 write,
158 1, /* force */
159 buf->pages,
160 NULL);
161 up_read(&current->mm->mmap_sem);
162 if (num_pages_from_user != buf->sg_desc.num_pages)
163 goto userptr_fail_get_user_pages;
164
165 sg_set_page(&buf->sg_desc.sglist[0], buf->pages[0],
166 PAGE_SIZE - buf->offset, buf->offset);
167 size -= PAGE_SIZE - buf->offset;
168 for (i = 1; i < buf->sg_desc.num_pages; ++i) {
169 sg_set_page(&buf->sg_desc.sglist[i], buf->pages[i],
170 min_t(size_t, PAGE_SIZE, size), 0);
171 size -= min_t(size_t, PAGE_SIZE, size);
172 }
173 return buf;
174
175userptr_fail_get_user_pages:
176 printk(KERN_DEBUG "get_user_pages requested/got: %d/%d]\n",
177 num_pages_from_user, buf->sg_desc.num_pages);
178 while (--num_pages_from_user >= 0)
179 put_page(buf->pages[num_pages_from_user]);
180 kfree(buf->pages);
181
182userptr_fail_pages_array_alloc:
183 vfree(buf->sg_desc.sglist);
184
185userptr_fail_sglist_alloc:
186 kfree(buf);
187 return NULL;
188}
189
190/*
191 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
192 * be used
193 */
194static void vb2_dma_sg_put_userptr(void *buf_priv)
195{
196 struct vb2_dma_sg_buf *buf = buf_priv;
197 int i = buf->sg_desc.num_pages;
198
199 printk(KERN_DEBUG "%s: Releasing userspace buffer of %d pages\n",
200 __func__, buf->sg_desc.num_pages);
201 if (buf->vaddr)
202 vm_unmap_ram(buf->vaddr, buf->sg_desc.num_pages);
203 while (--i >= 0) {
204 if (buf->write)
205 set_page_dirty_lock(buf->pages[i]);
206 put_page(buf->pages[i]);
207 }
208 vfree(buf->sg_desc.sglist);
209 kfree(buf->pages);
210 kfree(buf);
211}
212
213static void *vb2_dma_sg_vaddr(void *buf_priv)
214{
215 struct vb2_dma_sg_buf *buf = buf_priv;
216
217 BUG_ON(!buf);
218
219 if (!buf->vaddr)
220 buf->vaddr = vm_map_ram(buf->pages,
221 buf->sg_desc.num_pages,
222 -1,
223 PAGE_KERNEL);
224
225 /* add offset in case userptr is not page-aligned */
226 return buf->vaddr + buf->offset;
227}
228
229static unsigned int vb2_dma_sg_num_users(void *buf_priv)
230{
231 struct vb2_dma_sg_buf *buf = buf_priv;
232
233 return atomic_read(&buf->refcount);
234}
235
236static int vb2_dma_sg_mmap(void *buf_priv, struct vm_area_struct *vma)
237{
238 struct vb2_dma_sg_buf *buf = buf_priv;
239 unsigned long uaddr = vma->vm_start;
240 unsigned long usize = vma->vm_end - vma->vm_start;
241 int i = 0;
242
243 if (!buf) {
244 printk(KERN_ERR "No memory to map\n");
245 return -EINVAL;
246 }
247
248 do {
249 int ret;
250
251 ret = vm_insert_page(vma, uaddr, buf->pages[i++]);
252 if (ret) {
253 printk(KERN_ERR "Remapping memory, error: %d\n", ret);
254 return ret;
255 }
256
257 uaddr += PAGE_SIZE;
258 usize -= PAGE_SIZE;
259 } while (usize > 0);
260
261
262 /*
263 * Use common vm_area operations to track buffer refcount.
264 */
265 vma->vm_private_data = &buf->handler;
266 vma->vm_ops = &vb2_common_vm_ops;
267
268 vma->vm_ops->open(vma);
269
270 return 0;
271}
272
273static void *vb2_dma_sg_cookie(void *buf_priv)
274{
275 struct vb2_dma_sg_buf *buf = buf_priv;
276
277 return &buf->sg_desc;
278}
279
280const struct vb2_mem_ops vb2_dma_sg_memops = {
281 .alloc = vb2_dma_sg_alloc,
282 .put = vb2_dma_sg_put,
283 .get_userptr = vb2_dma_sg_get_userptr,
284 .put_userptr = vb2_dma_sg_put_userptr,
285 .vaddr = vb2_dma_sg_vaddr,
286 .mmap = vb2_dma_sg_mmap,
287 .num_users = vb2_dma_sg_num_users,
288 .cookie = vb2_dma_sg_cookie,
289};
290EXPORT_SYMBOL_GPL(vb2_dma_sg_memops);
291
292MODULE_DESCRIPTION("dma scatter/gather memory handling routines for videobuf2");
293MODULE_AUTHOR("Andrzej Pietrasiewicz");
294MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-memops.c b/drivers/media/video/videobuf2-memops.c
new file mode 100644
index 000000000000..5370a3a7ee25
--- /dev/null
+++ b/drivers/media/video/videobuf2-memops.c
@@ -0,0 +1,235 @@
1/*
2 * videobuf2-memops.c - generic memory handling routines for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 * Marek Szyprowski <m.szyprowski@samsung.com>
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.
12 */
13
14#include <linux/slab.h>
15#include <linux/module.h>
16#include <linux/dma-mapping.h>
17#include <linux/vmalloc.h>
18#include <linux/mm.h>
19#include <linux/sched.h>
20#include <linux/file.h>
21#include <linux/slab.h>
22
23#include <media/videobuf2-core.h>
24#include <media/videobuf2-memops.h>
25
26/**
27 * vb2_get_vma() - acquire and lock the virtual memory area
28 * @vma: given virtual memory area
29 *
30 * This function attempts to acquire an area mapped in the userspace for
31 * the duration of a hardware operation. The area is "locked" by performing
32 * the same set of operation that are done when process calls fork() and
33 * memory areas are duplicated.
34 *
35 * Returns a copy of a virtual memory region on success or NULL.
36 */
37struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma)
38{
39 struct vm_area_struct *vma_copy;
40
41 vma_copy = kmalloc(sizeof(*vma_copy), GFP_KERNEL);
42 if (vma_copy == NULL)
43 return NULL;
44
45 if (vma->vm_ops && vma->vm_ops->open)
46 vma->vm_ops->open(vma);
47
48 if (vma->vm_file)
49 get_file(vma->vm_file);
50
51 memcpy(vma_copy, vma, sizeof(*vma));
52
53 vma_copy->vm_mm = NULL;
54 vma_copy->vm_next = NULL;
55 vma_copy->vm_prev = NULL;
56
57 return vma_copy;
58}
59
60/**
61 * vb2_put_userptr() - release a userspace virtual memory area
62 * @vma: virtual memory region associated with the area to be released
63 *
64 * This function releases the previously acquired memory area after a hardware
65 * operation.
66 */
67void vb2_put_vma(struct vm_area_struct *vma)
68{
69 if (!vma)
70 return;
71
72 if (vma->vm_file)
73 fput(vma->vm_file);
74
75 if (vma->vm_ops && vma->vm_ops->close)
76 vma->vm_ops->close(vma);
77
78 kfree(vma);
79}
80EXPORT_SYMBOL_GPL(vb2_put_vma);
81
82/**
83 * vb2_get_contig_userptr() - lock physically contiguous userspace mapped memory
84 * @vaddr: starting virtual address of the area to be verified
85 * @size: size of the area
86 * @res_paddr: will return physical address for the given vaddr
87 * @res_vma: will return locked copy of struct vm_area for the given area
88 *
89 * This function will go through memory area of size @size mapped at @vaddr and
90 * verify that the underlying physical pages are contiguous. If they are
91 * contiguous the virtual memory area is locked and a @res_vma is filled with
92 * the copy and @res_pa set to the physical address of the buffer.
93 *
94 * Returns 0 on success.
95 */
96int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
97 struct vm_area_struct **res_vma, dma_addr_t *res_pa)
98{
99 struct mm_struct *mm = current->mm;
100 struct vm_area_struct *vma;
101 unsigned long offset, start, end;
102 unsigned long this_pfn, prev_pfn;
103 dma_addr_t pa = 0;
104 int ret = -EFAULT;
105
106 start = vaddr;
107 offset = start & ~PAGE_MASK;
108 end = start + size;
109
110 down_read(&mm->mmap_sem);
111 vma = find_vma(mm, start);
112
113 if (vma == NULL || vma->vm_end < end)
114 goto done;
115
116 for (prev_pfn = 0; start < end; start += PAGE_SIZE) {
117 ret = follow_pfn(vma, start, &this_pfn);
118 if (ret)
119 goto done;
120
121 if (prev_pfn == 0)
122 pa = this_pfn << PAGE_SHIFT;
123 else if (this_pfn != prev_pfn + 1) {
124 ret = -EFAULT;
125 goto done;
126 }
127 prev_pfn = this_pfn;
128 }
129
130 /*
131 * Memory is contigous, lock vma and return to the caller
132 */
133 *res_vma = vb2_get_vma(vma);
134 if (*res_vma == NULL) {
135 ret = -ENOMEM;
136 goto done;
137 }
138 *res_pa = pa + offset;
139 ret = 0;
140
141done:
142 up_read(&mm->mmap_sem);
143 return ret;
144}
145EXPORT_SYMBOL_GPL(vb2_get_contig_userptr);
146
147/**
148 * vb2_mmap_pfn_range() - map physical pages to userspace
149 * @vma: virtual memory region for the mapping
150 * @paddr: starting physical address of the memory to be mapped
151 * @size: size of the memory to be mapped
152 * @vm_ops: vm operations to be assigned to the created area
153 * @priv: private data to be associated with the area
154 *
155 * Returns 0 on success.
156 */
157int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
158 unsigned long size,
159 const struct vm_operations_struct *vm_ops,
160 void *priv)
161{
162 int ret;
163
164 size = min_t(unsigned long, vma->vm_end - vma->vm_start, size);
165
166 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
167 ret = remap_pfn_range(vma, vma->vm_start, paddr >> PAGE_SHIFT,
168 size, vma->vm_page_prot);
169 if (ret) {
170 printk(KERN_ERR "Remapping memory failed, error: %d\n", ret);
171 return ret;
172 }
173
174 vma->vm_flags |= VM_DONTEXPAND | VM_RESERVED;
175 vma->vm_private_data = priv;
176 vma->vm_ops = vm_ops;
177
178 vma->vm_ops->open(vma);
179
180 printk(KERN_DEBUG "%s: mapped paddr 0x%08lx at 0x%08lx, size %ld\n",
181 __func__, paddr, vma->vm_start, size);
182
183 return 0;
184}
185EXPORT_SYMBOL_GPL(vb2_mmap_pfn_range);
186
187/**
188 * vb2_common_vm_open() - increase refcount of the vma
189 * @vma: virtual memory region for the mapping
190 *
191 * This function adds another user to the provided vma. It expects
192 * struct vb2_vmarea_handler pointer in vma->vm_private_data.
193 */
194static void vb2_common_vm_open(struct vm_area_struct *vma)
195{
196 struct vb2_vmarea_handler *h = vma->vm_private_data;
197
198 printk(KERN_DEBUG "%s: %p, refcount: %d, vma: %08lx-%08lx\n",
199 __func__, h, atomic_read(h->refcount), vma->vm_start,
200 vma->vm_end);
201
202 atomic_inc(h->refcount);
203}
204
205/**
206 * vb2_common_vm_close() - decrease refcount of the vma
207 * @vma: virtual memory region for the mapping
208 *
209 * This function releases the user from the provided vma. It expects
210 * struct vb2_vmarea_handler pointer in vma->vm_private_data.
211 */
212static void vb2_common_vm_close(struct vm_area_struct *vma)
213{
214 struct vb2_vmarea_handler *h = vma->vm_private_data;
215
216 printk(KERN_DEBUG "%s: %p, refcount: %d, vma: %08lx-%08lx\n",
217 __func__, h, atomic_read(h->refcount), vma->vm_start,
218 vma->vm_end);
219
220 h->put(h->arg);
221}
222
223/**
224 * vb2_common_vm_ops - common vm_ops used for tracking refcount of mmaped
225 * video buffers
226 */
227const struct vm_operations_struct vb2_common_vm_ops = {
228 .open = vb2_common_vm_open,
229 .close = vb2_common_vm_close,
230};
231EXPORT_SYMBOL_GPL(vb2_common_vm_ops);
232
233MODULE_DESCRIPTION("common memory handling routines for videobuf2");
234MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
235MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/videobuf2-vmalloc.c b/drivers/media/video/videobuf2-vmalloc.c
new file mode 100644
index 000000000000..a3a884234059
--- /dev/null
+++ b/drivers/media/video/videobuf2-vmalloc.c
@@ -0,0 +1,132 @@
1/*
2 * videobuf2-vmalloc.c - vmalloc memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
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.
11 */
12
13#include <linux/module.h>
14#include <linux/mm.h>
15#include <linux/slab.h>
16#include <linux/vmalloc.h>
17
18#include <media/videobuf2-core.h>
19#include <media/videobuf2-memops.h>
20
21struct vb2_vmalloc_buf {
22 void *vaddr;
23 unsigned long size;
24 atomic_t refcount;
25 struct vb2_vmarea_handler handler;
26};
27
28static void vb2_vmalloc_put(void *buf_priv);
29
30static void *vb2_vmalloc_alloc(void *alloc_ctx, unsigned long size)
31{
32 struct vb2_vmalloc_buf *buf;
33
34 buf = kzalloc(sizeof *buf, GFP_KERNEL);
35 if (!buf)
36 return NULL;
37
38 buf->size = size;
39 buf->vaddr = vmalloc_user(buf->size);
40 buf->handler.refcount = &buf->refcount;
41 buf->handler.put = vb2_vmalloc_put;
42 buf->handler.arg = buf;
43
44 if (!buf->vaddr) {
45 printk(KERN_ERR "vmalloc of size %ld failed\n", buf->size);
46 kfree(buf);
47 return NULL;
48 }
49
50 atomic_inc(&buf->refcount);
51 printk(KERN_DEBUG "Allocated vmalloc buffer of size %ld at vaddr=%p\n",
52 buf->size, buf->vaddr);
53
54 return buf;
55}
56
57static void vb2_vmalloc_put(void *buf_priv)
58{
59 struct vb2_vmalloc_buf *buf = buf_priv;
60
61 if (atomic_dec_and_test(&buf->refcount)) {
62 printk(KERN_DEBUG "%s: Freeing vmalloc mem at vaddr=%p\n",
63 __func__, buf->vaddr);
64 vfree(buf->vaddr);
65 kfree(buf);
66 }
67}
68
69static void *vb2_vmalloc_vaddr(void *buf_priv)
70{
71 struct vb2_vmalloc_buf *buf = buf_priv;
72
73 BUG_ON(!buf);
74
75 if (!buf->vaddr) {
76 printk(KERN_ERR "Address of an unallocated plane requested\n");
77 return NULL;
78 }
79
80 return buf->vaddr;
81}
82
83static unsigned int vb2_vmalloc_num_users(void *buf_priv)
84{
85 struct vb2_vmalloc_buf *buf = buf_priv;
86 return atomic_read(&buf->refcount);
87}
88
89static int vb2_vmalloc_mmap(void *buf_priv, struct vm_area_struct *vma)
90{
91 struct vb2_vmalloc_buf *buf = buf_priv;
92 int ret;
93
94 if (!buf) {
95 printk(KERN_ERR "No memory to map\n");
96 return -EINVAL;
97 }
98
99 ret = remap_vmalloc_range(vma, buf->vaddr, 0);
100 if (ret) {
101 printk(KERN_ERR "Remapping vmalloc memory, error: %d\n", ret);
102 return ret;
103 }
104
105 /*
106 * Make sure that vm_areas for 2 buffers won't be merged together
107 */
108 vma->vm_flags |= VM_DONTEXPAND;
109
110 /*
111 * Use common vm_area operations to track buffer refcount.
112 */
113 vma->vm_private_data = &buf->handler;
114 vma->vm_ops = &vb2_common_vm_ops;
115
116 vma->vm_ops->open(vma);
117
118 return 0;
119}
120
121const struct vb2_mem_ops vb2_vmalloc_memops = {
122 .alloc = vb2_vmalloc_alloc,
123 .put = vb2_vmalloc_put,
124 .vaddr = vb2_vmalloc_vaddr,
125 .mmap = vb2_vmalloc_mmap,
126 .num_users = vb2_vmalloc_num_users,
127};
128EXPORT_SYMBOL_GPL(vb2_vmalloc_memops);
129
130MODULE_DESCRIPTION("vmalloc memory handling routines for videobuf2");
131MODULE_AUTHOR("Pawel Osciak <pawel@osciak.com>");
132MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index c49c39386bd0..2238a613d664 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -7,6 +7,9 @@
7 * John Sokol <sokol--a.t--videotechnology.com> 7 * John Sokol <sokol--a.t--videotechnology.com>
8 * http://v4l.videotechnology.com/ 8 * http://v4l.videotechnology.com/
9 * 9 *
10 * Conversion to videobuf2 by Pawel Osciak & Marek Szyprowski
11 * Copyright (c) 2010 Samsung Electronics
12 *
10 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the BSD Licence, GNU General Public License 14 * it under the terms of the BSD Licence, GNU General Public License
12 * as published by the Free Software Foundation; either version 2 of the 15 * as published by the Free Software Foundation; either version 2 of the
@@ -23,12 +26,12 @@
23#include <linux/mutex.h> 26#include <linux/mutex.h>
24#include <linux/videodev2.h> 27#include <linux/videodev2.h>
25#include <linux/kthread.h> 28#include <linux/kthread.h>
26#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 20)
27#include <linux/freezer.h> 29#include <linux/freezer.h>
28#endif 30#include <media/videobuf2-vmalloc.h>
29#include <media/videobuf-vmalloc.h>
30#include <media/v4l2-device.h> 31#include <media/v4l2-device.h>
31#include <media/v4l2-ioctl.h> 32#include <media/v4l2-ioctl.h>
33#include <media/v4l2-ctrls.h>
34#include <media/v4l2-fh.h>
32#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
33 36
34#define VIVI_MODULE_NAME "vivi" 37#define VIVI_MODULE_NAME "vivi"
@@ -42,7 +45,7 @@
42#define MAX_HEIGHT 1200 45#define MAX_HEIGHT 1200
43 46
44#define VIVI_MAJOR_VERSION 0 47#define VIVI_MAJOR_VERSION 0
45#define VIVI_MINOR_VERSION 7 48#define VIVI_MINOR_VERSION 8
46#define VIVI_RELEASE 0 49#define VIVI_RELEASE 0
47#define VIVI_VERSION \ 50#define VIVI_VERSION \
48 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE) 51 KERNEL_VERSION(VIVI_MAJOR_VERSION, VIVI_MINOR_VERSION, VIVI_RELEASE)
@@ -133,16 +136,11 @@ static struct vivi_fmt *get_format(struct v4l2_format *f)
133 return &formats[k]; 136 return &formats[k];
134} 137}
135 138
136struct sg_to_addr {
137 int pos;
138 struct scatterlist *sg;
139};
140
141/* buffer for one video frame */ 139/* buffer for one video frame */
142struct vivi_buffer { 140struct vivi_buffer {
143 /* common v4l buffer stuff -- must be first */ 141 /* common v4l buffer stuff -- must be first */
144 struct videobuf_buffer vb; 142 struct vb2_buffer vb;
145 143 struct list_head list;
146 struct vivi_fmt *fmt; 144 struct vivi_fmt *fmt;
147}; 145};
148 146
@@ -162,13 +160,20 @@ static LIST_HEAD(vivi_devlist);
162struct vivi_dev { 160struct vivi_dev {
163 struct list_head vivi_devlist; 161 struct list_head vivi_devlist;
164 struct v4l2_device v4l2_dev; 162 struct v4l2_device v4l2_dev;
163 struct v4l2_ctrl_handler ctrl_handler;
165 164
166 /* controls */ 165 /* controls */
167 int brightness; 166 struct v4l2_ctrl *brightness;
168 int contrast; 167 struct v4l2_ctrl *contrast;
169 int saturation; 168 struct v4l2_ctrl *saturation;
170 int hue; 169 struct v4l2_ctrl *hue;
171 int volume; 170 struct v4l2_ctrl *volume;
171 struct v4l2_ctrl *button;
172 struct v4l2_ctrl *boolean;
173 struct v4l2_ctrl *int32;
174 struct v4l2_ctrl *int64;
175 struct v4l2_ctrl *menu;
176 struct v4l2_ctrl *string;
172 177
173 spinlock_t slock; 178 spinlock_t slock;
174 struct mutex mutex; 179 struct mutex mutex;
@@ -181,6 +186,7 @@ struct vivi_dev {
181 /* Several counters */ 186 /* Several counters */
182 unsigned ms; 187 unsigned ms;
183 unsigned long jiffies; 188 unsigned long jiffies;
189 unsigned button_pressed;
184 190
185 int mv_count; /* Controls bars movement */ 191 int mv_count; /* Controls bars movement */
186 192
@@ -190,9 +196,10 @@ struct vivi_dev {
190 /* video capture */ 196 /* video capture */
191 struct vivi_fmt *fmt; 197 struct vivi_fmt *fmt;
192 unsigned int width, height; 198 unsigned int width, height;
193 struct videobuf_queue vb_vidq; 199 struct vb2_queue vb_vidq;
200 enum v4l2_field field;
201 unsigned int field_count;
194 202
195 unsigned long generating;
196 u8 bars[9][3]; 203 u8 bars[9][3];
197 u8 line[MAX_WIDTH * 4]; 204 u8 line[MAX_WIDTH * 4];
198}; 205};
@@ -443,10 +450,10 @@ static void gen_text(struct vivi_dev *dev, char *basep,
443 450
444static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf) 451static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
445{ 452{
446 int hmax = buf->vb.height; 453 int wmax = dev->width;
447 int wmax = buf->vb.width; 454 int hmax = dev->height;
448 struct timeval ts; 455 struct timeval ts;
449 void *vbuf = videobuf_to_vmalloc(&buf->vb); 456 void *vbuf = vb2_plane_vaddr(&buf->vb, 0);
450 unsigned ms; 457 unsigned ms;
451 char str[100]; 458 char str[100];
452 int h, line = 1; 459 int h, line = 1;
@@ -472,22 +479,38 @@ static void vivi_fillbuff(struct vivi_dev *dev, struct vivi_buffer *buf)
472 dev->width, dev->height, dev->input); 479 dev->width, dev->height, dev->input);
473 gen_text(dev, vbuf, line++ * 16, 16, str); 480 gen_text(dev, vbuf, line++ * 16, 16, str);
474 481
482 mutex_lock(&dev->ctrl_handler.lock);
475 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ", 483 snprintf(str, sizeof(str), " brightness %3d, contrast %3d, saturation %3d, hue %d ",
476 dev->brightness, 484 dev->brightness->cur.val,
477 dev->contrast, 485 dev->contrast->cur.val,
478 dev->saturation, 486 dev->saturation->cur.val,
479 dev->hue); 487 dev->hue->cur.val);
480 gen_text(dev, vbuf, line++ * 16, 16, str); 488 gen_text(dev, vbuf, line++ * 16, 16, str);
481 snprintf(str, sizeof(str), " volume %3d ", dev->volume); 489 snprintf(str, sizeof(str), " volume %3d ", dev->volume->cur.val);
482 gen_text(dev, vbuf, line++ * 16, 16, str); 490 gen_text(dev, vbuf, line++ * 16, 16, str);
491 snprintf(str, sizeof(str), " int32 %d, int64 %lld ",
492 dev->int32->cur.val,
493 dev->int64->cur.val64);
494 gen_text(dev, vbuf, line++ * 16, 16, str);
495 snprintf(str, sizeof(str), " boolean %d, menu %s, string \"%s\" ",
496 dev->boolean->cur.val,
497 dev->menu->qmenu[dev->menu->cur.val],
498 dev->string->cur.string);
499 mutex_unlock(&dev->ctrl_handler.lock);
500 gen_text(dev, vbuf, line++ * 16, 16, str);
501 if (dev->button_pressed) {
502 dev->button_pressed--;
503 snprintf(str, sizeof(str), " button pressed!");
504 gen_text(dev, vbuf, line++ * 16, 16, str);
505 }
483 506
484 dev->mv_count += 2; 507 dev->mv_count += 2;
485 508
486 /* Advice that buffer was filled */ 509 buf->vb.v4l2_buf.field = dev->field;
487 buf->vb.field_count++; 510 dev->field_count++;
511 buf->vb.v4l2_buf.sequence = dev->field_count >> 1;
488 do_gettimeofday(&ts); 512 do_gettimeofday(&ts);
489 buf->vb.ts = ts; 513 buf->vb.v4l2_buf.timestamp = ts;
490 buf->vb.state = VIDEOBUF_DONE;
491} 514}
492 515
493static void vivi_thread_tick(struct vivi_dev *dev) 516static void vivi_thread_tick(struct vivi_dev *dev)
@@ -504,23 +527,17 @@ static void vivi_thread_tick(struct vivi_dev *dev)
504 goto unlock; 527 goto unlock;
505 } 528 }
506 529
507 buf = list_entry(dma_q->active.next, 530 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
508 struct vivi_buffer, vb.queue); 531 list_del(&buf->list);
509 532
510 /* Nobody is waiting on this buffer, return */ 533 do_gettimeofday(&buf->vb.v4l2_buf.timestamp);
511 if (!waitqueue_active(&buf->vb.done))
512 goto unlock;
513
514 list_del(&buf->vb.queue);
515
516 do_gettimeofday(&buf->vb.ts);
517 534
518 /* Fill buffer */ 535 /* Fill buffer */
519 vivi_fillbuff(dev, buf); 536 vivi_fillbuff(dev, buf);
520 dprintk(dev, 1, "filled buffer %p\n", buf); 537 dprintk(dev, 1, "filled buffer %p\n", buf);
521 538
522 wake_up(&buf->vb.done); 539 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_DONE);
523 dprintk(dev, 2, "[%p/%d] wakeup\n", buf, buf->vb. i); 540 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
524unlock: 541unlock:
525 spin_unlock_irqrestore(&dev->slock, flags); 542 spin_unlock_irqrestore(&dev->slock, flags);
526} 543}
@@ -571,17 +588,12 @@ static int vivi_thread(void *data)
571 return 0; 588 return 0;
572} 589}
573 590
574static void vivi_start_generating(struct file *file) 591static int vivi_start_generating(struct vivi_dev *dev)
575{ 592{
576 struct vivi_dev *dev = video_drvdata(file);
577 struct vivi_dmaqueue *dma_q = &dev->vidq; 593 struct vivi_dmaqueue *dma_q = &dev->vidq;
578 594
579 dprintk(dev, 1, "%s\n", __func__); 595 dprintk(dev, 1, "%s\n", __func__);
580 596
581 if (test_and_set_bit(0, &dev->generating))
582 return;
583 file->private_data = dev;
584
585 /* Resets frame counters */ 597 /* Resets frame counters */
586 dev->ms = 0; 598 dev->ms = 0;
587 dev->mv_count = 0; 599 dev->mv_count = 0;
@@ -593,146 +605,200 @@ static void vivi_start_generating(struct file *file)
593 605
594 if (IS_ERR(dma_q->kthread)) { 606 if (IS_ERR(dma_q->kthread)) {
595 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n"); 607 v4l2_err(&dev->v4l2_dev, "kernel_thread() failed\n");
596 clear_bit(0, &dev->generating); 608 return PTR_ERR(dma_q->kthread);
597 return;
598 } 609 }
599 /* Wakes thread */ 610 /* Wakes thread */
600 wake_up_interruptible(&dma_q->wq); 611 wake_up_interruptible(&dma_q->wq);
601 612
602 dprintk(dev, 1, "returning from %s\n", __func__); 613 dprintk(dev, 1, "returning from %s\n", __func__);
614 return 0;
603} 615}
604 616
605static void vivi_stop_generating(struct file *file) 617static void vivi_stop_generating(struct vivi_dev *dev)
606{ 618{
607 struct vivi_dev *dev = video_drvdata(file);
608 struct vivi_dmaqueue *dma_q = &dev->vidq; 619 struct vivi_dmaqueue *dma_q = &dev->vidq;
609 620
610 dprintk(dev, 1, "%s\n", __func__); 621 dprintk(dev, 1, "%s\n", __func__);
611 622
612 if (!file->private_data)
613 return;
614 if (!test_and_clear_bit(0, &dev->generating))
615 return;
616
617 /* shutdown control thread */ 623 /* shutdown control thread */
618 if (dma_q->kthread) { 624 if (dma_q->kthread) {
619 kthread_stop(dma_q->kthread); 625 kthread_stop(dma_q->kthread);
620 dma_q->kthread = NULL; 626 dma_q->kthread = NULL;
621 } 627 }
622 videobuf_stop(&dev->vb_vidq);
623 videobuf_mmap_free(&dev->vb_vidq);
624}
625 628
626static int vivi_is_generating(struct vivi_dev *dev) 629 /*
627{ 630 * Typical driver might need to wait here until dma engine stops.
628 return test_bit(0, &dev->generating); 631 * In this case we can abort imiedetly, so it's just a noop.
632 */
633
634 /* Release all active buffers */
635 while (!list_empty(&dma_q->active)) {
636 struct vivi_buffer *buf;
637 buf = list_entry(dma_q->active.next, struct vivi_buffer, list);
638 list_del(&buf->list);
639 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
640 dprintk(dev, 2, "[%p/%d] done\n", buf, buf->vb.v4l2_buf.index);
641 }
629} 642}
630
631/* ------------------------------------------------------------------ 643/* ------------------------------------------------------------------
632 Videobuf operations 644 Videobuf operations
633 ------------------------------------------------------------------*/ 645 ------------------------------------------------------------------*/
634static int 646static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
635buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) 647 unsigned int *nplanes, unsigned long sizes[],
648 void *alloc_ctxs[])
636{ 649{
637 struct vivi_dev *dev = vq->priv_data; 650 struct vivi_dev *dev = vb2_get_drv_priv(vq);
651 unsigned long size;
652
653 size = dev->width * dev->height * 2;
654
655 if (0 == *nbuffers)
656 *nbuffers = 32;
638 657
639 *size = dev->width * dev->height * 2; 658 while (size * *nbuffers > vid_limit * 1024 * 1024)
659 (*nbuffers)--;
640 660
641 if (0 == *count) 661 *nplanes = 1;
642 *count = 32;
643 662
644 while (*size * *count > vid_limit * 1024 * 1024) 663 sizes[0] = size;
645 (*count)--;
646 664
647 dprintk(dev, 1, "%s, count=%d, size=%d\n", __func__, 665 /*
648 *count, *size); 666 * videobuf2-vmalloc allocator is context-less so no need to set
667 * alloc_ctxs array.
668 */
669
670 dprintk(dev, 1, "%s, count=%d, size=%ld\n", __func__,
671 *nbuffers, size);
649 672
650 return 0; 673 return 0;
651} 674}
652 675
653static void free_buffer(struct videobuf_queue *vq, struct vivi_buffer *buf) 676static int buffer_init(struct vb2_buffer *vb)
654{ 677{
655 struct vivi_dev *dev = vq->priv_data; 678 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
679
680 BUG_ON(NULL == dev->fmt);
656 681
657 dprintk(dev, 1, "%s, state: %i\n", __func__, buf->vb.state); 682 /*
683 * This callback is called once per buffer, after its allocation.
684 *
685 * Vivi does not allow changing format during streaming, but it is
686 * possible to do so when streaming is paused (i.e. in streamoff state).
687 * Buffers however are not freed when going into streamoff and so
688 * buffer size verification has to be done in buffer_prepare, on each
689 * qbuf.
690 * It would be best to move verification code here to buf_init and
691 * s_fmt though.
692 */
658 693
659 videobuf_vmalloc_free(&buf->vb); 694 return 0;
660 dprintk(dev, 1, "free_buffer: freed\n");
661 buf->vb.state = VIDEOBUF_NEEDS_INIT;
662} 695}
663 696
664static int 697static int buffer_prepare(struct vb2_buffer *vb)
665buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
666 enum v4l2_field field)
667{ 698{
668 struct vivi_dev *dev = vq->priv_data; 699 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
669 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 700 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
670 int rc; 701 unsigned long size;
671 702
672 dprintk(dev, 1, "%s, field=%d\n", __func__, field); 703 dprintk(dev, 1, "%s, field=%d\n", __func__, vb->v4l2_buf.field);
673 704
674 BUG_ON(NULL == dev->fmt); 705 BUG_ON(NULL == dev->fmt);
675 706
707 /*
708 * Theses properties only change when queue is idle, see s_fmt.
709 * The below checks should not be performed here, on each
710 * buffer_prepare (i.e. on each qbuf). Most of the code in this function
711 * should thus be moved to buffer_init and s_fmt.
712 */
676 if (dev->width < 48 || dev->width > MAX_WIDTH || 713 if (dev->width < 48 || dev->width > MAX_WIDTH ||
677 dev->height < 32 || dev->height > MAX_HEIGHT) 714 dev->height < 32 || dev->height > MAX_HEIGHT)
678 return -EINVAL; 715 return -EINVAL;
679 716
680 buf->vb.size = dev->width * dev->height * 2; 717 size = dev->width * dev->height * 2;
681 if (0 != buf->vb.baddr && buf->vb.bsize < buf->vb.size) 718 if (vb2_plane_size(vb, 0) < size) {
719 dprintk(dev, 1, "%s data will not fit into plane (%lu < %lu)\n",
720 __func__, vb2_plane_size(vb, 0), size);
682 return -EINVAL; 721 return -EINVAL;
722 }
683 723
684 /* These properties only change when queue is idle, see s_fmt */ 724 vb2_set_plane_payload(&buf->vb, 0, size);
685 buf->fmt = dev->fmt; 725
686 buf->vb.width = dev->width; 726 buf->fmt = dev->fmt;
687 buf->vb.height = dev->height;
688 buf->vb.field = field;
689 727
690 precalculate_bars(dev); 728 precalculate_bars(dev);
691 precalculate_line(dev); 729 precalculate_line(dev);
692 730
693 if (VIDEOBUF_NEEDS_INIT == buf->vb.state) { 731 return 0;
694 rc = videobuf_iolock(vq, &buf->vb, NULL); 732}
695 if (rc < 0)
696 goto fail;
697 }
698 733
699 buf->vb.state = VIDEOBUF_PREPARED; 734static int buffer_finish(struct vb2_buffer *vb)
735{
736 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
737 dprintk(dev, 1, "%s\n", __func__);
700 return 0; 738 return 0;
739}
740
741static void buffer_cleanup(struct vb2_buffer *vb)
742{
743 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
744 dprintk(dev, 1, "%s\n", __func__);
701 745
702fail:
703 free_buffer(vq, buf);
704 return rc;
705} 746}
706 747
707static void 748static void buffer_queue(struct vb2_buffer *vb)
708buffer_queue(struct videobuf_queue *vq, struct videobuf_buffer *vb)
709{ 749{
710 struct vivi_dev *dev = vq->priv_data; 750 struct vivi_dev *dev = vb2_get_drv_priv(vb->vb2_queue);
711 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 751 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb);
712 struct vivi_dmaqueue *vidq = &dev->vidq; 752 struct vivi_dmaqueue *vidq = &dev->vidq;
753 unsigned long flags = 0;
713 754
714 dprintk(dev, 1, "%s\n", __func__); 755 dprintk(dev, 1, "%s\n", __func__);
715 756
716 buf->vb.state = VIDEOBUF_QUEUED; 757 spin_lock_irqsave(&dev->slock, flags);
717 list_add_tail(&buf->vb.queue, &vidq->active); 758 list_add_tail(&buf->list, &vidq->active);
759 spin_unlock_irqrestore(&dev->slock, flags);
718} 760}
719 761
720static void buffer_release(struct videobuf_queue *vq, 762static int start_streaming(struct vb2_queue *vq)
721 struct videobuf_buffer *vb)
722{ 763{
723 struct vivi_dev *dev = vq->priv_data; 764 struct vivi_dev *dev = vb2_get_drv_priv(vq);
724 struct vivi_buffer *buf = container_of(vb, struct vivi_buffer, vb); 765 dprintk(dev, 1, "%s\n", __func__);
766 return vivi_start_generating(dev);
767}
725 768
769/* abort streaming and wait for last buffer */
770static int stop_streaming(struct vb2_queue *vq)
771{
772 struct vivi_dev *dev = vb2_get_drv_priv(vq);
726 dprintk(dev, 1, "%s\n", __func__); 773 dprintk(dev, 1, "%s\n", __func__);
774 vivi_stop_generating(dev);
775 return 0;
776}
727 777
728 free_buffer(vq, buf); 778static void vivi_lock(struct vb2_queue *vq)
779{
780 struct vivi_dev *dev = vb2_get_drv_priv(vq);
781 mutex_lock(&dev->mutex);
729} 782}
730 783
731static struct videobuf_queue_ops vivi_video_qops = { 784static void vivi_unlock(struct vb2_queue *vq)
732 .buf_setup = buffer_setup, 785{
733 .buf_prepare = buffer_prepare, 786 struct vivi_dev *dev = vb2_get_drv_priv(vq);
734 .buf_queue = buffer_queue, 787 mutex_unlock(&dev->mutex);
735 .buf_release = buffer_release, 788}
789
790
791static struct vb2_ops vivi_video_qops = {
792 .queue_setup = queue_setup,
793 .buf_init = buffer_init,
794 .buf_prepare = buffer_prepare,
795 .buf_finish = buffer_finish,
796 .buf_cleanup = buffer_cleanup,
797 .buf_queue = buffer_queue,
798 .start_streaming = start_streaming,
799 .stop_streaming = stop_streaming,
800 .wait_prepare = vivi_unlock,
801 .wait_finish = vivi_lock,
736}; 802};
737 803
738/* ------------------------------------------------------------------ 804/* ------------------------------------------------------------------
@@ -774,7 +840,7 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
774 840
775 f->fmt.pix.width = dev->width; 841 f->fmt.pix.width = dev->width;
776 f->fmt.pix.height = dev->height; 842 f->fmt.pix.height = dev->height;
777 f->fmt.pix.field = dev->vb_vidq.field; 843 f->fmt.pix.field = dev->field;
778 f->fmt.pix.pixelformat = dev->fmt->fourcc; 844 f->fmt.pix.pixelformat = dev->fmt->fourcc;
779 f->fmt.pix.bytesperline = 845 f->fmt.pix.bytesperline =
780 (f->fmt.pix.width * dev->fmt->depth) >> 3; 846 (f->fmt.pix.width * dev->fmt->depth) >> 3;
@@ -820,82 +886,60 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
820 struct v4l2_format *f) 886 struct v4l2_format *f)
821{ 887{
822 struct vivi_dev *dev = video_drvdata(file); 888 struct vivi_dev *dev = video_drvdata(file);
889 struct vb2_queue *q = &dev->vb_vidq;
823 890
824 int ret = vidioc_try_fmt_vid_cap(file, priv, f); 891 int ret = vidioc_try_fmt_vid_cap(file, priv, f);
825 if (ret < 0) 892 if (ret < 0)
826 return ret; 893 return ret;
827 894
828 if (vivi_is_generating(dev)) { 895 if (vb2_is_streaming(q)) {
829 dprintk(dev, 1, "%s device busy\n", __func__); 896 dprintk(dev, 1, "%s device busy\n", __func__);
830 ret = -EBUSY; 897 return -EBUSY;
831 goto out;
832 } 898 }
833 899
834 dev->fmt = get_format(f); 900 dev->fmt = get_format(f);
835 dev->width = f->fmt.pix.width; 901 dev->width = f->fmt.pix.width;
836 dev->height = f->fmt.pix.height; 902 dev->height = f->fmt.pix.height;
837 dev->vb_vidq.field = f->fmt.pix.field; 903 dev->field = f->fmt.pix.field;
838 ret = 0; 904
839out: 905 return 0;
840 return ret;
841} 906}
842 907
843static int vidioc_reqbufs(struct file *file, void *priv, 908static int vidioc_reqbufs(struct file *file, void *priv,
844 struct v4l2_requestbuffers *p) 909 struct v4l2_requestbuffers *p)
845{ 910{
846 struct vivi_dev *dev = video_drvdata(file); 911 struct vivi_dev *dev = video_drvdata(file);
847 912 return vb2_reqbufs(&dev->vb_vidq, p);
848 return videobuf_reqbufs(&dev->vb_vidq, p);
849} 913}
850 914
851static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p) 915static int vidioc_querybuf(struct file *file, void *priv, struct v4l2_buffer *p)
852{ 916{
853 struct vivi_dev *dev = video_drvdata(file); 917 struct vivi_dev *dev = video_drvdata(file);
854 918 return vb2_querybuf(&dev->vb_vidq, p);
855 return videobuf_querybuf(&dev->vb_vidq, p);
856} 919}
857 920
858static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p) 921static int vidioc_qbuf(struct file *file, void *priv, struct v4l2_buffer *p)
859{ 922{
860 struct vivi_dev *dev = video_drvdata(file); 923 struct vivi_dev *dev = video_drvdata(file);
861 924 return vb2_qbuf(&dev->vb_vidq, p);
862 return videobuf_qbuf(&dev->vb_vidq, p);
863} 925}
864 926
865static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p) 927static int vidioc_dqbuf(struct file *file, void *priv, struct v4l2_buffer *p)
866{ 928{
867 struct vivi_dev *dev = video_drvdata(file); 929 struct vivi_dev *dev = video_drvdata(file);
868 930 return vb2_dqbuf(&dev->vb_vidq, p, file->f_flags & O_NONBLOCK);
869 return videobuf_dqbuf(&dev->vb_vidq, p,
870 file->f_flags & O_NONBLOCK);
871} 931}
872 932
873static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i) 933static int vidioc_streamon(struct file *file, void *priv, enum v4l2_buf_type i)
874{ 934{
875 struct vivi_dev *dev = video_drvdata(file); 935 struct vivi_dev *dev = video_drvdata(file);
876 int ret; 936 return vb2_streamon(&dev->vb_vidq, i);
877
878 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
879 return -EINVAL;
880 ret = videobuf_streamon(&dev->vb_vidq);
881 if (ret)
882 return ret;
883
884 vivi_start_generating(file);
885 return 0;
886} 937}
887 938
888static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i) 939static int vidioc_streamoff(struct file *file, void *priv, enum v4l2_buf_type i)
889{ 940{
890 struct vivi_dev *dev = video_drvdata(file); 941 struct vivi_dev *dev = video_drvdata(file);
891 int ret; 942 return vb2_streamoff(&dev->vb_vidq, i);
892
893 if (i != V4L2_BUF_TYPE_VIDEO_CAPTURE)
894 return -EINVAL;
895 ret = videobuf_streamoff(&dev->vb_vidq);
896 if (!ret)
897 vivi_stop_generating(file);
898 return ret;
899} 943}
900 944
901static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i) 945static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *i)
@@ -938,80 +982,14 @@ static int vidioc_s_input(struct file *file, void *priv, unsigned int i)
938} 982}
939 983
940/* --- controls ---------------------------------------------- */ 984/* --- controls ---------------------------------------------- */
941static int vidioc_queryctrl(struct file *file, void *priv,
942 struct v4l2_queryctrl *qc)
943{
944 switch (qc->id) {
945 case V4L2_CID_AUDIO_VOLUME:
946 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 200);
947 case V4L2_CID_BRIGHTNESS:
948 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
949 case V4L2_CID_CONTRAST:
950 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 16);
951 case V4L2_CID_SATURATION:
952 return v4l2_ctrl_query_fill(qc, 0, 255, 1, 127);
953 case V4L2_CID_HUE:
954 return v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
955 }
956 return -EINVAL;
957}
958 985
959static int vidioc_g_ctrl(struct file *file, void *priv, 986static int vivi_s_ctrl(struct v4l2_ctrl *ctrl)
960 struct v4l2_control *ctrl)
961{ 987{
962 struct vivi_dev *dev = video_drvdata(file); 988 struct vivi_dev *dev = container_of(ctrl->handler, struct vivi_dev, ctrl_handler);
963 989
964 switch (ctrl->id) { 990 if (ctrl == dev->button)
965 case V4L2_CID_AUDIO_VOLUME: 991 dev->button_pressed = 30;
966 ctrl->value = dev->volume; 992 return 0;
967 return 0;
968 case V4L2_CID_BRIGHTNESS:
969 ctrl->value = dev->brightness;
970 return 0;
971 case V4L2_CID_CONTRAST:
972 ctrl->value = dev->contrast;
973 return 0;
974 case V4L2_CID_SATURATION:
975 ctrl->value = dev->saturation;
976 return 0;
977 case V4L2_CID_HUE:
978 ctrl->value = dev->hue;
979 return 0;
980 }
981 return -EINVAL;
982}
983
984static int vidioc_s_ctrl(struct file *file, void *priv,
985 struct v4l2_control *ctrl)
986{
987 struct vivi_dev *dev = video_drvdata(file);
988 struct v4l2_queryctrl qc;
989 int err;
990
991 qc.id = ctrl->id;
992 err = vidioc_queryctrl(file, priv, &qc);
993 if (err < 0)
994 return err;
995 if (ctrl->value < qc.minimum || ctrl->value > qc.maximum)
996 return -ERANGE;
997 switch (ctrl->id) {
998 case V4L2_CID_AUDIO_VOLUME:
999 dev->volume = ctrl->value;
1000 return 0;
1001 case V4L2_CID_BRIGHTNESS:
1002 dev->brightness = ctrl->value;
1003 return 0;
1004 case V4L2_CID_CONTRAST:
1005 dev->contrast = ctrl->value;
1006 return 0;
1007 case V4L2_CID_SATURATION:
1008 dev->saturation = ctrl->value;
1009 return 0;
1010 case V4L2_CID_HUE:
1011 dev->hue = ctrl->value;
1012 return 0;
1013 }
1014 return -EINVAL;
1015} 993}
1016 994
1017/* ------------------------------------------------------------------ 995/* ------------------------------------------------------------------
@@ -1023,21 +1001,19 @@ vivi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1023{ 1001{
1024 struct vivi_dev *dev = video_drvdata(file); 1002 struct vivi_dev *dev = video_drvdata(file);
1025 1003
1026 vivi_start_generating(file); 1004 dprintk(dev, 1, "read called\n");
1027 return videobuf_read_stream(&dev->vb_vidq, data, count, ppos, 0, 1005 return vb2_read(&dev->vb_vidq, data, count, ppos,
1028 file->f_flags & O_NONBLOCK); 1006 file->f_flags & O_NONBLOCK);
1029} 1007}
1030 1008
1031static unsigned int 1009static unsigned int
1032vivi_poll(struct file *file, struct poll_table_struct *wait) 1010vivi_poll(struct file *file, struct poll_table_struct *wait)
1033{ 1011{
1034 struct vivi_dev *dev = video_drvdata(file); 1012 struct vivi_dev *dev = video_drvdata(file);
1035 struct videobuf_queue *q = &dev->vb_vidq; 1013 struct vb2_queue *q = &dev->vb_vidq;
1036 1014
1037 dprintk(dev, 1, "%s\n", __func__); 1015 dprintk(dev, 1, "%s\n", __func__);
1038 1016 return vb2_poll(q, file, wait);
1039 vivi_start_generating(file);
1040 return videobuf_poll_stream(file, q, wait);
1041} 1017}
1042 1018
1043static int vivi_close(struct file *file) 1019static int vivi_close(struct file *file)
@@ -1045,11 +1021,12 @@ static int vivi_close(struct file *file)
1045 struct video_device *vdev = video_devdata(file); 1021 struct video_device *vdev = video_devdata(file);
1046 struct vivi_dev *dev = video_drvdata(file); 1022 struct vivi_dev *dev = video_drvdata(file);
1047 1023
1048 vivi_stop_generating(file); 1024 dprintk(dev, 1, "close called (dev=%s), file %p\n",
1025 video_device_node_name(vdev), file);
1049 1026
1050 dprintk(dev, 1, "close called (dev=%s)\n", 1027 if (v4l2_fh_is_singular_file(file))
1051 video_device_node_name(vdev)); 1028 vb2_queue_release(&dev->vb_vidq);
1052 return 0; 1029 return v4l2_fh_release(file);
1053} 1030}
1054 1031
1055static int vivi_mmap(struct file *file, struct vm_area_struct *vma) 1032static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
@@ -1059,8 +1036,7 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1059 1036
1060 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma); 1037 dprintk(dev, 1, "mmap called, vma=0x%08lx\n", (unsigned long)vma);
1061 1038
1062 ret = videobuf_mmap_mapper(&dev->vb_vidq, vma); 1039 ret = vb2_mmap(&dev->vb_vidq, vma);
1063
1064 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n", 1040 dprintk(dev, 1, "vma start=0x%08lx, size=%ld, ret=%d\n",
1065 (unsigned long)vma->vm_start, 1041 (unsigned long)vma->vm_start,
1066 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start, 1042 (unsigned long)vma->vm_end - (unsigned long)vma->vm_start,
@@ -1068,8 +1044,82 @@ static int vivi_mmap(struct file *file, struct vm_area_struct *vma)
1068 return ret; 1044 return ret;
1069} 1045}
1070 1046
1047static const struct v4l2_ctrl_ops vivi_ctrl_ops = {
1048 .s_ctrl = vivi_s_ctrl,
1049};
1050
1051#define VIVI_CID_CUSTOM_BASE (V4L2_CID_USER_BASE | 0xf000)
1052
1053static const struct v4l2_ctrl_config vivi_ctrl_button = {
1054 .ops = &vivi_ctrl_ops,
1055 .id = VIVI_CID_CUSTOM_BASE + 0,
1056 .name = "Button",
1057 .type = V4L2_CTRL_TYPE_BUTTON,
1058};
1059
1060static const struct v4l2_ctrl_config vivi_ctrl_boolean = {
1061 .ops = &vivi_ctrl_ops,
1062 .id = VIVI_CID_CUSTOM_BASE + 1,
1063 .name = "Boolean",
1064 .type = V4L2_CTRL_TYPE_BOOLEAN,
1065 .min = 0,
1066 .max = 1,
1067 .step = 1,
1068 .def = 1,
1069};
1070
1071static const struct v4l2_ctrl_config vivi_ctrl_int32 = {
1072 .ops = &vivi_ctrl_ops,
1073 .id = VIVI_CID_CUSTOM_BASE + 2,
1074 .name = "Integer 32 Bits",
1075 .type = V4L2_CTRL_TYPE_INTEGER,
1076 .min = 0x80000000,
1077 .max = 0x7fffffff,
1078 .step = 1,
1079};
1080
1081static const struct v4l2_ctrl_config vivi_ctrl_int64 = {
1082 .ops = &vivi_ctrl_ops,
1083 .id = VIVI_CID_CUSTOM_BASE + 3,
1084 .name = "Integer 64 Bits",
1085 .type = V4L2_CTRL_TYPE_INTEGER64,
1086};
1087
1088static const char * const vivi_ctrl_menu_strings[] = {
1089 "Menu Item 0 (Skipped)",
1090 "Menu Item 1",
1091 "Menu Item 2 (Skipped)",
1092 "Menu Item 3",
1093 "Menu Item 4",
1094 "Menu Item 5 (Skipped)",
1095 NULL,
1096};
1097
1098static const struct v4l2_ctrl_config vivi_ctrl_menu = {
1099 .ops = &vivi_ctrl_ops,
1100 .id = VIVI_CID_CUSTOM_BASE + 4,
1101 .name = "Menu",
1102 .type = V4L2_CTRL_TYPE_MENU,
1103 .min = 1,
1104 .max = 4,
1105 .def = 3,
1106 .menu_skip_mask = 0x04,
1107 .qmenu = vivi_ctrl_menu_strings,
1108};
1109
1110static const struct v4l2_ctrl_config vivi_ctrl_string = {
1111 .ops = &vivi_ctrl_ops,
1112 .id = VIVI_CID_CUSTOM_BASE + 5,
1113 .name = "String",
1114 .type = V4L2_CTRL_TYPE_STRING,
1115 .min = 2,
1116 .max = 4,
1117 .step = 1,
1118};
1119
1071static const struct v4l2_file_operations vivi_fops = { 1120static const struct v4l2_file_operations vivi_fops = {
1072 .owner = THIS_MODULE, 1121 .owner = THIS_MODULE,
1122 .open = v4l2_fh_open,
1073 .release = vivi_close, 1123 .release = vivi_close,
1074 .read = vivi_read, 1124 .read = vivi_read,
1075 .poll = vivi_poll, 1125 .poll = vivi_poll,
@@ -1093,9 +1143,6 @@ static const struct v4l2_ioctl_ops vivi_ioctl_ops = {
1093 .vidioc_s_input = vidioc_s_input, 1143 .vidioc_s_input = vidioc_s_input,
1094 .vidioc_streamon = vidioc_streamon, 1144 .vidioc_streamon = vidioc_streamon,
1095 .vidioc_streamoff = vidioc_streamoff, 1145 .vidioc_streamoff = vidioc_streamoff,
1096 .vidioc_queryctrl = vidioc_queryctrl,
1097 .vidioc_g_ctrl = vidioc_g_ctrl,
1098 .vidioc_s_ctrl = vidioc_s_ctrl,
1099}; 1146};
1100 1147
1101static struct video_device vivi_template = { 1148static struct video_device vivi_template = {
@@ -1126,6 +1173,7 @@ static int vivi_release(void)
1126 video_device_node_name(dev->vfd)); 1173 video_device_node_name(dev->vfd));
1127 video_unregister_device(dev->vfd); 1174 video_unregister_device(dev->vfd);
1128 v4l2_device_unregister(&dev->v4l2_dev); 1175 v4l2_device_unregister(&dev->v4l2_dev);
1176 v4l2_ctrl_handler_free(&dev->ctrl_handler);
1129 kfree(dev); 1177 kfree(dev);
1130 } 1178 }
1131 1179
@@ -1136,6 +1184,8 @@ static int __init vivi_create_instance(int inst)
1136{ 1184{
1137 struct vivi_dev *dev; 1185 struct vivi_dev *dev;
1138 struct video_device *vfd; 1186 struct video_device *vfd;
1187 struct v4l2_ctrl_handler *hdl;
1188 struct vb2_queue *q;
1139 int ret; 1189 int ret;
1140 1190
1141 dev = kzalloc(sizeof(*dev), GFP_KERNEL); 1191 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
@@ -1151,20 +1201,46 @@ static int __init vivi_create_instance(int inst)
1151 dev->fmt = &formats[0]; 1201 dev->fmt = &formats[0];
1152 dev->width = 640; 1202 dev->width = 640;
1153 dev->height = 480; 1203 dev->height = 480;
1154 dev->volume = 200; 1204 hdl = &dev->ctrl_handler;
1155 dev->brightness = 127; 1205 v4l2_ctrl_handler_init(hdl, 11);
1156 dev->contrast = 16; 1206 dev->volume = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1157 dev->saturation = 127; 1207 V4L2_CID_AUDIO_VOLUME, 0, 255, 1, 200);
1158 dev->hue = 0; 1208 dev->brightness = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1209 V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
1210 dev->contrast = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1211 V4L2_CID_CONTRAST, 0, 255, 1, 16);
1212 dev->saturation = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1213 V4L2_CID_SATURATION, 0, 255, 1, 127);
1214 dev->hue = v4l2_ctrl_new_std(hdl, &vivi_ctrl_ops,
1215 V4L2_CID_HUE, -128, 127, 1, 0);
1216 dev->button = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_button, NULL);
1217 dev->int32 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int32, NULL);
1218 dev->int64 = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_int64, NULL);
1219 dev->boolean = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_boolean, NULL);
1220 dev->menu = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_menu, NULL);
1221 dev->string = v4l2_ctrl_new_custom(hdl, &vivi_ctrl_string, NULL);
1222 if (hdl->error) {
1223 ret = hdl->error;
1224 goto unreg_dev;
1225 }
1226 dev->v4l2_dev.ctrl_handler = hdl;
1159 1227
1160 /* initialize locks */ 1228 /* initialize locks */
1161 spin_lock_init(&dev->slock); 1229 spin_lock_init(&dev->slock);
1162 mutex_init(&dev->mutex);
1163 1230
1164 videobuf_queue_vmalloc_init(&dev->vb_vidq, &vivi_video_qops, 1231 /* initialize queue */
1165 NULL, &dev->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, 1232 q = &dev->vb_vidq;
1166 V4L2_FIELD_INTERLACED, 1233 memset(q, 0, sizeof(dev->vb_vidq));
1167 sizeof(struct vivi_buffer), dev, &dev->mutex); 1234 q->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1235 q->io_modes = VB2_MMAP | VB2_USERPTR | VB2_READ;
1236 q->drv_priv = dev;
1237 q->buf_struct_size = sizeof(struct vivi_buffer);
1238 q->ops = &vivi_video_qops;
1239 q->mem_ops = &vb2_vmalloc_memops;
1240
1241 vb2_queue_init(q);
1242
1243 mutex_init(&dev->mutex);
1168 1244
1169 /* init video dma queues */ 1245 /* init video dma queues */
1170 INIT_LIST_HEAD(&dev->vidq.active); 1246 INIT_LIST_HEAD(&dev->vidq.active);
@@ -1178,6 +1254,12 @@ static int __init vivi_create_instance(int inst)
1178 *vfd = vivi_template; 1254 *vfd = vivi_template;
1179 vfd->debug = debug; 1255 vfd->debug = debug;
1180 vfd->v4l2_dev = &dev->v4l2_dev; 1256 vfd->v4l2_dev = &dev->v4l2_dev;
1257 set_bit(V4L2_FL_USE_FH_PRIO, &vfd->flags);
1258
1259 /*
1260 * Provide a mutex to v4l2 core. It will be used to protect
1261 * all fops and v4l2 ioctls.
1262 */
1181 vfd->lock = &dev->mutex; 1263 vfd->lock = &dev->mutex;
1182 1264
1183 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr); 1265 ret = video_register_device(vfd, VFL_TYPE_GRABBER, video_nr);
@@ -1200,6 +1282,7 @@ static int __init vivi_create_instance(int inst)
1200rel_vdev: 1282rel_vdev:
1201 video_device_release(vfd); 1283 video_device_release(vfd);
1202unreg_dev: 1284unreg_dev:
1285 v4l2_ctrl_handler_free(hdl);
1203 v4l2_device_unregister(&dev->v4l2_dev); 1286 v4l2_device_unregister(&dev->v4l2_dev);
1204free_dev: 1287free_dev:
1205 kfree(dev); 1288 kfree(dev);
diff --git a/drivers/media/video/vpx3220.c b/drivers/media/video/vpx3220.c
index 91a01b3cdf8c..75301d10a838 100644
--- a/drivers/media/video/vpx3220.c
+++ b/drivers/media/video/vpx3220.c
@@ -28,6 +28,7 @@
28#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29#include <media/v4l2-device.h> 29#include <media/v4l2-device.h>
30#include <media/v4l2-chip-ident.h> 30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-ctrls.h>
31 32
32MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver"); 33MODULE_DESCRIPTION("vpx3220a/vpx3216b/vpx3214c video decoder driver");
33MODULE_AUTHOR("Laurent Pinchart"); 34MODULE_AUTHOR("Laurent Pinchart");
@@ -44,16 +45,13 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)");
44 45
45struct vpx3220 { 46struct vpx3220 {
46 struct v4l2_subdev sd; 47 struct v4l2_subdev sd;
48 struct v4l2_ctrl_handler hdl;
47 unsigned char reg[255]; 49 unsigned char reg[255];
48 50
49 v4l2_std_id norm; 51 v4l2_std_id norm;
50 int ident; 52 int ident;
51 int input; 53 int input;
52 int enable; 54 int enable;
53 int bright;
54 int contrast;
55 int hue;
56 int sat;
57}; 55};
58 56
59static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd) 57static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
@@ -61,6 +59,11 @@ static inline struct vpx3220 *to_vpx3220(struct v4l2_subdev *sd)
61 return container_of(sd, struct vpx3220, sd); 59 return container_of(sd, struct vpx3220, sd);
62} 60}
63 61
62static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
63{
64 return &container_of(ctrl->handler, struct vpx3220, hdl)->sd;
65}
66
64static char *inputs[] = { "internal", "composite", "svideo" }; 67static char *inputs[] = { "internal", "composite", "svideo" };
65 68
66/* ----------------------------------------------------------------------- */ 69/* ----------------------------------------------------------------------- */
@@ -417,88 +420,26 @@ static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
417 return 0; 420 return 0;
418} 421}
419 422
420static int vpx3220_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc) 423static int vpx3220_s_ctrl(struct v4l2_ctrl *ctrl)
421{
422 switch (qc->id) {
423 case V4L2_CID_BRIGHTNESS:
424 v4l2_ctrl_query_fill(qc, -128, 127, 1, 0);
425 break;
426
427 case V4L2_CID_CONTRAST:
428 v4l2_ctrl_query_fill(qc, 0, 63, 1, 32);
429 break;
430
431 case V4L2_CID_SATURATION:
432 v4l2_ctrl_query_fill(qc, 0, 4095, 1, 2048);
433 break;
434
435 case V4L2_CID_HUE:
436 v4l2_ctrl_query_fill(qc, -512, 511, 1, 0);
437 break;
438
439 default:
440 return -EINVAL;
441 }
442 return 0;
443}
444
445static int vpx3220_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
446{ 424{
447 struct vpx3220 *decoder = to_vpx3220(sd); 425 struct v4l2_subdev *sd = to_sd(ctrl);
448 426
449 switch (ctrl->id) { 427 switch (ctrl->id) {
450 case V4L2_CID_BRIGHTNESS: 428 case V4L2_CID_BRIGHTNESS:
451 ctrl->value = decoder->bright; 429 vpx3220_write(sd, 0xe6, ctrl->val);
452 break; 430 return 0;
453 case V4L2_CID_CONTRAST: 431 case V4L2_CID_CONTRAST:
454 ctrl->value = decoder->contrast; 432 /* Bit 7 and 8 is for noise shaping */
455 break; 433 vpx3220_write(sd, 0xe7, ctrl->val + 192);
434 return 0;
456 case V4L2_CID_SATURATION: 435 case V4L2_CID_SATURATION:
457 ctrl->value = decoder->sat; 436 vpx3220_fp_write(sd, 0xa0, ctrl->val);
458 break; 437 return 0;
459 case V4L2_CID_HUE: 438 case V4L2_CID_HUE:
460 ctrl->value = decoder->hue; 439 vpx3220_fp_write(sd, 0x1c, ctrl->val);
461 break; 440 return 0;
462 default:
463 return -EINVAL;
464 } 441 }
465 return 0; 442 return -EINVAL;
466}
467
468static int vpx3220_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
469{
470 struct vpx3220 *decoder = to_vpx3220(sd);
471
472 switch (ctrl->id) {
473 case V4L2_CID_BRIGHTNESS:
474 if (decoder->bright != ctrl->value) {
475 decoder->bright = ctrl->value;
476 vpx3220_write(sd, 0xe6, decoder->bright);
477 }
478 break;
479 case V4L2_CID_CONTRAST:
480 if (decoder->contrast != ctrl->value) {
481 /* Bit 7 and 8 is for noise shaping */
482 decoder->contrast = ctrl->value;
483 vpx3220_write(sd, 0xe7, decoder->contrast + 192);
484 }
485 break;
486 case V4L2_CID_SATURATION:
487 if (decoder->sat != ctrl->value) {
488 decoder->sat = ctrl->value;
489 vpx3220_fp_write(sd, 0xa0, decoder->sat);
490 }
491 break;
492 case V4L2_CID_HUE:
493 if (decoder->hue != ctrl->value) {
494 decoder->hue = ctrl->value;
495 vpx3220_fp_write(sd, 0x1c, decoder->hue);
496 }
497 break;
498 default:
499 return -EINVAL;
500 }
501 return 0;
502} 443}
503 444
504static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip) 445static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ident *chip)
@@ -511,12 +452,20 @@ static int vpx3220_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
511 452
512/* ----------------------------------------------------------------------- */ 453/* ----------------------------------------------------------------------- */
513 454
455static const struct v4l2_ctrl_ops vpx3220_ctrl_ops = {
456 .s_ctrl = vpx3220_s_ctrl,
457};
458
514static const struct v4l2_subdev_core_ops vpx3220_core_ops = { 459static const struct v4l2_subdev_core_ops vpx3220_core_ops = {
515 .g_chip_ident = vpx3220_g_chip_ident, 460 .g_chip_ident = vpx3220_g_chip_ident,
516 .init = vpx3220_init, 461 .init = vpx3220_init,
517 .g_ctrl = vpx3220_g_ctrl, 462 .g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
518 .s_ctrl = vpx3220_s_ctrl, 463 .try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
519 .queryctrl = vpx3220_queryctrl, 464 .s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
465 .g_ctrl = v4l2_subdev_g_ctrl,
466 .s_ctrl = v4l2_subdev_s_ctrl,
467 .queryctrl = v4l2_subdev_queryctrl,
468 .querymenu = v4l2_subdev_querymenu,
520 .s_std = vpx3220_s_std, 469 .s_std = vpx3220_s_std,
521}; 470};
522 471
@@ -558,10 +507,24 @@ static int vpx3220_probe(struct i2c_client *client,
558 decoder->norm = V4L2_STD_PAL; 507 decoder->norm = V4L2_STD_PAL;
559 decoder->input = 0; 508 decoder->input = 0;
560 decoder->enable = 1; 509 decoder->enable = 1;
561 decoder->bright = 32768; 510 v4l2_ctrl_handler_init(&decoder->hdl, 4);
562 decoder->contrast = 32768; 511 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
563 decoder->hue = 32768; 512 V4L2_CID_BRIGHTNESS, -128, 127, 1, 0);
564 decoder->sat = 32768; 513 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
514 V4L2_CID_CONTRAST, 0, 63, 1, 32);
515 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
516 V4L2_CID_SATURATION, 0, 4095, 1, 2048);
517 v4l2_ctrl_new_std(&decoder->hdl, &vpx3220_ctrl_ops,
518 V4L2_CID_HUE, -512, 511, 1, 0);
519 sd->ctrl_handler = &decoder->hdl;
520 if (decoder->hdl.error) {
521 int err = decoder->hdl.error;
522
523 v4l2_ctrl_handler_free(&decoder->hdl);
524 kfree(decoder);
525 return err;
526 }
527 v4l2_ctrl_handler_setup(&decoder->hdl);
565 528
566 ver = i2c_smbus_read_byte_data(client, 0x00); 529 ver = i2c_smbus_read_byte_data(client, 0x00);
567 pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) + 530 pn = (i2c_smbus_read_byte_data(client, 0x02) << 8) +
@@ -599,9 +562,11 @@ static int vpx3220_probe(struct i2c_client *client,
599static int vpx3220_remove(struct i2c_client *client) 562static int vpx3220_remove(struct i2c_client *client)
600{ 563{
601 struct v4l2_subdev *sd = i2c_get_clientdata(client); 564 struct v4l2_subdev *sd = i2c_get_clientdata(client);
565 struct vpx3220 *decoder = to_vpx3220(sd);
602 566
603 v4l2_device_unregister_subdev(sd); 567 v4l2_device_unregister_subdev(sd);
604 kfree(to_vpx3220(sd)); 568 v4l2_ctrl_handler_free(&decoder->hdl);
569 kfree(decoder);
605 return 0; 570 return 0;
606} 571}
607 572
diff --git a/drivers/media/video/wm8775.c b/drivers/media/video/wm8775.c
index fe8ef6419f83..9cedb1e69b58 100644
--- a/drivers/media/video/wm8775.c
+++ b/drivers/media/video/wm8775.c
@@ -35,6 +35,7 @@
35#include <media/v4l2-device.h> 35#include <media/v4l2-device.h>
36#include <media/v4l2-chip-ident.h> 36#include <media/v4l2-chip-ident.h>
37#include <media/v4l2-ctrls.h> 37#include <media/v4l2-ctrls.h>
38#include <media/wm8775.h>
38 39
39MODULE_DESCRIPTION("wm8775 driver"); 40MODULE_DESCRIPTION("wm8775 driver");
40MODULE_AUTHOR("Ulf Eklund, Hans Verkuil"); 41MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
@@ -50,10 +51,16 @@ enum {
50 TOT_REGS 51 TOT_REGS
51}; 52};
52 53
54#define ALC_HOLD 0x85 /* R17: use zero cross detection, ALC hold time 42.6 ms */
55#define ALC_EN 0x100 /* R17: ALC enable */
56
53struct wm8775_state { 57struct wm8775_state {
54 struct v4l2_subdev sd; 58 struct v4l2_subdev sd;
55 struct v4l2_ctrl_handler hdl; 59 struct v4l2_ctrl_handler hdl;
56 struct v4l2_ctrl *mute; 60 struct v4l2_ctrl *mute;
61 struct v4l2_ctrl *vol;
62 struct v4l2_ctrl *bal;
63 struct v4l2_ctrl *loud;
57 u8 input; /* Last selected input (0-0xf) */ 64 u8 input; /* Last selected input (0-0xf) */
58}; 65};
59 66
@@ -85,6 +92,30 @@ static int wm8775_write(struct v4l2_subdev *sd, int reg, u16 val)
85 return -1; 92 return -1;
86} 93}
87 94
95static void wm8775_set_audio(struct v4l2_subdev *sd, int quietly)
96{
97 struct wm8775_state *state = to_state(sd);
98 u8 vol_l, vol_r;
99 int muted = 0 != state->mute->val;
100 u16 volume = (u16)state->vol->val;
101 u16 balance = (u16)state->bal->val;
102
103 /* normalize ( 65535 to 0 -> 255 to 0 (+24dB to -103dB) ) */
104 vol_l = (min(65536 - balance, 32768) * volume) >> 23;
105 vol_r = (min(balance, (u16)32768) * volume) >> 23;
106
107 /* Mute */
108 if (muted || quietly)
109 wm8775_write(sd, R21, 0x0c0 | state->input);
110
111 wm8775_write(sd, R14, vol_l | 0x100); /* 0x100= Left channel ADC zero cross enable */
112 wm8775_write(sd, R15, vol_r | 0x100); /* 0x100= Right channel ADC zero cross enable */
113
114 /* Un-mute */
115 if (!muted)
116 wm8775_write(sd, R21, state->input);
117}
118
88static int wm8775_s_routing(struct v4l2_subdev *sd, 119static int wm8775_s_routing(struct v4l2_subdev *sd,
89 u32 input, u32 output, u32 config) 120 u32 input, u32 output, u32 config)
90{ 121{
@@ -102,25 +133,26 @@ static int wm8775_s_routing(struct v4l2_subdev *sd,
102 state->input = input; 133 state->input = input;
103 if (!v4l2_ctrl_g_ctrl(state->mute)) 134 if (!v4l2_ctrl_g_ctrl(state->mute))
104 return 0; 135 return 0;
105 wm8775_write(sd, R21, 0x0c0); 136 if (!v4l2_ctrl_g_ctrl(state->vol))
106 wm8775_write(sd, R14, 0x1d4); 137 return 0;
107 wm8775_write(sd, R15, 0x1d4); 138 if (!v4l2_ctrl_g_ctrl(state->bal))
108 wm8775_write(sd, R21, 0x100 + state->input); 139 return 0;
140 wm8775_set_audio(sd, 1);
109 return 0; 141 return 0;
110} 142}
111 143
112static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl) 144static int wm8775_s_ctrl(struct v4l2_ctrl *ctrl)
113{ 145{
114 struct v4l2_subdev *sd = to_sd(ctrl); 146 struct v4l2_subdev *sd = to_sd(ctrl);
115 struct wm8775_state *state = to_state(sd);
116 147
117 switch (ctrl->id) { 148 switch (ctrl->id) {
118 case V4L2_CID_AUDIO_MUTE: 149 case V4L2_CID_AUDIO_MUTE:
119 wm8775_write(sd, R21, 0x0c0); 150 case V4L2_CID_AUDIO_VOLUME:
120 wm8775_write(sd, R14, 0x1d4); 151 case V4L2_CID_AUDIO_BALANCE:
121 wm8775_write(sd, R15, 0x1d4); 152 wm8775_set_audio(sd, 0);
122 if (!ctrl->val) 153 return 0;
123 wm8775_write(sd, R21, 0x100 + state->input); 154 case V4L2_CID_AUDIO_LOUDNESS:
155 wm8775_write(sd, R17, (ctrl->val ? ALC_EN : 0) | ALC_HOLD);
124 return 0; 156 return 0;
125 } 157 }
126 return -EINVAL; 158 return -EINVAL;
@@ -144,16 +176,7 @@ static int wm8775_log_status(struct v4l2_subdev *sd)
144 176
145static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq) 177static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *freq)
146{ 178{
147 struct wm8775_state *state = to_state(sd); 179 wm8775_set_audio(sd, 0);
148
149 /* If I remove this, then it can happen that I have no
150 sound the first time I tune from static to a valid channel.
151 It's difficult to reproduce and is almost certainly related
152 to the zero cross detect circuit. */
153 wm8775_write(sd, R21, 0x0c0);
154 wm8775_write(sd, R14, 0x1d4);
155 wm8775_write(sd, R15, 0x1d4);
156 wm8775_write(sd, R21, 0x100 + state->input);
157 return 0; 180 return 0;
158} 181}
159 182
@@ -203,6 +226,13 @@ static int wm8775_probe(struct i2c_client *client,
203{ 226{
204 struct wm8775_state *state; 227 struct wm8775_state *state;
205 struct v4l2_subdev *sd; 228 struct v4l2_subdev *sd;
229 int err;
230 bool is_nova_s = false;
231
232 if (client->dev.platform_data) {
233 struct wm8775_platform_data *data = client->dev.platform_data;
234 is_nova_s = data->is_nova_s;
235 }
206 236
207 /* Check if the adapter supports the needed features */ 237 /* Check if the adapter supports the needed features */
208 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 238 if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -218,13 +248,18 @@ static int wm8775_probe(struct i2c_client *client,
218 v4l2_i2c_subdev_init(sd, client, &wm8775_ops); 248 v4l2_i2c_subdev_init(sd, client, &wm8775_ops);
219 state->input = 2; 249 state->input = 2;
220 250
221 v4l2_ctrl_handler_init(&state->hdl, 1); 251 v4l2_ctrl_handler_init(&state->hdl, 4);
222 state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops, 252 state->mute = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
223 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0); 253 V4L2_CID_AUDIO_MUTE, 0, 1, 1, 0);
254 state->vol = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
255 V4L2_CID_AUDIO_VOLUME, 0, 65535, (65535+99)/100, 0xCF00); /* 0dB*/
256 state->bal = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
257 V4L2_CID_AUDIO_BALANCE, 0, 65535, (65535+99)/100, 32768);
258 state->loud = v4l2_ctrl_new_std(&state->hdl, &wm8775_ctrl_ops,
259 V4L2_CID_AUDIO_LOUDNESS, 0, 1, 1, 1);
224 sd->ctrl_handler = &state->hdl; 260 sd->ctrl_handler = &state->hdl;
225 if (state->hdl.error) { 261 err = state->hdl.error;
226 int err = state->hdl.error; 262 if (err) {
227
228 v4l2_ctrl_handler_free(&state->hdl); 263 v4l2_ctrl_handler_free(&state->hdl);
229 kfree(state); 264 kfree(state);
230 return err; 265 return err;
@@ -236,29 +271,44 @@ static int wm8775_probe(struct i2c_client *client,
236 wm8775_write(sd, R23, 0x000); 271 wm8775_write(sd, R23, 0x000);
237 /* Disable zero cross detect timeout */ 272 /* Disable zero cross detect timeout */
238 wm8775_write(sd, R7, 0x000); 273 wm8775_write(sd, R7, 0x000);
239 /* Left justified, 24-bit mode */ 274 /* HPF enable, left justified, 24-bit (Philips) mode */
240 wm8775_write(sd, R11, 0x021); 275 wm8775_write(sd, R11, 0x021);
241 /* Master mode, clock ratio 256fs */ 276 /* Master mode, clock ratio 256fs */
242 wm8775_write(sd, R12, 0x102); 277 wm8775_write(sd, R12, 0x102);
243 /* Powered up */ 278 /* Powered up */
244 wm8775_write(sd, R13, 0x000); 279 wm8775_write(sd, R13, 0x000);
245 /* ADC gain +2.5dB, enable zero cross */ 280
246 wm8775_write(sd, R14, 0x1d4); 281 if (!is_nova_s) {
247 /* ADC gain +2.5dB, enable zero cross */ 282 /* ADC gain +2.5dB, enable zero cross */
248 wm8775_write(sd, R15, 0x1d4); 283 wm8775_write(sd, R14, 0x1d4);
249 /* ALC Stereo, ALC target level -1dB FS max gain +8dB */ 284 /* ADC gain +2.5dB, enable zero cross */
250 wm8775_write(sd, R16, 0x1bf); 285 wm8775_write(sd, R15, 0x1d4);
251 /* Enable gain control, use zero cross detection, 286 /* ALC Stereo, ALC target level -1dB FS max gain +8dB */
252 ALC hold time 42.6 ms */ 287 wm8775_write(sd, R16, 0x1bf);
253 wm8775_write(sd, R17, 0x185); 288 /* Enable gain control, use zero cross detection,
289 ALC hold time 42.6 ms */
290 wm8775_write(sd, R17, 0x185);
291 } else {
292 /* ALC stereo, ALC target level -5dB FS, ALC max gain +8dB */
293 wm8775_write(sd, R16, 0x1bb);
294 /* Set ALC mode and hold time */
295 wm8775_write(sd, R17, (state->loud->val ? ALC_EN : 0) | ALC_HOLD);
296 }
254 /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */ 297 /* ALC gain ramp up delay 34 s, ALC gain ramp down delay 33 ms */
255 wm8775_write(sd, R18, 0x0a2); 298 wm8775_write(sd, R18, 0x0a2);
256 /* Enable noise gate, threshold -72dBfs */ 299 /* Enable noise gate, threshold -72dBfs */
257 wm8775_write(sd, R19, 0x005); 300 wm8775_write(sd, R19, 0x005);
258 /* Transient window 4ms, lower PGA gain limit -1dB */ 301 if (!is_nova_s) {
259 wm8775_write(sd, R20, 0x07a); 302 /* Transient window 4ms, lower PGA gain limit -1dB */
260 /* LRBOTH = 1, use input 2. */ 303 wm8775_write(sd, R20, 0x07a);
261 wm8775_write(sd, R21, 0x102); 304 /* LRBOTH = 1, use input 2. */
305 wm8775_write(sd, R21, 0x102);
306 } else {
307 /* Transient window 4ms, ALC min gain -5dB */
308 wm8775_write(sd, R20, 0x0fb);
309
310 wm8775_set_audio(sd, 1); /* set volume/mute/mux */
311 }
262 return 0; 312 return 0;
263} 313}
264 314
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8d7d098f7a03..a9a1af49281e 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -666,7 +666,7 @@ config MFD_VX855
666 and/or vx855_gpio drivers for this to do anything useful. 666 and/or vx855_gpio drivers for this to do anything useful.
667 667
668config MFD_WL1273_CORE 668config MFD_WL1273_CORE
669 tristate 669 tristate "Support for TI WL1273 FM radio."
670 depends on I2C 670 depends on I2C
671 select MFD_CORE 671 select MFD_CORE
672 default n 672 default n
diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c
index 529d65ba5353..f76f6c798046 100644
--- a/drivers/mfd/wl1273-core.c
+++ b/drivers/mfd/wl1273-core.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * MFD driver for wl1273 FM radio and audio codec submodules. 2 * MFD driver for wl1273 FM radio and audio codec submodules.
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2011 Nokia Corporation
5 * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com> 5 * Author: Matti Aaltonen <matti.j.aaltonen@nokia.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
@@ -31,6 +31,145 @@ static struct i2c_device_id wl1273_driver_id_table[] = {
31}; 31};
32MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table); 32MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table);
33 33
34static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value)
35{
36 struct i2c_client *client = core->client;
37 u8 b[2];
38 int r;
39
40 r = i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b);
41 if (r != 2) {
42 dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg);
43 return -EREMOTEIO;
44 }
45
46 *value = (u16)b[0] << 8 | b[1];
47
48 return 0;
49}
50
51static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param)
52{
53 struct i2c_client *client = core->client;
54 u8 buf[] = { (param >> 8) & 0xff, param & 0xff };
55 int r;
56
57 r = i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf);
58 if (r) {
59 dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd);
60 return r;
61 }
62
63 return 0;
64}
65
66static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 len)
67{
68 struct i2c_client *client = core->client;
69 struct i2c_msg msg;
70 int r;
71
72 msg.addr = client->addr;
73 msg.flags = 0;
74 msg.buf = data;
75 msg.len = len;
76
77 r = i2c_transfer(client->adapter, &msg, 1);
78 if (r != 1) {
79 dev_err(&client->dev, "%s: write error.\n", __func__);
80 return -EREMOTEIO;
81 }
82
83 return 0;
84}
85
86/**
87 * wl1273_fm_set_audio() - Set audio mode.
88 * @core: A pointer to the device struct.
89 * @new_mode: The new audio mode.
90 *
91 * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG.
92 */
93static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_mode)
94{
95 int r = 0;
96
97 if (core->mode == WL1273_MODE_OFF ||
98 core->mode == WL1273_MODE_SUSPENDED)
99 return -EPERM;
100
101 if (core->mode == WL1273_MODE_RX && new_mode == WL1273_AUDIO_DIGITAL) {
102 r = wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET,
103 WL1273_PCM_DEF_MODE);
104 if (r)
105 goto out;
106
107 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
108 core->i2s_mode);
109 if (r)
110 goto out;
111
112 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
113 WL1273_AUDIO_ENABLE_I2S);
114 if (r)
115 goto out;
116
117 } else if (core->mode == WL1273_MODE_RX &&
118 new_mode == WL1273_AUDIO_ANALOG) {
119 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE,
120 WL1273_AUDIO_ENABLE_ANALOG);
121 if (r)
122 goto out;
123
124 } else if (core->mode == WL1273_MODE_TX &&
125 new_mode == WL1273_AUDIO_DIGITAL) {
126 r = wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET,
127 core->i2s_mode);
128 if (r)
129 goto out;
130
131 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
132 WL1273_AUDIO_IO_SET_I2S);
133 if (r)
134 goto out;
135
136 } else if (core->mode == WL1273_MODE_TX &&
137 new_mode == WL1273_AUDIO_ANALOG) {
138 r = wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET,
139 WL1273_AUDIO_IO_SET_ANALOG);
140 if (r)
141 goto out;
142 }
143
144 core->audio_mode = new_mode;
145out:
146 return r;
147}
148
149/**
150 * wl1273_fm_set_volume() - Set volume.
151 * @core: A pointer to the device struct.
152 * @volume: The new volume value.
153 */
154static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int volume)
155{
156 u16 val;
157 int r;
158
159 if (volume > WL1273_MAX_VOLUME)
160 return -EINVAL;
161
162 if (core->volume == volume)
163 return 0;
164
165 r = wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume);
166 if (r)
167 return r;
168
169 core->volume = volume;
170 return 0;
171}
172
34static int wl1273_core_remove(struct i2c_client *client) 173static int wl1273_core_remove(struct i2c_client *client)
35{ 174{
36 struct wl1273_core *core = i2c_get_clientdata(client); 175 struct wl1273_core *core = i2c_get_clientdata(client);
@@ -81,6 +220,12 @@ static int __devinit wl1273_core_probe(struct i2c_client *client,
81 cell->mfd_data = &core; 220 cell->mfd_data = &core;
82 children++; 221 children++;
83 222
223 core->read = wl1273_fm_read_reg;
224 core->write = wl1273_fm_write_cmd;
225 core->write_data = wl1273_fm_write_data;
226 core->set_audio = wl1273_fm_set_audio;
227 core->set_volume = wl1273_fm_set_volume;
228
84 if (pdata->children & WL1273_CODEC_CHILD) { 229 if (pdata->children & WL1273_CODEC_CHILD) {
85 cell = &core->cells[children]; 230 cell = &core->cells[children];
86 231
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ccaa2009414b..18b43fcb4171 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -55,11 +55,7 @@ source "drivers/staging/cx25821/Kconfig"
55 55
56source "drivers/staging/tm6000/Kconfig" 56source "drivers/staging/tm6000/Kconfig"
57 57
58source "drivers/staging/dabusb/Kconfig" 58source "drivers/staging/cxd2099/Kconfig"
59
60source "drivers/staging/se401/Kconfig"
61
62source "drivers/staging/usbvideo/Kconfig"
63 59
64source "drivers/staging/usbip/Kconfig" 60source "drivers/staging/usbip/Kconfig"
65 61
@@ -183,5 +179,7 @@ source "drivers/staging/ste_rmi4/Kconfig"
183 179
184source "drivers/staging/gma500/Kconfig" 180source "drivers/staging/gma500/Kconfig"
185 181
182source "drivers/staging/altera-stapl/Kconfig"
183
186endif # !STAGING_EXCLUDE_BUILD 184endif # !STAGING_EXCLUDE_BUILD
187endif # STAGING 185endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 3b223cbf86b4..cfd13cd55efb 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -10,9 +10,7 @@ obj-$(CONFIG_SLICOSS) += slicoss/
10obj-$(CONFIG_VIDEO_GO7007) += go7007/ 10obj-$(CONFIG_VIDEO_GO7007) += go7007/
11obj-$(CONFIG_VIDEO_CX25821) += cx25821/ 11obj-$(CONFIG_VIDEO_CX25821) += cx25821/
12obj-$(CONFIG_VIDEO_TM6000) += tm6000/ 12obj-$(CONFIG_VIDEO_TM6000) += tm6000/
13obj-$(CONFIG_USB_DABUSB) += dabusb/ 13obj-$(CONFIG_DVB_CXD2099) += cxd2099/
14obj-$(CONFIG_USB_VICAM) += usbvideo/
15obj-$(CONFIG_USB_SE401) += se401/
16obj-$(CONFIG_LIRC_STAGING) += lirc/ 14obj-$(CONFIG_LIRC_STAGING) += lirc/
17obj-$(CONFIG_USB_IP_COMMON) += usbip/ 15obj-$(CONFIG_USB_IP_COMMON) += usbip/
18obj-$(CONFIG_W35UND) += winbond/ 16obj-$(CONFIG_W35UND) += winbond/
@@ -70,6 +68,7 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/
70obj-$(CONFIG_FT1000) += ft1000/ 68obj-$(CONFIG_FT1000) += ft1000/
71obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ 69obj-$(CONFIG_SND_INTEL_SST) += intel_sst/
72obj-$(CONFIG_SPEAKUP) += speakup/ 70obj-$(CONFIG_SPEAKUP) += speakup/
71obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
73obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ 72obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/
74obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ 73obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/
75obj-$(CONFIG_DRM_PSB) += gma500/ 74obj-$(CONFIG_DRM_PSB) += gma500/
diff --git a/drivers/staging/altera-stapl/Kconfig b/drivers/staging/altera-stapl/Kconfig
new file mode 100644
index 000000000000..7f01d8e93992
--- /dev/null
+++ b/drivers/staging/altera-stapl/Kconfig
@@ -0,0 +1,8 @@
1comment "Altera FPGA firmware download module"
2
3config ALTERA_STAPL
4 tristate "Altera FPGA firmware download module"
5 depends on I2C
6 default n
7 help
8 An Altera FPGA module. Say Y when you want to support this tool.
diff --git a/drivers/staging/altera-stapl/Makefile b/drivers/staging/altera-stapl/Makefile
new file mode 100644
index 000000000000..055f61ee781a
--- /dev/null
+++ b/drivers/staging/altera-stapl/Makefile
@@ -0,0 +1,3 @@
1altera-stapl-objs = altera-lpt.o altera-jtag.o altera-comp.o altera.o
2
3obj-$(CONFIG_ALTERA_STAPL) += altera-stapl.o
diff --git a/drivers/staging/altera-stapl/altera-comp.c b/drivers/staging/altera-stapl/altera-comp.c
new file mode 100644
index 000000000000..49b103bedaaf
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-comp.c
@@ -0,0 +1,142 @@
1/*
2 * altera-comp.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/kernel.h>
27#include "altera-exprt.h"
28
29#define SHORT_BITS 16
30#define CHAR_BITS 8
31#define DATA_BLOB_LENGTH 3
32#define MATCH_DATA_LENGTH 8192
33#define ALTERA_REQUEST_SIZE 1024
34#define ALTERA_BUFFER_SIZE (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE)
35
36static u32 altera_bits_req(u32 n)
37{
38 u32 result = SHORT_BITS;
39
40 if (n == 0)
41 result = 1;
42 else {
43 /* Look for the highest non-zero bit position */
44 while ((n & (1 << (SHORT_BITS - 1))) == 0) {
45 n <<= 1;
46 --result;
47 }
48 }
49
50 return result;
51}
52
53static u32 altera_read_packed(u8 *buffer, u32 bits, u32 *bits_avail,
54 u32 *in_index)
55{
56 u32 result = 0;
57 u32 shift = 0;
58 u32 databyte = 0;
59
60 while (bits > 0) {
61 databyte = buffer[*in_index];
62 result |= (((databyte >> (CHAR_BITS - *bits_avail))
63 & (0xff >> (CHAR_BITS - *bits_avail))) << shift);
64
65 if (bits <= *bits_avail) {
66 result &= (0xffff >> (SHORT_BITS - (bits + shift)));
67 *bits_avail -= bits;
68 bits = 0;
69 } else {
70 ++(*in_index);
71 shift += *bits_avail;
72 bits -= *bits_avail;
73 *bits_avail = CHAR_BITS;
74 }
75 }
76
77 return result;
78}
79
80u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version)
81{
82 u32 i, j, data_length = 0L;
83 u32 offset, length;
84 u32 match_data_length = MATCH_DATA_LENGTH;
85 u32 bits_avail = CHAR_BITS;
86 u32 in_index = 0L;
87
88 if (version > 0)
89 --match_data_length;
90
91 for (i = 0; i < out_length; ++i)
92 out[i] = 0;
93
94 /* Read number of bytes in data. */
95 for (i = 0; i < sizeof(in_length); ++i) {
96 data_length = data_length | (
97 altera_read_packed(in,
98 CHAR_BITS,
99 &bits_avail,
100 &in_index) << (i * CHAR_BITS));
101 }
102
103 if (data_length > out_length) {
104 data_length = 0L;
105 return data_length;
106 }
107
108 i = 0;
109 while (i < data_length) {
110 /* A 0 bit indicates literal data. */
111 if (altera_read_packed(in, 1, &bits_avail,
112 &in_index) == 0) {
113 for (j = 0; j < DATA_BLOB_LENGTH; ++j) {
114 if (i < data_length) {
115 out[i] = (u8)altera_read_packed(in,
116 CHAR_BITS,
117 &bits_avail,
118 &in_index);
119 i++;
120 }
121 }
122 } else {
123 /* A 1 bit indicates offset/length to follow. */
124 offset = altera_read_packed(in, altera_bits_req((s16)
125 (i > match_data_length ?
126 match_data_length : i)),
127 &bits_avail,
128 &in_index);
129 length = altera_read_packed(in, CHAR_BITS,
130 &bits_avail,
131 &in_index);
132 for (j = 0; j < length; ++j) {
133 if (i < data_length) {
134 out[i] = out[i - offset];
135 i++;
136 }
137 }
138 }
139 }
140
141 return data_length;
142}
diff --git a/drivers/staging/altera-stapl/altera-exprt.h b/drivers/staging/altera-stapl/altera-exprt.h
new file mode 100644
index 000000000000..39c38d84a670
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-exprt.h
@@ -0,0 +1,33 @@
1/*
2 * altera-exprt.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef ALTERA_EXPRT_H
27#define ALTERA_EXPRT_H
28
29
30u32 altera_shrink(u8 *in, u32 in_length, u8 *out, u32 out_length, s32 version);
31int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo);
32
33#endif /* ALTERA_EXPRT_H */
diff --git a/drivers/staging/altera-stapl/altera-jtag.c b/drivers/staging/altera-stapl/altera-jtag.c
new file mode 100644
index 000000000000..6b633b179a7e
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-jtag.c
@@ -0,0 +1,1020 @@
1/*
2 * altera-jtag.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/firmware.h>
27#include <linux/slab.h>
28#include <staging/altera.h>
29#include "altera-exprt.h"
30#include "altera-jtag.h"
31
32#define alt_jtag_io(a, b, c)\
33 astate->config->jtag_io(astate->config->dev, a, b, c);
34
35#define alt_malloc(a) kzalloc(a, GFP_KERNEL);
36
37/*
38 * This structure shows, for each JTAG state, which state is reached after
39 * a single TCK clock cycle with TMS high or TMS low, respectively. This
40 * describes all possible state transitions in the JTAG state machine.
41 */
42struct altera_jtag_machine {
43 enum altera_jtag_state tms_high;
44 enum altera_jtag_state tms_low;
45};
46
47static const struct altera_jtag_machine altera_transitions[] = {
48 /* RESET */ { RESET, IDLE },
49 /* IDLE */ { DRSELECT, IDLE },
50 /* DRSELECT */ { IRSELECT, DRCAPTURE },
51 /* DRCAPTURE */ { DREXIT1, DRSHIFT },
52 /* DRSHIFT */ { DREXIT1, DRSHIFT },
53 /* DREXIT1 */ { DRUPDATE, DRPAUSE },
54 /* DRPAUSE */ { DREXIT2, DRPAUSE },
55 /* DREXIT2 */ { DRUPDATE, DRSHIFT },
56 /* DRUPDATE */ { DRSELECT, IDLE },
57 /* IRSELECT */ { RESET, IRCAPTURE },
58 /* IRCAPTURE */ { IREXIT1, IRSHIFT },
59 /* IRSHIFT */ { IREXIT1, IRSHIFT },
60 /* IREXIT1 */ { IRUPDATE, IRPAUSE },
61 /* IRPAUSE */ { IREXIT2, IRPAUSE },
62 /* IREXIT2 */ { IRUPDATE, IRSHIFT },
63 /* IRUPDATE */ { DRSELECT, IDLE }
64};
65
66/*
67 * This table contains the TMS value to be used to take the NEXT STEP on
68 * the path to the desired state. The array index is the current state,
69 * and the bit position is the desired endstate. To find out which state
70 * is used as the intermediate state, look up the TMS value in the
71 * altera_transitions[] table.
72 */
73static const u16 altera_jtag_path_map[16] = {
74 /* RST RTI SDRS CDR SDR E1DR PDR E2DR */
75 0x0001, 0xFFFD, 0xFE01, 0xFFE7, 0xFFEF, 0xFF0F, 0xFFBF, 0xFFFF,
76 /* UDR SIRS CIR SIR E1IR PIR E2IR UIR */
77 0xFEFD, 0x0001, 0xF3FF, 0xF7FF, 0x87FF, 0xDFFF, 0xFFFF, 0x7FFD
78};
79
80/* Flag bits for alt_jtag_io() function */
81#define TMS_HIGH 1
82#define TMS_LOW 0
83#define TDI_HIGH 1
84#define TDI_LOW 0
85#define READ_TDO 1
86#define IGNORE_TDO 0
87
88int altera_jinit(struct altera_state *astate)
89{
90 struct altera_jtag *js = &astate->js;
91
92 /* initial JTAG state is unknown */
93 js->jtag_state = ILLEGAL_JTAG_STATE;
94
95 /* initialize to default state */
96 js->drstop_state = IDLE;
97 js->irstop_state = IDLE;
98 js->dr_pre = 0;
99 js->dr_post = 0;
100 js->ir_pre = 0;
101 js->ir_post = 0;
102 js->dr_length = 0;
103 js->ir_length = 0;
104
105 js->dr_pre_data = NULL;
106 js->dr_post_data = NULL;
107 js->ir_pre_data = NULL;
108 js->ir_post_data = NULL;
109 js->dr_buffer = NULL;
110 js->ir_buffer = NULL;
111
112 return 0;
113}
114
115int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state)
116{
117 js->drstop_state = state;
118
119 return 0;
120}
121
122int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state)
123{
124 js->irstop_state = state;
125
126 return 0;
127}
128
129int altera_set_dr_pre(struct altera_jtag *js,
130 u32 count, u32 start_index,
131 u8 *preamble_data)
132{
133 int status = 0;
134 u32 i;
135 u32 j;
136
137 if (count > js->dr_pre) {
138 kfree(js->dr_pre_data);
139 js->dr_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
140 if (js->dr_pre_data == NULL)
141 status = -ENOMEM;
142 else
143 js->dr_pre = count;
144 } else
145 js->dr_pre = count;
146
147 if (status == 0) {
148 for (i = 0; i < count; ++i) {
149 j = i + start_index;
150
151 if (preamble_data == NULL)
152 js->dr_pre_data[i >> 3] |= (1 << (i & 7));
153 else {
154 if (preamble_data[j >> 3] & (1 << (j & 7)))
155 js->dr_pre_data[i >> 3] |=
156 (1 << (i & 7));
157 else
158 js->dr_pre_data[i >> 3] &=
159 ~(u32)(1 << (i & 7));
160
161 }
162 }
163 }
164
165 return status;
166}
167
168int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
169 u8 *preamble_data)
170{
171 int status = 0;
172 u32 i;
173 u32 j;
174
175 if (count > js->ir_pre) {
176 kfree(js->ir_pre_data);
177 js->ir_pre_data = (u8 *)alt_malloc((count + 7) >> 3);
178 if (js->ir_pre_data == NULL)
179 status = -ENOMEM;
180 else
181 js->ir_pre = count;
182
183 } else
184 js->ir_pre = count;
185
186 if (status == 0) {
187 for (i = 0; i < count; ++i) {
188 j = i + start_index;
189 if (preamble_data == NULL)
190 js->ir_pre_data[i >> 3] |= (1 << (i & 7));
191 else {
192 if (preamble_data[j >> 3] & (1 << (j & 7)))
193 js->ir_pre_data[i >> 3] |=
194 (1 << (i & 7));
195 else
196 js->ir_pre_data[i >> 3] &=
197 ~(u32)(1 << (i & 7));
198
199 }
200 }
201 }
202
203 return status;
204}
205
206int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
207 u8 *postamble_data)
208{
209 int status = 0;
210 u32 i;
211 u32 j;
212
213 if (count > js->dr_post) {
214 kfree(js->dr_post_data);
215 js->dr_post_data = (u8 *)alt_malloc((count + 7) >> 3);
216
217 if (js->dr_post_data == NULL)
218 status = -ENOMEM;
219 else
220 js->dr_post = count;
221
222 } else
223 js->dr_post = count;
224
225 if (status == 0) {
226 for (i = 0; i < count; ++i) {
227 j = i + start_index;
228
229 if (postamble_data == NULL)
230 js->dr_post_data[i >> 3] |= (1 << (i & 7));
231 else {
232 if (postamble_data[j >> 3] & (1 << (j & 7)))
233 js->dr_post_data[i >> 3] |=
234 (1 << (i & 7));
235 else
236 js->dr_post_data[i >> 3] &=
237 ~(u32)(1 << (i & 7));
238
239 }
240 }
241 }
242
243 return status;
244}
245
246int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
247 u8 *postamble_data)
248{
249 int status = 0;
250 u32 i;
251 u32 j;
252
253 if (count > js->ir_post) {
254 kfree(js->ir_post_data);
255 js->ir_post_data = (u8 *)alt_malloc((count + 7) >> 3);
256 if (js->ir_post_data == NULL)
257 status = -ENOMEM;
258 else
259 js->ir_post = count;
260
261 } else
262 js->ir_post = count;
263
264 if (status != 0)
265 return status;
266
267 for (i = 0; i < count; ++i) {
268 j = i + start_index;
269
270 if (postamble_data == NULL)
271 js->ir_post_data[i >> 3] |= (1 << (i & 7));
272 else {
273 if (postamble_data[j >> 3] & (1 << (j & 7)))
274 js->ir_post_data[i >> 3] |= (1 << (i & 7));
275 else
276 js->ir_post_data[i >> 3] &=
277 ~(u32)(1 << (i & 7));
278
279 }
280 }
281
282 return status;
283}
284
285static void altera_jreset_idle(struct altera_state *astate)
286{
287 struct altera_jtag *js = &astate->js;
288 int i;
289 /* Go to Test Logic Reset (no matter what the starting state may be) */
290 for (i = 0; i < 5; ++i)
291 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
292
293 /* Now step to Run Test / Idle */
294 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
295 js->jtag_state = IDLE;
296}
297
298int altera_goto_jstate(struct altera_state *astate,
299 enum altera_jtag_state state)
300{
301 struct altera_jtag *js = &astate->js;
302 int tms;
303 int count = 0;
304 int status = 0;
305
306 if (js->jtag_state == ILLEGAL_JTAG_STATE)
307 /* initialize JTAG chain to known state */
308 altera_jreset_idle(astate);
309
310 if (js->jtag_state == state) {
311 /*
312 * We are already in the desired state.
313 * If it is a stable state, loop here.
314 * Otherwise do nothing (no clock cycles).
315 */
316 if ((state == IDLE) || (state == DRSHIFT) ||
317 (state == DRPAUSE) || (state == IRSHIFT) ||
318 (state == IRPAUSE)) {
319 alt_jtag_io(TMS_LOW, TDI_LOW, IGNORE_TDO);
320 } else if (state == RESET)
321 alt_jtag_io(TMS_HIGH, TDI_LOW, IGNORE_TDO);
322
323 } else {
324 while ((js->jtag_state != state) && (count < 9)) {
325 /* Get TMS value to take a step toward desired state */
326 tms = (altera_jtag_path_map[js->jtag_state] &
327 (1 << state))
328 ? TMS_HIGH : TMS_LOW;
329
330 /* Take a step */
331 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
332
333 if (tms)
334 js->jtag_state =
335 altera_transitions[js->jtag_state].tms_high;
336 else
337 js->jtag_state =
338 altera_transitions[js->jtag_state].tms_low;
339
340 ++count;
341 }
342 }
343
344 if (js->jtag_state != state)
345 status = -EREMOTEIO;
346
347 return status;
348}
349
350int altera_wait_cycles(struct altera_state *astate,
351 s32 cycles,
352 enum altera_jtag_state wait_state)
353{
354 struct altera_jtag *js = &astate->js;
355 int tms;
356 s32 count;
357 int status = 0;
358
359 if (js->jtag_state != wait_state)
360 status = altera_goto_jstate(astate, wait_state);
361
362 if (status == 0) {
363 /*
364 * Set TMS high to loop in RESET state
365 * Set TMS low to loop in any other stable state
366 */
367 tms = (wait_state == RESET) ? TMS_HIGH : TMS_LOW;
368
369 for (count = 0L; count < cycles; count++)
370 alt_jtag_io(tms, TDI_LOW, IGNORE_TDO);
371
372 }
373
374 return status;
375}
376
377int altera_wait_msecs(struct altera_state *astate,
378 s32 microseconds, enum altera_jtag_state wait_state)
379/*
380 * Causes JTAG hardware to sit in the specified stable
381 * state for the specified duration of real time. If
382 * no JTAG operations have been performed yet, then only
383 * a delay is performed. This permits the WAIT USECS
384 * statement to be used in VECTOR programs without causing
385 * any JTAG operations.
386 * Returns 0 for success, else appropriate error code.
387 */
388{
389 struct altera_jtag *js = &astate->js;
390 int status = 0;
391
392 if ((js->jtag_state != ILLEGAL_JTAG_STATE) &&
393 (js->jtag_state != wait_state))
394 status = altera_goto_jstate(astate, wait_state);
395
396 if (status == 0)
397 /* Wait for specified time interval */
398 udelay(microseconds);
399
400 return status;
401}
402
403static void altera_concatenate_data(u8 *buffer,
404 u8 *preamble_data,
405 u32 preamble_count,
406 u8 *target_data,
407 u32 start_index,
408 u32 target_count,
409 u8 *postamble_data,
410 u32 postamble_count)
411/*
412 * Copies preamble data, target data, and postamble data
413 * into one buffer for IR or DR scans.
414 */
415{
416 u32 i, j, k;
417
418 for (i = 0L; i < preamble_count; ++i) {
419 if (preamble_data[i >> 3L] & (1L << (i & 7L)))
420 buffer[i >> 3L] |= (1L << (i & 7L));
421 else
422 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
423
424 }
425
426 j = start_index;
427 k = preamble_count + target_count;
428 for (; i < k; ++i, ++j) {
429 if (target_data[j >> 3L] & (1L << (j & 7L)))
430 buffer[i >> 3L] |= (1L << (i & 7L));
431 else
432 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
433
434 }
435
436 j = 0L;
437 k = preamble_count + target_count + postamble_count;
438 for (; i < k; ++i, ++j) {
439 if (postamble_data[j >> 3L] & (1L << (j & 7L)))
440 buffer[i >> 3L] |= (1L << (i & 7L));
441 else
442 buffer[i >> 3L] &= ~(u32)(1L << (i & 7L));
443
444 }
445}
446
447static int alt_jtag_drscan(struct altera_state *astate,
448 int start_state,
449 int count,
450 u8 *tdi,
451 u8 *tdo)
452{
453 int i = 0;
454 int tdo_bit = 0;
455 int status = 1;
456
457 /* First go to DRSHIFT state */
458 switch (start_state) {
459 case 0: /* IDLE */
460 alt_jtag_io(1, 0, 0); /* DRSELECT */
461 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
462 alt_jtag_io(0, 0, 0); /* DRSHIFT */
463 break;
464
465 case 1: /* DRPAUSE */
466 alt_jtag_io(1, 0, 0); /* DREXIT2 */
467 alt_jtag_io(1, 0, 0); /* DRUPDATE */
468 alt_jtag_io(1, 0, 0); /* DRSELECT */
469 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
470 alt_jtag_io(0, 0, 0); /* DRSHIFT */
471 break;
472
473 case 2: /* IRPAUSE */
474 alt_jtag_io(1, 0, 0); /* IREXIT2 */
475 alt_jtag_io(1, 0, 0); /* IRUPDATE */
476 alt_jtag_io(1, 0, 0); /* DRSELECT */
477 alt_jtag_io(0, 0, 0); /* DRCAPTURE */
478 alt_jtag_io(0, 0, 0); /* DRSHIFT */
479 break;
480
481 default:
482 status = 0;
483 }
484
485 if (status) {
486 /* loop in the SHIFT-DR state */
487 for (i = 0; i < count; i++) {
488 tdo_bit = alt_jtag_io(
489 (i == count - 1),
490 tdi[i >> 3] & (1 << (i & 7)),
491 (tdo != NULL));
492
493 if (tdo != NULL) {
494 if (tdo_bit)
495 tdo[i >> 3] |= (1 << (i & 7));
496 else
497 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
498
499 }
500 }
501
502 alt_jtag_io(0, 0, 0); /* DRPAUSE */
503 }
504
505 return status;
506}
507
508static int alt_jtag_irscan(struct altera_state *astate,
509 int start_state,
510 int count,
511 u8 *tdi,
512 u8 *tdo)
513{
514 int i = 0;
515 int tdo_bit = 0;
516 int status = 1;
517
518 /* First go to IRSHIFT state */
519 switch (start_state) {
520 case 0: /* IDLE */
521 alt_jtag_io(1, 0, 0); /* DRSELECT */
522 alt_jtag_io(1, 0, 0); /* IRSELECT */
523 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
524 alt_jtag_io(0, 0, 0); /* IRSHIFT */
525 break;
526
527 case 1: /* DRPAUSE */
528 alt_jtag_io(1, 0, 0); /* DREXIT2 */
529 alt_jtag_io(1, 0, 0); /* DRUPDATE */
530 alt_jtag_io(1, 0, 0); /* DRSELECT */
531 alt_jtag_io(1, 0, 0); /* IRSELECT */
532 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
533 alt_jtag_io(0, 0, 0); /* IRSHIFT */
534 break;
535
536 case 2: /* IRPAUSE */
537 alt_jtag_io(1, 0, 0); /* IREXIT2 */
538 alt_jtag_io(1, 0, 0); /* IRUPDATE */
539 alt_jtag_io(1, 0, 0); /* DRSELECT */
540 alt_jtag_io(1, 0, 0); /* IRSELECT */
541 alt_jtag_io(0, 0, 0); /* IRCAPTURE */
542 alt_jtag_io(0, 0, 0); /* IRSHIFT */
543 break;
544
545 default:
546 status = 0;
547 }
548
549 if (status) {
550 /* loop in the SHIFT-IR state */
551 for (i = 0; i < count; i++) {
552 tdo_bit = alt_jtag_io(
553 (i == count - 1),
554 tdi[i >> 3] & (1 << (i & 7)),
555 (tdo != NULL));
556 if (tdo != NULL) {
557 if (tdo_bit)
558 tdo[i >> 3] |= (1 << (i & 7));
559 else
560 tdo[i >> 3] &= ~(u32)(1 << (i & 7));
561
562 }
563 }
564
565 alt_jtag_io(0, 0, 0); /* IRPAUSE */
566 }
567
568 return status;
569}
570
571static void altera_extract_target_data(u8 *buffer,
572 u8 *target_data,
573 u32 start_index,
574 u32 preamble_count,
575 u32 target_count)
576/*
577 * Copies target data from scan buffer, filtering out
578 * preamble and postamble data.
579 */
580{
581 u32 i;
582 u32 j;
583 u32 k;
584
585 j = preamble_count;
586 k = start_index + target_count;
587 for (i = start_index; i < k; ++i, ++j) {
588 if (buffer[j >> 3] & (1 << (j & 7)))
589 target_data[i >> 3] |= (1 << (i & 7));
590 else
591 target_data[i >> 3] &= ~(u32)(1 << (i & 7));
592
593 }
594}
595
596int altera_irscan(struct altera_state *astate,
597 u32 count,
598 u8 *tdi_data,
599 u32 start_index)
600/* Shifts data into instruction register */
601{
602 struct altera_jtag *js = &astate->js;
603 int start_code = 0;
604 u32 alloc_chars = 0;
605 u32 shift_count = js->ir_pre + count + js->ir_post;
606 int status = 0;
607 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
608
609 switch (js->jtag_state) {
610 case ILLEGAL_JTAG_STATE:
611 case RESET:
612 case IDLE:
613 start_code = 0;
614 start_state = IDLE;
615 break;
616
617 case DRSELECT:
618 case DRCAPTURE:
619 case DRSHIFT:
620 case DREXIT1:
621 case DRPAUSE:
622 case DREXIT2:
623 case DRUPDATE:
624 start_code = 1;
625 start_state = DRPAUSE;
626 break;
627
628 case IRSELECT:
629 case IRCAPTURE:
630 case IRSHIFT:
631 case IREXIT1:
632 case IRPAUSE:
633 case IREXIT2:
634 case IRUPDATE:
635 start_code = 2;
636 start_state = IRPAUSE;
637 break;
638
639 default:
640 status = -EREMOTEIO;
641 break;
642 }
643
644 if (status == 0)
645 if (js->jtag_state != start_state)
646 status = altera_goto_jstate(astate, start_state);
647
648 if (status == 0) {
649 if (shift_count > js->ir_length) {
650 alloc_chars = (shift_count + 7) >> 3;
651 kfree(js->ir_buffer);
652 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
653 if (js->ir_buffer == NULL)
654 status = -ENOMEM;
655 else
656 js->ir_length = alloc_chars * 8;
657
658 }
659 }
660
661 if (status == 0) {
662 /*
663 * Copy preamble data, IR data,
664 * and postamble data into a buffer
665 */
666 altera_concatenate_data(js->ir_buffer,
667 js->ir_pre_data,
668 js->ir_pre,
669 tdi_data,
670 start_index,
671 count,
672 js->ir_post_data,
673 js->ir_post);
674 /* Do the IRSCAN */
675 alt_jtag_irscan(astate,
676 start_code,
677 shift_count,
678 js->ir_buffer,
679 NULL);
680
681 /* alt_jtag_irscan() always ends in IRPAUSE state */
682 js->jtag_state = IRPAUSE;
683 }
684
685 if (status == 0)
686 if (js->irstop_state != IRPAUSE)
687 status = altera_goto_jstate(astate, js->irstop_state);
688
689
690 return status;
691}
692
693int altera_swap_ir(struct altera_state *astate,
694 u32 count,
695 u8 *in_data,
696 u32 in_index,
697 u8 *out_data,
698 u32 out_index)
699/* Shifts data into instruction register, capturing output data */
700{
701 struct altera_jtag *js = &astate->js;
702 int start_code = 0;
703 u32 alloc_chars = 0;
704 u32 shift_count = js->ir_pre + count + js->ir_post;
705 int status = 0;
706 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
707
708 switch (js->jtag_state) {
709 case ILLEGAL_JTAG_STATE:
710 case RESET:
711 case IDLE:
712 start_code = 0;
713 start_state = IDLE;
714 break;
715
716 case DRSELECT:
717 case DRCAPTURE:
718 case DRSHIFT:
719 case DREXIT1:
720 case DRPAUSE:
721 case DREXIT2:
722 case DRUPDATE:
723 start_code = 1;
724 start_state = DRPAUSE;
725 break;
726
727 case IRSELECT:
728 case IRCAPTURE:
729 case IRSHIFT:
730 case IREXIT1:
731 case IRPAUSE:
732 case IREXIT2:
733 case IRUPDATE:
734 start_code = 2;
735 start_state = IRPAUSE;
736 break;
737
738 default:
739 status = -EREMOTEIO;
740 break;
741 }
742
743 if (status == 0)
744 if (js->jtag_state != start_state)
745 status = altera_goto_jstate(astate, start_state);
746
747 if (status == 0) {
748 if (shift_count > js->ir_length) {
749 alloc_chars = (shift_count + 7) >> 3;
750 kfree(js->ir_buffer);
751 js->ir_buffer = (u8 *)alt_malloc(alloc_chars);
752 if (js->ir_buffer == NULL)
753 status = -ENOMEM;
754 else
755 js->ir_length = alloc_chars * 8;
756
757 }
758 }
759
760 if (status == 0) {
761 /*
762 * Copy preamble data, IR data,
763 * and postamble data into a buffer
764 */
765 altera_concatenate_data(js->ir_buffer,
766 js->ir_pre_data,
767 js->ir_pre,
768 in_data,
769 in_index,
770 count,
771 js->ir_post_data,
772 js->ir_post);
773
774 /* Do the IRSCAN */
775 alt_jtag_irscan(astate,
776 start_code,
777 shift_count,
778 js->ir_buffer,
779 js->ir_buffer);
780
781 /* alt_jtag_irscan() always ends in IRPAUSE state */
782 js->jtag_state = IRPAUSE;
783 }
784
785 if (status == 0)
786 if (js->irstop_state != IRPAUSE)
787 status = altera_goto_jstate(astate, js->irstop_state);
788
789
790 if (status == 0)
791 /* Now extract the returned data from the buffer */
792 altera_extract_target_data(js->ir_buffer,
793 out_data, out_index,
794 js->ir_pre, count);
795
796 return status;
797}
798
799int altera_drscan(struct altera_state *astate,
800 u32 count,
801 u8 *tdi_data,
802 u32 start_index)
803/* Shifts data into data register (ignoring output data) */
804{
805 struct altera_jtag *js = &astate->js;
806 int start_code = 0;
807 u32 alloc_chars = 0;
808 u32 shift_count = js->dr_pre + count + js->dr_post;
809 int status = 0;
810 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
811
812 switch (js->jtag_state) {
813 case ILLEGAL_JTAG_STATE:
814 case RESET:
815 case IDLE:
816 start_code = 0;
817 start_state = IDLE;
818 break;
819
820 case DRSELECT:
821 case DRCAPTURE:
822 case DRSHIFT:
823 case DREXIT1:
824 case DRPAUSE:
825 case DREXIT2:
826 case DRUPDATE:
827 start_code = 1;
828 start_state = DRPAUSE;
829 break;
830
831 case IRSELECT:
832 case IRCAPTURE:
833 case IRSHIFT:
834 case IREXIT1:
835 case IRPAUSE:
836 case IREXIT2:
837 case IRUPDATE:
838 start_code = 2;
839 start_state = IRPAUSE;
840 break;
841
842 default:
843 status = -EREMOTEIO;
844 break;
845 }
846
847 if (status == 0)
848 if (js->jtag_state != start_state)
849 status = altera_goto_jstate(astate, start_state);
850
851 if (status == 0) {
852 if (shift_count > js->dr_length) {
853 alloc_chars = (shift_count + 7) >> 3;
854 kfree(js->dr_buffer);
855 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
856 if (js->dr_buffer == NULL)
857 status = -ENOMEM;
858 else
859 js->dr_length = alloc_chars * 8;
860
861 }
862 }
863
864 if (status == 0) {
865 /*
866 * Copy preamble data, DR data,
867 * and postamble data into a buffer
868 */
869 altera_concatenate_data(js->dr_buffer,
870 js->dr_pre_data,
871 js->dr_pre,
872 tdi_data,
873 start_index,
874 count,
875 js->dr_post_data,
876 js->dr_post);
877 /* Do the DRSCAN */
878 alt_jtag_drscan(astate, start_code, shift_count,
879 js->dr_buffer, NULL);
880 /* alt_jtag_drscan() always ends in DRPAUSE state */
881 js->jtag_state = DRPAUSE;
882 }
883
884 if (status == 0)
885 if (js->drstop_state != DRPAUSE)
886 status = altera_goto_jstate(astate, js->drstop_state);
887
888 return status;
889}
890
891int altera_swap_dr(struct altera_state *astate, u32 count,
892 u8 *in_data, u32 in_index,
893 u8 *out_data, u32 out_index)
894/* Shifts data into data register, capturing output data */
895{
896 struct altera_jtag *js = &astate->js;
897 int start_code = 0;
898 u32 alloc_chars = 0;
899 u32 shift_count = js->dr_pre + count + js->dr_post;
900 int status = 0;
901 enum altera_jtag_state start_state = ILLEGAL_JTAG_STATE;
902
903 switch (js->jtag_state) {
904 case ILLEGAL_JTAG_STATE:
905 case RESET:
906 case IDLE:
907 start_code = 0;
908 start_state = IDLE;
909 break;
910
911 case DRSELECT:
912 case DRCAPTURE:
913 case DRSHIFT:
914 case DREXIT1:
915 case DRPAUSE:
916 case DREXIT2:
917 case DRUPDATE:
918 start_code = 1;
919 start_state = DRPAUSE;
920 break;
921
922 case IRSELECT:
923 case IRCAPTURE:
924 case IRSHIFT:
925 case IREXIT1:
926 case IRPAUSE:
927 case IREXIT2:
928 case IRUPDATE:
929 start_code = 2;
930 start_state = IRPAUSE;
931 break;
932
933 default:
934 status = -EREMOTEIO;
935 break;
936 }
937
938 if (status == 0)
939 if (js->jtag_state != start_state)
940 status = altera_goto_jstate(astate, start_state);
941
942 if (status == 0) {
943 if (shift_count > js->dr_length) {
944 alloc_chars = (shift_count + 7) >> 3;
945 kfree(js->dr_buffer);
946 js->dr_buffer = (u8 *)alt_malloc(alloc_chars);
947
948 if (js->dr_buffer == NULL)
949 status = -ENOMEM;
950 else
951 js->dr_length = alloc_chars * 8;
952
953 }
954 }
955
956 if (status == 0) {
957 /*
958 * Copy preamble data, DR data,
959 * and postamble data into a buffer
960 */
961 altera_concatenate_data(js->dr_buffer,
962 js->dr_pre_data,
963 js->dr_pre,
964 in_data,
965 in_index,
966 count,
967 js->dr_post_data,
968 js->dr_post);
969
970 /* Do the DRSCAN */
971 alt_jtag_drscan(astate,
972 start_code,
973 shift_count,
974 js->dr_buffer,
975 js->dr_buffer);
976
977 /* alt_jtag_drscan() always ends in DRPAUSE state */
978 js->jtag_state = DRPAUSE;
979 }
980
981 if (status == 0)
982 if (js->drstop_state != DRPAUSE)
983 status = altera_goto_jstate(astate, js->drstop_state);
984
985 if (status == 0)
986 /* Now extract the returned data from the buffer */
987 altera_extract_target_data(js->dr_buffer,
988 out_data,
989 out_index,
990 js->dr_pre,
991 count);
992
993 return status;
994}
995
996void altera_free_buffers(struct altera_state *astate)
997{
998 struct altera_jtag *js = &astate->js;
999 /* If the JTAG interface was used, reset it to TLR */
1000 if (js->jtag_state != ILLEGAL_JTAG_STATE)
1001 altera_jreset_idle(astate);
1002
1003 kfree(js->dr_pre_data);
1004 js->dr_pre_data = NULL;
1005
1006 kfree(js->dr_post_data);
1007 js->dr_post_data = NULL;
1008
1009 kfree(js->dr_buffer);
1010 js->dr_buffer = NULL;
1011
1012 kfree(js->ir_pre_data);
1013 js->ir_pre_data = NULL;
1014
1015 kfree(js->ir_post_data);
1016 js->ir_post_data = NULL;
1017
1018 kfree(js->ir_buffer);
1019 js->ir_buffer = NULL;
1020}
diff --git a/drivers/staging/altera-stapl/altera-jtag.h b/drivers/staging/altera-stapl/altera-jtag.h
new file mode 100644
index 000000000000..2f97e36a2fbc
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-jtag.h
@@ -0,0 +1,113 @@
1/*
2 * altera-jtag.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef ALTERA_JTAG_H
27#define ALTERA_JTAG_H
28
29/* Function Prototypes */
30enum altera_jtag_state {
31 ILLEGAL_JTAG_STATE = -1,
32 RESET = 0,
33 IDLE = 1,
34 DRSELECT = 2,
35 DRCAPTURE = 3,
36 DRSHIFT = 4,
37 DREXIT1 = 5,
38 DRPAUSE = 6,
39 DREXIT2 = 7,
40 DRUPDATE = 8,
41 IRSELECT = 9,
42 IRCAPTURE = 10,
43 IRSHIFT = 11,
44 IREXIT1 = 12,
45 IRPAUSE = 13,
46 IREXIT2 = 14,
47 IRUPDATE = 15
48
49};
50
51struct altera_jtag {
52 /* Global variable to store the current JTAG state */
53 enum altera_jtag_state jtag_state;
54
55 /* Store current stop-state for DR and IR scan commands */
56 enum altera_jtag_state drstop_state;
57 enum altera_jtag_state irstop_state;
58
59 /* Store current padding values */
60 u32 dr_pre;
61 u32 dr_post;
62 u32 ir_pre;
63 u32 ir_post;
64 u32 dr_length;
65 u32 ir_length;
66 u8 *dr_pre_data;
67 u8 *dr_post_data;
68 u8 *ir_pre_data;
69 u8 *ir_post_data;
70 u8 *dr_buffer;
71 u8 *ir_buffer;
72};
73
74#define ALTERA_STACK_SIZE 128
75#define ALTERA_MESSAGE_LENGTH 1024
76
77struct altera_state {
78 struct altera_config *config;
79 struct altera_jtag js;
80 char msg_buff[ALTERA_MESSAGE_LENGTH + 1];
81 long stack[ALTERA_STACK_SIZE];
82};
83
84int altera_jinit(struct altera_state *astate);
85int altera_set_drstop(struct altera_jtag *js, enum altera_jtag_state state);
86int altera_set_irstop(struct altera_jtag *js, enum altera_jtag_state state);
87int altera_set_dr_pre(struct altera_jtag *js, u32 count, u32 start_index,
88 u8 *preamble_data);
89int altera_set_ir_pre(struct altera_jtag *js, u32 count, u32 start_index,
90 u8 *preamble_data);
91int altera_set_dr_post(struct altera_jtag *js, u32 count, u32 start_index,
92 u8 *postamble_data);
93int altera_set_ir_post(struct altera_jtag *js, u32 count, u32 start_index,
94 u8 *postamble_data);
95int altera_goto_jstate(struct altera_state *astate,
96 enum altera_jtag_state state);
97int altera_wait_cycles(struct altera_state *astate, s32 cycles,
98 enum altera_jtag_state wait_state);
99int altera_wait_msecs(struct altera_state *astate, s32 microseconds,
100 enum altera_jtag_state wait_state);
101int altera_irscan(struct altera_state *astate, u32 count,
102 u8 *tdi_data, u32 start_index);
103int altera_swap_ir(struct altera_state *astate,
104 u32 count, u8 *in_data,
105 u32 in_index, u8 *out_data,
106 u32 out_index);
107int altera_drscan(struct altera_state *astate, u32 count,
108 u8 *tdi_data, u32 start_index);
109int altera_swap_dr(struct altera_state *astate, u32 count,
110 u8 *in_data, u32 in_index,
111 u8 *out_data, u32 out_index);
112void altera_free_buffers(struct altera_state *astate);
113#endif /* ALTERA_JTAG_H */
diff --git a/drivers/staging/altera-stapl/altera-lpt.c b/drivers/staging/altera-stapl/altera-lpt.c
new file mode 100644
index 000000000000..91456a03612d
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera-lpt.c
@@ -0,0 +1,70 @@
1/*
2 * altera-lpt.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Abylay Ospan <aospan@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <linux/io.h>
27#include <linux/kernel.h>
28#include "altera-exprt.h"
29
30static int lpt_hardware_initialized;
31
32static void byteblaster_write(int port, int data)
33{
34 outb((u8)data, (u16)(port + 0x378));
35};
36
37static int byteblaster_read(int port)
38{
39 int data = 0;
40 data = inb((u16)(port + 0x378));
41 return data & 0xff;
42};
43
44int netup_jtag_io_lpt(void *device, int tms, int tdi, int read_tdo)
45{
46 int data = 0;
47 int tdo = 0;
48 int initial_lpt_ctrl = 0;
49
50 if (!lpt_hardware_initialized) {
51 initial_lpt_ctrl = byteblaster_read(2);
52 byteblaster_write(2, (initial_lpt_ctrl | 0x02) & 0xdf);
53 lpt_hardware_initialized = 1;
54 }
55
56 data = ((tdi ? 0x40 : 0) | (tms ? 0x02 : 0));
57
58 byteblaster_write(0, data);
59
60 if (read_tdo) {
61 tdo = byteblaster_read(1);
62 tdo = ((tdo & 0x80) ? 0 : 1);
63 }
64
65 byteblaster_write(0, data | 0x01);
66
67 byteblaster_write(0, data);
68
69 return tdo;
70}
diff --git a/drivers/staging/altera-stapl/altera.c b/drivers/staging/altera-stapl/altera.c
new file mode 100644
index 000000000000..05aad351b120
--- /dev/null
+++ b/drivers/staging/altera-stapl/altera.c
@@ -0,0 +1,2527 @@
1/*
2 * altera.c
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010,2011 NetUP Inc.
8 * Copyright (C) 2010,2011 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#include <asm/unaligned.h>
27#include <linux/ctype.h>
28#include <linux/string.h>
29#include <linux/firmware.h>
30#include <linux/slab.h>
31#include <staging/altera.h>
32#include "altera-exprt.h"
33#include "altera-jtag.h"
34
35static int debug = 1;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "enable debugging information");
38
39MODULE_DESCRIPTION("altera FPGA kernel module");
40MODULE_AUTHOR("Igor M. Liplianin <liplianin@netup.ru>");
41MODULE_LICENSE("GPL");
42
43#define dprintk(args...) \
44 if (debug) { \
45 printk(KERN_DEBUG args); \
46 }
47
48enum altera_fpga_opcode {
49 OP_NOP = 0,
50 OP_DUP,
51 OP_SWP,
52 OP_ADD,
53 OP_SUB,
54 OP_MULT,
55 OP_DIV,
56 OP_MOD,
57 OP_SHL,
58 OP_SHR,
59 OP_NOT,
60 OP_AND,
61 OP_OR,
62 OP_XOR,
63 OP_INV,
64 OP_GT,
65 OP_LT,
66 OP_RET,
67 OP_CMPS,
68 OP_PINT,
69 OP_PRNT,
70 OP_DSS,
71 OP_DSSC,
72 OP_ISS,
73 OP_ISSC,
74 OP_DPR = 0x1c,
75 OP_DPRL,
76 OP_DPO,
77 OP_DPOL,
78 OP_IPR,
79 OP_IPRL,
80 OP_IPO,
81 OP_IPOL,
82 OP_PCHR,
83 OP_EXIT,
84 OP_EQU,
85 OP_POPT,
86 OP_ABS = 0x2c,
87 OP_BCH0,
88 OP_PSH0 = 0x2f,
89 OP_PSHL = 0x40,
90 OP_PSHV,
91 OP_JMP,
92 OP_CALL,
93 OP_NEXT,
94 OP_PSTR,
95 OP_SINT = 0x47,
96 OP_ST,
97 OP_ISTP,
98 OP_DSTP,
99 OP_SWPN,
100 OP_DUPN,
101 OP_POPV,
102 OP_POPE,
103 OP_POPA,
104 OP_JMPZ,
105 OP_DS,
106 OP_IS,
107 OP_DPRA,
108 OP_DPOA,
109 OP_IPRA,
110 OP_IPOA,
111 OP_EXPT,
112 OP_PSHE,
113 OP_PSHA,
114 OP_DYNA,
115 OP_EXPV = 0x5c,
116 OP_COPY = 0x80,
117 OP_REVA,
118 OP_DSC,
119 OP_ISC,
120 OP_WAIT,
121 OP_VS,
122 OP_CMPA = 0xc0,
123 OP_VSC,
124};
125
126struct altera_procinfo {
127 char *name;
128 u8 attrs;
129 struct altera_procinfo *next;
130};
131
132/* This function checks if enough parameters are available on the stack. */
133static int altera_check_stack(int stack_ptr, int count, int *status)
134{
135 if (stack_ptr < count) {
136 *status = -EOVERFLOW;
137 return 0;
138 }
139
140 return 1;
141}
142
143static void altera_export_int(char *key, s32 value)
144{
145 dprintk("Export: key = \"%s\", value = %d\n", key, value);
146}
147
148#define HEX_LINE_CHARS 72
149#define HEX_LINE_BITS (HEX_LINE_CHARS * 4)
150
151static void altera_export_bool_array(char *key, u8 *data, s32 count)
152{
153 char string[HEX_LINE_CHARS + 1];
154 s32 i, offset;
155 u32 size, line, lines, linebits, value, j, k;
156
157 if (count > HEX_LINE_BITS) {
158 dprintk("Export: key = \"%s\", %d bits, value = HEX\n",
159 key, count);
160 lines = (count + (HEX_LINE_BITS - 1)) / HEX_LINE_BITS;
161
162 for (line = 0; line < lines; ++line) {
163 if (line < (lines - 1)) {
164 linebits = HEX_LINE_BITS;
165 size = HEX_LINE_CHARS;
166 offset = count - ((line + 1) * HEX_LINE_BITS);
167 } else {
168 linebits =
169 count - ((lines - 1) * HEX_LINE_BITS);
170 size = (linebits + 3) / 4;
171 offset = 0L;
172 }
173
174 string[size] = '\0';
175 j = size - 1;
176 value = 0;
177
178 for (k = 0; k < linebits; ++k) {
179 i = k + offset;
180 if (data[i >> 3] & (1 << (i & 7)))
181 value |= (1 << (i & 3));
182 if ((i & 3) == 3) {
183 sprintf(&string[j], "%1x", value);
184 value = 0;
185 --j;
186 }
187 }
188 if ((k & 3) > 0)
189 sprintf(&string[j], "%1x", value);
190
191 dprintk("%s\n", string);
192 }
193
194 } else {
195 size = (count + 3) / 4;
196 string[size] = '\0';
197 j = size - 1;
198 value = 0;
199
200 for (i = 0; i < count; ++i) {
201 if (data[i >> 3] & (1 << (i & 7)))
202 value |= (1 << (i & 3));
203 if ((i & 3) == 3) {
204 sprintf(&string[j], "%1x", value);
205 value = 0;
206 --j;
207 }
208 }
209 if ((i & 3) > 0)
210 sprintf(&string[j], "%1x", value);
211
212 dprintk("Export: key = \"%s\", %d bits, value = HEX %s\n",
213 key, count, string);
214 }
215}
216
217static int altera_execute(struct altera_state *astate,
218 u8 *p,
219 s32 program_size,
220 s32 *error_address,
221 int *exit_code,
222 int *format_version)
223{
224 struct altera_config *aconf = astate->config;
225 char *msg_buff = astate->msg_buff;
226 long *stack = astate->stack;
227 int status = 0;
228 u32 first_word = 0L;
229 u32 action_table = 0L;
230 u32 proc_table = 0L;
231 u32 str_table = 0L;
232 u32 sym_table = 0L;
233 u32 data_sect = 0L;
234 u32 code_sect = 0L;
235 u32 debug_sect = 0L;
236 u32 action_count = 0L;
237 u32 proc_count = 0L;
238 u32 sym_count = 0L;
239 long *vars = NULL;
240 s32 *var_size = NULL;
241 char *attrs = NULL;
242 u8 *proc_attributes = NULL;
243 u32 pc;
244 u32 opcode_address;
245 u32 args[3];
246 u32 opcode;
247 u32 name_id;
248 u8 charbuf[4];
249 long long_tmp;
250 u32 variable_id;
251 u8 *charptr_tmp;
252 u8 *charptr_tmp2;
253 long *longptr_tmp;
254 int version = 0;
255 int delta = 0;
256 int stack_ptr = 0;
257 u32 arg_count;
258 int done = 0;
259 int bad_opcode = 0;
260 u32 count;
261 u32 index;
262 u32 index2;
263 s32 long_count;
264 s32 long_idx;
265 s32 long_idx2;
266 u32 i;
267 u32 j;
268 u32 uncomp_size;
269 u32 offset;
270 u32 value;
271 int current_proc = 0;
272 int reverse;
273
274 char *name;
275
276 dprintk("%s\n", __func__);
277
278 /* Read header information */
279 if (program_size > 52L) {
280 first_word = get_unaligned_be32(&p[0]);
281 version = (first_word & 1L);
282 *format_version = version + 1;
283 delta = version * 8;
284
285 action_table = get_unaligned_be32(&p[4]);
286 proc_table = get_unaligned_be32(&p[8]);
287 str_table = get_unaligned_be32(&p[4 + delta]);
288 sym_table = get_unaligned_be32(&p[16 + delta]);
289 data_sect = get_unaligned_be32(&p[20 + delta]);
290 code_sect = get_unaligned_be32(&p[24 + delta]);
291 debug_sect = get_unaligned_be32(&p[28 + delta]);
292 action_count = get_unaligned_be32(&p[40 + delta]);
293 proc_count = get_unaligned_be32(&p[44 + delta]);
294 sym_count = get_unaligned_be32(&p[48 + (2 * delta)]);
295 }
296
297 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L)) {
298 done = 1;
299 status = -EIO;
300 goto exit_done;
301 }
302
303 if (sym_count <= 0)
304 goto exit_done;
305
306 vars = kzalloc(sym_count * sizeof(long), GFP_KERNEL);
307
308 if (vars == NULL)
309 status = -ENOMEM;
310
311 if (status == 0) {
312 var_size = kzalloc(sym_count * sizeof(s32), GFP_KERNEL);
313
314 if (var_size == NULL)
315 status = -ENOMEM;
316 }
317
318 if (status == 0) {
319 attrs = kzalloc(sym_count, GFP_KERNEL);
320
321 if (attrs == NULL)
322 status = -ENOMEM;
323 }
324
325 if ((status == 0) && (version > 0)) {
326 proc_attributes = kzalloc(proc_count, GFP_KERNEL);
327
328 if (proc_attributes == NULL)
329 status = -ENOMEM;
330 }
331
332 if (status != 0)
333 goto exit_done;
334
335 delta = version * 2;
336
337 for (i = 0; i < sym_count; ++i) {
338 offset = (sym_table + ((11 + delta) * i));
339
340 value = get_unaligned_be32(&p[offset + 3 + delta]);
341
342 attrs[i] = p[offset];
343
344 /*
345 * use bit 7 of attribute byte to indicate that
346 * this buffer was dynamically allocated
347 * and should be freed later
348 */
349 attrs[i] &= 0x7f;
350
351 var_size[i] = get_unaligned_be32(&p[offset + 7 + delta]);
352
353 /*
354 * Attribute bits:
355 * bit 0: 0 = read-only, 1 = read-write
356 * bit 1: 0 = not compressed, 1 = compressed
357 * bit 2: 0 = not initialized, 1 = initialized
358 * bit 3: 0 = scalar, 1 = array
359 * bit 4: 0 = Boolean, 1 = integer
360 * bit 5: 0 = declared variable,
361 * 1 = compiler created temporary variable
362 */
363
364 if ((attrs[i] & 0x0c) == 0x04)
365 /* initialized scalar variable */
366 vars[i] = value;
367 else if ((attrs[i] & 0x1e) == 0x0e) {
368 /* initialized compressed Boolean array */
369 uncomp_size = get_unaligned_le32(&p[data_sect + value]);
370
371 /* allocate a buffer for the uncompressed data */
372 vars[i] = (long)kzalloc(uncomp_size, GFP_KERNEL);
373 if (vars[i] == 0L)
374 status = -ENOMEM;
375 else {
376 /* set flag so buffer will be freed later */
377 attrs[i] |= 0x80;
378
379 /* uncompress the data */
380 if (altera_shrink(&p[data_sect + value],
381 var_size[i],
382 (u8 *)vars[i],
383 uncomp_size,
384 version) != uncomp_size)
385 /* decompression failed */
386 status = -EIO;
387 else
388 var_size[i] = uncomp_size * 8L;
389
390 }
391 } else if ((attrs[i] & 0x1e) == 0x0c) {
392 /* initialized Boolean array */
393 vars[i] = value + data_sect + (long)p;
394 } else if ((attrs[i] & 0x1c) == 0x1c) {
395 /* initialized integer array */
396 vars[i] = value + data_sect;
397 } else if ((attrs[i] & 0x0c) == 0x08) {
398 /* uninitialized array */
399
400 /* flag attrs so that memory is freed */
401 attrs[i] |= 0x80;
402
403 if (var_size[i] > 0) {
404 u32 size;
405
406 if (attrs[i] & 0x10)
407 /* integer array */
408 size = (var_size[i] * sizeof(s32));
409 else
410 /* Boolean array */
411 size = ((var_size[i] + 7L) / 8L);
412
413 vars[i] = (long)kzalloc(size, GFP_KERNEL);
414
415 if (vars[i] == 0) {
416 status = -ENOMEM;
417 } else {
418 /* zero out memory */
419 for (j = 0; j < size; ++j)
420 ((u8 *)(vars[i]))[j] = 0;
421
422 }
423 } else
424 vars[i] = 0;
425
426 } else
427 vars[i] = 0;
428
429 }
430
431exit_done:
432 if (status != 0)
433 done = 1;
434
435 altera_jinit(astate);
436
437 pc = code_sect;
438 msg_buff[0] = '\0';
439
440 /*
441 * For JBC version 2, we will execute the procedures corresponding to
442 * the selected ACTION
443 */
444 if (version > 0) {
445 if (aconf->action == NULL) {
446 status = -EINVAL;
447 done = 1;
448 } else {
449 int action_found = 0;
450 for (i = 0; (i < action_count) && !action_found; ++i) {
451 name_id = get_unaligned_be32(&p[action_table +
452 (12 * i)]);
453
454 name = &p[str_table + name_id];
455
456 if (strnicmp(aconf->action, name, strlen(name)) == 0) {
457 action_found = 1;
458 current_proc =
459 get_unaligned_be32(&p[action_table +
460 (12 * i) + 8]);
461 }
462 }
463
464 if (!action_found) {
465 status = -EINVAL;
466 done = 1;
467 }
468 }
469
470 if (status == 0) {
471 int first_time = 1;
472 i = current_proc;
473 while ((i != 0) || first_time) {
474 first_time = 0;
475 /* check procedure attribute byte */
476 proc_attributes[i] =
477 (p[proc_table +
478 (13 * i) + 8] &
479 0x03);
480
481 /*
482 * BIT0 - OPTIONAL
483 * BIT1 - RECOMMENDED
484 * BIT6 - FORCED OFF
485 * BIT7 - FORCED ON
486 */
487
488 i = get_unaligned_be32(&p[proc_table +
489 (13 * i) + 4]);
490 }
491
492 /*
493 * Set current_proc to the first procedure
494 * to be executed
495 */
496 i = current_proc;
497 while ((i != 0) &&
498 ((proc_attributes[i] == 1) ||
499 ((proc_attributes[i] & 0xc0) == 0x40))) {
500 i = get_unaligned_be32(&p[proc_table +
501 (13 * i) + 4]);
502 }
503
504 if ((i != 0) || ((i == 0) && (current_proc == 0) &&
505 ((proc_attributes[0] != 1) &&
506 ((proc_attributes[0] & 0xc0) != 0x40)))) {
507 current_proc = i;
508 pc = code_sect +
509 get_unaligned_be32(&p[proc_table +
510 (13 * i) + 9]);
511 if ((pc < code_sect) || (pc >= debug_sect))
512 status = -ERANGE;
513 } else
514 /* there are no procedures to execute! */
515 done = 1;
516
517 }
518 }
519
520 msg_buff[0] = '\0';
521
522 while (!done) {
523 opcode = (p[pc] & 0xff);
524 opcode_address = pc;
525 ++pc;
526
527 if (debug > 1)
528 printk("opcode: %02x\n", opcode);
529
530 arg_count = (opcode >> 6) & 3;
531 for (i = 0; i < arg_count; ++i) {
532 args[i] = get_unaligned_be32(&p[pc]);
533 pc += 4;
534 }
535
536 switch (opcode) {
537 case OP_NOP:
538 break;
539 case OP_DUP:
540 if (altera_check_stack(stack_ptr, 1, &status)) {
541 stack[stack_ptr] = stack[stack_ptr - 1];
542 ++stack_ptr;
543 }
544 break;
545 case OP_SWP:
546 if (altera_check_stack(stack_ptr, 2, &status)) {
547 long_tmp = stack[stack_ptr - 2];
548 stack[stack_ptr - 2] = stack[stack_ptr - 1];
549 stack[stack_ptr - 1] = long_tmp;
550 }
551 break;
552 case OP_ADD:
553 if (altera_check_stack(stack_ptr, 2, &status)) {
554 --stack_ptr;
555 stack[stack_ptr - 1] += stack[stack_ptr];
556 }
557 break;
558 case OP_SUB:
559 if (altera_check_stack(stack_ptr, 2, &status)) {
560 --stack_ptr;
561 stack[stack_ptr - 1] -= stack[stack_ptr];
562 }
563 break;
564 case OP_MULT:
565 if (altera_check_stack(stack_ptr, 2, &status)) {
566 --stack_ptr;
567 stack[stack_ptr - 1] *= stack[stack_ptr];
568 }
569 break;
570 case OP_DIV:
571 if (altera_check_stack(stack_ptr, 2, &status)) {
572 --stack_ptr;
573 stack[stack_ptr - 1] /= stack[stack_ptr];
574 }
575 break;
576 case OP_MOD:
577 if (altera_check_stack(stack_ptr, 2, &status)) {
578 --stack_ptr;
579 stack[stack_ptr - 1] %= stack[stack_ptr];
580 }
581 break;
582 case OP_SHL:
583 if (altera_check_stack(stack_ptr, 2, &status)) {
584 --stack_ptr;
585 stack[stack_ptr - 1] <<= stack[stack_ptr];
586 }
587 break;
588 case OP_SHR:
589 if (altera_check_stack(stack_ptr, 2, &status)) {
590 --stack_ptr;
591 stack[stack_ptr - 1] >>= stack[stack_ptr];
592 }
593 break;
594 case OP_NOT:
595 if (altera_check_stack(stack_ptr, 1, &status))
596 stack[stack_ptr - 1] ^= (-1L);
597
598 break;
599 case OP_AND:
600 if (altera_check_stack(stack_ptr, 2, &status)) {
601 --stack_ptr;
602 stack[stack_ptr - 1] &= stack[stack_ptr];
603 }
604 break;
605 case OP_OR:
606 if (altera_check_stack(stack_ptr, 2, &status)) {
607 --stack_ptr;
608 stack[stack_ptr - 1] |= stack[stack_ptr];
609 }
610 break;
611 case OP_XOR:
612 if (altera_check_stack(stack_ptr, 2, &status)) {
613 --stack_ptr;
614 stack[stack_ptr - 1] ^= stack[stack_ptr];
615 }
616 break;
617 case OP_INV:
618 if (!altera_check_stack(stack_ptr, 1, &status))
619 break;
620 stack[stack_ptr - 1] = stack[stack_ptr - 1] ? 0L : 1L;
621 break;
622 case OP_GT:
623 if (!altera_check_stack(stack_ptr, 2, &status))
624 break;
625 --stack_ptr;
626 stack[stack_ptr - 1] =
627 (stack[stack_ptr - 1] > stack[stack_ptr]) ?
628 1L : 0L;
629
630 break;
631 case OP_LT:
632 if (!altera_check_stack(stack_ptr, 2, &status))
633 break;
634 --stack_ptr;
635 stack[stack_ptr - 1] =
636 (stack[stack_ptr - 1] < stack[stack_ptr]) ?
637 1L : 0L;
638
639 break;
640 case OP_RET:
641 if ((version > 0) && (stack_ptr == 0)) {
642 /*
643 * We completed one of the main procedures
644 * of an ACTION.
645 * Find the next procedure
646 * to be executed and jump to it.
647 * If there are no more procedures, then EXIT.
648 */
649 i = get_unaligned_be32(&p[proc_table +
650 (13 * current_proc) + 4]);
651 while ((i != 0) &&
652 ((proc_attributes[i] == 1) ||
653 ((proc_attributes[i] & 0xc0) == 0x40)))
654 i = get_unaligned_be32(&p[proc_table +
655 (13 * i) + 4]);
656
657 if (i == 0) {
658 /* no procedures to execute! */
659 done = 1;
660 *exit_code = 0; /* success */
661 } else {
662 current_proc = i;
663 pc = code_sect + get_unaligned_be32(
664 &p[proc_table +
665 (13 * i) + 9]);
666 if ((pc < code_sect) ||
667 (pc >= debug_sect))
668 status = -ERANGE;
669 }
670
671 } else
672 if (altera_check_stack(stack_ptr, 1, &status)) {
673 pc = stack[--stack_ptr] + code_sect;
674 if ((pc <= code_sect) ||
675 (pc >= debug_sect))
676 status = -ERANGE;
677
678 }
679
680 break;
681 case OP_CMPS:
682 /*
683 * Array short compare
684 * ...stack 0 is source 1 value
685 * ...stack 1 is source 2 value
686 * ...stack 2 is mask value
687 * ...stack 3 is count
688 */
689 if (altera_check_stack(stack_ptr, 4, &status)) {
690 s32 a = stack[--stack_ptr];
691 s32 b = stack[--stack_ptr];
692 long_tmp = stack[--stack_ptr];
693 count = stack[stack_ptr - 1];
694
695 if ((count < 1) || (count > 32))
696 status = -ERANGE;
697 else {
698 long_tmp &= ((-1L) >> (32 - count));
699
700 stack[stack_ptr - 1] =
701 ((a & long_tmp) == (b & long_tmp))
702 ? 1L : 0L;
703 }
704 }
705 break;
706 case OP_PINT:
707 /*
708 * PRINT add integer
709 * ...stack 0 is integer value
710 */
711 if (!altera_check_stack(stack_ptr, 1, &status))
712 break;
713 sprintf(&msg_buff[strlen(msg_buff)],
714 "%ld", stack[--stack_ptr]);
715 break;
716 case OP_PRNT:
717 /* PRINT finish */
718 if (debug)
719 printk(msg_buff, "\n");
720
721 msg_buff[0] = '\0';
722 break;
723 case OP_DSS:
724 /*
725 * DRSCAN short
726 * ...stack 0 is scan data
727 * ...stack 1 is count
728 */
729 if (!altera_check_stack(stack_ptr, 2, &status))
730 break;
731 long_tmp = stack[--stack_ptr];
732 count = stack[--stack_ptr];
733 put_unaligned_le32(long_tmp, &charbuf[0]);
734 status = altera_drscan(astate, count, charbuf, 0);
735 break;
736 case OP_DSSC:
737 /*
738 * DRSCAN short with capture
739 * ...stack 0 is scan data
740 * ...stack 1 is count
741 */
742 if (!altera_check_stack(stack_ptr, 2, &status))
743 break;
744 long_tmp = stack[--stack_ptr];
745 count = stack[stack_ptr - 1];
746 put_unaligned_le32(long_tmp, &charbuf[0]);
747 status = altera_swap_dr(astate, count, charbuf,
748 0, charbuf, 0);
749 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
750 break;
751 case OP_ISS:
752 /*
753 * IRSCAN short
754 * ...stack 0 is scan data
755 * ...stack 1 is count
756 */
757 if (!altera_check_stack(stack_ptr, 2, &status))
758 break;
759 long_tmp = stack[--stack_ptr];
760 count = stack[--stack_ptr];
761 put_unaligned_le32(long_tmp, &charbuf[0]);
762 status = altera_irscan(astate, count, charbuf, 0);
763 break;
764 case OP_ISSC:
765 /*
766 * IRSCAN short with capture
767 * ...stack 0 is scan data
768 * ...stack 1 is count
769 */
770 if (!altera_check_stack(stack_ptr, 2, &status))
771 break;
772 long_tmp = stack[--stack_ptr];
773 count = stack[stack_ptr - 1];
774 put_unaligned_le32(long_tmp, &charbuf[0]);
775 status = altera_swap_ir(astate, count, charbuf,
776 0, charbuf, 0);
777 stack[stack_ptr - 1] = get_unaligned_le32(&charbuf[0]);
778 break;
779 case OP_DPR:
780 if (!altera_check_stack(stack_ptr, 1, &status))
781 break;
782 count = stack[--stack_ptr];
783 status = altera_set_dr_pre(&astate->js, count, 0, NULL);
784 break;
785 case OP_DPRL:
786 /*
787 * DRPRE with literal data
788 * ...stack 0 is count
789 * ...stack 1 is literal data
790 */
791 if (!altera_check_stack(stack_ptr, 2, &status))
792 break;
793 count = stack[--stack_ptr];
794 long_tmp = stack[--stack_ptr];
795 put_unaligned_le32(long_tmp, &charbuf[0]);
796 status = altera_set_dr_pre(&astate->js, count, 0,
797 charbuf);
798 break;
799 case OP_DPO:
800 /*
801 * DRPOST
802 * ...stack 0 is count
803 */
804 if (altera_check_stack(stack_ptr, 1, &status)) {
805 count = stack[--stack_ptr];
806 status = altera_set_dr_post(&astate->js, count,
807 0, NULL);
808 }
809 break;
810 case OP_DPOL:
811 /*
812 * DRPOST with literal data
813 * ...stack 0 is count
814 * ...stack 1 is literal data
815 */
816 if (!altera_check_stack(stack_ptr, 2, &status))
817 break;
818 count = stack[--stack_ptr];
819 long_tmp = stack[--stack_ptr];
820 put_unaligned_le32(long_tmp, &charbuf[0]);
821 status = altera_set_dr_post(&astate->js, count, 0,
822 charbuf);
823 break;
824 case OP_IPR:
825 if (altera_check_stack(stack_ptr, 1, &status)) {
826 count = stack[--stack_ptr];
827 status = altera_set_ir_pre(&astate->js, count,
828 0, NULL);
829 }
830 break;
831 case OP_IPRL:
832 /*
833 * IRPRE with literal data
834 * ...stack 0 is count
835 * ...stack 1 is literal data
836 */
837 if (altera_check_stack(stack_ptr, 2, &status)) {
838 count = stack[--stack_ptr];
839 long_tmp = stack[--stack_ptr];
840 put_unaligned_le32(long_tmp, &charbuf[0]);
841 status = altera_set_ir_pre(&astate->js, count,
842 0, charbuf);
843 }
844 break;
845 case OP_IPO:
846 /*
847 * IRPOST
848 * ...stack 0 is count
849 */
850 if (altera_check_stack(stack_ptr, 1, &status)) {
851 count = stack[--stack_ptr];
852 status = altera_set_ir_post(&astate->js, count,
853 0, NULL);
854 }
855 break;
856 case OP_IPOL:
857 /*
858 * IRPOST with literal data
859 * ...stack 0 is count
860 * ...stack 1 is literal data
861 */
862 if (!altera_check_stack(stack_ptr, 2, &status))
863 break;
864 count = stack[--stack_ptr];
865 long_tmp = stack[--stack_ptr];
866 put_unaligned_le32(long_tmp, &charbuf[0]);
867 status = altera_set_ir_post(&astate->js, count, 0,
868 charbuf);
869 break;
870 case OP_PCHR:
871 if (altera_check_stack(stack_ptr, 1, &status)) {
872 u8 ch;
873 count = strlen(msg_buff);
874 ch = (char) stack[--stack_ptr];
875 if ((ch < 1) || (ch > 127)) {
876 /*
877 * character code out of range
878 * instead of flagging an error,
879 * force the value to 127
880 */
881 ch = 127;
882 }
883 msg_buff[count] = ch;
884 msg_buff[count + 1] = '\0';
885 }
886 break;
887 case OP_EXIT:
888 if (altera_check_stack(stack_ptr, 1, &status))
889 *exit_code = stack[--stack_ptr];
890
891 done = 1;
892 break;
893 case OP_EQU:
894 if (!altera_check_stack(stack_ptr, 2, &status))
895 break;
896 --stack_ptr;
897 stack[stack_ptr - 1] =
898 (stack[stack_ptr - 1] == stack[stack_ptr]) ?
899 1L : 0L;
900 break;
901 case OP_POPT:
902 if (altera_check_stack(stack_ptr, 1, &status))
903 --stack_ptr;
904
905 break;
906 case OP_ABS:
907 if (!altera_check_stack(stack_ptr, 1, &status))
908 break;
909 if (stack[stack_ptr - 1] < 0)
910 stack[stack_ptr - 1] = 0 - stack[stack_ptr - 1];
911
912 break;
913 case OP_BCH0:
914 /*
915 * Batch operation 0
916 * SWP
917 * SWPN 7
918 * SWP
919 * SWPN 6
920 * DUPN 8
921 * SWPN 2
922 * SWP
923 * DUPN 6
924 * DUPN 6
925 */
926
927 /* SWP */
928 if (altera_check_stack(stack_ptr, 2, &status)) {
929 long_tmp = stack[stack_ptr - 2];
930 stack[stack_ptr - 2] = stack[stack_ptr - 1];
931 stack[stack_ptr - 1] = long_tmp;
932 }
933
934 /* SWPN 7 */
935 index = 7 + 1;
936 if (altera_check_stack(stack_ptr, index, &status)) {
937 long_tmp = stack[stack_ptr - index];
938 stack[stack_ptr - index] = stack[stack_ptr - 1];
939 stack[stack_ptr - 1] = long_tmp;
940 }
941
942 /* SWP */
943 if (altera_check_stack(stack_ptr, 2, &status)) {
944 long_tmp = stack[stack_ptr - 2];
945 stack[stack_ptr - 2] = stack[stack_ptr - 1];
946 stack[stack_ptr - 1] = long_tmp;
947 }
948
949 /* SWPN 6 */
950 index = 6 + 1;
951 if (altera_check_stack(stack_ptr, index, &status)) {
952 long_tmp = stack[stack_ptr - index];
953 stack[stack_ptr - index] = stack[stack_ptr - 1];
954 stack[stack_ptr - 1] = long_tmp;
955 }
956
957 /* DUPN 8 */
958 index = 8 + 1;
959 if (altera_check_stack(stack_ptr, index, &status)) {
960 stack[stack_ptr] = stack[stack_ptr - index];
961 ++stack_ptr;
962 }
963
964 /* SWPN 2 */
965 index = 2 + 1;
966 if (altera_check_stack(stack_ptr, index, &status)) {
967 long_tmp = stack[stack_ptr - index];
968 stack[stack_ptr - index] = stack[stack_ptr - 1];
969 stack[stack_ptr - 1] = long_tmp;
970 }
971
972 /* SWP */
973 if (altera_check_stack(stack_ptr, 2, &status)) {
974 long_tmp = stack[stack_ptr - 2];
975 stack[stack_ptr - 2] = stack[stack_ptr - 1];
976 stack[stack_ptr - 1] = long_tmp;
977 }
978
979 /* DUPN 6 */
980 index = 6 + 1;
981 if (altera_check_stack(stack_ptr, index, &status)) {
982 stack[stack_ptr] = stack[stack_ptr - index];
983 ++stack_ptr;
984 }
985
986 /* DUPN 6 */
987 index = 6 + 1;
988 if (altera_check_stack(stack_ptr, index, &status)) {
989 stack[stack_ptr] = stack[stack_ptr - index];
990 ++stack_ptr;
991 }
992 break;
993 case OP_PSH0:
994 stack[stack_ptr++] = 0;
995 break;
996 case OP_PSHL:
997 stack[stack_ptr++] = (s32) args[0];
998 break;
999 case OP_PSHV:
1000 stack[stack_ptr++] = vars[args[0]];
1001 break;
1002 case OP_JMP:
1003 pc = args[0] + code_sect;
1004 if ((pc < code_sect) || (pc >= debug_sect))
1005 status = -ERANGE;
1006 break;
1007 case OP_CALL:
1008 stack[stack_ptr++] = pc;
1009 pc = args[0] + code_sect;
1010 if ((pc < code_sect) || (pc >= debug_sect))
1011 status = -ERANGE;
1012 break;
1013 case OP_NEXT:
1014 /*
1015 * Process FOR / NEXT loop
1016 * ...argument 0 is variable ID
1017 * ...stack 0 is step value
1018 * ...stack 1 is end value
1019 * ...stack 2 is top address
1020 */
1021 if (altera_check_stack(stack_ptr, 3, &status)) {
1022 s32 step = stack[stack_ptr - 1];
1023 s32 end = stack[stack_ptr - 2];
1024 s32 top = stack[stack_ptr - 3];
1025 s32 iterator = vars[args[0]];
1026 int break_out = 0;
1027
1028 if (step < 0) {
1029 if (iterator <= end)
1030 break_out = 1;
1031 } else if (iterator >= end)
1032 break_out = 1;
1033
1034 if (break_out) {
1035 stack_ptr -= 3;
1036 } else {
1037 vars[args[0]] = iterator + step;
1038 pc = top + code_sect;
1039 if ((pc < code_sect) ||
1040 (pc >= debug_sect))
1041 status = -ERANGE;
1042 }
1043 }
1044 break;
1045 case OP_PSTR:
1046 /*
1047 * PRINT add string
1048 * ...argument 0 is string ID
1049 */
1050 count = strlen(msg_buff);
1051 strlcpy(&msg_buff[count],
1052 &p[str_table + args[0]],
1053 ALTERA_MESSAGE_LENGTH - count);
1054 break;
1055 case OP_SINT:
1056 /*
1057 * STATE intermediate state
1058 * ...argument 0 is state code
1059 */
1060 status = altera_goto_jstate(astate, args[0]);
1061 break;
1062 case OP_ST:
1063 /*
1064 * STATE final state
1065 * ...argument 0 is state code
1066 */
1067 status = altera_goto_jstate(astate, args[0]);
1068 break;
1069 case OP_ISTP:
1070 /*
1071 * IRSTOP state
1072 * ...argument 0 is state code
1073 */
1074 status = altera_set_irstop(&astate->js, args[0]);
1075 break;
1076 case OP_DSTP:
1077 /*
1078 * DRSTOP state
1079 * ...argument 0 is state code
1080 */
1081 status = altera_set_drstop(&astate->js, args[0]);
1082 break;
1083
1084 case OP_SWPN:
1085 /*
1086 * Exchange top with Nth stack value
1087 * ...argument 0 is 0-based stack entry
1088 * to swap with top element
1089 */
1090 index = (args[0]) + 1;
1091 if (altera_check_stack(stack_ptr, index, &status)) {
1092 long_tmp = stack[stack_ptr - index];
1093 stack[stack_ptr - index] = stack[stack_ptr - 1];
1094 stack[stack_ptr - 1] = long_tmp;
1095 }
1096 break;
1097 case OP_DUPN:
1098 /*
1099 * Duplicate Nth stack value
1100 * ...argument 0 is 0-based stack entry to duplicate
1101 */
1102 index = (args[0]) + 1;
1103 if (altera_check_stack(stack_ptr, index, &status)) {
1104 stack[stack_ptr] = stack[stack_ptr - index];
1105 ++stack_ptr;
1106 }
1107 break;
1108 case OP_POPV:
1109 /*
1110 * Pop stack into scalar variable
1111 * ...argument 0 is variable ID
1112 * ...stack 0 is value
1113 */
1114 if (altera_check_stack(stack_ptr, 1, &status))
1115 vars[args[0]] = stack[--stack_ptr];
1116
1117 break;
1118 case OP_POPE:
1119 /*
1120 * Pop stack into integer array element
1121 * ...argument 0 is variable ID
1122 * ...stack 0 is array index
1123 * ...stack 1 is value
1124 */
1125 if (!altera_check_stack(stack_ptr, 2, &status))
1126 break;
1127 variable_id = args[0];
1128
1129 /*
1130 * If variable is read-only,
1131 * convert to writable array
1132 */
1133 if ((version > 0) &&
1134 ((attrs[variable_id] & 0x9c) == 0x1c)) {
1135 /* Allocate a writable buffer for this array */
1136 count = var_size[variable_id];
1137 long_tmp = vars[variable_id];
1138 longptr_tmp = kzalloc(count * sizeof(long),
1139 GFP_KERNEL);
1140 vars[variable_id] = (long)longptr_tmp;
1141
1142 if (vars[variable_id] == 0) {
1143 status = -ENOMEM;
1144 break;
1145 }
1146
1147 /* copy previous contents into buffer */
1148 for (i = 0; i < count; ++i) {
1149 longptr_tmp[i] =
1150 get_unaligned_be32(&p[long_tmp]);
1151 long_tmp += sizeof(long);
1152 }
1153
1154 /*
1155 * set bit 7 - buffer was
1156 * dynamically allocated
1157 */
1158 attrs[variable_id] |= 0x80;
1159
1160 /* clear bit 2 - variable is writable */
1161 attrs[variable_id] &= ~0x04;
1162 attrs[variable_id] |= 0x01;
1163
1164 }
1165
1166 /* check that variable is a writable integer array */
1167 if ((attrs[variable_id] & 0x1c) != 0x18)
1168 status = -ERANGE;
1169 else {
1170 longptr_tmp = (long *)vars[variable_id];
1171
1172 /* pop the array index */
1173 index = stack[--stack_ptr];
1174
1175 /* pop the value and store it into the array */
1176 longptr_tmp[index] = stack[--stack_ptr];
1177 }
1178
1179 break;
1180 case OP_POPA:
1181 /*
1182 * Pop stack into Boolean array
1183 * ...argument 0 is variable ID
1184 * ...stack 0 is count
1185 * ...stack 1 is array index
1186 * ...stack 2 is value
1187 */
1188 if (!altera_check_stack(stack_ptr, 3, &status))
1189 break;
1190 variable_id = args[0];
1191
1192 /*
1193 * If variable is read-only,
1194 * convert to writable array
1195 */
1196 if ((version > 0) &&
1197 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1198 /* Allocate a writable buffer for this array */
1199 long_tmp =
1200 (var_size[variable_id] + 7L) >> 3L;
1201 charptr_tmp2 = (u8 *)vars[variable_id];
1202 charptr_tmp =
1203 kzalloc(long_tmp, GFP_KERNEL);
1204 vars[variable_id] = (long)charptr_tmp;
1205
1206 if (vars[variable_id] == 0) {
1207 status = -ENOMEM;
1208 break;
1209 }
1210
1211 /* zero the buffer */
1212 for (long_idx = 0L;
1213 long_idx < long_tmp;
1214 ++long_idx) {
1215 charptr_tmp[long_idx] = 0;
1216 }
1217
1218 /* copy previous contents into buffer */
1219 for (long_idx = 0L;
1220 long_idx < var_size[variable_id];
1221 ++long_idx) {
1222 long_idx2 = long_idx;
1223
1224 if (charptr_tmp2[long_idx2 >> 3] &
1225 (1 << (long_idx2 & 7))) {
1226 charptr_tmp[long_idx >> 3] |=
1227 (1 << (long_idx & 7));
1228 }
1229 }
1230
1231 /*
1232 * set bit 7 - buffer was
1233 * dynamically allocated
1234 */
1235 attrs[variable_id] |= 0x80;
1236
1237 /* clear bit 2 - variable is writable */
1238 attrs[variable_id] &= ~0x04;
1239 attrs[variable_id] |= 0x01;
1240
1241 }
1242
1243 /*
1244 * check that variable is
1245 * a writable Boolean array
1246 */
1247 if ((attrs[variable_id] & 0x1c) != 0x08) {
1248 status = -ERANGE;
1249 break;
1250 }
1251
1252 charptr_tmp = (u8 *)vars[variable_id];
1253
1254 /* pop the count (number of bits to copy) */
1255 long_count = stack[--stack_ptr];
1256
1257 /* pop the array index */
1258 long_idx = stack[--stack_ptr];
1259
1260 reverse = 0;
1261
1262 if (version > 0) {
1263 /*
1264 * stack 0 = array right index
1265 * stack 1 = array left index
1266 */
1267
1268 if (long_idx > long_count) {
1269 reverse = 1;
1270 long_tmp = long_count;
1271 long_count = 1 + long_idx -
1272 long_count;
1273 long_idx = long_tmp;
1274
1275 /* reverse POPA is not supported */
1276 status = -ERANGE;
1277 break;
1278 } else
1279 long_count = 1 + long_count -
1280 long_idx;
1281
1282 }
1283
1284 /* pop the data */
1285 long_tmp = stack[--stack_ptr];
1286
1287 if (long_count < 1) {
1288 status = -ERANGE;
1289 break;
1290 }
1291
1292 for (i = 0; i < long_count; ++i) {
1293 if (long_tmp & (1L << (s32) i))
1294 charptr_tmp[long_idx >> 3L] |=
1295 (1L << (long_idx & 7L));
1296 else
1297 charptr_tmp[long_idx >> 3L] &=
1298 ~(1L << (long_idx & 7L));
1299
1300 ++long_idx;
1301 }
1302
1303 break;
1304 case OP_JMPZ:
1305 /*
1306 * Pop stack and branch if zero
1307 * ...argument 0 is address
1308 * ...stack 0 is condition value
1309 */
1310 if (altera_check_stack(stack_ptr, 1, &status)) {
1311 if (stack[--stack_ptr] == 0) {
1312 pc = args[0] + code_sect;
1313 if ((pc < code_sect) ||
1314 (pc >= debug_sect))
1315 status = -ERANGE;
1316 }
1317 }
1318 break;
1319 case OP_DS:
1320 case OP_IS:
1321 /*
1322 * DRSCAN
1323 * IRSCAN
1324 * ...argument 0 is scan data variable ID
1325 * ...stack 0 is array index
1326 * ...stack 1 is count
1327 */
1328 if (!altera_check_stack(stack_ptr, 2, &status))
1329 break;
1330 long_idx = stack[--stack_ptr];
1331 long_count = stack[--stack_ptr];
1332 reverse = 0;
1333 if (version > 0) {
1334 /*
1335 * stack 0 = array right index
1336 * stack 1 = array left index
1337 * stack 2 = count
1338 */
1339 long_tmp = long_count;
1340 long_count = stack[--stack_ptr];
1341
1342 if (long_idx > long_tmp) {
1343 reverse = 1;
1344 long_idx = long_tmp;
1345 }
1346 }
1347
1348 charptr_tmp = (u8 *)vars[args[0]];
1349
1350 if (reverse) {
1351 /*
1352 * allocate a buffer
1353 * and reverse the data order
1354 */
1355 charptr_tmp2 = charptr_tmp;
1356 charptr_tmp = kzalloc((long_count >> 3) + 1,
1357 GFP_KERNEL);
1358 if (charptr_tmp == NULL) {
1359 status = -ENOMEM;
1360 break;
1361 }
1362
1363 long_tmp = long_idx + long_count - 1;
1364 long_idx2 = 0;
1365 while (long_idx2 < long_count) {
1366 if (charptr_tmp2[long_tmp >> 3] &
1367 (1 << (long_tmp & 7)))
1368 charptr_tmp[long_idx2 >> 3] |=
1369 (1 << (long_idx2 & 7));
1370 else
1371 charptr_tmp[long_idx2 >> 3] &=
1372 ~(1 << (long_idx2 & 7));
1373
1374 --long_tmp;
1375 ++long_idx2;
1376 }
1377 }
1378
1379 if (opcode == 0x51) /* DS */
1380 status = altera_drscan(astate, long_count,
1381 charptr_tmp, long_idx);
1382 else /* IS */
1383 status = altera_irscan(astate, long_count,
1384 charptr_tmp, long_idx);
1385
1386 if (reverse)
1387 kfree(charptr_tmp);
1388
1389 break;
1390 case OP_DPRA:
1391 /*
1392 * DRPRE with array data
1393 * ...argument 0 is variable ID
1394 * ...stack 0 is array index
1395 * ...stack 1 is count
1396 */
1397 if (!altera_check_stack(stack_ptr, 2, &status))
1398 break;
1399 index = stack[--stack_ptr];
1400 count = stack[--stack_ptr];
1401
1402 if (version > 0)
1403 /*
1404 * stack 0 = array right index
1405 * stack 1 = array left index
1406 */
1407 count = 1 + count - index;
1408
1409 charptr_tmp = (u8 *)vars[args[0]];
1410 status = altera_set_dr_pre(&astate->js, count, index,
1411 charptr_tmp);
1412 break;
1413 case OP_DPOA:
1414 /*
1415 * DRPOST with array data
1416 * ...argument 0 is variable ID
1417 * ...stack 0 is array index
1418 * ...stack 1 is count
1419 */
1420 if (!altera_check_stack(stack_ptr, 2, &status))
1421 break;
1422 index = stack[--stack_ptr];
1423 count = stack[--stack_ptr];
1424
1425 if (version > 0)
1426 /*
1427 * stack 0 = array right index
1428 * stack 1 = array left index
1429 */
1430 count = 1 + count - index;
1431
1432 charptr_tmp = (u8 *)vars[args[0]];
1433 status = altera_set_dr_post(&astate->js, count, index,
1434 charptr_tmp);
1435 break;
1436 case OP_IPRA:
1437 /*
1438 * IRPRE with array data
1439 * ...argument 0 is variable ID
1440 * ...stack 0 is array index
1441 * ...stack 1 is count
1442 */
1443 if (!altera_check_stack(stack_ptr, 2, &status))
1444 break;
1445 index = stack[--stack_ptr];
1446 count = stack[--stack_ptr];
1447
1448 if (version > 0)
1449 /*
1450 * stack 0 = array right index
1451 * stack 1 = array left index
1452 */
1453 count = 1 + count - index;
1454
1455 charptr_tmp = (u8 *)vars[args[0]];
1456 status = altera_set_ir_pre(&astate->js, count, index,
1457 charptr_tmp);
1458
1459 break;
1460 case OP_IPOA:
1461 /*
1462 * IRPOST with array data
1463 * ...argument 0 is variable ID
1464 * ...stack 0 is array index
1465 * ...stack 1 is count
1466 */
1467 if (!altera_check_stack(stack_ptr, 2, &status))
1468 break;
1469 index = stack[--stack_ptr];
1470 count = stack[--stack_ptr];
1471
1472 if (version > 0)
1473 /*
1474 * stack 0 = array right index
1475 * stack 1 = array left index
1476 */
1477 count = 1 + count - index;
1478
1479 charptr_tmp = (u8 *)vars[args[0]];
1480 status = altera_set_ir_post(&astate->js, count, index,
1481 charptr_tmp);
1482
1483 break;
1484 case OP_EXPT:
1485 /*
1486 * EXPORT
1487 * ...argument 0 is string ID
1488 * ...stack 0 is integer expression
1489 */
1490 if (altera_check_stack(stack_ptr, 1, &status)) {
1491 name = &p[str_table + args[0]];
1492 long_tmp = stack[--stack_ptr];
1493 altera_export_int(name, long_tmp);
1494 }
1495 break;
1496 case OP_PSHE:
1497 /*
1498 * Push integer array element
1499 * ...argument 0 is variable ID
1500 * ...stack 0 is array index
1501 */
1502 if (!altera_check_stack(stack_ptr, 1, &status))
1503 break;
1504 variable_id = args[0];
1505 index = stack[stack_ptr - 1];
1506
1507 /* check variable type */
1508 if ((attrs[variable_id] & 0x1f) == 0x19) {
1509 /* writable integer array */
1510 longptr_tmp = (long *)vars[variable_id];
1511 stack[stack_ptr - 1] = longptr_tmp[index];
1512 } else if ((attrs[variable_id] & 0x1f) == 0x1c) {
1513 /* read-only integer array */
1514 long_tmp = vars[variable_id] +
1515 (index * sizeof(long));
1516 stack[stack_ptr - 1] =
1517 get_unaligned_be32(&p[long_tmp]);
1518 } else
1519 status = -ERANGE;
1520
1521 break;
1522 case OP_PSHA:
1523 /*
1524 * Push Boolean array
1525 * ...argument 0 is variable ID
1526 * ...stack 0 is count
1527 * ...stack 1 is array index
1528 */
1529 if (!altera_check_stack(stack_ptr, 2, &status))
1530 break;
1531 variable_id = args[0];
1532
1533 /* check that variable is a Boolean array */
1534 if ((attrs[variable_id] & 0x18) != 0x08) {
1535 status = -ERANGE;
1536 break;
1537 }
1538
1539 charptr_tmp = (u8 *)vars[variable_id];
1540
1541 /* pop the count (number of bits to copy) */
1542 count = stack[--stack_ptr];
1543
1544 /* pop the array index */
1545 index = stack[stack_ptr - 1];
1546
1547 if (version > 0)
1548 /*
1549 * stack 0 = array right index
1550 * stack 1 = array left index
1551 */
1552 count = 1 + count - index;
1553
1554 if ((count < 1) || (count > 32)) {
1555 status = -ERANGE;
1556 break;
1557 }
1558
1559 long_tmp = 0L;
1560
1561 for (i = 0; i < count; ++i)
1562 if (charptr_tmp[(i + index) >> 3] &
1563 (1 << ((i + index) & 7)))
1564 long_tmp |= (1L << i);
1565
1566 stack[stack_ptr - 1] = long_tmp;
1567
1568 break;
1569 case OP_DYNA:
1570 /*
1571 * Dynamically change size of array
1572 * ...argument 0 is variable ID
1573 * ...stack 0 is new size
1574 */
1575 if (!altera_check_stack(stack_ptr, 1, &status))
1576 break;
1577 variable_id = args[0];
1578 long_tmp = stack[--stack_ptr];
1579
1580 if (long_tmp > var_size[variable_id]) {
1581 var_size[variable_id] = long_tmp;
1582
1583 if (attrs[variable_id] & 0x10)
1584 /* allocate integer array */
1585 long_tmp *= sizeof(long);
1586 else
1587 /* allocate Boolean array */
1588 long_tmp = (long_tmp + 7) >> 3;
1589
1590 /*
1591 * If the buffer was previously allocated,
1592 * free it
1593 */
1594 if (attrs[variable_id] & 0x80) {
1595 kfree((void *)vars[variable_id]);
1596 vars[variable_id] = 0;
1597 }
1598
1599 /*
1600 * Allocate a new buffer
1601 * of the requested size
1602 */
1603 vars[variable_id] = (long)
1604 kzalloc(long_tmp, GFP_KERNEL);
1605
1606 if (vars[variable_id] == 0) {
1607 status = -ENOMEM;
1608 break;
1609 }
1610
1611 /*
1612 * Set the attribute bit to indicate that
1613 * this buffer was dynamically allocated and
1614 * should be freed later
1615 */
1616 attrs[variable_id] |= 0x80;
1617
1618 /* zero out memory */
1619 count = ((var_size[variable_id] + 7L) /
1620 8L);
1621 charptr_tmp = (u8 *)(vars[variable_id]);
1622 for (index = 0; index < count; ++index)
1623 charptr_tmp[index] = 0;
1624
1625 }
1626
1627 break;
1628 case OP_EXPV:
1629 /*
1630 * Export Boolean array
1631 * ...argument 0 is string ID
1632 * ...stack 0 is variable ID
1633 * ...stack 1 is array right index
1634 * ...stack 2 is array left index
1635 */
1636 if (!altera_check_stack(stack_ptr, 3, &status))
1637 break;
1638 if (version == 0) {
1639 /* EXPV is not supported in JBC 1.0 */
1640 bad_opcode = 1;
1641 break;
1642 }
1643 name = &p[str_table + args[0]];
1644 variable_id = stack[--stack_ptr];
1645 long_idx = stack[--stack_ptr];/* right indx */
1646 long_idx2 = stack[--stack_ptr];/* left indx */
1647
1648 if (long_idx > long_idx2) {
1649 /* reverse indices not supported */
1650 status = -ERANGE;
1651 break;
1652 }
1653
1654 long_count = 1 + long_idx2 - long_idx;
1655
1656 charptr_tmp = (u8 *)vars[variable_id];
1657 charptr_tmp2 = NULL;
1658
1659 if ((long_idx & 7L) != 0) {
1660 s32 k = long_idx;
1661 charptr_tmp2 =
1662 kzalloc(((long_count + 7L) / 8L),
1663 GFP_KERNEL);
1664 if (charptr_tmp2 == NULL) {
1665 status = -ENOMEM;
1666 break;
1667 }
1668
1669 for (i = 0; i < long_count; ++i) {
1670 if (charptr_tmp[k >> 3] &
1671 (1 << (k & 7)))
1672 charptr_tmp2[i >> 3] |=
1673 (1 << (i & 7));
1674 else
1675 charptr_tmp2[i >> 3] &=
1676 ~(1 << (i & 7));
1677
1678 ++k;
1679 }
1680 charptr_tmp = charptr_tmp2;
1681
1682 } else if (long_idx != 0)
1683 charptr_tmp = &charptr_tmp[long_idx >> 3];
1684
1685 altera_export_bool_array(name, charptr_tmp,
1686 long_count);
1687
1688 /* free allocated buffer */
1689 if ((long_idx & 7L) != 0)
1690 kfree(charptr_tmp2);
1691
1692 break;
1693 case OP_COPY: {
1694 /*
1695 * Array copy
1696 * ...argument 0 is dest ID
1697 * ...argument 1 is source ID
1698 * ...stack 0 is count
1699 * ...stack 1 is dest index
1700 * ...stack 2 is source index
1701 */
1702 s32 copy_count;
1703 s32 copy_index;
1704 s32 copy_index2;
1705 s32 destleft;
1706 s32 src_count;
1707 s32 dest_count;
1708 int src_reverse = 0;
1709 int dest_reverse = 0;
1710
1711 if (!altera_check_stack(stack_ptr, 3, &status))
1712 break;
1713
1714 copy_count = stack[--stack_ptr];
1715 copy_index = stack[--stack_ptr];
1716 copy_index2 = stack[--stack_ptr];
1717 reverse = 0;
1718
1719 if (version > 0) {
1720 /*
1721 * stack 0 = source right index
1722 * stack 1 = source left index
1723 * stack 2 = destination right index
1724 * stack 3 = destination left index
1725 */
1726 destleft = stack[--stack_ptr];
1727
1728 if (copy_count > copy_index) {
1729 src_reverse = 1;
1730 reverse = 1;
1731 src_count = 1 + copy_count - copy_index;
1732 /* copy_index = source start index */
1733 } else {
1734 src_count = 1 + copy_index - copy_count;
1735 /* source start index */
1736 copy_index = copy_count;
1737 }
1738
1739 if (copy_index2 > destleft) {
1740 dest_reverse = 1;
1741 reverse = !reverse;
1742 dest_count = 1 + copy_index2 - destleft;
1743 /* destination start index */
1744 copy_index2 = destleft;
1745 } else
1746 dest_count = 1 + destleft - copy_index2;
1747
1748 copy_count = (src_count < dest_count) ?
1749 src_count : dest_count;
1750
1751 if ((src_reverse || dest_reverse) &&
1752 (src_count != dest_count))
1753 /*
1754 * If either the source or destination
1755 * is reversed, we can't tolerate
1756 * a length mismatch, because we
1757 * "left justify" arrays when copying.
1758 * This won't work correctly
1759 * with reversed arrays.
1760 */
1761 status = -ERANGE;
1762
1763 }
1764
1765 count = copy_count;
1766 index = copy_index;
1767 index2 = copy_index2;
1768
1769 /*
1770 * If destination is a read-only array,
1771 * allocate a buffer and convert it to a writable array
1772 */
1773 variable_id = args[1];
1774 if ((version > 0) &&
1775 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1776 /* Allocate a writable buffer for this array */
1777 long_tmp =
1778 (var_size[variable_id] + 7L) >> 3L;
1779 charptr_tmp2 = (u8 *)vars[variable_id];
1780 charptr_tmp =
1781 kzalloc(long_tmp, GFP_KERNEL);
1782 vars[variable_id] = (long)charptr_tmp;
1783
1784 if (vars[variable_id] == 0) {
1785 status = -ENOMEM;
1786 break;
1787 }
1788
1789 /* zero the buffer */
1790 for (long_idx = 0L; long_idx < long_tmp;
1791 ++long_idx)
1792 charptr_tmp[long_idx] = 0;
1793
1794 /* copy previous contents into buffer */
1795 for (long_idx = 0L;
1796 long_idx < var_size[variable_id];
1797 ++long_idx) {
1798 long_idx2 = long_idx;
1799
1800 if (charptr_tmp2[long_idx2 >> 3] &
1801 (1 << (long_idx2 & 7)))
1802 charptr_tmp[long_idx >> 3] |=
1803 (1 << (long_idx & 7));
1804
1805 }
1806
1807 /*
1808 set bit 7 - buffer was dynamically allocated */
1809 attrs[variable_id] |= 0x80;
1810
1811 /* clear bit 2 - variable is writable */
1812 attrs[variable_id] &= ~0x04;
1813 attrs[variable_id] |= 0x01;
1814 }
1815
1816 charptr_tmp = (u8 *)vars[args[1]];
1817 charptr_tmp2 = (u8 *)vars[args[0]];
1818
1819 /* check if destination is a writable Boolean array */
1820 if ((attrs[args[1]] & 0x1c) != 0x08) {
1821 status = -ERANGE;
1822 break;
1823 }
1824
1825 if (count < 1) {
1826 status = -ERANGE;
1827 break;
1828 }
1829
1830 if (reverse)
1831 index2 += (count - 1);
1832
1833 for (i = 0; i < count; ++i) {
1834 if (charptr_tmp2[index >> 3] &
1835 (1 << (index & 7)))
1836 charptr_tmp[index2 >> 3] |=
1837 (1 << (index2 & 7));
1838 else
1839 charptr_tmp[index2 >> 3] &=
1840 ~(1 << (index2 & 7));
1841
1842 ++index;
1843 if (reverse)
1844 --index2;
1845 else
1846 ++index2;
1847 }
1848
1849 break;
1850 }
1851 case OP_DSC:
1852 case OP_ISC: {
1853 /*
1854 * DRSCAN with capture
1855 * IRSCAN with capture
1856 * ...argument 0 is scan data variable ID
1857 * ...argument 1 is capture variable ID
1858 * ...stack 0 is capture index
1859 * ...stack 1 is scan data index
1860 * ...stack 2 is count
1861 */
1862 s32 scan_right, scan_left;
1863 s32 capture_count = 0;
1864 s32 scan_count = 0;
1865 s32 capture_index;
1866 s32 scan_index;
1867
1868 if (!altera_check_stack(stack_ptr, 3, &status))
1869 break;
1870
1871 capture_index = stack[--stack_ptr];
1872 scan_index = stack[--stack_ptr];
1873
1874 if (version > 0) {
1875 /*
1876 * stack 0 = capture right index
1877 * stack 1 = capture left index
1878 * stack 2 = scan right index
1879 * stack 3 = scan left index
1880 * stack 4 = count
1881 */
1882 scan_right = stack[--stack_ptr];
1883 scan_left = stack[--stack_ptr];
1884 capture_count = 1 + scan_index - capture_index;
1885 scan_count = 1 + scan_left - scan_right;
1886 scan_index = scan_right;
1887 }
1888
1889 long_count = stack[--stack_ptr];
1890 /*
1891 * If capture array is read-only, allocate a buffer
1892 * and convert it to a writable array
1893 */
1894 variable_id = args[1];
1895 if ((version > 0) &&
1896 ((attrs[variable_id] & 0x9c) == 0x0c)) {
1897 /* Allocate a writable buffer for this array */
1898 long_tmp =
1899 (var_size[variable_id] + 7L) >> 3L;
1900 charptr_tmp2 = (u8 *)vars[variable_id];
1901 charptr_tmp =
1902 kzalloc(long_tmp, GFP_KERNEL);
1903 vars[variable_id] = (long)charptr_tmp;
1904
1905 if (vars[variable_id] == 0) {
1906 status = -ENOMEM;
1907 break;
1908 }
1909
1910 /* zero the buffer */
1911 for (long_idx = 0L; long_idx < long_tmp;
1912 ++long_idx)
1913 charptr_tmp[long_idx] = 0;
1914
1915 /* copy previous contents into buffer */
1916 for (long_idx = 0L;
1917 long_idx < var_size[variable_id];
1918 ++long_idx) {
1919 long_idx2 = long_idx;
1920
1921 if (charptr_tmp2[long_idx2 >> 3] &
1922 (1 << (long_idx2 & 7)))
1923 charptr_tmp[long_idx >> 3] |=
1924 (1 << (long_idx & 7));
1925
1926 }
1927
1928 /*
1929 * set bit 7 - buffer was
1930 * dynamically allocated
1931 */
1932 attrs[variable_id] |= 0x80;
1933
1934 /* clear bit 2 - variable is writable */
1935 attrs[variable_id] &= ~0x04;
1936 attrs[variable_id] |= 0x01;
1937
1938 }
1939
1940 charptr_tmp = (u8 *)vars[args[0]];
1941 charptr_tmp2 = (u8 *)vars[args[1]];
1942
1943 if ((version > 0) &&
1944 ((long_count > capture_count) ||
1945 (long_count > scan_count))) {
1946 status = -ERANGE;
1947 break;
1948 }
1949
1950 /*
1951 * check that capture array
1952 * is a writable Boolean array
1953 */
1954 if ((attrs[args[1]] & 0x1c) != 0x08) {
1955 status = -ERANGE;
1956 break;
1957 }
1958
1959 if (status == 0) {
1960 if (opcode == 0x82) /* DSC */
1961 status = altera_swap_dr(astate,
1962 long_count,
1963 charptr_tmp,
1964 scan_index,
1965 charptr_tmp2,
1966 capture_index);
1967 else /* ISC */
1968 status = altera_swap_ir(astate,
1969 long_count,
1970 charptr_tmp,
1971 scan_index,
1972 charptr_tmp2,
1973 capture_index);
1974
1975 }
1976
1977 break;
1978 }
1979 case OP_WAIT:
1980 /*
1981 * WAIT
1982 * ...argument 0 is wait state
1983 * ...argument 1 is end state
1984 * ...stack 0 is cycles
1985 * ...stack 1 is microseconds
1986 */
1987 if (!altera_check_stack(stack_ptr, 2, &status))
1988 break;
1989 long_tmp = stack[--stack_ptr];
1990
1991 if (long_tmp != 0L)
1992 status = altera_wait_cycles(astate, long_tmp,
1993 args[0]);
1994
1995 long_tmp = stack[--stack_ptr];
1996
1997 if ((status == 0) && (long_tmp != 0L))
1998 status = altera_wait_msecs(astate,
1999 long_tmp,
2000 args[0]);
2001
2002 if ((status == 0) && (args[1] != args[0]))
2003 status = altera_goto_jstate(astate,
2004 args[1]);
2005
2006 if (version > 0) {
2007 --stack_ptr; /* throw away MAX cycles */
2008 --stack_ptr; /* throw away MAX microseconds */
2009 }
2010 break;
2011 case OP_CMPA: {
2012 /*
2013 * Array compare
2014 * ...argument 0 is source 1 ID
2015 * ...argument 1 is source 2 ID
2016 * ...argument 2 is mask ID
2017 * ...stack 0 is source 1 index
2018 * ...stack 1 is source 2 index
2019 * ...stack 2 is mask index
2020 * ...stack 3 is count
2021 */
2022 s32 a, b;
2023 u8 *source1 = (u8 *)vars[args[0]];
2024 u8 *source2 = (u8 *)vars[args[1]];
2025 u8 *mask = (u8 *)vars[args[2]];
2026 u32 index1;
2027 u32 index2;
2028 u32 mask_index;
2029
2030 if (!altera_check_stack(stack_ptr, 4, &status))
2031 break;
2032
2033 index1 = stack[--stack_ptr];
2034 index2 = stack[--stack_ptr];
2035 mask_index = stack[--stack_ptr];
2036 long_count = stack[--stack_ptr];
2037
2038 if (version > 0) {
2039 /*
2040 * stack 0 = source 1 right index
2041 * stack 1 = source 1 left index
2042 * stack 2 = source 2 right index
2043 * stack 3 = source 2 left index
2044 * stack 4 = mask right index
2045 * stack 5 = mask left index
2046 */
2047 s32 mask_right = stack[--stack_ptr];
2048 s32 mask_left = stack[--stack_ptr];
2049 /* source 1 count */
2050 a = 1 + index2 - index1;
2051 /* source 2 count */
2052 b = 1 + long_count - mask_index;
2053 a = (a < b) ? a : b;
2054 /* mask count */
2055 b = 1 + mask_left - mask_right;
2056 a = (a < b) ? a : b;
2057 /* source 2 start index */
2058 index2 = mask_index;
2059 /* mask start index */
2060 mask_index = mask_right;
2061 long_count = a;
2062 }
2063
2064 long_tmp = 1L;
2065
2066 if (long_count < 1)
2067 status = -ERANGE;
2068 else {
2069 count = long_count;
2070
2071 for (i = 0; i < count; ++i) {
2072 if (mask[mask_index >> 3] &
2073 (1 << (mask_index & 7))) {
2074 a = source1[index1 >> 3] &
2075 (1 << (index1 & 7))
2076 ? 1 : 0;
2077 b = source2[index2 >> 3] &
2078 (1 << (index2 & 7))
2079 ? 1 : 0;
2080
2081 if (a != b) /* failure */
2082 long_tmp = 0L;
2083 }
2084 ++index1;
2085 ++index2;
2086 ++mask_index;
2087 }
2088 }
2089
2090 stack[stack_ptr++] = long_tmp;
2091
2092 break;
2093 }
2094 default:
2095 /* Unrecognized opcode -- ERROR! */
2096 bad_opcode = 1;
2097 break;
2098 }
2099
2100 if (bad_opcode)
2101 status = -ENOSYS;
2102
2103 if ((stack_ptr < 0) || (stack_ptr >= ALTERA_STACK_SIZE))
2104 status = -EOVERFLOW;
2105
2106 if (status != 0) {
2107 done = 1;
2108 *error_address = (s32)(opcode_address - code_sect);
2109 }
2110 }
2111
2112 altera_free_buffers(astate);
2113
2114 /* Free all dynamically allocated arrays */
2115 if ((attrs != NULL) && (vars != NULL))
2116 for (i = 0; i < sym_count; ++i)
2117 if (attrs[i] & 0x80)
2118 kfree((void *)vars[i]);
2119
2120 kfree(vars);
2121 kfree(var_size);
2122 kfree(attrs);
2123 kfree(proc_attributes);
2124
2125 return status;
2126}
2127
2128static int altera_get_note(u8 *p, s32 program_size,
2129 s32 *offset, char *key, char *value, int length)
2130/*
2131 * Gets key and value of NOTE fields in the JBC file.
2132 * Can be called in two modes: if offset pointer is NULL,
2133 * then the function searches for note fields which match
2134 * the key string provided. If offset is not NULL, then
2135 * the function finds the next note field of any key,
2136 * starting at the offset specified by the offset pointer.
2137 * Returns 0 for success, else appropriate error code
2138 */
2139{
2140 int status = -ENODATA;
2141 u32 note_strings = 0L;
2142 u32 note_table = 0L;
2143 u32 note_count = 0L;
2144 u32 first_word = 0L;
2145 int version = 0;
2146 int delta = 0;
2147 char *key_ptr;
2148 char *value_ptr;
2149 int i;
2150
2151 /* Read header information */
2152 if (program_size > 52L) {
2153 first_word = get_unaligned_be32(&p[0]);
2154 version = (first_word & 1L);
2155 delta = version * 8;
2156
2157 note_strings = get_unaligned_be32(&p[8 + delta]);
2158 note_table = get_unaligned_be32(&p[12 + delta]);
2159 note_count = get_unaligned_be32(&p[44 + (2 * delta)]);
2160 }
2161
2162 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2163 return -EIO;
2164
2165 if (note_count <= 0L)
2166 return status;
2167
2168 if (offset == NULL) {
2169 /*
2170 * We will search for the first note with a specific key,
2171 * and return only the value
2172 */
2173 for (i = 0; (i < note_count) &&
2174 (status != 0); ++i) {
2175 key_ptr = &p[note_strings +
2176 get_unaligned_be32(
2177 &p[note_table + (8 * i)])];
2178 if ((strnicmp(key, key_ptr, strlen(key_ptr)) == 0) &&
2179 (key != NULL)) {
2180 status = 0;
2181
2182 value_ptr = &p[note_strings +
2183 get_unaligned_be32(
2184 &p[note_table + (8 * i) + 4])];
2185
2186 if (value != NULL)
2187 strlcpy(value, value_ptr, length);
2188
2189 }
2190 }
2191 } else {
2192 /*
2193 * We will search for the next note, regardless of the key,
2194 * and return both the value and the key
2195 */
2196
2197 i = *offset;
2198
2199 if ((i >= 0) && (i < note_count)) {
2200 status = 0;
2201
2202 if (key != NULL)
2203 strlcpy(key, &p[note_strings +
2204 get_unaligned_be32(
2205 &p[note_table + (8 * i)])],
2206 length);
2207
2208 if (value != NULL)
2209 strlcpy(value, &p[note_strings +
2210 get_unaligned_be32(
2211 &p[note_table + (8 * i) + 4])],
2212 length);
2213
2214 *offset = i + 1;
2215 }
2216 }
2217
2218 return status;
2219}
2220
2221static int altera_check_crc(u8 *p, s32 program_size)
2222{
2223 int status = 0;
2224 u16 local_expected = 0,
2225 local_actual = 0,
2226 shift_reg = 0xffff;
2227 int bit, feedback;
2228 u8 databyte;
2229 u32 i;
2230 u32 crc_section = 0L;
2231 u32 first_word = 0L;
2232 int version = 0;
2233 int delta = 0;
2234
2235 if (program_size > 52L) {
2236 first_word = get_unaligned_be32(&p[0]);
2237 version = (first_word & 1L);
2238 delta = version * 8;
2239
2240 crc_section = get_unaligned_be32(&p[32 + delta]);
2241 }
2242
2243 if ((first_word != 0x4A414D00L) && (first_word != 0x4A414D01L))
2244 status = -EIO;
2245
2246 if (crc_section >= program_size)
2247 status = -EIO;
2248
2249 if (status == 0) {
2250 local_expected = (u16)get_unaligned_be16(&p[crc_section]);
2251
2252 for (i = 0; i < crc_section; ++i) {
2253 databyte = p[i];
2254 for (bit = 0; bit < 8; bit++) {
2255 feedback = (databyte ^ shift_reg) & 0x01;
2256 shift_reg >>= 1;
2257 if (feedback)
2258 shift_reg ^= 0x8408;
2259
2260 databyte >>= 1;
2261 }
2262 }
2263
2264 local_actual = (u16)~shift_reg;
2265
2266 if (local_expected != local_actual)
2267 status = -EILSEQ;
2268
2269 }
2270
2271 if (debug || status) {
2272 switch (status) {
2273 case 0:
2274 printk(KERN_INFO "%s: CRC matched: %04x\n", __func__,
2275 local_actual);
2276 break;
2277 case -EILSEQ:
2278 printk(KERN_ERR "%s: CRC mismatch: expected %04x, "
2279 "actual %04x\n", __func__, local_expected,
2280 local_actual);
2281 break;
2282 case -ENODATA:
2283 printk(KERN_ERR "%s: expected CRC not found, "
2284 "actual CRC = %04x\n", __func__,
2285 local_actual);
2286 break;
2287 case -EIO:
2288 printk(KERN_ERR "%s: error: format isn't "
2289 "recognized.\n", __func__);
2290 break;
2291 default:
2292 printk(KERN_ERR "%s: CRC function returned error "
2293 "code %d\n", __func__, status);
2294 break;
2295 }
2296 }
2297
2298 return status;
2299}
2300
2301static int altera_get_file_info(u8 *p,
2302 s32 program_size,
2303 int *format_version,
2304 int *action_count,
2305 int *procedure_count)
2306{
2307 int status = -EIO;
2308 u32 first_word = 0;
2309 int version = 0;
2310
2311 if (program_size <= 52L)
2312 return status;
2313
2314 first_word = get_unaligned_be32(&p[0]);
2315
2316 if ((first_word == 0x4A414D00L) || (first_word == 0x4A414D01L)) {
2317 status = 0;
2318
2319 version = (first_word & 1L);
2320 *format_version = version + 1;
2321
2322 if (version > 0) {
2323 *action_count = get_unaligned_be32(&p[48]);
2324 *procedure_count = get_unaligned_be32(&p[52]);
2325 }
2326 }
2327
2328 return status;
2329}
2330
2331static int altera_get_act_info(u8 *p,
2332 s32 program_size,
2333 int index,
2334 char **name,
2335 char **description,
2336 struct altera_procinfo **proc_list)
2337{
2338 int status = -EIO;
2339 struct altera_procinfo *procptr = NULL;
2340 struct altera_procinfo *tmpptr = NULL;
2341 u32 first_word = 0L;
2342 u32 action_table = 0L;
2343 u32 proc_table = 0L;
2344 u32 str_table = 0L;
2345 u32 note_strings = 0L;
2346 u32 action_count = 0L;
2347 u32 proc_count = 0L;
2348 u32 act_name_id = 0L;
2349 u32 act_desc_id = 0L;
2350 u32 act_proc_id = 0L;
2351 u32 act_proc_name = 0L;
2352 u8 act_proc_attribute = 0;
2353
2354 if (program_size <= 52L)
2355 return status;
2356 /* Read header information */
2357 first_word = get_unaligned_be32(&p[0]);
2358
2359 if (first_word != 0x4A414D01L)
2360 return status;
2361
2362 action_table = get_unaligned_be32(&p[4]);
2363 proc_table = get_unaligned_be32(&p[8]);
2364 str_table = get_unaligned_be32(&p[12]);
2365 note_strings = get_unaligned_be32(&p[16]);
2366 action_count = get_unaligned_be32(&p[48]);
2367 proc_count = get_unaligned_be32(&p[52]);
2368
2369 if (index >= action_count)
2370 return status;
2371
2372 act_name_id = get_unaligned_be32(&p[action_table + (12 * index)]);
2373 act_desc_id = get_unaligned_be32(&p[action_table + (12 * index) + 4]);
2374 act_proc_id = get_unaligned_be32(&p[action_table + (12 * index) + 8]);
2375
2376 *name = &p[str_table + act_name_id];
2377
2378 if (act_desc_id < (note_strings - str_table))
2379 *description = &p[str_table + act_desc_id];
2380
2381 do {
2382 act_proc_name = get_unaligned_be32(
2383 &p[proc_table + (13 * act_proc_id)]);
2384 act_proc_attribute =
2385 (p[proc_table + (13 * act_proc_id) + 8] & 0x03);
2386
2387 procptr = (struct altera_procinfo *)
2388 kzalloc(sizeof(struct altera_procinfo),
2389 GFP_KERNEL);
2390
2391 if (procptr == NULL)
2392 status = -ENOMEM;
2393 else {
2394 procptr->name = &p[str_table + act_proc_name];
2395 procptr->attrs = act_proc_attribute;
2396 procptr->next = NULL;
2397
2398 /* add record to end of linked list */
2399 if (*proc_list == NULL)
2400 *proc_list = procptr;
2401 else {
2402 tmpptr = *proc_list;
2403 while (tmpptr->next != NULL)
2404 tmpptr = tmpptr->next;
2405 tmpptr->next = procptr;
2406 }
2407 }
2408
2409 act_proc_id = get_unaligned_be32(
2410 &p[proc_table + (13 * act_proc_id) + 4]);
2411 } while ((act_proc_id != 0) && (act_proc_id < proc_count));
2412
2413 return status;
2414}
2415
2416int altera_init(struct altera_config *config, const struct firmware *fw)
2417{
2418 struct altera_state *astate = NULL;
2419 struct altera_procinfo *proc_list = NULL;
2420 struct altera_procinfo *procptr = NULL;
2421 char *key = NULL;
2422 char *value = NULL;
2423 char *action_name = NULL;
2424 char *description = NULL;
2425 int exec_result = 0;
2426 int exit_code = 0;
2427 int format_version = 0;
2428 int action_count = 0;
2429 int procedure_count = 0;
2430 int index = 0;
2431 s32 offset = 0L;
2432 s32 error_address = 0L;
2433
2434 key = kzalloc(33 * sizeof(char), GFP_KERNEL);
2435 if (!key)
2436 return -ENOMEM;
2437 value = kzalloc(257 * sizeof(char), GFP_KERNEL);
2438 if (!value)
2439 return -ENOMEM;
2440 astate = kzalloc(sizeof(struct altera_state), GFP_KERNEL);
2441 if (!astate)
2442 return -ENOMEM;
2443
2444 astate->config = config;
2445 if (!astate->config->jtag_io) {
2446 dprintk(KERN_INFO "%s: using byteblaster!\n", __func__);
2447 astate->config->jtag_io = netup_jtag_io_lpt;
2448 }
2449
2450 altera_check_crc((u8 *)fw->data, fw->size);
2451
2452 if (debug) {
2453 altera_get_file_info((u8 *)fw->data, fw->size, &format_version,
2454 &action_count, &procedure_count);
2455 printk(KERN_INFO "%s: File format is %s ByteCode format\n",
2456 __func__, (format_version == 2) ? "Jam STAPL" :
2457 "pre-standardized Jam 1.1");
2458 while (altera_get_note((u8 *)fw->data, fw->size,
2459 &offset, key, value, 256) == 0)
2460 printk(KERN_INFO "%s: NOTE \"%s\" = \"%s\"\n",
2461 __func__, key, value);
2462 }
2463
2464 if (debug && (format_version == 2) && (action_count > 0)) {
2465 printk(KERN_INFO "%s: Actions available:\n", __func__);
2466 for (index = 0; index < action_count; ++index) {
2467 altera_get_act_info((u8 *)fw->data, fw->size,
2468 index, &action_name,
2469 &description,
2470 &proc_list);
2471
2472 if (description == NULL)
2473 printk(KERN_INFO "%s: %s\n",
2474 __func__,
2475 action_name);
2476 else
2477 printk(KERN_INFO "%s: %s \"%s\"\n",
2478 __func__,
2479 action_name,
2480 description);
2481
2482 procptr = proc_list;
2483 while (procptr != NULL) {
2484 if (procptr->attrs != 0)
2485 printk(KERN_INFO "%s: %s (%s)\n",
2486 __func__,
2487 procptr->name,
2488 (procptr->attrs == 1) ?
2489 "optional" : "recommended");
2490
2491 proc_list = procptr->next;
2492 kfree(procptr);
2493 procptr = proc_list;
2494 }
2495 }
2496
2497 printk(KERN_INFO "\n");
2498 }
2499
2500 exec_result = altera_execute(astate, (u8 *)fw->data, fw->size,
2501 &error_address, &exit_code, &format_version);
2502
2503 if (exit_code)
2504 exec_result = -EREMOTEIO;
2505
2506 if ((format_version == 2) && (exec_result == -EINVAL)) {
2507 if (astate->config->action == NULL)
2508 printk(KERN_ERR "%s: error: no action specified for "
2509 "Jam STAPL file.\nprogram terminated.\n",
2510 __func__);
2511 else
2512 printk(KERN_ERR "%s: error: action \"%s\""
2513 " is not supported "
2514 "for this Jam STAPL file.\n"
2515 "Program terminated.\n", __func__,
2516 astate->config->action);
2517
2518 } else if (exec_result)
2519 printk(KERN_ERR "%s: error %d\n", __func__, exec_result);
2520
2521 kfree(key);
2522 kfree(value);
2523 kfree(astate);
2524
2525 return 0;
2526}
2527EXPORT_SYMBOL(altera_init);
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/staging/cx25821/Kconfig
index b2656957aa8f..5f6b54213713 100644
--- a/drivers/staging/cx25821/Kconfig
+++ b/drivers/staging/cx25821/Kconfig
@@ -1,7 +1,6 @@
1config VIDEO_CX25821 1config VIDEO_CX25821
2 tristate "Conexant cx25821 support" 2 tristate "Conexant cx25821 support"
3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C 3 depends on DVB_CORE && VIDEO_DEV && PCI && I2C
4 depends on BKL # please fix
5 select I2C_ALGOBIT 4 select I2C_ALGOBIT
6 select VIDEO_BTCX 5 select VIDEO_BTCX
7 select VIDEO_TVEEPROM 6 select VIDEO_TVEEPROM
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c
index 160f6693aa33..ebdba7c65bc5 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/staging/cx25821/cx25821-alsa.c
@@ -770,10 +770,12 @@ static int cx25821_alsa_init(void)
770 struct cx25821_dev *dev = NULL; 770 struct cx25821_dev *dev = NULL;
771 struct list_head *list; 771 struct list_head *list;
772 772
773 mutex_lock(&cx25821_devlist_mutex);
773 list_for_each(list, &cx25821_devlist) { 774 list_for_each(list, &cx25821_devlist) {
774 dev = list_entry(list, struct cx25821_dev, devlist); 775 dev = list_entry(list, struct cx25821_dev, devlist);
775 cx25821_audio_initdev(dev); 776 cx25821_audio_initdev(dev);
776 } 777 }
778 mutex_unlock(&cx25821_devlist_mutex);
777 779
778 if (dev == NULL) 780 if (dev == NULL)
779 pr_info("ERROR ALSA: no cx25821 cards found\n"); 781 pr_info("ERROR ALSA: no cx25821 cards found\n");
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/staging/cx25821/cx25821-core.c
index a216b620b718..523ac5e16c1b 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/staging/cx25821/cx25821-core.c
@@ -33,9 +33,6 @@ MODULE_DESCRIPTION("Driver for Athena cards");
33MODULE_AUTHOR("Shu Lin - Hiep Huynh"); 33MODULE_AUTHOR("Shu Lin - Hiep Huynh");
34MODULE_LICENSE("GPL"); 34MODULE_LICENSE("GPL");
35 35
36struct list_head cx25821_devlist;
37EXPORT_SYMBOL(cx25821_devlist);
38
39static unsigned int debug; 36static unsigned int debug;
40module_param(debug, int, 0644); 37module_param(debug, int, 0644);
41MODULE_PARM_DESC(debug, "enable debug messages"); 38MODULE_PARM_DESC(debug, "enable debug messages");
@@ -46,8 +43,10 @@ MODULE_PARM_DESC(card, "card type");
46 43
47static unsigned int cx25821_devcount; 44static unsigned int cx25821_devcount;
48 45
49static DEFINE_MUTEX(devlist); 46DEFINE_MUTEX(cx25821_devlist_mutex);
47EXPORT_SYMBOL(cx25821_devlist_mutex);
50LIST_HEAD(cx25821_devlist); 48LIST_HEAD(cx25821_devlist);
49EXPORT_SYMBOL(cx25821_devlist);
51 50
52struct sram_channel cx25821_sram_channels[] = { 51struct sram_channel cx25821_sram_channels[] = {
53 [SRAM_CH00] = { 52 [SRAM_CH00] = {
@@ -911,9 +910,9 @@ static int cx25821_dev_setup(struct cx25821_dev *dev)
911 dev->nr = ++cx25821_devcount; 910 dev->nr = ++cx25821_devcount;
912 sprintf(dev->name, "cx25821[%d]", dev->nr); 911 sprintf(dev->name, "cx25821[%d]", dev->nr);
913 912
914 mutex_lock(&devlist); 913 mutex_lock(&cx25821_devlist_mutex);
915 list_add_tail(&dev->devlist, &cx25821_devlist); 914 list_add_tail(&dev->devlist, &cx25821_devlist);
916 mutex_unlock(&devlist); 915 mutex_unlock(&cx25821_devlist_mutex);
917 916
918 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown"); 917 strcpy(cx25821_boards[UNKNOWN_BOARD].name, "unknown");
919 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821"); 918 strcpy(cx25821_boards[CX25821_BOARD].name, "cx25821");
@@ -1465,9 +1464,9 @@ static void __devexit cx25821_finidev(struct pci_dev *pci_dev)
1465 if (pci_dev->irq) 1464 if (pci_dev->irq)
1466 free_irq(pci_dev->irq, dev); 1465 free_irq(pci_dev->irq, dev);
1467 1466
1468 mutex_lock(&devlist); 1467 mutex_lock(&cx25821_devlist_mutex);
1469 list_del(&dev->devlist); 1468 list_del(&dev->devlist);
1470 mutex_unlock(&devlist); 1469 mutex_unlock(&cx25821_devlist_mutex);
1471 1470
1472 cx25821_dev_unregister(dev); 1471 cx25821_dev_unregister(dev);
1473 v4l2_device_unregister(v4l2_dev); 1472 v4l2_device_unregister(v4l2_dev);
@@ -1501,7 +1500,6 @@ static struct pci_driver cx25821_pci_driver = {
1501 1500
1502static int __init cx25821_init(void) 1501static int __init cx25821_init(void)
1503{ 1502{
1504 INIT_LIST_HEAD(&cx25821_devlist);
1505 pr_info("driver version %d.%d.%d loaded\n", 1503 pr_info("driver version %d.%d.%d loaded\n",
1506 (CX25821_VERSION_CODE >> 16) & 0xff, 1504 (CX25821_VERSION_CODE >> 16) & 0xff,
1507 (CX25821_VERSION_CODE >> 8) & 0xff, 1505 (CX25821_VERSION_CODE >> 8) & 0xff,
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/staging/cx25821/cx25821-video.c
index 0d8d75670516..ab05392386e8 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/staging/cx25821/cx25821-video.c
@@ -27,7 +27,6 @@
27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 28
29#include "cx25821-video.h" 29#include "cx25821-video.h"
30#include <linux/smp_lock.h>
31 30
32MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards"); 31MODULE_DESCRIPTION("v4l2 driver module for cx25821 based TV cards");
33MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>"); 32MODULE_AUTHOR("Hiep Huynh <hiep.huynh@conexant.com>");
@@ -815,7 +814,7 @@ static int video_open(struct file *file)
815 if (NULL == fh) 814 if (NULL == fh)
816 return -ENOMEM; 815 return -ENOMEM;
817 816
818 lock_kernel(); 817 mutex_lock(&cx25821_devlist_mutex);
819 818
820 list_for_each(list, &cx25821_devlist) 819 list_for_each(list, &cx25821_devlist)
821 { 820 {
@@ -832,8 +831,8 @@ static int video_open(struct file *file)
832 } 831 }
833 832
834 if (NULL == dev) { 833 if (NULL == dev) {
835 unlock_kernel(); 834 mutex_unlock(&cx25821_devlist_mutex);
836 return -ENODEV; 835 return -ENODEV;
837 } 836 }
838 837
839 file->private_data = fh; 838 file->private_data = fh;
@@ -862,7 +861,7 @@ static int video_open(struct file *file)
862 sizeof(struct cx25821_buffer), fh, NULL); 861 sizeof(struct cx25821_buffer), fh, NULL);
863 862
864 dprintk(1, "post videobuf_queue_init()\n"); 863 dprintk(1, "post videobuf_queue_init()\n");
865 unlock_kernel(); 864 mutex_unlock(&cx25821_devlist_mutex);
866 865
867 return 0; 866 return 0;
868} 867}
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/staging/cx25821/cx25821.h
index 55115235f7f6..6230243e2ccb 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/staging/cx25821/cx25821.h
@@ -31,7 +31,6 @@
31#include <linux/delay.h> 31#include <linux/delay.h>
32#include <linux/sched.h> 32#include <linux/sched.h>
33#include <linux/kdev_t.h> 33#include <linux/kdev_t.h>
34#include <linux/smp_lock.h>
35 34
36#include <media/v4l2-common.h> 35#include <media/v4l2-common.h>
37#include <media/v4l2-device.h> 36#include <media/v4l2-device.h>
@@ -445,6 +444,8 @@ static inline struct cx25821_dev *get_cx25821(struct v4l2_device *v4l2_dev)
445 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args) 444 v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
446 445
447extern struct list_head cx25821_devlist; 446extern struct list_head cx25821_devlist;
447extern struct mutex cx25821_devlist_mutex;
448
448extern struct cx25821_board cx25821_boards[]; 449extern struct cx25821_board cx25821_boards[];
449extern struct cx25821_subid cx25821_subids[]; 450extern struct cx25821_subid cx25821_subids[];
450 451
diff --git a/drivers/staging/cxd2099/Kconfig b/drivers/staging/cxd2099/Kconfig
new file mode 100644
index 000000000000..9d638c30735d
--- /dev/null
+++ b/drivers/staging/cxd2099/Kconfig
@@ -0,0 +1,11 @@
1config DVB_CXD2099
2 tristate "CXD2099AR Common Interface driver"
3 depends on DVB_CORE && PCI && I2C && DVB_NGENE
4 ---help---
5 Support for the CI module found on cineS2 DVB-S2, supported by
6 the Micronas PCIe device driver (ngene).
7
8 For now, data is passed through '/dev/dvb/adapterX/sec0':
9 - Encrypted data must be written to 'sec0'.
10 - Decrypted data can be read from 'sec0'.
11 - Setup the CAM using device 'ca0'.
diff --git a/drivers/staging/cxd2099/Makefile b/drivers/staging/cxd2099/Makefile
new file mode 100644
index 000000000000..72b14558c119
--- /dev/null
+++ b/drivers/staging/cxd2099/Makefile
@@ -0,0 +1,5 @@
1obj-$(CONFIG_DVB_CXD2099) += cxd2099.o
2
3EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
4EXTRA_CFLAGS += -Idrivers/media/dvb/frontends/
5EXTRA_CFLAGS += -Idrivers/media/common/tuners/
diff --git a/drivers/staging/cxd2099/TODO b/drivers/staging/cxd2099/TODO
new file mode 100644
index 000000000000..375bb6f8ee2c
--- /dev/null
+++ b/drivers/staging/cxd2099/TODO
@@ -0,0 +1,12 @@
1For now, data is passed through '/dev/dvb/adapterX/sec0':
2 - Encrypted data must be written to 'sec0'.
3 - Decrypted data can be read from 'sec0'.
4 - Setup the CAM using device 'ca0'.
5
6But this is wrong. There are some discussions about the proper way for
7doing it, as seen at:
8 http://www.mail-archive.com/linux-media@vger.kernel.org/msg22196.html
9
10While there's no proper fix for it, the driver should be kept in staging.
11
12Patches should be submitted to: linux-media@vger.kernel.org.
diff --git a/drivers/staging/cxd2099/cxd2099.c b/drivers/staging/cxd2099/cxd2099.c
new file mode 100644
index 000000000000..b49186c74eb3
--- /dev/null
+++ b/drivers/staging/cxd2099/cxd2099.c
@@ -0,0 +1,574 @@
1/*
2 * cxd2099.c: Driver for the CXD2099AR Common Interface Controller
3 *
4 * Copyright (C) 2010 DigitalDevices UG
5 *
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
9 * version 2 only, as published by the Free Software Foundation.
10 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 */
24
25#include <linux/version.h>
26#include <linux/slab.h>
27#include <linux/kernel.h>
28#include <linux/module.h>
29#include <linux/moduleparam.h>
30#include <linux/init.h>
31#include <linux/i2c.h>
32#include <linux/wait.h>
33#include <linux/delay.h>
34#include <linux/mutex.h>
35#include <linux/io.h>
36
37#include "cxd2099.h"
38
39#define MAX_BUFFER_SIZE 248
40
41struct cxd {
42 struct dvb_ca_en50221 en;
43
44 struct i2c_adapter *i2c;
45 u8 adr;
46 u8 regs[0x23];
47 u8 lastaddress;
48 u8 clk_reg_f;
49 u8 clk_reg_b;
50 int mode;
51 u32 bitrate;
52 int ready;
53 int dr;
54 int slot_stat;
55
56 u8 amem[1024];
57 int amem_read;
58
59 int cammode;
60 struct mutex lock;
61};
62
63static int i2c_write_reg(struct i2c_adapter *adapter, u8 adr,
64 u8 reg, u8 data)
65{
66 u8 m[2] = {reg, data};
67 struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = m, .len = 2};
68
69 if (i2c_transfer(adapter, &msg, 1) != 1) {
70 printk(KERN_ERR "Failed to write to I2C register %02x@%02x!\n",
71 reg, adr);
72 return -1;
73 }
74 return 0;
75}
76
77static int i2c_write(struct i2c_adapter *adapter, u8 adr,
78 u8 *data, u8 len)
79{
80 struct i2c_msg msg = {.addr = adr, .flags = 0, .buf = data, .len = len};
81
82 if (i2c_transfer(adapter, &msg, 1) != 1) {
83 printk(KERN_ERR "Failed to write to I2C!\n");
84 return -1;
85 }
86 return 0;
87}
88
89static int i2c_read_reg(struct i2c_adapter *adapter, u8 adr,
90 u8 reg, u8 *val)
91{
92 struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
93 .buf = &reg, .len = 1 },
94 {.addr = adr, .flags = I2C_M_RD,
95 .buf = val, .len = 1 } };
96
97 if (i2c_transfer(adapter, msgs, 2) != 2) {
98 printk(KERN_ERR "error in i2c_read_reg\n");
99 return -1;
100 }
101 return 0;
102}
103
104static int i2c_read(struct i2c_adapter *adapter, u8 adr,
105 u8 reg, u8 *data, u8 n)
106{
107 struct i2c_msg msgs[2] = {{.addr = adr, .flags = 0,
108 .buf = &reg, .len = 1 },
109 {.addr = adr, .flags = I2C_M_RD,
110 .buf = data, .len = n } };
111
112 if (i2c_transfer(adapter, msgs, 2) != 2) {
113 printk(KERN_ERR "error in i2c_read\n");
114 return -1;
115 }
116 return 0;
117}
118
119static int read_block(struct cxd *ci, u8 adr, u8 *data, u8 n)
120{
121 int status;
122
123 status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
124 if (!status) {
125 ci->lastaddress = adr;
126 status = i2c_read(ci->i2c, ci->adr, 1, data, n);
127 }
128 return status;
129}
130
131static int read_reg(struct cxd *ci, u8 reg, u8 *val)
132{
133 return read_block(ci, reg, val, 1);
134}
135
136
137static int read_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
138{
139 int status;
140 u8 addr[3] = { 2, address&0xff, address>>8 };
141
142 status = i2c_write(ci->i2c, ci->adr, addr, 3);
143 if (!status)
144 status = i2c_read(ci->i2c, ci->adr, 3, data, n);
145 return status;
146}
147
148static int write_pccard(struct cxd *ci, u16 address, u8 *data, u8 n)
149{
150 int status;
151 u8 addr[3] = { 2, address&0xff, address>>8 };
152
153 status = i2c_write(ci->i2c, ci->adr, addr, 3);
154 if (!status) {
155 u8 buf[256] = {3};
156 memcpy(buf+1, data, n);
157 status = i2c_write(ci->i2c, ci->adr, buf, n+1);
158 }
159 return status;
160}
161
162static int read_io(struct cxd *ci, u16 address, u8 *val)
163{
164 int status;
165 u8 addr[3] = { 2, address&0xff, address>>8 };
166
167 status = i2c_write(ci->i2c, ci->adr, addr, 3);
168 if (!status)
169 status = i2c_read(ci->i2c, ci->adr, 3, val, 1);
170 return status;
171}
172
173static int write_io(struct cxd *ci, u16 address, u8 val)
174{
175 int status;
176 u8 addr[3] = { 2, address&0xff, address>>8 };
177 u8 buf[2] = { 3, val };
178
179 status = i2c_write(ci->i2c, ci->adr, addr, 3);
180 if (!status)
181 status = i2c_write(ci->i2c, ci->adr, buf, 2);
182
183 return status;
184}
185
186
187static int write_regm(struct cxd *ci, u8 reg, u8 val, u8 mask)
188{
189 int status;
190
191 status = i2c_write_reg(ci->i2c, ci->adr, 0, reg);
192 if (!status && reg >= 6 && reg <= 8 && mask != 0xff)
193 status = i2c_read_reg(ci->i2c, ci->adr, 1, &ci->regs[reg]);
194 ci->regs[reg] = (ci->regs[reg]&(~mask))|val;
195 if (!status) {
196 ci->lastaddress = reg;
197 status = i2c_write_reg(ci->i2c, ci->adr, 1, ci->regs[reg]);
198 }
199 if (reg == 0x20)
200 ci->regs[reg] &= 0x7f;
201 return status;
202}
203
204static int write_reg(struct cxd *ci, u8 reg, u8 val)
205{
206 return write_regm(ci, reg, val, 0xff);
207}
208
209#ifdef BUFFER_MODE
210static int write_block(struct cxd *ci, u8 adr, u8 *data, int n)
211{
212 int status;
213 u8 buf[256] = {1};
214
215 status = i2c_write_reg(ci->i2c, ci->adr, 0, adr);
216 if (!status) {
217 ci->lastaddress = adr;
218 memcpy(buf+1, data, n);
219 status = i2c_write(ci->i2c, ci->adr, buf, n+1);
220 }
221 return status;
222}
223#endif
224
225static void set_mode(struct cxd *ci, int mode)
226{
227 if (mode == ci->mode)
228 return;
229
230 switch (mode) {
231 case 0x00: /* IO mem */
232 write_regm(ci, 0x06, 0x00, 0x07);
233 break;
234 case 0x01: /* ATT mem */
235 write_regm(ci, 0x06, 0x02, 0x07);
236 break;
237 default:
238 break;
239 }
240 ci->mode = mode;
241}
242
243static void cam_mode(struct cxd *ci, int mode)
244{
245 if (mode == ci->cammode)
246 return;
247
248 switch (mode) {
249 case 0x00:
250 write_regm(ci, 0x20, 0x80, 0x80);
251 break;
252 case 0x01:
253 printk(KERN_INFO "enable cam buffer mode\n");
254 /* write_reg(ci, 0x0d, 0x00); */
255 /* write_reg(ci, 0x0e, 0x01); */
256 write_regm(ci, 0x08, 0x40, 0x40);
257 /* read_reg(ci, 0x12, &dummy); */
258 write_regm(ci, 0x08, 0x80, 0x80);
259 break;
260 default:
261 break;
262 }
263 ci->cammode = mode;
264}
265
266
267
268#define CHK_ERROR(s) if ((status = s)) break
269
270static int init(struct cxd *ci)
271{
272 int status;
273
274 mutex_lock(&ci->lock);
275 ci->mode = -1;
276 do {
277 CHK_ERROR(write_reg(ci, 0x00, 0x00));
278 CHK_ERROR(write_reg(ci, 0x01, 0x00));
279 CHK_ERROR(write_reg(ci, 0x02, 0x10));
280 CHK_ERROR(write_reg(ci, 0x03, 0x00));
281 CHK_ERROR(write_reg(ci, 0x05, 0xFF));
282 CHK_ERROR(write_reg(ci, 0x06, 0x1F));
283 CHK_ERROR(write_reg(ci, 0x07, 0x1F));
284 CHK_ERROR(write_reg(ci, 0x08, 0x28));
285 CHK_ERROR(write_reg(ci, 0x14, 0x20));
286
287 CHK_ERROR(write_reg(ci, 0x09, 0x4D)); /* Input Mode C, BYPass Serial, TIVAL = low, MSB */
288 CHK_ERROR(write_reg(ci, 0x0A, 0xA7)); /* TOSTRT = 8, Mode B (gated clock), falling Edge, Serial, POL=HIGH, MSB */
289
290 /* Sync detector */
291 CHK_ERROR(write_reg(ci, 0x0B, 0x33));
292 CHK_ERROR(write_reg(ci, 0x0C, 0x33));
293
294 CHK_ERROR(write_regm(ci, 0x14, 0x00, 0x0F));
295 CHK_ERROR(write_reg(ci, 0x15, ci->clk_reg_b));
296 CHK_ERROR(write_regm(ci, 0x16, 0x00, 0x0F));
297 CHK_ERROR(write_reg(ci, 0x17, ci->clk_reg_f));
298
299 CHK_ERROR(write_reg(ci, 0x20, 0x28)); /* Integer Divider, Falling Edge, Internal Sync, */
300 CHK_ERROR(write_reg(ci, 0x21, 0x00)); /* MCLKI = TICLK/8 */
301 CHK_ERROR(write_reg(ci, 0x22, 0x07)); /* MCLKI = TICLK/8 */
302
303
304 CHK_ERROR(write_regm(ci, 0x20, 0x80, 0x80)); /* Reset CAM state machine */
305
306 CHK_ERROR(write_regm(ci, 0x03, 0x02, 02)); /* Enable IREQA Interrupt */
307 CHK_ERROR(write_reg(ci, 0x01, 0x04)); /* Enable CD Interrupt */
308 CHK_ERROR(write_reg(ci, 0x00, 0x31)); /* Enable TS1,Hot Swap,Slot A */
309 CHK_ERROR(write_regm(ci, 0x09, 0x08, 0x08)); /* Put TS in bypass */
310 ci->cammode = -1;
311#ifdef BUFFER_MODE
312 cam_mode(ci, 0);
313#endif
314 } while (0);
315 mutex_unlock(&ci->lock);
316
317 return 0;
318}
319
320
321static int read_attribute_mem(struct dvb_ca_en50221 *ca,
322 int slot, int address)
323{
324 struct cxd *ci = ca->data;
325 u8 val;
326 mutex_lock(&ci->lock);
327 set_mode(ci, 1);
328 read_pccard(ci, address, &val, 1);
329 mutex_unlock(&ci->lock);
330 return val;
331}
332
333
334static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
335 int address, u8 value)
336{
337 struct cxd *ci = ca->data;
338
339 mutex_lock(&ci->lock);
340 set_mode(ci, 1);
341 write_pccard(ci, address, &value, 1);
342 mutex_unlock(&ci->lock);
343 return 0;
344}
345
346static int read_cam_control(struct dvb_ca_en50221 *ca,
347 int slot, u8 address)
348{
349 struct cxd *ci = ca->data;
350 u8 val;
351
352 mutex_lock(&ci->lock);
353 set_mode(ci, 0);
354 read_io(ci, address, &val);
355 mutex_unlock(&ci->lock);
356 return val;
357}
358
359static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
360 u8 address, u8 value)
361{
362 struct cxd *ci = ca->data;
363
364 mutex_lock(&ci->lock);
365 set_mode(ci, 0);
366 write_io(ci, address, value);
367 mutex_unlock(&ci->lock);
368 return 0;
369}
370
371static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
372{
373 struct cxd *ci = ca->data;
374
375 mutex_lock(&ci->lock);
376 cam_mode(ci, 0);
377 write_reg(ci, 0x00, 0x21);
378 write_reg(ci, 0x06, 0x1F);
379 write_reg(ci, 0x00, 0x31);
380 write_regm(ci, 0x20, 0x80, 0x80);
381 write_reg(ci, 0x03, 0x02);
382 ci->ready = 0;
383 ci->mode = -1;
384 {
385 int i;
386 for (i = 0; i < 100; i++) {
387 msleep(10);
388 if (ci->ready)
389 break;
390 }
391 }
392 mutex_unlock(&ci->lock);
393 /* msleep(500); */
394 return 0;
395}
396
397static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
398{
399 struct cxd *ci = ca->data;
400
401 printk(KERN_INFO "slot_shutdown\n");
402 mutex_lock(&ci->lock);
403 /* write_regm(ci, 0x09, 0x08, 0x08); */
404 write_regm(ci, 0x20, 0x80, 0x80);
405 write_regm(ci, 0x06, 0x07, 0x07);
406 ci->mode = -1;
407 mutex_unlock(&ci->lock);
408 return 0; /* shutdown(ci); */
409}
410
411static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
412{
413 struct cxd *ci = ca->data;
414
415 mutex_lock(&ci->lock);
416 write_regm(ci, 0x09, 0x00, 0x08);
417 set_mode(ci, 0);
418#ifdef BUFFER_MODE
419 cam_mode(ci, 1);
420#endif
421 mutex_unlock(&ci->lock);
422 return 0;
423}
424
425
426static int campoll(struct cxd *ci)
427{
428 u8 istat;
429
430 read_reg(ci, 0x04, &istat);
431 if (!istat)
432 return 0;
433 write_reg(ci, 0x05, istat);
434
435 if (istat&0x40) {
436 ci->dr = 1;
437 printk(KERN_INFO "DR\n");
438 }
439 if (istat&0x20)
440 printk(KERN_INFO "WC\n");
441
442 if (istat&2) {
443 u8 slotstat;
444
445 read_reg(ci, 0x01, &slotstat);
446 if (!(2&slotstat)) {
447 if (!ci->slot_stat) {
448 ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
449 write_regm(ci, 0x03, 0x08, 0x08);
450 }
451
452 } else {
453 if (ci->slot_stat) {
454 ci->slot_stat = 0;
455 write_regm(ci, 0x03, 0x00, 0x08);
456 printk(KERN_INFO "NO CAM\n");
457 ci->ready = 0;
458 }
459 }
460 if (istat&8 && ci->slot_stat == DVB_CA_EN50221_POLL_CAM_PRESENT) {
461 ci->ready = 1;
462 ci->slot_stat |= DVB_CA_EN50221_POLL_CAM_READY;
463 printk(KERN_INFO "READY\n");
464 }
465 }
466 return 0;
467}
468
469
470static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
471{
472 struct cxd *ci = ca->data;
473 u8 slotstat;
474
475 mutex_lock(&ci->lock);
476 campoll(ci);
477 read_reg(ci, 0x01, &slotstat);
478 mutex_unlock(&ci->lock);
479
480 return ci->slot_stat;
481}
482
483#ifdef BUFFER_MODE
484static int read_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
485{
486 struct cxd *ci = ca->data;
487 u8 msb, lsb;
488 u16 len;
489
490 mutex_lock(&ci->lock);
491 campoll(ci);
492 mutex_unlock(&ci->lock);
493
494 printk(KERN_INFO "read_data\n");
495 if (!ci->dr)
496 return 0;
497
498 mutex_lock(&ci->lock);
499 read_reg(ci, 0x0f, &msb);
500 read_reg(ci, 0x10, &lsb);
501 len = (msb<<8)|lsb;
502 read_block(ci, 0x12, ebuf, len);
503 ci->dr = 0;
504 mutex_unlock(&ci->lock);
505
506 return len;
507}
508
509static int write_data(struct dvb_ca_en50221 *ca, int slot, u8 *ebuf, int ecount)
510{
511 struct cxd *ci = ca->data;
512
513 mutex_lock(&ci->lock);
514 printk(KERN_INFO "write_data %d\n", ecount);
515 write_reg(ci, 0x0d, ecount>>8);
516 write_reg(ci, 0x0e, ecount&0xff);
517 write_block(ci, 0x11, ebuf, ecount);
518 mutex_unlock(&ci->lock);
519 return ecount;
520}
521#endif
522
523static struct dvb_ca_en50221 en_templ = {
524 .read_attribute_mem = read_attribute_mem,
525 .write_attribute_mem = write_attribute_mem,
526 .read_cam_control = read_cam_control,
527 .write_cam_control = write_cam_control,
528 .slot_reset = slot_reset,
529 .slot_shutdown = slot_shutdown,
530 .slot_ts_enable = slot_ts_enable,
531 .poll_slot_status = poll_slot_status,
532#ifdef BUFFER_MODE
533 .read_data = read_data,
534 .write_data = write_data,
535#endif
536
537};
538
539struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv,
540 struct i2c_adapter *i2c)
541{
542 struct cxd *ci = 0;
543 u32 bitrate = 62000000;
544 u8 val;
545
546 if (i2c_read_reg(i2c, adr, 0, &val) < 0) {
547 printk(KERN_ERR "No CXD2099 detected at %02x\n", adr);
548 return 0;
549 }
550
551 ci = kmalloc(sizeof(struct cxd), GFP_KERNEL);
552 if (!ci)
553 return 0;
554 memset(ci, 0, sizeof(*ci));
555
556 mutex_init(&ci->lock);
557 ci->i2c = i2c;
558 ci->adr = adr;
559 ci->lastaddress = 0xff;
560 ci->clk_reg_b = 0x4a;
561 ci->clk_reg_f = 0x1b;
562 ci->bitrate = bitrate;
563
564 memcpy(&ci->en, &en_templ, sizeof(en_templ));
565 ci->en.data = ci;
566 init(ci);
567 printk(KERN_INFO "Attached CXD2099AR at %02x\n", ci->adr);
568 return &ci->en;
569}
570EXPORT_SYMBOL(cxd2099_attach);
571
572MODULE_DESCRIPTION("cxd2099");
573MODULE_AUTHOR("Ralph Metzler <rjkm@metzlerbros.de>");
574MODULE_LICENSE("GPL");
diff --git a/drivers/staging/cxd2099/cxd2099.h b/drivers/staging/cxd2099/cxd2099.h
new file mode 100644
index 000000000000..bed54ff3e30b
--- /dev/null
+++ b/drivers/staging/cxd2099/cxd2099.h
@@ -0,0 +1,41 @@
1/*
2 * cxd2099.h: Driver for the CXD2099AR Common Interface Controller
3 *
4 * Copyright (C) 2010 DigitalDevices UG
5 *
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
9 * version 2 only, as published by the Free Software Foundation.
10 *
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 *
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 * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
23 */
24
25#ifndef _CXD2099_H_
26#define _CXD2099_H_
27
28#include <dvb_ca_en50221.h>
29
30#if defined(CONFIG_DVB_CXD2099) || \
31 (defined(CONFIG_DVB_CXD2099_MODULE) && defined(MODULE))
32struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv, struct i2c_adapter *i2c);
33#else
34static inline struct dvb_ca_en50221 *cxd2099_attach(u8 adr, void *priv, struct i2c_adapter *i2c)
35{
36 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
37 return NULL;
38}
39#endif
40
41#endif
diff --git a/drivers/staging/dabusb/Kconfig b/drivers/staging/dabusb/Kconfig
deleted file mode 100644
index 87bdc425d3c5..000000000000
--- a/drivers/staging/dabusb/Kconfig
+++ /dev/null
@@ -1,14 +0,0 @@
1config USB_DABUSB
2 tristate "DABUSB driver"
3 depends on USB
4 ---help---
5 A Digital Audio Broadcasting (DAB) Receiver for USB and Linux
6 brought to you by the DAB-Team
7 <http://wwwbode.cs.tum.edu/Par/arch/dab/>. This driver can be taken
8 as an example for URB-based bulk, control, and isochronous
9 transactions. URB's are explained in
10 <Documentation/usb/URB.txt>.
11
12 To compile this driver as a module, choose M here: the
13 module will be called dabusb.
14
diff --git a/drivers/staging/dabusb/Makefile b/drivers/staging/dabusb/Makefile
deleted file mode 100644
index 2ff2f228e5f9..000000000000
--- a/drivers/staging/dabusb/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_USB_DABUSB) += dabusb.o
2
diff --git a/drivers/staging/dabusb/TODO b/drivers/staging/dabusb/TODO
deleted file mode 100644
index f9c0314ea0c1..000000000000
--- a/drivers/staging/dabusb/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1This is a driver for an experimental sample developed in 2003. The driver
2never supported any commercial product, nor had any known user.
3If nobody takes care on it, the driver will be removed for 2.6.39.
4
5Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/dabusb/dabusb.c b/drivers/staging/dabusb/dabusb.c
deleted file mode 100644
index 21768a627750..000000000000
--- a/drivers/staging/dabusb/dabusb.c
+++ /dev/null
@@ -1,926 +0,0 @@
1/*****************************************************************************/
2
3/*
4 * dabusb.c -- dab usb driver.
5 *
6 * Copyright (C) 1999 Deti Fliegl (deti@fliegl.de)
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., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 *
24 * $Id: dabusb.c,v 1.54 2000/07/24 21:39:39 deti Exp $
25 *
26 */
27
28/*****************************************************************************/
29
30#include <linux/module.h>
31#include <linux/socket.h>
32#include <linux/list.h>
33#include <linux/vmalloc.h>
34#include <linux/slab.h>
35#include <linux/init.h>
36#include <linux/uaccess.h>
37#include <linux/atomic.h>
38#include <linux/delay.h>
39#include <linux/usb.h>
40#include <linux/mutex.h>
41#include <linux/firmware.h>
42#include <linux/ihex.h>
43
44#include "dabusb.h"
45
46/*
47 * Version Information
48 */
49#define DRIVER_VERSION "v1.54"
50#define DRIVER_AUTHOR "Deti Fliegl, deti@fliegl.de"
51#define DRIVER_DESC "DAB-USB Interface Driver for Linux (c)1999"
52
53/* --------------------------------------------------------------------- */
54
55#ifdef CONFIG_USB_DYNAMIC_MINORS
56#define NRDABUSB 256
57#else
58#define NRDABUSB 4
59#endif
60
61/*-------------------------------------------------------------------*/
62
63static dabusb_t dabusb[NRDABUSB];
64static int buffers = 256;
65static struct usb_driver dabusb_driver;
66
67/*-------------------------------------------------------------------*/
68
69static int dabusb_add_buf_tail(pdabusb_t s, struct list_head *dst,
70 struct list_head *src)
71{
72 unsigned long flags;
73 struct list_head *tmp;
74 int ret = 0;
75
76 spin_lock_irqsave(&s->lock, flags);
77
78 if (list_empty(src)) {
79 /* no elements in source buffer */
80 ret = -1;
81 goto err;
82 }
83 tmp = src->next;
84 list_move_tail(tmp, dst);
85
86err: spin_unlock_irqrestore(&s->lock, flags);
87 return ret;
88}
89/*-------------------------------------------------------------------*/
90#ifdef DEBUG
91static void dump_urb(struct urb *urb)
92{
93 dbg("urb :%p", urb);
94 dbg("dev :%p", urb->dev);
95 dbg("pipe :%08X", urb->pipe);
96 dbg("status :%d", urb->status);
97 dbg("transfer_flags :%08X", urb->transfer_flags);
98 dbg("transfer_buffer :%p", urb->transfer_buffer);
99 dbg("transfer_buffer_length:%d", urb->transfer_buffer_length);
100 dbg("actual_length :%d", urb->actual_length);
101 dbg("setup_packet :%p", urb->setup_packet);
102 dbg("start_frame :%d", urb->start_frame);
103 dbg("number_of_packets :%d", urb->number_of_packets);
104 dbg("interval :%d", urb->interval);
105 dbg("error_count :%d", urb->error_count);
106 dbg("context :%p", urb->context);
107 dbg("complete :%p", urb->complete);
108}
109#endif
110/*-------------------------------------------------------------------*/
111static int dabusb_cancel_queue(pdabusb_t s, struct list_head *q)
112{
113 unsigned long flags;
114 pbuff_t b;
115
116 dbg("dabusb_cancel_queue");
117
118 spin_lock_irqsave(&s->lock, flags);
119
120 list_for_each_entry(b, q, buff_list) {
121#ifdef DEBUG
122 dump_urb(b->purb);
123#endif
124 usb_unlink_urb(b->purb);
125 }
126 spin_unlock_irqrestore(&s->lock, flags);
127 return 0;
128}
129/*-------------------------------------------------------------------*/
130static int dabusb_free_queue(struct list_head *q)
131{
132 struct list_head *tmp;
133 struct list_head *p;
134 pbuff_t b;
135
136 dbg("dabusb_free_queue");
137 for (p = q->next; p != q;) {
138 b = list_entry(p, buff_t, buff_list);
139
140#ifdef DEBUG
141 dump_urb(b->purb);
142#endif
143 kfree(b->purb->transfer_buffer);
144 usb_free_urb(b->purb);
145 tmp = p->next;
146 list_del(p);
147 kfree(b);
148 p = tmp;
149 }
150
151 return 0;
152}
153/*-------------------------------------------------------------------*/
154static int dabusb_free_buffers(pdabusb_t s)
155{
156 unsigned long flags;
157 dbg("dabusb_free_buffers");
158
159 spin_lock_irqsave(&s->lock, flags);
160
161 dabusb_free_queue(&s->free_buff_list);
162 dabusb_free_queue(&s->rec_buff_list);
163
164 spin_unlock_irqrestore(&s->lock, flags);
165
166 s->got_mem = 0;
167 return 0;
168}
169/*-------------------------------------------------------------------*/
170static void dabusb_iso_complete(struct urb *purb)
171{
172 pbuff_t b = purb->context;
173 pdabusb_t s = b->s;
174 int i;
175 int len;
176 int dst = 0;
177 void *buf = purb->transfer_buffer;
178
179 dbg("dabusb_iso_complete");
180
181 /* process if URB was not killed */
182 if (purb->status != -ENOENT) {
183 unsigned int pipe = usb_rcvisocpipe(purb->dev, _DABUSB_ISOPIPE);
184 int pipesize = usb_maxpacket(purb->dev, pipe,
185 usb_pipeout(pipe));
186 for (i = 0; i < purb->number_of_packets; i++)
187 if (!purb->iso_frame_desc[i].status) {
188 len = purb->iso_frame_desc[i].actual_length;
189 if (len <= pipesize) {
190 memcpy(buf + dst, buf + purb->iso_frame_desc[i].offset, len);
191 dst += len;
192 } else
193 dev_err(&purb->dev->dev,
194 "dabusb_iso_complete: invalid len %d\n",
195 len);
196 } else
197 dev_warn(&purb->dev->dev,
198 "dabusb_iso_complete: corrupted packet status: %d\n",
199 purb->iso_frame_desc[i].status);
200 if (dst != purb->actual_length)
201 dev_err(&purb->dev->dev,
202 "dst!=purb->actual_length:%d!=%d\n",
203 dst, purb->actual_length);
204 }
205
206 if (atomic_dec_and_test(&s->pending_io) &&
207 !s->remove_pending && s->state != _stopped) {
208 s->overruns++;
209 dev_err(&purb->dev->dev, "overrun (%d)\n", s->overruns);
210 }
211 wake_up(&s->wait);
212}
213/*-------------------------------------------------------------------*/
214static int dabusb_alloc_buffers(pdabusb_t s)
215{
216 int transfer_len = 0;
217 pbuff_t b;
218 unsigned int pipe = usb_rcvisocpipe(s->usbdev, _DABUSB_ISOPIPE);
219 int pipesize = usb_maxpacket(s->usbdev, pipe, usb_pipeout(pipe));
220 int packets = _ISOPIPESIZE / pipesize;
221 int transfer_buffer_length = packets * pipesize;
222 int i;
223
224 dbg("dabusb_alloc_buffers pipesize:%d packets:%d transfer_buffer_len:%d",
225 pipesize, packets, transfer_buffer_length);
226
227 while (transfer_len < (s->total_buffer_size << 10)) {
228 b = kzalloc(sizeof(buff_t), GFP_KERNEL);
229 if (!b) {
230 dev_err(&s->usbdev->dev,
231 "kzalloc(sizeof(buff_t))==NULL\n");
232 goto err;
233 }
234 b->s = s;
235 b->purb = usb_alloc_urb(packets, GFP_KERNEL);
236 if (!b->purb) {
237 dev_err(&s->usbdev->dev, "usb_alloc_urb == NULL\n");
238 kfree(b);
239 goto err;
240 }
241
242 b->purb->transfer_buffer = kmalloc(transfer_buffer_length,
243 GFP_KERNEL);
244 if (!b->purb->transfer_buffer) {
245 kfree(b->purb);
246 kfree(b);
247 dev_err(&s->usbdev->dev,
248 "kmalloc(%d)==NULL\n", transfer_buffer_length);
249 goto err;
250 }
251
252 b->purb->transfer_buffer_length = transfer_buffer_length;
253 b->purb->number_of_packets = packets;
254 b->purb->complete = dabusb_iso_complete;
255 b->purb->context = b;
256 b->purb->dev = s->usbdev;
257 b->purb->pipe = pipe;
258 b->purb->transfer_flags = URB_ISO_ASAP;
259
260 for (i = 0; i < packets; i++) {
261 b->purb->iso_frame_desc[i].offset = i * pipesize;
262 b->purb->iso_frame_desc[i].length = pipesize;
263 }
264
265 transfer_len += transfer_buffer_length;
266 list_add_tail(&b->buff_list, &s->free_buff_list);
267 }
268 s->got_mem = transfer_len;
269
270 return 0;
271
272err:
273 dabusb_free_buffers(s);
274 return -ENOMEM;
275}
276/*-------------------------------------------------------------------*/
277static int dabusb_bulk(pdabusb_t s, pbulk_transfer_t pb)
278{
279 int ret;
280 unsigned int pipe;
281 int actual_length;
282
283 dbg("dabusb_bulk");
284
285 if (!pb->pipe)
286 pipe = usb_rcvbulkpipe(s->usbdev, 2);
287 else
288 pipe = usb_sndbulkpipe(s->usbdev, 2);
289
290 ret = usb_bulk_msg(s->usbdev, pipe, pb->data,
291 pb->size, &actual_length, 100);
292 if (ret < 0) {
293 dev_err(&s->usbdev->dev,
294 "usb_bulk_msg failed(%d)\n", ret);
295
296 if (usb_set_interface(s->usbdev, _DABUSB_IF, 1) < 0) {
297 dev_err(&s->usbdev->dev, "set_interface failed\n");
298 return -EINVAL;
299 }
300
301 }
302
303 if (ret == -EPIPE) {
304 dev_warn(&s->usbdev->dev, "CLEAR_FEATURE request to remove STALL condition.\n");
305 if (usb_clear_halt(s->usbdev, usb_pipeendpoint(pipe)))
306 dev_err(&s->usbdev->dev, "request failed\n");
307 }
308
309 pb->size = actual_length;
310 return ret;
311}
312/* --------------------------------------------------------------------- */
313static int dabusb_writemem(pdabusb_t s, int pos, const unsigned char *data,
314 int len)
315{
316 int ret;
317 unsigned char *transfer_buffer = kmalloc(len, GFP_KERNEL);
318
319 if (!transfer_buffer) {
320 dev_err(&s->usbdev->dev,
321 "dabusb_writemem: kmalloc(%d) failed.\n", len);
322 return -ENOMEM;
323 }
324
325 memcpy(transfer_buffer, data, len);
326
327 ret = usb_control_msg(s->usbdev, usb_sndctrlpipe(s->usbdev, 0),
328 0xa0, 0x40, pos, 0, transfer_buffer, len, 300);
329
330 kfree(transfer_buffer);
331 return ret;
332}
333/* --------------------------------------------------------------------- */
334static int dabusb_8051_reset(pdabusb_t s, unsigned char reset_bit)
335{
336 dbg("dabusb_8051_reset: %d", reset_bit);
337 return dabusb_writemem(s, CPUCS_REG, &reset_bit, 1);
338}
339/* --------------------------------------------------------------------- */
340static int dabusb_loadmem(pdabusb_t s, const char *fname)
341{
342 int ret;
343 const struct ihex_binrec *rec;
344 const struct firmware *uninitialized_var(fw);
345
346 dbg("Enter dabusb_loadmem (internal)");
347
348 ret = request_ihex_firmware(&fw, "dabusb/firmware.fw", &s->usbdev->dev);
349 if (ret) {
350 dev_err(&s->usbdev->dev,
351 "Failed to load \"dabusb/firmware.fw\": %d\n", ret);
352 goto out;
353 }
354 ret = dabusb_8051_reset(s, 1);
355
356 for (rec = (const struct ihex_binrec *)fw->data; rec;
357 rec = ihex_next_binrec(rec)) {
358 dbg("dabusb_writemem: %04X %p %d)", be32_to_cpu(rec->addr),
359 rec->data, be16_to_cpu(rec->len));
360
361 ret = dabusb_writemem(s, be32_to_cpu(rec->addr), rec->data,
362 be16_to_cpu(rec->len));
363 if (ret < 0) {
364 dev_err(&s->usbdev->dev,
365 "dabusb_writemem failed (%d %04X %p %d)\n",
366 ret, be32_to_cpu(rec->addr),
367 rec->data, be16_to_cpu(rec->len));
368 break;
369 }
370 }
371 ret = dabusb_8051_reset(s, 0);
372 release_firmware(fw);
373 out:
374 dbg("dabusb_loadmem: exit");
375
376 return ret;
377}
378/* --------------------------------------------------------------------- */
379static int dabusb_fpga_clear(pdabusb_t s, pbulk_transfer_t b)
380{
381 b->size = 4;
382 b->data[0] = 0x2a;
383 b->data[1] = 0;
384 b->data[2] = 0;
385 b->data[3] = 0;
386
387 dbg("dabusb_fpga_clear");
388
389 return dabusb_bulk(s, b);
390}
391/* --------------------------------------------------------------------- */
392static int dabusb_fpga_init(pdabusb_t s, pbulk_transfer_t b)
393{
394 b->size = 4;
395 b->data[0] = 0x2c;
396 b->data[1] = 0;
397 b->data[2] = 0;
398 b->data[3] = 0;
399
400 dbg("dabusb_fpga_init");
401
402 return dabusb_bulk(s, b);
403}
404/* --------------------------------------------------------------------- */
405static int dabusb_fpga_download(pdabusb_t s, const char *fname)
406{
407 pbulk_transfer_t b = kmalloc(sizeof(bulk_transfer_t), GFP_KERNEL);
408 const struct firmware *fw;
409 unsigned int blen, n;
410 int ret;
411
412 dbg("Enter dabusb_fpga_download (internal)");
413
414 if (!b) {
415 dev_err(&s->usbdev->dev,
416 "kmalloc(sizeof(bulk_transfer_t))==NULL\n");
417 return -ENOMEM;
418 }
419
420 ret = request_firmware(&fw, "dabusb/bitstream.bin", &s->usbdev->dev);
421 if (ret) {
422 dev_err(&s->usbdev->dev,
423 "Failed to load \"dabusb/bitstream.bin\": %d\n", ret);
424 kfree(b);
425 return ret;
426 }
427
428 b->pipe = 1;
429 ret = dabusb_fpga_clear(s, b);
430 mdelay(10);
431 blen = fw->data[73] + (fw->data[72] << 8);
432
433 dbg("Bitstream len: %i", blen);
434
435 b->data[0] = 0x2b;
436 b->data[1] = 0;
437 b->data[2] = 0;
438 b->data[3] = 60;
439
440 for (n = 0; n <= blen + 60; n += 60) {
441 /* some cclks for startup */
442 b->size = 64;
443 memcpy(b->data + 4, fw->data + 74 + n, 60);
444 ret = dabusb_bulk(s, b);
445 if (ret < 0) {
446 dev_err(&s->usbdev->dev, "dabusb_bulk failed.\n");
447 break;
448 }
449 mdelay(1);
450 }
451
452 ret = dabusb_fpga_init(s, b);
453 kfree(b);
454 release_firmware(fw);
455
456 dbg("exit dabusb_fpga_download");
457
458 return ret;
459}
460
461static int dabusb_stop(pdabusb_t s)
462{
463 dbg("dabusb_stop");
464
465 s->state = _stopped;
466 dabusb_cancel_queue(s, &s->rec_buff_list);
467
468 dbg("pending_io: %d", s->pending_io.counter);
469
470 s->pending_io.counter = 0;
471 return 0;
472}
473
474static int dabusb_startrek(pdabusb_t s)
475{
476 if (!s->got_mem && s->state != _started) {
477
478 dbg("dabusb_startrek");
479
480 if (dabusb_alloc_buffers(s) < 0)
481 return -ENOMEM;
482 dabusb_stop(s);
483 s->state = _started;
484 s->readptr = 0;
485 }
486
487 if (!list_empty(&s->free_buff_list)) {
488 pbuff_t end;
489 int ret;
490
491 while (!dabusb_add_buf_tail(s, &s->rec_buff_list, &s->free_buff_list)) {
492
493 dbg("submitting: end:%p s->rec_buff_list:%p",
494 s->rec_buff_list.prev, &s->rec_buff_list);
495
496 end = list_entry(s->rec_buff_list.prev,
497 buff_t, buff_list);
498
499 ret = usb_submit_urb(end->purb, GFP_KERNEL);
500 if (ret) {
501 dev_err(&s->usbdev->dev,
502 "usb_submit_urb returned:%d\n", ret);
503 if (dabusb_add_buf_tail(s, &s->free_buff_list,
504 &s->rec_buff_list))
505 dev_err(&s->usbdev->dev,
506 "startrek: dabusb_add_buf_tail failed\n");
507 break;
508 } else
509 atomic_inc(&s->pending_io);
510 }
511 dbg("pending_io: %d", s->pending_io.counter);
512 }
513
514 return 0;
515}
516
517static ssize_t dabusb_read(struct file *file, char __user *buf,
518 size_t count, loff_t *ppos)
519{
520 pdabusb_t s = (pdabusb_t)file->private_data;
521 unsigned long flags;
522 unsigned ret = 0;
523 int rem;
524 int cnt;
525 pbuff_t b;
526 struct urb *purb = NULL;
527
528 dbg("dabusb_read");
529
530 if (*ppos)
531 return -ESPIPE;
532
533 if (s->remove_pending)
534 return -EIO;
535
536
537 if (!s->usbdev)
538 return -EIO;
539
540 while (count > 0) {
541 dabusb_startrek(s);
542
543 spin_lock_irqsave(&s->lock, flags);
544
545 if (list_empty(&s->rec_buff_list)) {
546
547 spin_unlock_irqrestore(&s->lock, flags);
548
549 dev_err(&s->usbdev->dev,
550 "error: rec_buf_list is empty\n");
551 goto err;
552 }
553
554 b = list_entry(s->rec_buff_list.next, buff_t, buff_list);
555 purb = b->purb;
556
557 spin_unlock_irqrestore(&s->lock, flags);
558
559 if (purb->status == -EINPROGRESS) {
560 /* return nonblocking */
561 if (file->f_flags & O_NONBLOCK) {
562 if (!ret)
563 ret = -EAGAIN;
564 goto err;
565 }
566
567 interruptible_sleep_on(&s->wait);
568
569 if (signal_pending(current)) {
570 if (!ret)
571 ret = -ERESTARTSYS;
572 goto err;
573 }
574
575 spin_lock_irqsave(&s->lock, flags);
576
577 if (list_empty(&s->rec_buff_list)) {
578 spin_unlock_irqrestore(&s->lock, flags);
579 dev_err(&s->usbdev->dev,
580 "error: still no buffer available.\n");
581 goto err;
582 }
583 spin_unlock_irqrestore(&s->lock, flags);
584 s->readptr = 0;
585 }
586 if (s->remove_pending) {
587 ret = -EIO;
588 goto err;
589 }
590
591 /* set remaining bytes to copy */
592 rem = purb->actual_length - s->readptr;
593
594 if (count >= rem)
595 cnt = rem;
596 else
597 cnt = count;
598
599 dbg("copy_to_user:%p %p %d", buf,
600 purb->transfer_buffer + s->readptr, cnt);
601
602 if (copy_to_user(buf,
603 purb->transfer_buffer + s->readptr,
604 cnt)) {
605 dev_err(&s->usbdev->dev, "read: copy_to_user failed\n");
606 if (!ret)
607 ret = -EFAULT;
608 goto err;
609 }
610
611 s->readptr += cnt;
612 count -= cnt;
613 buf += cnt;
614 ret += cnt;
615
616 if (s->readptr == purb->actual_length) {
617 /* finished, take next buffer */
618 if (dabusb_add_buf_tail(s, &s->free_buff_list,
619 &s->rec_buff_list))
620 dev_err(&s->usbdev->dev,
621 "read: dabusb_add_buf_tail failed\n");
622 s->readptr = 0;
623 }
624 }
625err: /*mutex_unlock(&s->mutex);*/
626 return ret;
627}
628
629static int dabusb_open(struct inode *inode, struct file *file)
630{
631 int devnum = iminor(inode);
632 pdabusb_t s;
633 int r;
634
635 if (devnum < DABUSB_MINOR || devnum >= (DABUSB_MINOR + NRDABUSB))
636 return -EIO;
637
638 s = &dabusb[devnum - DABUSB_MINOR];
639
640 dbg("dabusb_open");
641 mutex_lock(&s->mutex);
642
643 while (!s->usbdev || s->opened) {
644 mutex_unlock(&s->mutex);
645
646 if (file->f_flags & O_NONBLOCK)
647 return -EBUSY;
648 msleep_interruptible(500);
649
650 if (signal_pending(current))
651 return -EAGAIN;
652 mutex_lock(&s->mutex);
653 }
654 if (usb_set_interface(s->usbdev, _DABUSB_IF, 1) < 0) {
655 mutex_unlock(&s->mutex);
656 dev_err(&s->usbdev->dev, "set_interface failed\n");
657 return -EINVAL;
658 }
659 s->opened = 1;
660 mutex_unlock(&s->mutex);
661
662 file->f_pos = 0;
663 file->private_data = s;
664
665 r = nonseekable_open(inode, file);
666 return r;
667}
668
669static int dabusb_release(struct inode *inode, struct file *file)
670{
671 pdabusb_t s = (pdabusb_t)file->private_data;
672
673 dbg("dabusb_release");
674
675 mutex_lock(&s->mutex);
676 dabusb_stop(s);
677 dabusb_free_buffers(s);
678 mutex_unlock(&s->mutex);
679
680 if (!s->remove_pending) {
681 if (usb_set_interface(s->usbdev, _DABUSB_IF, 0) < 0)
682 dev_err(&s->usbdev->dev, "set_interface failed\n");
683 } else
684 wake_up(&s->remove_ok);
685
686 s->opened = 0;
687 return 0;
688}
689
690static long dabusb_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
691{
692 pdabusb_t s = (pdabusb_t)file->private_data;
693 pbulk_transfer_t pbulk;
694 int ret = 0;
695 int version = DABUSB_VERSION;
696
697 dbg("dabusb_ioctl");
698
699 if (s->remove_pending)
700 return -EIO;
701
702 mutex_lock(&s->mutex);
703
704 if (!s->usbdev) {
705 mutex_unlock(&s->mutex);
706 return -EIO;
707 }
708
709 switch (cmd) {
710
711 case IOCTL_DAB_BULK:
712 pbulk = memdup_user((void __user *)arg,
713 sizeof(bulk_transfer_t));
714
715 if (IS_ERR(pbulk)) {
716 ret = PTR_ERR(pbulk);
717 break;
718 }
719
720 ret = dabusb_bulk(s, pbulk);
721 if (ret == 0)
722 if (copy_to_user((void __user *)arg, pbulk,
723 sizeof(bulk_transfer_t)))
724 ret = -EFAULT;
725 kfree(pbulk);
726 break;
727
728 case IOCTL_DAB_OVERRUNS:
729 ret = put_user(s->overruns, (unsigned int __user *) arg);
730 break;
731
732 case IOCTL_DAB_VERSION:
733 ret = put_user(version, (unsigned int __user *) arg);
734 break;
735
736 default:
737 ret = -ENOIOCTLCMD;
738 break;
739 }
740 mutex_unlock(&s->mutex);
741 return ret;
742}
743
744static const struct file_operations dabusb_fops = {
745 .owner = THIS_MODULE,
746 .llseek = no_llseek,
747 .read = dabusb_read,
748 .unlocked_ioctl = dabusb_ioctl,
749 .open = dabusb_open,
750 .release = dabusb_release,
751};
752
753static char *dabusb_devnode(struct device *dev, mode_t *mode)
754{
755 return kasprintf(GFP_KERNEL, "usb/%s", dev_name(dev));
756}
757
758static struct usb_class_driver dabusb_class = {
759 .name = "dabusb%d",
760 .devnode = dabusb_devnode,
761 .fops = &dabusb_fops,
762 .minor_base = DABUSB_MINOR,
763};
764
765
766/* --------------------------------------------------------------------- */
767static int dabusb_probe(struct usb_interface *intf,
768 const struct usb_device_id *id)
769{
770 struct usb_device *usbdev = interface_to_usbdev(intf);
771 int retval;
772 pdabusb_t s;
773
774 dbg("dabusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
775 le16_to_cpu(usbdev->descriptor.idVendor),
776 le16_to_cpu(usbdev->descriptor.idProduct),
777 intf->altsetting->desc.bInterfaceNumber);
778
779 /* We don't handle multiple configurations */
780 if (usbdev->descriptor.bNumConfigurations != 1)
781 return -ENODEV;
782
783 if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF &&
784 le16_to_cpu(usbdev->descriptor.idProduct) == 0x9999)
785 return -ENODEV;
786
787
788
789 s = &dabusb[intf->minor];
790
791 mutex_lock(&s->mutex);
792 s->remove_pending = 0;
793 s->usbdev = usbdev;
794 s->devnum = intf->minor;
795
796 if (usb_reset_configuration(usbdev) < 0) {
797 dev_err(&intf->dev, "reset_configuration failed\n");
798 goto reject;
799 }
800 if (le16_to_cpu(usbdev->descriptor.idProduct) == 0x2131) {
801 dabusb_loadmem(s, NULL);
802 goto reject;
803 } else {
804 dabusb_fpga_download(s, NULL);
805
806 if (usb_set_interface(s->usbdev, _DABUSB_IF, 0) < 0) {
807 dev_err(&intf->dev, "set_interface failed\n");
808 goto reject;
809 }
810 }
811 dbg("bound to interface: %d", intf->altsetting->desc.bInterfaceNumber);
812 usb_set_intfdata(intf, s);
813 mutex_unlock(&s->mutex);
814
815 retval = usb_register_dev(intf, &dabusb_class);
816 if (retval) {
817 usb_set_intfdata(intf, NULL);
818 return -ENOMEM;
819 }
820
821 return 0;
822
823reject:
824 mutex_unlock(&s->mutex);
825 s->usbdev = NULL;
826 return -ENODEV;
827}
828
829static void dabusb_disconnect(struct usb_interface *intf)
830{
831 wait_queue_t __wait;
832 pdabusb_t s = usb_get_intfdata(intf);
833
834 dbg("dabusb_disconnect");
835
836 init_waitqueue_entry(&__wait, current);
837
838 usb_set_intfdata(intf, NULL);
839 if (s) {
840 usb_deregister_dev(intf, &dabusb_class);
841 s->remove_pending = 1;
842 wake_up(&s->wait);
843 add_wait_queue(&s->remove_ok, &__wait);
844 set_current_state(TASK_UNINTERRUPTIBLE);
845 if (s->state == _started)
846 schedule();
847 current->state = TASK_RUNNING;
848 remove_wait_queue(&s->remove_ok, &__wait);
849
850 s->usbdev = NULL;
851 s->overruns = 0;
852 }
853}
854
855static struct usb_device_id dabusb_ids[] = {
856 /* { USB_DEVICE(0x0547, 0x2131) },*/ /* An2131 chip, no boot ROM */
857 { USB_DEVICE(0x0547, 0x9999) },
858 { } /* Terminating entry */
859};
860
861MODULE_DEVICE_TABLE(usb, dabusb_ids);
862
863static struct usb_driver dabusb_driver = {
864 .name = "dabusb",
865 .probe = dabusb_probe,
866 .disconnect = dabusb_disconnect,
867 .id_table = dabusb_ids,
868};
869
870/* --------------------------------------------------------------------- */
871
872static int __init dabusb_init(void)
873{
874 int retval;
875 unsigned u;
876
877 /* initialize struct */
878 for (u = 0; u < NRDABUSB; u++) {
879 pdabusb_t s = &dabusb[u];
880 memset(s, 0, sizeof(dabusb_t));
881 mutex_init(&s->mutex);
882 s->usbdev = NULL;
883 s->total_buffer_size = buffers;
884 init_waitqueue_head(&s->wait);
885 init_waitqueue_head(&s->remove_ok);
886 spin_lock_init(&s->lock);
887 INIT_LIST_HEAD(&s->free_buff_list);
888 INIT_LIST_HEAD(&s->rec_buff_list);
889 }
890
891 /* register misc device */
892 retval = usb_register(&dabusb_driver);
893 if (retval)
894 goto out;
895
896 dbg("dabusb_init: driver registered");
897
898 printk(KERN_INFO KBUILD_MODNAME ": " DRIVER_VERSION ":"
899 DRIVER_DESC "\n");
900
901out:
902 return retval;
903}
904
905static void __exit dabusb_cleanup(void)
906{
907 dbg("dabusb_cleanup");
908
909 usb_deregister(&dabusb_driver);
910}
911
912/* --------------------------------------------------------------------- */
913
914MODULE_AUTHOR(DRIVER_AUTHOR);
915MODULE_DESCRIPTION(DRIVER_DESC);
916MODULE_LICENSE("GPL");
917MODULE_FIRMWARE("dabusb/firmware.fw");
918MODULE_FIRMWARE("dabusb/bitstream.bin");
919
920module_param(buffers, int, 0);
921MODULE_PARM_DESC(buffers, "Number of buffers (default=256)");
922
923module_init(dabusb_init);
924module_exit(dabusb_cleanup);
925
926/* --------------------------------------------------------------------- */
diff --git a/drivers/staging/dabusb/dabusb.h b/drivers/staging/dabusb/dabusb.h
deleted file mode 100644
index c1772efe7c2c..000000000000
--- a/drivers/staging/dabusb/dabusb.h
+++ /dev/null
@@ -1,80 +0,0 @@
1#define _BULK_DATA_LEN 64
2typedef struct {
3 unsigned char data[_BULK_DATA_LEN];
4 unsigned int size;
5 unsigned int pipe;
6} bulk_transfer_t, *pbulk_transfer_t;
7
8#define DABUSB_MINOR 240 /* some unassigned USB minor */
9#define DABUSB_VERSION 0x1000
10#define IOCTL_DAB_BULK _IOWR('d', 0x30, bulk_transfer_t)
11#define IOCTL_DAB_OVERRUNS _IOR('d', 0x15, int)
12#define IOCTL_DAB_VERSION _IOR('d', 0x3f, int)
13
14#ifdef __KERNEL__
15
16typedef enum { _stopped = 0, _started } driver_state_t;
17
18typedef struct {
19 struct mutex mutex;
20 struct usb_device *usbdev;
21 wait_queue_head_t wait;
22 wait_queue_head_t remove_ok;
23 spinlock_t lock;
24 atomic_t pending_io;
25 driver_state_t state;
26 int remove_pending;
27 int got_mem;
28 int total_buffer_size;
29 unsigned int overruns;
30 int readptr;
31 int opened;
32 int devnum;
33 struct list_head free_buff_list;
34 struct list_head rec_buff_list;
35} dabusb_t, *pdabusb_t;
36
37typedef struct {
38 pdabusb_t s;
39 struct urb *purb;
40 struct list_head buff_list;
41} buff_t, *pbuff_t;
42
43typedef struct {
44 wait_queue_head_t wait;
45} bulk_completion_context_t, *pbulk_completion_context_t;
46
47
48#define _DABUSB_IF 2
49#define _DABUSB_ISOPIPE 0x09
50#define _ISOPIPESIZE 16384
51
52#define _BULK_DATA_LEN 64
53/* Vendor specific request code for Anchor Upload/Download
54 *This one is implemented in the core */
55#define ANCHOR_LOAD_INTERNAL 0xA0
56
57/* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */
58#define CPUCS_REG 0x7F92
59#define _TOTAL_BUFFERS 384
60
61#define MAX_INTEL_HEX_RECORD_LENGTH 16
62
63#ifndef _BYTE_DEFINED
64#define _BYTE_DEFINED
65typedef unsigned char BYTE;
66#endif /* !_BYTE_DEFINED */
67
68#ifndef _WORD_DEFINED
69#define _WORD_DEFINED
70typedef unsigned short WORD;
71#endif /* !_WORD_DEFINED */
72
73typedef struct _INTEL_HEX_RECORD {
74 BYTE Length;
75 WORD Address;
76 BYTE Type;
77 BYTE Data[MAX_INTEL_HEX_RECORD_LENGTH];
78} INTEL_HEX_RECORD, *PINTEL_HEX_RECORD;
79
80#endif
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c
index 28a28e02c9ce..b3bd11d5879f 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/easycap/easycap_ioctl.c
@@ -1391,8 +1391,7 @@ long easycap_unlocked_ioctl(struct file *file,
1391 break; 1391 break;
1392 } 1392 }
1393/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 1393/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1394 case VIDIOC_S_CTRL: 1394 case VIDIOC_S_CTRL: {
1395 {
1396 struct v4l2_control v4l2_control; 1395 struct v4l2_control v4l2_control;
1397 1396
1398 JOM(8, "VIDIOC_S_CTRL\n"); 1397 JOM(8, "VIDIOC_S_CTRL\n");
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/lirc/Kconfig
index cdaff5903a8f..526ec0fc2f04 100644
--- a/drivers/staging/lirc/Kconfig
+++ b/drivers/staging/lirc/Kconfig
@@ -32,18 +32,6 @@ config LIRC_IMON
32 32
33 Current generation iMON devices use the input layer imon driver. 33 Current generation iMON devices use the input layer imon driver.
34 34
35config LIRC_IT87
36 tristate "ITE IT87XX CIR Port Receiver"
37 depends on LIRC && PNP
38 help
39 Driver for the ITE IT87xx IR Receiver
40
41config LIRC_ITE8709
42 tristate "ITE8709 CIR Port Receiver"
43 depends on LIRC && PNP
44 help
45 Driver for the ITE8709 IR Receiver
46
47config LIRC_PARALLEL 35config LIRC_PARALLEL
48 tristate "Homebrew Parallel Port Receiver" 36 tristate "Homebrew Parallel Port Receiver"
49 depends on LIRC && PARPORT 37 depends on LIRC && PARPORT
diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/lirc/Makefile
index 94af218d8373..d76b0fa2af53 100644
--- a/drivers/staging/lirc/Makefile
+++ b/drivers/staging/lirc/Makefile
@@ -6,8 +6,6 @@
6obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o 6obj-$(CONFIG_LIRC_BT829) += lirc_bt829.o
7obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o 7obj-$(CONFIG_LIRC_IGORPLUGUSB) += lirc_igorplugusb.o
8obj-$(CONFIG_LIRC_IMON) += lirc_imon.o 8obj-$(CONFIG_LIRC_IMON) += lirc_imon.o
9obj-$(CONFIG_LIRC_IT87) += lirc_it87.o
10obj-$(CONFIG_LIRC_ITE8709) += lirc_ite8709.o
11obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o 9obj-$(CONFIG_LIRC_PARALLEL) += lirc_parallel.o
12obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o 10obj-$(CONFIG_LIRC_SASEM) += lirc_sasem.o
13obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o 11obj-$(CONFIG_LIRC_SERIAL) += lirc_serial.o
diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/lirc/TODO.lirc_zilog
index 2d0263f07937..a97800a8e127 100644
--- a/drivers/staging/lirc/TODO.lirc_zilog
+++ b/drivers/staging/lirc/TODO.lirc_zilog
@@ -1,34 +1,33 @@
11. Both ir-kbd-i2c and lirc_zilog provide support for RX events. 11. Both ir-kbd-i2c and lirc_zilog provide support for RX events for
2The 'tx_only' lirc_zilog module parameter will allow ir-kbd-i2c 2the chips supported by lirc_zilog. Before moving lirc_zilog out of staging:
3and lirc_zilog to coexist in the kernel, if the user requires such a set-up. 3
4However the IR unit will not work well without coordination between the 4a. ir-kbd-i2c needs a module parameter added to allow the user to tell
5two modules. A shared mutex, for transceiver access locking, needs to be 5 ir-kbd-i2c to ignore Z8 IR units.
6supplied by bridge drivers, in struct IR_i2_init_data, to both ir-kbd-i2c 6
7and lirc_zilog, before they will coexist usefully. This should be fixed 7b. lirc_zilog should provide Rx key presses to the rc core like ir-kbd-i2c
8before moving out of staging. 8 does.
9 9
102. References and locking need careful examination. For cx18 and ivtv PCI 10
11cards, which are not easily "hot unplugged", the imperfect state of reference 112. lirc_zilog module ref-counting need examination. It has not been
12counting and locking is acceptable if not correct. For USB connected units 12verified that cdev and lirc_dev will take the proper module references on
13like HD PVR, PVR USB2, HVR-1900, and HVR1950, the likelyhood of an Ooops on 13lirc_zilog to prevent removal of lirc_zilog when the /dev/lircN device node
14unplug is probably great. Proper reference counting and locking needs to be 14is open.
15implemented before this module is moved out of staging. 15
16 16(The good news is ref-counting of lirc_zilog internal structures appears to be
173. The binding between hdpvr and lirc_zilog is currently disabled, 17complete. Testing has shown the cx18 module can be unloaded out from under
18due to an OOPS reported a few years ago when both the hdpvr and cx18 18irw + lircd + lirc_dev, with the /dev/lirc0 device node open, with no adverse
19drivers were loaded in his system. More details can be seen at: 19effects. The cx18 module could then be reloaded and irw properly began
20 http://www.mail-archive.com/linux-media@vger.kernel.org/msg09163.html 20receiving button presses again and ir_send worked without error.)
21More tests need to be done, in order to fix the reported issue. 21
22 22
234. In addition to providing a shared mutex for transceiver access 233. Bridge drivers, if able, should provide a chip reset() callback
24locking, bridge drivers, if able, should provide a chip reset() callback
25to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines 24to lirc_zilog via struct IR_i2c_init_data. cx18 and ivtv already have routines
26to perform Z8 chip resets via GPIO manipulations. This will allow lirc_zilog 25to perform Z8 chip resets via GPIO manipulations. This would allow lirc_zilog
27to bring the chip back to normal when it hangs, in the same places the 26to bring the chip back to normal when it hangs, in the same places the
28original lirc_pvr150 driver code does. This is not strictly needed, so it 27original lirc_pvr150 driver code does. This is not strictly needed, so it
29is not required to move lirc_zilog out of staging. 28is not required to move lirc_zilog out of staging.
30 29
315. Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed 30Note: Both lirc_zilog and ir-kbd-i2c support the Zilog Z8 for IR, as programmed
32and installed on Hauppauge products. When working on either module, developers 31and installed on Hauppauge products. When working on either module, developers
33must consider at least the following bridge drivers which mention an IR Rx unit 32must consider at least the following bridge drivers which mention an IR Rx unit
34at address 0x71 (indicative of a Z8): 33at address 0x71 (indicative of a Z8):
diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c
index 235cab0eb087..4039eda2a15b 100644
--- a/drivers/staging/lirc/lirc_imon.c
+++ b/drivers/staging/lirc/lirc_imon.c
@@ -379,7 +379,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
379 struct imon_context *context; 379 struct imon_context *context;
380 const unsigned char vfd_packet6[] = { 380 const unsigned char vfd_packet6[] = {
381 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; 381 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF };
382 int *data_buf; 382 int *data_buf = NULL;
383 383
384 context = file->private_data; 384 context = file->private_data;
385 if (!context) { 385 if (!context) {
diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c
deleted file mode 100644
index 5938616f3e8f..000000000000
--- a/drivers/staging/lirc/lirc_it87.c
+++ /dev/null
@@ -1,1027 +0,0 @@
1/*
2 * LIRC driver for ITE IT8712/IT8705 CIR port
3 *
4 * Copyright (C) 2001 Hans-Gunter Lutke Uphues <hg_lu@web.de>
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; 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 GNU
14 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 *
21 * ITE IT8705 and IT8712(not tested) and IT8720 CIR-port support for lirc based
22 * via cut and paste from lirc_sir.c (C) 2000 Milan Pikula
23 *
24 * Attention: Sendmode only tested with debugging logs
25 *
26 * 2001/02/27 Christoph Bartelmus <lirc@bartelmus.de> :
27 * reimplemented read function
28 * 2005/06/05 Andrew Calkin implemented support for Asus Digimatrix,
29 * based on work of the following member of the Outertrack Digimatrix
30 * Forum: Art103 <r_tay@hotmail.com>
31 * 2009/12/24 James Edwards <jimbo-lirc@edwardsclan.net> implemeted support
32 * for ITE8704/ITE8718, on my machine, the DSDT reports 8704, but the
33 * chip identifies as 18.
34 */
35
36#include <linux/module.h>
37#include <linux/sched.h>
38#include <linux/errno.h>
39#include <linux/signal.h>
40#include <linux/fs.h>
41#include <linux/interrupt.h>
42#include <linux/ioport.h>
43#include <linux/kernel.h>
44#include <linux/time.h>
45#include <linux/string.h>
46#include <linux/types.h>
47#include <linux/wait.h>
48#include <linux/mm.h>
49#include <linux/delay.h>
50#include <linux/poll.h>
51#include <asm/system.h>
52#include <linux/io.h>
53#include <linux/irq.h>
54#include <linux/fcntl.h>
55
56#include <linux/timer.h>
57#include <linux/pnp.h>
58
59#include <media/lirc.h>
60#include <media/lirc_dev.h>
61
62#include "lirc_it87.h"
63
64#ifdef LIRC_IT87_DIGIMATRIX
65static int digimatrix = 1;
66static int it87_freq = 36; /* kHz */
67static int irq = 9;
68#else
69static int digimatrix;
70static int it87_freq = 38; /* kHz */
71static int irq = IT87_CIR_DEFAULT_IRQ;
72#endif
73
74static unsigned long it87_bits_in_byte_out;
75static unsigned long it87_send_counter;
76static unsigned char it87_RXEN_mask = IT87_CIR_RCR_RXEN;
77
78#define RBUF_LEN 1024
79
80#define LIRC_DRIVER_NAME "lirc_it87"
81
82/* timeout for sequences in jiffies (=5/100s) */
83/* must be longer than TIME_CONST */
84#define IT87_TIMEOUT (HZ*5/100)
85
86/* module parameters */
87static int debug;
88#define dprintk(fmt, args...) \
89 do { \
90 if (debug) \
91 printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
92 fmt, ## args); \
93 } while (0)
94
95static int io = IT87_CIR_DEFAULT_IOBASE;
96/* receiver demodulator default: off */
97static int it87_enable_demodulator;
98
99static int timer_enabled;
100static DEFINE_SPINLOCK(timer_lock);
101static struct timer_list timerlist;
102/* time of last signal change detected */
103static struct timeval last_tv = {0, 0};
104/* time of last UART data ready interrupt */
105static struct timeval last_intr_tv = {0, 0};
106static int last_value;
107
108static DECLARE_WAIT_QUEUE_HEAD(lirc_read_queue);
109
110static DEFINE_SPINLOCK(hardware_lock);
111static DEFINE_SPINLOCK(dev_lock);
112static bool device_open;
113
114static int rx_buf[RBUF_LEN];
115unsigned int rx_tail, rx_head;
116
117static struct pnp_driver it87_pnp_driver;
118
119/* SECTION: Prototypes */
120
121/* Communication with user-space */
122static int lirc_open(struct inode *inode, struct file *file);
123static int lirc_close(struct inode *inode, struct file *file);
124static unsigned int lirc_poll(struct file *file, poll_table *wait);
125static ssize_t lirc_read(struct file *file, char *buf,
126 size_t count, loff_t *ppos);
127static ssize_t lirc_write(struct file *file, const char *buf,
128 size_t n, loff_t *pos);
129static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
130static void add_read_queue(int flag, unsigned long val);
131static int init_chrdev(void);
132static void drop_chrdev(void);
133/* Hardware */
134static irqreturn_t it87_interrupt(int irq, void *dev_id);
135static void send_space(unsigned long len);
136static void send_pulse(unsigned long len);
137static void init_send(void);
138static void terminate_send(unsigned long len);
139static int init_hardware(void);
140static void drop_hardware(void);
141/* Initialisation */
142static int init_port(void);
143static void drop_port(void);
144
145
146/* SECTION: Communication with user-space */
147
148static int lirc_open(struct inode *inode, struct file *file)
149{
150 spin_lock(&dev_lock);
151 if (device_open) {
152 spin_unlock(&dev_lock);
153 return -EBUSY;
154 }
155 device_open = true;
156 spin_unlock(&dev_lock);
157 return 0;
158}
159
160
161static int lirc_close(struct inode *inode, struct file *file)
162{
163 spin_lock(&dev_lock);
164 device_open = false;
165 spin_unlock(&dev_lock);
166 return 0;
167}
168
169
170static unsigned int lirc_poll(struct file *file, poll_table *wait)
171{
172 poll_wait(file, &lirc_read_queue, wait);
173 if (rx_head != rx_tail)
174 return POLLIN | POLLRDNORM;
175 return 0;
176}
177
178
179static ssize_t lirc_read(struct file *file, char *buf,
180 size_t count, loff_t *ppos)
181{
182 int n = 0;
183 int retval = 0;
184
185 while (n < count) {
186 if (file->f_flags & O_NONBLOCK && rx_head == rx_tail) {
187 retval = -EAGAIN;
188 break;
189 }
190 retval = wait_event_interruptible(lirc_read_queue,
191 rx_head != rx_tail);
192 if (retval)
193 break;
194
195 if (copy_to_user((void *) buf + n, (void *) (rx_buf + rx_head),
196 sizeof(int))) {
197 retval = -EFAULT;
198 break;
199 }
200 rx_head = (rx_head + 1) & (RBUF_LEN - 1);
201 n += sizeof(int);
202 }
203 if (n)
204 return n;
205 return retval;
206}
207
208
209static ssize_t lirc_write(struct file *file, const char *buf,
210 size_t n, loff_t *pos)
211{
212 int i = 0;
213 int *tx_buf;
214
215 if (n % sizeof(int))
216 return -EINVAL;
217 tx_buf = memdup_user(buf, n);
218 if (IS_ERR(tx_buf))
219 return PTR_ERR(tx_buf);
220 n /= sizeof(int);
221 init_send();
222 while (1) {
223 if (i >= n)
224 break;
225 if (tx_buf[i])
226 send_pulse(tx_buf[i]);
227 i++;
228 if (i >= n)
229 break;
230 if (tx_buf[i])
231 send_space(tx_buf[i]);
232 i++;
233 }
234 terminate_send(tx_buf[i - 1]);
235 kfree(tx_buf);
236 return n;
237}
238
239
240static long lirc_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
241{
242 int retval = 0;
243 __u32 value = 0;
244 unsigned long hw_flags;
245
246 if (cmd == LIRC_GET_FEATURES)
247 value = LIRC_CAN_SEND_PULSE |
248 LIRC_CAN_SET_SEND_CARRIER |
249 LIRC_CAN_REC_MODE2;
250 else if (cmd == LIRC_GET_SEND_MODE)
251 value = LIRC_MODE_PULSE;
252 else if (cmd == LIRC_GET_REC_MODE)
253 value = LIRC_MODE_MODE2;
254
255 switch (cmd) {
256 case LIRC_GET_FEATURES:
257 case LIRC_GET_SEND_MODE:
258 case LIRC_GET_REC_MODE:
259 retval = put_user(value, (__u32 *) arg);
260 break;
261
262 case LIRC_SET_SEND_MODE:
263 case LIRC_SET_REC_MODE:
264 retval = get_user(value, (__u32 *) arg);
265 break;
266
267 case LIRC_SET_SEND_CARRIER:
268 retval = get_user(value, (__u32 *) arg);
269 if (retval)
270 return retval;
271 value /= 1000;
272 if (value > IT87_CIR_FREQ_MAX ||
273 value < IT87_CIR_FREQ_MIN)
274 return -EINVAL;
275
276 it87_freq = value;
277
278 spin_lock_irqsave(&hardware_lock, hw_flags);
279 outb(((inb(io + IT87_CIR_TCR2) & IT87_CIR_TCR2_TXMPW) |
280 (it87_freq - IT87_CIR_FREQ_MIN) << 3),
281 io + IT87_CIR_TCR2);
282 spin_unlock_irqrestore(&hardware_lock, hw_flags);
283 dprintk("demodulation frequency: %d kHz\n", it87_freq);
284
285 break;
286
287 default:
288 retval = -EINVAL;
289 }
290
291 if (retval)
292 return retval;
293
294 if (cmd == LIRC_SET_REC_MODE) {
295 if (value != LIRC_MODE_MODE2)
296 retval = -ENOSYS;
297 } else if (cmd == LIRC_SET_SEND_MODE) {
298 if (value != LIRC_MODE_PULSE)
299 retval = -ENOSYS;
300 }
301 return retval;
302}
303
304static void add_read_queue(int flag, unsigned long val)
305{
306 unsigned int new_rx_tail;
307 int newval;
308
309 dprintk("add flag %d with val %lu\n", flag, val);
310
311 newval = val & PULSE_MASK;
312
313 /*
314 * statistically, pulses are ~TIME_CONST/2 too long. we could
315 * maybe make this more exact, but this is good enough
316 */
317 if (flag) {
318 /* pulse */
319 if (newval > TIME_CONST / 2)
320 newval -= TIME_CONST / 2;
321 else /* should not ever happen */
322 newval = 1;
323 newval |= PULSE_BIT;
324 } else
325 newval += TIME_CONST / 2;
326 new_rx_tail = (rx_tail + 1) & (RBUF_LEN - 1);
327 if (new_rx_tail == rx_head) {
328 dprintk("Buffer overrun.\n");
329 return;
330 }
331 rx_buf[rx_tail] = newval;
332 rx_tail = new_rx_tail;
333 wake_up_interruptible(&lirc_read_queue);
334}
335
336
337static const struct file_operations lirc_fops = {
338 .owner = THIS_MODULE,
339 .read = lirc_read,
340 .write = lirc_write,
341 .poll = lirc_poll,
342 .unlocked_ioctl = lirc_ioctl,
343#ifdef CONFIG_COMPAT
344 .compat_ioctl = lirc_ioctl,
345#endif
346 .open = lirc_open,
347 .release = lirc_close,
348 .llseek = noop_llseek,
349};
350
351static int set_use_inc(void *data)
352{
353 return 0;
354}
355
356static void set_use_dec(void *data)
357{
358}
359
360static struct lirc_driver driver = {
361 .name = LIRC_DRIVER_NAME,
362 .minor = -1,
363 .code_length = 1,
364 .sample_rate = 0,
365 .data = NULL,
366 .add_to_buf = NULL,
367 .set_use_inc = set_use_inc,
368 .set_use_dec = set_use_dec,
369 .fops = &lirc_fops,
370 .dev = NULL,
371 .owner = THIS_MODULE,
372};
373
374
375static int init_chrdev(void)
376{
377 driver.minor = lirc_register_driver(&driver);
378
379 if (driver.minor < 0) {
380 printk(KERN_ERR LIRC_DRIVER_NAME ": init_chrdev() failed.\n");
381 return -EIO;
382 }
383 return 0;
384}
385
386
387static void drop_chrdev(void)
388{
389 lirc_unregister_driver(driver.minor);
390}
391
392
393/* SECTION: Hardware */
394static long delta(struct timeval *tv1, struct timeval *tv2)
395{
396 unsigned long deltv;
397
398 deltv = tv2->tv_sec - tv1->tv_sec;
399 if (deltv > 15)
400 deltv = 0xFFFFFF;
401 else
402 deltv = deltv*1000000 + tv2->tv_usec - tv1->tv_usec;
403 return deltv;
404}
405
406static void it87_timeout(unsigned long data)
407{
408 unsigned long flags;
409
410 /* avoid interference with interrupt */
411 spin_lock_irqsave(&timer_lock, flags);
412
413 if (digimatrix) {
414 /* We have timed out. Disable the RX mechanism. */
415
416 outb((inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN) |
417 IT87_CIR_RCR_RXACT, io + IT87_CIR_RCR);
418 if (it87_RXEN_mask)
419 outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
420 io + IT87_CIR_RCR);
421 dprintk(" TIMEOUT\n");
422 timer_enabled = 0;
423
424 /* fifo clear */
425 outb(inb(io + IT87_CIR_TCR1) | IT87_CIR_TCR1_FIFOCLR,
426 io+IT87_CIR_TCR1);
427
428 } else {
429 /*
430 * if last received signal was a pulse, but receiving stopped
431 * within the 9 bit frame, we need to finish this pulse and
432 * simulate a signal change to from pulse to space. Otherwise
433 * upper layers will receive two sequences next time.
434 */
435
436 if (last_value) {
437 unsigned long pulse_end;
438
439 /* determine 'virtual' pulse end: */
440 pulse_end = delta(&last_tv, &last_intr_tv);
441 dprintk("timeout add %d for %lu usec\n",
442 last_value, pulse_end);
443 add_read_queue(last_value, pulse_end);
444 last_value = 0;
445 last_tv = last_intr_tv;
446 }
447 }
448 spin_unlock_irqrestore(&timer_lock, flags);
449}
450
451static irqreturn_t it87_interrupt(int irq, void *dev_id)
452{
453 unsigned char data;
454 struct timeval curr_tv;
455 static unsigned long deltv;
456 unsigned long deltintrtv;
457 unsigned long flags, hw_flags;
458 int iir, lsr;
459 int fifo = 0;
460 static char lastbit;
461 char bit;
462
463 /* Bit duration in microseconds */
464 const unsigned long bit_duration = 1000000ul /
465 (115200 / IT87_CIR_BAUDRATE_DIVISOR);
466
467
468 iir = inb(io + IT87_CIR_IIR);
469
470 switch (iir & IT87_CIR_IIR_IID) {
471 case 0x4:
472 case 0x6:
473 lsr = inb(io + IT87_CIR_RSR) & (IT87_CIR_RSR_RXFTO |
474 IT87_CIR_RSR_RXFBC);
475 fifo = lsr & IT87_CIR_RSR_RXFBC;
476 dprintk("iir: 0x%x fifo: 0x%x\n", iir, lsr);
477
478 /* avoid interference with timer */
479 spin_lock_irqsave(&timer_lock, flags);
480 spin_lock_irqsave(&hardware_lock, hw_flags);
481 if (digimatrix) {
482 static unsigned long acc_pulse;
483 static unsigned long acc_space;
484
485 do {
486 data = inb(io + IT87_CIR_DR);
487 data = ~data;
488 fifo--;
489 if (data != 0x00) {
490 if (timer_enabled)
491 del_timer(&timerlist);
492 /*
493 * start timer for end of
494 * sequence detection
495 */
496 timerlist.expires = jiffies +
497 IT87_TIMEOUT;
498 add_timer(&timerlist);
499 timer_enabled = 1;
500 }
501 /* Loop through */
502 for (bit = 0; bit < 8; ++bit) {
503 if ((data >> bit) & 1) {
504 ++acc_pulse;
505 if (lastbit == 0) {
506 add_read_queue(0,
507 acc_space *
508 bit_duration);
509 acc_space = 0;
510 }
511 } else {
512 ++acc_space;
513 if (lastbit == 1) {
514 add_read_queue(1,
515 acc_pulse *
516 bit_duration);
517 acc_pulse = 0;
518 }
519 }
520 lastbit = (data >> bit) & 1;
521 }
522
523 } while (fifo != 0);
524 } else { /* Normal Operation */
525 do {
526 del_timer(&timerlist);
527 data = inb(io + IT87_CIR_DR);
528
529 dprintk("data=%02x\n", data);
530 do_gettimeofday(&curr_tv);
531 deltv = delta(&last_tv, &curr_tv);
532 deltintrtv = delta(&last_intr_tv, &curr_tv);
533
534 dprintk("t %lu , d %d\n",
535 deltintrtv, (int)data);
536
537 /*
538 * if nothing came in last 2 cycles,
539 * it was gap
540 */
541 if (deltintrtv > TIME_CONST * 2) {
542 if (last_value) {
543 dprintk("GAP\n");
544
545 /* simulate signal change */
546 add_read_queue(last_value,
547 deltv -
548 deltintrtv);
549 last_value = 0;
550 last_tv.tv_sec =
551 last_intr_tv.tv_sec;
552 last_tv.tv_usec =
553 last_intr_tv.tv_usec;
554 deltv = deltintrtv;
555 }
556 }
557 data = 1;
558 if (data ^ last_value) {
559 /*
560 * deltintrtv > 2*TIME_CONST,
561 * remember ? the other case is
562 * timeout
563 */
564 add_read_queue(last_value,
565 deltv-TIME_CONST);
566 last_value = data;
567 last_tv = curr_tv;
568 if (last_tv.tv_usec >= TIME_CONST)
569 last_tv.tv_usec -= TIME_CONST;
570 else {
571 last_tv.tv_sec--;
572 last_tv.tv_usec += 1000000 -
573 TIME_CONST;
574 }
575 }
576 last_intr_tv = curr_tv;
577 if (data) {
578 /*
579 * start timer for end of
580 * sequence detection
581 */
582 timerlist.expires =
583 jiffies + IT87_TIMEOUT;
584 add_timer(&timerlist);
585 }
586 outb((inb(io + IT87_CIR_RCR) &
587 ~IT87_CIR_RCR_RXEN) |
588 IT87_CIR_RCR_RXACT,
589 io + IT87_CIR_RCR);
590 if (it87_RXEN_mask)
591 outb(inb(io + IT87_CIR_RCR) |
592 IT87_CIR_RCR_RXEN,
593 io + IT87_CIR_RCR);
594 fifo--;
595 } while (fifo != 0);
596 }
597 spin_unlock_irqrestore(&hardware_lock, hw_flags);
598 spin_unlock_irqrestore(&timer_lock, flags);
599
600 return IRQ_RETVAL(IRQ_HANDLED);
601
602 default:
603 /* not our irq */
604 dprintk("unknown IRQ (shouldn't happen) !!\n");
605 return IRQ_RETVAL(IRQ_NONE);
606 }
607}
608
609
610static void send_it87(unsigned long len, unsigned long stime,
611 unsigned char send_byte, unsigned int count_bits)
612{
613 long count = len / stime;
614 long time_left = 0;
615 static unsigned char byte_out;
616 unsigned long hw_flags;
617
618 dprintk("%s: len=%ld, sb=%d\n", __func__, len, send_byte);
619
620 time_left = (long)len - (long)count * (long)stime;
621 count += ((2 * time_left) / stime);
622 while (count) {
623 long i = 0;
624 for (i = 0; i < count_bits; i++) {
625 byte_out = (byte_out << 1) | (send_byte & 1);
626 it87_bits_in_byte_out++;
627 }
628 if (it87_bits_in_byte_out == 8) {
629 dprintk("out=0x%x, tsr_txfbc: 0x%x\n",
630 byte_out,
631 inb(io + IT87_CIR_TSR) &
632 IT87_CIR_TSR_TXFBC);
633
634 while ((inb(io + IT87_CIR_TSR) &
635 IT87_CIR_TSR_TXFBC) >= IT87_CIR_FIFO_SIZE)
636 ;
637
638 spin_lock_irqsave(&hardware_lock, hw_flags);
639 outb(byte_out, io + IT87_CIR_DR);
640 spin_unlock_irqrestore(&hardware_lock, hw_flags);
641
642 it87_bits_in_byte_out = 0;
643 it87_send_counter++;
644 byte_out = 0;
645 }
646 count--;
647 }
648}
649
650
651/*TODO: maybe exchange space and pulse because it8705 only modulates 0-bits */
652
653static void send_space(unsigned long len)
654{
655 send_it87(len, TIME_CONST, IT87_CIR_SPACE, IT87_CIR_BAUDRATE_DIVISOR);
656}
657
658static void send_pulse(unsigned long len)
659{
660 send_it87(len, TIME_CONST, IT87_CIR_PULSE, IT87_CIR_BAUDRATE_DIVISOR);
661}
662
663
664static void init_send()
665{
666 unsigned long flags;
667
668 spin_lock_irqsave(&hardware_lock, flags);
669 /* RXEN=0: receiver disable */
670 it87_RXEN_mask = 0;
671 outb(inb(io + IT87_CIR_RCR) & ~IT87_CIR_RCR_RXEN,
672 io + IT87_CIR_RCR);
673 spin_unlock_irqrestore(&hardware_lock, flags);
674 it87_bits_in_byte_out = 0;
675 it87_send_counter = 0;
676}
677
678
679static void terminate_send(unsigned long len)
680{
681 unsigned long flags;
682 unsigned long last = 0;
683
684 last = it87_send_counter;
685 /* make sure all necessary data has been sent */
686 while (last == it87_send_counter)
687 send_space(len);
688 /* wait until all data sent */
689 while ((inb(io + IT87_CIR_TSR) & IT87_CIR_TSR_TXFBC) != 0)
690 ;
691 /* then re-enable receiver */
692 spin_lock_irqsave(&hardware_lock, flags);
693 it87_RXEN_mask = IT87_CIR_RCR_RXEN;
694 outb(inb(io + IT87_CIR_RCR) | IT87_CIR_RCR_RXEN,
695 io + IT87_CIR_RCR);
696 spin_unlock_irqrestore(&hardware_lock, flags);
697}
698
699
700static int init_hardware(void)
701{
702 unsigned long flags;
703 unsigned char it87_rcr = 0;
704
705 spin_lock_irqsave(&hardware_lock, flags);
706 /* init cir-port */
707 /* enable r/w-access to Baudrate-Register */
708 outb(IT87_CIR_IER_BR, io + IT87_CIR_IER);
709 outb(IT87_CIR_BAUDRATE_DIVISOR % 0x100, io+IT87_CIR_BDLR);
710 outb(IT87_CIR_BAUDRATE_DIVISOR / 0x100, io+IT87_CIR_BDHR);
711 /* Baudrate Register off, define IRQs: Input only */
712 if (digimatrix) {
713 outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RFOIE, io + IT87_CIR_IER);
714 /* RX: HCFS=0, RXDCR = 001b (33,75..38,25 kHz), RXEN=1 */
715 } else {
716 outb(IT87_CIR_IER_IEC | IT87_CIR_IER_RDAIE, io + IT87_CIR_IER);
717 /* RX: HCFS=0, RXDCR = 001b (35,6..40,3 kHz), RXEN=1 */
718 }
719 it87_rcr = (IT87_CIR_RCR_RXEN & it87_RXEN_mask) | 0x1;
720 if (it87_enable_demodulator)
721 it87_rcr |= IT87_CIR_RCR_RXEND;
722 outb(it87_rcr, io + IT87_CIR_RCR);
723 if (digimatrix) {
724 /* Set FIFO depth to 1 byte, and disable TX */
725 outb(inb(io + IT87_CIR_TCR1) | 0x00,
726 io + IT87_CIR_TCR1);
727
728 /*
729 * TX: it87_freq (36kHz), 'reserved' sensitivity
730 * setting (0x00)
731 */
732 outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x00,
733 io + IT87_CIR_TCR2);
734 } else {
735 /* TX: 38kHz, 13,3us (pulse-width) */
736 outb(((it87_freq - IT87_CIR_FREQ_MIN) << 3) | 0x06,
737 io + IT87_CIR_TCR2);
738 }
739 spin_unlock_irqrestore(&hardware_lock, flags);
740 return 0;
741}
742
743
744static void drop_hardware(void)
745{
746 unsigned long flags;
747
748 spin_lock_irqsave(&hardware_lock, flags);
749 disable_irq(irq);
750 /* receiver disable */
751 it87_RXEN_mask = 0;
752 outb(0x1, io + IT87_CIR_RCR);
753 /* turn off irqs */
754 outb(0, io + IT87_CIR_IER);
755 /* fifo clear */
756 outb(IT87_CIR_TCR1_FIFOCLR, io+IT87_CIR_TCR1);
757 /* reset */
758 outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
759 enable_irq(irq);
760 spin_unlock_irqrestore(&hardware_lock, flags);
761}
762
763
764static unsigned char it87_read(unsigned char port)
765{
766 outb(port, IT87_ADRPORT);
767 return inb(IT87_DATAPORT);
768}
769
770
771static void it87_write(unsigned char port, unsigned char data)
772{
773 outb(port, IT87_ADRPORT);
774 outb(data, IT87_DATAPORT);
775}
776
777
778/* SECTION: Initialisation */
779
780static int init_port(void)
781{
782 unsigned long hw_flags;
783 int retval = 0;
784
785 unsigned char init_bytes[4] = IT87_INIT;
786 unsigned char it87_chipid = 0;
787 unsigned char ldn = 0;
788 unsigned int it87_io = 0;
789 unsigned int it87_irq = 0;
790
791 /* Enter MB PnP Mode */
792 outb(init_bytes[0], IT87_ADRPORT);
793 outb(init_bytes[1], IT87_ADRPORT);
794 outb(init_bytes[2], IT87_ADRPORT);
795 outb(init_bytes[3], IT87_ADRPORT);
796
797 /* 8712 or 8705 ? */
798 it87_chipid = it87_read(IT87_CHIP_ID1);
799 if (it87_chipid != 0x87) {
800 retval = -ENXIO;
801 return retval;
802 }
803 it87_chipid = it87_read(IT87_CHIP_ID2);
804 if ((it87_chipid != 0x05) &&
805 (it87_chipid != 0x12) &&
806 (it87_chipid != 0x18) &&
807 (it87_chipid != 0x20)) {
808 printk(KERN_INFO LIRC_DRIVER_NAME
809 ": no IT8704/05/12/18/20 found (claimed IT87%02x), "
810 "exiting..\n", it87_chipid);
811 retval = -ENXIO;
812 return retval;
813 }
814 printk(KERN_INFO LIRC_DRIVER_NAME
815 ": found IT87%02x.\n",
816 it87_chipid);
817
818 /* get I/O-Port and IRQ */
819 if (it87_chipid == 0x12 || it87_chipid == 0x18)
820 ldn = IT8712_CIR_LDN;
821 else
822 ldn = IT8705_CIR_LDN;
823 it87_write(IT87_LDN, ldn);
824
825 it87_io = it87_read(IT87_CIR_BASE_MSB) * 256 +
826 it87_read(IT87_CIR_BASE_LSB);
827 if (it87_io == 0) {
828 if (io == 0)
829 io = IT87_CIR_DEFAULT_IOBASE;
830 printk(KERN_INFO LIRC_DRIVER_NAME
831 ": set default io 0x%x\n",
832 io);
833 it87_write(IT87_CIR_BASE_MSB, io / 0x100);
834 it87_write(IT87_CIR_BASE_LSB, io % 0x100);
835 } else
836 io = it87_io;
837
838 it87_irq = it87_read(IT87_CIR_IRQ);
839 if (digimatrix || it87_irq == 0) {
840 if (irq == 0)
841 irq = IT87_CIR_DEFAULT_IRQ;
842 printk(KERN_INFO LIRC_DRIVER_NAME
843 ": set default irq 0x%x\n",
844 irq);
845 it87_write(IT87_CIR_IRQ, irq);
846 } else
847 irq = it87_irq;
848
849 spin_lock_irqsave(&hardware_lock, hw_flags);
850 /* reset */
851 outb(IT87_CIR_IER_RESET, io+IT87_CIR_IER);
852 /* fifo clear */
853 outb(IT87_CIR_TCR1_FIFOCLR |
854 /* IT87_CIR_TCR1_ILE | */
855 IT87_CIR_TCR1_TXRLE |
856 IT87_CIR_TCR1_TXENDF, io+IT87_CIR_TCR1);
857 spin_unlock_irqrestore(&hardware_lock, hw_flags);
858
859 /* get I/O port access and IRQ line */
860 if (request_region(io, 8, LIRC_DRIVER_NAME) == NULL) {
861 printk(KERN_ERR LIRC_DRIVER_NAME
862 ": i/o port 0x%.4x already in use.\n", io);
863 /* Leaving MB PnP Mode */
864 it87_write(IT87_CFGCTRL, 0x2);
865 return -EBUSY;
866 }
867
868 /* activate CIR-Device */
869 it87_write(IT87_CIR_ACT, 0x1);
870
871 /* Leaving MB PnP Mode */
872 it87_write(IT87_CFGCTRL, 0x2);
873
874 retval = request_irq(irq, it87_interrupt, 0 /*IRQF_DISABLED*/,
875 LIRC_DRIVER_NAME, NULL);
876 if (retval < 0) {
877 printk(KERN_ERR LIRC_DRIVER_NAME
878 ": IRQ %d already in use.\n",
879 irq);
880 release_region(io, 8);
881 return retval;
882 }
883
884 printk(KERN_INFO LIRC_DRIVER_NAME
885 ": I/O port 0x%.4x, IRQ %d.\n", io, irq);
886
887 init_timer(&timerlist);
888 timerlist.function = it87_timeout;
889 timerlist.data = 0xabadcafe;
890
891 return 0;
892}
893
894
895static void drop_port(void)
896{
897#if 0
898 unsigned char init_bytes[4] = IT87_INIT;
899
900 /* Enter MB PnP Mode */
901 outb(init_bytes[0], IT87_ADRPORT);
902 outb(init_bytes[1], IT87_ADRPORT);
903 outb(init_bytes[2], IT87_ADRPORT);
904 outb(init_bytes[3], IT87_ADRPORT);
905
906 /* deactivate CIR-Device */
907 it87_write(IT87_CIR_ACT, 0x0);
908
909 /* Leaving MB PnP Mode */
910 it87_write(IT87_CFGCTRL, 0x2);
911#endif
912
913 del_timer_sync(&timerlist);
914 free_irq(irq, NULL);
915 release_region(io, 8);
916}
917
918
919static int init_lirc_it87(void)
920{
921 int retval;
922
923 init_waitqueue_head(&lirc_read_queue);
924 retval = init_port();
925 if (retval < 0)
926 return retval;
927 init_hardware();
928 printk(KERN_INFO LIRC_DRIVER_NAME ": Installed.\n");
929 return 0;
930}
931
932static int it87_probe(struct pnp_dev *pnp_dev,
933 const struct pnp_device_id *dev_id)
934{
935 int retval;
936
937 driver.dev = &pnp_dev->dev;
938
939 retval = init_chrdev();
940 if (retval < 0)
941 return retval;
942
943 retval = init_lirc_it87();
944 if (retval)
945 goto init_lirc_it87_failed;
946
947 return 0;
948
949init_lirc_it87_failed:
950 drop_chrdev();
951
952 return retval;
953}
954
955static int __init lirc_it87_init(void)
956{
957 return pnp_register_driver(&it87_pnp_driver);
958}
959
960
961static void __exit lirc_it87_exit(void)
962{
963 drop_hardware();
964 drop_chrdev();
965 drop_port();
966 pnp_unregister_driver(&it87_pnp_driver);
967 printk(KERN_INFO LIRC_DRIVER_NAME ": Uninstalled.\n");
968}
969
970/* SECTION: PNP for ITE8704/13/18 */
971
972static const struct pnp_device_id pnp_dev_table[] = {
973 {"ITE8704", 0},
974 {"ITE8713", 0},
975 {}
976};
977
978MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
979
980static struct pnp_driver it87_pnp_driver = {
981 .name = LIRC_DRIVER_NAME,
982 .id_table = pnp_dev_table,
983 .probe = it87_probe,
984};
985
986module_init(lirc_it87_init);
987module_exit(lirc_it87_exit);
988
989MODULE_DESCRIPTION("LIRC driver for ITE IT8704/05/12/18/20 CIR port");
990MODULE_AUTHOR("Hans-Gunter Lutke Uphues");
991MODULE_LICENSE("GPL");
992
993module_param(io, int, S_IRUGO);
994MODULE_PARM_DESC(io, "I/O base address (default: 0x310)");
995
996module_param(irq, int, S_IRUGO);
997#ifdef LIRC_IT87_DIGIMATRIX
998MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 9)");
999#else
1000MODULE_PARM_DESC(irq, "Interrupt (1,3-12) (default: 7)");
1001#endif
1002
1003module_param(it87_enable_demodulator, bool, S_IRUGO);
1004MODULE_PARM_DESC(it87_enable_demodulator,
1005 "Receiver demodulator enable/disable (1/0), default: 0");
1006
1007module_param(debug, bool, S_IRUGO | S_IWUSR);
1008MODULE_PARM_DESC(debug, "Enable debugging messages");
1009
1010module_param(digimatrix, bool, S_IRUGO | S_IWUSR);
1011#ifdef LIRC_IT87_DIGIMATRIX
1012MODULE_PARM_DESC(digimatrix,
1013 "Asus Digimatrix it87 compat. enable/disable (1/0), default: 1");
1014#else
1015MODULE_PARM_DESC(digimatrix,
1016 "Asus Digimatrix it87 compat. enable/disable (1/0), default: 0");
1017#endif
1018
1019
1020module_param(it87_freq, int, S_IRUGO);
1021#ifdef LIRC_IT87_DIGIMATRIX
1022MODULE_PARM_DESC(it87_freq,
1023 "Carrier demodulator frequency (kHz), (default: 36)");
1024#else
1025MODULE_PARM_DESC(it87_freq,
1026 "Carrier demodulator frequency (kHz), (default: 38)");
1027#endif
diff --git a/drivers/staging/lirc/lirc_it87.h b/drivers/staging/lirc/lirc_it87.h
deleted file mode 100644
index cf021c893a35..000000000000
--- a/drivers/staging/lirc/lirc_it87.h
+++ /dev/null
@@ -1,116 +0,0 @@
1/* lirc_it87.h */
2/* SECTION: Definitions */
3
4/********************************* ITE IT87xx ************************/
5
6/* based on the following documentation from ITE:
7 a) IT8712F Preliminary CIR Programming Guide V0.1
8 b) IT8705F Simple LPC I/O Preliminary Specification V0.3
9 c) IT8712F EC-LPC I/O Preliminary Specification V0.5
10*/
11
12/* IT8712/05 Ports: */
13#define IT87_ADRPORT 0x2e
14#define IT87_DATAPORT 0x2f
15#define IT87_INIT {0x87, 0x01, 0x55, 0x55}
16
17/* alternate Ports: */
18/*
19#define IT87_ADRPORT 0x4e
20#define IT87_DATAPORT 0x4f
21#define IT87_INIT {0x87, 0x01, 0x55, 0xaa}
22 */
23
24/* IT8712/05 Registers */
25#define IT87_CFGCTRL 0x2
26#define IT87_LDN 0x7
27#define IT87_CHIP_ID1 0x20
28#define IT87_CHIP_ID2 0x21
29#define IT87_CFG_VERSION 0x22
30#define IT87_SWSUSPEND 0x23
31
32#define IT8712_CIR_LDN 0xa
33#define IT8705_CIR_LDN 0x7
34
35/* CIR Configuration Registers: */
36#define IT87_CIR_ACT 0x30
37#define IT87_CIR_BASE_MSB 0x60
38#define IT87_CIR_BASE_LSB 0x61
39#define IT87_CIR_IRQ 0x70
40#define IT87_CIR_CONFIG 0xf0
41
42/* List of IT87_CIR registers: offset to BaseAddr */
43#define IT87_CIR_DR 0
44#define IT87_CIR_IER 1
45#define IT87_CIR_RCR 2
46#define IT87_CIR_TCR1 3
47#define IT87_CIR_TCR2 4
48#define IT87_CIR_TSR 5
49#define IT87_CIR_RSR 6
50#define IT87_CIR_BDLR 5
51#define IT87_CIR_BDHR 6
52#define IT87_CIR_IIR 7
53
54/* Bit Definition */
55/* IER: */
56#define IT87_CIR_IER_TM_EN 0x80
57#define IT87_CIR_IER_RESEVED 0x40
58#define IT87_CIR_IER_RESET 0x20
59#define IT87_CIR_IER_BR 0x10
60#define IT87_CIR_IER_IEC 0x8
61#define IT87_CIR_IER_RFOIE 0x4
62#define IT87_CIR_IER_RDAIE 0x2
63#define IT87_CIR_IER_TLDLIE 0x1
64
65/* RCR: */
66#define IT87_CIR_RCR_RDWOS 0x80
67#define IT87_CIR_RCR_HCFS 0x40
68#define IT87_CIR_RCR_RXEN 0x20
69#define IT87_CIR_RCR_RXEND 0x10
70#define IT87_CIR_RCR_RXACT 0x8
71#define IT87_CIR_RCR_RXDCR 0x7
72
73/* TCR1: */
74#define IT87_CIR_TCR1_FIFOCLR 0x80
75#define IT87_CIR_TCR1_ILE 0x40
76#define IT87_CIR_TCR1_FIFOTL 0x30
77#define IT87_CIR_TCR1_TXRLE 0x8
78#define IT87_CIR_TCR1_TXENDF 0x4
79#define IT87_CIR_TCR1_TXMPM 0x3
80
81/* TCR2: */
82#define IT87_CIR_TCR2_CFQ 0xf8
83#define IT87_CIR_TCR2_TXMPW 0x7
84
85/* TSR: */
86#define IT87_CIR_TSR_RESERVED 0xc0
87#define IT87_CIR_TSR_TXFBC 0x3f
88
89/* RSR: */
90#define IT87_CIR_RSR_RXFTO 0x80
91#define IT87_CIR_RSR_RESERVED 0x40
92#define IT87_CIR_RSR_RXFBC 0x3f
93
94/* IIR: */
95#define IT87_CIR_IIR_RESERVED 0xf8
96#define IT87_CIR_IIR_IID 0x6
97#define IT87_CIR_IIR_IIP 0x1
98
99/* TM: */
100#define IT87_CIR_TM_IL_SEL 0x80
101#define IT87_CIR_TM_RESERVED 0x40
102#define IT87_CIR_TM_TM_REG 0x3f
103
104#define IT87_CIR_FIFO_SIZE 32
105
106/* Baudratedivisor for IT87: power of 2: only 1,2,4 or 8) */
107#define IT87_CIR_BAUDRATE_DIVISOR 0x1
108#define IT87_CIR_DEFAULT_IOBASE 0x310
109#define IT87_CIR_DEFAULT_IRQ 0x7
110#define IT87_CIR_SPACE 0x00
111#define IT87_CIR_PULSE 0xff
112#define IT87_CIR_FREQ_MIN 27
113#define IT87_CIR_FREQ_MAX 58
114#define TIME_CONST (IT87_CIR_BAUDRATE_DIVISOR * 8000000ul / 115200ul)
115
116/********************************* ITE IT87xx ************************/
diff --git a/drivers/staging/lirc/lirc_ite8709.c b/drivers/staging/lirc/lirc_ite8709.c
deleted file mode 100644
index cb20cfdcfadd..000000000000
--- a/drivers/staging/lirc/lirc_ite8709.c
+++ /dev/null
@@ -1,542 +0,0 @@
1/*
2 * LIRC driver for ITE8709 CIR port
3 *
4 * Copyright (C) 2008 Grégory Lardière <spmf2004-lirc@yahoo.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; 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 GNU
14 * 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, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22#include <linux/module.h>
23#include <linux/interrupt.h>
24#include <linux/sched.h>
25#include <linux/delay.h>
26#include <linux/pnp.h>
27#include <linux/io.h>
28
29#include <media/lirc.h>
30#include <media/lirc_dev.h>
31
32#define LIRC_DRIVER_NAME "lirc_ite8709"
33
34#define BUF_CHUNK_SIZE sizeof(int)
35#define BUF_SIZE (128*BUF_CHUNK_SIZE)
36
37/*
38 * The ITE8709 device seems to be the combination of IT8512 superIO chip and
39 * a specific firmware running on the IT8512's embedded micro-controller.
40 * In addition of the embedded micro-controller, the IT8512 chip contains a
41 * CIR module and several other modules. A few modules are directly accessible
42 * by the host CPU, but most of them are only accessible by the
43 * micro-controller. The CIR module is only accessible by the micro-controller.
44 * The battery-backed SRAM module is accessible by the host CPU and the
45 * micro-controller. So one of the MC's firmware role is to act as a bridge
46 * between the host CPU and the CIR module. The firmware implements a kind of
47 * communication protocol using the SRAM module as a shared memory. The IT8512
48 * specification is publicly available on ITE's web site, but the communication
49 * protocol is not, so it was reverse-engineered.
50 */
51
52/* ITE8709 Registers addresses and values (reverse-engineered) */
53#define ITE8709_MODE 0x1a
54#define ITE8709_REG_ADR 0x1b
55#define ITE8709_REG_VAL 0x1c
56#define ITE8709_IIR 0x1e /* Interrupt identification register */
57#define ITE8709_RFSR 0x1f /* Receiver FIFO status register */
58#define ITE8709_FIFO_START 0x20
59
60#define ITE8709_MODE_READY 0X00
61#define ITE8709_MODE_WRITE 0X01
62#define ITE8709_MODE_READ 0X02
63#define ITE8709_IIR_RDAI 0x02 /* Receiver data available interrupt */
64#define ITE8709_IIR_RFOI 0x04 /* Receiver FIFO overrun interrupt */
65#define ITE8709_RFSR_MASK 0x3f /* FIFO byte count mask */
66
67/*
68 * IT8512 CIR-module registers addresses and values
69 * (from IT8512 E/F specification v0.4.1)
70 */
71#define IT8512_REG_MSTCR 0x01 /* Master control register */
72#define IT8512_REG_IER 0x02 /* Interrupt enable register */
73#define IT8512_REG_CFR 0x04 /* Carrier frequency register */
74#define IT8512_REG_RCR 0x05 /* Receive control register */
75#define IT8512_REG_BDLR 0x08 /* Baud rate divisor low byte register */
76#define IT8512_REG_BDHR 0x09 /* Baud rate divisor high byte register */
77
78#define IT8512_MSTCR_RESET 0x01 /* Reset registers to default value */
79#define IT8512_MSTCR_FIFOCLR 0x02 /* Clear FIFO */
80#define IT8512_MSTCR_FIFOTL_7 0x04 /* FIFO threshold level : 7 */
81#define IT8512_MSTCR_FIFOTL_25 0x0c /* FIFO threshold level : 25 */
82#define IT8512_IER_RDAIE 0x02 /* Enable data interrupt request */
83#define IT8512_IER_RFOIE 0x04 /* Enable FIFO overrun interrupt req */
84#define IT8512_IER_IEC 0x80 /* Enable interrupt request */
85#define IT8512_CFR_CF_36KHZ 0x09 /* Carrier freq : low speed, 36kHz */
86#define IT8512_RCR_RXDCR_1 0x01 /* Demodulation carrier range : 1 */
87#define IT8512_RCR_RXACT 0x08 /* Receiver active */
88#define IT8512_RCR_RXEN 0x80 /* Receiver enable */
89#define IT8512_BDR_6 6 /* Baud rate divisor : 6 */
90
91/* Actual values used by this driver */
92#define CFG_FIFOTL IT8512_MSTCR_FIFOTL_25
93#define CFG_CR_FREQ IT8512_CFR_CF_36KHZ
94#define CFG_DCR IT8512_RCR_RXDCR_1
95#define CFG_BDR IT8512_BDR_6
96#define CFG_TIMEOUT 100000 /* Rearm interrupt when a space is > 100 ms */
97
98static int debug;
99
100struct ite8709_device {
101 int use_count;
102 int io;
103 int irq;
104 spinlock_t hardware_lock;
105 __u64 acc_pulse;
106 __u64 acc_space;
107 char lastbit;
108 struct timeval last_tv;
109 struct lirc_driver driver;
110 struct tasklet_struct tasklet;
111 char force_rearm;
112 char rearmed;
113 char device_busy;
114};
115
116#define dprintk(fmt, args...) \
117 do { \
118 if (debug) \
119 printk(KERN_DEBUG LIRC_DRIVER_NAME ": " \
120 fmt, ## args); \
121 } while (0)
122
123
124static unsigned char ite8709_read(struct ite8709_device *dev,
125 unsigned char port)
126{
127 outb(port, dev->io);
128 return inb(dev->io+1);
129}
130
131static void ite8709_write(struct ite8709_device *dev, unsigned char port,
132 unsigned char data)
133{
134 outb(port, dev->io);
135 outb(data, dev->io+1);
136}
137
138static void ite8709_wait_device(struct ite8709_device *dev)
139{
140 int i = 0;
141 /*
142 * loop until device tells it's ready to continue
143 * iterations count is usually ~750 but can sometimes achieve 13000
144 */
145 for (i = 0; i < 15000; i++) {
146 udelay(2);
147 if (ite8709_read(dev, ITE8709_MODE) == ITE8709_MODE_READY)
148 break;
149 }
150}
151
152static void ite8709_write_register(struct ite8709_device *dev,
153 unsigned char reg_adr, unsigned char reg_value)
154{
155 ite8709_wait_device(dev);
156
157 ite8709_write(dev, ITE8709_REG_VAL, reg_value);
158 ite8709_write(dev, ITE8709_REG_ADR, reg_adr);
159 ite8709_write(dev, ITE8709_MODE, ITE8709_MODE_WRITE);
160}
161
162static void ite8709_init_hardware(struct ite8709_device *dev)
163{
164 spin_lock_irq(&dev->hardware_lock);
165 dev->device_busy = 1;
166 spin_unlock_irq(&dev->hardware_lock);
167
168 ite8709_write_register(dev, IT8512_REG_BDHR, (CFG_BDR >> 8) & 0xff);
169 ite8709_write_register(dev, IT8512_REG_BDLR, CFG_BDR & 0xff);
170 ite8709_write_register(dev, IT8512_REG_CFR, CFG_CR_FREQ);
171 ite8709_write_register(dev, IT8512_REG_IER,
172 IT8512_IER_IEC | IT8512_IER_RFOIE | IT8512_IER_RDAIE);
173 ite8709_write_register(dev, IT8512_REG_RCR, CFG_DCR);
174 ite8709_write_register(dev, IT8512_REG_MSTCR,
175 CFG_FIFOTL | IT8512_MSTCR_FIFOCLR);
176 ite8709_write_register(dev, IT8512_REG_RCR,
177 IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR);
178
179 spin_lock_irq(&dev->hardware_lock);
180 dev->device_busy = 0;
181 spin_unlock_irq(&dev->hardware_lock);
182
183 tasklet_enable(&dev->tasklet);
184}
185
186static void ite8709_drop_hardware(struct ite8709_device *dev)
187{
188 tasklet_disable(&dev->tasklet);
189
190 spin_lock_irq(&dev->hardware_lock);
191 dev->device_busy = 1;
192 spin_unlock_irq(&dev->hardware_lock);
193
194 ite8709_write_register(dev, IT8512_REG_RCR, 0);
195 ite8709_write_register(dev, IT8512_REG_MSTCR,
196 IT8512_MSTCR_RESET | IT8512_MSTCR_FIFOCLR);
197
198 spin_lock_irq(&dev->hardware_lock);
199 dev->device_busy = 0;
200 spin_unlock_irq(&dev->hardware_lock);
201}
202
203static int ite8709_set_use_inc(void *data)
204{
205 struct ite8709_device *dev;
206 dev = data;
207 if (dev->use_count == 0)
208 ite8709_init_hardware(dev);
209 dev->use_count++;
210 return 0;
211}
212
213static void ite8709_set_use_dec(void *data)
214{
215 struct ite8709_device *dev;
216 dev = data;
217 dev->use_count--;
218 if (dev->use_count == 0)
219 ite8709_drop_hardware(dev);
220}
221
222static void ite8709_add_read_queue(struct ite8709_device *dev, int flag,
223 __u64 val)
224{
225 int value;
226
227 dprintk("add a %llu usec %s\n", val, flag ? "pulse" : "space");
228
229 value = (val > PULSE_MASK) ? PULSE_MASK : val;
230 if (flag)
231 value |= PULSE_BIT;
232
233 if (!lirc_buffer_full(dev->driver.rbuf)) {
234 lirc_buffer_write(dev->driver.rbuf, (void *) &value);
235 wake_up(&dev->driver.rbuf->wait_poll);
236 }
237}
238
239static irqreturn_t ite8709_interrupt(int irq, void *dev_id)
240{
241 unsigned char data;
242 int iir, rfsr, i;
243 int fifo = 0;
244 char bit;
245 struct timeval curr_tv;
246
247 /* Bit duration in microseconds */
248 const unsigned long bit_duration = 1000000ul / (115200 / CFG_BDR);
249
250 struct ite8709_device *dev;
251 dev = dev_id;
252
253 /*
254 * If device is busy, we simply discard data because we are in one of
255 * these two cases : shutting down or rearming the device, so this
256 * doesn't really matter and this avoids waiting too long in IRQ ctx
257 */
258 spin_lock(&dev->hardware_lock);
259 if (dev->device_busy) {
260 spin_unlock(&dev->hardware_lock);
261 return IRQ_RETVAL(IRQ_HANDLED);
262 }
263
264 iir = ite8709_read(dev, ITE8709_IIR);
265
266 switch (iir) {
267 case ITE8709_IIR_RFOI:
268 dprintk("fifo overrun, scheduling forced rearm just in case\n");
269 dev->force_rearm = 1;
270 tasklet_schedule(&dev->tasklet);
271 spin_unlock(&dev->hardware_lock);
272 return IRQ_RETVAL(IRQ_HANDLED);
273
274 case ITE8709_IIR_RDAI:
275 rfsr = ite8709_read(dev, ITE8709_RFSR);
276 fifo = rfsr & ITE8709_RFSR_MASK;
277 if (fifo > 32)
278 fifo = 32;
279 dprintk("iir: 0x%x rfsr: 0x%x fifo: %d\n", iir, rfsr, fifo);
280
281 if (dev->rearmed) {
282 do_gettimeofday(&curr_tv);
283 dev->acc_space += 1000000ull
284 * (curr_tv.tv_sec - dev->last_tv.tv_sec)
285 + (curr_tv.tv_usec - dev->last_tv.tv_usec);
286 dev->rearmed = 0;
287 }
288 for (i = 0; i < fifo; i++) {
289 data = ite8709_read(dev, i+ITE8709_FIFO_START);
290 data = ~data;
291 /* Loop through */
292 for (bit = 0; bit < 8; ++bit) {
293 if ((data >> bit) & 1) {
294 dev->acc_pulse += bit_duration;
295 if (dev->lastbit == 0) {
296 ite8709_add_read_queue(dev, 0,
297 dev->acc_space);
298 dev->acc_space = 0;
299 }
300 } else {
301 dev->acc_space += bit_duration;
302 if (dev->lastbit == 1) {
303 ite8709_add_read_queue(dev, 1,
304 dev->acc_pulse);
305 dev->acc_pulse = 0;
306 }
307 }
308 dev->lastbit = (data >> bit) & 1;
309 }
310 }
311 ite8709_write(dev, ITE8709_RFSR, 0);
312
313 if (dev->acc_space > CFG_TIMEOUT) {
314 dprintk("scheduling rearm IRQ\n");
315 do_gettimeofday(&dev->last_tv);
316 dev->force_rearm = 0;
317 tasklet_schedule(&dev->tasklet);
318 }
319
320 spin_unlock(&dev->hardware_lock);
321 return IRQ_RETVAL(IRQ_HANDLED);
322
323 default:
324 /* not our irq */
325 dprintk("unknown IRQ (shouldn't happen) !!\n");
326 spin_unlock(&dev->hardware_lock);
327 return IRQ_RETVAL(IRQ_NONE);
328 }
329}
330
331static void ite8709_rearm_irq(unsigned long data)
332{
333 struct ite8709_device *dev;
334 unsigned long flags;
335 dev = (struct ite8709_device *) data;
336
337 spin_lock_irqsave(&dev->hardware_lock, flags);
338 dev->device_busy = 1;
339 spin_unlock_irqrestore(&dev->hardware_lock, flags);
340
341 if (dev->force_rearm || dev->acc_space > CFG_TIMEOUT) {
342 dprintk("rearming IRQ\n");
343 ite8709_write_register(dev, IT8512_REG_RCR,
344 IT8512_RCR_RXACT | CFG_DCR);
345 ite8709_write_register(dev, IT8512_REG_MSTCR,
346 CFG_FIFOTL | IT8512_MSTCR_FIFOCLR);
347 ite8709_write_register(dev, IT8512_REG_RCR,
348 IT8512_RCR_RXEN | IT8512_RCR_RXACT | CFG_DCR);
349 if (!dev->force_rearm)
350 dev->rearmed = 1;
351 dev->force_rearm = 0;
352 }
353
354 spin_lock_irqsave(&dev->hardware_lock, flags);
355 dev->device_busy = 0;
356 spin_unlock_irqrestore(&dev->hardware_lock, flags);
357}
358
359static int ite8709_cleanup(struct ite8709_device *dev, int stage, int errno,
360 char *msg)
361{
362 if (msg != NULL)
363 printk(KERN_ERR LIRC_DRIVER_NAME ": %s\n", msg);
364
365 switch (stage) {
366 case 6:
367 if (dev->use_count > 0)
368 ite8709_drop_hardware(dev);
369 case 5:
370 free_irq(dev->irq, dev);
371 case 4:
372 release_region(dev->io, 2);
373 case 3:
374 lirc_unregister_driver(dev->driver.minor);
375 case 2:
376 lirc_buffer_free(dev->driver.rbuf);
377 kfree(dev->driver.rbuf);
378 case 1:
379 kfree(dev);
380 case 0:
381 ;
382 }
383
384 return errno;
385}
386
387static int __devinit ite8709_pnp_probe(struct pnp_dev *dev,
388 const struct pnp_device_id *dev_id)
389{
390 struct lirc_driver *driver;
391 struct ite8709_device *ite8709_dev;
392 int ret;
393
394 /* Check resources validity */
395 if (!pnp_irq_valid(dev, 0))
396 return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IRQ");
397 if (!pnp_port_valid(dev, 2))
398 return ite8709_cleanup(NULL, 0, -ENODEV, "invalid IO port");
399
400 /* Allocate memory for device struct */
401 ite8709_dev = kzalloc(sizeof(struct ite8709_device), GFP_KERNEL);
402 if (ite8709_dev == NULL)
403 return ite8709_cleanup(NULL, 0, -ENOMEM, "kzalloc failed");
404 pnp_set_drvdata(dev, ite8709_dev);
405
406 /* Initialize device struct */
407 ite8709_dev->use_count = 0;
408 ite8709_dev->irq = pnp_irq(dev, 0);
409 ite8709_dev->io = pnp_port_start(dev, 2);
410 ite8709_dev->hardware_lock =
411 __SPIN_LOCK_UNLOCKED(ite8709_dev->hardware_lock);
412 ite8709_dev->acc_pulse = 0;
413 ite8709_dev->acc_space = 0;
414 ite8709_dev->lastbit = 0;
415 do_gettimeofday(&ite8709_dev->last_tv);
416 tasklet_init(&ite8709_dev->tasklet, ite8709_rearm_irq,
417 (long) ite8709_dev);
418 ite8709_dev->force_rearm = 0;
419 ite8709_dev->rearmed = 0;
420 ite8709_dev->device_busy = 0;
421
422 /* Initialize driver struct */
423 driver = &ite8709_dev->driver;
424 strcpy(driver->name, LIRC_DRIVER_NAME);
425 driver->minor = -1;
426 driver->code_length = sizeof(int) * 8;
427 driver->sample_rate = 0;
428 driver->features = LIRC_CAN_REC_MODE2;
429 driver->data = ite8709_dev;
430 driver->add_to_buf = NULL;
431 driver->set_use_inc = ite8709_set_use_inc;
432 driver->set_use_dec = ite8709_set_use_dec;
433 driver->dev = &dev->dev;
434 driver->owner = THIS_MODULE;
435
436 /* Initialize LIRC buffer */
437 driver->rbuf = kmalloc(sizeof(struct lirc_buffer), GFP_KERNEL);
438 if (!driver->rbuf)
439 return ite8709_cleanup(ite8709_dev, 1, -ENOMEM,
440 "can't allocate lirc_buffer");
441 if (lirc_buffer_init(driver->rbuf, BUF_CHUNK_SIZE, BUF_SIZE))
442 return ite8709_cleanup(ite8709_dev, 1, -ENOMEM,
443 "lirc_buffer_init() failed");
444
445 /* Register LIRC driver */
446 ret = lirc_register_driver(driver);
447 if (ret < 0)
448 return ite8709_cleanup(ite8709_dev, 2, ret,
449 "lirc_register_driver() failed");
450
451 /* Reserve I/O port access */
452 if (!request_region(ite8709_dev->io, 2, LIRC_DRIVER_NAME))
453 return ite8709_cleanup(ite8709_dev, 3, -EBUSY,
454 "i/o port already in use");
455
456 /* Reserve IRQ line */
457 ret = request_irq(ite8709_dev->irq, ite8709_interrupt, 0,
458 LIRC_DRIVER_NAME, ite8709_dev);
459 if (ret < 0)
460 return ite8709_cleanup(ite8709_dev, 4, ret,
461 "IRQ already in use");
462
463 /* Initialize hardware */
464 ite8709_drop_hardware(ite8709_dev); /* Shutdown hw until first use */
465
466 printk(KERN_INFO LIRC_DRIVER_NAME ": device found : irq=%d io=0x%x\n",
467 ite8709_dev->irq, ite8709_dev->io);
468
469 return 0;
470}
471
472static void __devexit ite8709_pnp_remove(struct pnp_dev *dev)
473{
474 struct ite8709_device *ite8709_dev;
475 ite8709_dev = pnp_get_drvdata(dev);
476
477 ite8709_cleanup(ite8709_dev, 6, 0, NULL);
478
479 printk(KERN_INFO LIRC_DRIVER_NAME ": device removed\n");
480}
481
482#ifdef CONFIG_PM
483static int ite8709_pnp_suspend(struct pnp_dev *dev, pm_message_t state)
484{
485 struct ite8709_device *ite8709_dev;
486 ite8709_dev = pnp_get_drvdata(dev);
487
488 if (ite8709_dev->use_count > 0)
489 ite8709_drop_hardware(ite8709_dev);
490
491 return 0;
492}
493
494static int ite8709_pnp_resume(struct pnp_dev *dev)
495{
496 struct ite8709_device *ite8709_dev;
497 ite8709_dev = pnp_get_drvdata(dev);
498
499 if (ite8709_dev->use_count > 0)
500 ite8709_init_hardware(ite8709_dev);
501
502 return 0;
503}
504#else
505#define ite8709_pnp_suspend NULL
506#define ite8709_pnp_resume NULL
507#endif
508
509static const struct pnp_device_id pnp_dev_table[] = {
510 {"ITE8709", 0},
511 {}
512};
513
514MODULE_DEVICE_TABLE(pnp, pnp_dev_table);
515
516static struct pnp_driver ite8709_pnp_driver = {
517 .name = LIRC_DRIVER_NAME,
518 .probe = ite8709_pnp_probe,
519 .remove = __devexit_p(ite8709_pnp_remove),
520 .suspend = ite8709_pnp_suspend,
521 .resume = ite8709_pnp_resume,
522 .id_table = pnp_dev_table,
523};
524
525static int __init ite8709_init_module(void)
526{
527 return pnp_register_driver(&ite8709_pnp_driver);
528}
529module_init(ite8709_init_module);
530
531static void __exit ite8709_cleanup_module(void)
532{
533 pnp_unregister_driver(&ite8709_pnp_driver);
534}
535module_exit(ite8709_cleanup_module);
536
537MODULE_DESCRIPTION("LIRC driver for ITE8709 CIR port");
538MODULE_AUTHOR("Grégory Lardière");
539MODULE_LICENSE("GPL");
540
541module_param(debug, bool, S_IRUGO | S_IWUSR);
542MODULE_PARM_DESC(debug, "Enable debugging messages");
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c
index 925eabe14854..63a438d1c849 100644
--- a/drivers/staging/lirc/lirc_sasem.c
+++ b/drivers/staging/lirc/lirc_sasem.c
@@ -364,7 +364,7 @@ static ssize_t vfd_write(struct file *file, const char *buf,
364 int i; 364 int i;
365 int retval = 0; 365 int retval = 0;
366 struct sasem_context *context; 366 struct sasem_context *context;
367 int *data_buf; 367 int *data_buf = NULL;
368 368
369 context = (struct sasem_context *) file->private_data; 369 context = (struct sasem_context *) file->private_data;
370 if (!context) { 370 if (!context) {
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/lirc/lirc_zilog.c
index 0aad0d7a74a3..dd6a57c3c3a3 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/lirc/lirc_zilog.c
@@ -63,14 +63,16 @@
63#include <media/lirc_dev.h> 63#include <media/lirc_dev.h>
64#include <media/lirc.h> 64#include <media/lirc.h>
65 65
66struct IR;
67
66struct IR_rx { 68struct IR_rx {
69 struct kref ref;
70 struct IR *ir;
71
67 /* RX device */ 72 /* RX device */
73 struct mutex client_lock;
68 struct i2c_client *c; 74 struct i2c_client *c;
69 75
70 /* RX device buffer & lock */
71 struct lirc_buffer buf;
72 struct mutex buf_lock;
73
74 /* RX polling thread data */ 76 /* RX polling thread data */
75 struct task_struct *task; 77 struct task_struct *task;
76 78
@@ -80,7 +82,11 @@ struct IR_rx {
80}; 82};
81 83
82struct IR_tx { 84struct IR_tx {
85 struct kref ref;
86 struct IR *ir;
87
83 /* TX device */ 88 /* TX device */
89 struct mutex client_lock;
84 struct i2c_client *c; 90 struct i2c_client *c;
85 91
86 /* TX additional actions needed */ 92 /* TX additional actions needed */
@@ -89,19 +95,34 @@ struct IR_tx {
89}; 95};
90 96
91struct IR { 97struct IR {
98 struct kref ref;
99 struct list_head list;
100
101 /* FIXME spinlock access to l.features */
92 struct lirc_driver l; 102 struct lirc_driver l;
103 struct lirc_buffer rbuf;
93 104
94 struct mutex ir_lock; 105 struct mutex ir_lock;
95 int open; 106 atomic_t open_count;
96 107
97 struct i2c_adapter *adapter; 108 struct i2c_adapter *adapter;
109
110 spinlock_t rx_ref_lock; /* struct IR_rx kref get()/put() */
98 struct IR_rx *rx; 111 struct IR_rx *rx;
112
113 spinlock_t tx_ref_lock; /* struct IR_tx kref get()/put() */
99 struct IR_tx *tx; 114 struct IR_tx *tx;
100}; 115};
101 116
102/* Minor -> data mapping */ 117/* IR transceiver instance object list */
103static struct mutex ir_devices_lock; 118/*
104static struct IR *ir_devices[MAX_IRCTL_DEVICES]; 119 * This lock is used for the following:
120 * a. ir_devices_list access, insertions, deletions
121 * b. struct IR kref get()s and put()s
122 * c. serialization of ir_probe() for the two i2c_clients for a Z8
123 */
124static DEFINE_MUTEX(ir_devices_lock);
125static LIST_HEAD(ir_devices_list);
105 126
106/* Block size for IR transmitter */ 127/* Block size for IR transmitter */
107#define TX_BLOCK_SIZE 99 128#define TX_BLOCK_SIZE 99
@@ -147,6 +168,157 @@ static int minor = -1; /* minor number */
147 ## args); \ 168 ## args); \
148 } while (0) 169 } while (0)
149 170
171
172/* struct IR reference counting */
173static struct IR *get_ir_device(struct IR *ir, bool ir_devices_lock_held)
174{
175 if (ir_devices_lock_held) {
176 kref_get(&ir->ref);
177 } else {
178 mutex_lock(&ir_devices_lock);
179 kref_get(&ir->ref);
180 mutex_unlock(&ir_devices_lock);
181 }
182 return ir;
183}
184
185static void release_ir_device(struct kref *ref)
186{
187 struct IR *ir = container_of(ref, struct IR, ref);
188
189 /*
190 * Things should be in this state by now:
191 * ir->rx set to NULL and deallocated - happens before ir->rx->ir put()
192 * ir->rx->task kthread stopped - happens before ir->rx->ir put()
193 * ir->tx set to NULL and deallocated - happens before ir->tx->ir put()
194 * ir->open_count == 0 - happens on final close()
195 * ir_lock, tx_ref_lock, rx_ref_lock, all released
196 */
197 if (ir->l.minor >= 0 && ir->l.minor < MAX_IRCTL_DEVICES) {
198 lirc_unregister_driver(ir->l.minor);
199 ir->l.minor = MAX_IRCTL_DEVICES;
200 }
201 if (ir->rbuf.fifo_initialized)
202 lirc_buffer_free(&ir->rbuf);
203 list_del(&ir->list);
204 kfree(ir);
205}
206
207static int put_ir_device(struct IR *ir, bool ir_devices_lock_held)
208{
209 int released;
210
211 if (ir_devices_lock_held)
212 return kref_put(&ir->ref, release_ir_device);
213
214 mutex_lock(&ir_devices_lock);
215 released = kref_put(&ir->ref, release_ir_device);
216 mutex_unlock(&ir_devices_lock);
217
218 return released;
219}
220
221/* struct IR_rx reference counting */
222static struct IR_rx *get_ir_rx(struct IR *ir)
223{
224 struct IR_rx *rx;
225
226 spin_lock(&ir->rx_ref_lock);
227 rx = ir->rx;
228 if (rx != NULL)
229 kref_get(&rx->ref);
230 spin_unlock(&ir->rx_ref_lock);
231 return rx;
232}
233
234static void destroy_rx_kthread(struct IR_rx *rx, bool ir_devices_lock_held)
235{
236 /* end up polling thread */
237 if (!IS_ERR_OR_NULL(rx->task)) {
238 kthread_stop(rx->task);
239 rx->task = NULL;
240 /* Put the ir ptr that ir_probe() gave to the rx poll thread */
241 put_ir_device(rx->ir, ir_devices_lock_held);
242 }
243}
244
245static void release_ir_rx(struct kref *ref)
246{
247 struct IR_rx *rx = container_of(ref, struct IR_rx, ref);
248 struct IR *ir = rx->ir;
249
250 /*
251 * This release function can't do all the work, as we want
252 * to keep the rx_ref_lock a spinlock, and killing the poll thread
253 * and releasing the ir reference can cause a sleep. That work is
254 * performed by put_ir_rx()
255 */
256 ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
257 /* Don't put_ir_device(rx->ir) here; lock can't be freed yet */
258 ir->rx = NULL;
259 /* Don't do the kfree(rx) here; we still need to kill the poll thread */
260 return;
261}
262
263static int put_ir_rx(struct IR_rx *rx, bool ir_devices_lock_held)
264{
265 int released;
266 struct IR *ir = rx->ir;
267
268 spin_lock(&ir->rx_ref_lock);
269 released = kref_put(&rx->ref, release_ir_rx);
270 spin_unlock(&ir->rx_ref_lock);
271 /* Destroy the rx kthread while not holding the spinlock */
272 if (released) {
273 destroy_rx_kthread(rx, ir_devices_lock_held);
274 kfree(rx);
275 /* Make sure we're not still in a poll_table somewhere */
276 wake_up_interruptible(&ir->rbuf.wait_poll);
277 }
278 /* Do a reference put() for the rx->ir reference, if we released rx */
279 if (released)
280 put_ir_device(ir, ir_devices_lock_held);
281 return released;
282}
283
284/* struct IR_tx reference counting */
285static struct IR_tx *get_ir_tx(struct IR *ir)
286{
287 struct IR_tx *tx;
288
289 spin_lock(&ir->tx_ref_lock);
290 tx = ir->tx;
291 if (tx != NULL)
292 kref_get(&tx->ref);
293 spin_unlock(&ir->tx_ref_lock);
294 return tx;
295}
296
297static void release_ir_tx(struct kref *ref)
298{
299 struct IR_tx *tx = container_of(ref, struct IR_tx, ref);
300 struct IR *ir = tx->ir;
301
302 ir->l.features &= ~LIRC_CAN_SEND_PULSE;
303 /* Don't put_ir_device(tx->ir) here, so our lock doesn't get freed */
304 ir->tx = NULL;
305 kfree(tx);
306}
307
308static int put_ir_tx(struct IR_tx *tx, bool ir_devices_lock_held)
309{
310 int released;
311 struct IR *ir = tx->ir;
312
313 spin_lock(&ir->tx_ref_lock);
314 released = kref_put(&tx->ref, release_ir_tx);
315 spin_unlock(&ir->tx_ref_lock);
316 /* Do a reference put() for the tx->ir reference, if we released tx */
317 if (released)
318 put_ir_device(ir, ir_devices_lock_held);
319 return released;
320}
321
150static int add_to_buf(struct IR *ir) 322static int add_to_buf(struct IR *ir)
151{ 323{
152 __u16 code; 324 __u16 code;
@@ -156,23 +328,38 @@ static int add_to_buf(struct IR *ir)
156 int ret; 328 int ret;
157 int failures = 0; 329 int failures = 0;
158 unsigned char sendbuf[1] = { 0 }; 330 unsigned char sendbuf[1] = { 0 };
159 struct IR_rx *rx = ir->rx; 331 struct lirc_buffer *rbuf = ir->l.rbuf;
332 struct IR_rx *rx;
333 struct IR_tx *tx;
160 334
335 if (lirc_buffer_full(rbuf)) {
336 dprintk("buffer overflow\n");
337 return -EOVERFLOW;
338 }
339
340 rx = get_ir_rx(ir);
161 if (rx == NULL) 341 if (rx == NULL)
162 return -ENXIO; 342 return -ENXIO;
163 343
164 if (lirc_buffer_full(&rx->buf)) { 344 /* Ensure our rx->c i2c_client remains valid for the duration */
165 dprintk("buffer overflow\n"); 345 mutex_lock(&rx->client_lock);
166 return -EOVERFLOW; 346 if (rx->c == NULL) {
347 mutex_unlock(&rx->client_lock);
348 put_ir_rx(rx, false);
349 return -ENXIO;
167 } 350 }
168 351
352 tx = get_ir_tx(ir);
353
169 /* 354 /*
170 * service the device as long as it is returning 355 * service the device as long as it is returning
171 * data and we have space 356 * data and we have space
172 */ 357 */
173 do { 358 do {
174 if (kthread_should_stop()) 359 if (kthread_should_stop()) {
175 return -ENODATA; 360 ret = -ENODATA;
361 break;
362 }
176 363
177 /* 364 /*
178 * Lock i2c bus for the duration. RX/TX chips interfere so 365 * Lock i2c bus for the duration. RX/TX chips interfere so
@@ -182,7 +369,8 @@ static int add_to_buf(struct IR *ir)
182 369
183 if (kthread_should_stop()) { 370 if (kthread_should_stop()) {
184 mutex_unlock(&ir->ir_lock); 371 mutex_unlock(&ir->ir_lock);
185 return -ENODATA; 372 ret = -ENODATA;
373 break;
186 } 374 }
187 375
188 /* 376 /*
@@ -196,7 +384,7 @@ static int add_to_buf(struct IR *ir)
196 mutex_unlock(&ir->ir_lock); 384 mutex_unlock(&ir->ir_lock);
197 zilog_error("unable to read from the IR chip " 385 zilog_error("unable to read from the IR chip "
198 "after 3 resets, giving up\n"); 386 "after 3 resets, giving up\n");
199 return ret; 387 break;
200 } 388 }
201 389
202 /* Looks like the chip crashed, reset it */ 390 /* Looks like the chip crashed, reset it */
@@ -206,19 +394,23 @@ static int add_to_buf(struct IR *ir)
206 set_current_state(TASK_UNINTERRUPTIBLE); 394 set_current_state(TASK_UNINTERRUPTIBLE);
207 if (kthread_should_stop()) { 395 if (kthread_should_stop()) {
208 mutex_unlock(&ir->ir_lock); 396 mutex_unlock(&ir->ir_lock);
209 return -ENODATA; 397 ret = -ENODATA;
398 break;
210 } 399 }
211 schedule_timeout((100 * HZ + 999) / 1000); 400 schedule_timeout((100 * HZ + 999) / 1000);
212 ir->tx->need_boot = 1; 401 if (tx != NULL)
402 tx->need_boot = 1;
213 403
214 ++failures; 404 ++failures;
215 mutex_unlock(&ir->ir_lock); 405 mutex_unlock(&ir->ir_lock);
406 ret = 0;
216 continue; 407 continue;
217 } 408 }
218 409
219 if (kthread_should_stop()) { 410 if (kthread_should_stop()) {
220 mutex_unlock(&ir->ir_lock); 411 mutex_unlock(&ir->ir_lock);
221 return -ENODATA; 412 ret = -ENODATA;
413 break;
222 } 414 }
223 ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf)); 415 ret = i2c_master_recv(rx->c, keybuf, sizeof(keybuf));
224 mutex_unlock(&ir->ir_lock); 416 mutex_unlock(&ir->ir_lock);
@@ -234,12 +426,17 @@ static int add_to_buf(struct IR *ir)
234 426
235 /* key pressed ? */ 427 /* key pressed ? */
236 if (rx->hdpvr_data_fmt) { 428 if (rx->hdpvr_data_fmt) {
237 if (got_data && (keybuf[0] == 0x80)) 429 if (got_data && (keybuf[0] == 0x80)) {
238 return 0; 430 ret = 0;
239 else if (got_data && (keybuf[0] == 0x00)) 431 break;
240 return -ENODATA; 432 } else if (got_data && (keybuf[0] == 0x00)) {
241 } else if ((rx->b[0] & 0x80) == 0) 433 ret = -ENODATA;
242 return got_data ? 0 : -ENODATA; 434 break;
435 }
436 } else if ((rx->b[0] & 0x80) == 0) {
437 ret = got_data ? 0 : -ENODATA;
438 break;
439 }
243 440
244 /* look what we have */ 441 /* look what we have */
245 code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2); 442 code = (((__u16)rx->b[0] & 0x7f) << 6) | (rx->b[1] >> 2);
@@ -248,11 +445,16 @@ static int add_to_buf(struct IR *ir)
248 codes[1] = code & 0xff; 445 codes[1] = code & 0xff;
249 446
250 /* return it */ 447 /* return it */
251 lirc_buffer_write(&rx->buf, codes); 448 lirc_buffer_write(rbuf, codes);
252 ++got_data; 449 ++got_data;
253 } while (!lirc_buffer_full(&rx->buf)); 450 ret = 0;
451 } while (!lirc_buffer_full(rbuf));
254 452
255 return 0; 453 mutex_unlock(&rx->client_lock);
454 if (tx != NULL)
455 put_ir_tx(tx, false);
456 put_ir_rx(rx, false);
457 return ret;
256} 458}
257 459
258/* 460/*
@@ -268,19 +470,19 @@ static int add_to_buf(struct IR *ir)
268static int lirc_thread(void *arg) 470static int lirc_thread(void *arg)
269{ 471{
270 struct IR *ir = arg; 472 struct IR *ir = arg;
271 struct IR_rx *rx = ir->rx; 473 struct lirc_buffer *rbuf = ir->l.rbuf;
272 474
273 dprintk("poll thread started\n"); 475 dprintk("poll thread started\n");
274 476
275 while (!kthread_should_stop()) { 477 while (!kthread_should_stop()) {
276 set_current_state(TASK_INTERRUPTIBLE);
277
278 /* if device not opened, we can sleep half a second */ 478 /* if device not opened, we can sleep half a second */
279 if (!ir->open) { 479 if (atomic_read(&ir->open_count) == 0) {
280 schedule_timeout(HZ/2); 480 schedule_timeout(HZ/2);
281 continue; 481 continue;
282 } 482 }
283 483
484 set_current_state(TASK_INTERRUPTIBLE);
485
284 /* 486 /*
285 * This is ~113*2 + 24 + jitter (2*repeat gap + code length). 487 * This is ~113*2 + 24 + jitter (2*repeat gap + code length).
286 * We use this interval as the chip resets every time you poll 488 * We use this interval as the chip resets every time you poll
@@ -295,7 +497,7 @@ static int lirc_thread(void *arg)
295 if (kthread_should_stop()) 497 if (kthread_should_stop())
296 break; 498 break;
297 if (!add_to_buf(ir)) 499 if (!add_to_buf(ir))
298 wake_up_interruptible(&rx->buf.wait_poll); 500 wake_up_interruptible(&rbuf->wait_poll);
299 } 501 }
300 502
301 dprintk("poll thread ended\n"); 503 dprintk("poll thread ended\n");
@@ -304,34 +506,12 @@ static int lirc_thread(void *arg)
304 506
305static int set_use_inc(void *data) 507static int set_use_inc(void *data)
306{ 508{
307 struct IR *ir = data;
308
309 if (ir->l.owner == NULL || try_module_get(ir->l.owner) == 0)
310 return -ENODEV;
311
312 /* lock bttv in memory while /dev/lirc is in use */
313 /*
314 * this is completely broken code. lirc_unregister_driver()
315 * must be possible even when the device is open
316 */
317 if (ir->rx != NULL)
318 i2c_use_client(ir->rx->c);
319 if (ir->tx != NULL)
320 i2c_use_client(ir->tx->c);
321
322 return 0; 509 return 0;
323} 510}
324 511
325static void set_use_dec(void *data) 512static void set_use_dec(void *data)
326{ 513{
327 struct IR *ir = data; 514 return;
328
329 if (ir->rx)
330 i2c_release_client(ir->rx->c);
331 if (ir->tx)
332 i2c_release_client(ir->tx->c);
333 if (ir->l.owner != NULL)
334 module_put(ir->l.owner);
335} 515}
336 516
337/* safe read of a uint32 (always network byte order) */ 517/* safe read of a uint32 (always network byte order) */
@@ -585,7 +765,7 @@ static int fw_load(struct IR_tx *tx)
585 } 765 }
586 766
587 /* Request codeset data file */ 767 /* Request codeset data file */
588 ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", &tx->c->dev); 768 ret = request_firmware(&fw_entry, "haup-ir-blaster.bin", tx->ir->l.dev);
589 if (ret != 0) { 769 if (ret != 0) {
590 zilog_error("firmware haup-ir-blaster.bin not available " 770 zilog_error("firmware haup-ir-blaster.bin not available "
591 "(%d)\n", ret); 771 "(%d)\n", ret);
@@ -711,59 +891,32 @@ out:
711 return ret; 891 return ret;
712} 892}
713 893
714/* initialise the IR TX device */
715static int tx_init(struct IR_tx *tx)
716{
717 int ret;
718
719 /* Load 'firmware' */
720 ret = fw_load(tx);
721 if (ret != 0)
722 return ret;
723
724 /* Send boot block */
725 ret = send_boot_data(tx);
726 if (ret != 0)
727 return ret;
728 tx->need_boot = 0;
729
730 /* Looks good */
731 return 0;
732}
733
734/* do nothing stub to make LIRC happy */
735static loff_t lseek(struct file *filep, loff_t offset, int orig)
736{
737 return -ESPIPE;
738}
739
740/* copied from lirc_dev */ 894/* copied from lirc_dev */
741static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos) 895static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
742{ 896{
743 struct IR *ir = filep->private_data; 897 struct IR *ir = filep->private_data;
744 struct IR_rx *rx = ir->rx; 898 struct IR_rx *rx;
745 int ret = 0, written = 0; 899 struct lirc_buffer *rbuf = ir->l.rbuf;
900 int ret = 0, written = 0, retries = 0;
901 unsigned int m;
746 DECLARE_WAITQUEUE(wait, current); 902 DECLARE_WAITQUEUE(wait, current);
747 903
748 dprintk("read called\n"); 904 dprintk("read called\n");
749 if (rx == NULL) 905 if (n % rbuf->chunk_size) {
750 return -ENODEV;
751
752 if (mutex_lock_interruptible(&rx->buf_lock))
753 return -ERESTARTSYS;
754
755 if (n % rx->buf.chunk_size) {
756 dprintk("read result = -EINVAL\n"); 906 dprintk("read result = -EINVAL\n");
757 mutex_unlock(&rx->buf_lock);
758 return -EINVAL; 907 return -EINVAL;
759 } 908 }
760 909
910 rx = get_ir_rx(ir);
911 if (rx == NULL)
912 return -ENXIO;
913
761 /* 914 /*
762 * we add ourselves to the task queue before buffer check 915 * we add ourselves to the task queue before buffer check
763 * to avoid losing scan code (in case when queue is awaken somewhere 916 * to avoid losing scan code (in case when queue is awaken somewhere
764 * between while condition checking and scheduling) 917 * between while condition checking and scheduling)
765 */ 918 */
766 add_wait_queue(&rx->buf.wait_poll, &wait); 919 add_wait_queue(&rbuf->wait_poll, &wait);
767 set_current_state(TASK_INTERRUPTIBLE); 920 set_current_state(TASK_INTERRUPTIBLE);
768 921
769 /* 922 /*
@@ -771,7 +924,7 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
771 * mode and 'copy_to_user' is happy, wait for data. 924 * mode and 'copy_to_user' is happy, wait for data.
772 */ 925 */
773 while (written < n && ret == 0) { 926 while (written < n && ret == 0) {
774 if (lirc_buffer_empty(&rx->buf)) { 927 if (lirc_buffer_empty(rbuf)) {
775 /* 928 /*
776 * According to the read(2) man page, 'written' can be 929 * According to the read(2) man page, 'written' can be
777 * returned as less than 'n', instead of blocking 930 * returned as less than 'n', instead of blocking
@@ -791,20 +944,27 @@ static ssize_t read(struct file *filep, char *outbuf, size_t n, loff_t *ppos)
791 schedule(); 944 schedule();
792 set_current_state(TASK_INTERRUPTIBLE); 945 set_current_state(TASK_INTERRUPTIBLE);
793 } else { 946 } else {
794 unsigned char buf[rx->buf.chunk_size]; 947 unsigned char buf[rbuf->chunk_size];
795 lirc_buffer_read(&rx->buf, buf); 948 m = lirc_buffer_read(rbuf, buf);
796 ret = copy_to_user((void *)outbuf+written, buf, 949 if (m == rbuf->chunk_size) {
797 rx->buf.chunk_size); 950 ret = copy_to_user((void *)outbuf+written, buf,
798 written += rx->buf.chunk_size; 951 rbuf->chunk_size);
952 written += rbuf->chunk_size;
953 } else {
954 retries++;
955 }
956 if (retries >= 5) {
957 zilog_error("Buffer read failed!\n");
958 ret = -EIO;
959 }
799 } 960 }
800 } 961 }
801 962
802 remove_wait_queue(&rx->buf.wait_poll, &wait); 963 remove_wait_queue(&rbuf->wait_poll, &wait);
964 put_ir_rx(rx, false);
803 set_current_state(TASK_RUNNING); 965 set_current_state(TASK_RUNNING);
804 mutex_unlock(&rx->buf_lock);
805 966
806 dprintk("read result = %s (%d)\n", 967 dprintk("read result = %d (%s)\n", ret, ret ? "Error" : "OK");
807 ret ? "-EFAULT" : "OK", ret);
808 968
809 return ret ? ret : written; 969 return ret ? ret : written;
810} 970}
@@ -931,17 +1091,27 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
931 loff_t *ppos) 1091 loff_t *ppos)
932{ 1092{
933 struct IR *ir = filep->private_data; 1093 struct IR *ir = filep->private_data;
934 struct IR_tx *tx = ir->tx; 1094 struct IR_tx *tx;
935 size_t i; 1095 size_t i;
936 int failures = 0; 1096 int failures = 0;
937 1097
938 if (tx == NULL)
939 return -ENODEV;
940
941 /* Validate user parameters */ 1098 /* Validate user parameters */
942 if (n % sizeof(int)) 1099 if (n % sizeof(int))
943 return -EINVAL; 1100 return -EINVAL;
944 1101
1102 /* Get a struct IR_tx reference */
1103 tx = get_ir_tx(ir);
1104 if (tx == NULL)
1105 return -ENXIO;
1106
1107 /* Ensure our tx->c i2c_client remains valid for the duration */
1108 mutex_lock(&tx->client_lock);
1109 if (tx->c == NULL) {
1110 mutex_unlock(&tx->client_lock);
1111 put_ir_tx(tx, false);
1112 return -ENXIO;
1113 }
1114
945 /* Lock i2c bus for the duration */ 1115 /* Lock i2c bus for the duration */
946 mutex_lock(&ir->ir_lock); 1116 mutex_lock(&ir->ir_lock);
947 1117
@@ -952,11 +1122,24 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
952 1122
953 if (copy_from_user(&command, buf + i, sizeof(command))) { 1123 if (copy_from_user(&command, buf + i, sizeof(command))) {
954 mutex_unlock(&ir->ir_lock); 1124 mutex_unlock(&ir->ir_lock);
1125 mutex_unlock(&tx->client_lock);
1126 put_ir_tx(tx, false);
955 return -EFAULT; 1127 return -EFAULT;
956 } 1128 }
957 1129
958 /* Send boot data first if required */ 1130 /* Send boot data first if required */
959 if (tx->need_boot == 1) { 1131 if (tx->need_boot == 1) {
1132 /* Make sure we have the 'firmware' loaded, first */
1133 ret = fw_load(tx);
1134 if (ret != 0) {
1135 mutex_unlock(&ir->ir_lock);
1136 mutex_unlock(&tx->client_lock);
1137 put_ir_tx(tx, false);
1138 if (ret != -ENOMEM)
1139 ret = -EIO;
1140 return ret;
1141 }
1142 /* Prep the chip for transmitting codes */
960 ret = send_boot_data(tx); 1143 ret = send_boot_data(tx);
961 if (ret == 0) 1144 if (ret == 0)
962 tx->need_boot = 0; 1145 tx->need_boot = 0;
@@ -968,6 +1151,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
968 (unsigned)command & 0xFFFF); 1151 (unsigned)command & 0xFFFF);
969 if (ret == -EPROTO) { 1152 if (ret == -EPROTO) {
970 mutex_unlock(&ir->ir_lock); 1153 mutex_unlock(&ir->ir_lock);
1154 mutex_unlock(&tx->client_lock);
1155 put_ir_tx(tx, false);
971 return ret; 1156 return ret;
972 } 1157 }
973 } 1158 }
@@ -985,6 +1170,8 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
985 zilog_error("unable to send to the IR chip " 1170 zilog_error("unable to send to the IR chip "
986 "after 3 resets, giving up\n"); 1171 "after 3 resets, giving up\n");
987 mutex_unlock(&ir->ir_lock); 1172 mutex_unlock(&ir->ir_lock);
1173 mutex_unlock(&tx->client_lock);
1174 put_ir_tx(tx, false);
988 return ret; 1175 return ret;
989 } 1176 }
990 set_current_state(TASK_UNINTERRUPTIBLE); 1177 set_current_state(TASK_UNINTERRUPTIBLE);
@@ -998,6 +1185,11 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
998 /* Release i2c bus */ 1185 /* Release i2c bus */
999 mutex_unlock(&ir->ir_lock); 1186 mutex_unlock(&ir->ir_lock);
1000 1187
1188 mutex_unlock(&tx->client_lock);
1189
1190 /* Give back our struct IR_tx reference */
1191 put_ir_tx(tx, false);
1192
1001 /* All looks good */ 1193 /* All looks good */
1002 return n; 1194 return n;
1003} 1195}
@@ -1006,23 +1198,32 @@ static ssize_t write(struct file *filep, const char *buf, size_t n,
1006static unsigned int poll(struct file *filep, poll_table *wait) 1198static unsigned int poll(struct file *filep, poll_table *wait)
1007{ 1199{
1008 struct IR *ir = filep->private_data; 1200 struct IR *ir = filep->private_data;
1009 struct IR_rx *rx = ir->rx; 1201 struct IR_rx *rx;
1202 struct lirc_buffer *rbuf = ir->l.rbuf;
1010 unsigned int ret; 1203 unsigned int ret;
1011 1204
1012 dprintk("poll called\n"); 1205 dprintk("poll called\n");
1013 if (rx == NULL)
1014 return -ENODEV;
1015
1016 mutex_lock(&rx->buf_lock);
1017 1206
1018 poll_wait(filep, &rx->buf.wait_poll, wait); 1207 rx = get_ir_rx(ir);
1208 if (rx == NULL) {
1209 /*
1210 * Revisit this, if our poll function ever reports writeable
1211 * status for Tx
1212 */
1213 dprintk("poll result = POLLERR\n");
1214 return POLLERR;
1215 }
1019 1216
1020 dprintk("poll result = %s\n", 1217 /*
1021 lirc_buffer_empty(&rx->buf) ? "0" : "POLLIN|POLLRDNORM"); 1218 * Add our lirc_buffer's wait_queue to the poll_table. A wake up on
1219 * that buffer's wait queue indicates we may have a new poll status.
1220 */
1221 poll_wait(filep, &rbuf->wait_poll, wait);
1022 1222
1023 ret = lirc_buffer_empty(&rx->buf) ? 0 : (POLLIN|POLLRDNORM); 1223 /* Indicate what ops could happen immediately without blocking */
1224 ret = lirc_buffer_empty(rbuf) ? 0 : (POLLIN|POLLRDNORM);
1024 1225
1025 mutex_unlock(&rx->buf_lock); 1226 dprintk("poll result = %s\n", ret ? "POLLIN|POLLRDNORM" : "none");
1026 return ret; 1227 return ret;
1027} 1228}
1028 1229
@@ -1030,11 +1231,9 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
1030{ 1231{
1031 struct IR *ir = filep->private_data; 1232 struct IR *ir = filep->private_data;
1032 int result; 1233 int result;
1033 unsigned long mode, features = 0; 1234 unsigned long mode, features;
1034 1235
1035 features |= LIRC_CAN_SEND_PULSE; 1236 features = ir->l.features;
1036 if (ir->rx != NULL)
1037 features |= LIRC_CAN_REC_LIRCCODE;
1038 1237
1039 switch (cmd) { 1238 switch (cmd) {
1040 case LIRC_GET_LENGTH: 1239 case LIRC_GET_LENGTH:
@@ -1061,9 +1260,15 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
1061 result = -EINVAL; 1260 result = -EINVAL;
1062 break; 1261 break;
1063 case LIRC_GET_SEND_MODE: 1262 case LIRC_GET_SEND_MODE:
1263 if (!(features&LIRC_CAN_SEND_MASK))
1264 return -ENOSYS;
1265
1064 result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg); 1266 result = put_user(LIRC_MODE_PULSE, (unsigned long *) arg);
1065 break; 1267 break;
1066 case LIRC_SET_SEND_MODE: 1268 case LIRC_SET_SEND_MODE:
1269 if (!(features&LIRC_CAN_SEND_MASK))
1270 return -ENOSYS;
1271
1067 result = get_user(mode, (unsigned long *) arg); 1272 result = get_user(mode, (unsigned long *) arg);
1068 if (!result && mode != LIRC_MODE_PULSE) 1273 if (!result && mode != LIRC_MODE_PULSE)
1069 return -EINVAL; 1274 return -EINVAL;
@@ -1074,13 +1279,24 @@ static long ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
1074 return result; 1279 return result;
1075} 1280}
1076 1281
1077/* ir_devices_lock must be held */ 1282static struct IR *get_ir_device_by_minor(unsigned int minor)
1078static struct IR *find_ir_device_by_minor(unsigned int minor)
1079{ 1283{
1080 if (minor >= MAX_IRCTL_DEVICES) 1284 struct IR *ir;
1081 return NULL; 1285 struct IR *ret = NULL;
1286
1287 mutex_lock(&ir_devices_lock);
1288
1289 if (!list_empty(&ir_devices_list)) {
1290 list_for_each_entry(ir, &ir_devices_list, list) {
1291 if (ir->l.minor == minor) {
1292 ret = get_ir_device(ir, true);
1293 break;
1294 }
1295 }
1296 }
1082 1297
1083 return ir_devices[minor]; 1298 mutex_unlock(&ir_devices_lock);
1299 return ret;
1084} 1300}
1085 1301
1086/* 1302/*
@@ -1090,31 +1306,20 @@ static struct IR *find_ir_device_by_minor(unsigned int minor)
1090static int open(struct inode *node, struct file *filep) 1306static int open(struct inode *node, struct file *filep)
1091{ 1307{
1092 struct IR *ir; 1308 struct IR *ir;
1093 int ret;
1094 unsigned int minor = MINOR(node->i_rdev); 1309 unsigned int minor = MINOR(node->i_rdev);
1095 1310
1096 /* find our IR struct */ 1311 /* find our IR struct */
1097 mutex_lock(&ir_devices_lock); 1312 ir = get_ir_device_by_minor(minor);
1098 ir = find_ir_device_by_minor(minor);
1099 mutex_unlock(&ir_devices_lock);
1100 1313
1101 if (ir == NULL) 1314 if (ir == NULL)
1102 return -ENODEV; 1315 return -ENODEV;
1103 1316
1104 /* increment in use count */ 1317 atomic_inc(&ir->open_count);
1105 mutex_lock(&ir->ir_lock);
1106 ++ir->open;
1107 ret = set_use_inc(ir);
1108 if (ret != 0) {
1109 --ir->open;
1110 mutex_unlock(&ir->ir_lock);
1111 return ret;
1112 }
1113 mutex_unlock(&ir->ir_lock);
1114 1318
1115 /* stash our IR struct */ 1319 /* stash our IR struct */
1116 filep->private_data = ir; 1320 filep->private_data = ir;
1117 1321
1322 nonseekable_open(node, filep);
1118 return 0; 1323 return 0;
1119} 1324}
1120 1325
@@ -1128,22 +1333,12 @@ static int close(struct inode *node, struct file *filep)
1128 return -ENODEV; 1333 return -ENODEV;
1129 } 1334 }
1130 1335
1131 /* decrement in use count */ 1336 atomic_dec(&ir->open_count);
1132 mutex_lock(&ir->ir_lock);
1133 --ir->open;
1134 set_use_dec(ir);
1135 mutex_unlock(&ir->ir_lock);
1136 1337
1338 put_ir_device(ir, false);
1137 return 0; 1339 return 0;
1138} 1340}
1139 1341
1140static struct lirc_driver lirc_template = {
1141 .name = "lirc_zilog",
1142 .set_use_inc = set_use_inc,
1143 .set_use_dec = set_use_dec,
1144 .owner = THIS_MODULE
1145};
1146
1147static int ir_remove(struct i2c_client *client); 1342static int ir_remove(struct i2c_client *client);
1148static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id); 1343static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id);
1149 1344
@@ -1170,7 +1365,7 @@ static struct i2c_driver driver = {
1170 1365
1171static const struct file_operations lirc_fops = { 1366static const struct file_operations lirc_fops = {
1172 .owner = THIS_MODULE, 1367 .owner = THIS_MODULE,
1173 .llseek = lseek, 1368 .llseek = no_llseek,
1174 .read = read, 1369 .read = read,
1175 .write = write, 1370 .write = write,
1176 .poll = poll, 1371 .poll = poll,
@@ -1182,97 +1377,64 @@ static const struct file_operations lirc_fops = {
1182 .release = close 1377 .release = close
1183}; 1378};
1184 1379
1185static void destroy_rx_kthread(struct IR_rx *rx) 1380static struct lirc_driver lirc_template = {
1186{ 1381 .name = "lirc_zilog",
1187 /* end up polling thread */ 1382 .minor = -1,
1188 if (rx != NULL && !IS_ERR_OR_NULL(rx->task)) { 1383 .code_length = 13,
1189 kthread_stop(rx->task); 1384 .buffer_size = BUFLEN / 2,
1190 rx->task = NULL; 1385 .sample_rate = 0, /* tell lirc_dev to not start its own kthread */
1191 } 1386 .chunk_size = 2,
1192} 1387 .set_use_inc = set_use_inc,
1388 .set_use_dec = set_use_dec,
1389 .fops = &lirc_fops,
1390 .owner = THIS_MODULE,
1391};
1193 1392
1194/* ir_devices_lock must be held */ 1393static int ir_remove(struct i2c_client *client)
1195static int add_ir_device(struct IR *ir)
1196{ 1394{
1197 int i; 1395 if (strncmp("ir_tx_z8", client->name, 8) == 0) {
1198 1396 struct IR_tx *tx = i2c_get_clientdata(client);
1199 for (i = 0; i < MAX_IRCTL_DEVICES; i++) 1397 if (tx != NULL) {
1200 if (ir_devices[i] == NULL) { 1398 mutex_lock(&tx->client_lock);
1201 ir_devices[i] = ir; 1399 tx->c = NULL;
1202 break; 1400 mutex_unlock(&tx->client_lock);
1401 put_ir_tx(tx, false);
1203 } 1402 }
1204 1403 } else if (strncmp("ir_rx_z8", client->name, 8) == 0) {
1205 return i == MAX_IRCTL_DEVICES ? -ENOMEM : i; 1404 struct IR_rx *rx = i2c_get_clientdata(client);
1206} 1405 if (rx != NULL) {
1207 1406 mutex_lock(&rx->client_lock);
1208/* ir_devices_lock must be held */ 1407 rx->c = NULL;
1209static void del_ir_device(struct IR *ir) 1408 mutex_unlock(&rx->client_lock);
1210{ 1409 put_ir_rx(rx, false);
1211 int i;
1212
1213 for (i = 0; i < MAX_IRCTL_DEVICES; i++)
1214 if (ir_devices[i] == ir) {
1215 ir_devices[i] = NULL;
1216 break;
1217 } 1410 }
1218}
1219
1220static int ir_remove(struct i2c_client *client)
1221{
1222 struct IR *ir = i2c_get_clientdata(client);
1223
1224 mutex_lock(&ir_devices_lock);
1225
1226 if (ir == NULL) {
1227 /* We destroyed everything when the first client came through */
1228 mutex_unlock(&ir_devices_lock);
1229 return 0;
1230 } 1411 }
1231
1232 /* Good-bye LIRC */
1233 lirc_unregister_driver(ir->l.minor);
1234
1235 /* Good-bye Rx */
1236 destroy_rx_kthread(ir->rx);
1237 if (ir->rx != NULL) {
1238 if (ir->rx->buf.fifo_initialized)
1239 lirc_buffer_free(&ir->rx->buf);
1240 i2c_set_clientdata(ir->rx->c, NULL);
1241 kfree(ir->rx);
1242 }
1243
1244 /* Good-bye Tx */
1245 i2c_set_clientdata(ir->tx->c, NULL);
1246 kfree(ir->tx);
1247
1248 /* Good-bye IR */
1249 del_ir_device(ir);
1250 kfree(ir);
1251
1252 mutex_unlock(&ir_devices_lock);
1253 return 0; 1412 return 0;
1254} 1413}
1255 1414
1256 1415
1257/* ir_devices_lock must be held */ 1416/* ir_devices_lock must be held */
1258static struct IR *find_ir_device_by_adapter(struct i2c_adapter *adapter) 1417static struct IR *get_ir_device_by_adapter(struct i2c_adapter *adapter)
1259{ 1418{
1260 int i; 1419 struct IR *ir;
1261 struct IR *ir = NULL;
1262 1420
1263 for (i = 0; i < MAX_IRCTL_DEVICES; i++) 1421 if (list_empty(&ir_devices_list))
1264 if (ir_devices[i] != NULL && 1422 return NULL;
1265 ir_devices[i]->adapter == adapter) { 1423
1266 ir = ir_devices[i]; 1424 list_for_each_entry(ir, &ir_devices_list, list)
1267 break; 1425 if (ir->adapter == adapter) {
1426 get_ir_device(ir, true);
1427 return ir;
1268 } 1428 }
1269 1429
1270 return ir; 1430 return NULL;
1271} 1431}
1272 1432
1273static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id) 1433static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
1274{ 1434{
1275 struct IR *ir; 1435 struct IR *ir;
1436 struct IR_tx *tx;
1437 struct IR_rx *rx;
1276 struct i2c_adapter *adap = client->adapter; 1438 struct i2c_adapter *adap = client->adapter;
1277 int ret; 1439 int ret;
1278 bool tx_probe = false; 1440 bool tx_probe = false;
@@ -1296,133 +1458,170 @@ static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
1296 mutex_lock(&ir_devices_lock); 1458 mutex_lock(&ir_devices_lock);
1297 1459
1298 /* Use a single struct IR instance for both the Rx and Tx functions */ 1460 /* Use a single struct IR instance for both the Rx and Tx functions */
1299 ir = find_ir_device_by_adapter(adap); 1461 ir = get_ir_device_by_adapter(adap);
1300 if (ir == NULL) { 1462 if (ir == NULL) {
1301 ir = kzalloc(sizeof(struct IR), GFP_KERNEL); 1463 ir = kzalloc(sizeof(struct IR), GFP_KERNEL);
1302 if (ir == NULL) { 1464 if (ir == NULL) {
1303 ret = -ENOMEM; 1465 ret = -ENOMEM;
1304 goto out_no_ir; 1466 goto out_no_ir;
1305 } 1467 }
1468 kref_init(&ir->ref);
1469
1306 /* store for use in ir_probe() again, and open() later on */ 1470 /* store for use in ir_probe() again, and open() later on */
1307 ret = add_ir_device(ir); 1471 INIT_LIST_HEAD(&ir->list);
1308 if (ret) 1472 list_add_tail(&ir->list, &ir_devices_list);
1309 goto out_free_ir;
1310 1473
1311 ir->adapter = adap; 1474 ir->adapter = adap;
1312 mutex_init(&ir->ir_lock); 1475 mutex_init(&ir->ir_lock);
1476 atomic_set(&ir->open_count, 0);
1477 spin_lock_init(&ir->tx_ref_lock);
1478 spin_lock_init(&ir->rx_ref_lock);
1313 1479
1314 /* set lirc_dev stuff */ 1480 /* set lirc_dev stuff */
1315 memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver)); 1481 memcpy(&ir->l, &lirc_template, sizeof(struct lirc_driver));
1316 ir->l.minor = minor; /* module option */ 1482 /*
1317 ir->l.code_length = 13; 1483 * FIXME this is a pointer reference to us, but no refcount.
1318 ir->l.rbuf = NULL; 1484 *
1319 ir->l.fops = &lirc_fops; 1485 * This OK for now, since lirc_dev currently won't touch this
1320 ir->l.data = ir; 1486 * buffer as we provide our own lirc_fops.
1321 ir->l.dev = &adap->dev; 1487 *
1322 ir->l.sample_rate = 0; 1488 * Currently our own lirc_fops rely on this ir->l.rbuf pointer
1489 */
1490 ir->l.rbuf = &ir->rbuf;
1491 ir->l.dev = &adap->dev;
1492 ret = lirc_buffer_init(ir->l.rbuf,
1493 ir->l.chunk_size, ir->l.buffer_size);
1494 if (ret)
1495 goto out_put_ir;
1323 } 1496 }
1324 1497
1325 if (tx_probe) { 1498 if (tx_probe) {
1499 /* Get the IR_rx instance for later, if already allocated */
1500 rx = get_ir_rx(ir);
1501
1326 /* Set up a struct IR_tx instance */ 1502 /* Set up a struct IR_tx instance */
1327 ir->tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL); 1503 tx = kzalloc(sizeof(struct IR_tx), GFP_KERNEL);
1328 if (ir->tx == NULL) { 1504 if (tx == NULL) {
1329 ret = -ENOMEM; 1505 ret = -ENOMEM;
1330 goto out_free_xx; 1506 goto out_put_xx;
1331 } 1507 }
1332 1508 kref_init(&tx->ref);
1333 ir->tx->c = client; 1509 ir->tx = tx;
1334 ir->tx->need_boot = 1; 1510
1335 ir->tx->post_tx_ready_poll = 1511 ir->l.features |= LIRC_CAN_SEND_PULSE;
1512 mutex_init(&tx->client_lock);
1513 tx->c = client;
1514 tx->need_boot = 1;
1515 tx->post_tx_ready_poll =
1336 (id->driver_data & ID_FLAG_HDPVR) ? false : true; 1516 (id->driver_data & ID_FLAG_HDPVR) ? false : true;
1517
1518 /* An ir ref goes to the struct IR_tx instance */
1519 tx->ir = get_ir_device(ir, true);
1520
1521 /* A tx ref goes to the i2c_client */
1522 i2c_set_clientdata(client, get_ir_tx(ir));
1523
1524 /*
1525 * Load the 'firmware'. We do this before registering with
1526 * lirc_dev, so the first firmware load attempt does not happen
1527 * after a open() or write() call on the device.
1528 *
1529 * Failure here is not deemed catastrophic, so the receiver will
1530 * still be usable. Firmware load will be retried in write(),
1531 * if it is needed.
1532 */
1533 fw_load(tx);
1534
1535 /* Proceed only if the Rx client is also ready or not needed */
1536 if (rx == NULL && !tx_only) {
1537 zilog_info("probe of IR Tx on %s (i2c-%d) done. Waiting"
1538 " on IR Rx.\n", adap->name, adap->nr);
1539 goto out_ok;
1540 }
1337 } else { 1541 } else {
1542 /* Get the IR_tx instance for later, if already allocated */
1543 tx = get_ir_tx(ir);
1544
1338 /* Set up a struct IR_rx instance */ 1545 /* Set up a struct IR_rx instance */
1339 ir->rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL); 1546 rx = kzalloc(sizeof(struct IR_rx), GFP_KERNEL);
1340 if (ir->rx == NULL) { 1547 if (rx == NULL) {
1341 ret = -ENOMEM; 1548 ret = -ENOMEM;
1342 goto out_free_xx; 1549 goto out_put_xx;
1343 } 1550 }
1551 kref_init(&rx->ref);
1552 ir->rx = rx;
1344 1553
1345 ret = lirc_buffer_init(&ir->rx->buf, 2, BUFLEN / 2); 1554 ir->l.features |= LIRC_CAN_REC_LIRCCODE;
1346 if (ret) 1555 mutex_init(&rx->client_lock);
1347 goto out_free_xx; 1556 rx->c = client;
1348 1557 rx->hdpvr_data_fmt =
1349 mutex_init(&ir->rx->buf_lock);
1350 ir->rx->c = client;
1351 ir->rx->hdpvr_data_fmt =
1352 (id->driver_data & ID_FLAG_HDPVR) ? true : false; 1558 (id->driver_data & ID_FLAG_HDPVR) ? true : false;
1353 1559
1354 /* set lirc_dev stuff */ 1560 /* An ir ref goes to the struct IR_rx instance */
1355 ir->l.rbuf = &ir->rx->buf; 1561 rx->ir = get_ir_device(ir, true);
1356 }
1357
1358 i2c_set_clientdata(client, ir);
1359 1562
1360 /* Proceed only if we have the required Tx and Rx clients ready to go */ 1563 /* An rx ref goes to the i2c_client */
1361 if (ir->tx == NULL || 1564 i2c_set_clientdata(client, get_ir_rx(ir));
1362 (ir->rx == NULL && !tx_only)) {
1363 zilog_info("probe of IR %s on %s (i2c-%d) done. Waiting on "
1364 "IR %s.\n", tx_probe ? "Tx" : "Rx", adap->name,
1365 adap->nr, tx_probe ? "Rx" : "Tx");
1366 goto out_ok;
1367 }
1368 1565
1369 /* initialise RX device */ 1566 /*
1370 if (ir->rx != NULL) { 1567 * Start the polling thread.
1371 /* try to fire up polling thread */ 1568 * It will only perform an empty loop around schedule_timeout()
1372 ir->rx->task = kthread_run(lirc_thread, ir, 1569 * until we register with lirc_dev and the first user open()
1373 "zilog-rx-i2c-%d", adap->nr); 1570 */
1374 if (IS_ERR(ir->rx->task)) { 1571 /* An ir ref goes to the new rx polling kthread */
1375 ret = PTR_ERR(ir->rx->task); 1572 rx->task = kthread_run(lirc_thread, get_ir_device(ir, true),
1573 "zilog-rx-i2c-%d", adap->nr);
1574 if (IS_ERR(rx->task)) {
1575 ret = PTR_ERR(rx->task);
1376 zilog_error("%s: could not start IR Rx polling thread" 1576 zilog_error("%s: could not start IR Rx polling thread"
1377 "\n", __func__); 1577 "\n", __func__);
1378 goto out_free_xx; 1578 /* Failed kthread, so put back the ir ref */
1579 put_ir_device(ir, true);
1580 /* Failure exit, so put back rx ref from i2c_client */
1581 i2c_set_clientdata(client, NULL);
1582 put_ir_rx(rx, true);
1583 ir->l.features &= ~LIRC_CAN_REC_LIRCCODE;
1584 goto out_put_xx;
1585 }
1586
1587 /* Proceed only if the Tx client is also ready */
1588 if (tx == NULL) {
1589 zilog_info("probe of IR Rx on %s (i2c-%d) done. Waiting"
1590 " on IR Tx.\n", adap->name, adap->nr);
1591 goto out_ok;
1379 } 1592 }
1380 } 1593 }
1381 1594
1382 /* register with lirc */ 1595 /* register with lirc */
1596 ir->l.minor = minor; /* module option: user requested minor number */
1383 ir->l.minor = lirc_register_driver(&ir->l); 1597 ir->l.minor = lirc_register_driver(&ir->l);
1384 if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) { 1598 if (ir->l.minor < 0 || ir->l.minor >= MAX_IRCTL_DEVICES) {
1385 zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n", 1599 zilog_error("%s: \"minor\" must be between 0 and %d (%d)!\n",
1386 __func__, MAX_IRCTL_DEVICES-1, ir->l.minor); 1600 __func__, MAX_IRCTL_DEVICES-1, ir->l.minor);
1387 ret = -EBADRQC; 1601 ret = -EBADRQC;
1388 goto out_free_thread; 1602 goto out_put_xx;
1389 } 1603 }
1604 zilog_info("IR unit on %s (i2c-%d) registered as lirc%d and ready\n",
1605 adap->name, adap->nr, ir->l.minor);
1390 1606
1391 /*
1392 * if we have the tx device, load the 'firmware'. We do this
1393 * after registering with lirc as otherwise hotplug seems to take
1394 * 10s to create the lirc device.
1395 */
1396 ret = tx_init(ir->tx);
1397 if (ret != 0)
1398 goto out_unregister;
1399
1400 zilog_info("probe of IR %s on %s (i2c-%d) done. IR unit ready.\n",
1401 tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
1402out_ok: 1607out_ok:
1608 if (rx != NULL)
1609 put_ir_rx(rx, true);
1610 if (tx != NULL)
1611 put_ir_tx(tx, true);
1612 put_ir_device(ir, true);
1613 zilog_info("probe of IR %s on %s (i2c-%d) done\n",
1614 tx_probe ? "Tx" : "Rx", adap->name, adap->nr);
1403 mutex_unlock(&ir_devices_lock); 1615 mutex_unlock(&ir_devices_lock);
1404 return 0; 1616 return 0;
1405 1617
1406out_unregister: 1618out_put_xx:
1407 lirc_unregister_driver(ir->l.minor); 1619 if (rx != NULL)
1408out_free_thread: 1620 put_ir_rx(rx, true);
1409 destroy_rx_kthread(ir->rx); 1621 if (tx != NULL)
1410out_free_xx: 1622 put_ir_tx(tx, true);
1411 if (ir->rx != NULL) { 1623out_put_ir:
1412 if (ir->rx->buf.fifo_initialized) 1624 put_ir_device(ir, true);
1413 lirc_buffer_free(&ir->rx->buf);
1414 if (ir->rx->c != NULL)
1415 i2c_set_clientdata(ir->rx->c, NULL);
1416 kfree(ir->rx);
1417 }
1418 if (ir->tx != NULL) {
1419 if (ir->tx->c != NULL)
1420 i2c_set_clientdata(ir->tx->c, NULL);
1421 kfree(ir->tx);
1422 }
1423out_free_ir:
1424 del_ir_device(ir);
1425 kfree(ir);
1426out_no_ir: 1625out_no_ir:
1427 zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n", 1626 zilog_error("%s: probing IR %s on %s (i2c-%d) failed with %d\n",
1428 __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr, 1627 __func__, tx_probe ? "Tx" : "Rx", adap->name, adap->nr,
@@ -1438,7 +1637,6 @@ static int __init zilog_init(void)
1438 zilog_notify("Zilog/Hauppauge IR driver initializing\n"); 1637 zilog_notify("Zilog/Hauppauge IR driver initializing\n");
1439 1638
1440 mutex_init(&tx_data_lock); 1639 mutex_init(&tx_data_lock);
1441 mutex_init(&ir_devices_lock);
1442 1640
1443 request_module("firmware_class"); 1641 request_module("firmware_class");
1444 1642
diff --git a/drivers/staging/se401/Kconfig b/drivers/staging/se401/Kconfig
deleted file mode 100644
index b7f8222ad21b..000000000000
--- a/drivers/staging/se401/Kconfig
+++ /dev/null
@@ -1,13 +0,0 @@
1config USB_SE401
2 tristate "USB SE401 Camera support (DEPRECATED)"
3 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB
4 ---help---
5 Say Y here if you want to connect this type of camera to your
6 computer's USB port. See <file:Documentation/video4linux/se401.txt>
7 for more information and for a list of supported cameras.
8
9 This driver uses the deprecated V4L1 API and will be removed in
10 2.6.39, unless someone converts it to the V4L2 API.
11
12 To compile this driver as a module, choose M here: the
13 module will be called se401.
diff --git a/drivers/staging/se401/Makefile b/drivers/staging/se401/Makefile
deleted file mode 100644
index b465d49783af..000000000000
--- a/drivers/staging/se401/Makefile
+++ /dev/null
@@ -1 +0,0 @@
1obj-$(CONFIG_USB_SE401) += se401.o
diff --git a/drivers/staging/se401/TODO b/drivers/staging/se401/TODO
deleted file mode 100644
index 3b2c03836286..000000000000
--- a/drivers/staging/se401/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1This is an obsolete driver for some old webcams that still use V4L1 API.
2As V4L1 support is being removed from kernel, if nobody take care on it,
3the driver will be removed for 2.6.39.
4
5Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/se401/se401.c b/drivers/staging/se401/se401.c
deleted file mode 100644
index 41360d7c3e96..000000000000
--- a/drivers/staging/se401/se401.c
+++ /dev/null
@@ -1,1492 +0,0 @@
1/*
2 * Endpoints (formerly known as AOX) se401 USB Camera Driver
3 *
4 * Copyright (c) 2000 Jeroen B. Vreeken (pe1rxq@amsat.org)
5 *
6 * Still somewhat based on the Linux ov511 driver.
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * 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 Foundation,
20 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 *
23 * Thanks to Endpoints Inc. (www.endpoints.com) for making documentation on
24 * their chipset available and supporting me while writing this driver.
25 * - Jeroen Vreeken
26 */
27
28static const char version[] = "0.24";
29
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/vmalloc.h>
33#include <linux/slab.h>
34#include <linux/pagemap.h>
35#include <linux/usb.h>
36#include "se401.h"
37
38static int flickerless;
39static int video_nr = -1;
40
41static struct usb_device_id device_table[] = {
42 { USB_DEVICE(0x03e8, 0x0004) },/* Endpoints/Aox SE401 */
43 { USB_DEVICE(0x0471, 0x030b) },/* Philips PCVC665K */
44 { USB_DEVICE(0x047d, 0x5001) },/* Kensington 67014 */
45 { USB_DEVICE(0x047d, 0x5002) },/* Kensington 6701(5/7) */
46 { USB_DEVICE(0x047d, 0x5003) },/* Kensington 67016 */
47 { }
48};
49
50MODULE_DEVICE_TABLE(usb, device_table);
51
52MODULE_AUTHOR("Jeroen Vreeken <pe1rxq@amsat.org>");
53MODULE_DESCRIPTION("SE401 USB Camera Driver");
54MODULE_LICENSE("GPL");
55module_param(flickerless, int, 0);
56MODULE_PARM_DESC(flickerless,
57 "Net frequency to adjust exposure time to (0/50/60)");
58module_param(video_nr, int, 0);
59
60static struct usb_driver se401_driver;
61
62
63/**********************************************************************
64 *
65 * Memory management
66 *
67 **********************************************************************/
68static void *rvmalloc(unsigned long size)
69{
70 void *mem;
71 unsigned long adr;
72
73 size = PAGE_ALIGN(size);
74 mem = vmalloc_32(size);
75 if (!mem)
76 return NULL;
77
78 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
79 adr = (unsigned long) mem;
80 while (size > 0) {
81 SetPageReserved(vmalloc_to_page((void *)adr));
82 adr += PAGE_SIZE;
83 size -= PAGE_SIZE;
84 }
85
86 return mem;
87}
88
89static void rvfree(void *mem, unsigned long size)
90{
91 unsigned long adr;
92
93 if (!mem)
94 return;
95
96 adr = (unsigned long) mem;
97 while ((long) size > 0) {
98 ClearPageReserved(vmalloc_to_page((void *)adr));
99 adr += PAGE_SIZE;
100 size -= PAGE_SIZE;
101 }
102 vfree(mem);
103}
104
105
106
107/****************************************************************************
108 *
109 * se401 register read/write functions
110 *
111 ***************************************************************************/
112
113static int se401_sndctrl(int set, struct usb_se401 *se401, unsigned short req,
114 unsigned short value, unsigned char *cp, int size)
115{
116 return usb_control_msg(
117 se401->dev,
118 set ? usb_sndctrlpipe(se401->dev, 0) : usb_rcvctrlpipe(se401->dev, 0),
119 req,
120 (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
121 value,
122 0,
123 cp,
124 size,
125 1000
126 );
127}
128
129static int se401_set_feature(struct usb_se401 *se401, unsigned short selector,
130 unsigned short param)
131{
132 /* specs say that the selector (address) should go in the value field
133 and the param in index, but in the logs of the windows driver they do
134 this the other way around...
135 */
136 return usb_control_msg(
137 se401->dev,
138 usb_sndctrlpipe(se401->dev, 0),
139 SE401_REQ_SET_EXT_FEATURE,
140 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
141 param,
142 selector,
143 NULL,
144 0,
145 1000
146 );
147}
148
149static unsigned short se401_get_feature(struct usb_se401 *se401,
150 unsigned short selector)
151{
152 /* For 'set' the selecetor should be in index, not sure if the spec is
153 wrong here to....
154 */
155 unsigned char cp[2];
156 usb_control_msg(
157 se401->dev,
158 usb_rcvctrlpipe(se401->dev, 0),
159 SE401_REQ_GET_EXT_FEATURE,
160 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
161 0,
162 selector,
163 cp,
164 2,
165 1000
166 );
167 return cp[0]+cp[1]*256;
168}
169
170/****************************************************************************
171 *
172 * Camera control
173 *
174 ***************************************************************************/
175
176
177static int se401_send_pict(struct usb_se401 *se401)
178{
179 /* integration time low */
180 se401_set_feature(se401, HV7131_REG_TITL, se401->expose_l);
181 /* integration time mid */
182 se401_set_feature(se401, HV7131_REG_TITM, se401->expose_m);
183 /* integration time mid */
184 se401_set_feature(se401, HV7131_REG_TITU, se401->expose_h);
185 /* reset level value */
186 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
187 /* red color gain */
188 se401_set_feature(se401, HV7131_REG_ARCG, se401->rgain);
189 /* green color gain */
190 se401_set_feature(se401, HV7131_REG_AGCG, se401->ggain);
191 /* blue color gain */
192 se401_set_feature(se401, HV7131_REG_ABCG, se401->bgain);
193
194 return 0;
195}
196
197static void se401_set_exposure(struct usb_se401 *se401, int brightness)
198{
199 int integration = brightness << 5;
200
201 if (flickerless == 50)
202 integration = integration-integration % 106667;
203 if (flickerless == 60)
204 integration = integration-integration % 88889;
205 se401->brightness = integration >> 5;
206 se401->expose_h = (integration >> 16) & 0xff;
207 se401->expose_m = (integration >> 8) & 0xff;
208 se401->expose_l = integration & 0xff;
209}
210
211static int se401_get_pict(struct usb_se401 *se401, struct video_picture *p)
212{
213 p->brightness = se401->brightness;
214 if (se401->enhance)
215 p->whiteness = 32768;
216 else
217 p->whiteness = 0;
218
219 p->colour = 65535;
220 p->contrast = 65535;
221 p->hue = se401->rgain << 10;
222 p->palette = se401->palette;
223 p->depth = 3; /* rgb24 */
224 return 0;
225}
226
227
228static int se401_set_pict(struct usb_se401 *se401, struct video_picture *p)
229{
230 if (p->palette != VIDEO_PALETTE_RGB24)
231 return 1;
232 se401->palette = p->palette;
233 if (p->hue != se401->hue) {
234 se401->rgain = p->hue >> 10;
235 se401->bgain = 0x40-(p->hue >> 10);
236 se401->hue = p->hue;
237 }
238 if (p->brightness != se401->brightness)
239 se401_set_exposure(se401, p->brightness);
240
241 if (p->whiteness >= 32768)
242 se401->enhance = 1;
243 else
244 se401->enhance = 0;
245 se401_send_pict(se401);
246 se401_send_pict(se401);
247 return 0;
248}
249
250/*
251 Hyundai have some really nice docs about this and other sensor related
252 stuff on their homepage: www.hei.co.kr
253*/
254static void se401_auto_resetlevel(struct usb_se401 *se401)
255{
256 unsigned int ahrc, alrc;
257 int oldreset = se401->resetlevel;
258
259 /* For some reason this normally read-only register doesn't get reset
260 to zero after reading them just once...
261 */
262 se401_get_feature(se401, HV7131_REG_HIREFNOH);
263 se401_get_feature(se401, HV7131_REG_HIREFNOL);
264 se401_get_feature(se401, HV7131_REG_LOREFNOH);
265 se401_get_feature(se401, HV7131_REG_LOREFNOL);
266 ahrc = 256*se401_get_feature(se401, HV7131_REG_HIREFNOH) +
267 se401_get_feature(se401, HV7131_REG_HIREFNOL);
268 alrc = 256*se401_get_feature(se401, HV7131_REG_LOREFNOH) +
269 se401_get_feature(se401, HV7131_REG_LOREFNOL);
270
271 /* Not an exact science, but it seems to work pretty well... */
272 if (alrc > 10) {
273 while (alrc >= 10 && se401->resetlevel < 63) {
274 se401->resetlevel++;
275 alrc /= 2;
276 }
277 } else if (ahrc > 20) {
278 while (ahrc >= 20 && se401->resetlevel > 0) {
279 se401->resetlevel--;
280 ahrc /= 2;
281 }
282 }
283 if (se401->resetlevel != oldreset)
284 se401_set_feature(se401, HV7131_REG_ARLV, se401->resetlevel);
285
286 return;
287}
288
289/* irq handler for snapshot button */
290static void se401_button_irq(struct urb *urb)
291{
292 struct usb_se401 *se401 = urb->context;
293 int status;
294
295 if (!se401->dev) {
296 dev_info(&urb->dev->dev, "device vapourished\n");
297 return;
298 }
299
300 switch (urb->status) {
301 case 0:
302 /* success */
303 break;
304 case -ECONNRESET:
305 case -ENOENT:
306 case -ESHUTDOWN:
307 /* this urb is terminated, clean up */
308 dbg("%s - urb shutting down with status: %d",
309 __func__, urb->status);
310 return;
311 default:
312 dbg("%s - nonzero urb status received: %d",
313 __func__, urb->status);
314 goto exit;
315 }
316
317 if (urb->actual_length >= 2)
318 if (se401->button)
319 se401->buttonpressed = 1;
320exit:
321 status = usb_submit_urb(urb, GFP_ATOMIC);
322 if (status)
323 err("%s - usb_submit_urb failed with result %d",
324 __func__, status);
325}
326
327static void se401_video_irq(struct urb *urb)
328{
329 struct usb_se401 *se401 = urb->context;
330 int length = urb->actual_length;
331
332 /* ohoh... */
333 if (!se401->streaming)
334 return;
335
336 if (!se401->dev) {
337 dev_info(&urb->dev->dev, "device vapourished\n");
338 return;
339 }
340
341 /* 0 sized packets happen if we are to fast, but sometimes the camera
342 keeps sending them forever...
343 */
344 if (length && !urb->status) {
345 se401->nullpackets = 0;
346 switch (se401->scratch[se401->scratch_next].state) {
347 case BUFFER_READY:
348 case BUFFER_BUSY:
349 se401->dropped++;
350 break;
351 case BUFFER_UNUSED:
352 memcpy(se401->scratch[se401->scratch_next].data,
353 (unsigned char *)urb->transfer_buffer, length);
354 se401->scratch[se401->scratch_next].state
355 = BUFFER_READY;
356 se401->scratch[se401->scratch_next].offset
357 = se401->bayeroffset;
358 se401->scratch[se401->scratch_next].length = length;
359 if (waitqueue_active(&se401->wq))
360 wake_up_interruptible(&se401->wq);
361 se401->scratch_overflow = 0;
362 se401->scratch_next++;
363 if (se401->scratch_next >= SE401_NUMSCRATCH)
364 se401->scratch_next = 0;
365 break;
366 }
367 se401->bayeroffset += length;
368 if (se401->bayeroffset >= se401->cheight * se401->cwidth)
369 se401->bayeroffset = 0;
370 } else {
371 se401->nullpackets++;
372 if (se401->nullpackets > SE401_MAX_NULLPACKETS)
373 if (waitqueue_active(&se401->wq))
374 wake_up_interruptible(&se401->wq);
375 }
376
377 /* Resubmit urb for new data */
378 urb->status = 0;
379 urb->dev = se401->dev;
380 if (usb_submit_urb(urb, GFP_KERNEL))
381 dev_info(&urb->dev->dev, "urb burned down\n");
382 return;
383}
384
385static void se401_send_size(struct usb_se401 *se401, int width, int height)
386{
387 int i = 0;
388 int mode = 0x03; /* No compression */
389 int sendheight = height;
390 int sendwidth = width;
391
392 /* JangGu compression can only be used with the camera supported sizes,
393 but bayer seems to work with any size that fits on the sensor.
394 We check if we can use compression with the current size with either
395 4 or 16 times subcapturing, if not we use uncompressed bayer data
396 but this will result in cutouts of the maximum size....
397 */
398 while (i < se401->sizes && !(se401->width[i] == width &&
399 se401->height[i] == height))
400 i++;
401 while (i < se401->sizes) {
402 if (se401->width[i] == width * 2 &&
403 se401->height[i] == height * 2) {
404 sendheight = se401->height[i];
405 sendwidth = se401->width[i];
406 mode = 0x40;
407 }
408 if (se401->width[i] == width * 4 &&
409 se401->height[i] == height * 4) {
410 sendheight = se401->height[i];
411 sendwidth = se401->width[i];
412 mode = 0x42;
413 }
414 i++;
415 }
416
417 se401_sndctrl(1, se401, SE401_REQ_SET_WIDTH, sendwidth, NULL, 0);
418 se401_sndctrl(1, se401, SE401_REQ_SET_HEIGHT, sendheight, NULL, 0);
419 se401_set_feature(se401, SE401_OPERATINGMODE, mode);
420
421 if (mode == 0x03)
422 se401->format = FMT_BAYER;
423 else
424 se401->format = FMT_JANGGU;
425}
426
427/*
428 In this function se401_send_pict is called several times,
429 for some reason (depending on the state of the sensor and the phase of
430 the moon :) doing this only in either place doesn't always work...
431*/
432static int se401_start_stream(struct usb_se401 *se401)
433{
434 struct urb *urb;
435 int err = 0, i;
436 se401->streaming = 1;
437
438 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
439 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
440
441 /* Set picture settings */
442 /* windowed + pix intg */
443 se401_set_feature(se401, HV7131_REG_MODE_B, 0x05);
444 se401_send_pict(se401);
445
446 se401_send_size(se401, se401->cwidth, se401->cheight);
447
448 se401_sndctrl(1, se401, SE401_REQ_START_CONTINUOUS_CAPTURE,
449 0, NULL, 0);
450
451 /* Do some memory allocation */
452 for (i = 0; i < SE401_NUMFRAMES; i++) {
453 se401->frame[i].data = se401->fbuf + i * se401->maxframesize;
454 se401->frame[i].curpix = 0;
455 }
456 for (i = 0; i < SE401_NUMSBUF; i++) {
457 se401->sbuf[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
458 if (!se401->sbuf[i].data) {
459 for (i = i - 1; i >= 0; i--) {
460 kfree(se401->sbuf[i].data);
461 se401->sbuf[i].data = NULL;
462 }
463 return -ENOMEM;
464 }
465 }
466
467 se401->bayeroffset = 0;
468 se401->scratch_next = 0;
469 se401->scratch_use = 0;
470 se401->scratch_overflow = 0;
471 for (i = 0; i < SE401_NUMSCRATCH; i++) {
472 se401->scratch[i].data = kmalloc(SE401_PACKETSIZE, GFP_KERNEL);
473 if (!se401->scratch[i].data) {
474 for (i = i - 1; i >= 0; i--) {
475 kfree(se401->scratch[i].data);
476 se401->scratch[i].data = NULL;
477 }
478 goto nomem_sbuf;
479 }
480 se401->scratch[i].state = BUFFER_UNUSED;
481 }
482
483 for (i = 0; i < SE401_NUMSBUF; i++) {
484 urb = usb_alloc_urb(0, GFP_KERNEL);
485 if (!urb) {
486 for (i = i - 1; i >= 0; i--) {
487 usb_kill_urb(se401->urb[i]);
488 usb_free_urb(se401->urb[i]);
489 se401->urb[i] = NULL;
490 }
491 goto nomem_scratch;
492 }
493
494 usb_fill_bulk_urb(urb, se401->dev,
495 usb_rcvbulkpipe(se401->dev, SE401_VIDEO_ENDPOINT),
496 se401->sbuf[i].data, SE401_PACKETSIZE,
497 se401_video_irq,
498 se401);
499
500 se401->urb[i] = urb;
501
502 err = usb_submit_urb(se401->urb[i], GFP_KERNEL);
503 if (err)
504 err("urb burned down");
505 }
506
507 se401->framecount = 0;
508
509 return 0;
510
511 nomem_scratch:
512 for (i = 0; i < SE401_NUMSCRATCH; i++) {
513 kfree(se401->scratch[i].data);
514 se401->scratch[i].data = NULL;
515 }
516 nomem_sbuf:
517 for (i = 0; i < SE401_NUMSBUF; i++) {
518 kfree(se401->sbuf[i].data);
519 se401->sbuf[i].data = NULL;
520 }
521 return -ENOMEM;
522}
523
524static int se401_stop_stream(struct usb_se401 *se401)
525{
526 int i;
527
528 if (!se401->streaming || !se401->dev)
529 return 1;
530
531 se401->streaming = 0;
532
533 se401_sndctrl(1, se401, SE401_REQ_STOP_CONTINUOUS_CAPTURE, 0, NULL, 0);
534
535 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
536 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
537
538 for (i = 0; i < SE401_NUMSBUF; i++)
539 if (se401->urb[i]) {
540 usb_kill_urb(se401->urb[i]);
541 usb_free_urb(se401->urb[i]);
542 se401->urb[i] = NULL;
543 kfree(se401->sbuf[i].data);
544 }
545 for (i = 0; i < SE401_NUMSCRATCH; i++) {
546 kfree(se401->scratch[i].data);
547 se401->scratch[i].data = NULL;
548 }
549
550 return 0;
551}
552
553static int se401_set_size(struct usb_se401 *se401, int width, int height)
554{
555 int wasstreaming = se401->streaming;
556 /* Check to see if we need to change */
557 if (se401->cwidth == width && se401->cheight == height)
558 return 0;
559
560 /* Check for a valid mode */
561 if (!width || !height)
562 return 1;
563 if ((width & 1) || (height & 1))
564 return 1;
565 if (width > se401->width[se401->sizes-1])
566 return 1;
567 if (height > se401->height[se401->sizes-1])
568 return 1;
569
570 /* Stop a current stream and start it again at the new size */
571 if (wasstreaming)
572 se401_stop_stream(se401);
573 se401->cwidth = width;
574 se401->cheight = height;
575 if (wasstreaming)
576 se401_start_stream(se401);
577 return 0;
578}
579
580
581/****************************************************************************
582 *
583 * Video Decoding
584 *
585 ***************************************************************************/
586
587/*
588 This shouldn't really be done in a v4l driver....
589 But it does make the image look a lot more usable.
590 Basically it lifts the dark pixels more than the light pixels.
591*/
592static inline void enhance_picture(unsigned char *frame, int len)
593{
594 while (len--) {
595 *frame = (((*frame^255)*(*frame^255))/255)^255;
596 frame++;
597 }
598}
599
600static inline void decode_JangGu_integrate(struct usb_se401 *se401, int data)
601{
602 struct se401_frame *frame = &se401->frame[se401->curframe];
603 int linelength = se401->cwidth * 3;
604
605 if (frame->curlinepix >= linelength) {
606 frame->curlinepix = 0;
607 frame->curline += linelength;
608 }
609
610 /* First three are absolute, all others relative.
611 * Format is rgb from right to left (mirrorred image),
612 * we flip it to get bgr from left to right. */
613 if (frame->curlinepix < 3)
614 *(frame->curline-frame->curlinepix) = 1 + data * 4;
615 else
616 *(frame->curline-frame->curlinepix) =
617 *(frame->curline-frame->curlinepix + 3) + data * 4;
618 frame->curlinepix++;
619}
620
621static inline void decode_JangGu_vlc(struct usb_se401 *se401,
622 unsigned char *data, int bit_exp, int packetlength)
623{
624 int pos = 0;
625 int vlc_cod = 0;
626 int vlc_size = 0;
627 int vlc_data = 0;
628 int bit_cur;
629 int bit;
630 data += 4;
631 while (pos < packetlength) {
632 bit_cur = 8;
633 while (bit_cur && bit_exp) {
634 bit = ((*data) >> (bit_cur-1))&1;
635 if (!vlc_cod) {
636 if (bit) {
637 vlc_size++;
638 } else {
639 if (!vlc_size)
640 decode_JangGu_integrate(se401, 0);
641 else {
642 vlc_cod = 2;
643 vlc_data = 0;
644 }
645 }
646 } else {
647 if (vlc_cod == 2) {
648 if (!bit)
649 vlc_data = -(1 << vlc_size) + 1;
650 vlc_cod--;
651 }
652 vlc_size--;
653 vlc_data += bit << vlc_size;
654 if (!vlc_size) {
655 decode_JangGu_integrate(se401, vlc_data);
656 vlc_cod = 0;
657 }
658 }
659 bit_cur--;
660 bit_exp--;
661 }
662 pos++;
663 data++;
664 }
665}
666
667static inline void decode_JangGu(struct usb_se401 *se401,
668 struct se401_scratch *buffer)
669{
670 unsigned char *data = buffer->data;
671 int len = buffer->length;
672 int bit_exp = 0, pix_exp = 0, frameinfo = 0, packetlength = 0, size;
673 int datapos = 0;
674
675 /* New image? */
676 if (!se401->frame[se401->curframe].curpix) {
677 se401->frame[se401->curframe].curlinepix = 0;
678 se401->frame[se401->curframe].curline =
679 se401->frame[se401->curframe].data+
680 se401->cwidth * 3 - 1;
681 if (se401->frame[se401->curframe].grabstate == FRAME_READY)
682 se401->frame[se401->curframe].grabstate = FRAME_GRABBING;
683 se401->vlcdatapos = 0;
684 }
685 while (datapos < len) {
686 size = 1024 - se401->vlcdatapos;
687 if (size+datapos > len)
688 size = len-datapos;
689 memcpy(se401->vlcdata+se401->vlcdatapos, data+datapos, size);
690 se401->vlcdatapos += size;
691 packetlength = 0;
692 if (se401->vlcdatapos >= 4) {
693 bit_exp = se401->vlcdata[3] + (se401->vlcdata[2] << 8);
694 pix_exp = se401->vlcdata[1] +
695 ((se401->vlcdata[0] & 0x3f) << 8);
696 frameinfo = se401->vlcdata[0] & 0xc0;
697 packetlength = ((bit_exp + 47) >> 4) << 1;
698 if (packetlength > 1024) {
699 se401->vlcdatapos = 0;
700 datapos = len;
701 packetlength = 0;
702 se401->error++;
703 se401->frame[se401->curframe].curpix = 0;
704 }
705 }
706 if (packetlength && se401->vlcdatapos >= packetlength) {
707 decode_JangGu_vlc(se401, se401->vlcdata, bit_exp,
708 packetlength);
709 se401->frame[se401->curframe].curpix += pix_exp * 3;
710 datapos += size-(se401->vlcdatapos-packetlength);
711 se401->vlcdatapos = 0;
712 if (se401->frame[se401->curframe].curpix >= se401->cwidth * se401->cheight * 3) {
713 if (se401->frame[se401->curframe].curpix == se401->cwidth * se401->cheight * 3) {
714 if (se401->frame[se401->curframe].grabstate == FRAME_GRABBING) {
715 se401->frame[se401->curframe].grabstate = FRAME_DONE;
716 se401->framecount++;
717 se401->readcount++;
718 }
719 if (se401->frame[(se401->curframe + 1) & (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY)
720 se401->curframe = (se401->curframe + 1) & (SE401_NUMFRAMES - 1);
721 } else
722 se401->error++;
723 se401->frame[se401->curframe].curpix = 0;
724 datapos = len;
725 }
726 } else
727 datapos += size;
728 }
729}
730
731static inline void decode_bayer(struct usb_se401 *se401,
732 struct se401_scratch *buffer)
733{
734 unsigned char *data = buffer->data;
735 int len = buffer->length;
736 int offset = buffer->offset;
737 int datasize = se401->cwidth * se401->cheight;
738 struct se401_frame *frame = &se401->frame[se401->curframe];
739 unsigned char *framedata = frame->data, *curline, *nextline;
740 int width = se401->cwidth;
741 int blineoffset = 0, bline;
742 int linelength = width * 3, i;
743
744
745 if (frame->curpix == 0) {
746 if (frame->grabstate == FRAME_READY)
747 frame->grabstate = FRAME_GRABBING;
748
749 frame->curline = framedata + linelength;
750 frame->curlinepix = 0;
751 }
752
753 if (offset != frame->curpix) {
754 /* Regard frame as lost :( */
755 frame->curpix = 0;
756 se401->error++;
757 return;
758 }
759
760 /* Check if we have to much data */
761 if (frame->curpix + len > datasize)
762 len = datasize-frame->curpix;
763
764 if (se401->cheight % 4)
765 blineoffset = 1;
766 bline = frame->curpix / se401->cwidth+blineoffset;
767
768 curline = frame->curline;
769 nextline = curline + linelength;
770 if (nextline >= framedata+datasize * 3)
771 nextline = curline;
772 while (len) {
773 if (frame->curlinepix >= width) {
774 frame->curlinepix -= width;
775 bline = frame->curpix / width + blineoffset;
776 curline += linelength*2;
777 nextline += linelength*2;
778 if (curline >= framedata+datasize * 3) {
779 frame->curlinepix++;
780 curline -= 3;
781 nextline -= 3;
782 len--;
783 data++;
784 frame->curpix++;
785 }
786 if (nextline >= framedata+datasize*3)
787 nextline = curline;
788 }
789 if (bline & 1) {
790 if (frame->curlinepix & 1) {
791 *(curline + 2) = *data;
792 *(curline - 1) = *data;
793 *(nextline + 2) = *data;
794 *(nextline - 1) = *data;
795 } else {
796 *(curline + 1) =
797 (*(curline + 1) + *data) / 2;
798 *(curline-2) =
799 (*(curline - 2) + *data) / 2;
800 *(nextline + 1) = *data;
801 *(nextline - 2) = *data;
802 }
803 } else {
804 if (frame->curlinepix & 1) {
805 *(curline + 1) =
806 (*(curline + 1) + *data) / 2;
807 *(curline - 2) =
808 (*(curline - 2) + *data) / 2;
809 *(nextline + 1) = *data;
810 *(nextline - 2) = *data;
811 } else {
812 *curline = *data;
813 *(curline - 3) = *data;
814 *nextline = *data;
815 *(nextline - 3) = *data;
816 }
817 }
818 frame->curlinepix++;
819 curline -= 3;
820 nextline -= 3;
821 len--;
822 data++;
823 frame->curpix++;
824 }
825 frame->curline = curline;
826
827 if (frame->curpix >= datasize) {
828 /* Fix the top line */
829 framedata += linelength;
830 for (i = 0; i < linelength; i++) {
831 framedata--;
832 *framedata = *(framedata + linelength);
833 }
834 /* Fix the left side (green is already present) */
835 for (i = 0; i < se401->cheight; i++) {
836 *framedata = *(framedata + 3);
837 *(framedata + 1) = *(framedata + 4);
838 *(framedata + 2) = *(framedata + 5);
839 framedata += linelength;
840 }
841 frame->curpix = 0;
842 frame->grabstate = FRAME_DONE;
843 se401->framecount++;
844 se401->readcount++;
845 if (se401->frame[(se401->curframe + 1) &
846 (SE401_NUMFRAMES - 1)].grabstate == FRAME_READY) {
847 se401->curframe = (se401->curframe+1) &
848 (SE401_NUMFRAMES-1);
849 }
850 }
851}
852
853static int se401_newframe(struct usb_se401 *se401, int framenr)
854{
855 DECLARE_WAITQUEUE(wait, current);
856 int errors = 0;
857
858 while (se401->streaming &&
859 (se401->frame[framenr].grabstate == FRAME_READY ||
860 se401->frame[framenr].grabstate == FRAME_GRABBING)) {
861 if (!se401->frame[framenr].curpix)
862 errors++;
863
864 wait_interruptible(
865 se401->scratch[se401->scratch_use].state != BUFFER_READY,
866 &se401->wq, &wait);
867 if (se401->nullpackets > SE401_MAX_NULLPACKETS) {
868 se401->nullpackets = 0;
869 dev_info(&se401->dev->dev,
870 "too many null length packets, restarting capture\n");
871 se401_stop_stream(se401);
872 se401_start_stream(se401);
873 } else {
874 if (se401->scratch[se401->scratch_use].state !=
875 BUFFER_READY) {
876 se401->frame[framenr].grabstate = FRAME_ERROR;
877 return -EIO;
878 }
879 se401->scratch[se401->scratch_use].state = BUFFER_BUSY;
880 if (se401->format == FMT_JANGGU)
881 decode_JangGu(se401,
882 &se401->scratch[se401->scratch_use]);
883 else
884 decode_bayer(se401,
885 &se401->scratch[se401->scratch_use]);
886
887 se401->scratch[se401->scratch_use].state =
888 BUFFER_UNUSED;
889 se401->scratch_use++;
890 if (se401->scratch_use >= SE401_NUMSCRATCH)
891 se401->scratch_use = 0;
892 if (errors > SE401_MAX_ERRORS) {
893 errors = 0;
894 dev_info(&se401->dev->dev,
895 "too many errors, restarting capture\n");
896 se401_stop_stream(se401);
897 se401_start_stream(se401);
898 }
899 }
900 }
901
902 if (se401->frame[framenr].grabstate == FRAME_DONE)
903 if (se401->enhance)
904 enhance_picture(se401->frame[framenr].data,
905 se401->cheight * se401->cwidth * 3);
906 return 0;
907}
908
909static void usb_se401_remove_disconnected(struct usb_se401 *se401)
910{
911 int i;
912
913 se401->dev = NULL;
914
915 for (i = 0; i < SE401_NUMSBUF; i++)
916 if (se401->urb[i]) {
917 usb_kill_urb(se401->urb[i]);
918 usb_free_urb(se401->urb[i]);
919 se401->urb[i] = NULL;
920 kfree(se401->sbuf[i].data);
921 }
922
923 for (i = 0; i < SE401_NUMSCRATCH; i++)
924 kfree(se401->scratch[i].data);
925
926 if (se401->inturb) {
927 usb_kill_urb(se401->inturb);
928 usb_free_urb(se401->inturb);
929 }
930 dev_info(&se401->dev->dev, "%s disconnected", se401->camera_name);
931
932 /* Free the memory */
933 kfree(se401->width);
934 kfree(se401->height);
935 kfree(se401);
936}
937
938
939
940/****************************************************************************
941 *
942 * Video4Linux
943 *
944 ***************************************************************************/
945
946
947static int se401_open(struct file *file)
948{
949 struct video_device *dev = video_devdata(file);
950 struct usb_se401 *se401 = (struct usb_se401 *)dev;
951 int err = 0;
952
953 mutex_lock(&se401->lock);
954 if (se401->user) {
955 mutex_unlock(&se401->lock);
956 return -EBUSY;
957 }
958 se401->fbuf = rvmalloc(se401->maxframesize * SE401_NUMFRAMES);
959 if (se401->fbuf)
960 file->private_data = dev;
961 else
962 err = -ENOMEM;
963 se401->user = !err;
964 mutex_unlock(&se401->lock);
965
966 return err;
967}
968
969static int se401_close(struct file *file)
970{
971 struct video_device *dev = file->private_data;
972 struct usb_se401 *se401 = (struct usb_se401 *)dev;
973 int i;
974
975 rvfree(se401->fbuf, se401->maxframesize * SE401_NUMFRAMES);
976 if (se401->removed) {
977 dev_info(&se401->dev->dev, "device unregistered\n");
978 usb_se401_remove_disconnected(se401);
979 } else {
980 for (i = 0; i < SE401_NUMFRAMES; i++)
981 se401->frame[i].grabstate = FRAME_UNUSED;
982 if (se401->streaming)
983 se401_stop_stream(se401);
984 se401->user = 0;
985 }
986 file->private_data = NULL;
987 return 0;
988}
989
990static long se401_do_ioctl(struct file *file, unsigned int cmd, void *arg)
991{
992 struct video_device *vdev = file->private_data;
993 struct usb_se401 *se401 = (struct usb_se401 *)vdev;
994
995 if (!se401->dev)
996 return -EIO;
997
998 switch (cmd) {
999 case VIDIOCGCAP:
1000 {
1001 struct video_capability *b = arg;
1002 strcpy(b->name, se401->camera_name);
1003 b->type = VID_TYPE_CAPTURE;
1004 b->channels = 1;
1005 b->audios = 0;
1006 b->maxwidth = se401->width[se401->sizes-1];
1007 b->maxheight = se401->height[se401->sizes-1];
1008 b->minwidth = se401->width[0];
1009 b->minheight = se401->height[0];
1010 return 0;
1011 }
1012 case VIDIOCGCHAN:
1013 {
1014 struct video_channel *v = arg;
1015
1016 if (v->channel != 0)
1017 return -EINVAL;
1018 v->flags = 0;
1019 v->tuners = 0;
1020 v->type = VIDEO_TYPE_CAMERA;
1021 strcpy(v->name, "Camera");
1022 return 0;
1023 }
1024 case VIDIOCSCHAN:
1025 {
1026 struct video_channel *v = arg;
1027
1028 if (v->channel != 0)
1029 return -EINVAL;
1030 return 0;
1031 }
1032 case VIDIOCGPICT:
1033 {
1034 struct video_picture *p = arg;
1035
1036 se401_get_pict(se401, p);
1037 return 0;
1038 }
1039 case VIDIOCSPICT:
1040 {
1041 struct video_picture *p = arg;
1042
1043 if (se401_set_pict(se401, p))
1044 return -EINVAL;
1045 return 0;
1046 }
1047 case VIDIOCSWIN:
1048 {
1049 struct video_window *vw = arg;
1050
1051 if (vw->flags)
1052 return -EINVAL;
1053 if (vw->clipcount)
1054 return -EINVAL;
1055 if (se401_set_size(se401, vw->width, vw->height))
1056 return -EINVAL;
1057 return 0;
1058 }
1059 case VIDIOCGWIN:
1060 {
1061 struct video_window *vw = arg;
1062
1063 vw->x = 0; /* FIXME */
1064 vw->y = 0;
1065 vw->chromakey = 0;
1066 vw->flags = 0;
1067 vw->clipcount = 0;
1068 vw->width = se401->cwidth;
1069 vw->height = se401->cheight;
1070 return 0;
1071 }
1072 case VIDIOCGMBUF:
1073 {
1074 struct video_mbuf *vm = arg;
1075 int i;
1076
1077 memset(vm, 0, sizeof(*vm));
1078 vm->size = SE401_NUMFRAMES * se401->maxframesize;
1079 vm->frames = SE401_NUMFRAMES;
1080 for (i = 0; i < SE401_NUMFRAMES; i++)
1081 vm->offsets[i] = se401->maxframesize * i;
1082 return 0;
1083 }
1084 case VIDIOCMCAPTURE:
1085 {
1086 struct video_mmap *vm = arg;
1087
1088 if (vm->format != VIDEO_PALETTE_RGB24)
1089 return -EINVAL;
1090 if (vm->frame >= SE401_NUMFRAMES)
1091 return -EINVAL;
1092 if (se401->frame[vm->frame].grabstate != FRAME_UNUSED)
1093 return -EBUSY;
1094
1095 /* Is this according to the v4l spec??? */
1096 if (se401_set_size(se401, vm->width, vm->height))
1097 return -EINVAL;
1098 se401->frame[vm->frame].grabstate = FRAME_READY;
1099
1100 if (!se401->streaming)
1101 se401_start_stream(se401);
1102
1103 /* Set the picture properties */
1104 if (se401->framecount == 0)
1105 se401_send_pict(se401);
1106 /* Calibrate the reset level after a few frames. */
1107 if (se401->framecount % 20 == 1)
1108 se401_auto_resetlevel(se401);
1109
1110 return 0;
1111 }
1112 case VIDIOCSYNC:
1113 {
1114 int *frame = arg;
1115 int ret = 0;
1116
1117 if (*frame < 0 || *frame >= SE401_NUMFRAMES)
1118 return -EINVAL;
1119
1120 ret = se401_newframe(se401, *frame);
1121 se401->frame[*frame].grabstate = FRAME_UNUSED;
1122 return ret;
1123 }
1124 case VIDIOCGFBUF:
1125 {
1126 struct video_buffer *vb = arg;
1127
1128 memset(vb, 0, sizeof(*vb));
1129 return 0;
1130 }
1131 case VIDIOCKEY:
1132 return 0;
1133 case VIDIOCCAPTURE:
1134 return -EINVAL;
1135 case VIDIOCSFBUF:
1136 return -EINVAL;
1137 case VIDIOCGTUNER:
1138 case VIDIOCSTUNER:
1139 return -EINVAL;
1140 case VIDIOCGFREQ:
1141 case VIDIOCSFREQ:
1142 return -EINVAL;
1143 case VIDIOCGAUDIO:
1144 case VIDIOCSAUDIO:
1145 return -EINVAL;
1146 default:
1147 return -ENOIOCTLCMD;
1148 } /* end switch */
1149
1150 return 0;
1151}
1152
1153static long se401_ioctl(struct file *file,
1154 unsigned int cmd, unsigned long arg)
1155{
1156 return video_usercopy(file, cmd, arg, se401_do_ioctl);
1157}
1158
1159static ssize_t se401_read(struct file *file, char __user *buf,
1160 size_t count, loff_t *ppos)
1161{
1162 int realcount = count, ret = 0;
1163 struct video_device *dev = file->private_data;
1164 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1165
1166
1167 if (se401->dev == NULL)
1168 return -EIO;
1169 if (realcount > se401->cwidth*se401->cheight*3)
1170 realcount = se401->cwidth*se401->cheight*3;
1171
1172 /* Shouldn't happen: */
1173 if (se401->frame[0].grabstate == FRAME_GRABBING)
1174 return -EBUSY;
1175 se401->frame[0].grabstate = FRAME_READY;
1176 se401->frame[1].grabstate = FRAME_UNUSED;
1177 se401->curframe = 0;
1178
1179 if (!se401->streaming)
1180 se401_start_stream(se401);
1181
1182 /* Set the picture properties */
1183 if (se401->framecount == 0)
1184 se401_send_pict(se401);
1185 /* Calibrate the reset level after a few frames. */
1186 if (se401->framecount%20 == 1)
1187 se401_auto_resetlevel(se401);
1188
1189 ret = se401_newframe(se401, 0);
1190
1191 se401->frame[0].grabstate = FRAME_UNUSED;
1192 if (ret)
1193 return ret;
1194 if (copy_to_user(buf, se401->frame[0].data, realcount))
1195 return -EFAULT;
1196
1197 return realcount;
1198}
1199
1200static int se401_mmap(struct file *file, struct vm_area_struct *vma)
1201{
1202 struct video_device *dev = file->private_data;
1203 struct usb_se401 *se401 = (struct usb_se401 *)dev;
1204 unsigned long start = vma->vm_start;
1205 unsigned long size = vma->vm_end-vma->vm_start;
1206 unsigned long page, pos;
1207
1208 mutex_lock(&se401->lock);
1209
1210 if (se401->dev == NULL) {
1211 mutex_unlock(&se401->lock);
1212 return -EIO;
1213 }
1214 if (size > (((SE401_NUMFRAMES * se401->maxframesize) + PAGE_SIZE - 1)
1215 & ~(PAGE_SIZE - 1))) {
1216 mutex_unlock(&se401->lock);
1217 return -EINVAL;
1218 }
1219 pos = (unsigned long)se401->fbuf;
1220 while (size > 0) {
1221 page = vmalloc_to_pfn((void *)pos);
1222 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
1223 mutex_unlock(&se401->lock);
1224 return -EAGAIN;
1225 }
1226 start += PAGE_SIZE;
1227 pos += PAGE_SIZE;
1228 if (size > PAGE_SIZE)
1229 size -= PAGE_SIZE;
1230 else
1231 size = 0;
1232 }
1233 mutex_unlock(&se401->lock);
1234
1235 return 0;
1236}
1237
1238static const struct v4l2_file_operations se401_fops = {
1239 .owner = THIS_MODULE,
1240 .open = se401_open,
1241 .release = se401_close,
1242 .read = se401_read,
1243 .mmap = se401_mmap,
1244 .ioctl = se401_ioctl,
1245};
1246static struct video_device se401_template = {
1247 .name = "se401 USB camera",
1248 .fops = &se401_fops,
1249 .release = video_device_release_empty,
1250};
1251
1252
1253
1254/***************************/
1255static int se401_init(struct usb_se401 *se401, int button)
1256{
1257 int i = 0, rc;
1258 unsigned char cp[0x40];
1259 char temp[200];
1260 int slen;
1261
1262 /* led on */
1263 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1264
1265 /* get camera descriptor */
1266 rc = se401_sndctrl(0, se401, SE401_REQ_GET_CAMERA_DESCRIPTOR, 0,
1267 cp, sizeof(cp));
1268 if (cp[1] != 0x41) {
1269 err("Wrong descriptor type");
1270 return 1;
1271 }
1272 slen = snprintf(temp, 200, "ExtraFeatures: %d", cp[3]);
1273
1274 se401->sizes = cp[4] + cp[5] * 256;
1275 se401->width = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1276 if (!se401->width)
1277 return 1;
1278 se401->height = kmalloc(se401->sizes*sizeof(int), GFP_KERNEL);
1279 if (!se401->height) {
1280 kfree(se401->width);
1281 return 1;
1282 }
1283 for (i = 0; i < se401->sizes; i++) {
1284 se401->width[i] = cp[6 + i * 4 + 0] + cp[6 + i*4 + 1] * 256;
1285 se401->height[i] = cp[6 + i * 4 + 2] + cp[6 + i * 4 + 3] * 256;
1286 }
1287 slen += snprintf(temp + slen, 200 - slen, " Sizes:");
1288 for (i = 0; i < se401->sizes; i++) {
1289 slen += snprintf(temp + slen, 200 - slen,
1290 " %dx%d", se401->width[i], se401->height[i]);
1291 }
1292 dev_info(&se401->dev->dev, "%s\n", temp);
1293 se401->maxframesize = se401->width[se401->sizes-1] *
1294 se401->height[se401->sizes - 1] * 3;
1295
1296 rc = se401_sndctrl(0, se401, SE401_REQ_GET_WIDTH, 0, cp, sizeof(cp));
1297 se401->cwidth = cp[0]+cp[1]*256;
1298 rc = se401_sndctrl(0, se401, SE401_REQ_GET_HEIGHT, 0, cp, sizeof(cp));
1299 se401->cheight = cp[0]+cp[1]*256;
1300
1301 if (!(cp[2] & SE401_FORMAT_BAYER)) {
1302 err("Bayer format not supported!");
1303 return 1;
1304 }
1305 /* set output mode (BAYER) */
1306 se401_sndctrl(1, se401, SE401_REQ_SET_OUTPUT_MODE,
1307 SE401_FORMAT_BAYER, NULL, 0);
1308
1309 rc = se401_sndctrl(0, se401, SE401_REQ_GET_BRT, 0, cp, sizeof(cp));
1310 se401->brightness = cp[0]+cp[1]*256;
1311 /* some default values */
1312 se401->resetlevel = 0x2d;
1313 se401->rgain = 0x20;
1314 se401->ggain = 0x20;
1315 se401->bgain = 0x20;
1316 se401_set_exposure(se401, 20000);
1317 se401->palette = VIDEO_PALETTE_RGB24;
1318 se401->enhance = 1;
1319 se401->dropped = 0;
1320 se401->error = 0;
1321 se401->framecount = 0;
1322 se401->readcount = 0;
1323
1324 /* Start interrupt transfers for snapshot button */
1325 if (button) {
1326 se401->inturb = usb_alloc_urb(0, GFP_KERNEL);
1327 if (!se401->inturb) {
1328 dev_info(&se401->dev->dev,
1329 "Allocation of inturb failed\n");
1330 return 1;
1331 }
1332 usb_fill_int_urb(se401->inturb, se401->dev,
1333 usb_rcvintpipe(se401->dev, SE401_BUTTON_ENDPOINT),
1334 &se401->button, sizeof(se401->button),
1335 se401_button_irq,
1336 se401,
1337 8
1338 );
1339 if (usb_submit_urb(se401->inturb, GFP_KERNEL)) {
1340 dev_info(&se401->dev->dev, "int urb burned down\n");
1341 return 1;
1342 }
1343 } else
1344 se401->inturb = NULL;
1345
1346 /* Flash the led */
1347 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 1, NULL, 0);
1348 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 1, NULL, 0);
1349 se401_sndctrl(1, se401, SE401_REQ_CAMERA_POWER, 0, NULL, 0);
1350 se401_sndctrl(1, se401, SE401_REQ_LED_CONTROL, 0, NULL, 0);
1351
1352 return 0;
1353}
1354
1355static int se401_probe(struct usb_interface *intf,
1356 const struct usb_device_id *id)
1357{
1358 struct usb_device *dev = interface_to_usbdev(intf);
1359 struct usb_interface_descriptor *interface;
1360 struct usb_se401 *se401;
1361 char *camera_name = NULL;
1362 int button = 1;
1363
1364 /* We don't handle multi-config cameras */
1365 if (dev->descriptor.bNumConfigurations != 1)
1366 return -ENODEV;
1367
1368 interface = &intf->cur_altsetting->desc;
1369
1370 /* Is it an se401? */
1371 if (le16_to_cpu(dev->descriptor.idVendor) == 0x03e8 &&
1372 le16_to_cpu(dev->descriptor.idProduct) == 0x0004) {
1373 camera_name = "Endpoints/Aox SE401";
1374 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x0471 &&
1375 le16_to_cpu(dev->descriptor.idProduct) == 0x030b) {
1376 camera_name = "Philips PCVC665K";
1377 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1378 le16_to_cpu(dev->descriptor.idProduct) == 0x5001) {
1379 camera_name = "Kensington VideoCAM 67014";
1380 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1381 le16_to_cpu(dev->descriptor.idProduct) == 0x5002) {
1382 camera_name = "Kensington VideoCAM 6701(5/7)";
1383 } else if (le16_to_cpu(dev->descriptor.idVendor) == 0x047d &&
1384 le16_to_cpu(dev->descriptor.idProduct) == 0x5003) {
1385 camera_name = "Kensington VideoCAM 67016";
1386 button = 0;
1387 } else
1388 return -ENODEV;
1389
1390 /* Checking vendor/product should be enough, but what the hell */
1391 if (interface->bInterfaceClass != 0x00)
1392 return -ENODEV;
1393 if (interface->bInterfaceSubClass != 0x00)
1394 return -ENODEV;
1395
1396 /* We found one */
1397 dev_info(&intf->dev, "SE401 camera found: %s\n", camera_name);
1398
1399 se401 = kzalloc(sizeof(*se401), GFP_KERNEL);
1400 if (se401 == NULL) {
1401 err("couldn't kmalloc se401 struct");
1402 return -ENOMEM;
1403 }
1404
1405 se401->dev = dev;
1406 se401->iface = interface->bInterfaceNumber;
1407 se401->camera_name = camera_name;
1408
1409 dev_info(&intf->dev, "firmware version: %02x\n",
1410 le16_to_cpu(dev->descriptor.bcdDevice) & 255);
1411
1412 if (se401_init(se401, button)) {
1413 kfree(se401);
1414 return -EIO;
1415 }
1416
1417 memcpy(&se401->vdev, &se401_template, sizeof(se401_template));
1418 memcpy(se401->vdev.name, se401->camera_name,
1419 strlen(se401->camera_name));
1420 init_waitqueue_head(&se401->wq);
1421 mutex_init(&se401->lock);
1422 wmb();
1423
1424 if (video_register_device(&se401->vdev,
1425 VFL_TYPE_GRABBER, video_nr) < 0) {
1426 kfree(se401);
1427 err("video_register_device failed");
1428 return -EIO;
1429 }
1430 dev_info(&intf->dev, "registered new video device: %s\n",
1431 video_device_node_name(&se401->vdev));
1432
1433 usb_set_intfdata(intf, se401);
1434 return 0;
1435}
1436
1437static void se401_disconnect(struct usb_interface *intf)
1438{
1439 struct usb_se401 *se401 = usb_get_intfdata(intf);
1440
1441 usb_set_intfdata(intf, NULL);
1442 if (se401) {
1443 video_unregister_device(&se401->vdev);
1444 if (!se401->user)
1445 usb_se401_remove_disconnected(se401);
1446 else {
1447 se401->frame[0].grabstate = FRAME_ERROR;
1448 se401->frame[0].grabstate = FRAME_ERROR;
1449
1450 se401->streaming = 0;
1451
1452 wake_up_interruptible(&se401->wq);
1453 se401->removed = 1;
1454 }
1455 }
1456}
1457
1458static struct usb_driver se401_driver = {
1459 .name = "se401",
1460 .id_table = device_table,
1461 .probe = se401_probe,
1462 .disconnect = se401_disconnect,
1463};
1464
1465
1466
1467/****************************************************************************
1468 *
1469 * Module routines
1470 *
1471 ***************************************************************************/
1472
1473static int __init usb_se401_init(void)
1474{
1475 printk(KERN_INFO "SE401 usb camera driver version %s registering\n",
1476 version);
1477 if (flickerless)
1478 if (flickerless != 50 && flickerless != 60) {
1479 printk(KERN_ERR "Invallid flickerless value, use 0, 50 or 60.\n");
1480 return -1;
1481 }
1482 return usb_register(&se401_driver);
1483}
1484
1485static void __exit usb_se401_exit(void)
1486{
1487 usb_deregister(&se401_driver);
1488 printk(KERN_INFO "SE401 driver deregistered\frame");
1489}
1490
1491module_init(usb_se401_init);
1492module_exit(usb_se401_exit);
diff --git a/drivers/staging/se401/se401.h b/drivers/staging/se401/se401.h
deleted file mode 100644
index 2758f4716c3d..000000000000
--- a/drivers/staging/se401/se401.h
+++ /dev/null
@@ -1,236 +0,0 @@
1
2#ifndef __LINUX_se401_H
3#define __LINUX_se401_H
4
5#include <linux/uaccess.h>
6#include "videodev.h"
7#include <media/v4l2-common.h>
8#include <media/v4l2-ioctl.h>
9#include <linux/mutex.h>
10
11#define se401_DEBUG /* Turn on debug messages */
12
13#ifdef se401_DEBUG
14# define PDEBUG(level, fmt, args...) \
15if (debug >= level) \
16 info("[" __PRETTY_FUNCTION__ ":%d] " fmt, __LINE__ , ## args)
17#else
18# define PDEBUG(level, fmt, args...) do {} while (0)
19#endif
20
21/* An almost drop-in replacement for sleep_on_interruptible */
22#define wait_interruptible(test, queue, wait) \
23{ \
24 add_wait_queue(queue, wait); \
25 set_current_state(TASK_INTERRUPTIBLE); \
26 if (test) \
27 schedule(); \
28 remove_wait_queue(queue, wait); \
29 set_current_state(TASK_RUNNING); \
30 if (signal_pending(current)) \
31 break; \
32}
33
34#define SE401_REQ_GET_CAMERA_DESCRIPTOR 0x06
35#define SE401_REQ_START_CONTINUOUS_CAPTURE 0x41
36#define SE401_REQ_STOP_CONTINUOUS_CAPTURE 0x42
37#define SE401_REQ_CAPTURE_FRAME 0x43
38#define SE401_REQ_GET_BRT 0x44
39#define SE401_REQ_SET_BRT 0x45
40#define SE401_REQ_GET_WIDTH 0x4c
41#define SE401_REQ_SET_WIDTH 0x4d
42#define SE401_REQ_GET_HEIGHT 0x4e
43#define SE401_REQ_SET_HEIGHT 0x4f
44#define SE401_REQ_GET_OUTPUT_MODE 0x50
45#define SE401_REQ_SET_OUTPUT_MODE 0x51
46#define SE401_REQ_GET_EXT_FEATURE 0x52
47#define SE401_REQ_SET_EXT_FEATURE 0x53
48#define SE401_REQ_CAMERA_POWER 0x56
49#define SE401_REQ_LED_CONTROL 0x57
50#define SE401_REQ_BIOS 0xff
51
52#define SE401_BIOS_READ 0x07
53
54#define SE401_FORMAT_BAYER 0x40
55
56/* Hyundai hv7131b registers
57 7121 and 7141 should be the same (haven't really checked...) */
58/* Mode registers: */
59#define HV7131_REG_MODE_A 0x00
60#define HV7131_REG_MODE_B 0x01
61#define HV7131_REG_MODE_C 0x02
62/* Frame registers: */
63#define HV7131_REG_FRSU 0x10
64#define HV7131_REG_FRSL 0x11
65#define HV7131_REG_FCSU 0x12
66#define HV7131_REG_FCSL 0x13
67#define HV7131_REG_FWHU 0x14
68#define HV7131_REG_FWHL 0x15
69#define HV7131_REG_FWWU 0x16
70#define HV7131_REG_FWWL 0x17
71/* Timing registers: */
72#define HV7131_REG_THBU 0x20
73#define HV7131_REG_THBL 0x21
74#define HV7131_REG_TVBU 0x22
75#define HV7131_REG_TVBL 0x23
76#define HV7131_REG_TITU 0x25
77#define HV7131_REG_TITM 0x26
78#define HV7131_REG_TITL 0x27
79#define HV7131_REG_TMCD 0x28
80/* Adjust Registers: */
81#define HV7131_REG_ARLV 0x30
82#define HV7131_REG_ARCG 0x31
83#define HV7131_REG_AGCG 0x32
84#define HV7131_REG_ABCG 0x33
85#define HV7131_REG_APBV 0x34
86#define HV7131_REG_ASLP 0x54
87/* Offset Registers: */
88#define HV7131_REG_OFSR 0x50
89#define HV7131_REG_OFSG 0x51
90#define HV7131_REG_OFSB 0x52
91/* REset level statistics registers: */
92#define HV7131_REG_LOREFNOH 0x57
93#define HV7131_REG_LOREFNOL 0x58
94#define HV7131_REG_HIREFNOH 0x59
95#define HV7131_REG_HIREFNOL 0x5a
96
97/* se401 registers */
98#define SE401_OPERATINGMODE 0x2000
99
100
101/* size of usb transfers */
102#define SE401_PACKETSIZE 4096
103/* number of queued bulk transfers to use, should be about 8 */
104#define SE401_NUMSBUF 1
105/* read the usb specs for this one :) */
106#define SE401_VIDEO_ENDPOINT 1
107#define SE401_BUTTON_ENDPOINT 2
108/* number of frames supported by the v4l part */
109#define SE401_NUMFRAMES 2
110/* scratch buffers for passing data to the decoders */
111#define SE401_NUMSCRATCH 32
112/* maximum amount of data in a JangGu packet */
113#define SE401_VLCDATALEN 1024
114/* number of nul sized packets to receive before kicking the camera */
115#define SE401_MAX_NULLPACKETS 4000
116/* number of decoding errors before kicking the camera */
117#define SE401_MAX_ERRORS 200
118
119struct usb_device;
120
121struct se401_sbuf {
122 unsigned char *data;
123};
124
125enum {
126 FRAME_UNUSED, /* Unused (no MCAPTURE) */
127 FRAME_READY, /* Ready to start grabbing */
128 FRAME_GRABBING, /* In the process of being grabbed into */
129 FRAME_DONE, /* Finished grabbing, but not been synced yet */
130 FRAME_ERROR, /* Something bad happened while processing */
131};
132
133enum {
134 FMT_BAYER,
135 FMT_JANGGU,
136};
137
138enum {
139 BUFFER_UNUSED,
140 BUFFER_READY,
141 BUFFER_BUSY,
142 BUFFER_DONE,
143};
144
145struct se401_scratch {
146 unsigned char *data;
147 volatile int state;
148 int offset;
149 int length;
150};
151
152struct se401_frame {
153 unsigned char *data; /* Frame buffer */
154
155 volatile int grabstate; /* State of grabbing */
156
157 unsigned char *curline;
158 int curlinepix;
159 int curpix;
160};
161
162struct usb_se401 {
163 struct video_device vdev;
164
165 /* Device structure */
166 struct usb_device *dev;
167
168 unsigned char iface;
169
170 char *camera_name;
171
172 int change;
173 int brightness;
174 int hue;
175 int rgain;
176 int ggain;
177 int bgain;
178 int expose_h;
179 int expose_m;
180 int expose_l;
181 int resetlevel;
182
183 int enhance;
184
185 int format;
186 int sizes;
187 int *width;
188 int *height;
189 int cwidth; /* current width */
190 int cheight; /* current height */
191 int palette;
192 int maxframesize;
193 int cframesize; /* current framesize */
194
195 struct mutex lock;
196 int user; /* user count for exclusive use */
197 int removed; /* device disconnected */
198
199 int streaming; /* Are we streaming video? */
200
201 char *fbuf; /* Videodev buffer area */
202
203 struct urb *urb[SE401_NUMSBUF];
204 struct urb *inturb;
205
206 int button;
207 int buttonpressed;
208
209 int curframe; /* Current receiving frame */
210 struct se401_frame frame[SE401_NUMFRAMES];
211 int readcount;
212 int framecount;
213 int error;
214 int dropped;
215
216 int scratch_next;
217 int scratch_use;
218 int scratch_overflow;
219 struct se401_scratch scratch[SE401_NUMSCRATCH];
220
221 /* Decoder specific data: */
222 unsigned char vlcdata[SE401_VLCDATALEN];
223 int vlcdatapos;
224 int bayeroffset;
225
226 struct se401_sbuf sbuf[SE401_NUMSBUF];
227
228 wait_queue_head_t wq; /* Processes waiting */
229
230 int nullpackets;
231};
232
233
234
235#endif
236
diff --git a/drivers/staging/se401/videodev.h b/drivers/staging/se401/videodev.h
deleted file mode 100644
index f11efbef1c05..000000000000
--- a/drivers/staging/se401/videodev.h
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * Video for Linux version 1 - OBSOLETE
3 *
4 * Header file for v4l1 drivers and applications, for
5 * Linux kernels 2.2.x or 2.4.x.
6 *
7 * Provides header for legacy drivers and applications
8 *
9 * See http://linuxtv.org for more info
10 *
11 */
12#ifndef __LINUX_VIDEODEV_H
13#define __LINUX_VIDEODEV_H
14
15#include <linux/types.h>
16#include <linux/ioctl.h>
17#include <linux/videodev2.h>
18
19#define VID_TYPE_CAPTURE 1 /* Can capture */
20#define VID_TYPE_TUNER 2 /* Can tune */
21#define VID_TYPE_TELETEXT 4 /* Does teletext */
22#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
23#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
24#define VID_TYPE_CLIPPING 32 /* Can clip */
25#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
26#define VID_TYPE_SCALES 128 /* Scalable */
27#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
28#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
29#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
30#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
31#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
32#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
33
34struct video_capability
35{
36 char name[32];
37 int type;
38 int channels; /* Num channels */
39 int audios; /* Num audio devices */
40 int maxwidth; /* Supported width */
41 int maxheight; /* And height */
42 int minwidth; /* Supported width */
43 int minheight; /* And height */
44};
45
46
47struct video_channel
48{
49 int channel;
50 char name[32];
51 int tuners;
52 __u32 flags;
53#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
54#define VIDEO_VC_AUDIO 2 /* Channel has audio */
55 __u16 type;
56#define VIDEO_TYPE_TV 1
57#define VIDEO_TYPE_CAMERA 2
58 __u16 norm; /* Norm set by channel */
59};
60
61struct video_tuner
62{
63 int tuner;
64 char name[32];
65 unsigned long rangelow, rangehigh; /* Tuner range */
66 __u32 flags;
67#define VIDEO_TUNER_PAL 1
68#define VIDEO_TUNER_NTSC 2
69#define VIDEO_TUNER_SECAM 4
70#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
71#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
72#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
73#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
74#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
75 __u16 mode; /* PAL/NTSC/SECAM/OTHER */
76#define VIDEO_MODE_PAL 0
77#define VIDEO_MODE_NTSC 1
78#define VIDEO_MODE_SECAM 2
79#define VIDEO_MODE_AUTO 3
80 __u16 signal; /* Signal strength 16bit scale */
81};
82
83struct video_picture
84{
85 __u16 brightness;
86 __u16 hue;
87 __u16 colour;
88 __u16 contrast;
89 __u16 whiteness; /* Black and white only */
90 __u16 depth; /* Capture depth */
91 __u16 palette; /* Palette in use */
92#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
93#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
94#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
95#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
96#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
97#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
98#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
99#define VIDEO_PALETTE_YUYV 8
100#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
101#define VIDEO_PALETTE_YUV420 10
102#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
103#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
104#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
105#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
106#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
107#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
108#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
109#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
110};
111
112struct video_audio
113{
114 int audio; /* Audio channel */
115 __u16 volume; /* If settable */
116 __u16 bass, treble;
117 __u32 flags;
118#define VIDEO_AUDIO_MUTE 1
119#define VIDEO_AUDIO_MUTABLE 2
120#define VIDEO_AUDIO_VOLUME 4
121#define VIDEO_AUDIO_BASS 8
122#define VIDEO_AUDIO_TREBLE 16
123#define VIDEO_AUDIO_BALANCE 32
124 char name[16];
125#define VIDEO_SOUND_MONO 1
126#define VIDEO_SOUND_STEREO 2
127#define VIDEO_SOUND_LANG1 4
128#define VIDEO_SOUND_LANG2 8
129 __u16 mode;
130 __u16 balance; /* Stereo balance */
131 __u16 step; /* Step actual volume uses */
132};
133
134struct video_clip
135{
136 __s32 x,y;
137 __s32 width, height;
138 struct video_clip *next; /* For user use/driver use only */
139};
140
141struct video_window
142{
143 __u32 x,y; /* Position of window */
144 __u32 width,height; /* Its size */
145 __u32 chromakey;
146 __u32 flags;
147 struct video_clip __user *clips; /* Set only */
148 int clipcount;
149#define VIDEO_WINDOW_INTERLACE 1
150#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
151#define VIDEO_CLIP_BITMAP -1
152/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
153#define VIDEO_CLIPMAP_SIZE (128 * 625)
154};
155
156struct video_capture
157{
158 __u32 x,y; /* Offsets into image */
159 __u32 width, height; /* Area to capture */
160 __u16 decimation; /* Decimation divider */
161 __u16 flags; /* Flags for capture */
162#define VIDEO_CAPTURE_ODD 0 /* Temporal */
163#define VIDEO_CAPTURE_EVEN 1
164};
165
166struct video_buffer
167{
168 void *base;
169 int height,width;
170 int depth;
171 int bytesperline;
172};
173
174struct video_mmap
175{
176 unsigned int frame; /* Frame (0 - n) for double buffer */
177 int height,width;
178 unsigned int format; /* should be VIDEO_PALETTE_* */
179};
180
181struct video_key
182{
183 __u8 key[8];
184 __u32 flags;
185};
186
187struct video_mbuf
188{
189 int size; /* Total memory to map */
190 int frames; /* Frames */
191 int offsets[VIDEO_MAX_FRAME];
192};
193
194#define VIDEO_NO_UNIT (-1)
195
196struct video_unit
197{
198 int video; /* Video minor */
199 int vbi; /* VBI minor */
200 int radio; /* Radio minor */
201 int audio; /* Audio minor */
202 int teletext; /* Teletext minor */
203};
204
205struct vbi_format {
206 __u32 sampling_rate; /* in Hz */
207 __u32 samples_per_line;
208 __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
209 __s32 start[2]; /* starting line for each frame */
210 __u32 count[2]; /* count of lines for each frame */
211 __u32 flags;
212#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
213#define VBI_INTERLACED 2 /* lines are interlaced */
214};
215
216/* video_info is biased towards hardware mpeg encode/decode */
217/* but it could apply generically to any hardware compressor/decompressor */
218struct video_info
219{
220 __u32 frame_count; /* frames output since decode/encode began */
221 __u32 h_size; /* current unscaled horizontal size */
222 __u32 v_size; /* current unscaled veritcal size */
223 __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */
224 __u32 picture_type; /* current picture type */
225 __u32 temporal_reference; /* current temporal reference */
226 __u8 user_data[256]; /* user data last found in compressed stream */
227 /* user_data[0] contains user data flags, user_data[1] has count */
228};
229
230/* generic structure for setting playback modes */
231struct video_play_mode
232{
233 int mode;
234 int p1;
235 int p2;
236};
237
238/* for loading microcode / fpga programming */
239struct video_code
240{
241 char loadwhat[16]; /* name or tag of file being passed */
242 int datasize;
243 __u8 *data;
244};
245
246#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
247#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
248#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
249#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
250#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
251#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
252#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
253#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
254#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
255#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
256#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
257#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
258#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
259#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
260#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
261#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
262#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
263#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
264#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
265#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
266#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
267#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
268#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
269#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
270#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
271#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
272#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
273#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
274#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
275
276
277#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
278
279/* VIDIOCSWRITEMODE */
280#define VID_WRITE_MPEG_AUD 0
281#define VID_WRITE_MPEG_VID 1
282#define VID_WRITE_OSD 2
283#define VID_WRITE_TTX 3
284#define VID_WRITE_CC 4
285#define VID_WRITE_MJPEG 5
286
287/* VIDIOCSPLAYMODE */
288#define VID_PLAY_VID_OUT_MODE 0
289 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
290#define VID_PLAY_GENLOCK 1
291 /* p1: 0 = OFF, 1 = ON */
292 /* p2: GENLOCK FINE DELAY value */
293#define VID_PLAY_NORMAL 2
294#define VID_PLAY_PAUSE 3
295#define VID_PLAY_SINGLE_FRAME 4
296#define VID_PLAY_FAST_FORWARD 5
297#define VID_PLAY_SLOW_MOTION 6
298#define VID_PLAY_IMMEDIATE_NORMAL 7
299#define VID_PLAY_SWITCH_CHANNELS 8
300#define VID_PLAY_FREEZE_FRAME 9
301#define VID_PLAY_STILL_MODE 10
302#define VID_PLAY_MASTER_MODE 11
303 /* p1: see below */
304#define VID_PLAY_MASTER_NONE 1
305#define VID_PLAY_MASTER_VIDEO 2
306#define VID_PLAY_MASTER_AUDIO 3
307#define VID_PLAY_ACTIVE_SCANLINES 12
308 /* p1 = first active; p2 = last active */
309#define VID_PLAY_RESET 13
310#define VID_PLAY_END_MARK 14
311
312#endif /* __LINUX_VIDEODEV_H */
313
314/*
315 * Local variables:
316 * c-basic-offset: 8
317 * End:
318 */
diff --git a/drivers/staging/tm6000/tm6000-alsa.c b/drivers/staging/tm6000/tm6000-alsa.c
index 184cc505ed86..acb03172a887 100644
--- a/drivers/staging/tm6000/tm6000-alsa.c
+++ b/drivers/staging/tm6000/tm6000-alsa.c
@@ -76,14 +76,11 @@ MODULE_PARM_DESC(debug, "enable debug messages");
76static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip) 76static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
77{ 77{
78 struct tm6000_core *core = chip->core; 78 struct tm6000_core *core = chip->core;
79 int val;
80 79
81 dprintk(1, "Starting audio DMA\n"); 80 dprintk(1, "Starting audio DMA\n");
82 81
83 /* Enables audio */ 82 /* Enables audio */
84 val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0); 83 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x40, 0x40);
85 val |= 0x20;
86 tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
87 84
88 tm6000_set_audio_bitrate(core, 48000); 85 tm6000_set_audio_bitrate(core, 48000);
89 86
@@ -98,13 +95,11 @@ static int _tm6000_start_audio_dma(struct snd_tm6000_card *chip)
98static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip) 95static int _tm6000_stop_audio_dma(struct snd_tm6000_card *chip)
99{ 96{
100 struct tm6000_core *core = chip->core; 97 struct tm6000_core *core = chip->core;
101 int val; 98
102 dprintk(1, "Stopping audio DMA\n"); 99 dprintk(1, "Stopping audio DMA\n");
103 100
104 /* Enables audio */ 101 /* Disables audio */
105 val = tm6000_get_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x0); 102 tm6000_set_reg_mask(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0x00, 0x40);
106 val &= ~0x20;
107 tm6000_set_reg(core, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
108 103
109 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0); 104 tm6000_set_reg(core, TM6010_REQ08_R01_A_INIT, 0);
110 105
diff --git a/drivers/staging/tm6000/tm6000-cards.c b/drivers/staging/tm6000/tm6000-cards.c
index 455038bdfc9f..146c7e86deca 100644
--- a/drivers/staging/tm6000/tm6000-cards.c
+++ b/drivers/staging/tm6000/tm6000-cards.c
@@ -50,6 +50,9 @@
50#define TM6010_BOARD_BEHOLD_VOYAGER 11 50#define TM6010_BOARD_BEHOLD_VOYAGER 11
51#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12 51#define TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE 12
52#define TM6010_BOARD_TWINHAN_TU501 13 52#define TM6010_BOARD_TWINHAN_TU501 13
53#define TM6010_BOARD_BEHOLD_WANDER_LITE 14
54#define TM6010_BOARD_BEHOLD_VOYAGER_LITE 15
55#define TM5600_BOARD_TERRATEC_GRABSTER 16
53 56
54#define TM6000_MAXBOARDS 16 57#define TM6000_MAXBOARDS 16
55static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET }; 58static unsigned int card[] = {[0 ... (TM6000_MAXBOARDS - 1)] = UNSET };
@@ -63,6 +66,8 @@ struct tm6000_board {
63 char *name; 66 char *name;
64 67
65 struct tm6000_capabilities caps; 68 struct tm6000_capabilities caps;
69 enum tm6000_inaudio aradio;
70 enum tm6000_inaudio avideo;
66 71
67 enum tm6000_devtype type; /* variant of the chipset */ 72 enum tm6000_devtype type; /* variant of the chipset */
68 int tuner_type; /* type of the tuner */ 73 int tuner_type; /* type of the tuner */
@@ -227,12 +232,16 @@ struct tm6000_board tm6000_boards[] = {
227 .tuner_addr = 0xc2 >> 1, 232 .tuner_addr = 0xc2 >> 1,
228 .demod_addr = 0x1e >> 1, 233 .demod_addr = 0x1e >> 1,
229 .type = TM6010, 234 .type = TM6010,
235 .avideo = TM6000_AIP_SIF1,
236 .aradio = TM6000_AIP_LINE1,
230 .caps = { 237 .caps = {
231 .has_tuner = 1, 238 .has_tuner = 1,
232 .has_dvb = 1, 239 .has_dvb = 1,
233 .has_zl10353 = 1, 240 .has_zl10353 = 1,
234 .has_eeprom = 1, 241 .has_eeprom = 1,
235 .has_remote = 1, 242 .has_remote = 1,
243 .has_input_comp = 1,
244 .has_input_svid = 1,
236 }, 245 },
237 .gpio = { 246 .gpio = {
238 .tuner_reset = TM6010_GPIO_0, 247 .tuner_reset = TM6010_GPIO_0,
@@ -245,12 +254,16 @@ struct tm6000_board tm6000_boards[] = {
245 .tuner_type = TUNER_XC5000, 254 .tuner_type = TUNER_XC5000,
246 .tuner_addr = 0xc2 >> 1, 255 .tuner_addr = 0xc2 >> 1,
247 .type = TM6010, 256 .type = TM6010,
257 .avideo = TM6000_AIP_SIF1,
258 .aradio = TM6000_AIP_LINE1,
248 .caps = { 259 .caps = {
249 .has_tuner = 1, 260 .has_tuner = 1,
250 .has_dvb = 0, 261 .has_dvb = 0,
251 .has_zl10353 = 0, 262 .has_zl10353 = 0,
252 .has_eeprom = 1, 263 .has_eeprom = 1,
253 .has_remote = 1, 264 .has_remote = 1,
265 .has_input_comp = 1,
266 .has_input_svid = 1,
254 }, 267 },
255 .gpio = { 268 .gpio = {
256 .tuner_reset = TM6010_GPIO_0, 269 .tuner_reset = TM6010_GPIO_0,
@@ -281,6 +294,11 @@ struct tm6000_board tm6000_boards[] = {
281 }, 294 },
282 .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS, 295 .ir_codes = RC_MAP_NEC_TERRATEC_CINERGY_XS,
283 }, 296 },
297 [TM5600_BOARD_TERRATEC_GRABSTER] = {
298 .name = "Terratec Grabster AV 150/250 MX",
299 .type = TM5600,
300 .tuner_type = TUNER_ABSENT,
301 },
284 [TM6010_BOARD_TWINHAN_TU501] = { 302 [TM6010_BOARD_TWINHAN_TU501] = {
285 .name = "Twinhan TU501(704D1)", 303 .name = "Twinhan TU501(704D1)",
286 .tuner_type = TUNER_XC2028, /* has a XC3028 */ 304 .tuner_type = TUNER_XC2028, /* has a XC3028 */
@@ -303,7 +321,51 @@ struct tm6000_board tm6000_boards[] = {
303 .dvb_led = TM6010_GPIO_5, 321 .dvb_led = TM6010_GPIO_5,
304 .ir = TM6010_GPIO_0, 322 .ir = TM6010_GPIO_0,
305 }, 323 },
306 } 324 },
325 [TM6010_BOARD_BEHOLD_WANDER_LITE] = {
326 .name = "Beholder Wander Lite DVB-T/TV/FM USB2.0",
327 .tuner_type = TUNER_XC5000,
328 .tuner_addr = 0xc2 >> 1,
329 .demod_addr = 0x1e >> 1,
330 .type = TM6010,
331 .avideo = TM6000_AIP_SIF1,
332 .aradio = TM6000_AIP_LINE1,
333 .caps = {
334 .has_tuner = 1,
335 .has_dvb = 1,
336 .has_zl10353 = 1,
337 .has_eeprom = 1,
338 .has_remote = 0,
339 .has_input_comp = 0,
340 .has_input_svid = 0,
341 },
342 .gpio = {
343 .tuner_reset = TM6010_GPIO_0,
344 .demod_reset = TM6010_GPIO_1,
345 .power_led = TM6010_GPIO_6,
346 },
347 },
348 [TM6010_BOARD_BEHOLD_VOYAGER_LITE] = {
349 .name = "Beholder Voyager Lite TV/FM USB2.0",
350 .tuner_type = TUNER_XC5000,
351 .tuner_addr = 0xc2 >> 1,
352 .type = TM6010,
353 .avideo = TM6000_AIP_SIF1,
354 .aradio = TM6000_AIP_LINE1,
355 .caps = {
356 .has_tuner = 1,
357 .has_dvb = 0,
358 .has_zl10353 = 0,
359 .has_eeprom = 1,
360 .has_remote = 0,
361 .has_input_comp = 0,
362 .has_input_svid = 0,
363 },
364 .gpio = {
365 .tuner_reset = TM6010_GPIO_0,
366 .power_led = TM6010_GPIO_6,
367 },
368 },
307}; 369};
308 370
309/* table of devices that work with this driver */ 371/* table of devices that work with this driver */
@@ -321,10 +383,13 @@ struct usb_device_id tm6000_id_table[] = {
321 { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER }, 383 { USB_DEVICE(0x6000, 0xdec1), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER },
322 { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE }, 384 { USB_DEVICE(0x0ccd, 0x0086), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
323 { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE }, 385 { USB_DEVICE(0x0ccd, 0x00A5), .driver_info = TM6010_BOARD_TERRATEC_CINERGY_HYBRID_XE },
386 { USB_DEVICE(0x0ccd, 0x0079), .driver_info = TM5600_BOARD_TERRATEC_GRABSTER },
324 { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 387 { USB_DEVICE(0x13d3, 0x3240), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
325 { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 388 { USB_DEVICE(0x13d3, 0x3241), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
326 { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 389 { USB_DEVICE(0x13d3, 0x3243), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
327 { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 }, 390 { USB_DEVICE(0x13d3, 0x3264), .driver_info = TM6010_BOARD_TWINHAN_TU501 },
391 { USB_DEVICE(0x6000, 0xdec2), .driver_info = TM6010_BOARD_BEHOLD_WANDER_LITE },
392 { USB_DEVICE(0x6000, 0xdec3), .driver_info = TM6010_BOARD_BEHOLD_VOYAGER_LITE },
328 { }, 393 { },
329}; 394};
330 395
@@ -346,6 +411,8 @@ void tm6000_flash_led(struct tm6000_core *dev, u8 state)
346 break; 411 break;
347 case TM6010_BOARD_BEHOLD_WANDER: 412 case TM6010_BOARD_BEHOLD_WANDER:
348 case TM6010_BOARD_BEHOLD_VOYAGER: 413 case TM6010_BOARD_BEHOLD_VOYAGER:
414 case TM6010_BOARD_BEHOLD_WANDER_LITE:
415 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
349 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 416 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
350 dev->gpio.power_led, 0x01); 417 dev->gpio.power_led, 0x01);
351 break; 418 break;
@@ -362,6 +429,8 @@ void tm6000_flash_led(struct tm6000_core *dev, u8 state)
362 break; 429 break;
363 case TM6010_BOARD_BEHOLD_WANDER: 430 case TM6010_BOARD_BEHOLD_WANDER:
364 case TM6010_BOARD_BEHOLD_VOYAGER: 431 case TM6010_BOARD_BEHOLD_VOYAGER:
432 case TM6010_BOARD_BEHOLD_WANDER_LITE:
433 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
365 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 434 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
366 dev->gpio.power_led, 0x00); 435 dev->gpio.power_led, 0x00);
367 break; 436 break;
@@ -520,6 +589,7 @@ int tm6000_cards_setup(struct tm6000_core *dev)
520 msleep(15); 589 msleep(15);
521 break; 590 break;
522 case TM6010_BOARD_BEHOLD_WANDER: 591 case TM6010_BOARD_BEHOLD_WANDER:
592 case TM6010_BOARD_BEHOLD_WANDER_LITE:
523 /* Power led on (blue) */ 593 /* Power led on (blue) */
524 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01); 594 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
525 msleep(15); 595 msleep(15);
@@ -530,6 +600,7 @@ int tm6000_cards_setup(struct tm6000_core *dev)
530 msleep(15); 600 msleep(15);
531 break; 601 break;
532 case TM6010_BOARD_BEHOLD_VOYAGER: 602 case TM6010_BOARD_BEHOLD_VOYAGER:
603 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
533 /* Power led on (blue) */ 604 /* Power led on (blue) */
534 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01); 605 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, dev->gpio.power_led, 0x01);
535 msleep(15); 606 msleep(15);
@@ -588,8 +659,6 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
588 tun_setup.mode_mask = 0; 659 tun_setup.mode_mask = 0;
589 if (dev->caps.has_tuner) 660 if (dev->caps.has_tuner)
590 tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO); 661 tun_setup.mode_mask |= (T_ANALOG_TV | T_RADIO);
591 if (dev->caps.has_dvb)
592 tun_setup.mode_mask |= T_DIGITAL_TV;
593 662
594 switch (dev->tuner_type) { 663 switch (dev->tuner_type) {
595 case TUNER_XC2028: 664 case TUNER_XC2028:
@@ -644,13 +713,12 @@ static void tm6000_config_tuner(struct tm6000_core *dev)
644 struct xc5000_config ctl = { 713 struct xc5000_config ctl = {
645 .i2c_address = dev->tuner_addr, 714 .i2c_address = dev->tuner_addr,
646 .if_khz = 4570, 715 .if_khz = 4570,
647 .radio_input = XC5000_RADIO_FM1, 716 .radio_input = XC5000_RADIO_FM1_MONO,
648 }; 717 };
649 718
650 xc5000_cfg.tuner = TUNER_XC5000; 719 xc5000_cfg.tuner = TUNER_XC5000;
651 xc5000_cfg.priv = &ctl; 720 xc5000_cfg.priv = &ctl;
652 721
653
654 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, 722 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config,
655 &xc5000_cfg); 723 &xc5000_cfg);
656 } 724 }
@@ -683,6 +751,8 @@ static int tm6000_init_dev(struct tm6000_core *dev)
683 751
684 dev->caps = tm6000_boards[dev->model].caps; 752 dev->caps = tm6000_boards[dev->model].caps;
685 753
754 dev->avideo = tm6000_boards[dev->model].avideo;
755 dev->aradio = tm6000_boards[dev->model].aradio;
686 /* initialize hardware */ 756 /* initialize hardware */
687 rc = tm6000_init(dev); 757 rc = tm6000_init(dev);
688 if (rc < 0) 758 if (rc < 0)
@@ -957,6 +1027,8 @@ static void tm6000_usb_disconnect(struct usb_interface *interface)
957 break; 1027 break;
958 case TM6010_BOARD_BEHOLD_WANDER: 1028 case TM6010_BOARD_BEHOLD_WANDER:
959 case TM6010_BOARD_BEHOLD_VOYAGER: 1029 case TM6010_BOARD_BEHOLD_VOYAGER:
1030 case TM6010_BOARD_BEHOLD_WANDER_LITE:
1031 case TM6010_BOARD_BEHOLD_VOYAGER_LITE:
960 /* Power led off */ 1032 /* Power led off */
961 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, 1033 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN,
962 dev->gpio.power_led, 0x00); 1034 dev->gpio.power_led, 0x00);
diff --git a/drivers/staging/tm6000/tm6000-core.c b/drivers/staging/tm6000/tm6000-core.c
index 96aed4ace467..778e53413afb 100644
--- a/drivers/staging/tm6000/tm6000-core.c
+++ b/drivers/staging/tm6000/tm6000-core.c
@@ -116,6 +116,29 @@ int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index)
116} 116}
117EXPORT_SYMBOL_GPL(tm6000_get_reg); 117EXPORT_SYMBOL_GPL(tm6000_get_reg);
118 118
119int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
120 u16 index, u16 mask)
121{
122 int rc;
123 u8 buf[1];
124 u8 new_index;
125
126 rc = tm6000_read_write_usb(dev, USB_DIR_IN | USB_TYPE_VENDOR, req,
127 value, index, buf, 1);
128
129 if (rc < 0)
130 return rc;
131
132 new_index = (buf[0] & ~mask) | (index & mask);
133
134 if (new_index == index)
135 return 0;
136
137 return tm6000_read_write_usb(dev, USB_DIR_OUT | USB_TYPE_VENDOR,
138 req, value, new_index, NULL, 0);
139}
140EXPORT_SYMBOL_GPL(tm6000_set_reg_mask);
141
119int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index) 142int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index)
120{ 143{
121 int rc; 144 int rc;
@@ -245,17 +268,12 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
245 struct v4l2_frequency f; 268 struct v4l2_frequency f;
246 269
247 if (dev->dev_type == TM6010) { 270 if (dev->dev_type == TM6010) {
248 int val;
249
250 /* Enable video */ 271 /* Enable video */
251 val = tm6000_get_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, 0);
252 val |= 0x60;
253 tm6000_set_reg(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF, val);
254 val = tm6000_get_reg(dev,
255 TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0);
256 val &= ~0x40;
257 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, val);
258 272
273 tm6000_set_reg_mask(dev, TM6010_REQ07_RCC_ACTIVE_VIDEO_IF,
274 0x60, 0x60);
275 tm6000_set_reg_mask(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE,
276 0x00, 0x40);
259 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc); 277 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
260 278
261 } else { 279 } else {
@@ -268,11 +286,11 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
268 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80); 286 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x80);
269 287
270 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88); 288 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x88);
271 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23); 289 tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x23);
272 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0); 290 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xc0);
273 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8); 291 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xd8);
274 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06); 292 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x06);
275 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x1f); 293 tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f);
276 294
277 /* AP Software reset */ 295 /* AP Software reset */
278 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); 296 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
@@ -284,8 +302,8 @@ int tm6000_init_analog_mode(struct tm6000_core *dev)
284 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00); 302 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x00);
285 303
286 /* E3: Select input 0 - TV tuner */ 304 /* E3: Select input 0 - TV tuner */
287 tm6000_set_reg(dev, TM6010_REQ07_RE3_OUT_SEL1, 0x00); 305 tm6000_set_reg(dev, TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x00);
288 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x60); 306 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x60);
289 307
290 /* This controls input */ 308 /* This controls input */
291 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0); 309 tm6000_set_reg(dev, REQ_03_SET_GET_MCU_PIN, TM6000_GPIO_2, 0x0);
@@ -344,21 +362,21 @@ int tm6000_init_digital_mode(struct tm6000_core *dev)
344 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08); 362 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x08);
345 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00); 363 tm6000_set_reg(dev, TM6010_REQ07_RFF_SOFT_RESET, 0x00);
346 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01); 364 tm6000_set_reg(dev, TM6010_REQ07_R3F_RESET, 0x01);
347 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x08); 365 tm6000_set_reg(dev, TM6000_REQ07_RDF_PWDOWN_ACLK, 0x08);
348 tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c); 366 tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c);
349 tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff); 367 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff);
350 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0xd8); 368 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0xd8);
351 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40); 369 tm6000_set_reg(dev, TM6010_REQ07_RC0_ACTIVE_VIDEO_SOURCE, 0x40);
352 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0); 370 tm6000_set_reg(dev, TM6010_REQ07_RC1_TRESHOLD, 0xd0);
353 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09); 371 tm6000_set_reg(dev, TM6010_REQ07_RC3_HSTART1, 0x09);
354 tm6000_set_reg(dev, TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x37); 372 tm6000_set_reg(dev, TM6000_REQ07_RDA_CLK_SEL, 0x37);
355 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8); 373 tm6000_set_reg(dev, TM6010_REQ07_RD1_ADDR_FOR_REQ1, 0xd8);
356 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0); 374 tm6000_set_reg(dev, TM6010_REQ07_RD2_ADDR_FOR_REQ2, 0xc0);
357 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60); 375 tm6000_set_reg(dev, TM6010_REQ07_RD6_ENDP_REQ1_REQ2, 0x60);
358 376
359 tm6000_set_reg(dev, TM6010_REQ07_RE2_OUT_SEL2, 0x0c); 377 tm6000_set_reg(dev, TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x0c);
360 tm6000_set_reg(dev, TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0xff); 378 tm6000_set_reg(dev, TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0xff);
361 tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0x00eb, 0x08); 379 tm6000_set_reg(dev, TM6000_REQ07_REB_VADC_AADC_MODE, 0x08);
362 msleep(50); 380 msleep(50);
363 381
364 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00); 382 tm6000_set_reg(dev, REQ_04_EN_DISABLE_MCU_INT, 0x0020, 0x00);
@@ -388,18 +406,19 @@ struct reg_init {
388/* The meaning of those initializations are unknown */ 406/* The meaning of those initializations are unknown */
389struct reg_init tm6000_init_tab[] = { 407struct reg_init tm6000_init_tab[] = {
390 /* REG VALUE */ 408 /* REG VALUE */
391 { TM6010_REQ07_RD8_IR_PULSE_CNT0, 0x1f }, 409 { TM6000_REQ07_RDF_PWDOWN_ACLK, 0x1f },
392 { TM6010_REQ07_RFF_SOFT_RESET, 0x08 }, 410 { TM6010_REQ07_RFF_SOFT_RESET, 0x08 },
393 { TM6010_REQ07_RFF_SOFT_RESET, 0x00 }, 411 { TM6010_REQ07_RFF_SOFT_RESET, 0x00 },
394 { TM6010_REQ07_RD5_POWERSAVE, 0x4f }, 412 { TM6010_REQ07_RD5_POWERSAVE, 0x4f },
395 { TM6010_REQ07_RD8_IR_WAKEUP_SEL, 0x23 }, 413 { TM6000_REQ07_RDA_CLK_SEL, 0x23 },
396 { TM6010_REQ07_RD8_IR_WAKEUP_ADD, 0x08 }, 414 { TM6000_REQ07_RDB_OUT_SEL, 0x08 },
397 { TM6010_REQ07_RE2_OUT_SEL2, 0x00 }, 415 { TM6000_REQ07_RE2_VADC_STATUS_CTL, 0x00 },
398 { TM6010_REQ07_RE3_OUT_SEL1, 0x10 }, 416 { TM6000_REQ07_RE3_VADC_INP_LPF_SEL1, 0x10 },
399 { TM6010_REQ07_RE5_REMOTE_WAKEUP, 0x00 }, 417 { TM6000_REQ07_RE5_VADC_INP_LPF_SEL2, 0x00 },
400 { TM6010_REQ07_RE8_TYPESEL_MOS_I2S, 0x00 }, 418 { TM6000_REQ07_RE8_VADC_PWDOWN_CTL, 0x00 },
401 { REQ_07_SET_GET_AVREG, 0xeb, 0x64 }, /* 48000 bits/sample, external input */ 419 { TM6000_REQ07_REB_VADC_AADC_MODE, 0x64 }, /* 48000 bits/sample, external input */
402 { REQ_07_SET_GET_AVREG, 0xee, 0xc2 }, 420 { TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL, 0xc2 },
421
403 { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */ 422 { TM6010_REQ07_R3F_RESET, 0x01 }, /* Start of soft reset */
404 { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 }, 423 { TM6010_REQ07_R00_VIDEO_CONTROL0, 0x00 },
405 { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 }, 424 { TM6010_REQ07_R01_VIDEO_CONTROL1, 0x07 },
@@ -470,6 +489,14 @@ struct reg_init tm6010_init_tab[] = {
470 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 }, 489 { TM6010_REQ08_REB_SIF_GAIN_CTRL, 0xf0 },
471 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 }, 490 { TM6010_REQ08_REC_REVERSE_YC_CTRL, 0xc2 },
472 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 }, 491 { TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG, 0x60 },
492 { TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00},
493 { TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80},
494 { TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a},
495 { TM6010_REQ08_R0D_A_AMD_THRES, 0x40},
496 { TM6010_REQ08_R1A_A_NICAM_SER_MAX, 0x64},
497 { TM6010_REQ08_R1B_A_NICAM_SER_MIN, 0x20},
498 { TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe},
499 { TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01},
473 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc }, 500 { TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc },
474 501
475 { TM6010_REQ07_R3F_RESET, 0x01 }, 502 { TM6010_REQ07_R3F_RESET, 0x01 },
@@ -590,38 +617,213 @@ int tm6000_init(struct tm6000_core *dev)
590 617
591int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate) 618int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate)
592{ 619{
593 int val; 620 int val = 0;
621 u8 areg_f0 = 0x60; /* ADC MCLK = 250 Fs */
622 u8 areg_0a = 0x91; /* SIF 48KHz */
594 623
624 switch (bitrate) {
625 case 48000:
626 areg_f0 = 0x60; /* ADC MCLK = 250 Fs */
627 areg_0a = 0x91; /* SIF 48KHz */
628 dev->audio_bitrate = bitrate;
629 break;
630 case 32000:
631 areg_f0 = 0x00; /* ADC MCLK = 375 Fs */
632 areg_0a = 0x90; /* SIF 32KHz */
633 dev->audio_bitrate = bitrate;
634 break;
635 default:
636 return -EINVAL;
637 }
638
639
640 /* enable I2S, if we use sif or external I2S device */
595 if (dev->dev_type == TM6010) { 641 if (dev->dev_type == TM6010) {
596 val = tm6000_get_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0); 642 val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, areg_0a);
597 if (val < 0) 643 if (val < 0)
598 return val; 644 return val;
599 val = (val & 0xf0) | 0x1; /* 48 kHz, not muted */ 645
600 val = tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, val); 646 val = tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
647 areg_f0, 0xf0);
648 if (val < 0)
649 return val;
650 } else {
651 val = tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE,
652 areg_f0, 0xf0);
601 if (val < 0) 653 if (val < 0)
602 return val; 654 return val;
603 } 655 }
656 return 0;
657}
658EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate);
604 659
605 val = tm6000_get_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, 0x0); 660int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp)
606 if (val < 0) 661{
607 return val; 662 if (dev->dev_type == TM6010) {
663 /* Audio crossbar setting, default SIF1 */
664 u8 areg_f0 = 0x03;
608 665
609 val &= 0x0f; /* Preserve the audio input control bits */ 666 switch (ainp) {
610 switch (bitrate) { 667 case TM6000_AIP_SIF1:
611 case 44100: 668 case TM6000_AIP_SIF2:
612 val |= 0xd0; 669 areg_f0 = 0x03;
613 dev->audio_bitrate = bitrate; 670 break;
671 case TM6000_AIP_LINE1:
672 areg_f0 = 0x00;
673 break;
674 case TM6000_AIP_LINE2:
675 areg_f0 = 0x08;
676 break;
677 default:
678 return 0;
679 break;
680 }
681 /* Set audio input crossbar */
682 tm6000_set_reg_mask(dev, TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG,
683 areg_f0, 0x0f);
684 } else {
685 /* Audio setting, default LINE1 */
686 u8 areg_eb = 0x00;
687
688 switch (ainp) {
689 case TM6000_AIP_LINE1:
690 areg_eb = 0x00;
691 break;
692 case TM6000_AIP_LINE2:
693 areg_eb = 0x04;
694 break;
695 default:
696 return 0;
697 break;
698 }
699 /* Set audio input */
700 tm6000_set_reg_mask(dev, TM6000_REQ07_REB_VADC_AADC_MODE,
701 areg_eb, 0x0f);
702 }
703 return 0;
704}
705EXPORT_SYMBOL_GPL(tm6000_set_audio_input);
706
707void tm6010_set_mute_sif(struct tm6000_core *dev, u8 mute)
708{
709 u8 mute_reg = 0;
710
711 if (mute)
712 mute_reg = 0x08;
713
714 tm6000_set_reg_mask(dev, TM6010_REQ08_R0A_A_I2S_MOD, mute_reg, 0x08);
715}
716
717void tm6010_set_mute_adc(struct tm6000_core *dev, u8 mute)
718{
719 u8 mute_reg = 0;
720
721 if (mute)
722 mute_reg = 0x20;
723
724 if (dev->dev_type == TM6010) {
725 tm6000_set_reg_mask(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL,
726 mute_reg, 0x20);
727 tm6000_set_reg_mask(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL,
728 mute_reg, 0x20);
729 } else {
730 tm6000_set_reg_mask(dev, TM6000_REQ07_REC_VADC_AADC_LVOL,
731 mute_reg, 0x20);
732 tm6000_set_reg_mask(dev, TM6000_REQ07_RED_VADC_AADC_RVOL,
733 mute_reg, 0x20);
734 }
735}
736
737int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute)
738{
739 enum tm6000_inaudio ainp;
740
741 if (dev->radio)
742 ainp = dev->aradio;
743 else
744 ainp = dev->avideo;
745
746 switch (ainp) {
747 case TM6000_AIP_SIF1:
748 case TM6000_AIP_SIF2:
749 if (dev->dev_type == TM6010)
750 tm6010_set_mute_sif(dev, mute);
751 else {
752 printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has"
753 " SIF audio inputs. Please check the %s"
754 " configuration.\n", dev->name);
755 return -EINVAL;
756 }
614 break; 757 break;
615 case 48000: 758 case TM6000_AIP_LINE1:
616 val |= 0x60; 759 case TM6000_AIP_LINE2:
617 dev->audio_bitrate = bitrate; 760 tm6010_set_mute_adc(dev, mute);
761 break;
762 default:
763 return -EINVAL;
618 break; 764 break;
619 } 765 }
620 val = tm6000_set_reg(dev, REQ_07_SET_GET_AVREG, 0xeb, val); 766 return 0;
767}
768EXPORT_SYMBOL_GPL(tm6000_tvaudio_set_mute);
769
770void tm6010_set_volume_sif(struct tm6000_core *dev, int vol)
771{
772 u8 vol_reg;
773
774 vol_reg = vol & 0x0F;
775
776 if (vol < 0)
777 vol_reg |= 0x40;
778
779 tm6000_set_reg(dev, TM6010_REQ08_R07_A_LEFT_VOL, vol_reg);
780 tm6000_set_reg(dev, TM6010_REQ08_R08_A_RIGHT_VOL, vol_reg);
781}
782
783void tm6010_set_volume_adc(struct tm6000_core *dev, int vol)
784{
785 u8 vol_reg;
786
787 vol_reg = (vol + 0x10) & 0x1f;
788
789 if (dev->dev_type == TM6010) {
790 tm6000_set_reg(dev, TM6010_REQ08_RF2_LEFT_CHANNEL_VOL, vol_reg);
791 tm6000_set_reg(dev, TM6010_REQ08_RF3_RIGHT_CHANNEL_VOL, vol_reg);
792 } else {
793 tm6000_set_reg(dev, TM6000_REQ07_REC_VADC_AADC_LVOL, vol_reg);
794 tm6000_set_reg(dev, TM6000_REQ07_RED_VADC_AADC_RVOL, vol_reg);
795 }
796}
797
798void tm6000_set_volume(struct tm6000_core *dev, int vol)
799{
800 enum tm6000_inaudio ainp;
801
802 if (dev->radio) {
803 ainp = dev->aradio;
804 vol += 8; /* Offset to 0 dB */
805 } else
806 ainp = dev->avideo;
621 807
622 return val; 808 switch (ainp) {
809 case TM6000_AIP_SIF1:
810 case TM6000_AIP_SIF2:
811 if (dev->dev_type == TM6010)
812 tm6010_set_volume_sif(dev, vol);
813 else
814 printk(KERN_INFO "ERROR: TM5600 and TM6000 don't has"
815 " SIF audio inputs. Please check the %s"
816 " configuration.\n", dev->name);
817 break;
818 case TM6000_AIP_LINE1:
819 case TM6000_AIP_LINE2:
820 tm6010_set_volume_adc(dev, vol);
821 break;
822 default:
823 break;
824 }
623} 825}
624EXPORT_SYMBOL_GPL(tm6000_set_audio_bitrate); 826EXPORT_SYMBOL_GPL(tm6000_set_volume);
625 827
626static LIST_HEAD(tm6000_devlist); 828static LIST_HEAD(tm6000_devlist);
627static DEFINE_MUTEX(tm6000_devlist_mutex); 829static DEFINE_MUTEX(tm6000_devlist_mutex);
diff --git a/drivers/staging/tm6000/tm6000-regs.h b/drivers/staging/tm6000/tm6000-regs.h
index 1f0ced8fa20f..5375a8347374 100644
--- a/drivers/staging/tm6000/tm6000-regs.h
+++ b/drivers/staging/tm6000/tm6000-regs.h
@@ -97,6 +97,34 @@ enum {
97 TM6000_URB_MSG_ERR, 97 TM6000_URB_MSG_ERR,
98}; 98};
99 99
100/* Define specific TM6000 Video decoder registers */
101#define TM6000_REQ07_RD8_TEST_SEL 0x07, 0xd8
102#define TM6000_REQ07_RD9_A_SIM_SEL 0x07, 0xd9
103#define TM6000_REQ07_RDA_CLK_SEL 0x07, 0xda
104#define TM6000_REQ07_RDB_OUT_SEL 0x07, 0xdb
105#define TM6000_REQ07_RDC_NSEL_I2S 0x07, 0xdc
106#define TM6000_REQ07_RDD_GPIO2_MDRV 0x07, 0xdd
107#define TM6000_REQ07_RDE_GPIO1_MDRV 0x07, 0xde
108#define TM6000_REQ07_RDF_PWDOWN_ACLK 0x07, 0xdf
109#define TM6000_REQ07_RE0_VADC_REF_CTL 0x07, 0xe0
110#define TM6000_REQ07_RE1_VADC_DACLIMP 0x07, 0xe1
111#define TM6000_REQ07_RE2_VADC_STATUS_CTL 0x07, 0xe2
112#define TM6000_REQ07_RE3_VADC_INP_LPF_SEL1 0x07, 0xe3
113#define TM6000_REQ07_RE4_VADC_TARGET1 0x07, 0xe4
114#define TM6000_REQ07_RE5_VADC_INP_LPF_SEL2 0x07, 0xe5
115#define TM6000_REQ07_RE6_VADC_TARGET2 0x07, 0xe6
116#define TM6000_REQ07_RE7_VADC_AGAIN_CTL 0x07, 0xe7
117#define TM6000_REQ07_RE8_VADC_PWDOWN_CTL 0x07, 0xe8
118#define TM6000_REQ07_RE9_VADC_INPUT_CTL1 0x07, 0xe9
119#define TM6000_REQ07_REA_VADC_INPUT_CTL2 0x07, 0xea
120#define TM6000_REQ07_REB_VADC_AADC_MODE 0x07, 0xeb
121#define TM6000_REQ07_REC_VADC_AADC_LVOL 0x07, 0xec
122#define TM6000_REQ07_RED_VADC_AADC_RVOL 0x07, 0xed
123#define TM6000_REQ07_REE_VADC_CTRL_SEL_CONTROL 0x07, 0xee
124#define TM6000_REQ07_REF_VADC_GAIN_MAP_CTL 0x07, 0xef
125#define TM6000_REQ07_RFD_BIST_ERR_VST_LOW 0x07, 0xfd
126#define TM6000_REQ07_RFE_BIST_ERR_VST_HIGH 0x07, 0xfe
127
100/* Define TM6000/TM6010 Video decoder registers */ 128/* Define TM6000/TM6010 Video decoder registers */
101#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00 129#define TM6010_REQ07_R00_VIDEO_CONTROL0 0x07, 0x00
102#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01 130#define TM6010_REQ07_R01_VIDEO_CONTROL1 0x07, 0x01
@@ -241,6 +269,7 @@ enum {
241#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9 269#define TM6010_REQ07_RC9_VEND1 0x07, 0xc9
242#define TM6010_REQ07_RCA_VEND0 0x07, 0xca 270#define TM6010_REQ07_RCA_VEND0 0x07, 0xca
243#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb 271#define TM6010_REQ07_RCB_DELAY 0x07, 0xcb
272/* ONLY for TM6010 */
244#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF 0x07, 0xcc 273#define TM6010_REQ07_RCC_ACTIVE_VIDEO_IF 0x07, 0xcc
245#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0 274#define TM6010_REQ07_RD0_USB_PERIPHERY_CONTROL 0x07, 0xd0
246#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1 275#define TM6010_REQ07_RD1_ADDR_FOR_REQ1 0x07, 0xd1
@@ -250,32 +279,59 @@ enum {
250#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5 279#define TM6010_REQ07_RD5_POWERSAVE 0x07, 0xd5
251#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6 280#define TM6010_REQ07_RD6_ENDP_REQ1_REQ2 0x07, 0xd6
252#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7 281#define TM6010_REQ07_RD7_ENDP_REQ3_REQ4 0x07, 0xd7
282/* ONLY for TM6010 */
253#define TM6010_REQ07_RD8_IR 0x07, 0xd8 283#define TM6010_REQ07_RD8_IR 0x07, 0xd8
284/* ONLY for TM6010 */
254#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9 285#define TM6010_REQ07_RD8_IR_BSIZE 0x07, 0xd9
286/* ONLY for TM6010 */
255#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda 287#define TM6010_REQ07_RD8_IR_WAKEUP_SEL 0x07, 0xda
288/* ONLY for TM6010 */
256#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb 289#define TM6010_REQ07_RD8_IR_WAKEUP_ADD 0x07, 0xdb
290/* ONLY for TM6010 */
257#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc 291#define TM6010_REQ07_RD8_IR_LEADER1 0x07, 0xdc
292/* ONLY for TM6010 */
258#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd 293#define TM6010_REQ07_RD8_IR_LEADER0 0x07, 0xdd
294/* ONLY for TM6010 */
259#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde 295#define TM6010_REQ07_RD8_IR_PULSE_CNT1 0x07, 0xde
296/* ONLY for TM6010 */
260#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf 297#define TM6010_REQ07_RD8_IR_PULSE_CNT0 0x07, 0xdf
298/* ONLY for TM6010 */
261#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0 299#define TM6010_REQ07_RE0_DVIDEO_SOURCE 0x07, 0xe0
300/* ONLY for TM6010 */
262#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1 301#define TM6010_REQ07_RE0_DVIDEO_SOURCE_IF 0x07, 0xe1
302/* ONLY for TM6010 */
263#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2 303#define TM6010_REQ07_RE2_OUT_SEL2 0x07, 0xe2
304/* ONLY for TM6010 */
264#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3 305#define TM6010_REQ07_RE3_OUT_SEL1 0x07, 0xe3
306/* ONLY for TM6010 */
265#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4 307#define TM6010_REQ07_RE4_OUT_SEL0 0x07, 0xe4
308/* ONLY for TM6010 */
266#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5 309#define TM6010_REQ07_RE5_REMOTE_WAKEUP 0x07, 0xe5
310/* ONLY for TM6010 */
267#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7 311#define TM6010_REQ07_RE7_PUB_GPIO 0x07, 0xe7
312/* ONLY for TM6010 */
268#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8 313#define TM6010_REQ07_RE8_TYPESEL_MOS_I2S 0x07, 0xe8
314/* ONLY for TM6010 */
269#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9 315#define TM6010_REQ07_RE9_TYPESEL_MOS_TS 0x07, 0xe9
316/* ONLY for TM6010 */
270#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea 317#define TM6010_REQ07_REA_TYPESEL_MOS_CCIR 0x07, 0xea
318/* ONLY for TM6010 */
271#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0 319#define TM6010_REQ07_RF0_BIST_CRC_RESULT0 0x07, 0xf0
320/* ONLY for TM6010 */
272#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1 321#define TM6010_REQ07_RF1_BIST_CRC_RESULT1 0x07, 0xf1
322/* ONLY for TM6010 */
273#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2 323#define TM6010_REQ07_RF2_BIST_CRC_RESULT2 0x07, 0xf2
324/* ONLY for TM6010 */
274#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3 325#define TM6010_REQ07_RF3_BIST_CRC_RESULT3 0x07, 0xf3
326/* ONLY for TM6010 */
275#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4 327#define TM6010_REQ07_RF4_BIST_ERR_VST2 0x07, 0xf4
328/* ONLY for TM6010 */
276#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5 329#define TM6010_REQ07_RF5_BIST_ERR_VST1 0x07, 0xf5
330/* ONLY for TM6010 */
277#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6 331#define TM6010_REQ07_RF6_BIST_ERR_VST0 0x07, 0xf6
332/* ONLY for TM6010 */
278#define TM6010_REQ07_RF7_BIST 0x07, 0xf7 333#define TM6010_REQ07_RF7_BIST 0x07, 0xf7
334/* ONLY for TM6010 */
279#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe 335#define TM6010_REQ07_RFE_POWER_DOWN 0x07, 0xfe
280#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff 336#define TM6010_REQ07_RFF_SOFT_RESET 0x07, 0xff
281 337
@@ -477,7 +533,8 @@ enum {
477#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8 533#define TM6010_REQ05_RC4_DATA_FIFO14 0x05, 0xf8
478#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc 534#define TM6010_REQ05_RC4_DATA_FIFO15 0x05, 0xfc
479 535
480/* Define TM6000/TM6010 Audio decoder registers */ 536/* Define TM6010 Audio decoder registers */
537/* This core available only in TM6010 */
481#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00 538#define TM6010_REQ08_R00_A_VERSION 0x08, 0x00
482#define TM6010_REQ08_R01_A_INIT 0x08, 0x01 539#define TM6010_REQ08_R01_A_INIT 0x08, 0x01
483#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02 540#define TM6010_REQ08_R02_A_FIX_GAIN_CTRL 0x08, 0x02
@@ -518,7 +575,7 @@ enum {
518#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27 575#define TM6010_REQ08_R27_A_NOISE_AMP 0x08, 0x27
519#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28 576#define TM6010_REQ08_R28_A_AUDIO_MODE_RES 0x08, 0x28
520 577
521/* Define TM6000/TM6010 Video ADC registers */ 578/* Define TM6010 Video ADC registers */
522#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0 579#define TM6010_REQ08_RE0_ADC_REF 0x08, 0xe0
523#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1 580#define TM6010_REQ08_RE1_DAC_CLMP 0x08, 0xe1
524#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2 581#define TM6010_REQ08_RE2_POWER_DOWN_CTRL1 0x08, 0xe2
@@ -534,7 +591,7 @@ enum {
534#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec 591#define TM6010_REQ08_REC_REVERSE_YC_CTRL 0x08, 0xec
535#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed 592#define TM6010_REQ08_RED_GAIN_SEL 0x08, 0xed
536 593
537/* Define TM6000/TM6010 Audio ADC registers */ 594/* Define TM6010 Audio ADC registers */
538#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0 595#define TM6010_REQ08_RF0_DAUDIO_INPUT_CONFIG 0x08, 0xf0
539#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1 596#define TM6010_REQ08_RF1_AADC_POWER_DOWN 0x08, 0xf1
540#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2 597#define TM6010_REQ08_RF2_LEFT_CHANNEL_VOL 0x08, 0xf2
diff --git a/drivers/staging/tm6000/tm6000-stds.c b/drivers/staging/tm6000/tm6000-stds.c
index cc7b8664fc20..da3e51bde109 100644
--- a/drivers/staging/tm6000/tm6000-stds.c
+++ b/drivers/staging/tm6000/tm6000-stds.c
@@ -952,6 +952,22 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
952 uint8_t mono_flag = 0; /* No mono */ 952 uint8_t mono_flag = 0; /* No mono */
953 uint8_t nicam_flag = 0; /* No NICAM */ 953 uint8_t nicam_flag = 0; /* No NICAM */
954 954
955 if (dev->radio) {
956 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
957 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
958 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
959 tm6000_set_reg(dev, TM6010_REQ08_R04_A_SIF_AMP_CTRL, 0x80);
960 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
961 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
962 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
963 tm6000_set_reg(dev, TM6010_REQ08_R0C_A_ASD_THRES2, 0x0a);
964 tm6000_set_reg(dev, TM6010_REQ08_R0D_A_AMD_THRES, 0x40);
965 tm6000_set_reg(dev, TM6010_REQ08_RF1_AADC_POWER_DOWN, 0xfc);
966 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
967 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
968 return 0;
969 }
970
955 switch (std) { 971 switch (std) {
956#if 0 972#if 0
957 case DK_MONO: 973 case DK_MONO:
@@ -984,20 +1000,6 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
984 case EIAJ: 1000 case EIAJ:
985 areg_05 = 0x02; 1001 areg_05 = 0x02;
986 break; 1002 break;
987 case FM_RADIO:
988 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x00);
989 tm6000_set_reg(dev, TM6010_REQ08_R02_A_FIX_GAIN_CTRL, 0x04);
990 tm6000_set_reg(dev, TM6010_REQ08_R03_A_AUTO_GAIN_CTRL, 0x00);
991 tm6000_set_reg(dev, TM6010_REQ08_R05_A_STANDARD_MOD, 0x0c);
992 tm6000_set_reg(dev, TM6010_REQ08_R06_A_SOUND_MOD, 0x00);
993 tm6000_set_reg(dev, TM6010_REQ08_R09_A_MAIN_VOL, 0x18);
994 tm6000_set_reg(dev, TM6010_REQ08_R0A_A_I2S_MOD, 0x91);
995 tm6000_set_reg(dev, TM6010_REQ08_R16_A_AGC_GAIN_MAX, 0xfe);
996 tm6000_set_reg(dev, TM6010_REQ08_R17_A_AGC_GAIN_MIN, 0x01);
997 tm6000_set_reg(dev, TM6010_REQ08_R1E_A_GAIN_DEEMPH_OUT, 0x13);
998 tm6000_set_reg(dev, TM6010_REQ08_R01_A_INIT, 0x80);
999 return 0;
1000 break;
1001 case I_NICAM: 1003 case I_NICAM:
1002 areg_05 = 0x08; 1004 areg_05 = 0x08;
1003 nicam_flag = 1; 1005 nicam_flag = 1;
@@ -1010,6 +1012,9 @@ static int tm6000_set_audio_std(struct tm6000_core *dev,
1010 areg_05 = 0x0a; 1012 areg_05 = 0x0a;
1011 nicam_flag = 1; 1013 nicam_flag = 1;
1012 break; 1014 break;
1015 default:
1016 /* do nothink */
1017 break;
1013 } 1018 }
1014 1019
1015#if 0 1020#if 0
@@ -1156,8 +1161,6 @@ int tm6000_set_standard(struct tm6000_core *dev, v4l2_std_id * norm)
1156 rc = tm6000_load_std(dev, svideo_stds[i].common, 1161 rc = tm6000_load_std(dev, svideo_stds[i].common,
1157 sizeof(svideo_stds[i]. 1162 sizeof(svideo_stds[i].
1158 common)); 1163 common));
1159 tm6000_set_audio_std(dev, svideo_stds[i].audio_default_std);
1160
1161 goto ret; 1164 goto ret;
1162 } 1165 }
1163 } 1166 }
diff --git a/drivers/staging/tm6000/tm6000-video.c b/drivers/staging/tm6000/tm6000-video.c
index eb9b9f1bc138..c80a316d9d8f 100644
--- a/drivers/staging/tm6000/tm6000-video.c
+++ b/drivers/staging/tm6000/tm6000-video.c
@@ -53,11 +53,17 @@
53/* Declare static vars that will be used as parameters */ 53/* Declare static vars that will be used as parameters */
54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */ 54static unsigned int vid_limit = 16; /* Video memory limit, in Mb */
55static int video_nr = -1; /* /dev/videoN, -1 for autodetect */ 55static int video_nr = -1; /* /dev/videoN, -1 for autodetect */
56static int radio_nr = -1; /* /dev/radioN, -1 for autodetect */
56 57
57/* Debug level */ 58/* Debug level */
58int tm6000_debug; 59int tm6000_debug;
59EXPORT_SYMBOL_GPL(tm6000_debug); 60EXPORT_SYMBOL_GPL(tm6000_debug);
60 61
62static const struct v4l2_queryctrl no_ctrl = {
63 .name = "42",
64 .flags = V4L2_CTRL_FLAG_DISABLED,
65};
66
61/* supported controls */ 67/* supported controls */
62static struct v4l2_queryctrl tm6000_qctrl[] = { 68static struct v4l2_queryctrl tm6000_qctrl[] = {
63 { 69 {
@@ -96,9 +102,26 @@ static struct v4l2_queryctrl tm6000_qctrl[] = {
96 .step = 0x1, 102 .step = 0x1,
97 .default_value = 0, 103 .default_value = 0,
98 .flags = 0, 104 .flags = 0,
105 },
106 /* --- audio --- */
107 {
108 .id = V4L2_CID_AUDIO_MUTE,
109 .name = "Mute",
110 .minimum = 0,
111 .maximum = 1,
112 .type = V4L2_CTRL_TYPE_BOOLEAN,
113 }, {
114 .id = V4L2_CID_AUDIO_VOLUME,
115 .name = "Volume",
116 .minimum = -15,
117 .maximum = 15,
118 .step = 1,
119 .default_value = 0,
120 .type = V4L2_CTRL_TYPE_INTEGER,
99 } 121 }
100}; 122};
101 123
124static const unsigned int CTRLS = ARRAY_SIZE(tm6000_qctrl);
102static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)]; 125static int qctl_regs[ARRAY_SIZE(tm6000_qctrl)];
103 126
104static struct tm6000_fmt format[] = { 127static struct tm6000_fmt format[] = {
@@ -117,6 +140,16 @@ static struct tm6000_fmt format[] = {
117 } 140 }
118}; 141};
119 142
143static const struct v4l2_queryctrl *ctrl_by_id(unsigned int id)
144{
145 unsigned int i;
146
147 for (i = 0; i < CTRLS; i++)
148 if (tm6000_qctrl[i].id == id)
149 return tm6000_qctrl+i;
150 return NULL;
151}
152
120/* ------------------------------------------------------------------ 153/* ------------------------------------------------------------------
121 * DMA and thread functions 154 * DMA and thread functions
122 * ------------------------------------------------------------------ 155 * ------------------------------------------------------------------
@@ -199,13 +232,17 @@ static int copy_streams(u8 *data, unsigned long len,
199 char *voutp = NULL; 232 char *voutp = NULL;
200 unsigned int linewidth; 233 unsigned int linewidth;
201 234
202 /* get video buffer */ 235 if (!dev->radio) {
203 get_next_buf(dma_q, &vbuf); 236 /* get video buffer */
204 if (!vbuf) 237 get_next_buf(dma_q, &vbuf);
205 return rc; 238
206 voutp = videobuf_to_vmalloc(&vbuf->vb); 239 if (!vbuf)
207 if (!voutp) 240 return rc;
208 return 0; 241 voutp = videobuf_to_vmalloc(&vbuf->vb);
242
243 if (!voutp)
244 return 0;
245 }
209 246
210 for (ptr = data; ptr < endp;) { 247 for (ptr = data; ptr < endp;) {
211 if (!dev->isoc_ctl.cmd) { 248 if (!dev->isoc_ctl.cmd) {
@@ -257,29 +294,31 @@ static int copy_streams(u8 *data, unsigned long len,
257 */ 294 */
258 switch (cmd) { 295 switch (cmd) {
259 case TM6000_URB_MSG_VIDEO: 296 case TM6000_URB_MSG_VIDEO:
260 if ((dev->isoc_ctl.vfield != field) && 297 if (!dev->radio) {
261 (field == 1)) { 298 if ((dev->isoc_ctl.vfield != field) &&
299 (field == 1)) {
262 /* Announces that a new buffer 300 /* Announces that a new buffer
263 * were filled 301 * were filled
264 */ 302 */
265 buffer_filled(dev, dma_q, vbuf); 303 buffer_filled(dev, dma_q, vbuf);
266 dprintk(dev, V4L2_DEBUG_ISOC, 304 dprintk(dev, V4L2_DEBUG_ISOC,
267 "new buffer filled\n"); 305 "new buffer filled\n");
268 get_next_buf(dma_q, &vbuf); 306 get_next_buf(dma_q, &vbuf);
269 if (!vbuf) 307 if (!vbuf)
270 return rc; 308 return rc;
271 voutp = videobuf_to_vmalloc(&vbuf->vb); 309 voutp = videobuf_to_vmalloc(&vbuf->vb);
272 if (!voutp) 310 if (!voutp)
273 return rc; 311 return rc;
274 memset(voutp, 0, vbuf->vb.size); 312 memset(voutp, 0, vbuf->vb.size);
275 } 313 }
276 linewidth = vbuf->vb.width << 1; 314 linewidth = vbuf->vb.width << 1;
277 pos = ((line << 1) - field - 1) * linewidth + 315 pos = ((line << 1) - field - 1) *
278 block * TM6000_URB_MSG_LEN; 316 linewidth + block * TM6000_URB_MSG_LEN;
279 /* Don't allow to write out of the buffer */ 317 /* Don't allow to write out of the buffer */
280 if (pos + size > vbuf->vb.size) 318 if (pos + size > vbuf->vb.size)
281 cmd = TM6000_URB_MSG_ERR; 319 cmd = TM6000_URB_MSG_ERR;
282 dev->isoc_ctl.vfield = field; 320 dev->isoc_ctl.vfield = field;
321 }
283 break; 322 break;
284 case TM6000_URB_MSG_VBI: 323 case TM6000_URB_MSG_VBI:
285 break; 324 break;
@@ -537,7 +576,7 @@ static void tm6000_uninit_isoc(struct tm6000_core *dev)
537/* 576/*
538 * Allocate URBs and start IRQ 577 * Allocate URBs and start IRQ
539 */ 578 */
540static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize) 579static int tm6000_prepare_isoc(struct tm6000_core *dev)
541{ 580{
542 struct tm6000_dmaqueue *dma_q = &dev->vidq; 581 struct tm6000_dmaqueue *dma_q = &dev->vidq;
543 int i, j, sb_size, pipe, size, max_packets, num_bufs = 8; 582 int i, j, sb_size, pipe, size, max_packets, num_bufs = 8;
@@ -566,11 +605,7 @@ static int tm6000_prepare_isoc(struct tm6000_core *dev, unsigned int framesize)
566 605
567 dev->isoc_ctl.max_pkt_size = size; 606 dev->isoc_ctl.max_pkt_size = size;
568 607
569 max_packets = (framesize + size - 1) / size; 608 max_packets = TM6000_MAX_ISO_PACKETS;
570
571 if (max_packets > TM6000_MAX_ISO_PACKETS)
572 max_packets = TM6000_MAX_ISO_PACKETS;
573
574 sb_size = max_packets * size; 609 sb_size = max_packets * size;
575 610
576 dev->isoc_ctl.num_bufs = num_bufs; 611 dev->isoc_ctl.num_bufs = num_bufs;
@@ -746,7 +781,7 @@ buffer_prepare(struct videobuf_queue *vq, struct videobuf_buffer *vb,
746 urb_init = 1; 781 urb_init = 1;
747 782
748 if (urb_init) { 783 if (urb_init) {
749 rc = tm6000_prepare_isoc(dev, buf->vb.size); 784 rc = tm6000_prepare_isoc(dev);
750 if (rc < 0) 785 if (rc < 0)
751 goto fail; 786 goto fail;
752 787
@@ -1045,18 +1080,27 @@ static int vidioc_s_std (struct file *file, void *priv, v4l2_std_id *norm)
1045static int vidioc_enum_input(struct file *file, void *priv, 1080static int vidioc_enum_input(struct file *file, void *priv,
1046 struct v4l2_input *inp) 1081 struct v4l2_input *inp)
1047{ 1082{
1083 struct tm6000_fh *fh = priv;
1084 struct tm6000_core *dev = fh->dev;
1085
1048 switch (inp->index) { 1086 switch (inp->index) {
1049 case TM6000_INPUT_TV: 1087 case TM6000_INPUT_TV:
1050 inp->type = V4L2_INPUT_TYPE_TUNER; 1088 inp->type = V4L2_INPUT_TYPE_TUNER;
1051 strcpy(inp->name, "Television"); 1089 strcpy(inp->name, "Television");
1052 break; 1090 break;
1053 case TM6000_INPUT_COMPOSITE: 1091 case TM6000_INPUT_COMPOSITE:
1054 inp->type = V4L2_INPUT_TYPE_CAMERA; 1092 if (dev->caps.has_input_comp) {
1055 strcpy(inp->name, "Composite"); 1093 inp->type = V4L2_INPUT_TYPE_CAMERA;
1094 strcpy(inp->name, "Composite");
1095 } else
1096 return -EINVAL;
1056 break; 1097 break;
1057 case TM6000_INPUT_SVIDEO: 1098 case TM6000_INPUT_SVIDEO:
1058 inp->type = V4L2_INPUT_TYPE_CAMERA; 1099 if (dev->caps.has_input_svid) {
1059 strcpy(inp->name, "S-Video"); 1100 inp->type = V4L2_INPUT_TYPE_CAMERA;
1101 strcpy(inp->name, "S-Video");
1102 } else
1103 return -EINVAL;
1060 break; 1104 break;
1061 default: 1105 default:
1062 return -EINVAL; 1106 return -EINVAL;
@@ -1143,6 +1187,12 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
1143 case V4L2_CID_HUE: 1187 case V4L2_CID_HUE:
1144 val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0); 1188 val = tm6000_get_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, 0);
1145 return 0; 1189 return 0;
1190 case V4L2_CID_AUDIO_MUTE:
1191 val = dev->ctl_mute;
1192 return 0;
1193 case V4L2_CID_AUDIO_VOLUME:
1194 val = dev->ctl_volume;
1195 return 0;
1146 default: 1196 default:
1147 return -EINVAL; 1197 return -EINVAL;
1148 } 1198 }
@@ -1174,6 +1224,14 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
1174 case V4L2_CID_HUE: 1224 case V4L2_CID_HUE:
1175 tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val); 1225 tm6000_set_reg(dev, TM6010_REQ07_R0B_CHROMA_HUE_PHASE_ADJ, val);
1176 return 0; 1226 return 0;
1227 case V4L2_CID_AUDIO_MUTE:
1228 dev->ctl_mute = val;
1229 tm6000_tvaudio_set_mute(dev, val);
1230 return 0;
1231 case V4L2_CID_AUDIO_VOLUME:
1232 dev->ctl_volume = val;
1233 tm6000_set_volume(dev, val);
1234 return 0;
1177 } 1235 }
1178 return -EINVAL; 1236 return -EINVAL;
1179} 1237}
@@ -1221,7 +1279,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
1221 if (unlikely(UNSET == dev->tuner_type)) 1279 if (unlikely(UNSET == dev->tuner_type))
1222 return -EINVAL; 1280 return -EINVAL;
1223 1281
1224 f->type = V4L2_TUNER_ANALOG_TV; 1282 f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
1225 f->frequency = dev->freq; 1283 f->frequency = dev->freq;
1226 1284
1227 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f); 1285 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_frequency, f);
@@ -1235,13 +1293,14 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1235 struct tm6000_fh *fh = priv; 1293 struct tm6000_fh *fh = priv;
1236 struct tm6000_core *dev = fh->dev; 1294 struct tm6000_core *dev = fh->dev;
1237 1295
1238 if (unlikely(f->type != V4L2_TUNER_ANALOG_TV))
1239 return -EINVAL;
1240
1241 if (unlikely(UNSET == dev->tuner_type)) 1296 if (unlikely(UNSET == dev->tuner_type))
1242 return -EINVAL; 1297 return -EINVAL;
1243 if (unlikely(f->tuner != 0)) 1298 if (unlikely(f->tuner != 0))
1244 return -EINVAL; 1299 return -EINVAL;
1300 if (0 == fh->radio && V4L2_TUNER_ANALOG_TV != f->type)
1301 return -EINVAL;
1302 if (1 == fh->radio && V4L2_TUNER_RADIO != f->type)
1303 return -EINVAL;
1245 1304
1246 dev->freq = f->frequency; 1305 dev->freq = f->frequency;
1247 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f); 1306 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
@@ -1249,6 +1308,122 @@ static int vidioc_s_frequency(struct file *file, void *priv,
1249 return 0; 1308 return 0;
1250} 1309}
1251 1310
1311static int radio_querycap(struct file *file, void *priv,
1312 struct v4l2_capability *cap)
1313{
1314 struct tm6000_fh *fh = file->private_data;
1315 struct tm6000_core *dev = fh->dev;
1316
1317 strcpy(cap->driver, "tm6000");
1318 strlcpy(cap->card, dev->name, sizeof(dev->name));
1319 sprintf(cap->bus_info, "USB%04x:%04x",
1320 le16_to_cpu(dev->udev->descriptor.idVendor),
1321 le16_to_cpu(dev->udev->descriptor.idProduct));
1322 cap->version = dev->dev_type;
1323 cap->capabilities = V4L2_CAP_TUNER;
1324
1325 return 0;
1326}
1327
1328static int radio_g_tuner(struct file *file, void *priv,
1329 struct v4l2_tuner *t)
1330{
1331 struct tm6000_fh *fh = file->private_data;
1332 struct tm6000_core *dev = fh->dev;
1333
1334 if (0 != t->index)
1335 return -EINVAL;
1336
1337 memset(t, 0, sizeof(*t));
1338 strcpy(t->name, "Radio");
1339 t->type = V4L2_TUNER_RADIO;
1340
1341 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
1342
1343 if ((dev->aradio == TM6000_AIP_LINE1) ||
1344 (dev->aradio == TM6000_AIP_LINE2)) {
1345 t->rxsubchans = V4L2_TUNER_SUB_MONO;
1346 }
1347 else {
1348 t->rxsubchans = V4L2_TUNER_SUB_STEREO;
1349 }
1350
1351 return 0;
1352}
1353
1354static int radio_s_tuner(struct file *file, void *priv,
1355 struct v4l2_tuner *t)
1356{
1357 struct tm6000_fh *fh = file->private_data;
1358 struct tm6000_core *dev = fh->dev;
1359
1360 if (0 != t->index)
1361 return -EINVAL;
1362
1363 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
1364
1365 return 0;
1366}
1367
1368static int radio_enum_input(struct file *file, void *priv,
1369 struct v4l2_input *i)
1370{
1371 if (i->index != 0)
1372 return -EINVAL;
1373
1374 strcpy(i->name, "Radio");
1375 i->type = V4L2_INPUT_TYPE_TUNER;
1376
1377 return 0;
1378}
1379
1380static int radio_g_input(struct file *filp, void *priv, unsigned int *i)
1381{
1382 *i = 0;
1383 return 0;
1384}
1385
1386static int radio_g_audio(struct file *file, void *priv,
1387 struct v4l2_audio *a)
1388{
1389 memset(a, 0, sizeof(*a));
1390 strcpy(a->name, "Radio");
1391 return 0;
1392}
1393
1394static int radio_s_audio(struct file *file, void *priv,
1395 struct v4l2_audio *a)
1396{
1397 return 0;
1398}
1399
1400static int radio_s_input(struct file *filp, void *priv, unsigned int i)
1401{
1402 return 0;
1403}
1404
1405static int radio_s_std(struct file *file, void *fh, v4l2_std_id *norm)
1406{
1407 return 0;
1408}
1409
1410static int radio_queryctrl(struct file *file, void *priv,
1411 struct v4l2_queryctrl *c)
1412{
1413 const struct v4l2_queryctrl *ctrl;
1414
1415 if (c->id < V4L2_CID_BASE ||
1416 c->id >= V4L2_CID_LASTP1)
1417 return -EINVAL;
1418 if (c->id == V4L2_CID_AUDIO_MUTE) {
1419 ctrl = ctrl_by_id(c->id);
1420 *c = *ctrl;
1421 } else
1422 *c = no_ctrl;
1423
1424 return 0;
1425}
1426
1252/* ------------------------------------------------------------------ 1427/* ------------------------------------------------------------------
1253 File operations for the device 1428 File operations for the device
1254 ------------------------------------------------------------------*/ 1429 ------------------------------------------------------------------*/
@@ -1260,6 +1435,7 @@ static int tm6000_open(struct file *file)
1260 struct tm6000_fh *fh; 1435 struct tm6000_fh *fh;
1261 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1436 enum v4l2_buf_type type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1262 int i, rc; 1437 int i, rc;
1438 int radio = 0;
1263 1439
1264 printk(KERN_INFO "tm6000: open called (dev=%s)\n", 1440 printk(KERN_INFO "tm6000: open called (dev=%s)\n",
1265 video_device_node_name(vdev)); 1441 video_device_node_name(vdev));
@@ -1267,6 +1443,17 @@ static int tm6000_open(struct file *file)
1267 dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n", 1443 dprintk(dev, V4L2_DEBUG_OPEN, "tm6000: open called (dev=%s)\n",
1268 video_device_node_name(vdev)); 1444 video_device_node_name(vdev));
1269 1445
1446 switch (vdev->vfl_type) {
1447 case VFL_TYPE_GRABBER:
1448 type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
1449 break;
1450 case VFL_TYPE_VBI:
1451 type = V4L2_BUF_TYPE_VBI_CAPTURE;
1452 break;
1453 case VFL_TYPE_RADIO:
1454 radio = 1;
1455 break;
1456 }
1270 1457
1271 /* If more than one user, mutex should be added */ 1458 /* If more than one user, mutex should be added */
1272 dev->users++; 1459 dev->users++;
@@ -1284,8 +1471,9 @@ static int tm6000_open(struct file *file)
1284 1471
1285 file->private_data = fh; 1472 file->private_data = fh;
1286 fh->dev = dev; 1473 fh->dev = dev;
1287 1474 fh->radio = radio;
1288 fh->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1475 dev->radio = radio;
1476 fh->type = type;
1289 dev->fourcc = format[0].fourcc; 1477 dev->fourcc = format[0].fourcc;
1290 1478
1291 fh->fmt = format_by_fourcc(dev->fourcc); 1479 fh->fmt = format_by_fourcc(dev->fourcc);
@@ -1322,6 +1510,19 @@ static int tm6000_open(struct file *file)
1322 V4L2_FIELD_INTERLACED, 1510 V4L2_FIELD_INTERLACED,
1323 sizeof(struct tm6000_buffer), fh, &dev->lock); 1511 sizeof(struct tm6000_buffer), fh, &dev->lock);
1324 1512
1513 if (fh->radio) {
1514 dprintk(dev, V4L2_DEBUG_OPEN, "video_open: setting radio device\n");
1515 tm6000_set_audio_input(dev, dev->aradio);
1516 tm6000_set_volume(dev, dev->ctl_volume);
1517 v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
1518 tm6000_prepare_isoc(dev);
1519 tm6000_start_thread(dev);
1520 }
1521 else {
1522 tm6000_set_audio_input(dev, dev->avideo);
1523 tm6000_set_volume(dev, dev->ctl_volume);
1524 }
1525
1325 return 0; 1526 return 0;
1326} 1527}
1327 1528
@@ -1445,6 +1646,36 @@ static struct video_device tm6000_template = {
1445 .current_norm = V4L2_STD_NTSC_M, 1646 .current_norm = V4L2_STD_NTSC_M,
1446}; 1647};
1447 1648
1649static const struct v4l2_file_operations radio_fops = {
1650 .owner = THIS_MODULE,
1651 .open = tm6000_open,
1652 .release = tm6000_release,
1653 .ioctl = video_ioctl2,
1654};
1655
1656static const struct v4l2_ioctl_ops radio_ioctl_ops = {
1657 .vidioc_querycap = radio_querycap,
1658 .vidioc_g_tuner = radio_g_tuner,
1659 .vidioc_enum_input = radio_enum_input,
1660 .vidioc_g_audio = radio_g_audio,
1661 .vidioc_s_tuner = radio_s_tuner,
1662 .vidioc_s_audio = radio_s_audio,
1663 .vidioc_s_input = radio_s_input,
1664 .vidioc_s_std = radio_s_std,
1665 .vidioc_queryctrl = radio_queryctrl,
1666 .vidioc_g_input = radio_g_input,
1667 .vidioc_g_ctrl = vidioc_g_ctrl,
1668 .vidioc_s_ctrl = vidioc_s_ctrl,
1669 .vidioc_g_frequency = vidioc_g_frequency,
1670 .vidioc_s_frequency = vidioc_s_frequency,
1671};
1672
1673struct video_device tm6000_radio_template = {
1674 .name = "tm6000",
1675 .fops = &radio_fops,
1676 .ioctl_ops = &radio_ioctl_ops,
1677};
1678
1448/* ----------------------------------------------------------------- 1679/* -----------------------------------------------------------------
1449 * Initialization and module stuff 1680 * Initialization and module stuff
1450 * ------------------------------------------------------------------ 1681 * ------------------------------------------------------------------
@@ -1499,6 +1730,25 @@ int tm6000_v4l2_register(struct tm6000_core *dev)
1499 printk(KERN_INFO "%s: registered device %s\n", 1730 printk(KERN_INFO "%s: registered device %s\n",
1500 dev->name, video_device_node_name(dev->vfd)); 1731 dev->name, video_device_node_name(dev->vfd));
1501 1732
1733 dev->radio_dev = vdev_init(dev, &tm6000_radio_template,
1734 "radio");
1735 if (!dev->radio_dev) {
1736 printk(KERN_INFO "%s: can't register radio device\n",
1737 dev->name);
1738 return ret; /* FIXME release resource */
1739 }
1740
1741 ret = video_register_device(dev->radio_dev, VFL_TYPE_RADIO,
1742 radio_nr);
1743 if (ret < 0) {
1744 printk(KERN_INFO "%s: can't register radio device\n",
1745 dev->name);
1746 return ret; /* FIXME release resource */
1747 }
1748
1749 printk(KERN_INFO "%s: registered device %s\n",
1750 dev->name, video_device_node_name(dev->radio_dev));
1751
1502 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret); 1752 printk(KERN_INFO "Trident TVMaster TM5600/TM6000/TM6010 USB2 board (Load status: %d)\n", ret);
1503 return ret; 1753 return ret;
1504} 1754}
@@ -1507,6 +1757,14 @@ int tm6000_v4l2_unregister(struct tm6000_core *dev)
1507{ 1757{
1508 video_unregister_device(dev->vfd); 1758 video_unregister_device(dev->vfd);
1509 1759
1760 if (dev->radio_dev) {
1761 if (video_is_registered(dev->radio_dev))
1762 video_unregister_device(dev->radio_dev);
1763 else
1764 video_device_release(dev->radio_dev);
1765 dev->radio_dev = NULL;
1766 }
1767
1510 return 0; 1768 return 0;
1511} 1769}
1512 1770
diff --git a/drivers/staging/tm6000/tm6000.h b/drivers/staging/tm6000/tm6000.h
index bf11eeec92c7..99ae50e82b28 100644
--- a/drivers/staging/tm6000/tm6000.h
+++ b/drivers/staging/tm6000/tm6000.h
@@ -53,6 +53,14 @@ enum tm6000_devtype {
53 TM6010, 53 TM6010,
54}; 54};
55 55
56enum tm6000_inaudio {
57 TM6000_AIP_UNK = 0,
58 TM6000_AIP_SIF1,
59 TM6000_AIP_SIF2,
60 TM6000_AIP_LINE1,
61 TM6000_AIP_LINE2,
62};
63
56/* ------------------------------------------------------------------ 64/* ------------------------------------------------------------------
57 * Basic structures 65 * Basic structures
58 * ------------------------------------------------------------------ 66 * ------------------------------------------------------------------
@@ -121,6 +129,8 @@ struct tm6000_capabilities {
121 unsigned int has_zl10353:1; 129 unsigned int has_zl10353:1;
122 unsigned int has_eeprom:1; 130 unsigned int has_eeprom:1;
123 unsigned int has_remote:1; 131 unsigned int has_remote:1;
132 unsigned int has_input_comp:1;
133 unsigned int has_input_svid:1;
124}; 134};
125 135
126struct tm6000_dvb { 136struct tm6000_dvb {
@@ -174,6 +184,8 @@ struct tm6000_core {
174 184
175 char *ir_codes; 185 char *ir_codes;
176 186
187 __u8 radio;
188
177 /* Demodulator configuration */ 189 /* Demodulator configuration */
178 int demod_addr; /* demodulator address */ 190 int demod_addr; /* demodulator address */
179 191
@@ -194,6 +206,7 @@ struct tm6000_core {
194 bool is_res_read; 206 bool is_res_read;
195 207
196 struct video_device *vfd; 208 struct video_device *vfd;
209 struct video_device *radio_dev;
197 struct tm6000_dmaqueue vidq; 210 struct tm6000_dmaqueue vidq;
198 struct v4l2_device v4l2_dev; 211 struct v4l2_device v4l2_dev;
199 212
@@ -203,6 +216,9 @@ struct tm6000_core {
203 216
204 enum tm6000_mode mode; 217 enum tm6000_mode mode;
205 218
219 int ctl_mute; /* audio */
220 int ctl_volume;
221
206 /* DVB-T support */ 222 /* DVB-T support */
207 struct tm6000_dvb *dvb; 223 struct tm6000_dvb *dvb;
208 224
@@ -210,7 +226,8 @@ struct tm6000_core {
210 struct snd_tm6000_card *adev; 226 struct snd_tm6000_card *adev;
211 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */ 227 struct work_struct wq_trigger; /* Trigger to start/stop audio for alsa module */
212 atomic_t stream_started; /* stream should be running if true */ 228 atomic_t stream_started; /* stream should be running if true */
213 229 enum tm6000_inaudio avideo;
230 enum tm6000_inaudio aradio;
214 231
215 struct tm6000_IR *ir; 232 struct tm6000_IR *ir;
216 233
@@ -248,6 +265,7 @@ struct tm6000_ops {
248 265
249struct tm6000_fh { 266struct tm6000_fh {
250 struct tm6000_core *dev; 267 struct tm6000_core *dev;
268 unsigned int radio;
251 269
252 /* video capture */ 270 /* video capture */
253 struct tm6000_fmt *fmt; 271 struct tm6000_fmt *fmt;
@@ -276,12 +294,17 @@ int tm6000_get_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
276int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index); 294int tm6000_get_reg16(struct tm6000_core *dev, u8 req, u16 value, u16 index);
277int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index); 295int tm6000_get_reg32(struct tm6000_core *dev, u8 req, u16 value, u16 index);
278int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index); 296int tm6000_set_reg(struct tm6000_core *dev, u8 req, u16 value, u16 index);
297int tm6000_set_reg_mask(struct tm6000_core *dev, u8 req, u16 value,
298 u16 index, u16 mask);
279int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep); 299int tm6000_i2c_reset(struct tm6000_core *dev, u16 tsleep);
280int tm6000_init(struct tm6000_core *dev); 300int tm6000_init(struct tm6000_core *dev);
281 301
282int tm6000_init_analog_mode(struct tm6000_core *dev); 302int tm6000_init_analog_mode(struct tm6000_core *dev);
283int tm6000_init_digital_mode(struct tm6000_core *dev); 303int tm6000_init_digital_mode(struct tm6000_core *dev);
284int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate); 304int tm6000_set_audio_bitrate(struct tm6000_core *dev, int bitrate);
305int tm6000_set_audio_input(struct tm6000_core *dev, enum tm6000_inaudio ainp);
306int tm6000_tvaudio_set_mute(struct tm6000_core *dev, u8 mute);
307void tm6000_set_volume(struct tm6000_core *dev, int vol);
285 308
286int tm6000_v4l2_register(struct tm6000_core *dev); 309int tm6000_v4l2_register(struct tm6000_core *dev);
287int tm6000_v4l2_unregister(struct tm6000_core *dev); 310int tm6000_v4l2_unregister(struct tm6000_core *dev);
diff --git a/drivers/staging/usbvideo/Kconfig b/drivers/staging/usbvideo/Kconfig
deleted file mode 100644
index 566d659e6ff3..000000000000
--- a/drivers/staging/usbvideo/Kconfig
+++ /dev/null
@@ -1,15 +0,0 @@
1config VIDEO_USBVIDEO
2 tristate
3
4config USB_VICAM
5 tristate "USB 3com HomeConnect (aka vicam) support (DEPRECATED)"
6 depends on VIDEO_DEV && VIDEO_V4L2_COMMON && USB
7 select VIDEO_USBVIDEO
8 ---help---
9 Say Y here if you have 3com homeconnect camera (vicam).
10
11 This driver uses the deprecated V4L1 API and will be removed in
12 2.6.39, unless someone converts it to the V4L2 API.
13
14 To compile this driver as a module, choose M here: the
15 module will be called vicam.
diff --git a/drivers/staging/usbvideo/Makefile b/drivers/staging/usbvideo/Makefile
deleted file mode 100644
index 3c99a9a2d8d3..000000000000
--- a/drivers/staging/usbvideo/Makefile
+++ /dev/null
@@ -1,2 +0,0 @@
1obj-$(CONFIG_VIDEO_USBVIDEO) += usbvideo.o
2obj-$(CONFIG_USB_VICAM) += vicam.o
diff --git a/drivers/staging/usbvideo/TODO b/drivers/staging/usbvideo/TODO
deleted file mode 100644
index 3b2c03836286..000000000000
--- a/drivers/staging/usbvideo/TODO
+++ /dev/null
@@ -1,5 +0,0 @@
1This is an obsolete driver for some old webcams that still use V4L1 API.
2As V4L1 support is being removed from kernel, if nobody take care on it,
3the driver will be removed for 2.6.39.
4
5Please send patches to linux-media@vger.kernel.org
diff --git a/drivers/staging/usbvideo/usbvideo.c b/drivers/staging/usbvideo/usbvideo.c
deleted file mode 100644
index cd4c73af99ab..000000000000
--- a/drivers/staging/usbvideo/usbvideo.c
+++ /dev/null
@@ -1,2222 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16
17#include <linux/kernel.h>
18#include <linux/sched.h>
19#include <linux/list.h>
20#include <linux/slab.h>
21#include <linux/module.h>
22#include <linux/mm.h>
23#include <linux/vmalloc.h>
24#include <linux/init.h>
25#include <linux/spinlock.h>
26
27#include <linux/io.h>
28
29#include "usbvideo.h"
30
31#if defined(MAP_NR)
32#define virt_to_page(v) MAP_NR(v) /* Kernels 2.2.x */
33#endif
34
35static int video_nr = -1;
36module_param(video_nr, int, 0);
37
38/*
39 * Local prototypes.
40 */
41static void usbvideo_Disconnect(struct usb_interface *intf);
42static void usbvideo_CameraRelease(struct uvd *uvd);
43
44static long usbvideo_v4l_ioctl(struct file *file,
45 unsigned int cmd, unsigned long arg);
46static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma);
47static int usbvideo_v4l_open(struct file *file);
48static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
49 size_t count, loff_t *ppos);
50static int usbvideo_v4l_close(struct file *file);
51
52static int usbvideo_StartDataPump(struct uvd *uvd);
53static void usbvideo_StopDataPump(struct uvd *uvd);
54static int usbvideo_GetFrame(struct uvd *uvd, int frameNum);
55static int usbvideo_NewFrame(struct uvd *uvd, int framenum);
56static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
57 struct usbvideo_frame *frame);
58
59/*******************************/
60/* Memory management functions */
61/*******************************/
62static void *usbvideo_rvmalloc(unsigned long size)
63{
64 void *mem;
65 unsigned long adr;
66
67 size = PAGE_ALIGN(size);
68 mem = vmalloc_32(size);
69 if (!mem)
70 return NULL;
71
72 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
73 adr = (unsigned long) mem;
74 while (size > 0) {
75 SetPageReserved(vmalloc_to_page((void *)adr));
76 adr += PAGE_SIZE;
77 size -= PAGE_SIZE;
78 }
79
80 return mem;
81}
82
83static void usbvideo_rvfree(void *mem, unsigned long size)
84{
85 unsigned long adr;
86
87 if (!mem)
88 return;
89
90 adr = (unsigned long) mem;
91 while ((long) size > 0) {
92 ClearPageReserved(vmalloc_to_page((void *)adr));
93 adr += PAGE_SIZE;
94 size -= PAGE_SIZE;
95 }
96 vfree(mem);
97}
98
99static void RingQueue_Initialize(struct RingQueue *rq)
100{
101 assert(rq != NULL);
102 init_waitqueue_head(&rq->wqh);
103}
104
105static void RingQueue_Allocate(struct RingQueue *rq, int rqLen)
106{
107 /* Make sure the requested size is a power of 2 and
108 round up if necessary. This allows index wrapping
109 using masks rather than modulo */
110
111 int i = 1;
112 assert(rq != NULL);
113 assert(rqLen > 0);
114
115 while (rqLen >> i)
116 i++;
117 if (rqLen != 1 << (i-1))
118 rqLen = 1 << i;
119
120 rq->length = rqLen;
121 rq->ri = rq->wi = 0;
122 rq->queue = usbvideo_rvmalloc(rq->length);
123 assert(rq->queue != NULL);
124}
125
126static int RingQueue_IsAllocated(const struct RingQueue *rq)
127{
128 if (rq == NULL)
129 return 0;
130 return (rq->queue != NULL) && (rq->length > 0);
131}
132
133static void RingQueue_Free(struct RingQueue *rq)
134{
135 assert(rq != NULL);
136 if (RingQueue_IsAllocated(rq)) {
137 usbvideo_rvfree(rq->queue, rq->length);
138 rq->queue = NULL;
139 rq->length = 0;
140 }
141}
142
143int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len)
144{
145 int rql, toread;
146
147 assert(rq != NULL);
148 assert(dst != NULL);
149
150 rql = RingQueue_GetLength(rq);
151 if (!rql)
152 return 0;
153
154 /* Clip requested length to available data */
155 if (len > rql)
156 len = rql;
157
158 toread = len;
159 if (rq->ri > rq->wi) {
160 /* Read data from tail */
161 int read = (toread < (rq->length - rq->ri)) ? toread : rq->length - rq->ri;
162 memcpy(dst, rq->queue + rq->ri, read);
163 toread -= read;
164 dst += read;
165 rq->ri = (rq->ri + read) & (rq->length-1);
166 }
167 if (toread) {
168 /* Read data from head */
169 memcpy(dst, rq->queue + rq->ri, toread);
170 rq->ri = (rq->ri + toread) & (rq->length-1);
171 }
172 return len;
173}
174
175EXPORT_SYMBOL(RingQueue_Dequeue);
176
177int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n)
178{
179 int enqueued = 0;
180
181 assert(rq != NULL);
182 assert(cdata != NULL);
183 assert(rq->length > 0);
184 while (n > 0) {
185 int m, q_avail;
186
187 /* Calculate the largest chunk that fits the tail of the ring */
188 q_avail = rq->length - rq->wi;
189 if (q_avail <= 0) {
190 rq->wi = 0;
191 q_avail = rq->length;
192 }
193 m = n;
194 assert(q_avail > 0);
195 if (m > q_avail)
196 m = q_avail;
197
198 memcpy(rq->queue + rq->wi, cdata, m);
199 RING_QUEUE_ADVANCE_INDEX(rq, wi, m);
200 cdata += m;
201 enqueued += m;
202 n -= m;
203 }
204 return enqueued;
205}
206
207EXPORT_SYMBOL(RingQueue_Enqueue);
208
209static void RingQueue_InterruptibleSleepOn(struct RingQueue *rq)
210{
211 assert(rq != NULL);
212 interruptible_sleep_on(&rq->wqh);
213}
214
215void RingQueue_WakeUpInterruptible(struct RingQueue *rq)
216{
217 assert(rq != NULL);
218 if (waitqueue_active(&rq->wqh))
219 wake_up_interruptible(&rq->wqh);
220}
221
222EXPORT_SYMBOL(RingQueue_WakeUpInterruptible);
223
224void RingQueue_Flush(struct RingQueue *rq)
225{
226 assert(rq != NULL);
227 rq->ri = 0;
228 rq->wi = 0;
229}
230
231EXPORT_SYMBOL(RingQueue_Flush);
232
233
234/*
235 * usbvideo_VideosizeToString()
236 *
237 * This procedure converts given videosize value to readable string.
238 *
239 * History:
240 * 07-Aug-2000 Created.
241 * 19-Oct-2000 Reworked for usbvideo module.
242 */
243static void usbvideo_VideosizeToString(char *buf, int bufLen, videosize_t vs)
244{
245 char tmp[40];
246 int n;
247
248 n = 1 + sprintf(tmp, "%ldx%ld", VIDEOSIZE_X(vs), VIDEOSIZE_Y(vs));
249 assert(n < sizeof(tmp));
250 if ((buf == NULL) || (bufLen < n))
251 err("usbvideo_VideosizeToString: buffer is too small.");
252 else
253 memmove(buf, tmp, n);
254}
255
256/*
257 * usbvideo_OverlayChar()
258 *
259 * History:
260 * 01-Feb-2000 Created.
261 */
262static void usbvideo_OverlayChar(struct uvd *uvd, struct usbvideo_frame *frame,
263 int x, int y, int ch)
264{
265 static const unsigned short digits[16] = {
266 0xF6DE, /* 0 */
267 0x2492, /* 1 */
268 0xE7CE, /* 2 */
269 0xE79E, /* 3 */
270 0xB792, /* 4 */
271 0xF39E, /* 5 */
272 0xF3DE, /* 6 */
273 0xF492, /* 7 */
274 0xF7DE, /* 8 */
275 0xF79E, /* 9 */
276 0x77DA, /* a */
277 0xD75C, /* b */
278 0xF24E, /* c */
279 0xD6DC, /* d */
280 0xF34E, /* e */
281 0xF348 /* f */
282 };
283 unsigned short digit;
284 int ix, iy;
285 int value;
286
287 if ((uvd == NULL) || (frame == NULL))
288 return;
289
290 value = hex_to_bin(ch);
291 if (value < 0)
292 return;
293 digit = digits[value];
294
295 for (iy = 0; iy < 5; iy++) {
296 for (ix = 0; ix < 3; ix++) {
297 if (digit & 0x8000) {
298 if (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))
299/* TODO */ RGB24_PUTPIXEL(frame, x+ix, y+iy, 0xFF, 0xFF, 0xFF);
300 }
301 digit = digit << 1;
302 }
303 }
304}
305
306/*
307 * usbvideo_OverlayString()
308 *
309 * History:
310 * 01-Feb-2000 Created.
311 */
312static void usbvideo_OverlayString(struct uvd *uvd, struct usbvideo_frame *frame,
313 int x, int y, const char *str)
314{
315 while (*str) {
316 usbvideo_OverlayChar(uvd, frame, x, y, *str);
317 str++;
318 x += 4; /* 3 pixels character + 1 space */
319 }
320}
321
322/*
323 * usbvideo_OverlayStats()
324 *
325 * Overlays important debugging information.
326 *
327 * History:
328 * 01-Feb-2000 Created.
329 */
330static void usbvideo_OverlayStats(struct uvd *uvd, struct usbvideo_frame *frame)
331{
332 const int y_diff = 8;
333 char tmp[16];
334 int x = 10, y = 10;
335 long i, j, barLength;
336 const int qi_x1 = 60, qi_y1 = 10;
337 const int qi_x2 = VIDEOSIZE_X(frame->request) - 10, qi_h = 10;
338
339 /* Call the user callback, see if we may proceed after that */
340 if (VALID_CALLBACK(uvd, overlayHook)) {
341 if (GET_CALLBACK(uvd, overlayHook)(uvd, frame) < 0)
342 return;
343 }
344
345 /*
346 * We draw a (mostly) hollow rectangle with qi_xxx coordinates.
347 * Left edge symbolizes the queue index 0; right edge symbolizes
348 * the full capacity of the queue.
349 */
350 barLength = qi_x2 - qi_x1 - 2;
351 if ((barLength > 10) && (uvd->paletteBits & (1L << VIDEO_PALETTE_RGB24))) {
352/* TODO */ long u_lo, u_hi, q_used;
353 long m_ri, m_wi, m_lo, m_hi;
354
355 /*
356 * Determine fill zones (used areas of the queue):
357 * 0 xxxxxxx u_lo ...... uvd->dp.ri xxxxxxxx u_hi ..... uvd->dp.length
358 *
359 * if u_lo < 0 then there is no first filler.
360 */
361
362 q_used = RingQueue_GetLength(&uvd->dp);
363 if ((uvd->dp.ri + q_used) >= uvd->dp.length) {
364 u_hi = uvd->dp.length;
365 u_lo = (q_used + uvd->dp.ri) & (uvd->dp.length-1);
366 } else {
367 u_hi = (q_used + uvd->dp.ri);
368 u_lo = -1;
369 }
370
371 /* Convert byte indices into screen units */
372 m_ri = qi_x1 + ((barLength * uvd->dp.ri) / uvd->dp.length);
373 m_wi = qi_x1 + ((barLength * uvd->dp.wi) / uvd->dp.length);
374 m_lo = (u_lo > 0) ? (qi_x1 + ((barLength * u_lo) / uvd->dp.length)) : -1;
375 m_hi = qi_x1 + ((barLength * u_hi) / uvd->dp.length);
376
377 for (j = qi_y1; j < (qi_y1 + qi_h); j++) {
378 for (i = qi_x1; i < qi_x2; i++) {
379 /* Draw border lines */
380 if ((j == qi_y1) || (j == (qi_y1 + qi_h - 1)) ||
381 (i == qi_x1) || (i == (qi_x2 - 1))) {
382 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0xFF, 0xFF);
383 continue;
384 }
385 /* For all other points the Y coordinate does not matter */
386 if ((i >= m_ri) && (i <= (m_ri + 3)))
387 RGB24_PUTPIXEL(frame, i, j, 0x00, 0xFF, 0x00);
388 else if ((i >= m_wi) && (i <= (m_wi + 3)))
389 RGB24_PUTPIXEL(frame, i, j, 0xFF, 0x00, 0x00);
390 else if ((i < m_lo) || ((i > m_ri) && (i < m_hi)))
391 RGB24_PUTPIXEL(frame, i, j, 0x00, 0x00, 0xFF);
392 }
393 }
394 }
395
396 sprintf(tmp, "%8lx", uvd->stats.frame_num);
397 usbvideo_OverlayString(uvd, frame, x, y, tmp);
398 y += y_diff;
399
400 sprintf(tmp, "%8lx", uvd->stats.urb_count);
401 usbvideo_OverlayString(uvd, frame, x, y, tmp);
402 y += y_diff;
403
404 sprintf(tmp, "%8lx", uvd->stats.urb_length);
405 usbvideo_OverlayString(uvd, frame, x, y, tmp);
406 y += y_diff;
407
408 sprintf(tmp, "%8lx", uvd->stats.data_count);
409 usbvideo_OverlayString(uvd, frame, x, y, tmp);
410 y += y_diff;
411
412 sprintf(tmp, "%8lx", uvd->stats.header_count);
413 usbvideo_OverlayString(uvd, frame, x, y, tmp);
414 y += y_diff;
415
416 sprintf(tmp, "%8lx", uvd->stats.iso_skip_count);
417 usbvideo_OverlayString(uvd, frame, x, y, tmp);
418 y += y_diff;
419
420 sprintf(tmp, "%8lx", uvd->stats.iso_err_count);
421 usbvideo_OverlayString(uvd, frame, x, y, tmp);
422 y += y_diff;
423
424 sprintf(tmp, "%8x", uvd->vpic.colour);
425 usbvideo_OverlayString(uvd, frame, x, y, tmp);
426 y += y_diff;
427
428 sprintf(tmp, "%8x", uvd->vpic.hue);
429 usbvideo_OverlayString(uvd, frame, x, y, tmp);
430 y += y_diff;
431
432 sprintf(tmp, "%8x", uvd->vpic.brightness >> 8);
433 usbvideo_OverlayString(uvd, frame, x, y, tmp);
434 y += y_diff;
435
436 sprintf(tmp, "%8x", uvd->vpic.contrast >> 12);
437 usbvideo_OverlayString(uvd, frame, x, y, tmp);
438 y += y_diff;
439
440 sprintf(tmp, "%8d", uvd->vpic.whiteness >> 8);
441 usbvideo_OverlayString(uvd, frame, x, y, tmp);
442 y += y_diff;
443}
444
445/*
446 * usbvideo_ReportStatistics()
447 *
448 * This procedure prints packet and transfer statistics.
449 *
450 * History:
451 * 14-Jan-2000 Corrected default multiplier.
452 */
453static void usbvideo_ReportStatistics(const struct uvd *uvd)
454{
455 if ((uvd != NULL) && (uvd->stats.urb_count > 0)) {
456 unsigned long allPackets, badPackets, goodPackets, percent;
457 allPackets = uvd->stats.urb_count * CAMERA_URB_FRAMES;
458 badPackets = uvd->stats.iso_skip_count + uvd->stats.iso_err_count;
459 goodPackets = allPackets - badPackets;
460 /* Calculate percentage wisely, remember integer limits */
461 assert(allPackets != 0);
462 if (goodPackets < (((unsigned long)-1)/100))
463 percent = (100 * goodPackets) / allPackets;
464 else
465 percent = goodPackets / (allPackets / 100);
466 dev_info(&uvd->dev->dev,
467 "Packet Statistics: Total=%lu. Empty=%lu. Usage=%lu%%\n",
468 allPackets, badPackets, percent);
469 if (uvd->iso_packet_len > 0) {
470 unsigned long allBytes, xferBytes;
471 char multiplier = ' ';
472 allBytes = allPackets * uvd->iso_packet_len;
473 xferBytes = uvd->stats.data_count;
474 assert(allBytes != 0);
475 if (xferBytes < (((unsigned long)-1)/100))
476 percent = (100 * xferBytes) / allBytes;
477 else
478 percent = xferBytes / (allBytes / 100);
479 /* Scale xferBytes for easy reading */
480 if (xferBytes > 10*1024) {
481 xferBytes /= 1024;
482 multiplier = 'K';
483 if (xferBytes > 10*1024) {
484 xferBytes /= 1024;
485 multiplier = 'M';
486 if (xferBytes > 10*1024) {
487 xferBytes /= 1024;
488 multiplier = 'G';
489 if (xferBytes > 10*1024) {
490 xferBytes /= 1024;
491 multiplier = 'T';
492 }
493 }
494 }
495 }
496 dev_info(&uvd->dev->dev,
497 "Transfer Statistics: Transferred=%lu%cB Usage=%lu%%\n",
498 xferBytes, multiplier, percent);
499 }
500 }
501}
502
503/*
504 * usbvideo_TestPattern()
505 *
506 * Procedure forms a test pattern (yellow grid on blue background).
507 *
508 * Parameters:
509 * fullframe: if TRUE then entire frame is filled, otherwise the procedure
510 * continues from the current scanline.
511 * pmode 0: fill the frame with solid blue color (like on VCR or TV)
512 * 1: Draw a colored grid
513 *
514 * History:
515 * 01-Feb-2000 Created.
516 */
517void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode)
518{
519 struct usbvideo_frame *frame;
520 int num_cell = 0;
521 int scan_length = 0;
522 static int num_pass;
523
524 if (uvd == NULL) {
525 err("%s: uvd == NULL", __func__);
526 return;
527 }
528 if ((uvd->curframe < 0) || (uvd->curframe >= USBVIDEO_NUMFRAMES)) {
529 err("%s: uvd->curframe=%d.", __func__, uvd->curframe);
530 return;
531 }
532
533 /* Grab the current frame */
534 frame = &uvd->frame[uvd->curframe];
535
536 /* Optionally start at the beginning */
537 if (fullframe) {
538 frame->curline = 0;
539 frame->seqRead_Length = 0;
540 }
541#if 0
542 { /* For debugging purposes only */
543 char tmp[20];
544 usbvideo_VideosizeToString(tmp, sizeof(tmp), frame->request);
545 dev_info(&uvd->dev->dev, "testpattern: frame=%s\n", tmp);
546 }
547#endif
548 /* Form every scan line */
549 for (; frame->curline < VIDEOSIZE_Y(frame->request); frame->curline++) {
550 int i;
551 unsigned char *f = frame->data +
552 (VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL * frame->curline);
553 for (i = 0; i < VIDEOSIZE_X(frame->request); i++) {
554 unsigned char cb = 0x80;
555 unsigned char cg = 0;
556 unsigned char cr = 0;
557
558 if (pmode == 1) {
559 if (frame->curline % 32 == 0)
560 cb = 0, cg = cr = 0xFF;
561 else if (i % 32 == 0) {
562 if (frame->curline % 32 == 1)
563 num_cell++;
564 cb = 0, cg = cr = 0xFF;
565 } else {
566 cb = ((num_cell*7) + num_pass) & 0xFF;
567 cg = ((num_cell*5) + num_pass*2) & 0xFF;
568 cr = ((num_cell*3) + num_pass*3) & 0xFF;
569 }
570 } else {
571 /* Just the blue screen */
572 }
573
574 *f++ = cb;
575 *f++ = cg;
576 *f++ = cr;
577 scan_length += 3;
578 }
579 }
580
581 frame->frameState = FrameState_Done;
582 frame->seqRead_Length += scan_length;
583 ++num_pass;
584
585 /* We do this unconditionally, regardless of FLAGS_OVERLAY_STATS */
586 usbvideo_OverlayStats(uvd, frame);
587}
588
589EXPORT_SYMBOL(usbvideo_TestPattern);
590
591
592#ifdef DEBUG
593/*
594 * usbvideo_HexDump()
595 *
596 * A debugging tool. Prints hex dumps.
597 *
598 * History:
599 * 29-Jul-2000 Added printing of offsets.
600 */
601void usbvideo_HexDump(const unsigned char *data, int len)
602{
603 const int bytes_per_line = 32;
604 char tmp[128]; /* 32*3 + 5 */
605 int i, k;
606
607 for (i = k = 0; len > 0; i++, len--) {
608 if (i > 0 && ((i % bytes_per_line) == 0)) {
609 printk("%s\n", tmp);
610 k = 0;
611 }
612 if ((i % bytes_per_line) == 0)
613 k += sprintf(&tmp[k], "%04x: ", i);
614 k += sprintf(&tmp[k], "%02x ", data[i]);
615 }
616 if (k > 0)
617 printk("%s\n", tmp);
618}
619
620EXPORT_SYMBOL(usbvideo_HexDump);
621
622#endif
623
624/* ******************************************************************** */
625
626/* XXX: this piece of crap really wants some error handling.. */
627static int usbvideo_ClientIncModCount(struct uvd *uvd)
628{
629 if (uvd == NULL) {
630 err("%s: uvd == NULL", __func__);
631 return -EINVAL;
632 }
633 if (uvd->handle == NULL) {
634 err("%s: uvd->handle == NULL", __func__);
635 return -EINVAL;
636 }
637 if (!try_module_get(uvd->handle->md_module)) {
638 err("%s: try_module_get() == 0", __func__);
639 return -ENODEV;
640 }
641 return 0;
642}
643
644static void usbvideo_ClientDecModCount(struct uvd *uvd)
645{
646 if (uvd == NULL) {
647 err("%s: uvd == NULL", __func__);
648 return;
649 }
650 if (uvd->handle == NULL) {
651 err("%s: uvd->handle == NULL", __func__);
652 return;
653 }
654 if (uvd->handle->md_module == NULL) {
655 err("%s: uvd->handle->md_module == NULL", __func__);
656 return;
657 }
658 module_put(uvd->handle->md_module);
659}
660
661int usbvideo_register(
662 struct usbvideo **pCams,
663 const int num_cams,
664 const int num_extra,
665 const char *driverName,
666 const struct usbvideo_cb *cbTbl,
667 struct module *md,
668 const struct usb_device_id *id_table)
669{
670 struct usbvideo *cams;
671 int i, base_size, result;
672
673 /* Check parameters for sanity */
674 if ((num_cams <= 0) || (pCams == NULL) || (cbTbl == NULL)) {
675 err("%s: Illegal call", __func__);
676 return -EINVAL;
677 }
678
679 /* Check registration callback - must be set! */
680 if (cbTbl->probe == NULL) {
681 err("%s: probe() is required!", __func__);
682 return -EINVAL;
683 }
684
685 base_size = num_cams * sizeof(struct uvd) + sizeof(struct usbvideo);
686 cams = kzalloc(base_size, GFP_KERNEL);
687 if (cams == NULL) {
688 err("Failed to allocate %d. bytes for usbvideo struct", base_size);
689 return -ENOMEM;
690 }
691 dbg("%s: Allocated $%p (%d. bytes) for %d. cameras",
692 __func__, cams, base_size, num_cams);
693
694 /* Copy callbacks, apply defaults for those that are not set */
695 memmove(&cams->cb, cbTbl, sizeof(cams->cb));
696 if (cams->cb.getFrame == NULL)
697 cams->cb.getFrame = usbvideo_GetFrame;
698 if (cams->cb.disconnect == NULL)
699 cams->cb.disconnect = usbvideo_Disconnect;
700 if (cams->cb.startDataPump == NULL)
701 cams->cb.startDataPump = usbvideo_StartDataPump;
702 if (cams->cb.stopDataPump == NULL)
703 cams->cb.stopDataPump = usbvideo_StopDataPump;
704
705 cams->num_cameras = num_cams;
706 cams->cam = (struct uvd *) &cams[1];
707 cams->md_module = md;
708 mutex_init(&cams->lock); /* to 1 == available */
709
710 for (i = 0; i < num_cams; i++) {
711 struct uvd *up = &cams->cam[i];
712
713 up->handle = cams;
714
715 /* Allocate user_data separately because of kmalloc's limits */
716 if (num_extra > 0) {
717 up->user_size = num_cams * num_extra;
718 up->user_data = kmalloc(up->user_size, GFP_KERNEL);
719 if (up->user_data == NULL) {
720 err("%s: Failed to allocate user_data (%d. bytes)",
721 __func__, up->user_size);
722 while (i) {
723 up = &cams->cam[--i];
724 kfree(up->user_data);
725 }
726 kfree(cams);
727 return -ENOMEM;
728 }
729 dbg("%s: Allocated cams[%d].user_data=$%p (%d. bytes)",
730 __func__, i, up->user_data, up->user_size);
731 }
732 }
733
734 /*
735 * Register ourselves with USB stack.
736 */
737 strcpy(cams->drvName, (driverName != NULL) ? driverName : "Unknown");
738 cams->usbdrv.name = cams->drvName;
739 cams->usbdrv.probe = cams->cb.probe;
740 cams->usbdrv.disconnect = cams->cb.disconnect;
741 cams->usbdrv.id_table = id_table;
742
743 /*
744 * Update global handle to usbvideo. This is very important
745 * because probe() can be called before usb_register() returns.
746 * If the handle is not yet updated then the probe() will fail.
747 */
748 *pCams = cams;
749 result = usb_register(&cams->usbdrv);
750 if (result) {
751 for (i = 0; i < num_cams; i++) {
752 struct uvd *up = &cams->cam[i];
753 kfree(up->user_data);
754 }
755 kfree(cams);
756 }
757
758 return result;
759}
760
761EXPORT_SYMBOL(usbvideo_register);
762
763/*
764 * usbvideo_Deregister()
765 *
766 * Procedure frees all usbvideo and user data structures. Be warned that
767 * if you had some dynamically allocated components in ->user field then
768 * you should free them before calling here.
769 */
770void usbvideo_Deregister(struct usbvideo **pCams)
771{
772 struct usbvideo *cams;
773 int i;
774
775 if (pCams == NULL) {
776 err("%s: pCams == NULL", __func__);
777 return;
778 }
779 cams = *pCams;
780 if (cams == NULL) {
781 err("%s: cams == NULL", __func__);
782 return;
783 }
784
785 dbg("%s: Deregistering %s driver.", __func__, cams->drvName);
786 usb_deregister(&cams->usbdrv);
787
788 dbg("%s: Deallocating cams=$%p (%d. cameras)", __func__, cams, cams->num_cameras);
789 for (i = 0; i < cams->num_cameras; i++) {
790 struct uvd *up = &cams->cam[i];
791 int warning = 0;
792
793 if (up->user_data != NULL) {
794 if (up->user_size <= 0)
795 ++warning;
796 } else {
797 if (up->user_size > 0)
798 ++warning;
799 }
800 if (warning) {
801 err("%s: Warning: user_data=$%p user_size=%d.",
802 __func__, up->user_data, up->user_size);
803 } else {
804 dbg("%s: Freeing %d. $%p->user_data=$%p",
805 __func__, i, up, up->user_data);
806 kfree(up->user_data);
807 }
808 }
809 /* Whole array was allocated in one chunk */
810 dbg("%s: Freed %d uvd structures",
811 __func__, cams->num_cameras);
812 kfree(cams);
813 *pCams = NULL;
814}
815
816EXPORT_SYMBOL(usbvideo_Deregister);
817
818/*
819 * usbvideo_Disconnect()
820 *
821 * This procedure stops all driver activity. Deallocation of
822 * the interface-private structure (pointed by 'ptr') is done now
823 * (if we don't have any open files) or later, when those files
824 * are closed. After that driver should be removable.
825 *
826 * This code handles surprise removal. The uvd->user is a counter which
827 * increments on open() and decrements on close(). If we see here that
828 * this counter is not 0 then we have a client who still has us opened.
829 * We set uvd->remove_pending flag as early as possible, and after that
830 * all access to the camera will gracefully fail. These failures should
831 * prompt client to (eventually) close the video device, and then - in
832 * usbvideo_v4l_close() - we decrement uvd->uvd_used and usage counter.
833 *
834 * History:
835 * 22-Jan-2000 Added polling of MOD_IN_USE to delay removal until all users gone.
836 * 27-Jan-2000 Reworked to allow pending disconnects; see xxx_close()
837 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
838 * 19-Oct-2000 Moved to usbvideo module.
839 */
840static void usbvideo_Disconnect(struct usb_interface *intf)
841{
842 struct uvd *uvd = usb_get_intfdata(intf);
843 int i;
844
845 if (uvd == NULL) {
846 err("%s($%p): Illegal call.", __func__, intf);
847 return;
848 }
849
850 usb_set_intfdata(intf, NULL);
851
852 usbvideo_ClientIncModCount(uvd);
853 if (uvd->debug > 0)
854 dev_info(&intf->dev, "%s(%p.)\n", __func__, intf);
855
856 mutex_lock(&uvd->lock);
857 uvd->remove_pending = 1; /* Now all ISO data will be ignored */
858
859 /* At this time we ask to cancel outstanding URBs */
860 GET_CALLBACK(uvd, stopDataPump)(uvd);
861
862 for (i = 0; i < USBVIDEO_NUMSBUF; i++)
863 usb_free_urb(uvd->sbuf[i].urb);
864
865 usb_put_dev(uvd->dev);
866 uvd->dev = NULL; /* USB device is no more */
867
868 video_unregister_device(&uvd->vdev);
869 if (uvd->debug > 0)
870 dev_info(&intf->dev, "%s: Video unregistered.\n", __func__);
871
872 if (uvd->user)
873 dev_info(&intf->dev, "%s: In use, disconnect pending.\n",
874 __func__);
875 else
876 usbvideo_CameraRelease(uvd);
877 mutex_unlock(&uvd->lock);
878 dev_info(&intf->dev, "USB camera disconnected.\n");
879
880 usbvideo_ClientDecModCount(uvd);
881}
882
883/*
884 * usbvideo_CameraRelease()
885 *
886 * This code does final release of uvd. This happens
887 * after the device is disconnected -and- all clients
888 * closed their files.
889 *
890 * History:
891 * 27-Jan-2000 Created.
892 */
893static void usbvideo_CameraRelease(struct uvd *uvd)
894{
895 if (uvd == NULL) {
896 err("%s: Illegal call", __func__);
897 return;
898 }
899
900 RingQueue_Free(&uvd->dp);
901 if (VALID_CALLBACK(uvd, userFree))
902 GET_CALLBACK(uvd, userFree)(uvd);
903 uvd->uvd_used = 0; /* This is atomic, no need to take mutex */
904}
905
906/*
907 * usbvideo_find_struct()
908 *
909 * This code searches the array of preallocated (static) structures
910 * and returns index of the first one that isn't in use. Returns -1
911 * if there are no free structures.
912 *
913 * History:
914 * 27-Jan-2000 Created.
915 */
916static int usbvideo_find_struct(struct usbvideo *cams)
917{
918 int u, rv = -1;
919
920 if (cams == NULL) {
921 err("No usbvideo handle?");
922 return -1;
923 }
924 mutex_lock(&cams->lock);
925 for (u = 0; u < cams->num_cameras; u++) {
926 struct uvd *uvd = &cams->cam[u];
927 if (!uvd->uvd_used) { /* This one is free */
928 uvd->uvd_used = 1; /* In use now */
929 mutex_init(&uvd->lock); /* to 1 == available */
930 uvd->dev = NULL;
931 rv = u;
932 break;
933 }
934 }
935 mutex_unlock(&cams->lock);
936 return rv;
937}
938
939static const struct v4l2_file_operations usbvideo_fops = {
940 .owner = THIS_MODULE,
941 .open = usbvideo_v4l_open,
942 .release = usbvideo_v4l_close,
943 .read = usbvideo_v4l_read,
944 .mmap = usbvideo_v4l_mmap,
945 .ioctl = usbvideo_v4l_ioctl,
946};
947static const struct video_device usbvideo_template = {
948 .fops = &usbvideo_fops,
949};
950
951struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams)
952{
953 int i, devnum;
954 struct uvd *uvd = NULL;
955
956 if (cams == NULL) {
957 err("No usbvideo handle?");
958 return NULL;
959 }
960
961 devnum = usbvideo_find_struct(cams);
962 if (devnum == -1) {
963 err("IBM USB camera driver: Too many devices!");
964 return NULL;
965 }
966 uvd = &cams->cam[devnum];
967 dbg("Device entry #%d. at $%p", devnum, uvd);
968
969 /* Not relying upon caller we increase module counter ourselves */
970 usbvideo_ClientIncModCount(uvd);
971
972 mutex_lock(&uvd->lock);
973 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
974 uvd->sbuf[i].urb = usb_alloc_urb(FRAMES_PER_DESC, GFP_KERNEL);
975 if (uvd->sbuf[i].urb == NULL) {
976 err("usb_alloc_urb(%d.) failed.", FRAMES_PER_DESC);
977 uvd->uvd_used = 0;
978 uvd = NULL;
979 goto allocate_done;
980 }
981 }
982 uvd->user = 0;
983 uvd->remove_pending = 0;
984 uvd->last_error = 0;
985 RingQueue_Initialize(&uvd->dp);
986
987 /* Initialize video device structure */
988 uvd->vdev = usbvideo_template;
989 sprintf(uvd->vdev.name, "%.20s USB Camera", cams->drvName);
990 /*
991 * The client is free to overwrite those because we
992 * return control to the client's probe function right now.
993 */
994allocate_done:
995 mutex_unlock(&uvd->lock);
996 usbvideo_ClientDecModCount(uvd);
997 return uvd;
998}
999
1000EXPORT_SYMBOL(usbvideo_AllocateDevice);
1001
1002int usbvideo_RegisterVideoDevice(struct uvd *uvd)
1003{
1004 char tmp1[20], tmp2[20]; /* Buffers for printing */
1005
1006 if (uvd == NULL) {
1007 err("%s: Illegal call.", __func__);
1008 return -EINVAL;
1009 }
1010 if (uvd->video_endp == 0) {
1011 dev_info(&uvd->dev->dev,
1012 "%s: No video endpoint specified; data pump disabled.\n",
1013 __func__);
1014 }
1015 if (uvd->paletteBits == 0) {
1016 err("%s: No palettes specified!", __func__);
1017 return -EINVAL;
1018 }
1019 if (uvd->defaultPalette == 0) {
1020 dev_info(&uvd->dev->dev, "%s: No default palette!\n",
1021 __func__);
1022 }
1023
1024 uvd->max_frame_size = VIDEOSIZE_X(uvd->canvas) *
1025 VIDEOSIZE_Y(uvd->canvas) * V4L_BYTES_PER_PIXEL;
1026 usbvideo_VideosizeToString(tmp1, sizeof(tmp1), uvd->videosize);
1027 usbvideo_VideosizeToString(tmp2, sizeof(tmp2), uvd->canvas);
1028
1029 if (uvd->debug > 0) {
1030 dev_info(&uvd->dev->dev,
1031 "%s: iface=%d. endpoint=$%02x paletteBits=$%08lx\n",
1032 __func__, uvd->iface, uvd->video_endp,
1033 uvd->paletteBits);
1034 }
1035 if (uvd->dev == NULL) {
1036 err("%s: uvd->dev == NULL", __func__);
1037 return -EINVAL;
1038 }
1039 uvd->vdev.parent = &uvd->dev->dev;
1040 uvd->vdev.release = video_device_release_empty;
1041 if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) {
1042 err("%s: video_register_device failed", __func__);
1043 return -EPIPE;
1044 }
1045 if (uvd->debug > 1) {
1046 dev_info(&uvd->dev->dev,
1047 "%s: video_register_device() successful\n", __func__);
1048 }
1049
1050 dev_info(&uvd->dev->dev, "%s on %s: canvas=%s videosize=%s\n",
1051 (uvd->handle != NULL) ? uvd->handle->drvName : "???",
1052 video_device_node_name(&uvd->vdev), tmp2, tmp1);
1053
1054 usb_get_dev(uvd->dev);
1055 return 0;
1056}
1057
1058EXPORT_SYMBOL(usbvideo_RegisterVideoDevice);
1059
1060/* ******************************************************************** */
1061
1062static int usbvideo_v4l_mmap(struct file *file, struct vm_area_struct *vma)
1063{
1064 struct uvd *uvd = file->private_data;
1065 unsigned long start = vma->vm_start;
1066 unsigned long size = vma->vm_end-vma->vm_start;
1067 unsigned long page, pos;
1068
1069 if (!CAMERA_IS_OPERATIONAL(uvd))
1070 return -EFAULT;
1071
1072 if (size > (((USBVIDEO_NUMFRAMES * uvd->max_frame_size) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1073 return -EINVAL;
1074
1075 pos = (unsigned long) uvd->fbuf;
1076 while (size > 0) {
1077 page = vmalloc_to_pfn((void *)pos);
1078 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
1079 return -EAGAIN;
1080
1081 start += PAGE_SIZE;
1082 pos += PAGE_SIZE;
1083 if (size > PAGE_SIZE)
1084 size -= PAGE_SIZE;
1085 else
1086 size = 0;
1087 }
1088
1089 return 0;
1090}
1091
1092/*
1093 * usbvideo_v4l_open()
1094 *
1095 * This is part of Video 4 Linux API. The driver can be opened by one
1096 * client only (checks internal counter 'uvdser'). The procedure
1097 * then allocates buffers needed for video processing.
1098 *
1099 * History:
1100 * 22-Jan-2000 Rewrote, moved scratch buffer allocation here. Now the
1101 * camera is also initialized here (once per connect), at
1102 * expense of V4L client (it waits on open() call).
1103 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1104 * 24-May-2000 Corrected to prevent race condition (MOD_xxx_USE_COUNT).
1105 */
1106static int usbvideo_v4l_open(struct file *file)
1107{
1108 struct video_device *dev = video_devdata(file);
1109 struct uvd *uvd = (struct uvd *) dev;
1110 const int sb_size = FRAMES_PER_DESC * uvd->iso_packet_len;
1111 int i, errCode = 0;
1112
1113 if (uvd->debug > 1)
1114 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev);
1115
1116 if (usbvideo_ClientIncModCount(uvd) < 0)
1117 return -ENODEV;
1118 mutex_lock(&uvd->lock);
1119
1120 if (uvd->user) {
1121 err("%s: Someone tried to open an already opened device!", __func__);
1122 errCode = -EBUSY;
1123 } else {
1124 /* Clear statistics */
1125 memset(&uvd->stats, 0, sizeof(uvd->stats));
1126
1127 /* Clean pointers so we know if we allocated something */
1128 for (i = 0; i < USBVIDEO_NUMSBUF; i++)
1129 uvd->sbuf[i].data = NULL;
1130
1131 /* Allocate memory for the frame buffers */
1132 uvd->fbuf_size = USBVIDEO_NUMFRAMES * uvd->max_frame_size;
1133 uvd->fbuf = usbvideo_rvmalloc(uvd->fbuf_size);
1134 RingQueue_Allocate(&uvd->dp, RING_QUEUE_SIZE);
1135 if ((uvd->fbuf == NULL) ||
1136 (!RingQueue_IsAllocated(&uvd->dp))) {
1137 err("%s: Failed to allocate fbuf or dp", __func__);
1138 errCode = -ENOMEM;
1139 } else {
1140 /* Allocate all buffers */
1141 for (i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1142 uvd->frame[i].frameState = FrameState_Unused;
1143 uvd->frame[i].data = uvd->fbuf + i*(uvd->max_frame_size);
1144 /*
1145 * Set default sizes in case IOCTL (VIDIOCMCAPTURE)
1146 * is not used (using read() instead).
1147 */
1148 uvd->frame[i].canvas = uvd->canvas;
1149 uvd->frame[i].seqRead_Index = 0;
1150 }
1151 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1152 uvd->sbuf[i].data = kmalloc(sb_size, GFP_KERNEL);
1153 if (uvd->sbuf[i].data == NULL) {
1154 errCode = -ENOMEM;
1155 break;
1156 }
1157 }
1158 }
1159 if (errCode != 0) {
1160 /* Have to free all that memory */
1161 if (uvd->fbuf != NULL) {
1162 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1163 uvd->fbuf = NULL;
1164 }
1165 RingQueue_Free(&uvd->dp);
1166 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1167 kfree(uvd->sbuf[i].data);
1168 uvd->sbuf[i].data = NULL;
1169 }
1170 }
1171 }
1172
1173 /* If so far no errors then we shall start the camera */
1174 if (errCode == 0) {
1175 /* Start data pump if we have valid endpoint */
1176 if (uvd->video_endp != 0)
1177 errCode = GET_CALLBACK(uvd, startDataPump)(uvd);
1178 if (errCode == 0) {
1179 if (VALID_CALLBACK(uvd, setupOnOpen)) {
1180 if (uvd->debug > 1)
1181 dev_info(&uvd->dev->dev,
1182 "%s: setupOnOpen callback\n",
1183 __func__);
1184 errCode = GET_CALLBACK(uvd, setupOnOpen)(uvd);
1185 if (errCode < 0) {
1186 err("%s: setupOnOpen callback failed (%d.).",
1187 __func__, errCode);
1188 } else if (uvd->debug > 1) {
1189 dev_info(&uvd->dev->dev,
1190 "%s: setupOnOpen callback successful\n",
1191 __func__);
1192 }
1193 }
1194 if (errCode == 0) {
1195 uvd->settingsAdjusted = 0;
1196 if (uvd->debug > 1)
1197 dev_info(&uvd->dev->dev,
1198 "%s: Open succeeded.\n",
1199 __func__);
1200 uvd->user++;
1201 file->private_data = uvd;
1202 }
1203 }
1204 }
1205 mutex_unlock(&uvd->lock);
1206 if (errCode != 0)
1207 usbvideo_ClientDecModCount(uvd);
1208 if (uvd->debug > 0)
1209 dev_info(&uvd->dev->dev, "%s: Returning %d.\n", __func__,
1210 errCode);
1211 return errCode;
1212}
1213
1214/*
1215 * usbvideo_v4l_close()
1216 *
1217 * This is part of Video 4 Linux API. The procedure
1218 * stops streaming and deallocates all buffers that were earlier
1219 * allocated in usbvideo_v4l_open().
1220 *
1221 * History:
1222 * 22-Jan-2000 Moved scratch buffer deallocation here.
1223 * 27-Jan-2000 Used USBVIDEO_NUMSBUF as number of URB buffers.
1224 * 24-May-2000 Moved MOD_DEC_USE_COUNT outside of code that can sleep.
1225 */
1226static int usbvideo_v4l_close(struct file *file)
1227{
1228 struct video_device *dev = file->private_data;
1229 struct uvd *uvd = (struct uvd *) dev;
1230 int i;
1231
1232 if (uvd->debug > 1)
1233 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, dev);
1234
1235 mutex_lock(&uvd->lock);
1236 GET_CALLBACK(uvd, stopDataPump)(uvd);
1237 usbvideo_rvfree(uvd->fbuf, uvd->fbuf_size);
1238 uvd->fbuf = NULL;
1239 RingQueue_Free(&uvd->dp);
1240
1241 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1242 kfree(uvd->sbuf[i].data);
1243 uvd->sbuf[i].data = NULL;
1244 }
1245
1246#if USBVIDEO_REPORT_STATS
1247 usbvideo_ReportStatistics(uvd);
1248#endif
1249
1250 uvd->user--;
1251 if (uvd->remove_pending) {
1252 if (uvd->debug > 0)
1253 dev_info(&uvd->dev->dev, "%s: Final disconnect.\n",
1254 __func__);
1255 usbvideo_CameraRelease(uvd);
1256 }
1257 mutex_unlock(&uvd->lock);
1258 usbvideo_ClientDecModCount(uvd);
1259
1260 if (uvd->debug > 1)
1261 dev_info(&uvd->dev->dev, "%s: Completed.\n", __func__);
1262 file->private_data = NULL;
1263 return 0;
1264}
1265
1266/*
1267 * usbvideo_v4l_ioctl()
1268 *
1269 * This is part of Video 4 Linux API. The procedure handles ioctl() calls.
1270 *
1271 * History:
1272 * 22-Jan-2000 Corrected VIDIOCSPICT to reject unsupported settings.
1273 */
1274static long usbvideo_v4l_do_ioctl(struct file *file, unsigned int cmd, void *arg)
1275{
1276 struct uvd *uvd = file->private_data;
1277
1278 if (!CAMERA_IS_OPERATIONAL(uvd))
1279 return -EIO;
1280
1281 switch (cmd) {
1282 case VIDIOCGCAP:
1283 {
1284 struct video_capability *b = arg;
1285 *b = uvd->vcap;
1286 return 0;
1287 }
1288 case VIDIOCGCHAN:
1289 {
1290 struct video_channel *v = arg;
1291 *v = uvd->vchan;
1292 return 0;
1293 }
1294 case VIDIOCSCHAN:
1295 {
1296 struct video_channel *v = arg;
1297 if (v->channel != 0)
1298 return -EINVAL;
1299 return 0;
1300 }
1301 case VIDIOCGPICT:
1302 {
1303 struct video_picture *pic = arg;
1304 *pic = uvd->vpic;
1305 return 0;
1306 }
1307 case VIDIOCSPICT:
1308 {
1309 struct video_picture *pic = arg;
1310 /*
1311 * Use temporary 'video_picture' structure to preserve our
1312 * own settings (such as color depth, palette) that we
1313 * aren't allowing everyone (V4L client) to change.
1314 */
1315 uvd->vpic.brightness = pic->brightness;
1316 uvd->vpic.hue = pic->hue;
1317 uvd->vpic.colour = pic->colour;
1318 uvd->vpic.contrast = pic->contrast;
1319 uvd->settingsAdjusted = 0; /* Will force new settings */
1320 return 0;
1321 }
1322 case VIDIOCSWIN:
1323 {
1324 struct video_window *vw = arg;
1325
1326 if (VALID_CALLBACK(uvd, setVideoMode))
1327 return GET_CALLBACK(uvd, setVideoMode)(uvd, vw);
1328
1329 if (vw->flags)
1330 return -EINVAL;
1331 if (vw->clipcount)
1332 return -EINVAL;
1333 if (vw->width != VIDEOSIZE_X(uvd->canvas))
1334 return -EINVAL;
1335 if (vw->height != VIDEOSIZE_Y(uvd->canvas))
1336 return -EINVAL;
1337
1338 return 0;
1339 }
1340 case VIDIOCGWIN:
1341 {
1342 struct video_window *vw = arg;
1343
1344 vw->x = 0;
1345 vw->y = 0;
1346 vw->width = VIDEOSIZE_X(uvd->videosize);
1347 vw->height = VIDEOSIZE_Y(uvd->videosize);
1348 vw->chromakey = 0;
1349 if (VALID_CALLBACK(uvd, getFPS))
1350 vw->flags = GET_CALLBACK(uvd, getFPS)(uvd);
1351 else
1352 vw->flags = 10; /* FIXME: do better! */
1353 return 0;
1354 }
1355 case VIDIOCGMBUF:
1356 {
1357 struct video_mbuf *vm = arg;
1358 int i;
1359
1360 memset(vm, 0, sizeof(*vm));
1361 vm->size = uvd->max_frame_size * USBVIDEO_NUMFRAMES;
1362 vm->frames = USBVIDEO_NUMFRAMES;
1363 for (i = 0; i < USBVIDEO_NUMFRAMES; i++)
1364 vm->offsets[i] = i * uvd->max_frame_size;
1365
1366 return 0;
1367 }
1368 case VIDIOCMCAPTURE:
1369 {
1370 struct video_mmap *vm = arg;
1371
1372 if (uvd->debug >= 1) {
1373 dev_info(&uvd->dev->dev,
1374 "VIDIOCMCAPTURE: frame=%d. size=%dx%d, format=%d.\n",
1375 vm->frame, vm->width, vm->height, vm->format);
1376 }
1377 /*
1378 * Check if the requested size is supported. If the requestor
1379 * requests too big a frame then we may be tricked into accessing
1380 * outside of own preallocated frame buffer (in uvd->frame).
1381 * This will cause oops or a security hole. Theoretically, we
1382 * could only clamp the size down to acceptable bounds, but then
1383 * we'd need to figure out how to insert our smaller buffer into
1384 * larger caller's buffer... this is not an easy question. So we
1385 * here just flatly reject too large requests, assuming that the
1386 * caller will resubmit with smaller size. Callers should know
1387 * what size we support (returned by VIDIOCGCAP). However vidcat,
1388 * for one, does not care and allows to ask for any size.
1389 */
1390 if ((vm->width > VIDEOSIZE_X(uvd->canvas)) ||
1391 (vm->height > VIDEOSIZE_Y(uvd->canvas))) {
1392 if (uvd->debug > 0) {
1393 dev_info(&uvd->dev->dev,
1394 "VIDIOCMCAPTURE: Size=%dx%d "
1395 "too large; allowed only up "
1396 "to %ldx%ld\n", vm->width,
1397 vm->height,
1398 VIDEOSIZE_X(uvd->canvas),
1399 VIDEOSIZE_Y(uvd->canvas));
1400 }
1401 return -EINVAL;
1402 }
1403 /* Check if the palette is supported */
1404 if (((1L << vm->format) & uvd->paletteBits) == 0) {
1405 if (uvd->debug > 0) {
1406 dev_info(&uvd->dev->dev,
1407 "VIDIOCMCAPTURE: format=%d. "
1408 "not supported "
1409 "(paletteBits=$%08lx)\n",
1410 vm->format, uvd->paletteBits);
1411 }
1412 return -EINVAL;
1413 }
1414 if ((vm->frame < 0) || (vm->frame >= USBVIDEO_NUMFRAMES)) {
1415 err("VIDIOCMCAPTURE: vm.frame=%d. !E [0-%d]", vm->frame, USBVIDEO_NUMFRAMES-1);
1416 return -EINVAL;
1417 }
1418 if (uvd->frame[vm->frame].frameState == FrameState_Grabbing) {
1419 /* Not an error - can happen */
1420 }
1421 uvd->frame[vm->frame].request = VIDEOSIZE(vm->width, vm->height);
1422 uvd->frame[vm->frame].palette = vm->format;
1423
1424 /* Mark it as ready */
1425 uvd->frame[vm->frame].frameState = FrameState_Ready;
1426
1427 return usbvideo_NewFrame(uvd, vm->frame);
1428 }
1429 case VIDIOCSYNC:
1430 {
1431 int *frameNum = arg;
1432 int ret;
1433
1434 if (*frameNum < 0 || *frameNum >= USBVIDEO_NUMFRAMES)
1435 return -EINVAL;
1436
1437 if (uvd->debug >= 1)
1438 dev_info(&uvd->dev->dev,
1439 "VIDIOCSYNC: syncing to frame %d.\n",
1440 *frameNum);
1441 if (uvd->flags & FLAGS_NO_DECODING)
1442 ret = usbvideo_GetFrame(uvd, *frameNum);
1443 else if (VALID_CALLBACK(uvd, getFrame)) {
1444 ret = GET_CALLBACK(uvd, getFrame)(uvd, *frameNum);
1445 if ((ret < 0) && (uvd->debug >= 1))
1446 err("VIDIOCSYNC: getFrame() returned %d.", ret);
1447 } else {
1448 err("VIDIOCSYNC: getFrame is not set");
1449 ret = -EFAULT;
1450 }
1451
1452 /*
1453 * The frame is in FrameState_Done_Hold state. Release it
1454 * right now because its data is already mapped into
1455 * the user space and it's up to the application to
1456 * make use of it until it asks for another frame.
1457 */
1458 uvd->frame[*frameNum].frameState = FrameState_Unused;
1459 return ret;
1460 }
1461 case VIDIOCGFBUF:
1462 {
1463 struct video_buffer *vb = arg;
1464
1465 memset(vb, 0, sizeof(*vb));
1466 return 0;
1467 }
1468 case VIDIOCKEY:
1469 return 0;
1470
1471 case VIDIOCCAPTURE:
1472 return -EINVAL;
1473
1474 case VIDIOCSFBUF:
1475
1476 case VIDIOCGTUNER:
1477 case VIDIOCSTUNER:
1478
1479 case VIDIOCGFREQ:
1480 case VIDIOCSFREQ:
1481
1482 case VIDIOCGAUDIO:
1483 case VIDIOCSAUDIO:
1484 return -EINVAL;
1485
1486 default:
1487 return -ENOIOCTLCMD;
1488 }
1489 return 0;
1490}
1491
1492static long usbvideo_v4l_ioctl(struct file *file,
1493 unsigned int cmd, unsigned long arg)
1494{
1495 return video_usercopy(file, cmd, arg, usbvideo_v4l_do_ioctl);
1496}
1497
1498/*
1499 * usbvideo_v4l_read()
1500 *
1501 * This is mostly boring stuff. We simply ask for a frame and when it
1502 * arrives copy all the video data from it into user space. There is
1503 * no obvious need to override this method.
1504 *
1505 * History:
1506 * 20-Oct-2000 Created.
1507 * 01-Nov-2000 Added mutex (uvd->lock).
1508 */
1509static ssize_t usbvideo_v4l_read(struct file *file, char __user *buf,
1510 size_t count, loff_t *ppos)
1511{
1512 struct uvd *uvd = file->private_data;
1513 int noblock = file->f_flags & O_NONBLOCK;
1514 int frmx = -1, i;
1515 struct usbvideo_frame *frame;
1516
1517 if (!CAMERA_IS_OPERATIONAL(uvd) || (buf == NULL))
1518 return -EFAULT;
1519
1520 if (uvd->debug >= 1)
1521 dev_info(&uvd->dev->dev,
1522 "%s: %Zd. bytes, noblock=%d.\n",
1523 __func__, count, noblock);
1524
1525 mutex_lock(&uvd->lock);
1526
1527 /* See if a frame is completed, then use it. */
1528 for (i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1529 if ((uvd->frame[i].frameState == FrameState_Done) ||
1530 (uvd->frame[i].frameState == FrameState_Done_Hold) ||
1531 (uvd->frame[i].frameState == FrameState_Error)) {
1532 frmx = i;
1533 break;
1534 }
1535 }
1536
1537 /* FIXME: If we don't start a frame here then who ever does? */
1538 if (noblock && (frmx == -1)) {
1539 count = -EAGAIN;
1540 goto read_done;
1541 }
1542
1543 /*
1544 * If no FrameState_Done, look for a FrameState_Grabbing state.
1545 * See if a frame is in process (grabbing), then use it.
1546 * We will need to wait until it becomes cooked, of course.
1547 */
1548 if (frmx == -1) {
1549 for (i = 0; i < USBVIDEO_NUMFRAMES; i++) {
1550 if (uvd->frame[i].frameState == FrameState_Grabbing) {
1551 frmx = i;
1552 break;
1553 }
1554 }
1555 }
1556
1557 /*
1558 * If no frame is active, start one. We don't care which one
1559 * it will be, so #0 is as good as any.
1560 * In read access mode we don't have convenience of VIDIOCMCAPTURE
1561 * to specify the requested palette (video format) on per-frame
1562 * basis. This means that we have to return data in -some- format
1563 * and just hope that the client knows what to do with it.
1564 * The default format is configured in uvd->defaultPalette field
1565 * as one of VIDEO_PALETTE_xxx values. We stuff it into the new
1566 * frame and initiate the frame filling process.
1567 */
1568 if (frmx == -1) {
1569 if (uvd->defaultPalette == 0) {
1570 err("%s: No default palette; don't know what to do!", __func__);
1571 count = -EFAULT;
1572 goto read_done;
1573 }
1574 frmx = 0;
1575 /*
1576 * We have no per-frame control over video size.
1577 * Therefore we only can use whatever size was
1578 * specified as default.
1579 */
1580 uvd->frame[frmx].request = uvd->videosize;
1581 uvd->frame[frmx].palette = uvd->defaultPalette;
1582 uvd->frame[frmx].frameState = FrameState_Ready;
1583 usbvideo_NewFrame(uvd, frmx);
1584 /* Now frame 0 is supposed to start filling... */
1585 }
1586
1587 /*
1588 * Get a pointer to the active frame. It is either previously
1589 * completed frame or frame in progress but not completed yet.
1590 */
1591 frame = &uvd->frame[frmx];
1592
1593 /*
1594 * Sit back & wait until the frame gets filled and postprocessed.
1595 * If we fail to get the picture [in time] then return the error.
1596 * In this call we specify that we want the frame to be waited for,
1597 * postprocessed and switched into FrameState_Done_Hold state. This
1598 * state is used to hold the frame as "fully completed" between
1599 * subsequent partial reads of the same frame.
1600 */
1601 if (frame->frameState != FrameState_Done_Hold) {
1602 long rv = -EFAULT;
1603 if (uvd->flags & FLAGS_NO_DECODING)
1604 rv = usbvideo_GetFrame(uvd, frmx);
1605 else if (VALID_CALLBACK(uvd, getFrame))
1606 rv = GET_CALLBACK(uvd, getFrame)(uvd, frmx);
1607 else
1608 err("getFrame is not set");
1609 if ((rv != 0) || (frame->frameState != FrameState_Done_Hold)) {
1610 count = rv;
1611 goto read_done;
1612 }
1613 }
1614
1615 /*
1616 * Copy bytes to user space. We allow for partial reads, which
1617 * means that the user application can request read less than
1618 * the full frame size. It is up to the application to issue
1619 * subsequent calls until entire frame is read.
1620 *
1621 * First things first, make sure we don't copy more than we
1622 * have - even if the application wants more. That would be
1623 * a big security embarassment!
1624 */
1625 if ((count + frame->seqRead_Index) > frame->seqRead_Length)
1626 count = frame->seqRead_Length - frame->seqRead_Index;
1627
1628 /*
1629 * Copy requested amount of data to user space. We start
1630 * copying from the position where we last left it, which
1631 * will be zero for a new frame (not read before).
1632 */
1633 if (copy_to_user(buf, frame->data + frame->seqRead_Index, count)) {
1634 count = -EFAULT;
1635 goto read_done;
1636 }
1637
1638 /* Update last read position */
1639 frame->seqRead_Index += count;
1640 if (uvd->debug >= 1) {
1641 err("%s: {copy} count used=%Zd, new seqRead_Index=%ld",
1642 __func__, count, frame->seqRead_Index);
1643 }
1644
1645 /* Finally check if the frame is done with and "release" it */
1646 if (frame->seqRead_Index >= frame->seqRead_Length) {
1647 /* All data has been read */
1648 frame->seqRead_Index = 0;
1649
1650 /* Mark it as available to be used again. */
1651 uvd->frame[frmx].frameState = FrameState_Unused;
1652 if (usbvideo_NewFrame(uvd, (frmx + 1) % USBVIDEO_NUMFRAMES))
1653 err("%s: usbvideo_NewFrame failed.", __func__);
1654 }
1655read_done:
1656 mutex_unlock(&uvd->lock);
1657 return count;
1658}
1659
1660/*
1661 * Make all of the blocks of data contiguous
1662 */
1663static int usbvideo_CompressIsochronous(struct uvd *uvd, struct urb *urb)
1664{
1665 char *cdata;
1666 int i, totlen = 0;
1667
1668 for (i = 0; i < urb->number_of_packets; i++) {
1669 int n = urb->iso_frame_desc[i].actual_length;
1670 int st = urb->iso_frame_desc[i].status;
1671
1672 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
1673
1674 /* Detect and ignore errored packets */
1675 if (st < 0) {
1676 if (uvd->debug >= 1)
1677 err("Data error: packet=%d. len=%d. status=%d.", i, n, st);
1678 uvd->stats.iso_err_count++;
1679 continue;
1680 }
1681
1682 /* Detect and ignore empty packets */
1683 if (n <= 0) {
1684 uvd->stats.iso_skip_count++;
1685 continue;
1686 }
1687 totlen += n; /* Little local accounting */
1688 RingQueue_Enqueue(&uvd->dp, cdata, n);
1689 }
1690 return totlen;
1691}
1692
1693static void usbvideo_IsocIrq(struct urb *urb)
1694{
1695 int i, ret, len;
1696 struct uvd *uvd = urb->context;
1697
1698 /* We don't want to do anything if we are about to be removed! */
1699 if (!CAMERA_IS_OPERATIONAL(uvd))
1700 return;
1701#if 0
1702 if (urb->actual_length > 0) {
1703 dev_info(&uvd->dev->dev,
1704 "urb=$%p status=%d. errcount=%d. length=%d.\n",
1705 urb, urb->status, urb->error_count,
1706 urb->actual_length);
1707 } else {
1708 static int c = 0;
1709 if (c++ % 100 == 0)
1710 dev_info(&uvd->dev->dev, "No Isoc data\n");
1711 }
1712#endif
1713
1714 if (!uvd->streaming) {
1715 if (uvd->debug >= 1)
1716 dev_info(&uvd->dev->dev,
1717 "Not streaming, but interrupt!\n");
1718 return;
1719 }
1720
1721 uvd->stats.urb_count++;
1722 if (urb->actual_length <= 0)
1723 goto urb_done_with;
1724
1725 /* Copy the data received into ring queue */
1726 len = usbvideo_CompressIsochronous(uvd, urb);
1727 uvd->stats.urb_length = len;
1728 if (len <= 0)
1729 goto urb_done_with;
1730
1731 /* Here we got some data */
1732 uvd->stats.data_count += len;
1733 RingQueue_WakeUpInterruptible(&uvd->dp);
1734
1735urb_done_with:
1736 for (i = 0; i < FRAMES_PER_DESC; i++) {
1737 urb->iso_frame_desc[i].status = 0;
1738 urb->iso_frame_desc[i].actual_length = 0;
1739 }
1740 urb->status = 0;
1741 urb->dev = uvd->dev;
1742 ret = usb_submit_urb(urb, GFP_KERNEL);
1743 if (ret)
1744 err("usb_submit_urb error (%d)", ret);
1745 return;
1746}
1747
1748/*
1749 * usbvideo_StartDataPump()
1750 *
1751 * History:
1752 * 27-Jan-2000 Used ibmcam->iface, ibmcam->ifaceAltActive instead
1753 * of hardcoded values. Simplified by using for loop,
1754 * allowed any number of URBs.
1755 */
1756static int usbvideo_StartDataPump(struct uvd *uvd)
1757{
1758 struct usb_device *dev = uvd->dev;
1759 int i, errFlag;
1760
1761 if (uvd->debug > 1)
1762 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd);
1763
1764 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1765 err("%s: Camera is not operational", __func__);
1766 return -EFAULT;
1767 }
1768 uvd->curframe = -1;
1769
1770 /* Alternate interface 1 is is the biggest frame size */
1771 i = usb_set_interface(dev, uvd->iface, uvd->ifaceAltActive);
1772 if (i < 0) {
1773 err("%s: usb_set_interface error", __func__);
1774 uvd->last_error = i;
1775 return -EBUSY;
1776 }
1777 if (VALID_CALLBACK(uvd, videoStart))
1778 GET_CALLBACK(uvd, videoStart)(uvd);
1779 else
1780 err("%s: videoStart not set", __func__);
1781
1782 /* We double buffer the Iso lists */
1783 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1784 int j, k;
1785 struct urb *urb = uvd->sbuf[i].urb;
1786 urb->dev = dev;
1787 urb->context = uvd;
1788 urb->pipe = usb_rcvisocpipe(dev, uvd->video_endp);
1789 urb->interval = 1;
1790 urb->transfer_flags = URB_ISO_ASAP;
1791 urb->transfer_buffer = uvd->sbuf[i].data;
1792 urb->complete = usbvideo_IsocIrq;
1793 urb->number_of_packets = FRAMES_PER_DESC;
1794 urb->transfer_buffer_length = uvd->iso_packet_len * FRAMES_PER_DESC;
1795 for (j = k = 0; j < FRAMES_PER_DESC; j++, k += uvd->iso_packet_len) {
1796 urb->iso_frame_desc[j].offset = k;
1797 urb->iso_frame_desc[j].length = uvd->iso_packet_len;
1798 }
1799 }
1800
1801 /* Submit all URBs */
1802 for (i = 0; i < USBVIDEO_NUMSBUF; i++) {
1803 errFlag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
1804 if (errFlag)
1805 err("%s: usb_submit_isoc(%d) ret %d", __func__, i, errFlag);
1806 }
1807
1808 uvd->streaming = 1;
1809 if (uvd->debug > 1)
1810 dev_info(&uvd->dev->dev,
1811 "%s: streaming=1 video_endp=$%02x\n", __func__,
1812 uvd->video_endp);
1813 return 0;
1814}
1815
1816/*
1817 * usbvideo_StopDataPump()
1818 *
1819 * This procedure stops streaming and deallocates URBs. Then it
1820 * activates zero-bandwidth alt. setting of the video interface.
1821 *
1822 * History:
1823 * 22-Jan-2000 Corrected order of actions to work after surprise removal.
1824 * 27-Jan-2000 Used uvd->iface, uvd->ifaceAltInactive instead of hardcoded values.
1825 */
1826static void usbvideo_StopDataPump(struct uvd *uvd)
1827{
1828 int i, j;
1829
1830 if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
1831 return;
1832
1833 if (uvd->debug > 1)
1834 dev_info(&uvd->dev->dev, "%s($%p)\n", __func__, uvd);
1835
1836 /* Unschedule all of the iso td's */
1837 for (i = 0; i < USBVIDEO_NUMSBUF; i++)
1838 usb_kill_urb(uvd->sbuf[i].urb);
1839 if (uvd->debug > 1)
1840 dev_info(&uvd->dev->dev, "%s: streaming=0\n", __func__);
1841 uvd->streaming = 0;
1842
1843 if (!uvd->remove_pending) {
1844 /* Invoke minidriver's magic to stop the camera */
1845 if (VALID_CALLBACK(uvd, videoStop))
1846 GET_CALLBACK(uvd, videoStop)(uvd);
1847 else
1848 err("%s: videoStop not set", __func__);
1849
1850 /* Set packet size to 0 */
1851 j = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltInactive);
1852 if (j < 0) {
1853 err("%s: usb_set_interface() error %d.", __func__, j);
1854 uvd->last_error = j;
1855 }
1856 }
1857}
1858
1859/*
1860 * usbvideo_NewFrame()
1861 *
1862 * History:
1863 * 29-Mar-00 Added copying of previous frame into the current one.
1864 * 6-Aug-00 Added model 3 video sizes, removed redundant width, height.
1865 */
1866static int usbvideo_NewFrame(struct uvd *uvd, int framenum)
1867{
1868 struct usbvideo_frame *frame;
1869 int n;
1870
1871 if (uvd->debug > 1)
1872 dev_info(&uvd->dev->dev, "usbvideo_NewFrame($%p,%d.)\n", uvd,
1873 framenum);
1874
1875 /* If we're not grabbing a frame right now and the other frame is */
1876 /* ready to be grabbed into, then use it instead */
1877 if (uvd->curframe != -1)
1878 return 0;
1879
1880 /* If necessary we adjust picture settings between frames */
1881 if (!uvd->settingsAdjusted) {
1882 if (VALID_CALLBACK(uvd, adjustPicture))
1883 GET_CALLBACK(uvd, adjustPicture)(uvd);
1884 uvd->settingsAdjusted = 1;
1885 }
1886
1887 n = (framenum + 1) % USBVIDEO_NUMFRAMES;
1888 if (uvd->frame[n].frameState == FrameState_Ready)
1889 framenum = n;
1890
1891 frame = &uvd->frame[framenum];
1892
1893 frame->frameState = FrameState_Grabbing;
1894 frame->scanstate = ScanState_Scanning;
1895 frame->seqRead_Length = 0; /* Accumulated in xxx_parse_data() */
1896 frame->deinterlace = Deinterlace_None;
1897 frame->flags = 0; /* No flags yet, up to minidriver (or us) to set them */
1898 uvd->curframe = framenum;
1899
1900 /*
1901 * Normally we would want to copy previous frame into the current one
1902 * before we even start filling it with data; this allows us to stop
1903 * filling at any moment; top portion of the frame will be new and
1904 * bottom portion will stay as it was in previous frame. If we don't
1905 * do that then missing chunks of video stream will result in flickering
1906 * portions of old data whatever it was before.
1907 *
1908 * If we choose not to copy previous frame (to, for example, save few
1909 * bus cycles - the frame can be pretty large!) then we have an option
1910 * to clear the frame before using. If we experience losses in this
1911 * mode then missing picture will be black (no flickering).
1912 *
1913 * Finally, if user chooses not to clean the current frame before
1914 * filling it with data then the old data will be visible if we fail
1915 * to refill entire frame with new data.
1916 */
1917 if (!(uvd->flags & FLAGS_SEPARATE_FRAMES)) {
1918 /* This copies previous frame into this one to mask losses */
1919 int prev = (framenum - 1 + USBVIDEO_NUMFRAMES) % USBVIDEO_NUMFRAMES;
1920 memmove(frame->data, uvd->frame[prev].data, uvd->max_frame_size);
1921 } else {
1922 if (uvd->flags & FLAGS_CLEAN_FRAMES) {
1923 /* This provides a "clean" frame but slows things down */
1924 memset(frame->data, 0, uvd->max_frame_size);
1925 }
1926 }
1927 return 0;
1928}
1929
1930/*
1931 * usbvideo_CollectRawData()
1932 *
1933 * This procedure can be used instead of 'processData' callback if you
1934 * only want to dump the raw data from the camera into the output
1935 * device (frame buffer). You can look at it with V4L client, but the
1936 * image will be unwatchable. The main purpose of this code and of the
1937 * mode FLAGS_NO_DECODING is debugging and capturing of datastreams from
1938 * new, unknown cameras. This procedure will be automatically invoked
1939 * instead of the specified callback handler when uvd->flags has bit
1940 * FLAGS_NO_DECODING set. Therefore, any regular build of any driver
1941 * based on usbvideo can use this feature at any time.
1942 */
1943static void usbvideo_CollectRawData(struct uvd *uvd, struct usbvideo_frame *frame)
1944{
1945 int n;
1946
1947 assert(uvd != NULL);
1948 assert(frame != NULL);
1949
1950 /* Try to move data from queue into frame buffer */
1951 n = RingQueue_GetLength(&uvd->dp);
1952 if (n > 0) {
1953 int m;
1954 /* See how much space we have left */
1955 m = uvd->max_frame_size - frame->seqRead_Length;
1956 if (n > m)
1957 n = m;
1958 /* Now move that much data into frame buffer */
1959 RingQueue_Dequeue(
1960 &uvd->dp,
1961 frame->data + frame->seqRead_Length,
1962 m);
1963 frame->seqRead_Length += m;
1964 }
1965 /* See if we filled the frame */
1966 if (frame->seqRead_Length >= uvd->max_frame_size) {
1967 frame->frameState = FrameState_Done;
1968 uvd->curframe = -1;
1969 uvd->stats.frame_num++;
1970 }
1971}
1972
1973static int usbvideo_GetFrame(struct uvd *uvd, int frameNum)
1974{
1975 struct usbvideo_frame *frame = &uvd->frame[frameNum];
1976
1977 if (uvd->debug >= 2)
1978 dev_info(&uvd->dev->dev, "%s($%p,%d.)\n", __func__, uvd,
1979 frameNum);
1980
1981 switch (frame->frameState) {
1982 case FrameState_Unused:
1983 if (uvd->debug >= 2)
1984 dev_info(&uvd->dev->dev, "%s: FrameState_Unused\n",
1985 __func__);
1986 return -EINVAL;
1987 case FrameState_Ready:
1988 case FrameState_Grabbing:
1989 case FrameState_Error:
1990 {
1991 int ntries, signalPending;
1992redo:
1993 if (!CAMERA_IS_OPERATIONAL(uvd)) {
1994 if (uvd->debug >= 2)
1995 dev_info(&uvd->dev->dev,
1996 "%s: Camera is not operational (1)\n",
1997 __func__);
1998 return -EIO;
1999 }
2000 ntries = 0;
2001 do {
2002 RingQueue_InterruptibleSleepOn(&uvd->dp);
2003 signalPending = signal_pending(current);
2004 if (!CAMERA_IS_OPERATIONAL(uvd)) {
2005 if (uvd->debug >= 2)
2006 dev_info(&uvd->dev->dev,
2007 "%s: Camera is not "
2008 "operational (2)\n", __func__);
2009 return -EIO;
2010 }
2011 assert(uvd->fbuf != NULL);
2012 if (signalPending) {
2013 if (uvd->debug >= 2)
2014 dev_info(&uvd->dev->dev,
2015 "%s: Signal=$%08x\n", __func__,
2016 signalPending);
2017 if (uvd->flags & FLAGS_RETRY_VIDIOCSYNC) {
2018 usbvideo_TestPattern(uvd, 1, 0);
2019 uvd->curframe = -1;
2020 uvd->stats.frame_num++;
2021 if (uvd->debug >= 2)
2022 dev_info(&uvd->dev->dev,
2023 "%s: Forced test "
2024 "pattern screen\n",
2025 __func__);
2026 return 0;
2027 } else {
2028 /* Standard answer: Interrupted! */
2029 if (uvd->debug >= 2)
2030 dev_info(&uvd->dev->dev,
2031 "%s: Interrupted!\n",
2032 __func__);
2033 return -EINTR;
2034 }
2035 } else {
2036 /* No signals - we just got new data in dp queue */
2037 if (uvd->flags & FLAGS_NO_DECODING)
2038 usbvideo_CollectRawData(uvd, frame);
2039 else if (VALID_CALLBACK(uvd, processData))
2040 GET_CALLBACK(uvd, processData)(uvd, frame);
2041 else
2042 err("%s: processData not set", __func__);
2043 }
2044 } while (frame->frameState == FrameState_Grabbing);
2045 if (uvd->debug >= 2) {
2046 dev_info(&uvd->dev->dev,
2047 "%s: Grabbing done; state=%d. (%lu. bytes)\n",
2048 __func__, frame->frameState,
2049 frame->seqRead_Length);
2050 }
2051 if (frame->frameState == FrameState_Error) {
2052 int ret = usbvideo_NewFrame(uvd, frameNum);
2053 if (ret < 0) {
2054 err("%s: usbvideo_NewFrame() failed (%d.)", __func__, ret);
2055 return ret;
2056 }
2057 goto redo;
2058 }
2059 /* Note that we fall through to meet our destiny below */
2060 }
2061 case FrameState_Done:
2062 /*
2063 * Do all necessary postprocessing of data prepared in
2064 * "interrupt" code and the collecting code above. The
2065 * frame gets marked as FrameState_Done by queue parsing code.
2066 * This status means that we collected enough data and
2067 * most likely processed it as we went through. However
2068 * the data may need postprocessing, such as deinterlacing
2069 * or picture adjustments implemented in software (horror!)
2070 *
2071 * As soon as the frame becomes "final" it gets promoted to
2072 * FrameState_Done_Hold status where it will remain until the
2073 * caller consumed all the video data from the frame. Then
2074 * the empty shell of ex-frame is thrown out for dogs to eat.
2075 * But we, worried about pets, will recycle the frame!
2076 */
2077 uvd->stats.frame_num++;
2078 if ((uvd->flags & FLAGS_NO_DECODING) == 0) {
2079 if (VALID_CALLBACK(uvd, postProcess))
2080 GET_CALLBACK(uvd, postProcess)(uvd, frame);
2081 if (frame->flags & USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST)
2082 usbvideo_SoftwareContrastAdjustment(uvd, frame);
2083 }
2084 frame->frameState = FrameState_Done_Hold;
2085 if (uvd->debug >= 2)
2086 dev_info(&uvd->dev->dev,
2087 "%s: Entered FrameState_Done_Hold state.\n",
2088 __func__);
2089 return 0;
2090
2091 case FrameState_Done_Hold:
2092 /*
2093 * We stay in this state indefinitely until someone external,
2094 * like ioctl() or read() call finishes digesting the frame
2095 * data. Then it will mark the frame as FrameState_Unused and
2096 * it will be released back into the wild to roam freely.
2097 */
2098 if (uvd->debug >= 2)
2099 dev_info(&uvd->dev->dev,
2100 "%s: FrameState_Done_Hold state.\n",
2101 __func__);
2102 return 0;
2103 }
2104
2105 /* Catch-all for other cases. We shall not be here. */
2106 err("%s: Invalid state %d.", __func__, frame->frameState);
2107 frame->frameState = FrameState_Unused;
2108 return 0;
2109}
2110
2111/*
2112 * usbvideo_DeinterlaceFrame()
2113 *
2114 * This procedure deinterlaces the given frame. Some cameras produce
2115 * only half of scanlines - sometimes only even lines, sometimes only
2116 * odd lines. The deinterlacing method is stored in frame->deinterlace
2117 * variable.
2118 *
2119 * Here we scan the frame vertically and replace missing scanlines with
2120 * average between surrounding ones - before and after. If we have no
2121 * line above then we just copy next line. Similarly, if we need to
2122 * create a last line then preceding line is used.
2123 */
2124void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame)
2125{
2126 if ((uvd == NULL) || (frame == NULL))
2127 return;
2128
2129 if ((frame->deinterlace == Deinterlace_FillEvenLines) ||
2130 (frame->deinterlace == Deinterlace_FillOddLines)) {
2131 const int v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2132 int i = (frame->deinterlace == Deinterlace_FillEvenLines) ? 0 : 1;
2133
2134 for (; i < VIDEOSIZE_Y(frame->request); i += 2) {
2135 const unsigned char *fs1, *fs2;
2136 unsigned char *fd;
2137 int ip, in, j; /* Previous and next lines */
2138
2139 /*
2140 * Need to average lines before and after 'i'.
2141 * If we go out of bounds seeking those lines then
2142 * we point back to existing line.
2143 */
2144 ip = i - 1; /* First, get rough numbers */
2145 in = i + 1;
2146
2147 /* Now validate */
2148 if (ip < 0)
2149 ip = in;
2150 if (in >= VIDEOSIZE_Y(frame->request))
2151 in = ip;
2152
2153 /* Sanity check */
2154 if ((ip < 0) || (in < 0) ||
2155 (ip >= VIDEOSIZE_Y(frame->request)) ||
2156 (in >= VIDEOSIZE_Y(frame->request))) {
2157 err("Error: ip=%d. in=%d. req.height=%ld.",
2158 ip, in, VIDEOSIZE_Y(frame->request));
2159 break;
2160 }
2161
2162 /* Now we need to average lines 'ip' and 'in' to produce line 'i' */
2163 fs1 = frame->data + (v4l_linesize * ip);
2164 fs2 = frame->data + (v4l_linesize * in);
2165 fd = frame->data + (v4l_linesize * i);
2166
2167 /* Average lines around destination */
2168 for (j = 0; j < v4l_linesize; j++) {
2169 fd[j] = (unsigned char)((((unsigned) fs1[j]) +
2170 ((unsigned)fs2[j])) >> 1);
2171 }
2172 }
2173 }
2174
2175 /* Optionally display statistics on the screen */
2176 if (uvd->flags & FLAGS_OVERLAY_STATS)
2177 usbvideo_OverlayStats(uvd, frame);
2178}
2179
2180EXPORT_SYMBOL(usbvideo_DeinterlaceFrame);
2181
2182/*
2183 * usbvideo_SoftwareContrastAdjustment()
2184 *
2185 * This code adjusts the contrast of the frame, assuming RGB24 format.
2186 * As most software image processing, this job is CPU-intensive.
2187 * Get a camera that supports hardware adjustment!
2188 *
2189 * History:
2190 * 09-Feb-2001 Created.
2191 */
2192static void usbvideo_SoftwareContrastAdjustment(struct uvd *uvd,
2193 struct usbvideo_frame *frame)
2194{
2195 int i, j, v4l_linesize;
2196 signed long adj;
2197 const int ccm = 128; /* Color correction median - see below */
2198
2199 if ((uvd == NULL) || (frame == NULL)) {
2200 err("%s: Illegal call.", __func__);
2201 return;
2202 }
2203 adj = (uvd->vpic.contrast - 0x8000) >> 8; /* -128..+127 = -ccm..+(ccm-1)*/
2204 RESTRICT_TO_RANGE(adj, -ccm, ccm+1);
2205 if (adj == 0) {
2206 /* In rare case of no adjustment */
2207 return;
2208 }
2209 v4l_linesize = VIDEOSIZE_X(frame->request) * V4L_BYTES_PER_PIXEL;
2210 for (i = 0; i < VIDEOSIZE_Y(frame->request); i++) {
2211 unsigned char *fd = frame->data + (v4l_linesize * i);
2212 for (j = 0; j < v4l_linesize; j++) {
2213 signed long v = (signed long) fd[j];
2214 /* Magnify up to 2 times, reduce down to zero */
2215 v = 128 + ((ccm + adj) * (v - 128)) / ccm;
2216 RESTRICT_TO_RANGE(v, 0, 0xFF); /* Must flatten tails */
2217 fd[j] = (unsigned char) v;
2218 }
2219 }
2220}
2221
2222MODULE_LICENSE("GPL");
diff --git a/drivers/staging/usbvideo/usbvideo.h b/drivers/staging/usbvideo/usbvideo.h
deleted file mode 100644
index 95638a072b19..000000000000
--- a/drivers/staging/usbvideo/usbvideo.h
+++ /dev/null
@@ -1,395 +0,0 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15 */
16#ifndef usbvideo_h
17#define usbvideo_h
18
19#include "videodev.h"
20#include <media/v4l2-common.h>
21#include <media/v4l2-ioctl.h>
22#include <linux/usb.h>
23#include <linux/mutex.h>
24
25/* Most helpful debugging aid */
26#define assert(expr) ((void) ((expr) ? 0 : (err("assert failed at line %d",__LINE__))))
27
28#define USBVIDEO_REPORT_STATS 1 /* Set to 0 to block statistics on close */
29
30/* Bit flags (options) */
31#define FLAGS_RETRY_VIDIOCSYNC (1 << 0)
32#define FLAGS_MONOCHROME (1 << 1)
33#define FLAGS_DISPLAY_HINTS (1 << 2)
34#define FLAGS_OVERLAY_STATS (1 << 3)
35#define FLAGS_FORCE_TESTPATTERN (1 << 4)
36#define FLAGS_SEPARATE_FRAMES (1 << 5)
37#define FLAGS_CLEAN_FRAMES (1 << 6)
38#define FLAGS_NO_DECODING (1 << 7)
39
40/* Bit flags for frames (apply to the frame where they are specified) */
41#define USBVIDEO_FRAME_FLAG_SOFTWARE_CONTRAST (1 << 0)
42
43/* Camera capabilities (maximum) */
44#define CAMERA_URB_FRAMES 32
45#define CAMERA_MAX_ISO_PACKET 1023 /* 1022 actually sent by camera */
46#define FRAMES_PER_DESC (CAMERA_URB_FRAMES)
47#define FRAME_SIZE_PER_DESC (CAMERA_MAX_ISO_PACKET)
48
49/* This macro restricts an int variable to an inclusive range */
50#define RESTRICT_TO_RANGE(v,mi,ma) { if ((v) < (mi)) (v) = (mi); else if ((v) > (ma)) (v) = (ma); }
51
52#define V4L_BYTES_PER_PIXEL 3 /* Because we produce RGB24 */
53
54/*
55 * Use this macro to construct constants for different video sizes.
56 * We have to deal with different video sizes that have to be
57 * configured in the device or compared against when we receive
58 * a data. Normally one would define a bunch of VIDEOSIZE_x_by_y
59 * #defines and that's the end of story. However this solution
60 * does not allow to convert between real pixel sizes and the
61 * constant (integer) value that may be used to tag a frame or
62 * whatever. The set of macros below constructs videosize constants
63 * from the pixel size and allows to reconstruct the pixel size
64 * from the combined value later.
65 */
66#define VIDEOSIZE(x,y) (((x) & 0xFFFFL) | (((y) & 0xFFFFL) << 16))
67#define VIDEOSIZE_X(vs) ((vs) & 0xFFFFL)
68#define VIDEOSIZE_Y(vs) (((vs) >> 16) & 0xFFFFL)
69typedef unsigned long videosize_t;
70
71/*
72 * This macro checks if the camera is still operational. The 'uvd'
73 * pointer must be valid, uvd->dev must be valid, we are not
74 * removing the device and the device has not erred on us.
75 */
76#define CAMERA_IS_OPERATIONAL(uvd) (\
77 (uvd != NULL) && \
78 ((uvd)->dev != NULL) && \
79 ((uvd)->last_error == 0) && \
80 (!(uvd)->remove_pending))
81
82/*
83 * We use macros to do YUV -> RGB conversion because this is
84 * very important for speed and totally unimportant for size.
85 *
86 * YUV -> RGB Conversion
87 * ---------------------
88 *
89 * B = 1.164*(Y-16) + 2.018*(V-128)
90 * G = 1.164*(Y-16) - 0.813*(U-128) - 0.391*(V-128)
91 * R = 1.164*(Y-16) + 1.596*(U-128)
92 *
93 * If you fancy integer arithmetics (as you should), hear this:
94 *
95 * 65536*B = 76284*(Y-16) + 132252*(V-128)
96 * 65536*G = 76284*(Y-16) - 53281*(U-128) - 25625*(V-128)
97 * 65536*R = 76284*(Y-16) + 104595*(U-128)
98 *
99 * Make sure the output values are within [0..255] range.
100 */
101#define LIMIT_RGB(x) (((x) < 0) ? 0 : (((x) > 255) ? 255 : (x)))
102#define YUV_TO_RGB_BY_THE_BOOK(my,mu,mv,mr,mg,mb) { \
103 int mm_y, mm_yc, mm_u, mm_v, mm_r, mm_g, mm_b; \
104 mm_y = (my) - 16; \
105 mm_u = (mu) - 128; \
106 mm_v = (mv) - 128; \
107 mm_yc= mm_y * 76284; \
108 mm_b = (mm_yc + 132252*mm_v ) >> 16; \
109 mm_g = (mm_yc - 53281*mm_u - 25625*mm_v ) >> 16; \
110 mm_r = (mm_yc + 104595*mm_u ) >> 16; \
111 mb = LIMIT_RGB(mm_b); \
112 mg = LIMIT_RGB(mm_g); \
113 mr = LIMIT_RGB(mm_r); \
114}
115
116#define RING_QUEUE_SIZE (128*1024) /* Must be a power of 2 */
117#define RING_QUEUE_ADVANCE_INDEX(rq,ind,n) (rq)->ind = ((rq)->ind + (n)) & ((rq)->length-1)
118#define RING_QUEUE_DEQUEUE_BYTES(rq,n) RING_QUEUE_ADVANCE_INDEX(rq,ri,n)
119#define RING_QUEUE_PEEK(rq,ofs) ((rq)->queue[((ofs) + (rq)->ri) & ((rq)->length-1)])
120
121struct RingQueue {
122 unsigned char *queue; /* Data from the Isoc data pump */
123 int length; /* How many bytes allocated for the queue */
124 int wi; /* That's where we write */
125 int ri; /* Read from here until you hit write index */
126 wait_queue_head_t wqh; /* Processes waiting */
127};
128
129enum ScanState {
130 ScanState_Scanning, /* Scanning for header */
131 ScanState_Lines /* Parsing lines */
132};
133
134/* Completion states of the data parser */
135enum ParseState {
136 scan_Continue, /* Just parse next item */
137 scan_NextFrame, /* Frame done, send it to V4L */
138 scan_Out, /* Not enough data for frame */
139 scan_EndParse /* End parsing */
140};
141
142enum FrameState {
143 FrameState_Unused, /* Unused (no MCAPTURE) */
144 FrameState_Ready, /* Ready to start grabbing */
145 FrameState_Grabbing, /* In the process of being grabbed into */
146 FrameState_Done, /* Finished grabbing, but not been synced yet */
147 FrameState_Done_Hold, /* Are syncing or reading */
148 FrameState_Error, /* Something bad happened while processing */
149};
150
151/*
152 * Some frames may contain only even or odd lines. This type
153 * specifies what type of deinterlacing is required.
154 */
155enum Deinterlace {
156 Deinterlace_None=0,
157 Deinterlace_FillOddLines,
158 Deinterlace_FillEvenLines
159};
160
161#define USBVIDEO_NUMFRAMES 2 /* How many frames we work with */
162#define USBVIDEO_NUMSBUF 2 /* How many URBs linked in a ring */
163
164/* This structure represents one Isoc request - URB and buffer */
165struct usbvideo_sbuf {
166 char *data;
167 struct urb *urb;
168};
169
170struct usbvideo_frame {
171 char *data; /* Frame buffer */
172 unsigned long header; /* Significant bits from the header */
173
174 videosize_t canvas; /* The canvas (max. image) allocated */
175 videosize_t request; /* That's what the application asked for */
176 unsigned short palette; /* The desired format */
177
178 enum FrameState frameState;/* State of grabbing */
179 enum ScanState scanstate; /* State of scanning */
180 enum Deinterlace deinterlace;
181 int flags; /* USBVIDEO_FRAME_FLAG_xxx bit flags */
182
183 int curline; /* Line of frame we're working on */
184
185 long seqRead_Length; /* Raw data length of frame */
186 long seqRead_Index; /* Amount of data that has been already read */
187
188 void *user; /* Additional data that user may need */
189};
190
191/* Statistics that can be overlaid on screen */
192struct usbvideo_statistics {
193 unsigned long frame_num; /* Sequential number of the frame */
194 unsigned long urb_count; /* How many URBs we received so far */
195 unsigned long urb_length; /* Length of last URB */
196 unsigned long data_count; /* How many bytes we received */
197 unsigned long header_count; /* How many frame headers we found */
198 unsigned long iso_skip_count; /* How many empty ISO packets received */
199 unsigned long iso_err_count; /* How many bad ISO packets received */
200};
201
202struct usbvideo;
203
204struct uvd {
205 struct video_device vdev; /* Must be the first field! */
206 struct usb_device *dev;
207 struct usbvideo *handle; /* Points back to the struct usbvideo */
208 void *user_data; /* Camera-dependent data */
209 int user_size; /* Size of that camera-dependent data */
210 int debug; /* Debug level for usbvideo */
211 unsigned char iface; /* Video interface number */
212 unsigned char video_endp;
213 unsigned char ifaceAltActive;
214 unsigned char ifaceAltInactive; /* Alt settings */
215 unsigned long flags; /* FLAGS_USBVIDEO_xxx */
216 unsigned long paletteBits; /* Which palettes we accept? */
217 unsigned short defaultPalette; /* What palette to use for read() */
218 struct mutex lock;
219 int user; /* user count for exclusive use */
220
221 videosize_t videosize; /* Current setting */
222 videosize_t canvas; /* This is the width,height of the V4L canvas */
223 int max_frame_size; /* Bytes in one video frame */
224
225 int uvd_used; /* Is this structure in use? */
226 int streaming; /* Are we streaming Isochronous? */
227 int grabbing; /* Are we grabbing? */
228 int settingsAdjusted; /* Have we adjusted contrast etc.? */
229 int last_error; /* What calamity struck us? */
230
231 char *fbuf; /* Videodev buffer area */
232 int fbuf_size; /* Videodev buffer size */
233
234 int curframe;
235 int iso_packet_len; /* Videomode-dependent, saves bus bandwidth */
236
237 struct RingQueue dp; /* Isoc data pump */
238 struct usbvideo_frame frame[USBVIDEO_NUMFRAMES];
239 struct usbvideo_sbuf sbuf[USBVIDEO_NUMSBUF];
240
241 volatile int remove_pending; /* If set then about to exit */
242
243 struct video_picture vpic, vpic_old; /* Picture settings */
244 struct video_capability vcap; /* Video capabilities */
245 struct video_channel vchan; /* May be used for tuner support */
246 struct usbvideo_statistics stats;
247 char videoName[32]; /* Holds name like "video7" */
248};
249
250/*
251 * usbvideo callbacks (virtual methods). They are set when usbvideo
252 * services are registered. All of these default to NULL, except those
253 * that default to usbvideo-provided methods.
254 */
255struct usbvideo_cb {
256 int (*probe)(struct usb_interface *, const struct usb_device_id *);
257 void (*userFree)(struct uvd *);
258 void (*disconnect)(struct usb_interface *);
259 int (*setupOnOpen)(struct uvd *);
260 void (*videoStart)(struct uvd *);
261 void (*videoStop)(struct uvd *);
262 void (*processData)(struct uvd *, struct usbvideo_frame *);
263 void (*postProcess)(struct uvd *, struct usbvideo_frame *);
264 void (*adjustPicture)(struct uvd *);
265 int (*getFPS)(struct uvd *);
266 int (*overlayHook)(struct uvd *, struct usbvideo_frame *);
267 int (*getFrame)(struct uvd *, int);
268 int (*startDataPump)(struct uvd *uvd);
269 void (*stopDataPump)(struct uvd *uvd);
270 int (*setVideoMode)(struct uvd *uvd, struct video_window *vw);
271};
272
273struct usbvideo {
274 int num_cameras; /* As allocated */
275 struct usb_driver usbdrv; /* Interface to the USB stack */
276 char drvName[80]; /* Driver name */
277 struct mutex lock; /* Mutex protecting camera structures */
278 struct usbvideo_cb cb; /* Table of callbacks (virtual methods) */
279 struct video_device vdt; /* Video device template */
280 struct uvd *cam; /* Array of camera structures */
281 struct module *md_module; /* Minidriver module */
282};
283
284
285/*
286 * This macro retrieves callback address from the struct uvd object.
287 * No validity checks are done here, so be sure to check the
288 * callback beforehand with VALID_CALLBACK.
289 */
290#define GET_CALLBACK(uvd,cbName) ((uvd)->handle->cb.cbName)
291
292/*
293 * This macro returns either callback pointer or NULL. This is safe
294 * macro, meaning that most of components of data structures involved
295 * may be NULL - this only results in NULL being returned. You may
296 * wish to use this macro to make sure that the callback is callable.
297 * However keep in mind that those checks take time.
298 */
299#define VALID_CALLBACK(uvd,cbName) ((((uvd) != NULL) && \
300 ((uvd)->handle != NULL)) ? GET_CALLBACK(uvd,cbName) : NULL)
301
302int RingQueue_Dequeue(struct RingQueue *rq, unsigned char *dst, int len);
303int RingQueue_Enqueue(struct RingQueue *rq, const unsigned char *cdata, int n);
304void RingQueue_WakeUpInterruptible(struct RingQueue *rq);
305void RingQueue_Flush(struct RingQueue *rq);
306
307static inline int RingQueue_GetLength(const struct RingQueue *rq)
308{
309 return (rq->wi - rq->ri + rq->length) & (rq->length-1);
310}
311
312static inline int RingQueue_GetFreeSpace(const struct RingQueue *rq)
313{
314 return rq->length - RingQueue_GetLength(rq);
315}
316
317void usbvideo_DrawLine(
318 struct usbvideo_frame *frame,
319 int x1, int y1,
320 int x2, int y2,
321 unsigned char cr, unsigned char cg, unsigned char cb);
322void usbvideo_HexDump(const unsigned char *data, int len);
323void usbvideo_SayAndWait(const char *what);
324void usbvideo_TestPattern(struct uvd *uvd, int fullframe, int pmode);
325
326/* Memory allocation routines */
327unsigned long usbvideo_kvirt_to_pa(unsigned long adr);
328
329int usbvideo_register(
330 struct usbvideo **pCams,
331 const int num_cams,
332 const int num_extra,
333 const char *driverName,
334 const struct usbvideo_cb *cbTable,
335 struct module *md,
336 const struct usb_device_id *id_table);
337struct uvd *usbvideo_AllocateDevice(struct usbvideo *cams);
338int usbvideo_RegisterVideoDevice(struct uvd *uvd);
339void usbvideo_Deregister(struct usbvideo **uvt);
340
341int usbvideo_v4l_initialize(struct video_device *dev);
342
343void usbvideo_DeinterlaceFrame(struct uvd *uvd, struct usbvideo_frame *frame);
344
345/*
346 * This code performs bounds checking - use it when working with
347 * new formats, or else you may get oopses all over the place.
348 * If pixel falls out of bounds then it gets shoved back (as close
349 * to place of offence as possible) and is painted bright red.
350 *
351 * There are two important concepts: frame width, height and
352 * V4L canvas width, height. The former is the area requested by
353 * the application -for this very frame-. The latter is the largest
354 * possible frame that we can serve (we advertise that via V4L ioctl).
355 * The frame data is expected to be formatted as lines of length
356 * VIDEOSIZE_X(fr->request), total VIDEOSIZE_Y(frame->request) lines.
357 */
358static inline void RGB24_PUTPIXEL(
359 struct usbvideo_frame *fr,
360 int ix, int iy,
361 unsigned char vr,
362 unsigned char vg,
363 unsigned char vb)
364{
365 register unsigned char *pf;
366 int limiter = 0, mx, my;
367 mx = ix;
368 my = iy;
369 if (mx < 0) {
370 mx=0;
371 limiter++;
372 } else if (mx >= VIDEOSIZE_X((fr)->request)) {
373 mx= VIDEOSIZE_X((fr)->request) - 1;
374 limiter++;
375 }
376 if (my < 0) {
377 my = 0;
378 limiter++;
379 } else if (my >= VIDEOSIZE_Y((fr)->request)) {
380 my = VIDEOSIZE_Y((fr)->request) - 1;
381 limiter++;
382 }
383 pf = (fr)->data + V4L_BYTES_PER_PIXEL*((iy)*VIDEOSIZE_X((fr)->request) + (ix));
384 if (limiter) {
385 *pf++ = 0;
386 *pf++ = 0;
387 *pf++ = 0xFF;
388 } else {
389 *pf++ = (vb);
390 *pf++ = (vg);
391 *pf++ = (vr);
392 }
393}
394
395#endif /* usbvideo_h */
diff --git a/drivers/staging/usbvideo/vicam.c b/drivers/staging/usbvideo/vicam.c
deleted file mode 100644
index 38a373a8d077..000000000000
--- a/drivers/staging/usbvideo/vicam.c
+++ /dev/null
@@ -1,946 +0,0 @@
1/*
2 * USB ViCam WebCam driver
3 * Copyright (c) 2002 Joe Burks (jburks@wavicle.org),
4 * Christopher L Cheney (ccheney@cheney.cx),
5 * Pavel Machek (pavel@ucw.cz),
6 * John Tyner (jtyner@cs.ucr.edu),
7 * Monroe Williams (monroe@pobox.com)
8 *
9 * Supports 3COM HomeConnect PC Digital WebCam
10 * Supports Compro PS39U WebCam
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * This source code is based heavily on the CPiA webcam driver which was
27 * written by Peter Pregler, Scott J. Bertin and Johannes Erdfelt
28 *
29 * Portions of this code were also copied from usbvideo.c
30 *
31 * Special thanks to the whole team at Sourceforge for help making
32 * this driver become a reality. Notably:
33 * Andy Armstrong who reverse engineered the color encoding and
34 * Pavel Machek and Chris Cheney who worked on reverse engineering the
35 * camera controls and wrote the first generation driver.
36 */
37
38#include <linux/kernel.h>
39#include <linux/module.h>
40#include <linux/init.h>
41#include "videodev.h"
42#include <linux/usb.h>
43#include <linux/vmalloc.h>
44#include <linux/mm.h>
45#include <linux/slab.h>
46#include <linux/mutex.h>
47#include <linux/firmware.h>
48#include <linux/ihex.h>
49#include "usbvideo.h"
50
51/* #define VICAM_DEBUG */
52
53#ifdef VICAM_DEBUG
54#define ADBG(lineno, fmt, args...) printk(fmt, jiffies, __func__, lineno, ##args)
55#define DBG(fmt, args...) ADBG((__LINE__), KERN_DEBUG __FILE__"(%ld):%s (%d):"fmt, ##args)
56#else
57#define DBG(fmn, args...) do {} while (0)
58#endif
59
60#define DRIVER_AUTHOR "Joe Burks, jburks@wavicle.org"
61#define DRIVER_DESC "ViCam WebCam Driver"
62
63/* Define these values to match your device */
64#define USB_VICAM_VENDOR_ID 0x04c1
65#define USB_VICAM_PRODUCT_ID 0x009d
66#define USB_COMPRO_VENDOR_ID 0x0602
67#define USB_COMPRO_PRODUCT_ID 0x1001
68
69#define VICAM_BYTES_PER_PIXEL 3
70#define VICAM_MAX_READ_SIZE (512*242+128)
71#define VICAM_MAX_FRAME_SIZE (VICAM_BYTES_PER_PIXEL*320*240)
72#define VICAM_FRAMES 2
73
74#define VICAM_HEADER_SIZE 64
75
76/* rvmalloc / rvfree copied from usbvideo.c
77 *
78 * Not sure why these are not yet non-statics which I can reference through
79 * usbvideo.h the same as it is in 2.4.20. I bet this will get fixed sometime
80 * in the future.
81 *
82*/
83static void *rvmalloc(unsigned long size)
84{
85 void *mem;
86 unsigned long adr;
87
88 size = PAGE_ALIGN(size);
89 mem = vmalloc_32(size);
90 if (!mem)
91 return NULL;
92
93 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
94 adr = (unsigned long) mem;
95 while (size > 0) {
96 SetPageReserved(vmalloc_to_page((void *)adr));
97 adr += PAGE_SIZE;
98 size -= PAGE_SIZE;
99 }
100
101 return mem;
102}
103
104static void rvfree(void *mem, unsigned long size)
105{
106 unsigned long adr;
107
108 if (!mem)
109 return;
110
111 adr = (unsigned long) mem;
112 while ((long) size > 0) {
113 ClearPageReserved(vmalloc_to_page((void *)adr));
114 adr += PAGE_SIZE;
115 size -= PAGE_SIZE;
116 }
117 vfree(mem);
118}
119
120struct vicam_camera {
121 u16 shutter_speed; /* capture shutter speed */
122 u16 gain; /* capture gain */
123
124 u8 *raw_image; /* raw data captured from the camera */
125 u8 *framebuf; /* processed data in RGB24 format */
126 u8 *cntrlbuf; /* area used to send control msgs */
127
128 struct video_device vdev; /* v4l video device */
129 struct usb_device *udev; /* usb device */
130
131 /* guard against simultaneous accesses to the camera */
132 struct mutex cam_lock;
133
134 int is_initialized;
135 u8 open_count;
136 u8 bulkEndpoint;
137 int needsDummyRead;
138};
139
140static int vicam_probe(struct usb_interface *intf, const struct usb_device_id *id);
141static void vicam_disconnect(struct usb_interface *intf);
142static void read_frame(struct vicam_camera *cam, int framenum);
143static void vicam_decode_color(const u8 *, u8 *);
144
145static int __send_control_msg(struct vicam_camera *cam,
146 u8 request,
147 u16 value,
148 u16 index,
149 unsigned char *cp,
150 u16 size)
151{
152 int status;
153
154 /* cp must be memory that has been allocated by kmalloc */
155
156 status = usb_control_msg(cam->udev,
157 usb_sndctrlpipe(cam->udev, 0),
158 request,
159 USB_DIR_OUT | USB_TYPE_VENDOR |
160 USB_RECIP_DEVICE, value, index,
161 cp, size, 1000);
162
163 status = min(status, 0);
164
165 if (status < 0) {
166 printk(KERN_INFO "Failed sending control message, error %d.\n",
167 status);
168 }
169
170 return status;
171}
172
173static int send_control_msg(struct vicam_camera *cam,
174 u8 request,
175 u16 value,
176 u16 index,
177 unsigned char *cp,
178 u16 size)
179{
180 int status = -ENODEV;
181 mutex_lock(&cam->cam_lock);
182 if (cam->udev) {
183 status = __send_control_msg(cam, request, value,
184 index, cp, size);
185 }
186 mutex_unlock(&cam->cam_lock);
187 return status;
188}
189static int
190initialize_camera(struct vicam_camera *cam)
191{
192 int err;
193 const struct ihex_binrec *rec;
194 const struct firmware *uninitialized_var(fw);
195
196 err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
197 if (err) {
198 printk(KERN_ERR "Failed to load \"vicam/firmware.fw\": %d\n",
199 err);
200 return err;
201 }
202
203 for (rec = (void *)fw->data; rec; rec = ihex_next_binrec(rec)) {
204 memcpy(cam->cntrlbuf, rec->data, be16_to_cpu(rec->len));
205
206 err = send_control_msg(cam, 0xff, 0, 0,
207 cam->cntrlbuf, be16_to_cpu(rec->len));
208 if (err)
209 break;
210 }
211
212 release_firmware(fw);
213
214 return err;
215}
216
217static int
218set_camera_power(struct vicam_camera *cam, int state)
219{
220 int status;
221
222 status = send_control_msg(cam, 0x50, state, 0, NULL, 0);
223 if (status < 0)
224 return status;
225
226 if (state)
227 send_control_msg(cam, 0x55, 1, 0, NULL, 0);
228
229 return 0;
230}
231
232static long
233vicam_ioctl(struct file *file, unsigned int ioctlnr, unsigned long arg)
234{
235 void __user *user_arg = (void __user *)arg;
236 struct vicam_camera *cam = file->private_data;
237 long retval = 0;
238
239 if (!cam)
240 return -ENODEV;
241
242 switch (ioctlnr) {
243 /* query capabilities */
244 case VIDIOCGCAP:
245 {
246 struct video_capability b;
247
248 DBG("VIDIOCGCAP\n");
249 memset(&b, 0, sizeof(b));
250 strcpy(b.name, "ViCam-based Camera");
251 b.type = VID_TYPE_CAPTURE;
252 b.channels = 1;
253 b.audios = 0;
254 b.maxwidth = 320; /* VIDEOSIZE_CIF */
255 b.maxheight = 240;
256 b.minwidth = 320; /* VIDEOSIZE_48_48 */
257 b.minheight = 240;
258
259 if (copy_to_user(user_arg, &b, sizeof(b)))
260 retval = -EFAULT;
261
262 break;
263 }
264 /* get/set video source - we are a camera and nothing else */
265 case VIDIOCGCHAN:
266 {
267 struct video_channel v;
268
269 DBG("VIDIOCGCHAN\n");
270 if (copy_from_user(&v, user_arg, sizeof(v))) {
271 retval = -EFAULT;
272 break;
273 }
274 if (v.channel != 0) {
275 retval = -EINVAL;
276 break;
277 }
278
279 v.channel = 0;
280 strcpy(v.name, "Camera");
281 v.tuners = 0;
282 v.flags = 0;
283 v.type = VIDEO_TYPE_CAMERA;
284 v.norm = 0;
285
286 if (copy_to_user(user_arg, &v, sizeof(v)))
287 retval = -EFAULT;
288 break;
289 }
290
291 case VIDIOCSCHAN:
292 {
293 int v;
294
295 if (copy_from_user(&v, user_arg, sizeof(v)))
296 retval = -EFAULT;
297 DBG("VIDIOCSCHAN %d\n", v);
298
299 if (retval == 0 && v != 0)
300 retval = -EINVAL;
301
302 break;
303 }
304
305 /* image properties */
306 case VIDIOCGPICT:
307 {
308 struct video_picture vp;
309 DBG("VIDIOCGPICT\n");
310 memset(&vp, 0, sizeof(struct video_picture));
311 vp.brightness = cam->gain << 8;
312 vp.depth = 24;
313 vp.palette = VIDEO_PALETTE_RGB24;
314 if (copy_to_user(user_arg, &vp, sizeof(struct video_picture)))
315 retval = -EFAULT;
316 break;
317 }
318
319 case VIDIOCSPICT:
320 {
321 struct video_picture vp;
322
323 if (copy_from_user(&vp, user_arg, sizeof(vp))) {
324 retval = -EFAULT;
325 break;
326 }
327
328 DBG("VIDIOCSPICT depth = %d, pal = %d\n", vp.depth,
329 vp.palette);
330
331 cam->gain = vp.brightness >> 8;
332
333 if (vp.depth != 24
334 || vp.palette != VIDEO_PALETTE_RGB24)
335 retval = -EINVAL;
336
337 break;
338 }
339
340 /* get/set capture window */
341 case VIDIOCGWIN:
342 {
343 struct video_window vw;
344 vw.x = 0;
345 vw.y = 0;
346 vw.width = 320;
347 vw.height = 240;
348 vw.chromakey = 0;
349 vw.flags = 0;
350 vw.clips = NULL;
351 vw.clipcount = 0;
352
353 DBG("VIDIOCGWIN\n");
354
355 if (copy_to_user(user_arg, (void *)&vw, sizeof(vw)))
356 retval = -EFAULT;
357
358 /* I'm not sure what the deal with a capture window is, it is very poorly described
359 * in the doc. So I won't support it now. */
360 break;
361 }
362
363 case VIDIOCSWIN:
364 {
365
366 struct video_window vw;
367
368 if (copy_from_user(&vw, user_arg, sizeof(vw))) {
369 retval = -EFAULT;
370 break;
371 }
372
373 DBG("VIDIOCSWIN %d x %d\n", vw.width, vw.height);
374
375 if (vw.width != 320 || vw.height != 240)
376 retval = -EFAULT;
377
378 break;
379 }
380
381 /* mmap interface */
382 case VIDIOCGMBUF:
383 {
384 struct video_mbuf vm;
385 int i;
386
387 DBG("VIDIOCGMBUF\n");
388 memset(&vm, 0, sizeof(vm));
389 vm.size =
390 VICAM_MAX_FRAME_SIZE * VICAM_FRAMES;
391 vm.frames = VICAM_FRAMES;
392 for (i = 0; i < VICAM_FRAMES; i++)
393 vm.offsets[i] = VICAM_MAX_FRAME_SIZE * i;
394
395 if (copy_to_user(user_arg, (void *)&vm, sizeof(vm)))
396 retval = -EFAULT;
397
398 break;
399 }
400
401 case VIDIOCMCAPTURE:
402 {
403 struct video_mmap vm;
404 /* int video_size; */
405
406 if (copy_from_user((void *)&vm, user_arg, sizeof(vm))) {
407 retval = -EFAULT;
408 break;
409 }
410
411 DBG("VIDIOCMCAPTURE frame=%d, height=%d, width=%d, format=%d.\n",
412 vm.frame, vm.width, vm.height, vm.format);
413
414 if (vm.frame >= VICAM_FRAMES || vm.format != VIDEO_PALETTE_RGB24)
415 retval = -EINVAL;
416
417 /* in theory right here we'd start the image capturing
418 * (fill in a bulk urb and submit it asynchronously)
419 *
420 * Instead we're going to do a total hack job for now and
421 * retrieve the frame in VIDIOCSYNC */
422
423 break;
424 }
425
426 case VIDIOCSYNC:
427 {
428 int frame;
429
430 if (copy_from_user((void *)&frame, user_arg, sizeof(int))) {
431 retval = -EFAULT;
432 break;
433 }
434 DBG("VIDIOCSYNC: %d\n", frame);
435
436 read_frame(cam, frame);
437 vicam_decode_color(cam->raw_image,
438 cam->framebuf +
439 frame * VICAM_MAX_FRAME_SIZE);
440
441 break;
442 }
443
444 /* pointless to implement overlay with this camera */
445 case VIDIOCCAPTURE:
446 case VIDIOCGFBUF:
447 case VIDIOCSFBUF:
448 case VIDIOCKEY:
449 retval = -EINVAL;
450 break;
451
452 /* tuner interface - we have none */
453 case VIDIOCGTUNER:
454 case VIDIOCSTUNER:
455 case VIDIOCGFREQ:
456 case VIDIOCSFREQ:
457 retval = -EINVAL;
458 break;
459
460 /* audio interface - we have none */
461 case VIDIOCGAUDIO:
462 case VIDIOCSAUDIO:
463 retval = -EINVAL;
464 break;
465 default:
466 retval = -ENOIOCTLCMD;
467 break;
468 }
469
470 return retval;
471}
472
473static int
474vicam_open(struct file *file)
475{
476 struct vicam_camera *cam = video_drvdata(file);
477
478 DBG("open\n");
479
480 if (!cam) {
481 printk(KERN_ERR
482 "vicam video_device improperly initialized");
483 return -EINVAL;
484 }
485
486 /* cam_lock/open_count protects us from simultaneous opens
487 * ... for now. we probably shouldn't rely on this fact forever.
488 */
489
490 mutex_lock(&cam->cam_lock);
491 if (cam->open_count > 0) {
492 printk(KERN_INFO
493 "vicam_open called on already opened camera");
494 mutex_unlock(&cam->cam_lock);
495 return -EBUSY;
496 }
497
498 cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
499 if (!cam->raw_image) {
500 mutex_unlock(&cam->cam_lock);
501 return -ENOMEM;
502 }
503
504 cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
505 if (!cam->framebuf) {
506 kfree(cam->raw_image);
507 mutex_unlock(&cam->cam_lock);
508 return -ENOMEM;
509 }
510
511 cam->cntrlbuf = kmalloc(PAGE_SIZE, GFP_KERNEL);
512 if (!cam->cntrlbuf) {
513 kfree(cam->raw_image);
514 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
515 mutex_unlock(&cam->cam_lock);
516 return -ENOMEM;
517 }
518
519 cam->needsDummyRead = 1;
520 cam->open_count++;
521
522 file->private_data = cam;
523 mutex_unlock(&cam->cam_lock);
524
525
526 /* First upload firmware, then turn the camera on */
527
528 if (!cam->is_initialized) {
529 initialize_camera(cam);
530
531 cam->is_initialized = 1;
532 }
533
534 set_camera_power(cam, 1);
535
536 return 0;
537}
538
539static int
540vicam_close(struct file *file)
541{
542 struct vicam_camera *cam = file->private_data;
543 int open_count;
544 struct usb_device *udev;
545
546 DBG("close\n");
547
548 /* it's not the end of the world if
549 * we fail to turn the camera off.
550 */
551
552 set_camera_power(cam, 0);
553
554 kfree(cam->raw_image);
555 rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
556 kfree(cam->cntrlbuf);
557
558 mutex_lock(&cam->cam_lock);
559
560 cam->open_count--;
561 open_count = cam->open_count;
562 udev = cam->udev;
563
564 mutex_unlock(&cam->cam_lock);
565
566 if (!open_count && !udev)
567 kfree(cam);
568
569 return 0;
570}
571
572static void vicam_decode_color(const u8 *data, u8 *rgb)
573{
574 /* vicam_decode_color - Convert from Vicam Y-Cr-Cb to RGB
575 * Copyright (C) 2002 Monroe Williams (monroe@pobox.com)
576 */
577
578 int i, prevY, nextY;
579
580 prevY = 512;
581 nextY = 512;
582
583 data += VICAM_HEADER_SIZE;
584
585 for (i = 0; i < 240; i++, data += 512) {
586 const int y = (i * 242) / 240;
587
588 int j, prevX, nextX;
589 int Y, Cr, Cb;
590
591 if (y == 242 - 1)
592 nextY = -512;
593
594 prevX = 1;
595 nextX = 1;
596
597 for (j = 0; j < 320; j++, rgb += 3) {
598 const int x = (j * 512) / 320;
599 const u8 * const src = &data[x];
600
601 if (x == 512 - 1)
602 nextX = -1;
603
604 Cr = (src[prevX] - src[0]) +
605 (src[nextX] - src[0]);
606 Cr /= 2;
607
608 Cb = (src[prevY] - src[prevX + prevY]) +
609 (src[prevY] - src[nextX + prevY]) +
610 (src[nextY] - src[prevX + nextY]) +
611 (src[nextY] - src[nextX + nextY]);
612 Cb /= 4;
613
614 Y = 1160 * (src[0] + (Cr / 2) - 16);
615
616 if (i & 1) {
617 int Ct = Cr;
618 Cr = Cb;
619 Cb = Ct;
620 }
621
622 if ((x ^ i) & 1) {
623 Cr = -Cr;
624 Cb = -Cb;
625 }
626
627 rgb[0] = clamp(((Y + (2017 * Cb)) +
628 500) / 900, 0, 255);
629 rgb[1] = clamp(((Y - (392 * Cb) -
630 (813 * Cr)) +
631 500) / 1000, 0, 255);
632 rgb[2] = clamp(((Y + (1594 * Cr)) +
633 500) / 1300, 0, 255);
634
635 prevX = -1;
636 }
637
638 prevY = -512;
639 }
640}
641
642static void
643read_frame(struct vicam_camera *cam, int framenum)
644{
645 unsigned char *request = cam->cntrlbuf;
646 int realShutter;
647 int n;
648 int actual_length;
649
650 if (cam->needsDummyRead) {
651 cam->needsDummyRead = 0;
652 read_frame(cam, framenum);
653 }
654
655 memset(request, 0, 16);
656 request[0] = cam->gain; /* 0 = 0% gain, FF = 100% gain */
657
658 request[1] = 0; /* 512x242 capture */
659
660 request[2] = 0x90; /* the function of these two bytes */
661 request[3] = 0x07; /* is not yet understood */
662
663 if (cam->shutter_speed > 60) {
664 /* Short exposure */
665 realShutter =
666 ((-15631900 / cam->shutter_speed) + 260533) / 1000;
667 request[4] = realShutter & 0xFF;
668 request[5] = (realShutter >> 8) & 0xFF;
669 request[6] = 0x03;
670 request[7] = 0x01;
671 } else {
672 /* Long exposure */
673 realShutter = 15600 / cam->shutter_speed - 1;
674 request[4] = 0;
675 request[5] = 0;
676 request[6] = realShutter & 0xFF;
677 request[7] = realShutter >> 8;
678 }
679
680 /* Per John Markus Bjørndalen, byte at index 8 causes problems if it isn't 0*/
681 request[8] = 0;
682 /* bytes 9-15 do not seem to affect exposure or image quality */
683
684 mutex_lock(&cam->cam_lock);
685
686 if (!cam->udev)
687 goto done;
688
689 n = __send_control_msg(cam, 0x51, 0x80, 0, request, 16);
690
691 if (n < 0) {
692 printk(KERN_ERR
693 " Problem sending frame capture control message");
694 goto done;
695 }
696
697 n = usb_bulk_msg(cam->udev,
698 usb_rcvbulkpipe(cam->udev, cam->bulkEndpoint),
699 cam->raw_image,
700 512 * 242 + 128, &actual_length, 10000);
701
702 if (n < 0) {
703 printk(KERN_ERR "Problem during bulk read of frame data: %d\n",
704 n);
705 }
706
707 done:
708 mutex_unlock(&cam->cam_lock);
709}
710
711static ssize_t
712vicam_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
713{
714 struct vicam_camera *cam = file->private_data;
715
716 DBG("read %d bytes.\n", (int) count);
717
718 if (*ppos >= VICAM_MAX_FRAME_SIZE) {
719 *ppos = 0;
720 return 0;
721 }
722
723 if (*ppos == 0) {
724 read_frame(cam, 0);
725 vicam_decode_color(cam->raw_image,
726 cam->framebuf +
727 0 * VICAM_MAX_FRAME_SIZE);
728 }
729
730 count = min_t(size_t, count, VICAM_MAX_FRAME_SIZE - *ppos);
731
732 if (copy_to_user(buf, &cam->framebuf[*ppos], count))
733 count = -EFAULT;
734 else
735 *ppos += count;
736
737 if (count == VICAM_MAX_FRAME_SIZE)
738 *ppos = 0;
739
740 return count;
741}
742
743
744static int
745vicam_mmap(struct file *file, struct vm_area_struct *vma)
746{
747 /* TODO: allocate the raw frame buffer if necessary */
748 unsigned long page, pos;
749 unsigned long start = vma->vm_start;
750 unsigned long size = vma->vm_end-vma->vm_start;
751 struct vicam_camera *cam = file->private_data;
752
753 if (!cam)
754 return -ENODEV;
755
756 DBG("vicam_mmap: %ld\n", size);
757
758 /* We let mmap allocate as much as it wants because Linux was adding 2048 bytes
759 * to the size the application requested for mmap and it was screwing apps up.
760 if (size > VICAM_FRAMES*VICAM_MAX_FRAME_SIZE)
761 return -EINVAL;
762 */
763
764 pos = (unsigned long)cam->framebuf;
765 while (size > 0) {
766 page = vmalloc_to_pfn((void *)pos);
767 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED))
768 return -EAGAIN;
769
770 start += PAGE_SIZE;
771 pos += PAGE_SIZE;
772 if (size > PAGE_SIZE)
773 size -= PAGE_SIZE;
774 else
775 size = 0;
776 }
777
778 return 0;
779}
780
781static const struct v4l2_file_operations vicam_fops = {
782 .owner = THIS_MODULE,
783 .open = vicam_open,
784 .release = vicam_close,
785 .read = vicam_read,
786 .mmap = vicam_mmap,
787 .ioctl = vicam_ioctl,
788};
789
790static struct video_device vicam_template = {
791 .name = "ViCam-based USB Camera",
792 .fops = &vicam_fops,
793 .release = video_device_release_empty,
794};
795
796/* table of devices that work with this driver */
797static struct usb_device_id vicam_table[] = {
798 {USB_DEVICE(USB_VICAM_VENDOR_ID, USB_VICAM_PRODUCT_ID)},
799 {USB_DEVICE(USB_COMPRO_VENDOR_ID, USB_COMPRO_PRODUCT_ID)},
800 {} /* Terminating entry */
801};
802
803MODULE_DEVICE_TABLE(usb, vicam_table);
804
805static struct usb_driver vicam_driver = {
806 .name = "vicam",
807 .probe = vicam_probe,
808 .disconnect = vicam_disconnect,
809 .id_table = vicam_table
810};
811
812/**
813 * vicam_probe
814 * @intf: the interface
815 * @id: the device id
816 *
817 * Called by the usb core when a new device is connected that it thinks
818 * this driver might be interested in.
819 */
820static int
821vicam_probe(struct usb_interface *intf, const struct usb_device_id *id)
822{
823 struct usb_device *dev = interface_to_usbdev(intf);
824 int bulkEndpoint = 0;
825 const struct usb_host_interface *interface;
826 const struct usb_endpoint_descriptor *endpoint;
827 struct vicam_camera *cam;
828
829 printk(KERN_INFO "ViCam based webcam connected\n");
830
831 interface = intf->cur_altsetting;
832
833 DBG(KERN_DEBUG "Interface %d. has %u. endpoints!\n",
834 interface->desc.bInterfaceNumber, (unsigned) (interface->desc.bNumEndpoints));
835 endpoint = &interface->endpoint[0].desc;
836
837 if (usb_endpoint_is_bulk_in(endpoint)) {
838 /* we found a bulk in endpoint */
839 bulkEndpoint = endpoint->bEndpointAddress;
840 } else {
841 printk(KERN_ERR
842 "No bulk in endpoint was found ?! (this is bad)\n");
843 }
844
845 cam = kzalloc(sizeof(struct vicam_camera), GFP_KERNEL);
846 if (cam == NULL) {
847 printk(KERN_WARNING
848 "could not allocate kernel memory for vicam_camera struct\n");
849 return -ENOMEM;
850 }
851
852
853 cam->shutter_speed = 15;
854
855 mutex_init(&cam->cam_lock);
856
857 memcpy(&cam->vdev, &vicam_template, sizeof(vicam_template));
858 video_set_drvdata(&cam->vdev, cam);
859
860 cam->udev = dev;
861 cam->bulkEndpoint = bulkEndpoint;
862
863 if (video_register_device(&cam->vdev, VFL_TYPE_GRABBER, -1) < 0) {
864 kfree(cam);
865 printk(KERN_WARNING "video_register_device failed\n");
866 return -EIO;
867 }
868
869 printk(KERN_INFO "ViCam webcam driver now controlling device %s\n",
870 video_device_node_name(&cam->vdev));
871
872 usb_set_intfdata(intf, cam);
873
874 return 0;
875}
876
877static void
878vicam_disconnect(struct usb_interface *intf)
879{
880 int open_count;
881 struct vicam_camera *cam = usb_get_intfdata(intf);
882 usb_set_intfdata(intf, NULL);
883
884 /* we must unregister the device before taking its
885 * cam_lock. This is because the video open call
886 * holds the same lock as video unregister. if we
887 * unregister inside of the cam_lock and open also
888 * uses the cam_lock, we get deadlock.
889 */
890
891 video_unregister_device(&cam->vdev);
892
893 /* stop the camera from being used */
894
895 mutex_lock(&cam->cam_lock);
896
897 /* mark the camera as gone */
898
899 cam->udev = NULL;
900
901 /* the only thing left to do is synchronize with
902 * our close/release function on who should release
903 * the camera memory. if there are any users using the
904 * camera, it's their job. if there are no users,
905 * it's ours.
906 */
907
908 open_count = cam->open_count;
909
910 mutex_unlock(&cam->cam_lock);
911
912 if (!open_count)
913 kfree(cam);
914
915 printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
916}
917
918/*
919 */
920static int __init
921usb_vicam_init(void)
922{
923 int retval;
924 DBG(KERN_INFO "ViCam-based WebCam driver startup\n");
925 retval = usb_register(&vicam_driver);
926 if (retval)
927 printk(KERN_WARNING "usb_register failed!\n");
928 return retval;
929}
930
931static void __exit
932usb_vicam_exit(void)
933{
934 DBG(KERN_INFO
935 "ViCam-based WebCam driver shutdown\n");
936
937 usb_deregister(&vicam_driver);
938}
939
940module_init(usb_vicam_init);
941module_exit(usb_vicam_exit);
942
943MODULE_AUTHOR(DRIVER_AUTHOR);
944MODULE_DESCRIPTION(DRIVER_DESC);
945MODULE_LICENSE("GPL");
946MODULE_FIRMWARE("vicam/firmware.fw");
diff --git a/drivers/staging/usbvideo/videodev.h b/drivers/staging/usbvideo/videodev.h
deleted file mode 100644
index f11efbef1c05..000000000000
--- a/drivers/staging/usbvideo/videodev.h
+++ /dev/null
@@ -1,318 +0,0 @@
1/*
2 * Video for Linux version 1 - OBSOLETE
3 *
4 * Header file for v4l1 drivers and applications, for
5 * Linux kernels 2.2.x or 2.4.x.
6 *
7 * Provides header for legacy drivers and applications
8 *
9 * See http://linuxtv.org for more info
10 *
11 */
12#ifndef __LINUX_VIDEODEV_H
13#define __LINUX_VIDEODEV_H
14
15#include <linux/types.h>
16#include <linux/ioctl.h>
17#include <linux/videodev2.h>
18
19#define VID_TYPE_CAPTURE 1 /* Can capture */
20#define VID_TYPE_TUNER 2 /* Can tune */
21#define VID_TYPE_TELETEXT 4 /* Does teletext */
22#define VID_TYPE_OVERLAY 8 /* Overlay onto frame buffer */
23#define VID_TYPE_CHROMAKEY 16 /* Overlay by chromakey */
24#define VID_TYPE_CLIPPING 32 /* Can clip */
25#define VID_TYPE_FRAMERAM 64 /* Uses the frame buffer memory */
26#define VID_TYPE_SCALES 128 /* Scalable */
27#define VID_TYPE_MONOCHROME 256 /* Monochrome only */
28#define VID_TYPE_SUBCAPTURE 512 /* Can capture subareas of the image */
29#define VID_TYPE_MPEG_DECODER 1024 /* Can decode MPEG streams */
30#define VID_TYPE_MPEG_ENCODER 2048 /* Can encode MPEG streams */
31#define VID_TYPE_MJPEG_DECODER 4096 /* Can decode MJPEG streams */
32#define VID_TYPE_MJPEG_ENCODER 8192 /* Can encode MJPEG streams */
33
34struct video_capability
35{
36 char name[32];
37 int type;
38 int channels; /* Num channels */
39 int audios; /* Num audio devices */
40 int maxwidth; /* Supported width */
41 int maxheight; /* And height */
42 int minwidth; /* Supported width */
43 int minheight; /* And height */
44};
45
46
47struct video_channel
48{
49 int channel;
50 char name[32];
51 int tuners;
52 __u32 flags;
53#define VIDEO_VC_TUNER 1 /* Channel has a tuner */
54#define VIDEO_VC_AUDIO 2 /* Channel has audio */
55 __u16 type;
56#define VIDEO_TYPE_TV 1
57#define VIDEO_TYPE_CAMERA 2
58 __u16 norm; /* Norm set by channel */
59};
60
61struct video_tuner
62{
63 int tuner;
64 char name[32];
65 unsigned long rangelow, rangehigh; /* Tuner range */
66 __u32 flags;
67#define VIDEO_TUNER_PAL 1
68#define VIDEO_TUNER_NTSC 2
69#define VIDEO_TUNER_SECAM 4
70#define VIDEO_TUNER_LOW 8 /* Uses KHz not MHz */
71#define VIDEO_TUNER_NORM 16 /* Tuner can set norm */
72#define VIDEO_TUNER_STEREO_ON 128 /* Tuner is seeing stereo */
73#define VIDEO_TUNER_RDS_ON 256 /* Tuner is seeing an RDS datastream */
74#define VIDEO_TUNER_MBS_ON 512 /* Tuner is seeing an MBS datastream */
75 __u16 mode; /* PAL/NTSC/SECAM/OTHER */
76#define VIDEO_MODE_PAL 0
77#define VIDEO_MODE_NTSC 1
78#define VIDEO_MODE_SECAM 2
79#define VIDEO_MODE_AUTO 3
80 __u16 signal; /* Signal strength 16bit scale */
81};
82
83struct video_picture
84{
85 __u16 brightness;
86 __u16 hue;
87 __u16 colour;
88 __u16 contrast;
89 __u16 whiteness; /* Black and white only */
90 __u16 depth; /* Capture depth */
91 __u16 palette; /* Palette in use */
92#define VIDEO_PALETTE_GREY 1 /* Linear greyscale */
93#define VIDEO_PALETTE_HI240 2 /* High 240 cube (BT848) */
94#define VIDEO_PALETTE_RGB565 3 /* 565 16 bit RGB */
95#define VIDEO_PALETTE_RGB24 4 /* 24bit RGB */
96#define VIDEO_PALETTE_RGB32 5 /* 32bit RGB */
97#define VIDEO_PALETTE_RGB555 6 /* 555 15bit RGB */
98#define VIDEO_PALETTE_YUV422 7 /* YUV422 capture */
99#define VIDEO_PALETTE_YUYV 8
100#define VIDEO_PALETTE_UYVY 9 /* The great thing about standards is ... */
101#define VIDEO_PALETTE_YUV420 10
102#define VIDEO_PALETTE_YUV411 11 /* YUV411 capture */
103#define VIDEO_PALETTE_RAW 12 /* RAW capture (BT848) */
104#define VIDEO_PALETTE_YUV422P 13 /* YUV 4:2:2 Planar */
105#define VIDEO_PALETTE_YUV411P 14 /* YUV 4:1:1 Planar */
106#define VIDEO_PALETTE_YUV420P 15 /* YUV 4:2:0 Planar */
107#define VIDEO_PALETTE_YUV410P 16 /* YUV 4:1:0 Planar */
108#define VIDEO_PALETTE_PLANAR 13 /* start of planar entries */
109#define VIDEO_PALETTE_COMPONENT 7 /* start of component entries */
110};
111
112struct video_audio
113{
114 int audio; /* Audio channel */
115 __u16 volume; /* If settable */
116 __u16 bass, treble;
117 __u32 flags;
118#define VIDEO_AUDIO_MUTE 1
119#define VIDEO_AUDIO_MUTABLE 2
120#define VIDEO_AUDIO_VOLUME 4
121#define VIDEO_AUDIO_BASS 8
122#define VIDEO_AUDIO_TREBLE 16
123#define VIDEO_AUDIO_BALANCE 32
124 char name[16];
125#define VIDEO_SOUND_MONO 1
126#define VIDEO_SOUND_STEREO 2
127#define VIDEO_SOUND_LANG1 4
128#define VIDEO_SOUND_LANG2 8
129 __u16 mode;
130 __u16 balance; /* Stereo balance */
131 __u16 step; /* Step actual volume uses */
132};
133
134struct video_clip
135{
136 __s32 x,y;
137 __s32 width, height;
138 struct video_clip *next; /* For user use/driver use only */
139};
140
141struct video_window
142{
143 __u32 x,y; /* Position of window */
144 __u32 width,height; /* Its size */
145 __u32 chromakey;
146 __u32 flags;
147 struct video_clip __user *clips; /* Set only */
148 int clipcount;
149#define VIDEO_WINDOW_INTERLACE 1
150#define VIDEO_WINDOW_CHROMAKEY 16 /* Overlay by chromakey */
151#define VIDEO_CLIP_BITMAP -1
152/* bitmap is 1024x625, a '1' bit represents a clipped pixel */
153#define VIDEO_CLIPMAP_SIZE (128 * 625)
154};
155
156struct video_capture
157{
158 __u32 x,y; /* Offsets into image */
159 __u32 width, height; /* Area to capture */
160 __u16 decimation; /* Decimation divider */
161 __u16 flags; /* Flags for capture */
162#define VIDEO_CAPTURE_ODD 0 /* Temporal */
163#define VIDEO_CAPTURE_EVEN 1
164};
165
166struct video_buffer
167{
168 void *base;
169 int height,width;
170 int depth;
171 int bytesperline;
172};
173
174struct video_mmap
175{
176 unsigned int frame; /* Frame (0 - n) for double buffer */
177 int height,width;
178 unsigned int format; /* should be VIDEO_PALETTE_* */
179};
180
181struct video_key
182{
183 __u8 key[8];
184 __u32 flags;
185};
186
187struct video_mbuf
188{
189 int size; /* Total memory to map */
190 int frames; /* Frames */
191 int offsets[VIDEO_MAX_FRAME];
192};
193
194#define VIDEO_NO_UNIT (-1)
195
196struct video_unit
197{
198 int video; /* Video minor */
199 int vbi; /* VBI minor */
200 int radio; /* Radio minor */
201 int audio; /* Audio minor */
202 int teletext; /* Teletext minor */
203};
204
205struct vbi_format {
206 __u32 sampling_rate; /* in Hz */
207 __u32 samples_per_line;
208 __u32 sample_format; /* VIDEO_PALETTE_RAW only (1 byte) */
209 __s32 start[2]; /* starting line for each frame */
210 __u32 count[2]; /* count of lines for each frame */
211 __u32 flags;
212#define VBI_UNSYNC 1 /* can distingues between top/bottom field */
213#define VBI_INTERLACED 2 /* lines are interlaced */
214};
215
216/* video_info is biased towards hardware mpeg encode/decode */
217/* but it could apply generically to any hardware compressor/decompressor */
218struct video_info
219{
220 __u32 frame_count; /* frames output since decode/encode began */
221 __u32 h_size; /* current unscaled horizontal size */
222 __u32 v_size; /* current unscaled veritcal size */
223 __u32 smpte_timecode; /* current SMPTE timecode (for current GOP) */
224 __u32 picture_type; /* current picture type */
225 __u32 temporal_reference; /* current temporal reference */
226 __u8 user_data[256]; /* user data last found in compressed stream */
227 /* user_data[0] contains user data flags, user_data[1] has count */
228};
229
230/* generic structure for setting playback modes */
231struct video_play_mode
232{
233 int mode;
234 int p1;
235 int p2;
236};
237
238/* for loading microcode / fpga programming */
239struct video_code
240{
241 char loadwhat[16]; /* name or tag of file being passed */
242 int datasize;
243 __u8 *data;
244};
245
246#define VIDIOCGCAP _IOR('v',1,struct video_capability) /* Get capabilities */
247#define VIDIOCGCHAN _IOWR('v',2,struct video_channel) /* Get channel info (sources) */
248#define VIDIOCSCHAN _IOW('v',3,struct video_channel) /* Set channel */
249#define VIDIOCGTUNER _IOWR('v',4,struct video_tuner) /* Get tuner abilities */
250#define VIDIOCSTUNER _IOW('v',5,struct video_tuner) /* Tune the tuner for the current channel */
251#define VIDIOCGPICT _IOR('v',6,struct video_picture) /* Get picture properties */
252#define VIDIOCSPICT _IOW('v',7,struct video_picture) /* Set picture properties */
253#define VIDIOCCAPTURE _IOW('v',8,int) /* Start, end capture */
254#define VIDIOCGWIN _IOR('v',9, struct video_window) /* Get the video overlay window */
255#define VIDIOCSWIN _IOW('v',10, struct video_window) /* Set the video overlay window - passes clip list for hardware smarts , chromakey etc */
256#define VIDIOCGFBUF _IOR('v',11, struct video_buffer) /* Get frame buffer */
257#define VIDIOCSFBUF _IOW('v',12, struct video_buffer) /* Set frame buffer - root only */
258#define VIDIOCKEY _IOR('v',13, struct video_key) /* Video key event - to dev 255 is to all - cuts capture on all DMA windows with this key (0xFFFFFFFF == all) */
259#define VIDIOCGFREQ _IOR('v',14, unsigned long) /* Set tuner */
260#define VIDIOCSFREQ _IOW('v',15, unsigned long) /* Set tuner */
261#define VIDIOCGAUDIO _IOR('v',16, struct video_audio) /* Get audio info */
262#define VIDIOCSAUDIO _IOW('v',17, struct video_audio) /* Audio source, mute etc */
263#define VIDIOCSYNC _IOW('v',18, int) /* Sync with mmap grabbing */
264#define VIDIOCMCAPTURE _IOW('v',19, struct video_mmap) /* Grab frames */
265#define VIDIOCGMBUF _IOR('v',20, struct video_mbuf) /* Memory map buffer info */
266#define VIDIOCGUNIT _IOR('v',21, struct video_unit) /* Get attached units */
267#define VIDIOCGCAPTURE _IOR('v',22, struct video_capture) /* Get subcapture */
268#define VIDIOCSCAPTURE _IOW('v',23, struct video_capture) /* Set subcapture */
269#define VIDIOCSPLAYMODE _IOW('v',24, struct video_play_mode) /* Set output video mode/feature */
270#define VIDIOCSWRITEMODE _IOW('v',25, int) /* Set write mode */
271#define VIDIOCGPLAYINFO _IOR('v',26, struct video_info) /* Get current playback info from hardware */
272#define VIDIOCSMICROCODE _IOW('v',27, struct video_code) /* Load microcode into hardware */
273#define VIDIOCGVBIFMT _IOR('v',28, struct vbi_format) /* Get VBI information */
274#define VIDIOCSVBIFMT _IOW('v',29, struct vbi_format) /* Set VBI information */
275
276
277#define BASE_VIDIOCPRIVATE 192 /* 192-255 are private */
278
279/* VIDIOCSWRITEMODE */
280#define VID_WRITE_MPEG_AUD 0
281#define VID_WRITE_MPEG_VID 1
282#define VID_WRITE_OSD 2
283#define VID_WRITE_TTX 3
284#define VID_WRITE_CC 4
285#define VID_WRITE_MJPEG 5
286
287/* VIDIOCSPLAYMODE */
288#define VID_PLAY_VID_OUT_MODE 0
289 /* p1: = VIDEO_MODE_PAL, VIDEO_MODE_NTSC, etc ... */
290#define VID_PLAY_GENLOCK 1
291 /* p1: 0 = OFF, 1 = ON */
292 /* p2: GENLOCK FINE DELAY value */
293#define VID_PLAY_NORMAL 2
294#define VID_PLAY_PAUSE 3
295#define VID_PLAY_SINGLE_FRAME 4
296#define VID_PLAY_FAST_FORWARD 5
297#define VID_PLAY_SLOW_MOTION 6
298#define VID_PLAY_IMMEDIATE_NORMAL 7
299#define VID_PLAY_SWITCH_CHANNELS 8
300#define VID_PLAY_FREEZE_FRAME 9
301#define VID_PLAY_STILL_MODE 10
302#define VID_PLAY_MASTER_MODE 11
303 /* p1: see below */
304#define VID_PLAY_MASTER_NONE 1
305#define VID_PLAY_MASTER_VIDEO 2
306#define VID_PLAY_MASTER_AUDIO 3
307#define VID_PLAY_ACTIVE_SCANLINES 12
308 /* p1 = first active; p2 = last active */
309#define VID_PLAY_RESET 13
310#define VID_PLAY_END_MARK 14
311
312#endif /* __LINUX_VIDEODEV_H */
313
314/*
315 * Local variables:
316 * c-basic-offset: 8
317 * End:
318 */
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index a74439affce9..5ce6fa6e59f0 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -101,8 +101,6 @@
101 101
102#include <linux/version.h> 102#include <linux/version.h>
103 103
104#define __OLD_VIDIOC_
105
106#include "matroxfb_base.h" 104#include "matroxfb_base.h"
107#include "matroxfb_misc.h" 105#include "matroxfb_misc.h"
108#include "matroxfb_accel.h" 106#include "matroxfb_accel.h"
@@ -1152,7 +1150,6 @@ static int matroxfb_ioctl(struct fb_info *info,
1152 return -EFAULT; 1150 return -EFAULT;
1153 return err; 1151 return err;
1154 } 1152 }
1155 case VIDIOC_S_CTRL_OLD:
1156 case VIDIOC_S_CTRL: 1153 case VIDIOC_S_CTRL:
1157 { 1154 {
1158 struct v4l2_control ctrl; 1155 struct v4l2_control ctrl;
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index b0ada6f37dd6..75cf611641e6 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -233,6 +233,7 @@ header-y += magic.h
233header-y += major.h 233header-y += major.h
234header-y += map_to_7segment.h 234header-y += map_to_7segment.h
235header-y += matroxfb.h 235header-y += matroxfb.h
236header-y += media.h
236header-y += mempolicy.h 237header-y += mempolicy.h
237header-y += meye.h 238header-y += meye.h
238header-y += mii.h 239header-y += mii.h
@@ -276,6 +277,7 @@ header-y += nfsacl.h
276header-y += nl80211.h 277header-y += nl80211.h
277header-y += nubus.h 278header-y += nubus.h
278header-y += nvram.h 279header-y += nvram.h
280header-y += omap3isp.h
279header-y += omapfb.h 281header-y += omapfb.h
280header-y += oom.h 282header-y += oom.h
281header-y += param.h 283header-y += param.h
@@ -370,6 +372,8 @@ header-y += unistd.h
370header-y += usbdevice_fs.h 372header-y += usbdevice_fs.h
371header-y += utime.h 373header-y += utime.h
372header-y += utsname.h 374header-y += utsname.h
375header-y += v4l2-mediabus.h
376header-y += v4l2-subdev.h
373header-y += veth.h 377header-y += veth.h
374header-y += vhost.h 378header-y += vhost.h
375header-y += videodev2.h 379header-y += videodev2.h
diff --git a/include/linux/media.h b/include/linux/media.h
new file mode 100644
index 000000000000..0ef883327de2
--- /dev/null
+++ b/include/linux/media.h
@@ -0,0 +1,132 @@
1/*
2 * Multimedia device API
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __LINUX_MEDIA_H
24#define __LINUX_MEDIA_H
25
26#include <linux/ioctl.h>
27#include <linux/types.h>
28#include <linux/version.h>
29
30#define MEDIA_API_VERSION KERNEL_VERSION(0, 1, 0)
31
32struct media_device_info {
33 char driver[16];
34 char model[32];
35 char serial[40];
36 char bus_info[32];
37 __u32 media_version;
38 __u32 hw_revision;
39 __u32 driver_version;
40 __u32 reserved[31];
41};
42
43#define MEDIA_ENT_ID_FLAG_NEXT (1 << 31)
44
45#define MEDIA_ENT_TYPE_SHIFT 16
46#define MEDIA_ENT_TYPE_MASK 0x00ff0000
47#define MEDIA_ENT_SUBTYPE_MASK 0x0000ffff
48
49#define MEDIA_ENT_T_DEVNODE (1 << MEDIA_ENT_TYPE_SHIFT)
50#define MEDIA_ENT_T_DEVNODE_V4L (MEDIA_ENT_T_DEVNODE + 1)
51#define MEDIA_ENT_T_DEVNODE_FB (MEDIA_ENT_T_DEVNODE + 2)
52#define MEDIA_ENT_T_DEVNODE_ALSA (MEDIA_ENT_T_DEVNODE + 3)
53#define MEDIA_ENT_T_DEVNODE_DVB (MEDIA_ENT_T_DEVNODE + 4)
54
55#define MEDIA_ENT_T_V4L2_SUBDEV (2 << MEDIA_ENT_TYPE_SHIFT)
56#define MEDIA_ENT_T_V4L2_SUBDEV_SENSOR (MEDIA_ENT_T_V4L2_SUBDEV + 1)
57#define MEDIA_ENT_T_V4L2_SUBDEV_FLASH (MEDIA_ENT_T_V4L2_SUBDEV + 2)
58#define MEDIA_ENT_T_V4L2_SUBDEV_LENS (MEDIA_ENT_T_V4L2_SUBDEV + 3)
59
60#define MEDIA_ENT_FL_DEFAULT (1 << 0)
61
62struct media_entity_desc {
63 __u32 id;
64 char name[32];
65 __u32 type;
66 __u32 revision;
67 __u32 flags;
68 __u32 group_id;
69 __u16 pads;
70 __u16 links;
71
72 __u32 reserved[4];
73
74 union {
75 /* Node specifications */
76 struct {
77 __u32 major;
78 __u32 minor;
79 } v4l;
80 struct {
81 __u32 major;
82 __u32 minor;
83 } fb;
84 struct {
85 __u32 card;
86 __u32 device;
87 __u32 subdevice;
88 } alsa;
89 int dvb;
90
91 /* Sub-device specifications */
92 /* Nothing needed yet */
93 __u8 raw[184];
94 };
95};
96
97#define MEDIA_PAD_FL_SINK (1 << 0)
98#define MEDIA_PAD_FL_SOURCE (1 << 1)
99
100struct media_pad_desc {
101 __u32 entity; /* entity ID */
102 __u16 index; /* pad index */
103 __u32 flags; /* pad flags */
104 __u32 reserved[2];
105};
106
107#define MEDIA_LNK_FL_ENABLED (1 << 0)
108#define MEDIA_LNK_FL_IMMUTABLE (1 << 1)
109#define MEDIA_LNK_FL_DYNAMIC (1 << 2)
110
111struct media_link_desc {
112 struct media_pad_desc source;
113 struct media_pad_desc sink;
114 __u32 flags;
115 __u32 reserved[2];
116};
117
118struct media_links_enum {
119 __u32 entity;
120 /* Should have enough room for pads elements */
121 struct media_pad_desc __user *pads;
122 /* Should have enough room for links elements */
123 struct media_link_desc __user *links;
124 __u32 reserved[4];
125};
126
127#define MEDIA_IOC_DEVICE_INFO _IOWR('|', 0x00, struct media_device_info)
128#define MEDIA_IOC_ENUM_ENTITIES _IOWR('|', 0x01, struct media_entity_desc)
129#define MEDIA_IOC_ENUM_LINKS _IOWR('|', 0x02, struct media_links_enum)
130#define MEDIA_IOC_SETUP_LINK _IOWR('|', 0x03, struct media_link_desc)
131
132#endif /* __LINUX_MEDIA_H */
diff --git a/include/linux/mfd/wl1273-core.h b/include/linux/mfd/wl1273-core.h
index 9787293eae5f..db2f3f454a1b 100644
--- a/include/linux/mfd/wl1273-core.h
+++ b/include/linux/mfd/wl1273-core.h
@@ -280,7 +280,9 @@ struct wl1273_core {
280 280
281 struct i2c_client *client; 281 struct i2c_client *client;
282 282
283 int (*read)(struct wl1273_core *core, u8, u16 *);
283 int (*write)(struct wl1273_core *core, u8, u16); 284 int (*write)(struct wl1273_core *core, u8, u16);
285 int (*write_data)(struct wl1273_core *core, u8 *, u16);
284 int (*set_audio)(struct wl1273_core *core, unsigned int); 286 int (*set_audio)(struct wl1273_core *core, unsigned int);
285 int (*set_volume)(struct wl1273_core *core, unsigned int); 287 int (*set_volume)(struct wl1273_core *core, unsigned int);
286}; 288};
diff --git a/include/linux/omap3isp.h b/include/linux/omap3isp.h
new file mode 100644
index 000000000000..150822b4dbff
--- /dev/null
+++ b/include/linux/omap3isp.h
@@ -0,0 +1,646 @@
1/*
2 * omap3isp.h
3 *
4 * TI OMAP3 ISP - User-space API
5 *
6 * Copyright (C) 2010 Nokia Corporation
7 * Copyright (C) 2009 Texas Instruments, Inc.
8 *
9 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
10 * Sakari Ailus <sakari.ailus@iki.fi>
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful, but
17 * WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 * 02110-1301 USA
25 */
26
27#ifndef OMAP3_ISP_USER_H
28#define OMAP3_ISP_USER_H
29
30#include <linux/types.h>
31
32/*
33 * Private IOCTLs
34 *
35 * VIDIOC_OMAP3ISP_CCDC_CFG: Set CCDC configuration
36 * VIDIOC_OMAP3ISP_PRV_CFG: Set preview engine configuration
37 * VIDIOC_OMAP3ISP_AEWB_CFG: Set AEWB module configuration
38 * VIDIOC_OMAP3ISP_HIST_CFG: Set histogram module configuration
39 * VIDIOC_OMAP3ISP_AF_CFG: Set auto-focus module configuration
40 * VIDIOC_OMAP3ISP_STAT_REQ: Read statistics (AEWB/AF/histogram) data
41 * VIDIOC_OMAP3ISP_STAT_EN: Enable/disable a statistics module
42 */
43
44#define VIDIOC_OMAP3ISP_CCDC_CFG \
45 _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct omap3isp_ccdc_update_config)
46#define VIDIOC_OMAP3ISP_PRV_CFG \
47 _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct omap3isp_prev_update_config)
48#define VIDIOC_OMAP3ISP_AEWB_CFG \
49 _IOWR('V', BASE_VIDIOC_PRIVATE + 3, struct omap3isp_h3a_aewb_config)
50#define VIDIOC_OMAP3ISP_HIST_CFG \
51 _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct omap3isp_hist_config)
52#define VIDIOC_OMAP3ISP_AF_CFG \
53 _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct omap3isp_h3a_af_config)
54#define VIDIOC_OMAP3ISP_STAT_REQ \
55 _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct omap3isp_stat_data)
56#define VIDIOC_OMAP3ISP_STAT_EN \
57 _IOWR('V', BASE_VIDIOC_PRIVATE + 7, unsigned long)
58
59/*
60 * Events
61 *
62 * V4L2_EVENT_OMAP3ISP_AEWB: AEWB statistics data ready
63 * V4L2_EVENT_OMAP3ISP_AF: AF statistics data ready
64 * V4L2_EVENT_OMAP3ISP_HIST: Histogram statistics data ready
65 * V4L2_EVENT_OMAP3ISP_HS_VS: Horizontal/vertical synchronization detected
66 */
67
68#define V4L2_EVENT_OMAP3ISP_CLASS (V4L2_EVENT_PRIVATE_START | 0x100)
69#define V4L2_EVENT_OMAP3ISP_AEWB (V4L2_EVENT_OMAP3ISP_CLASS | 0x1)
70#define V4L2_EVENT_OMAP3ISP_AF (V4L2_EVENT_OMAP3ISP_CLASS | 0x2)
71#define V4L2_EVENT_OMAP3ISP_HIST (V4L2_EVENT_OMAP3ISP_CLASS | 0x3)
72#define V4L2_EVENT_OMAP3ISP_HS_VS (V4L2_EVENT_OMAP3ISP_CLASS | 0x4)
73
74struct omap3isp_stat_event_status {
75 __u32 frame_number;
76 __u16 config_counter;
77 __u8 buf_err;
78};
79
80/* AE/AWB related structures and flags*/
81
82/* H3A Range Constants */
83#define OMAP3ISP_AEWB_MAX_SATURATION_LIM 1023
84#define OMAP3ISP_AEWB_MIN_WIN_H 2
85#define OMAP3ISP_AEWB_MAX_WIN_H 256
86#define OMAP3ISP_AEWB_MIN_WIN_W 6
87#define OMAP3ISP_AEWB_MAX_WIN_W 256
88#define OMAP3ISP_AEWB_MIN_WINVC 1
89#define OMAP3ISP_AEWB_MIN_WINHC 1
90#define OMAP3ISP_AEWB_MAX_WINVC 128
91#define OMAP3ISP_AEWB_MAX_WINHC 36
92#define OMAP3ISP_AEWB_MAX_WINSTART 4095
93#define OMAP3ISP_AEWB_MIN_SUB_INC 2
94#define OMAP3ISP_AEWB_MAX_SUB_INC 32
95#define OMAP3ISP_AEWB_MAX_BUF_SIZE 83600
96
97#define OMAP3ISP_AF_IIRSH_MIN 0
98#define OMAP3ISP_AF_IIRSH_MAX 4095
99#define OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MIN 1
100#define OMAP3ISP_AF_PAXEL_HORIZONTAL_COUNT_MAX 36
101#define OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MIN 1
102#define OMAP3ISP_AF_PAXEL_VERTICAL_COUNT_MAX 128
103#define OMAP3ISP_AF_PAXEL_INCREMENT_MIN 2
104#define OMAP3ISP_AF_PAXEL_INCREMENT_MAX 32
105#define OMAP3ISP_AF_PAXEL_HEIGHT_MIN 2
106#define OMAP3ISP_AF_PAXEL_HEIGHT_MAX 256
107#define OMAP3ISP_AF_PAXEL_WIDTH_MIN 16
108#define OMAP3ISP_AF_PAXEL_WIDTH_MAX 256
109#define OMAP3ISP_AF_PAXEL_HZSTART_MIN 1
110#define OMAP3ISP_AF_PAXEL_HZSTART_MAX 4095
111#define OMAP3ISP_AF_PAXEL_VTSTART_MIN 0
112#define OMAP3ISP_AF_PAXEL_VTSTART_MAX 4095
113#define OMAP3ISP_AF_THRESHOLD_MAX 255
114#define OMAP3ISP_AF_COEF_MAX 4095
115#define OMAP3ISP_AF_PAXEL_SIZE 48
116#define OMAP3ISP_AF_MAX_BUF_SIZE 221184
117
118/**
119 * struct omap3isp_h3a_aewb_config - AE AWB configuration reset values
120 * saturation_limit: Saturation limit.
121 * @win_height: Window Height. Range 2 - 256, even values only.
122 * @win_width: Window Width. Range 6 - 256, even values only.
123 * @ver_win_count: Vertical Window Count. Range 1 - 128.
124 * @hor_win_count: Horizontal Window Count. Range 1 - 36.
125 * @ver_win_start: Vertical Window Start. Range 0 - 4095.
126 * @hor_win_start: Horizontal Window Start. Range 0 - 4095.
127 * @blk_ver_win_start: Black Vertical Windows Start. Range 0 - 4095.
128 * @blk_win_height: Black Window Height. Range 2 - 256, even values only.
129 * @subsample_ver_inc: Subsample Vertical points increment Range 2 - 32, even
130 * values only.
131 * @subsample_hor_inc: Subsample Horizontal points increment Range 2 - 32, even
132 * values only.
133 * @alaw_enable: AEW ALAW EN flag.
134 */
135struct omap3isp_h3a_aewb_config {
136 /*
137 * Common fields.
138 * They should be the first ones and must be in the same order as in
139 * ispstat_generic_config struct.
140 */
141 __u32 buf_size;
142 __u16 config_counter;
143
144 /* Private fields */
145 __u16 saturation_limit;
146 __u16 win_height;
147 __u16 win_width;
148 __u16 ver_win_count;
149 __u16 hor_win_count;
150 __u16 ver_win_start;
151 __u16 hor_win_start;
152 __u16 blk_ver_win_start;
153 __u16 blk_win_height;
154 __u16 subsample_ver_inc;
155 __u16 subsample_hor_inc;
156 __u8 alaw_enable;
157};
158
159/**
160 * struct omap3isp_stat_data - Statistic data sent to or received from user
161 * @ts: Timestamp of returned framestats.
162 * @buf: Pointer to pass to user.
163 * @frame_number: Frame number of requested stats.
164 * @cur_frame: Current frame number being processed.
165 * @config_counter: Number of the configuration associated with the data.
166 */
167struct omap3isp_stat_data {
168 struct timeval ts;
169 void __user *buf;
170 __u32 buf_size;
171 __u16 frame_number;
172 __u16 cur_frame;
173 __u16 config_counter;
174};
175
176
177/* Histogram related structs */
178
179/* Flags for number of bins */
180#define OMAP3ISP_HIST_BINS_32 0
181#define OMAP3ISP_HIST_BINS_64 1
182#define OMAP3ISP_HIST_BINS_128 2
183#define OMAP3ISP_HIST_BINS_256 3
184
185/* Number of bins * 4 colors * 4-bytes word */
186#define OMAP3ISP_HIST_MEM_SIZE_BINS(n) ((1 << ((n)+5))*4*4)
187
188#define OMAP3ISP_HIST_MEM_SIZE 1024
189#define OMAP3ISP_HIST_MIN_REGIONS 1
190#define OMAP3ISP_HIST_MAX_REGIONS 4
191#define OMAP3ISP_HIST_MAX_WB_GAIN 255
192#define OMAP3ISP_HIST_MIN_WB_GAIN 0
193#define OMAP3ISP_HIST_MAX_BIT_WIDTH 14
194#define OMAP3ISP_HIST_MIN_BIT_WIDTH 8
195#define OMAP3ISP_HIST_MAX_WG 4
196#define OMAP3ISP_HIST_MAX_BUF_SIZE 4096
197
198/* Source */
199#define OMAP3ISP_HIST_SOURCE_CCDC 0
200#define OMAP3ISP_HIST_SOURCE_MEM 1
201
202/* CFA pattern */
203#define OMAP3ISP_HIST_CFA_BAYER 0
204#define OMAP3ISP_HIST_CFA_FOVEONX3 1
205
206struct omap3isp_hist_region {
207 __u16 h_start;
208 __u16 h_end;
209 __u16 v_start;
210 __u16 v_end;
211};
212
213struct omap3isp_hist_config {
214 /*
215 * Common fields.
216 * They should be the first ones and must be in the same order as in
217 * ispstat_generic_config struct.
218 */
219 __u32 buf_size;
220 __u16 config_counter;
221
222 __u8 num_acc_frames; /* Num of image frames to be processed and
223 accumulated for each histogram frame */
224 __u16 hist_bins; /* number of bins: 32, 64, 128, or 256 */
225 __u8 cfa; /* BAYER or FOVEON X3 */
226 __u8 wg[OMAP3ISP_HIST_MAX_WG]; /* White Balance Gain */
227 __u8 num_regions; /* number of regions to be configured */
228 struct omap3isp_hist_region region[OMAP3ISP_HIST_MAX_REGIONS];
229};
230
231/* Auto Focus related structs */
232
233#define OMAP3ISP_AF_NUM_COEF 11
234
235enum omap3isp_h3a_af_fvmode {
236 OMAP3ISP_AF_MODE_SUMMED = 0,
237 OMAP3ISP_AF_MODE_PEAK = 1
238};
239
240/* Red, Green, and blue pixel location in the AF windows */
241enum omap3isp_h3a_af_rgbpos {
242 OMAP3ISP_AF_GR_GB_BAYER = 0, /* GR and GB as Bayer pattern */
243 OMAP3ISP_AF_RG_GB_BAYER = 1, /* RG and GB as Bayer pattern */
244 OMAP3ISP_AF_GR_BG_BAYER = 2, /* GR and BG as Bayer pattern */
245 OMAP3ISP_AF_RG_BG_BAYER = 3, /* RG and BG as Bayer pattern */
246 OMAP3ISP_AF_GG_RB_CUSTOM = 4, /* GG and RB as custom pattern */
247 OMAP3ISP_AF_RB_GG_CUSTOM = 5 /* RB and GG as custom pattern */
248};
249
250/* Contains the information regarding the Horizontal Median Filter */
251struct omap3isp_h3a_af_hmf {
252 __u8 enable; /* Status of Horizontal Median Filter */
253 __u8 threshold; /* Threshhold Value for Horizontal Median Filter */
254};
255
256/* Contains the information regarding the IIR Filters */
257struct omap3isp_h3a_af_iir {
258 __u16 h_start; /* IIR horizontal start */
259 __u16 coeff_set0[OMAP3ISP_AF_NUM_COEF]; /* Filter coefficient, set 0 */
260 __u16 coeff_set1[OMAP3ISP_AF_NUM_COEF]; /* Filter coefficient, set 1 */
261};
262
263/* Contains the information regarding the Paxels Structure in AF Engine */
264struct omap3isp_h3a_af_paxel {
265 __u16 h_start; /* Horizontal Start Position */
266 __u16 v_start; /* Vertical Start Position */
267 __u8 width; /* Width of the Paxel */
268 __u8 height; /* Height of the Paxel */
269 __u8 h_cnt; /* Horizontal Count */
270 __u8 v_cnt; /* vertical Count */
271 __u8 line_inc; /* Line Increment */
272};
273
274/* Contains the parameters required for hardware set up of AF Engine */
275struct omap3isp_h3a_af_config {
276 /*
277 * Common fields.
278 * They should be the first ones and must be in the same order as in
279 * ispstat_generic_config struct.
280 */
281 __u32 buf_size;
282 __u16 config_counter;
283
284 struct omap3isp_h3a_af_hmf hmf; /* HMF configurations */
285 struct omap3isp_h3a_af_iir iir; /* IIR filter configurations */
286 struct omap3isp_h3a_af_paxel paxel; /* Paxel parameters */
287 enum omap3isp_h3a_af_rgbpos rgb_pos; /* RGB Positions */
288 enum omap3isp_h3a_af_fvmode fvmode; /* Accumulator mode */
289 __u8 alaw_enable; /* AF ALAW status */
290};
291
292/* ISP CCDC structs */
293
294/* Abstraction layer CCDC configurations */
295#define OMAP3ISP_CCDC_ALAW (1 << 0)
296#define OMAP3ISP_CCDC_LPF (1 << 1)
297#define OMAP3ISP_CCDC_BLCLAMP (1 << 2)
298#define OMAP3ISP_CCDC_BCOMP (1 << 3)
299#define OMAP3ISP_CCDC_FPC (1 << 4)
300#define OMAP3ISP_CCDC_CULL (1 << 5)
301#define OMAP3ISP_CCDC_CONFIG_LSC (1 << 7)
302#define OMAP3ISP_CCDC_TBL_LSC (1 << 8)
303
304#define OMAP3ISP_RGB_MAX 3
305
306/* Enumeration constants for Alaw input width */
307enum omap3isp_alaw_ipwidth {
308 OMAP3ISP_ALAW_BIT12_3 = 0x3,
309 OMAP3ISP_ALAW_BIT11_2 = 0x4,
310 OMAP3ISP_ALAW_BIT10_1 = 0x5,
311 OMAP3ISP_ALAW_BIT9_0 = 0x6
312};
313
314/**
315 * struct omap3isp_ccdc_lsc_config - LSC configuration
316 * @offset: Table Offset of the gain table.
317 * @gain_mode_n: Vertical dimension of a paxel in LSC configuration.
318 * @gain_mode_m: Horizontal dimension of a paxel in LSC configuration.
319 * @gain_format: Gain table format.
320 * @fmtsph: Start pixel horizontal from start of the HS sync pulse.
321 * @fmtlnh: Number of pixels in horizontal direction to use for the data
322 * reformatter.
323 * @fmtslv: Start line from start of VS sync pulse for the data reformatter.
324 * @fmtlnv: Number of lines in vertical direction for the data reformatter.
325 * @initial_x: X position, in pixels, of the first active pixel in reference
326 * to the first active paxel. Must be an even number.
327 * @initial_y: Y position, in pixels, of the first active pixel in reference
328 * to the first active paxel. Must be an even number.
329 * @size: Size of LSC gain table. Filled when loaded from userspace.
330 */
331struct omap3isp_ccdc_lsc_config {
332 __u16 offset;
333 __u8 gain_mode_n;
334 __u8 gain_mode_m;
335 __u8 gain_format;
336 __u16 fmtsph;
337 __u16 fmtlnh;
338 __u16 fmtslv;
339 __u16 fmtlnv;
340 __u8 initial_x;
341 __u8 initial_y;
342 __u32 size;
343};
344
345/**
346 * struct omap3isp_ccdc_bclamp - Optical & Digital black clamp subtract
347 * @obgain: Optical black average gain.
348 * @obstpixel: Start Pixel w.r.t. HS pulse in Optical black sample.
349 * @oblines: Optical Black Sample lines.
350 * @oblen: Optical Black Sample Length.
351 * @dcsubval: Digital Black Clamp subtract value.
352 */
353struct omap3isp_ccdc_bclamp {
354 __u8 obgain;
355 __u8 obstpixel;
356 __u8 oblines;
357 __u8 oblen;
358 __u16 dcsubval;
359};
360
361/**
362 * struct omap3isp_ccdc_fpc - Faulty Pixels Correction
363 * @fpnum: Number of faulty pixels to be corrected in the frame.
364 * @fpcaddr: Memory address of the FPC Table
365 */
366struct omap3isp_ccdc_fpc {
367 __u16 fpnum;
368 __u32 fpcaddr;
369};
370
371/**
372 * struct omap3isp_ccdc_blcomp - Black Level Compensation parameters
373 * @b_mg: B/Mg pixels. 2's complement. -128 to +127.
374 * @gb_g: Gb/G pixels. 2's complement. -128 to +127.
375 * @gr_cy: Gr/Cy pixels. 2's complement. -128 to +127.
376 * @r_ye: R/Ye pixels. 2's complement. -128 to +127.
377 */
378struct omap3isp_ccdc_blcomp {
379 __u8 b_mg;
380 __u8 gb_g;
381 __u8 gr_cy;
382 __u8 r_ye;
383};
384
385/**
386 * omap3isp_ccdc_culling - Culling parameters
387 * @v_pattern: Vertical culling pattern.
388 * @h_odd: Horizontal Culling pattern for odd lines.
389 * @h_even: Horizontal Culling pattern for even lines.
390 */
391struct omap3isp_ccdc_culling {
392 __u8 v_pattern;
393 __u16 h_odd;
394 __u16 h_even;
395};
396
397/**
398 * omap3isp_ccdc_update_config - CCDC configuration
399 * @update: Specifies which CCDC registers should be updated.
400 * @flag: Specifies which CCDC functions should be enabled.
401 * @alawip: Enable/Disable A-Law compression.
402 * @bclamp: Black clamp control register.
403 * @blcomp: Black level compensation value for RGrGbB Pixels. 2's complement.
404 * @fpc: Number of faulty pixels corrected in the frame, address of FPC table.
405 * @cull: Cull control register.
406 * @lsc: Pointer to LSC gain table.
407 */
408struct omap3isp_ccdc_update_config {
409 __u16 update;
410 __u16 flag;
411 enum omap3isp_alaw_ipwidth alawip;
412 struct omap3isp_ccdc_bclamp __user *bclamp;
413 struct omap3isp_ccdc_blcomp __user *blcomp;
414 struct omap3isp_ccdc_fpc __user *fpc;
415 struct omap3isp_ccdc_lsc_config __user *lsc_cfg;
416 struct omap3isp_ccdc_culling __user *cull;
417 __u8 __user *lsc;
418};
419
420/* Preview configurations */
421#define OMAP3ISP_PREV_LUMAENH (1 << 0)
422#define OMAP3ISP_PREV_INVALAW (1 << 1)
423#define OMAP3ISP_PREV_HRZ_MED (1 << 2)
424#define OMAP3ISP_PREV_CFA (1 << 3)
425#define OMAP3ISP_PREV_CHROMA_SUPP (1 << 4)
426#define OMAP3ISP_PREV_WB (1 << 5)
427#define OMAP3ISP_PREV_BLKADJ (1 << 6)
428#define OMAP3ISP_PREV_RGB2RGB (1 << 7)
429#define OMAP3ISP_PREV_COLOR_CONV (1 << 8)
430#define OMAP3ISP_PREV_YC_LIMIT (1 << 9)
431#define OMAP3ISP_PREV_DEFECT_COR (1 << 10)
432#define OMAP3ISP_PREV_GAMMABYPASS (1 << 11)
433#define OMAP3ISP_PREV_DRK_FRM_CAPTURE (1 << 12)
434#define OMAP3ISP_PREV_DRK_FRM_SUBTRACT (1 << 13)
435#define OMAP3ISP_PREV_LENS_SHADING (1 << 14)
436#define OMAP3ISP_PREV_NF (1 << 15)
437#define OMAP3ISP_PREV_GAMMA (1 << 16)
438
439#define OMAP3ISP_PREV_NF_TBL_SIZE 64
440#define OMAP3ISP_PREV_CFA_TBL_SIZE 576
441#define OMAP3ISP_PREV_GAMMA_TBL_SIZE 1024
442#define OMAP3ISP_PREV_YENH_TBL_SIZE 128
443
444#define OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS 4
445
446/**
447 * struct omap3isp_prev_hmed - Horizontal Median Filter
448 * @odddist: Distance between consecutive pixels of same color in the odd line.
449 * @evendist: Distance between consecutive pixels of same color in the even
450 * line.
451 * @thres: Horizontal median filter threshold.
452 */
453struct omap3isp_prev_hmed {
454 __u8 odddist;
455 __u8 evendist;
456 __u8 thres;
457};
458
459/*
460 * Enumeration for CFA Formats supported by preview
461 */
462enum omap3isp_cfa_fmt {
463 OMAP3ISP_CFAFMT_BAYER,
464 OMAP3ISP_CFAFMT_SONYVGA,
465 OMAP3ISP_CFAFMT_RGBFOVEON,
466 OMAP3ISP_CFAFMT_DNSPL,
467 OMAP3ISP_CFAFMT_HONEYCOMB,
468 OMAP3ISP_CFAFMT_RRGGBBFOVEON
469};
470
471/**
472 * struct omap3isp_prev_cfa - CFA Interpolation
473 * @format: CFA Format Enum value supported by preview.
474 * @gradthrs_vert: CFA Gradient Threshold - Vertical.
475 * @gradthrs_horz: CFA Gradient Threshold - Horizontal.
476 * @table: Pointer to the CFA table.
477 */
478struct omap3isp_prev_cfa {
479 enum omap3isp_cfa_fmt format;
480 __u8 gradthrs_vert;
481 __u8 gradthrs_horz;
482 __u32 table[OMAP3ISP_PREV_CFA_TBL_SIZE];
483};
484
485/**
486 * struct omap3isp_prev_csup - Chrominance Suppression
487 * @gain: Gain.
488 * @thres: Threshold.
489 * @hypf_en: Flag to enable/disable the High Pass Filter.
490 */
491struct omap3isp_prev_csup {
492 __u8 gain;
493 __u8 thres;
494 __u8 hypf_en;
495};
496
497/**
498 * struct omap3isp_prev_wbal - White Balance
499 * @dgain: Digital gain (U10Q8).
500 * @coef3: White balance gain - COEF 3 (U8Q5).
501 * @coef2: White balance gain - COEF 2 (U8Q5).
502 * @coef1: White balance gain - COEF 1 (U8Q5).
503 * @coef0: White balance gain - COEF 0 (U8Q5).
504 */
505struct omap3isp_prev_wbal {
506 __u16 dgain;
507 __u8 coef3;
508 __u8 coef2;
509 __u8 coef1;
510 __u8 coef0;
511};
512
513/**
514 * struct omap3isp_prev_blkadj - Black Level Adjustment
515 * @red: Black level offset adjustment for Red in 2's complement format
516 * @green: Black level offset adjustment for Green in 2's complement format
517 * @blue: Black level offset adjustment for Blue in 2's complement format
518 */
519struct omap3isp_prev_blkadj {
520 /*Black level offset adjustment for Red in 2's complement format */
521 __u8 red;
522 /*Black level offset adjustment for Green in 2's complement format */
523 __u8 green;
524 /* Black level offset adjustment for Blue in 2's complement format */
525 __u8 blue;
526};
527
528/**
529 * struct omap3isp_prev_rgbtorgb - RGB to RGB Blending
530 * @matrix: Blending values(S12Q8 format)
531 * [RR] [GR] [BR]
532 * [RG] [GG] [BG]
533 * [RB] [GB] [BB]
534 * @offset: Blending offset value for R,G,B in 2's complement integer format.
535 */
536struct omap3isp_prev_rgbtorgb {
537 __u16 matrix[OMAP3ISP_RGB_MAX][OMAP3ISP_RGB_MAX];
538 __u16 offset[OMAP3ISP_RGB_MAX];
539};
540
541/**
542 * struct omap3isp_prev_csc - Color Space Conversion from RGB-YCbYCr
543 * @matrix: Color space conversion coefficients(S10Q8)
544 * [CSCRY] [CSCGY] [CSCBY]
545 * [CSCRCB] [CSCGCB] [CSCBCB]
546 * [CSCRCR] [CSCGCR] [CSCBCR]
547 * @offset: CSC offset values for Y offset, CB offset and CR offset respectively
548 */
549struct omap3isp_prev_csc {
550 __u16 matrix[OMAP3ISP_RGB_MAX][OMAP3ISP_RGB_MAX];
551 __s16 offset[OMAP3ISP_RGB_MAX];
552};
553
554/**
555 * struct omap3isp_prev_yclimit - Y, C Value Limit
556 * @minC: Minimum C value
557 * @maxC: Maximum C value
558 * @minY: Minimum Y value
559 * @maxY: Maximum Y value
560 */
561struct omap3isp_prev_yclimit {
562 __u8 minC;
563 __u8 maxC;
564 __u8 minY;
565 __u8 maxY;
566};
567
568/**
569 * struct omap3isp_prev_dcor - Defect correction
570 * @couplet_mode_en: Flag to enable or disable the couplet dc Correction in NF
571 * @detect_correct: Thresholds for correction bit 0:10 detect 16:25 correct
572 */
573struct omap3isp_prev_dcor {
574 __u8 couplet_mode_en;
575 __u32 detect_correct[OMAP3ISP_PREV_DETECT_CORRECT_CHANNELS];
576};
577
578/**
579 * struct omap3isp_prev_nf - Noise Filter
580 * @spread: Spread value to be used in Noise Filter
581 * @table: Pointer to the Noise Filter table
582 */
583struct omap3isp_prev_nf {
584 __u8 spread;
585 __u32 table[OMAP3ISP_PREV_NF_TBL_SIZE];
586};
587
588/**
589 * struct omap3isp_prev_gtables - Gamma correction tables
590 * @red: Array for red gamma table.
591 * @green: Array for green gamma table.
592 * @blue: Array for blue gamma table.
593 */
594struct omap3isp_prev_gtables {
595 __u32 red[OMAP3ISP_PREV_GAMMA_TBL_SIZE];
596 __u32 green[OMAP3ISP_PREV_GAMMA_TBL_SIZE];
597 __u32 blue[OMAP3ISP_PREV_GAMMA_TBL_SIZE];
598};
599
600/**
601 * struct omap3isp_prev_luma - Luma enhancement
602 * @table: Array for luma enhancement table.
603 */
604struct omap3isp_prev_luma {
605 __u32 table[OMAP3ISP_PREV_YENH_TBL_SIZE];
606};
607
608/**
609 * struct omap3isp_prev_update_config - Preview engine configuration (user)
610 * @update: Specifies which ISP Preview registers should be updated.
611 * @flag: Specifies which ISP Preview functions should be enabled.
612 * @shading_shift: 3bit value of shift used in shading compensation.
613 * @luma: Pointer to luma enhancement structure.
614 * @hmed: Pointer to structure containing the odd and even distance.
615 * between the pixels in the image along with the filter threshold.
616 * @cfa: Pointer to structure containing the CFA interpolation table, CFA.
617 * format in the image, vertical and horizontal gradient threshold.
618 * @csup: Pointer to Structure for Chrominance Suppression coefficients.
619 * @wbal: Pointer to structure for White Balance.
620 * @blkadj: Pointer to structure for Black Adjustment.
621 * @rgb2rgb: Pointer to structure for RGB to RGB Blending.
622 * @csc: Pointer to structure for Color Space Conversion from RGB-YCbYCr.
623 * @yclimit: Pointer to structure for Y, C Value Limit.
624 * @dcor: Pointer to structure for defect correction.
625 * @nf: Pointer to structure for Noise Filter
626 * @gamma: Pointer to gamma structure.
627 */
628struct omap3isp_prev_update_config {
629 __u32 update;
630 __u32 flag;
631 __u32 shading_shift;
632 struct omap3isp_prev_luma __user *luma;
633 struct omap3isp_prev_hmed __user *hmed;
634 struct omap3isp_prev_cfa __user *cfa;
635 struct omap3isp_prev_csup __user *csup;
636 struct omap3isp_prev_wbal __user *wbal;
637 struct omap3isp_prev_blkadj __user *blkadj;
638 struct omap3isp_prev_rgbtorgb __user *rgb2rgb;
639 struct omap3isp_prev_csc __user *csc;
640 struct omap3isp_prev_yclimit __user *yclimit;
641 struct omap3isp_prev_dcor __user *dcor;
642 struct omap3isp_prev_nf __user *nf;
643 struct omap3isp_prev_gtables __user *gamma;
644};
645
646#endif /* OMAP3_ISP_USER_H */
diff --git a/include/linux/v4l2-mediabus.h b/include/linux/v4l2-mediabus.h
new file mode 100644
index 000000000000..7054a7a8065e
--- /dev/null
+++ b/include/linux/v4l2-mediabus.h
@@ -0,0 +1,108 @@
1/*
2 * Media Bus API header
3 *
4 * Copyright (C) 2009, Guennadi Liakhovetski <g.liakhovetski@gmx.de>
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 version 2 as
8 * published by the Free Software Foundation.
9 */
10
11#ifndef __LINUX_V4L2_MEDIABUS_H
12#define __LINUX_V4L2_MEDIABUS_H
13
14#include <linux/types.h>
15#include <linux/videodev2.h>
16
17/*
18 * These pixel codes uniquely identify data formats on the media bus. Mostly
19 * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is
20 * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the
21 * data format is fixed. Additionally, "2X8" means that one pixel is transferred
22 * in two 8-bit samples, "BE" or "LE" specify in which order those samples are
23 * transferred over the bus: "LE" means that the least significant bits are
24 * transferred first, "BE" means that the most significant bits are transferred
25 * first, and "PADHI" and "PADLO" define which bits - low or high, in the
26 * incomplete high byte, are filled with padding bits.
27 *
28 * The pixel codes are grouped by type, bus_width, bits per component, samples
29 * per pixel and order of subsamples. Numerical values are sorted using generic
30 * numerical sort order (8 thus comes before 10).
31 *
32 * As their value can't change when a new pixel code is inserted in the
33 * enumeration, the pixel codes are explicitly given a numerical value. The next
34 * free values for each category are listed below, update them when inserting
35 * new pixel codes.
36 */
37enum v4l2_mbus_pixelcode {
38 V4L2_MBUS_FMT_FIXED = 0x0001,
39
40 /* RGB - next is 0x1009 */
41 V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE = 0x1001,
42 V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE = 0x1002,
43 V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE = 0x1003,
44 V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE = 0x1004,
45 V4L2_MBUS_FMT_BGR565_2X8_BE = 0x1005,
46 V4L2_MBUS_FMT_BGR565_2X8_LE = 0x1006,
47 V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007,
48 V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008,
49
50 /* YUV (including grey) - next is 0x2013 */
51 V4L2_MBUS_FMT_Y8_1X8 = 0x2001,
52 V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
53 V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003,
54 V4L2_MBUS_FMT_YUYV8_1_5X8 = 0x2004,
55 V4L2_MBUS_FMT_YVYU8_1_5X8 = 0x2005,
56 V4L2_MBUS_FMT_UYVY8_2X8 = 0x2006,
57 V4L2_MBUS_FMT_VYUY8_2X8 = 0x2007,
58 V4L2_MBUS_FMT_YUYV8_2X8 = 0x2008,
59 V4L2_MBUS_FMT_YVYU8_2X8 = 0x2009,
60 V4L2_MBUS_FMT_Y10_1X10 = 0x200a,
61 V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b,
62 V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c,
63 V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f,
64 V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010,
65 V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011,
66 V4L2_MBUS_FMT_YVYU8_1X16 = 0x2012,
67 V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d,
68 V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
69
70 /* Bayer - next is 0x3013 */
71 V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
72 V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002,
73 V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b,
74 V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c,
75 V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009,
76 V4L2_MBUS_FMT_SRGGB10_DPCM8_1X8 = 0x300d,
77 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE = 0x3003,
78 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE = 0x3004,
79 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE = 0x3005,
80 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE = 0x3006,
81 V4L2_MBUS_FMT_SBGGR10_1X10 = 0x3007,
82 V4L2_MBUS_FMT_SGBRG10_1X10 = 0x300e,
83 V4L2_MBUS_FMT_SGRBG10_1X10 = 0x300a,
84 V4L2_MBUS_FMT_SRGGB10_1X10 = 0x300f,
85 V4L2_MBUS_FMT_SBGGR12_1X12 = 0x3008,
86 V4L2_MBUS_FMT_SGBRG12_1X12 = 0x3010,
87 V4L2_MBUS_FMT_SGRBG12_1X12 = 0x3011,
88 V4L2_MBUS_FMT_SRGGB12_1X12 = 0x3012,
89};
90
91/**
92 * struct v4l2_mbus_framefmt - frame format on the media bus
93 * @width: frame width
94 * @height: frame height
95 * @code: data format code (from enum v4l2_mbus_pixelcode)
96 * @field: used interlacing type (from enum v4l2_field)
97 * @colorspace: colorspace of the data (from enum v4l2_colorspace)
98 */
99struct v4l2_mbus_framefmt {
100 __u32 width;
101 __u32 height;
102 __u32 code;
103 __u32 field;
104 __u32 colorspace;
105 __u32 reserved[7];
106};
107
108#endif
diff --git a/include/linux/v4l2-subdev.h b/include/linux/v4l2-subdev.h
new file mode 100644
index 000000000000..ed29cbbebfef
--- /dev/null
+++ b/include/linux/v4l2-subdev.h
@@ -0,0 +1,141 @@
1/*
2 * V4L2 subdev userspace API
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef __LINUX_V4L2_SUBDEV_H
24#define __LINUX_V4L2_SUBDEV_H
25
26#include <linux/ioctl.h>
27#include <linux/types.h>
28#include <linux/v4l2-mediabus.h>
29
30/**
31 * enum v4l2_subdev_format_whence - Media bus format type
32 * @V4L2_SUBDEV_FORMAT_TRY: try format, for negotiation only
33 * @V4L2_SUBDEV_FORMAT_ACTIVE: active format, applied to the device
34 */
35enum v4l2_subdev_format_whence {
36 V4L2_SUBDEV_FORMAT_TRY = 0,
37 V4L2_SUBDEV_FORMAT_ACTIVE = 1,
38};
39
40/**
41 * struct v4l2_subdev_format - Pad-level media bus format
42 * @which: format type (from enum v4l2_subdev_format_whence)
43 * @pad: pad number, as reported by the media API
44 * @format: media bus format (format code and frame size)
45 */
46struct v4l2_subdev_format {
47 __u32 which;
48 __u32 pad;
49 struct v4l2_mbus_framefmt format;
50 __u32 reserved[8];
51};
52
53/**
54 * struct v4l2_subdev_crop - Pad-level crop settings
55 * @which: format type (from enum v4l2_subdev_format_whence)
56 * @pad: pad number, as reported by the media API
57 * @rect: pad crop rectangle boundaries
58 */
59struct v4l2_subdev_crop {
60 __u32 which;
61 __u32 pad;
62 struct v4l2_rect rect;
63 __u32 reserved[8];
64};
65
66/**
67 * struct v4l2_subdev_mbus_code_enum - Media bus format enumeration
68 * @pad: pad number, as reported by the media API
69 * @index: format index during enumeration
70 * @code: format code (from enum v4l2_mbus_pixelcode)
71 */
72struct v4l2_subdev_mbus_code_enum {
73 __u32 pad;
74 __u32 index;
75 __u32 code;
76 __u32 reserved[9];
77};
78
79/**
80 * struct v4l2_subdev_frame_size_enum - Media bus format enumeration
81 * @pad: pad number, as reported by the media API
82 * @index: format index during enumeration
83 * @code: format code (from enum v4l2_mbus_pixelcode)
84 */
85struct v4l2_subdev_frame_size_enum {
86 __u32 index;
87 __u32 pad;
88 __u32 code;
89 __u32 min_width;
90 __u32 max_width;
91 __u32 min_height;
92 __u32 max_height;
93 __u32 reserved[9];
94};
95
96/**
97 * struct v4l2_subdev_frame_interval - Pad-level frame rate
98 * @pad: pad number, as reported by the media API
99 * @interval: frame interval in seconds
100 */
101struct v4l2_subdev_frame_interval {
102 __u32 pad;
103 struct v4l2_fract interval;
104 __u32 reserved[9];
105};
106
107/**
108 * struct v4l2_subdev_frame_interval_enum - Frame interval enumeration
109 * @pad: pad number, as reported by the media API
110 * @index: frame interval index during enumeration
111 * @code: format code (from enum v4l2_mbus_pixelcode)
112 * @width: frame width in pixels
113 * @height: frame height in pixels
114 * @interval: frame interval in seconds
115 */
116struct v4l2_subdev_frame_interval_enum {
117 __u32 index;
118 __u32 pad;
119 __u32 code;
120 __u32 width;
121 __u32 height;
122 struct v4l2_fract interval;
123 __u32 reserved[9];
124};
125
126#define VIDIOC_SUBDEV_G_FMT _IOWR('V', 4, struct v4l2_subdev_format)
127#define VIDIOC_SUBDEV_S_FMT _IOWR('V', 5, struct v4l2_subdev_format)
128#define VIDIOC_SUBDEV_G_FRAME_INTERVAL \
129 _IOWR('V', 21, struct v4l2_subdev_frame_interval)
130#define VIDIOC_SUBDEV_S_FRAME_INTERVAL \
131 _IOWR('V', 22, struct v4l2_subdev_frame_interval)
132#define VIDIOC_SUBDEV_ENUM_MBUS_CODE \
133 _IOWR('V', 2, struct v4l2_subdev_mbus_code_enum)
134#define VIDIOC_SUBDEV_ENUM_FRAME_SIZE \
135 _IOWR('V', 74, struct v4l2_subdev_frame_size_enum)
136#define VIDIOC_SUBDEV_ENUM_FRAME_INTERVAL \
137 _IOWR('V', 75, struct v4l2_subdev_frame_interval_enum)
138#define VIDIOC_SUBDEV_G_CROP _IOWR('V', 59, struct v4l2_subdev_crop)
139#define VIDIOC_SUBDEV_S_CROP _IOWR('V', 60, struct v4l2_subdev_crop)
140
141#endif
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 5f6f47044abf..aa6c393b7ae9 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -70,6 +70,7 @@
70 * Moved from videodev.h 70 * Moved from videodev.h
71 */ 71 */
72#define VIDEO_MAX_FRAME 32 72#define VIDEO_MAX_FRAME 32
73#define VIDEO_MAX_PLANES 8
73 74
74#ifndef __KERNEL__ 75#ifndef __KERNEL__
75 76
@@ -157,9 +158,23 @@ enum v4l2_buf_type {
157 /* Experimental */ 158 /* Experimental */
158 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8, 159 V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY = 8,
159#endif 160#endif
161 V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE = 9,
162 V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE = 10,
160 V4L2_BUF_TYPE_PRIVATE = 0x80, 163 V4L2_BUF_TYPE_PRIVATE = 0x80,
161}; 164};
162 165
166#define V4L2_TYPE_IS_MULTIPLANAR(type) \
167 ((type) == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE \
168 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE)
169
170#define V4L2_TYPE_IS_OUTPUT(type) \
171 ((type) == V4L2_BUF_TYPE_VIDEO_OUTPUT \
172 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \
173 || (type) == V4L2_BUF_TYPE_VIDEO_OVERLAY \
174 || (type) == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY \
175 || (type) == V4L2_BUF_TYPE_VBI_OUTPUT \
176 || (type) == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
177
163enum v4l2_tuner_type { 178enum v4l2_tuner_type {
164 V4L2_TUNER_RADIO = 1, 179 V4L2_TUNER_RADIO = 1,
165 V4L2_TUNER_ANALOG_TV = 2, 180 V4L2_TUNER_ANALOG_TV = 2,
@@ -245,6 +260,11 @@ struct v4l2_capability {
245#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */ 260#define V4L2_CAP_HW_FREQ_SEEK 0x00000400 /* Can do hardware frequency seek */
246#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */ 261#define V4L2_CAP_RDS_OUTPUT 0x00000800 /* Is an RDS encoder */
247 262
263/* Is a video capture device that supports multiplanar formats */
264#define V4L2_CAP_VIDEO_CAPTURE_MPLANE 0x00001000
265/* Is a video output device that supports multiplanar formats */
266#define V4L2_CAP_VIDEO_OUTPUT_MPLANE 0x00002000
267
248#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */ 268#define V4L2_CAP_TUNER 0x00010000 /* has a tuner */
249#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */ 269#define V4L2_CAP_AUDIO 0x00020000 /* has audio support */
250#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */ 270#define V4L2_CAP_RADIO 0x00040000 /* is a radio device */
@@ -319,6 +339,13 @@ struct v4l2_pix_format {
319#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */ 339#define V4L2_PIX_FMT_NV16 v4l2_fourcc('N', 'V', '1', '6') /* 16 Y/CbCr 4:2:2 */
320#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */ 340#define V4L2_PIX_FMT_NV61 v4l2_fourcc('N', 'V', '6', '1') /* 16 Y/CrCb 4:2:2 */
321 341
342/* two non contiguous planes - one Y, one Cr + Cb interleaved */
343#define V4L2_PIX_FMT_NV12M v4l2_fourcc('N', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 */
344#define V4L2_PIX_FMT_NV12MT v4l2_fourcc('T', 'M', '1', '2') /* 12 Y/CbCr 4:2:0 64x32 macroblocks */
345
346/* three non contiguous planes - Y, Cb, Cr */
347#define V4L2_PIX_FMT_YUV420M v4l2_fourcc('Y', 'M', '1', '2') /* 12 YUV420 planar */
348
322/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */ 349/* Bayer formats - see http://www.siliconimaging.com/RGB%20Bayer.htm */
323#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */ 350#define V4L2_PIX_FMT_SBGGR8 v4l2_fourcc('B', 'A', '8', '1') /* 8 BGBG.. GRGR.. */
324#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */ 351#define V4L2_PIX_FMT_SGBRG8 v4l2_fourcc('G', 'B', 'R', 'G') /* 8 GBGB.. RGRG.. */
@@ -328,6 +355,10 @@ struct v4l2_pix_format {
328#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */ 355#define V4L2_PIX_FMT_SGBRG10 v4l2_fourcc('G', 'B', '1', '0') /* 10 GBGB.. RGRG.. */
329#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */ 356#define V4L2_PIX_FMT_SGRBG10 v4l2_fourcc('B', 'A', '1', '0') /* 10 GRGR.. BGBG.. */
330#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */ 357#define V4L2_PIX_FMT_SRGGB10 v4l2_fourcc('R', 'G', '1', '0') /* 10 RGRG.. GBGB.. */
358#define V4L2_PIX_FMT_SBGGR12 v4l2_fourcc('B', 'G', '1', '2') /* 12 BGBG.. GRGR.. */
359#define V4L2_PIX_FMT_SGBRG12 v4l2_fourcc('G', 'B', '1', '2') /* 12 GBGB.. RGRG.. */
360#define V4L2_PIX_FMT_SGRBG12 v4l2_fourcc('B', 'A', '1', '2') /* 12 GRGR.. BGBG.. */
361#define V4L2_PIX_FMT_SRGGB12 v4l2_fourcc('R', 'G', '1', '2') /* 12 RGRG.. GBGB.. */
331 /* 10bit raw bayer DPCM compressed to 8 bits */ 362 /* 10bit raw bayer DPCM compressed to 8 bits */
332#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0') 363#define V4L2_PIX_FMT_SGRBG10DPCM8 v4l2_fourcc('B', 'D', '1', '0')
333 /* 364 /*
@@ -365,6 +396,7 @@ struct v4l2_pix_format {
365#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */ 396#define V4L2_PIX_FMT_TM6000 v4l2_fourcc('T', 'M', '6', '0') /* tm5600/tm60x0 */
366#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */ 397#define V4L2_PIX_FMT_CIT_YYVYUY v4l2_fourcc('C', 'I', 'T', 'V') /* one line of Y then 1 line of VYUY */
367#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */ 398#define V4L2_PIX_FMT_KONICA420 v4l2_fourcc('K', 'O', 'N', 'I') /* YUV420 planar in blocks of 256 pixels */
399#define V4L2_PIX_FMT_JPGL v4l2_fourcc('J', 'P', 'G', 'L') /* JPEG-Lite */
368 400
369/* 401/*
370 * F O R M A T E N U M E R A T I O N 402 * F O R M A T E N U M E R A T I O N
@@ -517,6 +549,62 @@ struct v4l2_requestbuffers {
517 __u32 reserved[2]; 549 __u32 reserved[2];
518}; 550};
519 551
552/**
553 * struct v4l2_plane - plane info for multi-planar buffers
554 * @bytesused: number of bytes occupied by data in the plane (payload)
555 * @length: size of this plane (NOT the payload) in bytes
556 * @mem_offset: when memory in the associated struct v4l2_buffer is
557 * V4L2_MEMORY_MMAP, equals the offset from the start of
558 * the device memory for this plane (or is a "cookie" that
559 * should be passed to mmap() called on the video node)
560 * @userptr: when memory is V4L2_MEMORY_USERPTR, a userspace pointer
561 * pointing to this plane
562 * @data_offset: offset in the plane to the start of data; usually 0,
563 * unless there is a header in front of the data
564 *
565 * Multi-planar buffers consist of one or more planes, e.g. an YCbCr buffer
566 * with two planes can have one plane for Y, and another for interleaved CbCr
567 * components. Each plane can reside in a separate memory buffer, or even in
568 * a completely separate memory node (e.g. in embedded devices).
569 */
570struct v4l2_plane {
571 __u32 bytesused;
572 __u32 length;
573 union {
574 __u32 mem_offset;
575 unsigned long userptr;
576 } m;
577 __u32 data_offset;
578 __u32 reserved[11];
579};
580
581/**
582 * struct v4l2_buffer - video buffer info
583 * @index: id number of the buffer
584 * @type: buffer type (type == *_MPLANE for multiplanar buffers)
585 * @bytesused: number of bytes occupied by data in the buffer (payload);
586 * unused (set to 0) for multiplanar buffers
587 * @flags: buffer informational flags
588 * @field: field order of the image in the buffer
589 * @timestamp: frame timestamp
590 * @timecode: frame timecode
591 * @sequence: sequence count of this frame
592 * @memory: the method, in which the actual video data is passed
593 * @offset: for non-multiplanar buffers with memory == V4L2_MEMORY_MMAP;
594 * offset from the start of the device memory for this plane,
595 * (or a "cookie" that should be passed to mmap() as offset)
596 * @userptr: for non-multiplanar buffers with memory == V4L2_MEMORY_USERPTR;
597 * a userspace pointer pointing to this buffer
598 * @planes: for multiplanar buffers; userspace pointer to the array of plane
599 * info structs for this buffer
600 * @length: size in bytes of the buffer (NOT its payload) for single-plane
601 * buffers (when type != *_MPLANE); number of elements in the
602 * planes array for multi-plane buffers
603 * @input: input number from which the video data has has been captured
604 *
605 * Contains data exchanged by application and driver using one of the Streaming
606 * I/O methods.
607 */
520struct v4l2_buffer { 608struct v4l2_buffer {
521 __u32 index; 609 __u32 index;
522 enum v4l2_buf_type type; 610 enum v4l2_buf_type type;
@@ -532,6 +620,7 @@ struct v4l2_buffer {
532 union { 620 union {
533 __u32 offset; 621 __u32 offset;
534 unsigned long userptr; 622 unsigned long userptr;
623 struct v4l2_plane *planes;
535 } m; 624 } m;
536 __u32 length; 625 __u32 length;
537 __u32 input; 626 __u32 input;
@@ -1622,12 +1711,56 @@ struct v4l2_mpeg_vbi_fmt_ivtv {
1622 * A G G R E G A T E S T R U C T U R E S 1711 * A G G R E G A T E S T R U C T U R E S
1623 */ 1712 */
1624 1713
1625/* Stream data format 1714/**
1715 * struct v4l2_plane_pix_format - additional, per-plane format definition
1716 * @sizeimage: maximum size in bytes required for data, for which
1717 * this plane will be used
1718 * @bytesperline: distance in bytes between the leftmost pixels in two
1719 * adjacent lines
1720 */
1721struct v4l2_plane_pix_format {
1722 __u32 sizeimage;
1723 __u16 bytesperline;
1724 __u16 reserved[7];
1725} __attribute__ ((packed));
1726
1727/**
1728 * struct v4l2_pix_format_mplane - multiplanar format definition
1729 * @width: image width in pixels
1730 * @height: image height in pixels
1731 * @pixelformat: little endian four character code (fourcc)
1732 * @field: field order (for interlaced video)
1733 * @colorspace: supplemental to pixelformat
1734 * @plane_fmt: per-plane information
1735 * @num_planes: number of planes for this format
1736 */
1737struct v4l2_pix_format_mplane {
1738 __u32 width;
1739 __u32 height;
1740 __u32 pixelformat;
1741 enum v4l2_field field;
1742 enum v4l2_colorspace colorspace;
1743
1744 struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES];
1745 __u8 num_planes;
1746 __u8 reserved[11];
1747} __attribute__ ((packed));
1748
1749/**
1750 * struct v4l2_format - stream data format
1751 * @type: type of the data stream
1752 * @pix: definition of an image format
1753 * @pix_mp: definition of a multiplanar image format
1754 * @win: definition of an overlaid image
1755 * @vbi: raw VBI capture or output parameters
1756 * @sliced: sliced VBI capture or output parameters
1757 * @raw_data: placeholder for future extensions and custom formats
1626 */ 1758 */
1627struct v4l2_format { 1759struct v4l2_format {
1628 enum v4l2_buf_type type; 1760 enum v4l2_buf_type type;
1629 union { 1761 union {
1630 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */ 1762 struct v4l2_pix_format pix; /* V4L2_BUF_TYPE_VIDEO_CAPTURE */
1763 struct v4l2_pix_format_mplane pix_mp; /* V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE */
1631 struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */ 1764 struct v4l2_window win; /* V4L2_BUF_TYPE_VIDEO_OVERLAY */
1632 struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */ 1765 struct v4l2_vbi_format vbi; /* V4L2_BUF_TYPE_VBI_CAPTURE */
1633 struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */ 1766 struct v4l2_sliced_vbi_format sliced; /* V4L2_BUF_TYPE_SLICED_VBI_CAPTURE */
@@ -1635,7 +1768,6 @@ struct v4l2_format {
1635 } fmt; 1768 } fmt;
1636}; 1769};
1637 1770
1638
1639/* Stream type-dependent parameters 1771/* Stream type-dependent parameters
1640 */ 1772 */
1641struct v4l2_streamparm { 1773struct v4l2_streamparm {
@@ -1808,16 +1940,6 @@ struct v4l2_dbg_chip_ident {
1808/* Reminder: when adding new ioctls please add support for them to 1940/* Reminder: when adding new ioctls please add support for them to
1809 drivers/media/video/v4l2-compat-ioctl32.c as well! */ 1941 drivers/media/video/v4l2-compat-ioctl32.c as well! */
1810 1942
1811#ifdef __OLD_VIDIOC_
1812/* for compatibility, will go away some day */
1813#define VIDIOC_OVERLAY_OLD _IOWR('V', 14, int)
1814#define VIDIOC_S_PARM_OLD _IOW('V', 22, struct v4l2_streamparm)
1815#define VIDIOC_S_CTRL_OLD _IOW('V', 28, struct v4l2_control)
1816#define VIDIOC_G_AUDIO_OLD _IOWR('V', 33, struct v4l2_audio)
1817#define VIDIOC_G_AUDOUT_OLD _IOWR('V', 49, struct v4l2_audioout)
1818#define VIDIOC_CROPCAP_OLD _IOR('V', 58, struct v4l2_cropcap)
1819#endif
1820
1821#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */ 1943#define BASE_VIDIOC_PRIVATE 192 /* 192-255 are private */
1822 1944
1823#endif /* __LINUX_VIDEODEV2_H */ 1945#endif /* __LINUX_VIDEODEV2_H */
diff --git a/include/media/media-device.h b/include/media/media-device.h
new file mode 100644
index 000000000000..6a27d916c250
--- /dev/null
+++ b/include/media/media-device.h
@@ -0,0 +1,95 @@
1/*
2 * Media device
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _MEDIA_DEVICE_H
24#define _MEDIA_DEVICE_H
25
26#include <linux/device.h>
27#include <linux/list.h>
28#include <linux/mutex.h>
29#include <linux/spinlock.h>
30
31#include <media/media-devnode.h>
32#include <media/media-entity.h>
33
34/**
35 * struct media_device - Media device
36 * @dev: Parent device
37 * @devnode: Media device node
38 * @model: Device model name
39 * @serial: Device serial number (optional)
40 * @bus_info: Unique and stable device location identifier
41 * @hw_revision: Hardware device revision
42 * @driver_version: Device driver version
43 * @entity_id: ID of the next entity to be registered
44 * @entities: List of registered entities
45 * @lock: Entities list lock
46 * @graph_mutex: Entities graph operation lock
47 *
48 * This structure represents an abstract high-level media device. It allows easy
49 * access to entities and provides basic media device-level support. The
50 * structure can be allocated directly or embedded in a larger structure.
51 *
52 * The parent @dev is a physical device. It must be set before registering the
53 * media device.
54 *
55 * @model is a descriptive model name exported through sysfs. It doesn't have to
56 * be unique.
57 */
58struct media_device {
59 /* dev->driver_data points to this struct. */
60 struct device *dev;
61 struct media_devnode devnode;
62
63 char model[32];
64 char serial[40];
65 char bus_info[32];
66 u32 hw_revision;
67 u32 driver_version;
68
69 u32 entity_id;
70 struct list_head entities;
71
72 /* Protects the entities list */
73 spinlock_t lock;
74 /* Serializes graph operations. */
75 struct mutex graph_mutex;
76
77 int (*link_notify)(struct media_pad *source,
78 struct media_pad *sink, u32 flags);
79};
80
81/* media_devnode to media_device */
82#define to_media_device(node) container_of(node, struct media_device, devnode)
83
84int __must_check media_device_register(struct media_device *mdev);
85void media_device_unregister(struct media_device *mdev);
86
87int __must_check media_device_register_entity(struct media_device *mdev,
88 struct media_entity *entity);
89void media_device_unregister_entity(struct media_entity *entity);
90
91/* Iterate over all entities. */
92#define media_device_for_each_entity(entity, mdev) \
93 list_for_each_entry(entity, &(mdev)->entities, list)
94
95#endif
diff --git a/include/media/media-devnode.h b/include/media/media-devnode.h
new file mode 100644
index 000000000000..f6caafc874cb
--- /dev/null
+++ b/include/media/media-devnode.h
@@ -0,0 +1,97 @@
1/*
2 * Media device node
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * --
23 *
24 * Common functions for media-related drivers to register and unregister media
25 * device nodes.
26 */
27
28#ifndef _MEDIA_DEVNODE_H
29#define _MEDIA_DEVNODE_H
30
31#include <linux/poll.h>
32#include <linux/fs.h>
33#include <linux/device.h>
34#include <linux/cdev.h>
35
36/*
37 * Flag to mark the media_devnode struct as registered. Drivers must not touch
38 * this flag directly, it will be set and cleared by media_devnode_register and
39 * media_devnode_unregister.
40 */
41#define MEDIA_FLAG_REGISTERED 0
42
43struct media_file_operations {
44 struct module *owner;
45 ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
46 ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
47 unsigned int (*poll) (struct file *, struct poll_table_struct *);
48 long (*ioctl) (struct file *, unsigned int, unsigned long);
49 int (*open) (struct file *);
50 int (*release) (struct file *);
51};
52
53/**
54 * struct media_devnode - Media device node
55 * @parent: parent device
56 * @minor: device node minor number
57 * @flags: flags, combination of the MEDIA_FLAG_* constants
58 *
59 * This structure represents a media-related device node.
60 *
61 * The @parent is a physical device. It must be set by core or device drivers
62 * before registering the node.
63 */
64struct media_devnode {
65 /* device ops */
66 const struct media_file_operations *fops;
67
68 /* sysfs */
69 struct device dev; /* media device */
70 struct cdev cdev; /* character device */
71 struct device *parent; /* device parent */
72
73 /* device info */
74 int minor;
75 unsigned long flags; /* Use bitops to access flags */
76
77 /* callbacks */
78 void (*release)(struct media_devnode *mdev);
79};
80
81/* dev to media_devnode */
82#define to_media_devnode(cd) container_of(cd, struct media_devnode, dev)
83
84int __must_check media_devnode_register(struct media_devnode *mdev);
85void media_devnode_unregister(struct media_devnode *mdev);
86
87static inline struct media_devnode *media_devnode_data(struct file *filp)
88{
89 return filp->private_data;
90}
91
92static inline int media_devnode_is_registered(struct media_devnode *mdev)
93{
94 return test_bit(MEDIA_FLAG_REGISTERED, &mdev->flags);
95}
96
97#endif /* _MEDIA_DEVNODE_H */
diff --git a/include/media/media-entity.h b/include/media/media-entity.h
new file mode 100644
index 000000000000..cd8bca63a502
--- /dev/null
+++ b/include/media/media-entity.h
@@ -0,0 +1,151 @@
1/*
2 * Media entity
3 *
4 * Copyright (C) 2010 Nokia Corporation
5 *
6 * Contacts: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
7 * Sakari Ailus <sakari.ailus@iki.fi>
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 version 2 as
11 * published by the Free Software Foundation.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#ifndef _MEDIA_ENTITY_H
24#define _MEDIA_ENTITY_H
25
26#include <linux/list.h>
27#include <linux/media.h>
28
29struct media_pipeline {
30};
31
32struct media_link {
33 struct media_pad *source; /* Source pad */
34 struct media_pad *sink; /* Sink pad */
35 struct media_link *reverse; /* Link in the reverse direction */
36 unsigned long flags; /* Link flags (MEDIA_LNK_FL_*) */
37};
38
39struct media_pad {
40 struct media_entity *entity; /* Entity this pad belongs to */
41 u16 index; /* Pad index in the entity pads array */
42 unsigned long flags; /* Pad flags (MEDIA_PAD_FL_*) */
43};
44
45struct media_entity_operations {
46 int (*link_setup)(struct media_entity *entity,
47 const struct media_pad *local,
48 const struct media_pad *remote, u32 flags);
49};
50
51struct media_entity {
52 struct list_head list;
53 struct media_device *parent; /* Media device this entity belongs to*/
54 u32 id; /* Entity ID, unique in the parent media
55 * device context */
56 const char *name; /* Entity name */
57 u32 type; /* Entity type (MEDIA_ENT_T_*) */
58 u32 revision; /* Entity revision, driver specific */
59 unsigned long flags; /* Entity flags (MEDIA_ENT_FL_*) */
60 u32 group_id; /* Entity group ID */
61
62 u16 num_pads; /* Number of sink and source pads */
63 u16 num_links; /* Number of existing links, both
64 * enabled and disabled */
65 u16 num_backlinks; /* Number of backlinks */
66 u16 max_links; /* Maximum number of links */
67
68 struct media_pad *pads; /* Pads array (num_pads elements) */
69 struct media_link *links; /* Links array (max_links elements)*/
70
71 const struct media_entity_operations *ops; /* Entity operations */
72
73 /* Reference counts must never be negative, but are signed integers on
74 * purpose: a simple WARN_ON(<0) check can be used to detect reference
75 * count bugs that would make them negative.
76 */
77 int stream_count; /* Stream count for the entity. */
78 int use_count; /* Use count for the entity. */
79
80 struct media_pipeline *pipe; /* Pipeline this entity belongs to. */
81
82 union {
83 /* Node specifications */
84 struct {
85 u32 major;
86 u32 minor;
87 } v4l;
88 struct {
89 u32 major;
90 u32 minor;
91 } fb;
92 struct {
93 u32 card;
94 u32 device;
95 u32 subdevice;
96 } alsa;
97 int dvb;
98
99 /* Sub-device specifications */
100 /* Nothing needed yet */
101 };
102};
103
104static inline u32 media_entity_type(struct media_entity *entity)
105{
106 return entity->type & MEDIA_ENT_TYPE_MASK;
107}
108
109static inline u32 media_entity_subtype(struct media_entity *entity)
110{
111 return entity->type & MEDIA_ENT_SUBTYPE_MASK;
112}
113
114#define MEDIA_ENTITY_ENUM_MAX_DEPTH 16
115
116struct media_entity_graph {
117 struct {
118 struct media_entity *entity;
119 int link;
120 } stack[MEDIA_ENTITY_ENUM_MAX_DEPTH];
121 int top;
122};
123
124int media_entity_init(struct media_entity *entity, u16 num_pads,
125 struct media_pad *pads, u16 extra_links);
126void media_entity_cleanup(struct media_entity *entity);
127
128int media_entity_create_link(struct media_entity *source, u16 source_pad,
129 struct media_entity *sink, u16 sink_pad, u32 flags);
130int __media_entity_setup_link(struct media_link *link, u32 flags);
131int media_entity_setup_link(struct media_link *link, u32 flags);
132struct media_link *media_entity_find_link(struct media_pad *source,
133 struct media_pad *sink);
134struct media_pad *media_entity_remote_source(struct media_pad *pad);
135
136struct media_entity *media_entity_get(struct media_entity *entity);
137void media_entity_put(struct media_entity *entity);
138
139void media_entity_graph_walk_start(struct media_entity_graph *graph,
140 struct media_entity *entity);
141struct media_entity *
142media_entity_graph_walk_next(struct media_entity_graph *graph);
143void media_entity_pipeline_start(struct media_entity *entity,
144 struct media_pipeline *pipe);
145void media_entity_pipeline_stop(struct media_entity *entity);
146
147#define media_entity_call(entity, operation, args...) \
148 (((entity)->ops && (entity)->ops->operation) ? \
149 (entity)->ops->operation((entity) , ##args) : -ENOIOCTLCMD)
150
151#endif
diff --git a/include/media/noon010pc30.h b/include/media/noon010pc30.h
new file mode 100644
index 000000000000..58eafee36b30
--- /dev/null
+++ b/include/media/noon010pc30.h
@@ -0,0 +1,28 @@
1/*
2 * Driver header for NOON010PC30L camera sensor chip.
3 *
4 * Copyright (c) 2010 Samsung Electronics, Co. Ltd
5 * Contact: Sylwester Nawrocki <s.nawrocki@samsung.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
13#ifndef NOON010PC30_H
14#define NOON010PC30_H
15
16/**
17 * @clk_rate: the clock frequency in Hz
18 * @gpio_nreset: GPIO driving nRESET pin
19 * @gpio_nstby: GPIO driving nSTBY pin
20 */
21
22struct noon010pc30_platform_data {
23 unsigned long clk_rate;
24 int gpio_nreset;
25 int gpio_nstby;
26};
27
28#endif /* NOON010PC30_H */
diff --git a/include/media/rc-map.h b/include/media/rc-map.h
index ee9e2f747c76..9184751f19c0 100644
--- a/include/media/rc-map.h
+++ b/include/media/rc-map.h
@@ -94,7 +94,7 @@ void rc_map_init(void);
94#define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z" 94#define RC_MAP_GADMEI_RM008Z "rc-gadmei-rm008z"
95#define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce" 95#define RC_MAP_GENIUS_TVGO_A11MCE "rc-genius-tvgo-a11mce"
96#define RC_MAP_GOTVIEW7135 "rc-gotview7135" 96#define RC_MAP_GOTVIEW7135 "rc-gotview7135"
97#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge-new" 97#define RC_MAP_HAUPPAUGE_NEW "rc-hauppauge"
98#define RC_MAP_IMON_MCE "rc-imon-mce" 98#define RC_MAP_IMON_MCE "rc-imon-mce"
99#define RC_MAP_IMON_PAD "rc-imon-pad" 99#define RC_MAP_IMON_PAD "rc-imon-pad"
100#define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e" 100#define RC_MAP_IODATA_BCTV7E "rc-iodata-bctv7e"
@@ -125,14 +125,16 @@ void rc_map_init(void);
125#define RC_MAP_PROTEUS_2309 "rc-proteus-2309" 125#define RC_MAP_PROTEUS_2309 "rc-proteus-2309"
126#define RC_MAP_PURPLETV "rc-purpletv" 126#define RC_MAP_PURPLETV "rc-purpletv"
127#define RC_MAP_PV951 "rc-pv951" 127#define RC_MAP_PV951 "rc-pv951"
128#define RC_MAP_RC5_HAUPPAUGE_NEW "rc-rc5-hauppauge-new" 128#define RC_MAP_HAUPPAUGE "rc-hauppauge"
129#define RC_MAP_RC5_TV "rc-rc5-tv" 129#define RC_MAP_RC5_TV "rc-rc5-tv"
130#define RC_MAP_RC6_MCE "rc-rc6-mce" 130#define RC_MAP_RC6_MCE "rc-rc6-mce"
131#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys" 131#define RC_MAP_REAL_AUDIO_220_32_KEYS "rc-real-audio-220-32-keys"
132#define RC_MAP_STREAMZAP "rc-streamzap" 132#define RC_MAP_STREAMZAP "rc-streamzap"
133#define RC_MAP_TBS_NEC "rc-tbs-nec" 133#define RC_MAP_TBS_NEC "rc-tbs-nec"
134#define RC_MAP_TECHNISAT_USB2 "rc-technisat-usb2"
134#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs" 135#define RC_MAP_TERRATEC_CINERGY_XS "rc-terratec-cinergy-xs"
135#define RC_MAP_TERRATEC_SLIM "rc-terratec-slim" 136#define RC_MAP_TERRATEC_SLIM "rc-terratec-slim"
137#define RC_MAP_TERRATEC_SLIM_2 "rc-terratec-slim-2"
136#define RC_MAP_TEVII_NEC "rc-tevii-nec" 138#define RC_MAP_TEVII_NEC "rc-tevii-nec"
137#define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand" 139#define RC_MAP_TOTAL_MEDIA_IN_HAND "rc-total-media-in-hand"
138#define RC_MAP_TREKSTOR "rc-trekstor" 140#define RC_MAP_TREKSTOR "rc-trekstor"
diff --git a/include/media/s3c_fimc.h b/include/media/s5p_fimc.h
index ca1b6738e4a4..9fdff8a4ed26 100644
--- a/include/media/s3c_fimc.h
+++ b/include/media/s5p_fimc.h
@@ -9,8 +9,8 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 */ 10 */
11 11
12#ifndef S3C_FIMC_H_ 12#ifndef S5P_FIMC_H_
13#define S3C_FIMC_H_ 13#define S5P_FIMC_H_
14 14
15enum cam_bus_type { 15enum cam_bus_type {
16 FIMC_ITU_601 = 1, 16 FIMC_ITU_601 = 1,
@@ -27,34 +27,35 @@ enum cam_bus_type {
27struct i2c_board_info; 27struct i2c_board_info;
28 28
29/** 29/**
30 * struct s3c_fimc_isp_info - image sensor information required for host 30 * struct s5p_fimc_isp_info - image sensor information required for host
31 * interace configuration. 31 * interace configuration.
32 * 32 *
33 * @board_info: pointer to I2C subdevice's board info 33 * @board_info: pointer to I2C subdevice's board info
34 * @clk_frequency: frequency of the clock the host interface provides to sensor
34 * @bus_type: determines bus type, MIPI, ITU-R BT.601 etc. 35 * @bus_type: determines bus type, MIPI, ITU-R BT.601 etc.
36 * @csi_data_align: MIPI-CSI interface data alignment in bits
35 * @i2c_bus_num: i2c control bus id the sensor is attached to 37 * @i2c_bus_num: i2c control bus id the sensor is attached to
36 * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU) 38 * @mux_id: FIMC camera interface multiplexer index (separate for MIPI and ITU)
37 * @bus_width: camera data bus width in bits
38 * @flags: flags defining bus signals polarity inversion (High by default) 39 * @flags: flags defining bus signals polarity inversion (High by default)
39 */ 40 */
40struct s3c_fimc_isp_info { 41struct s5p_fimc_isp_info {
41 struct i2c_board_info *board_info; 42 struct i2c_board_info *board_info;
43 unsigned long clk_frequency;
42 enum cam_bus_type bus_type; 44 enum cam_bus_type bus_type;
45 u16 csi_data_align;
43 u16 i2c_bus_num; 46 u16 i2c_bus_num;
44 u16 mux_id; 47 u16 mux_id;
45 u16 bus_width;
46 u16 flags; 48 u16 flags;
47}; 49};
48 50
49
50#define FIMC_MAX_CAMIF_CLIENTS 2
51
52/** 51/**
53 * struct s3c_platform_fimc - camera host interface platform data 52 * struct s5p_platform_fimc - camera host interface platform data
54 * 53 *
55 * @isp_info: properties of camera sensor required for host interface setup 54 * @isp_info: properties of camera sensor required for host interface setup
55 * @num_clients: the number of attached image sensors
56 */ 56 */
57struct s3c_platform_fimc { 57struct s5p_platform_fimc {
58 struct s3c_fimc_isp_info *isp_info[FIMC_MAX_CAMIF_CLIENTS]; 58 struct s5p_fimc_isp_info *isp_info;
59 int num_clients;
59}; 60};
60#endif /* S3C_FIMC_H_ */ 61#endif /* S5P_FIMC_H_ */
diff --git a/include/media/soc_camera.h b/include/media/soc_camera.h
index 9386db829fb7..f80b5372baf3 100644
--- a/include/media/soc_camera.h
+++ b/include/media/soc_camera.h
@@ -17,6 +17,7 @@
17#include <linux/pm.h> 17#include <linux/pm.h>
18#include <linux/videodev2.h> 18#include <linux/videodev2.h>
19#include <media/videobuf-core.h> 19#include <media/videobuf-core.h>
20#include <media/videobuf2-core.h>
20#include <media/v4l2-device.h> 21#include <media/v4l2-device.h>
21 22
22extern struct bus_type soc_camera_bus_type; 23extern struct bus_type soc_camera_bus_type;
@@ -29,6 +30,8 @@ struct soc_camera_device {
29 struct device *pdev; /* Platform device */ 30 struct device *pdev; /* Platform device */
30 s32 user_width; 31 s32 user_width;
31 s32 user_height; 32 s32 user_height;
33 u32 bytesperline; /* for padding, zero if unused */
34 u32 sizeimage;
32 enum v4l2_colorspace colorspace; 35 enum v4l2_colorspace colorspace;
33 unsigned char iface; /* Host number */ 36 unsigned char iface; /* Host number */
34 unsigned char devnum; /* Device number per host */ 37 unsigned char devnum; /* Device number per host */
@@ -44,7 +47,10 @@ struct soc_camera_device {
44 int use_count; 47 int use_count;
45 struct mutex video_lock; /* Protects device data */ 48 struct mutex video_lock; /* Protects device data */
46 struct file *streamer; /* stream owner */ 49 struct file *streamer; /* stream owner */
47 struct videobuf_queue vb_vidq; 50 union {
51 struct videobuf_queue vb_vidq;
52 struct vb2_queue vb2_vidq;
53 };
48}; 54};
49 55
50struct soc_camera_host { 56struct soc_camera_host {
@@ -78,6 +84,8 @@ struct soc_camera_host_ops {
78 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *); 84 int (*try_fmt)(struct soc_camera_device *, struct v4l2_format *);
79 void (*init_videobuf)(struct videobuf_queue *, 85 void (*init_videobuf)(struct videobuf_queue *,
80 struct soc_camera_device *); 86 struct soc_camera_device *);
87 int (*init_videobuf2)(struct vb2_queue *,
88 struct soc_camera_device *);
81 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *); 89 int (*reqbufs)(struct soc_camera_device *, struct v4l2_requestbuffers *);
82 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *); 90 int (*querycap)(struct soc_camera_host *, struct v4l2_capability *);
83 int (*set_bus_param)(struct soc_camera_device *, __u32); 91 int (*set_bus_param)(struct soc_camera_device *, __u32);
@@ -85,6 +93,7 @@ struct soc_camera_host_ops {
85 int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *); 93 int (*set_ctrl)(struct soc_camera_device *, struct v4l2_control *);
86 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 94 int (*get_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
87 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *); 95 int (*set_parm)(struct soc_camera_device *, struct v4l2_streamparm *);
96 int (*enum_fsizes)(struct soc_camera_device *, struct v4l2_frmsizeenum *);
88 unsigned int (*poll)(struct file *, poll_table *); 97 unsigned int (*poll)(struct file *, poll_table *);
89 const struct v4l2_queryctrl *controls; 98 const struct v4l2_queryctrl *controls;
90 int num_controls; 99 int num_controls;
@@ -299,4 +308,17 @@ static inline struct video_device *soc_camera_i2c_to_vdev(struct i2c_client *cli
299 return icd->vdev; 308 return icd->vdev;
300} 309}
301 310
311static inline struct soc_camera_device *soc_camera_from_vb2q(struct vb2_queue *vq)
312{
313 return container_of(vq, struct soc_camera_device, vb2_vidq);
314}
315
316static inline struct soc_camera_device *soc_camera_from_vbq(struct videobuf_queue *vq)
317{
318 return container_of(vq, struct soc_camera_device, vb_vidq);
319}
320
321void soc_camera_lock(struct vb2_queue *vq);
322void soc_camera_unlock(struct vb2_queue *vq);
323
302#endif 324#endif
diff --git a/include/media/soc_mediabus.h b/include/media/soc_mediabus.h
index 037cd7be001e..b338108ec305 100644
--- a/include/media/soc_mediabus.h
+++ b/include/media/soc_mediabus.h
@@ -12,8 +12,7 @@
12#define SOC_MEDIABUS_H 12#define SOC_MEDIABUS_H
13 13
14#include <linux/videodev2.h> 14#include <linux/videodev2.h>
15 15#include <linux/v4l2-mediabus.h>
16#include <media/v4l2-mediabus.h>
17 16
18/** 17/**
19 * enum soc_mbus_packing - data packing types on the media-bus 18 * enum soc_mbus_packing - data packing types on the media-bus
@@ -61,5 +60,6 @@ struct soc_mbus_pixelfmt {
61const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc( 60const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
62 enum v4l2_mbus_pixelcode code); 61 enum v4l2_mbus_pixelcode code);
63s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf); 62s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf);
63int soc_mbus_samples_per_pixel(const struct soc_mbus_pixelfmt *mf);
64 64
65#endif 65#endif
diff --git a/include/media/tuner.h b/include/media/tuner.h
index 51811eac46f1..963e33471835 100644
--- a/include/media/tuner.h
+++ b/include/media/tuner.h
@@ -21,6 +21,7 @@
21 21
22#ifndef _TUNER_H 22#ifndef _TUNER_H
23#define _TUNER_H 23#define _TUNER_H
24#ifdef __KERNEL__
24 25
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26 27
@@ -131,6 +132,7 @@
131#define TUNER_NXP_TDA18271 83 132#define TUNER_NXP_TDA18271 83
132#define TUNER_SONY_BTF_PXN01Z 84 133#define TUNER_SONY_BTF_PXN01Z 84
133#define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */ 134#define TUNER_PHILIPS_FQ1236_MK5 85 /* NTSC, TDA9885, no FM radio */
135#define TUNER_TENA_TNF_5337 86
134 136
135/* tv card specific */ 137/* tv card specific */
136#define TDA9887_PRESENT (1<<0) 138#define TDA9887_PRESENT (1<<0)
@@ -156,14 +158,10 @@
156#define TDA9887_GAIN_NORMAL (1<<20) 158#define TDA9887_GAIN_NORMAL (1<<20)
157#define TDA9887_RIF_41_3 (1<<21) /* radio IF1 41.3 vs 33.3 */ 159#define TDA9887_RIF_41_3 (1<<21) /* radio IF1 41.3 vs 33.3 */
158 160
159#ifdef __KERNEL__
160
161enum tuner_mode { 161enum tuner_mode {
162 T_UNINITIALIZED = 0,
163 T_RADIO = 1 << V4L2_TUNER_RADIO, 162 T_RADIO = 1 << V4L2_TUNER_RADIO,
164 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV, 163 T_ANALOG_TV = 1 << V4L2_TUNER_ANALOG_TV,
165 T_DIGITAL_TV = 1 << V4L2_TUNER_DIGITAL_TV, 164 /* Don't need to map V4L2_TUNER_DIGITAL_TV, as tuner-core won't use it */
166 T_STANDBY = 1 << 31
167}; 165};
168 166
169/* Older boards only had a single tuner device. Nowadays multiple tuner 167/* Older boards only had a single tuner device. Nowadays multiple tuner
@@ -193,11 +191,3 @@ struct tuner_setup {
193#endif /* __KERNEL__ */ 191#endif /* __KERNEL__ */
194 192
195#endif /* _TUNER_H */ 193#endif /* _TUNER_H */
196
197/*
198 * Overrides for Emacs so that we follow Linus's tabbing style.
199 * ---------------------------------------------------------------------------
200 * Local variables:
201 * c-basic-offset: 8
202 * End:
203 */
diff --git a/include/media/v4l2-chip-ident.h b/include/media/v4l2-chip-ident.h
index 44fe44ec9ea7..b3edb67a8311 100644
--- a/include/media/v4l2-chip-ident.h
+++ b/include/media/v4l2-chip-ident.h
@@ -75,6 +75,7 @@ enum {
75 V4L2_IDENT_OV9640 = 257, 75 V4L2_IDENT_OV9640 = 257,
76 V4L2_IDENT_OV6650 = 258, 76 V4L2_IDENT_OV6650 = 258,
77 V4L2_IDENT_OV2640 = 259, 77 V4L2_IDENT_OV2640 = 259,
78 V4L2_IDENT_OV9740 = 260,
78 79
79 /* module saa7146: reserved range 300-309 */ 80 /* module saa7146: reserved range 300-309 */
80 V4L2_IDENT_SAA7146 = 300, 81 V4L2_IDENT_SAA7146 = 300,
@@ -209,6 +210,9 @@ enum {
209 /* module sn9c20x: just ident 10000 */ 210 /* module sn9c20x: just ident 10000 */
210 V4L2_IDENT_SN9C20X = 10000, 211 V4L2_IDENT_SN9C20X = 10000,
211 212
213 /* Siliconfile sensors: reserved range 10100 - 10199 */
214 V4L2_IDENT_NOON010PC30 = 10100,
215
212 /* module cx231xx and cx25840 */ 216 /* module cx231xx and cx25840 */
213 V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */ 217 V4L2_IDENT_CX2310X_AV = 23099, /* Integrated A/V decoder; not in '100 */
214 V4L2_IDENT_CX23100 = 23100, 218 V4L2_IDENT_CX23100 = 23100,
diff --git a/include/media/v4l2-common.h b/include/media/v4l2-common.h
index a659319e8582..a298ec49ddc4 100644
--- a/include/media/v4l2-common.h
+++ b/include/media/v4l2-common.h
@@ -80,21 +80,6 @@
80 80
81/* ------------------------------------------------------------------------- */ 81/* ------------------------------------------------------------------------- */
82 82
83/* Priority helper functions */
84
85struct v4l2_prio_state {
86 atomic_t prios[4];
87};
88void v4l2_prio_init(struct v4l2_prio_state *global);
89int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
90 enum v4l2_priority new);
91void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
92void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
93enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
94int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
95
96/* ------------------------------------------------------------------------- */
97
98/* Control helper functions */ 83/* Control helper functions */
99 84
100int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl, 85int v4l2_ctrl_check(struct v4l2_ext_control *ctrl, struct v4l2_queryctrl *qctrl,
diff --git a/include/media/v4l2-dev.h b/include/media/v4l2-dev.h
index 15802a067a12..8266d5ade2ff 100644
--- a/include/media/v4l2-dev.h
+++ b/include/media/v4l2-dev.h
@@ -16,12 +16,15 @@
16#include <linux/mutex.h> 16#include <linux/mutex.h>
17#include <linux/videodev2.h> 17#include <linux/videodev2.h>
18 18
19#include <media/media-entity.h>
20
19#define VIDEO_MAJOR 81 21#define VIDEO_MAJOR 81
20 22
21#define VFL_TYPE_GRABBER 0 23#define VFL_TYPE_GRABBER 0
22#define VFL_TYPE_VBI 1 24#define VFL_TYPE_VBI 1
23#define VFL_TYPE_RADIO 2 25#define VFL_TYPE_RADIO 2
24#define VFL_TYPE_MAX 3 26#define VFL_TYPE_SUBDEV 3
27#define VFL_TYPE_MAX 4
25 28
26struct v4l2_ioctl_callbacks; 29struct v4l2_ioctl_callbacks;
27struct video_device; 30struct video_device;
@@ -32,7 +35,25 @@ struct v4l2_ctrl_handler;
32 Drivers can clear this flag if they want to block all future 35 Drivers can clear this flag if they want to block all future
33 device access. It is cleared by video_unregister_device. */ 36 device access. It is cleared by video_unregister_device. */
34#define V4L2_FL_REGISTERED (0) 37#define V4L2_FL_REGISTERED (0)
38/* file->private_data points to struct v4l2_fh */
35#define V4L2_FL_USES_V4L2_FH (1) 39#define V4L2_FL_USES_V4L2_FH (1)
40/* Use the prio field of v4l2_fh for core priority checking */
41#define V4L2_FL_USE_FH_PRIO (2)
42
43/* Priority helper functions */
44
45struct v4l2_prio_state {
46 atomic_t prios[4];
47};
48
49void v4l2_prio_init(struct v4l2_prio_state *global);
50int v4l2_prio_change(struct v4l2_prio_state *global, enum v4l2_priority *local,
51 enum v4l2_priority new);
52void v4l2_prio_open(struct v4l2_prio_state *global, enum v4l2_priority *local);
53void v4l2_prio_close(struct v4l2_prio_state *global, enum v4l2_priority local);
54enum v4l2_priority v4l2_prio_max(struct v4l2_prio_state *global);
55int v4l2_prio_check(struct v4l2_prio_state *global, enum v4l2_priority local);
56
36 57
37struct v4l2_file_operations { 58struct v4l2_file_operations {
38 struct module *owner; 59 struct module *owner;
@@ -54,6 +75,9 @@ struct v4l2_file_operations {
54 75
55struct video_device 76struct video_device
56{ 77{
78#if defined(CONFIG_MEDIA_CONTROLLER)
79 struct media_entity entity;
80#endif
57 /* device ops */ 81 /* device ops */
58 const struct v4l2_file_operations *fops; 82 const struct v4l2_file_operations *fops;
59 83
@@ -68,6 +92,9 @@ struct video_device
68 /* Control handler associated with this device node. May be NULL. */ 92 /* Control handler associated with this device node. May be NULL. */
69 struct v4l2_ctrl_handler *ctrl_handler; 93 struct v4l2_ctrl_handler *ctrl_handler;
70 94
95 /* Priority state. If NULL, then v4l2_dev->prio will be used. */
96 struct v4l2_prio_state *prio;
97
71 /* device info */ 98 /* device info */
72 char name[32]; 99 char name[32];
73 int vfl_type; 100 int vfl_type;
@@ -99,18 +126,31 @@ struct video_device
99 struct mutex *lock; 126 struct mutex *lock;
100}; 127};
101 128
129#define media_entity_to_video_device(entity) \
130 container_of(entity, struct video_device, entity)
102/* dev to video-device */ 131/* dev to video-device */
103#define to_video_device(cd) container_of(cd, struct video_device, dev) 132#define to_video_device(cd) container_of(cd, struct video_device, dev)
104 133
134int __must_check __video_register_device(struct video_device *vdev, int type,
135 int nr, int warn_if_nr_in_use, struct module *owner);
136
105/* Register video devices. Note that if video_register_device fails, 137/* Register video devices. Note that if video_register_device fails,
106 the release() callback of the video_device structure is *not* called, so 138 the release() callback of the video_device structure is *not* called, so
107 the caller is responsible for freeing any data. Usually that means that 139 the caller is responsible for freeing any data. Usually that means that
108 you call video_device_release() on failure. */ 140 you call video_device_release() on failure. */
109int __must_check video_register_device(struct video_device *vdev, int type, int nr); 141static inline int __must_check video_register_device(struct video_device *vdev,
142 int type, int nr)
143{
144 return __video_register_device(vdev, type, nr, 1, vdev->fops->owner);
145}
110 146
111/* Same as video_register_device, but no warning is issued if the desired 147/* Same as video_register_device, but no warning is issued if the desired
112 device node number was already in use. */ 148 device node number was already in use. */
113int __must_check video_register_device_no_warn(struct video_device *vdev, int type, int nr); 149static inline int __must_check video_register_device_no_warn(
150 struct video_device *vdev, int type, int nr)
151{
152 return __video_register_device(vdev, type, nr, 0, vdev->fops->owner);
153}
114 154
115/* Unregister video devices. Will do nothing if vdev == NULL or 155/* Unregister video devices. Will do nothing if vdev == NULL or
116 video_is_registered() returns false. */ 156 video_is_registered() returns false. */
diff --git a/include/media/v4l2-device.h b/include/media/v4l2-device.h
index b16f307d471a..bd102cf509ac 100644
--- a/include/media/v4l2-device.h
+++ b/include/media/v4l2-device.h
@@ -21,7 +21,9 @@
21#ifndef _V4L2_DEVICE_H 21#ifndef _V4L2_DEVICE_H
22#define _V4L2_DEVICE_H 22#define _V4L2_DEVICE_H
23 23
24#include <media/media-device.h>
24#include <media/v4l2-subdev.h> 25#include <media/v4l2-subdev.h>
26#include <media/v4l2-dev.h>
25 27
26/* Each instance of a V4L2 device should create the v4l2_device struct, 28/* Each instance of a V4L2 device should create the v4l2_device struct,
27 either stand-alone or embedded in a larger struct. 29 either stand-alone or embedded in a larger struct.
@@ -39,6 +41,9 @@ struct v4l2_device {
39 Note: dev might be NULL if there is no parent device 41 Note: dev might be NULL if there is no parent device
40 as is the case with e.g. ISA devices. */ 42 as is the case with e.g. ISA devices. */
41 struct device *dev; 43 struct device *dev;
44#if defined(CONFIG_MEDIA_CONTROLLER)
45 struct media_device *mdev;
46#endif
42 /* used to keep track of the registered subdevs */ 47 /* used to keep track of the registered subdevs */
43 struct list_head subdevs; 48 struct list_head subdevs;
44 /* lock this struct; can be used by the driver as well if this 49 /* lock this struct; can be used by the driver as well if this
@@ -51,10 +56,23 @@ struct v4l2_device {
51 unsigned int notification, void *arg); 56 unsigned int notification, void *arg);
52 /* The control handler. May be NULL. */ 57 /* The control handler. May be NULL. */
53 struct v4l2_ctrl_handler *ctrl_handler; 58 struct v4l2_ctrl_handler *ctrl_handler;
59 /* Device's priority state */
60 struct v4l2_prio_state prio;
54 /* BKL replacement mutex. Temporary solution only. */ 61 /* BKL replacement mutex. Temporary solution only. */
55 struct mutex ioctl_lock; 62 struct mutex ioctl_lock;
63 /* Keep track of the references to this struct. */
64 struct kref ref;
65 /* Release function that is called when the ref count goes to 0. */
66 void (*release)(struct v4l2_device *v4l2_dev);
56}; 67};
57 68
69static inline void v4l2_device_get(struct v4l2_device *v4l2_dev)
70{
71 kref_get(&v4l2_dev->ref);
72}
73
74int v4l2_device_put(struct v4l2_device *v4l2_dev);
75
58/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev. 76/* Initialize v4l2_dev and make dev->driver_data point to v4l2_dev.
59 dev may be NULL in rare cases (ISA devices). In that case you 77 dev may be NULL in rare cases (ISA devices). In that case you
60 must fill in the v4l2_dev->name field before calling this function. */ 78 must fill in the v4l2_dev->name field before calling this function. */
@@ -96,6 +114,12 @@ int __must_check v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
96 wasn't registered. In that case it will do nothing. */ 114 wasn't registered. In that case it will do nothing. */
97void v4l2_device_unregister_subdev(struct v4l2_subdev *sd); 115void v4l2_device_unregister_subdev(struct v4l2_subdev *sd);
98 116
117/* Register device nodes for all subdev of the v4l2 device that are marked with
118 * the V4L2_SUBDEV_FL_HAS_DEVNODE flag.
119 */
120int __must_check
121v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
122
99/* Iterate over all subdevs. */ 123/* Iterate over all subdevs. */
100#define v4l2_device_for_each_subdev(sd, v4l2_dev) \ 124#define v4l2_device_for_each_subdev(sd, v4l2_dev) \
101 list_for_each_entry(sd, &(v4l2_dev)->subdevs, list) 125 list_for_each_entry(sd, &(v4l2_dev)->subdevs, list)
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index 1d72dde320bf..0206aa55be24 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -35,6 +35,7 @@ struct v4l2_fh {
35 struct list_head list; 35 struct list_head list;
36 struct video_device *vdev; 36 struct video_device *vdev;
37 struct v4l2_events *events; /* events, pending and subscribed */ 37 struct v4l2_events *events; /* events, pending and subscribed */
38 enum v4l2_priority prio;
38}; 39};
39 40
40/* 41/*
@@ -50,8 +51,16 @@ int v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev);
50 */ 51 */
51void v4l2_fh_add(struct v4l2_fh *fh); 52void v4l2_fh_add(struct v4l2_fh *fh);
52/* 53/*
54 * Can be used as the open() op of v4l2_file_operations.
55 * It allocates a v4l2_fh and inits and adds it to the video_device associated
56 * with the file pointer.
57 */
58int v4l2_fh_open(struct file *filp);
59/*
53 * Remove file handle from the list of file handles. Must be called in 60 * Remove file handle from the list of file handles. Must be called in
54 * v4l2_file_operations->release() handler if the driver uses v4l2_fh. 61 * v4l2_file_operations->release() handler if the driver uses v4l2_fh.
62 * On error filp->private_data will be NULL, otherwise it will point to
63 * the v4l2_fh struct.
55 */ 64 */
56void v4l2_fh_del(struct v4l2_fh *fh); 65void v4l2_fh_del(struct v4l2_fh *fh);
57/* 66/*
@@ -61,5 +70,25 @@ void v4l2_fh_del(struct v4l2_fh *fh);
61 * driver uses v4l2_fh. 70 * driver uses v4l2_fh.
62 */ 71 */
63void v4l2_fh_exit(struct v4l2_fh *fh); 72void v4l2_fh_exit(struct v4l2_fh *fh);
73/*
74 * Can be used as the release() op of v4l2_file_operations.
75 * It deletes and exits the v4l2_fh associated with the file pointer and
76 * frees it. It will do nothing if filp->private_data (the pointer to the
77 * v4l2_fh struct) is NULL. This function always returns 0.
78 */
79int v4l2_fh_release(struct file *filp);
80/*
81 * Returns 1 if this filehandle is the only filehandle opened for the
82 * associated video_device. If fh is NULL, then it returns 0.
83 */
84int v4l2_fh_is_singular(struct v4l2_fh *fh);
85/*
86 * Helper function with struct file as argument. If filp->private_data is
87 * NULL, then it will return 0.
88 */
89static inline int v4l2_fh_is_singular_file(struct file *filp)
90{
91 return v4l2_fh_is_singular(filp->private_data);
92}
64 93
65#endif /* V4L2_EVENT_H */ 94#endif /* V4L2_EVENT_H */
diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 67df37542c68..dd9f1e7b8ff7 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -37,6 +37,10 @@ struct v4l2_ioctl_ops {
37 struct v4l2_fmtdesc *f); 37 struct v4l2_fmtdesc *f);
38 int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh, 38 int (*vidioc_enum_fmt_vid_out) (struct file *file, void *fh,
39 struct v4l2_fmtdesc *f); 39 struct v4l2_fmtdesc *f);
40 int (*vidioc_enum_fmt_vid_cap_mplane)(struct file *file, void *fh,
41 struct v4l2_fmtdesc *f);
42 int (*vidioc_enum_fmt_vid_out_mplane)(struct file *file, void *fh,
43 struct v4l2_fmtdesc *f);
40 int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh, 44 int (*vidioc_enum_fmt_type_private)(struct file *file, void *fh,
41 struct v4l2_fmtdesc *f); 45 struct v4l2_fmtdesc *f);
42 46
@@ -57,6 +61,10 @@ struct v4l2_ioctl_ops {
57 struct v4l2_format *f); 61 struct v4l2_format *f);
58 int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh, 62 int (*vidioc_g_fmt_sliced_vbi_out)(struct file *file, void *fh,
59 struct v4l2_format *f); 63 struct v4l2_format *f);
64 int (*vidioc_g_fmt_vid_cap_mplane)(struct file *file, void *fh,
65 struct v4l2_format *f);
66 int (*vidioc_g_fmt_vid_out_mplane)(struct file *file, void *fh,
67 struct v4l2_format *f);
60 int (*vidioc_g_fmt_type_private)(struct file *file, void *fh, 68 int (*vidioc_g_fmt_type_private)(struct file *file, void *fh,
61 struct v4l2_format *f); 69 struct v4l2_format *f);
62 70
@@ -77,6 +85,10 @@ struct v4l2_ioctl_ops {
77 struct v4l2_format *f); 85 struct v4l2_format *f);
78 int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh, 86 int (*vidioc_s_fmt_sliced_vbi_out)(struct file *file, void *fh,
79 struct v4l2_format *f); 87 struct v4l2_format *f);
88 int (*vidioc_s_fmt_vid_cap_mplane)(struct file *file, void *fh,
89 struct v4l2_format *f);
90 int (*vidioc_s_fmt_vid_out_mplane)(struct file *file, void *fh,
91 struct v4l2_format *f);
80 int (*vidioc_s_fmt_type_private)(struct file *file, void *fh, 92 int (*vidioc_s_fmt_type_private)(struct file *file, void *fh,
81 struct v4l2_format *f); 93 struct v4l2_format *f);
82 94
@@ -97,6 +109,10 @@ struct v4l2_ioctl_ops {
97 struct v4l2_format *f); 109 struct v4l2_format *f);
98 int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh, 110 int (*vidioc_try_fmt_sliced_vbi_out)(struct file *file, void *fh,
99 struct v4l2_format *f); 111 struct v4l2_format *f);
112 int (*vidioc_try_fmt_vid_cap_mplane)(struct file *file, void *fh,
113 struct v4l2_format *f);
114 int (*vidioc_try_fmt_vid_out_mplane)(struct file *file, void *fh,
115 struct v4l2_format *f);
100 int (*vidioc_try_fmt_type_private)(struct file *file, void *fh, 116 int (*vidioc_try_fmt_type_private)(struct file *file, void *fh,
101 struct v4l2_format *f); 117 struct v4l2_format *f);
102 118
@@ -254,7 +270,7 @@ struct v4l2_ioctl_ops {
254 270
255 /* For other private ioctls */ 271 /* For other private ioctls */
256 long (*vidioc_default) (struct file *file, void *fh, 272 long (*vidioc_default) (struct file *file, void *fh,
257 int cmd, void *arg); 273 bool valid_prio, int cmd, void *arg);
258}; 274};
259 275
260 276
diff --git a/include/media/v4l2-mediabus.h b/include/media/v4l2-mediabus.h
index 8e6559838ae3..971c7fa29614 100644
--- a/include/media/v4l2-mediabus.h
+++ b/include/media/v4l2-mediabus.h
@@ -11,66 +11,7 @@
11#ifndef V4L2_MEDIABUS_H 11#ifndef V4L2_MEDIABUS_H
12#define V4L2_MEDIABUS_H 12#define V4L2_MEDIABUS_H
13 13
14/* 14#include <linux/v4l2-mediabus.h>
15 * These pixel codes uniquely identify data formats on the media bus. Mostly
16 * they correspond to similarly named V4L2_PIX_FMT_* formats, format 0 is
17 * reserved, V4L2_MBUS_FMT_FIXED shall be used by host-client pairs, where the
18 * data format is fixed. Additionally, "2X8" means that one pixel is transferred
19 * in two 8-bit samples, "BE" or "LE" specify in which order those samples are
20 * transferred over the bus: "LE" means that the least significant bits are
21 * transferred first, "BE" means that the most significant bits are transferred
22 * first, and "PADHI" and "PADLO" define which bits - low or high, in the
23 * incomplete high byte, are filled with padding bits.
24 */
25enum v4l2_mbus_pixelcode {
26 V4L2_MBUS_FMT_FIXED = 1,
27 V4L2_MBUS_FMT_YUYV8_2X8,
28 V4L2_MBUS_FMT_YVYU8_2X8,
29 V4L2_MBUS_FMT_UYVY8_2X8,
30 V4L2_MBUS_FMT_VYUY8_2X8,
31 V4L2_MBUS_FMT_YVYU10_2X10,
32 V4L2_MBUS_FMT_YUYV10_2X10,
33 V4L2_MBUS_FMT_YVYU10_1X20,
34 V4L2_MBUS_FMT_YUYV10_1X20,
35 V4L2_MBUS_FMT_RGB444_2X8_PADHI_LE,
36 V4L2_MBUS_FMT_RGB444_2X8_PADHI_BE,
37 V4L2_MBUS_FMT_RGB555_2X8_PADHI_LE,
38 V4L2_MBUS_FMT_RGB555_2X8_PADHI_BE,
39 V4L2_MBUS_FMT_RGB565_2X8_LE,
40 V4L2_MBUS_FMT_RGB565_2X8_BE,
41 V4L2_MBUS_FMT_BGR565_2X8_LE,
42 V4L2_MBUS_FMT_BGR565_2X8_BE,
43 V4L2_MBUS_FMT_SBGGR8_1X8,
44 V4L2_MBUS_FMT_SBGGR10_1X10,
45 V4L2_MBUS_FMT_GREY8_1X8,
46 V4L2_MBUS_FMT_Y10_1X10,
47 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_LE,
48 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_LE,
49 V4L2_MBUS_FMT_SBGGR10_2X8_PADHI_BE,
50 V4L2_MBUS_FMT_SBGGR10_2X8_PADLO_BE,
51 V4L2_MBUS_FMT_SGRBG8_1X8,
52 V4L2_MBUS_FMT_SBGGR12_1X12,
53 V4L2_MBUS_FMT_YUYV8_1_5X8,
54 V4L2_MBUS_FMT_YVYU8_1_5X8,
55 V4L2_MBUS_FMT_UYVY8_1_5X8,
56 V4L2_MBUS_FMT_VYUY8_1_5X8,
57};
58
59/**
60 * struct v4l2_mbus_framefmt - frame format on the media bus
61 * @width: frame width
62 * @height: frame height
63 * @code: data format code
64 * @field: used interlacing type
65 * @colorspace: colorspace of the data
66 */
67struct v4l2_mbus_framefmt {
68 __u32 width;
69 __u32 height;
70 enum v4l2_mbus_pixelcode code;
71 enum v4l2_field field;
72 enum v4l2_colorspace colorspace;
73};
74 15
75static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt, 16static inline void v4l2_fill_pix_format(struct v4l2_pix_format *pix_fmt,
76 const struct v4l2_mbus_framefmt *mbus_fmt) 17 const struct v4l2_mbus_framefmt *mbus_fmt)
diff --git a/include/media/v4l2-mem2mem.h b/include/media/v4l2-mem2mem.h
index 8d149f1c58d0..16ac4733e80d 100644
--- a/include/media/v4l2-mem2mem.h
+++ b/include/media/v4l2-mem2mem.h
@@ -5,7 +5,7 @@
5 * and destination. 5 * and destination.
6 * 6 *
7 * Copyright (c) 2009 Samsung Electronics Co., Ltd. 7 * Copyright (c) 2009 Samsung Electronics Co., Ltd.
8 * Pawel Osciak, <p.osciak@samsung.com> 8 * Pawel Osciak, <pawel@osciak.com>
9 * Marek Szyprowski, <m.szyprowski@samsung.com> 9 * Marek Szyprowski, <m.szyprowski@samsung.com>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
@@ -17,7 +17,7 @@
17#ifndef _MEDIA_V4L2_MEM2MEM_H 17#ifndef _MEDIA_V4L2_MEM2MEM_H
18#define _MEDIA_V4L2_MEM2MEM_H 18#define _MEDIA_V4L2_MEM2MEM_H
19 19
20#include <media/videobuf-core.h> 20#include <media/videobuf2-core.h>
21 21
22/** 22/**
23 * struct v4l2_m2m_ops - mem-to-mem device driver callbacks 23 * struct v4l2_m2m_ops - mem-to-mem device driver callbacks
@@ -45,17 +45,20 @@ struct v4l2_m2m_ops {
45 void (*device_run)(void *priv); 45 void (*device_run)(void *priv);
46 int (*job_ready)(void *priv); 46 int (*job_ready)(void *priv);
47 void (*job_abort)(void *priv); 47 void (*job_abort)(void *priv);
48 void (*lock)(void *priv);
49 void (*unlock)(void *priv);
48}; 50};
49 51
50struct v4l2_m2m_dev; 52struct v4l2_m2m_dev;
51 53
52struct v4l2_m2m_queue_ctx { 54struct v4l2_m2m_queue_ctx {
53/* private: internal use only */ 55/* private: internal use only */
54 struct videobuf_queue q; 56 struct vb2_queue q;
55 57
56 /* Queue for buffers ready to be processed as soon as this 58 /* Queue for buffers ready to be processed as soon as this
57 * instance receives access to the device */ 59 * instance receives access to the device */
58 struct list_head rdy_queue; 60 struct list_head rdy_queue;
61 spinlock_t rdy_spinlock;
59 u8 num_rdy; 62 u8 num_rdy;
60}; 63};
61 64
@@ -72,19 +75,31 @@ struct v4l2_m2m_ctx {
72 /* For device job queue */ 75 /* For device job queue */
73 struct list_head queue; 76 struct list_head queue;
74 unsigned long job_flags; 77 unsigned long job_flags;
78 wait_queue_head_t finished;
75 79
76 /* Instance private data */ 80 /* Instance private data */
77 void *priv; 81 void *priv;
78}; 82};
79 83
84struct v4l2_m2m_buffer {
85 struct vb2_buffer vb;
86 struct list_head list;
87};
88
80void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev); 89void *v4l2_m2m_get_curr_priv(struct v4l2_m2m_dev *m2m_dev);
81 90
82struct videobuf_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx, 91struct vb2_queue *v4l2_m2m_get_vq(struct v4l2_m2m_ctx *m2m_ctx,
83 enum v4l2_buf_type type); 92 enum v4l2_buf_type type);
84 93
85void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev, 94void v4l2_m2m_job_finish(struct v4l2_m2m_dev *m2m_dev,
86 struct v4l2_m2m_ctx *m2m_ctx); 95 struct v4l2_m2m_ctx *m2m_ctx);
87 96
97static inline void
98v4l2_m2m_buf_done(struct vb2_buffer *buf, enum vb2_buffer_state state)
99{
100 vb2_buffer_done(buf, state);
101}
102
88int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx, 103int v4l2_m2m_reqbufs(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
89 struct v4l2_requestbuffers *reqbufs); 104 struct v4l2_requestbuffers *reqbufs);
90 105
@@ -110,13 +125,13 @@ int v4l2_m2m_mmap(struct file *file, struct v4l2_m2m_ctx *m2m_ctx,
110struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops); 125struct v4l2_m2m_dev *v4l2_m2m_init(struct v4l2_m2m_ops *m2m_ops);
111void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev); 126void v4l2_m2m_release(struct v4l2_m2m_dev *m2m_dev);
112 127
113struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(void *priv, struct v4l2_m2m_dev *m2m_dev, 128struct v4l2_m2m_ctx *v4l2_m2m_ctx_init(struct v4l2_m2m_dev *m2m_dev,
114 void (*vq_init)(void *priv, struct videobuf_queue *, 129 void *drv_priv,
115 enum v4l2_buf_type)); 130 int (*queue_init)(void *priv, struct vb2_queue *src_vq, struct vb2_queue *dst_vq));
131
116void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx); 132void v4l2_m2m_ctx_release(struct v4l2_m2m_ctx *m2m_ctx);
117 133
118void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct videobuf_queue *vq, 134void v4l2_m2m_buf_queue(struct v4l2_m2m_ctx *m2m_ctx, struct vb2_buffer *vb);
119 struct videobuf_buffer *vb);
120 135
121/** 136/**
122 * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for 137 * v4l2_m2m_num_src_bufs_ready() - return the number of source buffers ready for
@@ -138,7 +153,7 @@ unsigned int v4l2_m2m_num_dst_bufs_ready(struct v4l2_m2m_ctx *m2m_ctx)
138 return m2m_ctx->out_q_ctx.num_rdy; 153 return m2m_ctx->out_q_ctx.num_rdy;
139} 154}
140 155
141void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type); 156void *v4l2_m2m_next_buf(struct v4l2_m2m_queue_ctx *q_ctx);
142 157
143/** 158/**
144 * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready 159 * v4l2_m2m_next_src_buf() - return next source buffer from the list of ready
@@ -146,7 +161,7 @@ void *v4l2_m2m_next_buf(struct v4l2_m2m_ctx *m2m_ctx, enum v4l2_buf_type type);
146 */ 161 */
147static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx) 162static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
148{ 163{
149 return v4l2_m2m_next_buf(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 164 return v4l2_m2m_next_buf(&m2m_ctx->out_q_ctx);
150} 165}
151 166
152/** 167/**
@@ -155,29 +170,28 @@ static inline void *v4l2_m2m_next_src_buf(struct v4l2_m2m_ctx *m2m_ctx)
155 */ 170 */
156static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx) 171static inline void *v4l2_m2m_next_dst_buf(struct v4l2_m2m_ctx *m2m_ctx)
157{ 172{
158 return v4l2_m2m_next_buf(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 173 return v4l2_m2m_next_buf(&m2m_ctx->cap_q_ctx);
159} 174}
160 175
161/** 176/**
162 * v4l2_m2m_get_src_vq() - return videobuf_queue for source buffers 177 * v4l2_m2m_get_src_vq() - return vb2_queue for source buffers
163 */ 178 */
164static inline 179static inline
165struct videobuf_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx) 180struct vb2_queue *v4l2_m2m_get_src_vq(struct v4l2_m2m_ctx *m2m_ctx)
166{ 181{
167 return v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 182 return &m2m_ctx->out_q_ctx.q;
168} 183}
169 184
170/** 185/**
171 * v4l2_m2m_get_dst_vq() - return videobuf_queue for destination buffers 186 * v4l2_m2m_get_dst_vq() - return vb2_queue for destination buffers
172 */ 187 */
173static inline 188static inline
174struct videobuf_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx) 189struct vb2_queue *v4l2_m2m_get_dst_vq(struct v4l2_m2m_ctx *m2m_ctx)
175{ 190{
176 return v4l2_m2m_get_vq(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 191 return &m2m_ctx->cap_q_ctx.q;
177} 192}
178 193
179void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx, 194void *v4l2_m2m_buf_remove(struct v4l2_m2m_queue_ctx *q_ctx);
180 enum v4l2_buf_type type);
181 195
182/** 196/**
183 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready 197 * v4l2_m2m_src_buf_remove() - take off a source buffer from the list of ready
@@ -185,7 +199,7 @@ void *v4l2_m2m_buf_remove(struct v4l2_m2m_ctx *m2m_ctx,
185 */ 199 */
186static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) 200static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
187{ 201{
188 return v4l2_m2m_buf_remove(m2m_ctx, V4L2_BUF_TYPE_VIDEO_OUTPUT); 202 return v4l2_m2m_buf_remove(&m2m_ctx->out_q_ctx);
189} 203}
190 204
191/** 205/**
@@ -194,7 +208,7 @@ static inline void *v4l2_m2m_src_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
194 */ 208 */
195static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx) 209static inline void *v4l2_m2m_dst_buf_remove(struct v4l2_m2m_ctx *m2m_ctx)
196{ 210{
197 return v4l2_m2m_buf_remove(m2m_ctx, V4L2_BUF_TYPE_VIDEO_CAPTURE); 211 return v4l2_m2m_buf_remove(&m2m_ctx->cap_q_ctx);
198} 212}
199 213
200#endif /* _MEDIA_V4L2_MEM2MEM_H */ 214#endif /* _MEDIA_V4L2_MEM2MEM_H */
diff --git a/include/media/v4l2-subdev.h b/include/media/v4l2-subdev.h
index daf1e57d9b26..1562c4ff3a65 100644
--- a/include/media/v4l2-subdev.h
+++ b/include/media/v4l2-subdev.h
@@ -21,7 +21,11 @@
21#ifndef _V4L2_SUBDEV_H 21#ifndef _V4L2_SUBDEV_H
22#define _V4L2_SUBDEV_H 22#define _V4L2_SUBDEV_H
23 23
24#include <linux/v4l2-subdev.h>
25#include <media/media-entity.h>
24#include <media/v4l2-common.h> 26#include <media/v4l2-common.h>
27#include <media/v4l2-dev.h>
28#include <media/v4l2-fh.h>
25#include <media/v4l2-mediabus.h> 29#include <media/v4l2-mediabus.h>
26 30
27/* generic v4l2_device notify callback notification values */ 31/* generic v4l2_device notify callback notification values */
@@ -36,7 +40,10 @@
36 40
37struct v4l2_device; 41struct v4l2_device;
38struct v4l2_ctrl_handler; 42struct v4l2_ctrl_handler;
43struct v4l2_event_subscription;
44struct v4l2_fh;
39struct v4l2_subdev; 45struct v4l2_subdev;
46struct v4l2_subdev_fh;
40struct tuner_setup; 47struct tuner_setup;
41 48
42/* decode_vbi_line */ 49/* decode_vbi_line */
@@ -160,6 +167,10 @@ struct v4l2_subdev_core_ops {
160 int (*s_power)(struct v4l2_subdev *sd, int on); 167 int (*s_power)(struct v4l2_subdev *sd, int on);
161 int (*interrupt_service_routine)(struct v4l2_subdev *sd, 168 int (*interrupt_service_routine)(struct v4l2_subdev *sd,
162 u32 status, bool *handled); 169 u32 status, bool *handled);
170 int (*subscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
171 struct v4l2_event_subscription *sub);
172 int (*unsubscribe_event)(struct v4l2_subdev *sd, struct v4l2_fh *fh,
173 struct v4l2_event_subscription *sub);
163}; 174};
164 175
165/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio. 176/* s_mode: switch the tuner to a specific tuner mode. Replacement of s_radio.
@@ -257,6 +268,10 @@ struct v4l2_subdev_video_ops {
257 int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop); 268 int (*s_crop)(struct v4l2_subdev *sd, struct v4l2_crop *crop);
258 int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 269 int (*g_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
259 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param); 270 int (*s_parm)(struct v4l2_subdev *sd, struct v4l2_streamparm *param);
271 int (*g_frame_interval)(struct v4l2_subdev *sd,
272 struct v4l2_subdev_frame_interval *interval);
273 int (*s_frame_interval)(struct v4l2_subdev *sd,
274 struct v4l2_subdev_frame_interval *interval);
260 int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize); 275 int (*enum_framesizes)(struct v4l2_subdev *sd, struct v4l2_frmsizeenum *fsize);
261 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival); 276 int (*enum_frameintervals)(struct v4l2_subdev *sd, struct v4l2_frmivalenum *fival);
262 int (*enum_dv_presets) (struct v4l2_subdev *sd, 277 int (*enum_dv_presets) (struct v4l2_subdev *sd,
@@ -271,6 +286,8 @@ struct v4l2_subdev_video_ops {
271 struct v4l2_dv_timings *timings); 286 struct v4l2_dv_timings *timings);
272 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index, 287 int (*enum_mbus_fmt)(struct v4l2_subdev *sd, unsigned int index,
273 enum v4l2_mbus_pixelcode *code); 288 enum v4l2_mbus_pixelcode *code);
289 int (*enum_mbus_fsizes)(struct v4l2_subdev *sd,
290 struct v4l2_frmsizeenum *fsize);
274 int (*g_mbus_fmt)(struct v4l2_subdev *sd, 291 int (*g_mbus_fmt)(struct v4l2_subdev *sd,
275 struct v4l2_mbus_framefmt *fmt); 292 struct v4l2_mbus_framefmt *fmt);
276 int (*try_mbus_fmt)(struct v4l2_subdev *sd, 293 int (*try_mbus_fmt)(struct v4l2_subdev *sd,
@@ -324,9 +341,13 @@ struct v4l2_subdev_vbi_ops {
324 * This is needed for some sensors, which always corrupt 341 * This is needed for some sensors, which always corrupt
325 * several top lines of the output image, or which send their 342 * several top lines of the output image, or which send their
326 * metadata in them. 343 * metadata in them.
344 * @g_skip_frames: number of frames to skip at stream start. This is needed for
345 * buggy sensors that generate faulty frames when they are
346 * turned on.
327 */ 347 */
328struct v4l2_subdev_sensor_ops { 348struct v4l2_subdev_sensor_ops {
329 int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines); 349 int (*g_skip_top_lines)(struct v4l2_subdev *sd, u32 *lines);
350 int (*g_skip_frames)(struct v4l2_subdev *sd, u32 *frames);
330}; 351};
331 352
332/* 353/*
@@ -401,6 +422,25 @@ struct v4l2_subdev_ir_ops {
401 struct v4l2_subdev_ir_parameters *params); 422 struct v4l2_subdev_ir_parameters *params);
402}; 423};
403 424
425struct v4l2_subdev_pad_ops {
426 int (*enum_mbus_code)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
427 struct v4l2_subdev_mbus_code_enum *code);
428 int (*enum_frame_size)(struct v4l2_subdev *sd,
429 struct v4l2_subdev_fh *fh,
430 struct v4l2_subdev_frame_size_enum *fse);
431 int (*enum_frame_interval)(struct v4l2_subdev *sd,
432 struct v4l2_subdev_fh *fh,
433 struct v4l2_subdev_frame_interval_enum *fie);
434 int (*get_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
435 struct v4l2_subdev_format *format);
436 int (*set_fmt)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
437 struct v4l2_subdev_format *format);
438 int (*set_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
439 struct v4l2_subdev_crop *crop);
440 int (*get_crop)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
441 struct v4l2_subdev_crop *crop);
442};
443
404struct v4l2_subdev_ops { 444struct v4l2_subdev_ops {
405 const struct v4l2_subdev_core_ops *core; 445 const struct v4l2_subdev_core_ops *core;
406 const struct v4l2_subdev_tuner_ops *tuner; 446 const struct v4l2_subdev_tuner_ops *tuner;
@@ -409,6 +449,7 @@ struct v4l2_subdev_ops {
409 const struct v4l2_subdev_vbi_ops *vbi; 449 const struct v4l2_subdev_vbi_ops *vbi;
410 const struct v4l2_subdev_ir_ops *ir; 450 const struct v4l2_subdev_ir_ops *ir;
411 const struct v4l2_subdev_sensor_ops *sensor; 451 const struct v4l2_subdev_sensor_ops *sensor;
452 const struct v4l2_subdev_pad_ops *pad;
412}; 453};
413 454
414/* 455/*
@@ -420,23 +461,36 @@ struct v4l2_subdev_ops {
420 * 461 *
421 * unregistered: called when this subdev is unregistered. When called the 462 * unregistered: called when this subdev is unregistered. When called the
422 * v4l2_dev field is still set to the correct v4l2_device. 463 * v4l2_dev field is still set to the correct v4l2_device.
464 *
465 * open: called when the subdev device node is opened by an application.
466 *
467 * close: called when the subdev device node is closed.
423 */ 468 */
424struct v4l2_subdev_internal_ops { 469struct v4l2_subdev_internal_ops {
425 int (*registered)(struct v4l2_subdev *sd); 470 int (*registered)(struct v4l2_subdev *sd);
426 void (*unregistered)(struct v4l2_subdev *sd); 471 void (*unregistered)(struct v4l2_subdev *sd);
472 int (*open)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
473 int (*close)(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh);
427}; 474};
428 475
429#define V4L2_SUBDEV_NAME_SIZE 32 476#define V4L2_SUBDEV_NAME_SIZE 32
430 477
431/* Set this flag if this subdev is a i2c device. */ 478/* Set this flag if this subdev is a i2c device. */
432#define V4L2_SUBDEV_FL_IS_I2C (1U << 0) 479#define V4L2_SUBDEV_FL_IS_I2C (1U << 0)
433/* Set this flag if this subdev is a spi device. */ 480/* Set this flag if this subdev is a spi device. */
434#define V4L2_SUBDEV_FL_IS_SPI (1U << 1) 481#define V4L2_SUBDEV_FL_IS_SPI (1U << 1)
482/* Set this flag if this subdev needs a device node. */
483#define V4L2_SUBDEV_FL_HAS_DEVNODE (1U << 2)
484/* Set this flag if this subdev generates events. */
485#define V4L2_SUBDEV_FL_HAS_EVENTS (1U << 3)
435 486
436/* Each instance of a subdev driver should create this struct, either 487/* Each instance of a subdev driver should create this struct, either
437 stand-alone or embedded in a larger struct. 488 stand-alone or embedded in a larger struct.
438 */ 489 */
439struct v4l2_subdev { 490struct v4l2_subdev {
491#if defined(CONFIG_MEDIA_CONTROLLER)
492 struct media_entity entity;
493#endif
440 struct list_head list; 494 struct list_head list;
441 struct module *owner; 495 struct module *owner;
442 u32 flags; 496 u32 flags;
@@ -453,8 +507,47 @@ struct v4l2_subdev {
453 /* pointer to private data */ 507 /* pointer to private data */
454 void *dev_priv; 508 void *dev_priv;
455 void *host_priv; 509 void *host_priv;
510 /* subdev device node */
511 struct video_device devnode;
512 /* number of events to be allocated on open */
513 unsigned int nevents;
514};
515
516#define media_entity_to_v4l2_subdev(ent) \
517 container_of(ent, struct v4l2_subdev, entity)
518#define vdev_to_v4l2_subdev(vdev) \
519 container_of(vdev, struct v4l2_subdev, devnode)
520
521/*
522 * Used for storing subdev information per file handle
523 */
524struct v4l2_subdev_fh {
525 struct v4l2_fh vfh;
526#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
527 struct v4l2_mbus_framefmt *try_fmt;
528 struct v4l2_rect *try_crop;
529#endif
456}; 530};
457 531
532#define to_v4l2_subdev_fh(fh) \
533 container_of(fh, struct v4l2_subdev_fh, vfh)
534
535#if defined(CONFIG_VIDEO_V4L2_SUBDEV_API)
536static inline struct v4l2_mbus_framefmt *
537v4l2_subdev_get_try_format(struct v4l2_subdev_fh *fh, unsigned int pad)
538{
539 return &fh->try_fmt[pad];
540}
541
542static inline struct v4l2_rect *
543v4l2_subdev_get_try_crop(struct v4l2_subdev_fh *fh, unsigned int pad)
544{
545 return &fh->try_crop[pad];
546}
547#endif
548
549extern const struct v4l2_file_operations v4l2_subdev_fops;
550
458static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p) 551static inline void v4l2_set_subdevdata(struct v4l2_subdev *sd, void *p)
459{ 552{
460 sd->dev_priv = p; 553 sd->dev_priv = p;
@@ -475,20 +568,8 @@ static inline void *v4l2_get_subdev_hostdata(const struct v4l2_subdev *sd)
475 return sd->host_priv; 568 return sd->host_priv;
476} 569}
477 570
478static inline void v4l2_subdev_init(struct v4l2_subdev *sd, 571void v4l2_subdev_init(struct v4l2_subdev *sd,
479 const struct v4l2_subdev_ops *ops) 572 const struct v4l2_subdev_ops *ops);
480{
481 INIT_LIST_HEAD(&sd->list);
482 /* ops->core MUST be set */
483 BUG_ON(!ops || !ops->core);
484 sd->ops = ops;
485 sd->v4l2_dev = NULL;
486 sd->flags = 0;
487 sd->name[0] = '\0';
488 sd->grp_id = 0;
489 sd->dev_priv = NULL;
490 sd->host_priv = NULL;
491}
492 573
493/* Call an ops of a v4l2_subdev, doing the right checks against 574/* Call an ops of a v4l2_subdev, doing the right checks against
494 NULL pointers. 575 NULL pointers.
diff --git a/include/media/videobuf2-core.h b/include/media/videobuf2-core.h
new file mode 100644
index 000000000000..f87472acbc51
--- /dev/null
+++ b/include/media/videobuf2-core.h
@@ -0,0 +1,380 @@
1/*
2 * videobuf2-core.h - V4L2 driver helper framework
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
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.
11 */
12#ifndef _MEDIA_VIDEOBUF2_CORE_H
13#define _MEDIA_VIDEOBUF2_CORE_H
14
15#include <linux/mm_types.h>
16#include <linux/mutex.h>
17#include <linux/poll.h>
18#include <linux/videodev2.h>
19
20struct vb2_alloc_ctx;
21struct vb2_fileio_data;
22
23/**
24 * struct vb2_mem_ops - memory handling/memory allocator operations
25 * @alloc: allocate video memory and, optionally, allocator private data,
26 * return NULL on failure or a pointer to allocator private,
27 * per-buffer data on success; the returned private structure
28 * will then be passed as buf_priv argument to other ops in this
29 * structure
30 * @put: inform the allocator that the buffer will no longer be used;
31 * usually will result in the allocator freeing the buffer (if
32 * no other users of this buffer are present); the buf_priv
33 * argument is the allocator private per-buffer structure
34 * previously returned from the alloc callback
35 * @get_userptr: acquire userspace memory for a hardware operation; used for
36 * USERPTR memory types; vaddr is the address passed to the
37 * videobuf layer when queuing a video buffer of USERPTR type;
38 * should return an allocator private per-buffer structure
39 * associated with the buffer on success, NULL on failure;
40 * the returned private structure will then be passed as buf_priv
41 * argument to other ops in this structure
42 * @put_userptr: inform the allocator that a USERPTR buffer will no longer
43 * be used
44 * @vaddr: return a kernel virtual address to a given memory buffer
45 * associated with the passed private structure or NULL if no
46 * such mapping exists
47 * @cookie: return allocator specific cookie for a given memory buffer
48 * associated with the passed private structure or NULL if not
49 * available
50 * @num_users: return the current number of users of a memory buffer;
51 * return 1 if the videobuf layer (or actually the driver using
52 * it) is the only user
53 * @mmap: setup a userspace mapping for a given memory buffer under
54 * the provided virtual memory region
55 *
56 * Required ops for USERPTR types: get_userptr, put_userptr.
57 * Required ops for MMAP types: alloc, put, num_users, mmap.
58 * Required ops for read/write access types: alloc, put, num_users, vaddr
59 */
60struct vb2_mem_ops {
61 void *(*alloc)(void *alloc_ctx, unsigned long size);
62 void (*put)(void *buf_priv);
63
64 void *(*get_userptr)(void *alloc_ctx, unsigned long vaddr,
65 unsigned long size, int write);
66 void (*put_userptr)(void *buf_priv);
67
68 void *(*vaddr)(void *buf_priv);
69 void *(*cookie)(void *buf_priv);
70
71 unsigned int (*num_users)(void *buf_priv);
72
73 int (*mmap)(void *buf_priv, struct vm_area_struct *vma);
74};
75
76struct vb2_plane {
77 void *mem_priv;
78 int mapped:1;
79};
80
81/**
82 * enum vb2_io_modes - queue access methods
83 * @VB2_MMAP: driver supports MMAP with streaming API
84 * @VB2_USERPTR: driver supports USERPTR with streaming API
85 * @VB2_READ: driver supports read() style access
86 * @VB2_WRITE: driver supports write() style access
87 */
88enum vb2_io_modes {
89 VB2_MMAP = (1 << 0),
90 VB2_USERPTR = (1 << 1),
91 VB2_READ = (1 << 2),
92 VB2_WRITE = (1 << 3),
93};
94
95/**
96 * enum vb2_fileio_flags - flags for selecting a mode of the file io emulator,
97 * by default the 'streaming' style is used by the file io emulator
98 * @VB2_FILEIO_READ_ONCE: report EOF after reading the first buffer
99 * @VB2_FILEIO_WRITE_IMMEDIATELY: queue buffer after each write() call
100 */
101enum vb2_fileio_flags {
102 VB2_FILEIO_READ_ONCE = (1 << 0),
103 VB2_FILEIO_WRITE_IMMEDIATELY = (1 << 1),
104};
105
106/**
107 * enum vb2_buffer_state - current video buffer state
108 * @VB2_BUF_STATE_DEQUEUED: buffer under userspace control
109 * @VB2_BUF_STATE_QUEUED: buffer queued in videobuf, but not in driver
110 * @VB2_BUF_STATE_ACTIVE: buffer queued in driver and possibly used
111 * in a hardware operation
112 * @VB2_BUF_STATE_DONE: buffer returned from driver to videobuf, but
113 * not yet dequeued to userspace
114 * @VB2_BUF_STATE_ERROR: same as above, but the operation on the buffer
115 * has ended with an error, which will be reported
116 * to the userspace when it is dequeued
117 */
118enum vb2_buffer_state {
119 VB2_BUF_STATE_DEQUEUED,
120 VB2_BUF_STATE_QUEUED,
121 VB2_BUF_STATE_ACTIVE,
122 VB2_BUF_STATE_DONE,
123 VB2_BUF_STATE_ERROR,
124};
125
126struct vb2_queue;
127
128/**
129 * struct vb2_buffer - represents a video buffer
130 * @v4l2_buf: struct v4l2_buffer associated with this buffer; can
131 * be read by the driver and relevant entries can be
132 * changed by the driver in case of CAPTURE types
133 * (such as timestamp)
134 * @v4l2_planes: struct v4l2_planes associated with this buffer; can
135 * be read by the driver and relevant entries can be
136 * changed by the driver in case of CAPTURE types
137 * (such as bytesused); NOTE that even for single-planar
138 * types, the v4l2_planes[0] struct should be used
139 * instead of v4l2_buf for filling bytesused - drivers
140 * should use the vb2_set_plane_payload() function for that
141 * @vb2_queue: the queue to which this driver belongs
142 * @num_planes: number of planes in the buffer
143 * on an internal driver queue
144 * @state: current buffer state; do not change
145 * @queued_entry: entry on the queued buffers list, which holds all
146 * buffers queued from userspace
147 * @done_entry: entry on the list that stores all buffers ready to
148 * be dequeued to userspace
149 * @planes: private per-plane information; do not change
150 * @num_planes_mapped: number of mapped planes; do not change
151 */
152struct vb2_buffer {
153 struct v4l2_buffer v4l2_buf;
154 struct v4l2_plane v4l2_planes[VIDEO_MAX_PLANES];
155
156 struct vb2_queue *vb2_queue;
157
158 unsigned int num_planes;
159
160/* Private: internal use only */
161 enum vb2_buffer_state state;
162
163 struct list_head queued_entry;
164 struct list_head done_entry;
165
166 struct vb2_plane planes[VIDEO_MAX_PLANES];
167 unsigned int num_planes_mapped;
168};
169
170/**
171 * struct vb2_ops - driver-specific callbacks
172 *
173 * @queue_setup: called from a VIDIOC_REQBUFS handler, before
174 * memory allocation; driver should return the required
175 * number of buffers in num_buffers, the required number
176 * of planes per buffer in num_planes; the size of each
177 * plane should be set in the sizes[] array and optional
178 * per-plane allocator specific context in alloc_ctxs[]
179 * array
180 * @wait_prepare: release any locks taken while calling vb2 functions;
181 * it is called before an ioctl needs to wait for a new
182 * buffer to arrive; required to avoid a deadlock in
183 * blocking access type
184 * @wait_finish: reacquire all locks released in the previous callback;
185 * required to continue operation after sleeping while
186 * waiting for a new buffer to arrive
187 * @buf_init: called once after allocating a buffer (in MMAP case)
188 * or after acquiring a new USERPTR buffer; drivers may
189 * perform additional buffer-related initialization;
190 * initialization failure (return != 0) will prevent
191 * queue setup from completing successfully; optional
192 * @buf_prepare: called every time the buffer is queued from userspace;
193 * drivers may perform any initialization required before
194 * each hardware operation in this callback;
195 * if an error is returned, the buffer will not be queued
196 * in driver; optional
197 * @buf_finish: called before every dequeue of the buffer back to
198 * userspace; drivers may perform any operations required
199 * before userspace accesses the buffer; optional
200 * @buf_cleanup: called once before the buffer is freed; drivers may
201 * perform any additional cleanup; optional
202 * @start_streaming: called once before entering 'streaming' state; enables
203 * driver to receive buffers over buf_queue() callback
204 * @stop_streaming: called when 'streaming' state must be disabled; driver
205 * should stop any DMA transactions or wait until they
206 * finish and give back all buffers it got from buf_queue()
207 * callback; may use vb2_wait_for_all_buffers() function
208 * @buf_queue: passes buffer vb to the driver; driver may start
209 * hardware operation on this buffer; driver should give
210 * the buffer back by calling vb2_buffer_done() function
211 */
212struct vb2_ops {
213 int (*queue_setup)(struct vb2_queue *q, unsigned int *num_buffers,
214 unsigned int *num_planes, unsigned long sizes[],
215 void *alloc_ctxs[]);
216
217 void (*wait_prepare)(struct vb2_queue *q);
218 void (*wait_finish)(struct vb2_queue *q);
219
220 int (*buf_init)(struct vb2_buffer *vb);
221 int (*buf_prepare)(struct vb2_buffer *vb);
222 int (*buf_finish)(struct vb2_buffer *vb);
223 void (*buf_cleanup)(struct vb2_buffer *vb);
224
225 int (*start_streaming)(struct vb2_queue *q);
226 int (*stop_streaming)(struct vb2_queue *q);
227
228 void (*buf_queue)(struct vb2_buffer *vb);
229};
230
231/**
232 * struct vb2_queue - a videobuf queue
233 *
234 * @type: queue type (see V4L2_BUF_TYPE_* in linux/videodev2.h
235 * @io_modes: supported io methods (see vb2_io_modes enum)
236 * @io_flags: additional io flags (see vb2_fileio_flags enum)
237 * @ops: driver-specific callbacks
238 * @mem_ops: memory allocator specific callbacks
239 * @drv_priv: driver private data
240 * @buf_struct_size: size of the driver-specific buffer structure;
241 * "0" indicates the driver doesn't want to use a custom buffer
242 * structure type, so sizeof(struct vb2_buffer) will is used
243 *
244 * @memory: current memory type used
245 * @bufs: videobuf buffer structures
246 * @num_buffers: number of allocated/used buffers
247 * @queued_list: list of buffers currently queued from userspace
248 * @queued_count: number of buffers owned by the driver
249 * @done_list: list of buffers ready to be dequeued to userspace
250 * @done_lock: lock to protect done_list list
251 * @done_wq: waitqueue for processes waiting for buffers ready to be dequeued
252 * @alloc_ctx: memory type/allocator-specific contexts for each plane
253 * @streaming: current streaming state
254 * @fileio: file io emulator internal data, used only if emulator is active
255 */
256struct vb2_queue {
257 enum v4l2_buf_type type;
258 unsigned int io_modes;
259 unsigned int io_flags;
260
261 const struct vb2_ops *ops;
262 const struct vb2_mem_ops *mem_ops;
263 void *drv_priv;
264 unsigned int buf_struct_size;
265
266/* private: internal use only */
267 enum v4l2_memory memory;
268 struct vb2_buffer *bufs[VIDEO_MAX_FRAME];
269 unsigned int num_buffers;
270
271 struct list_head queued_list;
272
273 atomic_t queued_count;
274 struct list_head done_list;
275 spinlock_t done_lock;
276 wait_queue_head_t done_wq;
277
278 void *alloc_ctx[VIDEO_MAX_PLANES];
279
280 unsigned int streaming:1;
281
282 struct vb2_fileio_data *fileio;
283};
284
285void *vb2_plane_vaddr(struct vb2_buffer *vb, unsigned int plane_no);
286void *vb2_plane_cookie(struct vb2_buffer *vb, unsigned int plane_no);
287
288void vb2_buffer_done(struct vb2_buffer *vb, enum vb2_buffer_state state);
289int vb2_wait_for_all_buffers(struct vb2_queue *q);
290
291int vb2_querybuf(struct vb2_queue *q, struct v4l2_buffer *b);
292int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req);
293
294int vb2_queue_init(struct vb2_queue *q);
295
296void vb2_queue_release(struct vb2_queue *q);
297
298int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b);
299int vb2_dqbuf(struct vb2_queue *q, struct v4l2_buffer *b, bool nonblocking);
300
301int vb2_streamon(struct vb2_queue *q, enum v4l2_buf_type type);
302int vb2_streamoff(struct vb2_queue *q, enum v4l2_buf_type type);
303
304int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma);
305unsigned int vb2_poll(struct vb2_queue *q, struct file *file, poll_table *wait);
306size_t vb2_read(struct vb2_queue *q, char __user *data, size_t count,
307 loff_t *ppos, int nonblock);
308size_t vb2_write(struct vb2_queue *q, char __user *data, size_t count,
309 loff_t *ppos, int nonblock);
310
311/**
312 * vb2_is_streaming() - return streaming status of the queue
313 * @q: videobuf queue
314 */
315static inline bool vb2_is_streaming(struct vb2_queue *q)
316{
317 return q->streaming;
318}
319
320/**
321 * vb2_is_busy() - return busy status of the queue
322 * @q: videobuf queue
323 *
324 * This function checks if queue has any buffers allocated.
325 */
326static inline bool vb2_is_busy(struct vb2_queue *q)
327{
328 return (q->num_buffers > 0);
329}
330
331/**
332 * vb2_get_drv_priv() - return driver private data associated with the queue
333 * @q: videobuf queue
334 */
335static inline void *vb2_get_drv_priv(struct vb2_queue *q)
336{
337 return q->drv_priv;
338}
339
340/**
341 * vb2_set_plane_payload() - set bytesused for the plane plane_no
342 * @vb: buffer for which plane payload should be set
343 * @plane_no: plane number for which payload should be set
344 * @size: payload in bytes
345 */
346static inline void vb2_set_plane_payload(struct vb2_buffer *vb,
347 unsigned int plane_no, unsigned long size)
348{
349 if (plane_no < vb->num_planes)
350 vb->v4l2_planes[plane_no].bytesused = size;
351}
352
353/**
354 * vb2_get_plane_payload() - get bytesused for the plane plane_no
355 * @vb: buffer for which plane payload should be set
356 * @plane_no: plane number for which payload should be set
357 * @size: payload in bytes
358 */
359static inline unsigned long vb2_get_plane_payload(struct vb2_buffer *vb,
360 unsigned int plane_no)
361{
362 if (plane_no < vb->num_planes)
363 return vb->v4l2_planes[plane_no].bytesused;
364 return 0;
365}
366
367/**
368 * vb2_plane_size() - return plane size in bytes
369 * @vb: buffer for which plane size should be returned
370 * @plane_no: plane number for which size should be returned
371 */
372static inline unsigned long
373vb2_plane_size(struct vb2_buffer *vb, unsigned int plane_no)
374{
375 if (plane_no < vb->num_planes)
376 return vb->v4l2_planes[plane_no].length;
377 return 0;
378}
379
380#endif /* _MEDIA_VIDEOBUF2_CORE_H */
diff --git a/include/media/videobuf2-dma-contig.h b/include/media/videobuf2-dma-contig.h
new file mode 100644
index 000000000000..7e6c68b23773
--- /dev/null
+++ b/include/media/videobuf2-dma-contig.h
@@ -0,0 +1,32 @@
1/*
2 * videobuf2-dma-coherent.h - DMA coherent memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
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.
11 */
12
13#ifndef _MEDIA_VIDEOBUF2_DMA_COHERENT_H
14#define _MEDIA_VIDEOBUF2_DMA_COHERENT_H
15
16#include <media/videobuf2-core.h>
17#include <linux/dma-mapping.h>
18
19static inline dma_addr_t
20vb2_dma_contig_plane_paddr(struct vb2_buffer *vb, unsigned int plane_no)
21{
22 dma_addr_t *paddr = vb2_plane_cookie(vb, plane_no);
23
24 return *paddr;
25}
26
27void *vb2_dma_contig_init_ctx(struct device *dev);
28void vb2_dma_contig_cleanup_ctx(void *alloc_ctx);
29
30extern const struct vb2_mem_ops vb2_dma_contig_memops;
31
32#endif
diff --git a/include/media/videobuf2-dma-sg.h b/include/media/videobuf2-dma-sg.h
new file mode 100644
index 000000000000..0038526b8ef7
--- /dev/null
+++ b/include/media/videobuf2-dma-sg.h
@@ -0,0 +1,32 @@
1/*
2 * videobuf2-dma-sg.h - DMA scatter/gather memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
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.
11 */
12
13#ifndef _MEDIA_VIDEOBUF2_DMA_SG_H
14#define _MEDIA_VIDEOBUF2_DMA_SG_H
15
16#include <media/videobuf2-core.h>
17
18struct vb2_dma_sg_desc {
19 unsigned long size;
20 unsigned int num_pages;
21 struct scatterlist *sglist;
22};
23
24static inline struct vb2_dma_sg_desc *vb2_dma_sg_plane_desc(
25 struct vb2_buffer *vb, unsigned int plane_no)
26{
27 return (struct vb2_dma_sg_desc *)vb2_plane_cookie(vb, plane_no);
28}
29
30extern const struct vb2_mem_ops vb2_dma_sg_memops;
31
32#endif
diff --git a/include/media/videobuf2-memops.h b/include/media/videobuf2-memops.h
new file mode 100644
index 000000000000..84e1f6c031c5
--- /dev/null
+++ b/include/media/videobuf2-memops.h
@@ -0,0 +1,45 @@
1/*
2 * videobuf2-memops.h - generic memory handling routines for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
7 * Marek Szyprowski <m.szyprowski@samsung.com>
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.
12 */
13
14#ifndef _MEDIA_VIDEOBUF2_MEMOPS_H
15#define _MEDIA_VIDEOBUF2_MEMOPS_H
16
17#include <media/videobuf2-core.h>
18
19/**
20 * vb2_vmarea_handler - common vma refcount tracking handler
21 * @refcount: pointer to refcount entry in the buffer
22 * @put: callback to function that decreases buffer refcount
23 * @arg: argument for @put callback
24 */
25struct vb2_vmarea_handler {
26 atomic_t *refcount;
27 void (*put)(void *arg);
28 void *arg;
29};
30
31extern const struct vm_operations_struct vb2_common_vm_ops;
32
33int vb2_get_contig_userptr(unsigned long vaddr, unsigned long size,
34 struct vm_area_struct **res_vma, dma_addr_t *res_pa);
35
36int vb2_mmap_pfn_range(struct vm_area_struct *vma, unsigned long paddr,
37 unsigned long size,
38 const struct vm_operations_struct *vm_ops,
39 void *priv);
40
41struct vm_area_struct *vb2_get_vma(struct vm_area_struct *vma);
42void vb2_put_vma(struct vm_area_struct *vma);
43
44
45#endif
diff --git a/include/media/videobuf2-vmalloc.h b/include/media/videobuf2-vmalloc.h
new file mode 100644
index 000000000000..93a76b43038d
--- /dev/null
+++ b/include/media/videobuf2-vmalloc.h
@@ -0,0 +1,20 @@
1/*
2 * videobuf2-vmalloc.h - vmalloc memory allocator for videobuf2
3 *
4 * Copyright (C) 2010 Samsung Electronics
5 *
6 * Author: Pawel Osciak <pawel@osciak.com>
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.
11 */
12
13#ifndef _MEDIA_VIDEOBUF2_VMALLOC_H
14#define _MEDIA_VIDEOBUF2_VMALLOC_H
15
16#include <media/videobuf2-core.h>
17
18extern const struct vb2_mem_ops vb2_vmalloc_memops;
19
20#endif
diff --git a/include/media/wm8775.h b/include/media/wm8775.h
index 60739c5a23ae..d0e801a9935c 100644
--- a/include/media/wm8775.h
+++ b/include/media/wm8775.h
@@ -32,4 +32,13 @@
32#define WM8775_AIN3 4 32#define WM8775_AIN3 4
33#define WM8775_AIN4 8 33#define WM8775_AIN4 8
34 34
35
36struct wm8775_platform_data {
37 /*
38 * FIXME: Instead, we should parametrize the params
39 * that need different settings between ivtv, pvrusb2, and Nova-S
40 */
41 bool is_nova_s;
42};
43
35#endif 44#endif
diff --git a/include/staging/altera.h b/include/staging/altera.h
new file mode 100644
index 000000000000..94c0c6181daf
--- /dev/null
+++ b/include/staging/altera.h
@@ -0,0 +1,49 @@
1/*
2 * altera.h
3 *
4 * altera FPGA driver
5 *
6 * Copyright (C) Altera Corporation 1998-2001
7 * Copyright (C) 2010 NetUP Inc.
8 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
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 * (at your option) 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 *
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26#ifndef _ALTERA_H_
27#define _ALTERA_H_
28
29struct altera_config {
30 void *dev;
31 u8 *action;
32 int (*jtag_io) (void *dev, int tms, int tdi, int tdo);
33};
34
35#if defined(CONFIG_ALTERA_STAPL) || \
36 (defined(CONFIG_ALTERA_STAPL_MODULE) && defined(MODULE))
37
38extern int altera_init(struct altera_config *config, const struct firmware *fw);
39#else
40
41static inline int altera_init(struct altera_config *config,
42 const struct firmware *fw)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return 0;
46}
47#endif /* CONFIG_ALTERA_STAPL */
48
49#endif /* _ALTERA_H_ */
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index d63c1754e05f..6943e24a74a1 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -51,7 +51,7 @@ config SND_SOC_ALL_CODECS
51 select SND_SOC_TWL6040 if TWL4030_CORE 51 select SND_SOC_TWL6040 if TWL4030_CORE
52 select SND_SOC_UDA134X 52 select SND_SOC_UDA134X
53 select SND_SOC_UDA1380 if I2C 53 select SND_SOC_UDA1380 if I2C
54 select SND_SOC_WL1273 if RADIO_WL1273 54 select SND_SOC_WL1273 if MFD_WL1273_CORE
55 select SND_SOC_WM2000 if I2C 55 select SND_SOC_WM2000 if I2C
56 select SND_SOC_WM8350 if MFD_WM8350 56 select SND_SOC_WM8350 if MFD_WM8350
57 select SND_SOC_WM8400 if MFD_WM8400 57 select SND_SOC_WM8400 if MFD_WM8400
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c
index 1ad0d5aecece..c8a874d0d4ca 100644
--- a/sound/soc/codecs/wl1273.c
+++ b/sound/soc/codecs/wl1273.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com> 4 * Author: Matti Aaltonen, <matti.j.aaltonen@nokia.com>
5 * 5 *
6 * Copyright: (C) 2010 Nokia Corporation 6 * Copyright: (C) 2010, 2011 Nokia Corporation
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
@@ -179,7 +179,12 @@ static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol,
179 return 0; 179 return 0;
180} 180}
181 181
182static const char *wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" }; 182/*
183 * TODO: Implement the audio routing in the driver. Now this control
184 * only indicates the setting that has been done elsewhere (in the user
185 * space).
186 */
187static const char * const wl1273_audio_route[] = { "Bt", "FmRx", "FmTx" };
183 188
184static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, 189static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol,
185 struct snd_ctl_elem_value *ucontrol) 190 struct snd_ctl_elem_value *ucontrol)
@@ -239,7 +244,7 @@ static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol,
239 return 1; 244 return 1;
240} 245}
241 246
242static const char *wl1273_audio_strings[] = { "Digital", "Analog" }; 247static const char * const wl1273_audio_strings[] = { "Digital", "Analog" };
243 248
244static const struct soc_enum wl1273_audio_enum = 249static const struct soc_enum wl1273_audio_enum =
245 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings), 250 SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(wl1273_audio_strings),