aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-11-04 10:58:25 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-11-04 10:58:25 -0400
commit1046a2c428bedd64c960dcfd0c57cc69a82fea2f (patch)
treed34b83e0ac61b51305cece031f7ff49579e3fe76 /drivers
parent46e85f5f1c2a1d106c1ec0fa2a06280276b8e052 (diff)
parentb3f4e1eba45eda5d1213810ef3bc53e5247df2df (diff)
Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (144 commits) [media] saa7134.h: Suppress compiler warnings when CONFIG_VIDEO_SAA7134_RC is not set [media] it913x [VER 1.07] Support for single ITE 9135 devices [media] Support for Terratec G1 [media] cx25821: off by one in cx25821_vidioc_s_input() [media] media: tea5764: reconcile Kconfig symbol and macro [media] omap_vout: Add poll() support [media] omap3isp: preview: Add crop support on the sink pad [media] omap3isp: preview: Rename min/max input/output sizes defines [media] omap3isp: preview: Remove horizontal averager support [media] omap3isp: Report the ISP revision through the media controller API [media] omap3isp: ccdc: remove redundant operation [media] omap3isp: Fix memory leaks in initialization error paths [media] omap3isp: Add missing mutex_destroy() calls [media] omap3isp: Move *_init_entities() functions to the init/cleanup section [media] omap3isp: Move media_entity_cleanup() from unregister() to cleanup() [media] MFC: Change MFC firmware binary name [media] vb2: add vb2_get_unmapped_area in vb2 core [media] v4l: Add v4l2 subdev driver for S5K6AAFX sensor [media] v4l: Add AUTO option for the V4L2_CID_POWER_LINE_FREQUENCY control [media] media: ov6650: stylistic improvements ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/dma/ipu/ipu_idmac.c65
-rw-r--r--drivers/media/dvb/ddbridge/Makefile2
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile1
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h2
-rw-r--r--drivers/media/dvb/dvb-usb/it913x.c105
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf-demod.c614
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf-demod.h55
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.c228
-rw-r--r--drivers/media/dvb/dvb-usb/mxl111sf.h2
-rw-r--r--drivers/media/dvb/ngene/Makefile2
-rw-r--r--drivers/media/radio/radio-tea5764.c4
-rw-r--r--drivers/media/video/Kconfig9
-rw-r--r--drivers/media/video/Makefile2
-rw-r--r--drivers/media/video/atmel-isi.c142
-rw-r--r--drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--drivers/media/video/cx25821/Kconfig (renamed from drivers/staging/cx25821/Kconfig)0
-rw-r--r--drivers/media/video/cx25821/Makefile (renamed from drivers/staging/cx25821/Makefile)0
-rw-r--r--drivers/media/video/cx25821/cx25821-alsa.c (renamed from drivers/staging/cx25821/cx25821-alsa.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.c (renamed from drivers/staging/cx25821/cx25821-audio-upstream.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-audio-upstream.h (renamed from drivers/staging/cx25821/cx25821-audio-upstream.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-audio.h (renamed from drivers/staging/cx25821/cx25821-audio.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-biffuncs.h (renamed from drivers/staging/cx25821/cx25821-biffuncs.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-cards.c (renamed from drivers/staging/cx25821/cx25821-cards.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-core.c (renamed from drivers/staging/cx25821/cx25821-core.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-gpio.c (renamed from drivers/staging/cx25821/cx25821-gpio.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-i2c.c (renamed from drivers/staging/cx25821/cx25821-i2c.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-defines.h (renamed from drivers/staging/cx25821/cx25821-medusa-defines.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-reg.h (renamed from drivers/staging/cx25821/cx25821-medusa-reg.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.c (renamed from drivers/staging/cx25821/cx25821-medusa-video.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-medusa-video.h (renamed from drivers/staging/cx25821/cx25821-medusa-video.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-reg.h (renamed from drivers/staging/cx25821/cx25821-reg.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-sram.h (renamed from drivers/staging/cx25821/cx25821-sram.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.c (renamed from drivers/staging/cx25821/cx25821-video-upstream-ch2.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream-ch2.h (renamed from drivers/staging/cx25821/cx25821-video-upstream-ch2.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.c (renamed from drivers/staging/cx25821/cx25821-video-upstream.c)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video-upstream.h (renamed from drivers/staging/cx25821/cx25821-video-upstream.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821-video.c (renamed from drivers/staging/cx25821/cx25821-video.c)2
-rw-r--r--drivers/media/video/cx25821/cx25821-video.h (renamed from drivers/staging/cx25821/cx25821-video.h)0
-rw-r--r--drivers/media/video/cx25821/cx25821.h (renamed from drivers/staging/cx25821/cx25821.h)3
-rw-r--r--drivers/media/video/em28xx/em28xx-cards.c2
-rw-r--r--drivers/media/video/imx074.c54
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c2
-rw-r--r--drivers/media/video/marvell-ccic/mcam-core.c3
-rw-r--r--drivers/media/video/mem2mem_testdev.c7
-rw-r--r--drivers/media/video/mt9m001.c328
-rw-r--r--drivers/media/video/mt9m111.c260
-rw-r--r--drivers/media/video/mt9t031.c347
-rw-r--r--drivers/media/video/mt9t112.c269
-rw-r--r--drivers/media/video/mt9v022.c447
-rw-r--r--drivers/media/video/mx1_camera.c71
-rw-r--r--drivers/media/video/mx2_camera.c78
-rw-r--r--drivers/media/video/mx3_camera.c359
-rw-r--r--drivers/media/video/omap/omap_vout.c10
-rw-r--r--drivers/media/video/omap1_camera.c62
-rw-r--r--drivers/media/video/omap3isp/isp.c3
-rw-r--r--drivers/media/video/omap3isp/ispccdc.c86
-rw-r--r--drivers/media/video/omap3isp/ispccp2.c125
-rw-r--r--drivers/media/video/omap3isp/ispcsi2.c91
-rw-r--r--drivers/media/video/omap3isp/isph3a_aewb.c2
-rw-r--r--drivers/media/video/omap3isp/isph3a_af.c2
-rw-r--r--drivers/media/video/omap3isp/isphist.c2
-rw-r--r--drivers/media/video/omap3isp/isppreview.c419
-rw-r--r--drivers/media/video/omap3isp/isppreview.h9
-rw-r--r--drivers/media/video/omap3isp/ispreg.h3
-rw-r--r--drivers/media/video/omap3isp/ispresizer.c104
-rw-r--r--drivers/media/video/omap3isp/ispstat.c52
-rw-r--r--drivers/media/video/omap3isp/ispstat.h2
-rw-r--r--drivers/media/video/omap3isp/ispvideo.c11
-rw-r--r--drivers/media/video/omap3isp/ispvideo.h1
-rw-r--r--drivers/media/video/ov2640.c178
-rw-r--r--drivers/media/video/ov5642.c288
-rw-r--r--drivers/media/video/ov6650.c504
-rw-r--r--drivers/media/video/ov772x.c198
-rw-r--r--drivers/media/video/ov9640.c186
-rw-r--r--drivers/media/video/ov9640.h4
-rw-r--r--drivers/media/video/ov9740.c151
-rw-r--r--drivers/media/video/pwc/pwc-if.c6
-rw-r--r--drivers/media/video/pxa_camera.c140
-rw-r--r--drivers/media/video/rj54n1cb0c.c223
-rw-r--r--drivers/media/video/s5k6aa.c1680
-rw-r--r--drivers/media/video/s5p-fimc/fimc-capture.c6
-rw-r--r--drivers/media/video/s5p-fimc/fimc-core.c6
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c4
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_dec.c7
-rw-r--r--drivers/media/video/s5p-mfc/s5p_mfc_enc.c5
-rw-r--r--drivers/media/video/s5p-tv/mixer_video.c4
-rw-r--r--drivers/media/video/saa7134/saa7134.h12
-rw-r--r--drivers/media/video/sh_mobile_ceu_camera.c491
-rw-r--r--drivers/media/video/sh_mobile_csi2.c132
-rw-r--r--drivers/media/video/soc_camera.c273
-rw-r--r--drivers/media/video/soc_camera_platform.c45
-rw-r--r--drivers/media/video/soc_mediabus.c33
-rw-r--r--drivers/media/video/tw9910.c268
-rw-r--r--drivers/media/video/v4l2-compat-ioctl32.c76
-rw-r--r--drivers/media/video/v4l2-ctrls.c1
-rw-r--r--drivers/media/video/v4l2-device.c36
-rw-r--r--drivers/media/video/v4l2-ioctl.c36
-rw-r--r--drivers/media/video/videobuf2-core.c391
-rw-r--r--drivers/media/video/vivi.c6
-rw-r--r--drivers/staging/Kconfig16
-rw-r--r--drivers/staging/Makefile8
-rw-r--r--drivers/staging/cx25821/README6
-rw-r--r--drivers/staging/media/Kconfig37
-rw-r--r--drivers/staging/media/Makefile7
-rw-r--r--drivers/staging/media/as102/Kconfig7
-rw-r--r--drivers/staging/media/as102/Makefile6
-rw-r--r--drivers/staging/media/as102/as102_drv.c351
-rw-r--r--drivers/staging/media/as102/as102_drv.h141
-rw-r--r--drivers/staging/media/as102/as102_fe.c603
-rw-r--r--drivers/staging/media/as102/as102_fw.c251
-rw-r--r--drivers/staging/media/as102/as102_fw.h42
-rw-r--r--drivers/staging/media/as102/as102_usb_drv.c478
-rw-r--r--drivers/staging/media/as102/as102_usb_drv.h59
-rw-r--r--drivers/staging/media/as102/as10x_cmd.c452
-rw-r--r--drivers/staging/media/as102/as10x_cmd.h540
-rw-r--r--drivers/staging/media/as102/as10x_cmd_cfg.c215
-rw-r--r--drivers/staging/media/as102/as10x_cmd_stream.c223
-rw-r--r--drivers/staging/media/as102/as10x_handle.h58
-rw-r--r--drivers/staging/media/as102/as10x_types.h198
-rw-r--r--drivers/staging/media/cxd2099/Kconfig (renamed from drivers/staging/cxd2099/Kconfig)0
-rw-r--r--drivers/staging/media/cxd2099/Makefile (renamed from drivers/staging/cxd2099/Makefile)0
-rw-r--r--drivers/staging/media/cxd2099/TODO (renamed from drivers/staging/cxd2099/TODO)0
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.c (renamed from drivers/staging/cxd2099/cxd2099.c)0
-rw-r--r--drivers/staging/media/cxd2099/cxd2099.h (renamed from drivers/staging/cxd2099/cxd2099.h)0
-rw-r--r--drivers/staging/media/dt3155v4l/Kconfig (renamed from drivers/staging/dt3155v4l/Kconfig)0
-rw-r--r--drivers/staging/media/dt3155v4l/Makefile (renamed from drivers/staging/dt3155v4l/Makefile)0
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.c (renamed from drivers/staging/dt3155v4l/dt3155v4l.c)0
-rw-r--r--drivers/staging/media/dt3155v4l/dt3155v4l.h (renamed from drivers/staging/dt3155v4l/dt3155v4l.h)0
-rw-r--r--drivers/staging/media/easycap/Kconfig (renamed from drivers/staging/easycap/Kconfig)0
-rw-r--r--drivers/staging/media/easycap/Makefile (renamed from drivers/staging/easycap/Makefile)0
-rw-r--r--drivers/staging/media/easycap/README (renamed from drivers/staging/easycap/README)0
-rw-r--r--drivers/staging/media/easycap/easycap.h (renamed from drivers/staging/easycap/easycap.h)0
-rw-r--r--drivers/staging/media/easycap/easycap_ioctl.c (renamed from drivers/staging/easycap/easycap_ioctl.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_low.c (renamed from drivers/staging/easycap/easycap_low.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_main.c (renamed from drivers/staging/easycap/easycap_main.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_settings.c (renamed from drivers/staging/easycap/easycap_settings.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_sound.c (renamed from drivers/staging/easycap/easycap_sound.c)0
-rw-r--r--drivers/staging/media/easycap/easycap_testcard.c (renamed from drivers/staging/easycap/easycap_testcard.c)0
-rw-r--r--drivers/staging/media/go7007/Kconfig (renamed from drivers/staging/go7007/Kconfig)0
-rw-r--r--drivers/staging/media/go7007/Makefile (renamed from drivers/staging/go7007/Makefile)0
-rw-r--r--drivers/staging/media/go7007/README (renamed from drivers/staging/go7007/README)0
-rw-r--r--drivers/staging/media/go7007/go7007-driver.c (renamed from drivers/staging/go7007/go7007-driver.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-fw.c (renamed from drivers/staging/go7007/go7007-fw.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-i2c.c (renamed from drivers/staging/go7007/go7007-i2c.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-priv.h (renamed from drivers/staging/go7007/go7007-priv.h)0
-rw-r--r--drivers/staging/media/go7007/go7007-usb.c (renamed from drivers/staging/go7007/go7007-usb.c)0
-rw-r--r--drivers/staging/media/go7007/go7007-v4l2.c (renamed from drivers/staging/go7007/go7007-v4l2.c)0
-rw-r--r--drivers/staging/media/go7007/go7007.h (renamed from drivers/staging/go7007/go7007.h)0
-rw-r--r--drivers/staging/media/go7007/go7007.txt (renamed from drivers/staging/go7007/go7007.txt)0
-rw-r--r--drivers/staging/media/go7007/s2250-board.c (renamed from drivers/staging/go7007/s2250-board.c)0
-rw-r--r--drivers/staging/media/go7007/s2250-loader.c (renamed from drivers/staging/go7007/s2250-loader.c)0
-rw-r--r--drivers/staging/media/go7007/s2250-loader.h (renamed from drivers/staging/go7007/s2250-loader.h)0
-rw-r--r--drivers/staging/media/go7007/saa7134-go7007.c (renamed from drivers/staging/go7007/saa7134-go7007.c)0
-rw-r--r--drivers/staging/media/go7007/snd-go7007.c (renamed from drivers/staging/go7007/snd-go7007.c)0
-rw-r--r--drivers/staging/media/go7007/wis-i2c.h (renamed from drivers/staging/go7007/wis-i2c.h)0
-rw-r--r--drivers/staging/media/go7007/wis-ov7640.c (renamed from drivers/staging/go7007/wis-ov7640.c)0
-rw-r--r--drivers/staging/media/go7007/wis-saa7113.c (renamed from drivers/staging/go7007/wis-saa7113.c)0
-rw-r--r--drivers/staging/media/go7007/wis-saa7115.c (renamed from drivers/staging/go7007/wis-saa7115.c)0
-rw-r--r--drivers/staging/media/go7007/wis-sony-tuner.c (renamed from drivers/staging/go7007/wis-sony-tuner.c)0
-rw-r--r--drivers/staging/media/go7007/wis-tw2804.c (renamed from drivers/staging/go7007/wis-tw2804.c)0
-rw-r--r--drivers/staging/media/go7007/wis-tw9903.c (renamed from drivers/staging/go7007/wis-tw9903.c)0
-rw-r--r--drivers/staging/media/go7007/wis-uda1342.c (renamed from drivers/staging/go7007/wis-uda1342.c)0
-rw-r--r--drivers/staging/media/lirc/Kconfig (renamed from drivers/staging/lirc/Kconfig)0
-rw-r--r--drivers/staging/media/lirc/Makefile (renamed from drivers/staging/lirc/Makefile)0
-rw-r--r--drivers/staging/media/lirc/TODO (renamed from drivers/staging/lirc/TODO)0
-rw-r--r--drivers/staging/media/lirc/TODO.lirc_zilog (renamed from drivers/staging/lirc/TODO.lirc_zilog)0
-rw-r--r--drivers/staging/media/lirc/lirc_bt829.c (renamed from drivers/staging/lirc/lirc_bt829.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_ene0100.h (renamed from drivers/staging/lirc/lirc_ene0100.h)0
-rw-r--r--drivers/staging/media/lirc/lirc_igorplugusb.c (renamed from drivers/staging/lirc/lirc_igorplugusb.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_imon.c (renamed from drivers/staging/lirc/lirc_imon.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.c (renamed from drivers/staging/lirc/lirc_parallel.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_parallel.h (renamed from drivers/staging/lirc/lirc_parallel.h)0
-rw-r--r--drivers/staging/media/lirc/lirc_sasem.c (renamed from drivers/staging/lirc/lirc_sasem.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_serial.c (renamed from drivers/staging/lirc/lirc_serial.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_sir.c (renamed from drivers/staging/lirc/lirc_sir.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_ttusbir.c (renamed from drivers/staging/lirc/lirc_ttusbir.c)0
-rw-r--r--drivers/staging/media/lirc/lirc_zilog.c (renamed from drivers/staging/lirc/lirc_zilog.c)0
-rw-r--r--drivers/staging/media/solo6x10/Kconfig (renamed from drivers/staging/solo6x10/Kconfig)0
-rw-r--r--drivers/staging/media/solo6x10/Makefile (renamed from drivers/staging/solo6x10/Makefile)0
-rw-r--r--drivers/staging/media/solo6x10/TODO (renamed from drivers/staging/solo6x10/TODO)0
-rw-r--r--drivers/staging/media/solo6x10/core.c (renamed from drivers/staging/solo6x10/core.c)0
-rw-r--r--drivers/staging/media/solo6x10/disp.c (renamed from drivers/staging/solo6x10/disp.c)0
-rw-r--r--drivers/staging/media/solo6x10/enc.c (renamed from drivers/staging/solo6x10/enc.c)0
-rw-r--r--drivers/staging/media/solo6x10/g723.c (renamed from drivers/staging/solo6x10/g723.c)0
-rw-r--r--drivers/staging/media/solo6x10/gpio.c (renamed from drivers/staging/solo6x10/gpio.c)0
-rw-r--r--drivers/staging/media/solo6x10/i2c.c (renamed from drivers/staging/solo6x10/i2c.c)0
-rw-r--r--drivers/staging/media/solo6x10/jpeg.h (renamed from drivers/staging/solo6x10/jpeg.h)0
-rw-r--r--drivers/staging/media/solo6x10/offsets.h (renamed from drivers/staging/solo6x10/offsets.h)0
-rw-r--r--drivers/staging/media/solo6x10/osd-font.h (renamed from drivers/staging/solo6x10/osd-font.h)0
-rw-r--r--drivers/staging/media/solo6x10/p2m.c (renamed from drivers/staging/solo6x10/p2m.c)0
-rw-r--r--drivers/staging/media/solo6x10/registers.h (renamed from drivers/staging/solo6x10/registers.h)0
-rw-r--r--drivers/staging/media/solo6x10/solo6x10.h (renamed from drivers/staging/solo6x10/solo6x10.h)0
-rw-r--r--drivers/staging/media/solo6x10/tw28.c (renamed from drivers/staging/solo6x10/tw28.c)0
-rw-r--r--drivers/staging/media/solo6x10/tw28.h (renamed from drivers/staging/solo6x10/tw28.h)0
-rw-r--r--drivers/staging/media/solo6x10/v4l2-enc.c (renamed from drivers/staging/solo6x10/v4l2-enc.c)0
-rw-r--r--drivers/staging/media/solo6x10/v4l2.c (renamed from drivers/staging/solo6x10/v4l2.c)0
196 files changed, 9875 insertions, 3664 deletions
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index 6815905a772..ddc2a133182 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1307,6 +1307,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
1307 ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) { 1307 ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
1308 callback = descnew->txd.callback; 1308 callback = descnew->txd.callback;
1309 callback_param = descnew->txd.callback_param; 1309 callback_param = descnew->txd.callback_param;
1310 list_del_init(&descnew->list);
1310 spin_unlock(&ichan->lock); 1311 spin_unlock(&ichan->lock);
1311 if (callback) 1312 if (callback)
1312 callback(callback_param); 1313 callback(callback_param);
@@ -1428,39 +1429,58 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
1428{ 1429{
1429 struct idmac_channel *ichan = to_idmac_chan(chan); 1430 struct idmac_channel *ichan = to_idmac_chan(chan);
1430 struct idmac *idmac = to_idmac(chan->device); 1431 struct idmac *idmac = to_idmac(chan->device);
1432 struct ipu *ipu = to_ipu(idmac);
1433 struct list_head *list, *tmp;
1431 unsigned long flags; 1434 unsigned long flags;
1432 int i; 1435 int i;
1433 1436
1434 /* Only supports DMA_TERMINATE_ALL */ 1437 switch (cmd) {
1435 if (cmd != DMA_TERMINATE_ALL) 1438 case DMA_PAUSE:
1436 return -ENXIO; 1439 spin_lock_irqsave(&ipu->lock, flags);
1440 ipu_ic_disable_task(ipu, chan->chan_id);
1437 1441
1438 ipu_disable_channel(idmac, ichan, 1442 /* Return all descriptors into "prepared" state */
1439 ichan->status >= IPU_CHANNEL_ENABLED); 1443 list_for_each_safe(list, tmp, &ichan->queue)
1444 list_del_init(list);
1440 1445
1441 tasklet_disable(&to_ipu(idmac)->tasklet); 1446 ichan->sg[0] = NULL;
1447 ichan->sg[1] = NULL;
1442 1448
1443 /* ichan->queue is modified in ISR, have to spinlock */ 1449 spin_unlock_irqrestore(&ipu->lock, flags);
1444 spin_lock_irqsave(&ichan->lock, flags);
1445 list_splice_init(&ichan->queue, &ichan->free_list);
1446 1450
1447 if (ichan->desc) 1451 ichan->status = IPU_CHANNEL_INITIALIZED;
1448 for (i = 0; i < ichan->n_tx_desc; i++) { 1452 break;
1449 struct idmac_tx_desc *desc = ichan->desc + i; 1453 case DMA_TERMINATE_ALL:
1450 if (list_empty(&desc->list)) 1454 ipu_disable_channel(idmac, ichan,
1451 /* Descriptor was prepared, but not submitted */ 1455 ichan->status >= IPU_CHANNEL_ENABLED);
1452 list_add(&desc->list, &ichan->free_list);
1453 1456
1454 async_tx_clear_ack(&desc->txd); 1457 tasklet_disable(&ipu->tasklet);
1455 }
1456 1458
1457 ichan->sg[0] = NULL; 1459 /* ichan->queue is modified in ISR, have to spinlock */
1458 ichan->sg[1] = NULL; 1460 spin_lock_irqsave(&ichan->lock, flags);
1459 spin_unlock_irqrestore(&ichan->lock, flags); 1461 list_splice_init(&ichan->queue, &ichan->free_list);
1460 1462
1461 tasklet_enable(&to_ipu(idmac)->tasklet); 1463 if (ichan->desc)
1464 for (i = 0; i < ichan->n_tx_desc; i++) {
1465 struct idmac_tx_desc *desc = ichan->desc + i;
1466 if (list_empty(&desc->list))
1467 /* Descriptor was prepared, but not submitted */
1468 list_add(&desc->list, &ichan->free_list);
1462 1469
1463 ichan->status = IPU_CHANNEL_INITIALIZED; 1470 async_tx_clear_ack(&desc->txd);
1471 }
1472
1473 ichan->sg[0] = NULL;
1474 ichan->sg[1] = NULL;
1475 spin_unlock_irqrestore(&ichan->lock, flags);
1476
1477 tasklet_enable(&ipu->tasklet);
1478
1479 ichan->status = IPU_CHANNEL_INITIALIZED;
1480 break;
1481 default:
1482 return -ENOSYS;
1483 }
1464 1484
1465 return 0; 1485 return 0;
1466} 1486}
@@ -1663,7 +1683,6 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
1663 struct idmac_channel *ichan = ipu->channel + i; 1683 struct idmac_channel *ichan = ipu->channel + i;
1664 1684
1665 idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0); 1685 idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0);
1666 idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
1667 } 1686 }
1668 1687
1669 dma_async_device_unregister(&idmac->dma); 1688 dma_async_device_unregister(&idmac->dma);
diff --git a/drivers/media/dvb/ddbridge/Makefile b/drivers/media/dvb/ddbridge/Makefile
index cf7214edf65..38019bafb86 100644
--- a/drivers/media/dvb/ddbridge/Makefile
+++ b/drivers/media/dvb/ddbridge/Makefile
@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
11ccflags-y += -Idrivers/media/common/tuners/ 11ccflags-y += -Idrivers/media/common/tuners/
12 12
13# For the staging CI driver cxd2099 13# For the staging CI driver cxd2099
14ccflags-y += -Idrivers/staging/cxd2099/ 14ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 7d0710bb197..26c8b9e5705 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -102,6 +102,7 @@ obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
102 102
103dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o 103dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
104obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o 104obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
105obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
105obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o 106obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
106 107
107ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/ 108ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 2ad33ba92ba..2d08c9b5128 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -37,6 +37,7 @@
37#define USB_VID_HAUPPAUGE 0x2040 37#define USB_VID_HAUPPAUGE 0x2040
38#define USB_VID_HYPER_PALTEK 0x1025 38#define USB_VID_HYPER_PALTEK 0x1025
39#define USB_VID_INTEL 0x8086 39#define USB_VID_INTEL 0x8086
40#define USB_VID_ITETECH 0x048d
40#define USB_VID_KWORLD 0xeb2a 41#define USB_VID_KWORLD 0xeb2a
41#define USB_VID_KWORLD_2 0x1b80 42#define USB_VID_KWORLD_2 0x1b80
42#define USB_VID_KYE 0x0458 43#define USB_VID_KYE 0x0458
@@ -126,6 +127,7 @@
126#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0 127#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
127#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1 128#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
128#define USB_PID_INTEL_CE9500 0x9500 129#define USB_PID_INTEL_CE9500 0x9500
130#define USB_PID_ITETECH_IT9135 0x9135
129#define USB_PID_KWORLD_399U 0xe399 131#define USB_PID_KWORLD_399U 0xe399
130#define USB_PID_KWORLD_399U_2 0xe400 132#define USB_PID_KWORLD_399U_2 0xe400
131#define USB_PID_KWORLD_395U 0xe396 133#define USB_PID_KWORLD_395U 0xe396
diff --git a/drivers/media/dvb/dvb-usb/it913x.c b/drivers/media/dvb/dvb-usb/it913x.c
index f027a2c1c3e..c4622618714 100644
--- a/drivers/media/dvb/dvb-usb/it913x.c
+++ b/drivers/media/dvb/dvb-usb/it913x.c
@@ -60,6 +60,17 @@ struct it913x_state {
60 u8 id; 60 u8 id;
61}; 61};
62 62
63struct ite_config {
64 u8 chip_ver;
65 u16 chip_type;
66 u32 firmware;
67 u8 tuner_id_0;
68 u8 tuner_id_1;
69 u8 dual_mode;
70};
71
72struct ite_config it913x_config;
73
63static int it913x_bulk_write(struct usb_device *dev, 74static int it913x_bulk_write(struct usb_device *dev,
64 u8 *snd, int len, u8 pipe) 75 u8 *snd, int len, u8 pipe)
65{ 76{
@@ -191,18 +202,23 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg)
191static u32 it913x_query(struct usb_device *udev, u8 pro) 202static u32 it913x_query(struct usb_device *udev, u8 pro)
192{ 203{
193 int ret; 204 int ret;
194 u32 res = 0;
195 u8 data[4]; 205 u8 data[4];
196 ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ, 206 ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
197 0x1222, 0, &data[0], 1); 207 0x1222, 0, &data[0], 3);
198 if (data[0] == 0x1) { 208
199 ret = it913x_io(udev, READ_SHORT, pro, 209 it913x_config.chip_ver = data[0];
210 it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
211
212 info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
213 it913x_config.chip_type);
214
215 ret |= it913x_io(udev, READ_SHORT, pro,
200 CMD_QUERYINFO, 0, 0x1, &data[0], 4); 216 CMD_QUERYINFO, 0, 0x1, &data[0], 4);
201 res = (data[0] << 24) + (data[1] << 16) + 217
218 it913x_config.firmware = (data[0] << 24) + (data[1] << 16) +
202 (data[2] << 8) + data[3]; 219 (data[2] << 8) + data[3];
203 }
204 220
205 return (ret < 0) ? 0 : res; 221 return (ret < 0) ? 0 : it913x_config.firmware;
206} 222}
207 223
208static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff) 224static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
@@ -336,26 +352,35 @@ static int it913x_identify_state(struct usb_device *udev,
336 int *cold) 352 int *cold)
337{ 353{
338 int ret = 0, firm_no; 354 int ret = 0, firm_no;
339 u8 reg, adap, ep, tun0, tun1; 355 u8 reg, remote;
340 356
341 firm_no = it913x_return_status(udev); 357 firm_no = it913x_return_status(udev);
342 358
343 ep = it913x_read_reg(udev, 0x49ac); 359 /* checnk for dual mode */
344 adap = it913x_read_reg(udev, 0x49c5); 360 it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5);
345 tun0 = it913x_read_reg(udev, 0x49d0); 361
346 info("No. Adapters=%x Endpoints=%x Tuner Type=%x", adap, ep, tun0); 362 /* TODO different remotes */
363 remote = it913x_read_reg(udev, 0x49ac); /* Remote */
364 if (remote == 0)
365 props->rc.core.rc_codes = NULL;
366
367 /* TODO at the moment tuner_id is always assigned to 0x38 */
368 it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
369
370 info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
371 , remote, it913x_config.tuner_id_0);
347 372
348 if (firm_no > 0) { 373 if (firm_no > 0) {
349 *cold = 0; 374 *cold = 0;
350 return 0; 375 return 0;
351 } 376 }
352 377
353 if (adap > 2) { 378 if (it913x_config.dual_mode) {
354 tun1 = it913x_read_reg(udev, 0x49e0); 379 it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0);
355 ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1); 380 ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1);
356 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1); 381 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1);
357 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1); 382 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1);
358 msleep(50); /* Delay noticed reset cycle ? */ 383 msleep(50);
359 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0); 384 ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0);
360 msleep(50); 385 msleep(50);
361 reg = it913x_read_reg(udev, GPIOH1_O); 386 reg = it913x_read_reg(udev, GPIOH1_O);
@@ -366,14 +391,19 @@ static int it913x_identify_state(struct usb_device *udev,
366 ret = it913x_wr_reg(udev, DEV_0, 391 ret = it913x_wr_reg(udev, DEV_0,
367 GPIOH1_O, 0x0); 392 GPIOH1_O, 0x0);
368 } 393 }
394 props->num_adapters = 2;
369 } else 395 } else
370 props->num_adapters = 1; 396 props->num_adapters = 1;
371 397
372 reg = it913x_read_reg(udev, IO_MUX_POWER_CLK); 398 reg = it913x_read_reg(udev, IO_MUX_POWER_CLK);
373 399
374 ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR); 400 if (it913x_config.dual_mode) {
375 401 ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
376 ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1); 402 ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1);
403 } else {
404 ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0);
405 ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0);
406 }
377 407
378 *cold = 1; 408 *cold = 1;
379 409
@@ -403,13 +433,11 @@ static int it913x_download_firmware(struct usb_device *udev,
403 const struct firmware *fw) 433 const struct firmware *fw)
404{ 434{
405 int ret = 0, i; 435 int ret = 0, i;
406 u8 packet_size, dlen, tun1; 436 u8 packet_size, dlen;
407 u8 *fw_data; 437 u8 *fw_data;
408 438
409 packet_size = 0x29; 439 packet_size = 0x29;
410 440
411 tun1 = it913x_read_reg(udev, 0x49e0);
412
413 ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100); 441 ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100);
414 442
415 info("FRM Starting Firmware Download"); 443 info("FRM Starting Firmware Download");
@@ -444,11 +472,12 @@ static int it913x_download_firmware(struct usb_device *udev,
444 ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400); 472 ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400);
445 473
446 /* Tuner function */ 474 /* Tuner function */
447 ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0); 475 if (it913x_config.dual_mode)
476 ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
448 477
449 ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0); 478 ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0);
450 ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0); 479 ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0);
451 if (tun1 > 0) { 480 if (it913x_config.dual_mode) {
452 ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0); 481 ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0);
453 ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0); 482 ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0);
454 } 483 }
@@ -475,9 +504,28 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
475 u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK); 504 u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
476 u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5); 505 u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
477 u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize; 506 u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize;
507 u8 tuner_id, tuner_type;
508
509 if (adap->id == 0)
510 tuner_id = it913x_config.tuner_id_0;
511 else
512 tuner_id = it913x_config.tuner_id_1;
513
514 /* TODO we always use IT9137 possible references here*/
515 /* Documentation suggests don't care */
516 switch (tuner_id) {
517 case 0x51:
518 case 0x52:
519 case 0x60:
520 case 0x61:
521 case 0x62:
522 default:
523 case 0x38:
524 tuner_type = IT9137;
525 }
478 526
479 adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach, 527 adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach,
480 &adap->dev->i2c_adap, adap_addr, adf, IT9137); 528 &adap->dev->i2c_adap, adap_addr, adf, tuner_type);
481 529
482 if (adap->id == 0 && adap->fe_adap[0].fe) { 530 if (adap->id == 0 && adap->fe_adap[0].fe) {
483 ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1); 531 ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1);
@@ -533,6 +581,7 @@ static int it913x_probe(struct usb_interface *intf,
533 581
534static struct usb_device_id it913x_table[] = { 582static struct usb_device_id it913x_table[] = {
535 { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) }, 583 { USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) },
584 { USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) },
536 {} /* Terminating entry */ 585 {} /* Terminating entry */
537}; 586};
538 587
@@ -608,12 +657,14 @@ static struct dvb_usb_device_properties it913x_properties = {
608 .rc_codes = RC_MAP_KWORLD_315U, 657 .rc_codes = RC_MAP_KWORLD_315U,
609 }, 658 },
610 .i2c_algo = &it913x_i2c_algo, 659 .i2c_algo = &it913x_i2c_algo,
611 .num_device_descs = 1, 660 .num_device_descs = 2,
612 .devices = { 661 .devices = {
613 { "Kworld UB499-2T T09(IT9137)", 662 { "Kworld UB499-2T T09(IT9137)",
614 { &it913x_table[0], NULL }, 663 { &it913x_table[0], NULL },
615 }, 664 },
616 665 { "ITE 9135 Generic",
666 { &it913x_table[1], NULL },
667 },
617 } 668 }
618}; 669};
619 670
@@ -647,5 +698,5 @@ module_exit(it913x_module_exit);
647 698
648MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>"); 699MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
649MODULE_DESCRIPTION("it913x USB 2 Driver"); 700MODULE_DESCRIPTION("it913x USB 2 Driver");
650MODULE_VERSION("1.06"); 701MODULE_VERSION("1.07");
651MODULE_LICENSE("GPL"); 702MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.c b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
new file mode 100644
index 00000000000..d1f58371c71
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-demod.c
@@ -0,0 +1,614 @@
1/*
2 * mxl111sf-demod.c - driver for the MaxLinear MXL111SF DVB-T demodulator
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "mxl111sf-demod.h"
22#include "mxl111sf-reg.h"
23
24/* debug */
25static int mxl111sf_demod_debug;
26module_param_named(debug, mxl111sf_demod_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debugging level (1=info (or-able)).");
28
29#define mxl_dbg(fmt, arg...) \
30 if (mxl111sf_demod_debug) \
31 mxl_printk(KERN_DEBUG, fmt, ##arg)
32
33/* ------------------------------------------------------------------------ */
34
35struct mxl111sf_demod_state {
36 struct mxl111sf_state *mxl_state;
37
38 struct mxl111sf_demod_config *cfg;
39
40 struct dvb_frontend fe;
41};
42
43/* ------------------------------------------------------------------------ */
44
45static int mxl111sf_demod_read_reg(struct mxl111sf_demod_state *state,
46 u8 addr, u8 *data)
47{
48 return (state->cfg->read_reg) ?
49 state->cfg->read_reg(state->mxl_state, addr, data) :
50 -EINVAL;
51}
52
53static int mxl111sf_demod_write_reg(struct mxl111sf_demod_state *state,
54 u8 addr, u8 data)
55{
56 return (state->cfg->write_reg) ?
57 state->cfg->write_reg(state->mxl_state, addr, data) :
58 -EINVAL;
59}
60
61static
62int mxl111sf_demod_program_regs(struct mxl111sf_demod_state *state,
63 struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
64{
65 return (state->cfg->program_regs) ?
66 state->cfg->program_regs(state->mxl_state, ctrl_reg_info) :
67 -EINVAL;
68}
69
70/* ------------------------------------------------------------------------ */
71/* TPS */
72
73static
74int mxl1x1sf_demod_get_tps_code_rate(struct mxl111sf_demod_state *state,
75 fe_code_rate_t *code_rate)
76{
77 u8 val;
78 int ret = mxl111sf_demod_read_reg(state, V6_CODE_RATE_TPS_REG, &val);
79 /* bit<2:0> - 000:1/2, 001:2/3, 010:3/4, 011:5/6, 100:7/8 */
80 if (mxl_fail(ret))
81 goto fail;
82
83 switch (val & V6_CODE_RATE_TPS_MASK) {
84 case 0:
85 *code_rate = FEC_1_2;
86 break;
87 case 1:
88 *code_rate = FEC_2_3;
89 break;
90 case 2:
91 *code_rate = FEC_3_4;
92 break;
93 case 3:
94 *code_rate = FEC_5_6;
95 break;
96 case 4:
97 *code_rate = FEC_7_8;
98 break;
99 }
100fail:
101 return ret;
102}
103
104static
105int mxl1x1sf_demod_get_tps_constellation(struct mxl111sf_demod_state *state,
106 fe_modulation_t *constellation)
107{
108 u8 val;
109 int ret = mxl111sf_demod_read_reg(state, V6_MODORDER_TPS_REG, &val);
110 /* Constellation, 00 : QPSK, 01 : 16QAM, 10:64QAM */
111 if (mxl_fail(ret))
112 goto fail;
113
114 switch ((val & V6_PARAM_CONSTELLATION_MASK) >> 4) {
115 case 0:
116 *constellation = QPSK;
117 break;
118 case 1:
119 *constellation = QAM_16;
120 break;
121 case 2:
122 *constellation = QAM_64;
123 break;
124 }
125fail:
126 return ret;
127}
128
129static
130int mxl1x1sf_demod_get_tps_guard_fft_mode(struct mxl111sf_demod_state *state,
131 fe_transmit_mode_t *fft_mode)
132{
133 u8 val;
134 int ret = mxl111sf_demod_read_reg(state, V6_MODE_TPS_REG, &val);
135 /* FFT Mode, 00:2K, 01:8K, 10:4K */
136 if (mxl_fail(ret))
137 goto fail;
138
139 switch ((val & V6_PARAM_FFT_MODE_MASK) >> 2) {
140 case 0:
141 *fft_mode = TRANSMISSION_MODE_2K;
142 break;
143 case 1:
144 *fft_mode = TRANSMISSION_MODE_8K;
145 break;
146 case 2:
147 *fft_mode = TRANSMISSION_MODE_4K;
148 break;
149 }
150fail:
151 return ret;
152}
153
154static
155int mxl1x1sf_demod_get_tps_guard_interval(struct mxl111sf_demod_state *state,
156 fe_guard_interval_t *guard)
157{
158 u8 val;
159 int ret = mxl111sf_demod_read_reg(state, V6_CP_TPS_REG, &val);
160 /* 00:1/32, 01:1/16, 10:1/8, 11:1/4 */
161 if (mxl_fail(ret))
162 goto fail;
163
164 switch ((val & V6_PARAM_GI_MASK) >> 4) {
165 case 0:
166 *guard = GUARD_INTERVAL_1_32;
167 break;
168 case 1:
169 *guard = GUARD_INTERVAL_1_16;
170 break;
171 case 2:
172 *guard = GUARD_INTERVAL_1_8;
173 break;
174 case 3:
175 *guard = GUARD_INTERVAL_1_4;
176 break;
177 }
178fail:
179 return ret;
180}
181
182static
183int mxl1x1sf_demod_get_tps_hierarchy(struct mxl111sf_demod_state *state,
184 fe_hierarchy_t *hierarchy)
185{
186 u8 val;
187 int ret = mxl111sf_demod_read_reg(state, V6_TPS_HIERACHY_REG, &val);
188 /* bit<6:4> - 000:Non hierarchy, 001:1, 010:2, 011:4 */
189 if (mxl_fail(ret))
190 goto fail;
191
192 switch ((val & V6_TPS_HIERARCHY_INFO_MASK) >> 6) {
193 case 0:
194 *hierarchy = HIERARCHY_NONE;
195 break;
196 case 1:
197 *hierarchy = HIERARCHY_1;
198 break;
199 case 2:
200 *hierarchy = HIERARCHY_2;
201 break;
202 case 3:
203 *hierarchy = HIERARCHY_4;
204 break;
205 }
206fail:
207 return ret;
208}
209
210/* ------------------------------------------------------------------------ */
211/* LOCKS */
212
213static
214int mxl1x1sf_demod_get_sync_lock_status(struct mxl111sf_demod_state *state,
215 int *sync_lock)
216{
217 u8 val = 0;
218 int ret = mxl111sf_demod_read_reg(state, V6_SYNC_LOCK_REG, &val);
219 if (mxl_fail(ret))
220 goto fail;
221 *sync_lock = (val & SYNC_LOCK_MASK) >> 4;
222fail:
223 return ret;
224}
225
226static
227int mxl1x1sf_demod_get_rs_lock_status(struct mxl111sf_demod_state *state,
228 int *rs_lock)
229{
230 u8 val = 0;
231 int ret = mxl111sf_demod_read_reg(state, V6_RS_LOCK_DET_REG, &val);
232 if (mxl_fail(ret))
233 goto fail;
234 *rs_lock = (val & RS_LOCK_DET_MASK) >> 3;
235fail:
236 return ret;
237}
238
239static
240int mxl1x1sf_demod_get_tps_lock_status(struct mxl111sf_demod_state *state,
241 int *tps_lock)
242{
243 u8 val = 0;
244 int ret = mxl111sf_demod_read_reg(state, V6_TPS_LOCK_REG, &val);
245 if (mxl_fail(ret))
246 goto fail;
247 *tps_lock = (val & V6_PARAM_TPS_LOCK_MASK) >> 6;
248fail:
249 return ret;
250}
251
252static
253int mxl1x1sf_demod_get_fec_lock_status(struct mxl111sf_demod_state *state,
254 int *fec_lock)
255{
256 u8 val = 0;
257 int ret = mxl111sf_demod_read_reg(state, V6_IRQ_STATUS_REG, &val);
258 if (mxl_fail(ret))
259 goto fail;
260 *fec_lock = (val & IRQ_MASK_FEC_LOCK) >> 4;
261fail:
262 return ret;
263}
264
265#if 0
266static
267int mxl1x1sf_demod_get_cp_lock_status(struct mxl111sf_demod_state *state,
268 int *cp_lock)
269{
270 u8 val = 0;
271 int ret = mxl111sf_demod_read_reg(state, V6_CP_LOCK_DET_REG, &val);
272 if (mxl_fail(ret))
273 goto fail;
274 *cp_lock = (val & V6_CP_LOCK_DET_MASK) >> 2;
275fail:
276 return ret;
277}
278#endif
279
280static int mxl1x1sf_demod_reset_irq_status(struct mxl111sf_demod_state *state)
281{
282 return mxl111sf_demod_write_reg(state, 0x0e, 0xff);
283}
284
285/* ------------------------------------------------------------------------ */
286
287static int mxl111sf_demod_set_frontend(struct dvb_frontend *fe,
288 struct dvb_frontend_parameters *param)
289{
290 struct mxl111sf_demod_state *state = fe->demodulator_priv;
291 int ret = 0;
292
293 struct mxl111sf_reg_ctrl_info phy_pll_patch[] = {
294 {0x00, 0xff, 0x01}, /* change page to 1 */
295 {0x40, 0xff, 0x05},
296 {0x40, 0xff, 0x01},
297 {0x41, 0xff, 0xca},
298 {0x41, 0xff, 0xc0},
299 {0x00, 0xff, 0x00}, /* change page to 0 */
300 {0, 0, 0}
301 };
302
303 mxl_dbg("()");
304
305 if (fe->ops.tuner_ops.set_params) {
306 ret = fe->ops.tuner_ops.set_params(fe, param);
307 if (mxl_fail(ret))
308 goto fail;
309 msleep(50);
310 }
311 ret = mxl111sf_demod_program_regs(state, phy_pll_patch);
312 mxl_fail(ret);
313 msleep(50);
314 ret = mxl1x1sf_demod_reset_irq_status(state);
315 mxl_fail(ret);
316 msleep(100);
317fail:
318 return ret;
319}
320
321/* ------------------------------------------------------------------------ */
322
323#if 0
324/* resets TS Packet error count */
325/* After setting 7th bit of V5_PER_COUNT_RESET_REG, it should be reset to 0. */
326static
327int mxl1x1sf_demod_reset_packet_error_count(struct mxl111sf_demod_state *state)
328{
329 struct mxl111sf_reg_ctrl_info reset_per_count[] = {
330 {0x20, 0x01, 0x01},
331 {0x20, 0x01, 0x00},
332 {0, 0, 0}
333 };
334 return mxl111sf_demod_program_regs(state, reset_per_count);
335}
336#endif
337
338/* returns TS Packet error count */
339/* PER Count = FEC_PER_COUNT * (2 ** (FEC_PER_SCALE * 4)) */
340static int mxl111sf_demod_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
341{
342 struct mxl111sf_demod_state *state = fe->demodulator_priv;
343 u32 fec_per_count, fec_per_scale;
344 u8 val;
345 int ret;
346
347 *ucblocks = 0;
348
349 /* FEC_PER_COUNT Register */
350 ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_COUNT_REG, &val);
351 if (mxl_fail(ret))
352 goto fail;
353
354 fec_per_count = val;
355
356 /* FEC_PER_SCALE Register */
357 ret = mxl111sf_demod_read_reg(state, V6_FEC_PER_SCALE_REG, &val);
358 if (mxl_fail(ret))
359 goto fail;
360
361 val &= V6_FEC_PER_SCALE_MASK;
362 val *= 4;
363
364 fec_per_scale = 1 << val;
365
366 fec_per_count *= fec_per_scale;
367
368 *ucblocks = fec_per_count;
369fail:
370 return ret;
371}
372
373#ifdef MXL111SF_DEMOD_ENABLE_CALCULATIONS
374/* FIXME: leaving this enabled breaks the build on some architectures,
375 * and we shouldn't have any floating point math in the kernel, anyway.
376 *
377 * These macros need to be re-written, but it's harmless to simply
378 * return zero for now. */
379#define CALCULATE_BER(avg_errors, count) \
380 ((u32)(avg_errors * 4)/(count*64*188*8))
381#define CALCULATE_SNR(data) \
382 ((u32)((10 * (u32)data / 64) - 2.5))
383#else
384#define CALCULATE_BER(avg_errors, count) 0
385#define CALCULATE_SNR(data) 0
386#endif
387
388static int mxl111sf_demod_read_ber(struct dvb_frontend *fe, u32 *ber)
389{
390 struct mxl111sf_demod_state *state = fe->demodulator_priv;
391 u8 val1, val2, val3;
392 int ret;
393
394 *ber = 0;
395
396 ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_LSB_REG, &val1);
397 if (mxl_fail(ret))
398 goto fail;
399 ret = mxl111sf_demod_read_reg(state, V6_RS_AVG_ERRORS_MSB_REG, &val2);
400 if (mxl_fail(ret))
401 goto fail;
402 ret = mxl111sf_demod_read_reg(state, V6_N_ACCUMULATE_REG, &val3);
403 if (mxl_fail(ret))
404 goto fail;
405
406 *ber = CALCULATE_BER((val1 | (val2 << 8)), val3);
407fail:
408 return ret;
409}
410
411static int mxl111sf_demod_calc_snr(struct mxl111sf_demod_state *state,
412 u16 *snr)
413{
414 u8 val1, val2;
415 int ret;
416
417 *snr = 0;
418
419 ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_LSB_REG, &val1);
420 if (mxl_fail(ret))
421 goto fail;
422 ret = mxl111sf_demod_read_reg(state, V6_SNR_RB_MSB_REG, &val2);
423 if (mxl_fail(ret))
424 goto fail;
425
426 *snr = CALCULATE_SNR(val1 | ((val2 & 0x03) << 8));
427fail:
428 return ret;
429}
430
431static int mxl111sf_demod_read_snr(struct dvb_frontend *fe, u16 *snr)
432{
433 struct mxl111sf_demod_state *state = fe->demodulator_priv;
434
435 int ret = mxl111sf_demod_calc_snr(state, snr);
436 if (mxl_fail(ret))
437 goto fail;
438
439 *snr /= 10; /* 0.1 dB */
440fail:
441 return ret;
442}
443
444static int mxl111sf_demod_read_status(struct dvb_frontend *fe,
445 fe_status_t *status)
446{
447 struct mxl111sf_demod_state *state = fe->demodulator_priv;
448 int ret, locked, cr_lock, sync_lock, fec_lock;
449
450 *status = 0;
451
452 ret = mxl1x1sf_demod_get_rs_lock_status(state, &locked);
453 if (mxl_fail(ret))
454 goto fail;
455 ret = mxl1x1sf_demod_get_tps_lock_status(state, &cr_lock);
456 if (mxl_fail(ret))
457 goto fail;
458 ret = mxl1x1sf_demod_get_sync_lock_status(state, &sync_lock);
459 if (mxl_fail(ret))
460 goto fail;
461 ret = mxl1x1sf_demod_get_fec_lock_status(state, &fec_lock);
462 if (mxl_fail(ret))
463 goto fail;
464
465 if (locked)
466 *status |= FE_HAS_SIGNAL;
467 if (cr_lock)
468 *status |= FE_HAS_CARRIER;
469 if (sync_lock)
470 *status |= FE_HAS_SYNC;
471 if (fec_lock) /* false positives? */
472 *status |= FE_HAS_VITERBI;
473
474 if ((locked) && (cr_lock) && (sync_lock))
475 *status |= FE_HAS_LOCK;
476fail:
477 return ret;
478}
479
480static int mxl111sf_demod_read_signal_strength(struct dvb_frontend *fe,
481 u16 *signal_strength)
482{
483 struct mxl111sf_demod_state *state = fe->demodulator_priv;
484 fe_modulation_t constellation;
485 u16 snr;
486
487 mxl111sf_demod_calc_snr(state, &snr);
488 mxl1x1sf_demod_get_tps_constellation(state, &constellation);
489
490 switch (constellation) {
491 case QPSK:
492 *signal_strength = (snr >= 1300) ?
493 min(65535, snr * 44) : snr * 38;
494 break;
495 case QAM_16:
496 *signal_strength = (snr >= 1500) ?
497 min(65535, snr * 38) : snr * 33;
498 break;
499 case QAM_64:
500 *signal_strength = (snr >= 2000) ?
501 min(65535, snr * 29) : snr * 25;
502 break;
503 default:
504 *signal_strength = 0;
505 return -EINVAL;
506 }
507
508 return 0;
509}
510
511static int mxl111sf_demod_get_frontend(struct dvb_frontend *fe,
512 struct dvb_frontend_parameters *p)
513{
514 struct mxl111sf_demod_state *state = fe->demodulator_priv;
515
516 mxl_dbg("()");
517#if 0
518 p->inversion = /* FIXME */ ? INVERSION_ON : INVERSION_OFF;
519#endif
520 if (fe->ops.tuner_ops.get_bandwidth)
521 fe->ops.tuner_ops.get_bandwidth(fe, &p->u.ofdm.bandwidth);
522 if (fe->ops.tuner_ops.get_frequency)
523 fe->ops.tuner_ops.get_frequency(fe, &p->frequency);
524 mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_HP);
525 mxl1x1sf_demod_get_tps_code_rate(state, &p->u.ofdm.code_rate_LP);
526 mxl1x1sf_demod_get_tps_constellation(state, &p->u.ofdm.constellation);
527 mxl1x1sf_demod_get_tps_guard_fft_mode(state,
528 &p->u.ofdm.transmission_mode);
529 mxl1x1sf_demod_get_tps_guard_interval(state,
530 &p->u.ofdm.guard_interval);
531 mxl1x1sf_demod_get_tps_hierarchy(state,
532 &p->u.ofdm.hierarchy_information);
533
534 return 0;
535}
536
537static
538int mxl111sf_demod_get_tune_settings(struct dvb_frontend *fe,
539 struct dvb_frontend_tune_settings *tune)
540{
541 tune->min_delay_ms = 1000;
542 return 0;
543}
544
545static void mxl111sf_demod_release(struct dvb_frontend *fe)
546{
547 struct mxl111sf_demod_state *state = fe->demodulator_priv;
548 mxl_dbg("()");
549 kfree(state);
550 fe->demodulator_priv = NULL;
551}
552
553static struct dvb_frontend_ops mxl111sf_demod_ops = {
554
555 .info = {
556 .name = "MaxLinear MxL111SF DVB-T demodulator",
557 .type = FE_OFDM,
558 .frequency_min = 177000000,
559 .frequency_max = 858000000,
560 .frequency_stepsize = 166666,
561 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
562 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
563 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 |
564 FE_CAN_QAM_AUTO |
565 FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
566 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
567 },
568 .release = mxl111sf_demod_release,
569#if 0
570 .init = mxl111sf_init,
571 .i2c_gate_ctrl = mxl111sf_i2c_gate_ctrl,
572#endif
573 .set_frontend = mxl111sf_demod_set_frontend,
574 .get_frontend = mxl111sf_demod_get_frontend,
575 .get_tune_settings = mxl111sf_demod_get_tune_settings,
576 .read_status = mxl111sf_demod_read_status,
577 .read_signal_strength = mxl111sf_demod_read_signal_strength,
578 .read_ber = mxl111sf_demod_read_ber,
579 .read_snr = mxl111sf_demod_read_snr,
580 .read_ucblocks = mxl111sf_demod_read_ucblocks,
581};
582
583struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
584 struct mxl111sf_demod_config *cfg)
585{
586 struct mxl111sf_demod_state *state = NULL;
587
588 mxl_dbg("()");
589
590 state = kzalloc(sizeof(struct mxl111sf_demod_state), GFP_KERNEL);
591 if (state == NULL)
592 return NULL;
593
594 state->mxl_state = mxl_state;
595 state->cfg = cfg;
596
597 memcpy(&state->fe.ops, &mxl111sf_demod_ops,
598 sizeof(struct dvb_frontend_ops));
599
600 state->fe.demodulator_priv = state;
601 return &state->fe;
602}
603EXPORT_SYMBOL_GPL(mxl111sf_demod_attach);
604
605MODULE_DESCRIPTION("MaxLinear MxL111SF DVB-T demodulator driver");
606MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
607MODULE_LICENSE("GPL");
608MODULE_VERSION("0.1");
609
610/*
611 * Local variables:
612 * c-basic-offset: 8
613 * End:
614 */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf-demod.h b/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
new file mode 100644
index 00000000000..432706ae527
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/mxl111sf-demod.h
@@ -0,0 +1,55 @@
1/*
2 * mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
3 *
4 * Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef __MXL111SF_DEMOD_H__
22#define __MXL111SF_DEMOD_H__
23
24#include "dvb_frontend.h"
25#include "mxl111sf.h"
26
27struct mxl111sf_demod_config {
28 int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
29 int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
30 int (*program_regs)(struct mxl111sf_state *state,
31 struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
32};
33
34#if defined(CONFIG_DVB_USB_MXL111SF) || \
35 (defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
36extern
37struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
38 struct mxl111sf_demod_config *cfg);
39#else
40static inline
41struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
42 struct mxl111sf_demod_config *cfg)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_DVB_USB_MXL111SF */
48
49#endif /* __MXL111SF_DEMOD_H__ */
50
51/*
52 * Local variables:
53 * c-basic-offset: 8
54 * End:
55 */
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.c b/drivers/media/dvb/dvb-usb/mxl111sf.c
index 546ba5915a5..b5c98da5d9e 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.c
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.c
@@ -17,6 +17,7 @@
17#include "mxl111sf-i2c.h" 17#include "mxl111sf-i2c.h"
18#include "mxl111sf-gpio.h" 18#include "mxl111sf-gpio.h"
19 19
20#include "mxl111sf-demod.h"
20#include "mxl111sf-tuner.h" 21#include "mxl111sf-tuner.h"
21 22
22#include "lgdt3305.h" 23#include "lgdt3305.h"
@@ -362,6 +363,22 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
362 return ret; 363 return ret;
363} 364}
364 365
366static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
367{
368 struct dvb_usb_device *d = adap->dev;
369 struct mxl111sf_state *state = d->priv;
370 int ret = 0;
371
372 deb_info("%s(%d)\n", __func__, onoff);
373
374 if (onoff) {
375 ret = mxl111sf_enable_usb_output(state);
376 mxl_fail(ret);
377 }
378
379 return ret;
380}
381
365/* ------------------------------------------------------------------------ */ 382/* ------------------------------------------------------------------------ */
366 383
367static struct lgdt3305_config hauppauge_lgdt3305_config = { 384static struct lgdt3305_config hauppauge_lgdt3305_config = {
@@ -438,6 +455,70 @@ fail:
438 return ret; 455 return ret;
439} 456}
440 457
458static struct mxl111sf_demod_config mxl_demod_config = {
459 .read_reg = mxl111sf_read_reg,
460 .write_reg = mxl111sf_write_reg,
461 .program_regs = mxl111sf_ctrl_program_regs,
462};
463
464static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
465{
466 struct dvb_usb_device *d = adap->dev;
467 struct mxl111sf_state *state = d->priv;
468 int fe_id = adap->num_frontends_initialized;
469 struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
470 int ret;
471
472 deb_adv("%s()\n", __func__);
473
474 /* save a pointer to the dvb_usb_device in device state */
475 state->d = d;
476 adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
477 state->alt_mode = adap_state->alt_mode;
478
479 if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
480 err("set interface failed");
481
482 state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
483 adap_state->gpio_mode = state->gpio_mode;
484 adap_state->device_mode = MXL_SOC_MODE;
485 adap_state->ep6_clockphase = 1;
486
487 ret = mxl1x1sf_soft_reset(state);
488 if (mxl_fail(ret))
489 goto fail;
490 ret = mxl111sf_init_tuner_demod(state);
491 if (mxl_fail(ret))
492 goto fail;
493
494 ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
495 if (mxl_fail(ret))
496 goto fail;
497
498 ret = mxl111sf_enable_usb_output(state);
499 if (mxl_fail(ret))
500 goto fail;
501 ret = mxl1x1sf_top_master_ctrl(state, 1);
502 if (mxl_fail(ret))
503 goto fail;
504
505 /* dont care if this fails */
506 mxl111sf_init_port_expander(state);
507
508 adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
509 &mxl_demod_config);
510 if (adap->fe_adap[fe_id].fe) {
511 adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
512 adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
513 adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
514 adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
515 return 0;
516 }
517 ret = -EIO;
518fail:
519 return ret;
520}
521
441static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state, 522static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
442 int antpath) 523 int antpath)
443{ 524{
@@ -567,7 +648,8 @@ struct i2c_algorithm mxl111sf_i2c_algo = {
567#endif 648#endif
568}; 649};
569 650
570/* DVB USB Driver stuff */ 651static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
652static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
571static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties; 653static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
572static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties; 654static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
573 655
@@ -580,9 +662,15 @@ static int mxl111sf_probe(struct usb_interface *intf,
580 662
581 if (((dvb_usb_mxl111sf_isoc) && 663 if (((dvb_usb_mxl111sf_isoc) &&
582 (0 == dvb_usb_device_init(intf, 664 (0 == dvb_usb_device_init(intf,
665 &mxl111sf_dvbt_isoc_properties,
666 THIS_MODULE, &d, adapter_nr) ||
667 0 == dvb_usb_device_init(intf,
583 &mxl111sf_atsc_isoc_properties, 668 &mxl111sf_atsc_isoc_properties,
584 THIS_MODULE, &d, adapter_nr))) || 669 THIS_MODULE, &d, adapter_nr))) ||
585 0 == dvb_usb_device_init(intf, 670 0 == dvb_usb_device_init(intf,
671 &mxl111sf_dvbt_bulk_properties,
672 THIS_MODULE, &d, adapter_nr) ||
673 0 == dvb_usb_device_init(intf,
586 &mxl111sf_atsc_bulk_properties, 674 &mxl111sf_atsc_bulk_properties,
587 THIS_MODULE, &d, adapter_nr) || 0) { 675 THIS_MODULE, &d, adapter_nr) || 0) {
588 676
@@ -669,6 +757,36 @@ static struct usb_device_id mxl111sf_table[] = {
669MODULE_DEVICE_TABLE(usb, mxl111sf_table); 757MODULE_DEVICE_TABLE(usb, mxl111sf_table);
670 758
671 759
760#define MXL111SF_EP4_BULK_STREAMING_CONFIG \
761 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
762 .stream = { \
763 .type = USB_BULK, \
764 .count = 5, \
765 .endpoint = 0x04, \
766 .u = { \
767 .bulk = { \
768 .buffersize = 8192, \
769 } \
770 } \
771 }
772
773/* FIXME: works for v6 but not v8 silicon */
774#define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
775 .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
776 .stream = { \
777 .type = USB_ISOC, \
778 .count = 5, \
779 .endpoint = 0x04, \
780 .u = { \
781 .isoc = { \
782 .framesperurb = 96, \
783 /* FIXME: v6 SILICON: */ \
784 .framesize = 564, \
785 .interval = 1, \
786 } \
787 } \
788 }
789
672#define MXL111SF_EP6_BULK_STREAMING_CONFIG \ 790#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
673 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \ 791 .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
674 .stream = { \ 792 .stream = { \
@@ -712,7 +830,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table);
712 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \ 830 .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
713 .size_of_priv = sizeof(struct mxl111sf_state) 831 .size_of_priv = sizeof(struct mxl111sf_state)
714 832
715static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = { 833static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
716 MXL111SF_DEFAULT_DEVICE_PROPERTIES, 834 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
717 835
718 .num_adapters = 1, 836 .num_adapters = 1,
@@ -723,10 +841,106 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
723 .fe = {{ 841 .fe = {{
724 .size_of_priv = sizeof(struct mxl111sf_adap_state), 842 .size_of_priv = sizeof(struct mxl111sf_adap_state),
725 843
844 .frontend_attach = mxl111sf_attach_demod,
845 .tuner_attach = mxl111sf_attach_tuner,
846
847 MXL111SF_EP4_BULK_STREAMING_CONFIG,
848 } },
849 },
850 },
851 .num_device_descs = 4,
852 .devices = {
853 { "Hauppauge 126xxx DVBT (bulk)",
854 { NULL },
855 { &mxl111sf_table[4], &mxl111sf_table[8],
856 NULL },
857 },
858 { "Hauppauge 117xxx DVBT (bulk)",
859 { NULL },
860 { &mxl111sf_table[15], &mxl111sf_table[18],
861 NULL },
862 },
863 { "Hauppauge 138xxx DVBT (bulk)",
864 { NULL },
865 { &mxl111sf_table[20], &mxl111sf_table[22],
866 &mxl111sf_table[24], &mxl111sf_table[26],
867 NULL },
868 },
869 { "Hauppauge 126xxx (tp-bulk)",
870 { NULL },
871 { &mxl111sf_table[28], &mxl111sf_table[30],
872 NULL },
873 },
874 }
875};
876
877static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
878 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
879
880 .num_adapters = 1,
881 .adapter = {
882 {
883 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
884 .num_frontends = 1,
885 .fe = {{
886 .size_of_priv = sizeof(struct mxl111sf_adap_state),
887
888 .frontend_attach = mxl111sf_attach_demod,
889 .tuner_attach = mxl111sf_attach_tuner,
890
891 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
892 } },
893 },
894 },
895 .num_device_descs = 4,
896 .devices = {
897 { "Hauppauge 126xxx DVBT (isoc)",
898 { NULL },
899 { &mxl111sf_table[4], &mxl111sf_table[8],
900 NULL },
901 },
902 { "Hauppauge 117xxx DVBT (isoc)",
903 { NULL },
904 { &mxl111sf_table[15], &mxl111sf_table[18],
905 NULL },
906 },
907 { "Hauppauge 138xxx DVBT (isoc)",
908 { NULL },
909 { &mxl111sf_table[20], &mxl111sf_table[22],
910 &mxl111sf_table[24], &mxl111sf_table[26],
911 NULL },
912 },
913 { "Hauppauge 126xxx (tp-isoc)",
914 { NULL },
915 { &mxl111sf_table[28], &mxl111sf_table[30],
916 NULL },
917 },
918 }
919};
920
921static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
922 MXL111SF_DEFAULT_DEVICE_PROPERTIES,
923
924 .num_adapters = 1,
925 .adapter = {
926 {
927 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
928 .num_frontends = 2,
929 .fe = {{
930 .size_of_priv = sizeof(struct mxl111sf_adap_state),
931
726 .frontend_attach = mxl111sf_lgdt3305_frontend_attach, 932 .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
727 .tuner_attach = mxl111sf_attach_tuner, 933 .tuner_attach = mxl111sf_attach_tuner,
728 934
729 MXL111SF_EP6_BULK_STREAMING_CONFIG, 935 MXL111SF_EP6_BULK_STREAMING_CONFIG,
936 },
937 {
938 .size_of_priv = sizeof(struct mxl111sf_adap_state),
939
940 .frontend_attach = mxl111sf_attach_demod,
941 .tuner_attach = mxl111sf_attach_tuner,
942
943 MXL111SF_EP4_BULK_STREAMING_CONFIG,
730 }}, 944 }},
731 }, 945 },
732 }, 946 },
@@ -776,7 +990,7 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
776 .adapter = { 990 .adapter = {
777 { 991 {
778 .fe_ioctl_override = mxl111sf_fe_ioctl_override, 992 .fe_ioctl_override = mxl111sf_fe_ioctl_override,
779 .num_frontends = 1, 993 .num_frontends = 2,
780 .fe = {{ 994 .fe = {{
781 .size_of_priv = sizeof(struct mxl111sf_adap_state), 995 .size_of_priv = sizeof(struct mxl111sf_adap_state),
782 996
@@ -784,6 +998,14 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
784 .tuner_attach = mxl111sf_attach_tuner, 998 .tuner_attach = mxl111sf_attach_tuner,
785 999
786 MXL111SF_EP6_ISOC_STREAMING_CONFIG, 1000 MXL111SF_EP6_ISOC_STREAMING_CONFIG,
1001 },
1002 {
1003 .size_of_priv = sizeof(struct mxl111sf_adap_state),
1004
1005 .frontend_attach = mxl111sf_attach_demod,
1006 .tuner_attach = mxl111sf_attach_tuner,
1007
1008 MXL111SF_EP4_ISOC_STREAMING_CONFIG,
787 }}, 1009 }},
788 }, 1010 },
789 }, 1011 },
diff --git a/drivers/media/dvb/dvb-usb/mxl111sf.h b/drivers/media/dvb/dvb-usb/mxl111sf.h
index 5a2c7bb386c..364d89f826b 100644
--- a/drivers/media/dvb/dvb-usb/mxl111sf.h
+++ b/drivers/media/dvb/dvb-usb/mxl111sf.h
@@ -133,7 +133,7 @@ extern int dvb_usb_mxl111sf_debug;
133/* The following allows the mxl_fail() macro defined below to work 133/* The following allows the mxl_fail() macro defined below to work
134 * in externel modules, such as mxl111sf-tuner.ko, even though 134 * in externel modules, such as mxl111sf-tuner.ko, even though
135 * dvb_usb_mxl111sf_debug is not defined within those modules */ 135 * dvb_usb_mxl111sf_debug is not defined within those modules */
136#ifdef __MXL111SF_TUNER_H__ 136#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
137#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG 137#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
138#else 138#else
139#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug 139#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
diff --git a/drivers/media/dvb/ngene/Makefile b/drivers/media/dvb/ngene/Makefile
index 89873615e68..13ebeffb705 100644
--- a/drivers/media/dvb/ngene/Makefile
+++ b/drivers/media/dvb/ngene/Makefile
@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
11ccflags-y += -Idrivers/media/common/tuners/ 11ccflags-y += -Idrivers/media/common/tuners/
12 12
13# For the staging CI driver cxd2099 13# For the staging CI driver cxd2099
14ccflags-y += -Idrivers/staging/cxd2099/ 14ccflags-y += -Idrivers/staging/media/cxd2099/
diff --git a/drivers/media/radio/radio-tea5764.c b/drivers/media/radio/radio-tea5764.c
index 95ddcc4845d..db20904d01f 100644
--- a/drivers/media/radio/radio-tea5764.c
+++ b/drivers/media/radio/radio-tea5764.c
@@ -128,8 +128,10 @@ struct tea5764_write_regs {
128 u16 rdsbbl; /* PAUSEDET & RDSBBL */ 128 u16 rdsbbl; /* PAUSEDET & RDSBBL */
129} __attribute__ ((packed)); 129} __attribute__ ((packed));
130 130
131#ifndef RADIO_TEA5764_XTAL 131#ifdef CONFIG_RADIO_TEA5764_XTAL
132#define RADIO_TEA5764_XTAL 1 132#define RADIO_TEA5764_XTAL 1
133#else
134#define RADIO_TEA5764_XTAL 0
133#endif 135#endif
134 136
135static int radio_nr = -1; 137static int radio_nr = -1;
diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig
index d285c8c9281..b303a3f8a9f 100644
--- a/drivers/media/video/Kconfig
+++ b/drivers/media/video/Kconfig
@@ -517,6 +517,13 @@ config VIDEO_NOON010PC30
517 517
518source "drivers/media/video/m5mols/Kconfig" 518source "drivers/media/video/m5mols/Kconfig"
519 519
520config VIDEO_S5K6AA
521 tristate "Samsung S5K6AAFX sensor support"
522 depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
523 ---help---
524 This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
525 camera sensor with an embedded SoC image signal processor.
526
520comment "Flash devices" 527comment "Flash devices"
521 528
522config VIDEO_ADP1653 529config VIDEO_ADP1653
@@ -736,6 +743,8 @@ source "drivers/media/video/cx88/Kconfig"
736 743
737source "drivers/media/video/cx23885/Kconfig" 744source "drivers/media/video/cx23885/Kconfig"
738 745
746source "drivers/media/video/cx25821/Kconfig"
747
739source "drivers/media/video/au0828/Kconfig" 748source "drivers/media/video/au0828/Kconfig"
740 749
741source "drivers/media/video/ivtv/Kconfig" 750source "drivers/media/video/ivtv/Kconfig"
diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile
index 11fff97e719..117f9c4b4cb 100644
--- a/drivers/media/video/Makefile
+++ b/drivers/media/video/Makefile
@@ -72,6 +72,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
72obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o 72obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
73obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o 73obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
74obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/ 74obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
75obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
75obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o 76obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
76 77
77obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o 78obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
@@ -104,6 +105,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
104obj-$(CONFIG_VIDEO_EM28XX) += em28xx/ 105obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
105obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/ 106obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
106obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/ 107obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
108obj-$(CONFIG_VIDEO_CX25821) += cx25821/
107obj-$(CONFIG_VIDEO_USBVISION) += usbvision/ 109obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
108obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/ 110obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
109obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ 111obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
diff --git a/drivers/media/video/atmel-isi.c b/drivers/media/video/atmel-isi.c
index 774715d2f84..8c775c59e12 100644
--- a/drivers/media/video/atmel-isi.c
+++ b/drivers/media/video/atmel-isi.c
@@ -94,6 +94,7 @@ struct atmel_isi {
94 unsigned int irq; 94 unsigned int irq;
95 95
96 struct isi_platform_data *pdata; 96 struct isi_platform_data *pdata;
97 u16 width_flags; /* max 12 bits */
97 98
98 struct list_head video_buffer_list; 99 struct list_head video_buffer_list;
99 struct frame_buffer *active; 100 struct frame_buffer *active;
@@ -248,9 +249,9 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
248/* ------------------------------------------------------------------ 249/* ------------------------------------------------------------------
249 Videobuf operations 250 Videobuf operations
250 ------------------------------------------------------------------*/ 251 ------------------------------------------------------------------*/
251static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 252static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
252 unsigned int *nplanes, unsigned int sizes[], 253 unsigned int *nbuffers, unsigned int *nplanes,
253 void *alloc_ctxs[]) 254 unsigned int sizes[], void *alloc_ctxs[])
254{ 255{
255 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 256 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
256 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 257 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
@@ -647,50 +648,42 @@ static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
647 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 648 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
648} 649}
649 650
650static unsigned long make_bus_param(struct atmel_isi *isi) 651#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \
651{ 652 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
652 unsigned long flags; 653 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
653 /* 654 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
654 * Platform specified synchronization and pixel clock polarities are 655 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
655 * only a recommendation and are only used during probing. Atmel ISI 656 V4L2_MBUS_PCLK_SAMPLE_RISING | \
656 * camera interface only works in master mode, i.e., uses HSYNC and 657 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
657 * VSYNC signals from the sensor 658 V4L2_MBUS_DATA_ACTIVE_HIGH)
658 */
659 flags = SOCAM_MASTER |
660 SOCAM_HSYNC_ACTIVE_HIGH |
661 SOCAM_HSYNC_ACTIVE_LOW |
662 SOCAM_VSYNC_ACTIVE_HIGH |
663 SOCAM_VSYNC_ACTIVE_LOW |
664 SOCAM_PCLK_SAMPLE_RISING |
665 SOCAM_PCLK_SAMPLE_FALLING |
666 SOCAM_DATA_ACTIVE_HIGH;
667
668 if (isi->pdata->data_width_flags & ISI_DATAWIDTH_10)
669 flags |= SOCAM_DATAWIDTH_10;
670
671 if (isi->pdata->data_width_flags & ISI_DATAWIDTH_8)
672 flags |= SOCAM_DATAWIDTH_8;
673
674 if (flags & SOCAM_DATAWIDTH_MASK)
675 return flags;
676
677 return 0;
678}
679 659
680static int isi_camera_try_bus_param(struct soc_camera_device *icd, 660static int isi_camera_try_bus_param(struct soc_camera_device *icd,
681 unsigned char buswidth) 661 unsigned char buswidth)
682{ 662{
663 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
683 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 664 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
684 struct atmel_isi *isi = ici->priv; 665 struct atmel_isi *isi = ici->priv;
685 unsigned long camera_flags; 666 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
667 unsigned long common_flags;
686 int ret; 668 int ret;
687 669
688 camera_flags = icd->ops->query_bus_param(icd); 670 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
689 ret = soc_camera_bus_param_compatible(camera_flags, 671 if (!ret) {
690 make_bus_param(isi)); 672 common_flags = soc_mbus_config_compatible(&cfg,
691 if (!ret) 673 ISI_BUS_PARAM);
692 return -EINVAL; 674 if (!common_flags) {
693 return 0; 675 dev_warn(icd->parent,
676 "Flags incompatible: camera 0x%x, host 0x%x\n",
677 cfg.flags, ISI_BUS_PARAM);
678 return -EINVAL;
679 }
680 } else if (ret != -ENOIOCTLCMD) {
681 return ret;
682 }
683
684 if ((1 << (buswidth - 1)) & isi->width_flags)
685 return 0;
686 return -EINVAL;
694} 687}
695 688
696 689
@@ -812,59 +805,71 @@ static int isi_camera_querycap(struct soc_camera_host *ici,
812 805
813static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt) 806static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt)
814{ 807{
808 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
815 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 809 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
816 struct atmel_isi *isi = ici->priv; 810 struct atmel_isi *isi = ici->priv;
817 unsigned long bus_flags, camera_flags, common_flags; 811 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
812 unsigned long common_flags;
818 int ret; 813 int ret;
819 u32 cfg1 = 0; 814 u32 cfg1 = 0;
820 815
821 camera_flags = icd->ops->query_bus_param(icd); 816 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
822 817 if (!ret) {
823 bus_flags = make_bus_param(isi); 818 common_flags = soc_mbus_config_compatible(&cfg,
824 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 819 ISI_BUS_PARAM);
825 dev_dbg(icd->parent, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n", 820 if (!common_flags) {
826 camera_flags, bus_flags, common_flags); 821 dev_warn(icd->parent,
827 if (!common_flags) 822 "Flags incompatible: camera 0x%x, host 0x%x\n",
828 return -EINVAL; 823 cfg.flags, ISI_BUS_PARAM);
824 return -EINVAL;
825 }
826 } else if (ret != -ENOIOCTLCMD) {
827 return ret;
828 } else {
829 common_flags = ISI_BUS_PARAM;
830 }
831 dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
832 cfg.flags, ISI_BUS_PARAM, common_flags);
829 833
830 /* Make choises, based on platform preferences */ 834 /* Make choises, based on platform preferences */
831 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 835 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
832 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 836 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
833 if (isi->pdata->hsync_act_low) 837 if (isi->pdata->hsync_act_low)
834 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 838 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
835 else 839 else
836 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 840 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
837 } 841 }
838 842
839 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 843 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
840 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 844 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
841 if (isi->pdata->vsync_act_low) 845 if (isi->pdata->vsync_act_low)
842 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 846 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
843 else 847 else
844 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 848 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
845 } 849 }
846 850
847 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 851 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
848 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 852 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
849 if (isi->pdata->pclk_act_falling) 853 if (isi->pdata->pclk_act_falling)
850 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 854 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
851 else 855 else
852 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 856 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
853 } 857 }
854 858
855 ret = icd->ops->set_bus_param(icd, common_flags); 859 cfg.flags = common_flags;
856 if (ret < 0) { 860 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
857 dev_dbg(icd->parent, "Camera set_bus_param(%lx) returned %d\n", 861 if (ret < 0 && ret != -ENOIOCTLCMD) {
862 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
858 common_flags, ret); 863 common_flags, ret);
859 return ret; 864 return ret;
860 } 865 }
861 866
862 /* set bus param for ISI */ 867 /* set bus param for ISI */
863 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) 868 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
864 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW; 869 cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
865 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 870 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
866 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW; 871 cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
867 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) 872 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
868 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING; 873 cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
869 874
870 if (isi->pdata->has_emb_sync) 875 if (isi->pdata->has_emb_sync)
@@ -983,6 +988,11 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
983 goto err_ioremap; 988 goto err_ioremap;
984 } 989 }
985 990
991 if (pdata->data_width_flags & ISI_DATAWIDTH_8)
992 isi->width_flags = 1 << 7;
993 if (pdata->data_width_flags & ISI_DATAWIDTH_10)
994 isi->width_flags |= 1 << 9;
995
986 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); 996 isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
987 997
988 irq = platform_get_irq(pdev, 0); 998 irq = platform_get_irq(pdev, 0);
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index 9e2f870f425..c6ff32a6137 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -1085,6 +1085,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
1085 setup.addr = ADDR_UNSET; 1085 setup.addr = ADDR_UNSET;
1086 setup.type = cx->options.tuner; 1086 setup.type = cx->options.tuner;
1087 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ 1087 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1088 if (cx->options.radio > 0)
1089 setup.mode_mask |= T_RADIO;
1088 setup.tuner_callback = (setup.type == TUNER_XC2028) ? 1090 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1089 cx18_reset_tuner_gpio : NULL; 1091 cx18_reset_tuner_gpio : NULL;
1090 cx18_call_all(cx, tuner, s_type_addr, &setup); 1092 cx18_call_all(cx, tuner, s_type_addr, &setup);
diff --git a/drivers/staging/cx25821/Kconfig b/drivers/media/video/cx25821/Kconfig
index 5f6b5421371..5f6b5421371 100644
--- a/drivers/staging/cx25821/Kconfig
+++ b/drivers/media/video/cx25821/Kconfig
diff --git a/drivers/staging/cx25821/Makefile b/drivers/media/video/cx25821/Makefile
index aedde18c68f..aedde18c68f 100644
--- a/drivers/staging/cx25821/Makefile
+++ b/drivers/media/video/cx25821/Makefile
diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/media/video/cx25821/cx25821-alsa.c
index 09e99de5fd2..09e99de5fd2 100644
--- a/drivers/staging/cx25821/cx25821-alsa.c
+++ b/drivers/media/video/cx25821/cx25821-alsa.c
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.c b/drivers/media/video/cx25821/cx25821-audio-upstream.c
index c20d6dece15..c20d6dece15 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-audio-upstream.c
diff --git a/drivers/staging/cx25821/cx25821-audio-upstream.h b/drivers/media/video/cx25821/cx25821-audio-upstream.h
index af2ae7c5815..af2ae7c5815 100644
--- a/drivers/staging/cx25821/cx25821-audio-upstream.h
+++ b/drivers/media/video/cx25821/cx25821-audio-upstream.h
diff --git a/drivers/staging/cx25821/cx25821-audio.h b/drivers/media/video/cx25821/cx25821-audio.h
index 8eb55b7b88c..8eb55b7b88c 100644
--- a/drivers/staging/cx25821/cx25821-audio.h
+++ b/drivers/media/video/cx25821/cx25821-audio.h
diff --git a/drivers/staging/cx25821/cx25821-biffuncs.h b/drivers/media/video/cx25821/cx25821-biffuncs.h
index 9326a7c729e..9326a7c729e 100644
--- a/drivers/staging/cx25821/cx25821-biffuncs.h
+++ b/drivers/media/video/cx25821/cx25821-biffuncs.h
diff --git a/drivers/staging/cx25821/cx25821-cards.c b/drivers/media/video/cx25821/cx25821-cards.c
index 6ace60313b4..6ace60313b4 100644
--- a/drivers/staging/cx25821/cx25821-cards.c
+++ b/drivers/media/video/cx25821/cx25821-cards.c
diff --git a/drivers/staging/cx25821/cx25821-core.c b/drivers/media/video/cx25821/cx25821-core.c
index a7fa38f9594..a7fa38f9594 100644
--- a/drivers/staging/cx25821/cx25821-core.c
+++ b/drivers/media/video/cx25821/cx25821-core.c
diff --git a/drivers/staging/cx25821/cx25821-gpio.c b/drivers/media/video/cx25821/cx25821-gpio.c
index 29e43b03c85..29e43b03c85 100644
--- a/drivers/staging/cx25821/cx25821-gpio.c
+++ b/drivers/media/video/cx25821/cx25821-gpio.c
diff --git a/drivers/staging/cx25821/cx25821-i2c.c b/drivers/media/video/cx25821/cx25821-i2c.c
index 4d3d0ce4078..4d3d0ce4078 100644
--- a/drivers/staging/cx25821/cx25821-i2c.c
+++ b/drivers/media/video/cx25821/cx25821-i2c.c
diff --git a/drivers/staging/cx25821/cx25821-medusa-defines.h b/drivers/media/video/cx25821/cx25821-medusa-defines.h
index 60d197f5755..60d197f5755 100644
--- a/drivers/staging/cx25821/cx25821-medusa-defines.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-defines.h
diff --git a/drivers/staging/cx25821/cx25821-medusa-reg.h b/drivers/media/video/cx25821/cx25821-medusa-reg.h
index 1c1c228352d..1c1c228352d 100644
--- a/drivers/staging/cx25821/cx25821-medusa-reg.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-reg.h
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.c b/drivers/media/video/cx25821/cx25821-medusa-video.c
index fc780d0908d..fc780d0908d 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.c
+++ b/drivers/media/video/cx25821/cx25821-medusa-video.c
diff --git a/drivers/staging/cx25821/cx25821-medusa-video.h b/drivers/media/video/cx25821/cx25821-medusa-video.h
index 6175e096185..6175e096185 100644
--- a/drivers/staging/cx25821/cx25821-medusa-video.h
+++ b/drivers/media/video/cx25821/cx25821-medusa-video.h
diff --git a/drivers/staging/cx25821/cx25821-reg.h b/drivers/media/video/cx25821/cx25821-reg.h
index a3fc25a4dc0..a3fc25a4dc0 100644
--- a/drivers/staging/cx25821/cx25821-reg.h
+++ b/drivers/media/video/cx25821/cx25821-reg.h
diff --git a/drivers/staging/cx25821/cx25821-sram.h b/drivers/media/video/cx25821/cx25821-sram.h
index 5f05d153bc4..5f05d153bc4 100644
--- a/drivers/staging/cx25821/cx25821-sram.h
+++ b/drivers/media/video/cx25821/cx25821-sram.h
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
index 2a724ddfa53..2a724ddfa53 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.c
diff --git a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
index d42dab59b66..d42dab59b66 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream-ch2.h
+++ b/drivers/media/video/cx25821/cx25821-video-upstream-ch2.h
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.c b/drivers/media/video/cx25821/cx25821-video-upstream.c
index c0b80068f46..c0b80068f46 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.c
+++ b/drivers/media/video/cx25821/cx25821-video-upstream.c
diff --git a/drivers/staging/cx25821/cx25821-video-upstream.h b/drivers/media/video/cx25821/cx25821-video-upstream.h
index 268ec8aa6a6..268ec8aa6a6 100644
--- a/drivers/staging/cx25821/cx25821-video-upstream.h
+++ b/drivers/media/video/cx25821/cx25821-video-upstream.h
diff --git a/drivers/staging/cx25821/cx25821-video.c b/drivers/media/video/cx25821/cx25821-video.c
index 084fc0899e1..4d6907cda75 100644
--- a/drivers/staging/cx25821/cx25821-video.c
+++ b/drivers/media/video/cx25821/cx25821-video.c
@@ -1312,7 +1312,7 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
1312 return err; 1312 return err;
1313 } 1313 }
1314 1314
1315 if (i > 2) { 1315 if (i >= CX25821_NR_INPUT) {
1316 dprintk(1, "%s(): -EINVAL\n", __func__); 1316 dprintk(1, "%s(): -EINVAL\n", __func__);
1317 return -EINVAL; 1317 return -EINVAL;
1318 } 1318 }
diff --git a/drivers/staging/cx25821/cx25821-video.h b/drivers/media/video/cx25821/cx25821-video.h
index d0d9538ca5b..d0d9538ca5b 100644
--- a/drivers/staging/cx25821/cx25821-video.h
+++ b/drivers/media/video/cx25821/cx25821-video.h
diff --git a/drivers/staging/cx25821/cx25821.h b/drivers/media/video/cx25821/cx25821.h
index db2615b2bac..2d2d0093282 100644
--- a/drivers/staging/cx25821/cx25821.h
+++ b/drivers/media/video/cx25821/cx25821.h
@@ -98,6 +98,7 @@
98#define CX25821_BOARD_CONEXANT_ATHENA10 1 98#define CX25821_BOARD_CONEXANT_ATHENA10 1
99#define MAX_VID_CHANNEL_NUM 12 99#define MAX_VID_CHANNEL_NUM 12
100#define VID_CHANNEL_NUM 8 100#define VID_CHANNEL_NUM 8
101#define CX25821_NR_INPUT 2
101 102
102struct cx25821_fmt { 103struct cx25821_fmt {
103 char *name; 104 char *name;
@@ -196,7 +197,7 @@ struct cx25821_board {
196 unsigned char radio_addr; 197 unsigned char radio_addr;
197 198
198 u32 clk_freq; 199 u32 clk_freq;
199 struct cx25821_input input[2]; 200 struct cx25821_input input[CX25821_NR_INPUT];
200}; 201};
201 202
202struct cx25821_subid { 203struct cx25821_subid {
diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c
index 4240f0b720f..9b747c266af 100644
--- a/drivers/media/video/em28xx/em28xx-cards.c
+++ b/drivers/media/video/em28xx/em28xx-cards.c
@@ -1923,6 +1923,8 @@ struct usb_device_id em28xx_id_table[] = {
1923 .driver_info = EM2860_BOARD_TERRATEC_AV350 }, 1923 .driver_info = EM2860_BOARD_TERRATEC_AV350 },
1924 { USB_DEVICE(0x0ccd, 0x0096), 1924 { USB_DEVICE(0x0ccd, 0x0096),
1925 .driver_info = EM2860_BOARD_TERRATEC_GRABBY }, 1925 .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
1926 { USB_DEVICE(0x0ccd, 0x10AF),
1927 .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
1926 { USB_DEVICE(0x0fd9, 0x0033), 1928 { USB_DEVICE(0x0fd9, 0x0033),
1927 .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE}, 1929 .driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE},
1928 { USB_DEVICE(0x185b, 0x2870), 1930 { USB_DEVICE(0x185b, 0x2870),
diff --git a/drivers/media/video/imx074.c b/drivers/media/video/imx074.c
index 0382ea752e6..8775e262bb6 100644
--- a/drivers/media/video/imx074.c
+++ b/drivers/media/video/imx074.c
@@ -12,11 +12,11 @@
12 12
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/i2c.h> 14#include <linux/i2c.h>
15#include <linux/v4l2-mediabus.h>
15#include <linux/slab.h> 16#include <linux/slab.h>
16#include <linux/videodev2.h> 17#include <linux/videodev2.h>
17 18
18#include <media/soc_camera.h> 19#include <media/soc_camera.h>
19#include <media/soc_mediabus.h>
20#include <media/v4l2-subdev.h> 20#include <media/v4l2-subdev.h>
21#include <media/v4l2-chip-ident.h> 21#include <media/v4l2-chip-ident.h>
22 22
@@ -267,6 +267,17 @@ static int imx074_g_chip_ident(struct v4l2_subdev *sd,
267 return 0; 267 return 0;
268} 268}
269 269
270static int imx074_g_mbus_config(struct v4l2_subdev *sd,
271 struct v4l2_mbus_config *cfg)
272{
273 cfg->type = V4L2_MBUS_CSI2;
274 cfg->flags = V4L2_MBUS_CSI2_2_LANE |
275 V4L2_MBUS_CSI2_CHANNEL_0 |
276 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
277
278 return 0;
279}
280
270static struct v4l2_subdev_video_ops imx074_subdev_video_ops = { 281static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
271 .s_stream = imx074_s_stream, 282 .s_stream = imx074_s_stream,
272 .s_mbus_fmt = imx074_s_fmt, 283 .s_mbus_fmt = imx074_s_fmt,
@@ -275,6 +286,7 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
275 .enum_mbus_fmt = imx074_enum_fmt, 286 .enum_mbus_fmt = imx074_enum_fmt,
276 .g_crop = imx074_g_crop, 287 .g_crop = imx074_g_crop,
277 .cropcap = imx074_cropcap, 288 .cropcap = imx074_cropcap,
289 .g_mbus_config = imx074_g_mbus_config,
278}; 290};
279 291
280static struct v4l2_subdev_core_ops imx074_subdev_core_ops = { 292static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
@@ -286,28 +298,7 @@ static struct v4l2_subdev_ops imx074_subdev_ops = {
286 .video = &imx074_subdev_video_ops, 298 .video = &imx074_subdev_video_ops,
287}; 299};
288 300
289/* 301static int imx074_video_probe(struct i2c_client *client)
290 * We have to provide soc-camera operations, but we don't have anything to say
291 * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
292 */
293static unsigned long imx074_query_bus_param(struct soc_camera_device *icd)
294{
295 return 0;
296}
297
298static int imx074_set_bus_param(struct soc_camera_device *icd,
299 unsigned long flags)
300{
301 return -EINVAL;
302}
303
304static struct soc_camera_ops imx074_ops = {
305 .query_bus_param = imx074_query_bus_param,
306 .set_bus_param = imx074_set_bus_param,
307};
308
309static int imx074_video_probe(struct soc_camera_device *icd,
310 struct i2c_client *client)
311{ 302{
312 int ret; 303 int ret;
313 u16 id; 304 u16 id;
@@ -417,17 +408,10 @@ static int imx074_probe(struct i2c_client *client,
417 const struct i2c_device_id *did) 408 const struct i2c_device_id *did)
418{ 409{
419 struct imx074 *priv; 410 struct imx074 *priv;
420 struct soc_camera_device *icd = client->dev.platform_data;
421 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 411 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
422 struct soc_camera_link *icl; 412 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
423 int ret; 413 int ret;
424 414
425 if (!icd) {
426 dev_err(&client->dev, "IMX074: missing soc-camera data!\n");
427 return -EINVAL;
428 }
429
430 icl = to_soc_camera_link(icd);
431 if (!icl) { 415 if (!icl) {
432 dev_err(&client->dev, "IMX074: missing platform data!\n"); 416 dev_err(&client->dev, "IMX074: missing platform data!\n");
433 return -EINVAL; 417 return -EINVAL;
@@ -445,12 +429,10 @@ static int imx074_probe(struct i2c_client *client,
445 429
446 v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops); 430 v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops);
447 431
448 icd->ops = &imx074_ops;
449 priv->fmt = &imx074_colour_fmts[0]; 432 priv->fmt = &imx074_colour_fmts[0];
450 433
451 ret = imx074_video_probe(icd, client); 434 ret = imx074_video_probe(client);
452 if (ret < 0) { 435 if (ret < 0) {
453 icd->ops = NULL;
454 kfree(priv); 436 kfree(priv);
455 return ret; 437 return ret;
456 } 438 }
@@ -461,10 +443,8 @@ static int imx074_probe(struct i2c_client *client,
461static int imx074_remove(struct i2c_client *client) 443static int imx074_remove(struct i2c_client *client)
462{ 444{
463 struct imx074 *priv = to_imx074(client); 445 struct imx074 *priv = to_imx074(client);
464 struct soc_camera_device *icd = client->dev.platform_data; 446 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
465 struct soc_camera_link *icl = to_soc_camera_link(icd);
466 447
467 icd->ops = NULL;
468 if (icl->free_bus) 448 if (icl->free_bus)
469 icl->free_bus(icl); 449 icl->free_bus(icl);
470 kfree(priv); 450 kfree(priv);
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 0fb75524484..41108a9a195 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1180,6 +1180,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
1180 setup.addr = ADDR_UNSET; 1180 setup.addr = ADDR_UNSET;
1181 setup.type = itv->options.tuner; 1181 setup.type = itv->options.tuner;
1182 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */ 1182 setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
1183 if (itv->options.radio > 0)
1184 setup.mode_mask |= T_RADIO;
1183 setup.tuner_callback = (setup.type == TUNER_XC2028) ? 1185 setup.tuner_callback = (setup.type == TUNER_XC2028) ?
1184 ivtv_reset_tuner_gpio : NULL; 1186 ivtv_reset_tuner_gpio : NULL;
1185 ivtv_call_all(itv, tuner, s_type_addr, &setup); 1187 ivtv_call_all(itv, tuner, s_type_addr, &setup);
diff --git a/drivers/media/video/marvell-ccic/mcam-core.c b/drivers/media/video/marvell-ccic/mcam-core.c
index 1141b976dff..80ec64d2d6d 100644
--- a/drivers/media/video/marvell-ccic/mcam-core.c
+++ b/drivers/media/video/marvell-ccic/mcam-core.c
@@ -883,7 +883,8 @@ static int mcam_read_setup(struct mcam_camera *cam)
883 * Videobuf2 interface code. 883 * Videobuf2 interface code.
884 */ 884 */
885 885
886static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs, 886static int mcam_vb_queue_setup(struct vb2_queue *vq,
887 const struct v4l2_format *fmt, unsigned int *nbufs,
887 unsigned int *num_planes, unsigned int sizes[], 888 unsigned int *num_planes, unsigned int sizes[],
888 void *alloc_ctxs[]) 889 void *alloc_ctxs[])
889{ 890{
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c
index 9594b52f860..12897e8a331 100644
--- a/drivers/media/video/mem2mem_testdev.c
+++ b/drivers/media/video/mem2mem_testdev.c
@@ -738,9 +738,10 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
738 * Queue operations 738 * Queue operations
739 */ 739 */
740 740
741static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 741static int m2mtest_queue_setup(struct vb2_queue *vq,
742 unsigned int *nplanes, unsigned int sizes[], 742 const struct v4l2_format *fmt,
743 void *alloc_ctxs[]) 743 unsigned int *nbuffers, unsigned int *nplanes,
744 unsigned int sizes[], void *alloc_ctxs[])
744{ 745{
745 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq); 746 struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
746 struct m2mtest_q_data *q_data; 747 struct m2mtest_q_data *q_data;
diff --git a/drivers/media/video/mt9m001.c b/drivers/media/video/mt9m001.c
index 4da9cca939c..63ae5c61c9b 100644
--- a/drivers/media/video/mt9m001.c
+++ b/drivers/media/video/mt9m001.c
@@ -13,9 +13,11 @@
13#include <linux/i2c.h> 13#include <linux/i2c.h>
14#include <linux/log2.h> 14#include <linux/log2.h>
15 15
16#include <media/soc_camera.h>
17#include <media/soc_mediabus.h>
16#include <media/v4l2-subdev.h> 18#include <media/v4l2-subdev.h>
17#include <media/v4l2-chip-ident.h> 19#include <media/v4l2-chip-ident.h>
18#include <media/soc_camera.h> 20#include <media/v4l2-ctrls.h>
19 21
20/* 22/*
21 * mt9m001 i2c address 0x5d 23 * mt9m001 i2c address 0x5d
@@ -84,15 +86,19 @@ static const struct mt9m001_datafmt mt9m001_monochrome_fmts[] = {
84 86
85struct mt9m001 { 87struct mt9m001 {
86 struct v4l2_subdev subdev; 88 struct v4l2_subdev subdev;
89 struct v4l2_ctrl_handler hdl;
90 struct {
91 /* exposure/auto-exposure cluster */
92 struct v4l2_ctrl *autoexposure;
93 struct v4l2_ctrl *exposure;
94 };
87 struct v4l2_rect rect; /* Sensor window */ 95 struct v4l2_rect rect; /* Sensor window */
88 const struct mt9m001_datafmt *fmt; 96 const struct mt9m001_datafmt *fmt;
89 const struct mt9m001_datafmt *fmts; 97 const struct mt9m001_datafmt *fmts;
90 int num_fmts; 98 int num_fmts;
91 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */ 99 int model; /* V4L2_IDENT_MT9M001* codes from v4l2-chip-ident.h */
92 unsigned int gain; 100 unsigned int total_h;
93 unsigned int exposure;
94 unsigned short y_skip_top; /* Lines to skip at the top */ 101 unsigned short y_skip_top; /* Lines to skip at the top */
95 unsigned char autoexposure;
96}; 102};
97 103
98static struct mt9m001 *to_mt9m001(const struct i2c_client *client) 104static struct mt9m001 *to_mt9m001(const struct i2c_client *client)
@@ -165,54 +171,13 @@ static int mt9m001_s_stream(struct v4l2_subdev *sd, int enable)
165 return 0; 171 return 0;
166} 172}
167 173
168static int mt9m001_set_bus_param(struct soc_camera_device *icd,
169 unsigned long flags)
170{
171 struct soc_camera_link *icl = to_soc_camera_link(icd);
172 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
173
174 /* Only one width bit may be set */
175 if (!is_power_of_2(width_flag))
176 return -EINVAL;
177
178 if (icl->set_bus_param)
179 return icl->set_bus_param(icl, width_flag);
180
181 /*
182 * Without board specific bus width settings we only support the
183 * sensors native bus width
184 */
185 if (width_flag == SOCAM_DATAWIDTH_10)
186 return 0;
187
188 return -EINVAL;
189}
190
191static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
192{
193 struct soc_camera_link *icl = to_soc_camera_link(icd);
194 /* MT9M001 has all capture_format parameters fixed */
195 unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
196 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
197 SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
198
199 if (icl->query_bus_param)
200 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
201 else
202 flags |= SOCAM_DATAWIDTH_10;
203
204 return soc_camera_apply_sensor_flags(icl, flags);
205}
206
207static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 174static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
208{ 175{
209 struct i2c_client *client = v4l2_get_subdevdata(sd); 176 struct i2c_client *client = v4l2_get_subdevdata(sd);
210 struct mt9m001 *mt9m001 = to_mt9m001(client); 177 struct mt9m001 *mt9m001 = to_mt9m001(client);
211 struct v4l2_rect rect = a->c; 178 struct v4l2_rect rect = a->c;
212 struct soc_camera_device *icd = client->dev.platform_data;
213 int ret; 179 int ret;
214 const u16 hblank = 9, vblank = 25; 180 const u16 hblank = 9, vblank = 25;
215 unsigned int total_h;
216 181
217 if (mt9m001->fmts == mt9m001_colour_fmts) 182 if (mt9m001->fmts == mt9m001_colour_fmts)
218 /* 183 /*
@@ -231,7 +196,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
231 soc_camera_limit_side(&rect.top, &rect.height, 196 soc_camera_limit_side(&rect.top, &rect.height,
232 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT); 197 MT9M001_ROW_SKIP, MT9M001_MIN_HEIGHT, MT9M001_MAX_HEIGHT);
233 198
234 total_h = rect.height + mt9m001->y_skip_top + vblank; 199 mt9m001->total_h = rect.height + mt9m001->y_skip_top + vblank;
235 200
236 /* Blanking and start values - default... */ 201 /* Blanking and start values - default... */
237 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank); 202 ret = reg_write(client, MT9M001_HORIZONTAL_BLANKING, hblank);
@@ -240,7 +205,7 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
240 205
241 /* 206 /*
242 * The caller provides a supported format, as verified per 207 * The caller provides a supported format, as verified per
243 * call to icd->try_fmt() 208 * call to .try_mbus_fmt()
244 */ 209 */
245 if (!ret) 210 if (!ret)
246 ret = reg_write(client, MT9M001_COLUMN_START, rect.left); 211 ret = reg_write(client, MT9M001_COLUMN_START, rect.left);
@@ -251,17 +216,8 @@ static int mt9m001_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
251 if (!ret) 216 if (!ret)
252 ret = reg_write(client, MT9M001_WINDOW_HEIGHT, 217 ret = reg_write(client, MT9M001_WINDOW_HEIGHT,
253 rect.height + mt9m001->y_skip_top - 1); 218 rect.height + mt9m001->y_skip_top - 1);
254 if (!ret && mt9m001->autoexposure) { 219 if (!ret && v4l2_ctrl_g_ctrl(mt9m001->autoexposure) == V4L2_EXPOSURE_AUTO)
255 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, total_h); 220 ret = reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h);
256 if (!ret) {
257 const struct v4l2_queryctrl *qctrl =
258 soc_camera_find_qctrl(icd->ops,
259 V4L2_CID_EXPOSURE);
260 mt9m001->exposure = (524 + (total_h - 1) *
261 (qctrl->maximum - qctrl->minimum)) /
262 1048 + qctrl->minimum;
263 }
264 }
265 221
266 if (!ret) 222 if (!ret)
267 mt9m001->rect = rect; 223 mt9m001->rect = rect;
@@ -421,107 +377,48 @@ static int mt9m001_s_register(struct v4l2_subdev *sd,
421} 377}
422#endif 378#endif
423 379
424static const struct v4l2_queryctrl mt9m001_controls[] = { 380static int mt9m001_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
425 {
426 .id = V4L2_CID_VFLIP,
427 .type = V4L2_CTRL_TYPE_BOOLEAN,
428 .name = "Flip Vertically",
429 .minimum = 0,
430 .maximum = 1,
431 .step = 1,
432 .default_value = 0,
433 }, {
434 .id = V4L2_CID_GAIN,
435 .type = V4L2_CTRL_TYPE_INTEGER,
436 .name = "Gain",
437 .minimum = 0,
438 .maximum = 127,
439 .step = 1,
440 .default_value = 64,
441 .flags = V4L2_CTRL_FLAG_SLIDER,
442 }, {
443 .id = V4L2_CID_EXPOSURE,
444 .type = V4L2_CTRL_TYPE_INTEGER,
445 .name = "Exposure",
446 .minimum = 1,
447 .maximum = 255,
448 .step = 1,
449 .default_value = 255,
450 .flags = V4L2_CTRL_FLAG_SLIDER,
451 }, {
452 .id = V4L2_CID_EXPOSURE_AUTO,
453 .type = V4L2_CTRL_TYPE_BOOLEAN,
454 .name = "Automatic Exposure",
455 .minimum = 0,
456 .maximum = 1,
457 .step = 1,
458 .default_value = 1,
459 }
460};
461
462static struct soc_camera_ops mt9m001_ops = {
463 .set_bus_param = mt9m001_set_bus_param,
464 .query_bus_param = mt9m001_query_bus_param,
465 .controls = mt9m001_controls,
466 .num_controls = ARRAY_SIZE(mt9m001_controls),
467};
468
469static int mt9m001_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
470{ 381{
471 struct i2c_client *client = v4l2_get_subdevdata(sd); 382 struct mt9m001 *mt9m001 = container_of(ctrl->handler,
472 struct mt9m001 *mt9m001 = to_mt9m001(client); 383 struct mt9m001, hdl);
473 int data; 384 s32 min, max;
474 385
475 switch (ctrl->id) { 386 switch (ctrl->id) {
476 case V4L2_CID_VFLIP:
477 data = reg_read(client, MT9M001_READ_OPTIONS2);
478 if (data < 0)
479 return -EIO;
480 ctrl->value = !!(data & 0x8000);
481 break;
482 case V4L2_CID_EXPOSURE_AUTO: 387 case V4L2_CID_EXPOSURE_AUTO:
483 ctrl->value = mt9m001->autoexposure; 388 min = mt9m001->exposure->minimum;
484 break; 389 max = mt9m001->exposure->maximum;
485 case V4L2_CID_GAIN: 390 mt9m001->exposure->val =
486 ctrl->value = mt9m001->gain; 391 (524 + (mt9m001->total_h - 1) * (max - min)) / 1048 + min;
487 break;
488 case V4L2_CID_EXPOSURE:
489 ctrl->value = mt9m001->exposure;
490 break; 392 break;
491 } 393 }
492 return 0; 394 return 0;
493} 395}
494 396
495static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 397static int mt9m001_s_ctrl(struct v4l2_ctrl *ctrl)
496{ 398{
399 struct mt9m001 *mt9m001 = container_of(ctrl->handler,
400 struct mt9m001, hdl);
401 struct v4l2_subdev *sd = &mt9m001->subdev;
497 struct i2c_client *client = v4l2_get_subdevdata(sd); 402 struct i2c_client *client = v4l2_get_subdevdata(sd);
498 struct mt9m001 *mt9m001 = to_mt9m001(client); 403 struct v4l2_ctrl *exp = mt9m001->exposure;
499 struct soc_camera_device *icd = client->dev.platform_data;
500 const struct v4l2_queryctrl *qctrl;
501 int data; 404 int data;
502 405
503 qctrl = soc_camera_find_qctrl(&mt9m001_ops, ctrl->id);
504
505 if (!qctrl)
506 return -EINVAL;
507
508 switch (ctrl->id) { 406 switch (ctrl->id) {
509 case V4L2_CID_VFLIP: 407 case V4L2_CID_VFLIP:
510 if (ctrl->value) 408 if (ctrl->val)
511 data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000); 409 data = reg_set(client, MT9M001_READ_OPTIONS2, 0x8000);
512 else 410 else
513 data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000); 411 data = reg_clear(client, MT9M001_READ_OPTIONS2, 0x8000);
514 if (data < 0) 412 if (data < 0)
515 return -EIO; 413 return -EIO;
516 break; 414 return 0;
415
517 case V4L2_CID_GAIN: 416 case V4L2_CID_GAIN:
518 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
519 return -EINVAL;
520 /* See Datasheet Table 7, Gain settings. */ 417 /* See Datasheet Table 7, Gain settings. */
521 if (ctrl->value <= qctrl->default_value) { 418 if (ctrl->val <= ctrl->default_value) {
522 /* Pack it into 0..1 step 0.125, register values 0..8 */ 419 /* Pack it into 0..1 step 0.125, register values 0..8 */
523 unsigned long range = qctrl->default_value - qctrl->minimum; 420 unsigned long range = ctrl->default_value - ctrl->minimum;
524 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 421 data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
525 422
526 dev_dbg(&client->dev, "Setting gain %d\n", data); 423 dev_dbg(&client->dev, "Setting gain %d\n", data);
527 data = reg_write(client, MT9M001_GLOBAL_GAIN, data); 424 data = reg_write(client, MT9M001_GLOBAL_GAIN, data);
@@ -530,8 +427,8 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
530 } else { 427 } else {
531 /* Pack it into 1.125..15 variable step, register values 9..67 */ 428 /* Pack it into 1.125..15 variable step, register values 9..67 */
532 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ 429 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
533 unsigned long range = qctrl->maximum - qctrl->default_value - 1; 430 unsigned long range = ctrl->maximum - ctrl->default_value - 1;
534 unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * 431 unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
535 111 + range / 2) / range + 9; 432 111 + range / 2) / range + 9;
536 433
537 if (gain <= 32) 434 if (gain <= 32)
@@ -547,66 +444,44 @@ static int mt9m001_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
547 if (data < 0) 444 if (data < 0)
548 return -EIO; 445 return -EIO;
549 } 446 }
447 return 0;
550 448
551 /* Success */ 449 case V4L2_CID_EXPOSURE_AUTO:
552 mt9m001->gain = ctrl->value; 450 if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
553 break; 451 unsigned long range = exp->maximum - exp->minimum;
554 case V4L2_CID_EXPOSURE: 452 unsigned long shutter = ((exp->val - exp->minimum) * 1048 +
555 /* mt9m001 has maximum == default */
556 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
557 return -EINVAL;
558 else {
559 unsigned long range = qctrl->maximum - qctrl->minimum;
560 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 1048 +
561 range / 2) / range + 1; 453 range / 2) / range + 1;
562 454
563 dev_dbg(&client->dev, 455 dev_dbg(&client->dev,
564 "Setting shutter width from %d to %lu\n", 456 "Setting shutter width from %d to %lu\n",
565 reg_read(client, MT9M001_SHUTTER_WIDTH), 457 reg_read(client, MT9M001_SHUTTER_WIDTH), shutter);
566 shutter);
567 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0) 458 if (reg_write(client, MT9M001_SHUTTER_WIDTH, shutter) < 0)
568 return -EIO; 459 return -EIO;
569 mt9m001->exposure = ctrl->value; 460 } else {
570 mt9m001->autoexposure = 0;
571 }
572 break;
573 case V4L2_CID_EXPOSURE_AUTO:
574 if (ctrl->value) {
575 const u16 vblank = 25; 461 const u16 vblank = 25;
576 unsigned int total_h = mt9m001->rect.height + 462
463 mt9m001->total_h = mt9m001->rect.height +
577 mt9m001->y_skip_top + vblank; 464 mt9m001->y_skip_top + vblank;
578 if (reg_write(client, MT9M001_SHUTTER_WIDTH, 465 if (reg_write(client, MT9M001_SHUTTER_WIDTH, mt9m001->total_h) < 0)
579 total_h) < 0)
580 return -EIO; 466 return -EIO;
581 qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); 467 }
582 mt9m001->exposure = (524 + (total_h - 1) * 468 return 0;
583 (qctrl->maximum - qctrl->minimum)) /
584 1048 + qctrl->minimum;
585 mt9m001->autoexposure = 1;
586 } else
587 mt9m001->autoexposure = 0;
588 break;
589 } 469 }
590 return 0; 470 return -EINVAL;
591} 471}
592 472
593/* 473/*
594 * Interface active, can use i2c. If it fails, it can indeed mean, that 474 * Interface active, can use i2c. If it fails, it can indeed mean, that
595 * this wasn't our capture interface, so, we wait for the right one 475 * this wasn't our capture interface, so, we wait for the right one
596 */ 476 */
597static int mt9m001_video_probe(struct soc_camera_device *icd, 477static int mt9m001_video_probe(struct soc_camera_link *icl,
598 struct i2c_client *client) 478 struct i2c_client *client)
599{ 479{
600 struct mt9m001 *mt9m001 = to_mt9m001(client); 480 struct mt9m001 *mt9m001 = to_mt9m001(client);
601 struct soc_camera_link *icl = to_soc_camera_link(icd);
602 s32 data; 481 s32 data;
603 unsigned long flags; 482 unsigned long flags;
604 int ret; 483 int ret;
605 484
606 /* We must have a parent by now. And it cannot be a wrong one. */
607 BUG_ON(!icd->parent ||
608 to_soc_camera_host(icd->parent)->nr != icd->iface);
609
610 /* Enable the chip */ 485 /* Enable the chip */
611 data = reg_write(client, MT9M001_CHIP_ENABLE, 1); 486 data = reg_write(client, MT9M001_CHIP_ENABLE, 1);
612 dev_dbg(&client->dev, "write: %d\n", data); 487 dev_dbg(&client->dev, "write: %d\n", data);
@@ -661,18 +536,11 @@ static int mt9m001_video_probe(struct soc_camera_device *icd,
661 dev_err(&client->dev, "Failed to initialise the camera\n"); 536 dev_err(&client->dev, "Failed to initialise the camera\n");
662 537
663 /* mt9m001_init() has reset the chip, returning registers to defaults */ 538 /* mt9m001_init() has reset the chip, returning registers to defaults */
664 mt9m001->gain = 64; 539 return v4l2_ctrl_handler_setup(&mt9m001->hdl);
665 mt9m001->exposure = 255;
666
667 return ret;
668} 540}
669 541
670static void mt9m001_video_remove(struct soc_camera_device *icd) 542static void mt9m001_video_remove(struct soc_camera_link *icl)
671{ 543{
672 struct soc_camera_link *icl = to_soc_camera_link(icd);
673
674 dev_dbg(icd->pdev, "Video removed: %p, %p\n",
675 icd->parent, icd->vdev);
676 if (icl->free_bus) 544 if (icl->free_bus)
677 icl->free_bus(icl); 545 icl->free_bus(icl);
678} 546}
@@ -687,9 +555,12 @@ static int mt9m001_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
687 return 0; 555 return 0;
688} 556}
689 557
558static const struct v4l2_ctrl_ops mt9m001_ctrl_ops = {
559 .g_volatile_ctrl = mt9m001_g_volatile_ctrl,
560 .s_ctrl = mt9m001_s_ctrl,
561};
562
690static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = { 563static struct v4l2_subdev_core_ops mt9m001_subdev_core_ops = {
691 .g_ctrl = mt9m001_g_ctrl,
692 .s_ctrl = mt9m001_s_ctrl,
693 .g_chip_ident = mt9m001_g_chip_ident, 564 .g_chip_ident = mt9m001_g_chip_ident,
694#ifdef CONFIG_VIDEO_ADV_DEBUG 565#ifdef CONFIG_VIDEO_ADV_DEBUG
695 .g_register = mt9m001_g_register, 566 .g_register = mt9m001_g_register,
@@ -710,6 +581,40 @@ static int mt9m001_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
710 return 0; 581 return 0;
711} 582}
712 583
584static int mt9m001_g_mbus_config(struct v4l2_subdev *sd,
585 struct v4l2_mbus_config *cfg)
586{
587 struct i2c_client *client = v4l2_get_subdevdata(sd);
588 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
589
590 /* MT9M001 has all capture_format parameters fixed */
591 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_FALLING |
592 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
593 V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_MASTER;
594 cfg->type = V4L2_MBUS_PARALLEL;
595 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
596
597 return 0;
598}
599
600static int mt9m001_s_mbus_config(struct v4l2_subdev *sd,
601 const struct v4l2_mbus_config *cfg)
602{
603 const struct i2c_client *client = v4l2_get_subdevdata(sd);
604 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
605 struct mt9m001 *mt9m001 = to_mt9m001(client);
606 unsigned int bps = soc_mbus_get_fmtdesc(mt9m001->fmt->code)->bits_per_sample;
607
608 if (icl->set_bus_param)
609 return icl->set_bus_param(icl, 1 << (bps - 1));
610
611 /*
612 * Without board specific bus width settings we only support the
613 * sensors native bus width
614 */
615 return bps == 10 ? 0 : -EINVAL;
616}
617
713static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = { 618static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
714 .s_stream = mt9m001_s_stream, 619 .s_stream = mt9m001_s_stream,
715 .s_mbus_fmt = mt9m001_s_fmt, 620 .s_mbus_fmt = mt9m001_s_fmt,
@@ -719,6 +624,8 @@ static struct v4l2_subdev_video_ops mt9m001_subdev_video_ops = {
719 .g_crop = mt9m001_g_crop, 624 .g_crop = mt9m001_g_crop,
720 .cropcap = mt9m001_cropcap, 625 .cropcap = mt9m001_cropcap,
721 .enum_mbus_fmt = mt9m001_enum_fmt, 626 .enum_mbus_fmt = mt9m001_enum_fmt,
627 .g_mbus_config = mt9m001_g_mbus_config,
628 .s_mbus_config = mt9m001_s_mbus_config,
722}; 629};
723 630
724static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = { 631static struct v4l2_subdev_sensor_ops mt9m001_subdev_sensor_ops = {
@@ -735,17 +642,10 @@ static int mt9m001_probe(struct i2c_client *client,
735 const struct i2c_device_id *did) 642 const struct i2c_device_id *did)
736{ 643{
737 struct mt9m001 *mt9m001; 644 struct mt9m001 *mt9m001;
738 struct soc_camera_device *icd = client->dev.platform_data;
739 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 645 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
740 struct soc_camera_link *icl; 646 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
741 int ret; 647 int ret;
742 648
743 if (!icd) {
744 dev_err(&client->dev, "MT9M001: missing soc-camera data!\n");
745 return -EINVAL;
746 }
747
748 icl = to_soc_camera_link(icd);
749 if (!icl) { 649 if (!icl) {
750 dev_err(&client->dev, "MT9M001 driver needs platform data\n"); 650 dev_err(&client->dev, "MT9M001 driver needs platform data\n");
751 return -EINVAL; 651 return -EINVAL;
@@ -762,25 +662,40 @@ static int mt9m001_probe(struct i2c_client *client,
762 return -ENOMEM; 662 return -ENOMEM;
763 663
764 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops); 664 v4l2_i2c_subdev_init(&mt9m001->subdev, client, &mt9m001_subdev_ops);
665 v4l2_ctrl_handler_init(&mt9m001->hdl, 4);
666 v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
667 V4L2_CID_VFLIP, 0, 1, 1, 0);
668 v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
669 V4L2_CID_GAIN, 0, 127, 1, 64);
670 mt9m001->exposure = v4l2_ctrl_new_std(&mt9m001->hdl, &mt9m001_ctrl_ops,
671 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
672 /*
673 * Simulated autoexposure. If enabled, we calculate shutter width
674 * ourselves in the driver based on vertical blanking and frame width
675 */
676 mt9m001->autoexposure = v4l2_ctrl_new_std_menu(&mt9m001->hdl,
677 &mt9m001_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
678 V4L2_EXPOSURE_AUTO);
679 mt9m001->subdev.ctrl_handler = &mt9m001->hdl;
680 if (mt9m001->hdl.error) {
681 int err = mt9m001->hdl.error;
765 682
766 /* Second stage probe - when a capture adapter is there */ 683 kfree(mt9m001);
767 icd->ops = &mt9m001_ops; 684 return err;
685 }
686 v4l2_ctrl_auto_cluster(2, &mt9m001->autoexposure,
687 V4L2_EXPOSURE_MANUAL, true);
768 688
689 /* Second stage probe - when a capture adapter is there */
769 mt9m001->y_skip_top = 0; 690 mt9m001->y_skip_top = 0;
770 mt9m001->rect.left = MT9M001_COLUMN_SKIP; 691 mt9m001->rect.left = MT9M001_COLUMN_SKIP;
771 mt9m001->rect.top = MT9M001_ROW_SKIP; 692 mt9m001->rect.top = MT9M001_ROW_SKIP;
772 mt9m001->rect.width = MT9M001_MAX_WIDTH; 693 mt9m001->rect.width = MT9M001_MAX_WIDTH;
773 mt9m001->rect.height = MT9M001_MAX_HEIGHT; 694 mt9m001->rect.height = MT9M001_MAX_HEIGHT;
774 695
775 /* 696 ret = mt9m001_video_probe(icl, client);
776 * Simulated autoexposure. If enabled, we calculate shutter width
777 * ourselves in the driver based on vertical blanking and frame width
778 */
779 mt9m001->autoexposure = 1;
780
781 ret = mt9m001_video_probe(icd, client);
782 if (ret) { 697 if (ret) {
783 icd->ops = NULL; 698 v4l2_ctrl_handler_free(&mt9m001->hdl);
784 kfree(mt9m001); 699 kfree(mt9m001);
785 } 700 }
786 701
@@ -790,10 +705,11 @@ static int mt9m001_probe(struct i2c_client *client,
790static int mt9m001_remove(struct i2c_client *client) 705static int mt9m001_remove(struct i2c_client *client)
791{ 706{
792 struct mt9m001 *mt9m001 = to_mt9m001(client); 707 struct mt9m001 *mt9m001 = to_mt9m001(client);
793 struct soc_camera_device *icd = client->dev.platform_data; 708 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
794 709
795 icd->ops = NULL; 710 v4l2_device_unregister_subdev(&mt9m001->subdev);
796 mt9m001_video_remove(icd); 711 v4l2_ctrl_handler_free(&mt9m001->hdl);
712 mt9m001_video_remove(icl);
797 kfree(mt9m001); 713 kfree(mt9m001);
798 714
799 return 0; 715 return 0;
diff --git a/drivers/media/video/mt9m111.c b/drivers/media/video/mt9m111.c
index 07af26e6beb..f023cc092c2 100644
--- a/drivers/media/video/mt9m111.c
+++ b/drivers/media/video/mt9m111.c
@@ -13,10 +13,12 @@
13#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/gpio.h> 14#include <linux/gpio.h>
15#include <linux/delay.h> 15#include <linux/delay.h>
16#include <linux/v4l2-mediabus.h>
16 17
18#include <media/soc_camera.h>
17#include <media/v4l2-common.h> 19#include <media/v4l2-common.h>
20#include <media/v4l2-ctrls.h>
18#include <media/v4l2-chip-ident.h> 21#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h>
20 22
21/* 23/*
22 * MT9M111, MT9M112 and MT9M131: 24 * MT9M111, MT9M112 and MT9M131:
@@ -177,6 +179,8 @@ enum mt9m111_context {
177 179
178struct mt9m111 { 180struct mt9m111 {
179 struct v4l2_subdev subdev; 181 struct v4l2_subdev subdev;
182 struct v4l2_ctrl_handler hdl;
183 struct v4l2_ctrl *gain;
180 int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code 184 int model; /* V4L2_IDENT_MT9M111 or V4L2_IDENT_MT9M112 code
181 * from v4l2-chip-ident.h */ 185 * from v4l2-chip-ident.h */
182 enum mt9m111_context context; 186 enum mt9m111_context context;
@@ -185,13 +189,8 @@ struct mt9m111 {
185 int power_count; 189 int power_count;
186 const struct mt9m111_datafmt *fmt; 190 const struct mt9m111_datafmt *fmt;
187 int lastpage; /* PageMap cache value */ 191 int lastpage; /* PageMap cache value */
188 unsigned int gain;
189 unsigned char autoexposure;
190 unsigned char datawidth; 192 unsigned char datawidth;
191 unsigned int powered:1; 193 unsigned int powered:1;
192 unsigned int hflip:1;
193 unsigned int vflip:1;
194 unsigned int autowhitebalance:1;
195}; 194};
196 195
197static struct mt9m111 *to_mt9m111(const struct i2c_client *client) 196static struct mt9m111 *to_mt9m111(const struct i2c_client *client)
@@ -363,21 +362,6 @@ static int mt9m111_reset(struct mt9m111 *mt9m111)
363 return ret; 362 return ret;
364} 363}
365 364
366static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd)
367{
368 struct soc_camera_link *icl = to_soc_camera_link(icd);
369 unsigned long flags = SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING |
370 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
371 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
372
373 return soc_camera_apply_sensor_flags(icl, flags);
374}
375
376static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f)
377{
378 return 0;
379}
380
381static int mt9m111_make_rect(struct mt9m111 *mt9m111, 365static int mt9m111_make_rect(struct mt9m111 *mt9m111,
382 struct v4l2_rect *rect) 366 struct v4l2_rect *rect)
383{ 367{
@@ -660,50 +644,6 @@ static int mt9m111_s_register(struct v4l2_subdev *sd,
660} 644}
661#endif 645#endif
662 646
663static const struct v4l2_queryctrl mt9m111_controls[] = {
664 {
665 .id = V4L2_CID_VFLIP,
666 .type = V4L2_CTRL_TYPE_BOOLEAN,
667 .name = "Flip Verticaly",
668 .minimum = 0,
669 .maximum = 1,
670 .step = 1,
671 .default_value = 0,
672 }, {
673 .id = V4L2_CID_HFLIP,
674 .type = V4L2_CTRL_TYPE_BOOLEAN,
675 .name = "Flip Horizontaly",
676 .minimum = 0,
677 .maximum = 1,
678 .step = 1,
679 .default_value = 0,
680 }, { /* gain = 1/32*val (=>gain=1 if val==32) */
681 .id = V4L2_CID_GAIN,
682 .type = V4L2_CTRL_TYPE_INTEGER,
683 .name = "Gain",
684 .minimum = 0,
685 .maximum = 63 * 2 * 2,
686 .step = 1,
687 .default_value = 32,
688 .flags = V4L2_CTRL_FLAG_SLIDER,
689 }, {
690 .id = V4L2_CID_EXPOSURE_AUTO,
691 .type = V4L2_CTRL_TYPE_BOOLEAN,
692 .name = "Auto Exposure",
693 .minimum = 0,
694 .maximum = 1,
695 .step = 1,
696 .default_value = 1,
697 }
698};
699
700static struct soc_camera_ops mt9m111_ops = {
701 .query_bus_param = mt9m111_query_bus_param,
702 .set_bus_param = mt9m111_set_bus_param,
703 .controls = mt9m111_controls,
704 .num_controls = ARRAY_SIZE(mt9m111_controls),
705};
706
707static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask) 647static int mt9m111_set_flip(struct mt9m111 *mt9m111, int flip, int mask)
708{ 648{
709 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); 649 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
@@ -744,7 +684,6 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
744 if (gain > 63 * 2 * 2) 684 if (gain > 63 * 2 * 2)
745 return -EINVAL; 685 return -EINVAL;
746 686
747 mt9m111->gain = gain;
748 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) 687 if ((gain >= 64 * 2) && (gain < 63 * 2 * 2))
749 val = (1 << 10) | (1 << 9) | (gain / 4); 688 val = (1 << 10) | (1 << 9) | (gain / 4);
750 else if ((gain >= 64) && (gain < 64 * 2)) 689 else if ((gain >= 64) && (gain < 64 * 2))
@@ -758,118 +697,47 @@ static int mt9m111_set_global_gain(struct mt9m111 *mt9m111, int gain)
758static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on) 697static int mt9m111_set_autoexposure(struct mt9m111 *mt9m111, int on)
759{ 698{
760 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); 699 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
761 int ret;
762 700
763 if (on) 701 if (on)
764 ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); 702 return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
765 else 703 return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
766 ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN);
767
768 if (!ret)
769 mt9m111->autoexposure = on;
770
771 return ret;
772} 704}
773 705
774static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on) 706static int mt9m111_set_autowhitebalance(struct mt9m111 *mt9m111, int on)
775{ 707{
776 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev); 708 struct i2c_client *client = v4l2_get_subdevdata(&mt9m111->subdev);
777 int ret;
778 709
779 if (on) 710 if (on)
780 ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN); 711 return reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
781 else 712 return reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
782 ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOWHITEBAL_EN);
783
784 if (!ret)
785 mt9m111->autowhitebalance = on;
786
787 return ret;
788}
789
790static int mt9m111_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
791{
792 struct i2c_client *client = v4l2_get_subdevdata(sd);
793 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev);
794 int data;
795
796 switch (ctrl->id) {
797 case V4L2_CID_VFLIP:
798 if (mt9m111->context == HIGHPOWER)
799 data = reg_read(READ_MODE_B);
800 else
801 data = reg_read(READ_MODE_A);
802
803 if (data < 0)
804 return -EIO;
805 ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS);
806 break;
807 case V4L2_CID_HFLIP:
808 if (mt9m111->context == HIGHPOWER)
809 data = reg_read(READ_MODE_B);
810 else
811 data = reg_read(READ_MODE_A);
812
813 if (data < 0)
814 return -EIO;
815 ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS);
816 break;
817 case V4L2_CID_GAIN:
818 data = mt9m111_get_global_gain(mt9m111);
819 if (data < 0)
820 return data;
821 ctrl->value = data;
822 break;
823 case V4L2_CID_EXPOSURE_AUTO:
824 ctrl->value = mt9m111->autoexposure;
825 break;
826 case V4L2_CID_AUTO_WHITE_BALANCE:
827 ctrl->value = mt9m111->autowhitebalance;
828 break;
829 }
830 return 0;
831} 713}
832 714
833static int mt9m111_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 715static int mt9m111_s_ctrl(struct v4l2_ctrl *ctrl)
834{ 716{
835 struct mt9m111 *mt9m111 = container_of(sd, struct mt9m111, subdev); 717 struct mt9m111 *mt9m111 = container_of(ctrl->handler,
836 const struct v4l2_queryctrl *qctrl; 718 struct mt9m111, hdl);
837 int ret;
838
839 qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id);
840 if (!qctrl)
841 return -EINVAL;
842 719
843 switch (ctrl->id) { 720 switch (ctrl->id) {
844 case V4L2_CID_VFLIP: 721 case V4L2_CID_VFLIP:
845 mt9m111->vflip = ctrl->value; 722 return mt9m111_set_flip(mt9m111, ctrl->val,
846 ret = mt9m111_set_flip(mt9m111, ctrl->value,
847 MT9M111_RMB_MIRROR_ROWS); 723 MT9M111_RMB_MIRROR_ROWS);
848 break;
849 case V4L2_CID_HFLIP: 724 case V4L2_CID_HFLIP:
850 mt9m111->hflip = ctrl->value; 725 return mt9m111_set_flip(mt9m111, ctrl->val,
851 ret = mt9m111_set_flip(mt9m111, ctrl->value,
852 MT9M111_RMB_MIRROR_COLS); 726 MT9M111_RMB_MIRROR_COLS);
853 break;
854 case V4L2_CID_GAIN: 727 case V4L2_CID_GAIN:
855 ret = mt9m111_set_global_gain(mt9m111, ctrl->value); 728 return mt9m111_set_global_gain(mt9m111, ctrl->val);
856 break;
857 case V4L2_CID_EXPOSURE_AUTO: 729 case V4L2_CID_EXPOSURE_AUTO:
858 ret = mt9m111_set_autoexposure(mt9m111, ctrl->value); 730 return mt9m111_set_autoexposure(mt9m111, ctrl->val);
859 break;
860 case V4L2_CID_AUTO_WHITE_BALANCE: 731 case V4L2_CID_AUTO_WHITE_BALANCE:
861 ret = mt9m111_set_autowhitebalance(mt9m111, ctrl->value); 732 return mt9m111_set_autowhitebalance(mt9m111, ctrl->val);
862 break;
863 default:
864 ret = -EINVAL;
865 } 733 }
866 734
867 return ret; 735 return -EINVAL;
868} 736}
869 737
870static int mt9m111_suspend(struct mt9m111 *mt9m111) 738static int mt9m111_suspend(struct mt9m111 *mt9m111)
871{ 739{
872 mt9m111->gain = mt9m111_get_global_gain(mt9m111); 740 v4l2_ctrl_s_ctrl(mt9m111->gain, mt9m111_get_global_gain(mt9m111));
873 741
874 return 0; 742 return 0;
875} 743}
@@ -879,11 +747,7 @@ static void mt9m111_restore_state(struct mt9m111 *mt9m111)
879 mt9m111_set_context(mt9m111, mt9m111->context); 747 mt9m111_set_context(mt9m111, mt9m111->context);
880 mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code); 748 mt9m111_set_pixfmt(mt9m111, mt9m111->fmt->code);
881 mt9m111_setup_rect(mt9m111, &mt9m111->rect); 749 mt9m111_setup_rect(mt9m111, &mt9m111->rect);
882 mt9m111_set_flip(mt9m111, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); 750 v4l2_ctrl_handler_setup(&mt9m111->hdl);
883 mt9m111_set_flip(mt9m111, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS);
884 mt9m111_set_global_gain(mt9m111, mt9m111->gain);
885 mt9m111_set_autoexposure(mt9m111, mt9m111->autoexposure);
886 mt9m111_set_autowhitebalance(mt9m111, mt9m111->autowhitebalance);
887} 751}
888 752
889static int mt9m111_resume(struct mt9m111 *mt9m111) 753static int mt9m111_resume(struct mt9m111 *mt9m111)
@@ -911,8 +775,6 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
911 ret = mt9m111_reset(mt9m111); 775 ret = mt9m111_reset(mt9m111);
912 if (!ret) 776 if (!ret)
913 ret = mt9m111_set_context(mt9m111, mt9m111->context); 777 ret = mt9m111_set_context(mt9m111, mt9m111->context);
914 if (!ret)
915 ret = mt9m111_set_autoexposure(mt9m111, mt9m111->autoexposure);
916 if (ret) 778 if (ret)
917 dev_err(&client->dev, "mt9m111 init failed: %d\n", ret); 779 dev_err(&client->dev, "mt9m111 init failed: %d\n", ret);
918 return ret; 780 return ret;
@@ -922,22 +784,12 @@ static int mt9m111_init(struct mt9m111 *mt9m111)
922 * Interface active, can use i2c. If it fails, it can indeed mean, that 784 * Interface active, can use i2c. If it fails, it can indeed mean, that
923 * this wasn't our capture interface, so, we wait for the right one 785 * this wasn't our capture interface, so, we wait for the right one
924 */ 786 */
925static int mt9m111_video_probe(struct soc_camera_device *icd, 787static int mt9m111_video_probe(struct i2c_client *client)
926 struct i2c_client *client)
927{ 788{
928 struct mt9m111 *mt9m111 = to_mt9m111(client); 789 struct mt9m111 *mt9m111 = to_mt9m111(client);
929 s32 data; 790 s32 data;
930 int ret; 791 int ret;
931 792
932 /* We must have a parent by now. And it cannot be a wrong one. */
933 BUG_ON(!icd->parent ||
934 to_soc_camera_host(icd->parent)->nr != icd->iface);
935
936 mt9m111->lastpage = -1;
937
938 mt9m111->autoexposure = 1;
939 mt9m111->autowhitebalance = 1;
940
941 data = reg_read(CHIP_VERSION); 793 data = reg_read(CHIP_VERSION);
942 794
943 switch (data) { 795 switch (data) {
@@ -951,17 +803,16 @@ static int mt9m111_video_probe(struct soc_camera_device *icd,
951 dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data); 803 dev_info(&client->dev, "Detected a MT9M112 chip ID %x\n", data);
952 break; 804 break;
953 default: 805 default:
954 ret = -ENODEV;
955 dev_err(&client->dev, 806 dev_err(&client->dev,
956 "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n", 807 "No MT9M111/MT9M112/MT9M131 chip detected register read %x\n",
957 data); 808 data);
958 goto ei2c; 809 return -ENODEV;
959 } 810 }
960 811
961 ret = mt9m111_init(mt9m111); 812 ret = mt9m111_init(mt9m111);
962 813 if (ret)
963ei2c: 814 return ret;
964 return ret; 815 return v4l2_ctrl_handler_setup(&mt9m111->hdl);
965} 816}
966 817
967static int mt9m111_s_power(struct v4l2_subdev *sd, int on) 818static int mt9m111_s_power(struct v4l2_subdev *sd, int on)
@@ -998,9 +849,11 @@ out:
998 return ret; 849 return ret;
999} 850}
1000 851
852static const struct v4l2_ctrl_ops mt9m111_ctrl_ops = {
853 .s_ctrl = mt9m111_s_ctrl,
854};
855
1001static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = { 856static struct v4l2_subdev_core_ops mt9m111_subdev_core_ops = {
1002 .g_ctrl = mt9m111_g_ctrl,
1003 .s_ctrl = mt9m111_s_ctrl,
1004 .g_chip_ident = mt9m111_g_chip_ident, 857 .g_chip_ident = mt9m111_g_chip_ident,
1005 .s_power = mt9m111_s_power, 858 .s_power = mt9m111_s_power,
1006#ifdef CONFIG_VIDEO_ADV_DEBUG 859#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -1019,6 +872,21 @@ static int mt9m111_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1019 return 0; 872 return 0;
1020} 873}
1021 874
875static int mt9m111_g_mbus_config(struct v4l2_subdev *sd,
876 struct v4l2_mbus_config *cfg)
877{
878 struct i2c_client *client = v4l2_get_subdevdata(sd);
879 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
880
881 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
882 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
883 V4L2_MBUS_DATA_ACTIVE_HIGH;
884 cfg->type = V4L2_MBUS_PARALLEL;
885 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
886
887 return 0;
888}
889
1022static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = { 890static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
1023 .s_mbus_fmt = mt9m111_s_fmt, 891 .s_mbus_fmt = mt9m111_s_fmt,
1024 .g_mbus_fmt = mt9m111_g_fmt, 892 .g_mbus_fmt = mt9m111_g_fmt,
@@ -1027,6 +895,7 @@ static struct v4l2_subdev_video_ops mt9m111_subdev_video_ops = {
1027 .g_crop = mt9m111_g_crop, 895 .g_crop = mt9m111_g_crop,
1028 .cropcap = mt9m111_cropcap, 896 .cropcap = mt9m111_cropcap,
1029 .enum_mbus_fmt = mt9m111_enum_fmt, 897 .enum_mbus_fmt = mt9m111_enum_fmt,
898 .g_mbus_config = mt9m111_g_mbus_config,
1030}; 899};
1031 900
1032static struct v4l2_subdev_ops mt9m111_subdev_ops = { 901static struct v4l2_subdev_ops mt9m111_subdev_ops = {
@@ -1038,17 +907,10 @@ static int mt9m111_probe(struct i2c_client *client,
1038 const struct i2c_device_id *did) 907 const struct i2c_device_id *did)
1039{ 908{
1040 struct mt9m111 *mt9m111; 909 struct mt9m111 *mt9m111;
1041 struct soc_camera_device *icd = client->dev.platform_data;
1042 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 910 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1043 struct soc_camera_link *icl; 911 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1044 int ret; 912 int ret;
1045 913
1046 if (!icd) {
1047 dev_err(&client->dev, "mt9m111: soc-camera data missing!\n");
1048 return -EINVAL;
1049 }
1050
1051 icl = to_soc_camera_link(icd);
1052 if (!icl) { 914 if (!icl) {
1053 dev_err(&client->dev, "mt9m111: driver needs platform data\n"); 915 dev_err(&client->dev, "mt9m111: driver needs platform data\n");
1054 return -EINVAL; 916 return -EINVAL;
@@ -1065,19 +927,37 @@ static int mt9m111_probe(struct i2c_client *client,
1065 return -ENOMEM; 927 return -ENOMEM;
1066 928
1067 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops); 929 v4l2_i2c_subdev_init(&mt9m111->subdev, client, &mt9m111_subdev_ops);
930 v4l2_ctrl_handler_init(&mt9m111->hdl, 5);
931 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
932 V4L2_CID_VFLIP, 0, 1, 1, 0);
933 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
934 V4L2_CID_HFLIP, 0, 1, 1, 0);
935 v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
936 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
937 mt9m111->gain = v4l2_ctrl_new_std(&mt9m111->hdl, &mt9m111_ctrl_ops,
938 V4L2_CID_GAIN, 0, 63 * 2 * 2, 1, 32);
939 v4l2_ctrl_new_std_menu(&mt9m111->hdl,
940 &mt9m111_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
941 V4L2_EXPOSURE_AUTO);
942 mt9m111->subdev.ctrl_handler = &mt9m111->hdl;
943 if (mt9m111->hdl.error) {
944 int err = mt9m111->hdl.error;
1068 945
1069 /* Second stage probe - when a capture adapter is there */ 946 kfree(mt9m111);
1070 icd->ops = &mt9m111_ops; 947 return err;
948 }
1071 949
950 /* Second stage probe - when a capture adapter is there */
1072 mt9m111->rect.left = MT9M111_MIN_DARK_COLS; 951 mt9m111->rect.left = MT9M111_MIN_DARK_COLS;
1073 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS; 952 mt9m111->rect.top = MT9M111_MIN_DARK_ROWS;
1074 mt9m111->rect.width = MT9M111_MAX_WIDTH; 953 mt9m111->rect.width = MT9M111_MAX_WIDTH;
1075 mt9m111->rect.height = MT9M111_MAX_HEIGHT; 954 mt9m111->rect.height = MT9M111_MAX_HEIGHT;
1076 mt9m111->fmt = &mt9m111_colour_fmts[0]; 955 mt9m111->fmt = &mt9m111_colour_fmts[0];
956 mt9m111->lastpage = -1;
1077 957
1078 ret = mt9m111_video_probe(icd, client); 958 ret = mt9m111_video_probe(client);
1079 if (ret) { 959 if (ret) {
1080 icd->ops = NULL; 960 v4l2_ctrl_handler_free(&mt9m111->hdl);
1081 kfree(mt9m111); 961 kfree(mt9m111);
1082 } 962 }
1083 963
@@ -1087,9 +967,9 @@ static int mt9m111_probe(struct i2c_client *client,
1087static int mt9m111_remove(struct i2c_client *client) 967static int mt9m111_remove(struct i2c_client *client)
1088{ 968{
1089 struct mt9m111 *mt9m111 = to_mt9m111(client); 969 struct mt9m111 *mt9m111 = to_mt9m111(client);
1090 struct soc_camera_device *icd = client->dev.platform_data;
1091 970
1092 icd->ops = NULL; 971 v4l2_device_unregister_subdev(&mt9m111->subdev);
972 v4l2_ctrl_handler_free(&mt9m111->hdl);
1093 kfree(mt9m111); 973 kfree(mt9m111);
1094 974
1095 return 0; 975 return 0;
diff --git a/drivers/media/video/mt9t031.c b/drivers/media/video/mt9t031.c
index 30547cc3f89..7ee84cc578b 100644
--- a/drivers/media/video/mt9t031.c
+++ b/drivers/media/video/mt9t031.c
@@ -13,11 +13,20 @@
13#include <linux/log2.h> 13#include <linux/log2.h>
14#include <linux/pm.h> 14#include <linux/pm.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/v4l2-mediabus.h>
16#include <linux/videodev2.h> 17#include <linux/videodev2.h>
17 18
18#include <media/soc_camera.h> 19#include <media/soc_camera.h>
19#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
20#include <media/v4l2-subdev.h> 21#include <media/v4l2-subdev.h>
22#include <media/v4l2-ctrls.h>
23
24/*
25 * ATTENTION: this driver still cannot be used outside of the soc-camera
26 * framework because of its PM implementation, using the video_device node.
27 * If hardware becomes available for testing, alternative PM approaches shall
28 * be considered and tested.
29 */
21 30
22/* 31/*
23 * mt9t031 i2c address 0x5d 32 * mt9t031 i2c address 0x5d
@@ -57,21 +66,20 @@
57#define MT9T031_COLUMN_SKIP 32 66#define MT9T031_COLUMN_SKIP 32
58#define MT9T031_ROW_SKIP 20 67#define MT9T031_ROW_SKIP 20
59 68
60#define MT9T031_BUS_PARAM (SOCAM_PCLK_SAMPLE_RISING | \
61 SOCAM_PCLK_SAMPLE_FALLING | SOCAM_HSYNC_ACTIVE_HIGH | \
62 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH | \
63 SOCAM_MASTER | SOCAM_DATAWIDTH_10)
64
65struct mt9t031 { 69struct mt9t031 {
66 struct v4l2_subdev subdev; 70 struct v4l2_subdev subdev;
71 struct v4l2_ctrl_handler hdl;
72 struct {
73 /* exposure/auto-exposure cluster */
74 struct v4l2_ctrl *autoexposure;
75 struct v4l2_ctrl *exposure;
76 };
67 struct v4l2_rect rect; /* Sensor window */ 77 struct v4l2_rect rect; /* Sensor window */
68 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */ 78 int model; /* V4L2_IDENT_MT9T031* codes from v4l2-chip-ident.h */
69 u16 xskip; 79 u16 xskip;
70 u16 yskip; 80 u16 yskip;
71 unsigned int gain; 81 unsigned int total_h;
72 unsigned short y_skip_top; /* Lines to skip at the top */ 82 unsigned short y_skip_top; /* Lines to skip at the top */
73 unsigned int exposure;
74 unsigned char autoexposure;
75}; 83};
76 84
77static struct mt9t031 *to_mt9t031(const struct i2c_client *client) 85static struct mt9t031 *to_mt9t031(const struct i2c_client *client)
@@ -179,95 +187,6 @@ static int mt9t031_s_stream(struct v4l2_subdev *sd, int enable)
179 return 0; 187 return 0;
180} 188}
181 189
182static int mt9t031_set_bus_param(struct soc_camera_device *icd,
183 unsigned long flags)
184{
185 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
186
187 /* The caller should have queried our parameters, check anyway */
188 if (flags & ~MT9T031_BUS_PARAM)
189 return -EINVAL;
190
191 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
192 reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
193 else
194 reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
195
196 return 0;
197}
198
199static unsigned long mt9t031_query_bus_param(struct soc_camera_device *icd)
200{
201 struct soc_camera_link *icl = to_soc_camera_link(icd);
202
203 return soc_camera_apply_sensor_flags(icl, MT9T031_BUS_PARAM);
204}
205
206enum {
207 MT9T031_CTRL_VFLIP,
208 MT9T031_CTRL_HFLIP,
209 MT9T031_CTRL_GAIN,
210 MT9T031_CTRL_EXPOSURE,
211 MT9T031_CTRL_EXPOSURE_AUTO,
212};
213
214static const struct v4l2_queryctrl mt9t031_controls[] = {
215 [MT9T031_CTRL_VFLIP] = {
216 .id = V4L2_CID_VFLIP,
217 .type = V4L2_CTRL_TYPE_BOOLEAN,
218 .name = "Flip Vertically",
219 .minimum = 0,
220 .maximum = 1,
221 .step = 1,
222 .default_value = 0,
223 },
224 [MT9T031_CTRL_HFLIP] = {
225 .id = V4L2_CID_HFLIP,
226 .type = V4L2_CTRL_TYPE_BOOLEAN,
227 .name = "Flip Horizontally",
228 .minimum = 0,
229 .maximum = 1,
230 .step = 1,
231 .default_value = 0,
232 },
233 [MT9T031_CTRL_GAIN] = {
234 .id = V4L2_CID_GAIN,
235 .type = V4L2_CTRL_TYPE_INTEGER,
236 .name = "Gain",
237 .minimum = 0,
238 .maximum = 127,
239 .step = 1,
240 .default_value = 64,
241 .flags = V4L2_CTRL_FLAG_SLIDER,
242 },
243 [MT9T031_CTRL_EXPOSURE] = {
244 .id = V4L2_CID_EXPOSURE,
245 .type = V4L2_CTRL_TYPE_INTEGER,
246 .name = "Exposure",
247 .minimum = 1,
248 .maximum = 255,
249 .step = 1,
250 .default_value = 255,
251 .flags = V4L2_CTRL_FLAG_SLIDER,
252 },
253 [MT9T031_CTRL_EXPOSURE_AUTO] = {
254 .id = V4L2_CID_EXPOSURE_AUTO,
255 .type = V4L2_CTRL_TYPE_BOOLEAN,
256 .name = "Automatic Exposure",
257 .minimum = 0,
258 .maximum = 1,
259 .step = 1,
260 .default_value = 1,
261 }
262};
263
264static struct soc_camera_ops mt9t031_ops = {
265 .set_bus_param = mt9t031_set_bus_param,
266 .query_bus_param = mt9t031_query_bus_param,
267 .controls = mt9t031_controls,
268 .num_controls = ARRAY_SIZE(mt9t031_controls),
269};
270
271/* target must be _even_ */ 190/* target must be _even_ */
272static u16 mt9t031_skip(s32 *source, s32 target, s32 max) 191static u16 mt9t031_skip(s32 *source, s32 target, s32 max)
273{ 192{
@@ -353,7 +272,7 @@ static int mt9t031_set_params(struct i2c_client *client,
353 272
354 /* 273 /*
355 * The caller provides a supported format, as guaranteed by 274 * The caller provides a supported format, as guaranteed by
356 * icd->try_fmt_cap(), soc_camera_s_crop() and soc_camera_cropcap() 275 * .try_mbus_fmt(), soc_camera_s_crop() and soc_camera_cropcap()
357 */ 276 */
358 if (ret >= 0) 277 if (ret >= 0)
359 ret = reg_write(client, MT9T031_COLUMN_START, rect->left); 278 ret = reg_write(client, MT9T031_COLUMN_START, rect->left);
@@ -364,17 +283,10 @@ static int mt9t031_set_params(struct i2c_client *client,
364 if (ret >= 0) 283 if (ret >= 0)
365 ret = reg_write(client, MT9T031_WINDOW_HEIGHT, 284 ret = reg_write(client, MT9T031_WINDOW_HEIGHT,
366 rect->height + mt9t031->y_skip_top - 1); 285 rect->height + mt9t031->y_skip_top - 1);
367 if (ret >= 0 && mt9t031->autoexposure) { 286 if (ret >= 0 && v4l2_ctrl_g_ctrl(mt9t031->autoexposure) == V4L2_EXPOSURE_AUTO) {
368 unsigned int total_h = rect->height + mt9t031->y_skip_top + vblank; 287 mt9t031->total_h = rect->height + mt9t031->y_skip_top + vblank;
369 ret = set_shutter(client, total_h); 288
370 if (ret >= 0) { 289 ret = set_shutter(client, mt9t031->total_h);
371 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank;
372 const struct v4l2_queryctrl *qctrl =
373 &mt9t031_controls[MT9T031_CTRL_EXPOSURE];
374 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) *
375 (qctrl->maximum - qctrl->minimum)) /
376 shutter_max + qctrl->minimum;
377 }
378 } 290 }
379 291
380 /* Re-enable register update, commit all changes */ 292 /* Re-enable register update, commit all changes */
@@ -543,71 +455,57 @@ static int mt9t031_s_register(struct v4l2_subdev *sd,
543} 455}
544#endif 456#endif
545 457
546static int mt9t031_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 458static int mt9t031_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
547{ 459{
548 struct i2c_client *client = v4l2_get_subdevdata(sd); 460 struct mt9t031 *mt9t031 = container_of(ctrl->handler,
549 struct mt9t031 *mt9t031 = to_mt9t031(client); 461 struct mt9t031, hdl);
550 int data; 462 const u32 shutter_max = MT9T031_MAX_HEIGHT + MT9T031_VERTICAL_BLANK;
463 s32 min, max;
551 464
552 switch (ctrl->id) { 465 switch (ctrl->id) {
553 case V4L2_CID_VFLIP:
554 data = reg_read(client, MT9T031_READ_MODE_2);
555 if (data < 0)
556 return -EIO;
557 ctrl->value = !!(data & 0x8000);
558 break;
559 case V4L2_CID_HFLIP:
560 data = reg_read(client, MT9T031_READ_MODE_2);
561 if (data < 0)
562 return -EIO;
563 ctrl->value = !!(data & 0x4000);
564 break;
565 case V4L2_CID_EXPOSURE_AUTO: 466 case V4L2_CID_EXPOSURE_AUTO:
566 ctrl->value = mt9t031->autoexposure; 467 min = mt9t031->exposure->minimum;
567 break; 468 max = mt9t031->exposure->maximum;
568 case V4L2_CID_GAIN: 469 mt9t031->exposure->val =
569 ctrl->value = mt9t031->gain; 470 (shutter_max / 2 + (mt9t031->total_h - 1) * (max - min))
570 break; 471 / shutter_max + min;
571 case V4L2_CID_EXPOSURE:
572 ctrl->value = mt9t031->exposure;
573 break; 472 break;
574 } 473 }
575 return 0; 474 return 0;
576} 475}
577 476
578static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 477static int mt9t031_s_ctrl(struct v4l2_ctrl *ctrl)
579{ 478{
479 struct mt9t031 *mt9t031 = container_of(ctrl->handler,
480 struct mt9t031, hdl);
481 struct v4l2_subdev *sd = &mt9t031->subdev;
580 struct i2c_client *client = v4l2_get_subdevdata(sd); 482 struct i2c_client *client = v4l2_get_subdevdata(sd);
581 struct mt9t031 *mt9t031 = to_mt9t031(client); 483 struct v4l2_ctrl *exp = mt9t031->exposure;
582 const struct v4l2_queryctrl *qctrl;
583 int data; 484 int data;
584 485
585 switch (ctrl->id) { 486 switch (ctrl->id) {
586 case V4L2_CID_VFLIP: 487 case V4L2_CID_VFLIP:
587 if (ctrl->value) 488 if (ctrl->val)
588 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000); 489 data = reg_set(client, MT9T031_READ_MODE_2, 0x8000);
589 else 490 else
590 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000); 491 data = reg_clear(client, MT9T031_READ_MODE_2, 0x8000);
591 if (data < 0) 492 if (data < 0)
592 return -EIO; 493 return -EIO;
593 break; 494 return 0;
594 case V4L2_CID_HFLIP: 495 case V4L2_CID_HFLIP:
595 if (ctrl->value) 496 if (ctrl->val)
596 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000); 497 data = reg_set(client, MT9T031_READ_MODE_2, 0x4000);
597 else 498 else
598 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000); 499 data = reg_clear(client, MT9T031_READ_MODE_2, 0x4000);
599 if (data < 0) 500 if (data < 0)
600 return -EIO; 501 return -EIO;
601 break; 502 return 0;
602 case V4L2_CID_GAIN: 503 case V4L2_CID_GAIN:
603 qctrl = &mt9t031_controls[MT9T031_CTRL_GAIN];
604 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
605 return -EINVAL;
606 /* See Datasheet Table 7, Gain settings. */ 504 /* See Datasheet Table 7, Gain settings. */
607 if (ctrl->value <= qctrl->default_value) { 505 if (ctrl->val <= ctrl->default_value) {
608 /* Pack it into 0..1 step 0.125, register values 0..8 */ 506 /* Pack it into 0..1 step 0.125, register values 0..8 */
609 unsigned long range = qctrl->default_value - qctrl->minimum; 507 unsigned long range = ctrl->default_value - ctrl->minimum;
610 data = ((ctrl->value - qctrl->minimum) * 8 + range / 2) / range; 508 data = ((ctrl->val - ctrl->minimum) * 8 + range / 2) / range;
611 509
612 dev_dbg(&client->dev, "Setting gain %d\n", data); 510 dev_dbg(&client->dev, "Setting gain %d\n", data);
613 data = reg_write(client, MT9T031_GLOBAL_GAIN, data); 511 data = reg_write(client, MT9T031_GLOBAL_GAIN, data);
@@ -616,9 +514,9 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
616 } else { 514 } else {
617 /* Pack it into 1.125..128 variable step, register values 9..0x7860 */ 515 /* Pack it into 1.125..128 variable step, register values 9..0x7860 */
618 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */ 516 /* We assume qctrl->maximum - qctrl->default_value - 1 > 0 */
619 unsigned long range = qctrl->maximum - qctrl->default_value - 1; 517 unsigned long range = ctrl->maximum - ctrl->default_value - 1;
620 /* calculated gain: map 65..127 to 9..1024 step 0.125 */ 518 /* calculated gain: map 65..127 to 9..1024 step 0.125 */
621 unsigned long gain = ((ctrl->value - qctrl->default_value - 1) * 519 unsigned long gain = ((ctrl->val - ctrl->default_value - 1) *
622 1015 + range / 2) / range + 9; 520 1015 + range / 2) / range + 9;
623 521
624 if (gain <= 32) /* calculated gain 9..32 -> 9..32 */ 522 if (gain <= 32) /* calculated gain 9..32 -> 9..32 */
@@ -635,19 +533,13 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
635 if (data < 0) 533 if (data < 0)
636 return -EIO; 534 return -EIO;
637 } 535 }
536 return 0;
638 537
639 /* Success */ 538 case V4L2_CID_EXPOSURE_AUTO:
640 mt9t031->gain = ctrl->value; 539 if (ctrl->val == V4L2_EXPOSURE_MANUAL) {
641 break; 540 unsigned int range = exp->maximum - exp->minimum;
642 case V4L2_CID_EXPOSURE: 541 unsigned int shutter = ((exp->val - exp->minimum) * 1048 +
643 qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; 542 range / 2) / range + 1;
644 /* mt9t031 has maximum == default */
645 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum)
646 return -EINVAL;
647 else {
648 const unsigned long range = qctrl->maximum - qctrl->minimum;
649 const u32 shutter = ((ctrl->value - qctrl->minimum) * 1048 +
650 range / 2) / range + 1;
651 u32 old; 543 u32 old;
652 544
653 get_shutter(client, &old); 545 get_shutter(client, &old);
@@ -655,27 +547,15 @@ static int mt9t031_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
655 old, shutter); 547 old, shutter);
656 if (set_shutter(client, shutter) < 0) 548 if (set_shutter(client, shutter) < 0)
657 return -EIO; 549 return -EIO;
658 mt9t031->exposure = ctrl->value; 550 } else {
659 mt9t031->autoexposure = 0;
660 }
661 break;
662 case V4L2_CID_EXPOSURE_AUTO:
663 if (ctrl->value) {
664 const u16 vblank = MT9T031_VERTICAL_BLANK; 551 const u16 vblank = MT9T031_VERTICAL_BLANK;
665 const u32 shutter_max = MT9T031_MAX_HEIGHT + vblank; 552 mt9t031->total_h = mt9t031->rect.height +
666 unsigned int total_h = mt9t031->rect.height +
667 mt9t031->y_skip_top + vblank; 553 mt9t031->y_skip_top + vblank;
668 554
669 if (set_shutter(client, total_h) < 0) 555 if (set_shutter(client, mt9t031->total_h) < 0)
670 return -EIO; 556 return -EIO;
671 qctrl = &mt9t031_controls[MT9T031_CTRL_EXPOSURE]; 557 }
672 mt9t031->exposure = (shutter_max / 2 + (total_h - 1) * 558 return 0;
673 (qctrl->maximum - qctrl->minimum)) /
674 shutter_max + qctrl->minimum;
675 mt9t031->autoexposure = 1;
676 } else
677 mt9t031->autoexposure = 0;
678 break;
679 default: 559 default:
680 return -EINVAL; 560 return -EINVAL;
681 } 561 }
@@ -700,8 +580,7 @@ static int mt9t031_runtime_suspend(struct device *dev)
700static int mt9t031_runtime_resume(struct device *dev) 580static int mt9t031_runtime_resume(struct device *dev)
701{ 581{
702 struct video_device *vdev = to_video_device(dev); 582 struct video_device *vdev = to_video_device(dev);
703 struct soc_camera_device *icd = dev_get_drvdata(vdev->parent); 583 struct v4l2_subdev *sd = soc_camera_vdev_to_subdev(vdev);
704 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
705 struct i2c_client *client = v4l2_get_subdevdata(sd); 584 struct i2c_client *client = v4l2_get_subdevdata(sd);
706 struct mt9t031 *mt9t031 = to_mt9t031(client); 585 struct mt9t031 *mt9t031 = to_mt9t031(client);
707 586
@@ -734,6 +613,19 @@ static struct device_type mt9t031_dev_type = {
734 .pm = &mt9t031_dev_pm_ops, 613 .pm = &mt9t031_dev_pm_ops,
735}; 614};
736 615
616static int mt9t031_s_power(struct v4l2_subdev *sd, int on)
617{
618 struct i2c_client *client = v4l2_get_subdevdata(sd);
619 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
620
621 if (on)
622 vdev->dev.type = &mt9t031_dev_type;
623 else
624 vdev->dev.type = NULL;
625
626 return 0;
627}
628
737/* 629/*
738 * Interface active, can use i2c. If it fails, it can indeed mean, that 630 * Interface active, can use i2c. If it fails, it can indeed mean, that
739 * this wasn't our capture interface, so, we wait for the right one 631 * this wasn't our capture interface, so, we wait for the right one
@@ -741,7 +633,6 @@ static struct device_type mt9t031_dev_type = {
741static int mt9t031_video_probe(struct i2c_client *client) 633static int mt9t031_video_probe(struct i2c_client *client)
742{ 634{
743 struct mt9t031 *mt9t031 = to_mt9t031(client); 635 struct mt9t031 *mt9t031 = to_mt9t031(client);
744 struct video_device *vdev = soc_camera_i2c_to_vdev(client);
745 s32 data; 636 s32 data;
746 int ret; 637 int ret;
747 638
@@ -768,11 +659,7 @@ static int mt9t031_video_probe(struct i2c_client *client)
768 if (ret < 0) 659 if (ret < 0)
769 dev_err(&client->dev, "Failed to initialise the camera\n"); 660 dev_err(&client->dev, "Failed to initialise the camera\n");
770 else 661 else
771 vdev->dev.type = &mt9t031_dev_type; 662 v4l2_ctrl_handler_setup(&mt9t031->hdl);
772
773 /* mt9t031_idle() has reset the chip to default. */
774 mt9t031->exposure = 255;
775 mt9t031->gain = 64;
776 663
777 return ret; 664 return ret;
778} 665}
@@ -787,10 +674,14 @@ static int mt9t031_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
787 return 0; 674 return 0;
788} 675}
789 676
677static const struct v4l2_ctrl_ops mt9t031_ctrl_ops = {
678 .g_volatile_ctrl = mt9t031_g_volatile_ctrl,
679 .s_ctrl = mt9t031_s_ctrl,
680};
681
790static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = { 682static struct v4l2_subdev_core_ops mt9t031_subdev_core_ops = {
791 .g_ctrl = mt9t031_g_ctrl,
792 .s_ctrl = mt9t031_s_ctrl,
793 .g_chip_ident = mt9t031_g_chip_ident, 683 .g_chip_ident = mt9t031_g_chip_ident,
684 .s_power = mt9t031_s_power,
794#ifdef CONFIG_VIDEO_ADV_DEBUG 685#ifdef CONFIG_VIDEO_ADV_DEBUG
795 .g_register = mt9t031_g_register, 686 .g_register = mt9t031_g_register,
796 .s_register = mt9t031_s_register, 687 .s_register = mt9t031_s_register,
@@ -807,6 +698,34 @@ static int mt9t031_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
807 return 0; 698 return 0;
808} 699}
809 700
701static int mt9t031_g_mbus_config(struct v4l2_subdev *sd,
702 struct v4l2_mbus_config *cfg)
703{
704 struct i2c_client *client = v4l2_get_subdevdata(sd);
705 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
706
707 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_PCLK_SAMPLE_RISING |
708 V4L2_MBUS_PCLK_SAMPLE_FALLING | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
709 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH;
710 cfg->type = V4L2_MBUS_PARALLEL;
711 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
712
713 return 0;
714}
715
716static int mt9t031_s_mbus_config(struct v4l2_subdev *sd,
717 const struct v4l2_mbus_config *cfg)
718{
719 struct i2c_client *client = v4l2_get_subdevdata(sd);
720 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
721
722 if (soc_camera_apply_board_flags(icl, cfg) &
723 V4L2_MBUS_PCLK_SAMPLE_FALLING)
724 return reg_clear(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
725 else
726 return reg_set(client, MT9T031_PIXEL_CLOCK_CONTROL, 0x8000);
727}
728
810static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = { 729static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
811 .s_stream = mt9t031_s_stream, 730 .s_stream = mt9t031_s_stream,
812 .s_mbus_fmt = mt9t031_s_fmt, 731 .s_mbus_fmt = mt9t031_s_fmt,
@@ -816,6 +735,8 @@ static struct v4l2_subdev_video_ops mt9t031_subdev_video_ops = {
816 .g_crop = mt9t031_g_crop, 735 .g_crop = mt9t031_g_crop,
817 .cropcap = mt9t031_cropcap, 736 .cropcap = mt9t031_cropcap,
818 .enum_mbus_fmt = mt9t031_enum_fmt, 737 .enum_mbus_fmt = mt9t031_enum_fmt,
738 .g_mbus_config = mt9t031_g_mbus_config,
739 .s_mbus_config = mt9t031_s_mbus_config,
819}; 740};
820 741
821static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = { 742static struct v4l2_subdev_sensor_ops mt9t031_subdev_sensor_ops = {
@@ -832,18 +753,13 @@ static int mt9t031_probe(struct i2c_client *client,
832 const struct i2c_device_id *did) 753 const struct i2c_device_id *did)
833{ 754{
834 struct mt9t031 *mt9t031; 755 struct mt9t031 *mt9t031;
835 struct soc_camera_device *icd = client->dev.platform_data; 756 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
836 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 757 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
837 int ret; 758 int ret;
838 759
839 if (icd) { 760 if (!icl) {
840 struct soc_camera_link *icl = to_soc_camera_link(icd); 761 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
841 if (!icl) { 762 return -EINVAL;
842 dev_err(&client->dev, "MT9T031 driver needs platform data\n");
843 return -EINVAL;
844 }
845
846 icd->ops = &mt9t031_ops;
847 } 763 }
848 764
849 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { 765 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -857,6 +773,33 @@ static int mt9t031_probe(struct i2c_client *client,
857 return -ENOMEM; 773 return -ENOMEM;
858 774
859 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops); 775 v4l2_i2c_subdev_init(&mt9t031->subdev, client, &mt9t031_subdev_ops);
776 v4l2_ctrl_handler_init(&mt9t031->hdl, 5);
777 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
778 V4L2_CID_VFLIP, 0, 1, 1, 0);
779 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
780 V4L2_CID_HFLIP, 0, 1, 1, 0);
781 v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
782 V4L2_CID_GAIN, 0, 127, 1, 64);
783
784 /*
785 * Simulated autoexposure. If enabled, we calculate shutter width
786 * ourselves in the driver based on vertical blanking and frame width
787 */
788 mt9t031->autoexposure = v4l2_ctrl_new_std_menu(&mt9t031->hdl,
789 &mt9t031_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
790 V4L2_EXPOSURE_AUTO);
791 mt9t031->exposure = v4l2_ctrl_new_std(&mt9t031->hdl, &mt9t031_ctrl_ops,
792 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
793
794 mt9t031->subdev.ctrl_handler = &mt9t031->hdl;
795 if (mt9t031->hdl.error) {
796 int err = mt9t031->hdl.error;
797
798 kfree(mt9t031);
799 return err;
800 }
801 v4l2_ctrl_auto_cluster(2, &mt9t031->autoexposure,
802 V4L2_EXPOSURE_MANUAL, true);
860 803
861 mt9t031->y_skip_top = 0; 804 mt9t031->y_skip_top = 0;
862 mt9t031->rect.left = MT9T031_COLUMN_SKIP; 805 mt9t031->rect.left = MT9T031_COLUMN_SKIP;
@@ -864,12 +807,6 @@ static int mt9t031_probe(struct i2c_client *client,
864 mt9t031->rect.width = MT9T031_MAX_WIDTH; 807 mt9t031->rect.width = MT9T031_MAX_WIDTH;
865 mt9t031->rect.height = MT9T031_MAX_HEIGHT; 808 mt9t031->rect.height = MT9T031_MAX_HEIGHT;
866 809
867 /*
868 * Simulated autoexposure. If enabled, we calculate shutter width
869 * ourselves in the driver based on vertical blanking and frame width
870 */
871 mt9t031->autoexposure = 1;
872
873 mt9t031->xskip = 1; 810 mt9t031->xskip = 1;
874 mt9t031->yskip = 1; 811 mt9t031->yskip = 1;
875 812
@@ -880,8 +817,7 @@ static int mt9t031_probe(struct i2c_client *client,
880 mt9t031_disable(client); 817 mt9t031_disable(client);
881 818
882 if (ret) { 819 if (ret) {
883 if (icd) 820 v4l2_ctrl_handler_free(&mt9t031->hdl);
884 icd->ops = NULL;
885 kfree(mt9t031); 821 kfree(mt9t031);
886 } 822 }
887 823
@@ -891,10 +827,9 @@ static int mt9t031_probe(struct i2c_client *client,
891static int mt9t031_remove(struct i2c_client *client) 827static int mt9t031_remove(struct i2c_client *client)
892{ 828{
893 struct mt9t031 *mt9t031 = to_mt9t031(client); 829 struct mt9t031 *mt9t031 = to_mt9t031(client);
894 struct soc_camera_device *icd = client->dev.platform_data;
895 830
896 if (icd) 831 v4l2_device_unregister_subdev(&mt9t031->subdev);
897 icd->ops = NULL; 832 v4l2_ctrl_handler_free(&mt9t031->hdl);
898 kfree(mt9t031); 833 kfree(mt9t031);
899 834
900 return 0; 835 return 0;
diff --git a/drivers/media/video/mt9t112.c b/drivers/media/video/mt9t112.c
index d2e0a50063a..32114a3c0ca 100644
--- a/drivers/media/video/mt9t112.c
+++ b/drivers/media/video/mt9t112.c
@@ -22,11 +22,11 @@
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/v4l2-mediabus.h>
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26 27
27#include <media/mt9t112.h> 28#include <media/mt9t112.h>
28#include <media/soc_camera.h> 29#include <media/soc_camera.h>
29#include <media/soc_mediabus.h>
30#include <media/v4l2-chip-ident.h> 30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-common.h> 31#include <media/v4l2-common.h>
32 32
@@ -34,11 +34,7 @@
34/* #define EXT_CLOCK 24000000 */ 34/* #define EXT_CLOCK 24000000 */
35 35
36/************************************************************************ 36/************************************************************************
37
38
39 macro 37 macro
40
41
42************************************************************************/ 38************************************************************************/
43/* 39/*
44 * frame size 40 * frame size
@@ -80,17 +76,8 @@
80#define VAR8(id, offset) _VAR(id, offset, 0x8000) 76#define VAR8(id, offset) _VAR(id, offset, 0x8000)
81 77
82/************************************************************************ 78/************************************************************************
83
84
85 struct 79 struct
86
87
88************************************************************************/ 80************************************************************************/
89struct mt9t112_frame_size {
90 u16 width;
91 u16 height;
92};
93
94struct mt9t112_format { 81struct mt9t112_format {
95 enum v4l2_mbus_pixelcode code; 82 enum v4l2_mbus_pixelcode code;
96 enum v4l2_colorspace colorspace; 83 enum v4l2_colorspace colorspace;
@@ -102,21 +89,17 @@ struct mt9t112_priv {
102 struct v4l2_subdev subdev; 89 struct v4l2_subdev subdev;
103 struct mt9t112_camera_info *info; 90 struct mt9t112_camera_info *info;
104 struct i2c_client *client; 91 struct i2c_client *client;
105 struct soc_camera_device icd; 92 struct v4l2_rect frame;
106 struct mt9t112_frame_size frame;
107 const struct mt9t112_format *format; 93 const struct mt9t112_format *format;
108 int model; 94 int model;
109 u32 flags; 95 u32 flags;
110/* for flags */ 96/* for flags */
111#define INIT_DONE (1<<0) 97#define INIT_DONE (1 << 0)
98#define PCLK_RISING (1 << 1)
112}; 99};
113 100
114/************************************************************************ 101/************************************************************************
115
116
117 supported format 102 supported format
118
119
120************************************************************************/ 103************************************************************************/
121 104
122static const struct mt9t112_format mt9t112_cfmts[] = { 105static const struct mt9t112_format mt9t112_cfmts[] = {
@@ -154,11 +137,7 @@ static const struct mt9t112_format mt9t112_cfmts[] = {
154}; 137};
155 138
156/************************************************************************ 139/************************************************************************
157
158
159 general function 140 general function
160
161
162************************************************************************/ 141************************************************************************/
163static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client) 142static struct mt9t112_priv *to_mt9t112(const struct i2c_client *client)
164{ 143{
@@ -326,50 +305,47 @@ static int mt9t112_clock_info(const struct i2c_client *client, u32 ext)
326 n = (n >> 8) & 0x003f; 305 n = (n >> 8) & 0x003f;
327 306
328 enable = ((6000 > ext) || (54000 < ext)) ? "X" : ""; 307 enable = ((6000 > ext) || (54000 < ext)) ? "X" : "";
329 dev_info(&client->dev, "EXTCLK : %10u K %s\n", ext, enable); 308 dev_dbg(&client->dev, "EXTCLK : %10u K %s\n", ext, enable);
330 309
331 vco = 2 * m * ext / (n+1); 310 vco = 2 * m * ext / (n+1);
332 enable = ((384000 > vco) || (768000 < vco)) ? "X" : ""; 311 enable = ((384000 > vco) || (768000 < vco)) ? "X" : "";
333 dev_info(&client->dev, "VCO : %10u K %s\n", vco, enable); 312 dev_dbg(&client->dev, "VCO : %10u K %s\n", vco, enable);
334 313
335 clk = vco / (p1+1) / (p2+1); 314 clk = vco / (p1+1) / (p2+1);
336 enable = (96000 < clk) ? "X" : ""; 315 enable = (96000 < clk) ? "X" : "";
337 dev_info(&client->dev, "PIXCLK : %10u K %s\n", clk, enable); 316 dev_dbg(&client->dev, "PIXCLK : %10u K %s\n", clk, enable);
338 317
339 clk = vco / (p3+1); 318 clk = vco / (p3+1);
340 enable = (768000 < clk) ? "X" : ""; 319 enable = (768000 < clk) ? "X" : "";
341 dev_info(&client->dev, "MIPICLK : %10u K %s\n", clk, enable); 320 dev_dbg(&client->dev, "MIPICLK : %10u K %s\n", clk, enable);
342 321
343 clk = vco / (p6+1); 322 clk = vco / (p6+1);
344 enable = (96000 < clk) ? "X" : ""; 323 enable = (96000 < clk) ? "X" : "";
345 dev_info(&client->dev, "MCU CLK : %10u K %s\n", clk, enable); 324 dev_dbg(&client->dev, "MCU CLK : %10u K %s\n", clk, enable);
346 325
347 clk = vco / (p5+1); 326 clk = vco / (p5+1);
348 enable = (54000 < clk) ? "X" : ""; 327 enable = (54000 < clk) ? "X" : "";
349 dev_info(&client->dev, "SOC CLK : %10u K %s\n", clk, enable); 328 dev_dbg(&client->dev, "SOC CLK : %10u K %s\n", clk, enable);
350 329
351 clk = vco / (p4+1); 330 clk = vco / (p4+1);
352 enable = (70000 < clk) ? "X" : ""; 331 enable = (70000 < clk) ? "X" : "";
353 dev_info(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable); 332 dev_dbg(&client->dev, "Sensor CLK : %10u K %s\n", clk, enable);
354 333
355 clk = vco / (p7+1); 334 clk = vco / (p7+1);
356 dev_info(&client->dev, "External sensor : %10u K\n", clk); 335 dev_dbg(&client->dev, "External sensor : %10u K\n", clk);
357 336
358 clk = ext / (n+1); 337 clk = ext / (n+1);
359 enable = ((2000 > clk) || (24000 < clk)) ? "X" : ""; 338 enable = ((2000 > clk) || (24000 < clk)) ? "X" : "";
360 dev_info(&client->dev, "PFD : %10u K %s\n", clk, enable); 339 dev_dbg(&client->dev, "PFD : %10u K %s\n", clk, enable);
361 340
362 return 0; 341 return 0;
363} 342}
364#endif 343#endif
365 344
366static void mt9t112_frame_check(u32 *width, u32 *height) 345static void mt9t112_frame_check(u32 *width, u32 *height, u32 *left, u32 *top)
367{ 346{
368 if (*width > MAX_WIDTH) 347 soc_camera_limit_side(left, width, 0, 0, MAX_WIDTH);
369 *width = MAX_WIDTH; 348 soc_camera_limit_side(top, height, 0, 0, MAX_HEIGHT);
370
371 if (*height > MAX_HEIGHT)
372 *height = MAX_HEIGHT;
373} 349}
374 350
375static int mt9t112_set_a_frame_size(const struct i2c_client *client, 351static int mt9t112_set_a_frame_size(const struct i2c_client *client,
@@ -758,48 +734,7 @@ static int mt9t112_init_camera(const struct i2c_client *client)
758} 734}
759 735
760/************************************************************************ 736/************************************************************************
761
762
763 soc_camera_ops
764
765
766************************************************************************/
767static int mt9t112_set_bus_param(struct soc_camera_device *icd,
768 unsigned long flags)
769{
770 return 0;
771}
772
773static unsigned long mt9t112_query_bus_param(struct soc_camera_device *icd)
774{
775 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
776 struct mt9t112_priv *priv = to_mt9t112(client);
777 struct soc_camera_link *icl = to_soc_camera_link(icd);
778 unsigned long flags = SOCAM_MASTER | SOCAM_VSYNC_ACTIVE_HIGH |
779 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_HIGH;
780
781 flags |= (priv->info->flags & MT9T112_FLAG_PCLK_RISING_EDGE) ?
782 SOCAM_PCLK_SAMPLE_RISING : SOCAM_PCLK_SAMPLE_FALLING;
783
784 if (priv->info->flags & MT9T112_FLAG_DATAWIDTH_8)
785 flags |= SOCAM_DATAWIDTH_8;
786 else
787 flags |= SOCAM_DATAWIDTH_10;
788
789 return soc_camera_apply_sensor_flags(icl, flags);
790}
791
792static struct soc_camera_ops mt9t112_ops = {
793 .set_bus_param = mt9t112_set_bus_param,
794 .query_bus_param = mt9t112_query_bus_param,
795};
796
797/************************************************************************
798
799
800 v4l2_subdev_core_ops 737 v4l2_subdev_core_ops
801
802
803************************************************************************/ 738************************************************************************/
804static int mt9t112_g_chip_ident(struct v4l2_subdev *sd, 739static int mt9t112_g_chip_ident(struct v4l2_subdev *sd,
805 struct v4l2_dbg_chip_ident *id) 740 struct v4l2_dbg_chip_ident *id)
@@ -850,11 +785,7 @@ static struct v4l2_subdev_core_ops mt9t112_subdev_core_ops = {
850 785
851 786
852/************************************************************************ 787/************************************************************************
853
854
855 v4l2_subdev_video_ops 788 v4l2_subdev_video_ops
856
857
858************************************************************************/ 789************************************************************************/
859static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable) 790static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
860{ 791{
@@ -877,8 +808,7 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
877 } 808 }
878 809
879 if (!(priv->flags & INIT_DONE)) { 810 if (!(priv->flags & INIT_DONE)) {
880 u16 param = (MT9T112_FLAG_PCLK_RISING_EDGE & 811 u16 param = PCLK_RISING & priv->flags ? 0x0001 : 0x0000;
881 priv->info->flags) ? 0x0001 : 0x0000;
882 812
883 ECHECKER(ret, mt9t112_init_camera(client)); 813 ECHECKER(ret, mt9t112_init_camera(client));
884 814
@@ -910,19 +840,12 @@ static int mt9t112_s_stream(struct v4l2_subdev *sd, int enable)
910 return ret; 840 return ret;
911} 841}
912 842
913static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height, 843static int mt9t112_set_params(struct mt9t112_priv *priv,
844 const struct v4l2_rect *rect,
914 enum v4l2_mbus_pixelcode code) 845 enum v4l2_mbus_pixelcode code)
915{ 846{
916 struct mt9t112_priv *priv = to_mt9t112(client);
917 int i; 847 int i;
918 848
919 priv->format = NULL;
920
921 /*
922 * frame size check
923 */
924 mt9t112_frame_check(&width, &height);
925
926 /* 849 /*
927 * get color format 850 * get color format
928 */ 851 */
@@ -933,8 +856,13 @@ static int mt9t112_set_params(struct i2c_client *client, u32 width, u32 height,
933 if (i == ARRAY_SIZE(mt9t112_cfmts)) 856 if (i == ARRAY_SIZE(mt9t112_cfmts))
934 return -EINVAL; 857 return -EINVAL;
935 858
936 priv->frame.width = (u16)width; 859 priv->frame = *rect;
937 priv->frame.height = (u16)height; 860
861 /*
862 * frame size check
863 */
864 mt9t112_frame_check(&priv->frame.width, &priv->frame.height,
865 &priv->frame.left, &priv->frame.top);
938 866
939 priv->format = mt9t112_cfmts + i; 867 priv->format = mt9t112_cfmts + i;
940 868
@@ -945,9 +873,12 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
945{ 873{
946 a->bounds.left = 0; 874 a->bounds.left = 0;
947 a->bounds.top = 0; 875 a->bounds.top = 0;
948 a->bounds.width = VGA_WIDTH; 876 a->bounds.width = MAX_WIDTH;
949 a->bounds.height = VGA_HEIGHT; 877 a->bounds.height = MAX_HEIGHT;
950 a->defrect = a->bounds; 878 a->defrect.left = 0;
879 a->defrect.top = 0;
880 a->defrect.width = VGA_WIDTH;
881 a->defrect.height = VGA_HEIGHT;
951 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 882 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
952 a->pixelaspect.numerator = 1; 883 a->pixelaspect.numerator = 1;
953 a->pixelaspect.denominator = 1; 884 a->pixelaspect.denominator = 1;
@@ -957,11 +888,11 @@ static int mt9t112_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
957 888
958static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 889static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
959{ 890{
960 a->c.left = 0; 891 struct i2c_client *client = v4l2_get_subdevdata(sd);
961 a->c.top = 0; 892 struct mt9t112_priv *priv = to_mt9t112(client);
962 a->c.width = VGA_WIDTH; 893
963 a->c.height = VGA_HEIGHT; 894 a->c = priv->frame;
964 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 895 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
965 896
966 return 0; 897 return 0;
967} 898}
@@ -969,10 +900,10 @@ static int mt9t112_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
969static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 900static int mt9t112_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
970{ 901{
971 struct i2c_client *client = v4l2_get_subdevdata(sd); 902 struct i2c_client *client = v4l2_get_subdevdata(sd);
903 struct mt9t112_priv *priv = to_mt9t112(client);
972 struct v4l2_rect *rect = &a->c; 904 struct v4l2_rect *rect = &a->c;
973 905
974 return mt9t112_set_params(client, rect->width, rect->height, 906 return mt9t112_set_params(priv, rect, priv->format->code);
975 V4L2_MBUS_FMT_UYVY8_2X8);
976} 907}
977 908
978static int mt9t112_g_fmt(struct v4l2_subdev *sd, 909static int mt9t112_g_fmt(struct v4l2_subdev *sd,
@@ -981,16 +912,9 @@ static int mt9t112_g_fmt(struct v4l2_subdev *sd,
981 struct i2c_client *client = v4l2_get_subdevdata(sd); 912 struct i2c_client *client = v4l2_get_subdevdata(sd);
982 struct mt9t112_priv *priv = to_mt9t112(client); 913 struct mt9t112_priv *priv = to_mt9t112(client);
983 914
984 if (!priv->format) {
985 int ret = mt9t112_set_params(client, VGA_WIDTH, VGA_HEIGHT,
986 V4L2_MBUS_FMT_UYVY8_2X8);
987 if (ret < 0)
988 return ret;
989 }
990
991 mf->width = priv->frame.width; 915 mf->width = priv->frame.width;
992 mf->height = priv->frame.height; 916 mf->height = priv->frame.height;
993 /* TODO: set colorspace */ 917 mf->colorspace = priv->format->colorspace;
994 mf->code = priv->format->code; 918 mf->code = priv->format->code;
995 mf->field = V4L2_FIELD_NONE; 919 mf->field = V4L2_FIELD_NONE;
996 920
@@ -1001,17 +925,42 @@ static int mt9t112_s_fmt(struct v4l2_subdev *sd,
1001 struct v4l2_mbus_framefmt *mf) 925 struct v4l2_mbus_framefmt *mf)
1002{ 926{
1003 struct i2c_client *client = v4l2_get_subdevdata(sd); 927 struct i2c_client *client = v4l2_get_subdevdata(sd);
928 struct mt9t112_priv *priv = to_mt9t112(client);
929 struct v4l2_rect rect = {
930 .width = mf->width,
931 .height = mf->height,
932 .left = priv->frame.left,
933 .top = priv->frame.top,
934 };
935 int ret;
936
937 ret = mt9t112_set_params(priv, &rect, mf->code);
938
939 if (!ret)
940 mf->colorspace = priv->format->colorspace;
1004 941
1005 /* TODO: set colorspace */ 942 return ret;
1006 return mt9t112_set_params(client, mf->width, mf->height, mf->code);
1007} 943}
1008 944
1009static int mt9t112_try_fmt(struct v4l2_subdev *sd, 945static int mt9t112_try_fmt(struct v4l2_subdev *sd,
1010 struct v4l2_mbus_framefmt *mf) 946 struct v4l2_mbus_framefmt *mf)
1011{ 947{
1012 mt9t112_frame_check(&mf->width, &mf->height); 948 unsigned int top, left;
949 int i;
950
951 for (i = 0; i < ARRAY_SIZE(mt9t112_cfmts); i++)
952 if (mt9t112_cfmts[i].code == mf->code)
953 break;
954
955 if (i == ARRAY_SIZE(mt9t112_cfmts)) {
956 mf->code = V4L2_MBUS_FMT_UYVY8_2X8;
957 mf->colorspace = V4L2_COLORSPACE_JPEG;
958 } else {
959 mf->colorspace = mt9t112_cfmts[i].colorspace;
960 }
961
962 mt9t112_frame_check(&mf->width, &mf->height, &left, &top);
1013 963
1014 /* TODO: set colorspace */
1015 mf->field = V4L2_FIELD_NONE; 964 mf->field = V4L2_FIELD_NONE;
1016 965
1017 return 0; 966 return 0;
@@ -1024,6 +973,35 @@ static int mt9t112_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1024 return -EINVAL; 973 return -EINVAL;
1025 974
1026 *code = mt9t112_cfmts[index].code; 975 *code = mt9t112_cfmts[index].code;
976
977 return 0;
978}
979
980static int mt9t112_g_mbus_config(struct v4l2_subdev *sd,
981 struct v4l2_mbus_config *cfg)
982{
983 struct i2c_client *client = v4l2_get_subdevdata(sd);
984 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
985
986 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
987 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_HIGH |
988 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
989 cfg->type = V4L2_MBUS_PARALLEL;
990 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
991
992 return 0;
993}
994
995static int mt9t112_s_mbus_config(struct v4l2_subdev *sd,
996 const struct v4l2_mbus_config *cfg)
997{
998 struct i2c_client *client = v4l2_get_subdevdata(sd);
999 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1000 struct mt9t112_priv *priv = to_mt9t112(client);
1001
1002 if (soc_camera_apply_board_flags(icl, cfg) & V4L2_MBUS_PCLK_SAMPLE_RISING)
1003 priv->flags |= PCLK_RISING;
1004
1027 return 0; 1005 return 0;
1028} 1006}
1029 1007
@@ -1036,31 +1014,24 @@ static struct v4l2_subdev_video_ops mt9t112_subdev_video_ops = {
1036 .g_crop = mt9t112_g_crop, 1014 .g_crop = mt9t112_g_crop,
1037 .s_crop = mt9t112_s_crop, 1015 .s_crop = mt9t112_s_crop,
1038 .enum_mbus_fmt = mt9t112_enum_fmt, 1016 .enum_mbus_fmt = mt9t112_enum_fmt,
1017 .g_mbus_config = mt9t112_g_mbus_config,
1018 .s_mbus_config = mt9t112_s_mbus_config,
1039}; 1019};
1040 1020
1041/************************************************************************ 1021/************************************************************************
1042
1043
1044 i2c driver 1022 i2c driver
1045
1046
1047************************************************************************/ 1023************************************************************************/
1048static struct v4l2_subdev_ops mt9t112_subdev_ops = { 1024static struct v4l2_subdev_ops mt9t112_subdev_ops = {
1049 .core = &mt9t112_subdev_core_ops, 1025 .core = &mt9t112_subdev_core_ops,
1050 .video = &mt9t112_subdev_video_ops, 1026 .video = &mt9t112_subdev_video_ops,
1051}; 1027};
1052 1028
1053static int mt9t112_camera_probe(struct soc_camera_device *icd, 1029static int mt9t112_camera_probe(struct i2c_client *client)
1054 struct i2c_client *client)
1055{ 1030{
1056 struct mt9t112_priv *priv = to_mt9t112(client); 1031 struct mt9t112_priv *priv = to_mt9t112(client);
1057 const char *devname; 1032 const char *devname;
1058 int chipid; 1033 int chipid;
1059 1034
1060 /* We must have a parent by now. And it cannot be a wrong one. */
1061 BUG_ON(!icd->parent ||
1062 to_soc_camera_host(icd->parent)->nr != icd->iface);
1063
1064 /* 1035 /*
1065 * check and show chip ID 1036 * check and show chip ID
1066 */ 1037 */
@@ -1088,20 +1059,21 @@ static int mt9t112_camera_probe(struct soc_camera_device *icd,
1088static int mt9t112_probe(struct i2c_client *client, 1059static int mt9t112_probe(struct i2c_client *client,
1089 const struct i2c_device_id *did) 1060 const struct i2c_device_id *did)
1090{ 1061{
1091 struct mt9t112_priv *priv; 1062 struct mt9t112_priv *priv;
1092 struct soc_camera_device *icd = client->dev.platform_data; 1063 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1093 struct soc_camera_link *icl; 1064 struct v4l2_rect rect = {
1094 int ret; 1065 .width = VGA_WIDTH,
1066 .height = VGA_HEIGHT,
1067 .left = (MAX_WIDTH - VGA_WIDTH) / 2,
1068 .top = (MAX_HEIGHT - VGA_HEIGHT) / 2,
1069 };
1070 int ret;
1095 1071
1096 if (!icd) { 1072 if (!icl || !icl->priv) {
1097 dev_err(&client->dev, "mt9t112: missing soc-camera data!\n"); 1073 dev_err(&client->dev, "mt9t112: missing platform data!\n");
1098 return -EINVAL; 1074 return -EINVAL;
1099 } 1075 }
1100 1076
1101 icl = to_soc_camera_link(icd);
1102 if (!icl || !icl->priv)
1103 return -EINVAL;
1104
1105 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 1077 priv = kzalloc(sizeof(*priv), GFP_KERNEL);
1106 if (!priv) 1078 if (!priv)
1107 return -ENOMEM; 1079 return -ENOMEM;
@@ -1110,13 +1082,12 @@ static int mt9t112_probe(struct i2c_client *client,
1110 1082
1111 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops); 1083 v4l2_i2c_subdev_init(&priv->subdev, client, &mt9t112_subdev_ops);
1112 1084
1113 icd->ops = &mt9t112_ops; 1085 ret = mt9t112_camera_probe(client);
1114 1086 if (ret)
1115 ret = mt9t112_camera_probe(icd, client);
1116 if (ret) {
1117 icd->ops = NULL;
1118 kfree(priv); 1087 kfree(priv);
1119 } 1088
1089 /* Cannot fail: using the default supported pixel code */
1090 mt9t112_set_params(priv, &rect, V4L2_MBUS_FMT_UYVY8_2X8);
1120 1091
1121 return ret; 1092 return ret;
1122} 1093}
@@ -1124,9 +1095,7 @@ static int mt9t112_probe(struct i2c_client *client,
1124static int mt9t112_remove(struct i2c_client *client) 1095static int mt9t112_remove(struct i2c_client *client)
1125{ 1096{
1126 struct mt9t112_priv *priv = to_mt9t112(client); 1097 struct mt9t112_priv *priv = to_mt9t112(client);
1127 struct soc_camera_device *icd = client->dev.platform_data;
1128 1098
1129 icd->ops = NULL;
1130 kfree(priv); 1099 kfree(priv);
1131 return 0; 1100 return 0;
1132} 1101}
@@ -1147,11 +1116,7 @@ static struct i2c_driver mt9t112_i2c_driver = {
1147}; 1116};
1148 1117
1149/************************************************************************ 1118/************************************************************************
1150
1151
1152 module function 1119 module function
1153
1154
1155************************************************************************/ 1120************************************************************************/
1156static int __init mt9t112_module_init(void) 1121static int __init mt9t112_module_init(void)
1157{ 1122{
diff --git a/drivers/media/video/mt9v022.c b/drivers/media/video/mt9v022.c
index 51b0fccbfe7..b6a29f7de82 100644
--- a/drivers/media/video/mt9v022.c
+++ b/drivers/media/video/mt9v022.c
@@ -14,9 +14,11 @@
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16 16
17#include <media/soc_camera.h>
18#include <media/soc_mediabus.h>
17#include <media/v4l2-subdev.h> 19#include <media/v4l2-subdev.h>
18#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
19#include <media/soc_camera.h> 21#include <media/v4l2-ctrls.h>
20 22
21/* 23/*
22 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c 24 * mt9v022 i2c address 0x48, 0x4c, 0x58, 0x5c
@@ -100,6 +102,17 @@ static const struct mt9v022_datafmt mt9v022_monochrome_fmts[] = {
100 102
101struct mt9v022 { 103struct mt9v022 {
102 struct v4l2_subdev subdev; 104 struct v4l2_subdev subdev;
105 struct v4l2_ctrl_handler hdl;
106 struct {
107 /* exposure/auto-exposure cluster */
108 struct v4l2_ctrl *autoexposure;
109 struct v4l2_ctrl *exposure;
110 };
111 struct {
112 /* gain/auto-gain cluster */
113 struct v4l2_ctrl *autogain;
114 struct v4l2_ctrl *gain;
115 };
103 struct v4l2_rect rect; /* Sensor window */ 116 struct v4l2_rect rect; /* Sensor window */
104 const struct mt9v022_datafmt *fmt; 117 const struct mt9v022_datafmt *fmt;
105 const struct mt9v022_datafmt *fmts; 118 const struct mt9v022_datafmt *fmts;
@@ -178,6 +191,8 @@ static int mt9v022_init(struct i2c_client *client)
178 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); 191 ret = reg_clear(client, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1);
179 if (!ret) 192 if (!ret)
180 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0); 193 ret = reg_write(client, MT9V022_DIGITAL_TEST_PATTERN, 0);
194 if (!ret)
195 return v4l2_ctrl_handler_setup(&mt9v022->hdl);
181 196
182 return ret; 197 return ret;
183} 198}
@@ -199,78 +214,6 @@ static int mt9v022_s_stream(struct v4l2_subdev *sd, int enable)
199 return 0; 214 return 0;
200} 215}
201 216
202static int mt9v022_set_bus_param(struct soc_camera_device *icd,
203 unsigned long flags)
204{
205 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
206 struct mt9v022 *mt9v022 = to_mt9v022(client);
207 struct soc_camera_link *icl = to_soc_camera_link(icd);
208 unsigned int width_flag = flags & SOCAM_DATAWIDTH_MASK;
209 int ret;
210 u16 pixclk = 0;
211
212 /* Only one width bit may be set */
213 if (!is_power_of_2(width_flag))
214 return -EINVAL;
215
216 if (icl->set_bus_param) {
217 ret = icl->set_bus_param(icl, width_flag);
218 if (ret)
219 return ret;
220 } else {
221 /*
222 * Without board specific bus width settings we only support the
223 * sensors native bus width
224 */
225 if (width_flag != SOCAM_DATAWIDTH_10)
226 return -EINVAL;
227 }
228
229 flags = soc_camera_apply_sensor_flags(icl, flags);
230
231 if (flags & SOCAM_PCLK_SAMPLE_FALLING)
232 pixclk |= 0x10;
233
234 if (!(flags & SOCAM_HSYNC_ACTIVE_HIGH))
235 pixclk |= 0x1;
236
237 if (!(flags & SOCAM_VSYNC_ACTIVE_HIGH))
238 pixclk |= 0x2;
239
240 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
241 if (ret < 0)
242 return ret;
243
244 if (!(flags & SOCAM_MASTER))
245 mt9v022->chip_control &= ~0x8;
246
247 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
248 if (ret < 0)
249 return ret;
250
251 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
252 pixclk, mt9v022->chip_control);
253
254 return 0;
255}
256
257static unsigned long mt9v022_query_bus_param(struct soc_camera_device *icd)
258{
259 struct soc_camera_link *icl = to_soc_camera_link(icd);
260 unsigned int flags = SOCAM_MASTER | SOCAM_SLAVE |
261 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
262 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
263 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
264 SOCAM_DATA_ACTIVE_HIGH;
265
266 if (icl->query_bus_param)
267 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
268 else
269 flags |= SOCAM_DATAWIDTH_10;
270
271 return soc_camera_apply_sensor_flags(icl, flags);
272}
273
274static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 217static int mt9v022_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
275{ 218{
276 struct i2c_client *client = v4l2_get_subdevdata(sd); 219 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -389,7 +332,7 @@ static int mt9v022_s_fmt(struct v4l2_subdev *sd,
389 332
390 /* 333 /*
391 * The caller provides a supported format, as verified per call to 334 * The caller provides a supported format, as verified per call to
392 * icd->try_fmt(), datawidth is from our supported format list 335 * .try_mbus_fmt(), datawidth is from our supported format list
393 */ 336 */
394 switch (mf->code) { 337 switch (mf->code) {
395 case V4L2_MBUS_FMT_Y8_1X8: 338 case V4L2_MBUS_FMT_Y8_1X8:
@@ -502,236 +445,131 @@ static int mt9v022_s_register(struct v4l2_subdev *sd,
502} 445}
503#endif 446#endif
504 447
505static const struct v4l2_queryctrl mt9v022_controls[] = { 448static int mt9v022_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
506 {
507 .id = V4L2_CID_VFLIP,
508 .type = V4L2_CTRL_TYPE_BOOLEAN,
509 .name = "Flip Vertically",
510 .minimum = 0,
511 .maximum = 1,
512 .step = 1,
513 .default_value = 0,
514 }, {
515 .id = V4L2_CID_HFLIP,
516 .type = V4L2_CTRL_TYPE_BOOLEAN,
517 .name = "Flip Horizontally",
518 .minimum = 0,
519 .maximum = 1,
520 .step = 1,
521 .default_value = 0,
522 }, {
523 .id = V4L2_CID_GAIN,
524 .type = V4L2_CTRL_TYPE_INTEGER,
525 .name = "Analog Gain",
526 .minimum = 64,
527 .maximum = 127,
528 .step = 1,
529 .default_value = 64,
530 .flags = V4L2_CTRL_FLAG_SLIDER,
531 }, {
532 .id = V4L2_CID_EXPOSURE,
533 .type = V4L2_CTRL_TYPE_INTEGER,
534 .name = "Exposure",
535 .minimum = 1,
536 .maximum = 255,
537 .step = 1,
538 .default_value = 255,
539 .flags = V4L2_CTRL_FLAG_SLIDER,
540 }, {
541 .id = V4L2_CID_AUTOGAIN,
542 .type = V4L2_CTRL_TYPE_BOOLEAN,
543 .name = "Automatic Gain",
544 .minimum = 0,
545 .maximum = 1,
546 .step = 1,
547 .default_value = 1,
548 }, {
549 .id = V4L2_CID_EXPOSURE_AUTO,
550 .type = V4L2_CTRL_TYPE_BOOLEAN,
551 .name = "Automatic Exposure",
552 .minimum = 0,
553 .maximum = 1,
554 .step = 1,
555 .default_value = 1,
556 }
557};
558
559static struct soc_camera_ops mt9v022_ops = {
560 .set_bus_param = mt9v022_set_bus_param,
561 .query_bus_param = mt9v022_query_bus_param,
562 .controls = mt9v022_controls,
563 .num_controls = ARRAY_SIZE(mt9v022_controls),
564};
565
566static int mt9v022_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
567{ 449{
450 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
451 struct mt9v022, hdl);
452 struct v4l2_subdev *sd = &mt9v022->subdev;
568 struct i2c_client *client = v4l2_get_subdevdata(sd); 453 struct i2c_client *client = v4l2_get_subdevdata(sd);
569 const struct v4l2_queryctrl *qctrl; 454 struct v4l2_ctrl *gain = mt9v022->gain;
455 struct v4l2_ctrl *exp = mt9v022->exposure;
570 unsigned long range; 456 unsigned long range;
571 int data; 457 int data;
572 458
573 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
574
575 switch (ctrl->id) { 459 switch (ctrl->id) {
576 case V4L2_CID_VFLIP:
577 data = reg_read(client, MT9V022_READ_MODE);
578 if (data < 0)
579 return -EIO;
580 ctrl->value = !!(data & 0x10);
581 break;
582 case V4L2_CID_HFLIP:
583 data = reg_read(client, MT9V022_READ_MODE);
584 if (data < 0)
585 return -EIO;
586 ctrl->value = !!(data & 0x20);
587 break;
588 case V4L2_CID_EXPOSURE_AUTO:
589 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
590 if (data < 0)
591 return -EIO;
592 ctrl->value = !!(data & 0x1);
593 break;
594 case V4L2_CID_AUTOGAIN: 460 case V4L2_CID_AUTOGAIN:
595 data = reg_read(client, MT9V022_AEC_AGC_ENABLE);
596 if (data < 0)
597 return -EIO;
598 ctrl->value = !!(data & 0x2);
599 break;
600 case V4L2_CID_GAIN:
601 data = reg_read(client, MT9V022_ANALOG_GAIN); 461 data = reg_read(client, MT9V022_ANALOG_GAIN);
602 if (data < 0) 462 if (data < 0)
603 return -EIO; 463 return -EIO;
604 464
605 range = qctrl->maximum - qctrl->minimum; 465 range = gain->maximum - gain->minimum;
606 ctrl->value = ((data - 16) * range + 24) / 48 + qctrl->minimum; 466 gain->val = ((data - 16) * range + 24) / 48 + gain->minimum;
607 467 return 0;
608 break; 468 case V4L2_CID_EXPOSURE_AUTO:
609 case V4L2_CID_EXPOSURE:
610 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH); 469 data = reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH);
611 if (data < 0) 470 if (data < 0)
612 return -EIO; 471 return -EIO;
613 472
614 range = qctrl->maximum - qctrl->minimum; 473 range = exp->maximum - exp->minimum;
615 ctrl->value = ((data - 1) * range + 239) / 479 + qctrl->minimum; 474 exp->val = ((data - 1) * range + 239) / 479 + exp->minimum;
616 475 return 0;
617 break;
618 } 476 }
619 return 0; 477 return -EINVAL;
620} 478}
621 479
622static int mt9v022_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 480static int mt9v022_s_ctrl(struct v4l2_ctrl *ctrl)
623{ 481{
624 int data; 482 struct mt9v022 *mt9v022 = container_of(ctrl->handler,
483 struct mt9v022, hdl);
484 struct v4l2_subdev *sd = &mt9v022->subdev;
625 struct i2c_client *client = v4l2_get_subdevdata(sd); 485 struct i2c_client *client = v4l2_get_subdevdata(sd);
626 const struct v4l2_queryctrl *qctrl; 486 int data;
627
628 qctrl = soc_camera_find_qctrl(&mt9v022_ops, ctrl->id);
629 if (!qctrl)
630 return -EINVAL;
631 487
632 switch (ctrl->id) { 488 switch (ctrl->id) {
633 case V4L2_CID_VFLIP: 489 case V4L2_CID_VFLIP:
634 if (ctrl->value) 490 if (ctrl->val)
635 data = reg_set(client, MT9V022_READ_MODE, 0x10); 491 data = reg_set(client, MT9V022_READ_MODE, 0x10);
636 else 492 else
637 data = reg_clear(client, MT9V022_READ_MODE, 0x10); 493 data = reg_clear(client, MT9V022_READ_MODE, 0x10);
638 if (data < 0) 494 if (data < 0)
639 return -EIO; 495 return -EIO;
640 break; 496 return 0;
641 case V4L2_CID_HFLIP: 497 case V4L2_CID_HFLIP:
642 if (ctrl->value) 498 if (ctrl->val)
643 data = reg_set(client, MT9V022_READ_MODE, 0x20); 499 data = reg_set(client, MT9V022_READ_MODE, 0x20);
644 else 500 else
645 data = reg_clear(client, MT9V022_READ_MODE, 0x20); 501 data = reg_clear(client, MT9V022_READ_MODE, 0x20);
646 if (data < 0) 502 if (data < 0)
647 return -EIO; 503 return -EIO;
648 break; 504 return 0;
649 case V4L2_CID_GAIN: 505 case V4L2_CID_AUTOGAIN:
650 /* mt9v022 has minimum == default */ 506 if (ctrl->val) {
651 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) 507 if (reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
652 return -EINVAL; 508 return -EIO;
653 else { 509 } else {
654 unsigned long range = qctrl->maximum - qctrl->minimum; 510 struct v4l2_ctrl *gain = mt9v022->gain;
511 /* mt9v022 has minimum == default */
512 unsigned long range = gain->maximum - gain->minimum;
655 /* Valid values 16 to 64, 32 to 64 must be even. */ 513 /* Valid values 16 to 64, 32 to 64 must be even. */
656 unsigned long gain = ((ctrl->value - qctrl->minimum) * 514 unsigned long gain_val = ((gain->val - gain->minimum) *
657 48 + range / 2) / range + 16; 515 48 + range / 2) / range + 16;
658 if (gain >= 32) 516
659 gain &= ~1; 517 if (gain_val >= 32)
518 gain_val &= ~1;
519
660 /* 520 /*
661 * The user wants to set gain manually, hope, she 521 * The user wants to set gain manually, hope, she
662 * knows, what she's doing... Switch AGC off. 522 * knows, what she's doing... Switch AGC off.
663 */ 523 */
664
665 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0) 524 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2) < 0)
666 return -EIO; 525 return -EIO;
667 526
668 dev_dbg(&client->dev, "Setting gain from %d to %lu\n", 527 dev_dbg(&client->dev, "Setting gain from %d to %lu\n",
669 reg_read(client, MT9V022_ANALOG_GAIN), gain); 528 reg_read(client, MT9V022_ANALOG_GAIN), gain_val);
670 if (reg_write(client, MT9V022_ANALOG_GAIN, gain) < 0) 529 if (reg_write(client, MT9V022_ANALOG_GAIN, gain_val) < 0)
671 return -EIO; 530 return -EIO;
672 } 531 }
673 break; 532 return 0;
674 case V4L2_CID_EXPOSURE: 533 case V4L2_CID_EXPOSURE_AUTO:
675 /* mt9v022 has maximum == default */ 534 if (ctrl->val == V4L2_EXPOSURE_AUTO) {
676 if (ctrl->value > qctrl->maximum || ctrl->value < qctrl->minimum) 535 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
677 return -EINVAL; 536 } else {
678 else { 537 struct v4l2_ctrl *exp = mt9v022->exposure;
679 unsigned long range = qctrl->maximum - qctrl->minimum; 538 unsigned long range = exp->maximum - exp->minimum;
680 unsigned long shutter = ((ctrl->value - qctrl->minimum) * 539 unsigned long shutter = ((exp->val - exp->minimum) *
681 479 + range / 2) / range + 1; 540 479 + range / 2) / range + 1;
541
682 /* 542 /*
683 * The user wants to set shutter width manually, hope, 543 * The user wants to set shutter width manually, hope,
684 * she knows, what she's doing... Switch AEC off. 544 * she knows, what she's doing... Switch AEC off.
685 */ 545 */
686 546 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
687 if (reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1) < 0) 547 if (data < 0)
688 return -EIO; 548 return -EIO;
689
690 dev_dbg(&client->dev, "Shutter width from %d to %lu\n", 549 dev_dbg(&client->dev, "Shutter width from %d to %lu\n",
691 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH), 550 reg_read(client, MT9V022_TOTAL_SHUTTER_WIDTH),
692 shutter); 551 shutter);
693 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH, 552 if (reg_write(client, MT9V022_TOTAL_SHUTTER_WIDTH,
694 shutter) < 0) 553 shutter) < 0)
695 return -EIO; 554 return -EIO;
696 } 555 }
697 break; 556 return 0;
698 case V4L2_CID_AUTOGAIN:
699 if (ctrl->value)
700 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x2);
701 else
702 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x2);
703 if (data < 0)
704 return -EIO;
705 break;
706 case V4L2_CID_EXPOSURE_AUTO:
707 if (ctrl->value)
708 data = reg_set(client, MT9V022_AEC_AGC_ENABLE, 0x1);
709 else
710 data = reg_clear(client, MT9V022_AEC_AGC_ENABLE, 0x1);
711 if (data < 0)
712 return -EIO;
713 break;
714 } 557 }
715 return 0; 558 return -EINVAL;
716} 559}
717 560
718/* 561/*
719 * Interface active, can use i2c. If it fails, it can indeed mean, that 562 * Interface active, can use i2c. If it fails, it can indeed mean, that
720 * this wasn't our capture interface, so, we wait for the right one 563 * this wasn't our capture interface, so, we wait for the right one
721 */ 564 */
722static int mt9v022_video_probe(struct soc_camera_device *icd, 565static int mt9v022_video_probe(struct i2c_client *client)
723 struct i2c_client *client)
724{ 566{
725 struct mt9v022 *mt9v022 = to_mt9v022(client); 567 struct mt9v022 *mt9v022 = to_mt9v022(client);
726 struct soc_camera_link *icl = to_soc_camera_link(icd); 568 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
727 s32 data; 569 s32 data;
728 int ret; 570 int ret;
729 unsigned long flags; 571 unsigned long flags;
730 572
731 /* We must have a parent by now. And it cannot be a wrong one. */
732 BUG_ON(!icd->parent ||
733 to_soc_camera_host(icd->parent)->nr != icd->iface);
734
735 /* Read out the chip version register */ 573 /* Read out the chip version register */
736 data = reg_read(client, MT9V022_CHIP_VERSION); 574 data = reg_read(client, MT9V022_CHIP_VERSION);
737 575
@@ -805,16 +643,6 @@ ei2c:
805 return ret; 643 return ret;
806} 644}
807 645
808static void mt9v022_video_remove(struct soc_camera_device *icd)
809{
810 struct soc_camera_link *icl = to_soc_camera_link(icd);
811
812 dev_dbg(icd->pdev, "Video removed: %p, %p\n",
813 icd->parent, icd->vdev);
814 if (icl->free_bus)
815 icl->free_bus(icl);
816}
817
818static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines) 646static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
819{ 647{
820 struct i2c_client *client = v4l2_get_subdevdata(sd); 648 struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -825,9 +653,12 @@ static int mt9v022_g_skip_top_lines(struct v4l2_subdev *sd, u32 *lines)
825 return 0; 653 return 0;
826} 654}
827 655
656static const struct v4l2_ctrl_ops mt9v022_ctrl_ops = {
657 .g_volatile_ctrl = mt9v022_g_volatile_ctrl,
658 .s_ctrl = mt9v022_s_ctrl,
659};
660
828static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = { 661static struct v4l2_subdev_core_ops mt9v022_subdev_core_ops = {
829 .g_ctrl = mt9v022_g_ctrl,
830 .s_ctrl = mt9v022_s_ctrl,
831 .g_chip_ident = mt9v022_g_chip_ident, 662 .g_chip_ident = mt9v022_g_chip_ident,
832#ifdef CONFIG_VIDEO_ADV_DEBUG 663#ifdef CONFIG_VIDEO_ADV_DEBUG
833 .g_register = mt9v022_g_register, 664 .g_register = mt9v022_g_register,
@@ -848,6 +679,72 @@ static int mt9v022_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
848 return 0; 679 return 0;
849} 680}
850 681
682static int mt9v022_g_mbus_config(struct v4l2_subdev *sd,
683 struct v4l2_mbus_config *cfg)
684{
685 struct i2c_client *client = v4l2_get_subdevdata(sd);
686 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
687
688 cfg->flags = V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE |
689 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
690 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
691 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
692 V4L2_MBUS_DATA_ACTIVE_HIGH;
693 cfg->type = V4L2_MBUS_PARALLEL;
694 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
695
696 return 0;
697}
698
699static int mt9v022_s_mbus_config(struct v4l2_subdev *sd,
700 const struct v4l2_mbus_config *cfg)
701{
702 struct i2c_client *client = v4l2_get_subdevdata(sd);
703 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
704 struct mt9v022 *mt9v022 = to_mt9v022(client);
705 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
706 unsigned int bps = soc_mbus_get_fmtdesc(mt9v022->fmt->code)->bits_per_sample;
707 int ret;
708 u16 pixclk = 0;
709
710 if (icl->set_bus_param) {
711 ret = icl->set_bus_param(icl, 1 << (bps - 1));
712 if (ret)
713 return ret;
714 } else if (bps != 10) {
715 /*
716 * Without board specific bus width settings we only support the
717 * sensors native bus width
718 */
719 return -EINVAL;
720 }
721
722 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
723 pixclk |= 0x10;
724
725 if (!(flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH))
726 pixclk |= 0x1;
727
728 if (!(flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH))
729 pixclk |= 0x2;
730
731 ret = reg_write(client, MT9V022_PIXCLK_FV_LV, pixclk);
732 if (ret < 0)
733 return ret;
734
735 if (!(flags & V4L2_MBUS_MASTER))
736 mt9v022->chip_control &= ~0x8;
737
738 ret = reg_write(client, MT9V022_CHIP_CONTROL, mt9v022->chip_control);
739 if (ret < 0)
740 return ret;
741
742 dev_dbg(&client->dev, "Calculated pixclk 0x%x, chip control 0x%x\n",
743 pixclk, mt9v022->chip_control);
744
745 return 0;
746}
747
851static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = { 748static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
852 .s_stream = mt9v022_s_stream, 749 .s_stream = mt9v022_s_stream,
853 .s_mbus_fmt = mt9v022_s_fmt, 750 .s_mbus_fmt = mt9v022_s_fmt,
@@ -857,6 +754,8 @@ static struct v4l2_subdev_video_ops mt9v022_subdev_video_ops = {
857 .g_crop = mt9v022_g_crop, 754 .g_crop = mt9v022_g_crop,
858 .cropcap = mt9v022_cropcap, 755 .cropcap = mt9v022_cropcap,
859 .enum_mbus_fmt = mt9v022_enum_fmt, 756 .enum_mbus_fmt = mt9v022_enum_fmt,
757 .g_mbus_config = mt9v022_g_mbus_config,
758 .s_mbus_config = mt9v022_s_mbus_config,
860}; 759};
861 760
862static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = { 761static struct v4l2_subdev_sensor_ops mt9v022_subdev_sensor_ops = {
@@ -873,17 +772,10 @@ static int mt9v022_probe(struct i2c_client *client,
873 const struct i2c_device_id *did) 772 const struct i2c_device_id *did)
874{ 773{
875 struct mt9v022 *mt9v022; 774 struct mt9v022 *mt9v022;
876 struct soc_camera_device *icd = client->dev.platform_data; 775 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
877 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 776 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
878 struct soc_camera_link *icl;
879 int ret; 777 int ret;
880 778
881 if (!icd) {
882 dev_err(&client->dev, "MT9V022: missing soc-camera data!\n");
883 return -EINVAL;
884 }
885
886 icl = to_soc_camera_link(icd);
887 if (!icl) { 779 if (!icl) {
888 dev_err(&client->dev, "MT9V022 driver needs platform data\n"); 780 dev_err(&client->dev, "MT9V022 driver needs platform data\n");
889 return -EINVAL; 781 return -EINVAL;
@@ -900,10 +792,39 @@ static int mt9v022_probe(struct i2c_client *client,
900 return -ENOMEM; 792 return -ENOMEM;
901 793
902 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops); 794 v4l2_i2c_subdev_init(&mt9v022->subdev, client, &mt9v022_subdev_ops);
795 v4l2_ctrl_handler_init(&mt9v022->hdl, 6);
796 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
797 V4L2_CID_VFLIP, 0, 1, 1, 0);
798 v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
799 V4L2_CID_HFLIP, 0, 1, 1, 0);
800 mt9v022->autogain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
801 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
802 mt9v022->gain = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
803 V4L2_CID_GAIN, 0, 127, 1, 64);
804
805 /*
806 * Simulated autoexposure. If enabled, we calculate shutter width
807 * ourselves in the driver based on vertical blanking and frame width
808 */
809 mt9v022->autoexposure = v4l2_ctrl_new_std_menu(&mt9v022->hdl,
810 &mt9v022_ctrl_ops, V4L2_CID_EXPOSURE_AUTO, 1, 0,
811 V4L2_EXPOSURE_AUTO);
812 mt9v022->exposure = v4l2_ctrl_new_std(&mt9v022->hdl, &mt9v022_ctrl_ops,
813 V4L2_CID_EXPOSURE, 1, 255, 1, 255);
814
815 mt9v022->subdev.ctrl_handler = &mt9v022->hdl;
816 if (mt9v022->hdl.error) {
817 int err = mt9v022->hdl.error;
818
819 kfree(mt9v022);
820 return err;
821 }
822 v4l2_ctrl_auto_cluster(2, &mt9v022->autoexposure,
823 V4L2_EXPOSURE_MANUAL, true);
824 v4l2_ctrl_auto_cluster(2, &mt9v022->autogain, 0, true);
903 825
904 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT; 826 mt9v022->chip_control = MT9V022_CHIP_CONTROL_DEFAULT;
905 827
906 icd->ops = &mt9v022_ops;
907 /* 828 /*
908 * MT9V022 _really_ corrupts the first read out line. 829 * MT9V022 _really_ corrupts the first read out line.
909 * TODO: verify on i.MX31 830 * TODO: verify on i.MX31
@@ -914,9 +835,9 @@ static int mt9v022_probe(struct i2c_client *client,
914 mt9v022->rect.width = MT9V022_MAX_WIDTH; 835 mt9v022->rect.width = MT9V022_MAX_WIDTH;
915 mt9v022->rect.height = MT9V022_MAX_HEIGHT; 836 mt9v022->rect.height = MT9V022_MAX_HEIGHT;
916 837
917 ret = mt9v022_video_probe(icd, client); 838 ret = mt9v022_video_probe(client);
918 if (ret) { 839 if (ret) {
919 icd->ops = NULL; 840 v4l2_ctrl_handler_free(&mt9v022->hdl);
920 kfree(mt9v022); 841 kfree(mt9v022);
921 } 842 }
922 843
@@ -926,10 +847,12 @@ static int mt9v022_probe(struct i2c_client *client,
926static int mt9v022_remove(struct i2c_client *client) 847static int mt9v022_remove(struct i2c_client *client)
927{ 848{
928 struct mt9v022 *mt9v022 = to_mt9v022(client); 849 struct mt9v022 *mt9v022 = to_mt9v022(client);
929 struct soc_camera_device *icd = client->dev.platform_data; 850 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
930 851
931 icd->ops = NULL; 852 v4l2_device_unregister_subdev(&mt9v022->subdev);
932 mt9v022_video_remove(icd); 853 if (icl->free_bus)
854 icl->free_bus(icl);
855 v4l2_ctrl_handler_free(&mt9v022->hdl);
933 kfree(mt9v022); 856 kfree(mt9v022);
934 857
935 return 0; 858 return 0;
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c
index 087db12a3a6..18e94c7d2be 100644
--- a/drivers/media/video/mx1_camera.c
+++ b/drivers/media/video/mx1_camera.c
@@ -78,11 +78,10 @@
78#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \ 78#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
79 CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT) 79 CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
80 80
81#define CSI_BUS_FLAGS (SOCAM_MASTER | SOCAM_HSYNC_ACTIVE_HIGH | \ 81#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
82 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | \ 82 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
83 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \ 83 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
84 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW | \ 84 V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
85 SOCAM_DATAWIDTH_8)
86 85
87#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */ 86#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
88 87
@@ -490,59 +489,73 @@ static int mx1_camera_set_crop(struct soc_camera_device *icd,
490 489
491static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 490static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
492{ 491{
492 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
493 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 493 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
494 struct mx1_camera_dev *pcdev = ici->priv; 494 struct mx1_camera_dev *pcdev = ici->priv;
495 unsigned long camera_flags, common_flags; 495 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
496 unsigned long common_flags;
496 unsigned int csicr1; 497 unsigned int csicr1;
497 int ret; 498 int ret;
498 499
499 camera_flags = icd->ops->query_bus_param(icd);
500
501 /* MX1 supports only 8bit buswidth */ 500 /* MX1 supports only 8bit buswidth */
502 common_flags = soc_camera_bus_param_compatible(camera_flags, 501 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
503 CSI_BUS_FLAGS); 502 if (!ret) {
504 if (!common_flags) 503 common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
505 return -EINVAL; 504 if (!common_flags) {
505 dev_warn(icd->parent,
506 "Flags incompatible: camera 0x%x, host 0x%x\n",
507 cfg.flags, CSI_BUS_FLAGS);
508 return -EINVAL;
509 }
510 } else if (ret != -ENOIOCTLCMD) {
511 return ret;
512 } else {
513 common_flags = CSI_BUS_FLAGS;
514 }
506 515
507 /* Make choises, based on platform choice */ 516 /* Make choises, based on platform choice */
508 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 517 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
509 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 518 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
510 if (!pcdev->pdata || 519 if (!pcdev->pdata ||
511 pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH) 520 pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
512 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 521 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
513 else 522 else
514 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 523 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
515 } 524 }
516 525
517 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 526 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
518 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 527 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
519 if (!pcdev->pdata || 528 if (!pcdev->pdata ||
520 pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING) 529 pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
521 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 530 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
522 else 531 else
523 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 532 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
524 } 533 }
525 534
526 if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && 535 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
527 (common_flags & SOCAM_DATA_ACTIVE_LOW)) { 536 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
528 if (!pcdev->pdata || 537 if (!pcdev->pdata ||
529 pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH) 538 pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
530 common_flags &= ~SOCAM_DATA_ACTIVE_LOW; 539 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
531 else 540 else
532 common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; 541 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
533 } 542 }
534 543
535 ret = icd->ops->set_bus_param(icd, common_flags); 544 cfg.flags = common_flags;
536 if (ret < 0) 545 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
546 if (ret < 0 && ret != -ENOIOCTLCMD) {
547 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
548 common_flags, ret);
537 return ret; 549 return ret;
550 }
538 551
539 csicr1 = __raw_readl(pcdev->base + CSICR1); 552 csicr1 = __raw_readl(pcdev->base + CSICR1);
540 553
541 if (common_flags & SOCAM_PCLK_SAMPLE_RISING) 554 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
542 csicr1 |= CSICR1_REDGE; 555 csicr1 |= CSICR1_REDGE;
543 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) 556 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
544 csicr1 |= CSICR1_SOF_POL; 557 csicr1 |= CSICR1_SOF_POL;
545 if (common_flags & SOCAM_DATA_ACTIVE_LOW) 558 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
546 csicr1 |= CSICR1_DATA_POL; 559 csicr1 |= CSICR1_DATA_POL;
547 560
548 __raw_writel(csicr1, pcdev->base + CSICR1); 561 __raw_writel(csicr1, pcdev->base + CSICR1);
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c
index ec2410c0c80..a803d9ea8fd 100644
--- a/drivers/media/video/mx2_camera.c
+++ b/drivers/media/video/mx2_camera.c
@@ -686,16 +686,15 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q,
686 icd, &icd->video_lock); 686 icd, &icd->video_lock);
687} 687}
688 688
689#define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \ 689#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
690 SOCAM_MASTER | \ 690 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
691 SOCAM_VSYNC_ACTIVE_HIGH | \ 691 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
692 SOCAM_VSYNC_ACTIVE_LOW | \ 692 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
693 SOCAM_HSYNC_ACTIVE_HIGH | \ 693 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
694 SOCAM_HSYNC_ACTIVE_LOW | \ 694 V4L2_MBUS_PCLK_SAMPLE_RISING | \
695 SOCAM_PCLK_SAMPLE_RISING | \ 695 V4L2_MBUS_PCLK_SAMPLE_FALLING | \
696 SOCAM_PCLK_SAMPLE_FALLING | \ 696 V4L2_MBUS_DATA_ACTIVE_HIGH | \
697 SOCAM_DATA_ACTIVE_HIGH | \ 697 V4L2_MBUS_DATA_ACTIVE_LOW)
698 SOCAM_DATA_ACTIVE_LOW)
699 698
700static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev) 699static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
701{ 700{
@@ -770,46 +769,59 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
770static int mx2_camera_set_bus_param(struct soc_camera_device *icd, 769static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
771 __u32 pixfmt) 770 __u32 pixfmt)
772{ 771{
773 struct soc_camera_host *ici = 772 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
774 to_soc_camera_host(icd->parent); 773 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
775 struct mx2_camera_dev *pcdev = ici->priv; 774 struct mx2_camera_dev *pcdev = ici->priv;
776 unsigned long camera_flags, common_flags; 775 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
777 int ret = 0; 776 unsigned long common_flags;
777 int ret;
778 int bytesperline; 778 int bytesperline;
779 u32 csicr1 = pcdev->csicr1; 779 u32 csicr1 = pcdev->csicr1;
780 780
781 camera_flags = icd->ops->query_bus_param(icd); 781 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
782 782 if (!ret) {
783 common_flags = soc_camera_bus_param_compatible(camera_flags, 783 common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
784 MX2_BUS_FLAGS); 784 if (!common_flags) {
785 if (!common_flags) 785 dev_warn(icd->parent,
786 return -EINVAL; 786 "Flags incompatible: camera 0x%x, host 0x%x\n",
787 cfg.flags, MX2_BUS_FLAGS);
788 return -EINVAL;
789 }
790 } else if (ret != -ENOIOCTLCMD) {
791 return ret;
792 } else {
793 common_flags = MX2_BUS_FLAGS;
794 }
787 795
788 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 796 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
789 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 797 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
790 if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH) 798 if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
791 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 799 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
792 else 800 else
793 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 801 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
794 } 802 }
795 803
796 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 804 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
797 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 805 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
798 if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING) 806 if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
799 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 807 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
800 else 808 else
801 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 809 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
802 } 810 }
803 811
804 ret = icd->ops->set_bus_param(icd, common_flags); 812 cfg.flags = common_flags;
805 if (ret < 0) 813 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
814 if (ret < 0 && ret != -ENOIOCTLCMD) {
815 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
816 common_flags, ret);
806 return ret; 817 return ret;
818 }
807 819
808 if (common_flags & SOCAM_PCLK_SAMPLE_RISING) 820 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
809 csicr1 |= CSICR1_REDGE; 821 csicr1 |= CSICR1_REDGE;
810 if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH) 822 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
811 csicr1 |= CSICR1_SOF_POL; 823 csicr1 |= CSICR1_SOF_POL;
812 if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH) 824 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
813 csicr1 |= CSICR1_HSYNC_POL; 825 csicr1 |= CSICR1_HSYNC_POL;
814 if (pcdev->platform_flags & MX2_CAMERA_SWAP16) 826 if (pcdev->platform_flags & MX2_CAMERA_SWAP16)
815 csicr1 |= CSICR1_SWAP16_EN; 827 csicr1 |= CSICR1_SWAP16_EN;
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c
index c8e958a07e9..f96f92f00f9 100644
--- a/drivers/media/video/mx3_camera.c
+++ b/drivers/media/video/mx3_camera.c
@@ -109,10 +109,12 @@ struct mx3_camera_dev {
109 109
110 unsigned long platform_flags; 110 unsigned long platform_flags;
111 unsigned long mclk; 111 unsigned long mclk;
112 u16 width_flags; /* max 15 bits */
112 113
113 struct list_head capture; 114 struct list_head capture;
114 spinlock_t lock; /* Protects video buffer lists */ 115 spinlock_t lock; /* Protects video buffer lists */
115 struct mx3_camera_buffer *active; 116 struct mx3_camera_buffer *active;
117 size_t buf_total;
116 struct vb2_alloc_ctx *alloc_ctx; 118 struct vb2_alloc_ctx *alloc_ctx;
117 enum v4l2_field field; 119 enum v4l2_field field;
118 int sequence; 120 int sequence;
@@ -190,79 +192,53 @@ static void mx3_cam_dma_done(void *arg)
190 * Calculate the __buffer__ (not data) size and number of buffers. 192 * Calculate the __buffer__ (not data) size and number of buffers.
191 */ 193 */
192static int mx3_videobuf_setup(struct vb2_queue *vq, 194static int mx3_videobuf_setup(struct vb2_queue *vq,
195 const struct v4l2_format *fmt,
193 unsigned int *count, unsigned int *num_planes, 196 unsigned int *count, unsigned int *num_planes,
194 unsigned int sizes[], void *alloc_ctxs[]) 197 unsigned int sizes[], void *alloc_ctxs[])
195{ 198{
196 struct soc_camera_device *icd = soc_camera_from_vb2q(vq); 199 struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
197 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 200 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
198 struct mx3_camera_dev *mx3_cam = ici->priv; 201 struct mx3_camera_dev *mx3_cam = ici->priv;
199 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 202 int bytes_per_line;
200 icd->current_fmt->host_fmt); 203 unsigned int height;
201
202 if (bytes_per_line < 0)
203 return bytes_per_line;
204 204
205 if (!mx3_cam->idmac_channel[0]) 205 if (!mx3_cam->idmac_channel[0])
206 return -EINVAL; 206 return -EINVAL;
207 207
208 *num_planes = 1; 208 if (fmt) {
209 209 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
210 mx3_cam->sequence = 0; 210 fmt->fmt.pix.pixelformat);
211 sizes[0] = bytes_per_line * icd->user_height; 211 if (!xlate)
212 alloc_ctxs[0] = mx3_cam->alloc_ctx; 212 return -EINVAL;
213 213 bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
214 if (!*count) 214 xlate->host_fmt);
215 *count = 32; 215 height = fmt->fmt.pix.height;
216 216 } else {
217 if (sizes[0] * *count > MAX_VIDEO_MEM * 1024 * 1024) 217 /* Called from VIDIOC_REQBUFS or in compatibility mode */
218 *count = MAX_VIDEO_MEM * 1024 * 1024 / sizes[0]; 218 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
219
220 return 0;
221}
222
223static int mx3_videobuf_prepare(struct vb2_buffer *vb)
224{
225 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
226 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
227 struct mx3_camera_dev *mx3_cam = ici->priv;
228 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
229 struct scatterlist *sg;
230 struct mx3_camera_buffer *buf;
231 size_t new_size;
232 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
233 icd->current_fmt->host_fmt); 219 icd->current_fmt->host_fmt);
234 220 height = icd->user_height;
221 }
235 if (bytes_per_line < 0) 222 if (bytes_per_line < 0)
236 return bytes_per_line; 223 return bytes_per_line;
237 224
238 buf = to_mx3_vb(vb); 225 sizes[0] = bytes_per_line * height;
239 sg = &buf->sg;
240
241 new_size = bytes_per_line * icd->user_height;
242 226
243 if (vb2_plane_size(vb, 0) < new_size) { 227 alloc_ctxs[0] = mx3_cam->alloc_ctx;
244 dev_err(icd->parent, "Buffer too small (%lu < %zu)\n",
245 vb2_plane_size(vb, 0), new_size);
246 return -ENOBUFS;
247 }
248 228
249 if (buf->state == CSI_BUF_NEEDS_INIT) { 229 if (!vq->num_buffers)
250 sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); 230 mx3_cam->sequence = 0;
251 sg_dma_len(sg) = new_size;
252 231
253 buf->txd = ichan->dma_chan.device->device_prep_slave_sg( 232 if (!*count)
254 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE, 233 *count = 2;
255 DMA_PREP_INTERRUPT);
256 if (!buf->txd)
257 return -EIO;
258
259 buf->txd->callback_param = buf->txd;
260 buf->txd->callback = mx3_cam_dma_done;
261 234
262 buf->state = CSI_BUF_PREPARED; 235 /* If *num_planes != 0, we have already verified *count. */
263 } 236 if (!*num_planes &&
237 sizes[0] * *count + mx3_cam->buf_total > MAX_VIDEO_MEM * 1024 * 1024)
238 *count = (MAX_VIDEO_MEM * 1024 * 1024 - mx3_cam->buf_total) /
239 sizes[0];
264 240
265 vb2_set_plane_payload(vb, 0, new_size); 241 *num_planes = 1;
266 242
267 return 0; 243 return 0;
268} 244}
@@ -286,28 +262,58 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
286 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 262 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
287 struct mx3_camera_dev *mx3_cam = ici->priv; 263 struct mx3_camera_dev *mx3_cam = ici->priv;
288 struct mx3_camera_buffer *buf = to_mx3_vb(vb); 264 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
289 struct dma_async_tx_descriptor *txd = buf->txd; 265 struct scatterlist *sg = &buf->sg;
290 struct idmac_channel *ichan = to_idmac_chan(txd->chan); 266 struct dma_async_tx_descriptor *txd;
267 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
291 struct idmac_video_param *video = &ichan->params.video; 268 struct idmac_video_param *video = &ichan->params.video;
292 dma_cookie_t cookie; 269 const struct soc_mbus_pixelfmt *host_fmt = icd->current_fmt->host_fmt;
293 u32 fourcc = icd->current_fmt->host_fmt->fourcc; 270 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, host_fmt);
294 unsigned long flags; 271 unsigned long flags;
272 dma_cookie_t cookie;
273 size_t new_size;
274
275 BUG_ON(bytes_per_line <= 0);
276
277 new_size = bytes_per_line * icd->user_height;
278
279 if (vb2_plane_size(vb, 0) < new_size) {
280 dev_err(icd->parent, "Buffer #%d too small (%lu < %zu)\n",
281 vb->v4l2_buf.index, vb2_plane_size(vb, 0), new_size);
282 goto error;
283 }
284
285 if (buf->state == CSI_BUF_NEEDS_INIT) {
286 sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0);
287 sg_dma_len(sg) = new_size;
288
289 txd = ichan->dma_chan.device->device_prep_slave_sg(
290 &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE,
291 DMA_PREP_INTERRUPT);
292 if (!txd)
293 goto error;
294
295 txd->callback_param = txd;
296 txd->callback = mx3_cam_dma_done;
297
298 buf->state = CSI_BUF_PREPARED;
299 buf->txd = txd;
300 } else {
301 txd = buf->txd;
302 }
303
304 vb2_set_plane_payload(vb, 0, new_size);
295 305
296 /* This is the configuration of one sg-element */ 306 /* This is the configuration of one sg-element */
297 video->out_pixel_fmt = fourcc_to_ipu_pix(fourcc); 307 video->out_pixel_fmt = fourcc_to_ipu_pix(host_fmt->fourcc);
298 308
299 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) { 309 if (video->out_pixel_fmt == IPU_PIX_FMT_GENERIC) {
300 /* 310 /*
301 * If the IPU DMA channel is configured to transport 311 * If the IPU DMA channel is configured to transfer generic
302 * generic 8-bit data, we have to set up correctly the 312 * 8-bit data, we have to set up the geometry parameters
303 * geometry parameters upon the current pixel format. 313 * correctly, according to the current pixel format. The DMA
304 * So, since the DMA horizontal parameters are expressed 314 * horizontal parameters in this case are expressed in bytes,
305 * in bytes not pixels, convert these in the right unit. 315 * not in pixels.
306 */ 316 */
307 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
308 icd->current_fmt->host_fmt);
309 BUG_ON(bytes_per_line <= 0);
310
311 video->out_width = bytes_per_line; 317 video->out_width = bytes_per_line;
312 video->out_height = icd->user_height; 318 video->out_height = icd->user_height;
313 video->out_stride = bytes_per_line; 319 video->out_stride = bytes_per_line;
@@ -351,6 +357,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb)
351 mx3_cam->active = NULL; 357 mx3_cam->active = NULL;
352 358
353 spin_unlock_irqrestore(&mx3_cam->lock, flags); 359 spin_unlock_irqrestore(&mx3_cam->lock, flags);
360error:
354 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR); 361 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
355} 362}
356 363
@@ -384,17 +391,24 @@ static void mx3_videobuf_release(struct vb2_buffer *vb)
384 } 391 }
385 392
386 spin_unlock_irqrestore(&mx3_cam->lock, flags); 393 spin_unlock_irqrestore(&mx3_cam->lock, flags);
394
395 mx3_cam->buf_total -= vb2_plane_size(vb, 0);
387} 396}
388 397
389static int mx3_videobuf_init(struct vb2_buffer *vb) 398static int mx3_videobuf_init(struct vb2_buffer *vb)
390{ 399{
400 struct soc_camera_device *icd = soc_camera_from_vb2q(vb->vb2_queue);
401 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
402 struct mx3_camera_dev *mx3_cam = ici->priv;
391 struct mx3_camera_buffer *buf = to_mx3_vb(vb); 403 struct mx3_camera_buffer *buf = to_mx3_vb(vb);
404
392 /* This is for locking debugging only */ 405 /* This is for locking debugging only */
393 INIT_LIST_HEAD(&buf->queue); 406 INIT_LIST_HEAD(&buf->queue);
394 sg_init_table(&buf->sg, 1); 407 sg_init_table(&buf->sg, 1);
395 408
396 buf->state = CSI_BUF_NEEDS_INIT; 409 buf->state = CSI_BUF_NEEDS_INIT;
397 buf->txd = NULL; 410
411 mx3_cam->buf_total += vb2_plane_size(vb, 0);
398 412
399 return 0; 413 return 0;
400} 414}
@@ -405,13 +419,12 @@ static int mx3_stop_streaming(struct vb2_queue *q)
405 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 419 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
406 struct mx3_camera_dev *mx3_cam = ici->priv; 420 struct mx3_camera_dev *mx3_cam = ici->priv;
407 struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; 421 struct idmac_channel *ichan = mx3_cam->idmac_channel[0];
408 struct dma_chan *chan;
409 struct mx3_camera_buffer *buf, *tmp; 422 struct mx3_camera_buffer *buf, *tmp;
410 unsigned long flags; 423 unsigned long flags;
411 424
412 if (ichan) { 425 if (ichan) {
413 chan = &ichan->dma_chan; 426 struct dma_chan *chan = &ichan->dma_chan;
414 chan->device->device_control(chan, DMA_TERMINATE_ALL, 0); 427 chan->device->device_control(chan, DMA_PAUSE, 0);
415 } 428 }
416 429
417 spin_lock_irqsave(&mx3_cam->lock, flags); 430 spin_lock_irqsave(&mx3_cam->lock, flags);
@@ -419,8 +432,8 @@ static int mx3_stop_streaming(struct vb2_queue *q)
419 mx3_cam->active = NULL; 432 mx3_cam->active = NULL;
420 433
421 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) { 434 list_for_each_entry_safe(buf, tmp, &mx3_cam->capture, queue) {
422 buf->state = CSI_BUF_NEEDS_INIT;
423 list_del_init(&buf->queue); 435 list_del_init(&buf->queue);
436 vb2_buffer_done(&buf->vb, VB2_BUF_STATE_ERROR);
424 } 437 }
425 438
426 spin_unlock_irqrestore(&mx3_cam->lock, flags); 439 spin_unlock_irqrestore(&mx3_cam->lock, flags);
@@ -430,7 +443,6 @@ static int mx3_stop_streaming(struct vb2_queue *q)
430 443
431static struct vb2_ops mx3_videobuf_ops = { 444static struct vb2_ops mx3_videobuf_ops = {
432 .queue_setup = mx3_videobuf_setup, 445 .queue_setup = mx3_videobuf_setup,
433 .buf_prepare = mx3_videobuf_prepare,
434 .buf_queue = mx3_videobuf_queue, 446 .buf_queue = mx3_videobuf_queue,
435 .buf_cleanup = mx3_videobuf_release, 447 .buf_cleanup = mx3_videobuf_release,
436 .buf_init = mx3_videobuf_init, 448 .buf_init = mx3_videobuf_init,
@@ -514,6 +526,7 @@ static int mx3_camera_add_device(struct soc_camera_device *icd)
514 526
515 mx3_camera_activate(mx3_cam, icd); 527 mx3_camera_activate(mx3_cam, icd);
516 528
529 mx3_cam->buf_total = 0;
517 mx3_cam->icd = icd; 530 mx3_cam->icd = icd;
518 531
519 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n", 532 dev_info(icd->parent, "MX3 Camera driver attached to camera %d\n",
@@ -548,58 +561,27 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
548 unsigned char buswidth, unsigned long *flags) 561 unsigned char buswidth, unsigned long *flags)
549{ 562{
550 /* 563 /*
564 * If requested data width is supported by the platform, use it or any
565 * possible lower value - i.MX31 is smart enough to shift bits
566 */
567 if (buswidth > fls(mx3_cam->width_flags))
568 return -EINVAL;
569
570 /*
551 * Platform specified synchronization and pixel clock polarities are 571 * Platform specified synchronization and pixel clock polarities are
552 * only a recommendation and are only used during probing. MX3x 572 * only a recommendation and are only used during probing. MX3x
553 * camera interface only works in master mode, i.e., uses HSYNC and 573 * camera interface only works in master mode, i.e., uses HSYNC and
554 * VSYNC signals from the sensor 574 * VSYNC signals from the sensor
555 */ 575 */
556 *flags = SOCAM_MASTER | 576 *flags = V4L2_MBUS_MASTER |
557 SOCAM_HSYNC_ACTIVE_HIGH | 577 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
558 SOCAM_HSYNC_ACTIVE_LOW | 578 V4L2_MBUS_HSYNC_ACTIVE_LOW |
559 SOCAM_VSYNC_ACTIVE_HIGH | 579 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
560 SOCAM_VSYNC_ACTIVE_LOW | 580 V4L2_MBUS_VSYNC_ACTIVE_LOW |
561 SOCAM_PCLK_SAMPLE_RISING | 581 V4L2_MBUS_PCLK_SAMPLE_RISING |
562 SOCAM_PCLK_SAMPLE_FALLING | 582 V4L2_MBUS_PCLK_SAMPLE_FALLING |
563 SOCAM_DATA_ACTIVE_HIGH | 583 V4L2_MBUS_DATA_ACTIVE_HIGH |
564 SOCAM_DATA_ACTIVE_LOW; 584 V4L2_MBUS_DATA_ACTIVE_LOW;
565
566 /*
567 * If requested data width is supported by the platform, use it or any
568 * possible lower value - i.MX31 is smart enough to schift bits
569 */
570 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
571 *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 |
572 SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
573 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
574 *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 |
575 SOCAM_DATAWIDTH_4;
576 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
577 *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4;
578 else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
579 *flags |= SOCAM_DATAWIDTH_4;
580
581 switch (buswidth) {
582 case 15:
583 if (!(*flags & SOCAM_DATAWIDTH_15))
584 return -EINVAL;
585 break;
586 case 10:
587 if (!(*flags & SOCAM_DATAWIDTH_10))
588 return -EINVAL;
589 break;
590 case 8:
591 if (!(*flags & SOCAM_DATAWIDTH_8))
592 return -EINVAL;
593 break;
594 case 4:
595 if (!(*flags & SOCAM_DATAWIDTH_4))
596 return -EINVAL;
597 break;
598 default:
599 dev_warn(mx3_cam->soc_host.v4l2_dev.dev,
600 "Unsupported bus width %d\n", buswidth);
601 return -EINVAL;
602 }
603 585
604 return 0; 586 return 0;
605} 587}
@@ -607,9 +589,11 @@ static int test_platform_param(struct mx3_camera_dev *mx3_cam,
607static int mx3_camera_try_bus_param(struct soc_camera_device *icd, 589static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
608 const unsigned int depth) 590 const unsigned int depth)
609{ 591{
592 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
610 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 593 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
611 struct mx3_camera_dev *mx3_cam = ici->priv; 594 struct mx3_camera_dev *mx3_cam = ici->priv;
612 unsigned long bus_flags, camera_flags; 595 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
596 unsigned long bus_flags, common_flags;
613 int ret = test_platform_param(mx3_cam, depth, &bus_flags); 597 int ret = test_platform_param(mx3_cam, depth, &bus_flags);
614 598
615 dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret); 599 dev_dbg(icd->parent, "request bus width %d bit: %d\n", depth, ret);
@@ -617,15 +601,21 @@ static int mx3_camera_try_bus_param(struct soc_camera_device *icd,
617 if (ret < 0) 601 if (ret < 0)
618 return ret; 602 return ret;
619 603
620 camera_flags = icd->ops->query_bus_param(icd); 604 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
621 605 if (!ret) {
622 ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); 606 common_flags = soc_mbus_config_compatible(&cfg,
623 if (ret < 0) 607 bus_flags);
624 dev_warn(icd->parent, 608 if (!common_flags) {
625 "Flags incompatible: camera %lx, host %lx\n", 609 dev_warn(icd->parent,
626 camera_flags, bus_flags); 610 "Flags incompatible: camera 0x%x, host 0x%lx\n",
611 cfg.flags, bus_flags);
612 return -EINVAL;
613 }
614 } else if (ret != -ENOIOCTLCMD) {
615 return ret;
616 }
627 617
628 return ret; 618 return 0;
629} 619}
630 620
631static bool chan_filter(struct dma_chan *chan, void *arg) 621static bool chan_filter(struct dma_chan *chan, void *arg)
@@ -994,9 +984,11 @@ static int mx3_camera_querycap(struct soc_camera_host *ici,
994 984
995static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 985static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
996{ 986{
987 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
997 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 988 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
998 struct mx3_camera_dev *mx3_cam = ici->priv; 989 struct mx3_camera_dev *mx3_cam = ici->priv;
999 unsigned long bus_flags, camera_flags, common_flags; 990 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
991 unsigned long bus_flags, common_flags;
1000 u32 dw, sens_conf; 992 u32 dw, sens_conf;
1001 const struct soc_mbus_pixelfmt *fmt; 993 const struct soc_mbus_pixelfmt *fmt;
1002 int buswidth; 994 int buswidth;
@@ -1008,83 +1000,76 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1008 if (!fmt) 1000 if (!fmt)
1009 return -EINVAL; 1001 return -EINVAL;
1010 1002
1011 buswidth = fmt->bits_per_sample;
1012 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1013
1014 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); 1003 xlate = soc_camera_xlate_by_fourcc(icd, pixfmt);
1015 if (!xlate) { 1004 if (!xlate) {
1016 dev_warn(dev, "Format %x not found\n", pixfmt); 1005 dev_warn(dev, "Format %x not found\n", pixfmt);
1017 return -EINVAL; 1006 return -EINVAL;
1018 } 1007 }
1019 1008
1009 buswidth = fmt->bits_per_sample;
1010 ret = test_platform_param(mx3_cam, buswidth, &bus_flags);
1011
1020 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret); 1012 dev_dbg(dev, "requested bus width %d bit: %d\n", buswidth, ret);
1021 1013
1022 if (ret < 0) 1014 if (ret < 0)
1023 return ret; 1015 return ret;
1024 1016
1025 camera_flags = icd->ops->query_bus_param(icd); 1017 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1026 1018 if (!ret) {
1027 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 1019 common_flags = soc_mbus_config_compatible(&cfg,
1028 dev_dbg(dev, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n", 1020 bus_flags);
1029 camera_flags, bus_flags, common_flags); 1021 if (!common_flags) {
1030 if (!common_flags) { 1022 dev_warn(icd->parent,
1031 dev_dbg(dev, "no common flags"); 1023 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1032 return -EINVAL; 1024 cfg.flags, bus_flags);
1025 return -EINVAL;
1026 }
1027 } else if (ret != -ENOIOCTLCMD) {
1028 return ret;
1029 } else {
1030 common_flags = bus_flags;
1033 } 1031 }
1034 1032
1033 dev_dbg(dev, "Flags cam: 0x%x host: 0x%lx common: 0x%lx\n",
1034 cfg.flags, bus_flags, common_flags);
1035
1035 /* Make choices, based on platform preferences */ 1036 /* Make choices, based on platform preferences */
1036 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 1037 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1037 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 1038 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1038 if (mx3_cam->platform_flags & MX3_CAMERA_HSP) 1039 if (mx3_cam->platform_flags & MX3_CAMERA_HSP)
1039 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 1040 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1040 else 1041 else
1041 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 1042 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1042 } 1043 }
1043 1044
1044 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 1045 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1045 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 1046 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1046 if (mx3_cam->platform_flags & MX3_CAMERA_VSP) 1047 if (mx3_cam->platform_flags & MX3_CAMERA_VSP)
1047 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 1048 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1048 else 1049 else
1049 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 1050 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1050 } 1051 }
1051 1052
1052 if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && 1053 if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
1053 (common_flags & SOCAM_DATA_ACTIVE_LOW)) { 1054 (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
1054 if (mx3_cam->platform_flags & MX3_CAMERA_DP) 1055 if (mx3_cam->platform_flags & MX3_CAMERA_DP)
1055 common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; 1056 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
1056 else 1057 else
1057 common_flags &= ~SOCAM_DATA_ACTIVE_LOW; 1058 common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
1058 } 1059 }
1059 1060
1060 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1061 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1061 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1062 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1062 if (mx3_cam->platform_flags & MX3_CAMERA_PCP) 1063 if (mx3_cam->platform_flags & MX3_CAMERA_PCP)
1063 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1064 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1064 else 1065 else
1065 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1066 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1066 } 1067 }
1067 1068
1068 /* 1069 cfg.flags = common_flags;
1069 * Make the camera work in widest common mode, we'll take care of 1070 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1070 * the rest 1071 if (ret < 0 && ret != -ENOIOCTLCMD) {
1071 */ 1072 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1072 if (common_flags & SOCAM_DATAWIDTH_15)
1073 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1074 SOCAM_DATAWIDTH_15;
1075 else if (common_flags & SOCAM_DATAWIDTH_10)
1076 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1077 SOCAM_DATAWIDTH_10;
1078 else if (common_flags & SOCAM_DATAWIDTH_8)
1079 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1080 SOCAM_DATAWIDTH_8;
1081 else
1082 common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) |
1083 SOCAM_DATAWIDTH_4;
1084
1085 ret = icd->ops->set_bus_param(icd, common_flags);
1086 if (ret < 0) {
1087 dev_dbg(dev, "camera set_bus_param(%lx) returned %d\n",
1088 common_flags, ret); 1073 common_flags, ret);
1089 return ret; 1074 return ret;
1090 } 1075 }
@@ -1108,13 +1093,13 @@ static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1108 /* This has been set in mx3_camera_activate(), but we clear it above */ 1093 /* This has been set in mx3_camera_activate(), but we clear it above */
1109 sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER; 1094 sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER;
1110 1095
1111 if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) 1096 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1112 sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; 1097 sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT;
1113 if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) 1098 if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1114 sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; 1099 sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT;
1115 if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) 1100 if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1116 sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; 1101 sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT;
1117 if (common_flags & SOCAM_DATA_ACTIVE_LOW) 1102 if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
1118 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; 1103 sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT;
1119 1104
1120 /* Just do what we're asked to do */ 1105 /* Just do what we're asked to do */
@@ -1199,6 +1184,14 @@ static int __devinit mx3_camera_probe(struct platform_device *pdev)
1199 "data widths, using default 8 bit\n"); 1184 "data widths, using default 8 bit\n");
1200 mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; 1185 mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8;
1201 } 1186 }
1187 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)
1188 mx3_cam->width_flags = 1 << 3;
1189 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)
1190 mx3_cam->width_flags |= 1 << 7;
1191 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)
1192 mx3_cam->width_flags |= 1 << 9;
1193 if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)
1194 mx3_cam->width_flags |= 1 << 14;
1202 1195
1203 mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; 1196 mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000;
1204 if (!mx3_cam->mclk) { 1197 if (!mx3_cam->mclk) {
@@ -1281,8 +1274,6 @@ static int __devexit mx3_camera_remove(struct platform_device *pdev)
1281 1274
1282 dmaengine_put(); 1275 dmaengine_put();
1283 1276
1284 dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n");
1285
1286 return 0; 1277 return 0;
1287} 1278}
1288 1279
diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 30d8896bb71..9c5c19f142d 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -833,6 +833,15 @@ static void omap_vout_buffer_release(struct videobuf_queue *q,
833/* 833/*
834 * File operations 834 * File operations
835 */ 835 */
836static unsigned int omap_vout_poll(struct file *file,
837 struct poll_table_struct *wait)
838{
839 struct omap_vout_device *vout = file->private_data;
840 struct videobuf_queue *q = &vout->vbq;
841
842 return videobuf_poll_stream(file, q, wait);
843}
844
836static void omap_vout_vm_open(struct vm_area_struct *vma) 845static void omap_vout_vm_open(struct vm_area_struct *vma)
837{ 846{
838 struct omap_vout_device *vout = vma->vm_private_data; 847 struct omap_vout_device *vout = vma->vm_private_data;
@@ -1861,6 +1870,7 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = {
1861 1870
1862static const struct v4l2_file_operations omap_vout_fops = { 1871static const struct v4l2_file_operations omap_vout_fops = {
1863 .owner = THIS_MODULE, 1872 .owner = THIS_MODULE,
1873 .poll = omap_vout_poll,
1864 .unlocked_ioctl = video_ioctl2, 1874 .unlocked_ioctl = video_ioctl2,
1865 .mmap = omap_vout_mmap, 1875 .mmap = omap_vout_mmap,
1866 .open = omap_vout_open, 1876 .open = omap_vout_open,
diff --git a/drivers/media/video/omap1_camera.c b/drivers/media/video/omap1_camera.c
index 8a947e603ac..e87ae2f634b 100644
--- a/drivers/media/video/omap1_camera.c
+++ b/drivers/media/video/omap1_camera.c
@@ -102,10 +102,10 @@
102/* end of OMAP1 Camera Interface registers */ 102/* end of OMAP1 Camera Interface registers */
103 103
104 104
105#define SOCAM_BUS_FLAGS (SOCAM_MASTER | \ 105#define SOCAM_BUS_FLAGS (V4L2_MBUS_MASTER | \
106 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | \ 106 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
107 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \ 107 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
108 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8) 108 V4L2_MBUS_DATA_ACTIVE_HIGH)
109 109
110 110
111#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1) 111#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
@@ -1438,41 +1438,55 @@ static int omap1_cam_querycap(struct soc_camera_host *ici,
1438static int omap1_cam_set_bus_param(struct soc_camera_device *icd, 1438static int omap1_cam_set_bus_param(struct soc_camera_device *icd,
1439 __u32 pixfmt) 1439 __u32 pixfmt)
1440{ 1440{
1441 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1441 struct device *dev = icd->parent; 1442 struct device *dev = icd->parent;
1442 struct soc_camera_host *ici = to_soc_camera_host(dev); 1443 struct soc_camera_host *ici = to_soc_camera_host(dev);
1443 struct omap1_cam_dev *pcdev = ici->priv; 1444 struct omap1_cam_dev *pcdev = ici->priv;
1444 const struct soc_camera_format_xlate *xlate; 1445 const struct soc_camera_format_xlate *xlate;
1445 const struct soc_mbus_pixelfmt *fmt; 1446 const struct soc_mbus_pixelfmt *fmt;
1446 unsigned long camera_flags, common_flags; 1447 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1448 unsigned long common_flags;
1447 u32 ctrlclock, mode; 1449 u32 ctrlclock, mode;
1448 int ret; 1450 int ret;
1449 1451
1450 camera_flags = icd->ops->query_bus_param(icd); 1452 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1451 1453 if (!ret) {
1452 common_flags = soc_camera_bus_param_compatible(camera_flags, 1454 common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
1453 SOCAM_BUS_FLAGS); 1455 if (!common_flags) {
1454 if (!common_flags) 1456 dev_warn(dev,
1455 return -EINVAL; 1457 "Flags incompatible: camera 0x%x, host 0x%x\n",
1458 cfg.flags, SOCAM_BUS_FLAGS);
1459 return -EINVAL;
1460 }
1461 } else if (ret != -ENOIOCTLCMD) {
1462 return ret;
1463 } else {
1464 common_flags = SOCAM_BUS_FLAGS;
1465 }
1456 1466
1457 /* Make choices, possibly based on platform configuration */ 1467 /* Make choices, possibly based on platform configuration */
1458 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1468 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1459 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1469 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1460 if (!pcdev->pdata || 1470 if (!pcdev->pdata ||
1461 pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING) 1471 pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
1462 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1472 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1463 else 1473 else
1464 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1474 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1465 } 1475 }
1466 1476
1467 ret = icd->ops->set_bus_param(icd, common_flags); 1477 cfg.flags = common_flags;
1468 if (ret < 0) 1478 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1479 if (ret < 0 && ret != -ENOIOCTLCMD) {
1480 dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
1481 common_flags, ret);
1469 return ret; 1482 return ret;
1483 }
1470 1484
1471 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK); 1485 ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
1472 if (ctrlclock & LCLK_EN) 1486 if (ctrlclock & LCLK_EN)
1473 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN); 1487 CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
1474 1488
1475 if (common_flags & SOCAM_PCLK_SAMPLE_RISING) { 1489 if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
1476 dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n"); 1490 dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
1477 ctrlclock |= POLCLK; 1491 ctrlclock |= POLCLK;
1478 } else { 1492 } else {
@@ -1565,10 +1579,10 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
1565 pcdev->clk = clk; 1579 pcdev->clk = clk;
1566 1580
1567 pcdev->pdata = pdev->dev.platform_data; 1581 pcdev->pdata = pdev->dev.platform_data;
1568 pcdev->pflags = pcdev->pdata->flags; 1582 if (pcdev->pdata) {
1569 1583 pcdev->pflags = pcdev->pdata->flags;
1570 if (pcdev->pdata)
1571 pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000; 1584 pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
1585 }
1572 1586
1573 switch (pcdev->camexclk) { 1587 switch (pcdev->camexclk) {
1574 case 6000000: 1588 case 6000000:
@@ -1578,6 +1592,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
1578 case 24000000: 1592 case 24000000:
1579 break; 1593 break;
1580 default: 1594 default:
1595 /* pcdev->camexclk != 0 => pcdev->pdata != NULL */
1581 dev_warn(&pdev->dev, 1596 dev_warn(&pdev->dev,
1582 "Incorrect sensor clock frequency %ld kHz, " 1597 "Incorrect sensor clock frequency %ld kHz, "
1583 "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, " 1598 "should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
@@ -1585,8 +1600,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
1585 pcdev->pdata->camexclk_khz); 1600 pcdev->pdata->camexclk_khz);
1586 pcdev->camexclk = 0; 1601 pcdev->camexclk = 0;
1587 case 0: 1602 case 0:
1588 dev_info(&pdev->dev, 1603 dev_info(&pdev->dev, "Not providing sensor clock\n");
1589 "Not providing sensor clock\n");
1590 } 1604 }
1591 1605
1592 INIT_LIST_HEAD(&pcdev->capture); 1606 INIT_LIST_HEAD(&pcdev->capture);
@@ -1716,5 +1730,5 @@ MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
1716MODULE_DESCRIPTION("OMAP1 Camera Interface driver"); 1730MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
1717MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>"); 1731MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
1718MODULE_LICENSE("GPL v2"); 1732MODULE_LICENSE("GPL v2");
1719MODULE_LICENSE(DRIVER_VERSION); 1733MODULE_VERSION(DRIVER_VERSION);
1720MODULE_ALIAS("platform:" DRIVER_NAME); 1734MODULE_ALIAS("platform:" DRIVER_NAME);
diff --git a/drivers/media/video/omap3isp/isp.c b/drivers/media/video/omap3isp/isp.c
index 678e1252047..b818cacf420 100644
--- a/drivers/media/video/omap3isp/isp.c
+++ b/drivers/media/video/omap3isp/isp.c
@@ -1704,6 +1704,7 @@ static int isp_register_entities(struct isp_device *isp)
1704 isp->media_dev.dev = isp->dev; 1704 isp->media_dev.dev = isp->dev;
1705 strlcpy(isp->media_dev.model, "TI OMAP3 ISP", 1705 strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
1706 sizeof(isp->media_dev.model)); 1706 sizeof(isp->media_dev.model));
1707 isp->media_dev.hw_revision = isp->revision;
1707 isp->media_dev.link_notify = isp_pipeline_link_notify; 1708 isp->media_dev.link_notify = isp_pipeline_link_notify;
1708 ret = media_device_register(&isp->media_dev); 1709 ret = media_device_register(&isp->media_dev);
1709 if (ret < 0) { 1710 if (ret < 0) {
@@ -2210,6 +2211,8 @@ error:
2210 regulator_put(isp->isp_csiphy2.vdd); 2211 regulator_put(isp->isp_csiphy2.vdd);
2211 regulator_put(isp->isp_csiphy1.vdd); 2212 regulator_put(isp->isp_csiphy1.vdd);
2212 platform_set_drvdata(pdev, NULL); 2213 platform_set_drvdata(pdev, NULL);
2214
2215 mutex_destroy(&isp->isp_mutex);
2213 kfree(isp); 2216 kfree(isp);
2214 2217
2215 return ret; 2218 return ret;
diff --git a/drivers/media/video/omap3isp/ispccdc.c b/drivers/media/video/omap3isp/ispccdc.c
index 253fdcce2df..b0b0fa5a357 100644
--- a/drivers/media/video/omap3isp/ispccdc.c
+++ b/drivers/media/video/omap3isp/ispccdc.c
@@ -1836,7 +1836,7 @@ ccdc_try_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
1836 * callers to request an output size bigger than the input size 1836 * callers to request an output size bigger than the input size
1837 * up to the nearest multiple of 16. 1837 * up to the nearest multiple of 16.
1838 */ 1838 */
1839 fmt->width = clamp_t(u32, width, 32, (fmt->width + 15) & ~15); 1839 fmt->width = clamp_t(u32, width, 32, fmt->width + 15);
1840 fmt->width &= ~15; 1840 fmt->width &= ~15;
1841 fmt->height = clamp_t(u32, height, 32, fmt->height); 1841 fmt->height = clamp_t(u32, height, 32, fmt->height);
1842 break; 1842 break;
@@ -2152,6 +2152,37 @@ static const struct media_entity_operations ccdc_media_ops = {
2152 .link_setup = ccdc_link_setup, 2152 .link_setup = ccdc_link_setup,
2153}; 2153};
2154 2154
2155void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2156{
2157 v4l2_device_unregister_subdev(&ccdc->subdev);
2158 omap3isp_video_unregister(&ccdc->video_out);
2159}
2160
2161int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2162 struct v4l2_device *vdev)
2163{
2164 int ret;
2165
2166 /* Register the subdev and video node. */
2167 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2168 if (ret < 0)
2169 goto error;
2170
2171 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2172 if (ret < 0)
2173 goto error;
2174
2175 return 0;
2176
2177error:
2178 omap3isp_ccdc_unregister_entities(ccdc);
2179 return ret;
2180}
2181
2182/* -----------------------------------------------------------------------------
2183 * ISP CCDC initialisation and cleanup
2184 */
2185
2155/* 2186/*
2156 * ccdc_init_entities - Initialize V4L2 subdev and media entity 2187 * ccdc_init_entities - Initialize V4L2 subdev and media entity
2157 * @ccdc: ISP CCDC module 2188 * @ccdc: ISP CCDC module
@@ -2193,50 +2224,23 @@ static int ccdc_init_entities(struct isp_ccdc_device *ccdc)
2193 2224
2194 ret = omap3isp_video_init(&ccdc->video_out, "CCDC"); 2225 ret = omap3isp_video_init(&ccdc->video_out, "CCDC");
2195 if (ret < 0) 2226 if (ret < 0)
2196 return ret; 2227 goto error_video;
2197 2228
2198 /* Connect the CCDC subdev to the video node. */ 2229 /* Connect the CCDC subdev to the video node. */
2199 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF, 2230 ret = media_entity_create_link(&ccdc->subdev.entity, CCDC_PAD_SOURCE_OF,
2200 &ccdc->video_out.video.entity, 0, 0); 2231 &ccdc->video_out.video.entity, 0, 0);
2201 if (ret < 0) 2232 if (ret < 0)
2202 return ret; 2233 goto error_link;
2203
2204 return 0;
2205}
2206
2207void omap3isp_ccdc_unregister_entities(struct isp_ccdc_device *ccdc)
2208{
2209 media_entity_cleanup(&ccdc->subdev.entity);
2210
2211 v4l2_device_unregister_subdev(&ccdc->subdev);
2212 omap3isp_video_unregister(&ccdc->video_out);
2213}
2214
2215int omap3isp_ccdc_register_entities(struct isp_ccdc_device *ccdc,
2216 struct v4l2_device *vdev)
2217{
2218 int ret;
2219
2220 /* Register the subdev and video node. */
2221 ret = v4l2_device_register_subdev(vdev, &ccdc->subdev);
2222 if (ret < 0)
2223 goto error;
2224
2225 ret = omap3isp_video_register(&ccdc->video_out, vdev);
2226 if (ret < 0)
2227 goto error;
2228 2234
2229 return 0; 2235 return 0;
2230 2236
2231error: 2237error_link:
2232 omap3isp_ccdc_unregister_entities(ccdc); 2238 omap3isp_video_cleanup(&ccdc->video_out);
2239error_video:
2240 media_entity_cleanup(me);
2233 return ret; 2241 return ret;
2234} 2242}
2235 2243
2236/* -----------------------------------------------------------------------------
2237 * ISP CCDC initialisation and cleanup
2238 */
2239
2240/* 2244/*
2241 * omap3isp_ccdc_init - CCDC module initialization. 2245 * omap3isp_ccdc_init - CCDC module initialization.
2242 * @dev: Device pointer specific to the OMAP3 ISP. 2246 * @dev: Device pointer specific to the OMAP3 ISP.
@@ -2248,6 +2252,7 @@ error:
2248int omap3isp_ccdc_init(struct isp_device *isp) 2252int omap3isp_ccdc_init(struct isp_device *isp)
2249{ 2253{
2250 struct isp_ccdc_device *ccdc = &isp->isp_ccdc; 2254 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2255 int ret;
2251 2256
2252 spin_lock_init(&ccdc->lock); 2257 spin_lock_init(&ccdc->lock);
2253 init_waitqueue_head(&ccdc->wait); 2258 init_waitqueue_head(&ccdc->wait);
@@ -2276,7 +2281,13 @@ int omap3isp_ccdc_init(struct isp_device *isp)
2276 ccdc->update = OMAP3ISP_CCDC_BLCLAMP; 2281 ccdc->update = OMAP3ISP_CCDC_BLCLAMP;
2277 ccdc_apply_controls(ccdc); 2282 ccdc_apply_controls(ccdc);
2278 2283
2279 return ccdc_init_entities(ccdc); 2284 ret = ccdc_init_entities(ccdc);
2285 if (ret < 0) {
2286 mutex_destroy(&ccdc->ioctl_lock);
2287 return ret;
2288 }
2289
2290 return 0;
2280} 2291}
2281 2292
2282/* 2293/*
@@ -2287,6 +2298,9 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
2287{ 2298{
2288 struct isp_ccdc_device *ccdc = &isp->isp_ccdc; 2299 struct isp_ccdc_device *ccdc = &isp->isp_ccdc;
2289 2300
2301 omap3isp_video_cleanup(&ccdc->video_out);
2302 media_entity_cleanup(&ccdc->subdev.entity);
2303
2290 /* Free LSC requests. As the CCDC is stopped there's no active request, 2304 /* Free LSC requests. As the CCDC is stopped there's no active request,
2291 * so only the pending request and the free queue need to be handled. 2305 * so only the pending request and the free queue need to be handled.
2292 */ 2306 */
@@ -2296,4 +2310,6 @@ void omap3isp_ccdc_cleanup(struct isp_device *isp)
2296 2310
2297 if (ccdc->fpc.fpcaddr != 0) 2311 if (ccdc->fpc.fpcaddr != 0)
2298 omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr); 2312 omap_iommu_vfree(isp->domain, isp->iommu, ccdc->fpc.fpcaddr);
2313
2314 mutex_destroy(&ccdc->ioctl_lock);
2299} 2315}
diff --git a/drivers/media/video/omap3isp/ispccp2.c b/drivers/media/video/omap3isp/ispccp2.c
index fa1d09b0ad9..904ca8c8b17 100644
--- a/drivers/media/video/omap3isp/ispccp2.c
+++ b/drivers/media/video/omap3isp/ispccp2.c
@@ -1032,6 +1032,48 @@ static const struct media_entity_operations ccp2_media_ops = {
1032}; 1032};
1033 1033
1034/* 1034/*
1035 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev
1036 * @ccp2: Pointer to ISP CCP2 device
1037 */
1038void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1039{
1040 v4l2_device_unregister_subdev(&ccp2->subdev);
1041 omap3isp_video_unregister(&ccp2->video_in);
1042}
1043
1044/*
1045 * omap3isp_ccp2_register_entities - Register the subdev media entity
1046 * @ccp2: Pointer to ISP CCP2 device
1047 * @vdev: Pointer to v4l device
1048 * return negative error code or zero on success
1049 */
1050
1051int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1052 struct v4l2_device *vdev)
1053{
1054 int ret;
1055
1056 /* Register the subdev and video nodes. */
1057 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1058 if (ret < 0)
1059 goto error;
1060
1061 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1062 if (ret < 0)
1063 goto error;
1064
1065 return 0;
1066
1067error:
1068 omap3isp_ccp2_unregister_entities(ccp2);
1069 return ret;
1070}
1071
1072/* -----------------------------------------------------------------------------
1073 * ISP ccp2 initialisation and cleanup
1074 */
1075
1076/*
1035 * ccp2_init_entities - Initialize ccp2 subdev and media entity. 1077 * ccp2_init_entities - Initialize ccp2 subdev and media entity.
1036 * @ccp2: Pointer to ISP CCP2 device 1078 * @ccp2: Pointer to ISP CCP2 device
1037 * return negative error code or zero on success 1079 * return negative error code or zero on success
@@ -1083,72 +1125,23 @@ static int ccp2_init_entities(struct isp_ccp2_device *ccp2)
1083 1125
1084 ret = omap3isp_video_init(&ccp2->video_in, "CCP2"); 1126 ret = omap3isp_video_init(&ccp2->video_in, "CCP2");
1085 if (ret < 0) 1127 if (ret < 0)
1086 return ret; 1128 goto error_video;
1087 1129
1088 /* Connect the video node to the ccp2 subdev. */ 1130 /* Connect the video node to the ccp2 subdev. */
1089 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0, 1131 ret = media_entity_create_link(&ccp2->video_in.video.entity, 0,
1090 &ccp2->subdev.entity, CCP2_PAD_SINK, 0); 1132 &ccp2->subdev.entity, CCP2_PAD_SINK, 0);
1091 if (ret < 0) 1133 if (ret < 0)
1092 return ret; 1134 goto error_link;
1093 1135
1094 return 0; 1136 return 0;
1095}
1096 1137
1097/* 1138error_link:
1098 * omap3isp_ccp2_unregister_entities - Unregister media entities: subdev 1139 omap3isp_video_cleanup(&ccp2->video_in);
1099 * @ccp2: Pointer to ISP CCP2 device 1140error_video:
1100 */
1101void omap3isp_ccp2_unregister_entities(struct isp_ccp2_device *ccp2)
1102{
1103 media_entity_cleanup(&ccp2->subdev.entity); 1141 media_entity_cleanup(&ccp2->subdev.entity);
1104
1105 v4l2_device_unregister_subdev(&ccp2->subdev);
1106 omap3isp_video_unregister(&ccp2->video_in);
1107}
1108
1109/*
1110 * omap3isp_ccp2_register_entities - Register the subdev media entity
1111 * @ccp2: Pointer to ISP CCP2 device
1112 * @vdev: Pointer to v4l device
1113 * return negative error code or zero on success
1114 */
1115
1116int omap3isp_ccp2_register_entities(struct isp_ccp2_device *ccp2,
1117 struct v4l2_device *vdev)
1118{
1119 int ret;
1120
1121 /* Register the subdev and video nodes. */
1122 ret = v4l2_device_register_subdev(vdev, &ccp2->subdev);
1123 if (ret < 0)
1124 goto error;
1125
1126 ret = omap3isp_video_register(&ccp2->video_in, vdev);
1127 if (ret < 0)
1128 goto error;
1129
1130 return 0;
1131
1132error:
1133 omap3isp_ccp2_unregister_entities(ccp2);
1134 return ret; 1142 return ret;
1135} 1143}
1136 1144
1137/* -----------------------------------------------------------------------------
1138 * ISP ccp2 initialisation and cleanup
1139 */
1140
1141/*
1142 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1143 * @isp : Pointer to ISP device
1144 */
1145void omap3isp_ccp2_cleanup(struct isp_device *isp)
1146{
1147 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1148
1149 regulator_put(ccp2->vdds_csib);
1150}
1151
1152/* 1145/*
1153 * omap3isp_ccp2_init - CCP2 initialization. 1146 * omap3isp_ccp2_init - CCP2 initialization.
1154 * @isp : Pointer to ISP device 1147 * @isp : Pointer to ISP device
@@ -1184,13 +1177,25 @@ int omap3isp_ccp2_init(struct isp_device *isp)
1184 } 1177 }
1185 1178
1186 ret = ccp2_init_entities(ccp2); 1179 ret = ccp2_init_entities(ccp2);
1187 if (ret < 0) 1180 if (ret < 0) {
1188 goto out; 1181 regulator_put(ccp2->vdds_csib);
1182 return ret;
1183 }
1189 1184
1190 ccp2_reset(ccp2); 1185 ccp2_reset(ccp2);
1191out: 1186 return 0;
1192 if (ret) 1187}
1193 omap3isp_ccp2_cleanup(isp);
1194 1188
1195 return ret; 1189/*
1190 * omap3isp_ccp2_cleanup - CCP2 un-initialization
1191 * @isp : Pointer to ISP device
1192 */
1193void omap3isp_ccp2_cleanup(struct isp_device *isp)
1194{
1195 struct isp_ccp2_device *ccp2 = &isp->isp_ccp2;
1196
1197 omap3isp_video_cleanup(&ccp2->video_in);
1198 media_entity_cleanup(&ccp2->subdev.entity);
1199
1200 regulator_put(ccp2->vdds_csib);
1196} 1201}
diff --git a/drivers/media/video/omap3isp/ispcsi2.c b/drivers/media/video/omap3isp/ispcsi2.c
index 69161a682b3..0c5f1cb9d99 100644
--- a/drivers/media/video/omap3isp/ispcsi2.c
+++ b/drivers/media/video/omap3isp/ispcsi2.c
@@ -1187,6 +1187,37 @@ static const struct media_entity_operations csi2_media_ops = {
1187 .link_setup = csi2_link_setup, 1187 .link_setup = csi2_link_setup,
1188}; 1188};
1189 1189
1190void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2)
1191{
1192 v4l2_device_unregister_subdev(&csi2->subdev);
1193 omap3isp_video_unregister(&csi2->video_out);
1194}
1195
1196int omap3isp_csi2_register_entities(struct isp_csi2_device *csi2,
1197 struct v4l2_device *vdev)
1198{
1199 int ret;
1200
1201 /* Register the subdev and video nodes. */
1202 ret = v4l2_device_register_subdev(vdev, &csi2->subdev);
1203 if (ret < 0)
1204 goto error;
1205
1206 ret = omap3isp_video_register(&csi2->video_out, vdev);
1207 if (ret < 0)
1208 goto error;
1209
1210 return 0;
1211
1212error:
1213 omap3isp_csi2_unregister_entities(csi2);
1214 return ret;
1215}
1216
1217/* -----------------------------------------------------------------------------
1218 * ISP CSI2 initialisation and cleanup
1219 */
1220
1190/* 1221/*
1191 * csi2_init_entities - Initialize subdev and media entity. 1222 * csi2_init_entities - Initialize subdev and media entity.
1192 * @csi2: Pointer to csi2 structure. 1223 * @csi2: Pointer to csi2 structure.
@@ -1228,57 +1259,23 @@ static int csi2_init_entities(struct isp_csi2_device *csi2)
1228 1259
1229 ret = omap3isp_video_init(&csi2->video_out, "CSI2a"); 1260 ret = omap3isp_video_init(&csi2->video_out, "CSI2a");
1230 if (ret < 0) 1261 if (ret < 0)
1231 return ret; 1262 goto error_video;
1232 1263
1233 /* Connect the CSI2 subdev to the video node. */ 1264 /* Connect the CSI2 subdev to the video node. */
1234 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE, 1265 ret = media_entity_create_link(&csi2->subdev.entity, CSI2_PAD_SOURCE,
1235 &csi2->video_out.video.entity, 0, 0); 1266 &csi2->video_out.video.entity, 0, 0);
1236 if (ret < 0) 1267 if (ret < 0)
1237 return ret; 1268 goto error_link;
1238 1269
1239 return 0; 1270 return 0;
1240}
1241 1271
1242void omap3isp_csi2_unregister_entities(struct isp_csi2_device *csi2) 1272error_link:
1243{ 1273 omap3isp_video_cleanup(&csi2->video_out);
1274error_video:
1244 media_entity_cleanup(&csi2->subdev.entity); 1275 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; 1276 return ret;
1269} 1277}
1270 1278
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/* 1279/*
1283 * omap3isp_csi2_init - Routine for module driver init 1280 * omap3isp_csi2_init - Routine for module driver init
1284 */ 1281 */
@@ -1298,7 +1295,7 @@ int omap3isp_csi2_init(struct isp_device *isp)
1298 1295
1299 ret = csi2_init_entities(csi2a); 1296 ret = csi2_init_entities(csi2a);
1300 if (ret < 0) 1297 if (ret < 0)
1301 goto fail; 1298 return ret;
1302 1299
1303 if (isp->revision == ISP_REVISION_15_0) { 1300 if (isp->revision == ISP_REVISION_15_0) {
1304 csi2c->isp = isp; 1301 csi2c->isp = isp;
@@ -1311,7 +1308,15 @@ int omap3isp_csi2_init(struct isp_device *isp)
1311 } 1308 }
1312 1309
1313 return 0; 1310 return 0;
1314fail: 1311}
1315 omap3isp_csi2_cleanup(isp); 1312
1316 return ret; 1313/*
1314 * omap3isp_csi2_cleanup - Routine for module driver cleanup
1315 */
1316void omap3isp_csi2_cleanup(struct isp_device *isp)
1317{
1318 struct isp_csi2_device *csi2a = &isp->isp_csi2a;
1319
1320 omap3isp_video_cleanup(&csi2a->video_out);
1321 media_entity_cleanup(&csi2a->subdev.entity);
1317} 1322}
diff --git a/drivers/media/video/omap3isp/isph3a_aewb.c b/drivers/media/video/omap3isp/isph3a_aewb.c
index 8068cefd8d8..a3c76bf1817 100644
--- a/drivers/media/video/omap3isp/isph3a_aewb.c
+++ b/drivers/media/video/omap3isp/isph3a_aewb.c
@@ -370,5 +370,5 @@ void omap3isp_h3a_aewb_cleanup(struct isp_device *isp)
370{ 370{
371 kfree(isp->isp_aewb.priv); 371 kfree(isp->isp_aewb.priv);
372 kfree(isp->isp_aewb.recover_priv); 372 kfree(isp->isp_aewb.recover_priv);
373 omap3isp_stat_free(&isp->isp_aewb); 373 omap3isp_stat_cleanup(&isp->isp_aewb);
374} 374}
diff --git a/drivers/media/video/omap3isp/isph3a_af.c b/drivers/media/video/omap3isp/isph3a_af.c
index ba54d0acdec..58e0bc41489 100644
--- a/drivers/media/video/omap3isp/isph3a_af.c
+++ b/drivers/media/video/omap3isp/isph3a_af.c
@@ -425,5 +425,5 @@ void omap3isp_h3a_af_cleanup(struct isp_device *isp)
425{ 425{
426 kfree(isp->isp_af.priv); 426 kfree(isp->isp_af.priv);
427 kfree(isp->isp_af.recover_priv); 427 kfree(isp->isp_af.recover_priv);
428 omap3isp_stat_free(&isp->isp_af); 428 omap3isp_stat_cleanup(&isp->isp_af);
429} 429}
diff --git a/drivers/media/video/omap3isp/isphist.c b/drivers/media/video/omap3isp/isphist.c
index 1743856b30d..1163907bcdd 100644
--- a/drivers/media/video/omap3isp/isphist.c
+++ b/drivers/media/video/omap3isp/isphist.c
@@ -516,5 +516,5 @@ void omap3isp_hist_cleanup(struct isp_device *isp)
516 if (HIST_USING_DMA(&isp->isp_hist)) 516 if (HIST_USING_DMA(&isp->isp_hist))
517 omap_free_dma(isp->isp_hist.dma_ch); 517 omap_free_dma(isp->isp_hist.dma_ch);
518 kfree(isp->isp_hist.priv); 518 kfree(isp->isp_hist.priv);
519 omap3isp_stat_free(&isp->isp_hist); 519 omap3isp_stat_cleanup(&isp->isp_hist);
520} 520}
diff --git a/drivers/media/video/omap3isp/isppreview.c b/drivers/media/video/omap3isp/isppreview.c
index aba537af87e..ccb876fe023 100644
--- a/drivers/media/video/omap3isp/isppreview.c
+++ b/drivers/media/video/omap3isp/isppreview.c
@@ -76,9 +76,51 @@ static struct omap3isp_prev_csc flr_prev_csc = {
76 76
77#define DEF_DETECT_CORRECT_VAL 0xe 77#define DEF_DETECT_CORRECT_VAL 0xe
78 78
79#define PREV_MIN_WIDTH 64 79/*
80#define PREV_MIN_HEIGHT 8 80 * Margins and image size limits.
81#define PREV_MAX_HEIGHT 16384 81 *
82 * The preview engine crops several rows and columns internally depending on
83 * which filters are enabled. To avoid format changes when the filters are
84 * enabled or disabled (which would prevent them from being turned on or off
85 * during streaming), the driver assumes all the filters are enabled when
86 * computing sink crop and source format limits.
87 *
88 * If a filter is disabled, additional cropping is automatically added at the
89 * preview engine input by the driver to avoid overflow at line and frame end.
90 * This is completely transparent for applications.
91 *
92 * Median filter 4 pixels
93 * Noise filter,
94 * Faulty pixels correction 4 pixels, 4 lines
95 * CFA filter 4 pixels, 4 lines in Bayer mode
96 * 2 lines in other modes
97 * Color suppression 2 pixels
98 * or luma enhancement
99 * -------------------------------------------------------------
100 * Maximum total 14 pixels, 8 lines
101 *
102 * The color suppression and luma enhancement filters are applied after bayer to
103 * YUV conversion. They thus can crop one pixel on the left and one pixel on the
104 * right side of the image without changing the color pattern. When both those
105 * filters are disabled, the driver must crop the two pixels on the same side of
106 * the image to avoid changing the bayer pattern. The left margin is thus set to
107 * 8 pixels and the right margin to 6 pixels.
108 */
109
110#define PREV_MARGIN_LEFT 8
111#define PREV_MARGIN_RIGHT 6
112#define PREV_MARGIN_TOP 4
113#define PREV_MARGIN_BOTTOM 4
114
115#define PREV_MIN_IN_WIDTH 64
116#define PREV_MIN_IN_HEIGHT 8
117#define PREV_MAX_IN_HEIGHT 16384
118
119#define PREV_MIN_OUT_WIDTH 0
120#define PREV_MIN_OUT_HEIGHT 0
121#define PREV_MAX_OUT_WIDTH 1280
122#define PREV_MAX_OUT_WIDTH_ES2 3300
123#define PREV_MAX_OUT_WIDTH_3630 4096
82 124
83/* 125/*
84 * Coeficient Tables for the submodules in Preview. 126 * Coeficient Tables for the submodules in Preview.
@@ -979,52 +1021,36 @@ static void preview_config_averager(struct isp_prev_device *prev, u8 average)
979 * enabled when reporting source pad formats to userspace. If this assumption is 1021 * 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 1022 * 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. 1023 * input to avoid overflows at the end of lines and frames.
1024 *
1025 * See the explanation at the PREV_MARGIN_* definitions for more details.
982 */ 1026 */
983static void preview_config_input_size(struct isp_prev_device *prev) 1027static void preview_config_input_size(struct isp_prev_device *prev)
984{ 1028{
985 struct isp_device *isp = to_isp_device(prev); 1029 struct isp_device *isp = to_isp_device(prev);
986 struct prev_params *params = &prev->params; 1030 struct prev_params *params = &prev->params;
987 struct v4l2_mbus_framefmt *format = &prev->formats[PREV_PAD_SINK]; 1031 unsigned int sph = prev->crop.left;
988 unsigned int sph = 0; 1032 unsigned int eph = prev->crop.left + prev->crop.width - 1;
989 unsigned int eph = format->width - 1; 1033 unsigned int slv = prev->crop.top;
990 unsigned int slv = 0; 1034 unsigned int elv = prev->crop.top + prev->crop.height - 1;
991 unsigned int elv = format->height - 1; 1035
992 1036 if (params->features & PREV_CFA) {
993 if (prev->input == PREVIEW_INPUT_CCDC) { 1037 sph -= 2;
994 sph += 2; 1038 eph += 2;
995 eph -= 2; 1039 slv -= 2;
1040 elv += 2;
996 } 1041 }
997 1042 if (params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER)) {
998 /* 1043 sph -= 2;
999 * Median filter 4 pixels 1044 eph += 2;
1000 * Noise filter 4 pixels, 4 lines 1045 slv -= 2;
1001 * or faulty pixels correction 1046 elv += 2;
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 } 1047 }
1016 if (!(params->features & (PREV_DEFECT_COR | PREV_NOISE_FILTER))) { 1048 if (params->features & PREV_HORZ_MEDIAN_FILTER) {
1017 sph += 2; 1049 sph -= 2;
1018 eph -= 2; 1050 eph += 2;
1019 slv += 2;
1020 elv -= 2;
1021 } 1051 }
1022 if (!(params->features & PREV_HORZ_MEDIAN_FILTER)) { 1052 if (params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE))
1023 sph += 2; 1053 sph -= 2;
1024 eph -= 2;
1025 }
1026 if (!(params->features & (PREV_CHROMA_SUPPRESS | PREV_LUMA_ENHANCE)))
1027 sph += 2;
1028 1054
1029 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph, 1055 isp_reg_writel(isp, (sph << ISPPRV_HORZ_INFO_SPH_SHIFT) | eph,
1030 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO); 1056 OMAP3_ISP_IOMEM_PREV, ISPPRV_HORZ_INFO);
@@ -1228,7 +1254,6 @@ static void preview_init_params(struct isp_prev_device *prev)
1228 /* Init values */ 1254 /* Init values */
1229 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS; 1255 params->contrast = ISPPRV_CONTRAST_DEF * ISPPRV_CONTRAST_UNITS;
1230 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS; 1256 params->brightness = ISPPRV_BRIGHT_DEF * ISPPRV_BRIGHT_UNITS;
1231 params->average = NO_AVE;
1232 params->cfa.format = OMAP3ISP_CFAFMT_BAYER; 1257 params->cfa.format = OMAP3ISP_CFAFMT_BAYER;
1233 memcpy(params->cfa.table, cfa_coef_table, 1258 memcpy(params->cfa.table, cfa_coef_table,
1234 sizeof(params->cfa.table)); 1259 sizeof(params->cfa.table));
@@ -1281,14 +1306,14 @@ static unsigned int preview_max_out_width(struct isp_prev_device *prev)
1281 1306
1282 switch (isp->revision) { 1307 switch (isp->revision) {
1283 case ISP_REVISION_1_0: 1308 case ISP_REVISION_1_0:
1284 return ISPPRV_MAXOUTPUT_WIDTH; 1309 return PREV_MAX_OUT_WIDTH;
1285 1310
1286 case ISP_REVISION_2_0: 1311 case ISP_REVISION_2_0:
1287 default: 1312 default:
1288 return ISPPRV_MAXOUTPUT_WIDTH_ES2; 1313 return PREV_MAX_OUT_WIDTH_ES2;
1289 1314
1290 case ISP_REVISION_15_0: 1315 case ISP_REVISION_15_0:
1291 return ISPPRV_MAXOUTPUT_WIDTH_3630; 1316 return PREV_MAX_OUT_WIDTH_3630;
1292 } 1317 }
1293} 1318}
1294 1319
@@ -1296,8 +1321,6 @@ static void preview_configure(struct isp_prev_device *prev)
1296{ 1321{
1297 struct isp_device *isp = to_isp_device(prev); 1322 struct isp_device *isp = to_isp_device(prev);
1298 struct v4l2_mbus_framefmt *format; 1323 struct v4l2_mbus_framefmt *format;
1299 unsigned int max_out_width;
1300 unsigned int format_avg;
1301 1324
1302 preview_setup_hw(prev); 1325 preview_setup_hw(prev);
1303 1326
@@ -1335,10 +1358,7 @@ static void preview_configure(struct isp_prev_device *prev)
1335 preview_config_outlineoffset(prev, 1358 preview_config_outlineoffset(prev,
1336 ALIGN(format->width, 0x10) * 2); 1359 ALIGN(format->width, 0x10) * 2);
1337 1360
1338 max_out_width = preview_max_out_width(prev); 1361 preview_config_averager(prev, 0);
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); 1362 preview_config_ycpos(prev, format->code);
1343} 1363}
1344 1364
@@ -1597,6 +1617,16 @@ __preview_get_format(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1597 return &prev->formats[pad]; 1617 return &prev->formats[pad];
1598} 1618}
1599 1619
1620static struct v4l2_rect *
1621__preview_get_crop(struct isp_prev_device *prev, struct v4l2_subdev_fh *fh,
1622 enum v4l2_subdev_format_whence which)
1623{
1624 if (which == V4L2_SUBDEV_FORMAT_TRY)
1625 return v4l2_subdev_get_try_crop(fh, PREV_PAD_SINK);
1626 else
1627 return &prev->crop;
1628}
1629
1600/* previewer format descriptions */ 1630/* previewer format descriptions */
1601static const unsigned int preview_input_fmts[] = { 1631static const unsigned int preview_input_fmts[] = {
1602 V4L2_MBUS_FMT_SGRBG10_1X10, 1632 V4L2_MBUS_FMT_SGRBG10_1X10,
@@ -1611,24 +1641,25 @@ static const unsigned int preview_output_fmts[] = {
1611}; 1641};
1612 1642
1613/* 1643/*
1614 * preview_try_format - Handle try format by pad subdev method 1644 * preview_try_format - Validate a format
1615 * @prev: ISP preview device 1645 * @prev: ISP preview engine
1616 * @fh : V4L2 subdev file handle 1646 * @fh: V4L2 subdev file handle
1617 * @pad: pad num 1647 * @pad: pad number
1618 * @fmt: pointer to v4l2 format structure 1648 * @fmt: format to be validated
1649 * @which: try/active format selector
1650 *
1651 * Validate and adjust the given format for the given pad based on the preview
1652 * engine limits and the format and crop rectangles on other pads.
1619 */ 1653 */
1620static void preview_try_format(struct isp_prev_device *prev, 1654static void preview_try_format(struct isp_prev_device *prev,
1621 struct v4l2_subdev_fh *fh, unsigned int pad, 1655 struct v4l2_subdev_fh *fh, unsigned int pad,
1622 struct v4l2_mbus_framefmt *fmt, 1656 struct v4l2_mbus_framefmt *fmt,
1623 enum v4l2_subdev_format_whence which) 1657 enum v4l2_subdev_format_whence which)
1624{ 1658{
1625 struct v4l2_mbus_framefmt *format;
1626 unsigned int max_out_width;
1627 enum v4l2_mbus_pixelcode pixelcode; 1659 enum v4l2_mbus_pixelcode pixelcode;
1660 struct v4l2_rect *crop;
1628 unsigned int i; 1661 unsigned int i;
1629 1662
1630 max_out_width = preview_max_out_width(prev);
1631
1632 switch (pad) { 1663 switch (pad) {
1633 case PREV_PAD_SINK: 1664 case PREV_PAD_SINK:
1634 /* When reading data from the CCDC, the input size has already 1665 /* When reading data from the CCDC, the input size has already
@@ -1641,10 +1672,11 @@ static void preview_try_format(struct isp_prev_device *prev,
1641 * filter array interpolation. 1672 * filter array interpolation.
1642 */ 1673 */
1643 if (prev->input == PREVIEW_INPUT_MEMORY) { 1674 if (prev->input == PREVIEW_INPUT_MEMORY) {
1644 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_WIDTH, 1675 fmt->width = clamp_t(u32, fmt->width, PREV_MIN_IN_WIDTH,
1645 max_out_width * 8); 1676 preview_max_out_width(prev));
1646 fmt->height = clamp_t(u32, fmt->height, PREV_MIN_HEIGHT, 1677 fmt->height = clamp_t(u32, fmt->height,
1647 PREV_MAX_HEIGHT); 1678 PREV_MIN_IN_HEIGHT,
1679 PREV_MAX_IN_HEIGHT);
1648 } 1680 }
1649 1681
1650 fmt->colorspace = V4L2_COLORSPACE_SRGB; 1682 fmt->colorspace = V4L2_COLORSPACE_SRGB;
@@ -1661,15 +1693,8 @@ static void preview_try_format(struct isp_prev_device *prev,
1661 1693
1662 case PREV_PAD_SOURCE: 1694 case PREV_PAD_SOURCE:
1663 pixelcode = fmt->code; 1695 pixelcode = fmt->code;
1664 format = __preview_get_format(prev, fh, PREV_PAD_SINK, which); 1696 *fmt = *__preview_get_format(prev, fh, PREV_PAD_SINK, which);
1665 memcpy(fmt, format, sizeof(*fmt));
1666 1697
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) { 1698 switch (pixelcode) {
1674 case V4L2_MBUS_FMT_YUYV8_1X16: 1699 case V4L2_MBUS_FMT_YUYV8_1X16:
1675 case V4L2_MBUS_FMT_UYVY8_1X16: 1700 case V4L2_MBUS_FMT_UYVY8_1X16:
@@ -1681,31 +1706,14 @@ static void preview_try_format(struct isp_prev_device *prev,
1681 break; 1706 break;
1682 } 1707 }
1683 1708
1684 /* The TRM states (12.1.4.7.1.2) that 2 pixels must be cropped 1709 /* The preview module output size is configurable through the
1685 * from the left and right sides when the input source is the 1710 * averager (horizontal scaling by 1/1, 1/2, 1/4 or 1/8). This
1686 * CCDC. This seems not to be needed in practice, investigation 1711 * is not supported yet, hardcode the output size to the crop
1687 * is required. 1712 * rectangle size.
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 */ 1713 */
1707 fmt->width -= 14; 1714 crop = __preview_get_crop(prev, fh, which);
1708 fmt->height -= 8; 1715 fmt->width = crop->width;
1716 fmt->height = crop->height;
1709 1717
1710 fmt->colorspace = V4L2_COLORSPACE_JPEG; 1718 fmt->colorspace = V4L2_COLORSPACE_JPEG;
1711 break; 1719 break;
@@ -1715,6 +1723,49 @@ static void preview_try_format(struct isp_prev_device *prev,
1715} 1723}
1716 1724
1717/* 1725/*
1726 * preview_try_crop - Validate a crop rectangle
1727 * @prev: ISP preview engine
1728 * @sink: format on the sink pad
1729 * @crop: crop rectangle to be validated
1730 *
1731 * The preview engine crops lines and columns for its internal operation,
1732 * depending on which filters are enabled. Enforce minimum crop margins to
1733 * handle that transparently for userspace.
1734 *
1735 * See the explanation at the PREV_MARGIN_* definitions for more details.
1736 */
1737static void preview_try_crop(struct isp_prev_device *prev,
1738 const struct v4l2_mbus_framefmt *sink,
1739 struct v4l2_rect *crop)
1740{
1741 unsigned int left = PREV_MARGIN_LEFT;
1742 unsigned int right = sink->width - PREV_MARGIN_RIGHT;
1743 unsigned int top = PREV_MARGIN_TOP;
1744 unsigned int bottom = sink->height - PREV_MARGIN_BOTTOM;
1745
1746 /* When processing data on-the-fly from the CCDC, at least 2 pixels must
1747 * be cropped from the left and right sides of the image. As we don't
1748 * know which filters will be enabled, increase the left and right
1749 * margins by two.
1750 */
1751 if (prev->input == PREVIEW_INPUT_CCDC) {
1752 left += 2;
1753 right -= 2;
1754 }
1755
1756 /* Restrict left/top to even values to keep the Bayer pattern. */
1757 crop->left &= ~1;
1758 crop->top &= ~1;
1759
1760 crop->left = clamp_t(u32, crop->left, left, right - PREV_MIN_OUT_WIDTH);
1761 crop->top = clamp_t(u32, crop->top, top, bottom - PREV_MIN_OUT_HEIGHT);
1762 crop->width = clamp_t(u32, crop->width, PREV_MIN_OUT_WIDTH,
1763 right - crop->left);
1764 crop->height = clamp_t(u32, crop->height, PREV_MIN_OUT_HEIGHT,
1765 bottom - crop->top);
1766}
1767
1768/*
1718 * preview_enum_mbus_code - Handle pixel format enumeration 1769 * preview_enum_mbus_code - Handle pixel format enumeration
1719 * @sd : pointer to v4l2 subdev structure 1770 * @sd : pointer to v4l2 subdev structure
1720 * @fh : V4L2 subdev file handle 1771 * @fh : V4L2 subdev file handle
@@ -1776,6 +1827,60 @@ static int preview_enum_frame_size(struct v4l2_subdev *sd,
1776} 1827}
1777 1828
1778/* 1829/*
1830 * preview_get_crop - Retrieve the crop rectangle on a pad
1831 * @sd: ISP preview V4L2 subdevice
1832 * @fh: V4L2 subdev file handle
1833 * @crop: crop rectangle
1834 *
1835 * Return 0 on success or a negative error code otherwise.
1836 */
1837static int preview_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1838 struct v4l2_subdev_crop *crop)
1839{
1840 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1841
1842 /* Cropping is only supported on the sink pad. */
1843 if (crop->pad != PREV_PAD_SINK)
1844 return -EINVAL;
1845
1846 crop->rect = *__preview_get_crop(prev, fh, crop->which);
1847 return 0;
1848}
1849
1850/*
1851 * preview_set_crop - Retrieve the crop rectangle on a pad
1852 * @sd: ISP preview V4L2 subdevice
1853 * @fh: V4L2 subdev file handle
1854 * @crop: crop rectangle
1855 *
1856 * Return 0 on success or a negative error code otherwise.
1857 */
1858static int preview_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1859 struct v4l2_subdev_crop *crop)
1860{
1861 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1862 struct v4l2_mbus_framefmt *format;
1863
1864 /* Cropping is only supported on the sink pad. */
1865 if (crop->pad != PREV_PAD_SINK)
1866 return -EINVAL;
1867
1868 /* The crop rectangle can't be changed while streaming. */
1869 if (prev->state != ISP_PIPELINE_STREAM_STOPPED)
1870 return -EBUSY;
1871
1872 format = __preview_get_format(prev, fh, PREV_PAD_SINK, crop->which);
1873 preview_try_crop(prev, format, &crop->rect);
1874 *__preview_get_crop(prev, fh, crop->which) = crop->rect;
1875
1876 /* Update the source format. */
1877 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, crop->which);
1878 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, crop->which);
1879
1880 return 0;
1881}
1882
1883/*
1779 * preview_get_format - Handle get format by pads subdev method 1884 * preview_get_format - Handle get format by pads subdev method
1780 * @sd : pointer to v4l2 subdev structure 1885 * @sd : pointer to v4l2 subdev structure
1781 * @fh : V4L2 subdev file handle 1886 * @fh : V4L2 subdev file handle
@@ -1808,6 +1913,7 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1808{ 1913{
1809 struct isp_prev_device *prev = v4l2_get_subdevdata(sd); 1914 struct isp_prev_device *prev = v4l2_get_subdevdata(sd);
1810 struct v4l2_mbus_framefmt *format; 1915 struct v4l2_mbus_framefmt *format;
1916 struct v4l2_rect *crop;
1811 1917
1812 format = __preview_get_format(prev, fh, fmt->pad, fmt->which); 1918 format = __preview_get_format(prev, fh, fmt->pad, fmt->which);
1813 if (format == NULL) 1919 if (format == NULL)
@@ -1818,9 +1924,18 @@ static int preview_set_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1818 1924
1819 /* Propagate the format from sink to source */ 1925 /* Propagate the format from sink to source */
1820 if (fmt->pad == PREV_PAD_SINK) { 1926 if (fmt->pad == PREV_PAD_SINK) {
1927 /* Reset the crop rectangle. */
1928 crop = __preview_get_crop(prev, fh, fmt->which);
1929 crop->left = 0;
1930 crop->top = 0;
1931 crop->width = fmt->format.width;
1932 crop->height = fmt->format.height;
1933
1934 preview_try_crop(prev, &fmt->format, crop);
1935
1936 /* Update the source format. */
1821 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE, 1937 format = __preview_get_format(prev, fh, PREV_PAD_SOURCE,
1822 fmt->which); 1938 fmt->which);
1823 *format = fmt->format;
1824 preview_try_format(prev, fh, PREV_PAD_SOURCE, format, 1939 preview_try_format(prev, fh, PREV_PAD_SOURCE, format,
1825 fmt->which); 1940 fmt->which);
1826 } 1941 }
@@ -1869,6 +1984,8 @@ static const struct v4l2_subdev_pad_ops preview_v4l2_pad_ops = {
1869 .enum_frame_size = preview_enum_frame_size, 1984 .enum_frame_size = preview_enum_frame_size,
1870 .get_fmt = preview_get_format, 1985 .get_fmt = preview_get_format,
1871 .set_fmt = preview_set_format, 1986 .set_fmt = preview_set_format,
1987 .get_crop = preview_get_crop,
1988 .set_crop = preview_set_crop,
1872}; 1989};
1873 1990
1874/* subdev operations */ 1991/* subdev operations */
@@ -1966,8 +2083,44 @@ static const struct media_entity_operations preview_media_ops = {
1966 .link_setup = preview_link_setup, 2083 .link_setup = preview_link_setup,
1967}; 2084};
1968 2085
2086void omap3isp_preview_unregister_entities(struct isp_prev_device *prev)
2087{
2088 v4l2_device_unregister_subdev(&prev->subdev);
2089 omap3isp_video_unregister(&prev->video_in);
2090 omap3isp_video_unregister(&prev->video_out);
2091}
2092
2093int omap3isp_preview_register_entities(struct isp_prev_device *prev,
2094 struct v4l2_device *vdev)
2095{
2096 int ret;
2097
2098 /* Register the subdev and video nodes. */
2099 ret = v4l2_device_register_subdev(vdev, &prev->subdev);
2100 if (ret < 0)
2101 goto error;
2102
2103 ret = omap3isp_video_register(&prev->video_in, vdev);
2104 if (ret < 0)
2105 goto error;
2106
2107 ret = omap3isp_video_register(&prev->video_out, vdev);
2108 if (ret < 0)
2109 goto error;
2110
2111 return 0;
2112
2113error:
2114 omap3isp_preview_unregister_entities(prev);
2115 return ret;
2116}
2117
2118/* -----------------------------------------------------------------------------
2119 * ISP previewer initialisation and cleanup
2120 */
2121
1969/* 2122/*
1970 * review_init_entities - Initialize subdev and media entity. 2123 * preview_init_entities - Initialize subdev and media entity.
1971 * @prev : Pointer to preview structure 2124 * @prev : Pointer to preview structure
1972 * return -ENOMEM or zero on success 2125 * return -ENOMEM or zero on success
1973 */ 2126 */
@@ -2024,69 +2177,34 @@ static int preview_init_entities(struct isp_prev_device *prev)
2024 2177
2025 ret = omap3isp_video_init(&prev->video_in, "preview"); 2178 ret = omap3isp_video_init(&prev->video_in, "preview");
2026 if (ret < 0) 2179 if (ret < 0)
2027 return ret; 2180 goto error_video_in;
2028 2181
2029 ret = omap3isp_video_init(&prev->video_out, "preview"); 2182 ret = omap3isp_video_init(&prev->video_out, "preview");
2030 if (ret < 0) 2183 if (ret < 0)
2031 return ret; 2184 goto error_video_out;
2032 2185
2033 /* Connect the video nodes to the previewer subdev. */ 2186 /* Connect the video nodes to the previewer subdev. */
2034 ret = media_entity_create_link(&prev->video_in.video.entity, 0, 2187 ret = media_entity_create_link(&prev->video_in.video.entity, 0,
2035 &prev->subdev.entity, PREV_PAD_SINK, 0); 2188 &prev->subdev.entity, PREV_PAD_SINK, 0);
2036 if (ret < 0) 2189 if (ret < 0)
2037 return ret; 2190 goto error_link;
2038 2191
2039 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE, 2192 ret = media_entity_create_link(&prev->subdev.entity, PREV_PAD_SOURCE,
2040 &prev->video_out.video.entity, 0, 0); 2193 &prev->video_out.video.entity, 0, 0);
2041 if (ret < 0) 2194 if (ret < 0)
2042 return ret; 2195 goto error_link;
2043 2196
2044 return 0; 2197 return 0;
2045}
2046 2198
2047void omap3isp_preview_unregister_entities(struct isp_prev_device *prev) 2199error_link:
2048{ 2200 omap3isp_video_cleanup(&prev->video_out);
2201error_video_out:
2202 omap3isp_video_cleanup(&prev->video_in);
2203error_video_in:
2049 media_entity_cleanup(&prev->subdev.entity); 2204 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; 2205 return ret;
2080} 2206}
2081 2207
2082/* -----------------------------------------------------------------------------
2083 * ISP previewer initialisation and cleanup
2084 */
2085
2086void omap3isp_preview_cleanup(struct isp_device *isp)
2087{
2088}
2089
2090/* 2208/*
2091 * isp_preview_init - Previewer initialization. 2209 * isp_preview_init - Previewer initialization.
2092 * @dev : Pointer to ISP device 2210 * @dev : Pointer to ISP device
@@ -2095,19 +2213,20 @@ void omap3isp_preview_cleanup(struct isp_device *isp)
2095int omap3isp_preview_init(struct isp_device *isp) 2213int omap3isp_preview_init(struct isp_device *isp)
2096{ 2214{
2097 struct isp_prev_device *prev = &isp->isp_prev; 2215 struct isp_prev_device *prev = &isp->isp_prev;
2098 int ret;
2099 2216
2100 spin_lock_init(&prev->lock); 2217 spin_lock_init(&prev->lock);
2101 init_waitqueue_head(&prev->wait); 2218 init_waitqueue_head(&prev->wait);
2102 preview_init_params(prev); 2219 preview_init_params(prev);
2103 2220
2104 ret = preview_init_entities(prev); 2221 return preview_init_entities(prev);
2105 if (ret < 0) 2222}
2106 goto out;
2107 2223
2108out: 2224void omap3isp_preview_cleanup(struct isp_device *isp)
2109 if (ret) 2225{
2110 omap3isp_preview_cleanup(isp); 2226 struct isp_prev_device *prev = &isp->isp_prev;
2111 2227
2112 return ret; 2228 v4l2_ctrl_handler_free(&prev->ctrls);
2229 omap3isp_video_cleanup(&prev->video_in);
2230 omap3isp_video_cleanup(&prev->video_out);
2231 media_entity_cleanup(&prev->subdev.entity);
2113} 2232}
diff --git a/drivers/media/video/omap3isp/isppreview.h b/drivers/media/video/omap3isp/isppreview.h
index fa943bd05c7..f54e775c2df 100644
--- a/drivers/media/video/omap3isp/isppreview.h
+++ b/drivers/media/video/omap3isp/isppreview.h
@@ -45,11 +45,6 @@
45#define ISPPRV_CONTRAST_HIGH 0xFF 45#define ISPPRV_CONTRAST_HIGH 0xFF
46#define ISPPRV_CONTRAST_UNITS 0x1 46#define ISPPRV_CONTRAST_UNITS 0x1
47 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 */ 48/* Features list */
54#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH 49#define PREV_LUMA_ENHANCE OMAP3ISP_PREV_LUMAENH
55#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW 50#define PREV_INVERSE_ALAW OMAP3ISP_PREV_INVALAW
@@ -106,7 +101,6 @@ enum preview_ycpos_mode {
106 * @rgb2ycbcr: RGB to ycbcr parameters. 101 * @rgb2ycbcr: RGB to ycbcr parameters.
107 * @hmed: Horizontal median filter. 102 * @hmed: Horizontal median filter.
108 * @yclimit: YC limits parameters. 103 * @yclimit: YC limits parameters.
109 * @average: Downsampling rate for averager.
110 * @contrast: Contrast. 104 * @contrast: Contrast.
111 * @brightness: Brightness. 105 * @brightness: Brightness.
112 */ 106 */
@@ -124,7 +118,6 @@ struct prev_params {
124 struct omap3isp_prev_csc rgb2ycbcr; 118 struct omap3isp_prev_csc rgb2ycbcr;
125 struct omap3isp_prev_hmed hmed; 119 struct omap3isp_prev_hmed hmed;
126 struct omap3isp_prev_yclimit yclimit; 120 struct omap3isp_prev_yclimit yclimit;
127 u8 average;
128 u8 contrast; 121 u8 contrast;
129 u8 brightness; 122 u8 brightness;
130}; 123};
@@ -159,6 +152,7 @@ struct isptables_update {
159 * @subdev: V4L2 subdevice 152 * @subdev: V4L2 subdevice
160 * @pads: Media entity pads 153 * @pads: Media entity pads
161 * @formats: Active formats at the subdev pad 154 * @formats: Active formats at the subdev pad
155 * @crop: Active crop rectangle
162 * @input: Module currently connected to the input pad 156 * @input: Module currently connected to the input pad
163 * @output: Bitmask of the active output 157 * @output: Bitmask of the active output
164 * @video_in: Input video entity 158 * @video_in: Input video entity
@@ -177,6 +171,7 @@ struct isp_prev_device {
177 struct v4l2_subdev subdev; 171 struct v4l2_subdev subdev;
178 struct media_pad pads[PREV_PADS_NUM]; 172 struct media_pad pads[PREV_PADS_NUM];
179 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM]; 173 struct v4l2_mbus_framefmt formats[PREV_PADS_NUM];
174 struct v4l2_rect crop;
180 175
181 struct v4l2_ctrl_handler ctrls; 176 struct v4l2_ctrl_handler ctrls;
182 177
diff --git a/drivers/media/video/omap3isp/ispreg.h b/drivers/media/video/omap3isp/ispreg.h
index 69f6af6f6b9..084ea77d65a 100644
--- a/drivers/media/video/omap3isp/ispreg.h
+++ b/drivers/media/video/omap3isp/ispreg.h
@@ -402,9 +402,6 @@
402#define ISPPRV_YENH_TABLE_ADDR 0x1000 402#define ISPPRV_YENH_TABLE_ADDR 0x1000
403#define ISPPRV_CFA_TABLE_ADDR 0x1400 403#define ISPPRV_CFA_TABLE_ADDR 0x1400
404 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 405#define ISPRSZ_MIN_OUTPUT 64
409#define ISPRSZ_MAX_OUTPUT 3312 406#define ISPRSZ_MAX_OUTPUT 3312
410 407
diff --git a/drivers/media/video/omap3isp/ispresizer.c b/drivers/media/video/omap3isp/ispresizer.c
index 0bb0f8cd36f..50e593bfcfa 100644
--- a/drivers/media/video/omap3isp/ispresizer.c
+++ b/drivers/media/video/omap3isp/ispresizer.c
@@ -1608,6 +1608,42 @@ static const struct media_entity_operations resizer_media_ops = {
1608 .link_setup = resizer_link_setup, 1608 .link_setup = resizer_link_setup,
1609}; 1609};
1610 1610
1611void omap3isp_resizer_unregister_entities(struct isp_res_device *res)
1612{
1613 v4l2_device_unregister_subdev(&res->subdev);
1614 omap3isp_video_unregister(&res->video_in);
1615 omap3isp_video_unregister(&res->video_out);
1616}
1617
1618int omap3isp_resizer_register_entities(struct isp_res_device *res,
1619 struct v4l2_device *vdev)
1620{
1621 int ret;
1622
1623 /* Register the subdev and video nodes. */
1624 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1625 if (ret < 0)
1626 goto error;
1627
1628 ret = omap3isp_video_register(&res->video_in, vdev);
1629 if (ret < 0)
1630 goto error;
1631
1632 ret = omap3isp_video_register(&res->video_out, vdev);
1633 if (ret < 0)
1634 goto error;
1635
1636 return 0;
1637
1638error:
1639 omap3isp_resizer_unregister_entities(res);
1640 return ret;
1641}
1642
1643/* -----------------------------------------------------------------------------
1644 * ISP resizer initialization and cleanup
1645 */
1646
1611/* 1647/*
1612 * resizer_init_entities - Initialize resizer subdev and media entity. 1648 * resizer_init_entities - Initialize resizer subdev and media entity.
1613 * @res : Pointer to resizer device structure 1649 * @res : Pointer to resizer device structure
@@ -1652,68 +1688,34 @@ static int resizer_init_entities(struct isp_res_device *res)
1652 1688
1653 ret = omap3isp_video_init(&res->video_in, "resizer"); 1689 ret = omap3isp_video_init(&res->video_in, "resizer");
1654 if (ret < 0) 1690 if (ret < 0)
1655 return ret; 1691 goto error_video_in;
1656 1692
1657 ret = omap3isp_video_init(&res->video_out, "resizer"); 1693 ret = omap3isp_video_init(&res->video_out, "resizer");
1658 if (ret < 0) 1694 if (ret < 0)
1659 return ret; 1695 goto error_video_out;
1660 1696
1661 /* Connect the video nodes to the resizer subdev. */ 1697 /* Connect the video nodes to the resizer subdev. */
1662 ret = media_entity_create_link(&res->video_in.video.entity, 0, 1698 ret = media_entity_create_link(&res->video_in.video.entity, 0,
1663 &res->subdev.entity, RESZ_PAD_SINK, 0); 1699 &res->subdev.entity, RESZ_PAD_SINK, 0);
1664 if (ret < 0) 1700 if (ret < 0)
1665 return ret; 1701 goto error_link;
1666 1702
1667 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE, 1703 ret = media_entity_create_link(&res->subdev.entity, RESZ_PAD_SOURCE,
1668 &res->video_out.video.entity, 0, 0); 1704 &res->video_out.video.entity, 0, 0);
1669 if (ret < 0) 1705 if (ret < 0)
1670 return ret; 1706 goto error_link;
1671 1707
1672 return 0; 1708 return 0;
1673}
1674 1709
1675void omap3isp_resizer_unregister_entities(struct isp_res_device *res) 1710error_link:
1676{ 1711 omap3isp_video_cleanup(&res->video_out);
1712error_video_out:
1713 omap3isp_video_cleanup(&res->video_in);
1714error_video_in:
1677 media_entity_cleanup(&res->subdev.entity); 1715 media_entity_cleanup(&res->subdev.entity);
1678
1679 v4l2_device_unregister_subdev(&res->subdev);
1680 omap3isp_video_unregister(&res->video_in);
1681 omap3isp_video_unregister(&res->video_out);
1682}
1683
1684int omap3isp_resizer_register_entities(struct isp_res_device *res,
1685 struct v4l2_device *vdev)
1686{
1687 int ret;
1688
1689 /* Register the subdev and video nodes. */
1690 ret = v4l2_device_register_subdev(vdev, &res->subdev);
1691 if (ret < 0)
1692 goto error;
1693
1694 ret = omap3isp_video_register(&res->video_in, vdev);
1695 if (ret < 0)
1696 goto error;
1697
1698 ret = omap3isp_video_register(&res->video_out, vdev);
1699 if (ret < 0)
1700 goto error;
1701
1702 return 0;
1703
1704error:
1705 omap3isp_resizer_unregister_entities(res);
1706 return ret; 1716 return ret;
1707} 1717}
1708 1718
1709/* -----------------------------------------------------------------------------
1710 * ISP resizer initialization and cleanup
1711 */
1712
1713void omap3isp_resizer_cleanup(struct isp_device *isp)
1714{
1715}
1716
1717/* 1719/*
1718 * isp_resizer_init - Resizer initialization. 1720 * isp_resizer_init - Resizer initialization.
1719 * @isp : Pointer to ISP device 1721 * @isp : Pointer to ISP device
@@ -1722,17 +1724,17 @@ void omap3isp_resizer_cleanup(struct isp_device *isp)
1722int omap3isp_resizer_init(struct isp_device *isp) 1724int omap3isp_resizer_init(struct isp_device *isp)
1723{ 1725{
1724 struct isp_res_device *res = &isp->isp_res; 1726 struct isp_res_device *res = &isp->isp_res;
1725 int ret;
1726 1727
1727 init_waitqueue_head(&res->wait); 1728 init_waitqueue_head(&res->wait);
1728 atomic_set(&res->stopping, 0); 1729 atomic_set(&res->stopping, 0);
1729 ret = resizer_init_entities(res); 1730 return resizer_init_entities(res);
1730 if (ret < 0) 1731}
1731 goto out;
1732 1732
1733out: 1733void omap3isp_resizer_cleanup(struct isp_device *isp)
1734 if (ret) 1734{
1735 omap3isp_resizer_cleanup(isp); 1735 struct isp_res_device *res = &isp->isp_res;
1736 1736
1737 return ret; 1737 omap3isp_video_cleanup(&res->video_in);
1738 omap3isp_video_cleanup(&res->video_out);
1739 media_entity_cleanup(&res->subdev.entity);
1738} 1740}
diff --git a/drivers/media/video/omap3isp/ispstat.c b/drivers/media/video/omap3isp/ispstat.c
index 73290555226..68d539456c5 100644
--- a/drivers/media/video/omap3isp/ispstat.c
+++ b/drivers/media/video/omap3isp/ispstat.c
@@ -1023,24 +1023,6 @@ void omap3isp_stat_dma_isr(struct ispstat *stat)
1023 __stat_isr(stat, 1); 1023 __stat_isr(stat, 1);
1024} 1024}
1025 1025
1026static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1027 const struct v4l2_subdev_ops *sd_ops)
1028{
1029 struct v4l2_subdev *subdev = &stat->subdev;
1030 struct media_entity *me = &subdev->entity;
1031
1032 v4l2_subdev_init(subdev, sd_ops);
1033 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1034 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1035 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
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, 1026int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
1045 struct v4l2_fh *fh, 1027 struct v4l2_fh *fh,
1046 struct v4l2_event_subscription *sub) 1028 struct v4l2_event_subscription *sub)
@@ -1062,7 +1044,6 @@ int omap3isp_stat_unsubscribe_event(struct v4l2_subdev *subdev,
1062 1044
1063void omap3isp_stat_unregister_entities(struct ispstat *stat) 1045void omap3isp_stat_unregister_entities(struct ispstat *stat)
1064{ 1046{
1065 media_entity_cleanup(&stat->subdev.entity);
1066 v4l2_device_unregister_subdev(&stat->subdev); 1047 v4l2_device_unregister_subdev(&stat->subdev);
1067} 1048}
1068 1049
@@ -1072,21 +1053,50 @@ int omap3isp_stat_register_entities(struct ispstat *stat,
1072 return v4l2_device_register_subdev(vdev, &stat->subdev); 1053 return v4l2_device_register_subdev(vdev, &stat->subdev);
1073} 1054}
1074 1055
1056static int isp_stat_init_entities(struct ispstat *stat, const char *name,
1057 const struct v4l2_subdev_ops *sd_ops)
1058{
1059 struct v4l2_subdev *subdev = &stat->subdev;
1060 struct media_entity *me = &subdev->entity;
1061
1062 v4l2_subdev_init(subdev, sd_ops);
1063 snprintf(subdev->name, V4L2_SUBDEV_NAME_SIZE, "OMAP3 ISP %s", name);
1064 subdev->grp_id = 1 << 16; /* group ID for isp subdevs */
1065 subdev->flags |= V4L2_SUBDEV_FL_HAS_EVENTS | V4L2_SUBDEV_FL_HAS_DEVNODE;
1066 v4l2_set_subdevdata(subdev, stat);
1067
1068 stat->pad.flags = MEDIA_PAD_FL_SINK;
1069 me->ops = NULL;
1070
1071 return media_entity_init(me, 1, &stat->pad, 0);
1072}
1073
1075int omap3isp_stat_init(struct ispstat *stat, const char *name, 1074int omap3isp_stat_init(struct ispstat *stat, const char *name,
1076 const struct v4l2_subdev_ops *sd_ops) 1075 const struct v4l2_subdev_ops *sd_ops)
1077{ 1076{
1077 int ret;
1078
1078 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL); 1079 stat->buf = kcalloc(STAT_MAX_BUFS, sizeof(*stat->buf), GFP_KERNEL);
1079 if (!stat->buf) 1080 if (!stat->buf)
1080 return -ENOMEM; 1081 return -ENOMEM;
1082
1081 isp_stat_buf_clear(stat); 1083 isp_stat_buf_clear(stat);
1082 mutex_init(&stat->ioctl_lock); 1084 mutex_init(&stat->ioctl_lock);
1083 atomic_set(&stat->buf_err, 0); 1085 atomic_set(&stat->buf_err, 0);
1084 1086
1085 return isp_stat_init_entities(stat, name, sd_ops); 1087 ret = isp_stat_init_entities(stat, name, sd_ops);
1088 if (ret < 0) {
1089 mutex_destroy(&stat->ioctl_lock);
1090 kfree(stat->buf);
1091 }
1092
1093 return ret;
1086} 1094}
1087 1095
1088void omap3isp_stat_free(struct ispstat *stat) 1096void omap3isp_stat_cleanup(struct ispstat *stat)
1089{ 1097{
1098 media_entity_cleanup(&stat->subdev.entity);
1099 mutex_destroy(&stat->ioctl_lock);
1090 isp_stat_bufs_free(stat); 1100 isp_stat_bufs_free(stat);
1091 kfree(stat->buf); 1101 kfree(stat->buf);
1092} 1102}
diff --git a/drivers/media/video/omap3isp/ispstat.h b/drivers/media/video/omap3isp/ispstat.h
index d86da94fa50..9b7c8654dc8 100644
--- a/drivers/media/video/omap3isp/ispstat.h
+++ b/drivers/media/video/omap3isp/ispstat.h
@@ -144,7 +144,7 @@ int omap3isp_stat_request_statistics(struct ispstat *stat,
144 struct omap3isp_stat_data *data); 144 struct omap3isp_stat_data *data);
145int omap3isp_stat_init(struct ispstat *stat, const char *name, 145int omap3isp_stat_init(struct ispstat *stat, const char *name,
146 const struct v4l2_subdev_ops *sd_ops); 146 const struct v4l2_subdev_ops *sd_ops);
147void omap3isp_stat_free(struct ispstat *stat); 147void omap3isp_stat_cleanup(struct ispstat *stat);
148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev, 148int omap3isp_stat_subscribe_event(struct v4l2_subdev *subdev,
149 struct v4l2_fh *fh, 149 struct v4l2_fh *fh,
150 struct v4l2_event_subscription *sub); 150 struct v4l2_event_subscription *sub);
diff --git a/drivers/media/video/omap3isp/ispvideo.c b/drivers/media/video/omap3isp/ispvideo.c
index 0cb8a9f9d67..d1000723c5a 100644
--- a/drivers/media/video/omap3isp/ispvideo.c
+++ b/drivers/media/video/omap3isp/ispvideo.c
@@ -1325,6 +1325,13 @@ int omap3isp_video_init(struct isp_video *video, const char *name)
1325 return 0; 1325 return 0;
1326} 1326}
1327 1327
1328void omap3isp_video_cleanup(struct isp_video *video)
1329{
1330 media_entity_cleanup(&video->video.entity);
1331 mutex_destroy(&video->stream_lock);
1332 mutex_destroy(&video->mutex);
1333}
1334
1328int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev) 1335int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1329{ 1336{
1330 int ret; 1337 int ret;
@@ -1341,8 +1348,6 @@ int omap3isp_video_register(struct isp_video *video, struct v4l2_device *vdev)
1341 1348
1342void omap3isp_video_unregister(struct isp_video *video) 1349void omap3isp_video_unregister(struct isp_video *video)
1343{ 1350{
1344 if (video_is_registered(&video->video)) { 1351 if (video_is_registered(&video->video))
1345 media_entity_cleanup(&video->video.entity);
1346 video_unregister_device(&video->video); 1352 video_unregister_device(&video->video);
1347 }
1348} 1353}
diff --git a/drivers/media/video/omap3isp/ispvideo.h b/drivers/media/video/omap3isp/ispvideo.h
index 53160aa24e6..08cbfa144e6 100644
--- a/drivers/media/video/omap3isp/ispvideo.h
+++ b/drivers/media/video/omap3isp/ispvideo.h
@@ -190,6 +190,7 @@ struct isp_video_fh {
190 container_of(q, struct isp_video_fh, queue) 190 container_of(q, struct isp_video_fh, queue)
191 191
192int omap3isp_video_init(struct isp_video *video, const char *name); 192int omap3isp_video_init(struct isp_video *video, const char *name);
193void omap3isp_video_cleanup(struct isp_video *video);
193int omap3isp_video_register(struct isp_video *video, 194int omap3isp_video_register(struct isp_video *video,
194 struct v4l2_device *vdev); 195 struct v4l2_device *vdev);
195void omap3isp_video_unregister(struct isp_video *video); 196void omap3isp_video_unregister(struct isp_video *video);
diff --git a/drivers/media/video/ov2640.c b/drivers/media/video/ov2640.c
index 9ce2fa037b9..b5247cb64fd 100644
--- a/drivers/media/video/ov2640.c
+++ b/drivers/media/video/ov2640.c
@@ -18,11 +18,13 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/v4l2-mediabus.h>
21#include <linux/videodev2.h> 22#include <linux/videodev2.h>
23
24#include <media/soc_camera.h>
22#include <media/v4l2-chip-ident.h> 25#include <media/v4l2-chip-ident.h>
23#include <media/v4l2-subdev.h> 26#include <media/v4l2-subdev.h>
24#include <media/soc_camera.h> 27#include <media/v4l2-ctrls.h>
25#include <media/soc_mediabus.h>
26 28
27#define VAL_SET(x, mask, rshift, lshift) \ 29#define VAL_SET(x, mask, rshift, lshift) \
28 ((((x) >> rshift) & mask) << lshift) 30 ((((x) >> rshift) & mask) << lshift)
@@ -299,12 +301,10 @@ struct ov2640_win_size {
299 301
300struct ov2640_priv { 302struct ov2640_priv {
301 struct v4l2_subdev subdev; 303 struct v4l2_subdev subdev;
302 struct ov2640_camera_info *info; 304 struct v4l2_ctrl_handler hdl;
303 enum v4l2_mbus_pixelcode cfmt_code; 305 enum v4l2_mbus_pixelcode cfmt_code;
304 const struct ov2640_win_size *win; 306 const struct ov2640_win_size *win;
305 int model; 307 int model;
306 u16 flag_vflip:1;
307 u16 flag_hflip:1;
308}; 308};
309 309
310/* 310/*
@@ -610,29 +610,6 @@ static enum v4l2_mbus_pixelcode ov2640_codes[] = {
610}; 610};
611 611
612/* 612/*
613 * Supported controls
614 */
615static const struct v4l2_queryctrl ov2640_controls[] = {
616 {
617 .id = V4L2_CID_VFLIP,
618 .type = V4L2_CTRL_TYPE_BOOLEAN,
619 .name = "Flip Vertically",
620 .minimum = 0,
621 .maximum = 1,
622 .step = 1,
623 .default_value = 0,
624 }, {
625 .id = V4L2_CID_HFLIP,
626 .type = V4L2_CTRL_TYPE_BOOLEAN,
627 .name = "Flip Horizontally",
628 .minimum = 0,
629 .maximum = 1,
630 .step = 1,
631 .default_value = 0,
632 },
633};
634
635/*
636 * General functions 613 * General functions
637 */ 614 */
638static struct ov2640_priv *to_ov2640(const struct i2c_client *client) 615static struct ov2640_priv *to_ov2640(const struct i2c_client *client)
@@ -701,81 +678,23 @@ static int ov2640_s_stream(struct v4l2_subdev *sd, int enable)
701 return 0; 678 return 0;
702} 679}
703 680
704static int ov2640_set_bus_param(struct soc_camera_device *icd, 681static int ov2640_s_ctrl(struct v4l2_ctrl *ctrl)
705 unsigned long flags)
706{
707 struct soc_camera_link *icl = to_soc_camera_link(icd);
708 unsigned long width_flag = flags & SOCAM_DATAWIDTH_MASK;
709
710 /* Only one width bit may be set */
711 if (!is_power_of_2(width_flag))
712 return -EINVAL;
713
714 if (icl->set_bus_param)
715 return icl->set_bus_param(icl, width_flag);
716
717 /*
718 * Without board specific bus width settings we support only the
719 * sensors native bus width witch are tested working
720 */
721 if (width_flag & (SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8))
722 return 0;
723
724 return 0;
725}
726
727static unsigned long ov2640_query_bus_param(struct soc_camera_device *icd)
728{
729 struct soc_camera_link *icl = to_soc_camera_link(icd);
730 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
731 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
732 SOCAM_DATA_ACTIVE_HIGH;
733
734 if (icl->query_bus_param)
735 flags |= icl->query_bus_param(icl) & SOCAM_DATAWIDTH_MASK;
736 else
737 flags |= SOCAM_DATAWIDTH_10;
738
739 return soc_camera_apply_sensor_flags(icl, flags);
740}
741
742static int ov2640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
743{ 682{
683 struct v4l2_subdev *sd =
684 &container_of(ctrl->handler, struct ov2640_priv, hdl)->subdev;
744 struct i2c_client *client = v4l2_get_subdevdata(sd); 685 struct i2c_client *client = v4l2_get_subdevdata(sd);
745 struct ov2640_priv *priv = to_ov2640(client);
746
747 switch (ctrl->id) {
748 case V4L2_CID_VFLIP:
749 ctrl->value = priv->flag_vflip;
750 break;
751 case V4L2_CID_HFLIP:
752 ctrl->value = priv->flag_hflip;
753 break;
754 }
755 return 0;
756}
757
758static int ov2640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
759{
760 struct i2c_client *client = v4l2_get_subdevdata(sd);
761 struct ov2640_priv *priv = to_ov2640(client);
762 int ret = 0;
763 u8 val; 686 u8 val;
764 687
765 switch (ctrl->id) { 688 switch (ctrl->id) {
766 case V4L2_CID_VFLIP: 689 case V4L2_CID_VFLIP:
767 val = ctrl->value ? REG04_VFLIP_IMG : 0x00; 690 val = ctrl->val ? REG04_VFLIP_IMG : 0x00;
768 priv->flag_vflip = ctrl->value ? 1 : 0; 691 return ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
769 ret = ov2640_mask_set(client, REG04, REG04_VFLIP_IMG, val);
770 break;
771 case V4L2_CID_HFLIP: 692 case V4L2_CID_HFLIP:
772 val = ctrl->value ? REG04_HFLIP_IMG : 0x00; 693 val = ctrl->val ? REG04_HFLIP_IMG : 0x00;
773 priv->flag_hflip = ctrl->value ? 1 : 0; 694 return ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
774 ret = ov2640_mask_set(client, REG04, REG04_HFLIP_IMG, val);
775 break;
776 } 695 }
777 696
778 return ret; 697 return -EINVAL;
779} 698}
780 699
781static int ov2640_g_chip_ident(struct v4l2_subdev *sd, 700static int ov2640_g_chip_ident(struct v4l2_subdev *sd,
@@ -1023,18 +942,13 @@ static int ov2640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
1023 return 0; 942 return 0;
1024} 943}
1025 944
1026static int ov2640_video_probe(struct soc_camera_device *icd, 945static int ov2640_video_probe(struct i2c_client *client)
1027 struct i2c_client *client)
1028{ 946{
1029 struct ov2640_priv *priv = to_ov2640(client); 947 struct ov2640_priv *priv = to_ov2640(client);
1030 u8 pid, ver, midh, midl; 948 u8 pid, ver, midh, midl;
1031 const char *devname; 949 const char *devname;
1032 int ret; 950 int ret;
1033 951
1034 /* We must have a parent by now. And it cannot be a wrong one. */
1035 BUG_ON(!icd->parent ||
1036 to_soc_camera_host(icd->parent)->nr != icd->iface);
1037
1038 /* 952 /*
1039 * check and show product ID and manufacturer ID 953 * check and show product ID and manufacturer ID
1040 */ 954 */
@@ -1060,22 +974,17 @@ static int ov2640_video_probe(struct soc_camera_device *icd,
1060 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 974 "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
1061 devname, pid, ver, midh, midl); 975 devname, pid, ver, midh, midl);
1062 976
1063 return 0; 977 return v4l2_ctrl_handler_setup(&priv->hdl);
1064 978
1065err: 979err:
1066 return ret; 980 return ret;
1067} 981}
1068 982
1069static struct soc_camera_ops ov2640_ops = { 983static const struct v4l2_ctrl_ops ov2640_ctrl_ops = {
1070 .set_bus_param = ov2640_set_bus_param, 984 .s_ctrl = ov2640_s_ctrl,
1071 .query_bus_param = ov2640_query_bus_param,
1072 .controls = ov2640_controls,
1073 .num_controls = ARRAY_SIZE(ov2640_controls),
1074}; 985};
1075 986
1076static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = { 987static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1077 .g_ctrl = ov2640_g_ctrl,
1078 .s_ctrl = ov2640_s_ctrl,
1079 .g_chip_ident = ov2640_g_chip_ident, 988 .g_chip_ident = ov2640_g_chip_ident,
1080#ifdef CONFIG_VIDEO_ADV_DEBUG 989#ifdef CONFIG_VIDEO_ADV_DEBUG
1081 .g_register = ov2640_g_register, 990 .g_register = ov2640_g_register,
@@ -1083,6 +992,21 @@ static struct v4l2_subdev_core_ops ov2640_subdev_core_ops = {
1083#endif 992#endif
1084}; 993};
1085 994
995static int ov2640_g_mbus_config(struct v4l2_subdev *sd,
996 struct v4l2_mbus_config *cfg)
997{
998 struct i2c_client *client = v4l2_get_subdevdata(sd);
999 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1000
1001 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1002 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1003 V4L2_MBUS_DATA_ACTIVE_HIGH;
1004 cfg->type = V4L2_MBUS_PARALLEL;
1005 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1006
1007 return 0;
1008}
1009
1086static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = { 1010static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1087 .s_stream = ov2640_s_stream, 1011 .s_stream = ov2640_s_stream,
1088 .g_mbus_fmt = ov2640_g_fmt, 1012 .g_mbus_fmt = ov2640_g_fmt,
@@ -1091,6 +1015,7 @@ static struct v4l2_subdev_video_ops ov2640_subdev_video_ops = {
1091 .cropcap = ov2640_cropcap, 1015 .cropcap = ov2640_cropcap,
1092 .g_crop = ov2640_g_crop, 1016 .g_crop = ov2640_g_crop,
1093 .enum_mbus_fmt = ov2640_enum_fmt, 1017 .enum_mbus_fmt = ov2640_enum_fmt,
1018 .g_mbus_config = ov2640_g_mbus_config,
1094}; 1019};
1095 1020
1096static struct v4l2_subdev_ops ov2640_subdev_ops = { 1021static struct v4l2_subdev_ops ov2640_subdev_ops = {
@@ -1104,18 +1029,11 @@ static struct v4l2_subdev_ops ov2640_subdev_ops = {
1104static int ov2640_probe(struct i2c_client *client, 1029static int ov2640_probe(struct i2c_client *client,
1105 const struct i2c_device_id *did) 1030 const struct i2c_device_id *did)
1106{ 1031{
1107 struct ov2640_priv *priv; 1032 struct ov2640_priv *priv;
1108 struct soc_camera_device *icd = client->dev.platform_data; 1033 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1109 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1034 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1110 struct soc_camera_link *icl; 1035 int ret;
1111 int ret;
1112
1113 if (!icd) {
1114 dev_err(&adapter->dev, "OV2640: missing soc-camera data!\n");
1115 return -EINVAL;
1116 }
1117 1036
1118 icl = to_soc_camera_link(icd);
1119 if (!icl) { 1037 if (!icl) {
1120 dev_err(&adapter->dev, 1038 dev_err(&adapter->dev,
1121 "OV2640: Missing platform_data for driver\n"); 1039 "OV2640: Missing platform_data for driver\n");
@@ -1135,15 +1053,23 @@ static int ov2640_probe(struct i2c_client *client,
1135 return -ENOMEM; 1053 return -ENOMEM;
1136 } 1054 }
1137 1055
1138 priv->info = icl->priv;
1139
1140 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops); 1056 v4l2_i2c_subdev_init(&priv->subdev, client, &ov2640_subdev_ops);
1057 v4l2_ctrl_handler_init(&priv->hdl, 2);
1058 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1059 V4L2_CID_VFLIP, 0, 1, 1, 0);
1060 v4l2_ctrl_new_std(&priv->hdl, &ov2640_ctrl_ops,
1061 V4L2_CID_HFLIP, 0, 1, 1, 0);
1062 priv->subdev.ctrl_handler = &priv->hdl;
1063 if (priv->hdl.error) {
1064 int err = priv->hdl.error;
1141 1065
1142 icd->ops = &ov2640_ops; 1066 kfree(priv);
1067 return err;
1068 }
1143 1069
1144 ret = ov2640_video_probe(icd, client); 1070 ret = ov2640_video_probe(client);
1145 if (ret) { 1071 if (ret) {
1146 icd->ops = NULL; 1072 v4l2_ctrl_handler_free(&priv->hdl);
1147 kfree(priv); 1073 kfree(priv);
1148 } else { 1074 } else {
1149 dev_info(&adapter->dev, "OV2640 Probed\n"); 1075 dev_info(&adapter->dev, "OV2640 Probed\n");
@@ -1155,9 +1081,9 @@ static int ov2640_probe(struct i2c_client *client,
1155static int ov2640_remove(struct i2c_client *client) 1081static int ov2640_remove(struct i2c_client *client)
1156{ 1082{
1157 struct ov2640_priv *priv = to_ov2640(client); 1083 struct ov2640_priv *priv = to_ov2640(client);
1158 struct soc_camera_device *icd = client->dev.platform_data;
1159 1084
1160 icd->ops = NULL; 1085 v4l2_device_unregister_subdev(&priv->subdev);
1086 v4l2_ctrl_handler_free(&priv->hdl);
1161 kfree(priv); 1087 kfree(priv);
1162 return 0; 1088 return 0;
1163} 1089}
diff --git a/drivers/media/video/ov5642.c b/drivers/media/video/ov5642.c
index 349a4ad3ccc..bb37ec80f27 100644
--- a/drivers/media/video/ov5642.c
+++ b/drivers/media/video/ov5642.c
@@ -14,14 +14,16 @@
14 * published by the Free Software Foundation. 14 * published by the Free Software Foundation.
15 */ 15 */
16 16
17#include <linux/bitops.h>
17#include <linux/delay.h> 18#include <linux/delay.h>
18#include <linux/i2c.h> 19#include <linux/i2c.h>
20#include <linux/kernel.h>
19#include <linux/slab.h> 21#include <linux/slab.h>
20#include <linux/videodev2.h> 22#include <linux/videodev2.h>
21#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/v4l2-mediabus.h>
22 25
23#include <media/soc_camera.h> 26#include <media/soc_camera.h>
24#include <media/soc_mediabus.h>
25#include <media/v4l2-chip-ident.h> 27#include <media/v4l2-chip-ident.h>
26#include <media/v4l2-subdev.h> 28#include <media/v4l2-subdev.h>
27 29
@@ -35,7 +37,7 @@
35#define REG_WINDOW_START_Y_LOW 0x3803 37#define REG_WINDOW_START_Y_LOW 0x3803
36#define REG_WINDOW_WIDTH_HIGH 0x3804 38#define REG_WINDOW_WIDTH_HIGH 0x3804
37#define REG_WINDOW_WIDTH_LOW 0x3805 39#define REG_WINDOW_WIDTH_LOW 0x3805
38#define REG_WINDOW_HEIGHT_HIGH 0x3806 40#define REG_WINDOW_HEIGHT_HIGH 0x3806
39#define REG_WINDOW_HEIGHT_LOW 0x3807 41#define REG_WINDOW_HEIGHT_LOW 0x3807
40#define REG_OUT_WIDTH_HIGH 0x3808 42#define REG_OUT_WIDTH_HIGH 0x3808
41#define REG_OUT_WIDTH_LOW 0x3809 43#define REG_OUT_WIDTH_LOW 0x3809
@@ -45,19 +47,44 @@
45#define REG_OUT_TOTAL_WIDTH_LOW 0x380d 47#define REG_OUT_TOTAL_WIDTH_LOW 0x380d
46#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e 48#define REG_OUT_TOTAL_HEIGHT_HIGH 0x380e
47#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f 49#define REG_OUT_TOTAL_HEIGHT_LOW 0x380f
50#define REG_OUTPUT_FORMAT 0x4300
51#define REG_ISP_CTRL_01 0x5001
52#define REG_AVG_WINDOW_END_X_HIGH 0x5682
53#define REG_AVG_WINDOW_END_X_LOW 0x5683
54#define REG_AVG_WINDOW_END_Y_HIGH 0x5686
55#define REG_AVG_WINDOW_END_Y_LOW 0x5687
56
57/* active pixel array size */
58#define OV5642_SENSOR_SIZE_X 2592
59#define OV5642_SENSOR_SIZE_Y 1944
48 60
49/* 61/*
50 * define standard resolution. 62 * About OV5642 resolution, cropping and binning:
51 * Works currently only for up to 720 lines 63 * This sensor supports it all, at least in the feature description.
52 * eg. 320x240, 640x480, 800x600, 1280x720, 2048x720 64 * Unfortunately, no combination of appropriate registers settings could make
65 * the chip work the intended way. As it works with predefined register lists,
66 * some undocumented registers are presumably changed there to achieve their
67 * goals.
68 * This driver currently only works for resolutions up to 720 lines with a
69 * 1:1 scale. Hopefully these restrictions will be removed in the future.
53 */ 70 */
71#define OV5642_MAX_WIDTH OV5642_SENSOR_SIZE_X
72#define OV5642_MAX_HEIGHT 720
54 73
55#define OV5642_WIDTH 1280 74/* default sizes */
56#define OV5642_HEIGHT 720 75#define OV5642_DEFAULT_WIDTH 1280
57#define OV5642_TOTAL_WIDTH 3200 76#define OV5642_DEFAULT_HEIGHT OV5642_MAX_HEIGHT
58#define OV5642_TOTAL_HEIGHT 2000 77
59#define OV5642_SENSOR_SIZE_X 2592 78/* minimum extra blanking */
60#define OV5642_SENSOR_SIZE_Y 1944 79#define BLANKING_EXTRA_WIDTH 500
80#define BLANKING_EXTRA_HEIGHT 20
81
82/*
83 * the sensor's autoexposure is buggy when setting total_height low.
84 * It tries to expose longer than 1 frame period without taking care of it
85 * and this leads to weird output. So we set 1000 lines as minimum.
86 */
87#define BLANKING_MIN_HEIGHT 1000
61 88
62struct regval_list { 89struct regval_list {
63 u16 reg_num; 90 u16 reg_num;
@@ -582,6 +609,11 @@ struct ov5642_datafmt {
582struct ov5642 { 609struct ov5642 {
583 struct v4l2_subdev subdev; 610 struct v4l2_subdev subdev;
584 const struct ov5642_datafmt *fmt; 611 const struct ov5642_datafmt *fmt;
612 struct v4l2_rect crop_rect;
613
614 /* blanking information */
615 int total_width;
616 int total_height;
585}; 617};
586 618
587static const struct ov5642_datafmt ov5642_colour_fmts[] = { 619static const struct ov5642_datafmt ov5642_colour_fmts[] = {
@@ -642,6 +674,21 @@ static int reg_write(struct i2c_client *client, u16 reg, u8 val)
642 674
643 return 0; 675 return 0;
644} 676}
677
678/*
679 * convenience function to write 16 bit register values that are split up
680 * into two consecutive high and low parts
681 */
682static int reg_write16(struct i2c_client *client, u16 reg, u16 val16)
683{
684 int ret;
685
686 ret = reg_write(client, reg, val16 >> 8);
687 if (ret)
688 return ret;
689 return reg_write(client, reg + 1, val16 & 0x00ff);
690}
691
645#ifdef CONFIG_VIDEO_ADV_DEBUG 692#ifdef CONFIG_VIDEO_ADV_DEBUG
646static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg) 693static int ov5642_get_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *reg)
647{ 694{
@@ -685,58 +732,55 @@ static int ov5642_write_array(struct i2c_client *client,
685 return 0; 732 return 0;
686} 733}
687 734
688static int ov5642_set_resolution(struct i2c_client *client) 735static int ov5642_set_resolution(struct v4l2_subdev *sd)
689{ 736{
737 struct i2c_client *client = v4l2_get_subdevdata(sd);
738 struct ov5642 *priv = to_ov5642(client);
739 int width = priv->crop_rect.width;
740 int height = priv->crop_rect.height;
741 int total_width = priv->total_width;
742 int total_height = priv->total_height;
743 int start_x = (OV5642_SENSOR_SIZE_X - width) / 2;
744 int start_y = (OV5642_SENSOR_SIZE_Y - height) / 2;
690 int ret; 745 int ret;
691 u8 start_x_high = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) >> 8;
692 u8 start_x_low = ((OV5642_SENSOR_SIZE_X - OV5642_WIDTH) / 2) & 0xff;
693 u8 start_y_high = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) >> 8;
694 u8 start_y_low = ((OV5642_SENSOR_SIZE_Y - OV5642_HEIGHT) / 2) & 0xff;
695
696 u8 width_high = OV5642_WIDTH >> 8;
697 u8 width_low = OV5642_WIDTH & 0xff;
698 u8 height_high = OV5642_HEIGHT >> 8;
699 u8 height_low = OV5642_HEIGHT & 0xff;
700
701 u8 total_width_high = OV5642_TOTAL_WIDTH >> 8;
702 u8 total_width_low = OV5642_TOTAL_WIDTH & 0xff;
703 u8 total_height_high = OV5642_TOTAL_HEIGHT >> 8;
704 u8 total_height_low = OV5642_TOTAL_HEIGHT & 0xff;
705
706 ret = reg_write(client, REG_WINDOW_START_X_HIGH, start_x_high);
707 if (!ret)
708 ret = reg_write(client, REG_WINDOW_START_X_LOW, start_x_low);
709 if (!ret)
710 ret = reg_write(client, REG_WINDOW_START_Y_HIGH, start_y_high);
711 if (!ret)
712 ret = reg_write(client, REG_WINDOW_START_Y_LOW, start_y_low);
713 746
747 /*
748 * This should set the starting point for cropping.
749 * Doesn't work so far.
750 */
751 ret = reg_write16(client, REG_WINDOW_START_X_HIGH, start_x);
714 if (!ret) 752 if (!ret)
715 ret = reg_write(client, REG_WINDOW_WIDTH_HIGH, width_high); 753 ret = reg_write16(client, REG_WINDOW_START_Y_HIGH, start_y);
716 if (!ret) 754 if (!ret) {
717 ret = reg_write(client, REG_WINDOW_WIDTH_LOW , width_low); 755 priv->crop_rect.left = start_x;
718 if (!ret) 756 priv->crop_rect.top = start_y;
719 ret = reg_write(client, REG_WINDOW_HEIGHT_HIGH, height_high); 757 }
720 if (!ret)
721 ret = reg_write(client, REG_WINDOW_HEIGHT_LOW, height_low);
722 758
723 if (!ret) 759 if (!ret)
724 ret = reg_write(client, REG_OUT_WIDTH_HIGH, width_high); 760 ret = reg_write16(client, REG_WINDOW_WIDTH_HIGH, width);
725 if (!ret) 761 if (!ret)
726 ret = reg_write(client, REG_OUT_WIDTH_LOW , width_low); 762 ret = reg_write16(client, REG_WINDOW_HEIGHT_HIGH, height);
727 if (!ret) 763 if (ret)
728 ret = reg_write(client, REG_OUT_HEIGHT_HIGH, height_high); 764 return ret;
765 priv->crop_rect.width = width;
766 priv->crop_rect.height = height;
767
768 /* Set the output window size. Only 1:1 scale is supported so far. */
769 ret = reg_write16(client, REG_OUT_WIDTH_HIGH, width);
729 if (!ret) 770 if (!ret)
730 ret = reg_write(client, REG_OUT_HEIGHT_LOW, height_low); 771 ret = reg_write16(client, REG_OUT_HEIGHT_HIGH, height);
731 772
773 /* Total width = output size + blanking */
732 if (!ret) 774 if (!ret)
733 ret = reg_write(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width_high); 775 ret = reg_write16(client, REG_OUT_TOTAL_WIDTH_HIGH, total_width);
734 if (!ret) 776 if (!ret)
735 ret = reg_write(client, REG_OUT_TOTAL_WIDTH_LOW, total_width_low); 777 ret = reg_write16(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height);
778
779 /* Sets the window for AWB calculations */
736 if (!ret) 780 if (!ret)
737 ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_HIGH, total_height_high); 781 ret = reg_write16(client, REG_AVG_WINDOW_END_X_HIGH, width);
738 if (!ret) 782 if (!ret)
739 ret = reg_write(client, REG_OUT_TOTAL_HEIGHT_LOW, total_height_low); 783 ret = reg_write16(client, REG_AVG_WINDOW_END_Y_HIGH, height);
740 784
741 return ret; 785 return ret;
742} 786}
@@ -744,18 +788,18 @@ static int ov5642_set_resolution(struct i2c_client *client)
744static int ov5642_try_fmt(struct v4l2_subdev *sd, 788static int ov5642_try_fmt(struct v4l2_subdev *sd,
745 struct v4l2_mbus_framefmt *mf) 789 struct v4l2_mbus_framefmt *mf)
746{ 790{
791 struct i2c_client *client = v4l2_get_subdevdata(sd);
792 struct ov5642 *priv = to_ov5642(client);
747 const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code); 793 const struct ov5642_datafmt *fmt = ov5642_find_datafmt(mf->code);
748 794
749 dev_dbg(sd->v4l2_dev->dev, "%s(%u) width: %u heigth: %u\n", 795 mf->width = priv->crop_rect.width;
750 __func__, mf->code, mf->width, mf->height); 796 mf->height = priv->crop_rect.height;
751 797
752 if (!fmt) { 798 if (!fmt) {
753 mf->code = ov5642_colour_fmts[0].code; 799 mf->code = ov5642_colour_fmts[0].code;
754 mf->colorspace = ov5642_colour_fmts[0].colorspace; 800 mf->colorspace = ov5642_colour_fmts[0].colorspace;
755 } 801 }
756 802
757 mf->width = OV5642_WIDTH;
758 mf->height = OV5642_HEIGHT;
759 mf->field = V4L2_FIELD_NONE; 803 mf->field = V4L2_FIELD_NONE;
760 804
761 return 0; 805 return 0;
@@ -767,20 +811,13 @@ static int ov5642_s_fmt(struct v4l2_subdev *sd,
767 struct i2c_client *client = v4l2_get_subdevdata(sd); 811 struct i2c_client *client = v4l2_get_subdevdata(sd);
768 struct ov5642 *priv = to_ov5642(client); 812 struct ov5642 *priv = to_ov5642(client);
769 813
770 dev_dbg(sd->v4l2_dev->dev, "%s(%u)\n", __func__, mf->code);
771
772 /* MIPI CSI could have changed the format, double-check */ 814 /* MIPI CSI could have changed the format, double-check */
773 if (!ov5642_find_datafmt(mf->code)) 815 if (!ov5642_find_datafmt(mf->code))
774 return -EINVAL; 816 return -EINVAL;
775 817
776 ov5642_try_fmt(sd, mf); 818 ov5642_try_fmt(sd, mf);
777
778 priv->fmt = ov5642_find_datafmt(mf->code); 819 priv->fmt = ov5642_find_datafmt(mf->code);
779 820
780 ov5642_write_array(client, ov5642_default_regs_init);
781 ov5642_set_resolution(client);
782 ov5642_write_array(client, ov5642_default_regs_finalise);
783
784 return 0; 821 return 0;
785} 822}
786 823
@@ -794,8 +831,8 @@ static int ov5642_g_fmt(struct v4l2_subdev *sd,
794 831
795 mf->code = fmt->code; 832 mf->code = fmt->code;
796 mf->colorspace = fmt->colorspace; 833 mf->colorspace = fmt->colorspace;
797 mf->width = OV5642_WIDTH; 834 mf->width = priv->crop_rect.width;
798 mf->height = OV5642_HEIGHT; 835 mf->height = priv->crop_rect.height;
799 mf->field = V4L2_FIELD_NONE; 836 mf->field = V4L2_FIELD_NONE;
800 837
801 return 0; 838 return 0;
@@ -828,15 +865,44 @@ static int ov5642_g_chip_ident(struct v4l2_subdev *sd,
828 return 0; 865 return 0;
829} 866}
830 867
868static int ov5642_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
869{
870 struct i2c_client *client = v4l2_get_subdevdata(sd);
871 struct ov5642 *priv = to_ov5642(client);
872 struct v4l2_rect *rect = &a->c;
873 int ret;
874
875 v4l_bound_align_image(&rect->width, 48, OV5642_MAX_WIDTH, 1,
876 &rect->height, 32, OV5642_MAX_HEIGHT, 1, 0);
877
878 priv->crop_rect.width = rect->width;
879 priv->crop_rect.height = rect->height;
880 priv->total_width = rect->width + BLANKING_EXTRA_WIDTH;
881 priv->total_height = max_t(int, rect->height +
882 BLANKING_EXTRA_HEIGHT,
883 BLANKING_MIN_HEIGHT);
884 priv->crop_rect.width = rect->width;
885 priv->crop_rect.height = rect->height;
886
887 ret = ov5642_write_array(client, ov5642_default_regs_init);
888 if (!ret)
889 ret = ov5642_set_resolution(sd);
890 if (!ret)
891 ret = ov5642_write_array(client, ov5642_default_regs_finalise);
892
893 return ret;
894}
895
831static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 896static int ov5642_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
832{ 897{
898 struct i2c_client *client = v4l2_get_subdevdata(sd);
899 struct ov5642 *priv = to_ov5642(client);
833 struct v4l2_rect *rect = &a->c; 900 struct v4l2_rect *rect = &a->c;
834 901
835 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 902 if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
836 rect->top = 0; 903 return -EINVAL;
837 rect->left = 0; 904
838 rect->width = OV5642_WIDTH; 905 *rect = priv->crop_rect;
839 rect->height = OV5642_HEIGHT;
840 906
841 return 0; 907 return 0;
842} 908}
@@ -845,8 +911,8 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
845{ 911{
846 a->bounds.left = 0; 912 a->bounds.left = 0;
847 a->bounds.top = 0; 913 a->bounds.top = 0;
848 a->bounds.width = OV5642_WIDTH; 914 a->bounds.width = OV5642_MAX_WIDTH;
849 a->bounds.height = OV5642_HEIGHT; 915 a->bounds.height = OV5642_MAX_HEIGHT;
850 a->defrect = a->bounds; 916 a->defrect = a->bounds;
851 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 917 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
852 a->pixelaspect.numerator = 1; 918 a->pixelaspect.numerator = 1;
@@ -855,16 +921,47 @@ static int ov5642_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
855 return 0; 921 return 0;
856} 922}
857 923
924static int ov5642_g_mbus_config(struct v4l2_subdev *sd,
925 struct v4l2_mbus_config *cfg)
926{
927 cfg->type = V4L2_MBUS_CSI2;
928 cfg->flags = V4L2_MBUS_CSI2_2_LANE | V4L2_MBUS_CSI2_CHANNEL_0 |
929 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
930
931 return 0;
932}
933
934static int ov5642_s_power(struct v4l2_subdev *sd, int on)
935{
936 struct i2c_client *client;
937 int ret;
938
939 if (!on)
940 return 0;
941
942 client = v4l2_get_subdevdata(sd);
943 ret = ov5642_write_array(client, ov5642_default_regs_init);
944 if (!ret)
945 ret = ov5642_set_resolution(sd);
946 if (!ret)
947 ret = ov5642_write_array(client, ov5642_default_regs_finalise);
948
949 return ret;
950}
951
858static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = { 952static struct v4l2_subdev_video_ops ov5642_subdev_video_ops = {
859 .s_mbus_fmt = ov5642_s_fmt, 953 .s_mbus_fmt = ov5642_s_fmt,
860 .g_mbus_fmt = ov5642_g_fmt, 954 .g_mbus_fmt = ov5642_g_fmt,
861 .try_mbus_fmt = ov5642_try_fmt, 955 .try_mbus_fmt = ov5642_try_fmt,
862 .enum_mbus_fmt = ov5642_enum_fmt, 956 .enum_mbus_fmt = ov5642_enum_fmt,
957 .s_crop = ov5642_s_crop,
863 .g_crop = ov5642_g_crop, 958 .g_crop = ov5642_g_crop,
864 .cropcap = ov5642_cropcap, 959 .cropcap = ov5642_cropcap,
960 .g_mbus_config = ov5642_g_mbus_config,
865}; 961};
866 962
867static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = { 963static struct v4l2_subdev_core_ops ov5642_subdev_core_ops = {
964 .s_power = ov5642_s_power,
868 .g_chip_ident = ov5642_g_chip_ident, 965 .g_chip_ident = ov5642_g_chip_ident,
869#ifdef CONFIG_VIDEO_ADV_DEBUG 966#ifdef CONFIG_VIDEO_ADV_DEBUG
870 .g_register = ov5642_get_register, 967 .g_register = ov5642_get_register,
@@ -877,28 +974,7 @@ static struct v4l2_subdev_ops ov5642_subdev_ops = {
877 .video = &ov5642_subdev_video_ops, 974 .video = &ov5642_subdev_video_ops,
878}; 975};
879 976
880/* 977static int ov5642_video_probe(struct i2c_client *client)
881 * We have to provide soc-camera operations, but we don't have anything to say
882 * there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
883 */
884static unsigned long soc_ov5642_query_bus_param(struct soc_camera_device *icd)
885{
886 return 0;
887}
888
889static int soc_ov5642_set_bus_param(struct soc_camera_device *icd,
890 unsigned long flags)
891{
892 return -EINVAL;
893}
894
895static struct soc_camera_ops soc_ov5642_ops = {
896 .query_bus_param = soc_ov5642_query_bus_param,
897 .set_bus_param = soc_ov5642_set_bus_param,
898};
899
900static int ov5642_video_probe(struct soc_camera_device *icd,
901 struct i2c_client *client)
902{ 978{
903 int ret; 979 int ret;
904 u8 id_high, id_low; 980 u8 id_high, id_low;
@@ -929,16 +1005,9 @@ static int ov5642_probe(struct i2c_client *client,
929 const struct i2c_device_id *did) 1005 const struct i2c_device_id *did)
930{ 1006{
931 struct ov5642 *priv; 1007 struct ov5642 *priv;
932 struct soc_camera_device *icd = client->dev.platform_data; 1008 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
933 struct soc_camera_link *icl;
934 int ret; 1009 int ret;
935 1010
936 if (!icd) {
937 dev_err(&client->dev, "OV5642: missing soc-camera data!\n");
938 return -EINVAL;
939 }
940
941 icl = to_soc_camera_link(icd);
942 if (!icl) { 1011 if (!icl) {
943 dev_err(&client->dev, "OV5642: missing platform data!\n"); 1012 dev_err(&client->dev, "OV5642: missing platform data!\n");
944 return -EINVAL; 1013 return -EINVAL;
@@ -950,17 +1019,24 @@ static int ov5642_probe(struct i2c_client *client,
950 1019
951 v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops); 1020 v4l2_i2c_subdev_init(&priv->subdev, client, &ov5642_subdev_ops);
952 1021
953 icd->ops = &soc_ov5642_ops; 1022 priv->fmt = &ov5642_colour_fmts[0];
954 priv->fmt = &ov5642_colour_fmts[0]; 1023
1024 priv->crop_rect.width = OV5642_DEFAULT_WIDTH;
1025 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
1026 priv->crop_rect.left = (OV5642_MAX_WIDTH - OV5642_DEFAULT_WIDTH) / 2;
1027 priv->crop_rect.top = (OV5642_MAX_HEIGHT - OV5642_DEFAULT_HEIGHT) / 2;
1028 priv->crop_rect.width = OV5642_DEFAULT_WIDTH;
1029 priv->crop_rect.height = OV5642_DEFAULT_HEIGHT;
1030 priv->total_width = OV5642_DEFAULT_WIDTH + BLANKING_EXTRA_WIDTH;
1031 priv->total_height = BLANKING_MIN_HEIGHT;
955 1032
956 ret = ov5642_video_probe(icd, client); 1033 ret = ov5642_video_probe(client);
957 if (ret < 0) 1034 if (ret < 0)
958 goto error; 1035 goto error;
959 1036
960 return 0; 1037 return 0;
961 1038
962error: 1039error:
963 icd->ops = NULL;
964 kfree(priv); 1040 kfree(priv);
965 return ret; 1041 return ret;
966} 1042}
@@ -968,10 +1044,8 @@ error:
968static int ov5642_remove(struct i2c_client *client) 1044static int ov5642_remove(struct i2c_client *client)
969{ 1045{
970 struct ov5642 *priv = to_ov5642(client); 1046 struct ov5642 *priv = to_ov5642(client);
971 struct soc_camera_device *icd = client->dev.platform_data; 1047 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
972 struct soc_camera_link *icl = to_soc_camera_link(icd);
973 1048
974 icd->ops = NULL;
975 if (icl->free_bus) 1049 if (icl->free_bus)
976 icl->free_bus(icl); 1050 icl->free_bus(icl);
977 kfree(priv); 1051 kfree(priv);
diff --git a/drivers/media/video/ov6650.c b/drivers/media/video/ov6650.c
index 456d9ad9ae5..d5b057207a7 100644
--- a/drivers/media/video/ov6650.c
+++ b/drivers/media/video/ov6650.c
@@ -28,10 +28,11 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/i2c.h> 29#include <linux/i2c.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31#include <linux/v4l2-mediabus.h>
31 32
32#include <media/soc_camera.h> 33#include <media/soc_camera.h>
33#include <media/v4l2-chip-ident.h> 34#include <media/v4l2-chip-ident.h>
34 35#include <media/v4l2-ctrls.h>
35 36
36/* Register definitions */ 37/* Register definitions */
37#define REG_GAIN 0x00 /* range 00 - 3F */ 38#define REG_GAIN 0x00 /* range 00 - 3F */
@@ -177,20 +178,23 @@ struct ov6650_reg {
177 178
178struct ov6650 { 179struct ov6650 {
179 struct v4l2_subdev subdev; 180 struct v4l2_subdev subdev;
180 181 struct v4l2_ctrl_handler hdl;
181 int gain; 182 struct {
182 int blue; 183 /* exposure/autoexposure cluster */
183 int red; 184 struct v4l2_ctrl *autoexposure;
184 int saturation; 185 struct v4l2_ctrl *exposure;
185 int hue; 186 };
186 int brightness; 187 struct {
187 int exposure; 188 /* gain/autogain cluster */
188 int gamma; 189 struct v4l2_ctrl *autogain;
189 int aec; 190 struct v4l2_ctrl *gain;
190 bool vflip; 191 };
191 bool hflip; 192 struct {
192 bool awb; 193 /* blue/red/autowhitebalance cluster */
193 bool agc; 194 struct v4l2_ctrl *autowb;
195 struct v4l2_ctrl *blue;
196 struct v4l2_ctrl *red;
197 };
194 bool half_scale; /* scale down output by 2 */ 198 bool half_scale; /* scale down output by 2 */
195 struct v4l2_rect rect; /* sensor cropping window */ 199 struct v4l2_rect rect; /* sensor cropping window */
196 unsigned long pclk_limit; /* from host */ 200 unsigned long pclk_limit; /* from host */
@@ -210,126 +214,6 @@ static enum v4l2_mbus_pixelcode ov6650_codes[] = {
210 V4L2_MBUS_FMT_Y8_1X8, 214 V4L2_MBUS_FMT_Y8_1X8,
211}; 215};
212 216
213static const struct v4l2_queryctrl ov6650_controls[] = {
214 {
215 .id = V4L2_CID_AUTOGAIN,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "AGC",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221 .default_value = 1,
222 },
223 {
224 .id = V4L2_CID_GAIN,
225 .type = V4L2_CTRL_TYPE_INTEGER,
226 .name = "Gain",
227 .minimum = 0,
228 .maximum = 0x3f,
229 .step = 1,
230 .default_value = DEF_GAIN,
231 },
232 {
233 .id = V4L2_CID_AUTO_WHITE_BALANCE,
234 .type = V4L2_CTRL_TYPE_BOOLEAN,
235 .name = "AWB",
236 .minimum = 0,
237 .maximum = 1,
238 .step = 1,
239 .default_value = 1,
240 },
241 {
242 .id = V4L2_CID_BLUE_BALANCE,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "Blue",
245 .minimum = 0,
246 .maximum = 0xff,
247 .step = 1,
248 .default_value = DEF_BLUE,
249 },
250 {
251 .id = V4L2_CID_RED_BALANCE,
252 .type = V4L2_CTRL_TYPE_INTEGER,
253 .name = "Red",
254 .minimum = 0,
255 .maximum = 0xff,
256 .step = 1,
257 .default_value = DEF_RED,
258 },
259 {
260 .id = V4L2_CID_SATURATION,
261 .type = V4L2_CTRL_TYPE_INTEGER,
262 .name = "Saturation",
263 .minimum = 0,
264 .maximum = 0xf,
265 .step = 1,
266 .default_value = 0x8,
267 },
268 {
269 .id = V4L2_CID_HUE,
270 .type = V4L2_CTRL_TYPE_INTEGER,
271 .name = "Hue",
272 .minimum = 0,
273 .maximum = HUE_MASK,
274 .step = 1,
275 .default_value = DEF_HUE,
276 },
277 {
278 .id = V4L2_CID_BRIGHTNESS,
279 .type = V4L2_CTRL_TYPE_INTEGER,
280 .name = "Brightness",
281 .minimum = 0,
282 .maximum = 0xff,
283 .step = 1,
284 .default_value = 0x80,
285 },
286 {
287 .id = V4L2_CID_EXPOSURE_AUTO,
288 .type = V4L2_CTRL_TYPE_INTEGER,
289 .name = "AEC",
290 .minimum = 0,
291 .maximum = 3,
292 .step = 1,
293 .default_value = 0,
294 },
295 {
296 .id = V4L2_CID_EXPOSURE,
297 .type = V4L2_CTRL_TYPE_INTEGER,
298 .name = "Exposure",
299 .minimum = 0,
300 .maximum = 0xff,
301 .step = 1,
302 .default_value = DEF_AECH,
303 },
304 {
305 .id = V4L2_CID_GAMMA,
306 .type = V4L2_CTRL_TYPE_INTEGER,
307 .name = "Gamma",
308 .minimum = 0,
309 .maximum = 0xff,
310 .step = 1,
311 .default_value = 0x12,
312 },
313 {
314 .id = V4L2_CID_VFLIP,
315 .type = V4L2_CTRL_TYPE_BOOLEAN,
316 .name = "Flip Vertically",
317 .minimum = 0,
318 .maximum = 1,
319 .step = 1,
320 .default_value = 0,
321 },
322 {
323 .id = V4L2_CID_HFLIP,
324 .type = V4L2_CTRL_TYPE_BOOLEAN,
325 .name = "Flip Horizontally",
326 .minimum = 0,
327 .maximum = 1,
328 .step = 1,
329 .default_value = 0,
330 },
331};
332
333/* read a register */ 217/* read a register */
334static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val) 218static int ov6650_reg_read(struct i2c_client *client, u8 reg, u8 *val)
335{ 219{
@@ -419,213 +303,90 @@ static int ov6650_s_stream(struct v4l2_subdev *sd, int enable)
419 return 0; 303 return 0;
420} 304}
421 305
422/* Alter bus settings on camera side */
423static int ov6650_set_bus_param(struct soc_camera_device *icd,
424 unsigned long flags)
425{
426 struct soc_camera_link *icl = to_soc_camera_link(icd);
427 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
428 int ret;
429
430 flags = soc_camera_apply_sensor_flags(icl, flags);
431
432 if (flags & SOCAM_PCLK_SAMPLE_RISING)
433 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
434 else
435 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
436 if (ret)
437 return ret;
438
439 if (flags & SOCAM_HSYNC_ACTIVE_LOW)
440 ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
441 else
442 ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
443 if (ret)
444 return ret;
445
446 if (flags & SOCAM_VSYNC_ACTIVE_HIGH)
447 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
448 else
449 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
450
451 return ret;
452}
453
454/* Request bus settings on camera side */
455static unsigned long ov6650_query_bus_param(struct soc_camera_device *icd)
456{
457 struct soc_camera_link *icl = to_soc_camera_link(icd);
458
459 unsigned long flags = SOCAM_MASTER |
460 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
461 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW |
462 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW |
463 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
464
465 return soc_camera_apply_sensor_flags(icl, flags);
466}
467
468/* Get status of additional camera capabilities */ 306/* Get status of additional camera capabilities */
469static int ov6650_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 307static int ov6550_g_volatile_ctrl(struct v4l2_ctrl *ctrl)
470{ 308{
309 struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
310 struct v4l2_subdev *sd = &priv->subdev;
471 struct i2c_client *client = v4l2_get_subdevdata(sd); 311 struct i2c_client *client = v4l2_get_subdevdata(sd);
472 struct ov6650 *priv = to_ov6650(client); 312 uint8_t reg, reg2;
473 uint8_t reg; 313 int ret;
474 int ret = 0;
475 314
476 switch (ctrl->id) { 315 switch (ctrl->id) {
477 case V4L2_CID_AUTOGAIN: 316 case V4L2_CID_AUTOGAIN:
478 ctrl->value = priv->agc; 317 ret = ov6650_reg_read(client, REG_GAIN, &reg);
479 break; 318 if (!ret)
480 case V4L2_CID_GAIN: 319 priv->gain->val = reg;
481 if (priv->agc) { 320 return ret;
482 ret = ov6650_reg_read(client, REG_GAIN, &reg);
483 ctrl->value = reg;
484 } else {
485 ctrl->value = priv->gain;
486 }
487 break;
488 case V4L2_CID_AUTO_WHITE_BALANCE: 321 case V4L2_CID_AUTO_WHITE_BALANCE:
489 ctrl->value = priv->awb; 322 ret = ov6650_reg_read(client, REG_BLUE, &reg);
490 break; 323 if (!ret)
491 case V4L2_CID_BLUE_BALANCE: 324 ret = ov6650_reg_read(client, REG_RED, &reg2);
492 if (priv->awb) { 325 if (!ret) {
493 ret = ov6650_reg_read(client, REG_BLUE, &reg); 326 priv->blue->val = reg;
494 ctrl->value = reg; 327 priv->red->val = reg2;
495 } else {
496 ctrl->value = priv->blue;
497 }
498 break;
499 case V4L2_CID_RED_BALANCE:
500 if (priv->awb) {
501 ret = ov6650_reg_read(client, REG_RED, &reg);
502 ctrl->value = reg;
503 } else {
504 ctrl->value = priv->red;
505 } 328 }
506 break; 329 return ret;
507 case V4L2_CID_SATURATION:
508 ctrl->value = priv->saturation;
509 break;
510 case V4L2_CID_HUE:
511 ctrl->value = priv->hue;
512 break;
513 case V4L2_CID_BRIGHTNESS:
514 ctrl->value = priv->brightness;
515 break;
516 case V4L2_CID_EXPOSURE_AUTO: 330 case V4L2_CID_EXPOSURE_AUTO:
517 ctrl->value = priv->aec; 331 ret = ov6650_reg_read(client, REG_AECH, &reg);
518 break; 332 if (!ret)
519 case V4L2_CID_EXPOSURE: 333 priv->exposure->val = reg;
520 if (priv->aec) { 334 return ret;
521 ret = ov6650_reg_read(client, REG_AECH, &reg);
522 ctrl->value = reg;
523 } else {
524 ctrl->value = priv->exposure;
525 }
526 break;
527 case V4L2_CID_GAMMA:
528 ctrl->value = priv->gamma;
529 break;
530 case V4L2_CID_VFLIP:
531 ctrl->value = priv->vflip;
532 break;
533 case V4L2_CID_HFLIP:
534 ctrl->value = priv->hflip;
535 break;
536 } 335 }
537 return ret; 336 return -EINVAL;
538} 337}
539 338
540/* Set status of additional camera capabilities */ 339/* Set status of additional camera capabilities */
541static int ov6650_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 340static int ov6550_s_ctrl(struct v4l2_ctrl *ctrl)
542{ 341{
342 struct ov6650 *priv = container_of(ctrl->handler, struct ov6650, hdl);
343 struct v4l2_subdev *sd = &priv->subdev;
543 struct i2c_client *client = v4l2_get_subdevdata(sd); 344 struct i2c_client *client = v4l2_get_subdevdata(sd);
544 struct ov6650 *priv = to_ov6650(client); 345 int ret;
545 int ret = 0;
546 346
547 switch (ctrl->id) { 347 switch (ctrl->id) {
548 case V4L2_CID_AUTOGAIN: 348 case V4L2_CID_AUTOGAIN:
549 ret = ov6650_reg_rmw(client, REG_COMB, 349 ret = ov6650_reg_rmw(client, REG_COMB,
550 ctrl->value ? COMB_AGC : 0, COMB_AGC); 350 ctrl->val ? COMB_AGC : 0, COMB_AGC);
551 if (!ret) 351 if (!ret && !ctrl->val)
552 priv->agc = ctrl->value; 352 ret = ov6650_reg_write(client, REG_GAIN, priv->gain->val);
553 break; 353 return ret;
554 case V4L2_CID_GAIN:
555 ret = ov6650_reg_write(client, REG_GAIN, ctrl->value);
556 if (!ret)
557 priv->gain = ctrl->value;
558 break;
559 case V4L2_CID_AUTO_WHITE_BALANCE: 354 case V4L2_CID_AUTO_WHITE_BALANCE:
560 ret = ov6650_reg_rmw(client, REG_COMB, 355 ret = ov6650_reg_rmw(client, REG_COMB,
561 ctrl->value ? COMB_AWB : 0, COMB_AWB); 356 ctrl->val ? COMB_AWB : 0, COMB_AWB);
562 if (!ret) 357 if (!ret && !ctrl->val) {
563 priv->awb = ctrl->value; 358 ret = ov6650_reg_write(client, REG_BLUE, priv->blue->val);
564 break; 359 if (!ret)
565 case V4L2_CID_BLUE_BALANCE: 360 ret = ov6650_reg_write(client, REG_RED,
566 ret = ov6650_reg_write(client, REG_BLUE, ctrl->value); 361 priv->red->val);
567 if (!ret) 362 }
568 priv->blue = ctrl->value; 363 return ret;
569 break;
570 case V4L2_CID_RED_BALANCE:
571 ret = ov6650_reg_write(client, REG_RED, ctrl->value);
572 if (!ret)
573 priv->red = ctrl->value;
574 break;
575 case V4L2_CID_SATURATION: 364 case V4L2_CID_SATURATION:
576 ret = ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->value), 365 return ov6650_reg_rmw(client, REG_SAT, SET_SAT(ctrl->val),
577 SAT_MASK); 366 SAT_MASK);
578 if (!ret)
579 priv->saturation = ctrl->value;
580 break;
581 case V4L2_CID_HUE: 367 case V4L2_CID_HUE:
582 ret = ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->value), 368 return ov6650_reg_rmw(client, REG_HUE, SET_HUE(ctrl->val),
583 HUE_MASK); 369 HUE_MASK);
584 if (!ret)
585 priv->hue = ctrl->value;
586 break;
587 case V4L2_CID_BRIGHTNESS: 370 case V4L2_CID_BRIGHTNESS:
588 ret = ov6650_reg_write(client, REG_BRT, ctrl->value); 371 return ov6650_reg_write(client, REG_BRT, ctrl->val);
589 if (!ret)
590 priv->brightness = ctrl->value;
591 break;
592 case V4L2_CID_EXPOSURE_AUTO: 372 case V4L2_CID_EXPOSURE_AUTO:
593 switch (ctrl->value) { 373 ret = ov6650_reg_rmw(client, REG_COMB, ctrl->val ==
594 case V4L2_EXPOSURE_AUTO: 374 V4L2_EXPOSURE_AUTO ? COMB_AEC : 0, COMB_AEC);
595 ret = ov6650_reg_rmw(client, REG_COMB, COMB_AEC, 0); 375 if (!ret && ctrl->val == V4L2_EXPOSURE_MANUAL)
596 break; 376 ret = ov6650_reg_write(client, REG_AECH,
597 default: 377 priv->exposure->val);
598 ret = ov6650_reg_rmw(client, REG_COMB, 0, COMB_AEC); 378 return ret;
599 break;
600 }
601 if (!ret)
602 priv->aec = ctrl->value;
603 break;
604 case V4L2_CID_EXPOSURE:
605 ret = ov6650_reg_write(client, REG_AECH, ctrl->value);
606 if (!ret)
607 priv->exposure = ctrl->value;
608 break;
609 case V4L2_CID_GAMMA: 379 case V4L2_CID_GAMMA:
610 ret = ov6650_reg_write(client, REG_GAM1, ctrl->value); 380 return ov6650_reg_write(client, REG_GAM1, ctrl->val);
611 if (!ret)
612 priv->gamma = ctrl->value;
613 break;
614 case V4L2_CID_VFLIP: 381 case V4L2_CID_VFLIP:
615 ret = ov6650_reg_rmw(client, REG_COMB, 382 return ov6650_reg_rmw(client, REG_COMB,
616 ctrl->value ? COMB_FLIP_V : 0, COMB_FLIP_V); 383 ctrl->val ? COMB_FLIP_V : 0, COMB_FLIP_V);
617 if (!ret)
618 priv->vflip = ctrl->value;
619 break;
620 case V4L2_CID_HFLIP: 384 case V4L2_CID_HFLIP:
621 ret = ov6650_reg_rmw(client, REG_COMB, 385 return ov6650_reg_rmw(client, REG_COMB,
622 ctrl->value ? COMB_FLIP_H : 0, COMB_FLIP_H); 386 ctrl->val ? COMB_FLIP_H : 0, COMB_FLIP_H);
623 if (!ret)
624 priv->hflip = ctrl->value;
625 break;
626 } 387 }
627 388
628 return ret; 389 return -EINVAL;
629} 390}
630 391
631/* Get chip identification */ 392/* Get chip identification */
@@ -778,7 +539,7 @@ static u8 to_clkrc(struct v4l2_fract *timeperframe,
778static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf) 539static int ov6650_s_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *mf)
779{ 540{
780 struct i2c_client *client = v4l2_get_subdevdata(sd); 541 struct i2c_client *client = v4l2_get_subdevdata(sd);
781 struct soc_camera_device *icd = client->dev.platform_data; 542 struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
782 struct soc_camera_sense *sense = icd->sense; 543 struct soc_camera_sense *sense = icd->sense;
783 struct ov6650 *priv = to_ov6650(client); 544 struct ov6650 *priv = to_ov6650(client);
784 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect); 545 bool half_scale = !is_unscaled_ok(mf->width, mf->height, &priv->rect);
@@ -1057,8 +818,7 @@ static int ov6650_prog_dflt(struct i2c_client *client)
1057 return ret; 818 return ret;
1058} 819}
1059 820
1060static int ov6650_video_probe(struct soc_camera_device *icd, 821static int ov6650_video_probe(struct i2c_client *client)
1061 struct i2c_client *client)
1062{ 822{
1063 u8 pidh, pidl, midh, midl; 823 u8 pidh, pidl, midh, midl;
1064 int ret = 0; 824 int ret = 0;
@@ -1094,16 +854,12 @@ static int ov6650_video_probe(struct soc_camera_device *icd,
1094 return ret; 854 return ret;
1095} 855}
1096 856
1097static struct soc_camera_ops ov6650_ops = { 857static const struct v4l2_ctrl_ops ov6550_ctrl_ops = {
1098 .set_bus_param = ov6650_set_bus_param, 858 .g_volatile_ctrl = ov6550_g_volatile_ctrl,
1099 .query_bus_param = ov6650_query_bus_param, 859 .s_ctrl = ov6550_s_ctrl,
1100 .controls = ov6650_controls,
1101 .num_controls = ARRAY_SIZE(ov6650_controls),
1102}; 860};
1103 861
1104static struct v4l2_subdev_core_ops ov6650_core_ops = { 862static struct v4l2_subdev_core_ops ov6650_core_ops = {
1105 .g_ctrl = ov6650_g_ctrl,
1106 .s_ctrl = ov6650_s_ctrl,
1107 .g_chip_ident = ov6650_g_chip_ident, 863 .g_chip_ident = ov6650_g_chip_ident,
1108#ifdef CONFIG_VIDEO_ADV_DEBUG 864#ifdef CONFIG_VIDEO_ADV_DEBUG
1109 .g_register = ov6650_get_register, 865 .g_register = ov6650_get_register,
@@ -1111,6 +867,55 @@ static struct v4l2_subdev_core_ops ov6650_core_ops = {
1111#endif 867#endif
1112}; 868};
1113 869
870/* Request bus settings on camera side */
871static int ov6650_g_mbus_config(struct v4l2_subdev *sd,
872 struct v4l2_mbus_config *cfg)
873{
874 struct i2c_client *client = v4l2_get_subdevdata(sd);
875 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
876
877 cfg->flags = V4L2_MBUS_MASTER |
878 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
879 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
880 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
881 V4L2_MBUS_DATA_ACTIVE_HIGH;
882 cfg->type = V4L2_MBUS_PARALLEL;
883 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
884
885 return 0;
886}
887
888/* Alter bus settings on camera side */
889static int ov6650_s_mbus_config(struct v4l2_subdev *sd,
890 const struct v4l2_mbus_config *cfg)
891{
892 struct i2c_client *client = v4l2_get_subdevdata(sd);
893 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
894 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
895 int ret;
896
897 if (flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
898 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_PCLK_RISING, 0);
899 else
900 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_PCLK_RISING);
901 if (ret)
902 return ret;
903
904 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
905 ret = ov6650_reg_rmw(client, REG_COMF, COMF_HREF_LOW, 0);
906 else
907 ret = ov6650_reg_rmw(client, REG_COMF, 0, COMF_HREF_LOW);
908 if (ret)
909 return ret;
910
911 if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
912 ret = ov6650_reg_rmw(client, REG_COMJ, COMJ_VSYNC_HIGH, 0);
913 else
914 ret = ov6650_reg_rmw(client, REG_COMJ, 0, COMJ_VSYNC_HIGH);
915
916 return ret;
917}
918
1114static struct v4l2_subdev_video_ops ov6650_video_ops = { 919static struct v4l2_subdev_video_ops ov6650_video_ops = {
1115 .s_stream = ov6650_s_stream, 920 .s_stream = ov6650_s_stream,
1116 .g_mbus_fmt = ov6650_g_fmt, 921 .g_mbus_fmt = ov6650_g_fmt,
@@ -1122,6 +927,8 @@ static struct v4l2_subdev_video_ops ov6650_video_ops = {
1122 .s_crop = ov6650_s_crop, 927 .s_crop = ov6650_s_crop,
1123 .g_parm = ov6650_g_parm, 928 .g_parm = ov6650_g_parm,
1124 .s_parm = ov6650_s_parm, 929 .s_parm = ov6650_s_parm,
930 .g_mbus_config = ov6650_g_mbus_config,
931 .s_mbus_config = ov6650_s_mbus_config,
1125}; 932};
1126 933
1127static struct v4l2_subdev_ops ov6650_subdev_ops = { 934static struct v4l2_subdev_ops ov6650_subdev_ops = {
@@ -1136,16 +943,9 @@ static int ov6650_probe(struct i2c_client *client,
1136 const struct i2c_device_id *did) 943 const struct i2c_device_id *did)
1137{ 944{
1138 struct ov6650 *priv; 945 struct ov6650 *priv;
1139 struct soc_camera_device *icd = client->dev.platform_data; 946 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1140 struct soc_camera_link *icl;
1141 int ret; 947 int ret;
1142 948
1143 if (!icd) {
1144 dev_err(&client->dev, "Missing soc-camera data!\n");
1145 return -EINVAL;
1146 }
1147
1148 icl = to_soc_camera_link(icd);
1149 if (!icl) { 949 if (!icl) {
1150 dev_err(&client->dev, "Missing platform_data for driver\n"); 950 dev_err(&client->dev, "Missing platform_data for driver\n");
1151 return -EINVAL; 951 return -EINVAL;
@@ -1159,8 +959,46 @@ static int ov6650_probe(struct i2c_client *client,
1159 } 959 }
1160 960
1161 v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops); 961 v4l2_i2c_subdev_init(&priv->subdev, client, &ov6650_subdev_ops);
962 v4l2_ctrl_handler_init(&priv->hdl, 13);
963 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
964 V4L2_CID_VFLIP, 0, 1, 1, 0);
965 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
966 V4L2_CID_HFLIP, 0, 1, 1, 0);
967 priv->autogain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
968 V4L2_CID_AUTOGAIN, 0, 1, 1, 1);
969 priv->gain = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
970 V4L2_CID_GAIN, 0, 0x3f, 1, DEF_GAIN);
971 priv->autowb = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
972 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
973 priv->blue = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
974 V4L2_CID_BLUE_BALANCE, 0, 0xff, 1, DEF_BLUE);
975 priv->red = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
976 V4L2_CID_RED_BALANCE, 0, 0xff, 1, DEF_RED);
977 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
978 V4L2_CID_SATURATION, 0, 0xf, 1, 0x8);
979 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
980 V4L2_CID_HUE, 0, HUE_MASK, 1, DEF_HUE);
981 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
982 V4L2_CID_BRIGHTNESS, 0, 0xff, 1, 0x80);
983 priv->autoexposure = v4l2_ctrl_new_std_menu(&priv->hdl,
984 &ov6550_ctrl_ops, V4L2_CID_EXPOSURE_AUTO,
985 V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
986 priv->exposure = v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
987 V4L2_CID_EXPOSURE, 0, 0xff, 1, DEF_AECH);
988 v4l2_ctrl_new_std(&priv->hdl, &ov6550_ctrl_ops,
989 V4L2_CID_GAMMA, 0, 0xff, 1, 0x12);
990
991 priv->subdev.ctrl_handler = &priv->hdl;
992 if (priv->hdl.error) {
993 int err = priv->hdl.error;
1162 994
1163 icd->ops = &ov6650_ops; 995 kfree(priv);
996 return err;
997 }
998 v4l2_ctrl_auto_cluster(2, &priv->autogain, 0, true);
999 v4l2_ctrl_auto_cluster(3, &priv->autowb, 0, true);
1000 v4l2_ctrl_auto_cluster(2, &priv->autoexposure,
1001 V4L2_EXPOSURE_MANUAL, true);
1164 1002
1165 priv->rect.left = DEF_HSTRT << 1; 1003 priv->rect.left = DEF_HSTRT << 1;
1166 priv->rect.top = DEF_VSTRT << 1; 1004 priv->rect.top = DEF_VSTRT << 1;
@@ -1170,10 +1008,12 @@ static int ov6650_probe(struct i2c_client *client,
1170 priv->code = V4L2_MBUS_FMT_YUYV8_2X8; 1008 priv->code = V4L2_MBUS_FMT_YUYV8_2X8;
1171 priv->colorspace = V4L2_COLORSPACE_JPEG; 1009 priv->colorspace = V4L2_COLORSPACE_JPEG;
1172 1010
1173 ret = ov6650_video_probe(icd, client); 1011 ret = ov6650_video_probe(client);
1012 if (!ret)
1013 ret = v4l2_ctrl_handler_setup(&priv->hdl);
1174 1014
1175 if (ret) { 1015 if (ret) {
1176 icd->ops = NULL; 1016 v4l2_ctrl_handler_free(&priv->hdl);
1177 kfree(priv); 1017 kfree(priv);
1178 } 1018 }
1179 1019
@@ -1184,6 +1024,8 @@ static int ov6650_remove(struct i2c_client *client)
1184{ 1024{
1185 struct ov6650 *priv = to_ov6650(client); 1025 struct ov6650 *priv = to_ov6650(client);
1186 1026
1027 v4l2_device_unregister_subdev(&priv->subdev);
1028 v4l2_ctrl_handler_free(&priv->hdl);
1187 kfree(priv); 1029 kfree(priv);
1188 return 0; 1030 return 0;
1189} 1031}
diff --git a/drivers/media/video/ov772x.c b/drivers/media/video/ov772x.c
index 397870f076c..9f6ce3d8a29 100644
--- a/drivers/media/video/ov772x.c
+++ b/drivers/media/video/ov772x.c
@@ -20,12 +20,14 @@
20#include <linux/i2c.h> 20#include <linux/i2c.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/delay.h> 22#include <linux/delay.h>
23#include <linux/v4l2-mediabus.h>
23#include <linux/videodev2.h> 24#include <linux/videodev2.h>
25
26#include <media/ov772x.h>
27#include <media/soc_camera.h>
28#include <media/v4l2-ctrls.h>
24#include <media/v4l2-chip-ident.h> 29#include <media/v4l2-chip-ident.h>
25#include <media/v4l2-subdev.h> 30#include <media/v4l2-subdev.h>
26#include <media/soc_camera.h>
27#include <media/soc_mediabus.h>
28#include <media/ov772x.h>
29 31
30/* 32/*
31 * register offset 33 * register offset
@@ -400,6 +402,7 @@ struct ov772x_win_size {
400 402
401struct ov772x_priv { 403struct ov772x_priv {
402 struct v4l2_subdev subdev; 404 struct v4l2_subdev subdev;
405 struct v4l2_ctrl_handler hdl;
403 struct ov772x_camera_info *info; 406 struct ov772x_camera_info *info;
404 const struct ov772x_color_format *cfmt; 407 const struct ov772x_color_format *cfmt;
405 const struct ov772x_win_size *win; 408 const struct ov772x_win_size *win;
@@ -517,36 +520,6 @@ static const struct ov772x_win_size ov772x_win_qvga = {
517 .regs = ov772x_qvga_regs, 520 .regs = ov772x_qvga_regs,
518}; 521};
519 522
520static const struct v4l2_queryctrl ov772x_controls[] = {
521 {
522 .id = V4L2_CID_VFLIP,
523 .type = V4L2_CTRL_TYPE_BOOLEAN,
524 .name = "Flip Vertically",
525 .minimum = 0,
526 .maximum = 1,
527 .step = 1,
528 .default_value = 0,
529 },
530 {
531 .id = V4L2_CID_HFLIP,
532 .type = V4L2_CTRL_TYPE_BOOLEAN,
533 .name = "Flip Horizontally",
534 .minimum = 0,
535 .maximum = 1,
536 .step = 1,
537 .default_value = 0,
538 },
539 {
540 .id = V4L2_CID_BAND_STOP_FILTER,
541 .type = V4L2_CTRL_TYPE_INTEGER,
542 .name = "Band-stop filter",
543 .minimum = 0,
544 .maximum = 256,
545 .step = 1,
546 .default_value = 0,
547 },
548};
549
550/* 523/*
551 * general function 524 * general function
552 */ 525 */
@@ -620,75 +593,30 @@ static int ov772x_s_stream(struct v4l2_subdev *sd, int enable)
620 return 0; 593 return 0;
621} 594}
622 595
623static int ov772x_set_bus_param(struct soc_camera_device *icd, 596static int ov772x_s_ctrl(struct v4l2_ctrl *ctrl)
624 unsigned long flags)
625{
626 return 0;
627}
628
629static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
630{
631 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd));
632 struct ov772x_priv *priv = i2c_get_clientdata(client);
633 struct soc_camera_link *icl = to_soc_camera_link(icd);
634 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
635 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
636 SOCAM_DATA_ACTIVE_HIGH;
637
638 if (priv->info->flags & OV772X_FLAG_8BIT)
639 flags |= SOCAM_DATAWIDTH_8;
640 else
641 flags |= SOCAM_DATAWIDTH_10;
642
643 return soc_camera_apply_sensor_flags(icl, flags);
644}
645
646static int ov772x_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
647{
648 struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
649
650 switch (ctrl->id) {
651 case V4L2_CID_VFLIP:
652 ctrl->value = priv->flag_vflip;
653 break;
654 case V4L2_CID_HFLIP:
655 ctrl->value = priv->flag_hflip;
656 break;
657 case V4L2_CID_BAND_STOP_FILTER:
658 ctrl->value = priv->band_filter;
659 break;
660 }
661 return 0;
662}
663
664static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
665{ 597{
598 struct ov772x_priv *priv = container_of(ctrl->handler,
599 struct ov772x_priv, hdl);
600 struct v4l2_subdev *sd = &priv->subdev;
666 struct i2c_client *client = v4l2_get_subdevdata(sd); 601 struct i2c_client *client = v4l2_get_subdevdata(sd);
667 struct ov772x_priv *priv = container_of(sd, struct ov772x_priv, subdev);
668 int ret = 0; 602 int ret = 0;
669 u8 val; 603 u8 val;
670 604
671 switch (ctrl->id) { 605 switch (ctrl->id) {
672 case V4L2_CID_VFLIP: 606 case V4L2_CID_VFLIP:
673 val = ctrl->value ? VFLIP_IMG : 0x00; 607 val = ctrl->val ? VFLIP_IMG : 0x00;
674 priv->flag_vflip = ctrl->value; 608 priv->flag_vflip = ctrl->val;
675 if (priv->info->flags & OV772X_FLAG_VFLIP) 609 if (priv->info->flags & OV772X_FLAG_VFLIP)
676 val ^= VFLIP_IMG; 610 val ^= VFLIP_IMG;
677 ret = ov772x_mask_set(client, COM3, VFLIP_IMG, val); 611 return ov772x_mask_set(client, COM3, VFLIP_IMG, val);
678 break;
679 case V4L2_CID_HFLIP: 612 case V4L2_CID_HFLIP:
680 val = ctrl->value ? HFLIP_IMG : 0x00; 613 val = ctrl->val ? HFLIP_IMG : 0x00;
681 priv->flag_hflip = ctrl->value; 614 priv->flag_hflip = ctrl->val;
682 if (priv->info->flags & OV772X_FLAG_HFLIP) 615 if (priv->info->flags & OV772X_FLAG_HFLIP)
683 val ^= HFLIP_IMG; 616 val ^= HFLIP_IMG;
684 ret = ov772x_mask_set(client, COM3, HFLIP_IMG, val); 617 return ov772x_mask_set(client, COM3, HFLIP_IMG, val);
685 break;
686 case V4L2_CID_BAND_STOP_FILTER: 618 case V4L2_CID_BAND_STOP_FILTER:
687 if ((unsigned)ctrl->value > 256) 619 if (!ctrl->val) {
688 ctrl->value = 256;
689 if (ctrl->value == priv->band_filter)
690 break;
691 if (!ctrl->value) {
692 /* Switch the filter off, it is on now */ 620 /* Switch the filter off, it is on now */
693 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff); 621 ret = ov772x_mask_set(client, BDBASE, 0xff, 0xff);
694 if (!ret) 622 if (!ret)
@@ -696,7 +624,7 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
696 BNDF_ON_OFF, 0); 624 BNDF_ON_OFF, 0);
697 } else { 625 } else {
698 /* Switch the filter on, set AEC low limit */ 626 /* Switch the filter on, set AEC low limit */
699 val = 256 - ctrl->value; 627 val = 256 - ctrl->val;
700 ret = ov772x_mask_set(client, COM8, 628 ret = ov772x_mask_set(client, COM8,
701 BNDF_ON_OFF, BNDF_ON_OFF); 629 BNDF_ON_OFF, BNDF_ON_OFF);
702 if (!ret) 630 if (!ret)
@@ -704,11 +632,11 @@ static int ov772x_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
704 0xff, val); 632 0xff, val);
705 } 633 }
706 if (!ret) 634 if (!ret)
707 priv->band_filter = ctrl->value; 635 priv->band_filter = ctrl->val;
708 break; 636 return ret;
709 } 637 }
710 638
711 return ret; 639 return -EINVAL;
712} 640}
713 641
714static int ov772x_g_chip_ident(struct v4l2_subdev *sd, 642static int ov772x_g_chip_ident(struct v4l2_subdev *sd,
@@ -822,13 +750,13 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
822 goto ov772x_set_fmt_error; 750 goto ov772x_set_fmt_error;
823 751
824 ret = ov772x_mask_set(client, 752 ret = ov772x_mask_set(client,
825 EDGE_TRSHLD, EDGE_THRESHOLD_MASK, 753 EDGE_TRSHLD, OV772X_EDGE_THRESHOLD_MASK,
826 priv->info->edgectrl.threshold); 754 priv->info->edgectrl.threshold);
827 if (ret < 0) 755 if (ret < 0)
828 goto ov772x_set_fmt_error; 756 goto ov772x_set_fmt_error;
829 757
830 ret = ov772x_mask_set(client, 758 ret = ov772x_mask_set(client,
831 EDGE_STRNGT, EDGE_STRENGTH_MASK, 759 EDGE_STRNGT, OV772X_EDGE_STRENGTH_MASK,
832 priv->info->edgectrl.strength); 760 priv->info->edgectrl.strength);
833 if (ret < 0) 761 if (ret < 0)
834 goto ov772x_set_fmt_error; 762 goto ov772x_set_fmt_error;
@@ -840,13 +768,13 @@ static int ov772x_set_params(struct i2c_client *client, u32 *width, u32 *height,
840 * set upper and lower limit 768 * set upper and lower limit
841 */ 769 */
842 ret = ov772x_mask_set(client, 770 ret = ov772x_mask_set(client,
843 EDGE_UPPER, EDGE_UPPER_MASK, 771 EDGE_UPPER, OV772X_EDGE_UPPER_MASK,
844 priv->info->edgectrl.upper); 772 priv->info->edgectrl.upper);
845 if (ret < 0) 773 if (ret < 0)
846 goto ov772x_set_fmt_error; 774 goto ov772x_set_fmt_error;
847 775
848 ret = ov772x_mask_set(client, 776 ret = ov772x_mask_set(client,
849 EDGE_LOWER, EDGE_LOWER_MASK, 777 EDGE_LOWER, OV772X_EDGE_LOWER_MASK,
850 priv->info->edgectrl.lower); 778 priv->info->edgectrl.lower);
851 if (ret < 0) 779 if (ret < 0)
852 goto ov772x_set_fmt_error; 780 goto ov772x_set_fmt_error;
@@ -1025,17 +953,12 @@ static int ov772x_try_fmt(struct v4l2_subdev *sd,
1025 return 0; 953 return 0;
1026} 954}
1027 955
1028static int ov772x_video_probe(struct soc_camera_device *icd, 956static int ov772x_video_probe(struct i2c_client *client)
1029 struct i2c_client *client)
1030{ 957{
1031 struct ov772x_priv *priv = to_ov772x(client); 958 struct ov772x_priv *priv = to_ov772x(client);
1032 u8 pid, ver; 959 u8 pid, ver;
1033 const char *devname; 960 const char *devname;
1034 961
1035 /* We must have a parent by now. And it cannot be a wrong one. */
1036 BUG_ON(!icd->parent ||
1037 to_soc_camera_host(icd->parent)->nr != icd->iface);
1038
1039 /* 962 /*
1040 * check and show product ID and manufacturer ID 963 * check and show product ID and manufacturer ID
1041 */ 964 */
@@ -1064,20 +987,14 @@ static int ov772x_video_probe(struct soc_camera_device *icd,
1064 ver, 987 ver,
1065 i2c_smbus_read_byte_data(client, MIDH), 988 i2c_smbus_read_byte_data(client, MIDH),
1066 i2c_smbus_read_byte_data(client, MIDL)); 989 i2c_smbus_read_byte_data(client, MIDL));
1067 990 return v4l2_ctrl_handler_setup(&priv->hdl);
1068 return 0;
1069} 991}
1070 992
1071static struct soc_camera_ops ov772x_ops = { 993static const struct v4l2_ctrl_ops ov772x_ctrl_ops = {
1072 .set_bus_param = ov772x_set_bus_param, 994 .s_ctrl = ov772x_s_ctrl,
1073 .query_bus_param = ov772x_query_bus_param,
1074 .controls = ov772x_controls,
1075 .num_controls = ARRAY_SIZE(ov772x_controls),
1076}; 995};
1077 996
1078static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = { 997static struct v4l2_subdev_core_ops ov772x_subdev_core_ops = {
1079 .g_ctrl = ov772x_g_ctrl,
1080 .s_ctrl = ov772x_s_ctrl,
1081 .g_chip_ident = ov772x_g_chip_ident, 998 .g_chip_ident = ov772x_g_chip_ident,
1082#ifdef CONFIG_VIDEO_ADV_DEBUG 999#ifdef CONFIG_VIDEO_ADV_DEBUG
1083 .g_register = ov772x_g_register, 1000 .g_register = ov772x_g_register,
@@ -1095,6 +1012,21 @@ static int ov772x_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
1095 return 0; 1012 return 0;
1096} 1013}
1097 1014
1015static int ov772x_g_mbus_config(struct v4l2_subdev *sd,
1016 struct v4l2_mbus_config *cfg)
1017{
1018 struct i2c_client *client = v4l2_get_subdevdata(sd);
1019 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1020
1021 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
1022 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1023 V4L2_MBUS_DATA_ACTIVE_HIGH;
1024 cfg->type = V4L2_MBUS_PARALLEL;
1025 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1026
1027 return 0;
1028}
1029
1098static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = { 1030static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1099 .s_stream = ov772x_s_stream, 1031 .s_stream = ov772x_s_stream,
1100 .g_mbus_fmt = ov772x_g_fmt, 1032 .g_mbus_fmt = ov772x_g_fmt,
@@ -1103,6 +1035,7 @@ static struct v4l2_subdev_video_ops ov772x_subdev_video_ops = {
1103 .cropcap = ov772x_cropcap, 1035 .cropcap = ov772x_cropcap,
1104 .g_crop = ov772x_g_crop, 1036 .g_crop = ov772x_g_crop,
1105 .enum_mbus_fmt = ov772x_enum_fmt, 1037 .enum_mbus_fmt = ov772x_enum_fmt,
1038 .g_mbus_config = ov772x_g_mbus_config,
1106}; 1039};
1107 1040
1108static struct v4l2_subdev_ops ov772x_subdev_ops = { 1041static struct v4l2_subdev_ops ov772x_subdev_ops = {
@@ -1117,20 +1050,15 @@ static struct v4l2_subdev_ops ov772x_subdev_ops = {
1117static int ov772x_probe(struct i2c_client *client, 1050static int ov772x_probe(struct i2c_client *client,
1118 const struct i2c_device_id *did) 1051 const struct i2c_device_id *did)
1119{ 1052{
1120 struct ov772x_priv *priv; 1053 struct ov772x_priv *priv;
1121 struct soc_camera_device *icd = client->dev.platform_data; 1054 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1122 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1055 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1123 struct soc_camera_link *icl; 1056 int ret;
1124 int ret;
1125
1126 if (!icd) {
1127 dev_err(&client->dev, "OV772X: missing soc-camera data!\n");
1128 return -EINVAL;
1129 }
1130 1057
1131 icl = to_soc_camera_link(icd); 1058 if (!icl || !icl->priv) {
1132 if (!icl || !icl->priv) 1059 dev_err(&client->dev, "OV772X: missing platform data!\n");
1133 return -EINVAL; 1060 return -EINVAL;
1061 }
1134 1062
1135 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 1063 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
1136 dev_err(&adapter->dev, 1064 dev_err(&adapter->dev,
@@ -1146,12 +1074,24 @@ static int ov772x_probe(struct i2c_client *client,
1146 priv->info = icl->priv; 1074 priv->info = icl->priv;
1147 1075
1148 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops); 1076 v4l2_i2c_subdev_init(&priv->subdev, client, &ov772x_subdev_ops);
1077 v4l2_ctrl_handler_init(&priv->hdl, 3);
1078 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
1079 V4L2_CID_VFLIP, 0, 1, 1, 0);
1080 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
1081 V4L2_CID_HFLIP, 0, 1, 1, 0);
1082 v4l2_ctrl_new_std(&priv->hdl, &ov772x_ctrl_ops,
1083 V4L2_CID_BAND_STOP_FILTER, 0, 256, 1, 0);
1084 priv->subdev.ctrl_handler = &priv->hdl;
1085 if (priv->hdl.error) {
1086 int err = priv->hdl.error;
1149 1087
1150 icd->ops = &ov772x_ops; 1088 kfree(priv);
1089 return err;
1090 }
1151 1091
1152 ret = ov772x_video_probe(icd, client); 1092 ret = ov772x_video_probe(client);
1153 if (ret) { 1093 if (ret) {
1154 icd->ops = NULL; 1094 v4l2_ctrl_handler_free(&priv->hdl);
1155 kfree(priv); 1095 kfree(priv);
1156 } 1096 }
1157 1097
@@ -1161,9 +1101,9 @@ static int ov772x_probe(struct i2c_client *client,
1161static int ov772x_remove(struct i2c_client *client) 1101static int ov772x_remove(struct i2c_client *client)
1162{ 1102{
1163 struct ov772x_priv *priv = to_ov772x(client); 1103 struct ov772x_priv *priv = to_ov772x(client);
1164 struct soc_camera_device *icd = client->dev.platform_data;
1165 1104
1166 icd->ops = NULL; 1105 v4l2_device_unregister_subdev(&priv->subdev);
1106 v4l2_ctrl_handler_free(&priv->hdl);
1167 kfree(priv); 1107 kfree(priv);
1168 return 0; 1108 return 0;
1169} 1109}
diff --git a/drivers/media/video/ov9640.c b/drivers/media/video/ov9640.c
index 3681a6ff081..a4f99797eb5 100644
--- a/drivers/media/video/ov9640.c
+++ b/drivers/media/video/ov9640.c
@@ -24,10 +24,13 @@
24#include <linux/i2c.h> 24#include <linux/i2c.h>
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <linux/v4l2-mediabus.h>
27#include <linux/videodev2.h> 28#include <linux/videodev2.h>
29
30#include <media/soc_camera.h>
28#include <media/v4l2-chip-ident.h> 31#include <media/v4l2-chip-ident.h>
29#include <media/v4l2-common.h> 32#include <media/v4l2-common.h>
30#include <media/soc_camera.h> 33#include <media/v4l2-ctrls.h>
31 34
32#include "ov9640.h" 35#include "ov9640.h"
33 36
@@ -162,27 +165,6 @@ static enum v4l2_mbus_pixelcode ov9640_codes[] = {
162 V4L2_MBUS_FMT_RGB565_2X8_LE, 165 V4L2_MBUS_FMT_RGB565_2X8_LE,
163}; 166};
164 167
165static const struct v4l2_queryctrl ov9640_controls[] = {
166 {
167 .id = V4L2_CID_VFLIP,
168 .type = V4L2_CTRL_TYPE_BOOLEAN,
169 .name = "Flip Vertically",
170 .minimum = 0,
171 .maximum = 1,
172 .step = 1,
173 .default_value = 0,
174 },
175 {
176 .id = V4L2_CID_HFLIP,
177 .type = V4L2_CTRL_TYPE_BOOLEAN,
178 .name = "Flip Horizontally",
179 .minimum = 0,
180 .maximum = 1,
181 .step = 1,
182 .default_value = 0,
183 },
184};
185
186/* read a register */ 168/* read a register */
187static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val) 169static int ov9640_reg_read(struct i2c_client *client, u8 reg, u8 *val)
188{ 170{
@@ -284,75 +266,25 @@ static int ov9640_s_stream(struct v4l2_subdev *sd, int enable)
284 return 0; 266 return 0;
285} 267}
286 268
287/* Alter bus settings on camera side */
288static int ov9640_set_bus_param(struct soc_camera_device *icd,
289 unsigned long flags)
290{
291 return 0;
292}
293
294/* Request bus settings on camera side */
295static unsigned long ov9640_query_bus_param(struct soc_camera_device *icd)
296{
297 struct soc_camera_link *icl = to_soc_camera_link(icd);
298
299 /*
300 * REVISIT: the camera probably can do 10 bit transfers, but I don't
301 * have those pins connected on my hardware.
302 */
303 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
304 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
305 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
306
307 return soc_camera_apply_sensor_flags(icl, flags);
308}
309
310/* Get status of additional camera capabilities */
311static int ov9640_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
312{
313 struct ov9640_priv *priv = to_ov9640_sensor(sd);
314
315 switch (ctrl->id) {
316 case V4L2_CID_VFLIP:
317 ctrl->value = priv->flag_vflip;
318 break;
319 case V4L2_CID_HFLIP:
320 ctrl->value = priv->flag_hflip;
321 break;
322 }
323 return 0;
324}
325
326/* Set status of additional camera capabilities */ 269/* Set status of additional camera capabilities */
327static int ov9640_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 270static int ov9640_s_ctrl(struct v4l2_ctrl *ctrl)
328{ 271{
329 struct i2c_client *client = v4l2_get_subdevdata(sd); 272 struct ov9640_priv *priv = container_of(ctrl->handler, struct ov9640_priv, hdl);
330 struct ov9640_priv *priv = to_ov9640_sensor(sd); 273 struct i2c_client *client = v4l2_get_subdevdata(&priv->subdev);
331
332 int ret = 0;
333 274
334 switch (ctrl->id) { 275 switch (ctrl->id) {
335 case V4L2_CID_VFLIP: 276 case V4L2_CID_VFLIP:
336 priv->flag_vflip = ctrl->value; 277 if (ctrl->val)
337 if (ctrl->value) 278 return ov9640_reg_rmw(client, OV9640_MVFP,
338 ret = ov9640_reg_rmw(client, OV9640_MVFP,
339 OV9640_MVFP_V, 0); 279 OV9640_MVFP_V, 0);
340 else 280 return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_V);
341 ret = ov9640_reg_rmw(client, OV9640_MVFP,
342 0, OV9640_MVFP_V);
343 break;
344 case V4L2_CID_HFLIP: 281 case V4L2_CID_HFLIP:
345 priv->flag_hflip = ctrl->value; 282 if (ctrl->val)
346 if (ctrl->value) 283 return ov9640_reg_rmw(client, OV9640_MVFP,
347 ret = ov9640_reg_rmw(client, OV9640_MVFP,
348 OV9640_MVFP_H, 0); 284 OV9640_MVFP_H, 0);
349 else 285 return ov9640_reg_rmw(client, OV9640_MVFP, 0, OV9640_MVFP_H);
350 ret = ov9640_reg_rmw(client, OV9640_MVFP,
351 0, OV9640_MVFP_H);
352 break;
353 } 286 }
354 287 return -EINVAL;
355 return ret;
356} 288}
357 289
358/* Get chip identification */ 290/* Get chip identification */
@@ -646,10 +578,7 @@ static int ov9640_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
646 return 0; 578 return 0;
647} 579}
648 580
649 581static int ov9640_video_probe(struct i2c_client *client)
650
651static int ov9640_video_probe(struct soc_camera_device *icd,
652 struct i2c_client *client)
653{ 582{
654 struct v4l2_subdev *sd = i2c_get_clientdata(client); 583 struct v4l2_subdev *sd = i2c_get_clientdata(client);
655 struct ov9640_priv *priv = to_ov9640_sensor(sd); 584 struct ov9640_priv *priv = to_ov9640_sensor(sd);
@@ -657,29 +586,19 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
657 const char *devname; 586 const char *devname;
658 int ret = 0; 587 int ret = 0;
659 588
660 /* We must have a parent by now. And it cannot be a wrong one. */
661 BUG_ON(!icd->parent ||
662 to_soc_camera_host(icd->parent)->nr != icd->iface);
663
664 /* 589 /*
665 * check and show product ID and manufacturer ID 590 * check and show product ID and manufacturer ID
666 */ 591 */
667 592
668 ret = ov9640_reg_read(client, OV9640_PID, &pid); 593 ret = ov9640_reg_read(client, OV9640_PID, &pid);
594 if (!ret)
595 ret = ov9640_reg_read(client, OV9640_VER, &ver);
596 if (!ret)
597 ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
598 if (!ret)
599 ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
669 if (ret) 600 if (ret)
670 goto err; 601 return ret;
671
672 ret = ov9640_reg_read(client, OV9640_VER, &ver);
673 if (ret)
674 goto err;
675
676 ret = ov9640_reg_read(client, OV9640_MIDH, &midh);
677 if (ret)
678 goto err;
679
680 ret = ov9640_reg_read(client, OV9640_MIDL, &midl);
681 if (ret)
682 goto err;
683 602
684 switch (VERSION(pid, ver)) { 603 switch (VERSION(pid, ver)) {
685 case OV9640_V2: 604 case OV9640_V2:
@@ -693,27 +612,20 @@ static int ov9640_video_probe(struct soc_camera_device *icd,
693 break; 612 break;
694 default: 613 default:
695 dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver); 614 dev_err(&client->dev, "Product ID error %x:%x\n", pid, ver);
696 ret = -ENODEV; 615 return -ENODEV;
697 goto err;
698 } 616 }
699 617
700 dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n", 618 dev_info(&client->dev, "%s Product ID %0x:%0x Manufacturer ID %x:%x\n",
701 devname, pid, ver, midh, midl); 619 devname, pid, ver, midh, midl);
702 620
703err: 621 return v4l2_ctrl_handler_setup(&priv->hdl);
704 return ret;
705} 622}
706 623
707static struct soc_camera_ops ov9640_ops = { 624static const struct v4l2_ctrl_ops ov9640_ctrl_ops = {
708 .set_bus_param = ov9640_set_bus_param, 625 .s_ctrl = ov9640_s_ctrl,
709 .query_bus_param = ov9640_query_bus_param,
710 .controls = ov9640_controls,
711 .num_controls = ARRAY_SIZE(ov9640_controls),
712}; 626};
713 627
714static struct v4l2_subdev_core_ops ov9640_core_ops = { 628static struct v4l2_subdev_core_ops ov9640_core_ops = {
715 .g_ctrl = ov9640_g_ctrl,
716 .s_ctrl = ov9640_s_ctrl,
717 .g_chip_ident = ov9640_g_chip_ident, 629 .g_chip_ident = ov9640_g_chip_ident,
718#ifdef CONFIG_VIDEO_ADV_DEBUG 630#ifdef CONFIG_VIDEO_ADV_DEBUG
719 .g_register = ov9640_get_register, 631 .g_register = ov9640_get_register,
@@ -722,6 +634,22 @@ static struct v4l2_subdev_core_ops ov9640_core_ops = {
722 634
723}; 635};
724 636
637/* Request bus settings on camera side */
638static int ov9640_g_mbus_config(struct v4l2_subdev *sd,
639 struct v4l2_mbus_config *cfg)
640{
641 struct i2c_client *client = v4l2_get_subdevdata(sd);
642 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
643
644 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
645 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
646 V4L2_MBUS_DATA_ACTIVE_HIGH;
647 cfg->type = V4L2_MBUS_PARALLEL;
648 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
649
650 return 0;
651}
652
725static struct v4l2_subdev_video_ops ov9640_video_ops = { 653static struct v4l2_subdev_video_ops ov9640_video_ops = {
726 .s_stream = ov9640_s_stream, 654 .s_stream = ov9640_s_stream,
727 .s_mbus_fmt = ov9640_s_fmt, 655 .s_mbus_fmt = ov9640_s_fmt,
@@ -729,7 +657,7 @@ static struct v4l2_subdev_video_ops ov9640_video_ops = {
729 .enum_mbus_fmt = ov9640_enum_fmt, 657 .enum_mbus_fmt = ov9640_enum_fmt,
730 .cropcap = ov9640_cropcap, 658 .cropcap = ov9640_cropcap,
731 .g_crop = ov9640_g_crop, 659 .g_crop = ov9640_g_crop,
732 660 .g_mbus_config = ov9640_g_mbus_config,
733}; 661};
734 662
735static struct v4l2_subdev_ops ov9640_subdev_ops = { 663static struct v4l2_subdev_ops ov9640_subdev_ops = {
@@ -744,16 +672,9 @@ static int ov9640_probe(struct i2c_client *client,
744 const struct i2c_device_id *did) 672 const struct i2c_device_id *did)
745{ 673{
746 struct ov9640_priv *priv; 674 struct ov9640_priv *priv;
747 struct soc_camera_device *icd = client->dev.platform_data; 675 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
748 struct soc_camera_link *icl;
749 int ret; 676 int ret;
750 677
751 if (!icd) {
752 dev_err(&client->dev, "Missing soc-camera data!\n");
753 return -EINVAL;
754 }
755
756 icl = to_soc_camera_link(icd);
757 if (!icl) { 678 if (!icl) {
758 dev_err(&client->dev, "Missing platform_data for driver\n"); 679 dev_err(&client->dev, "Missing platform_data for driver\n");
759 return -EINVAL; 680 return -EINVAL;
@@ -768,12 +689,23 @@ static int ov9640_probe(struct i2c_client *client,
768 689
769 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops); 690 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9640_subdev_ops);
770 691
771 icd->ops = &ov9640_ops; 692 v4l2_ctrl_handler_init(&priv->hdl, 2);
693 v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
694 V4L2_CID_VFLIP, 0, 1, 1, 0);
695 v4l2_ctrl_new_std(&priv->hdl, &ov9640_ctrl_ops,
696 V4L2_CID_HFLIP, 0, 1, 1, 0);
697 priv->subdev.ctrl_handler = &priv->hdl;
698 if (priv->hdl.error) {
699 int err = priv->hdl.error;
700
701 kfree(priv);
702 return err;
703 }
772 704
773 ret = ov9640_video_probe(icd, client); 705 ret = ov9640_video_probe(client);
774 706
775 if (ret) { 707 if (ret) {
776 icd->ops = NULL; 708 v4l2_ctrl_handler_free(&priv->hdl);
777 kfree(priv); 709 kfree(priv);
778 } 710 }
779 711
@@ -785,6 +717,8 @@ static int ov9640_remove(struct i2c_client *client)
785 struct v4l2_subdev *sd = i2c_get_clientdata(client); 717 struct v4l2_subdev *sd = i2c_get_clientdata(client);
786 struct ov9640_priv *priv = to_ov9640_sensor(sd); 718 struct ov9640_priv *priv = to_ov9640_sensor(sd);
787 719
720 v4l2_device_unregister_subdev(&priv->subdev);
721 v4l2_ctrl_handler_free(&priv->hdl);
788 kfree(priv); 722 kfree(priv);
789 return 0; 723 return 0;
790} 724}
diff --git a/drivers/media/video/ov9640.h b/drivers/media/video/ov9640.h
index f8a51b70792..6b33a972c83 100644
--- a/drivers/media/video/ov9640.h
+++ b/drivers/media/video/ov9640.h
@@ -198,12 +198,10 @@ struct ov9640_reg {
198 198
199struct ov9640_priv { 199struct ov9640_priv {
200 struct v4l2_subdev subdev; 200 struct v4l2_subdev subdev;
201 struct v4l2_ctrl_handler hdl;
201 202
202 int model; 203 int model;
203 int revision; 204 int revision;
204
205 bool flag_vflip;
206 bool flag_hflip;
207}; 205};
208 206
209#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */ 207#endif /* __DRIVERS_MEDIA_VIDEO_OV9640_H__ */
diff --git a/drivers/media/video/ov9740.c b/drivers/media/video/ov9740.c
index edd1ffcca30..d9a9f7174f7 100644
--- a/drivers/media/video/ov9740.c
+++ b/drivers/media/video/ov9740.c
@@ -14,8 +14,11 @@
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/i2c.h> 15#include <linux/i2c.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17#include <media/v4l2-chip-ident.h> 17#include <linux/v4l2-mediabus.h>
18
18#include <media/soc_camera.h> 19#include <media/soc_camera.h>
20#include <media/v4l2-chip-ident.h>
21#include <media/v4l2-ctrls.h>
19 22
20#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev) 23#define to_ov9740(sd) container_of(sd, struct ov9740_priv, subdev)
21 24
@@ -192,6 +195,7 @@ struct ov9740_reg {
192 195
193struct ov9740_priv { 196struct ov9740_priv {
194 struct v4l2_subdev subdev; 197 struct v4l2_subdev subdev;
198 struct v4l2_ctrl_handler hdl;
195 199
196 int ident; 200 int ident;
197 u16 model; 201 u16 model;
@@ -392,27 +396,6 @@ static enum v4l2_mbus_pixelcode ov9740_codes[] = {
392 V4L2_MBUS_FMT_YUYV8_2X8, 396 V4L2_MBUS_FMT_YUYV8_2X8,
393}; 397};
394 398
395static const struct v4l2_queryctrl ov9740_controls[] = {
396 {
397 .id = V4L2_CID_VFLIP,
398 .type = V4L2_CTRL_TYPE_BOOLEAN,
399 .name = "Flip Vertically",
400 .minimum = 0,
401 .maximum = 1,
402 .step = 1,
403 .default_value = 0,
404 },
405 {
406 .id = V4L2_CID_HFLIP,
407 .type = V4L2_CTRL_TYPE_BOOLEAN,
408 .name = "Flip Horizontally",
409 .minimum = 0,
410 .maximum = 1,
411 .step = 1,
412 .default_value = 0,
413 },
414};
415
416/* read a register */ 399/* read a register */
417static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val) 400static int ov9740_reg_read(struct i2c_client *client, u16 reg, u8 *val)
418{ 401{
@@ -560,25 +543,6 @@ static int ov9740_s_stream(struct v4l2_subdev *sd, int enable)
560 return ret; 543 return ret;
561} 544}
562 545
563/* Alter bus settings on camera side */
564static int ov9740_set_bus_param(struct soc_camera_device *icd,
565 unsigned long flags)
566{
567 return 0;
568}
569
570/* Request bus settings on camera side */
571static unsigned long ov9740_query_bus_param(struct soc_camera_device *icd)
572{
573 struct soc_camera_link *icl = to_soc_camera_link(icd);
574
575 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
576 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
577 SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8;
578
579 return soc_camera_apply_sensor_flags(icl, flags);
580}
581
582/* select nearest higher resolution for capture */ 546/* select nearest higher resolution for capture */
583static void ov9740_res_roundup(u32 *width, u32 *height) 547static void ov9740_res_roundup(u32 *width, u32 *height)
584{ 548{
@@ -788,36 +752,18 @@ static int ov9740_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
788 return 0; 752 return 0;
789} 753}
790 754
791/* Get status of additional camera capabilities */
792static int ov9740_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
793{
794 struct ov9740_priv *priv = to_ov9740(sd);
795
796 switch (ctrl->id) {
797 case V4L2_CID_VFLIP:
798 ctrl->value = priv->flag_vflip;
799 break;
800 case V4L2_CID_HFLIP:
801 ctrl->value = priv->flag_hflip;
802 break;
803 default:
804 return -EINVAL;
805 }
806
807 return 0;
808}
809
810/* Set status of additional camera capabilities */ 755/* Set status of additional camera capabilities */
811static int ov9740_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl) 756static int ov9740_s_ctrl(struct v4l2_ctrl *ctrl)
812{ 757{
813 struct ov9740_priv *priv = to_ov9740(sd); 758 struct ov9740_priv *priv =
759 container_of(ctrl->handler, struct ov9740_priv, hdl);
814 760
815 switch (ctrl->id) { 761 switch (ctrl->id) {
816 case V4L2_CID_VFLIP: 762 case V4L2_CID_VFLIP:
817 priv->flag_vflip = ctrl->value; 763 priv->flag_vflip = ctrl->val;
818 break; 764 break;
819 case V4L2_CID_HFLIP: 765 case V4L2_CID_HFLIP:
820 priv->flag_hflip = ctrl->value; 766 priv->flag_hflip = ctrl->val;
821 break; 767 break;
822 default: 768 default:
823 return -EINVAL; 769 return -EINVAL;
@@ -890,18 +836,13 @@ static int ov9740_set_register(struct v4l2_subdev *sd,
890} 836}
891#endif 837#endif
892 838
893static int ov9740_video_probe(struct soc_camera_device *icd, 839static int ov9740_video_probe(struct i2c_client *client)
894 struct i2c_client *client)
895{ 840{
896 struct v4l2_subdev *sd = i2c_get_clientdata(client); 841 struct v4l2_subdev *sd = i2c_get_clientdata(client);
897 struct ov9740_priv *priv = to_ov9740(sd); 842 struct ov9740_priv *priv = to_ov9740(sd);
898 u8 modelhi, modello; 843 u8 modelhi, modello;
899 int ret; 844 int ret;
900 845
901 /* We must have a parent by now. And it cannot be a wrong one. */
902 BUG_ON(!icd->parent ||
903 to_soc_camera_host(icd->parent)->nr != icd->iface);
904
905 /* 846 /*
906 * check and show product ID and manufacturer ID 847 * check and show product ID and manufacturer ID
907 */ 848 */
@@ -942,25 +883,33 @@ err:
942 return ret; 883 return ret;
943} 884}
944 885
945static struct soc_camera_ops ov9740_ops = { 886/* Request bus settings on camera side */
946 .set_bus_param = ov9740_set_bus_param, 887static int ov9740_g_mbus_config(struct v4l2_subdev *sd,
947 .query_bus_param = ov9740_query_bus_param, 888 struct v4l2_mbus_config *cfg)
948 .controls = ov9740_controls, 889{
949 .num_controls = ARRAY_SIZE(ov9740_controls), 890 struct i2c_client *client = v4l2_get_subdevdata(sd);
950}; 891 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
892
893 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
894 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
895 V4L2_MBUS_DATA_ACTIVE_HIGH;
896 cfg->type = V4L2_MBUS_PARALLEL;
897 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
898
899 return 0;
900}
951 901
952static struct v4l2_subdev_video_ops ov9740_video_ops = { 902static struct v4l2_subdev_video_ops ov9740_video_ops = {
953 .s_stream = ov9740_s_stream, 903 .s_stream = ov9740_s_stream,
954 .s_mbus_fmt = ov9740_s_fmt, 904 .s_mbus_fmt = ov9740_s_fmt,
955 .try_mbus_fmt = ov9740_try_fmt, 905 .try_mbus_fmt = ov9740_try_fmt,
956 .enum_mbus_fmt = ov9740_enum_fmt, 906 .enum_mbus_fmt = ov9740_enum_fmt,
957 .cropcap = ov9740_cropcap, 907 .cropcap = ov9740_cropcap,
958 .g_crop = ov9740_g_crop, 908 .g_crop = ov9740_g_crop,
909 .g_mbus_config = ov9740_g_mbus_config,
959}; 910};
960 911
961static struct v4l2_subdev_core_ops ov9740_core_ops = { 912static struct v4l2_subdev_core_ops ov9740_core_ops = {
962 .g_ctrl = ov9740_g_ctrl,
963 .s_ctrl = ov9740_s_ctrl,
964 .g_chip_ident = ov9740_g_chip_ident, 913 .g_chip_ident = ov9740_g_chip_ident,
965 .s_power = ov9740_s_power, 914 .s_power = ov9740_s_power,
966#ifdef CONFIG_VIDEO_ADV_DEBUG 915#ifdef CONFIG_VIDEO_ADV_DEBUG
@@ -974,6 +923,10 @@ static struct v4l2_subdev_ops ov9740_subdev_ops = {
974 .video = &ov9740_video_ops, 923 .video = &ov9740_video_ops,
975}; 924};
976 925
926static const struct v4l2_ctrl_ops ov9740_ctrl_ops = {
927 .s_ctrl = ov9740_s_ctrl,
928};
929
977/* 930/*
978 * i2c_driver function 931 * i2c_driver function
979 */ 932 */
@@ -981,16 +934,9 @@ static int ov9740_probe(struct i2c_client *client,
981 const struct i2c_device_id *did) 934 const struct i2c_device_id *did)
982{ 935{
983 struct ov9740_priv *priv; 936 struct ov9740_priv *priv;
984 struct soc_camera_device *icd = client->dev.platform_data; 937 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
985 struct soc_camera_link *icl;
986 int ret; 938 int ret;
987 939
988 if (!icd) {
989 dev_err(&client->dev, "Missing soc-camera data!\n");
990 return -EINVAL;
991 }
992
993 icl = to_soc_camera_link(icd);
994 if (!icl) { 940 if (!icl) {
995 dev_err(&client->dev, "Missing platform_data for driver\n"); 941 dev_err(&client->dev, "Missing platform_data for driver\n");
996 return -EINVAL; 942 return -EINVAL;
@@ -1003,12 +949,24 @@ static int ov9740_probe(struct i2c_client *client,
1003 } 949 }
1004 950
1005 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops); 951 v4l2_i2c_subdev_init(&priv->subdev, client, &ov9740_subdev_ops);
952 v4l2_ctrl_handler_init(&priv->hdl, 13);
953 v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
954 V4L2_CID_VFLIP, 0, 1, 1, 0);
955 v4l2_ctrl_new_std(&priv->hdl, &ov9740_ctrl_ops,
956 V4L2_CID_HFLIP, 0, 1, 1, 0);
957 priv->subdev.ctrl_handler = &priv->hdl;
958 if (priv->hdl.error) {
959 int err = priv->hdl.error;
1006 960
1007 icd->ops = &ov9740_ops; 961 kfree(priv);
962 return err;
963 }
1008 964
1009 ret = ov9740_video_probe(icd, client); 965 ret = ov9740_video_probe(client);
966 if (!ret)
967 ret = v4l2_ctrl_handler_setup(&priv->hdl);
1010 if (ret < 0) { 968 if (ret < 0) {
1011 icd->ops = NULL; 969 v4l2_ctrl_handler_free(&priv->hdl);
1012 kfree(priv); 970 kfree(priv);
1013 } 971 }
1014 972
@@ -1019,8 +977,9 @@ static int ov9740_remove(struct i2c_client *client)
1019{ 977{
1020 struct ov9740_priv *priv = i2c_get_clientdata(client); 978 struct ov9740_priv *priv = i2c_get_clientdata(client);
1021 979
980 v4l2_device_unregister_subdev(&priv->subdev);
981 v4l2_ctrl_handler_free(&priv->hdl);
1022 kfree(priv); 982 kfree(priv);
1023
1024 return 0; 983 return 0;
1025} 984}
1026 985
diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c
index 360be226718..01ff643e682 100644
--- a/drivers/media/video/pwc/pwc-if.c
+++ b/drivers/media/video/pwc/pwc-if.c
@@ -744,9 +744,9 @@ static int pwc_video_mmap(struct file *file, struct vm_area_struct *vma)
744/***************************************************************************/ 744/***************************************************************************/
745/* Videobuf2 operations */ 745/* Videobuf2 operations */
746 746
747static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 747static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
748 unsigned int *nplanes, unsigned int sizes[], 748 unsigned int *nbuffers, unsigned int *nplanes,
749 void *alloc_ctxs[]) 749 unsigned int sizes[], void *alloc_ctxs[])
750{ 750{
751 struct pwc_device *pdev = vb2_get_drv_priv(vq); 751 struct pwc_device *pdev = vb2_get_drv_priv(vq);
752 752
diff --git a/drivers/media/video/pxa_camera.c b/drivers/media/video/pxa_camera.c
index d07df22a5ec..79fb22c89ae 100644
--- a/drivers/media/video/pxa_camera.c
+++ b/drivers/media/video/pxa_camera.c
@@ -214,6 +214,7 @@ struct pxa_camera_dev {
214 unsigned long ciclk; 214 unsigned long ciclk;
215 unsigned long mclk; 215 unsigned long mclk;
216 u32 mclk_divisor; 216 u32 mclk_divisor;
217 u16 width_flags; /* max 10 bits */
217 218
218 struct list_head capture; 219 struct list_head capture;
219 220
@@ -1020,37 +1021,20 @@ static int test_platform_param(struct pxa_camera_dev *pcdev,
1020 * quick capture interface supports both. 1021 * quick capture interface supports both.
1021 */ 1022 */
1022 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ? 1023 *flags = (pcdev->platform_flags & PXA_CAMERA_MASTER ?
1023 SOCAM_MASTER : SOCAM_SLAVE) | 1024 V4L2_MBUS_MASTER : V4L2_MBUS_SLAVE) |
1024 SOCAM_HSYNC_ACTIVE_HIGH | 1025 V4L2_MBUS_HSYNC_ACTIVE_HIGH |
1025 SOCAM_HSYNC_ACTIVE_LOW | 1026 V4L2_MBUS_HSYNC_ACTIVE_LOW |
1026 SOCAM_VSYNC_ACTIVE_HIGH | 1027 V4L2_MBUS_VSYNC_ACTIVE_HIGH |
1027 SOCAM_VSYNC_ACTIVE_LOW | 1028 V4L2_MBUS_VSYNC_ACTIVE_LOW |
1028 SOCAM_DATA_ACTIVE_HIGH | 1029 V4L2_MBUS_DATA_ACTIVE_HIGH |
1029 SOCAM_PCLK_SAMPLE_RISING | 1030 V4L2_MBUS_PCLK_SAMPLE_RISING |
1030 SOCAM_PCLK_SAMPLE_FALLING; 1031 V4L2_MBUS_PCLK_SAMPLE_FALLING;
1031 1032
1032 /* If requested data width is supported by the platform, use it */ 1033 /* If requested data width is supported by the platform, use it */
1033 switch (buswidth) { 1034 if ((1 << (buswidth - 1)) & pcdev->width_flags)
1034 case 10: 1035 return 0;
1035 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10))
1036 return -EINVAL;
1037 *flags |= SOCAM_DATAWIDTH_10;
1038 break;
1039 case 9:
1040 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9))
1041 return -EINVAL;
1042 *flags |= SOCAM_DATAWIDTH_9;
1043 break;
1044 case 8:
1045 if (!(pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8))
1046 return -EINVAL;
1047 *flags |= SOCAM_DATAWIDTH_8;
1048 break;
1049 default:
1050 return -EINVAL;
1051 }
1052 1036
1053 return 0; 1037 return -EINVAL;
1054} 1038}
1055 1039
1056static void pxa_camera_setup_cicr(struct soc_camera_device *icd, 1040static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
@@ -1070,12 +1054,12 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1070 * Datawidth is now guaranteed to be equal to one of the three values. 1054 * Datawidth is now guaranteed to be equal to one of the three values.
1071 * We fix bit-per-pixel equal to data-width... 1055 * We fix bit-per-pixel equal to data-width...
1072 */ 1056 */
1073 switch (flags & SOCAM_DATAWIDTH_MASK) { 1057 switch (icd->current_fmt->host_fmt->bits_per_sample) {
1074 case SOCAM_DATAWIDTH_10: 1058 case 10:
1075 dw = 4; 1059 dw = 4;
1076 bpp = 0x40; 1060 bpp = 0x40;
1077 break; 1061 break;
1078 case SOCAM_DATAWIDTH_9: 1062 case 9:
1079 dw = 3; 1063 dw = 3;
1080 bpp = 0x20; 1064 bpp = 0x20;
1081 break; 1065 break;
@@ -1084,7 +1068,7 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1084 * Actually it can only be 8 now, 1068 * Actually it can only be 8 now,
1085 * default is just to silence compiler warnings 1069 * default is just to silence compiler warnings
1086 */ 1070 */
1087 case SOCAM_DATAWIDTH_8: 1071 case 8:
1088 dw = 2; 1072 dw = 2;
1089 bpp = 0; 1073 bpp = 0;
1090 } 1074 }
@@ -1093,11 +1077,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1093 cicr4 |= CICR4_PCLK_EN; 1077 cicr4 |= CICR4_PCLK_EN;
1094 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN) 1078 if (pcdev->platform_flags & PXA_CAMERA_MCLK_EN)
1095 cicr4 |= CICR4_MCLK_EN; 1079 cicr4 |= CICR4_MCLK_EN;
1096 if (flags & SOCAM_PCLK_SAMPLE_FALLING) 1080 if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
1097 cicr4 |= CICR4_PCP; 1081 cicr4 |= CICR4_PCP;
1098 if (flags & SOCAM_HSYNC_ACTIVE_LOW) 1082 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
1099 cicr4 |= CICR4_HSP; 1083 cicr4 |= CICR4_HSP;
1100 if (flags & SOCAM_VSYNC_ACTIVE_LOW) 1084 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
1101 cicr4 |= CICR4_VSP; 1085 cicr4 |= CICR4_VSP;
1102 1086
1103 cicr0 = __raw_readl(pcdev->base + CICR0); 1087 cicr0 = __raw_readl(pcdev->base + CICR0);
@@ -1151,9 +1135,11 @@ static void pxa_camera_setup_cicr(struct soc_camera_device *icd,
1151 1135
1152static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) 1136static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1153{ 1137{
1138 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1154 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1139 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1155 struct pxa_camera_dev *pcdev = ici->priv; 1140 struct pxa_camera_dev *pcdev = ici->priv;
1156 unsigned long bus_flags, camera_flags, common_flags; 1141 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1142 unsigned long bus_flags, common_flags;
1157 int ret; 1143 int ret;
1158 struct pxa_cam *cam = icd->host_priv; 1144 struct pxa_cam *cam = icd->host_priv;
1159 1145
@@ -1162,44 +1148,58 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1162 if (ret < 0) 1148 if (ret < 0)
1163 return ret; 1149 return ret;
1164 1150
1165 camera_flags = icd->ops->query_bus_param(icd); 1151 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1166 1152 if (!ret) {
1167 common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); 1153 common_flags = soc_mbus_config_compatible(&cfg,
1168 if (!common_flags) 1154 bus_flags);
1169 return -EINVAL; 1155 if (!common_flags) {
1156 dev_warn(icd->parent,
1157 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1158 cfg.flags, bus_flags);
1159 return -EINVAL;
1160 }
1161 } else if (ret != -ENOIOCTLCMD) {
1162 return ret;
1163 } else {
1164 common_flags = bus_flags;
1165 }
1170 1166
1171 pcdev->channels = 1; 1167 pcdev->channels = 1;
1172 1168
1173 /* Make choises, based on platform preferences */ 1169 /* Make choises, based on platform preferences */
1174 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 1170 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
1175 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 1171 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
1176 if (pcdev->platform_flags & PXA_CAMERA_HSP) 1172 if (pcdev->platform_flags & PXA_CAMERA_HSP)
1177 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 1173 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
1178 else 1174 else
1179 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 1175 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
1180 } 1176 }
1181 1177
1182 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 1178 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
1183 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 1179 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
1184 if (pcdev->platform_flags & PXA_CAMERA_VSP) 1180 if (pcdev->platform_flags & PXA_CAMERA_VSP)
1185 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 1181 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1186 else 1182 else
1187 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 1183 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
1188 } 1184 }
1189 1185
1190 if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && 1186 if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
1191 (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { 1187 (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
1192 if (pcdev->platform_flags & PXA_CAMERA_PCP) 1188 if (pcdev->platform_flags & PXA_CAMERA_PCP)
1193 common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; 1189 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
1194 else 1190 else
1195 common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; 1191 common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
1196 } 1192 }
1197 1193
1198 cam->flags = common_flags; 1194 cfg.flags = common_flags;
1199 1195 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
1200 ret = icd->ops->set_bus_param(icd, common_flags); 1196 if (ret < 0 && ret != -ENOIOCTLCMD) {
1201 if (ret < 0) 1197 dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
1198 common_flags, ret);
1202 return ret; 1199 return ret;
1200 }
1201
1202 cam->flags = common_flags;
1203 1203
1204 pxa_camera_setup_cicr(icd, common_flags, pixfmt); 1204 pxa_camera_setup_cicr(icd, common_flags, pixfmt);
1205 1205
@@ -1209,17 +1209,31 @@ static int pxa_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
1209static int pxa_camera_try_bus_param(struct soc_camera_device *icd, 1209static int pxa_camera_try_bus_param(struct soc_camera_device *icd,
1210 unsigned char buswidth) 1210 unsigned char buswidth)
1211{ 1211{
1212 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
1212 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 1213 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1213 struct pxa_camera_dev *pcdev = ici->priv; 1214 struct pxa_camera_dev *pcdev = ici->priv;
1214 unsigned long bus_flags, camera_flags; 1215 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
1216 unsigned long bus_flags, common_flags;
1215 int ret = test_platform_param(pcdev, buswidth, &bus_flags); 1217 int ret = test_platform_param(pcdev, buswidth, &bus_flags);
1216 1218
1217 if (ret < 0) 1219 if (ret < 0)
1218 return ret; 1220 return ret;
1219 1221
1220 camera_flags = icd->ops->query_bus_param(icd); 1222 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
1223 if (!ret) {
1224 common_flags = soc_mbus_config_compatible(&cfg,
1225 bus_flags);
1226 if (!common_flags) {
1227 dev_warn(icd->parent,
1228 "Flags incompatible: camera 0x%x, host 0x%lx\n",
1229 cfg.flags, bus_flags);
1230 return -EINVAL;
1231 }
1232 } else if (ret == -ENOIOCTLCMD) {
1233 ret = 0;
1234 }
1221 1235
1222 return soc_camera_bus_param_compatible(camera_flags, bus_flags) ? 0 : -EINVAL; 1236 return ret;
1223} 1237}
1224 1238
1225static const struct soc_mbus_pixelfmt pxa_camera_formats[] = { 1239static const struct soc_mbus_pixelfmt pxa_camera_formats[] = {
@@ -1687,6 +1701,12 @@ static int __devinit pxa_camera_probe(struct platform_device *pdev)
1687 "data widths, using default 10 bit\n"); 1701 "data widths, using default 10 bit\n");
1688 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10; 1702 pcdev->platform_flags |= PXA_CAMERA_DATAWIDTH_10;
1689 } 1703 }
1704 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_8)
1705 pcdev->width_flags = 1 << 7;
1706 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_9)
1707 pcdev->width_flags |= 1 << 8;
1708 if (pcdev->platform_flags & PXA_CAMERA_DATAWIDTH_10)
1709 pcdev->width_flags |= 1 << 9;
1690 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000; 1710 pcdev->mclk = pcdev->pdata->mclk_10khz * 10000;
1691 if (!pcdev->mclk) { 1711 if (!pcdev->mclk) {
1692 dev_warn(&pdev->dev, 1712 dev_warn(&pdev->dev,
diff --git a/drivers/media/video/rj54n1cb0c.c b/drivers/media/video/rj54n1cb0c.c
index 847ccc067e8..6afc6168954 100644
--- a/drivers/media/video/rj54n1cb0c.c
+++ b/drivers/media/video/rj54n1cb0c.c
@@ -11,13 +11,14 @@
11#include <linux/delay.h> 11#include <linux/delay.h>
12#include <linux/i2c.h> 12#include <linux/i2c.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/v4l2-mediabus.h>
14#include <linux/videodev2.h> 15#include <linux/videodev2.h>
15 16
16#include <media/rj54n1cb0c.h> 17#include <media/rj54n1cb0c.h>
17#include <media/soc_camera.h> 18#include <media/soc_camera.h>
18#include <media/soc_mediabus.h>
19#include <media/v4l2-subdev.h> 19#include <media/v4l2-subdev.h>
20#include <media/v4l2-chip-ident.h> 20#include <media/v4l2-chip-ident.h>
21#include <media/v4l2-ctrls.h>
21 22
22#define RJ54N1_DEV_CODE 0x0400 23#define RJ54N1_DEV_CODE 0x0400
23#define RJ54N1_DEV_CODE2 0x0401 24#define RJ54N1_DEV_CODE2 0x0401
@@ -148,6 +149,7 @@ struct rj54n1_clock_div {
148 149
149struct rj54n1 { 150struct rj54n1 {
150 struct v4l2_subdev subdev; 151 struct v4l2_subdev subdev;
152 struct v4l2_ctrl_handler hdl;
151 struct rj54n1_clock_div clk_div; 153 struct rj54n1_clock_div clk_div;
152 const struct rj54n1_datafmt *fmt; 154 const struct rj54n1_datafmt *fmt;
153 struct v4l2_rect rect; /* Sensor window */ 155 struct v4l2_rect rect; /* Sensor window */
@@ -499,31 +501,6 @@ static int rj54n1_s_stream(struct v4l2_subdev *sd, int enable)
499 return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80); 501 return reg_set(client, RJ54N1_STILL_CONTROL, (!enable) << 7, 0x80);
500} 502}
501 503
502static int rj54n1_set_bus_param(struct soc_camera_device *icd,
503 unsigned long flags)
504{
505 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
506 struct i2c_client *client = v4l2_get_subdevdata(sd);
507 /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
508
509 if (flags & SOCAM_PCLK_SAMPLE_RISING)
510 return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
511 else
512 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
513}
514
515static unsigned long rj54n1_query_bus_param(struct soc_camera_device *icd)
516{
517 struct soc_camera_link *icl = to_soc_camera_link(icd);
518 const unsigned long flags =
519 SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING |
520 SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
521 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
522 SOCAM_DATA_ACTIVE_HIGH;
523
524 return soc_camera_apply_sensor_flags(icl, flags);
525}
526
527static int rj54n1_set_rect(struct i2c_client *client, 504static int rj54n1_set_rect(struct i2c_client *client,
528 u16 reg_x, u16 reg_y, u16 reg_xy, 505 u16 reg_x, u16 reg_y, u16 reg_xy,
529 u32 width, u32 height) 506 u32 width, u32 height)
@@ -1202,134 +1179,51 @@ static int rj54n1_s_register(struct v4l2_subdev *sd,
1202} 1179}
1203#endif 1180#endif
1204 1181
1205static const struct v4l2_queryctrl rj54n1_controls[] = { 1182static int rj54n1_s_ctrl(struct v4l2_ctrl *ctrl)
1206 {
1207 .id = V4L2_CID_VFLIP,
1208 .type = V4L2_CTRL_TYPE_BOOLEAN,
1209 .name = "Flip Vertically",
1210 .minimum = 0,
1211 .maximum = 1,
1212 .step = 1,
1213 .default_value = 0,
1214 }, {
1215 .id = V4L2_CID_HFLIP,
1216 .type = V4L2_CTRL_TYPE_BOOLEAN,
1217 .name = "Flip Horizontally",
1218 .minimum = 0,
1219 .maximum = 1,
1220 .step = 1,
1221 .default_value = 0,
1222 }, {
1223 .id = V4L2_CID_GAIN,
1224 .type = V4L2_CTRL_TYPE_INTEGER,
1225 .name = "Gain",
1226 .minimum = 0,
1227 .maximum = 127,
1228 .step = 1,
1229 .default_value = 66,
1230 .flags = V4L2_CTRL_FLAG_SLIDER,
1231 }, {
1232 .id = V4L2_CID_AUTO_WHITE_BALANCE,
1233 .type = V4L2_CTRL_TYPE_BOOLEAN,
1234 .name = "Auto white balance",
1235 .minimum = 0,
1236 .maximum = 1,
1237 .step = 1,
1238 .default_value = 1,
1239 },
1240};
1241
1242static struct soc_camera_ops rj54n1_ops = {
1243 .set_bus_param = rj54n1_set_bus_param,
1244 .query_bus_param = rj54n1_query_bus_param,
1245 .controls = rj54n1_controls,
1246 .num_controls = ARRAY_SIZE(rj54n1_controls),
1247};
1248
1249static int rj54n1_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1250{ 1183{
1184 struct rj54n1 *rj54n1 = container_of(ctrl->handler, struct rj54n1, hdl);
1185 struct v4l2_subdev *sd = &rj54n1->subdev;
1251 struct i2c_client *client = v4l2_get_subdevdata(sd); 1186 struct i2c_client *client = v4l2_get_subdevdata(sd);
1252 struct rj54n1 *rj54n1 = to_rj54n1(client);
1253 int data; 1187 int data;
1254 1188
1255 switch (ctrl->id) { 1189 switch (ctrl->id) {
1256 case V4L2_CID_VFLIP: 1190 case V4L2_CID_VFLIP:
1257 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE); 1191 if (ctrl->val)
1258 if (data < 0)
1259 return -EIO;
1260 ctrl->value = !(data & 1);
1261 break;
1262 case V4L2_CID_HFLIP:
1263 data = reg_read(client, RJ54N1_MIRROR_STILL_MODE);
1264 if (data < 0)
1265 return -EIO;
1266 ctrl->value = !(data & 2);
1267 break;
1268 case V4L2_CID_GAIN:
1269 data = reg_read(client, RJ54N1_Y_GAIN);
1270 if (data < 0)
1271 return -EIO;
1272
1273 ctrl->value = data / 2;
1274 break;
1275 case V4L2_CID_AUTO_WHITE_BALANCE:
1276 ctrl->value = rj54n1->auto_wb;
1277 break;
1278 }
1279
1280 return 0;
1281}
1282
1283static int rj54n1_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
1284{
1285 int data;
1286 struct i2c_client *client = v4l2_get_subdevdata(sd);
1287 struct rj54n1 *rj54n1 = to_rj54n1(client);
1288 const struct v4l2_queryctrl *qctrl;
1289
1290 qctrl = soc_camera_find_qctrl(&rj54n1_ops, ctrl->id);
1291 if (!qctrl)
1292 return -EINVAL;
1293
1294 switch (ctrl->id) {
1295 case V4L2_CID_VFLIP:
1296 if (ctrl->value)
1297 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1); 1192 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 1);
1298 else 1193 else
1299 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1); 1194 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 1, 1);
1300 if (data < 0) 1195 if (data < 0)
1301 return -EIO; 1196 return -EIO;
1302 break; 1197 return 0;
1303 case V4L2_CID_HFLIP: 1198 case V4L2_CID_HFLIP:
1304 if (ctrl->value) 1199 if (ctrl->val)
1305 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2); 1200 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 0, 2);
1306 else 1201 else
1307 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2); 1202 data = reg_set(client, RJ54N1_MIRROR_STILL_MODE, 2, 2);
1308 if (data < 0) 1203 if (data < 0)
1309 return -EIO; 1204 return -EIO;
1310 break; 1205 return 0;
1311 case V4L2_CID_GAIN: 1206 case V4L2_CID_GAIN:
1312 if (ctrl->value > qctrl->maximum || 1207 if (reg_write(client, RJ54N1_Y_GAIN, ctrl->val * 2) < 0)
1313 ctrl->value < qctrl->minimum)
1314 return -EINVAL;
1315 else if (reg_write(client, RJ54N1_Y_GAIN, ctrl->value * 2) < 0)
1316 return -EIO; 1208 return -EIO;
1317 break; 1209 return 0;
1318 case V4L2_CID_AUTO_WHITE_BALANCE: 1210 case V4L2_CID_AUTO_WHITE_BALANCE:
1319 /* Auto WB area - whole image */ 1211 /* Auto WB area - whole image */
1320 if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->value << 7, 1212 if (reg_set(client, RJ54N1_WB_SEL_WEIGHT_I, ctrl->val << 7,
1321 0x80) < 0) 1213 0x80) < 0)
1322 return -EIO; 1214 return -EIO;
1323 rj54n1->auto_wb = ctrl->value; 1215 rj54n1->auto_wb = ctrl->val;
1324 break; 1216 return 0;
1325 } 1217 }
1326 1218
1327 return 0; 1219 return -EINVAL;
1328} 1220}
1329 1221
1222static const struct v4l2_ctrl_ops rj54n1_ctrl_ops = {
1223 .s_ctrl = rj54n1_s_ctrl,
1224};
1225
1330static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = { 1226static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1331 .g_ctrl = rj54n1_g_ctrl,
1332 .s_ctrl = rj54n1_s_ctrl,
1333 .g_chip_ident = rj54n1_g_chip_ident, 1227 .g_chip_ident = rj54n1_g_chip_ident,
1334#ifdef CONFIG_VIDEO_ADV_DEBUG 1228#ifdef CONFIG_VIDEO_ADV_DEBUG
1335 .g_register = rj54n1_g_register, 1229 .g_register = rj54n1_g_register,
@@ -1337,6 +1231,36 @@ static struct v4l2_subdev_core_ops rj54n1_subdev_core_ops = {
1337#endif 1231#endif
1338}; 1232};
1339 1233
1234static int rj54n1_g_mbus_config(struct v4l2_subdev *sd,
1235 struct v4l2_mbus_config *cfg)
1236{
1237 struct i2c_client *client = v4l2_get_subdevdata(sd);
1238 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1239
1240 cfg->flags =
1241 V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING |
1242 V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH |
1243 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH;
1244 cfg->type = V4L2_MBUS_PARALLEL;
1245 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
1246
1247 return 0;
1248}
1249
1250static int rj54n1_s_mbus_config(struct v4l2_subdev *sd,
1251 const struct v4l2_mbus_config *cfg)
1252{
1253 struct i2c_client *client = v4l2_get_subdevdata(sd);
1254 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1255
1256 /* Figures 2.5-1 to 2.5-3 - default falling pixclk edge */
1257 if (soc_camera_apply_board_flags(icl, cfg) &
1258 V4L2_MBUS_PCLK_SAMPLE_RISING)
1259 return reg_write(client, RJ54N1_OUT_SIGPO, 1 << 4);
1260 else
1261 return reg_write(client, RJ54N1_OUT_SIGPO, 0);
1262}
1263
1340static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = { 1264static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1341 .s_stream = rj54n1_s_stream, 1265 .s_stream = rj54n1_s_stream,
1342 .s_mbus_fmt = rj54n1_s_fmt, 1266 .s_mbus_fmt = rj54n1_s_fmt,
@@ -1346,6 +1270,8 @@ static struct v4l2_subdev_video_ops rj54n1_subdev_video_ops = {
1346 .g_crop = rj54n1_g_crop, 1270 .g_crop = rj54n1_g_crop,
1347 .s_crop = rj54n1_s_crop, 1271 .s_crop = rj54n1_s_crop,
1348 .cropcap = rj54n1_cropcap, 1272 .cropcap = rj54n1_cropcap,
1273 .g_mbus_config = rj54n1_g_mbus_config,
1274 .s_mbus_config = rj54n1_s_mbus_config,
1349}; 1275};
1350 1276
1351static struct v4l2_subdev_ops rj54n1_subdev_ops = { 1277static struct v4l2_subdev_ops rj54n1_subdev_ops = {
@@ -1357,17 +1283,12 @@ static struct v4l2_subdev_ops rj54n1_subdev_ops = {
1357 * Interface active, can use i2c. If it fails, it can indeed mean, that 1283 * Interface active, can use i2c. If it fails, it can indeed mean, that
1358 * this wasn't our capture interface, so, we wait for the right one 1284 * this wasn't our capture interface, so, we wait for the right one
1359 */ 1285 */
1360static int rj54n1_video_probe(struct soc_camera_device *icd, 1286static int rj54n1_video_probe(struct i2c_client *client,
1361 struct i2c_client *client,
1362 struct rj54n1_pdata *priv) 1287 struct rj54n1_pdata *priv)
1363{ 1288{
1364 int data1, data2; 1289 int data1, data2;
1365 int ret; 1290 int ret;
1366 1291
1367 /* We must have a parent by now. And it cannot be a wrong one. */
1368 BUG_ON(!icd->parent ||
1369 to_soc_camera_host(icd->parent)->nr != icd->iface);
1370
1371 /* Read out the chip version register */ 1292 /* Read out the chip version register */
1372 data1 = reg_read(client, RJ54N1_DEV_CODE); 1293 data1 = reg_read(client, RJ54N1_DEV_CODE);
1373 data2 = reg_read(client, RJ54N1_DEV_CODE2); 1294 data2 = reg_read(client, RJ54N1_DEV_CODE2);
@@ -1395,18 +1316,11 @@ static int rj54n1_probe(struct i2c_client *client,
1395 const struct i2c_device_id *did) 1316 const struct i2c_device_id *did)
1396{ 1317{
1397 struct rj54n1 *rj54n1; 1318 struct rj54n1 *rj54n1;
1398 struct soc_camera_device *icd = client->dev.platform_data; 1319 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1399 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); 1320 struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
1400 struct soc_camera_link *icl;
1401 struct rj54n1_pdata *rj54n1_priv; 1321 struct rj54n1_pdata *rj54n1_priv;
1402 int ret; 1322 int ret;
1403 1323
1404 if (!icd) {
1405 dev_err(&client->dev, "RJ54N1CB0C: missing soc-camera data!\n");
1406 return -EINVAL;
1407 }
1408
1409 icl = to_soc_camera_link(icd);
1410 if (!icl || !icl->priv) { 1324 if (!icl || !icl->priv) {
1411 dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n"); 1325 dev_err(&client->dev, "RJ54N1CB0C: missing platform data!\n");
1412 return -EINVAL; 1326 return -EINVAL;
@@ -1425,8 +1339,22 @@ static int rj54n1_probe(struct i2c_client *client,
1425 return -ENOMEM; 1339 return -ENOMEM;
1426 1340
1427 v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops); 1341 v4l2_i2c_subdev_init(&rj54n1->subdev, client, &rj54n1_subdev_ops);
1342 v4l2_ctrl_handler_init(&rj54n1->hdl, 4);
1343 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1344 V4L2_CID_VFLIP, 0, 1, 1, 0);
1345 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1346 V4L2_CID_HFLIP, 0, 1, 1, 0);
1347 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1348 V4L2_CID_GAIN, 0, 127, 1, 66);
1349 v4l2_ctrl_new_std(&rj54n1->hdl, &rj54n1_ctrl_ops,
1350 V4L2_CID_AUTO_WHITE_BALANCE, 0, 1, 1, 1);
1351 rj54n1->subdev.ctrl_handler = &rj54n1->hdl;
1352 if (rj54n1->hdl.error) {
1353 int err = rj54n1->hdl.error;
1428 1354
1429 icd->ops = &rj54n1_ops; 1355 kfree(rj54n1);
1356 return err;
1357 }
1430 1358
1431 rj54n1->clk_div = clk_div; 1359 rj54n1->clk_div = clk_div;
1432 rj54n1->rect.left = RJ54N1_COLUMN_SKIP; 1360 rj54n1->rect.left = RJ54N1_COLUMN_SKIP;
@@ -1440,25 +1368,24 @@ static int rj54n1_probe(struct i2c_client *client,
1440 rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) / 1368 rj54n1->tgclk_mhz = (rj54n1_priv->mclk_freq / PLL_L * PLL_N) /
1441 (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1); 1369 (clk_div.ratio_tg + 1) / (clk_div.ratio_t + 1);
1442 1370
1443 ret = rj54n1_video_probe(icd, client, rj54n1_priv); 1371 ret = rj54n1_video_probe(client, rj54n1_priv);
1444 if (ret < 0) { 1372 if (ret < 0) {
1445 icd->ops = NULL; 1373 v4l2_ctrl_handler_free(&rj54n1->hdl);
1446 kfree(rj54n1); 1374 kfree(rj54n1);
1447 return ret; 1375 return ret;
1448 } 1376 }
1449 1377 return v4l2_ctrl_handler_setup(&rj54n1->hdl);
1450 return ret;
1451} 1378}
1452 1379
1453static int rj54n1_remove(struct i2c_client *client) 1380static int rj54n1_remove(struct i2c_client *client)
1454{ 1381{
1455 struct rj54n1 *rj54n1 = to_rj54n1(client); 1382 struct rj54n1 *rj54n1 = to_rj54n1(client);
1456 struct soc_camera_device *icd = client->dev.platform_data; 1383 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
1457 struct soc_camera_link *icl = to_soc_camera_link(icd);
1458 1384
1459 icd->ops = NULL; 1385 v4l2_device_unregister_subdev(&rj54n1->subdev);
1460 if (icl->free_bus) 1386 if (icl->free_bus)
1461 icl->free_bus(icl); 1387 icl->free_bus(icl);
1388 v4l2_ctrl_handler_free(&rj54n1->hdl);
1462 kfree(rj54n1); 1389 kfree(rj54n1);
1463 1390
1464 return 0; 1391 return 0;
diff --git a/drivers/media/video/s5k6aa.c b/drivers/media/video/s5k6aa.c
new file mode 100644
index 00000000000..2446736b787
--- /dev/null
+++ b/drivers/media/video/s5k6aa.c
@@ -0,0 +1,1680 @@
1/*
2 * Driver for Samsung S5K6AAFX SXGA 1/6" 1.3M CMOS Image Sensor
3 * with embedded SoC ISP.
4 *
5 * Copyright (C) 2011, Samsung Electronics Co., Ltd.
6 * Sylwester Nawrocki <s.nawrocki@samsung.com>
7 *
8 * Based on a driver authored by Dongsoo Nathaniel Kim.
9 * Copyright (C) 2009, Dongsoo Nathaniel Kim <dongsoo45.kim@samsung.com>
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 as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 */
16
17#include <linux/clk.h>
18#include <linux/delay.h>
19#include <linux/gpio.h>
20#include <linux/i2c.h>
21#include <linux/media.h>
22#include <linux/regulator/consumer.h>
23#include <linux/slab.h>
24
25#include <media/media-entity.h>
26#include <media/v4l2-ctrls.h>
27#include <media/v4l2-device.h>
28#include <media/v4l2-subdev.h>
29#include <media/v4l2-mediabus.h>
30#include <media/s5k6aa.h>
31
32static int debug;
33module_param(debug, int, 0644);
34
35#define DRIVER_NAME "S5K6AA"
36
37/* The token to indicate array termination */
38#define S5K6AA_TERM 0xffff
39#define S5K6AA_OUT_WIDTH_DEF 640
40#define S5K6AA_OUT_HEIGHT_DEF 480
41#define S5K6AA_WIN_WIDTH_MAX 1280
42#define S5K6AA_WIN_HEIGHT_MAX 1024
43#define S5K6AA_WIN_WIDTH_MIN 8
44#define S5K6AA_WIN_HEIGHT_MIN 8
45
46/*
47 * H/W register Interface (0xD0000000 - 0xD0000FFF)
48 */
49#define AHB_MSB_ADDR_PTR 0xfcfc
50#define GEN_REG_OFFSH 0xd000
51#define REG_CMDWR_ADDRH 0x0028
52#define REG_CMDWR_ADDRL 0x002a
53#define REG_CMDRD_ADDRH 0x002c
54#define REG_CMDRD_ADDRL 0x002e
55#define REG_CMDBUF0_ADDR 0x0f12
56#define REG_CMDBUF1_ADDR 0x0f10
57
58/*
59 * Host S/W Register interface (0x70000000 - 0x70002000)
60 * The value of the two most significant address bytes is 0x7000,
61 * (HOST_SWIF_OFFS_H). The register addresses below specify 2 LSBs.
62 */
63#define HOST_SWIF_OFFSH 0x7000
64
65/* Initialization parameters */
66/* Master clock frequency in KHz */
67#define REG_I_INCLK_FREQ_L 0x01b8
68#define REG_I_INCLK_FREQ_H 0x01ba
69#define MIN_MCLK_FREQ_KHZ 6000U
70#define MAX_MCLK_FREQ_KHZ 27000U
71#define REG_I_USE_NPVI_CLOCKS 0x01c6
72#define REG_I_USE_NMIPI_CLOCKS 0x01c8
73
74/* Clock configurations, n = 0..2. REG_I_* frequency unit is 4 kHz. */
75#define REG_I_OPCLK_4KHZ(n) ((n) * 6 + 0x01cc)
76#define REG_I_MIN_OUTRATE_4KHZ(n) ((n) * 6 + 0x01ce)
77#define REG_I_MAX_OUTRATE_4KHZ(n) ((n) * 6 + 0x01d0)
78#define SYS_PLL_OUT_FREQ (48000000 / 4000)
79#define PCLK_FREQ_MIN (24000000 / 4000)
80#define PCLK_FREQ_MAX (48000000 / 4000)
81#define REG_I_INIT_PARAMS_UPDATED 0x01e0
82#define REG_I_ERROR_INFO 0x01e2
83
84/* General purpose parameters */
85#define REG_USER_BRIGHTNESS 0x01e4
86#define REG_USER_CONTRAST 0x01e6
87#define REG_USER_SATURATION 0x01e8
88#define REG_USER_SHARPBLUR 0x01ea
89
90#define REG_G_SPEC_EFFECTS 0x01ee
91#define REG_G_ENABLE_PREV 0x01f0
92#define REG_G_ENABLE_PREV_CHG 0x01f2
93#define REG_G_NEW_CFG_SYNC 0x01f8
94#define REG_G_PREVZOOM_IN_WIDTH 0x020a
95#define REG_G_PREVZOOM_IN_HEIGHT 0x020c
96#define REG_G_PREVZOOM_IN_XOFFS 0x020e
97#define REG_G_PREVZOOM_IN_YOFFS 0x0210
98#define REG_G_INPUTS_CHANGE_REQ 0x021a
99#define REG_G_ACTIVE_PREV_CFG 0x021c
100#define REG_G_PREV_CFG_CHG 0x021e
101#define REG_G_PREV_OPEN_AFTER_CH 0x0220
102#define REG_G_PREV_CFG_ERROR 0x0222
103
104/* Preview control section. n = 0...4. */
105#define PREG(n, x) ((n) * 0x26 + x)
106#define REG_P_OUT_WIDTH(n) PREG(n, 0x0242)
107#define REG_P_OUT_HEIGHT(n) PREG(n, 0x0244)
108#define REG_P_FMT(n) PREG(n, 0x0246)
109#define REG_P_MAX_OUT_RATE(n) PREG(n, 0x0248)
110#define REG_P_MIN_OUT_RATE(n) PREG(n, 0x024a)
111#define REG_P_PVI_MASK(n) PREG(n, 0x024c)
112#define REG_P_CLK_INDEX(n) PREG(n, 0x024e)
113#define REG_P_FR_RATE_TYPE(n) PREG(n, 0x0250)
114#define FR_RATE_DYNAMIC 0
115#define FR_RATE_FIXED 1
116#define FR_RATE_FIXED_ACCURATE 2
117#define REG_P_FR_RATE_Q_TYPE(n) PREG(n, 0x0252)
118#define FR_RATE_Q_BEST_FRRATE 1 /* Binning enabled */
119#define FR_RATE_Q_BEST_QUALITY 2 /* Binning disabled */
120/* Frame period in 0.1 ms units */
121#define REG_P_MAX_FR_TIME(n) PREG(n, 0x0254)
122#define REG_P_MIN_FR_TIME(n) PREG(n, 0x0256)
123/* Conversion to REG_P_[MAX/MIN]_FR_TIME value; __t: time in us */
124#define US_TO_FR_TIME(__t) ((__t) / 100)
125#define S5K6AA_MIN_FR_TIME 33300 /* us */
126#define S5K6AA_MAX_FR_TIME 650000 /* us */
127#define S5K6AA_MAX_HIGHRES_FR_TIME 666 /* x100 us */
128/* The below 5 registers are for "device correction" values */
129#define REG_P_COLORTEMP(n) PREG(n, 0x025e)
130#define REG_P_PREV_MIRROR(n) PREG(n, 0x0262)
131
132/* Extended image property controls */
133/* Exposure time in 10 us units */
134#define REG_SF_USR_EXPOSURE_L 0x03c6
135#define REG_SF_USR_EXPOSURE_H 0x03c8
136#define REG_SF_USR_EXPOSURE_CHG 0x03ca
137#define REG_SF_USR_TOT_GAIN 0x03cc
138#define REG_SF_USR_TOT_GAIN_CHG 0x03ce
139#define REG_SF_RGAIN 0x03d0
140#define REG_SF_RGAIN_CHG 0x03d2
141#define REG_SF_GGAIN 0x03d4
142#define REG_SF_GGAIN_CHG 0x03d6
143#define REG_SF_BGAIN 0x03d8
144#define REG_SF_BGAIN_CHG 0x03da
145#define REG_SF_FLICKER_QUANT 0x03dc
146#define REG_SF_FLICKER_QUANT_CHG 0x03de
147
148/* Output interface (parallel/MIPI) setup */
149#define REG_OIF_EN_MIPI_LANES 0x03fa
150#define REG_OIF_EN_PACKETS 0x03fc
151#define REG_OIF_CFG_CHG 0x03fe
152
153/* Auto-algorithms enable mask */
154#define REG_DBG_AUTOALG_EN 0x0400
155#define AALG_ALL_EN_MASK (1 << 0)
156#define AALG_AE_EN_MASK (1 << 1)
157#define AALG_DIVLEI_EN_MASK (1 << 2)
158#define AALG_WB_EN_MASK (1 << 3)
159#define AALG_FLICKER_EN_MASK (1 << 5)
160#define AALG_FIT_EN_MASK (1 << 6)
161#define AALG_WRHW_EN_MASK (1 << 7)
162
163/* Firmware revision information */
164#define REG_FW_APIVER 0x012e
165#define S5K6AAFX_FW_APIVER 0x0001
166#define REG_FW_REVISION 0x0130
167
168/* For now we use only one user configuration register set */
169#define S5K6AA_MAX_PRESETS 1
170
171static const char * const s5k6aa_supply_names[] = {
172 "vdd_core", /* Digital core supply 1.5V (1.4V to 1.6V) */
173 "vdda", /* Analog power supply 2.8V (2.6V to 3.0V) */
174 "vdd_reg", /* Regulator input power 1.8V (1.7V to 1.9V)
175 or 2.8V (2.6V to 3.0) */
176 "vddio", /* I/O supply 1.8V (1.65V to 1.95V)
177 or 2.8V (2.5V to 3.1V) */
178};
179#define S5K6AA_NUM_SUPPLIES ARRAY_SIZE(s5k6aa_supply_names)
180
181enum s5k6aa_gpio_id {
182 STBY,
183 RST,
184 GPIO_NUM,
185};
186
187struct s5k6aa_regval {
188 u16 addr;
189 u16 val;
190};
191
192struct s5k6aa_pixfmt {
193 enum v4l2_mbus_pixelcode code;
194 u32 colorspace;
195 /* REG_P_FMT(x) register value */
196 u16 reg_p_fmt;
197};
198
199struct s5k6aa_preset {
200 /* output pixel format and resolution */
201 struct v4l2_mbus_framefmt mbus_fmt;
202 u8 clk_id;
203 u8 index;
204};
205
206struct s5k6aa_ctrls {
207 struct v4l2_ctrl_handler handler;
208 /* Auto / manual white balance cluster */
209 struct v4l2_ctrl *awb;
210 struct v4l2_ctrl *gain_red;
211 struct v4l2_ctrl *gain_blue;
212 struct v4l2_ctrl *gain_green;
213 /* Mirror cluster */
214 struct v4l2_ctrl *hflip;
215 struct v4l2_ctrl *vflip;
216 /* Auto exposure / manual exposure and gain cluster */
217 struct v4l2_ctrl *auto_exp;
218 struct v4l2_ctrl *exposure;
219 struct v4l2_ctrl *gain;
220};
221
222struct s5k6aa_interval {
223 u16 reg_fr_time;
224 struct v4l2_fract interval;
225 /* Maximum rectangle for the interval */
226 struct v4l2_frmsize_discrete size;
227};
228
229struct s5k6aa {
230 struct v4l2_subdev sd;
231 struct media_pad pad;
232
233 enum v4l2_mbus_type bus_type;
234 u8 mipi_lanes;
235
236 int (*s_power)(int enable);
237 struct regulator_bulk_data supplies[S5K6AA_NUM_SUPPLIES];
238 struct s5k6aa_gpio gpio[GPIO_NUM];
239
240 /* external master clock frequency */
241 unsigned long mclk_frequency;
242 /* ISP internal master clock frequency */
243 u16 clk_fop;
244 /* output pixel clock frequency range */
245 u16 pclk_fmin;
246 u16 pclk_fmax;
247
248 unsigned int inv_hflip:1;
249 unsigned int inv_vflip:1;
250
251 /* protects the struct members below */
252 struct mutex lock;
253
254 /* sensor matrix scan window */
255 struct v4l2_rect ccd_rect;
256
257 struct s5k6aa_ctrls ctrls;
258 struct s5k6aa_preset presets[S5K6AA_MAX_PRESETS];
259 struct s5k6aa_preset *preset;
260 const struct s5k6aa_interval *fiv;
261
262 unsigned int streaming:1;
263 unsigned int apply_cfg:1;
264 unsigned int apply_crop:1;
265 unsigned int power;
266};
267
268static struct s5k6aa_regval s5k6aa_analog_config[] = {
269 /* Analog settings */
270 { 0x112a, 0x0000 }, { 0x1132, 0x0000 },
271 { 0x113e, 0x0000 }, { 0x115c, 0x0000 },
272 { 0x1164, 0x0000 }, { 0x1174, 0x0000 },
273 { 0x1178, 0x0000 }, { 0x077a, 0x0000 },
274 { 0x077c, 0x0000 }, { 0x077e, 0x0000 },
275 { 0x0780, 0x0000 }, { 0x0782, 0x0000 },
276 { 0x0784, 0x0000 }, { 0x0786, 0x0000 },
277 { 0x0788, 0x0000 }, { 0x07a2, 0x0000 },
278 { 0x07a4, 0x0000 }, { 0x07a6, 0x0000 },
279 { 0x07a8, 0x0000 }, { 0x07b6, 0x0000 },
280 { 0x07b8, 0x0002 }, { 0x07ba, 0x0004 },
281 { 0x07bc, 0x0004 }, { 0x07be, 0x0005 },
282 { 0x07c0, 0x0005 }, { S5K6AA_TERM, 0 },
283};
284
285/* TODO: Add RGB888 and Bayer format */
286static const struct s5k6aa_pixfmt s5k6aa_formats[] = {
287 { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_JPEG, 5 },
288 /* range 16-240 */
289 { V4L2_MBUS_FMT_YUYV8_2X8, V4L2_COLORSPACE_REC709, 6 },
290 { V4L2_MBUS_FMT_RGB565_2X8_BE, V4L2_COLORSPACE_JPEG, 0 },
291};
292
293static const struct s5k6aa_interval s5k6aa_intervals[] = {
294 { 1000, {10000, 1000000}, {1280, 1024} }, /* 10 fps */
295 { 666, {15000, 1000000}, {1280, 1024} }, /* 15 fps */
296 { 500, {20000, 1000000}, {1280, 720} }, /* 20 fps */
297 { 400, {25000, 1000000}, {640, 480} }, /* 25 fps */
298 { 333, {33300, 1000000}, {640, 480} }, /* 30 fps */
299};
300
301#define S5K6AA_INTERVAL_DEF_INDEX 1 /* 15 fps */
302
303static inline struct v4l2_subdev *ctrl_to_sd(struct v4l2_ctrl *ctrl)
304{
305 return &container_of(ctrl->handler, struct s5k6aa, ctrls.handler)->sd;
306}
307
308static inline struct s5k6aa *to_s5k6aa(struct v4l2_subdev *sd)
309{
310 return container_of(sd, struct s5k6aa, sd);
311}
312
313/* Set initial values for all preview presets */
314static void s5k6aa_presets_data_init(struct s5k6aa *s5k6aa)
315{
316 struct s5k6aa_preset *preset = &s5k6aa->presets[0];
317 int i;
318
319 for (i = 0; i < S5K6AA_MAX_PRESETS; i++) {
320 preset->mbus_fmt.width = S5K6AA_OUT_WIDTH_DEF;
321 preset->mbus_fmt.height = S5K6AA_OUT_HEIGHT_DEF;
322 preset->mbus_fmt.code = s5k6aa_formats[0].code;
323 preset->index = i;
324 preset->clk_id = 0;
325 preset++;
326 }
327
328 s5k6aa->fiv = &s5k6aa_intervals[S5K6AA_INTERVAL_DEF_INDEX];
329 s5k6aa->preset = &s5k6aa->presets[0];
330}
331
332static int s5k6aa_i2c_read(struct i2c_client *client, u16 addr, u16 *val)
333{
334 u8 wbuf[2] = {addr >> 8, addr & 0xFF};
335 struct i2c_msg msg[2];
336 u8 rbuf[2];
337 int ret;
338
339 msg[0].addr = client->addr;
340 msg[0].flags = 0;
341 msg[0].len = 2;
342 msg[0].buf = wbuf;
343
344 msg[1].addr = client->addr;
345 msg[1].flags = I2C_M_RD;
346 msg[1].len = 2;
347 msg[1].buf = rbuf;
348
349 ret = i2c_transfer(client->adapter, msg, 2);
350 *val = be16_to_cpu(*((u16 *)rbuf));
351
352 v4l2_dbg(3, debug, client, "i2c_read: 0x%04X : 0x%04x\n", addr, *val);
353
354 return ret == 2 ? 0 : ret;
355}
356
357static int s5k6aa_i2c_write(struct i2c_client *client, u16 addr, u16 val)
358{
359 u8 buf[4] = {addr >> 8, addr & 0xFF, val >> 8, val & 0xFF};
360
361 int ret = i2c_master_send(client, buf, 4);
362 v4l2_dbg(3, debug, client, "i2c_write: 0x%04X : 0x%04x\n", addr, val);
363
364 return ret == 4 ? 0 : ret;
365}
366
367/* The command register write, assumes Command_Wr_addH = 0x7000. */
368static int s5k6aa_write(struct i2c_client *c, u16 addr, u16 val)
369{
370 int ret = s5k6aa_i2c_write(c, REG_CMDWR_ADDRL, addr);
371 if (ret)
372 return ret;
373 return s5k6aa_i2c_write(c, REG_CMDBUF0_ADDR, val);
374}
375
376/* The command register read, assumes Command_Rd_addH = 0x7000. */
377static int s5k6aa_read(struct i2c_client *client, u16 addr, u16 *val)
378{
379 int ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRL, addr);
380 if (ret)
381 return ret;
382 return s5k6aa_i2c_read(client, REG_CMDBUF0_ADDR, val);
383}
384
385static int s5k6aa_write_array(struct v4l2_subdev *sd,
386 const struct s5k6aa_regval *msg)
387{
388 struct i2c_client *client = v4l2_get_subdevdata(sd);
389 u16 addr_incr = 0;
390 int ret = 0;
391
392 while (msg->addr != S5K6AA_TERM) {
393 if (addr_incr != 2)
394 ret = s5k6aa_i2c_write(client, REG_CMDWR_ADDRL,
395 msg->addr);
396 if (ret)
397 break;
398 ret = s5k6aa_i2c_write(client, REG_CMDBUF0_ADDR, msg->val);
399 if (ret)
400 break;
401 /* Assume that msg->addr is always less than 0xfffc */
402 addr_incr = (msg + 1)->addr - msg->addr;
403 msg++;
404 }
405
406 return ret;
407}
408
409/* Configure the AHB high address bytes for GTG registers access */
410static int s5k6aa_set_ahb_address(struct i2c_client *client)
411{
412 int ret = s5k6aa_i2c_write(client, AHB_MSB_ADDR_PTR, GEN_REG_OFFSH);
413 if (ret)
414 return ret;
415 ret = s5k6aa_i2c_write(client, REG_CMDRD_ADDRH, HOST_SWIF_OFFSH);
416 if (ret)
417 return ret;
418 return s5k6aa_i2c_write(client, REG_CMDWR_ADDRH, HOST_SWIF_OFFSH);
419}
420
421/**
422 * s5k6aa_configure_pixel_clock - apply ISP main clock/PLL configuration
423 *
424 * Configure the internal ISP PLL for the required output frequency.
425 * Locking: called with s5k6aa.lock mutex held.
426 */
427static int s5k6aa_configure_pixel_clocks(struct s5k6aa *s5k6aa)
428{
429 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
430 unsigned long fmclk = s5k6aa->mclk_frequency / 1000;
431 u16 status;
432 int ret;
433
434 if (WARN(fmclk < MIN_MCLK_FREQ_KHZ || fmclk > MAX_MCLK_FREQ_KHZ,
435 "Invalid clock frequency: %ld\n", fmclk))
436 return -EINVAL;
437
438 s5k6aa->pclk_fmin = PCLK_FREQ_MIN;
439 s5k6aa->pclk_fmax = PCLK_FREQ_MAX;
440 s5k6aa->clk_fop = SYS_PLL_OUT_FREQ;
441
442 /* External input clock frequency in kHz */
443 ret = s5k6aa_write(c, REG_I_INCLK_FREQ_H, fmclk >> 16);
444 if (!ret)
445 ret = s5k6aa_write(c, REG_I_INCLK_FREQ_L, fmclk & 0xFFFF);
446 if (!ret)
447 ret = s5k6aa_write(c, REG_I_USE_NPVI_CLOCKS, 1);
448 /* Internal PLL frequency */
449 if (!ret)
450 ret = s5k6aa_write(c, REG_I_OPCLK_4KHZ(0), s5k6aa->clk_fop);
451 if (!ret)
452 ret = s5k6aa_write(c, REG_I_MIN_OUTRATE_4KHZ(0),
453 s5k6aa->pclk_fmin);
454 if (!ret)
455 ret = s5k6aa_write(c, REG_I_MAX_OUTRATE_4KHZ(0),
456 s5k6aa->pclk_fmax);
457 if (!ret)
458 ret = s5k6aa_write(c, REG_I_INIT_PARAMS_UPDATED, 1);
459 if (!ret)
460 ret = s5k6aa_read(c, REG_I_ERROR_INFO, &status);
461
462 return ret ? ret : (status ? -EINVAL : 0);
463}
464
465/* Set horizontal and vertical image flipping */
466static int s5k6aa_set_mirror(struct s5k6aa *s5k6aa, int horiz_flip)
467{
468 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
469 int index = s5k6aa->preset->index;
470
471 unsigned int vflip = s5k6aa->ctrls.vflip->val ^ s5k6aa->inv_vflip;
472 unsigned int flip = (horiz_flip ^ s5k6aa->inv_hflip) | (vflip << 1);
473
474 return s5k6aa_write(client, REG_P_PREV_MIRROR(index), flip);
475}
476
477/* Configure auto/manual white balance and R/G/B gains */
478static int s5k6aa_set_awb(struct s5k6aa *s5k6aa, int awb)
479{
480 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
481 struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
482 u16 reg;
483
484 int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &reg);
485
486 if (!ret && !awb) {
487 ret = s5k6aa_write(c, REG_SF_RGAIN, ctrls->gain_red->val);
488 if (!ret)
489 ret = s5k6aa_write(c, REG_SF_RGAIN_CHG, 1);
490 if (ret)
491 return ret;
492
493 ret = s5k6aa_write(c, REG_SF_GGAIN, ctrls->gain_green->val);
494 if (!ret)
495 ret = s5k6aa_write(c, REG_SF_GGAIN_CHG, 1);
496 if (ret)
497 return ret;
498
499 ret = s5k6aa_write(c, REG_SF_BGAIN, ctrls->gain_blue->val);
500 if (!ret)
501 ret = s5k6aa_write(c, REG_SF_BGAIN_CHG, 1);
502 }
503 if (!ret) {
504 reg = awb ? reg | AALG_WB_EN_MASK : reg & ~AALG_WB_EN_MASK;
505 ret = s5k6aa_write(c, REG_DBG_AUTOALG_EN, reg);
506 }
507
508 return ret;
509}
510
511/* Program FW with exposure time, 'exposure' in us units */
512static int s5k6aa_set_user_exposure(struct i2c_client *client, int exposure)
513{
514 unsigned int time = exposure / 10;
515
516 int ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_L, time & 0xffff);
517 if (!ret)
518 ret = s5k6aa_write(client, REG_SF_USR_EXPOSURE_H, time >> 16);
519 if (ret)
520 return ret;
521 return s5k6aa_write(client, REG_SF_USR_EXPOSURE_CHG, 1);
522}
523
524static int s5k6aa_set_user_gain(struct i2c_client *client, int gain)
525{
526 int ret = s5k6aa_write(client, REG_SF_USR_TOT_GAIN, gain);
527 if (ret)
528 return ret;
529 return s5k6aa_write(client, REG_SF_USR_TOT_GAIN_CHG, 1);
530}
531
532/* Set auto/manual exposure and total gain */
533static int s5k6aa_set_auto_exposure(struct s5k6aa *s5k6aa, int value)
534{
535 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
536 unsigned int exp_time = s5k6aa->ctrls.exposure->val;
537 u16 auto_alg;
538
539 int ret = s5k6aa_read(c, REG_DBG_AUTOALG_EN, &auto_alg);
540 if (ret)
541 return ret;
542
543 v4l2_dbg(1, debug, c, "man_exp: %d, auto_exp: %d, a_alg: 0x%x\n",
544 exp_time, value, auto_alg);
545
546 if (value == V4L2_EXPOSURE_AUTO) {
547 auto_alg |= AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK;
548 } else {
549 ret = s5k6aa_set_user_exposure(c, exp_time);
550 if (ret)
551 return ret;
552 ret = s5k6aa_set_user_gain(c, s5k6aa->ctrls.gain->val);
553 if (ret)
554 return ret;
555 auto_alg &= ~(AALG_AE_EN_MASK | AALG_DIVLEI_EN_MASK);
556 }
557
558 return s5k6aa_write(c, REG_DBG_AUTOALG_EN, auto_alg);
559}
560
561static int s5k6aa_set_anti_flicker(struct s5k6aa *s5k6aa, int value)
562{
563 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
564 u16 auto_alg;
565 int ret;
566
567 ret = s5k6aa_read(client, REG_DBG_AUTOALG_EN, &auto_alg);
568 if (ret)
569 return ret;
570
571 if (value == V4L2_CID_POWER_LINE_FREQUENCY_AUTO) {
572 auto_alg |= AALG_FLICKER_EN_MASK;
573 } else {
574 auto_alg &= ~AALG_FLICKER_EN_MASK;
575 /* The V4L2_CID_LINE_FREQUENCY control values match
576 * the register values */
577 ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT, value);
578 if (ret)
579 return ret;
580 ret = s5k6aa_write(client, REG_SF_FLICKER_QUANT_CHG, 1);
581 if (ret)
582 return ret;
583 }
584
585 return s5k6aa_write(client, REG_DBG_AUTOALG_EN, auto_alg);
586}
587
588static int s5k6aa_set_colorfx(struct s5k6aa *s5k6aa, int val)
589{
590 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
591 static const struct v4l2_control colorfx[] = {
592 { V4L2_COLORFX_NONE, 0 },
593 { V4L2_COLORFX_BW, 1 },
594 { V4L2_COLORFX_NEGATIVE, 2 },
595 { V4L2_COLORFX_SEPIA, 3 },
596 { V4L2_COLORFX_SKY_BLUE, 4 },
597 { V4L2_COLORFX_SKETCH, 5 },
598 };
599 int i;
600
601 for (i = 0; i < ARRAY_SIZE(colorfx); i++) {
602 if (colorfx[i].id == val)
603 return s5k6aa_write(client, REG_G_SPEC_EFFECTS,
604 colorfx[i].value);
605 }
606 return -EINVAL;
607}
608
609static int s5k6aa_preview_config_status(struct i2c_client *client)
610{
611 u16 error = 0;
612 int ret = s5k6aa_read(client, REG_G_PREV_CFG_ERROR, &error);
613
614 v4l2_dbg(1, debug, client, "error: 0x%x (%d)\n", error, ret);
615 return ret ? ret : (error ? -EINVAL : 0);
616}
617
618static int s5k6aa_get_pixfmt_index(struct s5k6aa *s5k6aa,
619 struct v4l2_mbus_framefmt *mf)
620{
621 unsigned int i;
622
623 for (i = 0; i < ARRAY_SIZE(s5k6aa_formats); i++)
624 if (mf->colorspace == s5k6aa_formats[i].colorspace &&
625 mf->code == s5k6aa_formats[i].code)
626 return i;
627 return 0;
628}
629
630static int s5k6aa_set_output_framefmt(struct s5k6aa *s5k6aa,
631 struct s5k6aa_preset *preset)
632{
633 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
634 int fmt_index = s5k6aa_get_pixfmt_index(s5k6aa, &preset->mbus_fmt);
635 int ret;
636
637 ret = s5k6aa_write(client, REG_P_OUT_WIDTH(preset->index),
638 preset->mbus_fmt.width);
639 if (!ret)
640 ret = s5k6aa_write(client, REG_P_OUT_HEIGHT(preset->index),
641 preset->mbus_fmt.height);
642 if (!ret)
643 ret = s5k6aa_write(client, REG_P_FMT(preset->index),
644 s5k6aa_formats[fmt_index].reg_p_fmt);
645 return ret;
646}
647
648static int s5k6aa_set_input_params(struct s5k6aa *s5k6aa)
649{
650 struct i2c_client *c = v4l2_get_subdevdata(&s5k6aa->sd);
651 struct v4l2_rect *r = &s5k6aa->ccd_rect;
652 int ret;
653
654 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_WIDTH, r->width);
655 if (!ret)
656 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_HEIGHT, r->height);
657 if (!ret)
658 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_XOFFS, r->left);
659 if (!ret)
660 ret = s5k6aa_write(c, REG_G_PREVZOOM_IN_YOFFS, r->top);
661 if (!ret)
662 ret = s5k6aa_write(c, REG_G_INPUTS_CHANGE_REQ, 1);
663 if (!ret)
664 s5k6aa->apply_crop = 0;
665
666 return ret;
667}
668
669/**
670 * s5k6aa_configure_video_bus - configure the video output interface
671 * @bus_type: video bus type: parallel or MIPI-CSI
672 * @nlanes: number of MIPI lanes to be used (MIPI-CSI only)
673 *
674 * Note: Only parallel bus operation has been tested.
675 */
676static int s5k6aa_configure_video_bus(struct s5k6aa *s5k6aa,
677 enum v4l2_mbus_type bus_type, int nlanes)
678{
679 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
680 u16 cfg = 0;
681 int ret;
682
683 /*
684 * TODO: The sensor is supposed to support BT.601 and BT.656
685 * but there is nothing indicating how to switch between both
686 * in the datasheet. For now default BT.601 interface is assumed.
687 */
688 if (bus_type == V4L2_MBUS_CSI2)
689 cfg = nlanes;
690 else if (bus_type != V4L2_MBUS_PARALLEL)
691 return -EINVAL;
692
693 ret = s5k6aa_write(client, REG_OIF_EN_MIPI_LANES, cfg);
694 if (ret)
695 return ret;
696 return s5k6aa_write(client, REG_OIF_CFG_CHG, 1);
697}
698
699/* This function should be called when switching to new user configuration set*/
700static int s5k6aa_new_config_sync(struct i2c_client *client, int timeout,
701 int cid)
702{
703 unsigned long end = jiffies + msecs_to_jiffies(timeout);
704 u16 reg = 1;
705 int ret;
706
707 ret = s5k6aa_write(client, REG_G_ACTIVE_PREV_CFG, cid);
708 if (!ret)
709 ret = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
710 if (!ret)
711 ret = s5k6aa_write(client, REG_G_NEW_CFG_SYNC, 1);
712 if (timeout == 0)
713 return ret;
714
715 while (ret >= 0 && time_is_after_jiffies(end)) {
716 ret = s5k6aa_read(client, REG_G_NEW_CFG_SYNC, &reg);
717 if (!reg)
718 return 0;
719 usleep_range(1000, 5000);
720 }
721 return ret ? ret : -ETIMEDOUT;
722}
723
724/**
725 * s5k6aa_set_prev_config - write user preview register set
726 *
727 * Configure output resolution and color fromat, pixel clock
728 * frequency range, device frame rate type and frame period range.
729 */
730static int s5k6aa_set_prev_config(struct s5k6aa *s5k6aa,
731 struct s5k6aa_preset *preset)
732{
733 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
734 int idx = preset->index;
735 u16 frame_rate_q;
736 int ret;
737
738 if (s5k6aa->fiv->reg_fr_time >= S5K6AA_MAX_HIGHRES_FR_TIME)
739 frame_rate_q = FR_RATE_Q_BEST_FRRATE;
740 else
741 frame_rate_q = FR_RATE_Q_BEST_QUALITY;
742
743 ret = s5k6aa_set_output_framefmt(s5k6aa, preset);
744 if (!ret)
745 ret = s5k6aa_write(client, REG_P_MAX_OUT_RATE(idx),
746 s5k6aa->pclk_fmax);
747 if (!ret)
748 ret = s5k6aa_write(client, REG_P_MIN_OUT_RATE(idx),
749 s5k6aa->pclk_fmin);
750 if (!ret)
751 ret = s5k6aa_write(client, REG_P_CLK_INDEX(idx),
752 preset->clk_id);
753 if (!ret)
754 ret = s5k6aa_write(client, REG_P_FR_RATE_TYPE(idx),
755 FR_RATE_DYNAMIC);
756 if (!ret)
757 ret = s5k6aa_write(client, REG_P_FR_RATE_Q_TYPE(idx),
758 frame_rate_q);
759 if (!ret)
760 ret = s5k6aa_write(client, REG_P_MAX_FR_TIME(idx),
761 s5k6aa->fiv->reg_fr_time + 33);
762 if (!ret)
763 ret = s5k6aa_write(client, REG_P_MIN_FR_TIME(idx),
764 s5k6aa->fiv->reg_fr_time - 33);
765 if (!ret)
766 ret = s5k6aa_new_config_sync(client, 250, idx);
767 if (!ret)
768 ret = s5k6aa_preview_config_status(client);
769 if (!ret)
770 s5k6aa->apply_cfg = 0;
771
772 v4l2_dbg(1, debug, client, "Frame interval: %d +/- 3.3ms. (%d)\n",
773 s5k6aa->fiv->reg_fr_time, ret);
774 return ret;
775}
776
777/**
778 * s5k6aa_initialize_isp - basic ISP MCU initialization
779 *
780 * Configure AHB addresses for registers read/write; configure PLLs for
781 * required output pixel clock. The ISP power supply needs to be already
782 * enabled, with an optional H/W reset.
783 * Locking: called with s5k6aa.lock mutex held.
784 */
785static int s5k6aa_initialize_isp(struct v4l2_subdev *sd)
786{
787 struct i2c_client *client = v4l2_get_subdevdata(sd);
788 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
789 int ret;
790
791 s5k6aa->apply_crop = 1;
792 s5k6aa->apply_cfg = 1;
793 msleep(100);
794
795 ret = s5k6aa_set_ahb_address(client);
796 if (ret)
797 return ret;
798 ret = s5k6aa_configure_video_bus(s5k6aa, s5k6aa->bus_type,
799 s5k6aa->mipi_lanes);
800 if (ret)
801 return ret;
802 ret = s5k6aa_write_array(sd, s5k6aa_analog_config);
803 if (ret)
804 return ret;
805 msleep(20);
806
807 return s5k6aa_configure_pixel_clocks(s5k6aa);
808}
809
810static int s5k6aa_gpio_set_value(struct s5k6aa *priv, int id, u32 val)
811{
812 if (!gpio_is_valid(priv->gpio[id].gpio))
813 return 0;
814 gpio_set_value(priv->gpio[id].gpio, !!val);
815 return 1;
816}
817
818static int s5k6aa_gpio_assert(struct s5k6aa *priv, int id)
819{
820 return s5k6aa_gpio_set_value(priv, id, priv->gpio[id].level);
821}
822
823static int s5k6aa_gpio_deassert(struct s5k6aa *priv, int id)
824{
825 return s5k6aa_gpio_set_value(priv, id, !priv->gpio[id].level);
826}
827
828static int __s5k6aa_power_on(struct s5k6aa *s5k6aa)
829{
830 int ret;
831
832 ret = regulator_bulk_enable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
833 if (ret)
834 return ret;
835 if (s5k6aa_gpio_deassert(s5k6aa, STBY))
836 usleep_range(150, 200);
837
838 if (s5k6aa->s_power)
839 ret = s5k6aa->s_power(1);
840 usleep_range(4000, 4000);
841
842 if (s5k6aa_gpio_deassert(s5k6aa, RST))
843 msleep(20);
844
845 return ret;
846}
847
848static int __s5k6aa_power_off(struct s5k6aa *s5k6aa)
849{
850 int ret;
851
852 if (s5k6aa_gpio_assert(s5k6aa, RST))
853 usleep_range(100, 150);
854
855 if (s5k6aa->s_power) {
856 ret = s5k6aa->s_power(0);
857 if (ret)
858 return ret;
859 }
860 if (s5k6aa_gpio_assert(s5k6aa, STBY))
861 usleep_range(50, 100);
862 s5k6aa->streaming = 0;
863
864 return regulator_bulk_disable(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
865}
866
867/*
868 * V4L2 subdev core and video operations
869 */
870static int s5k6aa_set_power(struct v4l2_subdev *sd, int on)
871{
872 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
873 int ret = 0;
874
875 mutex_lock(&s5k6aa->lock);
876
877 if (!on == s5k6aa->power) {
878 if (on) {
879 ret = __s5k6aa_power_on(s5k6aa);
880 if (!ret)
881 ret = s5k6aa_initialize_isp(sd);
882 } else {
883 ret = __s5k6aa_power_off(s5k6aa);
884 }
885
886 if (!ret)
887 s5k6aa->power += on ? 1 : -1;
888 }
889
890 mutex_unlock(&s5k6aa->lock);
891
892 if (!on || ret || s5k6aa->power != 1)
893 return ret;
894
895 return v4l2_ctrl_handler_setup(sd->ctrl_handler);
896}
897
898static int __s5k6aa_stream(struct s5k6aa *s5k6aa, int enable)
899{
900 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
901 int ret = 0;
902
903 ret = s5k6aa_write(client, REG_G_ENABLE_PREV, enable);
904 if (!ret)
905 ret = s5k6aa_write(client, REG_G_ENABLE_PREV_CHG, 1);
906 if (!ret)
907 s5k6aa->streaming = enable;
908
909 return ret;
910}
911
912static int s5k6aa_s_stream(struct v4l2_subdev *sd, int on)
913{
914 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
915 int ret = 0;
916
917 mutex_lock(&s5k6aa->lock);
918
919 if (s5k6aa->streaming == !on) {
920 if (!ret && s5k6aa->apply_cfg)
921 ret = s5k6aa_set_prev_config(s5k6aa, s5k6aa->preset);
922 if (s5k6aa->apply_crop)
923 ret = s5k6aa_set_input_params(s5k6aa);
924 if (!ret)
925 ret = __s5k6aa_stream(s5k6aa, !!on);
926 }
927 mutex_unlock(&s5k6aa->lock);
928
929 return ret;
930}
931
932static int s5k6aa_g_frame_interval(struct v4l2_subdev *sd,
933 struct v4l2_subdev_frame_interval *fi)
934{
935 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
936
937 mutex_lock(&s5k6aa->lock);
938 fi->interval = s5k6aa->fiv->interval;
939 mutex_unlock(&s5k6aa->lock);
940
941 return 0;
942}
943
944static int __s5k6aa_set_frame_interval(struct s5k6aa *s5k6aa,
945 struct v4l2_subdev_frame_interval *fi)
946{
947 struct v4l2_mbus_framefmt *mbus_fmt = &s5k6aa->preset->mbus_fmt;
948 const struct s5k6aa_interval *fiv = &s5k6aa_intervals[0];
949 unsigned int err, min_err = UINT_MAX;
950 unsigned int i, fr_time;
951
952 if (fi->interval.denominator == 0)
953 return -EINVAL;
954
955 fr_time = fi->interval.numerator * 10000 / fi->interval.denominator;
956
957 for (i = 0; i < ARRAY_SIZE(s5k6aa_intervals); i++) {
958 const struct s5k6aa_interval *iv = &s5k6aa_intervals[i];
959
960 if (mbus_fmt->width > iv->size.width ||
961 mbus_fmt->height > iv->size.height)
962 continue;
963
964 err = abs(iv->reg_fr_time - fr_time);
965 if (err < min_err) {
966 fiv = iv;
967 min_err = err;
968 }
969 }
970 s5k6aa->fiv = fiv;
971
972 v4l2_dbg(1, debug, &s5k6aa->sd, "Changed frame interval to %d us\n",
973 fiv->reg_fr_time * 100);
974 return 0;
975}
976
977static int s5k6aa_s_frame_interval(struct v4l2_subdev *sd,
978 struct v4l2_subdev_frame_interval *fi)
979{
980 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
981 int ret;
982
983 v4l2_dbg(1, debug, sd, "Setting %d/%d frame interval\n",
984 fi->interval.numerator, fi->interval.denominator);
985
986 mutex_lock(&s5k6aa->lock);
987 ret = __s5k6aa_set_frame_interval(s5k6aa, fi);
988 s5k6aa->apply_cfg = 1;
989
990 mutex_unlock(&s5k6aa->lock);
991 return ret;
992}
993
994/*
995 * V4L2 subdev pad level and video operations
996 */
997static int s5k6aa_enum_frame_interval(struct v4l2_subdev *sd,
998 struct v4l2_subdev_fh *fh,
999 struct v4l2_subdev_frame_interval_enum *fie)
1000{
1001 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1002 const struct s5k6aa_interval *fi;
1003 int ret = 0;
1004
1005 if (fie->index > ARRAY_SIZE(s5k6aa_intervals))
1006 return -EINVAL;
1007
1008 v4l_bound_align_image(&fie->width, S5K6AA_WIN_WIDTH_MIN,
1009 S5K6AA_WIN_WIDTH_MAX, 1,
1010 &fie->height, S5K6AA_WIN_HEIGHT_MIN,
1011 S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1012
1013 mutex_lock(&s5k6aa->lock);
1014 fi = &s5k6aa_intervals[fie->index];
1015 if (fie->width > fi->size.width || fie->height > fi->size.height)
1016 ret = -EINVAL;
1017 else
1018 fie->interval = fi->interval;
1019 mutex_unlock(&s5k6aa->lock);
1020
1021 return ret;
1022}
1023
1024static int s5k6aa_enum_mbus_code(struct v4l2_subdev *sd,
1025 struct v4l2_subdev_fh *fh,
1026 struct v4l2_subdev_mbus_code_enum *code)
1027{
1028 if (code->index >= ARRAY_SIZE(s5k6aa_formats))
1029 return -EINVAL;
1030
1031 code->code = s5k6aa_formats[code->index].code;
1032 return 0;
1033}
1034
1035static int s5k6aa_enum_frame_size(struct v4l2_subdev *sd,
1036 struct v4l2_subdev_fh *fh,
1037 struct v4l2_subdev_frame_size_enum *fse)
1038{
1039 int i = ARRAY_SIZE(s5k6aa_formats);
1040
1041 if (fse->index > 0)
1042 return -EINVAL;
1043
1044 while (--i)
1045 if (fse->code == s5k6aa_formats[i].code)
1046 break;
1047
1048 fse->code = s5k6aa_formats[i].code;
1049 fse->min_width = S5K6AA_WIN_WIDTH_MIN;
1050 fse->max_width = S5K6AA_WIN_WIDTH_MAX;
1051 fse->max_height = S5K6AA_WIN_HEIGHT_MIN;
1052 fse->min_height = S5K6AA_WIN_HEIGHT_MAX;
1053
1054 return 0;
1055}
1056
1057static struct v4l2_rect *
1058__s5k6aa_get_crop_rect(struct s5k6aa *s5k6aa, struct v4l2_subdev_fh *fh,
1059 enum v4l2_subdev_format_whence which)
1060{
1061 if (which == V4L2_SUBDEV_FORMAT_ACTIVE)
1062 return &s5k6aa->ccd_rect;
1063 if (which == V4L2_SUBDEV_FORMAT_TRY)
1064 return v4l2_subdev_get_try_crop(fh, 0);
1065
1066 return NULL;
1067}
1068
1069static void s5k6aa_try_format(struct s5k6aa *s5k6aa,
1070 struct v4l2_mbus_framefmt *mf)
1071{
1072 unsigned int index;
1073
1074 v4l_bound_align_image(&mf->width, S5K6AA_WIN_WIDTH_MIN,
1075 S5K6AA_WIN_WIDTH_MAX, 1,
1076 &mf->height, S5K6AA_WIN_HEIGHT_MIN,
1077 S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1078
1079 if (mf->colorspace != V4L2_COLORSPACE_JPEG &&
1080 mf->colorspace != V4L2_COLORSPACE_REC709)
1081 mf->colorspace = V4L2_COLORSPACE_JPEG;
1082
1083 index = s5k6aa_get_pixfmt_index(s5k6aa, mf);
1084
1085 mf->colorspace = s5k6aa_formats[index].colorspace;
1086 mf->code = s5k6aa_formats[index].code;
1087 mf->field = V4L2_FIELD_NONE;
1088}
1089
1090static int s5k6aa_get_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1091 struct v4l2_subdev_format *fmt)
1092{
1093 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1094 struct v4l2_mbus_framefmt *mf;
1095
1096 memset(fmt->reserved, 0, sizeof(fmt->reserved));
1097
1098 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1099 mf = v4l2_subdev_get_try_format(fh, 0);
1100 fmt->format = *mf;
1101 return 0;
1102 }
1103
1104 mutex_lock(&s5k6aa->lock);
1105 fmt->format = s5k6aa->preset->mbus_fmt;
1106 mutex_unlock(&s5k6aa->lock);
1107
1108 return 0;
1109}
1110
1111static int s5k6aa_set_fmt(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1112 struct v4l2_subdev_format *fmt)
1113{
1114 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1115 struct s5k6aa_preset *preset = s5k6aa->preset;
1116 struct v4l2_mbus_framefmt *mf;
1117 struct v4l2_rect *crop;
1118 int ret = 0;
1119
1120 mutex_lock(&s5k6aa->lock);
1121 s5k6aa_try_format(s5k6aa, &fmt->format);
1122
1123 if (fmt->which == V4L2_SUBDEV_FORMAT_TRY) {
1124 mf = v4l2_subdev_get_try_format(fh, fmt->pad);
1125 crop = v4l2_subdev_get_try_crop(fh, 0);
1126 } else {
1127 if (s5k6aa->streaming) {
1128 ret = -EBUSY;
1129 } else {
1130 mf = &preset->mbus_fmt;
1131 crop = &s5k6aa->ccd_rect;
1132 s5k6aa->apply_cfg = 1;
1133 }
1134 }
1135
1136 if (ret == 0) {
1137 struct v4l2_subdev_frame_interval fiv = {
1138 .interval = {0, 1}
1139 };
1140
1141 *mf = fmt->format;
1142 /*
1143 * Make sure the crop window is valid, i.e. its size is
1144 * greater than the output window, as the ISP supports
1145 * only down-scaling.
1146 */
1147 crop->width = clamp_t(unsigned int, crop->width, mf->width,
1148 S5K6AA_WIN_WIDTH_MAX);
1149 crop->height = clamp_t(unsigned int, crop->height, mf->height,
1150 S5K6AA_WIN_HEIGHT_MAX);
1151 crop->left = clamp_t(unsigned int, crop->left, 0,
1152 S5K6AA_WIN_WIDTH_MAX - crop->width);
1153 crop->top = clamp_t(unsigned int, crop->top, 0,
1154 S5K6AA_WIN_HEIGHT_MAX - crop->height);
1155
1156 /* Reset to minimum possible frame interval */
1157 ret = __s5k6aa_set_frame_interval(s5k6aa, &fiv);
1158 }
1159 mutex_unlock(&s5k6aa->lock);
1160
1161 return ret;
1162}
1163
1164static int s5k6aa_get_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1165 struct v4l2_subdev_crop *crop)
1166{
1167 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1168 struct v4l2_rect *rect;
1169
1170 memset(crop->reserved, 0, sizeof(crop->reserved));
1171 mutex_lock(&s5k6aa->lock);
1172
1173 rect = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
1174 if (rect)
1175 crop->rect = *rect;
1176
1177 mutex_unlock(&s5k6aa->lock);
1178
1179 v4l2_dbg(1, debug, sd, "Current crop rectangle: (%d,%d)/%dx%d\n",
1180 rect->left, rect->top, rect->width, rect->height);
1181
1182 return 0;
1183}
1184
1185static int s5k6aa_set_crop(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
1186 struct v4l2_subdev_crop *crop)
1187{
1188 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1189 struct v4l2_mbus_framefmt *mf;
1190 unsigned int max_x, max_y;
1191 struct v4l2_rect *crop_r;
1192
1193 mutex_lock(&s5k6aa->lock);
1194 crop_r = __s5k6aa_get_crop_rect(s5k6aa, fh, crop->which);
1195
1196 if (crop->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
1197 mf = &s5k6aa->preset->mbus_fmt;
1198 s5k6aa->apply_crop = 1;
1199 } else {
1200 mf = v4l2_subdev_get_try_format(fh, 0);
1201 }
1202 v4l_bound_align_image(&crop->rect.width, mf->width,
1203 S5K6AA_WIN_WIDTH_MAX, 1,
1204 &crop->rect.height, mf->height,
1205 S5K6AA_WIN_HEIGHT_MAX, 1, 0);
1206
1207 max_x = (S5K6AA_WIN_WIDTH_MAX - crop->rect.width) & ~1;
1208 max_y = (S5K6AA_WIN_HEIGHT_MAX - crop->rect.height) & ~1;
1209
1210 crop->rect.left = clamp_t(unsigned int, crop->rect.left, 0, max_x);
1211 crop->rect.top = clamp_t(unsigned int, crop->rect.top, 0, max_y);
1212
1213 *crop_r = crop->rect;
1214
1215 mutex_unlock(&s5k6aa->lock);
1216
1217 v4l2_dbg(1, debug, sd, "Set crop rectangle: (%d,%d)/%dx%d\n",
1218 crop_r->left, crop_r->top, crop_r->width, crop_r->height);
1219
1220 return 0;
1221}
1222
1223static const struct v4l2_subdev_pad_ops s5k6aa_pad_ops = {
1224 .enum_mbus_code = s5k6aa_enum_mbus_code,
1225 .enum_frame_size = s5k6aa_enum_frame_size,
1226 .enum_frame_interval = s5k6aa_enum_frame_interval,
1227 .get_fmt = s5k6aa_get_fmt,
1228 .set_fmt = s5k6aa_set_fmt,
1229 .get_crop = s5k6aa_get_crop,
1230 .set_crop = s5k6aa_set_crop,
1231};
1232
1233static const struct v4l2_subdev_video_ops s5k6aa_video_ops = {
1234 .g_frame_interval = s5k6aa_g_frame_interval,
1235 .s_frame_interval = s5k6aa_s_frame_interval,
1236 .s_stream = s5k6aa_s_stream,
1237};
1238
1239/*
1240 * V4L2 subdev controls
1241 */
1242
1243static int s5k6aa_s_ctrl(struct v4l2_ctrl *ctrl)
1244{
1245 struct v4l2_subdev *sd = ctrl_to_sd(ctrl);
1246 struct i2c_client *client = v4l2_get_subdevdata(sd);
1247 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1248 int idx, err = 0;
1249
1250 v4l2_dbg(1, debug, sd, "ctrl: 0x%x, value: %d\n", ctrl->id, ctrl->val);
1251
1252 mutex_lock(&s5k6aa->lock);
1253 /*
1254 * If the device is not powered up by the host driver do
1255 * not apply any controls to H/W at this time. Instead
1256 * the controls will be restored right after power-up.
1257 */
1258 if (s5k6aa->power == 0)
1259 goto unlock;
1260 idx = s5k6aa->preset->index;
1261
1262 switch (ctrl->id) {
1263 case V4L2_CID_AUTO_WHITE_BALANCE:
1264 err = s5k6aa_set_awb(s5k6aa, ctrl->val);
1265 break;
1266
1267 case V4L2_CID_BRIGHTNESS:
1268 err = s5k6aa_write(client, REG_USER_BRIGHTNESS, ctrl->val);
1269 break;
1270
1271 case V4L2_CID_COLORFX:
1272 err = s5k6aa_set_colorfx(s5k6aa, ctrl->val);
1273 break;
1274
1275 case V4L2_CID_CONTRAST:
1276 err = s5k6aa_write(client, REG_USER_CONTRAST, ctrl->val);
1277 break;
1278
1279 case V4L2_CID_EXPOSURE_AUTO:
1280 err = s5k6aa_set_auto_exposure(s5k6aa, ctrl->val);
1281 break;
1282
1283 case V4L2_CID_HFLIP:
1284 err = s5k6aa_set_mirror(s5k6aa, ctrl->val);
1285 if (err)
1286 break;
1287 err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
1288 break;
1289
1290 case V4L2_CID_POWER_LINE_FREQUENCY:
1291 err = s5k6aa_set_anti_flicker(s5k6aa, ctrl->val);
1292 break;
1293
1294 case V4L2_CID_SATURATION:
1295 err = s5k6aa_write(client, REG_USER_SATURATION, ctrl->val);
1296 break;
1297
1298 case V4L2_CID_SHARPNESS:
1299 err = s5k6aa_write(client, REG_USER_SHARPBLUR, ctrl->val);
1300 break;
1301
1302 case V4L2_CID_WHITE_BALANCE_TEMPERATURE:
1303 err = s5k6aa_write(client, REG_P_COLORTEMP(idx), ctrl->val);
1304 if (err)
1305 break;
1306 err = s5k6aa_write(client, REG_G_PREV_CFG_CHG, 1);
1307 break;
1308 }
1309unlock:
1310 mutex_unlock(&s5k6aa->lock);
1311 return err;
1312}
1313
1314static const struct v4l2_ctrl_ops s5k6aa_ctrl_ops = {
1315 .s_ctrl = s5k6aa_s_ctrl,
1316};
1317
1318static int s5k6aa_log_status(struct v4l2_subdev *sd)
1319{
1320 v4l2_ctrl_handler_log_status(sd->ctrl_handler, sd->name);
1321 return 0;
1322}
1323
1324#define V4L2_CID_RED_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1001)
1325#define V4L2_CID_GREEN_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1002)
1326#define V4L2_CID_BLUE_GAIN (V4L2_CTRL_CLASS_CAMERA | 0x1003)
1327
1328static const struct v4l2_ctrl_config s5k6aa_ctrls[] = {
1329 {
1330 .ops = &s5k6aa_ctrl_ops,
1331 .id = V4L2_CID_RED_GAIN,
1332 .type = V4L2_CTRL_TYPE_INTEGER,
1333 .name = "Gain, Red",
1334 .min = 0,
1335 .max = 256,
1336 .def = 127,
1337 .step = 1,
1338 }, {
1339 .ops = &s5k6aa_ctrl_ops,
1340 .id = V4L2_CID_GREEN_GAIN,
1341 .type = V4L2_CTRL_TYPE_INTEGER,
1342 .name = "Gain, Green",
1343 .min = 0,
1344 .max = 256,
1345 .def = 127,
1346 .step = 1,
1347 }, {
1348 .ops = &s5k6aa_ctrl_ops,
1349 .id = V4L2_CID_BLUE_GAIN,
1350 .type = V4L2_CTRL_TYPE_INTEGER,
1351 .name = "Gain, Blue",
1352 .min = 0,
1353 .max = 256,
1354 .def = 127,
1355 .step = 1,
1356 },
1357};
1358
1359static int s5k6aa_initialize_ctrls(struct s5k6aa *s5k6aa)
1360{
1361 const struct v4l2_ctrl_ops *ops = &s5k6aa_ctrl_ops;
1362 struct s5k6aa_ctrls *ctrls = &s5k6aa->ctrls;
1363 struct v4l2_ctrl_handler *hdl = &ctrls->handler;
1364
1365 int ret = v4l2_ctrl_handler_init(hdl, 16);
1366 if (ret)
1367 return ret;
1368 /* Auto white balance cluster */
1369 ctrls->awb = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_AUTO_WHITE_BALANCE,
1370 0, 1, 1, 1);
1371 ctrls->gain_red = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[0], NULL);
1372 ctrls->gain_green = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[1], NULL);
1373 ctrls->gain_blue = v4l2_ctrl_new_custom(hdl, &s5k6aa_ctrls[2], NULL);
1374 v4l2_ctrl_auto_cluster(4, &ctrls->awb, 0, false);
1375
1376 ctrls->hflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_HFLIP, 0, 1, 1, 0);
1377 ctrls->vflip = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_VFLIP, 0, 1, 1, 0);
1378 v4l2_ctrl_cluster(2, &ctrls->hflip);
1379
1380 ctrls->auto_exp = v4l2_ctrl_new_std_menu(hdl, ops,
1381 V4L2_CID_EXPOSURE_AUTO,
1382 V4L2_EXPOSURE_MANUAL, 0, V4L2_EXPOSURE_AUTO);
1383 /* Exposure time: x 1 us */
1384 ctrls->exposure = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_EXPOSURE,
1385 0, 6000000U, 1, 100000U);
1386 /* Total gain: 256 <=> 1x */
1387 ctrls->gain = v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAIN,
1388 0, 256, 1, 256);
1389 v4l2_ctrl_auto_cluster(3, &ctrls->auto_exp, 0, false);
1390
1391 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_POWER_LINE_FREQUENCY,
1392 V4L2_CID_POWER_LINE_FREQUENCY_AUTO, 0,
1393 V4L2_CID_POWER_LINE_FREQUENCY_AUTO);
1394
1395 v4l2_ctrl_new_std_menu(hdl, ops, V4L2_CID_COLORFX,
1396 V4L2_COLORFX_SKY_BLUE, ~0x6f, V4L2_COLORFX_NONE);
1397
1398 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_WHITE_BALANCE_TEMPERATURE,
1399 0, 256, 1, 0);
1400
1401 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SATURATION, -127, 127, 1, 0);
1402 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -127, 127, 1, 0);
1403 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -127, 127, 1, 0);
1404 v4l2_ctrl_new_std(hdl, ops, V4L2_CID_SHARPNESS, -127, 127, 1, 0);
1405
1406 if (hdl->error) {
1407 ret = hdl->error;
1408 v4l2_ctrl_handler_free(hdl);
1409 return ret;
1410 }
1411
1412 s5k6aa->sd.ctrl_handler = hdl;
1413 return 0;
1414}
1415
1416/*
1417 * V4L2 subdev internal operations
1418 */
1419static int s5k6aa_open(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
1420{
1421 struct v4l2_mbus_framefmt *format = v4l2_subdev_get_try_format(fh, 0);
1422 struct v4l2_rect *crop = v4l2_subdev_get_try_crop(fh, 0);
1423
1424 format->colorspace = s5k6aa_formats[0].colorspace;
1425 format->code = s5k6aa_formats[0].code;
1426 format->width = S5K6AA_OUT_WIDTH_DEF;
1427 format->height = S5K6AA_OUT_HEIGHT_DEF;
1428 format->field = V4L2_FIELD_NONE;
1429
1430 crop->width = S5K6AA_WIN_WIDTH_MAX;
1431 crop->height = S5K6AA_WIN_HEIGHT_MAX;
1432 crop->left = 0;
1433 crop->top = 0;
1434
1435 return 0;
1436}
1437
1438int s5k6aa_check_fw_revision(struct s5k6aa *s5k6aa)
1439{
1440 struct i2c_client *client = v4l2_get_subdevdata(&s5k6aa->sd);
1441 u16 api_ver = 0, fw_rev = 0;
1442
1443 int ret = s5k6aa_set_ahb_address(client);
1444
1445 if (!ret)
1446 ret = s5k6aa_read(client, REG_FW_APIVER, &api_ver);
1447 if (!ret)
1448 ret = s5k6aa_read(client, REG_FW_REVISION, &fw_rev);
1449 if (ret) {
1450 v4l2_err(&s5k6aa->sd, "FW revision check failed!\n");
1451 return ret;
1452 }
1453
1454 v4l2_info(&s5k6aa->sd, "FW API ver.: 0x%X, FW rev.: 0x%X\n",
1455 api_ver, fw_rev);
1456
1457 return api_ver == S5K6AAFX_FW_APIVER ? 0 : -ENODEV;
1458}
1459
1460static int s5k6aa_registered(struct v4l2_subdev *sd)
1461{
1462 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1463 int ret;
1464
1465 mutex_lock(&s5k6aa->lock);
1466 ret = __s5k6aa_power_on(s5k6aa);
1467 if (!ret) {
1468 msleep(100);
1469 ret = s5k6aa_check_fw_revision(s5k6aa);
1470 __s5k6aa_power_off(s5k6aa);
1471 }
1472 mutex_unlock(&s5k6aa->lock);
1473
1474 return ret;
1475}
1476
1477static const struct v4l2_subdev_internal_ops s5k6aa_subdev_internal_ops = {
1478 .registered = s5k6aa_registered,
1479 .open = s5k6aa_open,
1480};
1481
1482static const struct v4l2_subdev_core_ops s5k6aa_core_ops = {
1483 .s_power = s5k6aa_set_power,
1484 .log_status = s5k6aa_log_status,
1485};
1486
1487static const struct v4l2_subdev_ops s5k6aa_subdev_ops = {
1488 .core = &s5k6aa_core_ops,
1489 .pad = &s5k6aa_pad_ops,
1490 .video = &s5k6aa_video_ops,
1491};
1492
1493/*
1494 * GPIO setup
1495 */
1496static int s5k6aa_configure_gpio(int nr, int val, const char *name)
1497{
1498 unsigned long flags = val ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW;
1499 int ret;
1500
1501 if (!gpio_is_valid(nr))
1502 return 0;
1503 ret = gpio_request_one(nr, flags, name);
1504 if (!ret)
1505 gpio_export(nr, 0);
1506 return ret;
1507}
1508
1509static void s5k6aa_free_gpios(struct s5k6aa *s5k6aa)
1510{
1511 int i;
1512
1513 for (i = 0; i < ARRAY_SIZE(s5k6aa->gpio); i++) {
1514 if (!gpio_is_valid(s5k6aa->gpio[i].gpio))
1515 continue;
1516 gpio_free(s5k6aa->gpio[i].gpio);
1517 s5k6aa->gpio[i].gpio = -EINVAL;
1518 }
1519}
1520
1521static int s5k6aa_configure_gpios(struct s5k6aa *s5k6aa,
1522 const struct s5k6aa_platform_data *pdata)
1523{
1524 const struct s5k6aa_gpio *gpio = &pdata->gpio_stby;
1525 int ret;
1526
1527 s5k6aa->gpio[STBY].gpio = -EINVAL;
1528 s5k6aa->gpio[RST].gpio = -EINVAL;
1529
1530 ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_STBY");
1531 if (ret) {
1532 s5k6aa_free_gpios(s5k6aa);
1533 return ret;
1534 }
1535 s5k6aa->gpio[STBY] = *gpio;
1536 if (gpio_is_valid(gpio->gpio))
1537 gpio_set_value(gpio->gpio, 0);
1538
1539 gpio = &pdata->gpio_reset;
1540 ret = s5k6aa_configure_gpio(gpio->gpio, gpio->level, "S5K6AA_RST");
1541 if (ret) {
1542 s5k6aa_free_gpios(s5k6aa);
1543 return ret;
1544 }
1545 s5k6aa->gpio[RST] = *gpio;
1546 if (gpio_is_valid(gpio->gpio))
1547 gpio_set_value(gpio->gpio, 0);
1548
1549 return 0;
1550}
1551
1552static int s5k6aa_probe(struct i2c_client *client,
1553 const struct i2c_device_id *id)
1554{
1555 const struct s5k6aa_platform_data *pdata = client->dev.platform_data;
1556 struct v4l2_subdev *sd;
1557 struct s5k6aa *s5k6aa;
1558 int i, ret;
1559
1560 if (pdata == NULL) {
1561 dev_err(&client->dev, "Platform data not specified\n");
1562 return -EINVAL;
1563 }
1564
1565 if (pdata->mclk_frequency == 0) {
1566 dev_err(&client->dev, "MCLK frequency not specified\n");
1567 return -EINVAL;
1568 }
1569
1570 s5k6aa = kzalloc(sizeof(*s5k6aa), GFP_KERNEL);
1571 if (!s5k6aa)
1572 return -ENOMEM;
1573
1574 mutex_init(&s5k6aa->lock);
1575
1576 s5k6aa->mclk_frequency = pdata->mclk_frequency;
1577 s5k6aa->bus_type = pdata->bus_type;
1578 s5k6aa->mipi_lanes = pdata->nlanes;
1579 s5k6aa->s_power = pdata->set_power;
1580 s5k6aa->inv_hflip = pdata->horiz_flip;
1581 s5k6aa->inv_vflip = pdata->vert_flip;
1582
1583 sd = &s5k6aa->sd;
1584 strlcpy(sd->name, DRIVER_NAME, sizeof(sd->name));
1585 v4l2_i2c_subdev_init(sd, client, &s5k6aa_subdev_ops);
1586
1587 sd->internal_ops = &s5k6aa_subdev_internal_ops;
1588 sd->flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
1589
1590 s5k6aa->pad.flags = MEDIA_PAD_FL_SOURCE;
1591 sd->entity.type = MEDIA_ENT_T_V4L2_SUBDEV_SENSOR;
1592 ret = media_entity_init(&sd->entity, 1, &s5k6aa->pad, 0);
1593 if (ret)
1594 goto out_err1;
1595
1596 ret = s5k6aa_configure_gpios(s5k6aa, pdata);
1597 if (ret)
1598 goto out_err2;
1599
1600 for (i = 0; i < S5K6AA_NUM_SUPPLIES; i++)
1601 s5k6aa->supplies[i].supply = s5k6aa_supply_names[i];
1602
1603 ret = regulator_bulk_get(&client->dev, S5K6AA_NUM_SUPPLIES,
1604 s5k6aa->supplies);
1605 if (ret) {
1606 dev_err(&client->dev, "Failed to get regulators\n");
1607 goto out_err3;
1608 }
1609
1610 ret = s5k6aa_initialize_ctrls(s5k6aa);
1611 if (ret)
1612 goto out_err4;
1613
1614 s5k6aa_presets_data_init(s5k6aa);
1615
1616 s5k6aa->ccd_rect.width = S5K6AA_WIN_WIDTH_MAX;
1617 s5k6aa->ccd_rect.height = S5K6AA_WIN_HEIGHT_MAX;
1618 s5k6aa->ccd_rect.left = 0;
1619 s5k6aa->ccd_rect.top = 0;
1620
1621 return 0;
1622
1623out_err4:
1624 regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
1625out_err3:
1626 s5k6aa_free_gpios(s5k6aa);
1627out_err2:
1628 media_entity_cleanup(&s5k6aa->sd.entity);
1629out_err1:
1630 kfree(s5k6aa);
1631 return ret;
1632}
1633
1634static int s5k6aa_remove(struct i2c_client *client)
1635{
1636 struct v4l2_subdev *sd = i2c_get_clientdata(client);
1637 struct s5k6aa *s5k6aa = to_s5k6aa(sd);
1638
1639 v4l2_device_unregister_subdev(sd);
1640 v4l2_ctrl_handler_free(sd->ctrl_handler);
1641 media_entity_cleanup(&sd->entity);
1642 regulator_bulk_free(S5K6AA_NUM_SUPPLIES, s5k6aa->supplies);
1643 s5k6aa_free_gpios(s5k6aa);
1644 kfree(s5k6aa);
1645
1646 return 0;
1647}
1648
1649static const struct i2c_device_id s5k6aa_id[] = {
1650 { DRIVER_NAME, 0 },
1651 { },
1652};
1653MODULE_DEVICE_TABLE(i2c, s5k6aa_id);
1654
1655
1656static struct i2c_driver s5k6aa_i2c_driver = {
1657 .driver = {
1658 .name = DRIVER_NAME
1659 },
1660 .probe = s5k6aa_probe,
1661 .remove = s5k6aa_remove,
1662 .id_table = s5k6aa_id,
1663};
1664
1665static int __init s5k6aa_init(void)
1666{
1667 return i2c_add_driver(&s5k6aa_i2c_driver);
1668}
1669
1670static void __exit s5k6aa_exit(void)
1671{
1672 i2c_del_driver(&s5k6aa_i2c_driver);
1673}
1674
1675module_init(s5k6aa_init);
1676module_exit(s5k6aa_exit);
1677
1678MODULE_DESCRIPTION("Samsung S5K6AA(FX) SXGA camera driver");
1679MODULE_AUTHOR("Sylwester Nawrocki <s.nawrocki@samsung.com>");
1680MODULE_LICENSE("GPL");
diff --git a/drivers/media/video/s5p-fimc/fimc-capture.c b/drivers/media/video/s5p-fimc/fimc-capture.c
index 931f469604b..c8d91b0cd9b 100644
--- a/drivers/media/video/s5p-fimc/fimc-capture.c
+++ b/drivers/media/video/s5p-fimc/fimc-capture.c
@@ -246,9 +246,9 @@ static unsigned int get_plane_size(struct fimc_frame *fr, unsigned int plane)
246 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8; 246 return fr->f_width * fr->f_height * fr->fmt->depth[plane] / 8;
247} 247}
248 248
249static int queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, 249static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
250 unsigned int *num_planes, unsigned int sizes[], 250 unsigned int *num_buffers, unsigned int *num_planes,
251 void *allocators[]) 251 unsigned int sizes[], void *allocators[])
252{ 252{
253 struct fimc_ctx *ctx = vq->drv_priv; 253 struct fimc_ctx *ctx = vq->drv_priv;
254 struct fimc_fmt *fmt = ctx->d_frame.fmt; 254 struct fimc_fmt *fmt = ctx->d_frame.fmt;
diff --git a/drivers/media/video/s5p-fimc/fimc-core.c b/drivers/media/video/s5p-fimc/fimc-core.c
index 6c1c9cb5537..19ca6db38b2 100644
--- a/drivers/media/video/s5p-fimc/fimc-core.c
+++ b/drivers/media/video/s5p-fimc/fimc-core.c
@@ -670,9 +670,9 @@ static void fimc_job_abort(void *priv)
670 fimc_m2m_shutdown(priv); 670 fimc_m2m_shutdown(priv);
671} 671}
672 672
673static int fimc_queue_setup(struct vb2_queue *vq, unsigned int *num_buffers, 673static int fimc_queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
674 unsigned int *num_planes, unsigned int sizes[], 674 unsigned int *num_buffers, unsigned int *num_planes,
675 void *allocators[]) 675 unsigned int sizes[], void *allocators[])
676{ 676{
677 struct fimc_ctx *ctx = vb2_get_drv_priv(vq); 677 struct fimc_ctx *ctx = vb2_get_drv_priv(vq);
678 struct fimc_frame *f; 678 struct fimc_frame *f;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
index 5f4da80051b..f2481a85e0a 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_ctrl.c
@@ -38,7 +38,7 @@ int s5p_mfc_alloc_and_load_firmware(struct s5p_mfc_dev *dev)
38 * into kernel. */ 38 * into kernel. */
39 mfc_debug_enter(); 39 mfc_debug_enter();
40 err = request_firmware((const struct firmware **)&fw_blob, 40 err = request_firmware((const struct firmware **)&fw_blob,
41 "s5pc110-mfc.fw", dev->v4l2_dev.dev); 41 "s5p-mfc.fw", dev->v4l2_dev.dev);
42 if (err != 0) { 42 if (err != 0) {
43 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 43 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
44 return -EINVAL; 44 return -EINVAL;
@@ -116,7 +116,7 @@ int s5p_mfc_reload_firmware(struct s5p_mfc_dev *dev)
116 * into kernel. */ 116 * into kernel. */
117 mfc_debug_enter(); 117 mfc_debug_enter();
118 err = request_firmware((const struct firmware **)&fw_blob, 118 err = request_firmware((const struct firmware **)&fw_blob,
119 "s5pc110-mfc.fw", dev->v4l2_dev.dev); 119 "s5p-mfc.fw", dev->v4l2_dev.dev);
120 if (err != 0) { 120 if (err != 0) {
121 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); 121 mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n");
122 return -EINVAL; 122 return -EINVAL;
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
index bfbe0843205..725634d9736 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_dec.c
@@ -744,9 +744,10 @@ static const struct v4l2_ioctl_ops s5p_mfc_dec_ioctl_ops = {
744 .vidioc_g_crop = vidioc_g_crop, 744 .vidioc_g_crop = vidioc_g_crop,
745}; 745};
746 746
747static int s5p_mfc_queue_setup(struct vb2_queue *vq, unsigned int *buf_count, 747static int s5p_mfc_queue_setup(struct vb2_queue *vq,
748 unsigned int *plane_count, unsigned int psize[], 748 const struct v4l2_format *fmt, unsigned int *buf_count,
749 void *allocators[]) 749 unsigned int *plane_count, unsigned int psize[],
750 void *allocators[])
750{ 751{
751 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); 752 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
752 753
diff --git a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
index 4c90e53bd96..ecef127dbc6 100644
--- a/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
+++ b/drivers/media/video/s5p-mfc/s5p_mfc_enc.c
@@ -1513,8 +1513,9 @@ static int check_vb_with_fmt(struct s5p_mfc_fmt *fmt, struct vb2_buffer *vb)
1513} 1513}
1514 1514
1515static int s5p_mfc_queue_setup(struct vb2_queue *vq, 1515static int s5p_mfc_queue_setup(struct vb2_queue *vq,
1516 unsigned int *buf_count, unsigned int *plane_count, 1516 const struct v4l2_format *fmt,
1517 unsigned int psize[], void *allocators[]) 1517 unsigned int *buf_count, unsigned int *plane_count,
1518 unsigned int psize[], void *allocators[])
1518{ 1519{
1519 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv); 1520 struct s5p_mfc_ctx *ctx = fh_to_ctx(vq->drv_priv);
1520 1521
diff --git a/drivers/media/video/s5p-tv/mixer_video.c b/drivers/media/video/s5p-tv/mixer_video.c
index 4917e2c2b32..e16d3a4bc1d 100644
--- a/drivers/media/video/s5p-tv/mixer_video.c
+++ b/drivers/media/video/s5p-tv/mixer_video.c
@@ -727,8 +727,8 @@ static const struct v4l2_file_operations mxr_fops = {
727 .unlocked_ioctl = video_ioctl2, 727 .unlocked_ioctl = video_ioctl2,
728}; 728};
729 729
730static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 730static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *pfmt,
731 unsigned int *nplanes, unsigned int sizes[], 731 unsigned int *nbuffers, unsigned int *nplanes, unsigned int sizes[],
732 void *alloc_ctxs[]) 732 void *alloc_ctxs[])
733{ 733{
734 struct mxr_layer *layer = vb2_get_drv_priv(vq); 734 struct mxr_layer *layer = vb2_get_drv_priv(vq);
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index bc8d6bba8ee..9b550687213 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -843,10 +843,10 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
843int saa7134_ir_start(struct saa7134_dev *dev); 843int saa7134_ir_start(struct saa7134_dev *dev);
844void saa7134_ir_stop(struct saa7134_dev *dev); 844void saa7134_ir_stop(struct saa7134_dev *dev);
845#else 845#else
846#define saa7134_input_init1(dev) (0) 846#define saa7134_input_init1(dev) ((void)0)
847#define saa7134_input_fini(dev) (0) 847#define saa7134_input_fini(dev) ((void)0)
848#define saa7134_input_irq(dev) (0) 848#define saa7134_input_irq(dev) ((void)0)
849#define saa7134_probe_i2c_ir(dev) (0) 849#define saa7134_probe_i2c_ir(dev) ((void)0)
850#define saa7134_ir_start(dev) (0) 850#define saa7134_ir_start(dev) ((void)0)
851#define saa7134_ir_stop(dev) (0) 851#define saa7134_ir_stop(dev) ((void)0)
852#endif 852#endif
diff --git a/drivers/media/video/sh_mobile_ceu_camera.c b/drivers/media/video/sh_mobile_ceu_camera.c
index 8615fb81775..f390682629c 100644
--- a/drivers/media/video/sh_mobile_ceu_camera.c
+++ b/drivers/media/video/sh_mobile_ceu_camera.c
@@ -90,7 +90,6 @@
90struct sh_mobile_ceu_buffer { 90struct sh_mobile_ceu_buffer {
91 struct vb2_buffer vb; /* v4l buffer must be first */ 91 struct vb2_buffer vb; /* v4l buffer must be first */
92 struct list_head queue; 92 struct list_head queue;
93 enum v4l2_mbus_pixelcode code;
94}; 93};
95 94
96struct sh_mobile_ceu_dev { 95struct sh_mobile_ceu_dev {
@@ -100,7 +99,8 @@ struct sh_mobile_ceu_dev {
100 99
101 unsigned int irq; 100 unsigned int irq;
102 void __iomem *base; 101 void __iomem *base;
103 unsigned long video_limit; 102 size_t video_limit;
103 size_t buf_total;
104 104
105 spinlock_t lock; /* Protects video buffer lists */ 105 spinlock_t lock; /* Protects video buffer lists */
106 struct list_head capture; 106 struct list_head capture;
@@ -121,7 +121,7 @@ struct sh_mobile_ceu_dev {
121}; 121};
122 122
123struct sh_mobile_ceu_cam { 123struct sh_mobile_ceu_cam {
124 /* CEU offsets within scaled by the CEU camera output */ 124 /* CEU offsets within the camera output, before the CEU scaler */
125 unsigned int ceu_left; 125 unsigned int ceu_left;
126 unsigned int ceu_top; 126 unsigned int ceu_top;
127 /* Client output, as seen by the CEU */ 127 /* Client output, as seen by the CEU */
@@ -144,30 +144,6 @@ static struct sh_mobile_ceu_buffer *to_ceu_vb(struct vb2_buffer *vb)
144 return container_of(vb, struct sh_mobile_ceu_buffer, vb); 144 return container_of(vb, struct sh_mobile_ceu_buffer, vb);
145} 145}
146 146
147static unsigned long make_bus_param(struct sh_mobile_ceu_dev *pcdev)
148{
149 unsigned long flags;
150
151 flags = SOCAM_MASTER |
152 SOCAM_PCLK_SAMPLE_RISING |
153 SOCAM_HSYNC_ACTIVE_HIGH |
154 SOCAM_HSYNC_ACTIVE_LOW |
155 SOCAM_VSYNC_ACTIVE_HIGH |
156 SOCAM_VSYNC_ACTIVE_LOW |
157 SOCAM_DATA_ACTIVE_HIGH;
158
159 if (pcdev->pdata->flags & SH_CEU_FLAG_USE_8BIT_BUS)
160 flags |= SOCAM_DATAWIDTH_8;
161
162 if (pcdev->pdata->flags & SH_CEU_FLAG_USE_16BIT_BUS)
163 flags |= SOCAM_DATAWIDTH_16;
164
165 if (flags & SOCAM_DATAWIDTH_MASK)
166 return flags;
167
168 return 0;
169}
170
171static void ceu_write(struct sh_mobile_ceu_dev *priv, 147static void ceu_write(struct sh_mobile_ceu_dev *priv,
172 unsigned long reg_offs, u32 data) 148 unsigned long reg_offs, u32 data)
173{ 149{
@@ -216,33 +192,61 @@ static int sh_mobile_ceu_soft_reset(struct sh_mobile_ceu_dev *pcdev)
216/* 192/*
217 * Videobuf operations 193 * Videobuf operations
218 */ 194 */
195
196/*
197 * .queue_setup() is called to check, whether the driver can accept the
198 * requested number of buffers and to fill in plane sizes
199 * for the current frame format if required
200 */
219static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq, 201static int sh_mobile_ceu_videobuf_setup(struct vb2_queue *vq,
202 const struct v4l2_format *fmt,
220 unsigned int *count, unsigned int *num_planes, 203 unsigned int *count, unsigned int *num_planes,
221 unsigned int sizes[], void *alloc_ctxs[]) 204 unsigned int sizes[], void *alloc_ctxs[])
222{ 205{
223 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq); 206 struct soc_camera_device *icd = container_of(vq, struct soc_camera_device, vb2_vidq);
224 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 207 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
225 struct sh_mobile_ceu_dev *pcdev = ici->priv; 208 struct sh_mobile_ceu_dev *pcdev = ici->priv;
226 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 209 int bytes_per_line;
227 icd->current_fmt->host_fmt); 210 unsigned int height;
228 211
212 if (fmt) {
213 const struct soc_camera_format_xlate *xlate = soc_camera_xlate_by_fourcc(icd,
214 fmt->fmt.pix.pixelformat);
215 if (!xlate)
216 return -EINVAL;
217 bytes_per_line = soc_mbus_bytes_per_line(fmt->fmt.pix.width,
218 xlate->host_fmt);
219 height = fmt->fmt.pix.height;
220 } else {
221 /* Called from VIDIOC_REQBUFS or in compatibility mode */
222 bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
223 icd->current_fmt->host_fmt);
224 height = icd->user_height;
225 }
229 if (bytes_per_line < 0) 226 if (bytes_per_line < 0)
230 return bytes_per_line; 227 return bytes_per_line;
231 228
232 *num_planes = 1; 229 sizes[0] = bytes_per_line * height;
233 230
234 pcdev->sequence = 0;
235 sizes[0] = bytes_per_line * icd->user_height;
236 alloc_ctxs[0] = pcdev->alloc_ctx; 231 alloc_ctxs[0] = pcdev->alloc_ctx;
237 232
233 if (!vq->num_buffers)
234 pcdev->sequence = 0;
235
238 if (!*count) 236 if (!*count)
239 *count = 2; 237 *count = 2;
240 238
241 if (pcdev->video_limit) { 239 /* If *num_planes != 0, we have already verified *count. */
242 if (PAGE_ALIGN(sizes[0]) * *count > pcdev->video_limit) 240 if (pcdev->video_limit && !*num_planes) {
243 *count = pcdev->video_limit / PAGE_ALIGN(sizes[0]); 241 size_t size = PAGE_ALIGN(sizes[0]) * *count;
242
243 if (size + pcdev->buf_total > pcdev->video_limit)
244 *count = (pcdev->video_limit - pcdev->buf_total) /
245 PAGE_ALIGN(sizes[0]);
244 } 246 }
245 247
248 *num_planes = 1;
249
246 dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]); 250 dev_dbg(icd->parent, "count=%d, size=%u\n", *count, sizes[0]);
247 251
248 return 0; 252 return 0;
@@ -267,6 +271,7 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
267 unsigned long top1, top2; 271 unsigned long top1, top2;
268 unsigned long bottom1, bottom2; 272 unsigned long bottom1, bottom2;
269 u32 status; 273 u32 status;
274 bool planar;
270 int ret = 0; 275 int ret = 0;
271 276
272 /* 277 /*
@@ -314,17 +319,29 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
314 319
315 phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0); 320 phys_addr_top = vb2_dma_contig_plane_dma_addr(pcdev->active, 0);
316 321
317 ceu_write(pcdev, top1, phys_addr_top);
318 if (V4L2_FIELD_NONE != pcdev->field) {
319 phys_addr_bottom = phys_addr_top + icd->user_width;
320 ceu_write(pcdev, bottom1, phys_addr_bottom);
321 }
322
323 switch (icd->current_fmt->host_fmt->fourcc) { 322 switch (icd->current_fmt->host_fmt->fourcc) {
324 case V4L2_PIX_FMT_NV12: 323 case V4L2_PIX_FMT_NV12:
325 case V4L2_PIX_FMT_NV21: 324 case V4L2_PIX_FMT_NV21:
326 case V4L2_PIX_FMT_NV16: 325 case V4L2_PIX_FMT_NV16:
327 case V4L2_PIX_FMT_NV61: 326 case V4L2_PIX_FMT_NV61:
327 planar = true;
328 break;
329 default:
330 planar = false;
331 }
332
333 ceu_write(pcdev, top1, phys_addr_top);
334 if (V4L2_FIELD_NONE != pcdev->field) {
335 if (planar)
336 phys_addr_bottom = phys_addr_top + icd->user_width;
337 else
338 phys_addr_bottom = phys_addr_top +
339 soc_mbus_bytes_per_line(icd->user_width,
340 icd->current_fmt->host_fmt);
341 ceu_write(pcdev, bottom1, phys_addr_bottom);
342 }
343
344 if (planar) {
328 phys_addr_top += icd->user_width * 345 phys_addr_top += icd->user_width *
329 icd->user_height; 346 icd->user_height;
330 ceu_write(pcdev, top2, phys_addr_top); 347 ceu_write(pcdev, top2, phys_addr_top);
@@ -341,23 +358,40 @@ static int sh_mobile_ceu_capture(struct sh_mobile_ceu_dev *pcdev)
341 358
342static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb) 359static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
343{ 360{
361 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
362
363 /* Added list head initialization on alloc */
364 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
365
366 return 0;
367}
368
369static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
370{
344 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq); 371 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
345 struct sh_mobile_ceu_buffer *buf; 372 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
373 struct sh_mobile_ceu_dev *pcdev = ici->priv;
374 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
375 unsigned long size;
346 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 376 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width,
347 icd->current_fmt->host_fmt); 377 icd->current_fmt->host_fmt);
348 unsigned long size;
349 378
350 if (bytes_per_line < 0) 379 if (bytes_per_line < 0)
351 return bytes_per_line; 380 goto error;
352 381
353 buf = to_ceu_vb(vb); 382 size = icd->user_height * bytes_per_line;
383
384 if (vb2_plane_size(vb, 0) < size) {
385 dev_err(icd->parent, "Buffer #%d too small (%lu < %lu)\n",
386 vb->v4l2_buf.index, vb2_plane_size(vb, 0), size);
387 goto error;
388 }
389
390 vb2_set_plane_payload(vb, 0, size);
354 391
355 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__, 392 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
356 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0)); 393 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
357 394
358 /* Added list head initialization on alloc */
359 WARN(!list_empty(&buf->queue), "Buffer %p on queue!\n", vb);
360
361#ifdef DEBUG 395#ifdef DEBUG
362 /* 396 /*
363 * This can be useful if you want to see if we actually fill 397 * This can be useful if you want to see if we actually fill
@@ -367,31 +401,6 @@ static int sh_mobile_ceu_videobuf_prepare(struct vb2_buffer *vb)
367 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0)); 401 memset(vb2_plane_vaddr(vb, 0), 0xaa, vb2_get_plane_payload(vb, 0));
368#endif 402#endif
369 403
370 BUG_ON(NULL == icd->current_fmt);
371
372 size = icd->user_height * bytes_per_line;
373
374 if (vb2_plane_size(vb, 0) < size) {
375 dev_err(icd->parent, "Buffer too small (%lu < %lu)\n",
376 vb2_plane_size(vb, 0), size);
377 return -ENOBUFS;
378 }
379
380 vb2_set_plane_payload(vb, 0, size);
381
382 return 0;
383}
384
385static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
386{
387 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
388 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
389 struct sh_mobile_ceu_dev *pcdev = ici->priv;
390 struct sh_mobile_ceu_buffer *buf = to_ceu_vb(vb);
391
392 dev_dbg(icd->parent, "%s (vb=0x%p) 0x%p %lu\n", __func__,
393 vb, vb2_plane_vaddr(vb, 0), vb2_get_plane_payload(vb, 0));
394
395 spin_lock_irq(&pcdev->lock); 404 spin_lock_irq(&pcdev->lock);
396 list_add_tail(&buf->queue, &pcdev->capture); 405 list_add_tail(&buf->queue, &pcdev->capture);
397 406
@@ -405,6 +414,11 @@ static void sh_mobile_ceu_videobuf_queue(struct vb2_buffer *vb)
405 sh_mobile_ceu_capture(pcdev); 414 sh_mobile_ceu_capture(pcdev);
406 } 415 }
407 spin_unlock_irq(&pcdev->lock); 416 spin_unlock_irq(&pcdev->lock);
417
418 return;
419
420error:
421 vb2_buffer_done(vb, VB2_BUF_STATE_ERROR);
408} 422}
409 423
410static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb) 424static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
@@ -429,11 +443,23 @@ static void sh_mobile_ceu_videobuf_release(struct vb2_buffer *vb)
429 if (buf->queue.next) 443 if (buf->queue.next)
430 list_del_init(&buf->queue); 444 list_del_init(&buf->queue);
431 445
446 pcdev->buf_total -= PAGE_ALIGN(vb2_plane_size(vb, 0));
447 dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
448 pcdev->buf_total);
449
432 spin_unlock_irq(&pcdev->lock); 450 spin_unlock_irq(&pcdev->lock);
433} 451}
434 452
435static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb) 453static int sh_mobile_ceu_videobuf_init(struct vb2_buffer *vb)
436{ 454{
455 struct soc_camera_device *icd = container_of(vb->vb2_queue, struct soc_camera_device, vb2_vidq);
456 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
457 struct sh_mobile_ceu_dev *pcdev = ici->priv;
458
459 pcdev->buf_total += PAGE_ALIGN(vb2_plane_size(vb, 0));
460 dev_dbg(icd->parent, "%s() %zu bytes buffers\n", __func__,
461 pcdev->buf_total);
462
437 /* This is for locking debugging only */ 463 /* This is for locking debugging only */
438 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue); 464 INIT_LIST_HEAD(&to_ceu_vb(vb)->queue);
439 return 0; 465 return 0;
@@ -535,19 +561,29 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd)
535 561
536 pm_runtime_get_sync(ici->v4l2_dev.dev); 562 pm_runtime_get_sync(ici->v4l2_dev.dev);
537 563
564 pcdev->buf_total = 0;
565
538 ret = sh_mobile_ceu_soft_reset(pcdev); 566 ret = sh_mobile_ceu_soft_reset(pcdev);
539 567
540 csi2_sd = find_csi2(pcdev); 568 csi2_sd = find_csi2(pcdev);
569 if (csi2_sd)
570 csi2_sd->grp_id = (long)icd;
541 571
542 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1); 572 ret = v4l2_subdev_call(csi2_sd, core, s_power, 1);
543 if (ret != -ENODEV && ret != -ENOIOCTLCMD && ret < 0) { 573 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV) {
544 pm_runtime_put_sync(ici->v4l2_dev.dev); 574 pm_runtime_put_sync(ici->v4l2_dev.dev);
545 } else { 575 return ret;
546 pcdev->icd = icd;
547 ret = 0;
548 } 576 }
549 577
550 return ret; 578 /*
579 * -ENODEV is special: either csi2_sd == NULL or the CSI-2 driver
580 * has not found this soc-camera device among its clients
581 */
582 if (ret == -ENODEV && csi2_sd)
583 csi2_sd->grp_id = 0;
584 pcdev->icd = icd;
585
586 return 0;
551} 587}
552 588
553/* Called with .video_lock held */ 589/* Called with .video_lock held */
@@ -560,6 +596,8 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd)
560 BUG_ON(icd != pcdev->icd); 596 BUG_ON(icd != pcdev->icd);
561 597
562 v4l2_subdev_call(csi2_sd, core, s_power, 0); 598 v4l2_subdev_call(csi2_sd, core, s_power, 0);
599 if (csi2_sd)
600 csi2_sd->grp_id = 0;
563 /* disable capture, disable interrupts */ 601 /* disable capture, disable interrupts */
564 ceu_write(pcdev, CEIER, 0); 602 ceu_write(pcdev, CEIER, 0);
565 sh_mobile_ceu_soft_reset(pcdev); 603 sh_mobile_ceu_soft_reset(pcdev);
@@ -628,22 +666,22 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
628 left_offset = cam->ceu_left; 666 left_offset = cam->ceu_left;
629 top_offset = cam->ceu_top; 667 top_offset = cam->ceu_top;
630 668
631 /* CEU cropping (CFSZR) is applied _after_ the scaling filter (CFLCR) */ 669 WARN_ON(icd->user_width & 3 || icd->user_height & 3);
670
671 width = icd->user_width;
672
632 if (pcdev->image_mode) { 673 if (pcdev->image_mode) {
633 in_width = cam->width; 674 in_width = cam->width;
634 if (!pcdev->is_16bit) { 675 if (!pcdev->is_16bit) {
635 in_width *= 2; 676 in_width *= 2;
636 left_offset *= 2; 677 left_offset *= 2;
637 } 678 }
638 width = icd->user_width; 679 cdwdr_width = width;
639 cdwdr_width = icd->user_width;
640 } else { 680 } else {
641 int bytes_per_line = soc_mbus_bytes_per_line(icd->user_width, 681 int bytes_per_line = soc_mbus_bytes_per_line(width,
642 icd->current_fmt->host_fmt); 682 icd->current_fmt->host_fmt);
643 unsigned int w_factor; 683 unsigned int w_factor;
644 684
645 width = icd->user_width;
646
647 switch (icd->current_fmt->host_fmt->packing) { 685 switch (icd->current_fmt->host_fmt->packing) {
648 case SOC_MBUS_PACKING_2X8_PADHI: 686 case SOC_MBUS_PACKING_2X8_PADHI:
649 w_factor = 2; 687 w_factor = 2;
@@ -653,10 +691,10 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
653 } 691 }
654 692
655 in_width = cam->width * w_factor; 693 in_width = cam->width * w_factor;
656 left_offset = left_offset * w_factor; 694 left_offset *= w_factor;
657 695
658 if (bytes_per_line < 0) 696 if (bytes_per_line < 0)
659 cdwdr_width = icd->user_width; 697 cdwdr_width = width;
660 else 698 else
661 cdwdr_width = bytes_per_line; 699 cdwdr_width = bytes_per_line;
662 } 700 }
@@ -664,7 +702,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
664 height = icd->user_height; 702 height = icd->user_height;
665 in_height = cam->height; 703 in_height = cam->height;
666 if (V4L2_FIELD_NONE != pcdev->field) { 704 if (V4L2_FIELD_NONE != pcdev->field) {
667 height /= 2; 705 height = (height / 2) & ~3;
668 in_height /= 2; 706 in_height /= 2;
669 top_offset /= 2; 707 top_offset /= 2;
670 cdwdr_width *= 2; 708 cdwdr_width *= 2;
@@ -686,6 +724,7 @@ static void sh_mobile_ceu_set_rect(struct soc_camera_device *icd)
686 724
687 ceu_write(pcdev, CAMOR, camor); 725 ceu_write(pcdev, CAMOR, camor);
688 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width); 726 ceu_write(pcdev, CAPWR, (in_height << 16) | in_width);
727 /* CFSZR clipping is applied _after_ the scaling filter (CFLCR) */
689 ceu_write(pcdev, CFSZR, (height << 16) | width); 728 ceu_write(pcdev, CFSZR, (height << 16) | width);
690 ceu_write(pcdev, CDWDR, cdwdr_width); 729 ceu_write(pcdev, CDWDR, cdwdr_width);
691} 730}
@@ -723,66 +762,93 @@ static void capture_restore(struct sh_mobile_ceu_dev *pcdev, u32 capsr)
723 ceu_write(pcdev, CAPSR, capsr); 762 ceu_write(pcdev, CAPSR, capsr);
724} 763}
725 764
765/* Find the bus subdevice driver, e.g., CSI2 */
766static struct v4l2_subdev *find_bus_subdev(struct sh_mobile_ceu_dev *pcdev,
767 struct soc_camera_device *icd)
768{
769 if (pcdev->csi2_pdev) {
770 struct v4l2_subdev *csi2_sd = find_csi2(pcdev);
771 if (csi2_sd && csi2_sd->grp_id == (u32)icd)
772 return csi2_sd;
773 }
774
775 return soc_camera_to_subdev(icd);
776}
777
778#define CEU_BUS_FLAGS (V4L2_MBUS_MASTER | \
779 V4L2_MBUS_PCLK_SAMPLE_RISING | \
780 V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
781 V4L2_MBUS_HSYNC_ACTIVE_LOW | \
782 V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
783 V4L2_MBUS_VSYNC_ACTIVE_LOW | \
784 V4L2_MBUS_DATA_ACTIVE_HIGH)
785
726/* Capture is not running, no interrupts, no locking needed */ 786/* Capture is not running, no interrupts, no locking needed */
727static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd, 787static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
728 __u32 pixfmt) 788 __u32 pixfmt)
729{ 789{
730 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 790 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
731 struct sh_mobile_ceu_dev *pcdev = ici->priv; 791 struct sh_mobile_ceu_dev *pcdev = ici->priv;
732 int ret; 792 struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
733 unsigned long camera_flags, common_flags, value;
734 int yuv_lineskip;
735 struct sh_mobile_ceu_cam *cam = icd->host_priv; 793 struct sh_mobile_ceu_cam *cam = icd->host_priv;
794 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
795 unsigned long value, common_flags = CEU_BUS_FLAGS;
736 u32 capsr = capture_save_reset(pcdev); 796 u32 capsr = capture_save_reset(pcdev);
797 unsigned int yuv_lineskip;
798 int ret;
737 799
738 camera_flags = icd->ops->query_bus_param(icd); 800 /*
739 common_flags = soc_camera_bus_param_compatible(camera_flags, 801 * If the client doesn't implement g_mbus_config, we just use our
740 make_bus_param(pcdev)); 802 * platform data
741 if (!common_flags) 803 */
742 return -EINVAL; 804 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
805 if (!ret) {
806 common_flags = soc_mbus_config_compatible(&cfg,
807 common_flags);
808 if (!common_flags)
809 return -EINVAL;
810 } else if (ret != -ENOIOCTLCMD) {
811 return ret;
812 }
743 813
744 /* Make choises, based on platform preferences */ 814 /* Make choises, based on platform preferences */
745 if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && 815 if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
746 (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { 816 (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
747 if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW) 817 if (pcdev->pdata->flags & SH_CEU_FLAG_HSYNC_LOW)
748 common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; 818 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
749 else 819 else
750 common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; 820 common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
751 } 821 }
752 822
753 if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && 823 if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
754 (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { 824 (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
755 if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW) 825 if (pcdev->pdata->flags & SH_CEU_FLAG_VSYNC_LOW)
756 common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; 826 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
757 else 827 else
758 common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; 828 common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
759 } 829 }
760 830
761 ret = icd->ops->set_bus_param(icd, common_flags); 831 cfg.flags = common_flags;
762 if (ret < 0) 832 ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
833 if (ret < 0 && ret != -ENOIOCTLCMD)
763 return ret; 834 return ret;
764 835
765 switch (common_flags & SOCAM_DATAWIDTH_MASK) { 836 if (icd->current_fmt->host_fmt->bits_per_sample > 8)
766 case SOCAM_DATAWIDTH_8:
767 pcdev->is_16bit = 0;
768 break;
769 case SOCAM_DATAWIDTH_16:
770 pcdev->is_16bit = 1; 837 pcdev->is_16bit = 1;
771 break; 838 else
772 default: 839 pcdev->is_16bit = 0;
773 return -EINVAL;
774 }
775 840
776 ceu_write(pcdev, CRCNTR, 0); 841 ceu_write(pcdev, CRCNTR, 0);
777 ceu_write(pcdev, CRCMPR, 0); 842 ceu_write(pcdev, CRCMPR, 0);
778 843
779 value = 0x00000010; /* data fetch by default */ 844 value = 0x00000010; /* data fetch by default */
780 yuv_lineskip = 0; 845 yuv_lineskip = 0x10;
781 846
782 switch (icd->current_fmt->host_fmt->fourcc) { 847 switch (icd->current_fmt->host_fmt->fourcc) {
783 case V4L2_PIX_FMT_NV12: 848 case V4L2_PIX_FMT_NV12:
784 case V4L2_PIX_FMT_NV21: 849 case V4L2_PIX_FMT_NV21:
785 yuv_lineskip = 1; /* skip for NV12/21, no skip for NV16/61 */ 850 /* convert 4:2:2 -> 4:2:0 */
851 yuv_lineskip = 0; /* skip for NV12/21, no skip for NV16/61 */
786 /* fall-through */ 852 /* fall-through */
787 case V4L2_PIX_FMT_NV16: 853 case V4L2_PIX_FMT_NV16:
788 case V4L2_PIX_FMT_NV61: 854 case V4L2_PIX_FMT_NV61:
@@ -808,8 +874,8 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
808 icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61) 874 icd->current_fmt->host_fmt->fourcc == V4L2_PIX_FMT_NV61)
809 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */ 875 value ^= 0x00000100; /* swap U, V to change from NV1x->NVx1 */
810 876
811 value |= common_flags & SOCAM_VSYNC_ACTIVE_LOW ? 1 << 1 : 0; 877 value |= common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW ? 1 << 1 : 0;
812 value |= common_flags & SOCAM_HSYNC_ACTIVE_LOW ? 1 << 0 : 0; 878 value |= common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW ? 1 << 0 : 0;
813 value |= pcdev->is_16bit ? 1 << 12 : 0; 879 value |= pcdev->is_16bit ? 1 << 12 : 0;
814 880
815 /* CSI2 mode */ 881 /* CSI2 mode */
@@ -852,9 +918,7 @@ static int sh_mobile_ceu_set_bus_param(struct soc_camera_device *icd,
852 * using 7 we swap the data bytes to match the incoming order: 918 * using 7 we swap the data bytes to match the incoming order:
853 * D0, D1, D2, D3, D4, D5, D6, D7 919 * D0, D1, D2, D3, D4, D5, D6, D7
854 */ 920 */
855 value = 0x00000017; 921 value = 0x00000007 | yuv_lineskip;
856 if (yuv_lineskip)
857 value &= ~0x00000010; /* convert 4:2:2 -> 4:2:0 */
858 922
859 ceu_write(pcdev, CDOCR, value); 923 ceu_write(pcdev, CDOCR, value);
860 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */ 924 ceu_write(pcdev, CFWCR, 0); /* keep "datafetch firewall" disabled */
@@ -875,13 +939,19 @@ static int sh_mobile_ceu_try_bus_param(struct soc_camera_device *icd,
875{ 939{
876 struct soc_camera_host *ici = to_soc_camera_host(icd->parent); 940 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
877 struct sh_mobile_ceu_dev *pcdev = ici->priv; 941 struct sh_mobile_ceu_dev *pcdev = ici->priv;
878 unsigned long camera_flags, common_flags; 942 struct v4l2_subdev *sd = find_bus_subdev(pcdev, icd);
943 unsigned long common_flags = CEU_BUS_FLAGS;
944 struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
945 int ret;
879 946
880 camera_flags = icd->ops->query_bus_param(icd); 947 ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
881 common_flags = soc_camera_bus_param_compatible(camera_flags, 948 if (!ret)
882 make_bus_param(pcdev)); 949 common_flags = soc_mbus_config_compatible(&cfg,
883 if (!common_flags || buswidth > 16 || 950 common_flags);
884 (buswidth > 8 && !(common_flags & SOCAM_DATAWIDTH_16))) 951 else if (ret != -ENOIOCTLCMD)
952 return ret;
953
954 if (!common_flags || buswidth > 16)
885 return -EINVAL; 955 return -EINVAL;
886 956
887 return 0; 957 return 0;
@@ -891,26 +961,26 @@ static const struct soc_mbus_pixelfmt sh_mobile_ceu_formats[] = {
891 { 961 {
892 .fourcc = V4L2_PIX_FMT_NV12, 962 .fourcc = V4L2_PIX_FMT_NV12,
893 .name = "NV12", 963 .name = "NV12",
894 .bits_per_sample = 12, 964 .bits_per_sample = 8,
895 .packing = SOC_MBUS_PACKING_NONE, 965 .packing = SOC_MBUS_PACKING_1_5X8,
896 .order = SOC_MBUS_ORDER_LE, 966 .order = SOC_MBUS_ORDER_LE,
897 }, { 967 }, {
898 .fourcc = V4L2_PIX_FMT_NV21, 968 .fourcc = V4L2_PIX_FMT_NV21,
899 .name = "NV21", 969 .name = "NV21",
900 .bits_per_sample = 12, 970 .bits_per_sample = 8,
901 .packing = SOC_MBUS_PACKING_NONE, 971 .packing = SOC_MBUS_PACKING_1_5X8,
902 .order = SOC_MBUS_ORDER_LE, 972 .order = SOC_MBUS_ORDER_LE,
903 }, { 973 }, {
904 .fourcc = V4L2_PIX_FMT_NV16, 974 .fourcc = V4L2_PIX_FMT_NV16,
905 .name = "NV16", 975 .name = "NV16",
906 .bits_per_sample = 16, 976 .bits_per_sample = 8,
907 .packing = SOC_MBUS_PACKING_NONE, 977 .packing = SOC_MBUS_PACKING_2X8_PADHI,
908 .order = SOC_MBUS_ORDER_LE, 978 .order = SOC_MBUS_ORDER_LE,
909 }, { 979 }, {
910 .fourcc = V4L2_PIX_FMT_NV61, 980 .fourcc = V4L2_PIX_FMT_NV61,
911 .name = "NV61", 981 .name = "NV61",
912 .bits_per_sample = 16, 982 .bits_per_sample = 8,
913 .packing = SOC_MBUS_PACKING_NONE, 983 .packing = SOC_MBUS_PACKING_2X8_PADHI,
914 .order = SOC_MBUS_ORDER_LE, 984 .order = SOC_MBUS_ORDER_LE,
915 }, 985 },
916}; 986};
@@ -920,6 +990,8 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
920{ 990{
921 return fmt->packing == SOC_MBUS_PACKING_NONE || 991 return fmt->packing == SOC_MBUS_PACKING_NONE ||
922 (fmt->bits_per_sample == 8 && 992 (fmt->bits_per_sample == 8 &&
993 fmt->packing == SOC_MBUS_PACKING_1_5X8) ||
994 (fmt->bits_per_sample == 8 &&
923 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) || 995 fmt->packing == SOC_MBUS_PACKING_2X8_PADHI) ||
924 (fmt->bits_per_sample > 8 && 996 (fmt->bits_per_sample > 8 &&
925 fmt->packing == SOC_MBUS_PACKING_EXTEND16); 997 fmt->packing == SOC_MBUS_PACKING_EXTEND16);
@@ -927,6 +999,38 @@ static bool sh_mobile_ceu_packing_supported(const struct soc_mbus_pixelfmt *fmt)
927 999
928static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect); 1000static int client_g_rect(struct v4l2_subdev *sd, struct v4l2_rect *rect);
929 1001
1002static struct soc_camera_device *ctrl_to_icd(struct v4l2_ctrl *ctrl)
1003{
1004 return container_of(ctrl->handler, struct soc_camera_device,
1005 ctrl_handler);
1006}
1007
1008static int sh_mobile_ceu_s_ctrl(struct v4l2_ctrl *ctrl)
1009{
1010 struct soc_camera_device *icd = ctrl_to_icd(ctrl);
1011 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1012 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1013
1014 switch (ctrl->id) {
1015 case V4L2_CID_SHARPNESS:
1016 switch (icd->current_fmt->host_fmt->fourcc) {
1017 case V4L2_PIX_FMT_NV12:
1018 case V4L2_PIX_FMT_NV21:
1019 case V4L2_PIX_FMT_NV16:
1020 case V4L2_PIX_FMT_NV61:
1021 ceu_write(pcdev, CLFCR, !ctrl->val);
1022 return 0;
1023 }
1024 break;
1025 }
1026
1027 return -EINVAL;
1028}
1029
1030static const struct v4l2_ctrl_ops sh_mobile_ceu_ctrl_ops = {
1031 .s_ctrl = sh_mobile_ceu_s_ctrl,
1032};
1033
930static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx, 1034static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int idx,
931 struct soc_camera_format_xlate *xlate) 1035 struct soc_camera_format_xlate *xlate)
932{ 1036{
@@ -952,6 +1056,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
952 } 1056 }
953 1057
954 if (!pcdev->pdata->csi2) { 1058 if (!pcdev->pdata->csi2) {
1059 /* Are there any restrictions in the CSI-2 case? */
955 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample); 1060 ret = sh_mobile_ceu_try_bus_param(icd, fmt->bits_per_sample);
956 if (ret < 0) 1061 if (ret < 0)
957 return 0; 1062 return 0;
@@ -962,6 +1067,12 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
962 struct v4l2_rect rect; 1067 struct v4l2_rect rect;
963 int shift = 0; 1068 int shift = 0;
964 1069
1070 /* Add our control */
1071 v4l2_ctrl_new_std(&icd->ctrl_handler, &sh_mobile_ceu_ctrl_ops,
1072 V4L2_CID_SHARPNESS, 0, 1, 1, 0);
1073 if (icd->ctrl_handler.error)
1074 return icd->ctrl_handler.error;
1075
965 /* FIXME: subwindow is lost between close / open */ 1076 /* FIXME: subwindow is lost between close / open */
966 1077
967 /* Cache current client geometry */ 1078 /* Cache current client geometry */
@@ -1004,9 +1115,6 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
1004 cam->width = mf.width; 1115 cam->width = mf.width;
1005 cam->height = mf.height; 1116 cam->height = mf.height;
1006 1117
1007 cam->width = mf.width;
1008 cam->height = mf.height;
1009
1010 icd->host_priv = cam; 1118 icd->host_priv = cam;
1011 } else { 1119 } else {
1012 cam = icd->host_priv; 1120 cam = icd->host_priv;
@@ -1278,6 +1386,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
1278 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h; 1386 unsigned int width = mf->width, height = mf->height, tmp_w, tmp_h;
1279 unsigned int max_width, max_height; 1387 unsigned int max_width, max_height;
1280 struct v4l2_cropcap cap; 1388 struct v4l2_cropcap cap;
1389 bool ceu_1to1;
1281 int ret; 1390 int ret;
1282 1391
1283 ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, 1392 ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
@@ -1287,7 +1396,14 @@ static int client_s_fmt(struct soc_camera_device *icd,
1287 1396
1288 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height); 1397 dev_geo(dev, "camera scaled to %ux%u\n", mf->width, mf->height);
1289 1398
1290 if ((width == mf->width && height == mf->height) || !ceu_can_scale) 1399 if (width == mf->width && height == mf->height) {
1400 /* Perfect! The client has done it all. */
1401 ceu_1to1 = true;
1402 goto update_cache;
1403 }
1404
1405 ceu_1to1 = false;
1406 if (!ceu_can_scale)
1291 goto update_cache; 1407 goto update_cache;
1292 1408
1293 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 1409 cap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
@@ -1327,7 +1443,10 @@ update_cache:
1327 if (ret < 0) 1443 if (ret < 0)
1328 return ret; 1444 return ret;
1329 1445
1330 update_subrect(cam); 1446 if (ceu_1to1)
1447 cam->subrect = cam->rect;
1448 else
1449 update_subrect(cam);
1331 1450
1332 return 0; 1451 return 0;
1333} 1452}
@@ -1414,7 +1533,10 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1414 capsr = capture_save_reset(pcdev); 1533 capsr = capture_save_reset(pcdev);
1415 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr); 1534 dev_dbg(dev, "CAPSR 0x%x, CFLCR 0x%x\n", capsr, pcdev->cflcr);
1416 1535
1417 /* 1. - 2. Apply iterative camera S_CROP for new input window. */ 1536 /*
1537 * 1. - 2. Apply iterative camera S_CROP for new input window, read back
1538 * actual camera rectangle.
1539 */
1418 ret = client_s_crop(icd, a, &cam_crop); 1540 ret = client_s_crop(icd, a, &cam_crop);
1419 if (ret < 0) 1541 if (ret < 0)
1420 return ret; 1542 return ret;
@@ -1498,8 +1620,9 @@ static int sh_mobile_ceu_set_crop(struct soc_camera_device *icd,
1498 ceu_write(pcdev, CFLCR, cflcr); 1620 ceu_write(pcdev, CFLCR, cflcr);
1499 } 1621 }
1500 1622
1501 icd->user_width = out_width; 1623 icd->user_width = out_width & ~3;
1502 icd->user_height = out_height; 1624 icd->user_height = out_height & ~3;
1625 /* Offsets are applied at the CEU scaling filter input */
1503 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1; 1626 cam->ceu_left = scale_down(rect->left - cam_rect->left, scale_cam_h) & ~1;
1504 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1; 1627 cam->ceu_top = scale_down(rect->top - cam_rect->top, scale_cam_v) & ~1;
1505 1628
@@ -1538,7 +1661,7 @@ static int sh_mobile_ceu_get_crop(struct soc_camera_device *icd,
1538 * CEU crop, mapped backed onto the client input (subrect). 1661 * CEU crop, mapped backed onto the client input (subrect).
1539 */ 1662 */
1540static void calculate_client_output(struct soc_camera_device *icd, 1663static void calculate_client_output(struct soc_camera_device *icd,
1541 struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf) 1664 const struct v4l2_pix_format *pix, struct v4l2_mbus_framefmt *mf)
1542{ 1665{
1543 struct sh_mobile_ceu_cam *cam = icd->host_priv; 1666 struct sh_mobile_ceu_cam *cam = icd->host_priv;
1544 struct device *dev = icd->parent; 1667 struct device *dev = icd->parent;
@@ -1574,8 +1697,8 @@ static void calculate_client_output(struct soc_camera_device *icd,
1574 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v); 1697 dev_geo(dev, "3: scales %u:%u\n", scale_h, scale_v);
1575 1698
1576 /* 1699 /*
1577 * 4. Calculate client output window by applying combined scales to real 1700 * 4. Calculate desired client output window by applying combined scales
1578 * input window. 1701 * to client (real) input window.
1579 */ 1702 */
1580 mf->width = scale_down(cam->rect.width, scale_h); 1703 mf->width = scale_down(cam->rect.width, scale_h);
1581 mf->height = scale_down(cam->rect.height, scale_v); 1704 mf->height = scale_down(cam->rect.height, scale_v);
@@ -1600,8 +1723,6 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1600 bool image_mode; 1723 bool image_mode;
1601 enum v4l2_field field; 1724 enum v4l2_field field;
1602 1725
1603 dev_geo(dev, "S_FMT(pix=0x%x, %ux%u)\n", pixfmt, pix->width, pix->height);
1604
1605 switch (pix->field) { 1726 switch (pix->field) {
1606 default: 1727 default:
1607 pix->field = V4L2_FIELD_NONE; 1728 pix->field = V4L2_FIELD_NONE;
@@ -1622,8 +1743,8 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1622 return -EINVAL; 1743 return -EINVAL;
1623 } 1744 }
1624 1745
1625 /* 1.-4. Calculate client output geometry */ 1746 /* 1.-4. Calculate desired client output geometry */
1626 calculate_client_output(icd, &f->fmt.pix, &mf); 1747 calculate_client_output(icd, pix, &mf);
1627 mf.field = pix->field; 1748 mf.field = pix->field;
1628 mf.colorspace = pix->colorspace; 1749 mf.colorspace = pix->colorspace;
1629 mf.code = xlate->code; 1750 mf.code = xlate->code;
@@ -1639,6 +1760,9 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1639 image_mode = false; 1760 image_mode = false;
1640 } 1761 }
1641 1762
1763 dev_geo(dev, "S_FMT(pix=0x%x, fld 0x%x, code 0x%x, %ux%u)\n", pixfmt, mf.field, mf.code,
1764 pix->width, pix->height);
1765
1642 dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height); 1766 dev_geo(dev, "4: request camera output %ux%u\n", mf.width, mf.height);
1643 1767
1644 /* 5. - 9. */ 1768 /* 5. - 9. */
@@ -1700,6 +1824,10 @@ static int sh_mobile_ceu_set_fmt(struct soc_camera_device *icd,
1700 pcdev->field = field; 1824 pcdev->field = field;
1701 pcdev->image_mode = image_mode; 1825 pcdev->image_mode = image_mode;
1702 1826
1827 /* CFSZR requirement */
1828 pix->width &= ~3;
1829 pix->height &= ~3;
1830
1703 return 0; 1831 return 0;
1704} 1832}
1705 1833
@@ -1725,7 +1853,8 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1725 1853
1726 /* FIXME: calculate using depth and bus width */ 1854 /* FIXME: calculate using depth and bus width */
1727 1855
1728 v4l_bound_align_image(&pix->width, 2, 2560, 1, 1856 /* CFSZR requires height and width to be 4-pixel aligned */
1857 v4l_bound_align_image(&pix->width, 2, 2560, 2,
1729 &pix->height, 4, 1920, 2, 0); 1858 &pix->height, 4, 1920, 2, 0);
1730 1859
1731 width = pix->width; 1860 width = pix->width;
@@ -1778,6 +1907,9 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
1778 pix->height = height; 1907 pix->height = height;
1779 } 1908 }
1780 1909
1910 pix->width &= ~3;
1911 pix->height &= ~3;
1912
1781 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n", 1913 dev_geo(icd->parent, "%s(): return %d, fmt 0x%x, %ux%u\n",
1782 __func__, ret, pix->pixelformat, pix->width, pix->height); 1914 __func__, ret, pix->pixelformat, pix->width, pix->height);
1783 1915
@@ -1824,8 +1956,8 @@ static int sh_mobile_ceu_set_livecrop(struct soc_camera_device *icd,
1824 out_height != f.fmt.pix.height)) 1956 out_height != f.fmt.pix.height))
1825 ret = -EINVAL; 1957 ret = -EINVAL;
1826 if (!ret) { 1958 if (!ret) {
1827 icd->user_width = out_width; 1959 icd->user_width = out_width & ~3;
1828 icd->user_height = out_height; 1960 icd->user_height = out_height & ~3;
1829 ret = sh_mobile_ceu_set_bus_param(icd, 1961 ret = sh_mobile_ceu_set_bus_param(icd,
1830 icd->current_fmt->host_fmt->fourcc); 1962 icd->current_fmt->host_fmt->fourcc);
1831 } 1963 }
@@ -1869,55 +2001,6 @@ static int sh_mobile_ceu_init_videobuf(struct vb2_queue *q,
1869 return vb2_queue_init(q); 2001 return vb2_queue_init(q);
1870} 2002}
1871 2003
1872static int sh_mobile_ceu_get_ctrl(struct soc_camera_device *icd,
1873 struct v4l2_control *ctrl)
1874{
1875 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1876 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1877 u32 val;
1878
1879 switch (ctrl->id) {
1880 case V4L2_CID_SHARPNESS:
1881 val = ceu_read(pcdev, CLFCR);
1882 ctrl->value = val ^ 1;
1883 return 0;
1884 }
1885 return -ENOIOCTLCMD;
1886}
1887
1888static int sh_mobile_ceu_set_ctrl(struct soc_camera_device *icd,
1889 struct v4l2_control *ctrl)
1890{
1891 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
1892 struct sh_mobile_ceu_dev *pcdev = ici->priv;
1893
1894 switch (ctrl->id) {
1895 case V4L2_CID_SHARPNESS:
1896 switch (icd->current_fmt->host_fmt->fourcc) {
1897 case V4L2_PIX_FMT_NV12:
1898 case V4L2_PIX_FMT_NV21:
1899 case V4L2_PIX_FMT_NV16:
1900 case V4L2_PIX_FMT_NV61:
1901 ceu_write(pcdev, CLFCR, !ctrl->value);
1902 return 0;
1903 }
1904 return -EINVAL;
1905 }
1906 return -ENOIOCTLCMD;
1907}
1908
1909static const struct v4l2_queryctrl sh_mobile_ceu_controls[] = {
1910 {
1911 .id = V4L2_CID_SHARPNESS,
1912 .type = V4L2_CTRL_TYPE_BOOLEAN,
1913 .name = "Low-pass filter",
1914 .minimum = 0,
1915 .maximum = 1,
1916 .step = 1,
1917 .default_value = 0,
1918 },
1919};
1920
1921static struct soc_camera_host_ops sh_mobile_ceu_host_ops = { 2004static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1922 .owner = THIS_MODULE, 2005 .owner = THIS_MODULE,
1923 .add = sh_mobile_ceu_add_device, 2006 .add = sh_mobile_ceu_add_device,
@@ -1929,14 +2012,10 @@ static struct soc_camera_host_ops sh_mobile_ceu_host_ops = {
1929 .set_livecrop = sh_mobile_ceu_set_livecrop, 2012 .set_livecrop = sh_mobile_ceu_set_livecrop,
1930 .set_fmt = sh_mobile_ceu_set_fmt, 2013 .set_fmt = sh_mobile_ceu_set_fmt,
1931 .try_fmt = sh_mobile_ceu_try_fmt, 2014 .try_fmt = sh_mobile_ceu_try_fmt,
1932 .set_ctrl = sh_mobile_ceu_set_ctrl,
1933 .get_ctrl = sh_mobile_ceu_get_ctrl,
1934 .poll = sh_mobile_ceu_poll, 2015 .poll = sh_mobile_ceu_poll,
1935 .querycap = sh_mobile_ceu_querycap, 2016 .querycap = sh_mobile_ceu_querycap,
1936 .set_bus_param = sh_mobile_ceu_set_bus_param, 2017 .set_bus_param = sh_mobile_ceu_set_bus_param,
1937 .init_videobuf2 = sh_mobile_ceu_init_videobuf, 2018 .init_videobuf2 = sh_mobile_ceu_init_videobuf,
1938 .controls = sh_mobile_ceu_controls,
1939 .num_controls = ARRAY_SIZE(sh_mobile_ceu_controls),
1940}; 2019};
1941 2020
1942struct bus_wait { 2021struct bus_wait {
diff --git a/drivers/media/video/sh_mobile_csi2.c b/drivers/media/video/sh_mobile_csi2.c
index 2893a0134c7..37706eb81f2 100644
--- a/drivers/media/video/sh_mobile_csi2.c
+++ b/drivers/media/video/sh_mobile_csi2.c
@@ -19,6 +19,7 @@
19#include <media/sh_mobile_ceu.h> 19#include <media/sh_mobile_ceu.h>
20#include <media/sh_mobile_csi2.h> 20#include <media/sh_mobile_csi2.h>
21#include <media/soc_camera.h> 21#include <media/soc_camera.h>
22#include <media/soc_mediabus.h>
22#include <media/v4l2-common.h> 23#include <media/v4l2-common.h>
23#include <media/v4l2-dev.h> 24#include <media/v4l2-dev.h>
24#include <media/v4l2-device.h> 25#include <media/v4l2-device.h>
@@ -35,11 +36,10 @@ struct sh_csi2 {
35 struct v4l2_subdev subdev; 36 struct v4l2_subdev subdev;
36 struct list_head list; 37 struct list_head list;
37 unsigned int irq; 38 unsigned int irq;
39 unsigned long mipi_flags;
38 void __iomem *base; 40 void __iomem *base;
39 struct platform_device *pdev; 41 struct platform_device *pdev;
40 struct sh_csi2_client_config *client; 42 struct sh_csi2_client_config *client;
41 unsigned long (*query_bus_param)(struct soc_camera_device *);
42 int (*set_bus_param)(struct soc_camera_device *, unsigned long);
43}; 43};
44 44
45static int sh_csi2_try_fmt(struct v4l2_subdev *sd, 45static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
@@ -127,9 +127,34 @@ static int sh_csi2_s_fmt(struct v4l2_subdev *sd,
127 return 0; 127 return 0;
128} 128}
129 129
130static int sh_csi2_g_mbus_config(struct v4l2_subdev *sd,
131 struct v4l2_mbus_config *cfg)
132{
133 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING |
134 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH |
135 V4L2_MBUS_MASTER | V4L2_MBUS_DATA_ACTIVE_HIGH;
136 cfg->type = V4L2_MBUS_PARALLEL;
137
138 return 0;
139}
140
141static int sh_csi2_s_mbus_config(struct v4l2_subdev *sd,
142 const struct v4l2_mbus_config *cfg)
143{
144 struct sh_csi2 *priv = container_of(sd, struct sh_csi2, subdev);
145 struct soc_camera_device *icd = (struct soc_camera_device *)sd->grp_id;
146 struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
147 struct v4l2_mbus_config client_cfg = {.type = V4L2_MBUS_CSI2,
148 .flags = priv->mipi_flags};
149
150 return v4l2_subdev_call(client_sd, video, s_mbus_config, &client_cfg);
151}
152
130static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = { 153static struct v4l2_subdev_video_ops sh_csi2_subdev_video_ops = {
131 .s_mbus_fmt = sh_csi2_s_fmt, 154 .s_mbus_fmt = sh_csi2_s_fmt,
132 .try_mbus_fmt = sh_csi2_try_fmt, 155 .try_mbus_fmt = sh_csi2_try_fmt,
156 .g_mbus_config = sh_csi2_g_mbus_config,
157 .s_mbus_config = sh_csi2_s_mbus_config,
133}; 158};
134 159
135static void sh_csi2_hwinit(struct sh_csi2 *priv) 160static void sh_csi2_hwinit(struct sh_csi2 *priv)
@@ -144,11 +169,21 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv)
144 udelay(5); 169 udelay(5);
145 iowrite32(0x00000000, priv->base + SH_CSI2_SRST); 170 iowrite32(0x00000000, priv->base + SH_CSI2_SRST);
146 171
147 if (priv->client->lanes & 3) 172 switch (pdata->type) {
148 tmp |= priv->client->lanes & 3; 173 case SH_CSI2C:
149 else 174 if (priv->client->lanes == 1)
150 /* Default - both lanes */ 175 tmp |= 1;
151 tmp |= 3; 176 else
177 /* Default - both lanes */
178 tmp |= 3;
179 break;
180 case SH_CSI2I:
181 if (!priv->client->lanes || priv->client->lanes > 4)
182 /* Default - all 4 lanes */
183 tmp |= 0xf;
184 else
185 tmp |= (1 << priv->client->lanes) - 1;
186 }
152 187
153 if (priv->client->phy == SH_CSI2_PHY_MAIN) 188 if (priv->client->phy == SH_CSI2_PHY_MAIN)
154 tmp |= 0x8000; 189 tmp |= 0x8000;
@@ -163,38 +198,18 @@ static void sh_csi2_hwinit(struct sh_csi2 *priv)
163 iowrite32(tmp, priv->base + SH_CSI2_CHKSUM); 198 iowrite32(tmp, priv->base + SH_CSI2_CHKSUM);
164} 199}
165 200
166static int sh_csi2_set_bus_param(struct soc_camera_device *icd,
167 unsigned long flags)
168{
169 return 0;
170}
171
172static unsigned long sh_csi2_query_bus_param(struct soc_camera_device *icd)
173{
174 struct soc_camera_link *icl = to_soc_camera_link(icd);
175 const unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
176 SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
177 SOCAM_MASTER | SOCAM_DATAWIDTH_8 | SOCAM_DATA_ACTIVE_HIGH;
178
179 return soc_camera_apply_sensor_flags(icl, flags);
180}
181
182static int sh_csi2_client_connect(struct sh_csi2 *priv) 201static int sh_csi2_client_connect(struct sh_csi2 *priv)
183{ 202{
184 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data; 203 struct sh_csi2_pdata *pdata = priv->pdev->dev.platform_data;
185 struct v4l2_subdev *sd, *csi2_sd = &priv->subdev; 204 struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id;
186 struct soc_camera_device *icd = NULL; 205 struct v4l2_subdev *client_sd = soc_camera_to_subdev(icd);
187 struct device *dev = v4l2_get_subdevdata(&priv->subdev); 206 struct device *dev = v4l2_get_subdevdata(&priv->subdev);
188 int i; 207 struct v4l2_mbus_config cfg;
208 unsigned long common_flags, csi2_flags;
209 int i, ret;
189 210
190 v4l2_device_for_each_subdev(sd, csi2_sd->v4l2_dev) 211 if (priv->client)
191 if (sd->grp_id) { 212 return -EBUSY;
192 icd = (struct soc_camera_device *)sd->grp_id;
193 break;
194 }
195
196 if (!icd)
197 return -EINVAL;
198 213
199 for (i = 0; i < pdata->num_clients; i++) 214 for (i = 0; i < pdata->num_clients; i++)
200 if (&pdata->clients[i].pdev->dev == icd->pdev) 215 if (&pdata->clients[i].pdev->dev == icd->pdev)
@@ -205,14 +220,41 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
205 if (i == pdata->num_clients) 220 if (i == pdata->num_clients)
206 return -ENODEV; 221 return -ENODEV;
207 222
208 priv->client = pdata->clients + i; 223 /* Check if we can support this camera */
224 csi2_flags = V4L2_MBUS_CSI2_CONTINUOUS_CLOCK | V4L2_MBUS_CSI2_1_LANE;
225
226 switch (pdata->type) {
227 case SH_CSI2C:
228 if (pdata->clients[i].lanes != 1)
229 csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
230 break;
231 case SH_CSI2I:
232 switch (pdata->clients[i].lanes) {
233 default:
234 csi2_flags |= V4L2_MBUS_CSI2_4_LANE;
235 case 3:
236 csi2_flags |= V4L2_MBUS_CSI2_3_LANE;
237 case 2:
238 csi2_flags |= V4L2_MBUS_CSI2_2_LANE;
239 }
240 }
209 241
210 priv->set_bus_param = icd->ops->set_bus_param; 242 cfg.type = V4L2_MBUS_CSI2;
211 priv->query_bus_param = icd->ops->query_bus_param; 243 ret = v4l2_subdev_call(client_sd, video, g_mbus_config, &cfg);
212 icd->ops->set_bus_param = sh_csi2_set_bus_param; 244 if (ret == -ENOIOCTLCMD)
213 icd->ops->query_bus_param = sh_csi2_query_bus_param; 245 common_flags = csi2_flags;
246 else if (!ret)
247 common_flags = soc_mbus_config_compatible(&cfg,
248 csi2_flags);
249 else
250 common_flags = 0;
214 251
215 csi2_sd->grp_id = (long)icd; 252 if (!common_flags)
253 return -EINVAL;
254
255 /* All good: camera MIPI configuration supported */
256 priv->mipi_flags = common_flags;
257 priv->client = pdata->clients + i;
216 258
217 pm_runtime_get_sync(dev); 259 pm_runtime_get_sync(dev);
218 260
@@ -223,16 +265,10 @@ static int sh_csi2_client_connect(struct sh_csi2 *priv)
223 265
224static void sh_csi2_client_disconnect(struct sh_csi2 *priv) 266static void sh_csi2_client_disconnect(struct sh_csi2 *priv)
225{ 267{
226 struct soc_camera_device *icd = (struct soc_camera_device *)priv->subdev.grp_id; 268 if (!priv->client)
269 return;
227 270
228 priv->client = NULL; 271 priv->client = NULL;
229 priv->subdev.grp_id = 0;
230
231 /* Driver is about to be unbound */
232 icd->ops->set_bus_param = priv->set_bus_param;
233 icd->ops->query_bus_param = priv->query_bus_param;
234 priv->set_bus_param = NULL;
235 priv->query_bus_param = NULL;
236 272
237 pm_runtime_put(v4l2_get_subdevdata(&priv->subdev)); 273 pm_runtime_put(v4l2_get_subdevdata(&priv->subdev));
238} 274}
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c
index 5bdfe7e16bc..b72580c3895 100644
--- a/drivers/media/video/soc_camera.c
+++ b/drivers/media/video/soc_camera.c
@@ -50,49 +50,65 @@ static LIST_HEAD(hosts);
50static LIST_HEAD(devices); 50static LIST_HEAD(devices);
51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */ 51static DEFINE_MUTEX(list_lock); /* Protects the list of hosts */
52 52
53static int soc_camera_power_set(struct soc_camera_device *icd, 53static int soc_camera_power_on(struct soc_camera_device *icd,
54 struct soc_camera_link *icl, 54 struct soc_camera_link *icl)
55 int power_on)
56{ 55{
57 int ret; 56 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
58 57 int ret = regulator_bulk_enable(icl->num_regulators,
59 if (power_on) { 58 icl->regulators);
60 ret = regulator_bulk_enable(icl->num_regulators, 59 if (ret < 0) {
61 icl->regulators); 60 dev_err(icd->pdev, "Cannot enable regulators\n");
62 if (ret < 0) { 61 return ret;
63 dev_err(icd->pdev, "Cannot enable regulators\n"); 62 }
64 return ret;
65 }
66 63
67 if (icl->power) 64 if (icl->power) {
68 ret = icl->power(icd->pdev, power_on); 65 ret = icl->power(icd->pdev, 1);
69 if (ret < 0) { 66 if (ret < 0) {
70 dev_err(icd->pdev, 67 dev_err(icd->pdev,
71 "Platform failed to power-on the camera.\n"); 68 "Platform failed to power-on the camera.\n");
72 69 goto elinkpwr;
73 regulator_bulk_disable(icl->num_regulators,
74 icl->regulators);
75 return ret;
76 } 70 }
77 } else { 71 }
78 ret = 0; 72
79 if (icl->power) 73 ret = v4l2_subdev_call(sd, core, s_power, 1);
80 ret = icl->power(icd->pdev, 0); 74 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
75 goto esdpwr;
76
77 return 0;
78
79esdpwr:
80 if (icl->power)
81 icl->power(icd->pdev, 0);
82elinkpwr:
83 regulator_bulk_disable(icl->num_regulators,
84 icl->regulators);
85 return ret;
86}
87
88static int soc_camera_power_off(struct soc_camera_device *icd,
89 struct soc_camera_link *icl)
90{
91 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
92 int ret = v4l2_subdev_call(sd, core, s_power, 0);
93
94 if (ret < 0 && ret != -ENOIOCTLCMD && ret != -ENODEV)
95 return ret;
96
97 if (icl->power) {
98 ret = icl->power(icd->pdev, 0);
81 if (ret < 0) { 99 if (ret < 0) {
82 dev_err(icd->pdev, 100 dev_err(icd->pdev,
83 "Platform failed to power-off the camera.\n"); 101 "Platform failed to power-off the camera.\n");
84 return ret; 102 return ret;
85 } 103 }
86
87 ret = regulator_bulk_disable(icl->num_regulators,
88 icl->regulators);
89 if (ret < 0) {
90 dev_err(icd->pdev, "Cannot disable regulators\n");
91 return ret;
92 }
93 } 104 }
94 105
95 return 0; 106 ret = regulator_bulk_disable(icl->num_regulators,
107 icl->regulators);
108 if (ret < 0)
109 dev_err(icd->pdev, "Cannot disable regulators\n");
110
111 return ret;
96} 112}
97 113
98const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc( 114const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
@@ -108,38 +124,38 @@ const struct soc_camera_format_xlate *soc_camera_xlate_by_fourcc(
108EXPORT_SYMBOL(soc_camera_xlate_by_fourcc); 124EXPORT_SYMBOL(soc_camera_xlate_by_fourcc);
109 125
110/** 126/**
111 * soc_camera_apply_sensor_flags() - apply platform SOCAM_SENSOR_INVERT_* flags 127 * soc_camera_apply_board_flags() - apply platform SOCAM_SENSOR_INVERT_* flags
112 * @icl: camera platform parameters 128 * @icl: camera platform parameters
113 * @flags: flags to be inverted according to platform configuration 129 * @cfg: media bus configuration
114 * @return: resulting flags 130 * @return: resulting flags
115 */ 131 */
116unsigned long soc_camera_apply_sensor_flags(struct soc_camera_link *icl, 132unsigned long soc_camera_apply_board_flags(struct soc_camera_link *icl,
117 unsigned long flags) 133 const struct v4l2_mbus_config *cfg)
118{ 134{
119 unsigned long f; 135 unsigned long f, flags = cfg->flags;
120 136
121 /* If only one of the two polarities is supported, switch to the opposite */ 137 /* If only one of the two polarities is supported, switch to the opposite */
122 if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) { 138 if (icl->flags & SOCAM_SENSOR_INVERT_HSYNC) {
123 f = flags & (SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW); 139 f = flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW);
124 if (f == SOCAM_HSYNC_ACTIVE_HIGH || f == SOCAM_HSYNC_ACTIVE_LOW) 140 if (f == V4L2_MBUS_HSYNC_ACTIVE_HIGH || f == V4L2_MBUS_HSYNC_ACTIVE_LOW)
125 flags ^= SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_LOW; 141 flags ^= V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW;
126 } 142 }
127 143
128 if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) { 144 if (icl->flags & SOCAM_SENSOR_INVERT_VSYNC) {
129 f = flags & (SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW); 145 f = flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW);
130 if (f == SOCAM_VSYNC_ACTIVE_HIGH || f == SOCAM_VSYNC_ACTIVE_LOW) 146 if (f == V4L2_MBUS_VSYNC_ACTIVE_HIGH || f == V4L2_MBUS_VSYNC_ACTIVE_LOW)
131 flags ^= SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW; 147 flags ^= V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW;
132 } 148 }
133 149
134 if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) { 150 if (icl->flags & SOCAM_SENSOR_INVERT_PCLK) {
135 f = flags & (SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING); 151 f = flags & (V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING);
136 if (f == SOCAM_PCLK_SAMPLE_RISING || f == SOCAM_PCLK_SAMPLE_FALLING) 152 if (f == V4L2_MBUS_PCLK_SAMPLE_RISING || f == V4L2_MBUS_PCLK_SAMPLE_FALLING)
137 flags ^= SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING; 153 flags ^= V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING;
138 } 154 }
139 155
140 return flags; 156 return flags;
141} 157}
142EXPORT_SYMBOL(soc_camera_apply_sensor_flags); 158EXPORT_SYMBOL(soc_camera_apply_board_flags);
143 159
144#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \ 160#define pixfmtstr(x) (x) & 0xff, ((x) >> 8) & 0xff, ((x) >> 16) & 0xff, \
145 ((x) >> 24) & 0xff 161 ((x) >> 24) & 0xff
@@ -233,6 +249,14 @@ static int soc_camera_s_std(struct file *file, void *priv, v4l2_std_id *a)
233 return v4l2_subdev_call(sd, core, s_std, *a); 249 return v4l2_subdev_call(sd, core, s_std, *a);
234} 250}
235 251
252static int soc_camera_g_std(struct file *file, void *priv, v4l2_std_id *a)
253{
254 struct soc_camera_device *icd = file->private_data;
255 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
256
257 return v4l2_subdev_call(sd, core, g_std, a);
258}
259
236static int soc_camera_enum_fsizes(struct file *file, void *fh, 260static int soc_camera_enum_fsizes(struct file *file, void *fh,
237 struct v4l2_frmsizeenum *fsize) 261 struct v4l2_frmsizeenum *fsize)
238{ 262{
@@ -318,6 +342,32 @@ static int soc_camera_dqbuf(struct file *file, void *priv,
318 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK); 342 return vb2_dqbuf(&icd->vb2_vidq, p, file->f_flags & O_NONBLOCK);
319} 343}
320 344
345static int soc_camera_create_bufs(struct file *file, void *priv,
346 struct v4l2_create_buffers *create)
347{
348 struct soc_camera_device *icd = file->private_data;
349 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
350
351 /* videobuf2 only */
352 if (ici->ops->init_videobuf)
353 return -EINVAL;
354 else
355 return vb2_create_bufs(&icd->vb2_vidq, create);
356}
357
358static int soc_camera_prepare_buf(struct file *file, void *priv,
359 struct v4l2_buffer *b)
360{
361 struct soc_camera_device *icd = file->private_data;
362 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
363
364 /* videobuf2 only */
365 if (ici->ops->init_videobuf)
366 return -EINVAL;
367 else
368 return vb2_prepare_buf(&icd->vb2_vidq, b);
369}
370
321/* Always entered with .video_lock held */ 371/* Always entered with .video_lock held */
322static int soc_camera_init_user_formats(struct soc_camera_device *icd) 372static int soc_camera_init_user_formats(struct soc_camera_device *icd)
323{ 373{
@@ -448,7 +498,7 @@ static int soc_camera_open(struct file *file)
448 struct soc_camera_host *ici; 498 struct soc_camera_host *ici;
449 int ret; 499 int ret;
450 500
451 if (!icd->ops) 501 if (!to_soc_camera_control(icd))
452 /* No device driver attached */ 502 /* No device driver attached */
453 return -ENODEV; 503 return -ENODEV;
454 504
@@ -476,7 +526,7 @@ static int soc_camera_open(struct file *file)
476 }, 526 },
477 }; 527 };
478 528
479 ret = soc_camera_power_set(icd, icl, 1); 529 ret = soc_camera_power_on(icd, icl);
480 if (ret < 0) 530 if (ret < 0)
481 goto epower; 531 goto epower;
482 532
@@ -512,6 +562,7 @@ static int soc_camera_open(struct file *file)
512 if (ret < 0) 562 if (ret < 0)
513 goto einitvb; 563 goto einitvb;
514 } 564 }
565 v4l2_ctrl_handler_setup(&icd->ctrl_handler);
515 } 566 }
516 567
517 file->private_data = icd; 568 file->private_data = icd;
@@ -529,7 +580,7 @@ esfmt:
529eresume: 580eresume:
530 ici->ops->remove(icd); 581 ici->ops->remove(icd);
531eiciadd: 582eiciadd:
532 soc_camera_power_set(icd, icl, 0); 583 soc_camera_power_off(icd, icl);
533epower: 584epower:
534 icd->use_count--; 585 icd->use_count--;
535 module_put(ici->ops->owner); 586 module_put(ici->ops->owner);
@@ -553,7 +604,7 @@ static int soc_camera_close(struct file *file)
553 if (ici->ops->init_videobuf2) 604 if (ici->ops->init_videobuf2)
554 vb2_queue_release(&icd->vb2_vidq); 605 vb2_queue_release(&icd->vb2_vidq);
555 606
556 soc_camera_power_set(icd, icl, 0); 607 soc_camera_power_off(icd, icl);
557 } 608 }
558 609
559 if (icd->streamer == file) 610 if (icd->streamer == file)
@@ -781,75 +832,6 @@ static int soc_camera_streamoff(struct file *file, void *priv,
781 return 0; 832 return 0;
782} 833}
783 834
784static int soc_camera_queryctrl(struct file *file, void *priv,
785 struct v4l2_queryctrl *qc)
786{
787 struct soc_camera_device *icd = file->private_data;
788 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
789 int i;
790
791 WARN_ON(priv != file->private_data);
792
793 if (!qc->id)
794 return -EINVAL;
795
796 /* First check host controls */
797 for (i = 0; i < ici->ops->num_controls; i++)
798 if (qc->id == ici->ops->controls[i].id) {
799 memcpy(qc, &(ici->ops->controls[i]),
800 sizeof(*qc));
801 return 0;
802 }
803
804 /* Then device controls */
805 for (i = 0; i < icd->ops->num_controls; i++)
806 if (qc->id == icd->ops->controls[i].id) {
807 memcpy(qc, &(icd->ops->controls[i]),
808 sizeof(*qc));
809 return 0;
810 }
811
812 return -EINVAL;
813}
814
815static int soc_camera_g_ctrl(struct file *file, void *priv,
816 struct v4l2_control *ctrl)
817{
818 struct soc_camera_device *icd = file->private_data;
819 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
820 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
821 int ret;
822
823 WARN_ON(priv != file->private_data);
824
825 if (ici->ops->get_ctrl) {
826 ret = ici->ops->get_ctrl(icd, ctrl);
827 if (ret != -ENOIOCTLCMD)
828 return ret;
829 }
830
831 return v4l2_subdev_call(sd, core, g_ctrl, ctrl);
832}
833
834static int soc_camera_s_ctrl(struct file *file, void *priv,
835 struct v4l2_control *ctrl)
836{
837 struct soc_camera_device *icd = file->private_data;
838 struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
839 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
840 int ret;
841
842 WARN_ON(priv != file->private_data);
843
844 if (ici->ops->set_ctrl) {
845 ret = ici->ops->set_ctrl(icd, ctrl);
846 if (ret != -ENOIOCTLCMD)
847 return ret;
848 }
849
850 return v4l2_subdev_call(sd, core, s_ctrl, ctrl);
851}
852
853static int soc_camera_cropcap(struct file *file, void *fh, 835static int soc_camera_cropcap(struct file *file, void *fh,
854 struct v4l2_cropcap *a) 836 struct v4l2_cropcap *a)
855{ 837{
@@ -1003,7 +985,7 @@ static int soc_camera_init_i2c(struct soc_camera_device *icd,
1003 goto ei2cga; 985 goto ei2cga;
1004 } 986 }
1005 987
1006 icl->board_info->platform_data = icd; 988 icl->board_info->platform_data = icl;
1007 989
1008 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap, 990 subdev = v4l2_i2c_new_subdev_board(&ici->v4l2_dev, adap,
1009 icl->board_info, NULL); 991 icl->board_info, NULL);
@@ -1052,12 +1034,29 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1052 1034
1053 dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev)); 1035 dev_info(icd->pdev, "Probing %s\n", dev_name(icd->pdev));
1054 1036
1037 /*
1038 * Currently the subdev with the largest number of controls (13) is
1039 * ov6550. So let's pick 16 as a hint for the control handler. Note
1040 * that this is a hint only: too large and you waste some memory, too
1041 * small and there is a (very) small performance hit when looking up
1042 * controls in the internal hash.
1043 */
1044 ret = v4l2_ctrl_handler_init(&icd->ctrl_handler, 16);
1045 if (ret < 0)
1046 return ret;
1047
1055 ret = regulator_bulk_get(icd->pdev, icl->num_regulators, 1048 ret = regulator_bulk_get(icd->pdev, icl->num_regulators,
1056 icl->regulators); 1049 icl->regulators);
1057 if (ret < 0) 1050 if (ret < 0)
1058 goto ereg; 1051 goto ereg;
1059 1052
1060 ret = soc_camera_power_set(icd, icl, 1); 1053 /*
1054 * This will not yet call v4l2_subdev_core_ops::s_power(1), because the
1055 * subdevice has not been initialised yet. We'll have to call it once
1056 * again after initialisation, even though it shouldn't be needed, we
1057 * don't do any IO here.
1058 */
1059 ret = soc_camera_power_on(icd, icl);
1061 if (ret < 0) 1060 if (ret < 0)
1062 goto epower; 1061 goto epower;
1063 1062
@@ -1098,6 +1097,7 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1098 if (!control || !control->driver || !dev_get_drvdata(control) || 1097 if (!control || !control->driver || !dev_get_drvdata(control) ||
1099 !try_module_get(control->driver->owner)) { 1098 !try_module_get(control->driver->owner)) {
1100 icl->del_device(icd); 1099 icl->del_device(icd);
1100 ret = -ENODEV;
1101 goto enodrv; 1101 goto enodrv;
1102 } 1102 }
1103 } 1103 }
@@ -1105,6 +1105,9 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1105 sd = soc_camera_to_subdev(icd); 1105 sd = soc_camera_to_subdev(icd);
1106 sd->grp_id = (long)icd; 1106 sd->grp_id = (long)icd;
1107 1107
1108 if (v4l2_ctrl_add_handler(&icd->ctrl_handler, sd->ctrl_handler))
1109 goto ectrl;
1110
1108 /* At this point client .probe() should have run already */ 1111 /* At this point client .probe() should have run already */
1109 ret = soc_camera_init_user_formats(icd); 1112 ret = soc_camera_init_user_formats(icd);
1110 if (ret < 0) 1113 if (ret < 0)
@@ -1123,6 +1126,10 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1123 if (ret < 0) 1126 if (ret < 0)
1124 goto evidstart; 1127 goto evidstart;
1125 1128
1129 ret = v4l2_subdev_call(sd, core, s_power, 1);
1130 if (ret < 0 && ret != -ENOIOCTLCMD)
1131 goto esdpwr;
1132
1126 /* Try to improve our guess of a reasonable window format */ 1133 /* Try to improve our guess of a reasonable window format */
1127 if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) { 1134 if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
1128 icd->user_width = mf.width; 1135 icd->user_width = mf.width;
@@ -1133,16 +1140,19 @@ static int soc_camera_probe(struct soc_camera_device *icd)
1133 1140
1134 ici->ops->remove(icd); 1141 ici->ops->remove(icd);
1135 1142
1136 soc_camera_power_set(icd, icl, 0); 1143 soc_camera_power_off(icd, icl);
1137 1144
1138 mutex_unlock(&icd->video_lock); 1145 mutex_unlock(&icd->video_lock);
1139 1146
1140 return 0; 1147 return 0;
1141 1148
1149esdpwr:
1150 video_unregister_device(icd->vdev);
1142evidstart: 1151evidstart:
1143 mutex_unlock(&icd->video_lock); 1152 mutex_unlock(&icd->video_lock);
1144 soc_camera_free_user_formats(icd); 1153 soc_camera_free_user_formats(icd);
1145eiufmt: 1154eiufmt:
1155ectrl:
1146 if (icl->board_info) { 1156 if (icl->board_info) {
1147 soc_camera_free_i2c(icd); 1157 soc_camera_free_i2c(icd);
1148 } else { 1158 } else {
@@ -1152,13 +1162,15 @@ eiufmt:
1152enodrv: 1162enodrv:
1153eadddev: 1163eadddev:
1154 video_device_release(icd->vdev); 1164 video_device_release(icd->vdev);
1165 icd->vdev = NULL;
1155evdc: 1166evdc:
1156 ici->ops->remove(icd); 1167 ici->ops->remove(icd);
1157eadd: 1168eadd:
1158 soc_camera_power_set(icd, icl, 0); 1169 soc_camera_power_off(icd, icl);
1159epower: 1170epower:
1160 regulator_bulk_free(icl->num_regulators, icl->regulators); 1171 regulator_bulk_free(icl->num_regulators, icl->regulators);
1161ereg: 1172ereg:
1173 v4l2_ctrl_handler_free(&icd->ctrl_handler);
1162 return ret; 1174 return ret;
1163} 1175}
1164 1176
@@ -1173,6 +1185,7 @@ static int soc_camera_remove(struct soc_camera_device *icd)
1173 1185
1174 BUG_ON(!icd->parent); 1186 BUG_ON(!icd->parent);
1175 1187
1188 v4l2_ctrl_handler_free(&icd->ctrl_handler);
1176 if (vdev) { 1189 if (vdev) {
1177 video_unregister_device(vdev); 1190 video_unregister_device(vdev);
1178 icd->vdev = NULL; 1191 icd->vdev = NULL;
@@ -1363,24 +1376,24 @@ static int soc_camera_device_register(struct soc_camera_device *icd)
1363 1376
1364static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = { 1377static const struct v4l2_ioctl_ops soc_camera_ioctl_ops = {
1365 .vidioc_querycap = soc_camera_querycap, 1378 .vidioc_querycap = soc_camera_querycap,
1379 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
1366 .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap, 1380 .vidioc_g_fmt_vid_cap = soc_camera_g_fmt_vid_cap,
1367 .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
1368 .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap, 1381 .vidioc_s_fmt_vid_cap = soc_camera_s_fmt_vid_cap,
1382 .vidioc_enum_fmt_vid_cap = soc_camera_enum_fmt_vid_cap,
1369 .vidioc_enum_input = soc_camera_enum_input, 1383 .vidioc_enum_input = soc_camera_enum_input,
1370 .vidioc_g_input = soc_camera_g_input, 1384 .vidioc_g_input = soc_camera_g_input,
1371 .vidioc_s_input = soc_camera_s_input, 1385 .vidioc_s_input = soc_camera_s_input,
1372 .vidioc_s_std = soc_camera_s_std, 1386 .vidioc_s_std = soc_camera_s_std,
1387 .vidioc_g_std = soc_camera_g_std,
1373 .vidioc_enum_framesizes = soc_camera_enum_fsizes, 1388 .vidioc_enum_framesizes = soc_camera_enum_fsizes,
1374 .vidioc_reqbufs = soc_camera_reqbufs, 1389 .vidioc_reqbufs = soc_camera_reqbufs,
1375 .vidioc_try_fmt_vid_cap = soc_camera_try_fmt_vid_cap,
1376 .vidioc_querybuf = soc_camera_querybuf, 1390 .vidioc_querybuf = soc_camera_querybuf,
1377 .vidioc_qbuf = soc_camera_qbuf, 1391 .vidioc_qbuf = soc_camera_qbuf,
1378 .vidioc_dqbuf = soc_camera_dqbuf, 1392 .vidioc_dqbuf = soc_camera_dqbuf,
1393 .vidioc_create_bufs = soc_camera_create_bufs,
1394 .vidioc_prepare_buf = soc_camera_prepare_buf,
1379 .vidioc_streamon = soc_camera_streamon, 1395 .vidioc_streamon = soc_camera_streamon,
1380 .vidioc_streamoff = soc_camera_streamoff, 1396 .vidioc_streamoff = soc_camera_streamoff,
1381 .vidioc_queryctrl = soc_camera_queryctrl,
1382 .vidioc_g_ctrl = soc_camera_g_ctrl,
1383 .vidioc_s_ctrl = soc_camera_s_ctrl,
1384 .vidioc_cropcap = soc_camera_cropcap, 1397 .vidioc_cropcap = soc_camera_cropcap,
1385 .vidioc_g_crop = soc_camera_g_crop, 1398 .vidioc_g_crop = soc_camera_g_crop,
1386 .vidioc_s_crop = soc_camera_s_crop, 1399 .vidioc_s_crop = soc_camera_s_crop,
@@ -1409,6 +1422,7 @@ static int video_dev_create(struct soc_camera_device *icd)
1409 vdev->ioctl_ops = &soc_camera_ioctl_ops; 1422 vdev->ioctl_ops = &soc_camera_ioctl_ops;
1410 vdev->release = video_device_release; 1423 vdev->release = video_device_release;
1411 vdev->tvnorms = V4L2_STD_UNKNOWN; 1424 vdev->tvnorms = V4L2_STD_UNKNOWN;
1425 vdev->ctrl_handler = &icd->ctrl_handler;
1412 vdev->lock = &icd->video_lock; 1426 vdev->lock = &icd->video_lock;
1413 1427
1414 icd->vdev = vdev; 1428 icd->vdev = vdev;
@@ -1427,11 +1441,6 @@ static int soc_camera_video_start(struct soc_camera_device *icd)
1427 if (!icd->parent) 1441 if (!icd->parent)
1428 return -ENODEV; 1442 return -ENODEV;
1429 1443
1430 if (!icd->ops ||
1431 !icd->ops->query_bus_param ||
1432 !icd->ops->set_bus_param)
1433 return -EINVAL;
1434
1435 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1); 1444 ret = video_register_device(icd->vdev, VFL_TYPE_GRABBER, -1);
1436 if (ret < 0) { 1445 if (ret < 0) {
1437 dev_err(icd->pdev, "video_register_device failed: %d\n", ret); 1446 dev_err(icd->pdev, "video_register_device failed: %d\n", ret);
diff --git a/drivers/media/video/soc_camera_platform.c b/drivers/media/video/soc_camera_platform.c
index 8069cd6bc5e..4402a8a74f7 100644
--- a/drivers/media/video/soc_camera_platform.c
+++ b/drivers/media/video/soc_camera_platform.c
@@ -30,32 +30,12 @@ static struct soc_camera_platform_priv *get_priv(struct platform_device *pdev)
30 return container_of(subdev, struct soc_camera_platform_priv, subdev); 30 return container_of(subdev, struct soc_camera_platform_priv, subdev);
31} 31}
32 32
33static struct soc_camera_platform_info *get_info(struct soc_camera_device *icd)
34{
35 struct platform_device *pdev =
36 to_platform_device(to_soc_camera_control(icd));
37 return pdev->dev.platform_data;
38}
39
40static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable) 33static int soc_camera_platform_s_stream(struct v4l2_subdev *sd, int enable)
41{ 34{
42 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd); 35 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
43 return p->set_capture(p, enable); 36 return p->set_capture(p, enable);
44} 37}
45 38
46static int soc_camera_platform_set_bus_param(struct soc_camera_device *icd,
47 unsigned long flags)
48{
49 return 0;
50}
51
52static unsigned long
53soc_camera_platform_query_bus_param(struct soc_camera_device *icd)
54{
55 struct soc_camera_platform_info *p = get_info(icd);
56 return p->bus_param;
57}
58
59static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd, 39static int soc_camera_platform_fill_fmt(struct v4l2_subdev *sd,
60 struct v4l2_mbus_framefmt *mf) 40 struct v4l2_mbus_framefmt *mf)
61{ 41{
@@ -115,6 +95,17 @@ static int soc_camera_platform_cropcap(struct v4l2_subdev *sd,
115 return 0; 95 return 0;
116} 96}
117 97
98static int soc_camera_platform_g_mbus_config(struct v4l2_subdev *sd,
99 struct v4l2_mbus_config *cfg)
100{
101 struct soc_camera_platform_info *p = v4l2_get_subdevdata(sd);
102
103 cfg->flags = p->mbus_param;
104 cfg->type = p->mbus_type;
105
106 return 0;
107}
108
118static struct v4l2_subdev_video_ops platform_subdev_video_ops = { 109static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
119 .s_stream = soc_camera_platform_s_stream, 110 .s_stream = soc_camera_platform_s_stream,
120 .enum_mbus_fmt = soc_camera_platform_enum_fmt, 111 .enum_mbus_fmt = soc_camera_platform_enum_fmt,
@@ -123,6 +114,7 @@ static struct v4l2_subdev_video_ops platform_subdev_video_ops = {
123 .try_mbus_fmt = soc_camera_platform_fill_fmt, 114 .try_mbus_fmt = soc_camera_platform_fill_fmt,
124 .g_mbus_fmt = soc_camera_platform_fill_fmt, 115 .g_mbus_fmt = soc_camera_platform_fill_fmt,
125 .s_mbus_fmt = soc_camera_platform_fill_fmt, 116 .s_mbus_fmt = soc_camera_platform_fill_fmt,
117 .g_mbus_config = soc_camera_platform_g_mbus_config,
126}; 118};
127 119
128static struct v4l2_subdev_ops platform_subdev_ops = { 120static struct v4l2_subdev_ops platform_subdev_ops = {
@@ -130,11 +122,6 @@ static struct v4l2_subdev_ops platform_subdev_ops = {
130 .video = &platform_subdev_video_ops, 122 .video = &platform_subdev_video_ops,
131}; 123};
132 124
133static struct soc_camera_ops soc_camera_platform_ops = {
134 .set_bus_param = soc_camera_platform_set_bus_param,
135 .query_bus_param = soc_camera_platform_query_bus_param,
136};
137
138static int soc_camera_platform_probe(struct platform_device *pdev) 125static int soc_camera_platform_probe(struct platform_device *pdev)
139{ 126{
140 struct soc_camera_host *ici; 127 struct soc_camera_host *ici;
@@ -163,8 +150,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
163 /* Set the control device reference */ 150 /* Set the control device reference */
164 icd->control = &pdev->dev; 151 icd->control = &pdev->dev;
165 152
166 icd->ops = &soc_camera_platform_ops;
167
168 ici = to_soc_camera_host(icd->parent); 153 ici = to_soc_camera_host(icd->parent);
169 154
170 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops); 155 v4l2_subdev_init(&priv->subdev, &platform_subdev_ops);
@@ -178,7 +163,6 @@ static int soc_camera_platform_probe(struct platform_device *pdev)
178 return ret; 163 return ret;
179 164
180evdrs: 165evdrs:
181 icd->ops = NULL;
182 platform_set_drvdata(pdev, NULL); 166 platform_set_drvdata(pdev, NULL);
183 kfree(priv); 167 kfree(priv);
184 return ret; 168 return ret;
@@ -187,11 +171,10 @@ evdrs:
187static int soc_camera_platform_remove(struct platform_device *pdev) 171static int soc_camera_platform_remove(struct platform_device *pdev)
188{ 172{
189 struct soc_camera_platform_priv *priv = get_priv(pdev); 173 struct soc_camera_platform_priv *priv = get_priv(pdev);
190 struct soc_camera_platform_info *p = pdev->dev.platform_data; 174 struct soc_camera_platform_info *p = v4l2_get_subdevdata(&priv->subdev);
191 struct soc_camera_device *icd = p->icd;
192 175
176 p->icd->control = NULL;
193 v4l2_device_unregister_subdev(&priv->subdev); 177 v4l2_device_unregister_subdev(&priv->subdev);
194 icd->ops = NULL;
195 platform_set_drvdata(pdev, NULL); 178 platform_set_drvdata(pdev, NULL);
196 kfree(priv); 179 kfree(priv);
197 return 0; 180 return 0;
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c
index bea7c9cf4f8..cf7f2194ded 100644
--- a/drivers/media/video/soc_mediabus.c
+++ b/drivers/media/video/soc_mediabus.c
@@ -383,6 +383,39 @@ const struct soc_mbus_pixelfmt *soc_mbus_get_fmtdesc(
383} 383}
384EXPORT_SYMBOL(soc_mbus_get_fmtdesc); 384EXPORT_SYMBOL(soc_mbus_get_fmtdesc);
385 385
386unsigned int soc_mbus_config_compatible(const struct v4l2_mbus_config *cfg,
387 unsigned int flags)
388{
389 unsigned long common_flags;
390 bool hsync = true, vsync = true, pclk, data, mode;
391 bool mipi_lanes, mipi_clock;
392
393 common_flags = cfg->flags & flags;
394
395 switch (cfg->type) {
396 case V4L2_MBUS_PARALLEL:
397 hsync = common_flags & (V4L2_MBUS_HSYNC_ACTIVE_HIGH |
398 V4L2_MBUS_HSYNC_ACTIVE_LOW);
399 vsync = common_flags & (V4L2_MBUS_VSYNC_ACTIVE_HIGH |
400 V4L2_MBUS_VSYNC_ACTIVE_LOW);
401 case V4L2_MBUS_BT656:
402 pclk = common_flags & (V4L2_MBUS_PCLK_SAMPLE_RISING |
403 V4L2_MBUS_PCLK_SAMPLE_FALLING);
404 data = common_flags & (V4L2_MBUS_DATA_ACTIVE_HIGH |
405 V4L2_MBUS_DATA_ACTIVE_LOW);
406 mode = common_flags & (V4L2_MBUS_MASTER | V4L2_MBUS_SLAVE);
407 return (!hsync || !vsync || !pclk || !data || !mode) ?
408 0 : common_flags;
409 case V4L2_MBUS_CSI2:
410 mipi_lanes = common_flags & V4L2_MBUS_CSI2_LANES;
411 mipi_clock = common_flags & (V4L2_MBUS_CSI2_NONCONTINUOUS_CLOCK |
412 V4L2_MBUS_CSI2_CONTINUOUS_CLOCK);
413 return (!mipi_lanes || !mipi_clock) ? 0 : common_flags;
414 }
415 return 0;
416}
417EXPORT_SYMBOL(soc_mbus_config_compatible);
418
386static int __init soc_mbus_init(void) 419static int __init soc_mbus_init(void)
387{ 420{
388 return 0; 421 return 0;
diff --git a/drivers/media/video/tw9910.c b/drivers/media/video/tw9910.c
index 742482e3001..a514fa61116 100644
--- a/drivers/media/video/tw9910.c
+++ b/drivers/media/video/tw9910.c
@@ -22,11 +22,13 @@
22#include <linux/slab.h> 22#include <linux/slab.h>
23#include <linux/kernel.h> 23#include <linux/kernel.h>
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/v4l2-mediabus.h>
25#include <linux/videodev2.h> 26#include <linux/videodev2.h>
26#include <media/v4l2-chip-ident.h> 27
27#include <media/v4l2-subdev.h>
28#include <media/soc_camera.h> 28#include <media/soc_camera.h>
29#include <media/tw9910.h> 29#include <media/tw9910.h>
30#include <media/v4l2-chip-ident.h>
31#include <media/v4l2-subdev.h>
30 32
31#define GET_ID(val) ((val & 0xF8) >> 3) 33#define GET_ID(val) ((val & 0xF8) >> 3)
32#define GET_REV(val) (val & 0x07) 34#define GET_REV(val) (val & 0x07)
@@ -203,6 +205,10 @@
203#define RTSEL_FIELD 0x06 /* 0110 = FIELD */ 205#define RTSEL_FIELD 0x06 /* 0110 = FIELD */
204#define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */ 206#define RTSEL_RTCO 0x07 /* 0111 = RTCO ( Real Time Control ) */
205 207
208/* HSYNC start and end are constant for now */
209#define HSYNC_START 0x0260
210#define HSYNC_END 0x0300
211
206/* 212/*
207 * structure 213 * structure
208 */ 214 */
@@ -220,22 +226,11 @@ struct tw9910_scale_ctrl {
220 u16 vscale; 226 u16 vscale;
221}; 227};
222 228
223struct tw9910_cropping_ctrl {
224 u16 vdelay;
225 u16 vactive;
226 u16 hdelay;
227 u16 hactive;
228};
229
230struct tw9910_hsync_ctrl {
231 u16 start;
232 u16 end;
233};
234
235struct tw9910_priv { 229struct tw9910_priv {
236 struct v4l2_subdev subdev; 230 struct v4l2_subdev subdev;
237 struct tw9910_video_info *info; 231 struct tw9910_video_info *info;
238 const struct tw9910_scale_ctrl *scale; 232 const struct tw9910_scale_ctrl *scale;
233 v4l2_std_id norm;
239 u32 revision; 234 u32 revision;
240}; 235};
241 236
@@ -329,11 +324,6 @@ static const struct tw9910_scale_ctrl tw9910_pal_scales[] = {
329 }, 324 },
330}; 325};
331 326
332static const struct tw9910_hsync_ctrl tw9910_hsync_ctrl = {
333 .start = 0x0260,
334 .end = 0x0300,
335};
336
337/* 327/*
338 * general function 328 * general function
339 */ 329 */
@@ -378,21 +368,20 @@ static int tw9910_set_scale(struct i2c_client *client,
378 return ret; 368 return ret;
379} 369}
380 370
381static int tw9910_set_hsync(struct i2c_client *client, 371static int tw9910_set_hsync(struct i2c_client *client)
382 const struct tw9910_hsync_ctrl *hsync)
383{ 372{
384 struct tw9910_priv *priv = to_tw9910(client); 373 struct tw9910_priv *priv = to_tw9910(client);
385 int ret; 374 int ret;
386 375
387 /* bit 10 - 3 */ 376 /* bit 10 - 3 */
388 ret = i2c_smbus_write_byte_data(client, HSBEGIN, 377 ret = i2c_smbus_write_byte_data(client, HSBEGIN,
389 (hsync->start & 0x07F8) >> 3); 378 (HSYNC_START & 0x07F8) >> 3);
390 if (ret < 0) 379 if (ret < 0)
391 return ret; 380 return ret;
392 381
393 /* bit 10 - 3 */ 382 /* bit 10 - 3 */
394 ret = i2c_smbus_write_byte_data(client, HSEND, 383 ret = i2c_smbus_write_byte_data(client, HSEND,
395 (hsync->end & 0x07F8) >> 3); 384 (HSYNC_END & 0x07F8) >> 3);
396 if (ret < 0) 385 if (ret < 0)
397 return ret; 386 return ret;
398 387
@@ -400,8 +389,8 @@ static int tw9910_set_hsync(struct i2c_client *client,
400 /* bit 2 - 0 */ 389 /* bit 2 - 0 */
401 if (1 == priv->revision) 390 if (1 == priv->revision)
402 ret = tw9910_mask_set(client, HSLOWCTL, 0x77, 391 ret = tw9910_mask_set(client, HSLOWCTL, 0x77,
403 (hsync->start & 0x0007) << 4 | 392 (HSYNC_START & 0x0007) << 4 |
404 (hsync->end & 0x0007)); 393 (HSYNC_END & 0x0007));
405 394
406 return ret; 395 return ret;
407} 396}
@@ -433,12 +422,11 @@ static int tw9910_power(struct i2c_client *client, int enable)
433 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2); 422 return tw9910_mask_set(client, ACNTL2, ACNTL2_PDN_MASK, acntl2);
434} 423}
435 424
436static const struct tw9910_scale_ctrl* 425static const struct tw9910_scale_ctrl *tw9910_select_norm(v4l2_std_id norm,
437tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height) 426 u32 width, u32 height)
438{ 427{
439 const struct tw9910_scale_ctrl *scale; 428 const struct tw9910_scale_ctrl *scale;
440 const struct tw9910_scale_ctrl *ret = NULL; 429 const struct tw9910_scale_ctrl *ret = NULL;
441 v4l2_std_id norm = icd->vdev->current_norm;
442 __u32 diff = 0xffffffff, tmp; 430 __u32 diff = 0xffffffff, tmp;
443 int size, i; 431 int size, i;
444 432
@@ -465,7 +453,7 @@ tw9910_select_norm(struct soc_camera_device *icd, u32 width, u32 height)
465} 453}
466 454
467/* 455/*
468 * soc_camera_ops function 456 * subdevice operations
469 */ 457 */
470static int tw9910_s_stream(struct v4l2_subdev *sd, int enable) 458static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
471{ 459{
@@ -507,49 +495,27 @@ static int tw9910_s_stream(struct v4l2_subdev *sd, int enable)
507 return tw9910_power(client, enable); 495 return tw9910_power(client, enable);
508} 496}
509 497
510static int tw9910_set_bus_param(struct soc_camera_device *icd, 498static int tw9910_g_std(struct v4l2_subdev *sd, v4l2_std_id *norm)
511 unsigned long flags)
512{ 499{
513 struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
514 struct i2c_client *client = v4l2_get_subdevdata(sd); 500 struct i2c_client *client = v4l2_get_subdevdata(sd);
515 u8 val = VSSL_VVALID | HSSL_DVALID; 501 struct tw9910_priv *priv = to_tw9910(client);
516 502
517 /* 503 *norm = priv->norm;
518 * set OUTCTR1
519 *
520 * We use VVALID and DVALID signals to control VSYNC and HSYNC
521 * outputs, in this mode their polarity is inverted.
522 */
523 if (flags & SOCAM_HSYNC_ACTIVE_LOW)
524 val |= HSP_HI;
525 504
526 if (flags & SOCAM_VSYNC_ACTIVE_LOW) 505 return 0;
527 val |= VSP_HI;
528
529 return i2c_smbus_write_byte_data(client, OUTCTR1, val);
530} 506}
531 507
532static unsigned long tw9910_query_bus_param(struct soc_camera_device *icd) 508static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
533{ 509{
534 struct i2c_client *client = to_i2c_client(to_soc_camera_control(icd)); 510 struct i2c_client *client = v4l2_get_subdevdata(sd);
535 struct tw9910_priv *priv = to_tw9910(client); 511 struct tw9910_priv *priv = to_tw9910(client);
536 struct soc_camera_link *icl = to_soc_camera_link(icd);
537 unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
538 SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
539 SOCAM_VSYNC_ACTIVE_LOW | SOCAM_HSYNC_ACTIVE_LOW |
540 SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
541 512
542 return soc_camera_apply_sensor_flags(icl, flags); 513 if (!(norm & (V4L2_STD_NTSC | V4L2_STD_PAL)))
543} 514 return -EINVAL;
544
545static int tw9910_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
546{
547 int ret = -EINVAL;
548 515
549 if (norm & (V4L2_STD_NTSC | V4L2_STD_PAL)) 516 priv->norm = norm;
550 ret = 0;
551 517
552 return ret; 518 return 0;
553} 519}
554 520
555static int tw9910_g_chip_ident(struct v4l2_subdev *sd, 521static int tw9910_g_chip_ident(struct v4l2_subdev *sd,
@@ -600,19 +566,17 @@ static int tw9910_s_register(struct v4l2_subdev *sd,
600} 566}
601#endif 567#endif
602 568
603static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a) 569static int tw9910_set_frame(struct v4l2_subdev *sd, u32 *width, u32 *height)
604{ 570{
605 struct v4l2_rect *rect = &a->c;
606 struct i2c_client *client = v4l2_get_subdevdata(sd); 571 struct i2c_client *client = v4l2_get_subdevdata(sd);
607 struct tw9910_priv *priv = to_tw9910(client); 572 struct tw9910_priv *priv = to_tw9910(client);
608 struct soc_camera_device *icd = client->dev.platform_data; 573 int ret = -EINVAL;
609 int ret = -EINVAL; 574 u8 val;
610 u8 val;
611 575
612 /* 576 /*
613 * select suitable norm 577 * select suitable norm
614 */ 578 */
615 priv->scale = tw9910_select_norm(icd, rect->width, rect->height); 579 priv->scale = tw9910_select_norm(priv->norm, *width, *height);
616 if (!priv->scale) 580 if (!priv->scale)
617 goto tw9910_set_fmt_error; 581 goto tw9910_set_fmt_error;
618 582
@@ -670,14 +634,12 @@ static int tw9910_s_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
670 /* 634 /*
671 * set hsync 635 * set hsync
672 */ 636 */
673 ret = tw9910_set_hsync(client, &tw9910_hsync_ctrl); 637 ret = tw9910_set_hsync(client);
674 if (ret < 0) 638 if (ret < 0)
675 goto tw9910_set_fmt_error; 639 goto tw9910_set_fmt_error;
676 640
677 rect->width = priv->scale->width; 641 *width = priv->scale->width;
678 rect->height = priv->scale->height; 642 *height = priv->scale->height;
679 rect->left = 0;
680 rect->top = 0;
681 643
682 return ret; 644 return ret;
683 645
@@ -694,25 +656,15 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
694 struct i2c_client *client = v4l2_get_subdevdata(sd); 656 struct i2c_client *client = v4l2_get_subdevdata(sd);
695 struct tw9910_priv *priv = to_tw9910(client); 657 struct tw9910_priv *priv = to_tw9910(client);
696 658
697 if (!priv->scale) {
698 int ret;
699 struct v4l2_crop crop = {
700 .c = {
701 .left = 0,
702 .top = 0,
703 .width = 640,
704 .height = 480,
705 },
706 };
707 ret = tw9910_s_crop(sd, &crop);
708 if (ret < 0)
709 return ret;
710 }
711
712 a->c.left = 0; 659 a->c.left = 0;
713 a->c.top = 0; 660 a->c.top = 0;
714 a->c.width = priv->scale->width; 661 if (priv->norm & V4L2_STD_NTSC) {
715 a->c.height = priv->scale->height; 662 a->c.width = 640;
663 a->c.height = 480;
664 } else {
665 a->c.width = 768;
666 a->c.height = 576;
667 }
716 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 668 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
717 669
718 return 0; 670 return 0;
@@ -720,14 +672,19 @@ static int tw9910_g_crop(struct v4l2_subdev *sd, struct v4l2_crop *a)
720 672
721static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a) 673static int tw9910_cropcap(struct v4l2_subdev *sd, struct v4l2_cropcap *a)
722{ 674{
675 struct i2c_client *client = v4l2_get_subdevdata(sd);
676 struct tw9910_priv *priv = to_tw9910(client);
677
723 a->bounds.left = 0; 678 a->bounds.left = 0;
724 a->bounds.top = 0; 679 a->bounds.top = 0;
725 a->bounds.width = 768; 680 if (priv->norm & V4L2_STD_NTSC) {
726 a->bounds.height = 576; 681 a->bounds.width = 640;
727 a->defrect.left = 0; 682 a->bounds.height = 480;
728 a->defrect.top = 0; 683 } else {
729 a->defrect.width = 640; 684 a->bounds.width = 768;
730 a->defrect.height = 480; 685 a->bounds.height = 576;
686 }
687 a->defrect = a->bounds;
731 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; 688 a->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
732 a->pixelaspect.numerator = 1; 689 a->pixelaspect.numerator = 1;
733 a->pixelaspect.denominator = 1; 690 a->pixelaspect.denominator = 1;
@@ -743,15 +700,8 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
743 700
744 if (!priv->scale) { 701 if (!priv->scale) {
745 int ret; 702 int ret;
746 struct v4l2_crop crop = { 703 u32 width = 640, height = 480;
747 .c = { 704 ret = tw9910_set_frame(sd, &width, &height);
748 .left = 0,
749 .top = 0,
750 .width = 640,
751 .height = 480,
752 },
753 };
754 ret = tw9910_s_crop(sd, &crop);
755 if (ret < 0) 705 if (ret < 0)
756 return ret; 706 return ret;
757 } 707 }
@@ -768,17 +718,7 @@ static int tw9910_g_fmt(struct v4l2_subdev *sd,
768static int tw9910_s_fmt(struct v4l2_subdev *sd, 718static int tw9910_s_fmt(struct v4l2_subdev *sd,
769 struct v4l2_mbus_framefmt *mf) 719 struct v4l2_mbus_framefmt *mf)
770{ 720{
771 struct i2c_client *client = v4l2_get_subdevdata(sd); 721 u32 width = mf->width, height = mf->height;
772 struct tw9910_priv *priv = to_tw9910(client);
773 /* See tw9910_s_crop() - no proper cropping support */
774 struct v4l2_crop a = {
775 .c = {
776 .left = 0,
777 .top = 0,
778 .width = mf->width,
779 .height = mf->height,
780 },
781 };
782 int ret; 722 int ret;
783 723
784 WARN_ON(mf->field != V4L2_FIELD_ANY && 724 WARN_ON(mf->field != V4L2_FIELD_ANY &&
@@ -792,10 +732,10 @@ static int tw9910_s_fmt(struct v4l2_subdev *sd,
792 732
793 mf->colorspace = V4L2_COLORSPACE_JPEG; 733 mf->colorspace = V4L2_COLORSPACE_JPEG;
794 734
795 ret = tw9910_s_crop(sd, &a); 735 ret = tw9910_set_frame(sd, &width, &height);
796 if (!ret) { 736 if (!ret) {
797 mf->width = priv->scale->width; 737 mf->width = width;
798 mf->height = priv->scale->height; 738 mf->height = height;
799 } 739 }
800 return ret; 740 return ret;
801} 741}
@@ -804,7 +744,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
804 struct v4l2_mbus_framefmt *mf) 744 struct v4l2_mbus_framefmt *mf)
805{ 745{
806 struct i2c_client *client = v4l2_get_subdevdata(sd); 746 struct i2c_client *client = v4l2_get_subdevdata(sd);
807 struct soc_camera_device *icd = client->dev.platform_data; 747 struct tw9910_priv *priv = to_tw9910(client);
808 const struct tw9910_scale_ctrl *scale; 748 const struct tw9910_scale_ctrl *scale;
809 749
810 if (V4L2_FIELD_ANY == mf->field) { 750 if (V4L2_FIELD_ANY == mf->field) {
@@ -820,7 +760,7 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
820 /* 760 /*
821 * select suitable norm 761 * select suitable norm
822 */ 762 */
823 scale = tw9910_select_norm(icd, mf->width, mf->height); 763 scale = tw9910_select_norm(priv->norm, mf->width, mf->height);
824 if (!scale) 764 if (!scale)
825 return -EINVAL; 765 return -EINVAL;
826 766
@@ -830,16 +770,11 @@ static int tw9910_try_fmt(struct v4l2_subdev *sd,
830 return 0; 770 return 0;
831} 771}
832 772
833static int tw9910_video_probe(struct soc_camera_device *icd, 773static int tw9910_video_probe(struct i2c_client *client)
834 struct i2c_client *client)
835{ 774{
836 struct tw9910_priv *priv = to_tw9910(client); 775 struct tw9910_priv *priv = to_tw9910(client);
837 s32 id; 776 s32 id;
838 777
839 /* We must have a parent by now. And it cannot be a wrong one. */
840 BUG_ON(!icd->parent ||
841 to_soc_camera_host(icd->parent)->nr != icd->iface);
842
843 /* 778 /*
844 * tw9910 only use 8 or 16 bit bus width 779 * tw9910 only use 8 or 16 bit bus width
845 */ 780 */
@@ -868,20 +803,15 @@ static int tw9910_video_probe(struct soc_camera_device *icd,
868 dev_info(&client->dev, 803 dev_info(&client->dev,
869 "tw9910 Product ID %0x:%0x\n", id, priv->revision); 804 "tw9910 Product ID %0x:%0x\n", id, priv->revision);
870 805
871 icd->vdev->tvnorms = V4L2_STD_NTSC | V4L2_STD_PAL; 806 priv->norm = V4L2_STD_NTSC;
872 icd->vdev->current_norm = V4L2_STD_NTSC;
873 807
874 return 0; 808 return 0;
875} 809}
876 810
877static struct soc_camera_ops tw9910_ops = {
878 .set_bus_param = tw9910_set_bus_param,
879 .query_bus_param = tw9910_query_bus_param,
880};
881
882static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = { 811static struct v4l2_subdev_core_ops tw9910_subdev_core_ops = {
883 .g_chip_ident = tw9910_g_chip_ident, 812 .g_chip_ident = tw9910_g_chip_ident,
884 .s_std = tw9910_s_std, 813 .s_std = tw9910_s_std,
814 .g_std = tw9910_g_std,
885#ifdef CONFIG_VIDEO_ADV_DEBUG 815#ifdef CONFIG_VIDEO_ADV_DEBUG
886 .g_register = tw9910_g_register, 816 .g_register = tw9910_g_register,
887 .s_register = tw9910_s_register, 817 .s_register = tw9910_s_register,
@@ -898,6 +828,45 @@ static int tw9910_enum_fmt(struct v4l2_subdev *sd, unsigned int index,
898 return 0; 828 return 0;
899} 829}
900 830
831static int tw9910_g_mbus_config(struct v4l2_subdev *sd,
832 struct v4l2_mbus_config *cfg)
833{
834 struct i2c_client *client = v4l2_get_subdevdata(sd);
835 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
836
837 cfg->flags = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
838 V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW |
839 V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_LOW |
840 V4L2_MBUS_DATA_ACTIVE_HIGH;
841 cfg->type = V4L2_MBUS_PARALLEL;
842 cfg->flags = soc_camera_apply_board_flags(icl, cfg);
843
844 return 0;
845}
846
847static int tw9910_s_mbus_config(struct v4l2_subdev *sd,
848 const struct v4l2_mbus_config *cfg)
849{
850 struct i2c_client *client = v4l2_get_subdevdata(sd);
851 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
852 u8 val = VSSL_VVALID | HSSL_DVALID;
853 unsigned long flags = soc_camera_apply_board_flags(icl, cfg);
854
855 /*
856 * set OUTCTR1
857 *
858 * We use VVALID and DVALID signals to control VSYNC and HSYNC
859 * outputs, in this mode their polarity is inverted.
860 */
861 if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
862 val |= HSP_HI;
863
864 if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
865 val |= VSP_HI;
866
867 return i2c_smbus_write_byte_data(client, OUTCTR1, val);
868}
869
901static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = { 870static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
902 .s_stream = tw9910_s_stream, 871 .s_stream = tw9910_s_stream,
903 .g_mbus_fmt = tw9910_g_fmt, 872 .g_mbus_fmt = tw9910_g_fmt,
@@ -905,8 +874,9 @@ static struct v4l2_subdev_video_ops tw9910_subdev_video_ops = {
905 .try_mbus_fmt = tw9910_try_fmt, 874 .try_mbus_fmt = tw9910_try_fmt,
906 .cropcap = tw9910_cropcap, 875 .cropcap = tw9910_cropcap,
907 .g_crop = tw9910_g_crop, 876 .g_crop = tw9910_g_crop,
908 .s_crop = tw9910_s_crop,
909 .enum_mbus_fmt = tw9910_enum_fmt, 877 .enum_mbus_fmt = tw9910_enum_fmt,
878 .g_mbus_config = tw9910_g_mbus_config,
879 .s_mbus_config = tw9910_s_mbus_config,
910}; 880};
911 881
912static struct v4l2_subdev_ops tw9910_subdev_ops = { 882static struct v4l2_subdev_ops tw9910_subdev_ops = {
@@ -922,23 +892,18 @@ static int tw9910_probe(struct i2c_client *client,
922 const struct i2c_device_id *did) 892 const struct i2c_device_id *did)
923 893
924{ 894{
925 struct tw9910_priv *priv; 895 struct tw9910_priv *priv;
926 struct tw9910_video_info *info; 896 struct tw9910_video_info *info;
927 struct soc_camera_device *icd = client->dev.platform_data; 897 struct i2c_adapter *adapter =
928 struct i2c_adapter *adapter =
929 to_i2c_adapter(client->dev.parent); 898 to_i2c_adapter(client->dev.parent);
930 struct soc_camera_link *icl; 899 struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
931 int ret; 900 int ret;
932 901
933 if (!icd) { 902 if (!icl || !icl->priv) {
934 dev_err(&client->dev, "TW9910: missing soc-camera data!\n"); 903 dev_err(&client->dev, "TW9910: missing platform data!\n");
935 return -EINVAL; 904 return -EINVAL;
936 } 905 }
937 906
938 icl = to_soc_camera_link(icd);
939 if (!icl || !icl->priv)
940 return -EINVAL;
941
942 info = icl->priv; 907 info = icl->priv;
943 908
944 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { 909 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
@@ -956,14 +921,9 @@ static int tw9910_probe(struct i2c_client *client,
956 921
957 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops); 922 v4l2_i2c_subdev_init(&priv->subdev, client, &tw9910_subdev_ops);
958 923
959 icd->ops = &tw9910_ops; 924 ret = tw9910_video_probe(client);
960 icd->iface = icl->bus_id; 925 if (ret)
961
962 ret = tw9910_video_probe(icd, client);
963 if (ret) {
964 icd->ops = NULL;
965 kfree(priv); 926 kfree(priv);
966 }
967 927
968 return ret; 928 return ret;
969} 929}
@@ -971,9 +931,7 @@ static int tw9910_probe(struct i2c_client *client,
971static int tw9910_remove(struct i2c_client *client) 931static int tw9910_remove(struct i2c_client *client)
972{ 932{
973 struct tw9910_priv *priv = to_tw9910(client); 933 struct tw9910_priv *priv = to_tw9910(client);
974 struct soc_camera_device *icd = client->dev.platform_data;
975 934
976 icd->ops = NULL;
977 kfree(priv); 935 kfree(priv);
978 return 0; 936 return 0;
979} 937}
diff --git a/drivers/media/video/v4l2-compat-ioctl32.c b/drivers/media/video/v4l2-compat-ioctl32.c
index 61979b70f38..c68531b8827 100644
--- a/drivers/media/video/v4l2-compat-ioctl32.c
+++ b/drivers/media/video/v4l2-compat-ioctl32.c
@@ -159,11 +159,25 @@ struct v4l2_format32 {
159 } fmt; 159 } fmt;
160}; 160};
161 161
162static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) 162/**
163 * struct v4l2_create_buffers32 - VIDIOC_CREATE_BUFS32 argument
164 * @index: on return, index of the first created buffer
165 * @count: entry: number of requested buffers,
166 * return: number of created buffers
167 * @memory: buffer memory type
168 * @format: frame format, for which buffers are requested
169 * @reserved: future extensions
170 */
171struct v4l2_create_buffers32 {
172 __u32 index;
173 __u32 count;
174 enum v4l2_memory memory;
175 struct v4l2_format32 format;
176 __u32 reserved[8];
177};
178
179static int __get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
163{ 180{
164 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
165 get_user(kp->type, &up->type))
166 return -EFAULT;
167 switch (kp->type) { 181 switch (kp->type) {
168 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 182 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
169 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 183 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -192,11 +206,24 @@ static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
192 } 206 }
193} 207}
194 208
195static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up) 209static int get_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
210{
211 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_format32)) ||
212 get_user(kp->type, &up->type))
213 return -EFAULT;
214 return __get_v4l2_format32(kp, up);
215}
216
217static int get_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
218{
219 if (!access_ok(VERIFY_READ, up, sizeof(struct v4l2_create_buffers32)) ||
220 copy_from_user(kp, up, offsetof(struct v4l2_create_buffers32, format.fmt)))
221 return -EFAULT;
222 return __get_v4l2_format32(&kp->format, &up->format);
223}
224
225static int __put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
196{ 226{
197 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
198 put_user(kp->type, &up->type))
199 return -EFAULT;
200 switch (kp->type) { 227 switch (kp->type) {
201 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 228 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
202 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 229 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
@@ -225,6 +252,22 @@ static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user
225 } 252 }
226} 253}
227 254
255static int put_v4l2_format32(struct v4l2_format *kp, struct v4l2_format32 __user *up)
256{
257 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_format32)) ||
258 put_user(kp->type, &up->type))
259 return -EFAULT;
260 return __put_v4l2_format32(kp, up);
261}
262
263static int put_v4l2_create32(struct v4l2_create_buffers *kp, struct v4l2_create_buffers32 __user *up)
264{
265 if (!access_ok(VERIFY_WRITE, up, sizeof(struct v4l2_create_buffers32)) ||
266 copy_to_user(up, kp, offsetof(struct v4l2_create_buffers32, format.fmt)))
267 return -EFAULT;
268 return __put_v4l2_format32(&kp->format, &up->format);
269}
270
228struct v4l2_standard32 { 271struct v4l2_standard32 {
229 __u32 index; 272 __u32 index;
230 __u32 id[2]; /* __u64 would get the alignment wrong */ 273 __u32 id[2]; /* __u64 would get the alignment wrong */
@@ -702,6 +745,8 @@ static int put_v4l2_event32(struct v4l2_event *kp, struct v4l2_event32 __user *u
702#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32) 745#define VIDIOC_S_EXT_CTRLS32 _IOWR('V', 72, struct v4l2_ext_controls32)
703#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32) 746#define VIDIOC_TRY_EXT_CTRLS32 _IOWR('V', 73, struct v4l2_ext_controls32)
704#define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32) 747#define VIDIOC_DQEVENT32 _IOR ('V', 89, struct v4l2_event32)
748#define VIDIOC_CREATE_BUFS32 _IOWR('V', 92, struct v4l2_create_buffers32)
749#define VIDIOC_PREPARE_BUF32 _IOWR('V', 93, struct v4l2_buffer32)
705 750
706#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32) 751#define VIDIOC_OVERLAY32 _IOW ('V', 14, s32)
707#define VIDIOC_STREAMON32 _IOW ('V', 18, s32) 752#define VIDIOC_STREAMON32 _IOW ('V', 18, s32)
@@ -721,6 +766,7 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
721 struct v4l2_standard v2s; 766 struct v4l2_standard v2s;
722 struct v4l2_ext_controls v2ecs; 767 struct v4l2_ext_controls v2ecs;
723 struct v4l2_event v2ev; 768 struct v4l2_event v2ev;
769 struct v4l2_create_buffers v2crt;
724 unsigned long vx; 770 unsigned long vx;
725 int vi; 771 int vi;
726 } karg; 772 } karg;
@@ -751,6 +797,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
751 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break; 797 case VIDIOC_S_INPUT32: cmd = VIDIOC_S_INPUT; break;
752 case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break; 798 case VIDIOC_G_OUTPUT32: cmd = VIDIOC_G_OUTPUT; break;
753 case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break; 799 case VIDIOC_S_OUTPUT32: cmd = VIDIOC_S_OUTPUT; break;
800 case VIDIOC_CREATE_BUFS32: cmd = VIDIOC_CREATE_BUFS; break;
801 case VIDIOC_PREPARE_BUF32: cmd = VIDIOC_PREPARE_BUF; break;
754 } 802 }
755 803
756 switch (cmd) { 804 switch (cmd) {
@@ -775,6 +823,12 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
775 compatible_arg = 0; 823 compatible_arg = 0;
776 break; 824 break;
777 825
826 case VIDIOC_CREATE_BUFS:
827 err = get_v4l2_create32(&karg.v2crt, up);
828 compatible_arg = 0;
829 break;
830
831 case VIDIOC_PREPARE_BUF:
778 case VIDIOC_QUERYBUF: 832 case VIDIOC_QUERYBUF:
779 case VIDIOC_QBUF: 833 case VIDIOC_QBUF:
780 case VIDIOC_DQBUF: 834 case VIDIOC_DQBUF:
@@ -860,6 +914,10 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
860 err = put_v4l2_format32(&karg.v2f, up); 914 err = put_v4l2_format32(&karg.v2f, up);
861 break; 915 break;
862 916
917 case VIDIOC_CREATE_BUFS:
918 err = put_v4l2_create32(&karg.v2crt, up);
919 break;
920
863 case VIDIOC_QUERYBUF: 921 case VIDIOC_QUERYBUF:
864 case VIDIOC_QBUF: 922 case VIDIOC_QBUF:
865 case VIDIOC_DQBUF: 923 case VIDIOC_DQBUF:
@@ -959,6 +1017,8 @@ long v4l2_compat_ioctl32(struct file *file, unsigned int cmd, unsigned long arg)
959 case VIDIOC_DQEVENT32: 1017 case VIDIOC_DQEVENT32:
960 case VIDIOC_SUBSCRIBE_EVENT: 1018 case VIDIOC_SUBSCRIBE_EVENT:
961 case VIDIOC_UNSUBSCRIBE_EVENT: 1019 case VIDIOC_UNSUBSCRIBE_EVENT:
1020 case VIDIOC_CREATE_BUFS32:
1021 case VIDIOC_PREPARE_BUF32:
962 ret = do_video_ioctl(file, cmd, arg); 1022 ret = do_video_ioctl(file, cmd, arg);
963 break; 1023 break;
964 1024
diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c
index fc8666ae408..5552f813757 100644
--- a/drivers/media/video/v4l2-ctrls.c
+++ b/drivers/media/video/v4l2-ctrls.c
@@ -210,6 +210,7 @@ const char * const *v4l2_ctrl_get_menu(u32 id)
210 "Disabled", 210 "Disabled",
211 "50 Hz", 211 "50 Hz",
212 "60 Hz", 212 "60 Hz",
213 "Auto",
213 NULL 214 NULL
214 }; 215 };
215 static const char * const camera_exposure_auto[] = { 216 static const char * const camera_exposure_auto[] = {
diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c
index e6a2c3b302d..9fc0ae8a526 100644
--- a/drivers/media/video/v4l2-device.c
+++ b/drivers/media/video/v4l2-device.c
@@ -21,6 +21,7 @@
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/ioctl.h> 22#include <linux/ioctl.h>
23#include <linux/i2c.h> 23#include <linux/i2c.h>
24#include <linux/slab.h>
24#if defined(CONFIG_SPI) 25#if defined(CONFIG_SPI)
25#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
26#endif 27#endif
@@ -193,6 +194,13 @@ int v4l2_device_register_subdev(struct v4l2_device *v4l2_dev,
193} 194}
194EXPORT_SYMBOL_GPL(v4l2_device_register_subdev); 195EXPORT_SYMBOL_GPL(v4l2_device_register_subdev);
195 196
197static void v4l2_device_release_subdev_node(struct video_device *vdev)
198{
199 struct v4l2_subdev *sd = video_get_drvdata(vdev);
200 sd->devnode = NULL;
201 kfree(vdev);
202}
203
196int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev) 204int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
197{ 205{
198 struct video_device *vdev; 206 struct video_device *vdev;
@@ -206,22 +214,40 @@ int v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev)
206 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE)) 214 if (!(sd->flags & V4L2_SUBDEV_FL_HAS_DEVNODE))
207 continue; 215 continue;
208 216
209 vdev = &sd->devnode; 217 vdev = kzalloc(sizeof(*vdev), GFP_KERNEL);
218 if (!vdev) {
219 err = -ENOMEM;
220 goto clean_up;
221 }
222
223 video_set_drvdata(vdev, sd);
210 strlcpy(vdev->name, sd->name, sizeof(vdev->name)); 224 strlcpy(vdev->name, sd->name, sizeof(vdev->name));
211 vdev->v4l2_dev = v4l2_dev; 225 vdev->v4l2_dev = v4l2_dev;
212 vdev->fops = &v4l2_subdev_fops; 226 vdev->fops = &v4l2_subdev_fops;
213 vdev->release = video_device_release_empty; 227 vdev->release = v4l2_device_release_subdev_node;
214 vdev->ctrl_handler = sd->ctrl_handler; 228 vdev->ctrl_handler = sd->ctrl_handler;
215 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1, 229 err = __video_register_device(vdev, VFL_TYPE_SUBDEV, -1, 1,
216 sd->owner); 230 sd->owner);
217 if (err < 0) 231 if (err < 0) {
218 return err; 232 kfree(vdev);
233 goto clean_up;
234 }
219#if defined(CONFIG_MEDIA_CONTROLLER) 235#if defined(CONFIG_MEDIA_CONTROLLER)
220 sd->entity.v4l.major = VIDEO_MAJOR; 236 sd->entity.v4l.major = VIDEO_MAJOR;
221 sd->entity.v4l.minor = vdev->minor; 237 sd->entity.v4l.minor = vdev->minor;
222#endif 238#endif
239 sd->devnode = vdev;
223 } 240 }
224 return 0; 241 return 0;
242
243clean_up:
244 list_for_each_entry(sd, &v4l2_dev->subdevs, list) {
245 if (!sd->devnode)
246 break;
247 video_unregister_device(sd->devnode);
248 }
249
250 return err;
225} 251}
226EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes); 252EXPORT_SYMBOL_GPL(v4l2_device_register_subdev_nodes);
227 253
@@ -247,7 +273,7 @@ void v4l2_device_unregister_subdev(struct v4l2_subdev *sd)
247 if (v4l2_dev->mdev) 273 if (v4l2_dev->mdev)
248 media_device_unregister_entity(&sd->entity); 274 media_device_unregister_entity(&sd->entity);
249#endif 275#endif
250 video_unregister_device(&sd->devnode); 276 video_unregister_device(sd->devnode);
251 module_put(sd->owner); 277 module_put(sd->owner);
252} 278}
253EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev); 279EXPORT_SYMBOL_GPL(v4l2_device_unregister_subdev);
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c
index 24fd4332215..e1da8fc9dd2 100644
--- a/drivers/media/video/v4l2-ioctl.c
+++ b/drivers/media/video/v4l2-ioctl.c
@@ -273,6 +273,8 @@ static const char *v4l2_ioctls[] = {
273 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT", 273 [_IOC_NR(VIDIOC_DQEVENT)] = "VIDIOC_DQEVENT",
274 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT", 274 [_IOC_NR(VIDIOC_SUBSCRIBE_EVENT)] = "VIDIOC_SUBSCRIBE_EVENT",
275 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT", 275 [_IOC_NR(VIDIOC_UNSUBSCRIBE_EVENT)] = "VIDIOC_UNSUBSCRIBE_EVENT",
276 [_IOC_NR(VIDIOC_CREATE_BUFS)] = "VIDIOC_CREATE_BUFS",
277 [_IOC_NR(VIDIOC_PREPARE_BUF)] = "VIDIOC_PREPARE_BUF",
276}; 278};
277#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls) 279#define V4L2_IOCTLS ARRAY_SIZE(v4l2_ioctls)
278 280
@@ -2104,6 +2106,40 @@ static long __video_do_ioctl(struct file *file,
2104 dbgarg(cmd, "type=0x%8.8x", sub->type); 2106 dbgarg(cmd, "type=0x%8.8x", sub->type);
2105 break; 2107 break;
2106 } 2108 }
2109 case VIDIOC_CREATE_BUFS:
2110 {
2111 struct v4l2_create_buffers *create = arg;
2112
2113 if (!ops->vidioc_create_bufs)
2114 break;
2115 if (ret_prio) {
2116 ret = ret_prio;
2117 break;
2118 }
2119 ret = check_fmt(ops, create->format.type);
2120 if (ret)
2121 break;
2122
2123 ret = ops->vidioc_create_bufs(file, fh, create);
2124
2125 dbgarg(cmd, "count=%d @ %d\n", create->count, create->index);
2126 break;
2127 }
2128 case VIDIOC_PREPARE_BUF:
2129 {
2130 struct v4l2_buffer *b = arg;
2131
2132 if (!ops->vidioc_prepare_buf)
2133 break;
2134 ret = check_fmt(ops, b->type);
2135 if (ret)
2136 break;
2137
2138 ret = ops->vidioc_prepare_buf(file, fh, b);
2139
2140 dbgarg(cmd, "index=%d", b->index);
2141 break;
2142 }
2107 default: 2143 default:
2108 if (!ops->vidioc_default) 2144 if (!ops->vidioc_default)
2109 break; 2145 break;
diff --git a/drivers/media/video/videobuf2-core.c b/drivers/media/video/videobuf2-core.c
index 3f5c7a38e6e..979e544388c 100644
--- a/drivers/media/video/videobuf2-core.c
+++ b/drivers/media/video/videobuf2-core.c
@@ -38,7 +38,8 @@ module_param(debug, int, 0644);
38 (((q)->ops->op) ? ((q)->ops->op(args)) : 0) 38 (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
39 39
40#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \ 40#define V4L2_BUFFER_STATE_FLAGS (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
41 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR) 41 V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR | \
42 V4L2_BUF_FLAG_PREPARED)
42 43
43/** 44/**
44 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer 45 * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
@@ -109,13 +110,22 @@ static void __vb2_buf_userptr_put(struct vb2_buffer *vb)
109 * __setup_offsets() - setup unique offsets ("cookies") for every plane in 110 * __setup_offsets() - setup unique offsets ("cookies") for every plane in
110 * every buffer on the queue 111 * every buffer on the queue
111 */ 112 */
112static void __setup_offsets(struct vb2_queue *q) 113static void __setup_offsets(struct vb2_queue *q, unsigned int n)
113{ 114{
114 unsigned int buffer, plane; 115 unsigned int buffer, plane;
115 struct vb2_buffer *vb; 116 struct vb2_buffer *vb;
116 unsigned long off = 0; 117 unsigned long off;
117 118
118 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 119 if (q->num_buffers) {
120 struct v4l2_plane *p;
121 vb = q->bufs[q->num_buffers - 1];
122 p = &vb->v4l2_planes[vb->num_planes - 1];
123 off = PAGE_ALIGN(p->m.mem_offset + p->length);
124 } else {
125 off = 0;
126 }
127
128 for (buffer = q->num_buffers; buffer < q->num_buffers + n; ++buffer) {
119 vb = q->bufs[buffer]; 129 vb = q->bufs[buffer];
120 if (!vb) 130 if (!vb)
121 continue; 131 continue;
@@ -161,7 +171,7 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
161 vb->state = VB2_BUF_STATE_DEQUEUED; 171 vb->state = VB2_BUF_STATE_DEQUEUED;
162 vb->vb2_queue = q; 172 vb->vb2_queue = q;
163 vb->num_planes = num_planes; 173 vb->num_planes = num_planes;
164 vb->v4l2_buf.index = buffer; 174 vb->v4l2_buf.index = q->num_buffers + buffer;
165 vb->v4l2_buf.type = q->type; 175 vb->v4l2_buf.type = q->type;
166 vb->v4l2_buf.memory = memory; 176 vb->v4l2_buf.memory = memory;
167 177
@@ -189,15 +199,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
189 } 199 }
190 } 200 }
191 201
192 q->bufs[buffer] = vb; 202 q->bufs[q->num_buffers + buffer] = vb;
193 } 203 }
194 204
195 q->num_buffers = buffer; 205 __setup_offsets(q, buffer);
196
197 __setup_offsets(q);
198 206
199 dprintk(1, "Allocated %d buffers, %d plane(s) each\n", 207 dprintk(1, "Allocated %d buffers, %d plane(s) each\n",
200 q->num_buffers, num_planes); 208 buffer, num_planes);
201 209
202 return buffer; 210 return buffer;
203} 211}
@@ -205,12 +213,13 @@ static int __vb2_queue_alloc(struct vb2_queue *q, enum v4l2_memory memory,
205/** 213/**
206 * __vb2_free_mem() - release all video buffer memory for a given queue 214 * __vb2_free_mem() - release all video buffer memory for a given queue
207 */ 215 */
208static void __vb2_free_mem(struct vb2_queue *q) 216static void __vb2_free_mem(struct vb2_queue *q, unsigned int buffers)
209{ 217{
210 unsigned int buffer; 218 unsigned int buffer;
211 struct vb2_buffer *vb; 219 struct vb2_buffer *vb;
212 220
213 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 221 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
222 ++buffer) {
214 vb = q->bufs[buffer]; 223 vb = q->bufs[buffer];
215 if (!vb) 224 if (!vb)
216 continue; 225 continue;
@@ -224,17 +233,18 @@ static void __vb2_free_mem(struct vb2_queue *q)
224} 233}
225 234
226/** 235/**
227 * __vb2_queue_free() - free the queue - video memory and related information 236 * __vb2_queue_free() - free buffers at the end of the queue - video memory and
228 * and return the queue to an uninitialized state. Might be called even if the 237 * related information, if no buffers are left return the queue to an
229 * queue has already been freed. 238 * uninitialized state. Might be called even if the queue has already been freed.
230 */ 239 */
231static void __vb2_queue_free(struct vb2_queue *q) 240static void __vb2_queue_free(struct vb2_queue *q, unsigned int buffers)
232{ 241{
233 unsigned int buffer; 242 unsigned int buffer;
234 243
235 /* Call driver-provided cleanup function for each buffer, if provided */ 244 /* Call driver-provided cleanup function for each buffer, if provided */
236 if (q->ops->buf_cleanup) { 245 if (q->ops->buf_cleanup) {
237 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 246 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
247 ++buffer) {
238 if (NULL == q->bufs[buffer]) 248 if (NULL == q->bufs[buffer])
239 continue; 249 continue;
240 q->ops->buf_cleanup(q->bufs[buffer]); 250 q->ops->buf_cleanup(q->bufs[buffer]);
@@ -242,23 +252,25 @@ static void __vb2_queue_free(struct vb2_queue *q)
242 } 252 }
243 253
244 /* Release video buffer memory */ 254 /* Release video buffer memory */
245 __vb2_free_mem(q); 255 __vb2_free_mem(q, buffers);
246 256
247 /* Free videobuf buffers */ 257 /* Free videobuf buffers */
248 for (buffer = 0; buffer < q->num_buffers; ++buffer) { 258 for (buffer = q->num_buffers - buffers; buffer < q->num_buffers;
259 ++buffer) {
249 kfree(q->bufs[buffer]); 260 kfree(q->bufs[buffer]);
250 q->bufs[buffer] = NULL; 261 q->bufs[buffer] = NULL;
251 } 262 }
252 263
253 q->num_buffers = 0; 264 q->num_buffers -= buffers;
254 q->memory = 0; 265 if (!q->num_buffers)
266 q->memory = 0;
255} 267}
256 268
257/** 269/**
258 * __verify_planes_array() - verify that the planes array passed in struct 270 * __verify_planes_array() - verify that the planes array passed in struct
259 * v4l2_buffer from userspace can be safely used 271 * v4l2_buffer from userspace can be safely used
260 */ 272 */
261static int __verify_planes_array(struct vb2_buffer *vb, struct v4l2_buffer *b) 273static int __verify_planes_array(struct vb2_buffer *vb, const struct v4l2_buffer *b)
262{ 274{
263 /* Is memory for copying plane information present? */ 275 /* Is memory for copying plane information present? */
264 if (NULL == b->m.planes) { 276 if (NULL == b->m.planes) {
@@ -318,7 +330,7 @@ static bool __buffers_in_use(struct vb2_queue *q)
318static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) 330static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
319{ 331{
320 struct vb2_queue *q = vb->vb2_queue; 332 struct vb2_queue *q = vb->vb2_queue;
321 int ret = 0; 333 int ret;
322 334
323 /* Copy back data such as timestamp, flags, input, etc. */ 335 /* Copy back data such as timestamp, flags, input, etc. */
324 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m)); 336 memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
@@ -365,6 +377,9 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
365 case VB2_BUF_STATE_DONE: 377 case VB2_BUF_STATE_DONE:
366 b->flags |= V4L2_BUF_FLAG_DONE; 378 b->flags |= V4L2_BUF_FLAG_DONE;
367 break; 379 break;
380 case VB2_BUF_STATE_PREPARED:
381 b->flags |= V4L2_BUF_FLAG_PREPARED;
382 break;
368 case VB2_BUF_STATE_DEQUEUED: 383 case VB2_BUF_STATE_DEQUEUED:
369 /* nothing */ 384 /* nothing */
370 break; 385 break;
@@ -373,7 +388,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
373 if (__buffer_in_use(q, vb)) 388 if (__buffer_in_use(q, vb))
374 b->flags |= V4L2_BUF_FLAG_MAPPED; 389 b->flags |= V4L2_BUF_FLAG_MAPPED;
375 390
376 return ret; 391 return 0;
377} 392}
378 393
379/** 394/**
@@ -459,7 +474,7 @@ static int __verify_mmap_ops(struct vb2_queue *q)
459 */ 474 */
460int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) 475int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
461{ 476{
462 unsigned int num_buffers, num_planes; 477 unsigned int num_buffers, allocated_buffers, num_planes = 0;
463 int ret = 0; 478 int ret = 0;
464 479
465 if (q->fileio) { 480 if (q->fileio) {
@@ -507,7 +522,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
507 return -EBUSY; 522 return -EBUSY;
508 } 523 }
509 524
510 __vb2_queue_free(q); 525 __vb2_queue_free(q, q->num_buffers);
511 526
512 /* 527 /*
513 * In case of REQBUFS(0) return immediately without calling 528 * In case of REQBUFS(0) return immediately without calling
@@ -529,7 +544,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
529 * Ask the driver how many buffers and planes per buffer it requires. 544 * Ask the driver how many buffers and planes per buffer it requires.
530 * Driver also sets the size and allocator context for each plane. 545 * Driver also sets the size and allocator context for each plane.
531 */ 546 */
532 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes, 547 ret = call_qop(q, queue_setup, q, NULL, &num_buffers, &num_planes,
533 q->plane_sizes, q->alloc_ctx); 548 q->plane_sizes, q->alloc_ctx);
534 if (ret) 549 if (ret)
535 return ret; 550 return ret;
@@ -541,44 +556,168 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
541 return -ENOMEM; 556 return -ENOMEM;
542 } 557 }
543 558
559 allocated_buffers = ret;
560
544 /* 561 /*
545 * Check if driver can handle the allocated number of buffers. 562 * Check if driver can handle the allocated number of buffers.
546 */ 563 */
547 if (ret < num_buffers) { 564 if (allocated_buffers < num_buffers) {
548 unsigned int orig_num_buffers; 565 num_buffers = allocated_buffers;
549 566
550 orig_num_buffers = num_buffers = ret; 567 ret = call_qop(q, queue_setup, q, NULL, &num_buffers,
551 ret = call_qop(q, queue_setup, q, &num_buffers, &num_planes, 568 &num_planes, q->plane_sizes, q->alloc_ctx);
552 q->plane_sizes, q->alloc_ctx);
553 if (ret)
554 goto free_mem;
555 569
556 if (orig_num_buffers < num_buffers) { 570 if (!ret && allocated_buffers < num_buffers)
557 ret = -ENOMEM; 571 ret = -ENOMEM;
558 goto free_mem;
559 }
560 572
561 /* 573 /*
562 * Ok, driver accepted smaller number of buffers. 574 * Either the driver has accepted a smaller number of buffers,
575 * or .queue_setup() returned an error
563 */ 576 */
564 ret = num_buffers; 577 }
578
579 q->num_buffers = allocated_buffers;
580
581 if (ret < 0) {
582 __vb2_queue_free(q, allocated_buffers);
583 return ret;
565 } 584 }
566 585
567 /* 586 /*
568 * Return the number of successfully allocated buffers 587 * Return the number of successfully allocated buffers
569 * to the userspace. 588 * to the userspace.
570 */ 589 */
571 req->count = ret; 590 req->count = allocated_buffers;
572 591
573 return 0; 592 return 0;
574
575free_mem:
576 __vb2_queue_free(q);
577 return ret;
578} 593}
579EXPORT_SYMBOL_GPL(vb2_reqbufs); 594EXPORT_SYMBOL_GPL(vb2_reqbufs);
580 595
581/** 596/**
597 * vb2_create_bufs() - Allocate buffers and any required auxiliary structs
598 * @q: videobuf2 queue
599 * @create: creation parameters, passed from userspace to vidioc_create_bufs
600 * handler in driver
601 *
602 * Should be called from vidioc_create_bufs ioctl handler of a driver.
603 * This function:
604 * 1) verifies parameter sanity
605 * 2) calls the .queue_setup() queue operation
606 * 3) performs any necessary memory allocations
607 *
608 * The return values from this function are intended to be directly returned
609 * from vidioc_create_bufs handler in driver.
610 */
611int vb2_create_bufs(struct vb2_queue *q, struct v4l2_create_buffers *create)
612{
613 unsigned int num_planes = 0, num_buffers, allocated_buffers;
614 int ret = 0;
615
616 if (q->fileio) {
617 dprintk(1, "%s(): file io in progress\n", __func__);
618 return -EBUSY;
619 }
620
621 if (create->memory != V4L2_MEMORY_MMAP
622 && create->memory != V4L2_MEMORY_USERPTR) {
623 dprintk(1, "%s(): unsupported memory type\n", __func__);
624 return -EINVAL;
625 }
626
627 if (create->format.type != q->type) {
628 dprintk(1, "%s(): requested type is incorrect\n", __func__);
629 return -EINVAL;
630 }
631
632 /*
633 * Make sure all the required memory ops for given memory type
634 * are available.
635 */
636 if (create->memory == V4L2_MEMORY_MMAP && __verify_mmap_ops(q)) {
637 dprintk(1, "%s(): MMAP for current setup unsupported\n", __func__);
638 return -EINVAL;
639 }
640
641 if (create->memory == V4L2_MEMORY_USERPTR && __verify_userptr_ops(q)) {
642 dprintk(1, "%s(): USERPTR for current setup unsupported\n", __func__);
643 return -EINVAL;
644 }
645
646 if (q->num_buffers == VIDEO_MAX_FRAME) {
647 dprintk(1, "%s(): maximum number of buffers already allocated\n",
648 __func__);
649 return -ENOBUFS;
650 }
651
652 create->index = q->num_buffers;
653
654 if (!q->num_buffers) {
655 memset(q->plane_sizes, 0, sizeof(q->plane_sizes));
656 memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
657 q->memory = create->memory;
658 }
659
660 num_buffers = min(create->count, VIDEO_MAX_FRAME - q->num_buffers);
661
662 /*
663 * Ask the driver, whether the requested number of buffers, planes per
664 * buffer and their sizes are acceptable
665 */
666 ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
667 &num_planes, q->plane_sizes, q->alloc_ctx);
668 if (ret)
669 return ret;
670
671 /* Finally, allocate buffers and video memory */
672 ret = __vb2_queue_alloc(q, create->memory, num_buffers,
673 num_planes);
674 if (ret < 0) {
675 dprintk(1, "Memory allocation failed with error: %d\n", ret);
676 return ret;
677 }
678
679 allocated_buffers = ret;
680
681 /*
682 * Check if driver can handle the so far allocated number of buffers.
683 */
684 if (ret < num_buffers) {
685 num_buffers = ret;
686
687 /*
688 * q->num_buffers contains the total number of buffers, that the
689 * queue driver has set up
690 */
691 ret = call_qop(q, queue_setup, q, &create->format, &num_buffers,
692 &num_planes, q->plane_sizes, q->alloc_ctx);
693
694 if (!ret && allocated_buffers < num_buffers)
695 ret = -ENOMEM;
696
697 /*
698 * Either the driver has accepted a smaller number of buffers,
699 * or .queue_setup() returned an error
700 */
701 }
702
703 q->num_buffers += allocated_buffers;
704
705 if (ret < 0) {
706 __vb2_queue_free(q, allocated_buffers);
707 return ret;
708 }
709
710 /*
711 * Return the number of successfully allocated buffers
712 * to the userspace.
713 */
714 create->count = allocated_buffers;
715
716 return 0;
717}
718EXPORT_SYMBOL_GPL(vb2_create_bufs);
719
720/**
582 * vb2_plane_vaddr() - Return a kernel virtual address of a given plane 721 * vb2_plane_vaddr() - Return a kernel virtual address of a given plane
583 * @vb: vb2_buffer to which the plane in question belongs to 722 * @vb: vb2_buffer to which the plane in question belongs to
584 * @plane_no: plane number for which the address is to be returned 723 * @plane_no: plane number for which the address is to be returned
@@ -662,7 +801,7 @@ EXPORT_SYMBOL_GPL(vb2_buffer_done);
662 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in 801 * __fill_vb2_buffer() - fill a vb2_buffer with information provided in
663 * a v4l2_buffer by the userspace 802 * a v4l2_buffer by the userspace
664 */ 803 */
665static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, 804static int __fill_vb2_buffer(struct vb2_buffer *vb, const struct v4l2_buffer *b,
666 struct v4l2_plane *v4l2_planes) 805 struct v4l2_plane *v4l2_planes)
667{ 806{
668 unsigned int plane; 807 unsigned int plane;
@@ -726,7 +865,7 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
726/** 865/**
727 * __qbuf_userptr() - handle qbuf of a USERPTR buffer 866 * __qbuf_userptr() - handle qbuf of a USERPTR buffer
728 */ 867 */
729static int __qbuf_userptr(struct vb2_buffer *vb, struct v4l2_buffer *b) 868static int __qbuf_userptr(struct vb2_buffer *vb, const struct v4l2_buffer *b)
730{ 869{
731 struct v4l2_plane planes[VIDEO_MAX_PLANES]; 870 struct v4l2_plane planes[VIDEO_MAX_PLANES];
732 struct vb2_queue *q = vb->vb2_queue; 871 struct vb2_queue *q = vb->vb2_queue;
@@ -815,7 +954,7 @@ err:
815/** 954/**
816 * __qbuf_mmap() - handle qbuf of an MMAP buffer 955 * __qbuf_mmap() - handle qbuf of an MMAP buffer
817 */ 956 */
818static int __qbuf_mmap(struct vb2_buffer *vb, struct v4l2_buffer *b) 957static int __qbuf_mmap(struct vb2_buffer *vb, const struct v4l2_buffer *b)
819{ 958{
820 return __fill_vb2_buffer(vb, b, vb->v4l2_planes); 959 return __fill_vb2_buffer(vb, b, vb->v4l2_planes);
821} 960}
@@ -832,6 +971,95 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
832 q->ops->buf_queue(vb); 971 q->ops->buf_queue(vb);
833} 972}
834 973
974static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b)
975{
976 struct vb2_queue *q = vb->vb2_queue;
977 int ret;
978
979 switch (q->memory) {
980 case V4L2_MEMORY_MMAP:
981 ret = __qbuf_mmap(vb, b);
982 break;
983 case V4L2_MEMORY_USERPTR:
984 ret = __qbuf_userptr(vb, b);
985 break;
986 default:
987 WARN(1, "Invalid queue type\n");
988 ret = -EINVAL;
989 }
990
991 if (!ret)
992 ret = call_qop(q, buf_prepare, vb);
993 if (ret)
994 dprintk(1, "qbuf: buffer preparation failed: %d\n", ret);
995 else
996 vb->state = VB2_BUF_STATE_PREPARED;
997
998 return ret;
999}
1000
1001/**
1002 * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel
1003 * @q: videobuf2 queue
1004 * @b: buffer structure passed from userspace to vidioc_prepare_buf
1005 * handler in driver
1006 *
1007 * Should be called from vidioc_prepare_buf ioctl handler of a driver.
1008 * This function:
1009 * 1) verifies the passed buffer,
1010 * 2) calls buf_prepare callback in the driver (if provided), in which
1011 * driver-specific buffer initialization can be performed,
1012 *
1013 * The return values from this function are intended to be directly returned
1014 * from vidioc_prepare_buf handler in driver.
1015 */
1016int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b)
1017{
1018 struct vb2_buffer *vb;
1019 int ret;
1020
1021 if (q->fileio) {
1022 dprintk(1, "%s(): file io in progress\n", __func__);
1023 return -EBUSY;
1024 }
1025
1026 if (b->type != q->type) {
1027 dprintk(1, "%s(): invalid buffer type\n", __func__);
1028 return -EINVAL;
1029 }
1030
1031 if (b->index >= q->num_buffers) {
1032 dprintk(1, "%s(): buffer index out of range\n", __func__);
1033 return -EINVAL;
1034 }
1035
1036 vb = q->bufs[b->index];
1037 if (NULL == vb) {
1038 /* Should never happen */
1039 dprintk(1, "%s(): buffer is NULL\n", __func__);
1040 return -EINVAL;
1041 }
1042
1043 if (b->memory != q->memory) {
1044 dprintk(1, "%s(): invalid memory type\n", __func__);
1045 return -EINVAL;
1046 }
1047
1048 if (vb->state != VB2_BUF_STATE_DEQUEUED) {
1049 dprintk(1, "%s(): invalid buffer state %d\n", __func__, vb->state);
1050 return -EINVAL;
1051 }
1052
1053 ret = __buf_prepare(vb, b);
1054 if (ret < 0)
1055 return ret;
1056
1057 __fill_v4l2_buffer(vb, b);
1058
1059 return 0;
1060}
1061EXPORT_SYMBOL_GPL(vb2_prepare_buf);
1062
835/** 1063/**
836 * vb2_qbuf() - Queue a buffer from userspace 1064 * vb2_qbuf() - Queue a buffer from userspace
837 * @q: videobuf2 queue 1065 * @q: videobuf2 queue
@@ -841,8 +1069,8 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
841 * Should be called from vidioc_qbuf ioctl handler of a driver. 1069 * Should be called from vidioc_qbuf ioctl handler of a driver.
842 * This function: 1070 * This function:
843 * 1) verifies the passed buffer, 1071 * 1) verifies the passed buffer,
844 * 2) calls buf_prepare callback in the driver (if provided), in which 1072 * 2) if necessary, calls buf_prepare callback in the driver (if provided), in
845 * driver-specific buffer initialization can be performed, 1073 * which driver-specific buffer initialization can be performed,
846 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue 1074 * 3) if streaming is on, queues the buffer in driver by the means of buf_queue
847 * callback for processing. 1075 * callback for processing.
848 * 1076 *
@@ -852,7 +1080,7 @@ static void __enqueue_in_driver(struct vb2_buffer *vb)
852int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b) 1080int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
853{ 1081{
854 struct vb2_buffer *vb; 1082 struct vb2_buffer *vb;
855 int ret = 0; 1083 int ret;
856 1084
857 if (q->fileio) { 1085 if (q->fileio) {
858 dprintk(1, "qbuf: file io in progress\n"); 1086 dprintk(1, "qbuf: file io in progress\n");
@@ -881,29 +1109,18 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
881 return -EINVAL; 1109 return -EINVAL;
882 } 1110 }
883 1111
884 if (vb->state != VB2_BUF_STATE_DEQUEUED) { 1112 switch (vb->state) {
1113 case VB2_BUF_STATE_DEQUEUED:
1114 ret = __buf_prepare(vb, b);
1115 if (ret)
1116 return ret;
1117 case VB2_BUF_STATE_PREPARED:
1118 break;
1119 default:
885 dprintk(1, "qbuf: buffer already in use\n"); 1120 dprintk(1, "qbuf: buffer already in use\n");
886 return -EINVAL; 1121 return -EINVAL;
887 } 1122 }
888 1123
889 if (q->memory == V4L2_MEMORY_MMAP)
890 ret = __qbuf_mmap(vb, b);
891 else if (q->memory == V4L2_MEMORY_USERPTR)
892 ret = __qbuf_userptr(vb, b);
893 else {
894 WARN(1, "Invalid queue type\n");
895 return -EINVAL;
896 }
897
898 if (ret)
899 return ret;
900
901 ret = call_qop(q, buf_prepare, vb);
902 if (ret) {
903 dprintk(1, "qbuf: buffer preparation failed\n");
904 return ret;
905 }
906
907 /* 1124 /*
908 * Add to the queued buffers list, a buffer will stay on it until 1125 * Add to the queued buffers list, a buffer will stay on it until
909 * dequeued in dqbuf. 1126 * dequeued in dqbuf.
@@ -918,6 +1135,9 @@ int vb2_qbuf(struct vb2_queue *q, struct v4l2_buffer *b)
918 if (q->streaming) 1135 if (q->streaming)
919 __enqueue_in_driver(vb); 1136 __enqueue_in_driver(vb);
920 1137
1138 /* Fill buffer information for the userspace */
1139 __fill_v4l2_buffer(vb, b);
1140
921 dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index); 1141 dprintk(1, "qbuf of buffer %d succeeded\n", vb->v4l2_buf.index);
922 return 0; 1142 return 0;
923} 1143}
@@ -1347,6 +1567,37 @@ int vb2_mmap(struct vb2_queue *q, struct vm_area_struct *vma)
1347} 1567}
1348EXPORT_SYMBOL_GPL(vb2_mmap); 1568EXPORT_SYMBOL_GPL(vb2_mmap);
1349 1569
1570#ifndef CONFIG_MMU
1571unsigned long vb2_get_unmapped_area(struct vb2_queue *q,
1572 unsigned long addr,
1573 unsigned long len,
1574 unsigned long pgoff,
1575 unsigned long flags)
1576{
1577 unsigned long off = pgoff << PAGE_SHIFT;
1578 struct vb2_buffer *vb;
1579 unsigned int buffer, plane;
1580 int ret;
1581
1582 if (q->memory != V4L2_MEMORY_MMAP) {
1583 dprintk(1, "Queue is not currently set up for mmap\n");
1584 return -EINVAL;
1585 }
1586
1587 /*
1588 * Find the plane corresponding to the offset passed by userspace.
1589 */
1590 ret = __find_plane_by_offset(q, off, &buffer, &plane);
1591 if (ret)
1592 return ret;
1593
1594 vb = q->bufs[buffer];
1595
1596 return (unsigned long)vb2_plane_vaddr(vb, plane);
1597}
1598EXPORT_SYMBOL_GPL(vb2_get_unmapped_area);
1599#endif
1600
1350static int __vb2_init_fileio(struct vb2_queue *q, int read); 1601static int __vb2_init_fileio(struct vb2_queue *q, int read);
1351static int __vb2_cleanup_fileio(struct vb2_queue *q); 1602static int __vb2_cleanup_fileio(struct vb2_queue *q);
1352 1603
@@ -1464,7 +1715,7 @@ void vb2_queue_release(struct vb2_queue *q)
1464{ 1715{
1465 __vb2_cleanup_fileio(q); 1716 __vb2_cleanup_fileio(q);
1466 __vb2_queue_cancel(q); 1717 __vb2_queue_cancel(q);
1467 __vb2_queue_free(q); 1718 __vb2_queue_free(q, q->num_buffers);
1468} 1719}
1469EXPORT_SYMBOL_GPL(vb2_queue_release); 1720EXPORT_SYMBOL_GPL(vb2_queue_release);
1470 1721
diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c
index 7cf94c09d99..7d754fbcccb 100644
--- a/drivers/media/video/vivi.c
+++ b/drivers/media/video/vivi.c
@@ -650,9 +650,9 @@ static void vivi_stop_generating(struct vivi_dev *dev)
650/* ------------------------------------------------------------------ 650/* ------------------------------------------------------------------
651 Videobuf operations 651 Videobuf operations
652 ------------------------------------------------------------------*/ 652 ------------------------------------------------------------------*/
653static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers, 653static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
654 unsigned int *nplanes, unsigned int sizes[], 654 unsigned int *nbuffers, unsigned int *nplanes,
655 void *alloc_ctxs[]) 655 unsigned int sizes[], void *alloc_ctxs[])
656{ 656{
657 struct vivi_dev *dev = vb2_get_drv_priv(vq); 657 struct vivi_dev *dev = vb2_get_drv_priv(vq);
658 unsigned long size; 658 unsigned long size;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index d132c27dfb3..25cdff36a78 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -30,12 +30,6 @@ source "drivers/staging/et131x/Kconfig"
30 30
31source "drivers/staging/slicoss/Kconfig" 31source "drivers/staging/slicoss/Kconfig"
32 32
33source "drivers/staging/go7007/Kconfig"
34
35source "drivers/staging/cx25821/Kconfig"
36
37source "drivers/staging/cxd2099/Kconfig"
38
39source "drivers/staging/usbip/Kconfig" 33source "drivers/staging/usbip/Kconfig"
40 34
41source "drivers/staging/winbond/Kconfig" 35source "drivers/staging/winbond/Kconfig"
@@ -104,20 +98,12 @@ source "drivers/staging/wlags49_h25/Kconfig"
104 98
105source "drivers/staging/sm7xx/Kconfig" 99source "drivers/staging/sm7xx/Kconfig"
106 100
107source "drivers/staging/dt3155v4l/Kconfig"
108
109source "drivers/staging/crystalhd/Kconfig" 101source "drivers/staging/crystalhd/Kconfig"
110 102
111source "drivers/staging/cxt1e1/Kconfig" 103source "drivers/staging/cxt1e1/Kconfig"
112 104
113source "drivers/staging/xgifb/Kconfig" 105source "drivers/staging/xgifb/Kconfig"
114 106
115source "drivers/staging/lirc/Kconfig"
116
117source "drivers/staging/easycap/Kconfig"
118
119source "drivers/staging/solo6x10/Kconfig"
120
121source "drivers/staging/tidspbridge/Kconfig" 107source "drivers/staging/tidspbridge/Kconfig"
122 108
123source "drivers/staging/quickstart/Kconfig" 109source "drivers/staging/quickstart/Kconfig"
@@ -144,4 +130,6 @@ source "drivers/staging/mei/Kconfig"
144 130
145source "drivers/staging/nvec/Kconfig" 131source "drivers/staging/nvec/Kconfig"
146 132
133source "drivers/staging/media/Kconfig"
134
147endif # STAGING 135endif # STAGING
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 936b7c22e18..a25f3f26c7f 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -4,12 +4,9 @@
4obj-$(CONFIG_STAGING) += staging.o 4obj-$(CONFIG_STAGING) += staging.o
5 5
6obj-y += serial/ 6obj-y += serial/
7obj-y += media/
7obj-$(CONFIG_ET131X) += et131x/ 8obj-$(CONFIG_ET131X) += et131x/
8obj-$(CONFIG_SLICOSS) += slicoss/ 9obj-$(CONFIG_SLICOSS) += slicoss/
9obj-$(CONFIG_VIDEO_GO7007) += go7007/
10obj-$(CONFIG_VIDEO_CX25821) += cx25821/
11obj-$(CONFIG_DVB_CXD2099) += cxd2099/
12obj-$(CONFIG_LIRC_STAGING) += lirc/
13obj-$(CONFIG_USBIP_CORE) += usbip/ 10obj-$(CONFIG_USBIP_CORE) += usbip/
14obj-$(CONFIG_W35UND) += winbond/ 11obj-$(CONFIG_W35UND) += winbond/
15obj-$(CONFIG_PRISM2_USB) += wlan-ng/ 12obj-$(CONFIG_PRISM2_USB) += wlan-ng/
@@ -44,12 +41,9 @@ obj-$(CONFIG_ZCACHE) += zcache/
44obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ 41obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/
45obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ 42obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/
46obj-$(CONFIG_FB_SM7XX) += sm7xx/ 43obj-$(CONFIG_FB_SM7XX) += sm7xx/
47obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
48obj-$(CONFIG_CRYSTALHD) += crystalhd/ 44obj-$(CONFIG_CRYSTALHD) += crystalhd/
49obj-$(CONFIG_CXT1E1) += cxt1e1/ 45obj-$(CONFIG_CXT1E1) += cxt1e1/
50obj-$(CONFIG_FB_XGI) += xgifb/ 46obj-$(CONFIG_FB_XGI) += xgifb/
51obj-$(CONFIG_EASYCAP) += easycap/
52obj-$(CONFIG_SOLO6X10) += solo6x10/
53obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ 47obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
54obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/ 48obj-$(CONFIG_ACPI_QUICKSTART) += quickstart/
55obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/ 49obj-$(CONFIG_SBE_2T3E3) += sbe-2t3e3/
diff --git a/drivers/staging/cx25821/README b/drivers/staging/cx25821/README
deleted file mode 100644
index a9ba50b9888..00000000000
--- a/drivers/staging/cx25821/README
+++ /dev/null
@@ -1,6 +0,0 @@
1Todo:
2 - checkpatch.pl cleanups
3 - sparse cleanups
4
5Please send patches to linux-media@vger.kernel.org
6
diff --git a/drivers/staging/media/Kconfig b/drivers/staging/media/Kconfig
new file mode 100644
index 00000000000..7e5caa39ed3
--- /dev/null
+++ b/drivers/staging/media/Kconfig
@@ -0,0 +1,37 @@
1menuconfig STAGING_MEDIA
2 bool "Media staging drivers"
3 default n
4 ---help---
5 This option allows you to select a number of media drivers that
6 don't have the "normal" Linux kernel quality level.
7 Most of them don't follow properly the V4L, DVB and/or RC API's,
8 so, they won't likely work fine with the existing applications.
9 That also means that, one fixed, their API's will change to match
10 the existing ones.
11
12 If you wish to work on these drivers, to help improve them, or
13 to report problems you have with them, please use the
14 linux-media@vger.kernel.org mailing list.
15
16 If in doubt, say N here.
17
18
19if STAGING_MEDIA
20
21# Please keep them in alphabetic order
22source "drivers/staging/media/as102/Kconfig"
23
24source "drivers/staging/media/cxd2099/Kconfig"
25
26source "drivers/staging/media/dt3155v4l/Kconfig"
27
28source "drivers/staging/media/easycap/Kconfig"
29
30source "drivers/staging/media/go7007/Kconfig"
31
32source "drivers/staging/media/solo6x10/Kconfig"
33
34# Keep LIRC at the end, as it has sub-menus
35source "drivers/staging/media/lirc/Kconfig"
36
37endif
diff --git a/drivers/staging/media/Makefile b/drivers/staging/media/Makefile
new file mode 100644
index 00000000000..c69124cdb0d
--- /dev/null
+++ b/drivers/staging/media/Makefile
@@ -0,0 +1,7 @@
1obj-$(CONFIG_DVB_AS102) += as102/
2obj-$(CONFIG_DVB_CXD2099) += cxd2099/
3obj-$(CONFIG_EASYCAP) += easycap/
4obj-$(CONFIG_LIRC_STAGING) += lirc/
5obj-$(CONFIG_SOLO6X10) += solo6x10/
6obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
7obj-$(CONFIG_VIDEO_GO7007) += go7007/
diff --git a/drivers/staging/media/as102/Kconfig b/drivers/staging/media/as102/Kconfig
new file mode 100644
index 00000000000..5865029db0f
--- /dev/null
+++ b/drivers/staging/media/as102/Kconfig
@@ -0,0 +1,7 @@
1config DVB_AS102
2 tristate "Abilis AS102 DVB receiver"
3 depends on DVB_CORE && USB && I2C && INPUT
4 help
5 Choose Y or M here if you have a device containing an AS102
6
7 To compile this driver as a module, choose M here
diff --git a/drivers/staging/media/as102/Makefile b/drivers/staging/media/as102/Makefile
new file mode 100644
index 00000000000..e7dbb6f814d
--- /dev/null
+++ b/drivers/staging/media/as102/Makefile
@@ -0,0 +1,6 @@
1dvb-as102-objs := as102_drv.o as102_fw.o as10x_cmd.o as10x_cmd_stream.o \
2 as102_fe.o as102_usb_drv.o as10x_cmd_cfg.o
3
4obj-$(CONFIG_DVB_AS102) += dvb-as102.o
5
6EXTRA_CFLAGS += -DCONFIG_AS102_USB -Idrivers/media/dvb/dvb-core
diff --git a/drivers/staging/media/as102/as102_drv.c b/drivers/staging/media/as102/as102_drv.c
new file mode 100644
index 00000000000..d335c7d6fa0
--- /dev/null
+++ b/drivers/staging/media/as102/as102_drv.c
@@ -0,0 +1,351 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/mm.h>
26#include <linux/kref.h>
27#include <asm/uaccess.h>
28#include <linux/usb.h>
29
30/* header file for Usb device driver*/
31#include "as102_drv.h"
32#include "as102_fw.h"
33#include "dvbdev.h"
34
35int debug;
36module_param_named(debug, debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off debugging (default: off)");
38
39int dual_tuner;
40module_param_named(dual_tuner, dual_tuner, int, 0644);
41MODULE_PARM_DESC(dual_tuner, "Activate Dual-Tuner config (default: off)");
42
43static int fw_upload = 1;
44module_param_named(fw_upload, fw_upload, int, 0644);
45MODULE_PARM_DESC(fw_upload, "Turn on/off default FW upload (default: on)");
46
47static int pid_filtering;
48module_param_named(pid_filtering, pid_filtering, int, 0644);
49MODULE_PARM_DESC(pid_filtering, "Activate HW PID filtering (default: off)");
50
51static int ts_auto_disable;
52module_param_named(ts_auto_disable, ts_auto_disable, int, 0644);
53MODULE_PARM_DESC(ts_auto_disable, "Stream Auto Enable on FW (default: off)");
54
55int elna_enable = 1;
56module_param_named(elna_enable, elna_enable, int, 0644);
57MODULE_PARM_DESC(elna_enable, "Activate eLNA (default: on)");
58
59#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
60DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
61#endif
62
63static void as102_stop_stream(struct as102_dev_t *dev)
64{
65 struct as102_bus_adapter_t *bus_adap;
66
67 if (dev != NULL)
68 bus_adap = &dev->bus_adap;
69 else
70 return;
71
72 if (bus_adap->ops->stop_stream != NULL)
73 bus_adap->ops->stop_stream(dev);
74
75 if (ts_auto_disable) {
76 if (mutex_lock_interruptible(&dev->bus_adap.lock))
77 return;
78
79 if (as10x_cmd_stop_streaming(bus_adap) < 0)
80 dprintk(debug, "as10x_cmd_stop_streaming failed\n");
81
82 mutex_unlock(&dev->bus_adap.lock);
83 }
84}
85
86static int as102_start_stream(struct as102_dev_t *dev)
87{
88 struct as102_bus_adapter_t *bus_adap;
89 int ret = -EFAULT;
90
91 if (dev != NULL)
92 bus_adap = &dev->bus_adap;
93 else
94 return ret;
95
96 if (bus_adap->ops->start_stream != NULL)
97 ret = bus_adap->ops->start_stream(dev);
98
99 if (ts_auto_disable) {
100 if (mutex_lock_interruptible(&dev->bus_adap.lock))
101 return -EFAULT;
102
103 ret = as10x_cmd_start_streaming(bus_adap);
104
105 mutex_unlock(&dev->bus_adap.lock);
106 }
107
108 return ret;
109}
110
111static int as10x_pid_filter(struct as102_dev_t *dev,
112 int index, u16 pid, int onoff) {
113
114 struct as102_bus_adapter_t *bus_adap = &dev->bus_adap;
115 int ret = -EFAULT;
116
117 ENTER();
118
119 if (mutex_lock_interruptible(&dev->bus_adap.lock)) {
120 dprintk(debug, "mutex_lock_interruptible(lock) failed !\n");
121 return -EBUSY;
122 }
123
124 switch (onoff) {
125 case 0:
126 ret = as10x_cmd_del_PID_filter(bus_adap, (uint16_t) pid);
127 dprintk(debug, "DEL_PID_FILTER([%02d] 0x%04x) ret = %d\n",
128 index, pid, ret);
129 break;
130 case 1:
131 {
132 struct as10x_ts_filter filter;
133
134 filter.type = TS_PID_TYPE_TS;
135 filter.idx = 0xFF;
136 filter.pid = pid;
137
138 ret = as10x_cmd_add_PID_filter(bus_adap, &filter);
139 dprintk(debug, "ADD_PID_FILTER([%02d -> %02d], 0x%04x) ret = %d\n",
140 index, filter.idx, filter.pid, ret);
141 break;
142 }
143 }
144
145 mutex_unlock(&dev->bus_adap.lock);
146
147 LEAVE();
148 return ret;
149}
150
151static int as102_dvb_dmx_start_feed(struct dvb_demux_feed *dvbdmxfeed)
152{
153 int ret = 0;
154 struct dvb_demux *demux = dvbdmxfeed->demux;
155 struct as102_dev_t *as102_dev = demux->priv;
156
157 ENTER();
158
159 if (mutex_lock_interruptible(&as102_dev->sem))
160 return -ERESTARTSYS;
161
162 if (pid_filtering) {
163 as10x_pid_filter(as102_dev,
164 dvbdmxfeed->index, dvbdmxfeed->pid, 1);
165 }
166
167 if (as102_dev->streaming++ == 0)
168 ret = as102_start_stream(as102_dev);
169
170 mutex_unlock(&as102_dev->sem);
171 LEAVE();
172 return ret;
173}
174
175static int as102_dvb_dmx_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
176{
177 struct dvb_demux *demux = dvbdmxfeed->demux;
178 struct as102_dev_t *as102_dev = demux->priv;
179
180 ENTER();
181
182 if (mutex_lock_interruptible(&as102_dev->sem))
183 return -ERESTARTSYS;
184
185 if (--as102_dev->streaming == 0)
186 as102_stop_stream(as102_dev);
187
188 if (pid_filtering) {
189 as10x_pid_filter(as102_dev,
190 dvbdmxfeed->index, dvbdmxfeed->pid, 0);
191 }
192
193 mutex_unlock(&as102_dev->sem);
194 LEAVE();
195 return 0;
196}
197
198int as102_dvb_register(struct as102_dev_t *as102_dev)
199{
200 int ret = 0;
201 ENTER();
202
203 ret = dvb_register_adapter(&as102_dev->dvb_adap,
204 as102_dev->name,
205 THIS_MODULE,
206#if defined(CONFIG_AS102_USB)
207 &as102_dev->bus_adap.usb_dev->dev
208#elif defined(CONFIG_AS102_SPI)
209 &as102_dev->bus_adap.spi_dev->dev
210#else
211#error >>> dvb_register_adapter <<<
212#endif
213#ifdef DVB_DEFINE_MOD_OPT_ADAPTER_NR
214 , adapter_nr
215#endif
216 );
217 if (ret < 0) {
218 err("%s: dvb_register_adapter() failed (errno = %d)",
219 __func__, ret);
220 goto failed;
221 }
222
223 as102_dev->dvb_dmx.priv = as102_dev;
224 as102_dev->dvb_dmx.filternum = pid_filtering ? 16 : 256;
225 as102_dev->dvb_dmx.feednum = 256;
226 as102_dev->dvb_dmx.start_feed = as102_dvb_dmx_start_feed;
227 as102_dev->dvb_dmx.stop_feed = as102_dvb_dmx_stop_feed;
228
229 as102_dev->dvb_dmx.dmx.capabilities = DMX_TS_FILTERING |
230 DMX_SECTION_FILTERING;
231
232 as102_dev->dvb_dmxdev.filternum = as102_dev->dvb_dmx.filternum;
233 as102_dev->dvb_dmxdev.demux = &as102_dev->dvb_dmx.dmx;
234 as102_dev->dvb_dmxdev.capabilities = 0;
235
236 ret = dvb_dmx_init(&as102_dev->dvb_dmx);
237 if (ret < 0) {
238 err("%s: dvb_dmx_init() failed (errno = %d)", __func__, ret);
239 goto failed;
240 }
241
242 ret = dvb_dmxdev_init(&as102_dev->dvb_dmxdev, &as102_dev->dvb_adap);
243 if (ret < 0) {
244 err("%s: dvb_dmxdev_init() failed (errno = %d)", __func__,
245 ret);
246 goto failed;
247 }
248
249 ret = as102_dvb_register_fe(as102_dev, &as102_dev->dvb_fe);
250 if (ret < 0) {
251 err("%s: as102_dvb_register_frontend() failed (errno = %d)",
252 __func__, ret);
253 goto failed;
254 }
255
256 /* init bus mutex for token locking */
257 mutex_init(&as102_dev->bus_adap.lock);
258
259 /* init start / stop stream mutex */
260 mutex_init(&as102_dev->sem);
261
262#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
263 /*
264 * try to load as102 firmware. If firmware upload failed, we'll be
265 * able to upload it later.
266 */
267 if (fw_upload)
268 try_then_request_module(as102_fw_upload(&as102_dev->bus_adap),
269 "firmware_class");
270#endif
271
272failed:
273 LEAVE();
274 /* FIXME: free dvb_XXX */
275 return ret;
276}
277
278void as102_dvb_unregister(struct as102_dev_t *as102_dev)
279{
280 ENTER();
281
282 /* unregister as102 frontend */
283 as102_dvb_unregister_fe(&as102_dev->dvb_fe);
284
285 /* unregister demux device */
286 dvb_dmxdev_release(&as102_dev->dvb_dmxdev);
287 dvb_dmx_release(&as102_dev->dvb_dmx);
288
289 /* unregister dvb adapter */
290 dvb_unregister_adapter(&as102_dev->dvb_adap);
291
292 LEAVE();
293}
294
295static int __init as102_driver_init(void)
296{
297 int ret = 0;
298
299 ENTER();
300
301 /* register this driver with the low level subsystem */
302#if defined(CONFIG_AS102_USB)
303 ret = usb_register(&as102_usb_driver);
304 if (ret)
305 err("usb_register failed (ret = %d)", ret);
306#endif
307#if defined(CONFIG_AS102_SPI)
308 ret = spi_register_driver(&as102_spi_driver);
309 if (ret)
310 printk(KERN_ERR "spi_register failed (ret = %d)", ret);
311#endif
312
313 LEAVE();
314 return ret;
315}
316
317/*
318 * Mandatory function : Adds a special section to the module indicating
319 * where initialisation function is defined
320 */
321module_init(as102_driver_init);
322
323/**
324 * as102_driver_exit - as102 driver exit point
325 *
326 * This function is called when device has to be removed.
327 */
328static void __exit as102_driver_exit(void)
329{
330 ENTER();
331 /* deregister this driver with the low level bus subsystem */
332#if defined(CONFIG_AS102_USB)
333 usb_deregister(&as102_usb_driver);
334#endif
335#if defined(CONFIG_AS102_SPI)
336 spi_unregister_driver(&as102_spi_driver);
337#endif
338 LEAVE();
339}
340
341/*
342 * required function for unload: Adds a special section to the module
343 * indicating where unload function is defined
344 */
345module_exit(as102_driver_exit);
346/* modinfo details */
347MODULE_DESCRIPTION(DRIVER_FULL_NAME);
348MODULE_LICENSE("GPL");
349MODULE_AUTHOR("Pierrick Hascoet <pierrick.hascoet@abilis.com>");
350
351/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_drv.h b/drivers/staging/media/as102/as102_drv.h
new file mode 100644
index 00000000000..bcda635b5a9
--- /dev/null
+++ b/drivers/staging/media/as102/as102_drv.h
@@ -0,0 +1,141 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#if defined(CONFIG_AS102_USB)
21#include <linux/usb.h>
22extern struct usb_driver as102_usb_driver;
23#endif
24
25#if defined(CONFIG_AS102_SPI)
26#include <linux/platform_device.h>
27#include <linux/spi/spi.h>
28#include <linux/cdev.h>
29
30extern struct spi_driver as102_spi_driver;
31#endif
32
33#include "dvb_demux.h"
34#include "dvb_frontend.h"
35#include "dmxdev.h"
36
37#define DRIVER_FULL_NAME "Abilis Systems as10x usb driver"
38#define DRIVER_NAME "as10x_usb"
39
40extern int debug;
41
42#define dprintk(debug, args...) \
43 do { if (debug) { \
44 printk(KERN_DEBUG "%s: ",__FUNCTION__); \
45 printk(args); \
46 } } while (0)
47
48#ifdef TRACE
49#define ENTER() printk(">> enter %s\n", __FUNCTION__)
50#define LEAVE() printk("<< leave %s\n", __FUNCTION__)
51#else
52#define ENTER()
53#define LEAVE()
54#endif
55
56#define AS102_DEVICE_MAJOR 192
57
58#define AS102_USB_BUF_SIZE 512
59#define MAX_STREAM_URB 32
60
61#include "as10x_cmd.h"
62
63#if defined(CONFIG_AS102_USB)
64#include "as102_usb_drv.h"
65#endif
66
67#if defined(CONFIG_AS102_SPI)
68#include "as10x_spi_drv.h"
69#endif
70
71
72struct as102_bus_adapter_t {
73#if defined(CONFIG_AS102_USB)
74 struct usb_device *usb_dev;
75#elif defined(CONFIG_AS102_SPI)
76 struct spi_device *spi_dev;
77 struct cdev cdev; /* spidev raw device */
78
79 struct timer_list timer;
80 struct completion xfer_done;
81#endif
82 /* bus token lock */
83 struct mutex lock;
84 /* low level interface for bus adapter */
85 union as10x_bus_token_t {
86#if defined(CONFIG_AS102_USB)
87 /* usb token */
88 struct as10x_usb_token_cmd_t usb;
89#endif
90#if defined(CONFIG_AS102_SPI)
91 /* spi token */
92 struct as10x_spi_token_cmd_t spi;
93#endif
94 } token;
95
96 /* token cmd xfer id */
97 uint16_t cmd_xid;
98
99 /* as10x command and response for dvb interface*/
100 struct as10x_cmd_t *cmd, *rsp;
101
102 /* bus adapter private ops callback */
103 struct as102_priv_ops_t *ops;
104};
105
106struct as102_dev_t {
107 const char *name;
108 struct as102_bus_adapter_t bus_adap;
109 struct list_head device_entry;
110 struct kref kref;
111 unsigned long minor;
112
113 struct dvb_adapter dvb_adap;
114 struct dvb_frontend dvb_fe;
115 struct dvb_demux dvb_dmx;
116 struct dmxdev dvb_dmxdev;
117
118 /* demodulator stats */
119 struct as10x_demod_stats demod_stats;
120 /* signal strength */
121 uint16_t signal_strength;
122 /* bit error rate */
123 uint32_t ber;
124
125 /* timer handle to trig ts stream download */
126 struct timer_list timer_handle;
127
128 struct mutex sem;
129 dma_addr_t dma_addr;
130 void *stream;
131 int streaming;
132 struct urb *stream_urb[MAX_STREAM_URB];
133};
134
135int as102_dvb_register(struct as102_dev_t *dev);
136void as102_dvb_unregister(struct as102_dev_t *dev);
137
138int as102_dvb_register_fe(struct as102_dev_t *dev, struct dvb_frontend *fe);
139int as102_dvb_unregister_fe(struct dvb_frontend *dev);
140
141/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fe.c b/drivers/staging/media/as102/as102_fe.c
new file mode 100644
index 00000000000..3550f905367
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fe.c
@@ -0,0 +1,603 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/version.h>
21
22#include "as102_drv.h"
23#include "as10x_types.h"
24#include "as10x_cmd.h"
25
26extern int elna_enable;
27
28static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
29 struct as10x_tps *src);
30
31static void as102_fe_copy_tune_parameters(struct as10x_tune_args *dst,
32 struct dvb_frontend_parameters *src);
33
34static int as102_fe_set_frontend(struct dvb_frontend *fe,
35 struct dvb_frontend_parameters *params)
36{
37 int ret = 0;
38 struct as102_dev_t *dev;
39 struct as10x_tune_args tune_args = { 0 };
40
41 ENTER();
42
43 dev = (struct as102_dev_t *) fe->tuner_priv;
44 if (dev == NULL)
45 return -ENODEV;
46
47 if (mutex_lock_interruptible(&dev->bus_adap.lock))
48 return -EBUSY;
49
50 as102_fe_copy_tune_parameters(&tune_args, params);
51
52 /* send abilis command: SET_TUNE */
53 ret = as10x_cmd_set_tune(&dev->bus_adap, &tune_args);
54 if (ret != 0)
55 dprintk(debug, "as10x_cmd_set_tune failed. (err = %d)\n", ret);
56
57 mutex_unlock(&dev->bus_adap.lock);
58
59 LEAVE();
60 return (ret < 0) ? -EINVAL : 0;
61}
62
63static int as102_fe_get_frontend(struct dvb_frontend *fe,
64 struct dvb_frontend_parameters *p) {
65 int ret = 0;
66 struct as102_dev_t *dev;
67 struct as10x_tps tps = { 0 };
68
69 ENTER();
70
71 dev = (struct as102_dev_t *) fe->tuner_priv;
72 if (dev == NULL)
73 return -EINVAL;
74
75 if (mutex_lock_interruptible(&dev->bus_adap.lock))
76 return -EBUSY;
77
78 /* send abilis command: GET_TPS */
79 ret = as10x_cmd_get_tps(&dev->bus_adap, &tps);
80
81 if (ret == 0)
82 as10x_fe_copy_tps_parameters(p, &tps);
83
84 mutex_unlock(&dev->bus_adap.lock);
85
86 LEAVE();
87 return (ret < 0) ? -EINVAL : 0;
88}
89
90static int as102_fe_get_tune_settings(struct dvb_frontend *fe,
91 struct dvb_frontend_tune_settings *settings) {
92 ENTER();
93
94#if 0
95 dprintk(debug, "step_size = %d\n", settings->step_size);
96 dprintk(debug, "max_drift = %d\n", settings->max_drift);
97 dprintk(debug, "min_delay_ms = %d -> %d\n", settings->min_delay_ms,
98 1000);
99#endif
100
101 settings->min_delay_ms = 1000;
102
103 LEAVE();
104 return 0;
105}
106
107
108static int as102_fe_read_status(struct dvb_frontend *fe, fe_status_t *status)
109{
110 int ret = 0;
111 struct as102_dev_t *dev;
112 struct as10x_tune_status tstate = { 0 };
113
114 ENTER();
115
116 dev = (struct as102_dev_t *) fe->tuner_priv;
117 if (dev == NULL)
118 return -ENODEV;
119
120 if (mutex_lock_interruptible(&dev->bus_adap.lock))
121 return -EBUSY;
122
123 /* send abilis command: GET_TUNE_STATUS */
124 ret = as10x_cmd_get_tune_status(&dev->bus_adap, &tstate);
125 if (ret < 0) {
126 dprintk(debug, "as10x_cmd_get_tune_status failed (err = %d)\n",
127 ret);
128 goto out;
129 }
130
131 dev->signal_strength = tstate.signal_strength;
132 dev->ber = tstate.BER;
133
134 switch (tstate.tune_state) {
135 case TUNE_STATUS_SIGNAL_DVB_OK:
136 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
137 break;
138 case TUNE_STATUS_STREAM_DETECTED:
139 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC;
140 break;
141 case TUNE_STATUS_STREAM_TUNED:
142 *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_SYNC |
143 FE_HAS_LOCK;
144 break;
145 default:
146 *status = TUNE_STATUS_NOT_TUNED;
147 }
148
149 dprintk(debug, "tuner status: 0x%02x, strength %d, per: %d, ber: %d\n",
150 tstate.tune_state, tstate.signal_strength,
151 tstate.PER, tstate.BER);
152
153 if (*status & FE_HAS_LOCK) {
154 if (as10x_cmd_get_demod_stats(&dev->bus_adap,
155 (struct as10x_demod_stats *) &dev->demod_stats) < 0) {
156 memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
157 dprintk(debug, "as10x_cmd_get_demod_stats failed "
158 "(probably not tuned)\n");
159 } else {
160 dprintk(debug,
161 "demod status: fc: 0x%08x, bad fc: 0x%08x, "
162 "bytes corrected: 0x%08x , MER: 0x%04x\n",
163 dev->demod_stats.frame_count,
164 dev->demod_stats.bad_frame_count,
165 dev->demod_stats.bytes_fixed_by_rs,
166 dev->demod_stats.mer);
167 }
168 } else {
169 memset(&dev->demod_stats, 0, sizeof(dev->demod_stats));
170 }
171
172out:
173 mutex_unlock(&dev->bus_adap.lock);
174 LEAVE();
175 return ret;
176}
177
178/*
179 * Note:
180 * - in AS102 SNR=MER
181 * - the SNR will be returned in linear terms, i.e. not in dB
182 * - the accuracy equals ±2dB for a SNR range from 4dB to 30dB
183 * - the accuracy is >2dB for SNR values outside this range
184 */
185static int as102_fe_read_snr(struct dvb_frontend *fe, u16 *snr)
186{
187 struct as102_dev_t *dev;
188
189 ENTER();
190
191 dev = (struct as102_dev_t *) fe->tuner_priv;
192 if (dev == NULL)
193 return -ENODEV;
194
195 *snr = dev->demod_stats.mer;
196
197 LEAVE();
198 return 0;
199}
200
201static int as102_fe_read_ber(struct dvb_frontend *fe, u32 *ber)
202{
203 struct as102_dev_t *dev;
204
205 ENTER();
206
207 dev = (struct as102_dev_t *) fe->tuner_priv;
208 if (dev == NULL)
209 return -ENODEV;
210
211 *ber = dev->ber;
212
213 LEAVE();
214 return 0;
215}
216
217static int as102_fe_read_signal_strength(struct dvb_frontend *fe,
218 u16 *strength)
219{
220 struct as102_dev_t *dev;
221
222 ENTER();
223
224 dev = (struct as102_dev_t *) fe->tuner_priv;
225 if (dev == NULL)
226 return -ENODEV;
227
228 *strength = (((0xffff * 400) * dev->signal_strength + 41000) * 2);
229
230 LEAVE();
231 return 0;
232}
233
234static int as102_fe_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
235{
236 struct as102_dev_t *dev;
237
238 ENTER();
239
240 dev = (struct as102_dev_t *) fe->tuner_priv;
241 if (dev == NULL)
242 return -ENODEV;
243
244 if (dev->demod_stats.has_started)
245 *ucblocks = dev->demod_stats.bad_frame_count;
246 else
247 *ucblocks = 0;
248
249 LEAVE();
250 return 0;
251}
252
253static int as102_fe_ts_bus_ctrl(struct dvb_frontend *fe, int acquire)
254{
255 struct as102_dev_t *dev;
256 int ret;
257
258 ENTER();
259
260 dev = (struct as102_dev_t *) fe->tuner_priv;
261 if (dev == NULL)
262 return -ENODEV;
263
264 if (mutex_lock_interruptible(&dev->bus_adap.lock))
265 return -EBUSY;
266
267 if (acquire) {
268 if (elna_enable)
269 as10x_cmd_set_context(&dev->bus_adap, 1010, 0xC0);
270
271 ret = as10x_cmd_turn_on(&dev->bus_adap);
272 } else {
273 ret = as10x_cmd_turn_off(&dev->bus_adap);
274 }
275
276 mutex_unlock(&dev->bus_adap.lock);
277
278 LEAVE();
279 return ret;
280}
281
282static struct dvb_frontend_ops as102_fe_ops = {
283 .info = {
284 .name = "Unknown AS102 device",
285 .type = FE_OFDM,
286 .frequency_min = 174000000,
287 .frequency_max = 862000000,
288 .frequency_stepsize = 166667,
289 .caps = FE_CAN_INVERSION_AUTO
290 | FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4
291 | FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO
292 | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QPSK
293 | FE_CAN_QAM_AUTO
294 | FE_CAN_TRANSMISSION_MODE_AUTO
295 | FE_CAN_GUARD_INTERVAL_AUTO
296 | FE_CAN_HIERARCHY_AUTO
297 | FE_CAN_RECOVER
298 | FE_CAN_MUTE_TS
299 },
300
301 .set_frontend = as102_fe_set_frontend,
302 .get_frontend = as102_fe_get_frontend,
303 .get_tune_settings = as102_fe_get_tune_settings,
304
305 .read_status = as102_fe_read_status,
306 .read_snr = as102_fe_read_snr,
307 .read_ber = as102_fe_read_ber,
308 .read_signal_strength = as102_fe_read_signal_strength,
309 .read_ucblocks = as102_fe_read_ucblocks,
310 .ts_bus_ctrl = as102_fe_ts_bus_ctrl,
311};
312
313int as102_dvb_unregister_fe(struct dvb_frontend *fe)
314{
315 /* unregister frontend */
316 dvb_unregister_frontend(fe);
317
318 /* detach frontend */
319 dvb_frontend_detach(fe);
320
321 return 0;
322}
323
324int as102_dvb_register_fe(struct as102_dev_t *as102_dev,
325 struct dvb_frontend *dvb_fe)
326{
327 int errno;
328 struct dvb_adapter *dvb_adap;
329
330 if (as102_dev == NULL)
331 return -EINVAL;
332
333 /* extract dvb_adapter */
334 dvb_adap = &as102_dev->dvb_adap;
335
336 /* init frontend callback ops */
337 memcpy(&dvb_fe->ops, &as102_fe_ops, sizeof(struct dvb_frontend_ops));
338 strncpy(dvb_fe->ops.info.name, as102_dev->name,
339 sizeof(dvb_fe->ops.info.name));
340
341 /* register dbvb frontend */
342 errno = dvb_register_frontend(dvb_adap, dvb_fe);
343 if (errno == 0)
344 dvb_fe->tuner_priv = as102_dev;
345
346 return errno;
347}
348
349static void as10x_fe_copy_tps_parameters(struct dvb_frontend_parameters *dst,
350 struct as10x_tps *as10x_tps)
351{
352
353 struct dvb_ofdm_parameters *fe_tps = &dst->u.ofdm;
354
355 /* extract consteallation */
356 switch (as10x_tps->constellation) {
357 case CONST_QPSK:
358 fe_tps->constellation = QPSK;
359 break;
360 case CONST_QAM16:
361 fe_tps->constellation = QAM_16;
362 break;
363 case CONST_QAM64:
364 fe_tps->constellation = QAM_64;
365 break;
366 }
367
368 /* extract hierarchy */
369 switch (as10x_tps->hierarchy) {
370 case HIER_NONE:
371 fe_tps->hierarchy_information = HIERARCHY_NONE;
372 break;
373 case HIER_ALPHA_1:
374 fe_tps->hierarchy_information = HIERARCHY_1;
375 break;
376 case HIER_ALPHA_2:
377 fe_tps->hierarchy_information = HIERARCHY_2;
378 break;
379 case HIER_ALPHA_4:
380 fe_tps->hierarchy_information = HIERARCHY_4;
381 break;
382 }
383
384 /* extract code rate HP */
385 switch (as10x_tps->code_rate_HP) {
386 case CODE_RATE_1_2:
387 fe_tps->code_rate_HP = FEC_1_2;
388 break;
389 case CODE_RATE_2_3:
390 fe_tps->code_rate_HP = FEC_2_3;
391 break;
392 case CODE_RATE_3_4:
393 fe_tps->code_rate_HP = FEC_3_4;
394 break;
395 case CODE_RATE_5_6:
396 fe_tps->code_rate_HP = FEC_5_6;
397 break;
398 case CODE_RATE_7_8:
399 fe_tps->code_rate_HP = FEC_7_8;
400 break;
401 }
402
403 /* extract code rate LP */
404 switch (as10x_tps->code_rate_LP) {
405 case CODE_RATE_1_2:
406 fe_tps->code_rate_LP = FEC_1_2;
407 break;
408 case CODE_RATE_2_3:
409 fe_tps->code_rate_LP = FEC_2_3;
410 break;
411 case CODE_RATE_3_4:
412 fe_tps->code_rate_LP = FEC_3_4;
413 break;
414 case CODE_RATE_5_6:
415 fe_tps->code_rate_LP = FEC_5_6;
416 break;
417 case CODE_RATE_7_8:
418 fe_tps->code_rate_LP = FEC_7_8;
419 break;
420 }
421
422 /* extract guard interval */
423 switch (as10x_tps->guard_interval) {
424 case GUARD_INT_1_32:
425 fe_tps->guard_interval = GUARD_INTERVAL_1_32;
426 break;
427 case GUARD_INT_1_16:
428 fe_tps->guard_interval = GUARD_INTERVAL_1_16;
429 break;
430 case GUARD_INT_1_8:
431 fe_tps->guard_interval = GUARD_INTERVAL_1_8;
432 break;
433 case GUARD_INT_1_4:
434 fe_tps->guard_interval = GUARD_INTERVAL_1_4;
435 break;
436 }
437
438 /* extract transmission mode */
439 switch (as10x_tps->transmission_mode) {
440 case TRANS_MODE_2K:
441 fe_tps->transmission_mode = TRANSMISSION_MODE_2K;
442 break;
443 case TRANS_MODE_8K:
444 fe_tps->transmission_mode = TRANSMISSION_MODE_8K;
445 break;
446 }
447}
448
449static uint8_t as102_fe_get_code_rate(fe_code_rate_t arg)
450{
451 uint8_t c;
452
453 switch (arg) {
454 case FEC_1_2:
455 c = CODE_RATE_1_2;
456 break;
457 case FEC_2_3:
458 c = CODE_RATE_2_3;
459 break;
460 case FEC_3_4:
461 c = CODE_RATE_3_4;
462 break;
463 case FEC_5_6:
464 c = CODE_RATE_5_6;
465 break;
466 case FEC_7_8:
467 c = CODE_RATE_7_8;
468 break;
469 default:
470 c = CODE_RATE_UNKNOWN;
471 break;
472 }
473
474 return c;
475}
476
477static void as102_fe_copy_tune_parameters(struct as10x_tune_args *tune_args,
478 struct dvb_frontend_parameters *params)
479{
480
481 /* set frequency */
482 tune_args->freq = params->frequency / 1000;
483
484 /* fix interleaving_mode */
485 tune_args->interleaving_mode = INTLV_NATIVE;
486
487 switch (params->u.ofdm.bandwidth) {
488 case BANDWIDTH_8_MHZ:
489 tune_args->bandwidth = BW_8_MHZ;
490 break;
491 case BANDWIDTH_7_MHZ:
492 tune_args->bandwidth = BW_7_MHZ;
493 break;
494 case BANDWIDTH_6_MHZ:
495 tune_args->bandwidth = BW_6_MHZ;
496 break;
497 default:
498 tune_args->bandwidth = BW_8_MHZ;
499 }
500
501 switch (params->u.ofdm.guard_interval) {
502 case GUARD_INTERVAL_1_32:
503 tune_args->guard_interval = GUARD_INT_1_32;
504 break;
505 case GUARD_INTERVAL_1_16:
506 tune_args->guard_interval = GUARD_INT_1_16;
507 break;
508 case GUARD_INTERVAL_1_8:
509 tune_args->guard_interval = GUARD_INT_1_8;
510 break;
511 case GUARD_INTERVAL_1_4:
512 tune_args->guard_interval = GUARD_INT_1_4;
513 break;
514 case GUARD_INTERVAL_AUTO:
515 default:
516 tune_args->guard_interval = GUARD_UNKNOWN;
517 break;
518 }
519
520 switch (params->u.ofdm.constellation) {
521 case QPSK:
522 tune_args->constellation = CONST_QPSK;
523 break;
524 case QAM_16:
525 tune_args->constellation = CONST_QAM16;
526 break;
527 case QAM_64:
528 tune_args->constellation = CONST_QAM64;
529 break;
530 default:
531 tune_args->constellation = CONST_UNKNOWN;
532 break;
533 }
534
535 switch (params->u.ofdm.transmission_mode) {
536 case TRANSMISSION_MODE_2K:
537 tune_args->transmission_mode = TRANS_MODE_2K;
538 break;
539 case TRANSMISSION_MODE_8K:
540 tune_args->transmission_mode = TRANS_MODE_8K;
541 break;
542 default:
543 tune_args->transmission_mode = TRANS_MODE_UNKNOWN;
544 }
545
546 switch (params->u.ofdm.hierarchy_information) {
547 case HIERARCHY_NONE:
548 tune_args->hierarchy = HIER_NONE;
549 break;
550 case HIERARCHY_1:
551 tune_args->hierarchy = HIER_ALPHA_1;
552 break;
553 case HIERARCHY_2:
554 tune_args->hierarchy = HIER_ALPHA_2;
555 break;
556 case HIERARCHY_4:
557 tune_args->hierarchy = HIER_ALPHA_4;
558 break;
559 case HIERARCHY_AUTO:
560 tune_args->hierarchy = HIER_UNKNOWN;
561 break;
562 }
563
564 dprintk(debug, "tuner parameters: freq: %d bw: 0x%02x gi: 0x%02x\n",
565 params->frequency,
566 tune_args->bandwidth,
567 tune_args->guard_interval);
568
569 /*
570 * Detect a hierarchy selection
571 * if HP/LP are both set to FEC_NONE, HP will be selected.
572 */
573 if ((tune_args->hierarchy != HIER_NONE) &&
574 ((params->u.ofdm.code_rate_LP == FEC_NONE) ||
575 (params->u.ofdm.code_rate_HP == FEC_NONE))) {
576
577 if (params->u.ofdm.code_rate_LP == FEC_NONE) {
578 tune_args->hier_select = HIER_HIGH_PRIORITY;
579 tune_args->code_rate =
580 as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
581 }
582
583 if (params->u.ofdm.code_rate_HP == FEC_NONE) {
584 tune_args->hier_select = HIER_LOW_PRIORITY;
585 tune_args->code_rate =
586 as102_fe_get_code_rate(params->u.ofdm.code_rate_LP);
587 }
588
589 dprintk(debug, "\thierarchy: 0x%02x "
590 "selected: %s code_rate_%s: 0x%02x\n",
591 tune_args->hierarchy,
592 tune_args->hier_select == HIER_HIGH_PRIORITY ?
593 "HP" : "LP",
594 tune_args->hier_select == HIER_HIGH_PRIORITY ?
595 "HP" : "LP",
596 tune_args->code_rate);
597 } else {
598 tune_args->code_rate =
599 as102_fe_get_code_rate(params->u.ofdm.code_rate_HP);
600 }
601}
602
603/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.c b/drivers/staging/media/as102/as102_fw.c
new file mode 100644
index 00000000000..c019df933cc
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fw.c
@@ -0,0 +1,251 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/ctype.h>
23#include <linux/delay.h>
24#include <linux/firmware.h>
25
26#include "as102_drv.h"
27#include "as102_fw.h"
28
29#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
30char as102_st_fw1[] = "as102_data1_st.hex";
31char as102_st_fw2[] = "as102_data2_st.hex";
32char as102_dt_fw1[] = "as102_data1_dt.hex";
33char as102_dt_fw2[] = "as102_data2_dt.hex";
34
35static unsigned char atohx(unsigned char *dst, char *src)
36{
37 unsigned char value = 0;
38
39 char msb = tolower(*src) - '0';
40 char lsb = tolower(*(src + 1)) - '0';
41
42 if (msb > 9)
43 msb -= 7;
44 if (lsb > 9)
45 lsb -= 7;
46
47 *dst = value = ((msb & 0xF) << 4) | (lsb & 0xF);
48 return value;
49}
50
51/*
52 * Parse INTEL HEX firmware file to extract address and data.
53 */
54static int parse_hex_line(unsigned char *fw_data, unsigned char *addr,
55 unsigned char *data, int *dataLength,
56 unsigned char *addr_has_changed) {
57
58 int count = 0;
59 unsigned char *src, dst;
60
61 if (*fw_data++ != ':') {
62 printk(KERN_ERR "invalid firmware file\n");
63 return -EFAULT;
64 }
65
66 /* locate end of line */
67 for (src = fw_data; *src != '\n'; src += 2) {
68 atohx(&dst, src);
69 /* parse line to split addr / data */
70 switch (count) {
71 case 0:
72 *dataLength = dst;
73 break;
74 case 1:
75 addr[2] = dst;
76 break;
77 case 2:
78 addr[3] = dst;
79 break;
80 case 3:
81 /* check if data is an address */
82 if (dst == 0x04)
83 *addr_has_changed = 1;
84 else
85 *addr_has_changed = 0;
86 break;
87 case 4:
88 case 5:
89 if (*addr_has_changed)
90 addr[(count - 4)] = dst;
91 else
92 data[(count - 4)] = dst;
93 break;
94 default:
95 data[(count - 4)] = dst;
96 break;
97 }
98 count++;
99 }
100
101 /* return read value + ':' + '\n' */
102 return (count * 2) + 2;
103}
104
105static int as102_firmware_upload(struct as102_bus_adapter_t *bus_adap,
106 unsigned char *cmd,
107 const struct firmware *firmware) {
108
109 struct as10x_fw_pkt_t fw_pkt;
110 int total_read_bytes = 0, errno = 0;
111 unsigned char addr_has_changed = 0;
112
113 ENTER();
114
115 for (total_read_bytes = 0; total_read_bytes < firmware->size; ) {
116 int read_bytes = 0, data_len = 0;
117
118 /* parse intel hex line */
119 read_bytes = parse_hex_line(
120 (u8 *) (firmware->data + total_read_bytes),
121 fw_pkt.raw.address,
122 fw_pkt.raw.data,
123 &data_len,
124 &addr_has_changed);
125
126 if (read_bytes <= 0)
127 goto error;
128
129 /* detect the end of file */
130 total_read_bytes += read_bytes;
131 if (total_read_bytes == firmware->size) {
132 fw_pkt.u.request[0] = 0x00;
133 fw_pkt.u.request[1] = 0x03;
134
135 /* send EOF command */
136 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
137 (uint8_t *)
138 &fw_pkt, 2, 0);
139 if (errno < 0)
140 goto error;
141 } else {
142 if (!addr_has_changed) {
143 /* prepare command to send */
144 fw_pkt.u.request[0] = 0x00;
145 fw_pkt.u.request[1] = 0x01;
146
147 data_len += sizeof(fw_pkt.u.request);
148 data_len += sizeof(fw_pkt.raw.address);
149
150 /* send cmd to device */
151 errno = bus_adap->ops->upload_fw_pkt(bus_adap,
152 (uint8_t *)
153 &fw_pkt,
154 data_len,
155 0);
156 if (errno < 0)
157 goto error;
158 }
159 }
160 }
161error:
162 LEAVE();
163 return (errno == 0) ? total_read_bytes : errno;
164}
165
166int as102_fw_upload(struct as102_bus_adapter_t *bus_adap)
167{
168 int errno = -EFAULT;
169 const struct firmware *firmware;
170 unsigned char *cmd_buf = NULL;
171 char *fw1, *fw2;
172
173#if defined(CONFIG_AS102_USB)
174 struct usb_device *dev = bus_adap->usb_dev;
175#endif
176#if defined(CONFIG_AS102_SPI)
177 struct spi_device *dev = bus_adap->spi_dev;
178#endif
179 ENTER();
180
181 /* select fw file to upload */
182 if (dual_tuner) {
183 fw1 = as102_dt_fw1;
184 fw2 = as102_dt_fw2;
185 } else {
186 fw1 = as102_st_fw1;
187 fw2 = as102_st_fw2;
188 }
189
190#if defined(CONFIG_FW_LOADER) || defined(CONFIG_FW_LOADER_MODULE)
191 /* allocate buffer to store firmware upload command and data */
192 cmd_buf = kzalloc(MAX_FW_PKT_SIZE, GFP_KERNEL);
193 if (cmd_buf == NULL) {
194 errno = -ENOMEM;
195 goto error;
196 }
197
198 /* request kernel to locate firmware file: part1 */
199 errno = request_firmware(&firmware, fw1, &dev->dev);
200 if (errno < 0) {
201 printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
202 DRIVER_NAME, fw1);
203 goto error;
204 }
205
206 /* initiate firmware upload */
207 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
208 if (errno < 0) {
209 printk(KERN_ERR "%s: error during firmware upload part1\n",
210 DRIVER_NAME);
211 goto error;
212 }
213
214 printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
215 DRIVER_NAME, fw1);
216 release_firmware(firmware);
217
218 /* wait for boot to complete */
219 mdelay(100);
220
221 /* request kernel to locate firmware file: part2 */
222 errno = request_firmware(&firmware, fw2, &dev->dev);
223 if (errno < 0) {
224 printk(KERN_ERR "%s: unable to locate firmware file: %s\n",
225 DRIVER_NAME, fw2);
226 goto error;
227 }
228
229 /* initiate firmware upload */
230 errno = as102_firmware_upload(bus_adap, cmd_buf, firmware);
231 if (errno < 0) {
232 printk(KERN_ERR "%s: error during firmware upload part2\n",
233 DRIVER_NAME);
234 goto error;
235 }
236
237 printk(KERN_INFO "%s: fimrware: %s loaded with success\n",
238 DRIVER_NAME, fw2);
239error:
240 /* free data buffer */
241 kfree(cmd_buf);
242 /* release firmware if needed */
243 if (firmware != NULL)
244 release_firmware(firmware);
245#endif
246 LEAVE();
247 return errno;
248}
249#endif
250
251/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_fw.h b/drivers/staging/media/as102/as102_fw.h
new file mode 100644
index 00000000000..27e5347e2e1
--- /dev/null
+++ b/drivers/staging/media/as102/as102_fw.h
@@ -0,0 +1,42 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#define MAX_FW_PKT_SIZE 64
20
21extern int dual_tuner;
22
23#pragma pack(1)
24struct as10x_raw_fw_pkt {
25 unsigned char address[4];
26 unsigned char data[MAX_FW_PKT_SIZE - 6];
27};
28
29struct as10x_fw_pkt_t {
30 union {
31 unsigned char request[2];
32 unsigned char length[2];
33 } u;
34 struct as10x_raw_fw_pkt raw;
35};
36#pragma pack()
37
38#ifdef __KERNEL__
39int as102_fw_upload(struct as102_bus_adapter_t *bus_adap);
40#endif
41
42/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.c b/drivers/staging/media/as102/as102_usb_drv.c
new file mode 100644
index 00000000000..264be2dbd2a
--- /dev/null
+++ b/drivers/staging/media/as102/as102_usb_drv.c
@@ -0,0 +1,478 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/slab.h>
23#include <linux/mm.h>
24#include <linux/usb.h>
25
26#include "as102_drv.h"
27#include "as102_usb_drv.h"
28#include "as102_fw.h"
29
30static void as102_usb_disconnect(struct usb_interface *interface);
31static int as102_usb_probe(struct usb_interface *interface,
32 const struct usb_device_id *id);
33
34static int as102_usb_start_stream(struct as102_dev_t *dev);
35static void as102_usb_stop_stream(struct as102_dev_t *dev);
36
37static int as102_open(struct inode *inode, struct file *file);
38static int as102_release(struct inode *inode, struct file *file);
39
40static struct usb_device_id as102_usb_id_table[] = {
41 { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
42 { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
43 { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
44 { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
45 { } /* Terminating entry */
46};
47
48/* Note that this table must always have the same number of entries as the
49 as102_usb_id_table struct */
50static const char *as102_device_names[] = {
51 AS102_REFERENCE_DESIGN,
52 AS102_PCTV_74E,
53 AS102_ELGATO_EYETV_DTT_NAME,
54 AS102_NBOX_DVBT_DONGLE_NAME,
55 NULL /* Terminating entry */
56};
57
58struct usb_driver as102_usb_driver = {
59 .name = DRIVER_FULL_NAME,
60 .probe = as102_usb_probe,
61 .disconnect = as102_usb_disconnect,
62 .id_table = as102_usb_id_table
63};
64
65static const struct file_operations as102_dev_fops = {
66 .owner = THIS_MODULE,
67 .open = as102_open,
68 .release = as102_release,
69};
70
71static struct usb_class_driver as102_usb_class_driver = {
72 .name = "aton2-%d",
73 .fops = &as102_dev_fops,
74 .minor_base = AS102_DEVICE_MAJOR,
75};
76
77static int as102_usb_xfer_cmd(struct as102_bus_adapter_t *bus_adap,
78 unsigned char *send_buf, int send_buf_len,
79 unsigned char *recv_buf, int recv_buf_len)
80{
81 int ret = 0;
82 ENTER();
83
84 if (send_buf != NULL) {
85 ret = usb_control_msg(bus_adap->usb_dev,
86 usb_sndctrlpipe(bus_adap->usb_dev, 0),
87 AS102_USB_DEVICE_TX_CTRL_CMD,
88 USB_DIR_OUT | USB_TYPE_VENDOR |
89 USB_RECIP_DEVICE,
90 bus_adap->cmd_xid, /* value */
91 0, /* index */
92 send_buf, send_buf_len,
93 USB_CTRL_SET_TIMEOUT /* 200 */);
94 if (ret < 0) {
95 dprintk(debug, "usb_control_msg(send) failed, err %i\n",
96 ret);
97 return ret;
98 }
99
100 if (ret != send_buf_len) {
101 dprintk(debug, "only wrote %d of %d bytes\n",
102 ret, send_buf_len);
103 return -1;
104 }
105 }
106
107 if (recv_buf != NULL) {
108#ifdef TRACE
109 dprintk(debug, "want to read: %d bytes\n", recv_buf_len);
110#endif
111 ret = usb_control_msg(bus_adap->usb_dev,
112 usb_rcvctrlpipe(bus_adap->usb_dev, 0),
113 AS102_USB_DEVICE_RX_CTRL_CMD,
114 USB_DIR_IN | USB_TYPE_VENDOR |
115 USB_RECIP_DEVICE,
116 bus_adap->cmd_xid, /* value */
117 0, /* index */
118 recv_buf, recv_buf_len,
119 USB_CTRL_GET_TIMEOUT /* 200 */);
120 if (ret < 0) {
121 dprintk(debug, "usb_control_msg(recv) failed, err %i\n",
122 ret);
123 return ret;
124 }
125#ifdef TRACE
126 dprintk(debug, "read %d bytes\n", recv_buf_len);
127#endif
128 }
129
130 LEAVE();
131 return ret;
132}
133
134static int as102_send_ep1(struct as102_bus_adapter_t *bus_adap,
135 unsigned char *send_buf,
136 int send_buf_len,
137 int swap32)
138{
139 int ret = 0, actual_len;
140
141 ret = usb_bulk_msg(bus_adap->usb_dev,
142 usb_sndbulkpipe(bus_adap->usb_dev, 1),
143 send_buf, send_buf_len, &actual_len, 200);
144 if (ret) {
145 dprintk(debug, "usb_bulk_msg(send) failed, err %i\n", ret);
146 return ret;
147 }
148
149 if (actual_len != send_buf_len) {
150 dprintk(debug, "only wrote %d of %d bytes\n",
151 actual_len, send_buf_len);
152 return -1;
153 }
154 return ret ? ret : actual_len;
155}
156
157static int as102_read_ep2(struct as102_bus_adapter_t *bus_adap,
158 unsigned char *recv_buf, int recv_buf_len)
159{
160 int ret = 0, actual_len;
161
162 if (recv_buf == NULL)
163 return -EINVAL;
164
165 ret = usb_bulk_msg(bus_adap->usb_dev,
166 usb_rcvbulkpipe(bus_adap->usb_dev, 2),
167 recv_buf, recv_buf_len, &actual_len, 200);
168 if (ret) {
169 dprintk(debug, "usb_bulk_msg(recv) failed, err %i\n", ret);
170 return ret;
171 }
172
173 if (actual_len != recv_buf_len) {
174 dprintk(debug, "only read %d of %d bytes\n",
175 actual_len, recv_buf_len);
176 return -1;
177 }
178 return ret ? ret : actual_len;
179}
180
181struct as102_priv_ops_t as102_priv_ops = {
182 .upload_fw_pkt = as102_send_ep1,
183 .xfer_cmd = as102_usb_xfer_cmd,
184 .as102_read_ep2 = as102_read_ep2,
185 .start_stream = as102_usb_start_stream,
186 .stop_stream = as102_usb_stop_stream,
187};
188
189static int as102_submit_urb_stream(struct as102_dev_t *dev, struct urb *urb)
190{
191 int err;
192
193 usb_fill_bulk_urb(urb,
194 dev->bus_adap.usb_dev,
195 usb_rcvbulkpipe(dev->bus_adap.usb_dev, 0x2),
196 urb->transfer_buffer,
197 AS102_USB_BUF_SIZE,
198 as102_urb_stream_irq,
199 dev);
200
201 err = usb_submit_urb(urb, GFP_ATOMIC);
202 if (err)
203 dprintk(debug, "%s: usb_submit_urb failed\n", __func__);
204
205 return err;
206}
207
208void as102_urb_stream_irq(struct urb *urb)
209{
210 struct as102_dev_t *as102_dev = urb->context;
211
212 if (urb->actual_length > 0) {
213 dvb_dmx_swfilter(&as102_dev->dvb_dmx,
214 urb->transfer_buffer,
215 urb->actual_length);
216 } else {
217 if (urb->actual_length == 0)
218 memset(urb->transfer_buffer, 0, AS102_USB_BUF_SIZE);
219 }
220
221 /* is not stopped, re-submit urb */
222 if (as102_dev->streaming)
223 as102_submit_urb_stream(as102_dev, urb);
224}
225
226static void as102_free_usb_stream_buffer(struct as102_dev_t *dev)
227{
228 int i;
229
230 ENTER();
231
232 for (i = 0; i < MAX_STREAM_URB; i++)
233 usb_free_urb(dev->stream_urb[i]);
234
235 usb_free_coherent(dev->bus_adap.usb_dev,
236 MAX_STREAM_URB * AS102_USB_BUF_SIZE,
237 dev->stream,
238 dev->dma_addr);
239 LEAVE();
240}
241
242static int as102_alloc_usb_stream_buffer(struct as102_dev_t *dev)
243{
244 int i, ret = 0;
245
246 ENTER();
247
248 dev->stream = usb_alloc_coherent(dev->bus_adap.usb_dev,
249 MAX_STREAM_URB * AS102_USB_BUF_SIZE,
250 GFP_KERNEL,
251 &dev->dma_addr);
252 if (!dev->stream) {
253 dprintk(debug, "%s: usb_buffer_alloc failed\n", __func__);
254 return -ENOMEM;
255 }
256
257 memset(dev->stream, 0, MAX_STREAM_URB * AS102_USB_BUF_SIZE);
258
259 /* init urb buffers */
260 for (i = 0; i < MAX_STREAM_URB; i++) {
261 struct urb *urb;
262
263 urb = usb_alloc_urb(0, GFP_ATOMIC);
264 if (urb == NULL) {
265 dprintk(debug, "%s: usb_alloc_urb failed\n", __func__);
266 as102_free_usb_stream_buffer(dev);
267 return -ENOMEM;
268 }
269
270 urb->transfer_buffer = dev->stream + (i * AS102_USB_BUF_SIZE);
271 urb->transfer_buffer_length = AS102_USB_BUF_SIZE;
272
273 dev->stream_urb[i] = urb;
274 }
275 LEAVE();
276 return ret;
277}
278
279static void as102_usb_stop_stream(struct as102_dev_t *dev)
280{
281 int i;
282
283 for (i = 0; i < MAX_STREAM_URB; i++)
284 usb_kill_urb(dev->stream_urb[i]);
285}
286
287static int as102_usb_start_stream(struct as102_dev_t *dev)
288{
289 int i, ret = 0;
290
291 for (i = 0; i < MAX_STREAM_URB; i++) {
292 ret = as102_submit_urb_stream(dev, dev->stream_urb[i]);
293 if (ret) {
294 as102_usb_stop_stream(dev);
295 return ret;
296 }
297 }
298
299 return 0;
300}
301
302static void as102_usb_release(struct kref *kref)
303{
304 struct as102_dev_t *as102_dev;
305
306 ENTER();
307
308 as102_dev = container_of(kref, struct as102_dev_t, kref);
309 if (as102_dev != NULL) {
310 usb_put_dev(as102_dev->bus_adap.usb_dev);
311 kfree(as102_dev);
312 }
313
314 LEAVE();
315}
316
317static void as102_usb_disconnect(struct usb_interface *intf)
318{
319 struct as102_dev_t *as102_dev;
320
321 ENTER();
322
323 /* extract as102_dev_t from usb_device private data */
324 as102_dev = usb_get_intfdata(intf);
325
326 /* unregister dvb layer */
327 as102_dvb_unregister(as102_dev);
328
329 /* free usb buffers */
330 as102_free_usb_stream_buffer(as102_dev);
331
332 usb_set_intfdata(intf, NULL);
333
334 /* usb unregister device */
335 usb_deregister_dev(intf, &as102_usb_class_driver);
336
337 /* decrement usage counter */
338 kref_put(&as102_dev->kref, as102_usb_release);
339
340 printk(KERN_INFO "%s: device has been disconnected\n", DRIVER_NAME);
341
342 LEAVE();
343}
344
345static int as102_usb_probe(struct usb_interface *intf,
346 const struct usb_device_id *id)
347{
348 int ret;
349 struct as102_dev_t *as102_dev;
350 int i;
351
352 ENTER();
353
354 as102_dev = kzalloc(sizeof(struct as102_dev_t), GFP_KERNEL);
355 if (as102_dev == NULL) {
356 err("%s: kzalloc failed", __func__);
357 return -ENOMEM;
358 }
359
360 /* This should never actually happen */
361 if ((sizeof(as102_usb_id_table) / sizeof(struct usb_device_id)) !=
362 (sizeof(as102_device_names) / sizeof(const char *))) {
363 printk(KERN_ERR "Device names table invalid size");
364 return -EINVAL;
365 }
366
367 /* Assign the user-friendly device name */
368 for (i = 0; i < (sizeof(as102_usb_id_table) /
369 sizeof(struct usb_device_id)); i++) {
370 if (id == &as102_usb_id_table[i])
371 as102_dev->name = as102_device_names[i];
372 }
373
374 if (as102_dev->name == NULL)
375 as102_dev->name = "Unknown AS102 device";
376
377 /* set private callback functions */
378 as102_dev->bus_adap.ops = &as102_priv_ops;
379
380 /* init cmd token for usb bus */
381 as102_dev->bus_adap.cmd = &as102_dev->bus_adap.token.usb.c;
382 as102_dev->bus_adap.rsp = &as102_dev->bus_adap.token.usb.r;
383
384 /* init kernel device reference */
385 kref_init(&as102_dev->kref);
386
387 /* store as102 device to usb_device private data */
388 usb_set_intfdata(intf, (void *) as102_dev);
389
390 /* store in as102 device the usb_device pointer */
391 as102_dev->bus_adap.usb_dev = usb_get_dev(interface_to_usbdev(intf));
392
393 /* we can register the device now, as it is ready */
394 ret = usb_register_dev(intf, &as102_usb_class_driver);
395 if (ret < 0) {
396 /* something prevented us from registering this driver */
397 err("%s: usb_register_dev() failed (errno = %d)",
398 __func__, ret);
399 goto failed;
400 }
401
402 printk(KERN_INFO "%s: device has been detected\n", DRIVER_NAME);
403
404 /* request buffer allocation for streaming */
405 ret = as102_alloc_usb_stream_buffer(as102_dev);
406 if (ret != 0)
407 goto failed;
408
409 /* register dvb layer */
410 ret = as102_dvb_register(as102_dev);
411
412 LEAVE();
413 return ret;
414
415failed:
416 usb_set_intfdata(intf, NULL);
417 kfree(as102_dev);
418 return ret;
419}
420
421static int as102_open(struct inode *inode, struct file *file)
422{
423 int ret = 0, minor = 0;
424 struct usb_interface *intf = NULL;
425 struct as102_dev_t *dev = NULL;
426
427 ENTER();
428
429 /* read minor from inode */
430 minor = iminor(inode);
431
432 /* fetch device from usb interface */
433 intf = usb_find_interface(&as102_usb_driver, minor);
434 if (intf == NULL) {
435 printk(KERN_ERR "%s: can't find device for minor %d\n",
436 __func__, minor);
437 ret = -ENODEV;
438 goto exit;
439 }
440
441 /* get our device */
442 dev = usb_get_intfdata(intf);
443 if (dev == NULL) {
444 ret = -EFAULT;
445 goto exit;
446 }
447
448 /* save our device object in the file's private structure */
449 file->private_data = dev;
450
451 /* increment our usage count for the device */
452 kref_get(&dev->kref);
453
454exit:
455 LEAVE();
456 return ret;
457}
458
459static int as102_release(struct inode *inode, struct file *file)
460{
461 int ret = 0;
462 struct as102_dev_t *dev = NULL;
463
464 ENTER();
465
466 dev = file->private_data;
467 if (dev != NULL) {
468 /* decrement the count on our device */
469 kref_put(&dev->kref, as102_usb_release);
470 }
471
472 LEAVE();
473 return ret;
474}
475
476MODULE_DEVICE_TABLE(usb, as102_usb_id_table);
477
478/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as102_usb_drv.h b/drivers/staging/media/as102/as102_usb_drv.h
new file mode 100644
index 00000000000..fb1fc41dcd7
--- /dev/null
+++ b/drivers/staging/media/as102/as102_usb_drv.h
@@ -0,0 +1,59 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20#include <linux/version.h>
21
22#ifndef _AS102_USB_DRV_H_
23#define _AS102_USB_DRV_H_
24
25#define AS102_USB_DEVICE_TX_CTRL_CMD 0xF1
26#define AS102_USB_DEVICE_RX_CTRL_CMD 0xF2
27
28/* define these values to match the supported devices */
29
30/* Abilis system: "TITAN" */
31#define AS102_REFERENCE_DESIGN "Abilis Systems DVB-Titan"
32#define AS102_USB_DEVICE_VENDOR_ID 0x1BA6
33#define AS102_USB_DEVICE_PID_0001 0x0001
34
35/* PCTV Systems: PCTV picoStick (74e) */
36#define AS102_PCTV_74E "PCTV Systems picoStick (74e)"
37#define PCTV_74E_USB_VID 0x2013
38#define PCTV_74E_USB_PID 0x0246
39
40/* Elgato: EyeTV DTT Deluxe */
41#define AS102_ELGATO_EYETV_DTT_NAME "Elgato EyeTV DTT Deluxe"
42#define ELGATO_EYETV_DTT_USB_VID 0x0fd9
43#define ELGATO_EYETV_DTT_USB_PID 0x002c
44
45/* nBox: nBox DVB-T Dongle */
46#define AS102_NBOX_DVBT_DONGLE_NAME "nBox DVB-T Dongle"
47#define NBOX_DVBT_DONGLE_USB_VID 0x0b89
48#define NBOX_DVBT_DONGLE_USB_PID 0x0007
49
50void as102_urb_stream_irq(struct urb *urb);
51
52struct as10x_usb_token_cmd_t {
53 /* token cmd */
54 struct as10x_cmd_t c;
55 /* token response */
56 struct as10x_cmd_t r;
57};
58#endif
59/* EOF - vim: set textwidth=80 ts=8 sw=8 sts=8 noet: */
diff --git a/drivers/staging/media/as102/as10x_cmd.c b/drivers/staging/media/as102/as10x_cmd.c
new file mode 100644
index 00000000000..0dcba806578
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd.c
@@ -0,0 +1,452 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 * Copyright (C) 2010 Devin Heitmueller <dheitmueller@kernellabs.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/kernel.h>
22#include "as102_drv.h"
23#include "as10x_types.h"
24#include "as10x_cmd.h"
25
26/**
27 * as10x_cmd_turn_on - send turn on command to AS10x
28 * @phandle: pointer to AS10x handle
29 *
30 * Return 0 when no error, < 0 in case of error.
31 */
32int as10x_cmd_turn_on(as10x_handle_t *phandle)
33{
34 int error;
35 struct as10x_cmd_t *pcmd, *prsp;
36
37 ENTER();
38
39 pcmd = phandle->cmd;
40 prsp = phandle->rsp;
41
42 /* prepare command */
43 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
44 sizeof(pcmd->body.turn_on.req));
45
46 /* fill command */
47 pcmd->body.turn_on.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNON);
48
49 /* send command */
50 if (phandle->ops->xfer_cmd) {
51 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
52 sizeof(pcmd->body.turn_on.req) +
53 HEADER_SIZE,
54 (uint8_t *) prsp,
55 sizeof(prsp->body.turn_on.rsp) +
56 HEADER_SIZE);
57 } else {
58 error = AS10X_CMD_ERROR;
59 }
60
61 if (error < 0)
62 goto out;
63
64 /* parse response */
65 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNON_RSP);
66
67out:
68 LEAVE();
69 return error;
70}
71
72/**
73 * as10x_cmd_turn_off - send turn off command to AS10x
74 * @phandle: pointer to AS10x handle
75 *
76 * Return 0 on success or negative value in case of error.
77 */
78int as10x_cmd_turn_off(as10x_handle_t *phandle)
79{
80 int error;
81 struct as10x_cmd_t *pcmd, *prsp;
82
83 ENTER();
84
85 pcmd = phandle->cmd;
86 prsp = phandle->rsp;
87
88 /* prepare command */
89 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
90 sizeof(pcmd->body.turn_off.req));
91
92 /* fill command */
93 pcmd->body.turn_off.req.proc_id = cpu_to_le16(CONTROL_PROC_TURNOFF);
94
95 /* send command */
96 if (phandle->ops->xfer_cmd) {
97 error = phandle->ops->xfer_cmd(
98 phandle, (uint8_t *) pcmd,
99 sizeof(pcmd->body.turn_off.req) + HEADER_SIZE,
100 (uint8_t *) prsp,
101 sizeof(prsp->body.turn_off.rsp) + HEADER_SIZE);
102 } else {
103 error = AS10X_CMD_ERROR;
104 }
105
106 if (error < 0)
107 goto out;
108
109 /* parse response */
110 error = as10x_rsp_parse(prsp, CONTROL_PROC_TURNOFF_RSP);
111
112out:
113 LEAVE();
114 return error;
115}
116
117/**
118 * as10x_cmd_set_tune - send set tune command to AS10x
119 * @phandle: pointer to AS10x handle
120 * @ptune: tune parameters
121 *
122 * Return 0 on success or negative value in case of error.
123 */
124int as10x_cmd_set_tune(as10x_handle_t *phandle, struct as10x_tune_args *ptune)
125{
126 int error;
127 struct as10x_cmd_t *preq, *prsp;
128
129 ENTER();
130
131 preq = phandle->cmd;
132 prsp = phandle->rsp;
133
134 /* prepare command */
135 as10x_cmd_build(preq, (++phandle->cmd_xid),
136 sizeof(preq->body.set_tune.req));
137
138 /* fill command */
139 preq->body.set_tune.req.proc_id = cpu_to_le16(CONTROL_PROC_SETTUNE);
140 preq->body.set_tune.req.args.freq = cpu_to_le32(ptune->freq);
141 preq->body.set_tune.req.args.bandwidth = ptune->bandwidth;
142 preq->body.set_tune.req.args.hier_select = ptune->hier_select;
143 preq->body.set_tune.req.args.constellation = ptune->constellation;
144 preq->body.set_tune.req.args.hierarchy = ptune->hierarchy;
145 preq->body.set_tune.req.args.interleaving_mode =
146 ptune->interleaving_mode;
147 preq->body.set_tune.req.args.code_rate = ptune->code_rate;
148 preq->body.set_tune.req.args.guard_interval = ptune->guard_interval;
149 preq->body.set_tune.req.args.transmission_mode =
150 ptune->transmission_mode;
151
152 /* send command */
153 if (phandle->ops->xfer_cmd) {
154 error = phandle->ops->xfer_cmd(phandle,
155 (uint8_t *) preq,
156 sizeof(preq->body.set_tune.req)
157 + HEADER_SIZE,
158 (uint8_t *) prsp,
159 sizeof(prsp->body.set_tune.rsp)
160 + HEADER_SIZE);
161 } else {
162 error = AS10X_CMD_ERROR;
163 }
164
165 if (error < 0)
166 goto out;
167
168 /* parse response */
169 error = as10x_rsp_parse(prsp, CONTROL_PROC_SETTUNE_RSP);
170
171out:
172 LEAVE();
173 return error;
174}
175
176/**
177 * as10x_cmd_get_tune_status - send get tune status command to AS10x
178 * @phandle: pointer to AS10x handle
179 * @pstatus: pointer to updated status structure of the current tune
180 *
181 * Return 0 on success or negative value in case of error.
182 */
183int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
184 struct as10x_tune_status *pstatus)
185{
186 int error;
187 struct as10x_cmd_t *preq, *prsp;
188
189 ENTER();
190
191 preq = phandle->cmd;
192 prsp = phandle->rsp;
193
194 /* prepare command */
195 as10x_cmd_build(preq, (++phandle->cmd_xid),
196 sizeof(preq->body.get_tune_status.req));
197
198 /* fill command */
199 preq->body.get_tune_status.req.proc_id =
200 cpu_to_le16(CONTROL_PROC_GETTUNESTAT);
201
202 /* send command */
203 if (phandle->ops->xfer_cmd) {
204 error = phandle->ops->xfer_cmd(
205 phandle,
206 (uint8_t *) preq,
207 sizeof(preq->body.get_tune_status.req) + HEADER_SIZE,
208 (uint8_t *) prsp,
209 sizeof(prsp->body.get_tune_status.rsp) + HEADER_SIZE);
210 } else {
211 error = AS10X_CMD_ERROR;
212 }
213
214 if (error < 0)
215 goto out;
216
217 /* parse response */
218 error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTUNESTAT_RSP);
219 if (error < 0)
220 goto out;
221
222 /* Response OK -> get response data */
223 pstatus->tune_state = prsp->body.get_tune_status.rsp.sts.tune_state;
224 pstatus->signal_strength =
225 le16_to_cpu(prsp->body.get_tune_status.rsp.sts.signal_strength);
226 pstatus->PER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.PER);
227 pstatus->BER = le16_to_cpu(prsp->body.get_tune_status.rsp.sts.BER);
228
229out:
230 LEAVE();
231 return error;
232}
233
234/**
235 * send get TPS command to AS10x
236 * @phandle: pointer to AS10x handle
237 * @ptps: pointer to TPS parameters structure
238 *
239 * Return 0 on success or negative value in case of error.
240 */
241int as10x_cmd_get_tps(as10x_handle_t *phandle, struct as10x_tps *ptps)
242{
243 int error;
244 struct as10x_cmd_t *pcmd, *prsp;
245
246 ENTER();
247
248 pcmd = phandle->cmd;
249 prsp = phandle->rsp;
250
251 /* prepare command */
252 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
253 sizeof(pcmd->body.get_tps.req));
254
255 /* fill command */
256 pcmd->body.get_tune_status.req.proc_id =
257 cpu_to_le16(CONTROL_PROC_GETTPS);
258
259 /* send command */
260 if (phandle->ops->xfer_cmd) {
261 error = phandle->ops->xfer_cmd(phandle,
262 (uint8_t *) pcmd,
263 sizeof(pcmd->body.get_tps.req) +
264 HEADER_SIZE,
265 (uint8_t *) prsp,
266 sizeof(prsp->body.get_tps.rsp) +
267 HEADER_SIZE);
268 } else {
269 error = AS10X_CMD_ERROR;
270 }
271
272 if (error < 0)
273 goto out;
274
275 /* parse response */
276 error = as10x_rsp_parse(prsp, CONTROL_PROC_GETTPS_RSP);
277 if (error < 0)
278 goto out;
279
280 /* Response OK -> get response data */
281 ptps->constellation = prsp->body.get_tps.rsp.tps.constellation;
282 ptps->hierarchy = prsp->body.get_tps.rsp.tps.hierarchy;
283 ptps->interleaving_mode = prsp->body.get_tps.rsp.tps.interleaving_mode;
284 ptps->code_rate_HP = prsp->body.get_tps.rsp.tps.code_rate_HP;
285 ptps->code_rate_LP = prsp->body.get_tps.rsp.tps.code_rate_LP;
286 ptps->guard_interval = prsp->body.get_tps.rsp.tps.guard_interval;
287 ptps->transmission_mode = prsp->body.get_tps.rsp.tps.transmission_mode;
288 ptps->DVBH_mask_HP = prsp->body.get_tps.rsp.tps.DVBH_mask_HP;
289 ptps->DVBH_mask_LP = prsp->body.get_tps.rsp.tps.DVBH_mask_LP;
290 ptps->cell_ID = le16_to_cpu(prsp->body.get_tps.rsp.tps.cell_ID);
291
292out:
293 LEAVE();
294 return error;
295}
296
297/**
298 * as10x_cmd_get_demod_stats - send get demod stats command to AS10x
299 * @phandle: pointer to AS10x handle
300 * @pdemod_stats: pointer to demod stats parameters structure
301 *
302 * Return 0 on success or negative value in case of error.
303 */
304int as10x_cmd_get_demod_stats(as10x_handle_t *phandle,
305 struct as10x_demod_stats *pdemod_stats)
306{
307 int error;
308 struct as10x_cmd_t *pcmd, *prsp;
309
310 ENTER();
311
312 pcmd = phandle->cmd;
313 prsp = phandle->rsp;
314
315 /* prepare command */
316 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
317 sizeof(pcmd->body.get_demod_stats.req));
318
319 /* fill command */
320 pcmd->body.get_demod_stats.req.proc_id =
321 cpu_to_le16(CONTROL_PROC_GET_DEMOD_STATS);
322
323 /* send command */
324 if (phandle->ops->xfer_cmd) {
325 error = phandle->ops->xfer_cmd(phandle,
326 (uint8_t *) pcmd,
327 sizeof(pcmd->body.get_demod_stats.req)
328 + HEADER_SIZE,
329 (uint8_t *) prsp,
330 sizeof(prsp->body.get_demod_stats.rsp)
331 + HEADER_SIZE);
332 } else {
333 error = AS10X_CMD_ERROR;
334 }
335
336 if (error < 0)
337 goto out;
338
339 /* parse response */
340 error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_DEMOD_STATS_RSP);
341 if (error < 0)
342 goto out;
343
344 /* Response OK -> get response data */
345 pdemod_stats->frame_count =
346 le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.frame_count);
347 pdemod_stats->bad_frame_count =
348 le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bad_frame_count);
349 pdemod_stats->bytes_fixed_by_rs =
350 le32_to_cpu(prsp->body.get_demod_stats.rsp.stats.bytes_fixed_by_rs);
351 pdemod_stats->mer =
352 le16_to_cpu(prsp->body.get_demod_stats.rsp.stats.mer);
353 pdemod_stats->has_started =
354 prsp->body.get_demod_stats.rsp.stats.has_started;
355
356out:
357 LEAVE();
358 return error;
359}
360
361/**
362 * as10x_cmd_get_impulse_resp - send get impulse response command to AS10x
363 * @phandle: pointer to AS10x handle
364 * @is_ready: pointer to value indicating when impulse
365 * response data is ready
366 *
367 * Return 0 on success or negative value in case of error.
368 */
369int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
370 uint8_t *is_ready)
371{
372 int error;
373 struct as10x_cmd_t *pcmd, *prsp;
374
375 ENTER();
376
377 pcmd = phandle->cmd;
378 prsp = phandle->rsp;
379
380 /* prepare command */
381 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
382 sizeof(pcmd->body.get_impulse_rsp.req));
383
384 /* fill command */
385 pcmd->body.get_impulse_rsp.req.proc_id =
386 cpu_to_le16(CONTROL_PROC_GET_IMPULSE_RESP);
387
388 /* send command */
389 if (phandle->ops->xfer_cmd) {
390 error = phandle->ops->xfer_cmd(phandle,
391 (uint8_t *) pcmd,
392 sizeof(pcmd->body.get_impulse_rsp.req)
393 + HEADER_SIZE,
394 (uint8_t *) prsp,
395 sizeof(prsp->body.get_impulse_rsp.rsp)
396 + HEADER_SIZE);
397 } else {
398 error = AS10X_CMD_ERROR;
399 }
400
401 if (error < 0)
402 goto out;
403
404 /* parse response */
405 error = as10x_rsp_parse(prsp, CONTROL_PROC_GET_IMPULSE_RESP_RSP);
406 if (error < 0)
407 goto out;
408
409 /* Response OK -> get response data */
410 *is_ready = prsp->body.get_impulse_rsp.rsp.is_ready;
411
412out:
413 LEAVE();
414 return error;
415}
416
417/**
418 * as10x_cmd_build - build AS10x command header
419 * @pcmd: pointer to AS10x command buffer
420 * @xid: sequence id of the command
421 * @cmd_len: length of the command
422 */
423void as10x_cmd_build(struct as10x_cmd_t *pcmd,
424 uint16_t xid, uint16_t cmd_len)
425{
426 pcmd->header.req_id = cpu_to_le16(xid);
427 pcmd->header.prog = cpu_to_le16(SERVICE_PROG_ID);
428 pcmd->header.version = cpu_to_le16(SERVICE_PROG_VERSION);
429 pcmd->header.data_len = cpu_to_le16(cmd_len);
430}
431
432/**
433 * as10x_rsp_parse - Parse command response
434 * @prsp: pointer to AS10x command buffer
435 * @proc_id: id of the command
436 *
437 * Return 0 on success or negative value in case of error.
438 */
439int as10x_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
440{
441 int error;
442
443 /* extract command error code */
444 error = prsp->body.common.rsp.error;
445
446 if ((error == 0) &&
447 (le16_to_cpu(prsp->body.common.rsp.proc_id) == proc_id)) {
448 return 0;
449 }
450
451 return AS10X_CMD_ERROR;
452}
diff --git a/drivers/staging/media/as102/as10x_cmd.h b/drivers/staging/media/as102/as10x_cmd.h
new file mode 100644
index 00000000000..01a716380e0
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd.h
@@ -0,0 +1,540 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifndef _AS10X_CMD_H_
20#define _AS10X_CMD_H_
21
22#ifdef __KERNEL__
23#include <linux/kernel.h>
24#endif
25
26#include "as10x_types.h"
27
28/*********************************/
29/* MACRO DEFINITIONS */
30/*********************************/
31#define AS10X_CMD_ERROR -1
32
33#define SERVICE_PROG_ID 0x0002
34#define SERVICE_PROG_VERSION 0x0001
35
36#define HIER_NONE 0x00
37#define HIER_LOW_PRIORITY 0x01
38
39#define HEADER_SIZE (sizeof(struct as10x_cmd_header_t))
40
41/* context request types */
42#define GET_CONTEXT_DATA 1
43#define SET_CONTEXT_DATA 2
44
45/* ODSP suspend modes */
46#define CFG_MODE_ODSP_RESUME 0
47#define CFG_MODE_ODSP_SUSPEND 1
48
49/* Dump memory size */
50#define DUMP_BLOCK_SIZE_MAX 0x20
51
52/*********************************/
53/* TYPE DEFINITION */
54/*********************************/
55typedef enum {
56 CONTROL_PROC_TURNON = 0x0001,
57 CONTROL_PROC_TURNON_RSP = 0x0100,
58 CONTROL_PROC_SET_REGISTER = 0x0002,
59 CONTROL_PROC_SET_REGISTER_RSP = 0x0200,
60 CONTROL_PROC_GET_REGISTER = 0x0003,
61 CONTROL_PROC_GET_REGISTER_RSP = 0x0300,
62 CONTROL_PROC_SETTUNE = 0x000A,
63 CONTROL_PROC_SETTUNE_RSP = 0x0A00,
64 CONTROL_PROC_GETTUNESTAT = 0x000B,
65 CONTROL_PROC_GETTUNESTAT_RSP = 0x0B00,
66 CONTROL_PROC_GETTPS = 0x000D,
67 CONTROL_PROC_GETTPS_RSP = 0x0D00,
68 CONTROL_PROC_SETFILTER = 0x000E,
69 CONTROL_PROC_SETFILTER_RSP = 0x0E00,
70 CONTROL_PROC_REMOVEFILTER = 0x000F,
71 CONTROL_PROC_REMOVEFILTER_RSP = 0x0F00,
72 CONTROL_PROC_GET_IMPULSE_RESP = 0x0012,
73 CONTROL_PROC_GET_IMPULSE_RESP_RSP = 0x1200,
74 CONTROL_PROC_START_STREAMING = 0x0013,
75 CONTROL_PROC_START_STREAMING_RSP = 0x1300,
76 CONTROL_PROC_STOP_STREAMING = 0x0014,
77 CONTROL_PROC_STOP_STREAMING_RSP = 0x1400,
78 CONTROL_PROC_GET_DEMOD_STATS = 0x0015,
79 CONTROL_PROC_GET_DEMOD_STATS_RSP = 0x1500,
80 CONTROL_PROC_ELNA_CHANGE_MODE = 0x0016,
81 CONTROL_PROC_ELNA_CHANGE_MODE_RSP = 0x1600,
82 CONTROL_PROC_ODSP_CHANGE_MODE = 0x0017,
83 CONTROL_PROC_ODSP_CHANGE_MODE_RSP = 0x1700,
84 CONTROL_PROC_AGC_CHANGE_MODE = 0x0018,
85 CONTROL_PROC_AGC_CHANGE_MODE_RSP = 0x1800,
86
87 CONTROL_PROC_CONTEXT = 0x00FC,
88 CONTROL_PROC_CONTEXT_RSP = 0xFC00,
89 CONTROL_PROC_DUMP_MEMORY = 0x00FD,
90 CONTROL_PROC_DUMP_MEMORY_RSP = 0xFD00,
91 CONTROL_PROC_DUMPLOG_MEMORY = 0x00FE,
92 CONTROL_PROC_DUMPLOG_MEMORY_RSP = 0xFE00,
93 CONTROL_PROC_TURNOFF = 0x00FF,
94 CONTROL_PROC_TURNOFF_RSP = 0xFF00
95} control_proc;
96
97
98#pragma pack(1)
99typedef union {
100 /* request */
101 struct {
102 /* request identifier */
103 uint16_t proc_id;
104 } req;
105 /* response */
106 struct {
107 /* response identifier */
108 uint16_t proc_id;
109 /* error */
110 uint8_t error;
111 } rsp;
112} TURN_ON;
113
114typedef union {
115 /* request */
116 struct {
117 /* request identifier */
118 uint16_t proc_id;
119 } req;
120 /* response */
121 struct {
122 /* response identifier */
123 uint16_t proc_id;
124 /* error */
125 uint8_t err;
126 } rsp;
127} TURN_OFF;
128
129typedef union {
130 /* request */
131 struct {
132 /* request identifier */
133 uint16_t proc_id;
134 /* tune params */
135 struct as10x_tune_args args;
136 } req;
137 /* response */
138 struct {
139 /* response identifier */
140 uint16_t proc_id;
141 /* response error */
142 uint8_t error;
143 } rsp;
144} SET_TUNE;
145
146typedef union {
147 /* request */
148 struct {
149 /* request identifier */
150 uint16_t proc_id;
151 } req;
152 /* response */
153 struct {
154 /* response identifier */
155 uint16_t proc_id;
156 /* response error */
157 uint8_t error;
158 /* tune status */
159 struct as10x_tune_status sts;
160 } rsp;
161} GET_TUNE_STATUS;
162
163typedef union {
164 /* request */
165 struct {
166 /* request identifier */
167 uint16_t proc_id;
168 } req;
169 /* response */
170 struct {
171 /* response identifier */
172 uint16_t proc_id;
173 /* response error */
174 uint8_t error;
175 /* tps details */
176 struct as10x_tps tps;
177 } rsp;
178} GET_TPS;
179
180typedef union {
181 /* request */
182 struct {
183 /* request identifier */
184 uint16_t proc_id;
185 } req;
186 /* response */
187 struct {
188 /* response identifier */
189 uint16_t proc_id;
190 /* response error */
191 uint8_t error;
192 } rsp;
193} COMMON;
194
195typedef union {
196 /* request */
197 struct {
198 /* request identifier */
199 uint16_t proc_id;
200 /* PID to filter */
201 uint16_t pid;
202 /* stream type (MPE, PSI/SI or PES )*/
203 uint8_t stream_type;
204 /* PID index in filter table */
205 uint8_t idx;
206 } req;
207 /* response */
208 struct {
209 /* response identifier */
210 uint16_t proc_id;
211 /* response error */
212 uint8_t error;
213 /* Filter id */
214 uint8_t filter_id;
215 } rsp;
216} ADD_PID_FILTER;
217
218typedef union {
219 /* request */
220 struct {
221 /* request identifier */
222 uint16_t proc_id;
223 /* PID to remove */
224 uint16_t pid;
225 } req;
226 /* response */
227 struct {
228 /* response identifier */
229 uint16_t proc_id;
230 /* response error */
231 uint8_t error;
232 } rsp;
233} DEL_PID_FILTER;
234
235typedef union {
236 /* request */
237 struct {
238 /* request identifier */
239 uint16_t proc_id;
240 } req;
241 /* response */
242 struct {
243 /* response identifier */
244 uint16_t proc_id;
245 /* error */
246 uint8_t error;
247 } rsp;
248} START_STREAMING;
249
250typedef union {
251 /* request */
252 struct {
253 /* request identifier */
254 uint16_t proc_id;
255 } req;
256 /* response */
257 struct {
258 /* response identifier */
259 uint16_t proc_id;
260 /* error */
261 uint8_t error;
262 } rsp;
263} STOP_STREAMING;
264
265typedef union {
266 /* request */
267 struct {
268 /* request identifier */
269 uint16_t proc_id;
270 } req;
271 /* response */
272 struct {
273 /* response identifier */
274 uint16_t proc_id;
275 /* error */
276 uint8_t error;
277 /* demod stats */
278 struct as10x_demod_stats stats;
279 } rsp;
280} GET_DEMOD_STATS;
281
282typedef union {
283 /* request */
284 struct {
285 /* request identifier */
286 uint16_t proc_id;
287 } req;
288 /* response */
289 struct {
290 /* response identifier */
291 uint16_t proc_id;
292 /* error */
293 uint8_t error;
294 /* impulse response ready */
295 uint8_t is_ready;
296 } rsp;
297} GET_IMPULSE_RESP;
298
299typedef union {
300 /* request */
301 struct {
302 /* request identifier */
303 uint16_t proc_id;
304 /* value to write (for set context)*/
305 struct as10x_register_value reg_val;
306 /* context tag */
307 uint16_t tag;
308 /* context request type */
309 uint16_t type;
310 } req;
311 /* response */
312 struct {
313 /* response identifier */
314 uint16_t proc_id;
315 /* value read (for get context) */
316 struct as10x_register_value reg_val;
317 /* context request type */
318 uint16_t type;
319 /* error */
320 uint8_t error;
321 } rsp;
322} FW_CONTEXT;
323
324typedef union {
325 /* request */
326 struct {
327 /* response identifier */
328 uint16_t proc_id;
329 /* register description */
330 struct as10x_register_addr reg_addr;
331 /* register content */
332 struct as10x_register_value reg_val;
333 } req;
334 /* response */
335 struct {
336 /* response identifier */
337 uint16_t proc_id;
338 /* error */
339 uint8_t error;
340 } rsp;
341} SET_REGISTER;
342
343typedef union {
344 /* request */
345 struct {
346 /* response identifier */
347 uint16_t proc_id;
348 /* register description */
349 struct as10x_register_addr reg_addr;
350 } req;
351 /* response */
352 struct {
353 /* response identifier */
354 uint16_t proc_id;
355 /* error */
356 uint8_t error;
357 /* register content */
358 struct as10x_register_value reg_val;
359 } rsp;
360} GET_REGISTER;
361
362typedef union {
363 /* request */
364 struct {
365 /* request identifier */
366 uint16_t proc_id;
367 /* mode */
368 uint8_t mode;
369 } req;
370 /* response */
371 struct {
372 /* response identifier */
373 uint16_t proc_id;
374 /* error */
375 uint8_t error;
376 } rsp;
377} CFG_CHANGE_MODE;
378
379struct as10x_cmd_header_t {
380 uint16_t req_id;
381 uint16_t prog;
382 uint16_t version;
383 uint16_t data_len;
384};
385
386#define DUMP_BLOCK_SIZE 16
387typedef union {
388 /* request */
389 struct {
390 /* request identifier */
391 uint16_t proc_id;
392 /* dump memory type request */
393 uint8_t dump_req;
394 /* register description */
395 struct as10x_register_addr reg_addr;
396 /* nb blocks to read */
397 uint16_t num_blocks;
398 } req;
399 /* response */
400 struct {
401 /* response identifier */
402 uint16_t proc_id;
403 /* error */
404 uint8_t error;
405 /* dump response */
406 uint8_t dump_rsp;
407 /* data */
408 union {
409 uint8_t data8[DUMP_BLOCK_SIZE];
410 uint16_t data16[DUMP_BLOCK_SIZE / sizeof(uint16_t)];
411 uint32_t data32[DUMP_BLOCK_SIZE / sizeof(uint32_t)];
412 } u;
413 } rsp;
414} DUMP_MEMORY;
415
416typedef union {
417 struct {
418 /* request identifier */
419 uint16_t proc_id;
420 /* dump memory type request */
421 uint8_t dump_req;
422 } req;
423 struct {
424 /* request identifier */
425 uint16_t proc_id;
426 /* error */
427 uint8_t error;
428 /* dump response */
429 uint8_t dump_rsp;
430 /* dump data */
431 uint8_t data[DUMP_BLOCK_SIZE];
432 } rsp;
433} DUMPLOG_MEMORY;
434
435typedef union {
436 /* request */
437 struct {
438 uint16_t proc_id;
439 uint8_t data[64 - sizeof(struct as10x_cmd_header_t) -2 /* proc_id */];
440 } req;
441 /* response */
442 struct {
443 uint16_t proc_id;
444 uint8_t error;
445 uint8_t data[64 - sizeof(struct as10x_cmd_header_t) /* header */
446 - 2 /* proc_id */ - 1 /* rc */];
447 } rsp;
448} RAW_DATA;
449
450struct as10x_cmd_t {
451 /* header */
452 struct as10x_cmd_header_t header;
453 /* body */
454 union {
455 TURN_ON turn_on;
456 TURN_OFF turn_off;
457 SET_TUNE set_tune;
458 GET_TUNE_STATUS get_tune_status;
459 GET_TPS get_tps;
460 COMMON common;
461 ADD_PID_FILTER add_pid_filter;
462 DEL_PID_FILTER del_pid_filter;
463 START_STREAMING start_streaming;
464 STOP_STREAMING stop_streaming;
465 GET_DEMOD_STATS get_demod_stats;
466 GET_IMPULSE_RESP get_impulse_rsp;
467 FW_CONTEXT context;
468 SET_REGISTER set_register;
469 GET_REGISTER get_register;
470 CFG_CHANGE_MODE cfg_change_mode;
471 DUMP_MEMORY dump_memory;
472 DUMPLOG_MEMORY dumplog_memory;
473 RAW_DATA raw_data;
474 } body;
475};
476
477struct as10x_token_cmd_t {
478 /* token cmd */
479 struct as10x_cmd_t c;
480 /* token response */
481 struct as10x_cmd_t r;
482};
483#pragma pack()
484
485
486/**************************/
487/* FUNCTION DECLARATION */
488/**************************/
489
490void as10x_cmd_build(struct as10x_cmd_t *pcmd, uint16_t proc_id,
491 uint16_t cmd_len);
492int as10x_rsp_parse(struct as10x_cmd_t *r, uint16_t proc_id);
493
494#ifdef __cplusplus
495extern "C" {
496#endif
497
498/* as10x cmd */
499int as10x_cmd_turn_on(as10x_handle_t *phandle);
500int as10x_cmd_turn_off(as10x_handle_t *phandle);
501
502int as10x_cmd_set_tune(as10x_handle_t *phandle,
503 struct as10x_tune_args *ptune);
504
505int as10x_cmd_get_tune_status(as10x_handle_t *phandle,
506 struct as10x_tune_status *pstatus);
507
508int as10x_cmd_get_tps(as10x_handle_t *phandle,
509 struct as10x_tps *ptps);
510
511int as10x_cmd_get_demod_stats(as10x_handle_t *phandle,
512 struct as10x_demod_stats *pdemod_stats);
513
514int as10x_cmd_get_impulse_resp(as10x_handle_t *phandle,
515 uint8_t *is_ready);
516
517/* as10x cmd stream */
518int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
519 struct as10x_ts_filter *filter);
520int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
521 uint16_t pid_value);
522
523int as10x_cmd_start_streaming(as10x_handle_t *phandle);
524int as10x_cmd_stop_streaming(as10x_handle_t *phandle);
525
526/* as10x cmd cfg */
527int as10x_cmd_set_context(as10x_handle_t *phandle,
528 uint16_t tag,
529 uint32_t value);
530int as10x_cmd_get_context(as10x_handle_t *phandle,
531 uint16_t tag,
532 uint32_t *pvalue);
533
534int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode);
535int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id);
536#ifdef __cplusplus
537}
538#endif
539#endif
540/* EOF - vim: set textwidth=80 ts=3 sw=3 sts=3 et: */
diff --git a/drivers/staging/media/as102/as10x_cmd_cfg.c b/drivers/staging/media/as102/as10x_cmd_cfg.c
new file mode 100644
index 00000000000..ec6f69fcf39
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd_cfg.c
@@ -0,0 +1,215 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/kernel.h>
21#include "as102_drv.h"
22#include "as10x_types.h"
23#include "as10x_cmd.h"
24
25/***************************/
26/* FUNCTION DEFINITION */
27/***************************/
28
29/**
30 * as10x_cmd_get_context - Send get context command to AS10x
31 * @phandle: pointer to AS10x handle
32 * @tag: context tag
33 * @pvalue: pointer where to store context value read
34 *
35 * Return 0 on success or negative value in case of error.
36 */
37int as10x_cmd_get_context(as10x_handle_t *phandle, uint16_t tag,
38 uint32_t *pvalue)
39{
40 int error;
41 struct as10x_cmd_t *pcmd, *prsp;
42
43 ENTER();
44
45 pcmd = phandle->cmd;
46 prsp = phandle->rsp;
47
48 /* prepare command */
49 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
50 sizeof(pcmd->body.context.req));
51
52 /* fill command */
53 pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
54 pcmd->body.context.req.tag = cpu_to_le16(tag);
55 pcmd->body.context.req.type = cpu_to_le16(GET_CONTEXT_DATA);
56
57 /* send command */
58 if (phandle->ops->xfer_cmd) {
59 error = phandle->ops->xfer_cmd(phandle,
60 (uint8_t *) pcmd,
61 sizeof(pcmd->body.context.req)
62 + HEADER_SIZE,
63 (uint8_t *) prsp,
64 sizeof(prsp->body.context.rsp)
65 + HEADER_SIZE);
66 } else {
67 error = AS10X_CMD_ERROR;
68 }
69
70 if (error < 0)
71 goto out;
72
73 /* parse response: context command do not follow the common response */
74 /* structure -> specific handling response parse required */
75 error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
76
77 if (error == 0) {
78 /* Response OK -> get response data */
79 *pvalue = le32_to_cpu(prsp->body.context.rsp.reg_val.u.value32);
80 /* value returned is always a 32-bit value */
81 }
82
83out:
84 LEAVE();
85 return error;
86}
87
88/**
89 * as10x_cmd_set_context - send set context command to AS10x
90 * @phandle: pointer to AS10x handle
91 * @tag: context tag
92 * @value: value to set in context
93 *
94 * Return 0 on success or negative value in case of error.
95 */
96int as10x_cmd_set_context(as10x_handle_t *phandle, uint16_t tag,
97 uint32_t value)
98{
99 int error;
100 struct as10x_cmd_t *pcmd, *prsp;
101
102 ENTER();
103
104 pcmd = phandle->cmd;
105 prsp = phandle->rsp;
106
107 /* prepare command */
108 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
109 sizeof(pcmd->body.context.req));
110
111 /* fill command */
112 pcmd->body.context.req.proc_id = cpu_to_le16(CONTROL_PROC_CONTEXT);
113 /* pcmd->body.context.req.reg_val.mode initialization is not required */
114 pcmd->body.context.req.reg_val.u.value32 = cpu_to_le32(value);
115 pcmd->body.context.req.tag = cpu_to_le16(tag);
116 pcmd->body.context.req.type = cpu_to_le16(SET_CONTEXT_DATA);
117
118 /* send command */
119 if (phandle->ops->xfer_cmd) {
120 error = phandle->ops->xfer_cmd(phandle,
121 (uint8_t *) pcmd,
122 sizeof(pcmd->body.context.req)
123 + HEADER_SIZE,
124 (uint8_t *) prsp,
125 sizeof(prsp->body.context.rsp)
126 + HEADER_SIZE);
127 } else {
128 error = AS10X_CMD_ERROR;
129 }
130
131 if (error < 0)
132 goto out;
133
134 /* parse response: context command do not follow the common response */
135 /* structure -> specific handling response parse required */
136 error = as10x_context_rsp_parse(prsp, CONTROL_PROC_CONTEXT_RSP);
137
138out:
139 LEAVE();
140 return error;
141}
142
143/**
144 * as10x_cmd_eLNA_change_mode - send eLNA change mode command to AS10x
145 * @phandle: pointer to AS10x handle
146 * @mode: mode selected:
147 * - ON : 0x0 => eLNA always ON
148 * - OFF : 0x1 => eLNA always OFF
149 * - AUTO : 0x2 => eLNA follow hysteresis parameters
150 * to be ON or OFF
151 *
152 * Return 0 on success or negative value in case of error.
153 */
154int as10x_cmd_eLNA_change_mode(as10x_handle_t *phandle, uint8_t mode)
155{
156 int error;
157 struct as10x_cmd_t *pcmd, *prsp;
158
159 ENTER();
160
161 pcmd = phandle->cmd;
162 prsp = phandle->rsp;
163
164 /* prepare command */
165 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
166 sizeof(pcmd->body.cfg_change_mode.req));
167
168 /* fill command */
169 pcmd->body.cfg_change_mode.req.proc_id =
170 cpu_to_le16(CONTROL_PROC_ELNA_CHANGE_MODE);
171 pcmd->body.cfg_change_mode.req.mode = mode;
172
173 /* send command */
174 if (phandle->ops->xfer_cmd) {
175 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
176 sizeof(pcmd->body.cfg_change_mode.req)
177 + HEADER_SIZE, (uint8_t *) prsp,
178 sizeof(prsp->body.cfg_change_mode.rsp)
179 + HEADER_SIZE);
180 } else {
181 error = AS10X_CMD_ERROR;
182 }
183
184 if (error < 0)
185 goto out;
186
187 /* parse response */
188 error = as10x_rsp_parse(prsp, CONTROL_PROC_ELNA_CHANGE_MODE_RSP);
189
190out:
191 LEAVE();
192 return error;
193}
194
195/**
196 * as10x_context_rsp_parse - Parse context command response
197 * @prsp: pointer to AS10x command response buffer
198 * @proc_id: id of the command
199 *
200 * Since the contex command reponse does not follow the common
201 * response, a specific parse function is required.
202 * Return 0 on success or negative value in case of error.
203 */
204int as10x_context_rsp_parse(struct as10x_cmd_t *prsp, uint16_t proc_id)
205{
206 int err;
207
208 err = prsp->body.context.rsp.error;
209
210 if ((err == 0) &&
211 (le16_to_cpu(prsp->body.context.rsp.proc_id) == proc_id)) {
212 return 0;
213 }
214 return AS10X_CMD_ERROR;
215}
diff --git a/drivers/staging/media/as102/as10x_cmd_stream.c b/drivers/staging/media/as102/as10x_cmd_stream.c
new file mode 100644
index 00000000000..045c7068319
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_cmd_stream.c
@@ -0,0 +1,223 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20#include <linux/kernel.h>
21#include "as102_drv.h"
22#include "as10x_cmd.h"
23
24/**
25 * as10x_cmd_add_PID_filter - send add filter command to AS10x
26 * @phandle: pointer to AS10x handle
27 * @filter: TSFilter filter for DVB-T
28 *
29 * Return 0 on success or negative value in case of error.
30 */
31int as10x_cmd_add_PID_filter(as10x_handle_t *phandle,
32 struct as10x_ts_filter *filter)
33{
34 int error;
35 struct as10x_cmd_t *pcmd, *prsp;
36
37 ENTER();
38
39 pcmd = phandle->cmd;
40 prsp = phandle->rsp;
41
42 /* prepare command */
43 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
44 sizeof(pcmd->body.add_pid_filter.req));
45
46 /* fill command */
47 pcmd->body.add_pid_filter.req.proc_id =
48 cpu_to_le16(CONTROL_PROC_SETFILTER);
49 pcmd->body.add_pid_filter.req.pid = cpu_to_le16(filter->pid);
50 pcmd->body.add_pid_filter.req.stream_type = filter->type;
51
52 if (filter->idx < 16)
53 pcmd->body.add_pid_filter.req.idx = filter->idx;
54 else
55 pcmd->body.add_pid_filter.req.idx = 0xFF;
56
57 /* send command */
58 if (phandle->ops->xfer_cmd) {
59 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
60 sizeof(pcmd->body.add_pid_filter.req)
61 + HEADER_SIZE, (uint8_t *) prsp,
62 sizeof(prsp->body.add_pid_filter.rsp)
63 + HEADER_SIZE);
64 } else {
65 error = AS10X_CMD_ERROR;
66 }
67
68 if (error < 0)
69 goto out;
70
71 /* parse response */
72 error = as10x_rsp_parse(prsp, CONTROL_PROC_SETFILTER_RSP);
73
74 if (error == 0) {
75 /* Response OK -> get response data */
76 filter->idx = prsp->body.add_pid_filter.rsp.filter_id;
77 }
78
79out:
80 LEAVE();
81 return error;
82}
83
84/**
85 * as10x_cmd_del_PID_filter - Send delete filter command to AS10x
86 * @phandle: pointer to AS10x handle
87 * @pid_value: PID to delete
88 *
89 * Return 0 on success or negative value in case of error.
90 */
91int as10x_cmd_del_PID_filter(as10x_handle_t *phandle,
92 uint16_t pid_value)
93{
94 int error;
95 struct as10x_cmd_t *pcmd, *prsp;
96
97 ENTER();
98
99 pcmd = phandle->cmd;
100 prsp = phandle->rsp;
101
102 /* prepare command */
103 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
104 sizeof(pcmd->body.del_pid_filter.req));
105
106 /* fill command */
107 pcmd->body.del_pid_filter.req.proc_id =
108 cpu_to_le16(CONTROL_PROC_REMOVEFILTER);
109 pcmd->body.del_pid_filter.req.pid = cpu_to_le16(pid_value);
110
111 /* send command */
112 if (phandle->ops->xfer_cmd) {
113 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
114 sizeof(pcmd->body.del_pid_filter.req)
115 + HEADER_SIZE, (uint8_t *) prsp,
116 sizeof(prsp->body.del_pid_filter.rsp)
117 + HEADER_SIZE);
118 } else {
119 error = AS10X_CMD_ERROR;
120 }
121
122 if (error < 0)
123 goto out;
124
125 /* parse response */
126 error = as10x_rsp_parse(prsp, CONTROL_PROC_REMOVEFILTER_RSP);
127
128out:
129 LEAVE();
130 return error;
131}
132
133/**
134 * as10x_cmd_start_streaming - Send start streaming command to AS10x
135 * @phandle: pointer to AS10x handle
136 *
137 * Return 0 on success or negative value in case of error.
138 */
139int as10x_cmd_start_streaming(as10x_handle_t *phandle)
140{
141 int error;
142 struct as10x_cmd_t *pcmd, *prsp;
143
144 ENTER();
145
146 pcmd = phandle->cmd;
147 prsp = phandle->rsp;
148
149 /* prepare command */
150 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
151 sizeof(pcmd->body.start_streaming.req));
152
153 /* fill command */
154 pcmd->body.start_streaming.req.proc_id =
155 cpu_to_le16(CONTROL_PROC_START_STREAMING);
156
157 /* send command */
158 if (phandle->ops->xfer_cmd) {
159 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
160 sizeof(pcmd->body.start_streaming.req)
161 + HEADER_SIZE, (uint8_t *) prsp,
162 sizeof(prsp->body.start_streaming.rsp)
163 + HEADER_SIZE);
164 } else {
165 error = AS10X_CMD_ERROR;
166 }
167
168 if (error < 0)
169 goto out;
170
171 /* parse response */
172 error = as10x_rsp_parse(prsp, CONTROL_PROC_START_STREAMING_RSP);
173
174out:
175 LEAVE();
176 return error;
177}
178
179/**
180 * as10x_cmd_stop_streaming - Send stop streaming command to AS10x
181 * @phandle: pointer to AS10x handle
182 *
183 * Return 0 on success or negative value in case of error.
184 */
185int as10x_cmd_stop_streaming(as10x_handle_t *phandle)
186{
187 int8_t error;
188 struct as10x_cmd_t *pcmd, *prsp;
189
190 ENTER();
191
192 pcmd = phandle->cmd;
193 prsp = phandle->rsp;
194
195 /* prepare command */
196 as10x_cmd_build(pcmd, (++phandle->cmd_xid),
197 sizeof(pcmd->body.stop_streaming.req));
198
199 /* fill command */
200 pcmd->body.stop_streaming.req.proc_id =
201 cpu_to_le16(CONTROL_PROC_STOP_STREAMING);
202
203 /* send command */
204 if (phandle->ops->xfer_cmd) {
205 error = phandle->ops->xfer_cmd(phandle, (uint8_t *) pcmd,
206 sizeof(pcmd->body.stop_streaming.req)
207 + HEADER_SIZE, (uint8_t *) prsp,
208 sizeof(prsp->body.stop_streaming.rsp)
209 + HEADER_SIZE);
210 } else {
211 error = AS10X_CMD_ERROR;
212 }
213
214 if (error < 0)
215 goto out;
216
217 /* parse response */
218 error = as10x_rsp_parse(prsp, CONTROL_PROC_STOP_STREAMING_RSP);
219
220out:
221 LEAVE();
222 return error;
223}
diff --git a/drivers/staging/media/as102/as10x_handle.h b/drivers/staging/media/as102/as10x_handle.h
new file mode 100644
index 00000000000..4f01a76e982
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_handle.h
@@ -0,0 +1,58 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifdef __KERNEL__
20struct as102_bus_adapter_t;
21struct as102_dev_t;
22
23#define as10x_handle_t struct as102_bus_adapter_t
24#include "as10x_cmd.h"
25
26/* values for "mode" field */
27#define REGMODE8 8
28#define REGMODE16 16
29#define REGMODE32 32
30
31struct as102_priv_ops_t {
32 int (*upload_fw_pkt) (struct as102_bus_adapter_t *bus_adap,
33 unsigned char *buf, int buflen, int swap32);
34
35 int (*send_cmd) (struct as102_bus_adapter_t *bus_adap,
36 unsigned char *buf, int buflen);
37
38 int (*xfer_cmd) (struct as102_bus_adapter_t *bus_adap,
39 unsigned char *send_buf, int send_buf_len,
40 unsigned char *recv_buf, int recv_buf_len);
41/*
42 int (*pid_filter) (struct as102_bus_adapter_t *bus_adap,
43 int index, u16 pid, int onoff);
44*/
45 int (*start_stream) (struct as102_dev_t *dev);
46 void (*stop_stream) (struct as102_dev_t *dev);
47
48 int (*reset_target) (struct as102_bus_adapter_t *bus_adap);
49
50 int (*read_write)(struct as102_bus_adapter_t *bus_adap, uint8_t mode,
51 uint32_t rd_addr, uint16_t rd_len,
52 uint32_t wr_addr, uint16_t wr_len);
53
54 int (*as102_read_ep2) (struct as102_bus_adapter_t *bus_adap,
55 unsigned char *recv_buf,
56 int recv_buf_len);
57};
58#endif
diff --git a/drivers/staging/media/as102/as10x_types.h b/drivers/staging/media/as102/as10x_types.h
new file mode 100644
index 00000000000..3dedb3c1420
--- /dev/null
+++ b/drivers/staging/media/as102/as10x_types.h
@@ -0,0 +1,198 @@
1/*
2 * Abilis Systems Single DVB-T Receiver
3 * Copyright (C) 2008 Pierrick Hascoet <pierrick.hascoet@abilis.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19#ifndef _AS10X_TYPES_H_
20#define _AS10X_TYPES_H_
21
22#include "as10x_handle.h"
23
24/*********************************/
25/* MACRO DEFINITIONS */
26/*********************************/
27
28/* bandwidth constant values */
29#define BW_5_MHZ 0x00
30#define BW_6_MHZ 0x01
31#define BW_7_MHZ 0x02
32#define BW_8_MHZ 0x03
33
34/* hierarchy priority selection values */
35#define HIER_NO_PRIORITY 0x00
36#define HIER_LOW_PRIORITY 0x01
37#define HIER_HIGH_PRIORITY 0x02
38
39/* constellation available values */
40#define CONST_QPSK 0x00
41#define CONST_QAM16 0x01
42#define CONST_QAM64 0x02
43#define CONST_UNKNOWN 0xFF
44
45/* hierarchy available values */
46#define HIER_NONE 0x00
47#define HIER_ALPHA_1 0x01
48#define HIER_ALPHA_2 0x02
49#define HIER_ALPHA_4 0x03
50#define HIER_UNKNOWN 0xFF
51
52/* interleaving available values */
53#define INTLV_NATIVE 0x00
54#define INTLV_IN_DEPTH 0x01
55#define INTLV_UNKNOWN 0xFF
56
57/* code rate available values */
58#define CODE_RATE_1_2 0x00
59#define CODE_RATE_2_3 0x01
60#define CODE_RATE_3_4 0x02
61#define CODE_RATE_5_6 0x03
62#define CODE_RATE_7_8 0x04
63#define CODE_RATE_UNKNOWN 0xFF
64
65/* guard interval available values */
66#define GUARD_INT_1_32 0x00
67#define GUARD_INT_1_16 0x01
68#define GUARD_INT_1_8 0x02
69#define GUARD_INT_1_4 0x03
70#define GUARD_UNKNOWN 0xFF
71
72/* transmission mode available values */
73#define TRANS_MODE_2K 0x00
74#define TRANS_MODE_8K 0x01
75#define TRANS_MODE_4K 0x02
76#define TRANS_MODE_UNKNOWN 0xFF
77
78/* DVBH signalling available values */
79#define TIMESLICING_PRESENT 0x01
80#define MPE_FEC_PRESENT 0x02
81
82/* tune state available */
83#define TUNE_STATUS_NOT_TUNED 0x00
84#define TUNE_STATUS_IDLE 0x01
85#define TUNE_STATUS_LOCKING 0x02
86#define TUNE_STATUS_SIGNAL_DVB_OK 0x03
87#define TUNE_STATUS_STREAM_DETECTED 0x04
88#define TUNE_STATUS_STREAM_TUNED 0x05
89#define TUNE_STATUS_ERROR 0xFF
90
91/* available TS FID filter types */
92#define TS_PID_TYPE_TS 0
93#define TS_PID_TYPE_PSI_SI 1
94#define TS_PID_TYPE_MPE 2
95
96/* number of echos available */
97#define MAX_ECHOS 15
98
99/* Context types */
100#define CONTEXT_LNA 1010
101#define CONTEXT_ELNA_HYSTERESIS 4003
102#define CONTEXT_ELNA_GAIN 4004
103#define CONTEXT_MER_THRESHOLD 5005
104#define CONTEXT_MER_OFFSET 5006
105#define CONTEXT_IR_STATE 7000
106#define CONTEXT_TSOUT_MSB_FIRST 7004
107#define CONTEXT_TSOUT_FALLING_EDGE 7005
108
109/* Configuration modes */
110#define CFG_MODE_ON 0
111#define CFG_MODE_OFF 1
112#define CFG_MODE_AUTO 2
113
114#pragma pack(1)
115struct as10x_tps {
116 uint8_t constellation;
117 uint8_t hierarchy;
118 uint8_t interleaving_mode;
119 uint8_t code_rate_HP;
120 uint8_t code_rate_LP;
121 uint8_t guard_interval;
122 uint8_t transmission_mode;
123 uint8_t DVBH_mask_HP;
124 uint8_t DVBH_mask_LP;
125 uint16_t cell_ID;
126};
127
128struct as10x_tune_args {
129 /* frequency */
130 uint32_t freq;
131 /* bandwidth */
132 uint8_t bandwidth;
133 /* hierarchy selection */
134 uint8_t hier_select;
135 /* constellation */
136 uint8_t constellation;
137 /* hierarchy */
138 uint8_t hierarchy;
139 /* interleaving mode */
140 uint8_t interleaving_mode;
141 /* code rate */
142 uint8_t code_rate;
143 /* guard interval */
144 uint8_t guard_interval;
145 /* transmission mode */
146 uint8_t transmission_mode;
147};
148
149struct as10x_tune_status {
150 /* tune status */
151 uint8_t tune_state;
152 /* signal strength */
153 int16_t signal_strength;
154 /* packet error rate 10^-4 */
155 uint16_t PER;
156 /* bit error rate 10^-4 */
157 uint16_t BER;
158};
159
160struct as10x_demod_stats {
161 /* frame counter */
162 uint32_t frame_count;
163 /* Bad frame counter */
164 uint32_t bad_frame_count;
165 /* Number of wrong bytes fixed by Reed-Solomon */
166 uint32_t bytes_fixed_by_rs;
167 /* Averaged MER */
168 uint16_t mer;
169 /* statistics calculation state indicator (started or not) */
170 uint8_t has_started;
171};
172
173struct as10x_ts_filter {
174 uint16_t pid; /** valid PID value 0x00 : 0x2000 */
175 uint8_t type; /** Red TS_PID_TYPE_<N> values */
176 uint8_t idx; /** index in filtering table */
177};
178
179struct as10x_register_value {
180 uint8_t mode;
181 union {
182 uint8_t value8; /* 8 bit value */
183 uint16_t value16; /* 16 bit value */
184 uint32_t value32; /* 32 bit value */
185 }u;
186};
187
188#pragma pack()
189
190struct as10x_register_addr {
191 /* register addr */
192 uint32_t addr;
193 /* register mode access */
194 uint8_t mode;
195};
196
197
198#endif
diff --git a/drivers/staging/cxd2099/Kconfig b/drivers/staging/media/cxd2099/Kconfig
index b48aefddc84..b48aefddc84 100644
--- a/drivers/staging/cxd2099/Kconfig
+++ b/drivers/staging/media/cxd2099/Kconfig
diff --git a/drivers/staging/cxd2099/Makefile b/drivers/staging/media/cxd2099/Makefile
index 64cfc77be35..64cfc77be35 100644
--- a/drivers/staging/cxd2099/Makefile
+++ b/drivers/staging/media/cxd2099/Makefile
diff --git a/drivers/staging/cxd2099/TODO b/drivers/staging/media/cxd2099/TODO
index 375bb6f8ee2..375bb6f8ee2 100644
--- a/drivers/staging/cxd2099/TODO
+++ b/drivers/staging/media/cxd2099/TODO
diff --git a/drivers/staging/cxd2099/cxd2099.c b/drivers/staging/media/cxd2099/cxd2099.c
index 1c04185bcfd..1c04185bcfd 100644
--- a/drivers/staging/cxd2099/cxd2099.c
+++ b/drivers/staging/media/cxd2099/cxd2099.c
diff --git a/drivers/staging/cxd2099/cxd2099.h b/drivers/staging/media/cxd2099/cxd2099.h
index 19c588a5958..19c588a5958 100644
--- a/drivers/staging/cxd2099/cxd2099.h
+++ b/drivers/staging/media/cxd2099/cxd2099.h
diff --git a/drivers/staging/dt3155v4l/Kconfig b/drivers/staging/media/dt3155v4l/Kconfig
index 226a1ca90b3..226a1ca90b3 100644
--- a/drivers/staging/dt3155v4l/Kconfig
+++ b/drivers/staging/media/dt3155v4l/Kconfig
diff --git a/drivers/staging/dt3155v4l/Makefile b/drivers/staging/media/dt3155v4l/Makefile
index ce7a3ec2faf..ce7a3ec2faf 100644
--- a/drivers/staging/dt3155v4l/Makefile
+++ b/drivers/staging/media/dt3155v4l/Makefile
diff --git a/drivers/staging/dt3155v4l/dt3155v4l.c b/drivers/staging/media/dt3155v4l/dt3155v4l.c
index 04e93c49f03..04e93c49f03 100644
--- a/drivers/staging/dt3155v4l/dt3155v4l.c
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.c
diff --git a/drivers/staging/dt3155v4l/dt3155v4l.h b/drivers/staging/media/dt3155v4l/dt3155v4l.h
index 2e4f89d402e..2e4f89d402e 100644
--- a/drivers/staging/dt3155v4l/dt3155v4l.h
+++ b/drivers/staging/media/dt3155v4l/dt3155v4l.h
diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/media/easycap/Kconfig
index a425a6f9cdc..a425a6f9cdc 100644
--- a/drivers/staging/easycap/Kconfig
+++ b/drivers/staging/media/easycap/Kconfig
diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/media/easycap/Makefile
index a34e75f59c1..a34e75f59c1 100644
--- a/drivers/staging/easycap/Makefile
+++ b/drivers/staging/media/easycap/Makefile
diff --git a/drivers/staging/easycap/README b/drivers/staging/media/easycap/README
index 796b032384b..796b032384b 100644
--- a/drivers/staging/easycap/README
+++ b/drivers/staging/media/easycap/README
diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/media/easycap/easycap.h
index 7b256a948c2..7b256a948c2 100644
--- a/drivers/staging/easycap/easycap.h
+++ b/drivers/staging/media/easycap/easycap.h
diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/media/easycap/easycap_ioctl.c
index c99addfb624..c99addfb624 100644
--- a/drivers/staging/easycap/easycap_ioctl.c
+++ b/drivers/staging/media/easycap/easycap_ioctl.c
diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/media/easycap/easycap_low.c
index 0385735ac6d..0385735ac6d 100644
--- a/drivers/staging/easycap/easycap_low.c
+++ b/drivers/staging/media/easycap/easycap_low.c
diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/media/easycap/easycap_main.c
index a45c0b50706..a45c0b50706 100644
--- a/drivers/staging/easycap/easycap_main.c
+++ b/drivers/staging/media/easycap/easycap_main.c
diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/media/easycap/easycap_settings.c
index 70f59b13c34..70f59b13c34 100644
--- a/drivers/staging/easycap/easycap_settings.c
+++ b/drivers/staging/media/easycap/easycap_settings.c
diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/media/easycap/easycap_sound.c
index b22bb39b5f6..b22bb39b5f6 100644
--- a/drivers/staging/easycap/easycap_sound.c
+++ b/drivers/staging/media/easycap/easycap_sound.c
diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/media/easycap/easycap_testcard.c
index 0f71470ace3..0f71470ace3 100644
--- a/drivers/staging/easycap/easycap_testcard.c
+++ b/drivers/staging/media/easycap/easycap_testcard.c
diff --git a/drivers/staging/go7007/Kconfig b/drivers/staging/media/go7007/Kconfig
index 7dfb2815b9e..7dfb2815b9e 100644
--- a/drivers/staging/go7007/Kconfig
+++ b/drivers/staging/media/go7007/Kconfig
diff --git a/drivers/staging/go7007/Makefile b/drivers/staging/media/go7007/Makefile
index 6ee837c5670..6ee837c5670 100644
--- a/drivers/staging/go7007/Makefile
+++ b/drivers/staging/media/go7007/Makefile
diff --git a/drivers/staging/go7007/README b/drivers/staging/media/go7007/README
index 48f44763781..48f44763781 100644
--- a/drivers/staging/go7007/README
+++ b/drivers/staging/media/go7007/README
diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/media/go7007/go7007-driver.c
index 6c9279a6d60..6c9279a6d60 100644
--- a/drivers/staging/go7007/go7007-driver.c
+++ b/drivers/staging/media/go7007/go7007-driver.c
diff --git a/drivers/staging/go7007/go7007-fw.c b/drivers/staging/media/go7007/go7007-fw.c
index c9a6409edfe..c9a6409edfe 100644
--- a/drivers/staging/go7007/go7007-fw.c
+++ b/drivers/staging/media/go7007/go7007-fw.c
diff --git a/drivers/staging/go7007/go7007-i2c.c b/drivers/staging/media/go7007/go7007-i2c.c
index b8cfa1a6eae..b8cfa1a6eae 100644
--- a/drivers/staging/go7007/go7007-i2c.c
+++ b/drivers/staging/media/go7007/go7007-i2c.c
diff --git a/drivers/staging/go7007/go7007-priv.h b/drivers/staging/media/go7007/go7007-priv.h
index b58c394c655..b58c394c655 100644
--- a/drivers/staging/go7007/go7007-priv.h
+++ b/drivers/staging/media/go7007/go7007-priv.h
diff --git a/drivers/staging/go7007/go7007-usb.c b/drivers/staging/media/go7007/go7007-usb.c
index 3db3b0a91cc..3db3b0a91cc 100644
--- a/drivers/staging/go7007/go7007-usb.c
+++ b/drivers/staging/media/go7007/go7007-usb.c
diff --git a/drivers/staging/go7007/go7007-v4l2.c b/drivers/staging/media/go7007/go7007-v4l2.c
index 2b27d8da70a..2b27d8da70a 100644
--- a/drivers/staging/go7007/go7007-v4l2.c
+++ b/drivers/staging/media/go7007/go7007-v4l2.c
diff --git a/drivers/staging/go7007/go7007.h b/drivers/staging/media/go7007/go7007.h
index 7399c915a93..7399c915a93 100644
--- a/drivers/staging/go7007/go7007.h
+++ b/drivers/staging/media/go7007/go7007.h
diff --git a/drivers/staging/go7007/go7007.txt b/drivers/staging/media/go7007/go7007.txt
index 9db1f3952fd..9db1f3952fd 100644
--- a/drivers/staging/go7007/go7007.txt
+++ b/drivers/staging/media/go7007/go7007.txt
diff --git a/drivers/staging/go7007/s2250-board.c b/drivers/staging/media/go7007/s2250-board.c
index e7736a91553..e7736a91553 100644
--- a/drivers/staging/go7007/s2250-board.c
+++ b/drivers/staging/media/go7007/s2250-board.c
diff --git a/drivers/staging/go7007/s2250-loader.c b/drivers/staging/media/go7007/s2250-loader.c
index 4e132519e25..4e132519e25 100644
--- a/drivers/staging/go7007/s2250-loader.c
+++ b/drivers/staging/media/go7007/s2250-loader.c
diff --git a/drivers/staging/go7007/s2250-loader.h b/drivers/staging/media/go7007/s2250-loader.h
index b7c301af16c..b7c301af16c 100644
--- a/drivers/staging/go7007/s2250-loader.h
+++ b/drivers/staging/media/go7007/s2250-loader.h
diff --git a/drivers/staging/go7007/saa7134-go7007.c b/drivers/staging/media/go7007/saa7134-go7007.c
index cf7c34a9945..cf7c34a9945 100644
--- a/drivers/staging/go7007/saa7134-go7007.c
+++ b/drivers/staging/media/go7007/saa7134-go7007.c
diff --git a/drivers/staging/go7007/snd-go7007.c b/drivers/staging/media/go7007/snd-go7007.c
index deac938d850..deac938d850 100644
--- a/drivers/staging/go7007/snd-go7007.c
+++ b/drivers/staging/media/go7007/snd-go7007.c
diff --git a/drivers/staging/go7007/wis-i2c.h b/drivers/staging/media/go7007/wis-i2c.h
index 3c2b9be455d..3c2b9be455d 100644
--- a/drivers/staging/go7007/wis-i2c.h
+++ b/drivers/staging/media/go7007/wis-i2c.h
diff --git a/drivers/staging/go7007/wis-ov7640.c b/drivers/staging/media/go7007/wis-ov7640.c
index 6bc9470fecb..6bc9470fecb 100644
--- a/drivers/staging/go7007/wis-ov7640.c
+++ b/drivers/staging/media/go7007/wis-ov7640.c
diff --git a/drivers/staging/go7007/wis-saa7113.c b/drivers/staging/media/go7007/wis-saa7113.c
index 05e0e108386..05e0e108386 100644
--- a/drivers/staging/go7007/wis-saa7113.c
+++ b/drivers/staging/media/go7007/wis-saa7113.c
diff --git a/drivers/staging/go7007/wis-saa7115.c b/drivers/staging/media/go7007/wis-saa7115.c
index 46cff59e28b..46cff59e28b 100644
--- a/drivers/staging/go7007/wis-saa7115.c
+++ b/drivers/staging/media/go7007/wis-saa7115.c
diff --git a/drivers/staging/go7007/wis-sony-tuner.c b/drivers/staging/media/go7007/wis-sony-tuner.c
index 8f1b7d4f6a2..8f1b7d4f6a2 100644
--- a/drivers/staging/go7007/wis-sony-tuner.c
+++ b/drivers/staging/media/go7007/wis-sony-tuner.c
diff --git a/drivers/staging/go7007/wis-tw2804.c b/drivers/staging/media/go7007/wis-tw2804.c
index 9134f03e3cf..9134f03e3cf 100644
--- a/drivers/staging/go7007/wis-tw2804.c
+++ b/drivers/staging/media/go7007/wis-tw2804.c
diff --git a/drivers/staging/go7007/wis-tw9903.c b/drivers/staging/media/go7007/wis-tw9903.c
index 9230f4a8052..9230f4a8052 100644
--- a/drivers/staging/go7007/wis-tw9903.c
+++ b/drivers/staging/media/go7007/wis-tw9903.c
diff --git a/drivers/staging/go7007/wis-uda1342.c b/drivers/staging/media/go7007/wis-uda1342.c
index 0127be2f3be..0127be2f3be 100644
--- a/drivers/staging/go7007/wis-uda1342.c
+++ b/drivers/staging/media/go7007/wis-uda1342.c
diff --git a/drivers/staging/lirc/Kconfig b/drivers/staging/media/lirc/Kconfig
index 526ec0fc2f0..526ec0fc2f0 100644
--- a/drivers/staging/lirc/Kconfig
+++ b/drivers/staging/media/lirc/Kconfig
diff --git a/drivers/staging/lirc/Makefile b/drivers/staging/media/lirc/Makefile
index d76b0fa2af5..d76b0fa2af5 100644
--- a/drivers/staging/lirc/Makefile
+++ b/drivers/staging/media/lirc/Makefile
diff --git a/drivers/staging/lirc/TODO b/drivers/staging/media/lirc/TODO
index b6cb593f55c..b6cb593f55c 100644
--- a/drivers/staging/lirc/TODO
+++ b/drivers/staging/media/lirc/TODO
diff --git a/drivers/staging/lirc/TODO.lirc_zilog b/drivers/staging/media/lirc/TODO.lirc_zilog
index a97800a8e12..a97800a8e12 100644
--- a/drivers/staging/lirc/TODO.lirc_zilog
+++ b/drivers/staging/media/lirc/TODO.lirc_zilog
diff --git a/drivers/staging/lirc/lirc_bt829.c b/drivers/staging/media/lirc/lirc_bt829.c
index c5a0d27a02d..c5a0d27a02d 100644
--- a/drivers/staging/lirc/lirc_bt829.c
+++ b/drivers/staging/media/lirc/lirc_bt829.c
diff --git a/drivers/staging/lirc/lirc_ene0100.h b/drivers/staging/media/lirc/lirc_ene0100.h
index 06bebd6acc4..06bebd6acc4 100644
--- a/drivers/staging/lirc/lirc_ene0100.h
+++ b/drivers/staging/media/lirc/lirc_ene0100.h
diff --git a/drivers/staging/lirc/lirc_igorplugusb.c b/drivers/staging/media/lirc/lirc_igorplugusb.c
index 0dc2c2b22c2..0dc2c2b22c2 100644
--- a/drivers/staging/lirc/lirc_igorplugusb.c
+++ b/drivers/staging/media/lirc/lirc_igorplugusb.c
diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/media/lirc/lirc_imon.c
index f5308d5929c..f5308d5929c 100644
--- a/drivers/staging/lirc/lirc_imon.c
+++ b/drivers/staging/media/lirc/lirc_imon.c
diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/media/lirc/lirc_parallel.c
index 792aac0a8e7..792aac0a8e7 100644
--- a/drivers/staging/lirc/lirc_parallel.c
+++ b/drivers/staging/media/lirc/lirc_parallel.c
diff --git a/drivers/staging/lirc/lirc_parallel.h b/drivers/staging/media/lirc/lirc_parallel.h
index 4bed6afe063..4bed6afe063 100644
--- a/drivers/staging/lirc/lirc_parallel.h
+++ b/drivers/staging/media/lirc/lirc_parallel.h
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/media/lirc/lirc_sasem.c
index a2d18b0aa04..a2d18b0aa04 100644
--- a/drivers/staging/lirc/lirc_sasem.c
+++ b/drivers/staging/media/lirc/lirc_sasem.c
diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/media/lirc/lirc_serial.c
index 8a060a8a722..8a060a8a722 100644
--- a/drivers/staging/lirc/lirc_serial.c
+++ b/drivers/staging/media/lirc/lirc_serial.c
diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/media/lirc/lirc_sir.c
index 6903d3992ec..6903d3992ec 100644
--- a/drivers/staging/lirc/lirc_sir.c
+++ b/drivers/staging/media/lirc/lirc_sir.c
diff --git a/drivers/staging/lirc/lirc_ttusbir.c b/drivers/staging/media/lirc/lirc_ttusbir.c
index e4b329b8caf..e4b329b8caf 100644
--- a/drivers/staging/lirc/lirc_ttusbir.c
+++ b/drivers/staging/media/lirc/lirc_ttusbir.c
diff --git a/drivers/staging/lirc/lirc_zilog.c b/drivers/staging/media/lirc/lirc_zilog.c
index 0302d82a12f..0302d82a12f 100644
--- a/drivers/staging/lirc/lirc_zilog.c
+++ b/drivers/staging/media/lirc/lirc_zilog.c
diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/media/solo6x10/Kconfig
index 03dcac4ea4d..03dcac4ea4d 100644
--- a/drivers/staging/solo6x10/Kconfig
+++ b/drivers/staging/media/solo6x10/Kconfig
diff --git a/drivers/staging/solo6x10/Makefile b/drivers/staging/media/solo6x10/Makefile
index 72816cf1670..72816cf1670 100644
--- a/drivers/staging/solo6x10/Makefile
+++ b/drivers/staging/media/solo6x10/Makefile
diff --git a/drivers/staging/solo6x10/TODO b/drivers/staging/media/solo6x10/TODO
index 7e6c4fa130d..7e6c4fa130d 100644
--- a/drivers/staging/solo6x10/TODO
+++ b/drivers/staging/media/solo6x10/TODO
diff --git a/drivers/staging/solo6x10/core.c b/drivers/staging/media/solo6x10/core.c
index f974f6412ad..f974f6412ad 100644
--- a/drivers/staging/solo6x10/core.c
+++ b/drivers/staging/media/solo6x10/core.c
diff --git a/drivers/staging/solo6x10/disp.c b/drivers/staging/media/solo6x10/disp.c
index 884c0eb757c..884c0eb757c 100644
--- a/drivers/staging/solo6x10/disp.c
+++ b/drivers/staging/media/solo6x10/disp.c
diff --git a/drivers/staging/solo6x10/enc.c b/drivers/staging/media/solo6x10/enc.c
index de502599bb1..de502599bb1 100644
--- a/drivers/staging/solo6x10/enc.c
+++ b/drivers/staging/media/solo6x10/enc.c
diff --git a/drivers/staging/solo6x10/g723.c b/drivers/staging/media/solo6x10/g723.c
index 59274bfca95..59274bfca95 100644
--- a/drivers/staging/solo6x10/g723.c
+++ b/drivers/staging/media/solo6x10/g723.c
diff --git a/drivers/staging/solo6x10/gpio.c b/drivers/staging/media/solo6x10/gpio.c
index 0925e6f33a9..0925e6f33a9 100644
--- a/drivers/staging/solo6x10/gpio.c
+++ b/drivers/staging/media/solo6x10/gpio.c
diff --git a/drivers/staging/solo6x10/i2c.c b/drivers/staging/media/solo6x10/i2c.c
index ef95a500b4d..ef95a500b4d 100644
--- a/drivers/staging/solo6x10/i2c.c
+++ b/drivers/staging/media/solo6x10/i2c.c
diff --git a/drivers/staging/solo6x10/jpeg.h b/drivers/staging/media/solo6x10/jpeg.h
index 50defec318c..50defec318c 100644
--- a/drivers/staging/solo6x10/jpeg.h
+++ b/drivers/staging/media/solo6x10/jpeg.h
diff --git a/drivers/staging/solo6x10/offsets.h b/drivers/staging/media/solo6x10/offsets.h
index 3d7e569f1cf..3d7e569f1cf 100644
--- a/drivers/staging/solo6x10/offsets.h
+++ b/drivers/staging/media/solo6x10/offsets.h
diff --git a/drivers/staging/solo6x10/osd-font.h b/drivers/staging/media/solo6x10/osd-font.h
index 591e0e82e0e..591e0e82e0e 100644
--- a/drivers/staging/solo6x10/osd-font.h
+++ b/drivers/staging/media/solo6x10/osd-font.h
diff --git a/drivers/staging/solo6x10/p2m.c b/drivers/staging/media/solo6x10/p2m.c
index 56210f0fc5e..56210f0fc5e 100644
--- a/drivers/staging/solo6x10/p2m.c
+++ b/drivers/staging/media/solo6x10/p2m.c
diff --git a/drivers/staging/solo6x10/registers.h b/drivers/staging/media/solo6x10/registers.h
index aca544472c9..aca544472c9 100644
--- a/drivers/staging/solo6x10/registers.h
+++ b/drivers/staging/media/solo6x10/registers.h
diff --git a/drivers/staging/solo6x10/solo6x10.h b/drivers/staging/media/solo6x10/solo6x10.h
index abee7213202..abee7213202 100644
--- a/drivers/staging/solo6x10/solo6x10.h
+++ b/drivers/staging/media/solo6x10/solo6x10.h
diff --git a/drivers/staging/solo6x10/tw28.c b/drivers/staging/media/solo6x10/tw28.c
index db56b42c56c..db56b42c56c 100644
--- a/drivers/staging/solo6x10/tw28.c
+++ b/drivers/staging/media/solo6x10/tw28.c
diff --git a/drivers/staging/solo6x10/tw28.h b/drivers/staging/media/solo6x10/tw28.h
index a44a03afbd3..a44a03afbd3 100644
--- a/drivers/staging/solo6x10/tw28.h
+++ b/drivers/staging/media/solo6x10/tw28.h
diff --git a/drivers/staging/solo6x10/v4l2-enc.c b/drivers/staging/media/solo6x10/v4l2-enc.c
index bee7280bbed..bee7280bbed 100644
--- a/drivers/staging/solo6x10/v4l2-enc.c
+++ b/drivers/staging/media/solo6x10/v4l2-enc.c
diff --git a/drivers/staging/solo6x10/v4l2.c b/drivers/staging/media/solo6x10/v4l2.c
index 571c3a348d3..571c3a348d3 100644
--- a/drivers/staging/solo6x10/v4l2.c
+++ b/drivers/staging/media/solo6x10/v4l2.c